diff --git a/packages/web/src/components/LiveNowSidebar.tsx b/packages/web/src/components/LiveNowSidebar.tsx new file mode 100644 index 00000000..9ec2afe2 --- /dev/null +++ b/packages/web/src/components/LiveNowSidebar.tsx @@ -0,0 +1,98 @@ +import { useState, useEffect } from "react" +import { Link } from "@tanstack/react-router" +import { Radio, X } from "lucide-react" + +const DISMISS_KEY = "linsa_live_dismissed" +const DISMISS_DURATION_MS = 30 * 60 * 1000 // 30 minutes + +interface LiveNowSidebarProps { + /** Don't show on the nikiv page itself */ + currentUsername?: string +} + +export function LiveNowSidebar({ currentUsername }: LiveNowSidebarProps) { + const [isLive, setIsLive] = useState(false) + const [isDismissed, setIsDismissed] = useState(true) // Start hidden to avoid flash + + // Check if dismissed + useEffect(() => { + const stored = localStorage.getItem(DISMISS_KEY) + if (stored) { + const dismissedAt = parseInt(stored, 10) + if (Date.now() - dismissedAt < DISMISS_DURATION_MS) { + setIsDismissed(true) + return + } + } + setIsDismissed(false) + }, []) + + // Check live status + useEffect(() => { + const checkLiveStatus = async () => { + try { + const response = await fetch("/api/check-hls") + if (response.ok) { + const data = await response.json() + setIsLive(Boolean(data.isLive)) + } + } catch { + // Ignore errors + } + } + + checkLiveStatus() + const interval = setInterval(checkLiveStatus, 30000) + return () => clearInterval(interval) + }, []) + + const handleDismiss = (e: React.MouseEvent) => { + e.preventDefault() + e.stopPropagation() + localStorage.setItem(DISMISS_KEY, Date.now().toString()) + setIsDismissed(true) + } + + // Don't show if not live, dismissed, or already on nikiv's page + if (!isLive || isDismissed || currentUsername === "nikiv") { + return null + } + + return ( +
+ nikiv
+Streaming now
+
- nikiv
-Streaming now
-