From d17b617453e9bbd3a5e034bd83f7f32a33f55c99 Mon Sep 17 00:00:00 2001 From: Bohdan Triapitsyn Date: Tue, 27 Jan 2026 12:33:12 +0200 Subject: [PATCH] feat: add markdown viewer toggle in PlanView Enable switching between preview and edit modes for Markdown content Persist viewer mode in localStorage and restore on load Render PreviewToggleButton beside the path actions --- packages/ui/src/components/views/PlanView.tsx | 165 ++++++++++++------ 1 file changed, 107 insertions(+), 58 deletions(-) diff --git a/packages/ui/src/components/views/PlanView.tsx b/packages/ui/src/components/views/PlanView.tsx index 72ce9c46..a4723841 100644 --- a/packages/ui/src/components/views/PlanView.tsx +++ b/packages/ui/src/components/views/PlanView.tsx @@ -1,5 +1,8 @@ import React from 'react'; import { CodeMirrorEditor } from '@/components/ui/CodeMirrorEditor'; +import { PreviewToggleButton } from './PreviewToggleButton'; +import { SimpleMarkdownRenderer } from '@/components/chat/MarkdownRenderer'; +import { ErrorBoundary } from '@/components/ui/ErrorBoundary'; import { ScrollableOverlay } from '@/components/ui/ScrollableOverlay'; import { Textarea } from '@/components/ui/textarea'; import { Button } from '@/components/ui/button'; @@ -114,11 +117,36 @@ export const PlanView: React.FC = () => { const [loading, setLoading] = React.useState(false); const [copiedPath, setCopiedPath] = React.useState(false); const [copiedContent, setCopiedContent] = React.useState(false); + const [mdViewMode, setMdViewMode] = React.useState<'preview' | 'edit'>('edit'); const copiedTimeoutRef = React.useRef(null); const copiedContentTimeoutRef = React.useRef(null); const [lineSelection, setLineSelection] = React.useState(null); const [commentText, setCommentText] = React.useState(''); + + const MD_VIEWER_MODE_KEY = 'openchamber:plan:md-viewer-mode'; + + React.useEffect(() => { + try { + const stored = localStorage.getItem(MD_VIEWER_MODE_KEY); + if (!stored) return; + const parsed = JSON.parse(stored) as unknown; + if (parsed === 'preview' || parsed === 'edit') { + setMdViewMode(parsed); + } + } catch { + // ignore + } + }, []); + + const saveMdViewMode = React.useCallback((mode: 'preview' | 'edit') => { + setMdViewMode(mode); + try { + localStorage.setItem(MD_VIEWER_MODE_KEY, JSON.stringify(mode)); + } catch { + // ignore + } + }, []); const isSelectingRef = React.useRef(false); const selectionStartRef = React.useRef(null); @@ -421,6 +449,10 @@ export const PlanView: React.FC = () => { {resolvedPath ? (
+ saveMdViewMode(mdViewMode === 'preview' ? 'edit' : 'preview')} + />
@@ -565,7 +614,7 @@ export const PlanView: React.FC = () => { - {lineSelection && ( + {lineSelection && mdViewMode !== 'preview' && (