ref(TS) Convert more base files to TS (#12222)
This commit is contained in:
parent
3426960d5a
commit
0bccda2c9e
|
@ -1,11 +1,7 @@
|
||||||
// @flow
|
import { IStore } from '../../app/types';
|
||||||
|
|
||||||
import type { Dispatch } from 'redux';
|
|
||||||
|
|
||||||
import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from './actionTypes';
|
import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from './actionTypes';
|
||||||
|
|
||||||
declare var APP;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Signals that a specific App will mount (in the terms of React).
|
* Signals that a specific App will mount (in the terms of React).
|
||||||
*
|
*
|
||||||
|
@ -16,7 +12,7 @@ declare var APP;
|
||||||
* }}
|
* }}
|
||||||
*/
|
*/
|
||||||
export function appWillMount(app: Object) {
|
export function appWillMount(app: Object) {
|
||||||
return (dispatch: Dispatch<any>) => {
|
return (dispatch: IStore['dispatch']) => {
|
||||||
// TODO There was a redux action creator appInit which I did not like
|
// TODO There was a redux action creator appInit which I did not like
|
||||||
// because we already had the redux action creator appWillMount and,
|
// because we already had the redux action creator appWillMount and,
|
||||||
// respectively, the redux action APP_WILL_MOUNT. So I set out to remove
|
// respectively, the redux action APP_WILL_MOUNT. So I set out to remove
|
|
@ -1,19 +1,19 @@
|
||||||
// @flow
|
import { toState } from '../redux/functions';
|
||||||
|
|
||||||
import { toState } from '../redux';
|
import { IStateful } from './types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the value of a specific React {@code Component} prop of the currently
|
* Gets the value of a specific React {@code Component} prop of the currently
|
||||||
* mounted {@link App}.
|
* mounted {@link App}.
|
||||||
*
|
*
|
||||||
* @param {Function|Object} stateful - The redux store or {@code getState}
|
* @param {IStateful} stateful - The redux store or {@code getState}
|
||||||
* function.
|
* function.
|
||||||
* @param {string} propName - The name of the React {@code Component} prop of
|
* @param {string} propName - The name of the React {@code Component} prop of
|
||||||
* the currently mounted {@code App} to get.
|
* the currently mounted {@code App} to get.
|
||||||
* @returns {*} The value of the specified React {@code Component} prop of the
|
* @returns {*} The value of the specified React {@code Component} prop of the
|
||||||
* currently mounted {@code App}.
|
* currently mounted {@code App}.
|
||||||
*/
|
*/
|
||||||
export function getAppProp(stateful: Function | Object, propName: string) {
|
export function getAppProp(stateful: IStateful, propName: string) {
|
||||||
const state = toState(stateful)['features/base/app'];
|
const state = toState(stateful)['features/base/app'];
|
||||||
|
|
||||||
if (state) {
|
if (state) {
|
|
@ -1,5 +1,3 @@
|
||||||
// @flow
|
|
||||||
|
|
||||||
import { getLogger } from '../logging/functions';
|
import { getLogger } from '../logging/functions';
|
||||||
|
|
||||||
export default getLogger('features/base/app');
|
export default getLogger('features/base/app');
|
|
@ -3,7 +3,7 @@ import ReducerRegistry from '../redux/ReducerRegistry';
|
||||||
import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from './actionTypes';
|
import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from './actionTypes';
|
||||||
|
|
||||||
export interface IAppState {
|
export interface IAppState {
|
||||||
app?: Object | undefined;
|
app?: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReducerRegistry.register<IAppState>('features/base/app', (state = {}, action): IAppState => {
|
ReducerRegistry.register<IAppState>('features/base/app', (state = {}, action): IAppState => {
|
||||||
|
|
|
@ -425,7 +425,7 @@ export interface IConfig {
|
||||||
};
|
};
|
||||||
serviceUrl?: string;
|
serviceUrl?: string;
|
||||||
speakerStatsOrder?: Array<'role' | 'name' | 'hasLeft'>;
|
speakerStatsOrder?: Array<'role' | 'name' | 'hasLeft'>;
|
||||||
startAudioMuted?: boolean;
|
startAudioMuted?: number;
|
||||||
startAudioOnly?: boolean;
|
startAudioOnly?: boolean;
|
||||||
startLastN?: number;
|
startLastN?: number;
|
||||||
startScreenSharing?: boolean;
|
startScreenSharing?: boolean;
|
||||||
|
|
|
@ -1,18 +1,21 @@
|
||||||
/* global APP */
|
import { AnyAction } from 'redux';
|
||||||
|
|
||||||
|
/* eslint-disable lines-around-comment */
|
||||||
|
// @ts-ignore
|
||||||
import UIEvents from '../../../../service/UI/UIEvents';
|
import UIEvents from '../../../../service/UI/UIEvents';
|
||||||
import { processExternalDeviceRequest } from '../../device-selection';
|
import { IStore } from '../../app/types';
|
||||||
import {
|
import { processExternalDeviceRequest } from '../../device-selection/functions';
|
||||||
NOTIFICATION_TIMEOUT_TYPE,
|
import { showNotification, showWarningNotification } from '../../notifications/actions';
|
||||||
showNotification,
|
import { NOTIFICATION_TIMEOUT_TYPE } from '../../notifications/constants';
|
||||||
showWarningNotification
|
// @ts-ignore
|
||||||
} from '../../notifications';
|
|
||||||
import { replaceAudioTrackById, replaceVideoTrackById, setDeviceStatusWarning } from '../../prejoin/actions';
|
import { replaceAudioTrackById, replaceVideoTrackById, setDeviceStatusWarning } from '../../prejoin/actions';
|
||||||
|
// @ts-ignore
|
||||||
import { isPrejoinPageVisible } from '../../prejoin/functions';
|
import { isPrejoinPageVisible } from '../../prejoin/functions';
|
||||||
import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../app';
|
import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../app/actionTypes';
|
||||||
import JitsiMeetJS, { JitsiMediaDevicesEvents, JitsiTrackErrors } from '../lib-jitsi-meet';
|
import JitsiMeetJS, { JitsiMediaDevicesEvents, JitsiTrackErrors } from '../lib-jitsi-meet';
|
||||||
import { MiddlewareRegistry } from '../redux';
|
import MiddlewareRegistry from '../redux/MiddlewareRegistry';
|
||||||
import { updateSettings } from '../settings';
|
import { updateSettings } from '../settings/actions';
|
||||||
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
CHECK_AND_NOTIFY_FOR_NEW_DEVICE,
|
CHECK_AND_NOTIFY_FOR_NEW_DEVICE,
|
||||||
|
@ -35,6 +38,7 @@ import {
|
||||||
setAudioOutputDeviceId
|
setAudioOutputDeviceId
|
||||||
} from './functions';
|
} from './functions';
|
||||||
import logger from './logger';
|
import logger from './logger';
|
||||||
|
import { IDevicesState } from './reducer';
|
||||||
|
|
||||||
const JITSI_TRACK_ERROR_TO_MESSAGE_KEY_MAP = {
|
const JITSI_TRACK_ERROR_TO_MESSAGE_KEY_MAP = {
|
||||||
microphone: {
|
microphone: {
|
||||||
|
@ -57,7 +61,7 @@ const JITSI_TRACK_ERROR_TO_MESSAGE_KEY_MAP = {
|
||||||
/**
|
/**
|
||||||
* A listener for device permissions changed reported from lib-jitsi-meet.
|
* A listener for device permissions changed reported from lib-jitsi-meet.
|
||||||
*/
|
*/
|
||||||
let permissionsListener;
|
let permissionsListener: Function | undefined;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs the current device list.
|
* Logs the current device list.
|
||||||
|
@ -65,8 +69,9 @@ let permissionsListener;
|
||||||
* @param {Object} deviceList - Whatever is returned by {@link groupDevicesByKind}.
|
* @param {Object} deviceList - Whatever is returned by {@link groupDevicesByKind}.
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
function logDeviceList(deviceList) {
|
function logDeviceList(deviceList: IDevicesState['availableDevices']) {
|
||||||
const devicesToStr = list => list.map(device => `\t\t${device.label}[${device.deviceId}]`).join('\n');
|
const devicesToStr = (list?: MediaDeviceInfo[]) =>
|
||||||
|
list?.map(device => `\t\t${device.label}[${device.deviceId}]`).join('\n');
|
||||||
const audioInputs = devicesToStr(deviceList.audioInput);
|
const audioInputs = devicesToStr(deviceList.audioInput);
|
||||||
const audioOutputs = devicesToStr(deviceList.audioOutput);
|
const audioOutputs = devicesToStr(deviceList.audioOutput);
|
||||||
const videoInputs = devicesToStr(deviceList.videoInput);
|
const videoInputs = devicesToStr(deviceList.videoInput);
|
||||||
|
@ -87,7 +92,7 @@ function logDeviceList(deviceList) {
|
||||||
MiddlewareRegistry.register(store => next => action => {
|
MiddlewareRegistry.register(store => next => action => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case APP_WILL_MOUNT: {
|
case APP_WILL_MOUNT: {
|
||||||
const _permissionsListener = permissions => {
|
const _permissionsListener = (permissions: Object) => {
|
||||||
store.dispatch(devicePermissionsChanged(permissions));
|
store.dispatch(devicePermissionsChanged(permissions));
|
||||||
};
|
};
|
||||||
const { mediaDevices } = JitsiMeetJS;
|
const { mediaDevices } = JitsiMeetJS;
|
||||||
|
@ -214,7 +219,7 @@ MiddlewareRegistry.register(store => next => action => {
|
||||||
* @private
|
* @private
|
||||||
* @returns {Object} The value returned by {@code next(action)}.
|
* @returns {Object} The value returned by {@code next(action)}.
|
||||||
*/
|
*/
|
||||||
function _processPendingRequests({ dispatch, getState }, next, action) {
|
function _processPendingRequests({ dispatch, getState }: IStore, next: Function, action: AnyAction) {
|
||||||
const result = next(action);
|
const result = next(action);
|
||||||
const state = getState();
|
const state = getState();
|
||||||
const { pendingRequests } = state['features/base/devices'];
|
const { pendingRequests } = state['features/base/devices'];
|
||||||
|
@ -223,7 +228,7 @@ function _processPendingRequests({ dispatch, getState }, next, action) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
pendingRequests.forEach(request => {
|
pendingRequests.forEach((request: any) => {
|
||||||
processExternalDeviceRequest(
|
processExternalDeviceRequest(
|
||||||
dispatch,
|
dispatch,
|
||||||
getState,
|
getState,
|
||||||
|
@ -248,7 +253,7 @@ function _processPendingRequests({ dispatch, getState }, next, action) {
|
||||||
* @private
|
* @private
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
function _checkAndNotifyForNewDevice(store, newDevices, oldDevices) {
|
function _checkAndNotifyForNewDevice(store: IStore, newDevices: MediaDeviceInfo[], oldDevices: MediaDeviceInfo[]) {
|
||||||
const { dispatch } = store;
|
const { dispatch } = store;
|
||||||
|
|
||||||
// let's intersect both newDevices and oldDevices and handle thew newly
|
// let's intersect both newDevices and oldDevices and handle thew newly
|
||||||
|
@ -260,7 +265,9 @@ function _checkAndNotifyForNewDevice(store, newDevices, oldDevices) {
|
||||||
// we group devices by groupID which normally is the grouping by physical device
|
// we group devices by groupID which normally is the grouping by physical device
|
||||||
// plugging in headset we provide normally two device, one input and one output
|
// plugging in headset we provide normally two device, one input and one output
|
||||||
// and we want to show only one notification for this physical audio device
|
// and we want to show only one notification for this physical audio device
|
||||||
const devicesGroupBy = onlyNewDevices.reduce((accumulated, value) => {
|
const devicesGroupBy: {
|
||||||
|
[key: string]: MediaDeviceInfo[];
|
||||||
|
} = onlyNewDevices.reduce((accumulated: any, value) => {
|
||||||
accumulated[value.groupId] = accumulated[value.groupId] || [];
|
accumulated[value.groupId] = accumulated[value.groupId] || [];
|
||||||
accumulated[value.groupId].push(value);
|
accumulated[value.groupId].push(value);
|
||||||
|
|
||||||
|
@ -314,7 +321,7 @@ function _checkAndNotifyForNewDevice(store, newDevices, oldDevices) {
|
||||||
* @returns {boolean} - Returns true in order notifications to be dismissed.
|
* @returns {boolean} - Returns true in order notifications to be dismissed.
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
function _useDevice({ dispatch }, devices) {
|
function _useDevice({ dispatch }: IStore, devices: MediaDeviceInfo[]) {
|
||||||
devices.forEach(device => {
|
devices.forEach(device => {
|
||||||
switch (device.kind) {
|
switch (device.kind) {
|
||||||
case 'videoinput': {
|
case 'videoinput': {
|
|
@ -1,5 +1,3 @@
|
||||||
// @flow
|
|
||||||
|
|
||||||
import { SET_JWT } from './actionTypes';
|
import { SET_JWT } from './actionTypes';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -11,7 +9,7 @@ import { SET_JWT } from './actionTypes';
|
||||||
* jwt: (string|undefined)
|
* jwt: (string|undefined)
|
||||||
* }}
|
* }}
|
||||||
*/
|
*/
|
||||||
export function setJWT(jwt: ?string) {
|
export function setJWT(jwt?: string) {
|
||||||
return {
|
return {
|
||||||
type: SET_JWT,
|
type: SET_JWT,
|
||||||
jwt
|
jwt
|
|
@ -1,5 +1,3 @@
|
||||||
// @flow
|
|
||||||
|
|
||||||
import { SET_LAST_N } from './actionTypes';
|
import { SET_LAST_N } from './actionTypes';
|
||||||
|
|
||||||
/**
|
/**
|
|
@ -7,7 +7,7 @@ import { VIDEO_QUALITY_LEVELS } from '../../video-quality/constants';
|
||||||
* @param {number} channelLastN - LastN value set for the whole conference.
|
* @param {number} channelLastN - LastN value set for the whole conference.
|
||||||
* @returns {number} LastN value applicable to the quality level specified.
|
* @returns {number} LastN value applicable to the quality level specified.
|
||||||
*/
|
*/
|
||||||
export function getLastNForQualityLevel(qualityLevel, channelLastN) {
|
export function getLastNForQualityLevel(qualityLevel: number, channelLastN: number) {
|
||||||
let lastN = channelLastN;
|
let lastN = channelLastN;
|
||||||
|
|
||||||
const videoQualityLevels = Object.values(VIDEO_QUALITY_LEVELS);
|
const videoQualityLevels = Object.values(VIDEO_QUALITY_LEVELS);
|
||||||
|
@ -15,8 +15,8 @@ export function getLastNForQualityLevel(qualityLevel, channelLastN) {
|
||||||
for (const lvl in videoQualityLevels) {
|
for (const lvl in videoQualityLevels) {
|
||||||
if (videoQualityLevels.hasOwnProperty(lvl)
|
if (videoQualityLevels.hasOwnProperty(lvl)
|
||||||
&& qualityLevel === videoQualityLevels[lvl]
|
&& qualityLevel === videoQualityLevels[lvl]
|
||||||
&& lvl > 1) {
|
&& Number(lvl) > 1) {
|
||||||
lastN = Math.floor(channelLastN / Math.pow(2, lvl - 1));
|
lastN = Math.floor(channelLastN / Math.pow(2, Number(lvl) - 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ export function getLastNForQualityLevel(qualityLevel, channelLastN) {
|
||||||
* @param {Object} lastNLimits - The Object to be verified.
|
* @param {Object} lastNLimits - The Object to be verified.
|
||||||
* @returns {undefined|Map<number, number>}
|
* @returns {undefined|Map<number, number>}
|
||||||
*/
|
*/
|
||||||
export function validateLastNLimits(lastNLimits) {
|
export function validateLastNLimits(lastNLimits: any) {
|
||||||
// Checks if only numbers are used
|
// Checks if only numbers are used
|
||||||
if (typeof lastNLimits !== 'object'
|
if (typeof lastNLimits !== 'object'
|
||||||
|| !Object.keys(lastNLimits).length
|
|| !Object.keys(lastNLimits).length
|
||||||
|
@ -64,7 +64,7 @@ export function validateLastNLimits(lastNLimits) {
|
||||||
* @returns {number|undefined} - A "last N" number if there was a corresponding "last N" value matched with the number
|
* @returns {number|undefined} - A "last N" number if there was a corresponding "last N" value matched with the number
|
||||||
* of participants or {@code undefined} otherwise.
|
* of participants or {@code undefined} otherwise.
|
||||||
*/
|
*/
|
||||||
export function limitLastN(participantsCount, lastNLimits) {
|
export function limitLastN(participantsCount: number, lastNLimits: Map<number, number>) {
|
||||||
if (!lastNLimits || !lastNLimits.keys) {
|
if (!lastNLimits || !lastNLimits.keys) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
|
@ -1,5 +1,3 @@
|
||||||
// @flow
|
|
||||||
|
|
||||||
import { getLogger } from '../logging/functions';
|
import { getLogger } from '../logging/functions';
|
||||||
|
|
||||||
export default getLogger('features/base/lastn');
|
export default getLogger('features/base/lastn');
|
|
@ -1,7 +1,6 @@
|
||||||
// @flow
|
|
||||||
|
|
||||||
import debounce from 'lodash/debounce';
|
import debounce from 'lodash/debounce';
|
||||||
|
|
||||||
|
import { IStore } from '../../app/types';
|
||||||
import { SET_FILMSTRIP_ENABLED } from '../../filmstrip/actionTypes';
|
import { SET_FILMSTRIP_ENABLED } from '../../filmstrip/actionTypes';
|
||||||
import { SELECT_LARGE_VIDEO_PARTICIPANT } from '../../large-video/actionTypes';
|
import { SELECT_LARGE_VIDEO_PARTICIPANT } from '../../large-video/actionTypes';
|
||||||
import { APP_STATE_CHANGED } from '../../mobile/background/actionTypes';
|
import { APP_STATE_CHANGED } from '../../mobile/background/actionTypes';
|
||||||
|
@ -22,7 +21,9 @@ import {
|
||||||
getParticipantById,
|
getParticipantById,
|
||||||
getParticipantCount
|
getParticipantCount
|
||||||
} from '../participants/functions';
|
} from '../participants/functions';
|
||||||
import { MiddlewareRegistry } from '../redux';
|
import MiddlewareRegistry from '../redux/MiddlewareRegistry';
|
||||||
|
// eslint-disable-next-line lines-around-comment
|
||||||
|
// @ts-ignore
|
||||||
import { isLocalVideoTrackDesktop } from '../tracks/functions';
|
import { isLocalVideoTrackDesktop } from '../tracks/functions';
|
||||||
|
|
||||||
import { setLastN } from './actions';
|
import { setLastN } from './actions';
|
||||||
|
@ -36,7 +37,7 @@ import logger from './logger';
|
||||||
* @private
|
* @private
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
const _updateLastN = debounce(({ dispatch, getState }) => {
|
const _updateLastN = debounce(({ dispatch, getState }: IStore) => {
|
||||||
const state = getState();
|
const state = getState();
|
||||||
const { conference } = state['features/base/conference'];
|
const { conference } = state['features/base/conference'];
|
||||||
|
|
||||||
|
@ -61,6 +62,7 @@ const _updateLastN = debounce(({ dispatch, getState }) => {
|
||||||
let lastNSelected = config.startLastN ?? (config.channelLastN ?? -1);
|
let lastNSelected = config.startLastN ?? (config.channelLastN ?? -1);
|
||||||
|
|
||||||
// Apply last N limit based on the # of participants and config settings.
|
// Apply last N limit based on the # of participants and config settings.
|
||||||
|
// @ts-ignore
|
||||||
const limitedLastN = limitLastN(participantCount, lastNLimits);
|
const limitedLastN = limitLastN(participantCount, lastNLimits);
|
||||||
|
|
||||||
if (limitedLastN !== undefined) {
|
if (limitedLastN !== undefined) {
|
||||||
|
@ -81,7 +83,7 @@ const _updateLastN = debounce(({ dispatch, getState }) => {
|
||||||
// view since we make an exception only for screenshare when in audio-only mode. If the user unpins
|
// view since we make an exception only for screenshare when in audio-only mode. If the user unpins
|
||||||
// the screenshare, lastN will be set to 0 here. It will be set to 1 if screenshare has been auto pinned.
|
// the screenshare, lastN will be set to 0 here. It will be set to 1 if screenshare has been auto pinned.
|
||||||
if (!tileViewEnabled && largeVideoParticipant && !largeVideoParticipant.local) {
|
if (!tileViewEnabled && largeVideoParticipant && !largeVideoParticipant.local) {
|
||||||
lastNSelected = (remoteScreenShares || []).includes(largeVideoParticipantId) ? 1 : 0;
|
lastNSelected = (remoteScreenShares || []).includes(largeVideoParticipantId ?? '') ? 1 : 0;
|
||||||
} else {
|
} else {
|
||||||
lastNSelected = 0;
|
lastNSelected = 0;
|
||||||
}
|
}
|
|
@ -1,36 +1,35 @@
|
||||||
// @flow
|
|
||||||
|
|
||||||
import i18n from 'i18next';
|
import i18n from 'i18next';
|
||||||
import { batch } from 'react-redux';
|
import { batch } from 'react-redux';
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
import UIEvents from '../../../../service/UI/UIEvents';
|
import UIEvents from '../../../../service/UI/UIEvents';
|
||||||
|
import { IStore } from '../../app/types';
|
||||||
import { approveParticipant } from '../../av-moderation/actions';
|
import { approveParticipant } from '../../av-moderation/actions';
|
||||||
import { UPDATE_BREAKOUT_ROOMS } from '../../breakout-rooms/actionTypes';
|
import { UPDATE_BREAKOUT_ROOMS } from '../../breakout-rooms/actionTypes';
|
||||||
import { getBreakoutRooms } from '../../breakout-rooms/functions';
|
import { getBreakoutRooms } from '../../breakout-rooms/functions';
|
||||||
import { toggleE2EE } from '../../e2ee/actions';
|
import { toggleE2EE } from '../../e2ee/actions';
|
||||||
import { MAX_MODE } from '../../e2ee/constants';
|
import { MAX_MODE } from '../../e2ee/constants';
|
||||||
|
import { showNotification } from '../../notifications/actions';
|
||||||
import {
|
import {
|
||||||
LOCAL_RECORDING_NOTIFICATION_ID,
|
LOCAL_RECORDING_NOTIFICATION_ID,
|
||||||
NOTIFICATION_TIMEOUT_TYPE,
|
NOTIFICATION_TIMEOUT_TYPE,
|
||||||
RAISE_HAND_NOTIFICATION_ID,
|
RAISE_HAND_NOTIFICATION_ID
|
||||||
showNotification
|
} from '../../notifications/constants';
|
||||||
} from '../../notifications';
|
|
||||||
import { isForceMuted } from '../../participants-pane/functions';
|
import { isForceMuted } from '../../participants-pane/functions';
|
||||||
import { CALLING, INVITED } from '../../presence-status';
|
import { CALLING, INVITED } from '../../presence-status/constants';
|
||||||
import { RAISE_HAND_SOUND_ID } from '../../reactions/constants';
|
import { RAISE_HAND_SOUND_ID } from '../../reactions/constants';
|
||||||
import { RECORDING_OFF_SOUND_ID, RECORDING_ON_SOUND_ID } from '../../recording';
|
import { RECORDING_OFF_SOUND_ID, RECORDING_ON_SOUND_ID } from '../../recording/constants';
|
||||||
import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../app';
|
import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../app/actionTypes';
|
||||||
import {
|
import { CONFERENCE_WILL_JOIN } from '../conference/actionTypes';
|
||||||
CONFERENCE_WILL_JOIN,
|
import { forEachConference, getCurrentConference } from '../conference/functions';
|
||||||
forEachConference,
|
import { IJitsiConference } from '../conference/reducer';
|
||||||
getCurrentConference
|
import { SET_CONFIG } from '../config/actionTypes';
|
||||||
} from '../conference';
|
|
||||||
import { SET_CONFIG } from '../config';
|
|
||||||
import { getDisableRemoveRaisedHandOnFocus } from '../config/functions.any';
|
import { getDisableRemoveRaisedHandOnFocus } from '../config/functions.any';
|
||||||
import { JitsiConferenceEvents } from '../lib-jitsi-meet';
|
import { JitsiConferenceEvents } from '../lib-jitsi-meet';
|
||||||
import { MEDIA_TYPE } from '../media';
|
import { MEDIA_TYPE } from '../media/constants';
|
||||||
import { MiddlewareRegistry, StateListenerRegistry } from '../redux';
|
import MiddlewareRegistry from '../redux/MiddlewareRegistry';
|
||||||
import { playSound, registerSound, unregisterSound } from '../sounds';
|
import StateListenerRegistry from '../redux/StateListenerRegistry';
|
||||||
|
import { playSound, registerSound, unregisterSound } from '../sounds/actions';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
DOMINANT_SPEAKER_CHANGED,
|
DOMINANT_SPEAKER_CHANGED,
|
||||||
|
@ -79,9 +78,9 @@ import {
|
||||||
} from './functions';
|
} from './functions';
|
||||||
import logger from './logger';
|
import logger from './logger';
|
||||||
import { PARTICIPANT_JOINED_FILE, PARTICIPANT_LEFT_FILE } from './sounds';
|
import { PARTICIPANT_JOINED_FILE, PARTICIPANT_LEFT_FILE } from './sounds';
|
||||||
import './subscriber';
|
import { IJitsiParticipant } from './types';
|
||||||
|
|
||||||
declare var APP: Object;
|
import './subscriber';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Middleware that captures CONFERENCE_JOINED and CONFERENCE_LEFT actions and
|
* Middleware that captures CONFERENCE_JOINED and CONFERENCE_LEFT actions and
|
||||||
|
@ -128,8 +127,7 @@ MiddlewareRegistry.register(store => next => action => {
|
||||||
const participant = getDominantSpeakerParticipant(state);
|
const participant = getDominantSpeakerParticipant(state);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
participant
|
participant?.local
|
||||||
&& participant.local
|
|
||||||
&& hasRaisedHand(participant)
|
&& hasRaisedHand(participant)
|
||||||
&& action.level > LOWER_HAND_AUDIO_LEVEL
|
&& action.level > LOWER_HAND_AUDIO_LEVEL
|
||||||
&& !getDisableRemoveRaisedHandOnFocus(state)
|
&& !getDisableRemoveRaisedHandOnFocus(state)
|
||||||
|
@ -142,14 +140,14 @@ MiddlewareRegistry.register(store => next => action => {
|
||||||
case GRANT_MODERATOR: {
|
case GRANT_MODERATOR: {
|
||||||
const { conference } = store.getState()['features/base/conference'];
|
const { conference } = store.getState()['features/base/conference'];
|
||||||
|
|
||||||
conference.grantOwner(action.id);
|
conference?.grantOwner(action.id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case KICK_PARTICIPANT: {
|
case KICK_PARTICIPANT: {
|
||||||
const { conference } = store.getState()['features/base/conference'];
|
const { conference } = store.getState()['features/base/conference'];
|
||||||
|
|
||||||
conference.kickParticipant(action.id);
|
conference?.kickParticipant(action.id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,13 +162,13 @@ MiddlewareRegistry.register(store => next => action => {
|
||||||
// participant is uniquely identified by the very fact that there is
|
// participant is uniquely identified by the very fact that there is
|
||||||
// only one local participant.
|
// only one local participant.
|
||||||
|
|
||||||
id: localId,
|
id: localId ?? '',
|
||||||
local: true,
|
local: true,
|
||||||
raisedHandTimestamp
|
raisedHandTimestamp
|
||||||
}));
|
}));
|
||||||
|
|
||||||
store.dispatch(raiseHandUpdateQueue({
|
store.dispatch(raiseHandUpdateQueue({
|
||||||
id: localId,
|
id: localId ?? '',
|
||||||
raisedHandTimestamp
|
raisedHandTimestamp
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -188,14 +186,16 @@ MiddlewareRegistry.register(store => next => action => {
|
||||||
const { deploymentInfo } = state['features/base/config'];
|
const { deploymentInfo } = state['features/base/config'];
|
||||||
|
|
||||||
// if there userRegion set let's use it for the local participant
|
// if there userRegion set let's use it for the local participant
|
||||||
if (deploymentInfo && deploymentInfo.userRegion) {
|
if (deploymentInfo?.userRegion) {
|
||||||
const localId = getLocalParticipant(state)?.id;
|
const localId = getLocalParticipant(state)?.id;
|
||||||
|
|
||||||
store.dispatch(participantUpdated({
|
if (localId) {
|
||||||
id: localId,
|
store.dispatch(participantUpdated({
|
||||||
local: true,
|
id: localId,
|
||||||
region: deploymentInfo.userRegion
|
local: true,
|
||||||
}));
|
region: deploymentInfo.userRegion
|
||||||
|
}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -207,7 +207,7 @@ MiddlewareRegistry.register(store => next => action => {
|
||||||
const localId = getLocalParticipant(state)?.id;
|
const localId = getLocalParticipant(state)?.id;
|
||||||
const { localRecording } = state['features/base/config'];
|
const { localRecording } = state['features/base/config'];
|
||||||
|
|
||||||
if (localRecording?.notifyAllParticipants && !onlySelf) {
|
if (localRecording?.notifyAllParticipants && !onlySelf && localId) {
|
||||||
store.dispatch(participantUpdated({
|
store.dispatch(participantUpdated({
|
||||||
// XXX Only the local participant is allowed to update without
|
// XXX Only the local participant is allowed to update without
|
||||||
// stating the JitsiConference instance (i.e. participant property
|
// stating the JitsiConference instance (i.e. participant property
|
||||||
|
@ -227,7 +227,7 @@ MiddlewareRegistry.register(store => next => action => {
|
||||||
case MUTE_REMOTE_PARTICIPANT: {
|
case MUTE_REMOTE_PARTICIPANT: {
|
||||||
const { conference } = store.getState()['features/base/conference'];
|
const { conference } = store.getState()['features/base/conference'];
|
||||||
|
|
||||||
conference.muteParticipant(action.id, action.mediaType);
|
conference?.muteParticipant(action.id, action.mediaType);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -319,7 +319,7 @@ MiddlewareRegistry.register(store => next => action => {
|
||||||
if (breakoutRoom) {
|
if (breakoutRoom) {
|
||||||
const rooms = getBreakoutRooms(state);
|
const rooms = getBreakoutRooms(state);
|
||||||
const roomCounter = state['features/breakout-rooms'].roomCounter;
|
const roomCounter = state['features/breakout-rooms'].roomCounter;
|
||||||
const newRooms = {};
|
const newRooms: any = {};
|
||||||
|
|
||||||
Object.entries(rooms).forEach(([ key, r ]) => {
|
Object.entries(rooms).forEach(([ key, r ]) => {
|
||||||
const participants = r?.participants || {};
|
const participants = r?.participants || {};
|
||||||
|
@ -393,7 +393,7 @@ StateListenerRegistry.register(
|
||||||
/* listener */ ({ leaving }, { dispatch, getState }) => {
|
/* listener */ ({ leaving }, { dispatch, getState }) => {
|
||||||
const state = getState();
|
const state = getState();
|
||||||
const localParticipant = getLocalParticipant(state);
|
const localParticipant = getLocalParticipant(state);
|
||||||
let id;
|
let id: string;
|
||||||
|
|
||||||
if (!localParticipant
|
if (!localParticipant
|
||||||
|| (id = localParticipant.id)
|
|| (id = localParticipant.id)
|
||||||
|
@ -421,37 +421,41 @@ StateListenerRegistry.register(
|
||||||
state => state['features/base/conference'].conference,
|
state => state['features/base/conference'].conference,
|
||||||
(conference, store) => {
|
(conference, store) => {
|
||||||
if (conference) {
|
if (conference) {
|
||||||
const propertyHandlers = {
|
const propertyHandlers: {
|
||||||
'e2ee.enabled': (participant, value) => _e2eeUpdated(store, conference, participant.getId(), value),
|
[key: string]: Function;
|
||||||
'features_e2ee': (participant, value) =>
|
} = {
|
||||||
|
'e2ee.enabled': (participant: IJitsiParticipant, value: string) =>
|
||||||
|
_e2eeUpdated(store, conference, participant.getId(), value),
|
||||||
|
'features_e2ee': (participant: IJitsiParticipant, value: boolean) =>
|
||||||
store.dispatch(participantUpdated({
|
store.dispatch(participantUpdated({
|
||||||
conference,
|
conference,
|
||||||
id: participant.getId(),
|
id: participant.getId(),
|
||||||
e2eeSupported: value
|
e2eeSupported: value
|
||||||
})),
|
})),
|
||||||
'features_jigasi': (participant, value) =>
|
'features_jigasi': (participant: IJitsiParticipant, value: boolean) =>
|
||||||
store.dispatch(participantUpdated({
|
store.dispatch(participantUpdated({
|
||||||
conference,
|
conference,
|
||||||
id: participant.getId(),
|
id: participant.getId(),
|
||||||
isJigasi: value
|
isJigasi: value
|
||||||
})),
|
})),
|
||||||
'features_screen-sharing': (participant, value) => // eslint-disable-line no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
'features_screen-sharing': (participant: IJitsiParticipant, value: string) =>
|
||||||
store.dispatch(participantUpdated({
|
store.dispatch(participantUpdated({
|
||||||
conference,
|
conference,
|
||||||
id: participant.getId(),
|
id: participant.getId(),
|
||||||
features: { 'screen-sharing': true }
|
features: { 'screen-sharing': true }
|
||||||
})),
|
})),
|
||||||
'localRecording': (participant, value) =>
|
'localRecording': (participant: IJitsiParticipant, value: string) =>
|
||||||
_localRecordingUpdated(store, conference, participant.getId(), value),
|
_localRecordingUpdated(store, conference, participant.getId(), value),
|
||||||
'raisedHand': (participant, value) =>
|
'raisedHand': (participant: IJitsiParticipant, value: string) =>
|
||||||
_raiseHandUpdated(store, conference, participant.getId(), value),
|
_raiseHandUpdated(store, conference, participant.getId(), value),
|
||||||
'region': (participant, value) =>
|
'region': (participant: IJitsiParticipant, value: string) =>
|
||||||
store.dispatch(participantUpdated({
|
store.dispatch(participantUpdated({
|
||||||
conference,
|
conference,
|
||||||
id: participant.getId(),
|
id: participant.getId(),
|
||||||
region: value
|
region: value
|
||||||
})),
|
})),
|
||||||
'remoteControlSessionStatus': (participant, value) =>
|
'remoteControlSessionStatus': (participant: IJitsiParticipant, value: boolean) =>
|
||||||
store.dispatch(participantUpdated({
|
store.dispatch(participantUpdated({
|
||||||
conference,
|
conference,
|
||||||
id: participant.getId(),
|
id: participant.getId(),
|
||||||
|
@ -460,12 +464,12 @@ StateListenerRegistry.register(
|
||||||
};
|
};
|
||||||
|
|
||||||
// update properties for the participants that are already in the conference
|
// update properties for the participants that are already in the conference
|
||||||
conference.getParticipants().forEach(participant => {
|
conference.getParticipants().forEach((participant: any) => {
|
||||||
Object.keys(propertyHandlers).forEach(propertyName => {
|
Object.keys(propertyHandlers).forEach(propertyName => {
|
||||||
const value = participant.getProperty(propertyName);
|
const value = participant.getProperty(propertyName);
|
||||||
|
|
||||||
if (value !== undefined) {
|
if (value !== undefined) {
|
||||||
propertyHandlers[propertyName](participant, value);
|
propertyHandlers[propertyName as keyof typeof propertyHandlers](participant, value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -473,17 +477,17 @@ StateListenerRegistry.register(
|
||||||
// We joined a conference
|
// We joined a conference
|
||||||
conference.on(
|
conference.on(
|
||||||
JitsiConferenceEvents.PARTICIPANT_PROPERTY_CHANGED,
|
JitsiConferenceEvents.PARTICIPANT_PROPERTY_CHANGED,
|
||||||
(participant, propertyName, oldValue, newValue) => {
|
(participant: IJitsiParticipant, propertyName: string, oldValue: string, newValue: string) => {
|
||||||
if (propertyHandlers.hasOwnProperty(propertyName)) {
|
if (propertyHandlers.hasOwnProperty(propertyName)) {
|
||||||
propertyHandlers[propertyName](participant, newValue);
|
propertyHandlers[propertyName](participant, newValue);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const localParticipantId = getLocalParticipant(store.getState).id;
|
const localParticipantId = getLocalParticipant(store.getState)?.id;
|
||||||
|
|
||||||
// We left the conference, the local participant must be updated.
|
// We left the conference, the local participant must be updated.
|
||||||
_e2eeUpdated(store, conference, localParticipantId, false);
|
_e2eeUpdated(store, conference, localParticipantId ?? '', false);
|
||||||
_raiseHandUpdated(store, conference, localParticipantId, 0);
|
_raiseHandUpdated(store, conference, localParticipantId ?? '', 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -497,7 +501,8 @@ StateListenerRegistry.register(
|
||||||
* @param {boolean} newValue - The new value of the E2EE enabled status.
|
* @param {boolean} newValue - The new value of the E2EE enabled status.
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
function _e2eeUpdated({ getState, dispatch }, conference, participantId, newValue) {
|
function _e2eeUpdated({ getState, dispatch }: IStore, conference: IJitsiConference,
|
||||||
|
participantId: string, newValue: string | boolean) {
|
||||||
const e2eeEnabled = newValue === 'true';
|
const e2eeEnabled = newValue === 'true';
|
||||||
const { e2ee = {} } = getState()['features/base/config'];
|
const { e2ee = {} } = getState()['features/base/config'];
|
||||||
|
|
||||||
|
@ -530,11 +535,12 @@ function _e2eeUpdated({ getState, dispatch }, conference, participantId, newValu
|
||||||
* @private
|
* @private
|
||||||
* @returns {Object} The value returned by {@code next(action)}.
|
* @returns {Object} The value returned by {@code next(action)}.
|
||||||
*/
|
*/
|
||||||
function _localParticipantJoined({ getState, dispatch }, next, action) {
|
function _localParticipantJoined({ getState, dispatch }: IStore, next: Function, action: any) {
|
||||||
const result = next(action);
|
const result = next(action);
|
||||||
|
|
||||||
const settings = getState()['features/base/settings'];
|
const settings = getState()['features/base/settings'];
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
dispatch(localParticipantJoined({
|
dispatch(localParticipantJoined({
|
||||||
avatarURL: settings.avatarURL,
|
avatarURL: settings.avatarURL,
|
||||||
email: settings.email,
|
email: settings.email,
|
||||||
|
@ -555,7 +561,7 @@ function _localParticipantJoined({ getState, dispatch }, next, action) {
|
||||||
* @private
|
* @private
|
||||||
* @returns {Object} The value returned by {@code next(action)}.
|
* @returns {Object} The value returned by {@code next(action)}.
|
||||||
*/
|
*/
|
||||||
function _localParticipantLeft({ dispatch }, next, action) {
|
function _localParticipantLeft({ dispatch }: IStore, next: Function, action: any) {
|
||||||
const result = next(action);
|
const result = next(action);
|
||||||
|
|
||||||
dispatch(localParticipantLeft());
|
dispatch(localParticipantLeft());
|
||||||
|
@ -572,7 +578,7 @@ function _localParticipantLeft({ dispatch }, next, action) {
|
||||||
* @private
|
* @private
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
function _maybePlaySounds({ getState, dispatch }, action) {
|
function _maybePlaySounds({ getState, dispatch }: IStore, action: any) {
|
||||||
const state = getState();
|
const state = getState();
|
||||||
const { startAudioMuted } = state['features/base/config'];
|
const { startAudioMuted } = state['features/base/config'];
|
||||||
const { soundsParticipantJoined: joinSound, soundsParticipantLeft: leftSound } = state['features/base/settings'];
|
const { soundsParticipantJoined: joinSound, soundsParticipantLeft: leftSound } = state['features/base/settings'];
|
||||||
|
@ -617,7 +623,7 @@ function _maybePlaySounds({ getState, dispatch }, action) {
|
||||||
* @private
|
* @private
|
||||||
* @returns {Object} The value returned by {@code next(action)}.
|
* @returns {Object} The value returned by {@code next(action)}.
|
||||||
*/
|
*/
|
||||||
function _participantJoinedOrUpdated(store, next, action) {
|
function _participantJoinedOrUpdated(store: IStore, next: Function, action: any) {
|
||||||
const { dispatch, getState } = store;
|
const { dispatch, getState } = store;
|
||||||
const { overwrittenNameList } = store.getState()['features/base/participants'];
|
const { overwrittenNameList } = store.getState()['features/base/participants'];
|
||||||
const { participant: {
|
const { participant: {
|
||||||
|
@ -639,7 +645,7 @@ function _participantJoinedOrUpdated(store, next, action) {
|
||||||
const rHand = parseInt(raisedHandTimestamp, 10);
|
const rHand = parseInt(raisedHandTimestamp, 10);
|
||||||
|
|
||||||
// Send raisedHand signalling only if there is a change
|
// Send raisedHand signalling only if there is a change
|
||||||
if (conference && rHand !== getLocalParticipant(getState()).raisedHandTimestamp) {
|
if (conference && rHand !== getLocalParticipant(getState())?.raisedHandTimestamp) {
|
||||||
conference.setLocalParticipantProperty('raisedHand', rHand);
|
conference.setLocalParticipantProperty('raisedHand', rHand);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -657,7 +663,7 @@ function _participantJoinedOrUpdated(store, next, action) {
|
||||||
|
|
||||||
// Send localRecording signalling only if there is a change
|
// Send localRecording signalling only if there is a change
|
||||||
if (conference
|
if (conference
|
||||||
&& localRecording !== getLocalParticipant(getState()).localRecording) {
|
&& localRecording !== getLocalParticipant(getState())?.localRecording) {
|
||||||
conference.setLocalParticipantProperty('localRecording', localRecording);
|
conference.setLocalParticipantProperty('localRecording', localRecording);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -673,12 +679,12 @@ function _participantJoinedOrUpdated(store, next, action) {
|
||||||
const { disableThirdPartyRequests } = getState()['features/base/config'];
|
const { disableThirdPartyRequests } = getState()['features/base/config'];
|
||||||
|
|
||||||
if (!disableThirdPartyRequests && (avatarURL || email || id || name)) {
|
if (!disableThirdPartyRequests && (avatarURL || email || id || name)) {
|
||||||
const participantId = !id && local ? getLocalParticipant(getState()).id : id;
|
const participantId = !id && local ? getLocalParticipant(getState())?.id : id;
|
||||||
const updatedParticipant = getParticipantById(getState(), participantId);
|
const updatedParticipant = getParticipantById(getState(), participantId);
|
||||||
|
|
||||||
getFirstLoadableAvatarUrl(updatedParticipant, store)
|
getFirstLoadableAvatarUrl(updatedParticipant ?? { id: '' }, store)
|
||||||
.then(urlData => {
|
.then((urlData?: { isUsingCORS: boolean; src: string; }) => {
|
||||||
dispatch(setLoadableAvatarUrl(participantId, urlData?.src, urlData?.isUsingCORS));
|
dispatch(setLoadableAvatarUrl(participantId, urlData?.src ?? '', Boolean(urlData?.isUsingCORS)));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -703,7 +709,8 @@ function _participantJoinedOrUpdated(store, next, action) {
|
||||||
* @param {boolean} newValue - The new value of the local recording status.
|
* @param {boolean} newValue - The new value of the local recording status.
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
function _localRecordingUpdated({ dispatch, getState }, conference, participantId, newValue) {
|
function _localRecordingUpdated({ dispatch, getState }: IStore, conference: IJitsiConference,
|
||||||
|
participantId: string, newValue: string) {
|
||||||
const state = getState();
|
const state = getState();
|
||||||
|
|
||||||
dispatch(participantUpdated({
|
dispatch(participantUpdated({
|
||||||
|
@ -732,7 +739,8 @@ function _localRecordingUpdated({ dispatch, getState }, conference, participantI
|
||||||
* @param {boolean} newValue - The new value of the raise hand status.
|
* @param {boolean} newValue - The new value of the raise hand status.
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
function _raiseHandUpdated({ dispatch, getState }, conference, participantId, newValue) {
|
function _raiseHandUpdated({ dispatch, getState }: IStore, conference: IJitsiConference,
|
||||||
|
participantId: string, newValue: string | number) {
|
||||||
let raisedHandTimestamp;
|
let raisedHandTimestamp;
|
||||||
|
|
||||||
switch (newValue) {
|
switch (newValue) {
|
||||||
|
@ -744,7 +752,7 @@ function _raiseHandUpdated({ dispatch, getState }, conference, participantId, ne
|
||||||
raisedHandTimestamp = Date.now();
|
raisedHandTimestamp = Date.now();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
raisedHandTimestamp = parseInt(newValue, 10);
|
raisedHandTimestamp = parseInt(`${newValue}`, 10);
|
||||||
}
|
}
|
||||||
const state = getState();
|
const state = getState();
|
||||||
|
|
||||||
|
@ -811,7 +819,7 @@ function _raiseHandUpdated({ dispatch, getState }, conference, participantId, ne
|
||||||
* @private
|
* @private
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
function _registerSounds({ dispatch }) {
|
function _registerSounds({ dispatch }: IStore) {
|
||||||
dispatch(
|
dispatch(
|
||||||
registerSound(PARTICIPANT_JOINED_SOUND_ID, PARTICIPANT_JOINED_FILE));
|
registerSound(PARTICIPANT_JOINED_SOUND_ID, PARTICIPANT_JOINED_FILE));
|
||||||
dispatch(registerSound(PARTICIPANT_LEFT_SOUND_ID, PARTICIPANT_LEFT_FILE));
|
dispatch(registerSound(PARTICIPANT_LEFT_SOUND_ID, PARTICIPANT_LEFT_FILE));
|
||||||
|
@ -824,7 +832,7 @@ function _registerSounds({ dispatch }) {
|
||||||
* @private
|
* @private
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
function _unregisterSounds({ dispatch }) {
|
function _unregisterSounds({ dispatch }: IStore) {
|
||||||
dispatch(unregisterSound(PARTICIPANT_JOINED_SOUND_ID));
|
dispatch(unregisterSound(PARTICIPANT_JOINED_SOUND_ID));
|
||||||
dispatch(unregisterSound(PARTICIPANT_LEFT_SOUND_ID));
|
dispatch(unregisterSound(PARTICIPANT_LEFT_SOUND_ID));
|
||||||
}
|
}
|
|
@ -5,6 +5,7 @@ export interface Participant {
|
||||||
connectionStatus?: string;
|
connectionStatus?: string;
|
||||||
displayName?: string;
|
displayName?: string;
|
||||||
dominantSpeaker?: boolean;
|
dominantSpeaker?: boolean;
|
||||||
|
e2eeEnabled?: boolean;
|
||||||
e2eeSupported?: boolean;
|
e2eeSupported?: boolean;
|
||||||
email?: string;
|
email?: string;
|
||||||
features?: {
|
features?: {
|
||||||
|
@ -42,3 +43,7 @@ export interface LocalParticipant extends Participant {
|
||||||
userSelectedMicDeviceId?: string;
|
userSelectedMicDeviceId?: string;
|
||||||
userSelectedMicDeviceLabel?: string;
|
userSelectedMicDeviceLabel?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IJitsiParticipant {
|
||||||
|
getId: () => string;
|
||||||
|
}
|
||||||
|
|
|
@ -68,7 +68,7 @@ export function _removeAudioElement(soundId: string) {
|
||||||
* which was used in {@link registerSound} to register the sound).
|
* which was used in {@link registerSound} to register the sound).
|
||||||
* @returns {Function}
|
* @returns {Function}
|
||||||
*/
|
*/
|
||||||
export function playSound(soundId: string): Object {
|
export function playSound(soundId: string) {
|
||||||
return (dispatch: Function, getState: Function) => {
|
return (dispatch: Function, getState: Function) => {
|
||||||
const disabledSounds = getDisabledSounds(getState());
|
const disabledSounds = getDisabledSounds(getState());
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ export function playSound(soundId: string): Object {
|
||||||
* }}
|
* }}
|
||||||
*/
|
*/
|
||||||
export function registerSound(
|
export function registerSound(
|
||||||
soundId: string, soundName: string, options: Object = {}): Object {
|
soundId: string, soundName: string, options: Object = {}) {
|
||||||
return {
|
return {
|
||||||
type: REGISTER_SOUND,
|
type: REGISTER_SOUND,
|
||||||
soundId,
|
soundId,
|
||||||
|
@ -122,7 +122,7 @@ export function registerSound(
|
||||||
* soundId: string
|
* soundId: string
|
||||||
* }}
|
* }}
|
||||||
*/
|
*/
|
||||||
export function stopSound(soundId: string): Object {
|
export function stopSound(soundId: string) {
|
||||||
return {
|
return {
|
||||||
type: STOP_SOUND,
|
type: STOP_SOUND,
|
||||||
soundId
|
soundId
|
||||||
|
@ -141,7 +141,7 @@ export function stopSound(soundId: string): Object {
|
||||||
* soundId: string
|
* soundId: string
|
||||||
* }}
|
* }}
|
||||||
*/
|
*/
|
||||||
export function unregisterSound(soundId: string): Object {
|
export function unregisterSound(soundId: string) {
|
||||||
return {
|
return {
|
||||||
type: UNREGISTER_SOUND,
|
type: UNREGISTER_SOUND,
|
||||||
soundId
|
soundId
|
||||||
|
|
|
@ -1,37 +1,37 @@
|
||||||
// @flow
|
import { IStore } from '../app/types';
|
||||||
|
import { IStateful } from '../base/app/types';
|
||||||
import type { Dispatch } from 'redux';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
addPendingDeviceRequest,
|
addPendingDeviceRequest,
|
||||||
areDeviceLabelsInitialized,
|
|
||||||
getAudioOutputDeviceId,
|
|
||||||
getAvailableDevices,
|
getAvailableDevices,
|
||||||
getDeviceIdByLabel,
|
|
||||||
groupDevicesByKind,
|
|
||||||
setAudioInputDeviceAndUpdateSettings,
|
setAudioInputDeviceAndUpdateSettings,
|
||||||
setAudioOutputDevice,
|
setAudioOutputDevice,
|
||||||
setVideoInputDeviceAndUpdateSettings
|
setVideoInputDeviceAndUpdateSettings
|
||||||
} from '../base/devices';
|
} from '../base/devices/actions';
|
||||||
|
import {
|
||||||
|
areDeviceLabelsInitialized,
|
||||||
|
getAudioOutputDeviceId,
|
||||||
|
getDeviceIdByLabel,
|
||||||
|
groupDevicesByKind
|
||||||
|
} from '../base/devices/functions';
|
||||||
import { isIosMobileBrowser } from '../base/environment/utils';
|
import { isIosMobileBrowser } from '../base/environment/utils';
|
||||||
import JitsiMeetJS from '../base/lib-jitsi-meet';
|
import JitsiMeetJS from '../base/lib-jitsi-meet';
|
||||||
import { toState } from '../base/redux';
|
import { toState } from '../base/redux/functions';
|
||||||
import {
|
import {
|
||||||
getUserSelectedCameraDeviceId,
|
getUserSelectedCameraDeviceId,
|
||||||
getUserSelectedMicDeviceId,
|
getUserSelectedMicDeviceId,
|
||||||
getUserSelectedOutputDeviceId
|
getUserSelectedOutputDeviceId
|
||||||
} from '../base/settings';
|
} from '../base/settings/functions.any';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the properties for the device selection dialog from Redux state.
|
* Returns the properties for the device selection dialog from Redux state.
|
||||||
*
|
*
|
||||||
* @param {(Function|Object)} stateful -The (whole) redux state, or redux's
|
* @param {IStateful} stateful -The (whole) redux state, or redux's
|
||||||
* {@code getState} function to be used to retrieve the state.
|
* {@code getState} function to be used to retrieve the state.
|
||||||
* @param {boolean} isDisplayedOnWelcomePage - Indicates whether the device selection dialog is displayed on the
|
* @param {boolean} isDisplayedOnWelcomePage - Indicates whether the device selection dialog is displayed on the
|
||||||
* welcome page or not.
|
* welcome page or not.
|
||||||
* @returns {Object} - The properties for the device selection dialog.
|
* @returns {Object} - The properties for the device selection dialog.
|
||||||
*/
|
*/
|
||||||
export function getDeviceSelectionDialogProps(stateful: Object | Function, isDisplayedOnWelcomePage) {
|
export function getDeviceSelectionDialogProps(stateful: IStateful, isDisplayedOnWelcomePage: boolean) {
|
||||||
// On mobile Safari because of https://bugs.webkit.org/show_bug.cgi?id=179363#c30, the old track is stopped
|
// On mobile Safari because of https://bugs.webkit.org/show_bug.cgi?id=179363#c30, the old track is stopped
|
||||||
// by the browser when a new track is created for preview. That's why we are disabling all previews.
|
// by the browser when a new track is created for preview. That's why we are disabling all previews.
|
||||||
const disablePreviews = isIosMobileBrowser();
|
const disablePreviews = isIosMobileBrowser();
|
||||||
|
@ -96,9 +96,9 @@ export function getDeviceSelectionDialogProps(stateful: Object | Function, isDis
|
||||||
* @returns {boolean} - True if the request has been processed and false otherwise.
|
* @returns {boolean} - True if the request has been processed and false otherwise.
|
||||||
*/
|
*/
|
||||||
export function processExternalDeviceRequest( // eslint-disable-line max-params
|
export function processExternalDeviceRequest( // eslint-disable-line max-params
|
||||||
dispatch: Dispatch<any>,
|
dispatch: IStore['dispatch'],
|
||||||
getState: Function,
|
getState: IStore['getState'],
|
||||||
request: Object,
|
request: any,
|
||||||
responseCallback: Function) {
|
responseCallback: Function) {
|
||||||
if (request.type !== 'devices') {
|
if (request.type !== 'devices') {
|
||||||
return false;
|
return false;
|
||||||
|
@ -119,10 +119,10 @@ export function processExternalDeviceRequest( // eslint-disable-line max-params
|
||||||
case 'isMultipleAudioInputSupported':
|
case 'isMultipleAudioInputSupported':
|
||||||
responseCallback(JitsiMeetJS.isMultipleAudioInputSupported());
|
responseCallback(JitsiMeetJS.isMultipleAudioInputSupported());
|
||||||
break;
|
break;
|
||||||
case 'getCurrentDevices':
|
case 'getCurrentDevices': // @ts-ignore
|
||||||
dispatch(getAvailableDevices()).then(devices => {
|
dispatch(getAvailableDevices()).then((devices: MediaDeviceInfo[]) => {
|
||||||
if (areDeviceLabelsInitialized(state)) {
|
if (areDeviceLabelsInitialized(state)) {
|
||||||
const deviceDescriptions = {
|
const deviceDescriptions: any = {
|
||||||
audioInput: undefined,
|
audioInput: undefined,
|
||||||
audioOutput: undefined,
|
audioOutput: undefined,
|
||||||
videoInput: undefined
|
videoInput: undefined
|
||||||
|
@ -164,8 +164,8 @@ export function processExternalDeviceRequest( // eslint-disable-line max-params
|
||||||
});
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 'getAvailableDevices':
|
case 'getAvailableDevices': // @ts-ignore
|
||||||
dispatch(getAvailableDevices()).then(devices => {
|
dispatch(getAvailableDevices()).then((devices: MediaDeviceInfo[]) => {
|
||||||
if (areDeviceLabelsInitialized(state)) {
|
if (areDeviceLabelsInitialized(state)) {
|
||||||
responseCallback(groupDevicesByKind(devices));
|
responseCallback(groupDevicesByKind(devices));
|
||||||
} else {
|
} else {
|
|
@ -92,9 +92,12 @@ export function setNotificationsEnabled(enabled: boolean) {
|
||||||
interface INotificationProps {
|
interface INotificationProps {
|
||||||
appearance?: string;
|
appearance?: string;
|
||||||
concatText?: boolean;
|
concatText?: boolean;
|
||||||
|
customActionHandler?: Function[];
|
||||||
|
customActionNameKey?: string[];
|
||||||
description?: string;
|
description?: string;
|
||||||
descriptionKey?: string;
|
descriptionKey?: string;
|
||||||
icon?: string;
|
icon?: string;
|
||||||
|
title?: string;
|
||||||
titleArguments?: {
|
titleArguments?: {
|
||||||
[key: string]: string;
|
[key: string]: string;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue