refactor: split large modules and normalize rust layout
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { ArrowRight, Loader2, Sparkles } from 'lucide-react';
|
||||
import { ArrowRight, Loader2 } from 'lucide-react';
|
||||
import { AnimatePresence, motion } from 'motion/react';
|
||||
import {
|
||||
type Dispatch,
|
||||
@@ -332,6 +332,11 @@ import {
|
||||
filterGeneralPublicWorks,
|
||||
} from './platformEdutainmentVisibility';
|
||||
import { PlatformEntryCreationTypeModal } from './PlatformEntryCreationTypeModal';
|
||||
import {
|
||||
PuzzleOnboardingLoginOverlay,
|
||||
type PuzzleOnboardingPhase,
|
||||
PuzzleOnboardingView,
|
||||
} from './PlatformEntryFlowShellImpl/PuzzleOnboardingView';
|
||||
import type { PlatformCreationTypeId } from './platformEntryCreationTypes';
|
||||
import {
|
||||
derivePlatformCreationTypes,
|
||||
@@ -402,8 +407,6 @@ type PuzzleRuntimeReturnStage =
|
||||
| 'platform';
|
||||
type PuzzleRuntimeAuthMode = 'default' | 'isolated';
|
||||
|
||||
type PuzzleOnboardingPhase = 'input' | 'generating' | 'generated';
|
||||
|
||||
type PuzzleOnboardingDraft = {
|
||||
promptText: string;
|
||||
item: PuzzleWorkSummary;
|
||||
@@ -1340,134 +1343,6 @@ function markPuzzleOnboardingSeen() {
|
||||
}
|
||||
}
|
||||
|
||||
function PuzzleOnboardingView({
|
||||
prompt,
|
||||
phase,
|
||||
error,
|
||||
onPromptChange,
|
||||
onSubmit,
|
||||
onSkip,
|
||||
}: {
|
||||
prompt: string;
|
||||
phase: PuzzleOnboardingPhase;
|
||||
error: string | null;
|
||||
onPromptChange: (value: string) => void;
|
||||
onSubmit: () => void;
|
||||
onSkip: () => void;
|
||||
}) {
|
||||
const isGenerating = phase === 'generating';
|
||||
const isGenerated = phase === 'generated';
|
||||
const canSubmit = Boolean(prompt.trim()) && !isGenerating && !isGenerated;
|
||||
|
||||
return (
|
||||
<div className="relative flex min-h-screen items-center justify-center overflow-hidden bg-[radial-gradient(circle_at_30%_15%,rgba(251,191,36,0.22),transparent_30%),linear-gradient(135deg,#0f172a,#111827_46%,#1e1b4b)] px-4 py-8 text-white">
|
||||
<div className="absolute inset-0 bg-[linear-gradient(rgba(255,255,255,0.045)_1px,transparent_1px),linear-gradient(90deg,rgba(255,255,255,0.04)_1px,transparent_1px)] bg-[length:38px_38px] opacity-30" />
|
||||
<button
|
||||
type="button"
|
||||
disabled={isGenerating}
|
||||
onClick={onSkip}
|
||||
className="absolute right-4 top-4 z-10 inline-flex min-h-10 items-center justify-center rounded-full border border-white/14 bg-black/24 px-4 text-sm font-black text-white/86 shadow-[0_12px_28px_rgba(0,0,0,0.22)] backdrop-blur transition hover:border-amber-200/45 hover:text-amber-100 disabled:cursor-not-allowed disabled:opacity-45 sm:right-6 sm:top-6"
|
||||
>
|
||||
跳过
|
||||
</button>
|
||||
<section className="relative flex w-full max-w-[34rem] flex-col items-center gap-5 text-center">
|
||||
<div className="grid h-14 w-14 place-items-center rounded-[1.2rem] border border-amber-200/32 bg-amber-200/14 text-amber-100 shadow-[0_18px_48px_rgba(251,191,36,0.18)]">
|
||||
{isGenerating ? (
|
||||
<Loader2 className="h-6 w-6 animate-spin" />
|
||||
) : (
|
||||
<Sparkles className="h-6 w-6" />
|
||||
)}
|
||||
</div>
|
||||
<h1 className="text-[2rem] font-black leading-tight sm:text-[2.85rem]">
|
||||
{PUZZLE_ONBOARDING_COPY}
|
||||
</h1>
|
||||
<form
|
||||
className="flex w-full flex-col gap-3"
|
||||
onSubmit={(event) => {
|
||||
event.preventDefault();
|
||||
onSubmit();
|
||||
}}
|
||||
>
|
||||
<textarea
|
||||
value={prompt}
|
||||
disabled={isGenerating || isGenerated}
|
||||
onChange={(event) => onPromptChange(event.target.value)}
|
||||
placeholder="把你的梦讲给我听吧"
|
||||
rows={4}
|
||||
className="min-h-32 w-full resize-none rounded-[1.25rem] border border-white/14 bg-black/28 px-4 py-4 text-base font-semibold leading-7 text-white shadow-[0_18px_50px_rgba(0,0,0,0.24)] outline-none backdrop-blur placeholder:text-white/42 focus:border-amber-200/70 focus:ring-2 focus:ring-amber-200/20 disabled:opacity-70"
|
||||
/>
|
||||
<button
|
||||
type="submit"
|
||||
disabled={!canSubmit}
|
||||
className="inline-flex min-h-12 items-center justify-center gap-2 rounded-[1rem] bg-amber-200 px-5 text-sm font-black text-slate-950 transition hover:bg-amber-100 disabled:cursor-not-allowed disabled:opacity-45"
|
||||
>
|
||||
{isGenerating ? (
|
||||
<>
|
||||
<Loader2 className="h-4 w-4 animate-spin" />
|
||||
生成
|
||||
</>
|
||||
) : (
|
||||
'生成'
|
||||
)}
|
||||
</button>
|
||||
</form>
|
||||
{error ? (
|
||||
<div className="w-full rounded-[1rem] border border-red-300/30 bg-red-500/14 px-4 py-3 text-sm font-semibold text-red-50">
|
||||
{error}
|
||||
</div>
|
||||
) : null}
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function PuzzleOnboardingLoginOverlay({
|
||||
isSaving,
|
||||
error,
|
||||
onLogin,
|
||||
}: {
|
||||
isSaving: boolean;
|
||||
error: string | null;
|
||||
onLogin: () => void;
|
||||
}) {
|
||||
return (
|
||||
<div className="fixed inset-0 z-[110] flex items-center justify-center bg-slate-950/72 px-4 py-6 text-white backdrop-blur-md">
|
||||
<section className="flex w-full max-w-[24rem] flex-col items-center gap-5 rounded-[1.35rem] border border-white/14 bg-slate-950/94 px-5 py-6 text-center shadow-[0_28px_90px_rgba(0,0,0,0.5)]">
|
||||
<div className="grid h-12 w-12 place-items-center rounded-[1rem] bg-amber-200 text-slate-950">
|
||||
{isSaving ? (
|
||||
<Loader2 className="h-5 w-5 animate-spin" />
|
||||
) : (
|
||||
<Sparkles className="h-5 w-5" />
|
||||
)}
|
||||
</div>
|
||||
<h2 className="text-2xl font-black leading-tight">
|
||||
{PUZZLE_ONBOARDING_CLEAR_COPY}
|
||||
</h2>
|
||||
<button
|
||||
type="button"
|
||||
disabled={isSaving}
|
||||
onClick={onLogin}
|
||||
className="inline-flex min-h-12 w-full items-center justify-center gap-2 rounded-[1rem] bg-amber-200 px-5 text-sm font-black text-slate-950 transition hover:bg-amber-100 disabled:cursor-not-allowed disabled:opacity-45"
|
||||
>
|
||||
{isSaving ? (
|
||||
<>
|
||||
<Loader2 className="h-4 w-4 animate-spin" />
|
||||
注册账号 / 登录
|
||||
</>
|
||||
) : (
|
||||
'注册账号 / 登录'
|
||||
)}
|
||||
</button>
|
||||
{error ? (
|
||||
<div className="w-full rounded-[1rem] border border-red-300/30 bg-red-500/14 px-4 py-3 text-sm font-semibold text-red-50">
|
||||
{error}
|
||||
</div>
|
||||
) : null}
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function mergeBigFishWorkSummary(
|
||||
current: BigFishWorkSummary,
|
||||
updated: BigFishWorkSummary,
|
||||
@@ -12435,6 +12310,7 @@ export function PlatformEntryFlowShellImpl({
|
||||
prompt={puzzleOnboardingPrompt}
|
||||
phase={puzzleOnboardingPhase}
|
||||
error={puzzleOnboardingError}
|
||||
copy={PUZZLE_ONBOARDING_COPY}
|
||||
onPromptChange={setPuzzleOnboardingPrompt}
|
||||
onSubmit={() => {
|
||||
void submitPuzzleOnboardingPrompt();
|
||||
@@ -12808,6 +12684,7 @@ export function PlatformEntryFlowShellImpl({
|
||||
<PuzzleOnboardingLoginOverlay
|
||||
isSaving={isPuzzleOnboardingSaving}
|
||||
error={puzzleOnboardingError}
|
||||
copy={PUZZLE_ONBOARDING_CLEAR_COPY}
|
||||
onLogin={requestPuzzleOnboardingLogin}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
import { Loader2, Sparkles } from 'lucide-react';
|
||||
|
||||
export type PuzzleOnboardingPhase = 'input' | 'generating' | 'generated';
|
||||
|
||||
type PuzzleOnboardingViewProps = {
|
||||
prompt: string;
|
||||
phase: PuzzleOnboardingPhase;
|
||||
error: string | null;
|
||||
copy: string;
|
||||
onPromptChange: (value: string) => void;
|
||||
onSubmit: () => void;
|
||||
onSkip: () => void;
|
||||
};
|
||||
|
||||
export function PuzzleOnboardingView({
|
||||
prompt,
|
||||
phase,
|
||||
error,
|
||||
copy,
|
||||
onPromptChange,
|
||||
onSubmit,
|
||||
onSkip,
|
||||
}: PuzzleOnboardingViewProps) {
|
||||
const isGenerating = phase === 'generating';
|
||||
const isGenerated = phase === 'generated';
|
||||
const canSubmit = Boolean(prompt.trim()) && !isGenerating && !isGenerated;
|
||||
|
||||
return (
|
||||
<div className="relative flex min-h-screen items-center justify-center overflow-hidden bg-[radial-gradient(circle_at_30%_15%,rgba(251,191,36,0.22),transparent_30%),linear-gradient(135deg,#0f172a,#111827_46%,#1e1b4b)] px-4 py-8 text-white">
|
||||
<div className="absolute inset-0 bg-[linear-gradient(rgba(255,255,255,0.045)_1px,transparent_1px),linear-gradient(90deg,rgba(255,255,255,0.04)_1px,transparent_1px)] bg-[length:38px_38px] opacity-30" />
|
||||
<button
|
||||
type="button"
|
||||
disabled={isGenerating}
|
||||
onClick={onSkip}
|
||||
className="absolute right-4 top-4 z-10 inline-flex min-h-10 items-center justify-center rounded-full border border-white/14 bg-black/24 px-4 text-sm font-black text-white/86 shadow-[0_12px_28px_rgba(0,0,0,0.22)] backdrop-blur transition hover:border-amber-200/45 hover:text-amber-100 disabled:cursor-not-allowed disabled:opacity-45 sm:right-6 sm:top-6"
|
||||
>
|
||||
跳过
|
||||
</button>
|
||||
<section className="relative flex w-full max-w-[34rem] flex-col items-center gap-5 text-center">
|
||||
<div className="grid h-14 w-14 place-items-center rounded-[1.2rem] border border-amber-200/32 bg-amber-200/14 text-amber-100 shadow-[0_18px_48px_rgba(251,191,36,0.18)]">
|
||||
{isGenerating ? (
|
||||
<Loader2 className="h-6 w-6 animate-spin" />
|
||||
) : (
|
||||
<Sparkles className="h-6 w-6" />
|
||||
)}
|
||||
</div>
|
||||
<h1 className="text-[2rem] font-black leading-tight sm:text-[2.85rem]">
|
||||
{copy}
|
||||
</h1>
|
||||
<form
|
||||
className="flex w-full flex-col gap-3"
|
||||
onSubmit={(event) => {
|
||||
event.preventDefault();
|
||||
onSubmit();
|
||||
}}
|
||||
>
|
||||
<textarea
|
||||
value={prompt}
|
||||
disabled={isGenerating || isGenerated}
|
||||
onChange={(event) => onPromptChange(event.target.value)}
|
||||
placeholder="把你的梦讲给我听吧"
|
||||
rows={4}
|
||||
className="min-h-32 w-full resize-none rounded-[1.25rem] border border-white/14 bg-black/28 px-4 py-4 text-base font-semibold leading-7 text-white shadow-[0_18px_50px_rgba(0,0,0,0.24)] outline-none backdrop-blur placeholder:text-white/42 focus:border-amber-200/70 focus:ring-2 focus:ring-amber-200/20 disabled:opacity-70"
|
||||
/>
|
||||
<button
|
||||
type="submit"
|
||||
disabled={!canSubmit}
|
||||
className="inline-flex min-h-12 items-center justify-center gap-2 rounded-[1rem] bg-amber-200 px-5 text-sm font-black text-slate-950 transition hover:bg-amber-100 disabled:cursor-not-allowed disabled:opacity-45"
|
||||
>
|
||||
{isGenerating ? (
|
||||
<>
|
||||
<Loader2 className="h-4 w-4 animate-spin" />
|
||||
生成
|
||||
</>
|
||||
) : (
|
||||
'生成'
|
||||
)}
|
||||
</button>
|
||||
</form>
|
||||
{error ? (
|
||||
<div className="w-full rounded-[1rem] border border-red-300/30 bg-red-500/14 px-4 py-3 text-sm font-semibold text-red-50">
|
||||
{error}
|
||||
</div>
|
||||
) : null}
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
type PuzzleOnboardingLoginOverlayProps = {
|
||||
isSaving: boolean;
|
||||
error: string | null;
|
||||
copy: string;
|
||||
onLogin: () => void;
|
||||
};
|
||||
|
||||
export function PuzzleOnboardingLoginOverlay({
|
||||
isSaving,
|
||||
error,
|
||||
copy,
|
||||
onLogin,
|
||||
}: PuzzleOnboardingLoginOverlayProps) {
|
||||
return (
|
||||
<div className="fixed inset-0 z-[110] flex items-center justify-center bg-slate-950/72 px-4 py-6 text-white backdrop-blur-md">
|
||||
<section className="flex w-full max-w-[24rem] flex-col items-center gap-5 rounded-[1.35rem] border border-white/14 bg-slate-950/94 px-5 py-6 text-center shadow-[0_28px_90px_rgba(0,0,0,0.5)]">
|
||||
<div className="grid h-12 w-12 place-items-center rounded-[1rem] bg-amber-200 text-slate-950">
|
||||
{isSaving ? (
|
||||
<Loader2 className="h-5 w-5 animate-spin" />
|
||||
) : (
|
||||
<Sparkles className="h-5 w-5" />
|
||||
)}
|
||||
</div>
|
||||
<h2 className="text-2xl font-black leading-tight">{copy}</h2>
|
||||
<button
|
||||
type="button"
|
||||
disabled={isSaving}
|
||||
onClick={onLogin}
|
||||
className="inline-flex min-h-12 w-full items-center justify-center gap-2 rounded-[1rem] bg-amber-200 px-5 text-sm font-black text-slate-950 transition hover:bg-amber-100 disabled:cursor-not-allowed disabled:opacity-45"
|
||||
>
|
||||
{isSaving ? (
|
||||
<>
|
||||
<Loader2 className="h-4 w-4 animate-spin" />
|
||||
注册账号 / 登录
|
||||
</>
|
||||
) : (
|
||||
'注册账号 / 登录'
|
||||
)}
|
||||
</button>
|
||||
{error ? (
|
||||
<div className="w-full rounded-[1rem] border border-red-300/30 bg-red-500/14 px-4 py-3 text-sm font-semibold text-red-50">
|
||||
{error}
|
||||
</div>
|
||||
) : null}
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user