diff --git a/bigbluebutton-html5/imports/ui/components/modal/service.js b/bigbluebutton-html5/imports/ui/components/modal/service.js index d920ec8390784fe883de0e191093e5ec710b2e25..f8427302455b59b4968f1362838555045ef6c13a 100644 --- a/bigbluebutton-html5/imports/ui/components/modal/service.js +++ b/bigbluebutton-html5/imports/ui/components/modal/service.js @@ -1,5 +1,5 @@ import { Tracker } from 'meteor/tracker'; -import React, { Component } from 'react'; +import React, { PureComponent } from 'react'; const currentModal = { component: null, @@ -19,7 +19,7 @@ export const getModal = () => { }; export const withModalMounter = ComponentToWrap => - class ModalMounterWrapper extends Component { + class ModalMounterWrapper extends PureComponent { static mount(modalComponent) { showModal(null); // defer the execution to a subsequent event loop diff --git a/bigbluebutton-html5/imports/ui/components/nav-bar/component.jsx b/bigbluebutton-html5/imports/ui/components/nav-bar/component.jsx index fb8ae22b3ab6542d7f53036d519838f999d07bab..d4a16804c486417d0bb6d9d961ada84ec4015066 100755 --- a/bigbluebutton-html5/imports/ui/components/nav-bar/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/nav-bar/component.jsx @@ -1,4 +1,4 @@ -import React, { Component } from 'react'; +import React, { PureComponent } from 'react'; import PropTypes from 'prop-types'; import _ from 'lodash'; import cx from 'classnames'; @@ -67,7 +67,7 @@ const openBreakoutJoinConfirmation = (breakout, breakoutName, mountModal) => const closeBreakoutJoinConfirmation = mountModal => mountModal(null); -class NavBar extends Component { +class NavBar extends PureComponent { constructor(props) { super(props); diff --git a/bigbluebutton-html5/imports/ui/components/nav-bar/settings-dropdown/component.jsx b/bigbluebutton-html5/imports/ui/components/nav-bar/settings-dropdown/component.jsx index 108b08ce51ebd79e96d65133a33e36c2deef8d87..5b263c094f0d5be24a75e12ef8481963243fe723 100755 --- a/bigbluebutton-html5/imports/ui/components/nav-bar/settings-dropdown/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/nav-bar/settings-dropdown/component.jsx @@ -1,4 +1,4 @@ -import React, { Component } from 'react'; +import React, { PureComponent } from 'react'; import { defineMessages, injectIntl } from 'react-intl'; import cx from 'classnames'; import _ from 'lodash'; @@ -81,7 +81,7 @@ const intlMessages = defineMessages({ }, }); -class SettingsDropdown extends Component { +class SettingsDropdown extends PureComponent { constructor(props) { super(props); @@ -98,7 +98,7 @@ class SettingsDropdown extends Component { const { fullscreenLabel, fullscreenDesc, fullscreenIcon } = this.checkFullscreen(this.props); const { showHelpButton: helpButton } = Meteor.settings.public.app; - this.menuItems =_.compact( [(<DropdownListItem + this.menuItems = _.compact([(<DropdownListItem key={_.uniqueId('list-item-')} icon={fullscreenIcon} label={fullscreenLabel} @@ -142,14 +142,12 @@ class SettingsDropdown extends Component { description={intl.formatMessage(intlMessages.leaveSessionDesc)} onClick={() => mountModal(<LogoutConfirmationContainer />)} />), - ]) + ]); // Removes fullscreen button if not on Android if (!isAndroid) { this.menuItems.shift(); } - - } componentWillReceiveProps(nextProps) { diff --git a/bigbluebutton-html5/imports/ui/components/nav-bar/settings-dropdown/container.jsx b/bigbluebutton-html5/imports/ui/components/nav-bar/settings-dropdown/container.jsx index 6a13b39a6e9d209806b96997dfa2f84dd4bff391..9036ae76a533e4c06d5c3ff5a22c88b60996b203 100755 --- a/bigbluebutton-html5/imports/ui/components/nav-bar/settings-dropdown/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/nav-bar/settings-dropdown/container.jsx @@ -1,9 +1,9 @@ -import React, { Component } from 'react'; +import React, { PureComponent } from 'react'; import browser from 'browser-detect'; import SettingsDropdown from './component'; import { toggleFullScreen } from './service'; -export default class SettingsDropdownContainer extends Component { +export default class SettingsDropdownContainer extends PureComponent { constructor(props) { super(props); @@ -51,7 +51,7 @@ export default class SettingsDropdownContainer extends Component { render() { const handleToggleFullscreen = toggleFullScreen; - const isFullScreen = this.state.isFullScreen; + const { isFullScreen } = this.state; const result = browser(); const isAndroid = (result && result.os) ? result.os.includes('Android') : false; diff --git a/bigbluebutton-html5/imports/ui/components/user-list/component.jsx b/bigbluebutton-html5/imports/ui/components/user-list/component.jsx index 3643ae31703c19c152a8f0ce6649cce9f9d5d920..8b6c91d3956da8cae04e7840a65f0f58a8845e2c 100755 --- a/bigbluebutton-html5/imports/ui/components/user-list/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/component.jsx @@ -1,4 +1,4 @@ -import React, { Component } from 'react'; +import React, { PureComponent } from 'react'; import { injectIntl } from 'react-intl'; import PropTypes from 'prop-types'; import injectWbResizeEvent from '/imports/ui/components/presentation/resize-wrapper/component'; @@ -8,13 +8,14 @@ import UserContentContainer from './user-list-content/container'; const propTypes = { openChats: PropTypes.arrayOf(String).isRequired, - users: PropTypes.arrayOf(Object).isRequired, compact: PropTypes.bool, intl: PropTypes.shape({ formatMessage: PropTypes.func.isRequired, }).isRequired, currentUser: PropTypes.shape({}).isRequired, - meeting: PropTypes.shape({}), + CustomLogoUrl: PropTypes.string.isRequired, + handleEmojiChange: PropTypes.func.isRequired, + getUsersId: PropTypes.func.isRequired, isBreakoutRoom: PropTypes.bool, getAvailableActions: PropTypes.func.isRequired, normalizeEmojiName: PropTypes.func.isRequired, @@ -35,17 +36,13 @@ const propTypes = { const defaultProps = { compact: false, isBreakoutRoom: false, - // This one is kinda tricky, meteor takes sometime to fetch the data and passing down - // So the first time its create, the meeting comes as null, sending an error to the client. - meeting: {}, }; -class UserList extends Component { +class UserList extends PureComponent { render() { const { intl, openChats, - users, compact, currentUser, isBreakoutRoom, @@ -56,7 +53,6 @@ class UserList extends Component { muteAllUsers, muteAllExceptPresenter, changeRole, - meeting, getAvailableActions, normalizeEmojiName, isMeetingLocked, @@ -69,6 +65,7 @@ class UserList extends Component { getEmoji, showBranding, hasBreakoutRoom, + getUsersId, } = this.props; return ( @@ -83,7 +80,6 @@ class UserList extends Component { {...{ intl, openChats, - users, compact, currentUser, isBreakoutRoom, @@ -94,7 +90,6 @@ class UserList extends Component { muteAllUsers, muteAllExceptPresenter, changeRole, - meeting, getAvailableActions, normalizeEmojiName, isMeetingLocked, @@ -105,6 +100,7 @@ class UserList extends Component { getEmojiList, getEmoji, hasBreakoutRoom, + getUsersId, } } />} diff --git a/bigbluebutton-html5/imports/ui/components/user-list/container.jsx b/bigbluebutton-html5/imports/ui/components/user-list/container.jsx index c6d4b916d8fa732c049f8846cea2f2e03c3e7be6..8599e4c68d082e6751bfb0d8ae677903bf2c5bb9 100755 --- a/bigbluebutton-html5/imports/ui/components/user-list/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/container.jsx @@ -2,16 +2,14 @@ import React from 'react'; import PropTypes from 'prop-types'; import { withTracker } from 'meteor/react-meteor-data'; import { meetingIsBreakout } from '/imports/ui/components/app/service'; -import Meetings from '/imports/api/meetings'; import getFromUserSettings from '/imports/ui/services/users-settings'; import Service from './service'; import UserList from './component'; const propTypes = { openChats: PropTypes.arrayOf(String).isRequired, - users: PropTypes.arrayOf(Object).isRequired, currentUser: PropTypes.shape({}).isRequired, - meeting: PropTypes.shape({}).isRequired, + getUsersId: PropTypes.func.isRequired, isBreakoutRoom: PropTypes.bool.isRequired, getAvailableActions: PropTypes.func.isRequired, normalizeEmojiName: PropTypes.func.isRequired, @@ -33,9 +31,8 @@ const UserListContainer = props => <UserList {...props} />; UserListContainer.propTypes = propTypes; export default withTracker(({ chatID, compact }) => ({ - users: Service.getUsers(), - meeting: Meetings.findOne({}), hasBreakoutRoom: Service.hasBreakoutRoom(), + getUsersId: Service.getUsersId, currentUser: Service.getCurrentUser(), openChats: Service.getOpenChats(chatID), isBreakoutRoom: meetingIsBreakout(), diff --git a/bigbluebutton-html5/imports/ui/components/user-list/service.js b/bigbluebutton-html5/imports/ui/components/user-list/service.js index 3678f7d61dfff45b7f6ec8f30e5e16e0458d2f74..dbae3223c6cf128e43ac7f5119f273706d1541d9 100755 --- a/bigbluebutton-html5/imports/ui/components/user-list/service.js +++ b/bigbluebutton-html5/imports/ui/components/user-list/service.js @@ -188,6 +188,8 @@ const getUsers = () => { .sort(sortUsers); }; +const getUsersId = () => getUsers().map(u => u.id); + const hasBreakoutRoom = () => Breakouts.find({ parentMeetingId: Auth.meetingID }).count() > 0; const getOpenChats = (chatID) => { @@ -443,6 +445,7 @@ export default { muteAllExceptPresenter, changeRole, getUsers, + getUsersId, getOpenChats, getCurrentUser, getAvailableActions, diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/breakout-room/component.jsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/breakout-room/component.jsx index b0df572d51606acd8334bad0fa48b803adb27d11..5638e6ce9d2fb05eb41a9c1dca4a13e163d305ce 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/breakout-room/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/breakout-room/component.jsx @@ -1,5 +1,4 @@ -import React, { Component } from 'react'; -import PropTypes from 'prop-types'; +import React from 'react'; import { defineMessages, injectIntl } from 'react-intl'; import { Session } from 'meteor/session'; import Icon from '/imports/ui/components/icon/component'; diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/component.jsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/component.jsx index 9932dee6e9b7153be7e88948a77808d6351276b9..17188a23ad545946db55e7b762205b9c85fdf38b 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/component.jsx @@ -1,20 +1,18 @@ -import React from 'react'; +import React, { PureComponent } from 'react'; import PropTypes from 'prop-types'; import { styles } from './styles'; -import UserParticipants from './user-participants/component'; +import UserParticipantsContainer from './user-participants/container'; import UserMessages from './user-messages/component'; import UserPolls from './user-polls/component'; import BreakoutRoomItem from './breakout-room/component'; const propTypes = { openChats: PropTypes.arrayOf(String).isRequired, - users: PropTypes.arrayOf(Object).isRequired, compact: PropTypes.bool, intl: PropTypes.shape({ formatMessage: PropTypes.func.isRequired, }).isRequired, currentUser: PropTypes.shape({}).isRequired, - meeting: PropTypes.shape({}), isBreakoutRoom: PropTypes.bool, getAvailableActions: PropTypes.func.isRequired, normalizeEmojiName: PropTypes.func.isRequired, @@ -29,24 +27,23 @@ const propTypes = { changeRole: PropTypes.func.isRequired, roving: PropTypes.func.isRequired, getGroupChatPrivate: PropTypes.func.isRequired, + handleEmojiChange: PropTypes.func.isRequired, + getUsersId: PropTypes.func.isRequired, + pollIsOpen: PropTypes.bool.isRequired, + forcePollOpen: PropTypes.bool.isRequired, }; const defaultProps = { compact: false, isBreakoutRoom: false, - // This one is kinda tricky, meteor takes sometime to fetch the data and passing down - // So the first time its create, the meeting comes as null, sending an error to the client. - meeting: {}, }; -class UserContent extends React.Component { +class UserContent extends PureComponent { render() { const { - users, compact, intl, currentUser, - meeting, isBreakoutRoom, setEmojiStatus, assignPresenter, @@ -68,6 +65,7 @@ class UserContent extends React.Component { pollIsOpen, forcePollOpen, hasBreakoutRoom, + getUsersId, } = this.props; return ( @@ -93,13 +91,11 @@ class UserContent extends React.Component { }} /> <BreakoutRoomItem isPresenter={currentUser.isPresenter} hasBreakoutRoom={hasBreakoutRoom} /> - <UserParticipants + <UserParticipantsContainer {...{ - users, compact, intl, currentUser, - meeting, isBreakoutRoom, setEmojiStatus, assignPresenter, @@ -116,6 +112,7 @@ class UserContent extends React.Component { getEmojiList, getEmoji, getGroupChatPrivate, + getUsersId, }} /> </div> diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/container.jsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/container.jsx index f9daa37e1f0ee3e31ca5e865d0da36af9dad3211..2e85bee5452db9b5b6746acc350c3eaedb38e848 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/container.jsx @@ -3,9 +3,9 @@ import { withTracker } from 'meteor/react-meteor-data'; import { Session } from 'meteor/session'; import UserContent from './component'; -const UserContentContainer = ({ ...props }) => <UserContent {...props} />; +const UserContentContainer = props => <UserContent {...props} />; -export default withTracker(({ }) => ({ +export default withTracker(() => ({ pollIsOpen: Session.equals('isPollOpen', true), forcePollOpen: Session.equals('forcePollOpen', true), }))(UserContentContainer); diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-messages/component.jsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-messages/component.jsx index ca2b28c5a42a10f28fa48003d7750a937186a38d..cfb12a669f8bc5de943898e80ccea13649d3ec04 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-messages/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-messages/component.jsx @@ -1,4 +1,4 @@ -import React, { Component } from 'react'; +import React, { PureComponent } from 'react'; import { TransitionGroup, CSSTransition } from 'react-transition-group'; import PropTypes from 'prop-types'; import { defineMessages } from 'react-intl'; @@ -38,7 +38,7 @@ const intlMessages = defineMessages({ }, }); -class UserMessages extends Component { +class UserMessages extends PureComponent { constructor() { super(); diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/component.jsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/component.jsx index b3907e93290f68d1b38faa39d4140b235196442d..ad4c2ab6cfb4cdc93a9f3db3346ff4a5da826f26 100755 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/component.jsx @@ -4,17 +4,21 @@ import { defineMessages } from 'react-intl'; import PropTypes from 'prop-types'; import cx from 'classnames'; import { styles } from '/imports/ui/components/user-list/user-list-content/styles'; -import UserListItem from './user-list-item/component'; +import _ from 'lodash'; +import UserListItemContainer from './user-list-item/container'; import UserOptionsContainer from './user-options/container'; const propTypes = { - users: PropTypes.arrayOf(Object).isRequired, compact: PropTypes.bool, intl: PropTypes.shape({ formatMessage: PropTypes.func.isRequired, }).isRequired, currentUser: PropTypes.shape({}).isRequired, - meeting: PropTypes.shape({}), + meeting: PropTypes.shape({}).isRequired, + users: PropTypes.arrayOf(PropTypes.string).isRequired, + getGroupChatPrivate: PropTypes.func.isRequired, + handleEmojiChange: PropTypes.func.isRequired, + getUsersId: PropTypes.func.isRequired, isBreakoutRoom: PropTypes.bool, setEmojiStatus: PropTypes.func.isRequired, assignPresenter: PropTypes.func.isRequired, @@ -32,9 +36,6 @@ const propTypes = { const defaultProps = { compact: false, isBreakoutRoom: false, - // This one is kinda tricky, meteor takes sometime to fetch the data and passing down - // So the first time its create, the meeting comes as null, sending an error to the client. - meeting: {}, }; const listTransition = { @@ -83,6 +84,12 @@ class UserParticipants extends Component { } } + shouldComponentUpdate(nextProps, nextState) { + const isPropsEqual = _.isEqual(this.props, nextProps); + const isStateEqual = _.isEqual(this.state, nextState); + return !isPropsEqual || !isStateEqual; + } + componentDidUpdate(prevProps, prevState) { if (this.state.index === -1) { return; @@ -106,57 +113,60 @@ class UserParticipants extends Component { getAvailableActions, normalizeEmojiName, isMeetingLocked, - users, changeRole, assignPresenter, setEmojiStatus, removeUser, toggleVoice, - getGroupChatPrivate, // // TODO check if this is used - handleEmojiChange, // // TODO add to props validation + getGroupChatPrivate, + handleEmojiChange, getEmojiList, getEmoji, + users, } = this.props; let index = -1; - return users.map(user => ( - <CSSTransition - classNames={listTransition} - appear - enter - exit - timeout={0} - component="div" - className={cx(styles.participantsList)} - key={user.id} - > - <div ref={(node) => { this.userRefs[index += 1] = node; }}> - <UserListItem - {...{ - user, - currentUser, - compact, - isBreakoutRoom, - meeting, - getAvailableActions, - normalizeEmojiName, - isMeetingLocked, - handleEmojiChange, - getEmojiList, - getEmoji, - setEmojiStatus, - assignPresenter, - removeUser, - toggleVoice, - changeRole, - getGroupChatPrivate, - }} - getScrollContainerRef={this.getScrollContainerRef} - /> - </div> - </CSSTransition> - )); + const { meetingId } = meeting; + + return users.map(u => + ( + <CSSTransition + classNames={listTransition} + appear + enter + exit + timeout={0} + component="div" + className={cx(styles.participantsList)} + key={u} + > + <div ref={(node) => { this.userRefs[index += 1] = node; }}> + <UserListItemContainer + {...{ + currentUser, + compact, + isBreakoutRoom, + meetingId, + getAvailableActions, + normalizeEmojiName, + isMeetingLocked, + handleEmojiChange, + getEmojiList, + getEmoji, + setEmojiStatus, + assignPresenter, + removeUser, + toggleVoice, + changeRole, + getGroupChatPrivate, + }} + userId={u} + getScrollContainerRef={this.getScrollContainerRef} + /> + </div> + </CSSTransition> + )); } focusUserItem(index) { diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/container.jsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/container.jsx new file mode 100644 index 0000000000000000000000000000000000000000..b5ef848a0d23e708ebcd76bfe65add95a2980a35 --- /dev/null +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/container.jsx @@ -0,0 +1,11 @@ +import React from 'react'; +import { withTracker } from 'meteor/react-meteor-data'; +import Meetings from '/imports/api/meetings'; +import UserParticipants from './component'; + +const UserParticipantsContainer = ({ ...props }) => <UserParticipants {...props} />; + +export default withTracker(({ getUsersId }) => ({ + meeting: Meetings.findOne({}), + users: getUsersId(), +}))(UserParticipantsContainer); diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-item/component.jsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-item/component.jsx index 54d5fa0d7b24d8bdb4f50fe855d5dfd3e4d7990c..1bafe9249b99d8ba95574c8ce1bb576e4c6cf63d 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-item/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-item/component.jsx @@ -1,17 +1,10 @@ -import React, { Component } from 'react'; +import React, { PureComponent } from 'react'; import PropTypes from 'prop-types'; import { injectIntl } from 'react-intl'; +import _ from 'lodash'; import UserDropdown from './user-dropdown/component'; const propTypes = { - user: PropTypes.shape({ - name: PropTypes.string.isRequired, - isPresenter: PropTypes.bool.isRequired, - isVoiceUser: PropTypes.bool.isRequired, - isModerator: PropTypes.bool.isRequired, - image: PropTypes.string, - }).isRequired, - currentUser: PropTypes.shape({ id: PropTypes.string.isRequired, }).isRequired, @@ -22,7 +15,6 @@ const propTypes = { }).isRequired, isBreakoutRoom: PropTypes.bool, getAvailableActions: PropTypes.func.isRequired, - meeting: PropTypes.shape({}).isRequired, isMeetingLocked: PropTypes.func.isRequired, normalizeEmojiName: PropTypes.func.isRequired, getScrollContainerRef: PropTypes.func.isRequired, @@ -32,9 +24,10 @@ const defaultProps = { isBreakoutRoom: false, }; -class UserListItem extends Component { +class UserListItem extends PureComponent { render() { const { + user, assignPresenter, compact, currentUser, @@ -48,12 +41,11 @@ class UserListItem extends Component { intl, isBreakoutRoom, isMeetingLocked, - meeting, + meetingId, normalizeEmojiName, removeUser, setEmojiStatus, toggleVoice, - user, } = this.props; const contents = (<UserDropdown @@ -71,7 +63,7 @@ class UserListItem extends Component { intl, isBreakoutRoom, isMeetingLocked, - meeting, + meetingId, normalizeEmojiName, removeUser, setEmojiStatus, diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-item/container.jsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-item/container.jsx new file mode 100644 index 0000000000000000000000000000000000000000..e27d54154b162b2d11c859833d53dbcdde184cf6 --- /dev/null +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-item/container.jsx @@ -0,0 +1,11 @@ +import React from 'react'; +import { withTracker } from 'meteor/react-meteor-data'; +import Users from '/imports/api/users'; +import mapUser from '/imports/ui/services/user/mapUser'; +import UserListItem from './component'; + +const UserListItemContainer = props => <UserListItem {...props} />; + +export default withTracker(({ userId }) => ({ + user: mapUser(Users.findOne({ userId })), +}))(UserListItemContainer); diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-item/user-dropdown/component.jsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-item/user-dropdown/component.jsx index ccb9aa475ba187dbb71c652cc522616dfd268f49..8285826f0fa8fa836e2d79281326d95df1553093 100755 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-item/user-dropdown/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-item/user-dropdown/component.jsx @@ -1,4 +1,4 @@ -import React, { Component } from 'react'; +import React, { PureComponent } from 'react'; import { defineMessages } from 'react-intl'; import PropTypes from 'prop-types'; import { findDOMNode } from 'react-dom'; @@ -90,12 +90,11 @@ const propTypes = { formatMessage: PropTypes.func.isRequired, }).isRequired, normalizeEmojiName: PropTypes.func.isRequired, - meeting: PropTypes.shape({}).isRequired, isMeetingLocked: PropTypes.func.isRequired, getScrollContainerRef: PropTypes.func.isRequired, }; -class UserDropdown extends Component { +class UserDropdown extends PureComponent { /** * Return true if the content fit on the screen, false otherwise. * @@ -436,7 +435,7 @@ class UserDropdown extends Component { user, intl, isMeetingLocked, - meeting, + meetingId, } = this.props; const { @@ -484,7 +483,7 @@ class UserDropdown extends Component { user, compact, intl, - meeting, + meetingId, isMeetingLocked, userAriaLabel, isActionsOpen, diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-item/user-name/component.jsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-item/user-name/component.jsx index 231171c78e895fc8730fd2db8b1e7c113285e82e..d3c7e26181ae2c17ea2df0ebd3b6561a17c94ec7 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-item/user-name/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-list-item/user-name/component.jsx @@ -43,9 +43,10 @@ const propTypes = { intl: PropTypes.shape({ formatMessage: PropTypes.func.isRequired, }).isRequired, - meeting: PropTypes.shape({}).isRequired, isMeetingLocked: PropTypes.func.isRequired, userAriaLabel: PropTypes.string.isRequired, + meetingId: PropTypes.string.isRequired, + isActionsOpen: PropTypes.bool.isRequired, }; const UserName = (props) => { @@ -54,7 +55,7 @@ const UserName = (props) => { intl, compact, isMeetingLocked, - meeting, + meetingId, userAriaLabel, isActionsOpen, } = props; @@ -69,7 +70,7 @@ const UserName = (props) => { return null; } - if (isMeetingLocked(meeting.meetingId) && user.isLocked) { + if (isMeetingLocked(meetingId) && user.isLocked) { userNameSub.push(<span> <Icon iconName="lock" /> {intl.formatMessage(messages.locked)} @@ -81,7 +82,12 @@ const UserName = (props) => { } return ( - <div className={styles.userName} role="button" aria-label={userAriaLabel} aria-expanded={isActionsOpen}> + <div + className={styles.userName} + role="button" + aria-label={userAriaLabel} + aria-expanded={isActionsOpen} + > <span className={styles.userNameMain}> {user.name} <i>{(user.isCurrent) ? `(${intl.formatMessage(messages.you)})` : ''}</i> </span> @@ -90,7 +96,7 @@ const UserName = (props) => { <span className={styles.userNameSub}> {userNameSub.reduce((prev, curr) => [prev, ' | ', curr])} </span> - : null + : null } </div> ); diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-options/component.jsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-options/component.jsx index 3e689940efa29dc8d15164b34155a0cea5c0f528..2f4e7eb515e5d3198cdac665b38bf58370fce887 100755 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-options/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-options/component.jsx @@ -1,4 +1,4 @@ -import React, { Component } from 'react'; +import React, { PureComponent } from 'react'; import PropTypes from 'prop-types'; import { defineMessages, injectIntl } from 'react-intl'; import _ from 'lodash'; @@ -69,7 +69,7 @@ const intlMessages = defineMessages({ }, }); -class UserOptions extends Component { +class UserOptions extends PureComponent { constructor(props) { super(props); diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-options/container.jsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-options/container.jsx index 59561dab0d68b6c8b63d9e3d42f5b3cd2899ce1f..03872beb031be7e797ff390ee66a27ae42118f9b 100755 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-options/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-participants/user-options/container.jsx @@ -1,4 +1,4 @@ -import React, { Component } from 'react'; +import React, { PureComponent } from 'react'; import PropTypes from 'prop-types'; import logger from '/imports/startup/client/logger'; import Auth from '/imports/ui/services/auth'; @@ -15,7 +15,7 @@ const propTypes = { setEmojiStatus: PropTypes.func.isRequired, }; -export default class UserOptionsContainer extends Component { +export default class UserOptionsContainer extends PureComponent { constructor(props) { super(props); const meeting = Meetings.findOne({ meetingId: Auth.meetingID }); diff --git a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-polls/component.jsx b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-polls/component.jsx index 1d9098daea4f4812309daf89f8acf633d16eefd2..f0776f82536b937f6f9ffec1c3ef4d8856b4c6c0 100644 --- a/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-polls/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/user-list-content/user-polls/component.jsx @@ -1,4 +1,4 @@ -import React, { Component } from 'react'; +import React, { PureComponent } from 'react'; import _ from 'lodash'; import { defineMessages, injectIntl } from 'react-intl'; import Icon from '/imports/ui/components/icon/component'; @@ -12,11 +12,7 @@ const intlMessages = defineMessages({ }, }); -class UserPolls extends Component { - constructor(props) { - super(props); - } - +class UserPolls extends PureComponent { render() { const { intl, diff --git a/bigbluebutton-html5/package-lock.json b/bigbluebutton-html5/package-lock.json index 7b6939da5fc45d887f0f37b812eff814b4442f5c..4d75af4431362eaa3ce1dd8433613d3296e6de3b 100755 --- a/bigbluebutton-html5/package-lock.json +++ b/bigbluebutton-html5/package-lock.json @@ -6085,4 +6085,4 @@ } } } -} +} \ No newline at end of file