Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

VolumeSlider.js 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. /* @flow */
  2. import { withStyles } from '@material-ui/styles';
  3. import clsx from 'clsx';
  4. import React, { Component } from 'react';
  5. import { translate } from '../../../base/i18n';
  6. import { Icon, IconVolume } from '../../../base/icons';
  7. import { VOLUME_SLIDER_SCALE } from '../../constants';
  8. /**
  9. * The type of the React {@code Component} props of {@link VolumeSlider}.
  10. */
  11. type Props = {
  12. /**
  13. * An object containing the CSS classes.
  14. */
  15. classes: Object,
  16. /**
  17. * The value of the audio slider should display at when the component first
  18. * mounts. Changes will be stored in state. The value should be a number
  19. * between 0 and 1.
  20. */
  21. initialValue: number,
  22. /**
  23. * The callback to invoke when the audio slider value changes.
  24. */
  25. onChange: Function,
  26. /**
  27. * Invoked to obtain translated strings.
  28. */
  29. t: Function
  30. };
  31. /**
  32. * The type of the React {@code Component} state of {@link VolumeSlider}.
  33. */
  34. type State = {
  35. /**
  36. * The volume of the participant's audio element. The value will
  37. * be represented by a slider.
  38. */
  39. volumeLevel: number
  40. };
  41. const styles = theme => {
  42. return {
  43. container: {
  44. minHeight: '40px',
  45. minWidth: '180px',
  46. width: '100%',
  47. boxSizing: 'border-box',
  48. cursor: 'pointer',
  49. display: 'flex',
  50. alignItems: 'center',
  51. padding: '0 5px',
  52. '&:hover': {
  53. backgroundColor: theme.palette.ui04
  54. }
  55. },
  56. icon: {
  57. minWidth: '20px',
  58. padding: '5px',
  59. position: 'relative'
  60. },
  61. sliderContainer: {
  62. position: 'relative',
  63. width: '100%',
  64. paddingRight: '5px'
  65. },
  66. slider: {
  67. position: 'absolute',
  68. width: '100%',
  69. top: '50%',
  70. transform: 'translate(0, -50%)'
  71. }
  72. };
  73. };
  74. /**
  75. * Implements a React {@link Component} which displays an input slider for
  76. * adjusting the local volume of a remote participant.
  77. *
  78. * @augments Component
  79. */
  80. class VolumeSlider extends Component<Props, State> {
  81. /**
  82. * Initializes a new {@code VolumeSlider} instance.
  83. *
  84. * @param {Object} props - The read-only properties with which the new
  85. * instance is to be initialized.
  86. */
  87. constructor(props: Props) {
  88. super(props);
  89. this.state = {
  90. volumeLevel: (props.initialValue || 0) * VOLUME_SLIDER_SCALE
  91. };
  92. // Bind event handlers so they are only bound once for every instance.
  93. this._onVolumeChange = this._onVolumeChange.bind(this);
  94. }
  95. /**
  96. * Click handler.
  97. *
  98. * @param {MouseEvent} e - Click event.
  99. * @returns {void}
  100. */
  101. _onClick(e) {
  102. e.stopPropagation();
  103. }
  104. /**
  105. * Implements React's {@link Component#render()}.
  106. *
  107. * @inheritdoc
  108. * @returns {ReactElement}
  109. */
  110. render() {
  111. const { classes } = this.props;
  112. return (
  113. <div
  114. aria-label = { this.props.t('volumeSlider') }
  115. className = { clsx('popupmenu__contents', classes.container) }
  116. onClick = { this._onClick }>
  117. <span className = { classes.icon }>
  118. <Icon
  119. size = { 22 }
  120. src = { IconVolume } />
  121. </span>
  122. <div className = { classes.sliderContainer }>
  123. <input
  124. aria-valuemax = { VOLUME_SLIDER_SCALE }
  125. aria-valuemin = { 0 }
  126. aria-valuenow = { this.state.volumeLevel }
  127. className = { clsx('popupmenu__volume-slider', classes.slider) }
  128. max = { VOLUME_SLIDER_SCALE }
  129. min = { 0 }
  130. onChange = { this._onVolumeChange }
  131. tabIndex = { 0 }
  132. type = 'range'
  133. value = { this.state.volumeLevel } />
  134. </div>
  135. </div>
  136. );
  137. }
  138. _onVolumeChange: (Object) => void;
  139. /**
  140. * Sets the internal state of the volume level for the volume slider.
  141. * Invokes the prop onVolumeChange to notify of volume changes.
  142. *
  143. * @param {Object} event - DOM Event for slider change.
  144. * @private
  145. * @returns {void}
  146. */
  147. _onVolumeChange(event) {
  148. const volumeLevel = event.currentTarget.value;
  149. this.props.onChange(volumeLevel / VOLUME_SLIDER_SCALE);
  150. this.setState({ volumeLevel });
  151. }
  152. }
  153. export default translate(withStyles(styles)(VolumeSlider));