ref(TS) Convert some features to TS (#12591)

This commit is contained in:
Robert Pintilii 2022-11-23 11:12:26 +02:00 committed by GitHub
parent 6bce0bc917
commit 643cc2db81
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 166 additions and 191 deletions

1
globals.d.ts vendored
View File

@ -13,6 +13,7 @@ declare global {
keyboardshortcut: {
registerShortcut: Function;
unregisterShortcut: Function;
openDialog: Function;
}
};
const interfaceConfig: any;

View File

@ -454,18 +454,18 @@ export function sendLocalParticipant(
name
} = getLocalParticipant(stateful) ?? {};
avatarURL && conference.sendCommand(AVATAR_URL_COMMAND, {
avatarURL && conference?.sendCommand(AVATAR_URL_COMMAND, {
value: avatarURL
});
email && conference.sendCommand(EMAIL_COMMAND, {
email && conference?.sendCommand(EMAIL_COMMAND, {
value: email
});
if (features && features['screen-sharing'] === 'true') {
conference.setLocalParticipantProperty('features_screen-sharing', true);
conference?.setLocalParticipantProperty('features_screen-sharing', true);
}
conference.setDisplayName(name);
conference?.setDisplayName(name);
}
/**

View File

@ -65,6 +65,7 @@ export interface IJitsiConference {
isStartAudioMuted: Function;
isStartVideoMuted: Function;
join: Function;
joinLobby: Function;
kickParticipant: Function;
lock: Function;
muteParticipant: Function;
@ -104,7 +105,7 @@ export interface IConferenceState {
leaving?: Object;
localSubject?: string;
locked?: string;
membersOnly?: Object;
membersOnly?: IJitsiConference;
obfuscatedRoom?: string;
obfuscatedRoomSource?: string;
p2p?: Object;
@ -227,7 +228,8 @@ function _authStatusChanged(state: IConferenceState,
* @returns {Object} The new state of the feature base/conference after the
* reduction of the specified action.
*/
function _conferenceFailed(state: IConferenceState, { conference, error }: { conference: Object; error: Error; }) {
function _conferenceFailed(state: IConferenceState, { conference, error }: {
conference: IJitsiConference; error: Error; }) {
// The current (similar to getCurrentConference in
// base/conference/functions.any.js) conference which is joining or joined:
const conference_ = state.conference || state.joining;

View File

@ -214,7 +214,7 @@ export function getVideoTrackByParticipant(
export function getTrackByMediaTypeAndParticipant(
tracks: ITrack[],
mediaType: MediaType,
participantId: string) {
participantId?: string) {
return tracks.find(
t => Boolean(t.jitsiTrack) && t.participantId === participantId && t.mediaType === mediaType
);

View File

@ -11,7 +11,6 @@ import {
getParticipantDisplayName,
isWhiteboardParticipant
} from '../../../base/participants/functions';
import { IParticipant } from '../../../base/participants/types';
import { withPixelLineHeight } from '../../../base/styles/functions.web';
// @ts-ignore
import { getLargeVideoParticipant } from '../../../large-video/functions';
@ -50,9 +49,9 @@ const useStyles = makeStyles()(theme => {
*/
const StageParticipantNameLabel = () => {
const { classes, cx } = useStyles();
const largeVideoParticipant: IParticipant = useSelector(getLargeVideoParticipant);
const largeVideoParticipant = useSelector(getLargeVideoParticipant);
const selectedId = largeVideoParticipant?.id;
const nameToDisplay = useSelector((state: IReduxState) => getParticipantDisplayName(state, selectedId));
const nameToDisplay = useSelector((state: IReduxState) => getParticipantDisplayName(state, selectedId ?? ''));
const localParticipant = useSelector(getLocalParticipant);
const localId = localParticipant?.id;

View File

@ -1,19 +1,14 @@
// @flow
import { MiddlewareRegistry } from '../base/redux';
import MiddlewareRegistry from '../base/redux/MiddlewareRegistry';
import { OPEN_KEYBOARD_SHORTCUTS_DIALOG } from './actionTypes';
declare var APP: Object;
/**
* Implements the middleware of the feature keyboard-shortcuts.
*
* @param {Store} store - The redux store.
* @returns {Function}
*/
// eslint-disable-next-line no-unused-vars
MiddlewareRegistry.register(store => next => action => {
MiddlewareRegistry.register(_store => next => action => {
switch (action.type) {
case OPEN_KEYBOARD_SHORTCUTS_DIALOG:
if (typeof APP === 'object') {

View File

@ -1,8 +1,5 @@
// @flow
import type { Dispatch } from 'redux';
import { MEDIA_TYPE } from '../base/media';
import { IReduxState, IStore } from '../app/types';
import { MEDIA_TYPE } from '../base/media/constants';
import {
getDominantSpeakerParticipant,
getLocalParticipant,
@ -10,9 +7,10 @@ import {
getPinnedParticipant,
getRemoteParticipants,
getVirtualScreenshareParticipantByOwnerId
} from '../base/participants';
} from '../base/participants/functions';
import { ITrack } from '../base/tracks/types';
import { isStageFilmstripAvailable } from '../filmstrip/functions';
import { getAutoPinSetting } from '../video-layout';
import { getAutoPinSetting } from '../video-layout/functions';
import {
SELECT_LARGE_VIDEO_PARTICIPANT,
@ -30,8 +28,8 @@ import {
* displayed on the large video.
* @returns {Function}
*/
export function selectParticipantInLargeVideo(participant: ?string) {
return (dispatch: Dispatch<any>, getState: Function) => {
export function selectParticipantInLargeVideo(participant?: string) {
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
const state = getState();
if (isStageFilmstripAvailable(state, 2)) {
@ -48,7 +46,7 @@ export function selectParticipantInLargeVideo(participant: ?string) {
const remoteScreenShares = state['features/video-layout'].remoteScreenShares;
let latestScreenshareParticipantId;
if (remoteScreenShares && remoteScreenShares.length) {
if (remoteScreenShares?.length) {
latestScreenshareParticipantId = remoteScreenShares[remoteScreenShares.length - 1];
}
@ -94,7 +92,7 @@ export function updateKnownLargeVideoResolution(resolution: number) {
* width: number
* }}
*/
export function setLargeVideoDimensions(height, width) {
export function setLargeVideoDimensions(height: number, width: number) {
return {
type: SET_LARGE_VIDEO_DIMENSIONS,
height,
@ -109,7 +107,7 @@ export function setLargeVideoDimensions(height, width) {
* @private
* @returns {(Track|undefined)}
*/
function _electLastVisibleRemoteVideo(tracks) {
function _electLastVisibleRemoteVideo(tracks: ITrack[]) {
// First we try to get most recent remote video track.
for (let i = tracks.length - 1; i >= 0; --i) {
const track = tracks[i];
@ -129,7 +127,7 @@ function _electLastVisibleRemoteVideo(tracks) {
* @private
* @returns {(string|undefined)}
*/
function _electParticipantInLargeVideo(state) {
function _electParticipantInLargeVideo(state: IReduxState) {
// If a participant is pinned, they will be shown in the LargeVideo (regardless of whether they are local or
// remote) when the filmstrip on stage is disabled.
let participant = getPinnedParticipant(state);

View File

@ -1,3 +1 @@
// @flow
export * from './actions.any';

View File

@ -1,10 +1,8 @@
// @flow
import type { Dispatch } from 'redux';
// @ts-expect-error
import VideoLayout from '../../../modules/UI/videolayout/VideoLayout';
import { MEDIA_TYPE } from '../base/media';
import { getTrackByMediaTypeAndParticipant } from '../base/tracks';
import { IStore } from '../app/types';
import { MEDIA_TYPE } from '../base/media/constants';
import { getTrackByMediaTypeAndParticipant } from '../base/tracks/functions.web';
import { SET_SEE_WHAT_IS_BEING_SHARED, UPDATE_LAST_LARGE_VIDEO_MEDIA_EVENT } from './actionTypes';
@ -16,7 +14,7 @@ export * from './actions.any';
* @returns {Function}
*/
export function captureLargeVideoScreenshot() {
return (dispatch: Dispatch<any>, getState: Function): Promise<string> => {
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
const state = getState();
const largeVideo = state['features/large-video'];
const promise = Promise.resolve();
@ -28,7 +26,7 @@ export function captureLargeVideoScreenshot() {
const participantTrack = getTrackByMediaTypeAndParticipant(tracks, MEDIA_TYPE.VIDEO, largeVideo.participantId);
// Participants that join the call video muted do not have a jitsiTrack attached.
if (!(participantTrack && participantTrack.jitsiTrack)) {
if (!participantTrack?.jitsiTrack) {
return promise;
}
const videoStream = participantTrack.jitsiTrack.getOriginalStream();
@ -39,7 +37,7 @@ export function captureLargeVideoScreenshot() {
// Get the video element for the large video, cast HTMLElement to HTMLVideoElement to make flow happy.
/* eslint-disable-next-line no-extra-parens*/
const videoElement = ((document.getElementById('largeVideo'): any): HTMLVideoElement);
const videoElement = (document.getElementById('largeVideo') as any);
if (!videoElement) {
return promise;
@ -54,11 +52,11 @@ export function captureLargeVideoScreenshot() {
canvasElement.style.display = 'none';
canvasElement.height = parseInt(height, 10);
canvasElement.width = parseInt(width, 10);
ctx.drawImage(videoElement, 0, 0);
ctx?.drawImage(videoElement, 0, 0);
const dataURL = canvasElement.toDataURL('image/png', 1.0);
// Cleanup.
ctx.clearRect(0, 0, canvasElement.width, canvasElement.height);
ctx?.clearRect(0, 0, canvasElement.width, canvasElement.height);
canvasElement.remove();
return Promise.resolve(dataURL);
@ -73,7 +71,7 @@ export function captureLargeVideoScreenshot() {
* @returns {Function}
*/
export function resizeLargeVideo(width: number, height: number) {
return (dispatch: Dispatch<any>, getState: Function) => {
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
const state = getState();
const largeVideo = state['features/large-video'];

View File

@ -1,15 +0,0 @@
// @flow
import { getParticipantById } from '../base/participants';
/**
* Selector for the participant currently displaying on the large video.
*
* @param {Object} state - The redux state.
* @returns {Object}
*/
export function getLargeVideoParticipant(state: Object) {
const { participantId } = state['features/large-video'];
return getParticipantById(state, participantId);
}

View File

@ -0,0 +1,14 @@
import { IReduxState } from '../app/types';
import { getParticipantById } from '../base/participants/functions';
/**
* Selector for the participant currently displaying on the large video.
*
* @param {Object} state - The redux state.
* @returns {Object}
*/
export function getLargeVideoParticipant(state: IReduxState) {
const { participantId } = state['features/large-video'];
return getParticipantById(state, participantId ?? '');
}

View File

@ -1,5 +1,3 @@
// @flow
import { getLogger } from '../base/logging/functions';
export default getLogger('features/large-video');

View File

@ -1,19 +1,16 @@
// @flow
import {
DOMINANT_SPEAKER_CHANGED,
PARTICIPANT_JOINED,
PARTICIPANT_LEFT,
PIN_PARTICIPANT,
getDominantSpeakerParticipant,
getLocalParticipant
} from '../base/participants';
import { MiddlewareRegistry } from '../base/redux';
import { isTestModeEnabled } from '../base/testing';
PIN_PARTICIPANT
} from '../base/participants/actionTypes';
import { getDominantSpeakerParticipant, getLocalParticipant } from '../base/participants/functions';
import MiddlewareRegistry from '../base/redux/MiddlewareRegistry';
import { isTestModeEnabled } from '../base/testing/functions';
import {
TRACK_ADDED,
TRACK_REMOVED
} from '../base/tracks';
} from '../base/tracks/actionTypes';
import { TOGGLE_DOCUMENT_EDITING } from '../etherpad/actionTypes';
import { selectParticipantInLargeVideo } from './actions';

View File

@ -1,8 +1,7 @@
// @flow
// @ts-expect-error
import VideoLayout from '../../../modules/UI/videolayout/VideoLayout';
import { StateListenerRegistry } from '../base/redux';
import { getVideoTrackByParticipant } from '../base/tracks';
import StateListenerRegistry from '../base/redux/StateListenerRegistry';
import { getVideoTrackByParticipant } from '../base/tracks/functions.web';
import { getLargeVideoParticipant } from './functions';
@ -29,7 +28,7 @@ StateListenerRegistry.register(
streamingStatus: videoTrack?.streamingStatus
};
},
/* listener */ ({ participantId, streamingStatus }, previousState = {}) => {
/* listener */ ({ participantId, streamingStatus }, previousState: any = {}) => {
if (streamingStatus !== previousState.streamingStatus) {
VideoLayout.updateLargeVideo(participantId, true);
}

View File

@ -1,19 +1,13 @@
// @flow
import { type Dispatch } from 'redux';
import {
conferenceWillJoin,
getCurrentConference,
sendLocalParticipant,
setPassword
} from '../base/conference';
import { getLocalParticipant } from '../base/participants';
import { IStore } from '../app/types';
import { conferenceWillJoin, setPassword } from '../base/conference/actions';
import { getCurrentConference, sendLocalParticipant } from '../base/conference/functions';
import { getLocalParticipant } from '../base/participants/functions';
import { IParticipant } from '../base/participants/types';
import { onLobbyChatInitialized, removeLobbyChatParticipant, sendMessage } from '../chat/actions.any';
import { LOBBY_CHAT_MESSAGE } from '../chat/constants';
import { handleLobbyMessageReceived } from '../chat/middleware';
import { LOBBY_NOTIFICATION_ID, hideNotification } from '../notifications';
import { showNotification } from '../notifications/actions';
import { hideNotification, showNotification } from '../notifications/actions';
import { LOBBY_NOTIFICATION_ID } from '../notifications/constants';
import {
KNOCKING_PARTICIPANT_ARRIVED_OR_UPDATED,
@ -27,6 +21,7 @@ import {
} from './actionTypes';
import { LOBBY_CHAT_INITIALIZED, MODERATOR_IN_CHAT_WITH_LEFT } from './constants';
import { getKnockingParticipants, getLobbyEnabled } from './functions';
import { IKnockingParticipant } from './types';
/**
* Tries to join with a preset password.
@ -35,7 +30,7 @@ import { getKnockingParticipants, getLobbyEnabled } from './functions';
* @returns {Function}
*/
export function joinWithPassword(password: string) {
return async (dispatch: Dispatch<any>, getState: Function) => {
return async (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
const conference = getCurrentConference(getState);
dispatch(setPassword(conference, conference.join, password));
@ -67,7 +62,7 @@ export function knockingParticipantLeft(id: string) {
* type: KNOCKING_PARTICIPANT_ARRIVED_OR_UPDATED
* }}
*/
export function participantIsKnockingOrUpdated(participant: Object) {
export function participantIsKnockingOrUpdated(participant: IKnockingParticipant | Object) {
return {
participant,
type: KNOCKING_PARTICIPANT_ARRIVED_OR_UPDATED
@ -82,7 +77,7 @@ export function participantIsKnockingOrUpdated(participant: Object) {
* @returns {Function}
*/
export function answerKnockingParticipant(id: string, approved: boolean) {
return async (dispatch: Dispatch<any>) => {
return async (dispatch: IStore['dispatch']) => {
dispatch(setKnockingParticipantApproval(id, approved));
dispatch(hideNotification(LOBBY_NOTIFICATION_ID));
};
@ -96,7 +91,7 @@ export function answerKnockingParticipant(id: string, approved: boolean) {
* @returns {Function}
*/
export function setKnockingParticipantApproval(id: string, approved: boolean) {
return async (dispatch: Dispatch<any>, getState: Function) => {
return async (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
const conference = getCurrentConference(getState);
if (conference) {
@ -115,8 +110,8 @@ export function setKnockingParticipantApproval(id: string, approved: boolean) {
* @param {Array<Object>} participants - A list of knocking participants.
* @returns {void}
*/
export function admitMultiple(participants: Array<Object>) {
return (dispatch: Function, getState: Function) => {
export function admitMultiple(participants: Array<IKnockingParticipant>) {
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
const conference = getCurrentConference(getState);
participants.forEach(p => {
@ -132,10 +127,10 @@ export function admitMultiple(participants: Array<Object>) {
* @returns {Function}
*/
export function approveKnockingParticipant(id: string) {
return (dispatch: Dispatch<any>, getState: Function) => {
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
const conference = getCurrentConference(getState);
conference && conference.lobbyApproveAccess(id);
conference?.lobbyApproveAccess(id);
};
}
@ -146,10 +141,10 @@ export function approveKnockingParticipant(id: string) {
* @returns {Function}
*/
export function rejectKnockingParticipant(id: string) {
return (dispatch: Dispatch<any>, getState: Function) => {
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
const conference = getCurrentConference(getState);
conference && conference.lobbyDenyAccess(id);
conference?.lobbyDenyAccess(id);
};
}
@ -207,18 +202,20 @@ export function setPasswordJoinFailed(failed: boolean) {
* @returns {Function}
*/
export function startKnocking() {
return async (dispatch: Dispatch<any>, getState: Function) => {
return async (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
const state = getState();
const { membersOnly } = state['features/base/conference'];
const localParticipant = getLocalParticipant(state);
// @ts-ignore
dispatch(conferenceWillJoin(membersOnly));
// We need to update the conference object with the current display name, if approved
// we want to send that display name, it was not updated in case when pre-join is disabled
// @ts-ignore
sendLocalParticipant(state, membersOnly);
membersOnly.joinLobby(localParticipant.name, localParticipant.email);
membersOnly?.joinLobby(localParticipant?.name, localParticipant?.email);
dispatch(setLobbyMessageListener());
dispatch(setKnockingState(true));
};
@ -231,7 +228,7 @@ export function startKnocking() {
* @returns {Function}
*/
export function toggleLobbyMode(enabled: boolean) {
return async (dispatch: Dispatch<any>, getState: Function) => {
return async (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
const conference = getCurrentConference(getState);
if (enabled) {
@ -275,8 +272,8 @@ export function hideLobbyScreen() {
*
* @returns {Promise<void>}
*/
export function handleLobbyChatInitialized(payload: Object) {
return async (dispatch: Dispatch<any>, getState: Function) => {
export function handleLobbyChatInitialized(payload: { attendee: IParticipant; moderator: IParticipant; }) {
return async (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
const state = getState();
const conference = getCurrentConference(state);
@ -296,8 +293,8 @@ export function handleLobbyChatInitialized(payload: Object) {
dispatch(showNotification({
titleKey: 'lobby.lobbyChatStartedNotification',
titleArguments: {
moderator: payload.moderator.name,
attendee: payload.attendee.name
moderator: payload.moderator.name ?? '',
attendee: payload.attendee.name ?? ''
}
}));
}
@ -312,7 +309,7 @@ export function handleLobbyChatInitialized(payload: Object) {
* @returns {Promise<void>}
*/
export function onSendMessage(message: string) {
return async (dispatch: Dispatch<any>) => {
return async (dispatch: IStore['dispatch']) => {
dispatch(sendMessage(message));
};
}
@ -325,7 +322,7 @@ export function onSendMessage(message: string) {
* @returns {Promise<void>}
*/
export function sendLobbyChatMessage(message: Object) {
return async (dispatch: Dispatch<any>, getState: Function) => {
return async (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
const conference = getCurrentConference(getState);
conference.sendLobbyMessage(message);
@ -338,7 +335,7 @@ export function sendLobbyChatMessage(message: Object) {
* @returns {Function}
*/
export function maybeSetLobbyChatMessageListener() {
return async (dispatch: Dispatch<any>, getState: Function) => {
return async (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
const state = getState();
const lobbyEnabled = getLobbyEnabled(state);
@ -355,7 +352,7 @@ export function maybeSetLobbyChatMessageListener() {
* @returns {Function}
*/
export function updateLobbyParticipantOnLeave(participantId: string) {
return async (dispatch: Dispatch<any>, getState: Function) => {
return async (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
const state = getState();
const { knocking, knockingParticipants } = state['features/lobby'];
const { lobbyMessageRecipient } = state['features/chat'];
@ -370,7 +367,7 @@ export function updateLobbyParticipantOnLeave(participantId: string) {
const participantToNotify = knockingParticipants.find(p => p.chattingWithModerator === participantId);
if (participantToNotify) {
conference.sendLobbyMessage({
conference?.sendLobbyMessage({
type: MODERATOR_IN_CHAT_WITH_LEFT,
moderatorId: participantToNotify.chattingWithModerator
}, participantToNotify.id);
@ -389,7 +386,7 @@ export function updateLobbyParticipantOnLeave(participantId: string) {
* @returns {Function}
*/
export function setLobbyMessageListener() {
return async (dispatch: Dispatch<any>, getState: Function) => {
return async (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
const state = getState();
const conference = getCurrentConference(state);
const { enableLobbyChat = true } = state['features/base/config'];
@ -398,7 +395,7 @@ export function setLobbyMessageListener() {
return;
}
conference.addLobbyMessageListener((message: Object, participantId: string) => {
conference.addLobbyMessageListener((message: any, participantId: string) => {
if (message.type === LOBBY_CHAT_MESSAGE) {
return dispatch(handleLobbyMessageReceived(message.message, participantId));
}

View File

@ -1,6 +1,7 @@
import { batch } from 'react-redux';
import { appNavigate } from '../app/actions';
import { appNavigate } from '../app/actions.native';
import { IStore } from '../app/types';
import { hideLobbyScreen, setKnockingState } from './actions.any';
@ -12,7 +13,7 @@ export * from './actions.any';
* @returns {Function}
*/
export function cancelKnocking() {
return dispatch => {
return (dispatch: IStore['dispatch']) => {
batch(() => {
dispatch(setKnockingState(false));
dispatch(hideLobbyScreen());

View File

@ -1,20 +1,15 @@
// @flow
import { type Dispatch } from 'redux';
import { maybeRedirectToWelcomePage } from '../app/actions';
import { maybeRedirectToWelcomePage } from '../app/actions.web';
import { IStore } from '../app/types';
export * from './actions.any';
declare var APP: Object;
/**
* Cancels the ongoing knocking and abandons the join flow.
*
* @returns {Function}
*/
export function cancelKnocking() {
return async (dispatch: Dispatch<any>) => {
return async (dispatch: IStore['dispatch']) => {
// when we are redirecting the library should handle any
// unload and clean of the connection.
APP.API.notifyReadyToClose();

View File

@ -1,44 +1,46 @@
// @flow
import { IReduxState } from '../app/types';
import { getCurrentConference } from '../base/conference/functions';
import { IKnockingParticipant } from './types';
import { getCurrentConference } from '../base/conference';
/**
* Selector to return lobby enable state.
*
* @param {any} state - State object.
* @param {IReduxState} state - State object.
* @returns {boolean}
*/
export function getLobbyEnabled(state: any) {
export function getLobbyEnabled(state: IReduxState) {
return state['features/lobby'].lobbyEnabled;
}
/**
* Selector to return a list of knocking participants.
*
* @param {any} state - State object.
* @param {IReduxState} state - State object.
* @returns {Array<Object>}
*/
export function getKnockingParticipants(state: any) {
export function getKnockingParticipants(state: IReduxState) {
return state['features/lobby'].knockingParticipants;
}
/**
* Selector to return lobby visibility.
*
* @param {any} state - State object.
* @param {IReduxState} state - State object.
* @returns {any}
*/
export function getIsLobbyVisible(state: any) {
export function getIsLobbyVisible(state: IReduxState) {
return state['features/lobby'].lobbyVisible;
}
/**
* Selector to return array with knocking participant ids.
*
* @param {any} state - State object.
* @param {IReduxState} state - State object.
* @returns {Array}
*/
export function getKnockingParticipantsById(state: any) {
export function getKnockingParticipantsById(state: IReduxState) {
return getKnockingParticipants(state).map(participant => participant.id);
}
@ -50,9 +52,9 @@ export function getKnockingParticipantsById(state: any) {
* @returns {Function}
*/
export function showLobbyChatButton(
participant: Object
participant: IKnockingParticipant
) {
return function(state: Object) {
return function(state: IReduxState) {
const { enableLobbyChat = true } = state['features/base/config'];
const { lobbyMessageRecipient, isLobbyChatActive } = state['features/chat'];

View File

@ -1,5 +1,3 @@
// @flow
import { getLogger } from '../base/logging/functions';
export default getLogger('features/lobby');

View File

@ -1,39 +1,41 @@
// @flow
import i18n from 'i18next';
import { batch } from 'react-redux';
import { AnyAction } from 'redux';
import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../base/app';
import {
CONFERENCE_FAILED,
CONFERENCE_JOINED,
conferenceWillJoin
} from '../base/conference';
import { IStore } from '../app/types';
import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../base/app/actionTypes';
import { CONFERENCE_FAILED, CONFERENCE_JOINED } from '../base/conference/actionTypes';
import { conferenceWillJoin } from '../base/conference/actions';
import { JitsiConferenceErrors, JitsiConferenceEvents } from '../base/lib-jitsi-meet';
import { getFirstLoadableAvatarUrl, getParticipantDisplayName } from '../base/participants';
import { MiddlewareRegistry, StateListenerRegistry } from '../base/redux';
import { playSound, registerSound, unregisterSound } from '../base/sounds';
import { isTestModeEnabled } from '../base/testing';
import { getFirstLoadableAvatarUrl, getParticipantDisplayName } from '../base/participants/functions';
import MiddlewareRegistry from '../base/redux/MiddlewareRegistry';
import StateListenerRegistry from '../base/redux/StateListenerRegistry';
import { playSound, registerSound, unregisterSound } from '../base/sounds/actions';
import { isTestModeEnabled } from '../base/testing/functions';
import { handleLobbyChatInitialized, removeLobbyChatParticipant } from '../chat/actions.any';
import { approveKnockingParticipant, rejectKnockingParticipant } from '../lobby/actions';
import {
hideNotification,
showNotification
} from '../notifications/actions';
import {
LOBBY_NOTIFICATION_ID,
NOTIFICATION_ICON,
NOTIFICATION_TIMEOUT_TYPE,
NOTIFICATION_TYPE,
hideNotification,
showNotification
} from '../notifications';
NOTIFICATION_TYPE
} from '../notifications/constants';
import { INotificationProps } from '../notifications/types';
import { open as openParticipantsPane } from '../participants-pane/actions';
import { getParticipantsPaneOpen } from '../participants-pane/functions';
import { shouldAutoKnock } from '../prejoin/functions';
import { KNOCKING_PARTICIPANT_ARRIVED_OR_UPDATED, KNOCKING_PARTICIPANT_LEFT } from './actionTypes';
import {
approveKnockingParticipant,
hideLobbyScreen,
knockingParticipantLeft,
openLobbyScreen,
participantIsKnockingOrUpdated,
rejectKnockingParticipant,
setLobbyMessageListener,
setLobbyModeEnabled,
setPasswordJoinFailed,
@ -43,8 +45,7 @@ import { updateLobbyParticipantOnLeave } from './actions.any';
import { KNOCKING_PARTICIPANT_SOUND_ID } from './constants';
import { getKnockingParticipants, showLobbyChatButton } from './functions';
import { KNOCKING_PARTICIPANT_FILE } from './sounds';
declare var APP: Object;
import { IKnockingParticipant } from './types';
MiddlewareRegistry.register(store => next => action => {
switch (action.type) {
@ -88,14 +89,14 @@ StateListenerRegistry.register(
state => state['features/base/conference'].conference,
(conference, { dispatch, getState }, previousConference) => {
if (conference && !previousConference) {
conference.on(JitsiConferenceEvents.MEMBERS_ONLY_CHANGED, enabled => {
conference.on(JitsiConferenceEvents.MEMBERS_ONLY_CHANGED, (enabled: boolean) => {
dispatch(setLobbyModeEnabled(enabled));
if (enabled) {
dispatch(setLobbyMessageListener());
}
});
conference.on(JitsiConferenceEvents.LOBBY_USER_JOINED, (id, name) => {
conference.on(JitsiConferenceEvents.LOBBY_USER_JOINED, (id: string, name: string) => {
const { soundsParticipantKnocking } = getState()['features/base/settings'];
batch(() => {
@ -180,7 +181,7 @@ StateListenerRegistry.register(
});
});
conference.on(JitsiConferenceEvents.LOBBY_USER_UPDATED, (id, participant) => {
conference.on(JitsiConferenceEvents.LOBBY_USER_UPDATED, (id: string, participant: IKnockingParticipant) => {
dispatch(
participantIsKnockingOrUpdated({
...participant,
@ -189,7 +190,7 @@ StateListenerRegistry.register(
);
});
conference.on(JitsiConferenceEvents.LOBBY_USER_LEFT, id => {
conference.on(JitsiConferenceEvents.LOBBY_USER_LEFT, (id: string) => {
batch(() => {
dispatch(knockingParticipantLeft(id));
dispatch(removeLobbyChatParticipant());
@ -197,7 +198,7 @@ StateListenerRegistry.register(
});
});
conference.on(JitsiConferenceEvents.ENDPOINT_MESSAGE_RECEIVED, (origin, sender) =>
conference.on(JitsiConferenceEvents.ENDPOINT_MESSAGE_RECEIVED, (origin: any, sender: any) =>
_maybeSendLobbyNotification(origin, sender, {
dispatch,
getState
@ -213,7 +214,7 @@ StateListenerRegistry.register(
* @param {Object} store - The Redux store.
* @returns {void}
*/
function _handleLobbyNotification(store) {
function _handleLobbyNotification(store: IStore) {
const { dispatch, getState } = store;
const knockingParticipants = getKnockingParticipants(getState());
@ -275,7 +276,7 @@ function _handleLobbyNotification(store) {
* @param {Object} action - The Redux action.
* @returns {Object}
*/
function _conferenceFailed({ dispatch, getState }, next, action) {
function _conferenceFailed({ dispatch, getState }: IStore, next: Function, action: AnyAction) {
const { error } = action;
const state = getState();
const { membersOnly } = state['features/base/conference'];
@ -296,6 +297,7 @@ function _conferenceFailed({ dispatch, getState }, next, action) {
// In case of wrong password we need to be in the right state if in the meantime someone allows us to join
if (nonFirstFailure) {
// @ts-ignore
dispatch(conferenceWillJoin(membersOnly));
}
@ -328,7 +330,7 @@ function _conferenceFailed({ dispatch, getState }, next, action) {
* @param {Object} action - The Redux action.
* @returns {Object}
*/
function _conferenceJoined({ dispatch }, next, action) {
function _conferenceJoined({ dispatch }: IStore, next: Function, action: AnyAction) {
dispatch(hideLobbyScreen());
return next(action);
@ -341,13 +343,13 @@ function _conferenceJoined({ dispatch }, next, action) {
* @param {Object} participant - The knocking participant.
* @returns {void}
*/
function _findLoadableAvatarForKnockingParticipant(store, { id }) {
function _findLoadableAvatarForKnockingParticipant(store: IStore, { id }: { id: string; }) {
const { dispatch, getState } = store;
const updatedParticipant = getState()['features/lobby'].knockingParticipants.find(p => p.id === id);
const { disableThirdPartyRequests } = getState()['features/base/config'];
if (!disableThirdPartyRequests && updatedParticipant && !updatedParticipant.loadableAvatarUrl) {
getFirstLoadableAvatarUrl(updatedParticipant, store).then(result => {
getFirstLoadableAvatarUrl(updatedParticipant, store).then((result: { isUsingCORS: boolean; src: string; }) => {
if (result) {
const { isUsingCORS, src } = result;
@ -372,12 +374,12 @@ function _findLoadableAvatarForKnockingParticipant(store, { id }) {
* @param {Object} store - The Redux store.
* @returns {void}
*/
function _maybeSendLobbyNotification(origin, message, { dispatch, getState }) {
function _maybeSendLobbyNotification(origin: any, message: any, { dispatch, getState }: IStore) {
if (!origin?._id || message?.type !== 'lobby-notify') {
return;
}
const notificationProps: any = {
const notificationProps: INotificationProps = {
descriptionArguments: {
originParticipantName: getParticipantDisplayName(getState, origin._id),
targetParticipantName: message.name

View File

@ -1,5 +1,4 @@
import { CONFERENCE_JOINED, CONFERENCE_LEFT, SET_PASSWORD } from '../base/conference/actionTypes';
import { IParticipant } from '../base/participants/types';
import ReducerRegistry from '../base/redux/ReducerRegistry';
import {
@ -12,6 +11,7 @@ import {
SET_LOBBY_VISIBILITY,
SET_PASSWORD_JOIN_FAILED
} from './actionTypes';
import { IKnockingParticipant } from './types';
const DEFAULT_STATE = {
knocking: false,
@ -21,10 +21,6 @@ const DEFAULT_STATE = {
passwordJoinFailed: false
};
interface IKnockingParticipant extends IParticipant {
chattingWithModerator?: string;
}
export interface ILobbyState {
knocking: boolean;
knockingParticipants: IKnockingParticipant[];

View File

@ -0,0 +1,5 @@
import { IParticipant } from '../base/participants/types';
export interface IKnockingParticipant extends IParticipant {
chattingWithModerator?: string;
}

View File

@ -1,6 +1,4 @@
// @flow
import { browser } from '../../../react/features/base/lib-jitsi-meet';
import { browser } from '../base/lib-jitsi-meet';
/**
* Returns true if Jitsi Meet is running in too old jitsi-meet-electron app and false otherwise.

View File

@ -1,16 +1,16 @@
// @flow
import React from 'react';
import { AnyAction } from 'redux';
import { APP_WILL_MOUNT } from '../base/app';
import { MiddlewareRegistry } from '../base/redux';
import { NOTIFICATION_TIMEOUT_TYPE, showErrorNotification } from '../notifications';
import { IStore } from '../app/types';
import { APP_WILL_MOUNT } from '../base/app/actionTypes';
import MiddlewareRegistry from '../base/redux/MiddlewareRegistry';
import { showErrorNotification } from '../notifications/actions';
import { NOTIFICATION_TIMEOUT_TYPE } from '../notifications/constants';
// @ts-ignore
import { OldElectronAPPNotificationDescription } from './components';
import { isOldJitsiMeetElectronApp } from './functions';
declare var interfaceConfig: Object;
MiddlewareRegistry.register(store => next => action => {
switch (action.type) {
case APP_WILL_MOUNT:
@ -29,7 +29,7 @@ MiddlewareRegistry.register(store => next => action => {
* @private
* @returns {Object} The new state that is the result of the reduction of the specified {@code action}.
*/
function _appWillMount(store, next, action) {
function _appWillMount(store: IStore, next: Function, action: AnyAction) {
if (isOldJitsiMeetElectronApp()) {
const { dispatch } = store;

View File

@ -9,9 +9,7 @@ import { Avatar } from '../../../base/avatar';
import Icon from '../../../base/icons/components/Icon';
import { IconCheck, IconCloseLarge } from '../../../base/icons/svg';
import { withPixelLineHeight } from '../../../base/styles/functions.web';
// @ts-ignore
import { admitMultiple } from '../../../lobby/actions.web';
// @ts-ignore
import { getKnockingParticipants, getLobbyEnabled } from '../../../lobby/functions';
// @ts-ignore
import { Drawer, JitsiPortal } from '../../../toolbox/components/web';
@ -72,7 +70,7 @@ const useStyles = makeStyles()(theme => {
*/
export default function LobbyParticipants() {
const lobbyEnabled = useSelector(getLobbyEnabled);
const participants: Array<Object> = useSelector(getKnockingParticipants);
const participants = useSelector(getKnockingParticipants);
const { t } = useTranslation();
const { classes } = useStyles();
const dispatch = useDispatch();

View File

@ -2,9 +2,7 @@ import { useCallback, useState } from 'react';
import { useDispatch } from 'react-redux';
import { handleLobbyChatInitialized } from '../chat/actions.any';
// eslint-disable-next-line lines-around-comment
// @ts-ignore
import { approveKnockingParticipant, rejectKnockingParticipant } from '../lobby/actions';
import { approveKnockingParticipant, rejectKnockingParticipant } from '../lobby/actions.web';
interface IDrawerParticipant {
displayName?: string;
@ -24,12 +22,12 @@ export function useLobbyActions(participant?: IDrawerParticipant | null, closeDr
return [
useCallback(e => {
e.stopPropagation();
dispatch(approveKnockingParticipant(participant?.participantID));
dispatch(approveKnockingParticipant(participant?.participantID ?? ''));
closeDrawer?.();
}, [ dispatch, closeDrawer ]),
useCallback(() => {
dispatch(rejectKnockingParticipant(participant?.participantID));
dispatch(rejectKnockingParticipant(participant?.participantID ?? ''));
closeDrawer?.();
}, [ dispatch, closeDrawer ]),

View File

@ -26,6 +26,7 @@
"react/features/feedback",
"react/features/no-audio-signal",
"react/features/noise-suppression",
"react/features/old-client-notification",
"react/features/screen-share",
"react/features/stream-effects/noise-suppression",
"react/features/stream-effects/rnnoise",