From 30b13cbdbc639b4b7ef0f78a4b89301543bffa08 Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Tue, 8 Mar 2022 11:21:11 -0500 Subject: [PATCH] Working infinite scroll --- web/src/app/SubscriptionManager.js | 6 +----- web/src/components/Notifications.js | 32 +++++++++++++++++------------ 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/web/src/app/SubscriptionManager.js b/web/src/app/SubscriptionManager.js index fb9f3d3..4a9d343 100644 --- a/web/src/app/SubscriptionManager.js +++ b/web/src/app/SubscriptionManager.js @@ -35,18 +35,14 @@ class SubscriptionManager { return db.subscriptions.toCollection().first(); // May be undefined } - async getNotifications(subscriptionId, offset) { + async getNotifications(subscriptionId) { // This is quite awkward, but it is the recommended approach as per the Dexie docs. // It's actually fine, because the reading and filtering is quite fast. The rendering is what's // killing performance. See https://dexie.org/docs/Collection/Collection.offset()#a-better-paging-approach - console.log(`getNotifications(${subscriptionId}, ${offset})`) - const pageSize = 2000; return db.notifications .orderBy("time") // Sort by time first .filter(n => n.subscriptionId === subscriptionId) - .offset(offset) - .limit(pageSize) .reverse() .toArray(); } diff --git a/web/src/components/Notifications.js b/web/src/components/Notifications.js index 3d92f80..6be4431 100644 --- a/web/src/components/Notifications.js +++ b/web/src/components/Notifications.js @@ -3,7 +3,7 @@ import {ButtonBase, CardActions, CardContent, CircularProgress, Fade, Link, Moda import Card from "@mui/material/Card"; import Typography from "@mui/material/Typography"; import * as React from "react"; -import {useState} from "react"; +import {useEffect, useState} from "react"; import { formatBytes, formatMessage, @@ -36,37 +36,43 @@ const AllSubscriptions = () => { } else if (notifications.length === 0) { return ; } - return ; + return ; } const SingleSubscription = (props) => { const subscription = props.subscription; - const [offset, setOffset] = useState(0); - const notifications = useLiveQuery(() => subscriptionManager.getNotifications(subscription.id, offset), [subscription, offset]); + const notifications = useLiveQuery(() => subscriptionManager.getNotifications(subscription.id), [subscription]); if (notifications === null || notifications === undefined) { return ; } else if (notifications.length === 0) { return ; } - return { - console.log(`setOffset`) - setOffset(prev => prev + 20) - }}/>; + return ; } const NotificationList = (props) => { - const notifications = props.notifications; const pageSize = 20; - const [count, setCount] = useState(Math.min(notifications.length, pageSize)); + const notifications = props.notifications; + const [maxCount, setMaxCount] = useState(pageSize); + + // Reset state when the list identifier changes, i.e when we switch between subscriptions + useEffect(() => { + return () => { + setMaxCount(pageSize); + document.getElementById("main").scrollTo(0, 0); + } + }, [props.id]); + + const count = Math.min(notifications.length, maxCount); + console.log(`xxx id=${props.id} scrollMax=${maxCount} count=${count} len=${notifications.length}`) - console.log(`count ${count}`) return ( setCount(prev => Math.min(notifications.length, prev + 20))} + next={() => setMaxCount(prev => prev + pageSize)} hasMore={count < notifications.length} loader={

aa

} - scrollThreshold="400px" + scrollThreshold={0.7} scrollableTarget="main" >