import { FetchState, TicketMessage } from "@frontend/kitui"; import { create } from "zustand"; import { createJSONStorage, devtools, persist } from "zustand/middleware"; import { useUserStore } from "./user"; import { produce } from "immer"; type SessionData = { ticketId: string; sessionId: string; }; interface AuthData { sessionData: SessionData | null; isMessageSending: boolean; messages: TicketMessage[]; apiPage: number; messagesPerPage: number; lastMessageId: string | undefined; isPreventAutoscroll: boolean; unauthTicketMessageFetchState: FetchState; } interface TicketStore { unauthData: AuthData; authData: AuthData; } const initAuthData = { sessionData: null, isMessageSending: false, messages: [], apiPage: 0, messagesPerPage: 10, lastMessageId: undefined, isPreventAutoscroll: false, unauthTicketMessageFetchState: "idle" as FetchState, }; const initState = { unauthData: initAuthData, authData: initAuthData, }; export const useTicketStore = create()( persist( devtools((set, get) => initState, { name: "Unauth tickets", }), { version: 0, name: "unauth-ticket", storage: createJSONStorage(() => localStorage), }, ), ); export const cleanAuthTicketData = () => { useTicketStore.setState({ authData: initAuthData }); }; export const setTicketData = (sessionData: SessionData) => updateTicket((ticket) => { ticket.sessionData = sessionData; }); export const setIsMessageSending = ( isMessageSending: AuthData["isMessageSending"], ) => updateTicket((ticket) => { ticket.isMessageSending = isMessageSending; }); export const addOrUpdateUnauthMessages = (receivedMessages: TicketMessage[]) => updateTicket((ticket) => { const filtered = filterMessageUncompleteness(receivedMessages); console.log(filtered); if (filtered.length === 0) return; const messageIdToMessageMap: { [messageId: string]: TicketMessage } = {}; [...ticket.messages, ...filtered].forEach( (message) => (messageIdToMessageMap[message.id] = message), ); const sortedMessages = Object.values(messageIdToMessageMap).sort( sortMessagesByTime, ); ticket.messages = sortedMessages; ticket.lastMessageId = sortedMessages.at(-1)?.id; }); export const incrementUnauthMessage = () => updateTicket((ticket) => { ticket.apiPage++; }); export const setUnauthIsPreventAutoscroll = (isPreventAutoscroll: boolean) => updateTicket((ticket) => { ticket.isPreventAutoscroll = isPreventAutoscroll; }); export const setUnauthTicketMessageFetchState = ( unauthTicketMessageFetchState: FetchState, ) => updateTicket((ticket) => { ticket.unauthTicketMessageFetchState = unauthTicketMessageFetchState; }); function sortMessagesByTime(ticket1: TicketMessage, ticket2: TicketMessage) { const date1 = new Date(ticket1.created_at).getTime(); const date2 = new Date(ticket2.created_at).getTime(); return date1 - date2; } function filterMessageUncompleteness(messages: TicketMessage[]) { return messages.filter( (message) => "id" in message && "ticket_id" in message && "user_id" in message && "session_id" in message && "message" in message && "files" in message && "shown" in message && "request_screenshot" in message && "created_at" in message && ((message.files !== null && message.files.length > 0) || message.message.length > 0), ); } export const updateTicket = ( recipe: (ticket: AuthData) => void, ) => setProducedState( (state) => { //В зависимости от авторизованности вызывается изменение разных объектов if (Boolean(useUserStore.getState().userId)) { recipe(state.authData); } else { recipe(state.unauthData); } }, { type: "updateTicket", recipe, }, ); function setProducedState( recipe: (state: TicketStore) => void, action?: A, ) { useTicketStore.setState((state) => produce(state, recipe), false, action); }