mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-11-06 12:52:26 +00:00
[moderation] #25: per-video admin block list (hide a single video, not the author)
Admin moderation was author/community-level only. Admins (any editor — same gate as the author blacklist) can now hide a SINGLE offending video. - Record: a published kind-30000 NIP-51 list under d-tag bitvid:admin:event-blacklist, carrying blocked event ids as `e` tags (NOTE_TYPES.ADMIN_EVENT_BLACKLIST schema). Loaded/persisted through the existing admin-list machinery (adminListStore) and cached like whitelist/blacklist. - accessControl: eventBlacklist Set + getEventBlacklist/isEventBlacklisted/ addToEventBlacklist/removeFromEventBlacklist (editor-gated; normalizes hex or nevent/note) + onEventBlacklistChange. - Render filter already existed (app.blacklistedEventIds, honored by every feed/grid/ search/playback path) but was fed only by the static ADMIN_INITIAL_EVENT_BLACKLIST config. app._rebuildBlacklistedEventIds() now merges that static base with the dynamic admin list, and an onEventBlacklistChange listener rebuilds + refreshes grids on change. - UI: a "Block this video" item in the per-video ⋯ menu (editor-only), handled by handleBlacklistEventAction (js/ui/moreMenu/blacklistEventAction.js). Helpers extracted to js/adminEventBlacklistHelpers.js to keep adminListStore / accessControl / moreMenuController under their size caps. Tests: tests/admin-event-blacklist.test.mjs (9). Build + lint clean; admin/access/moderation suites 56/56. Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
2e7e2016d3
commit
3e57ab2ea9
11 files changed
+529
-44
No files matched your search
@@ -1209,7 +1209,10 @@ export default class ApplicationBootstrap {
|
||||
});
|
||||
app.appChromeController.initialize();
|
||||
|
||||
app.blacklistedEventIds = new Set();
|
||||
// Static, build-time per-event block list (operator config). Kept separate from
|
||||
// the dynamic admin list (#25) so app._rebuildBlacklistedEventIds() can re-merge
|
||||
// both whenever the published admin event-blacklist changes.
|
||||
app._staticBlacklistedEventIds = new Set();
|
||||
if (this.window?.NostrTools?.nip19?.decode) {
|
||||
for (const neventStr of ADMIN_INITIAL_EVENT_BLACKLIST) {
|
||||
if (!neventStr || neventStr.trim().length < 8) {
|
||||
@@ -1218,7 +1221,7 @@ export default class ApplicationBootstrap {
|
||||
try {
|
||||
const decoded = this.window.NostrTools.nip19.decode(neventStr);
|
||||
if (decoded?.type === "nevent" && decoded.data?.id) {
|
||||
app.blacklistedEventIds.add(decoded.data.id);
|
||||
app._staticBlacklistedEventIds.add(decoded.data.id);
|
||||
}
|
||||
} catch (err) {
|
||||
devLogger.error(
|
||||
@@ -1229,6 +1232,12 @@ export default class ApplicationBootstrap {
|
||||
}
|
||||
}
|
||||
}
|
||||
app.blacklistedEventIds = new Set(app._staticBlacklistedEventIds);
|
||||
if (typeof app._rebuildBlacklistedEventIds === "function") {
|
||||
// Fold in any already-loaded admin event-blacklist (accessControl may have
|
||||
// hydrated from cache synchronously before this point).
|
||||
app._rebuildBlacklistedEventIds();
|
||||
}
|
||||
|
||||
app.unsubscribeFromPubkeyState = null;
|
||||
app.unsubscribeFromCurrentUserState = null;
|
||||
|
||||
Reference in new issue
Block a user