From 5d38bae59c219ab767b50c2756cc61dac4dbaa1f Mon Sep 17 00:00:00 2001 From: Regalijan Date: Tue, 24 Oct 2023 00:32:53 -0400 Subject: [PATCH] Use MessageChannels to self-delete queue items Previous method would cause site to die --- app/routes/mod-queue.tsx | 61 ++++++++++++++++++++++++----- components/AppealCard.tsx | 4 +- components/GameAppealCard.tsx | 6 +-- components/InactivityNoticeCard.tsx | 20 +++++----- components/ReportCard.tsx | 20 +++++----- 5 files changed, 75 insertions(+), 36 deletions(-) diff --git a/app/routes/mod-queue.tsx b/app/routes/mod-queue.tsx index 5717823..83248e5 100644 --- a/app/routes/mod-queue.tsx +++ b/app/routes/mod-queue.tsx @@ -18,7 +18,7 @@ import { useToast, VStack, } from "@chakra-ui/react"; -import { type ReactElement, useEffect, useState } from "react"; +import { type ReactNode, useEffect, useState } from "react"; import AppealCard from "../../components/AppealCard.js"; import GameAppealCard from "../../components/GameAppealCard.js"; import NewGameBan from "../../components/NewGameBan.js"; @@ -115,8 +115,11 @@ export default function () { const pageProps = useLoaderData(); const isDesktop = useBreakpointValue({ base: false, lg: true }); const entryTypes = []; - const [entries, setEntries] = useState([] as ReactElement[]); + const [entries, setEntries] = useState( + [] as { element: ReactNode; id: string }[], + ); const [before, setBefore] = useState(Date.now()); + const [messageChannel] = useState(null as MessageChannel | null); const toast = useToast(); for (const type of pageProps.entry_types) @@ -126,6 +129,16 @@ export default function () { , ); + useEffect(() => { + if (!messageChannel) return; + + messageChannel.port1.onmessage = function (ev) { + const { data }: { data: string } = ev; + + setEntries([...entries].filter((entry) => entry.id !== data)); + }; + }, [messageChannel]); + async function updateQueue( queue_type: string, before: number, @@ -212,24 +225,54 @@ export default function () { switch (cardType) { case "appeal": - newEntries.push(); + newEntries.push({ + element: ( + + ), + id: `appeal_${entry.id}`, + }); break; case "gma": - newEntries.push(); + newEntries.push({ + element: ( + + ), + id: `gma_${entry.id}`, + }); break; case "inactivity": - newEntries.push( - , - ); + newEntries.push({ + element: ( + + ), + id: `inactivity_${entry.id}`, + }); break; case "report": - newEntries.push(); + newEntries.push({ + element: ( + + ), + id: `report_${entry.id}`, + }); break; } @@ -311,7 +354,7 @@ export default function () { {ItemDisplay} {entries.length ? ( - entries + entries.map((entry) => entry.element) ) : ( ( - + ); const Denied = () => ( - + ); diff --git a/components/ReportCard.tsx b/components/ReportCard.tsx index 35294c9..a44734a 100644 --- a/components/ReportCard.tsx +++ b/components/ReportCard.tsx @@ -13,11 +13,11 @@ import { Stack, Text, useToast, - VStack + VStack, } from "@chakra-ui/react"; import { useState } from "react"; -export default function(props: ReportCardProps) { +export default function (props: ReportCardProps & { port?: MessagePort }) { const [attachmentIdx, setAttachmentIdx] = useState(0); const [loading, setLoading] = useState(false); const toast = useToast(); @@ -26,7 +26,7 @@ export default function(props: ReportCardProps) { for (let i = 0; i < props.target_ids.length; i++) Object.defineProperty(targetMap, props.target_ids[i], { - value: props.target_usernames[i] + value: props.target_usernames[i], }); async function submitActions() { @@ -34,9 +34,9 @@ export default function(props: ReportCardProps) { const submitReq = await fetch(`/api/reports/${props.id}/action`, { body: JSON.stringify(actionMap), headers: { - "content-type": "application/json" + "content-type": "application/json", }, - method: "POST" + method: "POST", }); if (!submitReq.ok) { @@ -44,7 +44,7 @@ export default function(props: ReportCardProps) { toast({ description: ((await submitReq.json()) as { error: string }).error, status: "error", - title: "S̸̯̜̈́o̴̳̅̾̏̽m̴͔͕̈́̋ē̴̙͓̯̍̃ț̸͖̘̀h̶̛̳̝̐i̵̋͘͜ņ̷̙̤͌g̴̭̻̓̈́ ̴̘͍̦̪̆w̸̡̏̑̊é̸̠̖̹̂͜n̴̖̳̤̕t̴͚̊̊̕ ̸̛͙̺̬̎́w̴͈͑̋͊r̷̢̛o̵̱̩̍͋ͅṇ̸̝̰̮́g̵̡̢̦͕͂" + title: "S̸̯̜̈́o̴̳̅̾̏̽m̴͔͕̈́̋ē̴̙͓̯̍̃ț̸͖̘̀h̶̛̳̝̐i̵̋͘͜ņ̷̙̤͌g̴̭̻̓̈́ ̴̘͍̦̪̆w̸̡̏̑̊é̸̠̖̹̂͜n̴̖̳̤̕t̴͚̊̊̕ ̸̛͙̺̬̎́w̴͈͑̋͊r̷̢̛o̵̱̩̍͋ͅṇ̸̝̰̮́g̵̡̢̦͕͂", }); return; @@ -53,10 +53,10 @@ export default function(props: ReportCardProps) { toast({ description: "Actions were successfully applied", status: "success", - title: "Success" + title: "Success", }); setLoading(false); - location.reload(); + props.port?.postMessage(`report_${props.id}`); } return ( @@ -132,7 +132,7 @@ export default function(props: ReportCardProps) { - {(function() { + {(function () { const radioGroups = []; for (let i = 0; i < props.target_ids.length; i++) { radioGroups.push( @@ -154,7 +154,7 @@ export default function(props: ReportCardProps) { Ban - + , ); }