fix(27): seek native client to start when backing track ends

When track reaches end:
- UI was reset to position 0
- Native client was NOT seeked to position 0

Result: First play click failed because native client was still at end,
but UI showed position 0 so atEnd check was false and no seek was done.

Fix: Call SessionTrackSeekMs(0) when track ends, so native client
position matches UI state and next play works immediately.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Nuwan 2026-03-02 13:28:58 +05:30
parent d59fdae944
commit fe589f4ac2
1 changed files with 27 additions and 35 deletions

View File

@ -3,6 +3,8 @@ import { Modal, ModalHeader, ModalBody, ModalFooter, Button } from 'reactstrap';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faPlay, faPause, faStop } from '@fortawesome/free-solid-svg-icons';
import useMediaActions from '../../hooks/useMediaActions';
import playIcon from '../../assets/img/client/play.svg';
import stopIcon from '../../assets/img/client/stop.svg';
const JKSessionBackingTrackPlayer = ({
isOpen,
@ -188,6 +190,8 @@ const JKSessionBackingTrackPlayer = ({
console.log('[POLLING] Not looping, stopping and resetting');
// Stop playback and reset to beginning for clean state
await jamClient.SessionStopPlay();
// Seek native client to beginning so next play works immediately
await jamClient.SessionTrackSeekMs(0);
setIsPlaying(false);
setCurrentPositionMs(0);
setCurrentTime('0:00');
@ -491,34 +495,19 @@ const JKSessionBackingTrackPlayer = ({
height: '100vh',
display: 'flex',
flexDirection: 'column',
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", sans-serif',
backgroundColor: '#f8f9fa'
// fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", sans-serif',
backgroundColor: '#edf2f9f5'
}}>
{/* Popup Header */}
<div style={{
height: '40px',
backgroundColor: '#f8f9fa',
borderBottom: '1px solid #dee2e6',
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
padding: '0 12px',
fontWeight: 'bold',
color: '#495057',
userSelect: 'none'
}}>
<span>Backing Track Player</span>
</div>
{/* Popup Content */}
<div style={{
flex: 1,
padding: '30px 20px',
padding: '20px',
overflow: 'auto',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center'
// alignItems: 'center',
// justifyContent: 'center'
}}>
<div style={{ maxWidth: '420px', width: '100%' }}>
<div style={{ display: 'flex', flexDirection: 'column', gap: '20px' }}>
@ -528,7 +517,7 @@ const JKSessionBackingTrackPlayer = ({
fontSize: '14px',
fontWeight: 'normal'
}}>
<span style={{ color: '#999' }}>Backing Track: </span>
<span>Backing Track: </span>
{getFileName(backingTrack)}
</div>
@ -568,18 +557,19 @@ const JKSessionBackingTrackPlayer = ({
{/* Controls Section */}
<div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
{/* Circular Buttons and Seek Bar */}
<div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
<div style={{ display: 'flex', alignItems: 'center', gap: '3px' }}>
{/* Play Button - Circular */}
<button
onClick={handlePlay}
disabled={!backingTrack || isLoadingDuration || isOperating || error}
style={{
width: '36px',
height: '36px',
width: '44px',
height: '44px',
borderRadius: '50%',
border: 'none',
backgroundColor: isPlaying ? '#6c757d' : '#5b9bd5',
color: 'white',
//backgroundColor: isPlaying ? '#6c757d' : '#5b9bd5',
backgroundColor: '#edf2f9f5',
//color: 'white',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
@ -589,7 +579,8 @@ const JKSessionBackingTrackPlayer = ({
flexShrink: 0
}}
>
<FontAwesomeIcon icon={isPlaying ? faPause : faPlay} style={{ fontSize: '14px' }} />
{/* <FontAwesomeIcon icon={isPlaying ? faPause : faPlay} style={{ fontSize: '14px' }} /> */}
<img src={playIcon} alt='play' />
</button>
{/* Stop Button - Circular */}
@ -597,11 +588,11 @@ const JKSessionBackingTrackPlayer = ({
onClick={handleStop}
disabled={!backingTrack || isLoadingDuration || isOperating}
style={{
width: '36px',
height: '36px',
width: '44px',
height: '44ßpx',
borderRadius: '50%',
border: 'none',
backgroundColor: '#b0b0b0',
backgroundColor: '#edf2f9f5',
color: 'white',
display: 'flex',
alignItems: 'center',
@ -612,12 +603,13 @@ const JKSessionBackingTrackPlayer = ({
flexShrink: 0
}}
>
<FontAwesomeIcon icon={faStop} style={{ fontSize: '12px' }} />
{/* <FontAwesomeIcon icon={faStop} style={{ fontSize: '12px' }} /> */}
<img src={stopIcon} alt="stop" />
</button>
{/* Time and Seek Bar */}
<div style={{ display: 'flex', alignItems: 'center', flex: 1, gap: '8px' }}>
<span style={{ fontSize: '14px', color: '#666', minWidth: '35px', fontFamily: 'monospace' }}>{currentTime}</span>
<span style={{ fontSize: '14px', color: '#666', minWidth: '35px' }}>{currentTime}</span>
<input
type="range"
min="0"
@ -635,7 +627,7 @@ const JKSessionBackingTrackPlayer = ({
cursor: (!backingTrack || isLoadingDuration) ? 'not-allowed' : 'pointer'
}}
/>
<span style={{ fontSize: '14px', color: '#666', minWidth: '35px', fontFamily: 'monospace' }}>{duration}</span>
<span style={{ fontSize: '14px', color: '#666', minWidth: '35px' }}>{duration}</span>
</div>
</div>
@ -693,7 +685,7 @@ const JKSessionBackingTrackPlayer = ({
</ModalHeader>
<ModalBody>
<div style={{ display: 'flex', flexDirection: 'column', gap: '20px' }}>
<div style={{ display: 'flex', flexDirection: 'column', gap: '10px' }}>
{/* Title */}
<div style={{
color: '#666',