This commit is contained in:
2026-05-11 16:15:48 +08:00
parent 0c9254502c
commit e30b733b17
87 changed files with 3527 additions and 1261 deletions

View File

@@ -294,7 +294,7 @@ import {
buildVisualNovelEntryGenerationAnchorEntries,
buildVisualNovelEntryGenerationProgress,
type VisualNovelEntryFormPayload,
} from '../visual-novel-creation/VisualNovelAgentWorkspace';
} from '../visual-novel-creation/visualNovelEntryGeneration';
import { createMockVisualNovelRunFromDraft } from '../visual-novel-runtime/visualNovelMockData';
import {
canExposePublicWork,
@@ -426,7 +426,7 @@ function getPlatformPublicGalleryEntryKey(entry: PlatformPublicGalleryCard) {
? 'square-hole'
: isVisualNovelGalleryEntry(entry)
? 'visual-novel'
: 'rpg';
: 'rpg';
return `${kind}:${entry.ownerUserId}:${entry.profileId}`;
}
@@ -579,6 +579,7 @@ function mapPublicWorkDetailToMatch3DWork(
updatedAt: entry.updatedAt,
publishedAt: entry.publishedAt,
publishReady: true,
generatedItemAssets: entry.generatedItemAssets ?? [],
};
}
@@ -1446,7 +1447,9 @@ const VisualNovelResultView = lazy(async () => {
});
const VisualNovelRuntimeShell = lazy(async () => {
const module = await import('../visual-novel-runtime/VisualNovelRuntimeShell');
const module = await import(
'../visual-novel-runtime/VisualNovelRuntimeShell'
);
return {
default: module.VisualNovelRuntimeShell,
};
@@ -1698,8 +1701,10 @@ export function PlatformEntryFlowShellImpl({
useState<VisualNovelRuntimeReturnStage>('visual-novel-result');
const [visualNovelFormDraftPayload, setVisualNovelFormDraftPayload] =
useState<VisualNovelEntryFormPayload | null>(null);
const [visualNovelGenerationStartedAtMs, setVisualNovelGenerationStartedAtMs] =
useState<number | null>(null);
const [
visualNovelGenerationStartedAtMs,
setVisualNovelGenerationStartedAtMs,
] = useState<number | null>(null);
const [visualNovelGenerationPhase, setVisualNovelGenerationPhase] =
useState<VisualNovelEntryGenerationPhase>('generating');
const [isVisualNovelLoadingLibrary, setIsVisualNovelLoadingLibrary] =
@@ -1739,6 +1744,10 @@ export function PlatformEntryFlowShellImpl({
creationEntryTypes,
'big-fish',
);
const isSquareHoleCreationVisible = isPlatformCreationTypeVisible(
creationEntryTypes,
'square-hole',
);
const [profilePlayStats, setProfilePlayStats] =
useState<ProfilePlayStatsResponse | null>(null);
const [profilePlayStatsError, setProfilePlayStatsError] = useState<
@@ -2240,19 +2249,16 @@ export function PlatformEntryFlowShellImpl({
visualNovelGalleryEntries,
],
);
const recommendRuntimeEntries = useMemo(
() => {
const entryMap = new Map<string, PlatformPublicGalleryCard>();
filterGeneralPublicWorks([
...featuredGalleryEntries,
...latestGalleryEntries,
]).forEach((entry) => {
entryMap.set(getPlatformPublicGalleryEntryKey(entry), entry);
});
return Array.from(entryMap.values());
},
[featuredGalleryEntries, latestGalleryEntries],
);
const recommendRuntimeEntries = useMemo(() => {
const entryMap = new Map<string, PlatformPublicGalleryCard>();
filterGeneralPublicWorks([
...featuredGalleryEntries,
...latestGalleryEntries,
]).forEach((entry) => {
entryMap.set(getPlatformPublicGalleryEntryKey(entry), entry);
});
return Array.from(entryMap.values());
}, [featuredGalleryEntries, latestGalleryEntries]);
const creationHubItems = useMemo<CustomWorldWorkSummary[]>(
() =>
@@ -3676,7 +3682,10 @@ export function PlatformEntryFlowShellImpl({
setVisualNovelRuntimeReturnStage('visual-novel-result');
setSelectionStage('visual-novel-runtime');
setVisualNovelError(
resolvePuzzleErrorMessage(error, '已进入本地试玩,真实运行接口暂不可用。'),
resolvePuzzleErrorMessage(
error,
'已进入本地试玩,真实运行接口暂不可用。',
),
);
} finally {
setIsVisualNovelBusy(false);
@@ -3976,9 +3985,7 @@ export function PlatformEntryFlowShellImpl({
setPuzzleOperation(response.operation);
puzzleFlow.setSession(response.session);
} catch (error) {
setPuzzleError(
resolvePuzzleErrorMessage(error, '执行拼图操作失败。'),
);
setPuzzleError(resolvePuzzleErrorMessage(error, '执行拼图操作失败。'));
}
},
[puzzleFlow, resolvePuzzleErrorMessage, setPuzzleError],
@@ -4053,7 +4060,9 @@ export function PlatformEntryFlowShellImpl({
enterCreateTab();
setActiveCreativeAgentSessionId(creativeAgentSession.sessionId);
setCreativeDraftEditError(null);
setSelectionStage(resolveCreativeAgentTargetSelectionStage(binding.targetStage));
setSelectionStage(
resolveCreativeAgentTargetSelectionStage(binding.targetStage),
);
} catch (error) {
setCreativeAgentError(
resolvePuzzleErrorMessage(error, '打开拼图草稿失败。'),
@@ -5959,7 +5968,9 @@ export function PlatformEntryFlowShellImpl({
throw new Error('未找到视觉小说作品。');
}
openPublicWorkDetail(mapVisualNovelWorkToPublicWorkDetail(matchedEntry));
openPublicWorkDetail(
mapVisualNovelWorkToPublicWorkDetail(matchedEntry),
);
} catch (error) {
setPublicWorkDetailError(
resolvePuzzleErrorMessage(error, '读取视觉小说详情失败。'),
@@ -6522,7 +6533,9 @@ export function PlatformEntryFlowShellImpl({
} else if (isSquareHoleGalleryEntry(entry)) {
const work = mapPublicWorkDetailToSquareHoleWork(entry);
if (!work) {
setSquareHoleError('当前方洞挑战作品信息不完整,暂时无法进入玩法。');
setSquareHoleError(
'当前方洞挑战作品信息不完整,暂时无法进入玩法。',
);
} else {
started = await startSquareHoleRunFromProfile(
work,
@@ -6655,12 +6668,16 @@ export function PlatformEntryFlowShellImpl({
}
if (activeRecommendRuntimeKind === 'match3d') {
const generatedItemAssets = isMatch3DGalleryEntry(activeEntry)
? activeEntry.generatedItemAssets ?? []
: [];
return (
<Match3DRuntimeShell
run={match3dRun}
isBusy={isMatch3DBusy}
error={match3dError}
embedded
generatedItemAssets={generatedItemAssets}
onBack={() => {
setActiveRecommendRuntimeKind(null);
}}
@@ -6677,10 +6694,7 @@ export function PlatformEntryFlowShellImpl({
})
.catch((error) => {
setMatch3DError(
resolveMatch3DErrorMessage(
error,
'重新开始抓大鹅玩法失败。',
),
resolveMatch3DErrorMessage(error, '重新开始抓大鹅玩法失败。'),
);
})
.finally(() => {
@@ -6706,10 +6720,7 @@ export function PlatformEntryFlowShellImpl({
})
.catch((error) => {
setMatch3DError(
resolveMatch3DErrorMessage(
error,
'同步抓大鹅倒计时失败。',
),
resolveMatch3DErrorMessage(error, '同步抓大鹅倒计时失败。'),
);
});
}}
@@ -6847,7 +6858,9 @@ export function PlatformEntryFlowShellImpl({
}
return (
<div className={`platform-theme ${platformThemeClass} flex h-full min-h-0 items-center justify-center bg-[var(--platform-recommend-runtime-state-fill)] px-5 text-center text-sm font-semibold leading-6 text-[var(--platform-recommend-runtime-state-text)]`}>
<div
className={`platform-theme ${platformThemeClass} flex h-full min-h-0 items-center justify-center bg-[var(--platform-recommend-runtime-state-fill)] px-5 text-center text-sm font-semibold leading-6 text-[var(--platform-recommend-runtime-state-text)]`}
>
</div>
);
@@ -7260,7 +7273,10 @@ export function PlatformEntryFlowShellImpl({
const detailEntry = mapBigFishWorkToPublicWorkDetail(entry);
return (
canExposePublicWork(detailEntry) &&
isSameBigFishPublicWorkCode(normalizedKeyword, entry.sourceSessionId)
isSameBigFishPublicWorkCode(
normalizedKeyword,
entry.sourceSessionId,
)
);
});
@@ -7325,7 +7341,9 @@ export function PlatformEntryFlowShellImpl({
throw new Error('未找到视觉小说作品。');
}
openPublicWorkDetail(mapVisualNovelWorkToPublicWorkDetail(matchedEntry));
openPublicWorkDetail(
mapVisualNovelWorkToPublicWorkDetail(matchedEntry),
);
};
try {
@@ -7577,11 +7595,14 @@ export function PlatformEntryFlowShellImpl({
}
void refreshMatch3DGallery();
void refreshPuzzleGallery();
void refreshSquareHoleGallery();
if (isSquareHoleCreationVisible) {
void refreshSquareHoleGallery();
}
void refreshVisualNovelGallery();
}
}, [
isBigFishCreationVisible,
isSquareHoleCreationVisible,
refreshBigFishGallery,
refreshMatch3DGallery,
refreshPuzzleGallery,
@@ -7598,10 +7619,13 @@ export function PlatformEntryFlowShellImpl({
) {
void refreshPuzzleShelf();
void refreshMatch3DShelf();
void refreshSquareHoleShelf();
if (isSquareHoleCreationVisible) {
void refreshSquareHoleShelf();
}
void refreshVisualNovelShelf();
}
}, [
isSquareHoleCreationVisible,
platformBootstrap.canReadProtectedData,
platformBootstrap.platformTab,
refreshMatch3DShelf,
@@ -7641,7 +7665,7 @@ export function PlatformEntryFlowShellImpl({
platformBootstrap.isLoadingPlatform ||
isBigFishLoadingLibrary ||
isMatch3DLoadingLibrary ||
isSquareHoleLoadingLibrary ||
(isSquareHoleCreationVisible && isSquareHoleLoadingLibrary) ||
isPuzzleLoadingLibrary ||
isVisualNovelLoadingLibrary
}
@@ -7649,7 +7673,7 @@ export function PlatformEntryFlowShellImpl({
platformBootstrap.isLoadingPlatform ||
isBigFishLoadingLibrary ||
isMatch3DLoadingLibrary ||
isSquareHoleLoadingLibrary ||
(isSquareHoleCreationVisible && isSquareHoleLoadingLibrary) ||
isPuzzleLoadingLibrary ||
isVisualNovelLoadingLibrary
? null
@@ -7657,7 +7681,7 @@ export function PlatformEntryFlowShellImpl({
sessionController.agentWorkspaceRestoreError ??
bigFishError ??
match3dError ??
squareHoleError ??
(isSquareHoleCreationVisible ? squareHoleError : null) ??
puzzleShelfError ??
puzzleError ??
visualNovelError)
@@ -7688,7 +7712,9 @@ export function PlatformEntryFlowShellImpl({
void refreshBigFishShelf();
}
void refreshMatch3DShelf();
void refreshSquareHoleShelf();
if (isSquareHoleCreationVisible) {
void refreshSquareHoleShelf();
}
void refreshPuzzleShelf();
void refreshVisualNovelShelf();
}}
@@ -7697,7 +7723,7 @@ export function PlatformEntryFlowShellImpl({
sessionController.creationTypeError ??
bigFishError ??
match3dError ??
squareHoleError ??
(isSquareHoleCreationVisible ? squareHoleError : null) ??
puzzleCreationError ??
puzzleError ??
visualNovelError
@@ -7709,7 +7735,7 @@ export function PlatformEntryFlowShellImpl({
isCreativeAgentStreaming ||
isBigFishBusy ||
isMatch3DBusy ||
isSquareHoleBusy ||
(isSquareHoleCreationVisible && isSquareHoleBusy) ||
isPuzzleBusy ||
isVisualNovelBusy ||
isVisualNovelStreamingReply
@@ -7764,15 +7790,23 @@ export function PlatformEntryFlowShellImpl({
onDeleteMatch3D={(item) => {
handleDeleteMatch3DWork(item);
}}
squareHoleItems={squareHoleWorks}
onOpenSquareHoleDetail={(item) => {
runProtectedAction(() => {
void openSquareHoleDraft(item);
});
}}
onDeleteSquareHole={(item) => {
handleDeleteSquareHoleWork(item);
}}
squareHoleItems={isSquareHoleCreationVisible ? squareHoleWorks : []}
onOpenSquareHoleDetail={
isSquareHoleCreationVisible
? (item) => {
runProtectedAction(() => {
void openSquareHoleDraft(item);
});
}
: undefined
}
onDeleteSquareHole={
isSquareHoleCreationVisible
? (item) => {
handleDeleteSquareHoleWork(item);
}
: null
}
puzzleItems={puzzleWorks}
onOpenPuzzleDetail={(item) => {
runProtectedAction(() => {
@@ -7883,9 +7917,7 @@ export function PlatformEntryFlowShellImpl({
<div className="mt-3 min-h-0 flex-1 overflow-hidden">
{activeCreationFormType === 'match3d' ? (
<Suspense
fallback={
<LazyPanelFallback label="正在加载抓大鹅创作..." />
}
fallback={<LazyPanelFallback label="正在加载抓大鹅创作..." />}
>
<Match3DAgentWorkspace
session={match3dSession}
@@ -7925,7 +7957,9 @@ export function PlatformEntryFlowShellImpl({
/>
</Suspense>
) : (
<Suspense fallback={<LazyPanelFallback label="正在加载拼图创作..." />}>
<Suspense
fallback={<LazyPanelFallback label="正在加载拼图创作..." />}
>
<PuzzleAgentWorkspace
session={puzzleSession}
isBusy={isPuzzleBusy || isStreamingPuzzleReply}
@@ -8558,6 +8592,12 @@ export function PlatformEntryFlowShellImpl({
run={match3dRun}
isBusy={isMatch3DBusy}
error={match3dError}
generatedItemAssets={
selectedPublicWorkDetail &&
isMatch3DGalleryEntry(selectedPublicWorkDetail)
? (selectedPublicWorkDetail.generatedItemAssets ?? [])
: (match3dProfile?.generatedItemAssets ?? [])
}
onBack={() => {
if (match3dRun?.runId && match3dRun.status === 'running') {
void stopMatch3DRun(match3dRun.runId).catch(
@@ -9042,7 +9082,9 @@ export function PlatformEntryFlowShellImpl({
className="flex h-full min-h-0 flex-col"
>
<Suspense
fallback={<LazyPanelFallback label="正在加载视觉小说生成面板..." />}
fallback={
<LazyPanelFallback label="正在加载视觉小说生成面板..." />
}
>
<CustomWorldGenerationView
settingText={