Merge pull request #6829 from matrix-org/t3chguy/fix/18969

This commit is contained in:
Michael Telatynski 2021-10-14 09:59:34 +01:00 committed by GitHub
commit 4118d13846
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 526 additions and 209 deletions

View file

@ -70,6 +70,8 @@ import { mediaFromMxc } from "../../../customisations/Media";
import UIStore from "../../../stores/UIStore";
import { ComposerInsertPayload } from "../../../dispatcher/payloads/ComposerInsertPayload";
import SpaceStore from "../../../stores/SpaceStore";
import ConfirmSpaceUserActionDialog from "../dialogs/ConfirmSpaceUserActionDialog";
import { bulkSpaceBehaviour } from "../../../utils/space";
import { logger } from "matrix-js-sdk/src/logger";
import { shouldShowComponent } from "../../../customisations/helpers/UIComponents";
@ -534,7 +536,7 @@ interface IBaseProps {
stopUpdating(): void;
}
const RoomKickButton: React.FC<IBaseProps> = ({ member, startUpdating, stopUpdating }) => {
const RoomKickButton = ({ room, member, startUpdating, stopUpdating }: Omit<IBaseRoomProps, "powerLevels">) => {
const cli = useContext(MatrixClientContext);
// check if user can be kicked/disinvited
@ -544,21 +546,38 @@ const RoomKickButton: React.FC<IBaseProps> = ({ member, startUpdating, stopUpdat
const { finished } = Modal.createTrackedDialog(
'Confirm User Action Dialog',
'onKick',
ConfirmUserActionDialog,
room.isSpaceRoom() ? ConfirmSpaceUserActionDialog : ConfirmUserActionDialog,
{
member,
action: member.membership === "invite" ? _t("Disinvite") : _t("Kick"),
title: member.membership === "invite" ? _t("Disinvite this user?") : _t("Kick this user?"),
title: member.membership === "invite"
? _t("Disinvite from %(roomName)s", { roomName: room.name })
: _t("Kick from %(roomName)s", { roomName: room.name }),
askReason: member.membership === "join",
danger: true,
// space-specific props
space: room,
spaceChildFilter: (child: Room) => {
// Return true if the target member is not banned and we have sufficient PL to ban them
const myMember = child.getMember(cli.credentials.userId);
const theirMember = child.getMember(member.userId);
return myMember && theirMember && theirMember.membership === member.membership &&
myMember.powerLevel > theirMember.powerLevel &&
child.currentState.hasSufficientPowerLevelFor("kick", myMember.powerLevel);
},
allLabel: _t("Kick them from everything I'm able to"),
specificLabel: _t("Kick them from specific things I'm able to"),
warningMessage: _t("They'll still be able to access whatever you're not an admin of."),
},
room.isSpaceRoom() ? "mx_ConfirmSpaceUserActionDialog_wrapper" : undefined,
);
const [proceed, reason] = await finished;
const [proceed, reason, rooms = []] = await finished;
if (!proceed) return;
startUpdating();
cli.kick(member.roomId, member.userId, reason || undefined).then(() => {
bulkSpaceBehaviour(room, rooms, room => cli.kick(room.roomId, member.userId, reason || undefined)).then(() => {
// NO-OP; rely on the m.room.member event coming down else we could
// get out of sync if we force setState here!
logger.log("Kick success");
@ -658,34 +677,69 @@ const RedactMessagesButton: React.FC<IBaseProps> = ({ member }) => {
</AccessibleButton>;
};
const BanToggleButton: React.FC<IBaseProps> = ({ member, startUpdating, stopUpdating }) => {
const BanToggleButton = ({ room, member, startUpdating, stopUpdating }: Omit<IBaseRoomProps, "powerLevels">) => {
const cli = useContext(MatrixClientContext);
const isBanned = member.membership === "ban";
const onBanOrUnban = async () => {
const { finished } = Modal.createTrackedDialog(
'Confirm User Action Dialog',
'onBanOrUnban',
ConfirmUserActionDialog,
room.isSpaceRoom() ? ConfirmSpaceUserActionDialog : ConfirmUserActionDialog,
{
member,
action: member.membership === 'ban' ? _t("Unban") : _t("Ban"),
title: member.membership === 'ban' ? _t("Unban this user?") : _t("Ban this user?"),
askReason: member.membership !== 'ban',
danger: member.membership !== 'ban',
action: isBanned ? _t("Unban") : _t("Ban"),
title: isBanned
? _t("Unban from %(roomName)s", { roomName: room.name })
: _t("Ban from %(roomName)s", { roomName: room.name }),
askReason: !isBanned,
danger: !isBanned,
// space-specific props
space: room,
spaceChildFilter: isBanned
? (child: Room) => {
// Return true if the target member is banned and we have sufficient PL to unban
const myMember = child.getMember(cli.credentials.userId);
const theirMember = child.getMember(member.userId);
return myMember && theirMember && theirMember.membership === "ban" &&
myMember.powerLevel > theirMember.powerLevel &&
child.currentState.hasSufficientPowerLevelFor("ban", myMember.powerLevel);
}
: (child: Room) => {
// Return true if the target member isn't banned and we have sufficient PL to ban
const myMember = child.getMember(cli.credentials.userId);
const theirMember = child.getMember(member.userId);
return myMember && theirMember && theirMember.membership !== "ban" &&
myMember.powerLevel > theirMember.powerLevel &&
child.currentState.hasSufficientPowerLevelFor("ban", myMember.powerLevel);
},
allLabel: isBanned
? _t("Unban them from everything I'm able to")
: _t("Ban them from everything I'm able to"),
specificLabel: isBanned
? _t("Unban them from specific things I'm able to")
: _t("Ban them from specific things I'm able to"),
warningMessage: isBanned
? _t("They won't be able to access whatever you're not an admin of.")
: _t("They'll still be able to access whatever you're not an admin of."),
},
room.isSpaceRoom() ? "mx_ConfirmSpaceUserActionDialog_wrapper" : undefined,
);
const [proceed, reason] = await finished;
const [proceed, reason, rooms = []] = await finished;
if (!proceed) return;
startUpdating();
let promise;
if (member.membership === 'ban') {
promise = cli.unban(member.roomId, member.userId);
} else {
promise = cli.ban(member.roomId, member.userId, reason || undefined);
}
promise.then(() => {
const fn = (roomId: string) => {
if (isBanned) {
return cli.unban(roomId, member.userId);
} else {
return cli.ban(roomId, member.userId, reason || undefined);
}
};
bulkSpaceBehaviour(room, rooms, room => fn(room.roomId)).then(() => {
// NO-OP; rely on the m.room.member event coming down else we could
// get out of sync if we force setState here!
logger.log("Ban success");
@ -701,12 +755,12 @@ const BanToggleButton: React.FC<IBaseProps> = ({ member, startUpdating, stopUpda
};
let label = _t("Ban");
if (member.membership === 'ban') {
if (isBanned) {
label = _t("Unban");
}
const classes = classNames("mx_UserInfo_field", {
mx_UserInfo_destructive: member.membership !== 'ban',
mx_UserInfo_destructive: !isBanned,
});
return <AccessibleButton className={classes} onClick={onBanOrUnban}>
@ -820,7 +874,12 @@ const RoomAdminToolsContainer: React.FC<IBaseRoomProps> = ({
const canAffectUser = member.powerLevel < me.powerLevel || isMe;
if (!isMe && canAffectUser && me.powerLevel >= kickPowerLevel) {
kickButton = <RoomKickButton member={member} startUpdating={startUpdating} stopUpdating={stopUpdating} />;
kickButton = <RoomKickButton
room={room}
member={member}
startUpdating={startUpdating}
stopUpdating={stopUpdating}
/>;
}
if (me.powerLevel >= redactPowerLevel && (!SpaceStore.spacesEnabled || !room.isSpaceRoom())) {
redactButton = (
@ -828,7 +887,12 @@ const RoomAdminToolsContainer: React.FC<IBaseRoomProps> = ({
);
}
if (!isMe && canAffectUser && me.powerLevel >= banPowerLevel) {
banButton = <BanToggleButton member={member} startUpdating={startUpdating} stopUpdating={stopUpdating} />;
banButton = <BanToggleButton
room={room}
member={member}
startUpdating={startUpdating}
stopUpdating={stopUpdating}
/>;
}
if (!isMe && canAffectUser && me.powerLevel >= editPowerLevel && !room.isSpaceRoom()) {
muteButton = (