您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

functions.js 5.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. // @flow
  2. import _ from 'lodash';
  3. import {
  4. getParticipantById,
  5. PARTICIPANT_ROLE
  6. } from '../base/participants';
  7. import { objectSort } from '../base/util';
  8. /**
  9. * Checks if the speaker stats search is disabled.
  10. *
  11. * @param {*} state - The redux state.
  12. * @returns {boolean} - True if the speaker stats search is disabled and false otherwise.
  13. */
  14. export function isSpeakerStatsSearchDisabled(state: Object) {
  15. return state['features/base/config']?.disableSpeakerStatsSearch;
  16. }
  17. /**
  18. * Gets whether participants in speaker stats should be ordered or not, and with what priority.
  19. *
  20. * @param {*} state - The redux state.
  21. * @returns {Array<string>} - The speaker stats order array or an empty array.
  22. */
  23. export function getSpeakerStatsOrder(state: Object) {
  24. return state['features/base/config']?.speakerStatsOrder ?? [
  25. 'role',
  26. 'name',
  27. 'hasLeft'
  28. ];
  29. }
  30. /**
  31. * Gets speaker stats.
  32. *
  33. * @param {*} state - The redux state.
  34. * @returns {Object} - The speaker stats.
  35. */
  36. export function getSpeakerStats(state: Object) {
  37. return state['features/speaker-stats']?.stats ?? {};
  38. }
  39. /**
  40. * Gets speaker stats search criteria.
  41. *
  42. * @param {*} state - The redux state.
  43. * @returns {string | null} - The search criteria.
  44. */
  45. export function getSearchCriteria(state: Object) {
  46. return state['features/speaker-stats']?.criteria;
  47. }
  48. /**
  49. * Gets if speaker stats reorder is pending.
  50. *
  51. * @param {*} state - The redux state.
  52. * @returns {boolean} - The pending reorder flag.
  53. */
  54. export function getPendingReorder(state: Object) {
  55. return state['features/speaker-stats']?.pendingReorder ?? false;
  56. }
  57. /**
  58. * Get sorted speaker stats based on a configuration setting.
  59. *
  60. * @param {Object} state - The redux state.
  61. * @param {Object} stats - The current speaker stats.
  62. * @returns {Object} - Ordered speaker stats.
  63. * @public
  64. */
  65. export function getSortedSpeakerStats(state: Object, stats: Object) {
  66. const orderConfig = getSpeakerStatsOrder(state);
  67. if (orderConfig) {
  68. const enhancedStats = getEnhancedStatsForOrdering(state, stats, orderConfig);
  69. const sortedStats = objectSort(enhancedStats, (currentParticipant, nextParticipant) => {
  70. if (orderConfig.includes('hasLeft')) {
  71. if (nextParticipant.hasLeft() && !currentParticipant.hasLeft()) {
  72. return -1;
  73. } else if (currentParticipant.hasLeft() && !nextParticipant.hasLeft()) {
  74. return 1;
  75. }
  76. }
  77. let result;
  78. for (const sortCriteria of orderConfig) {
  79. switch (sortCriteria) {
  80. case 'role':
  81. if (!nextParticipant.isModerator && currentParticipant.isModerator) {
  82. result = -1;
  83. } else if (!currentParticipant.isModerator && nextParticipant.isModerator) {
  84. result = 1;
  85. } else {
  86. result = 0;
  87. }
  88. break;
  89. case 'name':
  90. result = (currentParticipant.displayName || '').localeCompare(
  91. nextParticipant.displayName || ''
  92. );
  93. break;
  94. }
  95. if (result !== 0) {
  96. break;
  97. }
  98. }
  99. return result;
  100. });
  101. return sortedStats;
  102. }
  103. }
  104. /**
  105. * Enhance speaker stats to include data needed for ordering.
  106. *
  107. * @param {Object} state - The redux state.
  108. * @param {Object} stats - Speaker stats.
  109. * @param {Array<string>} orderConfig - Ordering configuration.
  110. * @returns {Object} - Enhanced speaker stats.
  111. * @public
  112. */
  113. function getEnhancedStatsForOrdering(state, stats, orderConfig) {
  114. if (!orderConfig) {
  115. return stats;
  116. }
  117. for (const id in stats) {
  118. if (stats[id].hasOwnProperty('_hasLeft') && !stats[id].hasLeft()) {
  119. if (orderConfig.includes('role')) {
  120. const participant = getParticipantById(state, stats[id].getUserId());
  121. stats[id].isModerator = participant && participant.role === PARTICIPANT_ROLE.MODERATOR;
  122. }
  123. }
  124. }
  125. return stats;
  126. }
  127. /**
  128. * Filter stats by search criteria.
  129. *
  130. * @param {Object} state - The redux state.
  131. * @param {Object | undefined} stats - The unfiltered stats.
  132. *
  133. * @returns {Object} - Filtered speaker stats.
  134. * @public
  135. */
  136. export function filterBySearchCriteria(state: Object, stats: ?Object) {
  137. const filteredStats = _.cloneDeep(stats ?? getSpeakerStats(state));
  138. const criteria = getSearchCriteria(state);
  139. if (criteria !== null) {
  140. const searchRegex = new RegExp(criteria, 'gi');
  141. for (const id in filteredStats) {
  142. if (filteredStats[id].hasOwnProperty('_isLocalStats')) {
  143. const name = filteredStats[id].getDisplayName();
  144. filteredStats[id].hidden = !name || !name.match(searchRegex);
  145. }
  146. }
  147. }
  148. return filteredStats;
  149. }
  150. /**
  151. * Reset the hidden speaker stats.
  152. *
  153. * @param {Object} state - The redux state.
  154. * @param {Object | undefined} stats - The unfiltered stats.
  155. *
  156. * @returns {Object} - Speaker stats.
  157. * @public
  158. */
  159. export function resetHiddenStats(state: Object, stats: ?Object) {
  160. const resetStats = _.cloneDeep(stats ?? getSpeakerStats(state));
  161. for (const id in resetStats) {
  162. if (resetStats[id].hidden) {
  163. resetStats[id].hidden = false;
  164. }
  165. }
  166. return resetStats;
  167. }