diff --git a/bigbluebutton-html5/imports/api/meetings/server/modifiers/removeMeeting.js b/bigbluebutton-html5/imports/api/meetings/server/modifiers/removeMeeting.js index 5613e739bd498338b3fb83c5351ae76bc0df00db..f75c067da62b45bdb1f86b67b9f7236e52b44432 100755 --- a/bigbluebutton-html5/imports/api/meetings/server/modifiers/removeMeeting.js +++ b/bigbluebutton-html5/imports/api/meetings/server/modifiers/removeMeeting.js @@ -2,6 +2,7 @@ import Meetings from '/imports/api/meetings'; import Logger from '/imports/startup/server/logger'; import clearUsers from '/imports/api/users/server/modifiers/clearUsers'; +import clearUsersSettings from '/imports/api/users-settings/server/modifiers/clearUsersSettings'; import clearGroupChat from '/imports/api/group-chat/server/modifiers/clearGroupChat'; import clearBreakouts from '/imports/api/breakouts/server/modifiers/clearBreakouts'; import clearAnnotations from '/imports/api/annotations/server/modifiers/clearAnnotations'; @@ -22,6 +23,7 @@ export default function removeMeeting(meetingId) { clearAnnotations(meetingId); clearSlides(meetingId); clearUsers(meetingId); + clearUsersSettings(meetingId); clearVoiceUsers(meetingId); return Logger.info(`Cleared Meetings with id ${meetingId}`); diff --git a/bigbluebutton-html5/imports/api/users-settings/index.js b/bigbluebutton-html5/imports/api/users-settings/index.js new file mode 100644 index 0000000000000000000000000000000000000000..fc9e49a53e1f8fafb18595e69a7cd40e8b382f49 --- /dev/null +++ b/bigbluebutton-html5/imports/api/users-settings/index.js @@ -0,0 +1,11 @@ +import { Meteor } from 'meteor/meteor'; + +const UserSettings = new Mongo.Collection('users-settings'); + +if (Meteor.isServer) { + UserSettings._ensureIndex({ + meetingId: 1, userId: 1, + }); +} + +export default UserSettings; diff --git a/bigbluebutton-html5/imports/api/users-settings/server/index.js b/bigbluebutton-html5/imports/api/users-settings/server/index.js new file mode 100644 index 0000000000000000000000000000000000000000..cb2e66644f3c19b6fa865fa348de96a9281aa51f --- /dev/null +++ b/bigbluebutton-html5/imports/api/users-settings/server/index.js @@ -0,0 +1,2 @@ +import './methods'; +import './publishers'; diff --git a/bigbluebutton-html5/imports/api/users-settings/server/methods.js b/bigbluebutton-html5/imports/api/users-settings/server/methods.js new file mode 100644 index 0000000000000000000000000000000000000000..85bcb7d1b6acc37f5606e38fce6a106be1650e93 --- /dev/null +++ b/bigbluebutton-html5/imports/api/users-settings/server/methods.js @@ -0,0 +1,6 @@ +import { Meteor } from 'meteor/meteor'; +import addUserSettings from './methods/addUserSettings'; + +Meteor.methods({ + addUserSettings, +}); diff --git a/bigbluebutton-html5/imports/api/users-settings/server/methods/addUserSettings.js b/bigbluebutton-html5/imports/api/users-settings/server/methods/addUserSettings.js new file mode 100644 index 0000000000000000000000000000000000000000..23e12c888a8633f2b1be0dca693e84cf47972a4e --- /dev/null +++ b/bigbluebutton-html5/imports/api/users-settings/server/methods/addUserSettings.js @@ -0,0 +1,53 @@ +import { Meteor } from 'meteor/meteor'; +import { check } from 'meteor/check'; +import addUserSetting from '/imports/api/users-settings/server/modifiers/addUserSetting'; + +export default function addUserSettings(credentials, meetingId, userId, settings) { + check(meetingId, String); + check(userId, String); + check(settings, [Object]); + + const customData = settings.reduce((acc, data) => { + const key = Object.keys(data).shift(); + + const handledHTML5Parameters = [ + 'html5recordingbot', + // APP + 'autoJoin', + 'listenOnlyMode', + 'forceListenOnly', + 'skipCheck', + 'clientTitle', + 'lockOnJoin', // NOT IMPLEMENTED YET + 'askForFeedbackOnLogout', + // BRANDING + 'displayBrandingArea', + // KURENTO + 'enableScreensharing', + 'enableVideo', + 'enableVideoStats', + // WHITEBOARD + ]; + if (!handledHTML5Parameters.includes(key)) { + return acc; + } + + let value = data[key]; + try { + value = JSON.parse(value); + } catch (e) { + console.log('error', `Caught: ${e.message}`); + } + return { ...acc, [key]: value }; + }, {}); + + const settingsAdded = []; + + Object.entries(customData).forEach((el) => { + const setting = el[0]; + const value = el[1]; + settingsAdded.push(addUserSetting(meetingId, userId, setting, value)); + }); + + return settingsAdded; +} diff --git a/bigbluebutton-html5/imports/api/users-settings/server/modifiers/addUserSetting.js b/bigbluebutton-html5/imports/api/users-settings/server/modifiers/addUserSetting.js new file mode 100644 index 0000000000000000000000000000000000000000..bb57cfbf2af03a11c8bafe868bd03628809fba4c --- /dev/null +++ b/bigbluebutton-html5/imports/api/users-settings/server/modifiers/addUserSetting.js @@ -0,0 +1,34 @@ +import { check } from 'meteor/check'; +import UserSettings from '/imports/api/users-settings'; +import Logger from '/imports/startup/server/logger'; + +export default function addUserSetting(meetingId, userId, setting, value) { + check(meetingId, String); + check(userId, String); + check(setting, String); + check(value, Match.Any); + + const selector = { + meetingId, + userId, + setting, + }; + const modifier = { + $set: { + meetingId, + userId, + setting, + value, + }, + }; + + const cb = (err) => { + if (err) { + return Logger.error(`Adding user setting to collection: ${err}`); + } + + return Logger.verbose(`Upserted user setting for meetingId=${meetingId} userId=${userId} setting=${setting}`); + }; + + return UserSettings.upsert(selector, modifier, cb); +} diff --git a/bigbluebutton-html5/imports/api/users-settings/server/modifiers/clearUsersSettings.js b/bigbluebutton-html5/imports/api/users-settings/server/modifiers/clearUsersSettings.js new file mode 100644 index 0000000000000000000000000000000000000000..f1c4dd339046ae8a1f64ceee9e0c10f0e3492747 --- /dev/null +++ b/bigbluebutton-html5/imports/api/users-settings/server/modifiers/clearUsersSettings.js @@ -0,0 +1,6 @@ +import UserSettings from '/imports/api/users-settings'; +import Logger from '/imports/startup/server/logger'; + +export default function clearUsersSettings(meetingId) { + return UserSettings.remove({ meetingId }, Logger.info(`Cleared User Settings (${meetingId})`)); +} diff --git a/bigbluebutton-html5/imports/api/users-settings/server/publishers.js b/bigbluebutton-html5/imports/api/users-settings/server/publishers.js new file mode 100644 index 0000000000000000000000000000000000000000..d03400eb2ad4b892eb1ff69e7d5bb38f3349f29a --- /dev/null +++ b/bigbluebutton-html5/imports/api/users-settings/server/publishers.js @@ -0,0 +1,23 @@ +import { Meteor } from 'meteor/meteor'; +import { check } from 'meteor/check'; +import UserSettings from '/imports/api/users-settings'; +import Logger from '/imports/startup/server/logger'; +import mapToAcl from '/imports/startup/mapToAcl'; + +function userSettings(credentials) { + const { meetingId, requesterUserId } = credentials; + + check(meetingId, String); + check(requesterUserId, String); + + Logger.info(`Publishing user settings for user=${requesterUserId}`); + + return UserSettings.find({ meetingId, userId: requesterUserId }); +} + +function publish(...args) { + const boundUserSettings = userSettings.bind(this); + return mapToAcl('subscriptions.users-settings', boundUserSettings)(args); +} + +Meteor.publish('users-settings', publish); diff --git a/bigbluebutton-html5/imports/startup/client/auth.js b/bigbluebutton-html5/imports/startup/client/auth.js index 2621468a393f665ea7078bdc833a52e3eb65169a..723816d386897db4d825cdc625eb7c25f3e264ee 100755 --- a/bigbluebutton-html5/imports/startup/client/auth.js +++ b/bigbluebutton-html5/imports/startup/client/auth.js @@ -1,14 +1,13 @@ import Auth from '/imports/ui/services/auth'; import SessionStorage from '/imports/ui/services/storage/session'; import { setCustomLogoUrl } from '/imports/ui/components/user-list/service'; -import { log } from '/imports/ui/services/api'; +import { log, makeCall } from '/imports/ui/services/api'; import deviceInfo from '/imports/utils/deviceInfo'; import logger from '/imports/startup/client/logger'; // disconnected and trying to open a new connection const STATUS_CONNECTING = 'connecting'; const METADATA_KEY = 'metadata'; -const CUSTOM_DATA_KEY = 'customdata'; export function joinRouteHandler(nextState, replace, callback) { const { sessionToken } = nextState.location.query; @@ -61,29 +60,11 @@ export function joinRouteHandler(nextState, replace, callback) { return { ...acc, [key]: value }; }, {}) : {}; - const customData = customdata.length - ? customdata.reduce((acc, data) => { - const key = Object.keys(data).shift(); - - const handledHTML5Parameters = [ - 'html5recordingbot', - ]; - if (handledHTML5Parameters.indexOf(key) === -1) { - return acc; - } - - let value = data[key]; - try { - value = JSON.parse(value); - } catch (e) { - log('error', `Caught: ${e.message}`); - } - - return { ...acc, [key]: value }; - }, {}) : {}; + if (customdata.length) { + makeCall('addUserSettings', meetingID, internalUserID, customdata); + } SessionStorage.setItem(METADATA_KEY, metakeys); - SessionStorage.setItem(CUSTOM_DATA_KEY, customData); Auth.set( meetingID, internalUserID, authToken, logoutUrl, diff --git a/bigbluebutton-html5/imports/startup/client/base.jsx b/bigbluebutton-html5/imports/startup/client/base.jsx index afb5e63c05a41ab7bc16ff6ed9341991322c074c..23d9e8f0616c4b463dacba173347c6061ec6651d 100755 --- a/bigbluebutton-html5/imports/startup/client/base.jsx +++ b/bigbluebutton-html5/imports/startup/client/base.jsx @@ -119,7 +119,7 @@ Base.defaultProps = defaultProps; const SUBSCRIPTIONS_NAME = [ 'users', 'meetings', 'polls', 'presentations', 'slides', 'captions', 'breakouts', 'voiceUsers', 'whiteboard-multi-user', 'screenshare', - 'group-chat', 'presentation-pods', + 'group-chat', 'presentation-pods', 'users-settings', ]; const BaseContainer = withRouter(withTracker(({ params, router }) => { diff --git a/bigbluebutton-html5/imports/ui/components/actions-bar/component.jsx b/bigbluebutton-html5/imports/ui/components/actions-bar/component.jsx index ed7a2222bbd15a22a0202518f367b1e330951c40..5d83f32ea91a5e695a4feee1206e15c05c994c97 100755 --- a/bigbluebutton-html5/imports/ui/components/actions-bar/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/actions-bar/component.jsx @@ -18,6 +18,8 @@ class ActionsBar extends React.PureComponent { isUserModerator, recordSettingsList, toggleRecording, + screenSharingCheck, + enableVideo, } = this.props; const { @@ -45,7 +47,7 @@ class ActionsBar extends React.PureComponent { </div> <div className={isUserPresenter ? cx(styles.centerWithActions, actionBarClasses) : styles.center}> <AudioControlsContainer /> - {Meteor.settings.public.kurento.enableVideo ? + {enableVideo ? <JoinVideoOptionsContainer handleJoinVideo={handleJoinVideo} handleCloseVideo={handleExitVideo} @@ -56,6 +58,7 @@ class ActionsBar extends React.PureComponent { handleUnshareScreen, isVideoBroadcasting, isUserPresenter, + screenSharingCheck, }} /> </div> diff --git a/bigbluebutton-html5/imports/ui/components/actions-bar/container.jsx b/bigbluebutton-html5/imports/ui/components/actions-bar/container.jsx index ce90a94c153c5783f6e67c2fb1f101597baed895..c323ba829a794d969562cd7107b00bd5cec44abd 100644 --- a/bigbluebutton-html5/imports/ui/components/actions-bar/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/actions-bar/container.jsx @@ -1,5 +1,6 @@ import React from 'react'; import { withTracker } from 'meteor/react-meteor-data'; +import getFromUserSettings from '/imports/ui/services/users-settings'; import ActionsBar from './component'; import Service from './service'; import VideoService from '../video-provider/service'; @@ -17,4 +18,6 @@ export default withTracker(() => ({ isVideoBroadcasting: isVideoBroadcasting(), recordSettingsList: Service.recordSettingsList(), toggleRecording: Service.toggleRecording, + screenSharingCheck: getFromUserSettings('enableScreensharing', Meteor.settings.public.kurento.enableScreensharing), + enableVideo: getFromUserSettings('enableVideo', Meteor.settings.public.kurento.enableVideo), }))(ActionsBarContainer); diff --git a/bigbluebutton-html5/imports/ui/components/actions-bar/desktop-share/component.jsx b/bigbluebutton-html5/imports/ui/components/actions-bar/desktop-share/component.jsx index 7329d4774cc7afead29ce78a3198c97533577952..4eda188074daf3e13072d23567358e262d838ed4 100755 --- a/bigbluebutton-html5/imports/ui/components/actions-bar/desktop-share/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/actions-bar/desktop-share/component.jsx @@ -13,6 +13,7 @@ const propTypes = { handleShareScreen: PropTypes.func.isRequired, handleUnshareScreen: PropTypes.func.isRequired, isVideoBroadcasting: PropTypes.bool.isRequired, + screenSharingCheck: PropTypes.bool.isRequired, }; const intlMessages = defineMessages({ @@ -43,7 +44,7 @@ const isMobileBrowser = (BROWSER_RESULTS ? BROWSER_RESULTS.mobile : false) || (BROWSER_RESULTS && BROWSER_RESULTS.os ? BROWSER_RESULTS.os.includes('Android') : // mobile flag doesn't always work false); -const screenSharingCheck = Meteor.settings.public.kurento.enableScreensharing; + const ICE_CONNECTION_FAILED = 'ICE connection failed'; const DesktopShare = ({ @@ -52,6 +53,7 @@ const DesktopShare = ({ handleUnshareScreen, isVideoBroadcasting, isUserPresenter, + screenSharingCheck, }) => { const onFail = (error) => { switch (error) { diff --git a/bigbluebutton-html5/imports/ui/components/audio/audio-modal/container.jsx b/bigbluebutton-html5/imports/ui/components/audio/audio-modal/container.jsx index b26d8cc8d7290ecc7bdc344fdf875fbbe75755f5..0a4f97c786aa0fcaddc559ab765aaa949ff0bd6f 100755 --- a/bigbluebutton-html5/imports/ui/components/audio/audio-modal/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/audio/audio-modal/container.jsx @@ -2,6 +2,7 @@ import React from 'react'; import { withTracker } from 'meteor/react-meteor-data'; import { withModalMounter } from '/imports/ui/components/modal/service'; import browser from 'browser-detect'; +import getFromUserSettings from '/imports/ui/services/users-settings'; import AudioModal from './component'; import Service from '../service'; @@ -9,10 +10,13 @@ const AudioModalContainer = props => <AudioModal {...props} />; const APP_CONFIG = Meteor.settings.public.app; -const { listenOnlyMode, forceListenOnly, skipCheck } = APP_CONFIG; -export default withModalMounter(withTracker(({ mountModal }) => - ({ +export default withModalMounter(withTracker(({ mountModal }) => { + const listenOnlyMode = getFromUserSettings('listenOnlyMode', APP_CONFIG.listenOnlyMode); + const forceListenOnly = getFromUserSettings('forceListenOnly', APP_CONFIG.forceListenOnly); + const skipCheck = getFromUserSettings('skipCheck', APP_CONFIG.skipCheck); + + return ({ closeModal: () => { if (!Service.isConnecting()) mountModal(null); }, @@ -58,4 +62,5 @@ export default withModalMounter(withTracker(({ mountModal }) => joinFullAudioEchoTest: !listenOnlyMode && !skipCheck, forceListenOnlyAttendee: listenOnlyMode && forceListenOnly && !Service.isUserModerator(), isIOSChrome: browser().name === 'crios', - }))(AudioModalContainer)); + }); +})(AudioModalContainer)); diff --git a/bigbluebutton-html5/imports/ui/components/audio/container.jsx b/bigbluebutton-html5/imports/ui/components/audio/container.jsx index 3fb0db8597c7a4c89a1e07ddd1b7d1ada622ad2b..112476a3d7f4f097ed50b5a9186ed5d74c43be75 100755 --- a/bigbluebutton-html5/imports/ui/components/audio/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/audio/container.jsx @@ -5,6 +5,7 @@ import { injectIntl, defineMessages } from 'react-intl'; import _ from 'lodash'; import Breakouts from '/imports/api/breakouts'; import { notify } from '/imports/ui/services/notification'; +import getFromUserSettings from '/imports/ui/services/users-settings'; import Service from './service'; import AudioModalContainer from './audio-modal/container'; @@ -77,7 +78,7 @@ let didMountAutoJoin = false; export default withModalMounter(injectIntl(withTracker(({ mountModal, intl }) => { const APP_CONFIG = Meteor.settings.public.app; - const { autoJoin } = APP_CONFIG; + const autoJoin = getFromUserSettings('autoJoin', APP_CONFIG.autoJoin); const openAudioModal = mountModal.bind( null, <AudioModalContainer />, diff --git a/bigbluebutton-html5/imports/ui/components/logout-confirmation/container.jsx b/bigbluebutton-html5/imports/ui/components/logout-confirmation/container.jsx index 05e3fe59ae63a0571408fc9ceebd56501ad91b7c..3bb70c02b42cdb4961c0ddd890049cb51eaf39eb 100755 --- a/bigbluebutton-html5/imports/ui/components/logout-confirmation/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/logout-confirmation/container.jsx @@ -2,6 +2,7 @@ import React from 'react'; import { meetingIsBreakout } from '/imports/ui/components/app/service'; import { withTracker } from 'meteor/react-meteor-data'; import { withRouter } from 'react-router'; +import getFromUserSettings from '/imports/ui/services/users-settings'; import LogoutConfirmation from './component'; import { isModerator, @@ -14,7 +15,7 @@ const LogoutConfirmationContainer = props => ( export default withRouter(withTracker(({ router }) => { const APP_CONFIG = Meteor.settings.public.app; - const shouldShowFeedback = !meetingIsBreakout() && APP_CONFIG.askForFeedbackOnLogout; + const shouldShowFeedback = !meetingIsBreakout() && getFromUserSettings('askForFeedbackOnLogout', APP_CONFIG.askForFeedbackOnLogout); const showFeedback = shouldShowFeedback ? () => router.push('/ended/430') : () => router.push('/logout'); return { diff --git a/bigbluebutton-html5/imports/ui/components/media/container.jsx b/bigbluebutton-html5/imports/ui/components/media/container.jsx index e5bfff06b034a07e836b5d3a55cc9450f8a6e4b5..efb3eb28127bf99106dc534290e982fb4b712733 100755 --- a/bigbluebutton-html5/imports/ui/components/media/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/media/container.jsx @@ -5,6 +5,7 @@ import Settings from '/imports/ui/services/settings'; import { defineMessages, injectIntl } from 'react-intl'; import { notify } from '/imports/ui/services/notification'; import VideoService from '/imports/ui/components/video-provider/service'; +import getFromUserSettings from '/imports/ui/services/users-settings'; import Media from './component'; import MediaService, { getSwapLayout } from './service'; import PresentationPodsContainer from '../presentation-pod/container'; @@ -120,7 +121,7 @@ export default withTracker(() => { data.hideOverlay = hidePresentation; } - const { enableVideo } = Meteor.settings.public.kurento; + const enableVideo = getFromUserSettings('enableVideo', Meteor.settings.public.kurento.enableVideo); const autoShareWebcam = SessionStorage.getItem('metadata').html5autosharewebcam || false; if (enableVideo && autoShareWebcam) { diff --git a/bigbluebutton-html5/imports/ui/components/media/service.js b/bigbluebutton-html5/imports/ui/components/media/service.js index ccb411f7630325a4ff7a873db9df9836e366f568..5b2866c8cb58897bcf0527c79a78479630cd5d56 100755 --- a/bigbluebutton-html5/imports/ui/components/media/service.js +++ b/bigbluebutton-html5/imports/ui/components/media/service.js @@ -6,6 +6,7 @@ import Users from '/imports/api/users'; import Settings from '/imports/ui/services/settings'; import VideoService from '/imports/ui/components/video-provider/service'; import PollingService from '/imports/ui/components/polling/service'; +import getFromUserSettings from '/imports/ui/services/users-settings'; const getPresentationInfo = () => { const currentPresentation = Presentations.findOne({ @@ -24,11 +25,11 @@ function shouldShowWhiteboard() { } function shouldShowScreenshare() { - return isVideoBroadcasting() && Meteor.settings.public.kurento.enableScreensharing; + return isVideoBroadcasting() && getFromUserSettings('enableScreensharing', Meteor.settings.public.kurento.enableScreensharing); } function shouldShowOverlay() { - return Meteor.settings.public.kurento.enableVideo; + return getFromUserSettings('enableVideo', Meteor.settings.public.kurento.enableVideo); } const swapLayout = { diff --git a/bigbluebutton-html5/imports/ui/components/meeting-ended/component.jsx b/bigbluebutton-html5/imports/ui/components/meeting-ended/component.jsx index efcb6d3df9d324426c50486c897d91d3527c341d..60359a8904b1750c27b817b5d3667b1e50173f1b 100755 --- a/bigbluebutton-html5/imports/ui/components/meeting-ended/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/meeting-ended/component.jsx @@ -4,6 +4,7 @@ import PropTypes from 'prop-types'; import { defineMessages, injectIntl } from 'react-intl'; import Auth from '/imports/ui/services/auth'; import Button from '/imports/ui/components/button/component'; +import getFromUserSettings from '/imports/ui/services/users-settings'; import Rating from './rating/component'; import { styles } from './styles'; @@ -82,7 +83,7 @@ class MeetingEnded extends React.PureComponent { }; this.setSelectedStar = this.setSelectedStar.bind(this); this.sendFeedback = this.sendFeedback.bind(this); - this.shouldShowFeedback = Meteor.settings.public.app.askForFeedbackOnLogout; + this.shouldShowFeedback = getFromUserSettings('askForFeedbackOnLogout', Meteor.settings.public.app.askForFeedbackOnLogout); } setSelectedStar(starNumber) { this.setState({ diff --git a/bigbluebutton-html5/imports/ui/components/nav-bar/container.jsx b/bigbluebutton-html5/imports/ui/components/nav-bar/container.jsx index f9ef5610dba9e01767d1008fb48b889bd7af74ad..56796f79ebb1eacb443a0d7ddf618145eea9d203 100755 --- a/bigbluebutton-html5/imports/ui/components/nav-bar/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/nav-bar/container.jsx @@ -5,6 +5,7 @@ import { withRouter } from 'react-router'; import Meetings from '/imports/api/meetings'; import Auth from '/imports/ui/services/auth'; import { meetingIsBreakout } from '/imports/ui/components/app/service'; +import getFromUserSettings from '/imports/ui/services/users-settings'; import userListService from '../user-list/service'; import ChatService from '../chat/service'; import Service from './service'; @@ -12,7 +13,6 @@ import NavBar from './component'; const PUBLIC_CONFIG = Meteor.settings.public; const PUBLIC_GROUP_CHAT_ID = PUBLIC_CONFIG.chat.public_group_id; -const CLIENT_TITLE = PUBLIC_CONFIG.app.clientTitle; const NavBarContainer = ({ children, ...props }) => ( <NavBar {...props}> @@ -21,6 +21,8 @@ const NavBarContainer = ({ children, ...props }) => ( ); export default withRouter(withTracker(({ location, router }) => { + const CLIENT_TITLE = getFromUserSettings('clientTitle', PUBLIC_CONFIG.app.clientTitle); + let meetingTitle; let meetingRecorded; diff --git a/bigbluebutton-html5/imports/ui/components/user-list/component.jsx b/bigbluebutton-html5/imports/ui/components/user-list/component.jsx index 948345a9546702533ab75175250fdfef0b25edb7..1cee41caf0a7ac6642fbdd6f9c12e6338bac0310 100755 --- a/bigbluebutton-html5/imports/ui/components/user-list/component.jsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/component.jsx @@ -28,8 +28,9 @@ const propTypes = { changeRole: PropTypes.func.isRequired, roving: PropTypes.func.isRequired, getGroupChatPrivate: PropTypes.func.isRequired, + showBranding: PropTypes.bool.isRequired, }; -const SHOW_BRANDING = Meteor.settings.public.app.branding.displayBrandingArea; + const defaultProps = { compact: false, isBreakoutRoom: false, @@ -67,12 +68,13 @@ class UserList extends Component { handleEmojiChange, getEmojiList, getEmoji, + showBranding, } = this.props; return ( <div className={styles.userList}> { - SHOW_BRANDING + showBranding && !this.props.compact && CustomLogoUrl ? <CustomLogo CustomLogoUrl={CustomLogoUrl} /> : null diff --git a/bigbluebutton-html5/imports/ui/components/user-list/container.jsx b/bigbluebutton-html5/imports/ui/components/user-list/container.jsx index 6681437009194483abc1b3b59fe424bf3acae5b7..12092e8a4fd2676880cde1287479ff1c3e80da0d 100755 --- a/bigbluebutton-html5/imports/ui/components/user-list/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/user-list/container.jsx @@ -3,6 +3,7 @@ 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'; @@ -51,4 +52,5 @@ export default withTracker(({ chatID, compact }) => ({ handleEmojiChange: Service.setEmojiStatus, getEmojiList: Service.getEmojiList(), getEmoji: Service.getEmoji(), + showBranding: getFromUserSettings('displayBrandingArea', Meteor.settings.public.app.branding.displayBrandingArea), }))(UserListContainer); diff --git a/bigbluebutton-html5/imports/ui/components/video-provider/container.jsx b/bigbluebutton-html5/imports/ui/components/video-provider/container.jsx index 4a8e8c67569dd2d6502b72d48362fa4f34ec2d4b..12bab47d132c9406c24351b9571084d172acd7a9 100755 --- a/bigbluebutton-html5/imports/ui/components/video-provider/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/video-provider/container.jsx @@ -1,5 +1,6 @@ import React from 'react'; import { withTracker } from 'meteor/react-meteor-data'; +import getFromUserSettings from '/imports/ui/services/users-settings'; import VideoProvider from './component'; import VideoService from './service'; @@ -12,5 +13,5 @@ export default withTracker(() => ({ userId: VideoService.userId(), sessionToken: VideoService.sessionToken(), userName: VideoService.userName(), - enableVideoStats: Meteor.settings.public.kurento.enableVideoStats, + enableVideoStats: getFromUserSettings('enableVideoStats', Meteor.settings.public.kurento.enableVideoStats), }))(VideoProviderContainer); diff --git a/bigbluebutton-html5/imports/ui/services/users-settings/index.js b/bigbluebutton-html5/imports/ui/services/users-settings/index.js new file mode 100644 index 0000000000000000000000000000000000000000..644b1caaa98aaba21b837b5e3f136dca02f5d42c --- /dev/null +++ b/bigbluebutton-html5/imports/ui/services/users-settings/index.js @@ -0,0 +1,20 @@ +import Auth from '/imports/ui/services/auth'; +import UserSettings from '/imports/api/users-settings'; + +export default function getFromUserSettings(setting, defaultValue) { + const { meetingID: meetingId, userID: userId } = Auth; + + const selector = { + meetingId, + userId, + setting, + }; + + const userSetting = UserSettings.findOne(selector); + + if (userSetting !== undefined) { + return userSetting.value; + } + + return defaultValue; +} diff --git a/bigbluebutton-html5/private/config/settings-development.json b/bigbluebutton-html5/private/config/settings-development.json index f0f40fa656d4cb151247de4dcdf4b3411ab61ff2..40dab1137f586f421378d47dd1ba11610ccec6b2 100755 --- a/bigbluebutton-html5/private/config/settings-development.json +++ b/bigbluebutton-html5/private/config/settings-development.json @@ -111,7 +111,8 @@ "whiteboard-multi-user", "presentation-pods", "group-chat", - "group-chat-msg" + "group-chat-msg", + "users-settings" ], "methods": [ "listenOnlyToggle", diff --git a/bigbluebutton-html5/private/config/settings-production.json b/bigbluebutton-html5/private/config/settings-production.json index 43e0ffcc73029875c4407d13a40585622b87900e..973674e94d78e8b00461f38eb7e21356f000990e 100755 --- a/bigbluebutton-html5/private/config/settings-production.json +++ b/bigbluebutton-html5/private/config/settings-production.json @@ -111,7 +111,8 @@ "whiteboard-multi-user", "presentation-pods", "group-chat", - "group-chat-msg" + "group-chat-msg", + "users-settings" ], "methods": [ "listenOnlyToggle", diff --git a/bigbluebutton-html5/server/main.js b/bigbluebutton-html5/server/main.js index 545ff6cb8d473e6ffbd12c0e2aadf50cc7fbd7cb..a5584374cc034559d0ded9d128b0b24321ae348e 100755 --- a/bigbluebutton-html5/server/main.js +++ b/bigbluebutton-html5/server/main.js @@ -15,6 +15,7 @@ import '/imports/api/breakouts/server'; import '/imports/api/group-chat/server'; import '/imports/api/group-chat-msg/server'; import '/imports/api/screenshare/server'; +import '/imports/api/users-settings/server'; import '/imports/api/voice-users/server'; import '/imports/api/whiteboard-multi-user/server'; import '/imports/api/video/server';