fix: buggy exit progress when changing clips
This commit is contained in:
@@ -100,7 +100,7 @@ function useExitCountdown(
|
|||||||
composeActive: boolean,
|
composeActive: boolean,
|
||||||
onExit: () => void,
|
onExit: () => void,
|
||||||
) {
|
) {
|
||||||
const [exitProgress, setExitProgress] = useState<number | null>(null);
|
const [remainingMs, setRemainingMs] = useState<number | null>(null);
|
||||||
|
|
||||||
const handleExit = useEffectEvent(() => {
|
const handleExit = useEffectEvent(() => {
|
||||||
onExit();
|
onExit();
|
||||||
@@ -109,35 +109,35 @@ function useExitCountdown(
|
|||||||
// Start/cancel countdown based on playback status
|
// Start/cancel countdown based on playback status
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (status === "ended") {
|
if (status === "ended") {
|
||||||
setExitProgress(0);
|
setRemainingMs(EXIT_DELAY_MS);
|
||||||
} else {
|
} else {
|
||||||
setExitProgress(null);
|
setRemainingMs(null);
|
||||||
}
|
}
|
||||||
}, [status]);
|
}, [status]);
|
||||||
|
|
||||||
// Tick the countdown forward (pauses when compose is active)
|
// Tick the countdown down (pauses when compose is active)
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (exitProgress === null || composeActive) return;
|
if (remainingMs === null || remainingMs <= 0 || composeActive) return;
|
||||||
|
|
||||||
const interval = setInterval(() => {
|
const interval = setInterval(() => {
|
||||||
setExitProgress((prev) => {
|
setRemainingMs((prev) => {
|
||||||
if (prev === null) return null;
|
if (prev === null) return null;
|
||||||
const next = prev + EXIT_TICK_MS / EXIT_DELAY_MS;
|
const next = prev - EXIT_TICK_MS;
|
||||||
return next >= 1 ? 1 : next;
|
return next <= 0 ? 0 : next;
|
||||||
});
|
});
|
||||||
}, EXIT_TICK_MS);
|
}, EXIT_TICK_MS);
|
||||||
|
|
||||||
return () => clearInterval(interval);
|
return () => clearInterval(interval);
|
||||||
}, [exitProgress !== null, composeActive]);
|
}, [remainingMs !== null && remainingMs > 0, composeActive]);
|
||||||
|
|
||||||
// Navigate once countdown completes
|
// Navigate once countdown hits zero
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (exitProgress !== null && exitProgress >= 1) {
|
if (remainingMs !== null && remainingMs <= 0) {
|
||||||
handleExit();
|
handleExit();
|
||||||
}
|
}
|
||||||
}, [exitProgress]);
|
}, [remainingMs]);
|
||||||
|
|
||||||
return exitProgress;
|
return remainingMs;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- StreamView ---
|
// --- StreamView ---
|
||||||
@@ -161,7 +161,7 @@ export function StreamView({ path, streamParticle }: StreamViewProps) {
|
|||||||
navigate(`/${networkId}`);
|
navigate(`/${networkId}`);
|
||||||
}, [navigate, networkId]);
|
}, [navigate, networkId]);
|
||||||
|
|
||||||
const exitProgress = useExitCountdown(
|
const exitRemainingMs = useExitCountdown(
|
||||||
state.status,
|
state.status,
|
||||||
composeActive,
|
composeActive,
|
||||||
handleExitNavigate,
|
handleExitNavigate,
|
||||||
@@ -336,7 +336,6 @@ export function StreamView({ path, streamParticle }: StreamViewProps) {
|
|||||||
current={state.currentIndex}
|
current={state.currentIndex}
|
||||||
progress={progress}
|
progress={progress}
|
||||||
onGoTo={goTo}
|
onGoTo={goTo}
|
||||||
exitProgress={exitProgress}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -372,6 +371,15 @@ export function StreamView({ path, streamParticle }: StreamViewProps) {
|
|||||||
onActiveChange={setComposeActive}
|
onActiveChange={setComposeActive}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{/* Exit countdown */}
|
||||||
|
{exitRemainingMs !== null && (
|
||||||
|
<div className="absolute left-5 top-5 z-10 flex items-center justify-center pointer-events-none">
|
||||||
|
<span className="text-sm text-white/60">
|
||||||
|
Closing in {Math.ceil(exitRemainingMs / 1000)}s
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* Bottom overlay: stream info + reply */}
|
{/* Bottom overlay: stream info + reply */}
|
||||||
<div className="absolute right-0 left-0 bottom-0 z-10">
|
<div className="absolute right-0 left-0 bottom-0 z-10">
|
||||||
<ControlsIndicator type={"reply"} />
|
<ControlsIndicator type={"reply"} />
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ interface PlaybackPageIndicatorProps {
|
|||||||
current: number;
|
current: number;
|
||||||
progress: number;
|
progress: number;
|
||||||
onGoTo: (index: number) => void;
|
onGoTo: (index: number) => void;
|
||||||
exitProgress?: number | null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function PlaybackPageIndicator({
|
export function PlaybackPageIndicator({
|
||||||
@@ -13,7 +12,6 @@ export function PlaybackPageIndicator({
|
|||||||
current,
|
current,
|
||||||
progress,
|
progress,
|
||||||
onGoTo,
|
onGoTo,
|
||||||
exitProgress,
|
|
||||||
}: PlaybackPageIndicatorProps) {
|
}: PlaybackPageIndicatorProps) {
|
||||||
if (total === 0) return null;
|
if (total === 0) return null;
|
||||||
|
|
||||||
@@ -53,26 +51,6 @@ export function PlaybackPageIndicator({
|
|||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
{/* Exit countdown segment */}
|
|
||||||
{exitProgress != null && (
|
|
||||||
<div className="relative h-3 flex-1">
|
|
||||||
<div
|
|
||||||
className={cn(
|
|
||||||
"absolute inset-x-0 top-1 h-1 rounded-full bg-white/30",
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
className={cn(
|
|
||||||
"absolute left-0 top-1 h-1 rounded-full bg-white/90",
|
|
||||||
)}
|
|
||||||
style={{
|
|
||||||
width: `${exitProgress * 100}%`,
|
|
||||||
transition: "width 150ms linear",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user