diff --git a/react/features/base/avatar/components/Avatar.js b/react/features/base/avatar/components/Avatar.tsx similarity index 81% rename from react/features/base/avatar/components/Avatar.js rename to react/features/base/avatar/components/Avatar.tsx index 40d2011e5f..6690dcf57b 100644 --- a/react/features/base/avatar/components/Avatar.js +++ b/react/features/base/avatar/components/Avatar.tsx @@ -1,109 +1,111 @@ -// @flow - import React, { PureComponent } from 'react'; import { connect } from 'react-redux'; -import { getParticipantById } from '../../participants'; +import { IReduxState } from '../../../app/types'; +import { getParticipantById } from '../../participants/functions'; +import { IParticipant } from '../../participants/types'; import { getAvatarColor, getInitials, isCORSAvatarURL } from '../functions'; +import { IProps as AbstractProps } from './AbstractStatelessAvatar'; + import { StatelessAvatar } from './'; -export type Props = { +export interface IProps { /** * The URL patterns for URLs that needs to be handled with CORS. */ - _corsAvatarURLs: Array, + _corsAvatarURLs?: Array; /** * Custom avatar backgrounds from branding. */ - _customAvatarBackgrounds: Array, + _customAvatarBackgrounds?: Array; /** * The string we base the initials on (this is generated from a list of precedences). */ - _initialsBase: ?string, + _initialsBase?: string; /** * An URL that we validated that it can be loaded. */ - _loadableAvatarUrl: ?string, + _loadableAvatarUrl?: string; /** * Indicates whether _loadableAvatarUrl should use CORS or not. */ - _loadableAvatarUrlUseCORS: ?boolean, + _loadableAvatarUrlUseCORS?: boolean; /** * A prop to maintain compatibility with web. */ - className?: string, + className?: string; /** * A string to override the initials to generate a color of. This is handy if you don't want to make * the background color match the string that the initials are generated from. */ - colorBase?: string, + colorBase?: string; /** * Display name of the entity to render an avatar for (if any). This is handy when we need - * an avatar for a non-participasnt entity (e.g. A recent list item). + * an avatar for a non-participant entity (e.g. A recent list item). */ - displayName?: string, + displayName?: string; /** * Whether or not to update the background color of the avatar. */ - dynamicColor?: Boolean, + dynamicColor?: boolean; /** * ID of the element, if any. */ - id?: string, + id?: string; /** * The ID of the participant to render an avatar for (if it's a participant avatar). */ - participantId?: string, + participantId?: string; /** * The size of the avatar. */ - size: number, + size: number; /** * One of the expected status strings (e.g. 'available') to render a badge on the avatar, if necessary. */ - status?: ?string, + status?: string; /** * TestId of the element, if any. */ - testId?: string, + testId?: string; /** * URL of the avatar, if any. */ - url: ?string, + url?: string; /** * Indicates whether to load the avatar using CORS or not. */ - useCORS?: ?boolean + useCORS?: boolean; } type State = { - avatarFailed: boolean, - isUsingCORS: boolean -} + avatarFailed: boolean; + isUsingCORS: boolean; +}; export const DEFAULT_SIZE = 65; /** * Implements a class to render avatars in the app. */ -class Avatar extends PureComponent { +class Avatar

