Prefer MatrixClientContext over MatrixClientPeg (#10986)

This commit is contained in:
Michael Telatynski 2023-06-14 13:42:07 +01:00 committed by GitHub
parent b40f29f04c
commit 9c48487d85
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 120 additions and 87 deletions

View file

@ -20,7 +20,6 @@ import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import { RoomMember } from "matrix-js-sdk/src/models/room-member";
import { MatrixClient } from "matrix-js-sdk/src/matrix";
import { MatrixClientPeg } from "../../MatrixClientPeg";
import Modal from "../../Modal";
import { _t } from "../../languageHandler";
import ErrorDialog from "../views/dialogs/ErrorDialog";
@ -30,6 +29,7 @@ import Spinner from "../views/elements/Spinner";
import ResizeNotifier from "../../utils/ResizeNotifier";
import { RightPanelPhases } from "../../stores/right-panel/RightPanelStorePhases";
import { UserOnboardingPage } from "../views/user-onboarding/UserOnboardingPage";
import MatrixClientContext from "../../contexts/MatrixClientContext";
interface IProps {
userId: string;
@ -42,6 +42,9 @@ interface IState {
}
export default class UserView extends React.Component<IProps, IState> {
public static contextType = MatrixClientContext;
public context!: React.ContextType<typeof MatrixClientContext>;
public constructor(props: IProps) {
super(props);
this.state = {
@ -65,11 +68,10 @@ export default class UserView extends React.Component<IProps, IState> {
}
private async loadProfileInfo(): Promise<void> {
const cli = MatrixClientPeg.get();
this.setState({ loading: true });
let profileInfo: Awaited<ReturnType<MatrixClient["getProfileInfo"]>>;
try {
profileInfo = await cli.getProfileInfo(this.props.userId);
profileInfo = await this.context.getProfileInfo(this.props.userId);
} catch (err) {
Modal.createDialog(ErrorDialog, {
title: _t("Could not load user profile"),

View file

@ -25,13 +25,13 @@ import { formatTime } from "../../../DateUtils";
import { pillifyLinks, unmountPills } from "../../../utils/pillify";
import { tooltipifyLinks, unmountTooltips } from "../../../utils/tooltipify";
import { _t } from "../../../languageHandler";
import { MatrixClientPeg } from "../../../MatrixClientPeg";
import Modal from "../../../Modal";
import RedactedBody from "./RedactedBody";
import AccessibleButton from "../elements/AccessibleButton";
import ConfirmAndWaitRedactDialog from "../dialogs/ConfirmAndWaitRedactDialog";
import ViewSource from "../../structures/ViewSource";
import SettingsStore from "../../../settings/SettingsStore";
import MatrixClientContext from "../../../contexts/MatrixClientContext";
function getReplacedContent(event: MatrixEvent): IContent {
const originalContent = event.getOriginalContent();
@ -52,14 +52,18 @@ interface IState {
}
export default class EditHistoryMessage extends React.PureComponent<IProps, IState> {
public static contextType = MatrixClientContext;
public context!: React.ContextType<typeof MatrixClientContext>;
private content = createRef<HTMLDivElement>();
private pills: Element[] = [];
private tooltips: Element[] = [];
public constructor(props: IProps) {
public constructor(props: IProps, context: React.ContextType<typeof MatrixClientContext>) {
super(props);
this.context = context;
const cli = MatrixClientPeg.get();
const cli = this.context;
const userId = cli.getSafeUserId();
const event = this.props.mxEvent;
const room = cli.getRoom(event.getRoomId());
@ -74,7 +78,7 @@ export default class EditHistoryMessage extends React.PureComponent<IProps, ISta
private onRedactClick = async (): Promise<void> => {
const event = this.props.mxEvent;
const cli = MatrixClientPeg.get();
const cli = this.context;
Modal.createDialog(
ConfirmAndWaitRedactDialog,
@ -102,7 +106,7 @@ export default class EditHistoryMessage extends React.PureComponent<IProps, ISta
private pillifyLinks(): void {
// not present for redacted events
if (this.content.current) {
pillifyLinks(MatrixClientPeg.get(), this.content.current.children, this.props.mxEvent, this.pills);
pillifyLinks(this.context, this.content.current.children, this.props.mxEvent, this.pills);
}
}

View file

@ -27,7 +27,6 @@ import { User } from "matrix-js-sdk/src/models/user";
import EncryptionInfo from "./EncryptionInfo";
import VerificationPanel from "./VerificationPanel";
import { MatrixClientPeg } from "../../../MatrixClientPeg";
import { ensureDMExists } from "../../../createRoom";
import { useTypedEventEmitter } from "../../../hooks/useEventEmitter";
import Modal from "../../../Modal";
@ -35,6 +34,7 @@ import { _t } from "../../../languageHandler";
import { RightPanelPhases } from "../../../stores/right-panel/RightPanelStorePhases";
import RightPanelStore from "../../../stores/right-panel/RightPanelStore";
import ErrorDialog from "../dialogs/ErrorDialog";
import { useMatrixClientContext } from "../../../contexts/MatrixClientContext";
// cancellation codes which constitute a key mismatch
const MISMATCHES = ["m.key_mismatch", "m.user_error", "m.mismatched_sas"];
@ -49,6 +49,7 @@ interface IProps {
}
const EncryptionPanel: React.FC<IProps> = (props: IProps) => {
const cli = useMatrixClientContext();
const { verificationRequest, verificationRequestPromise, member, onClose, layout, isRoomEncrypted } = props;
const [request, setRequest] = useState(verificationRequest);
// state to show a spinner immediately after clicking "start verification",
@ -106,7 +107,6 @@ const EncryptionPanel: React.FC<IProps> = (props: IProps) => {
const onStartVerification = useCallback(async (): Promise<void> => {
setRequesting(true);
const cli = MatrixClientPeg.get();
let verificationRequest_: VerificationRequest;
try {
const roomId = await ensureDMExists(cli, member.userId);
@ -135,14 +135,12 @@ const EncryptionPanel: React.FC<IProps> = (props: IProps) => {
});
}
if (!RightPanelStore.instance.isOpen) RightPanelStore.instance.togglePanel(null);
}, [member]);
}, [cli, member]);
const requested: boolean =
(!request && isRequesting) ||
(!!request && (phase === PHASE_REQUESTED || phase === PHASE_UNSENT || phase === undefined));
const isSelfVerification = request
? request.isSelfVerification
: member.userId === MatrixClientPeg.get().getUserId();
const isSelfVerification = request ? request.isSelfVerification : member.userId === cli.getUserId();
if (!request || requested) {
const initiatedByMe = (!request && isRequesting) || (!!request && request.initiatedByMe);

View file

@ -17,12 +17,13 @@ limitations under the License.
import React, { ReactNode } from "react";
import { Room } from "matrix-js-sdk/src/models/room";
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import { MatrixClient } from "matrix-js-sdk/src/matrix";
import { _t } from "../../../../../languageHandler";
import { MatrixClientPeg } from "../../../../../MatrixClientPeg";
import BridgeTile from "../../BridgeTile";
import SettingsTab from "../SettingsTab";
import { SettingsSection } from "../../shared/SettingsSection";
import MatrixClientContext from "../../../../../contexts/MatrixClientContext";
const BRIDGE_EVENT_TYPES = [
"uk.half-shot.bridge",
@ -36,14 +37,16 @@ interface IProps {
}
export default class BridgeSettingsTab extends React.Component<IProps> {
public static contextType = MatrixClientContext;
public context!: React.ContextType<typeof MatrixClientContext>;
private renderBridgeCard(event: MatrixEvent, room: Room | null): ReactNode {
const content = event.getContent();
if (!room || !content?.channel || !content.protocol) return null;
return <BridgeTile key={event.getId()} room={room} ev={event} />;
}
public static getBridgeStateEvents(roomId: string): MatrixEvent[] {
const client = MatrixClientPeg.get();
public static getBridgeStateEvents(client: MatrixClient, roomId: string): MatrixEvent[] {
const roomState = client.getRoom(roomId)?.currentState;
if (!roomState) return [];
@ -53,7 +56,7 @@ export default class BridgeSettingsTab extends React.Component<IProps> {
public render(): React.ReactNode {
// This settings tab will only be invoked if the following function returns more
// than 0 events, so no validation is needed at this stage.
const bridgeEvents = BridgeSettingsTab.getBridgeStateEvents(this.props.room.roomId);
const bridgeEvents = BridgeSettingsTab.getBridgeStateEvents(this.context, this.props.room.roomId);
const room = this.props.room;
let content: JSX.Element;

View file

@ -18,7 +18,6 @@ import React, { createRef } from "react";
import { logger } from "matrix-js-sdk/src/logger";
import { _t } from "../../../../../languageHandler";
import { MatrixClientPeg } from "../../../../../MatrixClientPeg";
import AccessibleButton, { ButtonEvent } from "../../../elements/AccessibleButton";
import Notifier from "../../../../../Notifier";
import SettingsStore from "../../../../../settings/SettingsStore";
@ -116,7 +115,7 @@ export default class NotificationsSettingsTab extends React.Component<IProps, IS
type = "audio/ogg";
}
const { content_uri: url } = await MatrixClientPeg.get().uploadContent(this.state.uploadedFile, {
const { content_uri: url } = await this.context.uploadContent(this.state.uploadedFile, {
type,
});

View file

@ -25,7 +25,6 @@ import { IContent } from "matrix-js-sdk/src/models/event";
import { Room } from "matrix-js-sdk/src/matrix";
import { _t, _td } from "../../../../../languageHandler";
import { MatrixClientPeg } from "../../../../../MatrixClientPeg";
import AccessibleButton from "../../../elements/AccessibleButton";
import Modal from "../../../../../Modal";
import ErrorDialog from "../../../dialogs/ErrorDialog";
@ -38,6 +37,7 @@ import SdkConfig, { DEFAULTS } from "../../../../../SdkConfig";
import { AddPrivilegedUsers } from "../../AddPrivilegedUsers";
import SettingsTab from "../SettingsTab";
import { SettingsSection } from "../../shared/SettingsSection";
import MatrixClientContext from "../../../../../contexts/MatrixClientContext";
interface IEventShowOpts {
isState?: boolean;
@ -91,10 +91,11 @@ interface IBannedUserProps {
}
export class BannedUser extends React.Component<IBannedUserProps> {
public static contextType = MatrixClientContext;
public context!: React.ContextType<typeof MatrixClientContext>;
private onUnbanClick = (): void => {
MatrixClientPeg.get()
.unban(this.props.member.roomId, this.props.member.userId)
.catch((err) => {
this.context.unban(this.props.member.roomId, this.props.member.userId).catch((err) => {
logger.error("Failed to unban: " + err);
Modal.createDialog(ErrorDialog, {
title: _t("Error"),
@ -136,12 +137,15 @@ interface IProps {
}
export default class RolesRoomSettingsTab extends React.Component<IProps> {
public static contextType = MatrixClientContext;
public context!: React.ContextType<typeof MatrixClientContext>;
public componentDidMount(): void {
MatrixClientPeg.get().on(RoomStateEvent.Update, this.onRoomStateUpdate);
this.context.on(RoomStateEvent.Update, this.onRoomStateUpdate);
}
public componentWillUnmount(): void {
const client = MatrixClientPeg.get();
const client = this.context;
if (client) {
client.removeListener(RoomStateEvent.Update, this.onRoomStateUpdate);
}
@ -173,7 +177,7 @@ export default class RolesRoomSettingsTab extends React.Component<IProps> {
}
private onPowerLevelsChanged = (value: number, powerLevelKey: string): void => {
const client = MatrixClientPeg.get();
const client = this.context;
const room = this.props.room;
const plEvent = room.currentState.getStateEvents(EventType.RoomPowerLevels, "");
let plContent = plEvent?.getContent() ?? {};
@ -215,7 +219,7 @@ export default class RolesRoomSettingsTab extends React.Component<IProps> {
};
private onUserPowerLevelChanged = (value: number, powerLevelKey: string): void => {
const client = MatrixClientPeg.get();
const client = this.context;
const room = this.props.room;
const plEvent = room.currentState.getStateEvents(EventType.RoomPowerLevels, "");
let plContent = plEvent?.getContent() ?? {};
@ -241,7 +245,7 @@ export default class RolesRoomSettingsTab extends React.Component<IProps> {
};
public render(): React.ReactNode {
const client = MatrixClientPeg.get();
const client = this.context;
const room = this.props.room;
const isSpaceRoom = room.isSpaceRoom();

View file

@ -21,7 +21,6 @@ import { RoomState } from "matrix-js-sdk/src/models/room-state";
import { Room } from "matrix-js-sdk/src/matrix";
import { _t } from "../../../../../languageHandler";
import { MatrixClientPeg } from "../../../../../MatrixClientPeg";
import LabelledToggleSwitch from "../../../elements/LabelledToggleSwitch";
import SettingsSubsection from "../../shared/SettingsSubsection";
import SettingsTab from "../SettingsTab";
@ -38,14 +37,17 @@ const ElementCallSwitch: React.FC<ElementCallSwitchProps> = ({ room }) => {
const isPublic = useMemo(() => room.getJoinRule() === JoinRule.Public, [room]);
const [content, events, maySend] = useRoomState(
room,
useCallback((state: RoomState) => {
useCallback(
(state: RoomState) => {
const content = state?.getStateEvents(EventType.RoomPowerLevels, "")?.getContent();
return [
content ?? {},
content?.["events"] ?? {},
state?.maySendStateEvent(EventType.RoomPowerLevels, MatrixClientPeg.get().getSafeUserId()),
state?.maySendStateEvent(EventType.RoomPowerLevels, room.client.getSafeUserId()),
];
}, []),
},
[room.client],
),
);
const [elementCallEnabled, setElementCallEnabled] = useState<boolean>(() => {
@ -69,12 +71,12 @@ const ElementCallSwitch: React.FC<ElementCallSwitchProps> = ({ room }) => {
events[ElementCall.MEMBER_EVENT_TYPE.name] = adminLevel;
}
MatrixClientPeg.get().sendStateEvent(room.roomId, EventType.RoomPowerLevels, {
room.client.sendStateEvent(room.roomId, EventType.RoomPowerLevels, {
events: events,
...content,
});
},
[room.roomId, content, events, isPublic],
[room.client, room.roomId, content, events, isPublic],
);
const brand = SdkConfig.get("element_call").brand ?? DEFAULTS.element_call.brand;

View file

@ -19,7 +19,6 @@ import React, { ChangeEvent, ReactNode } from "react";
import { _t } from "../../../../../languageHandler";
import SdkConfig from "../../../../../SdkConfig";
import { MatrixClientPeg } from "../../../../../MatrixClientPeg";
import SettingsStore from "../../../../../settings/SettingsStore";
import SettingsFlag from "../../../elements/SettingsFlag";
import Field from "../../../elements/Field";
@ -34,6 +33,7 @@ import ImageSizePanel from "../../ImageSizePanel";
import SettingsTab from "../SettingsTab";
import { SettingsSection } from "../../shared/SettingsSection";
import SettingsSubsection, { SettingsSubsectionText } from "../../shared/SettingsSubsection";
import MatrixClientContext from "../../../../../contexts/MatrixClientContext";
interface IProps {}
@ -49,6 +49,9 @@ interface IState {
}
export default class AppearanceUserSettingsTab extends React.Component<IProps, IState> {
public static contextType = MatrixClientContext;
public context!: React.ContextType<typeof MatrixClientContext>;
private readonly MESSAGE_PREVIEW_TEXT = _t("Hey you. You're the best!");
private unmounted = false;
@ -66,7 +69,7 @@ export default class AppearanceUserSettingsTab extends React.Component<IProps, I
public async componentDidMount(): Promise<void> {
// Fetch the current user profile for the message preview
const client = MatrixClientPeg.get();
const client = this.context;
const userId = client.getUserId()!;
const profileInfo = await client.getProfileInfo(userId);
if (this.unmounted) return;

View file

@ -33,7 +33,6 @@ import SpellCheckSettings from "../../SpellCheckSettings";
import AccessibleButton from "../../../elements/AccessibleButton";
import DeactivateAccountDialog from "../../../dialogs/DeactivateAccountDialog";
import PlatformPeg from "../../../../../PlatformPeg";
import { MatrixClientPeg } from "../../../../../MatrixClientPeg";
import Modal from "../../../../../Modal";
import dis from "../../../../../dispatcher/dispatcher";
import { Service, ServicePolicyPair, startTermsFlow } from "../../../../../Terms";
@ -102,14 +101,15 @@ export default class GeneralUserSettingsTab extends React.Component<IProps, ISta
private readonly dispatcherRef: string;
public constructor(props: IProps) {
public constructor(props: IProps, context: React.ContextType<typeof MatrixClientContext>) {
super(props);
this.context = context;
this.state = {
language: languageHandler.getCurrentLanguage(),
spellCheckEnabled: false,
spellCheckLanguages: [],
haveIdServer: Boolean(MatrixClientPeg.get().getIdentityServerUrl()),
haveIdServer: Boolean(this.context.getIdentityServerUrl()),
idServerHasUnsignedTerms: false,
requiredPolicyInfo: {
// This object is passed along to a component for handling
@ -151,7 +151,7 @@ export default class GeneralUserSettingsTab extends React.Component<IProps, ISta
private onAction = (payload: ActionPayload): void => {
if (payload.action === "id_server_changed") {
this.setState({ haveIdServer: Boolean(MatrixClientPeg.get().getIdentityServerUrl()) });
this.setState({ haveIdServer: Boolean(this.context.getIdentityServerUrl()) });
this.getThreepidState();
}
};
@ -165,7 +165,7 @@ export default class GeneralUserSettingsTab extends React.Component<IProps, ISta
};
private async getCapabilities(): Promise<void> {
const cli = MatrixClientPeg.get();
const cli = this.context;
const serverSupportsSeparateAddAndBind = await cli.doesServerSupportSeparateAddAndBind();
@ -184,7 +184,7 @@ export default class GeneralUserSettingsTab extends React.Component<IProps, ISta
}
private async getThreepidState(): Promise<void> {
const cli = MatrixClientPeg.get();
const cli = this.context;
// Check to see if terms need accepting
this.checkTerms();
@ -195,7 +195,7 @@ export default class GeneralUserSettingsTab extends React.Component<IProps, ISta
try {
threepids = await getThreepidsWithBindStatus(cli);
} catch (e) {
const idServerUrl = MatrixClientPeg.get().getIdentityServerUrl();
const idServerUrl = this.context.getIdentityServerUrl();
logger.warn(
`Unable to reach identity server at ${idServerUrl} to check ` + `for 3PIDs bindings in Settings`,
);
@ -211,7 +211,7 @@ export default class GeneralUserSettingsTab extends React.Component<IProps, ISta
private async checkTerms(): Promise<void> {
// By starting the terms flow we get the logic for checking which terms the user has signed
// for free. So we might as well use that for our own purposes.
const idServerUrl = MatrixClientPeg.get().getIdentityServerUrl();
const idServerUrl = this.context.getIdentityServerUrl();
if (!this.state.haveIdServer || !idServerUrl) {
this.setState({ idServerHasUnsignedTerms: false });
return;

View file

@ -19,7 +19,6 @@ import { logger } from "matrix-js-sdk/src/logger";
import AccessibleButton from "../../../elements/AccessibleButton";
import { _t, getCurrentLanguage } from "../../../../../languageHandler";
import { MatrixClientPeg } from "../../../../../MatrixClientPeg";
import SdkConfig from "../../../../../SdkConfig";
import createRoom from "../../../../../createRoom";
import Modal from "../../../../../Modal";
@ -77,7 +76,7 @@ export default class HelpUserSettingsTab extends React.Component<IProps, IState>
private getVersionInfo(): { appVersion: string; olmVersion: string } {
const brand = SdkConfig.get().brand;
const appVersion = this.state.appVersion || "unknown";
const olmVersionTuple = MatrixClientPeg.get().olmVersion;
const olmVersionTuple = this.context.olmVersion;
const olmVersion = olmVersionTuple
? `${olmVersionTuple[0]}.${olmVersionTuple[1]}.${olmVersionTuple[2]}`
: "<not-enabled>";
@ -94,10 +93,8 @@ export default class HelpUserSettingsTab extends React.Component<IProps, IState>
// Dev note: please keep this log line, it's useful when troubleshooting a MatrixClient suddenly
// stopping in the middle of the logs.
logger.log("Clear cache & reload clicked");
MatrixClientPeg.get().stopClient();
MatrixClientPeg.get()
.store.deleteAllData()
.then(() => {
this.context.stopClient();
this.context.store.deleteAllData().then(() => {
PlatformPeg.get()?.reload();
});
};
@ -362,19 +359,19 @@ export default class HelpUserSettingsTab extends React.Component<IProps, IState>
{_t(
"Homeserver is <code>%(homeserverUrl)s</code>",
{
homeserverUrl: MatrixClientPeg.get().getHomeserverUrl(),
homeserverUrl: this.context.getHomeserverUrl(),
},
{
code: (sub) => <code>{sub}</code>,
},
)}
</SettingsSubsectionText>
{MatrixClientPeg.get().getIdentityServerUrl() && (
{this.context.getIdentityServerUrl() && (
<SettingsSubsectionText>
{_t(
"Identity server is <code>%(identityServerUrl)s</code>",
{
identityServerUrl: MatrixClientPeg.get().getIdentityServerUrl(),
identityServerUrl: this.context.getIdentityServerUrl(),
},
{
code: (sub) => <code>{sub}</code>,
@ -391,8 +388,8 @@ export default class HelpUserSettingsTab extends React.Component<IProps, IState>
" Do not share it with anyone.",
)}
</b>
<CopyableText getTextToCopy={() => MatrixClientPeg.get().getAccessToken()}>
{MatrixClientPeg.get().getAccessToken()}
<CopyableText getTextToCopy={() => this.context.getAccessToken()}>
{this.context.getAccessToken()}
</CopyableText>
</details>
</SettingsSubsectionText>

View file

@ -23,7 +23,6 @@ import { _t } from "../../../../../languageHandler";
import MediaDeviceHandler, { IMediaDevices, MediaDeviceKindEnum } from "../../../../../MediaDeviceHandler";
import Field from "../../../elements/Field";
import AccessibleButton from "../../../elements/AccessibleButton";
import { MatrixClientPeg } from "../../../../../MatrixClientPeg";
import { SettingLevel } from "../../../../../settings/SettingLevel";
import SettingsFlag from "../../../elements/SettingsFlag";
import LabelledToggleSwitch from "../../../elements/LabelledToggleSwitch";
@ -31,6 +30,7 @@ import { requestMediaPermissions } from "../../../../../utils/media/requestMedia
import SettingsTab from "../SettingsTab";
import { SettingsSection } from "../../shared/SettingsSection";
import SettingsSubsection from "../../shared/SettingsSubsection";
import MatrixClientContext from "../../../../../contexts/MatrixClientContext";
interface IState {
mediaDevices: IMediaDevices | null;
@ -58,6 +58,9 @@ const mapDeviceKindToHandlerValue = (deviceKind: MediaDeviceKindEnum): string |
};
export default class VoiceUserSettingsTab extends React.Component<{}, IState> {
public static contextType = MatrixClientContext;
public context!: React.ContextType<typeof MatrixClientContext>;
public constructor(props: {}) {
super(props);
@ -114,11 +117,11 @@ export default class VoiceUserSettingsTab extends React.Component<{}, IState> {
};
private changeWebRtcMethod = (p2p: boolean): void => {
MatrixClientPeg.get().setForceTURN(!p2p);
this.context.setForceTURN(!p2p);
};
private changeFallbackICEServerAllowed = (allow: boolean): void => {
MatrixClientPeg.get().setFallbackICEServerAllowed(allow);
this.context.setFallbackICEServerAllowed(allow);
};
private renderDeviceOptions(devices: Array<MediaDeviceInfo>, category: MediaDeviceKindEnum): Array<JSX.Element> {

View file

@ -16,10 +16,10 @@ limitations under the License.
import { ClientEvent } from "matrix-js-sdk/src/matrix";
import { MatrixClientPeg } from "../MatrixClientPeg";
import { useEventEmitterState } from "./useEventEmitter";
import { useMatrixClientContext } from "../contexts/MatrixClientContext";
export function useInitialSyncComplete(): boolean {
const cli = MatrixClientPeg.get();
const cli = useMatrixClientContext();
return useEventEmitterState(cli, ClientEvent.Sync, () => cli.isInitialSyncComplete());
}

View file

@ -18,9 +18,9 @@ import { logger } from "matrix-js-sdk/src/logger";
import { ClientEvent, MatrixClient } from "matrix-js-sdk/src/matrix";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { MatrixClientPeg } from "../MatrixClientPeg";
import { Notifier } from "../Notifier";
import DMRoomMap from "../utils/DMRoomMap";
import { useMatrixClientContext } from "../contexts/MatrixClientContext";
export interface UserOnboardingContext {
hasAvatar: boolean;
@ -47,7 +47,7 @@ function useRefOf<T extends any[], R>(value: (...values: T) => R): (...values: T
function useUserOnboardingContextValue<T>(defaultValue: T, callback: (cli: MatrixClient) => Promise<T>): T {
const [value, setValue] = useState<T>(defaultValue);
const cli = MatrixClientPeg.get();
const cli = useMatrixClientContext();
const handler = useRefOf(callback);

View file

@ -25,13 +25,13 @@ import {
VoiceBroadcastInfoState,
} from "..";
import { IBodyProps } from "../../components/views/messages/IBodyProps";
import { MatrixClientPeg } from "../../MatrixClientPeg";
import { RelationsHelper, RelationsHelperEvent } from "../../events/RelationsHelper";
import { SDKContext } from "../../contexts/SDKContext";
import { useMatrixClientContext } from "../../contexts/MatrixClientContext";
export const VoiceBroadcastBody: React.FC<IBodyProps> = ({ mxEvent }) => {
const sdkContext = useContext(SDKContext);
const client = MatrixClientPeg.get();
const client = useMatrixClientContext();
const [infoState, setInfoState] = useState(mxEvent.getContent()?.state || VoiceBroadcastInfoState.Stopped);
useEffect(() => {

View file

@ -19,7 +19,7 @@ import { render } from "@testing-library/react";
import { MatrixEvent, Room } from "matrix-js-sdk/src/matrix";
import BridgeSettingsTab from "../../../../../../src/components/views/settings/tabs/room/BridgeSettingsTab";
import { getMockClientWithEventEmitter } from "../../../../../test-utils";
import { getMockClientWithEventEmitter, withClientContextRenderOptions } from "../../../../../test-utils";
describe("<BridgeSettingsTab />", () => {
const userId = "@alice:server.org";
@ -28,7 +28,8 @@ describe("<BridgeSettingsTab />", () => {
});
const roomId = "!room:server.org";
const getComponent = (room: Room) => render(<BridgeSettingsTab room={room} />);
const getComponent = (room: Room) =>
render(<BridgeSettingsTab room={room} />, withClientContextRenderOptions(client));
it("renders when room is not bridging messages to any platform", () => {
const room = new Room(roomId, client, userId);

View file

@ -24,7 +24,7 @@ import { mocked } from "jest-mock";
import { RoomMember } from "matrix-js-sdk/src/matrix";
import RolesRoomSettingsTab from "../../../../../../src/components/views/settings/tabs/room/RolesRoomSettingsTab";
import { mkStubRoom, stubClient } from "../../../../../test-utils";
import { mkStubRoom, withClientContextRenderOptions, stubClient } from "../../../../../test-utils";
import { MatrixClientPeg } from "../../../../../../src/MatrixClientPeg";
import { VoiceBroadcastInfoEventType } from "../../../../../../src/voice-broadcast";
import SettingsStore from "../../../../../../src/settings/SettingsStore";
@ -37,7 +37,7 @@ describe("RolesRoomSettingsTab", () => {
let room: Room;
const renderTab = (propRoom: Room = room): RenderResult => {
return render(<RolesRoomSettingsTab room={propRoom} />);
return render(<RolesRoomSettingsTab room={propRoom} />, withClientContextRenderOptions(cli));
};
const getVoiceBroadcastsSelect = (): HTMLElement => {

View file

@ -16,9 +16,10 @@ limitations under the License.
import { render } from "@testing-library/react";
import React from "react";
import { MatrixClient } from "matrix-js-sdk/src/matrix";
import AppearanceUserSettingsTab from "../../../../../../src/components/views/settings/tabs/user/AppearanceUserSettingsTab";
import { stubClient } from "../../../../../test-utils";
import { withClientContextRenderOptions, stubClient } from "../../../../../test-utils";
// Fake random strings to give a predictable snapshot
jest.mock("matrix-js-sdk/src/randomstring", () => ({
@ -26,12 +27,14 @@ jest.mock("matrix-js-sdk/src/randomstring", () => ({
}));
describe("AppearanceUserSettingsTab", () => {
let client: MatrixClient;
beforeEach(() => {
stubClient();
client = stubClient();
});
it("should render", () => {
const { asFragment } = render(<AppearanceUserSettingsTab />);
const { asFragment } = render(<AppearanceUserSettingsTab />, withClientContextRenderOptions(client));
expect(asFragment()).toMatchSnapshot();
});
});

View file

@ -17,7 +17,7 @@ limitations under the License.
import React from "react";
import { act, render, RenderResult } from "@testing-library/react";
import { filterConsole, stubClient } from "../../../test-utils";
import { filterConsole, withClientContextRenderOptions, stubClient } from "../../../test-utils";
import { UserOnboardingPage } from "../../../../src/components/views/user-onboarding/UserOnboardingPage";
import { MatrixClientPeg } from "../../../../src/MatrixClientPeg";
import SdkConfig from "../../../../src/SdkConfig";
@ -34,7 +34,7 @@ jest.mock("../../../../src/components/structures/HomePage", () => ({
describe("UserOnboardingPage", () => {
const renderComponent = async (): Promise<RenderResult> => {
const renderResult = render(<UserOnboardingPage />);
const renderResult = render(<UserOnboardingPage />, withClientContextRenderOptions(MatrixClientPeg.safeGet()));
await act(async () => {
jest.runAllTimers();
});

View file

@ -16,6 +16,7 @@ limitations under the License.
import React, { ComponentType, Ref } from "react";
import { MatrixClient } from "matrix-js-sdk/src/matrix";
import { RenderOptions } from "@testing-library/react";
import { MatrixClientPeg as peg } from "../../src/MatrixClientPeg";
import MatrixClientContext from "../../src/contexts/MatrixClientContext";
@ -57,3 +58,15 @@ export function wrapInSdkContext<T>(
}
};
}
/**
* Test helper to generate React testing library render options for wrapping with a MatrixClientContext.Provider
* @param client the MatrixClient instance to expose via the provider
*/
export function withClientContextRenderOptions(client: MatrixClient): RenderOptions {
return {
wrapper: ({ children }) => (
<MatrixClientContext.Provider value={client}>{children}</MatrixClientContext.Provider>
),
};
}

View file

@ -28,7 +28,7 @@ import {
VoiceBroadcastPlayback,
VoiceBroadcastRecordingsStore,
} from "../../../src/voice-broadcast";
import { stubClient, wrapInSdkContext } from "../../test-utils";
import { withClientContextRenderOptions, stubClient, wrapInSdkContext } from "../../test-utils";
import { mkVoiceBroadcastInfoStateEvent } from "../utils/test-utils";
import { MediaEventHelper } from "../../../src/utils/MediaEventHelper";
import { RoomPermalinkCreator } from "../../../src/utils/permalinks/Permalinks";
@ -66,6 +66,7 @@ describe("VoiceBroadcastBody", () => {
onMessageAllowed={() => {}}
permalinkCreator={new RoomPermalinkCreator(room)}
/>,
withClientContextRenderOptions(client),
);
testRecording = SdkContextClass.instance.voiceBroadcastRecordingsStore.getByInfoEvent(infoEvent, client);
};