@ant-design/x-sdk
Version:
placeholder for @ant-design/x-sdk
111 lines • 3.29 kB
JavaScript
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
};
}