fix(ai): make section-fill cleanup page-aware for non-first pages

Follow-up on 36eb7c0. finalizePageRootAfterApply looked up the page
root via getNodeById(DEFAULT_FRAME_ID), which only works for Page 1 —
every subsequent page created via addPage() gets a fresh nanoid for its
root frame, so the lookup returned undefined and the cleanup was
silently a no-op on pages 2..N.

Rewrite the helper to read the active page's top-level children via
getActivePageChildren(doc, activePageId) and run
stripRedundantSectionFills on each top-level frame. Publishes once if
anything changed. Handles multi-root pages (comparison mockups, etc.)
by iterating. Still a no-op when the active page has no frame children
yet, which is the safe first-insert behavior.
This commit is contained in:
Fini 2026-04-06 18:34:51 +08:00
parent 36eb7c0f7d
commit 8d0a481718

View file

@ -341,19 +341,29 @@ export function insertStreamingNode(node: PenNode, parentId: string | null): voi
* or external MCP callers hedge with on section roots (they hide the real
* page background and break theming).
*
* This helper targets DEFAULT_FRAME_ID the canonical page root frame
* so it always honours the stripRedundantSectionFills scope contract
* regardless of what the caller actually inserted (a full page, a set of
* sections, or a single card). If the page root does not exist yet (first
* insert before any root frame was created), there is nothing to strip
* and the helper is a no-op.
* OpenPencil documents are multi-page only the FIRST page uses the
* constant DEFAULT_FRAME_ID for its root frame. Pages added later via
* addPage() receive a fresh nanoid, so we cannot look the page root up by
* a well-known id. Instead we pull the active page's top-level children
* and run stripRedundantSectionFills on every top-level frame we find.
* In the common case that's a single page-root frame; edge cases with
* multiple top-level frames on one page (comparison mockups, etc.) are
* handled by iterating. Publishes once if any frame was modified.
*/
function finalizePageRootAfterApply(): void {
const pageRoot = useDocumentStore.getState().getNodeById(DEFAULT_FRAME_ID);
if (!pageRoot || pageRoot.type !== 'frame') return;
if (stripRedundantSectionFills(pageRoot)) {
forcePageResync();
const doc = useDocumentStore.getState().document;
const activePageId = useCanvasStore.getState().activePageId;
const topLevel = getActivePageChildren(doc, activePageId);
if (!topLevel || topLevel.length === 0) return;
let anyChanged = false;
for (const node of topLevel) {
if (node.type !== 'frame') continue;
if (stripRedundantSectionFills(node)) {
anyChanged = true;
}
}
if (anyChanged) forcePageResync();
}
export function applyNodesToCanvas(nodes: PenNode[]): void {