Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3,971 changes: 2,725 additions & 1,246 deletions package-lock.json

Large diffs are not rendered by default.

20 changes: 11 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
"optional-require": "1.0.3",
"pixelmatch": "5.3.0",
"promise.allsettled": "1.0.4",
"promise.withresolvers": "1.0.3",
"punycode": "2.3.0",
"react": "18.2.0",
"react-dom": "18.2.0",
Expand Down Expand Up @@ -134,8 +135,9 @@
"@babel/plugin-transform-private-methods": "7.25.9",
"@babel/preset-env": "7.25.9",
"@babel/preset-react": "7.25.9",
"@jitsi/eslint-config": "4.1.10",
"@jitsi/eslint-config": "5.0.9",
"@react-native/metro-config": "0.75.4",
"@stylistic/eslint-plugin": "2.12.1",
"@types/amplitude-js": "8.16.5",
"@types/audioworklet": "0.0.29",
"@types/dom-screen-wake-lock": "1.0.1",
Expand All @@ -161,8 +163,8 @@
"@types/w3c-image-capture": "1.0.6",
"@types/w3c-web-hid": "1.0.3",
"@types/zxcvbn": "4.4.1",
"@typescript-eslint/eslint-plugin": "5.59.5",
"@typescript-eslint/parser": "5.59.5",
"@typescript-eslint/eslint-plugin": "8.19.1",
"@typescript-eslint/parser": "8.19.1",
"@wdio/allure-reporter": "9.4.3",
"@wdio/cli": "9.4.3",
"@wdio/globals": "9.4.3",
Expand All @@ -174,12 +176,12 @@
"circular-dependency-plugin": "5.2.0",
"clean-css-cli": "4.3.0",
"css-loader": "6.8.1",
"eslint": "8.40.0",
"eslint-plugin-import": "2.27.5",
"eslint-plugin-jsdoc": "46.2.6",
"eslint-plugin-react": "7.32.2",
"eslint-plugin-react-native": "4.0.0",
"eslint-plugin-typescript-sort-keys": "2.3.0",
"eslint": "8.57.0",
"eslint-plugin-import": "2.31.0",
"eslint-plugin-jsdoc": "50.6.1",
"eslint-plugin-react": "7.37.3",
"eslint-plugin-react-native": "5.0.0",
"eslint-plugin-typescript-sort-keys": "3.3.0",
"jetifier": "1.6.4",
"jsonwebtoken": "9.0.2",
"metro-react-native-babel-preset": "0.77.0",
Expand Down
20 changes: 5 additions & 15 deletions react/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,14 @@ module.exports = {
project: [ './tsconfig.web.json', './tsconfig.native.json' ]
},
rules: {
'@typescript-eslint/naming-convention': [
'error',
{
'selector': 'interface',
'format': [ 'PascalCase' ],
'custom': {
'regex': '^I[A-Z]',
'match': true
}
}
]
// TODO: Remove these and fix the warnings
'@typescript-eslint/no-unsafe-function-type': 0,
'@typescript-eslint/no-wrapper-object-types': 0,

'@typescript-eslint/no-require-imports': 0
}
}
],
'rules': {
// XXX remove this eventually.
'react/jsx-indent-props': 0
},
'settings': {
'react': {
'version': 'detect'
Expand Down
2 changes: 2 additions & 0 deletions react/features/always-on-top/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import ReactDOM from 'react-dom';
import AlwaysOnTop from './AlwaysOnTop';

// Render the main/root Component.
/* eslint-disable-next-line react/no-deprecated */
ReactDOM.render(<AlwaysOnTop />, document.getElementById('react'));

window.addEventListener(
'beforeunload',
/* eslint-disable-next-line react/no-deprecated */
() => ReactDOM.unmountComponentAtNode(document.getElementById('react') ?? document.body));
2 changes: 1 addition & 1 deletion react/features/analytics/AnalyticsEvents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ export function createInviteDialogEvent(
* @returns {Object}
*/
export function createNetworkInfoEvent({ isOnline, networkType, details }:
{ details?: Object; isOnline: boolean; networkType?: string; }) {
{ details?: Object; isOnline: boolean; networkType?: string; }) {
const attributes: {
details?: Object;
isOnline: boolean;
Expand Down
1 change: 0 additions & 1 deletion react/features/app/actions.any.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,4 +158,3 @@ export function maybeRedirectToTokenAuthUrl(
return false;
}


6 changes: 2 additions & 4 deletions react/features/app/components/AbstractApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,9 @@ export interface IProps {
*/
export class AbstractApp<P extends IProps = IProps> extends BaseApp<P> {
/**
* The deferred for the initialisation {{promise, resolve, reject}}.
* The deferred for the initialization {{promise, resolve, reject}}.
*/
_init: {
promise: Promise<any>;
};
_init: PromiseWithResolvers<any>;

/**
* Initializes the app.
Expand Down
5 changes: 1 addition & 4 deletions react/features/app/getRouteToRender.web.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,7 @@ function _getWebWelcomePageRoute(state: IReduxState) {
*
* @returns {Object}
*/
function _getEmptyRoute(): {
component: React.ReactNode;
href?: string;
} {
function _getEmptyRoute(): { component: React.ReactNode; href?: string; } {
return {
component: BlankPage,
href: undefined
Expand Down
3 changes: 1 addition & 2 deletions react/features/app/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,7 @@ function _isMaybeSplitBrainError(getState: IStore['getState'], action: AnyAction
const { error } = action;
const isShardChangedError = error
&& error.message === 'item-not-found'
&& error.details
&& error.details.shard_changed;
&& error.details?.shard_changed;

if (isShardChangedError) {
const state = getState();
Expand Down
7 changes: 2 additions & 5 deletions react/features/base/app/components/BaseApp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import PersistenceRegistry from '../../redux/PersistenceRegistry';
import ReducerRegistry from '../../redux/ReducerRegistry';
import StateListenerRegistry from '../../redux/StateListenerRegistry';
import SoundCollection from '../../sounds/components/SoundCollection';
import { createDeferred } from '../../util/helpers';
import { appWillMount, appWillUnmount } from '../actions';
import logger from '../logger';

Expand Down Expand Up @@ -46,9 +45,7 @@ export default class BaseApp<P> extends Component<P, IState> {
/**
* The deferred for the initialisation {{promise, resolve, reject}}.
*/
_init: {
promise: Promise<any>;
};
_init: PromiseWithResolvers<any>;

/**
* Initializes a new {@code BaseApp} instance.
Expand Down Expand Up @@ -79,7 +76,7 @@ export default class BaseApp<P> extends Component<P, IState> {
* @see {@link #_initStorage}
* @type {Promise}
*/
this._init = createDeferred<void>();
this._init = Promise.withResolvers();

try {
await this._initStorage();
Expand Down
5 changes: 2 additions & 3 deletions react/features/base/conference/middleware.any.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,8 +248,7 @@ function _conferenceFailed({ dispatch, getState }: IStore, next: Function, actio
}

!error.recoverable
&& conference
&& conference.leave(CONFERENCE_LEAVE_REASONS.UNRECOVERABLE_ERROR).catch((reason: Error) => {
&& conference?.leave(CONFERENCE_LEAVE_REASONS.UNRECOVERABLE_ERROR).catch((reason: Error) => {
// Even though we don't care too much about the failure, it may be
// good to know that it happen, so log it (on the info level).
logger.info('JitsiConference.leave() rejected with:', reason);
Expand Down Expand Up @@ -551,7 +550,7 @@ function _pinParticipant({ getState }: IStore, next: Function, action: AnyAction
const actionName = id ? ACTION_PINNED : ACTION_UNPINNED;
const local
= participantById?.local
|| (!id && pinnedParticipant && pinnedParticipant.local);
|| (!id && pinnedParticipant?.local);
let participantIdForEvent;

if (local) {
Expand Down
2 changes: 1 addition & 1 deletion react/features/base/conference/reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,7 @@ function _conferenceJoined(state: IConferenceState, { conference }: { conference
* reduction of the specified action.
*/
function _conferenceLeftOrWillLeave(state: IConferenceState, { conference, type }:
{ conference: IJitsiConference; type: string; }) {
{ conference: IJitsiConference; type: string; }) {
const nextState = { ...state };

// The redux action CONFERENCE_LEFT is the last time that we should be
Expand Down
2 changes: 1 addition & 1 deletion react/features/base/i18n/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ MiddlewareRegistry.register(store => next => action => {
? action.value
: store.getState()['features/dynamic-branding'];

if (language && labels && labels[language]) {
if (language && labels?.[language]) {
changeLanguageBundle(language, labels[language])
.catch(err => {
logger.log('Error setting dynamic language bundle', err);
Expand Down
2 changes: 1 addition & 1 deletion react/features/base/jwt/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ function _undoOverwriteLocalParticipant(
* }}
*/
function _user2participant({ avatar, avatarUrl, email, id, name, 'hidden-from-recorder': hiddenFromRecorder }:
{ avatar?: string; avatarUrl?: string; email: string; 'hidden-from-recorder': string | boolean;
{ avatar?: string; avatarUrl?: string; email: string; 'hidden-from-recorder': string | boolean;
id: string; name: string; }) {
const participant: {
avatarURL?: string;
Expand Down
2 changes: 1 addition & 1 deletion react/features/base/media/components/web/AudioTrack.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ class AudioTrack extends Component<IProps> {
* @returns {void}
*/
_detachTrack(track?: ITrack) {
if (this._ref?.current && track && track.jitsiTrack) {
if (this._ref?.current && track?.jitsiTrack) {
clearTimeout(this._playTimeout);
this._playTimeout = undefined;
track.jitsiTrack.detach(this._ref.current);
Expand Down
2 changes: 1 addition & 1 deletion react/features/base/media/components/web/Video.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ class Video extends Component<IProps> {
* @returns {void}
*/
_detachTrack(videoTrack?: Partial<ITrack>) {
if (this._videoElement && videoTrack && videoTrack.jitsiTrack) {
if (this._videoElement && videoTrack?.jitsiTrack) {
videoTrack.jitsiTrack.detach(this._videoElement);
}
}
Expand Down
10 changes: 5 additions & 5 deletions react/features/base/media/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
8 changes: 4 additions & 4 deletions react/features/base/media/reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { AnyAction, combineReducers } from 'redux';
import { CONFERENCE_FAILED, CONFERENCE_LEFT } from '../conference/actionTypes';
import ReducerRegistry from '../redux/ReducerRegistry';
import { TRACK_REMOVED } from '../tracks/actionTypes';
import { DefferedPromise, createDeferred } from '../util/helpers';

import {
GUM_PENDING,
Expand Down Expand Up @@ -93,7 +92,7 @@ function _audio(state: IAudioState = _AUDIO_INITIAL_MEDIA_STATE, action: AnyActi
// initial track creation haven't been started we would wait for it to finish before starting to join the room.
// NOTE: The previous implementation was using the GUM promise from conference.init. But it turned out that connect
// may finish even before conference.init is executed.
const DEFAULT_INITIAL_PROMISE_STATE = createDeferred<IInitialGUMPromiseResult>();
const DEFAULT_INITIAL_PROMISE_STATE = Promise.withResolvers<IInitialGUMPromiseResult>();

/**
* Reducer for the common properties in media state.
Expand All @@ -103,7 +102,8 @@ const DEFAULT_INITIAL_PROMISE_STATE = createDeferred<IInitialGUMPromiseResult>()
* @param {string} action.type - Type of action.
* @returns {ICommonState}
*/
function _initialGUMPromise(state: DefferedPromise<IInitialGUMPromiseResult> | null = DEFAULT_INITIAL_PROMISE_STATE,
function _initialGUMPromise(
state: PromiseWithResolvers<IInitialGUMPromiseResult> | null = DEFAULT_INITIAL_PROMISE_STATE,
action: AnyAction) {
if (action.type === SET_INITIAL_GUM_PROMISE) {
return action.promise ?? null;
Expand Down Expand Up @@ -294,7 +294,7 @@ interface IVideoState {

export interface IMediaState {
audio: IAudioState;
initialGUMPromise: DefferedPromise<IInitialGUMPromiseResult> | null;
initialGUMPromise: PromiseWithResolvers<IInitialGUMPromiseResult> | null;
screenshare: IScreenshareState;
video: IVideoState;
}
Expand Down
3 changes: 1 addition & 2 deletions react/features/base/participants/functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import i18next from '../i18n/i18next';
import { MEDIA_TYPE, MediaType, VIDEO_TYPE } from '../media/constants';
import { toState } from '../redux/functions';
import { getScreenShareTrack, isLocalTrackMuted } from '../tracks/functions.any';
import { createDeferred } from '../util/helpers';

import {
JIGASI_PARTICIPANT_ICON,
Expand Down Expand Up @@ -127,7 +126,7 @@ export function getActiveSpeakersToBeDisplayed(stateful: IStateful) {
* @returns {Promise}
*/
export function getFirstLoadableAvatarUrl(participant: IParticipant, store: IStore) {
const deferred: any = createDeferred();
const deferred: any = Promise.withResolvers();
const fullPromise = deferred.promise
.then(() => _getFirstLoadableAvatarUrl(participant, store))
.then((result: any) => {
Expand Down
4 changes: 1 addition & 3 deletions react/features/base/popover/components/Popover.web.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -340,9 +340,7 @@ class Popover extends Component<IProps, IState> {
_onTouchStart(event: TouchEvent) {
if (this.props.visible
&& !this.props.overflowDrawer
&& this._contextMenuRef
&& this._contextMenuRef.contains
&& !this._contextMenuRef.contains(event.target as Node)
&& !this._contextMenuRef?.contains?.(event.target as Node)
&& !this._containerRef?.current?.contains(event.target as Node)) {
this._onHideDialog();
}
Expand Down
4 changes: 2 additions & 2 deletions react/features/base/redux/StateListenerRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@ class StateListenerRegistry {
* @returns {void}
*/
_listener({ prevSelections, store }: {
prevSelections: Map<SelectorListener, any>;
store: Store<any, any>;
prevSelections: Map<SelectorListener, any>;
store: Store<any, any>;
}) {
for (const selectorListener of this._selectorListeners) {
const prevSelection = prevSelections.get(selectorListener);
Expand Down
2 changes: 1 addition & 1 deletion react/features/base/toolbox/components/AbstractButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ export default class AbstractButton<P extends IProps, S = any> extends Component

// blur after click to release focus from button to allow PTT.
// @ts-ignore
e?.currentTarget?.blur && e.currentTarget.blur();
e?.currentTarget?.blur?.();
}

/**
Expand Down
6 changes: 3 additions & 3 deletions react/features/base/ui/components/web/ContextMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -244,9 +244,9 @@ const ContextMenu = ({
list: Element | null,
currentFocus: Element | null,
traversalFunction: (
list: Element | null,
currentFocus: Element | null
) => Element | null
list: Element | null,
currentFocus: Element | null
) => Element | null
) => {
let wrappedOnce = false;
let nextFocus = traversalFunction(list, currentFocus);
Expand Down
2 changes: 1 addition & 1 deletion react/features/base/ui/components/web/DialogWithTabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ const useStyles = makeStyles()(theme => {
});

interface IObject {
[key: string]: string | string[] | boolean | number | number[] | {} | undefined;
[key: string]: unknown;
}

export interface IDialogTab<P> {
Expand Down
6 changes: 3 additions & 3 deletions react/features/base/ui/components/web/TextWithOverflow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import { makeStyles } from 'tss-react/mui';
import { TEXT_OVERFLOW_TYPES } from '../../constants.web';

interface ITextWithOverflowProps {
children: ReactNode;
className?: string;
overflowType?: TEXT_OVERFLOW_TYPES;
children: ReactNode;
className?: string;
overflowType?: TEXT_OVERFLOW_TYPES;
}

const useStyles = makeStyles<{ translateDiff: number; }>()((_, { translateDiff }) => {
Expand Down
21 changes: 0 additions & 21 deletions react/features/base/util/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,27 +22,6 @@ export function assignIfDefined(target: Object, source: Object) {
return to;
}

export type DefferedPromise<T> = {
promise: Promise<T>;
reject: (reason?: any) => void;
resolve: (value: T) => void;
};

/**
* Creates a deferred object.
*
* @returns {{promise, resolve, reject}}
*/
export function createDeferred<T>() {
const deferred = {} as DefferedPromise<T>;

deferred.promise = new Promise<T>((resolve, reject) => {
deferred.resolve = resolve;
deferred.reject = reject;
});

return deferred;
}

const MATCH_OPERATOR_REGEXP = /[|\\{}()[\]^$+*?.-]/g;

Expand Down
Loading
Loading