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.

MicrophoneButton.tsx 3.2KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. import React, { useCallback, useState } from 'react';
  2. import { TouchableOpacity, View, ViewStyle } from 'react-native';
  3. import { useDispatch, useSelector } from 'react-redux';
  4. import {
  5. ACTION_SHORTCUT_PRESSED as PRESSED,
  6. ACTION_SHORTCUT_RELEASED as RELEASED,
  7. createShortcutEvent
  8. } from '../../../../analytics/AnalyticsEvents';
  9. import { sendAnalytics } from '../../../../analytics/functions';
  10. import { IReduxState } from '../../../../app/types';
  11. import { AUDIO_MUTE_BUTTON_ENABLED } from '../../../../base/flags/constants';
  12. import { getFeatureFlag } from '../../../../base/flags/functions';
  13. import Icon from '../../../../base/icons/components/Icon';
  14. import { IconMic, IconMicSlash } from '../../../../base/icons/svg';
  15. import { MEDIA_TYPE } from '../../../../base/media/constants';
  16. import { isLocalTrackMuted } from '../../../../base/tracks/functions';
  17. import { isAudioMuteButtonDisabled } from '../../../../toolbox/functions.any';
  18. import { muteLocal } from '../../../../video-menu/actions';
  19. import styles from './styles';
  20. const LONG_PRESS = 'long.press';
  21. /**
  22. * Implements a round audio mute/unmute button of a custom size.
  23. *
  24. * @returns {JSX.Element} - The audio mute round button.
  25. */
  26. const MicrophoneButton = (): JSX.Element | null => {
  27. const dispatch = useDispatch();
  28. const audioMuted = useSelector((state: IReduxState) => isLocalTrackMuted(state['features/base/tracks'],
  29. MEDIA_TYPE.AUDIO));
  30. const disabled = useSelector(isAudioMuteButtonDisabled);
  31. const enabledFlag = useSelector((state: IReduxState) => getFeatureFlag(state, AUDIO_MUTE_BUTTON_ENABLED, true));
  32. const [ longPress, setLongPress ] = useState(false);
  33. if (!enabledFlag) {
  34. return null;
  35. }
  36. const onPressIn = useCallback(() => {
  37. !disabled && dispatch(muteLocal(!audioMuted, MEDIA_TYPE.AUDIO));
  38. }, [ audioMuted, disabled ]);
  39. const onLongPress = useCallback(() => {
  40. if (!disabled && !audioMuted) {
  41. sendAnalytics(createShortcutEvent(
  42. 'push.to.talk',
  43. PRESSED,
  44. {},
  45. LONG_PRESS));
  46. setLongPress(true);
  47. }
  48. }, [ audioMuted, disabled, setLongPress ]);
  49. const onPressOut = useCallback(() => {
  50. if (longPress) {
  51. setLongPress(false);
  52. sendAnalytics(createShortcutEvent(
  53. 'push.to.talk',
  54. RELEASED,
  55. {},
  56. LONG_PRESS
  57. ));
  58. dispatch(muteLocal(true, MEDIA_TYPE.AUDIO));
  59. }
  60. }, [ longPress, setLongPress ]);
  61. return (
  62. <TouchableOpacity
  63. onLongPress = { onLongPress }
  64. onPressIn = { onPressIn }
  65. onPressOut = { onPressOut } >
  66. <View
  67. style = { [
  68. styles.microphoneStyles.container,
  69. !audioMuted && styles.microphoneStyles.unmuted
  70. ] as ViewStyle[] }>
  71. <View
  72. style = { styles.microphoneStyles.iconContainer as ViewStyle }>
  73. <Icon
  74. src = { audioMuted ? IconMicSlash : IconMic }
  75. style = { styles.microphoneStyles.icon } />
  76. </View>
  77. </View>
  78. </TouchableOpacity>
  79. );
  80. };
  81. export default MicrophoneButton;