diff --git a/apps/ai-game-creator-shell/src/features/app-shell/LauncherNoticeToast.tsx b/apps/ai-game-creator-shell/src/features/app-shell/LauncherNoticeToast.tsx new file mode 100644 index 000000000..156322c7e --- /dev/null +++ b/apps/ai-game-creator-shell/src/features/app-shell/LauncherNoticeToast.tsx @@ -0,0 +1,91 @@ +import { PlatformRuntimeStatusToast } from '@genarrative/shared/components'; +import { useEffect, useRef } from 'react'; +import { createPortal } from 'react-dom'; + +import type { LauncherNoticeTone } from './model'; + +/** + * 一次性提示的时长:成功一闪而过就够;失败要留得够久,用户得看清是什么没跑起来。 + * + * 「运行 / 预览失败」这类错误已经不再写对话区(那里只保留对话内容),所以这枚 toast 是它 + * 唯一的出口——2.6 秒对错误太短。「已取消」这类回显也走同一套时长:它是「什么都没发生」, + * 不需要用户回头再看。承接原状态栏的状态不在这张表里,它们走 `sticky`。 + */ +const LAUNCHER_NOTICE_MILLIS: Record = { + success: 2600, + neutral: 2600, + error: 6000, +}; + +export type LauncherNotice = { + /** 每次提示自增,保证重复触发同一个文案时也会重新弹一次。 */ + id: number; + message: string; + tone?: LauncherNoticeTone; + /** + * 粘性提示不自动收起,直到被下一条提示替换。 + * + * 原来那行状态栏(进行中进度、失败结论)就是这种生存期:它要能被回头看见,不能自己消失; + * 只有「已取消」这类一次性回显才到点收起。 + */ + sticky?: boolean; +}; + +/** + * 外壳级浮层提示。 + * + * 承接三类反馈,页面上都不留文字: + * 1. 运行 / 预览类动作——以前以 assistant 消息写进对话区,会一直堆在对话底部挡住运行画面; + * 运行页的预览地址改用顶栏的「在浏览器打开」。 + * 2. 状态栏里的状态(进行中进度、失败结论、成功回显)——以前常驻在首页输入框下方和项目组页面 + * 头部那一行;现在走粘性浮层,语义不变(被下一条状态替换或清空时才消失)。 + * 3. 「已取消」这类一次性回显——到点自动收起。 + */ +export function LauncherNoticeToast({ + notice, + onDismiss, +}: { + notice: LauncherNotice | null; + onDismiss: () => void; +}) { + /** + * 收起回调只从 ref 读:外壳每渲染一次就会换一个内联箭头函数,把它写进 effect 依赖会 + * 让计时器在每次重渲染时重新起算——长驻页面上的提示就永远收不回去了。 + */ + const onDismissRef = useRef(onDismiss); + onDismissRef.current = onDismiss; + useEffect(() => { + if (!notice || notice.sticky) { + return; + } + const timer = window.setTimeout( + () => onDismissRef.current(), + LAUNCHER_NOTICE_MILLIS[notice.tone ?? 'success'], + ); + return () => { + window.clearTimeout(timer); + }; + }, [notice]); + + if (!notice) { + return null; + } + return createPortal( +
+ + {notice.message} + +
, + document.body, + ); +} diff --git a/apps/ai-game-creator-shell/src/features/app-shell/ProjectCreation.tsx b/apps/ai-game-creator-shell/src/features/app-shell/ProjectCreation.tsx index c6b9a06c1..925a01cd9 100644 --- a/apps/ai-game-creator-shell/src/features/app-shell/ProjectCreation.tsx +++ b/apps/ai-game-creator-shell/src/features/app-shell/ProjectCreation.tsx @@ -180,11 +180,9 @@ function ProjectMoreMenu({ } export function ProjectsPage({ - status, homeProject, recentProjects, }: { - status: string; homeProject: HomeProjectCreationController; recentProjects: RecentProjectsController; }) { @@ -249,11 +247,6 @@ export function ProjectsPage({

项目

-

- {recentProjects.recentWorkspaceRefreshing - ? '正在检查项目状态' - : status} -