移动端欢迎界面和说明
新增移动端首页欢迎弹窗,提示移动端仅支持作品展示。 替换欢迎弹窗 IP 图标并调整正文换行与标点。 关闭弹窗后本次页面生命周期内切换底部页签不再重复弹出,刷新后重新显示。 补充弹窗展示规则测试并同步玩法入口文档。
This commit is contained in:
@@ -129,6 +129,7 @@ Tab:
|
||||
- 桌面端从 `/creation` 切换到 `/project` 后,“项目”页签进入选中态,“创作”页签必须恢复为普通默认态,不保留创作主页的主按钮强调表现。
|
||||
- `/project` 项目页头部必须提供 `返回主站` 按钮,点击后切回平台首页 `/`,行为与桌面侧栏切回推荐页保持一致。
|
||||
- 移动端导航列表不展示“创作”和“项目”。
|
||||
- 移动端首次进入或刷新 `/` 平台首页时显示欢迎弹窗,文案提示移动端仅支持作品展示,体验创作工具请使用电脑端访问;点击 `好` 关闭后,本次页面生命周期内切换下方页签再回到首页不再弹出。
|
||||
- 移动端直接访问 `/creation` 时显示桌面端打开引导,不加载创作工具主页;`/creation/<play>` 继续直达对应玩法工作台。`/project` 暂不新增移动端拦截。
|
||||
|
||||
## 实施拆分
|
||||
@@ -195,6 +196,7 @@ git diff --check
|
||||
- 桌面导航显示“项目”,不显示“草稿”。
|
||||
- `/project` 头部点击“返回主站”回到 `/`,并退出项目页主内容。
|
||||
- 移动视口底部不显示“创作”和“项目”。
|
||||
- 移动端进入 `/` 首页时显示 `欢迎` 弹窗,正文包含移动端仅支持作品展示和电脑端访问提示,按钮为 `好`。
|
||||
- 移动端直达 `/creation` 显示“请在桌面端打开创作主页”,点击“返回首页”回到 `/`。
|
||||
- “我的”页没有项目快捷入口。
|
||||
- 陶泥儿精选素材瀑布流不出现账号级非项目素材、公开作品补充、上传素材、mock 素材、假作者或假泥点成本。
|
||||
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
|
After Width: | Height: | Size: 129 KiB |
@@ -536,6 +536,10 @@ import {
|
||||
PlatformEntryHomeView,
|
||||
type PlatformHomeTab,
|
||||
} from './PlatformEntryHomeView';
|
||||
import {
|
||||
PlatformMobileHomeWelcomeDialog,
|
||||
shouldOpenMobileHomeWelcomeDialog,
|
||||
} from './PlatformMobileHomeWelcomeDialog';
|
||||
import { PlatformProfileReferralModal } from './PlatformProfileReferralModal';
|
||||
import { usePlatformDesktopLayout } from './platformEntryResponsive';
|
||||
import {
|
||||
@@ -1692,6 +1696,8 @@ export function PlatformEntryFlowShellImpl({
|
||||
: 'platform-theme--light';
|
||||
const isDesktopLayout = usePlatformDesktopLayout();
|
||||
const [showCreationTypeModal, setShowCreationTypeModal] = useState(false);
|
||||
const [isMobileHomeWelcomeDismissed, setIsMobileHomeWelcomeDismissed] =
|
||||
useState(false);
|
||||
const [isCreationCommunityOpen, setIsCreationCommunityOpen] =
|
||||
useState(false);
|
||||
const [draftGenerationPointNotice, setDraftGenerationPointNotice] =
|
||||
@@ -15319,6 +15325,16 @@ export function PlatformEntryFlowShellImpl({
|
||||
},
|
||||
[platformBootstrap, selectionStage, setSelectionStage],
|
||||
);
|
||||
const shouldOpenMobileHomeWelcome = shouldOpenMobileHomeWelcomeDialog({
|
||||
isDesktopLayout,
|
||||
selectionStage,
|
||||
platformTab: platformBootstrap.platformTab,
|
||||
pathname:
|
||||
typeof window === 'undefined'
|
||||
? resolvePathForSelectionStage(selectionStage)
|
||||
: window.location.pathname,
|
||||
isDismissed: isMobileHomeWelcomeDismissed,
|
||||
});
|
||||
const platformHomeView = (
|
||||
<PlatformEntryHomeView
|
||||
activeTab={
|
||||
@@ -17887,6 +17903,11 @@ export function PlatformEntryFlowShellImpl({
|
||||
payload={publishSharePayload}
|
||||
onClose={() => setPublishSharePayload(null)}
|
||||
/>
|
||||
<PlatformMobileHomeWelcomeDialog
|
||||
open={shouldOpenMobileHomeWelcome}
|
||||
platformThemeClass={platformThemeClass}
|
||||
onClose={() => setIsMobileHomeWelcomeDismissed(true)}
|
||||
/>
|
||||
<PlatformErrorDialog
|
||||
error={activePlatformErrorDialog}
|
||||
onClose={closePlatformErrorDialog}
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
/* @vitest-environment jsdom */
|
||||
|
||||
import { fireEvent, render, screen } from '@testing-library/react';
|
||||
import { expect, test, vi } from 'vitest';
|
||||
|
||||
import {
|
||||
PlatformMobileHomeWelcomeDialog,
|
||||
shouldOpenMobileHomeWelcomeDialog,
|
||||
shouldShowMobileHomeWelcomeDialog,
|
||||
} from './PlatformMobileHomeWelcomeDialog';
|
||||
|
||||
test('shows mobile home welcome only for the mobile platform home route', () => {
|
||||
expect(
|
||||
shouldShowMobileHomeWelcomeDialog({
|
||||
isDesktopLayout: false,
|
||||
selectionStage: 'platform',
|
||||
platformTab: 'home',
|
||||
pathname: '/',
|
||||
}),
|
||||
).toBe(true);
|
||||
expect(
|
||||
shouldShowMobileHomeWelcomeDialog({
|
||||
isDesktopLayout: true,
|
||||
selectionStage: 'platform',
|
||||
platformTab: 'home',
|
||||
pathname: '/',
|
||||
}),
|
||||
).toBe(false);
|
||||
expect(
|
||||
shouldShowMobileHomeWelcomeDialog({
|
||||
isDesktopLayout: false,
|
||||
selectionStage: 'platform',
|
||||
platformTab: 'category',
|
||||
pathname: '/',
|
||||
}),
|
||||
).toBe(false);
|
||||
expect(
|
||||
shouldShowMobileHomeWelcomeDialog({
|
||||
isDesktopLayout: false,
|
||||
selectionStage: 'creation-home',
|
||||
platformTab: 'home',
|
||||
pathname: '/creation',
|
||||
}),
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
test('keeps mobile home welcome dismissed across bottom tab switches until refresh', () => {
|
||||
expect(
|
||||
shouldOpenMobileHomeWelcomeDialog({
|
||||
isDesktopLayout: false,
|
||||
selectionStage: 'platform',
|
||||
platformTab: 'home',
|
||||
pathname: '/',
|
||||
isDismissed: false,
|
||||
}),
|
||||
).toBe(true);
|
||||
expect(
|
||||
shouldOpenMobileHomeWelcomeDialog({
|
||||
isDesktopLayout: false,
|
||||
selectionStage: 'platform',
|
||||
platformTab: 'category',
|
||||
pathname: '/',
|
||||
isDismissed: true,
|
||||
}),
|
||||
).toBe(false);
|
||||
expect(
|
||||
shouldOpenMobileHomeWelcomeDialog({
|
||||
isDesktopLayout: false,
|
||||
selectionStage: 'platform',
|
||||
platformTab: 'home',
|
||||
pathname: '/',
|
||||
isDismissed: true,
|
||||
}),
|
||||
).toBe(false);
|
||||
expect(
|
||||
shouldOpenMobileHomeWelcomeDialog({
|
||||
isDesktopLayout: false,
|
||||
selectionStage: 'platform',
|
||||
platformTab: 'home',
|
||||
pathname: '/',
|
||||
isDismissed: false,
|
||||
}),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
test('renders mobile home welcome copy and closes with the acknowledge button', () => {
|
||||
const onClose = vi.fn();
|
||||
|
||||
const { container } = render(
|
||||
<PlatformMobileHomeWelcomeDialog
|
||||
open
|
||||
platformThemeClass="platform-theme--light"
|
||||
onClose={onClose}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(screen.getByRole('dialog', { name: '欢迎' })).toBeTruthy();
|
||||
expect(screen.getByRole('heading', { name: '欢迎' })).toBeTruthy();
|
||||
const copy = document.querySelector(
|
||||
'.platform-mobile-home-welcome-dialog__copy',
|
||||
);
|
||||
expect(copy?.textContent).toBe(
|
||||
'尼嚎,新陶泥er!移动端仅支持作品展示体验创作工具请使用电脑端访问该地址',
|
||||
);
|
||||
expect(copy?.querySelectorAll('br')).toHaveLength(2);
|
||||
expect(
|
||||
document
|
||||
.querySelector('.platform-mobile-home-welcome-dialog__icon')
|
||||
?.getAttribute('src'),
|
||||
).toBe('/branding/mobile-home-welcome-taonier-ip.png');
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: '好' }));
|
||||
|
||||
expect(onClose).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
@@ -0,0 +1,90 @@
|
||||
import { normalizeAppPath } from '../../routing/appPageRoutes';
|
||||
import { PlatformActionButton } from '../common/PlatformActionButton';
|
||||
import { UnifiedModal } from '../common/UnifiedModal';
|
||||
import type { SelectionStage } from './platformEntryTypes';
|
||||
|
||||
type MobileHomeWelcomeDecisionInput = {
|
||||
isDesktopLayout: boolean;
|
||||
selectionStage: SelectionStage;
|
||||
platformTab: string;
|
||||
pathname: string;
|
||||
};
|
||||
|
||||
type MobileHomeWelcomeOpenInput = MobileHomeWelcomeDecisionInput & {
|
||||
isDismissed: boolean;
|
||||
};
|
||||
|
||||
type PlatformMobileHomeWelcomeDialogProps = {
|
||||
open: boolean;
|
||||
platformThemeClass: string;
|
||||
onClose: () => void;
|
||||
};
|
||||
|
||||
export function shouldShowMobileHomeWelcomeDialog({
|
||||
isDesktopLayout,
|
||||
selectionStage,
|
||||
platformTab,
|
||||
pathname,
|
||||
}: MobileHomeWelcomeDecisionInput) {
|
||||
return (
|
||||
!isDesktopLayout &&
|
||||
selectionStage === 'platform' &&
|
||||
platformTab === 'home' &&
|
||||
normalizeAppPath(pathname) === '/'
|
||||
);
|
||||
}
|
||||
|
||||
export function shouldOpenMobileHomeWelcomeDialog({
|
||||
isDismissed,
|
||||
...decisionInput
|
||||
}: MobileHomeWelcomeOpenInput) {
|
||||
return !isDismissed && shouldShowMobileHomeWelcomeDialog(decisionInput);
|
||||
}
|
||||
|
||||
export function PlatformMobileHomeWelcomeDialog({
|
||||
open,
|
||||
platformThemeClass,
|
||||
onClose,
|
||||
}: PlatformMobileHomeWelcomeDialogProps) {
|
||||
return (
|
||||
<UnifiedModal
|
||||
open={open}
|
||||
title="欢迎"
|
||||
onClose={onClose}
|
||||
showHeader={false}
|
||||
showCloseButton={false}
|
||||
closeOnBackdrop={false}
|
||||
closeOnEscape={false}
|
||||
size="sm"
|
||||
overlayClassName={`platform-theme ${platformThemeClass} platform-mobile-home-welcome-overlay !items-center !p-4`}
|
||||
panelClassName="platform-remap-surface platform-mobile-home-welcome-dialog"
|
||||
bodyClassName="platform-mobile-home-welcome-dialog__body"
|
||||
footerClassName="platform-mobile-home-welcome-dialog__footer"
|
||||
footer={
|
||||
<PlatformActionButton
|
||||
onClick={onClose}
|
||||
size="md"
|
||||
shape="pill"
|
||||
fullWidth
|
||||
className="min-h-11"
|
||||
>
|
||||
好
|
||||
</PlatformActionButton>
|
||||
}
|
||||
>
|
||||
<img
|
||||
src="/branding/mobile-home-welcome-taonier-ip.png"
|
||||
alt=""
|
||||
className="platform-mobile-home-welcome-dialog__icon"
|
||||
/>
|
||||
<h1 className="platform-mobile-home-welcome-dialog__title">欢迎</h1>
|
||||
<p className="platform-mobile-home-welcome-dialog__copy">
|
||||
尼嚎,新陶泥er!
|
||||
<br />
|
||||
移动端仅支持作品展示
|
||||
<br />
|
||||
体验创作工具请使用电脑端访问该地址
|
||||
</p>
|
||||
</UnifiedModal>
|
||||
);
|
||||
}
|
||||
@@ -8822,6 +8822,63 @@ button.image-canvas-editor__reference-chip:disabled {
|
||||
box-shadow: 0 24px 80px rgba(0, 0, 0, 0.16);
|
||||
}
|
||||
|
||||
.platform-mobile-home-welcome-overlay {
|
||||
background:
|
||||
radial-gradient(circle at 50% 18%, rgba(255, 254, 252, 0.54), transparent 32%),
|
||||
rgba(61, 31, 16, 0.24);
|
||||
}
|
||||
|
||||
.platform-mobile-home-welcome-dialog {
|
||||
width: min(100%, 21rem);
|
||||
overflow: hidden;
|
||||
border-radius: 1.65rem;
|
||||
border: 1px solid rgba(255, 255, 255, 0.68);
|
||||
background:
|
||||
radial-gradient(circle at 18% 0%, rgba(240, 203, 169, 0.28), transparent 38%),
|
||||
var(--platform-modal-fill);
|
||||
box-shadow:
|
||||
0 24px 58px rgba(112, 57, 30, 0.2),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.82);
|
||||
}
|
||||
|
||||
.platform-mobile-home-welcome-dialog__body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 1.5rem 1.35rem 0.85rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.platform-mobile-home-welcome-dialog__footer {
|
||||
justify-content: center;
|
||||
border-top: 0;
|
||||
padding: 0.35rem 1.35rem 1.35rem;
|
||||
}
|
||||
|
||||
.platform-mobile-home-welcome-dialog__icon {
|
||||
display: block;
|
||||
width: 5.65rem;
|
||||
height: 5.65rem;
|
||||
object-fit: contain;
|
||||
filter: drop-shadow(0 14px 20px rgba(182, 98, 63, 0.16));
|
||||
}
|
||||
|
||||
.platform-mobile-home-welcome-dialog__title {
|
||||
margin-top: 0.85rem;
|
||||
color: var(--platform-text-strong);
|
||||
font-size: 1.32rem;
|
||||
font-weight: 900;
|
||||
line-height: 1.18;
|
||||
}
|
||||
|
||||
.platform-mobile-home-welcome-dialog__copy {
|
||||
margin-top: 0.65rem;
|
||||
color: var(--platform-text-base);
|
||||
font-size: 0.9rem;
|
||||
font-weight: 700;
|
||||
line-height: 1.75;
|
||||
}
|
||||
|
||||
.platform-modal-backdrop {
|
||||
background: var(--platform-overlay-fill);
|
||||
color: var(--platform-text-strong);
|
||||
|
||||
Reference in New Issue
Block a user