@bobfrankston/rmfmail 1.0.700 → 1.0.702
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 +135 -66
- package/client/app.bundle.js.map +3 -3
- package/client/app.js +21 -27
- package/client/app.js.map +1 -1
- package/client/app.ts +21 -27
- package/client/components/message-list.js +70 -40
- package/client/components/message-list.js.map +1 -1
- package/client/components/message-list.ts +71 -38
- package/client/components/message-viewer.js +23 -19
- package/client/components/message-viewer.js.map +1 -1
- package/client/components/message-viewer.ts +14 -14
- package/package.json +1 -1
- package/packages/mailx-imap/index.d.ts +5 -0
- package/packages/mailx-imap/index.d.ts.map +1 -1
- package/packages/mailx-imap/index.js +31 -1
- package/packages/mailx-imap/index.js.map +1 -1
- package/packages/mailx-imap/index.ts +29 -1
- package/packages/mailx-imap/node_modules.npmglobalize-stash-51012/.package-lock.json +116 -0
- package/packages/mailx-imap/package-lock.json +2 -2
- package/packages/mailx-imap/package.json +1 -1
- package/packages/mailx-types/index.d.ts +24 -0
- package/packages/mailx-types/index.d.ts.map +1 -1
- package/packages/mailx-types/index.js +44 -0
- package/packages/mailx-types/index.js.map +1 -1
- package/packages/mailx-types/index.ts +51 -0
- package/packages/mailx-types/package.json +1 -1
package/client/app.bundle.js
CHANGED
|
@@ -634,6 +634,48 @@ var init_message_state = __esm({
|
|
|
634
634
|
}
|
|
635
635
|
});
|
|
636
636
|
|
|
637
|
+
// packages/mailx-types/contact-rules.js
|
|
638
|
+
var init_contact_rules = __esm({
|
|
639
|
+
"packages/mailx-types/contact-rules.js"() {
|
|
640
|
+
"use strict";
|
|
641
|
+
}
|
|
642
|
+
});
|
|
643
|
+
|
|
644
|
+
// packages/mailx-types/groups.js
|
|
645
|
+
var init_groups = __esm({
|
|
646
|
+
"packages/mailx-types/groups.js"() {
|
|
647
|
+
"use strict";
|
|
648
|
+
}
|
|
649
|
+
});
|
|
650
|
+
|
|
651
|
+
// packages/mailx-types/index.js
|
|
652
|
+
function _has(msg, flag) {
|
|
653
|
+
return !!msg.flags && msg.flags.includes(flag);
|
|
654
|
+
}
|
|
655
|
+
function _set(msg, flag, state) {
|
|
656
|
+
const present = (msg.flags || []).includes(flag);
|
|
657
|
+
if (state === present)
|
|
658
|
+
return;
|
|
659
|
+
const next = state ? [...msg.flags || [], flag] : (msg.flags || []).filter((f) => f !== flag);
|
|
660
|
+
msg.flags = next;
|
|
661
|
+
}
|
|
662
|
+
var _SEEN, _FLAGGED, _DRAFT, seenOf, flaggedOf, draftOf, setSeen, setFlagged;
|
|
663
|
+
var init_mailx_types = __esm({
|
|
664
|
+
"packages/mailx-types/index.js"() {
|
|
665
|
+
"use strict";
|
|
666
|
+
init_contact_rules();
|
|
667
|
+
init_groups();
|
|
668
|
+
_SEEN = "\\Seen";
|
|
669
|
+
_FLAGGED = "\\Flagged";
|
|
670
|
+
_DRAFT = "\\Draft";
|
|
671
|
+
seenOf = (m) => _has(m, _SEEN);
|
|
672
|
+
flaggedOf = (m) => _has(m, _FLAGGED);
|
|
673
|
+
draftOf = (m) => _has(m, _DRAFT);
|
|
674
|
+
setSeen = (m, state) => _set(m, _SEEN, state);
|
|
675
|
+
setFlagged = (m, state) => _set(m, _FLAGGED, state);
|
|
676
|
+
}
|
|
677
|
+
});
|
|
678
|
+
|
|
637
679
|
// client/components/message-viewer.js
|
|
638
680
|
function parsedCacheGet(accountId, uid) {
|
|
639
681
|
const key = `${accountId}:${uid}`;
|
|
@@ -1047,7 +1089,7 @@ async function showMessage(accountId, uid, folderId, specialUse, isRetry = false
|
|
|
1047
1089
|
parsedCachePut(accountId, uid, msg);
|
|
1048
1090
|
currentMessage = msg;
|
|
1049
1091
|
currentAccountId = accountId;
|
|
1050
|
-
if (!msg
|
|
1092
|
+
if (!seenOf(msg)) {
|
|
1051
1093
|
let enabled = true;
|
|
1052
1094
|
let delaySec = 2;
|
|
1053
1095
|
try {
|
|
@@ -1059,21 +1101,24 @@ async function showMessage(accountId, uid, folderId, specialUse, isRetry = false
|
|
|
1059
1101
|
}
|
|
1060
1102
|
if (enabled) {
|
|
1061
1103
|
const captureGen = gen;
|
|
1062
|
-
const
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1104
|
+
const apply = () => {
|
|
1105
|
+
if (captureGen !== showMessageGeneration)
|
|
1106
|
+
return;
|
|
1107
|
+
setSeen(msg, true);
|
|
1108
|
+
updateFlags(accountId, uid, msg.flags);
|
|
1109
|
+
try {
|
|
1110
|
+
updateMessageFlags(accountId, uid, msg.flags);
|
|
1111
|
+
} catch {
|
|
1112
|
+
}
|
|
1113
|
+
try {
|
|
1114
|
+
setRowSeen(accountId, uid, true);
|
|
1115
|
+
} catch {
|
|
1116
|
+
}
|
|
1117
|
+
};
|
|
1118
|
+
if (delaySec === 0)
|
|
1119
|
+
apply();
|
|
1120
|
+
else
|
|
1121
|
+
setTimeout(apply, delaySec * 1e3);
|
|
1077
1122
|
}
|
|
1078
1123
|
}
|
|
1079
1124
|
headerEl.hidden = false;
|
|
@@ -2021,6 +2066,8 @@ var init_message_viewer = __esm({
|
|
|
2021
2066
|
init_api_client();
|
|
2022
2067
|
init_context_menu();
|
|
2023
2068
|
init_message_state();
|
|
2069
|
+
init_message_list();
|
|
2070
|
+
init_mailx_types();
|
|
2024
2071
|
currentMessage = null;
|
|
2025
2072
|
currentAccountId = "";
|
|
2026
2073
|
lastAutoOpenedDraftUid = -1;
|
|
@@ -2192,6 +2239,7 @@ __export(message_list_exports, {
|
|
|
2192
2239
|
removeMessagesAndReconcile: () => removeMessagesAndReconcile,
|
|
2193
2240
|
scrollFocusedIntoView: () => scrollFocusedIntoView,
|
|
2194
2241
|
setRowFlagged: () => setRowFlagged,
|
|
2242
|
+
setRowSeen: () => setRowSeen,
|
|
2195
2243
|
showThreadPopup: () => showThreadPopup
|
|
2196
2244
|
});
|
|
2197
2245
|
function cacheKey(mode, a, f, flagged, q) {
|
|
@@ -2313,6 +2361,11 @@ function setRowFlagged(accountId, uid, yes) {
|
|
|
2313
2361
|
if (row)
|
|
2314
2362
|
row.setFlaggedClass(yes);
|
|
2315
2363
|
}
|
|
2364
|
+
function setRowSeen(accountId, uid, yes) {
|
|
2365
|
+
const row = rowByKey.get(rowKey(accountId, uid));
|
|
2366
|
+
if (row)
|
|
2367
|
+
row.setUnreadClass(!yes);
|
|
2368
|
+
}
|
|
2316
2369
|
function scrollFocusedIntoView() {
|
|
2317
2370
|
if (focusedRow)
|
|
2318
2371
|
focusedRow.el.scrollIntoView({ block: "center" });
|
|
@@ -2803,7 +2856,7 @@ async function showThreadPopup(pillEl, headMsg) {
|
|
|
2803
2856
|
for (const msg of thread) {
|
|
2804
2857
|
const item = document.createElement("div");
|
|
2805
2858
|
item.className = "ml-thread-popup-item";
|
|
2806
|
-
if (!msg
|
|
2859
|
+
if (!seenOf(msg))
|
|
2807
2860
|
item.classList.add("unread");
|
|
2808
2861
|
const from = document.createElement("span");
|
|
2809
2862
|
from.className = "ml-thread-popup-from";
|
|
@@ -2908,6 +2961,7 @@ var init_message_list = __esm({
|
|
|
2908
2961
|
init_message_viewer();
|
|
2909
2962
|
init_context_menu();
|
|
2910
2963
|
init_folder_picker();
|
|
2964
|
+
init_mailx_types();
|
|
2911
2965
|
currentSpecialUse = "";
|
|
2912
2966
|
lastClickedRow = null;
|
|
2913
2967
|
loading = false;
|
|
@@ -2970,9 +3024,9 @@ var init_message_list = __esm({
|
|
|
2970
3024
|
this.el = row;
|
|
2971
3025
|
row.className = "ml-row";
|
|
2972
3026
|
row.draggable = true;
|
|
2973
|
-
if (!msg
|
|
3027
|
+
if (!seenOf(msg))
|
|
2974
3028
|
row.classList.add("unread");
|
|
2975
|
-
if (msg
|
|
3029
|
+
if (flaggedOf(msg))
|
|
2976
3030
|
row.classList.add("flagged");
|
|
2977
3031
|
if (!msg.bodyPath)
|
|
2978
3032
|
row.classList.add("not-downloaded");
|
|
@@ -3001,7 +3055,7 @@ var init_message_list = __esm({
|
|
|
3001
3055
|
avatar.addEventListener("contextmenu", (e) => this.onAvatarContextMenu(e));
|
|
3002
3056
|
const flag = document.createElement("span");
|
|
3003
3057
|
flag.className = "ml-flag";
|
|
3004
|
-
flag.textContent = msg
|
|
3058
|
+
flag.textContent = flaggedOf(msg) ? "\u2605" : "\u2606";
|
|
3005
3059
|
flag.title = "Toggle flag";
|
|
3006
3060
|
flag.addEventListener("click", (e) => this.onFlagClick(e));
|
|
3007
3061
|
this.flagEl = flag;
|
|
@@ -3097,6 +3151,28 @@ var init_message_list = __esm({
|
|
|
3097
3151
|
markBodyCached() {
|
|
3098
3152
|
this.el.classList.remove("not-downloaded");
|
|
3099
3153
|
}
|
|
3154
|
+
// Visual-state accessors for flag toggles. Read the *visual* state
|
|
3155
|
+
// (CSS class), not `this.msg.flags`, because the flag array can lag
|
|
3156
|
+
// the rendered class — auto-mark-as-read removes the `unread` class
|
|
3157
|
+
// immediately on click but `\Seen` doesn't land in `msg.flags` until
|
|
3158
|
+
// the auto-mark timer fires (default 2 s). Right-click menus and
|
|
3159
|
+
// keyboard shortcuts ask "what does the user see?" — that's what
|
|
3160
|
+
// these getters answer. Setters keep both visual + flag-array in
|
|
3161
|
+
// sync so the next read by either side agrees.
|
|
3162
|
+
get isSeen() {
|
|
3163
|
+
return !this.el.classList.contains("unread");
|
|
3164
|
+
}
|
|
3165
|
+
set isSeen(yes) {
|
|
3166
|
+
this.setUnreadClass(!yes);
|
|
3167
|
+
setSeen(this.msg, yes);
|
|
3168
|
+
}
|
|
3169
|
+
get isFlagged() {
|
|
3170
|
+
return this.el.classList.contains("flagged");
|
|
3171
|
+
}
|
|
3172
|
+
set isFlagged(yes) {
|
|
3173
|
+
this.setFlaggedClass(yes);
|
|
3174
|
+
setFlagged(this.msg, yes);
|
|
3175
|
+
}
|
|
3100
3176
|
onAvatarClick(e) {
|
|
3101
3177
|
e.stopPropagation();
|
|
3102
3178
|
const body = document.getElementById("ml-body");
|
|
@@ -3155,13 +3231,13 @@ var init_message_list = __esm({
|
|
|
3155
3231
|
}
|
|
3156
3232
|
async onFlagClick(e) {
|
|
3157
3233
|
e.stopPropagation();
|
|
3158
|
-
const
|
|
3159
|
-
const
|
|
3160
|
-
|
|
3234
|
+
const newFlaggedState = !this.el.classList.contains("flagged");
|
|
3235
|
+
const probe = { flags: [...this.msg.flags || []] };
|
|
3236
|
+
setFlagged(probe, newFlaggedState);
|
|
3161
3237
|
try {
|
|
3162
|
-
await updateFlags(this.accountId, this.msg.uid,
|
|
3163
|
-
this.msg.flags =
|
|
3164
|
-
this.setFlaggedClass(
|
|
3238
|
+
await updateFlags(this.accountId, this.msg.uid, probe.flags);
|
|
3239
|
+
this.msg.flags = probe.flags;
|
|
3240
|
+
this.setFlaggedClass(newFlaggedState);
|
|
3165
3241
|
} catch {
|
|
3166
3242
|
}
|
|
3167
3243
|
}
|
|
@@ -3175,10 +3251,8 @@ var init_message_list = __esm({
|
|
|
3175
3251
|
const willBeSelected = !this.isSelected;
|
|
3176
3252
|
this.setSelected(willBeSelected);
|
|
3177
3253
|
lastClickedRow = this.el;
|
|
3178
|
-
if (willBeSelected)
|
|
3254
|
+
if (willBeSelected)
|
|
3179
3255
|
focusRow(this);
|
|
3180
|
-
this.setUnreadClass(false);
|
|
3181
|
-
}
|
|
3182
3256
|
updateBulkBar();
|
|
3183
3257
|
return;
|
|
3184
3258
|
}
|
|
@@ -3188,13 +3262,11 @@ var init_message_list = __esm({
|
|
|
3188
3262
|
clearSelection();
|
|
3189
3263
|
selectRange(anchor, this.el);
|
|
3190
3264
|
lastClickedRow = this.el;
|
|
3191
|
-
this.setUnreadClass(false);
|
|
3192
3265
|
focusRow(this);
|
|
3193
3266
|
} else {
|
|
3194
3267
|
clearSelection();
|
|
3195
3268
|
focusRow(this);
|
|
3196
3269
|
lastClickedRow = this.el;
|
|
3197
|
-
this.setUnreadClass(false);
|
|
3198
3270
|
}
|
|
3199
3271
|
} else if (e.ctrlKey || e.metaKey) {
|
|
3200
3272
|
this.setSelected(!this.isSelected);
|
|
@@ -3203,7 +3275,6 @@ var init_message_list = __esm({
|
|
|
3203
3275
|
clearSelection();
|
|
3204
3276
|
focusRow(this);
|
|
3205
3277
|
lastClickedRow = this.el;
|
|
3206
|
-
this.setUnreadClass(false);
|
|
3207
3278
|
}
|
|
3208
3279
|
updateBulkBar();
|
|
3209
3280
|
}
|
|
@@ -3289,7 +3360,7 @@ var init_message_list = __esm({
|
|
|
3289
3360
|
}
|
|
3290
3361
|
}
|
|
3291
3362
|
const isSeen = !this.el.classList.contains("unread");
|
|
3292
|
-
const isFlagged = this.
|
|
3363
|
+
const isFlagged = this.el.classList.contains("flagged");
|
|
3293
3364
|
const accountId = this.accountId;
|
|
3294
3365
|
const msg = this.msg;
|
|
3295
3366
|
const self = this;
|
|
@@ -3297,17 +3368,13 @@ var init_message_list = __esm({
|
|
|
3297
3368
|
{
|
|
3298
3369
|
label: isSeen ? "Mark unread" : "Mark read",
|
|
3299
3370
|
action: async () => {
|
|
3300
|
-
const
|
|
3301
|
-
|
|
3302
|
-
set.delete("\\Seen");
|
|
3303
|
-
else
|
|
3304
|
-
set.add("\\Seen");
|
|
3305
|
-
const newFlags = Array.from(set);
|
|
3371
|
+
const probe = { flags: [...msg.flags || []] };
|
|
3372
|
+
setSeen(probe, !isSeen);
|
|
3306
3373
|
try {
|
|
3307
|
-
await updateFlags(accountId, msg.uid,
|
|
3308
|
-
msg.flags =
|
|
3309
|
-
updateMessageFlags(accountId, msg.uid,
|
|
3310
|
-
self.setUnreadClass(
|
|
3374
|
+
await updateFlags(accountId, msg.uid, probe.flags);
|
|
3375
|
+
msg.flags = probe.flags;
|
|
3376
|
+
updateMessageFlags(accountId, msg.uid, probe.flags);
|
|
3377
|
+
self.setUnreadClass(isSeen);
|
|
3311
3378
|
} catch {
|
|
3312
3379
|
}
|
|
3313
3380
|
}
|
|
@@ -3315,11 +3382,12 @@ var init_message_list = __esm({
|
|
|
3315
3382
|
{
|
|
3316
3383
|
label: isFlagged ? "Unflag" : "Flag",
|
|
3317
3384
|
action: async () => {
|
|
3318
|
-
const
|
|
3385
|
+
const probe = { flags: [...msg.flags || []] };
|
|
3386
|
+
setFlagged(probe, !isFlagged);
|
|
3319
3387
|
try {
|
|
3320
|
-
await updateFlags(accountId, msg.uid,
|
|
3321
|
-
msg.flags =
|
|
3322
|
-
self.setFlaggedClass(
|
|
3388
|
+
await updateFlags(accountId, msg.uid, probe.flags);
|
|
3389
|
+
msg.flags = probe.flags;
|
|
3390
|
+
self.setFlaggedClass(!isFlagged);
|
|
3323
3391
|
} catch {
|
|
3324
3392
|
}
|
|
3325
3393
|
}
|
|
@@ -5805,6 +5873,7 @@ async function updateFolderCounts() {
|
|
|
5805
5873
|
|
|
5806
5874
|
// client/app.ts
|
|
5807
5875
|
init_message_list();
|
|
5876
|
+
init_mailx_types();
|
|
5808
5877
|
init_message_viewer();
|
|
5809
5878
|
init_api_client();
|
|
5810
5879
|
init_message_state();
|
|
@@ -6711,14 +6780,14 @@ document.getElementById("btn-tb-spam")?.addEventListener("click", spamSelectedMe
|
|
|
6711
6780
|
document.getElementById("btn-flag")?.addEventListener("click", async () => {
|
|
6712
6781
|
const sel = getCurrentFocused();
|
|
6713
6782
|
if (!sel) return;
|
|
6714
|
-
const
|
|
6715
|
-
|
|
6783
|
+
const wasFlagged = flaggedOf(sel);
|
|
6784
|
+
setFlagged(sel, !wasFlagged);
|
|
6716
6785
|
try {
|
|
6717
|
-
await updateFlags(sel.accountId, sel.uid,
|
|
6718
|
-
sel.
|
|
6719
|
-
|
|
6720
|
-
setRowFlagged(sel.accountId, sel.uid, newFlags.includes("\\Flagged"));
|
|
6786
|
+
await updateFlags(sel.accountId, sel.uid, sel.flags);
|
|
6787
|
+
updateMessageFlags(sel.accountId, sel.uid, sel.flags);
|
|
6788
|
+
setRowFlagged(sel.accountId, sel.uid, !wasFlagged);
|
|
6721
6789
|
} catch (e) {
|
|
6790
|
+
setFlagged(sel, wasFlagged);
|
|
6722
6791
|
console.error(`Flag toggle failed: ${e.message}`);
|
|
6723
6792
|
}
|
|
6724
6793
|
});
|
|
@@ -6807,14 +6876,14 @@ document.getElementById("btn-compose")?.addEventListener("click", () => openComp
|
|
|
6807
6876
|
document.getElementById("btn-mark-unread")?.addEventListener("click", () => {
|
|
6808
6877
|
const sel = getCurrentFocused();
|
|
6809
6878
|
if (!sel) return;
|
|
6810
|
-
const
|
|
6811
|
-
|
|
6812
|
-
updateFlags(sel.accountId, sel.uid,
|
|
6813
|
-
sel.
|
|
6814
|
-
updateMessageFlags(sel.accountId, sel.uid, newFlags);
|
|
6879
|
+
const wasSeen = seenOf(sel);
|
|
6880
|
+
setSeen(sel, !wasSeen);
|
|
6881
|
+
updateFlags(sel.accountId, sel.uid, sel.flags).then(() => {
|
|
6882
|
+
updateMessageFlags(sel.accountId, sel.uid, sel.flags);
|
|
6815
6883
|
const row = document.querySelector(`.ml-row[data-uid="${sel.uid}"][data-account-id="${sel.accountId}"]`);
|
|
6816
|
-
if (row) row.classList.toggle("unread",
|
|
6884
|
+
if (row) row.classList.toggle("unread", wasSeen);
|
|
6817
6885
|
}).catch(() => {
|
|
6886
|
+
setSeen(sel, wasSeen);
|
|
6818
6887
|
});
|
|
6819
6888
|
});
|
|
6820
6889
|
document.getElementById("btn-reply")?.addEventListener("click", () => openCompose("reply"));
|
|
@@ -7828,14 +7897,14 @@ document.addEventListener("keydown", (e) => {
|
|
|
7828
7897
|
const sel = getCurrentFocused();
|
|
7829
7898
|
if (!sel) return;
|
|
7830
7899
|
e.preventDefault();
|
|
7831
|
-
const
|
|
7832
|
-
|
|
7833
|
-
updateFlags(sel.accountId, sel.uid,
|
|
7834
|
-
sel.
|
|
7835
|
-
updateMessageFlags(sel.accountId, sel.uid, newFlags);
|
|
7900
|
+
const wasSeen = seenOf(sel);
|
|
7901
|
+
setSeen(sel, !wasSeen);
|
|
7902
|
+
updateFlags(sel.accountId, sel.uid, sel.flags).then(() => {
|
|
7903
|
+
updateMessageFlags(sel.accountId, sel.uid, sel.flags);
|
|
7836
7904
|
const row = document.querySelector(`.ml-row[data-uid="${sel.uid}"][data-account-id="${sel.accountId}"]`);
|
|
7837
|
-
if (row) row.classList.toggle("unread",
|
|
7905
|
+
if (row) row.classList.toggle("unread", wasSeen);
|
|
7838
7906
|
}).catch(() => {
|
|
7907
|
+
setSeen(sel, wasSeen);
|
|
7839
7908
|
});
|
|
7840
7909
|
}
|
|
7841
7910
|
if (e.key.toLowerCase() === "z" && !e.ctrlKey && !e.metaKey && !e.altKey) {
|
|
@@ -9173,7 +9242,7 @@ document.addEventListener("mailx-popout-message", (async (e) => {
|
|
|
9173
9242
|
alert(`Couldn't load message: ${err?.message || err}`);
|
|
9174
9243
|
return;
|
|
9175
9244
|
}
|
|
9176
|
-
const isDraft =
|
|
9245
|
+
const isDraft = !!msg && draftOf(msg);
|
|
9177
9246
|
if (isDraft) {
|
|
9178
9247
|
const accts = await getAccounts();
|
|
9179
9248
|
const init = {
|