Skip to content

Commit 5aa6abf

Browse files
authored
feat: settings auto scroll toggle (#1293)
* feat: settings auto scroll toggle * feat: i18n support
1 parent 3e08a0d commit 5aa6abf

21 files changed

Lines changed: 82 additions & 3 deletions

File tree

src/main/events.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export const CONFIG_EVENTS = {
2121
SYNC_SETTINGS_CHANGED: 'config:sync-settings-changed',
2222
SEARCH_ENGINES_UPDATED: 'config:search-engines-updated',
2323
SEARCH_PREVIEW_CHANGED: 'config:search-preview-changed',
24+
AUTO_SCROLL_CHANGED: 'config:auto-scroll-changed',
2425
NOTIFICATIONS_CHANGED: 'config:notifications-changed',
2526
CONTENT_PROTECTION_CHANGED: 'config:content-protection-changed',
2627
SOUND_ENABLED_CHANGED: 'config:sound-enabled-changed', // 新增:声音开关变更事件

src/main/presenter/configPresenter/index.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -893,6 +893,14 @@ export class ConfigPresenter implements IConfigPresenter {
893893
this.uiSettingsHelper.setSearchPreviewEnabled(enabled)
894894
}
895895

896+
getAutoScrollEnabled(): boolean {
897+
return this.uiSettingsHelper.getAutoScrollEnabled()
898+
}
899+
900+
setAutoScrollEnabled(enabled: boolean): void {
901+
this.uiSettingsHelper.setAutoScrollEnabled(enabled)
902+
}
903+
896904
getContentProtectionEnabled(): boolean {
897905
return this.uiSettingsHelper.getContentProtectionEnabled()
898906
}

src/main/presenter/configPresenter/uiSettingsHelper.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,18 @@ export class UiSettingsHelper {
4949
eventBus.send(CONFIG_EVENTS.SEARCH_PREVIEW_CHANGED, SendTarget.ALL_WINDOWS, boolValue)
5050
}
5151

52+
getAutoScrollEnabled(): boolean {
53+
const value = this.getSetting<boolean>('autoScrollEnabled')
54+
if (value === undefined) return true
55+
return Boolean(value)
56+
}
57+
58+
setAutoScrollEnabled(enabled: boolean): void {
59+
const boolValue = Boolean(enabled)
60+
this.setSetting('autoScrollEnabled', boolValue)
61+
eventBus.send(CONFIG_EVENTS.AUTO_SCROLL_CHANGED, SendTarget.ALL_WINDOWS, boolValue)
62+
}
63+
5264
getContentProtectionEnabled(): boolean {
5365
const value = this.getSetting<boolean>('contentProtectionEnabled')
5466
return value === undefined || value === null ? false : value

src/renderer/settings/components/CommonSettings.vue

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,13 @@
1313
:model-value="searchPreviewEnabled"
1414
@update:model-value="handleSearchPreviewChange"
1515
/>
16+
<SettingToggleRow
17+
id="auto-scroll-switch"
18+
icon="lucide:arrow-down"
19+
:label="t('settings.common.autoScrollEnabled')"
20+
:model-value="autoScrollEnabled"
21+
@update:model-value="handleAutoScrollChange"
22+
/>
1623
<SettingToggleRow
1724
id="sound-switch"
1825
icon="lucide:volume-2"
@@ -58,6 +65,7 @@ const uiSettingsStore = useUiSettingsStore()
5865
const soundStore = useSoundStore()
5966
6067
const searchPreviewEnabled = computed(() => uiSettingsStore.searchPreviewEnabled)
68+
const autoScrollEnabled = computed(() => uiSettingsStore.autoScrollEnabled)
6169
const soundEnabled = computed(() => soundStore.soundEnabled)
6270
const copyWithCotEnabled = computed(() => uiSettingsStore.copyWithCotEnabled)
6371
const traceDebugEnabled = computed(() => uiSettingsStore.traceDebugEnabled)
@@ -66,6 +74,10 @@ const handleSearchPreviewChange = (value: boolean) => {
6674
uiSettingsStore.setSearchPreviewEnabled(value)
6775
}
6876
77+
const handleAutoScrollChange = (value: boolean) => {
78+
uiSettingsStore.setAutoScrollEnabled(value)
79+
}
80+
6981
const handleSoundChange = (value: boolean) => {
7082
soundStore.setSoundEnabled(value)
7183
}

src/renderer/src/components/message/MessageList.vue

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ import { getAllMessageDomInfo, getMessageDomInfo } from '@/lib/messageRuntimeCac
113113
import { useChatStore } from '@/stores/chat'
114114
import { useReferenceStore } from '@/stores/reference'
115115
import { useWorkspaceStore } from '@/stores/workspace'
116+
import { useUiSettingsStore } from '@/stores/uiSettingsStore'
116117
import type { ParentSelection } from '@shared/presenter'
117118
118119
// === Props & Emits ===
@@ -124,6 +125,7 @@ const props = defineProps<{
124125
const chatStore = useChatStore()
125126
const referenceStore = useReferenceStore()
126127
const workspaceStore = useWorkspaceStore()
128+
const uiSettingsStore = useUiSettingsStore()
127129
128130
// === Local State (需要先声明,因为 useMessageScroll 需要引用) ===
129131
const dynamicScrollerRef = ref<InstanceType<typeof DynamicScroller> | null>(null)
@@ -142,6 +144,7 @@ const pendingHeightUpdate = ref(false)
142144
const scroll = useMessageScroll({
143145
dynamicScrollerRef,
144146
shouldAutoFollow,
147+
autoScrollEnabled: computed(() => uiSettingsStore.autoScrollEnabled),
145148
scrollAnchor
146149
})
147150
const {
@@ -717,8 +720,12 @@ onMounted(() => {
717720
})
718721
719722
watch(
720-
() => aboveThreshold.value,
721-
(isAbove) => {
723+
() => [aboveThreshold.value, uiSettingsStore.autoScrollEnabled] as const,
724+
([isAbove, autoScrollEnabled]) => {
725+
if (!autoScrollEnabled) {
726+
shouldAutoFollow.value = false
727+
return
728+
}
722729
shouldAutoFollow.value = !isAbove
723730
}
724731
)

src/renderer/src/composables/message/useMessageScroll.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const PLACEHOLDER_POSITION_THRESHOLD = 5000
1313
export interface UseMessageScrollOptions {
1414
dynamicScrollerRef?: Ref<InstanceType<typeof DynamicScroller> | null>
1515
shouldAutoFollow?: Ref<boolean>
16+
autoScrollEnabled?: Ref<boolean>
1617
scrollAnchor?: Ref<HTMLDivElement | undefined>
1718
}
1819

@@ -73,8 +74,17 @@ export function useMessageScroll(options?: UseMessageScrollOptions) {
7374

7475
nextTick(() => {
7576
const shouldAutoFollow = options?.shouldAutoFollow
77+
const autoScrollEnabled = options?.autoScrollEnabled
78+
const canAutoFollow = autoScrollEnabled ? autoScrollEnabled.value : true
7679
if (force && shouldAutoFollow) {
77-
shouldAutoFollow.value = true
80+
if (canAutoFollow) {
81+
shouldAutoFollow.value = true
82+
}
83+
}
84+
85+
if (!force && !canAutoFollow) {
86+
updateScrollInfo()
87+
return
7888
}
7989

8090
if (!force && shouldAutoFollow && !shouldAutoFollow.value) {

src/renderer/src/events.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export const CONFIG_EVENTS = {
2020
SYNC_SETTINGS_CHANGED: 'config:sync-settings-changed',
2121
SEARCH_ENGINES_UPDATED: 'config:search-engines-updated',
2222
SEARCH_PREVIEW_CHANGED: 'config:search-preview-changed',
23+
AUTO_SCROLL_CHANGED: 'config:auto-scroll-changed',
2324
NOTIFICATIONS_CHANGED: 'config:notifications-changed',
2425
CONTENT_PROTECTION_CHANGED: 'config:content-protection-changed',
2526
LANGUAGE_CHANGED: 'config:language-changed', // 新增:语言变更事件

src/renderer/src/i18n/da-DK/settings.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"searchEngine": "Søgemaskine",
99
"searchEngineSelect": "Vælg søgemaskine",
1010
"searchPreview": "Søgeforhåndsvisning",
11+
"autoScrollEnabled": "Automatisk rulning under generering",
1112
"searchAssistantModel": "Assistentmodel",
1213
"selectModel": "Vælg model",
1314
"proxyMode": "Proxytilstand",

src/renderer/src/i18n/en-US/settings.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"searchEngine": "Search Engine",
99
"searchEngineSelect": "Select search engine",
1010
"searchPreview": "Search Preview",
11+
"autoScrollEnabled": "Auto-scroll while generating",
1112
"searchAssistantModel": "Assistant Model",
1213
"selectModel": "Select Model",
1314
"proxyMode": "Proxy Mode",

src/renderer/src/i18n/fa-IR/settings.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"searchEngine": "موتور جستجو",
99
"searchEngineSelect": "انتخاب موتور جستجو",
1010
"searchPreview": "پیش‌نمایش جستجو",
11+
"autoScrollEnabled": "پیمایش خودکار هنگام تولید",
1112
"searchAssistantModel": "مدل دستیار",
1213
"selectModel": "انتخاب مدل",
1314
"proxyMode": "حالت پراکسی",

0 commit comments

Comments
 (0)