@bobfrankston/rmfmail 1.2.215 → 1.2.217

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.
@@ -360,8 +360,9 @@ function deleteMessages(accountId, uids, folderIds) {
360
360
  return ipc().deleteMessages?.(accountId, uids, folderIds);
361
361
  }
362
362
  function moveMessages(accountId, uids, targetFolderId, folderIds, targetAccountId) {
363
- if (uids.length === 1)
363
+ if (uids.length === 1 && (targetAccountId || !folderIds?.length)) {
364
364
  return moveMessage(accountId, uids[0], targetFolderId, targetAccountId);
365
+ }
365
366
  return ipc().moveMessages?.(accountId, uids, targetFolderId, folderIds);
366
367
  }
367
368
  function markAsSpamMessages(accountId, uids, folderIds) {
@@ -9280,17 +9281,23 @@ This cannot be undone.`)) {
9280
9281
  });
9281
9282
  }
9282
9283
  }
9284
+ var undoChain = Promise.resolve();
9285
+ function queueUndo() {
9286
+ undoChain = undoChain.then(() => performUndo()).catch(() => {
9287
+ });
9288
+ }
9283
9289
  async function performUndo() {
9284
9290
  const op = popUndo();
9285
9291
  if (!op) return;
9286
9292
  const statusSync = document.getElementById("status-sync");
9293
+ const remaining = undoStack.length ? ` \u2014 ${undoStack.length} more to undo` : "";
9287
9294
  try {
9288
9295
  if (op.kind === "delete") {
9289
9296
  const msgs = Array.isArray(op.payload) ? op.payload : [op.payload];
9290
9297
  for (const m of msgs) {
9291
9298
  await undeleteMessage(m.accountId, m.uid, m.folderId);
9292
9299
  }
9293
- if (statusSync) statusSync.textContent = msgs.length === 1 ? "Message restored" : `Restored ${msgs.length} messages`;
9300
+ if (statusSync) statusSync.textContent = (msgs.length === 1 ? "Message restored" : `Restored ${msgs.length} messages`) + remaining;
9294
9301
  const first = msgs[0];
9295
9302
  if (first?.folderId) {
9296
9303
  await revealMessage(first.accountId, first.folderId, first.uid);
@@ -9298,19 +9305,19 @@ async function performUndo() {
9298
9305
  return;
9299
9306
  }
9300
9307
  } else if (op.kind === "move") {
9301
- const { messages: messages2 } = op.payload;
9308
+ const { messages: messages2, targetFolderId } = op.payload;
9302
9309
  const byDest = /* @__PURE__ */ new Map();
9303
9310
  for (const m of messages2) {
9304
9311
  const key = `${m.accountId}:${m.sourceFolderId}`;
9305
9312
  if (!byDest.has(key)) byDest.set(key, { accountId: m.accountId, folderId: m.sourceFolderId, uids: [] });
9306
9313
  byDest.get(key).uids.push(m.uid);
9307
9314
  }
9308
- const { moveMessages: moveMessages2, moveMessage: moveMessage2 } = await Promise.resolve().then(() => (init_api_client(), api_client_exports));
9315
+ const { moveMessages: moveMessages2 } = await Promise.resolve().then(() => (init_api_client(), api_client_exports));
9309
9316
  for (const group of byDest.values()) {
9310
- if (group.uids.length === 1) await moveMessage2(group.accountId, group.uids[0], group.folderId);
9311
- else await moveMessages2(group.accountId, group.uids, group.folderId);
9317
+ const currentFolderIds = targetFolderId ? group.uids.map(() => targetFolderId) : void 0;
9318
+ await moveMessages2(group.accountId, group.uids, group.folderId, currentFolderIds);
9312
9319
  }
9313
- if (statusSync) statusSync.textContent = `Undid move of ${messages2.length} message${messages2.length !== 1 ? "s" : ""}`;
9320
+ if (statusSync) statusSync.textContent = `Undid move of ${messages2.length} message${messages2.length !== 1 ? "s" : ""}${remaining}`;
9314
9321
  const firstMoved = messages2[0];
9315
9322
  if (firstMoved?.sourceFolderId) {
9316
9323
  await revealMessage(firstMoved.accountId, firstMoved.sourceFolderId, firstMoved.uid);
@@ -9326,7 +9333,7 @@ async function performUndo() {
9326
9333
  setRowFlagged(entry.accountId, entry.uid, entry.prevFlagged);
9327
9334
  updateMessageFlags(entry.accountId, entry.uid, flagsAfter);
9328
9335
  }
9329
- if (statusSync) statusSync.textContent = `Undid flag change on ${op.payload.length} message${op.payload.length !== 1 ? "s" : ""}`;
9336
+ if (statusSync) statusSync.textContent = `Undid flag change on ${op.payload.length} message${op.payload.length !== 1 ? "s" : ""}${remaining}`;
9330
9337
  }
9331
9338
  reloadCurrentFolder();
9332
9339
  } catch (e) {
@@ -9557,10 +9564,18 @@ async function spamSelectedMessages() {
9557
9564
  g.folderIds.push(msg.folderId);
9558
9565
  byAccount.set(msg.accountId, g);
9559
9566
  }
9560
- if (statusSync) statusSync.textContent = `Spam: ${snapshot.length} queued \u2014 pending server sync`;
9567
+ const spamUndo = {
9568
+ messages: snapshot.map((m) => ({ accountId: m.accountId, uid: m.uid, sourceFolderId: m.folderId })),
9569
+ targetAccountId: snapshot[0].accountId,
9570
+ targetFolderId: 0
9571
+ // filled in below — only the service knows which folder is \Junk
9572
+ };
9573
+ pushUndo({ kind: "move", at: Date.now(), payload: spamUndo });
9574
+ if (statusSync) statusSync.textContent = `Spam: ${snapshot.length} queued \u2014 Ctrl+Z to undo`;
9561
9575
  for (const [accountId, { uids, folderIds }] of byAccount) {
9562
9576
  markAsSpamMessages(accountId, uids, folderIds).then((result) => {
9563
9577
  console.log(`[spam] ${accountId}: moved ${result?.moved ?? uids.length} to folderId=${result?.targetFolderId}`);
9578
+ if (result?.targetFolderId) spamUndo.targetFolderId = result.targetFolderId;
9564
9579
  }).catch((e) => {
9565
9580
  console.error(`[spam] ${accountId} failed:`, e);
9566
9581
  if (statusSync) statusSync.textContent = `Spam sync issue (${accountId}): ${e?.message || e}`;
@@ -10903,7 +10918,7 @@ document.addEventListener("keydown", (e) => {
10903
10918
  const composeOpen = !!document.querySelector(".compose-overlay");
10904
10919
  if (!inEditable && !composeOpen && undoStack.length > 0) {
10905
10920
  e.preventDefault();
10906
- performUndo();
10921
+ queueUndo();
10907
10922
  }
10908
10923
  }
10909
10924
  if (e.key === "F5") {
@@ -11060,7 +11075,7 @@ function openShortcutsDialog() {
11060
11075
  ["Forward", "Ctrl+F"],
11061
11076
  ["Sync", "F5"],
11062
11077
  ["Delete selected", "Del or Ctrl+D"],
11063
- ["Undo last delete/move", "Ctrl+Z"],
11078
+ ["Undo delete / move / spam / flag (repeat to go back further)", "Ctrl+Z"],
11064
11079
  ["Toggle read/unread", "R"],
11065
11080
  ["Toggle flag (\u2605)", "(\u2691 button in viewer)"],
11066
11081
  ["Select all visible", "Ctrl+A"],