From 0ff5030ad2c8dddec123c8b1c19e2a206672b2c7 Mon Sep 17 00:00:00 2001
From: Till JS
Date: Sat, 25 Apr 2026 18:16:24 +0200
Subject: [PATCH] =?UTF-8?q?feat(comic):=20Mc3=20=E2=80=94=20Story-Create?=
=?UTF-8?q?=20nutzt=20Character-Mode=20+=20Quick-Fallback?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Story-Anlegen ist jetzt zweigleisig: Default ist Character-Mode
(picke einen iterierten Comic-Character mit gepinntem Look),
Fallback ist Quick-Mode (rohes face/body/garments wie bisher) als
opt-in-Toggle für Spontan-Stories ohne Setup.
Datenmodell-Erweiterung (soft, kein Breaking-Change):
- LocalComicStory + ComicStory bekommen ein optionales
`characterId?: string | null` Feld, plaintext, FK auf
comicCharacters.id. Im Quick-Modus null, im Character-Modus die
gewählte Character-id.
- `characterMediaIds` bleibt das einzige Feld, das runPanelGenerate
liest — im Character-Modus enthält es genau die
`pinnedVariantMediaId` als single-element-Array (Snapshot zum
Story-Create-Zeitpunkt). Re-Pinning eines Characters ändert
bestehende Stories also NICHT, weil sie das mediaId fix
gespeichert haben. Im Quick-Modus enthält's face + body? +
garments[] wie vorher. Beide Modi gehen durch denselben
/picture/generate-with-reference-Pfad.
- Soft-Migration: bestehende Stories ohne `characterId` zeigen
weiterhin keine Character-Linkage und rendern wie vorher (die
`characterMediaIds` waren vorher ja schon die Quelle).
Neue Komponente:
- `CharacterRefPicker.svelte` ersetzt den alten `CharacterPicker`
in StoryForm. Mode-Toggle (Character | Quick) erscheint nur wenn
Characters existieren — sonst startet's direkt im Quick-Modus.
Character-Mode zeigt Grid der usableCharacters (nicht-archived
+ pinnedVariantId gesetzt) mit Cover, Style-Badge, Active-Border.
"+ Neuer Character"-Tile öffnet die Builder-Route. Quick-Modus
rendert intern den alten CharacterPicker (face/body/garments) —
reuse statt parallel zu pflegen.
StoryForm:
- 2 neue $state-Felder: `characterId` und (umbenannt-) der bestehende
`characterMediaIds`. CharacterRefPicker emittiert beide via
onChange-Callback.
- createStory bekommt `characterId` mit, das landet auf der Story-
Row. canSubmit greift weiterhin auf `characterMediaIds.length > 0`
— beide Modi liefern mindestens 1 ref.
CharacterBuilder Bugfix: prettier hatte den Add-Prompt-Placeholder
mit nested double-quotes zerstört (z.B. "freundlicher Ausdruck"
wurde zu invalidem HTML). Auf einfache Liste umgestellt.
8/8 Encryption-Tests weiter grün. check für comic-files clean.
Co-Authored-By: Claude Opus 4.7 (1M context)
---
.../comic/components/CharacterBuilder.svelte | 2 +-
.../components/CharacterRefPicker.svelte | 233 ++++++++++++++++++
.../modules/comic/components/StoryForm.svelte | 17 +-
.../modules/comic/stores/stories.svelte.ts | 5 +
.../apps/web/src/lib/modules/comic/types.ts | 21 +-
5 files changed, 270 insertions(+), 8 deletions(-)
create mode 100644 apps/mana/apps/web/src/lib/modules/comic/components/CharacterRefPicker.svelte
diff --git a/apps/mana/apps/web/src/lib/modules/comic/components/CharacterBuilder.svelte b/apps/mana/apps/web/src/lib/modules/comic/components/CharacterBuilder.svelte
index 8fba2985d..99c84fff6 100644
--- a/apps/mana/apps/web/src/lib/modules/comic/components/CharacterBuilder.svelte
+++ b/apps/mana/apps/web/src/lib/modules/comic/components/CharacterBuilder.svelte
@@ -194,7 +194,7 @@
id="character-add-prompt"
type="text"
bind:value={addPrompt}
- placeholder="z.B. "freundlicher Ausdruck", "casual outfit", "action pose""
+ placeholder="z.B. freundlicher Ausdruck, casual outfit, action pose"
maxlength={200}
class="block w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary disabled:opacity-50"
disabled={busy}
diff --git a/apps/mana/apps/web/src/lib/modules/comic/components/CharacterRefPicker.svelte b/apps/mana/apps/web/src/lib/modules/comic/components/CharacterRefPicker.svelte
new file mode 100644
index 000000000..2defd322a
--- /dev/null
+++ b/apps/mana/apps/web/src/lib/modules/comic/components/CharacterRefPicker.svelte
@@ -0,0 +1,233 @@
+
+
+
+
+
+ {#if usableCharacters.length > 0}
+
+
+
+
+ {/if}
+
+ {#if mode === 'character'}
+
+
+
+ Comic-Character wählen
+
+
+ Iterier vorher einen Character mit deinem Stil — alle Panels nutzen dann denselben
+ gepinnten Look.
+