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 | |
| parent | d6a28db658487bab63067499c3c7dbe6165e18c1 (diff) | |
Some UI tweaks
Diffstat (limited to 'src')
| -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 | ||||
| -rw-r--r-- | src/frontend/public/maps/styles/openfreemap-dark.json | 28 | ||||
| -rw-r--r-- | src/frontend/public/maps/styles/openfreemap-light.json | 78 | ||||
| -rw-r--r-- | src/frontend/public/pwa-worker.js | 6 |
11 files changed, 152 insertions, 80 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 diff --git a/src/frontend/public/maps/styles/openfreemap-dark.json b/src/frontend/public/maps/styles/openfreemap-dark.json index 2803f1a..eb9cd25 100644 --- a/src/frontend/public/maps/styles/openfreemap-dark.json +++ b/src/frontend/public/maps/styles/openfreemap-dark.json @@ -3344,13 +3344,22 @@ "paint": { "line-opacity": [ "interpolate", - ["linear"], - ["get", "zoom"], - 0, 1, - 14, 1, - 16, 0.8, - 18, 0.6, - 22, 0.6 + [ + "linear" + ], + [ + "zoom" + ], + 0, + 1, + 14, + 1, + 16, + 0.8, + 18, + 0.6, + 22, + 0.6 ], "line-color": [ "match", @@ -3360,19 +3369,14 @@ ], "#CONGESTION", "hsl(70.7 100% 38%)", - "#MUYDENSO", "hsl(36.49 100% 50%)", - "#DENSO", "hsl(47.61 100% 49%)", - "#FLUIDO", "hsl(83.9 100% 40%)", - "#MUYFLUIDO", "hsl(161.25 100% 42%)", - "hsl(0.0 0% 0%)" ], "line-width": [ diff --git a/src/frontend/public/maps/styles/openfreemap-light.json b/src/frontend/public/maps/styles/openfreemap-light.json index d616fe7..535659f 100644 --- a/src/frontend/public/maps/styles/openfreemap-light.json +++ b/src/frontend/public/maps/styles/openfreemap-light.json @@ -5287,10 +5287,14 @@ false ], [ - "\u003E=", + ">=", [ - "get", - "rank" + "coalesce", + [ + "get", + "rank" + ], + 0 ], 20 ] @@ -5392,7 +5396,7 @@ "bus" ], [ - "\u003E=", + ">=", [ "get", "rank" @@ -5400,10 +5404,14 @@ 7 ], [ - "\u003C", + "<", [ - "get", - "rank" + "coalesce", + [ + "get", + "rank" + ], + 0 ], 20 ] @@ -5505,26 +5513,26 @@ "bus" ], [ - "!=", + ">=", [ - "get", - "class" - ], - "bus" - ], - [ - "\u003E=", - [ - "get", - "rank" + "coalesce", + [ + "get", + "rank" + ], + 1 ], 1 ], [ - "\u003C", + "<", [ - "get", - "rank" + "coalesce", + [ + "get", + "rank" + ], + 0 ], 7 ] @@ -6993,13 +7001,22 @@ "paint": { "line-opacity": [ "interpolate", - ["linear"], - ["get", "zoom"], - 0, 1, - 14, 1, - 16, 0.8, - 18, 0.6, - 22, 0.6 + [ + "linear" + ], + [ + "zoom" + ], + 0, + 1, + 14, + 1, + 16, + 0.8, + 18, + 0.6, + 22, + 0.6 ], "line-color": [ "match", @@ -7009,19 +7026,14 @@ ], "#CONGESTION", "hsl(70.7 100% 38%)", - "#MUYDENSO", "hsl(36.49 100% 50%)", - "#DENSO", "hsl(47.61 100% 49%)", - "#FLUIDO", "hsl(83.9 100% 40%)", - "#MUYFLUIDO", "hsl(161.25 100% 42%)", - "hsl(0.0 0% 0%)" ], "line-width": [ diff --git a/src/frontend/public/pwa-worker.js b/src/frontend/public/pwa-worker.js index eb69b84..649a161 100644 --- a/src/frontend/public/pwa-worker.js +++ b/src/frontend/public/pwa-worker.js @@ -1,4 +1,4 @@ -const CACHE_VERSION = "20251107a"; +const CACHE_VERSION = "20251118a"; const STATIC_CACHE_NAME = `static-cache-${CACHE_VERSION}`; const STATIC_CACHE_ASSETS = ["/favicon.ico", "/logo-256.png", "/logo-512.jpg"]; @@ -9,7 +9,6 @@ const ESTIMATES_MIN_AGE = 15 * 1000; const ESTIMATES_MAX_AGE = 30 * 1000; self.addEventListener("install", (event) => { - console.log("SW: Install event in progress. Cache version: ", CACHE_VERSION); event.waitUntil( caches .open(STATIC_CACHE_NAME) @@ -67,17 +66,14 @@ async function handleStaticRequest(request) { const cache = await caches.open(STATIC_CACHE_NAME); const cachedResponse = await cache.match(request); if (cachedResponse) { - console.log("SW handleStaticRequest: HIT for ", request.url); return cachedResponse; } try { const netResponse = await fetch(request); if (netResponse.ok) cache.put(request, netResponse.clone()); - console.log("SW handleStaticRequest: MISS for ", request.url); return netResponse; } catch (err) { - console.error("SW handleStaticRequest: FAIL for ", request.url, err); return null; } } |
