Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

VideoMuteButton.js 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. // @flow
  2. import { connect } from 'react-redux';
  3. import {
  4. ACTION_SHORTCUT_TRIGGERED,
  5. VIDEO_MUTE,
  6. createShortcutEvent,
  7. createToolbarEvent,
  8. sendAnalytics
  9. } from '../../analytics';
  10. import { translate } from '../../base/i18n';
  11. import {
  12. MEDIA_TYPE,
  13. VIDEO_MUTISM_AUTHORITY,
  14. setVideoMuted
  15. } from '../../base/media';
  16. import { AbstractVideoMuteButton } from '../../base/toolbox';
  17. import type { AbstractButtonProps } from '../../base/toolbox';
  18. import { isLocalTrackMuted } from '../../base/tracks';
  19. import UIEvents from '../../../../service/UI/UIEvents';
  20. declare var APP: Object;
  21. /**
  22. * The type of the React {@code Component} props of {@link VideoMuteButton}.
  23. */
  24. type Props = AbstractButtonProps & {
  25. /**
  26. * Whether the current conference is in audio only mode or not.
  27. */
  28. _audioOnly: boolean,
  29. /**
  30. * Whether video is currently muted or not.
  31. */
  32. _videoMuted: boolean,
  33. /**
  34. * The redux {@code dispatch} function.
  35. */
  36. dispatch: Function
  37. }
  38. /**
  39. * Component that renders a toolbar button for toggling video mute.
  40. *
  41. * @extends AbstractVideoMuteButton
  42. */
  43. class VideoMuteButton extends AbstractVideoMuteButton<Props, *> {
  44. label = 'toolbar.videomute';
  45. tooltip = 'toolbar.videomute';
  46. /**
  47. * Initializes a new {@code VideoMuteButton} instance.
  48. *
  49. * @param {Props} props - The read-only React {@code Component} props with
  50. * which the new instance is to be initialized.
  51. */
  52. constructor(props: Props) {
  53. super(props);
  54. // Bind event handlers so they are only bound once per instance.
  55. this._onKeyboardShortcut = this._onKeyboardShortcut.bind(this);
  56. }
  57. /**
  58. * Registers the keyboard shortcut that toggles the video muting.
  59. *
  60. * @inheritdoc
  61. * @returns {void}
  62. */
  63. componentDidMount() {
  64. typeof APP === 'undefined'
  65. || APP.keyboardshortcut.registerShortcut(
  66. 'V',
  67. null,
  68. this._onKeyboardShortcut,
  69. 'keyboardShortcuts.videoMute');
  70. }
  71. /**
  72. * Unregisters the keyboard shortcut that toggles the video muting.
  73. *
  74. * @inheritdoc
  75. * @returns {void}
  76. */
  77. componentWillUnmount() {
  78. typeof APP === 'undefined'
  79. || APP.keyboardshortcut.unregisterShortcut('V');
  80. }
  81. /**
  82. * Indicates if this button should be disabled or not.
  83. *
  84. * @override
  85. * @protected
  86. * @returns {boolean}
  87. */
  88. _isDisabled() {
  89. return this.props._audioOnly;
  90. }
  91. /**
  92. * Indicates if video is currently muted ot nor.
  93. *
  94. * @override
  95. * @protected
  96. * @returns {boolean}
  97. */
  98. _isVideoMuted() {
  99. return this.props._videoMuted;
  100. }
  101. _onKeyboardShortcut: () => void;
  102. /**
  103. * Creates an analytics keyboard shortcut event and dispatches an action to
  104. * toggle the video muting.
  105. *
  106. * @private
  107. * @returns {void}
  108. */
  109. _onKeyboardShortcut() {
  110. sendAnalytics(
  111. createShortcutEvent(
  112. VIDEO_MUTE,
  113. ACTION_SHORTCUT_TRIGGERED,
  114. { enable: !this._isVideoMuted() }));
  115. super._handleClick();
  116. }
  117. /**
  118. * Changes the muted state.
  119. *
  120. * @override
  121. * @param {boolean} videoMuted - Whether video should be muted or not.
  122. * @protected
  123. * @returns {void}
  124. */
  125. _setVideoMuted(videoMuted: boolean) {
  126. sendAnalytics(createToolbarEvent(VIDEO_MUTE, { enable: videoMuted }));
  127. this.props.dispatch(
  128. setVideoMuted(
  129. videoMuted,
  130. VIDEO_MUTISM_AUTHORITY.USER,
  131. /* ensureTrack */ true));
  132. // FIXME: The old conference logic still relies on this event being
  133. // emitted.
  134. typeof APP === 'undefined'
  135. || APP.UI.emitEvent(UIEvents.VIDEO_MUTED, videoMuted, true);
  136. }
  137. }
  138. /**
  139. * Maps (parts of) the redux state to the associated props for the
  140. * {@code VideoMuteButton} component.
  141. *
  142. * @param {Object} state - The Redux state.
  143. * @private
  144. * @returns {{
  145. * _audioOnly: boolean,
  146. * _videoMuted: boolean
  147. * }}
  148. */
  149. function _mapStateToProps(state): Object {
  150. const { audioOnly } = state['features/base/conference'];
  151. const tracks = state['features/base/tracks'];
  152. return {
  153. _audioOnly: Boolean(audioOnly),
  154. _videoMuted: isLocalTrackMuted(tracks, MEDIA_TYPE.VIDEO)
  155. };
  156. }
  157. export default translate(connect(_mapStateToProps)(VideoMuteButton));