mirror of
				https://github.com/zadam/trilium.git
				synced 2025-11-03 20:06:08 +01:00 
			
		
		
		
	chore(react/type_widget): more generic repositioning
This commit is contained in:
		@@ -4,6 +4,8 @@ import SplitEditor, { PreviewButton, SplitEditorProps } from "./SplitEditor";
 | 
				
			|||||||
import { RawHtmlBlock } from "../../react/RawHtml";
 | 
					import { RawHtmlBlock } from "../../react/RawHtml";
 | 
				
			||||||
import server from "../../../services/server";
 | 
					import server from "../../../services/server";
 | 
				
			||||||
import svgPanZoom, { zoomIn } from "svg-pan-zoom";
 | 
					import svgPanZoom, { zoomIn } from "svg-pan-zoom";
 | 
				
			||||||
 | 
					import { RefObject } from "preact";
 | 
				
			||||||
 | 
					import { useElementSize } from "../../react/hooks";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface SvgSplitEditorProps extends Omit<SplitEditorProps, "previewContent"> {
 | 
					interface SvgSplitEditorProps extends Omit<SplitEditorProps, "previewContent"> {
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@@ -53,37 +55,7 @@ export default function SvgSplitEditor({ note, attachmentName, renderSvg, ...pro
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Pan & zoom.
 | 
					    // Pan & zoom.
 | 
				
			||||||
    const lastPanZoom = useRef<{ pan: SvgPanZoom.Point, zoom: number }>();
 | 
					    useResizer(containerRef, note.noteId, svg);
 | 
				
			||||||
    const lastNoteId = useRef<string>();
 | 
					 | 
				
			||||||
    const zoomRef = useRef<SvgPanZoom.Instance>();
 | 
					 | 
				
			||||||
    useEffect(() => {
 | 
					 | 
				
			||||||
        const shouldPreservePanZoom = (lastNoteId.current === note.noteId);
 | 
					 | 
				
			||||||
        const svgEl = containerRef.current?.querySelector("svg");
 | 
					 | 
				
			||||||
        if (!svgEl) return;
 | 
					 | 
				
			||||||
        const zoomInstance = svgPanZoom(svgEl, {
 | 
					 | 
				
			||||||
            zoomEnabled: true,
 | 
					 | 
				
			||||||
            controlIconsEnabled: false
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Restore the previous pan/zoom if the user updates same note.
 | 
					 | 
				
			||||||
        if (shouldPreservePanZoom && lastPanZoom.current) {
 | 
					 | 
				
			||||||
            zoomInstance.zoom(lastPanZoom.current.zoom);
 | 
					 | 
				
			||||||
            zoomInstance.pan(lastPanZoom.current.pan);
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            zoomInstance.resize().center().fit();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        lastNoteId.current = note.noteId;
 | 
					 | 
				
			||||||
        zoomRef.current = zoomInstance;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return () => {
 | 
					 | 
				
			||||||
            lastPanZoom.current = {
 | 
					 | 
				
			||||||
                pan: zoomInstance.getPan(),
 | 
					 | 
				
			||||||
                zoom: zoomInstance.getZoom()
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            zoomInstance.destroy();
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
    }, [ svg ]);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
        <SplitEditor
 | 
					        <SplitEditor
 | 
				
			||||||
@@ -92,12 +64,6 @@ export default function SvgSplitEditor({ note, attachmentName, renderSvg, ...pro
 | 
				
			|||||||
            error={error}
 | 
					            error={error}
 | 
				
			||||||
            onContentChanged={onContentChanged}
 | 
					            onContentChanged={onContentChanged}
 | 
				
			||||||
            dataSaved={onSave}
 | 
					            dataSaved={onSave}
 | 
				
			||||||
            splitOptions={{
 | 
					 | 
				
			||||||
                onDrag: () => {
 | 
					 | 
				
			||||||
                    if (!zoomRef.current) return;
 | 
					 | 
				
			||||||
                    zoomRef.current.resize().fit().center();
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }}
 | 
					 | 
				
			||||||
            previewContent={(
 | 
					            previewContent={(
 | 
				
			||||||
                <RawHtmlBlock
 | 
					                <RawHtmlBlock
 | 
				
			||||||
                    className="render-container"
 | 
					                    className="render-container"
 | 
				
			||||||
@@ -126,3 +92,46 @@ export default function SvgSplitEditor({ note, attachmentName, renderSvg, ...pro
 | 
				
			|||||||
        />
 | 
					        />
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function useResizer(containerRef: RefObject<HTMLDivElement>, noteId: string, svg: string | undefined) {
 | 
				
			||||||
 | 
					    const lastPanZoom = useRef<{ pan: SvgPanZoom.Point, zoom: number }>();
 | 
				
			||||||
 | 
					    const lastNoteId = useRef<string>();
 | 
				
			||||||
 | 
					    const zoomRef = useRef<SvgPanZoom.Instance>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Set up pan & zoom.
 | 
				
			||||||
 | 
					    useEffect(() => {
 | 
				
			||||||
 | 
					        const shouldPreservePanZoom = (lastNoteId.current === noteId);
 | 
				
			||||||
 | 
					        const svgEl = containerRef.current?.querySelector("svg");
 | 
				
			||||||
 | 
					        if (!svgEl) return;
 | 
				
			||||||
 | 
					        const zoomInstance = svgPanZoom(svgEl, {
 | 
				
			||||||
 | 
					            zoomEnabled: true,
 | 
				
			||||||
 | 
					            controlIconsEnabled: false
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Restore the previous pan/zoom if the user updates same note.
 | 
				
			||||||
 | 
					        if (shouldPreservePanZoom && lastPanZoom.current) {
 | 
				
			||||||
 | 
					            zoomInstance.zoom(lastPanZoom.current.zoom);
 | 
				
			||||||
 | 
					            zoomInstance.pan(lastPanZoom.current.pan);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            zoomInstance.resize().center().fit();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        lastNoteId.current = noteId;
 | 
				
			||||||
 | 
					        zoomRef.current = zoomInstance;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return () => {
 | 
				
			||||||
 | 
					            lastPanZoom.current = {
 | 
				
			||||||
 | 
					                pan: zoomInstance.getPan(),
 | 
				
			||||||
 | 
					                zoom: zoomInstance.getZoom()
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            zoomInstance.destroy();
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					    }, [ svg ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // React to container changes.
 | 
				
			||||||
 | 
					    const width = useElementSize(containerRef);
 | 
				
			||||||
 | 
					    useEffect(() => {
 | 
				
			||||||
 | 
					        if (!zoomRef.current) return;
 | 
				
			||||||
 | 
					        zoomRef.current.resize().fit().center();
 | 
				
			||||||
 | 
					    }, [ width ]);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user