From c4406438fc50e18ea55d5e6f2985aea8334ef1c6 Mon Sep 17 00:00:00 2001 From: Louis Velez Date: Tue, 31 Dec 2024 18:33:42 -0500 Subject: [PATCH 1/2] Implement infinite scrolling and responsive grid layout for RouteList --- src/pages/dashboard/components/RouteList.tsx | 99 +++++++++++++------- 1 file changed, 63 insertions(+), 36 deletions(-) diff --git a/src/pages/dashboard/components/RouteList.tsx b/src/pages/dashboard/components/RouteList.tsx index 658e6af6..fd42fe13 100644 --- a/src/pages/dashboard/components/RouteList.tsx +++ b/src/pages/dashboard/components/RouteList.tsx @@ -5,19 +5,19 @@ import { createSignal, For, Suspense, + onCleanup, + onMount, + Index, + type VoidComponent, } from 'solid-js' -import type { VoidComponent } from 'solid-js' -import clsx from 'clsx' - +import { clsx } from 'clsx' import type { RouteSegments } from '~/types' - import RouteCard from '~/components/RouteCard' import { fetcher } from '~/api' -import Button from '~/components/material/Button' const PAGE_SIZE = 3 -type RouteListProps = { +interface RouteListProps { class?: string dongleId: string } @@ -52,39 +52,66 @@ const RouteList: VoidComponent = (props) => { }) const [size, setSize] = createSignal(1) - const onLoadMore = () => setSize(size() + 1) - const pageNumbers = () => Array.from(Array(size()).keys()) + const pageNumbers = () => Array.from({ length: size() }) + + const [sentinel, setSentinel] = createSignal() + let observer: IntersectionObserver | undefined + + onMount(() => { + observer = new IntersectionObserver( + (entries) => { + if (entries[0].isIntersecting) { + setSize((prev) => prev + 1) + } + }, + { threshold: 0.1 }, + ) + + const sentinelEl = sentinel() + if (sentinelEl) { + observer.observe(sentinelEl) + } + }) + + onCleanup(() => observer?.disconnect()) + + const LoadingSkeleton = () => ( +
+ + {() => ( +
+ )} + +
+ ) return ( -
- - {(i) => { - const [routes] = createResource(() => i, getPage) - return ( - -
-
-
- - } - > - - {(route) => } - - - ) - }} - -
- +
+
+ + {(_, i) => { + const [routes] = createResource(() => i(), getPage) + return ( + }> + + {(route) => ( +
+ +
+ )} +
+
+ ) + }} +
+
) } From 264ea45180a6653f7dc67af7f6b78680de7ea510 Mon Sep 17 00:00:00 2001 From: Louis Velez Date: Sun, 19 Jan 2025 00:40:43 -0500 Subject: [PATCH 2/2] fix for desktop browsers --- src/pages/dashboard/components/RouteList.tsx | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/pages/dashboard/components/RouteList.tsx b/src/pages/dashboard/components/RouteList.tsx index fd42fe13..99976abb 100644 --- a/src/pages/dashboard/components/RouteList.tsx +++ b/src/pages/dashboard/components/RouteList.tsx @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/no-misused-promises */ import { createEffect, createResource, @@ -33,13 +32,12 @@ const RouteList: VoidComponent = (props) => { return `${endpoint()}&end=${lastSegmentEndTime - 1}` } const getPage = (page: number): Promise => { - if (!pages[page]) { - // eslint-disable-next-line no-async-promise-executor - pages[page] = new Promise(async (resolve) => { + if (pages[page] === undefined) { + pages[page] = (async () => { const previousPageData = page > 0 ? await getPage(page - 1) : undefined const key = getKey(previousPageData) - resolve(key ? fetcher(key) : []) - }) + return key ? fetcher(key) : [] + })() } return pages[page] }