@bobfrankston/rmfmail 1.2.12 → 1.2.14
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 +21 -16
- package/client/app.bundle.js.map +2 -2
- package/client/app.js +33 -20
- package/client/app.js.map +1 -1
- package/client/app.ts +31 -18
- package/package.json +3 -3
package/client/app.js
CHANGED
|
@@ -1495,23 +1495,18 @@ async function deleteSelectedMessages() {
|
|
|
1495
1495
|
// the prompt and the undo promise must change: permanent delete always
|
|
1496
1496
|
// confirms (even a single message) and can't be undone (Bob 2026-06-12).
|
|
1497
1497
|
const inTrash = currentFolderSpecialUse === "trash";
|
|
1498
|
-
// SAFETY GATE.
|
|
1499
|
-
// - In Trash:
|
|
1500
|
-
// - Elsewhere:
|
|
1501
|
-
//
|
|
1502
|
-
//
|
|
1503
|
-
//
|
|
1498
|
+
// SAFETY GATE — only for the IRREVERSIBLE action.
|
|
1499
|
+
// - In Trash: delete is permanent → confirm (Bob explicitly wanted this).
|
|
1500
|
+
// - Elsewhere: move to Trash with NO prompt, single or bulk. It's
|
|
1501
|
+
// undoable (Ctrl+Z restores the whole batch) and matches Outlook /
|
|
1502
|
+
// Thunderbird, which don't nag on a move-to-trash. Bob 2026-06-15:
|
|
1503
|
+
// "stop giving me the trash warning message. It is annoying."
|
|
1504
1504
|
const n = selected.length;
|
|
1505
1505
|
if (inTrash) {
|
|
1506
1506
|
if (!confirm(`Permanently delete ${n} message${n === 1 ? "" : "s"} from Trash?\n\nThis cannot be undone.`)) {
|
|
1507
1507
|
return;
|
|
1508
1508
|
}
|
|
1509
1509
|
}
|
|
1510
|
-
else if (n > 1) {
|
|
1511
|
-
if (!confirm(`Move ${n} messages to Trash?\n\n(Ctrl+Z restores them if this was a mistake.)`)) {
|
|
1512
|
-
return;
|
|
1513
|
-
}
|
|
1514
|
-
}
|
|
1515
1510
|
const statusSync = document.getElementById("status-sync");
|
|
1516
1511
|
// Optimistic UI: remove from list IMMEDIATELY, then queue the IPC.
|
|
1517
1512
|
// Old order awaited the daemon round-trip (IPC + DB updates) before
|
|
@@ -3609,18 +3604,36 @@ document.addEventListener("keydown", (e) => {
|
|
|
3609
3604
|
// from the search box or compose draft list.
|
|
3610
3605
|
if (!e.ctrlKey && inText)
|
|
3611
3606
|
return;
|
|
3607
|
+
e.preventDefault();
|
|
3608
|
+
const applySeen = (m, seen) => {
|
|
3609
|
+
setSeen(m, seen);
|
|
3610
|
+
updateFlags(m.accountId, m.uid, m.flags).then(() => {
|
|
3611
|
+
messageState.updateMessageFlags(m.accountId, m.uid, m.flags);
|
|
3612
|
+
const row = document.querySelector(`.ml-row[data-uid="${m.uid}"][data-account-id="${CSS.escape(m.accountId)}"]`);
|
|
3613
|
+
if (row)
|
|
3614
|
+
row.classList.toggle("unread", !seen);
|
|
3615
|
+
}).catch(() => { setSeen(m, !seen); });
|
|
3616
|
+
};
|
|
3617
|
+
// getSelectedMessages returns only id tuples — resolve to the full
|
|
3618
|
+
// message objects (with flags) from the list state.
|
|
3619
|
+
const selectedIds = getSelectedMessages();
|
|
3620
|
+
if (selectedIds.length > 1) {
|
|
3621
|
+
// Multi-select → mark every selected message READ (not a toggle):
|
|
3622
|
+
// a triage sweep is "I've dealt with these," not "flip each one"
|
|
3623
|
+
// (Bob 2026-06-15). Skip those already read.
|
|
3624
|
+
const all = messageState.getMessages();
|
|
3625
|
+
for (const id of selectedIds) {
|
|
3626
|
+
const m = all.find(x => x.accountId === id.accountId && x.uid === id.uid && x.folderId === id.folderId);
|
|
3627
|
+
if (m && !seenOf(m))
|
|
3628
|
+
applySeen(m, true);
|
|
3629
|
+
}
|
|
3630
|
+
return;
|
|
3631
|
+
}
|
|
3632
|
+
// Single → toggle read/unread.
|
|
3612
3633
|
const sel = getCurrentFocused();
|
|
3613
3634
|
if (!sel)
|
|
3614
3635
|
return;
|
|
3615
|
-
|
|
3616
|
-
const wasSeen = seenOf(sel);
|
|
3617
|
-
setSeen(sel, !wasSeen);
|
|
3618
|
-
updateFlags(sel.accountId, sel.uid, sel.flags).then(() => {
|
|
3619
|
-
messageState.updateMessageFlags(sel.accountId, sel.uid, sel.flags);
|
|
3620
|
-
const row = document.querySelector(`.ml-row[data-uid="${sel.uid}"][data-account-id="${sel.accountId}"]`);
|
|
3621
|
-
if (row)
|
|
3622
|
-
row.classList.toggle("unread", wasSeen);
|
|
3623
|
-
}).catch(() => { setSeen(sel, wasSeen); });
|
|
3636
|
+
applySeen(sel, !seenOf(sel));
|
|
3624
3637
|
}
|
|
3625
3638
|
// Z = locate the focused row in the list (scroll-to-selected). After
|
|
3626
3639
|
// scrolling the list out of sync with the preview, this snaps back.
|