From 9757983046b1e77df876a5854ca3b7aa013807c6 Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Mon, 7 Mar 2022 20:11:58 -0500 Subject: [PATCH] Prep for infinite scroll --- web/src/app/SubscriptionManager.js | 14 +++++++++++--- web/src/components/Navigation.js | 15 ++++++++++----- web/src/components/Notifications.js | 7 +++---- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/web/src/app/SubscriptionManager.js b/web/src/app/SubscriptionManager.js index 70a7e18b..bbaede28 100644 --- a/web/src/app/SubscriptionManager.js +++ b/web/src/app/SubscriptionManager.js @@ -35,11 +35,19 @@ class SubscriptionManager { return db.subscriptions.toCollection().first(); // May be undefined } - async getNotifications(subscriptionId) { + async getNotifications(subscriptionId, offset) { + // 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 + + const pageSize = 20; return db.notifications - .where({ subscriptionId: subscriptionId }) + .orderBy("time") // Sort by time first + .filter(n => n.subscriptionId === subscriptionId) + .offset(offset) + .limit(pageSize) .reverse() - .sortBy("time"); // Inefficient, but there is no other way (see docs) + .toArray(); } async getAllNotifications() { diff --git a/web/src/components/Navigation.js b/web/src/components/Navigation.js index f2875d64..6786e663 100644 --- a/web/src/components/Navigation.js +++ b/web/src/components/Navigation.js @@ -9,7 +9,6 @@ import Toolbar from "@mui/material/Toolbar"; import Divider from "@mui/material/Divider"; import List from "@mui/material/List"; import SettingsIcon from "@mui/icons-material/Settings"; -import HomeIcon from '@mui/icons-material/Home'; import AddIcon from "@mui/icons-material/Add"; import SubscribeDialog from "./SubscribeDialog"; import {Alert, AlertTitle, Badge, CircularProgress, ListSubheader} from "@mui/material"; @@ -19,6 +18,7 @@ import {subscriptionRoute, topicShortUrl, topicUrl} from "../app/utils"; import {ConnectionState} from "../app/Connection"; import {useLocation, useNavigate} from "react-router-dom"; import subscriptionManager from "../app/SubscriptionManager"; +import {ChatBubble} from "@mui/icons-material"; const navWidth = 240; @@ -81,19 +81,24 @@ const NavList = (props) => { {showGrantPermissionsBox && } + {!showSubscriptionsList && + navigate("/")} selected={location.pathname === "/"}> + + + } {showSubscriptionsList && <> Subscribed topics + navigate("/")} selected={location.pathname === "/"}> + + + } - navigate("/")} selected={location.pathname === "/"}> - - - navigate("/settings")} selected={location.pathname === "/settings"}> diff --git a/web/src/components/Notifications.js b/web/src/components/Notifications.js index 68680fa9..03946721 100644 --- a/web/src/components/Notifications.js +++ b/web/src/components/Notifications.js @@ -40,19 +40,18 @@ const AllSubscriptions = () => { const SingleSubscription = (props) => { const subscription = props.subscription; - const notifications = useLiveQuery(() => subscriptionManager.getNotifications(subscription.id), [subscription]); + const [offset, setOffset] = useState(0); + const notifications = useLiveQuery(() => subscriptionManager.getNotifications(subscription.id, offset), [subscription, offset]); if (notifications === null || notifications === undefined) { return ; } else if (notifications.length === 0) { return ; } - return ; + return setOffset(prev => prev + 20)}/>; } const NotificationList = (props) => { const sortedNotifications = props.notifications; - /*const sortedNotifications = Array.from(props.notifications) - .sort((a, b) => a.time < b.time ? 1 : -1);*/ return (