webui: add "Send message on Enter" setting (#21577)
* webui: make Enter to send chat a setting * Shorten description * Use isMobile hook from $lib/hooks * Rebuild static output
This commit is contained in:
parent
ddf03c6d9a
commit
4ef9301e4d
File diff suppressed because one or more lines are too long
|
|
@ -18,7 +18,7 @@
|
|||
<div style="display: contents">
|
||||
<script>
|
||||
{
|
||||
__sveltekit_6n4hpv = {
|
||||
__sveltekit_1ao0o9h = {
|
||||
base: new URL('.', location).pathname.slice(0, -1)
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -294,11 +294,16 @@
|
|||
}
|
||||
|
||||
if (event.key === KeyboardKey.ENTER && !event.shiftKey && !isIMEComposing(event)) {
|
||||
event.preventDefault();
|
||||
const isModifier = event.ctrlKey || event.metaKey;
|
||||
const sendOnEnter = currentConfig.sendOnEnter !== false;
|
||||
|
||||
if (!canSubmit || disabled || isLoading || hasLoadingAttachments) return;
|
||||
if (sendOnEnter || isModifier) {
|
||||
event.preventDefault();
|
||||
|
||||
onSubmit?.();
|
||||
if (!canSubmit || disabled || isLoading || hasLoadingAttachments) return;
|
||||
|
||||
onSubmit?.();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,17 +1,30 @@
|
|||
<script lang="ts">
|
||||
import { browser } from '$app/environment';
|
||||
import { config } from '$lib/stores/settings.svelte';
|
||||
|
||||
interface Props {
|
||||
class?: string;
|
||||
show?: boolean;
|
||||
}
|
||||
|
||||
let { class: className = '', show = true }: Props = $props();
|
||||
|
||||
let sendOnEnter = $derived(config().sendOnEnter !== false);
|
||||
let modKey = browser && /Mac|iPhone|iPad|iPod/.test(navigator.platform) ? 'Cmd' : 'Ctrl';
|
||||
</script>
|
||||
|
||||
{#if show}
|
||||
<div class="mt-6 items-center justify-center {className} hidden md:flex">
|
||||
<p class="text-xs text-muted-foreground">
|
||||
Press <kbd class="rounded bg-muted px-1 py-0.5 font-mono text-xs">Enter</kbd> to send,
|
||||
<kbd class="rounded bg-muted px-1 py-0.5 font-mono text-xs">Shift + Enter</kbd> for new line
|
||||
</p>
|
||||
{#if sendOnEnter}
|
||||
<p class="text-xs text-muted-foreground">
|
||||
Press <kbd class="rounded bg-muted px-1 py-0.5 font-mono text-xs">Enter</kbd> to send,
|
||||
<kbd class="rounded bg-muted px-1 py-0.5 font-mono text-xs">Shift + Enter</kbd> for new line
|
||||
</p>
|
||||
{:else}
|
||||
<p class="text-xs text-muted-foreground">
|
||||
Press <kbd class="rounded bg-muted px-1 py-0.5 font-mono text-xs">{modKey} + Enter</kbd> to send,
|
||||
<kbd class="rounded bg-muted px-1 py-0.5 font-mono text-xs">Enter</kbd> for new line
|
||||
</p>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
|
|
|
|||
|
|
@ -64,6 +64,11 @@
|
|||
label: 'Paste long text to file length',
|
||||
type: SettingsFieldType.INPUT
|
||||
},
|
||||
{
|
||||
key: SETTINGS_KEYS.SEND_ON_ENTER,
|
||||
label: 'Send message on Enter',
|
||||
type: SettingsFieldType.CHECKBOX
|
||||
},
|
||||
{
|
||||
key: SETTINGS_KEYS.COPY_TEXT_ATTACHMENTS_AS_PLAIN_TEXT,
|
||||
label: 'Copy text attachments as plain text',
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ export const SETTING_CONFIG_DEFAULT: Record<string, string | number | boolean |
|
|||
renderUserContentAsMarkdown: false,
|
||||
alwaysShowSidebarOnDesktop: false,
|
||||
autoShowSidebarOnNewChat: true,
|
||||
sendOnEnter: true,
|
||||
autoMicOnEmpty: false,
|
||||
fullHeightCodeBlocks: false,
|
||||
showRawModelNames: false,
|
||||
|
|
@ -126,6 +127,8 @@ export const SETTING_CONFIG_INFO: Record<string, string> = {
|
|||
'Always keep the sidebar visible on desktop instead of auto-hiding it.',
|
||||
autoShowSidebarOnNewChat:
|
||||
'Automatically show sidebar when starting a new chat. Disable to keep the sidebar hidden until you click on it.',
|
||||
sendOnEnter:
|
||||
'Use Enter to send messages and Shift + Enter for new lines. When disabled, use Ctrl/Cmd + Enter.',
|
||||
autoMicOnEmpty:
|
||||
'Automatically show microphone button instead of send button when textarea is empty for models with audio modality support.',
|
||||
fullHeightCodeBlocks:
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ export const SETTINGS_KEYS = {
|
|||
SYSTEM_MESSAGE: 'systemMessage',
|
||||
PASTE_LONG_TEXT_TO_FILE_LEN: 'pasteLongTextToFileLen',
|
||||
COPY_TEXT_ATTACHMENTS_AS_PLAIN_TEXT: 'copyTextAttachmentsAsPlainText',
|
||||
SEND_ON_ENTER: 'sendOnEnter',
|
||||
ENABLE_CONTINUE_GENERATION: 'enableContinueGeneration',
|
||||
PDF_AS_IMAGE: 'pdfAsImage',
|
||||
ASK_FOR_TITLE_CONFIRMATION: 'askForTitleConfirmation',
|
||||
|
|
|
|||
|
|
@ -239,6 +239,12 @@ export const SYNCABLE_PARAMETERS: SyncableParameter[] = [
|
|||
serverKey: 'excludeReasoningFromContext',
|
||||
type: SyncableParameterType.BOOLEAN,
|
||||
canSync: true
|
||||
},
|
||||
{
|
||||
key: 'sendOnEnter',
|
||||
serverKey: 'sendOnEnter',
|
||||
type: SyncableParameterType.BOOLEAN,
|
||||
canSync: true
|
||||
}
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ import {
|
|||
SETTING_CONFIG_DEFAULT,
|
||||
USER_OVERRIDES_LOCALSTORAGE_KEY
|
||||
} from '$lib/constants';
|
||||
import { IsMobile } from '$lib/hooks/is-mobile.svelte';
|
||||
import { ParameterSyncService } from '$lib/services/parameter-sync.service';
|
||||
import { serverStore } from '$lib/stores/server.svelte';
|
||||
import {
|
||||
|
|
@ -122,6 +123,13 @@ class SettingsStore {
|
|||
...savedVal
|
||||
};
|
||||
|
||||
// Default sendOnEnter to false on mobile when the user has no saved preference
|
||||
if (!('sendOnEnter' in savedVal)) {
|
||||
if (new IsMobile().current) {
|
||||
this.config.sendOnEnter = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Load user overrides
|
||||
const savedOverrides = JSON.parse(
|
||||
localStorage.getItem(USER_OVERRIDES_LOCALSTORAGE_KEY) || '[]'
|
||||
|
|
|
|||
Loading…
Reference in New Issue