@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.bundle.js +205 -35
- package/client/app.bundle.js.map +4 -4
- package/client/app.js +42 -0
- package/client/app.js.map +1 -1
- package/client/app.ts +41 -0
- package/client/components/message-list.js +58 -35
- package/client/components/message-list.js.map +1 -1
- package/client/components/message-list.ts +55 -34
- package/client/components/tabs.js +155 -0
- package/client/components/tabs.js.map +1 -0
- package/client/components/tabs.ts +163 -0
- package/client/index.html +4 -0
- package/client/styles/components.css +58 -0
- package/client/styles/layout.css +15 -9
- package/docs/multi-view.md +81 -0
- package/package.json +3 -2
- /package/packages/mailx-imap/{node_modules.npmglobalize-stash-45456 → node_modules.npmglobalize-stash-49720}/.package-lock.json +0 -0
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)
|