You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

VolumeSlider.js 4.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. // @flow
  2. import _ from 'lodash';
  3. import React, { PureComponent } from 'react';
  4. import { View, Slider } from 'react-native';
  5. import { withTheme } from 'react-native-paper';
  6. import { translate } from '../../../base/i18n';
  7. import { Icon, IconVolumeEmpty } from '../../../base/icons';
  8. import {
  9. getLocalParticipant,
  10. getParticipantById
  11. } from '../../../base/participants';
  12. import { connect } from '../../../base/redux';
  13. import { setVolume } from '../../../participants-pane/actions.native';
  14. import { VOLUME_SLIDER_SCALE } from '../../constants';
  15. import styles from './styles';
  16. /**
  17. * The type of the React {@code Component} props of {@link VolumeSlider}.
  18. */
  19. type Props = {
  20. /**
  21. * Whether the participant enters the conference silent.
  22. */
  23. _startSilent: boolean,
  24. /**
  25. * The volume level for the participant.
  26. */
  27. _volume: number,
  28. /**
  29. * The redux dispatch function.
  30. */
  31. dispatch: Function,
  32. /**
  33. * Participant reference
  34. */
  35. participant: Object,
  36. /**
  37. * Theme used for styles.
  38. */
  39. theme: Object
  40. };
  41. /**
  42. * The type of the React {@code Component} state of {@link VolumeSlider}.
  43. */
  44. type State = {
  45. /**
  46. * The volume of the participant's audio element. The value will
  47. * be represented by a slider.
  48. */
  49. volumeLevel: number
  50. };
  51. /**
  52. * Component that renders the volume slider.
  53. *
  54. * @returns {React$Element<any>}
  55. */
  56. class VolumeSlider extends PureComponent<Props, State> {
  57. _onVolumeChange: Function;
  58. _originalVolumeChange: Function;
  59. /**
  60. * Initializes a new {@code VolumeSlider} instance.
  61. *
  62. * @param {Object} props - The read-only properties with which the new
  63. * instance is to be initialized.
  64. */
  65. constructor(props: Props) {
  66. super(props);
  67. this.state = {
  68. volumeLevel: props._volume || 0
  69. };
  70. this._originalVolumeChange = this._onVolumeChange;
  71. this._onVolumeChange = _.throttle(
  72. volumeLevel => this._originalVolumeChange(volumeLevel), 500
  73. );
  74. }
  75. /**
  76. * Implements React's {@link Component#render()}.
  77. *
  78. * @inheritdoc
  79. * @returns {ReactElement}
  80. */
  81. render() {
  82. const { _startSilent, theme } = this.props;
  83. const { volumeLevel } = this.state;
  84. const { palette } = theme;
  85. const onVolumeChange = _startSilent ? undefined : this._onVolumeChange;
  86. return (
  87. <View style = { styles.volumeSliderContainer } >
  88. <Icon
  89. size = { 20 }
  90. src = { IconVolumeEmpty }
  91. style = { styles.volumeIcon } />
  92. <Slider
  93. maximumTrackTintColor = { palette.field02 }
  94. maximumValue = { VOLUME_SLIDER_SCALE }
  95. minimumTrackTintColor = { palette.action01 }
  96. minimumValue = { 0 }
  97. onValueChange = { onVolumeChange }
  98. style = { styles.sliderContainer }
  99. thumbTintColor = { palette.field02 }
  100. value = { volumeLevel } />
  101. </View>
  102. );
  103. }
  104. /**
  105. * Sets the internal state of the volume level for the volume slider.
  106. * Invokes the prop onVolumeChange to notify of volume changes.
  107. *
  108. * @param {number} volumeLevel - Selected volume on slider.
  109. * @private
  110. * @returns {void}
  111. */
  112. _onVolumeChange(volumeLevel) {
  113. const { dispatch, participant } = this.props;
  114. const { id } = participant;
  115. dispatch(setVolume(id, volumeLevel));
  116. }
  117. }
  118. /**
  119. * Maps (parts of) the Redux state to the associated props for the
  120. * {@code VolumeSlider} component.
  121. *
  122. * @param {Object} state - The Redux state.
  123. * @param {Object} ownProps - The own props of the component.
  124. * @returns {Props}
  125. */
  126. function mapStateToProps(state, ownProps): Object {
  127. const { participant } = ownProps;
  128. const { startSilent } = state['features/base/config'];
  129. const { participantsVolume } = state['features/participants-pane'];
  130. const getParticipant = participant.id
  131. ? getParticipantById(state, participant.id) : getLocalParticipant(state);
  132. const { id } = getParticipant;
  133. return {
  134. _startSilent: Boolean(startSilent),
  135. _volume: participant.local ? undefined : participantsVolume[id]
  136. };
  137. }
  138. export default translate(connect(mapStateToProps)(withTheme(VolumeSlider)));