@bobfrankston/rmfmail 1.2.248 → 1.2.251

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.
Files changed (55) hide show
  1. package/bin/check-bridge-contract.mjs +9 -1
  2. package/client/app.bundle.js +222 -50
  3. package/client/app.bundle.js.map +4 -4
  4. package/client/app.js +23 -36
  5. package/client/app.js.map +1 -1
  6. package/client/app.ts +17 -36
  7. package/client/components/folder-picker.js +3 -2
  8. package/client/components/folder-picker.js.map +1 -1
  9. package/client/components/folder-picker.ts +3 -2
  10. package/client/components/folder-tree.js +90 -12
  11. package/client/components/folder-tree.js.map +1 -1
  12. package/client/components/folder-tree.ts +89 -12
  13. package/client/components/message-list.js +3 -2
  14. package/client/components/message-list.js.map +1 -1
  15. package/client/components/message-list.ts +3 -2
  16. package/client/components/message-viewer.js +149 -11
  17. package/client/components/message-viewer.js.map +1 -1
  18. package/client/components/message-viewer.ts +139 -11
  19. package/client/compose/compose.bundle.js +11 -0
  20. package/client/compose/compose.bundle.js.map +2 -2
  21. package/client/help/search-help.js +6 -1
  22. package/client/help/search-help.js.map +1 -1
  23. package/client/help/search-help.ts +6 -1
  24. package/client/lib/api-client.js +14 -0
  25. package/client/lib/api-client.js.map +1 -1
  26. package/client/lib/api-client.ts +9 -0
  27. package/client/lib/fold-text.js +18 -0
  28. package/client/lib/fold-text.js.map +1 -0
  29. package/client/lib/fold-text.ts +17 -0
  30. package/client/lib/mailxapi.js +12 -0
  31. package/client/styles/components.css +8 -3
  32. package/package.json +5 -5
  33. package/packages/mailx-imap/package-lock.json +2 -2
  34. package/packages/mailx-imap/package.json +1 -1
  35. package/packages/mailx-service/index.d.ts +16 -0
  36. package/packages/mailx-service/index.d.ts.map +1 -1
  37. package/packages/mailx-service/index.js +49 -1
  38. package/packages/mailx-service/index.js.map +1 -1
  39. package/packages/mailx-service/index.ts +48 -1
  40. package/packages/mailx-service/jsonrpc.js +2 -0
  41. package/packages/mailx-service/jsonrpc.js.map +1 -1
  42. package/packages/mailx-service/jsonrpc.ts +2 -0
  43. package/packages/mailx-service/package.json +1 -1
  44. package/packages/mailx-settings/package.json +1 -1
  45. package/packages/mailx-store/db.d.ts.map +1 -1
  46. package/packages/mailx-store/db.js +5 -2
  47. package/packages/mailx-store/db.js.map +1 -1
  48. package/packages/mailx-store/db.ts +5 -2
  49. package/packages/mailx-store/package.json +1 -1
  50. package/packages/mailx-store-web/package.json +1 -1
  51. package/packages/mailx-types/mailx-api.d.ts +7 -0
  52. package/packages/mailx-types/mailx-api.d.ts.map +1 -1
  53. package/packages/mailx-types/mailx-api.ts +4 -0
  54. package/packages/mailx-types/package.json +1 -1
  55. /package/packages/mailx-imap/{node_modules.npmglobalize-stash-63500 → node_modules.npmglobalize-stash-83100}/.package-lock.json +0 -0
package/client/app.js CHANGED
@@ -2,7 +2,7 @@
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, highlightFolder } from "./components/folder-tree.js";
5
+ import { initFolderTree, refreshFolderTree, updateFolderCounts, setFolderSynced, getFolderSynced, setOutboxTotal, highlightFolder, setFolderFilter } from "./components/folder-tree.js";
6
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";
@@ -2975,46 +2975,33 @@ document.getElementById("search-server-too")?.addEventListener("change", rerunAc
2975
2975
  document.getElementById("search-include-trash")?.addEventListener("change", rerunActiveSearch);
2976
2976
  // Message state handles move/delete — no manual event listener needed
2977
2977
  // ── Folder filter ──
2978
+ // The matching itself lives in folder-tree.ts (setFolderFilter), which filters
2979
+ // the folder DATA and re-renders. The old version here hid rendered rows,
2980
+ // which could only ever find folders that happened to be expanded — every
2981
+ // folder under a collapsed parent, and every folder of a collapsed account,
2982
+ // was invisible to it (Bob 2026-08-11: "folder search should not be case
2983
+ // sensitive" — the misses looked like a casing problem).
2978
2984
  const ftFilterInput = document.getElementById("ft-filter-input");
2979
2985
  if (ftFilterInput) {
2980
- ftFilterInput.addEventListener("input", () => {
2981
- const query = ftFilterInput.value.toLowerCase();
2982
- const tree = document.getElementById("folder-tree");
2983
- if (!tree)
2984
- return;
2985
- if (!query) {
2986
- // Clear filter — show everything
2987
- tree.querySelectorAll(".ft-filter-hidden").forEach(el => el.classList.remove("ft-filter-hidden"));
2988
- return;
2989
- }
2990
- // Hide all folders first, then show matches + their parent accounts
2991
- const folders = tree.querySelectorAll(".ft-folder");
2992
- const accounts = tree.querySelectorAll(".ft-account");
2993
- for (const acct of accounts)
2994
- acct.classList.add("ft-filter-hidden");
2995
- for (const f of folders)
2996
- f.classList.add("ft-filter-hidden");
2997
- for (const f of folders) {
2998
- const name = f.querySelector(".ft-folder-name")?.textContent?.toLowerCase() || "";
2999
- if (name.includes(query)) {
3000
- f.classList.remove("ft-filter-hidden");
3001
- // Show parent account
3002
- const acct = f.closest(".ft-account");
3003
- if (acct)
3004
- acct.classList.remove("ft-filter-hidden");
3005
- }
3006
- }
3007
- // Also show unified inbox if it matches
3008
- const unified = tree.querySelector(".ft-unified");
3009
- if (unified) {
3010
- const text = unified.textContent?.toLowerCase() || "";
3011
- unified.classList.toggle("ft-filter-hidden", !text.includes(query));
3012
- }
3013
- });
2986
+ // Re-render hits the folder API per account, so coalesce keystrokes.
2987
+ let ftFilterTimer = null;
2988
+ const FT_FILTER_DEBOUNCE_MS = 120;
2989
+ const applyFolderFilter = (immediate) => {
2990
+ if (ftFilterTimer) {
2991
+ clearTimeout(ftFilterTimer);
2992
+ ftFilterTimer = null;
2993
+ }
2994
+ const run = () => setFolderFilter(ftFilterInput.value);
2995
+ if (immediate)
2996
+ run();
2997
+ else
2998
+ ftFilterTimer = setTimeout(run, FT_FILTER_DEBOUNCE_MS);
2999
+ };
3000
+ ftFilterInput.addEventListener("input", () => applyFolderFilter(false));
3014
3001
  ftFilterInput.addEventListener("keydown", (e) => {
3015
3002
  if (e.key === "Escape") {
3016
3003
  ftFilterInput.value = "";
3017
- ftFilterInput.dispatchEvent(new Event("input"));
3004
+ applyFolderFilter(true);
3018
3005
  }
3019
3006
  });
3020
3007
  }