diff --git a/src/lib/components/AddTerminalServerModal.svelte b/src/lib/components/AddTerminalServerModal.svelte index b77bce529e..d8b036bac9 100644 --- a/src/lib/components/AddTerminalServerModal.svelte +++ b/src/lib/components/AddTerminalServerModal.svelte @@ -9,7 +9,7 @@ import SensitiveInput from '$lib/components/common/SensitiveInput.svelte'; import XMark from '$lib/components/icons/XMark.svelte'; import AccessControlModal from '$lib/components/workspace/common/AccessControlModal.svelte'; - import LockClosed from '$lib/components/icons/LockClosed.svelte'; + import AccessButton from '$lib/components/common/AccessButton.svelte'; import Tooltip from '$lib/components/common/Tooltip.svelte'; import ConfirmDialog from '$lib/components/common/ConfirmDialog.svelte'; import { @@ -775,19 +775,12 @@ {#if !direct} - + /> {/if} diff --git a/src/lib/components/AddToolServerModal.svelte b/src/lib/components/AddToolServerModal.svelte index bf3b0bb9f3..cb59a24482 100644 --- a/src/lib/components/AddToolServerModal.svelte +++ b/src/lib/components/AddToolServerModal.svelte @@ -20,7 +20,7 @@ import { getToolServerData } from '$lib/apis'; import { verifyToolServerConnection, registerOAuthClient } from '$lib/apis/configs'; import AccessControlModal from '$lib/components/workspace/common/AccessControlModal.svelte'; - import LockClosed from '$lib/components/icons/LockClosed.svelte'; + import AccessButton from '$lib/components/common/AccessButton.svelte'; import Spinner from '$lib/components/common/Spinner.svelte'; import XMark from '$lib/components/icons/XMark.svelte'; import Textarea from './common/Textarea.svelte'; @@ -804,19 +804,12 @@ {#if !direct} - + /> {/if} diff --git a/src/lib/components/chat/MessageInput.svelte b/src/lib/components/chat/MessageInput.svelte index 9dba0d53f0..0245de58ab 100644 --- a/src/lib/components/chat/MessageInput.svelte +++ b/src/lib/components/chat/MessageInput.svelte @@ -63,6 +63,7 @@ import { WEBUI_BASE_URL, WEBUI_API_BASE_URL, PASTED_TEXT_CHARACTER_LIMIT } from '$lib/constants'; import { initiateOAuthRedirect } from '$lib/apis/configs'; + import { matchKeybinding, Shortcut } from '$lib/shortcuts'; import { createNoteHandler } from '../notes/utils'; import { getSuggestionRenderer } from '../common/RichTextInput/suggestions'; @@ -1009,8 +1010,7 @@ shiftKey = true; } - // Cmd/Ctrl+Shift+L to toggle dictation - if (e.key.toLowerCase() === 'l' && (e.metaKey || e.ctrlKey) && e.shiftKey) { + if (matchKeybinding(e) === Shortcut.TOGGLE_DICTATION) { e.preventDefault(); if (recording) { // Confirm and stop recording diff --git a/src/lib/components/chat/Settings/Shortcuts.svelte b/src/lib/components/chat/Settings/Shortcuts.svelte index 8d84981af1..232a4ec04b 100644 --- a/src/lib/components/chat/Settings/Shortcuts.svelte +++ b/src/lib/components/chat/Settings/Shortcuts.svelte @@ -1,47 +1,116 @@ + +
-

- {$i18n.t('Keyboard Shortcuts')} -

+
+

+ {$i18n.t('Keyboard Shortcuts')} +

+ + +
@@ -99,8 +168,55 @@ - {#each items as shortcut} - + + + + + {#each items as { id, shortcut }} + {@const configurable = isConfigurableShortcut(id)} + {@const chord = configurable ? $keybindings[id] : ''} + {@const conflict = configurable ? getConflict(id, chord) : null} +
+ + +
+ {#if configurable} + {#if recordingShortcut === id} + + {$i18n.t('Press keys...')} + + {:else if chord} + + {:else} + + {/if} + + {#if conflict} + ! + {/if} + {:else} + + {/if} +
+
{/each}
diff --git a/src/lib/components/chat/ShortcutItem.svelte b/src/lib/components/chat/ShortcutItem.svelte index cdfa09d4e8..88cd0a6c3d 100644 --- a/src/lib/components/chat/ShortcutItem.svelte +++ b/src/lib/components/chat/ShortcutItem.svelte @@ -2,14 +2,21 @@ import { getContext, onMount } from 'svelte'; import type { Writable } from 'svelte/store'; import Tooltip from '../common/Tooltip.svelte'; - import { shortcuts } from '$lib/shortcuts'; + import { formatChord, isConfigurableShortcut, keybindings, shortcuts } from '$lib/shortcuts'; + import type { Shortcut } from '$lib/shortcuts'; type ShortcutDefinition = NonNullable<(typeof shortcuts)[keyof typeof shortcuts]>; + type I18nStore = Writable<{ + t: (key: string, options?: Record) => string; + }>; + export let id: Shortcut | undefined = undefined; export let shortcut: ShortcutDefinition; export let isMac: boolean; + export let compact = false; + export let keysOnly = false; - const i18n: Writable = getContext('i18n'); + const i18n: I18nStore = getContext('i18n'); let keyboardLayoutMap: Map | undefined; onMount(async () => { @@ -87,24 +94,49 @@ .map(formatKey) .join(isMac ? '' : ' + '); } + + function displayKeys(): string { + if (id && isConfigurableShortcut(id)) { + return formatChord($keybindings[id]) || $i18n.t('Unassigned'); + } + return formatKeys(shortcut.keys); + } -
-
- {#if shortcut.tooltip} - - - {$i18n.t(shortcut.name)} - * - - - {:else} - {$i18n.t(shortcut.name)} - {/if} -
+{#if keysOnly} - {formatKeys(shortcut.keys)} + {displayKeys()} -
+{:else} +
+
+ {#if shortcut.tooltip} + + + {$i18n.t(shortcut.name)} + * + + + {:else} + {$i18n.t(shortcut.name)} + {/if} +
+ {#if !compact} + + {displayKeys()} + + {/if} +
+{/if} diff --git a/src/lib/components/common/AccessButton.svelte b/src/lib/components/common/AccessButton.svelte new file mode 100644 index 0000000000..49d4d98062 --- /dev/null +++ b/src/lib/components/common/AccessButton.svelte @@ -0,0 +1,22 @@ + + + diff --git a/src/lib/components/common/HotkeyHint.svelte b/src/lib/components/common/HotkeyHint.svelte index 0cb7e7e09c..539b6cbd9f 100644 --- a/src/lib/components/common/HotkeyHint.svelte +++ b/src/lib/components/common/HotkeyHint.svelte @@ -1,19 +1,17 @@ {#if mounted && isVisible} {/if} diff --git a/src/lib/components/layout/Sidebar.svelte b/src/lib/components/layout/Sidebar.svelte index a13aea514f..3ba6bbb36c 100644 --- a/src/lib/components/layout/Sidebar.svelte +++ b/src/lib/components/layout/Sidebar.svelte @@ -792,7 +792,7 @@ {#if !$mobile && !$showSidebar}