收口前端平台组件库能力
新增 PlatformUiKit 通用弹窗、按钮、状态、空态、媒体、表单和标签等公共组件 迁移结果页、创作工作台、认证入口、RPG 暗色面板和运行态弹窗的重复 UI chrome 补充组件测试、页面回归测试、技术文档和 Hermes 共享决策记录
This commit is contained in:
@@ -1,13 +1,14 @@
|
||||
import { Check, Copy } from 'lucide-react';
|
||||
import { useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { useEffect, useMemo } from 'react';
|
||||
|
||||
import { copyTextToClipboard } from '../../services/clipboard';
|
||||
import { useAuthUi } from '../auth/AuthUiContext';
|
||||
import { CopyFeedbackButton } from './CopyFeedbackButton';
|
||||
import { PlatformInfoBlock } from './PlatformInfoBlock';
|
||||
import {
|
||||
buildPublishShareText,
|
||||
type PublishShareModalPayload,
|
||||
} from './publishShareModalModel';
|
||||
import { UnifiedModal } from './UnifiedModal';
|
||||
import { useCopyFeedback } from './useCopyFeedback';
|
||||
|
||||
type PublishShareModalProps = {
|
||||
open: boolean;
|
||||
@@ -94,43 +95,22 @@ export function PublishShareModal({
|
||||
onClose,
|
||||
}: PublishShareModalProps) {
|
||||
const platformTheme = useAuthUi()?.platformTheme ?? 'light';
|
||||
const [copyState, setCopyState] = useState<'idle' | 'copied' | 'failed'>(
|
||||
'idle',
|
||||
);
|
||||
const resetTimerRef = useRef<number | null>(null);
|
||||
const { copyState, copyText, resetCopyState } = useCopyFeedback();
|
||||
const shareText = useMemo(
|
||||
() => (payload ? buildPublishShareText(payload) : ''),
|
||||
[payload],
|
||||
);
|
||||
|
||||
useEffect(
|
||||
() => () => {
|
||||
if (resetTimerRef.current !== null) {
|
||||
window.clearTimeout(resetTimerRef.current);
|
||||
}
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
setCopyState('idle');
|
||||
}, [payload?.publicWorkCode]);
|
||||
resetCopyState();
|
||||
}, [payload?.publicWorkCode, resetCopyState]);
|
||||
|
||||
const copyShareText = () => {
|
||||
if (!shareText) {
|
||||
return;
|
||||
}
|
||||
|
||||
void copyTextToClipboard(shareText).then((copied) => {
|
||||
setCopyState(copied ? 'copied' : 'failed');
|
||||
if (resetTimerRef.current !== null) {
|
||||
window.clearTimeout(resetTimerRef.current);
|
||||
}
|
||||
resetTimerRef.current = window.setTimeout(() => {
|
||||
resetTimerRef.current = null;
|
||||
setCopyState('idle');
|
||||
}, 1400);
|
||||
});
|
||||
void copyText(shareText);
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -167,28 +147,22 @@ export function PublishShareModal({
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<div className="rounded-[1.25rem] border border-[var(--platform-subpanel-border)] bg-white/72 p-4">
|
||||
<div className="whitespace-pre-wrap break-words text-sm leading-6 text-[var(--platform-text-strong)]">
|
||||
{shareText}
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
<PlatformInfoBlock
|
||||
multiline
|
||||
className="rounded-[1.25rem] p-4"
|
||||
valueClassName="mt-0"
|
||||
>
|
||||
{shareText}
|
||||
</PlatformInfoBlock>
|
||||
<CopyFeedbackButton
|
||||
state={copyState}
|
||||
onClick={copyShareText}
|
||||
disabled={!shareText}
|
||||
className="platform-button platform-button--primary w-full justify-center gap-2 disabled:cursor-not-allowed disabled:opacity-55"
|
||||
>
|
||||
{copyState === 'copied' ? (
|
||||
<Check className="h-4 w-4" />
|
||||
) : (
|
||||
<Copy className="h-4 w-4" />
|
||||
)}
|
||||
{copyState === 'copied'
|
||||
? '已复制'
|
||||
: copyState === 'failed'
|
||||
? '复制失败'
|
||||
: '分享'}
|
||||
</button>
|
||||
idleLabel="分享"
|
||||
actionSurface="platform"
|
||||
actionFullWidth
|
||||
className="disabled:opacity-55"
|
||||
/>
|
||||
</UnifiedModal>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user