diff options
| author | Ariel Costas Guerrero <ariel@costas.dev> | 2025-11-19 12:40:48 +0100 |
|---|---|---|
| committer | Ariel Costas Guerrero <ariel@costas.dev> | 2025-11-19 12:40:48 +0100 |
| commit | d434204860fc0409ad6343e815d0057b97ce3573 (patch) | |
| tree | 37d349fb3a39e727150134a32e745c64a7312571 /src/frontend/app | |
| parent | d6a28db658487bab63067499c3c7dbe6165e18c1 (diff) | |
Some UI tweaks
Diffstat (limited to 'src/frontend/app')
| -rw-r--r-- | src/frontend/app/components/StopMapSheet.css | 11 | ||||
| -rw-r--r-- | src/frontend/app/components/StopMapSheet.tsx | 37 | ||||
| -rw-r--r-- | src/frontend/app/components/StopSheet.css | 1 | ||||
| -rw-r--r-- | src/frontend/app/root.css | 5 | ||||
| -rw-r--r-- | src/frontend/app/routes/home.css | 2 | ||||
| -rw-r--r-- | src/frontend/app/routes/map.tsx | 42 | ||||
| -rw-r--r-- | src/frontend/app/routes/stops-$id.css | 3 | ||||
| -rw-r--r-- | src/frontend/app/routes/stops-$id.tsx | 19 |
8 files changed, 90 insertions, 30 deletions
diff --git a/src/frontend/app/components/StopMapSheet.css b/src/frontend/app/components/StopMapSheet.css index 4b0f528..2b28a13 100644 --- a/src/frontend/app/components/StopMapSheet.css +++ b/src/frontend/app/components/StopMapSheet.css @@ -76,6 +76,17 @@ animation: userPulse 1.8s ease-out infinite; } +.stop-map-container small { + position: absolute; + bottom: 4px; + left: 4px; + font-size: 12px; + color: var(--text-secondary); + background-color: rgba(255, 255, 255, 0.7); + padding: 2px 4px; + border-radius: 4px; +} + @keyframes userPulse { 0% { transform: scale(0.6); diff --git a/src/frontend/app/components/StopMapSheet.tsx b/src/frontend/app/components/StopMapSheet.tsx index b3a1666..8bdcfa9 100644 --- a/src/frontend/app/components/StopMapSheet.tsx +++ b/src/frontend/app/components/StopMapSheet.tsx @@ -1,9 +1,9 @@ import maplibregl from "maplibre-gl"; import React, { useEffect, useMemo, useRef, useState } from "react"; import Map, { - AttributionControl, - Marker, - type MapRef, + AttributionControl, + Marker, + type MapRef, } from "react-map-gl/maplibre"; import { useApp } from "~/AppContext"; import { getLineColor } from "~/data/LineColors"; @@ -184,8 +184,26 @@ export const StopMap: React.FC<StopMapProps> = ({ useEffect(() => { if (!styleSpec || !mapRef.current || hasFitBounds.current) return; + const map = mapRef.current.getMap(); + + // Handle missing sprite images to suppress console warnings + const handleStyleImageMissing = (e: any) => { + if (!map || map.hasImage(e.id)) return; + // Add a transparent 1x1 placeholder + map.addImage(e.id, { + width: 1, + height: 1, + data: new Uint8Array(4), + }); + }; + + map.on("styleimagemissing", handleStyleImageMissing); + const points = computeFocusPoints(); - if (points.length === 0) return; + if (points.length === 0) { + map.off("styleimagemissing", handleStyleImageMissing); + return; + } let minLat = points[0].lat, maxLat = points[0].lat, @@ -223,6 +241,15 @@ export const StopMap: React.FC<StopMapProps> = ({ } hasFitBounds.current = true; } catch {} + + return () => { + if (mapRef.current) { + const map = mapRef.current.getMap(); + if (map) { + map.off("styleimagemissing", handleStyleImageMissing); + } + } + }; }, [styleSpec, stop.latitude, stop.longitude, busPositions, userPosition]); const handleCenter = () => { @@ -435,7 +462,7 @@ export const StopMap: React.FC<StopMapProps> = ({ })()} </Map> )} - {/* Floating controls */} + <div className="map-floating-controls"> <button type="button" diff --git a/src/frontend/app/components/StopSheet.css b/src/frontend/app/components/StopSheet.css index 31770a1..a34d730 100644 --- a/src/frontend/app/components/StopSheet.css +++ b/src/frontend/app/components/StopSheet.css @@ -177,6 +177,7 @@ gap: 0.75rem; margin: 0.75rem 0 1rem 0; padding-top: 0.75rem; + padding-inline: 16px; } .stop-sheet-timestamp { diff --git a/src/frontend/app/root.css b/src/frontend/app/root.css index 6331140..6c3dd99 100644 --- a/src/frontend/app/root.css +++ b/src/frontend/app/root.css @@ -144,9 +144,8 @@ body { } .navigation-bar__link svg { - width: 1.5rem; - height: 1.5rem; - margin-bottom: 5px; + width: 1.375rem; + height: 1.375rem; fill: none; stroke-width: 2; } diff --git a/src/frontend/app/routes/home.css b/src/frontend/app/routes/home.css index 253c0ab..3d5ba3a 100644 --- a/src/frontend/app/routes/home.css +++ b/src/frontend/app/routes/home.css @@ -1,6 +1,6 @@ /* Common page styles */ .page-title { - font-size: 1.8rem; + font-size: 1.4rem; margin-bottom: 1rem; font-weight: 600; color: var(--text-color); diff --git a/src/frontend/app/routes/map.tsx b/src/frontend/app/routes/map.tsx index 5a8c7a2..b8fb881 100644 --- a/src/frontend/app/routes/map.tsx +++ b/src/frontend/app/routes/map.tsx @@ -1,22 +1,21 @@ import StopDataProvider, { type Stop } from "../data/StopDataProvider"; import "./map.css"; +import { loadStyle } from "app/maps/styleloader"; +import type { Feature as GeoJsonFeature, Point } from "geojson"; import { useEffect, useRef, useState } from "react"; -import { useApp } from "~/AppContext"; +import { useTranslation } from "react-i18next"; import Map, { - AttributionControl, - GeolocateControl, - Layer, - NavigationControl, - Source, - type MapRef, - type MapLayerMouseEvent, - type StyleSpecification, + GeolocateControl, + Layer, + NavigationControl, + Source, + type MapLayerMouseEvent, + type MapRef, + type StyleSpecification } from "react-map-gl/maplibre"; -import { loadStyle } from "app/maps/styleloader"; -import type { Feature as GeoJsonFeature, Point } from "geojson"; +import { useApp } from "~/AppContext"; import { StopSheet } from "~/components/StopSheet"; -import { useTranslation } from "react-i18next"; import { REGIONS } from "~/data/RegionConfig"; // Default minimal fallback style before dynamic loading @@ -96,10 +95,26 @@ export default function StopMap() { updateMapState([center.lat, center.lng], zoom); }; + const handleStyleImageMissing = (e: any) => { + // Suppress warnings for missing sprite images from base style + // This prevents console noise from OpenFreeMap's missing icons + if (!mapRef.current) return; + const map = mapRef.current.getMap(); + if (!map || map.hasImage(e.id)) return; + + // Add a transparent 1x1 placeholder to prevent repeated warnings + map.addImage(e.id, { + width: 1, + height: 1, + data: new Uint8Array(4), + }); + }; + if (mapRef.current) { const map = mapRef.current.getMap(); if (map) { map.on("moveend", handleMapChange); + map.on("styleimagemissing", handleStyleImageMissing); } } @@ -108,6 +123,7 @@ export default function StopMap() { const map = mapRef.current.getMap(); if (map) { map.off("moveend", handleMapChange); + map.off("styleimagemissing", handleStyleImageMissing); } } }; @@ -168,7 +184,7 @@ export default function StopMap() { layout={{ "icon-image": [ "case", - ["boolean", ["get", "cancelled"], false], + ["coalesce", ["get", "cancelled"], false], `stop-${region}-cancelled`, `stop-${region}`, ], diff --git a/src/frontend/app/routes/stops-$id.css b/src/frontend/app/routes/stops-$id.css index 7df3af2..c515435 100644 --- a/src/frontend/app/routes/stops-$id.css +++ b/src/frontend/app/routes/stops-$id.css @@ -1,5 +1,6 @@ .page-title { margin-block: 0; + font-size: 1.5rem; } .estimates-content-wrapper { @@ -269,7 +270,7 @@ background-color: #fff3cd; border: 1px solid #ffc107; border-radius: 8px; - padding: 1rem; + padding: 0.5rem 1rem; color: #856404; flex-shrink: 0; } diff --git a/src/frontend/app/routes/stops-$id.tsx b/src/frontend/app/routes/stops-$id.tsx index ac41250..372582b 100644 --- a/src/frontend/app/routes/stops-$id.tsx +++ b/src/frontend/app/routes/stops-$id.tsx @@ -191,14 +191,19 @@ export default function Estimates() { <> <div className="page-container stops-page"> <div className="stops-header"> + <div> + <Star + className={`star-icon ${favourited ? "active" : ""}`} + onClick={toggleFavourite} + width={20} + /> + <Edit2 + className="edit-icon" + onClick={handleRename} + width={20} /> + </div> <h1 className="page-title"> - <Star - className={`star-icon ${favourited ? "active" : ""}`} - onClick={toggleFavourite} - /> - <Edit2 className="edit-icon" onClick={handleRename} /> - {getStopDisplayName()}{" "} - <span className="estimates-stop-id">({stopIdNum})</span> + {getStopDisplayName()} </h1> <button |
