refac
This commit is contained in:
@@ -26,7 +26,8 @@
|
||||
models,
|
||||
selectedFolder,
|
||||
WEBUI_NAME,
|
||||
sidebarWidth
|
||||
sidebarWidth,
|
||||
activeChatIds
|
||||
} from '$lib/stores';
|
||||
import { onMount, getContext, tick, onDestroy } from 'svelte';
|
||||
|
||||
@@ -42,6 +43,7 @@
|
||||
importChats
|
||||
} from '$lib/apis/chats';
|
||||
import { createNewFolder, getFolders, updateFolderParentIdById } from '$lib/apis/folders';
|
||||
import { checkActiveChats } from '$lib/apis/tasks';
|
||||
import { WEBUI_API_BASE_URL, WEBUI_BASE_URL } from '$lib/constants';
|
||||
|
||||
import ArchivedChatsModal from './ArchivedChatsModal.svelte';
|
||||
@@ -469,6 +471,17 @@
|
||||
await initChannels();
|
||||
}
|
||||
await initChatList();
|
||||
|
||||
// Check which chats have active tasks
|
||||
const allChatIds = [...$chats.map((c) => c.id), ...$pinnedChats.map((c) => c.id)];
|
||||
if (allChatIds.length > 0) {
|
||||
try {
|
||||
const res = await checkActiveChats(localStorage.token, allChatIds);
|
||||
activeChatIds.set(new Set(res.active_chat_ids || []));
|
||||
} catch (e) {
|
||||
console.debug('Failed to check active chats:', e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}),
|
||||
settings.subscribe((value) => {
|
||||
@@ -493,8 +506,32 @@
|
||||
dropZone?.addEventListener('dragover', onDragOver);
|
||||
dropZone?.addEventListener('drop', onDrop);
|
||||
dropZone?.addEventListener('dragleave', onDragLeave);
|
||||
|
||||
// Listen for real-time chat:active events via the events channel
|
||||
$socket?.off('events', chatActiveEventHandler);
|
||||
$socket?.on('events', chatActiveEventHandler);
|
||||
});
|
||||
|
||||
// Handler for chat:active events (defined outside onMount for proper cleanup)
|
||||
const chatActiveEventHandler = (event: {
|
||||
chat_id: string;
|
||||
message_id: string;
|
||||
data: { type: string; data: any };
|
||||
}) => {
|
||||
if (event.data?.type === 'chat:active') {
|
||||
const { active } = event.data.data;
|
||||
activeChatIds.update((ids) => {
|
||||
const newSet = new Set(ids);
|
||||
if (active) {
|
||||
newSet.add(event.chat_id);
|
||||
} else {
|
||||
newSet.delete(event.chat_id);
|
||||
}
|
||||
return newSet;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
onDestroy(() => {
|
||||
if (unsubscribers && unsubscribers.length > 0) {
|
||||
unsubscribers.forEach((unsubscriber) => {
|
||||
@@ -518,6 +555,9 @@
|
||||
dropZone?.removeEventListener('dragover', onDragOver);
|
||||
dropZone?.removeEventListener('drop', onDrop);
|
||||
dropZone?.removeEventListener('dragleave', onDragLeave);
|
||||
|
||||
// Clean up socket listener
|
||||
$socket?.off('events', chatActiveEventHandler);
|
||||
});
|
||||
|
||||
const newChatHandler = async () => {
|
||||
@@ -1244,7 +1284,7 @@
|
||||
className=""
|
||||
id={chat.id}
|
||||
title={chat.title}
|
||||
updatedAt={chat.updated_at}
|
||||
createdAt={chat.created_at}
|
||||
{shiftKey}
|
||||
selected={selectedChatId === chat.id}
|
||||
on:select={() => {
|
||||
@@ -1305,7 +1345,7 @@
|
||||
className=""
|
||||
id={chat.id}
|
||||
title={chat.title}
|
||||
updatedAt={chat.updated_at}
|
||||
createdAt={chat.created_at}
|
||||
{shiftKey}
|
||||
selected={selectedChatId === chat.id}
|
||||
on:select={() => {
|
||||
|
||||
@@ -27,7 +27,8 @@
|
||||
showSidebar,
|
||||
currentChatPage,
|
||||
tags,
|
||||
selectedFolder
|
||||
selectedFolder,
|
||||
activeChatIds
|
||||
} from '$lib/stores';
|
||||
|
||||
import ChatMenu from './ChatMenu.svelte';
|
||||
@@ -41,13 +42,14 @@
|
||||
import XMark from '$lib/components/icons/XMark.svelte';
|
||||
import Document from '$lib/components/icons/Document.svelte';
|
||||
import Sparkles from '$lib/components/icons/Sparkles.svelte';
|
||||
import Spinner from '$lib/components/common/Spinner.svelte';
|
||||
import { generateTitle } from '$lib/apis';
|
||||
|
||||
export let className = '';
|
||||
|
||||
export let id;
|
||||
export let title;
|
||||
export let updatedAt: number | null = null;
|
||||
export let createdAt: number | null = null;
|
||||
|
||||
export let selected = false;
|
||||
export let shiftKey = false;
|
||||
@@ -73,6 +75,7 @@
|
||||
return '1m';
|
||||
}
|
||||
|
||||
|
||||
let chat = null;
|
||||
|
||||
let mouseOver = false;
|
||||
@@ -443,6 +446,13 @@
|
||||
on:focus={(e) => {}}
|
||||
draggable="false"
|
||||
>
|
||||
<!-- Loading spinner for active chat (left side) -->
|
||||
{#if $activeChatIds.has(id)}
|
||||
<div class="shrink-0 self-center pr-2">
|
||||
<Spinner className="size-3" />
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="flex self-center flex-1 w-full min-w-0">
|
||||
<div dir="auto" class="text-left self-center overflow-hidden w-full h-[20px] truncate">
|
||||
{title}
|
||||
@@ -450,9 +460,9 @@
|
||||
</div>
|
||||
|
||||
<!-- Time ago indicator -->
|
||||
{#if updatedAt && !mouseOver}
|
||||
{#if createdAt && !mouseOver}
|
||||
<div class="shrink-0 self-center text-[10px] text-gray-400 dark:text-gray-500 pl-2">
|
||||
{formatTimeAgo(updatedAt)}
|
||||
{formatTimeAgo(createdAt)}
|
||||
</div>
|
||||
{/if}
|
||||
</a>
|
||||
|
||||
@@ -643,7 +643,7 @@
|
||||
<ChatItem
|
||||
id={chat.id}
|
||||
title={chat.title}
|
||||
updatedAt={chat.updated_at}
|
||||
createdAt={chat.created_at}
|
||||
{shiftKey}
|
||||
on:change={(e) => {
|
||||
dispatch('change', e.detail);
|
||||
|
||||
Reference in New Issue
Block a user