@@ -51,7 +51,7 @@ const MIN_LOGGER_HEIGHT = 100;
5151const PREVIEW_INITIAL_SCALE = 1 ;
5252const PREVIEW_MIN_SCALE = 0.25 ;
5353const PREVIEW_MAX_SCALE = 5 ;
54- const PREVIEW_ZOOM_STEP = 0.25 ;
54+ const PREVIEW_ZOOM_STEP = 0.05 ;
5555
5656const isElectron = ! ! window . electronAPI ;
5757
@@ -231,10 +231,12 @@ export const MainApp: React.FC = () => {
231231 const [ isRestoringActiveDocument , setIsRestoringActiveDocument ] = useState ( true ) ;
232232 const [ hasRestoredActiveDocument , setHasRestoredActiveDocument ] = useState ( false ) ;
233233 const [ previewScale , setPreviewScale ] = useState ( PREVIEW_INITIAL_SCALE ) ;
234+ const [ editorScale , setEditorScale ] = useState ( PREVIEW_INITIAL_SCALE ) ;
234235 const [ previewResetSignal , setPreviewResetSignal ] = useState ( 0 ) ;
235236 const [ isPreviewVisible , setIsPreviewVisible ] = useState ( false ) ;
236237 const [ isPreviewZoomReady , setIsPreviewZoomReady ] = useState ( false ) ;
237238 const [ previewMetadata , setPreviewMetadata ] = useState < PreviewMetadata | null > ( null ) ;
239+ const [ workspaceZoomTarget , setWorkspaceZoomTarget ] = useState < 'preview' | 'editor' > ( 'editor' ) ;
238240
239241 useEffect ( ( ) => {
240242 if ( ! isPreviewVisible ) {
@@ -252,25 +254,41 @@ export const MainApp: React.FC = () => {
252254 const openDocumentIds = tabState . order ;
253255 const storedActiveDocumentIdRef = useRef < string | null > ( null ) ;
254256
255- const clampPreviewScale = useCallback ( ( value : number ) => {
257+ const clampZoomScale = useCallback ( ( value : number ) => {
256258 return Math . min ( Math . max ( value , PREVIEW_MIN_SCALE ) , PREVIEW_MAX_SCALE ) ;
257259 } , [ ] ) ;
258260
259261 const handlePreviewScaleChange = useCallback ( ( value : number ) => {
260- setPreviewScale ( clampPreviewScale ( value ) ) ;
261- } , [ clampPreviewScale ] ) ;
262+ setPreviewScale ( clampZoomScale ( value ) ) ;
263+ } , [ clampZoomScale ] ) ;
262264
263265 const handlePreviewZoomIn = useCallback ( ( ) => {
264- setPreviewScale ( prev => clampPreviewScale ( prev * ( 1 + PREVIEW_ZOOM_STEP ) ) ) ;
265- } , [ clampPreviewScale ] ) ;
266+ if ( workspaceZoomTarget === 'preview' ) {
267+ setPreviewScale ( prev => clampZoomScale ( prev + PREVIEW_ZOOM_STEP ) ) ;
268+ } else {
269+ setEditorScale ( prev => clampZoomScale ( prev + PREVIEW_ZOOM_STEP ) ) ;
270+ }
271+ } , [ clampZoomScale , workspaceZoomTarget ] ) ;
266272
267273 const handlePreviewZoomOut = useCallback ( ( ) => {
268- setPreviewScale ( prev => clampPreviewScale ( prev / ( 1 + PREVIEW_ZOOM_STEP ) ) ) ;
269- } , [ clampPreviewScale ] ) ;
274+ if ( workspaceZoomTarget === 'preview' ) {
275+ setPreviewScale ( prev => clampZoomScale ( prev - PREVIEW_ZOOM_STEP ) ) ;
276+ } else {
277+ setEditorScale ( prev => clampZoomScale ( prev - PREVIEW_ZOOM_STEP ) ) ;
278+ }
279+ } , [ clampZoomScale , workspaceZoomTarget ] ) ;
270280
271281 const handlePreviewReset = useCallback ( ( ) => {
272- setPreviewScale ( PREVIEW_INITIAL_SCALE ) ;
273- setPreviewResetSignal ( prev => prev + 1 ) ;
282+ if ( workspaceZoomTarget === 'preview' ) {
283+ setPreviewScale ( PREVIEW_INITIAL_SCALE ) ;
284+ setPreviewResetSignal ( prev => prev + 1 ) ;
285+ } else {
286+ setEditorScale ( PREVIEW_INITIAL_SCALE ) ;
287+ }
288+ } , [ workspaceZoomTarget ] ) ;
289+
290+ const handleWorkspaceZoomTargetChange = useCallback ( ( target : 'preview' | 'editor' ) => {
291+ setWorkspaceZoomTarget ( target ) ;
274292 } , [ ] ) ;
275293
276294 const activateDocumentTab = useCallback ( ( documentId : string ) => {
@@ -483,11 +501,39 @@ export const MainApp: React.FC = () => {
483501 }
484502 } , [ activeDocument ] ) ;
485503
504+ const previewZoomAvailable = useMemo ( ( ) => {
505+ if ( view === 'info' ) {
506+ return true ;
507+ }
508+ return isPreviewVisible && isPreviewZoomReady ;
509+ } , [ isPreviewVisible , isPreviewZoomReady , view ] ) ;
510+
511+ const editorZoomAvailable = useMemo ( ( ) => {
512+ return view === 'editor' && documentView === 'editor' && Boolean ( activeDocument ) ;
513+ } , [ activeDocument , documentView , view ] ) ;
514+
515+ useEffect ( ( ) => {
516+ if ( workspaceZoomTarget === 'preview' && ! previewZoomAvailable && editorZoomAvailable ) {
517+ setWorkspaceZoomTarget ( 'editor' ) ;
518+ } else if ( workspaceZoomTarget === 'editor' && ! editorZoomAvailable && previewZoomAvailable ) {
519+ setWorkspaceZoomTarget ( 'preview' ) ;
520+ }
521+ } , [ editorZoomAvailable , previewZoomAvailable , workspaceZoomTarget ] ) ;
522+
523+ const isWorkspaceZoomAvailable = useMemo ( ( ) => {
524+ return workspaceZoomTarget === 'preview' ? previewZoomAvailable : editorZoomAvailable ;
525+ } , [ editorZoomAvailable , previewZoomAvailable , workspaceZoomTarget ] ) ;
526+
527+ const workspaceZoomScale = useMemo ( ( ) => {
528+ return workspaceZoomTarget === 'preview' ? previewScale : editorScale ;
529+ } , [ editorScale , previewScale , workspaceZoomTarget ] ) ;
530+
486531 const documentItems = useMemo ( ( ) => items . filter ( item => item . type === 'document' ) , [ items ] ) ;
487532 const activeDocumentId = activeDocument ?. id ?? null ;
488533
489534 useEffect ( ( ) => {
490535 setPreviewScale ( PREVIEW_INITIAL_SCALE ) ;
536+ setEditorScale ( PREVIEW_INITIAL_SCALE ) ;
491537 setPreviewResetSignal ( prev => prev + 1 ) ;
492538 } , [ activeNode ?. id , activeNode ?. type ] ) ;
493539
@@ -2802,7 +2848,7 @@ export const MainApp: React.FC = () => {
28022848 return (
28032849 < InfoView
28042850 settings = { settings }
2805- previewScale = { previewScale }
2851+ previewScale = { workspaceZoomScale }
28062852 onPreviewScaleChange = { handlePreviewScaleChange }
28072853 previewZoomOptions = { {
28082854 minScale : PREVIEW_MIN_SCALE ,
@@ -2813,6 +2859,7 @@ export const MainApp: React.FC = () => {
28132859 previewResetSignal = { previewResetSignal }
28142860 onPreviewVisibilityChange = { setIsPreviewVisible }
28152861 onPreviewZoomAvailabilityChange = { setIsPreviewZoomReady }
2862+ onZoomTargetChange = { handleWorkspaceZoomTargetChange }
28162863 />
28172864 ) ;
28182865 }
@@ -2852,6 +2899,7 @@ export const MainApp: React.FC = () => {
28522899 onToggleLock = { ( locked ) => handleSetNodeLockState ( activeNode . id , locked ) }
28532900 formatTrigger = { formatTrigger }
28542901 previewScale = { previewScale }
2902+ editorScale = { editorScale }
28552903 onPreviewScaleChange = { handlePreviewScaleChange }
28562904 previewMinScale = { PREVIEW_MIN_SCALE }
28572905 previewMaxScale = { PREVIEW_MAX_SCALE }
@@ -2861,6 +2909,7 @@ export const MainApp: React.FC = () => {
28612909 onPreviewVisibilityChange = { setIsPreviewVisible }
28622910 onPreviewZoomAvailabilityChange = { setIsPreviewZoomReady }
28632911 onPreviewMetadataChange = { setPreviewMetadata }
2912+ onZoomTargetChange = { handleWorkspaceZoomTargetChange }
28642913 />
28652914 ) ;
28662915 }
@@ -3045,15 +3094,16 @@ export const MainApp: React.FC = () => {
30453094 databaseStatus = { databaseStatus }
30463095 onDatabaseMenu = { handleDatabaseMenu }
30473096 onOpenAbout = { handleOpenAbout }
3048- previewScale = { previewScale }
3097+ previewScale = { workspaceZoomScale }
30493098 onPreviewZoomIn = { handlePreviewZoomIn }
30503099 onPreviewZoomOut = { handlePreviewZoomOut }
30513100 onPreviewReset = { handlePreviewReset }
3052- isPreviewZoomAvailable = { isPreviewVisible && isPreviewZoomReady }
3101+ isPreviewZoomAvailable = { isWorkspaceZoomAvailable }
30533102 previewMinScale = { PREVIEW_MIN_SCALE }
30543103 previewMaxScale = { PREVIEW_MAX_SCALE }
30553104 previewInitialScale = { PREVIEW_INITIAL_SCALE }
30563105 previewMetadata = { previewMetadata }
3106+ zoomTarget = { workspaceZoomTarget }
30573107 />
30583108 </ div >
30593109
0 commit comments