@bobfrankston/rmfmail 1.2.101 → 1.2.103

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.js CHANGED
@@ -2,8 +2,8 @@
2
2
  * mailx client entry point.
3
3
  * Wires together all UI components and WebSocket connection.
4
4
  */
5
- import { initFolderTree, refreshFolderTree, updateFolderCounts, setFolderSynced, getFolderSynced, setOutboxTotal } from "./components/folder-tree.js";
6
- import { initMessageList, loadMessages, loadUnifiedInbox, loadSearchResults, reloadCurrentFolder, clearSearchMode, getSelectedMessages, markBodiesCached, getCurrentFocused, releaseFocus, removeMessagesAndReconcile, setRowFlagged, scrollFocusedIntoView, refreshPriorityIndex, revealMessage, selectAllVisible, exitMultiSelect, getDateBasis, setDateBasis } from "./components/message-list.js";
5
+ import { initFolderTree, refreshFolderTree, updateFolderCounts, setFolderSynced, getFolderSynced, setOutboxTotal, highlightFolder } from "./components/folder-tree.js";
6
+ import { initMessageList, loadMessages, loadUnifiedInbox, loadSearchResults, reloadCurrentFolder, clearSearchMode, getSelectedMessages, markBodiesCached, getCurrentFocused, releaseFocus, removeMessagesAndReconcile, setRowFlagged, scrollFocusedIntoView, refreshPriorityIndex, revealMessage, getCurrentView, selectAllVisible, exitMultiSelect, getDateBasis, setDateBasis } from "./components/message-list.js";
7
7
  import { seenOf, flaggedOf, draftOf, setSeen, setFlagged } from "@bobfrankston/mailx-types";
8
8
  import { initTabs, setActiveView as setActiveTabView, openTab } from "./components/tabs.js";
9
9
  import { getCurrentMessage, initViewer, popOutCurrentMessage, popOutToWindow, printCurrentMessage, toggleFullscreenPreview, showPreviewBodyMenu, wrapHtmlBody } from "./components/message-viewer.js";
@@ -2637,21 +2637,42 @@ let lastListReloadAt = 0;
2637
2637
  // BEFORE clearing search mode, then navigate to that message's folder and
2638
2638
  // reselect it. With no selected result (or no folderId) fall back to the old
2639
2639
  // reloadCurrentFolder behavior.
2640
- function closeSearchAndReveal() {
2640
+ async function closeSearchAndReveal() {
2641
2641
  const focused = getCurrentFocused();
2642
2642
  clearSearchMode();
2643
2643
  const body = document.getElementById("ml-body");
2644
2644
  if (body)
2645
2645
  body.querySelectorAll(".filter-hidden").forEach(r => r.classList.remove("filter-hidden"));
2646
2646
  if (focused && focused.folderId) {
2647
- currentAccountId = focused.accountId;
2648
- currentFolderId = focused.folderId;
2649
- revealMessage(focused.accountId, focused.folderId, focused.uid);
2647
+ await revealMessage(focused.accountId, focused.folderId, focused.uid);
2650
2648
  }
2651
2649
  else {
2652
2650
  reloadCurrentFolder();
2653
2651
  }
2654
- setTitle(APP_NAME);
2652
+ // Leaving search must leave search STATE behind too. Before this, the
2653
+ // active tab kept its "Search: …" view (re-running the dead query on any
2654
+ // tab re-activation) and the folder tree kept the pre-search highlight —
2655
+ // so when the reveal landed somewhere unexpected (a Drafts result, a
2656
+ // stale folderId after a server-side rebind), every indicator still
2657
+ // claimed search-on-All-Inboxes and the list looked broken (Bob
2658
+ // 2026-07-04 "cleared the search but it isn't restoring the list").
2659
+ // Sync tab, tree highlight and titles to what the list actually shows.
2660
+ const vw = getCurrentView();
2661
+ if (vw.unified) {
2662
+ highlightFolder(null, -1);
2663
+ setActiveTabView({ kind: "unified" }, "All Inboxes");
2664
+ setTitle(`${APP_NAME} - All Inboxes`);
2665
+ setNarrowFolderTitle("All Inboxes");
2666
+ }
2667
+ else {
2668
+ currentAccountId = vw.accountId;
2669
+ currentFolderId = vw.folderId;
2670
+ currentFolderSpecialUse = vw.specialUse;
2671
+ const name = highlightFolder(vw.accountId, vw.folderId) || "Mail";
2672
+ setActiveTabView({ kind: "folder", accountId: vw.accountId, folderId: vw.folderId, specialUse: vw.specialUse }, name);
2673
+ setTitle(`${APP_NAME} - ${name}`);
2674
+ setNarrowFolderTitle(name);
2675
+ }
2655
2676
  }
2656
2677
  searchInput?.addEventListener("input", () => {
2657
2678
  clearTimeout(searchTimeout);
@@ -4542,10 +4563,10 @@ optTwoLine?.addEventListener("change", () => {
4542
4563
  }
4543
4564
  localStorage.setItem("mailx-two-line", String(optTwoLine.checked));
4544
4565
  });
4545
- // Eleanor view toggle — Thunderbird-classic one-line summary list
4546
- // ( | Subject | From | Date, whitespace, monochrome). Pure CSS class;
4547
- // the row markup is unchanged. TODO.md: generalize into per-column view
4548
- // control instead of a named preset.
4566
+ // Eleanor view toggle — Thunderbird-classic two-line card list at every
4567
+ // width (From Date / Subject, outlined entries, airy, monochrome).
4568
+ // Pure CSS class; the row markup is unchanged. TODO.md: generalize into
4569
+ // per-column view control instead of a named preset.
4549
4570
  function applyEleanorView(on) {
4550
4571
  document.getElementById("message-list")?.classList.toggle("eleanor-view", on);
4551
4572
  if (optEleanor)