修导航高亮:从共创侧进的详情/族谱/对比也高亮「共创」(复用入口来源标记,判定收敛在一处)
Project CI / Backend tests (pull_request) Failing after 22s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Successful in 7m17s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 4m30s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Successful in 6m27s
Project CI / Repository checks (pull_request) Failing after 26s
Project CI / Frontend tests (pull_request) Successful in 3m13s
Project CI / AI game creator shell web tests (pull_request) Failing after 3m32s
Project CI / Native shell tests (pull_request) Successful in 8m50s

This commit is contained in:
2026-10-07 19:45:55 +08:00
parent efe6138ede
commit 8458113c94
2 changed files with 98 additions and 10 deletions
@@ -1674,6 +1674,71 @@ describe('共创顶层入口(只列支持共创的作品)', () => {
).toBeNull();
});
it('导航高亮认「入口来源」:从共创侧进的详情高亮共创,其余高亮游戏(用户报的 bug)', async () => {
gameDistributionMock.getGame.mockResolvedValue({
id: 'game-1',
title: '作品',
summary: '简介',
description: '',
category: '动作',
tags: [],
coverColor: '#d77a51',
icon: '✦',
author: { id: 'author-1', name: '测试作者' },
deviceSupport: { desktop: true, mobile: true, touch: true },
status: 'published',
currentVersion: null,
playCount: 0,
createdAt: '2026-09-18T00:00:00.000Z',
forkCount: 0,
});
const cases = [
{
expected: '共创',
title: '共创页点卡(带 from=co-creation)',
url: '/games/detail?id=game-1&from=co-creation',
},
{
expected: '游戏',
title: '游戏页点卡(无来源标记)',
url: '/games/detail?id=game-1',
},
{
expected: '共创',
title: '族谱页(共创侧才进得来)',
url: '/games/lineage?id=game-root',
},
{
expected: '共创',
title: '对比页(共创侧才进得来)',
url: '/games/compare?left=game-1&right=game-2',
},
] as const;
for (const item of cases) {
window.history.replaceState(null, '', item.url);
const view = render(
<PlatformEntryFlowShellImpl
selectionStage={
item.url.includes('/games/detail')
? 'game-detail'
: item.url.includes('/games/lineage')
? 'game-lineage'
: 'game-compare'
}
setSelectionStage={vi.fn()}
/>,
);
const rail = screen.getByRole('navigation', { name: '平台导航' });
expect(
within(rail)
.getAllByRole('button')
.filter((button) => button.getAttribute('aria-current') === 'page')
.map((button) => button.getAttribute('aria-label')),
).toEqual([item.expected]);
view.unmount();
}
});
it('窄屏底部导航也有「共创」,点它同样直达共创页', async () => {
responsiveMock.isDesktopLayout = false;
window.history.replaceState(null, '', '/games');
@@ -47,6 +47,8 @@ import { ClientDownloadEntry } from '../creation-home/ClientDownloadEntry';
import { setCreatorViewer } from '../creator/creatorRelationshipState';
import {
CO_CREATION_DETAIL_SOURCE,
isCoCreator,
resolveGameViewerContext,
shouldCarryCoCreationSource,
} from '../game-distribution/gameViewerRole';
import { PaymentCheckoutView } from './PaymentCheckoutView';
@@ -830,10 +832,6 @@ export function PlatformEntryFlowShellImpl({
selectionStage === 'game-mine' ||
selectionStage === 'game-lineage' ||
selectionStage === 'game-publish';
/** 侧边栏 / 底部导航的「共创」高亮(顶层入口,2026-10-07 从游戏页子页签升上来)。 */
const isCoCreationStage = selectionStage === 'game-co-creation';
/** 游戏区但不在共创页时,「游戏」这个导航项才是激活态——进共创时高亮共创、不再高亮游戏。 */
const isGamesNavActive = isGamesStage && !isCoCreationStage;
/**
* 游玩页自己撑满剩余高度,面板不能再滚动,否则移动端会出现整页可滚的
* 半屏播放器;其余舞台继续沿用面板滚动。
@@ -842,8 +840,32 @@ export function PlatformEntryFlowShellImpl({
const gameSearchParams = new URLSearchParams(
typeof window === 'undefined' ? '' : window.location.search,
);
/**
* 本屏的**入口来源标记**:详情页上是「从哪一侧点进来」(`from=co-creation`),
* 族谱页上含义不同(`from=<gameId>` = 高亮哪个作品)——所以只认 `co-creation` 这一个值
* (复用 `resolveGameViewerContext` 的白名单,不自己判字符串)。
*/
const gameEntrySource = gameSearchParams.get('from');
/**
* 本屏是否属于「**共创侧**」上下文 —— **导航高亮(侧边栏 / 底部 dock)的唯一判据**。
*
* 用户报的 bug:共创页 → 点卡 → 详情后,侧边栏仍高亮「游戏」。根因是这里原先只看 `stage`,
* 而详情页的 stage 属于游戏区(`game-detail`),**来源被丢掉**。修法是复用详情页那套
* 已落地的来源判定(不新造参数、不新造标记):
* ① URL 的来源标记就是 `co-creation`(详情页,以及从它继续跳过去的页面);
* ② 或当前就在「共创侧才进得来的阶段」(共创页 / 族谱 / 对比,见 `shouldCarryCoCreationSource`)。
*/
const isCoCreationContext =
isGamesStage &&
(isCoCreator(resolveGameViewerContext(gameEntrySource)) ||
shouldCarryCoCreationSource({
stage: selectionStage,
currentSource: gameEntrySource,
}));
/** 游戏区、且**不在共创侧上下文**时,「游戏」这个导航项才是激活态(两者互斥、不双亮)。 */
const isGamesNavActive = isGamesStage && !isCoCreationContext;
const gameId = gameSearchParams.get('id');
const lineageHighlightGameId = gameSearchParams.get('from');
const lineageHighlightGameId = gameEntrySource;
const compareLeftGameId = gameSearchParams.get('left');
const compareRightGameId = gameSearchParams.get('right');
const creatorConnectionTab = gameSearchParams.get('tab');
@@ -912,12 +934,13 @@ export function PlatformEntryFlowShellImpl({
/>
{/*
「共创」:**顶层入口**(2026-10-07 用户口径:不该是游戏页里的子页签)。
指向 `scope="forkable"` 的那个列表页(`/games/co-creation`),
与「游戏」平级;在共创页时高亮的是这一项,不再是「游戏」。
指向 `scope="forkable"` 的那个列表页(`/games/co-creation`),与「游戏」平级。
高亮读 `isCoCreationContext`:共创页本身、以及**从共创侧点进去的详情/族谱/对比**
都算共创侧(用户报的「共创 → 详情后仍高亮游戏」就是这里原先只看 stage 造成的)。
*/}
<ActiveRailButton
active={isCoCreationStage}
emphasized={isCoCreationStage}
active={isCoCreationContext}
emphasized={isCoCreationContext}
icon={Sparkles}
iconSrc="/creation-home/nav-discover.png"
label="共创"
@@ -1206,7 +1229,7 @@ export function PlatformEntryFlowShellImpl({
<MobileProfileDock
active={isProfileStage}
gameActive={isGamesNavActive}
coCreationActive={isCoCreationStage}
coCreationActive={isCoCreationContext}
creatorActive={isCreatorStage}
onOpenCreator={() => openCreator()}
onOpenProfile={openProfile}