extends PureComponent { /** * Default values for {@code Avatar} component's properties. * @@ -179,7 +181,13 @@ class Avatar extends PureComponent { } = this.props; const { avatarFailed, isUsingCORS } = this.state; - const avatarProps = { + const avatarProps: AbstractProps & { + className?: string; + id?: string; + status?: string; + testId?: string; + useCORS?: boolean; + } = { className, color: undefined, id, @@ -212,7 +220,7 @@ class Avatar extends PureComponent { if (initials) { if (dynamicColor) { - avatarProps.color = getAvatarColor(colorBase || _initialsBase, _customAvatarBackgrounds); + avatarProps.color = getAvatarColor(colorBase || _initialsBase, _customAvatarBackgrounds ?? []); } avatarProps.initials = initials; @@ -224,8 +232,6 @@ class Avatar extends PureComponent { ); } - _onAvatarLoadError: () => void; - /** * Callback to handle the error while loading of the avatar URI. * @@ -233,7 +239,7 @@ class Avatar extends PureComponent { * @param {boolean} params.dontRetry - If false we will retry to load the Avatar with different CORS mode. * @returns {void} */ - _onAvatarLoadError(params = {}) { + _onAvatarLoadError(params: any = {}) { const { dontRetry = false } = params; if (Boolean(this.props.useCORS) === this.state.isUsingCORS && !dontRetry) { @@ -254,12 +260,12 @@ class Avatar extends PureComponent { * Maps part of the Redux state to the props of this component. * * @param {Object} state - The Redux state. - * @param {Props} ownProps - The own props of the component. - * @returns {Props} + * @param {IProps} ownProps - The own props of the component. + * @returns {IProps} */ -export function _mapStateToProps(state: Object, ownProps: Props) { +export function _mapStateToProps(state: IReduxState, ownProps: IProps) { const { colorBase, displayName, participantId } = ownProps; - const _participant: ?Object = participantId && getParticipantById(state, participantId); + const _participant: IParticipant | undefined = participantId ? getParticipantById(state, participantId) : undefined; const _initialsBase = _participant?.name ?? displayName; const { corsAvatarURLs } = state['features/base/config']; diff --git a/react/features/base/avatar/components/index.native.js b/react/features/base/avatar/components/index.native.js deleted file mode 100644 index 62d202f325..0000000000 --- a/react/features/base/avatar/components/index.native.js +++ /dev/null @@ -1,4 +0,0 @@ -// @flow - -export * from './native'; -export { default as Avatar } from './Avatar'; diff --git a/react/features/base/avatar/components/index.native.ts b/react/features/base/avatar/components/index.native.ts new file mode 100644 index 0000000000..2dfbe238df --- /dev/null +++ b/react/features/base/avatar/components/index.native.ts @@ -0,0 +1,3 @@ +// @ts-ignore +export { default as StatelessAvatar } from './native/StatelessAvatar'; +export { default as Avatar } from './Avatar'; diff --git a/react/features/base/avatar/components/index.web.js b/react/features/base/avatar/components/index.web.js deleted file mode 100644 index bdc40ea0a5..0000000000 --- a/react/features/base/avatar/components/index.web.js +++ /dev/null @@ -1,4 +0,0 @@ -// @flow - -export * from './web'; -export { default as Avatar } from './Avatar'; diff --git a/react/features/base/avatar/components/index.web.ts b/react/features/base/avatar/components/index.web.ts new file mode 100644 index 0000000000..3d4eaeeead --- /dev/null +++ b/react/features/base/avatar/components/index.web.ts @@ -0,0 +1,2 @@ +export { default as StatelessAvatar } from './web/StatelessAvatar'; +export { default as Avatar } from './Avatar'; diff --git a/react/features/base/avatar/components/native/index.js b/react/features/base/avatar/components/native/index.js deleted file mode 100644 index 82ca95fd84..0000000000 --- a/react/features/base/avatar/components/native/index.js +++ /dev/null @@ -1,3 +0,0 @@ -// @flow - -export { default as StatelessAvatar } from './StatelessAvatar'; diff --git a/react/features/base/avatar/components/web/index.js b/react/features/base/avatar/components/web/index.js deleted file mode 100644 index 82ca95fd84..0000000000 --- a/react/features/base/avatar/components/web/index.js +++ /dev/null @@ -1,3 +0,0 @@ -// @flow - -export { default as StatelessAvatar } from './StatelessAvatar'; diff --git a/react/features/chat/components/web/ChatMessageGroup.tsx b/react/features/chat/components/web/ChatMessageGroup.tsx index c9b9039f78..1e339785a9 100644 --- a/react/features/chat/components/web/ChatMessageGroup.tsx +++ b/react/features/chat/components/web/ChatMessageGroup.tsx @@ -2,8 +2,6 @@ import clsx from 'clsx'; import React from 'react'; import { makeStyles } from 'tss-react/mui'; -// eslint-disable-next-line lines-around-comment -// @ts-ignore import Avatar from '../../../base/avatar/components/Avatar'; import { IMessage } from '../../reducer'; diff --git a/react/features/filmstrip/components/web/Thumbnail.tsx b/react/features/filmstrip/components/web/Thumbnail.tsx index 0ef9988711..a12b7daa50 100644 --- a/react/features/filmstrip/components/web/Thumbnail.tsx +++ b/react/features/filmstrip/components/web/Thumbnail.tsx @@ -10,8 +10,7 @@ import { connect } from 'react-redux'; import { createScreenSharingIssueEvent } from '../../../analytics/AnalyticsEvents'; import { sendAnalytics } from '../../../analytics/functions'; import { IReduxState } from '../../../app/types'; -// @ts-ignore -import { Avatar } from '../../../base/avatar'; +import Avatar from '../../../base/avatar/components/Avatar'; import { isMobileBrowser } from '../../../base/environment/utils'; import { translate } from '../../../base/i18n/functions'; import { JitsiTrackEvents } from '../../../base/lib-jitsi-meet'; diff --git a/react/features/participants-pane/components/breakout-rooms/components/web/RoomParticipantContextMenu.tsx b/react/features/participants-pane/components/breakout-rooms/components/web/RoomParticipantContextMenu.tsx index 8affa5e4aa..d513485783 100644 --- a/react/features/participants-pane/components/breakout-rooms/components/web/RoomParticipantContextMenu.tsx +++ b/react/features/participants-pane/components/breakout-rooms/components/web/RoomParticipantContextMenu.tsx @@ -3,8 +3,7 @@ import { useTranslation } from 'react-i18next'; import { useSelector } from 'react-redux'; import { makeStyles } from 'tss-react/mui'; -// @ts-ignore -import { Avatar } from '../../../../../base/avatar'; +import Avatar from '../../../../../base/avatar/components/Avatar'; import { isLocalParticipantModerator } from '../../../../../base/participants/functions'; import ContextMenu from '../../../../../base/ui/components/web/ContextMenu'; import ContextMenuItemGroup from '../../../../../base/ui/components/web/ContextMenuItemGroup'; diff --git a/react/features/participants-pane/components/native/RoomParticipantMenu.tsx b/react/features/participants-pane/components/native/RoomParticipantMenu.tsx index d4b318bb75..48f997d8a9 100644 --- a/react/features/participants-pane/components/native/RoomParticipantMenu.tsx +++ b/react/features/participants-pane/components/native/RoomParticipantMenu.tsx @@ -5,8 +5,7 @@ import { Text, View } from 'react-native'; import { connect } from 'react-redux'; import { IReduxState } from '../../../app/types'; -// @ts-ignore -import { Avatar } from '../../../base/avatar'; +import Avatar from '../../../base/avatar/components/Avatar'; // @ts-ignore import { BottomSheet, hideSheet } from '../../../base/dialog'; // @ts-ignore diff --git a/react/features/participants-pane/components/web/LobbyParticipants.tsx b/react/features/participants-pane/components/web/LobbyParticipants.tsx index 3bc49cad35..67622ade49 100644 --- a/react/features/participants-pane/components/web/LobbyParticipants.tsx +++ b/react/features/participants-pane/components/web/LobbyParticipants.tsx @@ -3,8 +3,7 @@ import { useTranslation } from 'react-i18next'; import { useDispatch, useSelector } from 'react-redux'; import { makeStyles } from 'tss-react/mui'; -// @ts-ignore -import { Avatar } from '../../../base/avatar'; +import Avatar from '../../../base/avatar/components/Avatar'; import Icon from '../../../base/icons/components/Icon'; import { IconCheck, IconCloseLarge } from '../../../base/icons/svg'; import { withPixelLineHeight } from '../../../base/styles/functions.web'; diff --git a/react/features/participants-pane/components/web/ParticipantItem.tsx b/react/features/participants-pane/components/web/ParticipantItem.tsx index 4afa798707..c86c99a5ca 100644 --- a/react/features/participants-pane/components/web/ParticipantItem.tsx +++ b/react/features/participants-pane/components/web/ParticipantItem.tsx @@ -2,8 +2,7 @@ import React, { ReactElement, useCallback } from 'react'; import { WithTranslation } from 'react-i18next'; import { makeStyles } from 'tss-react/mui'; -// @ts-ignore -import { Avatar } from '../../../base/avatar'; +import Avatar from '../../../base/avatar/components/Avatar'; import ListItem from '../../../base/components/participants-pane-list/ListItem'; import { translate } from '../../../base/i18n/functions'; import { withPixelLineHeight } from '../../../base/styles/functions.web'; diff --git a/react/features/prejoin/components/web/Prejoin.tsx b/react/features/prejoin/components/web/Prejoin.tsx index 6083ad428b..6c80fb6883 100644 --- a/react/features/prejoin/components/web/Prejoin.tsx +++ b/react/features/prejoin/components/web/Prejoin.tsx @@ -4,9 +4,7 @@ import { WithTranslation } from 'react-i18next'; import { connect } from 'react-redux'; import { IReduxState } from '../../../app/types'; -// eslint-disable-next-line lines-around-comment -// @ts-ignore -import { Avatar } from '../../../base/avatar'; +import Avatar from '../../../base/avatar/components/Avatar'; import { isNameReadOnly } from '../../../base/config/functions.web'; import { translate } from '../../../base/i18n/functions'; import { IconArrowDown, IconArrowUp, IconPhoneRinging, IconVolumeOff } from '../../../base/icons/svg'; diff --git a/react/features/prejoin/components/web/dialogs/CallingDialog.tsx b/react/features/prejoin/components/web/dialogs/CallingDialog.tsx index ece85806cb..095b5696eb 100644 --- a/react/features/prejoin/components/web/dialogs/CallingDialog.tsx +++ b/react/features/prejoin/components/web/dialogs/CallingDialog.tsx @@ -2,8 +2,7 @@ import React from 'react'; import { WithTranslation } from 'react-i18next'; import { makeStyles } from 'tss-react/mui'; -// @ts-ignore -import { Avatar } from '../../../../base/avatar'; +import Avatar from '../../../../base/avatar/components/Avatar'; import { translate } from '../../../../base/i18n/functions'; import Icon from '../../../../base/icons/components/Icon'; import { IconCloseLarge } from '../../../../base/icons/svg'; diff --git a/react/features/settings/components/native/SettingsView.tsx b/react/features/settings/components/native/SettingsView.tsx index d74fa4e033..20b2e5ed8a 100644 --- a/react/features/settings/components/native/SettingsView.tsx +++ b/react/features/settings/components/native/SettingsView.tsx @@ -18,8 +18,7 @@ import { connect } from 'react-redux'; import { getDefaultURL } from '../../../app/functions.native'; import { IReduxState } from '../../../app/types'; -// @ts-ignore -import { Avatar } from '../../../base/avatar'; +import Avatar from '../../../base/avatar/components/Avatar'; import { getLegalUrls } from '../../../base/config/functions.native'; import { translate } from '../../../base/i18n/functions'; // @ts-ignore diff --git a/react/features/settings/components/web/ProfileTab.tsx b/react/features/settings/components/web/ProfileTab.tsx index 29b9c91cad..d3f080c7ae 100644 --- a/react/features/settings/components/web/ProfileTab.tsx +++ b/react/features/settings/components/web/ProfileTab.tsx @@ -7,8 +7,6 @@ import { WithTranslation } from 'react-i18next'; import UIEvents from '../../../../../service/UI/UIEvents'; import { createProfilePanelButtonEvent } from '../../../analytics/AnalyticsEvents'; import { sendAnalytics } from '../../../analytics/functions'; -// eslint-disable-next-line lines-around-comment -// @ts-ignore import Avatar from '../../../base/avatar/components/Avatar'; import AbstractDialogTab, { IProps as AbstractDialogTabProps } from '../../../base/dialog/components/web/AbstractDialogTab'; diff --git a/react/features/speaker-stats/components/web/SpeakerStatsItem.tsx b/react/features/speaker-stats/components/web/SpeakerStatsItem.tsx index ea52549d54..1d74d7a6ee 100644 --- a/react/features/speaker-stats/components/web/SpeakerStatsItem.tsx +++ b/react/features/speaker-stats/components/web/SpeakerStatsItem.tsx @@ -1,7 +1,6 @@ // eslint-disable-next-line lines-around-comment import React from 'react'; -// @ts-ignore import Avatar from '../../../base/avatar/components/Avatar'; import StatelessAvatar from '../../../base/avatar/components/web/StatelessAvatar'; import { getInitials } from '../../../base/avatar/functions'; diff --git a/react/features/video-menu/components/native/ConnectionStatusComponent.tsx b/react/features/video-menu/components/native/ConnectionStatusComponent.tsx index 1405c2a631..1d531ca467 100644 --- a/react/features/video-menu/components/native/ConnectionStatusComponent.tsx +++ b/react/features/video-menu/components/native/ConnectionStatusComponent.tsx @@ -7,7 +7,6 @@ import { withTheme } from 'react-native-paper'; import { connect } from 'react-redux'; import { IReduxState } from '../../../app/types'; -// @ts-ignore import Avatar from '../../../base/avatar/components/Avatar'; import { hideSheet } from '../../../base/dialog/actions'; // @ts-ignore diff --git a/react/features/video-menu/components/web/FakeParticipantContextMenu.tsx b/react/features/video-menu/components/web/FakeParticipantContextMenu.tsx index c839c8595c..d2d9055cfb 100644 --- a/react/features/video-menu/components/web/FakeParticipantContextMenu.tsx +++ b/react/features/video-menu/components/web/FakeParticipantContextMenu.tsx @@ -4,9 +4,7 @@ import { useDispatch, useSelector } from 'react-redux'; // @ts-ignore import TogglePinToStageButton from '../../../../features/video-menu/components/web/TogglePinToStageButton'; -// eslint-disable-next-line lines-around-comment -// @ts-ignore -import { Avatar } from '../../../base/avatar'; +import Avatar from '../../../base/avatar/components/Avatar'; import { IconPlay } from '../../../base/icons/svg'; import { isWhiteboardParticipant } from '../../../base/participants/functions'; import { IParticipant } from '../../../base/participants/types'; diff --git a/react/features/video-menu/components/web/ParticipantContextMenu.tsx b/react/features/video-menu/components/web/ParticipantContextMenu.tsx index 3c9d2aa39d..419d292d79 100644 --- a/react/features/video-menu/components/web/ParticipantContextMenu.tsx +++ b/react/features/video-menu/components/web/ParticipantContextMenu.tsx @@ -7,8 +7,7 @@ import { makeStyles } from 'tss-react/mui'; import { IReduxState } from '../../../app/types'; import { isSupported as isAvModerationSupported } from '../../../av-moderation/functions'; -// @ts-ignore -import { Avatar } from '../../../base/avatar'; +import Avatar from '../../../base/avatar/components/Avatar'; import { isIosMobileBrowser, isMobileBrowser } from '../../../base/environment/utils'; import { MEDIA_TYPE } from '../../../base/media/constants'; import { PARTICIPANT_ROLE } from '../../../base/participants/constants';