Files
Nitro-V3/src/components/mod-tools/views/room/ModToolsRoomView.tsx
T
simoleo89 349498ec34 Localize all hardcoded texts in mod tools using LocalizeText
Replace ~70 hardcoded English strings across 15 mod-tools files
with LocalizeText() calls using moderation.* keys matching the
existing ExternalTexts convention. Includes mod-tools-external-texts.json
with all required keys for ExternalTexts.json.
2026-03-18 20:46:07 +01:00

123 lines
6.9 KiB
TypeScript

import { CreateLinkEvent, GetModeratorRoomInfoMessageComposer, ModerateRoomMessageComposer, ModeratorActionMessageComposer, ModeratorRoomInfoEvent } from '@nitrots/nitro-renderer';
import { FC, useEffect, useState } from 'react';
import { LocalizeText, SendMessageComposer, TryVisitRoom } from '../../../../api';
import { Button, Column, DraggableWindowPosition, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../common';
import { useMessageEvent } from '../../../../hooks';
interface ModToolsRoomViewProps
{
roomId: number;
onCloseClick: () => void;
}
export const ModToolsRoomView: FC<ModToolsRoomViewProps> = props =>
{
const { roomId = null, onCloseClick = null } = props;
const [ infoRequested, setInfoRequested ] = useState(false);
const [ loadedRoomId, setLoadedRoomId ] = useState(null);
const [ name, setName ] = useState(null);
const [ ownerId, setOwnerId ] = useState(null);
const [ ownerName, setOwnerName ] = useState(null);
const [ ownerInRoom, setOwnerInRoom ] = useState(false);
const [ usersInRoom, setUsersInRoom ] = useState(0);
const [ kickUsers, setKickUsers ] = useState(false);
const [ lockRoom, setLockRoom ] = useState(false);
const [ changeRoomName, setChangeRoomName ] = useState(false);
const [ message, setMessage ] = useState('');
const handleClick = (action: string, value?: string) =>
{
if(!action) return;
switch(action)
{
case 'alert_only':
if(message.trim().length === 0) return;
SendMessageComposer(new ModeratorActionMessageComposer(ModeratorActionMessageComposer.ACTION_ALERT, message, ''));
SendMessageComposer(new ModerateRoomMessageComposer(roomId, lockRoom ? 1 : 0, changeRoomName ? 1 : 0, kickUsers ? 1 : 0));
return;
case 'send_message':
if(message.trim().length === 0) return;
SendMessageComposer(new ModeratorActionMessageComposer(ModeratorActionMessageComposer.ACTION_MESSAGE, message, ''));
SendMessageComposer(new ModerateRoomMessageComposer(roomId, lockRoom ? 1 : 0, changeRoomName ? 1 : 0, kickUsers ? 1 : 0));
return;
}
};
useMessageEvent<ModeratorRoomInfoEvent>(ModeratorRoomInfoEvent, event =>
{
const parser = event.getParser();
if(!parser || parser.data.flatId !== roomId) return;
setLoadedRoomId(parser.data.flatId);
setName(parser.data.room.name);
setOwnerId(parser.data.ownerId);
setOwnerName(parser.data.ownerName);
setOwnerInRoom(parser.data.ownerInRoom);
setUsersInRoom(parser.data.userCount);
});
useEffect(() =>
{
if(infoRequested) return;
SendMessageComposer(new GetModeratorRoomInfoMessageComposer(roomId));
setInfoRequested(true);
}, [ roomId, infoRequested, setInfoRequested ]);
return (
<NitroCardView className="nitro-mod-tools-room min-w-[280px]" theme="primary-slim" windowPosition={ DraggableWindowPosition.TOP_LEFT }>
<NitroCardHeaderView headerText={ LocalizeText('moderation.roomtool.info.title') } onCloseClick={ event => onCloseClick() } />
<NitroCardContentView className="text-black" gap={ 2 }>
{ name &&
<div className="bg-muted rounded px-2 py-1.5 text-center">
<Text bold truncate>{ name }</Text>
</div>
}
<div className="flex gap-2">
<Column grow gap={ 1 }>
<div className="flex items-center gap-1">
<Text bold className="opacity-60 shrink-0">{ LocalizeText('moderation.roomtool.roomowner.title') }</Text>
<Text bold pointer truncate underline onClick={ () => CreateLinkEvent(`mod-tools/open-user-info/${ ownerId }`) }>{ ownerName }</Text>
</div>
<div className="flex items-center gap-1">
<Text bold className="opacity-60 shrink-0">{ LocalizeText('moderation.roomtool.usersinroom.title') }</Text>
<Text>{ usersInRoom }</Text>
</div>
<div className="flex items-center gap-1">
<Text bold className="opacity-60 shrink-0">{ LocalizeText('moderation.roomtool.ownerinroom.title') }</Text>
<Text className={ ownerInRoom ? 'text-green-700' : 'text-red-700' }>{ ownerInRoom ? LocalizeText('moderation.roomtool.true.title') : LocalizeText('moderation.roomtool.false.title') }</Text>
</div>
</Column>
<div className="flex flex-col gap-1 shrink-0">
<Button onClick={ event => TryVisitRoom(roomId) }>{ LocalizeText('moderation.roomtool.button.visit.title') }</Button>
<Button onClick={ event => CreateLinkEvent(`mod-tools/open-room-chatlog/${ roomId }`) }>{ LocalizeText('moderation.modtools.roomchatlogs') }</Button>
</div>
</div>
<Column className="bg-muted rounded p-2" gap={ 1 }>
<div className="flex items-center gap-2">
<input checked={ kickUsers } className="form-check-input" type="checkbox" onChange={ event => setKickUsers(event.target.checked) } />
<Text small>{ LocalizeText('moderation.roomtool.kickall.title') }</Text>
</div>
<div className="flex items-center gap-2">
<input checked={ lockRoom } className="form-check-input" type="checkbox" onChange={ event => setLockRoom(event.target.checked) } />
<Text small>{ LocalizeText('moderation.roomtool.closeroom.title') }</Text>
</div>
<div className="flex items-center gap-2">
<input checked={ changeRoomName } className="form-check-input" type="checkbox" onChange={ event => setChangeRoomName(event.target.checked) } />
<Text small>{ LocalizeText('moderation.roomtool.inappropiatename.title') }</Text>
</div>
</Column>
<textarea className="min-h-[60px] px-2 py-1.5 rounded text-sm border border-black/10" placeholder={ LocalizeText('moderation.roomtool.presets.title') } value={ message } onChange={ event => setMessage(event.target.value) }></textarea>
<div className="flex gap-2">
<Button className="grow" variant="danger" onClick={ event => handleClick('send_message') }>{ LocalizeText('moderation.roomtool.button.caution.title') }</Button>
<Button className="grow" onClick={ event => handleClick('alert_only') }>{ LocalizeText('moderation.roomtool.button.message.title') }</Button>
</div>
</NitroCardContentView>
</NitroCardView>
);
};