Merge branch 'v2.0.x-release' of github.com:bigbluebutton/bigbluebutton into v2.0.x-release

This commit is contained in:
Richard Alam 2017-10-09 12:02:38 -07:00
commit 0f7478b238
17 changed files with 227 additions and 229 deletions

View File

@ -1,32 +1,32 @@
@font-face {
font-family: 'bbb-icons';
src: url('/fonts/BbbIcons/bbb-icons.eot?j1ntjp');
src: url('/fonts/BbbIcons/bbb-icons.eot?j1ntjp#iefix') format('embedded-opentype'),
url('/fonts/BbbIcons/bbb-icons.ttf?j1ntjp') format('truetype'),
url('/fonts/BbbIcons/bbb-icons.woff?j1ntjp') format('woff'),
url('/fonts/BbbIcons/bbb-icons.svg?j1ntjp#bbb-icons') format('svg');
font-weight: normal;
font-style: normal;
font-family: 'bbb-icons';
src: url('/fonts/BbbIcons/bbb-icons.eot?j1ntjp');
src: url('/fonts/BbbIcons/bbb-icons.eot?j1ntjp#iefix') format('embedded-opentype'),
url('/fonts/BbbIcons/bbb-icons.ttf?j1ntjp') format('truetype'),
url('/fonts/BbbIcons/bbb-icons.woff?j1ntjp') format('woff'),
url('/fonts/BbbIcons/bbb-icons.svg?j1ntjp#bbb-icons') format('svg');
font-weight: normal;
font-style: normal;
}
[class^="icon-bbb-"], [class*=" icon-bbb-"] {
/* use !important to prevent issues with browser extensions that change fonts */
font-family: 'bbb-icons' !important;
speak: none;
position: relative;
/*top: 1px;*/
display: inline-block;
font-style: normal;
font-weight: 400;
line-height: 1;
-webkit-font-smoothing: antialiased;
width: 1.28571429em;
text-align: center;
vertical-align: middle;
/* use !important to prevent issues with browser extensions that change fonts */
font-family: 'bbb-icons' !important;
speak: none;
position: relative;
/*top: 1px;*/
display: inline-block;
font-style: normal;
font-weight: 400;
line-height: 1;
-webkit-font-smoothing: antialiased;
width: 1.28571429em;
text-align: center;
vertical-align: middle;
/* Better Font Rendering =========== */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
/* Better Font Rendering =========== */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-bbb-mute:before {
@ -45,7 +45,7 @@
content: "\e92a";
}
.icon-bbb-exit_fullscreen:before {
content: "\e935";
content: "\e935";
}
.icon-bbb-settings:before {
content: "\e92b";
@ -95,8 +95,13 @@
.icon-bbb-video:before {
content: "\e930";
}
.icon-bbb-elipsis:before {
content: "\e902";
}
.icon-bbb-more:before {
content: "\e902";
display: inline-block;
transform: rotate(90deg);
}
.icon-bbb-promote:before {
content: "\e903";

View File

@ -1,4 +1,4 @@
import React, { Component } from 'react';
import React from 'react';
import PropTypes from 'prop-types';
import { defineMessages, injectIntl } from 'react-intl';
@ -10,129 +10,7 @@ import DropdownList from '/imports/ui/components/dropdown/list/component';
import DropdownListItem from '/imports/ui/components/dropdown/list/item/component';
import DropdownListSeparator from '/imports/ui/components/dropdown/list/separator/component';
const propTypes = {
// Emoji status of the current user
userEmojiStatus: PropTypes.string.isRequired,
actions: PropTypes.object.isRequired,
};
class EmojiMenu extends Component {
constructor(props) {
super(props);
}
render() {
const {
userEmojiStatus,
actions,
intl,
} = this.props;
return (
<Dropdown autoFocus>
<DropdownTrigger tabIndex={0}>
<Button
role="button"
label={intl.formatMessage(intlMessages.statusTriggerLabel)}
aria-label={intl.formatMessage(intlMessages.changeStatusLabel)}
aria-describedby="currentStatus"
icon="hand"
ghost={false}
circle
hideLabel={false}
color="primary"
size="lg"
// FIXME: Without onClick react proptypes keep warning
// even after the DropdownTrigger inject an onClick handler
onClick={() => null}
>
<div id="currentStatus" hidden>
{
intl.formatMessage(intlMessages.currentStatusDesc, { 0: userEmojiStatus })
}
</div>
</Button>
</DropdownTrigger>
<DropdownContent placement="top left">
<DropdownList>
<DropdownListItem
icon="hand"
label={intl.formatMessage(intlMessages.raiseLabel)}
description={intl.formatMessage(intlMessages.raiseDesc)}
onClick={() => actions.setEmojiHandler('raiseHand')}
tabIndex={-1}
/>
<DropdownListItem
icon="happy"
label={intl.formatMessage(intlMessages.happyLabel)}
description={intl.formatMessage(intlMessages.happyDesc)}
onClick={() => actions.setEmojiHandler('happy')}
tabIndex={-1}
/>
<DropdownListItem
icon="undecided"
label={intl.formatMessage(intlMessages.undecidedLabel)}
description={intl.formatMessage(intlMessages.undecidedDesc)}
onClick={() => actions.setEmojiHandler('neutral')}
tabIndex={-1}
/>
<DropdownListItem
icon="sad"
label={intl.formatMessage(intlMessages.sadLabel)}
description={intl.formatMessage(intlMessages.sadDesc)}
onClick={() => actions.setEmojiHandler('sad')}
tabIndex={-1}
/>
<DropdownListItem
icon="confused"
label={intl.formatMessage(intlMessages.confusedLabel)}
description={intl.formatMessage(intlMessages.confusedDesc)}
onClick={() => actions.setEmojiHandler('confused')}
tabIndex={-1}
/>
<DropdownListItem
icon="time"
label={intl.formatMessage(intlMessages.awayLabel)}
description={intl.formatMessage(intlMessages.awayDesc)}
onClick={() => actions.setEmojiHandler('away')}
tabIndex={-1}
/>
<DropdownListItem
icon="thumbs_up"
label={intl.formatMessage(intlMessages.thumbsUpLabel)}
description={intl.formatMessage(intlMessages.thumbsUpDesc)}
onClick={() => actions.setEmojiHandler('thumbsUp')}
tabIndex={-1}
/>
<DropdownListItem
icon="thumbs_down"
label={intl.formatMessage(intlMessages.thumbsDownLabel)}
description={intl.formatMessage(intlMessages.thumbsDownDesc)}
onClick={() => actions.setEmojiHandler('thumbsDown')}
tabIndex={-1}
/>
<DropdownListItem
icon="applause"
label={intl.formatMessage(intlMessages.applauseLabel)}
description={intl.formatMessage(intlMessages.applauseDesc)}
onClick={() => actions.setEmojiHandler('applause')}
tabIndex={-1}
/>
<DropdownListSeparator />
<DropdownListItem
icon="clear_status"
label={intl.formatMessage(intlMessages.clearLabel)}
description={intl.formatMessage(intlMessages.clearDesc)}
onClick={() => actions.setEmojiHandler('none')}
tabIndex={-1}
/>
</DropdownList>
</DropdownContent>
</Dropdown>
);
}
}
import { EMOJI_NORMALIZE } from '/imports/utils/statuses';
const intlMessages = defineMessages({
statusTriggerLabel: {
@ -229,5 +107,118 @@ const intlMessages = defineMessages({
},
});
const propTypes = {
// Emoji status of the current user
userEmojiStatus: PropTypes.string.isRequired,
actions: PropTypes.object.isRequired,
};
const EmojiMenu = ({
userEmojiStatus,
actions,
intl,
}) => (
<Dropdown autoFocus>
<DropdownTrigger tabIndex={0}>
<Button
role="button"
label={intl.formatMessage(intlMessages.statusTriggerLabel)}
aria-label={intl.formatMessage(intlMessages.changeStatusLabel)}
aria-describedby="currentStatus"
icon={userEmojiStatus in EMOJI_NORMALIZE ?
EMOJI_NORMALIZE[userEmojiStatus] : 'hand'}
ghost={false}
circle
hideLabel={false}
color="primary"
size="lg"
// FIXME: Without onClick react proptypes keep warning
// even after the DropdownTrigger inject an onClick handler
onClick={() => null}
>
<div id="currentStatus" hidden>
{ intl.formatMessage(intlMessages.currentStatusDesc, { 0: userEmojiStatus }) }
</div>
</Button>
</DropdownTrigger>
<DropdownContent placement="top left">
<DropdownList>
<DropdownListItem
icon="hand"
label={intl.formatMessage(intlMessages.raiseLabel)}
description={intl.formatMessage(intlMessages.raiseDesc)}
onClick={() => actions.setEmojiHandler('raiseHand')}
tabIndex={-1}
/>
<DropdownListItem
icon="happy"
label={intl.formatMessage(intlMessages.happyLabel)}
description={intl.formatMessage(intlMessages.happyDesc)}
onClick={() => actions.setEmojiHandler('happy')}
tabIndex={-1}
/>
<DropdownListItem
icon="undecided"
label={intl.formatMessage(intlMessages.undecidedLabel)}
description={intl.formatMessage(intlMessages.undecidedDesc)}
onClick={() => actions.setEmojiHandler('neutral')}
tabIndex={-1}
/>
<DropdownListItem
icon="sad"
label={intl.formatMessage(intlMessages.sadLabel)}
description={intl.formatMessage(intlMessages.sadDesc)}
onClick={() => actions.setEmojiHandler('sad')}
tabIndex={-1}
/>
<DropdownListItem
icon="confused"
label={intl.formatMessage(intlMessages.confusedLabel)}
description={intl.formatMessage(intlMessages.confusedDesc)}
onClick={() => actions.setEmojiHandler('confused')}
tabIndex={-1}
/>
<DropdownListItem
icon="time"
label={intl.formatMessage(intlMessages.awayLabel)}
description={intl.formatMessage(intlMessages.awayDesc)}
onClick={() => actions.setEmojiHandler('away')}
tabIndex={-1}
/>
<DropdownListItem
icon="thumbs_up"
label={intl.formatMessage(intlMessages.thumbsUpLabel)}
description={intl.formatMessage(intlMessages.thumbsUpDesc)}
onClick={() => actions.setEmojiHandler('thumbsUp')}
tabIndex={-1}
/>
<DropdownListItem
icon="thumbs_down"
label={intl.formatMessage(intlMessages.thumbsDownLabel)}
description={intl.formatMessage(intlMessages.thumbsDownDesc)}
onClick={() => actions.setEmojiHandler('thumbsDown')}
tabIndex={-1}
/>
<DropdownListItem
icon="applause"
label={intl.formatMessage(intlMessages.applauseLabel)}
description={intl.formatMessage(intlMessages.applauseDesc)}
onClick={() => actions.setEmojiHandler('applause')}
tabIndex={-1}
/>
<DropdownListSeparator />
<DropdownListItem
icon="clear_status"
label={intl.formatMessage(intlMessages.clearLabel)}
description={intl.formatMessage(intlMessages.clearDesc)}
onClick={() => actions.setEmojiHandler('none')}
tabIndex={-1}
/>
</DropdownList>
</DropdownContent>
</Dropdown>
);
EmojiMenu.propTypes = propTypes;
export default injectIntl(EmojiMenu);

View File

@ -46,6 +46,7 @@ $btn-jumbo-padding: $jumbo-padding-y $jumbo-padding-x;
vertical-align: middle;
cursor: pointer;
user-select: none;
transition: all .2s ease-in-out;
&:hover,
&:focus {
@ -99,7 +100,6 @@ $btn-jumbo-padding: $jumbo-padding-y $jumbo-padding-x;
opacity: .85;
display: block;
margin-top: $btn-spacing;
font-size: 90%;
color: #fff;
font-weight: normal;
line-height: 1.5;

View File

@ -4,7 +4,7 @@ import cx from 'classnames';
import { withModalMounter } from '/imports/ui/components/modal/service';
import Clipboard from 'clipboard';
import _ from 'lodash';
import Button from '/imports/ui/components/button/component';
import Icon from '/imports/ui/components/icon/component';
import Dropdown from '/imports/ui/components/dropdown/component';
import DropdownTrigger from '/imports/ui/components/dropdown/trigger/component';
import DropdownContent from '/imports/ui/components/dropdown/content/component';
@ -118,17 +118,12 @@ class ChatDropdown extends Component {
onShow={this.onActionsShow}
onHide={this.onActionsHide}
>
<DropdownTrigger tabIndex={0}>
<Button
label={intl.formatMessage(intlMessages.options)}
icon="more"
circle
hideLabel
className={cx(styles.btn, styles.btnSettings)}
// FIXME: Without onClick react proptypes keep warning
// even after the DropdownTrigger inject an onClick handler
onClick={() => null}
/>
<DropdownTrigger
tabIndex={0}
ariaLabel={intl.formatMessage(intlMessages.options)}
className={styles.btn}
>
<Icon iconName="more" />
</DropdownTrigger>
<DropdownContent placement="bottom right">
<DropdownList>

View File

@ -2,18 +2,5 @@
.btn {
flex: 0 0;
margin-left: $sm-padding-x / 2;
i{
color: black !important;
}
&:hover,
&:focus {
span {
background-color: transparent !important;
color: $color-white !important;
opacity: .75;
}
}
margin-top: auto;
}

View File

@ -70,6 +70,11 @@
.sendButton {
margin-left: $sm-padding-x;
align-self: flex-end;
i {
font-size: 115% !important;
}
}
.info {

View File

@ -16,13 +16,31 @@
}
.systemMessage {
.item + &,
& + .item {
margin-bottom: $line-height-computed * 1.5;
padding: $line-height-computed 0;
border-bottom: 1px solid $color-gray-lighter;
.item:not(&) + & {
border-top: 1px solid $color-gray-lighter;
}
& + & {
margin-top: -$line-height-computed;
}
&:last-child {
border-bottom: none;
}
.message {
color: $color-heading;
color: $color-gray;
// hide the <br> we dont want from the default WelcomeMessage
br:first-child,
br:last-child,
br + br {
display: none;
}
}
}
@ -70,7 +88,6 @@
display: flex;
min-width: 0;
font-weight: 600;
color: $color-gray-light;
text-transform: capitalize;
font-style: italic;

View File

@ -11,9 +11,11 @@ $padding: $md-padding-x;
position: relative;
overflow-x: hidden;
overflow-y: auto;
padding-left: $padding;
margin-left: -$padding;
padding-right: $padding;
padding-bottom: $padding;
margin-right: -$padding;
padding-bottom: $padding;
margin-bottom: -$padding;
}
@ -29,10 +31,11 @@ $padding: $md-padding-x;
}
.unreadButton {
flex-grow: 0;
flex-shrink: 0;
border-radius: 0;
width: 100%;
text-transform: uppercase;
margin-bottom: .5rem;
// margin-top: .25rem;
margin-bottom: .25rem;
background-color: darken($color-white, 5%);
@extend %text-elipsis;
}

View File

@ -41,16 +41,14 @@ export default class DropdownTrigger extends Component {
}
render() {
const { children, style, className, tabIndex } = this.props;
const { children, className, ...restProps } = this.props;
const TriggerComponent = React.Children.only(children);
const TriggerComponentBounded = React.cloneElement(children, {
const TriggerComponentBounded = React.cloneElement(TriggerComponent, {
...restProps,
onClick: this.handleClick,
onKeyDown: this.handleKeyDown,
'aria-haspopup': true,
tabIndex,
style,
className: cx(children.props.className, className),
});

View File

@ -46,11 +46,12 @@
content: '';
position: absolute;
border-radius: 50%;
width: 10px;
height: 10px;
bottom: 0;
right: 0;
width: 12px;
height: 12px;
bottom: 2px;
right: 3px;
background-color: $color-danger;
border: 2px solid;
}
}
@ -73,7 +74,6 @@
}
.btnSettings {
transform: rotate(90deg);
}
.dropdownBreakout {

View File

@ -5,7 +5,7 @@
*/
$user-avatar-border: $color-gray-light;
$user-avatar-text: $color-white;
$user-indicators-offset: -.15rem;
$user-indicators-offset: -5px;
$user-indicator-presenter-bg: $color-primary;
$user-indicator-voice-bg: $color-success;
$user-indicator-muted-bg: $color-danger;
@ -20,7 +20,7 @@ $user-list-bg: #F3F6F9;
text-align: center;
text-transform: capitalize;
transition: .3s ease-in-out;
font-size: 1rem;
font-size: .85rem;
&:after, &:before {
content: "";
@ -31,9 +31,9 @@ $user-list-bg: #F3F6F9;
color: inherit;
top: auto;
left: auto;
bottom: $user-indicators-offset / 2;
bottom: $user-indicators-offset;
right: $user-indicators-offset;
border: 1.25px solid $user-list-bg;
border: 1.5px solid $user-list-bg;
border-radius: 50%;
background-color: $user-indicator-voice-bg;
color: $user-avatar-text;
@ -60,7 +60,7 @@ $user-list-bg: #F3F6F9;
&:before {
content: "\00a0\e90b\00a0";
opacity: 1;
top: $user-indicators-offset / 2;
top: $user-indicators-offset;
left: $user-indicators-offset;
bottom: auto;
right: auto;

View File

@ -6,6 +6,7 @@
cursor: pointer;
padding: 0;
text-decoration: none;
color: $color-gray-dark;
}
.chatListItemLink {

View File

@ -2,6 +2,7 @@ import React, { Component } from 'react';
import { injectIntl } from 'react-intl';
import PropTypes from 'prop-types';
import { withRouter } from 'react-router';
import injectWbResizeEvent from '/imports/ui/components/presentation/resize-wrapper/component';
import styles from './styles';
import UserListHeader from './user-list-header/component';
@ -53,10 +54,10 @@ class UserList extends Component {
render() {
return (
<div className={styles.userList}>
<UserListHeader
{/* <UserListHeader
intl={this.props.intl}
compact={this.state.compact}
/>
/> */}
{<UserContent
intl={this.props.intl}
openChats={this.props.openChats}

View File

@ -61,6 +61,7 @@ $user-icons-color-hover: $color-gray;
background-color: $user-list-bg;
color: $user-list-text;
height: 100vh;
padding-top: $md-padding-x;
}
.lists {
@ -77,15 +78,6 @@ $user-icons-color-hover: $color-gray;
flex-shrink: 1;
}
.smallTitle {
font-size: 0.85rem;
font-weight: 600;
text-transform: uppercase;
padding: 0 $sm-padding-x;
margin: 0 0 ($lg-padding-x / 2) 0;
color: $color-gray-light;
}
.participants, .messages {
flex-grow: 0;
display: flex;
@ -94,7 +86,6 @@ $user-icons-color-hover: $color-gray;
}
.messages {
margin-bottom: $lg-padding-x;
}
.participants {
@ -105,6 +96,15 @@ $user-icons-color-hover: $color-gray;
overflow-y: auto;
}
.smallTitle {
font-size: 0.85rem;
font-weight: 600;
text-transform: uppercase;
padding: 0 $sm-padding-x;
margin: ($md-padding-x / 2) 0 0 0;
color: $color-gray-light;
}
.enter, .appear {
opacity: 0.01;
}

View File

@ -1,4 +1,5 @@
@import "/imports/ui/components/user-list/styles.scss";
@import "/imports/ui/stylesheets/mixins/_scrollable";
.content {
@extend %flex-column;
@ -8,4 +9,5 @@
.scrollableList {
@extend %customListFocus;
}
@include scrollbox-vertical();
}

View File

@ -1,12 +1,7 @@
@import "/imports/ui/components/user-list/styles.scss";
.smallTitle {
font-size: 0.85rem;
font-weight: 600;
text-transform: uppercase;
padding: 0 $sm-padding-x;
margin: 0 0 ($lg-padding-x / 2) 0;
color: $color-gray-light;
@extend .smallTitle;
}
.scrollableList {
@ -25,4 +20,4 @@
@extend .lists;
overflow-x: hidden;
flex-shrink: 1;
}
}

View File

@ -104,10 +104,10 @@ class UserParticipants extends Component {
componentDidMount() {
if (!this.props.compact) {
this._usersList.addEventListener('keydown',
this.refScrollContainer.addEventListener('keydown',
event => this.props.rovingIndex(event,
this._usersList,
this._userItems,
this.refScrollContainer,
this.refScrollItems,
this.props.users.length));
}
}
@ -179,10 +179,7 @@ class UserParticipants extends Component {
};
return (
<div
className={styles.participants}
ref={(ref) => { if (ref != null) { this.refScrollContainer = ref; } }}
>
<div className={styles.participants}>
{
!compact ?
<div className={styles.smallTitle} role="banner">
@ -194,7 +191,8 @@ class UserParticipants extends Component {
className={styles.scrollableList}
role="tabpanel"
tabIndex={0}
ref={(ref) => { this._usersList = ref; }}
refScrollContainer
ref={(ref) => { this.refScrollContainer = ref; }}
>
<CSSTransitionGroup
transitionName={listTransition}
@ -207,7 +205,7 @@ class UserParticipants extends Component {
component="div"
className={cx(styles.participantsList, styles.scrollableList)}
>
<div ref={(ref) => { this._userItems = ref; }}>
<div ref={(ref) => { this.refScrollItems = ref; }}>
{
users.map(user => (
<UserListItem