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.

Labels.js 5.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. // @flow
  2. import React, { Component } from 'react';
  3. import { TouchableOpacity, View } from 'react-native';
  4. import { JitsiRecordingConstants } from '../../../base/lib-jitsi-meet';
  5. import { RecordingLabel, RecordingExpandedLabel } from '../../../recording';
  6. import { TranscribingExpandedLabel, TranscribingLabel } from '../../../transcribing';
  7. import { VideoQualityExpandedLabel, VideoQualityLabel } from '../../../video-quality';
  8. import InsecureRoomNameExpandedLabel from './InsecureRoomNameExpandedLabel';
  9. import styles from './styles';
  10. import { InsecureRoomNameLabel } from '.';
  11. type Props = {}
  12. type State = {
  13. /**
  14. * String to show which {@code ExpandedLabel} to be shown. (Equals to the
  15. * label IDs below.)
  16. */
  17. visibleExpandedLabel: ?string
  18. }
  19. const LABEL_ID_QUALITY = 'quality';
  20. const LABEL_ID_RECORDING = 'recording';
  21. const LABEL_ID_STREAMING = 'streaming';
  22. const LABEL_ID_TRANSCRIBING = 'transcribing';
  23. const LABEL_ID_INSECURE_ROOM_NAME = 'insecure-room-name';
  24. const LabelHitSlop = {
  25. top: 10,
  26. bottom: 10,
  27. left: 0,
  28. right: 0
  29. };
  30. /**
  31. * The {@code ExpandedLabel} components to be rendered for the individual
  32. * {@code Label}s.
  33. */
  34. const EXPANDED_LABELS = {
  35. [LABEL_ID_QUALITY]: VideoQualityExpandedLabel,
  36. [LABEL_ID_RECORDING]: {
  37. component: RecordingExpandedLabel,
  38. props: {
  39. mode: JitsiRecordingConstants.mode.FILE
  40. }
  41. },
  42. [LABEL_ID_STREAMING]: {
  43. component: RecordingExpandedLabel,
  44. props: {
  45. mode: JitsiRecordingConstants.mode.STREAM
  46. }
  47. },
  48. [LABEL_ID_TRANSCRIBING]: TranscribingExpandedLabel,
  49. [LABEL_ID_INSECURE_ROOM_NAME]: InsecureRoomNameExpandedLabel
  50. };
  51. /**
  52. * Timeout to hide the {@ExpandedLabel}.
  53. */
  54. const EXPANDED_LABEL_TIMEOUT = 5000;
  55. /**
  56. * A container that renders the conference indicators, if any.
  57. */
  58. class Labels extends Component<Props, State> {
  59. /**
  60. * Timeout for the expanded labels to disappear.
  61. */
  62. expandedLabelTimeout: TimeoutID;
  63. /**
  64. * Instantiates a new instance of {@code Labels}.
  65. *
  66. * @inheritdoc
  67. */
  68. constructor(props: Props) {
  69. super(props);
  70. this.state = {
  71. visibleExpandedLabel: undefined
  72. };
  73. }
  74. /**
  75. * Implements React {@code Component}'s componentWillUnmount.
  76. *
  77. * @inheritdoc
  78. */
  79. componentWillUnmount() {
  80. clearTimeout(this.expandedLabelTimeout);
  81. }
  82. /**
  83. * Implements React {@code Component}'s render.
  84. *
  85. * @inheritdoc
  86. */
  87. render() {
  88. return (
  89. <>
  90. <View pointerEvents = 'box-none'>
  91. <View
  92. pointerEvents = 'box-none'
  93. style = { styles.indicatorContainer }>
  94. <TouchableOpacity
  95. hitSlop = { LabelHitSlop }
  96. onPress = { this._createOnPress(LABEL_ID_RECORDING) } >
  97. <RecordingLabel mode = { JitsiRecordingConstants.mode.FILE } />
  98. </TouchableOpacity>
  99. <TouchableOpacity
  100. hitSlop = { LabelHitSlop }
  101. onPress = { this._createOnPress(LABEL_ID_STREAMING) } >
  102. <RecordingLabel mode = { JitsiRecordingConstants.mode.STREAM } />
  103. </TouchableOpacity>
  104. <TouchableOpacity
  105. hitSlop = { LabelHitSlop }
  106. onPress = {
  107. this._createOnPress(LABEL_ID_TRANSCRIBING)
  108. } >
  109. <TranscribingLabel />
  110. </TouchableOpacity>
  111. <TouchableOpacity
  112. hitSlop = { LabelHitSlop }
  113. onPress = {
  114. this._createOnPress(LABEL_ID_INSECURE_ROOM_NAME)
  115. } >
  116. <InsecureRoomNameLabel />
  117. </TouchableOpacity>
  118. <TouchableOpacity
  119. hitSlop = { LabelHitSlop }
  120. onPress = {
  121. this._createOnPress(LABEL_ID_QUALITY) } >
  122. <VideoQualityLabel />
  123. </TouchableOpacity>
  124. </View>
  125. </View>
  126. { this._renderExpandedLabel() }
  127. </>
  128. );
  129. }
  130. /**
  131. * Creates a function to be invoked when the onPress of the touchables are
  132. * triggered.
  133. *
  134. * @param {string} label - The identifier of the label that's onLayout is
  135. * triggered.
  136. * @returns {Function}
  137. */
  138. _createOnPress(label) {
  139. return () => {
  140. let { visibleExpandedLabel } = this.state;
  141. visibleExpandedLabel
  142. = visibleExpandedLabel === label ? undefined : label;
  143. clearTimeout(this.expandedLabelTimeout);
  144. this.setState({
  145. visibleExpandedLabel
  146. });
  147. if (visibleExpandedLabel) {
  148. this.expandedLabelTimeout = setTimeout(() => {
  149. this.setState({
  150. visibleExpandedLabel: undefined
  151. });
  152. }, EXPANDED_LABEL_TIMEOUT);
  153. }
  154. };
  155. }
  156. /**
  157. * Rendes the expanded (explaining) label for the label that was touched.
  158. *
  159. * @returns {React$Element}
  160. */
  161. _renderExpandedLabel() {
  162. const { visibleExpandedLabel } = this.state;
  163. if (visibleExpandedLabel) {
  164. const expandedLabel = EXPANDED_LABELS[visibleExpandedLabel];
  165. if (expandedLabel) {
  166. const LabelComponent = expandedLabel.component || expandedLabel;
  167. const { props } = expandedLabel || {};
  168. return <LabelComponent { ...props } />;
  169. }
  170. }
  171. return null;
  172. }
  173. }
  174. export default Labels;