diff --git a/js/src/features/particles/stream-view.tsx b/js/src/features/particles/stream-view.tsx index 43de66c..5d973e4 100644 --- a/js/src/features/particles/stream-view.tsx +++ b/js/src/features/particles/stream-view.tsx @@ -90,6 +90,49 @@ const initialState: PlaybackState = { paused: false, }; +// --- Exit countdown hook --- + +const EXIT_DELAY_MS = 5000; +const EXIT_TICK_MS = 100; + +function useExitCountdown( + status: PlaybackStatus, + composeActive: boolean, + onExit: () => void, +) { + const [exitProgress, setExitProgress] = useState(null); + + // Start/cancel countdown based on playback status + useEffect(() => { + if (status === "ended") { + setExitProgress(0); + } else { + setExitProgress(null); + } + }, [status]); + + // Tick the countdown forward (pauses when compose is active) + useEffect(() => { + if (exitProgress === null || composeActive) return; + + const interval = setInterval(() => { + setExitProgress((prev) => { + if (prev === null) return null; + const next = prev + EXIT_TICK_MS / EXIT_DELAY_MS; + if (next >= 1) { + onExit(); + return 1; + } + return next; + }); + }, EXIT_TICK_MS); + + return () => clearInterval(interval); + }, [exitProgress !== null, composeActive, onExit]); + + return exitProgress; +} + // --- StreamView --- interface StreamViewProps { @@ -107,6 +150,16 @@ export function StreamView({ path, streamParticle }: StreamViewProps) { const [progress, setProgress] = useState(0); const hasInitializedRef = useRef(null); + const handleExitNavigate = useCallback(() => { + navigate(`/${networkId}`); + }, [navigate, networkId]); + + const exitProgress = useExitCountdown( + state.status, + composeActive, + handleExitNavigate, + ); + const userId = useAuthStore((s) => s.user?.id); // Reset progress when particle changes @@ -276,6 +329,7 @@ export function StreamView({ path, streamParticle }: StreamViewProps) { current={state.currentIndex} progress={progress} onGoTo={goTo} + exitProgress={exitProgress} /> diff --git a/js/src/features/playback/playback-page-indicator.tsx b/js/src/features/playback/playback-page-indicator.tsx index 7bcf8f9..ffe6d9d 100644 --- a/js/src/features/playback/playback-page-indicator.tsx +++ b/js/src/features/playback/playback-page-indicator.tsx @@ -5,6 +5,7 @@ interface PlaybackPageIndicatorProps { current: number; progress: number; onGoTo: (index: number) => void; + exitProgress?: number | null; } export function PlaybackPageIndicator({ @@ -12,6 +13,7 @@ export function PlaybackPageIndicator({ current, progress, onGoTo, + exitProgress, }: PlaybackPageIndicatorProps) { if (total === 0) return null; @@ -51,6 +53,26 @@ export function PlaybackPageIndicator({ /> ))} + + {/* Exit countdown segment */} + {exitProgress != null && ( +
+
+
+
+ )}
); }