From ce5fbf081933476308ee6bcc7f4dde719c068822 Mon Sep 17 00:00:00 2001 From: Martti Malmi Date: Fri, 16 Feb 2024 13:17:05 +0200 Subject: [PATCH] don't reload for you feed on refresh --- packages/app/src/Components/Feed/Timeline.tsx | 13 +++++++---- .../src/Components/Feed/TimelineFollows.tsx | 4 +++- packages/app/src/Components/ScrollToTop.tsx | 2 +- packages/app/src/Pages/Root/ForYouTab.tsx | 23 ++++++++++++++----- 4 files changed, 29 insertions(+), 13 deletions(-) diff --git a/packages/app/src/Components/Feed/Timeline.tsx b/packages/app/src/Components/Feed/Timeline.tsx index 3f7e7aea..3b75acbd 100644 --- a/packages/app/src/Components/Feed/Timeline.tsx +++ b/packages/app/src/Components/Feed/Timeline.tsx @@ -6,6 +6,7 @@ import { useCallback, useMemo, useState } from "react"; import { DisplayAs, DisplayAsSelector } from "@/Components/Feed/DisplayAsSelector"; import { TimelineRenderer } from "@/Components/Feed/TimelineRenderer"; import useTimelineFeed, { TimelineFeed, TimelineSubject } from "@/Feed/TimelineFeed"; +import useHistoryState from "@/Hooks/useHistoryState"; import useLogin from "@/Hooks/useLogin"; import { dedupeByPubkey } from "@/Utils"; @@ -27,13 +28,15 @@ export interface TimelineProps { */ const Timeline = (props: TimelineProps) => { const login = useLogin(); - const feedOptions = useMemo(() => { - return { + const [openedAt] = useHistoryState(Math.floor(Date.now() / 1000), "openedAt"); + const feedOptions = useMemo( + () => ({ method: props.method, window: props.window, - now: props.now, - }; - }, [props]); + now: props.now ?? openedAt, + }), + [props], + ); const feed: TimelineFeed = useTimelineFeed(props.subject, feedOptions); const displayAsInitial = props.displayAs ?? login.feedDisplayAs ?? "list"; const [displayAs, setDisplayAs] = useState(displayAsInitial); diff --git a/packages/app/src/Components/Feed/TimelineFollows.tsx b/packages/app/src/Components/Feed/TimelineFollows.tsx index 71a76839..d336fd02 100644 --- a/packages/app/src/Components/Feed/TimelineFollows.tsx +++ b/packages/app/src/Components/Feed/TimelineFollows.tsx @@ -7,6 +7,7 @@ import { Link } from "react-router-dom"; import { DisplayAs, DisplayAsSelector } from "@/Components/Feed/DisplayAsSelector"; import { TimelineRenderer } from "@/Components/Feed/TimelineRenderer"; import useTimelineFeed, { TimelineFeedOptions, TimelineSubject } from "@/Feed/TimelineFeed"; +import useHistoryState from "@/Hooks/useHistoryState"; import useLogin from "@/Hooks/useLogin"; import { dedupeByPubkey } from "@/Utils"; @@ -27,6 +28,7 @@ const TimelineFollows = (props: TimelineFollowsProps) => { const login = useLogin(); const displayAsInitial = props.displayAs ?? login.feedDisplayAs ?? "list"; const [displayAs, setDisplayAs] = useState(displayAsInitial); + const [openedAt] = useHistoryState(Math.floor(Date.now() / 1000), "openedAt"); const subject = useMemo( () => ({ @@ -41,7 +43,7 @@ const TimelineFollows = (props: TimelineFollowsProps) => { }) as TimelineSubject, [login.follows.item, login.tags.item], ); - const feed = useTimelineFeed(subject, { method: "TIME_RANGE" } as TimelineFeedOptions); + const feed = useTimelineFeed(subject, { method: "TIME_RANGE", now: openedAt } as TimelineFeedOptions); // TODO allow reposts: const postsOnly = useCallback( diff --git a/packages/app/src/Components/ScrollToTop.tsx b/packages/app/src/Components/ScrollToTop.tsx index b1fed339..c42b31fe 100644 --- a/packages/app/src/Components/ScrollToTop.tsx +++ b/packages/app/src/Components/ScrollToTop.tsx @@ -3,7 +3,7 @@ import { useLocation, useNavigationType } from "react-router-dom"; export default function ScrollToTop() { const { pathname } = useLocation(); - const navigationType = useNavigationType(); // This hook is available in React Router v6 + const navigationType = useNavigationType(); useEffect(() => { if (navigationType !== "POP") { diff --git a/packages/app/src/Pages/Root/ForYouTab.tsx b/packages/app/src/Pages/Root/ForYouTab.tsx index 7c1b4e5e..2c9ba7c5 100644 --- a/packages/app/src/Pages/Root/ForYouTab.tsx +++ b/packages/app/src/Pages/Root/ForYouTab.tsx @@ -1,13 +1,14 @@ import { EventKind, NostrEvent, RequestBuilder, TaggedNostrEvent } from "@snort/system"; import { memo, useEffect, useMemo, useState } from "react"; import { FormattedMessage } from "react-intl"; -import { Link } from "react-router-dom"; +import { Link, useNavigationType } from "react-router-dom"; import { Relay } from "@/Cache"; import { DisplayAs, DisplayAsSelector } from "@/Components/Feed/DisplayAsSelector"; import { TimelineRenderer } from "@/Components/Feed/TimelineRenderer"; import { TaskList } from "@/Components/Tasks/TaskList"; import useTimelineFeed, { TimelineFeedOptions, TimelineSubject } from "@/Feed/TimelineFeed"; +import useHistoryState from "@/Hooks/useHistoryState"; import useLogin from "@/Hooks/useLogin"; import messages from "@/Pages/messages"; import { System } from "@/system"; @@ -64,9 +65,12 @@ export const ForYouTab = memo(function ForYouTab() { const displayAsInitial = feedDisplayAs ?? "list"; const [displayAs, setDisplayAs] = useState(displayAsInitial); const { publicKey } = useLogin(); + const navigationType = useNavigationType(); + const [openedAt] = useHistoryState(Math.floor(Date.now() / 1000), "openedAt"); if (!reactionsRequested && publicKey) { reactionsRequested = true; + // on first load, ask relays for reactions to events by follows getReactedByFollows(follows.item); } @@ -86,11 +90,15 @@ export const ForYouTab = memo(function ForYouTab() { [login.follows.item, login.tags.item], ); // also get "follows" feed so data is loaded from relays and there's a fallback if "for you" feed is empty - const latestFeed = useTimelineFeed(subject, { method: "TIME_RANGE" } as TimelineFeedOptions); + const latestFeed = useTimelineFeed(subject, { method: "TIME_RANGE", now: openedAt } as TimelineFeedOptions); const filteredLatestFeed = useMemo(() => { - // no replies - return latestFeed.main?.filter((ev: NostrEvent) => !ev.tags.some((tag: string[]) => tag[0] === "e")) ?? []; - }, [latestFeed.main]); + return ( + latestFeed.main?.filter((ev: NostrEvent) => { + // no replies + return !ev.tags.some((tag: string[]) => tag[0] === "e"); + }) ?? [] + ); + }, [latestFeed.main, subject]); const getFeed = () => { if (!publicKey) { @@ -115,7 +123,10 @@ export const ForYouTab = memo(function ForYouTab() { }; useEffect(() => { - if (forYouFeed.events.length < 10 || Date.now() - forYouFeed.created_at > 1000 * 60 * 2) { + if ( + forYouFeed.events.length < 10 || + (navigationType !== "POP" && Date.now() - forYouFeed.created_at > 1000 * 60 * 2) + ) { getFeed(); } }, []);