Merge branch 'jetkvm:dev' into feat/local-web-server-loopback-mode

This commit is contained in:
Alex Goodkind 2025-05-24 09:03:47 -07:00 committed by GitHub
commit c2b4c5b243
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 33 additions and 20 deletions

View File

@ -1,4 +1,4 @@
import { useCallback, useEffect, useRef, useState } from "react"; import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { LuCornerDownLeft } from "react-icons/lu"; import { LuCornerDownLeft } from "react-icons/lu";
import { ExclamationCircleIcon } from "@heroicons/react/16/solid"; import { ExclamationCircleIcon } from "@heroicons/react/16/solid";
import { useClose } from "@headlessui/react"; import { useClose } from "@headlessui/react";
@ -39,6 +39,13 @@ export default function PasteModal() {
state => state.setKeyboardLayout, state => state.setKeyboardLayout,
); );
// this ensures we always get the original en-US if it hasn't been set yet
const safeKeyboardLayout = useMemo(() => {
if (keyboardLayout && keyboardLayout.length > 0)
return keyboardLayout;
return "en-US";
}, [keyboardLayout]);
useEffect(() => { useEffect(() => {
send("getKeyboardLayout", {}, resp => { send("getKeyboardLayout", {}, resp => {
if ("error" in resp) return; if ("error" in resp) return;
@ -56,14 +63,13 @@ export default function PasteModal() {
setPasteMode(false); setPasteMode(false);
setDisableVideoFocusTrap(false); setDisableVideoFocusTrap(false);
if (rpcDataChannel?.readyState !== "open" || !TextAreaRef.current) return; if (rpcDataChannel?.readyState !== "open" || !TextAreaRef.current) return;
if (!keyboardLayout) return; if (!safeKeyboardLayout) return;
if (!chars[keyboardLayout]) return; if (!chars[safeKeyboardLayout]) return;
const text = TextAreaRef.current.value; const text = TextAreaRef.current.value;
try { try {
for (const char of text) { for (const char of text) {
const { key, shift, altRight, deadKey, accentKey } = chars[keyboardLayout][char] const { key, shift, altRight, deadKey, accentKey } = chars[safeKeyboardLayout][char]
if (!key) continue; if (!key) continue;
const keyz = [ keys[key] ]; const keyz = [ keys[key] ];
@ -98,7 +104,7 @@ export default function PasteModal() {
console.error(error); console.error(error);
notifications.error("Failed to paste text"); notifications.error("Failed to paste text");
} }
}, [rpcDataChannel?.readyState, send, setDisableVideoFocusTrap, setPasteMode, keyboardLayout]); }, [rpcDataChannel?.readyState, send, setDisableVideoFocusTrap, setPasteMode, safeKeyboardLayout]);
useEffect(() => { useEffect(() => {
if (TextAreaRef.current) { if (TextAreaRef.current) {
@ -148,7 +154,7 @@ export default function PasteModal() {
// @ts-expect-error TS doesn't recognize Intl.Segmenter in some environments // @ts-expect-error TS doesn't recognize Intl.Segmenter in some environments
[...new Intl.Segmenter().segment(value)] [...new Intl.Segmenter().segment(value)]
.map(x => x.segment) .map(x => x.segment)
.filter(char => !chars[keyboardLayout][char]), .filter(char => !chars[safeKeyboardLayout][char]),
), ),
]; ];
@ -169,7 +175,7 @@ export default function PasteModal() {
</div> </div>
<div className="space-y-4"> <div className="space-y-4">
<p className="text-xs text-slate-600 dark:text-slate-400"> <p className="text-xs text-slate-600 dark:text-slate-400">
Sending text using keyboard layout: {layouts[keyboardLayout]} Sending text using keyboard layout: {layouts[safeKeyboardLayout]}
</p> </p>
</div> </div>
</div> </div>

View File

@ -1,4 +1,4 @@
import { useCallback, useEffect } from "react"; import { useCallback, useEffect, useMemo } from "react";
import { KeyboardLedSync, useSettingsStore } from "@/hooks/stores"; import { KeyboardLedSync, useSettingsStore } from "@/hooks/stores";
import { useJsonRpc } from "@/hooks/useJsonRpc"; import { useJsonRpc } from "@/hooks/useJsonRpc";
@ -20,6 +20,13 @@ export default function SettingsKeyboardRoute() {
state => state.setKeyboardLedSync, state => state.setKeyboardLedSync,
); );
// this ensures we always get the original en-US if it hasn't been set yet
const safeKeyboardLayout = useMemo(() => {
if (keyboardLayout && keyboardLayout.length > 0)
return keyboardLayout;
return "en-US";
}, [keyboardLayout]);
const layoutOptions = Object.entries(layouts).map(([code, language]) => { return { value: code, label: language } }) const layoutOptions = Object.entries(layouts).map(([code, language]) => { return { value: code, label: language } })
const ledSyncOptions = [ const ledSyncOptions = [
{ value: "auto", label: "Automatic" }, { value: "auto", label: "Automatic" },
@ -69,7 +76,7 @@ export default function SettingsKeyboardRoute() {
size="SM" size="SM"
label="" label=""
fullWidth fullWidth
value={keyboardLayout} value={safeKeyboardLayout}
onChange={onKeyboardLayoutChange} onChange={onKeyboardLayoutChange}
options={layoutOptions} options={layoutOptions}
/> />