diff --git a/src/Analytics.tsx b/src/Analytics.tsx index 23b278929a..639950574d 100644 --- a/src/Analytics.tsx +++ b/src/Analytics.tsx @@ -23,7 +23,7 @@ import { getCurrentLanguage, _t, _td, IVariables } from './languageHandler'; import PlatformPeg from './PlatformPeg'; import SdkConfig from './SdkConfig'; import Modal from './Modal'; -import * as sdk from './index'; +import ErrorDialog from "./components/views/dialogs/ErrorDialog"; import { SnakedObject } from "./utils/SnakedObject"; import { IConfigOptions } from "./IConfigOptions"; @@ -406,14 +406,12 @@ export class Analytics { { expl: _td('Your device resolution'), value: resolution }, ]; - // FIXME: Using an import will result in test failures const piwikConfig = SdkConfig.get("piwik"); let piwik: Optional>>; if (typeof piwikConfig === 'object') { piwik = new SnakedObject(piwikConfig); } const cookiePolicyUrl = piwik?.get("policy_url"); - const ErrorDialog = sdk.getComponent('dialogs.ErrorDialog'); const cookiePolicyLink = _t( "Our complete cookie policy can be found here.", {}, diff --git a/src/AsyncWrapper.tsx b/src/AsyncWrapper.tsx index 166e4f21e3..07a06f20d4 100644 --- a/src/AsyncWrapper.tsx +++ b/src/AsyncWrapper.tsx @@ -17,9 +17,11 @@ limitations under the License. import React, { ComponentType } from "react"; import { logger } from "matrix-js-sdk/src/logger"; -import * as sdk from './index'; import { _t } from './languageHandler'; import { IDialogProps } from "./components/views/dialogs/IDialogProps"; +import BaseDialog from "./components/views/dialogs/BaseDialog"; +import DialogButtons from "./components/views/elements/DialogButtons"; +import Spinner from "./components/views/elements/Spinner"; type AsyncImport = { default: T }; @@ -78,9 +80,6 @@ export default class AsyncWrapper extends React.Component { const Component = this.state.component; return ; } else if (this.state.error) { - // FIXME: Using an import will result in test failures - const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); - const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); return { _t("Unable to load! Check your network connectivity and try again.") } { ; } else { // show a spinner until the component is loaded. - const Spinner = sdk.getComponent("elements.Spinner"); return ; } } diff --git a/src/ContentMessages.ts b/src/ContentMessages.ts index babe4563f7..ed0999fe07 100644 --- a/src/ContentMessages.ts +++ b/src/ContentMessages.ts @@ -28,7 +28,6 @@ import { THREAD_RELATION_TYPE } from "matrix-js-sdk/src/models/thread"; import { IEncryptedFile, IMediaEventInfo } from "./customisations/models/IMediaEventContent"; import dis from './dispatcher/dispatcher'; -import * as sdk from './index'; import { _t } from './languageHandler'; import Modal from './Modal'; import Spinner from "./components/views/elements/Spinner"; @@ -47,6 +46,9 @@ import { decorateStartSendingTime, sendRoundTripMetric } from "./sendTimePerform import { TimelineRenderingType } from "./contexts/RoomContext"; import RoomViewStore from "./stores/RoomViewStore"; import { addReplyToMessageContent } from "./utils/Reply"; +import ErrorDialog from "./components/views/dialogs/ErrorDialog"; +import UploadFailureDialog from "./components/views/dialogs/UploadFailureDialog"; +import UploadConfirmDialog from "./components/views/dialogs/UploadConfirmDialog"; const MAX_WIDTH = 800; const MAX_HEIGHT = 600; @@ -485,8 +487,6 @@ export default class ContentMessages { } if (tooBigFiles.length > 0) { - // FIXME: Using an import will result in Element crashing - const UploadFailureDialog = sdk.getComponent("dialogs.UploadFailureDialog"); const { finished } = Modal.createTrackedDialog<[boolean]>('Upload Failure', '', UploadFailureDialog, { badFiles: tooBigFiles, totalFiles: files.length, @@ -503,8 +503,6 @@ export default class ContentMessages { for (let i = 0; i < okFiles.length; ++i) { const file = okFiles[i]; if (!uploadAll) { - // FIXME: Using an import will result in Element crashing - const UploadConfirmDialog = sdk.getComponent("dialogs.UploadConfirmDialog"); const { finished } = Modal.createTrackedDialog<[boolean, boolean]>('Upload Files confirmation', '', UploadConfirmDialog, { file, @@ -686,8 +684,6 @@ export default class ContentMessages { { fileName: upload.fileName }, ); } - // FIXME: Using an import will result in Element crashing - const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); Modal.createTrackedDialog('Upload failed', '', ErrorDialog, { title: _t('Upload Failed'), description: desc, diff --git a/src/MatrixClientPeg.ts b/src/MatrixClientPeg.ts index c8502b0795..7949518fc2 100644 --- a/src/MatrixClientPeg.ts +++ b/src/MatrixClientPeg.ts @@ -27,7 +27,6 @@ import { verificationMethods } from 'matrix-js-sdk/src/crypto'; import { SHOW_QR_CODE_METHOD } from "matrix-js-sdk/src/crypto/verification/QRCode"; import { logger } from "matrix-js-sdk/src/logger"; -import * as sdk from './index'; import createMatrixClient from './utils/createMatrixClient'; import SettingsStore from './settings/SettingsStore'; import MatrixActionCreators from './actions/MatrixActionCreators'; @@ -37,6 +36,7 @@ import * as StorageManager from './utils/StorageManager'; import IdentityAuthClient from './IdentityAuthClient'; import { crossSigningCallbacks, tryToUnlockSecretStorageWithDehydrationKey } from './SecurityManager'; import SecurityCustomisations from "./customisations/Security"; +import CryptoStoreTooNewDialog from "./components/views/dialogs/CryptoStoreTooNewDialog"; export interface IMatrixClientCreds { homeserverUrl: string; @@ -200,9 +200,6 @@ class MatrixClientPegClass implements IMatrixClientPeg { } catch (e) { if (e && e.name === 'InvalidCryptoStoreError') { // The js-sdk found a crypto DB too new for it to use - // FIXME: Using an import will result in test failures - const CryptoStoreTooNewDialog = - sdk.getComponent("views.dialogs.CryptoStoreTooNewDialog"); Modal.createDialog(CryptoStoreTooNewDialog); } // this can happen for a number of reasons, the most likely being diff --git a/src/SecurityManager.ts b/src/SecurityManager.ts index 0383b50fc4..f3d254d059 100644 --- a/src/SecurityManager.ts +++ b/src/SecurityManager.ts @@ -25,7 +25,6 @@ import { logger } from "matrix-js-sdk/src/logger"; import { ComponentType } from "react"; import Modal from './Modal'; -import * as sdk from './index'; import { MatrixClientPeg } from './MatrixClientPeg'; import { _t } from './languageHandler'; import { isSecureBackupRequired } from './utils/WellKnownUtils'; @@ -34,6 +33,7 @@ import RestoreKeyBackupDialog from './components/views/dialogs/security/RestoreK import SettingsStore from "./settings/SettingsStore"; import SecurityCustomisations from "./customisations/Security"; import QuestionDialog from "./components/views/dialogs/QuestionDialog"; +import InteractiveAuthDialog from "./components/views/dialogs/InteractiveAuthDialog"; // This stores the secret storage private keys in memory for the JS SDK. This is // only meant to act as a cache to avoid prompting the user multiple times @@ -360,8 +360,6 @@ export async function accessSecretStorage(func = async () => { }, forceReset = f throw new Error("Secret storage creation canceled"); } } else { - // FIXME: Using an import will result in test failures - const InteractiveAuthDialog = sdk.getComponent("dialogs.InteractiveAuthDialog"); await cli.bootstrapCrossSigning({ authUploadDeviceSigningKeys: async (makeRequest) => { const { finished } = Modal.createTrackedDialog( diff --git a/src/Terms.ts b/src/Terms.ts index 4b1480f536..aa94309ae3 100644 --- a/src/Terms.ts +++ b/src/Terms.ts @@ -19,8 +19,8 @@ import { SERVICE_TYPES } from 'matrix-js-sdk/src/service-types'; import { logger } from "matrix-js-sdk/src/logger"; import { MatrixClientPeg } from './MatrixClientPeg'; -import * as sdk from '.'; import Modal from './Modal'; +import TermsDialog from "./components/views/dialogs/TermsDialog"; export class TermsNotSignedError extends Error {} @@ -189,8 +189,6 @@ export async function dialogTermsInteractionCallback( extraClassNames?: string, ): Promise { logger.log("Terms that need agreement", policiesAndServicePairs); - // FIXME: Using an import will result in test failures - const TermsDialog = sdk.getComponent("views.dialogs.TermsDialog"); const { finished } = Modal.createTrackedDialog<[boolean, string[]]>('Terms of Service', '', TermsDialog, { policiesAndServicePairs, diff --git a/src/components/structures/HomePage.tsx b/src/components/structures/HomePage.tsx index 6ee31114ef..fdcb52a687 100644 --- a/src/components/structures/HomePage.tsx +++ b/src/components/structures/HomePage.tsx @@ -21,7 +21,6 @@ import AutoHideScrollbar from './AutoHideScrollbar'; import { getHomePageUrl } from "../../utils/pages"; import { _tDom } from "../../languageHandler"; import SdkConfig from "../../SdkConfig"; -import * as sdk from "../../index"; import dis from "../../dispatcher/dispatcher"; import { Action } from "../../dispatcher/actions"; import BaseAvatar from "../views/avatars/BaseAvatar"; @@ -33,6 +32,7 @@ import MatrixClientContext from "../../contexts/MatrixClientContext"; import MiniAvatarUploader, { AVATAR_SIZE } from "../views/elements/MiniAvatarUploader"; import Analytics from "../../Analytics"; import PosthogTrackers from "../../PosthogTrackers"; +import EmbeddedPage from "./EmbeddedPage"; const onClickSendDm = () => { Analytics.trackEvent('home_page', 'button', 'dm'); @@ -94,8 +94,6 @@ const HomePage: React.FC = ({ justRegistered = false }) => { const pageUrl = getHomePageUrl(config); if (pageUrl) { - // FIXME: Using an import will result in wrench-element-tests failures - const EmbeddedPage = sdk.getComponent('structures.EmbeddedPage'); return ; } diff --git a/src/components/views/auth/Welcome.tsx b/src/components/views/auth/Welcome.tsx index ad35ee0186..e76dabb4db 100644 --- a/src/components/views/auth/Welcome.tsx +++ b/src/components/views/auth/Welcome.tsx @@ -17,13 +17,13 @@ limitations under the License. import React from 'react'; import classNames from "classnames"; -import * as sdk from "../../../index"; import SdkConfig from '../../../SdkConfig'; import AuthPage from "./AuthPage"; import { _td } from "../../../languageHandler"; import SettingsStore from "../../../settings/SettingsStore"; import { UIFeature } from "../../../settings/UIFeature"; import LanguageSelector from "./LanguageSelector"; +import EmbeddedPage from "../../structures/EmbeddedPage"; // translatable strings for Welcome pages _td("Sign in with SSO"); @@ -34,9 +34,6 @@ interface IProps { export default class Welcome extends React.PureComponent { public render(): React.ReactNode { - // FIXME: Using an import will result in wrench-element-tests failures - const EmbeddedPage = sdk.getComponent("structures.EmbeddedPage"); - const pagesConfig = SdkConfig.getObject("embedded_pages"); let pageUrl = null; if (pagesConfig) { diff --git a/src/components/views/dialogs/InfoDialog.tsx b/src/components/views/dialogs/InfoDialog.tsx index ddcea275a9..dd9c985f8e 100644 --- a/src/components/views/dialogs/InfoDialog.tsx +++ b/src/components/views/dialogs/InfoDialog.tsx @@ -19,8 +19,9 @@ import React, { ReactNode, KeyboardEvent } from 'react'; import classNames from "classnames"; import { _t } from '../../../languageHandler'; -import * as sdk from '../../../index'; import { IDialogProps } from "./IDialogProps"; +import BaseDialog from "./BaseDialog"; +import DialogButtons from "../elements/DialogButtons"; interface IProps extends IDialogProps { title?: string; @@ -44,9 +45,6 @@ export default class InfoDialog extends React.Component { }; render() { - // FIXME: Using a regular import will break the app - const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); - const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); return ( { }; public render(): JSX.Element { - // Converting these to imports breaks wrench tests - const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); - const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); - let primaryButtonClass = ""; if (this.props.danger) { primaryButtonClass = "danger"; diff --git a/src/components/views/dialogs/security/AccessSecretStorageDialog.tsx b/src/components/views/dialogs/security/AccessSecretStorageDialog.tsx index 090eac783e..f0dca76bfb 100644 --- a/src/components/views/dialogs/security/AccessSecretStorageDialog.tsx +++ b/src/components/views/dialogs/security/AccessSecretStorageDialog.tsx @@ -20,7 +20,6 @@ import React, { ChangeEvent, FormEvent } from 'react'; import { ISecretStorageKeyInfo } from "matrix-js-sdk/src/crypto/api"; import { logger } from "matrix-js-sdk/src/logger"; -import * as sdk from '../../../../index'; import { MatrixClientPeg } from '../../../../MatrixClientPeg'; import Field from '../../elements/Field'; import AccessibleButton from '../../elements/AccessibleButton'; @@ -28,6 +27,9 @@ import { _t } from '../../../../languageHandler'; import { IDialogProps } from "../IDialogProps"; import { accessSecretStorage } from "../../../../SecurityManager"; import Modal from "../../../../Modal"; +import InteractiveAuthDialog from "../InteractiveAuthDialog"; +import DialogButtons from "../../elements/DialogButtons"; +import BaseDialog from "../BaseDialog"; // Maximum acceptable size of a key file. It's 59 characters including the spaces we encode, // so this should be plenty and allow for people putting extra whitespace in the file because @@ -230,8 +232,6 @@ export default class AccessSecretStorageDialog extends React.PureComponent { - // XXX: Making this an import breaks the app. - const InteractiveAuthDialog = sdk.getComponent("views.dialogs.InteractiveAuthDialog"); const { finished } = Modal.createTrackedDialog( 'Cross-signing keys dialog', '', InteractiveAuthDialog, { @@ -273,10 +273,6 @@ export default class AccessSecretStorageDialog extends React.PureComponent ; } else if (hasPassphrase && !this.state.forceRecoveryKey) { - const AccessibleButton = sdk.getComponent('elements.AccessibleButton'); title = _t("Security Phrase"); titleClass = ['mx_AccessSecretStorageDialog_titleWithIcon mx_AccessSecretStorageDialog_securePhraseTitle']; diff --git a/src/components/views/dialogs/security/RestoreKeyBackupDialog.tsx b/src/components/views/dialogs/security/RestoreKeyBackupDialog.tsx index 3db78f6877..719c31c48f 100644 --- a/src/components/views/dialogs/security/RestoreKeyBackupDialog.tsx +++ b/src/components/views/dialogs/security/RestoreKeyBackupDialog.tsx @@ -24,8 +24,11 @@ import { logger } from "matrix-js-sdk/src/logger"; import { MatrixClientPeg } from '../../../../MatrixClientPeg'; import { _t } from '../../../../languageHandler'; import { accessSecretStorage } from '../../../../SecurityManager'; -import * as sdk from '../../../../index'; import { IDialogProps } from "../IDialogProps"; +import Spinner from '../../elements/Spinner'; +import DialogButtons from "../../elements/DialogButtons"; +import AccessibleButton from "../../elements/AccessibleButton"; +import BaseDialog from "../BaseDialog"; enum RestoreType { Passphrase = "passphrase", @@ -298,12 +301,6 @@ export default class RestoreKeyBackupDialog extends React.PureComponent { ); // Handle displaying feedback on validity - // FIXME: Using an import will result in test failures - const Tooltip = sdk.getComponent("elements.Tooltip"); let fieldTooltip; if (tooltipContent || this.state.feedback) { fieldTooltip = { @@ -70,23 +78,25 @@ export default class MessageEvent extends React.Component implements IMe } } - private get bodyTypes(): Record { + private get bodyTypes(): Record { return { - [MsgType.Text]: sdk.getComponent('messages.TextualBody'), - [MsgType.Notice]: sdk.getComponent('messages.TextualBody'), - [MsgType.Emote]: sdk.getComponent('messages.TextualBody'), - [MsgType.Image]: sdk.getComponent('messages.MImageBody'), - [MsgType.File]: sdk.getComponent('messages.MFileBody'), - [MsgType.Audio]: sdk.getComponent('messages.MVoiceOrAudioBody'), - [MsgType.Video]: sdk.getComponent('messages.MVideoBody'), + [MsgType.Text]: TextualBody, + [MsgType.Notice]: TextualBody, + [MsgType.Emote]: TextualBody, + [MsgType.Image]: MImageBody, + [MsgType.File]: MFileBody, + [MsgType.Audio]: MVoiceOrAudioBody, + [MsgType.Video]: MVideoBody, ...(this.props.overrideBodyTypes || {}), }; } - private get evTypes(): Record { + private get evTypes(): Record { return { - [EventType.Sticker]: sdk.getComponent('messages.MStickerBody'), + [EventType.Sticker]: MStickerBody, + [M_POLL_START.name]: MPollBody, + [M_POLL_START.altName]: MPollBody, ...(this.props.overrideEventTypes || {}), }; @@ -108,7 +118,7 @@ export default class MessageEvent extends React.Component implements IMe const content = this.props.mxEvent.getContent(); const type = this.props.mxEvent.getType(); const msgtype = content.msgtype; - let BodyType: ReactAnyComponent = RedactedBody; + let BodyType: typeof React.Component | ReactAnyComponent = RedactedBody; if (!this.props.mxEvent.isRedacted()) { // only resolve BodyType if event is not redacted if (type && this.evTypes[type]) { @@ -123,17 +133,12 @@ export default class MessageEvent extends React.Component implements IMe BodyType = UnknownBody; } - // TODO: move to eventTypes when Polls spec stabilises - if (M_POLL_START.matches(type)) { - BodyType = sdk.getComponent('messages.MPollBody'); - } - // TODO: move to eventTypes when location sharing spec stabilises if ( M_LOCATION.matches(type) || (type === EventType.RoomMessage && msgtype === MsgType.Location) ) { - BodyType = sdk.getComponent('messages.MLocationBody'); + BodyType = MLocationBody; } } @@ -147,7 +152,7 @@ export default class MessageEvent extends React.Component implements IMe const serverBanned = Mjolnir.sharedInstance().isServerBanned(userDomain); if (userBanned || serverBanned) { - BodyType = sdk.getComponent('messages.MjolnirBody'); + BodyType = MjolnirBody; } } } diff --git a/src/components/views/right_panel/EncryptionPanel.tsx b/src/components/views/right_panel/EncryptionPanel.tsx index 2cfd4851e0..c2dfd7a379 100644 --- a/src/components/views/right_panel/EncryptionPanel.tsx +++ b/src/components/views/right_panel/EncryptionPanel.tsx @@ -30,10 +30,10 @@ import { MatrixClientPeg } from "../../../MatrixClientPeg"; import { ensureDMExists } from "../../../createRoom"; import { useTypedEventEmitter } from "../../../hooks/useEventEmitter"; import Modal from "../../../Modal"; -import * as sdk from "../../../index"; import { _t } from "../../../languageHandler"; import { RightPanelPhases } from '../../../stores/right-panel/RightPanelStorePhases'; import RightPanelStore from "../../../stores/right-panel/RightPanelStore"; +import ErrorDialog from "../dialogs/ErrorDialog"; // cancellation codes which constitute a key mismatch const MISMATCHES = ["m.key_mismatch", "m.user_error", "m.mismatched_sas"]; @@ -84,8 +84,6 @@ const EncryptionPanel: React.FC = (props: IProps) => { const changeHandler = useCallback(() => { // handle transitions -> cancelled for mismatches which fire a modal instead of showing a card if (request && request.cancelled && MISMATCHES.includes(request.cancellationCode)) { - // FIXME: Using an import will result in test failures - const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); Modal.createTrackedDialog("Verification failed", "insecure", ErrorDialog, { headerImage: require("../../../../res/img/e2e/warning.svg").default, title: _t("Your messages are not secure"), diff --git a/src/components/views/rooms/RoomDetailRow.js b/src/components/views/rooms/RoomDetailRow.js index 72d40cf6e0..47071adf85 100644 --- a/src/components/views/rooms/RoomDetailRow.js +++ b/src/components/views/rooms/RoomDetailRow.js @@ -17,11 +17,11 @@ limitations under the License. import React, { createRef } from 'react'; import PropTypes from 'prop-types'; -import * as sdk from '../../../index'; import { _t } from '../../../languageHandler'; import { linkifyElement } from '../../../HtmlUtils'; import { mediaFromMxc } from "../../../customisations/Media"; import { getDisplayAliasForAliasSet } from '../../../Rooms'; +import BaseAvatar from "../avatars/BaseAvatar"; export function getDisplayAliasForRoom(room) { return getDisplayAliasForAliasSet(room.canonicalAlias, room.aliases); @@ -82,8 +82,6 @@ export default class RoomDetailRow extends React.Component { }; render() { - const BaseAvatar = sdk.getComponent('avatars.BaseAvatar'); - const room = this.props.room; const name = room.name || getDisplayAliasForRoom(room) || _t('Unnamed room'); diff --git a/src/stores/RoomViewStore.tsx b/src/stores/RoomViewStore.tsx index 90ba1f8844..44f049c27e 100644 --- a/src/stores/RoomViewStore.tsx +++ b/src/stores/RoomViewStore.tsx @@ -28,7 +28,6 @@ import { ClientEvent } from "matrix-js-sdk/src/client"; import dis from '../dispatcher/dispatcher'; import { MatrixClientPeg } from '../MatrixClientPeg'; -import * as sdk from '../index'; import Modal from '../Modal'; import { _t } from '../languageHandler'; import { getCachedRoomIDForAlias, storeRoomAliasInCache } from '../RoomAliasCache'; @@ -45,6 +44,8 @@ import { JoinRoomPayload } from "../dispatcher/payloads/JoinRoomPayload"; import { JoinRoomReadyPayload } from "../dispatcher/payloads/JoinRoomReadyPayload"; import { JoinRoomErrorPayload } from "../dispatcher/payloads/JoinRoomErrorPayload"; import { ViewRoomErrorPayload } from "../dispatcher/payloads/ViewRoomErrorPayload"; +import RoomSettingsDialog from "../components/views/dialogs/RoomSettingsDialog"; +import ErrorDialog from "../components/views/dialogs/ErrorDialog"; const NUM_JOIN_RETRY = 5; @@ -211,8 +212,6 @@ class RoomViewStore extends Store { } break; case 'open_room_settings': { - // FIXME: Using an import will result in test failures - const RoomSettingsDialog = sdk.getComponent("dialogs.RoomSettingsDialog"); Modal.createTrackedDialog('Room settings', '', RoomSettingsDialog, { roomId: payload.room_id || this.state.roomId, initialTabId: payload.initial_tab_id, @@ -402,8 +401,6 @@ class RoomViewStore extends Store { } } - // FIXME: Using an import will result in test failures - const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); Modal.createTrackedDialog('Failed to join room', '', ErrorDialog, { title: _t("Failed to join room"), description: msg,