Add option to kick user in profile viewer
Signed-off-by: Ajay Bura <ajbura@gmail.com>
This commit is contained in:
parent
e38ddebfb6
commit
248fc15716
3 changed files with 79 additions and 15 deletions
|
@ -17,6 +17,7 @@ import colorMXID from '../../../util/colorMXID';
|
||||||
import Text from '../../atoms/text/Text';
|
import Text from '../../atoms/text/Text';
|
||||||
import Chip from '../../atoms/chip/Chip';
|
import Chip from '../../atoms/chip/Chip';
|
||||||
import IconButton from '../../atoms/button/IconButton';
|
import IconButton from '../../atoms/button/IconButton';
|
||||||
|
import Input from '../../atoms/input/Input';
|
||||||
import Avatar from '../../atoms/avatar/Avatar';
|
import Avatar from '../../atoms/avatar/Avatar';
|
||||||
import Button from '../../atoms/button/Button';
|
import Button from '../../atoms/button/Button';
|
||||||
import PowerLevelSelector from '../../molecules/power-level-selector/PowerLevelSelector';
|
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';
|
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 }) {
|
function SessionInfo({ userId }) {
|
||||||
const [devices, setDevices] = useState(null);
|
const [devices, setDevices] = useState(null);
|
||||||
const mx = initMatrix.matrixClient;
|
const mx = initMatrix.matrixClient;
|
||||||
|
@ -257,25 +297,30 @@ function useToggleDialog() {
|
||||||
return [isOpen, roomId, userId, closeDialog, afterClose];
|
return [isOpen, roomId, userId, closeDialog, afterClose];
|
||||||
}
|
}
|
||||||
|
|
||||||
function useRerenderOnRoleChange(roomId, userId) {
|
function useRerenderOnProfileChange(roomId, userId) {
|
||||||
const mx = initMatrix.matrixClient;
|
const mx = initMatrix.matrixClient;
|
||||||
const [, forceUpdate] = useForceUpdate();
|
const [, forceUpdate] = useForceUpdate();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handlePowerLevelChange = (mEvent, member) => {
|
const handleProfileChange = (mEvent, member) => {
|
||||||
if (mEvent.getRoomId() === roomId && member.userId === userId) {
|
if (
|
||||||
|
mEvent.getRoomId() === roomId
|
||||||
|
&& (member.userId === userId || member.userId === mx.getUserId())
|
||||||
|
) {
|
||||||
forceUpdate();
|
forceUpdate();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
mx.on('RoomMember.powerLevel', handlePowerLevelChange);
|
mx.on('RoomMember.powerLevel', handleProfileChange);
|
||||||
|
mx.on('RoomMember.membership', handleProfileChange);
|
||||||
return () => {
|
return () => {
|
||||||
mx.removeListener('RoomMember.powerLevel', handlePowerLevelChange);
|
mx.removeListener('RoomMember.powerLevel', handleProfileChange);
|
||||||
|
mx.removeListener('RoomMember.membership', handleProfileChange);
|
||||||
};
|
};
|
||||||
}, [roomId, userId]);
|
}, [roomId, userId]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function ProfileViewer() {
|
function ProfileViewer() {
|
||||||
const [isOpen, roomId, userId, closeDialog, handleAfterClose] = useToggleDialog();
|
const [isOpen, roomId, userId, closeDialog, handleAfterClose] = useToggleDialog();
|
||||||
useRerenderOnRoleChange(roomId, userId);
|
useRerenderOnProfileChange(roomId, userId);
|
||||||
|
|
||||||
const mx = initMatrix.matrixClient;
|
const mx = initMatrix.matrixClient;
|
||||||
const room = mx.getRoom(roomId);
|
const room = mx.getRoom(roomId);
|
||||||
|
@ -288,8 +333,8 @@ function ProfileViewer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const renderProfile = () => {
|
const renderProfile = () => {
|
||||||
const avatarMxc = roomMember.getMxcAvatarUrl?.() || mx.getMember(userId).avatarUrl;
|
const avatarMxc = roomMember?.getMxcAvatarUrl?.() || mx.getUser(userId).avatarUrl;
|
||||||
const avatarUrl = avatarMxc ? mx.mxcUrlToHttp(avatarMxc, 80, 80, 'crop') : null;
|
const avatarUrl = (avatarMxc && avatarMxc !== 'null') ? mx.mxcUrlToHttp(avatarMxc, 80, 80, 'crop') : null;
|
||||||
|
|
||||||
const powerLevel = roomMember.powerLevel || 0;
|
const powerLevel = roomMember.powerLevel || 0;
|
||||||
const myPowerLevel = room.getMember(mx.getUserId())?.powerLevel || 0;
|
const myPowerLevel = room.getMember(mx.getUserId())?.powerLevel || 0;
|
||||||
|
@ -344,13 +389,10 @@ function ProfileViewer() {
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<ModerationTools roomId={roomId} userId={userId} />
|
||||||
<SessionInfo userId={userId} />
|
<SessionInfo userId={userId} />
|
||||||
{ userId !== mx.getUserId() && (
|
{ userId !== mx.getUserId() && (
|
||||||
<ProfileFooter
|
<ProfileFooter roomId={roomId} userId={userId} onRequestClose={closeDialog} />
|
||||||
roomId={roomId}
|
|
||||||
userId={userId}
|
|
||||||
onRequestClose={closeDialog}
|
|
||||||
/>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
@use '../../partials/flex';
|
||||||
@use '../../partials/dir';
|
@use '../../partials/dir';
|
||||||
|
|
||||||
.profile-viewer__dialog {
|
.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 {
|
.session-info {
|
||||||
& .setting-tile__title .text {
|
& .setting-tile__title .text {
|
||||||
color: var(--tc-surface-high);
|
color: var(--tc-surface-high);
|
||||||
|
|
|
@ -192,10 +192,10 @@ async function invite(roomId, userId) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function kick(roomId, userId) {
|
async function kick(roomId, userId, reason) {
|
||||||
const mx = initMatrix.matrixClient;
|
const mx = initMatrix.matrixClient;
|
||||||
|
|
||||||
const result = await mx.kick(roomId, userId);
|
const result = await mx.kick(roomId, userId, reason);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue