fix: Scorecard-Whitespace + Instagram-Button ehrlicher

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 <a download> 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) <noreply@anthropic.com>
This commit is contained in:
Dotty Dotter 2026-05-07 13:11:48 +02:00
parent 0e5b2180ab
commit 5b2930b844
2 changed files with 52 additions and 31 deletions

View File

@ -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 <a download> 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).
// 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 safeDrs = (DRS || 'antrag').replace(/[^a-zA-Z0-9_-]/g, '-');
var file = new File([blob], 'gwoe-' + safeDrs + '.png', { type: 'image/png' });
var file = new File([blob], filename, { type: 'image/png' });
var data = { title: TITLE, text: body, files: [file] };
if (navigator.canShare && navigator.canShare(data) && navigator.share) {
if (navigator.canShare(data)) {
await navigator.share(data);
v2ShareToast('Share-Dialog geöffnet — Instagram als Ziel auswählen.');
return;
return; // Erfolg — kein Toast, OS-Sheet hat eigenes Feedback
}
}
} catch (_) {
// Cancel oder Fehler — fallthrough zum Fallback
} catch (e) {
if (e && e.name === 'AbortError') return; // User abgebrochen
// sonst weiter zu Pfad B
}
}
// 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() {

View File

@ -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 @@
</ul>
</div>
</div>
<div class="portrait-summary">{{ assessment.gwoe_begruendung|truncate(360, end="…") }}</div>
<div class="portrait-summary">{{ assessment.gwoe_begruendung|truncate(700, end="…") }}</div>
</div>
{% else %}
<div class="body-grid">