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";
@@ -31,7 +31,47 @@ export function useClipPlayback() {
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();
if (!audioRef.current) {
audio.onplay = () => {
@@ -70,49 +110,9 @@ export function useClipPlayback() {
audioRef.current = audio;
return audio;
}
}, [stopClip]);
function setPlaybackGain(value: number) {
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 fadeOutClip = useCallback((durationMs = 1000) => {
const audio = audioRef.current;
if (!audio || audio.paused) {
stopClip();
@@ -137,9 +137,9 @@ export function useClipPlayback() {
fadeOutTimerRef.current = window.setTimeout(() => {
stopClip(false);
}, 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) {
return;
}
@@ -192,7 +192,7 @@ export function useClipPlayback() {
stopClip();
throw error;
}
}
}, [ensureAudio, setPlaybackGain, stopClip]);
return {
activeKey,