@bobfrankston/rmfmail 1.2.242 → 1.2.244

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 (31) hide show
  1. package/client/android-bootstrap.bundle.js +24 -2
  2. package/client/android-bootstrap.bundle.js.map +2 -2
  3. package/client/app.bundle.js +28 -52
  4. package/client/app.bundle.js.map +3 -3
  5. package/client/app.js +22 -57
  6. package/client/app.js.map +1 -1
  7. package/client/app.ts +21 -54
  8. package/client/components/message-list.js +13 -2
  9. package/client/components/message-list.js.map +1 -1
  10. package/client/components/message-viewer.js +10 -2
  11. package/client/components/message-viewer.js.map +1 -1
  12. package/client/components/message-viewer.ts +11 -2
  13. package/package.json +7 -7
  14. package/packages/mailx-imap/index.d.ts +9 -0
  15. package/packages/mailx-imap/index.d.ts.map +1 -1
  16. package/packages/mailx-imap/index.js +86 -0
  17. package/packages/mailx-imap/index.js.map +1 -1
  18. package/packages/mailx-imap/index.ts +73 -0
  19. package/packages/mailx-imap/package-lock.json +2 -2
  20. package/packages/mailx-imap/package.json +1 -1
  21. package/packages/mailx-service/index.d.ts.map +1 -1
  22. package/packages/mailx-service/index.js +37 -4
  23. package/packages/mailx-service/index.js.map +1 -1
  24. package/packages/mailx-types/mime-inline-images.d.ts +0 -4
  25. package/packages/mailx-types/mime-inline-images.d.ts.map +1 -1
  26. package/packages/mailx-types/mime-inline-images.js +48 -4
  27. package/packages/mailx-types/mime-inline-images.js.map +1 -1
  28. package/packages/mailx-types/mime-inline-images.ts +45 -5
  29. package/packages/mailx-types/package.json +1 -1
  30. package/packages/mailx-types/test/inline-images.test.mjs +79 -0
  31. /package/packages/mailx-imap/{node_modules.npmglobalize-stash-33484 → node_modules.npmglobalize-stash-55392}/.package-lock.json +0 -0
package/client/app.js CHANGED
@@ -6,7 +6,7 @@ import { initFolderTree, refreshFolderTree, updateFolderCounts, setFolderSynced,
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";
9
- import { getCurrentMessage, initViewer, popOutCurrentMessage, popOutToWindow, printCurrentMessage, toggleFullscreenPreview, showPreviewBodyMenu, wrapHtmlBody } from "./components/message-viewer.js";
9
+ import { getCurrentMessage, initViewer, popOutCurrentMessage, popOutToWindow, printCurrentMessage, toggleFullscreenPreview, showPreviewBodyMenu } from "./components/message-viewer.js";
10
10
  import { connectWebSocket, onWsEvent, triggerSync, syncAccount, reauthenticate, getAccounts, getFolders, deleteMessage, deleteMessages, undeleteMessage, restartServer, getSyncPending, getVersion, getSettings, saveSettings, getAutocompleteSettings, saveAutocompleteSettings, repairAccounts, updateFlags, markAsSpamMessages, logClientEvent, sendMessage as apiSendMessage, subscribeStore, cancelServerSearch, installConsoleCapture, getAttachment } from "./lib/api-client.js";
11
11
  import * as messageState from "./lib/message-state.js";
12
12
  import { editMenuItems } from "./components/edit-menu.js";
@@ -2602,7 +2602,12 @@ document.addEventListener("mailx-compose", ((e) => {
2602
2602
  showComposeOverlay();
2603
2603
  }
2604
2604
  else {
2605
- openCompose(e.detail.mode);
2605
+ // `message`/`accountId` let a DETACHED surface compose for ITS own
2606
+ // message rather than whatever the main list has selected — openCompose
2607
+ // has taken those since the pop-out was written, but this listener
2608
+ // dropped them, so a pop-out could never have had working Reply
2609
+ // buttons even once it grew some.
2610
+ openCompose(e.detail.mode, e.detail.message, e.detail.accountId);
2606
2611
  }
2607
2612
  }));
2608
2613
  document.addEventListener("mailx-delete", () => deleteSelection());
