diff --git a/web/src/hooks/useModerationMutations.ts b/web/src/hooks/useModerationMutations.ts new file mode 100644 index 0000000..258251b --- /dev/null +++ b/web/src/hooks/useModerationMutations.ts @@ -0,0 +1,53 @@ +import { useMutation } from "@tanstack/react-query"; +import { useAuth } from "../lib/auth"; +import { resolveIdentity } from "../lib/atproto"; +import { + createBan, + createHide, + deleteBan, + deleteHide, +} from "../lib/writes"; +import { alertOnError } from "../lib/alerts"; + +// Shared ban/unban/hide/unhide mutations +// `ban` accepts either a DID or a handle +export function useModerationMutations() { + const { agent } = useAuth(); + + const ban = useMutation({ + mutationFn: async (identifier: string) => { + if (!agent) throw new Error("Not signed in"); + const did = identifier.startsWith("did:") + ? identifier + : (await resolveIdentity(identifier)).did; + await createBan(agent, did); + }, + onError: alertOnError("ban"), + }); + + const unban = useMutation({ + mutationFn: async (rkey: string) => { + if (!agent) throw new Error("Not signed in"); + await deleteBan(agent, rkey); + }, + onError: alertOnError("unban"), + }); + + const hide = useMutation({ + mutationFn: async (uri: string) => { + if (!agent) throw new Error("Not signed in"); + await createHide(agent, uri); + }, + onError: alertOnError("hide"), + }); + + const unhide = useMutation({ + mutationFn: async (rkey: string) => { + if (!agent) throw new Error("Not signed in"); + await deleteHide(agent, rkey); + }, + onError: alertOnError("unhide"), + }); + + return { ban, unban, hide, unhide }; +} diff --git a/web/src/pages/SysopModerate.tsx b/web/src/pages/SysopModerate.tsx index 9391751..305dc34 100644 --- a/web/src/pages/SysopModerate.tsx +++ b/web/src/pages/SysopModerate.tsx @@ -1,21 +1,14 @@ import { useState } from "react"; -import { useSuspenseQuery, useMutation } from "@tanstack/react-query"; +import { useSuspenseQuery } from "@tanstack/react-query"; import { useAuth } from "../lib/auth"; -import { resolveIdentity } from "../lib/atproto"; import { bbsQuery, sysopModerationQuery } from "../lib/queries"; import HandleInput from "../components/form/HandleInput"; import { Button } from "../components/form/Form"; import { usePageTitle } from "../hooks/usePageTitle"; -import { - createBan, - createHide, - deleteBan, - deleteHide, -} from "../lib/writes"; -import { alertOnError } from "../lib/alerts"; +import { useModerationMutations } from "../hooks/useModerationMutations"; export default function SysopModerate() { - const { user, agent } = useAuth(); + const { user } = useAuth(); const [identifier, setIdentifier] = useState(""); const [hideUri, setHideUri] = useState(""); usePageTitle("Moderate community — atbbs"); @@ -27,62 +20,31 @@ export default function SysopModerate() { ); const { banRkeys, bannedHandles, hideRkeys, hidden } = moderation; - const banMutation = useMutation({ - mutationFn: async (identifier: string) => { - if (!agent) throw new Error("Not signed in"); - let did = identifier; - if (!did.startsWith("did:")) did = (await resolveIdentity(did)).did; - await createBan(agent, did); - }, - onSuccess: () => setIdentifier(""), - onError: alertOnError("ban"), - }); + const { ban, unban, hide, unhide } = useModerationMutations(); - const unbanMutation = useMutation({ - mutationFn: async (rkey: string) => { - if (!agent) throw new Error("Not signed in"); - await deleteBan(agent, rkey); - }, - }); - - const hideMutation = useMutation({ - mutationFn: async (uri: string) => { - if (!agent) throw new Error("Not signed in"); - await createHide(agent, uri); - }, - onSuccess: () => setHideUri(""), - }); - - const unhideMutation = useMutation({ - mutationFn: async (rkey: string) => { - if (!agent) throw new Error("Not signed in"); - await deleteHide(agent, rkey); - }, - }); - - function ban() { + function onBan() { const id = identifier.trim(); if (!id) return; - banMutation.mutate(id); + ban.mutate(id, { onSuccess: () => setIdentifier("") }); } - function unban(rkey: string) { + function onUnban(rkey: string) { if (!confirm("Unban this user?")) return; - unbanMutation.mutate(rkey); + unban.mutate(rkey); } - function hide() { + function onHide() { const uri = hideUri.trim(); if (!uri.startsWith("at://")) { alert("Enter a valid AT-URI."); return; } - hideMutation.mutate(uri); + hide.mutate(uri, { onSuccess: () => setHideUri("") }); } - function unhide(rkey: string) { + function onUnhide(rkey: string) { if (!confirm("Unhide this post?")) return; - unhideMutation.mutate(rkey); + unhide.mutate(rkey); } return ( @@ -113,7 +75,7 @@ export default function SysopModerate() { {banRkeys[did] && ( + @@ -153,7 +115,7 @@ export default function SysopModerate() { {hideRkeys[post.uri] && ( + diff --git a/web/src/pages/Thread.tsx b/web/src/pages/Thread.tsx index 6511659..f952bca 100644 --- a/web/src/pages/Thread.tsx +++ b/web/src/pages/Thread.tsx @@ -9,14 +9,11 @@ import { BOARD, POST } from "../lib/lexicon"; import { makeAtUri, nowIso, parseAtUri } from "../lib/util"; import * as limits from "../lib/limits"; import { - createBan, - createHide, createPost, - deleteBan, - deleteHide, deleteRecord, uploadAttachments, } from "../lib/writes"; +import { useModerationMutations } from "../hooks/useModerationMutations"; import { bbsModerationQuery, bbsQuery, @@ -174,33 +171,7 @@ export default function ThreadPage() { onError: alertOnError("delete"), }); - const banMutation = useMutation({ - mutationFn: async (banDid: string) => { - if (!agent) throw new Error("Not signed in"); - await createBan(agent, banDid); - }, - }); - - const unbanMutation = useMutation({ - mutationFn: async (rkey: string) => { - if (!agent) throw new Error("Not signed in"); - await deleteBan(agent, rkey); - }, - }); - - const hideMutation = useMutation({ - mutationFn: async (uri: string) => { - if (!agent) throw new Error("Not signed in"); - await createHide(agent, uri); - }, - }); - - const unhideMutation = useMutation({ - mutationFn: async (rkey: string) => { - if (!agent) throw new Error("Not signed in"); - await deleteHide(agent, rkey); - }, - }); + const { ban, unban, hide, unhide } = useModerationMutations(); // --- Handlers --- @@ -226,22 +197,22 @@ export default function ThreadPage() { function onBan(banDid: string) { if (!confirm("Ban this user from your community?")) return; - banMutation.mutate(banDid); + ban.mutate(banDid); } function onUnban(rkey: string) { if (!confirm("Unban this user?")) return; - unbanMutation.mutate(rkey); + unban.mutate(rkey); } function onHide(uri: string) { if (!confirm("Hide this post?")) return; - hideMutation.mutate(uri); + hide.mutate(uri); } function onUnhide(rkey: string) { if (!confirm("Unhide this post?")) return; - unhideMutation.mutate(rkey); + unhide.mutate(rkey); } if (threadHidden) {