@bobfrankston/rmfmail 1.2.226 → 1.2.228
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 +62 -1
- package/client/app.bundle.js.map +2 -2
- package/client/components/message-viewer.js +89 -0
- package/client/components/message-viewer.js.map +1 -1
- package/client/components/message-viewer.ts +87 -0
- package/package.json +5 -5
- package/packages/mailx-service/jsonrpc.d.ts.map +1 -1
- package/packages/mailx-service/jsonrpc.js +82 -1
- package/packages/mailx-service/jsonrpc.js.map +1 -1
- package/packages/mailx-service/jsonrpc.ts +83 -1
- package/packages/mailx-service/package.json +1 -1
- /package/packages/mailx-imap/{node_modules.npmglobalize-stash-86196 → node_modules.npmglobalize-stash-78836}/.package-lock.json +0 -0
package/client/app.bundle.js
CHANGED
|
@@ -1795,6 +1795,18 @@ function confirmDeleteAttachments(msg, accountId, uid, ids, question) {
|
|
|
1795
1795
|
backdrop.append(panel);
|
|
1796
1796
|
document.body.append(backdrop);
|
|
1797
1797
|
}
|
|
1798
|
+
function markRenderStart(accountId, uid) {
|
|
1799
|
+
try {
|
|
1800
|
+
sessionStorage.setItem(RENDER_MARK_KEY, JSON.stringify({ key: renderKey(accountId, uid), at: Date.now() }));
|
|
1801
|
+
} catch {
|
|
1802
|
+
}
|
|
1803
|
+
}
|
|
1804
|
+
function markRenderDone() {
|
|
1805
|
+
try {
|
|
1806
|
+
sessionStorage.removeItem(RENDER_MARK_KEY);
|
|
1807
|
+
} catch {
|
|
1808
|
+
}
|
|
1809
|
+
}
|
|
1798
1810
|
async function showMessage(accountId, uid, folderId, specialUse, isRetry = false, envelope) {
|
|
1799
1811
|
const gen = ++showMessageGeneration;
|
|
1800
1812
|
if (!isRetry)
|
|
@@ -1850,11 +1862,28 @@ async function showMessage(accountId, uid, folderId, specialUse, isRetry = false
|
|
|
1850
1862
|
headerEl.hidden = true;
|
|
1851
1863
|
}
|
|
1852
1864
|
attEl.hidden = true;
|
|
1865
|
+
if (poisonedMessages.has(renderKey(accountId, uid)) && !isRetry) {
|
|
1866
|
+
const emlHint = envelope?.emlPath || "";
|
|
1867
|
+
bodyEl.innerHTML = `<div class="mv-system-message mv-system-error">
|
|
1868
|
+
<div class="mv-system-tag">mailx</div>
|
|
1869
|
+
<div class="mv-system-title">Render failed for this message</div>
|
|
1870
|
+
<div class="mv-system-body">The display engine stopped while drawing this message last time, so it hasn't been drawn again automatically.
|
|
1871
|
+
Usually this means an unusually large body.${emlHint ? `<br><code style="user-select:all;font-size:0.9em">${escapeHtml2(emlHint)}</code>` : ""}
|
|
1872
|
+
<br><br><button type="button" id="mv-render-anyway" class="mailx-modal-btn">Try anyway</button></div>
|
|
1873
|
+
</div>`;
|
|
1874
|
+
document.getElementById("mv-render-anyway")?.addEventListener("click", () => {
|
|
1875
|
+
poisonedMessages.delete(renderKey(accountId, uid));
|
|
1876
|
+
void showMessage(accountId, uid, folderId, specialUse, true, envelope);
|
|
1877
|
+
});
|
|
1878
|
+
attEl.hidden = true;
|
|
1879
|
+
return;
|
|
1880
|
+
}
|
|
1853
1881
|
try {
|
|
1854
1882
|
if (cachedMsg)
|
|
1855
1883
|
_ptick("parsedCache HIT \u2014 sync render");
|
|
1856
1884
|
else
|
|
1857
1885
|
_ptick("parsedCache MISS \u2014 IPC begin");
|
|
1886
|
+
markRenderStart(accountId, uid);
|
|
1858
1887
|
const msg = cachedMsg ? cachedMsg : await getMessage(accountId, uid, false, folderId);
|
|
1859
1888
|
if (!cachedMsg)
|
|
1860
1889
|
_ptick(`IPC done (cached=${msg.cached !== false}, ${msg.bodyHtml?.length || 0} bytes html)`);
|
|
@@ -2387,6 +2416,19 @@ async function showMessage(accountId, uid, folderId, specialUse, isRetry = false
|
|
|
2387
2416
|
const pre = document.createElement("pre");
|
|
2388
2417
|
pre.style.cssText = "padding: 1rem; white-space: pre-wrap; word-break: break-word; font-family: system-ui, sans-serif; font-size: 17.5px; line-height: 1.5; color: #1a1a2e; background: #fff; margin: 0; height: 100%; overflow: auto;";
|
|
2389
2418
|
pre.innerHTML = linkifyText(msg.bodyText);
|
|
2419
|
+
const trunc = msg.bodyTruncated;
|
|
2420
|
+
if (trunc) {
|
|
2421
|
+
const mb = (n) => `${(n / 1048576).toFixed(1)} MB`;
|
|
2422
|
+
const note = document.createElement("div");
|
|
2423
|
+
note.className = "mv-system-message mv-system-error";
|
|
2424
|
+
note.style.cssText = "margin: 0 0 12px 0;";
|
|
2425
|
+
note.innerHTML = `<div class="mv-system-tag">mailx</div>
|
|
2426
|
+
<div class="mv-system-title">Showing the first ${mb(trunc.sentBytes)} of a ${mb(trunc.totalBytes)} message</div>
|
|
2427
|
+
<div class="mv-system-body">This message has no MIME structure, so its entire payload is one plain-text part; the remainder is almost always the base64 of a returned attachment.
|
|
2428
|
+
The complete message is on disk:<br>
|
|
2429
|
+
<code style="user-select:all;font-size:0.9em">${escapeHtml2(trunc.emlPath || "(path unavailable)")}</code></div>`;
|
|
2430
|
+
bodyEl.appendChild(note);
|
|
2431
|
+
}
|
|
2390
2432
|
bodyEl.appendChild(pre);
|
|
2391
2433
|
} else {
|
|
2392
2434
|
const fetchErr = recentFetchErrors.get(`${accountId}:${uid}`);
|
|
@@ -2408,6 +2450,7 @@ async function showMessage(accountId, uid, folderId, specialUse, isRetry = false
|
|
|
2408
2450
|
</div>`;
|
|
2409
2451
|
}
|
|
2410
2452
|
}
|
|
2453
|
+
markRenderDone();
|
|
2411
2454
|
attEl.innerHTML = "";
|
|
2412
2455
|
attEl.hidden = true;
|
|
2413
2456
|
if (msg.attachments?.length) {
|
|
@@ -3275,7 +3318,7 @@ function spawnDesktopPopout(msg, accountId) {
|
|
|
3275
3318
|
function escapeHtmlLocal(s) {
|
|
3276
3319
|
return (s || "").replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
3277
3320
|
}
|
|
3278
|
-
var currentMessage, currentAccountId, dragOutUrls, showMessageGeneration, retryCount, lastEnvelope, PARSED_CACHE_LIMIT, parsedCache, sessionAllowedRemote, recentFetchErrors, ZOOM_KEY, ZOOM_MIN, ZOOM_MAX, ZOOM_STEP, previewZoom;
|
|
3321
|
+
var currentMessage, currentAccountId, dragOutUrls, showMessageGeneration, retryCount, lastEnvelope, PARSED_CACHE_LIMIT, parsedCache, sessionAllowedRemote, recentFetchErrors, ZOOM_KEY, ZOOM_MIN, ZOOM_MAX, ZOOM_STEP, previewZoom, RENDER_MARK_KEY, RENDER_MARK_MAX_AGE_MS, poisonedMessages, renderKey;
|
|
3279
3322
|
var init_message_viewer = __esm({
|
|
3280
3323
|
"client/components/message-viewer.js"() {
|
|
3281
3324
|
"use strict";
|
|
@@ -3324,6 +3367,24 @@ var init_message_viewer = __esm({
|
|
|
3324
3367
|
clearViewer();
|
|
3325
3368
|
}
|
|
3326
3369
|
});
|
|
3370
|
+
RENDER_MARK_KEY = "mailx-rendering";
|
|
3371
|
+
RENDER_MARK_MAX_AGE_MS = 6e4;
|
|
3372
|
+
poisonedMessages = /* @__PURE__ */ new Set();
|
|
3373
|
+
renderKey = (a, u) => `${a}:${u}`;
|
|
3374
|
+
(() => {
|
|
3375
|
+
try {
|
|
3376
|
+
const raw = sessionStorage.getItem(RENDER_MARK_KEY);
|
|
3377
|
+
if (!raw)
|
|
3378
|
+
return;
|
|
3379
|
+
sessionStorage.removeItem(RENDER_MARK_KEY);
|
|
3380
|
+
const mark = JSON.parse(raw);
|
|
3381
|
+
if (!mark?.key || Date.now() - (mark.at || 0) > RENDER_MARK_MAX_AGE_MS)
|
|
3382
|
+
return;
|
|
3383
|
+
poisonedMessages.add(mark.key);
|
|
3384
|
+
console.error(`[viewer] previous render of ${mark.key} did not complete \u2014 the WebView probably died on it; not auto-rendering again`);
|
|
3385
|
+
} catch {
|
|
3386
|
+
}
|
|
3387
|
+
})();
|
|
3327
3388
|
subscribeStore("*", (ev) => {
|
|
3328
3389
|
if (ev.kind !== "bodyFetchError")
|
|
3329
3390
|
return;
|