diff --git a/apps/mana/apps/web/src/lib/modules/comic/components/BatchPanelEditor.svelte b/apps/mana/apps/web/src/lib/modules/comic/components/BatchPanelEditor.svelte new file mode 100644 index 000000000..41caa0510 --- /dev/null +++ b/apps/mana/apps/web/src/lib/modules/comic/components/BatchPanelEditor.svelte @@ -0,0 +1,394 @@ + + + +
+
+
+

Batch-Panels

+

+ {filledRows.length} + {filledRows.length === 1 ? 'Panel' : 'Panels'} · {story.characterMediaIds.length} Referenz{story + .characterMediaIds.length === 1 + ? '' + : 'en'} · {roomLeft} + {roomLeft === 1 ? 'Slot' : 'Slots'} frei +

+
+ +
+ + {#if atCap} + + {:else if warn} +

+ Hinweis: Ab ~{PANEL_COUNT_WARN_THRESHOLD} Panels wird Character-Konsistenz spürbar schwerer. +

+ {/if} + +
+
+ {#each effectiveRows as row, index (row.id)} + {@const status = rowStatus[row.id]} +
+
+
+ + {panelCount + index + 1} + + Panel {index + 1} + {#if status?.status === 'pending'} + + + Wird generiert… + + {:else if status?.status === 'ok'} + + + Fertig + + {:else if status?.status === 'error'} + + + Fehlgeschlagen + + {/if} +
+
+ {#if status?.status === 'error'} + + {/if} + {#if rows.length > 1} + + {/if} +
+
+ + + +
+ + +
+ + {#if status?.status === 'error' && status.error} + + {/if} +
+ {/each} +
+ +
+ +
+ +
+
+ Qualität: + {#each QUALITIES as q (q)} + + {/each} +
+
+ Format: + + +
+
+ +
+ +
+
+
+ + diff --git a/apps/mana/apps/web/src/lib/modules/comic/views/DetailView.svelte b/apps/mana/apps/web/src/lib/modules/comic/views/DetailView.svelte index 778eea7fd..ffc6597d1 100644 --- a/apps/mana/apps/web/src/lib/modules/comic/views/DetailView.svelte +++ b/apps/mana/apps/web/src/lib/modules/comic/views/DetailView.svelte @@ -18,6 +18,7 @@ import { STYLE_LABELS } from '../constants'; import PanelStrip from '../components/PanelStrip.svelte'; import PanelEditor from '../components/PanelEditor.svelte'; + import BatchPanelEditor from '../components/BatchPanelEditor.svelte'; import { encryptRecord } from '$lib/data/crypto'; import type { ComicPanelMeta, LocalComicStory } from '../types'; @@ -31,7 +32,8 @@ const story$ = useStory(id); const story = $derived(story$.value); - let showEditor = $state(false); + type EditorMode = 'off' | 'single' | 'batch'; + let editorMode = $state('off'); async function handleToggleFavorite() { if (!story) return; @@ -168,15 +170,26 @@

Panels

- {#if !showEditor && !story.isArchived} - + {#if editorMode === 'off' && !story.isArchived} +
+ + +
{/if}
@@ -186,16 +199,18 @@ onRemove={handleRemovePanel} /> - {#if showEditor && !story.isArchived} + {#if editorMode === 'single' && !story.isArchived} (showEditor = false)} + onClose={() => (editorMode = 'off')} onGenerated={() => { // Keep the editor open for rapid iteration — the user // usually wants to generate 3–5 panels in a row. Reset // happens inside PanelEditor on success. }} /> + {:else if editorMode === 'batch' && !story.isArchived} + (editorMode = 'off')} /> {/if}