diff --git a/apps/ai-game-creator-shell/src/App.tsx b/apps/ai-game-creator-shell/src/App.tsx
index a26db09ca..57695ad3f 100644
--- a/apps/ai-game-creator-shell/src/App.tsx
+++ b/apps/ai-game-creator-shell/src/App.tsx
@@ -16,7 +16,6 @@ import {
BookOpen,
CircleHelp,
Contact,
- CreditCard,
FileText,
FolderKanban,
Gamepad2,
@@ -29,8 +28,8 @@ import {
Sparkles,
Upload,
User,
- Wallet,
X,
+ Zap,
} from 'lucide-react';
import type {
@@ -2168,6 +2167,11 @@ export function WorkspaceLauncher({
const [walletLedgerStatus, setWalletLedgerStatus] =
useState('尚未读取明细');
const [accountMenuOpen, setAccountMenuOpen] = useState(false);
+ const [helpMenuOpen, setHelpMenuOpen] = useState(false);
+ const [launcherNotice, setLauncherNotice] = useState<{
+ title: string;
+ message: string;
+ } | null>(null);
const [showcaseResources, setShowcaseResources] = useState<
EditorShowcaseResource[]
>([]);
@@ -2702,6 +2706,15 @@ export function WorkspaceLauncher({
}
}
+ function showLauncherNotice(title: string) {
+ setAccountMenuOpen(false);
+ setHelpMenuOpen(false);
+ setLauncherNotice({
+ title,
+ message: `${title}正在接入中,当前版本会先保留入口。`,
+ });
+ }
+
function handleRecentWorkspaceRefresh() {
if (recentWorkspaces.length === 0 || recentWorkspaceRefreshing) {
return;
@@ -2985,7 +2998,12 @@ export function WorkspaceLauncher({
-
- setLauncherView('guide')}
- >
-
- 使用指南
-
- setLauncherView('contact')}
- >
-
- 联系我们
-
- setLauncherView('news')}
- >
-
- 最新动态
-
-
+ {helpMenuOpen ? (
+
+ showLauncherNotice('使用指南')}
+ >
+
+ 使用指南
+
+ showLauncherNotice('联系我们')}
+ >
+
+ 联系我们
+
+ showLauncherNotice('最新动态')}
+ >
+
+ 最新动态
+
+
+ ) : null}
setWalletPanelOpen((open) => !open)}
+ onClick={() => {
+ setAccountMenuOpen(false);
+ setHelpMenuOpen(false);
+ setWalletPanelOpen((open) => !open);
+ }}
>
-
+
{formatMudPoints(profileDashboard?.walletBalance)}
{walletPanelOpen ? (
@@ -3129,9 +3159,8 @@ export function WorkspaceLauncher({
) : null}
- setWalletPanelOpen(true)}>
-
- 充值
+ showLauncherNotice('升级')}>
+ 升级
@@ -3631,6 +3660,35 @@ export function WorkspaceLauncher({
{runtimeConfigOpen ? (
setRuntimeConfigOpen(false)} />
) : null}
+ {launcherNotice ? (
+ {
+ if (event.target === event.currentTarget) {
+ setLauncherNotice(null);
+ }
+ }}
+ >
+
+ closeDialogOnEscape(event, () => setLauncherNotice(null))
+ }
+ >
+ {launcherNotice.title}
+ {launcherNotice.message}
+
+ setLauncherNotice(null)}>
+ 知道了
+
+
+
+
+ ) : null}
{pendingNonEmptyProject ? (
button,
@@ -370,8 +364,14 @@ textarea {
border-radius: 0;
}
+.launcher-wallet-group .launcher-wallet-anchor > button {
+ border-radius: 8px 0 0 8px;
+ font-weight: 500;
+}
+
.launcher-wallet-group > button {
border-left: 1px solid #e5e7eb;
+ border-radius: 0 8px 8px 0;
}
.launcher-wallet-anchor {
@@ -393,7 +393,7 @@ textarea {
background: #fff;
box-shadow: 0 16px 38px rgb(15 23 42 / 14%);
color: #111827;
- z-index: 9;
+ z-index: 90;
}
.launcher-account-nav .launcher-account-popover {
@@ -401,6 +401,9 @@ textarea {
right: auto;
bottom: -4px;
left: 36px;
+ width: 218px;
+ gap: 6px;
+ padding: 10px;
}
.launcher-account-popover strong,
@@ -423,7 +426,7 @@ textarea {
height: 30px;
padding: 0 8px;
border: 0;
- background: #f8fafc;
+ background: transparent;
color: #111827;
}
@@ -1483,6 +1486,7 @@ textarea {
.launcher-dialog-backdrop {
position: fixed;
inset: 0;
+ z-index: 200;
display: grid;
padding: 24px;
background: rgb(0 0 0 / 56%);
diff --git a/apps/ai-game-creator-shell/tests/appSurface.test.ts b/apps/ai-game-creator-shell/tests/appSurface.test.ts
index 6dc69fcb6..190038d21 100644
--- a/apps/ai-game-creator-shell/tests/appSurface.test.ts
+++ b/apps/ai-game-creator-shell/tests/appSurface.test.ts
@@ -798,7 +798,7 @@ describe('AI 游戏创作 App 界面边界', () => {
).not.toBeNull();
expect(
within(screen.getByLabelText('账户资产')).getByRole('button', {
- name: '充值',
+ name: '升级',
}),
).not.toBeNull();
expect(
@@ -831,6 +831,34 @@ describe('AI 游戏创作 App 界面边界', () => {
).toContain('/tmp/authorized-game');
});
+ it('opens account and help menus by click and routes placeholder items to one notice dialog', () => {
+ renderLauncherAt('/?launcher');
+
+ expect(
+ screen.queryByRole('menuitem', { name: '联系我们' }),
+ ).toBeNull();
+ fireEvent.click(screen.getByRole('button', { name: '帮助' }));
+ expect(
+ screen.getByRole('menuitem', { name: '联系我们' }),
+ ).not.toBeNull();
+ fireEvent.click(screen.getByRole('menuitem', { name: '联系我们' }));
+ expect(screen.getByRole('dialog', { name: '联系我们' })).not.toBeNull();
+ expect(
+ screen.getByText('联系我们正在接入中,当前版本会先保留入口。'),
+ ).not.toBeNull();
+ fireEvent.click(screen.getByRole('button', { name: '知道了' }));
+
+ fireEvent.click(screen.getByRole('button', { name: '我的' }));
+ expect(
+ screen.getByRole('menuitem', { name: '会员与升级' }),
+ ).not.toBeNull();
+ fireEvent.click(screen.getByRole('menuitem', { name: '会员与升级' }));
+ expect(screen.getByRole('dialog', { name: '会员与升级' })).not.toBeNull();
+ expect(
+ screen.getByText('会员与升级正在接入中,当前版本会先保留入口。'),
+ ).not.toBeNull();
+ });
+
it('opens the developer agent chat entry and persists selected agent messages', async () => {
const persistedMessages: Array<{
role: 'user' | 'assistant' | 'tool';