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

This commit is contained in:
Robert Pintilii 2022-11-11 10:20:33 +02:00 committed by GitHub
parent a884a6b232
commit 7a9f51b01b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 141 additions and 137 deletions

1
globals.native.d.ts vendored
View File

@ -27,6 +27,7 @@ interface IWindow {
clearTimeout: typeof clearTimeout;
setImmediate: typeof setImmediate;
clearImmediate: typeof clearImmediate;
addEventListener: Function;
}
interface INavigator {

View File

@ -58,6 +58,7 @@ export interface IJitsiConference {
isCallstatsEnabled: Function;
isEndConferenceSupported: Function;
isLobbySupported: Function;
isSIPCallingSupported: Function;
isStartAudioMuted: Function;
isStartVideoMuted: Function;
join: Function;

View File

@ -342,6 +342,7 @@ export interface IConfig {
iAmRecorder?: boolean;
iAmSipGateway?: boolean;
inviteAppName?: string | null;
jaasActuatorUrl?: string;
jaasFeedbackMetadataURL?: string;
jaasTokenUrl?: string;
lastNLimits?: {
@ -391,6 +392,7 @@ export interface IConfig {
hideMuteAllButton?: boolean;
};
pcStatsInterval?: number;
peopleSearchUrl?: string;
preferH264?: boolean;
preferredTranscribeLanguage?: string;
prejoinConfig?: {
@ -427,6 +429,7 @@ export interface IConfig {
mode?: 'always' | 'recording';
};
serviceUrl?: string;
sipInviteUrl?: string;
speakerStats?: {
disableSearch?: boolean;
disabled?: boolean;

View File

@ -1,13 +1,12 @@
// @flow
// @ts-expect-error
import { getJitsiMeetTransport } from '../../../modules/transport';
import {
CONFERENCE_FAILED,
CONFERENCE_JOINED,
DATA_CHANNEL_OPENED,
KICKED_OUT
} from '../base/conference';
import { SET_CONFIG } from '../base/config';
} from '../base/conference/actionTypes';
import { SET_CONFIG } from '../base/config/actionTypes';
import { NOTIFY_CAMERA_ERROR, NOTIFY_MIC_ERROR } from '../base/devices/actionTypes';
import { JitsiConferenceErrors } from '../base/lib-jitsi-meet';
import {
@ -16,21 +15,21 @@ import {
PARTICIPANT_KICKED,
PARTICIPANT_LEFT,
PARTICIPANT_ROLE_CHANGED,
SET_LOADABLE_AVATAR_URL,
SET_LOADABLE_AVATAR_URL
} from '../base/participants/actionTypes';
import {
getDominantSpeakerParticipant,
getLocalParticipant,
getParticipantById
} from '../base/participants';
import { MiddlewareRegistry } from '../base/redux';
import { getBaseUrl } from '../base/util';
import { appendSuffix } from '../display-name';
import { SUBMIT_FEEDBACK_ERROR, SUBMIT_FEEDBACK_SUCCESS } from '../feedback';
import { SET_FILMSTRIP_VISIBLE } from '../filmstrip';
} from '../base/participants/functions';
import MiddlewareRegistry from '../base/redux/MiddlewareRegistry';
import { getBaseUrl } from '../base/util/helpers';
import { appendSuffix } from '../display-name/functions';
import { SUBMIT_FEEDBACK_ERROR, SUBMIT_FEEDBACK_SUCCESS } from '../feedback/actionTypes';
import { SET_FILMSTRIP_VISIBLE } from '../filmstrip/actionTypes';
import './subscriber';
declare var APP: Object;
/**
* The middleware of the feature {@code external-api}.
*
@ -103,8 +102,8 @@ MiddlewareRegistry.register(store => next => action => {
const state = store.getState();
const { defaultLocalDisplayName } = state['features/base/config'];
const { room } = state['features/base/conference'];
const { loadableAvatarUrl, name, id, email } = getLocalParticipant(state);
const breakoutRoom = APP.conference.roomName.toString() !== room.toLowerCase();
const { loadableAvatarUrl, name, id, email } = getLocalParticipant(state) ?? {};
const breakoutRoom = APP.conference.roomName.toString() !== room?.toLowerCase();
// we use APP.conference.roomName as we do not update state['features/base/conference'].room when
// moving between rooms in case of breakout rooms and it stays always with the name of the main room
@ -114,7 +113,7 @@ MiddlewareRegistry.register(store => next => action => {
{
displayName: name,
formattedDisplayName: appendSuffix(
name,
name ?? '',
defaultLocalDisplayName
),
avatarURL: loadableAvatarUrl,
@ -132,7 +131,7 @@ MiddlewareRegistry.register(store => next => action => {
case KICKED_OUT:
APP.API.notifyKickedOut(
{
id: getLocalParticipant(store.getState()).id,
id: getLocalParticipant(store.getState())?.id,
local: true
},
{ id: action.participant ? action.participant.getId() : undefined }
@ -142,7 +141,7 @@ MiddlewareRegistry.register(store => next => action => {
case NOTIFY_CAMERA_ERROR:
if (action.error) {
APP.API.notifyOnCameraError(
action.error.name, action.error.message);
action.error.name, action.error.message);
}
break;

View File

@ -1,11 +1,7 @@
// @flow
import { getLocalParticipant } from '../base/participants';
import { StateListenerRegistry } from '../base/redux';
import { appendSuffix } from '../display-name';
import { shouldDisplayTileView } from '../video-layout';
declare var APP: Object;
import { getLocalParticipant } from '../base/participants/functions';
import StateListenerRegistry from '../base/redux/StateListenerRegistry';
import { appendSuffix } from '../display-name/functions';
import { shouldDisplayTileView } from '../video-layout/functions';
/**
* StateListenerRegistry provides a reliable way of detecting changes to

View File

@ -1,4 +1,4 @@
// @flow
import { IStore } from '../app/types';
import { SET_DETAILS } from './actionTypes';
import { getVpaasTenant, sendGetDetailsRequest } from './functions';
@ -10,7 +10,7 @@ import logger from './logger';
* @param {Object} details - The customer details object.
* @returns {Object}
*/
function setCustomerDetails(details) {
function setCustomerDetails(details: Object) {
return {
type: SET_DETAILS,
payload: details
@ -23,7 +23,7 @@ function setCustomerDetails(details) {
* @returns {Function}
*/
export function getCustomerDetails() {
return async function(dispatch: Function, getState: Function) {
return async function(dispatch: IStore['dispatch'], getState: IStore['getState']) {
const state = getState();
const baseUrl = state['features/base/config'].jaasActuatorUrl || 'https://api-vo-pilot.jitsi.net/jaas-actuator';
const appId = getVpaasTenant(state);

View File

@ -1,8 +1,7 @@
// @flow
import { IStore } from '../app/types';
import { openDialog } from '../base/dialog/actions';
import { openDialog } from '../base/dialog';
import { PremiumFeatureDialog } from './components';
import PremiumFeatureDialog from './components/web/PremiumFeatureDialog';
import { isFeatureDisabled } from './functions';
/**
@ -13,7 +12,7 @@ import { isFeatureDisabled } from './functions';
* @returns {Function}
*/
export function maybeShowPremiumFeatureDialog(feature: string) {
return function(dispatch: Function, getState: Function) {
return function(dispatch: IStore['dispatch'], getState: IStore['getState']) {
if (isFeatureDisabled(getState(), feature)) {
dispatch(openDialog(PremiumFeatureDialog));

View File

@ -1,6 +1,8 @@
import { createVpaasConferenceJoinedEvent, sendAnalytics } from '../analytics';
import { createVpaasConferenceJoinedEvent } from '../analytics/AnalyticsEvents';
import { sendAnalytics } from '../analytics/functions';
import { IReduxState } from '../app/types';
import { CONFERENCE_JOINED } from '../base/conference/actionTypes';
import { MiddlewareRegistry } from '../base/redux';
import MiddlewareRegistry from '../base/redux/MiddlewareRegistry';
import { getVpaasTenant, isVpaasMeeting } from './functions';
@ -29,7 +31,7 @@ MiddlewareRegistry.register(store => next => async action => {
* @param {Store} state - The app state.
* @returns {Function}
*/
function _maybeTrackVpaasConferenceJoin(state) {
function _maybeTrackVpaasConferenceJoin(state: IReduxState) {
if (isVpaasMeeting(state)) {
sendAnalytics(createVpaasConferenceJoinedEvent(
getVpaasTenant(state)));

View File

@ -1,10 +1,10 @@
import { redirectToStaticPage } from '../app/actions';
import { redirectToStaticPage } from '../app/actions.web';
import { CONFERENCE_JOINED } from '../base/conference/actionTypes';
import {
JitsiConferenceErrors,
JitsiConferenceEvents
} from '../base/lib-jitsi-meet';
import { MiddlewareRegistry } from '../base/redux';
import MiddlewareRegistry from '../base/redux/MiddlewareRegistry';
import { SET_DETAILS } from './actionTypes';
import { STATUSES } from './constants';
@ -27,7 +27,7 @@ MiddlewareRegistry.register(store => next => async action => {
}
conference.on(
JitsiConferenceEvents.CONFERENCE_ERROR, (errorType, errorMsg) => {
JitsiConferenceEvents.CONFERENCE_ERROR, (errorType: string, errorMsg: string) => {
errorType === JitsiConferenceErrors.SETTINGS_ERROR && logger.error(errorMsg);
});
break;

View File

@ -1,17 +1,17 @@
// @flow
import { getMeetingRegion, getRecordingSharingUrl } from '../base/config';
import { IStore } from '../app/types';
import { getMeetingRegion, getRecordingSharingUrl } from '../base/config/functions';
import JitsiMeetJS, { JitsiRecordingConstants } from '../base/lib-jitsi-meet';
import { getLocalParticipant, getParticipantDisplayName } from '../base/participants';
import { getLocalParticipant, getParticipantDisplayName } from '../base/participants/functions';
import { copyText } from '../base/util/copyText';
import { getVpaasTenant, isVpaasMeeting } from '../jaas/functions';
import {
NOTIFICATION_TIMEOUT_TYPE,
hideNotification,
showErrorNotification,
showNotification,
showWarningNotification
} from '../notifications';
} from '../notifications/actions';
import { NOTIFICATION_TIMEOUT_TYPE } from '../notifications/constants';
import { INotificationProps } from '../notifications/types';
import {
CLEAR_RECORDING_SESSIONS,
@ -31,8 +31,6 @@ import {
} from './functions';
import logger from './logger';
declare var APP: Object;
/**
* Clears the data of every recording sessions.
*
@ -70,7 +68,7 @@ export function setHighlightMomentButtonState(disabled: boolean) {
* @returns {Function}
*/
export function hidePendingRecordingNotification(streamType: string) {
return (dispatch: Function, getState: Function) => {
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
const { pendingNotificationUids } = getState()['features/recording'];
const pendingNotificationUid = pendingNotificationUids[streamType];
@ -108,7 +106,7 @@ export function setLiveStreamKey(streamKey: string) {
* @returns {Function}
*/
export function showPendingRecordingNotification(streamType: string) {
return async (dispatch: Function) => {
return async (dispatch: IStore['dispatch']) => {
const isLiveStreaming
= streamType === JitsiMeetJS.constants.recording.mode.STREAM;
const dialogProps = isLiveStreaming ? {
@ -209,13 +207,13 @@ export function showStoppedRecordingNotification(streamType: string, participant
*/
export function showStartedRecordingNotification(
mode: string,
initiator: Object | string,
initiator: { getId: Function; } | string,
sessionId: string) {
return async (dispatch: Function, getState: Function) => {
const state = getState();
const initiatorId = getResourceId(initiator);
const participantName = getParticipantDisplayName(state, initiatorId);
let dialogProps = {
let dialogProps: INotificationProps = {
descriptionKey: participantName ? 'liveStreaming.onBy' : 'liveStreaming.on',
descriptionArguments: { name: participantName },
titleKey: 'dialog.liveStreaming'
@ -223,7 +221,7 @@ export function showStartedRecordingNotification(
if (mode !== JitsiMeetJS.constants.recording.mode.STREAM) {
const recordingSharingUrl = getRecordingSharingUrl(state);
const iAmRecordingInitiator = getLocalParticipant(state).id === initiatorId;
const iAmRecordingInitiator = getLocalParticipant(state)?.id === initiatorId;
dialogProps = {
customActionHandler: undefined,
@ -278,7 +276,7 @@ export function showStartedRecordingNotification(
* sessionData: Object
* }}
*/
export function updateRecordingSessionData(session: Object) {
export function updateRecordingSessionData(session: any) {
const status = session.getStatus();
const timestamp
= status === JitsiRecordingConstants.status.ON
@ -327,7 +325,7 @@ export function setSelectedRecordingService(selectedRecordingService: string) {
* uid: number
* }}
*/
function _setPendingRecordingNotificationUid(uid: ?number, streamType: string) {
function _setPendingRecordingNotificationUid(uid: string | undefined, streamType: string) {
return {
type: SET_PENDING_RECORDING_NOTIFICATION_UID,
streamType,
@ -341,7 +339,7 @@ function _setPendingRecordingNotificationUid(uid: ?number, streamType: string) {
* @param {boolean} onlySelf - Whether to only record the local streams.
* @returns {Object}
*/
export function startLocalVideoRecording(onlySelf) {
export function startLocalVideoRecording(onlySelf: boolean) {
return {
type: START_LOCAL_RECORDING,
onlySelf

View File

@ -1,7 +1,10 @@
import { openSheet } from '../base/dialog';
import { IStore } from '../app/types';
import { openSheet } from '../base/dialog/actions';
import JitsiMeetJS from '../base/lib-jitsi-meet';
import { NOTIFICATION_TIMEOUT_TYPE, showNotification } from '../notifications';
import { showNotification } from '../notifications/actions';
import { NOTIFICATION_TIMEOUT_TYPE } from '../notifications/constants';
// @ts-ignore
import HighlightDialog from './components/Recording/native/HighlightDialog';
export * from './actions.any';
@ -12,7 +15,7 @@ export * from './actions.any';
* @returns {Function}
*/
export function openHighlightDialog() {
return (dispatch: Function) => {
return (dispatch: IStore['dispatch']) => {
dispatch(openSheet(HighlightDialog));
};
}
@ -26,7 +29,7 @@ export function openHighlightDialog() {
* @returns {showNotification}
*/
export function showRecordingLimitNotification(streamType: string) {
return (dispatch: Function, getState: Function) => {
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
const isLiveStreaming = streamType === JitsiMeetJS.constants.recording.mode.STREAM;
let descriptionKey, titleKey;

View File

@ -1,10 +1,10 @@
// @flow
import React from 'react';
import JitsiMeetJS from '../base/lib-jitsi-meet';
import { NOTIFICATION_TIMEOUT_TYPE, showNotification } from '../notifications';
import { showNotification } from '../notifications/actions';
import { NOTIFICATION_TIMEOUT_TYPE } from '../notifications/constants';
// @ts-ignore
import { RecordingLimitNotificationDescription } from './components';
export * from './actions.any';

View File

@ -1,13 +1,11 @@
// @flow
import { Component } from 'react';
import {
createRecordingDialogEvent,
sendAnalytics
} from '../../../analytics';
import { createRecordingDialogEvent } from '../../../analytics/AnalyticsEvents';
import { sendAnalytics } from '../../../analytics/functions';
import { IReduxState } from '../../../app/types';
import { IJitsiConference } from '../../../base/conference/reducer';
import { JitsiRecordingConstants } from '../../../base/lib-jitsi-meet';
import { setVideoMuted } from '../../../base/media';
import { setVideoMuted } from '../../../base/media/actions';
import { stopLocalVideoRecording } from '../../actions';
import { getActiveSession } from '../../functions';
@ -17,38 +15,38 @@ import LocalRecordingManager from './LocalRecordingManager';
* The type of the React {@code Component} props of
* {@link AbstractStopRecordingDialog}.
*/
export type Props = {
export interface IProps {
/**
* The {@code JitsiConference} for the current conference.
*/
_conference: Object,
_conference: IJitsiConference;
/**
* The redux representation of the recording session to be stopped.
*/
_fileRecordingSession: Object,
_fileRecordingSession: Object;
/**
* Whether the recording is a local recording or not.
*/
_localRecording: boolean,
_localRecording: boolean;
/**
* The redux dispatch function.
*/
dispatch: Function,
dispatch: Function;
/**
* The user trying to stop the video while local recording is running.
*/
localRecordingVideoStop?: boolean,
localRecordingVideoStop?: boolean;
/**
* Invoked to obtain translated strings.
*/
t: Function
};
t: Function;
}
/**
* Abstract React Component for getting confirmation to stop a file recording
@ -56,7 +54,7 @@ export type Props = {
*
* @augments Component
*/
export default class AbstractStopRecordingDialog<P: Props>
export default class AbstractStopRecordingDialog<P extends IProps>
extends Component<P> {
/**
* Initializes a new {@code AbstrStopRecordingDialog} instance.
@ -71,8 +69,6 @@ export default class AbstractStopRecordingDialog<P: Props>
this._toggleScreenshotCapture = this._toggleScreenshotCapture.bind(this);
}
_onSubmit: () => boolean;
/**
* Stops the recording session.
*
@ -90,7 +86,7 @@ export default class AbstractStopRecordingDialog<P: Props>
} else {
const { _fileRecordingSession } = this.props;
if (_fileRecordingSession) {
if (_fileRecordingSession) { // @ts-ignore
this.props._conference.stopRecording(_fileRecordingSession.id);
this._toggleScreenshotCapture();
}
@ -99,8 +95,6 @@ export default class AbstractStopRecordingDialog<P: Props>
return true;
}
_toggleScreenshotCapture: () => void;
/**
* Toggles screenshot capture feature.
*
@ -122,7 +116,7 @@ export default class AbstractStopRecordingDialog<P: Props>
* _fileRecordingSession: Object
* }}
*/
export function _mapStateToProps(state: Object) {
export function _mapStateToProps(state: IReduxState) {
return {
_conference: state['features/base/conference'].conference,
_fileRecordingSession:

View File

@ -3,11 +3,20 @@ import { IStore } from '../../../app/types';
interface ILocalRecordingManager {
addAudioTrackToLocalRecording: (track: any) => void;
isRecordingLocally: () => boolean;
startLocalRecording: (store: IStore) => void;
selfRecording: {
on: boolean;
withVideo: boolean;
};
startLocalRecording: (store: IStore, onlySelf: boolean) => void;
stopLocalRecording: () => void;
}
const LocalRecordingManager: ILocalRecordingManager = {
selfRecording: {
on: false,
withVideo: false
},
/**
* Adds audio track to the recording stream.
*

View File

@ -1,11 +1,14 @@
// @flow
import { IReduxState } from '../app/types';
import { isMobileBrowser } from '../base/environment/utils';
import { isJwtFeatureEnabled } from '../base/jwt/functions';
import { JitsiRecordingConstants, browser } from '../base/lib-jitsi-meet';
import { getLocalParticipant, getRemoteParticipants, isLocalParticipantModerator } from '../base/participants';
import {
getLocalParticipant,
getRemoteParticipants,
isLocalParticipantModerator
} from '../base/participants/functions';
import { isInBreakoutRoom } from '../breakout-rooms/functions';
import { isEnabled as isDropboxEnabled } from '../dropbox';
import { isEnabled as isDropboxEnabled } from '../dropbox/functions';
import { extractFqnFromPath } from '../dynamic-branding/functions.any';
import LocalRecordingManager from './components/Recording/LocalRecordingManager';
@ -20,7 +23,7 @@ import logger from './logger';
* @param {string} mode - Find an active recording session of the given mode.
* @returns {Object|undefined}
*/
export function getActiveSession(state: Object, mode: string) {
export function getActiveSession(state: IReduxState, mode: string) {
const { sessionDatas } = state['features/recording'];
const { status: statusConstants } = JitsiRecordingConstants;
@ -37,7 +40,7 @@ export function getActiveSession(state: Object, mode: string) {
* @param {number} size - The size in MB of the recorded video.
* @returns {number} - The estimated duration in minutes.
*/
export function getRecordingDurationEstimation(size: ?number) {
export function getRecordingDurationEstimation(size?: number | null) {
return Math.floor((size || 0) / 10);
}
@ -49,7 +52,7 @@ export function getRecordingDurationEstimation(size: ?number) {
* @param {string} id - The ID of the recording session to find.
* @returns {Object|undefined}
*/
export function getSessionById(state: Object, id: string) {
export function getSessionById(state: IReduxState, id: string) {
return state['features/recording'].sessionDatas.find(
sessionData => sessionData.id === id);
}
@ -81,7 +84,7 @@ export async function getRecordingLink(url: string, recordingSessionId: string,
* @param {Object} state - The redux state to search in.
* @returns {string}
*/
export function isSavingRecordingOnDropbox(state: Object) {
export function isSavingRecordingOnDropbox(state: IReduxState) {
return isDropboxEnabled(state)
&& state['features/recording'].selectedRecordingService === RECORDING_TYPES.DROPBOX;
}
@ -92,7 +95,7 @@ export function isSavingRecordingOnDropbox(state: Object) {
* @param {Object} state - The redux state to search in.
* @returns {string}
*/
export function isHighlightMeetingMomentDisabled(state: Object) {
export function isHighlightMeetingMomentDisabled(state: IReduxState) {
return state['features/recording'].disableHighlightMeetingMoment;
}
@ -105,7 +108,7 @@ export function isHighlightMeetingMomentDisabled(state: Object) {
* @param {string} mode - The recording mode to get status for.
* @returns {string|undefined}
*/
export function getSessionStatusToShow(state: Object, mode: string): ?string {
export function getSessionStatusToShow(state: IReduxState, mode: string): string | undefined {
const recordingSessions = state['features/recording'].sessionDatas;
let status;
@ -149,7 +152,7 @@ export function supportsLocalRecording() {
* visible: boolean
* }}
*/
export function getRecordButtonProps(state: Object): ?string {
export function getRecordButtonProps(state: IReduxState) {
let visible;
// a button can be disabled/enabled if enableFeaturesBasedOnToken
@ -197,7 +200,7 @@ export function getRecordButtonProps(state: Object): ?string {
* @param {Object | string} recorder - A participant or it's resource.
* @returns {string|undefined}
*/
export function getResourceId(recorder: string | Object) {
export function getResourceId(recorder: string | { getId: Function; }) {
if (recorder) {
return typeof recorder === 'string'
? recorder
@ -211,12 +214,12 @@ export function getResourceId(recorder: string | Object) {
* @param {Object} state - Redux state.
* @returns {boolean} - True if sent, false otherwise.
*/
export async function sendMeetingHighlight(state: Object) {
export async function sendMeetingHighlight(state: IReduxState) {
const { webhookProxyUrl: url } = state['features/base/config'];
const { conference } = state['features/base/conference'];
const { jwt } = state['features/base/jwt'];
const { connection } = state['features/base/connection'];
const jid = connection.getJid();
const jid = connection?.getJid();
const localParticipant = getLocalParticipant(state);
const headers = {
@ -226,10 +229,10 @@ export async function sendMeetingHighlight(state: Object) {
const reqBody = {
meetingFqn: extractFqnFromPath(state),
sessionId: conference.getMeetingUniqueId(),
sessionId: conference?.getMeetingUniqueId(),
submitted: Date.now(),
participantId: localParticipant.jwtId,
participantName: localParticipant.name,
participantId: localParticipant?.jwtId,
participantName: localParticipant?.name,
participantJid: jid
};
@ -259,7 +262,7 @@ export async function sendMeetingHighlight(state: Object) {
* @param {Object} state - Redux state.
* @returns {boolean}
*/
function isRemoteParticipantRecordingLocally(state) {
function isRemoteParticipantRecordingLocally(state: IReduxState) {
const participants = getRemoteParticipants(state);
// eslint-disable-next-line prefer-const

View File

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

View File

@ -1,27 +1,27 @@
/* @flow */
import {
createRecordingEvent,
sendAnalytics
} from '../analytics';
import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../base/app';
import { CONFERENCE_JOIN_IN_PROGRESS, getCurrentConference } from '../base/conference';
import { createRecordingEvent } from '../analytics/AnalyticsEvents';
import { sendAnalytics } from '../analytics/functions';
import { IStore } from '../app/types';
import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../base/app/actionTypes';
import { CONFERENCE_JOIN_IN_PROGRESS } from '../base/conference/actionTypes';
import { getCurrentConference } from '../base/conference/functions';
import JitsiMeetJS, {
JitsiConferenceEvents,
JitsiRecordingConstants
} from '../base/lib-jitsi-meet';
import { MEDIA_TYPE } from '../base/media';
import { getParticipantDisplayName, updateLocalRecordingStatus } from '../base/participants';
import { MiddlewareRegistry, StateListenerRegistry } from '../base/redux';
import { MEDIA_TYPE } from '../base/media/constants';
import { updateLocalRecordingStatus } from '../base/participants/actions';
import { getParticipantDisplayName } from '../base/participants/functions';
import MiddlewareRegistry from '../base/redux/MiddlewareRegistry';
import StateListenerRegistry from '../base/redux/StateListenerRegistry';
import {
playSound,
registerSound,
stopSound,
unregisterSound
} from '../base/sounds';
import { TRACK_ADDED } from '../base/tracks';
import { NOTIFICATION_TIMEOUT_TYPE, showErrorNotification, showNotification } from '../notifications';
} from '../base/sounds/actions';
import { TRACK_ADDED } from '../base/tracks/actionTypes';
import { showErrorNotification, showNotification } from '../notifications/actions';
import { NOTIFICATION_TIMEOUT_TYPE } from '../notifications/constants';
import { RECORDING_SESSION_UPDATED, START_LOCAL_RECORDING, STOP_LOCAL_RECORDING } from './actionTypes';
import {
@ -54,9 +54,6 @@ import {
RECORDING_ON_SOUND_FILE
} from './sounds';
declare var APP: Object;
declare var interfaceConfig: Object;
/**
* StateListenerRegistry provides a reliable way to detect the leaving of a
* conference, where we need to clean up the recording sessions.
@ -119,7 +116,7 @@ MiddlewareRegistry.register(({ dispatch, getState }) => next => async action =>
conference.on(
JitsiConferenceEvents.RECORDER_STATE_CHANGED,
recorderSession => {
(recorderSession: any) => {
if (recorderSession) {
recorderSession.getID() && dispatch(updateRecordingSessionData(recorderSession));
recorderSession.getError() && _showRecordingErrorNotification(recorderSession, dispatch);
@ -156,7 +153,7 @@ MiddlewareRegistry.register(({ dispatch, getState }) => next => async action =>
if (typeof APP !== 'undefined') {
APP.API.notifyRecordingStatusChanged(true, 'local');
}
} catch (err) {
} catch (err: any) {
logger.error('Capture failed', err);
let descriptionKey = 'recording.error';
@ -213,16 +210,16 @@ MiddlewareRegistry.register(({ dispatch, getState }) => next => async action =>
const updatedSessionData
= getSessionById(getState(), action.sessionData.id);
const { initiator, mode, terminator } = updatedSessionData;
const { initiator, mode = '', terminator } = updatedSessionData ?? {};
const { PENDING, OFF, ON } = JitsiRecordingConstants.status;
if (updatedSessionData.status === PENDING
if (updatedSessionData?.status === PENDING
&& (!oldSessionData || oldSessionData.status !== PENDING)) {
dispatch(showPendingRecordingNotification(mode));
} else if (updatedSessionData.status !== PENDING) {
} else if (updatedSessionData?.status !== PENDING) {
dispatch(hidePendingRecordingNotification(mode));
if (updatedSessionData.status === ON) {
if (updatedSessionData?.status === ON) {
// We receive 2 updates of the session status ON. The first one is from jibri when it joins.
// The second one is from jicofo which will deliever the initiator value. Since the start
@ -256,7 +253,7 @@ MiddlewareRegistry.register(({ dispatch, getState }) => next => async action =>
APP.API.notifyRecordingStatusChanged(true, mode);
}
}
} else if (updatedSessionData.status === OFF
} else if (updatedSessionData?.status === OFF
&& (!oldSessionData || oldSessionData.status !== OFF)) {
if (terminator) {
dispatch(
@ -266,7 +263,7 @@ MiddlewareRegistry.register(({ dispatch, getState }) => next => async action =>
let duration = 0, soundOff, soundOn;
if (oldSessionData && oldSessionData.timestamp) {
if (oldSessionData?.timestamp) {
duration
= (Date.now() / 1000) - oldSessionData.timestamp;
}
@ -319,7 +316,7 @@ MiddlewareRegistry.register(({ dispatch, getState }) => next => async action =>
* @param {Dispatch} dispatch - The Redux Dispatch function.
* @returns {void}
*/
function _showRecordingErrorNotification(recorderSession, dispatch) {
function _showRecordingErrorNotification(recorderSession: any, dispatch: IStore['dispatch']) {
const mode = recorderSession.getMode();
const error = recorderSession.getError();
const isStreamMode = mode === JitsiMeetJS.constants.recording.mode.STREAM;

View File

@ -19,18 +19,18 @@ const DEFAULT_STATE = {
interface ISessionData {
error?: Error;
id?: string;
initiator?: Object;
initiator?: { getId: Function; };
liveStreamViewURL?: string;
mode?: string;
status?: string;
terminator?: Object;
terminator?: { getId: Function; };
timestamp?: number;
}
export interface IRecordingState {
disableHighlightMeetingMoment: boolean;
pendingNotificationUids: {
[key: string]: number | undefined;
[key: string]: string | undefined;
};
selectedRecordingService: string;
sessionDatas: Array<ISessionData>;

View File

@ -3,7 +3,7 @@
import React from 'react';
import { IconCalendar, IconGear, IconRestore } from '../base/icons/svg';
import BaseTheme from '../base/ui/components/BaseTheme.native';
import BaseTheme from '../base/ui/components/BaseTheme';
// @ts-ignore
import TabIcon from './components/TabIcon';

View File

@ -217,6 +217,7 @@ function getConfig(options = {}) {
extensions: [
'.web.js',
'.web.ts',
'.web.tsx',
// Typescript:
'.tsx',