feat: restore agent sessions from creation drafts

This commit is contained in:
2026-04-23 21:23:46 +08:00
parent 349a397888
commit 53a9cdd791
11 changed files with 949 additions and 18 deletions

View File

@@ -1,6 +1,7 @@
import { useMemo, useState } from 'react';
import type { CustomWorldWorkSummary } from '../../../packages/shared/src/contracts/customWorldAgent';
import type { BigFishWorkSummary } from '../../../packages/shared/src/contracts/bigFishWorkSummary';
import type { PuzzleWorkSummary } from '../../../packages/shared/src/contracts/puzzleWorkSummary';
import { CustomWorldCreationStartCard } from './CustomWorldCreationStartCard';
import {
@@ -26,8 +27,11 @@ type CustomWorldCreationHubProps = {
onDeletePublished?: ((item: CustomWorldWorkSummary) => void) | null;
deletingWorkId?: string | null;
onExperienceRpg?: ((item: CustomWorldWorkSummary) => void) | null;
bigFishItems?: BigFishWorkSummary[];
onOpenBigFishDetail?: (item: BigFishWorkSummary) => void;
onExperienceBigFish?: ((item: BigFishWorkSummary) => void) | null;
puzzleItems?: PuzzleWorkSummary[];
onOpenPuzzleDetail?: (profileId: string) => void;
onOpenPuzzleDetail?: (item: PuzzleWorkSummary) => void;
onExperiencePuzzle?: ((profileId: string) => void) | null;
};
@@ -54,6 +58,9 @@ export function CustomWorldCreationHub({
onDeletePublished = null,
deletingWorkId = null,
onExperienceRpg = null,
bigFishItems = [],
onOpenBigFishDetail,
onExperienceBigFish = null,
puzzleItems = [],
onOpenPuzzleDetail,
onExperiencePuzzle = null,
@@ -63,18 +70,23 @@ export function CustomWorldCreationHub({
const unifiedItems = useMemo<UnifiedCreationWorkItem[]>(
() => [
...items.map((item) => ({ kind: 'rpg', item }) as const),
...bigFishItems.map((item) => ({ kind: 'big-fish', item }) as const),
...puzzleItems.map((item) => ({ kind: 'puzzle', item }) as const),
],
[items, puzzleItems],
[bigFishItems, items, puzzleItems],
);
const draftCount = unifiedItems.filter((entry) =>
entry.kind === 'puzzle'
? entry.item.publicationStatus === 'draft'
: entry.kind === 'big-fish'
? entry.item.status === 'draft'
: entry.item.status === 'draft',
).length;
const publishedCount = unifiedItems.filter((entry) =>
entry.kind === 'puzzle'
? entry.item.publicationStatus === 'published'
: entry.kind === 'big-fish'
? entry.item.status === 'published'
: entry.item.status === 'published',
).length;
const filteredItems = useMemo(
@@ -84,6 +96,8 @@ export function CustomWorldCreationHub({
? true
: entry.kind === 'puzzle'
? entry.item.publicationStatus === activeFilter
: entry.kind === 'big-fish'
? entry.item.status === activeFilter
: entry.item.status === activeFilter,
),
[activeFilter, unifiedItems],
@@ -144,7 +158,12 @@ export function CustomWorldCreationHub({
item={item}
onOpen={() => {
if (item.kind === 'puzzle') {
onOpenPuzzleDetail?.(item.item.profileId);
onOpenPuzzleDetail?.(item.item);
return;
}
if (item.kind === 'big-fish') {
onOpenBigFishDetail?.(item.item);
return;
}
@@ -167,6 +186,12 @@ export function CustomWorldCreationHub({
onExperiencePuzzle?.(item.item.profileId);
}
: null
: item.kind === 'big-fish'
? item.item.status === 'published'
? () => {
onExperienceBigFish?.(item.item);
}
: null
: item.item.status === 'published' && item.item.canEnterWorld
? () => {
onExperienceRpg?.(item.item);

View File

@@ -1,4 +1,5 @@
import type { CustomWorldWorkSummary } from '../../../packages/shared/src/contracts/customWorldAgent';
import type { BigFishWorkSummary } from '../../../packages/shared/src/contracts/bigFishWorkSummary';
import type { PuzzleWorkSummary } from '../../../packages/shared/src/contracts/puzzleWorkSummary';
import { CustomWorldCoverArtwork } from '../CustomWorldCoverArtwork';
@@ -21,6 +22,10 @@ export type UnifiedCreationWorkItem =
kind: 'rpg';
item: CustomWorldWorkSummary;
}
| {
kind: 'big-fish';
item: BigFishWorkSummary;
}
| {
kind: 'puzzle';
item: PuzzleWorkSummary;
@@ -42,19 +47,26 @@ export function CustomWorldWorkCard({
deleteBusy = false,
}: CustomWorldWorkCardProps) {
const isPuzzle = item.kind === 'puzzle';
const isBigFish = item.kind === 'big-fish';
const isDraft =
item.kind === 'puzzle'
? item.item.publicationStatus === 'draft'
: item.kind === 'big-fish'
? item.item.status === 'draft'
: item.item.status === 'draft';
const openActionLabel = isPuzzle
? '查看详情'
const openActionLabel = isPuzzle || isBigFish
? isDraft
? '继续创作'
: '查看详情'
: isDraft
? item.item.playableNpcCount > 0 || item.item.landmarkCount > 0
? '继续完善'
: '继续创作'
: '查看详情';
const title = isPuzzle ? item.item.levelName : item.item.title;
const subtitle = isPuzzle ? item.item.authorDisplayName : item.item.subtitle;
const title =
item.kind === 'puzzle' ? item.item.levelName : item.item.title;
const subtitle =
item.kind === 'puzzle' ? item.item.authorDisplayName : item.item.subtitle;
const summary = item.item.summary;
const updatedAt = item.item.updatedAt;
const coverImageSrc = item.item.coverImageSrc ?? null;
@@ -87,9 +99,9 @@ export function CustomWorldWorkCard({
{isDraft ? '草稿' : '已发布'}
</span>
<span className="platform-pill platform-pill--neutral px-3 py-1 text-[10px]">
{isPuzzle ? '拼图' : 'RPG'}
{isPuzzle ? '拼图' : isBigFish ? '大鱼' : 'RPG'}
</span>
{!isPuzzle && item.item.stageLabel ? (
{item.kind === 'rpg' && item.item.stageLabel ? (
<span className="platform-pill platform-pill--neutral px-3 py-1 text-[10px]">
{item.item.stageLabel}
</span>
@@ -133,6 +145,23 @@ export function CustomWorldWorkCard({
{item.item.playCount}
</span>
</>
) : isBigFish ? (
<>
<span className="platform-pill platform-pill--neutral px-3 py-1 text-[10px]">
{item.item.levelCount}
</span>
<span className="platform-pill platform-pill--neutral px-3 py-1 text-[10px]">
{item.item.levelMainImageReadyCount}
</span>
<span className="platform-pill platform-pill--neutral px-3 py-1 text-[10px]">
{item.item.levelMotionReadyCount}
</span>
{item.item.backgroundReady ? (
<span className="platform-pill platform-pill--success px-3 py-1 text-[10px]">
</span>
) : null}
</>
) : (
<>
<span className="platform-pill platform-pill--neutral px-3 py-1 text-[10px]">