|
1 | | -import { useEffect } from "react"; |
| 1 | +import { useEffect, useMemo } from "react"; |
2 | 2 |
|
3 | 3 | import { cx } from "@/cva.config"; |
4 | 4 | import { |
| 5 | + HidState, |
| 6 | + KeysDownState, |
| 7 | + MouseState, |
| 8 | + RTCState, |
| 9 | + SettingsState, |
5 | 10 | useHidStore, |
6 | 11 | useMouseStore, |
7 | 12 | useRTCStore, |
8 | 13 | useSettingsStore, |
9 | 14 | useVideoStore, |
| 15 | + VideoState, |
10 | 16 | } from "@/hooks/stores"; |
11 | 17 | import { keys, modifiers } from "@/keyboardMappings"; |
12 | 18 |
|
13 | 19 | export default function InfoBar() { |
14 | | - const activeKeys = useHidStore(state => state.activeKeys); |
15 | | - const activeModifiers = useHidStore(state => state.activeModifiers); |
16 | | - const mouseX = useMouseStore(state => state.mouseX); |
17 | | - const mouseY = useMouseStore(state => state.mouseY); |
18 | | - const mouseMove = useMouseStore(state => state.mouseMove); |
| 20 | + const keysDownState = useHidStore((state: HidState) => state.keysDownState); |
| 21 | + const mouseX = useMouseStore((state: MouseState) => state.mouseX); |
| 22 | + const mouseY = useMouseStore((state: MouseState) => state.mouseY); |
| 23 | + const mouseMove = useMouseStore((state: MouseState) => state.mouseMove); |
19 | 24 |
|
20 | 25 | const videoClientSize = useVideoStore( |
21 | | - state => `${Math.round(state.clientWidth)}x${Math.round(state.clientHeight)}`, |
| 26 | + (state: VideoState) => `${Math.round(state.clientWidth)}x${Math.round(state.clientHeight)}`, |
22 | 27 | ); |
23 | 28 |
|
24 | 29 | const videoSize = useVideoStore( |
25 | | - state => `${Math.round(state.width)}x${Math.round(state.height)}`, |
| 30 | + (state: VideoState) => `${Math.round(state.width)}x${Math.round(state.height)}`, |
26 | 31 | ); |
27 | 32 |
|
28 | | - const rpcDataChannel = useRTCStore(state => state.rpcDataChannel); |
| 33 | + const rpcDataChannel = useRTCStore((state: RTCState) => state.rpcDataChannel); |
29 | 34 |
|
30 | 35 | const settings = useSettingsStore(); |
31 | | - const showPressedKeys = useSettingsStore(state => state.showPressedKeys); |
| 36 | + const showPressedKeys = useSettingsStore((state: SettingsState) => state.showPressedKeys); |
32 | 37 |
|
33 | 38 | useEffect(() => { |
34 | 39 | if (!rpcDataChannel) return; |
35 | 40 | rpcDataChannel.onclose = () => console.log("rpcDataChannel has closed"); |
36 | | - rpcDataChannel.onerror = e => |
| 41 | + rpcDataChannel.onerror = (e: Event) => |
37 | 42 | console.log(`Error on DataChannel '${rpcDataChannel.label}': ${e}`); |
38 | 43 | }, [rpcDataChannel]); |
39 | 44 |
|
40 | | - const keyboardLedState = useHidStore(state => state.keyboardLedState); |
41 | | - const isTurnServerInUse = useRTCStore(state => state.isTurnServerInUse); |
| 45 | + const keyboardLedState = useHidStore((state: HidState) => state.keyboardLedState); |
| 46 | + const isTurnServerInUse = useRTCStore((state: RTCState) => state.isTurnServerInUse); |
42 | 47 |
|
43 | | - const usbState = useHidStore(state => state.usbState); |
44 | | - const hdmiState = useVideoStore(state => state.hdmiState); |
| 48 | + const usbState = useHidStore((state: HidState) => state.usbState); |
| 49 | + const hdmiState = useVideoStore((state: VideoState) => state.hdmiState); |
| 50 | + |
| 51 | + const displayKeys = useMemo(() => { |
| 52 | + if (!showPressedKeys || !keysDownState) |
| 53 | + return ""; |
| 54 | + |
| 55 | + const state = keysDownState as KeysDownState; |
| 56 | + const activeModifierMask = state.modifier || 0; |
| 57 | + const keysDown = state.keys || []; |
| 58 | + const modifierNames = Object.entries(modifiers).filter(([_, mask]) => (activeModifierMask & mask) !== 0).map(([name, _]) => name); |
| 59 | + const keyNames = Object.entries(keys).filter(([_, value]) => keysDown.includes(value)).map(([name, _]) => name); |
| 60 | + |
| 61 | + return [...modifierNames,...keyNames].join(", "); |
| 62 | + }, [keysDownState, showPressedKeys]); |
45 | 63 |
|
46 | 64 | return ( |
47 | 65 | <div className="bg-white border-t border-t-slate-800/30 text-slate-800 dark:border-t-slate-300/20 dark:bg-slate-900 dark:text-slate-300"> |
@@ -99,14 +117,7 @@ export default function InfoBar() { |
99 | 117 | <div className="flex items-center gap-x-1"> |
100 | 118 | <span className="text-xs font-semibold">Keys:</span> |
101 | 119 | <h2 className="text-xs"> |
102 | | - {[ |
103 | | - ...activeKeys.map( |
104 | | - x => Object.entries(keys).filter(y => y[1] === x)[0][0], |
105 | | - ), |
106 | | - activeModifiers.map( |
107 | | - x => Object.entries(modifiers).filter(y => y[1] === x)[0][0], |
108 | | - ), |
109 | | - ].join(", ")} |
| 120 | + {displayKeys} |
110 | 121 | </h2> |
111 | 122 | </div> |
112 | 123 | )} |
|
0 commit comments