@bobfrankston/rmfmail 1.1.170 → 1.1.177
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/bin/mailx.js +140 -4
- package/bin/mailx.js.map +1 -1
- package/bin/mailx.ts +127 -5
- package/client/android-bootstrap.bundle.js +4 -3
- package/client/android-bootstrap.bundle.js.map +2 -2
- package/client/app.bundle.js +91 -6
- package/client/app.bundle.js.map +2 -2
- package/client/app.js +39 -0
- package/client/app.js.map +1 -1
- package/client/app.ts +33 -0
- package/client/components/message-list.js +114 -7
- package/client/components/message-list.js.map +1 -1
- package/client/components/message-list.ts +113 -6
- package/client/compose/compose.bundle.js +2068 -1775
- package/client/compose/compose.bundle.js.map +4 -4
- package/client/compose/editor.js +85 -0
- package/client/compose/editor.js.map +1 -1
- package/client/compose/editor.ts +79 -0
- package/client/compose/spellcheck-core.js +253 -0
- package/client/compose/spellcheck-core.js.map +1 -0
- package/client/compose/spellcheck-core.ts +242 -0
- package/package.json +5 -5
- package/packages/mailx-core/index.js +1 -1
- package/packages/mailx-core/index.js.map +1 -1
- package/packages/mailx-core/index.ts +1 -1
- package/packages/mailx-imap/index.d.ts.map +1 -1
- package/packages/mailx-imap/index.js +15 -1
- package/packages/mailx-imap/index.js.map +1 -1
- package/packages/mailx-imap/index.ts +9 -1
- package/packages/mailx-imap/package-lock.json +2 -2
- package/packages/mailx-imap/package.json +1 -1
- package/packages/mailx-store/db.d.ts +9 -1
- package/packages/mailx-store/db.d.ts.map +1 -1
- package/packages/mailx-store/db.js +15 -2
- package/packages/mailx-store/db.js.map +1 -1
- package/packages/mailx-store/db.ts +18 -4
- package/packages/mailx-store/package.json +1 -1
- package/packages/mailx-store/store.js +1 -1
- package/packages/mailx-store/store.js.map +1 -1
- package/packages/mailx-store/store.ts +1 -1
- package/packages/mailx-store-web/android-bootstrap.js +1 -1
- package/packages/mailx-store-web/android-bootstrap.js.map +1 -1
- package/packages/mailx-store-web/android-bootstrap.ts +1 -1
- package/packages/mailx-store-web/db.d.ts +2 -1
- package/packages/mailx-store-web/db.d.ts.map +1 -1
- package/packages/mailx-store-web/db.js +3 -2
- package/packages/mailx-store-web/db.js.map +1 -1
- package/packages/mailx-store-web/db.ts +4 -3
- package/packages/mailx-store-web/package.json +1 -1
- package/packages/mailx-store-web/sync-manager.js +1 -1
- package/packages/mailx-store-web/sync-manager.js.map +1 -1
- package/packages/mailx-store-web/sync-manager.ts +1 -1
- /package/packages/mailx-imap/{node_modules.npmglobalize-stash-46236 → node_modules.npmglobalize-stash-50992}/.package-lock.json +0 -0
package/client/app.bundle.js
CHANGED
|
@@ -2531,6 +2531,31 @@ function currentViewKey() {
|
|
|
2531
2531
|
const flaggedOnly = document.getElementById("ml-body")?.classList.contains("flagged-only") || false;
|
|
2532
2532
|
return cacheKey("folder", currentAccountId2, currentFolderId, flaggedOnly);
|
|
2533
2533
|
}
|
|
2534
|
+
function withScrollAnchor(body, doRender) {
|
|
2535
|
+
const scrollTop = body.scrollTop;
|
|
2536
|
+
if (scrollTop < 4) {
|
|
2537
|
+
doRender();
|
|
2538
|
+
return;
|
|
2539
|
+
}
|
|
2540
|
+
const rowsBefore = Array.from(body.querySelectorAll(".ml-row"));
|
|
2541
|
+
let anchorUuid = "";
|
|
2542
|
+
let anchorOffsetWithinViewport = 0;
|
|
2543
|
+
for (const r of rowsBefore) {
|
|
2544
|
+
const visualTop = r.offsetTop - scrollTop;
|
|
2545
|
+
if (visualTop >= 0) {
|
|
2546
|
+
anchorUuid = r.dataset.uuid || "";
|
|
2547
|
+
anchorOffsetWithinViewport = visualTop;
|
|
2548
|
+
break;
|
|
2549
|
+
}
|
|
2550
|
+
}
|
|
2551
|
+
doRender();
|
|
2552
|
+
if (!anchorUuid)
|
|
2553
|
+
return;
|
|
2554
|
+
const after = body.querySelector(`.ml-row[data-uuid="${CSS.escape(anchorUuid)}"]`);
|
|
2555
|
+
if (after) {
|
|
2556
|
+
body.scrollTop = after.offsetTop - anchorOffsetWithinViewport;
|
|
2557
|
+
}
|
|
2558
|
+
}
|
|
2534
2559
|
function rememberPosition() {
|
|
2535
2560
|
const key = currentViewKey();
|
|
2536
2561
|
if (!key)
|
|
@@ -2644,8 +2669,30 @@ function setRowSeen(accountId, uid, yes) {
|
|
|
2644
2669
|
row.setUnreadClass(!yes);
|
|
2645
2670
|
}
|
|
2646
2671
|
function scrollFocusedIntoView() {
|
|
2647
|
-
if (focusedRow)
|
|
2648
|
-
|
|
2672
|
+
if (!focusedRow)
|
|
2673
|
+
return;
|
|
2674
|
+
let el = focusedRow.el;
|
|
2675
|
+
if (!document.body.contains(el)) {
|
|
2676
|
+
const body = document.getElementById("ml-body");
|
|
2677
|
+
const uid = focusedRow.msg?.uid;
|
|
2678
|
+
if (body && uid != null) {
|
|
2679
|
+
el = body.querySelector(`.ml-row[data-uid="${uid}"][data-account-id="${CSS.escape(focusedRow.accountId)}"]`) || body.querySelector(`.ml-row[data-uid="${uid}"]`);
|
|
2680
|
+
}
|
|
2681
|
+
if (!el) {
|
|
2682
|
+
const status = document.getElementById("status-sync");
|
|
2683
|
+
if (status) {
|
|
2684
|
+
status.textContent = "Selected message isn't in the loaded list \u2014 scroll down to load more, or open the folder it lives in.";
|
|
2685
|
+
setTimeout(() => {
|
|
2686
|
+
if (status?.textContent?.startsWith("Selected message"))
|
|
2687
|
+
status.textContent = "";
|
|
2688
|
+
}, 4e3);
|
|
2689
|
+
}
|
|
2690
|
+
return;
|
|
2691
|
+
}
|
|
2692
|
+
focusedRow.el = el;
|
|
2693
|
+
el.classList.add("selected");
|
|
2694
|
+
}
|
|
2695
|
+
el.scrollIntoView({ block: "center" });
|
|
2649
2696
|
}
|
|
2650
2697
|
function releaseFocus() {
|
|
2651
2698
|
focusedRow = null;
|
|
@@ -2953,10 +3000,11 @@ async function loadUnifiedInbox(autoSelect = true) {
|
|
|
2953
3000
|
return;
|
|
2954
3001
|
}
|
|
2955
3002
|
setMessages(result.items);
|
|
2956
|
-
renderMessages(body, "", result.items);
|
|
3003
|
+
withScrollAnchor(body, () => renderMessages(body, "", result.items));
|
|
2957
3004
|
const targetUuid = remembered ? pickRestoreUid(result.items, remembered) : null;
|
|
2958
3005
|
if (targetUuid) {
|
|
2959
|
-
|
|
3006
|
+
if (!cached)
|
|
3007
|
+
body.scrollTop = savedScroll;
|
|
2960
3008
|
restoreSelection(body, targetUuid);
|
|
2961
3009
|
} else if (autoSelect) {
|
|
2962
3010
|
selectFirst(body);
|
|
@@ -3101,7 +3149,7 @@ async function loadMessages(accountId, folderId, page = 1, specialUse = "", auto
|
|
|
3101
3149
|
return;
|
|
3102
3150
|
}
|
|
3103
3151
|
setMessages(result.items);
|
|
3104
|
-
renderMessages(body, accountId, result.items);
|
|
3152
|
+
withScrollAnchor(body, () => renderMessages(body, accountId, result.items));
|
|
3105
3153
|
if (focusedRow) {
|
|
3106
3154
|
const stillThere = result.items.some((m) => m.accountId === focusedRow.accountId && m.uid === focusedRow.msg.uid);
|
|
3107
3155
|
if (!stillThere) {
|
|
@@ -3114,7 +3162,8 @@ async function loadMessages(accountId, folderId, page = 1, specialUse = "", auto
|
|
|
3114
3162
|
requestAnimationFrame(() => {
|
|
3115
3163
|
if (myGen !== loadGen)
|
|
3116
3164
|
return;
|
|
3117
|
-
|
|
3165
|
+
if (!cached)
|
|
3166
|
+
body.scrollTop = savedScroll;
|
|
3118
3167
|
restoreSelection(body, targetUuid);
|
|
3119
3168
|
});
|
|
3120
3169
|
} else if (autoSelect) {
|
|
@@ -3153,6 +3202,15 @@ function renderMessages(body, accountId, items) {
|
|
|
3153
3202
|
while (tempDiv.firstChild)
|
|
3154
3203
|
fragment.appendChild(tempDiv.firstChild);
|
|
3155
3204
|
body.replaceChildren(fragment);
|
|
3205
|
+
if (focusedRow) {
|
|
3206
|
+
const fAcct = focusedRow.accountId;
|
|
3207
|
+
const fUid = focusedRow.msg?.uid;
|
|
3208
|
+
const stillThere = items.some((m) => (m.accountId || accountId) === fAcct && m.uid === fUid);
|
|
3209
|
+
if (!stillThere) {
|
|
3210
|
+
clearViewer();
|
|
3211
|
+
focusedRow = null;
|
|
3212
|
+
}
|
|
3213
|
+
}
|
|
3156
3214
|
}
|
|
3157
3215
|
function selectFirst(body) {
|
|
3158
3216
|
if (window.innerWidth <= 768)
|
|
@@ -9028,6 +9086,33 @@ document.getElementById("message-viewer")?.addEventListener("dblclick", (e) => {
|
|
|
9028
9086
|
if (target?.closest("a, button, input, select, textarea, [contenteditable]")) return;
|
|
9029
9087
|
toggleFullscreenPreview();
|
|
9030
9088
|
});
|
|
9089
|
+
function focusPaneById(id) {
|
|
9090
|
+
const el = document.getElementById(id);
|
|
9091
|
+
if (!el) return;
|
|
9092
|
+
if (!el.hasAttribute("tabindex")) el.setAttribute("tabindex", "-1");
|
|
9093
|
+
el.focus();
|
|
9094
|
+
el.style.outline = "2px solid var(--color-accent, #3b82f6)";
|
|
9095
|
+
el.style.outlineOffset = "-2px";
|
|
9096
|
+
setTimeout(() => {
|
|
9097
|
+
el.style.outline = "";
|
|
9098
|
+
el.style.outlineOffset = "";
|
|
9099
|
+
}, 600);
|
|
9100
|
+
}
|
|
9101
|
+
document.addEventListener("auxclick", (e) => {
|
|
9102
|
+
if (e.button !== 1) return;
|
|
9103
|
+
const target = e.target;
|
|
9104
|
+
if (!target) return;
|
|
9105
|
+
const ft = target.closest("#folder-tree");
|
|
9106
|
+
const ml = target.closest("#ml-body");
|
|
9107
|
+
const mv = target.closest("#message-viewer");
|
|
9108
|
+
let id = null;
|
|
9109
|
+
if (ft) id = "folder-tree";
|
|
9110
|
+
else if (ml) id = "ml-body";
|
|
9111
|
+
else if (mv) id = "message-viewer";
|
|
9112
|
+
if (!id) return;
|
|
9113
|
+
e.preventDefault();
|
|
9114
|
+
focusPaneById(id);
|
|
9115
|
+
});
|
|
9031
9116
|
function cyclePaneFocus(reverse) {
|
|
9032
9117
|
const panes = [
|
|
9033
9118
|
{ id: "folder-tree", el: document.getElementById("folder-tree") },
|