diff --git a/bigbluebutton-html5/imports/ui/components/components-data/users-context/service.js b/bigbluebutton-html5/imports/ui/components/components-data/users-context/service.js new file mode 100644 index 0000000000..5e05471f4c --- /dev/null +++ b/bigbluebutton-html5/imports/ui/components/components-data/users-context/service.js @@ -0,0 +1,31 @@ +import { useState, useContext, useEffect } from 'react'; +import { UsersContext } from '/imports/ui/components/components-data/users-context/context'; + +const USER_JOIN_UPDATE_TIMEOUT = 1000; +let updateTimeout = null; + +export default function useContextUsers() { + const usingUsersContext = useContext(UsersContext); + const { users: contextUsers } = usingUsersContext; + + const [users, setUsers] = useState(null); + const [isReady, setIsReady] = useState(true); + + useEffect(() => { + setIsReady(false); + + if (updateTimeout) { + clearTimeout(updateTimeout); + } + + updateTimeout = setTimeout(() => { + setUsers(contextUsers); + setIsReady(true); + }, USER_JOIN_UPDATE_TIMEOUT); + }, [contextUsers]); + + return { + users, + isReady, + }; +} diff --git a/bigbluebutton-html5/imports/ui/components/lock-viewers/context/container.jsx b/bigbluebutton-html5/imports/ui/components/lock-viewers/context/container.jsx index 302a446aa4..3c1bde6bb2 100644 --- a/bigbluebutton-html5/imports/ui/components/lock-viewers/context/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/lock-viewers/context/container.jsx @@ -2,16 +2,17 @@ import { withTracker } from 'meteor/react-meteor-data'; import Meetings from '/imports/api/meetings'; import Auth from '/imports/ui/services/auth'; import { LockStruct } from './context'; -import { withUsersConsumer } from '/imports/ui/components/components-data/users-context/context'; +import Users from '/imports/api/users'; import { withLockContext } from './withContext'; const ROLE_MODERATOR = Meteor.settings.public.user.role_moderator; -const lockContextContainer = component => withUsersConsumer(withTracker(({ users }) => { +const lockContextContainer = (component) => withTracker(() => { const lockSetting = new LockStruct(); const Meeting = Meetings.findOne({ meetingId: Auth.meetingID }, { fields: { lockSettingsProps: 1 } }); - const User = users[Auth.meetingID][Auth.userID]; + const User = Users.findOne({ userId: Auth.userID, meetingId: Auth.meetingID }, + { fields: { role: 1, locked: 1 } }); const userIsLocked = User.locked && User.role !== ROLE_MODERATOR; const lockSettings = Meeting.lockSettingsProps; @@ -25,6 +26,6 @@ const lockContextContainer = component => withUsersConsumer(withTracker(({ users lockSetting.userLocks.userLockedLayout = userIsLocked && lockSettings.lockedLayout; return lockSetting; -})(withLockContext(component))); +})(withLockContext(component)); export default lockContextContainer; 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 ab9eb951ba..4265bf383a 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 @@ -2,7 +2,6 @@ import React, { Component } from 'react'; import { defineMessages } from 'react-intl'; import PropTypes from 'prop-types'; import Styled from './styles'; -import _ from 'lodash'; import { findDOMNode } from 'react-dom'; import { AutoSizer, @@ -19,7 +18,7 @@ const propTypes = { intl: PropTypes.shape({ formatMessage: PropTypes.func.isRequired, }).isRequired, - currentUser: PropTypes.shape({}).isRequired, + currentUser: PropTypes.shape({}), users: PropTypes.arrayOf(PropTypes.shape({})).isRequired, setEmojiStatus: PropTypes.func.isRequired, clearAllEmojiStatus: PropTypes.func.isRequired, @@ -29,6 +28,7 @@ const propTypes = { const defaultProps = { compact: false, + currentUser: null, }; const intlMessages = defineMessages({ @@ -82,10 +82,8 @@ class UserParticipants extends Component { } } - shouldComponentUpdate(nextProps, nextState) { - const isPropsEqual = _.isEqual(this.props, nextProps); - const isStateEqual = _.isEqual(this.state, nextState); - return !isPropsEqual || !isStateEqual; + shouldComponentUpdate(nextProps) { + return nextProps.isReady; } selectEl(el) { @@ -205,7 +203,7 @@ class UserParticipants extends Component { {users.length} ) - {currentUser.role === ROLE_MODERATOR + {currentUser?.role === ROLE_MODERATOR ? ( { } = UserListService; const { videoUsers, whiteboardUsers } = props; - const usingUsersContext = useContext(UsersContext); - const { users: contextUsers } = usingUsersContext; - const currentUser = contextUsers[Auth.meetingID][Auth.userID]; - const usersArray = Object.values(contextUsers[Auth.meetingID]); - const users = formatUsers(usersArray, videoUsers, whiteboardUsers); + const { users: contextUsers, isReady } = useContextUsers(); + + const currentUser = contextUsers ? contextUsers[Auth.meetingID][Auth.userID] : null; + const usersArray = contextUsers ? Object.values(contextUsers[Auth.meetingID]) : null; + const users = contextUsers ? formatUsers(usersArray, videoUsers, whiteboardUsers) : []; return ( { clearAllEmojiStatus, roving, requestUserInformation, + isReady, ...props, } }