From 2db2746c9c7e8ccafbf30767985f56e444975fe4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 13 Oct 2025 23:55:12 +0000 Subject: [PATCH 1/4] Initial plan From c80012a349deefdb23a4d9932a9adaa9e3f18498 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 14 Oct 2025 00:00:21 +0000 Subject: [PATCH 2/4] Add initial viewport settings in SettingsDrawer Co-authored-by: mikebarkmin <2592379+mikebarkmin@users.noreply.github.com> --- packages/learningmap/src/EditorCanvas.tsx | 17 +++++- packages/learningmap/src/SettingsDrawer.tsx | 65 +++++++++++++++++++++ packages/learningmap/src/translations.ts | 21 +++++++ 3 files changed, 101 insertions(+), 2 deletions(-) diff --git a/packages/learningmap/src/EditorCanvas.tsx b/packages/learningmap/src/EditorCanvas.tsx index 5abb721..bffe308 100644 --- a/packages/learningmap/src/EditorCanvas.tsx +++ b/packages/learningmap/src/EditorCanvas.tsx @@ -1,5 +1,5 @@ -import { useCallback, memo } from "react"; -import { ReactFlow, Controls, Background, ControlButton, OnSelectionChangeFunc, Node, Edge } from "@xyflow/react"; +import { useCallback, memo, useEffect } from "react"; +import { ReactFlow, Controls, Background, ControlButton, OnSelectionChangeFunc, Node, Edge, useReactFlow } from "@xyflow/react"; import { Info, Redo, Undo } from "lucide-react"; import { useEditorStore, useTemporalStore } from "./editorStore"; import { TaskNode } from "./nodes/TaskNode"; @@ -45,9 +45,22 @@ export const EditorCanvas = memo(({ defaultLanguage = "en" }: EditorCanvasProps) const setEdgeDrawerOpen = useEditorStore(state => state.setEdgeDrawerOpen); const setHelpOpen = useEditorStore(state => state.setHelpOpen); + const { setViewport } = useReactFlow(); + const language = settings?.language || defaultLanguage; const t = getTranslations(language); + // Apply viewport from settings on mount or when settings change + useEffect(() => { + if (settings?.viewport) { + setViewport({ + x: settings.viewport.x, + y: settings.viewport.y, + zoom: settings.viewport.zoom, + }); + } + }, [settings?.viewport, setViewport]); + // Temporal store for undo/redo const { undo, redo, canUndo, canRedo } = useTemporalStore((state) => ({ undo: state.undo, diff --git a/packages/learningmap/src/SettingsDrawer.tsx b/packages/learningmap/src/SettingsDrawer.tsx index d292cd6..f36b7f8 100644 --- a/packages/learningmap/src/SettingsDrawer.tsx +++ b/packages/learningmap/src/SettingsDrawer.tsx @@ -44,6 +44,18 @@ export const SettingsDrawer: React.FC = ({ onClose(); }; + const handleUseCurrentViewport = () => { + const viewport = getViewport(); + setLocalSettings(settings => ({ + ...settings, + viewport: { + x: Math.round(viewport.x), + y: Math.round(viewport.y), + zoom: parseFloat(viewport.zoom.toFixed(2)), + } + })); + }; + return ( <>
@@ -82,6 +94,59 @@ export const SettingsDrawer: React.FC = ({ onChange={color => setLocalSettings(settings => ({ ...settings, background: { ...settings.background, color } }))} />
+ +
+ +
+
+ + setLocalSettings(settings => ({ + ...settings, + viewport: { ...settings.viewport, x: parseFloat(e.target.value) || 0, y: settings.viewport?.y ?? 0, zoom: settings.viewport?.zoom ?? 1 } + }))} + style={{ width: '100%' }} + /> +
+
+ + setLocalSettings(settings => ({ + ...settings, + viewport: { ...settings.viewport, y: parseFloat(e.target.value) || 0, x: settings.viewport?.x ?? 0, zoom: settings.viewport?.zoom ?? 1 } + }))} + style={{ width: '100%' }} + /> +
+
+ + setLocalSettings(settings => ({ + ...settings, + viewport: { ...settings.viewport, zoom: parseFloat(e.target.value) || 1, x: settings.viewport?.x ?? 0, y: settings.viewport?.y ?? 0 } + }))} + style={{ width: '100%' }} + /> +
+
+ +
diff --git a/packages/learningmap/src/translations.ts b/packages/learningmap/src/translations.ts index 12cbfb0..772fda4 100644 --- a/packages/learningmap/src/translations.ts +++ b/packages/learningmap/src/translations.ts @@ -184,6 +184,13 @@ export interface Translations { languageEnglish: string; languageGerman: string; + // Viewport settings + initialViewport: string; + viewportX: string; + viewportY: string; + viewportZoom: string; + useCurrentViewport: string; + // Welcome message welcomeTitle: string; welcomeSubtitle: string; @@ -380,6 +387,13 @@ const en: Translations = { languageEnglish: "English", languageGerman: "German", + // Viewport settings + initialViewport: "Initial Viewport", + viewportX: "X Position", + viewportY: "Y Position", + viewportZoom: "Zoom", + useCurrentViewport: "Use Current Viewport", + // Welcome message welcomeTitle: "Learningmap", welcomeSubtitle: "All data is stored locally in your browser", @@ -578,6 +592,13 @@ const de: Translations = { languageEnglish: "Englisch", languageGerman: "Deutsch", + // Viewport settings + initialViewport: "Initialer Ansichtsbereich", + viewportX: "X-Position", + viewportY: "Y-Position", + viewportZoom: "Zoom", + useCurrentViewport: "Aktuellen Ansichtsbereich verwenden", + // Welcome message welcomeTitle: "Learningmap", welcomeSubtitle: "Alle Daten werden lokal in Ihrem Browser gespeichert", From 002e8147f108585f453f99e349d9d014db415768 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 14 Oct 2025 00:06:06 +0000 Subject: [PATCH 3/4] Use viewport settings in LearningMap viewer component Co-authored-by: mikebarkmin <2592379+mikebarkmin@users.noreply.github.com> --- packages/learningmap/src/LearningMap.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/learningmap/src/LearningMap.tsx b/packages/learningmap/src/LearningMap.tsx index da3cb11..0e9dd31 100644 --- a/packages/learningmap/src/LearningMap.tsx +++ b/packages/learningmap/src/LearningMap.tsx @@ -81,9 +81,9 @@ export function LearningMap({ useEffect(() => { loadRoadmapData(parsedRoadmap, initialState); setViewport({ - x: initialState?.x || 0, - y: initialState?.y || 0, - zoom: initialState?.zoom || 1, + x: initialState?.x || settings?.viewport?.x || 0, + y: initialState?.y || settings?.viewport?.y || 0, + zoom: initialState?.zoom || settings?.viewport?.zoom || 1, }); }, [roadmapData, initialState]); From 570bdd3a89467ad4a4bbf7afc92e4b4c767d7a5c Mon Sep 17 00:00:00 2001 From: Mike Barkmin Date: Tue, 14 Oct 2025 08:03:46 +0200 Subject: [PATCH 4/4] Remove fitView property from EditorCanvas --- packages/learningmap/src/EditorCanvas.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/learningmap/src/EditorCanvas.tsx b/packages/learningmap/src/EditorCanvas.tsx index bffe308..74db906 100644 --- a/packages/learningmap/src/EditorCanvas.tsx +++ b/packages/learningmap/src/EditorCanvas.tsx @@ -118,7 +118,6 @@ export const EditorCanvas = memo(({ defaultLanguage = "en" }: EditorCanvasProps) nodeTypes={nodeTypes} selectionOnDrag={false} edgeTypes={edgeTypes} - fitView proOptions={{ hideAttribution: true }} defaultEdgeOptions={defaultEdgeOptions} nodesDraggable={true}