From 3a12b30d0e9c6bbd26c568afc629cd0ac5aa8f17 Mon Sep 17 00:00:00 2001 From: David Abell <79927957+david-abell@users.noreply.github.com> Date: Tue, 23 Apr 2024 16:34:06 +0100 Subject: [PATCH] Feat: Zoom to and show user location (#37) * fix: reenable board here and set destination stopmarker buttons * add experimental https to dev server * add LeafletControl wrapper * add UserLocation dot * fix: Location button position when footer visible * style: change setView to flyTo UserLocation * bump version to 0.9.0 --- .gitignore | 2 + package.json | 4 +- src/components/Map/LeafletControl.tsx | 37 +++++++++++ src/components/Map/MapContentLayer.tsx | 24 +++---- src/components/Map/StopPopup.tsx | 8 +-- src/components/Map/UserLocation.tsx | 88 ++++++++++++++++++++++++++ src/pages/index.tsx | 5 +- 7 files changed, 147 insertions(+), 21 deletions(-) create mode 100644 src/components/Map/LeafletControl.tsx create mode 100644 src/components/Map/UserLocation.tsx diff --git a/.gitignore b/.gitignore index b50558c..84c5c82 100644 --- a/.gitignore +++ b/.gitignore @@ -41,3 +41,5 @@ prisma/*.tgz prisma/backup/* last_modified_log.txt prisma/*.db-journal + +certificates \ No newline at end of file diff --git a/package.json b/package.json index fe0f1ee..282ddac 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,9 @@ { "name": "irish-buses", - "version": "0.8.10", + "version": "0.9.0", "type": "module", "scripts": { - "dev": "next dev", + "dev": "next dev --experimental-https", "build": "next build", "start": "next start", "lint": "next lint", diff --git a/src/components/Map/LeafletControl.tsx b/src/components/Map/LeafletControl.tsx new file mode 100644 index 0000000..47add1c --- /dev/null +++ b/src/components/Map/LeafletControl.tsx @@ -0,0 +1,37 @@ +import L from "leaflet"; +import React, { ReactNode, useEffect, useRef } from "react"; + +const POSITION_CLASSES = { + bottomleft: "leaflet-bottom leaflet-left", + bottomright: "leaflet-bottom leaflet-right", + topleft: "leaflet-top leaflet-left", + topright: "leaflet-top leaflet-right", +}; + +type ControlPosition = keyof typeof POSITION_CLASSES; +interface LeafLetControlProps { + position?: ControlPosition; + children: ReactNode; +} + +const LeafletControl: React.FC = ({ + position, + children, +}) => { + const divRef = useRef(null); + + useEffect(() => { + if (divRef.current) { + L.DomEvent.disableClickPropagation(divRef.current); + L.DomEvent.disableScrollPropagation(divRef.current); + } + }); + + return ( +
+
{children}
+
+ ); +}; + +export default LeafletControl; diff --git a/src/components/Map/MapContentLayer.tsx b/src/components/Map/MapContentLayer.tsx index 8348579..2cf464d 100644 --- a/src/components/Map/MapContentLayer.tsx +++ b/src/components/Map/MapContentLayer.tsx @@ -6,11 +6,8 @@ import { useMap, LayersControl, LayerGroup, - Marker, - Popup, Pane, useMapEvents, - Tooltip, } from "react-leaflet"; import { LatLngTuple } from "leaflet"; import { @@ -22,33 +19,24 @@ import { useRef, useState, } from "react"; -import { useLocalStorage } from "usehooks-ts"; import type { Route, Stop, StopTime } from "@prisma/client"; -import { - formatReadableDelay, - getDelayedTime, - parseDatetimeLocale, - timeSinceLastVehicleUpdate, -} from "@/lib/timeHelpers"; +import { parseDatetimeLocale } from "@/lib/timeHelpers"; import Bus from "./Bus"; import usePrevious from "@/hooks/usePrevious"; import isEqual from "react-fast-compare"; import { DateTime } from "luxon"; import useTripUpdates from "@/hooks/useTripUpdates"; import useStopId from "@/hooks/useStopId"; -import { SavedStop } from "../SavedStops"; import { Position } from "@turf/helpers"; import MarkerClusterGroup from "./MarkerClusterGroup"; import StopMarker from "./StopMarker"; -import StopPopup from "./StopPopup"; import useVehicleUpdates from "@/hooks/useVehicleUpdates"; -import { Button } from "../ui/button"; import { TripHandler } from "@/pages"; -import LiveText from "../LiveText"; import L from "leaflet"; import GPSGhost from "./GPSGhost"; import { MAP_DEFAULT_ZOOM } from "."; +import UserLocation from "./UserLocation"; export type ValidStop = Stop & { stopLat: NonNullable; @@ -67,6 +55,7 @@ type Props = { center: LatLngTuple; routesById: Map; shape: Position[] | undefined; + showFooter: boolean; stopsById: Map; stopTimes: StopTime[] | undefined; stopTimesByStopId: Map; @@ -89,6 +78,7 @@ function MapContentLayer({ stopTimesByStopId, setShowSavedStops, shape, + showFooter, stops, stopsById, selectedStopId, @@ -137,6 +127,7 @@ function MapContentLayer({ const { selectedStop } = useStopId(selectedStopId); + // Set map center location on new route selection useEffect(() => { if (!stopIds.length) return; @@ -155,6 +146,7 @@ function MapContentLayer({ } }, [center, map, prevCenter, previousStopIds, stopIds]); + // Set map dimensions onload/onresize useEffect(() => { if (map != null) { const mapContainer = map.getContainer(); @@ -299,6 +291,7 @@ function MapContentLayer({ ))} + {/* Route stop markers */} @@ -320,6 +313,9 @@ function MapContentLayer({ + {/* User Location dot */} + + {/* Trip line shape */} {!!shape && ( diff --git a/src/components/Map/StopPopup.tsx b/src/components/Map/StopPopup.tsx index 71ff278..434b0c0 100644 --- a/src/components/Map/StopPopup.tsx +++ b/src/components/Map/StopPopup.tsx @@ -144,19 +144,19 @@ function StopPopup({ )}
- {/* */} + - {/* {isValidDestination && ( + {isValidDestination && ( - )} */} + )} + + {!!userLocation && ( + <> + {radius > 100 && ( + + )} + + + )} + + + ); +} + +export default UserLocation; diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 461145d..990d215 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -278,6 +278,8 @@ export default function Home() { setDestId(null); }; + const showFooter = useMemo(() => !!routeId, [routeId]); + return (
@@ -366,6 +368,7 @@ export default function Home() { selectedDateTime={selectedDateTime} selectedStopId={stopId} selectedDestinationStopId={destId} + showFooter={showFooter} stopTimes={stopTimes} stopTimesByStopId={stopTimesByStopId} setShowSavedStops={setShowSavedStops} @@ -431,7 +434,7 @@ export default function Home() { /> )} - {!!routeId && ( + {!!showFooter && (