Merge branch 'html5-new-userlist' into html-userlist
This commit is contained in:
commit
ce32ae5b20
@ -16,7 +16,7 @@ addLocaleData([...en, ...es, ...pt]);
|
||||
// Safari sends us en-us instead of en-US
|
||||
let locale = navigator.language.split('-');
|
||||
locale = locale[1] ? `${locale[0]}-${locale[1].toUpperCase()}` : navigator.language;
|
||||
|
||||
// locale = 'pt-BR'; // Set a locale for testing
|
||||
/* TODO: We should load the en first then merge with the en-US
|
||||
(eg: load country translation then region) */
|
||||
let messages = Locales[locale] || Locales['en'] || {};
|
||||
|
@ -116,3 +116,6 @@
|
||||
.icon-bbb-audio-off:before {
|
||||
content: "\e91c";
|
||||
}
|
||||
.rotate-quarter {
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ eventEmitter.on('user_listening_only', function (arg) {
|
||||
|
||||
const handleVoiceEvent = function (arg) {
|
||||
const meetingId = arg.payload.meeting_id;
|
||||
const voiceUser = payload.user.voiceUser;
|
||||
const voiceUser = arg.payload.user.voiceUser;
|
||||
const voiceUserObj = {
|
||||
web_userid: voiceUser.web_userid,
|
||||
listen_only: arg.payload.listen_only,
|
||||
|
@ -141,8 +141,8 @@ eventEmitter.on('get_presentation_info_reply', function (arg) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return arg.callback();
|
||||
}
|
||||
|
||||
return arg.callback();
|
||||
});
|
||||
|
||||
|
@ -1,3 +1,7 @@
|
||||
{
|
||||
"app.home.greeting": "Welcome {name}! Your presentation will begin shortly..."
|
||||
"app.home.greeting": "Welcome {name}! Your presentation will begin shortly...",
|
||||
"app.userlist.participantsTitle": "Participants",
|
||||
"app.userlist.messagesTitle": "Messages",
|
||||
"app.userlist.presenter": "Presenter",
|
||||
"app.userlist.you": "You"
|
||||
}
|
||||
|
@ -1,3 +1,7 @@
|
||||
{
|
||||
"app.home.greeting": "Bem-vindo {name}! Sua aprensentação começará em breve..."
|
||||
"app.home.greeting": "Bem-vindo {name}! Sua aprensentação começará em breve...",
|
||||
"app.userlist.participantsTitle": "Participantes",
|
||||
"app.userlist.messagesTitle": "Mensagens",
|
||||
"app.userlist.presenter": "Apresentador",
|
||||
"app.userlist.you": "Você"
|
||||
}
|
||||
|
@ -4,10 +4,10 @@ import { Router, Route, Redirect, IndexRoute,
|
||||
import { createHistory } from 'history';
|
||||
|
||||
// route components
|
||||
import AppContainer from '../../ui/components/app/container';
|
||||
import {setCredentials, subscribeForData} from '../../ui/components/app/service';
|
||||
import UserListContainer from '../../ui/components/user-list/UserListContainer';
|
||||
import ChatContainer from '../../ui/components/chat/ChatContainer';
|
||||
import AppContainer from '../../ui/components/app/container.jsx';
|
||||
import {setCredentials, subscribeForData} from '../../ui/components/app/service.js';
|
||||
import UserListContainer from '../../ui/components/user-list/container.jsx';
|
||||
import ChatContainer from '../../ui/components/chat/ChatContainer.jsx';
|
||||
|
||||
const browserHistory = useRouterHistory(createHistory)({
|
||||
basename: '/html5client',
|
||||
|
@ -125,6 +125,7 @@ const handledMessageTypes = [
|
||||
'presentation_shared_message',
|
||||
'get_presentation_info_reply',
|
||||
'presentation_page_changed_message',
|
||||
'get_presentation_info_reply',
|
||||
'presentation_removed_message',
|
||||
'get_whiteboard_shapes_reply',
|
||||
'send_whiteboard_shape_message',
|
||||
|
@ -96,10 +96,12 @@ $actionsbar-height: 50px; // TODO: Change to ActionsBar real height
|
||||
.userList {
|
||||
@extend %full-page;
|
||||
z-index: 2;
|
||||
background: green;
|
||||
overflow: hidden;
|
||||
|
||||
@include mq($small-only) {
|
||||
padding-top: $navbar-height;
|
||||
}
|
||||
}
|
||||
|
||||
@include mq($small-only) {
|
||||
padding-top: $navbar-height;
|
||||
|
@ -1,24 +0,0 @@
|
||||
import React, { Component } from 'react';
|
||||
import styles from './styles.scss';
|
||||
import { Link } from 'react-router';
|
||||
|
||||
export default class UserList extends Component {
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<ul>
|
||||
<li><b>USER-LIST</b></li>
|
||||
<li>
|
||||
<Link to="/users/chat">Open Public chat</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link to={`/users/chat/${'fred-dixon'}`}>Open Private Chat With Fred</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link to={`/users/chat/${'tiago-jacobs'}`}>Open Private Chat With Tiago</Link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
import React, { Component } from 'react';
|
||||
import styles from '../styles.scss';
|
||||
import { Link } from 'react-router';
|
||||
import classNames from 'classnames';
|
||||
|
||||
export default class ChatListItem extends Component {
|
||||
render() {
|
||||
|
||||
return (
|
||||
<li tabIndex='0' className={styles.chatListItem}>
|
||||
<div className={styles.chatThumbnail}>
|
||||
<i className="icon-bbb-group-chat"></i>
|
||||
</div>
|
||||
<div className={styles.chatName}>
|
||||
<h3 className={styles.chatNameMain}>Public Chat</h3>
|
||||
</div>
|
||||
<div className={styles.unreadMessages}>
|
||||
<p className={styles.unreadMessagesText}>{Math.round(Math.random()*33)}</p>
|
||||
</div>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
import React, { Component } from 'react';
|
||||
import styles from './styles.scss';
|
||||
import { Link } from 'react-router';
|
||||
import UserListItem from './user-list-item/component.jsx';
|
||||
import ChatListItem from './chat-list-item/component.jsx';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
export default class UserList extends Component {
|
||||
render() {
|
||||
return (
|
||||
<div className={styles.userList}>
|
||||
{this.renderHeader()}
|
||||
{this.renderContent()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderHeader() {
|
||||
return (
|
||||
<div className={styles.header}>
|
||||
<h2 className={styles.headerTitle}>
|
||||
<FormattedMessage
|
||||
id="app.userlist.participantsTitle"
|
||||
description="Title for the Header"
|
||||
defaultMessage="Participants"
|
||||
/>
|
||||
</h2>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
renderContent() {
|
||||
return (
|
||||
<div className={styles.content}>
|
||||
{this.renderMessages()}
|
||||
{this.renderParticipants()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderMessages() {
|
||||
return (
|
||||
<div className={styles.messages}>
|
||||
<h3 className={styles.smallTitle}>
|
||||
<FormattedMessage
|
||||
id="app.userlist.messagesTitle"
|
||||
description="Title of messages list"
|
||||
defaultMessage="Messages"
|
||||
/>
|
||||
</h3>
|
||||
<ul className={styles.chatsList} tabIndex="1">
|
||||
<ChatListItem />
|
||||
</ul>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
renderParticipants() {
|
||||
return (
|
||||
<div className={styles.participants}>
|
||||
<h3 className={styles.smallTitle}>
|
||||
<FormattedMessage
|
||||
id="app.userlist.participantsTitle"
|
||||
description="Title for the Participants list"
|
||||
defaultMessage="Participants"
|
||||
/>
|
||||
({this.props.users.length})
|
||||
</h3>
|
||||
<ul className={styles.participantsList} tabIndex="1">
|
||||
{this.props.users.map(user => <UserListItem accessibilityLabel={'Status abc'} accessible={true} key={user.id} user={user}/>)}
|
||||
</ul>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
@ -1,16 +1,15 @@
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import { createContainer } from 'meteor/react-meteor-data';
|
||||
import Service from './service.js';
|
||||
|
||||
import UserList from './UserList';
|
||||
import UserList from './component.jsx';
|
||||
|
||||
class UserListContainer extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<UserList {...this.props}>
|
||||
<UserList
|
||||
{...this.props}
|
||||
users={this.props.users}>
|
||||
{this.props.children}
|
||||
</UserList>
|
||||
);
|
||||
@ -18,5 +17,6 @@ class UserListContainer extends Component {
|
||||
}
|
||||
|
||||
export default createContainer(() => {
|
||||
return {};
|
||||
const data = Service.mapUsers();
|
||||
return data;
|
||||
}, UserListContainer);
|
@ -0,0 +1,24 @@
|
||||
import Users from '/imports/api/users';
|
||||
import LocalStorage from '/imports/ui/services/storage';
|
||||
|
||||
let mapUsers = function() {
|
||||
let currentUserID = LocalStorage.get('userID');
|
||||
let users = Users.find().map(u => {
|
||||
return {
|
||||
id: u.user.userid,
|
||||
name: u.user.name,
|
||||
isPresenter: u.user.presenter,
|
||||
isModerator: u.user.role === "MODERATOR",
|
||||
isCurrent: u.user.userid === currentUserID,
|
||||
isVoiceUser: u.user.voiceUser.joined,
|
||||
isListenOnly: u.user.listenOnly,
|
||||
isSharingWebcam: u.user.webcam_stream.length
|
||||
};
|
||||
});
|
||||
|
||||
return {
|
||||
users: users
|
||||
};
|
||||
};
|
||||
|
||||
export default { mapUsers };
|
@ -0,0 +1,201 @@
|
||||
@import '../../stylesheets/variables/palette';
|
||||
|
||||
.flex-column {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
}
|
||||
|
||||
.zero-margin {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.header {
|
||||
@extend .flex-column;
|
||||
justify-content: center;
|
||||
min-height: 3rem;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.headerTitle {
|
||||
font-size: 1rem;
|
||||
margin-left: 30px;
|
||||
}
|
||||
|
||||
.content {
|
||||
@extend .flex-column;
|
||||
flex-grow: 9;
|
||||
}
|
||||
|
||||
.unreadMessages {
|
||||
@extend .flex-column;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.unreadMessagesText {
|
||||
@extend .flex-column;
|
||||
@extend .zero-margin;
|
||||
justify-content: center;
|
||||
color: $color-white;
|
||||
height: 1.3rem;
|
||||
padding: 0 8px;
|
||||
text-align: center;
|
||||
border-radius: 0.5rem/50%;
|
||||
font-size: 0.8rem;
|
||||
background-color: $color-danger;
|
||||
}
|
||||
|
||||
.userList {
|
||||
@extend .flex-column;
|
||||
justify-content: flex-start;
|
||||
background-color: $color-white;
|
||||
color: $color-gray-dark;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.lists {
|
||||
@extend .flex-column;
|
||||
@extend .zero-margin;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.participantsList,
|
||||
.chatsList {
|
||||
@extend .lists;
|
||||
}
|
||||
|
||||
.userListItem,
|
||||
.chatListItem {
|
||||
padding: 5px;
|
||||
padding-left: 15px;
|
||||
padding-right: 10px;
|
||||
margin-left: 15px;
|
||||
margin-top: 10px;
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
border-top-left-radius: 5px;
|
||||
border-bottom-left-radius: 5px;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: darken($color-white, 7%);
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.chatThumbnail {
|
||||
@extend .flex-column;
|
||||
justify-content: center;
|
||||
flex-basis: 30px;
|
||||
height: 30px;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.chatName {
|
||||
@extend .flex-column;
|
||||
flex-grow: 1;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.chatNameMain {
|
||||
@extend .zero-margin;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.thumbnail {
|
||||
@extend .flex-column;
|
||||
flex-basis: 2rem;
|
||||
height: 2rem;
|
||||
justify-content: center;
|
||||
font-size: 1.05rem;
|
||||
text-align: center;
|
||||
border-radius: 20px;
|
||||
border: 2px solid $color-gray-light;
|
||||
color: $color-gray-light;
|
||||
}
|
||||
|
||||
.thumbnailContainer {
|
||||
@extend .flex-column;
|
||||
flex-basis: 2rem;
|
||||
height: 2rem;
|
||||
justify-content: center;
|
||||
border-radius: 20px;
|
||||
}
|
||||
|
||||
.voiceUser{
|
||||
background-color: $color-success;
|
||||
color: $color-white;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.presenter {
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.moderator {
|
||||
border: none;
|
||||
color: $color-white;
|
||||
background-color: $color-primary;
|
||||
}
|
||||
|
||||
.userName {
|
||||
@extend .flex-column;
|
||||
flex-grow: 1;
|
||||
margin-left: 15px;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.userNameMain {
|
||||
font-size: 0.9rem;
|
||||
@extend .zero-margin;
|
||||
}
|
||||
|
||||
.userNameSub {
|
||||
@extend .zero-margin;
|
||||
font-size: 0.8rem;
|
||||
font-style: italic;
|
||||
color: $color-gray-light;
|
||||
}
|
||||
|
||||
.userIcons {
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
justify-content: space-between;
|
||||
text-align: right;
|
||||
font-size: 1rem;
|
||||
flex-basis: 4rem;
|
||||
color: $color-gray-light;
|
||||
}
|
||||
|
||||
.userIconsContainer {
|
||||
@extend .flex-column;
|
||||
text-align: center;
|
||||
flex-basis: 1rem;
|
||||
justify-content: center;
|
||||
transition: 0.3s all;
|
||||
&:hover,
|
||||
&:focus {
|
||||
color: $color-gray;
|
||||
}
|
||||
}
|
||||
|
||||
.smallTitle {
|
||||
margin-bottom: 0;
|
||||
color: $color-text;
|
||||
font-size: 0.9rem;
|
||||
text-transform: uppercase;
|
||||
margin: 10px 30px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.scrollable {
|
||||
overflow: auto;
|
||||
}
|
@ -0,0 +1,94 @@
|
||||
import React, { Component } from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import styles from '../styles.scss';
|
||||
import { Link } from 'react-router';
|
||||
import classNames from 'classnames/bind';
|
||||
let cx = classNames.bind(styles);
|
||||
|
||||
export default class ChatListItem extends Component {
|
||||
render() {
|
||||
return (
|
||||
<li tabIndex='0' className={styles.userListItem}>
|
||||
{this.renderThumbnail()}
|
||||
{this.renderUserName()}
|
||||
{this.renderUserIcons()}
|
||||
</li>
|
||||
);
|
||||
}
|
||||
|
||||
renderThumbnail() {
|
||||
let user = this.props.user;
|
||||
|
||||
let thumbnailClasses = {};
|
||||
thumbnailClasses[styles.presenter] = user.isPresenter;
|
||||
thumbnailClasses[styles.voiceUser] = user.isVoiceUser;
|
||||
thumbnailClasses[styles.moderator] = user.isModerator;
|
||||
thumbnailClasses[styles.image] = user.image;
|
||||
|
||||
return (
|
||||
<div className={cx(thumbnailClasses, styles.thumbnail)}>
|
||||
{user.name.slice(0, 1)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
renderUserName() {
|
||||
let user = this.props.user;
|
||||
|
||||
let userNameSub = null;
|
||||
if(user.isPresenter) {
|
||||
userNameSub = (
|
||||
<p className={styles.userNameSub}>
|
||||
<FormattedMessage
|
||||
id="app.userlist.presenter"
|
||||
description="Title for the Header"
|
||||
defaultMessage="Participants"
|
||||
/>
|
||||
</p>
|
||||
);
|
||||
} else if(user.isCurrent) {
|
||||
userNameSub = (
|
||||
<p className={styles.userNameSub}>
|
||||
(<FormattedMessage
|
||||
id="app.userlist.you"
|
||||
description="Title for the Header"
|
||||
defaultMessage="Participants"
|
||||
/>)
|
||||
</p>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.userName}>
|
||||
<h3 className={styles.userNameMain}>
|
||||
{user.name}
|
||||
</h3>
|
||||
{userNameSub}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
renderUserIcons() {
|
||||
let user = this.props.user;
|
||||
|
||||
let audioChatIcons = null;
|
||||
|
||||
if (user.isVoiceUser || user.isListenOnly) {
|
||||
audioChatIcons = user.isListenOnly ? <i className='icon-bbb-listen'></i> : <i className='icon-bbb-audio'></i>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.userIcons}>
|
||||
<span className={styles.userIconsContainer}>
|
||||
{user.isSharingWebcam ? <i className='icon-bbb-video'></i> : null}
|
||||
</span>
|
||||
<span className={styles.userIconsContainer}>
|
||||
{audioChatIcons}
|
||||
</span>
|
||||
<span className={styles.userIconsContainer}>
|
||||
<i className='icon-bbb-more rotate-quarter'></i>
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
15
bigbluebutton-html5/imports/ui/services/storage/index.js
Normal file
15
bigbluebutton-html5/imports/ui/services/storage/index.js
Normal file
@ -0,0 +1,15 @@
|
||||
const STORAGE = localStorage;
|
||||
const PREFIX = 'bbb_';
|
||||
|
||||
function get(key) {
|
||||
return STORAGE.getItem(key);
|
||||
}
|
||||
|
||||
function set(key) {
|
||||
STORAGE.setItem(key);
|
||||
}
|
||||
|
||||
export default {
|
||||
get,
|
||||
set
|
||||
}
|
Loading…
Reference in New Issue
Block a user