From 226da7423249730dd44a64c33ca42e454292243f Mon Sep 17 00:00:00 2001 From: mroxso <24775431+mroxso@users.noreply.github.com> Date: Sun, 19 Jan 2025 17:55:28 +0100 Subject: [PATCH] Feature: Load more (#28) * load more button on global feed * load more button on follower feed * load more button on follower feed * load more button on profile feed * only show first 20 instead of 100 images in profile quick view feed * load more button on profile text feed --- lumina/components/FollowerFeed.tsx | 50 ++++++++------ lumina/components/FollowerQuickViewFeed.tsx | 74 +++++++++++++-------- lumina/components/GlobalFeed.tsx | 29 ++++---- lumina/components/ProfileFeed.tsx | 50 +++++++++----- lumina/components/ProfileQuickViewFeed.tsx | 2 +- lumina/components/ProfileTextFeed.tsx | 45 +++++++++---- 6 files changed, 158 insertions(+), 92 deletions(-) diff --git a/lumina/components/FollowerFeed.tsx b/lumina/components/FollowerFeed.tsx index 541b6c6..6c5c490 100644 --- a/lumina/components/FollowerFeed.tsx +++ b/lumina/components/FollowerFeed.tsx @@ -1,8 +1,8 @@ -import { useRef } from "react"; +import { useRef, useState } from "react"; import { useNostrEvents, dateToUnix } from "nostr-react"; -import NoteCard from './NoteCard'; import KIND20Card from "./KIND20Card"; import { getImageUrl } from "@/utils/utils"; +import { Button } from "@/components/ui/button"; interface FollowerFeedProps { pubkey: string; @@ -10,6 +10,7 @@ interface FollowerFeedProps { const FollowerFeed: React.FC = ({ pubkey }) => { const now = useRef(new Date()); + const [limit, setLimit] = useState(20); const { events: following, isLoading: followingLoading } = useNostrEvents({ filter: { @@ -21,31 +22,42 @@ const FollowerFeed: React.FC = ({ pubkey }) => { let followingPubkeys = following.flatMap((event) => event.tags.map(tag => tag[1])).slice(0, 500); - const { events } = useNostrEvents({ + const { events, isLoading } = useNostrEvents({ filter: { - limit: 20, + limit: limit, kinds: [20], authors: followingPubkeys, }, }); + const loadMore = () => { + setLimit(prevLimit => prevLimit + 20); + }; + return ( -
- {events.map((event) => ( -
- + <> +
+ {events.map((event) => ( +
+ +
+ ))} +
+ {!isLoading && ( +
+
- ))} -
+ )} + ); } diff --git a/lumina/components/FollowerQuickViewFeed.tsx b/lumina/components/FollowerQuickViewFeed.tsx index 2ea8799..512ca40 100644 --- a/lumina/components/FollowerQuickViewFeed.tsx +++ b/lumina/components/FollowerQuickViewFeed.tsx @@ -1,6 +1,7 @@ -import { useRef } from "react"; +import { useRef, useState } from "react"; import { useNostrEvents, dateToUnix } from "nostr-react"; import { Skeleton } from "@/components/ui/skeleton"; +import { Button } from "@/components/ui/button"; import QuickViewNoteCard from "./QuickViewNoteCard"; import QuickViewKind20NoteCard from "./QuickViewKind20NoteCard"; import { getImageUrl } from "@/utils/utils"; @@ -11,6 +12,7 @@ interface FollowerQuickViewFeedProps { const FollowerQuickViewFeed: React.FC = ({ pubkey }) => { const now = useRef(new Date()); // Make sure current time isn't re-rendered + const [limit, setLimit] = useState(25); const { events: following, isLoading: followingLoading } = useNostrEvents({ filter: { @@ -19,51 +21,65 @@ const FollowerQuickViewFeed: React.FC = ({ pubkey }) limit: 1, }, }); - // let followingPubkeys = following.map((event) => event.tags[event.tags.length - 1][1]); - // let followingPubkeys = following.flatMap((event) => event.tags.map(tag => tag[1])).slice(0, 50); + let followingPubkeys = following.flatMap((event) => event.tags.map(tag => tag[1])).slice(0, 500); - const { events } = useNostrEvents({ + const { events, isLoading } = useNostrEvents({ filter: { - // since: dateToUnix(now.current), // all new events from now - // since: 0, - limit: 25, + limit: limit, kinds: [20], authors: followingPubkeys, }, }); + const loadMore = () => { + setLimit(prevLimit => prevLimit + 25); + }; + return ( <>
- {events.length === 0 ? ( + {events.length === 0 && isLoading ? ( <> -
- -
- - +
+
-
-
- -
- - +
+
-
-
- -
- - +
+ +
+
+ +
+
+ +
+
+
-
- ) : (events.map((event) => ( - - )))} + ) : ( + events.map((event) => ( + + )) + )}
+ {!isLoading && ( +
+ +
+ )} ); } diff --git a/lumina/components/GlobalFeed.tsx b/lumina/components/GlobalFeed.tsx index b969415..99ea636 100644 --- a/lumina/components/GlobalFeed.tsx +++ b/lumina/components/GlobalFeed.tsx @@ -1,16 +1,24 @@ import { useNostrEvents } from "nostr-react"; import KIND20Card from "./KIND20Card"; import { getImageUrl } from "@/utils/utils"; -import QuickViewKind20NoteCard from "./QuickViewKind20NoteCard"; +import { useState, useRef } from "react"; +import { Button } from "@/components/ui/button"; const GlobalFeed: React.FC = () => { - const { events } = useNostrEvents({ + const now = useRef(new Date()); + const [limit, setLimit] = useState(20); + + const { events, isLoading } = useNostrEvents({ filter: { - limit: 20, + limit: limit, kinds: [20], }, }); + const loadMore = () => { + setLimit(prevLimit => prevLimit + 20); + }; + return ( <>

Global Feed

@@ -29,20 +37,15 @@ const GlobalFeed: React.FC = () => { event={event} showViewNoteCardButton={true} /> - {/* */}
); })}
+ {!isLoading && ( +
+ +
+ )} ); } diff --git a/lumina/components/ProfileFeed.tsx b/lumina/components/ProfileFeed.tsx index e672f63..a790e81 100644 --- a/lumina/components/ProfileFeed.tsx +++ b/lumina/components/ProfileFeed.tsx @@ -1,7 +1,8 @@ -import { useRef } from "react"; +import { useRef, useState } from "react"; import { useNostrEvents, dateToUnix } from "nostr-react"; import NoteCard from '@/components/NoteCard'; import { Skeleton } from "@/components/ui/skeleton"; +import { Button } from "@/components/ui/button"; import KIND20Card from "./KIND20Card"; import { getImageUrl } from "@/utils/utils"; @@ -10,23 +11,24 @@ interface ProfileFeedProps { } const ProfileFeed: React.FC = ({ pubkey }) => { - const now = useRef(new Date()); // Make sure current time isn't re-rendered + const now = useRef(new Date()); + const [limit, setLimit] = useState(10); - const { events } = useNostrEvents({ + const { events, isLoading } = useNostrEvents({ filter: { - // since: dateToUnix(now.current), // all new events from now authors: [pubkey], - // since: 0, - // limit: 10, kinds: [20], + limit: limit, }, }); + const loadMore = () => { + setLimit(prevLimit => prevLimit + 10); + }; + return ( <> - {/*

Profile Feed

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

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

- // -
- -
- )))} + ) : ( + <> + {events.map((event) => ( +
+ +
+ ))} + {!isLoading && ( +
+ +
+ )} + + )} ); } diff --git a/lumina/components/ProfileQuickViewFeed.tsx b/lumina/components/ProfileQuickViewFeed.tsx index e8d1285..e76d706 100644 --- a/lumina/components/ProfileQuickViewFeed.tsx +++ b/lumina/components/ProfileQuickViewFeed.tsx @@ -11,7 +11,7 @@ interface ProfileQuickViewFeedProps { const ProfileQuickViewFeed: React.FC = ({ pubkey }) => { const now = useRef(new Date()); // Make sure current time isn't re-rendered - const [limit, setLimit] = useState(100); + const [limit, setLimit] = useState(20); const { isLoading, events } = useNostrEvents({ filter: { diff --git a/lumina/components/ProfileTextFeed.tsx b/lumina/components/ProfileTextFeed.tsx index ce93408..347bc7c 100644 --- a/lumina/components/ProfileTextFeed.tsx +++ b/lumina/components/ProfileTextFeed.tsx @@ -1,22 +1,22 @@ -import { useRef } from "react"; +import { useRef, useState } from "react"; import { useNostrEvents, dateToUnix } from "nostr-react"; import NoteCard from '@/components/NoteCard'; import { Skeleton } from "@/components/ui/skeleton"; +import { Button } from "@/components/ui/button"; interface ProfileTextFeedProps { pubkey: string; } const ProfileTextFeed: React.FC = ({ pubkey }) => { - const now = useRef(new Date()); // Make sure current time isn't re-rendered + const now = useRef(new Date()); + const [limit, setLimit] = useState(10); const { events, isLoading } = useNostrEvents({ filter: { - // since: dateToUnix(now.current), // all new events from now authors: [pubkey], - // since: 0, - // limit: 10, kinds: [1], + limit: limit, }, }); @@ -25,10 +25,12 @@ const ProfileTextFeed: React.FC = ({ pubkey }) => { // filter out all replies (tag[0] == e) filteredEvents = filteredEvents.filter((event) => !event.tags.some((tag) => { return tag[0] == 'e' })); + const loadMore = () => { + setLimit(prevLimit => prevLimit + 10); + }; + return ( <> - {/*

Profile Feed

*/} - {filteredEvents.length === 0 && isLoading ? (
@@ -37,13 +39,28 @@ const ProfileTextFeed: React.FC = ({ pubkey }) => {
- ) : (filteredEvents.map((event) => ( - //

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

- // -
- -
- )))} + ) : ( + <> + {filteredEvents.map((event) => ( +
+ +
+ ))} + {!isLoading && filteredEvents.length > 0 && ( +
+ +
+ )} + + )} ); }