Inline inviteMultipleToRoom (#33027)

This two-line method serves mostly to obfuscate, imho. Let's get rid of it.
This commit is contained in:
Richard van der Hoff
2026-04-09 22:11:12 +00:00
committed by GitHub
parent ca6943cb43
commit 4c4bfcde7e
5 changed files with 25 additions and 75 deletions
+3 -29
View File
@@ -7,9 +7,10 @@ Please see LICENSE files in the repository root for full details.
*/ */
import React, { type ComponentProps } from "react"; import React, { type ComponentProps } from "react";
import { EventType, type MatrixClient, type MatrixEvent, type Room, type User } from "matrix-js-sdk/src/matrix"; import { EventType, type MatrixEvent, type Room, type User } from "matrix-js-sdk/src/matrix";
import MultiInviter, { type CompletionStates, type MultiInviterOptions } from "./utils/MultiInviter"; import type MultiInviter from "./utils/MultiInviter";
import { type CompletionStates } from "./utils/MultiInviter";
import Modal from "./Modal"; import Modal from "./Modal";
import { _t } from "./languageHandler"; import { _t } from "./languageHandler";
import InviteDialog from "./components/views/dialogs/InviteDialog"; import InviteDialog from "./components/views/dialogs/InviteDialog";
@@ -19,33 +20,6 @@ import ErrorDialog from "./components/views/dialogs/ErrorDialog";
import { InviteKind } from "./components/views/dialogs/InviteDialogTypes"; import { InviteKind } from "./components/views/dialogs/InviteDialogTypes";
import { type Member } from "./utils/direct-messages"; import { type Member } from "./utils/direct-messages";
export interface IInviteResult {
states: CompletionStates;
inviter: MultiInviter;
}
/**
* Invites multiple addresses to a room.
*
* Simpler interface to {@link MultiInviter}.
*
* Any failures are returned via the `states` in the result.
*
* @param {string} roomId The ID of the room to invite to
* @param {string[]} addresses Array of strings of addresses to invite. May be matrix IDs or 3pids.
* @param options Options object.
* @returns {Promise} Promise
*/
export async function inviteMultipleToRoom(
client: MatrixClient,
roomId: string,
addresses: string[],
options: MultiInviterOptions = {},
): Promise<IInviteResult> {
const inviter = new MultiInviter(client, roomId, options);
return { states: await inviter.invite(addresses), inviter };
}
export function showStartChatInviteDialog(initialText = ""): void { export function showStartChatInviteDialog(initialText = ""): void {
// This dialog handles the room creation internally - we don't need to worry about it. // This dialog handles the room creation internally - we don't need to worry about it.
Modal.createDialog( Modal.createDialog(
@@ -34,7 +34,7 @@ import { useFeatureEnabled } from "../../hooks/useSettings";
import { useStateArray } from "../../hooks/useStateArray"; import { useStateArray } from "../../hooks/useStateArray";
import { _t } from "../../languageHandler"; import { _t } from "../../languageHandler";
import PosthogTrackers from "../../PosthogTrackers"; import PosthogTrackers from "../../PosthogTrackers";
import { inviteMultipleToRoom, showRoomInviteDialog } from "../../RoomInvite"; import { showRoomInviteDialog } from "../../RoomInvite";
import { UIComponent } from "../../settings/UIFeature"; import { UIComponent } from "../../settings/UIFeature";
import { UPDATE_EVENT } from "../../stores/AsyncStore"; import { UPDATE_EVENT } from "../../stores/AsyncStore";
import RightPanelStore from "../../stores/right-panel/RightPanelStore"; import RightPanelStore from "../../stores/right-panel/RightPanelStore";
@@ -76,6 +76,7 @@ import SpaceHierarchy, { showRoom } from "./SpaceHierarchy";
import { type RoomPermalinkCreator } from "../../utils/permalinks/Permalinks"; import { type RoomPermalinkCreator } from "../../utils/permalinks/Permalinks";
import SpacePillButton from "./SpacePillButton.tsx"; import SpacePillButton from "./SpacePillButton.tsx";
import { useRoomName } from "../../hooks/useRoomName.ts"; import { useRoomName } from "../../hooks/useRoomName.ts";
import MultiInviter from "../../utils/MultiInviter.ts";
interface IProps { interface IProps {
space: Room; space: Room;
@@ -538,11 +539,12 @@ const SpaceSetupPrivateInvite: React.FC<{
setBusy(true); setBusy(true);
const targetIds = emailAddresses.map((name) => name.trim()).filter(Boolean); const targetIds = emailAddresses.map((name) => name.trim()).filter(Boolean);
try { try {
const result = await inviteMultipleToRoom(space.client, space.roomId, targetIds); const inviter = new MultiInviter(space.client, space.roomId);
const states = await inviter.invite(targetIds);
const failedUsers = Object.keys(result.states).filter((a) => result.states[a] === "error"); const failedUsers = Object.keys(states).filter((a) => states[a] === "error");
if (failedUsers.length > 0) { if (failedUsers.length > 0) {
logger.log("Failed to invite users to space: ", result); logger.log("Failed to invite users to space:", states);
setError( setError(
_t("create_space|failed_invite_users", { _t("create_space|failed_invite_users", {
csvUsers: failedUsers.join(", "), csvUsers: failedUsers.join(", "),
@@ -25,7 +25,7 @@ import { getDefaultIdentityServerUrl, setToDefaultIdentityServer } from "../../.
import { buildActivityScores, buildMemberScores, compareMembers } from "../../../utils/SortMembers"; import { buildActivityScores, buildMemberScores, compareMembers } from "../../../utils/SortMembers";
import { abbreviateUrl } from "../../../utils/UrlUtils"; import { abbreviateUrl } from "../../../utils/UrlUtils";
import IdentityAuthClient from "../../../IdentityAuthClient"; import IdentityAuthClient from "../../../IdentityAuthClient";
import { type IInviteResult, inviteMultipleToRoom, showAnyInviteErrors } from "../../../RoomInvite"; import { showAnyInviteErrors } from "../../../RoomInvite";
import { Action } from "../../../dispatcher/actions"; import { Action } from "../../../dispatcher/actions";
import { DefaultTagID } from "../../../stores/room-list-v3/skip-list/tag"; import { DefaultTagID } from "../../../stores/room-list-v3/skip-list/tag";
import RoomListStore from "../../../stores/room-list/RoomListStore"; import RoomListStore from "../../../stores/room-list/RoomListStore";
@@ -63,6 +63,7 @@ import { type NonEmptyArray } from "../../../@types/common";
import { SdkContextClass } from "../../../contexts/SDKContext"; import { SdkContextClass } from "../../../contexts/SDKContext";
import { type UserProfilesStore } from "../../../stores/UserProfilesStore"; import { type UserProfilesStore } from "../../../stores/UserProfilesStore";
import InviteProgressBody from "./InviteProgressBody.tsx"; import InviteProgressBody from "./InviteProgressBody.tsx";
import MultiInviter, { type CompletionStates as MultiInviterCompletionStates } from "../../../utils/MultiInviter.ts";
// we have a number of types defined from the Matrix spec which can't reasonably be altered here. // we have a number of types defined from the Matrix spec which can't reasonably be altered here.
/* eslint-disable camelcase */ /* eslint-disable camelcase */
@@ -409,10 +410,14 @@ export default class InviteDialog extends React.PureComponent<Props, IInviteDial
.map((member) => ({ userId: member.userId, user: toMember(member) })); .map((member) => ({ userId: member.userId, user: toMember(member) }));
} }
private shouldAbortAfterInviteError(result: IInviteResult, room: Room): boolean { private shouldAbortAfterInviteError(
states: MultiInviterCompletionStates,
inviter: MultiInviter,
room: Room,
): boolean {
this.setState({ busy: false }); this.setState({ busy: false });
const userMap = new Map<string, Member>(this.state.targets.map((member) => [member.userId, member])); const userMap = new Map<string, Member>(this.state.targets.map((member) => [member.userId, member]));
return !showAnyInviteErrors(result.states, room, result.inviter, userMap); return !showAnyInviteErrors(states, room, inviter, userMap);
} }
private convertFilter(): Member[] { private convertFilter(): Member[] {
@@ -483,11 +488,12 @@ export default class InviteDialog extends React.PureComponent<Props, IInviteDial
} }
try { try {
const result = await inviteMultipleToRoom(cli, this.props.roomId, targetIds, { const inviter = new MultiInviter(cli, this.props.roomId, {
// We show our own progress body, so don't pop up a separate dialog. // We show our own progress body, so don't pop up a separate dialog.
inhibitProgressDialog: true, inhibitProgressDialog: true,
}); });
if (!this.shouldAbortAfterInviteError(result, room)) { const states = await inviter.invite(targetIds);
if (!this.shouldAbortAfterInviteError(states, inviter, room)) {
// handles setting error message too // handles setting error message too
this.props.onFinished(true); this.props.onFinished(true);
} }
+5 -4
View File
@@ -10,13 +10,13 @@ import { ClientEvent, EventType, type MatrixClient, type Room } from "matrix-js-
import { KnownMembership } from "matrix-js-sdk/src/types"; import { KnownMembership } from "matrix-js-sdk/src/types";
import { logger } from "matrix-js-sdk/src/logger"; import { logger } from "matrix-js-sdk/src/logger";
import { inviteMultipleToRoom, showAnyInviteErrors } from "../RoomInvite"; import { showAnyInviteErrors } from "../RoomInvite";
import Modal, { type IHandle } from "../Modal"; import Modal, { type IHandle } from "../Modal";
import { _t } from "../languageHandler"; import { _t } from "../languageHandler";
import ErrorDialog from "../components/views/dialogs/ErrorDialog"; import ErrorDialog from "../components/views/dialogs/ErrorDialog";
import SpaceStore from "../stores/spaces/SpaceStore"; import SpaceStore from "../stores/spaces/SpaceStore";
import Spinner from "../components/views/elements/Spinner"; import Spinner from "../components/views/elements/Spinner";
import type { MultiInviterOptions } from "./MultiInviter"; import MultiInviter, { type MultiInviterOptions } from "./MultiInviter";
export interface RoomUpgradeProgress { export interface RoomUpgradeProgress {
roomUpgraded: boolean; roomUpgraded: boolean;
@@ -158,7 +158,8 @@ async function inviteUsersToRoom(
userIds: string[], userIds: string[],
inviteOptions: MultiInviterOptions, inviteOptions: MultiInviterOptions,
): Promise<void> { ): Promise<void> {
const result = await inviteMultipleToRoom(client, roomId, userIds, inviteOptions); const inviter = new MultiInviter(client, roomId, inviteOptions);
const states = await inviter.invite(userIds);
const room = client.getRoom(roomId)!; const room = client.getRoom(roomId)!;
showAnyInviteErrors(result.states, room, result.inviter); showAnyInviteErrors(states, room, inviter);
} }
@@ -1,33 +0,0 @@
/*
Copyright 2025 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import { getMockClientWithEventEmitter } from "../test-utils";
import { inviteMultipleToRoom } from "../../src/RoomInvite.tsx";
afterEach(() => {
jest.restoreAllMocks();
});
describe("inviteMultipleToRoom", () => {
it("can be called wth no `options`", async () => {
const client = getMockClientWithEventEmitter({});
const { states, inviter } = await inviteMultipleToRoom(client, "!room:id", []);
expect(states).toEqual({});
// @ts-ignore reference to private property
expect(inviter.options).toEqual({});
});
});