mirror of
https://github.com/reduxjs/redux-devtools.git
synced 2025-04-25 10:43:43 +03:00
112 lines
3.2 KiB
TypeScript
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);
|