@bobfrankston/rmfmail 1.2.224 → 1.2.225

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.
@@ -970,10 +970,15 @@ function removeMessages(uids, currentlyFocused) {
970
970
  nextSurvivor: nextSurvivor ? { accountId: nextSurvivor.accountId, uid: nextSurvivor.uid, folderId: nextSurvivor.folderId } : null
971
971
  };
972
972
  }
973
- function updateMessageFlags(accountId, uid, flags) {
974
- const msg = messages.find((m) => m.uid === uid && m.accountId === accountId);
975
- if (msg)
976
- msg.flags = flags;
973
+ function updateMessageFlags(accountId, uid, flags, folderId) {
974
+ const candidates = messages.filter((m) => m.uid === uid && m.accountId === accountId && (folderId === void 0 || m.folderId === folderId));
975
+ if (candidates.length === 1) {
976
+ candidates[0].flags = flags;
977
+ return;
978
+ }
979
+ if (candidates.length > 1) {
980
+ console.warn(`[message-state] ambiguous flag update ${accountId}/uid=${uid} \u2014 ${candidates.length} folders match; caller must pass folderId`);
981
+ }
977
982
  }
978
983
  var messages, listeners;
979
984
  var init_message_state = __esm({
@@ -1939,11 +1944,11 @@ async function showMessage(accountId, uid, folderId, specialUse, isRetry = false
1939
1944
  setSeen(msg, true);
1940
1945
  updateFlags(accountId, uid, msg.flags, msg.folderId);
1941
1946
  try {
1942
- updateMessageFlags(accountId, uid, msg.flags);
1947
+ updateMessageFlags(accountId, uid, msg.flags, msg.folderId);
1943
1948
  } catch {
1944
1949
  }
1945
1950
  try {
1946
- setRowSeen(accountId, uid, true);
1951
+ setRowSeen(accountId, uid, true, msg.folderId);
1947
1952
  } catch {
1948
1953
  }
1949
1954
  };
@@ -3685,8 +3690,26 @@ async function refreshPriorityIndex() {
3685
3690
  } catch {
3686
3691
  }
3687
3692
  }
3688
- function rowKey(accountId, uid) {
3689
- return `${accountId}:${uid}`;
3693
+ function rowKey(accountId, uid, folderId) {
3694
+ return `${accountId}:${folderId ?? ""}:${uid}`;
3695
+ }
3696
+ function findRow(accountId, uid, folderId) {
3697
+ if (folderId !== void 0 && folderId !== null) {
3698
+ const exact = rowByKey.get(rowKey(accountId, uid, folderId));
3699
+ if (exact)
3700
+ return exact;
3701
+ }
3702
+ const hits = [];
3703
+ for (const row of rowByKey.values()) {
3704
+ if (row.accountId === accountId && row.msg.uid === uid)
3705
+ hits.push(row);
3706
+ }
3707
+ if (hits.length === 1)
3708
+ return hits[0];
3709
+ if (hits.length > 1) {
3710
+ console.warn(`[message-list] ambiguous row lookup ${accountId}/uid=${uid} \u2014 ${hits.length} folders match; caller must pass folderId`);
3711
+ }
3712
+ return void 0;
3690
3713
  }
3691
3714
  function focusRow(row, opts = {}) {
3692
3715
  const body = row.el.parentElement;
@@ -3720,26 +3743,26 @@ function getCurrentFocused() {
3720
3743
  return focusedRow ? focusedRow.msg : null;
3721
3744
  }
3722
3745
  function focusByIdentity(accountId, uid, opts = {}) {
3723
- const row = rowByKey.get(rowKey(accountId, uid));
3746
+ const row = findRow(accountId, uid, opts.folderId);
3724
3747
  if (!row)
3725
3748
  return false;
3726
3749
  focusRow(row, opts);
3727
3750
  return true;
3728
3751
  }
3729
- function setRowFlagged(accountId, uid, yes) {
3730
- const row = rowByKey.get(rowKey(accountId, uid));
3752
+ function setRowFlagged(accountId, uid, yes, folderId) {
3753
+ const row = findRow(accountId, uid, folderId);
3731
3754
  if (row)
3732
3755
  row.setFlaggedClass(yes);
3733
3756
  }
3734
- function setRowSeen(accountId, uid, yes) {
3735
- const row = rowByKey.get(rowKey(accountId, uid));
3757
+ function setRowSeen(accountId, uid, yes, folderId) {
3758
+ const row = findRow(accountId, uid, folderId);
3736
3759
  if (row)
3737
3760
  row.setUnreadClass(!yes);
3738
3761
  }
3739
3762
  function selectedRows() {
3740
3763
  const out = [];
3741
3764
  for (const s of getSelectedMessages()) {
3742
- const row = rowByKey.get(rowKey(s.accountId, s.uid));
3765
+ const row = findRow(s.accountId, s.uid, s.folderId);
3743
3766
  if (row)
3744
3767
  out.push(row);
3745
3768
  }
@@ -3749,7 +3772,7 @@ function visibleRowObjs() {
3749
3772
  const body = document.getElementById("ml-body");
3750
3773
  if (!body)
3751
3774
  return [];
3752
- return Array.from(body.querySelectorAll(".ml-row:not(.filter-hidden)")).map((el) => rowByKey.get(rowKey(el.dataset.accountId || "", Number(el.dataset.uid)))).filter((r) => !!r);
3775
+ return Array.from(body.querySelectorAll(".ml-row:not(.filter-hidden)")).map((el) => rowByKey.get(rowKey(el.dataset.accountId || "", Number(el.dataset.uid), el.dataset.folderId))).filter((r) => !!r);
3753
3776
  }
3754
3777
  function bulkTargets() {
3755
3778
  const sel = selectedRows();
@@ -3915,6 +3938,9 @@ function releaseFocus() {
3915
3938
  const body = document.getElementById("ml-body");
3916
3939
  body?.querySelectorAll(".ml-row.selected").forEach((r) => r.classList.remove("selected"));
3917
3940
  clearViewer();
3941
+ document.body.classList.remove("viewer-fullscreen");
3942
+ document.getElementById("message-viewer")?.classList.remove("narrow-active");
3943
+ document.getElementById("message-list")?.classList.remove("narrow-hidden");
3918
3944
  document.dispatchEvent(new CustomEvent("mailx-focus-changed", { detail: null }));
3919
3945
  }
3920
3946
  function markBodiesCached(items) {
@@ -4142,7 +4168,7 @@ function removeMessagesAndReconcile(uids) {
4142
4168
  const el = row;
4143
4169
  const key = `${el.dataset.accountId}:${el.dataset.folderId}:${el.dataset.uid}`;
4144
4170
  if (!stateUids.has(key)) {
4145
- const dead = rowByKey.get(rowKey(el.dataset.accountId || "", Number(el.dataset.uid)));
4171
+ const dead = rowByKey.get(rowKey(el.dataset.accountId || "", Number(el.dataset.uid), el.dataset.folderId));
4146
4172
  if (dead && dead.el === el)
4147
4173
  dead.detach();
4148
4174
  else
@@ -4155,12 +4181,12 @@ function removeMessagesAndReconcile(uids) {
4155
4181
  }
4156
4182
  if (outcome.focusedWasRemoved) {
4157
4183
  const survivor = outcome.nextSurvivor;
4158
- if (survivor && focusByIdentity(survivor.accountId, survivor.uid)) {
4184
+ if (survivor && focusByIdentity(survivor.accountId, survivor.uid, { folderId: survivor.folderId })) {
4159
4185
  return;
4160
4186
  }
4161
4187
  const remaining = getMessages2();
4162
4188
  for (const m of remaining) {
4163
- if (focusByIdentity(m.accountId, m.uid))
4189
+ if (focusByIdentity(m.accountId, m.uid, { folderId: m.folderId }))
4164
4190
  return;
4165
4191
  }
4166
4192
  releaseFocus();
@@ -4910,7 +4936,7 @@ var init_message_list = __esm({
4910
4936
  /** Insert this row into a list body and register it in the lookup map. */
4911
4937
  attach(body) {
4912
4938
  body.appendChild(this.el);
4913
- rowByKey.set(rowKey(this.accountId, this.msg.uid), this);
4939
+ rowByKey.set(rowKey(this.accountId, this.msg.uid, this.msg.folderId), this);
4914
4940
  }
4915
4941
  /** Remove this row from the DOM and the lookup map. If it was the
4916
4942
  * focused row, the controller is responsible for releasing focus
@@ -4918,7 +4944,7 @@ var init_message_list = __esm({
4918
4944
  * may want to hand focus to a sibling instead). */
4919
4945
  detach() {
4920
4946
  this.el.remove();
4921
- rowByKey.delete(rowKey(this.accountId, this.msg.uid));
4947
+ rowByKey.delete(rowKey(this.accountId, this.msg.uid, this.msg.folderId));
4922
4948
  }
4923
4949
  setSelected(yes) {
4924
4950
  this.el.classList.toggle("selected", yes);
@@ -5289,7 +5315,7 @@ var init_message_list = __esm({
5289
5315
  return;
5290
5316
  if (!ev.accountId || ev.previousDraftUid == null)
5291
5317
  return;
5292
- const row = rowByKey.get(rowKey(ev.accountId, ev.previousDraftUid));
5318
+ const row = findRow(ev.accountId, Number(ev.previousDraftUid), ev.folderId);
5293
5319
  if (row)
5294
5320
  row.setDate(typeof ev.savedAt === "number" ? ev.savedAt : Date.now());
5295
5321
  });
@@ -9458,8 +9484,8 @@ async function performUndo() {
9458
9484
  const flag = "\\Flagged";
9459
9485
  const flagsAfter = entry.prevFlagged ? [flag] : [];
9460
9486
  await updateFlags2(entry.accountId, entry.uid, flagsAfter, entry.folderId);
9461
- setRowFlagged(entry.accountId, entry.uid, entry.prevFlagged);
9462
- updateMessageFlags(entry.accountId, entry.uid, flagsAfter);
9487
+ setRowFlagged(entry.accountId, entry.uid, entry.prevFlagged, entry.folderId);
9488
+ updateMessageFlags(entry.accountId, entry.uid, flagsAfter, entry.folderId);
9463
9489
  }
9464
9490
  if (statusSync) statusSync.textContent = `Undid flag change on ${op.payload.length} message${op.payload.length !== 1 ? "s" : ""}${remaining}`;
9465
9491
  }
@@ -9637,8 +9663,8 @@ async function bulkFlagSelected() {
9637
9663
  for (const r of rows) {
9638
9664
  if (flaggedOf(r) === targetFlagged) continue;
9639
9665
  setFlagged(r, targetFlagged);
9640
- setRowFlagged(r.accountId, r.uid, targetFlagged);
9641
- updateMessageFlags(r.accountId, r.uid, r.flags);
9666
+ setRowFlagged(r.accountId, r.uid, targetFlagged, r.folderId);
9667
+ updateMessageFlags(r.accountId, r.uid, r.flags, r.folderId);
9642
9668
  try {
9643
9669
  await updateFlags2(r.accountId, r.uid, r.flags, r.folderId);
9644
9670
  } catch (e) {
@@ -9661,8 +9687,8 @@ document.getElementById("btn-flag")?.addEventListener("click", async () => {
9661
9687
  updateFlagButton();
9662
9688
  try {
9663
9689
  await updateFlags(sel.accountId, sel.uid, sel.flags, sel.folderId);
9664
- updateMessageFlags(sel.accountId, sel.uid, sel.flags);
9665
- setRowFlagged(sel.accountId, sel.uid, !wasFlagged);
9690
+ updateMessageFlags(sel.accountId, sel.uid, sel.flags, sel.folderId);
9691
+ setRowFlagged(sel.accountId, sel.uid, !wasFlagged, sel.folderId);
9666
9692
  } catch (e) {
9667
9693
  setFlagged(sel, wasFlagged);
9668
9694
  updateFlagButton();
@@ -9704,9 +9730,16 @@ async function spamSelectedMessages() {
9704
9730
  markAsSpamMessages(accountId, uids, folderIds).then((result) => {
9705
9731
  console.log(`[spam] ${accountId}: moved ${result?.moved ?? uids.length} to folderId=${result?.targetFolderId}`);
9706
9732
  if (result?.targetFolderId) spamUndo.targetFolderId = result.targetFolderId;
9707
- }).catch((e) => {
9733
+ }).catch(async (e) => {
9708
9734
  console.error(`[spam] ${accountId} failed:`, e);
9709
- if (statusSync) statusSync.textContent = `Spam sync issue (${accountId}): ${e?.message || e}`;
9735
+ if (statusSync) statusSync.textContent = `Spam FAILED (${accountId}): ${e?.message || e}`;
9736
+ try {
9737
+ await reloadCurrentFolder();
9738
+ } catch {
9739
+ }
9740
+ window.dispatchEvent(new CustomEvent("mailx-alert", {
9741
+ detail: { message: `Couldn't move ${uids.length} message(s) to spam: ${e?.message || e}`, key: "spam-move" }
9742
+ }));
9710
9743
  });
9711
9744
  }
9712
9745
  }
@@ -9766,7 +9799,7 @@ document.getElementById("btn-mark-unread")?.addEventListener("click", () => {
9766
9799
  const wasSeen = seenOf(sel);
9767
9800
  setSeen(sel, !wasSeen);
9768
9801
  updateFlags(sel.accountId, sel.uid, sel.flags, sel.folderId).then(() => {
9769
- updateMessageFlags(sel.accountId, sel.uid, sel.flags);
9802
+ updateMessageFlags(sel.accountId, sel.uid, sel.flags, sel.folderId);
9770
9803
  const row = document.querySelector(`.ml-row[data-uid="${sel.uid}"][data-account-id="${sel.accountId}"]`);
9771
9804
  if (row) row.classList.toggle("unread", wasSeen);
9772
9805
  }).catch(() => {
@@ -12808,7 +12841,7 @@ document.addEventListener("mailx-popout-action", ((e) => {
12808
12841
  const wasFlagged = flaggedOf(msg);
12809
12842
  setFlagged(msg, !wasFlagged);
12810
12843
  updateFlags(accountId, msg.uid, msg.flags, msg.folderId).catch((err) => console.error(`[popout] flag failed: ${err?.message || err}`));
12811
- setRowFlagged(accountId, msg.uid, !wasFlagged);
12844
+ setRowFlagged(accountId, msg.uid, !wasFlagged, msg.folderId);
12812
12845
  }
12813
12846
  }));
12814
12847
  document.addEventListener("mailx-popout-message", (async (e) => {