Prep for infinite scroll
parent
5bed926323
commit
9757983046
|
@ -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() {
|
||||
|
|
|
@ -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) => {
|
|||
<Toolbar sx={{ display: { xs: 'none', sm: 'block' } }}/>
|
||||
<List component="nav" sx={{ paddingTop: (showGrantPermissionsBox) ? '0' : '' }}>
|
||||
{showGrantPermissionsBox && <PermissionAlert onRequestPermissionClick={props.requestNotificationPermission}/>}
|
||||
{!showSubscriptionsList &&
|
||||
<ListItemButton onClick={() => navigate("/")} selected={location.pathname === "/"}>
|
||||
<ListItemIcon><ChatBubble/></ListItemIcon>
|
||||
<ListItemText primary="All notifications"/>
|
||||
</ListItemButton>}
|
||||
{showSubscriptionsList &&
|
||||
<>
|
||||
<ListSubheader>Subscribed topics</ListSubheader>
|
||||
<ListItemButton onClick={() => navigate("/")} selected={location.pathname === "/"}>
|
||||
<ListItemIcon><ChatBubble/></ListItemIcon>
|
||||
<ListItemText primary="All notifications"/>
|
||||
</ListItemButton>
|
||||
<SubscriptionList
|
||||
subscriptions={props.subscriptions}
|
||||
selectedSubscription={props.selectedSubscription}
|
||||
/>
|
||||
<Divider sx={{my: 1}}/>
|
||||
</>}
|
||||
<ListItemButton onClick={() => navigate("/")} selected={location.pathname === "/"}>
|
||||
<ListItemIcon><HomeIcon/></ListItemIcon>
|
||||
<ListItemText primary="Home"/>
|
||||
</ListItemButton>
|
||||
<ListItemButton onClick={() => navigate("/settings")} selected={location.pathname === "/settings"}>
|
||||
<ListItemIcon><SettingsIcon/></ListItemIcon>
|
||||
<ListItemText primary="Settings"/>
|
||||
|
|
|
@ -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 <Loading/>;
|
||||
} else if (notifications.length === 0) {
|
||||
return <NoNotifications subscription={subscription}/>;
|
||||
}
|
||||
return <NotificationList notifications={notifications}/>;
|
||||
return <NotificationList notifications={notifications} onScroll={() => 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 (
|
||||
<Container maxWidth="md" sx={{marginTop: 3, marginBottom: 3}}>
|
||||
<Stack spacing={3}>
|
||||
|
|
Loading…
Reference in New Issue