diff --git a/web/src/assets/styles/keyboard.css b/web/src/assets/styles/keyboard.css index 59497ce..921d507 100644 --- a/web/src/assets/styles/keyboard.css +++ b/web/src/assets/styles/keyboard.css @@ -79,7 +79,7 @@ box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); } -.hg-layout-default .hg-button.hg-functionBtn.hg-button-space { +.hg-button.hg-functionBtn.hg-button-space { width: 250px; } @@ -87,14 +87,14 @@ width: 350px; } -.simple-keyboard.hg-layout-default .simple-keyboard.hg-layout-mac .hg-button.hg-highlight { +.simple-keyboard .hg-highlight { background: rgb(37 99 235); border-bottom: 1px solid #2563eb; box-shadow: 0 1px 3px 0 rgb(37 99 235 / 0.1), 0 1px 2px -1px rgb(37 99 235 / 0.1); color: white; } -.simple-keyboard.hg-layout-default .simple-keyboard.hg-layout-mac .hg-button.hg-double{ +.simple-keyboard .hg-button.hg-double{ text-align: center; font-size: 14px; line-height: 16px; diff --git a/web/src/lib/localstorage.ts b/web/src/lib/localstorage.ts index 5609d6d..d37e1ec 100644 --- a/web/src/lib/localstorage.ts +++ b/web/src/lib/localstorage.ts @@ -7,6 +7,7 @@ const QUALITY_KEY = 'nano-kvm-quality'; const MOUSE_STYLE_KEY = 'nano-kvm-mouse-style'; const MOUSE_MODE_KEY = 'nano-kvm-mouse-mode'; const SKIP_UPDATE_KEY = 'nano-kvm-check-update'; +const KEYBOARD_LAYOUT_KEY = 'nano-kvm-keyboard-layout'; type ItemWithExpiry = { value: string; @@ -108,3 +109,11 @@ export function setSkipUpdate(skip: boolean) { const expiry = 3 * 24 * 60 * 60 * 1000; // 3天 setWithExpiry(SKIP_UPDATE_KEY, String(skip), expiry); } + +export function setKeyboardLayout(layout: string) { + localStorage.setItem(KEYBOARD_LAYOUT_KEY, layout); +} + +export function getKeyboardLayout() { + return localStorage.getItem(KEYBOARD_LAYOUT_KEY); +} diff --git a/web/src/pages/desktop/keyboard/virtual-keyboard.tsx b/web/src/pages/desktop/keyboard/virtual-keyboard.tsx index 322c253..ebe37e1 100644 --- a/web/src/pages/desktop/keyboard/virtual-keyboard.tsx +++ b/web/src/pages/desktop/keyboard/virtual-keyboard.tsx @@ -1,16 +1,16 @@ -import { useRef, useState } from 'react'; +import { useEffect, useRef, useState } from 'react'; +import { AppleOutlined, WindowsOutlined } from '@ant-design/icons'; +import { ConfigProvider, Segmented, theme } from 'antd'; import clsx from 'clsx'; import { useAtom } from 'jotai'; import { XIcon } from 'lucide-react'; import Keyboard, { KeyboardButtonTheme } from 'react-simple-keyboard'; import { Drawer } from 'vaul'; -import { Radio } from 'antd'; -import type { RadioChangeEvent } from 'antd'; -import { useTranslation } from 'react-i18next'; import 'react-simple-keyboard/build/css/index.css'; import '@/assets/styles/keyboard.css'; +import { getKeyboardLayout, setKeyboardLayout } from '@/lib/localstorage.ts'; import { client } from '@/lib/websocket.ts'; import { isKeyboardOpenAtom } from '@/jotai/keyboard.ts'; @@ -28,22 +28,21 @@ type KeyboardProps = { isBigScreen: boolean; }; -const keyboardLayoutOptions = [ - { label: 'Win', value: 'default' }, - { label: 'Mac', value: 'mac' } -]; - export const VirtualKeyboard = ({ isBigScreen }: KeyboardProps) => { - const { t } = useTranslation(); - const [isKeyboardOpen, setIsKeyboardOpen] = useAtom(isKeyboardOpenAtom); - const [isCapsLock, setIsCapsLock] = useState(false); - const [activeModifierKeys, setActiveModifierKeys] = useState([]); const [layout, setLayout] = useState('default'); + const [activeModifierKeys, setActiveModifierKeys] = useState([]); const keyboardRef = useRef(null); + useEffect(() => { + const keyboardLayout = getKeyboardLayout(); + if (keyboardLayout && ['default', 'mac'].includes(keyboardLayout)) { + setLayout(keyboardLayout); + } + }, []); + function onKeyPress(key: string) { if (modifierKeys.includes(key)) { if (activeModifierKeys.includes(key)) { @@ -52,13 +51,10 @@ export const VirtualKeyboard = ({ isBigScreen }: KeyboardProps) => { } else { setActiveModifierKeys([...activeModifierKeys, key]); } - } else { - if (key === '{capslock}') { - setIsCapsLock(!isCapsLock); - } - - sendKeydown(key); + return; } + + sendKeydown(key); } function onKeyReleased(key: string) { @@ -126,18 +122,16 @@ export const VirtualKeyboard = ({ isBigScreen }: KeyboardProps) => { function getButtonTheme(): KeyboardButtonTheme[] { const theme = [{ class: 'hg-double', buttons: doubleKeys.join(' ') }]; - const activeKeys = [...activeModifierKeys]; - if (isCapsLock) { - activeKeys.push('{capslock}'); - } - if (activeKeys.length > 0) { - theme.push({ class: 'hg-highlight', buttons: activeKeys.join(' ') }); + if (activeModifierKeys.length > 0) { + const buttons = activeModifierKeys.join(' '); + theme.push({ class: 'hg-highlight', buttons }); } return theme; } - function selectLayout({ target: { value } }: RadioChangeEvent) { + function selectLayout(value: string) { + setKeyboardLayout(value); setLayout(value); } @@ -153,18 +147,22 @@ export const VirtualKeyboard = ({ isBigScreen }: KeyboardProps) => { {/* header */}
-
- {t('keyboard')} -
- + + }, + { label: 'Mac', value: 'mac', icon: } + ]} + value={layout} + onChange={selectLayout} + /> +
-
+
{
+