diff --git a/conference.js b/conference.js index d9c57c93f..0799488e3 100644 --- a/conference.js +++ b/conference.js @@ -147,12 +147,8 @@ import { } from './react/features/notifications'; import { mediaPermissionPromptVisibilityChanged } from './react/features/overlay'; import { suspendDetected } from './react/features/power-monitor'; -import { - initPrejoin, - isPrejoinPageVisible, - makePrecallTest, - setJoiningInProgress -} from './react/features/prejoin'; +import { initPrejoin, makePrecallTest, setJoiningInProgress } from './react/features/prejoin/actions'; +import { isPrejoinPageVisible } from './react/features/prejoin/functions'; import { disableReceiver, stopReceiver } from './react/features/remote-control'; import { isScreenAudioShared, setScreenAudioShareState } from './react/features/screen-share/'; import { toggleScreenshotCaptureSummary } from './react/features/screenshot-capture'; diff --git a/globals.native.d.ts b/globals.native.d.ts index 989bb4d78..4da634791 100644 --- a/globals.native.d.ts +++ b/globals.native.d.ts @@ -2,11 +2,18 @@ import { IConfig } from "./react/features/base/config/configType"; export {}; +interface ILocation extends URL { + assign(url: string); + replace(url: string); + reload(); +}; + interface IWindow { JITSI_MEET_LITE_SDK: boolean; + JitsiMeetJS: any; config: IConfig; interfaceConfig: any; - location: URL; + location: ILocation; } interface INavigator { diff --git a/modules/API/API.js b/modules/API/API.js index 3ba8d4752..4a6560c70 100644 --- a/modules/API/API.js +++ b/modules/API/API.js @@ -95,8 +95,8 @@ import { getParticipantsPaneOpen, isForceMuted } from '../../react/features/part import { startLocalVideoRecording, stopLocalVideoRecording } from '../../react/features/recording'; import { RECORDING_TYPES } from '../../react/features/recording/constants'; import { getActiveSession, supportsLocalRecording } from '../../react/features/recording/functions'; -import { isScreenAudioSupported } from '../../react/features/screen-share'; import { startAudioScreenShareFlow, startScreenShareFlow } from '../../react/features/screen-share/actions'; +import { isScreenAudioSupported } from '../../react/features/screen-share/functions'; import { toggleScreenshotCaptureSummary } from '../../react/features/screenshot-capture'; import { isScreenshotCaptureEnabled } from '../../react/features/screenshot-capture/functions'; import { playSharedVideo, stopSharedVideo } from '../../react/features/shared-video/actions.any'; diff --git a/react/features/app/actions.native.ts b/react/features/app/actions.native.ts index 050e67176..1f861618b 100644 --- a/react/features/app/actions.native.ts +++ b/react/features/app/actions.native.ts @@ -156,6 +156,23 @@ export function appNavigate(uri?: string) { }; } +/** + * Check if the welcome page is enabled and redirects to it. + * If requested show a thank you dialog before that. + * If we have a close page enabled, redirect to it without + * showing any other dialog. + * + * @param {Object} _options - Used to decide which particular close page to show + * or if close page is disabled, whether we should show the thankyou dialog. + * @param {boolean} options.showThankYou - Whether we should + * show thank you dialog. + * @param {boolean} options.feedbackSubmitted - Whether feedback was submitted. + * @returns {Function} + */ +export function maybeRedirectToWelcomePage(_options: { feedbackSubmitted?: boolean; showThankYou?: boolean; } = {}) { + // Dummy. +} + /** * Reloads the page. * diff --git a/react/features/app/components/App.web.js b/react/features/app/components/App.web.js index 4953fcf76..afe3fa496 100644 --- a/react/features/app/components/App.web.js +++ b/react/features/app/components/App.web.js @@ -3,7 +3,7 @@ import { AtlasKitThemeProvider } from '@atlaskit/theme'; import React from 'react'; -import GlobalStyles from '../../base/ui/components/GlobalStyles'; +import GlobalStyles from '../../base/ui/components/GlobalStyles.web'; import JitsiThemeProvider from '../../base/ui/components/JitsiThemeProvider.web'; import DialogContainer from '../../base/ui/components/web/DialogContainer'; import { ChromeExtensionBanner } from '../../chrome-extension-banner'; diff --git a/react/features/app/middlewares.any.js b/react/features/app/middlewares.any.js index 27602427e..b9bea56cd 100644 --- a/react/features/app/middlewares.any.js +++ b/react/features/app/middlewares.any.js @@ -1,5 +1,3 @@ -// @flow - import '../analytics/middleware'; import '../av-moderation/middleware'; import '../base/conference/middleware'; @@ -12,7 +10,6 @@ import '../base/logging/middleware'; import '../base/media/middleware'; import '../base/net-info/middleware'; import '../base/participants/middleware'; -import '../base/redux/middleware'; import '../base/responsive-ui/middleware'; import '../base/settings/middleware'; import '../base/sounds/middleware'; @@ -46,7 +43,6 @@ import '../room-lock/middleware'; import '../rtcstats/middleware'; import '../speaker-stats/middleware'; import '../subtitles/middleware'; -import '../toolbox/middleware'; import '../transcribing/middleware'; import '../video-layout/middleware'; import '../video-quality/middleware'; diff --git a/react/features/app/middlewares.native.js b/react/features/app/middlewares.native.js index bf237c8e9..24d9565d9 100644 --- a/react/features/app/middlewares.native.js +++ b/react/features/app/middlewares.native.js @@ -1,5 +1,3 @@ -// @flow - import '../authentication/middleware'; import '../dynamic-branding/middleware'; import '../gifs/middleware'; diff --git a/react/features/app/middlewares.web.js b/react/features/app/middlewares.web.js index 6d46327e8..2bd435c92 100644 --- a/react/features/app/middlewares.web.js +++ b/react/features/app/middlewares.web.js @@ -1,9 +1,8 @@ -// @flow - import '../authentication/middleware'; import '../base/i18n/middleware'; import '../base/devices/middleware'; import '../base/media/middleware'; +import '../base/redux/middleware'; import '../dynamic-branding/middleware'; import '../e2ee/middleware'; import '../external-api/middleware'; @@ -19,6 +18,7 @@ import '../screen-share/middleware'; import '../shared-video/middleware'; import '../settings/middleware'; import '../talk-while-muted/middleware'; +import '../toolbox/middleware'; import '../face-landmarks/middleware'; import '../gifs/middleware'; import '../whiteboard/middleware'; diff --git a/react/features/base/conference/middleware.web.js b/react/features/base/conference/middleware.web.js index 5318805cb..d62fe5880 100644 --- a/react/features/base/conference/middleware.web.js +++ b/react/features/base/conference/middleware.web.js @@ -2,7 +2,7 @@ import { setPrejoinPageVisibility, setSkipPrejoinOnReload -} from '../../prejoin'; +} from '../../prejoin/actions.web'; import { JitsiConferenceErrors } from '../lib-jitsi-meet'; import { MiddlewareRegistry } from '../redux'; diff --git a/react/features/base/devices/middleware.ts b/react/features/base/devices/middleware.web.ts similarity index 99% rename from react/features/base/devices/middleware.ts rename to react/features/base/devices/middleware.web.ts index debd7e4d8..c4304e920 100644 --- a/react/features/base/devices/middleware.ts +++ b/react/features/base/devices/middleware.web.ts @@ -119,7 +119,7 @@ MiddlewareRegistry.register(store => next => action => { } break; case NOTIFY_CAMERA_ERROR: { - if (typeof APP !== 'object' || !action.error) { + if (!action.error) { break; } @@ -147,7 +147,7 @@ MiddlewareRegistry.register(store => next => action => { break; } case NOTIFY_MIC_ERROR: { - if (typeof APP !== 'object' || !action.error) { + if (!action.error) { break; } diff --git a/react/features/base/dialog/middleware.web.ts b/react/features/base/dialog/middleware.web.ts index 5e7e57045..50e9029eb 100644 --- a/react/features/base/dialog/middleware.web.ts +++ b/react/features/base/dialog/middleware.web.ts @@ -21,8 +21,8 @@ import StopRecordingDialog from '../../recording/components/Recording/web/StopRe // @ts-ignore import RemoteControlAuthorizationDialog from '../../remote-control/components/RemoteControlAuthorizationDialog'; import SalesforceLinkDialog from '../../salesforce/components/web/SalesforceLinkDialog'; -import ShareAudioDialog from '../../screen-share/components/ShareAudioDialog'; -import ShareScreenWarningDialog from '../../screen-share/components/ShareScreenWarningDialog'; +import ShareAudioDialog from '../../screen-share/components/web/ShareAudioDialog'; +import ShareScreenWarningDialog from '../../screen-share/components/web/ShareScreenWarningDialog'; import SecurityDialog from '../../security/components/security-dialog/web/SecurityDialog'; import LogoutDialog from '../../settings/components/web/LogoutDialog'; import SharedVideoDialog from '../../shared-video/components/web/SharedVideoDialog'; diff --git a/react/features/base/premeeting/components/web/PreMeetingScreen.tsx b/react/features/base/premeeting/components/web/PreMeetingScreen.tsx index 2d21ffb5a..e71827d7f 100644 --- a/react/features/base/premeeting/components/web/PreMeetingScreen.tsx +++ b/react/features/base/premeeting/components/web/PreMeetingScreen.tsx @@ -4,7 +4,7 @@ import React, { ReactNode } from 'react'; import { makeStyles } from 'tss-react/mui'; import { IReduxState } from '../../../../app/types'; -import DeviceStatus from '../../../../prejoin/components/preview/DeviceStatus'; +import DeviceStatus from '../../../../prejoin/components/web/preview/DeviceStatus'; // @ts-ignore import { Toolbox } from '../../../../toolbox/components/web'; import { getConferenceName } from '../../../conference/functions'; diff --git a/react/features/base/redux/middleware.ts b/react/features/base/redux/middleware.web.ts similarity index 100% rename from react/features/base/redux/middleware.ts rename to react/features/base/redux/middleware.web.ts diff --git a/react/features/base/settings/functions.web.ts b/react/features/base/settings/functions.web.ts index a39ff1392..a03199f99 100644 --- a/react/features/base/settings/functions.web.ts +++ b/react/features/base/settings/functions.web.ts @@ -58,24 +58,3 @@ function getDeviceIdByType(state: IReduxState, isType: string) { export function getDisplayName(state: IReduxState): string { return state['features/base/settings'].displayName || ''; } - - -/** - * Handles changes to the `disableCallIntegration` setting. - * Noop on web. - * - * @param {boolean} disabled - Whether call integration is disabled or not. - * @returns {void} - */ -// eslint-disable-next-line @typescript-eslint/no-empty-function, require-jsdoc -export function handleCallIntegrationChange(disabled: boolean) { } - -/** - * Handles changes to the `disableCrashReporting` setting. - * Noop on web. - * - * @param {boolean} disabled - Whether crash reporting is disabled or not. - * @returns {void} - */ -// eslint-disable-next-line @typescript-eslint/no-empty-function, require-jsdoc -export function handleCrashReportingChange(disabled: boolean) { } diff --git a/react/features/base/settings/middleware.any.ts b/react/features/base/settings/middleware.any.ts new file mode 100644 index 000000000..dde49607b --- /dev/null +++ b/react/features/base/settings/middleware.any.ts @@ -0,0 +1,118 @@ +/* eslint-disable lines-around-comment */ +import _ from 'lodash'; +import { AnyAction } from 'redux'; + +import { IStore } from '../../app/types'; +import { SET_LOCATION_URL } from '../connection/actionTypes'; +import { participantUpdated } from '../participants/actions'; +import { getLocalParticipant } from '../participants/functions'; +import MiddlewareRegistry from '../redux/MiddlewareRegistry'; +import { parseURLParams } from '../util/parseURLParams'; + +import { SETTINGS_UPDATED } from './actionTypes'; +import { updateSettings } from './actions'; + +/** + * The middleware of the feature base/settings. Distributes changes to the state + * of base/settings to the states of other features computed from the state of + * base/settings. + * + * @param {Store} store - The redux store. + * @returns {Function} + */ +MiddlewareRegistry.register(store => next => action => { + const result = next(action); + + switch (action.type) { + case SETTINGS_UPDATED: + _updateLocalParticipant(store, action); + break; + case SET_LOCATION_URL: + _updateLocalParticipantFromUrl(store); + break; + } + + return result; +}); + +/** + * Maps the settings field names to participant names where they don't match. + * Currently there is only one such field, but may be extended in the future. + * + * @private + * @param {string} settingsField - The name of the settings field to map. + * @returns {string} + */ +function _mapSettingsFieldToParticipant(settingsField: string) { + switch (settingsField) { + case 'displayName': + return 'name'; + } + + return settingsField; +} + +/** + * Updates the local participant according to settings changes. + * + * @param {Store} store - The redux store. + * @param {Object} action - The dispatched action. + * @private + * @returns {void} + */ +function _updateLocalParticipant({ dispatch, getState }: IStore, action: AnyAction) { + const { settings } = action; + const localParticipant = getLocalParticipant(getState()); + const newLocalParticipant = { + ...localParticipant + }; + + for (const key in settings) { + if (settings.hasOwnProperty(key)) { + newLocalParticipant[_mapSettingsFieldToParticipant(key) as keyof typeof newLocalParticipant] + = settings[key]; + } + } + + dispatch(participantUpdated({ + ...newLocalParticipant, + id: newLocalParticipant.id ?? '' + })); +} + + +/** + * Returns the userInfo set in the URL. + * + * @param {Store} store - The redux store. + * @private + * @returns {void} + */ +function _updateLocalParticipantFromUrl({ dispatch, getState }: IStore) { + const urlParams + = parseURLParams(getState()['features/base/connection'].locationURL ?? ''); + const urlEmail = urlParams['userInfo.email']; + const urlDisplayName = urlParams['userInfo.displayName']; + + if (!urlEmail && !urlDisplayName) { + return; + } + + const localParticipant = getLocalParticipant(getState()); + + if (localParticipant) { + const displayName = _.escape(urlDisplayName); + const email = _.escape(urlEmail); + + dispatch(participantUpdated({ + ...localParticipant, + email, + name: displayName + })); + + dispatch(updateSettings({ + displayName, + email + })); + } +} diff --git a/react/features/base/settings/middleware.native.ts b/react/features/base/settings/middleware.native.ts new file mode 100644 index 000000000..7b202f0d8 --- /dev/null +++ b/react/features/base/settings/middleware.native.ts @@ -0,0 +1,96 @@ +import { IStore } from '../../app/types'; +import { APP_WILL_MOUNT } from '../app/actionTypes'; +import { setAudioOnly } from '../audio-only/actions'; +import MiddlewareRegistry from '../redux/MiddlewareRegistry'; + +import { SETTINGS_UPDATED } from './actionTypes'; +import { handleCallIntegrationChange, handleCrashReportingChange } from './functions.native'; +import { ISettingsState } from './reducer'; + +import './middleware.any'; + +/** + * The middleware of the feature base/settings. Distributes changes to the state + * of base/settings to the states of other features computed from the state of + * base/settings. + * + * @param {Store} store - The redux store. + * @returns {Function} + */ +MiddlewareRegistry.register(store => next => action => { + const result = next(action); + + switch (action.type) { + case APP_WILL_MOUNT: + _initializeCallIntegration(store); + break; + case SETTINGS_UPDATED: + _maybeHandleCallIntegrationChange(action); + _maybeCrashReportingChange(action); + _maybeSetAudioOnly(store, action); + break; + } + + return result; +}); + +/** + * Initializes the audio device handler based on the `disableCallIntegration` setting. + * + * @param {Store} store - The redux store. + * @private + * @returns {void} + */ +function _initializeCallIntegration({ getState }: IStore) { + const { disableCallIntegration } = getState()['features/base/settings']; + + if (typeof disableCallIntegration === 'boolean') { + handleCallIntegrationChange(disableCallIntegration); + } +} + +/** + * Handles a change in the `disableCallIntegration` setting. + * + * @param {Object} action - The redux action. + * @private + * @returns {void} + */ +function _maybeHandleCallIntegrationChange({ settings: { disableCallIntegration } }: { + settings: Partial; +}) { + if (typeof disableCallIntegration === 'boolean') { + handleCallIntegrationChange(disableCallIntegration); + } +} + +/** + * Handles a change in the `disableCrashReporting` setting. + * + * @param {Object} action - The redux action. + * @private + * @returns {void} + */ +function _maybeCrashReportingChange({ settings: { disableCrashReporting } }: { + settings: Partial; +}) { + if (typeof disableCrashReporting === 'boolean') { + handleCrashReportingChange(disableCrashReporting); + } +} + +/** + * Updates {@code startAudioOnly} flag if it's updated in the settings. + * + * @param {Store} store - The redux store. + * @param {Object} action - The redux action. + * @private + * @returns {void} + */ +function _maybeSetAudioOnly( + { dispatch }: IStore, + { settings: { startAudioOnly } }: { settings: Partial; }) { + if (typeof startAudioOnly === 'boolean') { + dispatch(setAudioOnly(startAudioOnly)); + } +} diff --git a/react/features/base/settings/middleware.ts b/react/features/base/settings/middleware.ts deleted file mode 100644 index 2b146c43e..000000000 --- a/react/features/base/settings/middleware.ts +++ /dev/null @@ -1,235 +0,0 @@ -/* eslint-disable lines-around-comment */ -import _ from 'lodash'; -import { AnyAction } from 'redux'; - -import { IStore } from '../../app/types'; -import { PREJOIN_INITIALIZED } from '../../prejoin/actionTypes'; -import { setPrejoinPageVisibility } from '../../prejoin/actions'; -import { APP_WILL_MOUNT } from '../app/actionTypes'; -import { setAudioOnly } from '../audio-only/actions'; -import { SET_LOCATION_URL } from '../connection/actionTypes'; // minimize imports to avoid circular imports -import { getJwtName } from '../jwt/functions'; -import { participantUpdated } from '../participants/actions'; -import { getLocalParticipant } from '../participants/functions'; -import MiddlewareRegistry from '../redux/MiddlewareRegistry'; -import { parseURLParams } from '../util/parseURLParams'; - -import { SETTINGS_UPDATED } from './actionTypes'; -import { updateSettings } from './actions'; -import { handleCallIntegrationChange, handleCrashReportingChange } from './functions'; -import { ISettingsState } from './reducer'; - - -/** - * The middleware of the feature base/settings. Distributes changes to the state - * of base/settings to the states of other features computed from the state of - * base/settings. - * - * @param {Store} store - The redux store. - * @returns {Function} - */ -MiddlewareRegistry.register(store => next => action => { - const result = next(action); - - switch (action.type) { - case APP_WILL_MOUNT: - _initializeCallIntegration(store); - _initializeShowPrejoin(store); - break; - case PREJOIN_INITIALIZED: { - _maybeUpdateDisplayName(store); - break; - } - case SETTINGS_UPDATED: - _maybeHandleCallIntegrationChange(action); - _maybeSetAudioOnly(store, action); - _updateLocalParticipant(store, action); - _maybeCrashReportingChange(action); - break; - case SET_LOCATION_URL: - _updateLocalParticipantFromUrl(store); - break; - } - - return result; -}); - -/** - * Overwrites the showPrejoin flag based on cached used selection for showing prejoin screen. - * - * @param {Store} store - The redux store. - * @private - * @returns {void} - */ -function _initializeShowPrejoin({ dispatch, getState }: IStore) { - const { userSelectedSkipPrejoin } = getState()['features/base/settings']; - - if (userSelectedSkipPrejoin) { - dispatch(setPrejoinPageVisibility(false)); - } -} - -/** - * Initializes the audio device handler based on the `disableCallIntegration` setting. - * - * @param {Store} store - The redux store. - * @private - * @returns {void} - */ -function _initializeCallIntegration({ getState }: IStore) { - const { disableCallIntegration } = getState()['features/base/settings']; - - if (typeof disableCallIntegration === 'boolean') { - handleCallIntegrationChange(disableCallIntegration); - } -} - -/** - * Maps the settings field names to participant names where they don't match. - * Currently there is only one such field, but may be extended in the future. - * - * @private - * @param {string} settingsField - The name of the settings field to map. - * @returns {string} - */ -function _mapSettingsFieldToParticipant(settingsField: string) { - switch (settingsField) { - case 'displayName': - return 'name'; - } - - return settingsField; -} - -/** - * Handles a change in the `disableCallIntegration` setting. - * - * @param {Object} action - The redux action. - * @private - * @returns {void} - */ -function _maybeHandleCallIntegrationChange({ settings: { disableCallIntegration } }: { - settings: Partial; -}) { - if (typeof disableCallIntegration === 'boolean') { - handleCallIntegrationChange(disableCallIntegration); - } -} - -/** - * Handles a change in the `disableCrashReporting` setting. - * - * @param {Object} action - The redux action. - * @private - * @returns {void} - */ -function _maybeCrashReportingChange({ settings: { disableCrashReporting } }: { - settings: Partial; -}) { - if (typeof disableCrashReporting === 'boolean') { - handleCrashReportingChange(disableCrashReporting); - } -} - -/** - * Updates {@code startAudioOnly} flag if it's updated in the settings. - * - * @param {Store} store - The redux store. - * @param {Object} action - The redux action. - * @private - * @returns {void} - */ -function _maybeSetAudioOnly( - { dispatch }: IStore, - { settings: { startAudioOnly } }: { settings: Partial; }) { - if (typeof startAudioOnly === 'boolean') { - dispatch(setAudioOnly(startAudioOnly)); - } -} - -/** - * Updates the display name to the one in JWT if there is one. - * - * @param {Store} store - The redux store. - * @private - * @returns {void} - */ -function _maybeUpdateDisplayName({ dispatch, getState }: IStore) { - const state = getState(); - const hasJwt = Boolean(state['features/base/jwt'].jwt); - - if (hasJwt) { - const displayName = getJwtName(state); - - if (displayName) { - dispatch(updateSettings({ - displayName - })); - } - } -} - -/** - * Updates the local participant according to settings changes. - * - * @param {Store} store - The redux store. - * @param {Object} action - The dispatched action. - * @private - * @returns {void} - */ -function _updateLocalParticipant({ dispatch, getState }: IStore, action: AnyAction) { - const { settings } = action; - const localParticipant = getLocalParticipant(getState()); - const newLocalParticipant = { - ...localParticipant - }; - - for (const key in settings) { - if (settings.hasOwnProperty(key)) { - newLocalParticipant[_mapSettingsFieldToParticipant(key) as keyof typeof newLocalParticipant] - = settings[key]; - } - } - - dispatch(participantUpdated({ - ...newLocalParticipant, - id: newLocalParticipant.id ?? '' - })); -} - - -/** - * Returns the userInfo set in the URL. - * - * @param {Store} store - The redux store. - * @private - * @returns {void} - */ -function _updateLocalParticipantFromUrl({ dispatch, getState }: IStore) { - const urlParams - = parseURLParams(getState()['features/base/connection'].locationURL ?? ''); - const urlEmail = urlParams['userInfo.email']; - const urlDisplayName = urlParams['userInfo.displayName']; - - if (!urlEmail && !urlDisplayName) { - return; - } - - const localParticipant = getLocalParticipant(getState()); - - if (localParticipant) { - const displayName = _.escape(urlDisplayName); - const email = _.escape(urlEmail); - - dispatch(participantUpdated({ - ...localParticipant, - email, - name: displayName - })); - - dispatch(updateSettings({ - displayName, - email - })); - } -} diff --git a/react/features/base/settings/middleware.web.ts b/react/features/base/settings/middleware.web.ts new file mode 100644 index 000000000..6a91cb617 --- /dev/null +++ b/react/features/base/settings/middleware.web.ts @@ -0,0 +1,70 @@ +import { IStore } from '../../app/types'; +import { PREJOIN_INITIALIZED } from '../../prejoin/actionTypes'; +import { setPrejoinPageVisibility } from '../../prejoin/actions'; +import { APP_WILL_MOUNT } from '../app/actionTypes'; +import { getJwtName } from '../jwt/functions'; +import MiddlewareRegistry from '../redux/MiddlewareRegistry'; + +import { updateSettings } from './actions'; + +import './middleware.any'; + +/** + * The middleware of the feature base/settings. Distributes changes to the state + * of base/settings to the states of other features computed from the state of + * base/settings. + * + * @param {Store} store - The redux store. + * @returns {Function} + */ +MiddlewareRegistry.register(store => next => action => { + const result = next(action); + + switch (action.type) { + case APP_WILL_MOUNT: + _initializeShowPrejoin(store); + break; + case PREJOIN_INITIALIZED: + _maybeUpdateDisplayName(store); + break; + } + + return result; +}); + +/** + * Overwrites the showPrejoin flag based on cached used selection for showing prejoin screen. + * + * @param {Store} store - The redux store. + * @private + * @returns {void} + */ +function _initializeShowPrejoin({ dispatch, getState }: IStore) { + const { userSelectedSkipPrejoin } = getState()['features/base/settings']; + + if (userSelectedSkipPrejoin) { + dispatch(setPrejoinPageVisibility(false)); + } +} + +/** + * Updates the display name to the one in JWT if there is one. + * + * @param {Store} store - The redux store. + * @private + * @returns {void} + */ +function _maybeUpdateDisplayName({ dispatch, getState }: IStore) { + const state = getState(); + const hasJwt = Boolean(state['features/base/jwt'].jwt); + + if (hasJwt) { + const displayName = getJwtName(state); + + if (displayName) { + dispatch(updateSettings({ + displayName + })); + } + } +} diff --git a/react/features/base/tracks/actions.native.ts b/react/features/base/tracks/actions.native.ts index acacf1c36..e1fb4f545 100644 --- a/react/features/base/tracks/actions.native.ts +++ b/react/features/base/tracks/actions.native.ts @@ -15,9 +15,12 @@ export * from './actions.any'; * Signals that the local participant is ending screensharing or beginning the screensharing flow. * * @param {boolean} enabled - The state to toggle screen sharing to. + * @param {boolean} _ignore1 - Ignored. + * @param {boolean} _ignore2 - Ignored. + * @param {Object} _ignore3 - Ignored. * @returns {Function} */ -export function toggleScreensharing(enabled: boolean) { +export function toggleScreensharing(enabled: boolean, _ignore1?: boolean, _ignore2?: boolean, _ignore3?: any) { return (dispatch: IStore['dispatch'], getState: IStore['getState']) => { const state = getState(); diff --git a/react/features/base/ui/components/GlobalStyles.tsx b/react/features/base/ui/components/GlobalStyles.web.tsx similarity index 100% rename from react/features/base/ui/components/GlobalStyles.tsx rename to react/features/base/ui/components/GlobalStyles.web.tsx diff --git a/react/features/base/ui/components/web/ContextMenu.tsx b/react/features/base/ui/components/web/ContextMenu.tsx index d2abda9a5..15434e8d7 100644 --- a/react/features/base/ui/components/web/ContextMenu.tsx +++ b/react/features/base/ui/components/web/ContextMenu.tsx @@ -3,7 +3,6 @@ import React, { ReactNode, useEffect, useLayoutEffect, useRef, useState } from ' import { useSelector } from 'react-redux'; import { makeStyles } from 'tss-react/mui'; -import { getComputedOuterHeight } from '../../../../participants-pane/functions'; // eslint-disable-next-line lines-around-comment // @ts-ignore import { Drawer, JitsiPortal } from '../../../../toolbox/components/web'; @@ -11,6 +10,30 @@ import { showOverflowDrawer } from '../../../../toolbox/functions.web'; import participantsPaneTheme from '../../../components/themes/participantsPaneTheme.json'; import { withPixelLineHeight } from '../../../styles/functions.web'; +/** + * Get a style property from a style declaration as a float. + * + * @param {CSSStyleDeclaration} styles - Style declaration. + * @param {string} name - Property name. + * @returns {number} Float value. + */ +const getFloatStyleProperty = (styles: CSSStyleDeclaration, name: string) => + parseFloat(styles.getPropertyValue(name)); + +/** +* Gets the outer height of an element, including margins. +* +* @param {Element} element - Target element. +* @returns {number} Computed height. +*/ +const getComputedOuterHeight = (element: HTMLElement) => { + const computedStyle = getComputedStyle(element); + + return element.offsetHeight + + getFloatStyleProperty(computedStyle, 'margin-top') + + getFloatStyleProperty(computedStyle, 'margin-bottom'); +}; + type Props = { /** diff --git a/react/features/base/ui/constants.any.ts b/react/features/base/ui/constants.any.ts new file mode 100644 index 000000000..916f541e0 --- /dev/null +++ b/react/features/base/ui/constants.any.ts @@ -0,0 +1,18 @@ +/** + * The types of the buttons. + */ +export enum BUTTON_TYPES { + DESTRUCTIVE = 'destructive', + PRIMARY = 'primary', + SECONDARY = 'secondary', + TERTIARY = 'tertiary' +} + +/** + * The modes of the buttons. + */ +export const BUTTON_MODES: { + CONTAINED: 'contained'; +} = { + CONTAINED: 'contained' +}; diff --git a/react/features/base/ui/constants.native.ts b/react/features/base/ui/constants.native.ts new file mode 100644 index 000000000..24ab54110 --- /dev/null +++ b/react/features/base/ui/constants.native.ts @@ -0,0 +1 @@ +export * from './constants.any'; diff --git a/react/features/base/ui/constants.ts b/react/features/base/ui/constants.web.ts similarity index 96% rename from react/features/base/ui/constants.ts rename to react/features/base/ui/constants.web.ts index 09924d4b1..fdb15ec39 100644 --- a/react/features/base/ui/constants.ts +++ b/react/features/base/ui/constants.web.ts @@ -1,23 +1,6 @@ import { Theme } from '@mui/material'; -/** - * The types of the buttons. - */ -export enum BUTTON_TYPES { - DESTRUCTIVE = 'destructive', - PRIMARY = 'primary', - SECONDARY = 'secondary', - TERTIARY = 'tertiary' -} - -/** - * The modes of the buttons. - */ -export const BUTTON_MODES: { - CONTAINED: 'contained'; -} = { - CONTAINED: 'contained' -}; +export * from './constants.any'; /** * Returns an object containing the declaration of the common, reusable CSS classes. diff --git a/react/features/base/ui/functions.web.ts b/react/features/base/ui/functions.web.ts index 3c4ee6e5c..080717e8f 100644 --- a/react/features/base/ui/functions.web.ts +++ b/react/features/base/ui/functions.web.ts @@ -45,3 +45,17 @@ export function createWebTheme({ font, colors, colorMap, shape, spacing, typogra })); } +/** + * Find the first styled ancestor component of an element. + * + * @param {HTMLElement|null} target - Element to look up. + * @param {string} cssClass - Styled component reference. + * @returns {HTMLElement|null} Ancestor. + */ +export const findAncestorByClass = (target: HTMLElement | null, cssClass: string): HTMLElement | null => { + if (!target || target.classList.contains(cssClass)) { + return target; + } + + return findAncestorByClass(target.parentElement, cssClass); +}; diff --git a/react/features/base/ui/hooks/useContextMenu.web.ts b/react/features/base/ui/hooks/useContextMenu.web.ts index a9acb4c62..e0ba3341f 100644 --- a/react/features/base/ui/hooks/useContextMenu.web.ts +++ b/react/features/base/ui/hooks/useContextMenu.web.ts @@ -1,6 +1,6 @@ import { useCallback, useRef, useState } from 'react'; -import { findAncestorByClass } from '../../../participants-pane/functions'; +import { findAncestorByClass } from '../functions.web'; type RaiseContext = { diff --git a/react/features/base/util/downloadJSON.ts b/react/features/base/util/downloadJSON.web.ts similarity index 100% rename from react/features/base/util/downloadJSON.ts rename to react/features/base/util/downloadJSON.web.ts diff --git a/react/features/base/util/openURLInBrowser.native.ts b/react/features/base/util/openURLInBrowser.native.ts index c8a740f09..d7776e2e8 100644 --- a/react/features/base/util/openURLInBrowser.native.ts +++ b/react/features/base/util/openURLInBrowser.native.ts @@ -6,9 +6,10 @@ import logger from './logger'; * Opens URL in the browser. * * @param {string} url - The URL to be opened. + * @param {boolean} _ignore - Ignored. * @returns {void} */ -export function openURLInBrowser(url: string) { +export function openURLInBrowser(url: string, _ignore?: boolean) { Linking.openURL(url).catch(error => { logger.error(`An error occurred while trying to open ${url}`, error); }); diff --git a/react/features/conference/components/web/Conference.js b/react/features/conference/components/web/Conference.js index b1070f592..8e112aee8 100644 --- a/react/features/conference/components/web/Conference.js +++ b/react/features/conference/components/web/Conference.js @@ -17,7 +17,8 @@ import { LargeVideo } from '../../../large-video'; import { LobbyScreen } from '../../../lobby'; import { getIsLobbyVisible } from '../../../lobby/functions'; import { ParticipantsPane } from '../../../participants-pane/components/web'; -import { Prejoin, isPrejoinPageVisible } from '../../../prejoin'; +import Prejoin from '../../../prejoin/components/web/Prejoin'; +import { isPrejoinPageVisible } from '../../../prejoin/functions'; import { toggleToolboxVisible } from '../../../toolbox/actions.any'; import { fullScreenChanged, showToolbox } from '../../../toolbox/actions.web'; import { JitsiPortal, Toolbox } from '../../../toolbox/components/web'; diff --git a/react/features/mobile/navigation/components/RootNavigationContainer.js b/react/features/mobile/navigation/components/RootNavigationContainer.js index f0157525e..43d2fd5ff 100644 --- a/react/features/mobile/navigation/components/RootNavigationContainer.js +++ b/react/features/mobile/navigation/components/RootNavigationContainer.js @@ -4,7 +4,7 @@ import React, { useCallback } from 'react'; import { connect } from '../../../base/redux'; import { DialInSummary } from '../../../invite'; -import Prejoin from '../../../prejoin/components/Prejoin.native'; +import Prejoin from '../../../prejoin/components/native/Prejoin'; import WelcomePage from '../../../welcome/components/WelcomePage'; import { isWelcomePageEnabled } from '../../../welcome/functions'; import { _ROOT_NAVIGATION_READY } from '../actionTypes'; diff --git a/react/features/notifications/actions.ts b/react/features/notifications/actions.ts index ea293fe0d..d63609395 100644 --- a/react/features/notifications/actions.ts +++ b/react/features/notifications/actions.ts @@ -128,7 +128,7 @@ export function showNotification(props: INotificationProps = {}, type?: string) type: SHOW_NOTIFICATION, props, timeout: getNotificationTimeout(type, notificationTimeouts), - uid: props.uid || window.Date.now().toString() + uid: props.uid || Date.now().toString() }); } }; diff --git a/react/features/participants-pane/components/web/ParticipantsPane.tsx b/react/features/participants-pane/components/web/ParticipantsPane.tsx index 8672663a1..57c52a8fb 100644 --- a/react/features/participants-pane/components/web/ParticipantsPane.tsx +++ b/react/features/participants-pane/components/web/ParticipantsPane.tsx @@ -13,12 +13,12 @@ import { isLocalParticipantModerator } from '../../../base/participants/function import Button from '../../../base/ui/components/web/Button'; import ClickableIcon from '../../../base/ui/components/web/ClickableIcon'; import { BUTTON_TYPES } from '../../../base/ui/constants'; +import { findAncestorByClass } from '../../../base/ui/functions.web'; import { isAddBreakoutRoomButtonVisible } from '../../../breakout-rooms/functions'; // @ts-ignore import { MuteEveryoneDialog } from '../../../video-menu/components/'; import { close } from '../../actions'; import { - findAncestorByClass, getParticipantsPaneOpen, isMoreActionsVisible, isMuteAllVisible diff --git a/react/features/participants-pane/functions.ts b/react/features/participants-pane/functions.ts index 664a1e03e..e5ecd8698 100644 --- a/react/features/participants-pane/functions.ts +++ b/react/features/participants-pane/functions.ts @@ -24,21 +24,6 @@ import { isInBreakoutRoom } from '../breakout-rooms/functions'; import { MEDIA_STATE, QUICK_ACTION_BUTTON, REDUCER_KEY } from './constants'; -/** - * Find the first styled ancestor component of an element. - * - * @param {HTMLElement|null} target - Element to look up. - * @param {string} cssClass - Styled component reference. - * @returns {HTMLElement|null} Ancestor. - */ -export const findAncestorByClass = (target: HTMLElement | null, cssClass: string): HTMLElement | null => { - if (!target || target.classList.contains(cssClass)) { - return target; - } - - return findAncestorByClass(target.parentElement, cssClass); -}; - /** * Checks if a participant is force muted. * @@ -110,31 +95,6 @@ export function getParticipantVideoMediaState(participant: IParticipant, muted: return MEDIA_STATE.UNMUTED; } - -/** - * Get a style property from a style declaration as a float. - * - * @param {CSSStyleDeclaration} styles - Style declaration. - * @param {string} name - Property name. - * @returns {number} Float value. - */ -export const getFloatStyleProperty = (styles: CSSStyleDeclaration, name: string) => - parseFloat(styles.getPropertyValue(name)); - -/** - * Gets the outer height of an element, including margins. - * - * @param {Element} element - Target element. - * @returns {number} Computed height. - */ -export const getComputedOuterHeight = (element: HTMLElement) => { - const computedStyle = getComputedStyle(element); - - return element.offsetHeight - + getFloatStyleProperty(computedStyle, 'margin-top') - + getFloatStyleProperty(computedStyle, 'margin-bottom'); -}; - /** * Returns this feature's root state. * diff --git a/react/features/prejoin/actions.ts b/react/features/prejoin/actions.web.ts similarity index 100% rename from react/features/prejoin/actions.ts rename to react/features/prejoin/actions.web.ts diff --git a/react/features/prejoin/components/Prejoin.native.tsx b/react/features/prejoin/components/native/Prejoin.tsx similarity index 78% rename from react/features/prejoin/components/Prejoin.native.tsx rename to react/features/prejoin/components/native/Prejoin.tsx index 1c545f9f0..e88f57639 100644 --- a/react/features/prejoin/components/Prejoin.native.tsx +++ b/react/features/prejoin/components/native/Prejoin.tsx @@ -15,40 +15,39 @@ import { import { useDispatch, useSelector } from 'react-redux'; // @ts-ignore -import { appNavigate } from '../../app/actions.native'; -import { IReduxState } from '../../app/types'; -import { setAudioOnly } from '../../base/audio-only/actions'; -import { getConferenceName } from '../../base/conference/functions'; -import { connect } from '../../base/connection/actions.native'; -import { IconClose } from '../../base/icons/svg'; +import { appNavigate } from '../../../app/actions.native'; +import { IReduxState } from '../../../app/types'; +import { setAudioOnly } from '../../../base/audio-only/actions'; +import { getConferenceName } from '../../../base/conference/functions'; +import { connect } from '../../../base/connection/actions.native'; +import { IconClose } from '../../../base/icons/svg'; // @ts-ignore -import JitsiScreen from '../../base/modal/components/JitsiScreen'; -import { getLocalParticipant } from '../../base/participants/functions'; +import JitsiScreen from '../../../base/modal/components/JitsiScreen'; +import { getLocalParticipant } from '../../../base/participants/functions'; // @ts-ignore -import { getFieldValue } from '../../base/react'; -import { ASPECT_RATIO_NARROW } from '../../base/responsive-ui/constants'; -import { updateSettings } from '../../base/settings/actions'; -import BaseTheme from '../../base/ui/components/BaseTheme.native'; -import Button from '../../base/ui/components/native/Button'; -import { BUTTON_TYPES } from '../../base/ui/constants'; -import { BrandingImageBackground } from '../../dynamic-branding/components/native'; +import { getFieldValue } from '../../../base/react'; +import { ASPECT_RATIO_NARROW } from '../../../base/responsive-ui/constants'; +import { updateSettings } from '../../../base/settings/actions'; +import BaseTheme from '../../../base/ui/components/BaseTheme.native'; +import Button from '../../../base/ui/components/native/Button'; +import { BUTTON_TYPES } from '../../../base/ui/constants'; +import { BrandingImageBackground } from '../../../dynamic-branding/components/native'; // @ts-ignore -import { LargeVideo } from '../../large-video/components'; +import { LargeVideo } from '../../../large-video/components'; // @ts-ignore -import HeaderNavigationButton from '../../mobile/navigation/components/HeaderNavigationButton'; +import HeaderNavigationButton from '../../../mobile/navigation/components/HeaderNavigationButton'; // @ts-ignore -import { navigateRoot } from '../../mobile/navigation/rootNavigationContainerRef'; +import { navigateRoot } from '../../../mobile/navigation/rootNavigationContainerRef'; // @ts-ignore -import { screen } from '../../mobile/navigation/routes'; +import { screen } from '../../../mobile/navigation/routes'; // @ts-ignore -import AudioMuteButton from '../../toolbox/components/AudioMuteButton'; +import AudioMuteButton from '../../../toolbox/components/AudioMuteButton'; // @ts-ignore -import VideoMuteButton from '../../toolbox/components/VideoMuteButton'; -import { isDisplayNameRequired } from '../functions'; -import { IPrejoinProps } from '../types'; - +import VideoMuteButton from '../../../toolbox/components/VideoMuteButton'; +import { isDisplayNameRequired } from '../../functions'; +import { IPrejoinProps } from '../../types'; // @ts-ignore -import styles from './styles'; +import styles from '../styles'; const Prejoin: React.FC = ({ navigation }: IPrejoinProps) => { diff --git a/react/features/prejoin/components/DropdownButton.tsx b/react/features/prejoin/components/web/DropdownButton.tsx similarity index 97% rename from react/features/prejoin/components/DropdownButton.tsx rename to react/features/prejoin/components/web/DropdownButton.tsx index 5db4d531f..92db46610 100644 --- a/react/features/prejoin/components/DropdownButton.tsx +++ b/react/features/prejoin/components/web/DropdownButton.tsx @@ -2,7 +2,7 @@ import { Theme } from '@mui/material'; import React from 'react'; import { makeStyles } from 'tss-react/mui'; -import Icon from '../../base/icons/components/Icon'; +import Icon from '../../../base/icons/components/Icon'; type Props = { diff --git a/react/features/prejoin/components/Label.js b/react/features/prejoin/components/web/Label.js similarity index 100% rename from react/features/prejoin/components/Label.js rename to react/features/prejoin/components/web/Label.js diff --git a/react/features/prejoin/components/Prejoin.web.js b/react/features/prejoin/components/web/Prejoin.js similarity index 96% rename from react/features/prejoin/components/Prejoin.web.js rename to react/features/prejoin/components/web/Prejoin.js index 4fd132519..d9c84f135 100644 --- a/react/features/prejoin/components/Prejoin.web.js +++ b/react/features/prejoin/components/web/Prejoin.js @@ -3,28 +3,28 @@ import InlineDialog from '@atlaskit/inline-dialog'; import React, { Component } from 'react'; -import { Avatar } from '../../base/avatar'; -import { isNameReadOnly } from '../../base/config'; -import { translate } from '../../base/i18n'; -import { IconArrowDown, IconArrowUp, IconPhone, IconVolumeOff } from '../../base/icons'; -import { isVideoMutedByUser } from '../../base/media'; -import { getLocalParticipant } from '../../base/participants'; -import { ActionButton, InputField, PreMeetingScreen } from '../../base/premeeting'; -import { connect } from '../../base/redux'; -import { getDisplayName, updateSettings } from '../../base/settings'; -import { getLocalJitsiVideoTrack } from '../../base/tracks'; +import { Avatar } from '../../../base/avatar'; +import { isNameReadOnly } from '../../../base/config'; +import { translate } from '../../../base/i18n'; +import { IconArrowDown, IconArrowUp, IconPhone, IconVolumeOff } from '../../../base/icons'; +import { isVideoMutedByUser } from '../../../base/media'; +import { getLocalParticipant } from '../../../base/participants'; +import { ActionButton, InputField, PreMeetingScreen } from '../../../base/premeeting'; +import { connect } from '../../../base/redux'; +import { getDisplayName, updateSettings } from '../../../base/settings'; +import { getLocalJitsiVideoTrack } from '../../../base/tracks'; import { joinConference as joinConferenceAction, joinConferenceWithoutAudio as joinConferenceWithoutAudioAction, setJoinByPhoneDialogVisiblity as setJoinByPhoneDialogVisiblityAction -} from '../actions'; +} from '../../actions'; import { isDeviceStatusVisible, isDisplayNameRequired, isJoinByPhoneButtonVisible, isJoinByPhoneDialogVisible, isPrejoinDisplayNameVisible -} from '../functions'; +} from '../../functions'; import DropdownButton from './DropdownButton'; import JoinByPhoneDialog from './dialogs/JoinByPhoneDialog'; diff --git a/react/features/prejoin/components/PrejoinApp.js b/react/features/prejoin/components/web/PrejoinApp.js similarity index 82% rename from react/features/prejoin/components/PrejoinApp.js rename to react/features/prejoin/components/web/PrejoinApp.js index 622fca112..63ebd0802 100644 --- a/react/features/prejoin/components/PrejoinApp.js +++ b/react/features/prejoin/components/web/PrejoinApp.js @@ -4,14 +4,14 @@ import { AtlasKitThemeProvider } from '@atlaskit/theme'; import React from 'react'; import { batch } from 'react-redux'; -import { BaseApp } from '../../../features/base/app'; -import { getConferenceOptions } from '../../base/conference/functions'; -import { setConfig } from '../../base/config'; -import { DialogContainer } from '../../base/dialog'; -import { createPrejoinTracks } from '../../base/tracks'; -import GlobalStyles from '../../base/ui/components/GlobalStyles'; -import JitsiThemeProvider from '../../base/ui/components/JitsiThemeProvider.web'; -import { initPrejoin, makePrecallTest } from '../actions'; +import { BaseApp } from '../../../base/app'; +import { getConferenceOptions } from '../../../base/conference/functions'; +import { setConfig } from '../../../base/config'; +import { DialogContainer } from '../../../base/dialog'; +import { createPrejoinTracks } from '../../../base/tracks'; +import GlobalStyles from '../../../base/ui/components/GlobalStyles.web'; +import JitsiThemeProvider from '../../../base/ui/components/JitsiThemeProvider.web'; +import { initPrejoin, makePrecallTest } from '../../actions'; import PrejoinThirdParty from './PrejoinThirdParty'; diff --git a/react/features/prejoin/components/PrejoinThirdParty.js b/react/features/prejoin/components/web/PrejoinThirdParty.js similarity index 84% rename from react/features/prejoin/components/PrejoinThirdParty.js rename to react/features/prejoin/components/web/PrejoinThirdParty.js index 273bc7fc7..480fa3526 100644 --- a/react/features/prejoin/components/PrejoinThirdParty.js +++ b/react/features/prejoin/components/web/PrejoinThirdParty.js @@ -2,12 +2,12 @@ import React, { Component } from 'react'; -import { translate } from '../../base/i18n'; -import { isVideoMutedByUser } from '../../base/media'; -import { PreMeetingScreen } from '../../base/premeeting'; -import { connect } from '../../base/redux'; -import { getLocalJitsiVideoTrack } from '../../base/tracks'; -import { isDeviceStatusVisible } from '../functions'; +import { translate } from '../../../base/i18n'; +import { isVideoMutedByUser } from '../../../base/media'; +import { PreMeetingScreen } from '../../../base/premeeting'; +import { connect } from '../../../base/redux'; +import { getLocalJitsiVideoTrack } from '../../../base/tracks'; +import { isDeviceStatusVisible } from '../../functions'; type Props = { diff --git a/react/features/prejoin/components/country-picker/CountryDropdown.js b/react/features/prejoin/components/web/country-picker/CountryDropdown.js similarity index 93% rename from react/features/prejoin/components/country-picker/CountryDropdown.js rename to react/features/prejoin/components/web/country-picker/CountryDropdown.js index eec726f1f..a8beb333d 100644 --- a/react/features/prejoin/components/country-picker/CountryDropdown.js +++ b/react/features/prejoin/components/web/country-picker/CountryDropdown.js @@ -2,7 +2,7 @@ import React from 'react'; -import { countries } from '../../utils'; +import { countries } from '../../../utils'; import CountryRow from './CountryRow'; diff --git a/react/features/prejoin/components/country-picker/CountryPicker.js b/react/features/prejoin/components/web/country-picker/CountryPicker.js similarity index 95% rename from react/features/prejoin/components/country-picker/CountryPicker.js rename to react/features/prejoin/components/web/country-picker/CountryPicker.js index b7ded1fe6..8ef3ee940 100644 --- a/react/features/prejoin/components/country-picker/CountryPicker.js +++ b/react/features/prejoin/components/web/country-picker/CountryPicker.js @@ -3,10 +3,10 @@ import InlineDialog from '@atlaskit/inline-dialog'; import React, { PureComponent } from 'react'; -import { connect } from '../../../base/redux'; -import { setDialOutCountry, setDialOutNumber } from '../../actions'; -import { getDialOutCountry, getDialOutNumber } from '../../functions'; -import { getCountryFromDialCodeText } from '../../utils'; +import { connect } from '../../../../base/redux'; +import { setDialOutCountry, setDialOutNumber } from '../../../actions.web'; +import { getDialOutCountry, getDialOutNumber } from '../../../functions'; +import { getCountryFromDialCodeText } from '../../../utils'; import CountryDropDown from './CountryDropdown'; import CountrySelector from './CountrySelector'; diff --git a/react/features/prejoin/components/country-picker/CountryRow.js b/react/features/prejoin/components/web/country-picker/CountryRow.js similarity index 100% rename from react/features/prejoin/components/country-picker/CountryRow.js rename to react/features/prejoin/components/web/country-picker/CountryRow.js diff --git a/react/features/prejoin/components/country-picker/CountrySelector.js b/react/features/prejoin/components/web/country-picker/CountrySelector.js similarity index 94% rename from react/features/prejoin/components/country-picker/CountrySelector.js rename to react/features/prejoin/components/web/country-picker/CountrySelector.js index ee0deac92..da4b727a8 100644 --- a/react/features/prejoin/components/country-picker/CountrySelector.js +++ b/react/features/prejoin/components/web/country-picker/CountrySelector.js @@ -2,7 +2,7 @@ import React, { useCallback } from 'react'; -import { Icon, IconArrowDown } from '../../../base/icons'; +import { Icon, IconArrowDown } from '../../../../base/icons'; type Props = { diff --git a/react/features/prejoin/components/dialogs/CallingDialog.tsx b/react/features/prejoin/components/web/dialogs/CallingDialog.tsx similarity index 90% rename from react/features/prejoin/components/dialogs/CallingDialog.tsx rename to react/features/prejoin/components/web/dialogs/CallingDialog.tsx index 023d16624..50e92b32f 100644 --- a/react/features/prejoin/components/dialogs/CallingDialog.tsx +++ b/react/features/prejoin/components/web/dialogs/CallingDialog.tsx @@ -6,10 +6,10 @@ import { WithTranslation } from 'react-i18next'; import { makeStyles } from 'tss-react/mui'; // @ts-ignore -import { Avatar } from '../../../base/avatar'; -import { translate } from '../../../base/i18n/functions'; -import Icon from '../../../base/icons/components/Icon'; -import { IconClose } from '../../../base/icons/svg'; +import { Avatar } from '../../../../base/avatar'; +import { translate } from '../../../../base/i18n/functions'; +import Icon from '../../../../base/icons/components/Icon'; +import { IconClose } from '../../../../base/icons/svg'; // @ts-ignore import Label from '../Label'; diff --git a/react/features/prejoin/components/dialogs/DialInDialog.tsx b/react/features/prejoin/components/web/dialogs/DialInDialog.tsx similarity index 94% rename from react/features/prejoin/components/dialogs/DialInDialog.tsx rename to react/features/prejoin/components/web/dialogs/DialInDialog.tsx index 2fb764226..93cf1bc0e 100644 --- a/react/features/prejoin/components/dialogs/DialInDialog.tsx +++ b/react/features/prejoin/components/web/dialogs/DialInDialog.tsx @@ -5,12 +5,12 @@ import React from 'react'; import { WithTranslation } from 'react-i18next'; import { makeStyles } from 'tss-react/mui'; -import { translate } from '../../../base/i18n/functions'; -import Icon from '../../../base/icons/components/Icon'; -import { IconArrowLeft } from '../../../base/icons/svg'; -import { Button } from '../../../base/ui/components/web'; +import { translate } from '../../../../base/i18n/functions'; +import Icon from '../../../../base/icons/components/Icon'; +import { IconArrowLeft } from '../../../../base/icons/svg'; +import { Button } from '../../../../base/ui/components/web'; // @ts-ignore -import { getCountryCodeFromPhone } from '../../utils'; +import { getCountryCodeFromPhone } from '../../../utils'; // @ts-ignore import Label from '../Label'; diff --git a/react/features/prejoin/components/dialogs/DialOutDialog.tsx b/react/features/prejoin/components/web/dialogs/DialOutDialog.tsx similarity index 92% rename from react/features/prejoin/components/dialogs/DialOutDialog.tsx rename to react/features/prejoin/components/web/dialogs/DialOutDialog.tsx index b71987797..5b7725008 100644 --- a/react/features/prejoin/components/dialogs/DialOutDialog.tsx +++ b/react/features/prejoin/components/web/dialogs/DialOutDialog.tsx @@ -5,10 +5,10 @@ import React from 'react'; import { WithTranslation } from 'react-i18next'; import { makeStyles } from 'tss-react/mui'; -import { translate } from '../../../base/i18n/functions'; -import Icon from '../../../base/icons/components/Icon'; -import { IconClose } from '../../../base/icons/svg'; -import { Button } from '../../../base/ui/components/web'; +import { translate } from '../../../../base/i18n/functions'; +import Icon from '../../../../base/icons/components/Icon'; +import { IconClose } from '../../../../base/icons/svg'; +import { Button } from '../../../../base/ui/components/web'; // @ts-ignore import Label from '../Label'; // @ts-ignore diff --git a/react/features/prejoin/components/dialogs/JoinByPhoneDialog.js b/react/features/prejoin/components/web/dialogs/JoinByPhoneDialog.js similarity index 97% rename from react/features/prejoin/components/dialogs/JoinByPhoneDialog.js rename to react/features/prejoin/components/web/dialogs/JoinByPhoneDialog.js index 6e7b82ceb..72dfad2a7 100644 --- a/react/features/prejoin/components/dialogs/JoinByPhoneDialog.js +++ b/react/features/prejoin/components/web/dialogs/JoinByPhoneDialog.js @@ -2,18 +2,18 @@ import React, { PureComponent } from 'react'; -import { connect } from '../../../base/redux'; +import { connect } from '../../../../base/redux'; import { getConferenceId, getDefaultDialInNumber, updateDialInNumbers -} from '../../../invite'; +} from '../../../../invite'; import { dialOut as dialOutAction, joinConferenceWithoutAudio as joinConferenceWithoutAudioAction, openDialInPage as openDialInPageAction -} from '../../actions'; -import { getDialOutStatus, getFullDialOutNumber } from '../../functions'; +} from '../../../actions'; +import { getDialOutStatus, getFullDialOutNumber } from '../../../functions'; import CallingDialog from './CallingDialog'; import DialInDialog from './DialInDialog'; diff --git a/react/features/prejoin/components/preview/DeviceStatus.tsx b/react/features/prejoin/components/web/preview/DeviceStatus.tsx similarity index 92% rename from react/features/prejoin/components/preview/DeviceStatus.tsx rename to react/features/prejoin/components/web/preview/DeviceStatus.tsx index b7907a2e8..ed6997983 100644 --- a/react/features/prejoin/components/preview/DeviceStatus.tsx +++ b/react/features/prejoin/components/web/preview/DeviceStatus.tsx @@ -3,15 +3,15 @@ import React from 'react'; import { WithTranslation } from 'react-i18next'; import { makeStyles } from 'tss-react/mui'; -import { IReduxState } from '../../../app/types'; -import { translate } from '../../../base/i18n/functions'; -import Icon from '../../../base/icons/components/Icon'; -import { IconCheckSolid, IconExclamationTriangle } from '../../../base/icons/svg'; -import { connect } from '../../../base/redux/functions'; +import { IReduxState } from '../../../../app/types'; +import { translate } from '../../../../base/i18n/functions'; +import Icon from '../../../../base/icons/components/Icon'; +import { IconCheckSolid, IconExclamationTriangle } from '../../../../base/icons/svg'; +import { connect } from '../../../../base/redux/functions'; import { getDeviceStatusText, getDeviceStatusType -} from '../../functions'; +} from '../../../functions'; export interface IProps extends WithTranslation { diff --git a/react/features/prejoin/index.js b/react/features/prejoin/index.js deleted file mode 100644 index 5c58a5f3f..000000000 --- a/react/features/prejoin/index.js +++ /dev/null @@ -1,4 +0,0 @@ -export * from './actions'; -export * from './functions'; - -export { default as Prejoin } from './components/Prejoin'; diff --git a/react/features/prejoin/middleware.ts b/react/features/prejoin/middleware.web.ts similarity index 100% rename from react/features/prejoin/middleware.ts rename to react/features/prejoin/middleware.web.ts diff --git a/react/features/remote-control/actions.js b/react/features/remote-control/actions.js index f1361b8b9..883eae2d5 100644 --- a/react/features/remote-control/actions.js +++ b/react/features/remote-control/actions.js @@ -13,7 +13,7 @@ import { } from '../base/participants'; import { getLocalDesktopTrack, getLocalVideoTrack, toggleScreensharing } from '../base/tracks'; import { NOTIFICATION_TIMEOUT_TYPE, showNotification } from '../notifications'; -import { isScreenVideoShared } from '../screen-share'; +import { isScreenVideoShared } from '../screen-share/functions'; import { CAPTURE_EVENTS, diff --git a/react/features/room-lock/actions.ts b/react/features/room-lock/actions.ts index 73ac246f5..5e9deaa3c 100644 --- a/react/features/room-lock/actions.ts +++ b/react/features/room-lock/actions.ts @@ -1,7 +1,7 @@ import { appNavigate, maybeRedirectToWelcomePage -} from '../app/actions.web'; +} from '../app/actions'; import { IStore } from '../app/types'; import { conferenceLeft, setPassword } from '../base/conference/actions'; import { JITSI_CONFERENCE_URL_KEY } from '../base/conference/constants'; @@ -29,6 +29,8 @@ export function _cancelPasswordRequiredPrompt(conference: any) { // when we are redirecting the library should handle any // unload and clean of the connection. APP.API.notifyReadyToClose(); + + // @ts-ignore dispatch(maybeRedirectToWelcomePage()); return; diff --git a/react/features/screen-share/actions.any.ts b/react/features/screen-share/actions.any.ts new file mode 100644 index 000000000..491dc142a --- /dev/null +++ b/react/features/screen-share/actions.any.ts @@ -0,0 +1,19 @@ +import { + SET_SCREENSHARE_CAPTURE_FRAME_RATE +} from './actionTypes'; + +/** + * Updates the capture frame rate for screenshare in redux. + * + * @param {number} captureFrameRate - The frame rate to be used for screenshare. + * @returns {{ + * type: SET_SCREENSHARE_CAPTURE_FRAME_RATE, + * captureFrameRate: number + * }} + */ +export function setScreenshareFramerate(captureFrameRate: number) { + return { + type: SET_SCREENSHARE_CAPTURE_FRAME_RATE, + captureFrameRate + }; +} diff --git a/react/features/screen-share/actions.native.ts b/react/features/screen-share/actions.native.ts new file mode 100644 index 000000000..02b37d475 --- /dev/null +++ b/react/features/screen-share/actions.native.ts @@ -0,0 +1 @@ +export * from './actions.any'; diff --git a/react/features/screen-share/actions.ts b/react/features/screen-share/actions.web.ts similarity index 85% rename from react/features/screen-share/actions.ts rename to react/features/screen-share/actions.web.ts index 1eeb442d1..0d0d1f500 100644 --- a/react/features/screen-share/actions.ts +++ b/react/features/screen-share/actions.web.ts @@ -5,14 +5,15 @@ import { shouldHideShareAudioHelper } from '../base/settings/functions'; import { toggleScreensharing } from '../base/tracks/actions'; import { - SET_SCREENSHARE_CAPTURE_FRAME_RATE, SET_SCREENSHARE_TRACKS, SET_SCREEN_AUDIO_SHARE_STATE } from './actionTypes'; -import ShareAudioDialog from './components/ShareAudioDialog'; -import ShareMediaWarningDialog from './components/ShareScreenWarningDialog'; +import ShareAudioDialog from './components/web/ShareAudioDialog'; +import ShareMediaWarningDialog from './components/web/ShareScreenWarningDialog'; import { isAudioOnlySharing, isScreenVideoShared } from './functions'; +export * from './actions.any'; + /** * Updates the current known status of the shared video. * @@ -29,22 +30,6 @@ export function setScreenAudioShareState(isSharingAudio: boolean) { }; } -/** - * Updates the capture frame rate for screenshare in redux. - * - * @param {number} captureFrameRate - The frame rate to be used for screenshare. - * @returns {{ - * type: SET_SCREENSHARE_CAPTURE_FRAME_RATE, - * captureFrameRate: number - * }} - */ -export function setScreenshareFramerate(captureFrameRate: number) { - return { - type: SET_SCREENSHARE_CAPTURE_FRAME_RATE, - captureFrameRate - }; -} - /** * Updates the audio track associated with the screenshare. * diff --git a/react/features/screen-share/components/index.js b/react/features/screen-share/components/index.js deleted file mode 100644 index bc993d82d..000000000 --- a/react/features/screen-share/components/index.js +++ /dev/null @@ -1,2 +0,0 @@ -export { default as ShareAudioButton } from './ShareAudioButton'; -export { default as ShareAudioDialog } from './ShareAudioDialog'; diff --git a/react/features/screen-share/components/ShareAudioButton.js b/react/features/screen-share/components/web/ShareAudioButton.js similarity index 82% rename from react/features/screen-share/components/ShareAudioButton.js rename to react/features/screen-share/components/web/ShareAudioButton.js index b41f75195..82b17db8e 100644 --- a/react/features/screen-share/components/ShareAudioButton.js +++ b/react/features/screen-share/components/web/ShareAudioButton.js @@ -2,19 +2,19 @@ import type { Dispatch } from 'redux'; -import { translate } from '../../base/i18n'; +import { translate } from '../../../base/i18n'; import { IconShareAudio, IconStopAudioShare -} from '../../base/icons'; -import { connect } from '../../base/redux'; +} from '../../../base/icons'; +import { connect } from '../../../base/redux'; import { AbstractButton, type AbstractButtonProps -} from '../../base/toolbox/components'; -import { setOverflowMenuVisible } from '../../toolbox/actions'; -import { startAudioScreenShareFlow } from '../actions'; -import { isAudioOnlySharing } from '../functions'; +} from '../../../base/toolbox/components'; +import { setOverflowMenuVisible } from '../../../toolbox/actions.web'; +import { startAudioScreenShareFlow } from '../../actions.web'; +import { isAudioOnlySharing } from '../../functions'; type Props = AbstractButtonProps & { diff --git a/react/features/screen-share/components/ShareAudioDialog.tsx b/react/features/screen-share/components/web/ShareAudioDialog.tsx similarity index 86% rename from react/features/screen-share/components/ShareAudioDialog.tsx rename to react/features/screen-share/components/web/ShareAudioDialog.tsx index 67a3a2b65..aba4848fc 100644 --- a/react/features/screen-share/components/ShareAudioDialog.tsx +++ b/react/features/screen-share/components/web/ShareAudioDialog.tsx @@ -1,14 +1,14 @@ import React, { Component } from 'react'; import { WithTranslation } from 'react-i18next'; -import { IReduxState, IStore } from '../../app/types'; -import { translate } from '../../base/i18n/functions'; -import { connect } from '../../base/redux/functions'; -import { updateSettings } from '../../base/settings/actions'; -import { shouldHideShareAudioHelper } from '../../base/settings/functions.any'; -import { toggleScreensharing } from '../../base/tracks/actions'; -import Checkbox from '../../base/ui/components/web/Checkbox'; -import Dialog from '../../base/ui/components/web/Dialog'; +import { IReduxState, IStore } from '../../../app/types'; +import { translate } from '../../../base/i18n/functions'; +import { connect } from '../../../base/redux/functions'; +import { updateSettings } from '../../../base/settings/actions'; +import { shouldHideShareAudioHelper } from '../../../base/settings/functions.any'; +import { toggleScreensharing } from '../../../base/tracks/actions'; +import Checkbox from '../../../base/ui/components/web/Checkbox'; +import Dialog from '../../../base/ui/components/web/Dialog'; /** * The type of the React {@code Component} props of {@link ShareAudioDialog}. diff --git a/react/features/screen-share/components/ShareScreenWarningDialog.tsx b/react/features/screen-share/components/web/ShareScreenWarningDialog.tsx similarity index 90% rename from react/features/screen-share/components/ShareScreenWarningDialog.tsx rename to react/features/screen-share/components/web/ShareScreenWarningDialog.tsx index 2d8bc2d43..5a0caa38e 100644 --- a/react/features/screen-share/components/ShareScreenWarningDialog.tsx +++ b/react/features/screen-share/components/web/ShareScreenWarningDialog.tsx @@ -1,11 +1,11 @@ import React, { Component } from 'react'; import { WithTranslation } from 'react-i18next'; -import { IStore } from '../../app/types'; -import { translate } from '../../base/i18n/functions'; -import { connect } from '../../base/redux/functions'; -import { toggleScreensharing } from '../../base/tracks/actions'; -import Dialog from '../../base/ui/components/web/Dialog'; +import { IStore } from '../../../app/types'; +import { translate } from '../../../base/i18n/functions'; +import { connect } from '../../../base/redux/functions'; +import { toggleScreensharing } from '../../../base/tracks/actions'; +import Dialog from '../../../base/ui/components/web/Dialog'; export interface IProps extends WithTranslation { diff --git a/react/features/screen-share/index.js b/react/features/screen-share/index.js index e41fc768e..18f6963c1 100644 --- a/react/features/screen-share/index.js +++ b/react/features/screen-share/index.js @@ -1,6 +1,4 @@ export * from './actions'; export * from './actionTypes'; -export * from './components'; export * from './functions'; - diff --git a/react/features/screenshot-capture/functions.js b/react/features/screenshot-capture/functions.js index e4ccfba34..896c9044c 100644 --- a/react/features/screenshot-capture/functions.js +++ b/react/features/screenshot-capture/functions.js @@ -3,7 +3,7 @@ import { JitsiRecordingConstants } from '../base/lib-jitsi-meet'; import { toState } from '../base/redux'; import { getActiveSession } from '../recording/functions'; -import { isScreenVideoShared } from '../screen-share'; +import { isScreenVideoShared } from '../screen-share/functions'; import ScreenshotCaptureSummary from './ScreenshotCaptureSummary'; diff --git a/react/features/toolbox/components/web/ShareDesktopButton.js b/react/features/toolbox/components/web/ShareDesktopButton.js index 1a4ee0845..6489c4115 100644 --- a/react/features/toolbox/components/web/ShareDesktopButton.js +++ b/react/features/toolbox/components/web/ShareDesktopButton.js @@ -5,7 +5,7 @@ import { IconShareDesktop } from '../../../base/icons'; import JitsiMeetJS from '../../../base/lib-jitsi-meet/_'; import { connect } from '../../../base/redux'; import { AbstractButton, type AbstractButtonProps } from '../../../base/toolbox/components'; -import { isScreenVideoShared } from '../../../screen-share'; +import { isScreenVideoShared } from '../../../screen-share/functions'; import { isDesktopShareButtonDisabled } from '../../functions'; type Props = AbstractButtonProps & { diff --git a/react/features/toolbox/components/web/Toolbox.tsx b/react/features/toolbox/components/web/Toolbox.tsx index f2df9c7b8..1e36a674f 100644 --- a/react/features/toolbox/components/web/Toolbox.tsx +++ b/react/features/toolbox/components/web/Toolbox.tsx @@ -68,12 +68,14 @@ import { // @ts-ignore import { isSalesforceEnabled } from '../../../salesforce/functions'; import { - ShareAudioButton, - isScreenAudioSupported, - isScreenVideoShared, startScreenShareFlow - // @ts-ignore -} from '../../../screen-share'; +} from '../../../screen-share/actions.web'; +// @ts-ignore +import ShareAudioButton from '../../../screen-share/components/web/ShareAudioButton'; +import { + isScreenAudioSupported, + isScreenVideoShared +} from '../../../screen-share/functions'; // @ts-ignore import SecurityDialogButton from '../../../security/components/security-dialog/web/SecurityDialogButton'; // @ts-ignore diff --git a/react/features/toolbox/middleware.ts b/react/features/toolbox/middleware.web.ts similarity index 100% rename from react/features/toolbox/middleware.ts rename to react/features/toolbox/middleware.web.ts diff --git a/react/features/video-layout/actions.native.ts b/react/features/video-layout/actions.native.ts index c9aaad117..e936de287 100644 --- a/react/features/video-layout/actions.native.ts +++ b/react/features/video-layout/actions.native.ts @@ -11,7 +11,7 @@ export * from './actions.any'; * enabled: boolean * }} */ -export function setIsCarmode(enabled) { +export function setIsCarmode(enabled: boolean) { return { type: SET_CAR_MODE, enabled diff --git a/react/features/video-menu/actions.any.ts b/react/features/video-menu/actions.any.ts index 98ace5876..684f21437 100644 --- a/react/features/video-menu/actions.any.ts +++ b/react/features/video-menu/actions.any.ts @@ -1,6 +1,3 @@ -// @ts-ignore -import { getLogger } from '@jitsi/logger'; - // @ts-expect-error import UIEvents from '../../../service/UI/UIEvents'; import { @@ -20,7 +17,7 @@ import { getLocalParticipant, getRemoteParticipants } from '../base/participants import { toggleScreensharing } from '../base/tracks/actions'; import { isModerationNotificationDisplayed } from '../notifications/functions'; -const logger = getLogger(__filename); +import logger from './logger'; /** * Mutes the local participant. diff --git a/react/features/video-menu/logger.ts b/react/features/video-menu/logger.ts new file mode 100644 index 000000000..38b05556d --- /dev/null +++ b/react/features/video-menu/logger.ts @@ -0,0 +1,3 @@ +import { getLogger } from '../base/logging/functions'; + +export default getLogger('features/video-menu'); diff --git a/react/index.web.js b/react/index.web.js index 6a2b73d1d..0efd86175 100644 --- a/react/index.web.js +++ b/react/index.web.js @@ -7,7 +7,7 @@ import { App } from './features/app/components'; import { getLogger } from './features/base/logging/functions'; import { Platform } from './features/base/react'; import { getJitsiMeetGlobalNS } from './features/base/util'; -import PrejoinApp from './features/prejoin/components/PrejoinApp'; +import PrejoinApp from './features/prejoin/components/web/PrejoinApp'; const logger = getLogger('index.web'); const OS = Platform.OS; diff --git a/tsconfig.native.json b/tsconfig.native.json index d28c182a8..5338986b0 100644 --- a/tsconfig.native.json +++ b/tsconfig.native.json @@ -16,6 +16,7 @@ }, "exclude": [ "node_modules", + "react/features/analytics/handlers/GoogleAnalyticsHandler.ts", "react/features/base/components/participants-pane-list", "react/features/connection-stats", "react/features/desktop-picker", @@ -23,6 +24,7 @@ "react/features/embed-meeting", "react/features/face-landmarks", "react/features/feedback", + "react/features/noise-suppression", "react/features/screen-share", "react/features/stream-effects/noise-suppression", "react/features/stream-effects/rnnoise",