diff --git a/packages/app/src/Components/Event/LoadMore.tsx b/packages/app/src/Components/Event/LoadMore.tsx new file mode 100644 index 00000000..efaf1586 --- /dev/null +++ b/packages/app/src/Components/Event/LoadMore.tsx @@ -0,0 +1,35 @@ +import { useEffect } from "react"; +import { useInView } from "react-intersection-observer"; +import { FormattedMessage } from "react-intl"; + +interface ShowMoreProps { + text?: string; + className?: string; + onClick: () => void; +} + +const LoadMore = ({ text, onClick, className = "" }: ShowMoreProps) => { + return ( + + ); +}; + +export default LoadMore; + +export function AutoLoadMore({ text, onClick, className }: ShowMoreProps) { + const { ref, inView } = useInView({ rootMargin: "2000px" }); + + useEffect(() => { + if (inView) { + onClick(); + } + }, [inView]); + + return ( +
+ +
+ ); +} diff --git a/packages/app/src/Components/Event/ShowMore.tsx b/packages/app/src/Components/Event/ShowMore.tsx deleted file mode 100644 index 7d82927b..00000000 --- a/packages/app/src/Components/Event/ShowMore.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import classNames from "classnames"; -import { useEffect } from "react"; -import { useInView } from "react-intersection-observer"; -import { FormattedMessage } from "react-intl"; - -interface ShowMoreProps { - text?: string; - className?: string; - onClick: () => void; -} - -const ShowMore = ({ text, onClick, className = "" }: ShowMoreProps) => { - return ( -
- -
- ); -}; - -export default ShowMore; - -export function AutoShowMore({ text, onClick, className }: ShowMoreProps) { - const { ref, inView } = useInView({ rootMargin: "2000px" }); - - useEffect(() => { - if (inView) { - onClick(); - } - }, [inView]); - - return ( -
- -
- ); -} diff --git a/packages/app/src/Components/Event/Thread.css b/packages/app/src/Components/Event/Thread.css index e3259604..52d8df8d 100644 --- a/packages/app/src/Components/Event/Thread.css +++ b/packages/app/src/Components/Event/Thread.css @@ -31,16 +31,6 @@ border-radius: 0; } -.thread-container .show-more { - background: var(--gray-superdark); - padding-left: 76px; - width: 100%; - text-align: left; - border-radius: 0; - padding-top: 10px; - padding-bottom: 10px; -} - .subthread-container { position: relative; } diff --git a/packages/app/src/Components/Feed/Timeline.tsx b/packages/app/src/Components/Feed/Timeline.tsx index 737bf142..3f7e7aea 100644 --- a/packages/app/src/Components/Feed/Timeline.tsx +++ b/packages/app/src/Components/Feed/Timeline.tsx @@ -2,7 +2,6 @@ import "./Timeline.css"; import { socialGraphInstance, TaggedNostrEvent } from "@snort/system"; import { useCallback, useMemo, useState } from "react"; -import { FormattedMessage } from "react-intl"; import { DisplayAs, DisplayAsSelector } from "@/Components/Feed/DisplayAsSelector"; import { TimelineRenderer } from "@/Components/Feed/TimelineRenderer"; @@ -18,7 +17,6 @@ export interface TimelineProps { ignoreModeration?: boolean; window?: number; now?: number; - loadMore?: boolean; noSort?: boolean; displayAs?: DisplayAs; showDisplayAsSelector?: boolean; @@ -91,14 +89,8 @@ const Timeline = (props: TimelineProps) => { latest={latestAuthors} showLatest={t => onShowLatest(t)} displayAs={displayAs} + loadMore={() => feed.loadMore()} /> - {(props.loadMore === undefined || props.loadMore === true) && ( -
- -
- )} ); }; diff --git a/packages/app/src/Components/Feed/TimelineFollows.tsx b/packages/app/src/Components/Feed/TimelineFollows.tsx index 3ac7e5f3..1109fe17 100644 --- a/packages/app/src/Components/Feed/TimelineFollows.tsx +++ b/packages/app/src/Components/Feed/TimelineFollows.tsx @@ -4,7 +4,6 @@ import { EventKind, NostrEvent, TaggedNostrEvent } from "@snort/system"; import { ReactNode, useCallback, useMemo, useState } from "react"; import { Link } from "react-router-dom"; -import { AutoShowMore } from "@/Components/Event/ShowMore"; import { DisplayAs, DisplayAsSelector } from "@/Components/Feed/DisplayAsSelector"; import { TimelineRenderer } from "@/Components/Feed/TimelineRenderer"; import useTimelineFeed, { TimelineFeedOptions, TimelineSubject } from "@/Feed/TimelineFeed"; @@ -98,15 +97,8 @@ const TimelineFollows = (props: TimelineFollowsProps) => { } }} displayAs={displayAs} + loadMore={() => feed.loadMore()} /> - {mainFeed.length > 0 && ( - { - feed.loadMore(); - }} - className="mx-3 my-4" - /> - )} ); }; diff --git a/packages/app/src/Components/Feed/TimelineRenderer.tsx b/packages/app/src/Components/Feed/TimelineRenderer.tsx index 0ea214dd..8e3a5cfb 100644 --- a/packages/app/src/Components/Feed/TimelineRenderer.tsx +++ b/packages/app/src/Components/Feed/TimelineRenderer.tsx @@ -4,6 +4,7 @@ import { useInView } from "react-intersection-observer"; import { FormattedMessage } from "react-intl"; import ErrorBoundary from "@/Components/ErrorBoundary"; +import { AutoLoadMore } from "@/Components/Event/LoadMore"; import { DisplayAs } from "@/Components/Feed/DisplayAsSelector"; import ImageGridItem from "@/Components/Feed/ImageGridItem"; import { TimelineFragment } from "@/Components/Feed/TimelineFragment"; @@ -23,6 +24,7 @@ export interface TimelineRendererProps { noteOnClick?: (ev: TaggedNostrEvent) => void; noteContext?: (ev: TaggedNostrEvent) => ReactNode; displayAs?: DisplayAs; + loadMore?: () => void; } // filter frags[0].events that have media @@ -151,6 +153,7 @@ export function TimelineRenderer(props: TimelineRendererProps) { )} {props.displayAs === "grid" ? : renderNotes()} + {props.loadMore && } ); } diff --git a/packages/app/src/Hooks/usePageDimensions.tsx b/packages/app/src/Hooks/usePageDimensions.tsx new file mode 100644 index 00000000..1d6df19e --- /dev/null +++ b/packages/app/src/Hooks/usePageDimensions.tsx @@ -0,0 +1,26 @@ +import { useEffect, useRef, useState } from "react"; + +export default function usePageDimensions() { + const ref = useRef(document.querySelector("#root")); + const [dimensions, setDimensions] = useState({ + width: ref.current?.clientWidth ?? 0, + height: ref.current?.clientHeight ?? 0, + }); + + useEffect(() => { + if (ref.current && "ResizeObserver" in window) { + const observer = new ResizeObserver(entries => { + if (entries[0].target === ref.current) { + const { width, height } = entries[0].contentRect; + setDimensions({ width, height }); + } + }); + + observer.observe(ref.current); + + return () => observer.disconnect(); + } + }, [ref]); + + return dimensions; +} diff --git a/packages/app/src/Hooks/usePageWidth.tsx b/packages/app/src/Hooks/usePageWidth.tsx deleted file mode 100644 index 0dd2d3ff..00000000 --- a/packages/app/src/Hooks/usePageWidth.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import { useEffect, useRef, useState } from "react"; - -export default function usePageWidth() { - const ref = useRef(document.querySelector("#root")); - const [width, setWidth] = useState(0); - - useEffect(() => { - const updateSize = () => { - if (ref.current) { - setWidth(ref.current.offsetWidth); - } - }; - - window.addEventListener("resize", updateSize); - updateSize(); - return () => window.removeEventListener("resize", updateSize); - }, [ref]); - - return width; -} diff --git a/packages/app/src/Pages/Messages/MessagesPage.tsx b/packages/app/src/Pages/Messages/MessagesPage.tsx index 34bc0abe..6180fabd 100644 --- a/packages/app/src/Pages/Messages/MessagesPage.tsx +++ b/packages/app/src/Pages/Messages/MessagesPage.tsx @@ -8,7 +8,7 @@ import NoteTime from "@/Components/Event/Note/NoteTime"; import NoteToSelf from "@/Components/User/NoteToSelf"; import ProfileImage from "@/Components/User/ProfileImage"; import useLogin from "@/Hooks/useLogin"; -import usePageWidth from "@/Hooks/usePageWidth"; +import usePageDimensions from "@/Hooks/usePageDimensions"; import { ChatParticipantProfile } from "@/Pages/Messages/ChatParticipant"; import DmWindow from "@/Pages/Messages/DmWindow"; import NewChatWindow from "@/Pages/Messages/NewChatWindow"; @@ -21,7 +21,7 @@ export default function MessagesPage() { const { formatMessage } = useIntl(); const navigate = useNavigate(); const { id } = useParams(); - const pageWidth = usePageWidth(); + const { width: pageWidth } = usePageDimensions(); const chats = useChatSystems(); diff --git a/packages/app/src/Pages/Notifications/Notifications.tsx b/packages/app/src/Pages/Notifications/Notifications.tsx index 5e9212f9..5cb0806d 100644 --- a/packages/app/src/Pages/Notifications/Notifications.tsx +++ b/packages/app/src/Pages/Notifications/Notifications.tsx @@ -4,7 +4,7 @@ import { unwrap } from "@snort/shared"; import { NostrEvent, NostrLink, TaggedNostrEvent } from "@snort/system"; import { lazy, Suspense, useEffect, useMemo } from "react"; -import { AutoShowMore } from "@/Components/Event/ShowMore"; +import { AutoLoadMore } from "@/Components/Event/LoadMore"; import PageSpinner from "@/Components/PageSpinner"; import { useNotificationsView } from "@/Feed/WorkerRelayView"; import useLogin from "@/Hooks/useLogin"; @@ -63,7 +63,7 @@ export default function NotificationsPage({ onClick }: { onClick?: (link: NostrL {login.publicKey && [...timeGrouped.entries()].map(([k, g]) => )} - {}} /> + {}} /> ); diff --git a/packages/app/src/Pages/Profile/ProfileTabComponents.tsx b/packages/app/src/Pages/Profile/ProfileTabComponents.tsx index d54ae1ec..70b9a9a2 100644 --- a/packages/app/src/Pages/Profile/ProfileTabComponents.tsx +++ b/packages/app/src/Pages/Profile/ProfileTabComponents.tsx @@ -77,7 +77,6 @@ export function ProfileNotesTab({ id, relays, isMe }: { id: HexKey; relays?: Arr subject={subject} postsOnly={false} method={"LIMIT_UNTIL"} - loadMore={true} ignoreModeration={true} window={60 * 60 * 6} /> diff --git a/packages/app/src/Pages/TopicsPage.tsx b/packages/app/src/Pages/TopicsPage.tsx index 8c46d33a..1ef2e8d0 100644 --- a/packages/app/src/Pages/TopicsPage.tsx +++ b/packages/app/src/Pages/TopicsPage.tsx @@ -14,5 +14,5 @@ export function TopicsPage() { [tags, pubKey], ); - return ; + return ; } diff --git a/packages/app/src/lang.json b/packages/app/src/lang.json index 0592deb2..7320eb9d 100644 --- a/packages/app/src/lang.json +++ b/packages/app/src/lang.json @@ -773,9 +773,6 @@ "O3Jz4E": { "defaultMessage": "Use your invite code to earn sats!" }, - "O8Z8t9": { - "defaultMessage": "Show More" - }, "OEW7yJ": { "defaultMessage": "Zaps" }, diff --git a/packages/app/src/translations/en.json b/packages/app/src/translations/en.json index 713314e2..378fb520 100644 --- a/packages/app/src/translations/en.json +++ b/packages/app/src/translations/en.json @@ -255,7 +255,6 @@ "NepkXH": "Can't vote with {amount} sats, please set a different default zap amount", "NndBJE": "New users page", "O3Jz4E": "Use your invite code to earn sats!", - "O8Z8t9": "Show More", "OEW7yJ": "Zaps", "OKhRC6": "Share", "OLEm6z": "Unknown login error",