Update spacetime-client bindings and frontend
Large update across server and web clients: regenerated/added many spacetime-client module bindings and input types (including new delete/work_delete input types and numerous procedure/reducer files), updates to server-rs API modules (bark_battle, jump_hop, wooden_fish, auth, module-runtime and shared contracts), and fixes in module-runtime behavior and domain logic. Frontend changes include new/updated components and tests (creative audio helpers, bark-battle/jump-hop/wooden-fish clients and views, unified generation pages, RPG entry views, and runtime shells), plus CSS and service updates. Documentation and operational notes updated (.hermes pitfalls and multiple PRD/docs) to cover daily-task refresh, banner asset fallback, recommend-key bug, and other platform behaviors. Tests and verification steps added/updated alongside these changes.
This commit is contained in:
@@ -97,33 +97,18 @@ function resolveCurrentGenerationStep(
|
||||
);
|
||||
}
|
||||
|
||||
function buildFallbackRenderKey(
|
||||
value: string | null | undefined,
|
||||
fallback: string,
|
||||
) {
|
||||
const normalizedValue = value?.trim();
|
||||
return normalizedValue ? normalizedValue : fallback;
|
||||
}
|
||||
|
||||
export function CustomWorldGenerationView({
|
||||
settingText,
|
||||
anchorEntries = [],
|
||||
progress,
|
||||
isGenerating,
|
||||
onBack,
|
||||
onEditSetting,
|
||||
onRetry,
|
||||
onInterrupt,
|
||||
backLabel = '返回',
|
||||
settingActionLabel = '修改设定',
|
||||
retryLabel = '重新开始生成',
|
||||
interruptLabel = '中断世界生成',
|
||||
settingTitle = '玩家设定',
|
||||
settingDescription = '这段文本会直接驱动本轮世界框架、角色与场景生成。',
|
||||
progressTitle = '生成进度',
|
||||
activeBadgeLabel = '世界建设中',
|
||||
idleBadgeLabel = '等待操作',
|
||||
structuredEmptyText = '正在整理当前设定结构,请稍后。',
|
||||
hideBatchModule = false,
|
||||
}: CustomWorldGenerationViewProps) {
|
||||
void hideBatchModule;
|
||||
@@ -138,12 +123,6 @@ export function CustomWorldGenerationView({
|
||||
: isGenerating
|
||||
? '进行中'
|
||||
: '待处理';
|
||||
const hasStructuredAnchors = anchorEntries.length > 0;
|
||||
// 允许不同生成场景按需隐藏第二模块的说明和次级返回动作。
|
||||
const normalizedSettingActionLabel = settingActionLabel?.trim() ?? '';
|
||||
const normalizedSettingDescription = settingDescription?.trim() ?? '';
|
||||
const hasSettingActionLabel = normalizedSettingActionLabel.length > 0;
|
||||
const hasSettingDescription = normalizedSettingDescription.length > 0;
|
||||
const estimatedWaitText =
|
||||
progress?.estimatedRemainingMs != null
|
||||
? formatDuration(progress.estimatedRemainingMs)
|
||||
@@ -153,11 +132,10 @@ export function CustomWorldGenerationView({
|
||||
|
||||
return (
|
||||
<div
|
||||
className="relative isolate z-[1] -mx-3 -my-3 flex h-[calc(100%+1.5rem)] min-h-0 flex-col overflow-y-auto overscroll-y-contain bg-transparent px-4 pb-[max(1.25rem,env(safe-area-inset-bottom))] pt-4 text-[#3d1f10] sm:mx-0 sm:my-0 sm:h-full sm:rounded-[2rem] sm:px-5 sm:pt-5"
|
||||
style={{ WebkitOverflowScrolling: 'touch' }}
|
||||
className="relative isolate z-[1] -mx-3 -my-3 flex h-[calc(100%+1.5rem)] min-h-0 flex-col overflow-hidden bg-transparent px-4 pb-[max(1.25rem,env(safe-area-inset-bottom))] pt-4 text-[#3d1f10] sm:mx-0 sm:my-0 sm:h-full sm:rounded-[2rem] sm:px-5 sm:pt-5"
|
||||
>
|
||||
<GenerationPageBackdrop />
|
||||
<div className="relative z-10 mb-6 flex shrink-0 items-center justify-between gap-3 py-2 sm:mb-6">
|
||||
<div className="relative z-30 mb-4 flex shrink-0 items-center justify-between gap-3 py-2 sm:mb-5">
|
||||
<button
|
||||
type="button"
|
||||
onClick={onBack}
|
||||
@@ -171,7 +149,10 @@ export function CustomWorldGenerationView({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="relative z-10 flex flex-none flex-col gap-4">
|
||||
<div
|
||||
className="relative z-10 flex min-h-0 flex-1 flex-col overflow-y-auto overscroll-y-contain"
|
||||
style={{ WebkitOverflowScrolling: 'touch' }}
|
||||
>
|
||||
<section className="overflow-hidden px-0 pb-2 pt-0 sm:px-0">
|
||||
<GenerationProgressHero
|
||||
title={progressTitle}
|
||||
@@ -181,7 +162,7 @@ export function CustomWorldGenerationView({
|
||||
elapsedText={elapsedText}
|
||||
/>
|
||||
|
||||
<div className="mt-[-0.15rem] px-0 sm:px-0">
|
||||
<div className="mt-5 px-0 sm:mt-[-0.15rem] sm:px-0">
|
||||
<GenerationCurrentStepCard
|
||||
label={currentStepLabel}
|
||||
statusLabel={currentStepStatusLabel}
|
||||
@@ -191,24 +172,13 @@ export function CustomWorldGenerationView({
|
||||
|
||||
<div className="mt-4 flex flex-col gap-3 sm:flex-row sm:flex-wrap sm:justify-end">
|
||||
{!isGenerating ? (
|
||||
<>
|
||||
{hasSettingActionLabel ? (
|
||||
<button
|
||||
type="button"
|
||||
onClick={onEditSetting}
|
||||
className="platform-button platform-button--ghost min-h-0 rounded-full px-4 py-2 text-sm"
|
||||
>
|
||||
{normalizedSettingActionLabel}
|
||||
</button>
|
||||
) : null}
|
||||
<button
|
||||
type="button"
|
||||
onClick={onRetry}
|
||||
className="platform-button platform-button--primary w-full sm:w-auto"
|
||||
>
|
||||
{retryLabel}
|
||||
</button>
|
||||
</>
|
||||
<button
|
||||
type="button"
|
||||
onClick={onRetry}
|
||||
className="platform-button platform-button--primary w-full sm:w-auto"
|
||||
>
|
||||
{retryLabel}
|
||||
</button>
|
||||
) : onInterrupt ? (
|
||||
<button
|
||||
type="button"
|
||||
@@ -220,55 +190,6 @@ export function CustomWorldGenerationView({
|
||||
) : null}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="overflow-hidden rounded-[1.75rem] border border-[#eadcd1] bg-[rgba(255,250,246,0.92)] px-4 py-4 shadow-[0_20px_56px_rgba(112,57,30,0.08)] backdrop-blur-[5px] sm:px-5 sm:py-5">
|
||||
<div className="mb-4 flex items-start justify-between gap-3">
|
||||
<div className="min-w-0">
|
||||
<div className="text-[13px] font-black tracking-[0.08em] text-[#111111]">
|
||||
{settingTitle}
|
||||
</div>
|
||||
{hasSettingDescription ? (
|
||||
<div className="mt-2 text-[13px] leading-6 text-[#7e6656]">
|
||||
{normalizedSettingDescription}
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
{hasSettingActionLabel ? (
|
||||
<button
|
||||
type="button"
|
||||
onClick={onEditSetting}
|
||||
disabled={isGenerating}
|
||||
className={`platform-button platform-button--ghost min-h-0 px-3 py-1.5 text-[11px] ${isGenerating ? 'cursor-not-allowed opacity-40' : ''}`}
|
||||
>
|
||||
{normalizedSettingActionLabel}
|
||||
</button>
|
||||
) : null}
|
||||
</div>
|
||||
{hasStructuredAnchors ? (
|
||||
<div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
|
||||
{anchorEntries.map((entry, index) => (
|
||||
<div
|
||||
key={buildFallbackRenderKey(
|
||||
entry.id,
|
||||
`anchor-entry-${index}`,
|
||||
)}
|
||||
className="rounded-[1.15rem] border border-[#ead6c7] bg-white/74 px-4 py-4"
|
||||
>
|
||||
<div className="text-[9px] font-bold tracking-[0.12em] text-[#8e6f5d] sm:text-[10px]">
|
||||
{entry.label}
|
||||
</div>
|
||||
<div className="mt-2 whitespace-pre-line text-[13px] leading-7 text-[#111111]">
|
||||
{entry.value}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<div className="whitespace-pre-line rounded-[1.15rem] border border-[#ead6c7] bg-white/74 px-4 py-4 text-[13px] leading-7 text-[#111111] md:max-h-[16rem] md:overflow-y-auto">
|
||||
{settingText || structuredEmptyText}
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user