Add platform generation dialogs and task refresh
This commit is contained in:
@@ -3404,6 +3404,7 @@ export function PlatformEntryFlowShellImpl({
|
|||||||
})
|
})
|
||||||
| null
|
| null
|
||||||
>(null);
|
>(null);
|
||||||
|
const [profileTaskRefreshKey, setProfileTaskRefreshKey] = useState(0);
|
||||||
const [initialCreationUrlState] = useState(() => readCreationUrlState());
|
const [initialCreationUrlState] = useState(() => readCreationUrlState());
|
||||||
const handledInitialCreationUrlStateRef = useRef(false);
|
const handledInitialCreationUrlStateRef = useRef(false);
|
||||||
const [initialPuzzleRuntimeUrlState] = useState(() =>
|
const [initialPuzzleRuntimeUrlState] = useState(() =>
|
||||||
@@ -3549,7 +3550,7 @@ export function PlatformEntryFlowShellImpl({
|
|||||||
'ready',
|
'ready',
|
||||||
viewedImmediately,
|
viewedImmediately,
|
||||||
);
|
);
|
||||||
if (!viewedImmediately) {
|
setProfileTaskRefreshKey((current) => current + 1);
|
||||||
const completedAtMs = Date.now();
|
const completedAtMs = Date.now();
|
||||||
setPendingPlatformTaskCompletionDialog({
|
setPendingPlatformTaskCompletionDialog({
|
||||||
key: `${kind}:${collectDraftNoticeKeys(kind, ids).join('|')}:${completedAtMs}`,
|
key: `${kind}:${collectDraftNoticeKeys(kind, ids).join('|')}:${completedAtMs}`,
|
||||||
@@ -3557,7 +3558,6 @@ export function PlatformEntryFlowShellImpl({
|
|||||||
message: '生成任务已完成,可以继续查看草稿。',
|
message: '生成任务已完成,可以继续查看草稿。',
|
||||||
completedAtMs,
|
completedAtMs,
|
||||||
});
|
});
|
||||||
}
|
|
||||||
},
|
},
|
||||||
[setPendingPlatformTaskCompletionDialog, updateDraftGenerationNotices],
|
[setPendingPlatformTaskCompletionDialog, updateDraftGenerationNotices],
|
||||||
);
|
);
|
||||||
@@ -14755,6 +14755,7 @@ export function PlatformEntryFlowShellImpl({
|
|||||||
isLoadingPlatform={platformBootstrap.isLoadingPlatform}
|
isLoadingPlatform={platformBootstrap.isLoadingPlatform}
|
||||||
isLoadingDashboard={platformBootstrap.isLoadingDashboard}
|
isLoadingDashboard={platformBootstrap.isLoadingDashboard}
|
||||||
hasUnreadDraftUpdate={hasUnreadDraftUpdates}
|
hasUnreadDraftUpdate={hasUnreadDraftUpdates}
|
||||||
|
profileTaskRefreshKey={profileTaskRefreshKey}
|
||||||
isDesktopLayout={isDesktopLayout}
|
isDesktopLayout={isDesktopLayout}
|
||||||
isResumingSaveWorldKey={platformBootstrap.isResumingSaveWorldKey}
|
isResumingSaveWorldKey={platformBootstrap.isResumingSaveWorldKey}
|
||||||
platformError={
|
platformError={
|
||||||
|
|||||||
@@ -7137,6 +7137,48 @@ test('persisted generating puzzle draft keeps session polling on the same sessio
|
|||||||
expect(getPuzzleAgentSession).toHaveBeenCalledTimes(2);
|
expect(getPuzzleAgentSession).toHaveBeenCalledTimes(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('puzzle compile timeout shows failure dialog when reread session is still generating', async () => {
|
||||||
|
const user = userEvent.setup();
|
||||||
|
const runningSession = buildMockPuzzleAgentSession({
|
||||||
|
sessionId: 'puzzle-session-timeout',
|
||||||
|
draft: null,
|
||||||
|
stage: 'collecting_anchors',
|
||||||
|
progressPercent: 88,
|
||||||
|
lastAssistantReply: '正在生成拼图草稿。',
|
||||||
|
});
|
||||||
|
vi.mocked(createPuzzleAgentSession).mockResolvedValueOnce({
|
||||||
|
session: runningSession,
|
||||||
|
});
|
||||||
|
vi.mocked(executePuzzleAgentAction).mockRejectedValueOnce(
|
||||||
|
Object.assign(new Error('请求超时:1800000ms'), {
|
||||||
|
name: 'TimeoutError',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
vi.mocked(getPuzzleAgentSession).mockResolvedValue({
|
||||||
|
session: runningSession,
|
||||||
|
});
|
||||||
|
|
||||||
|
render(<TestWrapper withAuth />);
|
||||||
|
|
||||||
|
await openCreateTemplateHub(user);
|
||||||
|
await user.click(await findCreationTypeButton('拼图'));
|
||||||
|
await user.click(await screen.findByRole('button', { name: '生成草稿' }));
|
||||||
|
|
||||||
|
const dialog = await screen.findByRole('dialog', { name: '发生错误' });
|
||||||
|
expect(within(dialog).getByText('拼图草稿 puzzle-session-timeout')).toBeTruthy();
|
||||||
|
expect(
|
||||||
|
within(dialog).getByText(
|
||||||
|
'拼图共创操作超时,请确认运行时后端已启动后重试。',
|
||||||
|
),
|
||||||
|
).toBeTruthy();
|
||||||
|
expect(within(dialog).getByRole('button', { name: '复制报错' })).toBeTruthy();
|
||||||
|
expect(
|
||||||
|
await screen.findByRole('progressbar', {
|
||||||
|
name: '拼图草稿生成进度',
|
||||||
|
}),
|
||||||
|
).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
test('published puzzle work card restores its source session for editing', async () => {
|
test('published puzzle work card restores its source session for editing', async () => {
|
||||||
const user = userEvent.setup();
|
const user = userEvent.setup();
|
||||||
|
|
||||||
|
|||||||
@@ -216,6 +216,7 @@ export interface RpgEntryHomeViewProps {
|
|||||||
onOpenPlayedWork?: (work: ProfilePlayedWorkSummary) => void;
|
onOpenPlayedWork?: (work: ProfilePlayedWorkSummary) => void;
|
||||||
onOpenFeedback?: () => void;
|
onOpenFeedback?: () => void;
|
||||||
onRechargeSuccess?: () => void | Promise<void>;
|
onRechargeSuccess?: () => void | Promise<void>;
|
||||||
|
profileTaskRefreshKey?: number;
|
||||||
createTabContent?: ReactNode;
|
createTabContent?: ReactNode;
|
||||||
draftTabContent?: ReactNode;
|
draftTabContent?: ReactNode;
|
||||||
hasUnreadDraftUpdate?: boolean;
|
hasUnreadDraftUpdate?: boolean;
|
||||||
@@ -3983,6 +3984,7 @@ export function RpgEntryHomeView({
|
|||||||
onOpenPlayedWork,
|
onOpenPlayedWork,
|
||||||
onOpenFeedback,
|
onOpenFeedback,
|
||||||
onRechargeSuccess,
|
onRechargeSuccess,
|
||||||
|
profileTaskRefreshKey = 0,
|
||||||
createTabContent,
|
createTabContent,
|
||||||
draftTabContent,
|
draftTabContent,
|
||||||
hasUnreadDraftUpdate = false,
|
hasUnreadDraftUpdate = false,
|
||||||
@@ -4798,7 +4800,7 @@ export function RpgEntryHomeView({
|
|||||||
}
|
}
|
||||||
|
|
||||||
loadTaskCenter();
|
loadTaskCenter();
|
||||||
}, [activeTab, isAuthenticated, loadTaskCenter]);
|
}, [activeTab, isAuthenticated, loadTaskCenter, profileTaskRefreshKey]);
|
||||||
|
|
||||||
const openTaskCenterPanel = () => {
|
const openTaskCenterPanel = () => {
|
||||||
setIsTaskCenterOpen(true);
|
setIsTaskCenterOpen(true);
|
||||||
|
|||||||
@@ -9,6 +9,9 @@ import type { CustomWorldProfile } from '../../types';
|
|||||||
|
|
||||||
export function resolveRpgEntryErrorMessage(error: unknown, fallback: string) {
|
export function resolveRpgEntryErrorMessage(error: unknown, fallback: string) {
|
||||||
if (isTimeoutError(error)) {
|
if (isTimeoutError(error)) {
|
||||||
|
if (/拼图/u.test(fallback) && /操作|执行|编译|生成草稿/u.test(fallback)) {
|
||||||
|
return '拼图共创操作超时,请确认运行时后端已启动后重试。';
|
||||||
|
}
|
||||||
if (/智能创作/u.test(fallback)) {
|
if (/智能创作/u.test(fallback)) {
|
||||||
return '开启智能创作工作区超时,请确认运行时后端已启动后重试。';
|
return '开启智能创作工作区超时,请确认运行时后端已启动后重试。';
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user