ref(TS) Improve TS (#13167)

Fix some errors. Remove @ts-ignores
Convert some files to TS
Remove some eslint-disables
This commit is contained in:
Robert Pintilii
2023-04-04 17:08:59 +03:00
committed by GitHub
parent a828cacbfe
commit 3a2a129f44
73 changed files with 300 additions and 357 deletions

5
globals.d.ts vendored
View File

@@ -37,4 +37,9 @@ declare global {
const config: IConfig;
const JitsiMeetJS: any;
interface HTMLMediaElement {
setSinkId: (id: string) => Promise<undefined>;
stop: () => void;
}
}

View File

@@ -62,7 +62,7 @@ export function resetAnalytics() {
* @param {Store} store - The redux store in which the specified {@code action} is being dispatched.
* @returns {Promise} Resolves with the handlers that have been successfully loaded.
*/
export async function createHandlers({ getState }: { getState: Function; }) {
export async function createHandlers({ getState }: IStore) {
getJitsiMeetGlobalNS().analyticsHandlers = [];
if (!isAnalyticsEnabled(getState)) {
@@ -236,7 +236,7 @@ export function initAnalytics(store: IStore, handlers: Array<Object>) {
* loaded or the analytics is disabled.
*/
function _loadHandlers(scriptURLs: any[] = [], handlerConstructorOptions: Object) {
const promises = [];
const promises: Promise<{ error?: Error; type: string; url?: string; }>[] = [];
for (const url of scriptURLs) {
promises.push(
@@ -255,7 +255,7 @@ function _loadHandlers(scriptURLs: any[] = [], handlerConstructorOptions: Object
return Promise.all(promises).then(values => {
for (const el of values) {
if (el.type === 'error') { // @ts-ignore
if (el.type === 'error') {
logger.warn(`Failed to load ${el.url}: ${el.error}`);
}
}

View File

@@ -31,7 +31,7 @@ export default class AmplitudeHandler extends AbstractHandler {
};
if (navigator.product === 'ReactNative') {
amplitude.getInstance().init(amplitudeAPPKey); // @ts-ignore
amplitude.getInstance().init(amplitudeAPPKey);
fixDeviceID(amplitude.getInstance()).then(() => {
amplitude.getInstance().getDeviceId()
@@ -41,7 +41,7 @@ export default class AmplitudeHandler extends AbstractHandler {
});
});
} else {
const amplitudeOptions = {
const amplitudeOptions: any = {
includeReferrer: true,
onError
};

View File

@@ -1,9 +1,9 @@
/**
* Custom logic for setting the correct device id.
*
* @param {AmplitudeClient} amplitude - The amplitude instance.
* @param {AmplitudeClient} _amplitude - The amplitude instance.
* @returns {void}
*/
export function fixDeviceID(amplitude: any) { // eslint-disable-line @typescript-eslint/no-unused-vars
export function fixDeviceID(_amplitude: any): Promise<any> {
return new Promise(resolve => resolve(true));
}

View File

@@ -13,8 +13,6 @@ import MiddlewareRegistry from '../../redux/MiddlewareRegistry';
import PersistenceRegistry from '../../redux/PersistenceRegistry';
import ReducerRegistry from '../../redux/ReducerRegistry';
import StateListenerRegistry from '../../redux/StateListenerRegistry';
// eslint-disable-next-line lines-around-comment
// @ts-ignore
import SoundCollection from '../../sounds/components/SoundCollection';
import { createDeferred } from '../../util/helpers';
import { appWillMount, appWillUnmount } from '../actions';

View File

@@ -1,3 +1,3 @@
import { IReduxState, IStore } from '../../app/types';
export type IStateful = Function | IStore | IReduxState;
export type IStateful = (() => IReduxState) | IStore | IReduxState;

View File

@@ -1,3 +1,4 @@
import { IStateful } from '../app/types';
import { toState } from '../redux/functions';
import { StyleType } from '../styles/functions.any';
@@ -38,7 +39,7 @@ class ColorSchemeRegistry {
* want to retrieve.
* @returns {StyleType}
*/
get(stateful: Object | Function, componentName: string): StyleType {
get(stateful: IStateful, componentName: string): StyleType {
let schemedStyle = this._schemedStyles.get(componentName);
if (!schemedStyle) {
@@ -85,7 +86,7 @@ class ColorSchemeRegistry {
* @returns {StyleType}
*/
_applyColorScheme(
stateful: Object | Function,
stateful: IStateful,
componentName: string,
style: StyleType): StyleType {
let schemedStyle: any;
@@ -144,18 +145,15 @@ class ColorSchemeRegistry {
* @returns {string}
*/
_getColor(
stateful: Object | Function,
stateful: IStateful,
componentName: string,
colorDefinition: string): string {
// @ts-ignore
const colorScheme = toState(stateful)['features/base/color-scheme'] || {};
return {
...defaultScheme._defaultTheme,
...colorScheme._defaultTheme,
// @ts-ignore
...defaultScheme[componentName],
...defaultScheme[componentName as keyof typeof defaultScheme],
...colorScheme[componentName]
}[colorDefinition];
}

View File

@@ -569,7 +569,6 @@ export function checkIfCanJoin() {
const replaceParticipant = getReplaceParticipant(getState());
// @ts-ignore
authRequired && dispatch(_conferenceWillJoin(authRequired));
authRequired?.join(password, replaceParticipant);
};

View File

@@ -130,6 +130,7 @@ export interface IConfig {
_screenshotHistoryRegionUrl?: string;
analytics?: {
amplitudeAPPKey?: string;
blackListedEvents?: string[];
disabled?: boolean;
googleAnalyticsTrackingId?: string;
matomoEndpoint?: string;
@@ -141,6 +142,7 @@ export interface IConfig {
rtcstatsSendSdp?: boolean;
rtcstatsUseLegacy?: boolean;
scriptURLs?: Array<string>;
whiteListedEvents?: string[];
};
apiLogLevels?: Array<'warn' | 'log' | 'error' | 'info' | 'debug'>;
appId?: string;
@@ -223,6 +225,9 @@ export interface IConfig {
defaultLogoUrl?: string;
defaultRemoteDisplayName?: string;
deploymentInfo?: {
envType?: string;
environment?: string;
product?: string;
region?: string;
shard?: string;
userRegion?: string;

View File

@@ -232,8 +232,6 @@ export function restoreConfig(baseURL: string) {
return undefined;
}
/* eslint-disable max-params */
/**
* Inspects the hash part of the location URI and overrides values specified
* there in the corresponding config objects given as the arguments. The syntax

View File

@@ -141,8 +141,6 @@ function _connectionWillConnect(connection: Object) {
};
}
/* eslint-disable @typescript-eslint/no-unused-vars */
/**
* Closes connection.
*

View File

@@ -1,12 +1,10 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
/**
* Checks whether the chrome extensions defined in the config file are installed or not.
*
* @param {Object} config - Objects containing info about the configured extensions.
* @param {Object} _config - Objects containing info about the configured extensions.
*
* @returns {Promise[]}
*/
export default function checkChromeExtensionsInstalled(config: any = {}) {
export default function checkChromeExtensionsInstalled(_config: any = {}) {
return Promise.resolve([]);
}

View File

@@ -1,7 +1,7 @@
import React, { useCallback } from 'react';
import { Container } from '../../react/components/index';
import { styleTypeToObject } from '../../styles/functions';
import { StyleType, styleTypeToObject } from '../../styles/functions';
interface IProps {
@@ -93,7 +93,7 @@ interface IProps {
/**
* Style object to be applied.
*/
style?: Object;
style?: StyleType;
/**
* TabIndex for the Icon.
@@ -144,8 +144,6 @@ export default function Icon(props: IProps) {
color: styleColor,
fontSize: styleSize,
...restStyle
// @ts-ignore
} = styleTypeToObject(style ?? {});
const calculatedColor = color ?? styleColor ?? DEFAULT_COLOR;
const calculatedSize = size ?? styleSize ?? DEFAULT_SIZE;

View File

@@ -64,7 +64,7 @@ export function validateLastNLimits(lastNLimits: any) {
* @returns {number|undefined} - A "last N" number if there was a corresponding "last N" value matched with the number
* of participants or {@code undefined} otherwise.
*/
export function limitLastN(participantsCount: number, lastNLimits: Map<number, number>) {
export function limitLastN(participantsCount: number, lastNLimits?: Map<number, number>) {
if (!lastNLimits || !lastNLimits.keys) {
return undefined;
}

View File

@@ -59,7 +59,6 @@ const _updateLastN = debounce(({ dispatch, getState }: IStore) => {
let lastNSelected = config.startLastN ?? (config.channelLastN ?? -1);
// Apply last N limit based on the # of participants and config settings.
// @ts-ignore
const limitedLastN = limitLastN(participantCount, lastNLimits);
if (limitedLastN !== undefined) {

View File

@@ -10,9 +10,7 @@ import { validateLastNLimits } from './functions';
export interface ILastNState {
lastN?: number;
lastNLimits?: {
[key: number]: number;
};
lastNLimits?: Map<number, number>;
}
ReducerRegistry.register<ILastNState>('features/base/lastn', (state = {}, action): ILastNState => {

View File

@@ -17,7 +17,7 @@ export type AudioElement = {
/**
* {@code AbstractAudio} Component's property types.
*/
interface IProps {
export interface IProps {
loop?: boolean;
@@ -35,7 +35,7 @@ interface IProps {
*
* @type {Object | string}
*/
src: Object | string;
src: any | string;
stream?: Object;
}
@@ -48,7 +48,7 @@ export default class AbstractAudio extends Component<IProps> {
* The {@link AudioElement} instance which implements the audio playback
* functionality.
*/
_audioElementImpl: AudioElement | undefined;
_audioElementImpl?: AudioElement | null;
/**
* Initializes a new {@code AbstractAudio} instance.
@@ -69,7 +69,7 @@ export default class AbstractAudio extends Component<IProps> {
* @public
* @returns {void}
*/
pause(): void {
pause() {
this._audioElementImpl?.pause();
}
@@ -79,7 +79,7 @@ export default class AbstractAudio extends Component<IProps> {
* @public
* @returns {void}
*/
play(): void {
play() {
this._audioElementImpl?.play();
}
@@ -92,10 +92,9 @@ export default class AbstractAudio extends Component<IProps> {
* @protected
* @returns {void}
*/
setAudioElementImpl(element?: AudioElement): void {
setAudioElementImpl(element?: AudioElement | null) {
this._audioElementImpl = element;
// setRef
const { setRef } = this.props;
typeof setRef === 'function' && setRef(element ? this : null);
@@ -108,7 +107,7 @@ export default class AbstractAudio extends Component<IProps> {
* @param {string} sinkId - The sink ID (output device ID).
* @returns {void}
*/
setSinkId(sinkId: string): void {
setSinkId(sinkId: string) {
this._audioElementImpl
&& typeof this._audioElementImpl.setSinkId === 'function'
&& this._audioElementImpl.setSinkId(sinkId)
@@ -121,7 +120,7 @@ export default class AbstractAudio extends Component<IProps> {
* @public
* @returns {void}
*/
stop(): void {
stop() {
this._audioElementImpl?.stop();
}
}

View File

@@ -1,5 +0,0 @@
// @flow
import Audio from './native/Audio';
export default Audio;

View File

@@ -1,5 +0,0 @@
// @flow
import Audio from './web/Audio';
export default Audio;

View File

@@ -1,5 +0,0 @@
// @flow
import Video from './native/Video';
export default Video;

View File

@@ -1,4 +0,0 @@
// @ts-ignore
import Video from './web/Video';
export default Video;

View File

@@ -1,5 +1,2 @@
// @ts-ignore
export { default as Audio } from './web/Audio';
// @ts-ignore
export { default as Video } from './web/Video';

View File

@@ -1,9 +1,6 @@
// @flow
import React from 'react';
import AbstractAudio from '../AbstractAudio';
import type { AudioElement } from '../AbstractAudio';
import AbstractAudio, { IProps } from '../AbstractAudio';
/**
* The React/Web {@link Component} which is similar to and wraps around
@@ -18,7 +15,7 @@ export default class Audio extends AbstractAudio {
/**
* Reference to the HTML audio element, stored until the file is ready.
*/
_ref: ?AudioElement;
_ref?: HTMLAudioElement | null;
/**
* Creates new <code>Audio</code> element instance with given props.
@@ -26,12 +23,12 @@ export default class Audio extends AbstractAudio {
* @param {Object} props - The read-only properties with which the new
* instance is to be initialized.
*/
constructor(props: Object) {
constructor(props: IProps) {
super(props);
// Bind event handlers so they are only bound once for every instance.
this._onCanPlayThrough = this._onCanPlayThrough.bind(this);
this._setRef = this._setRef.bind(this);
this._setRef = this._setRef?.bind(this);
}
/**
@@ -46,8 +43,6 @@ export default class Audio extends AbstractAudio {
loop = { Boolean(this.props.loop) }
onCanPlayThrough = { this._onCanPlayThrough }
preload = 'auto'
// $FlowFixMe
ref = { this._setRef }
src = { this.props.src } />
);
@@ -61,8 +56,6 @@ export default class Audio extends AbstractAudio {
stop() {
if (this._ref) {
this._ref.pause();
// $FlowFixMe
this._ref.currentTime = 0;
}
}
@@ -81,8 +74,6 @@ export default class Audio extends AbstractAudio {
}
}
_onCanPlayThrough: () => void;
/**
* Called when 'canplaythrough' event is triggered on the audio element,
* which means that the whole file has been loaded.
@@ -95,8 +86,6 @@ export default class Audio extends AbstractAudio {
this._maybeSetAudioElementImpl();
}
_setRef: (?AudioElement) => void;
/**
* Sets the reference to the HTML audio element.
*
@@ -104,7 +93,7 @@ export default class Audio extends AbstractAudio {
* @private
* @returns {void}
*/
_setRef(audioElement: ?AudioElement) {
_setRef(audioElement?: HTMLAudioElement | null) {
this._ref = audioElement;
if (audioElement) {

View File

@@ -1,149 +1,179 @@
/* @flow */
import React, { Component, ReactEventHandler } from 'react';
import React, { Component } from 'react';
import { ITrack } from '../../../tracks/types';
/**
* The type of the React {@code Component} props of {@link Video}.
*/
type Props = {
interface IProps {
/**
* Used to determine the value of the autoplay attribute of the underlying
* video element.
*/
autoPlay: boolean;
/**
* CSS classes to add to the video element.
*/
className: string,
className: string;
/**
* A map of the event handlers for the video HTML element.
*/
eventHandlers?: {
/**
* OnAbort event handler.
*/
onAbort?: ReactEventHandler<HTMLVideoElement>;
/**
* OnCanPlay event handler.
*/
onCanPlay?: ReactEventHandler<HTMLVideoElement>;
/**
* OnCanPlayThrough event handler.
*/
onCanPlayThrough?: ReactEventHandler<HTMLVideoElement>;
/**
* OnEmptied event handler.
*/
onEmptied?: ReactEventHandler<HTMLVideoElement>;
/**
* OnEnded event handler.
*/
onEnded?: ReactEventHandler<HTMLVideoElement>;
/**
* OnError event handler.
*/
onError?: ReactEventHandler<HTMLVideoElement>;
/**
* OnLoadStart event handler.
*/
onLoadStart?: ReactEventHandler<HTMLVideoElement>;
/**
* OnLoadedData event handler.
*/
onLoadedData?: ReactEventHandler<HTMLVideoElement>;
/**
* OnLoadedMetadata event handler.
*/
onLoadedMetadata?: ReactEventHandler<HTMLVideoElement>;
/**
* OnPause event handler.
*/
onPause?: ReactEventHandler<HTMLVideoElement>;
/**
* OnPlay event handler.
*/
onPlay?: ReactEventHandler<HTMLVideoElement>;
/**
* OnPlaying event handler.
*/
onPlaying?: ReactEventHandler<HTMLVideoElement>;
/**
* OnRateChange event handler.
*/
onRateChange?: ReactEventHandler<HTMLVideoElement>;
/**
* OnStalled event handler.
*/
onStalled?: ReactEventHandler<HTMLVideoElement>;
/**
* OnSuspend event handler.
*/
onSuspend?: ReactEventHandler<HTMLVideoElement>;
/**
* OnWaiting event handler.
*/
onWaiting?: ReactEventHandler<HTMLVideoElement>;
};
/**
* The value of the id attribute of the video. Used by the torture tests to
* locate video elements.
*/
id: string,
id: string;
/**
* Optional callback to invoke once the video starts playing.
* Used on native.
*/
onVideoPlaying?: Function,
/**
* The JitsiLocalTrack to display.
*/
videoTrack: ?Object,
/**
* Used to determine the value of the autoplay attribute of the underlying
* video element.
*/
autoPlay: boolean,
/**
* Used to determine the value of the autoplay attribute of the underlying
* video element.
*/
playsinline: boolean,
/**
* A map of the event handlers for the video HTML element.
*/
eventHandlers?: {|
/**
* OnAbort event handler.
*/
onAbort?: ?Function,
/**
* OnCanPlay event handler.
*/
onCanPlay?: ?Function,
/**
* OnCanPlayThrough event handler.
*/
onCanPlayThrough?: ?Function,
/**
* OnEmptied event handler.
*/
onEmptied?: ?Function,
/**
* OnEnded event handler.
*/
onEnded?: ?Function,
/**
* OnError event handler.
*/
onError?: ?Function,
/**
* OnLoadedData event handler.
*/
onLoadedData?: ?Function,
/**
* OnLoadedMetadata event handler.
*/
onLoadedMetadata?: ?Function,
/**
* OnLoadStart event handler.
*/
onLoadStart?: ?Function,
/**
* OnPause event handler.
*/
onPause?: ?Function,
/**
* OnPlay event handler.
*/
onPlay?: ?Function,
/**
* OnPlaying event handler.
*/
onPlaying?: ?Function,
/**
* OnRateChange event handler.
*/
onRateChange?: ?Function,
/**
* OnStalled event handler.
*/
onStalled?: ?Function,
/**
* OnSuspend event handler.
*/
onSuspend?: ?Function,
/**
* OnWaiting event handler.
*/
onWaiting?: ?Function
|},
/**
* A styles that will be applied on the video element.
*/
style?: Object,
mirror?: boolean;
/**
* The value of the muted attribute for the underlying video element.
*/
muted?: boolean
};
muted?: boolean;
/**
* Used on native.
*/
onPlaying?: Function;
/**
* Used on native.
*/
onPress?: Function;
/**
* Optional callback to invoke once the video starts playing.
*/
onVideoPlaying?: Function;
/**
* Used to determine the value of the autoplay attribute of the underlying
* video element.
*/
playsinline: boolean;
/**
* Used on native.
*/
stream?: any;
/**
* A styles that will be applied on the video element.
*/
style?: Object;
/**
* The JitsiLocalTrack to display.
*/
videoTrack?: Partial<ITrack>;
/**
* Used on native.
*/
zOrder?: number;
/**
* Used on native.
*/
zoomEnabled?: boolean;
}
/**
* Component that renders a video element for a passed in video track.
*
* @augments Component
*/
class Video extends Component<Props> {
_videoElement: ?Object;
class Video extends Component<IProps> {
_videoElement?: HTMLVideoElement | null;
_mounted: boolean;
/**
@@ -164,7 +194,7 @@ class Video extends Component<Props> {
* @param {Object} props - The read-only properties with which the new
* instance is to be initialized.
*/
constructor(props: Props) {
constructor(props: IProps) {
super(props);
/**
@@ -235,11 +265,9 @@ class Video extends Component<Props> {
* @returns {boolean} - False is always returned to blackbox this component
* from React.
*/
shouldComponentUpdate(nextProps: Props) {
const currentJitsiTrack = this.props.videoTrack
&& this.props.videoTrack.jitsiTrack;
const nextJitsiTrack = nextProps.videoTrack
&& nextProps.videoTrack.jitsiTrack;
shouldComponentUpdate(nextProps: IProps) {
const currentJitsiTrack = this.props.videoTrack?.jitsiTrack;
const nextJitsiTrack = nextProps.videoTrack?.jitsiTrack;
if (currentJitsiTrack !== nextJitsiTrack) {
this._detachTrack(this.props.videoTrack);
@@ -292,7 +320,7 @@ class Video extends Component<Props> {
* @private
* @returns {void}
*/
_attachTrack(videoTrack) {
_attachTrack(videoTrack?: Partial<ITrack>) {
if (!videoTrack || !videoTrack.jitsiTrack) {
return;
}
@@ -310,14 +338,12 @@ class Video extends Component<Props> {
* @private
* @returns {void}
*/
_detachTrack(videoTrack) {
_detachTrack(videoTrack?: Partial<ITrack>) {
if (this._videoElement && videoTrack && videoTrack.jitsiTrack) {
videoTrack.jitsiTrack.detach(this._videoElement);
}
}
_onVideoPlaying: () => void;
/**
* Invokes the onvideoplaying callback if defined.
*
@@ -330,8 +356,6 @@ class Video extends Component<Props> {
}
}
_setVideoElement: () => void;
/**
* Sets an instance variable for the component's video element so it can be
* referenced later for attaching and detaching a JitsiLocalTrack.
@@ -340,7 +364,7 @@ class Video extends Component<Props> {
* @private
* @returns {void}
*/
_setVideoElement(element) {
_setVideoElement(element: HTMLVideoElement | null) {
this._videoElement = element;
}
}

View File

@@ -19,11 +19,11 @@ export const MEDIA_TYPE: {
AUDIO: MediaType;
SCREENSHARE: MediaType;
VIDEO: MediaType;
} = {
AUDIO: 'audio',
SCREENSHARE: 'screenshare',
VIDEO: 'video'
};
} = {
AUDIO: 'audio',
SCREENSHARE: 'screenshare',
VIDEO: 'video'
};
/* eslint-disable no-bitwise */

View File

@@ -35,8 +35,7 @@ export default class NetworkInfoService extends EventEmitter {
* @returns {boolean}
*/
static isSupported() {
// @ts-ignore
return window.addEventListener && typeof navigator.onLine !== 'undefined';
return Boolean(window.addEventListener) && typeof navigator.onLine !== 'undefined';
}
/**

View File

@@ -14,7 +14,6 @@ import type { NetworkInfo } from './types';
* @param {Store} store - The redux store.
* @returns {Function}
*/
// eslint-disable-next-line no-unused-vars
MiddlewareRegistry.register(({ dispatch, getState }) => next => action => {
const result = next(action);

View File

@@ -27,7 +27,7 @@ import { FakeParticipant, IJitsiParticipant, IParticipant, ISourceInfo } from '.
*/
const AVATAR_QUEUE: Object[] = [];
const AVATAR_CHECKED_URLS = new Map();
/* eslint-disable arrow-body-style, no-unused-vars */
/* eslint-disable arrow-body-style */
const AVATAR_CHECKER_FUNCTIONS = [
(participant: IParticipant) => {
return participant?.isJigasi ? JIGASI_PARTICIPANT_ICON : null;
@@ -53,7 +53,7 @@ const AVATAR_CHECKER_FUNCTIONS = [
return null;
}
];
/* eslint-enable arrow-body-style, no-unused-vars */
/* eslint-enable arrow-body-style */
/**
* Returns the list of active speakers that should be moved to the top of the sorted list of participants so that the

View File

@@ -548,11 +548,11 @@ function _localParticipantJoined({ getState, dispatch }: IStore, next: Function,
const settings = getState()['features/base/settings'];
// @ts-ignore
dispatch(localParticipantJoined({
avatarURL: settings.avatarURL,
email: settings.email,
name: settings.displayName
name: settings.displayName,
id: ''
}));
return result;

View File

@@ -11,7 +11,7 @@ import { isIconUrl } from './functions';
* @returns {Promise}
*/
export function preloadImage(
src: string | Object,
src: string,
useCORS = false,
tryOnce = false
): Promise<{ isUsingCORS?: boolean; src: string | Object; }> {
@@ -41,7 +41,6 @@ export function preloadImage(
image.referrerPolicy = 'no-referrer';
// @ts-ignore
image.src = src;
});
}

View File

@@ -190,8 +190,8 @@ class Popover extends Component<IProps, IState> {
* @param {MouseEvent} e - The click event.
* @returns {void}
*/
_onOutsideClick(e: React.MouseEvent) { // @ts-ignore
if (!this._containerRef?.current?.contains(e.target) && this.props.visible) {
_onOutsideClick(e: React.MouseEvent) {
if (!this._containerRef?.current?.contains(e.target as Node) && this.props.visible) {
this._onHideDialog();
}
}
@@ -303,8 +303,8 @@ class Popover extends Component<IProps, IState> {
if (this.props.visible
&& !this.props.overflowDrawer
&& this._contextMenuRef
&& this._contextMenuRef.contains // @ts-ignore
&& !this._contextMenuRef.contains(event.target)) {
&& this._contextMenuRef.contains
&& !this._contextMenuRef.contains(event.target as Node)) {
this._onHideDialog();
}
}

View File

@@ -1,6 +1,6 @@
import React, { Component, ReactNode } from 'react';
import { getFixedPlatformStyle } from '../../styles/functions';
import { StyleType, getFixedPlatformStyle } from '../../styles/functions';
/**
* {@code AbstractContainer} Component's property types.
@@ -40,7 +40,7 @@ export interface IProps {
* The style (as in stylesheet) to be applied to this
* {@code AbstractContainer}.
*/
style?: Array<string | undefined> | Object;
style?: StyleType;
/**
* If this instance is to provide visual feedback when touched, then
@@ -100,7 +100,6 @@ export default class AbstractContainer<P extends IProps> extends Component<P> {
...filteredProps
} = props || this.props;
// @ts-ignore
const _style = getFixedPlatformStyle(style);
return React.createElement(type, {

View File

@@ -1,5 +1,2 @@
/* eslint-disable lines-around-comment */
// @ts-ignore
export { default as Container } from './web/Container';
// @ts-ignore
export { default as Text } from './web/Text';

View File

@@ -1,10 +1,11 @@
import React from 'react';
import { GestureResponderEvent } from 'react-native';
export interface IIconButtonProps {
accessibilityLabel?: string;
color?: string;
disabled?: boolean;
onPress?: Function;
onPress?: (e?: GestureResponderEvent) => void;
size?: number | string;
src: Function;
style?: Object | undefined;

View File

@@ -1,6 +1,6 @@
import _ from 'lodash';
import { IReduxState } from '../../app/types';
import { IReduxState, IStore } from '../../app/types';
import { IStateful } from '../app/types';
/**
@@ -59,8 +59,6 @@ export function set<T extends Object>(state: T, property: keyof T, value: any):
return _set(state, property, value, /* copyOnWrite */ true);
}
/* eslint-disable max-params */
/**
* Sets a specific property of a specific state to a specific value. Prevents
* unnecessary state changes (when the specified {@code value} is equal to the
@@ -112,6 +110,16 @@ function _set<T extends Object>(
/* eslint-enable max-params */
/**
* Whether or not the entity is of type IStore.
*
* @param {IStateful} stateful - The entity to check.
* @returns {boolean}
*/
function isStore(stateful: IStateful): stateful is IStore {
return 'getState' in stateful && typeof stateful.getState === 'function';
}
/**
* Returns redux state from the specified {@code stateful} which is presumed to
* be related to the redux state (e.g. The redux store, the redux
@@ -128,14 +136,10 @@ export function toState(stateful: IStateful): IReduxState {
return stateful();
}
// @ts-ignore
const { getState } = stateful;
if (typeof getState === 'function') {
return getState();
if (isStore(stateful)) {
return stateful.getState();
}
}
// @ts-ignore
return stateful;
}

View File

@@ -1,35 +1,34 @@
// @flow
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { IReduxState, IStore } from '../../../app/types';
import { AudioElement } from '../../media/components/AbstractAudio';
import { Audio } from '../../media/components/index';
import { _addAudioElement, _removeAudioElement } from '../actions';
import type { Sound } from '../reducer';
import { Sound } from '../reducer';
/**
* {@link SoundCollection}'s properties.
*/
type Props = {
interface IProps {
/**
* Dispatches {@link _ADD_AUDIO_ELEMENT} Redux action which will store the
* {@link AudioElement} for a sound in the Redux store.
*/
_addAudioElement: Function,
_addAudioElement: Function;
/**
* Dispatches {@link _REMOVE_AUDIO_ELEMENT} Redux action which will remove
* the sound's {@link AudioElement} from the Redux store.
*/
_removeAudioElement: Function,
_removeAudioElement: Function;
/**
* It's the 'base/sounds' reducer's state mapped to a property. It's used to
* render audio elements for every registered sound.
*/
_sounds: Map<string, Sound>
_sounds: Map<string, Sound>;
}
/**
@@ -41,7 +40,7 @@ type Props = {
* state. When that happens the sound can be played using the {@link playSound}
* action.
*/
class SoundCollection extends Component<Props> {
class SoundCollection extends Component<IProps> {
/**
* Implements React's {@link Component#render()}.
*
@@ -58,10 +57,10 @@ class SoundCollection extends Component<Props> {
sounds.push(
React.createElement(
Audio, {
key,
key, // @ts-ignore
setRef: this._setRef.bind(this, soundId),
src,
loop: options.loop
loop: options?.loop
}));
key += 1;
}
@@ -80,7 +79,7 @@ class SoundCollection extends Component<Props> {
* @protected
* @returns {void}
*/
_setRef(soundId: string, element: ?AudioElement) {
_setRef(soundId: string, element?: AudioElement) {
if (element) {
this.props._addAudioElement(soundId, element);
} else {
@@ -98,7 +97,7 @@ class SoundCollection extends Component<Props> {
* _sounds: Map<string, Sound>
* }}
*/
function _mapStateToProps(state) {
function _mapStateToProps(state: IReduxState) {
return {
_sounds: state['features/base/sounds']
};
@@ -114,7 +113,7 @@ function _mapStateToProps(state) {
* _removeAudioElement: void
* }}
*/
export function _mapDispatchToProps(dispatch: Function) {
export function _mapDispatchToProps(dispatch: IStore['dispatch']) {
return {
/**
* Dispatches action to store the {@link AudioElement} for

View File

@@ -24,7 +24,9 @@ export type Sound = {
/**
* This field is container for all optional parameters related to the sound.
*/
options?: Object;
options?: {
loop: boolean;
};
/**
* This field describes the source of the audio resource to be played. It

View File

@@ -9,8 +9,8 @@ export * from './functions.any';
* @param {StyleType} style - The passed style prop to the component.
* @returns {StyleType}
*/
export function getFixedPlatformStyle(style: StyleType): StyleType {
export function getFixedPlatformStyle(style?: StyleType): StyleType {
// There is nothing to do on mobile - yet.
return style;
return style ?? {};
}

View File

@@ -16,8 +16,6 @@ import { getLocalDesktopTrack, getTrackState, isLocalVideoTrackDesktop } from '.
export * from './actions.any';
/* eslint-disable @typescript-eslint/no-unused-vars */
/**
* Signals that the local participant is ending screensharing or beginning the screensharing flow.
*
@@ -44,8 +42,6 @@ export function toggleScreensharing(enabled: boolean, _ignore1?: boolean, _ignor
};
}
/* eslint-enable @typescript-eslint/no-unused-vars */
/**
* Creates desktop track and replaces the local one.
*

View File

@@ -1,4 +1,3 @@
/* eslint-disable lines-around-comment */
// @ts-expect-error
import { AUDIO_ONLY_SCREEN_SHARE_NO_TRACK } from '../../../../modules/UI/UIErrors';
import { IReduxState, IStore } from '../../app/types';
@@ -11,13 +10,13 @@ import { setScreenAudioShareState, setScreenshareAudioTrack } from '../../screen
import { isAudioOnlySharing, isScreenVideoShared } from '../../screen-share/functions';
import { toggleScreenshotCaptureSummary } from '../../screenshot-capture/actions';
import { isScreenshotCaptureEnabled } from '../../screenshot-capture/functions';
// eslint-disable-next-line lines-around-comment
// @ts-ignore
import { AudioMixerEffect } from '../../stream-effects/audio-mixer/AudioMixerEffect';
import { getCurrentConference } from '../conference/functions';
import { JitsiTrackErrors, JitsiTrackEvents } from '../lib-jitsi-meet';
import { setScreenshareMuted } from '../media/actions';
import { MEDIA_TYPE, VIDEO_TYPE } from '../media/constants';
/* eslint-enable lines-around-comment */
import {
addLocalTrack,

View File

@@ -54,8 +54,6 @@ const IconButton: React.FC<IIconButtonProps> = ({
<TouchableRipple
accessibilityLabel = { accessibilityLabel }
disabled = { disabled }
// @ts-ignore
onPress = { onPress }
rippleColor = { rippleColor }
style = { [

View File

@@ -1,5 +1,3 @@
/* eslint-disable lines-around-comment */
import React, { forwardRef, useCallback, useState } from 'react';
import {
KeyboardTypeOptions,
@@ -24,7 +22,7 @@ import styles from './inputStyles';
interface IProps extends IInputProps {
accessibilityLabel?: any;
autoCapitalize?: string | undefined;
autoCapitalize?: 'none' | 'sentences' | 'words' | 'characters' | undefined;
autoFocus?: boolean;
blurOnSubmit?: boolean | undefined;
customStyles?: ICustomStyles;
@@ -117,7 +115,6 @@ const Input = forwardRef<TextInput, IInputProps>(({
style = { styles.icon } />}
<TextInput
accessibilityLabel = { accessibilityLabel }
// @ts-ignore
autoCapitalize = { autoCapitalize }
autoComplete = { 'off' }
autoCorrect = { false }
@@ -126,6 +123,8 @@ const Input = forwardRef<TextInput, IInputProps>(({
editable = { !disabled }
keyboardType = { keyboardType }
maxLength = { maxLength }
// @ts-ignore
minHeight = { minHeight }
multiline = { multiline }
numberOfLines = { numberOfLines }

View File

@@ -34,8 +34,6 @@ export function createWebTheme({ font, colors, colorMap, shape, spacing, typogra
spacing,
palette: createColorTokens(colorMap, colors),
shape,
// @ts-ignore
typography: {
// @ts-ignore
font,

View File

@@ -1,5 +1,3 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { Linking } from 'react-native';
import logger from './logger';

View File

@@ -42,11 +42,11 @@ export function parseURLParams(
}
}
paramParts.forEach(part => {
paramParts.forEach((part: string) => {
const param = part.split('=');
const key = param[0];
if (!key || key.split('.').some(k => blacklist.includes(k))) {
if (!key || key.split('.').some((k: string) => blacklist.includes(k))) {
return;
}

View File

@@ -263,7 +263,6 @@ export function parseStandardURIString(str: string) {
authority = authority.substring(userinfoEndIndex + 1);
}
// @ts-ignore
obj.host = authority;
// port

View File

@@ -266,7 +266,7 @@ export function moveToRoom(roomId?: string) {
* @param {string} participantId - ID of the given participant.
* @returns {string|undefined} - The participant connection JID if found.
*/
function _findParticipantJid(getState: Function, participantId: string) {
function _findParticipantJid(getState: IStore['getState'], participantId: string) {
const conference = getCurrentConference(getState);
if (!conference) {

View File

@@ -10,7 +10,6 @@ import Button from '../../../base/ui/components/web/Button';
import Input from '../../../base/ui/components/web/Input';
import { areSmileysDisabled } from '../../functions';
// @ts-ignore
import SmileysPanel from './SmileysPanel';
/**

View File

@@ -8,7 +8,6 @@ import { updateSettings } from '../../../base/settings/actions';
import Button from '../../../base/ui/components/web/Button';
import Input from '../../../base/ui/components/web/Input';
// @ts-ignore
import KeyboardAvoider from './KeyboardAvoider';
/**

View File

@@ -1,5 +1,3 @@
// @flow
import React, { useEffect, useState } from 'react';
import { isIosMobileBrowser } from '../../../base/environment/utils';

View File

@@ -1,5 +1,3 @@
// @flow
import React, { PureComponent } from 'react';
import Emoji from 'react-emoji-render';
@@ -8,28 +6,28 @@ import { smileys } from '../../smileys';
/**
* The type of the React {@code Component} props of {@link SmileysPanel}.
*/
type Props = {
interface IProps {
/**
* Callback to invoke when a smiley is selected. The smiley will be passed
* back.
*/
onSmileySelect: Function
};
onSmileySelect: Function;
}
/**
* Implements a React Component showing smileys that can be be shown in chat.
*
* @augments Component
*/
class SmileysPanel extends PureComponent<Props> {
class SmileysPanel extends PureComponent<IProps> {
/**
* Initializes a new {@code SmileysPanel} instance.
*
* @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 handler so it is only bound once for every instance.
@@ -38,8 +36,6 @@ class SmileysPanel extends PureComponent<Props> {
this._onEscKey = this._onEscKey.bind(this);
}
_onEscKey: (Object) => void;
/**
* KeyPress handler for accessibility.
*
@@ -47,7 +43,7 @@ class SmileysPanel extends PureComponent<Props> {
*
* @returns {void}
*/
_onEscKey(e) {
_onEscKey(e: React.KeyboardEvent) {
// Escape handling does not work in onKeyPress
if (e.key === 'Escape') {
e.preventDefault();
@@ -56,8 +52,6 @@ class SmileysPanel extends PureComponent<Props> {
}
}
_onKeyPress: (Object) => void;
/**
* KeyPress handler for accessibility.
*
@@ -65,15 +59,13 @@ class SmileysPanel extends PureComponent<Props> {
*
* @returns {void}
*/
_onKeyPress(e) {
_onKeyPress(e: React.KeyboardEvent<HTMLDivElement>) {
if (e.key === ' ') {
e.preventDefault();
e.preventDefault(); // @ts-ignore
this.props.onSmileySelect(e.target.id && smileys[e.target.id]);
}
}
_onClick: (Object) => void;
/**
* Click handler for to select emoji.
*
@@ -81,9 +73,9 @@ class SmileysPanel extends PureComponent<Props> {
*
* @returns {void}
*/
_onClick(e) {
_onClick(e: React.MouseEvent) {
e.preventDefault();
this.props.onSmileySelect(e.currentTarget.id && smileys[e.currentTarget.id]);
this.props.onSmileySelect(e.currentTarget.id && smileys[e.currentTarget.id as keyof typeof smileys]);
}
/**
@@ -105,7 +97,7 @@ class SmileysPanel extends PureComponent<Props> {
tabIndex = { 0 }>
<Emoji
onlyEmojiClassName = 'smiley'
text = { smileys[smileyKey] } />
text = { smileys[smileyKey as keyof typeof smileys] } />
</div>
));

View File

@@ -30,7 +30,6 @@ import AbstractConnectionIndicator, {
mapStateToProps as _abstractMapStateToProps
} from '../AbstractConnectionIndicator';
// @ts-ignore
import ConnectionIndicatorContent from './ConnectionIndicatorContent';
// eslint-disable-next-line lines-around-comment
// @ts-ignore
@@ -247,8 +246,6 @@ class ConnectionIndicator extends AbstractConnectionIndicator<IProps, IState> {
onPopoverClose = { this._onHidePopover }
onPopoverOpen = { this._onShowPopover }
position = { statsPopoverPosition }
// @ts-ignore
visible = { this.state.popoverVisible }>
{ this._renderIndicator() }
</Popover>

View File

@@ -2,9 +2,7 @@ import React, { Component } from 'react';
import { WithTranslation } from 'react-i18next';
import { translate } from '../../base/i18n/functions';
// eslint-disable-next-line lines-around-comment
// @ts-ignore
import Audio from '../../base/media/components/Audio.web';
import { Audio } from '../../base/media/components/index';
import Button from '../../base/ui/components/web/Button';
import { BUTTON_TYPES } from '../../base/ui/constants.any';
@@ -130,7 +128,7 @@ class AudioOutputPreview extends Component<IProps> {
*/
_setAudioSink() {
this._audioElement
&& this.props.deviceId // @ts-ignore
&& this.props.deviceId
&& this._audioElement.setSinkId(this.props.deviceId);
}
}

View File

@@ -1,7 +1,7 @@
import React from 'react';
import { makeStyles } from 'tss-react/mui';
import Video from '../../base/media/components/Video.web';
import { Video } from '../../base/media/components/index';
/**
* The type of the React {@code Component} props of {@link VideoInputPreview}.

View File

@@ -146,8 +146,7 @@ export function getSpaceUsage(token: string, appKey: string) {
* @returns {boolean}
*/
export function isEnabled(state: IReduxState) {
const { dropbox = {} } = state['features/base/config'];
const { dropbox = { appKey: undefined } } = state['features/base/config'];
// @ts-ignore
return typeof dropbox.appKey === 'string';
}

View File

@@ -131,7 +131,7 @@ interface IProps extends WithTranslation {
/**
* The participants in the call.
*/
_remoteParticipants: Array<Object>;
_remoteParticipants: Array<string>;
/**
* The length of the remote participants array.
@@ -596,7 +596,7 @@ class Filmstrip extends PureComponent <IProps, IState> {
* @param {Object} data - An object with the indexes identifying the ThumbnailWrapper instance.
* @returns {string} - The key.
*/
_gridItemKey({ columnIndex, rowIndex }: { columnIndex: number; rowIndex: number; }) {
_gridItemKey({ columnIndex, rowIndex }: { columnIndex: number; rowIndex: number; }): string {
const {
_disableSelfView,
_columns,
@@ -698,8 +698,6 @@ class Filmstrip extends PureComponent <IProps, IState> {
initialScrollLeft = { 0 }
initialScrollTop = { 0 }
itemData = {{ filmstripType }}
// @ts-ignore
itemKey = { this._gridItemKey }
onItemsRendered = { this._onGridItemsRendered }
overscanRowCount = { 1 }

View File

@@ -1264,12 +1264,16 @@ function _mapStateToProps(state: IReduxState, ownProps: any): Object {
case THUMBNAIL_TYPE.HORIZONTAL: {
const {
horizontalViewDimensions = {
local: {},
remote: {}
local: { width: undefined,
height: undefined },
remote: { width: undefined,
height: undefined }
},
verticalViewDimensions = {
local: {},
remote: {},
local: { width: undefined,
height: undefined },
remote: { width: undefined,
height: undefined },
gridView: {}
}
} = state['features/filmstrip'];
@@ -1278,8 +1282,8 @@ function _mapStateToProps(state: IReduxState, ownProps: any): Object {
= tileType === THUMBNAIL_TYPE.VERTICAL
? verticalViewDimensions : horizontalViewDimensions;
// @ts-ignore
const { width, height } = (isLocal ? local : remote) ?? {};
const { width, height } = (isLocal ? local : remote) ?? { width: undefined,
height: undefined };
size = {
_width: width,
@@ -1301,8 +1305,7 @@ function _mapStateToProps(state: IReduxState, ownProps: any): Object {
break;
}
case THUMBNAIL_TYPE.TILE: {
// @ts-ignore
const { thumbnailSize } = state['features/filmstrip'].tileViewDimensions;
const { thumbnailSize } = state['features/filmstrip'].tileViewDimensions ?? { thumbnailSize: undefined };
const {
stageFilmstripDimensions = {
thumbnailSize: {}

View File

@@ -393,7 +393,6 @@ const googleApi = {
});
},
/* eslint-disable max-params */
/**
* Updates the calendar event and adds a location and text.
*
@@ -435,7 +434,6 @@ const googleApi = {
});
},
/* eslint-enable max-params */
/**
* Returns the global Google API Client Library object. Direct use of this

View File

@@ -1,4 +1,3 @@
/* eslint-disable lines-around-comment */
import React, { useEffect } from 'react';
import { WithTranslation } from 'react-i18next';
import { connect } from 'react-redux';
@@ -28,10 +27,10 @@ import CopyMeetingLinkSection from './CopyMeetingLinkSection';
import DialInLimit from './DialInLimit';
import DialInSection from './DialInSection';
import InviteByEmailSection from './InviteByEmailSection';
// eslint-disable-next-line lines-around-comment
// @ts-ignore
import InviteContactsSection from './InviteContactsSection';
import LiveStreamSection from './LiveStreamSection';
/* eslint-enable lines-around-comment */
interface IProps extends WithTranslation {

View File

@@ -1,5 +1,3 @@
/* eslint-disable lines-around-comment */
import React, { Component } from 'react';
import { WithTranslation } from 'react-i18next';
import { Platform } from 'react-native';
@@ -12,6 +10,7 @@ import { areThereNotifications } from '../../functions';
import NotificationsTransition from '../NotificationsTransition';
import Notification from './Notification';
// eslint-disable-next-line lines-around-comment
// @ts-ignore
import styles from './styles';

View File

@@ -259,7 +259,6 @@ function _onMuteReactionsCommand(attributes: IMuteCommandAttributes = {}, id: st
const oldState = Boolean(state['features/base/conference'].startReactionsMuted);
// @ts-ignore
const newState = attributes.startReactionsMuted === 'true';
if (oldState !== newState) {

View File

@@ -18,11 +18,7 @@ import {
// eslint-disable-next-line lines-around-comment
// @ts-ignore
import GoogleSignInButton from '../../../../google-api/components/GoogleSignInButton.web';
import {
GOOGLE_API_STATES
// @ts-ignore
} from '../../../../google-api/constants';
import { GOOGLE_API_STATES } from '../../../../google-api/constants';
import AbstractStartLiveStreamDialog, {
IProps as AbstractProps,
_mapStateToProps as _abstractMapStateToProps

View File

@@ -9,8 +9,6 @@ import { maybeShowPremiumFeatureDialog } from '../../../jaas/actions';
import { hideNotification, showNotification } from '../../../notifications/actions';
import { NOTIFICATION_TIMEOUT_TYPE, NOTIFICATION_TYPE } from '../../../notifications/constants';
import { highlightMeetingMoment } from '../../actions.any';
// eslint-disable-next-line lines-around-comment
// @ts-ignore
import { PROMPT_RECORDING_NOTIFICATION_ID } from '../../constants';
import { getActiveSession, getRecordButtonProps, isHighlightMeetingMomentDisabled } from '../../functions';

View File

@@ -1,4 +1,3 @@
/* eslint-disable lines-around-comment */
import { Component } from 'react';
import { WithTranslation } from 'react-i18next';

View File

@@ -1,4 +1,3 @@
/* eslint-disable lines-around-comment */
import React from 'react';
import { connect } from 'react-redux';

View File

@@ -72,7 +72,6 @@ export const KEYS = {
PLUS: '+'
};
/* eslint-disable max-len */
/**
* Mapping between the key codes and keys defined in KEYS.
* The mappings are based on

View File

@@ -91,7 +91,7 @@ const SpeakerEntry = (props: IProps) => {
async function _onTestButtonClick(e: React.KeyboardEvent | React.MouseEvent) {
e.stopPropagation();
try { // @ts-ignore
try {
await audioRef.current?.setSinkId(props.deviceId);
audioRef.current?.play();
} catch (err) {

View File

@@ -5,7 +5,7 @@ import { connect } from 'react-redux';
import { IReduxState, IStore } from '../../../../app/types';
import { translate } from '../../../../base/i18n/functions';
import { IconImage } from '../../../../base/icons/svg';
import Video from '../../../../base/media/components/Video.web';
import { Video } from '../../../../base/media/components/index';
import { equals } from '../../../../base/redux/functions';
import { updateSettings } from '../../../../base/settings/actions';
import Checkbox from '../../../../base/ui/components/web/Checkbox';

View File

@@ -1,4 +1,3 @@
/* eslint-disable no-invalid-this */
// @ts-ignore
import Logger from '@jitsi/logger';
import throttle from 'lodash/throttle';

View File

@@ -27,7 +27,7 @@ import { isInBreakoutRoom } from '../../../breakout-rooms/functions';
*/
function HangupMenu() {
const dispatch = useDispatch();
const _styles: any = useSelector(state => ColorSchemeRegistry.get(state, 'Toolbox'));
const _styles: any = useSelector((state: IReduxState) => ColorSchemeRegistry.get(state, 'Toolbox'));
const inBreakoutRoom = useSelector(isInBreakoutRoom);
const isModerator = useSelector((state: IReduxState) =>
getLocalParticipant(state)?.role === PARTICIPANT_ROLE.MODERATOR);

View File

@@ -117,7 +117,12 @@ const styles = (theme: Theme) => {
* @augments Component
*/
class VideoQualitySlider extends Component<IProps> {
_sliderOptions: Array<Object>;
_sliderOptions: Array<{
audioOnly?: boolean;
onSelect: Function;
textKey: string;
videoQuality?: number;
}>;
/**
* Initializes a new {@code VideoQualitySlider} instance.
@@ -278,15 +283,14 @@ class VideoQualitySlider extends Component<IProps> {
if (_audioOnly) {
const audioOnlyOption = _sliderOptions.find(
({ audioOnly }: any) => audioOnly);
({ audioOnly }) => audioOnly);
// @ts-ignore
return _sliderOptions.indexOf(audioOnlyOption);
}
for (let i = 0; i < _sliderOptions.length; i++) {
// @ts-ignore
if (_sliderOptions[i].videoQuality >= _sendrecvVideoQuality) {
if (Number(_sliderOptions[i].videoQuality) >= _sendrecvVideoQuality) {
return i;
}
}

View File

@@ -7,7 +7,7 @@ import { connect } from 'react-redux';
import { IReduxState } from '../../app/types';
import { hideDialog } from '../../base/dialog/actions';
import { translate } from '../../base/i18n/functions';
import Video from '../../base/media/components/Video';
import { Video } from '../../base/media/components/index';
import { equals } from '../../base/redux/functions';
import { getCurrentCameraDeviceId } from '../../base/settings/functions.web';
import { createLocalTracksF } from '../../base/tracks/functions';

View File

@@ -1,6 +1,7 @@
import React from 'react';
import Icon from '../../base/icons/components/Icon';
import { StyleType } from '../../base/styles/functions.any';
import BaseTheme from '../../base/ui/components/BaseTheme';
import { INACTIVE_TAB_COLOR } from '../constants';
@@ -19,7 +20,7 @@ interface IProps {
/**
* The component's external style.
*/
style?: Object;
style?: StyleType;
}
const TabIcon = ({ focused, src, style }: IProps) => (