diff --git a/src/components/views/dialogs/ConfirmWipeDeviceDialog.js b/src/components/views/dialogs/ConfirmWipeDeviceDialog.js index 41ef9131fa..4faaad0f7e 100644 --- a/src/components/views/dialogs/ConfirmWipeDeviceDialog.js +++ b/src/components/views/dialogs/ConfirmWipeDeviceDialog.js @@ -18,7 +18,9 @@ import React from 'react'; import PropTypes from 'prop-types'; import {_t} from "../../../languageHandler"; import * as sdk from "../../../index"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.dialogs.ConfirmWipeDeviceDialog") export default class ConfirmWipeDeviceDialog extends React.Component { static propTypes = { onFinished: PropTypes.func.isRequired, diff --git a/src/components/views/dialogs/CreateCommunityPrototypeDialog.tsx b/src/components/views/dialogs/CreateCommunityPrototypeDialog.tsx index 1d9d92b9c9..9b4484d661 100644 --- a/src/components/views/dialogs/CreateCommunityPrototypeDialog.tsx +++ b/src/components/views/dialogs/CreateCommunityPrototypeDialog.tsx @@ -25,6 +25,7 @@ import InfoTooltip from "../elements/InfoTooltip"; import dis from "../../../dispatcher/dispatcher"; import {showCommunityRoomInviteDialog} from "../../../RoomInvite"; import GroupStore from "../../../stores/GroupStore"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps extends IDialogProps { } @@ -38,6 +39,7 @@ interface IState { avatarPreview: string; } +@replaceableComponent("views.dialogs.CreateCommunityPrototypeDialog") export default class CreateCommunityPrototypeDialog extends React.PureComponent { private avatarUploadRef: React.RefObject = React.createRef(); diff --git a/src/components/views/dialogs/CreateGroupDialog.js b/src/components/views/dialogs/CreateGroupDialog.js index 6636153c98..e6c7a67aca 100644 --- a/src/components/views/dialogs/CreateGroupDialog.js +++ b/src/components/views/dialogs/CreateGroupDialog.js @@ -20,7 +20,9 @@ import * as sdk from '../../../index'; import dis from '../../../dispatcher/dispatcher'; import { _t } from '../../../languageHandler'; import {MatrixClientPeg} from '../../../MatrixClientPeg'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.dialogs.CreateGroupDialog") export default class CreateGroupDialog extends React.Component { static propTypes = { onFinished: PropTypes.func.isRequired, diff --git a/src/components/views/dialogs/CreateRoomDialog.js b/src/components/views/dialogs/CreateRoomDialog.js index 0771b0ec45..e9dc6e2be0 100644 --- a/src/components/views/dialogs/CreateRoomDialog.js +++ b/src/components/views/dialogs/CreateRoomDialog.js @@ -27,7 +27,9 @@ import {MatrixClientPeg} from '../../../MatrixClientPeg'; import {Key} from "../../../Keyboard"; import {privateShouldBeEncrypted} from "../../../createRoom"; import {CommunityPrototypeStore} from "../../../stores/CommunityPrototypeStore"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.dialogs.CreateRoomDialog") export default class CreateRoomDialog extends React.Component { static propTypes = { onFinished: PropTypes.func.isRequired, diff --git a/src/components/views/dialogs/DeactivateAccountDialog.js b/src/components/views/dialogs/DeactivateAccountDialog.js index fca8c42546..4e52549d51 100644 --- a/src/components/views/dialogs/DeactivateAccountDialog.js +++ b/src/components/views/dialogs/DeactivateAccountDialog.js @@ -26,7 +26,9 @@ import { _t } from '../../../languageHandler'; import InteractiveAuth, {ERROR_USER_CANCELLED} from "../../structures/InteractiveAuth"; import {DEFAULT_PHASE, PasswordAuthEntry, SSOAuthEntry} from "../auth/InteractiveAuthEntryComponents"; import StyledCheckbox from "../elements/StyledCheckbox"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.dialogs.DeactivateAccountDialog") export default class DeactivateAccountDialog extends React.Component { constructor(props) { super(props); diff --git a/src/components/views/dialogs/DevtoolsDialog.js b/src/components/views/dialogs/DevtoolsDialog.js index 814378bb51..9b24aaa571 100644 --- a/src/components/views/dialogs/DevtoolsDialog.js +++ b/src/components/views/dialogs/DevtoolsDialog.js @@ -38,6 +38,7 @@ import {SETTINGS} from "../../../settings/Settings"; import SettingsStore, {LEVEL_ORDER} from "../../../settings/SettingsStore"; import Modal from "../../../Modal"; import ErrorDialog from "./ErrorDialog"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; class GenericEditor extends React.PureComponent { // static propTypes = {onBack: PropTypes.func.isRequired}; @@ -1089,6 +1090,7 @@ const Entries = [ SettingsExplorer, ]; +@replaceableComponent("views.dialogs.DevtoolsDialog") export default class DevtoolsDialog extends React.PureComponent { static propTypes = { roomId: PropTypes.string.isRequired, diff --git a/src/components/views/dialogs/EditCommunityPrototypeDialog.tsx b/src/components/views/dialogs/EditCommunityPrototypeDialog.tsx index 3071854b3e..504d563bd9 100644 --- a/src/components/views/dialogs/EditCommunityPrototypeDialog.tsx +++ b/src/components/views/dialogs/EditCommunityPrototypeDialog.tsx @@ -23,6 +23,7 @@ import AccessibleButton from "../elements/AccessibleButton"; import { MatrixClientPeg } from "../../../MatrixClientPeg"; import { CommunityPrototypeStore } from "../../../stores/CommunityPrototypeStore"; import FlairStore from "../../../stores/FlairStore"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps extends IDialogProps { communityId: string; @@ -38,6 +39,7 @@ interface IState { } // XXX: This is a lot of duplication from the create dialog, just in a different shape +@replaceableComponent("views.dialogs.EditCommunityPrototypeDialog") export default class EditCommunityPrototypeDialog extends React.PureComponent { private avatarUploadRef: React.RefObject = React.createRef(); diff --git a/src/components/views/dialogs/ErrorDialog.js b/src/components/views/dialogs/ErrorDialog.js index 3bfa635adf..5197c68b5a 100644 --- a/src/components/views/dialogs/ErrorDialog.js +++ b/src/components/views/dialogs/ErrorDialog.js @@ -29,7 +29,9 @@ import React from 'react'; import PropTypes from 'prop-types'; import * as sdk from '../../../index'; import { _t } from '../../../languageHandler'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.dialogs.ErrorDialog") export default class ErrorDialog extends React.Component { static propTypes = { title: PropTypes.string, diff --git a/src/components/views/dialogs/HostSignupDialog.tsx b/src/components/views/dialogs/HostSignupDialog.tsx index 45a03b7cf0..c8bc907136 100644 --- a/src/components/views/dialogs/HostSignupDialog.tsx +++ b/src/components/views/dialogs/HostSignupDialog.tsx @@ -31,6 +31,7 @@ import { IPostmessageResponseData, PostmessageAction, } from "./HostSignupDialogTypes"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; const HOST_SIGNUP_KEY = "host_signup"; @@ -42,6 +43,7 @@ interface IState { minimized: boolean; } +@replaceableComponent("views.dialogs.HostSignupDialog") export default class HostSignupDialog extends React.PureComponent { private iframeRef: React.RefObject = React.createRef(); private readonly config: IHostSignupConfig; diff --git a/src/components/views/dialogs/IncomingSasDialog.js b/src/components/views/dialogs/IncomingSasDialog.js index 2a4ff9cec3..d65ec7563f 100644 --- a/src/components/views/dialogs/IncomingSasDialog.js +++ b/src/components/views/dialogs/IncomingSasDialog.js @@ -19,6 +19,7 @@ import PropTypes from 'prop-types'; import {MatrixClientPeg} from '../../../MatrixClientPeg'; import * as sdk from '../../../index'; import { _t } from '../../../languageHandler'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; const PHASE_START = 0; const PHASE_SHOW_SAS = 1; @@ -26,6 +27,7 @@ const PHASE_WAIT_FOR_PARTNER_TO_CONFIRM = 2; const PHASE_VERIFIED = 3; const PHASE_CANCELLED = 4; +@replaceableComponent("views.dialogs.IncomingSasDialog") export default class IncomingSasDialog extends React.Component { static propTypes = { verifier: PropTypes.object.isRequired, diff --git a/src/components/views/dialogs/IntegrationsDisabledDialog.js b/src/components/views/dialogs/IntegrationsDisabledDialog.js index 7c996fbeab..0e9878f4bc 100644 --- a/src/components/views/dialogs/IntegrationsDisabledDialog.js +++ b/src/components/views/dialogs/IntegrationsDisabledDialog.js @@ -20,7 +20,9 @@ import {_t} from "../../../languageHandler"; import * as sdk from "../../../index"; import dis from '../../../dispatcher/dispatcher'; import {Action} from "../../../dispatcher/actions"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.dialogs.IntegrationsDisabledDialog") export default class IntegrationsDisabledDialog extends React.Component { static propTypes = { onFinished: PropTypes.func.isRequired, diff --git a/src/components/views/dialogs/IntegrationsImpossibleDialog.js b/src/components/views/dialogs/IntegrationsImpossibleDialog.js index 68bedc711d..9bc9d02ba6 100644 --- a/src/components/views/dialogs/IntegrationsImpossibleDialog.js +++ b/src/components/views/dialogs/IntegrationsImpossibleDialog.js @@ -19,7 +19,9 @@ import PropTypes from 'prop-types'; import {_t} from "../../../languageHandler"; import SdkConfig from "../../../SdkConfig"; import * as sdk from "../../../index"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.dialogs.IntegrationsImpossibleDialog") export default class IntegrationsImpossibleDialog extends React.Component { static propTypes = { onFinished: PropTypes.func.isRequired, diff --git a/src/components/views/dialogs/InteractiveAuthDialog.js b/src/components/views/dialogs/InteractiveAuthDialog.js index 22291225ad..28a9bf673a 100644 --- a/src/components/views/dialogs/InteractiveAuthDialog.js +++ b/src/components/views/dialogs/InteractiveAuthDialog.js @@ -25,7 +25,9 @@ import { _t } from '../../../languageHandler'; import AccessibleButton from '../elements/AccessibleButton'; import {ERROR_USER_CANCELLED} from "../../structures/InteractiveAuth"; import {SSOAuthEntry} from "../auth/InteractiveAuthEntryComponents"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.dialogs.InteractiveAuthDialog") export default class InteractiveAuthDialog extends React.Component { static propTypes = { // matrix client to use for UI auth requests diff --git a/src/components/views/dialogs/InviteDialog.tsx b/src/components/views/dialogs/InviteDialog.tsx index 9bc5b6476f..db9077291e 100644 --- a/src/components/views/dialogs/InviteDialog.tsx +++ b/src/components/views/dialogs/InviteDialog.tsx @@ -42,6 +42,7 @@ import {UIFeature} from "../../../settings/UIFeature"; import CountlyAnalytics from "../../../CountlyAnalytics"; import {Room} from "matrix-js-sdk/src/models/room"; import { MatrixCall } from 'matrix-js-sdk/src/webrtc/call'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; // we have a number of types defined from the Matrix spec which can't reasonably be altered here. /* eslint-disable camelcase */ @@ -337,6 +338,7 @@ interface IInviteDialogState { errorText: string, } +@replaceableComponent("views.dialogs.InviteDialog") export default class InviteDialog extends React.PureComponent { static defaultProps = { kind: KIND_DM, diff --git a/src/components/views/dialogs/LogoutDialog.js b/src/components/views/dialogs/LogoutDialog.js index af36dba2b6..7bced46d43 100644 --- a/src/components/views/dialogs/LogoutDialog.js +++ b/src/components/views/dialogs/LogoutDialog.js @@ -22,7 +22,9 @@ import dis from '../../../dispatcher/dispatcher'; import { _t } from '../../../languageHandler'; import { MatrixClientPeg } from '../../../MatrixClientPeg'; import RestoreKeyBackupDialog from './security/RestoreKeyBackupDialog'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.dialogs.LogoutDialog") export default class LogoutDialog extends React.Component { defaultProps = { onFinished: function() {}, diff --git a/src/components/views/dialogs/ManualDeviceKeyVerificationDialog.js b/src/components/views/dialogs/ManualDeviceKeyVerificationDialog.js index 4b9d7239e6..3151edd796 100644 --- a/src/components/views/dialogs/ManualDeviceKeyVerificationDialog.js +++ b/src/components/views/dialogs/ManualDeviceKeyVerificationDialog.js @@ -24,7 +24,9 @@ import {MatrixClientPeg} from '../../../MatrixClientPeg'; import * as sdk from '../../../index'; import * as FormattingUtils from '../../../utils/FormattingUtils'; import { _t } from '../../../languageHandler'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.dialogs.ManualDeviceKeyVerificationDialog") export default class ManualDeviceKeyVerificationDialog extends React.Component { static propTypes = { userId: PropTypes.string.isRequired, diff --git a/src/components/views/dialogs/MessageEditHistoryDialog.js b/src/components/views/dialogs/MessageEditHistoryDialog.js index 2bdf2be35c..7585561c0c 100644 --- a/src/components/views/dialogs/MessageEditHistoryDialog.js +++ b/src/components/views/dialogs/MessageEditHistoryDialog.js @@ -21,7 +21,9 @@ import { _t } from '../../../languageHandler'; import * as sdk from "../../../index"; import {wantsDateSeparator} from '../../../DateUtils'; import SettingsStore from '../../../settings/SettingsStore'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.dialogs.MessageEditHistoryDialog") export default class MessageEditHistoryDialog extends React.PureComponent { static propTypes = { mxEvent: PropTypes.object.isRequired, diff --git a/src/components/views/dialogs/ModalWidgetDialog.tsx b/src/components/views/dialogs/ModalWidgetDialog.tsx index 92fb406965..59eaab7b81 100644 --- a/src/components/views/dialogs/ModalWidgetDialog.tsx +++ b/src/components/views/dialogs/ModalWidgetDialog.tsx @@ -38,6 +38,7 @@ import {MatrixClientPeg} from "../../../MatrixClientPeg"; import {OwnProfileStore} from "../../../stores/OwnProfileStore"; import { arrayFastClone } from "../../../utils/arrays"; import { ElementWidget } from "../../../stores/widgets/StopGapWidget"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps { widgetDefinition: IModalWidgetOpenRequestData; @@ -53,6 +54,7 @@ interface IState { const MAX_BUTTONS = 3; +@replaceableComponent("views.dialogs.ModalWidgetDialog") export default class ModalWidgetDialog extends React.PureComponent { private readonly widget: Widget; private readonly possibleButtons: ModalButtonID[]; diff --git a/src/components/views/dialogs/ReportEventDialog.js b/src/components/views/dialogs/ReportEventDialog.js index f5509dec4d..67ed0f8f53 100644 --- a/src/components/views/dialogs/ReportEventDialog.js +++ b/src/components/views/dialogs/ReportEventDialog.js @@ -22,10 +22,12 @@ import {MatrixEvent} from "matrix-js-sdk"; import {MatrixClientPeg} from "../../../MatrixClientPeg"; import SdkConfig from '../../../SdkConfig'; import Markdown from '../../../Markdown'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; /* * A dialog for reporting an event. */ +@replaceableComponent("views.dialogs.ReportEventDialog") export default class ReportEventDialog extends PureComponent { static propTypes = { mxEvent: PropTypes.instanceOf(MatrixEvent).isRequired, diff --git a/src/components/views/dialogs/RoomSettingsDialog.js b/src/components/views/dialogs/RoomSettingsDialog.js index 9d9313f08f..045d11404a 100644 --- a/src/components/views/dialogs/RoomSettingsDialog.js +++ b/src/components/views/dialogs/RoomSettingsDialog.js @@ -30,6 +30,7 @@ import {MatrixClientPeg} from "../../../MatrixClientPeg"; import dis from "../../../dispatcher/dispatcher"; import SettingsStore from "../../../settings/SettingsStore"; import {UIFeature} from "../../../settings/UIFeature"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; export const ROOM_GENERAL_TAB = "ROOM_GENERAL_TAB"; export const ROOM_SECURITY_TAB = "ROOM_SECURITY_TAB"; @@ -38,6 +39,7 @@ export const ROOM_NOTIFICATIONS_TAB = "ROOM_NOTIFICATIONS_TAB"; export const ROOM_BRIDGES_TAB = "ROOM_BRIDGES_TAB"; export const ROOM_ADVANCED_TAB = "ROOM_ADVANCED_TAB"; +@replaceableComponent("views.dialogs.RoomSettingsDialog") export default class RoomSettingsDialog extends React.Component { static propTypes = { roomId: PropTypes.string.isRequired, diff --git a/src/components/views/dialogs/RoomUpgradeDialog.js b/src/components/views/dialogs/RoomUpgradeDialog.js index 85e97444ed..8f9ed42ada 100644 --- a/src/components/views/dialogs/RoomUpgradeDialog.js +++ b/src/components/views/dialogs/RoomUpgradeDialog.js @@ -20,7 +20,9 @@ import * as sdk from '../../../index'; import {MatrixClientPeg} from '../../../MatrixClientPeg'; import Modal from '../../../Modal'; import { _t } from '../../../languageHandler'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.dialogs.RoomUpgradeDialog") export default class RoomUpgradeDialog extends React.Component { static propTypes = { room: PropTypes.object.isRequired, diff --git a/src/components/views/dialogs/RoomUpgradeWarningDialog.js b/src/components/views/dialogs/RoomUpgradeWarningDialog.js index c83528c5ba..452ac56dff 100644 --- a/src/components/views/dialogs/RoomUpgradeWarningDialog.js +++ b/src/components/views/dialogs/RoomUpgradeWarningDialog.js @@ -22,7 +22,9 @@ import * as sdk from "../../../index"; import LabelledToggleSwitch from "../elements/LabelledToggleSwitch"; import {MatrixClientPeg} from "../../../MatrixClientPeg"; import Modal from "../../../Modal"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.dialogs.RoomUpgradeWarningDialog") export default class RoomUpgradeWarningDialog extends React.Component { static propTypes = { onFinished: PropTypes.func.isRequired, diff --git a/src/components/views/dialogs/ServerOfflineDialog.tsx b/src/components/views/dialogs/ServerOfflineDialog.tsx index 81f628343b..52ff056907 100644 --- a/src/components/views/dialogs/ServerOfflineDialog.tsx +++ b/src/components/views/dialogs/ServerOfflineDialog.tsx @@ -28,10 +28,12 @@ import AccessibleButton from "../elements/AccessibleButton"; import { UPDATE_EVENT } from "../../../stores/AsyncStore"; import { MatrixClientPeg } from "../../../MatrixClientPeg"; import { IDialogProps } from "./IDialogProps"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps extends IDialogProps { } +@replaceableComponent("views.dialogs.ServerOfflineDialog") export default class ServerOfflineDialog extends React.PureComponent { public componentDidMount() { EchoStore.instance.on(UPDATE_EVENT, this.onEchosUpdated); diff --git a/src/components/views/dialogs/ServerPickerDialog.tsx b/src/components/views/dialogs/ServerPickerDialog.tsx index 7ca115760e..4abc0a88b1 100644 --- a/src/components/views/dialogs/ServerPickerDialog.tsx +++ b/src/components/views/dialogs/ServerPickerDialog.tsx @@ -26,6 +26,7 @@ import Field from "../elements/Field"; import StyledRadioButton from "../elements/StyledRadioButton"; import TextWithTooltip from "../elements/TextWithTooltip"; import withValidation, {IFieldState} from "../elements/Validation"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps { title?: string; @@ -38,6 +39,7 @@ interface IState { otherHomeserver: string; } +@replaceableComponent("views.dialogs.ServerPickerDialog") export default class ServerPickerDialog extends React.PureComponent { private readonly defaultServer: ValidatedServerConfig; private readonly fieldRef = createRef(); diff --git a/src/components/views/dialogs/SessionRestoreErrorDialog.js b/src/components/views/dialogs/SessionRestoreErrorDialog.js index bae6b19fbe..50d7fbea09 100644 --- a/src/components/views/dialogs/SessionRestoreErrorDialog.js +++ b/src/components/views/dialogs/SessionRestoreErrorDialog.js @@ -22,8 +22,9 @@ import * as sdk from '../../../index'; import SdkConfig from '../../../SdkConfig'; import Modal from '../../../Modal'; import { _t } from '../../../languageHandler'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; - +@replaceableComponent("views.dialogs.SessionRestoreErrorDialog") export default class SessionRestoreErrorDialog extends React.Component { static propTypes = { error: PropTypes.string.isRequired, diff --git a/src/components/views/dialogs/SetEmailDialog.js b/src/components/views/dialogs/SetEmailDialog.js index 6514d94dc9..0f8f410a6a 100644 --- a/src/components/views/dialogs/SetEmailDialog.js +++ b/src/components/views/dialogs/SetEmailDialog.js @@ -22,6 +22,7 @@ import * as Email from '../../../email'; import AddThreepid from '../../../AddThreepid'; import { _t } from '../../../languageHandler'; import Modal from '../../../Modal'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; /* @@ -29,6 +30,7 @@ import Modal from '../../../Modal'; * * On success, `onFinished(true)` is called. */ +@replaceableComponent("views.dialogs.SetEmailDialog") export default class SetEmailDialog extends React.Component { static propTypes = { onFinished: PropTypes.func.isRequired, diff --git a/src/components/views/dialogs/ShareDialog.tsx b/src/components/views/dialogs/ShareDialog.tsx index 5264031cc6..df1206a4f0 100644 --- a/src/components/views/dialogs/ShareDialog.tsx +++ b/src/components/views/dialogs/ShareDialog.tsx @@ -34,6 +34,7 @@ import AccessibleTooltipButton from '../elements/AccessibleTooltipButton'; import { IDialogProps } from "./IDialogProps"; import SettingsStore from "../../../settings/SettingsStore"; import {UIFeature} from "../../../settings/UIFeature"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; const socials = [ { @@ -73,6 +74,7 @@ interface IState { permalinkCreator: RoomPermalinkCreator; } +@replaceableComponent("views.dialogs.ShareDialog") export default class ShareDialog extends React.PureComponent { static propTypes = { onFinished: PropTypes.func.isRequired, diff --git a/src/components/views/dialogs/StorageEvictedDialog.js b/src/components/views/dialogs/StorageEvictedDialog.js index a22f302807..15c5347644 100644 --- a/src/components/views/dialogs/StorageEvictedDialog.js +++ b/src/components/views/dialogs/StorageEvictedDialog.js @@ -20,7 +20,9 @@ import * as sdk from '../../../index'; import SdkConfig from '../../../SdkConfig'; import Modal from '../../../Modal'; import { _t } from '../../../languageHandler'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.dialogs.StorageEvictedDialog") export default class StorageEvictedDialog extends React.Component { static propTypes = { onFinished: PropTypes.func.isRequired, diff --git a/src/components/views/dialogs/TabbedIntegrationManagerDialog.js b/src/components/views/dialogs/TabbedIntegrationManagerDialog.js index 9f5c9f6a11..07e29adcff 100644 --- a/src/components/views/dialogs/TabbedIntegrationManagerDialog.js +++ b/src/components/views/dialogs/TabbedIntegrationManagerDialog.js @@ -22,7 +22,9 @@ import * as sdk from '../../../index'; import {dialogTermsInteractionCallback, TermsNotSignedError} from "../../../Terms"; import classNames from 'classnames'; import * as ScalarMessaging from "../../../ScalarMessaging"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.dialogs.TabbedIntegrationManagerDialog") export default class TabbedIntegrationManagerDialog extends React.Component { static propTypes = { /** diff --git a/src/components/views/dialogs/TermsDialog.js b/src/components/views/dialogs/TermsDialog.js index 402605c545..72e6c3f3a0 100644 --- a/src/components/views/dialogs/TermsDialog.js +++ b/src/components/views/dialogs/TermsDialog.js @@ -21,6 +21,7 @@ import * as sdk from '../../../index'; import { _t, pickBestLanguage } from '../../../languageHandler'; import Matrix from 'matrix-js-sdk'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; class TermsCheckbox extends React.PureComponent { static propTypes = { @@ -41,6 +42,7 @@ class TermsCheckbox extends React.PureComponent { } } +@replaceableComponent("views.dialogs.TermsDialog") export default class TermsDialog extends React.PureComponent { static propTypes = { /** diff --git a/src/components/views/dialogs/TextInputDialog.js b/src/components/views/dialogs/TextInputDialog.js index 69cc4390be..97abd209c0 100644 --- a/src/components/views/dialogs/TextInputDialog.js +++ b/src/components/views/dialogs/TextInputDialog.js @@ -19,7 +19,9 @@ import PropTypes from 'prop-types'; import * as sdk from '../../../index'; import Field from "../elements/Field"; import { _t, _td } from '../../../languageHandler'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.dialogs.TextInputDialog") export default class TextInputDialog extends React.Component { static propTypes = { title: PropTypes.string, diff --git a/src/components/views/dialogs/UploadConfirmDialog.js b/src/components/views/dialogs/UploadConfirmDialog.js index e3521eb282..2ff16b9440 100644 --- a/src/components/views/dialogs/UploadConfirmDialog.js +++ b/src/components/views/dialogs/UploadConfirmDialog.js @@ -20,7 +20,9 @@ import PropTypes from 'prop-types'; import * as sdk from '../../../index'; import { _t } from '../../../languageHandler'; import filesize from "filesize"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.dialogs.UploadConfirmDialog") export default class UploadConfirmDialog extends React.Component { static propTypes = { file: PropTypes.object.isRequired, diff --git a/src/components/views/dialogs/UploadFailureDialog.js b/src/components/views/dialogs/UploadFailureDialog.js index 4be1656f66..d220d6c684 100644 --- a/src/components/views/dialogs/UploadFailureDialog.js +++ b/src/components/views/dialogs/UploadFailureDialog.js @@ -21,12 +21,14 @@ import PropTypes from 'prop-types'; import * as sdk from '../../../index'; import { _t } from '../../../languageHandler'; import ContentMessages from '../../../ContentMessages'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; /* * Tells the user about files we know cannot be uploaded before we even try uploading * them. This is named fairly generically but the only thing we check right now is * the size of the file. */ +@replaceableComponent("views.dialogs.UploadFailureDialog") export default class UploadFailureDialog extends React.Component { static propTypes = { badFiles: PropTypes.arrayOf(PropTypes.object).isRequired, diff --git a/src/components/views/dialogs/UserSettingsDialog.js b/src/components/views/dialogs/UserSettingsDialog.js index 7164540aea..32abef874b 100644 --- a/src/components/views/dialogs/UserSettingsDialog.js +++ b/src/components/views/dialogs/UserSettingsDialog.js @@ -33,6 +33,7 @@ import * as sdk from "../../../index"; import SdkConfig from "../../../SdkConfig"; import MjolnirUserSettingsTab from "../settings/tabs/user/MjolnirUserSettingsTab"; import {UIFeature} from "../../../settings/UIFeature"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; export const USER_GENERAL_TAB = "USER_GENERAL_TAB"; export const USER_APPEARANCE_TAB = "USER_APPEARANCE_TAB"; @@ -45,6 +46,7 @@ export const USER_LABS_TAB = "USER_LABS_TAB"; export const USER_MJOLNIR_TAB = "USER_MJOLNIR_TAB"; export const USER_HELP_TAB = "USER_HELP_TAB"; +@replaceableComponent("views.dialogs.UserSettingsDialog") export default class UserSettingsDialog extends React.Component { static propTypes = { onFinished: PropTypes.func.isRequired, diff --git a/src/components/views/dialogs/VerificationRequestDialog.js b/src/components/views/dialogs/VerificationRequestDialog.js index 3a6e9a2d10..574beebbc6 100644 --- a/src/components/views/dialogs/VerificationRequestDialog.js +++ b/src/components/views/dialogs/VerificationRequestDialog.js @@ -19,7 +19,9 @@ import PropTypes from 'prop-types'; import {MatrixClientPeg} from '../../../MatrixClientPeg'; import * as sdk from '../../../index'; import { _t } from '../../../languageHandler'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.dialogs.VerificationRequestDialog") export default class VerificationRequestDialog extends React.Component { static propTypes = { verificationRequest: PropTypes.object, diff --git a/src/components/views/dialogs/WidgetCapabilitiesPromptDialog.tsx b/src/components/views/dialogs/WidgetCapabilitiesPromptDialog.tsx index 535e0b7b8e..70fe7fe5e3 100644 --- a/src/components/views/dialogs/WidgetCapabilitiesPromptDialog.tsx +++ b/src/components/views/dialogs/WidgetCapabilitiesPromptDialog.tsx @@ -29,6 +29,7 @@ import StyledCheckbox from "../elements/StyledCheckbox"; import DialogButtons from "../elements/DialogButtons"; import LabelledToggleSwitch from "../elements/LabelledToggleSwitch"; import { CapabilityText } from "../../../widgets/CapabilityText"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; export function getRememberedCapabilitiesForWidget(widget: Widget): Capability[] { return JSON.parse(localStorage.getItem(`widget_${widget.id}_approved_caps`) || "[]"); @@ -54,6 +55,7 @@ interface IState { rememberSelection: boolean; } +@replaceableComponent("views.dialogs.WidgetCapabilitiesPromptDialog") export default class WidgetCapabilitiesPromptDialog extends React.PureComponent { private eventPermissionsMap = new Map(); diff --git a/src/components/views/dialogs/WidgetOpenIDPermissionsDialog.js b/src/components/views/dialogs/WidgetOpenIDPermissionsDialog.js index c01d3d39b8..f45adf9738 100644 --- a/src/components/views/dialogs/WidgetOpenIDPermissionsDialog.js +++ b/src/components/views/dialogs/WidgetOpenIDPermissionsDialog.js @@ -21,7 +21,9 @@ import * as sdk from "../../../index"; import LabelledToggleSwitch from "../elements/LabelledToggleSwitch"; import {Widget} from "matrix-widget-api"; import {OIDCState, WidgetPermissionStore} from "../../../stores/widgets/WidgetPermissionStore"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.dialogs.WidgetOpenIDPermissionsDialog") export default class WidgetOpenIDPermissionsDialog extends React.Component { static propTypes = { onFinished: PropTypes.func.isRequired, diff --git a/src/components/views/elements/AccessibleTooltipButton.tsx b/src/components/views/elements/AccessibleTooltipButton.tsx index b7c7b78e63..3bb264fb3e 100644 --- a/src/components/views/elements/AccessibleTooltipButton.tsx +++ b/src/components/views/elements/AccessibleTooltipButton.tsx @@ -20,6 +20,7 @@ import classNames from 'classnames'; import AccessibleButton from "./AccessibleButton"; import Tooltip from './Tooltip'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface ITooltipProps extends React.ComponentProps { title: string; @@ -33,6 +34,7 @@ interface IState { hover: boolean; } +@replaceableComponent("views.elements.AccessibleTooltipButton") export default class AccessibleTooltipButton extends React.PureComponent { constructor(props: ITooltipProps) { super(props); diff --git a/src/components/views/elements/ActionButton.js b/src/components/views/elements/ActionButton.js index bec016bce0..1714891cb5 100644 --- a/src/components/views/elements/ActionButton.js +++ b/src/components/views/elements/ActionButton.js @@ -20,7 +20,9 @@ import AccessibleButton from './AccessibleButton'; import dis from '../../../dispatcher/dispatcher'; import * as sdk from '../../../index'; import Analytics from '../../../Analytics'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.elements.ActionButton") export default class ActionButton extends React.Component { static propTypes = { size: PropTypes.string, diff --git a/src/components/views/elements/AddressSelector.js b/src/components/views/elements/AddressSelector.js index 2a71622bb8..33b2906870 100644 --- a/src/components/views/elements/AddressSelector.js +++ b/src/components/views/elements/AddressSelector.js @@ -20,7 +20,9 @@ import PropTypes from 'prop-types'; import * as sdk from '../../../index'; import classNames from 'classnames'; import { UserAddressType } from '../../../UserAddress'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.elements.AddressSelector") export default class AddressSelector extends React.Component { static propTypes = { onSelected: PropTypes.func.isRequired, diff --git a/src/components/views/elements/AddressTile.js b/src/components/views/elements/AddressTile.js index dc6c6b2914..4a216dbae4 100644 --- a/src/components/views/elements/AddressTile.js +++ b/src/components/views/elements/AddressTile.js @@ -22,8 +22,9 @@ import * as sdk from "../../../index"; import {MatrixClientPeg} from "../../../MatrixClientPeg"; import { _t } from '../../../languageHandler'; import { UserAddressType } from '../../../UserAddress.js'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; - +@replaceableComponent("views.elements.AddressTile") export default class AddressTile extends React.Component { static propTypes = { address: UserAddressType.isRequired, diff --git a/src/components/views/elements/AppPermission.js b/src/components/views/elements/AppPermission.js index ec8bffc32f..65e40ef19a 100644 --- a/src/components/views/elements/AppPermission.js +++ b/src/components/views/elements/AppPermission.js @@ -24,7 +24,9 @@ import { _t } from '../../../languageHandler'; import SdkConfig from '../../../SdkConfig'; import WidgetUtils from "../../../utils/WidgetUtils"; import {MatrixClientPeg} from "../../../MatrixClientPeg"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.elements.AppPermission") export default class AppPermission extends React.Component { static propTypes = { url: PropTypes.string.isRequired, diff --git a/src/components/views/elements/AppTile.js b/src/components/views/elements/AppTile.js index 2a72621ccc..e206fda797 100644 --- a/src/components/views/elements/AppTile.js +++ b/src/components/views/elements/AppTile.js @@ -38,7 +38,9 @@ import {ElementWidgetActions} from "../../../stores/widgets/ElementWidgetActions import {MatrixCapabilities} from "matrix-widget-api"; import RoomWidgetContextMenu from "../context_menus/WidgetContextMenu"; import WidgetAvatar from "../avatars/WidgetAvatar"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.elements.AppTile") export default class AppTile extends React.Component { constructor(props) { super(props); diff --git a/src/components/views/elements/DesktopCapturerSourcePicker.tsx b/src/components/views/elements/DesktopCapturerSourcePicker.tsx index 6ae465c362..2d066a7ed7 100644 --- a/src/components/views/elements/DesktopCapturerSourcePicker.tsx +++ b/src/components/views/elements/DesktopCapturerSourcePicker.tsx @@ -19,6 +19,7 @@ import { _t } from '../../../languageHandler'; import BaseDialog from "..//dialogs/BaseDialog" import AccessibleButton from './AccessibleButton'; import {getDesktopCapturerSources} from "matrix-js-sdk/src/webrtc/call"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; export interface DesktopCapturerSource { id: string; @@ -69,6 +70,7 @@ export interface DesktopCapturerSourcePickerIProps { onFinished(source: DesktopCapturerSource): void; } +@replaceableComponent("views.elements.DesktopCapturerSourcePicker") export default class DesktopCapturerSourcePicker extends React.Component< DesktopCapturerSourcePickerIProps, DesktopCapturerSourcePickerIState diff --git a/src/components/views/elements/DialogButtons.js b/src/components/views/elements/DialogButtons.js index 3417485eb8..dcb1cee077 100644 --- a/src/components/views/elements/DialogButtons.js +++ b/src/components/views/elements/DialogButtons.js @@ -19,10 +19,12 @@ limitations under the License. import React from "react"; import PropTypes from "prop-types"; import { _t } from '../../../languageHandler'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; /** * Basic container for buttons in modal dialogs. */ +@replaceableComponent("views.elements.DialogButtons") export default class DialogButtons extends React.Component { static propTypes = { // The primary button which is styled differently and has default focus. diff --git a/src/components/views/elements/DirectorySearchBox.js b/src/components/views/elements/DirectorySearchBox.js index 644b69417b..6447bb3cd8 100644 --- a/src/components/views/elements/DirectorySearchBox.js +++ b/src/components/views/elements/DirectorySearchBox.js @@ -18,7 +18,9 @@ import React from 'react'; import PropTypes from 'prop-types'; import * as sdk from '../../../index'; import { _t } from '../../../languageHandler'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.elements.DirectorySearchBox") export default class DirectorySearchBox extends React.Component { constructor(props) { super(props); diff --git a/src/components/views/elements/Draggable.tsx b/src/components/views/elements/Draggable.tsx index a6eb8323f3..6032721a48 100644 --- a/src/components/views/elements/Draggable.tsx +++ b/src/components/views/elements/Draggable.tsx @@ -15,6 +15,7 @@ limitations under the License. */ import React from 'react'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps { className: string; @@ -33,6 +34,7 @@ export interface ILocationState { currentY: number; } +@replaceableComponent("views.elements.Draggable") export default class Draggable extends React.Component { constructor(props: IProps) { super(props); diff --git a/src/components/views/elements/Dropdown.js b/src/components/views/elements/Dropdown.js index 6b3efb5ee1..981c0becc0 100644 --- a/src/components/views/elements/Dropdown.js +++ b/src/components/views/elements/Dropdown.js @@ -22,6 +22,7 @@ import classnames from 'classnames'; import AccessibleButton from './AccessibleButton'; import { _t } from '../../../languageHandler'; import {Key} from "../../../Keyboard"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; class MenuOption extends React.Component { constructor(props) { @@ -83,6 +84,7 @@ MenuOption.propTypes = { * * TODO: Port NetworkDropdown to use this. */ +@replaceableComponent("views.elements.Dropdown") export default class Dropdown extends React.Component { constructor(props) { super(props); diff --git a/src/components/views/elements/EditableItemList.js b/src/components/views/elements/EditableItemList.js index 5a07a400d7..ff62f169fa 100644 --- a/src/components/views/elements/EditableItemList.js +++ b/src/components/views/elements/EditableItemList.js @@ -19,6 +19,7 @@ import PropTypes from 'prop-types'; import {_t} from '../../../languageHandler'; import Field from "./Field"; import AccessibleButton from "./AccessibleButton"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; export class EditableItem extends React.Component { static propTypes = { @@ -85,6 +86,7 @@ export class EditableItem extends React.Component { } } +@replaceableComponent("views.elements.EditableItemList") export default class EditableItemList extends React.Component { static propTypes = { id: PropTypes.string.isRequired, diff --git a/src/components/views/elements/EditableText.js b/src/components/views/elements/EditableText.js index 49eb331aef..638fd02553 100644 --- a/src/components/views/elements/EditableText.js +++ b/src/components/views/elements/EditableText.js @@ -18,7 +18,9 @@ limitations under the License. import React, {createRef} from 'react'; import PropTypes from 'prop-types'; import {Key} from "../../../Keyboard"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.elements.EditableText") export default class EditableText extends React.Component { static propTypes = { onValueChanged: PropTypes.func, diff --git a/src/components/views/elements/EditableTextContainer.js b/src/components/views/elements/EditableTextContainer.js index bbc5560557..e925220089 100644 --- a/src/components/views/elements/EditableTextContainer.js +++ b/src/components/views/elements/EditableTextContainer.js @@ -17,6 +17,7 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; import * as sdk from '../../../index'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; /** * A component which wraps an EditableText, with a spinner while updates take @@ -29,6 +30,7 @@ import * as sdk from '../../../index'; * similarly asynchronous way. If this is not provided, the initial value is * taken from the 'initialValue' property. */ +@replaceableComponent("views.elements.EditableTextContainer") export default class EditableTextContainer extends React.Component { constructor(props) { super(props); diff --git a/src/components/views/elements/ErrorBoundary.js b/src/components/views/elements/ErrorBoundary.js index 9fe6861250..9037287f49 100644 --- a/src/components/views/elements/ErrorBoundary.js +++ b/src/components/views/elements/ErrorBoundary.js @@ -21,11 +21,13 @@ import {MatrixClientPeg} from '../../../MatrixClientPeg'; import PlatformPeg from '../../../PlatformPeg'; import Modal from '../../../Modal'; import SdkConfig from "../../../SdkConfig"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; /** * This error boundary component can be used to wrap large content areas and * catch exceptions during rendering in the component tree below them. */ +@replaceableComponent("views.elements.ErrorBoundary") export default class ErrorBoundary extends React.PureComponent { constructor(props) { super(props); diff --git a/src/components/views/elements/EventTilePreview.tsx b/src/components/views/elements/EventTilePreview.tsx index 49c97831bc..c539f2be1c 100644 --- a/src/components/views/elements/EventTilePreview.tsx +++ b/src/components/views/elements/EventTilePreview.tsx @@ -24,6 +24,7 @@ import EventTile from '../rooms/EventTile'; import SettingsStore from "../../../settings/SettingsStore"; import {Layout} from "../../../settings/Layout"; import {UIFeature} from "../../../settings/UIFeature"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps { /** @@ -52,6 +53,7 @@ interface IState { const AVATAR_SIZE = 32; +@replaceableComponent("views.elements.EventTilePreview") export default class EventTilePreview extends React.Component { constructor(props: IProps) { super(props); diff --git a/src/components/views/elements/Flair.js b/src/components/views/elements/Flair.js index 0f06904b68..04eba5bc42 100644 --- a/src/components/views/elements/Flair.js +++ b/src/components/views/elements/Flair.js @@ -21,6 +21,7 @@ import PropTypes from 'prop-types'; import FlairStore from '../../../stores/FlairStore'; import dis from '../../../dispatcher/dispatcher'; import MatrixClientContext from "../../../contexts/MatrixClientContext"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; class FlairAvatar extends React.Component { @@ -64,6 +65,7 @@ FlairAvatar.propTypes = { FlairAvatar.contextType = MatrixClientContext; +@replaceableComponent("views.elements.Flair") export default class Flair extends React.Component { constructor() { super(); diff --git a/src/components/views/elements/IRCTimelineProfileResizer.tsx b/src/components/views/elements/IRCTimelineProfileResizer.tsx index ecd63816de..cd1ccf2fc4 100644 --- a/src/components/views/elements/IRCTimelineProfileResizer.tsx +++ b/src/components/views/elements/IRCTimelineProfileResizer.tsx @@ -18,6 +18,7 @@ import React from 'react'; import SettingsStore from "../../../settings/SettingsStore"; import Draggable, {ILocationState} from './Draggable'; import { SettingLevel } from "../../../settings/SettingLevel"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps { // Current room @@ -31,6 +32,7 @@ interface IState { IRCLayoutRoot: HTMLElement; } +@replaceableComponent("views.elements.IRCTimelineProfileResizer") export default class IRCTimelineProfileResizer extends React.Component { constructor(props: IProps) { super(props); diff --git a/src/components/views/elements/ImageView.js b/src/components/views/elements/ImageView.js index e39075cedc..96b6de832d 100644 --- a/src/components/views/elements/ImageView.js +++ b/src/components/views/elements/ImageView.js @@ -26,7 +26,9 @@ import Modal from "../../../Modal"; import * as sdk from "../../../index"; import {Key} from "../../../Keyboard"; import FocusLock from "react-focus-lock"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.elements.ImageView") export default class ImageView extends React.Component { static propTypes = { src: PropTypes.string.isRequired, // the source of the image being displayed diff --git a/src/components/views/elements/InfoTooltip.tsx b/src/components/views/elements/InfoTooltip.tsx index dd21c95b74..8f7f1ea53f 100644 --- a/src/components/views/elements/InfoTooltip.tsx +++ b/src/components/views/elements/InfoTooltip.tsx @@ -20,6 +20,7 @@ import classNames from 'classnames'; import Tooltip from './Tooltip'; import { _t } from "../../../languageHandler"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface ITooltipProps { tooltip?: React.ReactNode; @@ -30,6 +31,7 @@ interface IState { hover: boolean; } +@replaceableComponent("views.elements.InfoTooltip") export default class InfoTooltip extends React.PureComponent { constructor(props: ITooltipProps) { super(props); diff --git a/src/components/views/elements/InlineSpinner.js b/src/components/views/elements/InlineSpinner.js index 73316157f4..3654a1f34c 100644 --- a/src/components/views/elements/InlineSpinner.js +++ b/src/components/views/elements/InlineSpinner.js @@ -17,7 +17,9 @@ limitations under the License. import React from "react"; import {_t} from "../../../languageHandler"; import SettingsStore from "../../../settings/SettingsStore"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.elements.InlineSpinner") export default class InlineSpinner extends React.Component { render() { const w = this.props.w || 16; diff --git a/src/components/views/elements/LabelledToggleSwitch.js b/src/components/views/elements/LabelledToggleSwitch.js index 78beb2aa91..e6378f0e6a 100644 --- a/src/components/views/elements/LabelledToggleSwitch.js +++ b/src/components/views/elements/LabelledToggleSwitch.js @@ -17,7 +17,9 @@ limitations under the License. import React from 'react'; import PropTypes from "prop-types"; import ToggleSwitch from "./ToggleSwitch"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.elements.LabelledToggleSwitch") export default class LabelledToggleSwitch extends React.Component { static propTypes = { // The value for the toggle switch diff --git a/src/components/views/elements/LanguageDropdown.js b/src/components/views/elements/LanguageDropdown.js index 03ec456af5..2e961be700 100644 --- a/src/components/views/elements/LanguageDropdown.js +++ b/src/components/views/elements/LanguageDropdown.js @@ -22,6 +22,7 @@ import * as sdk from '../../../index'; import * as languageHandler from '../../../languageHandler'; import SettingsStore from "../../../settings/SettingsStore"; import { _t } from "../../../languageHandler"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; function languageMatchesSearchQuery(query, language) { if (language.label.toUpperCase().includes(query.toUpperCase())) return true; @@ -29,6 +30,7 @@ function languageMatchesSearchQuery(query, language) { return false; } +@replaceableComponent("views.elements.LanguageDropdown") export default class LanguageDropdown extends React.Component { constructor(props) { super(props); diff --git a/src/components/views/elements/LazyRenderList.js b/src/components/views/elements/LazyRenderList.js index 7572dced0b..f2c8148cd2 100644 --- a/src/components/views/elements/LazyRenderList.js +++ b/src/components/views/elements/LazyRenderList.js @@ -16,6 +16,7 @@ limitations under the License. import React from "react"; import PropTypes from 'prop-types'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; class ItemRange { constructor(topCount, renderCount, bottomCount) { @@ -55,6 +56,7 @@ class ItemRange { } } +@replaceableComponent("views.elements.LazyRenderList") export default class LazyRenderList extends React.Component { constructor(props) { super(props); diff --git a/src/components/views/elements/MemberEventListSummary.tsx b/src/components/views/elements/MemberEventListSummary.tsx index 073bedf207..0290ef6d83 100644 --- a/src/components/views/elements/MemberEventListSummary.tsx +++ b/src/components/views/elements/MemberEventListSummary.tsx @@ -24,6 +24,7 @@ import { _t } from '../../../languageHandler'; import { formatCommaSeparatedList } from '../../../utils/FormattingUtils'; import { isValid3pidInvite } from "../../../RoomInvite"; import EventListSummary from "./EventListSummary"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps { // An array of member events to summarise @@ -69,6 +70,7 @@ enum TransitionType { const SEP = ","; +@replaceableComponent("views.elements.MemberEventListSummary") export default class MemberEventListSummary extends React.Component { static defaultProps = { summaryLength: 1, diff --git a/src/components/views/elements/PersistedElement.js b/src/components/views/elements/PersistedElement.js index 3732f644b8..f504b3e97f 100644 --- a/src/components/views/elements/PersistedElement.js +++ b/src/components/views/elements/PersistedElement.js @@ -24,6 +24,7 @@ import dis from '../../../dispatcher/dispatcher'; import MatrixClientContext from "../../../contexts/MatrixClientContext"; import {MatrixClientPeg} from "../../../MatrixClientPeg"; import {isNullOrUndefined} from "matrix-js-sdk/src/utils"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; // Shamelessly ripped off Modal.js. There's probably a better way // of doing reusable widgets like dialog boxes & menus where we go and @@ -56,6 +57,7 @@ function getOrCreateContainer(containerId) { * children are made visible and are positioned into a div that is given the same * bounding rect as the parent of PE. */ +@replaceableComponent("views.elements.PersistedElement") export default class PersistedElement extends React.Component { static propTypes = { // Unique identifier for this PersistedElement instance diff --git a/src/components/views/elements/PersistentApp.js b/src/components/views/elements/PersistentApp.js index 7801076c66..5df373e4fe 100644 --- a/src/components/views/elements/PersistentApp.js +++ b/src/components/views/elements/PersistentApp.js @@ -21,7 +21,9 @@ import ActiveWidgetStore from '../../../stores/ActiveWidgetStore'; import WidgetUtils from '../../../utils/WidgetUtils'; import * as sdk from '../../../index'; import {MatrixClientPeg} from '../../../MatrixClientPeg'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.elements.PersistentApp") export default class PersistentApp extends React.Component { state = { roomId: RoomViewStore.getRoomId(), diff --git a/src/components/views/elements/Pill.js b/src/components/views/elements/Pill.js index c6806c289e..b0d4fc7fa2 100644 --- a/src/components/views/elements/Pill.js +++ b/src/components/views/elements/Pill.js @@ -27,7 +27,9 @@ import {getPrimaryPermalinkEntity, parseAppLocalLink} from "../../../utils/perma import MatrixClientContext from "../../../contexts/MatrixClientContext"; import {Action} from "../../../dispatcher/actions"; import Tooltip from './Tooltip'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.elements.Pill") class Pill extends React.Component { static roomNotifPos(text) { return text.indexOf("@room"); diff --git a/src/components/views/elements/PowerSelector.js b/src/components/views/elements/PowerSelector.js index 66922df0f8..622bed9890 100644 --- a/src/components/views/elements/PowerSelector.js +++ b/src/components/views/elements/PowerSelector.js @@ -20,7 +20,9 @@ import * as Roles from '../../../Roles'; import { _t } from '../../../languageHandler'; import Field from "./Field"; import {Key} from "../../../Keyboard"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.elements.PowerSelector") export default class PowerSelector extends React.Component { static propTypes = { value: PropTypes.number.isRequired, diff --git a/src/components/views/elements/ReplyThread.js b/src/components/views/elements/ReplyThread.js index 27d773b099..2e0cc50435 100644 --- a/src/components/views/elements/ReplyThread.js +++ b/src/components/views/elements/ReplyThread.js @@ -31,10 +31,12 @@ import {Action} from "../../../dispatcher/actions"; import sanitizeHtml from "sanitize-html"; import {UIFeature} from "../../../settings/UIFeature"; import {PERMITTED_URL_SCHEMES} from "../../../HtmlUtils"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; // This component does no cycle detection, simply because the only way to make such a cycle would be to // craft event_id's, using a homeserver that generates predictable event IDs; even then the impact would // be low as each event being loaded (after the first) is triggered by an explicit user action. +@replaceableComponent("views.elements.ReplyThread") export default class ReplyThread extends React.Component { static propTypes = { // the latest event in this chain of replies diff --git a/src/components/views/elements/RoomAliasField.js b/src/components/views/elements/RoomAliasField.js index 04bbe1c3de..1db154c2cd 100644 --- a/src/components/views/elements/RoomAliasField.js +++ b/src/components/views/elements/RoomAliasField.js @@ -19,8 +19,10 @@ import PropTypes from 'prop-types'; import * as sdk from '../../../index'; import withValidation from './Validation'; import {MatrixClientPeg} from '../../../MatrixClientPeg'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; // Controlled form component wrapping Field for inputting a room alias scoped to a given domain +@replaceableComponent("views.elements.RoomAliasField") export default class RoomAliasField extends React.PureComponent { static propTypes = { domain: PropTypes.string.isRequired, diff --git a/src/components/views/elements/SettingsFlag.tsx b/src/components/views/elements/SettingsFlag.tsx index 03e91fac62..4f885ab47d 100644 --- a/src/components/views/elements/SettingsFlag.tsx +++ b/src/components/views/elements/SettingsFlag.tsx @@ -21,6 +21,7 @@ import { _t } from '../../../languageHandler'; import ToggleSwitch from "./ToggleSwitch"; import StyledCheckbox from "./StyledCheckbox"; import { SettingLevel } from "../../../settings/SettingLevel"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps { // The setting must be a boolean @@ -39,6 +40,7 @@ interface IState { value: boolean; } +@replaceableComponent("views.elements.SettingsFlag") export default class SettingsFlag extends React.Component { constructor(props: IProps) { super(props); diff --git a/src/components/views/elements/Slider.tsx b/src/components/views/elements/Slider.tsx index b7c8e1b533..b513f90460 100644 --- a/src/components/views/elements/Slider.tsx +++ b/src/components/views/elements/Slider.tsx @@ -15,6 +15,7 @@ limitations under the License. */ import * as React from 'react'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps { // A callback for the selected value @@ -34,6 +35,7 @@ interface IProps { disabled: boolean; } +@replaceableComponent("views.elements.Slider") export default class Slider extends React.Component { // offset is a terrible inverse approximation. // if the values represents some function f(x) = y where x is the diff --git a/src/components/views/elements/SpellCheckLanguagesDropdown.tsx b/src/components/views/elements/SpellCheckLanguagesDropdown.tsx index c647f6e410..06e1efe415 100644 --- a/src/components/views/elements/SpellCheckLanguagesDropdown.tsx +++ b/src/components/views/elements/SpellCheckLanguagesDropdown.tsx @@ -21,6 +21,7 @@ import * as sdk from '../../../index'; import PlatformPeg from "../../../PlatformPeg"; import SettingsStore from "../../../settings/SettingsStore"; import { _t } from "../../../languageHandler"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; function languageMatchesSearchQuery(query, language) { if (language.label.toUpperCase().includes(query.toUpperCase())) return true; @@ -39,6 +40,7 @@ interface SpellCheckLanguagesDropdownIState { languages: any, } +@replaceableComponent("views.elements.SpellCheckLanguagesDropdown") export default class SpellCheckLanguagesDropdown extends React.Component { constructor(props) { diff --git a/src/components/views/elements/Spoiler.js b/src/components/views/elements/Spoiler.js index b75967b225..33b4382a2c 100644 --- a/src/components/views/elements/Spoiler.js +++ b/src/components/views/elements/Spoiler.js @@ -15,7 +15,9 @@ */ import React from 'react'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.elements.Spoiler") export default class Spoiler extends React.Component { constructor(props) { super(props); diff --git a/src/components/views/elements/StyledCheckbox.tsx b/src/components/views/elements/StyledCheckbox.tsx index f8d2665d07..2454d1336b 100644 --- a/src/components/views/elements/StyledCheckbox.tsx +++ b/src/components/views/elements/StyledCheckbox.tsx @@ -16,6 +16,7 @@ limitations under the License. import React from "react"; import { randomString } from "matrix-js-sdk/src/randomstring"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps extends React.InputHTMLAttributes { } @@ -23,6 +24,7 @@ interface IProps extends React.InputHTMLAttributes { interface IState { } +@replaceableComponent("views.elements.StyledCheckbox") export default class StyledCheckbox extends React.PureComponent { private id: string; diff --git a/src/components/views/elements/StyledRadioButton.tsx b/src/components/views/elements/StyledRadioButton.tsx index 2efd084861..835394e055 100644 --- a/src/components/views/elements/StyledRadioButton.tsx +++ b/src/components/views/elements/StyledRadioButton.tsx @@ -16,6 +16,7 @@ limitations under the License. import React from 'react'; import classnames from 'classnames'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps extends React.InputHTMLAttributes { outlined?: boolean; @@ -24,6 +25,7 @@ interface IProps extends React.InputHTMLAttributes { interface IState { } +@replaceableComponent("views.elements.StyledRadioButton") export default class StyledRadioButton extends React.PureComponent { public static readonly defaultProps = { className: '', diff --git a/src/components/views/elements/SyntaxHighlight.js b/src/components/views/elements/SyntaxHighlight.js index a4dc97d46e..f9874c5367 100644 --- a/src/components/views/elements/SyntaxHighlight.js +++ b/src/components/views/elements/SyntaxHighlight.js @@ -17,7 +17,9 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; import {highlightBlock} from 'highlight.js'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.elements.SyntaxHighlight") export default class SyntaxHighlight extends React.Component { static propTypes = { className: PropTypes.string, diff --git a/src/components/views/elements/TagTile.js b/src/components/views/elements/TagTile.js index 6c9a01a840..663acd6329 100644 --- a/src/components/views/elements/TagTile.js +++ b/src/components/views/elements/TagTile.js @@ -30,12 +30,14 @@ import GroupFilterOrderStore from '../../../stores/GroupFilterOrderStore'; import MatrixClientContext from "../../../contexts/MatrixClientContext"; import AccessibleButton from "./AccessibleButton"; import SettingsStore from "../../../settings/SettingsStore"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; // A class for a child of GroupFilterPanel (possibly wrapped in a DNDTagTile) that represents // a thing to click on for the user to filter the visible rooms in the RoomList to: // - Rooms that are part of the group // - Direct messages with members of the group // with the intention that this could be expanded to arbitrary tags in future. +@replaceableComponent("views.elements.TagTile") export default class TagTile extends React.Component { static propTypes = { // A string tag such as "m.favourite" or a group ID such as "+groupid:domain.bla" diff --git a/src/components/views/elements/TextWithTooltip.js b/src/components/views/elements/TextWithTooltip.js index b0405dc4c9..e4ad234ae2 100644 --- a/src/components/views/elements/TextWithTooltip.js +++ b/src/components/views/elements/TextWithTooltip.js @@ -17,7 +17,9 @@ import React from 'react'; import PropTypes from 'prop-types'; import * as sdk from '../../../index'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.elements.TextWithTooltip") export default class TextWithTooltip extends React.Component { static propTypes = { class: PropTypes.string, diff --git a/src/components/views/elements/TintableSvg.js b/src/components/views/elements/TintableSvg.js index df55b0a854..690deeedcd 100644 --- a/src/components/views/elements/TintableSvg.js +++ b/src/components/views/elements/TintableSvg.js @@ -18,7 +18,9 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; import Tinter from "../../../Tinter"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.elements.TintableSvg") class TintableSvg extends React.Component { static propTypes = { src: PropTypes.string.isRequired, diff --git a/src/components/views/elements/Tooltip.tsx b/src/components/views/elements/Tooltip.tsx index 03b9eb08d0..b2dd00de18 100644 --- a/src/components/views/elements/Tooltip.tsx +++ b/src/components/views/elements/Tooltip.tsx @@ -21,6 +21,7 @@ limitations under the License. import React, {Component, CSSProperties} from 'react'; import ReactDOM from 'react-dom'; import classNames from 'classnames'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; const MIN_TOOLTIP_HEIGHT = 25; @@ -39,6 +40,7 @@ interface IProps { yOffset?: number; } +@replaceableComponent("views.elements.Tooltip") export default class Tooltip extends React.Component { private tooltipContainer: HTMLElement; private tooltip: void | Element | Component; diff --git a/src/components/views/elements/TooltipButton.js b/src/components/views/elements/TooltipButton.js index 240d763bdc..c5ebb3b1aa 100644 --- a/src/components/views/elements/TooltipButton.js +++ b/src/components/views/elements/TooltipButton.js @@ -17,7 +17,9 @@ limitations under the License. import React from 'react'; import * as sdk from '../../../index'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.elements.TooltipButton") export default class TooltipButton extends React.Component { state = { hover: false, diff --git a/src/components/views/elements/TruncatedList.js b/src/components/views/elements/TruncatedList.js index 81eb057e36..0509775545 100644 --- a/src/components/views/elements/TruncatedList.js +++ b/src/components/views/elements/TruncatedList.js @@ -18,7 +18,9 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; import { _t } from '../../../languageHandler'; +import {replaceableComponent} from "../../../utils/replaceableComponent"; +@replaceableComponent("views.elements.TruncatedList") export default class TruncatedList extends React.Component { static propTypes = { // The number of elements to show before truncating. If negative, no truncation is done. diff --git a/src/components/views/elements/UserTagTile.tsx b/src/components/views/elements/UserTagTile.tsx index e7c74bb10e..d3e07a0a34 100644 --- a/src/components/views/elements/UserTagTile.tsx +++ b/src/components/views/elements/UserTagTile.tsx @@ -21,6 +21,7 @@ import GroupFilterOrderStore from "../../../stores/GroupFilterOrderStore"; import AccessibleTooltipButton from "./AccessibleTooltipButton"; import classNames from "classnames"; import { _t } from "../../../languageHandler"; +import {replaceableComponent} from "../../../utils/replaceableComponent"; interface IProps { } @@ -29,6 +30,7 @@ interface IState { selected: boolean; } +@replaceableComponent("views.elements.UserTagTile") export default class UserTagTile extends React.PureComponent { private tagStoreRef: fbEmitter.EventSubscription;