From 622e3f0db6df8eaf67a04d44d732086d66992d13 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Sat, 10 Jan 2026 21:37:37 +0800 Subject: [PATCH] feat: Add year to topic timestamp and improve unpin UX (#12408) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Initial plan * feat: Add year to topic time display format Co-authored-by: GeorgeDong32 <98630204+GeorgeDong32@users.noreply.github.com> * fix: improve topic unpin UX by moving to top of unpinned list - Unpinned topics now move to the top of the unpinned section - List automatically scrolls to the unpinned topic position - Keeps the requirement to unpin before deleting pinned topics Closes #12398 --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: GeorgeDong32 <98630204+GeorgeDong32@users.noreply.github.com> Co-authored-by: George·Dong --- .../src/pages/home/Tabs/components/Topics.tsx | 43 ++++++++++++++++++- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/src/renderer/src/pages/home/Tabs/components/Topics.tsx b/src/renderer/src/pages/home/Tabs/components/Topics.tsx index 29232e65d9..e0f88a9c80 100644 --- a/src/renderer/src/pages/home/Tabs/components/Topics.tsx +++ b/src/renderer/src/pages/home/Tabs/components/Topics.tsx @@ -1,4 +1,5 @@ import AssistantAvatar from '@renderer/components/Avatar/AssistantAvatar' +import type { DraggableVirtualListRef } from '@renderer/components/DraggableList' import { DraggableVirtualList } from '@renderer/components/DraggableList' import { CopyIcon, DeleteIcon, EditIcon } from '@renderer/components/Icons' import ObsidianExportPopup from '@renderer/components/Popups/ObsidianExportPopup' @@ -85,6 +86,7 @@ export const Topics: React.FC = ({ assistant: _assistant, activeTopic, se const [deletingTopicId, setDeletingTopicId] = useState(null) const deleteTimerRef = useRef(null) const [editingTopicId, setEditingTopicId] = useState(null) + const listRef = useRef(null) // 管理模式状态 const manageState = useTopicManageMode() @@ -168,10 +170,46 @@ export const Topics: React.FC = ({ assistant: _assistant, activeTopic, se const onPinTopic = useCallback( (topic: Topic) => { + let newIndex = 0 + + if (topic.pinned) { + // 取消固定:将话题移到未固定话题的顶部 + const pinnedTopics = assistant.topics.filter((t) => t.pinned) + const unpinnedTopics = assistant.topics.filter((t) => !t.pinned) + + // 构建新顺序:其他固定话题 + 取消固定的话题(移到顶部) + 其他未固定话题 + const reorderedTopics = [ + ...pinnedTopics.filter((t) => t.id !== topic.id), // 其他固定话题 + topic, // 取消固定的话题移到顶部 + ...unpinnedTopics // 其他未固定话题 + ] + + newIndex = pinnedTopics.length - 1 // 最后一个固定话题的索引 + 1 = 第一个未固定的索引 + updateTopics(reorderedTopics) + } else { + // 固定话题:移到固定区域顶部 + const pinnedTopics = assistant.topics.filter((t) => t.pinned) + const unpinnedTopics = assistant.topics.filter((t) => !t.pinned) + + const reorderedTopics = [ + topic, // 新固定的话题移到顶部 + ...pinnedTopics, // 其他固定话题 + ...unpinnedTopics.filter((t) => t.id !== topic.id) // 其他未固定话题(排除 topic) + ] + + newIndex = 0 + updateTopics(reorderedTopics) + } + const updatedTopic = { ...topic, pinned: !topic.pinned } updateTopic(updatedTopic) + + // 延迟滚动到话题位置(等待渲染完成) + setTimeout(() => { + listRef.current?.scrollToIndex(newIndex, { align: 'auto' }) + }, 50) }, - [updateTopic] + [assistant.topics, updateTopic, updateTopics] ) const onDeleteTopic = useCallback( @@ -529,6 +567,7 @@ export const Topics: React.FC = ({ assistant: _assistant, activeTopic, se return ( <> = ({ assistant: _assistant, activeTopic, se )} {showTopicTime && ( - {dayjs(topic.createdAt).format('MM/DD HH:mm')} + {dayjs(topic.createdAt).format('YYYY/MM/DD HH:mm')} )}