From b189497aa6abf2d86f4d0fbce77cdf96a03a0fc3 Mon Sep 17 00:00:00 2001 From: Traines Date: Wed, 5 Feb 2025 17:08:28 +0000 Subject: [PATCH 1/4] ui: geolocation --- ui/src/app.css | 4 ++++ ui/src/lib/RailViz.svelte | 16 ++++++++++++++++ ui/src/lib/SearchMask.svelte | 25 +++++++++++++++++++++++-- 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/ui/src/app.css b/ui/src/app.css index 126a34ad4..8382cda63 100644 --- a/ui/src/app.css +++ b/ui/src/app.css @@ -105,3 +105,7 @@ flex-direction: column; z-index: 3; } + +.maplibregl-ctrl-group .maplibregl-ctrl-geolocate { + display: none; +} diff --git a/ui/src/lib/RailViz.svelte b/ui/src/lib/RailViz.svelte index 3e9eba1ca..cf173dc29 100644 --- a/ui/src/lib/RailViz.svelte +++ b/ui/src/lib/RailViz.svelte @@ -15,6 +15,7 @@ import { Button } from '$lib/components/ui/button'; import Palette from 'lucide-svelte/icons/palette'; import Rss from 'lucide-svelte/icons/rss'; + import LocateFixed from 'lucide-svelte/icons/locate-fixed'; import { browser } from '$app/environment'; let { @@ -248,6 +249,17 @@ }, 60000); }; + const geolocate = new maplibregl.GeolocateControl({ + positionOptions: { + enableHighAccuracy: true + }, + showAccuracyCircle: false + }); + + const getLocation = () => { + geolocate.trigger(); + }; + $effect(() => { if (map && !overlay) { overlay = new MapboxOverlay({ @@ -270,6 +282,7 @@ onClickTrip(object.trips[0].tripId); } }); + map.addControl(geolocate); map.addControl(overlay); console.log('updateRailviz: init'); @@ -311,6 +324,9 @@ {/if} + {#if railvizError} diff --git a/ui/src/lib/SearchMask.svelte b/ui/src/lib/SearchMask.svelte index 805443119..310fd2b6a 100644 --- a/ui/src/lib/SearchMask.svelte +++ b/ui/src/lib/SearchMask.svelte @@ -1,5 +1,6 @@
+ + +{#if expanded} +
+ { + if (o && !selectedModes.length) selectedModes = [...possibleModes]; + }} + > + + +
{selectedModeLabel}
+ +
+ + + + + + + {#each modes as mode, i (i + mode.value)} + + {#snippet children({ selected })} + {mode.label} + {#if selected} +
+ +
+ {/if} + {/snippet} +
+ {/each} +
+ + + +
+
+
+ + + + +
{t.unreliableOptions}
+
+{/if} diff --git a/ui/src/lib/SearchMask.svelte b/ui/src/lib/SearchMask.svelte index 310fd2b6a..7e18ed8ab 100644 --- a/ui/src/lib/SearchMask.svelte +++ b/ui/src/lib/SearchMask.svelte @@ -1,16 +1,14 @@ @@ -78,24 +80,22 @@ for="departure" class="flex items-center rounded-md border-2 border-muted bg-popover p-1 px-2 hover:bg-accent hover:text-accent-foreground [&:has([data-state=checked])]:border-blue-600 hover:cursor-pointer" > - + {t.departure} -
- - - - - - -
+
diff --git a/ui/src/lib/components/ui/switch/index.ts b/ui/src/lib/components/ui/switch/index.ts new file mode 100644 index 000000000..f5533db72 --- /dev/null +++ b/ui/src/lib/components/ui/switch/index.ts @@ -0,0 +1,7 @@ +import Root from "./switch.svelte"; + +export { + Root, + // + Root as Switch, +}; diff --git a/ui/src/lib/components/ui/switch/switch.svelte b/ui/src/lib/components/ui/switch/switch.svelte new file mode 100644 index 000000000..575ed524e --- /dev/null +++ b/ui/src/lib/components/ui/switch/switch.svelte @@ -0,0 +1,32 @@ + + +
+ + + + {label} +
diff --git a/ui/src/lib/i18n/de.ts b/ui/src/lib/i18n/de.ts index 8d58644c2..52ca15b33 100644 --- a/ui/src/lib/i18n/de.ts +++ b/ui/src/lib/i18n/de.ts @@ -37,7 +37,34 @@ const translations: Translations = { sharingProvider: 'Anbieter', roundtripStationReturnConstraint: 'Das Fahrzeug muss wieder an der Abfahrtsstation abgestellt werden.', - noItinerariesFound: 'Keine Verbindungen gefunden.' + noItinerariesFound: 'Keine Verbindungen gefunden.', + advancedSearchOptions: 'Optionen', + selectModes: 'Öffentliche Verkehrsmittel auswählen', + defaultSelectedModes: 'Alle Verkehrsmittel', + wheelchair: 'Barrierfreie Umstiege', + bikeRental: 'Sharing-Fahrzeuge zulassen', + bikeCarriage: 'Fahrradmitnahme', + unreliableOptions: 'Je nach Datenverfügbarkeit können diese Optionen unzuverlässig sein.', + WALK: 'Zu Fuß', + BIKE: 'Fahrrad', + RENTAL: 'Sharing', + CAR: 'Auto', + CAR_PARKING: 'Car parking', + TRANSIT: 'ÖPV', + TRAM: 'Tram', + SUBWAY: 'U-Bahn', + FERRY: 'Fähre', + AIRPLANE: 'Flugzeug', + METRO: 'S-Bahn', + BUS: 'Bus', + COACH: 'Reisebus', + RAIL: 'Zug', + HIGHSPEED_RAIL: 'Hochgeschwindigkeitszug', + LONG_DISTANCE: 'Intercityzug', + NIGHT_RAIL: 'Nachtzug', + REGIONAL_FAST_RAIL: 'Regionalexpresszug', + REGIONAL_RAIL: 'Regionalzug', + OTHER: 'Andere' }; export default translations; diff --git a/ui/src/lib/i18n/en.ts b/ui/src/lib/i18n/en.ts index 9e21aa72a..a61820fed 100644 --- a/ui/src/lib/i18n/en.ts +++ b/ui/src/lib/i18n/en.ts @@ -36,7 +36,34 @@ const translations: Translations = { }, sharingProvider: 'Provider', roundtripStationReturnConstraint: 'The vehicle must be returned to the departure station.', - noItinerariesFound: 'No itineraries found.' + noItinerariesFound: 'No itineraries found.', + advancedSearchOptions: 'Options', + selectModes: 'Select transit modes', + defaultSelectedModes: 'All transit modes', + wheelchair: 'Barrier-free transfers', + bikeRental: 'Allow usage of sharing vehicles', + bikeCarriage: 'Bike carriage', + unreliableOptions: 'Depending on data availability, these options may be unreliable.', + WALK: 'Walking', + BIKE: 'Bike', + RENTAL: 'Sharing', + CAR: 'Car', + CAR_PARKING: 'Car Parking', + TRANSIT: 'Transit', + TRAM: 'Tram', + SUBWAY: 'Subway', + FERRY: 'Ferry', + AIRPLANE: 'Airplane', + METRO: 'Metropolitan Rail', + BUS: 'Bus', + COACH: 'Coach', + RAIL: 'Train', + HIGHSPEED_RAIL: 'High Speed Rail', + LONG_DISTANCE: 'Intercity Rail', + NIGHT_RAIL: 'Night Rail', + REGIONAL_FAST_RAIL: 'Regional Fast Rail', + REGIONAL_RAIL: 'Regional Rail', + OTHER: 'Other' }; export default translations; diff --git a/ui/src/lib/i18n/fr.ts b/ui/src/lib/i18n/fr.ts index b40660b29..652b3a399 100644 --- a/ui/src/lib/i18n/fr.ts +++ b/ui/src/lib/i18n/fr.ts @@ -36,7 +36,34 @@ const translations: Translations = { sharingProvider: 'Fournisseur', transfers: 'correspondances', roundtripStationReturnConstraint: 'Le véhicule doit être retourné à la station de départ.', - noItinerariesFound: 'Aucun itinéraire trouvé.' + noItinerariesFound: 'Aucun itinéraire trouvé.', + advancedSearchOptions: 'Options', + selectModes: 'Sélectionner les modes de transport en commun', + defaultSelectedModes: 'Tous les transports en commun', + wheelchair: 'Correspondances sans obstacles', + bikeRental: 'Utiliser véhicules partagés', + bikeCarriage: 'Transport vélo', + unreliableOptions: 'Selon la disponibilité des données, ces options peuvent ne pas être fiables.', + WALK: 'À pied', + BIKE: 'Vélo', + RENTAL: 'Loué', + CAR: 'Voiture', + CAR_PARKING: 'Garage voiture', + TRANSIT: 'Transports en commun', + TRAM: 'Tram', + SUBWAY: 'Métro', + FERRY: 'Ferry', + AIRPLANE: 'Avion', + METRO: 'RER', + BUS: 'Bus', + COACH: 'Autocar', + RAIL: 'Train', + HIGHSPEED_RAIL: 'Train à grande vitesse', + LONG_DISTANCE: 'Train intercité', + NIGHT_RAIL: 'Train de nuit', + REGIONAL_FAST_RAIL: 'Train express régional', + REGIONAL_RAIL: 'Train régional', + OTHER: 'Autres' }; export default translations; diff --git a/ui/src/lib/i18n/pl.ts b/ui/src/lib/i18n/pl.ts index 98a5d2492..bf1a020c6 100644 --- a/ui/src/lib/i18n/pl.ts +++ b/ui/src/lib/i18n/pl.ts @@ -36,7 +36,34 @@ const translations: Translations = { }, sharingProvider: 'Dostawca', roundtripStationReturnConstraint: 'Pojazd musi zostać zwrócony do stacji początkowej.', - noItinerariesFound: 'No itineraries found.' + noItinerariesFound: 'No itineraries found.', + advancedSearchOptions: 'Options', + selectModes: 'Select transit modes', + defaultSelectedModes: 'All transit modes', + wheelchair: 'Barrier-free transfers', + bikeRental: 'Allow usage of sharing vehicles', + bikeCarriage: 'Bike carriage', + unreliableOptions: 'Depending on data availability, these options may be unreliable.', + WALK: 'Walking', + BIKE: 'Bike', + RENTAL: 'Sharing', + CAR: 'Car', + CAR_PARKING: 'Car Parking', + TRANSIT: 'Transit', + TRAM: 'Tram', + SUBWAY: 'Subway', + FERRY: 'Ferry', + AIRPLANE: 'Airplane', + METRO: 'Metropolitan Rail', + BUS: 'Bus', + COACH: 'Coach', + RAIL: 'Train', + HIGHSPEED_RAIL: 'High Speed Rail', + LONG_DISTANCE: 'Intercity Rail', + NIGHT_RAIL: 'Night Rail', + REGIONAL_FAST_RAIL: 'Regional Fast Rail', + REGIONAL_RAIL: 'Regional Rail', + OTHER: 'Other' }; export default translations; diff --git a/ui/src/lib/i18n/translation.ts b/ui/src/lib/i18n/translation.ts index 945965864..a34eea28f 100644 --- a/ui/src/lib/i18n/translation.ts +++ b/ui/src/lib/i18n/translation.ts @@ -32,6 +32,33 @@ export type Translations = { sharingProvider: string; roundtripStationReturnConstraint: string; noItinerariesFound: string; + advancedSearchOptions: string; + selectModes: string; + defaultSelectedModes: string; + wheelchair: string; + bikeRental: string; + bikeCarriage: string; + unreliableOptions: string; + WALK: string; + BIKE: string; + RENTAL: string; + CAR: string; + CAR_PARKING: string; + TRANSIT: string; + TRAM: string; + SUBWAY: string; + FERRY: string; + AIRPLANE: string; + METRO: string; + BUS: string; + COACH: string; + RAIL: string; + HIGHSPEED_RAIL: string; + LONG_DISTANCE: string; + NIGHT_RAIL: string; + REGIONAL_FAST_RAIL: string; + REGIONAL_RAIL: string; + OTHER: string; }; const translations: Map = new Map( diff --git a/ui/src/routes/+page.svelte b/ui/src/routes/+page.svelte index 8aa9f3e9a..bd44b971f 100644 --- a/ui/src/routes/+page.svelte +++ b/ui/src/routes/+page.svelte @@ -115,6 +115,8 @@ let timeType = $state('departure'); let wheelchair = $state(false); let bikeRental = $state(false); + let bikeCarriage = $state(false); + let selectedTransitModes = $state([]); const toPlaceString = (l: Location) => { if (l.value.match?.type === 'STOP') { @@ -125,7 +127,11 @@ return `${lngLatToStr(l.value.match!)},0`; } }; - let modes = $derived(['WALK', ...(bikeRental ? ['RENTAL'] : [])] as Mode[]); + let modes = $derived([ + 'WALK', + ...(bikeRental ? ['RENTAL'] : []), + ...(bikeCarriage ? ['BIKE'] : []) + ] as Mode[]); let baseQuery = $derived( from.value.match && to.value.match ? ({ @@ -138,7 +144,9 @@ pedestrianProfile: wheelchair ? 'WHEELCHAIR' : 'FOOT', preTransitModes: modes, postTransitModes: modes, - directModes: modes + directModes: modes, + requireBikeTransport: bikeCarriage, + transitModes: selectedTransitModes.length ? selectedTransitModes : undefined } } as PlanData) : undefined @@ -293,8 +301,17 @@ {#if !isSmallScreen || (!page.state.selectedItinerary && !page.state.selectedStop)} - - + + {/if} @@ -304,7 +321,7 @@ {#if !page.state.selectedItinerary && routingResponses.length !== 0} - +

{t.journeyDetails}