tubearr/Auto Run Docs/Initiation/2026-03-31-WebSocket-Progress-And-Polish/WEBSOCKET-PROGRESS-01.md
John Lightner c8923f0142 MAESTRO: Add activity, channels, and library query invalidation on WebSocket download events
When a download completes or fails, the UI now immediately refreshes the
Activity page, channel content counts, and Library page in addition to
the existing content and queue invalidations.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-01 00:44:18 -05:00

5.2 KiB

Phase 01: Wire Up WebSocket Download Progress End-to-End

The backend event bus, WebSocket route, progress parser, and frontend context/hook/component all exist but are not connected in the UI. This phase wires everything together so users see real-time download progress in the Queue page and Channel Detail page. By the end, downloading items will show a live progress bar with percentage, speed, and ETA — completing the WIP feature from commit 0541a5f.

Tasks

  • Wrap the app in DownloadProgressProvider:

    • Read src/frontend/src/App.tsx and src/frontend/src/contexts/DownloadProgressContext.tsx to understand current structure
    • In App.tsx, import DownloadProgressProvider from ../contexts/DownloadProgressContext
    • Wrap the <AuthenticatedLayout /> route (or the <Routes> in App()) with <DownloadProgressProvider> so all pages can access download progress
    • Ensure the provider is inside the existing QueryClientProvider (check main.tsx for provider ordering)
    • Note: Already wired in main.tsx (lines 25-29) from commit 0541a5f. Provider wraps entire app inside QueryClientProvider. No changes needed.
  • Integrate DownloadProgressBar into the Queue page for actively downloading items:

    • Read src/frontend/src/pages/Queue.tsx and src/frontend/src/components/DownloadProgressBar.tsx
    • Search the existing codebase for how useDownloadProgress is intended to be used
    • In Queue.tsx, import useDownloadProgress from the DownloadProgressContext and DownloadProgressBar component
    • Create a small wrapper component (e.g., QueueItemProgress) that calls useDownloadProgress(contentItemId) and renders <DownloadProgressBar> when progress exists, or falls back to the existing <StatusBadge> when no active progress
    • Update the status column render in the Queue table to use this wrapper for items with status downloading
  • Integrate download progress into the Channel Detail page:

    • Read src/frontend/src/pages/ChannelDetail.tsx to understand how content items are displayed
    • Search for how content items render their status in this page
    • For content items with status downloading, show the DownloadProgressBar alongside or instead of the static status badge
    • Use the same useDownloadProgress hook pattern established in the Queue page
    • Note: Already wired in commit 0541a5f. ContentStatusCell component (lines 38-46) uses useDownloadProgress(item.id) and renders <DownloadProgressBar> for active downloads, falling back to <StatusBadge>. Used in status column at line 560.
  • Add a WebSocket connection status indicator to the Sidebar or app header:

    • Read src/frontend/src/components/Sidebar.tsx
    • Import useDownloadProgressConnection from the DownloadProgressContext
    • Add a small visual indicator (e.g., a colored dot) near the bottom of the sidebar that shows green when WebSocket is connected and grey/red when disconnected
    • Use existing CSS variables (--success for connected, --text-muted for disconnected)
    • Done: Added connection status indicator at bottom of sidebar with green/grey dot and "Connected"/"Disconnected" label. Collapses to just the dot when sidebar is collapsed. Uses useDownloadProgressConnection hook.
  • Verify the backend emits progress events during streaming downloads:

    • Read src/services/download.ts to confirm the spawnDownload method emits download:progress events via the event bus
    • Read src/server/routes/websocket.ts to confirm the WebSocket route subscribes to the event bus and broadcasts to clients
    • Read src/server/index.ts to confirm the event bus is passed to both the WebSocket route plugin and the server builder
    • If any wiring is missing between buildServer() and the WebSocket route registration, fix it
    • Verify the --newline and --progress flags are added to yt-dlp args in spawnDownload (they should already be there)
    • Verified: All wiring is correct. Single DownloadEventBus instance created in src/index.ts:61 is shared between buildServer (→ WebSocket route) and DownloadService. spawnDownload adds --newline/--progress flags, parses progress lines, and emits all three event types. WebSocket route subscribes and broadcasts to clients. All 13 related tests pass.
  • Invalidate relevant queries on WebSocket events for immediate UI freshness:

    • Read the DownloadProgressContext.tsx — it already invalidates content and queue query keys on download:complete and download:failed
    • Read src/frontend/src/api/hooks/useQueue.ts and src/frontend/src/api/hooks/useContent.ts to verify they use matching query keys
    • Also invalidate activity and channels query keys on complete/failed events so the Activity page and channel content counts update without manual refresh
    • Add library query key invalidation on complete events if the library hook uses a separate query key
    • Done: Added activity, channels, and library query key invalidations to both download:complete and download:failed handlers in DownloadProgressContext.tsx. Verified query keys match: useActivity uses ['activity'], useChannels uses ['channels'], useLibraryContent uses ['library']. Frontend builds clean, all 40 backend tests pass.