Merge branch 'v2.6.x-release' into shared-notes-on-media

This commit is contained in:
Joao Victor 2022-10-24 10:40:54 -03:00
commit d061b0e570
22 changed files with 123 additions and 57 deletions

View File

@ -342,7 +342,7 @@ class ActionsDropdown extends PureComponent {
}
actions={children}
opts={{
id: "default-dropdown-menu",
id: "actions-dropdown-menu",
keepMounted: true,
transitionDuration: 0,
elevation: 3,

View File

@ -428,7 +428,7 @@ class InputStreamLiveSelector extends Component {
)}
actions={dropdownListComplete}
opts={{
id: 'default-dropdown-menu',
id: 'audio-selector-dropdown-menu',
keepMounted: true,
transitionDuration: 0,
elevation: 3,

View File

@ -102,7 +102,7 @@ class BreakoutDropdown extends PureComponent {
/>
}
opts={{
id: "default-dropdown-menu",
id: "breakoutroom-dropdown-menu",
keepMounted: true,
transitionDuration: 0,
elevation: 3,

View File

@ -144,7 +144,7 @@ class ChatDropdown extends PureComponent {
/>
}
opts={{
id: 'default-dropdown-menu',
id: 'chat-options-dropdown-menu',
keepMounted: true,
transitionDuration: 0,
elevation: 3,

View File

@ -66,6 +66,7 @@ export default class Checkbox extends PureComponent {
ref={(node) => { this.checkbox = node; }}
>
<Styled.CheckboxInput
tabIndex={-1}
type="checkbox"
onChange={this.handleChange}
checked={checked}

View File

@ -4,7 +4,6 @@ import { defineMessages, injectIntl } from "react-intl";
import Menu from "@material-ui/core/Menu";
import { Divider } from "@material-ui/core";
import Icon from "/imports/ui/components/common/icon/component";
import { SMALL_VIEWPORT_BREAKPOINT } from '/imports/ui/components/layout/enums';
@ -65,7 +64,7 @@ class BBBMenu extends React.Component {
const { actions, selectedEmoji } = this.props;
return actions?.map(a => {
const { dataTest, label, onClick, key, disabled } = a;
const { dataTest, label, onClick, key, disabled, description } = a;
const emojiSelected = key?.toLowerCase()?.includes(selectedEmoji?.toLowerCase());
@ -101,7 +100,8 @@ class BBBMenu extends React.Component {
}}>
<Styled.MenuItemWrapper>
{a.icon ? <Icon iconName={a.icon} key="icon" /> : null}
<Styled.Option>{label}</Styled.Option>
<Styled.Option aria-describedby={`${key}-option-desc`}>{label}</Styled.Option>
{description && <div className="sr-only" id={`${key}-option-desc`}>{description}</div>}
{a.iconRight ? <Styled.IconRight iconName={a.iconRight} key="iconRight" /> : null}
</Styled.MenuItemWrapper>
</Styled.BBBMenuItem>,

View File

@ -72,6 +72,14 @@ const LayoutModalComponent = (props) => {
id: 'app.layout.style.videoFocus',
description: 'label for videoFocus layout style',
},
layoutSingular: {
id: 'app.layout.modal.layoutSingular',
description: 'label for singular layout',
},
layoutBtnDesc: {
id: 'app.layout.modal.layoutBtnDesc',
description: 'label for singular layout',
},
});
const handleSwitchLayout = (e) => {
@ -122,12 +130,18 @@ const LayoutModalComponent = (props) => {
{Object.values(LAYOUT_TYPE)
.map((layout) => (
<Styled.ButtonLayoutContainer key={layout}>
<Styled.LabelLayoutNames>{intl.formatMessage(intlMessages[`${layout}Layout`])}</Styled.LabelLayoutNames>
<Styled.LabelLayoutNames aria-hidden>{intl.formatMessage(intlMessages[`${layout}Layout`])}</Styled.LabelLayoutNames>
<Styled.LayoutBtn
label=""
customIcon={<Styled.IconSvg src={`${LAYOUTS_PATH}${layout}.svg`} alt={`${LAYOUTS_PATH}${layout}Layout`} />}
customIcon={(
<Styled.IconSvg
src={`${LAYOUTS_PATH}${layout}.svg`}
alt={`${layout} ${intl.formatMessage(intlMessages.layoutSingular)}`}
/>
)}
onClick={() => handleSwitchLayout(layout)}
active={(layout === selectedLayout).toString()}
aria-describedby="layout-btn-desc"
/>
</Styled.ButtonLayoutContainer>
))}
@ -159,7 +173,7 @@ const LayoutModalComponent = (props) => {
<Styled.BottomButton
label={intl.formatMessage(intlMessages.cancel)}
onClick={closeModal}
color='secondary'
color="secondary"
/>
<Button
color="primary"
@ -167,6 +181,7 @@ const LayoutModalComponent = (props) => {
onClick={handleCloseModal}
/>
</Styled.ButtonBottomContainer>
<div style={{ display: 'none' }} id="layout-btn-desc">{intl.formatMessage(intlMessages.layoutBtnDesc)}</div>
</Styled.LayoutModal>
);
};

View File

@ -80,6 +80,12 @@ const LayoutBtn = styled(Button)`
border-radius: 10px;
width: fit-content;
}
&:focus,
&:hover {
border: ${colorPrimary} solid 6px;
border-radius: 5px;
}
${({ active }) => (active === 'true') && `
border: ${colorPrimary} solid 6px;

View File

@ -333,7 +333,7 @@ class SettingsDropdown extends PureComponent {
)}
actions={this.renderMenuItems()}
opts={{
id: "default-dropdown-menu",
id: "app-settings-dropdown-menu",
keepMounted: true,
transitionDuration: 0,
elevation: 3,

View File

@ -53,6 +53,11 @@ const intlMessages = defineMessages({
description: 'Snapshot of current slide label',
defaultMessage: 'Snapshot of current slide',
},
whiteboardLabel: {
id: "app.shortcut-help.whiteboard",
description: 'used for aria whiteboard options button label',
defaultMessage: 'Whiteboard',
}
});
const propTypes = {
@ -267,7 +272,7 @@ const PresentationMenu = (props) => {
<TooltipContainer title={intl.formatMessage(intlMessages.optionsLabel)}>
<Styled.DropdownButton
state={isDropdownOpen ? 'open' : 'closed'}
aria-label={intl.formatMessage(intlMessages.optionsLabel)}
aria-label={`${intl.formatMessage(intlMessages.whiteboardLabel)} ${intl.formatMessage(intlMessages.optionsLabel)}`}
data-test="whiteboardOptionsButton"
onClick={() => {
setIsDropdownOpen((isOpen) => !isOpen)
@ -278,7 +283,7 @@ const PresentationMenu = (props) => {
</TooltipContainer>
}
opts={{
id: "default-dropdown-menu",
id: "presentation-dropdown-menu",
keepMounted: true,
transitionDuration: 0,
elevation: 3,

View File

@ -132,17 +132,19 @@ const SkipSlideSelect = styled.select`
&:-moz-focusring {
outline: none;
}
&:focus,
&:hover {
outline: transparent;
outline-style: dotted;
outline-width: ${borderSize};
background-color: #DCE4EC;
border-radius: 4px;
}
&:focus {
outline: transparent;
outline-width: ${borderSize};
outline-style: solid;
box-shadow: 0 0 0 1px #cdd6e0 !important;
}
`;

View File

@ -5,6 +5,7 @@ import {
} from '/imports/ui/stylesheets/styled-components/palette';
import {
whiteboardToolbarMargin,
borderSize,
} from '/imports/ui/stylesheets/styled-components/general';
import Button from '/imports/ui/components/common/button/component';
@ -22,11 +23,6 @@ const ResetZoomButton = styled(Button)`
font-weight: 200;
margin-left: ${whiteboardToolbarMargin};
margin-right: ${whiteboardToolbarMargin};
&:hover {
opacity: .8;
}
position: relative;
color: ${toolbarButtonColor};
background-color: ${colorOffWhite};
@ -34,9 +30,22 @@ const ResetZoomButton = styled(Button)`
box-shadow: none !important;
border: 0;
&:focus,
&:hover {
outline: transparent;
outline-style: dotted;
outline-width: ${borderSize};
background-color: #DCE4EC;
border-radius: 4px;
}
&:hover {
opacity: .8;
}
&:focus {
background-color: ${colorOffWhite};
border: 0;
outline-style: solid;
box-shadow: 0 0 0 1px #cdd6e0 !important;
}
`;

View File

@ -195,6 +195,7 @@ class UserParticipants extends Component {
clearAllEmojiStatus,
currentUser,
meetingIsBreakout,
isMeetingMuteOnStart,
} = this.props;
const { isOpen, scrollArea } = this.state;
@ -214,6 +215,7 @@ class UserParticipants extends Component {
users,
clearAllEmojiStatus,
meetingIsBreakout,
isMeetingMuteOnStart,
}}
/>
) : null

View File

@ -54,7 +54,15 @@ export default withTracker(() => {
const currentMeeting = Meetings.findOne({ meetingId: Auth.meetingID },
{ fields: { lockSettingsProps: 1 } });
const isMeetingMuteOnStart = () => {
const { voiceProp } = Meetings.findOne({ meetingId: Auth.meetingID },
{ fields: { 'voiceProp.muteOnStart': 1 } });
const { muteOnStart } = voiceProp;
return muteOnStart;
};
return ({
isMeetingMuteOnStart: isMeetingMuteOnStart(),
meetingIsBreakout: meetingIsBreakout(),
videoUsers: VideoService.getUsersIdFromVideoStreams(),
whiteboardUsers,

View File

@ -124,6 +124,10 @@ const intlMessages = defineMessages({
id: 'app.userList.userOptions.sortedLastName.heading',
description: '',
},
newTab: {
id: 'app.modal.newTab',
description: 'label used in aria description',
}
});
class UserOptions extends PureComponent {
@ -228,7 +232,7 @@ class UserOptions extends PureComponent {
this.menuItems.push({
key: this.muteAllId,
label: intl.formatMessage(intlMessages[isMeetingMuted ? 'unmuteAllLabel' : 'muteAllLabel']),
// description: intl.formatMessage(intlMessages[isMeetingMuted ? 'unmuteAllDesc' : 'muteAllDesc']),
description: intl.formatMessage(intlMessages[isMeetingMuted ? 'unmuteAllDesc' : 'muteAllDesc']),
onClick: toggleMuteAllUsers,
icon: isMeetingMuted ? 'unmute' : 'mute',
});
@ -237,7 +241,7 @@ class UserOptions extends PureComponent {
this.menuItems.push({
key: this.muteId,
label: intl.formatMessage(intlMessages.muteAllExceptPresenterLabel),
// description: intl.formatMessage(intlMessages.muteAllExceptPresenterDesc),
description: intl.formatMessage(intlMessages.muteAllExceptPresenterDesc),
onClick: toggleMuteAllUsersExceptPresenter,
icon: 'mute',
});
@ -246,7 +250,7 @@ class UserOptions extends PureComponent {
this.menuItems.push({
key: this.lockId,
label: intl.formatMessage(intlMessages.lockViewersLabel),
// description: intl.formatMessage(intlMessages.lockViewersDesc),
description: intl.formatMessage(intlMessages.lockViewersDesc),
onClick: () => mountModal(<LockViewersContainer />),
icon: 'lock',
dataTest: 'lockViewersButton',
@ -257,7 +261,7 @@ class UserOptions extends PureComponent {
key: this.guestPolicyId,
icon: 'user',
label: intl.formatMessage(intlMessages.guestPolicyLabel),
// description: intl.formatMessage(intlMessages.guestPolicyDesc),
description: intl.formatMessage(intlMessages.guestPolicyDesc),
onClick: () => mountModal(<GuestPolicyContainer />),
dataTest: 'guestPolicyLabel',
});
@ -278,7 +282,7 @@ class UserOptions extends PureComponent {
this.menuItems.push({
key: this.clearStatusId,
label: intl.formatMessage(intlMessages.clearAllLabel),
// description: intl.formatMessage(intlMessages.clearAllDesc),
description: intl.formatMessage(intlMessages.clearAllDesc),
onClick: toggleStatus,
icon: 'clear_status',
divider: true,
@ -289,7 +293,7 @@ class UserOptions extends PureComponent {
key: this.createBreakoutId,
icon: 'rooms',
label: intl.formatMessage(intlMessages.createBreakoutRoom),
// description: intl.formatMessage(intlMessages.createBreakoutRoomDesc),
description: intl.formatMessage(intlMessages.createBreakoutRoomDesc),
onClick: this.onCreateBreakouts,
dataTest: 'createBreakoutRooms',
});
@ -299,7 +303,7 @@ class UserOptions extends PureComponent {
this.menuItems.push({
icon: 'closed_caption',
label: intl.formatMessage(intlMessages.captionsLabel),
// description: intl.formatMessage(intlMessages.captionsDesc),
description: intl.formatMessage(intlMessages.captionsDesc),
key: this.captionsId,
onClick: this.handleCaptionsClick,
});
@ -310,7 +314,7 @@ class UserOptions extends PureComponent {
icon: 'multi_whiteboard',
iconRight: 'popout_window',
label: intl.formatMessage(intlMessages.learningDashboardLabel),
description: intl.formatMessage(intlMessages.learningDashboardDesc),
description: `${intl.formatMessage(intlMessages.learningDashboardDesc)} ${intl.formatMessage(intlMessages.newTab)}`,
key: this.learningDashboardId,
onClick: () => { openLearningDashboardUrl(locale); },
dividerTop: true,
@ -341,7 +345,7 @@ class UserOptions extends PureComponent {
)}
actions={this.renderMenuItems()}
opts={{
id: "default-dropdown-menu",
id: "user-options-dropdown-menu",
keepMounted: true,
transitionDuration: 0,
elevation: 3,

View File

@ -37,8 +37,9 @@ const UserOptionsContainer = withTracker((props) => {
users,
clearAllEmojiStatus,
intl,
isMeetingMuteOnStart,
} = props;
const toggleStatus = () => {
clearAllEmojiStatus(users);
@ -47,13 +48,6 @@ const UserOptionsContainer = withTracker((props) => {
);
};
const isMeetingMuteOnStart = () => {
const { voiceProp } = Meetings.findOne({ meetingId: Auth.meetingID },
{ fields: { 'voiceProp.muteOnStart': 1 } });
const { muteOnStart } = voiceProp;
return muteOnStart;
};
const getMeetingName = () => {
const { meetingProp } = Meetings.findOne({ meetingId: Auth.meetingID },
{ fields: { 'meetingProp.name': 1 } });
@ -66,7 +60,7 @@ const UserOptionsContainer = withTracker((props) => {
return {
toggleMuteAllUsers: () => {
UserListService.muteAllUsers(Auth.userID);
if (isMeetingMuteOnStart()) {
if (isMeetingMuteOnStart) {
return meetingMuteDisabledLog();
}
return logger.info({
@ -76,7 +70,7 @@ const UserOptionsContainer = withTracker((props) => {
},
toggleMuteAllUsersExceptPresenter: () => {
UserListService.muteAllExceptPresenter(Auth.userID);
if (isMeetingMuteOnStart()) {
if (isMeetingMuteOnStart) {
return meetingMuteDisabledLog();
}
return logger.info({
@ -85,7 +79,7 @@ const UserOptionsContainer = withTracker((props) => {
}, 'moderator enabled meeting mute, all users muted except presenter');
},
toggleStatus,
isMeetingMuted: isMeetingMuteOnStart(),
isMeetingMuted: isMeetingMuteOnStart,
amIModerator: ActionsBarService.amIModerator(),
hasBreakoutRoom: UserListService.hasBreakoutRoom(),
isBreakoutRecordable: ActionsBarService.isBreakoutRecordable(),

View File

@ -201,6 +201,14 @@ const intlMessages = defineMessages({
id: 'app.videoPreview.wholeImageBrightnessLabel',
description: 'Whole image brightness label',
},
wholeImageBrightnessDesc: {
id: 'app.videoPreview.wholeImageBrightnessDesc',
description: 'Whole image brightness aria description',
},
sliderDesc: {
id: 'app.videoPreview.sliderDesc',
description: 'Brightness slider aria description',
},
});
class VideoPreview extends Component {
@ -801,7 +809,7 @@ class VideoPreview extends Component {
<Styled.Label htmlFor="brightness">
{intl.formatMessage(intlMessages.brightness)}
</Styled.Label>
<div>
<div aria-hidden>
<Styled.MarkerDynamicWrapper>
<Styled.MarkerDynamic
ref={(ref) => this.brightnessMarker = ref}
@ -818,6 +826,7 @@ class VideoPreview extends Component {
min={0}
max={200}
value={brightness}
aria-describedBy={'brightness-slider-desc'}
onChange={(e) => {
const brightness = e.target.valueAsNumber;
this.currentVideoStream.changeCameraBrightness(brightness);
@ -825,7 +834,10 @@ class VideoPreview extends Component {
}}
disabled={!isVirtualBackgroundSupported() || isStartSharingDisabled}
/>
<Styled.MarkerWrapper>
<div style={{ display: 'none' }} id={'brightness-slider-desc'}>
{intl.formatMessage(intlMessages.sliderDesc)}
</div>
<Styled.MarkerWrapper aria-hidden>
<Styled.Marker>{'-100'}</Styled.Marker>
<Styled.Marker>{'0'}</Styled.Marker>
<Styled.Marker>{'100'}</Styled.Marker>
@ -834,17 +846,14 @@ class VideoPreview extends Component {
<Checkbox
onChange={this.handleBrightnessAreaChange}
checked={wholeImageBrightness}
ariaLabelledBy="brightnessAreaLabel"
id="brightnessArea"
ariaLabel={intl.formatMessage(intlMessages.wholeImageBrightnessLabel)}
ariaDescribedBy={'whole-image-desc'}
ariaDesc={intl.formatMessage(intlMessages.wholeImageBrightnessDesc)}
disabled={!isVirtualBackgroundSupported() || isStartSharingDisabled}
/>
<label
htmlFor="brightnessArea"
id="brightnessAreaLabel"
style={{ margin: '0 .5rem' }}
>
<div aria-hidden style={{ margin: '0 .5rem' }}>
{intl.formatMessage(intlMessages.wholeImageBrightnessLabel)}
</label>
</div>
</div>
</>
);

View File

@ -64,6 +64,10 @@ const intlMessages = defineMessages({
id: 'app.video.virtualBackground.camBgAriaDesc',
description: 'Label for virtual background button aria',
},
customDesc: {
id: 'app.video.virtualBackground.button.customDesc',
description: 'Aria description for upload virtual background button',
},
background: {
id: 'app.video.virtualBackground.background',
description: 'Label for the background word',
@ -338,6 +342,7 @@ const VirtualBgSelector = ({
disabled={disabled}
label={intl.formatMessage(intlMessages.removeLabel)}
aria-label={intl.formatMessage(intlMessages.removeLabel)}
aria-describedby={`vr-cam-btn-${index + 1}`}
data-test="removeCustomBackground"
icon="close"
size="sm"
@ -384,7 +389,7 @@ const VirtualBgSelector = ({
accept={MIME_TYPES_ALLOWED.join(', ')}
/>
<div aria-hidden className="sr-only" id={`vr-cam-btn-custom`}>
{intl.formatMessage(intlMessages.customLabel)}
{intl.formatMessage(intlMessages.customDesc)}
</div>
</>
);

View File

@ -156,6 +156,7 @@ const JoinVideoButton = ({
hideLabel
label={intl.formatMessage(intlMessages.videoSettings)}
rotate
tabIndex={0}
/>
)}
actions={actions}

View File

@ -148,7 +148,7 @@ const UserActions = (props) => {
)}
actions={getAvailableActions()}
opts={{
id: 'default-dropdown-menu',
id: `webcam-${user?.userId}-dropdown-menu`,
keepMounted: true,
transitionDuration: 0,
elevation: 3,

View File

@ -128,7 +128,7 @@ export default function Whiteboard(props) {
next.pages[curPageId].shapes["slide-background-shape"] = {
assetId: `slide-background-asset-${curPageId}`,
childIndex: 0.5,
childIndex: -1,
id: "slide-background-shape",
name: "Image",
type: TDShapeType.Image,

View File

@ -841,7 +841,7 @@
"app.connection-status.next": "Next page",
"app.connection-status.prev": "Previous page",
"app.learning-dashboard.label": "Learning Analytics Dashboard",
"app.learning-dashboard.description": "Open dashboard with users activities",
"app.learning-dashboard.description": "Dashboard with users activities",
"app.learning-dashboard.clickHereToOpen": "Open Learning Analytics Dashboard",
"app.recording.startTitle": "Start recording",
"app.recording.stopTitle": "Pause recording",
@ -877,6 +877,8 @@
"app.videoPreview.profileNotFoundLabel": "No supported camera profile",
"app.videoPreview.brightness": "Brightness",
"app.videoPreview.wholeImageBrightnessLabel": "Whole image",
"app.videoPreview.wholeImageBrightnessDesc": "Applies brighteness to stream and background image",
"app.videoPreview.sliderDesc": "Increase or decrease levels of brightness",
"app.video.joinVideo": "Share webcam",
"app.video.connecting": "Webcam sharing is starting ...",
"app.video.leaveVideo": "Stop sharing webcam",
@ -930,6 +932,7 @@
"app.video.virtualBackground.errorOnRead": "Something went wrong when reading the file.",
"app.video.virtualBackground.uploaded": "Uploaded",
"app.video.virtualBackground.uploading": "Uploading...",
"app.video.virtualBackground.button.customDesc": "Adds a new virtual background image",
"app.video.camCapReached": "You cannot share more cameras",
"app.video.meetingCamCapReached": "Meeting reached it's simultaneous cameras limit",
"app.video.dropZoneLabel": "Drop here",
@ -1085,6 +1088,8 @@
"app.layout.modal.keepPushingLayoutLabel": "Keep pushing to everyone",
"app.layout.modal.pushLayoutLabel": "Push to everyone",
"app.layout.modal.layoutToastLabel": "Layout settings changed",
"app.layout.modal.layoutSingular": "Layout",
"app.layout.modal.layoutBtnDesc": "Sets layout as selected option",
"app.layout.style.custom": "Custom",
"app.layout.style.smart": "Smart layout",
"app.layout.style.presentationFocus": "Focus on presentation",