Skip to content

Commit

Permalink
[fix] Fix issue with playing audio in Audio Explorer
Browse files Browse the repository at this point in the history
- Created reusable `AudioPlayer` component with native audio tag
- Fixed `AudioBox` component issues (Explorers)
- Replaced 'material-ui-audio-player' component with `AudioPlayer` component (Explorers)
  • Loading branch information
KaroMourad committed Jul 10, 2023
1 parent e769435 commit 6692831
Show file tree
Hide file tree
Showing 15 changed files with 500 additions and 481 deletions.
15 changes: 15 additions & 0 deletions src/aimcore/web/ui/src/components/AudioPlayer/AudioPlayer.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react';

export interface AudioPlayerProps extends React.HTMLProps<HTMLAudioElement> {
audioRef: React.MutableRefObject<HTMLMediaElement | null>;
src: string;
isPlaying: boolean;
processing: boolean;
onDownload?: () => void;
caption?: string;
readyToPlay: boolean;
onEnded: () => void;
onCanPlay: () => void;
onPlay: () => void;
onPause: () => void;
}
58 changes: 58 additions & 0 deletions src/aimcore/web/ui/src/components/AudioPlayer/AudioPlayer.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
@use 'src/styles/abstracts' as *;

.AudioPlayer {
max-width: toRem(268px);
&__controllers {
position: relative;
display: flex;
align-items: center;
padding: $space-xs;
background-color: $pico-5;
border-radius: $border-radius-main;
width: toRem(268px);
height: toRem(40px);
&__download {
min-width: 1.5rem;
}
&__player {
min-width: 1.5rem;
height: 1.5rem;
border-radius: $radius-main;
position: relative;
display: flex;
align-items: center;
justify-content: center;
transition: background-color 0.18s ease-out;
&:hover {
background-color: rgba(28, 40, 82, 0.04);
}
.Icon__container {
position: absolute;
z-index: 0;
font-size: $text-sm;
}
.MuiPaper-root {
height: 1.5rem;
width: 1.5rem;
display: flex;
align-items: center;
justify-self: center;
background-color: transparent;
box-shadow: unset;
.MuiGrid-root {
padding: 0;
display: flex;
svg {
font-size: $text-xxl;
color: transparent;
z-index: 1;
position: relative;
&:hover {
color: transparent;
}
}
}
}
}
}
}
101 changes: 101 additions & 0 deletions src/aimcore/web/ui/src/components/AudioPlayer/AudioPlayer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import React from 'react';

import ErrorBoundary from 'components/ErrorBoundary';
import { Tooltip, Text } from 'components/kit_v2';

import { Button, Icon, Spinner } from '../kit';

import { AudioPlayerProps, AudioPlayerProgress, AudioPlayerVolume } from '.';

import './AudioPlayer.scss';

function AudioPlayer(props: AudioPlayerProps) {
const {
preload = 'metadata',
muted = true,
autoPlay = true,
audioRef,
src,
onEnded,
onCanPlay,
onPlay,
onPause,
isPlaying = false,
processing = false,
caption = '',
readyToPlay = false,
onDownload,
} = props;

return (
<ErrorBoundary>
<div className='AudioPlayer'>
<div className='AudioPlayer__controllers'>
<div className='AudioPlayer__controllers__player'>
<audio
ref={audioRef}
src={src}
preload={preload}
muted={muted}
autoPlay={autoPlay}
onEnded={onEnded}
onCanPlay={onCanPlay}
onPlay={onPlay}
onPause={onPause}
/>
<>
{processing ? (
<Spinner
className='Icon__container'
size={12}
color='#414b6d'
thickness={2}
/>
) : (
<Button
onClick={isPlaying ? onPause : onPlay}
color='secondary'
withOnlyIcon
size='xSmall'
>
<Icon name={isPlaying ? 'pause' : 'play'} />
</Button>
)}
</>
</div>
<AudioPlayerProgress
audio={audioRef.current}
isPlaying={isPlaying}
src={src}
disabled={!readyToPlay}
/>
<AudioPlayerVolume audio={audioRef.current} />
<div className='AudioPlayer__controllers__download'>
<Button withOnlyIcon size='xSmall' onClick={onDownload}>
{processing ? (
<Spinner
className='Icon__container'
size={12}
color='#414b6d'
thickness={2}
/>
) : (
<Icon name='download' />
)}
</Button>
</div>
</div>
{caption ? (
<Tooltip content={caption} contentProps={{ side: 'bottom' }}>
<Text as='p' weight={400} size={8} ellipsis css={{ marginTop: 4 }}>
{caption}
</Text>
</Tooltip>
) : null}
</div>
</ErrorBoundary>
);
}

