diff --git a/package-lock.json b/package-lock.json index 8920af9e9..003644747 100644 --- a/package-lock.json +++ b/package-lock.json @@ -147,6 +147,7 @@ "@types/js-md5": "0.4.3", "@types/lodash": "4.14.182", "@types/react": "17.0.14", + "@types/react-dom": "17.0.14", "@types/react-linkify": "1.0.1", "@types/react-native": "0.68.9", "@types/react-redux": "7.1.24", @@ -6532,6 +6533,15 @@ "csstype": "^3.0.2" } }, + "node_modules/@types/react-dom": { + "version": "17.0.14", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.14.tgz", + "integrity": "sha512-H03xwEP1oXmSfl3iobtmQ/2dHF5aBHr8aUMwyGZya6OW45G+xtdzmq6HkncefiBt5JU8DVyaWl/nWZbjZCnzAQ==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@types/react-is": { "version": "17.0.3", "resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-17.0.3.tgz", @@ -25267,6 +25277,15 @@ "csstype": "^3.0.2" } }, + "@types/react-dom": { + "version": "17.0.14", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.14.tgz", + "integrity": "sha512-H03xwEP1oXmSfl3iobtmQ/2dHF5aBHr8aUMwyGZya6OW45G+xtdzmq6HkncefiBt5JU8DVyaWl/nWZbjZCnzAQ==", + "dev": true, + "requires": { + "@types/react": "*" + } + }, "@types/react-is": { "version": "17.0.3", "resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-17.0.3.tgz", diff --git a/package.json b/package.json index 41bdf75dd..409ac63cd 100644 --- a/package.json +++ b/package.json @@ -152,6 +152,7 @@ "@types/js-md5": "0.4.3", "@types/lodash": "4.14.182", "@types/react": "17.0.14", + "@types/react-dom": "17.0.14", "@types/react-linkify": "1.0.1", "@types/react-native": "0.68.9", "@types/react-redux": "7.1.24", diff --git a/react/features/app/types.ts b/react/features/app/types.ts index 3c9591c88..53537d65c 100644 --- a/react/features/app/types.ts +++ b/react/features/app/types.ts @@ -90,6 +90,7 @@ export interface IReduxState { 'features/background': IBackgroundState; 'features/base/app': IAppState; 'features/base/audio-only': IAudioOnlyState; + 'features/base/color-scheme': any; 'features/base/conference': IConferenceState; 'features/base/config': IConfigState; 'features/base/connection': IConnectionState; diff --git a/react/features/authentication/middleware.web.ts b/react/features/authentication/middleware.web.ts index 68ea7a197..60649164c 100644 --- a/react/features/authentication/middleware.web.ts +++ b/react/features/authentication/middleware.web.ts @@ -24,9 +24,8 @@ import { openWaitForOwnerDialog, stopWaitForOwner } from './actions.web'; -// eslint-disable-next-line lines-around-comment -// @ts-ignore -import { LoginDialog, WaitForOwnerDialog } from './components'; +import LoginDialog from './components/web/LoginDialog'; +import WaitForOwnerDialog from './components/web/WaitForOwnerDialog'; /** * Middleware that captures connection or conference failed errors and controls diff --git a/react/features/base/color-scheme/ColorSchemeRegistry.js b/react/features/base/color-scheme/ColorSchemeRegistry.ts similarity index 95% rename from react/features/base/color-scheme/ColorSchemeRegistry.js rename to react/features/base/color-scheme/ColorSchemeRegistry.ts index cc1bcd8b9..9f6a84938 100644 --- a/react/features/base/color-scheme/ColorSchemeRegistry.js +++ b/react/features/base/color-scheme/ColorSchemeRegistry.ts @@ -1,7 +1,5 @@ -// @flow - -import { toState } from '../redux'; -import { StyleType } from '../styles'; +import { toState } from '../redux/functions'; +import { StyleType } from '../styles/functions.any'; import defaultScheme from './defaultScheme'; @@ -90,7 +88,7 @@ class ColorSchemeRegistry { stateful: Object | Function, componentName: string, style: StyleType): StyleType { - let schemedStyle; + let schemedStyle: any; if (Array.isArray(style)) { // The style is an array of styles, we apply the same transformation @@ -116,7 +114,7 @@ class ColorSchemeRegistry { // The value is another style object, we apply the same // transformation recursively. schemedStyle[styleName] - = this._applyColorScheme( + = this._applyColorScheme( // @ts-ignore stateful, componentName, styleValue); } else if (typeof styleValue === 'function') { // The value is a function, which indicates that it's a @@ -149,11 +147,14 @@ class ColorSchemeRegistry { stateful: Object | Function, componentName: string, colorDefinition: string): string { + // @ts-ignore const colorScheme = toState(stateful)['features/base/color-scheme'] || {}; return { ...defaultScheme._defaultTheme, ...colorScheme._defaultTheme, + + // @ts-ignore ...defaultScheme[componentName], ...colorScheme[componentName] }[colorDefinition]; diff --git a/react/features/base/color-scheme/defaultScheme.js b/react/features/base/color-scheme/defaultScheme.ts similarity index 86% rename from react/features/base/color-scheme/defaultScheme.js rename to react/features/base/color-scheme/defaultScheme.ts index dd0ab4c96..537d2584d 100644 --- a/react/features/base/color-scheme/defaultScheme.js +++ b/react/features/base/color-scheme/defaultScheme.ts @@ -1,4 +1,5 @@ -import { ColorPalette, getRGBAFormat } from '../styles'; +import { ColorPalette } from '../styles/components/styles/ColorPalette'; +import { getRGBAFormat } from '../styles/functions.any'; /** * The default color scheme of the application. diff --git a/react/features/base/color-scheme/functions.js b/react/features/base/color-scheme/functions.ts similarity index 97% rename from react/features/base/color-scheme/functions.js rename to react/features/base/color-scheme/functions.ts index fcf92b525..b8a437b83 100644 --- a/react/features/base/color-scheme/functions.js +++ b/react/features/base/color-scheme/functions.ts @@ -1,5 +1,3 @@ -// @flow - /** * A special function to be used in the {@code createColorSchemedStyle} call, * that denotes that the color is a dynamic color. diff --git a/react/features/base/dialog/functions.ts b/react/features/base/dialog/functions.ts index 2741c2aad..c2b7afe48 100644 --- a/react/features/base/dialog/functions.ts +++ b/react/features/base/dialog/functions.ts @@ -2,9 +2,7 @@ import { ComponentType } from 'react'; import { IReduxState } from '../../app/types'; import { IStateful } from '../app/types'; -// eslint-disable-next-line lines-around-comment -// @ts-ignore -import { ColorSchemeRegistry } from '../color-scheme'; +import ColorSchemeRegistry from '../color-scheme/ColorSchemeRegistry'; import { toState } from '../redux/functions'; /** @@ -28,7 +26,7 @@ export function isAnyDialogOpen(stateful: IStateful) { * {@code Dialog} to be checked. * @returns {boolean} */ -export function isDialogOpen(stateful: IStateful, component: ComponentType) { +export function isDialogOpen(stateful: IStateful, component: ComponentType) { return toState(stateful)['features/base/dialog'].component === component; } diff --git a/react/features/base/icons/components/Icon.tsx b/react/features/base/icons/components/Icon.tsx index a826e823f..f714883a6 100644 --- a/react/features/base/icons/components/Icon.tsx +++ b/react/features/base/icons/components/Icon.tsx @@ -2,9 +2,7 @@ import React, { useCallback } from 'react'; // @ts-ignore import { Container } from '../../react/base'; -// eslint-disable-next-line lines-around-comment -// @ts-ignore -import { styleTypeToObject } from '../../styles'; +import { styleTypeToObject } from '../../styles/functions'; interface IProps { @@ -141,6 +139,8 @@ 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; diff --git a/react/features/base/media/middleware.web.ts b/react/features/base/media/middleware.web.ts index 6fa532fd8..485c1803b 100644 --- a/react/features/base/media/middleware.web.ts +++ b/react/features/base/media/middleware.web.ts @@ -4,8 +4,6 @@ import { IStore } from '../../app/types'; import { showNotification } from '../../notifications/actions'; import { NOTIFICATION_TIMEOUT_TYPE } from '../../notifications/constants'; import LocalRecordingManager from '../../recording/components/Recording/LocalRecordingManager.web'; -// eslint-disable-next-line lines-around-comment -// @ts-ignore import StopRecordingDialog from '../../recording/components/Recording/web/StopRecordingDialog'; import { openDialog } from '../dialog/actions'; import MiddlewareRegistry from '../redux/MiddlewareRegistry'; diff --git a/react/features/base/net-info/NetworkInfoService.native.js b/react/features/base/net-info/NetworkInfoService.native.ts similarity index 91% rename from react/features/base/net-info/NetworkInfoService.native.js rename to react/features/base/net-info/NetworkInfoService.native.ts index 652b3e173..bf51059ed 100644 --- a/react/features/base/net-info/NetworkInfoService.native.js +++ b/react/features/base/net-info/NetworkInfoService.native.ts @@ -1,6 +1,7 @@ -// @flow import NetInfo from '@react-native-community/netinfo'; import type { NetInfoState, NetInfoSubscription } from '@react-native-community/netinfo'; +// eslint-disable-next-line lines-around-comment +// @ts-ignore import EventEmitter from 'events'; import { ONLINE_STATE_CHANGED_EVENT } from './events'; @@ -25,7 +26,10 @@ export default class NetworkInfoService extends EventEmitter { */ static _convertNetInfoState(netInfoState: NetInfoState): NetworkInfo { return { + // @ts-ignore isOnline: netInfoState.isInternetReachable, + + // @ts-ignore details: netInfoState.details, networkType: netInfoState.type }; @@ -47,6 +51,7 @@ export default class NetworkInfoService extends EventEmitter { */ start() { this._subscription = NetInfo.addEventListener(netInfoState => { + // @ts-ignore this.emit(ONLINE_STATE_CHANGED_EVENT, NetworkInfoService._convertNetInfoState(netInfoState)); }); } @@ -59,6 +64,8 @@ export default class NetworkInfoService extends EventEmitter { stop() { if (this._subscription) { this._subscription(); + + // @ts-ignore this._subscription = undefined; } } diff --git a/react/features/base/net-info/NetworkInfoService.web.js b/react/features/base/net-info/NetworkInfoService.web.ts similarity index 91% rename from react/features/base/net-info/NetworkInfoService.web.js rename to react/features/base/net-info/NetworkInfoService.web.ts index 50ac08fd3..b2517714f 100644 --- a/react/features/base/net-info/NetworkInfoService.web.js +++ b/react/features/base/net-info/NetworkInfoService.web.ts @@ -6,6 +6,8 @@ import { ONLINE_STATE_CHANGED_EVENT } from './events'; * The network info service implementation for web (Chrome, Firefox and Safari). */ export default class NetworkInfoService extends EventEmitter { + _onlineStateListener: any; + _offlineStateListener: any; /** * Creates new instance... @@ -23,7 +25,7 @@ export default class NetworkInfoService extends EventEmitter { * @private * @returns {void} */ - _handleOnlineStatusChange(isOnline) { + _handleOnlineStatusChange(isOnline: boolean) { this.emit(ONLINE_STATE_CHANGED_EVENT, { isOnline }); } @@ -33,6 +35,7 @@ export default class NetworkInfoService extends EventEmitter { * @returns {boolean} */ static isSupported() { + // @ts-ignore return window.addEventListener && typeof navigator.onLine !== 'undefined'; } diff --git a/react/features/base/net-info/middleware.ts b/react/features/base/net-info/middleware.ts index 5d7f49a27..f21db487c 100644 --- a/react/features/base/net-info/middleware.ts +++ b/react/features/base/net-info/middleware.ts @@ -1,7 +1,6 @@ import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../app/actionTypes'; import MiddlewareRegistry from '../redux/MiddlewareRegistry'; -// @ts-ignore import NetworkInfoService from './NetworkInfoService'; import { _storeNetworkInfoCleanup, setNetworkInfo } from './actions'; import { STORE_NAME } from './constants'; @@ -25,9 +24,12 @@ MiddlewareRegistry.register(({ dispatch, getState }) => next => action => { const networkInfoService = new NetworkInfoService(); const stop = () => { networkInfoService.stop(); + + // @ts-ignore networkInfoService.removeAllListeners(); }; + // @ts-ignore networkInfoService.addListener( ONLINE_STATE_CHANGED_EVENT, ({ isOnline, networkType, details }: NetworkInfo) => { diff --git a/react/features/base/participants/functions.ts b/react/features/base/participants/functions.ts index 4045711ef..e693b074a 100644 --- a/react/features/base/participants/functions.ts +++ b/react/features/base/participants/functions.ts @@ -19,8 +19,6 @@ import { PARTICIPANT_ROLE, WHITEBOARD_PARTICIPANT_ICON } from './constants'; -// eslint-disable-next-line lines-around-comment -// @ts-ignore import { preloadImage } from './preloadImage'; import { FakeParticipant, IJitsiParticipant, IParticipant, ISourceInfo } from './types'; diff --git a/react/features/base/participants/preloadImage.native.js b/react/features/base/participants/preloadImage.native.ts similarity index 75% rename from react/features/base/participants/preloadImage.native.js rename to react/features/base/participants/preloadImage.native.ts index 50ae5fa03..2357acda5 100644 --- a/react/features/base/participants/preloadImage.native.js +++ b/react/features/base/participants/preloadImage.native.ts @@ -1,6 +1,3 @@ - -// @flow - import { Image } from 'react-native'; import { isIconUrl } from './functions'; @@ -9,14 +6,16 @@ import { isIconUrl } from './functions'; * Tries to preload an image. * * @param {string | Object} src - Source of the avatar. + * @param {boolean} _isUsingCORS - Used on web. * @returns {Promise} */ -export function preloadImage(src: string | Object): Promise { +export function preloadImage(src: string | Object, _isUsingCORS: boolean): Promise { if (isIconUrl(src)) { return Promise.resolve(src); } return new Promise((resolve, reject) => { + // @ts-ignore Image.prefetch(src).then( () => resolve({ src, diff --git a/react/features/base/participants/preloadImage.web.js b/react/features/base/participants/preloadImage.web.ts similarity index 89% rename from react/features/base/participants/preloadImage.web.js rename to react/features/base/participants/preloadImage.web.ts index b39c61a47..b237185b2 100644 --- a/react/features/base/participants/preloadImage.web.js +++ b/react/features/base/participants/preloadImage.web.ts @@ -1,6 +1,4 @@ -// @flow - import { isIconUrl } from './functions'; /** @@ -14,9 +12,9 @@ import { isIconUrl } from './functions'; */ export function preloadImage( src: string | Object, - useCORS: ?boolean = false, - tryOnce: ?boolean = false -): Promise { + useCORS = false, + tryOnce = false +): Promise<{ isUsingCORS?: boolean; src: string | Object; }> { if (isIconUrl(src)) { return Promise.resolve({ src }); } @@ -41,8 +39,9 @@ export function preloadImage( } }; - // $FlowExpectedError image.referrerPolicy = 'no-referrer'; + + // @ts-ignore image.src = src; }); } diff --git a/react/features/base/popover/components/Popover.web.tsx b/react/features/base/popover/components/Popover.web.tsx index 9f43b938d..2d706743a 100644 --- a/react/features/base/popover/components/Popover.web.tsx +++ b/react/features/base/popover/components/Popover.web.tsx @@ -1,9 +1,9 @@ import React, { Component, ReactNode } from 'react'; import { IReduxState } from '../../../app/types'; -// eslint-disable-next-line lines-around-comment -// @ts-ignore -import { DialogPortal, Drawer, JitsiPortal } from '../../../toolbox/components/web'; +import DialogPortal from '../../../toolbox/components/web/DialogPortal'; +import Drawer from '../../../toolbox/components/web/Drawer'; +import JitsiPortal from '../../../toolbox/components/web/JitsiPortal'; import { isMobileBrowser } from '../../environment/utils'; import { connect } from '../../redux/functions'; import { getContextMenuStyle } from '../functions.web'; diff --git a/react/features/base/premeeting/components/web/PreMeetingScreen.tsx b/react/features/base/premeeting/components/web/PreMeetingScreen.tsx index e0b2edcf9..1c7a1f452 100644 --- a/react/features/base/premeeting/components/web/PreMeetingScreen.tsx +++ b/react/features/base/premeeting/components/web/PreMeetingScreen.tsx @@ -1,4 +1,3 @@ -/* eslint-disable lines-around-comment */ import clsx from 'clsx'; import React, { ReactNode } from 'react'; import { connect } from 'react-redux'; @@ -6,17 +5,16 @@ import { makeStyles } from 'tss-react/mui'; import { IReduxState } from '../../../../app/types'; import DeviceStatus from '../../../../prejoin/components/web/preview/DeviceStatus'; -// @ts-ignore -import { Toolbox } from '../../../../toolbox/components/web'; +import Toolbox from '../../../../toolbox/components/web/Toolbox'; import { getConferenceName } from '../../../conference/functions'; import { PREMEETING_BUTTONS, THIRD_PARTY_PREJOIN_BUTTONS } from '../../../config/constants'; import { getToolbarButtons, isToolbarButtonEnabled } from '../../../config/functions.web'; import { withPixelLineHeight } from '../../../styles/functions.web'; import ConnectionStatus from './ConnectionStatus'; +// eslint-disable-next-line lines-around-comment // @ts-ignore import Preview from './Preview'; -/* eslint-enable lines-around-comment */ interface IProps { diff --git a/react/features/base/react/components/AbstractContainer.js b/react/features/base/react/components/AbstractContainer.ts similarity index 79% rename from react/features/base/react/components/AbstractContainer.js rename to react/features/base/react/components/AbstractContainer.ts index 8f20b77b9..9ef32886a 100644 --- a/react/features/base/react/components/AbstractContainer.js +++ b/react/features/base/react/components/AbstractContainer.ts @@ -1,8 +1,6 @@ -/* @flow */ +import React, { Component, ReactNode } from 'react'; -import React, { Component } from 'react'; - -import { getFixedPlatformStyle } from '../../styles'; +import { getFixedPlatformStyle } from '../../styles/functions'; /** * {@code AbstractContainer} Component's property types. @@ -12,22 +10,22 @@ export type Props = { /** * An optional accessibility label to apply to the container root. */ - accessibilityLabel?: string, + accessibilityLabel?: string; /** * Whether or not this element is an accessibility element. */ - accessible?: boolean, + accessible?: boolean; /** * React Elements to display within the component. */ - children: React$Node, + children: ReactNode; /** * Class names of the component (for web). */ - className?: string, + className?: string; /** * The event handler/listener to be invoked when this @@ -36,13 +34,13 @@ export type Props = { * undefined, {@code touchFeedback} is considered defined as * {@code true}. */ - onClick?: ?Function, + onClick?: Function; /** * The style (as in stylesheet) to be applied to this * {@code AbstractContainer}. */ - style?: Array | Object, + style?: Array | Object; /** * If this instance is to provide visual feedback when touched, then @@ -50,19 +48,19 @@ export type Props = { * undefined and {@link onClick} is defined, {@code touchFeedback} is * considered defined as {@code true}. */ - touchFeedback?: ?Function, + touchFeedback?: Function; /** * Color to display when clicked. */ - underlayColor?: string, + underlayColor?: string; /** * If this {@code AbstractContainer} is to be visible, then {@code true} * or {@code false} if this instance is to be hidden or not rendered at * all. */ - visible?: ?boolean + visible?: boolean; }; /** @@ -71,7 +69,7 @@ export type Props = { * * @augments Component */ -export default class AbstractContainer extends Component

{ +export default class AbstractContainer

extends Component

{ /** * Renders this {@code AbstractContainer} as a React {@code Component} of a * specific type. @@ -84,12 +82,12 @@ export default class AbstractContainer extends Component

{ * @protected * @returns {ReactElement} */ - _render(type, props?: P) { + _render(type: string, props?: P) { const { children, style, - /* eslint-disable no-unused-vars */ + /* eslint-disable @typescript-eslint/no-unused-vars */ // The following properties are defined for the benefit of // AbstractContainer and its extenders so they are to not be @@ -97,14 +95,14 @@ export default class AbstractContainer extends Component

{ touchFeedback, visible, - /* eslint-enable no-unused-vars */ + /* eslint-enable @typescript-eslint/no-unused-vars */ ...filteredProps } = props || this.props; + // @ts-ignore const _style = getFixedPlatformStyle(style); - // $FlowFixMe return React.createElement(type, { style: _style, ...filteredProps diff --git a/react/features/base/react/components/web/Container.js b/react/features/base/react/components/web/Container.ts similarity index 66% rename from react/features/base/react/components/web/Container.js rename to react/features/base/react/components/web/Container.ts index 1350ae599..3649a9e88 100644 --- a/react/features/base/react/components/web/Container.js +++ b/react/features/base/react/components/web/Container.ts @@ -1,14 +1,11 @@ -/* @flow */ - -import AbstractContainer from '../AbstractContainer'; -import type { Props } from '../AbstractContainer'; +import AbstractContainer, { Props } from '../AbstractContainer'; /** * Represents a container of React/Web {@link Component} children with a style. * * @augments AbstractContainer */ -export default class Container extends AbstractContainer

{ +export default class Container

extends AbstractContainer

{ /** * Implements React's {@link Component#render()}. * diff --git a/react/features/base/styles/components/styles/BoxModel.js b/react/features/base/styles/components/styles/BoxModel.ts similarity index 100% rename from react/features/base/styles/components/styles/BoxModel.js rename to react/features/base/styles/components/styles/BoxModel.ts diff --git a/react/features/base/styles/functions.any.js b/react/features/base/styles/functions.any.ts similarity index 92% rename from react/features/base/styles/functions.any.js rename to react/features/base/styles/functions.any.ts index 3964240f5..aaac1059f 100644 --- a/react/features/base/styles/functions.any.js +++ b/react/features/base/styles/functions.any.ts @@ -1,9 +1,11 @@ -/* @flow */ import Platform from '../react/Platform'; -import { ColorPalette } from './components'; +import { ColorPalette } from './components/styles/ColorPalette'; + +declare type StyleSheet = { + [key: string]: string; +}; -declare type StyleSheet = Object; export type StyleType = StyleSheet | Array; /** @@ -44,7 +46,7 @@ const _WELL_KNOWN_NUMBER_PROPERTIES = [ 'height', 'width' ]; * @param {Styletype} st - The complex style type. * @returns {Object} */ -export function styleTypeToObject(st: StyleType): Object { +export function styleTypeToObject(st: StyleType): { [key: string]: string | number; } { if (!st) { return {}; } @@ -103,12 +105,15 @@ export function combineStyles(a: StyleType, b: StyleType): StyleType { */ export function createStyleSheet( styles: StyleSheet, overrides: StyleSheet = {}): StyleSheet { - const combinedStyles = {}; + const combinedStyles: any = {}; for (const k of Object.keys(styles)) { combinedStyles[k] = _shimStyles({ + // @ts-ignore ...styles[k], + + // @ts-ignore ...overrides[k] }); } @@ -126,9 +131,12 @@ export function createStyleSheet( * @public * @returns {StyleSheet} */ -export function fixAndroidViewClipping(styles: T): T { +export function fixAndroidViewClipping(styles: T): T { if (Platform.OS === 'android') { + // @ts-ignore styles.borderColor = ColorPalette.appBackground; + + // @ts-ignore styles.borderWidth = 1; } @@ -220,7 +228,7 @@ function _getColorLuminance(c: number): number { * b: number * }} */ -function _getRGBObjectFormat(color: string): {r: number, g: number, b: number} { +function _getRGBObjectFormat(color: string): { b: number; g: number; r: number; } { let match = color.match(HEX_LONG_COLOR_FORMAT); if (match) { @@ -265,7 +273,7 @@ function _getRGBObjectFormat(color: string): {r: number, g: number, b: number} { * @private * @returns {StyleSheet} */ -function _shimStyles(styles: T): T { +function _shimStyles(styles: T): T { // Certain style properties may not be numbers on Web but must be numbers on // React Native. For example, height and width may be expressed in percent // on Web but React Native will not understand them and we will get errors @@ -281,6 +289,7 @@ function _shimStyles(styles: T): T { if (Number.isNaN(numberV)) { delete styles[k]; } else { + // @ts-ignore styles[k] = numberV; } } diff --git a/react/features/base/styles/functions.native.js b/react/features/base/styles/functions.native.ts similarity index 86% rename from react/features/base/styles/functions.native.js rename to react/features/base/styles/functions.native.ts index 854d13472..93091e07b 100644 --- a/react/features/base/styles/functions.native.js +++ b/react/features/base/styles/functions.native.ts @@ -1,6 +1,4 @@ -// @flow - -import { type StyleType } from './functions.any'; +import { StyleType } from './functions.any'; export * from './functions.any'; diff --git a/react/features/base/styles/functions.web.ts b/react/features/base/styles/functions.web.ts index 0695b0336..83cd17a17 100644 --- a/react/features/base/styles/functions.web.ts +++ b/react/features/base/styles/functions.web.ts @@ -1,7 +1,5 @@ -// @ts-ignore import { StyleType } from './functions.any'; -// @ts-ignore export * from './functions.any'; /** diff --git a/react/features/base/tracks/actions.any.ts b/react/features/base/tracks/actions.any.ts index 6901e9936..bfc861531 100644 --- a/react/features/base/tracks/actions.any.ts +++ b/react/features/base/tracks/actions.any.ts @@ -159,7 +159,7 @@ export function createLocalTracksA(options: ITrackOptions = {}) { throw new Error(`Local track for ${device} already exists`); } - const gumProcess + const gumProcess: any = createLocalTracksF( { cameraDeviceId: options.cameraDeviceId, @@ -169,7 +169,7 @@ export function createLocalTracksA(options: ITrackOptions = {}) { micDeviceId: options.micDeviceId }, store) - .then( + .then( // @ts-ignore (localTracks: any[]) => { // Because GUM is called for 1 device (which is actually // a media type 'audio', 'video', 'screen', etc.) we diff --git a/react/features/base/tracks/actions.web.ts b/react/features/base/tracks/actions.web.ts index eb7b3cc7b..c7c28724a 100644 --- a/react/features/base/tracks/actions.web.ts +++ b/react/features/base/tracks/actions.web.ts @@ -6,7 +6,6 @@ import { shouldShowModeratedNotification } from '../../av-moderation/functions'; import { setNoiseSuppressionEnabled } from '../../noise-suppression/actions'; import { showNotification } from '../../notifications/actions'; import { NOTIFICATION_TIMEOUT_TYPE } from '../../notifications/constants'; -// @ts-ignore import { stopReceiver } from '../../remote-control/actions'; import { setScreenAudioShareState, setScreenshareAudioTrack } from '../../screen-share/actions'; import { isAudioOnlySharing, isScreenVideoShared } from '../../screen-share/functions'; diff --git a/react/features/base/tracks/functions.web.ts b/react/features/base/tracks/functions.web.ts index 41ccf989f..0b1d6a516 100644 --- a/react/features/base/tracks/functions.web.ts +++ b/react/features/base/tracks/functions.web.ts @@ -9,7 +9,6 @@ import { getUserSelectedMicDeviceId } from '../settings/functions.web'; -// @ts-ignore import loadEffects from './loadEffects'; import logger from './logger'; import { ITrackOptions } from './types'; diff --git a/react/features/base/tracks/loadEffects.native.js b/react/features/base/tracks/loadEffects.native.ts similarity index 50% rename from react/features/base/tracks/loadEffects.native.js rename to react/features/base/tracks/loadEffects.native.ts index 567b12a42..5d90617eb 100644 --- a/react/features/base/tracks/loadEffects.native.js +++ b/react/features/base/tracks/loadEffects.native.ts @@ -1,11 +1,9 @@ -// @flow - /** * Loads the enabled stream effects. * - * @param {Object} store - The Redux store. + * @param {Object} _store - The Redux store. * @returns {Promsie} - A Promise which resolves with an array of the loaded effects. */ -export default function loadEffects(store: Object): Promise> { // eslint-disable-line no-unused-vars +export default function loadEffects(_store: Object): Promise> { return Promise.resolve([]); } diff --git a/react/features/base/tracks/loadEffects.web.js b/react/features/base/tracks/loadEffects.web.ts similarity index 78% rename from react/features/base/tracks/loadEffects.web.js rename to react/features/base/tracks/loadEffects.web.ts index 2ba643c21..17d7023b1 100644 --- a/react/features/base/tracks/loadEffects.web.js +++ b/react/features/base/tracks/loadEffects.web.ts @@ -1,5 +1,6 @@ -// @flow - +import { IStore } from '../../app/types'; +// eslint-disable-next-line lines-around-comment +// @ts-ignore import { createVirtualBackgroundEffect } from '../../stream-effects/virtual-background'; import logger from './logger'; @@ -10,13 +11,13 @@ import logger from './logger'; * @param {Object} store - The Redux store. * @returns {Promsie} - A Promise which resolves when all effects are created. */ -export default function loadEffects(store: Object): Promise { +export default function loadEffects(store: IStore): Promise { const state = store.getState(); const virtualBackground = state['features/virtual-background']; const backgroundPromise = virtualBackground.backgroundEffectEnabled ? createVirtualBackgroundEffect(virtualBackground) - .catch(error => { + .catch((error: Error) => { logger.error('Failed to obtain the background effect instance with error: ', error); return Promise.resolve(); diff --git a/react/features/base/ui/components/web/ContextMenu.tsx b/react/features/base/ui/components/web/ContextMenu.tsx index b05dc9659..47666191f 100644 --- a/react/features/base/ui/components/web/ContextMenu.tsx +++ b/react/features/base/ui/components/web/ContextMenu.tsx @@ -2,9 +2,8 @@ import React, { ReactNode, useEffect, useLayoutEffect, useRef, useState } from ' import { useSelector } from 'react-redux'; import { makeStyles } from 'tss-react/mui'; -// eslint-disable-next-line lines-around-comment -// @ts-ignore -import { Drawer, JitsiPortal } from '../../../../toolbox/components/web'; +import Drawer from '../../../../toolbox/components/web/Drawer'; +import JitsiPortal from '../../../../toolbox/components/web/JitsiPortal'; import { showOverflowDrawer } from '../../../../toolbox/functions.web'; import participantsPaneTheme from '../../../components/themes/participantsPaneTheme.json'; import { withPixelLineHeight } from '../../../styles/functions.web'; @@ -202,7 +201,7 @@ const ContextMenu = ({ return _overflowDrawer ?

{ 'keyboardShortcuts.toggleFilmstrip' ); document.addEventListener('mouseup', this._onDragMouseUp); + // @ts-ignore document.addEventListener('mousemove', this._throttledResize); } @@ -319,6 +317,7 @@ class Filmstrip extends PureComponent { componentWillUnmount() { APP.keyboardshortcut.unregisterShortcut('F'); document.removeEventListener('mouseup', this._onDragMouseUp); + // @ts-ignore document.removeEventListener('mousemove', this._throttledResize); } @@ -694,6 +693,7 @@ class Filmstrip extends PureComponent { initialScrollLeft = { 0 } initialScrollTop = { 0 } itemData = {{ filmstripType }} + // @ts-ignore itemKey = { this._gridItemKey } onItemsRendered = { this._onGridItemsRendered } diff --git a/react/features/filmstrip/components/web/Thumbnail.tsx b/react/features/filmstrip/components/web/Thumbnail.tsx index 4785c2c70..5da3d6ef9 100644 --- a/react/features/filmstrip/components/web/Thumbnail.tsx +++ b/react/features/filmstrip/components/web/Thumbnail.tsx @@ -66,6 +66,7 @@ import ThumbnailBottomIndicators from './ThumbnailBottomIndicators'; import ThumbnailTopIndicators from './ThumbnailTopIndicators'; // @ts-ignore import VirtualScreenshareParticipant from './VirtualScreenshareParticipant'; +/* eslint-enable lines-around-comment */ /** * The type of the React {@code Component} state of {@link Thumbnail}. @@ -1218,6 +1219,7 @@ function _mapStateToProps(state: IReduxState, ownProps: any): Object { const { local, remote } = tileType === THUMBNAIL_TYPE.VERTICAL ? verticalViewDimensions : horizontalViewDimensions; + // @ts-ignore const { width, height } = (isLocal ? local : remote) ?? {}; diff --git a/react/features/filmstrip/components/web/ThumbnailWrapper.js b/react/features/filmstrip/components/web/ThumbnailWrapper.tsx similarity index 88% rename from react/features/filmstrip/components/web/ThumbnailWrapper.js rename to react/features/filmstrip/components/web/ThumbnailWrapper.tsx index 40a7fb044..a6196c9e7 100644 --- a/react/features/filmstrip/components/web/ThumbnailWrapper.js +++ b/react/features/filmstrip/components/web/ThumbnailWrapper.tsx @@ -1,13 +1,14 @@ -/* @flow */ import React, { Component } from 'react'; +import { connect } from 'react-redux'; import { shouldComponentUpdate } from 'react-window'; -import { getLocalParticipant } from '../../../base/participants'; -import { connect } from '../../../base/redux'; +import { IReduxState } from '../../../app/types'; +import { getLocalParticipant } from '../../../base/participants/functions'; import { getHideSelfView } from '../../../base/settings/functions.any'; -import { LAYOUTS, getCurrentLayout } from '../../../video-layout'; +import { LAYOUTS } from '../../../video-layout/constants'; +import { getCurrentLayout } from '../../../video-layout/functions.web'; import { FILMSTRIP_TYPE, TILE_ASPECT_RATIO, TILE_HORIZONTAL_MARGIN } from '../../constants'; -import { getActiveParticipantsIds, showGridInVerticalView } from '../../functions'; +import { getActiveParticipantsIds, showGridInVerticalView } from '../../functions.web'; import Thumbnail from './Thumbnail'; @@ -19,53 +20,53 @@ type Props = { /** * Whether or not to hide the self view. */ - _disableSelfView: boolean, + _disableSelfView?: boolean; /** * The type of filmstrip this thumbnail is displayed in. */ - _filmstripType: string, + _filmstripType?: string; /** * The horizontal offset in px for the thumbnail. Used to center the thumbnails in the last row in tile view. */ - _horizontalOffset: number, - - /** - * The ID of the participant associated with the Thumbnail. - */ - _participantID: ?string, + _horizontalOffset?: number; /** * Whether or not the thumbnail is a local screen share. */ - _isLocalScreenShare: boolean, + _isLocalScreenShare?: boolean; + + /** + * The ID of the participant associated with the Thumbnail. + */ + _participantID?: string; /** * The width of the thumbnail. Used for expanding the width of the thumbnails on last row in case * there is empty space. */ - _thumbnailWidth: number, + _thumbnailWidth?: number; /** * The index of the column in tile view. */ - columnIndex?: number, + columnIndex?: number; /** * The index of the ThumbnailWrapper in stage view. */ - index?: number, + index?: number; /** * The index of the row in tile view. */ - rowIndex?: number, + rowIndex?: number; /** * The styles coming from react-window. */ - style: Object + style: Object; }; /** @@ -73,6 +74,7 @@ type Props = { * to the Thumbnail Component's props. */ class ThumbnailWrapper extends Component { + shouldComponentUpdate: (p: any, s: any) => boolean; /** * Creates new ThumbnailWrapper instance. @@ -85,8 +87,6 @@ class ThumbnailWrapper extends Component { this.shouldComponentUpdate = shouldComponentUpdate.bind(this); } - shouldComponentUpdate: Props => boolean; - /** * Implements React's {@link Component#render()}. * @@ -148,7 +148,8 @@ class ThumbnailWrapper extends Component { * @private * @returns {Props} */ -function _mapStateToProps(state, ownProps) { +function _mapStateToProps(state: IReduxState, ownProps: { columnIndex: number; + data: { filmstripType: string; }; index?: number; rowIndex: number; }) { const _currentLayout = getCurrentLayout(state); const { remoteParticipants: remote } = state['features/filmstrip']; const activeParticipants = getActiveParticipantsIds(state); @@ -159,23 +160,23 @@ function _mapStateToProps(state, ownProps) { const sortedActiveParticipants = activeParticipants.sort(); const remoteParticipants = stageFilmstrip ? sortedActiveParticipants : remote; const remoteParticipantsLength = remoteParticipants.length; - const localId = getLocalParticipant(state).id; + const localId = getLocalParticipant(state)?.id; if (_currentLayout === LAYOUTS.TILE_VIEW || _verticalViewGrid || stageFilmstrip) { const { columnIndex, rowIndex } = ownProps; const { tileViewDimensions, stageFilmstripDimensions, verticalViewDimensions } = state['features/filmstrip']; const { gridView } = verticalViewDimensions; - let gridDimensions = tileViewDimensions.gridDimensions, - thumbnailSize = tileViewDimensions.thumbnailSize; + let gridDimensions = tileViewDimensions?.gridDimensions, + thumbnailSize = tileViewDimensions?.thumbnailSize; if (stageFilmstrip) { gridDimensions = stageFilmstripDimensions.gridDimensions; thumbnailSize = stageFilmstripDimensions.thumbnailSize; } else if (_verticalViewGrid) { - gridDimensions = gridView.gridDimensions; - thumbnailSize = gridView.thumbnailSize; + gridDimensions = gridView?.gridDimensions; + thumbnailSize = gridView?.thumbnailSize; } - const { columns, rows } = gridDimensions; + const { columns = 1, rows = 1 } = gridDimensions ?? {}; const index = (rowIndex * columns) + columnIndex; let horizontalOffset, thumbnailWidth; const { iAmRecorder, disableTileEnlargement } = state['features/base/config']; @@ -202,7 +203,7 @@ function _mapStateToProps(state, ownProps) { const partialLastRowParticipantsNumber = participantsLength % columns; if (partialLastRowParticipantsNumber > 0) { - const { width, height } = thumbnailSize; + const { width = 1, height = 1 } = thumbnailSize ?? {}; const availableWidth = columns * (width + TILE_HORIZONTAL_MARGIN); let widthDifference = 0; let widthToUse = width; diff --git a/react/features/filmstrip/components/web/styles.js b/react/features/filmstrip/components/web/styles.ts similarity index 89% rename from react/features/filmstrip/components/web/styles.js rename to react/features/filmstrip/components/web/styles.ts index 1696373e8..8e4b2e9d5 100644 --- a/react/features/filmstrip/components/web/styles.js +++ b/react/features/filmstrip/components/web/styles.ts @@ -1,3 +1,4 @@ +import { Theme } from '@mui/material'; const BACKGROUND_COLOR = 'rgba(51, 51, 51, .5)'; @@ -7,17 +8,17 @@ const BACKGROUND_COLOR = 'rgba(51, 51, 51, .5)'; * @param {Object} theme - The current theme. * @returns {Object} */ -export const styles = theme => { +export const styles = (theme: Theme) => { return { toggleFilmstripContainer: { display: 'flex', - flexWrap: 'nowrap', + flexWrap: 'nowrap' as const, alignItems: 'center', justifyContent: 'center', backgroundColor: BACKGROUND_COLOR, width: '32px', height: '24px', - position: 'absolute', + position: 'absolute' as const, borderRadius: '4px', top: 'calc(-24px - 3px)', left: 'calc(50% - 16px)', @@ -33,7 +34,7 @@ export const styles = theme => { toggleFilmstripButton: { fontSize: '14px', lineHeight: 1.2, - textAlign: 'center', + textAlign: 'center' as const, background: 'transparent', height: 'auto', width: '100%', @@ -61,7 +62,7 @@ export const styles = theme => { }, toggleTopPanelContainerHidden: { - visibility: 'hidden' + visibility: 'hidden' as const }, filmstrip: { @@ -83,7 +84,7 @@ export const styles = theme => { }, '& .dragHandleContainer': { - visibility: 'visible' + visibility: 'visible' as const } }, @@ -112,8 +113,8 @@ export const styles = theme => { resizableFilmstripContainer: { display: 'flex', - position: 'relative', - flexDirection: 'row', + position: 'relative' as const, + flexDirection: 'row' as const, alignItems: 'center', height: '100%', width: '100%', @@ -133,12 +134,12 @@ export const styles = theme => { height: '100%', width: '9px', backgroundColor: 'transparent', - position: 'relative', + position: 'relative' as const, cursor: 'col-resize', display: 'flex', alignItems: 'center', justifyContent: 'center', - visibility: 'hidden', + visibility: 'hidden' as const, '&:hover': { '& .dragHandle': { diff --git a/react/features/filmstrip/constants.ts b/react/features/filmstrip/constants.ts index cbe134765..a40834626 100644 --- a/react/features/filmstrip/constants.ts +++ b/react/features/filmstrip/constants.ts @@ -1,5 +1,4 @@ -// @ts-ignore -import { BoxModel } from '../base/styles'; +import { BoxModel } from '../base/styles/components/styles/BoxModel'; /** * The size (height and width) of the small (not tile view) thumbnails. diff --git a/react/features/follow-me/subscriber.ts b/react/features/follow-me/subscriber.ts index 940bd2dee..f9606b14e 100644 --- a/react/features/follow-me/subscriber.ts +++ b/react/features/follow-me/subscriber.ts @@ -5,8 +5,6 @@ import { isLocalParticipantModerator } from '../base/participants/functions'; import StateListenerRegistry from '../base/redux/StateListenerRegistry'; -// eslint-disable-next-line lines-around-comment -// @ts-ignore import { getPinnedActiveParticipants, isStageFilmstripEnabled } from '../filmstrip/functions'; import { shouldDisplayTileView } from '../video-layout/functions'; diff --git a/react/features/gifs/components/web/GifsMenu.tsx b/react/features/gifs/components/web/GifsMenu.tsx index 707447d5d..8c3580fb8 100644 --- a/react/features/gifs/components/web/GifsMenu.tsx +++ b/react/features/gifs/components/web/GifsMenu.tsx @@ -13,9 +13,8 @@ import { sendMessage } from '../../../chat/actions.any'; import { SCROLL_SIZE } from '../../../filmstrip/constants'; import { toggleReactionsMenuVisibility } from '../../../reactions/actions.web'; import { setOverflowMenuVisible } from '../../../toolbox/actions.web'; -// eslint-disable-next-line lines-around-comment -// @ts-ignore -import { Drawer, JitsiPortal } from '../../../toolbox/components/web'; +import Drawer from '../../../toolbox/components/web/Drawer'; +import JitsiPortal from '../../../toolbox/components/web/JitsiPortal'; import { showOverflowDrawer } from '../../../toolbox/functions.web'; import { setGifDrawerVisibility } from '../../actions'; import { diff --git a/react/features/invite/components/add-people-dialog/web/AddPeopleDialog.tsx b/react/features/invite/components/add-people-dialog/web/AddPeopleDialog.tsx index bd4f83dc6..508e47a05 100644 --- a/react/features/invite/components/add-people-dialog/web/AddPeopleDialog.tsx +++ b/react/features/invite/components/add-people-dialog/web/AddPeopleDialog.tsx @@ -35,6 +35,7 @@ import InviteByEmailSection from './InviteByEmailSection'; import InviteContactsSection from './InviteContactsSection'; // @ts-ignore import LiveStreamSection from './LiveStreamSection'; +/* eslint-enable lines-around-comment */ interface IProps extends WithTranslation { diff --git a/react/features/participants-pane/components/web/LobbyParticipants.tsx b/react/features/participants-pane/components/web/LobbyParticipants.tsx index 58adaea14..3bc49cad3 100644 --- a/react/features/participants-pane/components/web/LobbyParticipants.tsx +++ b/react/features/participants-pane/components/web/LobbyParticipants.tsx @@ -10,9 +10,8 @@ import { IconCheck, IconCloseLarge } from '../../../base/icons/svg'; import { withPixelLineHeight } from '../../../base/styles/functions.web'; import { admitMultiple } from '../../../lobby/actions.web'; import { getKnockingParticipants, getLobbyEnabled } from '../../../lobby/functions'; -// eslint-disable-next-line lines-around-comment -// @ts-ignore -import { Drawer, JitsiPortal } from '../../../toolbox/components/web'; +import Drawer from '../../../toolbox/components/web/Drawer'; +import JitsiPortal from '../../../toolbox/components/web/JitsiPortal'; import { showOverflowDrawer } from '../../../toolbox/functions.web'; import { useLobbyActions, useParticipantDrawer } from '../../hooks'; diff --git a/react/features/participants-pane/components/web/MeetingParticipants.tsx b/react/features/participants-pane/components/web/MeetingParticipants.tsx index 3934a4786..79adb581c 100644 --- a/react/features/participants-pane/components/web/MeetingParticipants.tsx +++ b/react/features/participants-pane/components/web/MeetingParticipants.tsx @@ -26,11 +26,13 @@ import { InviteButton } from './InviteButton'; import MeetingParticipantContextMenu from './MeetingParticipantContextMenu'; // @ts-ignore import MeetingParticipantItems from './MeetingParticipantItems'; +/* eslint-enable lines-around-comment */ const useStyles = makeStyles()(theme => { return { heading: { color: theme.palette.text02, + // @ts-ignore ...withPixelLineHeight(theme.typography.labelButton), margin: `8px 0 ${participantsPaneTheme.panePadding}px`, diff --git a/react/features/polls/components/web/PollsPane.tsx b/react/features/polls/components/web/PollsPane.tsx index 1b412ee65..bec99b053 100644 --- a/react/features/polls/components/web/PollsPane.tsx +++ b/react/features/polls/components/web/PollsPane.tsx @@ -6,6 +6,7 @@ import AbstractPollsPane, { AbstractProps } from '../AbstractPollsPane'; import PollCreate from './PollCreate'; import PollsList from './PollsList'; +/* eslint-enable lines-around-comment */ const useStyles = makeStyles()(() => { return { diff --git a/react/features/prejoin/components/web/dialogs/DialInDialog.tsx b/react/features/prejoin/components/web/dialogs/DialInDialog.tsx index b161bd96b..6eba13eb5 100644 --- a/react/features/prejoin/components/web/dialogs/DialInDialog.tsx +++ b/react/features/prejoin/components/web/dialogs/DialInDialog.tsx @@ -12,6 +12,7 @@ import Button from '../../../../base/ui/components/web/Button'; import { getCountryCodeFromPhone } from '../../../utils'; // @ts-ignore import Label from '../Label'; +/* eslint-enable lines-around-comment */ interface IProps extends WithTranslation { diff --git a/react/features/prejoin/components/web/dialogs/DialOutDialog.tsx b/react/features/prejoin/components/web/dialogs/DialOutDialog.tsx index 53eea631d..e957eec7b 100644 --- a/react/features/prejoin/components/web/dialogs/DialOutDialog.tsx +++ b/react/features/prejoin/components/web/dialogs/DialOutDialog.tsx @@ -12,6 +12,7 @@ import Button from '../../../../base/ui/components/web/Button'; import Label from '../Label'; // @ts-ignore import CountryPicker from '../country-picker/CountryPicker'; +/* eslint-enable lines-around-comment */ interface IProps extends WithTranslation { diff --git a/react/features/recording/components/Recording/AbstractStopRecordingDialog.ts b/react/features/recording/components/Recording/AbstractStopRecordingDialog.ts index b1cd2fbf6..78a42cc9e 100644 --- a/react/features/recording/components/Recording/AbstractStopRecordingDialog.ts +++ b/react/features/recording/components/Recording/AbstractStopRecordingDialog.ts @@ -1,4 +1,5 @@ import { Component } from 'react'; +import { WithTranslation } from 'react-i18next'; import { createRecordingDialogEvent } from '../../../analytics/AnalyticsEvents'; import { sendAnalytics } from '../../../analytics/functions'; @@ -15,7 +16,7 @@ import LocalRecordingManager from './LocalRecordingManager'; * The type of the React {@code Component} props of * {@link AbstractStopRecordingDialog}. */ -export interface IProps { +export interface IProps extends WithTranslation { /** * The {@code JitsiConference} for the current conference. @@ -41,11 +42,6 @@ export interface IProps { * The user trying to stop the video while local recording is running. */ localRecordingVideoStop?: boolean; - - /** - * Invoked to obtain translated strings. - */ - t: Function; } /** diff --git a/react/features/recording/components/Recording/web/StopRecordingDialog.js b/react/features/recording/components/Recording/web/StopRecordingDialog.tsx similarity index 82% rename from react/features/recording/components/Recording/web/StopRecordingDialog.js rename to react/features/recording/components/Recording/web/StopRecordingDialog.tsx index 52b8135ce..2aec8ee59 100644 --- a/react/features/recording/components/Recording/web/StopRecordingDialog.js +++ b/react/features/recording/components/Recording/web/StopRecordingDialog.tsx @@ -1,13 +1,13 @@ -// @flow - import React from 'react'; -import { translate } from '../../../../base/i18n'; -import { connect } from '../../../../base/redux'; +import { translate } from '../../../../base/i18n/functions'; +import { connect } from '../../../../base/redux/functions'; import Dialog from '../../../../base/ui/components/web/Dialog'; +// eslint-disable-next-line lines-around-comment +// @ts-ignore import { toggleScreenshotCaptureSummary } from '../../../../screenshot-capture'; import AbstractStopRecordingDialog, { - type Props, + IProps, _mapStateToProps } from '../AbstractStopRecordingDialog'; @@ -17,7 +17,7 @@ import AbstractStopRecordingDialog, { * * @augments Component */ -class StopRecordingDialog extends AbstractStopRecordingDialog { +class StopRecordingDialog extends AbstractStopRecordingDialog { /** * Implements React's {@link Component#render()}. * diff --git a/react/features/security/components/security-dialog/web/SecurityDialog.tsx b/react/features/security/components/security-dialog/web/SecurityDialog.tsx index f2210e2b0..055d06d40 100644 --- a/react/features/security/components/security-dialog/web/SecurityDialog.tsx +++ b/react/features/security/components/security-dialog/web/SecurityDialog.tsx @@ -12,6 +12,7 @@ import { E2EESection } from '../../../../e2ee/components'; import { LobbySection } from '../../../../lobby'; import PasswordSection from './PasswordSection'; +/* eslint-enable lines-around-comment */ export interface INotifyClick { key: string; diff --git a/react/features/settings/components/web/ProfileTab.tsx b/react/features/settings/components/web/ProfileTab.tsx index 30d737d3a..20959e705 100644 --- a/react/features/settings/components/web/ProfileTab.tsx +++ b/react/features/settings/components/web/ProfileTab.tsx @@ -14,6 +14,7 @@ import { translate } from '../../../base/i18n/functions'; import Button from '../../../base/ui/components/web/Button'; import Input from '../../../base/ui/components/web/Input'; import { openLogoutDialog } from '../../actions'; +/* eslint-enable lines-around-comment */ /** * The type of the React {@code Component} props of {@link ProfileTab}. @@ -182,6 +183,7 @@ class ProfileTab extends AbstractDialogTab { const { authLogin, t + // @ts-ignore } = this.props; diff --git a/react/features/settings/components/web/SettingsDialog.tsx b/react/features/settings/components/web/SettingsDialog.tsx index 99e8e01f4..bfaf9ef86 100644 --- a/react/features/settings/components/web/SettingsDialog.tsx +++ b/react/features/settings/components/web/SettingsDialog.tsx @@ -38,6 +38,7 @@ import ModeratorTab from './ModeratorTab'; import MoreTab from './MoreTab'; import ProfileTab from './ProfileTab'; import SoundsTab from './SoundsTab'; +/* eslint-enable lines-around-comment */ /** * The type of the React {@code Component} props of @@ -247,10 +248,12 @@ class SettingsDialog extends Component { return { ...tab, onMount: tab.onMount + // @ts-ignore ? (...args: any) => dispatch(tab.onMount(...args)) : undefined, submit: (...args: any) => tab.submit + // @ts-ignore && dispatch(tab.submit(...args)) }; diff --git a/react/features/toolbox/components/web/DialogPortal.js b/react/features/toolbox/components/web/DialogPortal.ts similarity index 79% rename from react/features/toolbox/components/web/DialogPortal.js rename to react/features/toolbox/components/web/DialogPortal.ts index 1189ba49c..e1a48381d 100644 --- a/react/features/toolbox/components/web/DialogPortal.js +++ b/react/features/toolbox/components/web/DialogPortal.ts @@ -1,6 +1,4 @@ -// @flow - -import { useEffect, useRef, useState } from 'react'; +import { ReactNode, useEffect, useRef, useState } from 'react'; import ReactDOM from 'react-dom'; type Props = { @@ -8,27 +6,27 @@ type Props = { /** * The component(s) to be displayed within the drawer portal. */ - children: React$Node, + children: ReactNode; /** * Custom class name to apply on the container div. */ - className?: string, + className?: string; /** - * Function used to get the refferrence to the container div. + * Function used to get the reference to the container div. */ - getRef?: Function, + getRef?: Function; /** * Function used to get the updated size info of the container on it's resize. */ - setSize?: Function, + setSize?: Function; /** * Custom style to apply to the container div. */ - style?: Object, + style?: any; }; /** @@ -45,13 +43,12 @@ function DialogPortal({ children, className, style, getRef, setSize }: Props) { return portalDiv; }); - const timerRef = useRef(); + const timerRef = useRef(); useEffect(() => { if (style) { for (const styleProp of Object.keys(style)) { - // https://github.com/facebook/flow/issues/3733 - const objStyle: Object = portalTarget.style; + const objStyle: any = portalTarget.style; objStyle[styleProp] = style[styleProp]; } @@ -76,9 +73,9 @@ function DialogPortal({ children, className, style, getRef, setSize }: Props) { const { contentRect } = entries[0]; if (contentRect.width !== size.width || contentRect.height !== size.height) { - setSize && setSize(contentRect); + setSize?.(contentRect); clearTimeout(timerRef.current); - timerRef.current = setTimeout(() => { + timerRef.current = window.setTimeout(() => { portalTarget.style.visibility = 'visible'; }, 100); } @@ -98,8 +95,8 @@ function DialogPortal({ children, className, style, getRef, setSize }: Props) { }, []); return ReactDOM.createPortal( - children, - portalTarget + children, + portalTarget ); } diff --git a/react/features/toolbox/components/web/Drawer.tsx b/react/features/toolbox/components/web/Drawer.tsx index 770069de0..f16a22c21 100644 --- a/react/features/toolbox/components/web/Drawer.tsx +++ b/react/features/toolbox/components/web/Drawer.tsx @@ -1,4 +1,4 @@ -import React, { ReactElement, useCallback } from 'react'; +import React, { ReactNode, useCallback } from 'react'; import { makeStyles } from 'tss-react/mui'; import { DRAWER_MAX_HEIGHT } from '../../constants'; @@ -9,7 +9,7 @@ interface IProps { /** * The component(s) to be displayed within the drawer menu. */ - children: ReactElement; + children: ReactNode; /** * Class name for custom styles. @@ -24,7 +24,7 @@ interface IProps { /** * Function that hides the drawer. */ - onClose: Function; + onClose?: Function; } const useStyles = makeStyles()(theme => { @@ -68,7 +68,7 @@ function Drawer({ */ const handleOutsideClick = useCallback(event => { event.stopPropagation(); - onClose(); + onClose?.(); }, [ onClose ]); return ( diff --git a/react/features/toolbox/components/web/JitsiPortal.js b/react/features/toolbox/components/web/JitsiPortal.tsx similarity index 87% rename from react/features/toolbox/components/web/JitsiPortal.js rename to react/features/toolbox/components/web/JitsiPortal.tsx index 64a09935f..0892d2119 100644 --- a/react/features/toolbox/components/web/JitsiPortal.js +++ b/react/features/toolbox/components/web/JitsiPortal.tsx @@ -1,5 +1,4 @@ -// @flow -import React from 'react'; +import React, { ReactNode } from 'react'; import DialogPortal from './DialogPortal'; @@ -8,12 +7,12 @@ type Props = { /** * The component(s) to be displayed within the drawer portal. */ - children: React$Node, + children: ReactNode; /** * Class name used to add custom styles to the portal. */ - className?: string + className?: string; }; /** diff --git a/react/features/toolbox/components/web/OverflowMenuButton.tsx b/react/features/toolbox/components/web/OverflowMenuButton.tsx index 0d5a794de..5508cce2c 100644 --- a/react/features/toolbox/components/web/OverflowMenuButton.tsx +++ b/react/features/toolbox/components/web/OverflowMenuButton.tsx @@ -13,12 +13,11 @@ import { getReactionsQueue } from '../../../reactions/functions.any'; import { DRAWER_MAX_HEIGHT } from '../../constants'; import { showOverflowDrawer } from '../../functions.web'; -// @ts-ignore import Drawer from './Drawer'; -// @ts-ignore import JitsiPortal from './JitsiPortal'; // @ts-ignore import OverflowToggleButton from './OverflowToggleButton'; +/* eslint-enable lines-around-comment */ /** * The type of the React {@code Component} props of {@link OverflowMenuButton}. diff --git a/react/features/toolbox/components/web/Toolbox.tsx b/react/features/toolbox/components/web/Toolbox.tsx index a331bc058..818ae05e8 100644 --- a/react/features/toolbox/components/web/Toolbox.tsx +++ b/react/features/toolbox/components/web/Toolbox.tsx @@ -2,7 +2,7 @@ import { withStyles } from '@mui/styles'; import React, { Component } from 'react'; import { WithTranslation } from 'react-i18next'; -import { batch } from 'react-redux'; +import { batch, connect } from 'react-redux'; // @ts-expect-error import keyboardShortcut from '../../../../../modules/keyboardshortcut/keyboardshortcut'; @@ -10,6 +10,7 @@ import { isSpeakerStatsDisabled } from '../../../../features/speaker-stats/funct import { ACTION_SHORTCUT_TRIGGERED, createShortcutEvent, createToolbarEvent } from '../../../analytics/AnalyticsEvents'; import { sendAnalytics } from '../../../analytics/functions'; import { IReduxState } from '../../../app/types'; +import { IJitsiConference } from '../../../base/conference/reducer'; import { getMultipleVideoSendingSupportFeatureFlag, getToolbarButtons, @@ -27,8 +28,8 @@ import { hasRaisedHand, isLocalParticipantModerator } from '../../../base/participants/functions'; -import { connect } from '../../../base/redux/functions'; import { getLocalVideoTrack } from '../../../base/tracks/functions'; +import { ITrack } from '../../../base/tracks/types'; import ContextMenu from '../../../base/ui/components/web/ContextMenu'; import ContextMenuItemGroup from '../../../base/ui/components/web/ContextMenuItemGroup'; import { toggleChat } from '../../../chat/actions.web'; @@ -138,6 +139,7 @@ import ShareDesktopButton from './ShareDesktopButton'; import ToggleCameraButton from './ToggleCameraButton'; // @ts-ignore import VideoSettingsButton from './VideoSettingsButton'; +/* eslint-enable lines-around-comment */ /** * The type of the React {@code Component} props of {@link Toolbox}. @@ -147,12 +149,12 @@ interface IProps extends WithTranslation { /** * String showing if the virtual background type is desktop-share. */ - _backgroundType: String; + _backgroundType: string; /** * Toolbar buttons which have their click exposed through the API. */ - _buttonsWithNotifyClick: Array; @@ -170,7 +172,7 @@ interface IProps extends WithTranslation { /** * The {@code JitsiConference} for the current conference. */ - _conference: Object; + _conference?: IJitsiConference; /** * Whether or not screensharing button is disabled. @@ -205,7 +207,7 @@ interface IProps extends WithTranslation { /** * Whether or not the app is currently in full screen. */ - _fullScreen: boolean; + _fullScreen?: boolean; /** * Whether or not the GIFs feature is enabled. @@ -245,7 +247,7 @@ interface IProps extends WithTranslation { /** * Whether or not speaker stats is disable. */ - _isSpeakerStatsDisabled: boolean; + _isSpeakerStatsDisabled?: boolean; /** @@ -261,12 +263,12 @@ interface IProps extends WithTranslation { /** * The ID of the local participant. */ - _localParticipantID: String; + _localParticipantID?: string; /** * The JitsiLocalTrack to display. */ - _localVideo: Object; + _localVideo?: ITrack; /** * Whether or not multi-stream send support is enabled. @@ -306,7 +308,7 @@ interface IProps extends WithTranslation { /** * Whether or not the local participant is sharing a YouTube video. */ - _sharingVideo: boolean; + _sharingVideo?: boolean; /** * Whether or not the tile view is enabled. @@ -1540,7 +1542,7 @@ function _mapStateToProps(state: IReduxState, ownProps: Partial) { const toolbarButtons = ownProps.toolbarButtons || getToolbarButtons(state); return { - _backgroundType: state['features/virtual-background'].backgroundType, + _backgroundType: state['features/virtual-background'].backgroundType ?? '', _buttonsWithNotifyClick: buttonsWithNotifyClick, _chatOpen: state['features/chat'].isOpen, _clientWidth: clientWidth, diff --git a/react/features/video-menu/components/web/LocalVideoMenuTriggerButton.tsx b/react/features/video-menu/components/web/LocalVideoMenuTriggerButton.tsx index 8d1501d81..364a68302 100644 --- a/react/features/video-menu/components/web/LocalVideoMenuTriggerButton.tsx +++ b/react/features/video-menu/components/web/LocalVideoMenuTriggerButton.tsx @@ -30,6 +30,7 @@ import FlipLocalVideoButton from './FlipLocalVideoButton'; import HideSelfViewVideoButton from './HideSelfViewVideoButton'; // @ts-ignore import TogglePinToStageButton from './TogglePinToStageButton'; +/* eslint-enable lines-around-comment */ /** * The type of the React {@code Component} props of diff --git a/react/features/video-menu/components/web/ParticipantContextMenu.tsx b/react/features/video-menu/components/web/ParticipantContextMenu.tsx index 08c13a444..319c477a5 100644 --- a/react/features/video-menu/components/web/ParticipantContextMenu.tsx +++ b/react/features/video-menu/components/web/ParticipantContextMenu.tsx @@ -47,6 +47,7 @@ import { VolumeSlider // @ts-ignore } from './'; +/* eslint-enable lines-around-comment */ interface IProps { diff --git a/react/features/video-menu/components/web/RemoteVideoMenuTriggerButton.tsx b/react/features/video-menu/components/web/RemoteVideoMenuTriggerButton.tsx index cff43f355..860882d59 100644 --- a/react/features/video-menu/components/web/RemoteVideoMenuTriggerButton.tsx +++ b/react/features/video-menu/components/web/RemoteVideoMenuTriggerButton.tsx @@ -23,6 +23,7 @@ import FakeParticipantContextMenu from './FakeParticipantContextMenu'; import ParticipantContextMenu from './ParticipantContextMenu'; // @ts-ignore import { REMOTE_CONTROL_MENU_STATES } from './RemoteControlButton'; +/* eslint-enable lines-around-comment */ /** * The type of the React {@code Component} props of diff --git a/react/features/video-menu/components/web/VerifyParticipantButton.tsx b/react/features/video-menu/components/web/VerifyParticipantButton.tsx index e722f0e83..bf20f2cf5 100644 --- a/react/features/video-menu/components/web/VerifyParticipantButton.tsx +++ b/react/features/video-menu/components/web/VerifyParticipantButton.tsx @@ -1,4 +1,3 @@ -/* eslint-disable lines-around-comment */ import { withStyles } from '@mui/styles'; import React, { Component } from 'react'; import { WithTranslation } from 'react-i18next'; @@ -15,15 +14,16 @@ import { startVerification } from '../../../e2ee/actions'; * {@link VerifyParticipantButton}. */ interface IProps extends WithTranslation { + /** * The redux {@code dispatch} function. */ - dispatch: Function; + dispatch: Function; - /** + /** * The ID of the participant that this button is supposed to verified. */ - participantID: string; + participantID: string; } const styles = () => { diff --git a/react/features/virtual-background/components/VirtualBackgroundDialog.tsx b/react/features/virtual-background/components/VirtualBackgroundDialog.tsx index 85a6f2aab..8d8612ab8 100644 --- a/react/features/virtual-background/components/VirtualBackgroundDialog.tsx +++ b/react/features/virtual-background/components/VirtualBackgroundDialog.tsx @@ -28,6 +28,7 @@ import logger from '../logger'; import UploadImageButton from './UploadImageButton'; // @ts-ignore import VirtualBackgroundPreview from './VirtualBackgroundPreview'; +/* eslint-enable lines-around-comment */ interface IProps extends WithTranslation { @@ -129,6 +130,7 @@ const useStyles = makeStyles()(theme => { gridTemplateColumns: 'auto auto auto auto auto', columnGap: '9px', cursor: 'pointer', + // @ts-ignore [[ '& .desktop-share:hover', '& .thumbnail:hover', @@ -235,6 +237,7 @@ const useStyles = makeStyles()(theme => { height: '60px', width: '60px' }, + // @ts-ignore [[ '& .desktop-share-selected', '& .thumbnail-selected', @@ -468,6 +471,7 @@ function VirtualBackground({ {loading ? (