fix wooden fish draft recovery
This commit is contained in:
@@ -269,12 +269,13 @@ fn create_wooden_fish_agent_session_tx(
|
|||||||
.map(parse_config)
|
.map(parse_config)
|
||||||
.transpose()?
|
.transpose()?
|
||||||
.unwrap_or_else(|| default_config_from_input(&input));
|
.unwrap_or_else(|| default_config_from_input(&input));
|
||||||
let draft = input
|
let mut draft = input
|
||||||
.draft_json
|
.draft_json
|
||||||
.as_deref()
|
.as_deref()
|
||||||
.map(parse_json)
|
.map(parse_json)
|
||||||
.transpose()?
|
.transpose()?
|
||||||
.unwrap_or_else(|| draft_from_config(&config, None, WOODEN_FISH_GENERATION_DRAFT));
|
.unwrap_or_else(|| draft_from_config(&config, None, WOODEN_FISH_GENERATION_DRAFT));
|
||||||
|
draft.generation_status = WOODEN_FISH_GENERATION_GENERATING.to_string();
|
||||||
|
|
||||||
ctx.db
|
ctx.db
|
||||||
.wooden_fish_agent_session()
|
.wooden_fish_agent_session()
|
||||||
@@ -282,8 +283,8 @@ fn create_wooden_fish_agent_session_tx(
|
|||||||
session_id: input.session_id.clone(),
|
session_id: input.session_id.clone(),
|
||||||
owner_user_id: input.owner_user_id.clone(),
|
owner_user_id: input.owner_user_id.clone(),
|
||||||
current_turn: 0,
|
current_turn: 0,
|
||||||
progress_percent: 0,
|
progress_percent: 1,
|
||||||
stage: WOODEN_FISH_STAGE_COLLECTING.to_string(),
|
stage: WOODEN_FISH_STAGE_GENERATING.to_string(),
|
||||||
config_json: to_json_string(&config),
|
config_json: to_json_string(&config),
|
||||||
draft_json: to_json_string(&draft),
|
draft_json: to_json_string(&draft),
|
||||||
published_profile_id: String::new(),
|
published_profile_id: String::new(),
|
||||||
|
|||||||
@@ -4,11 +4,13 @@ use serde::{Deserialize, Serialize};
|
|||||||
pub const WOODEN_FISH_TEMPLATE_ID: &str = "wooden-fish";
|
pub const WOODEN_FISH_TEMPLATE_ID: &str = "wooden-fish";
|
||||||
pub const WOODEN_FISH_TEMPLATE_NAME: &str = "敲木鱼";
|
pub const WOODEN_FISH_TEMPLATE_NAME: &str = "敲木鱼";
|
||||||
pub const WOODEN_FISH_STAGE_COLLECTING: &str = "Collecting";
|
pub const WOODEN_FISH_STAGE_COLLECTING: &str = "Collecting";
|
||||||
|
pub const WOODEN_FISH_STAGE_GENERATING: &str = "Generating";
|
||||||
pub const WOODEN_FISH_STAGE_DRAFT_COMPILED: &str = "DraftCompiled";
|
pub const WOODEN_FISH_STAGE_DRAFT_COMPILED: &str = "DraftCompiled";
|
||||||
pub const WOODEN_FISH_STAGE_PUBLISHED: &str = "Published";
|
pub const WOODEN_FISH_STAGE_PUBLISHED: &str = "Published";
|
||||||
pub const WOODEN_FISH_PUBLICATION_DRAFT: &str = "Draft";
|
pub const WOODEN_FISH_PUBLICATION_DRAFT: &str = "Draft";
|
||||||
pub const WOODEN_FISH_PUBLICATION_PUBLISHED: &str = "Published";
|
pub const WOODEN_FISH_PUBLICATION_PUBLISHED: &str = "Published";
|
||||||
pub const WOODEN_FISH_GENERATION_DRAFT: &str = "draft";
|
pub const WOODEN_FISH_GENERATION_DRAFT: &str = "draft";
|
||||||
|
pub const WOODEN_FISH_GENERATION_GENERATING: &str = "generating";
|
||||||
pub const WOODEN_FISH_GENERATION_READY: &str = "ready";
|
pub const WOODEN_FISH_GENERATION_READY: &str = "ready";
|
||||||
pub const WOODEN_FISH_EVENT_RUN_STARTED: &str = "run-started";
|
pub const WOODEN_FISH_EVENT_RUN_STARTED: &str = "run-started";
|
||||||
pub const WOODEN_FISH_EVENT_RUN_CHECKPOINT: &str = "checkpoint";
|
pub const WOODEN_FISH_EVENT_RUN_CHECKPOINT: &str = "checkpoint";
|
||||||
|
|||||||
@@ -1966,13 +1966,65 @@ function buildWoodenFishCreationUrlState(params: {
|
|||||||
const profileId = normalizeCreationUrlValue(
|
const profileId = normalizeCreationUrlValue(
|
||||||
params.work?.summary.profileId ?? params.session?.draft?.profileId,
|
params.work?.summary.profileId ?? params.session?.draft?.profileId,
|
||||||
);
|
);
|
||||||
|
const draftId = profileId ?? sessionId;
|
||||||
return {
|
return {
|
||||||
sessionId,
|
sessionId,
|
||||||
profileId,
|
profileId,
|
||||||
|
draftId,
|
||||||
workId: normalizeCreationUrlValue(params.work?.summary.workId ?? profileId),
|
workId: normalizeCreationUrlValue(params.work?.summary.workId ?? profileId),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function buildWoodenFishSessionFromWorkDetail(
|
||||||
|
work: WoodenFishWorkProfileResponse,
|
||||||
|
fallbackItem?: WoodenFishWorkSummaryResponse | null,
|
||||||
|
): WoodenFishSessionSnapshotResponse {
|
||||||
|
const sessionId =
|
||||||
|
normalizeCreationUrlValue(work.summary.sourceSessionId) ??
|
||||||
|
normalizeCreationUrlValue(fallbackItem?.sourceSessionId) ??
|
||||||
|
work.summary.profileId;
|
||||||
|
return {
|
||||||
|
sessionId,
|
||||||
|
ownerUserId: work.summary.ownerUserId,
|
||||||
|
status: work.summary.generationStatus,
|
||||||
|
draft: work.draft,
|
||||||
|
createdAt: work.summary.updatedAt,
|
||||||
|
updatedAt: work.summary.updatedAt,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildWoodenFishPendingSession(
|
||||||
|
item: WoodenFishWorkSummaryResponse,
|
||||||
|
): WoodenFishSessionSnapshotResponse {
|
||||||
|
const sessionId =
|
||||||
|
normalizeCreationUrlValue(item.sourceSessionId) ?? item.profileId;
|
||||||
|
return {
|
||||||
|
sessionId,
|
||||||
|
ownerUserId: item.ownerUserId,
|
||||||
|
status: item.generationStatus,
|
||||||
|
draft: {
|
||||||
|
templateId: 'wooden-fish',
|
||||||
|
templateName: '敲木鱼',
|
||||||
|
profileId: item.profileId,
|
||||||
|
workTitle: item.workTitle,
|
||||||
|
workDescription: item.workDescription,
|
||||||
|
themeTags: item.themeTags,
|
||||||
|
hitObjectPrompt: '',
|
||||||
|
hitObjectReferenceImageSrc: null,
|
||||||
|
hitSoundPrompt: null,
|
||||||
|
floatingWords: ['功德 +1'],
|
||||||
|
hitObjectAsset: null,
|
||||||
|
backgroundAsset: null,
|
||||||
|
backButtonAsset: null,
|
||||||
|
hitSoundAsset: null,
|
||||||
|
coverImageSrc: item.coverImageSrc,
|
||||||
|
generationStatus: item.generationStatus,
|
||||||
|
},
|
||||||
|
createdAt: item.updatedAt,
|
||||||
|
updatedAt: item.updatedAt,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function buildBarkBattleCreationUrlState(
|
function buildBarkBattleCreationUrlState(
|
||||||
draft: BarkBattleDraftConfig | null,
|
draft: BarkBattleDraftConfig | null,
|
||||||
): CreationUrlState {
|
): CreationUrlState {
|
||||||
@@ -2480,6 +2532,37 @@ function buildPendingJumpHopWorks(
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function buildPendingWoodenFishWorks(
|
||||||
|
pending: Record<string, PendingDraftShelfState> | undefined,
|
||||||
|
existingItems: readonly WoodenFishWorkSummaryResponse[],
|
||||||
|
): WoodenFishWorkSummaryResponse[] {
|
||||||
|
if (!pending) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return Object.entries(pending)
|
||||||
|
.filter(([sessionId]) =>
|
||||||
|
existingItems.every((item) => item.sourceSessionId !== sessionId),
|
||||||
|
)
|
||||||
|
.map(([sessionId, state]) => ({
|
||||||
|
runtimeKind: 'wooden-fish',
|
||||||
|
workId: `wooden-fish-work-${sessionId}`,
|
||||||
|
profileId: sessionId,
|
||||||
|
ownerUserId: '',
|
||||||
|
sourceSessionId: sessionId,
|
||||||
|
workTitle: '敲木鱼草稿',
|
||||||
|
workDescription: '正在生成敲木鱼草稿。',
|
||||||
|
themeTags: ['敲木鱼'],
|
||||||
|
coverImageSrc: null,
|
||||||
|
publicationStatus: 'draft',
|
||||||
|
playCount: 0,
|
||||||
|
updatedAt: state.updatedAt,
|
||||||
|
publishedAt: null,
|
||||||
|
publishReady: false,
|
||||||
|
generationStatus: state.status === 'generating' ? 'generating' : 'ready',
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
function buildPendingMatch3DWorks(
|
function buildPendingMatch3DWorks(
|
||||||
pending: Record<string, PendingDraftShelfState> | undefined,
|
pending: Record<string, PendingDraftShelfState> | undefined,
|
||||||
existingItems: readonly Match3DWorkSummary[],
|
existingItems: readonly Match3DWorkSummary[],
|
||||||
@@ -4512,8 +4595,14 @@ export function PlatformEntryFlowShellImpl({
|
|||||||
[jumpHopWorks, pendingDraftShelfItems],
|
[jumpHopWorks, pendingDraftShelfItems],
|
||||||
);
|
);
|
||||||
const woodenFishShelfItems = useMemo(
|
const woodenFishShelfItems = useMemo(
|
||||||
() => woodenFishWorks,
|
() => [
|
||||||
[woodenFishWorks],
|
...buildPendingWoodenFishWorks(
|
||||||
|
pendingDraftShelfItems['wooden-fish'],
|
||||||
|
woodenFishWorks,
|
||||||
|
),
|
||||||
|
...woodenFishWorks,
|
||||||
|
],
|
||||||
|
[pendingDraftShelfItems, woodenFishWorks],
|
||||||
);
|
);
|
||||||
const match3dShelfItems = useMemo(
|
const match3dShelfItems = useMemo(
|
||||||
() => [
|
() => [
|
||||||
@@ -8891,6 +8980,33 @@ export function PlatformEntryFlowShellImpl({
|
|||||||
setSelectionStage('wooden-fish-generating');
|
setSelectionStage('wooden-fish-generating');
|
||||||
markDraftGenerating('wooden-fish', [created.session.sessionId]);
|
markDraftGenerating('wooden-fish', [created.session.sessionId]);
|
||||||
markPendingDraftGenerating('wooden-fish', created.session.sessionId);
|
markPendingDraftGenerating('wooden-fish', created.session.sessionId);
|
||||||
|
const createdAt = created.session.updatedAt ?? created.session.createdAt;
|
||||||
|
setWoodenFishWorks((current) => [
|
||||||
|
{
|
||||||
|
runtimeKind: 'wooden-fish',
|
||||||
|
workId: created.session.sessionId,
|
||||||
|
profileId: created.session.sessionId,
|
||||||
|
ownerUserId: created.session.ownerUserId,
|
||||||
|
sourceSessionId: created.session.sessionId,
|
||||||
|
workTitle:
|
||||||
|
payload?.workTitle ?? created.session.draft?.workTitle ?? '敲木鱼',
|
||||||
|
workDescription:
|
||||||
|
payload?.workDescription ??
|
||||||
|
created.session.draft?.workDescription ??
|
||||||
|
'',
|
||||||
|
themeTags: payload?.themeTags ?? created.session.draft?.themeTags ?? ['敲木鱼'],
|
||||||
|
coverImageSrc: created.session.draft?.coverImageSrc ?? null,
|
||||||
|
publicationStatus: 'draft',
|
||||||
|
playCount: 0,
|
||||||
|
updatedAt: createdAt,
|
||||||
|
publishedAt: null,
|
||||||
|
publishReady: false,
|
||||||
|
generationStatus: 'generating',
|
||||||
|
},
|
||||||
|
...current.filter(
|
||||||
|
(item) => item.sourceSessionId !== created.session.sessionId,
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await woodenFishClient.executeAction(
|
const response = await woodenFishClient.executeAction(
|
||||||
@@ -8929,7 +9045,9 @@ export function PlatformEntryFlowShellImpl({
|
|||||||
setWoodenFishWorks((current) => [
|
setWoodenFishWorks((current) => [
|
||||||
response.work!.summary,
|
response.work!.summary,
|
||||||
...current.filter(
|
...current.filter(
|
||||||
(item) => item.workId !== response.work!.summary.workId,
|
(item) =>
|
||||||
|
item.workId !== response.work!.summary.workId &&
|
||||||
|
item.sourceSessionId !== response.work!.summary.sourceSessionId,
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
markPendingDraftReady(
|
markPendingDraftReady(
|
||||||
@@ -11812,18 +11930,43 @@ export function PlatformEntryFlowShellImpl({
|
|||||||
setWoodenFishError(null);
|
setWoodenFishError(null);
|
||||||
setPublicWorkDetailError(null);
|
setPublicWorkDetailError(null);
|
||||||
setIsWoodenFishBusy(true);
|
setIsWoodenFishBusy(true);
|
||||||
|
if (item.generationStatus === 'generating') {
|
||||||
|
const pendingSession = buildWoodenFishPendingSession(item);
|
||||||
|
setWoodenFishSession(pendingSession);
|
||||||
|
setWoodenFishRun(null);
|
||||||
|
setWoodenFishWork(null);
|
||||||
|
writeCreationUrlState(
|
||||||
|
buildWoodenFishCreationUrlState({ session: pendingSession }),
|
||||||
|
);
|
||||||
|
enterCreateTab();
|
||||||
|
setSelectionStage('wooden-fish-generating');
|
||||||
|
setIsWoodenFishBusy(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
const detail = await woodenFishClient.getWorkDetail(item.profileId);
|
const detail = await woodenFishClient.getWorkDetail(item.profileId);
|
||||||
setWoodenFishSession(null);
|
const recoveredSession = buildWoodenFishSessionFromWorkDetail(
|
||||||
|
detail.item,
|
||||||
|
item,
|
||||||
|
);
|
||||||
|
setWoodenFishSession(recoveredSession);
|
||||||
setWoodenFishRun(null);
|
setWoodenFishRun(null);
|
||||||
setWoodenFishWork(detail.item);
|
setWoodenFishWork(detail.item);
|
||||||
setWoodenFishRuntimeReturnStage('wooden-fish-result');
|
setWoodenFishRuntimeReturnStage('wooden-fish-result');
|
||||||
|
writeCreationUrlState(
|
||||||
|
buildWoodenFishCreationUrlState({
|
||||||
|
session: recoveredSession,
|
||||||
|
work: detail.item,
|
||||||
|
}),
|
||||||
|
);
|
||||||
enterCreateTab();
|
enterCreateTab();
|
||||||
setSelectionStage('wooden-fish-result');
|
setSelectionStage('wooden-fish-result');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setWoodenFishError(
|
setWoodenFishError(
|
||||||
resolveRpgCreationErrorMessage(error, '读取敲木鱼草稿失败。'),
|
resolveRpgCreationErrorMessage(error, '读取敲木鱼草稿失败。'),
|
||||||
);
|
);
|
||||||
|
enterCreateTab();
|
||||||
|
setSelectionStage('wooden-fish-generating');
|
||||||
} finally {
|
} finally {
|
||||||
setIsWoodenFishBusy(false);
|
setIsWoodenFishBusy(false);
|
||||||
}
|
}
|
||||||
@@ -11832,6 +11975,7 @@ export function PlatformEntryFlowShellImpl({
|
|||||||
enterCreateTab,
|
enterCreateTab,
|
||||||
markDraftNoticeSeen,
|
markDraftNoticeSeen,
|
||||||
openWoodenFishPublicWorkDetail,
|
openWoodenFishPublicWorkDetail,
|
||||||
|
writeCreationUrlState,
|
||||||
setSelectionStage,
|
setSelectionStage,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user