您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

AudioMuteButton.js 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. // @flow
  2. import React, { Component } from 'react';
  3. // We need to reference these files directly to avoid loading things that are not available
  4. // in this environment (e.g. JitsiMeetJS or interfaceConfig)
  5. import { IconMicrophoneEmpty, IconMicrophoneEmptySlash } from '../base/icons';
  6. import type { Props } from '../base/toolbox/components/AbstractButton';
  7. import ToolbarButton from './ToolbarButton';
  8. const { api } = window.alwaysOnTop;
  9. /**
  10. * The type of the React {@code Component} state of {@link AudioMuteButton}.
  11. */
  12. type State = {
  13. /**
  14. * Whether audio is available is not.
  15. */
  16. audioAvailable: boolean,
  17. /**
  18. * Whether audio is muted or not.
  19. */
  20. audioMuted: boolean
  21. };
  22. /**
  23. * Stateless "mute/unmute audio" button for the Always-on-Top windows.
  24. */
  25. export default class AudioMuteButton extends Component<Props, State> {
  26. icon = IconMicrophoneEmpty;
  27. toggledIcon = IconMicrophoneEmptySlash;
  28. accessibilityLabel = 'Audio mute';
  29. /**
  30. * Initializes a new {@code AudioMuteButton} instance.
  31. *
  32. * @param {Props} props - The React {@code Component} props to initialize
  33. * the new {@code AudioMuteButton} instance with.
  34. */
  35. constructor(props: Props) {
  36. super(props);
  37. this.state = {
  38. audioAvailable: false,
  39. audioMuted: true
  40. };
  41. // Bind event handlers so they are only bound once per instance.
  42. this._audioAvailabilityListener
  43. = this._audioAvailabilityListener.bind(this);
  44. this._audioMutedListener = this._audioMutedListener.bind(this);
  45. this._onClick = this._onClick.bind(this);
  46. }
  47. /**
  48. * Sets mouse move listener and initial toolbar timeout.
  49. *
  50. * @inheritdoc
  51. * @returns {void}
  52. */
  53. componentDidMount() {
  54. api.on('audioAvailabilityChanged', this._audioAvailabilityListener);
  55. api.on('audioMuteStatusChanged', this._audioMutedListener);
  56. Promise.all([
  57. api.isAudioAvailable(),
  58. api.isAudioMuted()
  59. ])
  60. .then(([ audioAvailable, audioMuted ]) =>
  61. this.setState({
  62. audioAvailable,
  63. audioMuted
  64. }))
  65. .catch(console.error);
  66. }
  67. /**
  68. * Removes all listeners.
  69. *
  70. * @inheritdoc
  71. * @returns {void}
  72. */
  73. componentWillUnmount() {
  74. api.removeListener(
  75. 'audioAvailabilityChanged',
  76. this._audioAvailabilityListener);
  77. api.removeListener(
  78. 'audioMuteStatusChanged',
  79. this._audioMutedListener);
  80. }
  81. _audioAvailabilityListener: ({ available: boolean }) => void;
  82. /**
  83. * Handles audio available api events.
  84. *
  85. * @param {{ available: boolean }} status - The new available status.
  86. * @returns {void}
  87. */
  88. _audioAvailabilityListener({ available }) {
  89. this.setState({ audioAvailable: available });
  90. }
  91. _audioMutedListener: ({ muted: boolean }) => void;
  92. /**
  93. * Handles audio muted api events.
  94. *
  95. * @param {{ muted: boolean }} status - The new muted status.
  96. * @returns {void}
  97. */
  98. _audioMutedListener({ muted }) {
  99. this.setState({ audioMuted: muted });
  100. }
  101. /**
  102. * Indicates if audio is currently muted or not.
  103. *
  104. * @override
  105. * @protected
  106. * @returns {boolean}
  107. */
  108. _isAudioMuted() {
  109. return this.state.audioMuted;
  110. }
  111. /**
  112. * Indicates whether this button is disabled or not.
  113. *
  114. * @override
  115. * @protected
  116. * @returns {boolean}
  117. */
  118. _isDisabled() {
  119. return !this.state.audioAvailable;
  120. }
  121. /**
  122. * Changes the muted state.
  123. *
  124. * @override
  125. * @param {boolean} audioMuted - Whether audio should be muted or not.
  126. * @protected
  127. * @returns {void}
  128. */
  129. _setAudioMuted(audioMuted: boolean) { // eslint-disable-line no-unused-vars
  130. this.state.audioAvailable && api.executeCommand('toggleAudio');
  131. }
  132. _onClick: () => {};
  133. /**
  134. * Handles clicking / pressing the button, and toggles the audio mute state
  135. * accordingly.
  136. *
  137. * @returns {void}
  138. */
  139. _onClick() {
  140. this._setAudioMuted(!this._isAudioMuted());
  141. }
  142. /**
  143. * Implements React's {@link Component#render()}.
  144. *
  145. * @inheritdoc
  146. * @returns {ReactElement}
  147. */
  148. render() {
  149. const toggled = this._isAudioMuted();
  150. return (<ToolbarButton
  151. accessibilityLabel = { this.accessibilityLabel }
  152. disabled = { this._isDisabled() }
  153. icon = { toggled ? this.toggledIcon : this.icon }
  154. onClick = { this._onClick }
  155. toggled = { toggled } />);
  156. }
  157. }