This commit is contained in:
2026-04-23 06:01:00 +08:00
parent 9dc56f0fc0
commit f6046ef658
123 changed files with 7752 additions and 436 deletions

View File

@@ -16,6 +16,7 @@ import type {
BigFishSessionSnapshotResponse,
ExecuteBigFishActionRequest,
} from '../../../packages/shared/src/contracts/bigFish';
import { ResolvedAssetImage } from '../ResolvedAssetImage';
type BigFishAssetStudioTarget =
| {
@@ -61,7 +62,10 @@ function findAssetSlot(
}
function assetReadyLabel(slot: BigFishAssetSlotResponse | undefined) {
return slot?.status === 'ready' ? '已生成' : '待生成';
if (slot?.status !== 'ready') {
return '待生成';
}
return isBigFishPlaceholderAsset(slot) ? '占位已生成' : '已生成';
}
function buildLevelAssetPreview(slot: BigFishAssetSlotResponse | undefined) {
@@ -71,15 +75,43 @@ function buildLevelAssetPreview(slot: BigFishAssetSlotResponse | undefined) {
return null;
}
function isBigFishPlaceholderAsset(slot: BigFishAssetSlotResponse | undefined) {
return Boolean(slot?.assetUrl?.includes('/generated-big-fish/'));
}
function buildStudioAssetPreview(
slots: BigFishAssetSlotResponse[],
target: BigFishAssetStudioTarget,
) {
if (target.kind === 'stage_background') {
return buildLevelAssetPreview(findAssetSlot(slots, 'stage_background'));
}
if (target.kind === 'level_main_image') {
return buildLevelAssetPreview(
findAssetSlot(slots, 'level_main_image', target.level.level),
);
}
return buildLevelAssetPreview(
findAssetSlot(
slots,
'level_motion',
target.level.level,
target.motionKey,
),
);
}
function BigFishAssetStudioModal({
draft,
target,
previewUrl,
isBusy,
onClose,
onExecuteAction,
}: {
draft: BigFishGameDraftResponse;
target: BigFishAssetStudioTarget;
previewUrl?: string | null;
isBusy: boolean;
onClose: () => void;
onExecuteAction: (payload: ExecuteBigFishActionRequest) => void;
@@ -140,8 +172,16 @@ function BigFishAssetStudioModal({
{prompt}
</div>
</div>
<div className="flex aspect-[9/5] items-center justify-center rounded-[1.4rem] border border-dashed border-cyan-300/50 bg-cyan-50/40 text-sm text-[var(--platform-text-base)]">
AI
<div className="flex aspect-[9/5] items-center justify-center overflow-hidden rounded-[1.4rem] border border-dashed border-cyan-300/50 bg-cyan-50/40 text-sm text-[var(--platform-text-base)]">
{previewUrl ? (
<ResolvedAssetImage
src={previewUrl}
alt={title}
className="h-full w-full object-cover"
/>
) : (
'AI 资产候选预览'
)}
</div>
</div>
<div className="flex justify-end gap-2 border-t border-[var(--platform-subpanel-border)] px-4 py-4">
@@ -160,7 +200,7 @@ function BigFishAssetStudioModal({
className="inline-flex items-center gap-2 rounded-full bg-cyan-600 px-4 py-2 text-sm font-bold text-white disabled:opacity-45"
>
{isBusy ? <Loader2 className="h-4 w-4 animate-spin" /> : null}
</button>
</div>
</div>
@@ -203,7 +243,7 @@ function BigFishLevelCard({
<div className="flex gap-3 p-3">
<div className="flex h-24 w-24 shrink-0 items-center justify-center overflow-hidden rounded-[1.15rem] bg-[radial-gradient(circle_at_center,rgba(34,211,238,0.28),transparent_68%),linear-gradient(145deg,rgba(8,47,73,0.88),rgba(15,23,42,0.94))] text-white">
{previewUrl ? (
<img
<ResolvedAssetImage
src={previewUrl}
alt={level.name}
className="h-full w-full object-cover"
@@ -297,10 +337,17 @@ export function BigFishResultView({
useState<BigFishAssetStudioTarget | null>(null);
const draft = session.draft;
const backgroundSlot = findAssetSlot(session.assetSlots, 'stage_background');
const backgroundPreviewUrl = buildLevelAssetPreview(backgroundSlot);
const blockers = useMemo(
() => session.assetCoverage.blockers.filter(Boolean),
[session.assetCoverage.blockers],
);
const studioPreviewUrl = useMemo(() => {
if (!studioTarget) {
return null;
}
return buildStudioAssetPreview(session.assetSlots, studioTarget);
}, [session.assetSlots, studioTarget]);
if (!draft) {
return (
@@ -404,7 +451,15 @@ export function BigFishResultView({
</div>
<ImagePlus className="h-5 w-5 text-cyan-600" />
</div>
<div className="mt-3 aspect-[9/16] rounded-[1.2rem] bg-[radial-gradient(circle_at_center,rgba(34,211,238,0.2),transparent_62%),linear-gradient(180deg,rgba(8,47,73,0.88),rgba(15,23,42,0.94))]" />
<div className="mt-3 aspect-[9/16] overflow-hidden rounded-[1.2rem] bg-[radial-gradient(circle_at_center,rgba(34,211,238,0.2),transparent_62%),linear-gradient(180deg,rgba(8,47,73,0.88),rgba(15,23,42,0.94))]">
{backgroundPreviewUrl ? (
<ResolvedAssetImage
src={backgroundPreviewUrl}
alt={`${draft.background.theme} 场地背景`}
className="h-full w-full object-cover"
/>
) : null}
</div>
<button
type="button"
disabled={isBusy}
@@ -454,6 +509,7 @@ export function BigFishResultView({
<BigFishAssetStudioModal
draft={draft}
target={studioTarget}
previewUrl={studioPreviewUrl}
isBusy={isBusy}
onClose={() => {
setStudioTarget(null);