Add option to kick user in profile viewer

Signed-off-by: Ajay Bura <ajbura@gmail.com>
This commit is contained in:
Ajay Bura 2022-01-12 18:26:52 +05:30
parent e38ddebfb6
commit 248fc15716
3 changed files with 79 additions and 15 deletions

View file

@ -17,6 +17,7 @@ import colorMXID from '../../../util/colorMXID';
import Text from '../../atoms/text/Text';
import Chip from '../../atoms/chip/Chip';
import IconButton from '../../atoms/button/IconButton';
import Input from '../../atoms/input/Input';
import Avatar from '../../atoms/avatar/Avatar';
import Button from '../../atoms/button/Button';
import PowerLevelSelector from '../../molecules/power-level-selector/PowerLevelSelector';
@ -29,6 +30,45 @@ import CrossIC from '../../../../public/res/ic/outlined/cross.svg';
import { useForceUpdate } from '../../hooks/useForceUpdate';
function ModerationTools({
roomId, userId,
}) {
const mx = initMatrix.matrixClient;
const room = mx.getRoom(roomId);
const roomMember = room.getMember(userId);
const myPowerLevel = room.getMember(mx.getUserId()).powerLevel;
const powerLevel = roomMember?.powerLevel || 0;
const canIKick = (
roomMember?.membership === 'join'
&& room.currentState.hasSufficientPowerLevelFor('kick', myPowerLevel)
&& powerLevel < myPowerLevel
);
const handleKick = (e) => {
e.preventDefault();
const kickReason = e.target.elements['kick-reason']?.value.trim();
roomActions.kick(roomId, userId, kickReason !== '' ? kickReason : undefined);
};
return (
<div className="moderation-tools">
{canIKick && (
<>
<form onSubmit={handleKick}>
<Input label="Kick reason" name="kick-reason" />
<Button type="submit">Kick</Button>
</form>
</>
)}
</div>
);
}
ModerationTools.propTypes = {
roomId: PropTypes.string.isRequired,
userId: PropTypes.string.isRequired,
};
function SessionInfo({ userId }) {
const [devices, setDevices] = useState(null);
const mx = initMatrix.matrixClient;
@ -257,25 +297,30 @@ function useToggleDialog() {
return [isOpen, roomId, userId, closeDialog, afterClose];
}
function useRerenderOnRoleChange(roomId, userId) {
function useRerenderOnProfileChange(roomId, userId) {
const mx = initMatrix.matrixClient;
const [, forceUpdate] = useForceUpdate();
useEffect(() => {
const handlePowerLevelChange = (mEvent, member) => {
if (mEvent.getRoomId() === roomId && member.userId === userId) {
const handleProfileChange = (mEvent, member) => {
if (
mEvent.getRoomId() === roomId
&& (member.userId === userId || member.userId === mx.getUserId())
) {
forceUpdate();
}
};
mx.on('RoomMember.powerLevel', handlePowerLevelChange);
mx.on('RoomMember.powerLevel', handleProfileChange);
mx.on('RoomMember.membership', handleProfileChange);
return () => {
mx.removeListener('RoomMember.powerLevel', handlePowerLevelChange);
mx.removeListener('RoomMember.powerLevel', handleProfileChange);
mx.removeListener('RoomMember.membership', handleProfileChange);
};
}, [roomId, userId]);
}
function ProfileViewer() {
const [isOpen, roomId, userId, closeDialog, handleAfterClose] = useToggleDialog();
useRerenderOnRoleChange(roomId, userId);
useRerenderOnProfileChange(roomId, userId);
const mx = initMatrix.matrixClient;
const room = mx.getRoom(roomId);
@ -288,8 +333,8 @@ function ProfileViewer() {
}
const renderProfile = () => {
const avatarMxc = roomMember.getMxcAvatarUrl?.() || mx.getMember(userId).avatarUrl;
const avatarUrl = avatarMxc ? mx.mxcUrlToHttp(avatarMxc, 80, 80, 'crop') : null;
const avatarMxc = roomMember?.getMxcAvatarUrl?.() || mx.getUser(userId).avatarUrl;
const avatarUrl = (avatarMxc && avatarMxc !== 'null') ? mx.mxcUrlToHttp(avatarMxc, 80, 80, 'crop') : null;
const powerLevel = roomMember.powerLevel || 0;
const myPowerLevel = room.getMember(mx.getUserId())?.powerLevel || 0;
@ -344,13 +389,10 @@ function ProfileViewer() {
</Button>
</div>
</div>
<ModerationTools roomId={roomId} userId={userId} />
<SessionInfo userId={userId} />
{ userId !== mx.getUserId() && (
<ProfileFooter
roomId={roomId}
userId={userId}
onRequestClose={closeDialog}
/>
<ProfileFooter roomId={roomId} userId={userId} onRequestClose={closeDialog} />
)}
</div>
);

View file

@ -1,3 +1,4 @@
@use '../../partials/flex';
@use '../../partials/dir';
.profile-viewer__dialog {
@ -61,6 +62,27 @@
}
}
.profile-viewer__admin-tool {
.setting-tile {
margin-top: var(--sp-loose);
}
}
.moderation-tools {
& > form {
margin: var(--sp-normal) 0;
display: flex;
align-items: flex-end;
& .input-container {
@extend .cp-fx__item-one;
@include dir.side(margin, 0, var(--sp-tight));
}
& button {
height: 46px;
}
}
}
.session-info {
& .setting-tile__title .text {
color: var(--tc-surface-high);

View file

@ -192,10 +192,10 @@ async function invite(roomId, userId) {
return result;
}
async function kick(roomId, userId) {
async function kick(roomId, userId, reason) {
const mx = initMatrix.matrixClient;
const result = await mx.kick(roomId, userId);
const result = await mx.kick(roomId, userId, reason);
return result;
}