diff --git a/frontend/src/hooks/useScanActivity.ts b/frontend/src/hooks/useScanActivity.ts index 159d00e..f74583e 100644 --- a/frontend/src/hooks/useScanActivity.ts +++ b/frontend/src/hooks/useScanActivity.ts @@ -20,11 +20,21 @@ function pendingTasks(ws: WorkerStatus | undefined): number { /** Tasks actively being executed by workers right now. Distinct from * pendingTasks so we can drop the spinner the moment no real work is - * in flight, even if reserved tasks linger. */ + * in flight, even if reserved tasks linger. + * + * Excludes the periodic `watch_folders` heartbeat — the watcher + * worker reports it as a perpetually-active task, which would pin + * the spinner on indefinitely with no real work in flight. */ +const IDLE_TASK_NAMES = new Set(['watch_folders']) function activeTasks(ws: WorkerStatus | undefined): number { if (!ws) return 0 return ( - ws.workers?.reduce((sum, w) => sum + (w.active ?? 0), 0) ?? 0 + ws.workers?.reduce((sum, w) => { + const real = (w.active_tasks ?? []).filter( + (t) => !IDLE_TASK_NAMES.has(t.name), + ).length + return sum + real + }, 0) ?? 0 ) }