This commit is contained in:
2026-05-08 11:44:42 +08:00
parent b08127031c
commit abf1f1ebea
249 changed files with 39411 additions and 887 deletions

View File

@@ -14,6 +14,8 @@ export interface PlatformEntryCreationTypeModalProps {
onSelectMatch3D: () => void;
onSelectSquareHole: () => void;
onSelectPuzzle: () => void;
onSelectCreativeAgent: () => void;
onSelectVisualNovel: () => void;
}
function CreationTypeCard(props: {
@@ -29,31 +31,44 @@ function CreationTypeCard(props: {
type="button"
disabled={disabled}
onClick={onSelect}
className={`platform-interactive-card relative flex min-h-[8.25rem] flex-col overflow-hidden rounded-[1.65rem] border px-4 py-4 text-left ${
className={`platform-creation-reference-card platform-interactive-card relative flex min-h-[10rem] flex-col overflow-hidden rounded-[1.65rem] border p-0 text-left ${
item.locked
? 'cursor-not-allowed border-[var(--platform-subpanel-border)] bg-[var(--platform-subpanel-fill)] text-[var(--platform-text-soft)]'
: 'border-[var(--platform-cool-border)] bg-[radial-gradient(circle_at_top_left,rgba(255,255,255,0.24),transparent_34%),linear-gradient(135deg,rgba(255,79,139,0.96),rgba(255,145,110,0.9))] text-white'
? 'cursor-not-allowed border-[var(--platform-subpanel-border)] bg-[var(--platform-subpanel-fill)] text-white'
: 'border-[var(--platform-cool-border)] bg-white text-white'
} ${busy && !item.locked ? 'opacity-70' : ''}`}
>
<div className="flex min-h-6 items-start justify-end gap-3">
<img
src={item.imageSrc}
alt=""
className="absolute inset-0 h-full w-full object-cover"
loading="lazy"
/>
<div
className={`absolute inset-0 ${
item.locked
? 'bg-[linear-gradient(180deg,rgba(3,7,18,0.1)_0%,rgba(3,7,18,0.22)_42%,rgba(3,7,18,0.84)_100%)] backdrop-blur-[1px]'
: 'bg-[linear-gradient(180deg,rgba(3,7,18,0.03)_0%,rgba(3,7,18,0.16)_42%,rgba(3,7,18,0.82)_100%)]'
}`}
/>
<div className="relative z-10 flex min-h-6 items-start justify-end gap-3 px-4 pt-4">
{item.locked ? (
<span className="platform-pill platform-pill--neutral px-3 text-[var(--platform-text-soft)]">
{item.badge}
</span>
) : null}
{item.locked ? (
<span className="text-lg leading-none text-white/45">·</span>
<span className="text-lg leading-none text-white/62">·</span>
) : (
<ArrowRight className="h-4 w-4 text-white/80" />
)}
</div>
<div className="mt-auto pt-4">
<div className="text-xl font-black leading-tight text-inherit">
<div className="relative z-10 mt-auto px-4 pb-4 pt-8 text-white [text-shadow:0_1px_8px_rgba(0,0,0,0.78)]">
<div className="text-xl font-black leading-tight text-white">
{item.title}
</div>
<div
className={`mt-2 text-sm ${
item.locked ? 'text-zinc-500' : 'text-zinc-200/82'
item.locked ? 'text-white/74' : 'text-white/88'
}`}
>
{item.subtitle}
@@ -77,6 +92,8 @@ export function PlatformEntryCreationTypeModal({
onSelectMatch3D,
onSelectSquareHole,
onSelectPuzzle,
onSelectCreativeAgent,
onSelectVisualNovel,
}: PlatformEntryCreationTypeModalProps) {
if (!isOpen) {
return null;
@@ -117,6 +134,12 @@ export function PlatformEntryCreationTypeModal({
if (item.id === 'puzzle') {
onSelectPuzzle();
}
if (item.id === 'creative-agent') {
onSelectCreativeAgent();
}
if (item.id === 'visual-novel') {
onSelectVisualNovel();
}
}}
/>
))}

File diff suppressed because it is too large Load Diff

View File

@@ -63,6 +63,9 @@ function getSourceLabel(entry: PlatformPublicGalleryCard) {
if ('sourceType' in entry && entry.sourceType === 'square-hole') {
return '方洞挑战';
}
if ('sourceType' in entry && entry.sourceType === 'visual-novel') {
return '视觉小说';
}
return 'RPG';
}

View File

@@ -23,6 +23,7 @@ test('platform creation types are derived from new work entry config', () => {
title: puzzleConfig?.title,
subtitle: puzzleConfig?.subtitle,
badge: puzzleConfig?.badge,
imageSrc: puzzleConfig?.imageSrc,
locked: false,
hidden: false,
}),
@@ -30,30 +31,34 @@ test('platform creation types are derived from new work entry config', () => {
expect(PLATFORM_CREATION_TYPES).toContainEqual(
expect.objectContaining({
id: 'match3d',
title: '抓大鹅',
subtitle: '经典消除玩法',
title: match3dConfig?.title,
subtitle: match3dConfig?.subtitle,
badge: match3dConfig?.badge,
imageSrc: match3dConfig?.imageSrc,
locked: false,
hidden: false,
hidden: !match3dConfig?.visible,
}),
);
});
test('every platform creation type has a generated reference image', () => {
expect(
NEW_WORK_ENTRY_CONFIG.creationTypes.every((item) =>
item.imageSrc.startsWith('/creation-type-references/'),
),
).toBe(true);
});
test('new work entry config controls visibility and open order', () => {
const visibleIds = getVisiblePlatformCreationTypes().map((item) => item.id);
expect(isPlatformCreationTypeVisible('rpg')).toBe(false);
expect(isPlatformCreationTypeVisible('big-fish')).toBe(false);
expect(isPlatformCreationTypeVisible('match3d')).toBe(true);
expect(isPlatformCreationTypeVisible('match3d')).toBe(false);
expect(isPlatformCreationTypeVisible('creative-agent')).toBe(false);
expect(visibleIds).not.toContain('rpg');
expect(visibleIds).not.toContain('big-fish');
expect(visibleIds).toContain('match3d');
expect(visibleIds[0]).toBe('puzzle');
expect(visibleIds).toEqual([
'puzzle',
'match3d',
'square-hole',
'airp',
'visual-novel',
]);
expect(visibleIds).not.toContain('match3d');
expect(visibleIds).not.toContain('creative-agent');
expect(visibleIds).toEqual(['puzzle', 'square-hole', 'visual-novel', 'airp']);
});

View File

@@ -10,6 +10,7 @@ export type PlatformCreationTypeCard = {
title: string;
subtitle: string;
badge: string;
imageSrc: string;
locked: boolean;
hidden?: boolean;
};
@@ -47,6 +48,7 @@ export const PLATFORM_CREATION_TYPES: PlatformCreationTypeCard[] =
title: item.title,
subtitle: item.subtitle,
badge: item.badge,
imageSrc: item.imageSrc,
locked: !item.open,
hidden: !item.visible,
}));

View File

@@ -29,6 +29,11 @@ export type SelectionStage =
| 'square-hole-generating'
| 'square-hole-result'
| 'square-hole-runtime'
| 'creative-agent-workspace'
| 'visual-novel-agent-workspace'
| 'visual-novel-result'
| 'visual-novel-gallery-detail'
| 'visual-novel-runtime'
| 'puzzle-agent-workspace'
| 'puzzle-generating'
| 'puzzle-onboarding'