mirror of
https://gitcode.com/GitHub_Trending/ji/jitsi-meet.git
synced 2025-12-30 03:12:29 +00:00
ref(TS) Convert some files to TS (#13223)
This commit is contained in:
@@ -197,6 +197,8 @@
|
||||
"lint-fix": "eslint --ext .js,.ts,.tsx --max-warnings 0 --fix .",
|
||||
"postinstall": "patch-package --error-on-fail && jetify",
|
||||
"validate": "npm ls",
|
||||
"tsc-test:web": "tsc --project tsconfig.web.json --listFilesOnly | grep -v node_modules | grep native",
|
||||
"tsc-test:native": "tsc --project tsconfig.native.json --listFilesOnly | grep -v node_modules | grep web",
|
||||
"start": "make dev"
|
||||
},
|
||||
"resolutions": {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// @flow
|
||||
import { AnyAction } from 'redux';
|
||||
|
||||
import { readyToClose } from '../../../features/mobile/external-api/actions';
|
||||
import {
|
||||
ACTION_PINNED,
|
||||
ACTION_UNPINNED,
|
||||
@@ -9,8 +8,10 @@ import {
|
||||
} from '../../analytics/AnalyticsEvents';
|
||||
import { sendAnalytics } from '../../analytics/functions';
|
||||
import { reloadNow } from '../../app/actions';
|
||||
import { IReduxState, IStore } from '../../app/types';
|
||||
import { removeLobbyChatParticipant } from '../../chat/actions.any';
|
||||
import { openDisplayNamePrompt } from '../../display-name/actions';
|
||||
import { readyToClose } from '../../mobile/external-api/actions';
|
||||
import { showErrorNotification, showWarningNotification } from '../../notifications/actions';
|
||||
import { NOTIFICATION_TIMEOUT_TYPE } from '../../notifications/constants';
|
||||
import { setIAmVisitor } from '../../visitors/actions';
|
||||
@@ -62,12 +63,10 @@ import {
|
||||
} from './functions';
|
||||
import logger from './logger';
|
||||
|
||||
declare var APP: Object;
|
||||
|
||||
/**
|
||||
* Handler for before unload event.
|
||||
*/
|
||||
let beforeUnloadHandler;
|
||||
let beforeUnloadHandler: Function | undefined;
|
||||
|
||||
/**
|
||||
* Implements the middleware of the feature base/conference.
|
||||
@@ -129,7 +128,7 @@ MiddlewareRegistry.register(store => next => action => {
|
||||
* @private
|
||||
* @returns {Object} The value returned by {@code next(action)}.
|
||||
*/
|
||||
function _conferenceFailed({ dispatch, getState }, next, action) {
|
||||
function _conferenceFailed({ dispatch, getState }: IStore, next: Function, action: AnyAction) {
|
||||
const { conference, error } = action;
|
||||
|
||||
if (error.name === JitsiConferenceErrors.REDIRECTED) {
|
||||
@@ -191,7 +190,7 @@ function _conferenceFailed({ dispatch, getState }, next, action) {
|
||||
const newConfig = restoreConferenceOptions(getState);
|
||||
|
||||
if (newConfig) {
|
||||
dispatch(overwriteConfig(newConfig))
|
||||
dispatch(overwriteConfig(newConfig)) // @ts-ignore
|
||||
.then(dispatch(conferenceWillLeave(conference)))
|
||||
.then(conference.leave())
|
||||
.then(dispatch(disconnect()))
|
||||
@@ -217,7 +216,7 @@ function _conferenceFailed({ dispatch, getState }, next, action) {
|
||||
|
||||
const [ vnode ] = error.params;
|
||||
|
||||
dispatch(overwriteConfig(newConfig))
|
||||
dispatch(overwriteConfig(newConfig)) // @ts-ignore
|
||||
.then(dispatch(conferenceWillLeave(conference)))
|
||||
.then(conference.leave())
|
||||
.then(dispatch(disconnect()))
|
||||
@@ -234,7 +233,7 @@ function _conferenceFailed({ dispatch, getState }, next, action) {
|
||||
if (typeof APP === 'undefined') {
|
||||
!error.recoverable
|
||||
&& conference
|
||||
&& conference.leave(CONFERENCE_LEAVE_REASONS.UNRECOVERABLE_ERROR).catch(reason => {
|
||||
&& conference.leave(CONFERENCE_LEAVE_REASONS.UNRECOVERABLE_ERROR).catch((reason: Error) => {
|
||||
// Even though we don't care too much about the failure, it may be
|
||||
// good to know that it happen, so log it (on the info level).
|
||||
logger.info('JitsiConference.leave() rejected with:', reason);
|
||||
@@ -267,7 +266,7 @@ function _conferenceFailed({ dispatch, getState }, next, action) {
|
||||
* @private
|
||||
* @returns {Object} The value returned by {@code next(action)}.
|
||||
*/
|
||||
function _conferenceJoined({ dispatch, getState }, next, action) {
|
||||
function _conferenceJoined({ dispatch, getState }: IStore, next: Function, action: AnyAction) {
|
||||
const result = next(action);
|
||||
const { conference } = action;
|
||||
const { pendingSubjectChange } = getState()['features/base/conference'];
|
||||
@@ -288,6 +287,8 @@ function _conferenceJoined({ dispatch, getState }, next, action) {
|
||||
beforeUnloadHandler = () => {
|
||||
dispatch(conferenceWillLeave(conference));
|
||||
};
|
||||
|
||||
// @ts-ignore
|
||||
window.addEventListener(disableBeforeUnloadHandlers ? 'unload' : 'beforeunload', beforeUnloadHandler);
|
||||
|
||||
if (requireDisplayName
|
||||
@@ -313,7 +314,7 @@ function _conferenceJoined({ dispatch, getState }, next, action) {
|
||||
* @private
|
||||
* @returns {Object} The value returned by {@code next(action)}.
|
||||
*/
|
||||
function _connectionEstablished({ dispatch }, next, action) {
|
||||
function _connectionEstablished({ dispatch }: IStore, next: Function, action: AnyAction) {
|
||||
const result = next(action);
|
||||
|
||||
// FIXME: Workaround for the web version. Currently, the creation of the
|
||||
@@ -330,7 +331,7 @@ function _connectionEstablished({ dispatch }, next, action) {
|
||||
* @param {Object} state - The redux state.
|
||||
* @returns {void}
|
||||
*/
|
||||
function _logJwtErrors(message, state) {
|
||||
function _logJwtErrors(message: string, state: IReduxState) {
|
||||
const { jwt } = state['features/base/jwt'];
|
||||
|
||||
if (!jwt) {
|
||||
@@ -357,7 +358,7 @@ function _logJwtErrors(message, state) {
|
||||
* @private
|
||||
* @returns {Object} The value returned by {@code next(action)}.
|
||||
*/
|
||||
function _connectionFailed({ dispatch, getState }, next, action) {
|
||||
function _connectionFailed({ dispatch, getState }: IStore, next: Function, action: AnyAction) {
|
||||
_logJwtErrors(action.error.message, getState());
|
||||
|
||||
const result = next(action);
|
||||
@@ -417,7 +418,7 @@ function _connectionFailed({ dispatch, getState }, next, action) {
|
||||
* @private
|
||||
* @returns {Object} The value returned by {@code next(action)}.
|
||||
*/
|
||||
function _conferenceSubjectChanged({ dispatch, getState }, next, action) {
|
||||
function _conferenceSubjectChanged({ dispatch, getState }: IStore, next: Function, action: AnyAction) {
|
||||
const result = next(action);
|
||||
const { subject } = getState()['features/base/conference'];
|
||||
|
||||
@@ -442,7 +443,7 @@ function _conferenceSubjectChanged({ dispatch, getState }, next, action) {
|
||||
* @param {Object} store - The redux store.
|
||||
* @returns {void}
|
||||
*/
|
||||
function _conferenceWillLeave({ getState }: { getState: Function }) {
|
||||
function _conferenceWillLeave({ getState }: IStore) {
|
||||
_removeUnloadHandler(getState);
|
||||
}
|
||||
|
||||
@@ -460,7 +461,7 @@ function _conferenceWillLeave({ getState }: { getState: Function }) {
|
||||
* @private
|
||||
* @returns {Object} The value returned by {@code next(action)}.
|
||||
*/
|
||||
function _pinParticipant({ getState }, next, action) {
|
||||
function _pinParticipant({ getState }: IStore, next: Function, action: AnyAction) {
|
||||
const state = getState();
|
||||
const { conference } = state['features/base/conference'];
|
||||
|
||||
@@ -473,7 +474,7 @@ function _pinParticipant({ getState }, next, action) {
|
||||
const pinnedParticipant = getPinnedParticipant(state);
|
||||
const actionName = id ? ACTION_PINNED : ACTION_UNPINNED;
|
||||
const local
|
||||
= (participantById && participantById.local)
|
||||
= participantById?.local
|
||||
|| (!id && pinnedParticipant && pinnedParticipant.local);
|
||||
let participantIdForEvent;
|
||||
|
||||
@@ -481,7 +482,7 @@ function _pinParticipant({ getState }, next, action) {
|
||||
participantIdForEvent = local;
|
||||
} else {
|
||||
participantIdForEvent
|
||||
= actionName === ACTION_PINNED ? id : pinnedParticipant && pinnedParticipant.id;
|
||||
= actionName === ACTION_PINNED ? id : pinnedParticipant?.id;
|
||||
}
|
||||
|
||||
sendAnalytics(createPinnedEvent(
|
||||
@@ -501,10 +502,11 @@ function _pinParticipant({ getState }, next, action) {
|
||||
* @param {Function} getState - The redux getState function.
|
||||
* @returns {void}
|
||||
*/
|
||||
function _removeUnloadHandler(getState) {
|
||||
function _removeUnloadHandler(getState: IStore['getState']) {
|
||||
if (typeof beforeUnloadHandler !== 'undefined') {
|
||||
const { disableBeforeUnloadHandlers = false } = getState()['features/base/config'];
|
||||
|
||||
// @ts-ignore
|
||||
window.removeEventListener(disableBeforeUnloadHandlers ? 'unload' : 'beforeunload', beforeUnloadHandler);
|
||||
beforeUnloadHandler = undefined;
|
||||
}
|
||||
@@ -522,7 +524,7 @@ function _removeUnloadHandler(getState) {
|
||||
* @private
|
||||
* @returns {Object} The value returned by {@code next(action)}.
|
||||
*/
|
||||
function _sendTones({ getState }, next, action) {
|
||||
function _sendTones({ getState }: IStore, next: Function, action: AnyAction) {
|
||||
const state = getState();
|
||||
const { conference } = state['features/base/conference'];
|
||||
|
||||
@@ -549,15 +551,15 @@ function _sendTones({ getState }, next, action) {
|
||||
* @private
|
||||
* @returns {Object} The value returned by {@code next(action)}.
|
||||
*/
|
||||
function _setRoom({ dispatch, getState }, next, action) {
|
||||
function _setRoom({ dispatch, getState }: IStore, next: Function, action: AnyAction) {
|
||||
const state = getState();
|
||||
const { localSubject, subject } = state['features/base/config'];
|
||||
const { room } = action;
|
||||
|
||||
if (room) {
|
||||
// Set the stored subject.
|
||||
dispatch(setLocalSubject(localSubject));
|
||||
dispatch(setSubject(subject));
|
||||
dispatch(setLocalSubject(localSubject ?? ''));
|
||||
dispatch(setSubject(subject ?? ''));
|
||||
}
|
||||
|
||||
return next(action);
|
||||
@@ -572,7 +574,7 @@ function _setRoom({ dispatch, getState }, next, action) {
|
||||
* @private
|
||||
* @returns {Promise}
|
||||
*/
|
||||
function _syncConferenceLocalTracksWithState({ getState }, action) {
|
||||
function _syncConferenceLocalTracksWithState({ getState }: IStore, action: AnyAction) {
|
||||
const conference = getCurrentConference(getState);
|
||||
let promise;
|
||||
|
||||
@@ -603,7 +605,7 @@ function _syncConferenceLocalTracksWithState({ getState }, action) {
|
||||
* @private
|
||||
* @returns {Object} The value returned by {@code next(action)}.
|
||||
*/
|
||||
function _trackAddedOrRemoved(store, next, action) {
|
||||
function _trackAddedOrRemoved(store: IStore, next: Function, action: AnyAction) {
|
||||
const track = action.track;
|
||||
|
||||
// TODO All track swapping should happen here instead of conference.js.
|
||||
@@ -628,7 +630,7 @@ function _trackAddedOrRemoved(store, next, action) {
|
||||
* @private
|
||||
* @returns {Object} The value returned by {@code next(action)}.
|
||||
*/
|
||||
function _updateLocalParticipantInConference({ dispatch, getState }, next, action) {
|
||||
function _updateLocalParticipantInConference({ dispatch, getState }: IStore, next: Function, action: AnyAction) {
|
||||
const { conference } = getState()['features/base/conference'];
|
||||
const { participant } = action;
|
||||
const result = next(action);
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
import {
|
||||
setPrejoinPageVisibility,
|
||||
setSkipPrejoinOnReload
|
||||
@@ -60,6 +60,7 @@ export interface IJitsiConference {
|
||||
getMetadataHandler: Function;
|
||||
getName: Function;
|
||||
getParticipantById: Function;
|
||||
getParticipantCount: Function;
|
||||
getParticipants: Function;
|
||||
getRole: Function;
|
||||
getSpeakerStats: () => ISpeakerStats;
|
||||
@@ -101,6 +102,7 @@ export interface IJitsiConference {
|
||||
sendMessage: Function;
|
||||
sendPrivateTextMessage: Function;
|
||||
sendTextMessage: Function;
|
||||
sendTones: Function;
|
||||
sessionId: string;
|
||||
setDesktopSharingFrameRate: Function;
|
||||
setDisplayName: Function;
|
||||
|
||||
@@ -7,6 +7,7 @@ import _ from 'lodash';
|
||||
|
||||
import { IReduxState } from '../../app/types';
|
||||
import { browser } from '../lib-jitsi-meet';
|
||||
import { IMediaState } from '../media/reducer';
|
||||
import { parseURLParams } from '../util/parseURLParams';
|
||||
|
||||
import { IConfig } from './configType';
|
||||
@@ -65,7 +66,7 @@ export function getMeetingRegion(state: IReduxState) {
|
||||
* @param {Object} _state - The global state.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function getMultipleVideoSendingSupportFeatureFlag(_state: IReduxState) {
|
||||
export function getMultipleVideoSendingSupportFeatureFlag(_state: IReduxState | IMediaState) {
|
||||
return browser.supportsUnifiedPlan();
|
||||
}
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ export type ConnectionFailedError = {
|
||||
* connection: JitsiConnection
|
||||
* }}
|
||||
*/
|
||||
export function connectionDisconnected(connection: Object) {
|
||||
export function connectionDisconnected(connection?: Object) {
|
||||
return {
|
||||
type: CONNECTION_DISCONNECTED,
|
||||
connection
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// @flow
|
||||
|
||||
import { getLogger } from '../logging/functions';
|
||||
|
||||
export default getLogger('features/base/jitsi-local-storage');
|
||||
@@ -1,6 +1,7 @@
|
||||
// @flow
|
||||
|
||||
// @ts-ignore
|
||||
import Bourne from '@hapi/bourne';
|
||||
// eslint-disable-next-line lines-around-comment
|
||||
// @ts-ignore
|
||||
import { jitsiLocalStorage } from '@jitsi/js-utils/jitsi-local-storage';
|
||||
|
||||
import { browser } from '../lib-jitsi-meet';
|
||||
@@ -9,9 +10,6 @@ import { parseURLParams } from '../util/parseURLParams';
|
||||
|
||||
import logger from './logger';
|
||||
|
||||
declare var APP: Object;
|
||||
declare var config: Object;
|
||||
|
||||
|
||||
/**
|
||||
* Handles changes of the fake local storage.
|
||||
@@ -29,7 +27,7 @@ function onFakeLocalStorageChanged() {
|
||||
* @returns {boolean} - True if the local storage of the host page needs to be used instead jitsi-meet's local storage
|
||||
* and false otherwise.
|
||||
*/
|
||||
function shouldUseHostPageLocalStorage(urlParams) {
|
||||
function shouldUseHostPageLocalStorage(urlParams: { 'config.useHostPageLocalStorage'?: boolean; }) {
|
||||
// NOTE: normally the url params and the config will be merged into the redux store. But we want to setup the local
|
||||
// storage as soon as possible, the store is not created yet and the merging of the URL params and the config
|
||||
// haven't been executed yet. That's why we need to manually parse the URL params and also access the config through
|
||||
@@ -58,6 +56,7 @@ function shouldUseHostPageLocalStorage(urlParams) {
|
||||
* @returns {void}
|
||||
*/
|
||||
function setupJitsiLocalStorage() {
|
||||
// @ts-ignore
|
||||
const urlParams = parseURLParams(window.location);
|
||||
|
||||
if (shouldUseHostPageLocalStorage(urlParams)) {
|
||||
@@ -2,5 +2,6 @@
|
||||
// of) the project jitsi-meet.
|
||||
//
|
||||
|
||||
// @ts-ignore
|
||||
import JitsiMeetJS from 'lib-jitsi-meet';
|
||||
export { JitsiMeetJS as default };
|
||||
@@ -1,5 +0,0 @@
|
||||
// @flow
|
||||
|
||||
declare var JitsiMeetJS: Object;
|
||||
|
||||
export default JitsiMeetJS;
|
||||
3
react/features/base/lib-jitsi-meet/_.web.ts
Normal file
3
react/features/base/lib-jitsi-meet/_.web.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
declare let JitsiMeetJS: any;
|
||||
|
||||
export default JitsiMeetJS;
|
||||
@@ -157,7 +157,7 @@ export function setVideoAvailable(available: boolean) {
|
||||
* @returns {Function}
|
||||
*/
|
||||
export function setVideoMuted(
|
||||
muted: boolean,
|
||||
muted: boolean | number,
|
||||
authority: number = VIDEO_MUTISM_AUTHORITY.USER,
|
||||
ensureTrack = false) {
|
||||
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// @flow
|
||||
import { AnyAction } from 'redux';
|
||||
|
||||
import {
|
||||
createStartAudioOnlyEvent,
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
createTrackMutedEvent
|
||||
} from '../../analytics/AnalyticsEvents';
|
||||
import { sendAnalytics } from '../../analytics/functions';
|
||||
import { IStore } from '../../app/types';
|
||||
import { APP_STATE_CHANGED } from '../../mobile/background/actionTypes';
|
||||
import { showWarningNotification } from '../../notifications/actions';
|
||||
import { NOTIFICATION_TIMEOUT_TYPE } from '../../notifications/constants';
|
||||
@@ -23,6 +24,7 @@ import { getPropertyValue } from '../settings/functions.any';
|
||||
import { TRACK_ADDED } from '../tracks/actionTypes';
|
||||
import { destroyLocalTracks } from '../tracks/actions.any';
|
||||
import { isLocalTrackMuted, isLocalVideoTrackDesktop, setTrackMuted } from '../tracks/functions.any';
|
||||
import { ITrack } from '../tracks/types';
|
||||
|
||||
import {
|
||||
SET_AUDIO_MUTED,
|
||||
@@ -155,7 +157,7 @@ MiddlewareRegistry.register(store => next => action => {
|
||||
* @private
|
||||
* @returns {Object} The value returned by {@code next(action)}.
|
||||
*/
|
||||
function _appStateChanged({ dispatch, getState }, next, action) {
|
||||
function _appStateChanged({ dispatch, getState }: IStore, next: Function, action: AnyAction) {
|
||||
if (navigator.product === 'ReactNative') {
|
||||
const { appState } = action;
|
||||
const mute = appState !== 'active' && !isLocalVideoTrackDesktop(getState());
|
||||
@@ -180,7 +182,7 @@ function _appStateChanged({ dispatch, getState }, next, action) {
|
||||
* @private
|
||||
* @returns {Object} The value returned by {@code next(action)}.
|
||||
*/
|
||||
function _setAudioOnly({ dispatch, getState }, next, action) {
|
||||
function _setAudioOnly({ dispatch, getState }: IStore, next: Function, action: AnyAction) {
|
||||
const { audioOnly } = action;
|
||||
const state = getState();
|
||||
|
||||
@@ -209,7 +211,7 @@ function _setAudioOnly({ dispatch, getState }, next, action) {
|
||||
* @returns {Object} The new state that is the result of the reduction of the
|
||||
* specified {@code action}.
|
||||
*/
|
||||
function _setRoom({ dispatch, getState }, next, action) {
|
||||
function _setRoom({ dispatch, getState }: IStore, next: Function, action: AnyAction) {
|
||||
// Figure out the desires/intents i.e. the state of base/media. There are
|
||||
// multiple desires/intents ordered by precedence such as server-side
|
||||
// config, config overrides in the user-supplied URL, user's own app
|
||||
@@ -222,7 +224,7 @@ function _setRoom({ dispatch, getState }, next, action) {
|
||||
const videoMuted = roomIsValid ? getStartWithVideoMuted(state) : _VIDEO_INITIAL_MEDIA_STATE.muted;
|
||||
|
||||
sendAnalytics(
|
||||
createStartMutedConfigurationEvent('local', audioMuted, videoMuted));
|
||||
createStartMutedConfigurationEvent('local', audioMuted, Boolean(videoMuted)));
|
||||
logger.log(
|
||||
`Start muted: ${audioMuted ? 'audio, ' : ''}${
|
||||
videoMuted ? 'video' : ''}`);
|
||||
@@ -295,7 +297,7 @@ function _setRoom({ dispatch, getState }, next, action) {
|
||||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
function _syncTrackMutedState({ getState }, track) {
|
||||
function _syncTrackMutedState({ getState }: IStore, track: ITrack) {
|
||||
const state = getState()['features/base/media'];
|
||||
const mediaType = track.mediaType;
|
||||
const muted = Boolean(state[mediaType].muted);
|
||||
@@ -1 +1 @@
|
||||
import './middleware.any.js';
|
||||
import './middleware.any';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import './middleware.any.js';
|
||||
import './middleware.any';
|
||||
|
||||
import { IStore } from '../../app/types';
|
||||
import { showNotification } from '../../notifications/actions';
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
} from '../config/functions.any';
|
||||
import { JitsiTrackErrors, browser } from '../lib-jitsi-meet';
|
||||
import { MEDIA_TYPE, MediaType, VIDEO_TYPE } from '../media/constants';
|
||||
import { IMediaState } from '../media/reducer';
|
||||
import {
|
||||
getVirtualScreenshareParticipantOwnerId,
|
||||
isScreenShareParticipant
|
||||
@@ -359,7 +360,7 @@ export function isUserInteractionRequiredForUnmute(state: IReduxState) {
|
||||
* @param {Object} state - The redux state.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function setTrackMuted(track: any, muted: boolean, state: IReduxState) {
|
||||
export function setTrackMuted(track: any, muted: boolean, state: IReduxState | IMediaState) {
|
||||
muted = Boolean(muted); // eslint-disable-line no-param-reassign
|
||||
|
||||
// Ignore the check for desktop track muted operation. When the screenshare is terminated by clicking on the
|
||||
|
||||
@@ -283,6 +283,7 @@ export function updateProfile(calendarType: string) {
|
||||
return Promise.reject('No integration found');
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
return dispatch(integration.getCurrentEmail())
|
||||
.then((email: string) => {
|
||||
dispatch(setCalendarProfileEmail(email));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { ColorPalette } from '../../base/styles/components/styles/ColorPalette';
|
||||
import { createStyleSheet } from '../../base/styles/functions.any';
|
||||
import BaseTheme from '../../base/ui/components/BaseTheme.native';
|
||||
import BaseTheme from '../../base/ui/components/BaseTheme';
|
||||
|
||||
const NOTIFICATION_SIZE = 55;
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ export interface ICalendarSyncState {
|
||||
integrationReady: boolean;
|
||||
integrationType?: string;
|
||||
isLoadingEvents?: boolean;
|
||||
msAuthState?: Object;
|
||||
msAuthState?: any;
|
||||
profileEmail?: string;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
// @flow
|
||||
|
||||
import type { Dispatch } from 'redux';
|
||||
|
||||
import { IStore } from '../../app/types';
|
||||
import {
|
||||
getCalendarEntries,
|
||||
loadGoogleAPI,
|
||||
signIn,
|
||||
updateCalendarEvent,
|
||||
updateProfile
|
||||
} from '../../google-api/actions';
|
||||
} from '../../google-api/actions'; // @ts-ignore
|
||||
import googleApi from '../../google-api/googleApi.web';
|
||||
|
||||
/**
|
||||
@@ -43,7 +40,7 @@ export const googleCalendarApi = {
|
||||
* @returns {function(Dispatch<any>, Function): Promise<void>}
|
||||
*/
|
||||
load() {
|
||||
return (dispatch: Dispatch<any>) => dispatch(loadGoogleAPI());
|
||||
return (dispatch: IStore['dispatch']) => dispatch(loadGoogleAPI());
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -1,16 +1,18 @@
|
||||
// @flow
|
||||
|
||||
import { Client } from '@microsoft/microsoft-graph-client';
|
||||
// eslint-disable-next-line lines-around-comment
|
||||
// @ts-ignore
|
||||
import base64js from 'base64-js';
|
||||
import type { Dispatch } from 'redux';
|
||||
import { v4 as uuidV4 } from 'uuid';
|
||||
import { findWindows } from 'windows-iana';
|
||||
import { IanaName } from 'windows-iana/dist/enums';
|
||||
|
||||
// @ts-expect-error
|
||||
import { createDeferred } from '../../../../modules/util/helpers';
|
||||
import { IStore } from '../../app/types';
|
||||
import { parseURLParams } from '../../base/util/parseURLParams';
|
||||
import { parseStandardURIString } from '../../base/util/uri';
|
||||
import { getShareInfoText } from '../../invite/functions';
|
||||
import { setCalendarAPIAuthState } from '../actions';
|
||||
import { setCalendarAPIAuthState } from '../actions.web';
|
||||
|
||||
|
||||
/**
|
||||
@@ -63,7 +65,7 @@ const MS_API_CONFIGURATION = {
|
||||
* @private
|
||||
* @type {Object|null}
|
||||
*/
|
||||
let popupAuthWindow = null;
|
||||
let popupAuthWindow: Window | null = null;
|
||||
|
||||
/**
|
||||
* A stateless collection of action creators that implements the expected
|
||||
@@ -81,10 +83,10 @@ export const microsoftCalendarApi = {
|
||||
* @param {number} fetchEndDays - The number of days to fetch.
|
||||
* @returns {function(Dispatch<any>, Function): Promise<CalendarEntries>}
|
||||
*/
|
||||
getCalendarEntries(fetchStartDays: ?number, fetchEndDays: ?number) {
|
||||
return (dispatch: Dispatch<any>, getState: Function): Promise<*> => {
|
||||
getCalendarEntries(fetchStartDays?: number, fetchEndDays?: number) {
|
||||
return (dispatch: IStore['dispatch'], getState: IStore['getState']): Promise<any> => {
|
||||
const state = getState()['features/calendar-sync'] || {};
|
||||
const token = state.msAuthState && state.msAuthState.accessToken;
|
||||
const token = state.msAuthState?.accessToken;
|
||||
|
||||
if (!token) {
|
||||
return Promise.reject('Not authorized, please sign in!');
|
||||
@@ -98,8 +100,8 @@ export const microsoftCalendarApi = {
|
||||
.api(MS_API_CONFIGURATION.CALENDAR_ENDPOINT)
|
||||
.get()
|
||||
.then(response => {
|
||||
const calendarIds = response.value.map(en => en.id);
|
||||
const getEventsPromises = calendarIds.map(id =>
|
||||
const calendarIds = response.value.map((en: any) => en.id);
|
||||
const getEventsPromises = calendarIds.map((id: string) =>
|
||||
requestCalendarEvents(
|
||||
client, id, fetchStartDays, fetchEndDays));
|
||||
|
||||
@@ -120,7 +122,7 @@ export const microsoftCalendarApi = {
|
||||
* @returns {function(Dispatch<*, Function>): Promise<string>}
|
||||
*/
|
||||
getCurrentEmail(): Function {
|
||||
return (dispatch: Dispatch<any>, getState: Function) => {
|
||||
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
|
||||
const { msAuthState = {} }
|
||||
= getState()['features/calendar-sync'] || {};
|
||||
const email = msAuthState.userSigninName || '';
|
||||
@@ -134,7 +136,7 @@ export const microsoftCalendarApi = {
|
||||
*
|
||||
* @returns {function(): Promise<void>}
|
||||
*/
|
||||
load(): Function {
|
||||
load() {
|
||||
return () => Promise.resolve();
|
||||
},
|
||||
|
||||
@@ -143,8 +145,8 @@ export const microsoftCalendarApi = {
|
||||
*
|
||||
* @returns {function(Dispatch<any>, Function): Promise<void>}
|
||||
*/
|
||||
signIn(): Function {
|
||||
return (dispatch: Dispatch<any>, getState: Function) => {
|
||||
signIn() {
|
||||
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
|
||||
// Ensure only one popup window at a time.
|
||||
if (popupAuthWindow) {
|
||||
popupAuthWindow.focus();
|
||||
@@ -164,7 +166,7 @@ export const microsoftCalendarApi = {
|
||||
const { microsoftApiApplicationClientID }
|
||||
= getState()['features/base/config'];
|
||||
const authUrl = getAuthUrl(
|
||||
microsoftApiApplicationClientID,
|
||||
microsoftApiApplicationClientID ?? '',
|
||||
guids.authState,
|
||||
guids.authNonce);
|
||||
const h = 600;
|
||||
@@ -178,7 +180,7 @@ export const microsoftCalendarApi = {
|
||||
(screen.width / 2) - (w / 2)}`);
|
||||
|
||||
const windowCloseCheck = setInterval(() => {
|
||||
if (popupAuthWindow && popupAuthWindow.closed) {
|
||||
if (popupAuthWindow?.closed) {
|
||||
signInDeferred.reject(
|
||||
'Popup closed before completing auth.');
|
||||
popupAuthWindow = null;
|
||||
@@ -199,19 +201,19 @@ export const microsoftCalendarApi = {
|
||||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
function handleAuth({ data }) {
|
||||
function handleAuth({ data }: any) {
|
||||
if (!data || data.type !== 'ms-login') {
|
||||
return;
|
||||
}
|
||||
|
||||
window.removeEventListener('message', handleAuth);
|
||||
|
||||
popupAuthWindow && popupAuthWindow.close();
|
||||
popupAuthWindow?.close();
|
||||
popupAuthWindow = null;
|
||||
|
||||
const params = getParamsFromHash(data.url);
|
||||
const tokenParts = getValidatedTokenParts(
|
||||
params, guids, microsoftApiApplicationClientID);
|
||||
params, guids, microsoftApiApplicationClientID ?? '');
|
||||
|
||||
if (!tokenParts) {
|
||||
signInDeferred.reject('Invalid token received');
|
||||
@@ -242,8 +244,8 @@ export const microsoftCalendarApi = {
|
||||
*
|
||||
* @returns {function(Dispatch<any>, Function): Promise<boolean>}
|
||||
*/
|
||||
_isSignedIn(): Function {
|
||||
return (dispatch: Dispatch<any>, getState: Function) => {
|
||||
_isSignedIn() {
|
||||
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
|
||||
const now = new Date().getTime();
|
||||
const state
|
||||
= getState()['features/calendar-sync'].msAuthState || {};
|
||||
@@ -271,9 +273,9 @@ export const microsoftCalendarApi = {
|
||||
* @returns {function(Dispatch<any>): Promise<string|never>}
|
||||
*/
|
||||
updateCalendarEvent(id: string, calendarId: string, location: string) {
|
||||
return (dispatch: Dispatch<any>, getState: Function): Promise<*> => {
|
||||
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
|
||||
const state = getState()['features/calendar-sync'] || {};
|
||||
const token = state.msAuthState && state.msAuthState.accessToken;
|
||||
const token = state.msAuthState?.accessToken;
|
||||
|
||||
if (!token) {
|
||||
return Promise.reject('Not authorized, please sign in!');
|
||||
@@ -329,7 +331,7 @@ export const microsoftCalendarApi = {
|
||||
* title: string
|
||||
* }}
|
||||
*/
|
||||
function formatCalendarEntry(entry) {
|
||||
function formatCalendarEntry(entry: any) {
|
||||
return {
|
||||
calendarId: entry.calendarId,
|
||||
description: entry.body.content,
|
||||
@@ -352,7 +354,7 @@ function formatCalendarEntry(entry) {
|
||||
* @private
|
||||
* @returns {string} - The auth URL.
|
||||
*/
|
||||
function getAuthRefreshUrl(appId, userDomainType, userSigninName) {
|
||||
function getAuthRefreshUrl(appId: string, userDomainType: string, userSigninName: string) {
|
||||
return [
|
||||
getAuthUrl(appId, 'undefined', 'undefined'),
|
||||
'prompt=none',
|
||||
@@ -370,7 +372,7 @@ function getAuthRefreshUrl(appId, userDomainType, userSigninName) {
|
||||
* @private
|
||||
* @returns {string} - The auth URL.
|
||||
*/
|
||||
function getAuthUrl(appId, authState, authNonce) {
|
||||
function getAuthUrl(appId: string, authState: string, authNonce: string) {
|
||||
const authParams = [
|
||||
'response_type=id_token+token',
|
||||
`client_id=${appId}`,
|
||||
@@ -392,7 +394,8 @@ function getAuthUrl(appId, authState, authNonce) {
|
||||
* @private
|
||||
* @returns {Object}
|
||||
*/
|
||||
function getParamsFromHash(url) {
|
||||
function getParamsFromHash(url: string) {
|
||||
// @ts-ignore
|
||||
const params = parseURLParams(parseStandardURIString(url), true, 'hash');
|
||||
|
||||
// Get the number of seconds the token is valid for, subtract 5 minutes
|
||||
@@ -418,7 +421,7 @@ function getParamsFromHash(url) {
|
||||
* @private
|
||||
* @returns {Object|null}
|
||||
*/
|
||||
function getValidatedTokenParts(tokenInfo, guids, appId) {
|
||||
function getValidatedTokenParts(tokenInfo: any, guids: any, appId: string) {
|
||||
// Make sure the token matches the request source by matching the GUID.
|
||||
if (tokenInfo.state !== guids.authState) {
|
||||
return null;
|
||||
@@ -479,15 +482,15 @@ function getValidatedTokenParts(tokenInfo, guids, appId) {
|
||||
* @private
|
||||
* @returns {function(Dispatch<any>, Function): Promise<void>}
|
||||
*/
|
||||
function refreshAuthToken(): Function {
|
||||
return (dispatch: Dispatch<any>, getState: Function) => {
|
||||
function refreshAuthToken() {
|
||||
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
|
||||
const { microsoftApiApplicationClientID }
|
||||
= getState()['features/base/config'];
|
||||
const { msAuthState = {} }
|
||||
= getState()['features/calendar-sync'] || {};
|
||||
|
||||
const refreshAuthUrl = getAuthRefreshUrl(
|
||||
microsoftApiApplicationClientID,
|
||||
microsoftApiApplicationClientID ?? '',
|
||||
msAuthState.userDomainType,
|
||||
msAuthState.userSigninName);
|
||||
|
||||
@@ -500,7 +503,7 @@ function refreshAuthToken(): Function {
|
||||
|
||||
const signInPromise = new Promise(resolve => {
|
||||
iframe.onload = () => {
|
||||
resolve(iframe.contentWindow.location.hash);
|
||||
resolve(iframe.contentWindow?.location.hash);
|
||||
};
|
||||
});
|
||||
|
||||
@@ -514,7 +517,7 @@ function refreshAuthToken(): Function {
|
||||
document.body.appendChild(iframe);
|
||||
|
||||
return signInPromise.then(hash => {
|
||||
const params = getParamsFromHash(hash);
|
||||
const params = getParamsFromHash(hash as string);
|
||||
|
||||
dispatch(setCalendarAPIAuthState({
|
||||
accessToken: params.access_token,
|
||||
@@ -537,22 +540,22 @@ function refreshAuthToken(): Function {
|
||||
* @private
|
||||
*/
|
||||
function requestCalendarEvents( // eslint-disable-line max-params
|
||||
client,
|
||||
calendarId,
|
||||
fetchStartDays,
|
||||
fetchEndDays): Promise<*> {
|
||||
client: any,
|
||||
calendarId: string,
|
||||
fetchStartDays?: number,
|
||||
fetchEndDays?: number): Promise<any> {
|
||||
const startDate = new Date();
|
||||
const endDate = new Date();
|
||||
|
||||
startDate.setDate(startDate.getDate() + fetchStartDays);
|
||||
endDate.setDate(endDate.getDate() + fetchEndDays);
|
||||
startDate.setDate(startDate.getDate() + Number(fetchStartDays));
|
||||
endDate.setDate(endDate.getDate() + Number(fetchEndDays));
|
||||
|
||||
const filter = `Start/DateTime ge '${
|
||||
startDate.toISOString()}' and End/DateTime lt '${
|
||||
endDate.toISOString()}'`;
|
||||
|
||||
const ianaTimeZone = new Intl.DateTimeFormat().resolvedOptions().timeZone;
|
||||
const windowsTimeZone = findWindows(ianaTimeZone);
|
||||
const windowsTimeZone = findWindows(ianaTimeZone as IanaName);
|
||||
|
||||
return client
|
||||
.api(`/me/calendars/${calendarId}/events`)
|
||||
@@ -561,7 +564,7 @@ function requestCalendarEvents( // eslint-disable-line max-params
|
||||
.select('id,subject,start,end,location,body')
|
||||
.orderby('createdDateTime DESC')
|
||||
.get()
|
||||
.then(result => result.value.map(item => {
|
||||
.then((result: any) => result.value.map((item: Object) => {
|
||||
return {
|
||||
...item,
|
||||
calendarId
|
||||
@@ -576,7 +579,7 @@ function requestCalendarEvents( // eslint-disable-line max-params
|
||||
* @private
|
||||
* @returns {string} - The converted string.
|
||||
*/
|
||||
function b64utoutf8(str) {
|
||||
function b64utoutf8(str: string) {
|
||||
let s = str;
|
||||
|
||||
// Convert from Base64URL to Base64.
|
||||
@@ -595,7 +598,7 @@ function b64utoutf8(str) {
|
||||
|
||||
// Convert bytes to hex.
|
||||
|
||||
s = bytes.reduce((str_, byte) => str_ + byte.toString(16).padStart(2, '0'), '');
|
||||
s = bytes.reduce((str_: any, byte: any) => str_ + byte.toString(16).padStart(2, '0'), '');
|
||||
|
||||
// Convert a hexadecimal string to a URLComponent string
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// @flow
|
||||
|
||||
import MiddlewareRegistry from '../base/redux/MiddlewareRegistry';
|
||||
|
||||
import { OPEN_DESKTOP_APP } from './actionTypes';
|
||||
@@ -9,12 +9,12 @@ import {
|
||||
getParticipantPresenceStatus,
|
||||
getRemoteParticipants
|
||||
} from '../../../base/participants/functions';
|
||||
import { Container, Text } from '../../../base/react/components/index.web';
|
||||
import { Container, Text } from '../../../base/react/components/index';
|
||||
import { isLocalTrackMuted } from '../../../base/tracks/functions.any';
|
||||
import PresenceLabel from '../../../presence-status/components/PresenceLabel';
|
||||
import { CALLING } from '../../../presence-status/constants';
|
||||
|
||||
import styles from './styles.web';
|
||||
import styles from './styles';
|
||||
|
||||
/**
|
||||
* The type of the React {@code Component} props of {@link CalleeInfo}.
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
// @flow
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { IReduxState } from '../../app/types';
|
||||
import { shouldDisplayTileView } from '../../video-layout/functions.web';
|
||||
|
||||
/**
|
||||
@@ -22,7 +21,7 @@ export const ORIENTATION = {
|
||||
* The type of the React {@code Component} props of
|
||||
* {@link LargeVideoBackgroundCanvas}.
|
||||
*/
|
||||
type Props = {
|
||||
interface IProps {
|
||||
|
||||
/**
|
||||
* Whether or not the layout should change to support tile view mode.
|
||||
@@ -30,35 +29,35 @@ type Props = {
|
||||
* @protected
|
||||
* @type {boolean}
|
||||
*/
|
||||
_shouldDisplayTileView: boolean,
|
||||
_shouldDisplayTileView: boolean;
|
||||
|
||||
/**
|
||||
* Additional CSS class names to add to the root of the component.
|
||||
*/
|
||||
className: String,
|
||||
className: String;
|
||||
|
||||
/**
|
||||
* Whether or not the background should have its visibility hidden.
|
||||
*/
|
||||
hidden: boolean,
|
||||
hidden: boolean;
|
||||
|
||||
/**
|
||||
* Whether or not the video should display flipped horizontally, so left
|
||||
* becomes right and right becomes left.
|
||||
*/
|
||||
mirror: boolean,
|
||||
mirror: boolean;
|
||||
|
||||
/**
|
||||
* Whether the component should ensure full width of the video is displayed
|
||||
* (landscape) or full height (portrait).
|
||||
*/
|
||||
orientationFit: string,
|
||||
orientationFit: string;
|
||||
|
||||
/**
|
||||
* The video stream to display.
|
||||
*/
|
||||
videoElement: Object
|
||||
};
|
||||
videoElement: HTMLVideoElement;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@@ -67,10 +66,10 @@ type Props = {
|
||||
*
|
||||
* @augments Component
|
||||
*/
|
||||
export class LargeVideoBackground extends Component<Props> {
|
||||
_canvasEl: Object;
|
||||
export class LargeVideoBackground extends Component<IProps> {
|
||||
_canvasEl: HTMLCanvasElement;
|
||||
|
||||
_updateCanvasInterval: *;
|
||||
_updateCanvasInterval: number | undefined;
|
||||
|
||||
/**
|
||||
* Initializes new {@code LargeVideoBackground} instance.
|
||||
@@ -78,7 +77,7 @@ export class LargeVideoBackground extends Component<Props> {
|
||||
* @param {*} props - The read-only properties with which the new instance
|
||||
* is to be initialized.
|
||||
*/
|
||||
constructor(props: Props) {
|
||||
constructor(props: IProps) {
|
||||
super(props);
|
||||
|
||||
// Bind event handlers so they are only bound once per instance.
|
||||
@@ -107,7 +106,7 @@ export class LargeVideoBackground extends Component<Props> {
|
||||
*
|
||||
* @inheritdoc
|
||||
*/
|
||||
componentDidUpdate(prevProps: Props) {
|
||||
componentDidUpdate(prevProps: IProps) {
|
||||
const wasCanvasUpdating = !prevProps.hidden && !prevProps._shouldDisplayTileView && prevProps.videoElement;
|
||||
const shouldCanvasUpdating
|
||||
= !this.props.hidden && !this.props._shouldDisplayTileView && this.props.videoElement;
|
||||
@@ -163,7 +162,7 @@ export class LargeVideoBackground extends Component<Props> {
|
||||
_clearCanvas() {
|
||||
const cavnasContext = this._canvasEl.getContext('2d');
|
||||
|
||||
cavnasContext.clearRect(
|
||||
cavnasContext?.clearRect(
|
||||
0, 0, this._canvasEl.width, this._canvasEl.height);
|
||||
}
|
||||
|
||||
@@ -177,8 +176,6 @@ export class LargeVideoBackground extends Component<Props> {
|
||||
clearInterval(this._updateCanvasInterval);
|
||||
}
|
||||
|
||||
_setCanvasEl: () => void;
|
||||
|
||||
/**
|
||||
* Sets the instance variable for the component's canvas element so it can
|
||||
* be accessed directly for drawing on.
|
||||
@@ -187,7 +184,7 @@ export class LargeVideoBackground extends Component<Props> {
|
||||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
_setCanvasEl(element) {
|
||||
_setCanvasEl(element: HTMLCanvasElement) {
|
||||
this._canvasEl = element;
|
||||
}
|
||||
|
||||
@@ -199,11 +196,9 @@ export class LargeVideoBackground extends Component<Props> {
|
||||
*/
|
||||
_setUpdateCanvasInterval() {
|
||||
this._clearUpdateCanvasInterval();
|
||||
this._updateCanvasInterval = setInterval(this._updateCanvas, 200);
|
||||
this._updateCanvasInterval = window.setInterval(this._updateCanvas, 200);
|
||||
}
|
||||
|
||||
_updateCanvas: () => void;
|
||||
|
||||
/**
|
||||
* Draws the current frame of the passed in video element onto the canvas.
|
||||
*
|
||||
@@ -235,13 +230,13 @@ export class LargeVideoBackground extends Component<Props> {
|
||||
if (this.props.orientationFit === ORIENTATION.LANDSCAPE) {
|
||||
const heightScaledToFit = (canvasWidth / videoWidth) * videoHeight;
|
||||
|
||||
canvasContext.drawImage(
|
||||
videoElement, 0, 0, canvasWidth, heightScaledToFit);
|
||||
canvasContext?.drawImage(
|
||||
videoElement as any, 0, 0, canvasWidth, heightScaledToFit);
|
||||
} else {
|
||||
const widthScaledToFit = (canvasHeight / videoHeight) * videoWidth;
|
||||
|
||||
canvasContext.drawImage(
|
||||
videoElement, 0, 0, widthScaledToFit, canvasHeight);
|
||||
canvasContext?.drawImage(
|
||||
videoElement as any, 0, 0, widthScaledToFit, canvasHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -255,7 +250,7 @@ export class LargeVideoBackground extends Component<Props> {
|
||||
* _shouldDisplayTileView: boolean
|
||||
* }}
|
||||
*/
|
||||
function _mapStateToProps(state) {
|
||||
function _mapStateToProps(state: IReduxState) {
|
||||
return {
|
||||
_shouldDisplayTileView: shouldDisplayTileView(state)
|
||||
};
|
||||
@@ -7,6 +7,7 @@ import { createSharedVideoEvent as createEvent } from '../../../analytics/Analyt
|
||||
import { sendAnalytics } from '../../../analytics/functions';
|
||||
import { IReduxState } from '../../../app/types';
|
||||
import { getCurrentConference } from '../../../base/conference/functions';
|
||||
import { IJitsiConference } from '../../../base/conference/reducer';
|
||||
import { MEDIA_TYPE } from '../../../base/media/constants';
|
||||
import { getLocalParticipant } from '../../../base/participants/functions';
|
||||
import { isLocalTrackMuted } from '../../../base/tracks/functions';
|
||||
@@ -39,7 +40,7 @@ export interface IProps {
|
||||
/**
|
||||
* The current conference.
|
||||
*/
|
||||
_conference: Object;
|
||||
_conference?: IJitsiConference;
|
||||
|
||||
/**
|
||||
* Warning that indicates an incorrect video url.
|
||||
@@ -71,12 +72,12 @@ export interface IProps {
|
||||
/**
|
||||
* Store flag for muted state.
|
||||
*/
|
||||
_muted: boolean;
|
||||
_muted?: boolean;
|
||||
|
||||
/**
|
||||
* The shared video owner id.
|
||||
*/
|
||||
_ownerId: string;
|
||||
_ownerId?: string;
|
||||
|
||||
/**
|
||||
* Updates the shared video status.
|
||||
@@ -86,7 +87,7 @@ export interface IProps {
|
||||
/**
|
||||
* The shared video status.
|
||||
*/
|
||||
_status: string;
|
||||
_status?: string;
|
||||
|
||||
/**
|
||||
* Action to stop video sharing.
|
||||
@@ -97,12 +98,12 @@ export interface IProps {
|
||||
* Seek time in seconds.
|
||||
*
|
||||
*/
|
||||
_time: number;
|
||||
_time?: number;
|
||||
|
||||
/**
|
||||
* The video url.
|
||||
*/
|
||||
_videoUrl: string;
|
||||
_videoUrl?: string;
|
||||
|
||||
/**
|
||||
* The video id.
|
||||
@@ -185,8 +186,8 @@ class AbstractVideoManager extends PureComponent<IProps> {
|
||||
|
||||
const playerTime = this.getTime();
|
||||
|
||||
if (shouldSeekToPosition(_time, playerTime)) {
|
||||
this.seek(_time);
|
||||
if (shouldSeekToPosition(Number(_time), Number(playerTime))) {
|
||||
this.seek(Number(_time));
|
||||
}
|
||||
|
||||
if (this.getPlaybackStatus() !== _status) {
|
||||
@@ -214,7 +215,7 @@ class AbstractVideoManager extends PureComponent<IProps> {
|
||||
* @param {Object|undefined} e - The error returned by the API or none.
|
||||
* @returns {void}
|
||||
*/
|
||||
onError(e: any) {
|
||||
onError(e?: any) {
|
||||
logger.error('Error in the video player', e?.data,
|
||||
e?.data ? 'Check error code at https://developers.google.com/youtube/iframe_api_reference#onError' : '');
|
||||
this.props._stopSharedVideo();
|
||||
@@ -251,7 +252,7 @@ class AbstractVideoManager extends PureComponent<IProps> {
|
||||
const volume = this.getVolume();
|
||||
const muted = this.isMuted();
|
||||
|
||||
if (volume > 0 && !muted) {
|
||||
if (Number(volume) > 0 && !muted) {
|
||||
this.smartAudioMute();
|
||||
}
|
||||
|
||||
@@ -290,7 +291,7 @@ class AbstractVideoManager extends PureComponent<IProps> {
|
||||
|
||||
const status = this.getPlaybackStatus();
|
||||
|
||||
if (!Object.values(PLAYBACK_STATUSES).includes(status)) {
|
||||
if (!Object.values(PLAYBACK_STATUSES).includes(status ?? '')) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -320,7 +321,7 @@ class AbstractVideoManager extends PureComponent<IProps> {
|
||||
isSharedVideoVolumeOn() {
|
||||
return this.getPlaybackStatus() === PLAYBACK_STATUSES.PLAYING
|
||||
&& !this.isMuted()
|
||||
&& this.getVolume() > 0;
|
||||
&& Number(this.getVolume()) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -342,54 +343,93 @@ class AbstractVideoManager extends PureComponent<IProps> {
|
||||
/**
|
||||
* Seeks video to provided time.
|
||||
*
|
||||
* @param {number} time
|
||||
* @param {number} _time - Time to seek to.
|
||||
* @returns {void}
|
||||
*/
|
||||
seek: (time: number) => void;
|
||||
seek(_time: number) {
|
||||
// to be implemented by subclass
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the playback state of the video.
|
||||
*
|
||||
* @returns {string}
|
||||
*/
|
||||
getPlaybackStatus: () => string;
|
||||
getPlaybackStatus(): string | undefined {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the video is muted.
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isMuted: () => boolean;
|
||||
isMuted(): boolean | undefined {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves current volume.
|
||||
*
|
||||
* @returns {number}
|
||||
*/
|
||||
getVolume: () => number;
|
||||
getVolume() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Plays video.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
play: () => void;
|
||||
play() {
|
||||
// to be implemented by subclass
|
||||
}
|
||||
|
||||
/**
|
||||
* Pauses video.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
pause: () => void;
|
||||
pause() {
|
||||
// to be implemented by subclass
|
||||
}
|
||||
|
||||
/**
|
||||
* Mutes video.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
mute: () => void;
|
||||
mute() {
|
||||
// to be implemented by subclass
|
||||
}
|
||||
|
||||
/**
|
||||
* Unmutes video.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
unMute: () => void;
|
||||
unMute() {
|
||||
// to be implemented by subclass
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves current time.
|
||||
*
|
||||
* @returns {number}
|
||||
*/
|
||||
getTime: () => number;
|
||||
getTime() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disposes current video player.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
dispose: () => void;
|
||||
dispose() {
|
||||
// to be implemented by subclass
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import { connect } from 'react-redux';
|
||||
import { PLAYBACK_STATUSES } from '../../constants';
|
||||
|
||||
import AbstractVideoManager, {
|
||||
Props,
|
||||
IProps,
|
||||
_mapDispatchToProps,
|
||||
_mapStateToProps
|
||||
} from './AbstractVideoManager';
|
||||
@@ -13,7 +13,9 @@ import AbstractVideoManager, {
|
||||
/**
|
||||
* Manager of shared video.
|
||||
*/
|
||||
class VideoManager extends AbstractVideoManager<Props> {
|
||||
class VideoManager extends AbstractVideoManager {
|
||||
playerRef: React.RefObject<HTMLVideoElement>;
|
||||
|
||||
/**
|
||||
* Initializes a new VideoManager instance.
|
||||
*
|
||||
@@ -21,7 +23,7 @@ class VideoManager extends AbstractVideoManager<Props> {
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
constructor(props) {
|
||||
constructor(props: IProps) {
|
||||
super(props);
|
||||
|
||||
this.playerRef = React.createRef();
|
||||
@@ -70,7 +72,7 @@ class VideoManager extends AbstractVideoManager<Props> {
|
||||
* @returns {number}
|
||||
*/
|
||||
getVolume() {
|
||||
return this.player?.volume;
|
||||
return Number(this.player?.volume);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -79,7 +81,7 @@ class VideoManager extends AbstractVideoManager<Props> {
|
||||
* @returns {number}
|
||||
*/
|
||||
getTime() {
|
||||
return this.player?.currentTime;
|
||||
return Number(this.player?.currentTime);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -89,7 +91,7 @@ class VideoManager extends AbstractVideoManager<Props> {
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
seek(time) {
|
||||
seek(time: number) {
|
||||
if (this.player) {
|
||||
this.player.currentTime = time;
|
||||
}
|
||||
@@ -143,7 +145,7 @@ class VideoManager extends AbstractVideoManager<Props> {
|
||||
getPlayerOptions() {
|
||||
const { _isOwner, videoId } = this.props;
|
||||
|
||||
let options = {
|
||||
let options: any = {
|
||||
autoPlay: true,
|
||||
src: videoId,
|
||||
controls: _isOwner,
|
||||
@@ -6,6 +6,7 @@ import YouTube from 'react-youtube';
|
||||
import { PLAYBACK_STATUSES } from '../../constants';
|
||||
|
||||
import AbstractVideoManager, {
|
||||
IProps,
|
||||
_mapDispatchToProps,
|
||||
_mapStateToProps
|
||||
} from './AbstractVideoManager';
|
||||
@@ -16,6 +17,9 @@ import AbstractVideoManager, {
|
||||
* @returns {void}
|
||||
*/
|
||||
class YoutubeVideoManager extends AbstractVideoManager {
|
||||
isPlayerAPILoaded: boolean;
|
||||
player?: any;
|
||||
|
||||
/**
|
||||
* Initializes a new YoutubeVideoManager instance.
|
||||
*
|
||||
@@ -23,7 +27,7 @@ class YoutubeVideoManager extends AbstractVideoManager {
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
constructor(props) {
|
||||
constructor(props: IProps) {
|
||||
super(props);
|
||||
|
||||
this.isPlayerAPILoaded = false;
|
||||
@@ -88,7 +92,7 @@ class YoutubeVideoManager extends AbstractVideoManager {
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
seek(time) {
|
||||
seek(time: number) {
|
||||
return this.player?.seekTo(time);
|
||||
}
|
||||
|
||||
@@ -147,7 +151,7 @@ class YoutubeVideoManager extends AbstractVideoManager {
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
onPlayerStateChange = event => {
|
||||
onPlayerStateChange = (event: any) => {
|
||||
if (event.data === YouTube.PlayerState.PLAYING) {
|
||||
this.onPlay();
|
||||
} else if (event.data === YouTube.PlayerState.PAUSED) {
|
||||
@@ -162,7 +166,7 @@ class YoutubeVideoManager extends AbstractVideoManager {
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
onPlayerReady = event => {
|
||||
onPlayerReady = (event: any) => {
|
||||
const { _isOwner } = this.props;
|
||||
|
||||
this.player = event.target;
|
||||
@@ -201,7 +205,7 @@ class YoutubeVideoManager extends AbstractVideoManager {
|
||||
'rel': 0
|
||||
}
|
||||
},
|
||||
onError: e => this.onError(e),
|
||||
onError: (e: any) => this.onError(e),
|
||||
onReady: this.onPlayerReady,
|
||||
onStateChange: this.onPlayerStateChange,
|
||||
videoId
|
||||
@@ -1,5 +1,3 @@
|
||||
// @flow
|
||||
|
||||
import JitsiMeetJS from '../../base/lib-jitsi-meet';
|
||||
import { MEDIA_TYPE } from '../../base/media/constants';
|
||||
|
||||
@@ -12,12 +10,12 @@ export class AudioMixerEffect {
|
||||
/**
|
||||
* JitsiLocalTrack that is going to be mixed into the track that uses this effect.
|
||||
*/
|
||||
_mixAudio: Object;
|
||||
_mixAudio: any;
|
||||
|
||||
/**
|
||||
* MediaStream resulted from mixing.
|
||||
*/
|
||||
_mixedMediaStream: Object;
|
||||
_mixedMediaStream: any;
|
||||
|
||||
/**
|
||||
* MediaStreamTrack obtained from mixed stream.
|
||||
@@ -32,19 +30,19 @@ export class AudioMixerEffect {
|
||||
/**
|
||||
* MediaStreamTrack obtained from the original MediaStream.
|
||||
*/
|
||||
_originalTrack: Object;
|
||||
_originalTrack: any;
|
||||
|
||||
/**
|
||||
* Lib-jitsi-meet AudioMixer.
|
||||
*/
|
||||
_audioMixer: Object;
|
||||
_audioMixer: any;
|
||||
|
||||
/**
|
||||
* Creates AudioMixerEffect.
|
||||
*
|
||||
* @param {JitsiLocalTrack} mixAudio - JitsiLocalTrack which will be mixed with the original track.
|
||||
*/
|
||||
constructor(mixAudio: Object) {
|
||||
constructor(mixAudio: any) {
|
||||
if (mixAudio.getType() !== MEDIA_TYPE.AUDIO) {
|
||||
throw new Error('AudioMixerEffect only supports audio JitsiLocalTracks; effect will not work!');
|
||||
}
|
||||
@@ -58,7 +56,7 @@ export class AudioMixerEffect {
|
||||
* @param {JitsiLocalTrack} sourceLocalTrack - Track to which the effect will be applied.
|
||||
* @returns {boolean} - Returns true if this effect can run on the specified track, false otherwise.
|
||||
*/
|
||||
isEnabled(sourceLocalTrack: Object) {
|
||||
isEnabled(sourceLocalTrack: any) {
|
||||
// Both JitsiLocalTracks need to be audio i.e. contain an audio MediaStreamTrack
|
||||
return sourceLocalTrack.isAudioTrack() && this._mixAudio.isAudioTrack();
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
// @flow
|
||||
|
||||
// Script expects to find rnnoise webassembly binary in the same public path root, otherwise it won't load
|
||||
// During the build phase this needs to be taken care of manually
|
||||
// @ts-ignore
|
||||
import { createRNNWasmModule } from '@jitsi/rnnoise-wasm';
|
||||
|
||||
import RnnoiseProcessor from './RnnoiseProcessor';
|
||||
@@ -9,7 +8,7 @@ import RnnoiseProcessor from './RnnoiseProcessor';
|
||||
export { RNNOISE_SAMPLE_LENGTH } from './RnnoiseProcessor';
|
||||
export type { RnnoiseProcessor };
|
||||
|
||||
let rnnoiseModule;
|
||||
let rnnoiseModule: Promise<any> | undefined;
|
||||
|
||||
/**
|
||||
* Creates a new instance of RnnoiseProcessor.
|
||||
@@ -21,5 +20,5 @@ export function createRnnoiseProcessor() {
|
||||
rnnoiseModule = createRNNWasmModule();
|
||||
}
|
||||
|
||||
return rnnoiseModule.then(mod => new RnnoiseProcessor(mod));
|
||||
return rnnoiseModule?.then(mod => new RnnoiseProcessor(mod));
|
||||
}
|
||||
@@ -29,7 +29,7 @@ import {
|
||||
AbstractWelcomePage,
|
||||
_mapStateToProps as _abstractMapStateToProps
|
||||
} from './AbstractWelcomePage';
|
||||
import styles from './styles';
|
||||
import styles from './styles.native';
|
||||
|
||||
interface IProps extends AbstractProps {
|
||||
|
||||
|
||||
@@ -31,9 +31,7 @@
|
||||
"react/features/remote-control",
|
||||
"react/features/screen-share",
|
||||
"react/features/screenshot-capture",
|
||||
"react/features/stream-effects/noise-suppression",
|
||||
"react/features/stream-effects/rnnoise",
|
||||
"react/features/stream-effects/virtual-background",
|
||||
"react/features/stream-effects",
|
||||
"react/features/virtual-background",
|
||||
"react/features/web-hid",
|
||||
"react/features/whiteboard",
|
||||
|
||||
Reference in New Issue
Block a user