]> git.djapps.eu Git - pkg/ggml/sources/llama.cpp/commitdiff
webui: minor settings reorganization and add disable autoscroll option (#17452)
authorPascal <redacted>
Sun, 23 Nov 2025 17:42:00 +0000 (18:42 +0100)
committerGitHub <redacted>
Sun, 23 Nov 2025 17:42:00 +0000 (18:42 +0100)
* webui: added a dedicated 'Display' settings section that groups visualization options

* webui: added a Display setting to toggle automatic chat scrolling

* chore: update webui build output

tools/server/public/index.html.gz
tools/server/webui/src/lib/components/app/chat/ChatScreen/ChatScreen.svelte
tools/server/webui/src/lib/components/app/chat/ChatSettings/ChatSettings.svelte
tools/server/webui/src/lib/constants/settings-config.ts

index 097c9440be2d9bb6cab4a13d359106427ea74ceb..484956100bc1cb40c5430db2888c53d22da907f0 100644 (file)
Binary files a/tools/server/public/index.html.gz and b/tools/server/public/index.html.gz differ
index e891f7efdc55ff8e296ad5d36b27b3a7a94a7882..c736178fe22e9a5aac25ad2bb89bc84ffc34ac12 100644 (file)
@@ -29,6 +29,7 @@
                sendMessage,
                stopGeneration
        } from '$lib/stores/chat.svelte';
+       import { config } from '$lib/stores/settings.svelte';
        import {
                supportsVision,
                supportsAudio,
@@ -47,6 +48,7 @@
 
        let { showCenteredEmpty = false } = $props();
 
+       let disableAutoScroll = $derived(Boolean(config().disableAutoScroll));
        let autoScrollEnabled = $state(true);
        let chatScrollContainer: HTMLDivElement | undefined = $state();
        let dragCounter = $state(0);
        }
 
        function handleScroll() {
-               if (!chatScrollContainer) return;
+               if (disableAutoScroll || !chatScrollContainer) return;
 
                const { scrollTop, scrollHeight, clientHeight } = chatScrollContainer;
                const distanceFromBottom = scrollHeight - scrollTop - clientHeight;
                const extras = result?.extras;
 
                // Enable autoscroll for user-initiated message sending
-               userScrolledUp = false;
-               autoScrollEnabled = true;
+               if (!disableAutoScroll) {
+                       userScrolledUp = false;
+                       autoScrollEnabled = true;
+               }
                await sendMessage(message, extras);
                scrollChatToBottom();
 
        }
 
        function scrollChatToBottom(behavior: ScrollBehavior = 'smooth') {
+               if (disableAutoScroll) return;
+
                chatScrollContainer?.scrollTo({
                        top: chatScrollContainer?.scrollHeight,
                        behavior
        }
 
        afterNavigate(() => {
-               setTimeout(() => scrollChatToBottom('instant'), INITIAL_SCROLL_DELAY);
+               if (!disableAutoScroll) {
+                       setTimeout(() => scrollChatToBottom('instant'), INITIAL_SCROLL_DELAY);
+               }
        });
 
        onMount(() => {
-               setTimeout(() => scrollChatToBottom('instant'), INITIAL_SCROLL_DELAY);
+               if (!disableAutoScroll) {
+                       setTimeout(() => scrollChatToBottom('instant'), INITIAL_SCROLL_DELAY);
+               }
        });
 
        $effect(() => {
+               if (disableAutoScroll) {
+                       autoScrollEnabled = false;
+                       if (scrollInterval) {
+                               clearInterval(scrollInterval);
+                               scrollInterval = undefined;
+                       }
+                       return;
+               }
+
                if (isCurrentConversationLoading && autoScrollEnabled) {
                        scrollInterval = setInterval(scrollChatToBottom, AUTO_SCROLL_INTERVAL);
                } else if (scrollInterval) {
                        class="mb-16 md:mb-24"
                        messages={activeMessages()}
                        onUserAction={() => {
-                               userScrolledUp = false;
-                               autoScrollEnabled = true;
-                               scrollChatToBottom();
+                               if (!disableAutoScroll) {
+                                       userScrolledUp = false;
+                                       autoScrollEnabled = true;
+                                       scrollChatToBottom();
+                               }
                        }}
                />
 
index d00ae128538b4c212f978102c94f3b7079ca63a0..204f0d7551e5a4f925ec4cedbe29660b5e98db08 100644 (file)
@@ -3,7 +3,6 @@
                Settings,
                Funnel,
                AlertTriangle,
-               Brain,
                Code,
                Monitor,
                Sun,
                                        label: 'Paste long text to file length',
                                        type: 'input'
                                },
+                               {
+                                       key: 'enableContinueGeneration',
+                                       label: 'Enable "Continue" button',
+                                       type: 'checkbox',
+                                       isExperimental: true
+                               },
+                               {
+                                       key: 'pdfAsImage',
+                                       label: 'Parse PDF as image',
+                                       type: 'checkbox'
+                               },
+                               {
+                                       key: 'askForTitleConfirmation',
+                                       label: 'Ask for confirmation before changing conversation title',
+                                       type: 'checkbox'
+                               }
+                       ]
+               },
+               {
+                       title: 'Display',
+                       icon: Monitor,
+                       fields: [
+                               {
+                                       key: 'showThoughtInProgress',
+                                       label: 'Show thought in progress',
+                                       type: 'checkbox'
+                               },
                                {
                                        key: 'showMessageStats',
                                        label: 'Show message generation statistics',
                                        type: 'checkbox'
                                },
                                {
-                                       key: 'enableContinueGeneration',
-                                       label: 'Enable "Continue" button',
-                                       type: 'checkbox',
-                                       isExperimental: true
-                               },
-                               {
-                                       key: 'pdfAsImage',
-                                       label: 'Parse PDF as image',
+                                       key: 'disableAutoScroll',
+                                       label: 'Disable automatic scroll',
                                        type: 'checkbox'
                                },
                                {
                                        key: 'renderUserContentAsMarkdown',
                                        label: 'Render user content as Markdown',
                                        type: 'checkbox'
-                               },
-                               {
-                                       key: 'askForTitleConfirmation',
-                                       label: 'Ask for confirmation before changing conversation title',
-                                       type: 'checkbox'
                                }
                        ]
                },
                                }
                        ]
                },
