FastGPT/client/src/store/shareChat.ts
2023-07-25 13:20:04 +08:00

147 lines
4.4 KiB
TypeScript

import { create } from 'zustand';
import { devtools, persist } from 'zustand/middleware';
import { immer } from 'zustand/middleware/immer';
import type { ChatSiteItemType, ShareChatHistoryItemType, ShareChatType } from '@/types/chat';
import { HUMAN_ICON } from '@/constants/chat';
import { customAlphabet } from 'nanoid';
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 12);
type State = {
shareChatData: ShareChatType;
setShareChatData: (e: ShareChatType | ((e: ShareChatType) => ShareChatType)) => void;
shareChatHistory: ShareChatHistoryItemType[];
saveChatResponse: (e: {
historyId: string;
prompts: ChatSiteItemType[];
variables: Record<string, any>;
shareId: string;
}) => { newChatId: string };
delOneShareHistoryByHistoryId: (historyId: string) => void;
delShareChatHistoryItemById: (e: { historyId: string; index: number }) => void;
delManyShareChatHistoryByShareId: (shareId?: string) => void;
};
export const defaultHistory: ShareChatHistoryItemType = {
_id: `${Date.now()}`,
updateTime: new Date(),
title: '新对话',
shareId: '',
chats: []
};
const defaultShareChatData: ShareChatType = {
maxContext: 5,
userAvatar: HUMAN_ICON,
app: {
name: '',
avatar: '/icon/logo.png',
intro: ''
},
history: defaultHistory
};
export const useShareChatStore = create<State>()(
devtools(
persist(
immer((set, get) => ({
shareChatData: defaultShareChatData,
setShareChatData(e) {
const val = (() => {
if (typeof e === 'function') {
return e(get().shareChatData);
} else {
return e;
}
})();
set((state) => {
state.shareChatData = val;
// update history
state.shareChatHistory = state.shareChatHistory.map((item) =>
item._id === val.history._id ? val.history : item
);
});
},
shareChatHistory: [],
saveChatResponse({ historyId, prompts, variables, shareId }) {
const history = get().shareChatHistory.find((item) => item._id === historyId);
const newChatId = history ? '' : nanoid();
const historyList = (() => {
if (history) {
return get().shareChatHistory.map((item) =>
item._id === historyId
? {
...item,
title: prompts[prompts.length - 2]?.value,
updateTime: new Date(),
chats: prompts,
variables
}
: item
);
}
return get().shareChatHistory.concat({
_id: newChatId,
shareId,
title: prompts[prompts.length - 2]?.value,
updateTime: new Date(),
chats: prompts,
variables
});
})();
// @ts-ignore
historyList.sort((a, b) => new Date(b.updateTime) - new Date(a.updateTime));
set((state) => {
state.shareChatHistory = historyList.slice(0, 100);
});
return {
newChatId
};
},
delOneShareHistoryByHistoryId(historyId: string) {
set((state) => {
state.shareChatHistory = state.shareChatHistory.filter(
(item) => item._id !== historyId
);
});
},
delShareChatHistoryItemById({ historyId, index }) {
set((state) => {
// update history store
const newHistoryList = state.shareChatHistory.map((item) =>
item._id === historyId
? {
...item,
chats: [...item.chats.slice(0, index), ...item.chats.slice(index + 1)]
}
: item
);
state.shareChatHistory = newHistoryList;
});
},
delManyShareChatHistoryByShareId(shareId?: string) {
set((state) => {
if (shareId) {
state.shareChatHistory = state.shareChatHistory.filter(
(item) => item.shareId !== shareId
);
} else {
state.shareChatHistory = [];
}
});
}
})),
{
name: 'shareChatStore',
partialize: (state) => ({
shareChatHistory: state.shareChatHistory
})
}
)
)
);