feat: clear conversation

This commit is contained in:
kangfenmao 2024-07-02 18:48:32 +08:00
parent 0b6d15ec65
commit 7f61ab2a21
5 changed files with 63 additions and 32 deletions

View File

@ -54,10 +54,15 @@ const Conversations: FC<Props> = ({ agent, topic }) => {
onSendMessage(msg) onSendMessage(msg)
setTimeout(() => EventEmitter.emit(EVENT_NAMES.AI_AUTO_RENAME), 100) setTimeout(() => EventEmitter.emit(EVENT_NAMES.AI_AUTO_RENAME), 100)
}), }),
EventEmitter.on(EVENT_NAMES.AI_AUTO_RENAME, autoRenameTopic) EventEmitter.on(EVENT_NAMES.AI_AUTO_RENAME, autoRenameTopic),
EventEmitter.on(EVENT_NAMES.CLEAR_CONVERSATION, () => {
setMessages([])
updateTopic({ ...topic, messages: [] })
LocalStorage.clearTopicMessages(topic.id)
})
] ]
return () => unsubscribes.forEach((unsub) => unsub()) return () => unsubscribes.forEach((unsub) => unsub())
}, [agent, autoRenameTopic, onSendMessage, topic]) }, [agent, autoRenameTopic, onSendMessage, topic, updateTopic])
useEffect(() => { useEffect(() => {
runAsyncFunction(async () => { runAsyncFunction(async () => {

View File

@ -4,9 +4,10 @@ import { uuid } from '@renderer/utils'
import { FC, useState } from 'react' import { FC, useState } from 'react'
import styled from 'styled-components' import styled from 'styled-components'
import { MoreOutlined } from '@ant-design/icons' import { MoreOutlined } from '@ant-design/icons'
import { Tooltip } from 'antd' import { Button, Popconfirm, Tooltip } from 'antd'
import { useShowRightSidebar } from '@renderer/hooks/useStore' import { useShowRightSidebar } from '@renderer/hooks/useStore'
import { useAgent } from '@renderer/hooks/useAgents' import { useAgent } from '@renderer/hooks/useAgents'
import { ClearOutlined, HistoryOutlined, PlusCircleOutlined } from '@ant-design/icons'
interface Props { interface Props {
agent: Agent agent: Agent
@ -48,26 +49,44 @@ const Inputbar: FC<Props> = ({ agent, setActiveTopic }) => {
setActiveTopic(topic) setActiveTopic(topic)
} }
const clearTopic = () => {
EventEmitter.emit(EVENT_NAMES.CLEAR_CONVERSATION)
}
return ( return (
<Container> <Container>
<Toolbar> <Toolbar>
<ToolbarMenu> <ToolbarMenu>
<Tooltip placement="top" title=" New Chat " arrow> <Tooltip placement="top" title=" New Chat " arrow>
<ToolbarItem onClick={addNewConversation}> <ToolbarButton type="text" onClick={addNewConversation}>
<i className="iconfont icon-a-new-chat"></i> <PlusCircleOutlined />
</ToolbarItem> </ToolbarButton>
</Tooltip> </Tooltip>
<Tooltip placement="top" title=" Topics " arrow> <Tooltip placement="top" title=" Topics " arrow>
<ToolbarItem onClick={setShowRightSidebar}> <ToolbarButton type="text" onClick={setShowRightSidebar}>
<i className="iconfont icon-textedit_text_topic" /> <HistoryOutlined />
</ToolbarItem> </ToolbarButton>
</Tooltip>
<Tooltip placement="top" title=" Clear " arrow>
<Popconfirm
icon={false}
title="Clear all messages?"
description="Are you sure to clear all messages?"
placement="top"
onConfirm={clearTopic}
okText="Clear"
cancelText="Cancel">
<ToolbarButton type="text">
<ClearOutlined />
</ToolbarButton>
</Popconfirm>
</Tooltip> </Tooltip>
</ToolbarMenu> </ToolbarMenu>
<ToolbarMenu> <ToolbarMenu>
<Tooltip placement="top" title=" Settings " arrow> <Tooltip placement="top" title=" Settings " arrow>
<ToolbarItem style={{ marginRight: 0 }}> <ToolbarButton type="text" style={{ marginRight: 0 }}>
<MoreOutlined /> <MoreOutlined />
</ToolbarItem> </ToolbarButton>
</Tooltip> </Tooltip>
</ToolbarMenu> </ToolbarMenu>
</Toolbar> </Toolbar>
@ -75,7 +94,7 @@ const Inputbar: FC<Props> = ({ agent, setActiveTopic }) => {
value={text} value={text}
onChange={(e) => setText(e.target.value)} onChange={(e) => setText(e.target.value)}
onKeyDown={handleKeyDown} onKeyDown={handleKeyDown}
placeholder="Type a message..." placeholder="Type your message here..."
autoFocus autoFocus
contextMenu="true" contextMenu="true"
/> />
@ -98,7 +117,8 @@ const Textarea = styled.textarea`
border: none; border: none;
outline: none; outline: none;
resize: none; resize: none;
font-size: 14px; font-size: 13px;
line-height: 18px;
color: var(--color-text); color: var(--color-text);
background-color: transparent; background-color: transparent;
` `
@ -107,8 +127,8 @@ const Toolbar = styled.div`
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: space-between; justify-content: space-between;
margin-bottom: 5px;
margin: 0 -5px; margin: 0 -5px;
margin-bottom: 5px;
` `
const ToolbarMenu = styled.div` const ToolbarMenu = styled.div`
@ -117,29 +137,21 @@ const ToolbarMenu = styled.div`
align-items: center; align-items: center;
` `
const ToolbarItem = styled.div` const ToolbarButton = styled(Button)`
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
cursor: pointer;
width: 32px; width: 32px;
height: 32px; height: 32px;
font-size: 18px; font-size: 18px;
border-radius: 50%; border-radius: 50%;
transition: all 0.2s ease-in-out; transition: all 0.3s ease;
margin-right: 6px; margin-right: 6px;
color: var(--color-icon); color: var(--color-icon);
.iconfont { &.anticon {
font-size: 18px; transition: all 0.3s ease;
transition: all 0.2s ease-in-out; color: var(--color-icon);
}
.icon-textedit_text_topic {
font-size: 20px;
} }
&:hover { &:hover {
background-color: var(--color-background-soft); background-color: var(--color-background-soft);
.iconfont { .anticon {
color: white; color: white;
} }
} }

View File

@ -76,12 +76,14 @@ const TopicList: FC<Props> = ({ agent, activeTopic, setActiveTopic }) => {
<TopicTitle> <TopicTitle>
<span>Topics ({agent.topics.length})</span> <span>Topics ({agent.topics.length})</span>
<Popconfirm <Popconfirm
icon={false}
title="Delete all topic?" title="Delete all topic?"
description="Are you sure to delete all topics?" description="Are you sure to delete all topics?"
placement="leftBottom" placement="leftBottom"
onConfirm={removeAllTopics} onConfirm={removeAllTopics}
okText="Yes" okText="Delete All"
cancelText="No"> okType="danger"
cancelText="Cancel">
<DeleteButton type="text"> <DeleteButton type="text">
<DeleteIcon /> <DeleteIcon />
</DeleteButton> </DeleteButton>

View File

@ -5,5 +5,6 @@ export const EventEmitter = new Emittery()
export const EVENT_NAMES = { export const EVENT_NAMES = {
SEND_MESSAGE: 'SEND_MESSAGE', SEND_MESSAGE: 'SEND_MESSAGE',
AI_CHAT_COMPLETION: 'AI_CHAT_COMPLETION', AI_CHAT_COMPLETION: 'AI_CHAT_COMPLETION',
AI_AUTO_RENAME: 'AI_AUTO_RENAME' AI_AUTO_RENAME: 'AI_AUTO_RENAME',
CLEAR_CONVERSATION: 'CLEAR_CONVERSATION'
} }

View File

@ -2,12 +2,23 @@ import { Topic } from '@renderer/types'
import localforage from 'localforage' import localforage from 'localforage'
export default class LocalStorage { export default class LocalStorage {
static async getTopic(id: string) {
return localforage.getItem<Topic>(`topic:${id}`)
}
static async getTopicMessages(id: string) { static async getTopicMessages(id: string) {
const topic = await localforage.getItem<Topic>(`topic:${id}`) const topic = await this.getTopic(id)
return topic ? topic.messages : [] return topic ? topic.messages : []
} }
static async removeTopic(id: string) { static async removeTopic(id: string) {
localforage.removeItem(`topic:${id}`) localforage.removeItem(`topic:${id}`)
} }
static async clearTopicMessages(id: string) {
const topic = await this.getTopic(id)
if (topic) {
topic.messages = []
await localforage.setItem(`topic:${id}`, topic)
}
}
} }