From deace43225351431f4abfd8a74bc269f27668ab3 Mon Sep 17 00:00:00 2001 From: Timothy Armes Date: Wed, 5 Jul 2023 13:36:12 +0200 Subject: [PATCH] Sync list to map (#42) --- .vscode/settings.json | 1 + app/[lang]/tournois/SearchBar.tsx | 2 +- app/[lang]/tournois/TournamentMap.tsx | 15 +++++++++++++-- app/[lang]/tournois/TournamentTable.tsx | 20 ++++++++++++++++---- app/atoms.ts | 16 ++++++++++++++-- messages/en.json | 1 + messages/fr.json | 1 + utils/atomWithDebounce.ts | 2 +- 8 files changed, 48 insertions(+), 10 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 02b2b65..f4fbe17 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -9,6 +9,7 @@ "Française", "Lente", "localisation", + "moveend", "randomisation", "Rapide", "Rees", diff --git a/app/[lang]/tournois/SearchBar.tsx b/app/[lang]/tournois/SearchBar.tsx index bec0624..8332ed9 100644 --- a/app/[lang]/tournois/SearchBar.tsx +++ b/app/[lang]/tournois/SearchBar.tsx @@ -8,7 +8,7 @@ const SearchBar = () => { const [searchString, setSearchString] = useAtom(searchStringAtom); return ( -
+
diff --git a/app/[lang]/tournois/TournamentMap.tsx b/app/[lang]/tournois/TournamentMap.tsx index f875d6e..1a5f1a1 100644 --- a/app/[lang]/tournois/TournamentMap.tsx +++ b/app/[lang]/tournois/TournamentMap.tsx @@ -7,18 +7,28 @@ import { TileLayer, LayersControl, LayerGroup, + useMapEvent, } from "react-leaflet"; -import { useAtomValue } from "jotai"; +import { useAtomValue, useSetAtom } from "jotai"; import "leaflet/dist/leaflet.css"; import "leaflet-defaulticon-compatibility/dist/leaflet-defaulticon-compatibility.css"; import "leaflet-defaulticon-compatibility"; -import { tournamentsAtom } from "@/app/atoms"; +import { tournamentsAtom, mapBoundsAtom } from "@/app/atoms"; import Legend from "./Legend"; import { TournamentMarker } from "./TournamentMarker"; +const MapEvents = () => { + const setMapBounds = useSetAtom(mapBoundsAtom); + const map = useMapEvent("moveend", () => { + setMapBounds(map.getBounds()); + }); + + return null; +}; + export default function TournamentMap() { const tournaments = useAtomValue(tournamentsAtom); const center: LatLngLiteral = { lat: 47.0844, lng: 2.3964 }; @@ -68,6 +78,7 @@ export default function TournamentMap() { height: "100%", }} > + -
+
-
- +
+
+ + + ([]); export const searchStringAtom = atom(''); +export const mapBoundsAtom = atom(null); +export const syncVisibleAtom = atom(true); export const { currentValueAtom: hoveredMapTournamentIdAtom, @@ -18,7 +21,16 @@ export const { export const filteredTournamentsAtom = atom((get) => { const tournaments = get(tournamentsAtom); const searchString = get(searchStringAtom).trim(); + const mapBounds = get(mapBoundsAtom); + const syncVisible = get(syncVisibleAtom); - if (searchString === '') return tournaments; - return tournaments.filter((t) => t.town.includes(searchString.toUpperCase())) + // When searching, we search all the tournament, regardless of the map display + if (searchString !== '') + return tournaments.filter((t) => t.town.includes(searchString.toUpperCase())) + + // If we not syncing to the map, return all tournaments + if (mapBounds === null || !syncVisible) return tournaments; + + // Filter by those in the current map bounds + return tournaments.filter(tournament => mapBounds.contains({ lat: tournament.coordinates[0], lng: tournament.coordinates[1]})) }) diff --git a/messages/en.json b/messages/en.json index bff781b..d8a8f9c 100644 --- a/messages/en.json +++ b/messages/en.json @@ -35,6 +35,7 @@ "loading": "Loading...", "searchLabel": "Search", "searchPlaceholder": "Search", + "syncWithMapCheckbox": "Tournaments visible on the map", "noneFound": "No tournaments found", "date": "Date", "town": "Town", diff --git a/messages/fr.json b/messages/fr.json index 7041bda..06edfdb 100644 --- a/messages/fr.json +++ b/messages/fr.json @@ -35,6 +35,7 @@ "loading": "Téléchargement...", "searchLabel": "Rechercher", "searchPlaceholder": "Rechercher", + "syncWithMapCheckbox": "Tournois visibles sur la carte", "noneFound": "Pas de tournois trouvé", "date": "Date", "town": "Ville", diff --git a/utils/atomWithDebounce.ts b/utils/atomWithDebounce.ts index fbf076a..8b94bc8 100644 --- a/utils/atomWithDebounce.ts +++ b/utils/atomWithDebounce.ts @@ -52,7 +52,7 @@ export default function atomWithDebounce( ); // exported atom setter to clear timeout if needed - const clearTimeoutAtom = atom(null, (get, set, _arg) => { + const clearTimeoutAtom = atom(null, (get, set) => { clearTimeout(get(prevTimeoutAtom)); set(isDebouncingAtom, false); });