Eliminate the use of MatrixClientPeg in utils (#10910)

This commit is contained in:
Michael Telatynski 2023-05-23 16:24:12 +01:00 committed by GitHub
parent a0c2676c38
commit 30429df948
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
108 changed files with 409 additions and 325 deletions

View File

@ -436,15 +436,18 @@ export default class ContentMessages {
}
}
promBefore = doMaybeLocalRoomAction(roomId, (actualRoomId) =>
this.sendContentToRoom(
file,
actualRoomId,
relation,
matrixClient,
replyToEvent ?? undefined,
loopPromiseBefore,
),
promBefore = doMaybeLocalRoomAction(
roomId,
(actualRoomId) =>
this.sendContentToRoom(
file,
actualRoomId,
relation,
matrixClient,
replyToEvent ?? undefined,
loopPromiseBefore,
),
matrixClient,
);
}

View File

@ -301,7 +301,7 @@ export default class DeviceListener {
} else {
// No cross-signing or key backup on account (set up encryption)
await cli.waitForClientWellKnown();
if (isSecureBackupRequired() && isLoggedIn()) {
if (isSecureBackupRequired(cli) && isLoggedIn()) {
// If we're meant to set up, and Secure Backup is required,
// trigger the flow directly without a toast once logged in.
hideSetupEncryptionToast();

View File

@ -133,8 +133,8 @@ export default class IdentityAuthClient {
if (
!this.tempClient &&
!doesAccountDataHaveIdentityServer() &&
!(await doesIdentityServerHaveTerms(identityServerUrl))
!doesAccountDataHaveIdentityServer(this.matrixClient) &&
!(await doesIdentityServerHaveTerms(this.matrixClient, identityServerUrl))
) {
const { finished } = Modal.createDialog(QuestionDialog, {
title: _t("Identity server has no terms of service"),
@ -158,7 +158,7 @@ export default class IdentityAuthClient {
});
const [confirmed] = await finished;
if (confirmed) {
setToDefaultIdentityServer();
setToDefaultIdentityServer(this.matrixClient);
} else {
throw new AbortedIdentityActionError("User aborted identity server action without terms");
}

View File

@ -1209,7 +1209,7 @@ export default class LegacyCallHandler extends EventEmitter {
}
try {
await WidgetUtils.addJitsiWidget(roomId, type, "Jitsi", false);
await WidgetUtils.addJitsiWidget(client, roomId, type, "Jitsi", false);
logger.log("Jitsi widget added");
} catch (e) {
if (e instanceof MatrixError && e.errcode === "M_FORBIDDEN") {

View File

@ -636,7 +636,7 @@ async function doSetLoggedIn(credentials: IMatrixClientCreds, clearStorageEnable
}
dis.fire(Action.OnLoggedIn);
await startMatrixClient(/*startSyncing=*/ !softLogout);
await startMatrixClient(client, /*startSyncing=*/ !softLogout);
return client;
}
@ -780,10 +780,11 @@ export function isLoggingOut(): boolean {
/**
* Starts the matrix client and all other react-sdk services that
* listen for events while a session is logged in.
* @param client the matrix client to start
* @param {boolean} startSyncing True (default) to actually start
* syncing the client.
*/
async function startMatrixClient(startSyncing = true): Promise<void> {
async function startMatrixClient(client: MatrixClient, startSyncing = true): Promise<void> {
logger.log(`Lifecycle: Starting MatrixClient`);
// dispatch this before starting the matrix client: it's used
@ -796,10 +797,10 @@ async function startMatrixClient(startSyncing = true): Promise<void> {
SdkContextClass.instance.typingStore.reset();
ToastStore.sharedInstance().reset();
DialogOpener.instance.prepare();
DialogOpener.instance.prepare(client);
Notifier.start();
UserActivity.sharedInstance().start();
DMRoomMap.makeShared().start();
DMRoomMap.makeShared(client).start();
IntegrationManagers.sharedInstance().startWatching();
ActiveWidgetStore.instance.start();
LegacyCallHandler.instance.start();

View File

@ -20,6 +20,7 @@ import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import { User } from "matrix-js-sdk/src/models/user";
import { logger } from "matrix-js-sdk/src/logger";
import { EventType } from "matrix-js-sdk/src/@types/event";
import { MatrixClient } from "matrix-js-sdk/src/matrix";
import { MatrixClientPeg } from "./MatrixClientPeg";
import MultiInviter, { CompletionStates } from "./utils/MultiInviter";
@ -49,12 +50,13 @@ export interface IInviteResult {
* @returns {Promise} Promise
*/
export function inviteMultipleToRoom(
client: MatrixClient,
roomId: string,
addresses: string[],
sendSharedHistoryKeys = false,
progressCallback?: () => void,
): Promise<IInviteResult> {
const inviter = new MultiInviter(roomId, progressCallback);
const inviter = new MultiInviter(client, roomId, progressCallback);
return inviter
.invite(addresses, undefined, sendSharedHistoryKeys)
.then((states) => Promise.resolve({ states, inviter }));
@ -105,12 +107,13 @@ export function isValid3pidInvite(event: MatrixEvent): boolean {
}
export function inviteUsersToRoom(
client: MatrixClient,
roomId: string,
userIds: string[],
sendSharedHistoryKeys = false,
progressCallback?: () => void,
): Promise<void> {
return inviteMultipleToRoom(roomId, userIds, sendSharedHistoryKeys, progressCallback)
return inviteMultipleToRoom(client, roomId, userIds, sendSharedHistoryKeys, progressCallback)
.then((result) => {
const room = MatrixClientPeg.get().getRoom(roomId)!;
showAnyInviteErrors(result.states, room, result.inviter);

View File

@ -411,6 +411,7 @@ function kickUser(event: MessageEvent<any>, roomId: string, userId: string): voi
}
function setWidget(event: MessageEvent<any>, roomId: string | null): void {
const client = MatrixClientPeg.get();
const widgetId = event.data.widget_id;
let widgetType = event.data.type;
const widgetUrl = event.data.url;
@ -458,7 +459,7 @@ function setWidget(event: MessageEvent<any>, roomId: string | null): void {
widgetType = WidgetType.fromString(widgetType);
if (userWidget) {
WidgetUtils.setUserWidget(widgetId, widgetType, widgetUrl, widgetName, widgetData)
WidgetUtils.setUserWidget(client, widgetId, widgetType, widgetUrl, widgetName, widgetData)
.then(() => {
sendResponse(event, {
success: true,
@ -476,6 +477,7 @@ function setWidget(event: MessageEvent<any>, roomId: string | null): void {
return;
}
WidgetUtils.setRoomWidget(
client,
roomId,
widgetId,
widgetType,
@ -516,7 +518,7 @@ function getWidgets(event: MessageEvent<any>, roomId: string | null): void {
}
// Add user widgets (not linked to a specific room)
const userWidgets = WidgetUtils.getUserWidgetsArray();
const userWidgets = WidgetUtils.getUserWidgetsArray(client);
widgetStateEvents = widgetStateEvents.concat(userWidgets);
sendResponse(event, widgetStateEvents);

View File

@ -344,7 +344,7 @@ export async function accessSecretStorage(func = async (): Promise<void> => {},
onBeforeClose: async (reason): Promise<boolean> => {
// If Secure Backup is required, you cannot leave the modal.
if (reason === "backgroundClick") {
return !isSecureBackupRequired();
return !isSecureBackupRequired(cli);
}
return true;
},

View File

@ -576,7 +576,7 @@ export const Commands = [
prom = finished.then(([useDefault]) => {
if (useDefault) {
setToDefaultIdentityServer();
setToDefaultIdentityServer(MatrixClientPeg.get());
return;
}
throw new UserFriendlyError(
@ -589,7 +589,7 @@ export const Commands = [
);
}
}
const inviter = new MultiInviter(roomId);
const inviter = new MultiInviter(MatrixClientPeg.get(), roomId);
return success(
prom
.then(() => {
@ -765,7 +765,7 @@ export const Commands = [
}
if (!targetRoomId) targetRoomId = roomId;
return success(leaveRoomBehaviour(targetRoomId));
return success(leaveRoomBehaviour(cli, targetRoomId));
},
category: CommandCategories.actions,
renderingTypes: [TimelineRenderingType.Room],
@ -1018,7 +1018,7 @@ export const Commands = [
if (!widgetUrl.startsWith("https://") && !widgetUrl.startsWith("http://")) {
return reject(new UserFriendlyError("Please supply a https:// or http:// widget URL"));
}
if (WidgetUtils.canUserModifyWidgets(roomId)) {
if (WidgetUtils.canUserModifyWidgets(MatrixClientPeg.get(), roomId)) {
const userId = MatrixClientPeg.get().getUserId();
const nowMs = new Date().getTime();
const widgetId = encodeURIComponent(`${roomId}_${userId}_${nowMs}`);
@ -1036,7 +1036,9 @@ export const Commands = [
widgetUrl = WidgetUtils.getLocalJitsiWrapperUrl();
}
return success(WidgetUtils.setRoomWidget(roomId, widgetId, type, widgetUrl, name, data));
return success(
WidgetUtils.setRoomWidget(MatrixClientPeg.get(), roomId, widgetId, type, widgetUrl, name, data),
);
} else {
return reject(new UserFriendlyError("You cannot modify widgets in this room."));
}

View File

@ -110,8 +110,10 @@ export default class CreateSecretStorageDialog extends React.PureComponent<IProp
public constructor(props: IProps) {
super(props);
let passPhraseKeySelected;
const setupMethods = getSecureBackupSetupMethods();
const cli = MatrixClientPeg.get();
let passPhraseKeySelected: SecureBackupSetupMethod;
const setupMethods = getSecureBackupSetupMethods(cli);
if (setupMethods.includes(SecureBackupSetupMethod.Key)) {
passPhraseKeySelected = SecureBackupSetupMethod.Key;
} else {
@ -143,13 +145,13 @@ export default class CreateSecretStorageDialog extends React.PureComponent<IProp
// does the server offer a UI auth flow with just m.login.password
// for /keys/device_signing/upload?
accountPasswordCorrect: null,
canSkip: !isSecureBackupRequired(),
canSkip: !isSecureBackupRequired(cli),
canUploadKeysWithPasswordOnly,
passPhraseKeySelected,
accountPassword,
};
MatrixClientPeg.get().on(CryptoEvent.KeyBackupStatus, this.onKeyBackupStatusChange);
cli.on(CryptoEvent.KeyBackupStatus, this.onKeyBackupStatusChange);
this.getInitialPhase();
}
@ -542,7 +544,7 @@ export default class CreateSecretStorageDialog extends React.PureComponent<IProp
}
private renderPhaseChooseKeyPassphrase(): JSX.Element {
const setupMethods = getSecureBackupSetupMethods();
const setupMethods = getSecureBackupSetupMethods(MatrixClientPeg.get());
const optionKey = setupMethods.includes(SecureBackupSetupMethod.Key) ? this.renderOptionKey() : null;
const optionPassphrase = setupMethods.includes(SecureBackupSetupMethod.Passphrase)
? this.renderOptionPassphrase()

View File

@ -57,7 +57,7 @@ function matcherObject(
export default class RoomProvider extends AutocompleteProvider {
protected matcher: QueryMatcher<ReturnType<typeof matcherObject>>;
public constructor(room: Room, renderingType?: TimelineRenderingType) {
public constructor(private readonly room: Room, renderingType?: TimelineRenderingType) {
super({ commandRegex: ROOM_REGEX, renderingType });
this.matcher = new QueryMatcher<ReturnType<typeof matcherObject>>([], {
keys: ["displayedAlias", "matchName"],
@ -119,7 +119,7 @@ export default class RoomProvider extends AutocompleteProvider {
completionId: room.room.roomId,
type: "room",
suffix: " ",
href: makeRoomPermalink(room.displayedAlias),
href: makeRoomPermalink(this.room.client, room.displayedAlias),
component: (
<PillCompletion title={room.room.name} description={room.displayedAlias}>
<RoomAvatar width={24} height={24} room={room.room} />

View File

@ -28,7 +28,7 @@ import { OwnProfileStore } from "../../stores/OwnProfileStore";
import AccessibleButton, { ButtonEvent } from "../views/elements/AccessibleButton";
import { UPDATE_EVENT } from "../../stores/AsyncStore";
import { useEventEmitter } from "../../hooks/useEventEmitter";
import MatrixClientContext from "../../contexts/MatrixClientContext";
import MatrixClientContext, { useMatrixClientContext } from "../../contexts/MatrixClientContext";
import MiniAvatarUploader, { AVATAR_SIZE } from "../views/elements/MiniAvatarUploader";
import PosthogTrackers from "../../PosthogTrackers";
import EmbeddedPage from "./EmbeddedPage";
@ -97,8 +97,9 @@ const UserWelcomeTop: React.FC = () => {
};
const HomePage: React.FC<IProps> = ({ justRegistered = false }) => {
const cli = useMatrixClientContext();
const config = SdkConfig.get();
const pageUrl = getHomePageUrl(config);
const pageUrl = getHomePageUrl(config, cli);
if (pageUrl) {
return <EmbeddedPage className="mx_HomePage" url={pageUrl} scrollbar={true} />;

View File

@ -1154,7 +1154,8 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
}
private leaveRoom(roomId: string): void {
const roomToLeave = MatrixClientPeg.get().getRoom(roomId);
const cli = MatrixClientPeg.get();
const roomToLeave = cli.getRoom(roomId);
const warnings = this.leaveRoomWarnings(roomId);
const isSpace = roomToLeave?.isSpaceRoom();
@ -1173,9 +1174,9 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
</span>
),
button: _t("Leave"),
onFinished: (shouldLeave) => {
onFinished: async (shouldLeave) => {
if (shouldLeave) {
leaveRoomBehaviour(roomId);
await leaveRoomBehaviour(cli, roomId);
dis.dispatch<AfterLeaveRoomPayload>({
action: Action.AfterLeaveRoom,
@ -1211,7 +1212,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
}
private async copyRoom(roomId: string): Promise<void> {
const roomLink = makeRoomPermalink(roomId);
const roomLink = makeRoomPermalink(MatrixClientPeg.get(), roomId);
const success = await copyPlaintext(roomLink);
if (!success) {
Modal.createDialog(ErrorDialog, {

View File

@ -743,7 +743,7 @@ export default class MessagePanel extends React.Component<IProps, IState> {
lastInSection =
willWantDateSeparator ||
mxEv.getSender() !== nextEv.getSender() ||
getEventDisplayInfo(nextEv, this.showHiddenEvents).isInfoMessage ||
getEventDisplayInfo(MatrixClientPeg.get(), nextEv, this.showHiddenEvents).isInfoMessage ||
!shouldFormContinuation(mxEv, nextEv, this.showHiddenEvents, this.context.timelineRenderingType);
}

View File

@ -561,7 +561,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
createdByCurrentUserTs - lastCreatedByOtherTs < PREVENT_MULTIPLE_JITSI_WITHIN
) {
// more than one Jitsi widget with the last one from the current user → remove it
WidgetUtils.setRoomWidget(this.state.roomId, createdByCurrentUser.id);
WidgetUtils.setRoomWidget(this.context.client, this.state.roomId, createdByCurrentUser.id);
}
}

View File

@ -549,7 +549,7 @@ const SpaceSetupPrivateInvite: React.FC<{
setBusy(true);
const targetIds = emailAddresses.map((name) => name.trim()).filter(Boolean);
try {
const result = await inviteMultipleToRoom(space.roomId, targetIds);
const result = await inviteMultipleToRoom(space.client, space.roomId, targetIds);
const failedUsers = Object.keys(result.states).filter((a) => result.states[a] === "error");
if (failedUsers.length > 0) {

View File

@ -110,7 +110,7 @@ export default class UserMenu extends React.Component<IProps, IState> {
}
private get hasHomePage(): boolean {
return !!getHomePageUrl(SdkConfig.get());
return !!getHomePageUrl(SdkConfig.get(), this.context.client!);
}
private onCurrentVoiceBroadcastRecordingChanged = (recording: VoiceBroadcastRecording | null): void => {

View File

@ -153,7 +153,9 @@ export default class ViewSource extends React.Component<IProps, IState> {
const isEditing = this.state.isEditing;
const roomId = mxEvent.getRoomId()!;
const eventId = mxEvent.getId()!;
const canEdit = mxEvent.isState() ? this.canSendStateEvent(mxEvent) : canEditContent(this.props.mxEvent);
const canEdit = mxEvent.isState()
? this.canSendStateEvent(mxEvent)
: canEditContent(MatrixClientPeg.get(), this.props.mxEvent);
return (
<BaseDialog className="mx_ViewSource" onFinished={this.props.onFinished} title={_t("View Source")}>
<div className="mx_ViewSource_header">

View File

@ -22,6 +22,7 @@ import SdkConfig from "../../../SdkConfig";
import withValidation, { IFieldState, IValidationResult } from "../elements/Validation";
import { _t, _td } from "../../../languageHandler";
import Field, { IInputProps } from "../elements/Field";
import { MatrixClientPeg } from "../../../MatrixClientPeg";
interface IProps extends Omit<IInputProps, "onValidate" | "element"> {
autoFocus?: boolean;
@ -56,7 +57,7 @@ class PassphraseField extends PureComponent<IProps> {
deriveData: async ({ value }): Promise<zxcvbn.ZXCVBNResult | null> => {
if (!value) return null;
const { scorePassword } = await import("../../../utils/PasswordScorer");
return scorePassword(value);
return scorePassword(MatrixClientPeg.get(), value);
},
rules: [
{

View File

@ -165,7 +165,7 @@ export default class DecoratedRoomAvatar extends React.PureComponent<IProps, ISt
const otherUserId = DMRoomMap.shared().getUserIdForRoomId(this.props.room.roomId);
if (otherUserId && this.props.room.getJoinedMemberCount() === 2) {
// Track presence, if available
if (isPresenceEnabled()) {
if (isPresenceEnabled(this.props.room.client)) {
this.dmUser = MatrixClientPeg.get().getUser(otherUserId);
icon = this.getPresenceIcon();
}

View File

@ -317,7 +317,12 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
};
private onEditClick = (): void => {
editEvent(this.props.mxEvent, this.context.timelineRenderingType, this.props.getRelationsForEvent);
editEvent(
MatrixClientPeg.get(),
this.props.mxEvent,
this.context.timelineRenderingType,
this.props.getRelationsForEvent,
);
this.closeMenu();
};
@ -617,7 +622,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
}
let editButton: JSX.Element | undefined;
if (rightClick && canEditContent(mxEvent)) {
if (rightClick && canEditContent(cli, mxEvent)) {
editButton = (
<IconizedContextMenuOption
iconClassName="mx_MessageContextMenu_iconEdit"

View File

@ -61,7 +61,7 @@ export const WidgetContextMenu: React.FC<IProps> = ({
const { room, roomId } = useContext(RoomContext);
const widgetMessaging = WidgetMessagingStore.instance.getMessagingForUid(WidgetUtils.getWidgetUid(app));
const canModify = userWidget || WidgetUtils.canUserModifyWidgets(roomId);
const canModify = userWidget || WidgetUtils.canUserModifyWidgets(cli, roomId);
let streamAudioStreamButton: JSX.Element | undefined;
if (roomId && getConfigLivestreamUrl() && WidgetType.JITSI.matches(app.type)) {
@ -138,7 +138,7 @@ export const WidgetContextMenu: React.FC<IProps> = ({
button: _t("Delete widget"),
onFinished: (confirmed) => {
if (!confirmed) return;
WidgetUtils.setRoomWidget(roomId, app.id);
WidgetUtils.setRoomWidget(cli, roomId, app.id);
},
});
}

View File

@ -75,9 +75,10 @@ export default class CreateRoomDialog extends React.Component<IProps, IState> {
joinRule = JoinRule.Restricted;
}
const cli = MatrixClientPeg.get();
this.state = {
isPublic: this.props.defaultPublic || false,
isEncrypted: this.props.defaultEncrypted ?? privateShouldBeEncrypted(),
isEncrypted: this.props.defaultEncrypted ?? privateShouldBeEncrypted(cli),
joinRule,
name: this.props.defaultName || "",
topic: "",
@ -88,9 +89,9 @@ export default class CreateRoomDialog extends React.Component<IProps, IState> {
canChangeEncryption: true,
};
MatrixClientPeg.get()
.doesServerForceEncryptionForPreset(Preset.PrivateChat)
.then((isForced) => this.setState({ canChangeEncryption: !isForced }));
cli.doesServerForceEncryptionForPreset(Preset.PrivateChat).then((isForced) =>
this.setState({ canChangeEncryption: !isForced }),
);
}
private roomCreateOptions(): IOpts {
@ -284,7 +285,7 @@ export default class CreateRoomDialog extends React.Component<IProps, IState> {
let e2eeSection: JSX.Element | undefined;
if (this.state.joinRule !== JoinRule.Public) {
let microcopy: string;
if (privateShouldBeEncrypted()) {
if (privateShouldBeEncrypted(MatrixClientPeg.get())) {
if (this.state.canChangeEncryption) {
microcopy = isVideoRoom
? _t("You can't disable this later. The room will be encrypted but the embedded call will not.")

View File

@ -407,7 +407,7 @@ export default class InviteDialog extends React.PureComponent<Props, IInviteDial
}
public componentDidMount(): void {
this.encryptionByDefault = privateShouldBeEncrypted();
this.encryptionByDefault = privateShouldBeEncrypted(MatrixClientPeg.get());
if (this.props.initialText) {
this.updateSuggestions(this.props.initialText);
@ -613,7 +613,7 @@ export default class InviteDialog extends React.PureComponent<Props, IInviteDial
}
try {
const result = await inviteMultipleToRoom(this.props.roomId, targetIds, true);
const result = await inviteMultipleToRoom(cli, this.props.roomId, targetIds, true);
if (!this.shouldAbortAfterInviteError(result, room)) {
// handles setting error message too
this.props.onFinished(true);
@ -986,7 +986,7 @@ export default class InviteDialog extends React.PureComponent<Props, IInviteDial
// Update the IS in account data. Actually using it may trigger terms.
// eslint-disable-next-line react-hooks/rules-of-hooks
setToDefaultIdentityServer();
setToDefaultIdentityServer(MatrixClientPeg.get());
this.setState({ canUseIdentityServer: true, tryingIdentityServer: false });
};
@ -1395,7 +1395,7 @@ export default class InviteDialog extends React.PureComponent<Props, IInviteDial
</a>
),
a: (sub) => (
<a href={makeRoomPermalink(roomId)} rel="noreferrer noopener" target="_blank">
<a href={makeRoomPermalink(cli, roomId)} rel="noreferrer noopener" target="_blank">
{sub}
</a>
),

View File

@ -76,7 +76,7 @@ class LocationPicker extends React.Component<ILocationPickerProps, IState> {
try {
this.map = new maplibregl.Map({
container: "mx_LocationPicker_map",
style: findMapStyleUrl(),
style: findMapStyleUrl(this.context),
center: [0, 0],
zoom: 1,
});

View File

@ -101,7 +101,7 @@ export default class EditHistoryMessage extends React.PureComponent<IProps, ISta
private pillifyLinks(): void {
// not present for redacted events
if (this.content.current) {
pillifyLinks(this.content.current.children, this.props.mxEvent, this.pills);
pillifyLinks(MatrixClientPeg.get(), this.content.current.children, this.props.mxEvent, this.pills);
}
}

View File

@ -114,16 +114,18 @@ export default class MKeyVerificationConclusion extends React.Component<IProps>
if (request.done) {
title = _t("You verified %(name)s", {
name: getNameForEventRoom(request.otherUserId, mxEvent.getRoomId()!),
name: getNameForEventRoom(client, request.otherUserId, mxEvent.getRoomId()!),
});
} else if (request.cancelled) {
const userId = request.cancellingUserId;
if (userId === myUserId) {
title = _t("You cancelled verifying %(name)s", {
name: getNameForEventRoom(request.otherUserId, mxEvent.getRoomId()!),
name: getNameForEventRoom(client, request.otherUserId, mxEvent.getRoomId()!),
});
} else if (userId) {
title = _t("%(name)s cancelled verifying", { name: getNameForEventRoom(userId, mxEvent.getRoomId()!) });
title = _t("%(name)s cancelled verifying", {
name: getNameForEventRoom(client, userId, mxEvent.getRoomId()!),
});
}
}
@ -135,7 +137,7 @@ export default class MKeyVerificationConclusion extends React.Component<IProps>
<EventTileBubble
className={classes}
title={title}
subtitle={userLabelForEventRoom(request.otherUserId, mxEvent.getRoomId()!)}
subtitle={userLabelForEventRoom(client, request.otherUserId, mxEvent.getRoomId()!)}
timestamp={this.props.timestamp}
/>
);

View File

@ -93,7 +93,9 @@ export default class MKeyVerificationRequest extends React.Component<IProps> {
if (userId === myUserId) {
return _t("You accepted");
} else {
return _t("%(name)s accepted", { name: getNameForEventRoom(userId, this.props.mxEvent.getRoomId()!) });
return _t("%(name)s accepted", {
name: getNameForEventRoom(client, userId, this.props.mxEvent.getRoomId()!),
});
}
}
@ -110,14 +112,19 @@ export default class MKeyVerificationRequest extends React.Component<IProps> {
}
} else {
if (declined) {
return _t("%(name)s declined", { name: getNameForEventRoom(userId, this.props.mxEvent.getRoomId()!) });
return _t("%(name)s declined", {
name: getNameForEventRoom(client, userId, this.props.mxEvent.getRoomId()!),
});
} else {
return _t("%(name)s cancelled", { name: getNameForEventRoom(userId, this.props.mxEvent.getRoomId()!) });
return _t("%(name)s cancelled", {
name: getNameForEventRoom(client, userId, this.props.mxEvent.getRoomId()!),
});
}
}
}
public render(): React.ReactNode {
const client = MatrixClientPeg.get();
const { mxEvent } = this.props;
const request = mxEvent.verificationRequest;
@ -149,9 +156,9 @@ export default class MKeyVerificationRequest extends React.Component<IProps> {
}
if (!request.initiatedByMe) {
const name = getNameForEventRoom(request.requestingUserId, mxEvent.getRoomId()!);
const name = getNameForEventRoom(client, request.requestingUserId, mxEvent.getRoomId()!);
title = _t("%(name)s wants to verify", { name });
subtitle = userLabelForEventRoom(request.requestingUserId, mxEvent.getRoomId()!);
subtitle = userLabelForEventRoom(client, request.requestingUserId, mxEvent.getRoomId()!);
if (request.canAccept) {
stateNode = (
<div className="mx_cryptoEvent_buttons">
@ -167,7 +174,7 @@ export default class MKeyVerificationRequest extends React.Component<IProps> {
} else {
// request sent by us
title = _t("You sent a verification request");
subtitle = userLabelForEventRoom(request.receivingUserId, mxEvent.getRoomId()!);
subtitle = userLabelForEventRoom(client, request.receivingUserId, mxEvent.getRoomId()!);
}
if (title) {

View File

@ -363,7 +363,12 @@ export default class MessageActionBar extends React.PureComponent<IMessageAction
e.preventDefault();
e.stopPropagation();
editEvent(this.props.mxEvent, this.context.timelineRenderingType, this.props.getRelationsForEvent);
editEvent(
MatrixClientPeg.get(),
this.props.mxEvent,
this.context.timelineRenderingType,
this.props.getRelationsForEvent,
);
};
private readonly forbiddenThreadHeadMsgType = [MsgType.KeyVerificationRequest];
@ -424,7 +429,7 @@ export default class MessageActionBar extends React.PureComponent<IMessageAction
public render(): React.ReactNode {
const toolbarOpts: JSX.Element[] = [];
if (canEditContent(this.props.mxEvent)) {
if (canEditContent(MatrixClientPeg.get(), this.props.mxEvent)) {
toolbarOpts.push(
<RovingAccessibleTooltipButton
className="mx_MessageActionBar_iconButton"

View File

@ -48,6 +48,7 @@ import { options as linkifyOpts } from "../../../linkify-matrix";
import { getParentEventId } from "../../../utils/Reply";
import { EditWysiwygComposer } from "../rooms/wysiwyg_composer";
import { IEventTileOps } from "../rooms/EventTile";
import { MatrixClientPeg } from "../../../MatrixClientPeg";
const MAX_HIGHLIGHT_LENGTH = 4096;
@ -92,7 +93,7 @@ export default class TextualBody extends React.Component<IBodyProps, IState> {
this.activateSpoilers([content]);
HtmlUtils.linkifyElement(content);
pillifyLinks([content], this.props.mxEvent, this.pills);
pillifyLinks(MatrixClientPeg.get(), [content], this.props.mxEvent, this.pills);
this.calculateUrlPreview();

View File

@ -108,8 +108,8 @@ const AppRow: React.FC<IAppRowProps> = ({ app, room }) => {
const [canModifyWidget, setCanModifyWidget] = useState<boolean>();
useEffect(() => {
setCanModifyWidget(WidgetUtils.canUserModifyWidgets(room.roomId));
}, [room.roomId]);
setCanModifyWidget(WidgetUtils.canUserModifyWidgets(room.client, room.roomId));
}, [room.client, room.roomId]);
const onOpenWidgetClick = (): void => {
RightPanelStore.instance.pushCard({

View File

@ -456,7 +456,7 @@ export const UserOptionsSection: React.FC<{
const onInviteUserButton = async (ev: ButtonEvent): Promise<void> => {
try {
// We use a MultiInviter to re-use the invite logic, even though we're only inviting one user.
const inviter = new MultiInviter(roomId || "");
const inviter = new MultiInviter(cli, roomId || "");
await inviter.invite([member.userId]).then(() => {
if (inviter.getCompletionState(member.userId) !== "invited") {
const errorStringFromInviterUtility = inviter.getErrorText(member.userId);

View File

@ -50,6 +50,7 @@ import { editorRoomKey, editorStateKey } from "../../../Editing";
import DocumentOffset from "../../../editor/offset";
import { attachMentions, attachRelation } from "./SendMessageComposer";
import { filterBoolean } from "../../../utils/arrays";
import { MatrixClientPeg } from "../../../MatrixClientPeg";
function getHtmlReplyFallback(mxEvent: MatrixEvent): string {
const html = mxEvent.getContent().formatted_body;
@ -184,6 +185,7 @@ class EditMessageComposer extends React.Component<IEditMessageComposerProps, ISt
events: this.events,
isForward: false,
fromEventId: this.props.editState.getEvent().getId(),
matrixClient: MatrixClientPeg.get(),
});
if (previousEvent) {
dis.dispatch({
@ -203,6 +205,7 @@ class EditMessageComposer extends React.Component<IEditMessageComposerProps, ISt
events: this.events,
isForward: true,
fromEventId: this.props.editState.getEvent().getId(),
matrixClient: MatrixClientPeg.get(),
});
if (nextEvent) {
dis.dispatch({

View File

@ -34,7 +34,6 @@ import dis from "../../../dispatcher/dispatcher";
import { Layout } from "../../../settings/enums/Layout";
import { formatTime } from "../../../DateUtils";
import { MatrixClientPeg } from "../../../MatrixClientPeg";
import MatrixClientContext from "../../../contexts/MatrixClientContext";
import { DecryptionFailureBody } from "../messages/DecryptionFailureBody";
import { E2EState } from "./E2EIcon";
import RoomAvatar from "../avatars/RoomAvatar";
@ -267,7 +266,7 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
private unmounted = false;
public constructor(props: EventTileProps, context: React.ContextType<typeof MatrixClientContext>) {
public constructor(props: EventTileProps, context: React.ContextType<typeof RoomContext>) {
super(props, context);
const thread = this.thread;
@ -904,7 +903,12 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
isLeftAlignedBubbleMessage,
noBubbleEvent,
isSeeingThroughMessageHiddenForModeration,
} = getEventDisplayInfo(this.props.mxEvent, this.context.showHiddenEvents, this.shouldHideEvent());
} = getEventDisplayInfo(
MatrixClientPeg.get(),
this.props.mxEvent,
this.context.showHiddenEvents,
this.shouldHideEvent(),
);
const { isQuoteExpanded } = this.state;
// This shouldn't happen: the caller should check we support this type
// before trying to instantiate us

View File

@ -527,7 +527,7 @@ export class MessageComposer extends React.Component<IProps, IState> {
const continuesLink = replacementRoomId ? (
<a
href={makeRoomPermalink(replacementRoomId)}
href={makeRoomPermalink(MatrixClientPeg.get(), replacementRoomId)}
className="mx_MessageComposer_roomReplaced_link"
onClick={this.onTombstoneClick}
>

View File

@ -44,7 +44,7 @@ import { shouldEncryptRoomWithSingle3rdPartyInvite } from "../../../utils/room/s
function hasExpectedEncryptionSettings(matrixClient: MatrixClient, room: Room): boolean {
const isEncrypted: boolean = matrixClient.isRoomEncrypted(room.roomId);
const isPublic: boolean = room.getJoinRule() === "public";
return isPublic || !privateShouldBeEncrypted() || isEncrypted;
return isPublic || !privateShouldBeEncrypted(matrixClient) || isEncrypted;
}
const determineIntroMessage = (room: Room, encryptedSingle3rdPartyInvite: boolean): string => {

View File

@ -34,6 +34,7 @@ import MVoiceMessageBody from "../messages/MVoiceMessageBody";
import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload";
import { renderReplyTile } from "../../../events/EventTileFactory";
import { GetRelationsForEvent } from "../rooms/EventTile";
import { MatrixClientPeg } from "../../../MatrixClientPeg";
interface IProps {
mxEvent: MatrixEvent;
@ -110,6 +111,7 @@ export default class ReplyTile extends React.PureComponent<IProps> {
const evType = mxEvent.getType();
const { hasRenderer, isInfoMessage, isSeeingThroughMessageHiddenForModeration } = getEventDisplayInfo(
MatrixClientPeg.get(),
mxEvent,
false /* Replies are never hidden, so this should be fine */,
);

View File

@ -335,6 +335,7 @@ export class SendMessageComposer extends React.Component<ISendMessageComposerPro
? findEditableEvent({
events,
isForward: false,
matrixClient: MatrixClientPeg.get(),
})
: undefined;
if (editEvent) {

View File

@ -123,7 +123,7 @@ export default class Stickerpicker extends React.PureComponent<IProps, IState> {
}
this.props.setStickerPickerOpen(false);
WidgetUtils.removeStickerpickerWidgets()
WidgetUtils.removeStickerpickerWidgets(this.props.room.client)
.then(() => {
this.forceUpdate();
})
@ -169,7 +169,7 @@ export default class Stickerpicker extends React.PureComponent<IProps, IState> {
}
private updateWidget = (): void => {
const stickerpickerWidget = WidgetUtils.getStickerpickerWidgets()[0];
const stickerpickerWidget = WidgetUtils.getStickerpickerWidgets(this.props.room.client)[0];
if (!stickerpickerWidget) {
Stickerpicker.currentWidget = undefined;
this.setState({ stickerpickerWidget: null, widgetId: null });

View File

@ -146,8 +146,10 @@ export default class VoiceRecordComposerTile extends React.PureComponent<IProps,
});
}
doMaybeLocalRoomAction(this.props.room.roomId, (actualRoomId: string) =>
MatrixClientPeg.get().sendMessage(actualRoomId, content),
doMaybeLocalRoomAction(
this.props.room.roomId,
(actualRoomId: string) => MatrixClientPeg.get().sendMessage(actualRoomId, content),
this.props.room.client,
);
} catch (e) {
logger.error("Error sending voice message:", e);

View File

@ -185,6 +185,7 @@ function dispatchEditEvent(
events: foundEvents,
isForward,
fromEventId: editorStateTransfer?.getEvent().getId(),
matrixClient: mxClient,
});
if (newEvent) {
dis.dispatch({

View File

@ -419,7 +419,7 @@ export default class SecureBackupPanel extends React.PureComponent<{}, IState> {
</AccessibleButton>,
);
if (!isSecureBackupRequired()) {
if (!isSecureBackupRequired(MatrixClientPeg.get())) {
actions.push(
<AccessibleButton key="delete" kind="danger" onClick={this.deleteBackup}>
{_t("Delete Backup")}

View File

@ -179,7 +179,7 @@ export default class SetIdServer extends React.Component<IProps, IState> {
let save = true;
// Double check that the identity server even has terms of service.
const hasTerms = await doesIdentityServerHaveTerms(fullUrl);
const hasTerms = await doesIdentityServerHaveTerms(MatrixClientPeg.get(), fullUrl);
if (!hasTerms) {
const [confirmed] = await this.showNoTermsWarning(fullUrl);
save = !!confirmed;

View File

@ -316,7 +316,7 @@ export default class SecurityUserSettingsTab extends React.Component<IProps, ISt
);
let warning;
if (!privateShouldBeEncrypted()) {
if (!privateShouldBeEncrypted(MatrixClientPeg.get())) {
warning = (
<div className="mx_SecurityUserSettingsTab_warning">
{_t(

View File

@ -165,7 +165,7 @@ export default class VerificationRequestToast extends React.PureComponent<IProps
} else {
const userId = request.otherUserId;
const roomId = request.channel.roomId;
description = roomId ? userLabelForEventRoom(userId, roomId) : userId;
description = roomId ? userLabelForEventRoom(MatrixClientPeg.get(), userId, roomId) : userId;
// for legacy to_device verification requests
if (description === userId) {
const client = MatrixClientPeg.get();

View File

@ -30,6 +30,7 @@ import EmbeddedPage from "../../structures/EmbeddedPage";
import HomePage from "../../structures/HomePage";
import { UserOnboardingHeader } from "./UserOnboardingHeader";
import { UserOnboardingList } from "./UserOnboardingList";
import { useMatrixClientContext } from "../../../contexts/MatrixClientContext";
interface Props {
justRegistered?: boolean;
@ -44,8 +45,9 @@ export function showUserOnboardingPage(useCase: UseCase | null): boolean {
const ANIMATION_DURATION = 2800;
export function UserOnboardingPage({ justRegistered = false }: Props): JSX.Element {
const cli = useMatrixClientContext();
const config = SdkConfig.get();
const pageUrl = getHomePageUrl(config);
const pageUrl = getHomePageUrl(config, cli);
const useCase = useSettingValue<UseCase | null>("FTUE.useCaseSelection");
const context = useUserOnboardingContext();

View File

@ -36,7 +36,7 @@ export interface MatrixClientProps {
mxClient: MatrixClient;
}
export function useMatrixClientContext(): MatrixClient | undefined {
export function useMatrixClientContext(): MatrixClient {
return useContext(MatrixClientContext);
}

View File

@ -462,7 +462,7 @@ export async function ensureDMExists(client: MatrixClient, userId: string): Prom
roomId = existingDMRoom.roomId;
} else {
let encryption: boolean | undefined;
if (privateShouldBeEncrypted()) {
if (privateShouldBeEncrypted(client)) {
encryption = await canEncryptToAllUsers(client, [userId]);
}

View File

@ -115,7 +115,7 @@ export class IntegrationManagers {
private setupAccountManagers(): void {
if (!this.client || !this.client.getUserId()) return; // not logged in
const widgets = WidgetUtils.getIntegrationManagerWidgets();
const widgets = WidgetUtils.getIntegrationManagerWidgets(this.client);
widgets.forEach((w) => {
const data = w.content["data"];
if (!data) return;
@ -180,14 +180,6 @@ export class IntegrationManagers {
Modal.createDialog(IntegrationsDisabledDialog);
}
public async overwriteManagerOnAccount(manager: IntegrationManagerInstance): Promise<void> {
// TODO: TravisR - We should be logging out of scalar clients.
await WidgetUtils.removeIntegrationManagerWidgets();
// TODO: TravisR - We should actually be carrying over the discovery response verbatim.
await WidgetUtils.addIntegrationManagerWidget(manager.name, manager.uiUrl, manager.apiUrl);
}
/**
* Attempts to discover an integration manager using only its name. This will not validate that
* the integration manager is functional - that is the caller's responsibility.

View File

@ -30,6 +30,7 @@ import dis from "./dispatcher/dispatcher";
import { Action } from "./dispatcher/actions";
import { ViewUserPayload } from "./dispatcher/payloads/ViewUserPayload";
import { ViewRoomPayload } from "./dispatcher/payloads/ViewRoomPayload";
import { MatrixClientPeg } from "./MatrixClientPeg";
export enum Type {
URL = "url",
@ -196,7 +197,7 @@ export const options: Opts = {
case Type.RoomAlias:
case Type.UserId:
default: {
return tryTransformEntityToPermalink(href) ?? "";
return tryTransformEntityToPermalink(MatrixClientPeg.get(), href) ?? "";
}
}
},

View File

@ -342,7 +342,7 @@ export class JitsiCall extends Call {
}
public static async create(room: Room): Promise<void> {
await WidgetUtils.addJitsiWidget(room.roomId, CallType.Video, "Group call", true, room.name);
await WidgetUtils.addJitsiWidget(room.client, room.roomId, CallType.Video, "Group call", true, room.name);
}
private updateParticipants(): void {

View File

@ -22,7 +22,6 @@ import { EventType } from "matrix-js-sdk/src/@types/event";
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import { Optional } from "matrix-events-sdk";
import { MatrixClientPeg } from "../MatrixClientPeg";
import { filterValidMDirect } from "./dm/filterValidMDirect";
/**
@ -53,8 +52,8 @@ export default class DMRoomMap {
* Makes and returns a new shared instance that can then be accessed
* with shared(). This returned instance is not automatically started.
*/
public static makeShared(): DMRoomMap {
DMRoomMap.sharedInstance = new DMRoomMap(MatrixClientPeg.get());
public static makeShared(matrixClient: MatrixClient): DMRoomMap {
DMRoomMap.sharedInstance = new DMRoomMap(matrixClient);
return DMRoomMap.sharedInstance;
}
@ -175,7 +174,7 @@ export default class DMRoomMap {
}
const joinedRooms = commonRooms
.map((r) => MatrixClientPeg.get().getRoom(r))
.map((r) => this.matrixClient.getRoom(r))
.filter((r) => r && r.getMyMembership() === "join");
return joinedRooms[0];

View File

@ -16,13 +16,13 @@ limitations under the License.
import classnames from "classnames";
import { ComponentProps } from "react";
import { MatrixClient } from "matrix-js-sdk/src/matrix";
import defaultDispatcher from "../dispatcher/dispatcher";
import { ActionPayload } from "../dispatcher/payloads";
import Modal from "../Modal";
import RoomSettingsDialog from "../components/views/dialogs/RoomSettingsDialog";
import ForwardDialog from "../components/views/dialogs/ForwardDialog";
import { MatrixClientPeg } from "../MatrixClientPeg";
import { Action } from "../dispatcher/actions";
import ReportEventDialog from "../components/views/dialogs/ReportEventDialog";
import SpacePreferencesDialog from "../components/views/dialogs/SpacePreferencesDialog";
@ -43,18 +43,21 @@ export class DialogOpener {
public static readonly instance = new DialogOpener();
private isRegistered = false;
private matrixClient?: MatrixClient;
private constructor() {}
// We could do this in the constructor, but then we wouldn't have
// a function to call from Lifecycle to capture the class.
public prepare(): void {
public prepare(matrixClient: MatrixClient): void {
this.matrixClient = matrixClient;
if (this.isRegistered) return;
defaultDispatcher.register(this.onDispatch);
this.isRegistered = true;
}
private onDispatch = (payload: ActionPayload): void => {
if (!this.matrixClient) return;
switch (payload.action) {
case "open_room_settings":
Modal.createDialog(
@ -70,7 +73,7 @@ export class DialogOpener {
break;
case Action.OpenForwardDialog:
Modal.createDialog(ForwardDialog, {
matrixClient: MatrixClientPeg.get(),
matrixClient: this.matrixClient,
event: payload.event,
permalinkCreator: payload.permalinkCreator,
});

View File

@ -18,11 +18,10 @@ import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import { EventType, MsgType } from "matrix-js-sdk/src/@types/event";
import { M_POLL_END, M_POLL_START } from "matrix-js-sdk/src/@types/polls";
import { M_BEACON_INFO } from "matrix-js-sdk/src/@types/beacon";
import { IContent } from "matrix-js-sdk/src/matrix";
import { IContent, MatrixClient } from "matrix-js-sdk/src/matrix";
import SettingsStore from "../settings/SettingsStore";
import { haveRendererForEvent, JitsiEventFactory, JSONEventFactory, pickFactory } from "../events/EventTileFactory";
import { MatrixClientPeg } from "../MatrixClientPeg";
import { getMessageModerationState, isLocationEvent, MessageModerationState } from "./EventUtils";
import { ElementCall } from "../models/Call";
import { VoiceBroadcastInfoEventType, VoiceBroadcastInfoState } from "../voice-broadcast";
@ -48,6 +47,7 @@ const calcIsInfoMessage = (
};
export function getEventDisplayInfo(
matrixClient: MatrixClient,
mxEvent: MatrixEvent,
showHiddenEvents: boolean,
hideEvent?: boolean,
@ -65,7 +65,7 @@ export function getEventDisplayInfo(
let isSeeingThroughMessageHiddenForModeration = false;
if (SettingsStore.getValue("feature_msc3531_hide_messages_pending_moderation")) {
switch (getMessageModerationState(mxEvent)) {
switch (getMessageModerationState(mxEvent, matrixClient)) {
case MessageModerationState.VISIBLE_FOR_ALL:
case MessageModerationState.HIDDEN_TO_CURRENT_USER:
// Nothing specific to do here
@ -77,8 +77,7 @@ export function getEventDisplayInfo(
}
}
// TODO: Thread a MatrixClient through to here
let factory = pickFactory(mxEvent, MatrixClientPeg.get(), showHiddenEvents);
let factory = pickFactory(mxEvent, matrixClient, showHiddenEvents);
// Info messages are basically information about commands processed on a room
let isBubbleMessage =
@ -103,10 +102,8 @@ export function getEventDisplayInfo(
// replace relations (which otherwise would display as a confusing
// duplicate of the thing they are replacing).
if (hideEvent || !haveRendererForEvent(mxEvent, showHiddenEvents)) {
// forcefully ask for a factory for a hidden event (hidden event
// setting is checked internally)
// TODO: Thread a MatrixClient through to here
factory = pickFactory(mxEvent, MatrixClientPeg.get(), showHiddenEvents, true);
// forcefully ask for a factory for a hidden event (hidden event setting is checked internally)
factory = pickFactory(mxEvent, matrixClient, showHiddenEvents, true);
if (factory === JSONEventFactory) {
isBubbleMessage = false;
// Reuse info message avatar and sender profile styling

View File

@ -23,7 +23,6 @@ import { M_LOCATION } from "matrix-js-sdk/src/@types/location";
import { M_BEACON_INFO } from "matrix-js-sdk/src/@types/beacon";
import { THREAD_RELATION_TYPE } from "matrix-js-sdk/src/models/thread";
import { MatrixClientPeg } from "../MatrixClientPeg";
import shouldHideEvent from "../shouldHideEvent";
import { GetRelationsForEvent } from "../components/views/rooms/EventTile";
import SettingsStore from "../settings/SettingsStore";
@ -69,7 +68,7 @@ export function isContentActionable(mxEvent: MatrixEvent): boolean {
return false;
}
export function canEditContent(mxEvent: MatrixEvent): boolean {
export function canEditContent(matrixClient: MatrixClient, mxEvent: MatrixEvent): boolean {
const isCancellable = mxEvent.getType() === EventType.RoomMessage || M_POLL_START.matches(mxEvent.getType());
if (
@ -77,7 +76,7 @@ export function canEditContent(mxEvent: MatrixEvent): boolean {
mxEvent.status === EventStatus.CANCELLED ||
mxEvent.isRedacted() ||
mxEvent.isRelation(RelationType.Replace) ||
mxEvent.getSender() !== MatrixClientPeg.get().getUserId()
mxEvent.getSender() !== matrixClient.getUserId()
) {
return false;
}
@ -89,22 +88,24 @@ export function canEditContent(mxEvent: MatrixEvent): boolean {
);
}
export function canEditOwnEvent(mxEvent: MatrixEvent): boolean {
export function canEditOwnEvent(matrixClient: MatrixClient, mxEvent: MatrixEvent): boolean {
// for now we only allow editing
// your own events. So this just call through
// In the future though, moderators will be able to
// edit other people's messages as well but we don't
// want findEditableEvent to return other people's events
// hence this method.
return canEditContent(mxEvent);
return canEditContent(matrixClient, mxEvent);
}
const MAX_JUMP_DISTANCE = 100;
export function findEditableEvent({
matrixClient,
events,
isForward,
fromEventId,
}: {
matrixClient: MatrixClient;
events: MatrixEvent[];
isForward: boolean;
fromEventId?: string;
@ -126,7 +127,7 @@ export function findEditableEvent({
// don't look further than MAX_JUMP_DISTANCE events from `fromEventId`
// to not iterate potentially 1000nds of events on key up/down
endIdx = Math.min(Math.max(0, i + inc * MAX_JUMP_DISTANCE), maxIdx);
} else if (foundFromEventId && !shouldHideEvent(e) && canEditOwnEvent(e)) {
} else if (foundFromEventId && !shouldHideEvent(e) && canEditOwnEvent(matrixClient, e)) {
// otherwise look for editable event
return e;
}
@ -170,9 +171,7 @@ const getMsc3531Enabled = (): boolean => {
* If MSC3531 is deactivated in settings, all messages are considered visible
* to all.
*/
export function getMessageModerationState(mxEvent: MatrixEvent, client?: MatrixClient): MessageModerationState {
client = client ?? MatrixClientPeg.get(); // because param defaults don't do the correct thing
export function getMessageModerationState(mxEvent: MatrixEvent, client: MatrixClient): MessageModerationState {
if (!getMsc3531Enabled()) {
return MessageModerationState.VISIBLE_FOR_ALL;
}
@ -246,11 +245,12 @@ export async function fetchInitialEvent(
}
export function editEvent(
matrixClient: MatrixClient,
mxEvent: MatrixEvent,
timelineRenderingType: TimelineRenderingType,
getRelationsForEvent?: GetRelationsForEvent,
): void {
if (!canEditContent(mxEvent)) return;
if (!canEditContent(matrixClient, mxEvent)) return;
if (M_POLL_START.matches(mxEvent.getType())) {
launchPollEditor(mxEvent, getRelationsForEvent);

View File

@ -17,27 +17,27 @@ limitations under the License.
import { SERVICE_TYPES } from "matrix-js-sdk/src/service-types";
import { logger } from "matrix-js-sdk/src/logger";
import { HTTPError } from "matrix-js-sdk/src/http-api";
import { MatrixClient } from "matrix-js-sdk/src/matrix";
import SdkConfig from "../SdkConfig";
import { MatrixClientPeg } from "../MatrixClientPeg";
import { Policies } from "../Terms";
export function getDefaultIdentityServerUrl(): string | undefined {
return SdkConfig.get("validated_server_config")?.isUrl;
}
export function setToDefaultIdentityServer(): void {
export function setToDefaultIdentityServer(matrixClient: MatrixClient): void {
const url = getDefaultIdentityServerUrl();
// Account data change will update localstorage, client, etc through dispatcher
MatrixClientPeg.get().setAccountData("m.identity_server", {
matrixClient.setAccountData("m.identity_server", {
base_url: url,
});
}
export async function doesIdentityServerHaveTerms(fullUrl: string): Promise<boolean> {
export async function doesIdentityServerHaveTerms(matrixClient: MatrixClient, fullUrl: string): Promise<boolean> {
let terms: { policies?: Policies } | null;
try {
terms = await MatrixClientPeg.get().getTerms(SERVICE_TYPES.IS, fullUrl);
terms = await matrixClient.getTerms(SERVICE_TYPES.IS, fullUrl);
} catch (e) {
logger.error(e);
if (e.cors === "rejected" || (e instanceof HTTPError && e.httpStatus === 404)) {
@ -50,7 +50,7 @@ export async function doesIdentityServerHaveTerms(fullUrl: string): Promise<bool
return !!terms?.["policies"] && Object.keys(terms["policies"]).length > 0;
}
export function doesAccountDataHaveIdentityServer(): boolean {
const event = MatrixClientPeg.get().getAccountData("m.identity_server");
return event && event.getContent() && event.getContent()["base_url"];
export function doesAccountDataHaveIdentityServer(matrixClient: MatrixClient): boolean {
const event = matrixClient.getAccountData("m.identity_server");
return event?.getContent()["base_url"];
}

View File

@ -14,18 +14,18 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import { MatrixClientPeg } from "../MatrixClientPeg";
import { MatrixClient } from "matrix-js-sdk/src/matrix";
import { _t } from "../languageHandler";
export function getNameForEventRoom(userId: string, roomId: string): string {
const client = MatrixClientPeg.get();
const room = client.getRoom(roomId);
export function getNameForEventRoom(matrixClient: MatrixClient, userId: string, roomId: string): string {
const room = matrixClient.getRoom(roomId);
const member = room && room.getMember(userId);
return member ? member.name : userId;
}
export function userLabelForEventRoom(userId: string, roomId: string): string {
const name = getNameForEventRoom(userId, roomId);
export function userLabelForEventRoom(matrixClient: MatrixClient, userId: string, roomId: string): string {
const name = getNameForEventRoom(matrixClient, userId, roomId);
if (name !== userId) {
return _t("%(name)s (%(userId)s)", { name, userId });
} else {

View File

@ -21,7 +21,6 @@ import { MatrixClient } from "matrix-js-sdk/src/client";
import { EventType } from "matrix-js-sdk/src/@types/event";
import { HistoryVisibility } from "matrix-js-sdk/src/@types/partials";
import { MatrixClientPeg } from "../MatrixClientPeg";
import { AddressType, getAddressType } from "../UserAddress";
import { _t } from "../languageHandler";
import Modal from "../Modal";
@ -54,8 +53,6 @@ const USER_ALREADY_INVITED = "IO.ELEMENT.ALREADY_INVITED";
* Invites multiple addresses to a room, handling rate limiting from the server
*/
export default class MultiInviter {
private readonly matrixClient: MatrixClient;
private canceled = false;
private addresses: string[] = [];
private busy = false;
@ -66,12 +63,15 @@ export default class MultiInviter {
private reason: string | undefined;
/**
* @param matrixClient the client of the logged in user
* @param {string} roomId The ID of the room to invite to
* @param {function} progressCallback optional callback, fired after each invite.
*/
public constructor(private roomId: string, private readonly progressCallback?: () => void) {
this.matrixClient = MatrixClientPeg.get();
}
public constructor(
private readonly matrixClient: MatrixClient,
private roomId: string,
private readonly progressCallback?: () => void,
) {}
public get fatal(): boolean {
return this._fatal;

View File

@ -15,8 +15,8 @@ limitations under the License.
*/
import zxcvbn, { ZXCVBNFeedbackWarning } from "zxcvbn";
import { MatrixClient } from "matrix-js-sdk/src/matrix";
import { MatrixClientPeg } from "../MatrixClientPeg";
import { _t, _td } from "../languageHandler";
const ZXCVBN_USER_INPUTS = ["riot", "matrix"];
@ -58,14 +58,15 @@ _td("Short keyboard patterns are easy to guess");
* (obviously) which is large.
*
* @param {string} password Password to score
* @param matrixClient the client of the logged in user, if any
* @returns {object} Score result with `score` and `feedback` properties
*/
export function scorePassword(password: string): zxcvbn.ZXCVBNResult | null {
export function scorePassword(matrixClient: MatrixClient | undefined, password: string): zxcvbn.ZXCVBNResult | null {
if (password.length === 0) return null;
const userInputs = ZXCVBN_USER_INPUTS.slice();
if (MatrixClientPeg.get()) {
userInputs.push(MatrixClientPeg.get().getUserIdLocalpart()!);
if (matrixClient) {
userInputs.push(matrixClient.getUserIdLocalpart()!);
}
let zxcvbnResult = zxcvbn(password, userInputs);

View File

@ -118,7 +118,7 @@ export async function upgradeRoom(
if (toInvite.length > 0) {
// Errors are handled internally to this function
await inviteUsersToRoom(newRoomId, toInvite, false, () => {
await inviteUsersToRoom(cli, newRoomId, toInvite, false, () => {
progress.inviteUsersProgress!++;
progressCallback?.(progress);
});

View File

@ -14,11 +14,9 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import { IClientWellKnown } from "matrix-js-sdk/src/client";
import { IClientWellKnown, MatrixClient } from "matrix-js-sdk/src/client";
import { UnstableValue } from "matrix-js-sdk/src/NamespacedValue";
import { MatrixClientPeg } from "../MatrixClientPeg";
const CALL_BEHAVIOUR_WK_KEY = "io.element.call_behaviour";
const E2EE_WK_KEY = "io.element.e2ee";
const E2EE_WK_KEY_DEPRECATED = "im.vector.riot.e2ee";
@ -45,13 +43,13 @@ export interface IEmbeddedPagesWellKnown {
}
/* eslint-enable camelcase */
export function getCallBehaviourWellKnown(): ICallBehaviourWellKnown {
const clientWellKnown = MatrixClientPeg.get().getClientWellKnown();
export function getCallBehaviourWellKnown(matrixClient: MatrixClient): ICallBehaviourWellKnown {
const clientWellKnown = matrixClient.getClientWellKnown();
return clientWellKnown?.[CALL_BEHAVIOUR_WK_KEY];
}
export function getE2EEWellKnown(): IE2EEWellKnown | null {
const clientWellKnown = MatrixClientPeg.get().getClientWellKnown();
export function getE2EEWellKnown(matrixClient: MatrixClient): IE2EEWellKnown | null {
const clientWellKnown = matrixClient.getClientWellKnown();
if (clientWellKnown?.[E2EE_WK_KEY]) {
return clientWellKnown[E2EE_WK_KEY];
}
@ -61,24 +59,24 @@ export function getE2EEWellKnown(): IE2EEWellKnown | null {
return null;
}
export function getTileServerWellKnown(): ITileServerWellKnown | undefined {
return tileServerFromWellKnown(MatrixClientPeg.get().getClientWellKnown());
export function getTileServerWellKnown(matrixClient: MatrixClient): ITileServerWellKnown | undefined {
return tileServerFromWellKnown(matrixClient.getClientWellKnown());
}
export function tileServerFromWellKnown(clientWellKnown?: IClientWellKnown | undefined): ITileServerWellKnown {
return clientWellKnown?.[TILE_SERVER_WK_KEY.name] ?? clientWellKnown?.[TILE_SERVER_WK_KEY.altName];
}
export function getEmbeddedPagesWellKnown(): IEmbeddedPagesWellKnown | undefined {
return embeddedPagesFromWellKnown(MatrixClientPeg.get()?.getClientWellKnown());
export function getEmbeddedPagesWellKnown(matrixClient: MatrixClient | undefined): IEmbeddedPagesWellKnown | undefined {
return embeddedPagesFromWellKnown(matrixClient?.getClientWellKnown());
}
export function embeddedPagesFromWellKnown(clientWellKnown?: IClientWellKnown): IEmbeddedPagesWellKnown {
return clientWellKnown?.[EMBEDDED_PAGES_WK_PROPERTY];
}
export function isSecureBackupRequired(): boolean {
return getE2EEWellKnown()?.["secure_backup_required"] === true;
export function isSecureBackupRequired(matrixClient: MatrixClient): boolean {
return getE2EEWellKnown(matrixClient)?.["secure_backup_required"] === true;
}
export enum SecureBackupSetupMethod {
@ -86,8 +84,8 @@ export enum SecureBackupSetupMethod {
Passphrase = "passphrase",
}
export function getSecureBackupSetupMethods(): SecureBackupSetupMethod[] {
const wellKnown = getE2EEWellKnown();
export function getSecureBackupSetupMethods(matrixClient: MatrixClient): SecureBackupSetupMethod[] {
const wellKnown = getE2EEWellKnown(matrixClient);
if (
!wellKnown ||
!wellKnown["secure_backup_setup_methods"] ||

View File

@ -20,11 +20,10 @@ import { IWidget, IWidgetData } from "matrix-widget-api";
import { Room } from "matrix-js-sdk/src/models/room";
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import { logger } from "matrix-js-sdk/src/logger";
import { ClientEvent, RoomStateEvent } from "matrix-js-sdk/src/matrix";
import { ClientEvent, MatrixClient, RoomStateEvent } from "matrix-js-sdk/src/matrix";
import { CallType } from "matrix-js-sdk/src/webrtc/call";
import { randomString, randomLowercaseString, randomUppercaseString } from "matrix-js-sdk/src/randomstring";
import { MatrixClientPeg } from "../MatrixClientPeg";
import PlatformPeg from "../PlatformPeg";
import SdkConfig from "../SdkConfig";
import dis from "../dispatcher/dispatcher";
@ -55,19 +54,20 @@ export interface UserWidget extends Omit<IWidgetEvent, "content"> {
}
export default class WidgetUtils {
/* Returns true if user is able to send state events to modify widgets in this room
/**
* Returns true if user is able to send state events to modify widgets in this room
* (Does not apply to non-room-based / user widgets)
* @param client The matrix client of the logged-in user
* @param roomId -- The ID of the room to check
* @return Boolean -- true if the user can modify widgets in this room
* @throws Error -- specifies the error reason
*/
public static canUserModifyWidgets(roomId?: string): boolean {
public static canUserModifyWidgets(client: MatrixClient, roomId?: string): boolean {
if (!roomId) {
logger.warn("No room ID specified");
return false;
}
const client = MatrixClientPeg.get();
if (!client) {
logger.warn("User must be be logged in");
return false;
@ -79,7 +79,7 @@ export default class WidgetUtils {
return false;
}
const me = client.credentials.userId;
const me = client.getUserId();
if (!me) {
logger.warn("Failed to get user ID");
return false;
@ -97,6 +97,7 @@ export default class WidgetUtils {
// TODO: Generify the name of this function. It's not just scalar.
/**
* Returns true if specified url is a scalar URL, typically https://scalar.vector.im/api
* @param matrixClient The matrix client of the logged-in user
* @param {[type]} testUrlString URL to check
* @return {Boolean} True if specified URL is a scalar URL
*/
@ -138,13 +139,14 @@ export default class WidgetUtils {
* ID has been added as a user widget (ie. the accountData event
* arrives) or rejects after a timeout
*
* @param {string} widgetId The ID of the widget to wait for
* @param {boolean} add True to wait for the widget to be added,
* @param client The matrix client of the logged-in user
* @param widgetId The ID of the widget to wait for
* @param add True to wait for the widget to be added,
* false to wait for it to be deleted.
* @returns {Promise} that resolves when the widget is in the
* requested state according to the `add` param
*/
public static waitForUserWidget(widgetId: string, add: boolean): Promise<void> {
public static waitForUserWidget(client: MatrixClient, widgetId: string, add: boolean): Promise<void> {
return new Promise((resolve, reject) => {
// Tests an account data event, returning true if it's in the state
// we're waiting for it to be in
@ -157,25 +159,25 @@ export default class WidgetUtils {
}
}
const startingAccountDataEvent = MatrixClientPeg.get().getAccountData("m.widgets");
const startingAccountDataEvent = client.getAccountData("m.widgets");
if (eventInIntendedState(startingAccountDataEvent)) {
resolve();
return;
}
function onAccountData(ev: MatrixEvent): void {
const currentAccountDataEvent = MatrixClientPeg.get().getAccountData("m.widgets");
const currentAccountDataEvent = client.getAccountData("m.widgets");
if (eventInIntendedState(currentAccountDataEvent)) {
MatrixClientPeg.get().removeListener(ClientEvent.AccountData, onAccountData);
client.removeListener(ClientEvent.AccountData, onAccountData);
clearTimeout(timerId);
resolve();
}
}
const timerId = window.setTimeout(() => {
MatrixClientPeg.get().removeListener(ClientEvent.AccountData, onAccountData);
client.removeListener(ClientEvent.AccountData, onAccountData);
reject(new Error("Timed out waiting for widget ID " + widgetId + " to appear"));
}, WIDGET_WAIT_TIME);
MatrixClientPeg.get().on(ClientEvent.AccountData, onAccountData);
client.on(ClientEvent.AccountData, onAccountData);
});
}
@ -184,6 +186,7 @@ export default class WidgetUtils {
* ID has been added as a room widget in the given room (ie. the
* room state event arrives) or rejects after a timeout
*
* @param client The matrix client of the logged-in user
* @param {string} widgetId The ID of the widget to wait for
* @param {string} roomId The ID of the room to wait for the widget in
* @param {boolean} add True to wait for the widget to be added,
@ -191,7 +194,12 @@ export default class WidgetUtils {
* @returns {Promise} that resolves when the widget is in the
* requested state according to the `add` param
*/
public static waitForRoomWidget(widgetId: string, roomId: string, add: boolean): Promise<void> {
public static waitForRoomWidget(
client: MatrixClient,
widgetId: string,
roomId: string,
add: boolean,
): Promise<void> {
return new Promise((resolve, reject) => {
// Tests a list of state events, returning true if it's in the state
// we're waiting for it to be in
@ -206,7 +214,7 @@ export default class WidgetUtils {
}
}
const room = MatrixClientPeg.get().getRoom(roomId);
const room = client.getRoom(roomId);
// TODO: Enable support for m.widget event type (https://github.com/vector-im/element-web/issues/13111)
const startingWidgetEvents = room?.currentState.getStateEvents("im.vector.modular.widgets");
if (eventsInIntendedState(startingWidgetEvents)) {
@ -221,30 +229,30 @@ export default class WidgetUtils {
const currentWidgetEvents = room?.currentState.getStateEvents("im.vector.modular.widgets");
if (eventsInIntendedState(currentWidgetEvents)) {
MatrixClientPeg.get().removeListener(RoomStateEvent.Events, onRoomStateEvents);
client.removeListener(RoomStateEvent.Events, onRoomStateEvents);
clearTimeout(timerId);
resolve();
}
}
const timerId = window.setTimeout(() => {
MatrixClientPeg.get().removeListener(RoomStateEvent.Events, onRoomStateEvents);
client.removeListener(RoomStateEvent.Events, onRoomStateEvents);
reject(new Error("Timed out waiting for widget ID " + widgetId + " to appear"));
}, WIDGET_WAIT_TIME);
MatrixClientPeg.get().on(RoomStateEvent.Events, onRoomStateEvents);
client.on(RoomStateEvent.Events, onRoomStateEvents);
});
}
public static setUserWidget(
client: MatrixClient,
widgetId: string,
widgetType: WidgetType,
widgetUrl: string,
widgetName: string,
widgetData: IWidgetData,
): Promise<void> {
const client = MatrixClientPeg.get();
// Get the current widgets and clone them before we modify them, otherwise
// we'll modify the content of the old event.
const userWidgets = objectClone(WidgetUtils.getUserWidgets());
const userWidgets = objectClone(WidgetUtils.getUserWidgets(client));
// Delete existing widget with ID
try {
@ -284,7 +292,7 @@ export default class WidgetUtils {
return client
.setAccountData("m.widgets", userWidgets)
.then(() => {
return WidgetUtils.waitForUserWidget(widgetId, addingWidget);
return WidgetUtils.waitForUserWidget(client, widgetId, addingWidget);
})
.then(() => {
dis.dispatch({ action: "user_widget_updated" });
@ -292,6 +300,7 @@ export default class WidgetUtils {
}
public static setRoomWidget(
client: MatrixClient,
roomId: string,
widgetId: string,
widgetType?: WidgetType,
@ -318,20 +327,24 @@ export default class WidgetUtils {
content = {};
}
return WidgetUtils.setRoomWidgetContent(roomId, widgetId, content as IWidget);
return WidgetUtils.setRoomWidgetContent(client, roomId, widgetId, content as IWidget);
}
public static setRoomWidgetContent(roomId: string, widgetId: string, content: IWidget): Promise<void> {
public static setRoomWidgetContent(
client: MatrixClient,
roomId: string,
widgetId: string,
content: IWidget,
): Promise<void> {
const addingWidget = !!content.url;
WidgetEchoStore.setRoomWidgetEcho(roomId, widgetId, content);
const client = MatrixClientPeg.get();
// TODO: Enable support for m.widget event type (https://github.com/vector-im/element-web/issues/13111)
return client
.sendStateEvent(roomId, "im.vector.modular.widgets", content, widgetId)
.then(() => {
return WidgetUtils.waitForRoomWidget(widgetId, roomId, addingWidget);
return WidgetUtils.waitForRoomWidget(client, widgetId, roomId, addingWidget);
})
.finally(() => {
WidgetEchoStore.removeRoomWidgetEcho(roomId, widgetId);
@ -357,10 +370,10 @@ export default class WidgetUtils {
/**
* Get user specific widgets (not linked to a specific room)
* @param client The matrix client of the logged-in user
* @return {object} Event content object containing current / active user widgets
*/
public static getUserWidgets(): Record<string, UserWidget> {
const client = MatrixClientPeg.get();
public static getUserWidgets(client: MatrixClient | undefined): Record<string, UserWidget> {
if (!client) {
throw new Error("User not logged in");
}
@ -373,27 +386,30 @@ export default class WidgetUtils {
/**
* Get user specific widgets (not linked to a specific room) as an array
* @param client The matrix client of the logged-in user
* @return {[object]} Array containing current / active user widgets
*/
public static getUserWidgetsArray(): UserWidget[] {
return Object.values(WidgetUtils.getUserWidgets());
public static getUserWidgetsArray(client: MatrixClient | undefined): UserWidget[] {
return Object.values(WidgetUtils.getUserWidgets(client));
}
/**
* Get active stickerpicker widgets (stickerpickers are user widgets by nature)
* @param client The matrix client of the logged-in user
* @return {[object]} Array containing current / active stickerpicker widgets
*/
public static getStickerpickerWidgets(): UserWidget[] {
const widgets = WidgetUtils.getUserWidgetsArray();
public static getStickerpickerWidgets(client: MatrixClient | undefined): UserWidget[] {
const widgets = WidgetUtils.getUserWidgetsArray(client);
return widgets.filter((widget) => widget.content?.type === "m.stickerpicker");
}
/**
* Get all integration manager widgets for this user.
* @param client The matrix client of the logged-in user
* @returns {Object[]} An array of integration manager user widgets.
*/
public static getIntegrationManagerWidgets(): UserWidget[] {
const widgets = WidgetUtils.getUserWidgetsArray();
public static getIntegrationManagerWidgets(client: MatrixClient | undefined): UserWidget[] {
const widgets = WidgetUtils.getUserWidgetsArray(client);
return widgets.filter((w) => w.content?.type === "m.integration_manager");
}
@ -405,8 +421,7 @@ export default class WidgetUtils {
});
}
public static async removeIntegrationManagerWidgets(): Promise<void> {
const client = MatrixClientPeg.get();
public static async removeIntegrationManagerWidgets(client: MatrixClient | undefined): Promise<void> {
if (!client) {
throw new Error("User not logged in");
}
@ -421,8 +436,14 @@ export default class WidgetUtils {
await client.setAccountData("m.widgets", userWidgets);
}
public static addIntegrationManagerWidget(name: string, uiUrl: string, apiUrl: string): Promise<void> {
public static addIntegrationManagerWidget(
client: MatrixClient,
name: string,
uiUrl: string,
apiUrl: string,
): Promise<void> {
return WidgetUtils.setUserWidget(
client,
"integration_manager_" + new Date().getTime(),
WidgetType.INTEGRATION_MANAGER,
uiUrl,
@ -433,10 +454,10 @@ export default class WidgetUtils {
/**
* Remove all stickerpicker widgets (stickerpickers are user widgets by nature)
* @param client The matrix client of the logged-in user
* @return {Promise} Resolves on account data updated
*/
public static async removeStickerpickerWidgets(): Promise<void> {
const client = MatrixClientPeg.get();
public static async removeStickerpickerWidgets(client: MatrixClient | undefined): Promise<void> {
if (!client) {
throw new Error("User not logged in");
}
@ -452,6 +473,7 @@ export default class WidgetUtils {
}
public static async addJitsiWidget(
client: MatrixClient,
roomId: string,
type: CallType,
name: string,
@ -462,7 +484,7 @@ export default class WidgetUtils {
const auth = (await Jitsi.getInstance().getJitsiAuth()) ?? undefined;
const widgetId = randomString(24); // Must be globally unique
let confId;
let confId: string;
if (auth === "openidtoken-jwt") {
// Create conference ID from room ID
// For compatibility with Jitsi, use base32 without padding.
@ -479,9 +501,9 @@ export default class WidgetUtils {
widgetUrl.search = ""; // Causes the URL class use searchParams instead
widgetUrl.searchParams.set("confId", confId);
await WidgetUtils.setRoomWidget(roomId, widgetId, WidgetType.JITSI, widgetUrl.toString(), name, {
await WidgetUtils.setRoomWidget(client, roomId, widgetId, WidgetType.JITSI, widgetUrl.toString(), name, {
conferenceId: confId,
roomName: oobRoomName ?? MatrixClientPeg.get().getRoom(roomId)?.name,
roomName: oobRoomName ?? client.getRoom(roomId)?.name,
isAudioOnly: type === CallType.Voice,
isVideoChannel,
domain,

View File

@ -51,7 +51,7 @@ export async function startDmOnFirstMessage(client: MatrixClient, targets: Membe
return existingRoom.roomId;
}
if (targets.length === 1 && targets[0] instanceof ThreepidMember && privateShouldBeEncrypted()) {
if (targets.length === 1 && targets[0] instanceof ThreepidMember && privateShouldBeEncrypted(client)) {
// Single 3rd-party invite and well-known promotes encryption:
// Directly create a room and invite the other.
return await startDm(client, targets);
@ -192,7 +192,7 @@ export interface IDMUserTileProps {
* @returns {Promise<boolean>}
*/
export async function determineCreateRoomEncryptionOption(client: MatrixClient, targets: Member[]): Promise<boolean> {
if (privateShouldBeEncrypted()) {
if (privateShouldBeEncrypted(client)) {
// Enable encryption for a single 3rd party invite.
if (targets.length === 1 && targets[0] instanceof ThreepidMember) return true;

View File

@ -16,13 +16,11 @@ limitations under the License.
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import { Room } from "matrix-js-sdk/src/models/room";
import { MatrixClient } from "matrix-js-sdk/src/client";
import { Direction } from "matrix-js-sdk/src/models/event-timeline";
import { saveAs } from "file-saver";
import { logger } from "matrix-js-sdk/src/logger";
import sanitizeFilename from "sanitize-filename";
import { MatrixClientPeg } from "../../MatrixClientPeg";
import { ExportType, IExportOptions } from "./exportUtils";
import { decryptFile } from "../DecryptFile";
import { mediaFromContent } from "../../customisations/Media";
@ -39,7 +37,6 @@ type BlobFile = {
export default abstract class Exporter {
protected files: BlobFile[] = [];
protected client: MatrixClient;
protected cancelled = false;
protected constructor(
@ -56,7 +53,6 @@ export default abstract class Exporter {
) {
throw new Error("Invalid export options");
}
this.client = MatrixClientPeg.get();
window.addEventListener("beforeunload", this.onBeforeUnload);
}
@ -124,7 +120,7 @@ export default abstract class Exporter {
}
protected setEventMetadata(event: MatrixEvent): MatrixEvent {
const roomState = this.client.getRoom(this.room.roomId)?.currentState;
const roomState = this.room.currentState;
const sender = event.getSender();
event.sender = (!!sender && roomState?.getSentinelMember(sender)) || null;
if (event.getType() === "m.room.member") {
@ -151,7 +147,7 @@ export default abstract class Exporter {
}
protected async getRequiredEvents(): Promise<MatrixEvent[]> {
const eventMapper = this.client.getEventMapper();
const eventMapper = this.room.client.getEventMapper();
let prevToken: string | null = null;
let limit = this.getLimit();
@ -159,7 +155,7 @@ export default abstract class Exporter {
while (limit) {
const eventsPerCrawl = Math.min(limit, 1000);
const res = await this.client.createMessagesRequest(
const res = await this.room.client.createMessagesRequest(
this.room.roomId,
prevToken,
eventsPerCrawl,
@ -211,7 +207,7 @@ export default abstract class Exporter {
const decryptionPromises = events
.filter((event) => event.isEncrypted())
.map((event) => {
return this.client.decryptEventIfNeeded(event, {
return this.room.client.decryptEventIfNeeded(event, {
isRetry: true,
emit: false,
});

View File

@ -94,7 +94,7 @@ export default class HTMLExporter extends Exporter {
const exportDate = formatFullDateNoDayNoTime(new Date());
const creator = this.room.currentState.getStateEvents(EventType.RoomCreate, "")?.getSender();
const creatorName = (creator ? this.room.getMember(creator)?.rawDisplayName : creator) || creator;
const exporter = this.client.getUserId()!;
const exporter = this.room.client.getSafeUserId();
const exporterName = this.room.getMember(exporter)?.rawDisplayName;
const topic = this.room.currentState.getStateEvents(EventType.RoomTopic, "")?.getContent()?.topic || "";
const createdText = _t("%(creatorName)s created this room.", {
@ -282,7 +282,7 @@ export default class HTMLExporter extends Exporter {
public getEventTile(mxEv: MatrixEvent, continuation: boolean): JSX.Element {
return (
<div className="mx_Export_EventWrapper" id={mxEv.getId()}>
<MatrixClientContext.Provider value={this.client}>
<MatrixClientContext.Provider value={this.room.client}>
<EventTile
mxEvent={mxEv}
continuation={continuation}

View File

@ -47,7 +47,7 @@ export default class JSONExporter extends Exporter {
const creator = this.room.currentState.getStateEvents(EventType.RoomCreate, "")?.getSender();
const creatorName = (creator && this.room?.getMember(creator)?.rawDisplayName) || creator;
const topic = this.room.currentState.getStateEvents(EventType.RoomTopic, "")?.getContent()?.topic || "";
const exporter = this.client.getUserId()!;
const exporter = this.room.client.getUserId()!;
const exporterName = this.room?.getMember(exporter)?.rawDisplayName || exporter;
const jsonObject = {
room_name: this.room.name,

View File

@ -19,11 +19,10 @@ import React, { ReactNode } from "react";
import { EventStatus } from "matrix-js-sdk/src/models/event-status";
import { MatrixEventEvent } from "matrix-js-sdk/src/models/event";
import { Room } from "matrix-js-sdk/src/models/room";
import { MatrixError } from "matrix-js-sdk/src/matrix";
import { MatrixClient, MatrixError } from "matrix-js-sdk/src/matrix";
import Modal, { IHandle } from "../Modal";
import Spinner from "../components/views/elements/Spinner";
import { MatrixClientPeg } from "../MatrixClientPeg";
import { _t } from "../languageHandler";
import ErrorDialog from "../components/views/dialogs/ErrorDialog";
import { isMetaSpace } from "../stores/spaces";
@ -38,15 +37,19 @@ import { bulkSpaceBehaviour } from "./space";
import { SdkContextClass } from "../contexts/SDKContext";
import SettingsStore from "../settings/SettingsStore";
export async function leaveRoomBehaviour(roomId: string, retry = true, spinner = true): Promise<void> {
export async function leaveRoomBehaviour(
matrixClient: MatrixClient,
roomId: string,
retry = true,
spinner = true,
): Promise<void> {
let spinnerModal: IHandle<any> | undefined;
if (spinner) {
spinnerModal = Modal.createDialog(Spinner, undefined, "mx_Dialog_spinner");
}
const cli = MatrixClientPeg.get();
let leavingAllVersions = true;
const history = cli.getRoomUpgradeHistory(
const history = matrixClient.getRoomUpgradeHistory(
roomId,
false,
SettingsStore.getValue("feature_dynamic_room_predecessors"),
@ -60,7 +63,7 @@ export async function leaveRoomBehaviour(roomId: string, retry = true, spinner =
}
}
const room = cli.getRoom(roomId);
const room = matrixClient.getRoom(roomId);
// should not encounter this
if (!room) {
@ -97,9 +100,9 @@ export async function leaveRoomBehaviour(roomId: string, retry = true, spinner =
let results: { [roomId: string]: Error | MatrixError | null } = {};
if (!leavingAllVersions) {
try {
await cli.leave(roomId);
await matrixClient.leave(roomId);
} catch (e) {
if (e?.data?.errcode) {
if (e instanceof MatrixError) {
const message = e.data.error || _t("Unexpected server error trying to leave the room");
results[roomId] = Object.assign(new Error(message), { errcode: e.data.errcode, data: e.data });
} else {
@ -107,7 +110,7 @@ export async function leaveRoomBehaviour(roomId: string, retry = true, spinner =
}
}
} else {
results = await cli.leaveRoomChain(roomId, retry);
results = await matrixClient.leaveRoomChain(roomId, retry);
}
if (retry) {
@ -116,7 +119,7 @@ export async function leaveRoomBehaviour(roomId: string, retry = true, spinner =
) as MatrixError;
if (limitExceededError) {
await sleep(limitExceededError.data.retry_after_ms ?? 100);
return leaveRoomBehaviour(roomId, false, false);
return leaveRoomBehaviour(matrixClient, roomId, false, false);
}
}
@ -186,7 +189,7 @@ export const leaveSpace = (space: Room): void => {
space,
onFinished: async (leave: boolean, rooms: Room[]): Promise<void> => {
if (!leave) return;
await bulkSpaceBehaviour(space, rooms, (room) => leaveRoomBehaviour(room.roomId));
await bulkSpaceBehaviour(space, rooms, (room) => leaveRoomBehaviour(space.client, room.roomId));
dis.dispatch<AfterLeaveRoomPayload>({
action: Action.AfterLeaveRoom,

View File

@ -18,7 +18,6 @@ import { logger } from "matrix-js-sdk/src/logger";
import { ClientEvent, MatrixClient } from "matrix-js-sdk/src/matrix";
import defaultDispatcher from "../dispatcher/dispatcher";
import { MatrixClientPeg } from "../MatrixClientPeg";
import { LocalRoom, LocalRoomState } from "../models/LocalRoom";
import { isLocalRoom } from "./localRoom/isLocalRoom";
import { isRoomReady } from "./localRoom/isRoomReady";
@ -39,10 +38,9 @@ import { isRoomReady } from "./localRoom/isRoomReady";
export async function doMaybeLocalRoomAction<T>(
roomId: string,
fn: (actualRoomId: string) => Promise<T>,
client?: MatrixClient,
client: MatrixClient,
): Promise<T> {
if (isLocalRoom(roomId)) {
client = client ?? MatrixClientPeg.get();
const room = client.getRoom(roomId) as LocalRoom;
if (room.isCreated) {

View File

@ -15,6 +15,7 @@ limitations under the License.
*/
import { logger } from "matrix-js-sdk/src/logger";
import { MatrixClient } from "matrix-js-sdk/src/matrix";
import SdkConfig from "../../SdkConfig";
import { getTileServerWellKnown } from "../WellKnownUtils";
@ -25,8 +26,8 @@ import { LocationShareError } from "./LocationShareErrors";
* .well-known location, or, failing that, in our local config, or, failing
* that, defaults to the same tile server listed by matrix.org.
*/
export function findMapStyleUrl(): string {
const mapStyleUrl = getTileServerWellKnown()?.map_style_url ?? SdkConfig.get().map_style_url;
export function findMapStyleUrl(matrixClient: MatrixClient): string {
const mapStyleUrl = getTileServerWellKnown(matrixClient)?.map_style_url ?? SdkConfig.get().map_style_url;
if (!mapStyleUrl) {
logger.error("'map_style_url' missing from homeserver .well-known area, and missing from from config.json.");

View File

@ -15,7 +15,7 @@ limitations under the License.
*/
import * as maplibregl from "maplibre-gl";
import { MatrixEvent } from "matrix-js-sdk/src/matrix";
import { MatrixClient, MatrixEvent } from "matrix-js-sdk/src/matrix";
import { M_LOCATION } from "matrix-js-sdk/src/@types/location";
import { logger } from "matrix-js-sdk/src/logger";
@ -24,9 +24,14 @@ import { parseGeoUri } from "./parseGeoUri";
import { findMapStyleUrl } from "./findMapStyleUrl";
import { LocationShareError } from "./LocationShareErrors";
export const createMap = (interactive: boolean, bodyId: string, onError?: (error: Error) => void): maplibregl.Map => {
export const createMap = (
client: MatrixClient,
interactive: boolean,
bodyId: string,
onError?: (error: Error) => void,
): maplibregl.Map => {
try {
const styleUrl = findMapStyleUrl();
const styleUrl = findMapStyleUrl(client);
const map = new maplibregl.Map({
container: bodyId,

View File

@ -18,6 +18,7 @@ import { useEffect, useState } from "react";
import { Map as MapLibreMap } from "maplibre-gl";
import { createMap } from "./map";
import { useMatrixClientContext } from "../../contexts/MatrixClientContext";
interface UseMapProps {
bodyId: string;
@ -32,12 +33,13 @@ interface UseMapProps {
* As map is recreated on changes to it
*/
export const useMap = ({ interactive, bodyId, onError }: UseMapProps): MapLibreMap | undefined => {
const cli = useMatrixClientContext();
const [map, setMap] = useState<MapLibreMap>();
useEffect(
() => {
try {
setMap(createMap(!!interactive, bodyId, onError));
setMap(createMap(cli, !!interactive, bodyId, onError));
} catch (error) {
onError?.(error);
}

View File

@ -15,12 +15,13 @@ limitations under the License.
*/
import { logger } from "matrix-js-sdk/src/logger";
import { MatrixClient } from "matrix-js-sdk/src/matrix";
import { IConfigOptions } from "../IConfigOptions";
import { getEmbeddedPagesWellKnown } from "../utils/WellKnownUtils";
import { SnakedObject } from "./SnakedObject";
export function getHomePageUrl(appConfig: IConfigOptions): string | undefined {
export function getHomePageUrl(appConfig: IConfigOptions, matrixClient: MatrixClient): string | undefined {
const config = new SnakedObject(appConfig);
const pagesConfig = config.get("embedded_pages");
@ -40,7 +41,7 @@ export function getHomePageUrl(appConfig: IConfigOptions): string | undefined {
}
if (!pageUrl) {
pageUrl = getEmbeddedPagesWellKnown()?.home_url;
pageUrl = getEmbeddedPagesWellKnown(matrixClient)?.home_url;
}
return pageUrl;

View File

@ -20,8 +20,8 @@ import { Room } from "matrix-js-sdk/src/models/room";
import { logger } from "matrix-js-sdk/src/logger";
import { RoomStateEvent } from "matrix-js-sdk/src/models/room-state";
import { EventType } from "matrix-js-sdk/src/@types/event";
import { MatrixClient } from "matrix-js-sdk/src/matrix";
import { MatrixClientPeg } from "../../MatrixClientPeg";
import MatrixToPermalinkConstructor, {
baseUrl as matrixtoBaseUrl,
baseUrlPattern as matrixToBaseUrlPattern,
@ -284,7 +284,7 @@ export function makeUserPermalink(userId: string): string {
return getPermalinkConstructor().forUser(userId);
}
export function makeRoomPermalink(roomId: string): string {
export function makeRoomPermalink(matrixClient: MatrixClient, roomId: string): string {
if (!roomId) {
throw new Error("can't permalink a falsy roomId");
}
@ -293,8 +293,7 @@ export function makeRoomPermalink(roomId: string): string {
// Aliases are already routable, and don't need extra information.
if (roomId[0] !== "!") return getPermalinkConstructor().forRoom(roomId, []);
const client = MatrixClientPeg.get();
const room = client.getRoom(roomId);
const room = matrixClient.getRoom(roomId);
if (!room) {
return getPermalinkConstructor().forRoom(roomId, []);
}
@ -317,11 +316,11 @@ export function isPermalinkHost(host: string): boolean {
* @param {string} entity The entity to transform.
* @returns {string|null} The transformed permalink or null if unable.
*/
export function tryTransformEntityToPermalink(entity: string): string | null {
export function tryTransformEntityToPermalink(matrixClient: MatrixClient, entity: string): string | null {
if (!entity) return null;
// Check to see if it is a bare entity for starters
if (entity[0] === "#" || entity[0] === "!") return makeRoomPermalink(entity);
if (entity[0] === "#" || entity[0] === "!") return makeRoomPermalink(matrixClient, entity);
if (entity[0] === "@") return makeUserPermalink(entity);
if (entity.slice(0, 7) === "matrix:") {

View File

@ -18,8 +18,8 @@ import React from "react";
import ReactDOM from "react-dom";
import { PushProcessor } from "matrix-js-sdk/src/pushprocessor";
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import { MatrixClient } from "matrix-js-sdk/src/matrix";
import { MatrixClientPeg } from "../MatrixClientPeg";
import SettingsStore from "../settings/SettingsStore";
import { Pill, PillType, pillRoomNotifLen, pillRoomNotifPos } from "../components/views/elements/Pill";
import { parsePermalink } from "./permalinks/Permalinks";
@ -51,6 +51,7 @@ const shouldBePillified = (node: Element, href: string, parts: PermalinkParts |
* into pills based on the context of a given room. Returns a list of
* the resulting React nodes so they can be unmounted rather than leaking.
*
* @param matrixClient the client of the logged-in user
* @param {Element[]} nodes - a list of sibling DOM nodes to traverse to try
* to turn into pills.
* @param {MatrixEvent} mxEvent - the matrix event which the DOM nodes are
@ -59,8 +60,13 @@ const shouldBePillified = (node: Element, href: string, parts: PermalinkParts |
* React components which have been mounted as part of this.
* The initial caller should pass in an empty array to seed the accumulator.
*/
export function pillifyLinks(nodes: ArrayLike<Element>, mxEvent: MatrixEvent, pills: Element[]): void {
const room = MatrixClientPeg.get().getRoom(mxEvent.getRoomId()) ?? undefined;
export function pillifyLinks(
matrixClient: MatrixClient,
nodes: ArrayLike<Element>,
mxEvent: MatrixEvent,
pills: Element[],
): void {
const room = matrixClient.getRoom(mxEvent.getRoomId()) ?? undefined;
const shouldShowPillAvatar = SettingsStore.getValue("Pill.shouldShowPillAvatar");
let node = nodes[0];
while (node) {
@ -118,7 +124,7 @@ export function pillifyLinks(nodes: ArrayLike<Element>, mxEvent: MatrixEvent, pi
}
if (roomNotifTextNodes.length > 0) {
const pushProcessor = new PushProcessor(MatrixClientPeg.get());
const pushProcessor = new PushProcessor(matrixClient);
const atRoomRule = pushProcessor.getPushRuleById(".m.rule.roomnotif");
if (atRoomRule && pushProcessor.ruleMatchesEvent(atRoomRule, mxEvent)) {
// Now replace all those nodes with Pills
@ -151,7 +157,7 @@ export function pillifyLinks(nodes: ArrayLike<Element>, mxEvent: MatrixEvent, pi
}
if (node.childNodes && node.childNodes.length && !pillified) {
pillifyLinks(node.childNodes as NodeListOf<Element>, mxEvent, pills);
pillifyLinks(matrixClient, node.childNodes as NodeListOf<Element>, mxEvent, pills);
}
node = node.nextSibling as Element;

View File

@ -14,11 +14,12 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import { MatrixClientPeg } from "../MatrixClientPeg";
import { MatrixClient } from "matrix-js-sdk/src/matrix";
import SdkConfig from "../SdkConfig";
export function isPresenceEnabled(): boolean {
const hsUrl = MatrixClientPeg.get().baseUrl;
export function isPresenceEnabled(matrixClient: MatrixClient): boolean {
const hsUrl = matrixClient.baseUrl;
const urls = SdkConfig.get("enable_presence_by_hs_url");
if (!urls) return true;
if (urls[hsUrl] || urls[hsUrl] === undefined) return true;

View File

@ -27,7 +27,7 @@ export const shouldEncryptRoomWithSingle3rdPartyInvite = (
room: Room,
): { shouldEncrypt: true; inviteEvent: MatrixEvent } | { shouldEncrypt: false; inviteEvent?: undefined } => {
// encryption not promoted via .well-known
if (!privateShouldBeEncrypted()) return { shouldEncrypt: false };
if (!privateShouldBeEncrypted(room.client)) return { shouldEncrypt: false };
// not a DM room
if (!DMRoomMap.shared().getRoomIds().has(room.roomId)) return { shouldEncrypt: false };

View File

@ -14,10 +14,12 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import { MatrixClient } from "matrix-js-sdk/src/matrix";
import { getE2EEWellKnown } from "./WellKnownUtils";
export function privateShouldBeEncrypted(): boolean {
const e2eeWellKnown = getE2EEWellKnown();
export function privateShouldBeEncrypted(client: MatrixClient): boolean {
const e2eeWellKnown = getE2EEWellKnown(client);
if (e2eeWellKnown) {
const defaultDisabled = e2eeWellKnown["default"] === false;
return !defaultDisabled;

View File

@ -38,7 +38,7 @@ function getWidgetBuildUrl(): string | undefined {
return SdkConfig.get().widget_build_url;
}
/* eslint-disable-next-line camelcase */
return getCallBehaviourWellKnown()?.widget_build_url;
return getCallBehaviourWellKnown(MatrixClientPeg.get())?.widget_build_url;
}
export function isManagedHybridWidgetEnabled(): boolean {
@ -53,7 +53,7 @@ export async function addManagedHybridWidget(roomId: string): Promise<void> {
}
// Check for permission
if (!WidgetUtils.canUserModifyWidgets(roomId)) {
if (!WidgetUtils.canUserModifyWidgets(cli, roomId)) {
logger.error(`User not allowed to modify widgets in ${roomId}`);
return;
}
@ -87,7 +87,7 @@ export async function addManagedHybridWidget(roomId: string): Promise<void> {
// Add the widget
try {
await WidgetUtils.setRoomWidgetContent(roomId, widgetId, widgetContent);
await WidgetUtils.setRoomWidgetContent(cli, roomId, widgetId, widgetContent);
} catch (e) {
logger.error(`Unable to add managed hybrid widget in room ${roomId}`, e);
return;

View File

@ -112,7 +112,7 @@ describe("MessagePanel", function () {
return arg === "showDisplaynameChanges";
});
DMRoomMap.makeShared();
DMRoomMap.makeShared(client);
});
afterEach(function () {

View File

@ -91,7 +91,7 @@ describe("PipContainer", () => {
stubClient();
client = mocked(MatrixClientPeg.get());
DMRoomMap.makeShared();
DMRoomMap.makeShared(client);
room = new Room("!1:example.org", client, "@alice:example.org", {
pendingEventOrdering: PendingEventOrdering.Detached,

View File

@ -48,7 +48,7 @@ describe("RightPanel", () => {
beforeEach(() => {
stubClient();
cli = mocked(MatrixClientPeg.get());
DMRoomMap.makeShared();
DMRoomMap.makeShared(cli);
context = new SdkContextClass();
context.client = cli;
RightPanel = wrapInSdkContext(RightPanelBase, context);

View File

@ -83,7 +83,7 @@ describe("RoomView", () => {
room.on(RoomEvent.Timeline, (...args) => cli.emit(RoomEvent.Timeline, ...args));
room.on(RoomEvent.TimelineReset, (...args) => cli.emit(RoomEvent.TimelineReset, ...args));
DMRoomMap.makeShared();
DMRoomMap.makeShared(cli);
stores = new SdkContextClass();
stores.client = cli;
stores.rightPanelStore.useUnitTestClient(cli);
@ -457,7 +457,7 @@ describe("RoomView", () => {
});
it("the last Jitsi widget should be removed", () => {
expect(WidgetUtils.setRoomWidget).toHaveBeenCalledWith(room.roomId, widget2Id);
expect(WidgetUtils.setRoomWidget).toHaveBeenCalledWith(cli, room.roomId, widget2Id);
});
});

View File

@ -131,7 +131,7 @@ describe("ThreadView", () => {
rootEvent = res.rootEvent;
DMRoomMap.makeShared();
DMRoomMap.makeShared(mockClient);
jest.spyOn(DMRoomMap.shared(), "getUserIdForRoomId").mockReturnValue(SENDER);
});

View File

@ -90,7 +90,7 @@ describe("ForwardDialog", () => {
};
beforeEach(() => {
DMRoomMap.makeShared();
DMRoomMap.makeShared(mockClient);
jest.clearAllMocks();
mockClient.getUserId.mockReturnValue("@bob:example.org");
mockClient.getSafeUserId.mockReturnValue("@bob:example.org");

View File

@ -143,7 +143,7 @@ describe("InviteDialog", () => {
getClientWellKnown: jest.fn().mockResolvedValue({}),
});
SdkConfig.put({ validated_server_config: {} as ValidatedServerConfig } as IConfigOptions);
DMRoomMap.makeShared();
DMRoomMap.makeShared(mockClient);
jest.clearAllMocks();
room = new Room(roomId, mockClient, mockClient.getSafeUserId());

View File

@ -86,7 +86,7 @@ describe("AppTile", () => {
cli.hasLazyLoadMembersEnabled = () => false;
// Init misc. startup deps
DMRoomMap.makeShared();
DMRoomMap.makeShared(cli);
r1 = new Room("r1", cli, "@name:example.com");
r2 = new Room("r2", cli, "@name:example.com");

View File

@ -75,7 +75,7 @@ describe("<Pill>", () => {
beforeEach(() => {
client = mocked(stubClient());
SdkContextClass.instance.client = client;
DMRoomMap.makeShared();
DMRoomMap.makeShared(client);
room1 = new Room(room1Id, client, user1Id);
room1.name = "Room 1";
const user1JoinRoom1Event = mkRoomMemberJoinEvent(user1Id, room1Id, {

View File

@ -120,7 +120,7 @@ describe("<TextualBody />", () => {
);
it("renders m.emote correctly", () => {
DMRoomMap.makeShared();
DMRoomMap.makeShared(defaultMatrixClient);
const ev = mkEvent({
type: "m.room.message",
@ -140,7 +140,7 @@ describe("<TextualBody />", () => {
});
it("renders m.notice correctly", () => {
DMRoomMap.makeShared();
DMRoomMap.makeShared(defaultMatrixClient);
const ev = mkEvent({
type: "m.room.message",
@ -161,7 +161,7 @@ describe("<TextualBody />", () => {
describe("renders plain-text m.text correctly", () => {
beforeEach(() => {
DMRoomMap.makeShared();
DMRoomMap.makeShared(defaultMatrixClient);
});
it("simple message renders as expected", () => {
@ -264,7 +264,7 @@ describe("<TextualBody />", () => {
isGuest: () => false,
mxcUrlToHttp: (s: string) => s,
});
DMRoomMap.makeShared();
DMRoomMap.makeShared(defaultMatrixClient);
});
it("italics, bold, underline and strikethrough render as expected", () => {
@ -408,7 +408,7 @@ describe("<TextualBody />", () => {
isGuest: () => false,
mxcUrlToHttp: (s: string) => s,
});
DMRoomMap.makeShared();
DMRoomMap.makeShared(defaultMatrixClient);
const ev = mkRoomTextMessage("Visit https://matrix.org/");
const { container, rerender } = getComponent(

View File

@ -71,7 +71,7 @@ describe("<RoomSummaryCard />", () => {
beforeEach(() => {
jest.clearAllMocks();
DMRoomMap.makeShared();
DMRoomMap.makeShared(mockClient);
mockClient.getRoom.mockReturnValue(room);
jest.spyOn(room, "isElementVideoRoom").mockRestore();

View File

@ -97,7 +97,7 @@ describe("<EditMessageComposer/>", () => {
userEvent.setup();
DMRoomMap.makeShared();
DMRoomMap.makeShared(mockClient);
jest.spyOn(Autocompleter.prototype, "getCompletions").mockResolvedValue([
{

View File

@ -47,7 +47,7 @@ describe("NewRoomIntro", () => {
beforeAll(() => {
client = stubClient();
DMRoomMap.makeShared();
DMRoomMap.makeShared(client);
});
describe("for a DM Room", () => {

View File

@ -112,7 +112,7 @@ describe("RoomHeader", () => {
[MediaDeviceKindEnum.AudioOutput]: [],
});
DMRoomMap.makeShared();
DMRoomMap.makeShared(client);
jest.spyOn(DMRoomMap.shared(), "getUserIdForRoomId").mockReturnValue(carol.userId);
});
@ -761,7 +761,7 @@ function createRoom(info: IRoomCreationInfo) {
};
}
DMRoomMap.makeShared().start();
DMRoomMap.makeShared(client).start();
const room = new Room(roomId, client, userId, {
pendingEventOrdering: PendingEventOrdering.Detached,

View File

@ -33,8 +33,9 @@ jest.mock("../../../../src/IdentityAuthClient", () => {
jest.useRealTimers();
const createRoom = (roomId: string, userId: string): Room => {
const newRoom = new Room(roomId, MatrixClientPeg.get(), userId, {});
DMRoomMap.makeShared().start();
const cli = MatrixClientPeg.get();
const newRoom = new Room(roomId, cli, userId, {});
DMRoomMap.makeShared(cli).start();
return newRoom;
};

View File

@ -42,7 +42,7 @@ describe("RoomPreviewCard", () => {
stubClient();
client = mocked(MatrixClientPeg.get());
client.getUserId.mockReturnValue("@alice:example.org");
DMRoomMap.makeShared();
DMRoomMap.makeShared(client);
room = new Room("!1:example.org", client, "@alice:example.org", {
pendingEventOrdering: PendingEventOrdering.Detached,

View File

@ -90,7 +90,7 @@ describe("RoomTile", () => {
client = mocked(stubClient());
sdkContext.client = client;
DMRoomMap.makeShared();
DMRoomMap.makeShared(client);
room = new Room("!1:example.org", client, "@alice:example.org", {
pendingEventOrdering: PendingEventOrdering.Detached,

View File

@ -159,7 +159,7 @@ describe("<SpacePanel />", () => {
mkStubRoom("!room2:server", "Room 2", mockClient),
mkStubRoom("!room3:server", "Room 3", mockClient),
];
DMRoomMap.makeShared();
DMRoomMap.makeShared(mockClient);
jest.useFakeTimers();
const { getByLabelText } = render(<SpacePanel />);

View File

@ -40,7 +40,7 @@ jest.mock("../../../../src/stores/spaces/SpaceStore", () => {
describe("SpaceButton", () => {
stubClient();
const space = mkRoom(MatrixClientPeg.get(), "!1:example.org");
DMRoomMap.makeShared();
DMRoomMap.makeShared(MatrixClientPeg.get());
const dispatchSpy = jest.spyOn(defaultDispatcher, "dispatch");

View File

@ -37,7 +37,7 @@ describe("RightPanelStore", () => {
beforeEach(() => {
stubClient();
cli = mocked(MatrixClientPeg.get());
DMRoomMap.makeShared();
DMRoomMap.makeShared(cli);
// Make sure we start with a clean store
store.reset();

View File

@ -162,7 +162,7 @@ describe("RoomListStore", () => {
room1.updateMyMembership("join");
room2.updateMyMembership("join");
room3.updateMyMembership("join");
DMRoomMap.makeShared();
DMRoomMap.makeShared(client);
const { store } = createStore();
client.getVisibleRooms = jest.fn().mockReturnValue([room1, room2, room3]);
@ -274,7 +274,7 @@ describe("RoomListStore", () => {
it("Passes the feature flag on to the client when asking for visible rooms", () => {
// Given a store that we can ask for a room list
DMRoomMap.makeShared();
DMRoomMap.makeShared(client);
const { store } = createStore();
client.getVisibleRooms = jest.fn().mockReturnValue([]);

View File

@ -41,7 +41,7 @@ describe("Algorithm", () => {
beforeEach(() => {
stubClient();
client = mocked(MatrixClientPeg.get());
DMRoomMap.makeShared();
DMRoomMap.makeShared(client);
algorithm = new Algorithm();
algorithm.start();

Some files were not shown because too many files have changed in this diff Show More