fix: client bug fixes from review

- FileBrowser: reload hidden files when profile changes
- WebSocket: wrap JSON.parse in try-catch
- WebSocket: exponential backoff on reconnect (2s -> 30s max)
- WebSocket: clean up connection on destroy

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-16 20:09:21 +02:00
parent 39f873bec2
commit 9776b83ac5
3 changed files with 34 additions and 15 deletions
+8
View File
@@ -16,6 +16,14 @@
} }
}); });
// Reload hidden files when profile changes
$effect(() => {
void $profile;
if (selectedRoot) {
loadFiles();
}
});
async function loadFiles() { async function loadFiles() {
$files = await getFiles(selectedRoot); $files = await getFiles(selectedRoot);
const hidden = await getHidden($profile); const hidden = await getHidden($profile);
+12 -2
View File
@@ -2,12 +2,18 @@ import { getServer } from "./api";
import { exportStatus, exportCompleted } from "./stores"; import { exportStatus, exportCompleted } from "./stores";
let socket: WebSocket | null = null; let socket: WebSocket | null = null;
let reconnectDelay = 2000;
export function connectExportWs() { export function connectExportWs() {
const wsUrl = getServer().replace(/^http/, "ws") + "/ws/export"; const wsUrl = getServer().replace(/^http/, "ws") + "/ws/export";
socket = new WebSocket(wsUrl); socket = new WebSocket(wsUrl);
socket.onopen = () => {
reconnectDelay = 2000; // reset backoff on successful connect
};
socket.onmessage = (event) => { socket.onmessage = (event) => {
try {
const msg = JSON.parse(event.data); const msg = JSON.parse(event.data);
switch (msg.type) { switch (msg.type) {
case "clip_done": case "clip_done":
@@ -21,11 +27,15 @@ export function connectExportWs() {
console.error("Export error:", msg.msg); console.error("Export error:", msg.msg);
break; break;
} }
} catch (e) {
console.error("Failed to parse WebSocket message:", e);
}
}; };
socket.onclose = () => { socket.onclose = () => {
// Reconnect after 2s // Reconnect with exponential backoff, max 30s
setTimeout(connectExportWs, 2000); setTimeout(connectExportWs, reconnectDelay);
reconnectDelay = Math.min(reconnectDelay * 2, 30000);
}; };
} }
+2 -1
View File
@@ -6,7 +6,7 @@
import ProfileBar from "../components/ProfileBar.svelte"; import ProfileBar from "../components/ProfileBar.svelte";
import { mpvStart, mpvLoad, mpvSeek, mpvPause, mpvResume, mpvSetLoop, mpvClearLoop, mpvTimePos, mpvDuration } from "$lib/mpv"; import { mpvStart, mpvLoad, mpvSeek, mpvPause, mpvResume, mpvSetLoop, mpvClearLoop, mpvTimePos, mpvDuration } from "$lib/mpv";
import { streamUrl, audioUrl, deleteExport, getMarkers } from "$lib/api"; 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 { loadSettings, saveSettings } from "$lib/settings";
import { import {
currentFile, cursor, duration, playPos, playing, quality, currentFile, cursor, duration, playPos, playing, quality,
@@ -44,6 +44,7 @@
onDestroy(() => { onDestroy(() => {
clearInterval(pollInterval); clearInterval(pollInterval);
disconnectExportWs();
}); });
// Load file into mpv when currentFile OR quality changes // Load file into mpv when currentFile OR quality changes