mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-24 07:53:09 +00:00
e803d28bf1
The walk's detail opened from a day lists its stops in order, each with its stay, importance and protection, and marks one visited or skipped for that day, or takes it back. The day row shows how many were visited. Marks reach the other travellers at once and change no route, place or order; a copy or another day starts with none.
40 lines
1.5 KiB
TypeScript
40 lines
1.5 KiB
TypeScript
import { tourVisitSchema } from '@trek/shared';
|
|
import { useEffect } from 'react';
|
|
import { addListener, removeListener } from '../../../api/websocket';
|
|
import { useTourVisitStore } from '../../../store/tourVisitStore';
|
|
import type { WebSocketEvent } from '../../../types';
|
|
|
|
/**
|
|
* CW-03: the visits of a trip's city walks, read when the trip opens and kept
|
|
* current by its socket, so a station another traveller checks off shows on
|
|
* every day plan at once. Offline the day plan shows none until it is back.
|
|
*/
|
|
export function useTourVisitsSync(tripId: number | string | undefined, enabled: boolean) {
|
|
useEffect(() => {
|
|
if (!enabled || tripId === undefined) return;
|
|
let current = true;
|
|
useTourVisitStore
|
|
.getState()
|
|
.load(tripId)
|
|
.catch(() => {
|
|
// Offline or refused, the day plan shows no progress rather than another trip's.
|
|
if (current) useTourVisitStore.getState().reset(tripId);
|
|
});
|
|
const onEvent = (event: WebSocketEvent) => {
|
|
if (event?.type !== 'tours:visits' || String(event.tripId ?? '') !== String(tripId)) return;
|
|
const visits = Array.isArray(event.visits)
|
|
? event.visits.flatMap((raw) => {
|
|
const parsed = tourVisitSchema.safeParse(raw);
|
|
return parsed.success ? [parsed.data] : [];
|
|
})
|
|
: [];
|
|
useTourVisitStore.getState().applyRemote(Number(event.assignmentId), visits);
|
|
};
|
|
addListener(onEvent);
|
|
return () => {
|
|
current = false;
|
|
removeListener(onEvent);
|
|
};
|
|
}, [enabled, tripId]);
|
|
}
|