import { parseCanonicalResourceUri, type Nsid } from "@atcute/lexicons/syntax"; import { COMMENT_COLLECTION } from "#lib/api/comment.ts"; import { isAccountModeration, type Moderation, type ModerationLevel } from "#lib/api/moderationLabels.ts"; import { PROFILE_COLLECTION } from "#lib/api/profile.ts"; import { TICKET_COLLECTION } from "#lib/api/ticket.ts"; import { getAuth } from "#lib/auth.svelte.ts"; const RECORD_NOUNS: Partial> = { [PROFILE_COLLECTION]: "profile", [COMMENT_COLLECTION]: "comment", [TICKET_COLLECTION]: "issue" }; const OUTCOMES: Record = { hide: "hidden by moderators", warn: "flagged" }; const subjectNoun = (moderation: Moderation): string => { if (isAccountModeration(moderation)) return "account"; return RECORD_NOUNS[parseCanonicalResourceUri(moderation.target).collection] ?? "post"; }; export const moderationMessage = (moderation: Moderation): string => `This ${subjectNoun(moderation)} has been ${OUTCOMES[moderation.level]}.`; export interface ModerationGate { readonly moderation?: Moderation; readonly masked: boolean; readonly revealable: boolean; reveal(): void; } export const createModerationGate = ( moderation: () => Moderation | undefined, isOwner: () => boolean = () => false, subject: () => string | undefined = () => undefined ): ModerationGate => { let revealedFor = $state(); const active = $derived(isOwner() ? undefined : moderation()); const key = $derived(subject() ?? active?.target); const covering = $derived( active?.level === "warn" && key !== undefined && revealedFor === key ? undefined : active ); return { get moderation() { return covering; }, get masked() { return covering !== undefined; }, get revealable() { return covering?.level === "warn"; }, reveal: () => { revealedFor = key; } }; }; export const createAuthorGate = ( moderation: () => Moderation | undefined, author: () => string | undefined, subject?: () => string | undefined ): ModerationGate => { const auth = getAuth(); return createModerationGate( moderation, () => { const did = author(); return did !== undefined && auth?.currentDid === did; }, subject ); };