引导移动端创作主页使用桌面端
移动端直达 /creation 时展示桌面端打开引导 补充移动端创作主页回归测试 同步创作主页与玩法链路文档口径
This commit is contained in:
@@ -67,7 +67,7 @@
|
||||
## 2026-06-18 `/creation` 独立为陶泥儿创作工具主页
|
||||
|
||||
- 背景:图片画布项目已经成为独立项目资产,旧“创作”站内 Tab 和一级“草稿”入口不能清晰表达桌面端创作工具主页与项目管理入口。
|
||||
- 决策:桌面端新增独立 `/creation` 创作工具主页,桌面端直接打开站点首页 `/` 时也默认展示新版创作主页;顶级“创作”入口跳转 `/creation`,原“草稿”入口替换为“项目”并跳转 `/project`。移动端首页 `/` 继续保持原推荐首页,移动端隐藏“创作”和“项目”入口,但不拦截直接 URL。页面文案统一使用“陶泥儿”,外部品牌只作为设计参考,不进入用户可见 UI、测试名、产品文案或验收口径。`陶泥儿精选` 是用户素材瀑布流,不展示玩法入口列表;创作入口事实源继续来自 `/api/creation-entry/config`,项目入口通过 `createEditorProject` 和 `/editor/canvas?projectid=xxx` 链路进入画布。
|
||||
- 决策:桌面端新增独立 `/creation` 创作工具主页,桌面端直接打开站点首页 `/` 时也默认展示新版创作主页;顶级“创作”入口跳转 `/creation`,原“草稿”入口替换为“项目”并跳转 `/project`。移动端首页 `/` 继续保持原推荐首页,移动端隐藏“创作”和“项目”入口;移动端直达 `/creation` 时不加载创作主页,显示桌面端打开引导,`/creation/<play>` 玩法工作台直达仍按原链路进入。页面文案统一使用“陶泥儿”,外部品牌只作为设计参考,不进入用户可见 UI、测试名、产品文案或验收口径。`陶泥儿精选` 是用户素材瀑布流,不展示玩法入口列表;创作入口事实源继续来自 `/api/creation-entry/config`,项目入口通过 `createEditorProject` 和 `/editor/canvas?projectid=xxx` 链路进入画布。
|
||||
- 影响范围:平台入口导航、`SelectionStage` 路由、`/creation` 首页、`/project` 项目入口、`/editor/canvas` 项目打开链路、“我的”页快捷入口和创作入口相关测试。
|
||||
- 验证方式:桌面 `/` 初始阶段和 `/creation` 解析为创作主页,移动端 `/` 仍是推荐首页,`/creation/<play>` 仍进入对应玩法工作台;桌面导航显示“创作 / 项目”且不显示“草稿”;移动端底部不显示“创作 / 项目”;页面不出现外站品牌或 `Discord` 字样;新建项目进入 `/editor/canvas?projectid=xxx`。
|
||||
- 关联文档:`docs/【玩法创作】创作主页与项目入口改版计划-2026-06-18.md`、`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md`。
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
- 新增桌面端独立 `/creation` 创作工具主页。
|
||||
- 桌面端直接打开站点首页 `/` 时默认展示新版创作主页内容;移动端继续保持原推荐首页。
|
||||
- 顶级导航中“创作”进入 `/creation`,“草稿”改为“项目”并进入 `/project`。
|
||||
- 移动端隐藏“创作”和“项目”入口,只保留浏览和个人相关入口。
|
||||
- 移动端隐藏“创作”和“项目”入口,只保留浏览和个人相关入口;移动端直达 `/creation` 时提示用户使用桌面端打开。
|
||||
- 登录后在创作主页展示最近项目,并通过新建项目进入 `/editor/canvas?projectid=xxx`。
|
||||
- `陶泥儿精选` 展示真实账号素材瀑布流,不使用 mock 素材。
|
||||
- 现有 `/creation/<play>` 玩法工作台、草稿、作品架、生成恢复和发布链路保持不变。
|
||||
@@ -128,7 +128,7 @@ Tab:
|
||||
- 桌面端从 `/creation` 切换到 `/project` 后,“项目”页签进入选中态,“创作”页签必须恢复为普通默认态,不保留创作主页的主按钮强调表现。
|
||||
- `/project` 项目页头部必须提供 `返回主站` 按钮,点击后切回平台首页 `/`,行为与桌面侧栏切回推荐页保持一致。
|
||||
- 移动端导航列表不展示“创作”和“项目”。
|
||||
- 移动端不拦截用户直接访问 `/creation` 或 `/project`。
|
||||
- 移动端直接访问 `/creation` 时显示桌面端打开引导,不加载创作工具主页;`/creation/<play>` 继续直达对应玩法工作台。`/project` 暂不新增移动端拦截。
|
||||
|
||||
## 实施拆分
|
||||
|
||||
@@ -137,7 +137,7 @@ Tab:
|
||||
- 增加 `/creation` 路由映射和测试。
|
||||
- 增加桌面 `/` 初始阶段映射测试,确认不会影响移动端首页。
|
||||
- 调整桌面导航文案与点击行为。
|
||||
- 移动端导航移除“创作”和“项目”入口。
|
||||
- 移动端导航移除“创作”和“项目”入口,并为直达 `/creation` 增加桌面端打开引导。
|
||||
- 保持现有 `/creation/<play>` 工作台、生成页、结果页和运行态路由不回归。
|
||||
|
||||
### 创作主页
|
||||
@@ -194,6 +194,7 @@ git diff --check
|
||||
- 桌面导航显示“项目”,不显示“草稿”。
|
||||
- `/project` 头部点击“返回主站”回到 `/`,并退出项目页主内容。
|
||||
- 移动视口底部不显示“创作”和“项目”。
|
||||
- 移动端直达 `/creation` 显示“请在桌面端打开创作主页”,点击“返回首页”回到 `/`。
|
||||
- “我的”页没有项目快捷入口。
|
||||
- 陶泥儿精选素材瀑布流不出现 mock 素材、假作者或假泥点成本。
|
||||
- 陶泥儿精选素材卡按真实素材宽高呈现瀑布流,不退化为固定等高网格。
|
||||
@@ -205,4 +206,5 @@ git diff --check
|
||||
- 不删除现有玩法草稿、作品架、生成恢复、发布或运行态能力。
|
||||
- 不恢复前端硬编码创作入口配置。
|
||||
- 不用 mock 素材填充用户素材展示。
|
||||
- 不在移动端禁止直接 URL 访问 `/creation` 或 `/project`。
|
||||
- 不影响 `/creation/<play>` 玩法工作台、生成页、结果页和运行态直达恢复。
|
||||
- 不在本轮拦截移动端直接 URL 访问 `/project`。
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
|
||||
import { Loader2 } from 'lucide-react';
|
||||
import { Home, Loader2, Monitor } from 'lucide-react';
|
||||
|
||||
import { AnimatePresence, motion } from 'motion/react';
|
||||
import {
|
||||
@@ -1636,6 +1636,45 @@ function CreationResultRecoveryPanel({
|
||||
);
|
||||
}
|
||||
|
||||
function MobileCreationDesktopGuide({
|
||||
onReturnHome,
|
||||
}: {
|
||||
onReturnHome: () => void;
|
||||
}) {
|
||||
return (
|
||||
<main
|
||||
className="flex min-h-full flex-1 items-center justify-center px-4 py-8"
|
||||
aria-label="桌面端创作提示"
|
||||
>
|
||||
<PlatformSubpanel
|
||||
as="section"
|
||||
radius="xl"
|
||||
padding="none"
|
||||
className="platform-remap-surface w-full max-w-sm px-5 py-6 text-center"
|
||||
>
|
||||
<span className="mx-auto flex h-14 w-14 items-center justify-center rounded-[1.05rem] bg-[rgba(199,101,50,0.12)] text-[var(--platform-accent-strong)]">
|
||||
<Monitor aria-hidden="true" className="h-7 w-7" />
|
||||
</span>
|
||||
<h1 className="mt-4 text-xl font-black leading-tight text-[var(--platform-text-strong)]">
|
||||
请在桌面端打开创作主页
|
||||
</h1>
|
||||
<p className="mt-3 text-sm font-semibold leading-6 text-[var(--platform-text-base)]">
|
||||
图片画布、项目管理和素材库需要更大的操作空间。
|
||||
</p>
|
||||
<PlatformActionButton
|
||||
onClick={onReturnHome}
|
||||
size="md"
|
||||
shape="pill"
|
||||
className="mt-5 min-h-11 w-full"
|
||||
>
|
||||
<Home aria-hidden="true" className="h-4 w-4" />
|
||||
返回首页
|
||||
</PlatformActionButton>
|
||||
</PlatformSubpanel>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
export function PlatformEntryFlowShellImpl({
|
||||
selectionStage,
|
||||
setSelectionStage,
|
||||
@@ -15238,7 +15277,7 @@ export function PlatformEntryFlowShellImpl({
|
||||
'works-only',
|
||||
'正在加载草稿列表...',
|
||||
);
|
||||
const creationLandingContent = (
|
||||
const creationLandingContent = isDesktopLayout ? (
|
||||
<Suspense fallback={<LazyPanelFallback label="正在加载创作主页..." />}>
|
||||
<CreationLandingView
|
||||
onOpenProject={openEditorProject}
|
||||
@@ -15250,6 +15289,14 @@ export function PlatformEntryFlowShellImpl({
|
||||
]}
|
||||
/>
|
||||
</Suspense>
|
||||
) : (
|
||||
<MobileCreationDesktopGuide
|
||||
onReturnHome={() => {
|
||||
pushAppHistoryPath('/');
|
||||
platformBootstrap.setPlatformTab('home');
|
||||
setSelectionStage('platform', { path: '/' });
|
||||
}}
|
||||
/>
|
||||
);
|
||||
const projectGalleryContent = (
|
||||
<Suspense fallback={<LazyPanelFallback label="正在加载项目..." />}>
|
||||
|
||||
@@ -9267,13 +9267,22 @@ test('project page header can return to main site', async () => {
|
||||
expect(window.location.pathname).toBe('/');
|
||||
});
|
||||
|
||||
test('direct mobile creation home keeps landing content without mobile nav entry', async () => {
|
||||
test('direct mobile creation home guides users to desktop without mobile nav entry', async () => {
|
||||
const user = userEvent.setup();
|
||||
window.history.replaceState(null, '', '/creation');
|
||||
const { container } = render(<TestWrapper withAuth />);
|
||||
|
||||
expect(
|
||||
await screen.findByRole('main', { name: '陶泥儿创作主页' }),
|
||||
await screen.findByRole('main', { name: '桌面端创作提示' }),
|
||||
).toBeTruthy();
|
||||
expect(screen.getByText('请在桌面端打开创作主页')).toBeTruthy();
|
||||
expect(
|
||||
screen.getByText('图片画布、项目管理和素材库需要更大的操作空间。'),
|
||||
).toBeTruthy();
|
||||
expect(
|
||||
screen.queryByRole('main', { name: '陶泥儿创作主页' }),
|
||||
).toBeNull();
|
||||
|
||||
const bottomNav = container.querySelector('.platform-bottom-nav');
|
||||
expect(bottomNav).toBeTruthy();
|
||||
expect(
|
||||
@@ -9282,6 +9291,15 @@ test('direct mobile creation home keeps landing content without mobile nav entry
|
||||
expect(
|
||||
within(bottomNav as HTMLElement).queryByRole('button', { name: '项目' }),
|
||||
).toBeNull();
|
||||
|
||||
await user.click(screen.getByRole('button', { name: /返回首页/u }));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(window.location.pathname).toBe('/');
|
||||
expect(
|
||||
screen.queryByRole('main', { name: '桌面端创作提示' }),
|
||||
).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
test('embedded puzzle form timeout exits busy state and shows a readable error', async () => {
|
||||
|
||||
Reference in New Issue
Block a user