2026-06-11 04:15:25 +02:00
import { useMutation , useQuery , useQueryClient } from "@tanstack/react-query" ;
2026-06-14 07:08:59 +02:00
import { Database , History , Loader2 , Pause , Play } from "lucide-react" ;
2026-06-11 04:15:25 +02:00
import { api } from "../lib/api" ;
import { formatViews } from "../lib/format" ;
2026-06-14 07:08:59 +02:00
import Tooltip from "./Tooltip" ;
2026-06-11 04:15:25 +02:00
2026-06-14 06:55:18 +02:00
// Per-user status (not the global catalog): shows the number of videos available to *this*
2026-06-14 07:08:59 +02:00
// user, how many of *their* channels are still being fetched, and how many lack full
// history (clickable -> channel manager filtered to those). The pause control is admin-only.
export default function SyncStatus ( {
isAdmin ,
onGoToFullHistory ,
} : {
isAdmin : boolean ;
onGoToFullHistory : ( ) = > void ;
} ) {
2026-06-11 04:15:25 +02:00
const qc = useQueryClient ( ) ;
const { data } = useQuery ( {
2026-06-14 06:55:18 +02:00
queryKey : [ "my-status" ] ,
queryFn : api.myStatus ,
2026-06-11 04:15:25 +02:00
refetchInterval : 30_000 ,
staleTime : 25_000 ,
} ) ;
const toggle = useMutation ( {
mutationFn : ( ) = > ( data ? . paused ? api . resumeSync ( ) : api . pauseSync ( ) ) ,
2026-06-14 06:55:18 +02:00
onSuccess : ( ) = > qc . invalidateQueries ( { queryKey : [ "my-status" ] } ) ,
2026-06-11 04:15:25 +02:00
} ) ;
if ( ! data ) return null ;
2026-06-14 06:55:18 +02:00
const syncing = data . channels_recent_pending ;
2026-06-14 07:08:59 +02:00
const notFull = data . channels_deep_pending ; // your channels without full history yet
2026-06-14 06:55:18 +02:00
2026-06-11 04:15:25 +02:00
return (
< div className = "hidden lg:flex items-center gap-2 text-xs text-muted" >
< Database className = "w-3.5 h-3.5" / >
2026-06-14 06:55:18 +02:00
< span > { formatViews ( data . my_videos ) } videos < / span >
2026-06-11 04:15:25 +02:00
< span className = "opacity-40" > · < / span >
{ data . paused ? (
< span className = "text-accent font-medium" > paused < / span >
2026-06-14 06:55:18 +02:00
) : syncing > 0 ? (
2026-06-11 04:15:25 +02:00
< span className = "flex items-center gap-1" >
< Loader2 className = "w-3.5 h-3.5 animate-spin" / >
2026-06-14 06:55:18 +02:00
{ syncing } syncing
2026-06-11 04:15:25 +02:00
< / span >
) : (
< span > all synced < / span >
) }
2026-06-14 07:08:59 +02:00
{ notFull > 0 && (
< >
< span className = "opacity-40" > · < / span >
< Tooltip hint = "Some of your channels only have their recent uploads. Click to open the channel manager (filtered to these) and request their full back-catalog." >
< button
onClick = { onGoToFullHistory }
className = "flex items-center gap-1 hover:text-fg underline decoration-dotted decoration-muted/40 underline-offset-4 transition cursor-pointer"
>
< History className = "w-3.5 h-3.5" / >
{ notFull } without full history
< / button >
< / Tooltip >
< / >
) }
2026-06-14 06:55:18 +02:00
{ isAdmin && (
2026-06-11 04:15:25 +02:00
< button
onClick = { ( ) = > toggle . mutate ( ) }
disabled = { toggle . isPending }
title = { data . paused ? "Resume background sync" : "Pause background sync" }
className = "ml-1 p-1 rounded-md hover:bg-card hover:text-fg transition"
>
{ data . paused ? < Play className = "w-3.5 h-3.5" / > : < Pause className = "w-3.5 h-3.5" / > }
< / button >
) }
< / div >
) ;
}