mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-06 05:09:09 +08:00
feat: support pin topic to the top
Signed-off-by: jtsang4 <info@jtsang.me>
This commit is contained in:
parent
ee042e11f1
commit
631fa3a42a
@ -12,6 +12,7 @@ import {
|
|||||||
setTheme,
|
setTheme,
|
||||||
SettingsState,
|
SettingsState,
|
||||||
setTopicPosition,
|
setTopicPosition,
|
||||||
|
setPinTopicsToTop,
|
||||||
setTray as _setTray,
|
setTray as _setTray,
|
||||||
setTrayOnClose,
|
setTrayOnClose,
|
||||||
setWindowStyle
|
setWindowStyle
|
||||||
@ -68,6 +69,9 @@ export function useSettings() {
|
|||||||
setTopicPosition(topicPosition: 'left' | 'right') {
|
setTopicPosition(topicPosition: 'left' | 'right') {
|
||||||
dispatch(setTopicPosition(topicPosition))
|
dispatch(setTopicPosition(topicPosition))
|
||||||
},
|
},
|
||||||
|
setPinTopicsToTop(pinTopicsToTop: boolean) {
|
||||||
|
dispatch(setPinTopicsToTop(pinTopicsToTop))
|
||||||
|
},
|
||||||
updateSidebarIcons(icons: { visible: SidebarIcon[]; disabled: SidebarIcon[] }) {
|
updateSidebarIcons(icons: { visible: SidebarIcon[]; disabled: SidebarIcon[] }) {
|
||||||
dispatch(setSidebarIcons(icons))
|
dispatch(setSidebarIcons(icons))
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1635,6 +1635,7 @@
|
|||||||
"topic.position.left": "Left",
|
"topic.position.left": "Left",
|
||||||
"topic.position.right": "Right",
|
"topic.position.right": "Right",
|
||||||
"topic.show.time": "Show topic time",
|
"topic.show.time": "Show topic time",
|
||||||
|
"topic.pin_to_top": "Pin Topics to Top",
|
||||||
"tray.onclose": "Minimize to Tray on Close",
|
"tray.onclose": "Minimize to Tray on Close",
|
||||||
"tray.show": "Show Tray Icon",
|
"tray.show": "Show Tray Icon",
|
||||||
"tray.title": "Tray",
|
"tray.title": "Tray",
|
||||||
|
|||||||
@ -1626,6 +1626,7 @@
|
|||||||
"topic.position.left": "左",
|
"topic.position.left": "左",
|
||||||
"topic.position.right": "右",
|
"topic.position.right": "右",
|
||||||
"topic.show.time": "トピックの時間を表示",
|
"topic.show.time": "トピックの時間を表示",
|
||||||
|
"topic.pin_to_top": "固定トピックを上部に表示",
|
||||||
"tray.onclose": "閉じるときにトレイに最小化",
|
"tray.onclose": "閉じるときにトレイに最小化",
|
||||||
"tray.show": "トレイアイコンを表示",
|
"tray.show": "トレイアイコンを表示",
|
||||||
"tray.title": "トレイ",
|
"tray.title": "トレイ",
|
||||||
|
|||||||
@ -1626,6 +1626,7 @@
|
|||||||
"topic.position.left": "Слева",
|
"topic.position.left": "Слева",
|
||||||
"topic.position.right": "Справа",
|
"topic.position.right": "Справа",
|
||||||
"topic.show.time": "Показывать время топика",
|
"topic.show.time": "Показывать время топика",
|
||||||
|
"topic.pin_to_top": "Закрепленные топики сверху",
|
||||||
"tray.onclose": "Свернуть в трей при закрытии",
|
"tray.onclose": "Свернуть в трей при закрытии",
|
||||||
"tray.show": "Показать значок в трее",
|
"tray.show": "Показать значок в трее",
|
||||||
"tray.title": "Трей",
|
"tray.title": "Трей",
|
||||||
|
|||||||
@ -1635,6 +1635,7 @@
|
|||||||
"topic.position.left": "左侧",
|
"topic.position.left": "左侧",
|
||||||
"topic.position.right": "右侧",
|
"topic.position.right": "右侧",
|
||||||
"topic.show.time": "显示话题时间",
|
"topic.show.time": "显示话题时间",
|
||||||
|
"topic.pin_to_top": "固定话题置顶",
|
||||||
"tray.onclose": "关闭时最小化到托盘",
|
"tray.onclose": "关闭时最小化到托盘",
|
||||||
"tray.show": "显示托盘图标",
|
"tray.show": "显示托盘图标",
|
||||||
"tray.title": "托盘",
|
"tray.title": "托盘",
|
||||||
|
|||||||
@ -1629,6 +1629,7 @@
|
|||||||
"topic.position.left": "左側",
|
"topic.position.left": "左側",
|
||||||
"topic.position.right": "右側",
|
"topic.position.right": "右側",
|
||||||
"topic.show.time": "顯示話題時間",
|
"topic.show.time": "顯示話題時間",
|
||||||
|
"topic.pin_to_top": "固定話題置頂",
|
||||||
"tray.onclose": "關閉時最小化到系统匣",
|
"tray.onclose": "關閉時最小化到系统匣",
|
||||||
"tray.show": "顯示系统匣圖示",
|
"tray.show": "顯示系统匣圖示",
|
||||||
"tray.title": "系统匣",
|
"tray.title": "系统匣",
|
||||||
|
|||||||
@ -54,7 +54,7 @@ const Topics: FC<Props> = ({ assistant: _assistant, activeTopic, setActiveTopic
|
|||||||
const { assistants } = useAssistants()
|
const { assistants } = useAssistants()
|
||||||
const { assistant, removeTopic, moveTopic, updateTopic, updateTopics } = useAssistant(_assistant.id)
|
const { assistant, removeTopic, moveTopic, updateTopic, updateTopics } = useAssistant(_assistant.id)
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const { showTopicTime, topicPosition } = useSettings()
|
const { showTopicTime, topicPosition, pinTopicsToTop } = useSettings()
|
||||||
|
|
||||||
const borderRadius = showTopicTime ? 12 : 'var(--list-item-border-radius)'
|
const borderRadius = showTopicTime ? 12 : 'var(--list-item-border-radius)'
|
||||||
|
|
||||||
@ -380,10 +380,22 @@ const Topics: FC<Props> = ({ assistant: _assistant, activeTopic, setActiveTopic
|
|||||||
targetTopic
|
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 (
|
return (
|
||||||
<Dropdown menu={{ items: getTopicMenuItems }} trigger={['contextMenu']}>
|
<Dropdown menu={{ items: getTopicMenuItems }} trigger={['contextMenu']}>
|
||||||
<Container right={topicPosition === 'right'} className="topics-tab">
|
<Container right={topicPosition === 'right'} className="topics-tab">
|
||||||
<DragableList list={assistant.topics} onUpdate={updateTopics}>
|
<DragableList list={sortedTopics} onUpdate={updateTopics}>
|
||||||
{(topic) => {
|
{(topic) => {
|
||||||
const isActive = topic.id === activeTopic?.id
|
const isActive = topic.id === activeTopic?.id
|
||||||
const topicName = topic.name.replace('`', '')
|
const topicName = topic.name.replace('`', '')
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import {
|
|||||||
setAssistantIconType,
|
setAssistantIconType,
|
||||||
setClickAssistantToShowTopic,
|
setClickAssistantToShowTopic,
|
||||||
setCustomCss,
|
setCustomCss,
|
||||||
|
setPinTopicsToTop,
|
||||||
setShowTopicTime,
|
setShowTopicTime,
|
||||||
setSidebarIcons
|
setSidebarIcons
|
||||||
} from '@renderer/store/settings'
|
} from '@renderer/store/settings'
|
||||||
@ -32,6 +33,7 @@ const DisplaySettings: FC = () => {
|
|||||||
setTopicPosition,
|
setTopicPosition,
|
||||||
clickAssistantToShowTopic,
|
clickAssistantToShowTopic,
|
||||||
showTopicTime,
|
showTopicTime,
|
||||||
|
pinTopicsToTop,
|
||||||
customCss,
|
customCss,
|
||||||
sidebarIcons,
|
sidebarIcons,
|
||||||
assistantIconType
|
assistantIconType
|
||||||
@ -189,6 +191,11 @@ const DisplaySettings: FC = () => {
|
|||||||
<SettingRowTitle>{t('settings.topic.show.time')}</SettingRowTitle>
|
<SettingRowTitle>{t('settings.topic.show.time')}</SettingRowTitle>
|
||||||
<Switch checked={showTopicTime} onChange={(checked) => dispatch(setShowTopicTime(checked))} />
|
<Switch checked={showTopicTime} onChange={(checked) => dispatch(setShowTopicTime(checked))} />
|
||||||
</SettingRow>
|
</SettingRow>
|
||||||
|
<SettingDivider />
|
||||||
|
<SettingRow>
|
||||||
|
<SettingRowTitle>{t('settings.topic.pin_to_top')}</SettingRowTitle>
|
||||||
|
<Switch checked={pinTopicsToTop} onChange={(checked) => dispatch(setPinTopicsToTop(checked))} />
|
||||||
|
</SettingRow>
|
||||||
</SettingGroup>
|
</SettingGroup>
|
||||||
<SettingGroup theme={theme}>
|
<SettingGroup theme={theme}>
|
||||||
<SettingTitle>{t('settings.display.assistant.title')}</SettingTitle>
|
<SettingTitle>{t('settings.display.assistant.title')}</SettingTitle>
|
||||||
|
|||||||
@ -52,6 +52,7 @@ export interface SettingsState {
|
|||||||
fontSize: number
|
fontSize: number
|
||||||
topicPosition: 'left' | 'right'
|
topicPosition: 'left' | 'right'
|
||||||
showTopicTime: boolean
|
showTopicTime: boolean
|
||||||
|
pinTopicsToTop: boolean
|
||||||
assistantIconType: AssistantIconType
|
assistantIconType: AssistantIconType
|
||||||
pasteLongTextAsFile: boolean
|
pasteLongTextAsFile: boolean
|
||||||
pasteLongTextThreshold: number
|
pasteLongTextThreshold: number
|
||||||
@ -192,6 +193,7 @@ export const initialState: SettingsState = {
|
|||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
topicPosition: 'left',
|
topicPosition: 'left',
|
||||||
showTopicTime: false,
|
showTopicTime: false,
|
||||||
|
pinTopicsToTop: false,
|
||||||
assistantIconType: 'emoji',
|
assistantIconType: 'emoji',
|
||||||
pasteLongTextAsFile: false,
|
pasteLongTextAsFile: false,
|
||||||
pasteLongTextThreshold: 1500,
|
pasteLongTextThreshold: 1500,
|
||||||
@ -375,6 +377,9 @@ const settingsSlice = createSlice({
|
|||||||
setShowTopicTime: (state, action: PayloadAction<boolean>) => {
|
setShowTopicTime: (state, action: PayloadAction<boolean>) => {
|
||||||
state.showTopicTime = action.payload
|
state.showTopicTime = action.payload
|
||||||
},
|
},
|
||||||
|
setPinTopicsToTop: (state, action: PayloadAction<boolean>) => {
|
||||||
|
state.pinTopicsToTop = action.payload
|
||||||
|
},
|
||||||
setAssistantIconType: (state, action: PayloadAction<AssistantIconType>) => {
|
setAssistantIconType: (state, action: PayloadAction<AssistantIconType>) => {
|
||||||
state.assistantIconType = action.payload
|
state.assistantIconType = action.payload
|
||||||
},
|
},
|
||||||
@ -655,6 +660,7 @@ export const {
|
|||||||
setWindowStyle,
|
setWindowStyle,
|
||||||
setTopicPosition,
|
setTopicPosition,
|
||||||
setShowTopicTime,
|
setShowTopicTime,
|
||||||
|
setPinTopicsToTop,
|
||||||
setAssistantIconType,
|
setAssistantIconType,
|
||||||
setPasteLongTextAsFile,
|
setPasteLongTextAsFile,
|
||||||
setAutoCheckUpdate,
|
setAutoCheckUpdate,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user