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.

SpeakerStatsItem.js 3.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. /* @flow */
  2. import React from 'react';
  3. import { Avatar, StatelessAvatar } from '../../../base/avatar';
  4. import { getInitials } from '../../../base/avatar/functions';
  5. import BaseTheme from '../../../base/ui/components/BaseTheme';
  6. import { FACE_EXPRESSIONS } from '../../../face-landmarks/constants';
  7. import TimeElapsed from './TimeElapsed';
  8. /**
  9. * The type of the React {@code Component} props of {@link SpeakerStatsItem}.
  10. */
  11. type Props = {
  12. /**
  13. * The name of the participant.
  14. */
  15. displayName: string,
  16. /**
  17. * The object that has as keys the face expressions of the
  18. * participant and as values a number that represents the count .
  19. */
  20. faceExpressions: Object,
  21. /**
  22. * True if the face expressions detection is not disabled.
  23. */
  24. showFaceExpressions: boolean,
  25. /**
  26. * The total milliseconds the participant has been dominant speaker.
  27. */
  28. dominantSpeakerTime: number,
  29. /**
  30. * The id of the user.
  31. */
  32. participantId: string,
  33. /**
  34. * True if the participant is no longer in the meeting.
  35. */
  36. hasLeft: boolean,
  37. /**
  38. * True if the participant is not shown in speaker stats.
  39. */
  40. hidden: boolean,
  41. /**
  42. * True if the participant is currently the dominant speaker.
  43. */
  44. isDominantSpeaker: boolean,
  45. /**
  46. * Styles for the item.
  47. */
  48. styles: Object,
  49. /**
  50. * Invoked to obtain translated strings.
  51. */
  52. t: Function
  53. }
  54. const SpeakerStatsItem = (props: Props) => {
  55. const hasLeftClass = props.hasLeft ? props.styles.hasLeft : '';
  56. const rowDisplayClass = `row ${hasLeftClass} ${props.styles.item}`;
  57. const expressionClass = 'expression';
  58. const nameTimeClass = `name-time${
  59. props.showFaceExpressions ? ' name-time_expressions-on' : ''
  60. }`;
  61. const timeClass = `${props.styles.time} ${props.isDominantSpeaker ? props.styles.dominant : ''}`;
  62. const FaceExpressions = () => FACE_EXPRESSIONS.map(
  63. expression => (
  64. <div
  65. aria-label = { props.t(`speakerStats.${expression}`) }
  66. className = {
  67. `${expressionClass} ${
  68. props.faceExpressions[expression] === 0 ? props.styles.hasLeft : ''
  69. }`
  70. }
  71. key = { expression }>
  72. { props.faceExpressions[expression] }
  73. </div>
  74. )
  75. );
  76. return (
  77. <div
  78. className = { rowDisplayClass }
  79. key = { props.participantId } >
  80. <div className = { `avatar ${props.styles.avatar}` }>
  81. {
  82. props.hasLeft ? (
  83. <StatelessAvatar
  84. className = 'userAvatar'
  85. color = { BaseTheme.palette.ui04 }
  86. id = 'avatar'
  87. initials = { getInitials(props.displayName) } />
  88. ) : (
  89. <Avatar
  90. className = 'userAvatar'
  91. participantId = { props.participantId } />
  92. )
  93. }
  94. </div>
  95. <div className = { nameTimeClass }>
  96. <div
  97. aria-label = { props.t('speakerStats.speakerStats') }
  98. className = { props.styles.displayName }>
  99. { props.displayName }
  100. </div>
  101. <div
  102. aria-label = { props.t('speakerStats.speakerTime') }
  103. className = { timeClass }>
  104. <TimeElapsed
  105. time = { props.dominantSpeakerTime } />
  106. </div>
  107. </div>
  108. { props.showFaceExpressions
  109. && (
  110. <div className = { `expressions ${props.styles.expressions}` }>
  111. <FaceExpressions />
  112. </div>
  113. )}
  114. </div>
  115. );
  116. };
  117. export default SpeakerStatsItem;