f4ae344b30
Kind 3 (NIP-02 follow list), kind 30000 (NIP-51 follow set), and kind 39089 (follow pack) are all the same semantic thing — an event containing a list of p-tagged pubkeys — but were being rendered three different ways, with kind 3 having no rendering at all, kind 30000 routing to a bespoke ListDetailPage, and kind 39089 using its own FollowPackDetailContent. Merge the three into a single PeopleListContent (feed card) and PeopleListDetailContent (full detail). The detail component hosts every feature from the predecessors: Follow All with existing p-tag preservation, Save-as-copy for non-owners, owner-mode member removal for kind 30000, the Feed/Members/Comments tabs, sidebar integration, and the share/copy-link menu. For kind 3 the event has no title of its own, so we fall back to the author's display name. Additional refinements bundled in: - Register kinds 3 and 30000 at every previously-missing rendering point: KIND_HEADER_MAP, shellTitleForKind, CommentContext KIND_LABELS/ICONS, extraKinds specific labels and icons, and ExternalContentHeader fallbacks. Kind 3 and 30000 now share the packs feed toggle via extraFeedKinds. - Add infinite scroll to the people-list Feed tab via useTabFeed + IntersectionObserver sentinel, replacing the useStreamPosts 40-post cap. - Add Comments tab alongside Feed and Members, powered by useComments (NIP-22 kind 1111). Drop the redundant variant badge. Allow kind 39089 packs to be pinned to the sidebar. - Trim redundant chrome: drop the member-count pill in the feed card, drop the member-count line in the detail header, and stop pulling the author's 'about' and 'banner' into kind 3 follow list views. - Add a dedicated FollowListCommentContext branch so comments on kind 3 show '@Name's follow list' instead of 'a follow list'. - Replace the three-dots DropdownMenu on the detail view with the shared PostActionBar (reply/repost/react/zap/share/more), matching other detail views. - Promote EmbeddedPost from ReplyComposeModal into a shared component that dispatches to EmbeddedNote / EmbeddedNaddr, with a new EmbeddedPeopleListCard for kinds 3/30000/39089 so quote posts, reply indicators, hover cards, and the More menu all render follow lists correctly. - Link the 'N following' count on profile pages to a naddr of the kind 3 event (routing to the new detail view) instead of a bespoke modal. Delete FollowingListModal. Using naddr rather than nevent ensures the link always resolves to the latest replaceable event. Delete ListDetailPage, FollowPackDetailContent, and FollowingListModal entirely. All three kinds now route through AddrPostDetailPage → PeopleListDetailContent.
58 lines
2.0 KiB
TypeScript
58 lines
2.0 KiB
TypeScript
import type { NostrEvent } from '@nostrify/nostrify';
|
|
|
|
import { EmbeddedNote } from '@/components/EmbeddedNote';
|
|
import { EmbeddedNaddr } from '@/components/EmbeddedNaddr';
|
|
import { ProfilePreview } from '@/components/ExternalContentHeader';
|
|
import { cn } from '@/lib/utils';
|
|
|
|
interface EmbeddedPostProps {
|
|
/** The event to render. */
|
|
event: NostrEvent;
|
|
/** Extra classes applied to the outermost wrapper. */
|
|
className?: string;
|
|
/** When true, ProfileHoverCards inside the card are disabled to prevent nested hover cards. */
|
|
disableHoverCards?: boolean;
|
|
}
|
|
|
|
/**
|
|
* Compact embedded preview of a Nostr event.
|
|
*
|
|
* Delegates to the shared `EmbeddedNote` / `EmbeddedNaddr` components used by
|
|
* quote posts, reply indicators, comment context, and hover cards so every
|
|
* surface that previews an event renders it consistently — regardless of
|
|
* whether it's a text note, an addressable event (article, people list,
|
|
* badge…), or a profile (kind 0).
|
|
*/
|
|
export function EmbeddedPost({ event, className, disableHoverCards }: EmbeddedPostProps) {
|
|
// Kind 0 (profile) — show a profile card instead of trying to render the raw JSON content
|
|
if (event.kind === 0) {
|
|
return (
|
|
<div className={cn('rounded-xl border border-border bg-secondary/30 overflow-hidden', className)}>
|
|
<ProfilePreview pubkey={event.pubkey} />
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// Addressable events (kind 30000-39999) — use EmbeddedNaddr
|
|
if (event.kind >= 30000 && event.kind < 40000) {
|
|
const dTag = event.tags.find(([name]) => name === 'd')?.[1] ?? '';
|
|
return (
|
|
<EmbeddedNaddr
|
|
addr={{ kind: event.kind, pubkey: event.pubkey, identifier: dTag }}
|
|
className={className}
|
|
disableHoverCards={disableHoverCards}
|
|
/>
|
|
);
|
|
}
|
|
|
|
// Everything else — use EmbeddedNote (the event is already in the query cache)
|
|
return (
|
|
<EmbeddedNote
|
|
eventId={event.id}
|
|
authorHint={event.pubkey}
|
|
className={className}
|
|
disableHoverCards={disableHoverCards}
|
|
/>
|
|
);
|
|
}
|