Skip to content

Commit

Permalink
ar(feat) DPCP-31: Audio Player
Browse files Browse the repository at this point in the history
  • Loading branch information
angeloreale committed Aug 4, 2024
1 parent 2fcbac5 commit a3e793f
Showing 1 changed file with 84 additions and 18 deletions.
102 changes: 84 additions & 18 deletions src/molecules/02_AudioPlayer/AudioPlayer.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
/* eslint jsx-a11y/media-has-caption:0, no-nested-ternary:0, no-unused-vars:0, max-len:0, no-shadow:0, @typescript-eslint/no-explicit-any:0, object-curly-newline:0 */

Check failure on line 1 in src/molecules/02_AudioPlayer/AudioPlayer.tsx

View workflow job for this annotation

GitHub Actions / oneiros::pr_checks::build

'audioElement.current' is possibly 'undefined'.

Check failure on line 1 in src/molecules/02_AudioPlayer/AudioPlayer.tsx

View workflow job for this annotation

GitHub Actions / oneiros::pr_checks::build

Property 'isPlaying' does not exist on type 'never'.

Check failure on line 1 in src/molecules/02_AudioPlayer/AudioPlayer.tsx

View workflow job for this annotation

GitHub Actions / oneiros::pr_checks::build

Property 'pause' does not exist on type 'never'.

Check failure on line 1 in src/molecules/02_AudioPlayer/AudioPlayer.tsx

View workflow job for this annotation

GitHub Actions / oneiros::pr_checks::build

Property 'currentTime' does not exist on type 'never'.

Check failure on line 1 in src/molecules/02_AudioPlayer/AudioPlayer.tsx

View workflow job for this annotation

GitHub Actions / oneiros::pr_checks::build

'audioElement.current' is possibly 'undefined'.

Check failure on line 1 in src/molecules/02_AudioPlayer/AudioPlayer.tsx

View workflow job for this annotation

GitHub Actions / oneiros::pr_checks::build

'audioElement.current' is possibly 'undefined'.

Check failure on line 1 in src/molecules/02_AudioPlayer/AudioPlayer.tsx

View workflow job for this annotation

GitHub Actions / oneiros::pr_checks::build

Expected 2 arguments, but got 1.

Check failure on line 1 in src/molecules/02_AudioPlayer/AudioPlayer.tsx

View workflow job for this annotation

GitHub Actions / oneiros::pr_checks::build

'audioElement.current' is possibly 'undefined'.

Check failure on line 1 in src/molecules/02_AudioPlayer/AudioPlayer.tsx

View workflow job for this annotation

GitHub Actions / oneiros::pr_checks::build

'audioElement.current' is possibly 'undefined'.
// @atoms/AudioPlayer.tsx
import clsx from 'clsx';
import { Fragment } from 'react';
import { Fragment, useRef, useState, useEffect } from 'react';
import Grid, {
EBleedVariant,
EGridVariant,
} from '../../atoms/10_Grid/Grid.tsx';

import { Button, ButtonVariant, EButtonTheme } from '../../atoms/01_Button';
import { Typography } from '../../atoms/02_Typography';
import { ESystemIcon } from '../../atoms/05_SystemIcon';

export const DEFAULT_TRACKS = [
{
id: 'dreampip__chan_0000',
Expand Down Expand Up @@ -49,6 +53,8 @@ export interface IAudioPlayer {
className?: string;
tracks?: IAudioTrack[];
onPlayTrack?: () => void;
nativeControls?: boolean;
prompt?: string;
theme?: 'light' | 'dark';
}

Expand All @@ -57,22 +63,62 @@ export const HAudioPlayer = function ({
className = '',
tracks = DEFAULT_TRACKS,
onPlayTrack = () => {},
nativeControls = false,
prompt = 'Rotation portals',
theme = 'light',
}: IAudioPlayer) {
const audioElement = useRef();
const [status, setStatus] = useState('stopped');
const [title, setTitle] = useState(prompt);
const gridSx = [
{
[`class02
grid
sm:grid-cols-12
sm:!gap-a0
md:!gap-a4
md:!gap-a1
content-center
items-center
align-center
justify-center
`]: true,
},
];

const gridStyles = `${clsx(gridSx)} ${className}`;

onPlayTrack();
const handlePlay = () => {
onPlayTrack();
audioElement.current.isPlaying = status === 'playing';

if (audioElement?.current?.isPlaying) {
audioElement.current.pause();
audioElement.current.currentTime = 0;
setStatus('stopped');
} else {
audioElement.current.play();
setStatus('playing');
}
};

const handleStatus = (status: string, options: { title?: string }) => () => {
setStatus(status);
setTitle(options?.title || prompt);
};

useEffect(() => {
const handlePlay = handleStatus('playing', {
title: audioElement.current.getAttribute('data-title'),
});
const handleStop = handleStatus('stopped');
audioElement.current.addEventListener('play', handlePlay);
audioElement.current.addEventListener('ended', handleStop);

return () => {
audioElement.current.removeEventListener('play', handlePlay);
audioElement.current.removeEventListener('ended', handleStop);

Check warning on line 119 in src/molecules/02_AudioPlayer/AudioPlayer.tsx

View workflow job for this annotation

GitHub Actions / oneiros::pr_checks::lint

The ref value 'audioElement.current' will likely have changed by the time this effect cleanup function runs. If this ref points to a node rendered by React, copy 'audioElement.current' to a variable inside the effect, and use that variable in the cleanup function
};
}, [status]);

Check warning on line 121 in src/molecules/02_AudioPlayer/AudioPlayer.tsx

View workflow job for this annotation

GitHub Actions / oneiros::pr_checks::lint

React Hook useEffect has a missing dependency: 'handleStatus'. Either include it or remove the dependency array

return (
<Grid
Expand All @@ -82,23 +128,43 @@ export const HAudioPlayer = function ({
variant={EGridVariant.TWELVE_COLUMNS}
bleed={EBleedVariant.RESPONSIVE}
>
<audio
src={tracks[0].url}
<div className="flex items-center justify-center col-span-full sm:col-span-1 lg:col-span-1 col-start-0">
<Button
className="w-full"
theme={theme}
icon={status === 'playing' ? ESystemIcon.stop : ESystemIcon.play}
variant={ButtonVariant.FILLED}
buttonTheme={EButtonTheme.PRIMARY}
onClick={handlePlay}
/>
<audio
src={tracks[0].url}
controls={nativeControls}
ref={audioElement}
autoPlay
preload
>
{tracks.map((file) => (
<>
<source src={file.url} type="audio/mpeg" />
<track
kind="subtitles"
key={`molecules__AudioPlayer__card__element--${file.title}`}
data-title={file.title}
srcLang="en"
label="English"
src={file.url}
/>
</>
))}
</audio>
</div>
<Typography
className="col-span-full sm:col-span-6 lg:col-span-4 col-start-0"
truncate
>
{tracks.map((file) => (
<>
<source src={file.url} type="audio/mpeg" />
<track
kind="subtitles"
key={`molecules__AudioPlayer__card__element--${file.title}`}
srcLang="en"
label="English"
src={file.url}
/>
</>
))}
</audio>
{title}
</Typography>
</Grid>
);
};
Expand Down

0 comments on commit a3e793f

Please sign in to comment.