Support additional_creators in /upgraderoom (MSC4289) (#31934)

Signed-off-by: Andy Balaam <andy.balaam@matrix.org>
This commit is contained in:
Andy Balaam
2026-02-02 16:21:42 +00:00
committed by GitHub
parent 7c3cf696fd
commit 1b082a248c
5 changed files with 110 additions and 7 deletions

View File

@@ -61,6 +61,7 @@ import { CommandCategories } from "./slash-commands/interface";
import { Command } from "./slash-commands/command";
import { goto, join } from "./slash-commands/join";
import { manuallyVerifyDevice } from "./components/views/dialogs/ManualDeviceKeyVerificationDialog";
import { parseUpgradeRoomArgs } from "./slash-commands/upgraderoom/parseUpgradeRoomArgs";
export { CommandCategories, Command };
@@ -146,11 +147,15 @@ export const Commands = [
}),
new Command({
command: "upgraderoom",
args: "<new_version>",
args: "<new_version> [<additional-creator-user-id> ...]",
description: _td("slash_command|upgraderoom"),
isEnabled: (cli) => !isCurrentLocalRoom(cli),
runFn: function (cli, roomId, threadId, args) {
if (args) {
if (!args) {
return reject(this.getUsage());
}
const parsedArgs = parseUpgradeRoomArgs(args);
if (parsedArgs) {
const room = cli.getRoom(roomId);
if (!room?.currentState.mayClientSendStateEvent("m.room.tombstone", cli)) {
return reject(new UserFriendlyError("slash_command|upgraderoom_permission_error"));
@@ -158,7 +163,7 @@ export const Commands = [
const { finished } = Modal.createDialog(
RoomUpgradeWarningDialog,
{ roomId: roomId, targetVersion: args },
{ roomId: roomId, targetVersion: parsedArgs.targetVersion },
/*className=*/ undefined,
/*isPriority=*/ false,
/*isStatic=*/ true,
@@ -167,7 +172,17 @@ export const Commands = [
return success(
finished.then(async ([resp]): Promise<void> => {
if (!resp?.continue) return;
await upgradeRoom(room, args, resp.invite);
await upgradeRoom(
room,
parsedArgs.targetVersion,
resp.invite,
true,
true,
false,
undefined,
false,
parsedArgs.additionalCreators,
);
}),
);
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright 2026 Element Creations Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
export type UpgradeRoomParsedArgs = {
targetVersion: string;
additionalCreators?: string[];
};
/**
* Parse the supplied arguments for a room upgrade, or return null if the
* arguments are not valid. The arguments must be a room version followed by
* zero or more valid user IDs.
*/
export function parseUpgradeRoomArgs(args: string): UpgradeRoomParsedArgs | null {
const parts = args.split(/\s+/);
if (parts.length === 0 || parts[0] === "") {
return null;
} else {
const targetVersion = parts[0];
let additionalCreators: string[] | undefined;
for (let i = 1; i < parts.length; ++i) {
if (additionalCreators === undefined) {
additionalCreators = [];
}
additionalCreators.push(parts[i]);
}
return { targetVersion, additionalCreators };
}
}

View File

@@ -53,6 +53,7 @@ export async function upgradeRoom(
awaitRoom = false,
progressCallback?: (progress: RoomUpgradeProgress) => void,
inhibitInviteProgressDialog = false,
additionalCreators?: string[],
): Promise<string> {
const cli = room.client;
let spinnerModal: IHandle<any> | undefined;
@@ -91,7 +92,7 @@ export async function upgradeRoom(
let newRoomId: string;
try {
({ replacement_room: newRoomId } = await cli.upgradeRoom(room.roomId, targetVersion));
({ replacement_room: newRoomId } = await cli.upgradeRoom(room.roomId, targetVersion, additionalCreators));
} catch (e) {
if (!handleError) throw e;
logger.error(e);