From 857100ef949137b0450315de5116769e22573255 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ullrich=20Sch=C3=A4fer?= Date: Sat, 11 Apr 2026 00:27:09 +0200 Subject: [PATCH] Fix overnight flag lost on Journal roundtrip MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three gaps in the Planner → Journal → Planner roundtrip: 1. SaveToJournalButton: wasn't including isDayBreak when building waypoints for GPX generation 2. PlannerMap GPX import: wasn't setting overnight on Y.Maps when importing waypoints with isDayBreak 3. use-yjs initial waypoints: wasn't setting overnight from isDayBreak Also widened the waypoint type throughout the chain (api.sessions, session.$id, SessionView, extractWaypoints) to carry isDayBreak. Co-Authored-By: Claude Opus 4.6 (1M context) --- apps/planner/app/components/PlannerMap.tsx | 2 ++ apps/planner/app/components/SaveToJournalButton.tsx | 1 + apps/planner/app/components/SessionView.tsx | 2 +- apps/planner/app/lib/use-yjs.ts | 3 ++- apps/planner/app/routes/api.sessions.ts | 2 +- apps/planner/app/routes/session.$id.tsx | 2 +- packages/gpx/src/waypoints.ts | 2 +- 7 files changed, 9 insertions(+), 5 deletions(-) diff --git a/apps/planner/app/components/PlannerMap.tsx b/apps/planner/app/components/PlannerMap.tsx index b6759bf..0feae90 100644 --- a/apps/planner/app/components/PlannerMap.tsx +++ b/apps/planner/app/components/PlannerMap.tsx @@ -411,6 +411,8 @@ export function PlannerMap({ yjs, onRouteRequest, highlightPosition, onImportErr const yMap = new Y.Map(); yMap.set("lat", wp.lat); yMap.set("lon", wp.lon); + if (wp.name) yMap.set("name", wp.name); + if (wp.isDayBreak) yMap.set("overnight", true); yjs.waypoints.push([yMap]); } diff --git a/apps/planner/app/components/SaveToJournalButton.tsx b/apps/planner/app/components/SaveToJournalButton.tsx index 52f1138..56a753c 100644 --- a/apps/planner/app/components/SaveToJournalButton.tsx +++ b/apps/planner/app/components/SaveToJournalButton.tsx @@ -45,6 +45,7 @@ export function SaveToJournalButton({ yjs, callbackUrl, callbackToken, returnUrl lat: yMap.get("lat") as number, lon: yMap.get("lon") as number, name: yMap.get("name") as string | undefined, + isDayBreak: yMap.get("overnight") === true ? true : undefined, })); const gpx = generateGpx({ name: "trails.cool route", waypoints, tracks, noGoAreas }); diff --git a/apps/planner/app/components/SessionView.tsx b/apps/planner/app/components/SessionView.tsx index 5906ee2..18b4dc2 100644 --- a/apps/planner/app/components/SessionView.tsx +++ b/apps/planner/app/components/SessionView.tsx @@ -180,7 +180,7 @@ interface SessionViewProps { callbackUrl?: string; callbackToken?: string; returnUrl?: string; - initialWaypoints?: Array<{ lat: number; lon: number; name?: string }>; + initialWaypoints?: Array<{ lat: number; lon: number; name?: string; isDayBreak?: boolean }>; initialNoGoAreas?: Array<{ points: Array<{ lat: number; lon: number }> }>; } diff --git a/apps/planner/app/lib/use-yjs.ts b/apps/planner/app/lib/use-yjs.ts index 95135dd..d573a34 100644 --- a/apps/planner/app/lib/use-yjs.ts +++ b/apps/planner/app/lib/use-yjs.ts @@ -42,7 +42,7 @@ export interface YjsState { export function useYjs( sessionId: string, - initialWaypoints?: Array<{ lat: number; lon: number; name?: string }>, + initialWaypoints?: Array<{ lat: number; lon: number; name?: string; isDayBreak?: boolean }>, initialNoGoAreas?: Array<{ points: Array<{ lat: number; lon: number }> }>, ): YjsState | null { const [state, setState] = useState(null); @@ -106,6 +106,7 @@ export function useYjs( yMap.set("lat", wp.lat); yMap.set("lon", wp.lon); if (wp.name) yMap.set("name", wp.name); + if (wp.isDayBreak) yMap.set("overnight", true); waypoints.push([yMap]); } if (initialNoGoAreas?.length && noGoAreas.length === 0) { diff --git a/apps/planner/app/routes/api.sessions.ts b/apps/planner/app/routes/api.sessions.ts index fd7df07..af238d2 100644 --- a/apps/planner/app/routes/api.sessions.ts +++ b/apps/planner/app/routes/api.sessions.ts @@ -19,7 +19,7 @@ export async function action({ request }: Route.ActionArgs) { return withDb(async () => { const session = await createSession({ callbackUrl, callbackToken }); - let initialWaypoints: Array<{ lat: number; lon: number; name?: string }> | undefined; + let initialWaypoints: Array<{ lat: number; lon: number; name?: string; isDayBreak?: boolean }> | undefined; let initialNoGoAreas: Array<{ points: Array<{ lat: number; lon: number }> }> | undefined; if (gpx) { try { diff --git a/apps/planner/app/routes/session.$id.tsx b/apps/planner/app/routes/session.$id.tsx index 33b8311..a0f93ad 100644 --- a/apps/planner/app/routes/session.$id.tsx +++ b/apps/planner/app/routes/session.$id.tsx @@ -33,7 +33,7 @@ export default function SessionPage({ loaderData }: Route.ComponentProps) { const [searchParams] = useSearchParams(); const returnUrl = searchParams.get("returnUrl") ?? undefined; const waypointsParam = searchParams.get("waypoints"); - let initialWaypoints: Array<{ lat: number; lon: number; name?: string }> | undefined; + let initialWaypoints: Array<{ lat: number; lon: number; name?: string; isDayBreak?: boolean }> | undefined; if (waypointsParam) { try { initialWaypoints = JSON.parse(waypointsParam); } catch { /* ignore */ } } diff --git a/packages/gpx/src/waypoints.ts b/packages/gpx/src/waypoints.ts index dddfffb..2283b88 100644 --- a/packages/gpx/src/waypoints.ts +++ b/packages/gpx/src/waypoints.ts @@ -5,7 +5,7 @@ import type { GpxData } from "./types.ts"; * Uses explicit elements if present, otherwise simplifies the * track using Douglas-Peucker to find significant turning points. */ -export function extractWaypoints(gpxData: GpxData): Array<{ lat: number; lon: number; name?: string }> { +export function extractWaypoints(gpxData: GpxData): Array<{ lat: number; lon: number; name?: string; isDayBreak?: boolean }> { if (gpxData.waypoints.length > 0) return gpxData.waypoints; if (gpxData.tracks.length === 0) return [];