Files
Genarrative/apps/ai-game-creator-shell/src/view/project-development/ResourceRenameDialog.tsx
T
suzmii d1581892d7 修复 PR #316 review(前端 TS/TSX):资源工作台与资源画布
- 素材重命名(跨范围契约):`rename_local_project_asset` 现在要求 `expectedProjectId` + `expectedProjectRevision`,前端按删除 / 分类保存同一套 CAS 口径补齐——先 `get_local_game_project_revision` 读当前 revision 再连同项目身份提交,不用可能过期的本地缓存值
- 失败文案统一:新增 `projectAssetCommandErrorMessage`,把 `project-identity-conflict` / `project-revision-conflict` 翻成用户可读中文,重命名 / 删除 / 分类保存三条链路共用一份映射,其余错误原样透出
- index.tsx:资源面板下载按 `resolveDownloadablePanelEntries` 过滤,版本卡这类合成 path 的条目不再进入落盘链路
- index.tsx:`characterAnimationPanel` 纳入画布浮层开关判据(抽 `resolveResourceCanvasFloatingPanelOpen`),「生成动画」面板与快速编辑 / 信息浮层共用同一条「点外部 / Esc 关闭」规则
- index.tsx:去掉 `ResourceBookScene` 上重复的 `onWheel`,滚轮只由 manager 上的原生 `passive:false` 监听处理,平移 / 缩放不再被翻倍
- index.tsx:快速编辑的源资源在层 id 命中不到时回落到已正规化的 `asset:<id>`,重试不再静默什么都不做;取不到时给出可见失败
- ResourceCanvasPanelView.tsx:下载按钮按可下载条数判可用、不再在上传中显示下载转圈;上传中禁掉 × / Esc / 遮罩三条关闭路径;预览占位文案抽 helper
- GameRunVersionPicker.tsx:portal 菜单在滚动 / 缩放后重算位置;外部点击判定沿用共享 `useImageCanvasFloatingOptionDismiss` + `menuRef` 边界(review 该条已修,保留现状并补位置用例)
- ResourceCanvasGenerationPanelView.tsx:`submitting` 改 `finally` 收回,成功路径不再永久锁住面板
- ResourceAssetDeleteDialog.tsx / ResourceRenameDialog.tsx / ResourceClassificationPanel.tsx:在飞时 `closeOnEscape` / `closeOnBackdrop` 与头部 × 一起挡住
- resourceEditModel.ts / resourceCanvasToolbarModel.ts / useProjectResourceCardPreviews.ts / projectResourceLiveUpdateModel.ts:抽 `resourceBaseName`、`canonicalProjectedResourceMediaType` 参数收窄去掉强转、删未使用参数、补「IO 失败会 reject」的签名说明
- resourceCanvasHistoryModel.ts:`resourceCanvasSnapshotsEqual` 不再比较不可恢复的 `manuallyPlaced`,消除「压进历史但撤销是空操作」
- resourceCanvasSectionMapping.ts:删掉从未接线、且注释与实现相矛盾的 `LEGACY_RESOURCE_CANVAS_SECTION_FALLBACK`
- resourceCanvasChrome.css:`.game-resource-panel-grid` 补 `flex: 1 1 auto; min-height: 0`,卡片网格成为真正的滚动区
- 用例:重命名 CAS 载荷与读序、CAS 拒绝文案、版本卡下载门禁、上传中关闭路径、浮层判据、菜单跟随滚动、分区映射
2026-09-12 20:49:03 +08:00

108 lines
3.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { useState } from 'react';
import { PlatformActionButton } from '../../../../../packages/shared/src/components/PlatformActionButton';
import { PlatformTextField } from '../../../../../packages/shared/src/components/PlatformTextField';
import type { GameCreationAppAssetManifestEntry } from '../../../../../packages/shared/src/contracts/gameCreationApp';
import { ThemedModal } from '../../components/modal/ThemedModal';
export type RenameLocalProjectAssetResult = {
asset: GameCreationAppAssetManifestEntry;
previousLocalPath: string;
committedProjectRevision: number;
};
function assetFileName(localPath: string) {
return localPath.split(/[\\/]/u).pop() ?? localPath;
}
type ResourceRenameDialogProps = {
open: boolean;
asset: GameCreationAppAssetManifestEntry;
renaming: boolean;
error: string | null;
onClose: () => void;
onConfirm: (newFileName: string) => void;
};
/**
* 素材重命名面板。
*
* 只输入新文件名:目录由资产的 `localPath` 决定,用户不能换目录;
* 扩展名一致、同名冲突等规则由 Rust 侧 `rename_local_project_asset` 强校验,
* 这里只做输入与错误呈现。
*/
export function ResourceRenameDialog({
open,
asset,
renaming,
error,
onClose,
onConfirm,
}: ResourceRenameDialogProps) {
const [draft, setDraft] = useState(() => assetFileName(asset.localPath));
return (
<ThemedModal
open={open}
ariaLabel="重命名素材"
onClose={onClose}
// 重命名在飞时头部 × / 取消 / 重命名都已禁用,Escape 与遮罩也必须一起挡住,
// 保持同一个"在飞不可关闭"的判据。
closeOnBackdrop={!renaming}
closeOnEscape={!renaming}
panelClassName="game-approval-dialog game-resource-rename-dialog"
>
<header>
<div>
<h2>重命名素材</h2>
<p>{asset.localPath}</p>
</div>
<button
type="button"
aria-label="关闭重命名素材"
onClick={onClose}
disabled={renaming}
>
×
</button>
</header>
<div className="game-resource-rename-body">
<PlatformTextField
aria-label="新文件名"
value={draft}
disabled={renaming}
autoFocus
onChange={(event) => setDraft(event.currentTarget.value)}
onKeyDown={(event) => {
if (event.key === 'Enter' && !renaming && draft.trim() !== '') {
event.preventDefault();
onConfirm(draft);
}
}}
/>
{error ? (
<p className="game-resource-rename-error" role="alert">
{error}
</p>
) : null}
</div>
<footer>
<PlatformActionButton
tone="secondary"
onClick={onClose}
disabled={renaming}
>
取消
</PlatformActionButton>
<PlatformActionButton
aria-label="确认重命名素材"
onClick={() => onConfirm(draft)}
disabled={renaming || draft.trim() === ''}
>
重命名
</PlatformActionButton>
</footer>
</ThemedModal>
);
}