From 3ba5bf92eb47b0f7a3f10f984d4feef50c09c6a3 Mon Sep 17 00:00:00 2001 From: Cyril Date: Tue, 13 Jan 2026 11:38:54 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8(frontend)=20real-time=20shortcut=20sy?= =?UTF-8?q?nc=20via=20valtio=20store?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Shortcut changes in settings menu now update tooltip instantly. --- .../settings/components/tabs/ShortcutTab.tsx | 70 +++++++++---------- src/frontend/src/stores/shortcutOverrides.ts | 27 +++++++ 2 files changed, 59 insertions(+), 38 deletions(-) diff --git a/src/frontend/src/features/settings/components/tabs/ShortcutTab.tsx b/src/frontend/src/features/settings/components/tabs/ShortcutTab.tsx index 767a9be5..56d25604 100644 --- a/src/frontend/src/features/settings/components/tabs/ShortcutTab.tsx +++ b/src/frontend/src/features/settings/components/tabs/ShortcutTab.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect, useMemo, useState } from 'react' +import React, { useCallback, useMemo, useState } from 'react' import { Shortcut } from '@/features/shortcuts/types' import { shortcutCatalog } from '@/features/shortcuts/catalog' import { @@ -12,27 +12,13 @@ import { useTranslation } from 'react-i18next' import { text } from '@/primitives/Text' import { buttonRecipe } from '@/primitives/buttonRecipe' import { TabPanel, type TabPanelProps } from '@/primitives/Tabs' - -type ShortcutOverrides = Record - -const STORAGE_KEY = 'shortcuts:overrides' - -const loadOverrides = (): ShortcutOverrides => { - if (typeof window === 'undefined') return {} - try { - const raw = localStorage.getItem(STORAGE_KEY) - if (!raw) return {} - return JSON.parse(raw) as ShortcutOverrides - } catch (e) { - console.warn('Failed to parse shortcut overrides', e) - return {} - } -} - -const saveOverrides = (overrides: ShortcutOverrides) => { - if (typeof window === 'undefined') return - localStorage.setItem(STORAGE_KEY, JSON.stringify(overrides)) -} +import { useSnapshot } from 'valtio' +import { + loadShortcutOverrides, + removeOverride, + setOverride, + shortcutOverridesStore, +} from '@/stores/shortcutOverrides' const rowStyle = css({ display: 'grid', @@ -63,24 +49,18 @@ const ShortcutTab = ({ id }: Pick) => { t(key, { ns: 'rooms', ...options }), [t] ) - const [overrides, setOverrides] = useState({}) + loadShortcutOverrides() + const { overrides } = useSnapshot(shortcutOverridesStore) const [editingId, setEditingId] = useState(null) const [confirmationMessage, setConfirmationMessage] = useState('') - useEffect(() => { - setOverrides(loadOverrides()) - }, []) - const handleStartEdit = useCallback((shortcutId: string) => { setEditingId(shortcutId) }, []) const handleReset = useCallback( (shortcutId: string) => { - const next = { ...overrides } - delete next[shortcutId] - setOverrides(next) - saveOverrides(next) + removeOverride(shortcutId) setConfirmationMessage( t('shortcutsEditor.resetConfirmation', { defaultValue: 'Shortcut reset', @@ -88,7 +68,7 @@ const ShortcutTab = ({ id }: Pick) => { ) setTimeout(() => setConfirmationMessage(''), 3000) }, - [overrides, t] + [t] ) const handleKeyCapture = useCallback( @@ -111,9 +91,7 @@ const ShortcutTab = ({ id }: Pick) => { shiftKey, altKey, } - const next = { ...overrides, [shortcutId]: normalized } - setOverrides(next) - saveOverrides(next) + setOverride(shortcutId, normalized) setEditingId(null) setConfirmationMessage( t('shortcutsEditor.modifiedConfirmation', { @@ -122,12 +100,28 @@ const ShortcutTab = ({ id }: Pick) => { ) setTimeout(() => setConfirmationMessage(''), 3000) }, - [overrides, t] + [t] + ) + + const handleEditButtonKeyDown = useCallback( + (e: React.KeyboardEvent, shortcutId: string) => { + // If already in edit mode, capture the key + if (editingId === shortcutId) { + handleKeyCapture(e, shortcutId) + return + } + // Otherwise, if it's Enter or Space, start edit mode (like a click) + if (e.key === 'Enter' || e.key === ' ') { + e.preventDefault() + handleStartEdit(shortcutId) + } + }, + [editingId, handleKeyCapture, handleStartEdit] ) const rows = useMemo(() => { return shortcutCatalog.map((item) => { - const override = overrides[item.id] + const override = overrides.get(item.id) const effectiveShortcut = override ?? item.shortcut const visualShortcut = item.kind === 'longPress' @@ -260,7 +254,7 @@ const ShortcutTab = ({ id }: Pick) => {