Skip to content

Commit

Permalink
fix(fuselage): AudioPlayer responsiveness (#1052)
Browse files Browse the repository at this point in the history
  • Loading branch information
juliajforesti committed May 19, 2023
1 parent 5d64e33 commit 75bdb4e
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 71 deletions.
104 changes: 68 additions & 36 deletions packages/fuselage/src/components/AudioPlayer/AudioPlayer.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { useMergedRefs } from '@rocket.chat/fuselage-hooks';
import { css } from '@rocket.chat/css-in-js';
import { useMergedRefs, useResizeObserver } from '@rocket.chat/fuselage-hooks';
import React, { useState, useRef, forwardRef } from 'react';

import { Box, IconButton } from '../..';
import { Palette } from '../../Theme';
import { Slider } from '../Slider';

const getMaskTime = (durationTime: number) =>
Expand All @@ -27,6 +29,12 @@ function forceDownload(url: string, fileName?: string) {
};
xhr.send();
}
const SpeedControlStyle = css`
cursor: pointer;
&:hover {
background-color: ${Palette.surface['surface-hover']};
}
`;

export const AudioPlayer = forwardRef<
HTMLAudioElement,
Expand Down Expand Up @@ -68,6 +76,10 @@ export const AudioPlayer = forwardRef<
const [currentTime, setCurrentTime] = useState(0);
const [durationTime, setDurationTime] = useState(0);
const [playbackSpeed, setPlaybackSpeed] = useState(1);
const { ref: containerRef, borderBoxSize } = useResizeObserver();

const collapseControls =
borderBoxSize.inlineSize && borderBoxSize.inlineSize < 240;

