diff --git a/src/components/NoteList/index.tsx b/src/components/NoteList/index.tsx index c494a96c..89fb0bf0 100644 --- a/src/components/NoteList/index.tsx +++ b/src/components/NoteList/index.tsx @@ -1,4 +1,5 @@ import { Button } from '@/components/ui/button' +import { Skeleton } from '@/components/ui/skeleton' import { PICTURE_EVENT_KIND } from '@/constants' import { isReplyNoteEvent } from '@/lib/event' import { checkAlgoRelay } from '@/lib/relay' @@ -187,14 +188,14 @@ export default function NoteList({ }} pullingContent="" > -
+
{newEvents.filter((event: Event) => { return ( (!filterMutedNotes || !mutePubkeys.includes(event.pubkey)) && (listMode !== 'posts' || !isReplyNoteEvent(event)) ) }).length > 0 && ( -
+
@@ -202,7 +203,7 @@ export default function NoteList({ )} {isPictures ? ( @@ -220,19 +221,19 @@ export default function NoteList({ ))}
)} -
- {hasMore || refreshing ? ( -
{t('loading...')}
- ) : events.length ? ( - t('no more notes') - ) : ( -
- -
- )} -
+ {hasMore || refreshing ? ( +
+ +
+ ) : events.length ? ( +
t('no more notes')
+ ) : ( +
+ +
+ )}
@@ -320,3 +321,45 @@ function PictureNoteCardMasonry({
) } + +function LoadingSkeleton({ isPictures }: { isPictures: boolean }) { + const { isLargeScreen } = useScreenSize() + + if (isPictures) { + return ( +
+ {[...Array(isLargeScreen ? 3 : 2)].map((_, i) => ( +
+ +
+ +
+ + +
+
+
+ ))} +
+ ) + } + + return ( +
+
+ +
+ + +
+
+ + +
+ ) +} diff --git a/src/components/NotificationList/index.tsx b/src/components/NotificationList/index.tsx index 24ed9c19..5b2313f9 100644 --- a/src/components/NotificationList/index.tsx +++ b/src/components/NotificationList/index.tsx @@ -1,3 +1,4 @@ +import { Skeleton } from '@/components/ui/skeleton' import { COMMENT_EVENT_KIND, PICTURE_EVENT_KIND } from '@/constants' import { useFetchEvent } from '@/hooks' import { extractEmbeddedNotesFromContent, extractImagesFromContent } from '@/lib/event' @@ -9,7 +10,15 @@ import client from '@/services/client.service' import dayjs from 'dayjs' import { Heart, MessageCircle, Repeat, ThumbsUp } from 'lucide-react' import { Event, kinds, nip19, validateEvent } from 'nostr-tools' -import { useCallback, useEffect, useMemo, useRef, useState } from 'react' +import { + forwardRef, + useCallback, + useEffect, + useImperativeHandle, + useMemo, + useRef, + useState +} from 'react' import { useTranslation } from 'react-i18next' import PullToRefresh from 'react-simple-pull-to-refresh' import { embedded, embeddedNostrNpubRenderer, embeddedNostrProfileRenderer } from '../Embedded' @@ -18,7 +27,7 @@ import UserAvatar from '../UserAvatar' const LIMIT = 100 -export default function NotificationList() { +const NotificationList = forwardRef((_, ref) => { const { t } = useTranslation() const { pubkey } = useNostr() const [refreshCount, setRefreshCount] = useState(0) @@ -27,6 +36,16 @@ export default function NotificationList() { const [notifications, setNotifications] = useState([]) const [until, setUntil] = useState(dayjs().unix()) const bottomRef = useRef(null) + useImperativeHandle( + ref, + () => ({ + refresh: () => { + if (refreshing) return + setRefreshCount((count) => count + 1) + } + }), + [refreshing] + ) useEffect(() => { if (!pubkey) { @@ -133,7 +152,33 @@ export default function NotificationList() { ))}
{until || refreshing ? ( -
{t('loading...')}
+
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
) : ( t('no more notifications') )} @@ -141,7 +186,9 @@ export default function NotificationList() {
) -} +}) +NotificationList.displayName = 'NotificationList' +export default NotificationList function NotificationItem({ notification }: { notification: Event }) { if (notification.kind === kinds.Reaction) { diff --git a/src/pages/primary/NotificationListPage/index.tsx b/src/pages/primary/NotificationListPage/index.tsx index e3f0bde7..82f16b31 100644 --- a/src/pages/primary/NotificationListPage/index.tsx +++ b/src/pages/primary/NotificationListPage/index.tsx @@ -1,10 +1,22 @@ import NotificationList from '@/components/NotificationList' import PrimaryPageLayout from '@/layouts/PrimaryPageLayout' +import { usePrimaryPage } from '@/PageManager' import { Bell } from 'lucide-react' -import { forwardRef } from 'react' +import { forwardRef, useEffect, useRef } from 'react' import { useTranslation } from 'react-i18next' const NotificationListPage = forwardRef((_, ref) => { + const { current } = usePrimaryPage() + const firstRenderRef = useRef(true) + const notificationListRef = useRef<{ refresh: () => void }>(null) + + useEffect(() => { + if (current === 'notifications' && !firstRenderRef.current) { + notificationListRef.current?.refresh() + } + firstRenderRef.current = false + }, [current]) + return ( { displayScrollToTopButton >
- +
)