From 280f6a9d93fdbabfbf8491a5a5a6680a6d2c86e7 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 15 Jun 2023 08:46:19 +0100 Subject: [PATCH] Use MatrixClientPeg::safeGet in src/components/views/* (#10987) --- .../views/avatars/DecoratedRoomAvatar.tsx | 2 +- src/components/views/avatars/RoomAvatar.tsx | 2 +- .../context_menus/MessageContextMenu.tsx | 20 +++++------ .../context_menus/ThreadListContextMenu.tsx | 2 +- .../views/dialogs/CreateRoomDialog.tsx | 6 ++-- .../views/dialogs/DeactivateAccountDialog.tsx | 6 ++-- .../views/dialogs/IncomingSasDialog.tsx | 6 ++-- src/components/views/dialogs/InviteDialog.tsx | 28 +++++++-------- src/components/views/dialogs/LogoutDialog.tsx | 6 ++-- .../dialogs/MessageEditHistoryDialog.tsx | 4 +-- .../views/dialogs/ModalWidgetDialog.tsx | 4 +-- .../views/dialogs/ReportEventDialog.tsx | 6 ++-- .../views/dialogs/RoomSettingsDialog.tsx | 6 ++-- .../dialogs/RoomUpgradeWarningDialog.tsx | 2 +- .../views/dialogs/SetEmailDialog.tsx | 2 +- .../dialogs/SlidingSyncOptionsDialog.tsx | 4 +-- .../views/dialogs/UntrustedDeviceDialog.tsx | 2 +- .../dialogs/VerificationRequestDialog.tsx | 2 +- .../security/AccessSecretStorageDialog.tsx | 4 +-- .../security/CreateCrossSigningDialog.tsx | 11 +++--- .../security/RestoreKeyBackupDialog.tsx | 16 ++++----- .../dialogs/spotlight/SpotlightDialog.tsx | 4 +-- .../views/directory/NetworkDropdown.tsx | 2 +- .../views/elements/AppPermission.tsx | 2 +- .../views/elements/ErrorBoundary.tsx | 4 +-- .../views/elements/PersistedElement.tsx | 2 +- src/components/views/elements/Pill.tsx | 4 +-- src/components/views/elements/ReplyChain.tsx | 2 +- .../views/emojipicker/ReactionPicker.tsx | 6 ++-- .../views/messages/DateSeparator.tsx | 2 +- .../views/messages/EncryptionEvent.tsx | 2 +- src/components/views/messages/MImageBody.tsx | 6 ++-- .../views/messages/MJitsiWidgetEvent.tsx | 2 +- .../messages/MKeyVerificationConclusion.tsx | 6 ++-- .../messages/MKeyVerificationRequest.tsx | 8 ++--- src/components/views/messages/MPollBody.tsx | 2 +- .../views/messages/MessageActionBar.tsx | 10 +++--- .../views/messages/RoomAvatarEvent.tsx | 4 +-- .../views/messages/RoomPredecessorTile.tsx | 2 +- src/components/views/messages/TextualBody.tsx | 2 +- .../views/messages/TextualEvent.tsx | 2 +- .../views/messages/ViewSourceEvent.tsx | 2 +- .../room_settings/RoomProfileSettings.tsx | 4 +-- .../room_settings/RoomPublishSetting.tsx | 6 ++-- .../room_settings/UrlPreviewSettings.tsx | 2 +- src/components/views/rooms/AuxPanel.tsx | 2 +- .../views/rooms/EditMessageComposer.tsx | 6 ++-- src/components/views/rooms/EventTile.tsx | 36 +++++++++---------- src/components/views/rooms/MemberList.tsx | 10 +++--- src/components/views/rooms/MemberTile.tsx | 6 ++-- .../views/rooms/MessageComposer.tsx | 10 +++--- .../views/rooms/MessageComposerButtons.tsx | 2 +- src/components/views/rooms/NewRoomIntro.tsx | 7 ++-- src/components/views/rooms/ReplyTile.tsx | 2 +- src/components/views/rooms/RoomList.tsx | 2 +- src/components/views/rooms/RoomPreviewBar.tsx | 18 +++++----- src/components/views/rooms/RoomTile.tsx | 2 +- .../views/rooms/SendMessageComposer.tsx | 8 ++--- src/components/views/rooms/Stickerpicker.tsx | 8 +++-- .../views/rooms/ThirdPartyMemberInfo.tsx | 8 ++--- .../views/rooms/VoiceRecordComposerTile.tsx | 4 +-- .../views/rooms/WhoIsTypingTile.tsx | 4 +-- .../views/settings/ChangeDisplayName.tsx | 4 +-- .../views/settings/ChangePassword.tsx | 4 +-- .../views/settings/CryptographyPanel.tsx | 8 ++--- .../views/settings/FontScalingPanel.tsx | 4 +-- .../views/settings/Notifications.tsx | 28 +++++++-------- .../views/settings/ProfileSettings.tsx | 4 +-- .../views/settings/SecureBackupPanel.tsx | 29 +++++++-------- src/components/views/settings/SetIdServer.tsx | 18 +++++----- .../views/settings/account/EmailAddresses.tsx | 4 +-- .../views/settings/account/PhoneNumbers.tsx | 4 +-- .../settings/discovery/EmailAddresses.tsx | 10 +++--- .../views/settings/discovery/PhoneNumbers.tsx | 10 +++--- .../views/spaces/SpacePublicShare.tsx | 3 +- src/components/views/voip/LegacyCallView.tsx | 6 ++-- src/components/views/voip/VideoFeed.tsx | 2 +- .../views/messages/EncryptionEvent-test.tsx | 1 + .../views/right_panel/UserInfo-test.tsx | 1 + .../views/rooms/RoomPreviewBar-test.tsx | 10 ++++-- .../views/spaces/SpacePanel-test.tsx | 1 + 81 files changed, 265 insertions(+), 250 deletions(-) diff --git a/src/components/views/avatars/DecoratedRoomAvatar.tsx b/src/components/views/avatars/DecoratedRoomAvatar.tsx index 508285d07e..711bacda87 100644 --- a/src/components/views/avatars/DecoratedRoomAvatar.tsx +++ b/src/components/views/avatars/DecoratedRoomAvatar.tsx @@ -166,7 +166,7 @@ export default class DecoratedRoomAvatar extends React.PureComponent { } public componentDidMount(): void { - MatrixClientPeg.get().on(RoomStateEvent.Events, this.onRoomStateEvents); + MatrixClientPeg.safeGet().on(RoomStateEvent.Events, this.onRoomStateEvents); } public componentWillUnmount(): void { diff --git a/src/components/views/context_menus/MessageContextMenu.tsx b/src/components/views/context_menus/MessageContextMenu.tsx index 9fc7ca8110..ea5170c38a 100644 --- a/src/components/views/context_menus/MessageContextMenu.tsx +++ b/src/components/views/context_menus/MessageContextMenu.tsx @@ -144,7 +144,7 @@ export default class MessageContextMenu extends React.Component } public componentDidMount(): void { - MatrixClientPeg.get().on(RoomMemberEvent.PowerLevel, this.checkPermissions); + MatrixClientPeg.safeGet().on(RoomMemberEvent.PowerLevel, this.checkPermissions); // re-check the permissions on send progress (`maySendRedactionForEvent` only returns true for events that have // been fully sent and echoed back, and we want to ensure the "Remove" option is added once that happens.) @@ -162,7 +162,7 @@ export default class MessageContextMenu extends React.Component } private checkPermissions = (): void => { - const cli = MatrixClientPeg.get(); + const cli = MatrixClientPeg.safeGet(); const room = cli.getRoom(this.props.mxEvent.getRoomId()); // We explicitly decline to show the redact option on ACL events as it has a potential @@ -184,7 +184,7 @@ export default class MessageContextMenu extends React.Component }; private isPinned(): boolean { - const room = MatrixClientPeg.get().getRoom(this.props.mxEvent.getRoomId()); + const room = MatrixClientPeg.safeGet().getRoom(this.props.mxEvent.getRoomId()); const pinnedEvent = room?.currentState.getStateEvents(EventType.RoomPinnedEvents, ""); if (!pinnedEvent) return false; const content = pinnedEvent.getContent(); @@ -195,13 +195,13 @@ export default class MessageContextMenu extends React.Component return ( M_POLL_START.matches(mxEvent.getType()) && this.state.canRedact && - !isPollEnded(mxEvent, MatrixClientPeg.get()) + !isPollEnded(mxEvent, MatrixClientPeg.safeGet()) ); } private onResendReactionsClick = (): void => { for (const reaction of this.getUnsentReactions()) { - Resend.resend(MatrixClientPeg.get(), reaction); + Resend.resend(MatrixClientPeg.safeGet(), reaction); } this.closeMenu(); }; @@ -253,7 +253,7 @@ export default class MessageContextMenu extends React.Component }; private onPinClick = (): void => { - const cli = MatrixClientPeg.get(); + const cli = MatrixClientPeg.safeGet(); const room = cli.getRoom(this.props.mxEvent.getRoomId()); if (!room) return; const eventId = this.props.mxEvent.getId(); @@ -318,7 +318,7 @@ export default class MessageContextMenu extends React.Component private onEditClick = (): void => { editEvent( - MatrixClientPeg.get(), + MatrixClientPeg.safeGet(), this.props.mxEvent, this.context.timelineRenderingType, this.props.getRelationsForEvent, @@ -345,7 +345,7 @@ export default class MessageContextMenu extends React.Component }; private onEndPollClick = (): void => { - const matrixClient = MatrixClientPeg.get(); + const matrixClient = MatrixClientPeg.safeGet(); Modal.createDialog( EndPollDialog, { @@ -359,7 +359,7 @@ export default class MessageContextMenu extends React.Component }; private getReactions(filter: (e: MatrixEvent) => boolean): MatrixEvent[] { - const cli = MatrixClientPeg.get(); + const cli = MatrixClientPeg.safeGet(); const room = cli.getRoom(this.props.mxEvent.getRoomId()); const eventId = this.props.mxEvent.getId(); return ( @@ -386,7 +386,7 @@ export default class MessageContextMenu extends React.Component }; public render(): React.ReactNode { - const cli = MatrixClientPeg.get(); + const cli = MatrixClientPeg.safeGet(); const me = cli.getUserId(); const { mxEvent, rightClick, link, eventTileOps, reactions, collapseReplyChain, ...other } = this.props; delete other.getRelationsForEvent; diff --git a/src/components/views/context_menus/ThreadListContextMenu.tsx b/src/components/views/context_menus/ThreadListContextMenu.tsx index 543f2b9d96..c4464a6edd 100644 --- a/src/components/views/context_menus/ThreadListContextMenu.tsx +++ b/src/components/views/context_menus/ThreadListContextMenu.tsx @@ -84,7 +84,7 @@ const ThreadListContextMenu: React.FC = ({ onMenuToggle?.(menuDisplayed); }, [menuDisplayed, onMenuToggle]); - const room = MatrixClientPeg.get().getRoom(mxEvent.getRoomId()); + const room = MatrixClientPeg.safeGet().getRoom(mxEvent.getRoomId()); const isMainSplitTimelineShown = !!room && !WidgetLayoutStore.instance.hasMaximisedWidget(room); return ( diff --git a/src/components/views/dialogs/CreateRoomDialog.tsx b/src/components/views/dialogs/CreateRoomDialog.tsx index 2484d5fd7e..3ef2ff5c96 100644 --- a/src/components/views/dialogs/CreateRoomDialog.tsx +++ b/src/components/views/dialogs/CreateRoomDialog.tsx @@ -75,7 +75,7 @@ export default class CreateRoomDialog extends React.Component { joinRule = JoinRule.Restricted; } - const cli = MatrixClientPeg.get(); + const cli = MatrixClientPeg.safeGet(); this.state = { isPublic: this.props.defaultPublic || false, isEncrypted: this.props.defaultEncrypted ?? privateShouldBeEncrypted(cli), @@ -222,7 +222,7 @@ export default class CreateRoomDialog extends React.Component { let aliasField: JSX.Element | undefined; if (this.state.joinRule === JoinRule.Public) { - const domain = MatrixClientPeg.get().getDomain()!; + const domain = MatrixClientPeg.safeGet().getDomain()!; aliasField = (
{ let e2eeSection: JSX.Element | undefined; if (this.state.joinRule !== JoinRule.Public) { let microcopy: string; - if (privateShouldBeEncrypted(MatrixClientPeg.get())) { + if (privateShouldBeEncrypted(MatrixClientPeg.safeGet())) { if (this.state.canChangeEncryption) { microcopy = isVideoRoom ? _t("You can't disable this later. The room will be encrypted but the embedded call will not.") diff --git a/src/components/views/dialogs/DeactivateAccountDialog.tsx b/src/components/views/dialogs/DeactivateAccountDialog.tsx index 8e8f0be770..0c3a9c8565 100644 --- a/src/components/views/dialogs/DeactivateAccountDialog.tsx +++ b/src/components/views/dialogs/DeactivateAccountDialog.tsx @@ -125,7 +125,7 @@ export default class DeactivateAccountDialog extends React.Component { // Deactivation worked - logout & close this dialog @@ -158,7 +158,7 @@ export default class DeactivateAccountDialog extends React.Component { // If we got here, oops. The server didn't require any auth. @@ -190,7 +190,7 @@ export default class DeactivateAccountDialog extends React.Component {this.state.bodyText} { private async fetchOpponentProfile(): Promise { try { - const prof = await MatrixClientPeg.get().getProfileInfo(this.props.verifier.userId); + const prof = await MatrixClientPeg.safeGet().getProfileInfo(this.props.verifier.userId); this.setState({ opponentProfile: prof, }); @@ -143,7 +143,7 @@ export default class IncomingSasDialog extends React.Component { }; private renderPhaseStart(): ReactNode { - const isSelf = this.props.verifier.userId === MatrixClientPeg.get().getUserId(); + const isSelf = this.props.verifier.userId === MatrixClientPeg.safeGet().getUserId(); let profile; const oppProfile = this.state.opponentProfile; @@ -233,7 +233,7 @@ export default class IncomingSasDialog extends React.Component { sas={this.showSasEvent.sas} onCancel={this.onCancelClick} onDone={this.onSasMatchesClick} - isSelf={this.props.verifier.userId === MatrixClientPeg.get().getUserId()} + isSelf={this.props.verifier.userId === MatrixClientPeg.safeGet().getUserId()} inDialog={true} /> ); diff --git a/src/components/views/dialogs/InviteDialog.tsx b/src/components/views/dialogs/InviteDialog.tsx index 30dc15e5cc..b5e96a8010 100644 --- a/src/components/views/dialogs/InviteDialog.tsx +++ b/src/components/views/dialogs/InviteDialog.tsx @@ -373,12 +373,12 @@ export default class InviteDialog extends React.PureComponent alreadyInvited.add(m.userId)); room.getMembersWithMembership("join").forEach((m) => alreadyInvited.add(m.userId)); @@ -395,7 +395,7 @@ export default class InviteDialog extends React.PureComponent u.userId !== myUserId); for (const member of otherMembers) { @@ -491,7 +491,7 @@ export default class InviteDialog extends React.PureComponent): { userId: string; user: Member }[] { - const cli = MatrixClientPeg.get(); + const cli = MatrixClientPeg.safeGet(); const activityScores = buildActivityScores(cli); const memberScores = buildMemberScores(cli); @@ -560,7 +560,7 @@ export default class InviteDialog extends React.PureComponent t.userId); - const cli = MatrixClientPeg.get(); + const cli = MatrixClientPeg.safeGet(); const room = cli.getRoom(this.props.roomId); if (!room) { logger.error("Failed to find the room to invite users to"); @@ -694,7 +694,7 @@ export default class InviteDialog extends React.PureComponent => { - MatrixClientPeg.get() + MatrixClientPeg.safeGet() .searchUserDirectory({ term }) .then(async (r): Promise => { if (term !== this.state.filterText) { @@ -774,7 +774,7 @@ export default class InviteDialog extends React.PureComponent 0 || (this.state.filterText && this.state.filterText.includes("@")); - const cli = MatrixClientPeg.get(); + const cli = MatrixClientPeg.safeGet(); const userId = cli.getUserId()!; if (this.props.kind === InviteKind.Dm) { title = _t("Direct Messages"); @@ -1332,11 +1332,11 @@ export default class InviteDialog extends React.PureComponent{_t("If you can't see who you're looking for, send them your invite link below.")}

); - const link = makeUserPermalink(MatrixClientPeg.get().getUserId()!); + const link = makeUserPermalink(MatrixClientPeg.safeGet().getSafeUserId()); footer = (

{_t("Or send invite link")}

- makeUserPermalink(MatrixClientPeg.get().getUserId()!)}> + makeUserPermalink(MatrixClientPeg.safeGet().getSafeUserId())}> {link} diff --git a/src/components/views/dialogs/LogoutDialog.tsx b/src/components/views/dialogs/LogoutDialog.tsx index daf81ced65..bf92719c19 100644 --- a/src/components/views/dialogs/LogoutDialog.tsx +++ b/src/components/views/dialogs/LogoutDialog.tsx @@ -50,7 +50,7 @@ export default class LogoutDialog extends React.Component { public constructor(props: IProps) { super(props); - const cli = MatrixClientPeg.get(); + const cli = MatrixClientPeg.safeGet(); const shouldLoadBackupStatus = cli.isCryptoEnabled() && !cli.getKeyBackupEnabled(); this.state = { @@ -66,7 +66,7 @@ export default class LogoutDialog extends React.Component { private async loadBackupStatus(): Promise { try { - const backupInfo = await MatrixClientPeg.get().getKeyBackupVersion(); + const backupInfo = await MatrixClientPeg.safeGet().getKeyBackupVersion(); this.setState({ loading: false, backupInfo, @@ -86,7 +86,7 @@ export default class LogoutDialog extends React.Component { typeof ExportE2eKeysDialog >, { - matrixClient: MatrixClientPeg.get(), + matrixClient: MatrixClientPeg.safeGet(), }, ); }; diff --git a/src/components/views/dialogs/MessageEditHistoryDialog.tsx b/src/components/views/dialogs/MessageEditHistoryDialog.tsx index a8b446df09..58e7ba9b18 100644 --- a/src/components/views/dialogs/MessageEditHistoryDialog.tsx +++ b/src/components/views/dialogs/MessageEditHistoryDialog.tsx @@ -67,7 +67,7 @@ export default class MessageEditHistoryDialog extends React.PureComponent(); let result: Awaited>; @@ -102,7 +102,7 @@ export default class MessageEditHistoryDialog extends React.PureComponent b.id); @@ -130,7 +130,7 @@ export default class ModalWidgetDialog extends React.PureComponent { // Does the room support it, too? // Extract state events to determine whether we should display - const client = MatrixClientPeg.get(); + const client = MatrixClientPeg.safeGet(); const room = client.getRoom(props.mxEvent.getRoomId()); for (const stateEventType of MODERATED_BY_STATE_EVENT_TYPE) { @@ -237,7 +237,7 @@ export default class ReportEventDialog extends React.Component { }); try { - const client = MatrixClientPeg.get(); + const client = MatrixClientPeg.safeGet(); const ev = this.props.mxEvent; if (this.moderation && this.state.nature !== NonStandardValue.Admin) { const nature = this.state.nature; @@ -312,7 +312,7 @@ export default class ReportEventDialog extends React.Component { if (this.moderation) { // Display report-to-moderator dialog. // We let the user pick a nature. - const client = MatrixClientPeg.get(); + const client = MatrixClientPeg.safeGet(); const homeServerName = SdkConfig.get("validated_server_config")!.hsName; let subtitle: string; switch (this.state.nature) { diff --git a/src/components/views/dialogs/RoomSettingsDialog.tsx b/src/components/views/dialogs/RoomSettingsDialog.tsx index 55e49843b2..86d748730b 100644 --- a/src/components/views/dialogs/RoomSettingsDialog.tsx +++ b/src/components/views/dialogs/RoomSettingsDialog.tsx @@ -73,7 +73,7 @@ class RoomSettingsDialog extends React.Component { public componentDidMount(): void { this.dispatcherRef = dis.register(this.onAction); - MatrixClientPeg.get().on(RoomEvent.Name, this.onRoomName); + MatrixClientPeg.safeGet().on(RoomEvent.Name, this.onRoomName); this.onRoomName(); } @@ -89,7 +89,7 @@ class RoomSettingsDialog extends React.Component { dis.unregister(this.dispatcherRef); } - MatrixClientPeg.get().removeListener(RoomEvent.Name, this.onRoomName); + MatrixClientPeg.get()?.removeListener(RoomEvent.Name, this.onRoomName); } /** @@ -98,7 +98,7 @@ class RoomSettingsDialog extends React.Component { * @throws when room is not found */ private getRoom(): Room { - const room = MatrixClientPeg.get().getRoom(this.props.roomId)!; + const room = MatrixClientPeg.safeGet().getRoom(this.props.roomId)!; // something is really wrong if we encounter this if (!room) { diff --git a/src/components/views/dialogs/RoomUpgradeWarningDialog.tsx b/src/components/views/dialogs/RoomUpgradeWarningDialog.tsx index 4ae49a327f..be59a3e011 100644 --- a/src/components/views/dialogs/RoomUpgradeWarningDialog.tsx +++ b/src/components/views/dialogs/RoomUpgradeWarningDialog.tsx @@ -60,7 +60,7 @@ export default class RoomUpgradeWarningDialog extends React.Component { }); return; } - this.addThreepid = new AddThreepid(MatrixClientPeg.get()); + this.addThreepid = new AddThreepid(MatrixClientPeg.safeGet()); this.addThreepid.addEmailAddress(emailAddress).then( () => { Modal.createDialog(QuestionDialog, { diff --git a/src/components/views/dialogs/SlidingSyncOptionsDialog.tsx b/src/components/views/dialogs/SlidingSyncOptionsDialog.tsx index 9ef3e83ede..3745700091 100644 --- a/src/components/views/dialogs/SlidingSyncOptionsDialog.tsx +++ b/src/components/views/dialogs/SlidingSyncOptionsDialog.tsx @@ -63,7 +63,7 @@ async function proxyHealthCheck(endpoint: string, hsUrl?: string): Promise } export const SlidingSyncOptionsDialog: React.FC<{ onFinished(enabled: boolean): void }> = ({ onFinished }) => { - const cli = MatrixClientPeg.get(); + const cli = MatrixClientPeg.safeGet(); const currentProxy = SettingsStore.getValue("feature_sliding_sync_proxy_url"); const hasNativeSupport = useAsyncMemo( () => @@ -87,7 +87,7 @@ export const SlidingSyncOptionsDialog: React.FC<{ onFinished(enabled: boolean): const validProxy = withValidation({ async deriveData({ value }): Promise<{ error?: Error }> { try { - await proxyHealthCheck(value!, MatrixClientPeg.get().baseUrl); + await proxyHealthCheck(value!, MatrixClientPeg.safeGet().baseUrl); return {}; } catch (error) { return { error }; diff --git a/src/components/views/dialogs/UntrustedDeviceDialog.tsx b/src/components/views/dialogs/UntrustedDeviceDialog.tsx index 393590ff9d..296a8f0610 100644 --- a/src/components/views/dialogs/UntrustedDeviceDialog.tsx +++ b/src/components/views/dialogs/UntrustedDeviceDialog.tsx @@ -34,7 +34,7 @@ const UntrustedDeviceDialog: React.FC = ({ device, user, onFinished }) = let askToVerifyText: string; let newSessionText: string; - if (MatrixClientPeg.get().getUserId() === user.userId) { + if (MatrixClientPeg.safeGet().getUserId() === user.userId) { newSessionText = _t("You signed in to a new session without verifying it:"); askToVerifyText = _t("Verify your other session using one of the options below."); } else { diff --git a/src/components/views/dialogs/VerificationRequestDialog.tsx b/src/components/views/dialogs/VerificationRequestDialog.tsx index ebd54165cc..f087969c1b 100644 --- a/src/components/views/dialogs/VerificationRequestDialog.tsx +++ b/src/components/views/dialogs/VerificationRequestDialog.tsx @@ -48,7 +48,7 @@ export default class VerificationRequestDialog extends React.Component => { // Now reset cross-signing so everything Just Works™ again. - const cli = MatrixClientPeg.get(); + const cli = MatrixClientPeg.safeGet(); await cli.bootstrapCrossSigning({ authUploadDeviceSigningKeys: async (makeRequest): Promise => { const { finished } = Modal.createDialog(InteractiveAuthDialog, { diff --git a/src/components/views/dialogs/security/CreateCrossSigningDialog.tsx b/src/components/views/dialogs/security/CreateCrossSigningDialog.tsx index 2bac1f028c..7a6412c8ed 100644 --- a/src/components/views/dialogs/security/CreateCrossSigningDialog.tsx +++ b/src/components/views/dialogs/security/CreateCrossSigningDialog.tsx @@ -73,7 +73,7 @@ export default class CreateCrossSigningDialog extends React.PureComponent { try { - await MatrixClientPeg.get().uploadDeviceSigningKeys(undefined, {} as CrossSigningKeys); + await MatrixClientPeg.safeGet().uploadDeviceSigningKeys(undefined, {} as CrossSigningKeys); // We should never get here: the server should always require // UI auth to upload device signing keys. If we do, we upload // no keys which would be a no-op. @@ -98,11 +98,11 @@ export default class CreateCrossSigningDialog extends React.PureComponent): void => { this.setState({ recoveryKey: e.target.value, - recoveryKeyValid: MatrixClientPeg.get().isValidRecoveryKey(e.target.value), + recoveryKeyValid: MatrixClientPeg.safeGet().isValidRecoveryKey(e.target.value), }); }; @@ -145,7 +145,7 @@ export default class RestoreKeyBackupDialog extends React.PureComponent => { if (!this.state.backupInfo) return; - await MatrixClientPeg.get().restoreKeyBackupWithSecretStorage( + await MatrixClientPeg.safeGet().restoreKeyBackupWithSecretStorage( this.state.backupInfo, undefined, undefined, @@ -252,7 +252,7 @@ export default class RestoreKeyBackupDialog extends React.PureComponent { if (!backupInfo) return false; try { - const recoverInfo = await MatrixClientPeg.get().restoreKeyBackupWithCache( + const recoverInfo = await MatrixClientPeg.safeGet().restoreKeyBackupWithCache( undefined /* targetRoomId */, undefined /* targetSessionId */, backupInfo, @@ -274,7 +274,7 @@ export default class RestoreKeyBackupDialog extends React.PureComponent { - const myUserId = MatrixClientPeg.get().getUserId(); + const myUserId = MatrixClientPeg.safeGet().getUserId(); const otherUserId = DMRoomMap.shared().getUserIdForRoomId(room.roomId); if (otherUserId) { @@ -281,7 +281,7 @@ interface IDirectoryOpts { const SpotlightDialog: React.FC = ({ initialText = "", initialFilter = null, onFinished }) => { const inputRef = useRef(null); const scrollContainerRef = useRef(null); - const cli = MatrixClientPeg.get(); + const cli = MatrixClientPeg.safeGet(); const rovingContext = useContext(RovingTabIndexContext); const [query, _setQuery] = useState(initialText); const [recentSearches, clearRecentSearches] = useRecentSearches(); diff --git a/src/components/views/directory/NetworkDropdown.tsx b/src/components/views/directory/NetworkDropdown.tsx index b4ed2e10ae..081d7e2a7c 100644 --- a/src/components/views/directory/NetworkDropdown.tsx +++ b/src/components/views/directory/NetworkDropdown.tsx @@ -42,7 +42,7 @@ const validServer = withValidation({ deriveData: async ({ value }): Promise<{ error?: MatrixError }> => { try { // check if we can successfully load this server's room directory - await MatrixClientPeg.get().publicRooms({ + await MatrixClientPeg.safeGet().publicRooms({ limit: 1, server: value ?? undefined, }); diff --git a/src/components/views/elements/AppPermission.tsx b/src/components/views/elements/AppPermission.tsx index f57a5e4a29..463db9f2e3 100644 --- a/src/components/views/elements/AppPermission.tsx +++ b/src/components/views/elements/AppPermission.tsx @@ -57,7 +57,7 @@ export default class AppPermission extends React.Component { const urlInfo = this.parseWidgetUrl(); // The second step is to find the user's profile so we can show it on the prompt - const room = MatrixClientPeg.get().getRoom(this.props.roomId); + const room = MatrixClientPeg.safeGet().getRoom(this.props.roomId); let roomMember: RoomMember | null = null; if (room) roomMember = room.getMember(this.props.creatorUserId); diff --git a/src/components/views/elements/ErrorBoundary.tsx b/src/components/views/elements/ErrorBoundary.tsx index a230ab84c5..dca7d4562f 100644 --- a/src/components/views/elements/ErrorBoundary.tsx +++ b/src/components/views/elements/ErrorBoundary.tsx @@ -60,8 +60,8 @@ export default class ErrorBoundary extends React.PureComponent { private onClearCacheAndReload = (): void => { if (!PlatformPeg.get()) return; - MatrixClientPeg.get().stopClient(); - MatrixClientPeg.get() + MatrixClientPeg.safeGet().stopClient(); + MatrixClientPeg.safeGet() .store.deleteAllData() .then(() => { PlatformPeg.get()?.reload(); diff --git a/src/components/views/elements/PersistedElement.tsx b/src/components/views/elements/PersistedElement.tsx index b1d53247db..2d4c763eb2 100644 --- a/src/components/views/elements/PersistedElement.tsx +++ b/src/components/views/elements/PersistedElement.tsx @@ -162,7 +162,7 @@ export default class PersistedElement extends React.Component { private renderApp(): void { const content = ( - +
{this.props.children}
diff --git a/src/components/views/elements/Pill.tsx b/src/components/views/elements/Pill.tsx index 49c6c1bfd2..e5e9d383ea 100644 --- a/src/components/views/elements/Pill.tsx +++ b/src/components/views/elements/Pill.tsx @@ -106,7 +106,7 @@ export const Pill: React.FC = ({ type: propType, url, inMessage, room mx_RoomPill: type === PillType.RoomMention, mx_SpacePill: type === "space", mx_UserPill: type === PillType.UserMention, - mx_UserPill_me: resourceId === MatrixClientPeg.get().getUserId(), + mx_UserPill_me: resourceId === MatrixClientPeg.safeGet().getUserId(), mx_EventPill: type === PillType.EventInOtherRoom || type === PillType.EventInSameRoom, }); @@ -158,7 +158,7 @@ export const Pill: React.FC = ({ type: propType, url, inMessage, room return ( - + {inMessage && url ? ( { } private get matrixClient(): MatrixClient { - return MatrixClientPeg.get(); + return MatrixClientPeg.safeGet(); } public componentDidMount(): void { diff --git a/src/components/views/emojipicker/ReactionPicker.tsx b/src/components/views/emojipicker/ReactionPicker.tsx index 97222740f8..b479b446e2 100644 --- a/src/components/views/emojipicker/ReactionPicker.tsx +++ b/src/components/views/emojipicker/ReactionPicker.tsx @@ -77,7 +77,7 @@ class ReactionPicker extends React.Component { if (!this.props.reactions) { return {}; } - const userId = MatrixClientPeg.get().getUserId()!; + const userId = MatrixClientPeg.safeGet().getSafeUserId(); const myAnnotations = this.props.reactions.getAnnotationsBySender()?.[userId] ?? new Set(); return Object.fromEntries( [...myAnnotations] @@ -99,7 +99,7 @@ class ReactionPicker extends React.Component { if (myReactions.hasOwnProperty(reaction)) { if (this.props.mxEvent.isRedacted() || !this.context.canSelfRedact) return false; - MatrixClientPeg.get().redactEvent(this.props.mxEvent.getRoomId()!, myReactions[reaction]); + MatrixClientPeg.safeGet().redactEvent(this.props.mxEvent.getRoomId()!, myReactions[reaction]); dis.dispatch({ action: Action.FocusAComposer, context: this.context.timelineRenderingType, @@ -107,7 +107,7 @@ class ReactionPicker extends React.Component { // Tell the emoji picker not to bump this in the more frequently used list. return false; } else { - MatrixClientPeg.get().sendEvent(this.props.mxEvent.getRoomId()!, EventType.Reaction, { + MatrixClientPeg.safeGet().sendEvent(this.props.mxEvent.getRoomId()!, EventType.Reaction, { "m.relates_to": { rel_type: RelationType.Annotation, event_id: this.props.mxEvent.getId(), diff --git a/src/components/views/messages/DateSeparator.tsx b/src/components/views/messages/DateSeparator.tsx index 4eed475d5c..87969ac4b7 100644 --- a/src/components/views/messages/DateSeparator.tsx +++ b/src/components/views/messages/DateSeparator.tsx @@ -125,7 +125,7 @@ export default class DateSeparator extends React.Component { const roomIdForJumpRequest = this.props.roomId; try { - const cli = MatrixClientPeg.get(); + const cli = MatrixClientPeg.safeGet(); const { event_id: eventId, origin_server_ts: originServerTs } = await cli.timestampToEvent( roomIdForJumpRequest, unixTimestamp, diff --git a/src/components/views/messages/EncryptionEvent.tsx b/src/components/views/messages/EncryptionEvent.tsx index fbc1da18d3..963afd415e 100644 --- a/src/components/views/messages/EncryptionEvent.tsx +++ b/src/components/views/messages/EncryptionEvent.tsx @@ -36,7 +36,7 @@ const ALGORITHM = "m.megolm.v1.aes-sha2"; const EncryptionEvent = forwardRef(({ mxEvent, timestamp }, ref) => { const cli = useContext(MatrixClientContext); const roomId = mxEvent.getRoomId()!; - const isRoomEncrypted = MatrixClientPeg.get().isRoomEncrypted(roomId); + const isRoomEncrypted = MatrixClientPeg.safeGet().isRoomEncrypted(roomId); const prevContent = mxEvent.getPrevContent() as IRoomEncryption; const content = mxEvent.getContent(); diff --git a/src/components/views/messages/MImageBody.tsx b/src/components/views/messages/MImageBody.tsx index acfe2e27ab..3f62c72fae 100644 --- a/src/components/views/messages/MImageBody.tsx +++ b/src/components/views/messages/MImageBody.tsx @@ -160,7 +160,7 @@ export default class MImageBody extends React.Component { }; private clearError = (): void => { - MatrixClientPeg.get().off(ClientEvent.Sync, this.reconnectedListener); + MatrixClientPeg.get()?.off(ClientEvent.Sync, this.reconnectedListener); this.setState({ imgError: false }); }; @@ -177,7 +177,7 @@ export default class MImageBody extends React.Component { this.setState({ imgError: true, }); - MatrixClientPeg.get().on(ClientEvent.Sync, this.reconnectedListener); + MatrixClientPeg.safeGet().on(ClientEvent.Sync, this.reconnectedListener); }; private onImageLoad = (): void => { @@ -373,7 +373,7 @@ export default class MImageBody extends React.Component { public componentWillUnmount(): void { this.unmounted = true; - MatrixClientPeg.get().off(ClientEvent.Sync, this.reconnectedListener); + MatrixClientPeg.get()?.off(ClientEvent.Sync, this.reconnectedListener); this.clearBlurhashTimeout(); if (this.sizeWatcher) SettingsStore.unwatchSetting(this.sizeWatcher); if (this.state.isAnimated && this.state.thumbUrl) { diff --git a/src/components/views/messages/MJitsiWidgetEvent.tsx b/src/components/views/messages/MJitsiWidgetEvent.tsx index b299d96f6d..e71a468143 100644 --- a/src/components/views/messages/MJitsiWidgetEvent.tsx +++ b/src/components/views/messages/MJitsiWidgetEvent.tsx @@ -37,7 +37,7 @@ export default class MJitsiWidgetEvent extends React.PureComponent { const url = this.props.mxEvent.getContent()["url"]; const prevUrl = this.props.mxEvent.getPrevContent()["url"]; const senderName = this.props.mxEvent.sender?.name || this.props.mxEvent.getSender(); - const room = MatrixClientPeg.get().getRoom(this.props.mxEvent.getRoomId()); + const room = MatrixClientPeg.safeGet().getRoom(this.props.mxEvent.getRoomId()); if (!room) return null; const widgetId = this.props.mxEvent.getStateKey(); const widget = WidgetStore.instance.getRoom(room.roomId, true).widgets.find((w) => w.id === widgetId); diff --git a/src/components/views/messages/MKeyVerificationConclusion.tsx b/src/components/views/messages/MKeyVerificationConclusion.tsx index 84dec01690..4ec24231dc 100644 --- a/src/components/views/messages/MKeyVerificationConclusion.tsx +++ b/src/components/views/messages/MKeyVerificationConclusion.tsx @@ -42,7 +42,7 @@ export default class MKeyVerificationConclusion extends React.Component if (request) { request.on(VerificationRequestEvent.Change, this.onRequestChanged); } - MatrixClientPeg.get().on(CryptoEvent.UserTrustStatusChanged, this.onTrustChanged); + MatrixClientPeg.safeGet().on(CryptoEvent.UserTrustStatusChanged, this.onTrustChanged); } public componentWillUnmount(): void { @@ -89,7 +89,7 @@ export default class MKeyVerificationConclusion extends React.Component } // User isn't actually verified - if (!MatrixClientPeg.get().checkUserTrust(request.otherUserId).isCrossSigningVerified()) { + if (!MatrixClientPeg.safeGet().checkUserTrust(request.otherUserId).isCrossSigningVerified()) { return false; } @@ -104,7 +104,7 @@ export default class MKeyVerificationConclusion extends React.Component return null; } - const client = MatrixClientPeg.get(); + const client = MatrixClientPeg.safeGet(); const myUserId = client.getUserId(); let title: string | undefined; diff --git a/src/components/views/messages/MKeyVerificationRequest.tsx b/src/components/views/messages/MKeyVerificationRequest.tsx index cf5273a861..5ae432b90c 100644 --- a/src/components/views/messages/MKeyVerificationRequest.tsx +++ b/src/components/views/messages/MKeyVerificationRequest.tsx @@ -55,7 +55,7 @@ export default class MKeyVerificationRequest extends React.Component { let member: User | undefined; const { verificationRequest } = this.props.mxEvent; if (verificationRequest) { - member = MatrixClientPeg.get().getUser(verificationRequest.otherUserId) ?? undefined; + member = MatrixClientPeg.safeGet().getUser(verificationRequest.otherUserId) ?? undefined; } RightPanelStore.instance.setCards([ { phase: RightPanelPhases.RoomSummary }, @@ -92,7 +92,7 @@ export default class MKeyVerificationRequest extends React.Component { }; private acceptedLabel(userId: string): string { - const client = MatrixClientPeg.get(); + const client = MatrixClientPeg.safeGet(); const myUserId = client.getUserId(); if (userId === myUserId) { return _t("You accepted"); @@ -104,7 +104,7 @@ export default class MKeyVerificationRequest extends React.Component { } private cancelledLabel(userId: string): string { - const client = MatrixClientPeg.get(); + const client = MatrixClientPeg.safeGet(); const myUserId = client.getUserId(); const cancellationCode = this.props.mxEvent.verificationRequest?.cancellationCode; const declined = cancellationCode === "m.user"; @@ -128,7 +128,7 @@ export default class MKeyVerificationRequest extends React.Component { } public render(): React.ReactNode { - const client = MatrixClientPeg.get(); + const client = MatrixClientPeg.safeGet(); const { mxEvent } = this.props; const request = mxEvent.verificationRequest; diff --git a/src/components/views/messages/MPollBody.tsx b/src/components/views/messages/MPollBody.tsx index 1029f7370d..5a5c1b5315 100644 --- a/src/components/views/messages/MPollBody.tsx +++ b/src/components/views/messages/MPollBody.tsx @@ -118,7 +118,7 @@ export function pollAlreadyHasVotes(mxEvent: MatrixEvent, getRelationsForEvent?: } export function launchPollEditor(mxEvent: MatrixEvent, getRelationsForEvent?: GetRelationsForEvent): void { - const room = MatrixClientPeg.get().getRoom(mxEvent.getRoomId()); + const room = MatrixClientPeg.safeGet().getRoom(mxEvent.getRoomId()); if (pollAlreadyHasVotes(mxEvent, getRelationsForEvent)) { Modal.createDialog(ErrorDialog, { title: _t("Can't edit poll"), diff --git a/src/components/views/messages/MessageActionBar.tsx b/src/components/views/messages/MessageActionBar.tsx index 22f13178b3..a0b730b65f 100644 --- a/src/components/views/messages/MessageActionBar.tsx +++ b/src/components/views/messages/MessageActionBar.tsx @@ -311,7 +311,7 @@ export default class MessageActionBar extends React.PureComponent Resend.resend(MatrixClientPeg.get(), tarEv)); + this.runActionOnFailedEv((tarEv) => Resend.resend(MatrixClientPeg.safeGet(), tarEv)); }; private onCancelClick = (ev: ButtonEvent): void => { this.runActionOnFailedEv( - (tarEv) => Resend.removeFromQueue(MatrixClientPeg.get(), tarEv), + (tarEv) => Resend.removeFromQueue(MatrixClientPeg.safeGet(), tarEv), (testEv) => canCancel(testEv.status), ); }; public render(): React.ReactNode { const toolbarOpts: JSX.Element[] = []; - if (canEditContent(MatrixClientPeg.get(), this.props.mxEvent)) { + if (canEditContent(MatrixClientPeg.safeGet(), this.props.mxEvent)) { toolbarOpts.push( { private onAvatarClick = (): void => { - const cli = MatrixClientPeg.get(); + const cli = MatrixClientPeg.safeGet(); const ev = this.props.mxEvent; const httpUrl = mediaFromMxc(ev.getContent().url).srcHttp; if (!httpUrl) return; @@ -63,7 +63,7 @@ export default class RoomAvatarEvent extends React.Component { ); } - const room = MatrixClientPeg.get().getRoom(ev.getRoomId()); + const room = MatrixClientPeg.safeGet().getRoom(ev.getRoomId()); // Provide all arguments to RoomAvatar via oobData because the avatar is historic const oobData = { avatarUrl: ev.getContent().url, diff --git a/src/components/views/messages/RoomPredecessorTile.tsx b/src/components/views/messages/RoomPredecessorTile.tsx index bee0849fa4..67be715634 100644 --- a/src/components/views/messages/RoomPredecessorTile.tsx +++ b/src/components/views/messages/RoomPredecessorTile.tsx @@ -87,7 +87,7 @@ export const RoomPredecessorTile: React.FC = ({ mxEvent, timestamp }) => return
; } - const prevRoom = MatrixClientPeg.get().getRoom(predecessor.roomId); + const prevRoom = MatrixClientPeg.safeGet().getRoom(predecessor.roomId); // We need either the previous room, or some servers to find it with. // Otherwise, we must bail out here diff --git a/src/components/views/messages/TextualBody.tsx b/src/components/views/messages/TextualBody.tsx index b02c52a64a..3c4e98fb58 100644 --- a/src/components/views/messages/TextualBody.tsx +++ b/src/components/views/messages/TextualBody.tsx @@ -93,7 +93,7 @@ export default class TextualBody extends React.Component { this.activateSpoilers([content]); HtmlUtils.linkifyElement(content); - pillifyLinks(MatrixClientPeg.get(), [content], this.props.mxEvent, this.pills); + pillifyLinks(MatrixClientPeg.safeGet(), [content], this.props.mxEvent, this.pills); this.calculateUrlPreview(); diff --git a/src/components/views/messages/TextualEvent.tsx b/src/components/views/messages/TextualEvent.tsx index 93501bac67..fa82c3bf31 100644 --- a/src/components/views/messages/TextualEvent.tsx +++ b/src/components/views/messages/TextualEvent.tsx @@ -31,7 +31,7 @@ export default class TextualEvent extends React.Component { public render(): React.ReactNode { const text = TextForEvent.textForEvent( this.props.mxEvent, - MatrixClientPeg.get(), + MatrixClientPeg.safeGet(), true, this.context?.showHiddenEvents, ); diff --git a/src/components/views/messages/ViewSourceEvent.tsx b/src/components/views/messages/ViewSourceEvent.tsx index 1d33074a7a..5bd8550796 100644 --- a/src/components/views/messages/ViewSourceEvent.tsx +++ b/src/components/views/messages/ViewSourceEvent.tsx @@ -42,7 +42,7 @@ export default class ViewSourceEvent extends React.PureComponent public componentDidMount(): void { const { mxEvent } = this.props; - const client = MatrixClientPeg.get(); + const client = MatrixClientPeg.safeGet(); client.decryptEventIfNeeded(mxEvent); if (mxEvent.isBeingDecrypted()) { diff --git a/src/components/views/room_settings/RoomProfileSettings.tsx b/src/components/views/room_settings/RoomProfileSettings.tsx index 7117608f39..21768cd16a 100644 --- a/src/components/views/room_settings/RoomProfileSettings.tsx +++ b/src/components/views/room_settings/RoomProfileSettings.tsx @@ -52,7 +52,7 @@ export default class RoomProfileSettings extends React.Component public constructor(props: IProps) { super(props); - const client = MatrixClientPeg.get(); + const client = MatrixClientPeg.safeGet(); const room = client.getRoom(props.roomId); if (!room) throw new Error(`Expected a room for ID: ${props.roomId}`); @@ -124,7 +124,7 @@ export default class RoomProfileSettings extends React.Component if (!this.isSaveEnabled()) return; this.setState({ profileFieldsTouched: {} }); - const client = MatrixClientPeg.get(); + const client = MatrixClientPeg.safeGet(); const newState: Partial = {}; // TODO: What do we do about errors? diff --git a/src/components/views/room_settings/RoomPublishSetting.tsx b/src/components/views/room_settings/RoomPublishSetting.tsx index 1aeeb1876d..a2f93e4cc5 100644 --- a/src/components/views/room_settings/RoomPublishSetting.tsx +++ b/src/components/views/room_settings/RoomPublishSetting.tsx @@ -45,7 +45,7 @@ export default class RoomPublishSetting extends React.PureComponent { this.setState({ isRoomPublished: result.visibility === "public" }); }); } public render(): React.ReactNode { - const client = MatrixClientPeg.get(); + const client = MatrixClientPeg.safeGet(); const room = client.getRoom(this.props.roomId); const isRoomPublishable = room && room.getJoinRule() !== JoinRule.Invite; diff --git a/src/components/views/room_settings/UrlPreviewSettings.tsx b/src/components/views/room_settings/UrlPreviewSettings.tsx index e859f3adc4..15d70132e2 100644 --- a/src/components/views/room_settings/UrlPreviewSettings.tsx +++ b/src/components/views/room_settings/UrlPreviewSettings.tsx @@ -43,7 +43,7 @@ export default class UrlPreviewSettings extends React.Component { public render(): ReactNode { const roomId = this.props.room.roomId; - const isEncrypted = MatrixClientPeg.get().isRoomEncrypted(roomId); + const isEncrypted = MatrixClientPeg.safeGet().isRoomEncrypted(roomId); let previewsForAccount: ReactNode | undefined; let previewsForRoom: ReactNode | undefined; diff --git a/src/components/views/rooms/AuxPanel.tsx b/src/components/views/rooms/AuxPanel.tsx index e7f9141629..73002f484b 100644 --- a/src/components/views/rooms/AuxPanel.tsx +++ b/src/components/views/rooms/AuxPanel.tsx @@ -65,7 +65,7 @@ export default class AuxPanel extends React.Component { } public componentDidMount(): void { - const cli = MatrixClientPeg.get(); + const cli = MatrixClientPeg.safeGet(); if (SettingsStore.getValue("feature_state_counters")) { cli.on(RoomStateEvent.Events, this.onRoomStateEvents); } diff --git a/src/components/views/rooms/EditMessageComposer.tsx b/src/components/views/rooms/EditMessageComposer.tsx index 1b403e31fb..08e307b5dd 100644 --- a/src/components/views/rooms/EditMessageComposer.tsx +++ b/src/components/views/rooms/EditMessageComposer.tsx @@ -182,7 +182,7 @@ class EditMessageComposer extends React.Component if (!this.props.mxEvent) return false; // Sanity check (should never happen, but we shouldn't explode if it does) - const room = MatrixClientPeg.get().getRoom(this.props.mxEvent.getRoomId()); + const room = MatrixClientPeg.safeGet().getRoom(this.props.mxEvent.getRoomId()); if (!room) return false; // Quickly check to see if the event was sent by us. If it wasn't, it won't qualify for // special read receipts. - const myUserId = MatrixClientPeg.get().getUserId(); + const myUserId = MatrixClientPeg.safeGet().getUserId(); if (this.props.mxEvent.getSender() !== myUserId) return false; // Finally, determine if the type is relevant to the user. This notably excludes state @@ -344,7 +344,7 @@ export class UnwrappedEventTile extends React.Component // If anyone has read the event besides us, we don't want to show a sent receipt. const receipts = this.props.readReceipts || []; - const myUserId = MatrixClientPeg.get().getUserId(); + const myUserId = MatrixClientPeg.safeGet().getUserId(); if (receipts.some((r) => r.userId !== myUserId)) return false; // Finally, we should show a receipt. @@ -366,7 +366,7 @@ export class UnwrappedEventTile extends React.Component public componentDidMount(): void { this.suppressReadReceiptAnimation = false; - const client = MatrixClientPeg.get(); + const client = MatrixClientPeg.safeGet(); if (!this.props.forExport) { client.on(CryptoEvent.DeviceVerificationChanged, this.onDeviceVerificationChanged); client.on(CryptoEvent.UserTrustStatusChanged, this.onUserVerificationChanged); @@ -431,7 +431,7 @@ export class UnwrappedEventTile extends React.Component } // If we're not listening for receipts and expect to be, register a listener. if (!this.isListeningForReceipts && (this.shouldShowSentReceipt || this.shouldShowSendingReceipt)) { - MatrixClientPeg.get().on(RoomEvent.Receipt, this.onRoomReceipt); + MatrixClientPeg.safeGet().on(RoomEvent.Receipt, this.onRoomReceipt); this.isListeningForReceipts = true; } // re-check the sender verification as outgoing events progress through the send process. @@ -443,7 +443,7 @@ export class UnwrappedEventTile extends React.Component private onNewThread = (thread: Thread): void => { if (thread.id === this.props.mxEvent.getId()) { this.updateThread(thread); - const room = MatrixClientPeg.get().getRoom(this.props.mxEvent.getRoomId()); + const room = MatrixClientPeg.safeGet().getRoom(this.props.mxEvent.getRoomId()); room?.off(ThreadEvent.New, this.onNewThread); } }; @@ -457,7 +457,7 @@ export class UnwrappedEventTile extends React.Component * when we are at the sync stage */ if (!thread) { - const room = MatrixClientPeg.get().getRoom(this.props.mxEvent.getRoomId()); + const room = MatrixClientPeg.safeGet().getRoom(this.props.mxEvent.getRoomId()); thread = room?.findThreadForEvent(this.props.mxEvent) ?? undefined; } return thread ?? null; @@ -519,7 +519,7 @@ export class UnwrappedEventTile extends React.Component private onRoomReceipt = (ev: MatrixEvent, room: Room): void => { // ignore events for other rooms - const tileRoom = MatrixClientPeg.get().getRoom(this.props.mxEvent.getRoomId()); + const tileRoom = MatrixClientPeg.safeGet().getRoom(this.props.mxEvent.getRoomId()); if (room !== tileRoom) return; if (!this.shouldShowSentReceipt && !this.shouldShowSendingReceipt && !this.isListeningForReceipts) { @@ -531,7 +531,7 @@ export class UnwrappedEventTile extends React.Component this.forceUpdate(() => { // Per elsewhere in this file, we can remove the listener once we will have no further purpose for it. if (!this.shouldShowSentReceipt && !this.shouldShowSendingReceipt) { - MatrixClientPeg.get().removeListener(RoomEvent.Receipt, this.onRoomReceipt); + MatrixClientPeg.safeGet().removeListener(RoomEvent.Receipt, this.onRoomReceipt); this.isListeningForReceipts = false; } }); @@ -574,7 +574,7 @@ export class UnwrappedEventTile extends React.Component return; } - const encryptionInfo = MatrixClientPeg.get().getEventEncryptionInfo(mxEvent); + const encryptionInfo = MatrixClientPeg.safeGet().getEventEncryptionInfo(mxEvent); const senderId = mxEvent.getSender(); if (!senderId) { // something definitely wrong is going on here @@ -582,7 +582,7 @@ export class UnwrappedEventTile extends React.Component return; } - const userTrust = MatrixClientPeg.get().checkUserTrust(senderId); + const userTrust = MatrixClientPeg.safeGet().checkUserTrust(senderId); if (encryptionInfo.mismatchedSender) { // something definitely wrong is going on here @@ -601,7 +601,7 @@ export class UnwrappedEventTile extends React.Component const eventSenderTrust = senderId && encryptionInfo.sender && - (await MatrixClientPeg.get() + (await MatrixClientPeg.safeGet() .getCrypto() ?.getDeviceVerificationStatus(senderId, encryptionInfo.sender.deviceId)); @@ -686,7 +686,7 @@ export class UnwrappedEventTile extends React.Component if (this.context.timelineRenderingType === TimelineRenderingType.Notification) return false; if (this.context.timelineRenderingType === TimelineRenderingType.ThreadsList) return false; - const cli = MatrixClientPeg.get(); + const cli = MatrixClientPeg.safeGet(); const actions = cli.getPushActionsForEvent(this.props.mxEvent.replacingEvent() || this.props.mxEvent); // get the actions for the previous version of the event too if it is an edit const previousActions = this.props.mxEvent.replacingEvent() @@ -697,7 +697,7 @@ export class UnwrappedEventTile extends React.Component } // don't show self-highlights from another of our clients - if (this.props.mxEvent.getSender() === MatrixClientPeg.get().credentials.userId) { + if (this.props.mxEvent.getSender() === cli.credentials.userId) { return false; } @@ -754,7 +754,7 @@ export class UnwrappedEventTile extends React.Component } } - if (MatrixClientPeg.get().isRoomEncrypted(ev.getRoomId()!)) { + if (MatrixClientPeg.safeGet().isRoomEncrypted(ev.getRoomId()!)) { // else if room is encrypted // and event is being encrypted or is not_sent (Unknown Devices/Network Error) if (ev.status === EventStatus.ENCRYPTING) { @@ -904,7 +904,7 @@ export class UnwrappedEventTile extends React.Component noBubbleEvent, isSeeingThroughMessageHiddenForModeration, } = getEventDisplayInfo( - MatrixClientPeg.get(), + MatrixClientPeg.safeGet(), this.props.mxEvent, this.context.showHiddenEvents, this.shouldHideEvent(), @@ -1186,7 +1186,7 @@ export class UnwrappedEventTile extends React.Component } // Use `getSender()` because searched events might not have a proper `sender`. - const isOwnEvent = this.props.mxEvent?.getSender() === MatrixClientPeg.get().getUserId(); + const isOwnEvent = this.props.mxEvent?.getSender() === MatrixClientPeg.safeGet().getUserId(); switch (this.context.timelineRenderingType) { case TimelineRenderingType.Thread: { @@ -1242,7 +1242,7 @@ export class UnwrappedEventTile extends React.Component } case TimelineRenderingType.Notification: case TimelineRenderingType.ThreadsList: { - const room = MatrixClientPeg.get().getRoom(this.props.mxEvent.getRoomId()); + const room = MatrixClientPeg.safeGet().getRoom(this.props.mxEvent.getRoomId()); // tab-index=-1 to allow it to be focusable but do not add tab stop for it, primarily for screen readers return React.createElement( this.props.as || "li", diff --git a/src/components/views/rooms/MemberList.tsx b/src/components/views/rooms/MemberList.tsx index d064bdfe3d..e8e0403fa0 100644 --- a/src/components/views/rooms/MemberList.tsx +++ b/src/components/views/rooms/MemberList.tsx @@ -84,7 +84,7 @@ export default class MemberList extends React.Component { } private listenForMembersChanges(): void { - const cli = MatrixClientPeg.get(); + const cli = MatrixClientPeg.safeGet(); cli.on(RoomStateEvent.Update, this.onRoomStateUpdate); cli.on(RoomMemberEvent.Name, this.onRoomMemberName); cli.on(RoomStateEvent.Events, this.onRoomStateEvent); @@ -121,7 +121,7 @@ export default class MemberList extends React.Component { } private get canInvite(): boolean { - const cli = MatrixClientPeg.get(); + const cli = MatrixClientPeg.safeGet(); const room = cli.getRoom(this.props.roomId); return ( @@ -284,7 +284,7 @@ export default class MemberList extends React.Component { // The HS may have already converted these into m.room.member invites so // we shouldn't add them if the 3pid invite state key (token) is in the // member invite (content.third_party_invite.signed.token) - const room = MatrixClientPeg.get().getRoom(this.props.roomId); + const room = MatrixClientPeg.safeGet().getRoom(this.props.roomId); if (room) { return room.currentState.getStateEvents("m.room.third_party_invite").filter(function (e) { @@ -348,7 +348,7 @@ export default class MemberList extends React.Component { ); } - const cli = MatrixClientPeg.get(); + const cli = MatrixClientPeg.safeGet(); const room = cli.getRoom(this.props.roomId); let inviteButton: JSX.Element | undefined; @@ -442,7 +442,7 @@ export default class MemberList extends React.Component { private onInviteButtonClick = (ev: ButtonEvent): void => { PosthogTrackers.trackInteraction("WebRightPanelMemberListInviteButton", ev); - if (MatrixClientPeg.get().isGuest()) { + if (MatrixClientPeg.safeGet().isGuest()) { dis.dispatch({ action: "require_registration" }); return; } diff --git a/src/components/views/rooms/MemberTile.tsx b/src/components/views/rooms/MemberTile.tsx index f8f891a486..e5dd30a302 100644 --- a/src/components/views/rooms/MemberTile.tsx +++ b/src/components/views/rooms/MemberTile.tsx @@ -62,7 +62,7 @@ export default class MemberTile extends React.Component { } public componentDidMount(): void { - const cli = MatrixClientPeg.get(); + const cli = MatrixClientPeg.safeGet(); const { roomId } = this.props.member; if (roomId) { @@ -97,7 +97,7 @@ export default class MemberTile extends React.Component { if (ev.getRoomId() !== roomId) return; // The room is encrypted now. - const cli = MatrixClientPeg.get(); + const cli = MatrixClientPeg.safeGet(); cli.removeListener(RoomStateEvent.Events, this.onRoomStateEvents); this.setState({ isRoomEncrypted: true, @@ -116,7 +116,7 @@ export default class MemberTile extends React.Component { }; private async updateE2EStatus(): Promise { - const cli = MatrixClientPeg.get(); + const cli = MatrixClientPeg.safeGet(); const { userId } = this.props.member; const isMe = userId === cli.getUserId(); const userTrust = cli.checkUserTrust(userId); diff --git a/src/components/views/rooms/MessageComposer.tsx b/src/components/views/rooms/MessageComposer.tsx index 55742d8c7e..1c3167214f 100644 --- a/src/components/views/rooms/MessageComposer.tsx +++ b/src/components/views/rooms/MessageComposer.tsx @@ -243,7 +243,7 @@ export class MessageComposer extends React.Component { private waitForOwnMember(): void { // If we have the member already, do that - const me = this.props.room.getMember(MatrixClientPeg.get().getUserId()!); + const me = this.props.room.getMember(MatrixClientPeg.safeGet().getUserId()!); if (me) { this.setState({ me }); return; @@ -252,7 +252,7 @@ export class MessageComposer extends React.Component { // The members should already be loading, and loadMembersIfNeeded // will return the promise for the existing operation this.props.room.loadMembersIfNeeded().then(() => { - const me = this.props.room.getMember(MatrixClientPeg.get().getSafeUserId()) ?? undefined; + const me = this.props.room.getMember(MatrixClientPeg.safeGet().getSafeUserId()) ?? undefined; this.setState({ me }); }); } @@ -271,7 +271,7 @@ export class MessageComposer extends React.Component { ev.preventDefault(); const replacementRoomId = this.context.tombstone?.getContent()["replacement_room"]; - const replacementRoom = MatrixClientPeg.get().getRoom(replacementRoomId); + const replacementRoom = MatrixClientPeg.safeGet().getRoom(replacementRoomId); let createEventId: string | undefined; if (replacementRoom) { const createEvent = replacementRoom.currentState.getStateEvents(EventType.RoomCreate, ""); @@ -527,7 +527,7 @@ export class MessageComposer extends React.Component { const continuesLink = replacementRoomId ? ( @@ -636,7 +636,7 @@ export class MessageComposer extends React.Component { onStartVoiceBroadcastClick={() => { setUpVoiceBroadcastPreRecording( this.props.room, - MatrixClientPeg.get(), + MatrixClientPeg.safeGet(), SdkContextClass.instance.voiceBroadcastPlaybacksStore, SdkContextClass.instance.voiceBroadcastRecordingsStore, SdkContextClass.instance.voiceBroadcastPreRecordingStore, diff --git a/src/components/views/rooms/MessageComposerButtons.tsx b/src/components/views/rooms/MessageComposerButtons.tsx index dc95b5044e..864809b541 100644 --- a/src/components/views/rooms/MessageComposerButtons.tsx +++ b/src/components/views/rooms/MessageComposerButtons.tsx @@ -309,7 +309,7 @@ class PollButton extends React.PureComponent { this.context?.(); // close overflow menu const canSend = this.props.room.currentState.maySendEvent( M_POLL_START.name, - MatrixClientPeg.get().getUserId()!, + MatrixClientPeg.safeGet().getSafeUserId(), ); if (!canSend) { Modal.createDialog(ErrorDialog, { diff --git a/src/components/views/rooms/NewRoomIntro.tsx b/src/components/views/rooms/NewRoomIntro.tsx index b1186a6d45..84cb408c8a 100644 --- a/src/components/views/rooms/NewRoomIntro.tsx +++ b/src/components/views/rooms/NewRoomIntro.tsx @@ -278,8 +278,11 @@ const NewRoomIntro: React.FC = () => { "like email invites.", ); - let subButton; - if (room.currentState.mayClientSendStateEvent(EventType.RoomEncryption, MatrixClientPeg.get()) && !isLocalRoom) { + let subButton: JSX.Element | undefined; + if ( + room.currentState.mayClientSendStateEvent(EventType.RoomEncryption, MatrixClientPeg.safeGet()) && + !isLocalRoom + ) { subButton = ( {_t("Enable encryption in settings.")} diff --git a/src/components/views/rooms/ReplyTile.tsx b/src/components/views/rooms/ReplyTile.tsx index 05997eb78b..7dacf2bfed 100644 --- a/src/components/views/rooms/ReplyTile.tsx +++ b/src/components/views/rooms/ReplyTile.tsx @@ -111,7 +111,7 @@ export default class ReplyTile extends React.PureComponent { const evType = mxEvent.getType(); const { hasRenderer, isInfoMessage, isSeeingThroughMessageHiddenForModeration } = getEventDisplayInfo( - MatrixClientPeg.get(), + MatrixClientPeg.safeGet(), mxEvent, false /* Replies are never hidden, so this should be fine */, ); diff --git a/src/components/views/rooms/RoomList.tsx b/src/components/views/rooms/RoomList.tsx index 06396de03c..8c0d797df6 100644 --- a/src/components/views/rooms/RoomList.tsx +++ b/src/components/views/rooms/RoomList.tsx @@ -222,7 +222,7 @@ const UntaggedAuxButton: React.FC = ({ tabIndex }) => { if (menuDisplayed && activeSpace) { const canAddRooms = activeSpace.currentState.maySendStateEvent( EventType.SpaceChild, - MatrixClientPeg.get().getUserId()!, + MatrixClientPeg.safeGet().getSafeUserId(), ); contextMenuContent = ( diff --git a/src/components/views/rooms/RoomPreviewBar.tsx b/src/components/views/rooms/RoomPreviewBar.tsx index a4b419949e..96cbaa9917 100644 --- a/src/components/views/rooms/RoomPreviewBar.tsx +++ b/src/components/views/rooms/RoomPreviewBar.tsx @@ -136,19 +136,19 @@ export default class RoomPreviewBar extends React.Component { this.setState({ busy: true }); try { // Gather the account 3PIDs - const account3pids = await MatrixClientPeg.get().getThreePids(); + const account3pids = await MatrixClientPeg.safeGet().getThreePids(); this.setState({ accountEmails: account3pids.threepids.filter((b) => b.medium === "email").map((b) => b.address), }); // If we have an IS connected, use that to lookup the email and // check the bound MXID. - if (!MatrixClientPeg.get().getIdentityServerUrl()) { + if (!MatrixClientPeg.safeGet().getIdentityServerUrl()) { this.setState({ busy: false }); return; } const authClient = new IdentityAuthClient(); const identityAccessToken = await authClient.getAccessToken(); - const result = await MatrixClientPeg.get().lookupThreePid( + const result = await MatrixClientPeg.safeGet().lookupThreePid( "email", this.props.invitedEmail, identityAccessToken!, @@ -162,7 +162,7 @@ export default class RoomPreviewBar extends React.Component { } private getMessageCase(): MessageCase { - const isGuest = MatrixClientPeg.get().isGuest(); + const isGuest = MatrixClientPeg.safeGet().isGuest(); if (isGuest) { return MessageCase.NotLoggedIn; @@ -192,9 +192,9 @@ export default class RoomPreviewBar extends React.Component { return MessageCase.OtherThreePIDError; } else if (this.state.accountEmails && !this.state.accountEmails.includes(this.props.invitedEmail)) { return MessageCase.InvitedEmailNotFoundInAccount; - } else if (!MatrixClientPeg.get().getIdentityServerUrl()) { + } else if (!MatrixClientPeg.safeGet().getIdentityServerUrl()) { return MessageCase.InvitedEmailNoIdentityServer; - } else if (this.state.invitedEmailMxid != MatrixClientPeg.get().getUserId()) { + } else if (this.state.invitedEmailMxid != MatrixClientPeg.safeGet().getUserId()) { return MessageCase.InvitedEmailMismatch; } } @@ -232,7 +232,7 @@ export default class RoomPreviewBar extends React.Component { } private getMyMember(): RoomMember | null { - return this.props.room?.getMember(MatrixClientPeg.get().getUserId()!) ?? null; + return this.props.room?.getMember(MatrixClientPeg.safeGet().getSafeUserId()) ?? null; } private getInviteMember(): RoomMember | null { @@ -240,7 +240,7 @@ export default class RoomPreviewBar extends React.Component { if (!room) { return null; } - const myUserId = MatrixClientPeg.get().getUserId()!; + const myUserId = MatrixClientPeg.safeGet().getSafeUserId(); const inviteEvent = room.currentState.getMember(myUserId); if (!inviteEvent) { return null; @@ -504,7 +504,7 @@ export default class RoomPreviewBar extends React.Component { primaryActionLabel = _t("Accept"); } - const myUserId = MatrixClientPeg.get().getUserId()!; + const myUserId = MatrixClientPeg.safeGet().getSafeUserId(); const member = this.props.room?.currentState.getMember(myUserId); const memberEventContent = member?.events.member?.getContent(); diff --git a/src/components/views/rooms/RoomTile.tsx b/src/components/views/rooms/RoomTile.tsx index d070c2a59d..76f8154c7c 100644 --- a/src/components/views/rooms/RoomTile.tsx +++ b/src/components/views/rooms/RoomTile.tsx @@ -285,7 +285,7 @@ export class RoomTile extends React.PureComponent { private renderNotificationsMenu(isActive: boolean): React.ReactElement | null { if ( - MatrixClientPeg.get().isGuest() || + MatrixClientPeg.safeGet().isGuest() || this.props.tag === DefaultTagID.Archived || !this.showContextMenu || this.props.isMinimized diff --git a/src/components/views/rooms/SendMessageComposer.tsx b/src/components/views/rooms/SendMessageComposer.tsx index 263e7d1329..ed2e022b38 100644 --- a/src/components/views/rooms/SendMessageComposer.tsx +++ b/src/components/views/rooms/SendMessageComposer.tsx @@ -336,7 +336,7 @@ export class SendMessageComposer extends React.Component { this.dispatcherRef = dis.register(this.onAction); // Track updates to widget state in account data - MatrixClientPeg.get().on(ClientEvent.AccountData, this.updateWidget); + MatrixClientPeg.safeGet().on(ClientEvent.AccountData, this.updateWidget); RightPanelStore.instance.on(UPDATE_EVENT, this.onRightPanelStoreUpdate); // Initialise widget state from current account data @@ -291,8 +291,10 @@ export default class Stickerpicker extends React.PureComponent { room={this.props.room} threadId={this.props.threadId} fullWidth={true} - userId={MatrixClientPeg.get().credentials.userId!} - creatorUserId={stickerpickerWidget.sender || MatrixClientPeg.get().credentials.userId!} + userId={MatrixClientPeg.safeGet().credentials.userId!} + creatorUserId={ + stickerpickerWidget.sender || MatrixClientPeg.safeGet().credentials.userId! + } waitForIframeLoad={true} showMenubar={true} onEditClick={this.launchManageIntegrations} diff --git a/src/components/views/rooms/ThirdPartyMemberInfo.tsx b/src/components/views/rooms/ThirdPartyMemberInfo.tsx index 3a17f62eee..9f3fb1e5d3 100644 --- a/src/components/views/rooms/ThirdPartyMemberInfo.tsx +++ b/src/components/views/rooms/ThirdPartyMemberInfo.tsx @@ -50,8 +50,8 @@ export default class ThirdPartyMemberInfo extends React.Component { - MatrixClientPeg.get() + MatrixClientPeg.safeGet() .sendStateEvent(this.state.roomId, "m.room.third_party_invite", {}, this.state.stateKey) .catch((err) => { logger.error(err); diff --git a/src/components/views/rooms/VoiceRecordComposerTile.tsx b/src/components/views/rooms/VoiceRecordComposerTile.tsx index fb90e17609..6e0589868a 100644 --- a/src/components/views/rooms/VoiceRecordComposerTile.tsx +++ b/src/components/views/rooms/VoiceRecordComposerTile.tsx @@ -130,7 +130,7 @@ export default class VoiceRecordComposerTile extends React.PureComponent MatrixClientPeg.get().sendMessage(actualRoomId, content), + (actualRoomId: string) => MatrixClientPeg.safeGet().sendMessage(actualRoomId, content), this.props.room.client, ); } catch (e) { diff --git a/src/components/views/rooms/WhoIsTypingTile.tsx b/src/components/views/rooms/WhoIsTypingTile.tsx index 5552fc5c69..a478204eda 100644 --- a/src/components/views/rooms/WhoIsTypingTile.tsx +++ b/src/components/views/rooms/WhoIsTypingTile.tsx @@ -57,8 +57,8 @@ export default class WhoIsTypingTile extends React.Component { }; public componentDidMount(): void { - MatrixClientPeg.get().on(RoomMemberEvent.Typing, this.onRoomMemberTyping); - MatrixClientPeg.get().on(RoomEvent.Timeline, this.onRoomTimeline); + MatrixClientPeg.safeGet().on(RoomMemberEvent.Typing, this.onRoomMemberTyping); + MatrixClientPeg.safeGet().on(RoomEvent.Timeline, this.onRoomTimeline); } public componentDidUpdate(prevProps: IProps, prevState: IState): void { diff --git a/src/components/views/settings/ChangeDisplayName.tsx b/src/components/views/settings/ChangeDisplayName.tsx index 696384ef67..3add2d2b4c 100644 --- a/src/components/views/settings/ChangeDisplayName.tsx +++ b/src/components/views/settings/ChangeDisplayName.tsx @@ -22,7 +22,7 @@ import EditableTextContainer from "../elements/EditableTextContainer"; export default class ChangeDisplayName extends React.Component { private getDisplayName = async (): Promise => { - const cli = MatrixClientPeg.get(); + const cli = MatrixClientPeg.safeGet(); try { const res = await cli.getProfileInfo(cli.getUserId()!); return res.displayname ?? ""; @@ -32,7 +32,7 @@ export default class ChangeDisplayName extends React.Component { }; private changeDisplayName = (newDisplayname: string): Promise<{}> => { - const cli = MatrixClientPeg.get(); + const cli = MatrixClientPeg.safeGet(); return cli.setDisplayName(newDisplayname).catch(function () { throw new Error("Failed to set display name"); }); diff --git a/src/components/views/settings/ChangePassword.tsx b/src/components/views/settings/ChangePassword.tsx index 69e30948b4..4c3f51eda8 100644 --- a/src/components/views/settings/ChangePassword.tsx +++ b/src/components/views/settings/ChangePassword.tsx @@ -93,7 +93,7 @@ export default class ChangePassword extends React.Component { } private async onChangePassword(oldPassword: string, newPassword: string): Promise { - const cli = MatrixClientPeg.get(); + const cli = MatrixClientPeg.safeGet(); // if the server supports it then don't sign user out of all devices const serverSupportsControlOfDevicesLogout = await cli.doesServerSupportLogoutDevices(); @@ -235,7 +235,7 @@ export default class ChangePassword extends React.Component { typeof ExportE2eKeysDialog >, { - matrixClient: MatrixClientPeg.get(), + matrixClient: MatrixClientPeg.safeGet(), }, ); }; diff --git a/src/components/views/settings/CryptographyPanel.tsx b/src/components/views/settings/CryptographyPanel.tsx index d947946b75..5a5e424abe 100644 --- a/src/components/views/settings/CryptographyPanel.tsx +++ b/src/components/views/settings/CryptographyPanel.tsx @@ -38,7 +38,7 @@ export default class CryptographyPanel extends React.Component { } public render(): React.ReactNode { - const client = MatrixClientPeg.get(); + const client = MatrixClientPeg.safeGet(); const deviceId = client.deviceId; let identityKey = client.getDeviceEd25519Key(); if (!identityKey) { @@ -103,7 +103,7 @@ export default class CryptographyPanel extends React.Component { import("../../../async-components/views/dialogs/security/ExportE2eKeysDialog") as unknown as Promise< typeof ExportE2eKeysDialog >, - { matrixClient: MatrixClientPeg.get() }, + { matrixClient: MatrixClientPeg.safeGet() }, ); }; @@ -112,11 +112,11 @@ export default class CryptographyPanel extends React.Component { import("../../../async-components/views/dialogs/security/ImportE2eKeysDialog") as unknown as Promise< typeof ImportE2eKeysDialog >, - { matrixClient: MatrixClientPeg.get() }, + { matrixClient: MatrixClientPeg.safeGet() }, ); }; private updateBlacklistDevicesFlag = (checked: boolean): void => { - MatrixClientPeg.get().setGlobalBlacklistUnverifiedDevices(checked); + MatrixClientPeg.safeGet().setGlobalBlacklistUnverifiedDevices(checked); }; } diff --git a/src/components/views/settings/FontScalingPanel.tsx b/src/components/views/settings/FontScalingPanel.tsx index cfede4d14c..04a511f82f 100644 --- a/src/components/views/settings/FontScalingPanel.tsx +++ b/src/components/views/settings/FontScalingPanel.tsx @@ -62,8 +62,8 @@ export default class FontScalingPanel extends React.Component { public async componentDidMount(): Promise { // Fetch the current user profile for the message preview - const client = MatrixClientPeg.get(); - const userId = client.getUserId()!; + const client = MatrixClientPeg.safeGet(); + const userId = client.getSafeUserId(); const profileInfo = await client.getProfileInfo(userId); if (this.unmounted) return; diff --git a/src/components/views/settings/Notifications.tsx b/src/components/views/settings/Notifications.tsx index 18d5c34c10..61ff474fa0 100644 --- a/src/components/views/settings/Notifications.tsx +++ b/src/components/views/settings/Notifications.tsx @@ -270,7 +270,7 @@ export default class Notifications extends React.PureComponent { } private async refreshFromAccountData(): Promise { - const cli = MatrixClientPeg.get(); + const cli = MatrixClientPeg.safeGet(); const settingsEvent = cli.getAccountData(getLocalNotificationAccountDataEventType(cli.deviceId)); if (settingsEvent) { const notificationsEnabled = !(settingsEvent.getContent() as LocalNotificationSettings).is_silenced; @@ -279,14 +279,14 @@ export default class Notifications extends React.PureComponent { } private persistLocalNotificationSettings(enabled: boolean): Promise<{}> { - const cli = MatrixClientPeg.get(); + const cli = MatrixClientPeg.safeGet(); return cli.setAccountData(getLocalNotificationAccountDataEventType(cli.deviceId), { is_silenced: !enabled, }); } private async refreshRules(): Promise> { - const ruleSets = await MatrixClientPeg.get().getPushRules()!; + const ruleSets = await MatrixClientPeg.safeGet().getPushRules()!; const categories: Record = { [RuleId.Master]: RuleClass.Master, @@ -384,11 +384,11 @@ export default class Notifications extends React.PureComponent { } private refreshPushers(): Promise> { - return MatrixClientPeg.get().getPushers(); + return MatrixClientPeg.safeGet().getPushers(); } private refreshThreepids(): Promise> { - return MatrixClientPeg.get().getThreePids(); + return MatrixClientPeg.safeGet().getThreePids(); } private showSaveError(): void { @@ -403,7 +403,7 @@ export default class Notifications extends React.PureComponent { const masterRule = this.state.masterPushRule!; try { - await MatrixClientPeg.get().setPushRuleEnabled("global", masterRule.kind, masterRule.rule_id, !checked); + await MatrixClientPeg.safeGet().setPushRuleEnabled("global", masterRule.kind, masterRule.rule_id, !checked); await this.refreshFromServer(); } catch (e) { this.setState({ phase: Phase.Error }); @@ -428,7 +428,7 @@ export default class Notifications extends React.PureComponent { try { if (checked) { - await MatrixClientPeg.get().setPusher({ + await MatrixClientPeg.safeGet().setPusher({ kind: "email", app_id: "m.email", pushkey: email, @@ -446,7 +446,7 @@ export default class Notifications extends React.PureComponent { } else { const pusher = this.state.pushers?.find((p) => p.kind === "email" && p.pushkey === email); if (pusher) { - await MatrixClientPeg.get().removePusher(pusher.pushkey, pusher.app_id); + await MatrixClientPeg.safeGet().removePusher(pusher.pushkey, pusher.app_id); } } @@ -477,7 +477,7 @@ export default class Notifications extends React.PureComponent { })); try { - const cli = MatrixClientPeg.get(); + const cli = MatrixClientPeg.safeGet(); if (rule.ruleId === KEYWORD_RULE_ID) { // should not encounter this if (!this.state.vectorKeywordRuleInfo) { @@ -536,7 +536,7 @@ export default class Notifications extends React.PureComponent { private onClearNotificationsClicked = async (): Promise => { try { this.setState({ clearingNotifications: true }); - const client = MatrixClientPeg.get(); + const client = MatrixClientPeg.safeGet(); await clearAllNotifications(client); } finally { this.setState({ clearingNotifications: false }); @@ -560,7 +560,7 @@ export default class Notifications extends React.PureComponent { for (const word of diff.removed) { for (const rule of originalRules.filter((r) => r.pattern === word)) { - await MatrixClientPeg.get().deletePushRule("global", rule.kind, rule.rule_id); + await MatrixClientPeg.safeGet().deletePushRule("global", rule.kind, rule.rule_id); } } @@ -577,12 +577,12 @@ export default class Notifications extends React.PureComponent { } const kind = PushRuleKind.ContentSpecific; for (const word of diff.added) { - await MatrixClientPeg.get().addPushRule("global", kind, word, { + await MatrixClientPeg.safeGet().addPushRule("global", kind, word, { actions: PushRuleVectorState.actionsFor(ruleVectorState), pattern: word, }); if (ruleVectorState === VectorState.Off) { - await MatrixClientPeg.get().setPushRuleEnabled("global", kind, word, false); + await MatrixClientPeg.safeGet().setPushRuleEnabled("global", kind, word, false); } } @@ -730,7 +730,7 @@ export default class Notifications extends React.PureComponent { let clearNotifsButton: JSX.Element | undefined; if ( category === RuleClass.VectorOther && - MatrixClientPeg.get() + MatrixClientPeg.safeGet() .getRooms() .some((r) => r.getUnreadNotificationCount() > 0) ) { diff --git a/src/components/views/settings/ProfileSettings.tsx b/src/components/views/settings/ProfileSettings.tsx index 529bb86a78..f277872c86 100644 --- a/src/components/views/settings/ProfileSettings.tsx +++ b/src/components/views/settings/ProfileSettings.tsx @@ -47,7 +47,7 @@ export default class ProfileSettings extends React.Component<{}, IState> { public constructor(props: {}) { super(props); - this.userId = MatrixClientPeg.get().getSafeUserId(); + this.userId = MatrixClientPeg.safeGet().getSafeUserId(); let avatarUrl = OwnProfileStore.instance.avatarMxc; if (avatarUrl) avatarUrl = mediaFromMxc(avatarUrl).getSquareThumbnailHttp(96); this.state = { @@ -96,11 +96,11 @@ export default class ProfileSettings extends React.Component<{}, IState> { if (!this.state.enableProfileSave) return; this.setState({ enableProfileSave: false }); - const client = MatrixClientPeg.get(); const newState: Partial = {}; const displayName = this.state.displayName.trim(); try { + const client = MatrixClientPeg.safeGet(); if (this.state.originalDisplayName !== this.state.displayName) { await client.setDisplayName(displayName); newState.originalDisplayName = displayName; diff --git a/src/components/views/settings/SecureBackupPanel.tsx b/src/components/views/settings/SecureBackupPanel.tsx index 7f988d8d41..aabb1cb90c 100644 --- a/src/components/views/settings/SecureBackupPanel.tsx +++ b/src/components/views/settings/SecureBackupPanel.tsx @@ -69,16 +69,16 @@ export default class SecureBackupPanel extends React.PureComponent<{}, IState> { public componentDidMount(): void { this.checkKeyBackupStatus(); - MatrixClientPeg.get().on(CryptoEvent.KeyBackupStatus, this.onKeyBackupStatus); - MatrixClientPeg.get().on(CryptoEvent.KeyBackupSessionsRemaining, this.onKeyBackupSessionsRemaining); + MatrixClientPeg.safeGet().on(CryptoEvent.KeyBackupStatus, this.onKeyBackupStatus); + MatrixClientPeg.safeGet().on(CryptoEvent.KeyBackupSessionsRemaining, this.onKeyBackupSessionsRemaining); } public componentWillUnmount(): void { this.unmounted = true; if (MatrixClientPeg.get()) { - MatrixClientPeg.get().removeListener(CryptoEvent.KeyBackupStatus, this.onKeyBackupStatus); - MatrixClientPeg.get().removeListener( + MatrixClientPeg.get()!.removeListener(CryptoEvent.KeyBackupStatus, this.onKeyBackupStatus); + MatrixClientPeg.get()!.removeListener( CryptoEvent.KeyBackupSessionsRemaining, this.onKeyBackupSessionsRemaining, ); @@ -100,7 +100,7 @@ export default class SecureBackupPanel extends React.PureComponent<{}, IState> { private async checkKeyBackupStatus(): Promise { this.getUpdatedDiagnostics(); try { - const keyBackupResult = await MatrixClientPeg.get().checkKeyBackup(); + const keyBackupResult = await MatrixClientPeg.safeGet().checkKeyBackup(); this.setState({ loading: false, error: null, @@ -123,8 +123,8 @@ export default class SecureBackupPanel extends React.PureComponent<{}, IState> { this.setState({ loading: true }); this.getUpdatedDiagnostics(); try { - const backupInfo = await MatrixClientPeg.get().getKeyBackupVersion(); - const backupSigStatus = backupInfo ? await MatrixClientPeg.get().isKeyBackupTrusted(backupInfo) : null; + const backupInfo = await MatrixClientPeg.safeGet().getKeyBackupVersion(); + const backupSigStatus = backupInfo ? await MatrixClientPeg.safeGet().isKeyBackupTrusted(backupInfo) : null; if (this.unmounted) return; this.setState({ loading: false, @@ -145,7 +145,7 @@ export default class SecureBackupPanel extends React.PureComponent<{}, IState> { } private async getUpdatedDiagnostics(): Promise { - const cli = MatrixClientPeg.get(); + const cli = MatrixClientPeg.safeGet(); const crypto = cli.crypto; if (!crypto) return; @@ -195,7 +195,7 @@ export default class SecureBackupPanel extends React.PureComponent<{}, IState> { onFinished: (proceed) => { if (!proceed) return; this.setState({ loading: true }); - MatrixClientPeg.get() + MatrixClientPeg.safeGet() .deleteKeyBackupVersion(this.state.backupInfo!.version!) .then(() => { this.loadBackupStatus(); @@ -246,7 +246,7 @@ export default class SecureBackupPanel extends React.PureComponent<{}, IState> { } else if (backupInfo) { let restoreButtonCaption = _t("Restore from Backup"); - if (MatrixClientPeg.get().getKeyBackupEnabled()) { + if (MatrixClientPeg.safeGet().getKeyBackupEnabled()) { statusDescription =

✅ {_t("This session is backing up your keys.")}

; } else { statusDescription = ( @@ -272,7 +272,7 @@ export default class SecureBackupPanel extends React.PureComponent<{}, IState> { } let uploadStatus: ReactNode; - if (!MatrixClientPeg.get().getKeyBackupEnabled()) { + if (!MatrixClientPeg.safeGet().getKeyBackupEnabled()) { // No upload status to show when backup disabled. uploadStatus = ""; } else if (sessionsRemaining > 0) { @@ -311,8 +311,9 @@ export default class SecureBackupPanel extends React.PureComponent<{}, IState> { {deviceName} ); const fromThisDevice = - sig.device && sig.device.getFingerprint() === MatrixClientPeg.get().getDeviceEd25519Key(); - const fromThisUser = sig.crossSigningId && sig.deviceId === MatrixClientPeg.get().getCrossSigningId(); + sig.device && sig.device.getFingerprint() === MatrixClientPeg.safeGet().getDeviceEd25519Key(); + const fromThisUser = + sig.crossSigningId && sig.deviceId === MatrixClientPeg.safeGet().getCrossSigningId(); let sigStatus; if (sig.valid && fromThisUser) { sigStatus = _t( @@ -419,7 +420,7 @@ export default class SecureBackupPanel extends React.PureComponent<{}, IState> {
, ); - if (!isSecureBackupRequired(MatrixClientPeg.get())) { + if (!isSecureBackupRequired(MatrixClientPeg.safeGet())) { actions.push( {_t("Delete Backup")} diff --git a/src/components/views/settings/SetIdServer.tsx b/src/components/views/settings/SetIdServer.tsx index df2f992601..2256556b58 100644 --- a/src/components/views/settings/SetIdServer.tsx +++ b/src/components/views/settings/SetIdServer.tsx @@ -88,7 +88,7 @@ export default class SetIdServer extends React.Component { super(props); let defaultIdServer = ""; - if (!MatrixClientPeg.get().getIdentityServerUrl() && getDefaultIdentityServerUrl()) { + if (!MatrixClientPeg.safeGet().getIdentityServerUrl() && getDefaultIdentityServerUrl()) { // If no identity server is configured but there's one in the config, prepopulate // the field to help the user. defaultIdServer = abbreviateUrl(getDefaultIdentityServerUrl()); @@ -96,7 +96,7 @@ export default class SetIdServer extends React.Component { this.state = { defaultIdServer, - currentClientIdServer: MatrixClientPeg.get().getIdentityServerUrl(), + currentClientIdServer: MatrixClientPeg.safeGet().getIdentityServerUrl(), idServer: "", busy: false, disconnectBusy: false, @@ -118,7 +118,7 @@ export default class SetIdServer extends React.Component { if (payload.action !== "id_server_changed") return; this.setState({ - currentClientIdServer: MatrixClientPeg.get().getIdentityServerUrl(), + currentClientIdServer: MatrixClientPeg.safeGet().getIdentityServerUrl(), }); }; @@ -149,7 +149,7 @@ export default class SetIdServer extends React.Component { private saveIdServer = (fullUrl: string): void => { // Account data change will update localstorage, client, etc through dispatcher - MatrixClientPeg.get().setAccountData("m.identity_server", { + MatrixClientPeg.safeGet().setAccountData("m.identity_server", { base_url: fullUrl, }); this.setState({ @@ -181,7 +181,7 @@ export default class SetIdServer extends React.Component { let save = true; // Double check that the identity server even has terms of service. - const hasTerms = await doesIdentityServerHaveTerms(MatrixClientPeg.get(), fullUrl); + const hasTerms = await doesIdentityServerHaveTerms(MatrixClientPeg.safeGet(), fullUrl); if (!hasTerms) { const [confirmed] = await this.showNoTermsWarning(fullUrl); save = !!confirmed; @@ -217,7 +217,7 @@ export default class SetIdServer extends React.Component { busy: false, checking: false, error: errStr ?? undefined, - currentClientIdServer: MatrixClientPeg.get().getIdentityServerUrl(), + currentClientIdServer: MatrixClientPeg.safeGet().getIdentityServerUrl(), }); }; @@ -272,7 +272,7 @@ export default class SetIdServer extends React.Component { let currentServerReachable = true; try { threepids = await timeout( - getThreepidsWithBindStatus(MatrixClientPeg.get()), + getThreepidsWithBindStatus(MatrixClientPeg.safeGet()), Promise.reject(new Error("Timeout attempting to reach identity server")), REACHABILITY_TIMEOUT, ); @@ -362,7 +362,7 @@ export default class SetIdServer extends React.Component { private disconnectIdServer = (): void => { // Account data change will update localstorage, client, etc through dispatcher - MatrixClientPeg.get().setAccountData("m.identity_server", { + MatrixClientPeg.safeGet().setAccountData("m.identity_server", { base_url: null, // clear }); @@ -376,7 +376,7 @@ export default class SetIdServer extends React.Component { this.setState({ busy: false, error: undefined, - currentClientIdServer: MatrixClientPeg.get().getIdentityServerUrl(), + currentClientIdServer: MatrixClientPeg.safeGet().getIdentityServerUrl(), idServer: newFieldVal, }); }; diff --git a/src/components/views/settings/account/EmailAddresses.tsx b/src/components/views/settings/account/EmailAddresses.tsx index f698b0b331..3d7fe2380e 100644 --- a/src/components/views/settings/account/EmailAddresses.tsx +++ b/src/components/views/settings/account/EmailAddresses.tsx @@ -77,7 +77,7 @@ export class ExistingEmailAddress extends React.Component { return this.props.onRemoved(this.props.email); @@ -181,7 +181,7 @@ export default class EmailAddresses extends React.Component { return; } - const task = new AddThreepid(MatrixClientPeg.get()); + const task = new AddThreepid(MatrixClientPeg.safeGet()); this.setState({ verifying: true, continueDisabled: true, addTask: task }); task.addEmailAddress(email) diff --git a/src/components/views/settings/account/PhoneNumbers.tsx b/src/components/views/settings/account/PhoneNumbers.tsx index ece9549d94..f7a4109ae7 100644 --- a/src/components/views/settings/account/PhoneNumbers.tsx +++ b/src/components/views/settings/account/PhoneNumbers.tsx @@ -72,7 +72,7 @@ export class ExistingPhoneNumber extends React.Component { return this.props.onRemoved(this.props.msisdn); @@ -182,7 +182,7 @@ export default class PhoneNumbers extends React.Component { const phoneNumber = this.state.newPhoneNumber; const phoneCountry = this.state.phoneCountry; - const task = new AddThreepid(MatrixClientPeg.get()); + const task = new AddThreepid(MatrixClientPeg.safeGet()); this.setState({ verifying: true, continueDisabled: true, addTask: task }); task.addMsisdn(phoneCountry, phoneNumber) diff --git a/src/components/views/settings/discovery/EmailAddresses.tsx b/src/components/views/settings/discovery/EmailAddresses.tsx index 1d1cac2d67..01b6480d73 100644 --- a/src/components/views/settings/discovery/EmailAddresses.tsx +++ b/src/components/views/settings/discovery/EmailAddresses.tsx @@ -78,7 +78,7 @@ export class EmailAddress extends React.Component { - if (!(await MatrixClientPeg.get().doesServerSupportSeparateAddAndBind())) { + if (!(await MatrixClientPeg.safeGet().doesServerSupportSeparateAddAndBind())) { return this.changeBindingTangledAddBind({ bind, label, errorTitle }); } @@ -86,7 +86,7 @@ export class EmailAddress extends React.Component { const { medium, address } = this.props.email; - const task = new AddThreepid(MatrixClientPeg.get()); + const task = new AddThreepid(MatrixClientPeg.safeGet()); this.setState({ verifying: true, continueDisabled: true, @@ -125,7 +125,7 @@ export class EmailAddress extends React.Component { - if (!(await MatrixClientPeg.get().doesServerSupportSeparateAddAndBind())) { + if (!(await MatrixClientPeg.safeGet().doesServerSupportSeparateAddAndBind())) { return this.changeBindingTangledAddBind({ bind, label, errorTitle }); } @@ -82,7 +82,7 @@ export class PhoneNumber extends React.Component { const { medium, address } = this.props.msisdn; - const task = new AddThreepid(MatrixClientPeg.get()); + const task = new AddThreepid(MatrixClientPeg.safeGet()); this.setState({ verifying: true, continueDisabled: true, @@ -126,7 +126,7 @@ export class PhoneNumber extends React.Component = ({ space, onFinished }) => { {_t("Share invite link")}
{copiedText}
- {space.canInvite(MatrixClientPeg.get()?.getSafeUserId()) && shouldShowComponent(UIComponent.InviteUsers) ? ( + {space.canInvite(MatrixClientPeg.safeGet().getSafeUserId()) && + shouldShowComponent(UIComponent.InviteUsers) ? ( { diff --git a/src/components/views/voip/LegacyCallView.tsx b/src/components/views/voip/LegacyCallView.tsx index aa0e24e735..4d90539708 100644 --- a/src/components/views/voip/LegacyCallView.tsx +++ b/src/components/views/voip/LegacyCallView.tsx @@ -432,7 +432,7 @@ export default class LegacyCallView extends React.Component { const { isLocalOnHold, isRemoteOnHold, sidebarShown, primaryFeed, secondaryFeed, sidebarFeeds } = this.state; const callRoomId = LegacyCallHandler.instance.roomIdForCall(call); - const callRoom = (callRoomId ? MatrixClientPeg.get().getRoom(callRoomId) : undefined) ?? undefined; + const callRoom = (callRoomId ? MatrixClientPeg.safeGet().getRoom(callRoomId) : undefined) ?? undefined; const avatarSize = pipMode ? 76 : 160; const transfereeCall = LegacyCallHandler.instance.getTransfereeForCallId(call.callId); const isOnHold = isLocalOnHold || isRemoteOnHold; @@ -452,7 +452,7 @@ export default class LegacyCallView extends React.Component { let holdTransferContent: React.ReactNode; if (transfereeCall) { - const cli = MatrixClientPeg.get(); + const cli = MatrixClientPeg.safeGet(); const callRoomId = LegacyCallHandler.instance.roomIdForCall(call); const transferTargetRoom = callRoomId ? cli.getRoom(callRoomId) : null; const transferTargetName = transferTargetRoom ? transferTargetRoom.name : _t("unknown person"); @@ -575,7 +575,7 @@ export default class LegacyCallView extends React.Component { const { call, secondaryCall, pipMode, showApps, onMouseDownOnHeader } = this.props; const { sidebarShown, sidebarFeeds } = this.state; - const client = MatrixClientPeg.get(); + const client = MatrixClientPeg.safeGet(); const callRoomId = LegacyCallHandler.instance.roomIdForCall(call); const secondaryCallRoomId = LegacyCallHandler.instance.roomIdForCall(secondaryCall); const callRoom = callRoomId ? client.getRoom(callRoomId) : null; diff --git a/src/components/views/voip/VideoFeed.tsx b/src/components/views/voip/VideoFeed.tsx index 87c0eeb7f0..9c4d25190e 100644 --- a/src/components/views/voip/VideoFeed.tsx +++ b/src/components/views/voip/VideoFeed.tsx @@ -200,7 +200,7 @@ export default class VideoFeed extends React.PureComponent { let content; if (this.state.videoMuted) { const callRoomId = LegacyCallHandler.instance.roomIdForCall(this.props.call); - const callRoom = (callRoomId ? MatrixClientPeg.get().getRoom(callRoomId) : undefined) ?? undefined; + const callRoom = (callRoomId ? MatrixClientPeg.safeGet().getRoom(callRoomId) : undefined) ?? undefined; let avatarSize; if (pipMode && primary) avatarSize = 76; diff --git a/test/components/views/messages/EncryptionEvent-test.tsx b/test/components/views/messages/EncryptionEvent-test.tsx index ebf084cdbc..75d11bdc9e 100644 --- a/test/components/views/messages/EncryptionEvent-test.tsx +++ b/test/components/views/messages/EncryptionEvent-test.tsx @@ -49,6 +49,7 @@ describe("EncryptionEvent", () => { jest.clearAllMocks(); client = createTestClient(); jest.spyOn(MatrixClientPeg, "get").mockReturnValue(client); + jest.spyOn(MatrixClientPeg, "safeGet").mockReturnValue(client); event = mkMessage({ event: true, room: roomId, diff --git a/test/components/views/right_panel/UserInfo-test.tsx b/test/components/views/right_panel/UserInfo-test.tsx index 95c0fff74c..66e75e4ab5 100644 --- a/test/components/views/right_panel/UserInfo-test.tsx +++ b/test/components/views/right_panel/UserInfo-test.tsx @@ -166,6 +166,7 @@ beforeEach(() => { } as unknown as MatrixClient); jest.spyOn(MatrixClientPeg, "get").mockReturnValue(mockClient); + jest.spyOn(MatrixClientPeg, "safeGet").mockReturnValue(mockClient); }); describe("", () => { diff --git a/test/components/views/rooms/RoomPreviewBar-test.tsx b/test/components/views/rooms/RoomPreviewBar-test.tsx index 0638ed31b6..e39c5fc6f6 100644 --- a/test/components/views/rooms/RoomPreviewBar-test.tsx +++ b/test/components/views/rooms/RoomPreviewBar-test.tsx @@ -18,7 +18,7 @@ import React, { ComponentProps } from "react"; import { render, fireEvent, RenderResult, waitFor } from "@testing-library/react"; import { Room, RoomMember, MatrixError, IContent } from "matrix-js-sdk/src/matrix"; -import { stubClient } from "../../../test-utils"; +import { withClientContextRenderOptions, stubClient } from "../../../test-utils"; import { MatrixClientPeg } from "../../../../src/MatrixClientPeg"; import DMRoomMap from "../../../../src/utils/DMRoomMap"; import RoomPreviewBar from "../../../../src/components/views/rooms/RoomPreviewBar"; @@ -77,7 +77,10 @@ describe("", () => { roomId, room: createRoom(roomId, userId), }; - return render(); + return render( + , + withClientContextRenderOptions(MatrixClientPeg.safeGet()), + ); }; const isSpinnerRendered = (wrapper: RenderResult) => !!wrapper.container.querySelector(".mx_Spinner"); @@ -92,7 +95,10 @@ describe("", () => { beforeEach(() => { stubClient(); + MatrixClientPeg.get().getUserId = jest.fn().mockReturnValue(userId); + MatrixClientPeg.get().getSafeUserId = jest.fn().mockReturnValue(userId); MatrixClientPeg.safeGet().getUserId = jest.fn().mockReturnValue(userId); + MatrixClientPeg.safeGet().getSafeUserId = jest.fn().mockReturnValue(userId); }); afterEach(() => { diff --git a/test/components/views/spaces/SpacePanel-test.tsx b/test/components/views/spaces/SpacePanel-test.tsx index fc798abbb2..e474c3f055 100644 --- a/test/components/views/spaces/SpacePanel-test.tsx +++ b/test/components/views/spaces/SpacePanel-test.tsx @@ -127,6 +127,7 @@ describe("", () => { beforeAll(() => { jest.spyOn(MatrixClientPeg, "get").mockReturnValue(mockClient); + jest.spyOn(MatrixClientPeg, "safeGet").mockReturnValue(mockClient); }); beforeEach(() => {