Refine play type integration flow and docs

This commit is contained in:
2026-06-03 00:57:24 +08:00
parent dbe4c902b4
commit 67ba40c678
35 changed files with 2226 additions and 619 deletions

View File

@@ -125,6 +125,8 @@ export type CreationWorkShelfItem = {
kind: CreationWorkShelfKind;
status: CreationWorkShelfStatus;
isGenerating?: boolean;
hasGenerationFailure?: boolean;
generationFailureSummary?: string;
hasUnreadUpdate?: boolean;
title: string;
summary: string;
@@ -145,6 +147,16 @@ export type CreationWorkShelfItem = {
source: CreationWorkShelfSource;
};
export type CreationWorkShelfRuntimeState = {
isGenerating?: boolean;
hasGenerationFailure?: boolean;
generationFailureSummary?: string;
hasUnreadUpdate?: boolean;
suppressPersistedGenerating?: boolean;
titleOverride?: string;
summaryOverride?: string;
};
export function buildCreationWorkShelfItems(params: {
rpgItems: CustomWorldWorkSummary[];
rpgLibraryEntries?: CustomWorldLibraryEntry<CustomWorldProfile>[];
@@ -191,7 +203,7 @@ export function buildCreationWorkShelfItems(params: {
onDeleteVisualNovel?: (item: VisualNovelWorkSummary) => void;
getItemState?: (
item: CreationWorkShelfItem,
) => { isGenerating?: boolean; hasUnreadUpdate?: boolean } | null;
) => CreationWorkShelfRuntimeState | null;
}) {
const {
rpgItems,
@@ -307,18 +319,24 @@ export function buildCreationWorkShelfItems(params: {
.map((item) => {
const state = getItemState?.(item);
const persistedIsGenerating = isPersistedCreationWorkGenerating(item);
return state
const isGenerating = Boolean(
state?.isGenerating ||
(!state?.suppressPersistedGenerating && persistedIsGenerating),
);
return state || isGenerating
? {
...item,
isGenerating: Boolean(state.isGenerating || persistedIsGenerating),
hasUnreadUpdate: state.hasUnreadUpdate,
title: state?.titleOverride ?? item.title,
summary: state?.summaryOverride ?? item.summary,
isGenerating,
hasGenerationFailure:
state?.hasGenerationFailure ?? item.hasGenerationFailure,
generationFailureSummary:
state?.generationFailureSummary ??
item.generationFailureSummary,
hasUnreadUpdate: state?.hasUnreadUpdate,
}
: persistedIsGenerating
? {
...item,
isGenerating: true,
}
: item;
: item;
})
.sort(
(left, right) =>
@@ -327,7 +345,6 @@ export function buildCreationWorkShelfItems(params: {
);
}
function mergeBarkBattleShelfSourceItems(
items: readonly BarkBattleWorkSummary[],
): BarkBattleWorkSummary[] {
@@ -376,8 +393,8 @@ function mapRpgWorkToShelfItem(
: null;
const publicWorkCode =
item.status === 'published'
? (libraryEntry?.publicWorkCode?.trim() ||
(item.profileId ? buildCustomWorldPublicWorkCode(item.profileId) : null))
? libraryEntry?.publicWorkCode?.trim() ||
(item.profileId ? buildCustomWorldPublicWorkCode(item.profileId) : null)
: null;
const badges: CreationWorkShelfBadge[] = [
buildStatusBadge(item.status),
@@ -843,7 +860,9 @@ function mapWoodenFishWorkToShelfItem(
): CreationWorkShelfItem {
const status = item.publicationStatus === 'published' ? 'published' : 'draft';
const publicWorkCode =
status === 'published' ? buildWoodenFishPublicWorkCode(item.profileId) : null;
status === 'published'
? buildWoodenFishPublicWorkCode(item.profileId)
: null;
const title = item.workTitle.trim() || '敲木鱼';
const summary =
item.workDescription.trim() || (status === 'draft' ? '未填写作品描述' : '');
@@ -884,10 +903,7 @@ function mapWoodenFishWorkToShelfItem(
};
}
function resolveAuthorDisplayName(
...sources: Array<unknown>
) {
function resolveAuthorDisplayName(...sources: Array<unknown>) {
for (const source of sources) {
const authorDisplayName =
source &&
@@ -961,7 +977,8 @@ export function resolvePuzzleLevelCoverImageSrc(
const fallbackCandidateImageSrc = normalizeCoverImageSrc(
level.candidates[level.candidates.length - 1]?.imageSrc,
);
const candidateImageSrc = selectedCandidateImageSrc || fallbackCandidateImageSrc;
const candidateImageSrc =
selectedCandidateImageSrc || fallbackCandidateImageSrc;
if (
candidateImageSrc &&
@@ -984,7 +1001,9 @@ function resolveMatch3DWorkCoverImageSrc(item: Match3DWorkSummary) {
const topLevelContainerImageSrc =
normalizeCoverImageSrc(item.generatedBackgroundAsset?.containerImageSrc) ||
normalizeCoverImageSrc(item.generatedBackgroundAsset?.containerImageObjectKey);
normalizeCoverImageSrc(
item.generatedBackgroundAsset?.containerImageObjectKey,
);
if (topLevelContainerImageSrc) {
return topLevelContainerImageSrc;
}