继续收口RPG发布检查弹窗壳层
RPG结果页发布检查弹窗复用 PlatformToolModalShell 保留发布检查、封面预览和发布动作业务语义 补充组件测试断言共享白底工具弹窗壳层 同步 PlatformUiKit 文档和 Hermes 决策记录
This commit is contained in:
@@ -75,6 +75,8 @@ test('RPG result publish dialog uses PlatformPillBadge and PlatformSubpanel for
|
||||
const coverBadge = within(dialog).getByText('上传封面');
|
||||
const coverShell = within(dialog).getByLabelText('封面预览外壳');
|
||||
|
||||
expect(dialog.className).toContain('platform-remap-surface');
|
||||
expect(dialog.className).toContain('shadow-[0_24px_80px_rgba(0,0,0,0.55)]');
|
||||
expect(coverBadge.className).toContain('rounded-full');
|
||||
expect(coverBadge.className).toContain('bg-white/72');
|
||||
expect(coverShell.className).toContain('platform-subpanel');
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
import { type ReactNode, useState } from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
|
||||
import { resolveCustomWorldCoverPresentation } from '../../services/customWorldCover';
|
||||
import type { CustomWorldProfile } from '../../types';
|
||||
import { useAuthUi } from '../auth/AuthUiContext';
|
||||
import { PlatformActionButton } from '../common/PlatformActionButton';
|
||||
import { PlatformFieldLabel } from '../common/PlatformFieldLabel';
|
||||
import { PlatformModalCloseButton } from '../common/PlatformModalCloseButton';
|
||||
import { PlatformPillBadge } from '../common/PlatformPillBadge';
|
||||
import { PlatformStatusMessage } from '../common/PlatformStatusMessage';
|
||||
import { PlatformSubpanel } from '../common/PlatformSubpanel';
|
||||
import { PlatformToolModalShell } from '../common/PlatformToolModalShell';
|
||||
import { CustomWorldCoverArtwork } from '../CustomWorldCoverArtwork';
|
||||
|
||||
function SmallButton({
|
||||
@@ -54,112 +52,21 @@ function PublishPanelDialog({
|
||||
onEditCover: () => void;
|
||||
onPublish: () => void;
|
||||
}) {
|
||||
const platformTheme = useAuthUi()?.platformTheme ?? 'light';
|
||||
const coverPresentation = resolveCustomWorldCoverPresentation(profile);
|
||||
|
||||
if (typeof document === 'undefined') {
|
||||
return null;
|
||||
}
|
||||
|
||||
return createPortal(
|
||||
<div
|
||||
className={`platform-theme platform-theme--${platformTheme} platform-overlay fixed inset-0 z-[140] flex items-end justify-center p-3 backdrop-blur-sm sm:items-center sm:p-4`}
|
||||
onClick={(event) => {
|
||||
if (event.target === event.currentTarget) {
|
||||
onClose();
|
||||
}
|
||||
}}
|
||||
>
|
||||
<div
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-label="发布作品"
|
||||
className="platform-modal-shell platform-remap-surface flex max-h-[min(90vh,46rem)] w-full max-w-4xl flex-col overflow-hidden rounded-t-[1.75rem] shadow-[0_24px_80px_rgba(0,0,0,0.55)] sm:rounded-[1.75rem]"
|
||||
onClick={(event) => event.stopPropagation()}
|
||||
>
|
||||
<div className="flex items-center justify-between gap-3 border-b border-[var(--platform-subpanel-border)] px-5 py-4">
|
||||
<div>
|
||||
<div className="text-base font-semibold text-[var(--platform-text-strong)]">
|
||||
发布作品
|
||||
</div>
|
||||
<div className="mt-1 text-sm leading-6 text-[var(--platform-text-soft)]">
|
||||
发布前检查与封面设置
|
||||
</div>
|
||||
</div>
|
||||
<PlatformModalCloseButton
|
||||
variant="platformIcon"
|
||||
label="关闭发布作品"
|
||||
onClick={onClose}
|
||||
/>
|
||||
</div>
|
||||
<div className="min-h-0 flex-1 overflow-y-auto px-5 py-4">
|
||||
<div className="grid gap-4 lg:grid-cols-[minmax(0,1fr)_minmax(18rem,0.78fr)]">
|
||||
<div className="space-y-3">
|
||||
<PlatformFieldLabel variant="section">
|
||||
发布检查
|
||||
</PlatformFieldLabel>
|
||||
{blockers.length > 0 ? (
|
||||
<div className="space-y-2">
|
||||
{blockers.map((blocker, index) => (
|
||||
<PlatformStatusMessage
|
||||
key={`publish-blocker-${index}-${blocker}`}
|
||||
tone="warning"
|
||||
surface="platform"
|
||||
>
|
||||
<div className="text-xs font-semibold tracking-[0.14em] text-[var(--platform-warm-text)] opacity-80">
|
||||
阻断项 {index + 1}
|
||||
</div>
|
||||
<div className="mt-1 text-[var(--platform-text-strong)]">
|
||||
{blocker}
|
||||
</div>
|
||||
</PlatformStatusMessage>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<PlatformStatusMessage tone="success" surface="platform">
|
||||
当前作品已满足发布条件。
|
||||
</PlatformStatusMessage>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="space-y-3">
|
||||
<div className="flex items-center justify-between gap-3">
|
||||
<PlatformFieldLabel variant="section">
|
||||
封面设置
|
||||
</PlatformFieldLabel>
|
||||
<PlatformPillBadge
|
||||
tone="neutral"
|
||||
size="xs"
|
||||
className="px-2.5 py-1 text-[10px]"
|
||||
>
|
||||
{coverPresentation.sourceType === 'uploaded'
|
||||
? '上传封面'
|
||||
: coverPresentation.sourceType === 'generated'
|
||||
? 'AI封面'
|
||||
: '默认封面'}
|
||||
</PlatformPillBadge>
|
||||
</div>
|
||||
<PlatformSubpanel
|
||||
padding="none"
|
||||
aria-label="封面预览外壳"
|
||||
className="p-2"
|
||||
>
|
||||
<CustomWorldCoverArtwork
|
||||
imageSrc={coverPresentation.imageSrc}
|
||||
title={profile.name}
|
||||
fallbackLabel={profile.name.slice(0, 4) || '封面'}
|
||||
renderMode={coverPresentation.renderMode}
|
||||
characterImageSrcs={coverPresentation.characterImageSrcs}
|
||||
className="aspect-[16/9] max-h-[15rem] rounded-[1rem]"
|
||||
/>
|
||||
</PlatformSubpanel>
|
||||
<SmallButton onClick={onEditCover} tone="sky">
|
||||
设置封面
|
||||
</SmallButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col-reverse gap-3 border-t border-[var(--platform-subpanel-border)] px-5 py-4 sm:flex-row sm:justify-end">
|
||||
return (
|
||||
<PlatformToolModalShell
|
||||
open
|
||||
title="发布作品"
|
||||
description="发布前检查与封面设置"
|
||||
onClose={onClose}
|
||||
closeLabel="关闭发布作品"
|
||||
zIndexClassName="z-[140]"
|
||||
size="xl"
|
||||
panelClassName="!max-h-[min(90vh,46rem)] !max-w-4xl"
|
||||
footerClassName="flex-col-reverse sm:flex-row sm:justify-end"
|
||||
footer={
|
||||
<>
|
||||
<SmallButton onClick={onClose}>取消</SmallButton>
|
||||
<PlatformActionButton
|
||||
onClick={onPublish}
|
||||
@@ -167,10 +74,71 @@ function PublishPanelDialog({
|
||||
>
|
||||
{isPublishing ? '发布中...' : '发布到广场'}
|
||||
</PlatformActionButton>
|
||||
</>
|
||||
}
|
||||
>
|
||||
<div className="grid gap-4 lg:grid-cols-[minmax(0,1fr)_minmax(18rem,0.78fr)]">
|
||||
<div className="space-y-3">
|
||||
<PlatformFieldLabel variant="section">发布检查</PlatformFieldLabel>
|
||||
{blockers.length > 0 ? (
|
||||
<div className="space-y-2">
|
||||
{blockers.map((blocker, index) => (
|
||||
<PlatformStatusMessage
|
||||
key={`publish-blocker-${index}-${blocker}`}
|
||||
tone="warning"
|
||||
surface="platform"
|
||||
>
|
||||
<div className="text-xs font-semibold tracking-[0.14em] text-[var(--platform-warm-text)] opacity-80">
|
||||
阻断项 {index + 1}
|
||||
</div>
|
||||
<div className="mt-1 text-[var(--platform-text-strong)]">
|
||||
{blocker}
|
||||
</div>
|
||||
</PlatformStatusMessage>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<PlatformStatusMessage tone="success" surface="platform">
|
||||
当前作品已满足发布条件。
|
||||
</PlatformStatusMessage>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="space-y-3">
|
||||
<div className="flex items-center justify-between gap-3">
|
||||
<PlatformFieldLabel variant="section">封面设置</PlatformFieldLabel>
|
||||
<PlatformPillBadge
|
||||
tone="neutral"
|
||||
size="xs"
|
||||
className="px-2.5 py-1 text-[10px]"
|
||||
>
|
||||
{coverPresentation.sourceType === 'uploaded'
|
||||
? '上传封面'
|
||||
: coverPresentation.sourceType === 'generated'
|
||||
? 'AI封面'
|
||||
: '默认封面'}
|
||||
</PlatformPillBadge>
|
||||
</div>
|
||||
<PlatformSubpanel
|
||||
padding="none"
|
||||
aria-label="封面预览外壳"
|
||||
className="p-2"
|
||||
>
|
||||
<CustomWorldCoverArtwork
|
||||
imageSrc={coverPresentation.imageSrc}
|
||||
title={profile.name}
|
||||
fallbackLabel={profile.name.slice(0, 4) || '封面'}
|
||||
renderMode={coverPresentation.renderMode}
|
||||
characterImageSrcs={coverPresentation.characterImageSrcs}
|
||||
className="aspect-[16/9] max-h-[15rem] rounded-[1rem]"
|
||||
/>
|
||||
</PlatformSubpanel>
|
||||
<SmallButton onClick={onEditCover} tone="sky">
|
||||
设置封面
|
||||
</SmallButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
document.body,
|
||||
</PlatformToolModalShell>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user