This commit is contained in:
2026-04-22 22:01:07 +08:00
parent d8716d70b0
commit b317c2a8ea
37 changed files with 1821 additions and 515 deletions

View File

@@ -1,5 +1,7 @@
import { ArrowRight, X } from 'lucide-react';
import { PLATFORM_CREATION_TYPES } from './platformEntryCreationTypes';
export interface PlatformEntryCreationTypeModalProps {
isOpen: boolean;
isBusy: boolean;
@@ -10,54 +12,8 @@ export interface PlatformEntryCreationTypeModalProps {
onSelectPuzzle: () => void;
}
type CreationGameTypeCard = {
id: 'rpg' | 'big-fish' | 'puzzle' | 'airp' | 'visual-novel';
title: string;
subtitle: string;
badge: string;
locked: boolean;
};
const CREATION_GAME_TYPES: CreationGameTypeCard[] = [
{
id: 'rpg',
title: '角色扮演 RPG',
subtitle: 'Agent 共创',
badge: '可创建',
locked: false,
},
{
id: 'big-fish',
title: '大鱼吃小鱼',
subtitle: '实时成长玩法',
badge: '可创建',
locked: false,
},
{
id: 'puzzle',
title: '拼图玩法',
subtitle: '图像锚点共创',
badge: '可创建',
locked: false,
},
{
id: 'airp',
title: 'AIRP',
subtitle: '敬请期待',
badge: '锁定',
locked: true,
},
{
id: 'visual-novel',
title: '视觉小说',
subtitle: '敬请期待',
badge: '锁定',
locked: true,
},
];
function CreationTypeCard(props: {
item: CreationGameTypeCard;
item: (typeof PLATFORM_CREATION_TYPES)[number];
busy: boolean;
onSelect: () => void;
}) {
@@ -147,7 +103,7 @@ export function PlatformEntryCreationTypeModal({
<div className="px-4 py-4 sm:px-5 sm:py-5">
<div className="grid gap-3 sm:grid-cols-5">
{CREATION_GAME_TYPES.map((item) => (
{PLATFORM_CREATION_TYPES.map((item) => (
<CreationTypeCard
key={item.id}
item={item}

View File

@@ -74,6 +74,7 @@ import {
normalizeAgentBackedProfile,
resolveRpgCreationErrorMessage,
} from './platformEntryShared';
import type { PlatformCreationTypeId } from './platformEntryCreationTypes';
import type { PlatformEntryFlowShellProps } from './platformEntryTypes';
import { PlatformEntryWorldDetailView } from './PlatformEntryWorldDetailView';
import { usePlatformEntryBootstrap } from './usePlatformEntryBootstrap';
@@ -363,9 +364,9 @@ export function PlatformEntryFlowShellImpl({
[authUi],
);
const openCreationTypePicker = useCallback(() => {
const prepareCreationLaunch = useCallback(() => {
if (sessionController.isCreatingAgentSession) {
return;
return false;
}
if (!hasSavedGame) {
@@ -373,13 +374,21 @@ export function PlatformEntryFlowShellImpl({
}
sessionController.setCreationTypeError(null);
setShowCreationTypeModal(true);
return true;
}, [
handleStartNewGame,
hasSavedGame,
sessionController,
]);
const openCreationTypePicker = useCallback(() => {
if (!prepareCreationLaunch()) {
return;
}
setShowCreationTypeModal(true);
}, [prepareCreationLaunch]);
const resolveBigFishErrorMessage = useCallback(
(error: unknown, fallback: string) =>
resolveRpgCreationErrorMessage(error, fallback),
@@ -466,6 +475,45 @@ export function PlatformEntryFlowShellImpl({
setSelectionStage,
]);
const handleCreationHubCreateType = useCallback(
(type: PlatformCreationTypeId) => {
if (type === 'airp' || type === 'visual-novel') {
return;
}
if (!prepareCreationLaunch()) {
return;
}
if (type === 'rpg') {
runProtectedAction(() => {
void sessionController.openRpgAgentWorkspace();
});
return;
}
if (type === 'big-fish') {
runProtectedAction(() => {
void openBigFishAgentWorkspace();
});
return;
}
if (type === 'puzzle') {
runProtectedAction(() => {
void openPuzzleAgentWorkspace();
});
}
},
[
openBigFishAgentWorkspace,
openPuzzleAgentWorkspace,
prepareCreationLaunch,
runProtectedAction,
sessionController,
],
);
const leaveBigFishFlow = useCallback(() => {
setBigFishError(null);
setBigFishRun(null);
@@ -925,9 +973,6 @@ export function PlatformEntryFlowShellImpl({
sessionController.creationTypeError ??
puzzleError
}
onBack={() => {
platformBootstrap.setPlatformTab('home');
}}
onRetry={() => {
platformBootstrap.setPlatformError(null);
void platformBootstrap.refreshCustomWorldWorks().catch((error) => {
@@ -936,7 +981,11 @@ export function PlatformEntryFlowShellImpl({
);
});
}}
onCreateNew={openCreationTypePicker}
createError={sessionController.creationTypeError ?? bigFishError ?? puzzleError}
createBusy={
sessionController.isCreatingAgentSession || isBigFishBusy || isPuzzleBusy
}
onCreateType={handleCreationHubCreateType}
onOpenDraft={(item) => {
runProtectedAction(() => {
void detailNavigation.handleOpenCreationWork(item);

View File

@@ -0,0 +1,55 @@
export type PlatformCreationTypeId =
| 'rpg'
| 'big-fish'
| 'puzzle'
| 'airp'
| 'visual-novel';
export type PlatformCreationTypeCard = {
id: PlatformCreationTypeId;
title: string;
subtitle: string;
badge: string;
locked: boolean;
};
/**
* 创作页与类型弹层共用同一份模板元数据,避免多入口文案和可用状态漂移。
*/
export const PLATFORM_CREATION_TYPES: PlatformCreationTypeCard[] = [
{
id: 'rpg',
title: '角色扮演 RPG',
subtitle: 'Agent 共创',
badge: '可创建',
locked: false,
},
{
id: 'big-fish',
title: '大鱼吃小鱼',
subtitle: '实时成长玩法',
badge: '可创建',
locked: false,
},
{
id: 'puzzle',
title: '拼图玩法',
subtitle: '图像锚点共创',
badge: '可创建',
locked: false,
},
{
id: 'airp',
title: 'AIRP',
subtitle: '敬请期待',
badge: '锁定',
locked: true,
},
{
id: 'visual-novel',
title: '视觉小说',
subtitle: '敬请期待',
badge: '锁定',
locked: true,
},
];