Frame initial canvas loading around direct members

This commit is contained in:
2026-11-10 17:10:49 +08:00
parent 786453cce0
commit b735667e00
2 changed files with 13 additions and 1 deletions
+5
View File
@@ -892,3 +892,8 @@ valid ACK. Unknown fields/components/versions, unresolved requests and run/asset
receipts stay raw. Existing stored raw receipts are not migrated by this policy.
The recovery envelope remains unchanged: receipts are opaque JSON, and the
adapter-local summary has its own version and explicit replay rejection.
The application's initial loading fit targets the current canvas's direct node
members, including partition entries. Expanded descendant cards remain rendered
and pannable but cannot move their parent entry outside the initial viewport.
The manual fit control keeps its existing whole-scene behavior.
@@ -55,7 +55,14 @@ function CanvasView({ engine, board, viewId, renderers,fitLoading=true }: { engi
if (liveView) lastView.current = liveView;
const view = liveView ?? lastView.current!, flow = useReactFlow<ProjectionNode>();
const canCreate=!loading||loading.version>=4&&engine.editor.getQueries(root.document).coverage.completeCanvasIds.includes(view.canvasId);
useEffect(()=>{if(!needsLoadingFit.current||!flow.viewportInitialized||!root.document.elements.size)return;needsLoadingFit.current=false;void flow.fitView({padding:.2,maxZoom:1});},[flow,root.document]);
useEffect(()=>{
if(!needsLoadingFit.current||!flow.viewportInitialized||!root.document.canvases.has(view.canvasId))return;
// Expanded descendants can extend far beyond their partition entry. Initial
// framing belongs to the direct members of this canvas.
const nodes=engine.editor.getQueries(root.document).members(view.canvasId).filter(id=>root.document.elements.get(id)?.structure==='node').map(id=>({id}));
if(!nodes.length)return;
needsLoadingFit.current=false;void flow.fitView({nodes,padding:.2,maxZoom:1});
},[engine,flow,root.document,view.canvasId]);
const preparingCopy = [...(root.runtime.imports?.values() ?? [])].some(job => job.status === 'preparing' && job.source?.targetCanvasId === view.canvasId);
const [editorFocused, setEditorFocused] = useState(false), focusEpoch = useRef(0);
useEffect(() => { focusEpoch.current++; setEditorFocused(false); return () => { focusEpoch.current++; }; }, [engine,viewId]);