@bobfrankston/rmfmail 1.2.127 → 1.2.128

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.ts CHANGED
@@ -994,7 +994,15 @@ async function openCompose(mode: ComposeMode, overrideMsg?: any, overrideAccount
994
994
  mode === "editAsNew" ? "Edit as new" :
995
995
  "Compose";
996
996
  const titleSubject = mode === "new" ? "" : (msg?.subject || "");
997
- const frame = showComposeOverlay(titleSubject ? `${titlePrefix}: ${titleSubject}` : titlePrefix);
997
+ const composeTitle = titleSubject ? `${titlePrefix}: ${titleSubject}` : titlePrefix;
998
+ // Default: compose/reply/forward open in their OWN OS window — an
999
+ // overlay covering the message list/preview is the thing Bob wants gone
1000
+ // (2026-07-12 "the default on a reply should just be a separate window
1001
+ // outside the frame"). Overlay remains: small screens, Android (no
1002
+ // popout host), Settings toggle off, or daemon spawn failure.
1003
+ const preferWindow = window.innerWidth > 768 && window.innerHeight > 600
1004
+ && localStorage.getItem("mailx-compose-in-window") !== "0";
1005
+ let frame: HTMLIFrameElement | null = preferWindow ? null : showComposeOverlay(composeTitle);
998
1006
  // Now finish initialisation off the critical path — editor bootstrap
999
1007
  // inside the iframe runs concurrently with this await.
1000
1008
  const accounts = await accountsP;
@@ -1202,6 +1210,18 @@ async function openCompose(mode: ComposeMode, overrideMsg?: any, overrideAccount
1202
1210
  // payload so the iframe can populate even when storage doesn't bridge.
1203
1211
  // sessionStorage remains as the fast-path for iframes that finish
1204
1212
  // loading before postMessage fires.
1213
+ if (preferWindow && !frame) {
1214
+ try {
1215
+ const { popoutCompose } = await import("./lib/api-client.js");
1216
+ const r = await popoutCompose(init);
1217
+ if (r?.ok) return;
1218
+ console.error("[compose] separate-window open failed — overlay fallback:", r?.reason);
1219
+ } catch (e: any) {
1220
+ console.error("[compose] separate-window open threw — overlay fallback:", e?.message || e);
1221
+ }
1222
+ frame = showComposeOverlay(composeTitle);
1223
+ }
1224
+
1205
1225
  const initJson = JSON.stringify(init);
1206
1226
  try { sessionStorage.setItem("composeInit", initJson); }
1207
1227
  catch (e: any) { console.error("[compose] sessionStorage.setItem failed:", e?.message || e); }
@@ -5254,6 +5274,12 @@ getSettings().then((s: any) => {
5254
5274
  if (optEditorQuill) optEditorQuill.checked = ed === "quill";
5255
5275
  if (optEditorTiptap) optEditorTiptap.checked = ed === "tiptap";
5256
5276
  if (optEditorTinymce) optEditorTinymce.checked = ed === "tinymce";
5277
+ const cwEl = document.getElementById("opt-compose-window") as HTMLInputElement | null;
5278
+ if (cwEl) {
5279
+ const inWindow = s.ui?.composeInWindow !== false;
5280
+ cwEl.checked = inWindow;
5281
+ try { localStorage.setItem("mailx-compose-in-window", inWindow ? "1" : "0"); } catch { /* */ }
5282
+ }
5257
5283
  const fontEl = document.getElementById("opt-compose-font-size") as HTMLInputElement | null;
5258
5284
  if (fontEl) {
5259
5285
  const px = Number(s.ui?.composeFontSize);
@@ -5261,6 +5287,15 @@ getSettings().then((s: any) => {
5261
5287
  }
5262
5288
  }).catch(() => {});
5263
5289
 
5290
+ document.getElementById("opt-compose-window")?.addEventListener("change", (e) => {
5291
+ const on = (e.target as HTMLInputElement).checked;
5292
+ try { localStorage.setItem("mailx-compose-in-window", on ? "1" : "0"); } catch { /* */ }
5293
+ getSettings().then((settings: any) => {
5294
+ settings.ui = { ...settings.ui, composeInWindow: on };
5295
+ saveSettings(settings);
5296
+ }).catch(() => {});
5297
+ });
5298
+
5264
5299
  // Unified compose editing font size (px). Same sync-cache-then-persist shape
5265
5300
  // as saveEditorSetting: compose.ts reads `mailx-compose-font-size` from
5266
5301
  // localStorage at module load, so the very next compose-open is correct.
@@ -4054,13 +4054,19 @@ var ccInput = document.getElementById("compose-cc");
4054
4054
  var bccInput = document.getElementById("compose-bcc");
4055
4055
  var subjectInput = document.getElementById("compose-subject");
4056
4056
  function autoGrowAddrInput(el) {
4057
- if (!el) return;
4057
+ if (!el || el.offsetParent === null) return;
4058
4058
  el.style.height = "auto";
4059
4059
  const max = 8 * 22;
4060
4060
  el.style.height = Math.min(el.scrollHeight, max) + "px";
4061
4061
  if (el.scrollHeight > max) el.style.overflowY = "auto";
4062
4062
  else el.style.overflowY = "hidden";
4063
4063
  }
4064
+ function autoGrowAllAddrInputs() {
4065
+ autoGrowAllAddrInputs();
4066
+ requestAnimationFrame(() => requestAnimationFrame(autoGrowAllAddrInputs));
4067
+ setTimeout(autoGrowAllAddrInputs, 250);
4068
+ }
4069
+ window.addEventListener("resize", () => autoGrowAllAddrInputs());
4064
4070
  function parseRecipientSegment(seg) {
4065
4071
  const s = (seg || "").trim();
4066
4072
  if (!s) return null;
@@ -5255,11 +5261,13 @@ var toggleBccBtn = document.getElementById("btn-toggle-bcc");
5255
5261
  function setCcVisible(visible) {
5256
5262
  ccRow.hidden = !visible;
5257
5263
  toggleCcBtn.classList.toggle("active", visible);
5264
+ if (visible) autoGrowAddrInput(ccInput);
5258
5265
  if (visible) ccInput.focus();
5259
5266
  }
5260
5267
  function setBccVisible(visible) {
5261
5268
  bccRow.hidden = !visible;
5262
5269
  toggleBccBtn.classList.toggle("active", visible);
5270
+ if (visible) autoGrowAddrInput(bccInput);
5263
5271
  if (visible) bccInput.focus();
5264
5272
  }
5265
5273
  toggleCcBtn?.addEventListener("click", () => setCcVisible(!!ccRow.hidden));