Disable Skip button while a sort is in progress
Summary
A user reported data loss after hitting Skip on the random page while a sort was mid-move: the source folder was gone but the destination was incomplete.
The Skip button on src/routes/random/+page.svelte was only disabled while $isLoading (random-album-fetch state) was true — it had no visibility into whether a sort was in flight. SortForm.handleSort()'s isSortLoading was local component state, so when Skip loaded a new album the previous SortForm unmounted and any in-flight sort became invisible to the UI (the server-side executeSort keeps running regardless — Node doesn't abort on client disconnect).
This change lifts sort-in-progress state into a shared Svelte store so the Skip button can gate on it.
Changes
-
src/lib/stores/albums.ts— addisSortingwritable store next toisLoading. -
src/lib/components/SortForm.svelte—handleSort()setsisSortingtrue on entry and false infinally, around thefetch('/api/preview?action=execute')call that runsexecuteSort(cp → verify → rm) insorter.ts. -
src/routes/random/+page.svelte— Skip button is nowdisabled={$isLoading || $isSorting}and shows "Sorting..." while a sort is running.
Out of scope (follow-ups)
- The copy→rm sequence in
src/lib/server/services/sorter.ts:214-234is still non-atomic. The file-count check at 217-230 is the only guard beforerm(originalPath)at 234; ifcpsilently under-copies over NFS andgetDirectoryStatsdoesn't notice, data loss is still possible even without Skip. - If a sort fails after the user has already moved to a new album, the error toast is lost with the unmounted SortForm. A global toast or a persistent sort-activity indicator would fix that.
Test plan
-
pnpm run buildpasses. -
Open /random, click Sort on a small album → Skip is disabled and reads "Sorting..." for the duration of the request, then re-enables. -
With an artificially slowed executeSort(temporaryawait delay(5000)beforefs.promises.cp), Skip remains disabled for the full duration. -
Skip still behaves normally when no sort is active.