mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-11 16:39:15 +08:00
feat: Add year to topic timestamp and improve unpin UX (#12408)
* 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 <GeorgeDong32@qq.com>
This commit is contained in:
parent
e5a2980da8
commit
622e3f0db6
@ -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<Props> = ({ assistant: _assistant, activeTopic, se
|
||||
const [deletingTopicId, setDeletingTopicId] = useState<string | null>(null)
|
||||
const deleteTimerRef = useRef<NodeJS.Timeout>(null)
|
||||
const [editingTopicId, setEditingTopicId] = useState<string | null>(null)
|
||||
const listRef = useRef<DraggableVirtualListRef>(null)
|
||||
|
||||
// 管理模式状态
|
||||
const manageState = useTopicManageMode()
|
||||
@ -168,10 +170,46 @@ export const Topics: React.FC<Props> = ({ 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<Props> = ({ assistant: _assistant, activeTopic, se
|
||||
return (
|
||||
<>
|
||||
<DraggableVirtualList
|
||||
ref={listRef}
|
||||
className="topics-tab"
|
||||
list={filteredTopics}
|
||||
onUpdate={updateTopics}
|
||||
@ -663,7 +702,7 @@ export const Topics: React.FC<Props> = ({ assistant: _assistant, activeTopic, se
|
||||
</TopicPromptText>
|
||||
)}
|
||||
{showTopicTime && (
|
||||
<TopicTime className="time">{dayjs(topic.createdAt).format('MM/DD HH:mm')}</TopicTime>
|
||||
<TopicTime className="time">{dayjs(topic.createdAt).format('YYYY/MM/DD HH:mm')}</TopicTime>
|
||||
)}
|
||||
</TopicListItem>
|
||||
</Dropdown>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user