@bobfrankston/rmfmail 1.2.98 → 1.2.101

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 (46) hide show
  1. package/TODO.md +1 -0
  2. package/client/android-bootstrap.bundle.js +85 -22
  3. package/client/android-bootstrap.bundle.js.map +2 -2
  4. package/client/app.bundle.js +57 -0
  5. package/client/app.bundle.js.map +2 -2
  6. package/client/app.js +63 -0
  7. package/client/app.js.map +1 -1
  8. package/client/app.ts +58 -0
  9. package/client/components/message-viewer.js +23 -0
  10. package/client/components/message-viewer.js.map +1 -1
  11. package/client/components/message-viewer.ts +19 -0
  12. package/client/index.html +1 -0
  13. package/client/styles/components.css +50 -0
  14. package/docs/preferences.md +1 -0
  15. package/package.json +7 -7
  16. package/packages/mailx-imap/index.d.ts.map +1 -1
  17. package/packages/mailx-imap/index.js +6 -2
  18. package/packages/mailx-imap/index.js.map +1 -1
  19. package/packages/mailx-imap/index.ts +6 -2
  20. package/packages/mailx-imap/package-lock.json +2 -2
  21. package/packages/mailx-imap/package.json +1 -1
  22. package/packages/mailx-settings/docs/preferences.md +1 -0
  23. package/packages/mailx-store/db.d.ts +7 -0
  24. package/packages/mailx-store/db.d.ts.map +1 -1
  25. package/packages/mailx-store/db.js +13 -1
  26. package/packages/mailx-store/db.js.map +1 -1
  27. package/packages/mailx-store/db.ts +19 -1
  28. package/packages/mailx-store/package.json +1 -1
  29. package/packages/mailx-store-web/android-bootstrap.d.ts.map +1 -1
  30. package/packages/mailx-store-web/android-bootstrap.js +74 -19
  31. package/packages/mailx-store-web/android-bootstrap.js.map +1 -1
  32. package/packages/mailx-store-web/android-bootstrap.ts +71 -16
  33. package/packages/mailx-store-web/db.d.ts +1 -0
  34. package/packages/mailx-store-web/db.d.ts.map +1 -1
  35. package/packages/mailx-store-web/db.js +21 -5
  36. package/packages/mailx-store-web/db.js.map +1 -1
  37. package/packages/mailx-store-web/db.ts +20 -7
  38. package/packages/mailx-store-web/imap-web-provider.d.ts.map +1 -1
  39. package/packages/mailx-store-web/imap-web-provider.js +1 -0
  40. package/packages/mailx-store-web/imap-web-provider.js.map +1 -1
  41. package/packages/mailx-store-web/imap-web-provider.ts +1 -0
  42. package/packages/mailx-store-web/package.json +1 -1
  43. package/packages/mailx-store-web/sync-manager.d.ts.map +1 -1
  44. package/packages/mailx-store-web/sync-manager.js +4 -0
  45. package/packages/mailx-store-web/sync-manager.js.map +1 -1
  46. package/packages/mailx-store-web/sync-manager.ts +4 -0
package/client/app.js CHANGED
@@ -710,6 +710,31 @@ document.getElementById("btn-back")?.addEventListener("click", backToList);
710
710
  // Android WebView sometimes drops synthetic clicks after a touchend inside a
711
711
  // header bar layered above the iframe — handle touchend explicitly too.
712
712
  document.getElementById("btn-back")?.addEventListener("touchend", backToList);
713
+ // ── Fold/unfold (and any window resize) layout reconcile ──
714
+ // narrow-active/narrow-hidden are otherwise only set when a message is
715
+ // CLICKED while already narrow. Opening a message on the Fold's inner
716
+ // screen (wide, two panes) and then folding to the cover screen crossed
717
+ // into the narrow layout with neither class set — the viewer vanished and
718
+ // there was no back-to-inbox button (Bob 2026-07-03). Reconcile on every
719
+ // tier crossing: into narrow with a message open → full-screen viewer +
720
+ // back button, exactly as if it had been opened narrow; out of narrow →
721
+ // both panes, classes off. matchMedia mirrors layout.css's narrow query
722
+ // (768px width OR 600px height) so JS and CSS agree on the tier.
723
+ const narrowMq = window.matchMedia("(max-width: 768px), (max-height: 600px)");
724
+ narrowMq.addEventListener("change", () => {
725
+ const viewer = document.getElementById("message-viewer");
726
+ const list = document.getElementById("message-list");
727
+ if (narrowMq.matches) {
728
+ if (getCurrentMessage()) {
729
+ viewer?.classList.add("narrow-active");
730
+ list?.classList.add("narrow-hidden");
731
+ }
732
+ }
733
+ else {
734
+ viewer?.classList.remove("narrow-active");
735
+ list?.classList.remove("narrow-hidden");
736
+ }
737
+ });
713
738
  // Pop-out viewer button — desktop spawns a floating overlay (multiple at
