Update space children (best effort) when upgrading a room

pull/21833/head
Michael Telatynski 2021-07-09 08:43:41 +01:00
parent f412fb44a7
commit 437d53d1cc
3 changed files with 60 additions and 37 deletions

View File

@ -17,10 +17,10 @@ limitations under the License.
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import * as sdk from '../../../index'; import * as sdk from '../../../index';
import { MatrixClientPeg } from '../../../MatrixClientPeg';
import Modal from '../../../Modal'; import Modal from '../../../Modal';
import { _t } from '../../../languageHandler'; import { _t } from '../../../languageHandler';
import { replaceableComponent } from "../../../utils/replaceableComponent"; import { replaceableComponent } from "../../../utils/replaceableComponent";
import { upgradeRoom } from "../../../utils/RoomUpgrade";
@replaceableComponent("views.dialogs.RoomUpgradeDialog") @replaceableComponent("views.dialogs.RoomUpgradeDialog")
export default class RoomUpgradeDialog extends React.Component { export default class RoomUpgradeDialog extends React.Component {
@ -45,7 +45,7 @@ export default class RoomUpgradeDialog extends React.Component {
_onUpgradeClick = () => { _onUpgradeClick = () => {
this.setState({ busy: true }); this.setState({ busy: true });
MatrixClientPeg.get().upgradeRoom(this.props.room.roomId, this._targetVersion).then(() => { upgradeRoom(this.props.room, this._targetVersion, false, false).then(() => {
this.props.onFinished(true); this.props.onFinished(true);
}).catch((err) => { }).catch((err) => {
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");

View File

@ -335,6 +335,10 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
return sortBy(parents, r => r.roomId)?.[0] || null; return sortBy(parents, r => r.roomId)?.[0] || null;
} }
public getKnownParents(roomId: string): Set<string> {
return this.parentMap.get(roomId) || new Set();
}
public getSpaceFilteredRoomIds = (space: Room | null): Set<string> => { public getSpaceFilteredRoomIds = (space: Room | null): Set<string> => {
if (!space && SettingsStore.getValue("feature_spaces.all_rooms")) { if (!space && SettingsStore.getValue("feature_spaces.all_rooms")) {
return new Set(this.matrixClient.getVisibleRooms().map(r => r.roomId)); return new Set(this.matrixClient.getVisibleRooms().map(r => r.roomId));

View File

@ -15,31 +15,43 @@ limitations under the License.
*/ */
import { Room } from "matrix-js-sdk/src/models/room"; import { Room } from "matrix-js-sdk/src/models/room";
import { EventType } from "matrix-js-sdk/src/@types/event";
import { inviteUsersToRoom } from "../RoomInvite"; import { inviteUsersToRoom } from "../RoomInvite";
import Modal from "../Modal"; import Modal 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/SpaceStore";
export async function upgradeRoom( export async function upgradeRoom(
room: Room, room: Room,
targetVersion: string, targetVersion: string,
inviteUsers = false, inviteUsers = false,
// eslint-disable-next-line camelcase handleError = true,
): Promise<{ replacement_room: string }> { updateSpaces = true,
): Promise<string> {
const cli = room.client; const cli = room.client;
let checkForUpgradeFn: (room: Room) => Promise<void>; let newRoomId: string;
try { try {
const upgradePromise = cli.upgradeRoom(room.roomId, targetVersion); ({ replacement_room: newRoomId } = await cli.upgradeRoom(room.roomId, targetVersion));
} catch (e) {
if (!handleError) throw e;
console.error(e);
Modal.createTrackedDialog("Room Upgrade Error", "", ErrorDialog, {
title: _t('Error upgrading room'),
description: _t('Double check that your server supports the room version chosen and try again.'),
});
throw e;
}
// We have to wait for the js-sdk to give us the room back so // We have to wait for the js-sdk to give us the room back so
// we can more effectively abuse the MultiInviter behaviour // we can more effectively abuse the MultiInviter behaviour
// which heavily relies on the Room object being available. // which heavily relies on the Room object being available.
if (inviteUsers) { if (inviteUsers) {
checkForUpgradeFn = async (newRoom: Room) => { const checkForUpgradeFn = async (newRoom: Room): Promise<void> => {
// The upgradePromise should be done by the time we await it here. // The upgradePromise should be done by the time we await it here.
const { replacement_room: newRoomId } = await upgradePromise;
if (newRoom.roomId !== newRoomId) return; if (newRoom.roomId !== newRoomId) return;
const toInvite = [ const toInvite = [
@ -57,18 +69,25 @@ export async function upgradeRoom(
cli.on('Room', checkForUpgradeFn); cli.on('Room', checkForUpgradeFn);
} }
// We have to await after so that the checkForUpgradesFn has a proper reference if (updateSpaces) {
// to the new room's ID. const parents = SpaceStore.instance.getKnownParents(room.roomId);
return upgradePromise; try {
} catch (e) { for (const parentId of parents) {
console.error(e); const parent = cli.getRoom(parentId);
if (!parent?.currentState.maySendStateEvent(EventType.SpaceChild, cli.getUserId())) continue;
if (checkForUpgradeFn) cli.removeListener('Room', checkForUpgradeFn); const currentEv = parent.currentState.getStateEvents(EventType.SpaceChild, room.roomId);
await cli.sendStateEvent(parentId, EventType.SpaceChild, {
Modal.createTrackedDialog('Slash Commands', 'room upgrade error', ErrorDialog, { ...(currentEv?.getContent() || {}), // copy existing attributes like suggested
title: _t('Error upgrading room'), via: [cli.getDomain()],
description: _t('Double check that your server supports the room version chosen and try again.'), }, newRoomId);
}); await cli.sendStateEvent(parentId, EventType.SpaceChild, {}, room.roomId);
throw e;
} }
} catch (e) {
// These errors are not critical to the room upgrade itself
console.warn("Failed to update parent spaces during room upgrade", e);
}
}
return newRoomId;
} }