@bobfrankston/rmfmail 1.2.121 → 1.2.122
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 +14 -2
- package/client/app.bundle.js.map +2 -2
- package/client/app.js +24 -6
- package/client/app.js.map +1 -1
- package/client/app.ts +23 -6
- package/client/compose/compose.bundle.js +11 -8
- package/client/compose/compose.bundle.js.map +2 -2
- package/client/compose/compose.html +0 -1
- package/client/compose/compose.js +15 -13
- package/client/compose/compose.js.map +1 -1
- package/client/compose/compose.ts +13 -11
- package/package.json +1 -1
package/client/app.ts
CHANGED
|
@@ -1266,6 +1266,7 @@ function showComposeOverlay(title = "Compose"): HTMLIFrameElement {
|
|
|
1266
1266
|
const SVG_ATTRS = `width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"`;
|
|
1267
1267
|
const TRASH_SVG = `<svg ${SVG_ATTRS}><path d="M3 6h18"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6"/><path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></svg>`;
|
|
1268
1268
|
const POPOUT_SVG = `<svg ${SVG_ATTRS}><path d="M15 3h6v6"/><path d="M10 14 21 3"/><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/></svg>`;
|
|
1269
|
+
const MAXIMIZE_SVG = `<svg ${SVG_ATTRS}><rect x="4" y="4" width="16" height="16" rx="2"/><path d="M4 9h16"/></svg>`;
|
|
1269
1270
|
const RESTORE_SVG = `<svg ${SVG_ATTRS}><path d="M21 9v-6h-6"/><path d="M3 15v6h6"/><path d="M21 3l-7 7"/><path d="M3 21l7-7"/></svg>`;
|
|
1270
1271
|
const makeIconBtn = (svg: string, titleStr: string, hoverColor: string): HTMLButtonElement => {
|
|
1271
1272
|
const b = document.createElement("button");
|
|
@@ -1286,11 +1287,27 @@ function showComposeOverlay(title = "Compose"): HTMLIFrameElement {
|
|
|
1286
1287
|
});
|
|
1287
1288
|
btnCluster.appendChild(discardBtn);
|
|
1288
1289
|
|
|
1289
|
-
//
|
|
1290
|
-
//
|
|
1291
|
-
//
|
|
1292
|
-
//
|
|
1293
|
-
|
|
1290
|
+
// True popout — hand the live compose off to its own OS window (native
|
|
1291
|
+
// msger window via the daemon; see compose.ts popoutHandoff). Lives in
|
|
1292
|
+
// the TITLE BAR with the other frame controls because it's about the
|
|
1293
|
+
// frame, not the content (Bob 2026-07-12). The iframe owns the state, so
|
|
1294
|
+
// this just pokes it with an event, same pattern as Discard/Close.
|
|
1295
|
+
// Hidden on small screens where the overlay is full-screen and a separate
|
|
1296
|
+
// OS window makes no sense (and Android has no popout host).
|
|
1297
|
+
if (!isSmall) {
|
|
1298
|
+
const osPopoutBtn = makeIconBtn(POPOUT_SVG, "Open in separate window", "#000");
|
|
1299
|
+
osPopoutBtn.addEventListener("click", () => {
|
|
1300
|
+
try {
|
|
1301
|
+
const win = frame.contentWindow;
|
|
1302
|
+
if (win) win.dispatchEvent(new Event("compose-popout"));
|
|
1303
|
+
} catch { /* */ }
|
|
1304
|
+
});
|
|
1305
|
+
btnCluster.appendChild(osPopoutBtn);
|
|
1306
|
+
}
|
|
1307
|
+
|
|
1308
|
+
// Maximize = toggle between the floating overlay and a host-window-filling
|
|
1309
|
+
// layout — second click restores the floating geometry.
|
|
1310
|
+
const popoutBtn = makeIconBtn(MAXIMIZE_SVG, "Maximize", "#000");
|
|
1294
1311
|
let maximized = false;
|
|
1295
1312
|
let savedCss = "";
|
|
1296
1313
|
popoutBtn.addEventListener("click", () => {
|
|
@@ -1302,7 +1319,7 @@ function showComposeOverlay(title = "Compose"): HTMLIFrameElement {
|
|
|
1302
1319
|
maximized = true;
|
|
1303
1320
|
} else {
|
|
1304
1321
|
wrapper.style.cssText = savedCss;
|
|
1305
|
-
popoutBtn.innerHTML =
|
|
1322
|
+
popoutBtn.innerHTML = MAXIMIZE_SVG;
|
|
1306
1323
|
popoutBtn.title = "Maximize";
|
|
1307
1324
|
maximized = false;
|
|
1308
1325
|
}
|
|
@@ -5158,9 +5158,10 @@ document.getElementById("btn-discard")?.addEventListener("click", async () => {
|
|
|
5158
5158
|
}
|
|
5159
5159
|
closeCompose();
|
|
5160
5160
|
});
|
|
5161
|
-
var
|
|
5162
|
-
|
|
5163
|
-
|
|
5161
|
+
var popoutHandoffInFlight = false;
|
|
5162
|
+
async function popoutHandoff() {
|
|
5163
|
+
if (popoutInitId || popoutHandoffInFlight) return;
|
|
5164
|
+
popoutHandoffInFlight = true;
|
|
5164
5165
|
if (!draftId) draftId = `mailx-draft-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
5165
5166
|
const init = {
|
|
5166
5167
|
// "draft" mode so applyInit does NOT re-append the signature — the
|
|
@@ -5180,7 +5181,6 @@ composePopoutBtn?.addEventListener("click", async () => {
|
|
|
5180
5181
|
draftUid: draftUid ?? void 0,
|
|
5181
5182
|
draftId: draftId ?? void 0
|
|
5182
5183
|
};
|
|
5183
|
-
composePopoutBtn.disabled = true;
|
|
5184
5184
|
try {
|
|
5185
5185
|
const r = await popoutCompose(init);
|
|
5186
5186
|
if (r?.ok) {
|
|
@@ -5193,14 +5193,17 @@ composePopoutBtn?.addEventListener("click", async () => {
|
|
|
5193
5193
|
draftTimer = null;
|
|
5194
5194
|
}
|
|
5195
5195
|
closeCompose();
|
|
5196
|
-
|
|
5197
|
-
showDraftStatus(`Popout failed: ${r?.reason || "unknown"}`, true);
|
|
5198
|
-
composePopoutBtn.disabled = false;
|
|
5196
|
+
return;
|
|
5199
5197
|
}
|
|
5198
|
+
showDraftStatus(`Popout failed: ${r?.reason || "unknown"}`, true);
|
|
5200
5199
|
} catch (e) {
|
|
5201
5200
|
showDraftStatus(`Popout failed: ${e?.message || e}`, true);
|
|
5202
|
-
|
|
5201
|
+
} finally {
|
|
5202
|
+
popoutHandoffInFlight = false;
|
|
5203
5203
|
}
|
|
5204
|
+
}
|
|
5205
|
+
window.addEventListener("compose-popout", () => {
|
|
5206
|
+
void popoutHandoff();
|
|
5204
5207
|
});
|
|
5205
5208
|
var ccRow = document.getElementById("compose-cc-row");
|
|
5206
5209
|
var bccRow = document.getElementById("compose-bcc-row");
|