Switch mobile app to dark theme and fix calendar filtering

Switch mobile app to dark theme and fix calendar filtering

- Default to dark theme in mobile app, matching web app style
- Filter native calendar events by location to exclude empty ones
- Add batch edit panel for destinations on web calendar
- Add edit support to AddEventModal
- Update notification trigger input type export
This commit is contained in:
2026-05-13 09:45:55 +02:00
parent de9a8606ab
commit 9e461aab1a
22 changed files with 632 additions and 168 deletions
+17 -3
View File
@@ -6,6 +6,7 @@ import type {
CalendarEvent,
Journey,
Station,
WienerLinienDeparture,
} from "@timetoleave/core";
import { hafasDateTime } from "@timetoleave/core";
@@ -213,15 +214,15 @@ export class ApiClient {
],
});
const stations = result?.svcReqL?.[0]?.res?.match?.locL ?? [];
const stations: HafasLocation[] = result?.svcReqL?.[0]?.res?.match?.locL ?? [];
if (stations.length === 0) return null;
// Filter to only "S" (station) type results, then pick the closest
const stationResults = stations.filter((s) => s.type === "S");
const stationResults = stations.filter((s: HafasLocation) => s.type === "S");
if (stationResults.length === 0) return null;
// Find the closest station by Euclidean distance
const closest = stationResults.reduce((best, candidate) => {
const closest = stationResults.reduce((best: HafasLocation, candidate: HafasLocation) => {
const bestDist = Math.hypot((best.lat ?? lat) - lat, (best.lng ?? lng) - lng);
const candDist = Math.hypot((candidate.lat ?? lat) - lat, (candidate.lng ?? lng) - lng);
return candDist < bestDist ? candidate : best;
@@ -229,4 +230,17 @@ export class ApiClient {
return closest;
}
async monitorStops(stopIds: string[]): Promise<WienerLinienDeparture[]> {
if (stopIds.length === 0) return [];
const params = new URLSearchParams();
for (const id of stopIds) {
params.append("stopIds", id);
}
const url = `${this.baseUrl}/api/wienerlinien/monitor?${params.toString()}`;
const res = await fetch(url);
if (!res.ok) throw new Error(`Monitor failed: ${res.status}`);
const data: { departures?: WienerLinienDeparture[] } = await res.json();
return data.departures ?? [];
}
}