714
739
  // once), mobile toggles `body.viewer-fullscreen` for full-screen reading.
715
740
  // Threshold and behavior live in popOutCurrentMessage.
@@ -4076,6 +4101,7 @@ function openShortcutsDialog() {
4076
4101
  const viewBtn = document.getElementById("btn-view");
4077
4102
  const viewDropdown = document.getElementById("view-dropdown");
4078
4103
  const optTwoLine = document.getElementById("opt-two-line");
4104
+ const optEleanor = document.getElementById("opt-eleanor");
4079
4105
  const optPreview = document.getElementById("opt-preview");
4080
4106
  const optSnippet = document.getElementById("opt-snippet");
4081
4107
  const optFlagStars = document.getElementById("opt-flag-stars");
@@ -4268,6 +4294,7 @@ document.addEventListener("keydown", (e) => {
4268
4294
  });
4269
4295
  // Restore saved view settings
4270
4296
  const savedTwoLine = localStorage.getItem("mailx-two-line") === "true";
4297
+ const savedEleanor = localStorage.getItem("mailx-eleanor-view") === "true";
4271
4298
  const savedPreview = localStorage.getItem("mailx-preview") !== "false"; // default true
4272
4299
  const savedSnippet = localStorage.getItem("mailx-snippet") !== "false"; // default true
4273
4300
  const savedFlagStars = localStorage.getItem("mailx-flag-stars") !== "false"; // default true (show)
@@ -4285,6 +4312,8 @@ catch { /* private mode */ }
4285
4312
  const savedFolderCounts = localStorage.getItem("mailx-folder-counts") === "true";
4286
4313
  if (optTwoLine)
4287
4314
  optTwoLine.checked = savedTwoLine;
4315
+ if (optEleanor)
4316
+ optEleanor.checked = savedEleanor;
4288
4317
  if (optPreview)
4289
4318
  optPreview.checked = savedPreview;
4290
4319
  if (optSnippet)
@@ -4299,6 +4328,8 @@ if (optFolderCounts)
4299
4328
  optFolderCounts.checked = savedFolderCounts;
4300
4329
  if (savedTwoLine)
4301
4330
  document.getElementById("message-list")?.classList.add("two-line");
4331
+ if (savedEleanor)
4332
+ document.getElementById("message-list")?.classList.add("eleanor-view");
4302
4333
  if (!savedPreview)
4303
4334
  document.querySelector(".main-area")?.classList.add("no-preview");
4304
4335
  if (!savedSnippet)
@@ -4511,6 +4542,38 @@ optTwoLine?.addEventListener("change", () => {
4511
4542
  }
4512
4543
  localStorage.setItem("mailx-two-line", String(optTwoLine.checked));
4513
4544
  });
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.
4549
+ function applyEleanorView(on) {
4550
+ document.getElementById("message-list")?.classList.toggle("eleanor-view", on);
4551
+ if (optEleanor)
4552
+ optEleanor.checked = on;
4553
+ try {
4554
+ localStorage.setItem("mailx-eleanor-view", String(on));
4555
+ }
4556
+ catch { /* private mode */ }
4557
+ }
4558
+ optEleanor?.addEventListener("change", () => {
4559
+ applyEleanorView(optEleanor.checked);
4560
+ // Mirror to preferences.jsonc (ui.eleanorView) so the choice follows the
4561
+ // shared config across machines; localStorage stays the synchronous
4562
+ // first-paint cache, same split as the editor setting.
4563
+ getSettings().then((settings) => {
4564
+ settings.ui = { ...settings.ui, eleanorView: optEleanor.checked };
4565
+ saveSettings(settings);
4566
+ }).catch(() => { });
4567
+ });
4568
+ // A ui.eleanorView value in preferences.jsonc wins over the local cache once
4569
+ // it arrives — so the view can be enabled by editing the shared config file
4570
+ // directly, without touching the View menu on that machine.
4571
+ getSettings().then((s) => {
4572
+ const pref = s.ui?.eleanorView;
4573
+ if (typeof pref === "boolean" && pref !== (localStorage.getItem("mailx-eleanor-view") === "true")) {
4574
+ applyEleanorView(pref);
4575
+ }
4576
+ }).catch(() => { });
4514
4577
  // Preview pane toggle
4515
4578
  optPreview?.addEventListener("change", () => {
4516
4579
  const main = document.querySelector(".main-area");