ref(TS) Convert some features to TS (#12546)
This commit is contained in:
parent
a884a6b232
commit
7a9f51b01b
|
@ -27,6 +27,7 @@ interface IWindow {
|
|||
clearTimeout: typeof clearTimeout;
|
||||
setImmediate: typeof setImmediate;
|
||||
clearImmediate: typeof clearImmediate;
|
||||
addEventListener: Function;
|
||||
}
|
||||
|
||||
interface INavigator {
|
||||
|
|
|
@ -58,6 +58,7 @@ export interface IJitsiConference {
|
|||
isCallstatsEnabled: Function;
|
||||
isEndConferenceSupported: Function;
|
||||
isLobbySupported: Function;
|
||||
isSIPCallingSupported: Function;
|
||||
isStartAudioMuted: Function;
|
||||
isStartVideoMuted: Function;
|
||||
join: Function;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
@ -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
|
|
@ -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);
|
|
@ -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));
|
||||
|
|
@ -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)));
|
|
@ -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;
|
|
@ -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
|
|
@ -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;
|
||||
|
|
@ -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';
|
|
@ -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:
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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
|
|
@ -1,5 +1,3 @@
|
|||
// @flow
|
||||
|
||||
import { getLogger } from '../base/logging/functions';
|
||||
|
||||
export default getLogger('features/recording');
|
|
@ -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;
|
|
@ -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>;
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -217,6 +217,7 @@ function getConfig(options = {}) {
|
|||
extensions: [
|
||||
'.web.js',
|
||||
'.web.ts',
|
||||
'.web.tsx',
|
||||
|
||||
// Typescript:
|
||||
'.tsx',
|
||||
|
|
Loading…
Reference in New Issue