@bobfrankston/rmfmail 1.2.192 → 1.2.193

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
@@ -1755,6 +1755,16 @@ async function performUndo(): Promise<void> {
1755
1755
  if (statusSync) statusSync.textContent = msgs.length === 1
1756
1756
  ? "Message restored"
1757
1757
  : `Restored ${msgs.length} messages`;
1758
+ // Position at what was just restored — an undo whose effect lands
1759
+ // off-screen (or in a folder you've since left) reads as a no-op.
1760
+ // Reveal the first of the batch; the rest are in the same view.
1761
+ // On a miss revealMessage restores the prior view itself.
1762
+ const first = msgs[0];
1763
+ if (first?.folderId) {
1764
+ await revealMessage(first.accountId, first.folderId, first.uid);
1765
+ syncChromeToListView();
1766
+ return;
1767
+ }
1758
1768
  } else if (op.kind === "move") {
1759
1769
  const { messages } = op.payload;
1760
1770
  const byDest = new Map<string, { accountId: string; folderId: number; uids: number[] }>();
@@ -1769,6 +1779,14 @@ async function performUndo(): Promise<void> {
1769
1779
  else await moveMessages(group.accountId, group.uids, group.folderId);
1770
1780
  }
1771
1781
  if (statusSync) statusSync.textContent = `Undid move of ${messages.length} message${messages.length !== 1 ? "s" : ""}`;
1782
+ // Same positioning rule as undo-delete: show the message back in
1783
+ // its original folder.
1784
+ const firstMoved = messages[0];
1785
+ if (firstMoved?.sourceFolderId) {
1786
+ await revealMessage(firstMoved.accountId, firstMoved.sourceFolderId, firstMoved.uid);
1787
+ syncChromeToListView();
1788
+ return;
1789
+ }
1772
1790
  } else if (op.kind === "flag") {
1773
1791
  const { updateFlags } = await import("./lib/api-client.js");
1774
1792
  // Restore each row's prior \Flagged state. Mutates message-state
@@ -2644,6 +2662,14 @@ async function closeSearchAndReveal(): Promise<void> {
2644
2662
  // claimed search-on-All-Inboxes and the list looked broken (Bob
2645
2663
  // 2026-07-04 "cleared the search but it isn't restoring the list").
2646
2664
  // Sync tab, tree highlight and titles to what the list actually shows.
2665
+ syncChromeToListView();
2666
+ }
2667
+
2668
+ /** Mirror tab, folder-tree highlight and titles to whatever view the message
2669
+ * list is actually showing. Needed after any list-driven navigation
2670
+ * (revealMessage from search-close or undo) — the list module can land on a
2671
+ * different folder than the surrounding chrome still claims. */
2672
+ function syncChromeToListView(): void {
2647
2673
  const vw = getCurrentView();
2648
2674
  if (vw.unified) {
2649
2675
  highlightFolder(null, -1);
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bobfrankston/mailx-client",
3
- "version": "1.0.21",
3
+ "version": "1.0.22",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "scripts": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bobfrankston/rmfmail",
3
- "version": "1.2.192",
3
+ "version": "1.2.193",
4
4
  "description": "Local-first email client with IMAP sync and standalone native app",
5
5
  "type": "module",
6
6
  "main": "bin/mailx.js",