diff --git a/client/src/components/FileBrowser.svelte b/client/src/components/FileBrowser.svelte index de698a4..c19bef0 100644 --- a/client/src/components/FileBrowser.svelte +++ b/client/src/components/FileBrowser.svelte @@ -16,6 +16,14 @@ } }); + // Reload hidden files when profile changes + $effect(() => { + void $profile; + if (selectedRoot) { + loadFiles(); + } + }); + async function loadFiles() { $files = await getFiles(selectedRoot); const hidden = await getHidden($profile); diff --git a/client/src/lib/ws.ts b/client/src/lib/ws.ts index a143650..5d99ba7 100644 --- a/client/src/lib/ws.ts +++ b/client/src/lib/ws.ts @@ -2,30 +2,40 @@ import { getServer } from "./api"; import { exportStatus, exportCompleted } from "./stores"; let socket: WebSocket | null = null; +let reconnectDelay = 2000; export function connectExportWs() { const wsUrl = getServer().replace(/^http/, "ws") + "/ws/export"; socket = new WebSocket(wsUrl); + socket.onopen = () => { + reconnectDelay = 2000; // reset backoff on successful connect + }; + socket.onmessage = (event) => { - const msg = JSON.parse(event.data); - switch (msg.type) { - case "clip_done": - exportCompleted.update(n => n + 1); - break; - case "all_done": - exportStatus.set("done"); - break; - case "error": - exportStatus.set("error"); - console.error("Export error:", msg.msg); - break; + try { + const msg = JSON.parse(event.data); + switch (msg.type) { + case "clip_done": + exportCompleted.update(n => n + 1); + break; + case "all_done": + exportStatus.set("done"); + break; + case "error": + exportStatus.set("error"); + console.error("Export error:", msg.msg); + break; + } + } catch (e) { + console.error("Failed to parse WebSocket message:", e); } }; socket.onclose = () => { - // Reconnect after 2s - setTimeout(connectExportWs, 2000); + // Reconnect with exponential backoff, max 30s + setTimeout(connectExportWs, reconnectDelay); + reconnectDelay = Math.min(reconnectDelay * 2, 30000); }; } diff --git a/client/src/routes/+page.svelte b/client/src/routes/+page.svelte index f10280b..53ab6c5 100644 --- a/client/src/routes/+page.svelte +++ b/client/src/routes/+page.svelte @@ -6,7 +6,7 @@ import ProfileBar from "../components/ProfileBar.svelte"; import { mpvStart, mpvLoad, mpvSeek, mpvPause, mpvResume, mpvSetLoop, mpvClearLoop, mpvTimePos, mpvDuration } from "$lib/mpv"; import { streamUrl, audioUrl, deleteExport, getMarkers } from "$lib/api"; - import { connectExportWs } from "$lib/ws"; + import { connectExportWs, disconnectExportWs } from "$lib/ws"; import { loadSettings, saveSettings } from "$lib/settings"; import { currentFile, cursor, duration, playPos, playing, quality, @@ -44,6 +44,7 @@ onDestroy(() => { clearInterval(pollInterval); + disconnectExportWs(); }); // Load file into mpv when currentFile OR quality changes