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 99c84fff6..1e6f8eeae 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 @@ -31,27 +31,36 @@ * character — name+style+source are locked, only Add-Prompt * is editable per generation. */ existing?: ComicCharacter; + /** Optional pre-fills for create-mode — used by the wardrobe- + * hook (Mc5) to seed an addPrompt like "wearing the + * Bühnenoutfit" when the user clicks "Als Comic-Character" + * on a Wardrobe-Outfit. Ignored in extend-mode. */ + initialName?: string; + initialAddPrompt?: string; + initialStyle?: ComicStyle; /** Called after the first successful variant batch with the * resulting character id, so the parent route can navigate. */ onCreated?: (characterId: string) => void; onClose?: () => void; } - let { existing, onClose, onCreated }: Props = $props(); + let { existing, initialName, initialAddPrompt, initialStyle, onClose, onCreated }: Props = + $props(); const isExtend = $derived(Boolean(existing)); // Builder state. In extend-mode all of these come from `existing` // at mount time and aren't editable; in create-mode the user fills - // them in. Init-time read of `existing` is intentional — the + // them in (with optional pre-fills from URL-params via the route + // page wrapper). Init-time read is intentional — the // character is always remounted via {#key} when the route id // changes, so capturing the snapshot here is correct. // svelte-ignore state_referenced_locally - let name = $state(existing?.name ?? ''); + let name = $state(existing?.name ?? initialName ?? ''); // svelte-ignore state_referenced_locally - let style = $state(existing?.style ?? 'comic'); + let style = $state(existing?.style ?? initialStyle ?? 'comic'); // svelte-ignore state_referenced_locally - let addPrompt = $state(existing?.addPrompt ?? ''); + let addPrompt = $state(existing?.addPrompt ?? initialAddPrompt ?? ''); type Quality = 'low' | 'medium' | 'high'; const QUALITIES: readonly Quality[] = ['low', 'medium', 'high'] as const; diff --git a/apps/mana/apps/web/src/lib/modules/wardrobe/views/DetailGarmentView.svelte b/apps/mana/apps/web/src/lib/modules/wardrobe/views/DetailGarmentView.svelte index 5a739e622..931ff93da 100644 --- a/apps/mana/apps/web/src/lib/modules/wardrobe/views/DetailGarmentView.svelte +++ b/apps/mana/apps/web/src/lib/modules/wardrobe/views/DetailGarmentView.svelte @@ -6,7 +6,7 @@ --> @@ -16,6 +34,6 @@ Detail kannst du jederzeit weitere generieren.

- + diff --git a/docs/plans/comic-module.md b/docs/plans/comic-module.md index 40d62f931..fd61cac43 100644 --- a/docs/plans/comic-module.md +++ b/docs/plans/comic-module.md @@ -685,11 +685,23 @@ Encryption-Roundtrip-Test. `generate_character_variant` in AI_TOOL_CATALOG. - Persona kann „mach mir einen Manga-Character für Story X" sagen. -**Mc5 — Wardrobe-Hook** (~2h, optional): -- In Wardrobe-DetailOutfitView nach erfolgreichem Try-On ein - Knopf „Als Comic-Character speichern" → öffnet Builder mit - Try-On-Result als optionalem `sourceBodyMediaId`. -- In DetailGarmentView analog für ein einzelnes Kleidungsstück. +**Mc5 — Wardrobe-Hook** ✅ shipped: +- In Wardrobe-DetailOutfitView ein „Als Comic-Character"-Knopf + unterhalb des TryOnButton, navigiert zu + `/comic/character/new?title=…&prompt=wearing+the+OUTFITNAME+outfit`. +- In DetailGarmentView analog mit `prompt=wearing+GARMENTNAME`. +- CharacterBuilder akzeptiert `initialName` / `initialAddPrompt` / + `initialStyle`-Props. Die `/comic/character/new`-Route liest + URL-Params und reicht sie als initial state durch — der Builder + startet mit dem prefillten Add-Prompt, User picked Stil + rendert + die ersten 4 Varianten selbst. +- Bewusst KEIN Try-On-Output als sourceBodyMediaId: das + Try-On-Bild ist mit `app='picture'` getaggt, der + `verifyMediaOwnership`-Check des Comic-Endpoints akzeptiert nur + `['me', 'wardrobe', 'comic']`. Re-Upload als 'comic' wäre eine + zusätzliche Server-Route — Aufwand vs. Nutzen nicht klar. + Workflow stattdessen: rohe meImages bleiben Source, der + Add-Prompt steuert den Outfit-Look. ### Tradeoffs