refactor: split large modules and normalize rust layout

This commit is contained in:
kdletters
2026-05-18 19:40:14 +08:00
parent 472a47eae7
commit 269f35cecf
51 changed files with 17492 additions and 17169 deletions

View File

@@ -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}

View File

@@ -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>
);
}