refac
This commit is contained in:
@@ -885,6 +885,34 @@ export const toggleChatPinnedStatusById = async (token: string, id: string) => {
|
||||
return res;
|
||||
};
|
||||
|
||||
export const markChatUnreadById = async (token: string, id: string) => {
|
||||
let error = null;
|
||||
|
||||
const res = await fetch(`${WEBUI_API_BASE_URL}/chats/${id}/unread`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
...(token && { authorization: `Bearer ${token}` })
|
||||
}
|
||||
})
|
||||
.then(async (res) => {
|
||||
if (!res.ok) throw await res.json();
|
||||
return res.json();
|
||||
})
|
||||
.catch((err) => {
|
||||
error = 'detail' in err ? err.detail : err;
|
||||
console.error(err);
|
||||
return null;
|
||||
});
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
export const cloneChatById = async (token: string, id: string, title?: string) => {
|
||||
let error = null;
|
||||
|
||||
|
||||
@@ -235,6 +235,34 @@ export const deleteFolderById = async (token: string, id: string, deleteContents
|
||||
return res;
|
||||
};
|
||||
|
||||
export const markFolderChatsReadById = async (token: string, id: string) => {
|
||||
let error = null;
|
||||
|
||||
const res = await fetch(`${WEBUI_API_BASE_URL}/folders/${id}/read`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
authorization: `Bearer ${token}`
|
||||
}
|
||||
})
|
||||
.then(async (res) => {
|
||||
if (!res.ok) throw await res.json();
|
||||
return res.json();
|
||||
})
|
||||
.catch((err) => {
|
||||
error = err.detail;
|
||||
console.error(err);
|
||||
return null;
|
||||
});
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
export const updateFolderAccessById = async (token: string, id: string, accessGrants: any[]) => {
|
||||
let error = null;
|
||||
|
||||
|
||||
@@ -3470,6 +3470,7 @@
|
||||
|
||||
const initChatHandler = async (history) => {
|
||||
let _chatId = $chatId;
|
||||
const selectedFolderId = $selectedFolder?.id;
|
||||
|
||||
if (!$temporaryChatEnabled) {
|
||||
chat = await createNewChat(
|
||||
@@ -3502,6 +3503,10 @@
|
||||
await refreshChatList(localStorage.token);
|
||||
}
|
||||
|
||||
if (selectedFolderId) {
|
||||
await refreshFolderChatLists(selectedFolderId, chat);
|
||||
}
|
||||
|
||||
selectedFolder.set(null);
|
||||
} else {
|
||||
_chatId = createTemporaryChatId($socket?.id);
|
||||
|
||||
@@ -123,7 +123,15 @@
|
||||
let showSharedFolders = false;
|
||||
|
||||
let folders = {};
|
||||
let folderRegistry: Record<string, { setFolderItems?: () => unknown }> = {};
|
||||
let folderRegistry: Record<
|
||||
string,
|
||||
{
|
||||
setFolderItems?: () => unknown;
|
||||
upsertChat?: (chat: Record<string, unknown>) => unknown;
|
||||
setChatActive?: (chatId: string, active: boolean) => boolean;
|
||||
setChatReadAt?: (chatId: string, lastReadAt: number) => boolean;
|
||||
}
|
||||
> = {};
|
||||
|
||||
let newFolderId = null;
|
||||
|
||||
@@ -403,6 +411,35 @@
|
||||
chatListLoading = false;
|
||||
};
|
||||
|
||||
const applyFolderUnreadCounts = (folderUnreadCounts: Record<string, number>) => {
|
||||
folders = Object.fromEntries(
|
||||
Object.entries(folders).map(([id, folder]) => [
|
||||
id,
|
||||
id in folderUnreadCounts ? { ...folder, unread_count: folderUnreadCounts[id] } : folder
|
||||
])
|
||||
);
|
||||
_folders.update((folderList) =>
|
||||
folderList.map((folder) =>
|
||||
folder.id in folderUnreadCounts
|
||||
? { ...folder, unread_count: folderUnreadCounts[folder.id] }
|
||||
: folder
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
const applyChatReadState = (data) => {
|
||||
if (data?.folder_unread_counts) {
|
||||
applyFolderUnreadCounts(data.folder_unread_counts);
|
||||
}
|
||||
|
||||
if (data?.chat_id && typeof data?.last_read_at === 'number') {
|
||||
setChatReadAt(data.chat_id, data.last_read_at);
|
||||
for (const folder of Object.values(folderRegistry)) {
|
||||
folder?.setChatReadAt?.(data.chat_id, data.last_read_at);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const importChatHandler = async (items, pinned = false, folderId = null) => {
|
||||
if (!canImportChats) {
|
||||
toast.error($i18n.t('Access prohibited'));
|
||||
@@ -656,9 +693,17 @@
|
||||
socketInstance?.on('events', chatActiveEventHandler);
|
||||
socketInstance?.on('connect', refreshChatRows);
|
||||
|
||||
const unregisterFolderRefreshHandler = registerFolderRefreshHandler(() =>
|
||||
Promise.all(Object.values(folderRegistry).map((folder) => folder?.setFolderItems?.()))
|
||||
);
|
||||
const unregisterFolderRefreshHandler = registerFolderRefreshHandler((folderId, chat) => {
|
||||
if (folderId) {
|
||||
if (chat) {
|
||||
return folderRegistry[folderId]?.upsertChat?.(chat);
|
||||
}
|
||||
|
||||
return folderRegistry[folderId]?.setFolderItems?.();
|
||||
}
|
||||
|
||||
return Promise.all(Object.values(folderRegistry).map((folder) => folder?.setFolderItems?.()));
|
||||
});
|
||||
|
||||
await tick();
|
||||
initPinnedMenuSortable();
|
||||
@@ -696,14 +741,23 @@
|
||||
type: string;
|
||||
data: {
|
||||
active?: boolean;
|
||||
folder_id?: string | null;
|
||||
last_read_at?: number;
|
||||
folder_unread_counts?: Record<string, number>;
|
||||
};
|
||||
};
|
||||
}) => {
|
||||
if (event.data?.type === 'chat:active') {
|
||||
const active = event.data.data.active ?? false;
|
||||
const eventData = event.data.data ?? {};
|
||||
const active = eventData.active ?? false;
|
||||
const found = setChatActive(event.chat_id, active);
|
||||
let foundInFolder = false;
|
||||
for (const folder of Object.values(folderRegistry)) {
|
||||
foundInFolder = folder?.setChatActive?.(event.chat_id, active) || foundInFolder;
|
||||
}
|
||||
if (!foundInFolder && active && eventData.folder_id) {
|
||||
await folderRegistry[eventData.folder_id]?.setFolderItems?.();
|
||||
}
|
||||
if (!found && active) {
|
||||
await refreshChatRows();
|
||||
}
|
||||
@@ -711,27 +765,21 @@
|
||||
const eventData = event.data.data ?? {};
|
||||
const folderUnreadCounts = eventData.folder_unread_counts;
|
||||
if (folderUnreadCounts) {
|
||||
folders = Object.fromEntries(
|
||||
Object.entries(folders).map(([id, folder]) => [
|
||||
id,
|
||||
id in folderUnreadCounts ? { ...folder, unread_count: folderUnreadCounts[id] } : folder
|
||||
])
|
||||
);
|
||||
_folders.update((folderList) =>
|
||||
folderList.map((folder) =>
|
||||
folder.id in folderUnreadCounts
|
||||
? { ...folder, unread_count: folderUnreadCounts[folder.id] }
|
||||
: folder
|
||||
)
|
||||
);
|
||||
applyFolderUnreadCounts(folderUnreadCounts);
|
||||
}
|
||||
|
||||
if (typeof eventData.last_read_at === 'number') {
|
||||
setChatReadAt(event.chat_id, eventData.last_read_at);
|
||||
for (const folder of Object.values(folderRegistry)) {
|
||||
folder?.setChatReadAt?.(event.chat_id, eventData.last_read_at);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
refreshChatRows();
|
||||
await refreshChatRows();
|
||||
if (eventData.folder_id) {
|
||||
await folderRegistry[eventData.folder_id]?.setFolderItems?.();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1295,6 +1343,7 @@
|
||||
bind:folderRegistry
|
||||
{folders}
|
||||
{shiftKey}
|
||||
onFolderUnreadCounts={applyFolderUnreadCounts}
|
||||
onDelete={(folderId) => {
|
||||
selectedFolder.set(null);
|
||||
initChatList();
|
||||
@@ -1465,6 +1514,7 @@
|
||||
on:change={async () => {
|
||||
initChatList();
|
||||
}}
|
||||
onReadStateChange={applyChatReadState}
|
||||
on:tag={(e) => {
|
||||
const { type, name } = e.detail;
|
||||
tagEventHandler(type, name, chat.id);
|
||||
@@ -1529,6 +1579,7 @@
|
||||
on:change={async () => {
|
||||
initChatList();
|
||||
}}
|
||||
onReadStateChange={applyChatReadState}
|
||||
on:tag={(e) => {
|
||||
const { type, name } = e.detail;
|
||||
tagEventHandler(type, name, chat.id);
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
getAllTags,
|
||||
getChatById,
|
||||
getChatListByTagName,
|
||||
markChatUnreadById,
|
||||
updateChatById,
|
||||
updateChatFolderIdById
|
||||
} from '$lib/apis/chats';
|
||||
@@ -76,6 +77,7 @@
|
||||
|
||||
export let ownerName: string | null = null;
|
||||
export let ownerUserId: string | null = null;
|
||||
export let onReadStateChange = (data) => {};
|
||||
|
||||
export let onDragEnd = () => {};
|
||||
|
||||
@@ -139,6 +141,18 @@
|
||||
}
|
||||
};
|
||||
|
||||
const markUnreadHandler = async () => {
|
||||
const res = await markChatUnreadById(localStorage.token, id).catch((error) => {
|
||||
toast.error(`${error}`);
|
||||
return null;
|
||||
});
|
||||
if (!res) return;
|
||||
|
||||
viewedAt = null;
|
||||
lastReadAt = res.last_read_at ?? 0;
|
||||
onReadStateChange(res);
|
||||
};
|
||||
|
||||
let showShareChatModal = false;
|
||||
let confirmEdit = false;
|
||||
|
||||
@@ -693,6 +707,7 @@
|
||||
deleteHandler={() => {
|
||||
showDeleteConfirm = true;
|
||||
}}
|
||||
{markUnreadHandler}
|
||||
onClose={() => {
|
||||
dispatch('unselect');
|
||||
}}
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
import PinSlashIcon from './icons/PinSlash.svelte';
|
||||
import ShareIcon from './icons/Share.svelte';
|
||||
import TrashIcon from './icons/Trash.svelte';
|
||||
import ChatCheckIcon from '$lib/components/icons/ChatCheck.svelte';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
@@ -39,6 +40,7 @@
|
||||
export let renameHandler: Function;
|
||||
export let deleteHandler: Function;
|
||||
export let onClose: Function;
|
||||
export let markUnreadHandler: Function = () => {};
|
||||
|
||||
export let chatId = '';
|
||||
|
||||
@@ -369,6 +371,18 @@
|
||||
<div class="flex items-center">{$i18n.t('Rename')}</div>
|
||||
</button>
|
||||
|
||||
<button
|
||||
draggable="false"
|
||||
class="flex h-[1.6875rem] gap-2 items-center rounded-xl px-2 text-[13px] cursor-pointer hover:bg-gray-50/40 dark:hover:bg-gray-800/40 w-full"
|
||||
on:click={() => {
|
||||
show = false;
|
||||
markUnreadHandler();
|
||||
}}
|
||||
>
|
||||
<ChatCheckIcon className="size-3.5" strokeWidth="1.5" />
|
||||
<div class="flex items-center">{$i18n.t('Mark as unread')}</div>
|
||||
</button>
|
||||
|
||||
<hr class="border-gray-50/30 dark:border-gray-800/30 mx-1 my-0.5" />
|
||||
|
||||
<button
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
export let shiftKey = false;
|
||||
|
||||
export let onDelete = (folderId) => {};
|
||||
export let onFolderUnreadCounts = (counts) => {};
|
||||
|
||||
let ownedList = [];
|
||||
let sharedList = [];
|
||||
@@ -52,6 +53,7 @@
|
||||
{shiftKey}
|
||||
{onDelete}
|
||||
{onItemMove}
|
||||
{onFolderUnreadCounts}
|
||||
on:import={(e) => {
|
||||
dispatch('import', e.detail);
|
||||
}}
|
||||
@@ -77,6 +79,7 @@
|
||||
{shiftKey}
|
||||
{onDelete}
|
||||
{onItemMove}
|
||||
{onFolderUnreadCounts}
|
||||
on:import={(e) => {
|
||||
dispatch('import', e.detail);
|
||||
}}
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
import TrashIcon from '../icons/Trash.svelte';
|
||||
import Tooltip from '$lib/components/common/Tooltip.svelte';
|
||||
import Download from '../icons/Download.svelte';
|
||||
import CheckIcon from '$lib/components/icons/Check.svelte';
|
||||
|
||||
export let align: 'start' | 'end' = 'start';
|
||||
export let onEdit = () => {};
|
||||
@@ -19,6 +20,7 @@
|
||||
export let onShare = () => {};
|
||||
export let onDelete = () => {};
|
||||
export let onCreateSubFolder = () => {};
|
||||
export let onMarkAllRead = () => {};
|
||||
|
||||
let show = false;
|
||||
</script>
|
||||
@@ -57,6 +59,19 @@
|
||||
|
||||
<hr class="border-gray-50/30 dark:border-gray-800/30 mx-1 my-0.5" />
|
||||
|
||||
<button
|
||||
class="flex h-[1.6875rem] w-full items-center gap-2 rounded-xl px-2 text-[13px] select-none cursor-pointer hover:bg-gray-50/40 dark:hover:bg-gray-800/40"
|
||||
on:click={() => {
|
||||
show = false;
|
||||
onMarkAllRead();
|
||||
}}
|
||||
>
|
||||
<CheckIcon className="size-3.5" />
|
||||
<div class="flex items-center">{$i18n.t('Mark all as read')}</div>
|
||||
</button>
|
||||
|
||||
<hr class="border-gray-50/30 dark:border-gray-800/30 mx-1 my-0.5" />
|
||||
|
||||
<button
|
||||
class="flex h-[1.6875rem] w-full items-center gap-2 rounded-xl px-2 text-[13px] select-none cursor-pointer hover:bg-gray-50/40 dark:hover:bg-gray-800/40"
|
||||
on:click={() => {
|
||||
|
||||
@@ -20,7 +20,8 @@
|
||||
updateFolderParentIdById,
|
||||
getFolderById,
|
||||
createNewFolder,
|
||||
getSharedFolderChats
|
||||
getSharedFolderChats,
|
||||
markFolderChatsReadById
|
||||
} from '$lib/apis/folders';
|
||||
import {
|
||||
getChatById,
|
||||
@@ -60,6 +61,7 @@
|
||||
|
||||
export let onDelete = (e) => {};
|
||||
export let onItemMove = (e) => {};
|
||||
export let onFolderUnreadCounts = (counts) => {};
|
||||
|
||||
let folderElement;
|
||||
|
||||
@@ -83,6 +85,79 @@
|
||||
compactDisplay: 'short'
|
||||
}).format(count);
|
||||
|
||||
const isUnreadChat = (chat) =>
|
||||
!(chat.active ?? false) &&
|
||||
(chat.last_read_at == null ||
|
||||
(typeof chat.updated_at === 'number' &&
|
||||
typeof chat.last_read_at === 'number' &&
|
||||
chat.updated_at > chat.last_read_at));
|
||||
|
||||
const sortFolderChats = (items) =>
|
||||
[...items].sort(
|
||||
(a, b) =>
|
||||
Number(isUnreadChat(b)) - Number(isUnreadChat(a)) ||
|
||||
Number(b.updated_at ?? 0) - Number(a.updated_at ?? 0)
|
||||
);
|
||||
|
||||
const mergeFolderChats = (items, nextItems) => {
|
||||
const merged = [...items];
|
||||
const indexById = new Map(merged.map((chat, index) => [chat.id, index]));
|
||||
|
||||
for (const chat of nextItems) {
|
||||
if (!chat?.id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const index = indexById.get(chat.id);
|
||||
if (index === undefined) {
|
||||
indexById.set(chat.id, merged.length);
|
||||
merged.push(chat);
|
||||
} else {
|
||||
merged[index] = { ...merged[index], ...chat };
|
||||
}
|
||||
}
|
||||
|
||||
return sortFolderChats(merged);
|
||||
};
|
||||
|
||||
const applyReadState = (data) => {
|
||||
if (data?.folder_unread_counts) {
|
||||
onFolderUnreadCounts(data.folder_unread_counts);
|
||||
}
|
||||
|
||||
if (typeof data?.last_read_at === 'number') {
|
||||
folderRegistry[folderId]?.setChatReadAt?.(data.chat_id, data.last_read_at);
|
||||
}
|
||||
};
|
||||
|
||||
const markAllReadHandler = async () => {
|
||||
const res = await markFolderChatsReadById(localStorage.token, folderId).catch((error) => {
|
||||
toast.error(`${error}`);
|
||||
return null;
|
||||
});
|
||||
if (!res) return;
|
||||
|
||||
if (res.folder_unread_counts) {
|
||||
onFolderUnreadCounts(res.folder_unread_counts);
|
||||
}
|
||||
|
||||
for (const readFolderId of res.folder_ids ?? []) {
|
||||
if (readFolderId !== folderId) {
|
||||
folderRegistry[readFolderId]?.setFolderItems?.();
|
||||
}
|
||||
}
|
||||
|
||||
if (chats) {
|
||||
chats = sortFolderChats(
|
||||
chats.map((chat) =>
|
||||
!chat.user_id || chat.user_id === $user?.id
|
||||
? { ...chat, last_read_at: chat.updated_at }
|
||||
: chat
|
||||
)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const onDragOver = (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
@@ -275,8 +350,48 @@
|
||||
onMount(async () => {
|
||||
open = folders[folderId].is_expanded;
|
||||
folderRegistry[folderId] = {
|
||||
setFolderItems: () => {
|
||||
setFolderItems();
|
||||
setFolderItems,
|
||||
upsertChat: (chat) => {
|
||||
if (chat.folder_id && chat.folder_id !== folderId) {
|
||||
return;
|
||||
}
|
||||
|
||||
pendingUpsertChats = mergeFolderChats(pendingUpsertChats, [chat]);
|
||||
if (open || chats) {
|
||||
chats = mergeFolderChats(chats ?? [], [chat]);
|
||||
}
|
||||
},
|
||||
setChatActive: (chatId, active) => {
|
||||
if (chats) {
|
||||
let found = false;
|
||||
chats = sortFolderChats(
|
||||
chats.map((chat) => {
|
||||
if (chat.id !== chatId) {
|
||||
return chat;
|
||||
}
|
||||
found = true;
|
||||
return { ...chat, active };
|
||||
})
|
||||
);
|
||||
return found;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
setChatReadAt: (chatId, lastReadAt) => {
|
||||
if (chats) {
|
||||
let found = false;
|
||||
chats = sortFolderChats(
|
||||
chats.map((chat) => {
|
||||
if (chat.id !== chatId) {
|
||||
return chat;
|
||||
}
|
||||
found = true;
|
||||
return { ...chat, last_read_at: lastReadAt };
|
||||
})
|
||||
);
|
||||
return found;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
if (folderElement) {
|
||||
@@ -396,10 +511,19 @@
|
||||
let chatsPage = 1;
|
||||
let hasMoreChats = false;
|
||||
let chatsLoading = false;
|
||||
let queuedReload = false;
|
||||
let pendingUpsertChats = [];
|
||||
|
||||
export const setFolderItems = async (append = false) => {
|
||||
await tick();
|
||||
if (open && !chatsLoading) {
|
||||
if (open && chatsLoading) {
|
||||
if (!append) {
|
||||
queuedReload = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (open) {
|
||||
// Always use getSharedFolderChats so owners also see chats
|
||||
// created by users who have write access to this folder.
|
||||
const nextPage = append ? chatsPage + 1 : 1;
|
||||
@@ -409,7 +533,11 @@
|
||||
page: nextPage
|
||||
});
|
||||
const nextChats = res?.chats ?? [];
|
||||
chats = append ? [...(chats ?? []), ...nextChats] : nextChats;
|
||||
const merged = append ? mergeFolderChats(chats ?? [], nextChats) : nextChats;
|
||||
chats = mergeFolderChats(merged, pendingUpsertChats);
|
||||
pendingUpsertChats = pendingUpsertChats.filter(
|
||||
(pendingChat) => !nextChats.some((chat) => chat.id === pendingChat.id)
|
||||
);
|
||||
chatsPage = nextPage;
|
||||
hasMoreChats = res?.has_more ?? nextChats.length === SIDEBAR_CHATS_PAGE_SIZE;
|
||||
} catch (error) {
|
||||
@@ -420,16 +548,26 @@
|
||||
return [];
|
||||
}
|
||||
);
|
||||
chats = append ? [...(chats ?? []), ...(fallback ?? [])] : (fallback ?? []);
|
||||
const fallbackChats = fallback ?? [];
|
||||
const merged = append ? mergeFolderChats(chats ?? [], fallbackChats) : fallbackChats;
|
||||
chats = mergeFolderChats(merged, pendingUpsertChats);
|
||||
pendingUpsertChats = pendingUpsertChats.filter(
|
||||
(pendingChat) => !fallbackChats.some((chat) => chat.id === pendingChat.id)
|
||||
);
|
||||
chatsPage = nextPage;
|
||||
hasMoreChats = (fallback?.length ?? 0) === SIDEBAR_CHATS_PAGE_SIZE;
|
||||
} finally {
|
||||
chatsLoading = false;
|
||||
if (queuedReload) {
|
||||
queuedReload = false;
|
||||
setFolderItems();
|
||||
}
|
||||
}
|
||||
} else if (!open) {
|
||||
chats = null;
|
||||
chatsPage = 1;
|
||||
hasMoreChats = false;
|
||||
queuedReload = false;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -710,6 +848,7 @@
|
||||
createSubFolderParentId = folderId;
|
||||
showCreateSubFolderModal = true;
|
||||
}}
|
||||
onMarkAllRead={markAllReadHandler}
|
||||
>
|
||||
<div
|
||||
class="flex size-5 items-center justify-center self-center dark:hover:text-white transition m-0 touch-auto"
|
||||
@@ -746,6 +885,7 @@
|
||||
parentDragged={dragged}
|
||||
{onItemMove}
|
||||
{onDelete}
|
||||
{onFolderUnreadCounts}
|
||||
on:import={(e) => {
|
||||
dispatch('import', e.detail);
|
||||
}}
|
||||
@@ -771,6 +911,7 @@
|
||||
ownerUserId={folders[folderId]?.shared && chat.owner_name ? chat.user_id : null}
|
||||
readonly={chat.user_id !== $user?.id}
|
||||
{shiftKey}
|
||||
onReadStateChange={applyReadState}
|
||||
on:change={(e) => {
|
||||
dispatch('change', e.detail);
|
||||
}}
|
||||
|
||||
@@ -65,7 +65,7 @@ export const refreshChatList = async (
|
||||
// through a registry of per-folder callbacks that only the sidebar can reach.
|
||||
// Handlers registered here let other components (e.g. the open chat's menu)
|
||||
// request that refresh without a reference to the sidebar.
|
||||
type FolderRefreshHandler = () => unknown;
|
||||
type FolderRefreshHandler = (folderId?: string | null, chat?: ChatListItem | null) => unknown;
|
||||
const folderRefreshHandlers = new Set<FolderRefreshHandler>();
|
||||
|
||||
export const registerFolderRefreshHandler = (handler: FolderRefreshHandler) => {
|
||||
@@ -75,8 +75,8 @@ export const registerFolderRefreshHandler = (handler: FolderRefreshHandler) => {
|
||||
};
|
||||
};
|
||||
|
||||
export const refreshFolderChatLists = async () => {
|
||||
await Promise.all([...folderRefreshHandlers].map((handler) => handler()));
|
||||
export const refreshFolderChatLists = async (folderId?: string | null, chat?: ChatListItem | null) => {
|
||||
await Promise.all([...folderRefreshHandlers].map((handler) => handler(folderId, chat)));
|
||||
};
|
||||
|
||||
export const loadNextChatListPage = async (token: string = ''): Promise<ChatListResult> => {
|
||||
|
||||
Reference in New Issue
Block a user