mirror of https://github.com/vector-im/riot-web
Update space children (best effort) when upgrading a room
parent
f412fb44a7
commit
437d53d1cc
|
@ -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");
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -15,60 +15,79 @@ 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));
|
||||||
|
|
||||||
// We have to wait for the js-sdk to give us the room back so
|
|
||||||
// we can more effectively abuse the MultiInviter behaviour
|
|
||||||
// which heavily relies on the Room object being available.
|
|
||||||
if (inviteUsers) {
|
|
||||||
checkForUpgradeFn = async (newRoom: Room) => {
|
|
||||||
// The upgradePromise should be done by the time we await it here.
|
|
||||||
const { replacement_room: newRoomId } = await upgradePromise;
|
|
||||||
if (newRoom.roomId !== newRoomId) return;
|
|
||||||
|
|
||||||
const toInvite = [
|
|
||||||
...room.getMembersWithMembership("join"),
|
|
||||||
...room.getMembersWithMembership("invite"),
|
|
||||||
].map(m => m.userId).filter(m => m !== cli.getUserId());
|
|
||||||
|
|
||||||
if (toInvite.length > 0) {
|
|
||||||
// Errors are handled internally to this function
|
|
||||||
await inviteUsersToRoom(newRoomId, toInvite);
|
|
||||||
}
|
|
||||||
|
|
||||||
cli.removeListener('Room', checkForUpgradeFn);
|
|
||||||
};
|
|
||||||
cli.on('Room', checkForUpgradeFn);
|
|
||||||
}
|
|
||||||
|
|
||||||
// We have to await after so that the checkForUpgradesFn has a proper reference
|
|
||||||
// to the new room's ID.
|
|
||||||
return upgradePromise;
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
if (!handleError) throw e;
|
||||||
console.error(e);
|
console.error(e);
|
||||||
|
|
||||||
if (checkForUpgradeFn) cli.removeListener('Room', checkForUpgradeFn);
|
Modal.createTrackedDialog("Room Upgrade Error", "", ErrorDialog, {
|
||||||
|
|
||||||
Modal.createTrackedDialog('Slash Commands', 'room upgrade error', ErrorDialog, {
|
|
||||||
title: _t('Error upgrading room'),
|
title: _t('Error upgrading room'),
|
||||||
description: _t('Double check that your server supports the room version chosen and try again.'),
|
description: _t('Double check that your server supports the room version chosen and try again.'),
|
||||||
});
|
});
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We have to wait for the js-sdk to give us the room back so
|
||||||
|
// we can more effectively abuse the MultiInviter behaviour
|
||||||
|
// which heavily relies on the Room object being available.
|
||||||
|
if (inviteUsers) {
|
||||||
|
const checkForUpgradeFn = async (newRoom: Room): Promise<void> => {
|
||||||
|
// The upgradePromise should be done by the time we await it here.
|
||||||
|
if (newRoom.roomId !== newRoomId) return;
|
||||||
|
|
||||||
|
const toInvite = [
|
||||||
|
...room.getMembersWithMembership("join"),
|
||||||
|
...room.getMembersWithMembership("invite"),
|
||||||
|
].map(m => m.userId).filter(m => m !== cli.getUserId());
|
||||||
|
|
||||||
|
if (toInvite.length > 0) {
|
||||||
|
// Errors are handled internally to this function
|
||||||
|
await inviteUsersToRoom(newRoomId, toInvite);
|
||||||
|
}
|
||||||
|
|
||||||
|
cli.removeListener('Room', checkForUpgradeFn);
|
||||||
|
};
|
||||||
|
cli.on('Room', checkForUpgradeFn);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updateSpaces) {
|
||||||
|
const parents = SpaceStore.instance.getKnownParents(room.roomId);
|
||||||
|
try {
|
||||||
|
for (const parentId of parents) {
|
||||||
|
const parent = cli.getRoom(parentId);
|
||||||
|
if (!parent?.currentState.maySendStateEvent(EventType.SpaceChild, cli.getUserId())) continue;
|
||||||
|
|
||||||
|
const currentEv = parent.currentState.getStateEvents(EventType.SpaceChild, room.roomId);
|
||||||
|
await cli.sendStateEvent(parentId, EventType.SpaceChild, {
|
||||||
|
...(currentEv?.getContent() || {}), // copy existing attributes like suggested
|
||||||
|
via: [cli.getDomain()],
|
||||||
|
}, newRoomId);
|
||||||
|
await cli.sendStateEvent(parentId, EventType.SpaceChild, {}, room.roomId);
|
||||||
|
}
|
||||||
|
} 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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue