redux-devtools/extension/src/devpanel/index.tsx
Nathan Bierema 1aa6c4f7a0
Fix remounting root for devpanel (#1302)
* Fix remounting root for devpanel

* Create seven-turkeys-battle.md
2022-12-26 12:37:55 -05:00

112 lines
3.2 KiB
TypeScript

import React, { CSSProperties, ReactNode } from 'react';
import { createRoot, Root } from 'react-dom/client';
import { Provider } from 'react-redux';
import { Persistor } from 'redux-persist';
import { REMOVE_INSTANCE, StoreAction } from '@redux-devtools/app';
import App from '../app/App';
import configureStore from './store/panelStore';
import './devpanel.pug';
import { Action, Store } from 'redux';
import type { PanelMessage } from '../background/store/apiMiddleware';
import type { StoreStateWithoutSocket } from './store/panelReducer';
import { PersistGate } from 'redux-persist/integration/react';
const position = location.hash;
const messageStyle: CSSProperties = {
padding: '20px',
width: '100%',
textAlign: 'center',
};
let rendered: boolean | undefined;
let currentRoot: Root | undefined;
let store: Store<StoreStateWithoutSocket, StoreAction> | undefined;
let persistor: Persistor | undefined;
let bgConnection: chrome.runtime.Port;
let naTimeout: NodeJS.Timeout;
const isChrome = navigator.userAgent.indexOf('Firefox') === -1;
function renderNodeAtRoot(node: ReactNode) {
if (currentRoot) currentRoot.unmount();
currentRoot = createRoot(document.getElementById('root')!);
currentRoot.render(node);
}
function renderDevTools() {
clearTimeout(naTimeout);
({ store, persistor } = configureStore(position, bgConnection));
renderNodeAtRoot(
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<App position={position} />
</PersistGate>
</Provider>
);
rendered = true;
}
function renderNA() {
if (rendered === false) return;
rendered = false;
naTimeout = setTimeout(() => {
let message = (
<div style={messageStyle}>
No store found. Make sure to follow{' '}
<a
href="https://github.com/zalmoxisus/redux-devtools-extension#usage"
target="_blank"
>
the instructions
</a>
.
</div>
);
if (isChrome) {
chrome.devtools.inspectedWindow.getResources((resources) => {
if (resources[0].url.substr(0, 4) === 'file') {
message = (
<div style={messageStyle}>
No store found. Most likely you did not allow access to file URLs.{' '}
<a
href="https://github.com/zalmoxisus/redux-devtools-extension/blob/master/docs/Troubleshooting.md#access-file-url-file"
target="_blank"
>
See details
</a>
.
</div>
);
}
renderNodeAtRoot(message);
store = undefined;
});
} else {
renderNodeAtRoot(message);
store = undefined;
}
}, 3500);
}
function init(id: number) {
renderNA();
bgConnection = chrome.runtime.connect({
name: id ? id.toString() : undefined,
});
bgConnection.onMessage.addListener(
<S, A extends Action<unknown>>(message: PanelMessage<S, A>) => {
if (message.type === 'NA') {
if (message.id === id) renderNA();
else store!.dispatch({ type: REMOVE_INSTANCE, id: message.id });
} else {
if (!rendered) renderDevTools();
store!.dispatch(message);
}
}
);
}
init(chrome.devtools.inspectedWindow.tabId);