From 5b2930b844450814eb4d5a496c01ab895bf4d769 Mon Sep 17 00:00:00 2001 From: Dotty Dotter Date: Thu, 7 May 2026 13:11:48 +0200 Subject: [PATCH] fix: Scorecard-Whitespace + Instagram-Button ehrlicher MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Whitespace-Problem (User: 'Da ist immer noch viel Rand'): Inspektion am gerenderten PNG zeigte: massive Slack-Zone unten zwischen Summary-Text und Footer. Ursache: portrait-body hatte flex:1 ohne justify-content, alle Items stapelten sich am oberen Rand und der Bottom war leer. Plus: Summary war auf 360 Zeichen + line-clamp:6 beschraenkt — Text wurde regelmaessig vor Ende abgeschnitten und fuellte selbst die wenigen Zeilen nicht voll. Fix: - portrait-body bekommt justify-content: space-between und padding-bottom: 26px - Summary truncate 360 → 700, line-clamp 6 → 9 - gap 16 → 14, margin-top 16 → 14 Effekt: Slack wird zwischen Sektionen gleichverteilt UND der Begruendungs- text fuellt jetzt seinen Bereich, sodass kaum noch Slack uebrig ist. Instagram-Button (User: 'funktioniert weiter nicht'): Realitaet ist: Instagram hat keine Web-Publishing-API. Auf Desktop ist 'Direkt-Posten' physikalisch nicht moeglich. Vorher: Fallback oeffnete das Bild im neuen Tab — fuehlte sich nicht wie 'Sharing' an. Jetzt zwei klar getrennte Pfade: A) Mobile mit Web-Share-Files: navigator.share({files:[png]}) oeffnet OS-Share-Sheet, Instagram als Ziel; AbortError (User-Cancel) wird STILL gehandelt (vorher fiel das in den Fallback). B) Desktop / unsupported: PNG-Download via getriggert, Begleittext geht in die Zwischenablage. Toast erklaert klar: 'Bild aufs Phone uebertragen, in der Instagram-App posten, Text einfuegen.' — keine falsche Erwartung mehr, dass Web allein das Posten erledigt. Co-Authored-By: Claude Opus 4.7 (1M context) --- app/templates/v2/screens/antrag_detail.html | 69 +++++++++++++-------- app/templates/v2/screens/scorecard.html | 14 +++-- 2 files changed, 52 insertions(+), 31 deletions(-) diff --git a/app/templates/v2/screens/antrag_detail.html b/app/templates/v2/screens/antrag_detail.html index 961111f..c136ef9 100644 --- a/app/templates/v2/screens/antrag_detail.html +++ b/app/templates/v2/screens/antrag_detail.html @@ -942,44 +942,61 @@ window.v2ShowMatrixFieldInfo = function(field) { window.open(url, '_blank', 'noopener'); }; - /* Instagram-Sharing: bevorzugt Web-Share-API mit Datei-Blob — auf - Mobile-Browsern (Safari iOS, Chrome Android) oeffnet das den nativen - Share-Sheet, in dem Instagram als Ziel auftaucht und den User direkt - in die Instagram-App pusht. Auf Desktop (kein File-Sharing) oder - unsupported Browsern: PNG im neuen Tab + Text in Zwischenablage. */ + /* Instagram-Sharing — Realismus: + Instagram hat KEINE Web-Publishing-API. Wir koennen also nicht + direkt posten. Realistisch sind zwei Pfade: + + A) Mobile (iOS Safari / Chrome Android) mit Web-Share-Files-Support: + navigator.share({files:[png]}) oeffnet den OS-Share-Sheet, + Instagram-App taucht dort als Ziel auf, der Bild-Blob wird + an die App uebergeben. Funktioniert NICHT auf Firefox Mobile + und unzuverlaessig je nach Android-Build. + + B) Desktop oder unsupported Browser: + - Bild via herunterladen (User hat das PNG dann lokal) + - Begleittext in die Zwischenablage + - Klare Anweisung: Bild auf's Phone uebertragen, in Instagram + posten, Text mit Strg/⌘-V einfuegen. + Es gibt keinen ehrlicheren Weg auf Desktop. */ window.v2DetailShareInstagram = async function() { var url = '/api/assessment/scorecard.png?drucksache=' + encodeURIComponent(DRS) + '&bundesland=' + encodeURIComponent(BL || 'NRW') + '&format=portrait&scale=2'; var body = buildLongShareText(); + var safeDrs = (DRS || 'antrag').replace(/[^a-zA-Z0-9_-]/g, '-'); + var filename = 'gwoe-' + safeDrs + '.png'; - // Native Web-Share-API mit Datei probieren (nur Mobile-Browser - // koennen files: mit canShare positiv beantworten). - try { - var resp = await fetch(url); - if (resp.ok) { - var blob = await resp.blob(); - var safeDrs = (DRS || 'antrag').replace(/[^a-zA-Z0-9_-]/g, '-'); - var file = new File([blob], 'gwoe-' + safeDrs + '.png', { type: 'image/png' }); - var data = { title: TITLE, text: body, files: [file] }; - if (navigator.canShare && navigator.canShare(data) && navigator.share) { - await navigator.share(data); - v2ShareToast('Share-Dialog geöffnet — Instagram als Ziel auswählen.'); - return; + // Pfad A — Web-Share mit Datei (nur Mobile) + if (navigator.canShare && navigator.share) { + try { + var resp = await fetch(url); + if (resp.ok) { + var blob = await resp.blob(); + var file = new File([blob], filename, { type: 'image/png' }); + var data = { title: TITLE, text: body, files: [file] }; + if (navigator.canShare(data)) { + await navigator.share(data); + return; // Erfolg — kein Toast, OS-Sheet hat eigenes Feedback + } } + } catch (e) { + if (e && e.name === 'AbortError') return; // User abgebrochen + // sonst weiter zu Pfad B } - } catch (_) { - // Cancel oder Fehler — fallthrough zum Fallback } - // Fallback Desktop / unsupported: PNG in neuem Tab + Text kopieren - var win = window.open(url, '_blank', 'noopener'); + // Pfad B — Desktop: Download + Clipboard if (navigator.clipboard && navigator.clipboard.writeText) { - navigator.clipboard.writeText(body).then(function() { - v2ShareToast('Bild öffnet — speichern und in Instagram posten. Text liegt in der Zwischenablage.'); - }); + try { await navigator.clipboard.writeText(body); } catch (_) { /* OK */ } } - if (!win) v2ShareToast('Bitte Pop-up-Blocker prüfen.'); + var a = document.createElement('a'); + a.href = url; + a.download = filename; + a.style.display = 'none'; + document.body.appendChild(a); + a.click(); + setTimeout(function() { document.body.removeChild(a); }, 100); + v2ShareToast('Bild heruntergeladen, Begleittext in der Zwischenablage. Bild auf\'s Phone übertragen, in der Instagram-App posten, Text einfügen.'); }; window.v2DetailShareImage = function() { diff --git a/app/templates/v2/screens/scorecard.html b/app/templates/v2/screens/scorecard.html index 8fbbd92..1a32862 100644 --- a/app/templates/v2/screens/scorecard.html +++ b/app/templates/v2/screens/scorecard.html @@ -150,13 +150,17 @@ aspect-ratio: 1 / 1; } - /* ── portrait Layout — kompakt, weniger Rand ── */ + /* ── portrait Layout — kompakt, weniger Rand. + justify-content: space-between verteilt etwaige Slack-Hoehe + gleichmaessig zwischen die Sektionen statt unten zu stapeln. */ .portrait-body { flex: 1; display: flex; flex-direction: column; - gap: 16px; - margin-top: 16px; + justify-content: space-between; + gap: 14px; + margin-top: 14px; + padding-bottom: 26px; } .portrait-title { font-size: 36pt; @@ -263,7 +267,7 @@ line-height: 1.5; color: #333; display: -webkit-box; - -webkit-line-clamp: 6; + -webkit-line-clamp: 9; -webkit-box-orient: vertical; overflow: hidden; } @@ -330,7 +334,7 @@ -
{{ assessment.gwoe_begruendung|truncate(360, end="…") }}
+
{{ assessment.gwoe_begruendung|truncate(700, end="…") }}
{% else %}