feat(speaker-stats): mobile web view

This commit is contained in:
Gabriel Borlea 2022-01-21 15:00:46 +02:00 committed by Calinteodor
parent 758ece50c2
commit 55d9c9640b
8 changed files with 92 additions and 40 deletions

View File

@ -32,12 +32,6 @@
text-align: center;
}
}
}
}
.text-large{
font-size: 14px;
font-weight: 400;
}

View File

@ -49,7 +49,9 @@ const useStyles = makeStyles(theme => {
}
},
switchLabel: {
marginRight: 10
marginRight: 10,
fontSize: 14,
fontWeight: 400
}
};
});
@ -83,7 +85,7 @@ export default function FacialExpressionsSwitch({ onChange, showFacialExpression
return (
<div className = { classes.switchContainer } >
<label
className = { `text-large ${classes.switchLabel}` }
className = { classes.switchLabel }
htmlFor = 'facial-expressions-switch'>
{ t('speakerStats.displayEmotions')}
</label>

View File

@ -7,6 +7,11 @@ import { useSelector, useDispatch } from 'react-redux';
import { Dialog } from '../../../base/dialog';
import { escapeRegexp } from '../../../base/util';
import { resetSearchCriteria, toggleFacialExpressions, initSearch } from '../../actions';
import {
DISPLAY_SWITCH_BREAKPOINT,
MOBILE_BREAKPOINT,
RESIZE_SEARCH_SWITCH_CONTAINER_BREAKPOINT
} from '../../constants';
import FacialExpressionsSwitch from './FacialExpressionsSwitch';
import SpeakerStatsLabels from './SpeakerStatsLabels';
@ -22,11 +27,6 @@ const useStyles = makeStyles(theme => {
left: 0,
backgroundColor: theme.palette.border02
},
speakerStatsDialog: {
'& > div': {
}
},
searchSwitchContainer: {
display: 'flex',
justifyContent: 'space-between',
@ -35,7 +35,7 @@ const useStyles = makeStyles(theme => {
},
searchSwitchContainerExpressionsOn: {
width: '58.5%',
[theme.breakpoints.down('750')]: {
[theme.breakpoints.down(RESIZE_SEARCH_SWITCH_CONTAINER_BREAKPOINT)]: {
width: '100%'
}
},
@ -52,7 +52,8 @@ const SpeakerStats = () => {
const { enableDisplayFacialExpressions } = useSelector(state => state['features/base/config']);
const { showFacialExpressions } = useSelector(state => state['features/speaker-stats']);
const { clientWidth } = useSelector(state => state['features/base/responsive-ui']);
const displaySwitch = enableDisplayFacialExpressions && clientWidth > 600;
const displaySwitch = enableDisplayFacialExpressions && clientWidth > DISPLAY_SWITCH_BREAKPOINT;
const displayLabels = clientWidth > MOBILE_BREAKPOINT;
const dispatch = useDispatch();
const classes = useStyles();
@ -68,7 +69,6 @@ const SpeakerStats = () => {
useEffect(() => {
showFacialExpressions && !displaySwitch && dispatch(toggleFacialExpressions());
}, [ clientWidth ]);
useEffect(() => () => dispatch(resetSearchCriteria()), []);
return (
@ -100,10 +100,13 @@ const SpeakerStats = () => {
showFacialExpressions = { showFacialExpressions } />
}
</div>
<SpeakerStatsLabels
showFacialExpressions = { showFacialExpressions ?? false } />
<div className = { classes.separator } />
{ displayLabels && (
<>
<SpeakerStatsLabels
showFacialExpressions = { showFacialExpressions ?? false } />
<div className = { classes.separator } />
</>
)}
<SpeakerStatsList />
</div>
</Dialog>

View File

@ -118,7 +118,7 @@ const SpeakerStatsItem = (props: Props) => {
<div className = { nameTimeClass }>
<div
aria-label = { props.t('speakerStats.speakerStats') }
className = 'text-large'>
className = { props.styles.displayName }>
{ props.displayName }
</div>
<div
@ -133,8 +133,7 @@ const SpeakerStatsItem = (props: Props) => {
<div className = { `expressions ${props.styles.expressions}` }>
<FacialExpressions />
</div>
)
}
)}
</div>
);
};

View File

@ -13,9 +13,10 @@ const useStyles = makeStyles(() => {
height: 20
},
emojis: {
paddingLeft: 27
paddingLeft: 27,
fontSize: 14,
fontWeight: 400
}
};
});
@ -37,7 +38,7 @@ const SpeakerStatsLabels = (props: Props) => {
const FacialExpressionsLabels = () => Object.keys(FACIAL_EXPRESSION_EMOJIS).map(
expression => (
<div
className = 'expression text-large'
className = 'expression'
key = { expression }>
<Tooltip
content = { t(`speakerStats.${expression}`) }

View File

@ -3,6 +3,7 @@
import { makeStyles } from '@material-ui/core/styles';
import React from 'react';
import { MOBILE_BREAKPOINT } from '../../constants';
import abstractSpeakerStatsList from '../AbstractSpeakerStatsList';
import SpeakerStatsItem from './SpeakerStatsItem';
@ -13,7 +14,12 @@ const useStyles = makeStyles(theme => {
marginTop: 15
},
item: {
height: 48
height: 48,
[theme.breakpoints.down(MOBILE_BREAKPOINT)]: {
height: 64,
fontSize: 16,
fontWeight: 400
}
},
avatar: {
height: 32
@ -24,9 +30,20 @@ const useStyles = makeStyles(theme => {
hasLeft: {
color: theme.palette.text03
},
displayName: {
fontSize: 14,
fontWeight: 400,
[theme.breakpoints.down(MOBILE_BREAKPOINT)]: {
fontSize: 16
}
},
time: {
padding: '2px 4px',
borderRadius: '4px'
borderRadius: '4px',
[theme.breakpoints.down(MOBILE_BREAKPOINT)]: {
fontSize: 16,
fontWeight: 400
}
},
dominant: {
backgroundColor: theme.palette.success02
@ -50,5 +67,4 @@ const SpeakerStatsList = () => {
);
};
export default SpeakerStatsList;

View File

@ -5,11 +5,28 @@ import React, { useCallback, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useSelector } from 'react-redux';
import { IconSearch, Icon } from '../../../base/icons';
import { getFieldValue } from '../../../base/react';
import { MOBILE_BREAKPOINT } from '../../constants';
import { isSpeakerStatsSearchDisabled } from '../../functions';
const useStyles = makeStyles(theme => {
return {
speakerStatsSearchContainer: {
position: 'relative'
},
searchIcon: {
display: 'none',
[theme.breakpoints.down(MOBILE_BREAKPOINT)]: {
display: 'block',
position: 'absolute',
color: theme.palette.text03,
left: 16,
top: 13,
width: 20,
height: 20
}
},
speakerStatsSearch: {
backgroundColor: theme.palette.field01,
border: '1px solid',
@ -23,6 +40,13 @@ const useStyles = makeStyles(theme => {
color: theme.palette.text03,
fontSize: 14,
fontWeight: 400
},
[theme.breakpoints.down(MOBILE_BREAKPOINT)]: {
height: 48,
padding: '13px 16px 13px 44px',
'&::placeholder': {
fontSize: 16
}
}
}
};
@ -69,17 +93,24 @@ function SpeakerStatsSearch({ onSearch }: Props) {
}
return (
<input
autoComplete = 'off'
autoFocus = { false }
className = { classes.speakerStatsSearch }
id = 'speaker-stats-search'
name = 'speakerStatsSearch'
onChange = { onChange }
onKeyPress = { preventDismiss }
placeholder = { t('speakerStats.search') }
tabIndex = { 0 }
value = { searchValue } />
<div className = { classes.speakerStatsSearchContainer }>
<Icon
className = { classes.searchIcon }
color = '#858585'
src = { IconSearch } />
<input
autoComplete = 'off'
autoFocus = { false }
className = { classes.speakerStatsSearch }
id = 'speaker-stats-search'
name = 'speakerStatsSearch'
onChange = { onChange }
onKeyPress = { preventDismiss }
placeholder = { t('speakerStats.search') }
tabIndex = { 0 }
value = { searchValue } />
</div>
);
}

View File

@ -1 +1,7 @@
export const SPEAKER_STATS_RELOAD_INTERVAL = 1000;
export const DISPLAY_SWITCH_BREAKPOINT = 600;
export const RESIZE_SEARCH_SWITCH_CONTAINER_BREAKPOINT = 750;
export const MOBILE_BREAKPOINT = 480;