Sync notes through GPX, Journal, and Planner roundtrip
Full notes lifecycle: - GPX: description field in GpxData, <metadata><desc> in generate/parse - Export: Plan GPX and Save to Journal include notes as description - Journal: updateRoute extracts description from GPX, stores on route - Reimport: Edit in Planner passes notes via URL params → Yjs Y.Text - Drop import: GPX with <desc> restores notes in session Spec updated: session-notes gains GPX export, Journal sync, and reimport requirements. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
b12b706b77
commit
08070cdd90
13 changed files with 62 additions and 9 deletions
|
|
@ -69,7 +69,8 @@ export function ExportButton({ yjs }: { yjs: YjsState }) {
|
|||
const tracks = getTracks(yjs);
|
||||
const waypoints = getWaypoints(yjs);
|
||||
const noGoAreas = getNoGoAreas(yjs);
|
||||
const gpx = generateGpx({ name: "trails.cool route", waypoints, tracks, noGoAreas });
|
||||
const notes = yjs.notes.toString() || undefined;
|
||||
const gpx = generateGpx({ name: "trails.cool route", description: notes, waypoints, tracks, noGoAreas });
|
||||
download(gpx, "route-plan.gpx");
|
||||
setOpen(false);
|
||||
}, [yjs]);
|
||||
|
|
|
|||
|
|
@ -614,6 +614,12 @@ export function PlannerMap({ yjs, onRouteRequest, highlightPosition, highlighted
|
|||
yMap.set("points", area.points);
|
||||
yjs.noGoAreas.push([yMap]);
|
||||
}
|
||||
|
||||
// Replace notes if GPX has a description
|
||||
if (gpxData.description) {
|
||||
yjs.notes.delete(0, yjs.notes.length);
|
||||
yjs.notes.insert(0, gpxData.description);
|
||||
}
|
||||
}, "local");
|
||||
} catch {
|
||||
onImportError?.(t("importGpxError"));
|
||||
|
|
|
|||
|
|
@ -48,7 +48,8 @@ export function SaveToJournalButton({ yjs, callbackUrl, callbackToken, returnUrl
|
|||
isDayBreak: yMap.get("overnight") === true ? true : undefined,
|
||||
}));
|
||||
|
||||
const gpx = generateGpx({ name: "trails.cool route", waypoints, tracks, noGoAreas });
|
||||
const notes = yjs.notes.toString() || undefined;
|
||||
const gpx = generateGpx({ name: "trails.cool route", description: notes, waypoints, tracks, noGoAreas });
|
||||
|
||||
// POST to Journal callback
|
||||
const response = await fetch(callbackUrl, {
|
||||
|
|
|
|||
|
|
@ -152,12 +152,13 @@ interface SessionViewProps {
|
|||
returnUrl?: string;
|
||||
initialWaypoints?: Array<{ lat: number; lon: number; name?: string; isDayBreak?: boolean }>;
|
||||
initialNoGoAreas?: Array<{ points: Array<{ lat: number; lon: number }> }>;
|
||||
initialNotes?: string;
|
||||
}
|
||||
|
||||
export function SessionView({ sessionId, callbackUrl, callbackToken, returnUrl, initialWaypoints, initialNoGoAreas }: SessionViewProps) {
|
||||
export function SessionView({ sessionId, callbackUrl, callbackToken, returnUrl, initialWaypoints, initialNoGoAreas, initialNotes }: SessionViewProps) {
|
||||
const { t } = useTranslation("planner");
|
||||
useEffect(() => { Sentry.setTag("session_id", sessionId); }, [sessionId]);
|
||||
const yjs = useYjs(sessionId, initialWaypoints, initialNoGoAreas);
|
||||
const yjs = useYjs(sessionId, initialWaypoints, initialNoGoAreas, initialNotes);
|
||||
const { computing, routeError, routeStats, requestRoute } = useRouting(yjs);
|
||||
const { canUndo, canRedo, undo, redo } = useUndo(yjs?.undoManager ?? null);
|
||||
useUndoShortcuts(yjs?.undoManager ?? null);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue