Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

SpeakerStats.tsx 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. import { Theme } from '@mui/material';
  2. import React, { useCallback, useEffect } from 'react';
  3. import { useDispatch, useSelector } from 'react-redux';
  4. import { makeStyles } from 'tss-react/mui';
  5. import { IReduxState } from '../../../app/types';
  6. import Dialog from '../../../base/ui/components/web/Dialog';
  7. import { escapeRegexp } from '../../../base/util/helpers';
  8. import { initSearch, resetSearchCriteria, toggleFaceExpressions } from '../../actions';
  9. import {
  10. DISPLAY_SWITCH_BREAKPOINT,
  11. MOBILE_BREAKPOINT,
  12. RESIZE_SEARCH_SWITCH_CONTAINER_BREAKPOINT
  13. } from '../../constants';
  14. import FaceExpressionsSwitch from './FaceExpressionsSwitch';
  15. import SpeakerStatsLabels from './SpeakerStatsLabels';
  16. import SpeakerStatsList from './SpeakerStatsList';
  17. import SpeakerStatsSearch from './SpeakerStatsSearch';
  18. const useStyles = makeStyles()((theme: Theme) => {
  19. return {
  20. speakerStats: {
  21. '& .row': {
  22. display: 'flex',
  23. alignItems: 'center',
  24. '& .avatar': {
  25. width: '32px',
  26. marginRight: theme.spacing(3)
  27. },
  28. '& .name-time': {
  29. width: 'calc(100% - 48px)',
  30. display: 'flex',
  31. justifyContent: 'space-between',
  32. alignItems: 'center'
  33. },
  34. '& .name-time_expressions-on': {
  35. width: 'calc(47% - 48px)'
  36. },
  37. '& .expressions': {
  38. width: 'calc(53% - 29px)',
  39. display: 'flex',
  40. justifyContent: 'space-between',
  41. '& .expression': {
  42. width: '30px',
  43. textAlign: 'center'
  44. }
  45. }
  46. }
  47. },
  48. labelsContainer: {
  49. position: 'relative'
  50. },
  51. separator: {
  52. position: 'absolute',
  53. width: 'calc(100% + 48px)',
  54. height: 1,
  55. left: -24,
  56. backgroundColor: theme.palette.ui05
  57. },
  58. searchSwitchContainer: {
  59. display: 'flex',
  60. justifyContent: 'space-between',
  61. alignItems: 'center',
  62. width: '100%'
  63. },
  64. searchSwitchContainerExpressionsOn: {
  65. width: '58.5%',
  66. [theme.breakpoints.down(RESIZE_SEARCH_SWITCH_CONTAINER_BREAKPOINT)]: {
  67. width: '100%'
  68. }
  69. },
  70. searchContainer: {
  71. width: '50%'
  72. },
  73. searchContainerFullWidth: {
  74. width: '100%'
  75. }
  76. };
  77. });
  78. const SpeakerStats = () => {
  79. const { faceLandmarks } = useSelector((state: IReduxState) => state['features/base/config']);
  80. const { showFaceExpressions } = useSelector((state: IReduxState) => state['features/speaker-stats']);
  81. const { clientWidth } = useSelector((state: IReduxState) => state['features/base/responsive-ui']);
  82. const displaySwitch = faceLandmarks?.enableDisplayFaceExpressions && clientWidth > DISPLAY_SWITCH_BREAKPOINT;
  83. const displayLabels = clientWidth > MOBILE_BREAKPOINT;
  84. const dispatch = useDispatch();
  85. const { classes } = useStyles();
  86. const onToggleFaceExpressions = useCallback(() =>
  87. dispatch(toggleFaceExpressions())
  88. , [ dispatch ]);
  89. const onSearch = useCallback((criteria = '') => {
  90. dispatch(initSearch(escapeRegexp(criteria)));
  91. }
  92. , [ dispatch ]);
  93. useEffect(() => {
  94. showFaceExpressions && !displaySwitch && dispatch(toggleFaceExpressions());
  95. }, [ clientWidth ]);
  96. useEffect(() => () => {
  97. dispatch(resetSearchCriteria());
  98. }, []);
  99. return (
  100. <Dialog
  101. cancel = {{ hidden: true }}
  102. ok = {{ hidden: true }}
  103. size = { showFaceExpressions ? 'large' : 'medium' }
  104. titleKey = 'speakerStats.speakerStats'>
  105. <div className = { classes.speakerStats }>
  106. <div
  107. className = {
  108. `${classes.searchSwitchContainer}
  109. ${showFaceExpressions ? classes.searchSwitchContainerExpressionsOn : ''}`
  110. }>
  111. <div
  112. className = {
  113. displaySwitch
  114. ? classes.searchContainer
  115. : classes.searchContainerFullWidth }>
  116. <SpeakerStatsSearch
  117. onSearch = { onSearch } />
  118. </div>
  119. { displaySwitch
  120. && <FaceExpressionsSwitch
  121. onChange = { onToggleFaceExpressions }
  122. showFaceExpressions = { showFaceExpressions } />
  123. }
  124. </div>
  125. { displayLabels && (
  126. <div className = { classes.labelsContainer }>
  127. <SpeakerStatsLabels
  128. showFaceExpressions = { showFaceExpressions ?? false } />
  129. <div className = { classes.separator } />
  130. </div>
  131. )}
  132. <SpeakerStatsList />
  133. </div>
  134. </Dialog>
  135. );
  136. };
  137. export default SpeakerStats;