From e05f9fa17e1e0480b80b89b0b3fcf55bb86b2857 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Wed, 15 Jul 2026 00:30:28 -0400 Subject: [PATCH] refac --- src/lib/components/chat/Settings/About.svelte | 2 +- .../components/chat/Settings/Account.svelte | 2 +- .../chat/Settings/ArchivedChats.svelte | 2 +- src/lib/components/chat/Settings/Audio.svelte | 2 +- .../chat/Settings/Connections.svelte | 2 +- .../chat/Settings/DataControls.svelte | 2 +- .../components/chat/Settings/General.svelte | 2 +- .../chat/Settings/Integrations.svelte | 2 +- .../components/chat/Settings/Interface.svelte | 2 +- .../chat/Settings/Personalization.svelte | 2 +- .../components/chat/Settings/Shortcuts.svelte | 105 ++++++++++++++ src/lib/components/chat/SettingsModal.svelte | 54 ++++++- src/lib/components/chat/ShortcutItem.svelte | 52 ++++--- src/lib/components/chat/ShortcutsModal.svelte | 135 ------------------ .../components/layout/Sidebar/UserMenu.svelte | 14 +- src/lib/stores/index.ts | 1 - src/routes/(app)/+layout.svelte | 4 +- 17 files changed, 201 insertions(+), 184 deletions(-) create mode 100644 src/lib/components/chat/Settings/Shortcuts.svelte delete mode 100644 src/lib/components/chat/ShortcutsModal.svelte diff --git a/src/lib/components/chat/Settings/About.svelte b/src/lib/components/chat/Settings/About.svelte index da02daa485..f6c56c5eef 100644 --- a/src/lib/components/chat/Settings/About.svelte +++ b/src/lib/components/chat/Settings/About.svelte @@ -45,7 +45,7 @@
-
+
diff --git a/src/lib/components/chat/Settings/Account.svelte b/src/lib/components/chat/Settings/Account.svelte index 6d238d61aa..82ac098e5e 100644 --- a/src/lib/components/chat/Settings/Account.svelte +++ b/src/lib/components/chat/Settings/Account.svelte @@ -125,7 +125,7 @@
-
+

{$i18n.t('Account')}

diff --git a/src/lib/components/chat/Settings/ArchivedChats.svelte b/src/lib/components/chat/Settings/ArchivedChats.svelte index ccc03145d6..d572b28e5b 100644 --- a/src/lib/components/chat/Settings/ArchivedChats.svelte +++ b/src/lib/components/chat/Settings/ArchivedChats.svelte @@ -174,7 +174,7 @@ />
-
+
{$i18n.t('Conversations')} diff --git a/src/lib/components/chat/Settings/Audio.svelte b/src/lib/components/chat/Settings/Audio.svelte index 478725a40d..4fcc4cc028 100644 --- a/src/lib/components/chat/Settings/Audio.svelte +++ b/src/lib/components/chat/Settings/Audio.svelte @@ -175,7 +175,7 @@ dispatch('save'); }} > -
+
{$i18n.t('STT Settings')} diff --git a/src/lib/components/chat/Settings/Connections.svelte b/src/lib/components/chat/Settings/Connections.svelte index d1e9e68e2d..a29d9ba630 100644 --- a/src/lib/components/chat/Settings/Connections.svelte +++ b/src/lib/components/chat/Settings/Connections.svelte @@ -76,7 +76,7 @@ updateHandler(); }} > -
+
{#if config !== null}
diff --git a/src/lib/components/chat/Settings/DataControls.svelte b/src/lib/components/chat/Settings/DataControls.svelte index ee32d79b7d..001193d889 100644 --- a/src/lib/components/chat/Settings/DataControls.svelte +++ b/src/lib/components/chat/Settings/DataControls.svelte @@ -133,7 +133,7 @@ />
-
+
-
+
{$i18n.t('WebUI Settings')} diff --git a/src/lib/components/chat/Settings/Integrations.svelte b/src/lib/components/chat/Settings/Integrations.svelte index 926b718b40..7ce3e27f9d 100644 --- a/src/lib/components/chat/Settings/Integrations.svelte +++ b/src/lib/components/chat/Settings/Integrations.svelte @@ -80,7 +80,7 @@ updateHandler(); }} > -
+
{#if servers !== null}
diff --git a/src/lib/components/chat/Settings/Interface.svelte b/src/lib/components/chat/Settings/Interface.svelte index 9bf888c130..85ec5c4c06 100644 --- a/src/lib/components/chat/Settings/Interface.svelte +++ b/src/lib/components/chat/Settings/Interface.svelte @@ -335,7 +335,7 @@ }} /> -
+

