This commit is contained in:
2026-05-08 20:48:29 +08:00
parent abf1f1ebea
commit 94975e4735
82 changed files with 7786 additions and 1012 deletions

View File

@@ -47,6 +47,37 @@ function getProgressPercentage(progress: CustomWorldGenerationProgress | null) {
return Math.max(0, Math.min(100, progress?.overallProgress ?? 0));
}
function getStepProgressPercentage(step: {
completed: number;
total: number;
status: string;
}) {
if (step.status === 'completed') {
return 100;
}
if (step.total <= 0) {
return 0;
}
return Math.max(
0,
Math.min(100, Math.round((step.completed / step.total) * 100)),
);
}
function getStepStatusLabel(step: { status: string }) {
if (step.status === 'completed') {
return '完成';
}
if (step.status === 'active') {
return '进行中';
}
return '待处理';
}
function buildFallbackRenderKey(
value: string | null | undefined,
fallback: string,
@@ -177,30 +208,47 @@ export function CustomWorldGenerationView({
</div>
<div className="mt-4 space-y-2 xl:grid xl:min-h-0 xl:flex-1 xl:grid-cols-2 xl:content-start xl:gap-2 xl:space-y-0 xl:overflow-y-auto xl:pr-1">
{steps.map((step, index) => (
<div
key={buildFallbackRenderKey(step.id, `progress-step-${index}`)}
className={`rounded-2xl border px-4 py-3 transition-colors ${
step.status === 'completed'
? 'border-emerald-400/16 bg-emerald-500/8'
: step.status === 'active'
? 'border-sky-300/22 bg-sky-500/10'
: 'platform-subpanel'
}`}
>
<div className="flex items-center justify-between gap-3">
<div className="text-sm font-semibold text-white">
{step.label}
{steps.map((step, index) => {
const stepProgress = getStepProgressPercentage(step);
return (
<div
key={buildFallbackRenderKey(step.id, `progress-step-${index}`)}
className={`rounded-2xl border px-4 py-3 transition-colors ${
step.status === 'completed'
? 'border-emerald-400/16 bg-emerald-500/8'
: step.status === 'active'
? 'border-sky-300/22 bg-sky-500/10'
: 'platform-subpanel'
}`}
>
<div className="flex items-center justify-between gap-3">
<div className="min-w-0 text-sm font-semibold text-white">
{step.label}
</div>
<div className="shrink-0 text-xs font-semibold text-zinc-300">
{getStepStatusLabel(step)} {stepProgress}%
</div>
</div>
<div className="text-xs text-zinc-300">
{step.completed}/{step.total}
<div className="mt-2 h-2 overflow-hidden rounded-full bg-white/8">
<motion.div
className={`h-full rounded-full ${
step.status === 'completed'
? 'bg-emerald-300'
: step.status === 'active'
? 'bg-[linear-gradient(90deg,#7dd3fc_0%,#fcd34d_100%)]'
: 'bg-white/18'
}`}
animate={{ width: `${stepProgress}%` }}
transition={{ duration: 0.45, ease: 'easeOut' }}
/>
</div>
<div className="mt-2 text-xs leading-6 text-zinc-400">
{step.detail}
</div>
</div>
<div className="mt-1 text-xs leading-6 text-zinc-400">
{step.detail}
</div>
</div>
))}
);
})}
</div>
{error ? (