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<Record<Nsid, string>> = {
[PROFILE_COLLECTION]: "profile",
[COMMENT_COLLECTION]: "comment",
[TICKET_COLLECTION]: "issue"
};
const OUTCOMES: Record<ModerationLevel, string> = {
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<string>();
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
);
};