Safety: account-level (per-creator) web-of-trust overrides

Add "trusted creator" overrides that suppress the web-of-trust warning/blur
for ALL of a creator's videos until reset — the account-level companion to the
existing per-video "Show anyway".

- cache.js: per-author override store (bitvid:moderationAuthorOverrides:v1),
  keyed by author hex, with get/set/has/clear/list + persist/load, mirroring
  the per-video store.
- moderationDecorator: overrideActive now also honors an account-level override
  for the video's author, so the whole class of WoT warnings clears for every
  video by that creator.
- app.js: load the author overrides on startup.
- Services + contract: getAuthorModerationOverrides / setAuthorModerationOverride
  / clearAuthorModerationOverride; set/clear refresh the feed + fire the shared
  moderation-override event so the Safety tab list updates.
- Safety tab: a "Trusted creators" section — add by npub, list each with a
  Reset, mirroring the Active-overrides section.
- tests: storage set/get/has/clear/list, hex normalization, persist→load,
  invalid-input guard.

Next: the "Always show this creator" button on the video warning overlay
(second entry point) — a larger multi-component UI change, done separately.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
thePR0M3TH3ANandClaude Opus 4.8 committed 2026-07-08 15:58:10 -04:00
1 parent 18e7197bdc
commit a0131c718e
9 files changed
+538 -5

No files matched your search

+43
View File
@@ -58,6 +58,9 @@ import {
getDmPrivacySettings,
setDmPrivacySettings,
clearModerationOverride,
getAuthorModerationOverridesList,
setAuthorModerationOverride,
clearAuthorModerationOverride,
persistSavedProfiles,
getSavedProfiles,
getActiveProfilePubkey,
@@ -93,6 +96,30 @@ import {
} from "./components/staticModalAccessibility.js";
import ModalManager from "./ModalManager.js";
// After an account-level ("trusted creator") override is set/cleared, refresh
// the feed so every video by that author re-decorates (warning on/off), and
// fire the shared moderation-override event so the Safety tab list refreshes.
function notifyAuthorModerationOverrideChanged(app, pubkey) {
try {
if (typeof document !== "undefined") {
document.dispatchEvent(
new CustomEvent("video:moderation-override", {
detail: { authorPubkey: pubkey || "", accountLevel: true },
}),
);
}
} catch (error) {
// best-effort
}
try {
if (typeof app?.onVideosShouldRefresh === "function") {
void app.onVideosShouldRefresh({ reason: "author-moderation-override" });
}
} catch (error) {
// best-effort
}
}
export default class ApplicationBootstrap {
constructor({
app,
@@ -550,6 +577,22 @@ export default class ApplicationBootstrap {
getModerationOverrides: () => getModerationOverridesList(),
clearModerationOverride: (descriptor) =>
clearModerationOverride(descriptor),
// Account-level ("trusted creator") WoT overrides. Setting/clearing
// one re-renders the feed so every video by that author updates, and
// fires the shared event so the Safety tab list refreshes.
getAuthorModerationOverrides: () => getAuthorModerationOverridesList(),
setAuthorModerationOverride: (pubkey) => {
const entry = setAuthorModerationOverride(pubkey, {
showAnyway: true,
});
notifyAuthorModerationOverrideChanged(app, pubkey);
return entry;
},
clearAuthorModerationOverride: (pubkey) => {
const removed = clearAuthorModerationOverride(pubkey);
notifyAuthorModerationOverrideChanged(app, pubkey);
return removed;
},
loadVideos: (forceFetch, context) =>
app.loadVideos(forceFetch, context),
onVideosShouldRefresh: (context) =>