landings: QR center logo as PNG for Android (full Taler wordmark)

Android WebView often failed the official Penpot SVG: root fill=none
and wordmark paths only inherited black from a parent <g>, so the blue
T showed without the "taler" letters. Serve taler-assets qr-logo.png,
keep fixed SVG as fallback, explicit logo size/alt.
This commit is contained in:
Hernâni Marques 2026-07-10 22:12:00 +02:00
parent 6e808c2ab1
commit 96c37cae3c
No known key found for this signature in database
9 changed files with 46 additions and 15 deletions

View file

@ -1437,18 +1437,33 @@ tw balance</pre>
var WITHDRAW_EXCHANGE = "taler://withdraw-exchange/exchange.hacktivism.ch/"; var WITHDRAW_EXCHANGE = "taler://withdraw-exchange/exchange.hacktivism.ch/";
/* QR_Taler: off-DOM encode → PNG img + center logo (same as shop-pay / merchant) */ /* QR_Taler: off-DOM encode → PNG img + center logo (same as shop-pay / merchant) */
/* Prefer PNG: Android WebView often fails the official Penpot SVG
(root fill="none" + wordmark paths inherit black from a parent <g>
→ blue T only, missing "taler"). PNG matches taler-assets qr-logo.png. */
function logoSrc() { function logoSrc() {
try { try {
var b = document.querySelector("base"); var b = document.querySelector("base");
if (b && b.href) return new URL("qr-logo.svg", b.href).href; if (b && b.href) return new URL("qr-logo.png", b.href).href;
} catch (e) {} } catch (e) {}
return "/intro/qr-logo.svg"; return "/intro/qr-logo.png";
} }
function setQrLogo(imgEl) { function setQrLogo(imgEl) {
if (!imgEl) return; if (!imgEl) return;
imgEl.alt = "Taler";
imgEl.width = 100;
imgEl.height = 50;
imgEl.decoding = "async";
imgEl.src = logoSrc(); imgEl.src = logoSrc();
imgEl.onerror = function () { imgEl.onerror = function () {
imgEl.style.display = "none"; /* fallback to fixed SVG if PNG missing */
try {
var b = document.querySelector("base");
imgEl.src = b && b.href
? new URL("qr-logo.svg", b.href).href
: "/intro/qr-logo.svg";
} catch (e2) {
imgEl.style.display = "none";
}
}; };
imgEl.style.display = ""; imgEl.style.display = "";
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

Before After
Before After

View file

@ -123,7 +123,7 @@ button.shop-item {
background: #fff; background: #fff;
image-rendering: pixelated; image-rendering: pixelated;
} }
/* Center logo plate — official qr-logo (webui uses ~100×50 on large QR) */ /* Center logo plate — official qr-logo.png (webui ~100×50; PNG for Android) */
.goa-pay-taler-qr__logo { .goa-pay-taler-qr__logo {
position: absolute; position: absolute;
top: 50%; top: 50%;
@ -132,8 +132,11 @@ button.shop-item {
width: 28%; width: 28%;
height: auto; height: auto;
max-width: 100px; max-width: 100px;
aspect-ratio: 200 / 95;
object-fit: contain;
pointer-events: none; pointer-events: none;
background: transparent; background: #fff;
border-radius: 4px;
} }
/* Settlement: collapsed by default, expand on click */ /* Settlement: collapsed by default, expand on click */

View file

@ -3,7 +3,7 @@
* Flow: POST templates/{id} taler://pay/… + payto links. * Flow: POST templates/{id} taler://pay/… + payto links.
* *
* QR display matches taler-merchant-webui QR_Taler * QR display matches taler-merchant-webui QR_Taler
* (@gnu-taler/web-util QR.tsx): animated #0042B3 conic ring + qr-logo.svg. * (@gnu-taler/web-util QR.tsx): animated #0042B3 conic ring + qr-logo.png.
* Uses qrcode-generator (same lib as webui) via global QRCode if present, * Uses qrcode-generator (same lib as webui) via global QRCode if present,
* else falls back to canvas from qrcode.min.js (davidshimjs). * else falls back to canvas from qrcode.min.js (davidshimjs).
*/ */
@ -21,7 +21,8 @@
} }
function logoSrc() { function logoSrc() {
return introBase() + "qr-logo.svg"; /* PNG: Android often drops SVG wordmark fill inheritance (missing "taler") */
return introBase() + "qr-logo.png";
} }
function templateHttps(productId) { function templateHttps(productId) {
@ -214,9 +215,13 @@
function setLogo(imgEl) { function setLogo(imgEl) {
if (!imgEl) return; if (!imgEl) return;
imgEl.alt = "Taler";
imgEl.width = 100;
imgEl.height = 50;
imgEl.decoding = "async";
imgEl.src = logoSrc(); imgEl.src = logoSrc();
imgEl.onerror = function () { imgEl.onerror = function () {
imgEl.style.display = "none"; imgEl.src = introBase() + "qr-logo.svg";
}; };
imgEl.style.display = ""; imgEl.style.display = "";
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

Before After
Before After

View file

@ -123,7 +123,7 @@ button.shop-item {
background: #fff; background: #fff;
image-rendering: pixelated; image-rendering: pixelated;
} }
/* Center logo plate — official qr-logo (webui uses ~100×50 on large QR) */ /* Center logo plate — official qr-logo.png (webui ~100×50; PNG for Android) */
.goa-pay-taler-qr__logo { .goa-pay-taler-qr__logo {
position: absolute; position: absolute;
top: 50%; top: 50%;
@ -132,8 +132,11 @@ button.shop-item {
width: 28%; width: 28%;
height: auto; height: auto;
max-width: 100px; max-width: 100px;
aspect-ratio: 200 / 95;
object-fit: contain;
pointer-events: none; pointer-events: none;
background: transparent; background: #fff;
border-radius: 4px;
} }
/* Settlement: collapsed by default, expand on click */ /* Settlement: collapsed by default, expand on click */

View file

@ -3,7 +3,7 @@
* Flow: POST templates/{id} taler://pay/… + payto links. * Flow: POST templates/{id} taler://pay/… + payto links.
* *
* QR display matches taler-merchant-webui QR_Taler * QR display matches taler-merchant-webui QR_Taler
* (@gnu-taler/web-util QR.tsx): animated #0042B3 conic ring + qr-logo.svg. * (@gnu-taler/web-util QR.tsx): animated #0042B3 conic ring + qr-logo.png.
* Uses qrcode-generator (same lib as webui) via global QRCode if present, * Uses qrcode-generator (same lib as webui) via global QRCode if present,
* else falls back to canvas from qrcode.min.js (davidshimjs). * else falls back to canvas from qrcode.min.js (davidshimjs).
*/ */
@ -21,7 +21,8 @@
} }
function logoSrc() { function logoSrc() {
return introBase() + "qr-logo.svg"; /* PNG: Android often drops SVG wordmark fill inheritance (missing "taler") */
return introBase() + "qr-logo.png";
} }
function templateHttps(productId) { function templateHttps(productId) {
@ -214,9 +215,13 @@
function setLogo(imgEl) { function setLogo(imgEl) {
if (!imgEl) return; if (!imgEl) return;
imgEl.alt = "Taler";
imgEl.width = 100;
imgEl.height = 50;
imgEl.decoding = "async";
imgEl.src = logoSrc(); imgEl.src = logoSrc();
imgEl.onerror = function () { imgEl.onerror = function () {
imgEl.style.display = "none"; imgEl.src = introBase() + "qr-logo.svg";
}; };
imgEl.style.display = ""; imgEl.style.display = "";
} }