diff --git a/src/App.tsx b/src/App.tsx index 793e06c5..f8eb5964 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -13,6 +13,7 @@ import { MediaUploadServiceProvider } from './providers/MediaUploadServiceProvid import { MuteListProvider } from './providers/MuteListProvider' import { NostrProvider } from './providers/NostrProvider' import { NoteStatsProvider } from './providers/NoteStatsProvider' +import { ReplyProvider } from './providers/ReplyProvider' import { ScreenSizeProvider } from './providers/ScreenSizeProvider' import { ZapProvider } from './providers/ZapProvider' @@ -28,12 +29,14 @@ export default function App(): JSX.Element { - - - - - - + + + + + + + + diff --git a/src/components/Nip22ReplyNoteList/index.tsx b/src/components/Nip22ReplyNoteList/index.tsx index f66a7ce9..6d64d06b 100644 --- a/src/components/Nip22ReplyNoteList/index.tsx +++ b/src/components/Nip22ReplyNoteList/index.tsx @@ -1,10 +1,9 @@ import { Separator } from '@/components/ui/separator' import { BIG_RELAY_URLS, ExtendedKind } from '@/constants' import { isCommentEvent, isProtectedEvent } from '@/lib/event' -import { tagNameEquals } from '@/lib/tag' +import { generateEventId, tagNameEquals } from '@/lib/tag' import { cn } from '@/lib/utils' import { useNostr } from '@/providers/NostrProvider' -import { useNoteStats } from '@/providers/NoteStatsProvider' import client from '@/services/client.service' import dayjs from 'dayjs' import { Event as NEvent } from 'nostr-tools' @@ -31,7 +30,6 @@ export default function Nip22ReplyNoteList({ >({}) const [loading, setLoading] = useState(false) const [highlightReplyId, setHighlightReplyId] = useState(undefined) - const { updateNoteReplyCount } = useNoteStats() const replyRefs = useRef>({}) const bottomRef = useRef(null) @@ -111,8 +109,6 @@ export default function Nip22ReplyNoteList({ }, [event]) useEffect(() => { - updateNoteReplyCount(event.id, replies.length) - const replyMap: Record = {} for (const reply of replies) { @@ -128,7 +124,7 @@ export default function Nip22ReplyNoteList({ continue } setReplyMap(replyMap) - }, [replies, event.id, updateNoteReplyCount]) + }, [replies, event.id]) const loadMore = useCallback(async () => { if (loading || !until || !timelineKey) return @@ -192,8 +188,8 @@ export default function Nip22ReplyNoteList({
(replyRefs.current[reply.id] = el)} key={reply.id}> info?.parent?.id && highlightReply(info?.parent?.id)} highlight={highlightReplyId === reply.id} />
diff --git a/src/components/Note/index.tsx b/src/components/Note/index.tsx index efb12026..a80e575c 100644 --- a/src/components/Note/index.tsx +++ b/src/components/Note/index.tsx @@ -1,6 +1,5 @@ import { useSecondaryPage } from '@/PageManager' import { ExtendedKind } from '@/constants' -import { useFetchEvent } from '@/hooks' import { extractImageInfosFromEventTags, getParentEventId, getUsingClient } from '@/lib/event' import { toNote } from '@/lib/link' import { Event } from 'nostr-tools' @@ -30,7 +29,6 @@ export default function Note({ [event, hideParentNotePreview] ) const imageInfos = useMemo(() => extractImageInfosFromEventTags(event), [event]) - const { event: parentEvent, isFetching } = useFetchEvent(parentEventId) const usingClient = useMemo(() => getUsingClient(event), [event]) return ( @@ -60,8 +58,7 @@ export default function Note({ {parentEventId && ( { e.stopPropagation() diff --git a/src/components/NoteStats/ReplyButton.tsx b/src/components/NoteStats/ReplyButton.tsx index c7393969..9db92af7 100644 --- a/src/components/NoteStats/ReplyButton.tsx +++ b/src/components/NoteStats/ReplyButton.tsx @@ -1,5 +1,5 @@ import { useNostr } from '@/providers/NostrProvider' -import { useNoteStats } from '@/providers/NoteStatsProvider' +import { useReply } from '@/providers/ReplyProvider' import { MessageCircle } from 'lucide-react' import { Event } from 'nostr-tools' import { useMemo, useState } from 'react' @@ -7,19 +7,13 @@ import { useTranslation } from 'react-i18next' import PostEditor from '../PostEditor' import { formatCount } from './utils' -export default function ReplyButton({ - event, - variant = 'note' -}: { - event: Event - variant?: 'note' | 'reply' -}) { +export default function ReplyButton({ event }: { event: Event }) { const { t } = useTranslation() const { checkLogin } = useNostr() - const { noteStatsMap } = useNoteStats() - const { replyCount } = useMemo( - () => (variant === 'reply' ? {} : (noteStatsMap.get(event.id) ?? {})), - [noteStatsMap, event.id, variant] + const { repliesMap } = useReply() + const replyCount = useMemo( + () => repliesMap.get(event.id)?.events.length || 0, + [repliesMap, event.id] ) const [open, setOpen] = useState(false) @@ -36,9 +30,7 @@ export default function ReplyButton({ title={t('Reply')} > - {variant !== 'reply' && !!replyCount && ( -
{formatCount(replyCount)}
- )} + {!!replyCount &&
{formatCount(replyCount)}
} diff --git a/src/components/NoteStats/index.tsx b/src/components/NoteStats/index.tsx index f104027a..5ce9af84 100644 --- a/src/components/NoteStats/index.tsx +++ b/src/components/NoteStats/index.tsx @@ -16,8 +16,7 @@ export default function NoteStats({ event, className, classNames, - fetchIfNotExisting = false, - variant = 'note' + fetchIfNotExisting = false }: { event: Event className?: string @@ -25,7 +24,6 @@ export default function NoteStats({ buttonBar?: string } fetchIfNotExisting?: boolean - variant?: 'note' | 'reply' }) { const { isSmallScreen } = useScreenSize() const { fetchNoteStats } = useNoteStats() @@ -50,7 +48,7 @@ export default function NoteStats({ )} onClick={(e) => e.stopPropagation()} > - + @@ -70,7 +68,7 @@ export default function NoteStats({ className={cn('flex items-center', loading ? 'animate-pulse' : '')} onClick={(e) => e.stopPropagation()} > - + diff --git a/src/components/ParentNotePreview/index.tsx b/src/components/ParentNotePreview/index.tsx index cb436beb..4fa6e76a 100644 --- a/src/components/ParentNotePreview/index.tsx +++ b/src/components/ParentNotePreview/index.tsx @@ -1,25 +1,24 @@ import { Skeleton } from '@/components/ui/skeleton' +import { useFetchEvent } from '@/hooks' import { cn } from '@/lib/utils' import { useMuteList } from '@/providers/MuteListProvider' -import { Event } from 'nostr-tools' import { useMemo } from 'react' import { useTranslation } from 'react-i18next' import ContentPreview from '../ContentPreview' import UserAvatar from '../UserAvatar' export default function ParentNotePreview({ - event, - isFetching = false, + eventId, className, onClick }: { - event?: Event - isFetching?: boolean + eventId: string className?: string onClick?: React.MouseEventHandler | undefined }) { const { t } = useTranslation() const { mutePubkeys } = useMuteList() + const { event, isFetching } = useFetchEvent(eventId) const isMuted = useMemo( () => (event ? mutePubkeys.includes(event.pubkey) : false), [mutePubkeys, event] @@ -43,6 +42,20 @@ export default function ParentNotePreview({ ) } + if (!event) { + return ( +
+
{t('reply to')}
+
{`[${t('Not found the note')}]`}
+
+ ) + } + return (
{}, highlight = false }: { event: Event - parentEvent?: Event - onClickParent?: (eventId: string) => void + parentEventId?: string + onClickParent?: () => void highlight?: boolean }) { const { t } = useTranslation() @@ -53,20 +53,20 @@ export default function ReplyNote({
- {parentEvent && ( + {parentEventId && ( { e.stopPropagation() - onClickParent(parentEvent.id) + onClickParent() }} /> )} {show ? ( <> - + ) : (