@bobfrankston/rmfmail 1.0.701 → 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.
@@ -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.flags.includes("\\Seen")) {
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 newFlags = [...msg.flags, "\\Seen"];
1063
- if (delaySec === 0) {
1064
- updateFlags(accountId, uid, newFlags);
1065
- } else {
1066
- setTimeout(() => {
1067
- if (captureGen !== showMessageGeneration)
1068
- return;
1069
- updateFlags(accountId, uid, newFlags);
1070
- msg.flags = newFlags;
1071
- try {
1072
- updateMessageFlags(accountId, uid, newFlags);
1073
- } catch {
1074
- }
1075
- }, delaySec * 1e3);
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;
@@ -2175,69 +2222,6 @@ var init_folder_picker = __esm({
2175
2222
  }
2176
2223
  });
2177
2224
 
2178
- // packages/mailx-types/contact-rules.js
2179
- var init_contact_rules = __esm({
2180
- "packages/mailx-types/contact-rules.js"() {
2181
- "use strict";
2182
- }
2183
- });
2184
-
2185
- // packages/mailx-types/groups.js
2186
- var init_groups = __esm({
2187
- "packages/mailx-types/groups.js"() {
2188
- "use strict";
2189
- }
2190
- });
2191
-
2192
- // packages/mailx-types/index.js
2193
- var FLAG, flagOps;
2194
- var init_mailx_types = __esm({
2195
- "packages/mailx-types/index.js"() {
2196
- "use strict";
2197
- init_contact_rules();
2198
- init_groups();
2199
- FLAG = {
2200
- SEEN: "\\Seen",
2201
- FLAGGED: "\\Flagged",
2202
- DELETED: "\\Deleted",
2203
- DRAFT: "\\Draft",
2204
- ANSWERED: "\\Answered",
2205
- RECENT: "\\Recent"
2206
- };
2207
- flagOps = {
2208
- has(flags, f) {
2209
- return !!flags && flags.includes(f);
2210
- },
2211
- isSeen(flags) {
2212
- return flagOps.has(flags, FLAG.SEEN);
2213
- },
2214
- isFlagged(flags) {
2215
- return flagOps.has(flags, FLAG.FLAGGED);
2216
- },
2217
- isAnswered(flags) {
2218
- return flagOps.has(flags, FLAG.ANSWERED);
2219
- },
2220
- isDraft(flags) {
2221
- return flagOps.has(flags, FLAG.DRAFT);
2222
- },
2223
- /** Return flags with `f` added (dedup). */
2224
- add(flags, f) {
2225
- const set = new Set(flags || []);
2226
- set.add(f);
2227
- return Array.from(set);
2228
- },
2229
- /** Return flags with `f` removed. */
2230
- remove(flags, f) {
2231
- return (flags || []).filter((x) => x !== f);
2232
- },
2233
- /** Return flags with `f` toggled to `state` (true=present, false=absent). */
2234
- set(flags, f, state) {
2235
- return state ? flagOps.add(flags, f) : flagOps.remove(flags, f);
2236
- }
2237
- };
2238
- }
2239
- });
2240
-
2241
2225
  // client/components/message-list.js
2242
2226
  var message_list_exports = {};
2243
2227
  __export(message_list_exports, {
@@ -2255,6 +2239,7 @@ __export(message_list_exports, {
2255
2239
  removeMessagesAndReconcile: () => removeMessagesAndReconcile,
2256
2240
  scrollFocusedIntoView: () => scrollFocusedIntoView,
2257
2241
  setRowFlagged: () => setRowFlagged,
2242
+ setRowSeen: () => setRowSeen,
2258
2243
  showThreadPopup: () => showThreadPopup
2259
2244
  });
2260
2245
  function cacheKey(mode, a, f, flagged, q) {
@@ -2376,6 +2361,11 @@ function setRowFlagged(accountId, uid, yes) {
2376
2361
  if (row)
2377
2362
  row.setFlaggedClass(yes);
2378
2363
  }
2364
+ function setRowSeen(accountId, uid, yes) {
2365
+ const row = rowByKey.get(rowKey(accountId, uid));
2366
+ if (row)
2367
+ row.setUnreadClass(!yes);
2368
+ }
2379
2369
  function scrollFocusedIntoView() {
2380
2370
  if (focusedRow)
2381
2371
  focusedRow.el.scrollIntoView({ block: "center" });
@@ -2866,7 +2856,7 @@ async function showThreadPopup(pillEl, headMsg) {
2866
2856
  for (const msg of thread) {
2867
2857
  const item = document.createElement("div");
2868
2858
  item.className = "ml-thread-popup-item";
2869
- if (!flagOps.isSeen(msg.flags))
2859
+ if (!seenOf(msg))
2870
2860
  item.classList.add("unread");
2871
2861
  const from = document.createElement("span");
2872
2862
  from.className = "ml-thread-popup-from";
@@ -3034,9 +3024,9 @@ var init_message_list = __esm({
3034
3024
  this.el = row;
3035
3025
  row.className = "ml-row";
3036
3026
  row.draggable = true;
3037
- if (!flagOps.isSeen(msg.flags))
3027
+ if (!seenOf(msg))
3038
3028
  row.classList.add("unread");
3039
- if (flagOps.isFlagged(msg.flags))
3029
+ if (flaggedOf(msg))
3040
3030
  row.classList.add("flagged");
3041
3031
  if (!msg.bodyPath)
3042
3032
  row.classList.add("not-downloaded");
@@ -3065,7 +3055,7 @@ var init_message_list = __esm({
3065
3055
  avatar.addEventListener("contextmenu", (e) => this.onAvatarContextMenu(e));
3066
3056
  const flag = document.createElement("span");
3067
3057
  flag.className = "ml-flag";
3068
- flag.textContent = flagOps.isFlagged(msg.flags) ? "\u2605" : "\u2606";
3058
+ flag.textContent = flaggedOf(msg) ? "\u2605" : "\u2606";
3069
3059
  flag.title = "Toggle flag";
3070
3060
  flag.addEventListener("click", (e) => this.onFlagClick(e));
3071
3061
  this.flagEl = flag;
@@ -3174,14 +3164,14 @@ var init_message_list = __esm({
3174
3164
  }
3175
3165
  set isSeen(yes) {
3176
3166
  this.setUnreadClass(!yes);
3177
- this.msg.flags = flagOps.set(this.msg.flags, FLAG.SEEN, yes);
3167
+ setSeen(this.msg, yes);
3178
3168
  }
3179
3169
  get isFlagged() {
3180
3170
  return this.el.classList.contains("flagged");
3181
3171
  }
3182
3172
  set isFlagged(yes) {
3183
3173
  this.setFlaggedClass(yes);
3184
- this.msg.flags = flagOps.set(this.msg.flags, FLAG.FLAGGED, yes);
3174
+ setFlagged(this.msg, yes);
3185
3175
  }
3186
3176
  onAvatarClick(e) {
3187
3177
  e.stopPropagation();
@@ -3241,13 +3231,13 @@ var init_message_list = __esm({
3241
3231
  }
3242
3232
  async onFlagClick(e) {
3243
3233
  e.stopPropagation();
3244
- const isFlagged = this.el.classList.contains("flagged");
3245
- const currentFlags = this.msg.flags || [];
3246
- const newFlags = isFlagged ? flagOps.remove(currentFlags, FLAG.FLAGGED) : flagOps.add(currentFlags, FLAG.FLAGGED);
3234
+ const newFlaggedState = !this.el.classList.contains("flagged");
3235
+ const probe = { flags: [...this.msg.flags || []] };
3236
+ setFlagged(probe, newFlaggedState);
3247
3237
  try {
3248
- await updateFlags(this.accountId, this.msg.uid, newFlags);
3249
- this.msg.flags = newFlags;
3250
- this.setFlaggedClass(!isFlagged);
3238
+ await updateFlags(this.accountId, this.msg.uid, probe.flags);
3239
+ this.msg.flags = probe.flags;
3240
+ this.setFlaggedClass(newFlaggedState);
3251
3241
  } catch {
3252
3242
  }
3253
3243
  }
@@ -3261,10 +3251,8 @@ var init_message_list = __esm({
3261
3251
  const willBeSelected = !this.isSelected;
3262
3252
  this.setSelected(willBeSelected);
3263
3253
  lastClickedRow = this.el;
3264
- if (willBeSelected) {
3254
+ if (willBeSelected)
3265
3255
  focusRow(this);
3266
- this.setUnreadClass(false);
3267
- }
3268
3256
  updateBulkBar();
3269
3257
  return;
3270
3258
  }
@@ -3274,13 +3262,11 @@ var init_message_list = __esm({
3274
3262
  clearSelection();
3275
3263
  selectRange(anchor, this.el);
3276
3264
  lastClickedRow = this.el;
3277
- this.setUnreadClass(false);
3278
3265
  focusRow(this);
3279
3266
  } else {
3280
3267
  clearSelection();
3281
3268
  focusRow(this);
3282
3269
  lastClickedRow = this.el;
3283
- this.setUnreadClass(false);
3284
3270
  }
3285
3271
  } else if (e.ctrlKey || e.metaKey) {
3286
3272
  this.setSelected(!this.isSelected);
@@ -3289,7 +3275,6 @@ var init_message_list = __esm({
3289
3275
  clearSelection();
3290
3276
  focusRow(this);
3291
3277
  lastClickedRow = this.el;
3292
- this.setUnreadClass(false);
3293
3278
  }
3294
3279
  updateBulkBar();
3295
3280
  }
@@ -3375,7 +3360,7 @@ var init_message_list = __esm({
3375
3360
  }
3376
3361
  }
3377
3362
  const isSeen = !this.el.classList.contains("unread");
3378
- const isFlagged = flagOps.isFlagged(this.msg.flags);
3363
+ const isFlagged = this.el.classList.contains("flagged");
3379
3364
  const accountId = this.accountId;
3380
3365
  const msg = this.msg;
3381
3366
  const self = this;
@@ -3383,12 +3368,13 @@ var init_message_list = __esm({
3383
3368
  {
3384
3369
  label: isSeen ? "Mark unread" : "Mark read",
3385
3370
  action: async () => {
3386
- const newFlags = flagOps.set(msg.flags, FLAG.SEEN, !isSeen);
3371
+ const probe = { flags: [...msg.flags || []] };
3372
+ setSeen(probe, !isSeen);
3387
3373
  try {
3388
- await updateFlags(accountId, msg.uid, newFlags);
3389
- msg.flags = newFlags;
3390
- updateMessageFlags(accountId, msg.uid, newFlags);
3391
- self.setUnreadClass(!flagOps.isSeen(newFlags));
3374
+ await updateFlags(accountId, msg.uid, probe.flags);
3375
+ msg.flags = probe.flags;
3376
+ updateMessageFlags(accountId, msg.uid, probe.flags);
3377
+ self.setUnreadClass(isSeen);
3392
3378
  } catch {
3393
3379
  }
3394
3380
  }
@@ -3396,11 +3382,12 @@ var init_message_list = __esm({
3396
3382
  {
3397
3383
  label: isFlagged ? "Unflag" : "Flag",
3398
3384
  action: async () => {
3399
- const newFlags = flagOps.set(msg.flags, FLAG.FLAGGED, !isFlagged);
3385
+ const probe = { flags: [...msg.flags || []] };
3386
+ setFlagged(probe, !isFlagged);
3400
3387
  try {
3401
- await updateFlags(accountId, msg.uid, newFlags);
3402
- msg.flags = newFlags;
3403
- self.setFlaggedClass(flagOps.isFlagged(newFlags));
3388
+ await updateFlags(accountId, msg.uid, probe.flags);
3389
+ msg.flags = probe.flags;
3390
+ self.setFlaggedClass(!isFlagged);
3404
3391
  } catch {
3405
3392
  }
3406
3393
  }
@@ -6793,14 +6780,14 @@ document.getElementById("btn-tb-spam")?.addEventListener("click", spamSelectedMe
6793
6780
  document.getElementById("btn-flag")?.addEventListener("click", async () => {
6794
6781
  const sel = getCurrentFocused();
6795
6782
  if (!sel) return;
6796
- const isFlagged = flagOps.isFlagged(sel.flags);
6797
- const newFlags = isFlagged ? flagOps.remove(sel.flags, FLAG.FLAGGED) : flagOps.add(sel.flags, FLAG.FLAGGED);
6783
+ const wasFlagged = flaggedOf(sel);
6784
+ setFlagged(sel, !wasFlagged);
6798
6785
  try {
6799
- await updateFlags(sel.accountId, sel.uid, newFlags);
6800
- sel.flags = newFlags;
6801
- updateMessageFlags(sel.accountId, sel.uid, newFlags);
6802
- setRowFlagged(sel.accountId, sel.uid, flagOps.isFlagged(newFlags));
6786
+ await updateFlags(sel.accountId, sel.uid, sel.flags);
6787
+ updateMessageFlags(sel.accountId, sel.uid, sel.flags);
6788
+ setRowFlagged(sel.accountId, sel.uid, !wasFlagged);
6803
6789
  } catch (e) {
6790
+ setFlagged(sel, wasFlagged);
6804
6791
  console.error(`Flag toggle failed: ${e.message}`);
6805
6792
  }
6806
6793
  });
@@ -6889,14 +6876,14 @@ document.getElementById("btn-compose")?.addEventListener("click", () => openComp
6889
6876
  document.getElementById("btn-mark-unread")?.addEventListener("click", () => {
6890
6877
  const sel = getCurrentFocused();
6891
6878
  if (!sel) return;
6892
- const isSeen = flagOps.isSeen(sel.flags);
6893
- const newFlags = flagOps.set(sel.flags, FLAG.SEEN, !isSeen);
6894
- updateFlags(sel.accountId, sel.uid, newFlags).then(() => {
6895
- sel.flags = newFlags;
6896
- 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);
6897
6883
  const row = document.querySelector(`.ml-row[data-uid="${sel.uid}"][data-account-id="${sel.accountId}"]`);
6898
- if (row) row.classList.toggle("unread", !flagOps.isSeen(newFlags));
6884
+ if (row) row.classList.toggle("unread", wasSeen);
6899
6885
  }).catch(() => {
6886
+ setSeen(sel, wasSeen);
6900
6887
  });
6901
6888
  });
6902
6889
  document.getElementById("btn-reply")?.addEventListener("click", () => openCompose("reply"));
@@ -7910,14 +7897,14 @@ document.addEventListener("keydown", (e) => {
7910
7897
  const sel = getCurrentFocused();
7911
7898
  if (!sel) return;
7912
7899
  e.preventDefault();
7913
- const isSeen = flagOps.isSeen(sel.flags);
7914
- const newFlags = flagOps.set(sel.flags, FLAG.SEEN, !isSeen);
7915
- updateFlags(sel.accountId, sel.uid, newFlags).then(() => {
7916
- sel.flags = newFlags;
7917
- 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);
7918
7904
  const row = document.querySelector(`.ml-row[data-uid="${sel.uid}"][data-account-id="${sel.accountId}"]`);
7919
- if (row) row.classList.toggle("unread", !flagOps.isSeen(newFlags));
7905
+ if (row) row.classList.toggle("unread", wasSeen);
7920
7906
  }).catch(() => {
7907
+ setSeen(sel, wasSeen);
7921
7908
  });
7922
7909
  }
7923
7910
  if (e.key.toLowerCase() === "z" && !e.ctrlKey && !e.metaKey && !e.altKey) {
@@ -9255,7 +9242,7 @@ document.addEventListener("mailx-popout-message", (async (e) => {
9255
9242
  alert(`Couldn't load message: ${err?.message || err}`);
9256
9243
  return;
9257
9244
  }
9258
- const isDraft = Array.isArray(msg?.flags) && flagOps.isDraft(msg.flags);
9245
+ const isDraft = !!msg && draftOf(msg);
9259
9246
  if (isDraft) {
9260
9247
  const accts = await getAccounts();
9261
9248
  const init = {