From 9d67f237a2b23bf63061888d4a228c32c11becd7 Mon Sep 17 00:00:00 2001 From: Yaojia Wang Date: Tue, 30 Jun 2026 08:56:23 +0200 Subject: [PATCH] =?UTF-8?q?feat(web):=20=E7=94=9F=E6=88=90=E5=99=A8=20Thin?= =?UTF-8?q?kingIndicator/=E7=A9=BA=E7=BB=93=E6=9E=9C=E6=80=81/=E6=95=B0?= =?UTF-8?q?=E9=87=8F=E6=A0=A1=E9=AA=8C=20+=20=E6=96=87=E9=A3=8E=E9=A1=B5?= =?UTF-8?q?=20PageHeader=20+=20Codex=20=E5=88=86=E6=AE=B5=E6=8E=A7?= =?UTF-8?q?=E4=BB=B6=20+=20RefineView=20role=20=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web/components/codex/CodexPage.tsx | 28 ++++------- .../generation/CharacterGenerator.tsx | 25 ++++++++-- .../generation/ConflictAdjudication.tsx | 6 +++ .../components/generation/WorldGenerator.tsx | 47 ++++++++++++++++++- apps/web/components/style/RefineView.tsx | 26 ++++++---- apps/web/components/style/StylePage.tsx | 38 ++++++++++----- apps/web/components/style/StylePanel.tsx | 2 +- 7 files changed, 126 insertions(+), 46 deletions(-) diff --git a/apps/web/components/codex/CodexPage.tsx b/apps/web/components/codex/CodexPage.tsx index 050e36a..6124627 100644 --- a/apps/web/components/codex/CodexPage.tsx +++ b/apps/web/components/codex/CodexPage.tsx @@ -11,6 +11,7 @@ import { Button } from "@/components/ui/Button"; import { Card } from "@/components/ui/Card"; import { EmptyState } from "@/components/ui/EmptyState"; import { PageHeader } from "@/components/ui/PageHeader"; +import { SegmentedControl } from "@/components/ui/SegmentedControl"; import type { CharacterCardView, ProjectResponse, @@ -70,24 +71,13 @@ export function CodexPage({ title="设定库" description="人物、世界观与时间线共同构成写作时的真相源。AI 生成内容也要先预览、再确认入库。" /> -
- {TABS.map((t) => ( - - ))} -
+ ({ value: t.key, label: t.label }))} + />
{tab === "characters" ? ( @@ -119,7 +109,7 @@ export function CodexPage({ {c.relations.map((r, j) => (
  • {r.kind} · {r.name} diff --git a/apps/web/components/generation/CharacterGenerator.tsx b/apps/web/components/generation/CharacterGenerator.tsx index 06af9e8..ae978d5 100644 --- a/apps/web/components/generation/CharacterGenerator.tsx +++ b/apps/web/components/generation/CharacterGenerator.tsx @@ -3,6 +3,7 @@ import { useCallback, useEffect, useMemo, useState } from "react"; import { Database, Sparkles } from "lucide-react"; +import { ThinkingIndicator } from "@/components/ThinkingIndicator"; import { Button } from "@/components/ui/Button"; import { Field } from "@/components/ui/Field"; import { SectionHeader } from "@/components/ui/SectionHeader"; @@ -10,6 +11,7 @@ import { StatusNote } from "@/components/ui/StatusNote"; import { TextInput } from "@/components/ui/TextInput"; import type { CharacterCardView } from "@/lib/api/types"; import { + clampCharacterCount, MAX_CHARACTER_COUNT, MIN_CHARACTER_COUNT, updateCard, @@ -95,13 +97,19 @@ export function CharacterGenerator({ />
    - + setCount(Number(e.target.value))} + onChange={(e) => + setCount(clampCharacterCount(Number(e.target.value))) + } /> @@ -113,7 +121,12 @@ export function CharacterGenerator({
  • + {generating ? ( +
    + +
    + ) : null} + {gen.genStatus === "preview" && drafts.length > 0 ? (

    diff --git a/apps/web/components/generation/ConflictAdjudication.tsx b/apps/web/components/generation/ConflictAdjudication.tsx index 908fab5..a34250e 100644 --- a/apps/web/components/generation/ConflictAdjudication.tsx +++ b/apps/web/components/generation/ConflictAdjudication.tsx @@ -1,5 +1,6 @@ "use client"; +import { ThinkingIndicator } from "@/components/ThinkingIndicator"; import { Button } from "@/components/ui/Button"; import type { IngestConflicts } from "@/lib/generation/cards"; @@ -74,6 +75,11 @@ export function ConflictAdjudication({ 取消,回去改卡

    + {busy ? ( +
    + +
    + ) : null} ); } diff --git a/apps/web/components/generation/WorldGenerator.tsx b/apps/web/components/generation/WorldGenerator.tsx index 677cea4..3cb27dc 100644 --- a/apps/web/components/generation/WorldGenerator.tsx +++ b/apps/web/components/generation/WorldGenerator.tsx @@ -1,10 +1,12 @@ "use client"; import { useCallback, useState } from "react"; -import { Copy, Sparkles } from "lucide-react"; +import { Copy, Globe2, RotateCcw, Sparkles } from "lucide-react"; import { useToast } from "@/components/Toast"; +import { ThinkingIndicator } from "@/components/ThinkingIndicator"; import { Button } from "@/components/ui/Button"; +import { EmptyState } from "@/components/ui/EmptyState"; import { Field } from "@/components/ui/Field"; import { SectionHeader } from "@/components/ui/SectionHeader"; import { StatusNote } from "@/components/ui/StatusNote"; @@ -72,6 +74,49 @@ export function WorldGenerator({ projectId }: WorldGeneratorProps) { + {generating ? ( +
    + +
    + ) : null} + + {gen.status === "error" ? ( + + + 生成失败,请稍后重试。 + + + + ) : null} + + {gen.status === "done" && gen.entities.length === 0 ? ( + void onGenerate()} + disabled={brief.trim().length === 0} + > +