diff --git a/web/src/store/modules/chat/helper.ts b/web/src/store/modules/chat/helper.ts index 5a8cb6ea..0284334d 100644 --- a/web/src/store/modules/chat/helper.ts +++ b/web/src/store/modules/chat/helper.ts @@ -2,15 +2,27 @@ import { ss } from '@/utils/storage' const LOCAL_NAME = 'chatStorage' +const default_chat_data: Chat.ChatState = { + active: null, + history: [], + chat: {}, +} + export function getLocalState(): Chat.ChatState { const localState = ss.get(LOCAL_NAME) - return localState ?? { - active: null, - history: [], - chat: [], - } + return localState ?? default_chat_data } export function setLocalState(state: Chat.ChatState) { ss.set(LOCAL_NAME, state) } + +export function check_chat(chat: Chat.ChatState['chat'], need_length = true) { + const keys = Object.keys(chat) + const data: [Array, number?] = [keys] + if (need_length) { + const keys_length = keys.length + data.push(keys_length) + } + return data +} diff --git a/web/src/store/modules/chat/index.ts b/web/src/store/modules/chat/index.ts index 2b6470a4..2e4f6f12 100644 --- a/web/src/store/modules/chat/index.ts +++ b/web/src/store/modules/chat/index.ts @@ -1,7 +1,7 @@ import { defineStore } from 'pinia' import { v4 as uuidv4 } from 'uuid' -import { getLocalState, setLocalState } from './helper' +import { check_chat, getLocalState, setLocalState } from './helper' import { router } from '@/router' import { clearSessionChatMessages, @@ -45,10 +45,10 @@ export const useChatStore = defineStore('chat-store', { getChatSessionDataByUuid(state: Chat.ChatState) { return (uuid?: string) => { if (uuid) - return state.chat.find(item => item.uuid === uuid)?.data ?? [] - return ( - state.chat.find(item => item.uuid === state.active)?.data ?? [] - ) + return state.chat[uuid] ?? [] + if (state.active) + return state.chat[state.active] ?? [] + return [] } }, }, @@ -66,12 +66,8 @@ export const useChatStore = defineStore('chat-store', { async syncChatSessions() { const sessions = await getChatSessionsByUser() this.history = [] - this.chat = [] await sessions.forEach(async (r: Chat.Session) => { this.history.unshift(r) - const chatData = await getChatSessionHistory(r.uuid) - // chatData.uuid = chatData?.uuid - this.chat.unshift({ uuid: r.uuid, data: chatData }) }) if (this.history.length === 0) { const new_chat_text = t('chat.new') @@ -88,10 +84,18 @@ export const useChatStore = defineStore('chat-store', { this.reloadRoute(this.active) }, + async syncChatMessages(need_uuid: string) { + if (need_uuid) { + const messageData = await getChatSessionHistory(need_uuid) + this.chat[need_uuid] = messageData + this.reloadRoute(need_uuid) + } + }, + addChatSession(history: Chat.Session, chatData: Chat.Message[] = []) { createChatSession(history.uuid, history.title, history.model) this.history.unshift(history) - this.chat.unshift({ uuid: history.uuid, data: chatData }) + this.chat[history.uuid] = chatData this.active = history.uuid this.reloadRoute(history.uuid) }, @@ -108,8 +112,8 @@ export const useChatStore = defineStore('chat-store', { deleteChatSession(index: number) { deleteChatSession(this.history[index].uuid) + delete this.chat[this.history[index].uuid] this.history.splice(index, 1) - this.chat.splice(index, 1) if (this.history.length === 0) { this.active = null @@ -119,23 +123,20 @@ export const useChatStore = defineStore('chat-store', { if (index > 0 && index <= this.history.length) { const uuid = this.history[index - 1].uuid - this.active = uuid - this.reloadRoute(uuid) + this.setActive(uuid) return } if (index === 0) { if (this.history.length > 0) { const uuid = this.history[0].uuid - this.active = uuid - this.reloadRoute(uuid) + this.setActive(uuid) } } if (index > this.history.length) { const uuid = this.history[this.history.length - 1].uuid - this.active = uuid - this.reloadRoute(uuid) + this.setActive(uuid) } }, @@ -146,19 +147,21 @@ export const useChatStore = defineStore('chat-store', { }, getChatByUuidAndIndex(uuid: string, index: number) { + const [keys, keys_length] = check_chat(this.chat) if (!uuid) { - if (this.chat.length) - return this.chat[0].data[index] + if (keys_length) + return this.chat[uuid][index] return null } - const chatIndex = this.chat.findIndex(item => item.uuid === uuid) - if (chatIndex !== -1) - return this.chat[chatIndex].data[index] + // const chatIndex = this.chat.findIndex(item => item.uuid === uuid) + if (keys.includes(uuid)) + return this.chat[uuid][index] return null }, async addChatByUuid(uuid: string, chat: Chat.Message) { const new_chat_text = t('chat.new') + const [keys] = check_chat(this.chat, false) if (!uuid) { if (this.history.length === 0) { const uuid = uuidv4() @@ -167,12 +170,14 @@ export const useChatStore = defineStore('chat-store', { createChatSession(uuid, chat.text, default_model_parameters.model) this.history.push({ uuid, title: chat.text, isEdit: false }) // first chat message is prompt - this.chat.push({ uuid, data: [{ ...chat, isPrompt: true, isPin: false }] }) + // this.chat.push({ uuid, data: [{ ...chat, isPrompt: true, isPin: false }] }) + this.chat[uuid] = [{ ...chat, isPrompt: true, isPin: false }] this.active = uuid this.recordState() } else { - this.chat[0].data.push(chat) + // this.chat[0].data.push(chat) + this.chat[keys[0]].push(chat) if (this.history[0].title === new_chat_text) { this.history[0].title = chat.text renameChatSession(this.history[0].uuid, chat.text.substring(0, 20)) @@ -181,12 +186,12 @@ export const useChatStore = defineStore('chat-store', { } } - const index = this.chat.findIndex(item => item.uuid === uuid) - if (index !== -1) { - if (this.chat[index].data.length === 0) - this.chat[index].data.push({ ...chat, isPrompt: true, isPin: false }) + // const index = this.chat.findIndex(item => item.uuid === uuid) + if (keys.includes(uuid)) { + if (this.chat[uuid].length === 0) + this.chat[uuid].push({ ...chat, isPrompt: true, isPin: false }) else - this.chat[index].data.push(chat) + this.chat[uuid].push(chat) if (this.history[0].title === new_chat_text) { this.history[0].title = chat.text @@ -198,17 +203,18 @@ export const useChatStore = defineStore('chat-store', { async updateChatByUuid(uuid: string, index: number, chat: Chat.Message) { // TODO: sync with server + const [keys, keys_length] = check_chat(this.chat) if (!uuid) { - if (this.chat.length) { - this.chat[0].data[index] = chat + if (keys_length) { + this.chat[keys[0]][index] = chat this.recordState() } return } - const chatIndex = this.chat.findIndex(item => item.uuid === uuid) - if (chatIndex !== -1) { - this.chat[chatIndex].data[index] = chat + // const chatIndex = this.chat.findIndex(item => item.uuid === uuid) + if (keys.includes(uuid)) { + this.chat[uuid][index] = chat this.recordState() } }, @@ -218,18 +224,19 @@ export const useChatStore = defineStore('chat-store', { index: number, chat: Partial, ) { + const [keys, keys_length] = check_chat(this.chat) if (!uuid) { - if (this.chat.length) { - this.chat[0].data[index] = { ...this.chat[0].data[index], ...chat } + if (keys_length) { + this.chat[keys[0]][index] = { ...this.chat[keys[0]][index], ...chat } this.recordState() } return } - const chatIndex = this.chat.findIndex(item => item.uuid === uuid) - if (chatIndex !== -1) { - this.chat[chatIndex].data[index] = { - ...this.chat[chatIndex].data[index], + // const chatIndex = this.chat.findIndex(item => item.uuid === uuid) + if (keys.includes(uuid)) { + this.chat[uuid][index] = { + ...this.chat[uuid][index], ...chat, } this.recordState() @@ -237,9 +244,10 @@ export const useChatStore = defineStore('chat-store', { }, async deleteChatByUuid(uuid: string, index: number) { + const [keys, keys_length] = check_chat(this.chat) if (!uuid) { - if (this.chat.length) { - const chatData = this.chat[0].data + if (keys_length) { + const chatData = this.chat[keys[0]] const chat = chatData[index] chatData.splice(index, 1) this.recordState() @@ -249,9 +257,9 @@ export const useChatStore = defineStore('chat-store', { return } - const chatIndex = this.chat.findIndex(item => item.uuid === uuid) - if (chatIndex !== -1) { - const chatData = this.chat[chatIndex].data + // const chatIndex = this.chat.findIndex(item => item.uuid === uuid) + if (keys.includes(uuid)) { + const chatData = this.chat[uuid] const chat = chatData[index] chatData.splice(index, 1) this.recordState() @@ -262,29 +270,30 @@ export const useChatStore = defineStore('chat-store', { clearChatByUuid(uuid: string) { // does this every happen? + const [keys, keys_length] = check_chat(this.chat) if (!uuid) { - if (this.chat.length) { - this.chat[0].data = [] + if (keys_length) { + this.chat[keys[0]] = [] this.recordState() } return } - const index = this.chat.findIndex(item => item.uuid === uuid) - if (index !== -1) { + // const index = this.chat.findIndex(item => item.uuid === uuid) + if (keys.includes(uuid)) { const data: Chat.Message[] = [] - for (const chat of this.chat[index].data) { + for (const chat of this.chat[uuid]) { if (chat.isPin || chat.isPrompt) data.push(chat) } - this.chat[index].data = data + this.chat[uuid] = data clearSessionChatMessages(uuid) this.recordState() } }, clearState() { this.history = [] - this.chat = [] + this.chat = {} this.active = null this.recordState() }, diff --git a/web/src/typings/chat.d.ts b/web/src/typings/chat.d.ts index 7930dd18..f3131f98 100644 --- a/web/src/typings/chat.d.ts +++ b/web/src/typings/chat.d.ts @@ -28,7 +28,7 @@ declare namespace Chat { interface ChatState { active: string | null history: Session[] - chat: { uuid: string; data: Message[] }[] + chat: { [uuid: string]: Message[] } } interface ConversationRequest { diff --git a/web/src/views/chat/index.vue b/web/src/views/chat/index.vue index 80667095..41bd7cc0 100644 --- a/web/src/views/chat/index.vue +++ b/web/src/views/chat/index.vue @@ -37,8 +37,9 @@ const { scrollRef, scrollToBottom } = useScroll() // session uuid const { uuid } = route.params as { uuid: string } const sessionUuid = uuid +chatStore.syncChatMessages(sessionUuid) const dataSources = computed(() => chatStore.getChatSessionDataByUuid(sessionUuid)) -const chatSession = computed(() => chatStore.getChatSessionByUuid(uuid)) +const chatSession = computed(() => chatStore.getChatSessionByUuid(sessionUuid)) const prompt = ref('') const loading = ref(false)