diff --git a/CloudronManifest.json b/CloudronManifest.json index 75a11cc..d0be45b 100644 --- a/CloudronManifest.json +++ b/CloudronManifest.json @@ -3,7 +3,7 @@ "title": "Sendewerk", "description": "Redaktionelle Planung und Durchführung von heinzlive-Sendungen.", "tagline": "Vom Fundstück bis zur Livesendung", - "version": "0.6.0", + "version": "0.6.1", "healthCheckPath": "/healthz", "httpPort": 3000, "addons": { diff --git a/docs/ACCEPTANCE.md b/docs/ACCEPTANCE.md index e09882f..c05396b 100644 --- a/docs/ACCEPTANCE.md +++ b/docs/ACCEPTANCE.md @@ -1,5 +1,26 @@ # Abnahme +## Wartungsrelease 0.6.1 + +| Bereich | Stand | +| --- | --- | +| Live-Timer, Kopfzeile, Drawer und Positionsanzeige | behoben | +| Mobile Formulare und Iconsuche | behoben | +| Vorbereitungsaufwand und Übersicht | behoben | +| Bild-Präsentationsmodus | behoben | +| Twitch-Tags je Abschnitt | behoben | +| Sendungskarten und Gastabstände | behoben | +| Gemeinsamer Freigabedialog einschließlich Live-Regie | behoben | +| Editorzustand und Drag-and-drop | bestehende zustandserhaltende bzw. alternative Bedienwege unverändert; Browserprüfung offen | + +- `npm run check`: 0 Fehler und 0 Warnungen. +- `npm test`: 52 von 52 Verhaltenstests erfolgreich. +- `npm run build`: erfolgreich. +- `npm run test:e2e`: zweiter Lauf mit 14 erfolgreichen Abläufen; Live-Regie und + Abschluss/Freigaben schlugen fehl, zwei nachfolgende Abläufe wurden wegen des + 120-Sekunden-Zeitlimits nicht mehr ausgeführt. Die Browsermatrix ist offen. +- Safari auf echtem iOS-Gerät: nicht verfügbar. + ## Etappe 1 | Kriterium | Nachweis | Stand | diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index 8c4518a..77647a7 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -404,3 +404,12 @@ betroffenen Route und Action geprüft. Markdown und fremdes HTML werden vor Ausgabe bereinigt. Uploadzugriff folgt denselben Rechten. Netzwerkabrufe für Präsentationsmetadaten und Vorschaubilder schützen interne Ziele auch nach DNS-Auflösung und Redirects und besitzen Größen-, Zeit- und Redirectlimits. + +## Wartungsfelder 0.6.1 + +Migration `0017` ergänzt den optionalen Vorbereitungsaufwand am Original und +kommagetrennt validierte Twitch-Tags am Abschnitt. Der Bildmodus wird wegen der +bestehenden SQLite-Check-Constraints als zusätzliches Kennzeichen an Original +und Usage-Snapshot gespeichert; nach außen bleibt er der eindeutige Modus +`image`. Öffentlich passiert weiterhin nur das ausdrücklich gewählte +Präsentationsmedium. diff --git a/docs/DECISIONS.md b/docs/DECISIONS.md index f51ca82..2de2df0 100644 --- a/docs/DECISIONS.md +++ b/docs/DECISIONS.md @@ -451,3 +451,11 @@ oder URL zu wechseln. Bearbeitungen behalten den Link, invalidieren aber vorhandene Passwortsitzungen. Vollständiges Löschen ist der unmittelbare Widerruf. Die Sendungsbearbeitung und die zentrale Verwaltung verwenden dieselbe Geschäftslogik und bleiben Barkeepern vorbehalten. + +## D-028: Additive Wartungsfelder und gemeinsamer Freigabedialog + +Vorbereitungsaufwand und Twitch-Tags sind optionale additive Felder. Der neue +Bildmodus verwendet ein separates boolesches Kennzeichen, damit bestehende +Tabellen und Daten trotz älterer Modus-Check-Constraints ohne riskanten +Tabellenumbau erhalten bleiben. Freigabeverwaltung bleibt eine gemeinsame +Komponente und öffnet in allen drei internen Einstiegen als nativer Dialog. diff --git a/docs/RELEASE_NOTES.md b/docs/RELEASE_NOTES.md index 12a8aa9..c99a847 100644 --- a/docs/RELEASE_NOTES.md +++ b/docs/RELEASE_NOTES.md @@ -1,5 +1,16 @@ # Release Notes +## 0.6.1 - Redaktionelle Wartung + +Veröffentlicht am 25. Oktober 2026 + +- Live-Countdowns übernehmen geänderte Abschnittsplanzeiten, ohne Laufzeit zu verlieren; die mobile Regie gruppiert ihre Kopfaktionen robuster und zeigt den Ablauf als oberstes Sheet. +- Mobile Formularfelder und die Iconsuche vermeiden iOS-Fokuszoom; Sendungskarten und Gastansicht erhalten klarere Abstände. +- Pieces führen optionalen Vorbereitungsaufwand, die Sendungsübersicht bündelt offene Vorbereitung und Abschnitte speichern kopierbare Twitch-Tags. +- Präsentationen können ein ausdrücklich gewähltes Bild ohne Begleittext ausgeben; Originale und Sendungsfassungen bleiben getrennte Snapshots. +- Lesefreigaben öffnen in Sendung, Verwaltung und Live-Regie über denselben Dialog. +- Migration `0017_maintenance_fields.sql` ergänzt ausschließlich optionale, rückwärtskompatible Felder. + ## 0.6.0 - Abschluss, Archiv und Freigaben Veröffentlicht am 25. Oktober 2026 diff --git a/docs/STATUS.md b/docs/STATUS.md index 72803f9..bd62ab1 100644 --- a/docs/STATUS.md +++ b/docs/STATUS.md @@ -7,6 +7,19 @@ Anmeldung, Rollen, persistente Inhaltsbearbeitung, Sendungsplanung, Live-Steuerung, Präsentationsausgabe, unveränderliche Sendungshistorie, Archiv und sichere Lesefreigaben sind dokumentiert. +## Wartungsrelease 0.6.1 + +- Abschnitts-Countdown, mobile Live-Kopfzeile und Ablauf-Sheet wurden korrigiert; die doppelte Piece-Positionsanzeige entfällt. +- Optionaler Vorbereitungsaufwand, kompakte Vorbereitungsliste und Abschnitts-Twitch-Tags sind additiv persistiert. +- Der Präsentationsmodus `image` gibt ausschließlich das bewusst gewählte Snapshot-Medium aus. +- Mobile Eingaben, Iconsuche, Sendungskarten und Gastabstände wurden angepasst. +- Lesefreigaben verwenden einen gemeinsamen Dialog und sind auch aus der Live-Regie erreichbar. + +Geprüft wurden 52 Verhaltenstests, Typprüfung und Produktionsbuild. Im zweiten +Chromium-Lauf waren 14 Abläufe erfolgreich; zwei Abläufe schlugen vor dem +Zeitlimit fehl, zwei weitere wurden nicht mehr ausgeführt. Die vollständige +Browsermatrix bleibt damit offen. + ## Abschluss, Archiv und Freigaben 0.6.0 - das Ende eines Live-Laufs bleibt wiederaufnehmbar; erst der getrennte, diff --git a/migrations/0017_maintenance_fields.sql b/migrations/0017_maintenance_fields.sql new file mode 100644 index 0000000..ec3b106 --- /dev/null +++ b/migrations/0017_maintenance_fields.sql @@ -0,0 +1,10 @@ +ALTER TABLE pieces ADD COLUMN preparation_effort TEXT CHECK ( + preparation_effort IS NULL OR preparation_effort IN ('low', 'medium', 'high') +); +ALTER TABLE pieces ADD COLUMN presentation_image_only INTEGER NOT NULL DEFAULT 0 + CHECK (presentation_image_only IN (0, 1)); +ALTER TABLE piece_usages ADD COLUMN presentation_image_only_snapshot INTEGER NOT NULL DEFAULT 0 + CHECK (presentation_image_only_snapshot IN (0, 1)); + +ALTER TABLE show_sections ADD COLUMN twitch_tags TEXT NOT NULL DEFAULT ''; +ALTER TABLE show_template_sections ADD COLUMN twitch_tags TEXT NOT NULL DEFAULT ''; diff --git a/package-lock.json b/package-lock.json index b6d1d29..1c0102e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "sendewerk", - "version": "0.6.0", + "version": "0.6.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "sendewerk", - "version": "0.6.0", + "version": "0.6.1", "dependencies": { "@node-rs/argon2": "^2.2.2", "better-sqlite3": "^13.0.3", diff --git a/package.json b/package.json index 9b518f3..f74a05f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "sendewerk", "private": true, - "version": "0.6.0", + "version": "0.6.1", "type": "module", "engines": { "node": ">=22.17 <25" diff --git a/src/app.css b/src/app.css index 33f06ba..126daf0 100644 --- a/src/app.css +++ b/src/app.css @@ -328,6 +328,18 @@ object-fit: contain; } +.output-image-only { + display: grid; + height: 100%; + place-items: center; +} + +.output-image-only img { + width: 100%; + height: 100%; + object-fit: contain; +} + .shared-copy, .historical-usage section, .historical-usage details { @@ -4731,6 +4743,45 @@ textarea:focus { gap: 0.5rem; } +.preparation-list { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(min(18rem, 100%), 1fr)); + gap: 0.5rem; +} + +.preparation-list a { + display: flex; + min-width: 0; + align-items: center; + justify-content: space-between; + gap: 0.75rem; + padding: 0.7rem 0.8rem; + border: 1px solid var(--line); + border-radius: var(--radius-medium); + background: var(--panel-soft); +} + +.preparation-list span { + display: grid; + min-width: 0; +} + +.preparation-list small { + overflow: hidden; + color: var(--text-muted); + font-size: 0.68rem; + text-overflow: ellipsis; + white-space: nowrap; +} + +.effort { + padding: 0.2rem 0.45rem; + border-radius: 2rem; + background: var(--panel-strong); + color: var(--text-muted); + font-size: 0.62rem; +} + .show-card { display: flex; align-items: center; @@ -6427,6 +6478,21 @@ textarea:focus { flex-direction: column; gap: 0.75rem; } + input:not([type='checkbox']):not([type='radio']):not([type='hidden']), + select, + textarea, + .icon-picker-popover input[type='search'] { + font-size: 1rem; + } + .icon-picker-popover { + display: grid; + max-height: calc(100dvh - var(--mobile-header) - var(--mobile-nav) - 1rem); + grid-template-rows: auto minmax(0, 1fr) auto; + } + .icon-picker-grid { + min-height: 0; + overflow-y: auto; + } .usage-editor-dialog { width: calc(100vw - 1rem); max-height: calc(100dvh - 1rem); @@ -7361,6 +7427,18 @@ body:has(.heinzlive-output.empty), calc(0.5rem + env(safe-area-inset-left)); width: auto; max-height: none; + display: grid; + grid-template-rows: auto minmax(0, 1fr) auto; + overflow: hidden; + } + + .icon-picker-popover input[type='search'] { + font-size: 1rem; + } + + .icon-picker-grid { + min-height: 0; + overflow-y: auto; } .piece-subsection-heading .choice-picker-popover { diff --git a/src/lib/components/PresentationDisplay.svelte b/src/lib/components/PresentationDisplay.svelte index 1a336c8..73a0554 100644 --- a/src/lib/components/PresentationDisplay.svelte +++ b/src/lib/components/PresentationDisplay.svelte @@ -60,6 +60,11 @@ {/each} {/if} +{:else if content.mode === 'image'} +
+ {#if content.topics.length}

{content.topics.join(' · ')}

{/if} + {#if imageSrc}{content.images?.[0]?.altText{/if} +
{:else if content.mode === 'link'}