From 547e25d7dd6f3e4cfb66f4965fb08d8f451b151e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 6 Sep 2026 20:18:25 +0000 Subject: [PATCH] Fix notification event selection and account read-state sync Co-authored-by: mroxso <24775431+mroxso@users.noreply.github.com> --- src/components/nostr/NotificationsCenter.tsx | 6 ++++-- src/hooks/useLocalStorage.ts | 11 +++++++++-- src/hooks/useNotifications.ts | 9 +++++++-- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/components/nostr/NotificationsCenter.tsx b/src/components/nostr/NotificationsCenter.tsx index 5d0dfc7..772a8cb 100644 --- a/src/components/nostr/NotificationsCenter.tsx +++ b/src/components/nostr/NotificationsCenter.tsx @@ -22,7 +22,7 @@ import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip import { useAuthor } from '@/hooks/useAuthor'; import { useNotificationReadState, useNotifications, type Notification, type NotificationKind } from '@/hooks/useNotifications'; import { useWindowManager } from '@/os/useWindowManager'; -import { displayName, relativeTime } from '@/lib/nostrUtils'; +import { displayName, relativeTime, rootReference } from '@/lib/nostrUtils'; import { cn } from '@/lib/utils'; const ICONS: Record = { @@ -179,7 +179,9 @@ function NotificationRow({ notification, unread, onNavigate }: { notification: N const Icon = ICONS[notification.kind]; const author = displayName(notification.event.pubkey, data?.metadata); const preview = notification.event.content.replace(/\s+/g, ' ').trim(); - const targetEvent = notification.event.tags.find(([name]) => name === 'e')?.[1]; + const targetEvent = notification.kind === 'mention' || notification.kind === 'reply' + ? notification.event.id + : rootReference(notification.event); const openNotification = () => { if (targetEvent) openApp('notes', { id: targetEvent }); diff --git a/src/hooks/useLocalStorage.ts b/src/hooks/useLocalStorage.ts index 01966dc..1e3b35e 100644 --- a/src/hooks/useLocalStorage.ts +++ b/src/hooks/useLocalStorage.ts @@ -29,7 +29,7 @@ export function useLocalStorage( const serialize = serializer?.serialize || JSON.stringify; const deserialize = serializer?.deserialize || JSON.parse; - const [state, setState] = useState(() => { + const readValue = () => { try { const item = localStorage.getItem(key); return item ? deserialize(item) : defaultValue; @@ -37,7 +37,14 @@ export function useLocalStorage( console.warn(`Failed to load ${key} from localStorage:`, error); return defaultValue; } - }); + }; + + const [state, setState] = useState(readValue); + const [storageKey, setStorageKey] = useState(key); + if (storageKey !== key) { + setStorageKey(key); + setState(readValue()); + } const setValue = useCallback( (value: T | ((prev: T) => T)) => { diff --git a/src/hooks/useNotifications.ts b/src/hooks/useNotifications.ts index 0a41ab0..407208d 100644 --- a/src/hooks/useNotifications.ts +++ b/src/hooks/useNotifications.ts @@ -1,6 +1,7 @@ import { useQuery } from '@tanstack/react-query'; import { useNostr } from '@nostrify/react'; import type { NostrEvent } from '@nostrify/nostrify'; +import { isReply } from '@/lib/nostrUtils'; import { useCurrentUser } from './useCurrentUser'; import { useLocalStorage } from './useLocalStorage'; @@ -26,7 +27,7 @@ function notificationKind(event: NostrEvent): NotificationKind { case 9735: return 'zap'; case 1: - return event.tags.some(([name]) => name === 'e') ? 'reply' : 'mention'; + return isReply(event) ? 'reply' : 'mention'; default: return 'mention'; } @@ -58,7 +59,11 @@ export function useNotifications() { const seen = new Set(); return events - .filter((event) => event.pubkey !== user.pubkey && !seen.has(event.id) && seen.add(event.id)) + .filter((event) => { + if (event.pubkey === user.pubkey || seen.has(event.id)) return false; + seen.add(event.id); + return true; + }) .sort((left, right) => right.created_at - left.created_at) .map((event) => ({ event, kind: notificationKind(event) })); },