收口单按钮已读状态弹窗
新增 PlatformAcknowledgeStatusDialog 统一承接单按钮已读状态壳层 迁移大鱼结果页与个人中心支付结果复用共享已读状态弹窗 迁移 RPG 编辑器与平台入口提示链路复用共享已读状态弹窗 迁移自定义世界实体目录阻断提示复用共享已读状态弹窗 补充共享组件测试并更新 PlatformUiKit 收口文档与决策记录
This commit is contained in:
@@ -23,6 +23,7 @@ import {
|
||||
type SceneChapterBlueprint,
|
||||
} from '../types';
|
||||
import { CharacterAnimator } from './CharacterAnimator';
|
||||
import { PlatformAcknowledgeStatusDialog } from './common/PlatformAcknowledgeStatusDialog';
|
||||
import { PlatformActionButton } from './common/PlatformActionButton';
|
||||
import { PlatformDangerConfirmDialog } from './common/PlatformDangerConfirmDialog';
|
||||
import { PlatformEmptyState } from './common/PlatformEmptyState';
|
||||
@@ -30,7 +31,6 @@ import { PlatformMediaFrame } from './common/PlatformMediaFrame';
|
||||
import { PlatformPillBadge } from './common/PlatformPillBadge';
|
||||
import { PlatformProgressBar } from './common/PlatformProgressBar';
|
||||
import { PlatformStatGrid } from './common/PlatformStatGrid';
|
||||
import { PlatformStatusDialog } from './common/PlatformStatusDialog';
|
||||
import { PlatformStatusMessage } from './common/PlatformStatusMessage';
|
||||
import { PlatformSubpanel } from './common/PlatformSubpanel';
|
||||
import { PlatformTextField } from './common/PlatformTextField';
|
||||
@@ -1440,17 +1440,12 @@ export function CustomWorldEntityCatalog({
|
||||
</PlatformDangerConfirmDialog>
|
||||
) : null}
|
||||
{confirmState?.kind === 'minimum-playable' ? (
|
||||
<PlatformStatusDialog
|
||||
<PlatformAcknowledgeStatusDialog
|
||||
status="error"
|
||||
title="无法删除"
|
||||
description="至少保留一个可扮演角色,才能正常进入自定义世界。"
|
||||
onClose={closeConfirmDialog}
|
||||
closeOnBackdrop={false}
|
||||
action={{
|
||||
label: '知道了',
|
||||
onClick: closeConfirmDialog,
|
||||
surface: 'platform',
|
||||
}}
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
@@ -16,6 +16,7 @@ import type {
|
||||
BigFishSessionSnapshotResponse,
|
||||
ExecuteBigFishActionRequest,
|
||||
} from '../../../packages/shared/src/contracts/bigFish';
|
||||
import { PlatformAcknowledgeStatusDialog } from '../common/PlatformAcknowledgeStatusDialog';
|
||||
import { PlatformActionButton } from '../common/PlatformActionButton';
|
||||
import { PlatformEmptyState } from '../common/PlatformEmptyState';
|
||||
import { PlatformFieldLabel } from '../common/PlatformFieldLabel';
|
||||
@@ -23,7 +24,6 @@ import { PlatformIconBadge } from '../common/PlatformIconBadge';
|
||||
import { PlatformIconButton } from '../common/PlatformIconButton';
|
||||
import { PlatformMediaFrame } from '../common/PlatformMediaFrame';
|
||||
import { PlatformPillBadge } from '../common/PlatformPillBadge';
|
||||
import { PlatformStatusDialog } from '../common/PlatformStatusDialog';
|
||||
import { PlatformStatusMessage } from '../common/PlatformStatusMessage';
|
||||
import { PlatformSubpanel } from '../common/PlatformSubpanel';
|
||||
|
||||
@@ -619,7 +619,7 @@ function BigFishResultErrorModal({
|
||||
onClose: () => void;
|
||||
}) {
|
||||
return (
|
||||
<PlatformStatusDialog
|
||||
<PlatformAcknowledgeStatusDialog
|
||||
status="error"
|
||||
title="发布失败"
|
||||
description={message}
|
||||
@@ -627,12 +627,7 @@ function BigFishResultErrorModal({
|
||||
icon={<Waves className="h-4 w-4" />}
|
||||
iconLabel="发布失败提示"
|
||||
iconClassName="mt-0.5 bg-[var(--platform-button-danger-fill)] text-[var(--platform-button-danger-text)]"
|
||||
action={{
|
||||
label: '知道了',
|
||||
onClick: onClose,
|
||||
surface: 'platform',
|
||||
className: 'border-slate-950 bg-slate-950 text-white',
|
||||
}}
|
||||
actionClassName="border-slate-950 bg-slate-950 text-white"
|
||||
zIndexClassName="z-[160]"
|
||||
overlayClassName="bg-slate-950/58"
|
||||
panelClassName="border-red-100/80 bg-white text-slate-950 shadow-2xl"
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/* @vitest-environment jsdom */
|
||||
|
||||
import { fireEvent, render, screen } from '@testing-library/react';
|
||||
import { expect, test, vi } from 'vitest';
|
||||
|
||||
import { PlatformAcknowledgeStatusDialog } from './PlatformAcknowledgeStatusDialog';
|
||||
|
||||
test('renders a standard acknowledge action and closes through 知道了', () => {
|
||||
const onClose = vi.fn();
|
||||
|
||||
render(
|
||||
<PlatformAcknowledgeStatusDialog
|
||||
status="error"
|
||||
title="提示"
|
||||
description="至少保留一个可扮演角色。"
|
||||
onClose={onClose}
|
||||
/>,
|
||||
);
|
||||
|
||||
const action = screen.getByRole('button', { name: '知道了' });
|
||||
|
||||
expect(action.className).toContain('platform-button');
|
||||
fireEvent.click(action);
|
||||
expect(onClose).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test('supports custom action styling and header notice layout', () => {
|
||||
render(
|
||||
<PlatformAcknowledgeStatusDialog
|
||||
status="error"
|
||||
title="发布失败"
|
||||
description="还缺少 16 个基础动作"
|
||||
onClose={() => {}}
|
||||
showHeader
|
||||
showCloseButton
|
||||
closeOnBackdrop
|
||||
iconLabel="发布失败提示"
|
||||
actionClassName="border-slate-950 bg-slate-950 text-white"
|
||||
/>,
|
||||
);
|
||||
|
||||
const action = screen.getByRole('button', { name: '知道了' });
|
||||
const dialog = screen.getByRole('dialog', { name: '发布失败' });
|
||||
|
||||
expect(action.className).toContain('border-slate-950');
|
||||
expect(action.className).toContain('bg-slate-950');
|
||||
expect(dialog.querySelector('[aria-label="发布失败提示"]')).toBeTruthy();
|
||||
});
|
||||
111
src/components/common/PlatformAcknowledgeStatusDialog.tsx
Normal file
111
src/components/common/PlatformAcknowledgeStatusDialog.tsx
Normal file
@@ -0,0 +1,111 @@
|
||||
import type { ReactNode } from 'react';
|
||||
|
||||
import type {
|
||||
PlatformActionButtonSize,
|
||||
PlatformActionButtonSurface,
|
||||
PlatformActionButtonTone,
|
||||
} from './platformActionButtonModel';
|
||||
import {
|
||||
PlatformStatusDialog,
|
||||
type PlatformStatusDialogStatus,
|
||||
} from './PlatformStatusDialog';
|
||||
|
||||
type PlatformAcknowledgeStatusDialogProps = {
|
||||
open?: boolean;
|
||||
status: PlatformStatusDialogStatus;
|
||||
title: string;
|
||||
description?: ReactNode;
|
||||
children?: ReactNode;
|
||||
onClose: () => void;
|
||||
actionLabel?: string;
|
||||
actionDisabled?: boolean;
|
||||
actionTone?: PlatformActionButtonTone;
|
||||
actionSurface?: PlatformActionButtonSurface;
|
||||
actionSize?: PlatformActionButtonSize;
|
||||
actionFullWidth?: boolean;
|
||||
actionClassName?: string;
|
||||
showHeader?: boolean;
|
||||
showBodyTitle?: boolean;
|
||||
showCloseButton?: boolean;
|
||||
closeOnBackdrop?: boolean;
|
||||
closeOnEscape?: boolean;
|
||||
closeLabel?: string;
|
||||
closeDisabled?: boolean;
|
||||
zIndexClassName?: string;
|
||||
overlayClassName?: string;
|
||||
panelClassName?: string;
|
||||
bodyClassName?: string;
|
||||
iconClassName?: string;
|
||||
icon?: ReactNode;
|
||||
iconLabel?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* 平台已读确认状态弹窗。
|
||||
* 统一承接“状态提示 + 知道了”这一类单按钮确认已读的弹窗语义。
|
||||
*/
|
||||
export function PlatformAcknowledgeStatusDialog({
|
||||
open,
|
||||
status,
|
||||
title,
|
||||
description,
|
||||
children,
|
||||
onClose,
|
||||
actionLabel = '知道了',
|
||||
actionDisabled = false,
|
||||
actionTone,
|
||||
actionSurface = 'platform',
|
||||
actionSize,
|
||||
actionFullWidth,
|
||||
actionClassName,
|
||||
showHeader,
|
||||
showBodyTitle,
|
||||
showCloseButton,
|
||||
closeOnBackdrop,
|
||||
closeOnEscape,
|
||||
closeLabel,
|
||||
closeDisabled,
|
||||
zIndexClassName,
|
||||
overlayClassName,
|
||||
panelClassName,
|
||||
bodyClassName,
|
||||
iconClassName,
|
||||
icon,
|
||||
iconLabel,
|
||||
}: PlatformAcknowledgeStatusDialogProps) {
|
||||
return (
|
||||
<PlatformStatusDialog
|
||||
open={open}
|
||||
status={status}
|
||||
title={title}
|
||||
description={description}
|
||||
onClose={onClose}
|
||||
showHeader={showHeader}
|
||||
showBodyTitle={showBodyTitle}
|
||||
showCloseButton={showCloseButton}
|
||||
closeOnBackdrop={closeOnBackdrop}
|
||||
closeOnEscape={closeOnEscape}
|
||||
closeLabel={closeLabel}
|
||||
closeDisabled={closeDisabled}
|
||||
zIndexClassName={zIndexClassName}
|
||||
overlayClassName={overlayClassName}
|
||||
panelClassName={panelClassName}
|
||||
bodyClassName={bodyClassName}
|
||||
iconClassName={iconClassName}
|
||||
icon={icon}
|
||||
iconLabel={iconLabel}
|
||||
action={{
|
||||
label: actionLabel,
|
||||
onClick: onClose,
|
||||
disabled: actionDisabled,
|
||||
tone: actionTone,
|
||||
surface: actionSurface,
|
||||
size: actionSize,
|
||||
fullWidth: actionFullWidth,
|
||||
className: actionClassName,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</PlatformStatusDialog>
|
||||
);
|
||||
}
|
||||
@@ -363,10 +363,10 @@ import {
|
||||
} from '../../services/wooden-fish/woodenFishClient';
|
||||
import type { CustomWorldProfile } from '../../types';
|
||||
import { useAuthUi } from '../auth/AuthUiContext';
|
||||
import { PlatformAcknowledgeStatusDialog } from '../common/PlatformAcknowledgeStatusDialog';
|
||||
import { PlatformActionButton } from '../common/PlatformActionButton';
|
||||
import { PlatformDangerConfirmDialog } from '../common/PlatformDangerConfirmDialog';
|
||||
import { PlatformFieldLabel } from '../common/PlatformFieldLabel';
|
||||
import { PlatformStatusDialog } from '../common/PlatformStatusDialog';
|
||||
import { PlatformStatusMessage } from '../common/PlatformStatusMessage';
|
||||
import { PlatformSubpanel } from '../common/PlatformSubpanel';
|
||||
import { PublishShareModal } from '../common/PublishShareModal';
|
||||
@@ -16997,7 +16997,7 @@ export function PlatformEntryFlowShellImpl({
|
||||
}}
|
||||
/>
|
||||
) : null}
|
||||
<PlatformStatusDialog
|
||||
<PlatformAcknowledgeStatusDialog
|
||||
open={Boolean(draftGenerationPointNotice)}
|
||||
status="error"
|
||||
title={draftGenerationPointNotice?.title ?? '泥点提示'}
|
||||
@@ -17013,14 +17013,9 @@ export function PlatformEntryFlowShellImpl({
|
||||
? undefined
|
||||
: 'bg-amber-100/80 text-amber-600'
|
||||
}
|
||||
action={{
|
||||
label: '知道了',
|
||||
onClick: () => setDraftGenerationPointNotice(null),
|
||||
surface: 'platform',
|
||||
}}
|
||||
>
|
||||
{draftGenerationPointNotice?.message}
|
||||
</PlatformStatusDialog>
|
||||
</PlatformAcknowledgeStatusDialog>
|
||||
<PublishShareModal
|
||||
open={Boolean(publishSharePayload)}
|
||||
payload={publishSharePayload}
|
||||
@@ -17038,7 +17033,7 @@ export function PlatformEntryFlowShellImpl({
|
||||
overlayClassName={`platform-theme ${platformThemeClass} !items-center`}
|
||||
panelClassName="platform-remap-surface rounded-[1.5rem]"
|
||||
/>
|
||||
<PlatformStatusDialog
|
||||
<PlatformAcknowledgeStatusDialog
|
||||
open={Boolean(workNotFoundRecoveryDialog)}
|
||||
status="error"
|
||||
title="作品不可用"
|
||||
@@ -17048,14 +17043,9 @@ export function PlatformEntryFlowShellImpl({
|
||||
closeOnBackdrop
|
||||
overlayClassName={`platform-theme ${platformThemeClass} !items-center`}
|
||||
panelClassName="platform-remap-surface rounded-[1.75rem]"
|
||||
action={{
|
||||
label: '知道了',
|
||||
onClick: confirmWorkNotFoundRecovery,
|
||||
surface: 'platform',
|
||||
}}
|
||||
>
|
||||
{workNotFoundRecoveryDialog?.message}
|
||||
</PlatformStatusDialog>
|
||||
</PlatformAcknowledgeStatusDialog>
|
||||
<PlatformDangerConfirmDialog
|
||||
open={Boolean(pendingDeleteCreationWork)}
|
||||
title="删除作品"
|
||||
@@ -17083,7 +17073,7 @@ export function PlatformEntryFlowShellImpl({
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
>
|
||||
<PlatformStatusDialog
|
||||
<PlatformAcknowledgeStatusDialog
|
||||
status="error"
|
||||
title="未找到结果"
|
||||
description="公开编号搜索"
|
||||
@@ -17093,14 +17083,9 @@ export function PlatformEntryFlowShellImpl({
|
||||
closeLabel="关闭搜索结果"
|
||||
overlayClassName={`platform-theme ${platformThemeClass} !items-center bg-black/45 !p-4`}
|
||||
panelClassName="platform-remap-surface rounded-[1.6rem]"
|
||||
action={{
|
||||
label: '知道了',
|
||||
onClick: closePublicSearchResult,
|
||||
surface: 'platform',
|
||||
}}
|
||||
>
|
||||
{publicSearchError}
|
||||
</PlatformStatusDialog>
|
||||
</PlatformAcknowledgeStatusDialog>
|
||||
</motion.div>
|
||||
) : searchedPublicUser ? (
|
||||
<motion.div
|
||||
|
||||
@@ -94,6 +94,7 @@ import {
|
||||
} from '../asset-studio/characterAssetWorkflowPersistence';
|
||||
import { useAuthUi } from '../auth/AuthUiContext';
|
||||
import { CharacterAnimator } from '../CharacterAnimator';
|
||||
import { PlatformAcknowledgeStatusDialog } from '../common/PlatformAcknowledgeStatusDialog';
|
||||
import { PlatformAssetPickerGrid } from '../common/PlatformAssetPickerCard';
|
||||
import { PlatformEmptyState } from '../common/PlatformEmptyState';
|
||||
import { PlatformIconButton } from '../common/PlatformIconButton';
|
||||
@@ -102,7 +103,6 @@ import { PlatformModalCloseButton } from '../common/PlatformModalCloseButton';
|
||||
import { PlatformOverlayBadge } from '../common/PlatformOverlayBadge';
|
||||
import { PlatformPillBadge } from '../common/PlatformPillBadge';
|
||||
import { PlatformSlotBadge } from '../common/PlatformSlotBadge';
|
||||
import { PlatformStatusDialog } from '../common/PlatformStatusDialog';
|
||||
import { PlatformStatusMessage } from '../common/PlatformStatusMessage';
|
||||
import { PlatformSubpanel } from '../common/PlatformSubpanel';
|
||||
import { PlatformUnsavedLeaveConfirmDialog } from '../common/PlatformUnsavedLeaveConfirmDialog';
|
||||
@@ -1491,7 +1491,7 @@ function EditorNoticeDialog({
|
||||
onClose: () => void;
|
||||
}) {
|
||||
return (
|
||||
<PlatformStatusDialog
|
||||
<PlatformAcknowledgeStatusDialog
|
||||
status="error"
|
||||
title="提示"
|
||||
description={message}
|
||||
@@ -1500,14 +1500,9 @@ function EditorNoticeDialog({
|
||||
showCloseButton
|
||||
closeOnBackdrop
|
||||
closeOnEscape
|
||||
action={{
|
||||
label: '知道了',
|
||||
onClick: onClose,
|
||||
surface: 'platform',
|
||||
size: 'sm',
|
||||
fullWidth: false,
|
||||
className: 'min-h-0 rounded-full px-4 py-2',
|
||||
}}
|
||||
actionSize="sm"
|
||||
actionFullWidth={false}
|
||||
actionClassName="min-h-0 rounded-full px-4 py-2"
|
||||
zIndexClassName="z-[140]"
|
||||
overlayClassName="rpg-editor-notice-dialog-overlay !items-center"
|
||||
panelClassName="platform-remap-surface rounded-[1.5rem]"
|
||||
|
||||
@@ -73,6 +73,7 @@ import {
|
||||
import { shouldShowRechargeEntry } from '../../services/payment/paymentPlatform';
|
||||
import type { CustomWorldProfile } from '../../types';
|
||||
import { useAuthUi } from '../auth/AuthUiContext';
|
||||
import { PlatformAcknowledgeStatusDialog } from '../common/PlatformAcknowledgeStatusDialog';
|
||||
import { CopyFeedbackButton } from '../common/CopyFeedbackButton';
|
||||
import { LegalDocumentModal } from '../common/LegalDocumentModal';
|
||||
import {
|
||||
@@ -2476,12 +2477,12 @@ function RechargePaymentResultModal({
|
||||
: 'error';
|
||||
|
||||
return (
|
||||
<PlatformStatusDialog
|
||||
<PlatformAcknowledgeStatusDialog
|
||||
status={status}
|
||||
title={result.title}
|
||||
description={result.message}
|
||||
onClose={onClose}
|
||||
action={{ label: '知道了', onClick: onClose }}
|
||||
actionSurface="profile"
|
||||
zIndexClassName="z-[90]"
|
||||
overlayClassName={PROFILE_MODAL_OVERLAY_CLASS}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user