diff --git a/apps/ai-game-creator-shell/src/view/project-development/index.tsx b/apps/ai-game-creator-shell/src/view/project-development/index.tsx index 043f8f3cf..617f24059 100644 --- a/apps/ai-game-creator-shell/src/view/project-development/index.tsx +++ b/apps/ai-game-creator-shell/src/view/project-development/index.tsx @@ -112,6 +112,7 @@ import { zoomResourceBookViewport, } from './resourceBookViewport'; import { + createResourceCanvasPageCategorySignature, createResourceCanvasPageWheelState, queueResourceCanvasPageWheel, resetResourceCanvasPageWheel, @@ -1826,11 +1827,11 @@ export default function ProjectDevelopmentView({ }); }, [resourceCategoryScopeKey]); const resourcePageCategoryKey = useMemo( - () => canvasResources.map((resource) => resource.category).join('|'), + () => createResourceCanvasPageCategorySignature(canvasResources), [canvasResources], ); const resourcePageCategories = useMemo( - () => (resourcePageCategoryKey ? visibleCategoryOrder : []), + () => (resourcePageCategoryKey ? [...visibleCategoryOrder] : []), [resourcePageCategoryKey], ); const activePageCategory = diff --git a/apps/ai-game-creator-shell/src/view/project-development/resourceCanvasController.ts b/apps/ai-game-creator-shell/src/view/project-development/resourceCanvasController.ts index 8a7432f3b..d2789348b 100644 --- a/apps/ai-game-creator-shell/src/view/project-development/resourceCanvasController.ts +++ b/apps/ai-game-creator-shell/src/view/project-development/resourceCanvasController.ts @@ -6,6 +6,15 @@ export type ResourceCanvasPageWheelState = { pendingTimerId: number | null; }; +export function createResourceCanvasPageCategorySignature< + TCategory extends string, +>(resources: readonly { category: TCategory }[]) { + return resources + .map((resource) => resource.category) + .sort() + .join('|'); +} + export function createResourceCanvasPageWheelState< TCategory, >(): ResourceCanvasPageWheelState { diff --git a/apps/ai-game-creator-shell/tests/appSurface/project-development.suite.ts b/apps/ai-game-creator-shell/tests/appSurface/project-development.suite.ts index 0367f8af8..cacfa4d36 100644 --- a/apps/ai-game-creator-shell/tests/appSurface/project-development.suite.ts +++ b/apps/ai-game-creator-shell/tests/appSurface/project-development.suite.ts @@ -1315,7 +1315,7 @@ export function registerProjectWorkbenchFoundationTests() { }); }); - it('renders an imported image as a resource-canvas card after manifest refresh', async () => { + it('refreshes resource pages when a same-count manifest update changes category', async () => { const manifest = createGameCreationAppManifest( 'workbench-imported-image-canvas', '导入图片资源画布测试', @@ -1385,7 +1385,6 @@ export function registerProjectWorkbenchFoundationTests() { const refreshedManifest = { ...manifest, assets: [ - ...manifest.assets, { id: 'imported-image', kind: 'ui', @@ -1398,6 +1397,7 @@ export function registerProjectWorkbenchFoundationTests() { }, ], }; + expect(refreshedManifest.assets).toHaveLength(manifest.assets.length); rendered.rerender( React.createElement(ProjectDevelopmentView, { ...viewProps, diff --git a/apps/ai-game-creator-shell/tests/resourceCanvasController.test.ts b/apps/ai-game-creator-shell/tests/resourceCanvasController.test.ts index 2a76877a0..213a94388 100644 --- a/apps/ai-game-creator-shell/tests/resourceCanvasController.test.ts +++ b/apps/ai-game-creator-shell/tests/resourceCanvasController.test.ts @@ -1,6 +1,7 @@ import { describe, expect, it } from 'vitest'; import { + createResourceCanvasPageCategorySignature, createResourceCanvasPageWheelState, queueResourceCanvasPageWheel, resetResourceCanvasPageWheel, @@ -8,6 +9,19 @@ import { } from '../src/view/project-development/resourceCanvasController'; describe('resource canvas page wheel controller', () => { + it('invalidates page categories for same-count category changes without reacting to resource order', () => { + const original = [{ category: 'document' }, { category: 'art' }]; + const reordered = [...original].reverse(); + const changed = [{ category: 'document' }, { category: 'audio' }]; + + expect(createResourceCanvasPageCategorySignature(reordered)).toBe( + createResourceCanvasPageCategorySignature(original), + ); + expect(createResourceCanvasPageCategorySignature(changed)).not.toBe( + createResourceCanvasPageCategorySignature(original), + ); + }); + it('keeps the 20px threshold and converts wheel deltas into page steps', () => { const state = createResourceCanvasPageWheelState<'document'>(); queueResourceCanvasPageWheel(state, {