convert talking-indicator component

This commit is contained in:
Ramón Souza 2021-11-02 16:25:39 +00:00
parent b430d53289
commit e384cd81fe
6 changed files with 193 additions and 170 deletions

View File

@ -1,9 +1,7 @@
import React, { PureComponent } from 'react';
import cx from 'classnames';
import _ from 'lodash';
import { defineMessages, injectIntl } from 'react-intl';
import Button from '/imports/ui/components/button/component';
import { styles } from './styles';
import Styled from './styles';
import Service from './service';
const intlMessages = defineMessages({
@ -60,15 +58,6 @@ class TalkingIndicator extends PureComponent {
callerName,
} = talkers[`${id}`];
const style = {
[styles.talker]: true,
[styles.spoke]: !talking,
[styles.muted]: muted,
[styles.mobileHide]: sidebarNavigationIsOpen
&& sidebarContentIsOpen,
[styles.isViewer]: !amIModerator,
};
const ariaLabel = intl.formatMessage(talking
? intlMessages.isTalking : intlMessages.wasTalking, {
0: callerName,
@ -78,9 +67,12 @@ class TalkingIndicator extends PureComponent {
icon = muted ? 'mute' : icon;
return (
<Button
<Styled.TalkingIndicatorButton
spoke={!talking}
muted={muted}
mobileHide={sidebarNavigationIsOpen && sidebarContentIsOpen}
isViewer={!amIModerator}
key={_.uniqueId(`${callerName}-`)}
className={cx(style)}
onClick={() => this.handleMuteUser(id)}
label={callerName}
tooltipLabel={!muted && amIModerator
@ -98,11 +90,11 @@ class TalkingIndicator extends PureComponent {
}}
>
{talking ? (
<div id="description" className={styles.hidden}>
<Styled.Hidden id="description">
{`${intl.formatMessage(intlMessages.ariaMuteDesc)}`}
</div>
</Styled.Hidden>
) : null}
</Button>
</Styled.TalkingIndicatorButton>
);
});
@ -111,14 +103,6 @@ class TalkingIndicator extends PureComponent {
const nobodyTalking = Service.nobodyTalking(talkers);
const style = {
[styles.talker]: true,
[styles.spoke]: nobodyTalking,
// [styles.muted]: false,
[styles.mobileHide]: sidebarNavigationIsOpen
&& sidebarContentIsOpen,
};
const { moreThanMaxIndicatorsTalking, moreThanMaxIndicatorsWereTalking } = intlMessages;
const ariaLabel = intl.formatMessage(nobodyTalking
@ -127,9 +111,12 @@ class TalkingIndicator extends PureComponent {
});
return (
<Button
<Styled.TalkingIndicatorButton
spoke={nobodyTalking}
muted={false}
mobileHide={sidebarNavigationIsOpen && sidebarContentIsOpen}
isViewer={false}
key={_.uniqueId('_has__More_')}
className={cx(style)}
onClick={() => {}} // maybe add a dropdown to show the rest of the users
label="..."
tooltipLabel={ariaLabel}
@ -146,12 +133,12 @@ class TalkingIndicator extends PureComponent {
};
return (
<div className={styles.isTalkingWrapper}>
<div className={styles.speaking}>
<Styled.IsTalkingWrapper>
<Styled.Speaking>
{talkingUserElements}
{maxIndicator()}
</div>
</div>
</Styled.Speaking>
</Styled.IsTalkingWrapper>
);
}
}

View File

@ -0,0 +1,156 @@
import styled from 'styled-components';
import {
borderSize,
borderRadius,
talkerBorderRadius,
talkerPaddingXsm,
talkerPaddingLg,
talkerMaxWidth,
talkerMarginSm,
spokeOpacity,
talkerPaddingXl,
} from '/imports/ui/stylesheets/styled-components/general';
import {
colorWhite,
colorSuccess,
colorDanger,
} from '/imports/ui/stylesheets/styled-components/palette';
import {
fontSizeBase,
talkerFontWeight,
fontSizeXS,
fontSizeSmaller,
} from '/imports/ui/stylesheets/styled-components/typography';
import { phoneLandscape, smallOnly } from '/imports/ui/stylesheets/styled-components/breakpoints';
import Button from '/imports/ui/components/button/component';
const TalkingIndicatorButton = styled(Button)`
display: flex;
flex-direction: row;
outline: transparent;
outline-style: dotted;
outline-width: ${borderSize};
flex: 0 0 auto;
color: ${colorWhite};
font-weight: ${talkerFontWeight};
border-radius: ${talkerBorderRadius} ${talkerBorderRadius};
font-size: ${fontSizeBase};
padding: ${talkerPaddingXsm} ${talkerPaddingLg} ${talkerPaddingXsm} ${talkerPaddingLg};
margin-left: ${borderRadius};
margin-right: ${borderRadius};
box-shadow: none !important;
@media ${phoneLandscape} {
height: 1rem;
}
i,
span {
position: relative;
}
span {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
margin: 0 0 0 0 !important;
max-width: ${talkerMaxWidth};
@media ${phoneLandscape} {
font-size: ${fontSizeXS};
}
[dir="rtl"] & {
margin-left: ${talkerMarginSm};
}
}
i {
font-size: ${fontSizeSmaller};
width: 1rem;
height: 1rem;
line-height: 1rem;
background-color: ${colorSuccess};
border-radius: 50%;
position: relative;
right: ${talkerMarginSm};
@media ${phoneLandscape} {
height: ${talkerMarginSm};
width: ${talkerMarginSm};
font-size: ${fontSizeXS};
}
[dir="rtl"] & {
right: calc(${talkerMarginSm} * -1);
}
}
span:hover {
opacity: 1;
}
${({ spoke }) => spoke && `
opacity: ${spokeOpacity};
[dir="rtl"] & {
padding-right: ${talkerPaddingLg}
}
`}
${({ muted }) => muted && `
cursor: default;
i {
background-color: ${colorDanger};
}
`}
${({ mobileHide }) => mobileHide && `
@media ${smallOnly} {
visibility: hidden;
}
`}
${({ isViewer }) => isViewer && `
cursor: default;
`}
`;
const Hidden = styled.div`
display: none;
`;
const IsTalkingWrapper = styled.div`
display: flex;
flex-direction: row;
position: relative;
margin-top: ${talkerMarginSm};
overflow: hidden;
`;
const Speaking = styled.div`
display: flex;
flex-direction: row;
flex-wrap: nowrap;
overflow-x: auto;
overflow-y: hidden;
max-height: ${talkerPaddingXl};
scrollbar-width: 0; // firefox
scrollbar-color: transparent;
&::-webkit-scrollbar {
width: 0px;
height: 0px;
background: transparent;
}
`;
export default {
TalkingIndicatorButton,
Hidden,
IsTalkingWrapper,
Speaking,
};

View File

@ -1,139 +0,0 @@
@import "/imports/ui/stylesheets/variables/breakpoints";
@import "/imports/ui/stylesheets/mixins/_indicators";
@import "/imports/ui/stylesheets/variables/placeholders";
:root {
--spoke-opacity: .5;
--talker-margin-sm: .5rem;
--talker-padding-lg: .75rem;
--talker-padding-xl: 1.62rem;
--talker-padding-xsm: .13rem;
--talker-max-width: 10rem;
--talker-font-weight: 400;
--talker-border-radius: 2rem;
}
.hidden {
display: none;
}
.isTalkingWrapper,
.speaking,
.talker,
.spoke {
display: flex;
flex-direction: row;
}
.isTalkingWrapper {
position: relative;
margin-top: var(--talker-margin-sm);
overflow: hidden;
}
.speaking {
flex-wrap: nowrap;
overflow-x: auto;
overflow-y: hidden;
max-height: var(--talker-padding-xl);
scrollbar-width: 0; // firefox
scrollbar-color: transparent;
}
.speaking::-webkit-scrollbar {
width: 0px;
height: 0px;
background: transparent;
}
.talker {
@extend %highContrastOutline;
flex: 0 0 auto;
color: var(--color-white);
font-weight: var(--talker-font-weight);
border-radius: var(--talker-border-radius) var(--talker-border-radius);
font-size: var(--font-size-base);
padding: var(--talker-padding-xsm) var(--talker-padding-lg) var(--talker-padding-xsm) var(--talker-padding-lg);
margin-left: var(--border-radius);
margin-right: var(--border-radius);
height: var(--talker-height);
box-shadow: none !important;
@include mq($phone-landscape) {
height: 1rem;
}
i,
span {
position: relative;
}
span {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
margin: 0 0 0 0 !important;
max-width: var(--talker-max-width);
bottom: var(--bottom-offset);
@include mq($phone-landscape) {
font-size: var(--font-size-xs);
}
[dir="rtl"] & {
margin-left: var(--talker-margin-sm);
}
}
i {
font-size: var(--font-size-smaller);
width: 1rem;
height: 1rem;
line-height: 1rem;
background-color: var(--color-success);
border-radius: 50%;
position: relative;
right: var(--talker-margin-sm);
@include mq($phone-landscape) {
height: var(--talker-margin-sm);
width: var(--talker-margin-sm);
font-size: var(--font-size-xs);
}
[dir="rtl"] & {
right: calc(var(--talker-margin-sm) * -1);
}
}
span:hover {
opacity: 1;
}
}
.spoke {
opacity: var(--spoke-opacity);
[dir="rtl"] & {
padding-right: var(--talker-padding-lg)
}
}
.muted {
cursor: default;
i {
background-color: var(--color-danger);
}
}
.mobileHide {
@include mq($small-only) {
visibility: hidden;
}
}
.isViewer {
cursor: default;
}

View File

@ -1,9 +1,11 @@
const smallOnly = 'only screen and (max-width: 40em)';
const mediumOnly = 'only screen and (min-width: 40.063em) and (max-width: 64em)';
const mediumUp = 'only screen and (min-width: 40.063em)';
const phoneLandscape = 'only screen and (max-width: 480px) and (orientation: landscape)';
export {
smallOnly,
mediumOnly,
mediumUp,
phoneLandscape,
};

View File

@ -23,6 +23,14 @@ const userIndicatorsOffset = '-5px';
const indicatorPadding = '.45rem'; // used to center presenter indicator icon in Chrome / Firefox / Edge
const chatPollMarginSm = '.5rem';
const talkerBorderRadius = '2rem';
const talkerPaddingXsm = '.13rem';
const talkerPaddingLg = '.75rem';
const talkerPaddingXl = '1.62rem';
const talkerMaxWidth = '10rem';
const talkerMarginSm = '.5rem';
const spokeOpacity = '.5';
export {
borderSizeSmall,
borderSize,
@ -47,4 +55,11 @@ export {
userIndicatorsOffset,
indicatorPadding,
chatPollMarginSm,
talkerBorderRadius,
talkerPaddingXsm,
talkerPaddingLg,
talkerMaxWidth,
talkerMarginSm,
spokeOpacity,
talkerPaddingXl,
};

View File

@ -10,6 +10,7 @@ const fontSizeMD = '0.95rem';
const headingsFontWeight = '500';
const btnFontWeight = '600';
const talkerFontWeight = '400';
export {
lineHeightComputed,
@ -23,4 +24,5 @@ export {
fontSizeMD,
headingsFontWeight,
btnFontWeight,
talkerFontWeight,
};