snapshot of https://github.com/jitsi/jitsi-meet.git @ fd1749dd28f4138aa80234fc7f311b19aaffa0e7 (2026-09-15)
This commit is contained in:
111
react/features/video-menu/components/web/VolumeSlider.tsx
Normal file
111
react/features/video-menu/components/web/VolumeSlider.tsx
Normal file
@@ -0,0 +1,111 @@
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { makeStyles } from 'tss-react/mui';
|
||||
|
||||
import Icon from '../../../base/icons/components/Icon';
|
||||
import { IconVolumeUp } from '../../../base/icons/svg';
|
||||
import { VOLUME_SLIDER_SCALE } from '../../constants';
|
||||
|
||||
/**
|
||||
* The type of the React {@code Component} props of {@link VolumeSlider}.
|
||||
*/
|
||||
interface IProps {
|
||||
|
||||
/**
|
||||
* The value of the audio slider should display at when the component first
|
||||
* mounts. Changes will be stored in state. The value should be a number
|
||||
* between 0 and 1.
|
||||
*/
|
||||
initialValue: number;
|
||||
|
||||
/**
|
||||
* The callback to invoke when the audio slider value changes.
|
||||
*/
|
||||
onChange: Function;
|
||||
}
|
||||
|
||||
const useStyles = makeStyles()(theme => {
|
||||
return {
|
||||
container: {
|
||||
minHeight: '40px',
|
||||
minWidth: '180px',
|
||||
width: '100%',
|
||||
boxSizing: 'border-box',
|
||||
cursor: 'pointer',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
padding: '10px 16px',
|
||||
|
||||
'&:hover': {
|
||||
backgroundColor: theme.palette.videoMenuSliderBackground
|
||||
}
|
||||
},
|
||||
|
||||
icon: {
|
||||
minWidth: '20px',
|
||||
marginRight: '16px',
|
||||
position: 'relative'
|
||||
},
|
||||
|
||||
sliderContainer: {
|
||||
position: 'relative',
|
||||
width: '100%'
|
||||
},
|
||||
|
||||
slider: {
|
||||
position: 'absolute',
|
||||
width: '100%',
|
||||
top: '50%',
|
||||
transform: 'translate(0, -50%)'
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
const _onClick = (e: React.MouseEvent) => {
|
||||
e.stopPropagation();
|
||||
};
|
||||
|
||||
const VolumeSlider = ({
|
||||
initialValue,
|
||||
onChange
|
||||
}: IProps) => {
|
||||
const { classes, cx } = useStyles();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [ volumeLevel, setVolumeLevel ] = useState((initialValue || 0) * VOLUME_SLIDER_SCALE);
|
||||
|
||||
const _onVolumeChange = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const newVolumeLevel = Number(event.currentTarget.value);
|
||||
|
||||
onChange(newVolumeLevel / VOLUME_SLIDER_SCALE);
|
||||
setVolumeLevel(newVolumeLevel);
|
||||
}, [ onChange ]);
|
||||
|
||||
return (
|
||||
<div
|
||||
aria-label = { t('volumeSlider') }
|
||||
className = { cx('popupmenu__contents', classes.container) }
|
||||
onClick = { _onClick }>
|
||||
<span className = { classes.icon }>
|
||||
<Icon
|
||||
size = { 22 }
|
||||
src = { IconVolumeUp } />
|
||||
</span>
|
||||
<div className = { classes.sliderContainer }>
|
||||
<input
|
||||
aria-valuemax = { VOLUME_SLIDER_SCALE }
|
||||
aria-valuemin = { 0 }
|
||||
aria-valuenow = { volumeLevel }
|
||||
className = { cx('popupmenu__volume-slider', classes.slider) }
|
||||
max = { VOLUME_SLIDER_SCALE }
|
||||
min = { 0 }
|
||||
onChange = { _onVolumeChange }
|
||||
tabIndex = { 0 }
|
||||
type = 'range'
|
||||
value = { volumeLevel } />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default VolumeSlider;
|
||||
Reference in New Issue
Block a user