diff --git a/package-lock.json b/package-lock.json index 73300cce..0aa94a11 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "imwald", - "version": "23.1.2", + "version": "23.3.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "imwald", - "version": "23.1.2", + "version": "23.3.0", "license": "MIT", "dependencies": { "@asciidoctor/core": "^3.0.4", @@ -6679,9 +6679,9 @@ } }, "node_modules/@xmldom/xmldom": { - "version": "0.8.12", - "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.12.tgz", - "integrity": "sha512-9k/gHF6n/pAi/9tqr3m3aqkuiNosYTurLLUtc7xQ9sxB/wm7WPygCv8GYa6mS0fLJEHhqMC1ATYhz++U/lRHqg==", + "version": "0.8.13", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.13.tgz", + "integrity": "sha512-KRYzxepc14G/CEpEGc3Yn+JKaAeT63smlDr+vjB8jRfgTBBI9wRj/nkQEO+ucV8p8I9bfKLWp37uHgFrbntPvw==", "license": "MIT", "optional": true, "engines": { @@ -12498,9 +12498,9 @@ } }, "node_modules/postcss": { - "version": "8.5.8", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", - "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", + "version": "8.5.13", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.13.tgz", + "integrity": "sha512-qif0+jGGZoLWdHey3UFHHWP0H7Gbmsk8T5VEqyYFbWqPr1XqvLGBbk/sl8V5exGmcYJklJOhOQq1pV9IcsiFag==", "funding": [ { "type": "opencollective", diff --git a/package.json b/package.json index c01058db..98f8005a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "imwald", - "version": "23.2.0", + "version": "23.3.0", "description": "Imwald — a user-friendly Nostr client focused on relay feed browsing, publications, and relay discovery", "private": true, "type": "module", diff --git a/src/components/ContentPreview/index.tsx b/src/components/ContentPreview/index.tsx index 7bc0014c..335e3e7f 100644 --- a/src/components/ContentPreview/index.tsx +++ b/src/components/ContentPreview/index.tsx @@ -1,5 +1,5 @@ import { Skeleton } from '@/components/ui/skeleton' -import { ExtendedKind } from '@/constants' +import { ExtendedKind, isNip71StyleVideoKind } from '@/constants' import { notificationReactionSummaryKey, useNotificationReactionDisplay @@ -184,7 +184,7 @@ export default function ContentPreview({ return withKindRow() } - if (event.kind === ExtendedKind.VIDEO || event.kind === ExtendedKind.SHORT_VIDEO) { + if (isNip71StyleVideoKind(event.kind)) { return withKindRow() } diff --git a/src/components/KindFilter/index.tsx b/src/components/KindFilter/index.tsx index 873893d5..013f08b4 100644 --- a/src/components/KindFilter/index.tsx +++ b/src/components/KindFilter/index.tsx @@ -4,7 +4,7 @@ import { Switch } from '@/components/ui/switch' import { Drawer, DrawerContent, DrawerHeader, DrawerTitle, DrawerTrigger } from '@/components/ui/drawer' import { Label } from '@/components/ui/label' import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover' -import { ExtendedKind, PROFILE_FEED_KINDS } from '@/constants' +import { ExtendedKind, NIP71_VIDEO_KINDS, PROFILE_FEED_KINDS } from '@/constants' import { LIVE_ACTIVITY_KINDS } from '@/lib/live-activities' import { cn } from '@/lib/utils' import { useKindFilter } from '@/providers/KindFilterProvider' @@ -24,7 +24,7 @@ const KIND_FILTER_OPTIONS = [ { kindGroup: [ExtendedKind.ZAP_POLL], label: 'Zap polls' }, { kindGroup: [ExtendedKind.VOICE, ExtendedKind.VOICE_COMMENT], label: 'Voice Posts' }, { kindGroup: [ExtendedKind.PICTURE], label: 'Photo Posts' }, - { kindGroup: [ExtendedKind.VIDEO, ExtendedKind.SHORT_VIDEO], label: 'Video Posts' }, + { kindGroup: [...NIP71_VIDEO_KINDS], label: 'Video Posts' }, { kindGroup: [ExtendedKind.DISCUSSION], label: 'Discussions' }, { kindGroup: [ExtendedKind.CALENDAR_EVENT_DATE, ExtendedKind.CALENDAR_EVENT_TIME], label: 'Calendar Events' }, { kindGroup: [...LIVE_ACTIVITY_KINDS], label: 'Live streams' }, diff --git a/src/components/LatestFromFollowsSection/index.tsx b/src/components/LatestFromFollowsSection/index.tsx index d53d2064..93183e0a 100644 --- a/src/components/LatestFromFollowsSection/index.tsx +++ b/src/components/LatestFromFollowsSection/index.tsx @@ -1,7 +1,7 @@ import NoteCard from '@/components/NoteCard' import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible' import { Skeleton } from '@/components/ui/skeleton' -import { ExtendedKind } from '@/constants' +import { ExtendedKind, NIP71_VIDEO_KINDS } from '@/constants' import { buildFollowOutboxAggregateReadUrls } from '@/lib/follow-outbox-aggregate-relays' import { buildSearchFollowsFeedScopeKey, @@ -52,8 +52,7 @@ const FEED_KINDS = [ kinds.LongFormArticle, kinds.Highlights, ExtendedKind.PICTURE, - ExtendedKind.VIDEO, - ExtendedKind.SHORT_VIDEO, + ...NIP71_VIDEO_KINDS, ExtendedKind.COMMENT, kinds.Repost, ExtendedKind.GENERIC_REPOST diff --git a/src/components/MediaGridItem/index.tsx b/src/components/MediaGridItem/index.tsx index d9f4efad..0e0b060f 100644 --- a/src/components/MediaGridItem/index.tsx +++ b/src/components/MediaGridItem/index.tsx @@ -1,3 +1,4 @@ +import { isNip71StyleVideoKind } from '@/constants' import { getCachedThreadContextEvents } from '@/lib/navigation-related-events' import { toNote } from '@/lib/link' import client from '@/services/client.service' @@ -13,8 +14,7 @@ export default function MediaGridItem({ event }: { event: Event }) { const media = useMemo(() => extractAllMediaFromEvent(event), [event]) const first = media.all[0] - const isVideo = - first?.m?.startsWith('video/') || event.kind === 21 || event.kind === 22 + const isVideo = first?.m?.startsWith('video/') || isNip71StyleVideoKind(event.kind) const isAudio = first?.m?.startsWith('audio/') || event.kind === 1222 const hasMultiple = media.all.length > 1 diff --git a/src/components/NormalFeed/index.tsx b/src/components/NormalFeed/index.tsx index 668f076f..36ac5b2f 100644 --- a/src/components/NormalFeed/index.tsx +++ b/src/components/NormalFeed/index.tsx @@ -4,6 +4,7 @@ import Tabs, { TabDefinition } from '@/components/Tabs' import { useKindFilter } from '@/providers/KindFilterProvider' import { useUserTrust } from '@/contexts/user-trust-context' import storage from '@/services/local-storage.service' +import { PROFILE_MEDIA_TAB_KINDS } from '@/constants' import type { TPrimaryPageName } from '@/PageManager' import { TFeedSubRequest, TNoteListMode } from '@/types' import { cn } from '@/lib/utils' @@ -116,10 +117,10 @@ const NormalFeed = forwardRef(null) const onFeedFilterTabRowSlotRef = useCallback((node: HTMLDivElement | null) => { - setFeedFilterTabRowHost(node) + setFeedFilterTabRowHost((prev) => (Object.is(prev, node) ? prev : node)) }, []) - const MEDIA_KINDS = useMemo(() => [20, 21, 22, 1222], []) + const MEDIA_KINDS = useMemo(() => [...PROFILE_MEDIA_TAB_KINDS], []) const tabs = useMemo( (): TabDefinition[] => { @@ -224,6 +225,9 @@ const NormalFeed = forwardRef setSubHeader(null) + // Intentionally omit `tabsElement`: same semantics are covered by listMode + subHeaderFilterDepsKey. + // Listing tabsElement here can retrigger the effect every render if its useMemo input references churn, + // which calls setSubHeader repeatedly → parent state → maximum update depth (#185). }, [ isMainFeed, setSubHeader, @@ -232,7 +236,6 @@ const NormalFeed = forwardRef - } else if (event.kind === ExtendedKind.VIDEO || event.kind === ExtendedKind.SHORT_VIDEO) { + } else if (isNip71StyleVideoKind(event.kind)) { content = } else if (event.kind === ExtendedKind.RELAY_REVIEW) { content = diff --git a/src/components/NoteList/index.tsx b/src/components/NoteList/index.tsx index f9fe9af2..8af05127 100644 --- a/src/components/NoteList/index.tsx +++ b/src/components/NoteList/index.tsx @@ -1786,7 +1786,7 @@ const NoteList = forwardRef( ...(rawTotal === 0 ? { emptyHint: - 'All sub-batches returned 0 events: relays may not index these kinds for this author, the query may have timed out before slow relays EOSEd, or posts are kind 1 with links (this tab uses kinds 20/21/22/1222 only).' + 'All sub-batches returned 0 events: relays may not index these kinds for this author, the query may have timed out before slow relays EOSEd, or posts are kind 1 with links (this tab uses native media kinds only: picture, NIP-71 video regular/addressable, voice).' } : {}) }) diff --git a/src/components/PostEditor/PostContent.tsx b/src/components/PostEditor/PostContent.tsx index d0e100ee..c78091fd 100644 --- a/src/components/PostEditor/PostContent.tsx +++ b/src/components/PostEditor/PostContent.tsx @@ -37,7 +37,12 @@ import { collectUploadImetaTagsForContentUrls, mergeUploadImetaTagsInto } from '@/lib/draft-event' -import { ExtendedKind, MAX_PUBLISH_RELAYS } from '@/constants' +import { + ExtendedKind, + isNip71ShortVideoKind, + isNip71StyleVideoKind, + MAX_PUBLISH_RELAYS +} from '@/constants' import { cn } from '@/lib/utils' import { useNostr } from '@/providers/NostrProvider' import { useFeed } from '@/providers/FeedProvider' @@ -878,7 +883,7 @@ export default function PostContent({ mediaImetaTags: uploadImetaTagsOpt } ) - } else if (mediaNoteKind === ExtendedKind.VIDEO || mediaNoteKind === ExtendedKind.SHORT_VIDEO) { + } else if (isNip71StyleVideoKind(mediaNoteKind)) { return await createVideoDraftEvent( cleanedText, mediaImetaTags, @@ -1927,7 +1932,7 @@ export default function PostContent({ } else if (/\.mp4$/i.test(fileName)) { mimeType = 'audio/mp4' } - } else if (kindHint === ExtendedKind.VIDEO || kindHint === ExtendedKind.SHORT_VIDEO) { + } else if (isNip71StyleVideoKind(kindHint)) { const fileName = uploadingFile.name.toLowerCase() if (/\.webm$/i.test(fileName)) { mimeType = 'video/webm' @@ -2321,10 +2326,8 @@ export default function PostContent({ return t('Voice Note') } else if (determinedKind === ExtendedKind.PICTURE) { return t('Picture Note') - } else if (determinedKind === ExtendedKind.VIDEO) { - return t('Video Note') - } else if (determinedKind === ExtendedKind.SHORT_VIDEO) { - return t('Short Video Note') + } else if (isNip71StyleVideoKind(determinedKind)) { + return isNip71ShortVideoKind(determinedKind) ? t('Short Video Note') : t('Video Note') } else if (determinedKind === ExtendedKind.POLL) { return t('New Poll') } else if (determinedKind === ExtendedKind.PUBLIC_MESSAGE) { diff --git a/src/components/WebPreview/index.tsx b/src/components/WebPreview/index.tsx index 3691ae6f..a8edead7 100644 --- a/src/components/WebPreview/index.tsx +++ b/src/components/WebPreview/index.tsx @@ -34,8 +34,10 @@ function getEventTypeName(kind: number): string { case ExtendedKind.PICTURE: return 'Picture' case ExtendedKind.VIDEO: + case ExtendedKind.VIDEO_ADDRESSABLE: return 'Video' case ExtendedKind.SHORT_VIDEO: + case ExtendedKind.SHORT_VIDEO_ADDRESSABLE: return 'Short Video' case ExtendedKind.POLL: return 'Poll' diff --git a/src/constants.ts b/src/constants.ts index 2242df3a..5bd858ed 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -447,6 +447,10 @@ export const ExtendedKind = { PICTURE: 20, VIDEO: 21, SHORT_VIDEO: 22, + /** NIP-71: addressable normal video (same rendering as {@link ExtendedKind.VIDEO}). */ + VIDEO_ADDRESSABLE: 34235, + /** NIP-71: addressable short video (same rendering as {@link ExtendedKind.SHORT_VIDEO}). */ + SHORT_VIDEO_ADDRESSABLE: 34236, POLL: 1068, /** NIP-B9 zap poll (paid votes via zaps). */ ZAP_POLL: 6969, @@ -538,6 +542,26 @@ export function isUnsignedExperimentalKind(kind: number): boolean { return kind >= UNSIGNED_EXPERIMENTAL_KIND_MIN && kind <= UNSIGNED_EXPERIMENTAL_KIND_MAX } +/** NIP-71 regular + addressable video kinds (21, 22, 34235, 34236). */ +export const NIP71_VIDEO_KINDS: readonly number[] = [ + ExtendedKind.VIDEO, + ExtendedKind.SHORT_VIDEO, + ExtendedKind.VIDEO_ADDRESSABLE, + ExtendedKind.SHORT_VIDEO_ADDRESSABLE +] + +const NIP71_VIDEO_KIND_SET = new Set(NIP71_VIDEO_KINDS) + +/** True for NIP-71 normal/short video events (regular or addressable). */ +export function isNip71StyleVideoKind(kind: number): boolean { + return NIP71_VIDEO_KIND_SET.has(kind) +} + +/** Short-form portrait-style bucket (kind 22 or 34236). */ +export function isNip71ShortVideoKind(kind: number): boolean { + return kind === ExtendedKind.SHORT_VIDEO || kind === ExtendedKind.SHORT_VIDEO_ADDRESSABLE +} + /** Max kind for signed “custom event” notes in the generic composer (below the unsigned experimental range). */ export const MAX_SIGNED_CUSTOM_EVENT_KIND = 40000 @@ -695,6 +719,8 @@ export const SUPPORTED_KINDS = [ ExtendedKind.PICTURE, ExtendedKind.VIDEO, ExtendedKind.SHORT_VIDEO, + ExtendedKind.VIDEO_ADDRESSABLE, + ExtendedKind.SHORT_VIDEO_ADDRESSABLE, ExtendedKind.POLL, ExtendedKind.ZAP_POLL, ExtendedKind.COMMENT, @@ -748,8 +774,7 @@ const PROFILE_PUBLICATIONS_TAB_KIND_SET = new Set(PROFILE_PUBLICATIONS_T /** NIP native media kinds for the profile Media tab (and Spells → media faux spell). */ export const PROFILE_MEDIA_TAB_KINDS: readonly number[] = [ ExtendedKind.PICTURE, - ExtendedKind.VIDEO, - ExtendedKind.SHORT_VIDEO, + ...NIP71_VIDEO_KINDS, ExtendedKind.VOICE ] diff --git a/src/lib/draft-event.ts b/src/lib/draft-event.ts index 3fec3657..b235db0a 100644 --- a/src/lib/draft-event.ts +++ b/src/lib/draft-event.ts @@ -1951,7 +1951,7 @@ export async function createVideoDraftEvent( content: string, imetaTags: string[][], mentions: string[], - videoKind: number, // 21 or 22 + videoKind: number, // 21, 22, 34235, or 34236 (NIP-71) options: { title?: string addClientTag?: boolean diff --git a/src/lib/kind-description.ts b/src/lib/kind-description.ts index 23e39659..0f1c8eda 100644 --- a/src/lib/kind-description.ts +++ b/src/lib/kind-description.ts @@ -36,6 +36,10 @@ export function getKindDescription( return { number: 21, description: 'Video Note' } case ExtendedKind.SHORT_VIDEO: return { number: 22, description: 'Short Video Note' } + case ExtendedKind.VIDEO_ADDRESSABLE: + return { number: 34235, description: 'Video Note (addressable)' } + case ExtendedKind.SHORT_VIDEO_ADDRESSABLE: + return { number: 34236, description: 'Short Video Note (addressable)' } case kinds.LongFormArticle: return { number: 30023, description: 'Long-form Article' } case ExtendedKind.WIKI_ARTICLE: diff --git a/src/lib/wisp-trending-relay.ts b/src/lib/wisp-trending-relay.ts index 68977879..2623b448 100644 --- a/src/lib/wisp-trending-relay.ts +++ b/src/lib/wisp-trending-relay.ts @@ -1,3 +1,4 @@ +import { ExtendedKind } from '@/constants' import { normalizeUrl } from '@/lib/url' /** @@ -17,7 +18,18 @@ export function buildWispTrendingNotesRelayUrl( } /** Wisp `FeedSubscriptionManager` FEED_KINDS when subscribing to trending notes. */ -export const WISP_TRENDING_FEED_KINDS: readonly number[] = [1, 6, 1068, 6969, 30023, 20, 21, 22] +export const WISP_TRENDING_FEED_KINDS: readonly number[] = [ + 1, + 6, + 1068, + 6969, + 30023, + ExtendedKind.PICTURE, + ExtendedKind.VIDEO, + ExtendedKind.SHORT_VIDEO, + ExtendedKind.VIDEO_ADDRESSABLE, + ExtendedKind.SHORT_VIDEO_ADDRESSABLE +] /** True when `url` is any nostrarchives notes trending WebSocket feed (path `/notes/trending/...`). */ export function isWispTrendingNotesRelayUrl(url: string): boolean { diff --git a/src/pages/primary/NoteListPage/RelaysFeed.tsx b/src/pages/primary/NoteListPage/RelaysFeed.tsx index d666ceb1..68150508 100644 --- a/src/pages/primary/NoteListPage/RelaysFeed.tsx +++ b/src/pages/primary/NoteListPage/RelaysFeed.tsx @@ -73,12 +73,13 @@ const RelaysFeed = forwardRef< } }, [relayUrlsKey, relayUrls.length]) - const defaultKinds = - kindsOverride && kindsOverride.length > 0 - ? kindsOverride - : showKinds.length > 0 - ? showKinds - : [kinds.ShortTextNote] + /** Stable identity when kind filter is empty so `subRequests` does not invalidate every render. */ + const fallbackNoteKinds = useMemo(() => [kinds.ShortTextNote], []) + const defaultKinds = useMemo(() => { + if (kindsOverride && kindsOverride.length > 0) return kindsOverride + if (showKinds.length > 0) return showKinds + return fallbackNoteKinds + }, [kindsOverride, showKinds, fallbackNoteKinds]) const canRenderFeed = (feedInfo.feedType === 'relay' || diff --git a/src/pages/secondary/NotePage/index.tsx b/src/pages/secondary/NotePage/index.tsx index fd4c993a..4dac4d06 100644 --- a/src/pages/secondary/NotePage/index.tsx +++ b/src/pages/secondary/NotePage/index.tsx @@ -52,8 +52,10 @@ function getEventTypeName(kind: number): string { case ExtendedKind.PICTURE: return 'Picture' case ExtendedKind.VIDEO: + case ExtendedKind.VIDEO_ADDRESSABLE: return 'Video' case ExtendedKind.SHORT_VIDEO: + case ExtendedKind.SHORT_VIDEO_ADDRESSABLE: return 'Short Video' case ExtendedKind.POLL: return 'Poll' @@ -205,8 +207,10 @@ const NotePage = forwardRef(({ id, index, hideTitlebar = false, initialEvent }: case 20: // ExtendedKind.PICTURE return 'Note: Picture' case 21: // ExtendedKind.VIDEO + case 34235: // ExtendedKind.VIDEO_ADDRESSABLE (NIP-71) return 'Note: Video' case 22: // ExtendedKind.SHORT_VIDEO + case 34236: // ExtendedKind.SHORT_VIDEO_ADDRESSABLE (NIP-71) return 'Note: Short Video' case 11: // ExtendedKind.DISCUSSION return 'Discussions' diff --git a/src/providers/FavoriteRelaysActivityProvider.tsx b/src/providers/FavoriteRelaysActivityProvider.tsx index af2542e7..bd54476b 100644 --- a/src/providers/FavoriteRelaysActivityProvider.tsx +++ b/src/providers/FavoriteRelaysActivityProvider.tsx @@ -1,5 +1,5 @@ import logger from '@/lib/logger' -import { ExtendedKind } from '@/constants' +import { ExtendedKind, NIP71_VIDEO_KINDS } from '@/constants' import { getFavoritesFeedRelayUrls } from '@/lib/favorites-feed-relays' import { readRelayPulseActiveNpubsCache, @@ -34,8 +34,7 @@ const ACTIVE_PULSE_KINDS = [ kinds.Highlights, ExtendedKind.DISCUSSION, ExtendedKind.PICTURE, - ExtendedKind.VIDEO, - ExtendedKind.SHORT_VIDEO, + ...NIP71_VIDEO_KINDS, ExtendedKind.COMMENT, ExtendedKind.GENERIC_REPOST ] as number[] diff --git a/src/services/event-archive.service.ts b/src/services/event-archive.service.ts index d5ff8101..0d26340d 100644 --- a/src/services/event-archive.service.ts +++ b/src/services/event-archive.service.ts @@ -1,4 +1,4 @@ -import { ExtendedKind } from '@/constants' +import { ExtendedKind, NIP71_VIDEO_KINDS } from '@/constants' import { shouldDropEventOnIngest } from '@/lib/event-ingest-filter' import { getEventArchiveConfig } from '@/lib/event-archive-config' import { isNip18RepostKind, isNip25ReactionKind, isReplaceableEvent } from '@/lib/event' @@ -12,9 +12,8 @@ const CORE_FEED_KINDS = new Set([ kinds.ShortTextNote, 11, ExtendedKind.COMMENT, - 20, - 21, - 22, + ExtendedKind.PICTURE, + ...NIP71_VIDEO_KINDS, 9802 // highlights ]) diff --git a/src/services/local-storage.service.ts b/src/services/local-storage.service.ts index 6463d2dc..8bad5af4 100644 --- a/src/services/local-storage.service.ts +++ b/src/services/local-storage.service.ts @@ -325,13 +325,27 @@ class LocalStorageService { showKinds.push(ExtendedKind.WIKI_ARTICLE_MARKDOWN) } } + if (showKindsVersion < 13) { + // NIP-71 addressable video (34235 / 34236): add when user already had regular video kinds enabled. + if ( + showKinds.includes(ExtendedKind.VIDEO) || + showKinds.includes(ExtendedKind.SHORT_VIDEO) + ) { + if (!showKinds.includes(ExtendedKind.VIDEO_ADDRESSABLE)) { + showKinds.push(ExtendedKind.VIDEO_ADDRESSABLE) + } + if (!showKinds.includes(ExtendedKind.SHORT_VIDEO_ADDRESSABLE)) { + showKinds.push(ExtendedKind.SHORT_VIDEO_ADDRESSABLE) + } + } + } // v9: boosts are optional in the same filter list as other kinds; do not auto-enable (leave absent). this.showKinds = showKinds // Only persist when we read from localStorage. If SHOW_KINDS is missing here (migrated to IDB and // keys cleared), persisting would write DEFAULT_FEED_SHOW_KINDS to IndexedDB and wipe the user's // saved filter before initAsync/applySettings runs. this.persistSetting(StorageKey.SHOW_KINDS, JSON.stringify(this.showKinds)) - this.persistSetting(StorageKey.SHOW_KINDS_VERSION, '12') + this.persistSetting(StorageKey.SHOW_KINDS_VERSION, '13') } // Feed filter: kind 1 OPs, kind 1 replies, kind 1111 (migrate from legacy showRepliesAndComments if set) diff --git a/src/services/mention-event-search.service.ts b/src/services/mention-event-search.service.ts index c268635a..b489c8d9 100644 --- a/src/services/mention-event-search.service.ts +++ b/src/services/mention-event-search.service.ts @@ -8,7 +8,7 @@ import { citationPickerMatchesQuery, tryParseCitationEventIdFromQuery } from '@/lib/citation-picker-search' -import { ExtendedKind, SEARCHABLE_RELAY_URLS } from '@/constants' +import { ExtendedKind, NIP71_VIDEO_KINDS, SEARCHABLE_RELAY_URLS } from '@/constants' import { kinds, type Event as NEvent } from 'nostr-tools' import client, { eventService, queryService } from './client.service' import indexedDb from './indexed-db.service' @@ -22,8 +22,7 @@ export const MENTION_NPUB_DROPDOWN_LIMIT = 50 export const NEVENT_KINDS = [ kinds.ShortTextNote, ExtendedKind.PICTURE, - ExtendedKind.VIDEO, - ExtendedKind.SHORT_VIDEO, + ...NIP71_VIDEO_KINDS, ExtendedKind.POLL, ExtendedKind.ZAP_POLL, ExtendedKind.COMMENT, @@ -139,7 +138,7 @@ async function searchCitationEventsForPickerInternal( /** * Search for events: session cache → IndexedDB → relays. Merges and dedupes by event id, up to limit. - * @param mode - 'nevent' uses NEVENT_KINDS (1,11,20,21,22,9802), 'naddr' uses NADDR_KINDS (30023,30817,30818,30040). + * @param mode - 'nevent' uses NEVENT_KINDS (incl. NIP-71 video 21/22/34235/34236), 'naddr' uses NADDR_KINDS (30023,30817,30818,30040). * @param kindFilter - When set, only these kinds are searched (overrides `mode` for the kinds list). */ export async function searchEventsForPicker( diff --git a/src/services/nip89.service.ts b/src/services/nip89.service.ts index 860fa1c7..ed8aadcb 100644 --- a/src/services/nip89.service.ts +++ b/src/services/nip89.service.ts @@ -219,6 +219,8 @@ class Nip89Service { ExtendedKind.PICTURE, ExtendedKind.VIDEO, ExtendedKind.SHORT_VIDEO, + ExtendedKind.VIDEO_ADDRESSABLE, + ExtendedKind.SHORT_VIDEO_ADDRESSABLE, ExtendedKind.POLL, ExtendedKind.COMMENT, ExtendedKind.VOICE,