From 2c9bae18f085a463d409cfe2ffbe8a33dc91d011 Mon Sep 17 00:00:00 2001 From: mroxso <24775431+mroxso@users.noreply.github.com> Date: Sat, 18 Jan 2025 02:03:12 +0100 Subject: [PATCH] Feature: Implement NIP-68 (Picture-first feeds) (#26) * update global feed to use kind 20 and kind 20 cards (NIP-68 Picture-first feeds) * update profile quick view feed to use kind 20 and kind 20 cards (NIP-68 Picture-first feeds) * refactor: move getImageUrl function to utils for better modularity * show kind 20 notes on note subpage * also show comments on kind 20 events * update follower feed and follower quick view feed to use kind 20 and kind 20 cards (NIP-68 Picture-first feeds) * update profile feed to use kind 20 and kind 20 cards (NIP-68 Picture-first feeds) * update search feed to use kind 20 and kind 20 cards (NIP-68 Picture-first feeds) * update tag feed to use kind 20 and kind 20 cards (NIP-68 Picture-first feeds) * add relay.damus.io * update KIND20Card and QuickViewKind20NoteCard to use Next.js Image component and extract dimensions from event metadata --- lumina/app/dashboard/[pubkey]/page.tsx | 1 + lumina/app/feed/page.tsx | 1 + lumina/app/global/page.tsx | 1 + lumina/app/note/[id]/page.tsx | 1 + lumina/app/notifications/page.tsx | 1 + lumina/app/onboarding/createProfile/page.tsx | 1 + lumina/app/onboarding/page.tsx | 1 + lumina/app/page.tsx | 3 +- lumina/app/profile/[pubkey]/page.tsx | 1 + lumina/app/profile/settings/page.tsx | 1 + lumina/app/reel/page.tsx | 1 + lumina/app/search/[searchTag]/page.tsx | 1 + lumina/app/search/page.tsx | 1 + lumina/app/tag/[tag]/page.tsx | 1 + lumina/app/upload/page.tsx | 1 + lumina/components/CommentsCompontent.tsx | 2 +- lumina/components/FollowerFeed.tsx | 17 +-- lumina/components/FollowerQuickViewFeed.tsx | 14 +- lumina/components/GlobalFeed.tsx | 48 ++++--- lumina/components/KIND20Card.tsx | 124 ++++++++++++++++++ lumina/components/NotePageComponent.tsx | 38 +++++- lumina/components/ProfileFeed.tsx | 14 +- lumina/components/ProfileQuickViewFeed.tsx | 24 ++-- lumina/components/QuickViewKind20NoteCard.tsx | 65 +++++++++ lumina/components/TagFeed.tsx | 17 +-- .../searchComponents/SearchNotesBox.tsx | 10 +- lumina/utils/utils.ts | 24 ++++ 27 files changed, 326 insertions(+), 88 deletions(-) create mode 100644 lumina/components/KIND20Card.tsx create mode 100644 lumina/components/QuickViewKind20NoteCard.tsx create mode 100644 lumina/utils/utils.ts diff --git a/lumina/app/dashboard/[pubkey]/page.tsx b/lumina/app/dashboard/[pubkey]/page.tsx index 8a8f76b..f91d1f1 100644 --- a/lumina/app/dashboard/[pubkey]/page.tsx +++ b/lumina/app/dashboard/[pubkey]/page.tsx @@ -18,6 +18,7 @@ const DashboardPage: React.FC= ({ }) => { const relayUrls = [ "wss://relay.nostr.band", + "wss://relay.damus.io", ]; return ( diff --git a/lumina/app/feed/page.tsx b/lumina/app/feed/page.tsx index 26e6bde..b0a685d 100644 --- a/lumina/app/feed/page.tsx +++ b/lumina/app/feed/page.tsx @@ -29,6 +29,7 @@ export default function FeedPage() { const relayUrls = [ "wss://relay.nostr.band", + "wss://relay.damus.io", ]; return ( diff --git a/lumina/app/global/page.tsx b/lumina/app/global/page.tsx index d3550eb..7c552bc 100644 --- a/lumina/app/global/page.tsx +++ b/lumina/app/global/page.tsx @@ -7,6 +7,7 @@ export default function Home() { const relayUrls = [ "wss://relay.nostr.band", + "wss://relay.damus.io", ]; return ( diff --git a/lumina/app/note/[id]/page.tsx b/lumina/app/note/[id]/page.tsx index c4b67f2..a260727 100644 --- a/lumina/app/note/[id]/page.tsx +++ b/lumina/app/note/[id]/page.tsx @@ -17,6 +17,7 @@ export default function NotePage() { const relayUrls = [ "wss://relay.nostr.band", + "wss://relay.damus.io", ]; return ( diff --git a/lumina/app/notifications/page.tsx b/lumina/app/notifications/page.tsx index f76c1a6..34bf595 100644 --- a/lumina/app/notifications/page.tsx +++ b/lumina/app/notifications/page.tsx @@ -20,6 +20,7 @@ const NotificationsPage: React.FC= ({ }) => { const relayUrls = [ "wss://relay.nostr.band", + "wss://relay.damus.io", ]; return ( diff --git a/lumina/app/onboarding/createProfile/page.tsx b/lumina/app/onboarding/createProfile/page.tsx index 18155cf..e96c101 100644 --- a/lumina/app/onboarding/createProfile/page.tsx +++ b/lumina/app/onboarding/createProfile/page.tsx @@ -8,6 +8,7 @@ export default function OnboardingCreateProfile() { const relayUrls = [ "wss://relay.nostr.band", + "wss://relay.damus.io", ]; return ( diff --git a/lumina/app/onboarding/page.tsx b/lumina/app/onboarding/page.tsx index 5c8dda6..faff798 100644 --- a/lumina/app/onboarding/page.tsx +++ b/lumina/app/onboarding/page.tsx @@ -9,6 +9,7 @@ export default function OnboardingHome() { const relayUrls = [ "wss://relay.nostr.band", + "wss://relay.damus.io", ]; return ( diff --git a/lumina/app/page.tsx b/lumina/app/page.tsx index ecd4050..ded2472 100644 --- a/lumina/app/page.tsx +++ b/lumina/app/page.tsx @@ -9,7 +9,8 @@ import { NostrProvider } from "nostr-react"; export default function Home() { const relayUrls = [ - "wss://relay.nostr.band", + // "wss://relay.nostr.band", + "wss://relay.damus.io", ]; return ( diff --git a/lumina/app/profile/[pubkey]/page.tsx b/lumina/app/profile/[pubkey]/page.tsx index 49cf1d9..84a51bf 100644 --- a/lumina/app/profile/[pubkey]/page.tsx +++ b/lumina/app/profile/[pubkey]/page.tsx @@ -24,6 +24,7 @@ export default function ProfilePage() { const relayUrls = [ "wss://relay.nostr.band", + "wss://relay.damus.io", ]; return ( diff --git a/lumina/app/profile/settings/page.tsx b/lumina/app/profile/settings/page.tsx index 3d09e97..28f36f3 100644 --- a/lumina/app/profile/settings/page.tsx +++ b/lumina/app/profile/settings/page.tsx @@ -20,6 +20,7 @@ export default function ProfileSettingsPage() { const relayUrls = [ "wss://relay.nostr.band", + "wss://relay.damus.io", ]; return ( diff --git a/lumina/app/reel/page.tsx b/lumina/app/reel/page.tsx index 5cd0556..15e5da8 100644 --- a/lumina/app/reel/page.tsx +++ b/lumina/app/reel/page.tsx @@ -6,6 +6,7 @@ import { NostrProvider } from "nostr-react"; export default function ReelPage() { const relayUrls = [ "wss://relay.nostr.band", + "wss://relay.damus.io", ]; return ( diff --git a/lumina/app/search/[searchTag]/page.tsx b/lumina/app/search/[searchTag]/page.tsx index b6609bb..06ffb95 100644 --- a/lumina/app/search/[searchTag]/page.tsx +++ b/lumina/app/search/[searchTag]/page.tsx @@ -34,6 +34,7 @@ export default function SearchPage() { const relayUrls = [ "wss://relay.nostr.band", + "wss://relay.damus.io", ]; return ( diff --git a/lumina/app/search/page.tsx b/lumina/app/search/page.tsx index 74d7ec9..e8ef0b1 100644 --- a/lumina/app/search/page.tsx +++ b/lumina/app/search/page.tsx @@ -10,6 +10,7 @@ export default function SearchMainPage() { const relayUrls = [ "wss://relay.nostr.band", + "wss://relay.damus.io", ]; return ( diff --git a/lumina/app/tag/[tag]/page.tsx b/lumina/app/tag/[tag]/page.tsx index a664e93..9d4ab0b 100644 --- a/lumina/app/tag/[tag]/page.tsx +++ b/lumina/app/tag/[tag]/page.tsx @@ -23,6 +23,7 @@ export default function Home() { const relayUrls = [ "wss://relay.nostr.band", + "wss://relay.damus.io", ]; return ( diff --git a/lumina/app/upload/page.tsx b/lumina/app/upload/page.tsx index 8281aa0..e0a96c5 100644 --- a/lumina/app/upload/page.tsx +++ b/lumina/app/upload/page.tsx @@ -26,6 +26,7 @@ export default function UploadPage() { const relayUrls = [ "wss://relay.nostr.band", + "wss://relay.damus.io", ]; return ( diff --git a/lumina/components/CommentsCompontent.tsx b/lumina/components/CommentsCompontent.tsx index 8f913a2..cdc7868 100644 --- a/lumina/components/CommentsCompontent.tsx +++ b/lumina/components/CommentsCompontent.tsx @@ -14,7 +14,7 @@ const CommentsCompontent: React.FC = ({ pubkey, event } const { events } = useNostrEvents({ filter: { - kinds: [1], + // kinds: [1], '#e': [event.id], }, }); diff --git a/lumina/components/FollowerFeed.tsx b/lumina/components/FollowerFeed.tsx index f577f03..40f4da2 100644 --- a/lumina/components/FollowerFeed.tsx +++ b/lumina/components/FollowerFeed.tsx @@ -1,6 +1,8 @@ import { useRef } from "react"; import { useNostrEvents, dateToUnix } from "nostr-react"; import NoteCard from './NoteCard'; +import KIND20Card from "./KIND20Card"; +import { getImageUrl } from "@/utils/utils"; interface FollowerFeedProps { pubkey: string; @@ -25,26 +27,17 @@ const FollowerFeed: React.FC = ({ pubkey }) => { // since: dateToUnix(now.current), // all new events from now // since: 0, limit: 1000, - kinds: [1], + kinds: [20], authors: followingPubkeys, }, }); - // const filteredEvents = events.filter((event) => event.content.includes(".jpg")); - // filter events with regex that checks for png, jpg, or gif - let filteredEvents = events.filter((event) => event.content.match(/https?:\/\/.*\.(?:png|jpg|gif|mp4|webm|jpeg)/g)?.[0]); - - // now filter all events with a tag[0] == t and tag[1] == nsfw - filteredEvents = filteredEvents.filter((event) => event.tags.map((tag) => tag[0] == "t" && tag[1] == "nsfw")); - // filter out all replies - filteredEvents = filteredEvents.filter((event) => !event.tags.some((tag) => { return tag[0] == 'e' })); - return ( <> - {filteredEvents.map((event) => ( + {events.map((event) => ( //

{event.pubkey} posted: {event.content}

- +
))} diff --git a/lumina/components/FollowerQuickViewFeed.tsx b/lumina/components/FollowerQuickViewFeed.tsx index 78c5ab0..86d8875 100644 --- a/lumina/components/FollowerQuickViewFeed.tsx +++ b/lumina/components/FollowerQuickViewFeed.tsx @@ -2,6 +2,8 @@ import { useRef } from "react"; import { useNostrEvents, dateToUnix } from "nostr-react"; import { Skeleton } from "@/components/ui/skeleton"; import QuickViewNoteCard from "./QuickViewNoteCard"; +import QuickViewKind20NoteCard from "./QuickViewKind20NoteCard"; +import { getImageUrl } from "@/utils/utils"; interface FollowerQuickViewFeedProps { pubkey: string; @@ -26,19 +28,15 @@ const FollowerQuickViewFeed: React.FC = ({ pubkey }) // since: dateToUnix(now.current), // all new events from now // since: 0, limit: 1000, - kinds: [1], + kinds: [20], authors: followingPubkeys, }, }); - let filteredEvents = events.filter((event) => event.content.match(/https?:\/\/.*\.(?:png|jpg|gif|jpeg)/g)?.[0]); - // filter out all replies (tag[0] == e) - filteredEvents = filteredEvents.filter((event) => !event.tags.some((tag) => { return tag[0] == 'e' })); - return ( <>
- {filteredEvents.length === 0 ? ( + {events.length === 0 ? ( <>
@@ -62,8 +60,8 @@ const FollowerQuickViewFeed: React.FC = ({ pubkey })
- ) : (filteredEvents.map((event) => ( - + ) : (events.map((event) => ( + )))} diff --git a/lumina/components/GlobalFeed.tsx b/lumina/components/GlobalFeed.tsx index 51aa17d..ddb5901 100644 --- a/lumina/components/GlobalFeed.tsx +++ b/lumina/components/GlobalFeed.tsx @@ -1,40 +1,38 @@ -import { useRef } from "react"; -import { useNostrEvents, dateToUnix } from "nostr-react"; -import NoteCard from './NoteCard'; +import { useNostrEvents } from "nostr-react"; +import KIND20Card from "./KIND20Card"; +import { getImageUrl } from "@/utils/utils"; const GlobalFeed: React.FC = () => { - const now = useRef(new Date()); // Make sure current time isn't re-rendered - const { events } = useNostrEvents({ filter: { - // since: dateToUnix(now.current), // all new events from now - // since: 0, limit: 100, - kinds: [1], + kinds: [20], }, }); - // const filteredEvents = events.filter((event) => event.content.includes(".jpg")); - // filter events with regex that checks for png, jpg, or gif - let filteredEvents = events.filter((event) => event.content.match(/https?:\/\/.*\.(?:png|jpg|gif|jpeg)/g)?.[0]); - - // now filter all events with a tag[0] == t and tag[1] == nsfw - // filteredEvents = filteredEvents.filter((event) => event.tags.map((tag) => tag[0] == "t" && tag[1] == "nsfw")); - filteredEvents = filteredEvents.filter((event) => !event.tags.some((tag) => { return tag[0] == 't' && tag[1] == 'nsfw'})); - // filter out all replies - filteredEvents = filteredEvents.filter((event) => !event.tags.some((tag) => { return tag[0] == 'e' })); - return ( <>

Global Feed

- {filteredEvents.map((event) => ( - //

{event.pubkey} posted: {event.content}

-
- -
- ))} + {events.map((event) => { + const imageUrl = getImageUrl(event.tags); + return ( +
+ +
+ ); + })} ); } -export default GlobalFeed; \ No newline at end of file +export default GlobalFeed; + diff --git a/lumina/components/KIND20Card.tsx b/lumina/components/KIND20Card.tsx new file mode 100644 index 0000000..5f7d56d --- /dev/null +++ b/lumina/components/KIND20Card.tsx @@ -0,0 +1,124 @@ +import React from 'react'; +import { useProfile } from "nostr-react"; +import { + nip19, +} from "nostr-tools"; +import { + Card, + CardContent, + CardFooter, + CardHeader, + CardTitle, +} from "@/components/ui/card" +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, +} from "@/components/ui/tooltip" +import { + Carousel, + CarouselContent, + CarouselItem, + CarouselNext, + CarouselPrevious, +} from "@/components/ui/carousel" +import ReactionButton from '@/components/ReactionButton'; +import { Avatar, AvatarImage } from '@/components/ui/avatar'; +import ViewRawButton from '@/components/ViewRawButton'; +import ViewNoteButton from './ViewNoteButton'; +import Link from 'next/link'; +import ViewCopyButton from './ViewCopyButton'; +import { Event as NostrEvent } from "nostr-tools"; +import ZapButton from './ZapButton'; +import Image from 'next/image'; +import { extractDimensions } from '@/utils/utils'; + +interface KIND20CardProps { + pubkey: string; + text: string; + image: string; + eventId: string; + tags: string[][]; + event: NostrEvent; + showViewNoteCardButton: boolean; +} + +const KIND20Card: React.FC = ({ pubkey, text, image, eventId, tags, event, showViewNoteCardButton }) => { + const { data: userData } = useProfile({ + pubkey, + }); + + const title = userData?.username || userData?.display_name || userData?.name || userData?.npub || nip19.npubEncode(pubkey); + text = text.replaceAll('\n', ' '); + const createdAt = new Date(event.created_at * 1000); + const hrefProfile = `/profile/${nip19.npubEncode(pubkey)}`; + const profileImageSrc = userData?.picture || "https://robohash.org/" + pubkey; + + const { width, height } = extractDimensions(event); + + return ( + <> + + + + + + + +
+ + + + {title} +
+
+ +

{title}

+
+
+
+ +
+
+ +
+
+ {image && ( + {text} + )} +
+
+
+ {text} +
+
+
+
+
+ + + {showViewNoteCardButton && } +
+
+ + +
+
+
+ + {createdAt.toLocaleString()} + +
+ + ); +} + +export default KIND20Card; \ No newline at end of file diff --git a/lumina/components/NotePageComponent.tsx b/lumina/components/NotePageComponent.tsx index 7cfa1d6..dbfc24a 100644 --- a/lumina/components/NotePageComponent.tsx +++ b/lumina/components/NotePageComponent.tsx @@ -2,6 +2,8 @@ import { useRef } from "react"; import { useNostrEvents } from "nostr-react"; import NoteCard from '@/components/NoteCard'; import CommentsCompontent from "@/components/CommentsCompontent"; +import KIND20Card from "./KIND20Card"; +import { getImageUrl } from "@/utils/utils"; interface NotePageComponentProps { id: string; @@ -12,23 +14,45 @@ const NotePageComponent: React.FC = ({ id }) => { const { events } = useNostrEvents({ filter: { - // since: dateToUnix(now.current), // all new events from now - // since: 0, ids: [id], limit: 1, - kinds: [1], }, }); // filter out all events that also have another e tag with another id - const filteredEvents = events.filter((event) => { return event.tags.filter((tag) => { return tag[0] === '#e' && tag[1] !== id }).length === 0 }); + const filteredEvents = events.filter((event) => { + return event.tags.filter((tag) => { + return tag[0] === '#e' && tag[1] !== id; + }).length === 0; + }); return ( <> - {events.map((event) => ( - //

{event.pubkey} posted: {event.content}

+ {filteredEvents.map((event) => (
- + {event.kind === 1 && ( + + )} + {event.kind === 20 && ( + + )}
diff --git a/lumina/components/ProfileFeed.tsx b/lumina/components/ProfileFeed.tsx index b6ee766..e672f63 100644 --- a/lumina/components/ProfileFeed.tsx +++ b/lumina/components/ProfileFeed.tsx @@ -2,6 +2,8 @@ import { useRef } from "react"; import { useNostrEvents, dateToUnix } from "nostr-react"; import NoteCard from '@/components/NoteCard'; import { Skeleton } from "@/components/ui/skeleton"; +import KIND20Card from "./KIND20Card"; +import { getImageUrl } from "@/utils/utils"; interface ProfileFeedProps { pubkey: string; @@ -16,19 +18,15 @@ const ProfileFeed: React.FC = ({ pubkey }) => { authors: [pubkey], // since: 0, // limit: 10, - kinds: [1], + kinds: [20], }, }); - let filteredEvents = events.filter((event) => event.content.match(/https?:\/\/.*\.(?:png|jpg|gif|mp4|webm|mov|jpeg)/g)?.[0]); - // filter out all replies (tag[0] == e) - filteredEvents = filteredEvents.filter((event) => !event.tags.some((tag) => { return tag[0] == 'e' })); - return ( <> {/*

Profile Feed

*/} - {filteredEvents.length === 0 ? ( + {events.length === 0 ? (
@@ -36,11 +34,11 @@ const ProfileFeed: React.FC = ({ pubkey }) => {
- ) : (filteredEvents.map((event) => ( + ) : (events.map((event) => ( //

{event.pubkey} posted: {event.content}

//
- +
)))} diff --git a/lumina/components/ProfileQuickViewFeed.tsx b/lumina/components/ProfileQuickViewFeed.tsx index be4370e..e8d1285 100644 --- a/lumina/components/ProfileQuickViewFeed.tsx +++ b/lumina/components/ProfileQuickViewFeed.tsx @@ -1,8 +1,9 @@ import { useRef, useState } from "react"; -import { useNostrEvents, dateToUnix } from "nostr-react"; +import { useNostrEvents } from "nostr-react"; import { Skeleton } from "@/components/ui/skeleton"; -import QuickViewNoteCard from "./QuickViewNoteCard"; import { Button } from "@/components/ui/button"; +import QuickViewKind20NoteCard from "./QuickViewKind20NoteCard"; +import { getImageUrl } from "@/utils/utils"; interface ProfileQuickViewFeedProps { pubkey: string; @@ -12,18 +13,14 @@ const ProfileQuickViewFeed: React.FC = ({ pubkey }) = const now = useRef(new Date()); // Make sure current time isn't re-rendered const [limit, setLimit] = useState(100); - const { isLoading ,events } = useNostrEvents({ + const { isLoading, events } = useNostrEvents({ filter: { authors: [pubkey], limit: limit, - kinds: [1], + kinds: [20], }, }); - let filteredEvents = events.filter((event) => event.content.match(/https?:\/\/.*\.(?:png|jpg|gif|mp4|webm|mov|jpeg)/g)?.[0]); - // filter out all replies (tag[0] == e) - filteredEvents = filteredEvents.filter((event) => !event.tags.some((tag) => { return tag[0] == 'e' })); - const loadMore = () => { setLimit(limit => limit + 50); } @@ -31,7 +28,7 @@ const ProfileQuickViewFeed: React.FC = ({ pubkey }) = return ( <>
- {filteredEvents.length === 0 && isLoading ? ( + {events.length === 0 && isLoading ? ( <>
@@ -45,9 +42,12 @@ const ProfileQuickViewFeed: React.FC = ({ pubkey }) = ) : ( <> - {filteredEvents.map((event) => ( - - ))} + {events.map((event) => { + const imageUrl = getImageUrl(event.tags); + return ( + + ); + })} )}
diff --git a/lumina/components/QuickViewKind20NoteCard.tsx b/lumina/components/QuickViewKind20NoteCard.tsx new file mode 100644 index 0000000..7295fc5 --- /dev/null +++ b/lumina/components/QuickViewKind20NoteCard.tsx @@ -0,0 +1,65 @@ +import React from 'react'; +import { useProfile } from "nostr-react"; +import { + nip19, +} from "nostr-tools"; +import { + Card, + SmallCardContent, +} from "@/components/ui/card" +import Link from 'next/link'; +import Image from 'next/image'; +import { extractDimensions } from '@/utils/utils'; + +interface QuickViewKind20NoteCardProps { + pubkey: string; + text: string; + image: string; + eventId: string; + tags: string[][]; + event: any; + linkToNote: boolean; +} + +const QuickViewKind20NoteCard: React.FC = ({ pubkey, text, image, eventId, tags, event, linkToNote }) => { + + text = text.replaceAll('\n', ' '); + const encodedNoteId = nip19.noteEncode(event.id) + + const { width, height } = extractDimensions(event); + + const card = ( + + +
+
+
+ {text} +
+
+
+
+
+ ); + + return ( + <> + {linkToNote ? ( + + {card} + + ) : ( + card + )} + + ); +} + +export default QuickViewKind20NoteCard; \ No newline at end of file diff --git a/lumina/components/TagFeed.tsx b/lumina/components/TagFeed.tsx index 080f1c0..1b6744c 100644 --- a/lumina/components/TagFeed.tsx +++ b/lumina/components/TagFeed.tsx @@ -1,6 +1,8 @@ import { useRef } from "react"; import { useNostrEvents, dateToUnix } from "nostr-react"; import NoteCard from './NoteCard'; +import KIND20Card from "./KIND20Card"; +import { getImageUrl } from "@/utils/utils"; interface TagFeedProps { tag: string; @@ -14,27 +16,18 @@ const TagFeed: React.FC = ({tag}) => { // since: dateToUnix(now.current), // all new events from now // since: 0, // limit: 100, - kinds: [1], + kinds: [20], "#t": [tag], }, }); - // const filteredEvents = events.filter((event) => event.content.includes(".jpg")); - // filter events with regex that checks for png, jpg, or gif - let filteredEvents = events.filter((event) => event.content.match(/https?:\/\/.*\.(?:png|jpg|gif|mp4|webm|jpeg)/g)?.[0]); - - // now filter all events with a tag[0] == t and tag[1] == nsfw - filteredEvents = filteredEvents.filter((event) => event.tags.map((tag) => tag[0] == "t" && tag[1] == "nsfw")); - // filter out all replies - filteredEvents = filteredEvents.filter((event) => !event.tags.some((tag) => { return tag[0] == 'e' })); - return ( <>

Tag Feed for {tag}

- {filteredEvents.map((event) => ( + {events.map((event) => ( //

{event.pubkey} posted: {event.content}

- +
))} diff --git a/lumina/components/searchComponents/SearchNotesBox.tsx b/lumina/components/searchComponents/SearchNotesBox.tsx index edfca51..9172b4f 100644 --- a/lumina/components/searchComponents/SearchNotesBox.tsx +++ b/lumina/components/searchComponents/SearchNotesBox.tsx @@ -30,6 +30,8 @@ import Link from 'next/link'; import { Event as NostrEvent } from "nostr-tools"; import ProfileInfoCard from '../ProfileInfoCard'; import NoteCard from '../NoteCard'; +import KIND20Card from '../KIND20Card'; +import { getImageUrl } from '@/utils/utils'; interface SearchNotesBoxProps { searchTag: string; @@ -38,7 +40,7 @@ interface SearchNotesBoxProps { const SearchNotesBox: React.FC = ({ searchTag }) => { const { events: notes } = useNostrEvents({ filter: { - kinds: [1], + kinds: [1, 20], search: searchTag, limit: 10, }, @@ -53,7 +55,11 @@ const SearchNotesBox: React.FC = ({ searchTag }) => {
{notes.map((event: NostrEvent) => ( - + event.kind === 1 ? ( + + ) : event.kind === 20 ? ( + + ) : null ))}
diff --git a/lumina/utils/utils.ts b/lumina/utils/utils.ts new file mode 100644 index 0000000..f64db28 --- /dev/null +++ b/lumina/utils/utils.ts @@ -0,0 +1,24 @@ +import { Event as NostrEvent } from "nostr-tools"; + +export function getImageUrl(tags: string[][]): string { + const imetaTag = tags.find(tag => tag[0] === 'imeta'); + if (imetaTag) { + const urlItem = imetaTag.find(item => item.startsWith('url ')); + if (urlItem) { + return urlItem.split(' ')[1]; + } + } + return ''; + } + +export function extractDimensions(event: NostrEvent): { width: number; height: number } { + const imetaTag = event.tags.find(tag => tag[0] === 'imeta'); + if (imetaTag) { + const dimInfo = imetaTag.find(item => item.startsWith('dim ')); + if (dimInfo) { + const [width, height] = dimInfo.split(' ')[1].split('x').map(Number); + return { width, height }; + } + } + return { width: 500, height: 300 }; // Default dimensions if not found +}