diff --git a/src/renderer/src/hooks/useSettings.ts b/src/renderer/src/hooks/useSettings.ts index ba6185aba9..5eea046d00 100644 --- a/src/renderer/src/hooks/useSettings.ts +++ b/src/renderer/src/hooks/useSettings.ts @@ -12,6 +12,7 @@ import { setTheme, SettingsState, setTopicPosition, + setPinTopicsToTop, setTray as _setTray, setTrayOnClose, setWindowStyle @@ -68,6 +69,9 @@ export function useSettings() { setTopicPosition(topicPosition: 'left' | 'right') { dispatch(setTopicPosition(topicPosition)) }, + setPinTopicsToTop(pinTopicsToTop: boolean) { + dispatch(setPinTopicsToTop(pinTopicsToTop)) + }, updateSidebarIcons(icons: { visible: SidebarIcon[]; disabled: SidebarIcon[] }) { dispatch(setSidebarIcons(icons)) }, diff --git a/src/renderer/src/i18n/locales/en-us.json b/src/renderer/src/i18n/locales/en-us.json index b6b742fd85..578032003c 100644 --- a/src/renderer/src/i18n/locales/en-us.json +++ b/src/renderer/src/i18n/locales/en-us.json @@ -1635,6 +1635,7 @@ "topic.position.left": "Left", "topic.position.right": "Right", "topic.show.time": "Show topic time", + "topic.pin_to_top": "Pin Topics to Top", "tray.onclose": "Minimize to Tray on Close", "tray.show": "Show Tray Icon", "tray.title": "Tray", diff --git a/src/renderer/src/i18n/locales/ja-jp.json b/src/renderer/src/i18n/locales/ja-jp.json index 42a7564d06..38abc69bc3 100644 --- a/src/renderer/src/i18n/locales/ja-jp.json +++ b/src/renderer/src/i18n/locales/ja-jp.json @@ -1626,6 +1626,7 @@ "topic.position.left": "左", "topic.position.right": "右", "topic.show.time": "トピックの時間を表示", + "topic.pin_to_top": "固定トピックを上部に表示", "tray.onclose": "閉じるときにトレイに最小化", "tray.show": "トレイアイコンを表示", "tray.title": "トレイ", diff --git a/src/renderer/src/i18n/locales/ru-ru.json b/src/renderer/src/i18n/locales/ru-ru.json index 28aacde678..2ca59e4007 100644 --- a/src/renderer/src/i18n/locales/ru-ru.json +++ b/src/renderer/src/i18n/locales/ru-ru.json @@ -1626,6 +1626,7 @@ "topic.position.left": "Слева", "topic.position.right": "Справа", "topic.show.time": "Показывать время топика", + "topic.pin_to_top": "Закрепленные топики сверху", "tray.onclose": "Свернуть в трей при закрытии", "tray.show": "Показать значок в трее", "tray.title": "Трей", diff --git a/src/renderer/src/i18n/locales/zh-cn.json b/src/renderer/src/i18n/locales/zh-cn.json index 89fac6e56e..759302c82d 100644 --- a/src/renderer/src/i18n/locales/zh-cn.json +++ b/src/renderer/src/i18n/locales/zh-cn.json @@ -1635,6 +1635,7 @@ "topic.position.left": "左侧", "topic.position.right": "右侧", "topic.show.time": "显示话题时间", + "topic.pin_to_top": "固定话题置顶", "tray.onclose": "关闭时最小化到托盘", "tray.show": "显示托盘图标", "tray.title": "托盘", diff --git a/src/renderer/src/i18n/locales/zh-tw.json b/src/renderer/src/i18n/locales/zh-tw.json index 3b5650f5a2..ceaf666452 100644 --- a/src/renderer/src/i18n/locales/zh-tw.json +++ b/src/renderer/src/i18n/locales/zh-tw.json @@ -1629,6 +1629,7 @@ "topic.position.left": "左側", "topic.position.right": "右側", "topic.show.time": "顯示話題時間", + "topic.pin_to_top": "固定話題置頂", "tray.onclose": "關閉時最小化到系统匣", "tray.show": "顯示系统匣圖示", "tray.title": "系统匣", diff --git a/src/renderer/src/pages/home/Tabs/TopicsTab.tsx b/src/renderer/src/pages/home/Tabs/TopicsTab.tsx index 2df5fb5db8..f53989be0c 100644 --- a/src/renderer/src/pages/home/Tabs/TopicsTab.tsx +++ b/src/renderer/src/pages/home/Tabs/TopicsTab.tsx @@ -54,7 +54,7 @@ const Topics: FC = ({ assistant: _assistant, activeTopic, setActiveTopic const { assistants } = useAssistants() const { assistant, removeTopic, moveTopic, updateTopic, updateTopics } = useAssistant(_assistant.id) const { t } = useTranslation() - const { showTopicTime, topicPosition } = useSettings() + const { showTopicTime, topicPosition, pinTopicsToTop } = useSettings() const borderRadius = showTopicTime ? 12 : 'var(--list-item-border-radius)' @@ -380,10 +380,22 @@ const Topics: FC = ({ assistant: _assistant, activeTopic, setActiveTopic targetTopic ]) + // Sort topics based on pinned status if pinTopicsToTop is enabled + const sortedTopics = useMemo(() => { + if (pinTopicsToTop) { + return [...assistant.topics].sort((a, b) => { + if (a.pinned && !b.pinned) return -1 + if (!a.pinned && b.pinned) return 1 + return 0 + }) + } + return assistant.topics + }, [assistant.topics, pinTopicsToTop]) + return ( - + {(topic) => { const isActive = topic.id === activeTopic?.id const topicName = topic.name.replace('`', '') diff --git a/src/renderer/src/pages/settings/DisplaySettings/DisplaySettings.tsx b/src/renderer/src/pages/settings/DisplaySettings/DisplaySettings.tsx index d58cf0c01a..b48633abba 100644 --- a/src/renderer/src/pages/settings/DisplaySettings/DisplaySettings.tsx +++ b/src/renderer/src/pages/settings/DisplaySettings/DisplaySettings.tsx @@ -9,6 +9,7 @@ import { setAssistantIconType, setClickAssistantToShowTopic, setCustomCss, + setPinTopicsToTop, setShowTopicTime, setSidebarIcons } from '@renderer/store/settings' @@ -32,6 +33,7 @@ const DisplaySettings: FC = () => { setTopicPosition, clickAssistantToShowTopic, showTopicTime, + pinTopicsToTop, customCss, sidebarIcons, assistantIconType @@ -189,6 +191,11 @@ const DisplaySettings: FC = () => { {t('settings.topic.show.time')} dispatch(setShowTopicTime(checked))} /> + + + {t('settings.topic.pin_to_top')} + dispatch(setPinTopicsToTop(checked))} /> + {t('settings.display.assistant.title')} diff --git a/src/renderer/src/store/settings.ts b/src/renderer/src/store/settings.ts index cda007c7f8..a089a6a6f3 100644 --- a/src/renderer/src/store/settings.ts +++ b/src/renderer/src/store/settings.ts @@ -52,6 +52,7 @@ export interface SettingsState { fontSize: number topicPosition: 'left' | 'right' showTopicTime: boolean + pinTopicsToTop: boolean assistantIconType: AssistantIconType pasteLongTextAsFile: boolean pasteLongTextThreshold: number @@ -192,6 +193,7 @@ export const initialState: SettingsState = { fontSize: 14, topicPosition: 'left', showTopicTime: false, + pinTopicsToTop: false, assistantIconType: 'emoji', pasteLongTextAsFile: false, pasteLongTextThreshold: 1500, @@ -375,6 +377,9 @@ const settingsSlice = createSlice({ setShowTopicTime: (state, action: PayloadAction) => { state.showTopicTime = action.payload }, + setPinTopicsToTop: (state, action: PayloadAction) => { + state.pinTopicsToTop = action.payload + }, setAssistantIconType: (state, action: PayloadAction) => { state.assistantIconType = action.payload }, @@ -655,6 +660,7 @@ export const { setWindowStyle, setTopicPosition, setShowTopicTime, + setPinTopicsToTop, setAssistantIconType, setPasteLongTextAsFile, setAutoCheckUpdate,