diff --git a/ui/src/assets/attach-icon.svg b/ui/src/assets/attach-icon.svg deleted file mode 100644 index 88deb80a..00000000 --- a/ui/src/assets/attach-icon.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - diff --git a/ui/src/components/VirtualKeyboard.tsx b/ui/src/components/VirtualKeyboard.tsx index 798b3fdc..77927a63 100644 --- a/ui/src/components/VirtualKeyboard.tsx +++ b/ui/src/components/VirtualKeyboard.tsx @@ -2,33 +2,31 @@ import { ChevronDownIcon } from "@heroicons/react/16/solid"; import { AnimatePresence, motion } from "framer-motion"; import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import Keyboard from "react-simple-keyboard"; +import { LuKeyboard } from "react-icons/lu"; import Card from "@components/Card"; // eslint-disable-next-line import/order -import { Button } from "@components/Button"; +import { Button, LinkButton } from "@components/Button"; import "react-simple-keyboard/build/css/index.css"; -import AttachIconRaw from "@/assets/attach-icon.svg"; import DetachIconRaw from "@/assets/detach-icon.svg"; import { cx } from "@/cva.config"; import { useHidStore, useUiStore } from "@/hooks/stores"; import useKeyboard from "@/hooks/useKeyboard"; import useKeyboardLayout from "@/hooks/useKeyboardLayout"; -import { keys, modifiers, latchingKeys, decodeModifiers } from "@/keyboardMappings"; +import { decodeModifiers, keys, latchingKeys, modifiers } from "@/keyboardMappings"; export const DetachIcon = ({ className }: { className?: string }) => { return Detach Icon; }; -const AttachIcon = ({ className }: { className?: string }) => { - return Attach Icon; -}; - function KeyboardWrapper() { const keyboardRef = useRef(null); - const { isAttachedVirtualKeyboardVisible, setAttachedVirtualKeyboardVisibility } = useUiStore(); - const { keysDownState, /* keyboardLedState,*/ isVirtualKeyboardEnabled, setVirtualKeyboardEnabled } = useHidStore(); + const { isAttachedVirtualKeyboardVisible, setAttachedVirtualKeyboardVisibility } = + useUiStore(); + const { keysDownState, isVirtualKeyboardEnabled, setVirtualKeyboardEnabled } = + useHidStore(); const { handleKeyPress, executeMacro } = useKeyboard(); const { selectedKeyboard } = useKeyboardLayout(); @@ -44,29 +42,28 @@ function KeyboardWrapper() { return selectedKeyboard.virtualKeyboard; }, [selectedKeyboard]); - //const isCapsLockActive = useMemo(() => { - // return (keyboardLedState.caps_lock); - //}, [keyboardLedState]); - - const { isShiftActive, /*isControlActive, isAltActive, isMetaActive, isAltGrActive*/ } = useMemo(() => { + const { isShiftActive } = useMemo(() => { return decodeModifiers(keysDownState.modifier); }, [keysDownState]); const mainLayoutName = useMemo(() => { - const layoutName = isShiftActive ? "shift": "default"; - return layoutName; + return isShiftActive ? "shift" : "default"; }, [isShiftActive]); const keyNamesForDownKeys = useMemo(() => { const activeModifierMask = keysDownState.modifier || 0; - const modifierNames = Object.entries(modifiers).filter(([_, mask]) => (activeModifierMask & mask) !== 0).map(([name, _]) => name); + const modifierNames = Object.entries(modifiers) + .filter(([_, mask]) => (activeModifierMask & mask) !== 0) + .map(([name, _]) => name); const keysDown = keysDownState.keys || []; - const keyNames = Object.entries(keys).filter(([_, value]) => keysDown.includes(value)).map(([name, _]) => name); + const keyNames = Object.entries(keys) + .filter(([_, value]) => keysDown.includes(value)) + .map(([name, _]) => name); - return [...modifierNames,...keyNames, ' ']; // we have to have at least one space to avoid keyboard whining + return [...modifierNames, ...keyNames, " "]; // we have to have at least one space to avoid keyboard whining }, [keysDownState]); - + const startDrag = useCallback((e: MouseEvent | TouchEvent) => { if (!keyboardRef.current) return; if (e instanceof TouchEvent && e.touches.length > 1) return; @@ -110,6 +107,9 @@ function KeyboardWrapper() { }, []); useEffect(() => { + // Is the keyboard detached or attached? + if (isAttachedVirtualKeyboardVisible) return; + const handle = keyboardRef.current; if (handle) { handle.addEventListener("touchstart", startDrag); @@ -134,15 +134,12 @@ function KeyboardWrapper() { document.removeEventListener("mousemove", onDrag); document.removeEventListener("touchmove", onDrag); }; - }, [endDrag, onDrag, startDrag]); + }, [isAttachedVirtualKeyboardVisible, endDrag, onDrag, startDrag]); - const onKeyUp = useCallback( - async (_: string, e: MouseEvent | undefined) => { - e?.preventDefault(); - e?.stopPropagation(); - }, - [] - ); + const onKeyUp = useCallback(async (_: string, e: MouseEvent | undefined) => { + e?.preventDefault(); + e?.stopPropagation(); + }, []); const onKeyDown = useCallback( async (key: string, e: MouseEvent | undefined) => { @@ -151,24 +148,30 @@ function KeyboardWrapper() { // handle the fake key-macros we have defined for common combinations if (key === "CtrlAltDelete") { - await executeMacro([ { keys: ["Delete"], modifiers: ["ControlLeft", "AltLeft"], delay: 100 } ]); + await executeMacro([ + { keys: ["Delete"], modifiers: ["ControlLeft", "AltLeft"], delay: 100 }, + ]); return; } if (key === "AltMetaEscape") { - await executeMacro([ { keys: ["Escape"], modifiers: ["AltLeft", "MetaLeft"], delay: 100 } ]); + await executeMacro([ + { keys: ["Escape"], modifiers: ["AltLeft", "MetaLeft"], delay: 100 }, + ]); return; } if (key === "CtrlAltBackspace") { - await executeMacro([ { keys: ["Backspace"], modifiers: ["ControlLeft", "AltLeft"], delay: 100 } ]); + await executeMacro([ + { keys: ["Backspace"], modifiers: ["ControlLeft", "AltLeft"], delay: 100 }, + ]); return; } // if they press any of the latching keys, we send a keypress down event and the release it automatically (on timer) if (latchingKeys.includes(key)) { console.debug(`Latching key pressed: ${key} sending down and delayed up pair`); - handleKeyPress(keys[key], true) + handleKeyPress(keys[key], true); setTimeout(() => handleKeyPress(keys[key], false), 100); return; } @@ -176,8 +179,10 @@ function KeyboardWrapper() { // if they press any of the dynamic keys, we send a keypress down event but we don't release it until they click it again if (Object.keys(modifiers).includes(key)) { const currentlyDown = keyNamesForDownKeys.includes(key); - console.debug(`Dynamic key pressed: ${key} was currently down: ${currentlyDown}, toggling state`); - handleKeyPress(keys[key], !currentlyDown) + console.debug( + `Dynamic key pressed: ${key} was currently down: ${currentlyDown}, toggling state`, + ); + handleKeyPress(keys[key], !currentlyDown); return; } @@ -211,7 +216,7 @@ function KeyboardWrapper() {
@@ -241,15 +246,22 @@ function KeyboardWrapper() { size="XS" theme="light" text="Attach" - LeadingIcon={AttachIcon} onClick={() => setAttachedVirtualKeyboardVisibility(true)} /> )}
-

- Virtual Keyboard - {selectedKeyboard.name} +

+ Virtual Keyboard

-
+
+ +
- { /* TODO add optional number pad */ } + {/* TODO add optional number pad */}