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.

ConferenceInfo.tsx 6.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. /* eslint-disable react/no-multi-comp */
  2. import React, { Component } from 'react';
  3. import { connect } from 'react-redux';
  4. import { IReduxState, IStore } from '../../../app/types';
  5. import { JitsiRecordingConstants } from '../../../base/lib-jitsi-meet';
  6. import E2EELabel from '../../../e2ee/components/E2EELabel';
  7. import HighlightButton from '../../../recording/components/Recording/web/HighlightButton';
  8. import RecordingLabel from '../../../recording/components/web/RecordingLabel';
  9. import { showToolbox } from '../../../toolbox/actions.web';
  10. import { isToolboxVisible } from '../../../toolbox/functions.web';
  11. import TranscribingLabel from '../../../transcribing/components/TranscribingLabel.web';
  12. import VideoQualityLabel from '../../../video-quality/components/VideoQualityLabel.web';
  13. import VisitorsCountLabel from '../../../visitors/components/web/VisitorsCountLabel';
  14. import ConferenceTimer from '../ConferenceTimer';
  15. import { getConferenceInfo } from '../functions.web';
  16. import ConferenceInfoContainer from './ConferenceInfoContainer';
  17. import InsecureRoomNameLabel from './InsecureRoomNameLabel';
  18. import RaisedHandsCountLabel from './RaisedHandsCountLabel';
  19. import SpeakerStatsLabel from './SpeakerStatsLabel';
  20. import SubjectText from './SubjectText';
  21. import ToggleTopPanelLabel from './ToggleTopPanelLabel';
  22. /**
  23. * The type of the React {@code Component} props of {@link Subject}.
  24. */
  25. interface IProps {
  26. /**
  27. * The conference info labels to be shown in the conference header.
  28. */
  29. _conferenceInfo: {
  30. alwaysVisible?: string[];
  31. autoHide?: string[];
  32. };
  33. /**
  34. * Indicates whether the component should be visible or not.
  35. */
  36. _visible: boolean;
  37. /**
  38. * Invoked to active other features of the app.
  39. */
  40. dispatch: IStore['dispatch'];
  41. }
  42. const COMPONENTS: Array<{
  43. Component: React.ComponentType<any>;
  44. id: string;
  45. }> = [
  46. {
  47. Component: HighlightButton,
  48. id: 'highlight-moment'
  49. },
  50. {
  51. Component: SubjectText,
  52. id: 'subject'
  53. },
  54. {
  55. Component: ConferenceTimer,
  56. id: 'conference-timer'
  57. },
  58. {
  59. Component: SpeakerStatsLabel,
  60. id: 'participants-count'
  61. },
  62. {
  63. Component: E2EELabel,
  64. id: 'e2ee'
  65. },
  66. {
  67. Component: () => (
  68. <>
  69. <RecordingLabel mode = { JitsiRecordingConstants.mode.FILE } />
  70. <RecordingLabel mode = { JitsiRecordingConstants.mode.STREAM } />
  71. </>
  72. ),
  73. id: 'recording'
  74. },
  75. {
  76. Component: RaisedHandsCountLabel,
  77. id: 'raised-hands-count'
  78. },
  79. {
  80. Component: TranscribingLabel,
  81. id: 'transcribing'
  82. },
  83. {
  84. Component: VideoQualityLabel,
  85. id: 'video-quality'
  86. },
  87. {
  88. Component: VisitorsCountLabel,
  89. id: 'visitors-count'
  90. },
  91. {
  92. Component: InsecureRoomNameLabel,
  93. id: 'insecure-room'
  94. },
  95. {
  96. Component: ToggleTopPanelLabel,
  97. id: 'top-panel-toggle'
  98. }
  99. ];
  100. /**
  101. * The upper band of the meeing containing the conference name, timer and labels.
  102. *
  103. * @param {Object} props - The props of the component.
  104. * @returns {React$None}
  105. */
  106. class ConferenceInfo extends Component<IProps> {
  107. /**
  108. * Initializes a new {@code ConferenceInfo} instance.
  109. *
  110. * @param {IProps} props - The read-only React {@code Component} props with
  111. * which the new instance is to be initialized.
  112. */
  113. constructor(props: IProps) {
  114. super(props);
  115. this._renderAutoHide = this._renderAutoHide.bind(this);
  116. this._renderAlwaysVisible = this._renderAlwaysVisible.bind(this);
  117. this._onTabIn = this._onTabIn.bind(this);
  118. }
  119. /**
  120. * Callback invoked when the component is focused to show the conference
  121. * info if necessary.
  122. *
  123. * @returns {void}
  124. */
  125. _onTabIn() {
  126. if (this.props._conferenceInfo.autoHide?.length && !this.props._visible) {
  127. this.props.dispatch(showToolbox());
  128. }
  129. }
  130. /**
  131. * Renders auto-hidden info header labels.
  132. *
  133. * @returns {void}
  134. */
  135. _renderAutoHide() {
  136. const { autoHide } = this.props._conferenceInfo;
  137. if (!autoHide?.length) {
  138. return null;
  139. }
  140. return (
  141. <ConferenceInfoContainer
  142. id = 'autoHide'
  143. visible = { this.props._visible }>
  144. {
  145. COMPONENTS
  146. .filter(comp => autoHide.includes(comp.id))
  147. .map(c =>
  148. <c.Component key = { c.id } />
  149. )
  150. }
  151. </ConferenceInfoContainer>
  152. );
  153. }
  154. /**
  155. * Renders the always visible info header labels.
  156. *
  157. * @returns {void}
  158. */
  159. _renderAlwaysVisible() {
  160. const { alwaysVisible } = this.props._conferenceInfo;
  161. if (!alwaysVisible?.length) {
  162. return null;
  163. }
  164. return (
  165. <ConferenceInfoContainer
  166. id = 'alwaysVisible'
  167. visible = { true } >
  168. {
  169. COMPONENTS
  170. .filter(comp => alwaysVisible.includes(comp.id))
  171. .map(c =>
  172. <c.Component key = { c.id } />
  173. )
  174. }
  175. </ConferenceInfoContainer>
  176. );
  177. }
  178. /**
  179. * Implements React's {@link Component#render()}.
  180. *
  181. * @inheritdoc
  182. * @returns {ReactElement}
  183. */
  184. render() {
  185. return (
  186. <div
  187. className = 'details-container'
  188. onFocus = { this._onTabIn }>
  189. { this._renderAlwaysVisible() }
  190. { this._renderAutoHide() }
  191. </div>
  192. );
  193. }
  194. }
  195. /**
  196. * Maps (parts of) the Redux state to the associated
  197. * {@code Subject}'s props.
  198. *
  199. * @param {Object} state - The Redux state.
  200. * @private
  201. * @returns {{
  202. * _visible: boolean,
  203. * _conferenceInfo: Object
  204. * }}
  205. */
  206. function _mapStateToProps(state: IReduxState) {
  207. return {
  208. _visible: isToolboxVisible(state),
  209. _conferenceInfo: getConferenceInfo(state)
  210. };
  211. }
  212. export default connect(_mapStateToProps)(ConferenceInfo);