Fix gameday playback regression

This commit is contained in:
Codex
2026-04-23 11:21:52 -05:00
parent 0c24ba7111
commit 8f17355417

View File

@@ -1,4 +1,4 @@
import { useEffect, useRef, useState } from "react"; import { useCallback, useEffect, useRef, useState } from "react";
import { API_BASE } from "../api/client"; import { API_BASE } from "../api/client";
@@ -31,7 +31,47 @@ export function useClipPlayback() {
useEffect(() => stopClip(), []); useEffect(() => stopClip(), []);
function ensureAudio() { const setPlaybackGain = useCallback((value: number) => {
const gainNode = gainNodeRef.current;
if (!gainNode) {
return;
}
gainNode.gain.cancelScheduledValues(gainNode.context.currentTime);
gainNode.gain.setValueAtTime(value, gainNode.context.currentTime);
}, []);
const clearFadeOutTimer = useCallback(() => {
if (fadeOutTimerRef.current !== null) {
window.clearTimeout(fadeOutTimerRef.current);
fadeOutTimerRef.current = null;
}
}, []);
const stopClip = useCallback((resetGain = true) => {
clearFadeOutTimer();
const audio = audioRef.current;
if (audio) {
audio.pause();
audio.currentTime = 0;
audio.removeAttribute("src");
audio.load();
}
if (resetGain) {
setPlaybackGain(1);
}
activeKeyRef.current = null;
playbackRangeRef.current = null;
setActiveKey(null);
setActiveDetails(null);
setIsPlaying(false);
setCurrentTimeMs(null);
}, [clearFadeOutTimer, setPlaybackGain]);
const ensureAudio = useCallback(() => {
const audio = audioRef.current ?? new Audio(); const audio = audioRef.current ?? new Audio();
if (!audioRef.current) { if (!audioRef.current) {
audio.onplay = () => { audio.onplay = () => {
@@ -70,49 +110,9 @@ export function useClipPlayback() {
audioRef.current = audio; audioRef.current = audio;
return audio; return audio;
} }, [stopClip]);
function setPlaybackGain(value: number) { const fadeOutClip = useCallback((durationMs = 1000) => {
const gainNode = gainNodeRef.current;
if (!gainNode) {
return;
}
gainNode.gain.cancelScheduledValues(gainNode.context.currentTime);
gainNode.gain.setValueAtTime(value, gainNode.context.currentTime);
}
function clearFadeOutTimer() {
if (fadeOutTimerRef.current !== null) {
window.clearTimeout(fadeOutTimerRef.current);
fadeOutTimerRef.current = null;
}
}
function stopClip(resetGain = true) {
clearFadeOutTimer();
const audio = audioRef.current;
if (audio) {
audio.pause();
audio.currentTime = 0;
audio.removeAttribute("src");
audio.load();
}
if (resetGain) {
setPlaybackGain(1);
}
activeKeyRef.current = null;
playbackRangeRef.current = null;
setActiveKey(null);
setActiveDetails(null);
setIsPlaying(false);
setCurrentTimeMs(null);
}
function fadeOutClip(durationMs = 1000) {
const audio = audioRef.current; const audio = audioRef.current;
if (!audio || audio.paused) { if (!audio || audio.paused) {
stopClip(); stopClip();
@@ -137,9 +137,9 @@ export function useClipPlayback() {
fadeOutTimerRef.current = window.setTimeout(() => { fadeOutTimerRef.current = window.setTimeout(() => {
stopClip(false); stopClip(false);
}, safeDuration); }, safeDuration);
} }, [clearFadeOutTimer, stopClip]);
async function playClip({ key, url, startMs, endMs, title, subtitle }: PlayClipArgs) { const playClip = useCallback(async ({ key, url, startMs, endMs, title, subtitle }: PlayClipArgs) => {
if (!url) { if (!url) {
return; return;
} }
@@ -192,7 +192,7 @@ export function useClipPlayback() {
stopClip(); stopClip();
throw error; throw error;
} }
} }, [ensureAudio, setPlaybackGain, stopClip]);
return { return {
activeKey, activeKey,