From bdaaf38fb3a9bc380931b964f68741ac2e2136a5 Mon Sep 17 00:00:00 2001 From: Tyler Yu Date: Tue, 8 Oct 2024 19:39:47 -0700 Subject: [PATCH 1/3] feat: clustering --- packages/web/package.json | 1 + packages/web/src/components/Home/Home.jsx | 3 +-- packages/web/src/components/Map/Map.jsx | 16 ++++++++------ pnpm-lock.yaml | 26 +++++++++++++++++++++++ 4 files changed, 38 insertions(+), 8 deletions(-) diff --git a/packages/web/package.json b/packages/web/package.json index 7084359..7c1ed13 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -26,6 +26,7 @@ "react-ga4": "^2.1.0", "react-icons": "^4.10.1", "react-leaflet": "^4.2.1", + "react-leaflet-cluster": "^2.1.0", "react-resizable": "^3.0.5", "react-resizable-panels": "^0.0.53", "react-router-dom": "^6.11.2", diff --git a/packages/web/src/components/Home/Home.jsx b/packages/web/src/components/Home/Home.jsx index c0b55e3..2e16a7b 100644 --- a/packages/web/src/components/Home/Home.jsx +++ b/packages/web/src/components/Home/Home.jsx @@ -726,8 +726,7 @@ export default function Home() { left={10} bottom={10} > - - + 0 ? results : data; - const allMarkers = markersData.filter(filterItemCallback).map((item) => { - return ( + const allMarkers = useMemo(() => { + return markersData.filter(filterItemCallback).map((item) => ( - ); - }); + )); + }, [markersData, filterItemCallback, onOpen, setItemData, setFocusLocation]); // moves map when focusLocation state changes function MapFocusLocation({ location }) { @@ -353,8 +354,11 @@ export default function Map({ {!isEdit && ( )} - {!isEdit} - {!isEdit && allMarkers} + {!isEdit && ( + + {allMarkers} + + )} {isEdit && } {showDonut && focusLocation && ( diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6148c5a..21527e1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -164,6 +164,9 @@ importers: react-leaflet: specifier: ^4.2.1 version: 4.2.1(leaflet@1.9.4)(react-dom@18.2.0)(react@18.2.0) + react-leaflet-cluster: + specifier: ^2.1.0 + version: 2.1.0(leaflet@1.9.4)(react-dom@18.2.0)(react-leaflet@4.2.1)(react@18.2.0) react-resizable: specifier: ^3.0.5 version: 3.0.5(react-dom@18.2.0)(react@18.2.0) @@ -9441,6 +9444,14 @@ packages: readable-stream: 2.3.8 dev: true + /leaflet.markercluster@1.5.3(leaflet@1.9.4): + resolution: {integrity: sha512-vPTw/Bndq7eQHjLBVlWpnGeLa3t+3zGiuM7fJwCkiMFq+nmRuG3RI3f7f4N4TDX7T4NpbAXpR2+NTRSEGfCSeA==} + peerDependencies: + leaflet: ^1.3.1 + dependencies: + leaflet: 1.9.4 + dev: false + /leaflet@1.9.4: resolution: {integrity: sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==} dev: false @@ -10559,6 +10570,21 @@ packages: /react-is@18.3.1: resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + /react-leaflet-cluster@2.1.0(leaflet@1.9.4)(react-dom@18.2.0)(react-leaflet@4.2.1)(react@18.2.0): + resolution: {integrity: sha512-16X7XQpRThQFC4PH4OpXHimGg19ouWmjxjtpxOeBKpvERSvIRqTx7fvhTwkEPNMFTQ8zTfddz6fRTUmUEQul7g==} + peerDependencies: + leaflet: ^1.8.0 + react: ^18.0.0 + react-dom: ^18.0.0 + react-leaflet: ^4.0.0 + dependencies: + leaflet: 1.9.4 + leaflet.markercluster: 1.5.3(leaflet@1.9.4) + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-leaflet: 4.2.1(leaflet@1.9.4)(react-dom@18.2.0)(react@18.2.0) + dev: false + /react-leaflet@4.2.1(leaflet@1.9.4)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-p9chkvhcKrWn/H/1FFeVSqLdReGwn2qmiobOQGO3BifX+/vV/39qhY8dGqbdcPh1e6jxh/QHriLXr7a4eLFK4Q==} peerDependencies: From 9f46aa93dd996cf074da86cfa55128c5410ab9ba Mon Sep 17 00:00:00 2001 From: Tyler Yu Date: Tue, 8 Oct 2024 20:09:37 -0700 Subject: [PATCH 2/3] feat: mobile view notch fix --- packages/web/src/components/Home/Home.jsx | 4 ++-- packages/web/src/components/Login/Login.jsx | 4 ++-- packages/web/src/components/Map/Map.css | 4 ++-- packages/web/src/components/ResultsBar/ResultsBar.jsx | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/web/src/components/Home/Home.jsx b/packages/web/src/components/Home/Home.jsx index c0b55e3..026bf4d 100644 --- a/packages/web/src/components/Home/Home.jsx +++ b/packages/web/src/components/Home/Home.jsx @@ -330,7 +330,7 @@ export default function Home() { > ); -} +} \ No newline at end of file diff --git a/packages/web/src/components/Login/Login.jsx b/packages/web/src/components/Login/Login.jsx index 7638b6a..a55c92b 100644 --- a/packages/web/src/components/Login/Login.jsx +++ b/packages/web/src/components/Login/Login.jsx @@ -19,7 +19,7 @@ export default function Login() { return ( @@ -47,7 +47,7 @@ export default function Login() { {"Login From befd2e26643d0b8eba4dc17a00d7a3858e63dbb2 Mon Sep 17 00:00:00 2001 From: Tyler Yu Date: Thu, 10 Oct 2024 18:14:52 -0700 Subject: [PATCH 3/3] feat: autoscroll --- .../src/components/ResultsBar/ResultsBar.jsx | 33 +++++++++++++++---- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/packages/web/src/components/ResultsBar/ResultsBar.jsx b/packages/web/src/components/ResultsBar/ResultsBar.jsx index 23ba064..5a67dcf 100644 --- a/packages/web/src/components/ResultsBar/ResultsBar.jsx +++ b/packages/web/src/components/ResultsBar/ResultsBar.jsx @@ -1,4 +1,4 @@ -import { useContext, useCallback, useState } from "react"; +import { useContext, useCallback, useState, useEffect, useRef } from "react"; import "./ResultsBar.css"; import ResultCard from "../ResultCard/ResultCard"; import { Box, Flex, Text, Button } from "@chakra-ui/react"; @@ -19,6 +19,8 @@ export default function ResultsBar({ const { user } = UserAuth(); const [itemsonScreenLimit, setItemsOnScreenLimit] = useState(10); + const [isAutoScrolling, setIsAutoScrolling] = useState(true); + const resultsBarRef = useRef(null); const filterItemCallback = useCallback( (item) => filterItem(item, findFilter, user), @@ -60,7 +62,6 @@ export default function ResultsBar({ ? data.filter(filterItemCallback).map(mapItem) : results.filter(filterItemCallback).map(mapItem); - // Callback function that increases the number of items displayed on the screen by 10 const handleLoadMore = useCallback(() => { setItemsOnScreenLimit(itemsonScreenLimit + 10); }, [itemsonScreenLimit]); @@ -80,15 +81,11 @@ export default function ResultsBar({ ); - // Retrieve all items that meet the filter criteria - - // Display only the first 10 items on the screen, all items if there are less than 10 items left to be loaded const viewableResults = allResults.slice( 0, Math.min(itemsonScreenLimit, allResults.length) ); - // Define JSX for empty results bar (no result cards) const noResults = ( @@ -97,6 +94,24 @@ export default function ResultsBar({ ); + useEffect(() => { + let scrollInterval; + if (isAutoScrolling && resultsBarRef.current) { + scrollInterval = setInterval(() => { + if (resultsBarRef.current.scrollTop + resultsBarRef.current.clientHeight < resultsBarRef.current.scrollHeight) { + resultsBarRef.current.scrollTop += 1; + } else { + resultsBarRef.current.scrollTop = 0; + } + }, 50); + } + return () => clearInterval(scrollInterval); + }, [isAutoScrolling]); + + const handleUserInteraction = () => { + setIsAutoScrolling(false); + }; + return ( {allResults.length > 0 ? viewableResults : noResults} {viewableResults.length < allResults.length && loadMoreButton} ); -} +} \ No newline at end of file