-               {
-                       title: 'Reasoning',
-                       icon: Brain,
-                       fields: [
-                               {
-                                       key: 'showThoughtInProgress',
-                                       label: 'Show thought in progress',
-                                       type: 'checkbox'
-                               }
-                       ]
-               },
                {
                        title: 'Import/Export',
                        icon: Database,
index c25ea23f37be3047e25f07dff60b2091e8062d71..6783757e6b46b32243fbd190f62a2179e884100b 100644 (file)
@@ -14,6 +14,7 @@ export const SETTING_CONFIG_DEFAULT: Record<string, string | number | boolean> =
        pasteLongTextToFileLen: 2500,
        pdfAsImage: false,
        showModelInfo: false,
+       disableAutoScroll: false,
        renderUserContentAsMarkdown: false,
        modelSelectorEnabled: false,
        // make sure these default values are in sync with `common.h`
@@ -93,6 +94,8 @@ export const SETTING_CONFIG_INFO: Record<string, string> = {
                'Ask for confirmation before automatically changing conversation title when editing the first message.',
        pdfAsImage: 'Parse PDF as image instead of text (requires vision-capable model).',
        showModelInfo: 'Display the model name used to generate each message below the message content.',
+       disableAutoScroll:
+               'Disable automatic scrolling while messages stream so you can control the viewport position manually.',
        renderUserContentAsMarkdown: 'Render user messages using markdown formatting in the chat.',
        modelSelectorEnabled:
                'Enable the model selector in the chat input to choose the inference model. Sends the associated model field in API requests.',