mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-20 22:16:26 +00:00
32dfc75756
A city walk now shows, at each stop, when the walk gets there, until when the stay lasts, and what the stop's opening hours say about that visit. The same lines appear under each stop row in the planner and under each stop in the walk's detail, in the user's 12 or 24 hour format. A conflict names the stop, the arrival, the end of the stay and the hours it was checked against, for instance "Lenbachhaus closes at 18:00, during the stay from 17:20 to 18:20 (open 10:00 to 18:00)", in the warning colour. Nothing is changed by these hints: no stop, order or route moves. The times belong to one day the walk is on. Opened from a day of the plan, the detail keeps that day, and checking stops off stays bound to it. Opened otherwise, and in the planner, a small pill above the stops names the day and its start, and the walk's other days can be picked from it; it starts on the first day with a start time. The pick is only what is looked at and is never saved, and another day never takes over the times quietly. Without a day, a date or a start time the line says what is missing and no arrival is shown. TREK keeps no time zone on a trip, so start, arrivals and opening hours are all read as the local time of the plan, and an arrival after midnight is said to be on the next day without being checked. Opening hours come from the trip place a stop stands for, as the travellers entered them, and otherwise from OpenStreetMap; a pill at each stop names the source, and a notice says the hours are a hint to check. A stop without hours stays unknown and is never shown as open, hours that are not in a plain form are shown as written, and an arrival that is only a lower bound, because a stay before it is not entered yet, is not judged unless no later arrival could escape the conflict. A trip place that a stop stands for also gives the stop its name before "Stop N". The arrival at a stop is found where the route passes it in the walk's order, so the end of a loop and a stop passed on the way out and back get the right time. The rules live once in the shared package, for the server to give the same answers. The walk's detail reads its stops again after a save, its own or a teammate's.
47 lines
1.9 KiB
TypeScript
47 lines
1.9 KiB
TypeScript
import { walkStationsOf } from '@trek/shared';
|
|
import { useEffect, useState } from 'react';
|
|
import { tourRepo } from '../../../repo/tourRepo';
|
|
import { randomId } from '../../../utils/randomId';
|
|
import { plannerWaypointsOf, type TourPlannerWaypoint } from '../planner/tourPlannerWaypoints';
|
|
|
|
/**
|
|
* CW-03: a synced walk's stations all carry a key. Points without any are the
|
|
* route's ends, which this device reads in their place while it holds none of
|
|
* the stations, so they are not listed as the walk's. A walk saved offline has
|
|
* no keys before it synced, and its stations stay.
|
|
*/
|
|
function ownStations(points: TourPlannerWaypoint[], placeId: number): TourPlannerWaypoint[] {
|
|
return placeId < 0 || points.some((point) => point.key) ? points : [];
|
|
}
|
|
|
|
/**
|
|
* CW-03: a saved walk's stations in order: null while they load, none where
|
|
* they could not be read. Read again when the walk is saved (its revision
|
|
* moves on), here or by someone else, so the detail never shows the stations
|
|
* of before; the ones shown stay until the new ones are in.
|
|
*/
|
|
export function useWalkStations(
|
|
tripId: number | string,
|
|
placeId: number,
|
|
enabled: boolean,
|
|
revision?: number
|
|
): TourPlannerWaypoint[] | null {
|
|
const [stations, setStations] = useState<{ placeId: number; points: TourPlannerWaypoint[] } | null>(null);
|
|
useEffect(() => {
|
|
if (!enabled) return;
|
|
const controller = new AbortController();
|
|
tourRepo
|
|
.detail(tripId, placeId, controller.signal)
|
|
.then((detail) => {
|
|
if (controller.signal.aborted) return;
|
|
const points = walkStationsOf(plannerWaypointsOf(detail.waypoints, randomId));
|
|
setStations({ placeId, points: ownStations(points, placeId) });
|
|
})
|
|
.catch(() => {
|
|
if (!controller.signal.aborted) setStations({ placeId, points: [] });
|
|
});
|
|
return () => controller.abort();
|
|
}, [enabled, placeId, revision, tripId]);
|
|
return enabled && stations?.placeId === placeId ? stations.points : null;
|
|
}
|