ref(TS Convert some files to TS (#12191)

This commit is contained in:
Robert Pintilii 2022-09-19 10:40:03 +03:00 committed by GitHub
parent ffe005ba0a
commit 6dd04136de
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 134 additions and 110 deletions

View File

@ -1,5 +1,6 @@
module.exports = {
'extends': [
'@jitsi/eslint-config'
]
],
'ignorePatterns': [ '*.d.ts' ]
};

6
globals.d.ts vendored Normal file
View File

@ -0,0 +1,6 @@
export {};
declare global {
const APP: any;
const interfaceConfig: any;
}

View File

@ -1,25 +1,24 @@
// @flow
import { sha512_256 as sha512 } from 'js-sha512';
import _ from 'lodash';
// @ts-ignore
import { getName } from '../../app/functions';
import { IState, IStore } from '../../app/types';
import { determineTranscriptionLanguage } from '../../transcribing/functions';
import { IStateful } from '../app/types';
import { JitsiTrackErrors } from '../lib-jitsi-meet';
import {
getLocalParticipant,
hiddenParticipantJoined,
hiddenParticipantLeft,
participantJoined,
participantLeft
} from '../participants';
import { toState } from '../redux';
import {
getBackendSafePath,
getJitsiMeetGlobalNS,
safeDecodeURIComponent
} from '../util';
} from '../participants/actions';
import { getLocalParticipant } from '../participants/functions';
import { toState } from '../redux/functions';
import { getJitsiMeetGlobalNS } from '../util/helpers';
import { getBackendSafePath, safeDecodeURIComponent } from '../util/uri';
// @ts-ignore
import { setObfuscatedRoom } from './actions';
import {
AVATAR_URL_COMMAND,
@ -27,22 +26,23 @@ import {
JITSI_CONFERENCE_URL_KEY
} from './constants';
import logger from './logger';
import { IJitsiConference } from './reducer';
/**
* Returns root conference state.
*
* @param {Object} state - Global state.
* @param {IState} state - Global state.
* @returns {Object} Conference state.
*/
export const getConferenceState = (state: Object) => state['features/base/conference'];
export const getConferenceState = (state: IState) => state['features/base/conference'];
/**
* Is the conference joined or not.
*
* @param {Object} state - Global state.
* @param {IState} state - Global state.
* @returns {boolean}
*/
export const getIsConferenceJoined = (state: Object) => Boolean(getConferenceState(state).conference);
export const getIsConferenceJoined = (state: IState) => Boolean(getConferenceState(state).conference);
/**
* Attach a set of local tracks to a conference.
@ -53,7 +53,7 @@ export const getIsConferenceJoined = (state: Object) => Boolean(getConferenceSta
* @returns {Promise}
*/
export function _addLocalTracksToConference(
conference: { addTrack: Function, getLocalTracks: Function },
conference: IJitsiConference,
localTracks: Array<Object>) {
const conferenceLocalTracks = conference.getLocalTracks();
const promises = [];
@ -63,7 +63,7 @@ export function _addLocalTracksToConference(
// adding one and the same video track multiple times.
if (conferenceLocalTracks.indexOf(track) === -1) {
promises.push(
conference.addTrack(track).catch(err => {
conference.addTrack(track).catch((err: Error) => {
_reportError(
'Failed to add local track to conference',
err);
@ -86,16 +86,16 @@ export function _addLocalTracksToConference(
* @returns {void}
*/
export function commonUserJoinedHandling(
{ dispatch }: Object,
conference: Object,
user: Object) {
{ dispatch }: IStore,
conference: IJitsiConference,
user: any) {
const id = user.getId();
const displayName = user.getDisplayName();
if (user.isHidden()) {
dispatch(hiddenParticipantJoined(id, displayName));
} else {
const isReplacing = user.isReplacing && user.isReplacing();
const isReplacing = user?.isReplacing();
dispatch(participantJoined({
botType: user.getBotType(),
@ -122,15 +122,15 @@ export function commonUserJoinedHandling(
* @returns {void}
*/
export function commonUserLeftHandling(
{ dispatch }: Object,
conference: Object,
user: Object) {
{ dispatch }: IStore,
conference: IJitsiConference,
user: any) {
const id = user.getId();
if (user.isHidden()) {
dispatch(hiddenParticipantLeft(id));
} else {
const isReplaced = user.isReplaced && user.isReplaced();
const isReplaced = user.isReplaced?.();
dispatch(participantLeft(id, conference, { isReplaced }));
}
@ -140,7 +140,7 @@ export function commonUserLeftHandling(
* Evaluates a specific predicate for each {@link JitsiConference} known to the
* redux state features/base/conference while it returns {@code true}.
*
* @param {Function | Object} stateful - The redux store, state, or
* @param {IStateful} stateful - The redux store, state, or
* {@code getState} function.
* @param {Function} predicate - The predicate to evaluate for each
* {@code JitsiConference} know to the redux state features/base/conference
@ -150,8 +150,8 @@ export function commonUserLeftHandling(
* features/base/conference.
*/
export function forEachConference(
stateful: Function | Object,
predicate: (Object, URL) => boolean) {
stateful: IStateful,
predicate: (a: any, b: URL) => boolean) {
const state = getConferenceState(toState(stateful));
for (const v of Object.values(state)) {
@ -178,48 +178,48 @@ export function forEachConference(
/**
* Returns the display name of the conference.
*
* @param {Function | Object} stateful - Reference that can be resolved to Redux
* @param {IStateful} stateful - Reference that can be resolved to Redux
* state with the {@code toState} function.
* @returns {string}
*/
export function getConferenceName(stateful: Function | Object): string {
export function getConferenceName(stateful: IStateful): string {
const state = toState(stateful);
const { callee } = state['features/base/jwt'];
const { callDisplayName } = state['features/base/config'];
const { localSubject, room, subject } = getConferenceState(state);
return localSubject
return (localSubject
|| subject
|| callDisplayName
|| (callee && callee.name)
|| (room && safeStartCase(safeDecodeURIComponent(room)));
|| callee?.name
|| (room && safeStartCase(safeDecodeURIComponent(room)))) ?? '';
}
/**
* Returns the name of the conference formatted for the title.
*
* @param {Function | Object} stateful - Reference that can be resolved to Redux state with the {@code toState}
* @param {IStateful} stateful - Reference that can be resolved to Redux state with the {@code toState}
* function.
* @returns {string} - The name of the conference formatted for the title.
*/
export function getConferenceNameForTitle(stateful: Function | Object) {
return safeStartCase(safeDecodeURIComponent(getConferenceState(toState(stateful)).room));
export function getConferenceNameForTitle(stateful: IStateful) {
return safeStartCase(safeDecodeURIComponent(getConferenceState(toState(stateful)).room ?? ''));
}
/**
* Returns an object aggregating the conference options.
*
* @param {Object|Function} stateful - The redux store state.
* @param {IStateful} stateful - The redux store state.
* @returns {Object} - Options object.
*/
export function getConferenceOptions(stateful: Function | Object) {
export function getConferenceOptions(stateful: IStateful) {
const state = toState(stateful);
const config = state['features/base/config'];
const { locationURL } = state['features/base/connection'];
const { tenant } = state['features/base/jwt'];
const { email, name: nick } = getLocalParticipant(state);
const options = { ...config };
const { email, name: nick } = getLocalParticipant(state) ?? {};
const options: any = { ...config };
if (tenant) {
options.siteID = tenant;
@ -257,11 +257,11 @@ export function getConferenceOptions(stateful: Function | Object) {
/**
* Returns the UTC timestamp when the first participant joined the conference.
*
* @param {Function | Object} stateful - Reference that can be resolved to Redux
* @param {IStateful} stateful - Reference that can be resolved to Redux
* state with the {@code toState} function.
* @returns {number}
*/
export function getConferenceTimestamp(stateful: Function | Object): number {
export function getConferenceTimestamp(stateful: IStateful) {
const state = toState(stateful);
const { conferenceTimestamp } = getConferenceState(state);
@ -274,11 +274,11 @@ export function getConferenceTimestamp(stateful: Function | Object): number {
* {@code conference} state of the feature base/conference which is not joining
* but may be leaving already.
*
* @param {Function|Object} stateful - The redux store, state, or
* @param {IStateful} stateful - The redux store, state, or
* {@code getState} function.
* @returns {JitsiConference|undefined}
*/
export function getCurrentConference(stateful: Function | Object) {
export function getCurrentConference(stateful: IStateful): any {
const { conference, joining, leaving, membersOnly, passwordRequired }
= getConferenceState(toState(stateful));
@ -293,25 +293,29 @@ export function getCurrentConference(stateful: Function | Object) {
/**
* Returns the stored room name.
*
* @param {Object} state - The current state of the app.
* @param {IState} state - The current state of the app.
* @returns {string}
*/
export function getRoomName(state: Object): string {
export function getRoomName(state: IState) {
return getConferenceState(state).room;
}
/**
* Get an obfuscated room name or create and persist it if it doesn't exists.
*
* @param {Object} state - The current state of the app.
* @param {IState} state - The current state of the app.
* @param {Function} dispatch - The Redux dispatch function.
* @returns {string} - Obfuscated room name.
*/
export function getOrCreateObfuscatedRoomName(state: Object, dispatch: Function) {
export function getOrCreateObfuscatedRoomName(state: IState, dispatch: IStore['dispatch']) {
let { obfuscatedRoom } = getConferenceState(state);
const { obfuscatedRoomSource } = getConferenceState(state);
const room = getRoomName(state);
if (!room) {
return;
}
// On native mobile the store doesn't clear when joining a new conference so we might have the obfuscatedRoom
// stored even though a different room was joined.
// Check if the obfuscatedRoom was already computed for the current room.
@ -327,11 +331,11 @@ export function getOrCreateObfuscatedRoomName(state: Object, dispatch: Function)
* Analytics may require an obfuscated room name, this functions decides based on a config if the normal or
* obfuscated room name should be returned.
*
* @param {Object} state - The current state of the app.
* @param {IState} state - The current state of the app.
* @param {Function} dispatch - The Redux dispatch function.
* @returns {string} - Analytics room name.
*/
export function getAnalyticsRoomName(state: Object, dispatch: Function) {
export function getAnalyticsRoomName(state: IState, dispatch: IStore['dispatch']) {
const { analysis: { obfuscateRoomName = false } = {} } = state['features/base/config'];
if (obfuscateRoomName) {
@ -365,7 +369,7 @@ function getWiFiStatsMethod() {
* @protected
* @returns {void}
*/
export function _handleParticipantError(err: { message: ?string }) {
export function _handleParticipantError(err: Error) {
// XXX DataChannels are initialized at some later point when the conference
// has multiple participants, but code that pins or selects a participant
// might be executed before. So here we're swallowing a particular error.
@ -384,7 +388,7 @@ export function _handleParticipantError(err: { message: ?string }) {
* @returns {boolean} If the specified room name is valid, then true; otherwise,
* false.
*/
export function isRoomValid(room: ?string) {
export function isRoomValid(room?: string) {
return typeof room === 'string' && room !== '';
}
@ -397,11 +401,11 @@ export function isRoomValid(room: ?string) {
* @returns {Promise}
*/
export function _removeLocalTracksFromConference(
conference: { removeTrack: Function },
conference: IJitsiConference,
localTracks: Array<Object>) {
return Promise.all(localTracks.map(track =>
conference.removeTrack(track)
.catch(err => {
.catch((err: Error) => {
// Local track might be already disposed by direct
// JitsiTrack#dispose() call. So we should ignore this error
// here.
@ -425,7 +429,7 @@ export function _removeLocalTracksFromConference(
* @private
* @returns {void}
*/
function _reportError(msg, err) {
function _reportError(msg: string, err: Error) {
// TODO This is a good point to call some global error handler when we have
// one.
logger.error(msg, err);
@ -443,17 +447,14 @@ function _reportError(msg, err) {
* @returns {void}
*/
export function sendLocalParticipant(
stateful: Function | Object,
conference: {
sendCommand: Function,
setDisplayName: Function,
setLocalParticipantProperty: Function }) {
stateful: IStateful,
conference: IJitsiConference) {
const {
avatarURL,
email,
features,
name
} = getLocalParticipant(stateful);
} = getLocalParticipant(stateful) ?? {};
avatarURL && conference.sendCommand(AVATAR_URL_COMMAND, {
value: avatarURL

View File

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

View File

@ -40,11 +40,26 @@ const DEFAULT_STATE = {
passwordRequired: undefined
};
export interface IJitsiConference {
addTrack: Function;
getBreakoutRooms: Function;
getLocalTracks: Function;
isAVModerationSupported: Function;
isEndConferenceSupported: Function;
isLobbySupported: Function;
removeTrack: Function;
sendCommand: Function;
sendEndpointMessage: Function;
sessionId: string;
setDisplayName: Function;
setLocalParticipantProperty: Function;
}
export interface IConferenceState {
authEnabled?: boolean;
authLogin?: string;
authRequired?: Object;
conference?: any;
conference?: IJitsiConference;
conferenceTimestamp?: number;
e2eeSupported?: boolean;
error?: Error;

View File

@ -125,6 +125,7 @@ export interface IConfig {
key: ButtonsWithNotifyClick;
preventExecution: boolean;
}>;
callDisplayName?: string;
callStatsConfigParams?: {
additionalIDs?: {
customerID?: string;

View File

@ -71,7 +71,11 @@ const CONFERENCE_HEADER_MAPPING: any = {
};
export interface IConfigState extends IConfig {
analysis?: {
obfuscateRoomName?: boolean;
};
error?: Error;
firefox_fake_device?: string;
}
ReducerRegistry.register<IConfigState>('features/base/config', (state = _getInitialState(), action): IConfigState => {

View File

@ -4,9 +4,13 @@ import { equals } from '../redux/functions';
import { SET_JWT } from './actionTypes';
export interface IJwtState {
callee?: {
name: string;
};
group?: string;
jwt?: string;
server?: string;
tenant?: string;
}
/**

View File

@ -1,10 +1,8 @@
/* @flow */
import type { Dispatch } from 'redux';
import { Dispatch } from 'redux';
import { showModeratedNotification } from '../../av-moderation/actions';
import { shouldShowModeratedNotification } from '../../av-moderation/functions';
import { isModerationNotificationDisplayed } from '../../notifications';
import { isModerationNotificationDisplayed } from '../../notifications/functions';
import {
SET_AUDIO_MUTED,
@ -55,7 +53,7 @@ export function setAudioAvailable(available: boolean) {
* muted: boolean
* }}
*/
export function setAudioMuted(muted: boolean, ensureTrack: boolean = false) {
export function setAudioMuted(muted: boolean, ensureTrack = false) {
return {
type: SET_AUDIO_MUTED,
ensureTrack,
@ -70,7 +68,7 @@ export function setAudioMuted(muted: boolean, ensureTrack: boolean = false) {
* @param {boolean|undefined} skipNotification - True if we want to skip showing the notification.
* @returns {Function}
*/
export function setAudioUnmutePermissions(blocked: boolean, skipNotification: boolean = false) {
export function setAudioUnmutePermissions(blocked: boolean, skipNotification = false) {
return {
type: SET_AUDIO_UNMUTE_PERMISSIONS,
blocked,
@ -107,7 +105,7 @@ export function setScreenshareMuted(
muted: boolean,
mediaType: MediaType = MEDIA_TYPE.SCREENSHARE,
authority: number = SCREENSHARE_MUTISM_AUTHORITY.USER,
ensureTrack: boolean = false) {
ensureTrack = false) {
return (dispatch: Dispatch<any>, getState: Function) => {
const state = getState();
@ -168,7 +166,7 @@ export function setVideoMuted(
muted: boolean,
mediaType: string = MEDIA_TYPE.VIDEO,
authority: number = VIDEO_MUTISM_AUTHORITY.USER,
ensureTrack: boolean = false) {
ensureTrack = false) {
return (dispatch: Dispatch<any>, getState: Function) => {
const state = getState();
@ -203,7 +201,7 @@ export function setVideoMuted(
* @param {boolean|undefined} skipNotification - True if we want to skip showing the notification.
* @returns {Function}
*/
export function setVideoUnmutePermissions(blocked: boolean, skipNotification: boolean = false) {
export function setVideoUnmutePermissions(blocked: boolean, skipNotification = false) {
return {
type: SET_VIDEO_UNMUTE_PERMISSIONS,
blocked,

View File

@ -8,7 +8,7 @@ export interface Participant {
e2eeSupported?: boolean;
email?: string;
features?: {
'screen-sharing'?: boolean;
'screen-sharing'?: boolean | string;
};
getId?: Function;
id: string;

View File

@ -1,8 +1,9 @@
// @flow
import { getMultipleVideoSupportFeatureFlag } from '../config';
import { MEDIA_TYPE, VIDEO_TYPE } from '../media';
import { getParticipantById } from '../participants';
import { IState, IStore } from '../../app/types';
import { getMultipleVideoSupportFeatureFlag } from '../config/functions.any';
import { MEDIA_TYPE, VIDEO_TYPE } from '../media/constants';
import { getParticipantById } from '../participants/functions';
// eslint-disable-next-line lines-around-comment
// @ts-ignore
import { getTrackByMediaTypeAndParticipant, getVirtualScreenshareParticipantTrack } from '../tracks';
/**
@ -10,23 +11,23 @@ import { getTrackByMediaTypeAndParticipant, getVirtualScreenshareParticipantTrac
* {@link TestHint} and other components from the testing package will be
* rendered in various places across the app to help with automatic testing.
*
* @param {Object} state - The redux store state.
* @param {IState} state - The redux store state.
* @returns {boolean}
*/
export function isTestModeEnabled(state: Object): boolean {
export function isTestModeEnabled(state: IState): boolean {
const testingConfig = state['features/base/config'].testing;
return Boolean(testingConfig && testingConfig.testMode);
return Boolean(testingConfig?.testMode);
}
/**
* Returns the video type of the remote participant's video.
*
* @param {Store} store - The redux store.
* @param {IStore} store - The redux store.
* @param {string} id - The participant ID for the remote video.
* @returns {VIDEO_TYPE}
*/
export function getRemoteVideoType({ getState }: Object, id: String): VIDEO_TYPE {
export function getRemoteVideoType({ getState }: IStore, id: string) {
const state = getState();
const participant = getParticipantById(state, id);
@ -40,13 +41,13 @@ export function getRemoteVideoType({ getState }: Object, id: String): VIDEO_TYPE
/**
* Returns whether the last media event received for large video indicates that the video is playing, if not muted.
*
* @param {Store} store - The redux store.
* @param {IStore} store - The redux store.
* @returns {boolean}
*/
export function isLargeVideoReceived({ getState }: Object): boolean {
export function isLargeVideoReceived({ getState }: IStore): boolean {
const state = getState();
const largeVideoParticipantId = state['features/large-video'].participantId;
const largeVideoParticipant = getParticipantById(state, largeVideoParticipantId);
const largeVideoParticipant = getParticipantById(state, largeVideoParticipantId ?? '');
const tracks = state['features/base/tracks'];
let videoTrack;
@ -64,11 +65,11 @@ export function isLargeVideoReceived({ getState }: Object): boolean {
/**
* Returns whether the last media event received for a remote video indicates that the video is playing, if not muted.
*
* @param {Store} store - The redux store.
* @param {IStore} store - The redux store.
* @param {string} id - The participant ID for the remote video.
* @returns {boolean}
*/
export function isRemoteVideoReceived({ getState }: Object, id: String): boolean {
export function isRemoteVideoReceived({ getState }: IStore, id: string): boolean {
const state = getState();
const tracks = state['features/base/tracks'];
const participant = getParticipantById(state, id);

View File

@ -111,7 +111,7 @@ export async function sendFaceExpressionsWebhook(state: IState) {
const reqBody = {
meetingFqn: extractFqnFromPath(),
sessionId: conference.sessionId,
sessionId: conference?.sessionId,
submitted: Date.now(),
emotions: faceExpressionsBuffer,
participantId: localParticipant?.jwtId,

View File

@ -1,19 +1,16 @@
// @flow
import { MODERATION_NOTIFICATIONS } from '../av-moderation/constants';
import { MEDIA_TYPE } from '../base/media';
import { toState } from '../base/redux';
declare var interfaceConfig: Object;
import { IStateful } from '../base/app/types';
import { MediaType } from '../base/media/constants';
import { toState } from '../base/redux/functions';
/**
* Tells whether or not the notifications are enabled and if there are any
* notifications to be displayed based on the current Redux state.
*
* @param {Object|Function} stateful - The redux store state.
* @param {IStateful} stateful - The redux store state.
* @returns {boolean}
*/
export function areThereNotifications(stateful: Object | Function) {
export function areThereNotifications(stateful: IStateful) {
const state = toState(stateful);
const { enabled, notifications } = state['features/notifications'];
@ -33,10 +30,10 @@ export function joinLeaveNotificationsDisabled() {
* Returns whether or not the moderation notification for the given type is displayed.
*
* @param {MEDIA_TYPE} mediaType - The media type to check.
* @param {Object | Function} stateful - The redux store state.
* @param {IStateful} stateful - The redux store state.
* @returns {boolean}
*/
export function isModerationNotificationDisplayed(mediaType: MEDIA_TYPE, stateful: Object | Function) {
export function isModerationNotificationDisplayed(mediaType: MediaType, stateful: IStateful) {
const state = toState(stateful);
const { notifications } = state['features/notifications'];

View File

@ -65,7 +65,7 @@ const Prejoin: React.FC<PrejoinProps> = ({ navigation }: PrejoinProps) => {
);
const localParticipant = useSelector((state: IState) => getLocalParticipant(state));
const isDisplayNameMandatory = useSelector(state => isDisplayNameRequired(state));
const roomName = useSelector(state => getConferenceName(state));
const roomName = useSelector((state: IState) => getConferenceName(state));
const participantName = localParticipant?.name;
const [ displayName, setDisplayName ]
= useState(participantName || '');

View File

@ -69,7 +69,7 @@ export async function sendReactionsWebhook(state: IState, reactions: Array<strin
const reqBody = {
meetingFqn: extractFqnFromPath(),
sessionId: conference.sessionId,
sessionId: conference?.sessionId,
submitted: Date.now(),
reactions,
participantId: localParticipant?.jwtId,

View File

@ -1,7 +1,7 @@
// @flow
import i18next from 'i18next';
import { IConfig } from '../base/config/configType';
import JITSI_TO_BCP47_MAP from './jitsi-bcp47-map.json';
import logger from './logger';
import TRANSCRIBER_LANGS from './transcriber-langs.json';
@ -14,7 +14,7 @@ const DEFAULT_TRANSCRIBER_LANG = 'en-US';
* @param {*} config - Application config.
* @returns {string}
*/
export function determineTranscriptionLanguage(config: Object) {
export function determineTranscriptionLanguage(config: IConfig) {
const { transcription } = config;
// if transcriptions are not enabled nothing to determine
@ -27,11 +27,11 @@ export function determineTranscriptionLanguage(config: Object) {
// Jitsi language detections uses custom language tags, but the transcriber expects BCP-47 compliant tags,
// we use a mapping file to convert them.
const bcp47Locale = transcription?.useAppLanguage ?? true
? JITSI_TO_BCP47_MAP[i18next.language]
? JITSI_TO_BCP47_MAP[i18next.language as keyof typeof JITSI_TO_BCP47_MAP]
: transcription?.preferredLanguage;
// Check if the obtained language is supported by the transcriber
let safeBCP47Locale = TRANSCRIBER_LANGS[bcp47Locale] && bcp47Locale;
let safeBCP47Locale = TRANSCRIBER_LANGS[bcp47Locale as keyof typeof TRANSCRIBER_LANGS] && bcp47Locale;
if (!safeBCP47Locale) {
safeBCP47Locale = DEFAULT_TRANSCRIBER_LANG;

View File

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

View File

@ -1,5 +1,5 @@
{
"include": ["react/features/**/*.ts", "react/features/**/*.tsx", "./custom.d.ts"],
"include": ["react/features/**/*.ts", "react/features/**/*.tsx", "./custom.d.ts", "./globals.d.ts"],
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"module": "es6",