UNPKG

@ant-design/x-sdk

Version:

placeholder for @ant-design/x-sdk

111 lines 3.29 kB
import { useEffect, useState, useSyncExternalStore } from 'react'; export const chatMessagesStoreHelper = { _chatMessagesStores: new Map(), get: conversationKey => { return chatMessagesStoreHelper._chatMessagesStores.get(conversationKey); }, set: (key, store) => { chatMessagesStoreHelper._chatMessagesStores.set(key, store); }, delete: key => { chatMessagesStoreHelper._chatMessagesStores.delete(key); }, getMessages: conversationKey => { const store = chatMessagesStoreHelper._chatMessagesStores.get(conversationKey); return store?.getMessages(); } }; export class ChatMessagesStore { messages = []; listeners = []; conversationKey; emitListeners() { this.listeners.forEach(listener => { listener(); }); } constructor(defaultMessages, conversationKey) { this.setMessages(defaultMessages); if (conversationKey) { this.conversationKey = conversationKey; chatMessagesStoreHelper.set(this.conversationKey, this); } } setMessages = messages => { let list; if (typeof messages === 'function') { list = messages(this.messages); } else { list = messages; } this.messages = [...list]; this.emitListeners(); return true; }; getMessages = () => { return this.messages; }; getMessage = id => { return this.messages.find(item => item.id === id); }; addMessage = message => { const exist = this.getMessage(message.id); if (!exist) { this.setMessages([...this.messages, message]); return true; } return false; }; setMessage = (id, message) => { const originMessage = this.getMessage(id); if (originMessage) { const mergeMessage = typeof message === 'function' ? message(originMessage) : message; Object.assign(originMessage, mergeMessage); this.setMessages([...this.messages]); return true; } return false; }; removeMessage = id => { const index = this.messages.findIndex(item => item.id === id); if (index !== -1) { this.messages.splice(index, 1); this.setMessages([...this.messages]); return true; } return false; }; getSnapshot = () => { return this.messages; }; subscribe = callback => { this.listeners.push(callback); return () => { this.listeners = this.listeners.filter(listener => listener !== callback); }; }; } export function useChatStore(defaultValue, conversationKey) { const createStore = () => { if (conversationKey && chatMessagesStoreHelper.get(conversationKey)) { return chatMessagesStoreHelper.get(conversationKey); } const messages = typeof defaultValue === 'function' ? defaultValue() : defaultValue; const store = new ChatMessagesStore(messages || [], conversationKey); return store; }; const [store, setStore] = useState(createStore); useEffect(() => { setStore(createStore()); }, [conversationKey]); const messages = useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot); return { messages, addMessage: store.addMessage, removeMessage: store.removeMessage, setMessage: store.setMessage, getMessage: store.getMessage, setMessages: store.setMessages, getMessages: store.getMessages }; }