diff --git a/CloudronManifest.json b/CloudronManifest.json index 7451db5..f9b8ac6 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.7.0", + "version": "0.7.1", "healthCheckPath": "/healthz", "httpPort": 3000, "addons": { diff --git a/docs/ACCEPTANCE.md b/docs/ACCEPTANCE.md index c8ad78c..efc48c7 100644 --- a/docs/ACCEPTANCE.md +++ b/docs/ACCEPTANCE.md @@ -1,5 +1,25 @@ # Abnahme +## Wartungsrelease 0.7.1 + +| Bereich | Nachweis | Stand | +| ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- | +| Abschnittsdauer und Rückkehr zu früheren Pieces (#1) | Live-Verhaltenstests für geänderte Plandauer, Wiederaufnahme, Abschnittslaufzeit und Gesamtzeit; Chromium-Ablauf | erfüllt am 25.10.2026 | +| Mobiler Live-Ablauf und Metadaten (#3, #13) | kleine Live-Regie bei 390 x 700 ohne horizontalen Überlauf; Sheet, Fokus und Viewportgrenzen im Chromium-Ablauf | Chromium erfüllt; Safari und installierte iOS-Webapp offen | +| Mobile Sendungskarten (#5) | responsive Karten im vollständigen Chromium-Lauf bei 390 Pixeln geöffnet | erfüllt am 25.10.2026 | +| Vorbereitung nach Einplanung (#6, #15) | Servertest schließt ungeplante Pieces aus und liefert konkrete Usage-Snapshots priorisiert mit Themenicons | erfüllt am 25.10.2026 | +| Kontextabhängige Präsentation (#8) | Fundus- und Usage-Editor im Chromium-Lauf; Text-, Bild-, Link- und Videozustände durch bestehende Verhaltenstests gedeckt | erfüllt am 25.10.2026 | +| Gastansicht und Freigaben (#11, #12) | Gastansicht mobil/desktop, erneut geöffnete Dialogergebnisse und Tokenersatz mit Invalidierungstest | erfüllt am 25.10.2026 | +| Iconsuche (#14) | Chromium prüft sichtbares und unmittelbar fokussiertes Suchfeld bei 390, 960 und 1280 Pixeln | erfüllt am 25.10.2026 | + +- `npm test`: 60 von 60 Verhaltenstests erfolgreich. +- `npm run lint`: erfolgreich. +- `npm run check`: 0 Fehler und 0 Warnungen. +- `npm run build`: erfolgreich mit `@sveltejs/adapter-node`. +- `npm run test:e2e`: 18 von 18 Chromium-Abläufen erfolgreich. +- Safari auf echtem iOS-Gerät: offen. +- Installierte Webapp auf echtem iOS-Gerät: separat offen. + ## Etappe 7 | Kriterium | Nachweis | Stand | diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index fd657c1..876c947 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -450,3 +450,17 @@ 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. + +## Wartungskorrekturen 0.7.1 + +Die Vorbereitungsliste projiziert bestehende Daten statt einen zweiten +Vorbereitungszustand einzuführen: Sie verbindet aktive Sendungen mit ihren +Usage-Snapshots und berücksichtigt nur Originale im Zustand `preparing`. +Dadurch erscheinen Mehrfachplanungen als getrennte Sendungsfassungen, während +ungeplante Fundus-Pieces ausgeschlossen bleiben. Der Link adressiert die Usage +direkt; Titel und Themenicons stammen aus dem stabilen Snapshot. + +Ein Freigabe-Ersatzlink rotiert ausschließlich den gehashten Token derselben +Freigabe. Umfang, Passwort-Hash und Ablauf bleiben erhalten, der alte Token und +alle bisherigen Gastsitzungen werden in derselben Transaktion ungültig. Der neue +Klartexttoken wird weiterhin nur in der Action-Antwort ausgegeben. diff --git a/docs/DECISIONS.md b/docs/DECISIONS.md index acbc832..25e71e2 100644 --- a/docs/DECISIONS.md +++ b/docs/DECISIONS.md @@ -492,3 +492,15 @@ abgewiesen. OpenAPI 3.1 beschreibt diese Grenze maschinenlesbar. Ein MCP-Adapter oder ein bestimmter KI-Client wird nicht vorgetäuscht: Die Anwendung bleibt ohne KI vollständig nutzbar und eine konkrete Client-Verbindung muss separat geprüft werden. + +## D-031: Usage-basierte Vorbereitung und rotierende Freigabelinks + +Die Sendungsübersicht erzeugt keinen zusätzlichen Vorbereitungszustand. Sie +projiziert konkrete Usage-Snapshots aktiver Sendungen, deren Fundus-Original noch +`preparing` ist. So bleiben bestehende Daten und Snapshots unverändert, während +ungeplante Fundus-Arbeit aus der Sendungsübersicht verschwindet. + +Weil Freigabetokens nur gehasht gespeichert werden, kann ein bestehender Link +nicht erneut angezeigt werden. Ein Ersatzlink rotiert deshalb den Token derselben +Freigabe transaktional und löscht alle Gastsitzungen; Sichtumfang, Passwort und +Ablauf werden nicht stillschweigend verändert. diff --git a/docs/RELEASE_NOTES.md b/docs/RELEASE_NOTES.md index ff6201b..2e34696 100644 --- a/docs/RELEASE_NOTES.md +++ b/docs/RELEASE_NOTES.md @@ -1,5 +1,29 @@ # Release Notes +## 0.7.1 - Bedienung und Live-Korrekturen + +Veröffentlicht am 25. Oktober 2026 + +- Live-Abschnittszeiten übernehmen geänderte Plandauern. Frühere erledigte oder + übersprungene Pieces können offiziell wiederaufgenommen werden, ohne ihre + Abschnittslaufzeit oder die Gesamtzeit zurückzusetzen (#1). +- Mobiler Live-Ablauf, lange Metadaten und Sendungskarten halten ihre verfügbare + Breite ein. Der Ablauf bleibt als fokussierbares Sheet bedienbar (#3, #5, #13). +- „Noch vorzubereiten“ zeigt nur tatsächlich eingeplante unfertige Fassungen + aktiver Sendungen, priorisiert sie und verlinkt sie mit ihren Themenicons direkt + in den Usage-Editor (#6, #15). +- Fundus- und Usage-Editor unterscheiden Text, Nur Bild, Linkvorschau und Video + durch kontextsensitive Eingaben und passende Vorschauen (#8). +- Gastabschnitte verzichten auf unnötige äußere Karten. Freigabedialoge zeigen + den einmaligen Link nach dem Anlegen sofort wieder an, bieten Kopieren und + können einen alten Token sicher durch einen neuen ersetzen (#11, #12). +- Die Iconsuche ist nach dem Öffnen sofort sichtbar und fokussiert (#14). +- RSS-Feeds und technische Zugänge verwenden in der Verwaltung kompakte + Hinzufügen-Einstiege und dieselbe visuelle Listenlogik wie der Werkzeugkatalog. +- Paket, Lockdatei und Cloudron-Manifest tragen Version `0.7.1`. Es gibt keine + neue Datenbankmigration. 60 Verhaltenstests und 18 Chromium-Abläufe sind + erfolgreich; echtes Safari und die installierte Webapp auf iOS bleiben offen. + ## 0.7.0 - RSS-Import und externe Assistenz Veröffentlicht am 25. Oktober 2026 diff --git a/docs/STATUS.md b/docs/STATUS.md index f245360..1619827 100644 --- a/docs/STATUS.md +++ b/docs/STATUS.md @@ -8,6 +8,33 @@ Live-Steuerung, Präsentationsausgabe, unveränderliche Sendungshistorie, Archiv, sichere Lesefreigaben, RSS-Import und technische REST-Zugänge sind dokumentiert. +## Fehlerkorrekturen 0.7.1 + +- Explizite Abschnittsdauern werden während der Live-Regie nach Änderungen + synchronisiert. Erledigte oder übersprungene Pieces lassen sich bewusst + wiederaufnehmen; frühere Abschnitts- und Gesamtzeiten bleiben dabei erhalten. +- Der mobile Ablauf liegt innerhalb eines isolierten Live-Containers, und lange + Metadaten verbreitern die Regie nicht mehr. Sendungskarten stapeln ihre Inhalte + auf kleinen Bildschirmen eindeutig. +- Die Vorbereitung zeigt nur konkrete Einplanungen aktiver Sendungen, deren + Fundus-Original noch in Vorbereitung ist. Usage-Titel, Sendung, Abschnitt, + Priorität und gespeicherte Themenicons führen direkt zur Sendungsfassung. +- Text, Nur Bild, Linkvorschau und Video besitzen in Fundus- und Usage-Editor + kontextsensitive Felder und Vorschauen. Ausgeblendete Werte bleiben beim + Moduswechsel erhalten. +- Die Iconsuche fokussiert beim Öffnen sofort das Suchfeld. RSS-Feeds und + technische Zugänge folgen in der Verwaltung dem kompakten Katalogmuster. +- Lesefreigaben öffnen nach Serverantworten wieder mit dem einmalig sichtbaren + Link, bieten Kopieren und sichere Ersatzlinks. Ersatzlinks invalidieren den + alten Token und dessen Gastsitzungen. Die Gastansicht trennt Abschnitte ohne + zusätzliche äußere Karten. + +Geprüft wurden 60 von 60 Verhaltenstests, Lint, Typprüfung, Produktionsbuild und +18 von 18 Chromium-Abläufe. Die Browsermatrix öffnete beide Piece-Editoren, +Sendungsübersicht, Verwaltung und Freigabedialoge, Gastansicht sowie Live-Regie +bei Desktop- und Mobilbreiten. Safari und die installierte Webapp auf einem +echten iOS-Gerät bleiben mangels Gerät getrennt offen. + ## RSS-Import und externe Assistenz 0.7.0 - Barkeeper verwalten RSS-/Atom-Feeds mit Standardkategorie, Aktivierung und diff --git a/package-lock.json b/package-lock.json index 39a0a77..ddf9a4e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "sendewerk", - "version": "0.7.0", + "version": "0.7.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "sendewerk", - "version": "0.7.0", + "version": "0.7.1", "dependencies": { "@node-rs/argon2": "^2.2.2", "better-sqlite3": "^13.0.3", diff --git a/package.json b/package.json index 20016cd..bb4c8c9 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "sendewerk", "private": true, - "version": "0.7.0", + "version": "0.7.1", "type": "module", "engines": { "node": ">=22.17 <25" diff --git a/src/app.css b/src/app.css index 126daf0..b35eb44 100644 --- a/src/app.css +++ b/src/app.css @@ -262,6 +262,13 @@ overflow-wrap: anywhere; } +.share-result > div { + display: flex; + align-items: center; + justify-content: space-between; + gap: 0.75rem; +} + .guest-shell { min-height: 100dvh; } @@ -294,6 +301,11 @@ margin-top: 1.25rem; } +.shared-section { + padding: 0 0 1.25rem; + border-bottom: 1px solid var(--line); +} + .shared-section > header, .historical-section > header, .shared-usage-heading, @@ -1325,6 +1337,8 @@ textarea:focus { .live-page { display: grid; + position: relative; + isolation: isolate; width: 100%; height: 100dvh; grid-template-rows: auto auto minmax(0, 1fr) auto; @@ -1796,7 +1810,7 @@ textarea:focus { .live-piece-heading { display: grid; - grid-template-columns: auto minmax(0, 1fr) auto; + grid-template-columns: minmax(0, 1fr) auto; align-items: baseline; gap: 0.35rem 0.65rem; padding-bottom: 0.5rem; @@ -1819,6 +1833,7 @@ textarea:focus { } .live-current h1 { + min-width: 0; max-width: none; margin: 0; font-size: clamp(1.2rem, 2.2vw, 1.9rem); @@ -2390,11 +2405,11 @@ textarea:focus { .live-page.without-rail .live-rail, .live-rail { display: grid; - position: fixed; + position: absolute; z-index: 80; inset: max(0.4rem, env(safe-area-inset-top)) max(0.4rem, env(safe-area-inset-right)) max(0.4rem, env(safe-area-inset-bottom)) auto; - width: min(22rem, calc(100vw - 0.8rem - env(safe-area-inset-left))); + width: min(22rem, calc(100% - 0.8rem - env(safe-area-inset-left))); transform: translateX(calc(100% + 1rem)); visibility: hidden; transition: @@ -2414,7 +2429,7 @@ textarea:focus { .live-rail-backdrop.visible { display: block; - position: fixed; + position: absolute; z-index: 70; inset: 0; border: 0; @@ -2431,9 +2446,16 @@ textarea:focus { } .live-piece-heading { + min-width: 0; gap: 0.3rem 0.45rem; } + .live-piece-time { + max-width: 8rem; + overflow: hidden; + text-overflow: ellipsis; + } + .live-support-actions { display: grid; } @@ -4761,11 +4783,24 @@ textarea:focus { background: var(--panel-soft); } -.preparation-list span { +.preparation-copy, +.preparation-copy > span:last-child { display: grid; min-width: 0; } +.preparation-copy { + grid-template-columns: auto minmax(0, 1fr); + align-items: center; + gap: 0.6rem; +} + +.preparation-topics { + display: flex; + gap: 0.2rem; + color: var(--accent-text); +} + .preparation-list small { overflow: hidden; color: var(--text-muted); @@ -6742,6 +6777,10 @@ textarea:focus { .show-card-facts { align-items: flex-start; } + .show-card { + flex-direction: column; + align-items: stretch; + } .show-card-facts { flex-direction: row; align-items: center; diff --git a/src/lib/components/IconPicker.svelte b/src/lib/components/IconPicker.svelte index 8cd7832..9ff260b 100644 --- a/src/lib/components/IconPicker.svelte +++ b/src/lib/components/IconPicker.svelte @@ -6,6 +6,7 @@ $props(); let query = $state(''); let menu: HTMLDetailsElement; + let searchInput: HTMLInputElement; let filtered = $derived( classicRegularIcons.filter((icon) => `${icon.name} ${icon.label} ${icon.terms.join(' ')}` @@ -18,7 +19,12 @@