@bobfrankston/rmfmail 1.2.185 → 1.2.187
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/app.bundle.js +49 -0
- package/client/app.bundle.js.map +2 -2
- package/client/app.js +17 -2
- package/client/app.js.map +1 -1
- package/client/app.ts +16 -2
- package/client/components/message-viewer.js +42 -0
- package/client/components/message-viewer.js.map +1 -1
- package/client/components/message-viewer.ts +38 -0
- package/client/package.json +1 -1
- package/client/styles/layout.css +20 -5
- package/package.json +3 -3
- /package/packages/mailx-imap/{node_modules.npmglobalize-stash-71308 → node_modules.npmglobalize-stash-35072}/.package-lock.json +0 -0
package/client/app.bundle.js
CHANGED
|
@@ -1440,9 +1440,26 @@ function showPreviewBodyMenu(absX, absY, selectedText, sourceWindow, linkUrl, li
|
|
|
1440
1440
|
function toggleFullscreenPreview() {
|
|
1441
1441
|
const body = document.body;
|
|
1442
1442
|
const on = !body.classList.contains("fullscreen-preview");
|
|
1443
|
+
if (on && !currentMessage)
|
|
1444
|
+
return;
|
|
1443
1445
|
body.classList.toggle("fullscreen-preview", on);
|
|
1446
|
+
try {
|
|
1447
|
+
window.mailxapi?.logClientEvent?.(`[fullscreen] preview ${on ? "ON" : "OFF"}`);
|
|
1448
|
+
} catch {
|
|
1449
|
+
}
|
|
1444
1450
|
let exit = document.getElementById("mv-exit-fullscreen");
|
|
1445
1451
|
if (on) {
|
|
1452
|
+
if (!document.getElementById("mv-fullscreen-hint")) {
|
|
1453
|
+
const hint = document.createElement("div");
|
|
1454
|
+
hint.id = "mv-fullscreen-hint";
|
|
1455
|
+
hint.textContent = "Fullscreen reading \u2014 press Esc or double-click to exit";
|
|
1456
|
+
hint.style.cssText = "position:fixed;top:16px;left:50%;transform:translateX(-50%);z-index:6000;background:rgba(0,0,0,0.7);color:#fff;padding:8px 16px;border-radius:16px;font-size:13px;pointer-events:none;opacity:1;transition:opacity 0.5s;";
|
|
1457
|
+
document.body.appendChild(hint);
|
|
1458
|
+
setTimeout(() => {
|
|
1459
|
+
hint.style.opacity = "0";
|
|
1460
|
+
}, 2500);
|
|
1461
|
+
setTimeout(() => hint.remove(), 3100);
|
|
1462
|
+
}
|
|
1446
1463
|
if (!exit) {
|
|
1447
1464
|
exit = document.createElement("button");
|
|
1448
1465
|
exit.id = "mv-exit-fullscreen";
|
|
@@ -1464,6 +1481,7 @@ function toggleFullscreenPreview() {
|
|
|
1464
1481
|
}
|
|
1465
1482
|
} else {
|
|
1466
1483
|
exit?.remove();
|
|
1484
|
+
document.getElementById("mv-fullscreen-hint")?.remove();
|
|
1467
1485
|
}
|
|
1468
1486
|
}
|
|
1469
1487
|
function initViewer() {
|
|
@@ -2635,6 +2653,26 @@ ${csp}
|
|
|
2635
2653
|
window.parent.postMessage({ type: "linkClick", url: url }, "*");
|
|
2636
2654
|
}
|
|
2637
2655
|
document.addEventListener("click", handleLinkTap, true);
|
|
2656
|
+
// Remote-image failure diagnostic. Bob 2026-07-28: an allowlisted
|
|
2657
|
+
// Nextdoor digest rendered every https image as a broken icon while the
|
|
2658
|
+
// same URLs fetched fine from curl \u2014 untraceable after the fact because
|
|
2659
|
+
// image load failures are silent. Report failures to the parent, which
|
|
2660
|
+
// logs them to the daemon log with the first failing URL.
|
|
2661
|
+
window.addEventListener("load", function () {
|
|
2662
|
+
setTimeout(function () {
|
|
2663
|
+
try {
|
|
2664
|
+
var bad = [];
|
|
2665
|
+
var imgs = document.images || [];
|
|
2666
|
+
for (var i = 0; i < imgs.length; i++) {
|
|
2667
|
+
var im = imgs[i];
|
|
2668
|
+
if (im.complete && im.naturalWidth === 0 && /^https?:/.test(im.src)) bad.push(im.src);
|
|
2669
|
+
}
|
|
2670
|
+
if (bad.length) {
|
|
2671
|
+
window.parent.postMessage({ type: "imgLoadFail", count: bad.length, total: imgs.length, first: String(bad[0]).slice(0, 160) }, "*");
|
|
2672
|
+
}
|
|
2673
|
+
} catch (e3) { /* diagnostic only */ }
|
|
2674
|
+
}, 3000);
|
|
2675
|
+
});
|
|
2638
2676
|
// Android WebView fallback: some builds drop the synthetic click after
|
|
2639
2677
|
// touchend, so treat a stationary touchstart\u2192touchend on the same link
|
|
2640
2678
|
// as a tap. Anything that moves more than TAP_SLOP pixels is a scroll
|
|
@@ -10046,6 +10084,17 @@ window.addEventListener("message", (e) => {
|
|
|
10046
10084
|
if (api?.openExternal) api.openExternal(url);
|
|
10047
10085
|
else window.open(url, "_blank", "noopener,noreferrer");
|
|
10048
10086
|
}
|
|
10087
|
+
if (e.data?.type === "imgLoadFail") {
|
|
10088
|
+
try {
|
|
10089
|
+
logClientEvent("[viewer] remote images failed to load", {
|
|
10090
|
+
failed: e.data.count,
|
|
10091
|
+
total: e.data.total,
|
|
10092
|
+
first: e.data.first
|
|
10093
|
+
});
|
|
10094
|
+
} catch {
|
|
10095
|
+
}
|
|
10096
|
+
return;
|
|
10097
|
+
}
|
|
10049
10098
|
if (e.data?.type === "previewToggleFullscreen") {
|
|
10050
10099
|
toggleFullscreenPreview();
|
|
10051
10100
|
return;
|