From c966eba00f469ed69c5a31ae23395b40f52f26ef Mon Sep 17 00:00:00 2001 From: Hristo Terezov Date: Tue, 16 Apr 2024 17:10:36 -0500 Subject: [PATCH] ref(modules/UI): remove events system. Many of the events are not used at all or used only on one place. For the rest of them the listeners were added 2 times on promoted visitors and not cleaned at all. --- conference.js | 241 +++++++----------- modules/API/API.js | 8 +- modules/UI/UI.js | 62 +---- modules/UI/etherpad/Etherpad.js | 3 +- react/features/base/audio-only/actions.ts | 4 +- react/features/base/conference/actions.ts | 6 +- react/features/base/devices/middleware.web.ts | 6 +- .../features/base/participants/middleware.ts | 5 +- .../conference/components/web/Conference.tsx | 2 - react/features/etherpad/middleware.ts | 4 +- react/features/room-lock/middleware.ts | 8 - react/features/settings/actions.native.ts | 13 + react/features/settings/actions.web.ts | 17 +- react/features/toolbox/actions.any.ts | 4 +- react/features/video-menu/actions.any.ts | 7 +- service/UI/UIEvents.js | 57 ----- 16 files changed, 151 insertions(+), 296 deletions(-) delete mode 100644 service/UI/UIEvents.js diff --git a/conference.js b/conference.js index c2e120e44d47..af135e1cfce0 100644 --- a/conference.js +++ b/conference.js @@ -2,7 +2,6 @@ import { jitsiLocalStorage } from '@jitsi/js-utils'; import Logger from '@jitsi/logger'; -import EventEmitter from 'events'; import { ENDPOINT_TEXT_MESSAGE_NAME } from './modules/API/constants'; import { AUDIO_ONLY_SCREEN_SHARE_NO_TRACK } from './modules/UI/UIErrors'; @@ -165,12 +164,9 @@ import { AudioMixerEffect } from './react/features/stream-effects/audio-mixer/Au import { createRnnoiseProcessor } from './react/features/stream-effects/rnnoise'; import { handleToggleVideoMuted } from './react/features/toolbox/actions.any'; import { muteLocal } from './react/features/video-menu/actions.any'; -import UIEvents from './service/UI/UIEvents'; const logger = Logger.getLogger(__filename); -const eventEmitter = new EventEmitter(); - let room; /* @@ -1916,21 +1912,12 @@ export default { JitsiE2ePingEvents.E2E_RTT_CHANGED, (...args) => APP.store.dispatch(e2eRttChanged(...args))); - APP.UI.addListener(UIEvents.AUDIO_MUTED, muted => { - this.muteAudio(muted); - }); - APP.UI.addListener(UIEvents.VIDEO_MUTED, (muted, showUI = false) => { - this.muteVideo(muted, showUI); - }); - room.addCommandListener(this.commands.defaults.ETHERPAD, ({ value }) => { APP.UI.initEtherpad(value); } ); - APP.UI.addListener(UIEvents.EMAIL_CHANGED, - this.changeLocalEmail.bind(this)); room.addCommandListener(this.commands.defaults.EMAIL, (data, from) => { APP.store.dispatch(participantUpdated({ conference: room, @@ -1950,9 +1937,6 @@ export default { })); }); - APP.UI.addListener(UIEvents.NICKNAME_CHANGED, - this.changeLocalDisplayName.bind(this)); - room.on( JitsiConferenceEvents.START_MUTED_POLICY_CHANGED, ({ audio, video }) => { @@ -2007,113 +1991,117 @@ export default { }, NOTIFICATION_TIMEOUT_TYPE.STICKY)); } ); + }, - // call hangup - APP.UI.addListener(UIEvents.HANGUP, () => { - this.hangup(true); - }); - - APP.UI.addListener( - UIEvents.VIDEO_DEVICE_CHANGED, - cameraDeviceId => { - const videoWasMuted = this.isLocalVideoMuted(); - const localVideoTrack = getLocalJitsiVideoTrack(APP.store.getState()); + /** + * Handles audio device changes. + * + * @param {string} cameraDeviceId - The new device id. + * @returns {Promise} + */ + async onAudioDeviceChanged(micDeviceId) { + const audioWasMuted = this.isLocalAudioMuted(); + + // Disable noise suppression if it was enabled on the previous track. + await APP.store.dispatch(setNoiseSuppressionEnabled(false)); + + // When the 'default' mic needs to be selected, we need to pass the real device id to gUM instead of + // 'default' in order to get the correct MediaStreamTrack from chrome because of the following bug. + // https://bugs.chromium.org/p/chromium/issues/detail?id=997689. + const isDefaultMicSelected = micDeviceId === 'default'; + const selectedDeviceId = isDefaultMicSelected + ? getDefaultDeviceId(APP.store.getState(), 'audioInput') + : micDeviceId; + + logger.info(`Switching audio input device to ${selectedDeviceId}`); + sendAnalytics(createDeviceChangedEvent('audio', 'input')); + createLocalTracksF({ + devices: [ 'audio' ], + micDeviceId: selectedDeviceId + }) + .then(([ stream ]) => { + // if audio was muted before changing the device, mute + // with the new device + if (audioWasMuted) { + return stream.mute() + .then(() => stream); + } - if (localVideoTrack?.getDeviceId() === cameraDeviceId) { - return; - } + return stream; + }) + .then(async stream => { + await this._maybeApplyAudioMixerEffect(stream); - sendAnalytics(createDeviceChangedEvent('video', 'input')); + return this.useAudioStream(stream); + }) + .then(() => { + const localAudio = getLocalJitsiAudioTrack(APP.store.getState()); - createLocalTracksF({ - devices: [ 'video' ], - cameraDeviceId - }) - .then(([ stream ]) => { - // if we are in audio only mode or video was muted before - // changing device, then mute - if (this.isAudioOnly() || videoWasMuted) { - return stream.mute() - .then(() => stream); - } + if (localAudio && isDefaultMicSelected) { + // workaround for the default device to be shown as selected in the + // settings even when the real device id was passed to gUM because of the + // above mentioned chrome bug. + localAudio._realDeviceId = localAudio.deviceId = 'default'; + } + }) + .catch(err => { + logger.error(`Failed to switch to selected audio input device ${selectedDeviceId}, error=${err}`); + APP.store.dispatch(notifyMicError(err)); + }); + }, - return stream; - }) - .then(stream => { - logger.info(`Switching the local video device to ${cameraDeviceId}.`); + /** + * Handles video device changes. + * + * @param {string} cameraDeviceId - The new device id. + * @returns {void} + */ + onVideoDeviceChanged(cameraDeviceId) { + const videoWasMuted = this.isLocalVideoMuted(); + const localVideoTrack = getLocalJitsiVideoTrack(APP.store.getState()); - return this.useVideoStream(stream); - }) - .catch(error => { - logger.error(`Failed to switch to selected camera:${cameraDeviceId}, error:${error}`); + if (localVideoTrack?.getDeviceId() === cameraDeviceId) { + return; + } - return APP.store.dispatch(notifyCameraError(error)); - }); + sendAnalytics(createDeviceChangedEvent('video', 'input')); + + createLocalTracksF({ + devices: [ 'video' ], + cameraDeviceId + }) + .then(([ stream ]) => { + // if we are in audio only mode or video was muted before + // changing device, then mute + if (this.isAudioOnly() || videoWasMuted) { + return stream.mute() + .then(() => stream); } - ); - APP.UI.addListener( - UIEvents.AUDIO_DEVICE_CHANGED, - async micDeviceId => { - const audioWasMuted = this.isLocalAudioMuted(); - - // Disable noise suppression if it was enabled on the previous track. - await APP.store.dispatch(setNoiseSuppressionEnabled(false)); - - // When the 'default' mic needs to be selected, we need to pass the real device id to gUM instead of - // 'default' in order to get the correct MediaStreamTrack from chrome because of the following bug. - // https://bugs.chromium.org/p/chromium/issues/detail?id=997689. - const isDefaultMicSelected = micDeviceId === 'default'; - const selectedDeviceId = isDefaultMicSelected - ? getDefaultDeviceId(APP.store.getState(), 'audioInput') - : micDeviceId; - - logger.info(`Switching audio input device to ${selectedDeviceId}`); - sendAnalytics(createDeviceChangedEvent('audio', 'input')); - createLocalTracksF({ - devices: [ 'audio' ], - micDeviceId: selectedDeviceId - }) - .then(([ stream ]) => { - // if audio was muted before changing the device, mute - // with the new device - if (audioWasMuted) { - return stream.mute() - .then(() => stream); - } + return stream; + }) + .then(stream => { + logger.info(`Switching the local video device to ${cameraDeviceId}.`); - return stream; - }) - .then(async stream => { - await this._maybeApplyAudioMixerEffect(stream); + return this.useVideoStream(stream); + }) + .catch(error => { + logger.error(`Failed to switch to selected camera:${cameraDeviceId}, error:${error}`); - return this.useAudioStream(stream); - }) - .then(() => { - const localAudio = getLocalJitsiAudioTrack(APP.store.getState()); - - if (localAudio && isDefaultMicSelected) { - // workaround for the default device to be shown as selected in the - // settings even when the real device id was passed to gUM because of the - // above mentioned chrome bug. - localAudio._realDeviceId = localAudio.deviceId = 'default'; - } - }) - .catch(err => { - logger.error(`Failed to switch to selected audio input device ${selectedDeviceId}, error=${err}`); - APP.store.dispatch(notifyMicError(err)); - }); - } - ); + return APP.store.dispatch(notifyCameraError(error)); + }); + }, - APP.UI.addListener(UIEvents.TOGGLE_AUDIO_ONLY, () => { - // Immediately update the UI by having remote videos and the large video update themselves. - const displayedUserId = APP.UI.getLargeVideoID(); + /** + * Handles audio only changes. + */ + onToggleAudioOnly() { + // Immediately update the UI by having remote videos and the large video update themselves. + const displayedUserId = APP.UI.getLargeVideoID(); - if (displayedUserId) { - APP.UI.updateLargeVideo(displayedUserId, true); - } - }); + if (displayedUserId) { + APP.UI.updateLargeVideo(displayedUserId, true); + } }, /** @@ -2408,8 +2396,6 @@ export default { this.deviceChangeListener); } - APP.UI.removeAllListeners(); - let feedbackResultPromise = Promise.resolve({}); if (requestFeedback) { @@ -2516,37 +2502,6 @@ export default { room.sendEndpointMessage(to, payload); }, - /** - * Adds new listener. - * @param {String} eventName the name of the event - * @param {Function} listener the listener. - */ - addListener(eventName, listener) { - eventEmitter.addListener(eventName, listener); - }, - - /** - * Removes listener. - * @param {String} eventName the name of the event that triggers the - * listener - * @param {Function} listener the listener. - */ - removeListener(eventName, listener) { - eventEmitter.removeListener(eventName, listener); - }, - - /** - * Changes the display name for the local user - * @param nickname {string} the new display name - */ - changeLocalDisplayName(nickname = '') { - const formattedNickname = getNormalizedDisplayName(nickname); - - APP.store.dispatch(updateSettings({ - displayName: formattedNickname - })); - }, - /** * Callback invoked by the external api create or update a direct connection * from the local client to an external client. diff --git a/modules/API/API.js b/modules/API/API.js index 6999e99aed41..fd6671b9aa9e 100644 --- a/modules/API/API.js +++ b/modules/API/API.js @@ -76,6 +76,7 @@ import { setMediaEncryptionKey, toggleE2EE } from '../../react/features/e2ee/act import { addStageParticipant, resizeFilmStrip, + setFilmstripVisible, setVolume, togglePinStageParticipant } from '../../react/features/filmstrip/actions.web'; @@ -104,6 +105,7 @@ import { startAudioScreenShareFlow, startScreenShareFlow } from '../../react/fea import { isScreenAudioSupported } from '../../react/features/screen-share/functions'; import { toggleScreenshotCaptureSummary } from '../../react/features/screenshot-capture/actions'; import { isScreenshotCaptureEnabled } from '../../react/features/screenshot-capture/functions'; +import { changeLocalDisplayName } from '../../react/features/settings/actions.web'; import SettingsDialog from '../../react/features/settings/components/web/SettingsDialog'; import { SETTINGS_TABS } from '../../react/features/settings/constants'; import { playSharedVideo, stopSharedVideo } from '../../react/features/shared-video/actions.any'; @@ -199,7 +201,7 @@ function initCommands() { }, 'display-name': displayName => { sendAnalytics(createApiEvent('display.name.changed')); - APP.conference.changeLocalDisplayName(displayName); + APP.store.dispatch(changeLocalDisplayName(displayName)); }, 'local-subject': localSubject => { sendAnalytics(createApiEvent('local.subject.changed')); @@ -376,7 +378,9 @@ function initCommands() { }, 'toggle-film-strip': () => { sendAnalytics(createApiEvent('film.strip.toggled')); - APP.UI.toggleFilmstrip(); + const { visible } = APP.store.getState()['features/filmstrip']; + + APP.store.dispatch(setFilmstripVisible(!visible)); }, /* diff --git a/modules/UI/UI.js b/modules/UI/UI.js index 35d583524aa6..2962442d16fe 100644 --- a/modules/UI/UI.js +++ b/modules/UI/UI.js @@ -4,7 +4,6 @@ const UI = {}; import Logger from '@jitsi/logger'; -import EventEmitter from 'events'; import { conferenceWillInit @@ -13,7 +12,6 @@ import { isMobileBrowser } from '../../react/features/base/environment/utils'; import { setColorAlpha } from '../../react/features/base/util/helpers'; import { sanitizeUrl } from '../../react/features/base/util/uri'; import { setDocumentUrl } from '../../react/features/etherpad/actions'; -import { setFilmstripVisible } from '../../react/features/filmstrip/actions.any'; import { setNotificationsEnabled, showNotification @@ -25,7 +23,6 @@ import { setToolboxEnabled, showToolbox } from '../../react/features/toolbox/actions.web'; -import UIEvents from '../../service/UI/UIEvents'; import EtherpadManager from './etherpad/Etherpad'; import UIUtil from './util/UIUtil'; @@ -33,22 +30,8 @@ import VideoLayout from './videolayout/VideoLayout'; const logger = Logger.getLogger(__filename); -const eventEmitter = new EventEmitter(); - -UI.eventEmitter = eventEmitter; - let etherpadManager; -const UIListeners = new Map([ - [ - UIEvents.ETHERPAD_CLICKED, - () => etherpadManager && etherpadManager.toggleEtherpad() - ], [ - UIEvents.TOGGLE_FILMSTRIP, - () => UI.toggleFilmstrip() - ] -]); - /** * Indicates if we're currently in full screen mode. * @@ -96,10 +79,11 @@ UI.start = function() { }; /** - * Setup some UI event listeners. + * Handles etherpad click. */ -UI.registerListeners - = () => UIListeners.forEach((value, key) => UI.addListener(key, value)); +UI.onEtherpadClicked = function() { + etherpadManager && etherpadManager.toggleEtherpad(); +}; /** * @@ -143,7 +127,7 @@ UI.initEtherpad = name => { } logger.log('Etherpad is enabled'); - etherpadManager = new EtherpadManager(eventEmitter); + etherpadManager = new EtherpadManager(); const url = new URL(name, etherpadBaseUrl); @@ -197,15 +181,6 @@ UI.updateUserStatus = (user, status) => { }, NOTIFICATION_TIMEOUT_TYPE.SHORT)); }; -/** - * Toggles filmstrip. - */ -UI.toggleFilmstrip = function() { - const { visible } = APP.store.getState()['features/filmstrip']; - - APP.store.dispatch(setFilmstripVisible(!visible)); -}; - /** * Sets muted video state for participant */ @@ -219,33 +194,6 @@ UI.setVideoMuted = function(id) { UI.updateLargeVideo = (id, forceUpdate) => VideoLayout.updateLargeVideo(id, forceUpdate); -/** - * Adds a listener that would be notified on the given type of event. - * - * @param type the type of the event we're listening for - * @param listener a function that would be called when notified - */ -UI.addListener = function(type, listener) { - eventEmitter.on(type, listener); -}; - -/** - * Removes the all listeners for all events. - * - * @returns {void} - */ -UI.removeAllListeners = function() { - eventEmitter.removeAllListeners(); -}; - -/** - * Emits the event of given type by specifying the parameters in options. - * - * @param type the type of the event we're emitting - * @param options the parameters for the event - */ -UI.emitEvent = (type, ...options) => eventEmitter.emit(type, ...options); - // Used by torture. UI.showToolbar = timeout => APP.store.dispatch(showToolbox(timeout)); diff --git a/modules/UI/etherpad/Etherpad.js b/modules/UI/etherpad/Etherpad.js index a11014d5362c..9031bcdebaf2 100644 --- a/modules/UI/etherpad/Etherpad.js +++ b/modules/UI/etherpad/Etherpad.js @@ -138,8 +138,7 @@ export default class EtherpadManager { /** * */ - constructor(eventEmitter) { - this.eventEmitter = eventEmitter; + constructor() { this.etherpad = null; } diff --git a/react/features/base/audio-only/actions.ts b/react/features/base/audio-only/actions.ts index 3560dafabf2d..32312b84b576 100644 --- a/react/features/base/audio-only/actions.ts +++ b/react/features/base/audio-only/actions.ts @@ -1,5 +1,3 @@ -// @ts-expect-error -import UIEvents from '../../../../service/UI/UIEvents'; import { createAudioOnlyChangedEvent } from '../../analytics/AnalyticsEvents'; import { sendAnalytics } from '../../analytics/functions'; import { IStore } from '../../app/types'; @@ -33,7 +31,7 @@ export function setAudioOnly(audioOnly: boolean) { if (typeof APP !== 'undefined') { // TODO This should be a temporary solution that lasts only until video // tracks and all ui is moved into react/redux on the web. - APP.UI.emitEvent(UIEvents.TOGGLE_AUDIO_ONLY, audioOnly); + APP.conference.onToggleAudioOnly(); } } }; diff --git a/react/features/base/conference/actions.ts b/react/features/base/conference/actions.ts index 8eb706f739e9..553e1194f260 100644 --- a/react/features/base/conference/actions.ts +++ b/react/features/base/conference/actions.ts @@ -1,5 +1,3 @@ -// @ts-expect-error -import UIEvents from '../../../../service/UI/UIEvents'; import { createStartMutedConfigurationEvent } from '../../analytics/AnalyticsEvents'; import { sendAnalytics } from '../../analytics/functions'; import { IReduxState, IStore } from '../../app/types'; @@ -1083,7 +1081,7 @@ export function redirect(vnode: string, focusJid: string, username: string) { dispatch(setAudioMuted(false, true)); // // FIXME: The old conference logic still relies on this event being emitted. - typeof APP === 'undefined' || APP.UI.emitEvent(UIEvents.AUDIO_MUTED, false); + typeof APP === 'undefined' || APP.conference.muteAudio(false); } } @@ -1096,7 +1094,7 @@ export function redirect(vnode: string, focusJid: string, username: string) { dispatch(setVideoMuted(false, VIDEO_MUTISM_AUTHORITY.USER, true)); // // FIXME: The old conference logic still relies on this event being emitted. - typeof APP === 'undefined' || APP.UI.emitEvent(UIEvents.VIDEO_MUTED, false); + typeof APP === 'undefined' || APP.conference.muteVideo(false, false); } } } diff --git a/react/features/base/devices/middleware.web.ts b/react/features/base/devices/middleware.web.ts index dce6c442eb6b..5d1e08ff5dc9 100644 --- a/react/features/base/devices/middleware.web.ts +++ b/react/features/base/devices/middleware.web.ts @@ -1,7 +1,5 @@ import { AnyAction } from 'redux'; -// @ts-expect-error -import UIEvents from '../../../../service/UI/UIEvents'; import { IStore } from '../../app/types'; import { processExternalDeviceRequest } from '../../device-selection/functions'; import { showNotification, showWarningNotification } from '../../notifications/actions'; @@ -161,7 +159,7 @@ MiddlewareRegistry.register(store => next => action => { if (isPrejoinPageVisible(store.getState())) { store.dispatch(replaceAudioTrackById(action.deviceId)); } else { - APP.UI.emitEvent(UIEvents.AUDIO_DEVICE_CHANGED, action.deviceId); + APP.conference.onAudioDeviceChanged(action.deviceId); } break; case SET_VIDEO_INPUT_DEVICE: { @@ -174,7 +172,7 @@ MiddlewareRegistry.register(store => next => action => { if (isPrejoinPageVisible(store.getState())) { store.dispatch(replaceVideoTrackById(action.deviceId)); } else { - APP.UI.emitEvent(UIEvents.VIDEO_DEVICE_CHANGED, action.deviceId); + APP.conference.onVideoDeviceChanged(action.deviceId); } break; } diff --git a/react/features/base/participants/middleware.ts b/react/features/base/participants/middleware.ts index 1755ec848774..c8c97c65e637 100644 --- a/react/features/base/participants/middleware.ts +++ b/react/features/base/participants/middleware.ts @@ -2,8 +2,6 @@ import i18n from 'i18next'; import { batch } from 'react-redux'; import { AnyAction } from 'redux'; -// @ts-expect-error -import UIEvents from '../../../../service/UI/UIEvents'; import { IStore } from '../../app/types'; import { approveParticipant } from '../../av-moderation/actions'; import { UPDATE_BREAKOUT_ROOMS } from '../../breakout-rooms/actionTypes'; @@ -20,6 +18,7 @@ import { isForceMuted } from '../../participants-pane/functions'; import { CALLING, INVITED } from '../../presence-status/constants'; import { RAISE_HAND_SOUND_ID } from '../../reactions/constants'; import { RECORDING_OFF_SOUND_ID, RECORDING_ON_SOUND_ID } from '../../recording/constants'; +import { changeLocalDisplayName } from '../../settings/actions'; import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../app/actionTypes'; import { CONFERENCE_WILL_JOIN } from '../conference/actionTypes'; import { forEachConference, getCurrentConference } from '../conference/functions'; @@ -241,7 +240,7 @@ MiddlewareRegistry.register(store => next => action => { const participant = getLocalParticipant(store.getState()); if (participant && participant.id === action.id) { - APP.UI.emitEvent(UIEvents.NICKNAME_CHANGED, action.name); + store.dispatch(changeLocalDisplayName(action.name)); } } diff --git a/react/features/conference/components/web/Conference.tsx b/react/features/conference/components/web/Conference.tsx index 70ac8793b3cc..c357e6118373 100644 --- a/react/features/conference/components/web/Conference.tsx +++ b/react/features/conference/components/web/Conference.tsx @@ -368,8 +368,6 @@ class Conference extends AbstractConference { */ _start() { APP.UI.start(); - - APP.UI.registerListeners(); APP.UI.bindEvents(); FULL_SCREEN_EVENTS.forEach(name => diff --git a/react/features/etherpad/middleware.ts b/react/features/etherpad/middleware.ts index 8ed139e90f66..ba9fa1a2154b 100644 --- a/react/features/etherpad/middleware.ts +++ b/react/features/etherpad/middleware.ts @@ -1,5 +1,3 @@ -// @ts-expect-error -import UIEvents from '../../../service/UI/UIEvents'; import { CONFERENCE_JOIN_IN_PROGRESS } from '../base/conference/actionTypes'; import { getCurrentConference } from '../base/conference/functions'; import MiddlewareRegistry from '../base/redux/MiddlewareRegistry'; @@ -41,7 +39,7 @@ MiddlewareRegistry.register(({ dispatch, getState }) => next => action => { } case TOGGLE_DOCUMENT_EDITING: { if (typeof APP !== 'undefined') { - APP.UI.emitEvent(UIEvents.ETHERPAD_CLICKED); + APP.UI.onEtherpadClicked(); } break; } diff --git a/react/features/room-lock/middleware.ts b/react/features/room-lock/middleware.ts index b83c81377766..61a24e217746 100644 --- a/react/features/room-lock/middleware.ts +++ b/react/features/room-lock/middleware.ts @@ -1,7 +1,5 @@ import { AnyAction } from 'redux'; -// @ts-expect-error -import UIEvents from '../../../service/UI/UIEvents'; import { IStore } from '../app/types'; import { CONFERENCE_FAILED, @@ -36,12 +34,6 @@ MiddlewareRegistry.register(store => next => action => { return _conferenceJoined(store, next, action); case LOCK_STATE_CHANGED: { - // TODO Remove this logic when all components interested in the lock - // state change event are moved into react/redux. - if (typeof APP !== 'undefined') { - APP.UI.emitEvent(UIEvents.TOGGLE_ROOM_LOCK, action.locked); - } - const previousLockedState = store.getState()['features/base/conference'].locked; const result = next(action); diff --git a/react/features/settings/actions.native.ts b/react/features/settings/actions.native.ts index fe6c149cb96c..7cee33edddd3 100644 --- a/react/features/settings/actions.native.ts +++ b/react/features/settings/actions.native.ts @@ -36,3 +36,16 @@ export function openLogoutDialog() { })); }; } + +/** +* Changes the display name for the local user. +* +* @param {string} _nickname - The new display name. +* @returns {Function} +*/ +export function changeLocalDisplayName(_nickname = '') { + // not used on mobile. + return (_dispatch: IStore['dispatch'], _getState: IStore['getState']) => { + // no-op action. + }; +} diff --git a/react/features/settings/actions.web.ts b/react/features/settings/actions.web.ts index 65e2f4a77bfe..a85a59f975c4 100644 --- a/react/features/settings/actions.web.ts +++ b/react/features/settings/actions.web.ts @@ -12,6 +12,7 @@ import { hangup } from '../base/connection/actions.web'; import { openDialog } from '../base/dialog/actions'; import i18next from '../base/i18n/i18next'; import { browser } from '../base/lib-jitsi-meet'; +import { getNormalizedDisplayName } from '../base/participants/functions'; import { updateSettings } from '../base/settings/actions'; import { getLocalVideoTrack } from '../base/tracks/functions.web'; import { appendURLHashParam } from '../base/util/uri'; @@ -191,7 +192,7 @@ export function submitProfileTab(newState: any) { const currentState = getProfileTabProps(getState()); if (newState.displayName !== currentState.displayName) { - APP.conference.changeLocalDisplayName(newState.displayName); + dispatch(changeLocalDisplayName(newState.displayName)); } if (newState.email !== currentState.email) { @@ -200,6 +201,20 @@ export function submitProfileTab(newState: any) { }; } +/** +* Changes the display name for the local user. +* +* @param {string} nickname - The new display name. +* @returns {Function} +*/ +export function changeLocalDisplayName(nickname = '') { + return (dispatch: IStore['dispatch']) => { + const formattedNickname = getNormalizedDisplayName(nickname); + + dispatch(updateSettings({ displayName: formattedNickname })); + }; +} + /** * Submits the settings from the "Sounds" tab of the settings dialog. * diff --git a/react/features/toolbox/actions.any.ts b/react/features/toolbox/actions.any.ts index 972fd386fa02..a89fa55871aa 100644 --- a/react/features/toolbox/actions.any.ts +++ b/react/features/toolbox/actions.any.ts @@ -1,5 +1,3 @@ -// @ts-expect-error -import UIEvents from '../../../service/UI/UIEvents'; import { VIDEO_MUTE, createToolbarEvent } from '../analytics/AnalyticsEvents'; import { sendAnalytics } from '../analytics/functions'; import { IStore } from '../app/types'; @@ -103,7 +101,7 @@ export function handleToggleVideoMuted(muted: boolean, showUI: boolean, ensureTr // FIXME: The old conference logic still relies on this event being // emitted. typeof APP === 'undefined' - || APP.UI.emitEvent(UIEvents.VIDEO_MUTED, muted, showUI); + || APP.conference.muteVideo(muted, showUI); }; } diff --git a/react/features/video-menu/actions.any.ts b/react/features/video-menu/actions.any.ts index 76d5566236a9..e0beeb92ebcc 100644 --- a/react/features/video-menu/actions.any.ts +++ b/react/features/video-menu/actions.any.ts @@ -1,5 +1,3 @@ -// @ts-expect-error -import UIEvents from '../../../service/UI/UIEvents'; import { AUDIO_MUTE, VIDEO_MUTE, @@ -55,8 +53,9 @@ export function muteLocal(enable: boolean, mediaType: MediaType, stopScreenShari : setVideoMuted(enable, VIDEO_MUTISM_AUTHORITY.USER, /* ensureTrack */ true)); // FIXME: The old conference logic still relies on this event being emitted. - typeof APP === 'undefined' - || APP.UI.emitEvent(isAudio ? UIEvents.AUDIO_MUTED : UIEvents.VIDEO_MUTED, enable); + if (typeof APP !== 'undefined') { + isAudio ? APP.conference.muteAudio(enable) : APP.conference.muteVideo(enable, false); + } }; } diff --git a/service/UI/UIEvents.js b/service/UI/UIEvents.js deleted file mode 100644 index 12b1fe58248f..000000000000 --- a/service/UI/UIEvents.js +++ /dev/null @@ -1,57 +0,0 @@ -export default { - NICKNAME_CHANGED: 'UI.nickname_changed', - - /** - * Notifies that local user changed email. - */ - EMAIL_CHANGED: 'UI.email_changed', - - /** - * Notifies that "start muted" settings changed. - */ - AUDIO_MUTED: 'UI.audio_muted', - VIDEO_MUTED: 'UI.video_muted', - ETHERPAD_CLICKED: 'UI.etherpad_clicked', - - /** - * Updates shared video with params: url, state, time(optional) - * Where url is the video link, state is stop/start/pause and time is the - * current video playing time. - */ - TOGGLE_FULLSCREEN: 'UI.toogle_fullscreen', - FULLSCREEN_TOGGLED: 'UI.fullscreen_toggled', - - /** - * Notifies that the audio only mode was toggled. - */ - TOGGLE_AUDIO_ONLY: 'UI.toggle_audioonly', - - /** - * Notifies that a command to toggle the filmstrip has been issued. The - * event may optionally specify a {Boolean} (primitive) value to assign to - * the visibility of the filmstrip (i.e. the event may act as a setter). - * The very toggling of the filmstrip may or may not occurred at the time - * of the receipt of the event depending on the position of the receiving - * event listener in relation to the event listener which carries out the - * command to toggle the filmstrip. - * - * @see {TOGGLED_FILMSTRIP} - */ - TOGGLE_FILMSTRIP: 'UI.toggle_filmstrip', - - HANGUP: 'UI.hangup', - VIDEO_DEVICE_CHANGED: 'UI.video_device_changed', - AUDIO_DEVICE_CHANGED: 'UI.audio_device_changed', - - /** - * Notifies that the side toolbar container has been toggled. The actual - * event must contain the identifier of the container that has been toggled - * and information about toggle on or off. - */ - SIDE_TOOLBAR_CONTAINER_TOGGLED: 'UI.side_container_toggled', - - /** - * Notifies that the raise hand has been changed. - */ - LOCAL_RAISE_HAND_CHANGED: 'UI.local_raise_hand_changed' -};