From f8b9df5e805a986bc141bfe823366aae2956bde1 Mon Sep 17 00:00:00 2001 From: npeter83 Date: Sun, 14 Jun 2026 06:55:18 +0200 Subject: [PATCH] fix(header): show per-user sync status instead of the global catalog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The header status bar read the global /api/sync/status (videos_total + channels_backfilling), so every user saw the whole catalog's numbers — confusing and a small cross-user info leak (e.g. "3 syncing" for a user with 2 channels). It now uses /api/sync/my-status: the user's own available video count and how many of their own channels are still being fetched (channels_recent_pending). The pause control stays admin-only via an isAdmin prop. --- frontend/src/components/Header.tsx | 2 +- frontend/src/components/SyncStatus.tsx | 21 +++++++++++++-------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/frontend/src/components/Header.tsx b/frontend/src/components/Header.tsx index 99e4eda..bdce358 100644 --- a/frontend/src/components/Header.tsx +++ b/frontend/src/components/Header.tsx @@ -36,7 +36,7 @@ export default function Header({ Siftlode - + {page === "feed" ? (
diff --git a/frontend/src/components/SyncStatus.tsx b/frontend/src/components/SyncStatus.tsx index b79fb7b..88c4288 100644 --- a/frontend/src/components/SyncStatus.tsx +++ b/frontend/src/components/SyncStatus.tsx @@ -3,38 +3,43 @@ import { Database, Loader2, Pause, Play } from "lucide-react"; import { api } from "../lib/api"; import { formatViews } from "../lib/format"; -export default function SyncStatus() { +// Per-user status (not the global catalog): shows the number of videos available to *this* +// user and how many of *their* channels are still being fetched. The pause control is +// admin-only (it pauses the shared background sync). +export default function SyncStatus({ isAdmin }: { isAdmin: boolean }) { const qc = useQueryClient(); const { data } = useQuery({ - queryKey: ["sync-status"], - queryFn: api.status, + queryKey: ["my-status"], + queryFn: api.myStatus, refetchInterval: 30_000, staleTime: 25_000, }); const toggle = useMutation({ mutationFn: () => (data?.paused ? api.resumeSync() : api.pauseSync()), - onSuccess: () => qc.invalidateQueries({ queryKey: ["sync-status"] }), + onSuccess: () => qc.invalidateQueries({ queryKey: ["my-status"] }), }); if (!data) return null; + const syncing = data.channels_recent_pending; + return (
- {formatViews(data.videos_total)} videos + {formatViews(data.my_videos)} videos · {data.paused ? ( paused - ) : data.channels_backfilling > 0 ? ( + ) : syncing > 0 ? ( - {data.channels_backfilling} syncing + {syncing} syncing ) : ( all synced )} - {data.is_admin && ( + {isAdmin && (