Add tournament and multiplayer community chat moderation
All checks were successful
Deploy MineGeo to Dokploy / deploy (push) Successful in 12m17s

This commit is contained in:
2026-10-27 12:54:15 +05:00
parent b8a430d4c2
commit 9c314ecb4e
19 changed files with 1070 additions and 16 deletions

View File

@@ -15,11 +15,13 @@ export function RoomChat({
playerId,
available,
playing,
endpoint,
}: {
id: string;
playerId: string | null;
available: boolean;
playing: boolean;
endpoint?: string;
}) {
const { t } = useI18n();
const [open, setOpen] = useState(false);
@@ -38,12 +40,7 @@ export function RoomChat({
const followLatest = useRef(true);
const enabled = !!playerId && available;
const accept = useCallback((view: ChatView) => {
setMessages((previous) =>
previous.length === view.messages.length &&
previous.at(-1)?.id === view.messages.at(-1)?.id
? previous
: view.messages,
);
setMessages(view.messages);
if (!initialized.current) {
initialized.current = true;
setLastRead(BigInt(view.messages.at(-1)?.id ?? "0"));
@@ -54,12 +51,12 @@ export function RoomChat({
if (inFlight.current) return;
const current = ++version.current;
try {
const view = await api<ChatView>(`rooms/${id}/chat`);
const view = await api<ChatView>(endpoint ?? `rooms/${id}/chat`);
if (current === version.current) accept(view);
} catch (failure) {
if (current === version.current) setError((failure as Error).message);
}
}, [id, accept]);
}, [id, endpoint, accept]);
useEffect(() => {
if (!enabled) return;
let stopped = false;
@@ -111,7 +108,7 @@ export function RoomChat({
setError("");
const current = ++version.current;
try {
const view = await api<ChatView>(`rooms/${id}/chat`, body);
const view = await api<ChatView>(endpoint ?? `rooms/${id}/chat`, body);
if (current === version.current) {
accept(view);
followLatest.current = true;
@@ -199,6 +196,7 @@ export function RoomChat({
>
<strong>
<Username name={message.name} appearance={message.appearance} />
{message.tag && <small> · {message.tag}</small>}
{message.playerId === playerId && ` ${t("(you)")}`}
</strong>
<span>{message.text}</span>