From 3b76c2611e28886cc90732b9b6183eff5f8ec403 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BE=B7=E5=AE=87?= Date: Wed, 30 Sep 2026 13:33:02 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B8=B8=E6=88=8F=E5=88=86=E5=8F=91=E5=9B=9B?= =?UTF-8?q?=E4=B8=AA=E9=A1=B5=E9=9D=A2=E7=9A=84=E8=BF=94=E5=9B=9E=E6=8C=89?= =?UTF-8?q?=E9=92=AE=E6=96=87=E6=A1=88=E7=BB=9F=E4=B8=80=E6=88=90=E3=80=8C?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=E3=80=8D=20-=20GamePlayPage=20=E8=BF=94?= =?UTF-8?q?=E5=9B=9E=E8=AF=A6=E6=83=85=20=E2=86=92=20=E8=BF=94=E5=9B=9E?= =?UTF-8?q?=EF=BC=88=E5=90=AB=E5=90=AF=E5=8A=A8=E8=B6=85=E6=97=B6=E9=9D=A2?= =?UTF-8?q?=E6=9D=BF=E9=87=8C=E7=9A=84=E6=8C=89=E9=92=AE=EF=BC=89=20-=20My?= =?UTF-8?q?GamesPage=20=E4=B8=8E=20GamePublishPage=EF=BC=88=E4=B8=89?= =?UTF-8?q?=E5=A4=84=E5=88=86=E6=94=AF=EF=BC=89=E8=BF=94=E5=9B=9E=E6=B8=B8?= =?UTF-8?q?=E6=88=8F=E5=B9=BF=E5=9C=BA=20=E2=86=92=20=E8=BF=94=E5=9B=9E=20?= =?UTF-8?q?-=20=E7=9B=AE=E6=A0=87=E9=A1=B5=E4=BB=8D=E7=94=B1=E5=90=84?= =?UTF-8?q?=E8=87=AA=20onBack=20=E5=86=B3=E5=AE=9A=EF=BC=8C=E6=8C=89?= =?UTF-8?q?=E9=92=AE=E4=B8=8D=E5=86=8D=E6=89=BF=E8=AF=BA=E5=8F=AF=E8=83=BD?= =?UTF-8?q?=E4=B8=8D=E5=AF=B9=E7=9A=84=E7=9B=AE=E7=9A=84=E5=9C=B0=20-=20Ga?= =?UTF-8?q?meDistributionPages.test.tsx=20=E8=B6=85=E6=97=B6=E7=94=A8?= =?UTF-8?q?=E4=BE=8B=E6=96=AD=E8=A8=80=E6=94=B9=E4=B8=BA=20/^=E8=BF=94?= =?UTF-8?q?=E5=9B=9E$/u=20-=20=E5=90=8C=E6=AD=A5=E9=87=8C=E7=A8=8B?= =?UTF-8?q?=E7=A2=91=E6=96=87=E6=A1=A3=E4=B8=8E=E7=8E=A9=E6=B3=95=E9=93=BE?= =?UTF-8?q?=E8=B7=AF=E6=96=87=E6=A1=A3=E7=9A=84=E8=BF=94=E5=9B=9E=E6=96=87?= =?UTF-8?q?=E6=A1=88=E6=8F=8F=E8=BF=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../【里程碑】游戏分发目录详情与在线游玩-2026-09-18.md | 3 ++- docs/【玩法创作】平台入口与玩法链路-2026-05-15.md | 2 +- .../game-distribution/GameDistributionPages.test.tsx | 4 ++-- src/components/game-distribution/GamePlayPage.tsx | 4 ++-- src/components/game-distribution/GamePublishPage.tsx | 6 +++--- src/components/game-distribution/MyGamesPage.tsx | 2 +- 6 files changed, 11 insertions(+), 10 deletions(-) diff --git a/docs/project-memory/plans/【里程碑】游戏分发目录详情与在线游玩-2026-09-18.md b/docs/project-memory/plans/【里程碑】游戏分发目录详情与在线游玩-2026-09-18.md index e3bb04b9a..7d22dd8c7 100644 --- a/docs/project-memory/plans/【里程碑】游戏分发目录详情与在线游玩-2026-09-18.md +++ b/docs/project-memory/plans/【里程碑】游戏分发目录详情与在线游玩-2026-09-18.md @@ -330,5 +330,6 @@ - **页签面板左右留白对齐**:`.platform-tab-panel` 原本写死 `padding-right`(并在移动端与 workbench 两处再压成 0),而它是不分层规则、优先级高于 Tailwind 的 `padding-inline`,导致面板左 12/24px、右 0,列表左右留白 28/16。三处 `padding-right` 删除后左右统一由使用处的 `px-3`/`sm:px-6` 决定:390 下 12/12(列表 28/28)、820 下 24/24(列表 44/44),无 px 类的舞台仍是 0/0;Chromium 夹具实测「我的游戏」与画廊两张页面同时恢复对称,且横向溢出保持 0。 - **广场的「发布游戏」「我的游戏」上移到 hero 右上角**:两个入口原本混在 hero 下方的 `.game-toolbar` 动作区(和搜索框同排),现在提到 `.game-page-actions` 一行、右对齐放在 hero 上方,并留 1.1rem 底部间距;工具栏只保留标题与搜索。未登录或灰度未命中时两者都不渲染,该行随之消失。Chromium 夹具实测 390/360/820 三档都是 `aboveHero=true`、与 hero 间距 18px、右边缘与 hero 对齐。 - 真机口径的守卫补在现役 E2E 里:`scripts/check-game-distribution-web-e2e.mjs` 的移动端段新增「移动端游玩页不可滚动(面板与整页都不溢出)」,断言 `.platform-tab-panel` 的 `overflow-y` 为 `hidden`,且面板与整页**横竖两轴**都不溢出(面板自身 `overflow-x: hidden`,横向溢出只会被静默裁掉,只量 `scrollHeight` 会漏掉「内容被裁一半」)。(该脚本需要管理员账号发布一款真实游戏,未在本轮执行;同一批数值用 Chromium 直连 dev 栈的 `/games/play?id=…` 量过,见 pitfalls 同日条目。) -- **详情页返回按来源回到上一页**:`GameDetailPage` 左上角原来是写死的「返回游戏广场」,并且直接 `setSelectionStage('games')`(等于 push 一条新的 `/games`)。从「我的游戏」点进详情再返回就落到广场,从广场进详情返回也会多压一条重复历史。现在文案简化为「返回」,行为改成优先 `window.history.back()`,由 `ActiveApp` 已有的 `popstate` 同步把舞台还原成真正的来源页(我的游戏 / 广场);游玩页的「返回详情」同样处理,避免详情↔游玩互相 push。协议侧给应用写入的历史条目补了 `__genarrativeAppHistoryDepth`,新增 `hasAppHistoryBackEntry()` 判断「当前条目是应用内导航写入的且存在上一页」;直接打开详情深链、或原生壳里没有可回退条目时,才 `replaceAppHistoryPath` 兜底到广场(游玩页兜底到自己的详情)。回归用例 `activeAppPageRoutes.test.ts` 锁定深度标记语义,`PlatformEntryActiveFlowShell.test.tsx`「游戏详情返回」两条锁定原生返回与深链兜底。 +- **详情页返回按来源回到上一页**:`GameDetailPage` 左上角原来是写死的「返回游戏广场」,并且直接 `setSelectionStage('games')`(等于 push 一条新的 `/games`)。从「我的游戏」点进详情再返回就落到广场,从广场进详情返回也会多压一条重复历史。现在文案简化为「返回」,行为改成优先 `window.history.back()`,由 `ActiveApp` 已有的 `popstate` 同步把舞台还原成真正的来源页(我的游戏 / 广场);游玩页的返回同样处理,避免详情↔游玩互相 push。协议侧给应用写入的历史条目补了 `__genarrativeAppHistoryDepth`,新增 `hasAppHistoryBackEntry()` 判断「当前条目是应用内导航写入的且存在上一页」;直接打开详情深链、或原生壳里没有可回退条目时,才 `replaceAppHistoryPath` 兜底到广场(游玩页兜底到自己的详情)。回归用例 `activeAppPageRoutes.test.ts` 锁定深度标记语义,`PlatformEntryActiveFlowShell.test.tsx`「游戏详情返回」两条锁定原生返回与深链兜底。 +- **游戏分发的返回文案统一成「返回」**:`GameDetailPage`、`GamePlayPage`(含超时面板里的按钮)、`MyGamesPage`、`GamePublishPage` 四处原本是「返回游戏广场 / 返回详情」,同一套流程里出现三种写法;现在统一成「返回」,目标页仍由各自的 `onBack`(广场 / 我的游戏 / 详情)决定,按钮不再承诺一个可能不对的目的地。`GameDistributionPages.test.tsx` 的断言同步改为 `/^返回$/u`。游玩页工具栏上那个按钮展示的是游戏名(退出开始面板后就靠它认游戏),不属于「返回 xx」文案,保持不动。 - 验证:`npx vitest run src/components/game-distribution/GameDistributionPages.test.tsx`(21 passed)、`npx vitest run src/components/platform-entry/PlatformEntryActiveFlowShell.test.tsx`(22 passed)、`npx vitest run src/routing/activeAppPageRoutes.test.ts`、`npm run typecheck`、`npx eslint`(五个改动文件)、`npm run check:encoding`、`git diff --check` 全部通过;启动面板的溢出可达性、「我的游戏」移动端横向溢出都用真实 Chromium 静态夹具量过(见 pitfalls 同日条目),详情返回链在真实 Chromium(dev 栈 390x844)实测 `/games`→详情→返回=`/games`、深链直开详情→返回=`/games`、详情→立即玩→返回详情=`/games/detail?id=…`。视觉与真机横竖屏走查仍需人工/截图评审(沿用阶段 C 第 8 条未取证口径)。 diff --git a/docs/【玩法创作】平台入口与玩法链路-2026-05-15.md b/docs/【玩法创作】平台入口与玩法链路-2026-05-15.md index 99e4c004a..8e98e71bf 100644 --- a/docs/【玩法创作】平台入口与玩法链路-2026-05-15.md +++ b/docs/【玩法创作】平台入口与玩法链路-2026-05-15.md @@ -72,7 +72,7 @@ - 游戏目录 `/games`、详情 `/games/detail?id=`、游玩 `/games/play?id=`;作者管理 `/games/mine` 只列当前账号的游戏和发行状态。平台壳及既有账号页提供入口,不建立第二套账号或作品系统。 - 目录使用重点推荐位和紧凑卡片网格,首版推荐位只消费后台明确设置且已公开的游戏;其余列表按发布时间排列。支持关键词、分类与设备筛选,筛选写入 URL,返回列表恢复筛选和滚动位置;没有内容时展示真实空态。 - 详情的主动作是“立即玩”,展示封面、标题、作者、短简介、设备标识、截图和简短操作方式;不虚构评分、玩家数、排名和收藏状态。游客浏览详情及启动游戏均无需登录;上传、更新、撤回和作者管理需要当前平台登录态。 -- 游玩页先展示封面与开始按钮,用户点击后加载游戏,避免列表自动加载多个 iframe 或自动播音;提供加载、超时、重试、返回详情和全屏。iframe 的 `load` 事件只表示文档已加载,不宣称已经通过运行验证;首版不把 iframe 消息当平台业务状态。 +- 游玩页先展示封面与开始按钮,用户点击后加载游戏,避免列表自动加载多个 iframe 或自动播音;提供加载、超时、重试、返回和全屏。iframe 的 `load` 事件只表示文档已加载,不宣称已经通过运行验证;首版不把 iframe 消息当平台业务状态。 - 移动端优先采用全宽内容、底部主要动作、至少 44px 点击区域,覆盖安全区、横竖屏和键盘焦点。游戏声明仅支持桌面时,手机详情保留可浏览内容并禁用开始,明确显示“请在电脑上游玩”;横屏游戏提供旋转提示,但不能把系统方向锁定成功作为启动前提。 - 视觉延续当前暖色主题 token、米白/浅暖背景、橙色主动作与现有字体;通过封面占比、留白、圆角和清晰状态层级现代化呈现,不另建配色系统。通用卡片动作、弹窗、上传、状态反馈、空态与媒体预览优先复用共享组件。发布打开独立弹窗/抽屉,不在当前页面末尾追加表单;技术信息仅在失败诊断或确需用户决策时展示。 diff --git a/src/components/game-distribution/GameDistributionPages.test.tsx b/src/components/game-distribution/GameDistributionPages.test.tsx index f550408c7..8c2c4a430 100644 --- a/src/components/game-distribution/GameDistributionPages.test.tsx +++ b/src/components/game-distribution/GameDistributionPages.test.tsx @@ -422,7 +422,7 @@ describe('GameGalleryPage 筛选与返回上下文', () => { }); describe('GamePlayPage 启动超时与旋转提示', () => { - it('启动超时后给出重试与返回详情,重试可恢复可玩', async () => { + it('启动超时后给出重试与返回,重试可恢复可玩', async () => { vi.useFakeTimers(); try { const onBack = vi.fn(); @@ -439,7 +439,7 @@ describe('GamePlayPage 启动超时与旋转提示', () => { vi.advanceTimersByTime(GAME_PLAY_STARTUP_TIMEOUT_MS); }); expect(screen.getByText(/启动超时/u)).toBeTruthy(); - expect(screen.getByRole('button', { name: /返回详情/u })).toBeTruthy(); + expect(screen.getByRole('button', { name: /^返回$/u })).toBeTruthy(); fireEvent.click(screen.getByRole('button', { name: /^重试$/u })); const retriedFrame = screen.getByTitle('星轨防线 在线游玩'); diff --git a/src/components/game-distribution/GamePlayPage.tsx b/src/components/game-distribution/GamePlayPage.tsx index 615af9d18..ecd1df9d5 100644 --- a/src/components/game-distribution/GamePlayPage.tsx +++ b/src/components/game-distribution/GamePlayPage.tsx @@ -126,7 +126,7 @@ export function GamePlayPage({ gameId, onBack }: GamePlayPageProps) { return (
) : null} diff --git a/src/components/game-distribution/GamePublishPage.tsx b/src/components/game-distribution/GamePublishPage.tsx index a6fecdab8..514c098d5 100644 --- a/src/components/game-distribution/GamePublishPage.tsx +++ b/src/components/game-distribution/GamePublishPage.tsx @@ -670,7 +670,7 @@ export function GamePublishPage({ return (
正在检查发布灰度… @@ -683,7 +683,7 @@ export function GamePublishPage({ return (
@@ -709,7 +709,7 @@ export function GamePublishPage({ return (
diff --git a/src/components/game-distribution/MyGamesPage.tsx b/src/components/game-distribution/MyGamesPage.tsx index 2cfd1ed06..afa8f7dac 100644 --- a/src/components/game-distribution/MyGamesPage.tsx +++ b/src/components/game-distribution/MyGamesPage.tsx @@ -160,7 +160,7 @@ export function MyGamesPage({ return (