import type { CaptureToggles, PolicyScopeType } from "#lib/api/types.js"; import { t } from "#lib/i18n/locale.svelte.js"; export type ToggleKey = keyof CaptureToggles; type DefaultScope = "channel" | "dm" | "group"; export const TOGGLE_KEYS: ToggleKey[] = [ "messages", "media", "self_destruct_media", "stt", "reactions", "track_edits_deletes", "profile_history", "stories", "presence", "backfill", ]; const DEFAULT_SCOPES: Partial> = { default_channel: "channel", default_dm: "dm", default_group: "group", }; const SHOWN_CHIPS = 3; const SHORT_LIST = 2; export interface Chip { hint?: string; label: string; sign: "plus" | "minus"; } export function toggleLabel(key: ToggleKey): string { return t(`policy.toggle.${key}`); } function exceptLabel(key: ToggleKey): string { return t(`policy.except.${key}`); } export function defaultLabel(scopeType: PolicyScopeType): string { const scope = DEFAULT_SCOPES[scopeType]; return scope ? t(`policy.default.${scope}`) : ""; } export function pickToggles(source: CaptureToggles): CaptureToggles { return { backfill: source.backfill, media: source.media, messages: source.messages, presence: source.presence, profile_history: source.profile_history, reactions: source.reactions, self_destruct_media: source.self_destruct_media, stories: source.stories, stt: source.stt, track_edits_deletes: source.track_edits_deletes, }; } export function preset(only: ToggleKey[] | "all"): CaptureToggles { const toggles = {} as CaptureToggles; for (const key of TOGGLE_KEYS) { toggles[key] = only === "all" || only.includes(key); } return toggles; } export function sameToggles(a: CaptureToggles, b: CaptureToggles): boolean { return TOGGLE_KEYS.every((key) => a[key] === b[key]); } function exceptList(keys: ToggleKey[]): string { const [first, second] = keys.map(exceptLabel); return second === undefined ? (first ?? "") : t("policy.summary.pair", { a: first ?? "", b: second }); } export function summary(toggles: CaptureToggles): string { const on = TOGGLE_KEYS.filter((key) => toggles[key]); const off = TOGGLE_KEYS.filter((key) => !toggles[key]); if (off.length === 0) { return t("policy.summary.all"); } if (on.length === 0) { return t("policy.summary.none"); } if (on.length === 1 && on[0] === "messages") { return t("policy.summary.messagesOnly"); } if (off.length <= SHORT_LIST) { return t("policy.summary.except", { list: exceptList(off) }); } const names = on.slice(0, SHORT_LIST).map(toggleLabel).join(", "); const rest = on.length - SHORT_LIST; return rest > 0 ? t("policy.summary.more", { count: rest, names }) : names; } export function parentLabel( scopeType: PolicyScopeType, title: string | null ): string { if (scopeType === "folder") { return t("policy.parent.folder", { title: title ?? t("policy.parent.untitled"), }); } const scope = DEFAULT_SCOPES[scopeType]; return scope ? t(`policy.parent.${scope}`) : t("policy.parent.default"); } function labelList(keys: ToggleKey[]): string { return keys.map(toggleLabel).join(", "); } function named(keys: ToggleKey[], sign: Chip["sign"]): Chip[] { return keys.map((key) => ({ label: toggleLabel(key), sign })); } function counted(keys: ToggleKey[], sign: Chip["sign"]): Chip[] { if (keys.length === 0) { return []; } if (keys.length <= SHOWN_CHIPS) { return named(keys, sign); } return [ { hint: labelList(keys), label: t("policy.chip.settings", { count: keys.length }), sign, }, ]; } export function contentChips(rule: CaptureToggles): Chip[] { const on = TOGGLE_KEYS.filter((key) => rule[key]); const off = TOGGLE_KEYS.filter((key) => !rule[key]); if (off.length === 0) { return [{ label: t("policy.chip.allOn"), sign: "plus" }]; } if (on.length === 0) { return [{ label: t("policy.chip.allOff"), sign: "minus" }]; } if (off.length <= SHOWN_CHIPS) { return [ { label: t("policy.summary.all"), sign: "plus" }, ...named(off, "minus"), ]; } return [...counted(on, "plus"), ...counted(off, "minus")]; } export function diffChips(rule: CaptureToggles, base: CaptureToggles): Chip[] { const plus = TOGGLE_KEYS.filter((key) => rule[key] && !base[key]); const minus = TOGGLE_KEYS.filter((key) => !rule[key] && base[key]); if (plus.length > SHOWN_CHIPS && TOGGLE_KEYS.every((key) => rule[key])) { return [{ label: t("policy.chip.allOn"), sign: "plus" }]; } if (minus.length > SHOWN_CHIPS && TOGGLE_KEYS.every((key) => !rule[key])) { return [{ label: t("policy.chip.allOff"), sign: "minus" }]; } return [...counted(plus, "plus"), ...counted(minus, "minus")]; }