@bobfrankston/rmfmail 1.2.216 → 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.
package/client/app.ts CHANGED
@@ -1799,17 +1799,22 @@ async function performUndo(): Promise<void> {
1799
1799
  return;
1800
1800
  }
1801
1801
  } else if (op.kind === "move") {
1802
- const { messages } = op.payload;
1802
+ const { messages, targetFolderId } = op.payload;
1803
1803
  const byDest = new Map<string, { accountId: string; folderId: number; uids: number[] }>();
1804
1804
  for (const m of messages) {
1805
1805
  const key = `${m.accountId}:${m.sourceFolderId}`;
1806
1806
  if (!byDest.has(key)) byDest.set(key, { accountId: m.accountId, folderId: m.sourceFolderId, uids: [] });
1807
1807
  byDest.get(key)!.uids.push(m.uid);
1808
1808
  }
1809
- const { moveMessages, moveMessage } = await import("./lib/api-client.js");
1809
+ const { moveMessages } = await import("./lib/api-client.js");
1810
1810
  for (const group of byDest.values()) {
1811
- if (group.uids.length === 1) await moveMessage(group.accountId, group.uids[0], group.folderId);
1812
- else await moveMessages(group.accountId, group.uids, group.folderId);
1811
+ // The messages are sitting in targetFolderId right now, so that
1812
+ // is their SOURCE for the reverse move — pass it explicitly.
1813
+ // Without it the service resolves each row by (account, uid)
1814
+ // alone and a same-numbered uid in another folder can be moved
1815
+ // instead (the flag-clear / spam-move wrong-folder class).
1816
+ const currentFolderIds = targetFolderId ? group.uids.map(() => targetFolderId) : undefined;
1817
+ await moveMessages(group.accountId, group.uids, group.folderId, currentFolderIds);
1813
1818
  }
1814
1819
  if (statusSync) statusSync.textContent = `Undid move of ${messages.length} message${messages.length !== 1 ? "s" : ""}${remaining}`;
1815
1820
  // Same positioning rule as undo-delete: show the message back in
@@ -2130,20 +2135,21 @@ async function spamSelectedMessages(): Promise<void> {
2130
2135
  // performUndo restores each message to its own sourceFolderId, so a
2131
2136
  // selection spanning folders comes back correctly; targetFolderId is only
2132
2137
  // known once the service answers and the undo doesn't need it.
2133
- pushUndo({
2134
- kind: "move",
2135
- at: Date.now(),
2136
- payload: {
2137
- messages: snapshot.map(m => ({ accountId: m.accountId, uid: m.uid, sourceFolderId: m.folderId })),
2138
- targetAccountId: snapshot[0].accountId,
2139
- targetFolderId: 0,
2140
- },
2141
- });
2138
+ const spamUndo: MovedBatch = {
2139
+ messages: snapshot.map(m => ({ accountId: m.accountId, uid: m.uid, sourceFolderId: m.folderId })),
2140
+ targetAccountId: snapshot[0].accountId,
2141
+ targetFolderId: 0, // filled in below — only the service knows which folder is \Junk
2142
+ };
2143
+ pushUndo({ kind: "move", at: Date.now(), payload: spamUndo });
2142
2144
  if (statusSync) statusSync.textContent = `Spam: ${snapshot.length} queued — Ctrl+Z to undo`;
2143
2145
  for (const [accountId, { uids, folderIds }] of byAccount) {
2144
2146
  markAsSpamMessages(accountId, uids, folderIds)
2145
2147
  .then(result => {
2146
2148
  console.log(`[spam] ${accountId}: moved ${result?.moved ?? uids.length} to folderId=${result?.targetFolderId}`);
2149
+ // Now we know where they landed. The undo op is still on the
2150
+ // stack (same object) — record it so the reverse move names the
2151
+ // messages' current folder instead of guessing by uid alone.
2152
+ if (result?.targetFolderId) spamUndo.targetFolderId = result.targetFolderId;
2147
2153
  })
2148
2154
  .catch(e => {
2149
2155
  console.error(`[spam] ${accountId} failed:`, e);
@@ -1357,8 +1357,9 @@ function deleteMessages(accountId, uids, folderIds) {
1357
1357
  return ipc().deleteMessages?.(accountId, uids, folderIds);
1358
1358
  }
1359
1359
  function moveMessages(accountId, uids, targetFolderId, folderIds, targetAccountId) {
1360
- if (uids.length === 1)
1360
+ if (uids.length === 1 && (targetAccountId || !folderIds?.length)) {
1361
1361
  return moveMessage(accountId, uids[0], targetFolderId, targetAccountId);
1362
+ }
1362
1363
  return ipc().moveMessages?.(accountId, uids, targetFolderId, folderIds);
1363
1364
  }
1364
1365
  function markAsSpamMessages(accountId, uids, folderIds) {