feat(05-03): implement seek slider with UAT-003 fix
- Add handleSeek with useCallback wrapper - Implement UAT-003 fix pattern (pending seek while paused, immediate while playing) - Store pending seek in pendingSeekRef when paused, update UI immediately - Apply pending seek on resume in handlePlay (already implemented) - Add seek slider with correct min/max/value bindings - Disable slider during operations and before duration loaded - Parse slider value to int before passing to handler - Error handling for seek failures Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
e5e0102921
commit
16af15c858
|
|
@ -183,6 +183,29 @@ const JKSessionJamTrackPlayer = ({
|
|||
}
|
||||
}, [isOperating, jamClient, dispatch]);
|
||||
|
||||
// Seek handler
|
||||
const handleSeek = useCallback(async (newPositionMs) => {
|
||||
if (isOperating || !jamClient || !fqIdRef.current) return;
|
||||
|
||||
try {
|
||||
setError(null);
|
||||
|
||||
// UAT-003 fix: if paused, store pending seek
|
||||
if (jamTrackState.isPaused) {
|
||||
pendingSeekRef.current = newPositionMs;
|
||||
dispatch(setJamTrackState({ currentPositionMs: newPositionMs }));
|
||||
return;
|
||||
}
|
||||
|
||||
// If playing, seek immediately
|
||||
await jamClient.JamTrackSeekMs(fqIdRef.current, newPositionMs);
|
||||
dispatch(setJamTrackState({ currentPositionMs: newPositionMs }));
|
||||
} catch (err) {
|
||||
console.error('[JamTrack] Seek error:', err);
|
||||
setError({ type: 'playback', message: 'Failed to seek' });
|
||||
}
|
||||
}, [isOperating, jamClient, jamTrackState.isPaused, dispatch]);
|
||||
|
||||
// Helper: Format milliseconds to MM:SS
|
||||
const formatTime = (ms) => {
|
||||
if (!ms || isNaN(ms)) return '00:00';
|
||||
|
|
@ -279,6 +302,18 @@ const JKSessionJamTrackPlayer = ({
|
|||
</button>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<input
|
||||
type="range"
|
||||
min="0"
|
||||
max={jamTrackState.durationMs || 100}
|
||||
value={jamTrackState.currentPositionMs || 0}
|
||||
onChange={(e) => handleSeek(parseInt(e.target.value, 10))}
|
||||
disabled={isOperating || !jamTrackState.durationMs}
|
||||
style={{ width: '300px' }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p>
|
||||
{formatTime(jamTrackState.currentPositionMs)} / {formatTime(jamTrackState.durationMs)}
|
||||
|
|
|
|||
Loading…
Reference in New Issue