From d8217bda496f87499837d510dcad7c35e9c57e26 Mon Sep 17 00:00:00 2001
From: Jure <44338+hoornet@users.noreply.github.com>
Date: Mon, 13 Apr 2026 20:51:24 +0200
Subject: [PATCH] Add new account age badge on notes (< 60 days)
---
src/components/feed/NoteCard.tsx | 5 +++++
src/components/search/SearchView.tsx | 10 +++++-----
src/lib/nostr/social.ts | 12 +++++++++---
src/lib/notificationPoller.ts | 3 +--
4 files changed, 20 insertions(+), 10 deletions(-)
diff --git a/src/components/feed/NoteCard.tsx b/src/components/feed/NoteCard.tsx
index fba91e3..9dcd81d 100644
--- a/src/components/feed/NoteCard.tsx
+++ b/src/components/feed/NoteCard.tsx
@@ -34,6 +34,8 @@ export const NoteCard = memo(function NoteCard({ event, focused, onReplyInThread
const nip05 = typeof profile?.nip05 === "string" ? profile.nip05 : null;
const verified = useNip05Verified(event.pubkey, nip05);
const time = event.created_at ? timeAgo(event.created_at) : "";
+ const profileCreatedAt = typeof profile?._createdAt === "number" ? profile._createdAt : null;
+ const isNewAccount = profileCreatedAt !== null && (Date.now() / 1000 - profileCreatedAt) < 60 * 24 * 3600;
const loggedIn = useUserStore((s) => s.loggedIn);
const ownPubkey = useUserStore((s) => s.pubkey);
@@ -108,6 +110,9 @@ export const NoteCard = memo(function NoteCard({ event, focused, onReplyInThread
)}
{time}
+ {isNewAccount && (
+ new
+ )}
{/* Context menu — hidden until card hover, not shown for own notes */}
{loggedIn && event.pubkey !== ownPubkey && (
diff --git a/src/components/search/SearchView.tsx b/src/components/search/SearchView.tsx
index d8cd8f2..a74e985 100644
--- a/src/components/search/SearchView.tsx
+++ b/src/components/search/SearchView.tsx
@@ -172,11 +172,11 @@ export function SearchView() {
...s,
profile: p ? {
pubkey: s.pubkey,
- name: (p as Record).name || "",
- displayName: (p as Record).display_name || (p as Record).name || "",
- picture: (p as Record).picture || "",
- nip05: (p as Record).nip05 || "",
- about: (p as Record).about || "",
+ name: (p as Record).name as string || "",
+ displayName: (p as Record).display_name as string || (p as Record).name as string || "",
+ picture: (p as Record).picture as string || "",
+ nip05: (p as Record).nip05 as string || "",
+ about: (p as Record).about as string || "",
} : null,
};
} catch {
diff --git a/src/lib/nostr/social.ts b/src/lib/nostr/social.ts
index 291d00c..f631932 100644
--- a/src/lib/nostr/social.ts
+++ b/src/lib/nostr/social.ts
@@ -33,9 +33,15 @@ export async function publishContactList(pubkeys: string[]): Promise {
export async function fetchProfile(pubkey: string) {
const instance = getNDK();
- const user = instance.getUser({ pubkey });
- await user.fetchProfile();
- return user.profile;
+ const events = await fetchWithTimeout(instance, { kinds: [0], authors: [pubkey] }, FEED_TIMEOUT);
+ const event = [...events].sort((a, b) => (b.created_at ?? 0) - (a.created_at ?? 0))[0];
+ if (!event) return null;
+ try {
+ const content = JSON.parse(event.content) as Record;
+ return { ...content, _createdAt: event.created_at ?? null };
+ } catch {
+ return null;
+ }
}
export async function fetchFollowSuggestions(myFollows: string[]): Promise<{ pubkey: string; mutualCount: number }[]> {
diff --git a/src/lib/notificationPoller.ts b/src/lib/notificationPoller.ts
index 5bb6a86..45e570b 100644
--- a/src/lib/notificationPoller.ts
+++ b/src/lib/notificationPoller.ts
@@ -12,8 +12,7 @@ async function getProfileName(pubkey: string): Promise {
try {
const p = await fetchProfile(pubkey);
if (p) {
- const meta = p as Record;
- return meta.display_name || meta.name || pubkey.slice(0, 8) + "…";
+ return (p as Record).display_name as string || (p as Record).name as string || pubkey.slice(0, 8) + "…";
}
} catch { /* ignore */ }
return pubkey.slice(0, 8) + "…";