Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

AbstractSpeakerStatsList.ts 4.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. import { useCallback, useEffect, useRef } from 'react';
  2. import { useTranslation } from 'react-i18next';
  3. import { useDispatch, useSelector } from 'react-redux';
  4. import { IReduxState } from '../../app/types';
  5. import { getLocalParticipant } from '../../base/participants/functions';
  6. import { initUpdateStats } from '../actions.any';
  7. import {
  8. SPEAKER_STATS_RELOAD_INTERVAL
  9. } from '../constants';
  10. /**
  11. * Component that renders the list of speaker stats.
  12. *
  13. * @param {Function} speakerStatsItem - React element tu use when rendering.
  14. * @param {Object} itemStyles - Styles for the speaker stats item.
  15. * @returns {Function}
  16. */
  17. const abstractSpeakerStatsList = (speakerStatsItem: Function): Function[] => {
  18. const dispatch = useDispatch();
  19. const { t } = useTranslation();
  20. const { conference } = useSelector((state: IReduxState) => state['features/base/conference']);
  21. const {
  22. stats: speakerStats,
  23. showFaceExpressions,
  24. sortedSpeakerStatsIds
  25. } = useSelector((state: IReduxState) => state['features/speaker-stats']);
  26. const localParticipant = useSelector(getLocalParticipant);
  27. const { defaultRemoteDisplayName } = useSelector(
  28. (state: IReduxState) => state['features/base/config']) || {};
  29. const { faceLandmarks: faceLandmarksConfig } = useSelector((state: IReduxState) =>
  30. state['features/base/config']) || {};
  31. const { faceLandmarks } = useSelector((state: IReduxState) => state['features/face-landmarks'])
  32. || { faceLandmarks: [] };
  33. const reloadInterval = useRef<number>();
  34. /**
  35. * Update the internal state with the latest speaker stats.
  36. *
  37. * @returns {Object}
  38. * @private
  39. */
  40. const getSpeakerStats = useCallback(() => {
  41. const stats = conference?.getSpeakerStats();
  42. for (const userId in stats) {
  43. if (stats[userId]) {
  44. if (stats[userId].isLocalStats()) {
  45. const meString = t('me');
  46. stats[userId].setDisplayName(
  47. localParticipant?.name
  48. ? `${localParticipant.name} (${meString})`
  49. : meString
  50. );
  51. if (faceLandmarksConfig?.enableDisplayFaceExpressions) {
  52. stats[userId].setFaceLandmarks(faceLandmarks);
  53. }
  54. }
  55. if (!stats[userId].getDisplayName()) {
  56. stats[userId].setDisplayName(
  57. conference?.getParticipantById(userId)?.name
  58. );
  59. }
  60. }
  61. }
  62. return stats ?? {};
  63. }, [ faceLandmarks ]);
  64. const updateStats = useCallback(
  65. () => dispatch(initUpdateStats(getSpeakerStats)),
  66. [ dispatch, initUpdateStats, getSpeakerStats ]);
  67. useEffect(() => {
  68. reloadInterval.current = window.setInterval(() => {
  69. updateStats();
  70. }, SPEAKER_STATS_RELOAD_INTERVAL);
  71. return () => {
  72. if (reloadInterval.current) {
  73. clearInterval(reloadInterval.current);
  74. }
  75. };
  76. }, [ faceLandmarks ]);
  77. const localSpeakerStats = Object.keys(speakerStats).length === 0 ? getSpeakerStats() : speakerStats;
  78. const localSortedSpeakerStatsIds
  79. = sortedSpeakerStatsIds.length === 0 ? Object.keys(localSpeakerStats) : sortedSpeakerStatsIds;
  80. const userIds = localSortedSpeakerStatsIds.filter(id => localSpeakerStats[id] && !localSpeakerStats[id].hidden);
  81. return userIds.map(userId => {
  82. const statsModel = localSpeakerStats[userId];
  83. const props = {
  84. isDominantSpeaker: statsModel.isDominantSpeaker(),
  85. dominantSpeakerTime: statsModel.getTotalDominantSpeakerTime(),
  86. participantId: userId,
  87. hasLeft: statsModel.hasLeft(),
  88. faceLandmarks: showFaceExpressions ? statsModel.getFaceLandmarks() : undefined,
  89. hidden: statsModel.hidden,
  90. showFaceExpressions,
  91. displayName: statsModel.getDisplayName() || defaultRemoteDisplayName,
  92. t
  93. };
  94. return speakerStatsItem(props);
  95. });
  96. };
  97. export default abstractSpeakerStatsList;