Drop the Strg+V hint: PC gets drag-and-drop and file picker only

Ctrl+V does not reach the dialog either - Chrome only delivers a paste
gesture when there is a paste target, and the dialog has no input field.
So the shortcut is no longer mentioned anywhere; the computer now offers
exactly two routes, dragging and the file picker, and the phone keeps the
clipboard button. The paste listener stays as a silent bonus for browsers
that do deliver the event, and the now-orphaned tastenkuerzelEinfuegen()
is gone.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-17 00:44:05 +02:00
parent e5e82b3634
commit 91dfd4807a
5 changed files with 64 additions and 54 deletions
+8
View File
@@ -1194,6 +1194,14 @@ wraps the web app for iPhone; a PWA home-screen install is the accepted intermed
stark eingeschränkt (sonst könnte jede Seite still mitlesen, was zuletzt kopiert wurde).
Live geprüft: Desktop zeigt nur noch "Datei auswählen [primaer]"/"Abbrechen", Mobil (375px,
`pointer: coarse`) weiterhin alle drei Knöpfe.
(4) **Auch Strg+V half am Rechner nicht** - vom Nutzer getestet und zurückgemeldet ("ctrl+v
doesnt work either, pc doesnt know where to paste"). Stimmt: Chrome stellt eine Einfüge-Geste
nur zu, wenn es ein Einfüge-Ziel gibt (Eingabefeld/contenteditable), und das Fenster hat
keines. Der Hinweis ist deshalb überall entfernt; am Rechner heißt es jetzt schlicht "PDF
hierher ziehen / oder unten auswählen", am Telefon "Beleg einfügen / das aus der Mail
kopierte PDF". Der `paste`-Listener bleibt als stille Zugabe für Browser, die das Ereignis
doch zustellen, wird aber nirgends mehr beworben; `tastenkuerzelEinfuegen()` wurde damit
verwaist und ist entfernt. **Am Rechner also bewusst nur zwei Wege: Ziehen und Dateiauswahl.**
- [x] Preis je Liter überall auf 2 Nachkommastellen (2026-08-17, Nutzerwunsch: "€/l for gas is
common to be displayed as x,xx €/l") — alle sieben Stellen von `de(..., 3)` auf `de(..., 2)`
umgestellt: Jahres- und Monatsschnitt in der Tankliste, Zeilenwert je Tankvorgang, "Preis je
@@ -3046,22 +3046,15 @@ function belegPopupSchliessenUndLaden(datei) {
}
/* Telefon-Weg: das aus der Mail kopierte PDF liegt in der Zwischenablage.
navigator.clipboard.read() ist der einzige Weg, ohne dass der Nutzer in ein
Eingabefeld tippen muss - iOS zeigt dafür seine eigene Einfügen-Abfrage.
WICHTIG (Ursache eines gemeldeten Fehlers): Am Rechner hilft dieser Knopf
bei einer im Explorer/Finder kopierten Datei NICHT. clipboard.read() gibt
laut Spezifikation nur Text, HTML und Bilder heraus - eine kopierte
PDF-Datei taucht dort gar nicht auf, egal wie frisch sie ist. Der Weg, der
dort funktioniert, ist Strg+V: das paste-Ereignis trägt die echte Datei in
clipboardData.files. Deshalb sagt die Meldung unten genau das, statt
pauschal "kein PDF" zu behaupten. */
navigator.clipboard.read() ist dort der einzige Weg, ohne dass der Nutzer
in ein Eingabefeld tippen muss - iOS zeigt dafür seine eigene
Einfügen-Abfrage. Der Knopf erscheint deshalb nur auf Tippgeräten, siehe
zwischenablageKnopfSinnvoll(). */
async function belegAusZwischenablage() {
const ctx = belegPopup;
if (!ctx) return;
const strgVHinweis = `Am Rechner kann der Browser eine kopierte Datei nur über ${tastenkuerzelEinfuegen()} entgegennehmen - bitte so einfügen oder das PDF hineinziehen.`;
if (!navigator.clipboard || !navigator.clipboard.read) {
belegPopup.fehler = strgVHinweis;
belegPopup.fehler = "Dieser Browser gibt die Zwischenablage nicht heraus - bitte \"Datei auswählen\".";
render(); return;
}
try {
@@ -3069,37 +3062,41 @@ async function belegAusZwischenablage() {
const typ = (eintrag.types || []).find((t) => t === "application/pdf");
if (typ) { belegPopupSchliessenUndLaden(new File([await eintrag.getType(typ)], "beleg.pdf", { type: "application/pdf" })); return; }
}
belegPopup.fehler = strgVHinweis;
belegPopup.fehler = "In der Zwischenablage liegt kein PDF - bitte den Beleg erneut kopieren oder \"Datei auswählen\".";
} catch (err) {
belegPopup.fehler = "Kein Zugriff auf die Zwischenablage. " + strgVHinweis;
belegPopup.fehler = "Kein Zugriff auf die Zwischenablage - bitte \"Datei auswählen\".";
}
render();
}
function tastenkuerzelEinfuegen() {
return /Mac|iPhone|iPad/.test(navigator.platform || navigator.userAgent) ? "Cmd+V" : "Strg+V";
}
/* Der Einfügen-Knopf wird nur auf Tippgeräten angeboten. Am Rechner kann er
aus Datenschutzgründen prinzipiell nicht funktionieren (clipboard.read()
gibt Dateien nie heraus, siehe oben) - ein Knopf, der dort zwangsläufig
scheitert, führt nur in eine Sackgasse. Dort bleiben Ziehen und Strg+V. */
/* Der Einfügen-Knopf wird nur auf Tippgeräten angeboten. Am Rechner scheitert
er zwangsläufig: clipboard.read() gibt aus Datenschutzgründen nur Text,
HTML und Bilder heraus, eine im Explorer kopierte Datei taucht dort nie
auf. Und das Tastenkürzel Strg+V hilft dort ebenfalls nicht - ohne
Eingabefeld im Fenster hat der Browser kein Ziel für die Einfüge-Geste
(vom Nutzer bestätigt). Am Rechner bleiben daher Ziehen und Dateiauswahl. */
function zwischenablageKnopfSinnvoll() {
return window.matchMedia && window.matchMedia("(pointer: coarse)").matches;
}
function vBelegPopup() {
if (!belegPopup) return "";
// Am Telefon ist Einfügen der Hauptweg (PDF aus der Mail kopiert), am
// Rechner Ziehen bzw. Dateiauswahl. Strg+V wird am Rechner bewusst NICHT
// mehr angeboten: ohne Eingabefeld im Fenster hat der Browser kein Ziel für
// die Einfüge-Geste, das Tastenkürzel läuft dort also ins Leere.
const telefon = zwischenablageKnopfSinnvoll();
return `<div class="beleg-catcher" data-belegzu></div>
<div class="beleg-popup" role="dialog" aria-modal="true" aria-label="Beleg hochladen">
<span class="label">Beleg hochladen</span>
<div class="beleg-drop" id="belegDrop">
<strong>PDF hierher ziehen</strong>
<span>oder mit ${tastenkuerzelEinfuegen()} einfügen</span>
${telefon
? `<strong>Beleg einfügen</strong><span>das aus der Mail kopierte PDF</span>`
: `<strong>PDF hierher ziehen</strong><span>oder unten auswählen</span>`}
</div>
${belegPopup.fehler ? `<span class="label" style="margin-top:10px;color:var(--red)">${esc(belegPopup.fehler)}</span>` : ""}
${zwischenablageKnopfSinnvoll() ? `<button class="aktion primaer" data-belegeinfuegen>Aus Zwischenablage einfügen</button>` : ""}
<button class="aktion ${zwischenablageKnopfSinnvoll() ? "" : "primaer"}" data-belegdatei>Datei auswählen</button>
${telefon ? `<button class="aktion primaer" data-belegeinfuegen>Aus Zwischenablage einfügen</button>` : ""}
<button class="aktion ${telefon ? "" : "primaer"}" data-belegdatei>Datei auswählen</button>
<button class="aktion" data-belegzu>Abbrechen</button>
</div>`;
}
@@ -3407,6 +3404,10 @@ function ereignisseVerdrahten() {
belegPopup.fehler = "Das war kein PDF.";
render();
});
/* Zugabe, kein beworbener Weg: wo der Browser eine Einfüge-Geste ohne
Eingabefeld überhaupt zustellt, wird sie mitgenommen. Am Rechner tut
Chrome das nicht (deshalb steht Strg+V nirgends mehr als Hinweis), es
kostet aber nichts, das Ereignis trotzdem anzunehmen. */
document.addEventListener("paste", (e) => {
if (!belegPopup) return;
const datei = belegAusDateiliste(e.clipboardData && e.clipboardData.files);
@@ -1 +1 @@
{"version": 1786919856}
{"version": 1786920185}
+27 -26
View File
@@ -3046,22 +3046,15 @@ function belegPopupSchliessenUndLaden(datei) {
}
/* Telefon-Weg: das aus der Mail kopierte PDF liegt in der Zwischenablage.
navigator.clipboard.read() ist der einzige Weg, ohne dass der Nutzer in ein
Eingabefeld tippen muss - iOS zeigt dafür seine eigene Einfügen-Abfrage.
WICHTIG (Ursache eines gemeldeten Fehlers): Am Rechner hilft dieser Knopf
bei einer im Explorer/Finder kopierten Datei NICHT. clipboard.read() gibt
laut Spezifikation nur Text, HTML und Bilder heraus - eine kopierte
PDF-Datei taucht dort gar nicht auf, egal wie frisch sie ist. Der Weg, der
dort funktioniert, ist Strg+V: das paste-Ereignis trägt die echte Datei in
clipboardData.files. Deshalb sagt die Meldung unten genau das, statt
pauschal "kein PDF" zu behaupten. */
navigator.clipboard.read() ist dort der einzige Weg, ohne dass der Nutzer
in ein Eingabefeld tippen muss - iOS zeigt dafür seine eigene
Einfügen-Abfrage. Der Knopf erscheint deshalb nur auf Tippgeräten, siehe
zwischenablageKnopfSinnvoll(). */
async function belegAusZwischenablage() {
const ctx = belegPopup;
if (!ctx) return;
const strgVHinweis = `Am Rechner kann der Browser eine kopierte Datei nur über ${tastenkuerzelEinfuegen()} entgegennehmen - bitte so einfügen oder das PDF hineinziehen.`;
if (!navigator.clipboard || !navigator.clipboard.read) {
belegPopup.fehler = strgVHinweis;
belegPopup.fehler = "Dieser Browser gibt die Zwischenablage nicht heraus - bitte \"Datei auswählen\".";
render(); return;
}
try {
@@ -3069,37 +3062,41 @@ async function belegAusZwischenablage() {
const typ = (eintrag.types || []).find((t) => t === "application/pdf");
if (typ) { belegPopupSchliessenUndLaden(new File([await eintrag.getType(typ)], "beleg.pdf", { type: "application/pdf" })); return; }
}
belegPopup.fehler = strgVHinweis;
belegPopup.fehler = "In der Zwischenablage liegt kein PDF - bitte den Beleg erneut kopieren oder \"Datei auswählen\".";
} catch (err) {
belegPopup.fehler = "Kein Zugriff auf die Zwischenablage. " + strgVHinweis;
belegPopup.fehler = "Kein Zugriff auf die Zwischenablage - bitte \"Datei auswählen\".";
}
render();
}
function tastenkuerzelEinfuegen() {
return /Mac|iPhone|iPad/.test(navigator.platform || navigator.userAgent) ? "Cmd+V" : "Strg+V";
}
/* Der Einfügen-Knopf wird nur auf Tippgeräten angeboten. Am Rechner kann er
aus Datenschutzgründen prinzipiell nicht funktionieren (clipboard.read()
gibt Dateien nie heraus, siehe oben) - ein Knopf, der dort zwangsläufig
scheitert, führt nur in eine Sackgasse. Dort bleiben Ziehen und Strg+V. */
/* Der Einfügen-Knopf wird nur auf Tippgeräten angeboten. Am Rechner scheitert
er zwangsläufig: clipboard.read() gibt aus Datenschutzgründen nur Text,
HTML und Bilder heraus, eine im Explorer kopierte Datei taucht dort nie
auf. Und das Tastenkürzel Strg+V hilft dort ebenfalls nicht - ohne
Eingabefeld im Fenster hat der Browser kein Ziel für die Einfüge-Geste
(vom Nutzer bestätigt). Am Rechner bleiben daher Ziehen und Dateiauswahl. */
function zwischenablageKnopfSinnvoll() {
return window.matchMedia && window.matchMedia("(pointer: coarse)").matches;
}
function vBelegPopup() {
if (!belegPopup) return "";
// Am Telefon ist Einfügen der Hauptweg (PDF aus der Mail kopiert), am
// Rechner Ziehen bzw. Dateiauswahl. Strg+V wird am Rechner bewusst NICHT
// mehr angeboten: ohne Eingabefeld im Fenster hat der Browser kein Ziel für
// die Einfüge-Geste, das Tastenkürzel läuft dort also ins Leere.
const telefon = zwischenablageKnopfSinnvoll();
return `<div class="beleg-catcher" data-belegzu></div>
<div class="beleg-popup" role="dialog" aria-modal="true" aria-label="Beleg hochladen">
<span class="label">Beleg hochladen</span>
<div class="beleg-drop" id="belegDrop">
<strong>PDF hierher ziehen</strong>
<span>oder mit ${tastenkuerzelEinfuegen()} einfügen</span>
${telefon
? `<strong>Beleg einfügen</strong><span>das aus der Mail kopierte PDF</span>`
: `<strong>PDF hierher ziehen</strong><span>oder unten auswählen</span>`}
</div>
${belegPopup.fehler ? `<span class="label" style="margin-top:10px;color:var(--red)">${esc(belegPopup.fehler)}</span>` : ""}
${zwischenablageKnopfSinnvoll() ? `<button class="aktion primaer" data-belegeinfuegen>Aus Zwischenablage einfügen</button>` : ""}
<button class="aktion ${zwischenablageKnopfSinnvoll() ? "" : "primaer"}" data-belegdatei>Datei auswählen</button>
${telefon ? `<button class="aktion primaer" data-belegeinfuegen>Aus Zwischenablage einfügen</button>` : ""}
<button class="aktion ${telefon ? "" : "primaer"}" data-belegdatei>Datei auswählen</button>
<button class="aktion" data-belegzu>Abbrechen</button>
</div>`;
}
@@ -3407,6 +3404,10 @@ function ereignisseVerdrahten() {
belegPopup.fehler = "Das war kein PDF.";
render();
});
/* Zugabe, kein beworbener Weg: wo der Browser eine Einfüge-Geste ohne
Eingabefeld überhaupt zustellt, wird sie mitgenommen. Am Rechner tut
Chrome das nicht (deshalb steht Strg+V nirgends mehr als Hinweis), es
kostet aber nichts, das Ereignis trotzdem anzunehmen. */
document.addEventListener("paste", (e) => {
if (!belegPopup) return;
const datei = belegAusDateiliste(e.clipboardData && e.clipboardData.files);
@@ -1 +1 @@
{"version": 1786919856}
{"version": 1786920185}