AudioPlayer.displayName = 'AudioPlayer';
export default AudioPlayer;
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export interface AudioPlayerProgressProps {
audio: HTMLAudioElement | null;
isPlaying: boolean;
src: string;
disabled?: boolean;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
@use 'src/styles/abstracts' as *;

.AudioPlayerProgress {
display: flex;
align-items: center;
width: 100%;
&__timer {
display: flex;
span {
width: 2rem;
text-align: right;
@include monospaceFontFamily();
&:last-child {
text-align: left;
}
}
&-long {
min-width: toRem(74px);
span {
min-width: 2.5rem;
text-align: right;
display: inline-block;
&:last-child {
text-align: left;
}
}
}
}
&__progressSlider {
margin: 0 $space-xxxs 0 $space-xxs;
height: toRem(40px);
.MuiSlider-root {
height: 100% !important;
}
&.Slider {
&:hover {
.MuiSlider-thumb {
opacity: 1;
visibility: visible;
}
.Mui-disabled {
.MuiSlider-thumb {
opacity: 0;
visibility: hidden;
}
}
}
.MuiSlider {
&-root {
height: 0.375rem;
display: flex;
align-items: center;
}
&-thumb {
width: 0.5rem;
height: 0.5rem;
box-shadow: unset;
margin-top: 0;
transition: opacity 0.18s ease-out;
opacity: 0;
visibility: hidden;
&:hover {
box-shadow: unset;
}
&::after {
width: toRem(18px);
height: toRem(22px);
top: toRem(-6px);
left: toRem(-5px);
}
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,18 @@ import React from 'react';
import moment from 'moment';

import { Slider, Text } from 'components/kit';
import ErrorBoundary from 'components/ErrorBoundary/ErrorBoundary';
import ErrorBoundary from 'components/ErrorBoundary';

import { IAudioBoxProgressProps } from '.';
import { AudioPlayerProgressProps } from './AudioPlayerProgress.d';

function AudioBoxProgress({
import './AudioPlayerProgress.scss';

function AudioPlayerProgress({
audio,
isPlaying,
src,
disabled,
}: IAudioBoxProgressProps) {
}: AudioPlayerProgressProps) {
const [trackProgress, setTrackProgress] = React.useState(0);
const intervalRef = React.useRef<number>();

Expand All @@ -28,12 +30,12 @@ function AudioBoxProgress({
clearInterval(intervalRef.current);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isPlaying, src]);
}, [isPlaying, src, audio]);

function startTimer(): void {
clearInterval(intervalRef.current);
intervalRef.current = window.setInterval(() => {
setTrackProgress(audio.currentTime);
setTrackProgress(audio?.currentTime || 0);
}, 100);
}

Expand All @@ -56,8 +58,8 @@ function AudioBoxProgress({

function formatDuration(): string {
return moment
.utc(Math.round(audio.duration || 0) * 1000)
.format(defineTimeFormat(audio.duration || 0));
.utc(Math.round(audio?.duration || 0) * 1000)
.format(defineTimeFormat(audio?.duration || 0));
}

function defineTimeFormat(duration: number): string {
Expand All @@ -67,34 +69,38 @@ function AudioBoxProgress({
function formatProgress(): string {
return moment
.utc(Math.round(trackProgress) * 1000)
.format(defineTimeFormat(audio.duration || 0));
.format(defineTimeFormat(audio?.duration || 0));
}

return (
<ErrorBoundary>
<Slider
containerClassName='AudioBox__controllers__progressSlider'
onChangeCommitted={onTimerChange}
onChange={onProgressChange}
value={trackProgress}
step={0.1}
max={Math.round(audio?.duration)}
min={0}
disabled={disabled}
/>
<div
className={`AudioBox__controllers__timer ${
audio?.duration > 3600 ? 'AudioBox__controllers__timer-long' : ''
}`}
>
<Text weight={400} size={12}>
{(audio && formatProgress()) || '00:00'}
</Text>
<Text weight={400} size={12}>
/{(audio && formatDuration()) || '00:00'}
</Text>
<div className='AudioPlayerProgress'>
<Slider
containerClassName='AudioPlayerProgress__progressSlider'
onChangeCommitted={onTimerChange}
onChange={onProgressChange}
value={trackProgress}
step={0.1}
max={Math.round(audio?.duration || 0)}
min={0}
disabled={disabled}
/>
<div
className={`AudioPlayerProgress__timer ${
audio?.duration && audio.duration > 3600
? 'AudioPlayerProgress__timer-long'
: ''
}`}
>
<Text weight={400} size={12}>
{(audio && formatProgress()) || '00:00'}
</Text>
<Text weight={400} size={12}>
/{(audio && formatDuration()) || '00:00'}
</Text>
</div>
</div>
</ErrorBoundary>
);
}
export default AudioBoxProgress;
export default AudioPlayerProgress;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export interface AudioPlayerVolumeProps {
audio: HTMLAudioElement | null;
}
Loading

0 comments on commit 6692831

Please sign in to comment.