Skip to content

Commit 4ef9301

Browse files
authored
webui: add "Send message on Enter" setting (ggml-org#21577)
* webui: make Enter to send chat a setting * Shorten description * Use isMobile hook from $lib/hooks * Rebuild static output
1 parent ddf03c6 commit 4ef9301

9 files changed

Lines changed: 144 additions & 103 deletions

File tree

tools/server/public/bundle.js

Lines changed: 95 additions & 95 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tools/server/public/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
<div style="display: contents">
1919
<script>
2020
{
21-
__sveltekit_6n4hpv = {
21+
__sveltekit_1ao0o9h = {
2222
base: new URL('.', location).pathname.slice(0, -1)
2323
};
2424

tools/server/webui/src/lib/components/app/chat/ChatForm/ChatForm.svelte

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -294,11 +294,16 @@
294294
}
295295
296296
if (event.key === KeyboardKey.ENTER && !event.shiftKey && !isIMEComposing(event)) {
297-
event.preventDefault();
297+
const isModifier = event.ctrlKey || event.metaKey;
298+
const sendOnEnter = currentConfig.sendOnEnter !== false;
299+
300+
if (sendOnEnter || isModifier) {
301+
event.preventDefault();
298302
299-
if (!canSubmit || disabled || isLoading || hasLoadingAttachments) return;
303+
if (!canSubmit || disabled || isLoading || hasLoadingAttachments) return;
300304
301-
onSubmit?.();
305+
onSubmit?.();
306+
}
302307
}
303308
}
304309
Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,30 @@
11
<script lang="ts">
2+
import { browser } from '$app/environment';
3+
import { config } from '$lib/stores/settings.svelte';
4+
25
interface Props {
36
class?: string;
47
show?: boolean;
58
}
69
710
let { class: className = '', show = true }: Props = $props();
11+
12+
let sendOnEnter = $derived(config().sendOnEnter !== false);
13+
let modKey = browser && /Mac|iPhone|iPad|iPod/.test(navigator.platform) ? 'Cmd' : 'Ctrl';
814
</script>
915

1016
{#if show}
1117
<div class="mt-6 items-center justify-center {className} hidden md:flex">
12-
<p class="text-xs text-muted-foreground">
13-
Press <kbd class="rounded bg-muted px-1 py-0.5 font-mono text-xs">Enter</kbd> to send,
14-
<kbd class="rounded bg-muted px-1 py-0.5 font-mono text-xs">Shift + Enter</kbd> for new line
15-
</p>
18+
{#if sendOnEnter}
19+
<p class="text-xs text-muted-foreground">
20+
Press <kbd class="rounded bg-muted px-1 py-0.5 font-mono text-xs">Enter</kbd> to send,
21+
<kbd class="rounded bg-muted px-1 py-0.5 font-mono text-xs">Shift + Enter</kbd> for new line
22+
</p>
23+
{:else}
24+
<p class="text-xs text-muted-foreground">
25+
Press <kbd class="rounded bg-muted px-1 py-0.5 font-mono text-xs">{modKey} + Enter</kbd> to send,
26+
<kbd class="rounded bg-muted px-1 py-0.5 font-mono text-xs">Enter</kbd> for new line
27+
</p>
28+
{/if}
1629
</div>
1730
{/if}

tools/server/webui/src/lib/components/app/chat/ChatSettings/ChatSettings.svelte

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@
6464
label: 'Paste long text to file length',
6565
type: SettingsFieldType.INPUT
6666
},
67+
{
68+
key: SETTINGS_KEYS.SEND_ON_ENTER,
69+
label: 'Send message on Enter',
70+
type: SettingsFieldType.CHECKBOX
71+
},
6772
{
6873
key: SETTINGS_KEYS.COPY_TEXT_ATTACHMENTS_AS_PLAIN_TEXT,
6974
label: 'Copy text attachments as plain text',

tools/server/webui/src/lib/constants/settings-config.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export const SETTING_CONFIG_DEFAULT: Record<string, string | number | boolean |
2222
renderUserContentAsMarkdown: false,
2323
alwaysShowSidebarOnDesktop: false,
2424
autoShowSidebarOnNewChat: true,
25+
sendOnEnter: true,
2526
autoMicOnEmpty: false,
2627
fullHeightCodeBlocks: false,
2728
showRawModelNames: false,
@@ -126,6 +127,8 @@ export const SETTING_CONFIG_INFO: Record<string, string> = {
126127
'Always keep the sidebar visible on desktop instead of auto-hiding it.',
127128
autoShowSidebarOnNewChat:
128129
'Automatically show sidebar when starting a new chat. Disable to keep the sidebar hidden until you click on it.',
130+
sendOnEnter:
131+
'Use Enter to send messages and Shift + Enter for new lines. When disabled, use Ctrl/Cmd + Enter.',
129132
autoMicOnEmpty:
130133
'Automatically show microphone button instead of send button when textarea is empty for models with audio modality support.',
131134
fullHeightCodeBlocks:

tools/server/webui/src/lib/constants/settings-keys.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export const SETTINGS_KEYS = {
1111
SYSTEM_MESSAGE: 'systemMessage',
1212
PASTE_LONG_TEXT_TO_FILE_LEN: 'pasteLongTextToFileLen',
1313
COPY_TEXT_ATTACHMENTS_AS_PLAIN_TEXT: 'copyTextAttachmentsAsPlainText',
14+
SEND_ON_ENTER: 'sendOnEnter',
1415
ENABLE_CONTINUE_GENERATION: 'enableContinueGeneration',
1516
PDF_AS_IMAGE: 'pdfAsImage',
1617
ASK_FOR_TITLE_CONFIRMATION: 'askForTitleConfirmation',

tools/server/webui/src/lib/services/parameter-sync.service.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,12 @@ export const SYNCABLE_PARAMETERS: SyncableParameter[] = [
239239
serverKey: 'excludeReasoningFromContext',
240240
type: SyncableParameterType.BOOLEAN,
241241
canSync: true
242+
},
243+
{
244+
key: 'sendOnEnter',
245+
serverKey: 'sendOnEnter',
246+
type: SyncableParameterType.BOOLEAN,
247+
canSync: true
242248
}
243249
];
244250

tools/server/webui/src/lib/stores/settings.svelte.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import {
3737
SETTING_CONFIG_DEFAULT,
3838
USER_OVERRIDES_LOCALSTORAGE_KEY
3939
} from '$lib/constants';
40+
import { IsMobile } from '$lib/hooks/is-mobile.svelte';
4041
import { ParameterSyncService } from '$lib/services/parameter-sync.service';
4142
import { serverStore } from '$lib/stores/server.svelte';
4243
import {
@@ -122,6 +123,13 @@ class SettingsStore {
122123
...savedVal
123124
};
124125

126+
// Default sendOnEnter to false on mobile when the user has no saved preference
127+
if (!('sendOnEnter' in savedVal)) {
128+
if (new IsMobile().current) {
129+
this.config.sendOnEnter = false;
130+
}
131+
}
132+
125133
// Load user overrides
126134
const savedOverrides = JSON.parse(
127135
localStorage.getItem(USER_OVERRIDES_LOCALSTORAGE_KEY) || '[]'

0 commit comments

Comments
 (0)