refactor: Simplify topic deletion interaction
This commit is contained in:
parent
0d236a94ab
commit
40912eaaf4
@ -139,7 +139,6 @@
|
||||
"topics.pinned": "Pinned Topics",
|
||||
"topics.title": "Topics",
|
||||
"topics.unpinned": "Unpinned Topics",
|
||||
"topics.delete.title": "Are you sure you want to delete this topic? This action cannot be undone",
|
||||
"topics.delete.shortcut": "Hold {{key}} to delete directly",
|
||||
"translate": "Translate",
|
||||
"topics.prompt": "Topic Prompts",
|
||||
|
||||
@ -139,7 +139,6 @@
|
||||
"topics.pinned": "トピックを固定",
|
||||
"topics.title": "トピック",
|
||||
"topics.unpinned": "固定解除",
|
||||
"topics.delete.title": "このトピックを削除してもよろしいですか?この操作は元に戻せません",
|
||||
"topics.delete.shortcut": "{{key}}キーを押しながらで直接削除",
|
||||
"translate": "翻訳",
|
||||
"topics.prompt": "トピック提示語",
|
||||
|
||||
@ -139,7 +139,6 @@
|
||||
"topics.pinned": "Закрепленные темы",
|
||||
"topics.title": "Топики",
|
||||
"topics.unpinned": "Открепленные темы",
|
||||
"topics.delete.title": "Вы уверены, что хотите удалить этот топик? Это действие нельзя отменить",
|
||||
"topics.delete.shortcut": "Удерживайте {{key}} для мгновенного удаления",
|
||||
"translate": "Перевести",
|
||||
"topics.prompt": "Тематические подсказки",
|
||||
|
||||
@ -141,7 +141,6 @@
|
||||
"topics.pinned": "固定话题",
|
||||
"topics.title": "话题",
|
||||
"topics.unpinned": "取消固定",
|
||||
"topics.delete.title": "确定要删除此话题吗?此操作无法撤销",
|
||||
"topics.delete.shortcut": "按住 {{key}} 可直接删除",
|
||||
"translate": "翻译",
|
||||
"topics.prompt": "话题提示词",
|
||||
|
||||
@ -139,7 +139,6 @@
|
||||
"topics.pinned": "固定話題",
|
||||
"topics.title": "話題",
|
||||
"topics.unpinned": "取消固定",
|
||||
"topics.delete.title": "確定要刪除此話題嗎?此操作無法撤銷",
|
||||
"topics.delete.shortcut": "按住 {{key}} 可直接刪除",
|
||||
"translate": "翻譯",
|
||||
"topics.prompt": "話題提示詞",
|
||||
|
||||
@ -22,10 +22,10 @@ import store from '@renderer/store'
|
||||
import { setGenerating } from '@renderer/store/runtime'
|
||||
import { Assistant, Topic } from '@renderer/types'
|
||||
import { exportTopicAsMarkdown, exportTopicToNotion, topicToMarkdown } from '@renderer/utils/export'
|
||||
import { Dropdown, MenuProps, Popconfirm, Tooltip } from 'antd'
|
||||
import { Dropdown, MenuProps, Tooltip } from 'antd'
|
||||
import dayjs from 'dayjs'
|
||||
import { findIndex } from 'lodash'
|
||||
import { FC, useCallback } from 'react'
|
||||
import { FC, useCallback, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import styled from 'styled-components'
|
||||
|
||||
@ -43,6 +43,42 @@ const Topics: FC<Props> = ({ assistant: _assistant, activeTopic, setActiveTopic
|
||||
|
||||
const borderRadius = showTopicTime ? 12 : 'var(--list-item-border-radius)'
|
||||
|
||||
const [deletingTopicId, setDeletingTopicId] = useState<string | null>(null)
|
||||
const deleteTimerRef = useRef<NodeJS.Timeout>()
|
||||
|
||||
const handleDeleteClick = useCallback((topicId: string, e: React.MouseEvent) => {
|
||||
e.stopPropagation()
|
||||
|
||||
if (deleteTimerRef.current) {
|
||||
clearTimeout(deleteTimerRef.current)
|
||||
}
|
||||
|
||||
setDeletingTopicId(topicId)
|
||||
|
||||
deleteTimerRef.current = setTimeout(() => setDeletingTopicId(null), 2000)
|
||||
}, [])
|
||||
|
||||
const onClearMessages = useCallback(() => {
|
||||
window.keyv.set(EVENT_NAMES.CHAT_COMPLETION_PAUSED, true)
|
||||
store.dispatch(setGenerating(false))
|
||||
EventEmitter.emit(EVENT_NAMES.CLEAR_MESSAGES)
|
||||
}, [])
|
||||
|
||||
const handleConfirmDelete = useCallback(
|
||||
async (topic: Topic, e: React.MouseEvent) => {
|
||||
e.stopPropagation()
|
||||
if (assistant.topics.length === 1) {
|
||||
return onClearMessages()
|
||||
}
|
||||
await modelGenerating()
|
||||
const index = findIndex(assistant.topics, (t) => t.id === topic.id)
|
||||
setActiveTopic(assistant.topics[index + 1 === assistant.topics.length ? index - 1 : index + 1])
|
||||
removeTopic(topic)
|
||||
setDeletingTopicId(null)
|
||||
},
|
||||
[assistant.topics, onClearMessages, removeTopic, setActiveTopic]
|
||||
)
|
||||
|
||||
const onPinTopic = useCallback(
|
||||
(topic: Topic) => {
|
||||
const updatedTopic = { ...topic, pinned: !topic.pinned }
|
||||
@ -79,12 +115,6 @@ const Topics: FC<Props> = ({ assistant: _assistant, activeTopic, setActiveTopic
|
||||
[setActiveTopic]
|
||||
)
|
||||
|
||||
const onClearMessages = useCallback(() => {
|
||||
window.keyv.set(EVENT_NAMES.CHAT_COMPLETION_PAUSED, true)
|
||||
store.dispatch(setGenerating(false))
|
||||
EventEmitter.emit(EVENT_NAMES.CLEAR_MESSAGES)
|
||||
}, [])
|
||||
|
||||
const getTopicMenuItems = useCallback(
|
||||
(topic: Topic) => {
|
||||
const menus: MenuProps['items'] = [
|
||||
@ -245,54 +275,34 @@ const Topics: FC<Props> = ({ assistant: _assistant, activeTopic, setActiveTopic
|
||||
)}
|
||||
<MenuButton className="pin">{topic.pinned && <PushpinOutlined />}</MenuButton>
|
||||
{isActive && !topic.pinned && (
|
||||
<Popconfirm
|
||||
title={t('chat.topics.delete.title')}
|
||||
placement="top"
|
||||
okButtonProps={{ danger: true }}
|
||||
okText={t('common.delete')}
|
||||
onConfirm={async (e) => {
|
||||
e?.stopPropagation()
|
||||
if (assistant.topics.length === 1) {
|
||||
return onClearMessages()
|
||||
}
|
||||
await modelGenerating()
|
||||
const index = findIndex(assistant.topics, (t) => t.id === topic.id)
|
||||
setActiveTopic(assistant.topics[index + 1 === assistant.topics.length ? index - 1 : index + 1])
|
||||
removeTopic(topic)
|
||||
}}
|
||||
onCancel={(e) => e?.stopPropagation()}>
|
||||
<Tooltip
|
||||
placement="bottom"
|
||||
mouseEnterDelay={0.7}
|
||||
title={
|
||||
<div>
|
||||
<div style={{ fontSize: '12px', opacity: 0.8, fontStyle: 'italic' }}>
|
||||
{t('chat.topics.delete.shortcut', {
|
||||
key: isMac ? '⌘' : 'Ctrl'
|
||||
})}
|
||||
{t('chat.topics.delete.shortcut', { key: isMac ? '⌘' : 'Ctrl' })}
|
||||
</div>
|
||||
</div>
|
||||
}>
|
||||
<MenuButton
|
||||
className="menu"
|
||||
onClick={async (e) => {
|
||||
e.stopPropagation()
|
||||
if (assistant.topics.length === 1) {
|
||||
return onClearMessages()
|
||||
}
|
||||
onClick={(e) => {
|
||||
if (e.ctrlKey || e.metaKey) {
|
||||
await modelGenerating()
|
||||
const index = findIndex(assistant.topics, (t) => t.id === topic.id)
|
||||
setActiveTopic(
|
||||
assistant.topics[index + 1 === assistant.topics.length ? index - 1 : index + 1]
|
||||
)
|
||||
removeTopic(topic)
|
||||
handleConfirmDelete(topic, e)
|
||||
} else if (deletingTopicId === topic.id) {
|
||||
handleConfirmDelete(topic, e)
|
||||
} else {
|
||||
handleDeleteClick(topic.id, e)
|
||||
}
|
||||
}}>
|
||||
{deletingTopicId === topic.id ? (
|
||||
<DeleteOutlined style={{ color: 'var(--color-error)' }} />
|
||||
) : (
|
||||
<CloseOutlined />
|
||||
)}
|
||||
</MenuButton>
|
||||
</Tooltip>
|
||||
</Popconfirm>
|
||||
)}
|
||||
</TopicListItem>
|
||||
</Dropdown>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user