Inline inviteMultipleToRoom (#33027)
This two-line method serves mostly to obfuscate, imho. Let's get rid of it.
This commit is contained in:
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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({});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
Reference in New Issue
Block a user