Add progress bar to restricted room upgrade dialog

This commit is contained in:
Michael Telatynski 2021-10-08 12:20:43 +01:00
parent 5264b1db9d
commit 2483f1dc90
5 changed files with 188 additions and 70 deletions

View file

@ -28,15 +28,25 @@ import { IDialogProps } from "./IDialogProps";
import BugReportDialog from './BugReportDialog';
import BaseDialog from "./BaseDialog";
import DialogButtons from "../elements/DialogButtons";
import ProgressBar from "../elements/ProgressBar";
export interface IFinishedOpts {
continue: boolean;
invite: boolean;
}
interface IProps extends IDialogProps {
roomId: string;
targetVersion: string;
description?: ReactNode;
doUpgrade?(opts: IFinishedOpts, fn: (progressText: string, progress: number, total: number) => void): Promise<void>;
}
interface IState {
inviteUsersToNewRoom: boolean;
progressText?: string;
progress?: number;
total?: number;
}
@replaceableComponent("views.dialogs.RoomUpgradeWarningDialog")
@ -50,15 +60,30 @@ export default class RoomUpgradeWarningDialog extends React.Component<IProps, IS
const room = MatrixClientPeg.get().getRoom(this.props.roomId);
const joinRules = room?.currentState.getStateEvents(EventType.RoomJoinRules, "");
this.isPrivate = joinRules?.getContent()['join_rule'] !== JoinRule.Public ?? true;
this.currentVersion = room?.getVersion() || "1";
this.currentVersion = room?.getVersion();
this.state = {
inviteUsersToNewRoom: true,
};
}
private onProgressCallback = (progressText: string, progress: number, total: number): void => {
this.setState({ progressText, progress, total });
};
private onContinue = () => {
this.props.onFinished({ continue: true, invite: this.isPrivate && this.state.inviteUsersToNewRoom });
const opts = {
continue: true,
invite: this.isPrivate && this.state.inviteUsersToNewRoom,
};
if (this.props.doUpgrade) {
this.props.doUpgrade(opts, this.onProgressCallback).then(() => {
this.props.onFinished(opts);
});
} else {
this.props.onFinished(opts);
}
};
private onCancel = () => {
@ -118,6 +143,23 @@ export default class RoomUpgradeWarningDialog extends React.Component<IProps, IS
);
}
let footer: JSX.Element;
if (this.state.progressText) {
footer = <span className="mx_RoomUpgradeWarningDialog_progress">
<ProgressBar value={this.state.progress} max={this.state.total} />
<div className="mx_RoomUpgradeWarningDialog_progressText">
{ this.state.progressText }
</div>
</span>;
} else {
footer = <DialogButtons
primaryButton={_t("Upgrade")}
onPrimaryButtonClick={this.onContinue}
cancelButton={_t("Cancel")}
onCancel={this.onCancel}
/>;
}
return (
<BaseDialog
className='mx_RoomUpgradeWarningDialog'
@ -154,12 +196,7 @@ export default class RoomUpgradeWarningDialog extends React.Component<IProps, IS
</p>
{ inviteToggle }
</div>
<DialogButtons
primaryButton={_t("Upgrade")}
onPrimaryButtonClick={this.onContinue}
cancelButton={_t("Cancel")}
onCancel={this.onCancel}
/>
{ footer }
</BaseDialog>
);
}

View file

