import { get, readonly, writable } from 'svelte/store'; import { getChatList, getPinnedChatList } from '$lib/apis/chats'; type ChatListItem = { id: string; [key: string]: unknown; }; const chatsStore = writable(null); const pinnedChatsStore = writable([]); export const chats = readonly(chatsStore); export const pinnedChats = readonly(pinnedChatsStore); let currentPage = 1; let paginationReady = false; let requestGeneration = 0; let allLoaded = false; let loadingNextPage = false; type RefreshChatListOptions = { refreshPinned?: boolean; clearPinned?: boolean; }; type ChatListResult = { accepted: boolean; allLoaded: boolean; }; export const refreshChatList = async ( token: string = '', options: RefreshChatListOptions = {} ): Promise => { const generation = ++requestGeneration; paginationReady = false; loadingNextPage = false; const [nextChats, nextPinnedChats] = await Promise.all([ getChatList(token, 1) as Promise, options.refreshPinned && !options.clearPinned ? (getPinnedChatList(token) as Promise) : Promise.resolve(undefined as ChatListItem[] | undefined) ]); if (generation !== requestGeneration) { return { accepted: false, allLoaded }; } chatsStore.set(nextChats); currentPage = 1; allLoaded = nextChats.length === 0; if (options.clearPinned) { pinnedChatsStore.set([]); } else if (options.refreshPinned) { pinnedChatsStore.set(nextPinnedChats ?? []); } paginationReady = true; return { accepted: true, allLoaded }; }; export const loadNextChatListPage = async (token: string = ''): Promise => { if (!paginationReady || allLoaded || loadingNextPage) { return { accepted: false, allLoaded }; } const generation = requestGeneration; const nextPage = currentPage + 1; loadingNextPage = true; try { const nextChats = (await getChatList(token, nextPage)) as ChatListItem[]; if (generation !== requestGeneration) { return { accepted: false, allLoaded }; } allLoaded = nextChats.length === 0; currentPage = nextPage; const existingIds = new Set((get(chatsStore) ?? []).map((chat) => chat.id)); const uniqueChats = nextChats.filter((chat) => !existingIds.has(chat.id)); chatsStore.set([...(get(chatsStore) ?? []), ...uniqueChats]); return { accepted: true, allLoaded }; } finally { loadingNextPage = false; } }; export const setChatActive = (chatId: string, active: boolean): boolean => { let found = false; const updateChat = (chat: ChatListItem) => { if (chat.id !== chatId) { return chat; } found = true; return { ...chat, active }; }; chatsStore.update((items) => (items ? items.map(updateChat) : items)); pinnedChatsStore.update((items) => items.map(updateChat)); return found; }; export const resetChatListState = () => { requestGeneration += 1; currentPage = 1; paginationReady = false; allLoaded = false; loadingNextPage = false; chatsStore.set(null); pinnedChatsStore.set([]); };