fix: polish bark battle creation flow
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import type { BarkBattleWorkSummary } from '../../../packages/shared/src/contracts/barkBattle';
|
||||
import type { BigFishWorkSummary } from '../../../packages/shared/src/contracts/bigFishWorkSummary';
|
||||
import type { BabyObjectMatchDraft } from '../../../packages/shared/src/contracts/edutainmentBabyObject';
|
||||
import { BABY_OBJECT_MATCH_EDUTAINMENT_TAG } from '../../../packages/shared/src/contracts/edutainmentBabyObject';
|
||||
@@ -22,6 +23,7 @@ import { buildCustomWorldPlayableCharacters } from '../../data/characterPresets'
|
||||
import { resolveCustomWorldCampSceneImage } from '../../data/customWorldVisuals';
|
||||
import {
|
||||
buildBabyObjectMatchPublicWorkCode,
|
||||
buildBarkBattlePublicWorkCode,
|
||||
buildBigFishPublicWorkCode,
|
||||
buildMatch3DPublicWorkCode,
|
||||
buildPuzzlePublicWorkCode,
|
||||
@@ -43,6 +45,7 @@ export type PlatformWorldCardLike =
|
||||
| PlatformSquareHoleGalleryCard
|
||||
| PlatformPuzzleGalleryCard
|
||||
| PlatformVisualNovelGalleryCard
|
||||
| PlatformBarkBattleGalleryCard
|
||||
| PlatformEdutainmentGalleryCard;
|
||||
|
||||
export type PlatformPuzzleGalleryCard = {
|
||||
@@ -196,6 +199,34 @@ export type PlatformEdutainmentGalleryCard = {
|
||||
updatedAt: string;
|
||||
};
|
||||
|
||||
export type PlatformBarkBattleGalleryCard = {
|
||||
sourceType: 'bark-battle';
|
||||
workId: string;
|
||||
profileId: string;
|
||||
sourceSessionId?: string | null;
|
||||
publicWorkCode: string;
|
||||
ownerUserId: string;
|
||||
authorPublicUserCode: string | null;
|
||||
authorDisplayName: string;
|
||||
worldName: string;
|
||||
subtitle: string;
|
||||
summaryText: string;
|
||||
coverImageSrc: string | null;
|
||||
coverRenderMode: 'image' | 'scene_with_roles';
|
||||
coverCharacterImageSrcs: string[];
|
||||
themeTags: string[];
|
||||
themeMode: CustomWorldGalleryCard['themeMode'];
|
||||
playableNpcCount: number;
|
||||
landmarkCount: number;
|
||||
playCount?: number;
|
||||
remixCount?: number;
|
||||
likeCount?: number;
|
||||
recentPlayCount7d?: number;
|
||||
visibility: 'published';
|
||||
publishedAt: string | null;
|
||||
updatedAt: string;
|
||||
};
|
||||
|
||||
export type PlatformPublicGalleryCard =
|
||||
| CustomWorldGalleryCard
|
||||
| PlatformBigFishGalleryCard
|
||||
@@ -203,6 +234,7 @@ export type PlatformPublicGalleryCard =
|
||||
| PlatformSquareHoleGalleryCard
|
||||
| PlatformPuzzleGalleryCard
|
||||
| PlatformVisualNovelGalleryCard
|
||||
| PlatformBarkBattleGalleryCard
|
||||
| PlatformEdutainmentGalleryCard;
|
||||
|
||||
export function isLibraryWorldEntry(
|
||||
@@ -247,6 +279,12 @@ export function isEdutainmentGalleryEntry(
|
||||
return 'sourceType' in entry && entry.sourceType === 'edutainment';
|
||||
}
|
||||
|
||||
export function isBarkBattleGalleryEntry(
|
||||
entry: PlatformWorldCardLike,
|
||||
): entry is PlatformBarkBattleGalleryCard {
|
||||
return 'sourceType' in entry && entry.sourceType === 'bark-battle';
|
||||
}
|
||||
|
||||
export function mapPuzzleWorkToPlatformGalleryCard(
|
||||
work: PuzzleWorkSummary,
|
||||
): PlatformPuzzleGalleryCard {
|
||||
@@ -422,6 +460,64 @@ export function mapBabyObjectMatchDraftToPlatformGalleryCard(
|
||||
};
|
||||
}
|
||||
|
||||
export function mapBarkBattleWorkToPlatformGalleryCard(
|
||||
work: BarkBattleWorkSummary,
|
||||
): PlatformBarkBattleGalleryCard {
|
||||
const playerCharacterImageSrc = normalizePlatformOptionalImageSrc(
|
||||
work.playerCharacterImageSrc,
|
||||
);
|
||||
const opponentCharacterImageSrc = normalizePlatformOptionalImageSrc(
|
||||
work.opponentCharacterImageSrc,
|
||||
);
|
||||
const backgroundImageSrc = normalizePlatformOptionalImageSrc(
|
||||
work.uiBackgroundImageSrc,
|
||||
);
|
||||
const coverImageSrc =
|
||||
backgroundImageSrc ??
|
||||
playerCharacterImageSrc ??
|
||||
opponentCharacterImageSrc ??
|
||||
'/creation-type-references/bark-battle.webp';
|
||||
const coverCharacterImageSrcs = [
|
||||
playerCharacterImageSrc,
|
||||
opponentCharacterImageSrc,
|
||||
].filter((imageSrc): imageSrc is string => Boolean(imageSrc));
|
||||
const canRenderSceneWithRoles =
|
||||
Boolean(backgroundImageSrc) && coverCharacterImageSrcs.length >= 2;
|
||||
|
||||
return {
|
||||
sourceType: 'bark-battle',
|
||||
workId: work.workId,
|
||||
profileId: work.workId,
|
||||
sourceSessionId: work.draftId ?? null,
|
||||
publicWorkCode: buildBarkBattlePublicWorkCode(work.workId),
|
||||
ownerUserId: work.ownerUserId,
|
||||
authorPublicUserCode: null,
|
||||
authorDisplayName: work.authorDisplayName,
|
||||
worldName: work.title.trim() || '汪汪声浪大作战',
|
||||
subtitle: `汪汪声浪 · ${describeBarkBattleDifficultyLabel(
|
||||
work.difficultyPreset,
|
||||
)}`,
|
||||
summaryText:
|
||||
work.summary.trim() ||
|
||||
work.themeDescription.trim() ||
|
||||
'用声音能量挑战对手。',
|
||||
coverImageSrc,
|
||||
coverRenderMode: canRenderSceneWithRoles ? 'scene_with_roles' : 'image',
|
||||
coverCharacterImageSrcs,
|
||||
themeTags: buildBarkBattleThemeTags(work),
|
||||
themeMode: 'martial',
|
||||
playableNpcCount: 0,
|
||||
landmarkCount: 0,
|
||||
playCount: work.playCount ?? 0,
|
||||
remixCount: 0,
|
||||
likeCount: 0,
|
||||
recentPlayCount7d: work.recentPlayCount7d ?? 0,
|
||||
visibility: 'published',
|
||||
publishedAt: work.publishedAt ?? null,
|
||||
updatedAt: work.updatedAt,
|
||||
};
|
||||
}
|
||||
|
||||
export function resolvePlatformWorldStats(entry: PlatformWorldCardLike) {
|
||||
return {
|
||||
playCount: 'playCount' in entry ? (entry.playCount ?? 0) : 0,
|
||||
@@ -473,6 +569,10 @@ export function resolvePlatformWorldFallbackCoverImage(
|
||||
return '/creation-type-references/creative-agent.webp';
|
||||
}
|
||||
|
||||
if (isBarkBattleGalleryEntry(entry)) {
|
||||
return '/creation-type-references/bark-battle.webp';
|
||||
}
|
||||
|
||||
return '/creation-type-references/rpg.webp';
|
||||
}
|
||||
|
||||
@@ -634,6 +734,12 @@ export function buildPlatformWorldTags(entry: PlatformWorldCardLike) {
|
||||
: [entry.templateName];
|
||||
}
|
||||
|
||||
if (isBarkBattleGalleryEntry(entry)) {
|
||||
return entry.themeTags.length > 0
|
||||
? entry.themeTags.slice(0, 3)
|
||||
: ['汪汪声浪'];
|
||||
}
|
||||
|
||||
if (!isLibraryWorldEntry(entry)) {
|
||||
return [
|
||||
describePlatformThemeLabel(entry.themeMode),
|
||||
@@ -724,6 +830,10 @@ export function resolvePlatformPublicWorkCode(
|
||||
return entry.publicWorkCode;
|
||||
}
|
||||
|
||||
if (isBarkBattleGalleryEntry(entry)) {
|
||||
return entry.publicWorkCode;
|
||||
}
|
||||
|
||||
return entry.publicWorkCode;
|
||||
}
|
||||
|
||||
@@ -745,3 +855,31 @@ export function describePlatformThemeLabel(
|
||||
return '回响';
|
||||
}
|
||||
}
|
||||
|
||||
function normalizePlatformOptionalImageSrc(value?: string | null) {
|
||||
return value?.trim() || null;
|
||||
}
|
||||
|
||||
function describeBarkBattleDifficultyLabel(
|
||||
difficulty: BarkBattleWorkSummary['difficultyPreset'],
|
||||
) {
|
||||
switch (difficulty) {
|
||||
case 'easy':
|
||||
return '轻松';
|
||||
case 'hard':
|
||||
return '高能';
|
||||
default:
|
||||
return '普通';
|
||||
}
|
||||
}
|
||||
|
||||
function buildBarkBattleThemeTags(work: BarkBattleWorkSummary) {
|
||||
return [
|
||||
'汪汪声浪',
|
||||
describeBarkBattleDifficultyLabel(work.difficultyPreset),
|
||||
work.themeDescription,
|
||||
]
|
||||
.map((tag) => tag.trim())
|
||||
.filter(Boolean)
|
||||
.slice(0, 3);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user