From 7c3d2010e4d4aa7aed26037a7e20f6bc5b630bac Mon Sep 17 00:00:00 2001 From: Robert Pintilii Date: Fri, 28 Oct 2022 11:53:24 +0300 Subject: [PATCH] ref(TS) Convert some features to TS (#12471) --- react/features/analytics/AnalyticsEvents.ts | 2 +- react/features/base/conference/actions.ts | 7 +++- react/features/base/conference/reducer.ts | 1 + react/features/base/participants/actions.ts | 2 +- .../prejoin/{middleware.js => middleware.ts} | 15 ++++---- react/features/prejoin/{utils.js => utils.ts} | 6 +-- .../{functions.js => functions.ts} | 4 -- .../rejoin/{middleware.js => middleware.ts} | 7 ++-- .../room-lock/{actions.js => actions.ts} | 38 +++++++++---------- .../room-lock/{logger.js => logger.ts} | 2 - .../{middleware.js => middleware.ts} | 26 ++++++------- .../salesforce/{actions.js => actions.ts} | 15 ++++---- .../components/web/SalesforceLinkDialog.tsx | 5 ++- .../salesforce/{functions.js => functions.ts} | 22 +++++++---- ...nkDialog.js => useSalesforceLinkDialog.ts} | 28 +++++++------- 15 files changed, 91 insertions(+), 89 deletions(-) rename react/features/prejoin/{middleware.js => middleware.ts} (84%) rename react/features/prejoin/{utils.js => utils.ts} (99%) rename react/features/presence-status/{functions.js => functions.ts} (83%) rename react/features/rejoin/{middleware.js => middleware.ts} (77%) rename react/features/room-lock/{actions.js => actions.ts} (78%) rename react/features/room-lock/{logger.js => logger.ts} (91%) rename react/features/room-lock/{middleware.js => middleware.ts} (87%) rename react/features/salesforce/{actions.js => actions.ts} (74%) rename react/features/salesforce/{functions.js => functions.ts} (85%) rename react/features/salesforce/{useSalesforceLinkDialog.js => useSalesforceLinkDialog.ts} (82%) diff --git a/react/features/analytics/AnalyticsEvents.ts b/react/features/analytics/AnalyticsEvents.ts index 20217f243e..2e3b5eab5e 100644 --- a/react/features/analytics/AnalyticsEvents.ts +++ b/react/features/analytics/AnalyticsEvents.ts @@ -503,7 +503,7 @@ export function createLocalTracksDurationEvent(duration: { * @returns {Object} The event in a format suitable for sending via * sendAnalytics. */ -export function createRecordingEvent(action: string, type: string, value: number) { +export function createRecordingEvent(action: string, type: string, value?: number) { return { action, actionSubject: `recording.${type}`, diff --git a/react/features/base/conference/actions.ts b/react/features/base/conference/actions.ts index e71acecb1f..192e16d9fa 100644 --- a/react/features/base/conference/actions.ts +++ b/react/features/base/conference/actions.ts @@ -785,10 +785,13 @@ export function setStartReactionsMuted(muted: boolean, updateBackend = false) { * @returns {Function} */ export function setPassword( - conference: IJitsiConference, - method: Function, + conference: IJitsiConference | undefined, + method: Function | undefined, password: string) { return (dispatch: IStore['dispatch'], getState: IStore['getState']) => { + if (!conference) { + return; + } switch (method) { case conference.join: { let state = getState()['features/base/conference']; diff --git a/react/features/base/conference/reducer.ts b/react/features/base/conference/reducer.ts index 6cf73f1853..35621cb0cd 100644 --- a/react/features/base/conference/reducer.ts +++ b/react/features/base/conference/reducer.ts @@ -50,6 +50,7 @@ export interface IJitsiConference { getBreakoutRooms: Function; getLocalParticipantProperty: Function; getLocalTracks: Function; + getMeetingUniqueId: Function; getParticipantById: Function; grantOwner: Function; isAVModerationSupported: Function; diff --git a/react/features/base/participants/actions.ts b/react/features/base/participants/actions.ts index e6dd752092..9661330fb6 100644 --- a/react/features/base/participants/actions.ts +++ b/react/features/base/participants/actions.ts @@ -706,7 +706,7 @@ export function overwriteParticipantsNames(participantList: IParticipant[]) { * recording: boolean * }} */ -export function updateLocalRecordingStatus(recording: boolean, onlySelf: boolean) { +export function updateLocalRecordingStatus(recording: boolean, onlySelf?: boolean) { return { type: SET_LOCAL_PARTICIPANT_RECORDING_STATUS, recording, diff --git a/react/features/prejoin/middleware.js b/react/features/prejoin/middleware.ts similarity index 84% rename from react/features/prejoin/middleware.js rename to react/features/prejoin/middleware.ts index 8c5774d51c..92e2cbfe17 100644 --- a/react/features/prejoin/middleware.js +++ b/react/features/prejoin/middleware.ts @@ -1,13 +1,14 @@ -// @flow +import { AnyAction } from 'redux'; -import { CONFERENCE_FAILED, CONFERENCE_JOINED } from '../base/conference'; -import { SET_AUDIO_MUTED, SET_VIDEO_MUTED } from '../base/media'; -import { MiddlewareRegistry } from '../base/redux'; -import { updateSettings } from '../base/settings'; +import { IStore } from '../app/types'; +import { CONFERENCE_FAILED, CONFERENCE_JOINED } from '../base/conference/actionTypes'; +import { SET_AUDIO_MUTED, SET_VIDEO_MUTED } from '../base/media/actionTypes'; +import MiddlewareRegistry from '../base/redux/MiddlewareRegistry'; +import { updateSettings } from '../base/settings/actions'; import { TRACK_ADDED, TRACK_NO_DATA_FROM_SOURCE -} from '../base/tracks'; +} from '../base/tracks/actionTypes'; import { setDeviceStatusOk, @@ -83,7 +84,7 @@ MiddlewareRegistry.register(store => next => async action => { * @param {Object} action - The Redux action. * @returns {Object} */ -function _conferenceJoined({ dispatch }, next, action) { +function _conferenceJoined({ dispatch }: IStore, next: Function, action: AnyAction) { dispatch(setJoiningInProgress(false)); return next(action); diff --git a/react/features/prejoin/utils.js b/react/features/prejoin/utils.ts similarity index 99% rename from react/features/prejoin/utils.js rename to react/features/prejoin/utils.ts index dcb0b13d57..860a69a6fa 100644 --- a/react/features/prejoin/utils.js +++ b/react/features/prejoin/utils.ts @@ -1,5 +1,3 @@ -// @flow - export const countries = [ { name: 'Afghanistan', dialCode: '93', @@ -745,7 +743,7 @@ export const countries = [ code: 'zw' } ]; -const countriesByCodeMap = countries.reduce((result, country) => { +const countriesByCodeMap = countries.reduce((result, country) => { result[country.dialCode] = country; return result; @@ -755,7 +753,7 @@ const countriesByCodeMap = countries.reduce((result, country) => { * Map between country dial codes and country objects. * */ -const codesByNumbersMap = countries.reduce((result, country) => { +const codesByNumbersMap = countries.reduce((result, country) => { result[country.dialCode] = country.code; return result; diff --git a/react/features/presence-status/functions.js b/react/features/presence-status/functions.ts similarity index 83% rename from react/features/presence-status/functions.js rename to react/features/presence-status/functions.ts index 8201f710fc..0acd133e19 100644 --- a/react/features/presence-status/functions.js +++ b/react/features/presence-status/functions.ts @@ -1,7 +1,3 @@ -// @flow - -declare var interfaceConfig: Object; - /** * Tells whether presence status should be displayed. * diff --git a/react/features/rejoin/middleware.js b/react/features/rejoin/middleware.ts similarity index 77% rename from react/features/rejoin/middleware.js rename to react/features/rejoin/middleware.ts index 4a64940ada..536246529d 100644 --- a/react/features/rejoin/middleware.js +++ b/react/features/rejoin/middleware.ts @@ -1,12 +1,13 @@ -import { createRejoinedEvent, sendAnalytics } from '../analytics'; -import { StateListenerRegistry } from '../base/redux'; +import { createRejoinedEvent } from '../analytics/AnalyticsEvents'; +import { sendAnalytics } from '../analytics/functions'; +import StateListenerRegistry from '../base/redux/StateListenerRegistry'; StateListenerRegistry.register( /* selector */ state => { const recentList = state['features/recent-list']; // Return the most recent conference entry - return recentList && recentList.length && recentList[recentList.length - 1]; + return recentList?.length && recentList[recentList.length - 1]; }, // eslint-disable-next-line no-empty-pattern /* listener */ (newMostRecent, { }, prevMostRecent) => { diff --git a/react/features/room-lock/actions.js b/react/features/room-lock/actions.ts similarity index 78% rename from react/features/room-lock/actions.js rename to react/features/room-lock/actions.ts index eeb8b5479c..73ac246f52 100644 --- a/react/features/room-lock/actions.js +++ b/react/features/room-lock/actions.ts @@ -1,23 +1,19 @@ -// @flow - -import type { Dispatch } from 'redux'; - import { appNavigate, maybeRedirectToWelcomePage -} from '../app/actions'; -import { - JITSI_CONFERENCE_URL_KEY, - conferenceLeft, - setPassword -} from '../base/conference'; -import { hideDialog, openDialog } from '../base/dialog'; +} from '../app/actions.web'; +import { IStore } from '../app/types'; +import { conferenceLeft, setPassword } from '../base/conference/actions'; +import { JITSI_CONFERENCE_URL_KEY } from '../base/conference/constants'; +import { IJitsiConference } from '../base/conference/reducer'; +import { hideDialog, openDialog } from '../base/dialog/actions'; +// eslint-disable-next-line lines-around-comment +// @ts-ignore import { SecurityDialog } from '../security/components/security-dialog'; +// @ts-ignore import { PasswordRequiredPrompt } from './components'; -declare var APP: Object; - /** * Cancels a prompt for a password to join a specific conference/room. * @@ -26,8 +22,8 @@ declare var APP: Object; * @protected * @returns {Function} */ -export function _cancelPasswordRequiredPrompt(conference: Object) { - return (dispatch: Dispatch, getState: Function) => { +export function _cancelPasswordRequiredPrompt(conference: any) { + return (dispatch: IStore['dispatch'], getState: IStore['getState']) => { if (typeof APP !== 'undefined') { // when we are redirecting the library should handle any @@ -70,9 +66,9 @@ export function _cancelPasswordRequiredPrompt(conference: Object) { * @returns {Function} */ export function endRoomLockRequest( - conference: { lock: Function }, - password: ?string) { - return (dispatch: Function) => { + conference: IJitsiConference, + password?: string) { + return (dispatch: IStore['dispatch']) => { const setPassword_ = password ? dispatch(setPassword(conference, conference.lock, password)) @@ -95,7 +91,7 @@ export function endRoomLockRequest( * props: PropTypes * }} */ -export function _openPasswordRequiredPrompt(conference: Object) { +export function _openPasswordRequiredPrompt(conference: IJitsiConference) { return openDialog(PasswordRequiredPrompt, { conference }); } @@ -105,12 +101,12 @@ export function _openPasswordRequiredPrompt(conference: Object) { * @returns {Function} */ export function unlockRoom() { - return (dispatch: Dispatch, getState: Function) => { + return (dispatch: IStore['dispatch'], getState: IStore['getState']) => { const { conference } = getState()['features/base/conference']; return dispatch(setPassword( conference, - conference.lock, + conference?.lock, '' )); }; diff --git a/react/features/room-lock/logger.js b/react/features/room-lock/logger.ts similarity index 91% rename from react/features/room-lock/logger.js rename to react/features/room-lock/logger.ts index de6b3916e5..03430729ff 100644 --- a/react/features/room-lock/logger.js +++ b/react/features/room-lock/logger.ts @@ -1,5 +1,3 @@ -// @flow - import { getLogger } from '../base/logging/functions'; export default getLogger('features/room-lock'); diff --git a/react/features/room-lock/middleware.js b/react/features/room-lock/middleware.ts similarity index 87% rename from react/features/room-lock/middleware.js rename to react/features/room-lock/middleware.ts index 6970737106..0d3aef24b1 100644 --- a/react/features/room-lock/middleware.js +++ b/react/features/room-lock/middleware.ts @@ -1,27 +1,27 @@ -// @flow +import { AnyAction } from 'redux'; +// @ts-expect-error import UIEvents from '../../../service/UI/UIEvents'; +import { IStore } from '../app/types'; import { CONFERENCE_FAILED, CONFERENCE_JOINED, LOCK_STATE_CHANGED, SET_PASSWORD_FAILED -} from '../base/conference'; -import { hideDialog } from '../base/dialog'; +} from '../base/conference/actionTypes'; +import { hideDialog } from '../base/dialog/actions'; import { JitsiConferenceErrors } from '../base/lib-jitsi-meet'; -import { MiddlewareRegistry } from '../base/redux'; -import { - NOTIFICATION_TIMEOUT_TYPE, - showNotification -} from '../notifications'; +import MiddlewareRegistry from '../base/redux/MiddlewareRegistry'; +import { showNotification } from '../notifications/actions'; +import { NOTIFICATION_TIMEOUT_TYPE } from '../notifications/constants'; import { _openPasswordRequiredPrompt } from './actions'; +// eslint-disable-next-line lines-around-comment +// @ts-ignore import { PasswordRequiredPrompt } from './components'; import { LOCKED_REMOTELY } from './constants'; import logger from './logger'; -declare var APP: Object; - /** * Middleware that captures conference failed and checks for password required * error and requests a dialog for user to enter password. @@ -83,7 +83,7 @@ MiddlewareRegistry.register(store => next => action => { * @private * @returns {*} */ -function _conferenceJoined({ dispatch }, next, action) { +function _conferenceJoined({ dispatch }: IStore, next: Function, action: AnyAction) { dispatch(hideDialog(PasswordRequiredPrompt)); return next(action); @@ -101,7 +101,7 @@ function _conferenceJoined({ dispatch }, next, action) { * @private * @returns {*} */ -function _conferenceFailed({ dispatch }, next, action) { +function _conferenceFailed({ dispatch }: IStore, next: Function, action: AnyAction) { const { conference, error } = action; if (conference && error.name === JitsiConferenceErrors.PASSWORD_REQUIRED) { @@ -132,7 +132,7 @@ function _conferenceFailed({ dispatch }, next, action) { * @private * @returns {*} */ -function _setPasswordFailed(store, next, action) { +function _setPasswordFailed(store: IStore, next: Function, action: AnyAction) { if (typeof APP !== 'undefined') { // TODO Remove this logic when displaying of error messages on web is // handled through react/redux. diff --git a/react/features/salesforce/actions.js b/react/features/salesforce/actions.ts similarity index 74% rename from react/features/salesforce/actions.js rename to react/features/salesforce/actions.ts index 149c3a6312..a8015fcf8a 100644 --- a/react/features/salesforce/actions.js +++ b/react/features/salesforce/actions.ts @@ -1,14 +1,13 @@ -// @flow - -import { openDialog } from '../base/dialog'; +import { IStore } from '../app/types'; +import { openDialog } from '../base/dialog/actions'; +import { hideNotification, showNotification } from '../notifications/actions'; import { NOTIFICATION_TIMEOUT_TYPE, NOTIFICATION_TYPE, - SALESFORCE_LINK_NOTIFICATION_ID, - hideNotification, - showNotification -} from '../notifications'; + SALESFORCE_LINK_NOTIFICATION_ID +} from '../notifications/constants'; +// @ts-ignore import { SalesforceLinkDialog } from './components'; import { isSalesforceEnabled } from './functions'; @@ -18,7 +17,7 @@ import { isSalesforceEnabled } from './functions'; * @returns {void} */ export function showSalesforceNotification() { - return (dispatch: Object, getState: Function) => { + return (dispatch: IStore['dispatch'], getState: IStore['getState']) => { if (!isSalesforceEnabled(getState())) { return; } diff --git a/react/features/salesforce/components/web/SalesforceLinkDialog.tsx b/react/features/salesforce/components/web/SalesforceLinkDialog.tsx index 03ac52d0b4..91ec2144d3 100644 --- a/react/features/salesforce/components/web/SalesforceLinkDialog.tsx +++ b/react/features/salesforce/components/web/SalesforceLinkDialog.tsx @@ -13,7 +13,6 @@ import { getFieldValue } from '../../../base/react/functions'; import { withPixelLineHeight } from '../../../base/styles/functions.web'; import Dialog from '../../../base/ui/components/web/Dialog'; import { NOTES_MAX_LENGTH } from '../../constants'; -// @ts-ignore import { useSalesforceLinkDialog } from '../../useSalesforceLinkDialog'; import { RecordItem } from './RecordItem'; @@ -168,7 +167,9 @@ function SalesforceLinkDialog() { const renderSelection = () => (
+ {/* @ts-ignore */} + {/* @ts-ignore */} {selectedRecordOwner && } {hasDetailsErrors && renderDetailsErrors()}
@@ -199,7 +200,7 @@ function SalesforceLinkDialog() { onChange = { handleChange } placeholder = { t('dialog.searchInSalesforce') } tabIndex = { 0 } - value = { searchTerm } /> + value = { searchTerm ?? '' } /> {(!isLoading && !hasRecordsErrors) && (
{showSearchResults diff --git a/react/features/salesforce/functions.js b/react/features/salesforce/functions.ts similarity index 85% rename from react/features/salesforce/functions.js rename to react/features/salesforce/functions.ts index 280fa08f08..e117f674bb 100644 --- a/react/features/salesforce/functions.js +++ b/react/features/salesforce/functions.ts @@ -1,16 +1,15 @@ -// @flow - -import { doGetJSON } from '../base/util'; +import { IReduxState } from '../app/types'; +import { doGetJSON } from '../base/util/httpUtils'; import { isInBreakoutRoom } from '../breakout-rooms/functions'; /** * Determines whether Salesforce is enabled for the current conference. * - * @param {Function|Object} state - The redux store, the redux + * @param {IReduxState} state - The redux store, the redux * {@code getState} function, or the redux state itself. * @returns {boolean} */ -export const isSalesforceEnabled = (state: Function | Object) => { +export const isSalesforceEnabled = (state: IReduxState) => { const { salesforceUrl } = state['features/base/config']; const isBreakoutRoom = isInBreakoutRoom(state); @@ -66,9 +65,12 @@ export async function searchSessionRecords( export async function getSessionRecordDetails( url: string, jwt: string, - item: Object + item: { + id: string; + type: string; + } | null ) { - const fullUrl = `${url}/records/${item.id}?type=${item.type}`; + const fullUrl = `${url}/records/${item?.id}?type=${item?.type}`; return doGetJSON(fullUrl, true, { headers: { @@ -90,7 +92,11 @@ export async function executeLinkMeetingRequest( url: string, jwt: string, sessionId: String, - body: Object + body: { + id?: string; + notes: string; + type?: string; + } ) { const fullUrl = `${url}/sessions/${sessionId}/records/${body.id}`; const res = await fetch(fullUrl, { diff --git a/react/features/salesforce/useSalesforceLinkDialog.js b/react/features/salesforce/useSalesforceLinkDialog.ts similarity index 82% rename from react/features/salesforce/useSalesforceLinkDialog.js rename to react/features/salesforce/useSalesforceLinkDialog.ts index 6401160768..5b81fb25cb 100644 --- a/react/features/salesforce/useSalesforceLinkDialog.js +++ b/react/features/salesforce/useSalesforceLinkDialog.ts @@ -2,14 +2,14 @@ import { useCallback, useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useDispatch, useSelector } from 'react-redux'; -import { getCurrentConference } from '../base/conference'; +import { IReduxState } from '../app/types'; +import { getCurrentConference } from '../base/conference/functions'; +import { hideNotification, showNotification } from '../notifications/actions'; import { NOTIFICATION_TIMEOUT_TYPE, NOTIFICATION_TYPE, - SALESFORCE_LINK_NOTIFICATION_ID, - hideNotification, - showNotification -} from '../notifications'; + SALESFORCE_LINK_NOTIFICATION_ID +} from '../notifications/constants'; import { executeLinkMeetingRequest, @@ -21,18 +21,20 @@ import { export const useSalesforceLinkDialog = () => { const { t } = useTranslation(); const dispatch = useDispatch(); - const [ selectedRecord, setSelectedRecord ] = useState(null); - const [ selectedRecordOwner, setSelectedRecordOwner ] = useState(null); + const [ selectedRecord, setSelectedRecord ] = useState<{ + id: string; name: string; onClick: Function; type: string; } | null>(null); + const [ selectedRecordOwner, setSelectedRecordOwner ] = useState<{ + id: string; name: string; type: string; } | null>(null); const [ records, setRecords ] = useState([]); const [ isLoading, setLoading ] = useState(false); - const [ searchTerm, setSearchTerm ] = useState(null); + const [ searchTerm, setSearchTerm ] = useState(null); const [ notes, setNotes ] = useState(''); const [ hasRecordsErrors, setRecordsErrors ] = useState(false); const [ hasDetailsErrors, setDetailsErrors ] = useState(false); const conference = useSelector(getCurrentConference); const sessionId = conference.getMeetingUniqueId(); - const { salesforceUrl } = useSelector(state => state['features/base/config']); - const { jwt } = useSelector(state => state['features/base/jwt']); + const { salesforceUrl = '' } = useSelector((state: IReduxState) => state['features/base/config']); + const { jwt = '' } = useSelector((state: IReduxState) => state['features/base/jwt']); const showSearchResults = searchTerm && searchTerm.length > 1; const showNoResults = showSearchResults && records.length === 0; @@ -98,8 +100,8 @@ export const useSalesforceLinkDialog = () => { try { await executeLinkMeetingRequest(salesforceUrl, jwt, sessionId, { - id: selectedRecord.id, - type: selectedRecord.type, + id: selectedRecord?.id, + type: selectedRecord?.type, notes }); dispatch(hideNotification(SALESFORCE_LINK_NOTIFICATION_ID)); @@ -108,7 +110,7 @@ export const useSalesforceLinkDialog = () => { uid: SALESFORCE_LINK_NOTIFICATION_ID, appearance: NOTIFICATION_TYPE.SUCCESS }, NOTIFICATION_TIMEOUT_TYPE.LONG)); - } catch (error) { + } catch (error: any) { dispatch(hideNotification(SALESFORCE_LINK_NOTIFICATION_ID)); dispatch(showNotification({ titleKey: 'notify.linkToSalesforceError',