const handlePlay = () => {
const isPlaying = audioRef.current?.paused;
Expand All @@ -81,28 +93,35 @@ export const AudioPlayer = forwardRef<

const handlePlaybackSpeed = (mod: 1 | -1) => {
if (audioRef.current) {
audioRef.current.playbackRate = Math.max(
Math.min(
audioRef.current.playbackRate + playbackSpeedStep * mod,
maxPlaybackSpeed
),
minPlaybackSpeed
);
audioRef.current.playbackRate += playbackSpeedStep * mod;
}
};

const handleIncreasePlayBackSpeed = () => handlePlaybackSpeed(1);

const handleDecreasePlayBackSpeed = () => handlePlaybackSpeed(-1);

const handlePlaybackSpeedSingleControl = () => {
const reachedMaxPlaybackSpeed =
maxPlaybackSpeed === audioRef?.current?.playbackRate;

if (reachedMaxPlaybackSpeed) {
audioRef.current.playbackRate = minPlaybackSpeed;
return;
}
handleIncreasePlayBackSpeed();
};

return (
<Box
borderWidth='default'
bg='light'
borderColor='extra-light'
p='x16'
width='fit-content'
p='x8'
borderRadius='x4'
w='100%'
maxWidth='x300'
ref={containerRef}
>
<Box display='flex' alignItems='center'>
<IconButton
Expand All @@ -111,7 +130,7 @@ export const AudioPlayer = forwardRef<
aria-label={isPlaying ? pauseLabel : playLabel}
icon={isPlaying ? 'pause-unfilled' : 'play-unfilled'}
/>
<Box mi='x12' position='relative'>
<Box mi='x12' position='relative' w='100%'>
<Slider
aria-label={audioPlaybackRangeLabel}
showOutput={false}
Expand All @@ -134,35 +153,48 @@ export const AudioPlayer = forwardRef<
mb={'neg-x8'}
>
{getMaskTime(currentTime)}
<Box
fontScale='micro'
display='flex'
justifyContent='space-around'
id='controllers'
>
{collapseControls ? (
<Box width='100%' display='flex' justifyContent='space-around'>
<Box
p='x4'
onClick={handlePlaybackSpeedSingleControl}
borderRadius='x4'
className={SpeedControlStyle}
>
{playbackSpeed.toFixed(1)}x
</Box>
</Box>
) : (
<Box
mi='x8'
fontScale='micro'
display='flex'
alignItems='center'
justifyContent='space-between'
justifyContent='space-around'
id='controllers'
>
<IconButton
aria-label={reducePlaybackSpeedLabel}
disabled={playbackSpeed <= minPlaybackSpeed}
icon='h-bar'
mini
onClick={handleDecreasePlayBackSpeed}
/>
<Box mi='x8'>{playbackSpeed.toFixed(1)}x</Box>
<IconButton
aria-label={increasePlaybackSpeedLabel}
disabled={playbackSpeed >= maxPlaybackSpeed}
icon='plus'
mini
onClick={handleIncreasePlayBackSpeed}
/>
<Box
mi='x8'
display='flex'
alignItems='center'
justifyContent='space-between'
>
<IconButton
aria-label={reducePlaybackSpeedLabel}
disabled={playbackSpeed <= minPlaybackSpeed}
icon='h-bar'
mini
onClick={handleDecreasePlayBackSpeed}
/>
<Box mi='x8'>{playbackSpeed.toFixed(1)}x</Box>
<IconButton
aria-label={increasePlaybackSpeedLabel}
disabled={playbackSpeed >= maxPlaybackSpeed}
icon='plus'
mini
onClick={handleIncreasePlayBackSpeed}
/>
</Box>
</Box>
</Box>
)}
{getMaskTime(durationTime)}
</Box>
</Box>
Expand Down
35 changes: 11 additions & 24 deletions packages/fuselage/src/components/Slider/Slider.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,12 @@ export default {
} as ComponentMeta<typeof Slider>;

const Template: ComponentStory<typeof Slider> = (args) => (
<Box width='500px' minHeight='100%' display='flex' alignItems='center'>
<Box width='x300' display='flex' alignItems='center'>
<Slider {...args} />
</Box>
);
const TemplateVertical: ComponentStory<typeof Slider> = (args) => (
<Box h='x200' display='flex' alignItems='center'>
<Slider {...args} />
</Box>
);
Expand Down Expand Up @@ -63,18 +68,6 @@ Default.args = {
'maxValue': 500,
} as const;

export const Small: ComponentStory<typeof Slider> = Template.bind({});
Small.args = {
'aria-label': 'aria-range-label',
'small': true,
} as const;

export const Large: ComponentStory<typeof Slider> = Template.bind({});
Large.args = {
'aria-label': 'aria-range-label',
'large': true,
} as const;

export const NoOutput: ComponentStory<typeof Slider> = Template.bind({});
NoOutput.args = {
'showOutput': false,
Expand All @@ -87,30 +80,24 @@ WithLabel.args = {
'aria-label': 'range',
} as const;

export const Vertical: ComponentStory<typeof Slider> = Template.bind({});
export const Vertical: ComponentStory<typeof Slider> = TemplateVertical.bind(
{}
);
Vertical.args = {
'label': 'Range',
'aria-label': 'range',
'orientation': 'vertical',
} as const;

export const VerticalMultiThumb: ComponentStory<typeof Slider> = Template.bind(
{}
);
export const VerticalMultiThumb: ComponentStory<typeof Slider> =
TemplateVertical.bind({});
VerticalMultiThumb.args = {
'label': 'Range',
'aria-label': 'range',
'orientation': 'vertical',
'multiThumb': true,
} as const;

export const VerticalSmall: ComponentStory<typeof Slider> = Template.bind({});
VerticalSmall.args = {
'aria-label': 'aria-range-label',
'small': true,
'orientation': 'vertical',
} as const;

export const WithDefaultValue: ComponentStory<typeof Slider> = Template.bind(
{}
);
Expand Down
11 changes: 2 additions & 9 deletions packages/fuselage/src/components/Slider/Slider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,6 @@ type SliderProps<T extends number | number[]> = AriaAttributes & {
orientation?: 'horizontal' | 'vertical';
disabled?: boolean;
defaultValue?: T;
small?: boolean;
/**
* 100% of parent's dimention
*/
large?: boolean;
} & (
| {
value: T;
Expand All @@ -61,8 +56,6 @@ export function Slider<T extends number | [min: number, max: number]>(
multiThumb,
maxValue,
minValue,
small,
large,
} = props;

// Get a defaultValue in the range for multiThumb
Expand Down Expand Up @@ -119,12 +112,12 @@ export function Slider<T extends number | [min: number, max: number]>(
${isHorizontal &&
css`
flex-direction: column;
width: ${small ? '150px' : large ? '100%' : '300px'};
width: 100%;
`};
${isVertical &&
css`
flex-direction: row-reverse;
height: ${small ? '50px' : large ? '100%' : '100px'};
height: 100%;
`}
`,
sliderState
Expand Down
4 changes: 2 additions & 2 deletions packages/fuselage/src/components/Slider/SliderTrack.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export const SliderTrack = ({
const getTrackGradient = () => {
if (isHorizontal) {
return multiThumb
? `to right, ${light}} ${getThumbPosition(
? `to right, ${light} ${getThumbPosition(
state.values[0]
)}%, ${highlight} 0, ${highlight} ${getThumbPosition(
state.values[1]
Expand Down Expand Up @@ -98,7 +98,7 @@ export const SliderTrack = ({
height: 100%;
&::before {
left: 50%;
width: 8px;
width: 4px;
height: 100%;
}
`};
Expand Down

0 comments on commit 75bdb4e

Please sign in to comment.