Files
xmrpay.link/i18n.min.js
Alexander Schmidt 8bcdb33fa3 feat: UI polish, a11y, performance optimizations
- Payment summary card with prominent amount display
- "Bezahlt" stamp over dimmed QR code with TX details below
- Hide wallet/address buttons when paid, show only PDF
- URI box removed (was technical noise)
- Smart countdown: "29 Tage, 23 Std." instead of ticking seconds
- Dynamic page title for shared invoices
- Font fallbacks with size-adjust to prevent layout shifts
- Async Google Fonts loading, proper preconnect hints
- Deferred script loading (defer attribute)
- Minified JS (app.min.js, i18n.min.js)
- WCAG contrast fixes for badges and disabled button
- Footer link always underlined for a11y
- Translated aria-labels via data-i18n-aria
- i18n onChange callback for dynamic content updates
- Result card fade-in animation, responsive QR on mobile
2026-03-25 16:50:55 +01:00

2 lines
5.6 KiB
JavaScript

var I18n=(function(){"use strict";var d={de:{name:"Deutsch",flag:"DE"},en:{name:"English",flag:"EN"}},i={de:{subtitle:"Monero-Zahlungsanforderung in Sekunden",label_addr:"XMR-Adresse",placeholder_addr:"4...",label_amount:"Betrag",label_desc:"Beschreibung (optional)",placeholder_desc:"z.B. Rechnung #42, Freelance-Arbeit...",label_timer:"Zahlungsfrist (optional)",days:"Tage",placeholder_timer_custom:"Tage",btn_generate:"Zahlungsanforderung erstellen",btn_open_wallet:"In Wallet \xF6ffnen",btn_copy_addr:"Adresse kopieren",btn_download_pdf:"PDF Rechnung",pdf_title:"Zahlungsanforderung",pdf_address:"XMR-Adresse",pdf_amount:"Betrag",pdf_desc:"Beschreibung",pdf_deadline:"Zahlungsfrist",pdf_deadline_days:"{d} Tage",pdf_date:"Datum",pdf_scan_qr:"QR-Code scannen zum Bezahlen",pdf_footer:"Erstellt mit xmrpay.link \u2014 Keine Registrierung, kein KYC",qr_hint:"Klick auf QR zum Speichern",footer:'Open Source &middot; Kein Backend &middot; Kein KYC &middot; <a href="https://gitea.schmidt.eco/schmidt1024/xmrpay.link" target="_blank">Source</a>',aria_currency:"W\xE4hrung",label_uri_details:"Monero-URI anzeigen",label_share_link:"Teilbarer Link",btn_new_request:"Neue Zahlungsanforderung",toast_copied:"Kopiert!",countdown_expired:"Zahlungsfrist abgelaufen",countdown_remaining_days:"Zahlungsfrist: {d} Tage, {h} Std.",countdown_remaining_hours:"Zahlungsfrist: {h}:{m} Std.",rates_offline:"Kurse nicht verf\xFCgbar \u2014 nur XMR-Betrag m\xF6glich",btn_prove_payment:"Zahlung nachweisen",label_tx_hash:"Transaction ID (TX Hash)",placeholder_tx_hash:"64 Hex-Zeichen...",label_tx_key:"Transaction Key (TX Key)",placeholder_tx_key:"64 Hex-Zeichen...",btn_verify_proof:"Zahlung verifizieren",proof_verifying:"Verifiziere...",proof_verified:"Zahlung best\xE4tigt: {amount} XMR",proof_no_match:"Kein passender Output gefunden \u2014 TX Key oder Adresse stimmt nicht",proof_tx_not_found:"Transaktion nicht gefunden",proof_error:"Fehler bei der Verifizierung",status_paid:"Bezahlt"},en:{subtitle:"Monero payment request in seconds",label_addr:"XMR Address",placeholder_addr:"4...",label_amount:"Amount",label_desc:"Description (optional)",placeholder_desc:"e.g. Invoice #42, freelance work...",label_timer:"Payment deadline (optional)",days:"days",placeholder_timer_custom:"Days",btn_generate:"Create payment request",btn_open_wallet:"Open in wallet",btn_copy_addr:"Copy address",btn_download_pdf:"PDF Invoice",pdf_title:"Payment Request",pdf_address:"XMR Address",pdf_amount:"Amount",pdf_desc:"Description",pdf_deadline:"Payment deadline",pdf_deadline_days:"{d} days",pdf_date:"Date",pdf_scan_qr:"Scan QR code to pay",pdf_footer:"Created with xmrpay.link \u2014 No registration, no KYC",qr_hint:"Click QR to save",footer:'Open Source &middot; No Backend &middot; No KYC &middot; <a href="https://gitea.schmidt.eco/schmidt1024/xmrpay.link" target="_blank">Source</a>',aria_currency:"Currency",label_uri_details:"Show Monero URI",label_share_link:"Shareable link",btn_new_request:"New payment request",toast_copied:"Copied!",countdown_expired:"Payment deadline expired",countdown_remaining_days:"Deadline: {d} days, {h} hrs",countdown_remaining_hours:"Deadline: {h}:{m} hrs",rates_offline:"Rates unavailable \u2014 XMR amount only",btn_prove_payment:"Prove payment",label_tx_hash:"Transaction ID (TX Hash)",placeholder_tx_hash:"64 hex characters...",label_tx_key:"Transaction Key (TX Key)",placeholder_tx_key:"64 hex characters...",btn_verify_proof:"Verify payment",proof_verifying:"Verifying...",proof_verified:"Payment confirmed: {amount} XMR",proof_no_match:"No matching output found \u2014 TX key or address mismatch",proof_tx_not_found:"Transaction not found",proof_error:"Verification error",status_paid:"Paid"}},o="de";function u(){var e=null;try{e=localStorage.getItem("xmrpay_lang")}catch{}if(e&&i[e])return e;for(var n=navigator.languages||[navigator.language||"de"],t=0;t<n.length;t++){var a=n[t].substring(0,2).toLowerCase();if(i[a])return a}return"de"}function _(e){document.querySelectorAll("[data-i18n]").forEach(function(n){n.textContent=e[n.getAttribute("data-i18n")]||""}),document.querySelectorAll("[data-i18n-placeholder]").forEach(function(n){n.placeholder=e[n.getAttribute("data-i18n-placeholder")]||""}),document.querySelectorAll("[data-i18n-html]").forEach(function(n){n.innerHTML=e[n.getAttribute("data-i18n-html")]||""}),document.querySelectorAll("[data-i18n-aria]").forEach(function(n){n.setAttribute("aria-label",e[n.getAttribute("data-i18n-aria")]||"")})}function l(e){o=e;var n=i[e];document.documentElement.lang=e;try{localStorage.setItem("xmrpay_lang",e)}catch{}_(n);var t=document.getElementById("langCurrent");t&&(t.textContent=d[e].flag),document.querySelectorAll(".lang-option").forEach(function(r){r.classList.toggle("active",r.getAttribute("data-lang")===e)});for(var a=0;a<c.length;a++)c[a](e)}var c=[];function f(e){c.push(e)}function p(){var e=document.getElementById("langDropdown");if(e){e.innerHTML="";for(var n=Object.keys(d),t=0;t<n.length;t++){var a=n[t],r=document.createElement("button");r.className="lang-option",r.setAttribute("data-lang",a),r.textContent=d[a].name,a===o&&r.classList.add("active"),r.addEventListener("click",(function(y){return function(){l(y),s()}})(a)),e.appendChild(r)}}}function s(){var e=document.getElementById("langPicker");e&&e.classList.remove("open")}function g(){var e=document.getElementById("langPicker"),n=document.getElementById("langToggle");!e||!n||(n.addEventListener("click",function(t){t.stopPropagation(),e.classList.toggle("open")}),document.addEventListener("click",function(t){e.contains(t.target)||s()}))}function h(e){return i[o]&&i[o][e]||e}function m(){return o}return o=u(),document.addEventListener("DOMContentLoaded",function(){p(),g(),l(o)}),{t:h,apply:l,getLang:m,onChange:f}})();