refactor: devtools
This commit is contained in:
parent
6526989db6
commit
8ae9daa9ba
|
@ -1,52 +1,37 @@
|
|||
import {useCallback, useState} from 'react';
|
||||
import {useEffect} from 'react';
|
||||
import {Tab, Tabs, TabList, TabPanel} from 'react-tabs';
|
||||
import 'react-tabs/style/react-tabs.css';
|
||||
|
||||
import {useClient} from '@/react/context/client.js';
|
||||
import {useEcsTick} from '@/react/context/ecs.js';
|
||||
import {useMainEntity} from '@/react/context/main-entity.js';
|
||||
|
||||
import styles from './devtools.module.css';
|
||||
|
||||
import Tiles from './devtools/tiles.jsx';
|
||||
import TabComponents from './devtools/components.js';
|
||||
|
||||
export default function Devtools({
|
||||
eventsChannel,
|
||||
}) {
|
||||
const client = useClient();
|
||||
const mainEntityRef = useMainEntity();
|
||||
const [mainEntityJson, setMainEntityJson] = useState('');
|
||||
const onEcsTick = useCallback((payload, ecs) => {
|
||||
if (!mainEntityRef.current) {
|
||||
return;
|
||||
useEffect(() => {
|
||||
if (import.meta.hot) {
|
||||
const updating = new Set(TabComponents.map(([path]) => path));
|
||||
import.meta.hot.on('vite:afterUpdate', ({updates}) => {
|
||||
if (updates.some(({path}) => updating.has(path))) {
|
||||
import.meta.hot.invalidate();
|
||||
}
|
||||
});
|
||||
}
|
||||
setMainEntityJson(JSON.stringify(ecs.get(mainEntityRef.current), null, 2));
|
||||
}, [mainEntityRef]);
|
||||
useEcsTick(onEcsTick);
|
||||
}, []);
|
||||
return (
|
||||
<div className={styles.devtools}>
|
||||
<Tabs>
|
||||
<TabList>
|
||||
<Tab>Dashboard</Tab>
|
||||
<Tab>Tiles</Tab>
|
||||
{TabComponents.map(([path, {displayName}]) => <Tab key={path}>{displayName}</Tab>)}
|
||||
</TabList>
|
||||
<TabPanel>
|
||||
<div className={styles.dashboard}>
|
||||
<form>
|
||||
<div className={styles.engineBar}>
|
||||
<div>{Math.round(client.rtt * 100) / 100}rtt</div>
|
||||
<div>{Math.round(((client.throughput.down * 8) / 1024) * 10) / 10}kb/s down</div>
|
||||
<div>{Math.round(((client.throughput.up * 8) / 1024) * 10) / 10}kb/s up</div>
|
||||
</div>
|
||||
</form>
|
||||
<pre><code><small>{mainEntityJson}</small></code></pre>
|
||||
</div>
|
||||
</TabPanel>
|
||||
<TabPanel>
|
||||
<Tiles
|
||||
eventsChannel={eventsChannel}
|
||||
/>
|
||||
</TabPanel>
|
||||
{TabComponents.map(([path, TabComponent]) => (
|
||||
<TabPanel key={path}>
|
||||
<TabComponent
|
||||
eventsChannel={eventsChannel}
|
||||
/>
|
||||
</TabPanel>
|
||||
))}
|
||||
</Tabs>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,9 +1,3 @@
|
|||
.engineBar {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
margin-bottom: 16px 0;
|
||||
}
|
||||
|
||||
.devtools {
|
||||
background-color: #444444;
|
||||
color: white;
|
||||
|
@ -43,10 +37,3 @@
|
|||
background-color: #00000044;
|
||||
}
|
||||
}
|
||||
|
||||
.dashboard {
|
||||
margin: 16px;
|
||||
pre {
|
||||
user-select: text;
|
||||
}
|
||||
}
|
||||
|
|
7
app/react/components/devtools/components.js
Normal file
7
app/react/components/devtools/components.js
Normal file
|
@ -0,0 +1,7 @@
|
|||
const entries = Object.entries(
|
||||
import.meta.glob('./*.jsx', {eager: true}),
|
||||
);
|
||||
|
||||
export default entries
|
||||
.filter(([, M]) => M.default)
|
||||
.map(([path, M]) => ([new URL(path, import.meta.url).pathname, M.default]));
|
36
app/react/components/devtools/dashboard.jsx
Normal file
36
app/react/components/devtools/dashboard.jsx
Normal file
|
@ -0,0 +1,36 @@
|
|||
import {useCallback, useState} from 'react';
|
||||
|
||||
import {useClient} from '@/react/context/client.js';
|
||||
import {useEcsTick} from '@/react/context/ecs.js';
|
||||
import {useMainEntity} from '@/react/context/main-entity.js';
|
||||
|
||||
import styles from './dashboard.module.css';
|
||||
|
||||
function Dashboard() {
|
||||
const client = useClient();
|
||||
const mainEntityRef = useMainEntity();
|
||||
const [mainEntityJson, setMainEntityJson] = useState('');
|
||||
const onEcsTick = useCallback((payload, ecs) => {
|
||||
if (!mainEntityRef.current) {
|
||||
return;
|
||||
}
|
||||
setMainEntityJson(JSON.stringify(ecs.get(mainEntityRef.current), null, 2));
|
||||
}, [mainEntityRef]);
|
||||
useEcsTick(onEcsTick);
|
||||
return (
|
||||
<div className={styles.dashboard}>
|
||||
<form>
|
||||
<div className={styles.engineBar}>
|
||||
<div>{Math.round(client.rtt * 100) / 100}rtt</div>
|
||||
<div>{Math.round(((client.throughput.down * 8) / 1024) * 10) / 10}kb/s down</div>
|
||||
<div>{Math.round(((client.throughput.up * 8) / 1024) * 10) / 10}kb/s up</div>
|
||||
</div>
|
||||
</form>
|
||||
<pre><code><small>{mainEntityJson}</small></code></pre>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Dashboard.displayName = 'Dashboard';
|
||||
|
||||
export default Dashboard;
|
12
app/react/components/devtools/dashboard.module.css
Normal file
12
app/react/components/devtools/dashboard.module.css
Normal file
|
@ -0,0 +1,12 @@
|
|||
.dashboard {
|
||||
margin: 16px;
|
||||
pre {
|
||||
user-select: text;
|
||||
}
|
||||
}
|
||||
|
||||
.engineBar {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
margin-bottom: 16px 0;
|
||||
}
|
|
@ -6,7 +6,7 @@ import useRect from '@/react/hooks/use-rect.js';
|
|||
|
||||
import styles from './tiles.module.css';
|
||||
|
||||
export default function Tiles({eventsChannel}) {
|
||||
function Tiles({eventsChannel}) {
|
||||
const client = useClient();
|
||||
const wrapperRef = useRef();
|
||||
const imageRef = useRef();
|
||||
|
@ -228,4 +228,8 @@ export default function Tiles({eventsChannel}) {
|
|||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Tiles.displayName = 'Tiles';
|
||||
|
||||
export default Tiles;
|
||||
|
|
Loading…
Reference in New Issue
Block a user