@@ -6506,61 +6511,21 @@ document.addEventListener("mailx-popout-message", (async (e) => {
6506
6511
  showComposeOverlay(msg.subject ? `Edit: ${msg.subject}` : "Edit draft");
6507
6512
  return;
6508
6513
  }
6509
- const wrapper = document.createElement("div");
6510
- wrapper.className = "popout-overlay";
6511
- wrapper.style.cssText = "position:fixed;top:5vh;right:5vw;width:min(900px,60vw);height:min(800px,80vh);z-index:1500;background:var(--color-bg);border:1px solid var(--color-border);border-radius:6px;box-shadow:0 8px 32px rgba(0,0,0,0.3);display:flex;flex-direction:column;resize:both;overflow:hidden;";
6512
- const header = document.createElement("div");
6513
- header.style.cssText = "display:flex;align-items:center;gap:8px;padding:8px 12px;background:var(--color-bg-surface);border-bottom:1px solid var(--color-border);font-weight:600;cursor:move;";
6514
- const title = document.createElement("span");
6515
- title.textContent = subject || "(no subject)";
6516
- title.style.cssText = "flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;";
6517
- const closeBtn = document.createElement("button");
6518
- closeBtn.textContent = "×";
6519
- closeBtn.style.cssText = "background:none;border:none;font-size:1.4rem;cursor:pointer;padding:0 8px;";
6520
- closeBtn.addEventListener("click", () => wrapper.remove());
6521
- header.appendChild(title);
6522
- header.appendChild(closeBtn);
6523
- const meta = document.createElement("div");
6524
- meta.style.cssText = "padding:8px 12px;border-bottom:1px solid var(--color-border);font-size:0.9rem;color:var(--color-text-muted);";
6525
- meta.innerHTML = `<div><b>From:</b> ${escapeHtmlBasic(msg.from?.name || "")} &lt;${escapeHtmlBasic(msg.from?.address || "")}&gt;</div>
6526
- <div><b>To:</b> ${(msg.to || []).map((a) => escapeHtmlBasic(`${a.name || ""} <${a.address}>`)).join(", ")}</div>
6527
- ${msg.cc?.length ? `<div><b>Cc:</b> ${msg.cc.map((a) => escapeHtmlBasic(`${a.name || ""} <${a.address}>`)).join(", ")}</div>` : ""}
6528
- <div><b>Date:</b> ${new Date(msg.date).toLocaleString()}</div>`;
6529
- const body = document.createElement("iframe");
6530
- body.style.cssText = "flex:1;border:none;width:100%;background:#fff;";
6531
- body.sandbox.add("allow-same-origin");
6532
- wrapper.appendChild(header);
6533
- wrapper.appendChild(meta);
6534
- wrapper.appendChild(body);
6535
- document.body.appendChild(wrapper);
6536
- // Use the same wrapHtmlBody styling as the inline preview pane so the
6537
- // popout's typography matches the preview's typography. Earlier the
6538
- // popout fed bodyHtml DIRECTLY into srcdoc with no CSS wrapping, so
6539
- // the browser used its default font (Times serif) while the preview
6540
- // pane used system-ui sans-serif (Bob 2026-05-12: "double clicking on
6541
- // the summary shows in a different font than in preview").
6542
- body.srcdoc = msg.bodyHtml
6543
- ? wrapHtmlBody(msg.bodyHtml, !!msg.remoteAllowed)
6544
- : `<!DOCTYPE html><html><head><style>body{font-family:system-ui,sans-serif;font-size:17.5px;line-height:1.5;color:#1a1a2e;padding:1rem;margin:0;}pre{white-space:pre-wrap;word-break:break-word;font-family:inherit;font-size:inherit;margin:0;}</style></head><body><pre>${escapeHtmlBasic(msg.bodyText || "(no body)")}</pre></body></html>`;
6545
- // Drag-to-move.
6546
- let dragX = 0, dragY = 0, dragging = false;
6547
- header.addEventListener("mousedown", (de) => {
6548
- if (de.target.tagName === "BUTTON")
6549
- return;
6550
- dragging = true;
6551
- const rect = wrapper.getBoundingClientRect();
6552
- dragX = de.clientX - rect.left;
6553
- dragY = de.clientY - rect.top;
6554
- de.preventDefault();
6555
- });
6556
- document.addEventListener("mousemove", (de) => {
6557
- if (!dragging)
6558
- return;
6559
- wrapper.style.left = `${de.clientX - dragX}px`;
6560
- wrapper.style.top = `${de.clientY - dragY}px`;
6561
- wrapper.style.right = "auto";
6562
- });
6563
- document.addEventListener("mouseup", () => { dragging = false; });
6514
+ // ONE read-only popout, not three. This handler used to build its own
6515
+ // `.popout-overlay` — header, meta block, body iframe — with NO action
6516
+ // buttons at all, which is what a double-click on a message opened:
6517
+ // "I wanted to pop this out for editing but I don't see any controls.
6518
+ // It's just a view without even the reply etc." (Bob 2026-08-09). The
6519
+ // other two popout surfaces (the ⧉ overlay in message-viewer.ts and the
6520
+ // native msger window in popout-server.ts) have had a Reply/Reply-All/
6521
+ // Forward/Edit-as-new/Flag/Delete toolbar since 2026-05-16; this copy
6522
+ // never got one, and the handler's own comment noted it was "missing
6523
+ // every action button" while working around it for drafts only.
6524
+ //
6525
+ // Deleting the copy is the fix: double-click now opens the SAME overlay
6526
+ // the toolbar button does, so there is one surface to keep working.
6527
+ const { spawnDesktopPopout } = await import("./components/message-viewer.js");
6528
+ spawnDesktopPopout(msg, accountId);
6564
6529
  }));
6565
6530
  function escapeHtmlBasic(s) {
6566
6531
  return (s || "").replace(/[&<>"']/g, c => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", "\"": "&quot;", "'": "&#39;" }[c]));