@bobfrankston/rmfmail 1.1.36 → 1.1.38

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
@@ -5,6 +5,7 @@
5
5
  import { initFolderTree, refreshFolderTree, updateFolderCounts, setFolderSynced, getFolderSynced, setOutboxTotal } from "./components/folder-tree.js";
6
6
  import { initMessageList, loadMessages, loadUnifiedInbox, loadSearchResults, reloadCurrentFolder, clearSearchMode, getSelectedMessages, markBodiesCached, getCurrentFocused, releaseFocus, removeMessagesAndReconcile, setRowFlagged, scrollFocusedIntoView, refreshPriorityIndex } from "./components/message-list.js";
7
7
  import { seenOf, flaggedOf, draftOf, setSeen, setFlagged } from "@bobfrankston/mailx-types";
8
+ import { initTabs, setActiveView as setActiveTabView } from "./components/tabs.js";
8
9
  import { getCurrentMessage, initViewer, popOutCurrentMessage, toggleFullscreenPreview, showPreviewBodyMenu, wrapHtmlBody } from "./components/message-viewer.js";
9
10
  import { connectWebSocket, onWsEvent, triggerSync, syncAccount, reauthenticate, getAccounts, getFolders, deleteMessages, undeleteMessage, restartServer, getSyncPending, getVersion, getSettings, saveSettings, getAutocompleteSettings, saveAutocompleteSettings, repairAccounts, updateFlags, markAsSpamMessages, logClientEvent, sendMessage as apiSendMessage, subscribeStore } from "./lib/api-client.js";
10
11
  import * as messageState from "./lib/message-state.js";
@@ -420,6 +421,9 @@ initFolderTree(folderTree, (accountId, folderId, folderName, specialUse) => {
420
421
  loadMessages(accountId, folderId, 1, specialUse);
421
422
  setTitle(`${APP_NAME} - ${folderName}`);
422
423
  setNarrowFolderTitle(folderName);
424
+ // Record the navigation in the active tab so a later tab-switch restores
425
+ // this folder. Folder navigation happens IN the current tab.
426
+ setActiveTabView({ kind: "folder", accountId, folderId, specialUse }, folderName);
423
427
  document.dispatchEvent(new CustomEvent("mailx-folder-changed", { detail: { accountId, folderId } }));
424
428
  }, () => {
425
429
  // Unified inbox handler
@@ -436,7 +440,44 @@ initFolderTree(folderTree, (accountId, folderId, folderName, specialUse) => {
436
440
  loadUnifiedInbox();
437
441
  setTitle(`${APP_NAME} - All Inboxes`);
438
442
  setNarrowFolderTitle("All Inboxes");
443
+ setActiveTabView({ kind: "unified" }, "All Inboxes");
439
444
  });
445
+ // ── View tabs (docs/multi-view.md) ──────────────────────────────────────
446
+ // `applyTabView` loads a tab's view into the single three-pane when the user
447
+ // switches tabs. It mirrors the folder-tree handlers above but must NOT call
448
+ // setActiveTabView (that would be a no-op update, but keeping them separate
449
+ // keeps "user navigated" distinct from "tab restored").
450
+ function applyTabView(tab) {
451
+ if (searchInput)
452
+ searchInput.value = "";
453
+ clearSearchMode();
454
+ releaseFocus();
455
+ const v = tab.view;
456
+ if (v.kind === "unified") {
457
+ currentFolderSpecialUse = "inbox";
458
+ loadUnifiedInbox();
459
+ setTitle(`${APP_NAME} - All Inboxes`);
460
+ setNarrowFolderTitle("All Inboxes");
461
+ }
462
+ else if (v.kind === "folder") {
463
+ currentFolderSpecialUse = v.specialUse;
464
+ currentAccountId = v.accountId;
465
+ currentFolderId = v.folderId;
466
+ loadMessages(v.accountId, v.folderId, 1, v.specialUse);
467
+ setTitle(`${APP_NAME} - ${tab.title}`);
468
+ setNarrowFolderTitle(tab.title);
469
+ }
470
+ else {
471
+ if (searchInput)
472
+ searchInput.value = v.query;
473
+ loadSearchResults(v.query, v.scope, v.accountId, v.folderId, v.includeTrash);
474
+ setTitle(`${APP_NAME} - Search`);
475
+ setNarrowFolderTitle(`Search: ${v.query}`);
476
+ }
477
+ }
478
+ const tabStripEl = document.getElementById("view-tab-strip");
479
+ if (tabStripEl)
480
+ initTabs(tabStripEl, applyTabView);
440
481
  initMessageList((_accountId, _uid, _folderId) => {
441
482
  // The list row's setFocus() already drove the viewer with its own
442
483
  // envelope (header + preview paint synchronously, body fetches in
@@ -1878,6 +1919,7 @@ function doSearch(immediate = false) {
1878
1919
  }
1879
1920
  loadSearchResults(query, effectiveScope, currentAccountId, currentFolderId, includeTrash);
1880
1921
  setTitle(`${APP_NAME} - Search: ${query}`);
1922
+ setActiveTabView({ kind: "search", query, scope: effectiveScope, accountId: currentAccountId, folderId: currentFolderId, includeTrash }, `Search: ${query}`);
1881
1923
  // Only record on `immediate=true` (Enter / scope change) — debounced
1882
1924
  // typing would otherwise add every keystroke as its own entry.
1883
1925
  if (immediate)