Files
time_to_leave/apps/mobile/src/hooks/useDepartureTime.ts
T
fegger 9e461aab1a 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
2026-05-13 09:45:55 +02:00

64 lines
2.2 KiB
TypeScript

import { useMemo } from 'react';
import type { Journey } from '@timetoleave/core';
interface DepartureTimeResult {
departureTime: Date | null;
arrivalTime: Date | null;
mode: 'train' | 'bike' | null;
}
/**
* Calculate departure time based on selected transport mode.
* Mirrors the web app's useDepartureTime hook.
*/
export function useDepartureTime(
eventTime: Date,
journeys: Journey[] | null,
bikeDurationSeconds: number | null,
activeMode: 'train' | 'bike' | null,
arrivalBufferMinutes: number,
): DepartureTimeResult {
return useMemo(() => {
// Calculate target arrival time (event time minus buffer)
const targetArrivalTime = new Date(eventTime);
targetArrivalTime.setMinutes(targetArrivalTime.getMinutes() - arrivalBufferMinutes);
// Filter out cancelled journeys
const validJourneys = journeys?.filter((journey) => !journey.cancelled) || [];
let departureTime: Date | null = null;
let arrivalTime: Date | null = null;
let mode: 'train' | 'bike' | null = null;
if (activeMode === 'train' && validJourneys.length > 0) {
// Find journeys that arrive by target time
const onTimeJourneys = validJourneys.filter(
(journey) => journey.rA.getTime() <= targetArrivalTime.getTime(),
);
if (onTimeJourneys.length > 0) {
// Pick the journey with the latest departure that still arrives on time
const bestJourney = onTimeJourneys.reduce((latest, current) =>
current.rD.getTime() > latest.rD.getTime() ? current : latest,
);
departureTime = new Date(bestJourney.rD);
arrivalTime = new Date(bestJourney.rA);
mode = 'train';
}
}
if (activeMode === 'bike' && bikeDurationSeconds !== null && bikeDurationSeconds > 0) {
const bikeDurationMs = bikeDurationSeconds * 1000;
const totalBufferMs = arrivalBufferMinutes * 60 * 1000;
const targetArrivalMs = eventTime.getTime() - totalBufferMs;
departureTime = new Date(targetArrivalMs - bikeDurationMs);
arrivalTime = new Date(targetArrivalMs);
mode = 'bike';
}
return { departureTime, arrivalTime, mode };
}, [eventTime, journeys, bikeDurationSeconds, activeMode, arrivalBufferMinutes]);
}