49 lines
1.3 KiB
TypeScript
49 lines
1.3 KiB
TypeScript
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;
|
|
}
|