{$i18n.t('UI')}

diff --git a/src/lib/components/chat/Settings/Personalization.svelte b/src/lib/components/chat/Settings/Personalization.svelte index fe8a1eaba1..a0384a3450 100644 --- a/src/lib/components/chat/Settings/Personalization.svelte +++ b/src/lib/components/chat/Settings/Personalization.svelte @@ -29,7 +29,7 @@ dispatch('save'); }} > -
+
+ import { getContext, onMount } from 'svelte'; + import type { Writable } from 'svelte/store'; + import { shortcuts } from '$lib/shortcuts'; + import { settings } from '$lib/stores'; + import ShortcutItem from '../ShortcutItem.svelte'; + + type ShortcutDefinition = NonNullable<(typeof shortcuts)[keyof typeof shortcuts]>; + type CategorizedShortcuts = { + [category: string]: ShortcutDefinition[]; + }; + + const i18n: Writable = getContext('i18n'); + + let categorizedShortcuts: CategorizedShortcuts = {}; + let isMac = false; + + onMount(() => { + isMac = /Mac/i.test(navigator.userAgent); + }); + + $: { + const allShortcuts = Object.values(shortcuts).filter((shortcut) => { + if (!shortcut.setting) { + return true; + } + return ($settings as Record)[shortcut.setting.id] === shortcut.setting.value; + }); + + categorizedShortcuts = allShortcuts.reduce((acc, shortcut) => { + const category = shortcut.category; + if (!acc[category]) { + acc[category] = []; + } + acc[category].push(shortcut); + return acc; + }, {}); + } + + +
+
+
+ + {$i18n.t('Command')} + + + {$i18n.t('Key')} + +
+ + {#each Object.entries(categorizedShortcuts) as [category, items], categoryIndex} +
0 ? 'mt-3' : ''}> +
+ {$i18n.t(category)} +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {#each items as shortcut} + + {/each} +
+
+ {/each} +
+
diff --git a/src/lib/components/chat/SettingsModal.svelte b/src/lib/components/chat/SettingsModal.svelte index b289c65598..91dae84da0 100644 --- a/src/lib/components/chat/SettingsModal.svelte +++ b/src/lib/components/chat/SettingsModal.svelte @@ -12,6 +12,7 @@ import About from './Settings/About.svelte'; import General from './Settings/General.svelte'; import Interface from './Settings/Interface.svelte'; + import Shortcuts from './Settings/Shortcuts.svelte'; import Audio from './Settings/Audio.svelte'; import DataControls from './Settings/DataControls.svelte'; import ArchivedChats from './Settings/ArchivedChats.svelte'; @@ -31,17 +32,32 @@ import UserBadgeCheck from '../icons/UserBadgeCheck.svelte'; import ArchiveBox from '../icons/ArchiveBox.svelte'; import ChevronLeft from '../icons/ChevronLeft.svelte'; + import Keyboard from '../icons/Keyboard.svelte'; const i18n: Writable = getContext('i18n'); export let show: boolean | string = false; + let modalShow = false; + let lastShow: boolean | string = false; - $: if (show) { + $: if (show !== lastShow) { + lastShow = show; if (typeof show === 'string') { selectedTab = show; show = true; + lastShow = true; + modalShow = true; + } else { + modalShow = show; + if (!show) { + selectedTab = 'general'; + } } - } else { + } + + $: if (!modalShow && show !== false) { + show = false; + lastShow = false; selectedTab = 'general'; } @@ -211,6 +227,21 @@ 'web search in chat' ] }, + { + id: 'shortcuts', + title: 'Keyboard Shortcuts', + keywords: [ + 'commands', + 'hotkeys', + 'keyboard', + 'keyboard shortcuts', + 'keybindings', + 'keys', + 'shortcut', + 'shortcuts', + 'show shortcuts' + ] + }, { id: 'connections', title: 'Connections', @@ -593,8 +624,8 @@
- - {#each Object.entries(categorizedShortcuts) as [category, items], categoryIndex} - {#if categoryIndex > 0} -
-
-
- {/if} - -
-
{$i18n.t(category)}
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {#each items as shortcut} -
- -
- {/each} -
-
-
- {/each} -
- - - diff --git a/src/lib/components/layout/Sidebar/UserMenu.svelte b/src/lib/components/layout/Sidebar/UserMenu.svelte index 3297d917ba..ad43d01faf 100644 --- a/src/lib/components/layout/Sidebar/UserMenu.svelte +++ b/src/lib/components/layout/Sidebar/UserMenu.svelte @@ -7,15 +7,7 @@ import { getUsage } from '$lib/apis'; import { getSessionUser, userSignOut } from '$lib/apis/auths'; - import { - showSettings, - mobile, - showSidebar, - showShortcuts, - user, - config, - settings - } from '$lib/stores'; + import { showSettings, mobile, showSidebar, user, config, settings } from '$lib/stores'; import { WEBUI_API_BASE_URL } from '$lib/constants'; @@ -25,7 +17,6 @@ import QuestionMarkCircle from '$lib/components/icons/QuestionMarkCircle.svelte'; import Map from '$lib/components/icons/Map.svelte'; import Keyboard from '$lib/components/icons/Keyboard.svelte'; - import ShortcutsModal from '$lib/components/chat/ShortcutsModal.svelte'; import Settings from '$lib/components/icons/Settings.svelte'; import Code from '$lib/components/icons/Code.svelte'; import UserGroup from '$lib/components/icons/UserGroup.svelte'; @@ -109,7 +100,6 @@ }} /> - { @@ -546,7 +536,7 @@ id="chat-share-button" on:click={async () => { show = false; - showShortcuts.set(!$showShortcuts); + showSettings.set('shortcuts'); if ($mobile) { await tick(); diff --git a/src/lib/stores/index.ts b/src/lib/stores/index.ts index 7ba3fd54b5..76b43ff224 100644 --- a/src/lib/stores/index.ts +++ b/src/lib/stores/index.ts @@ -92,7 +92,6 @@ export const sidebarWidth = writable(245); export const showSidebar = writable(false); export const showSearch = writable(false); export const showSettings: Writable = writable(false); -export const showShortcuts = writable(false); export const showChangelog = writable(false); export const showControls = writable(false); diff --git a/src/routes/(app)/+layout.svelte b/src/routes/(app)/+layout.svelte index e3509ba96e..5fe727196a 100644 --- a/src/routes/(app)/+layout.svelte +++ b/src/routes/(app)/+layout.svelte @@ -30,7 +30,6 @@ tags, banners, showSettings, - showShortcuts, showChangelog, temporaryChatEnabled, toolServers, @@ -281,12 +280,11 @@ } else if (isShortcutMatch(event, shortcuts[Shortcut.SHOW_SHORTCUTS])) { console.log('Shortcut triggered: SHOW_SHORTCUTS'); event.preventDefault(); - showShortcuts.set(!$showShortcuts); + showSettings.set('shortcuts'); } else if (isShortcutMatch(event, shortcuts[Shortcut.CLOSE_MODAL])) { console.log('Shortcut triggered: CLOSE_MODAL'); event.preventDefault(); showSettings.set(false); - showShortcuts.set(false); } else if (isShortcutMatch(event, shortcuts[Shortcut.OPEN_MODEL_SELECTOR])) { console.log('Shortcut triggered: OPEN_MODEL_SELECTOR'); event.preventDefault();