1
This commit is contained in:
@@ -68,15 +68,19 @@ function Section({
|
||||
badge,
|
||||
actions,
|
||||
children,
|
||||
className = '',
|
||||
}: {
|
||||
title: string;
|
||||
subtitle?: string;
|
||||
badge?: ReactNode;
|
||||
actions?: ReactNode;
|
||||
children: ReactNode;
|
||||
className?: string;
|
||||
}) {
|
||||
return (
|
||||
<div className="platform-surface platform-surface--soft px-3.5 py-3">
|
||||
<div
|
||||
className={`platform-surface platform-surface--soft px-3.5 py-3 ${className}`}
|
||||
>
|
||||
<div className="flex items-start justify-between gap-3">
|
||||
<div className="min-w-0">
|
||||
<div className="text-xs font-bold tracking-[0.16em] text-white">
|
||||
@@ -220,9 +224,7 @@ function PendingEntityCard({
|
||||
<div className="text-sm font-semibold text-[var(--platform-text-strong)]">
|
||||
{title}
|
||||
</div>
|
||||
<div className="mt-1 text-xs leading-6">
|
||||
{phaseLabel}
|
||||
</div>
|
||||
<div className="mt-1 text-xs leading-6">{phaseLabel}</div>
|
||||
</div>
|
||||
<div className="platform-pill platform-pill--cool px-2.5 py-1 text-[10px]">
|
||||
{Math.round(progress)}%
|
||||
@@ -286,9 +288,11 @@ function buildSceneChapterSearchText(
|
||||
}
|
||||
|
||||
function buildSceneTaskDescriptionText(sceneChapters: SceneChapterBlueprint[]) {
|
||||
return compactTextList(
|
||||
sceneChapters.map((chapter) => chapter.sceneTaskDescription),
|
||||
)[0] ?? '';
|
||||
return (
|
||||
compactTextList(
|
||||
sceneChapters.map((chapter) => chapter.sceneTaskDescription),
|
||||
)[0] ?? ''
|
||||
);
|
||||
}
|
||||
|
||||
function SceneActPreviewStrip({
|
||||
@@ -364,9 +368,7 @@ function CatalogCard({
|
||||
onClick={disabled ? undefined : onClick}
|
||||
aria-disabled={disabled}
|
||||
className={`w-full rounded-[1.3rem] border p-2.5 text-left transition-colors xl:p-3 ${
|
||||
isSelected
|
||||
? 'border-rose-300/35 bg-rose-500/10'
|
||||
: 'platform-subpanel'
|
||||
isSelected ? 'border-rose-300/35 bg-rose-500/10' : 'platform-subpanel'
|
||||
}`}
|
||||
>
|
||||
<div className="flex items-start gap-3 xl:gap-3.5">
|
||||
@@ -388,7 +390,9 @@ function CatalogCard({
|
||||
<div className="mt-1.5 text-sm leading-5 text-zinc-300 xl:line-clamp-2">
|
||||
{description || '暂无描述'}
|
||||
</div>
|
||||
{actions ? <div className="mt-2 flex flex-wrap gap-2">{actions}</div> : null}
|
||||
{actions ? (
|
||||
<div className="mt-2 flex flex-wrap gap-2">{actions}</div>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -402,9 +406,7 @@ function CatalogCard({
|
||||
onClick={disabled ? undefined : onClick}
|
||||
aria-disabled={disabled}
|
||||
className={`w-full rounded-[1.4rem] border p-3 text-left transition-colors ${
|
||||
isSelected
|
||||
? 'border-rose-300/35 bg-rose-500/10'
|
||||
: 'platform-subpanel'
|
||||
isSelected ? 'border-rose-300/35 bg-rose-500/10' : 'platform-subpanel'
|
||||
}`}
|
||||
>
|
||||
<div className="space-y-3">
|
||||
@@ -816,17 +818,19 @@ export function CustomWorldEntityCatalog({
|
||||
return (
|
||||
<div
|
||||
ref={scrollContainerRef}
|
||||
className="h-full min-h-0 space-y-3 overflow-y-auto overscroll-contain pr-1 scrollbar-hide xl:space-y-4 xl:pr-2"
|
||||
className="h-full min-h-0 space-y-3 overflow-y-auto overscroll-contain pr-1 scrollbar-hide xl:space-y-4 xl:pr-2 2xl:space-y-5 2xl:pr-3"
|
||||
>
|
||||
<div className="px-1 pb-1 text-center xl:rounded-[2rem] xl:border xl:border-[var(--platform-subpanel-border)] xl:bg-white/55 xl:px-6 xl:py-4 xl:text-left xl:shadow-[0_18px_70px_rgba(255,79,139,0.08)] xl:backdrop-blur-sm">
|
||||
<div className="px-1 pb-1 text-center xl:flex xl:items-end xl:justify-between xl:gap-6 xl:rounded-[2rem] xl:border xl:border-[var(--platform-subpanel-border)] xl:bg-white/55 xl:px-6 xl:py-3 xl:text-left xl:shadow-[0_18px_70px_rgba(255,79,139,0.08)] xl:backdrop-blur-sm 2xl:px-7">
|
||||
<div className="text-[11px] font-bold tracking-[0.28em] text-zinc-500">
|
||||
世界档案
|
||||
</div>
|
||||
<div className="mt-2 text-3xl font-black text-[var(--platform-text-strong)] sm:text-[2.2rem] xl:mt-1 xl:text-[2rem]">
|
||||
{profile.name}
|
||||
</div>
|
||||
<div className="mt-2 text-sm tracking-[0.18em] text-zinc-400 xl:mt-1 xl:text-xs">
|
||||
{profile.subtitle}
|
||||
<div className="min-w-0 xl:flex xl:flex-1 xl:items-end xl:justify-between xl:gap-5">
|
||||
<div className="mt-2 truncate text-3xl font-black text-[var(--platform-text-strong)] sm:text-[2.2rem] xl:mt-0 xl:text-[2rem] 2xl:text-[2.25rem]">
|
||||
{profile.name}
|
||||
</div>
|
||||
<div className="mt-2 min-w-0 text-sm tracking-[0.18em] text-zinc-400 xl:mt-0 xl:max-w-[34rem] xl:truncate xl:text-right xl:text-xs">
|
||||
{profile.subtitle}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -898,7 +902,7 @@ export function CustomWorldEntityCatalog({
|
||||
</div>
|
||||
|
||||
{activeTab === 'world' ? (
|
||||
<div className="space-y-3 xl:grid xl:grid-cols-[0.8fr_1.2fr] xl:items-start xl:gap-3 xl:space-y-0">
|
||||
<div className="space-y-3 xl:grid xl:grid-cols-[minmax(18rem,0.82fr)_minmax(0,1fr)_minmax(24rem,1.08fr)] xl:items-start xl:gap-3 xl:space-y-0 2xl:gap-4">
|
||||
<Section title="档案规模">
|
||||
<div className="grid grid-cols-3 gap-2 text-center text-[11px] text-zinc-300">
|
||||
<div className="platform-subpanel rounded-xl px-2 py-3">
|
||||
@@ -926,7 +930,7 @@ export function CustomWorldEntityCatalog({
|
||||
title="角色维度"
|
||||
subtitle={profile.attributeSchema?.schemaName}
|
||||
>
|
||||
<div className="grid grid-cols-2 gap-2 sm:grid-cols-3">
|
||||
<div className="grid grid-cols-2 gap-2 sm:grid-cols-3 xl:grid-cols-2 2xl:grid-cols-3">
|
||||
{attributeSlots.map((slot) => (
|
||||
<div
|
||||
key={slot.slotId}
|
||||
@@ -963,19 +967,20 @@ export function CustomWorldEntityCatalog({
|
||||
)
|
||||
}
|
||||
>
|
||||
<div className="space-y-3 text-sm leading-7 text-zinc-300">
|
||||
<p>{profile.summary}</p>
|
||||
<div className="platform-banner platform-banner--warning rounded-2xl px-3 py-3">
|
||||
主线目标:{profile.playerGoal}
|
||||
</div>
|
||||
<div className="platform-subpanel rounded-2xl px-3 py-3">
|
||||
世界基调:{profile.tone}
|
||||
</div>
|
||||
<div className="space-y-3 text-sm leading-7 text-zinc-300">
|
||||
<p>{profile.summary}</p>
|
||||
<div className="platform-banner platform-banner--warning rounded-2xl px-3 py-3">
|
||||
主线目标:{profile.playerGoal}
|
||||
</div>
|
||||
<div className="platform-subpanel rounded-2xl px-3 py-3">
|
||||
世界基调:{profile.tone}
|
||||
</div>
|
||||
</div>
|
||||
</Section>
|
||||
|
||||
<Section
|
||||
title="基本设定"
|
||||
className="xl:col-span-3"
|
||||
actions={
|
||||
readOnly ? (
|
||||
<SmallButton
|
||||
@@ -1006,14 +1011,16 @@ export function CustomWorldEntityCatalog({
|
||||
</div>
|
||||
{entry.value ? (
|
||||
<div className="mt-3 flex flex-wrap gap-2">
|
||||
{parseFoundationTagText(entry.value).map((tag, index) => (
|
||||
<span
|
||||
key={`${entry.id}-${index}-${tag}`}
|
||||
className="rounded-full border border-white/10 bg-white/[0.06] px-3 py-1 text-xs leading-5 text-zinc-100"
|
||||
>
|
||||
{tag}
|
||||
</span>
|
||||
))}
|
||||
{parseFoundationTagText(entry.value).map(
|
||||
(tag, index) => (
|
||||
<span
|
||||
key={`${entry.id}-${index}-${tag}`}
|
||||
className="rounded-full border border-white/10 bg-white/[0.06] px-3 py-1 text-xs leading-5 text-zinc-100"
|
||||
>
|
||||
{tag}
|
||||
</span>
|
||||
),
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<div className="mt-2 text-sm leading-7 text-zinc-100">
|
||||
@@ -1029,7 +1036,7 @@ export function CustomWorldEntityCatalog({
|
||||
) : null}
|
||||
|
||||
{activeTab === 'playable' ? (
|
||||
<div className="space-y-3 xl:grid xl:grid-cols-2 xl:gap-3 xl:space-y-0 2xl:grid-cols-3">
|
||||
<div className="space-y-3 xl:grid xl:grid-cols-3 xl:gap-3 xl:space-y-0 2xl:grid-cols-4 2xl:gap-4">
|
||||
{pendingGeneratedEntity?.kind === 'playable' ? (
|
||||
<PendingEntityCard
|
||||
title={pendingGeneratedEntity.title}
|
||||
@@ -1060,7 +1067,9 @@ export function CustomWorldEntityCatalog({
|
||||
<CatalogCard
|
||||
title={role.name}
|
||||
description={description || '暂无描述'}
|
||||
badge={recentPlayableIdSet.has(role.id) ? <NewBadge /> : null}
|
||||
badge={
|
||||
recentPlayableIdSet.has(role.id) ? <NewBadge /> : null
|
||||
}
|
||||
isSelectionMode={false}
|
||||
isSelected={false}
|
||||
layout="compact"
|
||||
@@ -1093,9 +1102,9 @@ export function CustomWorldEntityCatalog({
|
||||
className="h-full w-full object-cover object-top"
|
||||
/>
|
||||
) : (
|
||||
<div className="flex h-full w-full items-center justify-center bg-[rgba(255,255,255,0.64)] px-3 text-center text-xs font-semibold tracking-[0.16em] text-[var(--platform-text-soft)]">
|
||||
{role.name.slice(0, 4) || '角色'}
|
||||
</div>
|
||||
<div className="flex h-full w-full items-center justify-center bg-[rgba(255,255,255,0.64)] px-3 text-center text-xs font-semibold tracking-[0.16em] text-[var(--platform-text-soft)]">
|
||||
{role.name.slice(0, 4) || '角色'}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
/>
|
||||
@@ -1140,7 +1149,7 @@ export function CustomWorldEntityCatalog({
|
||||
) : null}
|
||||
|
||||
{activeTab === 'story' ? (
|
||||
<div className="space-y-3 xl:grid xl:grid-cols-2 xl:gap-3 xl:space-y-0 2xl:grid-cols-3">
|
||||
<div className="space-y-3 xl:grid xl:grid-cols-3 xl:gap-3 xl:space-y-0 2xl:grid-cols-4 2xl:gap-4">
|
||||
{pendingGeneratedEntity?.kind === 'story' ? (
|
||||
<PendingEntityCard
|
||||
title={pendingGeneratedEntity.title}
|
||||
@@ -1200,7 +1209,7 @@ export function CustomWorldEntityCatalog({
|
||||
) : null}
|
||||
|
||||
{activeTab === 'landmarks' ? (
|
||||
<div className="space-y-3 xl:grid xl:grid-cols-2 xl:gap-3 xl:space-y-0 2xl:grid-cols-3">
|
||||
<div className="space-y-3 xl:grid xl:grid-cols-3 xl:gap-3 xl:space-y-0 2xl:grid-cols-4 2xl:gap-4">
|
||||
{pendingGeneratedEntity?.kind === 'landmark' ? (
|
||||
<PendingEntityCard
|
||||
title={pendingGeneratedEntity.title}
|
||||
@@ -1218,16 +1227,15 @@ export function CustomWorldEntityCatalog({
|
||||
`scene-entry-${index}-${scene.name.trim() || scene.kind}`,
|
||||
)}
|
||||
title={scene.name}
|
||||
description={
|
||||
compactTextList([
|
||||
scene.kind === 'camp'
|
||||
? `开局场景 · ${scene.description}`
|
||||
: scene.description,
|
||||
scene.sceneTaskDescription,
|
||||
]).join(' / ')
|
||||
}
|
||||
description={compactTextList([
|
||||
scene.kind === 'camp'
|
||||
? `开局场景 · ${scene.description}`
|
||||
: scene.description,
|
||||
scene.sceneTaskDescription,
|
||||
]).join(' / ')}
|
||||
badge={
|
||||
scene.kind === 'landmark' && recentLandmarkIdSet.has(scene.id) ? (
|
||||
scene.kind === 'landmark' &&
|
||||
recentLandmarkIdSet.has(scene.id) ? (
|
||||
<NewBadge />
|
||||
) : null
|
||||
}
|
||||
@@ -1270,4 +1278,3 @@ export function CustomWorldEntityCatalog({
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user