diff --git a/src/audio-player-composable/__tests__/__snapshots__/audio-player-composable.test.tsx.snap b/src/audio-player-composable/__tests__/__snapshots__/audio-player-composable.test.tsx.snap index 930595dc38..4bd6248bbc 100644 --- a/src/audio-player-composable/__tests__/__snapshots__/audio-player-composable.test.tsx.snap +++ b/src/audio-player-composable/__tests__/__snapshots__/audio-player-composable.test.tsx.snap @@ -806,6 +806,7 @@ exports[`Audio Player Composable renders with TimeDisplay label overrides 1`] = 00:00/00:00 @@ -2357,6 +2358,7 @@ exports[`Audio Player Composable seekBar should renders with overrides 1`] = ` 00:00/00:00 diff --git a/src/audio-player-composable/__tests__/audio-player-composable.stories.tsx b/src/audio-player-composable/__tests__/audio-player-composable.stories.tsx index 58c7de4f58..5936978f7f 100644 --- a/src/audio-player-composable/__tests__/audio-player-composable.stories.tsx +++ b/src/audio-player-composable/__tests__/audio-player-composable.stories.tsx @@ -467,6 +467,58 @@ export const AudioSubComponents = () => ( ); AudioSubComponents.storyName = 'audio-sub-components'; +export const AudioPlayerWithInitialProps = () => { + const breakpointKey = useBreakpointKey(); + return ( + + + {Areas => ( + <> + + + + + + + + + + + + + + calculateTime(currentTime)} + /> + + + + calculateTime(duration)} + /> + + + )} + + + ); +}; + +AudioPlayerWithInitialProps.storyName = 'audio-player-with-initial-props'; + export const AudioPlayerOverrides = () => ( Audio player with overrides diff --git a/src/audio-player-composable/__tests__/audio-player-composable.test.tsx b/src/audio-player-composable/__tests__/audio-player-composable.test.tsx index 5fe306e489..48223e8016 100644 --- a/src/audio-player-composable/__tests__/audio-player-composable.test.tsx +++ b/src/audio-player-composable/__tests__/audio-player-composable.test.tsx @@ -77,6 +77,17 @@ const AudioPropsAndVolumeControlWithInitialVolumeCollapsed: AudioPlayerComposabl ), }; +const AudioPropsWithInitialTime: AudioPlayerComposableProps = { + initialTime: 50, + src: 'https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3', + children: ( + <> + + + + ), +}; + const AudioPropsAndVolumeControlVertical: AudioPlayerComposableProps = { src: 'https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3', initialVolume: 0.2, @@ -902,6 +913,25 @@ describe('Audio Player Composable', () => { expect(asFragment()).toMatchSnapshot(); }); }); + describe('initialTime prop', () => { + it('should render correctly with initial time', () => { + const {getByTestId} = renderWithTheme( + AudioPlayerComposable, + AudioPropsWithInitialTime, + ); + + const audioElement = getByTestId('audio-element') as HTMLAudioElement; + const audioTimeLabel = getByTestId( + 'audio-player-time-display', + ) as HTMLParagraphElement; + + const seekBar = getByTestId('audio-slider-track') as HTMLDivElement; + fireEvent.timeUpdate(audioElement); + expect(audioElement.currentTime).toEqual(50); + expect(audioTimeLabel.innerHTML).toEqual('00:50/00:00 '); + expect(seekBar.getAttribute('values')).toEqual('50'); + }); + }); describe('Instrumentation tests', () => { test('should raise "end" event when the track has ended', () => { diff --git a/src/audio-player-composable/audio-functions.ts b/src/audio-player-composable/audio-functions.ts index 60d9326556..68755c1401 100644 --- a/src/audio-player-composable/audio-functions.ts +++ b/src/audio-player-composable/audio-functions.ts @@ -223,6 +223,7 @@ export const useAudioFunctions = ({ const onTimeUpdate = useCallback( ({target}: SyntheticEvent) => { const eventTime = Math.floor((target as HTMLAudioElement).currentTime); + if (currentTimeRef.current !== eventTime) { setCurrentTime(eventTime); diff --git a/src/audio-player-composable/audio-player-composable.tsx b/src/audio-player-composable/audio-player-composable.tsx index 1afc7267ad..cf96ba3b33 100644 --- a/src/audio-player-composable/audio-player-composable.tsx +++ b/src/audio-player-composable/audio-player-composable.tsx @@ -47,6 +47,7 @@ export const AudioPlayerComposable = ({ ariaLandmark, keyboardShortcuts: keyboardShortcutsProp, initialVolume = 0.7, + initialTime = 0, ...props }: AudioPlayerComposableProps) => { const currentTimeRef = useRef(0); @@ -71,9 +72,15 @@ export const AudioPlayerComposable = ({ }); useEffect(() => { + // On render onTimeUpdate will be fired and initialTime will be set as a value for currentTime state. + // I can't set this one to the setCurrentTime state directly as the audioElement time + // will still be 0, currentTime will be overridden to 0 and the audio will start from 0 + if (audioRef && audioRef.current) { + audioRef.current.currentTime = initialTime; + } setCurrentTime(0); setDisplayDuration(0); - }, [src]); + }, [src, initialTime]); const { audioEvents, @@ -224,7 +231,7 @@ export const AudioPlayerComposable = ({ initialVolume, muteButtonSize, }), - [volume, onChangeVolumeSlider], + [volume, initialVolume, onChangeVolumeSlider], ); const getSkipPreviousButtonProps = useCallback( diff --git a/src/audio-player-composable/components/time-display/time-display.tsx b/src/audio-player-composable/components/time-display/time-display.tsx index 97c9349573..785d984b89 100644 --- a/src/audio-player-composable/components/time-display/time-display.tsx +++ b/src/audio-player-composable/components/time-display/time-display.tsx @@ -22,7 +22,12 @@ const ThemelessTimeDisplay = ({ const {format: defaultFormat, currentTime, duration} = getTimeDisplayProps!(); const formatFn = typeof format === 'function' ? format : defaultFormat; return ( - + {formatFn({currentTime, duration})} ); diff --git a/src/audio-player-composable/types.ts b/src/audio-player-composable/types.ts index 9265bcd2e5..779ac14f04 100644 --- a/src/audio-player-composable/types.ts +++ b/src/audio-player-composable/types.ts @@ -103,6 +103,7 @@ export interface AudioPlayerComposableProps jumpToEnd: string | string[]; }; initialVolume?: 0 | 0.1 | 0.2 | 0.3 | 0.4 | 0.5 | 0.6 | 0.7 | 0.8 | 0.9 | 1; + initialTime?: number; } export enum AudioEvents {