import { useEffect, useState } from "react" import { createFileRoute } from "@tanstack/react-router" import { getStreamByUsername, type StreamPageData } from "@/lib/stream/db" import { VideoPlayer } from "@/components/VideoPlayer" import { CloudflareStreamPlayer } from "@/components/CloudflareStreamPlayer" import { WebRTCPlayer } from "@/components/WebRTCPlayer" import { resolveStreamPlayback } from "@/lib/stream/playback" import { JazzProvider } from "@/lib/jazz/provider" import { ViewerCount } from "@/components/ViewerCount" export const Route = createFileRoute("/$username")({ ssr: false, component: StreamPage, }) // Cloudflare Stream HLS URL const HLS_URL = "https://customer-xctsztqzu046isdc.cloudflarestream.com/bb7858eafc85de6c92963f3817477b5d/manifest/video.m3u8" const NIKIV_PLAYBACK = resolveStreamPlayback({ hlsUrl: HLS_URL, webrtcUrl: null }) // Hardcoded user for nikiv const NIKIV_DATA: StreamPageData = { user: { id: "nikiv", name: "Nikita", username: "nikiv", image: null, }, stream: { id: "nikiv-stream", title: "Live Coding", description: "Building in public", is_live: false, // Set to true when actually streaming viewer_count: 0, hls_url: HLS_URL, webrtc_url: null, playback: NIKIV_PLAYBACK, thumbnail_url: null, started_at: null, }, } function StreamPage() { const { username } = Route.useParams() const [data, setData] = useState(null) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) const [streamReady, setStreamReady] = useState(false) const [webRtcFailed, setWebRtcFailed] = useState(false) useEffect(() => { let isActive = true const setReadySafe = (ready: boolean) => { if (isActive) { setStreamReady(ready) } } const setDataSafe = (next: StreamPageData | null) => { if (isActive) { setData(next) } } const setLoadingSafe = (next: boolean) => { if (isActive) { setLoading(next) } } const setErrorSafe = (next: string | null) => { if (isActive) { setError(next) } } const setWebRtcFailedSafe = (next: boolean) => { if (isActive) { setWebRtcFailed(next) } } setReadySafe(false) setWebRtcFailedSafe(false) // Special handling for nikiv - hardcoded stream if (username === "nikiv") { setDataSafe(NIKIV_DATA) setLoadingSafe(false) return () => { isActive = false } } const loadData = async () => { setLoadingSafe(true) setErrorSafe(null) try { const result = await getStreamByUsername(username) setDataSafe(result) } catch (err) { setErrorSafe("Failed to load stream") console.error(err) } finally { setLoadingSafe(false) } } loadData() return () => { isActive = false } }, [username]) const stream = data?.stream ?? null const playback = stream?.playback ?? null const fallbackPlayback = stream?.hls_url ? resolveStreamPlayback({ hlsUrl: stream.hls_url, webrtcUrl: null, preferWebRtc: false, }) : null const activePlayback = playback?.type === "webrtc" && webRtcFailed ? fallbackPlayback ?? playback : playback useEffect(() => { let isActive = true if (!activePlayback || activePlayback.type !== "hls") { return () => { isActive = false } } setStreamReady(false) fetch(activePlayback.url) .then((res) => { if (isActive) { setStreamReady(res.ok) } }) .catch(() => { if (isActive) { setStreamReady(false) } }) return () => { isActive = false } }, [ activePlayback?.type, activePlayback?.type === "hls" ? activePlayback.url : null, ]) if (loading) { return (
Loading...
) } if (error) { return (

Error

{error}

) } if (!data) { return (

User not found

This username doesn't exist or hasn't set up streaming.

) } const showPlayer = activePlayback?.type === "cloudflare" || activePlayback?.type === "webrtc" || (activePlayback?.type === "hls" && streamReady) return (
{/* Viewer count overlay */}
{stream?.is_live && activePlayback && showPlayer ? ( activePlayback.type === "webrtc" ? (
setStreamReady(true)} onError={() => { setWebRtcFailed(true) setStreamReady(!fallbackPlayback) }} /> {!streamReady && (
🔴

Connecting to stream...

)}
) : activePlayback.type === "cloudflare" ? (
setStreamReady(true)} /> {!streamReady && (
🔴

Connecting to stream...

)}
) : ( ) ) : stream?.is_live && activePlayback ? (
🔴

Connecting to stream...

) : ( )}
) }