step 4: stream playback experience
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { useEvent } from "@/hooks/use-event";
|
||||
|
||||
export const EXIT_DELAY_MS = 5000;
|
||||
export const EXIT_TICK_MS = 100;
|
||||
|
||||
type PlaybackStatus = "idle" | "playing" | "ended";
|
||||
|
||||
/**
|
||||
* Returns the remaining ms when the stream has ended, or null otherwise.
|
||||
* Pauses while `paused` is true (compose, hold-to-pause, swipe-down…).
|
||||
*/
|
||||
export function useExitCountdown(
|
||||
status: PlaybackStatus,
|
||||
paused: boolean,
|
||||
onExit: () => void,
|
||||
): number | null {
|
||||
const [remainingMs, setRemainingMs] = useState<number | null>(null);
|
||||
const handleExit = useEvent(onExit);
|
||||
|
||||
useEffect(() => {
|
||||
if (status === "ended") {
|
||||
setRemainingMs(EXIT_DELAY_MS);
|
||||
} else {
|
||||
setRemainingMs(null);
|
||||
}
|
||||
}, [status]);
|
||||
|
||||
useEffect(() => {
|
||||
if (remainingMs === null || remainingMs <= 0 || paused) return;
|
||||
const interval = setInterval(() => {
|
||||
setRemainingMs((prev) => {
|
||||
if (prev === null) return null;
|
||||
const next = prev - EXIT_TICK_MS;
|
||||
return next <= 0 ? 0 : next;
|
||||
});
|
||||
}, EXIT_TICK_MS);
|
||||
return () => clearInterval(interval);
|
||||
}, [remainingMs !== null && remainingMs > 0, paused, remainingMs]);
|
||||
|
||||
useEffect(() => {
|
||||
if (remainingMs !== null && remainingMs <= 0) {
|
||||
handleExit();
|
||||
}
|
||||
}, [remainingMs, handleExit]);
|
||||
|
||||
return remainingMs;
|
||||
}
|
||||
Reference in New Issue
Block a user