Merge remote-tracking branch 'upstream/develop' into styled-components-small

This commit is contained in:
Ramón Souza 2021-10-26 16:09:58 +00:00
commit d1f321f3d5
26 changed files with 1024 additions and 814 deletions

View File

@ -2,14 +2,14 @@ import _ from 'lodash';
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { defineMessages } from 'react-intl';
import Button from '/imports/ui/components/button/component';
import { withModalMounter } from '/imports/ui/components/modal/service';
import withShortcutHelper from '/imports/ui/components/shortcut-help/service';
import ExternalVideoModal from '/imports/ui/components/external-video-player/modal/container';
import RandomUserSelectContainer from '/imports/ui/components/modal/random-user/container';
import BBBMenu from '/imports/ui/components/menu/component';
import cx from 'classnames';
import { styles } from '../styles';
import { styles } from '../styles.scss';
import Styled from './styles'
import { PANELS, ACTIONS } from '../../layout/enums';
const propTypes = {
@ -268,8 +268,8 @@ class ActionsDropdown extends PureComponent {
classes={[styles.offsetBottom]}
accessKey={OPEN_ACTIONS_AK}
trigger={
<Button
className={isDropdownOpen ? styles.hideDropdownButton : ''}
<Styled.HideDropdownButton
open={isDropdownOpen}
hideLabel
aria-label={intl.formatMessage(intlMessages.actionsLabel)}
label={intl.formatMessage(intlMessages.actionsLabel)}

View File

@ -0,0 +1,15 @@
import styled from 'styled-components';
import { smallOnly } from '/imports/ui/stylesheets/styled-components/breakpoints';
import Button from '/imports/ui/components/button/component';
const HideDropdownButton = styled(Button)`
${({ open }) => open && `
@media ${smallOnly} {
display:none;
}
`}
`;
export default {
HideDropdownButton,
};

View File

@ -1,9 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import cx from 'classnames';
import { defineMessages, injectIntl } from 'react-intl';
import { styles } from '/imports/ui/components/actions-bar/styles';
import Button from '/imports/ui/components/button/component';
import Styled from './styles';
const propTypes = {
intl: PropTypes.shape({
@ -25,8 +23,7 @@ const intlMessages = defineMessages({
});
const CaptionsButton = ({ intl, isActive, handleOnClick }) => (
<Button
className={cx(isActive || styles.btn)}
<Styled.CaptionsButton
icon="closed_caption"
label={intl.formatMessage(isActive ? intlMessages.stop : intlMessages.start)}
color={isActive ? 'primary' : 'default'}

View File

@ -1,11 +1,10 @@
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import Modal from '/imports/ui/components/modal/simple/component';
import Button from '/imports/ui/components/button/component';
import { GithubPicker } from 'react-color';
import { defineMessages, injectIntl } from 'react-intl';
import { withModalMounter } from '/imports/ui/components/modal/service';
import { styles } from './styles.scss';
import Styled from './styles';
const DEFAULT_VALUE = 'select';
const DEFAULT_KEY = -1;
@ -224,26 +223,23 @@ class ReaderMenu extends PureComponent {
const ariaSize = `${intl.formatMessage(intlMessages.captionsLabel)} ${intl.formatMessage(intlMessages.fontSize)}`;
return (
<Modal
overlayClassName={styles.overlay}
className={styles.modal}
<Styled.ReaderMenuModal
onRequestClose={closeModal}
hideBorder
contentLabel={intl.formatMessage(intlMessages.title)}
>
<header className={styles.title}>
<Styled.Title>
{intl.formatMessage(intlMessages.title)}
</header>
</Styled.Title>
{!locale ? null : (
<div>
<div className={styles.col}>
<div className={styles.row}>
<div aria-hidden className={styles.label}>
<Styled.Col>
<Styled.Row>
<Styled.Label aria-hidden>
{intl.formatMessage(intlMessages.ariaSelectLang)}
</div>
<select
</Styled.Label>
<Styled.Select
aria-label={intl.formatMessage(intlMessages.ariaSelectLang)}
className={styles.select}
onChange={this.handleLocaleChange}
defaultValue={defaultLocale}
lang={locale}
@ -264,29 +260,27 @@ class ReaderMenu extends PureComponent {
{loc.name}
</option>
))}
</select>
</div>
</Styled.Select>
</Styled.Row>
<div className={styles.row}>
<div aria-hidden className={styles.label}>
<Styled.Row>
<Styled.Label aria-hidden>
{intl.formatMessage(intlMessages.fontColor)}
</div>
<div
</Styled.Label>
<Styled.Swatch
aria-label={ariaTextColor}
tabIndex={DEFAULT_INDEX}
className={styles.swatch}
onClick={this.handleColorPickerClick.bind(this, 'displayFontColorPicker')}
onKeyPress={() => { }}
role="button"
>
<div className={styles.swatchInner} style={{ background: fontColor }} />
</div>
<Styled.SwatchInner style={{ background: fontColor }} />
</Styled.Swatch>
{
displayFontColorPicker
? (
<div className={styles.colorPickerPopover}>
<div
className={styles.colorPickerOverlay}
<Styled.ColorPickerPopover>
<Styled.ColorPickerOverlay
onClick={this.handleCloseColorPicker.bind(this)}
onKeyPress={() => { }}
role="button"
@ -300,33 +294,31 @@ class ReaderMenu extends PureComponent {
width="140px"
triangle="hide"
/>
</div>
</Styled.ColorPickerPopover>
)
: null
}
</div>
</Styled.Row>
<div className={styles.row}>
<div aria-hidden className={styles.label}>
<Styled.Row>
<Styled.Label aria-hidden>
{intl.formatMessage(intlMessages.backgroundColor)}
</div>
<div
</Styled.Label>
<Styled.Swatch
aria-label={ariaBackgroundColor}
tabIndex={DEFAULT_INDEX}
className={styles.swatch}
onClick={this.handleColorPickerClick.bind(this, 'displayBackgroundColorPicker')}
role="button"
onKeyPress={() => { }}
>
<div className={styles.swatchInner} style={{ background: backgroundColor }} />
</div>
<Styled.SwatchInner style={{ background: backgroundColor }} />
</Styled.Swatch>
{
displayBackgroundColorPicker
? (
<div className={styles.colorPickerPopover}>
<div
<Styled.ColorPickerPopover>
<Styled.ColorPickerOverlay
aria-label={ariaBackgroundColor}
className={styles.colorPickerOverlay}
onClick={this.handleCloseColorPicker.bind(this)}
tabIndex={0}
role="button"
@ -339,19 +331,18 @@ class ReaderMenu extends PureComponent {
width="140px"
triangle="hide"
/>
</div>
</Styled.ColorPickerPopover>
)
: null
}
</div>
</Styled.Row>
<div className={styles.row}>
<div aria-hidden className={styles.label}>
<Styled.Row>
<Styled.Label aria-hidden>
{intl.formatMessage(intlMessages.fontFamily)}
</div>
<select
</Styled.Label>
<Styled.Select
aria-label={ariaFont}
className={styles.select}
defaultValue={FONT_FAMILIES.indexOf(fontFamily)}
onChange={this.handleSelectChange.bind(this, 'fontFamily', FONT_FAMILIES)}
>
@ -363,16 +354,15 @@ class ReaderMenu extends PureComponent {
{family}
</option>
))}
</select>
</div>
</Styled.Select>
</Styled.Row>
<div className={styles.row}>
<div aria-hidden className={styles.label}>
<Styled.Row>
<Styled.Label aria-hidden>
{intl.formatMessage(intlMessages.fontSize)}
</div>
<select
</Styled.Label>
<Styled.Select
aria-label={ariaSize}
className={styles.select}
defaultValue={FONT_SIZES.indexOf(fontSize)}
onChange={this.handleSelectChange.bind(this, 'fontSize', FONT_SIZES)}
>
@ -384,18 +374,18 @@ class ReaderMenu extends PureComponent {
{size}
</option>
))}
</select>
</div>
</Styled.Select>
</Styled.Row>
<div className={styles.row}>
<div className={styles.label}>{intl.formatMessage(intlMessages.preview)}</div>
<Styled.Row>
<Styled.Label>{intl.formatMessage(intlMessages.preview)}</Styled.Label>
<span aria-hidden style={this.getPreviewStyle()}>AaBbCc</span>
</div>
</div>
</Styled.Row>
</Styled.Col>
</div>
)}
<div className={styles.footer}>
<div className={styles.actions}>
<Styled.Footer>
<Styled.Actions>
<Button
label={intl.formatMessage(intlMessages.cancelLabel)}
onClick={closeModal}
@ -406,9 +396,9 @@ class ReaderMenu extends PureComponent {
onClick={() => this.handleStart()}
disabled={locale == null}
/>
</div>
</div>
</Modal>
</Styled.Actions>
</Styled.Footer>
</Styled.ReaderMenuModal>
);
}
}

View File

@ -0,0 +1,133 @@
import styled from 'styled-components';
import { smallOnly } from '/imports/ui/stylesheets/styled-components/breakpoints';
import Modal from '/imports/ui/components/modal/simple/component';
import {
colorBackground,
colorWhite,
colorGrayLabel,
colorGrayLight,
colorPrimary,
} from '/imports/ui/stylesheets/styled-components/palette';
import { borderSize, borderSizeLarge } from '/imports/ui/stylesheets/styled-components/general';
const ReaderMenuModal = styled(Modal)`
padding: 1rem;
`;
const Title = styled.header`
display: block;
color: ${colorBackground};
font-size: 1.4rem;
text-align: center;
`;
const Col = styled.div`
display: flex;
flex-direction: column;
height: 100%;
margin: 0 1.5rem 0 0;
justify-content: center;
[dir="rtl"] & {
margin: 0 0 0 1.5rem;
}
@media ${smallOnly} {
width: 100%;
height: unset;
}
`;
const Row = styled.div`
display: flex;
justify-content: space-between;
padding: .2rem 0 .2rem 0;
`;
const Label = styled.div`
flex: 1 0 0;
`;
const Select = styled.select`
background-color: ${colorWhite};
border-radius: 0.3rem;
color: ${colorGrayLabel};
height: 1.6rem;
margin-top: 0.4rem;
width: 50%;
`;
const Swatch = styled.div`
flex: 1 0 0;
border-radius: ${borderSize};
border: ${borderSize} solid ${colorGrayLight};
display: inline-block;
vertical-align: middle;
cursor: pointer;
&:focus {
outline: none;
box-shadow: inset 0 0 0 ${borderSizeLarge} ${colorPrimary};
border-radius: ${borderSize};
}
`;
const SwatchInner = styled.div`
width: auto;
height: 1.1rem;
border-radius: ${borderSize};
`;
const ColorPickerPopover = styled.div`
position: absolute;
z-index: 1001;
`;
const ColorPickerOverlay = styled.div`
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
`;
const Footer = styled.div`
display: flex;
`;
const Actions = styled.div`
margin-left: auto;
margin-right: 3px;
[dir="rtl"] & {
margin-right: auto;
margin-left: 3px;
}
> * {
&:first-child {
margin-right: 3px;
margin-left: inherit;
[dir="rtl"] & {
margin-right: inherit;
margin-left: 3px;
}
}
}
`;
export default {
ReaderMenuModal,
Title,
Col,
Row,
Label,
Select,
Swatch,
SwatchInner,
ColorPickerPopover,
ColorPickerOverlay,
Footer,
Actions,
};

View File

@ -1,112 +0,0 @@
@import "/imports/ui/stylesheets/variables/breakpoints";
@import "/imports/ui/components/modal/simple/styles";
@import "/imports/ui/stylesheets/mixins/focus";
.header {
display: flex;
border: none;
}
.footer {
display: flex;
}
.title {
display: block;
color: var(--color-background);
font-size: 1.4rem;
text-align: center;
}
.actions {
margin-left: auto;
margin-right: 3px;
[dir="rtl"] & {
margin-right: auto;
margin-left: 3px;
}
:first-child {
margin-right: 3px;
margin-left: inherit;
[dir="rtl"] & {
margin-right: inherit;
margin-left: 3px;
}
}
}
.modal {
@extend .modal;
padding: 1rem;
}
.col {
display: flex;
flex-direction: column;
height: 100%;
margin: 0 1.5rem 0 0;
justify-content: center;
[dir="rtl"] & {
margin: 0 0 0 1.5rem;
}
@include mq($small-only) {
width: 100%;
height: unset;
}
}
.select {
background-color: var(--color-white);
border-radius: 0.3rem;
color: var(--color-gray-label);
height: 1.6rem;
margin-top: 0.4rem;
width: 50%;
}
.label {
flex: 1 0 0;
}
.colorPickerOverlay {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.colorPickerPopover {
position: absolute;
z-index: 1001;
}
.swatch {
flex: 1 0 0;
@include elementFocus(var(--color-primary));
border-radius: var(--border-size);
border: var(--border-size) solid var(--color-gray-light);
display: inline-block;
vertical-align: middle;
cursor: pointer;
}
.swatchInner {
width: auto;
height: 1.1rem;
border-radius: var(--border-size);
}
.row {
display: flex;
justify-content: space-between;
padding: .2rem 0 .2rem 0;
}

View File

@ -0,0 +1,17 @@
import styled from 'styled-components';
import Button from '/imports/ui/components/button/component';
import { colorWhite } from '/imports/ui/stylesheets/styled-components/palette';
const CaptionsButton = styled(Button)`
${({ ghost }) => ghost && `
span {
box-shadow: none;
background-color: transparent !important;
border-color: ${colorWhite} !important;
}
`}
`;
export default {
CaptionsButton,
};

View File

@ -1,9 +1,7 @@
import React, { PureComponent } from 'react';
import cx from 'classnames';
import Button from '/imports/ui/components/button/component';
import CaptionsButtonContainer from '/imports/ui/components/actions-bar/captions/container';
import withShortcutHelper from '/imports/ui/components/shortcut-help/service';
import { styles } from './styles.scss';
import Styled from './styles';
import ActionsDropdown from './actions-dropdown/container';
import ScreenshareButtonContainer from '/imports/ui/components/actions-bar/screenshare/container';
import AudioControlsContainer from '../audio/audio-controls/container';
@ -40,15 +38,14 @@ class ActionsBar extends PureComponent {
} = this.props;
return (
<div
className={styles.actionsbar}
<Styled.ActionsBar
style={
{
height: actionsBarStyle.innerHeight,
}
}
>
<div className={styles.left}>
<Styled.Left>
<ActionsDropdown {...{
amIPresenter,
amIModerator,
@ -67,8 +64,8 @@ class ActionsBar extends PureComponent {
<CaptionsButtonContainer {...{ intl }} />
)
: null}
</div>
<div className={styles.center}>
</Styled.Left>
<Styled.Center>
<AudioControlsContainer />
{enableVideo
? (
@ -80,8 +77,8 @@ class ActionsBar extends PureComponent {
isMeteorConnected,
}}
/>
</div>
<div className={styles.right}>
</Styled.Center>
<Styled.Right>
{!isOldMinimizeButtonEnabled ||
(isOldMinimizeButtonEnabled && isLayoutSwapped && !isPresentationDisabled)
? (
@ -97,7 +94,7 @@ class ActionsBar extends PureComponent {
: null}
{isRaiseHandButtonEnabled
? (
<Button
<Styled.RaiseHandButton
icon="hand"
label={intl.formatMessage({
id: `app.actionsBar.emojiMenu.${
@ -110,7 +107,7 @@ class ActionsBar extends PureComponent {
color={currentUser.emoji === 'raiseHand' ? 'primary' : 'default'}
data-test={currentUser.emoji === 'raiseHand' ? 'lowerHandLabel' : 'raiseHandLabel'}
ghost={currentUser.emoji !== 'raiseHand'}
className={cx(currentUser.emoji === 'raiseHand' || styles.btn)}
emoji={currentUser.emoji}
hideLabel
circle
size="lg"
@ -123,8 +120,8 @@ class ActionsBar extends PureComponent {
/>
)
: null}
</div>
</div>
</Styled.Right>
</Styled.ActionsBar>
);
}
}

View File

@ -2,15 +2,13 @@ import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { defineMessages, injectIntl } from 'react-intl';
import _ from 'lodash';
import cx from 'classnames';
import deviceInfo from '/imports/utils/deviceInfo';
import Button from '/imports/ui/components/button/component';
import { Session } from 'meteor/session';
import Modal from '/imports/ui/components/modal/fullscreen/component';
import { withModalMounter } from '/imports/ui/components/modal/service';
import HoldButton from '/imports/ui/components/presentation/presentation-toolbar/zoom-tool/holdButton/component';
import SortList from './sort-user-list/component';
import styles from './styles';
import Styled from './styles';
const ROLE_MODERATOR = Meteor.settings.public.user.role_moderator;
@ -130,7 +128,7 @@ const intlMessages = defineMessages({
roomNameInputDesc: {
id: 'app.createBreakoutRoom.roomNameInputDesc',
description: 'aria description for room name change',
}
},
});
const BREAKOUT_LIM = Meteor.settings.public.app.breakouts.breakoutRoomLimit;
@ -265,7 +263,7 @@ class BreakoutRoom extends PureComponent {
const text = activeListSibling.getElementsByTagName('input')[0].value;
const roomNumber = text.match(/\d/g).join('');
users.forEach((u, index) => {
if (u.userId === document.activeElement.id) {
if (`roomUserItem-${u.userId}` === document.activeElement.id) {
users[index].room = text.substr(text.length - 1).includes(')') ? 0 : parseInt(roomNumber, 10);
}
});
@ -278,11 +276,11 @@ class BreakoutRoom extends PureComponent {
if (event.key.includes('ArrowDown')) {
const {
nextElementSibling, className, childNodes, parentElement,
nextElementSibling, id, childNodes, parentElement,
} = activeElement;
if (className.includes('breakoutBox')) return childNodes[0].focus();
if (id.includes('breakoutBox')) return childNodes[0].focus();
if (className.includes('roomUserItem')) {
if (id.includes('roomUserItem')) {
if (!nextElementSibling) {
return parentElement.firstElementChild.focus();
}
@ -292,11 +290,11 @@ class BreakoutRoom extends PureComponent {
if (event.key.includes('ArrowUp')) {
const {
previousElementSibling, className, childNodes, parentElement,
previousElementSibling, id, childNodes, parentElement,
} = activeElement;
if (className.includes('breakoutBox')) return childNodes[childNodes.length - 1].focus();
if (id.includes('breakoutBox')) return childNodes[childNodes.length - 1].focus();
if (className.includes('roomUserItem')) {
if (id.includes('roomUserItem')) {
if (!previousElementSibling) {
return parentElement.lastElementChild.focus();
}
@ -306,14 +304,14 @@ class BreakoutRoom extends PureComponent {
if (event.key.includes('ArrowRight')) {
const { parentElement: listContainer } = activeElement;
if (listContainer.className.includes('breakoutBox')) {
if (listContainer.id.includes('breakoutBox')) {
this.handleShiftUser(listContainer.parentElement.nextSibling);
}
}
if (event.key.includes('ArrowLeft')) {
const { parentElement: listContainer } = activeElement;
if (listContainer.className.includes('breakoutBox')) {
if (listContainer.id.includes('breakoutBox')) {
this.handleShiftUser(listContainer.parentElement.previousSibling);
}
}
@ -503,7 +501,7 @@ class BreakoutRoom extends PureComponent {
changeUserRoom(userId, room) {
const { users, freeJoin } = this.state;
const idxUser = users.findIndex((user) => user.userId === userId);
const idxUser = users.findIndex((user) => user.userId === userId.replace('roomUserItem-', ''));
const usersCopy = [...users];
@ -619,63 +617,60 @@ class BreakoutRoom extends PureComponent {
};
return (
<div className={styles.boxContainer} key="rooms-grid-" ref={(r) => { this.listOfUsers = r; }}>
<div role="alert" className={!leastOneUserIsValid ? styles.changeToWarn : null}>
<span className={styles.freeJoinLabel}>
<input
<Styled.BoxContainer key="rooms-grid-" ref={(r) => { this.listOfUsers = r; }}>
<Styled.Alert valid={leastOneUserIsValid} role="alert">
<Styled.FreeJoinLabel>
<Styled.BreakoutNameInput
type="text"
readOnly
className={styles.breakoutNameInput}
value={
intl.formatMessage(intlMessages.notAssigned, { 0: this.getUserByRoom(0).length })
}
/>
</span>
<div className={styles.breakoutBox} onDrop={drop(0)} onDragOver={allowDrop} tabIndex={0}>
</Styled.FreeJoinLabel>
<Styled.BreakoutBox id="breakoutBox-0" onDrop={drop(0)} onDragOver={allowDrop} tabIndex={0}>
{this.renderUserItemByRoom(0)}
</div>
<span className={leastOneUserIsValid ? styles.dontShow : styles.spanWarn}>
</Styled.BreakoutBox>
<Styled.SpanWarn valid={leastOneUserIsValid}>
{intl.formatMessage(intlMessages.leastOneWarnBreakout)}
</span>
</div>
</Styled.SpanWarn>
</Styled.Alert>
{
_.range(1, rooms + 1).map((value) => (
<div key={`room-${value}`}>
<span className={styles.freeJoinLabel}>
<input
<Styled.FreeJoinLabel>
<Styled.RoomName
type="text"
maxLength="255"
className={cx(styles.breakoutNameInput,
this.getRoomName(value).length === 0 ? styles.errorBorder : null,
this.hasNameDuplicated(value) ? styles.errorBorder : null)}
duplicated={this.hasNameDuplicated(value)}
value={this.getRoomName(value)}
onChange={changeRoomName(value)}
onBlur={changeRoomName(value)}
aria-label={`${this.getRoomName(value)}`}
aria-describedby={this.getRoomName(value).length === 0 ? `room-error-${value}` : `room-input-${value}`}
/>
<div aria-hidden id={`room-input-${value}`} className={"sr-only"}>
<div aria-hidden id={`room-input-${value}`} className="sr-only">
{intl.formatMessage(intlMessages.roomNameInputDesc)}
</div>
</span>
<div className={styles.breakoutBox} onDrop={drop(value)} onDragOver={allowDrop} tabIndex={0}>
</Styled.FreeJoinLabel>
<Styled.BreakoutBox id={`breakoutBox-${value}`} onDrop={drop(value)} onDragOver={allowDrop} tabIndex={0}>
{this.renderUserItemByRoom(value)}
{isInvitation && this.renderJoinedUsers(value)}
</div>
</Styled.BreakoutBox>
{this.hasNameDuplicated(value) ? (
<span className={styles.spanWarn}>
<Styled.SpanWarn valid={false}>
{intl.formatMessage(intlMessages.roomNameDuplicatedIsValid)}
</span>
</Styled.SpanWarn>
) : null}
{this.getRoomName(value).length === 0 ? (
<span aria-hidden id={`room-error-${value}`} className={styles.spanWarn}>
<Styled.SpanWarn valid={false} aria-hidden id={`room-error-${value}`}>
{intl.formatMessage(intlMessages.roomNameEmptyIsValid)}
</span>
</Styled.SpanWarn>
) : null}
</div>
))
}
</div>
</Styled.BoxContainer>
);
}
@ -694,20 +689,15 @@ class BreakoutRoom extends PureComponent {
return (
<React.Fragment key="breakout-form">
<div className={styles.breakoutSettings}>
<Styled.BreakoutSettings>
<div>
<p
className={cx(styles.labelText, !numberOfRoomsIsValid
&& styles.withError)}
aria-hidden
>
<Styled.FormLabel valid={numberOfRoomsIsValid} aria-hidden>
{intl.formatMessage(intlMessages.numberOfRooms)}
</p>
<select
</Styled.FormLabel>
<Styled.InputRooms
id="numberOfRooms"
name="numberOfRooms"
className={cx(styles.inputRooms, !numberOfRoomsIsValid
&& styles.errorBorder)}
valid={numberOfRoomsIsValid}
value={numberOfRooms}
onChange={this.changeNumberOfRooms}
aria-label={intl.formatMessage(intlMessages.numberOfRooms)}
@ -715,28 +705,26 @@ class BreakoutRoom extends PureComponent {
{
_.range(MIN_BREAKOUT_ROOMS, MAX_BREAKOUT_ROOMS + 1).map((item) => (<option key={_.uniqueId('value-')}>{item}</option>))
}
</select>
</Styled.InputRooms>
</div>
<label htmlFor="breakoutRoomTime" className={!durationIsValid ? styles.changeToWarn : null}>
<p className={styles.labelText} aria-hidden>
<Styled.DurationLabel valid={durationIsValid} htmlFor="breakoutRoomTime">
<Styled.LabelText aria-hidden>
{intl.formatMessage(intlMessages.duration)}
</p>
<div className={styles.durationArea}>
<input
</Styled.LabelText>
<Styled.DurationArea>
<Styled.DurationInput
type="number"
className={styles.duration}
min="1"
value={durationTime}
onChange={this.changeDurationTime}
onBlur={this.blurDurationTime}
aria-label={intl.formatMessage(intlMessages.duration)}
/>
<HoldButton
<Styled.HoldButtonWrapper
key="decrease-breakout-time"
exec={this.decreaseDurationTime}
minBound={MIN_BREAKOUT_ROOMS}
value={durationTime}
className={styles.btnStyle}
>
<Button
label={intl.formatMessage(intlMessages.minusRoomTime)}
@ -749,11 +737,10 @@ class BreakoutRoom extends PureComponent {
circle
size="sm"
/>
</HoldButton>
<HoldButton
</Styled.HoldButtonWrapper>
<Styled.HoldButtonWrapper
key="increase-breakout-time"
exec={this.increaseDurationTime}
className={styles.btnStyle}
>
<Button
label={intl.formatMessage(intlMessages.addRoomTime)}
@ -766,34 +753,30 @@ class BreakoutRoom extends PureComponent {
circle
size="sm"
/>
</HoldButton>
</div>
<span className={durationIsValid ? styles.dontShow : styles.leastOneWarn}>
</Styled.HoldButtonWrapper>
</Styled.DurationArea>
<Styled.SpanWarn valid={durationIsValid}>
{
intl.formatMessage(
intlMessages.minimumDurationWarnBreakout,
{ 0: MIN_BREAKOUT_TIME },
)
}
</span>
</label>
<Button
</Styled.SpanWarn>
</Styled.DurationLabel>
<Styled.RandomlyAssignBtn
data-test="randomlyAssign"
label={intl.formatMessage(intlMessages.randomlyAssign)}
aria-describedby="randomlyAssignDesc"
className={styles.randomlyAssignBtn}
onClick={this.onAssignRandomly}
size="sm"
color="default"
disabled={!numberOfRoomsIsValid}
/>
</div>
<span className={!numberOfRoomsIsValid
? styles.withError : styles.dontShow}
>
</Styled.BreakoutSettings>
<Styled.SpanWarn valid={numberOfRoomsIsValid}>
{intl.formatMessage(intlMessages.numberOfRoomsIsValid)}
</span>
</Styled.SpanWarn>
<span aria-hidden id="randomlyAssignDesc" className="sr-only">
{intl.formatMessage(intlMessages.randomlyAssignDesc)}
</span>
@ -829,25 +812,23 @@ class BreakoutRoom extends PureComponent {
record,
} = this.state;
return (
<div className={styles.checkBoxesContainer} key="breakout-checkboxes">
<label htmlFor="freeJoinCheckbox" className={styles.freeJoinLabel} key="free-join-breakouts">
<input
<Styled.CheckBoxesContainer key="breakout-checkboxes">
<Styled.FreeJoinLabel htmlFor="freeJoinCheckbox" key="free-join-breakouts">
<Styled.FreeJoinCheckbox
type="checkbox"
id="freeJoinCheckbox"
className={styles.freeJoinCheckbox}
onChange={this.setFreeJoin}
checked={freeJoin}
aria-label={intl.formatMessage(intlMessages.freeJoinLabel)}
/>
<span aria-hidden>{intl.formatMessage(intlMessages.freeJoinLabel)}</span>
</label>
</Styled.FreeJoinLabel>
{
isBreakoutRecordable ? (
<label htmlFor="recordBreakoutCheckbox" className={styles.freeJoinLabel} key="record-breakouts">
<input
<Styled.FreeJoinLabel htmlFor="recordBreakoutCheckbox" key="record-breakouts">
<Styled.FreeJoinCheckbox
id="recordBreakoutCheckbox"
type="checkbox"
className={styles.freeJoinCheckbox}
onChange={this.setRecord}
checked={record}
aria-label={intl.formatMessage(intlMessages.record)}
@ -855,10 +836,10 @@ class BreakoutRoom extends PureComponent {
<span aria-hidden>
{intl.formatMessage(intlMessages.record)}
</span>
</label>
</Styled.FreeJoinLabel>
) : null
}
</div>
</Styled.CheckBoxesContainer>
);
}
@ -885,39 +866,34 @@ class BreakoutRoom extends PureComponent {
return this.getUserByRoom(room)
.map((user) => (
<p
<Styled.RoomUserItem
tabIndex={-1}
id={user.userId}
id={`roomUserItem-${user.userId}`}
key={user.userId}
className={cx(
styles.roomUserItem,
seletedId === user.userId ? styles.selectedItem : null,
)}
selected={seletedId === user.userId}
disabled={false}
draggable
onDragStart={dragStart}
onDragEnd={dragEnd}
>
{user.userName}
<i>{(isMe(user.userId)) ? ` (${intl.formatMessage(intlMessages.you)})` : ''}</i>
</p>
</Styled.RoomUserItem>
));
}
renderJoinedUsers(room) {
return this.getUsersByRoomSequence(room)
.map((user) => (
<p
id={user.userId}
<Styled.RoomUserItem
id={`roomUserItem-${user.userId}`}
key={user.userId}
selected={false}
disabled
className={cx(
styles.roomUserItem,
styles.disableItem,
)}
>
{user.name}
<span className={styles.lockIcon} />
</p>
<Styled.LockIcon />
</Styled.RoomUserItem>
));
}
@ -926,28 +902,27 @@ class BreakoutRoom extends PureComponent {
const { numberOfRooms } = this.state;
const onClick = (roomNumber) => this.setState({ formFillLevel: 3, roomSelected: roomNumber });
return (
<div className={styles.listContainer}>
<Styled.ListContainer>
<span>
{
new Array(numberOfRooms).fill(1).map((room, idx) => (
<div className={styles.roomItem}>
<h2 className={styles.itemTitle}>
<Styled.RoomItem>
<Styled.ItemTitle>
{intl.formatMessage(intlMessages.breakoutRoomLabel, { 0: idx + 1 })}
</h2>
<Button
className={styles.itemButton}
</Styled.ItemTitle>
<Styled.ItemButton
label={intl.formatMessage(intlMessages.addParticipantLabel)}
size="lg"
ghost
color="primary"
onClick={() => onClick(idx + 1)}
/>
</div>
</Styled.RoomItem>
))
}
</span>
{isInvitation || this.renderButtonSetLevel(1, intl.formatMessage(intlMessages.backLabel))}
</div>
</Styled.ListContainer>
);
}
@ -965,27 +940,27 @@ class BreakoutRoom extends PureComponent {
<>
{!leastOneUserIsValid
&& (
<span className={styles.withError}>
<Styled.WithError>
{intl.formatMessage(intlMessages.leastOneWarnBreakout)}
</span>
</Styled.WithError>
)}
{!numberOfRoomsIsValid
&& (
<span className={styles.withError}>
<Styled.WithError>
{intl.formatMessage(intlMessages.numberOfRoomsIsValid)}
</span>
</Styled.WithError>
)}
{!roomNameDuplicatedIsValid
&& (
<span className={styles.withError}>
<Styled.WithError>
{intl.formatMessage(intlMessages.roomNameDuplicatedIsValid)}
</span>
</Styled.WithError>
)}
{!roomNameEmptyIsValid
&& (
<span className={styles.withError}>
<Styled.WithError>
{intl.formatMessage(intlMessages.roomNameEmptyIsValid)}
</span>
</Styled.WithError>
)}
</>
);
@ -1039,9 +1014,9 @@ class BreakoutRoom extends PureComponent {
renderTitle() {
const { intl } = this.props;
return (
<p className={styles.subTitle}>
<Styled.SubTitle>
{intl.formatMessage(intlMessages.breakoutRoomDesc)}
</p>
</Styled.SubTitle>
);
}
@ -1085,10 +1060,10 @@ class BreakoutRoom extends PureComponent {
}}
preventClosing={preventClosing}
>
<div className={styles.content}>
<Styled.Content>
{isInvitation || this.renderTitle()}
{isMobile ? this.renderMobile() : this.renderDesktop()}
</div>
</Styled.Content>
</Modal>
);
}

View File

@ -1,8 +1,7 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { defineMessages, injectIntl } from 'react-intl';
import Button from '/imports/ui/components/button/component';
import { styles } from '../styles';
import Styled from './styles';
const propTypes = {
confirm: PropTypes.func.isRequired,
@ -78,8 +77,8 @@ class SortUsers extends Component {
const { users } = this.state;
return users
.map((user, idx) => (
<div id={user.userId} className={styles.selectUserContainer} key={`breakout-user-${user.userId}`}>
<span className={styles.round}>
<Styled.SelectUserContainer id={user.userId} key={`breakout-user-${user.userId}`}>
<Styled.Round>
<input
type="checkbox"
id={`itemId${idx}`}
@ -94,12 +93,12 @@ class SortUsers extends Component {
onChange={this.onChage(user.userId, room)}
/>
</label>
</span>
<span className={styles.textName}>
</Styled.Round>
<Styled.TextName>
{user.userName}
{user.room && !(user.room === room) ? `\t[${user.room}]` : ''}
</span>
</div>
</Styled.TextName>
</Styled.SelectUserContainer>
));
}
@ -111,13 +110,13 @@ class SortUsers extends Component {
.map((b) => b.joinedUsers.map((u) => ({ ...u, room: b.sequence })))
.flat()
.map((user) => (
<div className={styles.selectUserContainer}>
<span className={styles.lockIcon} />
<span className={styles.textName}>
<Styled.SelectUserContainer>
<Styled.LockIcon />
<Styled.TextName>
{user.name}
{`\t[${user.room}]`}
</span>
</div>
</Styled.TextName>
</Styled.SelectUserContainer>
));
}
@ -128,22 +127,21 @@ class SortUsers extends Component {
confirm,
} = this.props;
return (
<div className={styles.selectUserScreen}>
<header className={styles.header}>
<h2 className={styles.title}>
<Styled.SelectUserScreen>
<Styled.Header>
<Styled.Title>
{intl.formatMessage(intlMessages.breakoutRoomLabel, { 0: room })}
</h2>
<Button
className={styles.buttonAdd}
</Styled.Title>
<Styled.ButtonAdd
size="md"
label={intl.formatMessage(intlMessages.doneLabel)}
color="primary"
onClick={confirm}
/>
</header>
</Styled.Header>
{this.renderUserItem()}
{this.renderJoinedUserItem()}
</div>
</Styled.SelectUserScreen>
);
}
}

View File

@ -0,0 +1,133 @@
import styled from 'styled-components';
import Button from '/imports/ui/components/button/component';
import { TextElipsis, TitleElipsis } from '/imports/ui/stylesheets/styled-components/placeholders';
import Styled from '/imports/ui/components/actions-bar/create-breakout-room/styles';
import { colorWhite, colorGrayLighter } from '/imports/ui/stylesheets/styled-components/palette';
import { borderSize } from '/imports/ui/stylesheets/styled-components/general';
import { lineHeightComputed } from '/imports/ui/stylesheets/styled-components/typography';
const SelectUserContainer = styled.div`
margin: 1.5rem 1rem;
`;
const Round = styled.span`
position: relative;
& > label {
margin-top: -10px;
background-color: #fff;
border: 1px solid #ccc;
border-radius: 50%;
cursor: pointer;
height: 28px;
left: 0;
right : auto;
position: absolute;
top: 0;
width: 28px;
[dir="rtl"] & {
left : auto;
right: 0;
}
}
& > label:after {
border: {
style: solid;
color: #fff;
width: 2px;
right: {
style : none;
}
top: {
style: none;
}
}
content: "";
height: 6px;
left: 7px;
opacity: 0;
position: absolute;
top: 8px;
transform: rotate(-45deg);
width: 12px;
[dir="rtl"] & {
border: {
style: solid;
color: #fff;
width: 2px;
left: {
style : none;
}
top: {
style: none;
}
}
}
}
& > input[type="checkbox"] {
visibility: hidden;
}
& > input[type="checkbox"]:checked + label {
background-color: #66bb6a;
border-color: #66bb6a;
}
& > input[type="checkbox"]:checked + label:after {
opacity: 1;
}
`;
const TextName = styled(TextElipsis)`
margin-left: 1.5rem;
`;
const LockIcon = styled(Styled.LockIcon)`
background:red;
`;
const SelectUserScreen = styled.div`
position: fixed;
display: block;
height: 100vh;
width: 100%;
background-color: ${colorWhite};
z-index: 1002;
top: 0;
bottom: 0;
left: 0;
right: 0;
`;
const Header = styled.header`
display: flex;
padding: ${lineHeightComputed} 0;
border-bottom: ${borderSize} solid ${colorGrayLighter};
margin: 0 1rem 0 1rem;
`;
const Title = styled(TitleElipsis)`
align-content: flex-end;
flex: 1;
margin: 0;
font-weight: 400;
`;
const ButtonAdd = styled(Button)`
flex: 0 1 35%;
`;
export default {
SelectUserContainer,
Round,
TextName,
LockIcon,
SelectUserScreen,
Header,
Title,
ButtonAdd,
};

View File

@ -0,0 +1,317 @@
import styled from 'styled-components';
import { smallOnly } from '/imports/ui/stylesheets/styled-components/breakpoints';
import { ScrollboxVertical } from '/imports/ui/stylesheets/styled-components/scrollable';
import HoldButton from '/imports/ui/components/presentation/presentation-toolbar/zoom-tool/holdButton/component';
import Button from '/imports/ui/components/button/component';
import { FlexRow, FlexColumn } from '/imports/ui/stylesheets/styled-components/placeholders';
import {
colorDanger,
colorGray,
colorGrayLight,
colorGrayLighter,
colorWhite,
colorPrimary,
colorBlueLight,
} from '/imports/ui/stylesheets/styled-components/palette';
import { fontSizeSmall, fontSizeBase } from '/imports/ui/stylesheets/styled-components/typography';
import {
borderRadius,
borderSize,
lgPaddingX,
} from '/imports/ui/stylesheets/styled-components/general';
const BoxContainer = styled.div`
display: grid;
grid-template-columns: repeat(3, minmax(4rem, 16rem));
grid-template-rows: repeat(auto-fill, minmax(4rem, 8rem));
grid-gap: 1.6rem 1rem;
box-sizing: border-box;
padding-bottom: 1rem;
`;
const Alert = styled.div`
${({ valid }) => !valid && `
position: relative;
& > * {
border-color: ${colorDanger} !important;
color: ${colorDanger};
}
`}
`;
const FreeJoinLabel = styled.label`
font-size: ${fontSizeSmall};
font-weight: bolder;
display: flex;
align-items: center;
font-size: ${fontSizeSmall};
margin-bottom: 0;
& > * {
margin: 0 .5rem 0 0;
[dir="rtl"] & {
margin: 0 0 0 .5rem;
}
}
`;
const BreakoutNameInput = styled.input`
width: 100%;
text-align: left;
font-weight: normal;
padding: .25rem;
margin: 0;
&::placeholder {
color: ${colorGray};
opacity: 1;
}
`;
const BreakoutBox = styled(ScrollboxVertical)`
width: 100%;
height: 80%;
min-height: 4rem;
max-height: 8rem;
border: 1px solid ${colorGrayLighter};
border-radius: ${borderRadius};
`;
const SpanWarn = styled.span`
${({ valid }) => valid && `
display: none;
`}
${({ valid }) => !valid && `
margin: .25rem;
position: absolute;
font-size: ${fontSizeSmall};
color: ${colorDanger};
font-weight: 200;
white-space: nowrap;
`}
`;
const RoomName = styled(BreakoutNameInput)`
${({ value }) => value.length === 0 && `
border-color: ${colorDanger} !important;
`}
${({ duplicated }) => duplicated === 0 && `
border-color: ${colorDanger} !important;
`}
`;
const BreakoutSettings = styled.div`
display: grid;
grid-template-columns: 2fr 2fr 1fr;
grid-template-rows: 1fr;
grid-gap: 1rem;
@media ${smallOnly} {
grid-template-columns: 1fr ;
grid-template-rows: 1fr 1fr 1fr;
flex-direction: column;
}
`;
const FormLabel = styled.p`
color: ${colorGray};
white-space: nowrap;
margin-bottom: .5rem;
${({ valid }) => !valid && `
color: ${colorDanger};
`}
`;
const InputRooms = styled.select`
background-color: ${colorWhite};
color: ${colorGray};
border: 1px solid ${colorGrayLighter};
border-radius: ${borderRadius};
width: 100%;
padding-top: .25rem;
padding-bottom: .25rem;
padding: .25rem 0 .25rem .25rem;
${({ valid }) => !valid && `
border-color: ${colorDanger} !important;
`}
`;
const DurationLabel = styled.label`
${({ valid }) => !valid && `
& > * {
border-color: ${colorDanger} !important;
color: ${colorDanger};
}
`}
`;
const LabelText = styled.p`
color: ${colorGray};
white-space: nowrap;
margin-bottom: .5rem;
`;
const DurationArea = styled.div`
display: flex;
align-items: center;
justify-content: space-between;
`;
const DurationInput = styled.input`
background-color: ${colorWhite};
color: ${colorGray};
border: 1px solid ${colorGrayLighter};
border-radius: ${borderRadius};
width: 50%;
text-align: center;
padding: .25rem;
&::placeholder {
color: ${colorGray};
opacity: 1;
}
`;
const HoldButtonWrapper = styled(HoldButton)`
& > button > span {
padding-bottom: ${borderSize};
}
& > button > span > i {
color: ${colorGray};
width: ${lgPaddingX};
height: ${lgPaddingX};
font-size: 170% !important;
}
`;
const RandomlyAssignBtn = styled(Button)`
color: ${colorPrimary};
font-size: ${fontSizeSmall};
white-space: nowrap;
margin: 0 auto 0 0;
align-self: flex-end;
[dir="rtl"] & {
margin: 0 0 0 auto;
}
`;
const CheckBoxesContainer = styled(FlexRow)`
margin-top: 2rem;
`;
const FreeJoinCheckbox = styled.input`
width: 1rem;
height: 1rem;
`;
const RoomUserItem = styled.p`
margin: 0;
padding: .25rem 0 .25rem .25rem;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
cursor: pointer;
border-bottom: solid .5px ${colorGrayLighter};
[dir="rtl"] & {
padding: .25rem .25rem .25rem 0;
}
${({ selected }) => selected && `
background-color: ${colorPrimary};
color: ${colorWhite};
`}
${({ disabled }) => disabled && `
cursor: not-allowed;
color: ${colorGrayLighter};
`}
`;
const LockIcon = styled.span`
float: right;
margin-right: 1rem;
@media ${smallOnly} {
margin-left: .5rem;
margin-right: auto;
float: left;
}
&:after {
font-family: 'bbb-icons' !important;
content: '\\e926';
color: ${colorGrayLight};
}
`;
const ListContainer = styled(FlexColumn)`
justify-content: flex-start;
`;
const RoomItem = styled.div`
margin: 1rem 0 1rem 0;
`;
const ItemTitle = styled.h2`
margin: 0;
color: ${colorBlueLight};
`;
const ItemButton = styled(Button)`
padding: 0;
outline: none !important;
& > span {
color: ${colorBlueLight};
}
`;
const WithError = styled.span`
color: ${colorDanger};
`;
const SubTitle = styled.p`
font-size: ${fontSizeBase};
text-align: justify;
color: ${colorGray};
`;
const Content = styled(FlexColumn)``;
export default {
BoxContainer,
Alert,
FreeJoinLabel,
BreakoutNameInput,
BreakoutBox,
SpanWarn,
RoomName,
BreakoutSettings,
FormLabel,
InputRooms,
DurationLabel,
LabelText,
DurationArea,
DurationInput,
HoldButtonWrapper,
RandomlyAssignBtn,
CheckBoxesContainer,
FreeJoinCheckbox,
RoomUserItem,
LockIcon,
ListContainer,
RoomItem,
ItemTitle,
ItemButton,
WithError,
SubTitle,
Content,
};

View File

@ -1,387 +0,0 @@
@import "/imports/ui/stylesheets/variables/breakpoints";
@import "/imports/ui/stylesheets/variables/placeholders";
@import "/imports/ui/stylesheets/mixins/_scrollable";
input[type="number"]::-webkit-outer-spin-button, input[type="number"]::-webkit-inner-spin-button {
-webkit-appearance: none;
}
.btnStyle > button > span {
padding-bottom: var(--border-size);
}
.btnStyle > button > span > i {
color: var(--color-gray);
width: var(--lg-padding-x);
height: var(--lg-padding-x);
font-size: 170% !important;
}
.subTitle {
font-size: var(--font-size-base);
text-align: justify;
color: var(--color-gray);
}
.breakoutSettings {
display: grid;
grid-template-columns: 2fr 2fr 1fr;
grid-template-rows: 1fr;
grid-gap: 1rem;
@include mq($small-only) {
grid-template-columns: 1fr ;
grid-template-rows: 1fr 1fr 1fr;
flex-direction: column;
}
}
.content {
@extend %flex-column;
}
.labelText {
color: var(--color-gray);
white-space: nowrap;
margin-bottom: .5rem;
}
.duration,
.inputRooms {
background-color: var(--color-white);
color: var(--color-gray);
border: 1px solid var(--color-gray-lighter);
border-radius: var(--border-radius);
width: 100%;
padding-top: .25rem;
padding-bottom: .25rem;
padding: .25rem 0 .25rem .25rem;
}
.duration {
width: 50%;
text-align: center;
padding: .25rem;
&::placeholder {
color: var(--color-gray);
opacity: 1;
}
}
.iconsColor {
cursor: pointer;
color: var(--color-gray-light);
font-size: var(--font-size-large);
@include mq($small-only) {
font-size: 2rem;
margin: 0 0 0 .5rem;
[dir="rtl"] & {
margin: 0 .5rem 0 0;
}
}
}
.durationArea {
display: flex;
align-items: center;
justify-content: space-between;
}
.randomlyAssignBtn {
color: var(--color-primary);
font-size: var(--font-size-small);
white-space: nowrap;
margin: 0 auto 0 0;
align-self: flex-end;
[dir="rtl"] & {
margin: 0 0 0 auto;
}
}
.freeJoinCheckbox {
width: 1rem;
height: 1rem;
}
.freeJoinLabel {
display: flex;
align-items: center;
font-size: var(--font-size-small);
margin-bottom: 0;
& > * {
margin: 0 .5rem 0 0;
[dir="rtl"] & {
margin: 0 0 0 .5rem;
}
}
}
.boxContainer {
display: grid;
grid-template-columns: repeat(3, minmax(4rem, 16rem));
grid-template-rows: repeat(auto-fill, minmax(4rem, 8rem));
grid-gap: 1.6rem 1rem;
box-sizing: border-box;
padding-bottom: 1rem;
}
.changeToWarn {
position: relative;
& > .breakoutBox {
border-color: var(--color-danger) !important;
}
& > .freeJoinLabel {
color: var(--color-danger);
}
& > .labelText {
color: var(--color-danger);
}
& .duration {
border-color: var(--color-danger) !important;
}
}
.breakoutNameInput {
width: 100%;
text-align: left;
font-weight: normal;
padding: .25rem;
margin: 0;
&::placeholder {
color: var(--color-gray);
opacity: 1;
}
}
.breakoutBox {
@include scrollbox-vertical();
width: 100%;
height: 80%;
min-height: 4rem;
max-height: 8rem;
border: 1px solid var(--color-gray-lighter);
border-radius: var(--border-radius);
}
.freeJoinLabel {
font-size: var(--font-size-small);
font-weight: bolder;
}
.spanWarn {
margin: .25rem;
position: absolute;
font-size: var(--font-size-small);
color: var(--color-danger);
font-weight: 200;
white-space: nowrap;
}
.roomUserItem {
@extend %no-margin;
padding: .25rem 0 .25rem .25rem;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
cursor: pointer;
border-bottom: solid .5px var(--color-gray-lighter);
[dir="rtl"] & {
padding: .25rem .25rem .25rem 0;
}
}
.selectedItem {
background-color: var(--color-primary);
color: var(--color-white)
}
/* mobile */
.listContainer {
@extend %flex-column;
justify-content: flex-start;
}
.itemTitle {
@extend %no-margin;
color: var(--color-blue-light);
}
.roomItem {
margin: 1rem 0 1rem 0;
}
.itemButton {
padding: 0;
outline: none !important;
span {
color: var(--color-blue-light);
}
}
.selectUserScreenContainer {
position: fixed;
z-index: 1002;
top: 0;
bottom: 0;
left: 0;
right: 0;
background-color: rgba(0, 0, 0, .85);
}
.selectUserScreen {
position: fixed;
display: block;
height: 100vh;
width: 100%;
background-color: var(--color-white);
z-index: 1002;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.header {
display: flex;
padding: var(--line-height-computed) 0;
border-bottom: var(--border-size) solid var(--color-gray-lighter);
margin: 0 1rem 0 1rem;
}
.title {
@extend %text-elipsis;
align-content: flex-end;
flex: 1;
margin: 0;
font-weight: 400;
}
.buttonAdd {
flex: 0 1 35%;
}
.selectUserContainer {
margin: 1.5rem 1rem;
}
.textName {
@extend %text-elipsis;
margin-left: 1.5rem;
}
.round {
position: relative;
& label {
margin-top: -10px;
background-color: #fff;
border: 1px solid #ccc;
border-radius: 50%;
cursor: pointer;
height: 28px;
left: 0;
right : auto;
position: absolute;
top: 0;
width: 28px;
[dir="rtl"] & {
left : auto;
right: 0;
}
}
& label:after {
border: {
style: solid;
color: #fff;
width: 2px;
right: {
style : none;
}
top: {
style: none;
}
}
content: "";
height: 6px;
left: 7px;
opacity: 0;
position: absolute;
top: 8px;
transform: rotate(-45deg);
width: 12px;
[dir="rtl"] & {
border: {
style: solid;
color: #fff;
width: 2px;
left: {
style : none;
}
top: {
style: none;
}
}
}
}
& input[type="checkbox"] {
visibility: hidden;
}
& input[type="checkbox"]:checked + label {
background-color: #66bb6a;
border-color: #66bb6a;
}
& input[type="checkbox"]:checked + label:after {
opacity: 1;
}
}
.dontShow {
display: none;
}
.checkBoxesContainer {
@extend %flex-row;
margin-top: 2rem;
}
.withError {
color: var(--color-danger);
}
.errorBorder {
border-color: var(--color-danger) !important;
}
.disableItem {
cursor: not-allowed;
color: var(--color-gray-lighter);
}
.lockIcon {
float: right;
margin-right: 1rem;
@include mq($small-only) {
margin-left: .5rem;
margin-right: auto;
float: left;
}
&:after {
font-family: 'bbb-icons';
content: "\E926";
color: var(--color-gray-light);
}
}

View File

@ -1,10 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import { defineMessages, injectIntl } from 'react-intl';
import Button from '/imports/ui/components/button/component';
import MediaService from '/imports/ui/components/media/service';
import cx from 'classnames';
import { styles } from '../styles';
import Styled from './styles';
const propTypes = {
intl: PropTypes.shape({
@ -51,8 +48,7 @@ const PresentationOptionsContainer = ({
const isThereCurrentPresentation = hasExternalVideo || hasScreenshare || hasPresentation;
return (
<Button
className={cx(styles.button, !isLayoutSwapped || styles.btn)}
<Styled.RestorePresentationButton
icon={`${buttonType}${isLayoutSwapped ? '_off' : ''}`}
label={intl.formatMessage(isLayoutSwapped ? intlMessages.restorePresentationLabel : intlMessages.minimizePresentationLabel)}
aria-label={intl.formatMessage(isLayoutSwapped ? intlMessages.restorePresentationLabel : intlMessages.minimizePresentationLabel)}

View File

@ -0,0 +1,17 @@
import styled from 'styled-components';
import Button from '/imports/ui/components/button/component';
import { colorWhite } from '/imports/ui/stylesheets/styled-components/palette';
const RestorePresentationButton = styled(Button)`
${({ ghost }) => ghost && `
span {
box-shadow: none;
background-color: transparent !important;
border-color: ${colorWhite} !important;
}
`}
`;
export default {
RestorePresentationButton,
};

View File

@ -2,9 +2,8 @@ import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { defineMessages } from 'react-intl';
import _ from 'lodash';
import Button from '/imports/ui/components/button/component';
import Dropdown from '/imports/ui/components/dropdown/component';
import { styles } from '../styles';
import Styled from './styles';
import { PANELS, ACTIONS } from '../../layout/enums';
const POLL_SETTINGS = Meteor.settings.public.poll;
@ -161,9 +160,8 @@ class QuickPollDropdown extends Component {
}
let btn = (
<Button
<Styled.QuickPollButton
aria-label={intl.formatMessage(intlMessages.quickPollLabel)}
className={styles.quickPollBtn}
label={quickPollLabel}
tooltipLabel={intl.formatMessage(intlMessages.quickPollLabel)}
onClick={() => {
@ -180,9 +178,8 @@ class QuickPollDropdown extends Component {
if (usePollDropdown) {
btn = (
<Button
<Styled.QuickPollButton
aria-label={intl.formatMessage(intlMessages.quickPollLabel)}
className={styles.quickPollBtn}
label={quickPollLabel}
tooltipLabel={intl.formatMessage(intlMessages.quickPollLabel)}
onClick={() => null}

View File

@ -0,0 +1,30 @@
import styled from 'styled-components';
import Button from '/imports/ui/components/button/component';
import { colorOffWhite, toolbarButtonColor } from '/imports/ui/stylesheets/styled-components/palette';
import { whiteboardToolbarPadding, borderSizeLarge } from '/imports/ui/stylesheets/styled-components/general';
import { headingsFontWeight } from '/imports/ui/stylesheets/styled-components/typography';
const QuickPollButton = styled(Button)`
padding: ${whiteboardToolbarPadding};
background-color: ${colorOffWhite} !important;
box-shadow: none !important;
& > span:first-child {
border: 1px solid ${toolbarButtonColor};
border-radius: ${borderSizeLarge};
color: ${toolbarButtonColor};
font-size: small;
font-weight: ${headingsFontWeight};
opacity: 1;
padding-right: ${borderSizeLarge};
padding-left: ${borderSizeLarge};
}
& > span:first-child:hover {
opacity: 1 !important;
}
`;
export default {
QuickPollButton,
};

View File

@ -3,13 +3,10 @@ import PropTypes from 'prop-types';
import { defineMessages, injectIntl } from 'react-intl';
import deviceInfo from '/imports/utils/deviceInfo';
import browserInfo from '/imports/utils/browserInfo';
import Button from '/imports/ui/components/button/component';
import logger from '/imports/startup/client/logger';
import { notify } from '/imports/ui/services/notification';
import cx from 'classnames';
import Modal from '/imports/ui/components/modal/simple/component';
import { withModalMounter } from '../../modal/service';
import { styles } from '../styles';
import Styled from './styles';
import ScreenshareBridgeService from '/imports/api/screenshare/client/bridge/service';
import {
shareScreen,
@ -142,18 +139,16 @@ const ScreenshareButton = ({
};
const renderScreenshareUnavailableModal = () => mountModal(
<Modal
overlayClassName={styles.overlay}
className={styles.modal}
<Styled.ScreenShareModal
onRequestClose={() => mountModal(null)}
hideBorder
contentLabel={intl.formatMessage(intlMessages.screenShareUnavailable)}
>
<h3 className={styles.title}>
<Styled.Title>
{intl.formatMessage(intlMessages.screenShareUnavailable)}
</h3>
</Styled.Title>
<p>{intl.formatMessage(intlMessages.screenShareNotSupported)}</p>
</Modal>,
</Styled.ScreenShareModal>,
);
const screenshareLocked = screenshareDataSavingSetting
@ -171,8 +166,7 @@ const ScreenshareButton = ({
return shouldAllowScreensharing
? (
<Button
className={cx(isVideoBroadcasting || styles.btn)}
<Styled.ScreenShareButton
disabled={(!isMeteorConnected && !isVideoBroadcasting) || !screenshareDataSavingSetting}
icon={isVideoBroadcasting ? 'desktop' : 'desktop_off'}
data-test={isVideoBroadcasting ? 'stopScreenShare' : 'startScreenShare'}

View File

@ -0,0 +1,41 @@
import styled from 'styled-components';
import Modal from '/imports/ui/components/modal/simple/component';
import Button from '/imports/ui/components/button/component';
import { colorBackground, colorWhite } from '/imports/ui/stylesheets/styled-components/palette';
import {
jumboPaddingY,
minModalHeight,
headingsFontWeight,
mdPaddingX,
} from '/imports/ui/stylesheets/styled-components/general';
import { fontSizeLarge } from '/imports/ui/stylesheets/styled-components/typography';
const ScreenShareModal = styled(Modal)`
padding: ${jumboPaddingY};
min-height: ${minModalHeight};
text-align: center;
`;
const Title = styled.h3`
font-weight: ${headingsFontWeight};
font-size: ${fontSizeLarge};
color: ${colorBackground};
white-space: normal;
padding-bottom: ${mdPaddingX};
`;
const ScreenShareButton = styled(Button)`
${({ ghost }) => ghost && `
span {
box-shadow: none;
background-color: transparent !important;
border-color: ${colorWhite} !important;
}
`}
`;
export default {
ScreenShareModal,
Title,
ScreenShareButton,
};

View File

@ -0,0 +1,95 @@
import styled from 'styled-components';
import { smallOnly } from '/imports/ui/stylesheets/styled-components/breakpoints';
import { smPaddingX, smPaddingY } from '/imports/ui/stylesheets/styled-components/general';
import { colorwhite } from '/imports/ui/stylesheets/styled-components/palette';
import Button from '/imports/ui/components/button/component';
const ActionsBar = styled.div`
display: flex;
flex-direction: row;
`;
const Left = styled.div`
display: inherit;
flex: 0;
> * {
margin: 0 ${smPaddingX};
@media ${smallOnly} {
margin: 0 ${smPaddingY};
}
}
@media ${smallOnly} {
bottom: ${smPaddingX};
left: ${smPaddingX};
right: auto;
[dir="rtl"] & {
left: auto;
right: ${smPaddingX};
}
}
`;
const Center = styled.div`
display: flex;
flex-direction: row;
flex: 1;
justify-content: center;
> * {
margin: 0 ${smPaddingX};
@media ${smallOnly} {
margin: 0 ${smPaddingY};
}
}
`;
const Right = styled.div`
display: flex;
flex-direction: row;
justify-content: center;
position: relative;
[dir="rtl"] & {
right: auto;
left: ${smPaddingX};
}
@media ${smallOnly} {
right: 0;
left: 0;
display: contents;
}
> * {
margin: 0 ${smPaddingX};
@media ${smallOnly} {
margin: 0 ${smPaddingY};
}
}
`;
const RaiseHandButton = styled(Button)`
${({ emoji }) => emoji !== 'raiseHand' && `
span {
box-shadow: none;
background-color: transparent !important;
border-color: ${colorwhite} !important;
}
`}
`;
export default {
ActionsBar,
Left,
Center,
Right,
RaiseHandButton,
};

View File

@ -24,40 +24,6 @@
padding-bottom: var(--md-padding-x);
}
.actionsbar,
.center,
.right {
display: flex;
flex-direction: row;
}
.right {
justify-content: center;
@include mq($small-only) {
position: relative;
right: 0;
left: 0;
display: contents;
}
}
.center {
flex: 1;
justify-content: center;
}
.left,
.center,
.right {
> * {
margin: 0 var(--sm-padding-x);
@include mq($small-only) {
margin: 0 var(--sm-padding-y);
}
}
}
.offsetBottom {
:global(.MuiPaper-root) {
top: auto !important;
@ -65,30 +31,6 @@
}
}
.left {
display: inherit;
flex: 0;
@include mq($small-only) {
bottom: var(--sm-padding-x);
left: var(--sm-padding-x);
right: auto;
[dir="rtl"] & {
left: auto;
right: var(--sm-padding-x);
}
}
}
.right {
position: relative;
[dir="rtl"] & {
right: auto;
left: var(--sm-padding-x);
}
}
.quickPollBtn {
padding: var(--whiteboard-toolbar-padding);
background-color: var(--color-off-white) !important;
@ -122,12 +64,6 @@
z-index: 4;
}
.hideDropdownButton {
@include mq($small-only) {
display:none;
}
}
.presentationItem {
span {
text-overflow: ellipsis;

View File

@ -0,0 +1,5 @@
const smallOnly = 'only screen and (max-width: 40em)';
export {
smallOnly,
};

View File

@ -1,17 +1,28 @@
const borderSize = '2px';
const borderSizeLarge = '3px';
const borderRadius = '.2rem';
const smPaddingX = '.75rem';
const smPaddingY = '.3rem';
const mdPaddingY = '.45rem';
const mdPaddingX = '1rem';
const lgPaddingX = '1.25rem';
const lgPaddingY = '0.6rem';
const jumboPaddingY = '1.5rem';
const whiteboardToolbarPadding = '.5rem';
const minModalHeight = '20rem';
export {
borderSize,
borderSizeLarge,
borderRadius,
smPaddingX,
smPaddingY,
mdPaddingX,
mdPaddingY,
lgPaddingX,
lgPaddingY,
jumboPaddingY,
whiteboardToolbarPadding,
minModalHeight,
};

View File

@ -6,6 +6,7 @@ const colorGrayDark = '#06172A';
const colorGrayLight = '#8B9AA8';
const colorGrayLighter = '#A7B3BD';
const colorBlueLight = '#54a1f3';
const colorBlueLighter = '#92BCEA';
const colorTransparent = '#ff000000';
@ -13,13 +14,19 @@ const colorTransparent = '#ff000000';
const colorPrimary = '#0F70D7';
const colorDanger = '#DF2721';
const colorBackground = colorGrayDark;
const userListBg = colorOffWhite;
const userListText = colorGray;
const unreadMessagesBg = colorDanger;
const colorGrayLabel = colorGray;
const listItemBgHover = '#DCE4ED';
const itemFocusBorder = colorBlueLighter;
const btnDefaultColor = colorGray;
const toolbarButtonColor = btnDefaultColor;
export {
colorWhite,
colorOffWhite,
@ -28,11 +35,17 @@ export {
colorGrayLight,
colorGrayLighter,
colorTransparent,
colorBlueLight,
colorBlueLighter,
colorPrimary,
colorDanger,
colorBackground,
userListBg,
userListText,
unreadMessagesBg,
colorGrayLabel,
listItemBgHover,
itemFocusBorder,
btnDefaultColor,
toolbarButtonColor,
};

View File

@ -40,7 +40,6 @@ const ScrollboxVertical = styled.div`
&::-webkit-scrollbar-corner { background: 0 0; }
`;
const VirtualizedScrollboxVertical = styled(List)`
overflow-y: auto;
background: linear-gradient(white 30%, rgba(255,255,255,0)),
@ -83,4 +82,4 @@ const VirtualizedScrollboxVertical = styled(List)`
export {
ScrollboxVertical,
VirtualizedScrollboxVertical,
}
};

View File

@ -5,6 +5,8 @@ const fontSizeSmaller = '.75rem';
const fontSizeXS = '.575rem';
const fontSizeLarge = '1.25rem';
const headingsFontWeight = '500';
export {
lineHeightComputed,
fontSizeBase,
@ -12,4 +14,5 @@ export {
fontSizeSmaller,
fontSizeXS,
fontSizeLarge,
headingsFontWeight,
};