移除资源画布顶部手动生成入口
删除资源画布顶部的生成视频、生成音效、生成背景音乐和新增 UI 设计按钮 移除仅服务于这些入口的前端 handler 与入口配置 保留 Agent 语义生成、已有资源编辑、生成动画和未完成任务恢复能力 补充顶部入口消失与画布级操作保留的定向回归测试 同步更新 AGC 配置白名单、技术方案与项目决策记录
This commit is contained in:
@@ -127,6 +127,7 @@ const rustSharedContractSource = fs.readFileSync(
|
||||
const allowedUncalledTauriCommands = [
|
||||
'chat_with_game_creator_agent',
|
||||
'check_ui_editor_font_glyph_coverage',
|
||||
'create_ui_design_resource',
|
||||
'open_game_creator_launcher_window',
|
||||
'open_game_creator_workspace_window',
|
||||
];
|
||||
@@ -1547,13 +1548,11 @@ if (!viteConfigSource.includes('allow: [repoRoot]')) {
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
!(
|
||||
tauriConfig.build?.beforeDevCommand?.includes(
|
||||
'run ai-game-creator-shell:dev-server',
|
||||
) || tauriConfig.build?.beforeDevCommand?.includes('run agc:serve')
|
||||
)
|
||||
) {
|
||||
if (!(
|
||||
tauriConfig.build?.beforeDevCommand?.includes(
|
||||
'run ai-game-creator-shell:dev-server',
|
||||
) || tauriConfig.build?.beforeDevCommand?.includes('run agc:serve')
|
||||
)) {
|
||||
throw new Error(
|
||||
'AI game creator shell beforeDevCommand must start the selected Vite dev server',
|
||||
);
|
||||
|
||||
@@ -106,8 +106,6 @@ import {
|
||||
type ProjectResourceEditCapability,
|
||||
resolveProjectCharacterAnimationCapability,
|
||||
resolveProjectResourceEditCapability,
|
||||
type ResourceGenerationKind,
|
||||
resourceGenerationOptions,
|
||||
} from './resourceEditModel';
|
||||
import {
|
||||
type ResourceEditSubmitInput,
|
||||
@@ -213,12 +211,6 @@ type UiEditorRoute = {
|
||||
resourceLabel: string;
|
||||
};
|
||||
|
||||
type CreateUiDesignResourceResult = {
|
||||
asset: { id: string };
|
||||
manifest: GameCreationAppManifest;
|
||||
committedProjectRevision: number;
|
||||
};
|
||||
|
||||
type DeriveLocalProjectResourceResult = {
|
||||
operationId: string;
|
||||
sourceResourceId: string;
|
||||
@@ -1606,8 +1598,7 @@ export default function ProjectDevelopmentView({
|
||||
}
|
||||
const viewport = resolveViewport(event);
|
||||
const category = viewport?.dataset.resourceSectionScroll as
|
||||
| ResourceCategory
|
||||
| undefined;
|
||||
ResourceCategory | undefined;
|
||||
if (!viewport || !category) {
|
||||
return;
|
||||
}
|
||||
@@ -1626,8 +1617,7 @@ export default function ProjectDevelopmentView({
|
||||
const event = rawEvent as WebKitGestureEvent;
|
||||
const viewport = resolveViewport(event);
|
||||
const category = viewport?.dataset.resourceSectionScroll as
|
||||
| ResourceCategory
|
||||
| undefined;
|
||||
ResourceCategory | undefined;
|
||||
if (!viewport || !category) {
|
||||
return;
|
||||
}
|
||||
@@ -1739,8 +1729,7 @@ export default function ProjectDevelopmentView({
|
||||
.querySelectorAll<HTMLElement>('[data-resource-section-scroll]')
|
||||
.forEach((viewport) => {
|
||||
const category = viewport.dataset.resourceSectionScroll as
|
||||
| ResourceCategory
|
||||
| undefined;
|
||||
ResourceCategory | undefined;
|
||||
if (!category) {
|
||||
return;
|
||||
}
|
||||
@@ -1760,8 +1749,7 @@ export default function ProjectDevelopmentView({
|
||||
?.querySelectorAll<HTMLElement>('[data-resource-section-scroll]')
|
||||
.forEach((viewport) => {
|
||||
const category = viewport.dataset.resourceSectionScroll as
|
||||
| ResourceCategory
|
||||
| undefined;
|
||||
ResourceCategory | undefined;
|
||||
if (!category) {
|
||||
return;
|
||||
}
|
||||
@@ -2258,34 +2246,6 @@ export default function ProjectDevelopmentView({
|
||||
],
|
||||
);
|
||||
|
||||
const createUiDesignResource = useCallback(async () => {
|
||||
const invoke = window.__TAURI__?.core?.invoke;
|
||||
if (!invoke) {
|
||||
setAssetCanvasNotice('UI 设计资源需要在客户端内创建');
|
||||
return;
|
||||
}
|
||||
setAssetCanvasNotice('正在创建 UI 设计…');
|
||||
try {
|
||||
const result = await invoke<CreateUiDesignResourceResult>(
|
||||
'create_ui_design_resource',
|
||||
{ projectPath, expectedProjectId: manifest.projectId },
|
||||
);
|
||||
if (result.manifest.projectId !== manifest.projectId) {
|
||||
throw new Error('UI 设计资源登记结果与当前项目不一致');
|
||||
}
|
||||
onManifestChange?.(projectPath, result.manifest, {
|
||||
projectId: result.manifest.projectId,
|
||||
revision: result.committedProjectRevision,
|
||||
source: 'asset-command',
|
||||
});
|
||||
setAssetCanvasNotice('UI 设计已创建,正在同步资源与布局…');
|
||||
} catch (error) {
|
||||
setAssetCanvasNotice(
|
||||
error instanceof Error ? error.message : String(error),
|
||||
);
|
||||
}
|
||||
}, [manifest.projectId, onManifestChange, projectPath]);
|
||||
|
||||
const resetResourceCanvasViewport = useCallback(() => {
|
||||
const canvasSize = resourceCanvasElementSize(resourceCanvasRef.current);
|
||||
setConstrainedResourceCanvasViewport(
|
||||
@@ -2635,39 +2595,6 @@ export default function ProjectDevelopmentView({
|
||||
[advanceFocusGeneration],
|
||||
);
|
||||
|
||||
const openCreateResource = useCallback(
|
||||
(kind: ResourceGenerationKind) => {
|
||||
canvasOpenEpochRef.current += 1;
|
||||
advanceFocusGeneration();
|
||||
const flowId = crypto.randomUUID();
|
||||
activeFocusFlowIdRef.current = flowId;
|
||||
pendingResourceFocusRef.current = null;
|
||||
setAssetCanvasRoute(null);
|
||||
setAssetCanvasNotice('');
|
||||
const sourceMediaType = kind === 'video' ? 'video/mp4' : 'audio/mpeg';
|
||||
setResourceEditorRoute({
|
||||
flowId,
|
||||
operationId: crypto.randomUUID(),
|
||||
idempotencyKey: crypto.randomUUID(),
|
||||
resource: null,
|
||||
capability: {
|
||||
route: 'derive',
|
||||
editKind: kind,
|
||||
sourceMediaType,
|
||||
semanticNotice:
|
||||
kind === 'background-music'
|
||||
? '将生成全新的背景音乐。'
|
||||
: kind === 'sound-effect'
|
||||
? '将生成全新的音效。'
|
||||
: '将生成全新的视频。',
|
||||
generationMode: 'create',
|
||||
},
|
||||
generationMode: 'create',
|
||||
});
|
||||
},
|
||||
[advanceFocusGeneration],
|
||||
);
|
||||
|
||||
const cancelResourceEditor = useCallback(() => {
|
||||
if (resourceEditorRoute) {
|
||||
resourceEditorRevisionRef.current.delete(resourceEditorRoute.operationId);
|
||||
@@ -3277,16 +3204,16 @@ export default function ProjectDevelopmentView({
|
||||
dependencyLayoutSettled: dependencyLayout.settled,
|
||||
dependencyPositioned: Boolean(
|
||||
intent.resourceId &&
|
||||
dependencyLayout.layout.positions.some(
|
||||
(position) => position.resourceId === intent.resourceId,
|
||||
),
|
||||
dependencyLayout.layout.positions.some(
|
||||
(position) => position.resourceId === intent.resourceId,
|
||||
),
|
||||
),
|
||||
typeLayoutSettled: typeLayout.settled,
|
||||
typePositioned: Boolean(
|
||||
intent.resourceId &&
|
||||
typeLayout.layout.positions.some(
|
||||
(position) => position.resourceId === intent.resourceId,
|
||||
),
|
||||
typeLayout.layout.positions.some(
|
||||
(position) => position.resourceId === intent.resourceId,
|
||||
),
|
||||
),
|
||||
visible: targetVisible,
|
||||
domRendered: Boolean(card),
|
||||
@@ -3457,23 +3384,6 @@ export default function ProjectDevelopmentView({
|
||||
: `管理未完成编辑 (${pendingResourceEdits.length})`}
|
||||
</button>
|
||||
) : null}
|
||||
{resourceGenerationOptions.map((option) => (
|
||||
<button
|
||||
key={option.kind}
|
||||
type="button"
|
||||
onClick={() => openCreateResource(option.kind)}
|
||||
>
|
||||
<Sparkles size={15} aria-hidden="true" />
|
||||
{option.label}
|
||||
</button>
|
||||
))}
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => void createUiDesignResource()}
|
||||
>
|
||||
<Sparkles size={15} aria-hidden="true" />
|
||||
新增 UI 设计
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className={sortMode === 'dependency' ? 'is-active' : ''}
|
||||
|
||||
@@ -32,20 +32,6 @@ export type ProjectResourceEditCapability =
|
||||
generationMode?: 'create' | 'derive';
|
||||
};
|
||||
|
||||
export type ResourceGenerationKind = Exclude<
|
||||
LocalProjectResourceEditKind,
|
||||
'image-reference' | 'svg' | 'text' | 'agent-result' | 'version'
|
||||
>;
|
||||
|
||||
export const resourceGenerationOptions: Array<{
|
||||
kind: ResourceGenerationKind;
|
||||
label: string;
|
||||
}> = [
|
||||
{ kind: 'video', label: '生成视频' },
|
||||
{ kind: 'sound-effect', label: '生成音效' },
|
||||
{ kind: 'background-music', label: '生成背景音乐' },
|
||||
];
|
||||
|
||||
const extensionMediaTypes: Record<string, string> = {
|
||||
png: 'image/png',
|
||||
jpg: 'image/jpeg',
|
||||
|
||||
@@ -1800,6 +1800,14 @@ export function registerProjectWorkbenchFoundationTests() {
|
||||
expect(
|
||||
screen.getByText('美术资源计划已完成,尚未生成或登记图片'),
|
||||
).not.toBeNull();
|
||||
for (const label of [
|
||||
'生成视频',
|
||||
'生成音效',
|
||||
'生成背景音乐',
|
||||
'新增 UI 设计',
|
||||
]) {
|
||||
expect(screen.queryByRole('button', { name: label })).toBeNull();
|
||||
}
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: '按类型' }));
|
||||
const searchInput = screen.getByLabelText(
|
||||
@@ -1855,7 +1863,14 @@ export function registerProjectWorkbenchFoundationTests() {
|
||||
'resources.focused.document',
|
||||
);
|
||||
expect(screen.getByLabelText('搜索项目资源')).not.toBeNull();
|
||||
expect(screen.getByRole('button', { name: '生成视频' })).not.toBeNull();
|
||||
for (const label of [
|
||||
'生成视频',
|
||||
'生成音效',
|
||||
'生成背景音乐',
|
||||
'新增 UI 设计',
|
||||
]) {
|
||||
expect(screen.queryByRole('button', { name: label })).toBeNull();
|
||||
}
|
||||
expect(screen.getByRole('button', { name: '按依赖' })).not.toBeNull();
|
||||
expect(
|
||||
screen
|
||||
@@ -9409,8 +9424,7 @@ export function registerProjectSupervisorSurfaceTests() {
|
||||
projectPath,
|
||||
});
|
||||
let directTurnUpdateHandler:
|
||||
| ((event: { payload: Record<string, unknown> }) => void)
|
||||
| null = null;
|
||||
((event: { payload: Record<string, unknown> }) => void) | null = null;
|
||||
const listen = vi.fn(
|
||||
async (
|
||||
eventName: string,
|
||||
@@ -10368,8 +10382,7 @@ export function registerProjectAgentStatusTests() {
|
||||
},
|
||||
);
|
||||
let runtimeUpdateHandler:
|
||||
| ((event: { payload: Record<string, unknown> }) => void)
|
||||
| null = null;
|
||||
((event: { payload: Record<string, unknown> }) => void) | null = null;
|
||||
const listen = vi.fn(
|
||||
async (
|
||||
eventName: string,
|
||||
|
||||
@@ -700,15 +700,14 @@ describe('project resource live canvas integration', () => {
|
||||
const sourceCard = await screen.findByRole('button', {
|
||||
name: /source-art\.png/,
|
||||
});
|
||||
expect(
|
||||
(
|
||||
screen.getByRole('button', {
|
||||
name: '生成视频',
|
||||
}) as HTMLButtonElement
|
||||
).disabled,
|
||||
).toBe(false);
|
||||
expect(screen.getByRole('button', { name: '生成音效' })).not.toBeNull();
|
||||
expect(screen.getByRole('button', { name: '生成背景音乐' })).not.toBeNull();
|
||||
for (const label of [
|
||||
'生成视频',
|
||||
'生成音效',
|
||||
'生成背景音乐',
|
||||
'新增 UI 设计',
|
||||
]) {
|
||||
expect(screen.queryByRole('button', { name: label })).toBeNull();
|
||||
}
|
||||
fireEvent.click(sourceCard);
|
||||
const sourceDetails = screen.getByRole('dialog', {
|
||||
name: /source-art\.png/,
|
||||
@@ -718,7 +717,14 @@ describe('project resource live canvas integration', () => {
|
||||
);
|
||||
expect(sourceDetails.hasAttribute('aria-modal')).toBe(false);
|
||||
expect(document.querySelector('.game-resource-focus-backdrop')).toBeNull();
|
||||
expect(screen.getByRole('button', { name: '生成视频' })).not.toBeNull();
|
||||
for (const label of [
|
||||
'生成视频',
|
||||
'生成音效',
|
||||
'生成背景音乐',
|
||||
'新增 UI 设计',
|
||||
]) {
|
||||
expect(screen.queryByRole('button', { name: label })).toBeNull();
|
||||
}
|
||||
expect(
|
||||
screen
|
||||
.getByRole('button', { name: '按依赖' })
|
||||
|
||||
@@ -5,7 +5,6 @@ import {
|
||||
resolveProjectCharacterAnimationCapability,
|
||||
resolveProjectResourceEditCapability,
|
||||
resourceEditPromptMaxLength,
|
||||
resourceGenerationOptions,
|
||||
} from '../src/view/project-development/resourceEditModel';
|
||||
import type { ProjectResource } from '../src/view/project-development/resourceProjectionModel';
|
||||
|
||||
@@ -241,12 +240,4 @@ describe('全类型资源编辑能力模型', () => {
|
||||
),
|
||||
).toBeNull();
|
||||
});
|
||||
|
||||
it('资源页提供新建视频、音效和背景音乐入口', () => {
|
||||
expect(resourceGenerationOptions).toEqual([
|
||||
{ kind: 'video', label: '生成视频' },
|
||||
{ kind: 'sound-effect', label: '生成音效' },
|
||||
{ kind: 'background-music', label: '生成背景音乐' },
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user