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.

VideoSettingsButton.js 2.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. // @flow
  2. import React, { Component } from 'react';
  3. import { toggleVideoSettings, VideoSettingsPopup } from '../../../settings';
  4. import VideoMuteButton from '../VideoMuteButton';
  5. import JitsiMeetJS from '../../../base/lib-jitsi-meet/_';
  6. import { hasAvailableDevices } from '../../../base/devices';
  7. import { IconArrowDown } from '../../../base/icons';
  8. import { connect } from '../../../base/redux';
  9. import { ToolboxButtonWithIcon } from '../../../base/toolbox';
  10. type Props = {
  11. /**
  12. * Click handler for the small icon. Opens video options.
  13. */
  14. onVideoOptionsClick: Function,
  15. /**
  16. * If the user has any video devices.
  17. */
  18. hasDevices: boolean,
  19. /**
  20. * Flag controlling the visibility of the button.
  21. */
  22. visible: boolean,
  23. };
  24. type State = {
  25. /**
  26. * Whether the app has video permissions or not.
  27. */
  28. hasPermissions: boolean,
  29. };
  30. /**
  31. * Button used for video & video settings.
  32. *
  33. * @returns {ReactElement}
  34. */
  35. class VideoSettingsButton extends Component<Props, State> {
  36. /**
  37. * Initializes a new {@code VideoSettingsButton} instance.
  38. *
  39. * @param {Object} props - The read-only properties with which the new
  40. * instance is to be initialized.
  41. */
  42. constructor(props) {
  43. super(props);
  44. this.state = {
  45. hasPermissions: false
  46. };
  47. }
  48. /**
  49. * Updates device permissions.
  50. *
  51. * @returns {Promise<void>}
  52. */
  53. async _updatePermissions() {
  54. const hasPermissions = await JitsiMeetJS.mediaDevices.isDevicePermissionGranted(
  55. 'video',
  56. );
  57. this.setState({
  58. hasPermissions
  59. });
  60. }
  61. /**
  62. * Implements React's {@link Component#componentDidMount}.
  63. *
  64. * @inheritdoc
  65. */
  66. componentDidMount() {
  67. this._updatePermissions();
  68. }
  69. /**
  70. * Implements React's {@link Component#render}.
  71. *
  72. * @inheritdoc
  73. */
  74. render() {
  75. const { hasDevices, onVideoOptionsClick, visible } = this.props;
  76. const iconDisabled = !this.state.hasPermissions || !hasDevices;
  77. return visible ? (
  78. <VideoSettingsPopup>
  79. <ToolboxButtonWithIcon
  80. icon = { IconArrowDown }
  81. iconDisabled = { iconDisabled }
  82. onIconClick = { onVideoOptionsClick }>
  83. <VideoMuteButton />
  84. </ToolboxButtonWithIcon>
  85. </VideoSettingsPopup>
  86. ) : null;
  87. }
  88. }
  89. /**
  90. * Function that maps parts of Redux state tree into component props.
  91. *
  92. * @param {Object} state - Redux state.
  93. * @returns {Object}
  94. */
  95. function mapStateToProps(state) {
  96. return {
  97. hasDevices: hasAvailableDevices(state, 'videoInput')
  98. };
  99. }
  100. const mapDispatchToProps = {
  101. onVideoOptionsClick: toggleVideoSettings
  102. };
  103. export default connect(
  104. mapStateToProps,
  105. mapDispatchToProps,
  106. )(VideoSettingsButton);