@ -27,8 +27,7 @@ import SpaceStore from "../../../stores/SpaceStore";
import { MatrixClientPeg } from "../../../MatrixClientPeg";
import Modal from "../../../Modal";
import ManageRestrictedJoinRuleDialog from "../dialogs/ManageRestrictedJoinRuleDialog";
import RoomUpgradeWarningDialog from "../dialogs/RoomUpgradeWarningDialog";
import QuestionDialog from "../dialogs/QuestionDialog";
import RoomUpgradeWarningDialog, { IFinishedOpts } from "../dialogs/RoomUpgradeWarningDialog";
import { upgradeRoom } from "../../../utils/RoomUpgrade";
import { arrayHasDiff } from "../../../utils/arrays";
import { useLocalEcho } from "../../../hooks/useLocalEcho";
@ -210,47 +209,70 @@ const JoinRuleSettings = ({ room, promptUpgrade, onError, beforeChange, closeSet
// Block this action on a room upgrade otherwise it'd make their room unjoinable
const targetVersion = preferredRestrictionVersion;
const modal = Modal.createTrackedDialog('Restricted join rule upgrade', '', RoomUpgradeWarningDialog, {
roomId: room.roomId,
targetVersion,
description: _t("This upgrade will allow members of selected spaces " +
"access to this room without an invite."),
});
const [resp] = await modal.finished;
if (!resp?.continue) return;
let warning: JSX.Element;
const userId = cli.getUserId();
const unableToUpdateSomeParents = Array.from(SpaceStore.instance.getKnownParents(room.roomId))
.some(roomId => !cli.getRoom(roomId)?.currentState.maySendStateEvent(EventType.SpaceChild, userId));
if (unableToUpdateSomeParents) {
const modal = Modal.createTrackedDialog<[boolean]>('Parent relink warning', '', QuestionDialog, {
title: _t("Before you upgrade"),
description: (
<div>{ _t("This room is in some spaces youre not an admin of. " +
"In those spaces, the old room will still be shown, " +
"but people will be prompted to join the new one.") }</div>
),
hasCancelButton: true,
button: _t("Upgrade anyway"),
danger: true,
});
const [shouldUpgrade] = await modal.finished;
if (!shouldUpgrade) return;
warning = <b>
{ _t("This room is in some spaces youre not an admin of. " +
"In those spaces, the old room will still be shown, " +
"but people will be prompted to join the new one.") }
</b>;
}
const roomId = await upgradeRoom(room, targetVersion, resp.invite, true, true, true);
closeSettingsFn();
// switch to the new room in the background
dis.dispatch({
action: "view_room",
room_id: roomId,
});
// open new settings on this tab
dis.dispatch({
action: "open_room_settings",
initial_tab_id: ROOM_SECURITY_TAB,
Modal.createTrackedDialog('Restricted join rule upgrade', '', RoomUpgradeWarningDialog, {
roomId: room.roomId,
targetVersion,
description: <>
{ _t("This upgrade will allow members of selected spaces " +
"access to this room without an invite.") }
{ warning }
</>,
doUpgrade: async (
opts: IFinishedOpts,
fn: (progressText: string, progress: number, total: number) => void,
): Promise<void> => {
const roomId = await upgradeRoom(
room,
targetVersion,
opts.invite,
true,
true,
true,
progress => {
const total = 2 + progress.updateSpacesTotal + progress.inviteUsersTotal;
if (!progress.roomUpgraded) {
fn(_t("Upgrading room"), 0, total);
} else if (!progress.roomSynced) {
fn(_t("Loading new room"), 1, total);
} else if (progress.inviteUsersProgress < progress.inviteUsersTotal) {
fn(_t("Sending invites... (%(progress)s out of %(count)s)", {
progress: progress.inviteUsersProgress,
count: progress.inviteUsersTotal,
}), 2 + progress.inviteUsersProgress, total);
} else if (progress.updateSpacesProgress < progress.updateSpacesTotal) {
fn(_t("Updating spaces... (%(progress)s out of %(count)s)", {
progress: progress.updateSpacesProgress,
count: progress.updateSpacesTotal,
}), 2 + progress.inviteUsersProgress + progress.updateSpacesProgress, total);
}
},
);
closeSettingsFn();
// switch to the new room in the background
dis.dispatch({
action: "view_room",
room_id: roomId,
});
// open new settings on this tab
dis.dispatch({
action: "open_room_settings",
initial_tab_id: ROOM_SECURITY_TAB,
});
},
});
return;