Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

SpeakerStats.js 4.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. // @flow
  2. import React, { Component } from 'react';
  3. import { Dialog } from '../../base/dialog';
  4. import { translate } from '../../base/i18n';
  5. import { getLocalParticipant } from '../../base/participants';
  6. import { connect } from '../../base/redux';
  7. import SpeakerStatsItem from './SpeakerStatsItem';
  8. import SpeakerStatsLabels from './SpeakerStatsLabels';
  9. declare var interfaceConfig: Object;
  10. /**
  11. * The type of the React {@code Component} props of {@link SpeakerStats}.
  12. */
  13. type Props = {
  14. /**
  15. * The display name for the local participant obtained from the redux store.
  16. */
  17. _localDisplayName: string,
  18. /**
  19. * The JitsiConference from which stats will be pulled.
  20. */
  21. conference: Object,
  22. /**
  23. * The function to translate human-readable text.
  24. */
  25. t: Function
  26. };
  27. /**
  28. * The type of the React {@code Component} state of {@link SpeakerStats}.
  29. */
  30. type State = {
  31. /**
  32. * The stats summary provided by the JitsiConference.
  33. */
  34. stats: Object
  35. };
  36. /**
  37. * React component for displaying a list of speaker stats.
  38. *
  39. * @extends Component
  40. */
  41. class SpeakerStats extends Component<Props, State> {
  42. _updateInterval: IntervalID;
  43. /**
  44. * Initializes a new SpeakerStats instance.
  45. *
  46. * @param {Object} props - The read-only React Component props with which
  47. * the new instance is to be initialized.
  48. */
  49. constructor(props) {
  50. super(props);
  51. this.state = {
  52. stats: this.props.conference.getSpeakerStats()
  53. };
  54. // Bind event handlers so they are only bound once per instance.
  55. this._updateStats = this._updateStats.bind(this);
  56. }
  57. /**
  58. * Begin polling for speaker stats updates.
  59. *
  60. * @inheritdoc
  61. */
  62. componentDidMount() {
  63. this._updateInterval = setInterval(this._updateStats, 1000);
  64. }
  65. /**
  66. * Stop polling for speaker stats updates.
  67. *
  68. * @inheritdoc
  69. * @returns {void}
  70. */
  71. componentWillUnmount() {
  72. clearInterval(this._updateInterval);
  73. }
  74. /**
  75. * Implements React's {@link Component#render()}.
  76. *
  77. * @inheritdoc
  78. * @returns {ReactElement}
  79. */
  80. render() {
  81. const userIds = Object.keys(this.state.stats);
  82. const items = userIds.map(userId => this._createStatsItem(userId));
  83. return (
  84. <Dialog
  85. cancelKey = { 'dialog.close' }
  86. submitDisabled = { true }
  87. titleKey = 'speakerStats.speakerStats'>
  88. <div className = 'speaker-stats'>
  89. <SpeakerStatsLabels />
  90. { items }
  91. </div>
  92. </Dialog>
  93. );
  94. }
  95. /**
  96. * Create a SpeakerStatsItem instance for the passed in user id.
  97. *
  98. * @param {string} userId - User id used to look up the associated
  99. * speaker stats from the jitsi library.
  100. * @returns {SpeakerStatsItem|null}
  101. * @private
  102. */
  103. _createStatsItem(userId) {
  104. const statsModel = this.state.stats[userId];
  105. if (!statsModel) {
  106. return null;
  107. }
  108. const isDominantSpeaker = statsModel.isDominantSpeaker();
  109. const dominantSpeakerTime = statsModel.getTotalDominantSpeakerTime();
  110. const hasLeft = statsModel.hasLeft();
  111. let displayName;
  112. if (statsModel.isLocalStats()) {
  113. const { t } = this.props;
  114. const meString = t('me');
  115. displayName = this.props._localDisplayName;
  116. displayName
  117. = displayName ? `${displayName} (${meString})` : meString;
  118. } else {
  119. displayName
  120. = this.state.stats[userId].getDisplayName()
  121. || interfaceConfig.DEFAULT_REMOTE_DISPLAY_NAME;
  122. }
  123. return (
  124. <SpeakerStatsItem
  125. displayName = { displayName }
  126. dominantSpeakerTime = { dominantSpeakerTime }
  127. hasLeft = { hasLeft }
  128. isDominantSpeaker = { isDominantSpeaker }
  129. key = { userId } />
  130. );
  131. }
  132. _updateStats: () => void;
  133. /**
  134. * Update the internal state with the latest speaker stats.
  135. *
  136. * @returns {void}
  137. * @private
  138. */
  139. _updateStats() {
  140. const stats = this.props.conference.getSpeakerStats();
  141. this.setState({ stats });
  142. }
  143. }
  144. /**
  145. * Maps (parts of) the redux state to the associated SpeakerStats's props.
  146. *
  147. * @param {Object} state - The redux state.
  148. * @private
  149. * @returns {{
  150. * _localDisplayName: ?string
  151. * }}
  152. */
  153. function _mapStateToProps(state) {
  154. const localParticipant = getLocalParticipant(state);
  155. return {
  156. /**
  157. * The local display name.
  158. *
  159. * @private
  160. * @type {string|undefined}
  161. */
  162. _localDisplayName: localParticipant && localParticipant.name
  163. };
  164. }
  165. export default translate(connect(_mapStateToProps)(SpeakerStats));