Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Power Level Switcher #554

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 28 additions & 22 deletions src/ui/views/session/dialogs/MemberListDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import { BadgeWrapper } from "../../../atoms/badge/BadgeWrapper";
import { NotificationBadge } from "../../../atoms/badge/NotificationBadge";
import { useAnimationFrame } from "../nametags/Nametags";
import { setPowerLevel } from "../../../utils/matrixUtils";
import { PowerLevelSelector } from "./PowerLevelSelector";

interface MemberListDialogProps {
room: Room;
Expand Down Expand Up @@ -65,15 +66,17 @@ export function MemberListDialog({ room, requestClose }: MemberListDialogProps)

const { active, invited, joined, leaved, banned } = useRoomMembers(room) ?? {};
const [inviteOpen, setInviteOpen] = useState(false);
const [changeUserIdPL, setChangeUserIdPL] = useState<string>();

const isWorld = room.type === "org.matrix.msc3815.world";
const filteredJoined = joined?.filter((member) => !active?.find((m) => m.userId === member.userId));

const { canDoAction, getPowerLevel } = usePowerLevels(room);
const { canDoAction, getPowerLevel, canSendStateEvent } = usePowerLevels(room);
const myPL = getPowerLevel(session.userId);
const canInvite = canDoAction("invite", myPL);
const canKick = canDoAction("kick", myPL);
const canBan = canDoAction("ban", myPL);
const canChangePL = canSendStateEvent("m.room.power_levels", myPL);

const [activeCat, setActiveCat] = useState(true);
const [joinedCat, setJoinedCat] = useState(true);
Expand All @@ -86,9 +89,6 @@ export function MemberListDialog({ room, requestClose }: MemberListDialogProps)
const kick = (roomId: string, userId: string) => session.hsApi.kick(roomId, userId);
const ban = (roomId: string, userId: string) => session.hsApi.ban(roomId, userId);
const unban = (roomId: string, userId: string) => session.hsApi.unban(roomId, userId);
const makeMember = (roomId: string, userId: string) => setPowerLevel(session, roomId, userId, 0);
const makeMod = (roomId: string, userId: string) => setPowerLevel(session, roomId, userId, 50);
const makeAdmin = (roomId: string, userId: string) => setPowerLevel(session, roomId, userId, 100);

const engine = useMainThreadContext();
const toggleMute = (userId: string) => toggleMutePeer(engine, userId);
Expand Down Expand Up @@ -123,6 +123,13 @@ export function MemberListDialog({ room, requestClose }: MemberListDialogProps)
Ignore
</DropdownMenuItem>,
];
if (canChangePL && myPL > userPL) {
menuItems.push(
<DropdownMenuItem key="change-pl" onSelect={() => setChangeUserIdPL(userId)}>
Change Power Level
</DropdownMenuItem>
);
}
switch (membership) {
case "join":
if (canKick && myPL > userPL)
Expand All @@ -137,23 +144,6 @@ export function MemberListDialog({ room, requestClose }: MemberListDialogProps)
Ban
</DropdownMenuItem>
);
if (myPL === 100) {
menuItems.push(
<DropdownMenuItem key="make-member" disabled={userPL === 0} onSelect={() => makeMember(room.id, userId)}>
Make Member
</DropdownMenuItem>
);
menuItems.push(
<DropdownMenuItem key="make-mod" disabled={userPL === 50} onSelect={() => makeMod(room.id, userId)}>
Make Moderator
</DropdownMenuItem>
);
menuItems.push(
<DropdownMenuItem key="make-admin" disabled={userPL === 100} onSelect={() => makeAdmin(room.id, userId)}>
Make Admin
</DropdownMenuItem>
);
}
break;
case "ban":
if (canKick && myPL > userPL)
Expand Down Expand Up @@ -209,7 +199,7 @@ export function MemberListDialog({ room, requestClose }: MemberListDialogProps)
{name}
</Text>
<Text className="truncate" color="surface-low" variant="b3">
{userId}
{`${userId} • PL: ${getPowerLevel(userId)}`}
</Text>
</>
}
Expand All @@ -227,6 +217,22 @@ export function MemberListDialog({ room, requestClose }: MemberListDialogProps)

return (
<>
<Dialog open={!!changeUserIdPL} onOpenChange={() => setChangeUserIdPL(undefined)}>
<Header
left={<HeaderTitle size="lg">Power Level Selector</HeaderTitle>}
right={<IconButton iconSrc={CrossIC} onClick={() => setChangeUserIdPL(undefined)} label="Close" />}
/>
{changeUserIdPL && (
<PowerLevelSelector
value={getPowerLevel(changeUserIdPL)}
max={myPL}
onSelect={(newPL) => {
setPowerLevel(session, room.id, changeUserIdPL, newPL);
setChangeUserIdPL(undefined);
}}
/>
)}
</Dialog>
<Header
left={<HeaderTitle size="lg">Members</HeaderTitle>}
right={
Expand Down
54 changes: 54 additions & 0 deletions src/ui/views/session/dialogs/PowerLevelSelector.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { NumericInput } from "../../../atoms/input/NumericInput";
import { MenuItem } from "../../../atoms/menu/MenuItem";
import { Label } from "../../../atoms/text/Label";

interface PowerLevelSelectorProps {
value: number;
max: number;
onSelect: (value: number) => void;
}

export function PowerLevelSelector({ value, max, onSelect }: PowerLevelSelectorProps) {
const handleSubmit = (powerLevel: number) => {
if (!powerLevel) return;
onSelect(powerLevel);
};

return (
<div className="power-level-selector flex flex-column gap-md">
<div className="flex flex-column gap-xxs" style={{ padding: "0 var(--sp-md)" }}>
<Label>Select Power Level</Label>
<NumericInput
value={value}
type="u32"
onChange={handleSubmit}
max={max}
mdStep={1}
smStep={5}
lgStep={10}
placeholder="Power level"
autoComplete="off"
required
/>
</div>
<div>
{max >= 0 && <Label style={{ padding: "0 var(--sp-md)" }}>Presets</Label>}
{max >= 100 && (
<MenuItem variant={value === 100 ? "primary" : "surface"} onClick={() => onSelect(100)}>
Admin - 100
</MenuItem>
)}
{max >= 50 && (
<MenuItem variant={value === 50 ? "primary" : "surface"} onClick={() => onSelect(50)}>
Mod - 50
</MenuItem>
)}
{max >= 0 && (
<MenuItem variant={value === 0 ? "primary" : "surface"} onClick={() => onSelect(0)}>
Member - 0
</MenuItem>
)}
</div>
</div>
);
}