diff --git a/src/lib/components/chat/Chat.svelte b/src/lib/components/chat/Chat.svelte index a7b7f7a08..a44756feb 100644 --- a/src/lib/components/chat/Chat.svelte +++ b/src/lib/components/chat/Chat.svelte @@ -110,10 +110,10 @@ let loading = true; const eventTarget = new EventTarget(); - let controlPane; - let controlPaneComponent; + let controlPane: Pane | undefined; + let controlPaneComponent: ChatControls | undefined; - let messageInput; + let messageInput: MessageInput | undefined; let autoScroll = true; let processing = ''; @@ -130,8 +130,6 @@ let eventConfirmationInputType = ''; let eventCallback = null; - let chatIdUnsubscriber: Unsubscriber | undefined; - let selectedModels = ['']; let atSelectedModel: Model | undefined; let selectedModelIds = []; @@ -657,24 +655,23 @@ savedModelIds(); } - let pageSubscribe = null; - let showControlsSubscribe = null; - let selectedFolderSubscribe = null; - const stopAudio = () => { try { speechSynthesis.cancel(); - $audioQueue.stop(); + $audioQueue?.stop(); } catch {} }; - onMount(async () => { + onMount(() => { loading = true; console.log('mounted'); window.addEventListener('message', onMessageHandler); $socket?.on('events', chatEventHandler); - audioQueue.set(new AudioQueue(document.getElementById('audioElement'))); + $audioQueue?.destroy(); + + const audioQueueInstance = new AudioQueue(document.getElementById('audioElement')); + audioQueue.set(audioQueueInstance); // Reset direct terminal enabled states — selectedTerminalId starts null on every page load if ($settings?.terminalServers?.some((s) => s.enabled)) { @@ -684,7 +681,7 @@ }); } - pageSubscribe = page.subscribe(async (p) => { + const pageSubscribe = page.subscribe(async (p) => { if (p.url.pathname === '/') { await tick(); initNewChat(); @@ -693,46 +690,12 @@ stopAudio(); }); - const storageChatInput = sessionStorage.getItem( - `chat-input${chatIdProp ? `-${chatIdProp}` : ''}` - ); - - if (!chatIdProp) { - loading = false; + const showControlsSubscribe = showControls.subscribe(async (value) => { await tick(); - } - - if (storageChatInput) { - prompt = ''; - messageInput?.setText(''); - - files = []; - selectedToolIds = []; - selectedFilterIds = []; - webSearchEnabled = false; - imageGenerationEnabled = false; - codeInterpreterEnabled = false; - - try { - const input = JSON.parse(storageChatInput); - - if (!$temporaryChatEnabled) { - messageInput?.setText(input.prompt); - files = input.files; - selectedToolIds = input.selectedToolIds; - selectedFilterIds = input.selectedFilterIds; - webSearchEnabled = input.webSearchEnabled; - imageGenerationEnabled = input.imageGenerationEnabled; - codeInterpreterEnabled = input.codeInterpreterEnabled; - } - } catch (e) {} - } - - showControlsSubscribe = showControls.subscribe(async (value) => { if (controlPane && !$mobile) { try { if (value) { - controlPaneComponent.openPane(); + controlPaneComponent?.openPane(); } else { controlPane.collapse(); } @@ -748,7 +711,8 @@ } }); - selectedFolderSubscribe = selectedFolder.subscribe(async (folder) => { + const selectedFolderSubscribe = selectedFolder.subscribe(async (folder) => { + await tick(); if ( folder?.data?.model_ids && JSON.stringify(selectedModels) !== JSON.stringify(folder.data.model_ids) @@ -759,22 +723,60 @@ } }); - const chatInput = document.getElementById('chat-input'); - chatInput?.focus(); - }); + const storageChatInput = sessionStorage.getItem( + `chat-input${chatIdProp ? `-${chatIdProp}` : ''}` + ); - onDestroy(() => { - try { - pageSubscribe(); - showControlsSubscribe(); - selectedFolderSubscribe(); - chatIdUnsubscriber?.(); - window.removeEventListener('message', onMessageHandler); - $socket?.off('events', chatEventHandler); - $audioQueue?.destroy(); - } catch (e) { - console.error(e); - } + const init = async () => { + if (!chatIdProp) { + loading = false; + await tick(); + } + + if (storageChatInput) { + prompt = ''; + messageInput?.setText(''); + + files = []; + selectedToolIds = []; + selectedFilterIds = []; + webSearchEnabled = false; + imageGenerationEnabled = false; + codeInterpreterEnabled = false; + + try { + const input = JSON.parse(storageChatInput); + + if (!$temporaryChatEnabled) { + messageInput?.setText(input.prompt); + files = input.files; + selectedToolIds = input.selectedToolIds; + selectedFilterIds = input.selectedFilterIds; + webSearchEnabled = input.webSearchEnabled; + imageGenerationEnabled = input.imageGenerationEnabled; + codeInterpreterEnabled = input.codeInterpreterEnabled; + } + } catch (e) {} + } + + const chatInput = document.getElementById('chat-input'); + chatInput?.focus(); + }; + init(); + + return () => { + try { + pageSubscribe(); + showControlsSubscribe(); + selectedFolderSubscribe(); + window.removeEventListener('message', onMessageHandler); + $socket?.off('events', chatEventHandler); + audioQueueInstance?.destroy(); + audioQueue.set(null); + } catch (e) { + console.error(e); + } + }; }); // File upload functions diff --git a/src/lib/stores/index.ts b/src/lib/stores/index.ts index 2877e4adc..bdc8fe31c 100644 --- a/src/lib/stores/index.ts +++ b/src/lib/stores/index.ts @@ -3,6 +3,7 @@ import { type Writable, writable } from 'svelte/store'; import type { ModelConfig } from '$lib/apis'; import type { Banner } from '$lib/types'; import type { Socket } from 'socket.io-client'; +import type { AudioQueue } from '$lib/utils/audio'; import emojiShortCodes from '$lib/emoji-shortcodes.json'; @@ -75,7 +76,7 @@ export const banners: Writable = writable([]); export const settings: Writable = writable({}); -export const audioQueue = writable(null); +export const audioQueue = writable(null); export const sidebarWidth = writable(260);