diff --git a/config/instance-config.js b/config/instance-config.js index 49e36ea6..6a22e0ef 100644 --- a/config/instance-config.js +++ b/config/instance-config.js @@ -234,6 +234,21 @@ export const DEFAULT_WHITELIST_MODE_ENABLED = true; */ export const ALLOW_NSFW_CONTENT = false; +/** + * Whether the client ingests NIP-71 video events published by *other* Nostr + * apps (kinds 21/22 and addressable 34235/34236) and surfaces them in bitvid's + * feeds. + * + * Defaults to `true` so bitvid discovers videos from the wider Nostr ecosystem + * (Nostube, Flotilla, etc.). bitvid's own outbound mirrors are skipped to avoid + * duplicate listings, and ingested NSFW content still respects + * `ALLOW_NSFW_CONTENT` plus the standard trust/blacklist/mute gating. + * + * Set to `false` to disable all inbound NIP-71 ingest with a single switch if it + * ever causes problems (spam, low-quality content, performance). + */ +export const FEATURE_NIP71_INGEST = true; + /** * Emergency fallback accounts for seeding the moderation graph. * diff --git a/js/config.js b/js/config.js index 4f9e6b98..d4e20286 100644 --- a/js/config.js +++ b/js/config.js @@ -24,6 +24,7 @@ import { ADMIN_WHITELIST_MODE_STORAGE_KEY, DEFAULT_WHITELIST_MODE_ENABLED, ALLOW_NSFW_CONTENT, + FEATURE_NIP71_INGEST, DEFAULT_TRUST_SEED_NPUBS, DEFAULT_BLUR_THRESHOLD, DEFAULT_AUTOPLAY_BLOCK_THRESHOLD, @@ -117,6 +118,7 @@ export const ADMIN_LIST_NAMESPACE = "bitvid:admin"; // Reserved for Nostr lists export const ADMIN_COMMUNITY_BLACKLIST_SOURCES = "community:blacklist:sources"; export const ADMIN_COMMUNITY_BLACKLIST_PREFIX = "community:blacklist"; export { ALLOW_NSFW_CONTENT }; +export { FEATURE_NIP71_INGEST }; export { DEFAULT_TRUST_SEED_NPUBS }; export { DEFAULT_BLUR_THRESHOLD }; export { DEFAULT_AUTOPLAY_BLOCK_THRESHOLD }; diff --git a/js/constants.js b/js/constants.js index f6a9c202..63d2b534 100644 --- a/js/constants.js +++ b/js/constants.js @@ -6,6 +6,7 @@ import { DEFAULT_TRUSTED_SPAM_HIDE_THRESHOLD as CONFIG_DEFAULT_TRUSTED_SPAM_HIDE_THRESHOLD, DEFAULT_PLAYBACK_SOURCE, DEFAULT_PLAYBACK_START_TIMEOUT, + FEATURE_NIP71_INGEST as CONFIG_FEATURE_NIP71_INGEST, IS_DEV_MODE, } from "./config.js"; @@ -185,6 +186,9 @@ const DEFAULT_FLAGS = Object.freeze({ // Opt-in NIP-71 *mirror* (addressable 34235/36) managed per-video from the // My Videos tab. Independent of FEATURE_PUBLISH_NIP71 (legacy 21/22 auto-publish). FEATURE_NIP71_MIRROR: true, + // Inbound ingest of NIP-71 videos published by other Nostr apps. Sourced from + // the admin instance config so a deployer flips it in one place. + FEATURE_NIP71_INGEST: CONFIG_FEATURE_NIP71_INGEST !== false, FEATURE_HASHTAG_PREFERENCES: false, FEATURE_SEARCH_FILTERS: Boolean(IS_DEV_MODE), FEATURE_TRUST_SEEDS: true, // Rollback: disable to drop baseline trust seeds without code changes. @@ -206,6 +210,7 @@ const runtimeFlags = (() => { FEATURE_WATCH_HISTORY_V2: DEFAULT_FLAGS.FEATURE_WATCH_HISTORY_V2, FEATURE_PUBLISH_NIP71: DEFAULT_FLAGS.FEATURE_PUBLISH_NIP71, FEATURE_NIP71_MIRROR: DEFAULT_FLAGS.FEATURE_NIP71_MIRROR, + FEATURE_NIP71_INGEST: DEFAULT_FLAGS.FEATURE_NIP71_INGEST, FEATURE_HASHTAG_PREFERENCES: DEFAULT_FLAGS.FEATURE_HASHTAG_PREFERENCES, FEATURE_SEARCH_FILTERS: DEFAULT_FLAGS.FEATURE_SEARCH_FILTERS, FEATURE_TRUST_SEEDS: DEFAULT_FLAGS.FEATURE_TRUST_SEEDS, @@ -242,6 +247,11 @@ export let FEATURE_NIP71_MIRROR = coerceBoolean( DEFAULT_FLAGS.FEATURE_NIP71_MIRROR ); +export let FEATURE_NIP71_INGEST = coerceBoolean( + runtimeFlags.FEATURE_NIP71_INGEST, + DEFAULT_FLAGS.FEATURE_NIP71_INGEST +); + export let FEATURE_HASHTAG_PREFERENCES = coerceBoolean( runtimeFlags.FEATURE_HASHTAG_PREFERENCES, DEFAULT_FLAGS.FEATURE_HASHTAG_PREFERENCES