@bobfrankston/rmfmail 1.2.252 → 1.2.254
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/android-bootstrap.bundle.js +29 -31
- package/client/android-bootstrap.bundle.js.map +2 -2
- package/client/app.bundle.js +23 -0
- package/client/app.bundle.js.map +3 -3
- package/client/app.js +26 -0
- package/client/app.js.map +1 -1
- package/client/app.ts +24 -0
- package/client/compose/compose.bundle.js +37 -3
- package/client/compose/compose.bundle.js.map +3 -3
- package/client/compose/compose.css +13 -0
- package/client/compose/compose.js +41 -1
- package/client/compose/compose.js.map +1 -1
- package/client/compose/compose.ts +38 -1
- package/client/lib/api-client.js +7 -0
- package/client/lib/api-client.js.map +1 -1
- package/client/lib/api-client.ts +8 -0
- package/client/lib/mailxapi.js +10 -2
- package/package.json +5 -5
- package/packages/mailx-imap/package-lock.json +2 -2
- package/packages/mailx-imap/package.json +1 -1
- package/packages/mailx-service/index.d.ts +19 -1
- package/packages/mailx-service/index.d.ts.map +1 -1
- package/packages/mailx-service/index.js +27 -2
- package/packages/mailx-service/index.js.map +1 -1
- package/packages/mailx-service/index.ts +28 -2
- package/packages/mailx-service/jsonrpc.js +3 -1
- package/packages/mailx-service/jsonrpc.js.map +1 -1
- package/packages/mailx-service/jsonrpc.ts +3 -1
- package/packages/mailx-service/package.json +1 -1
- package/packages/mailx-settings/package.json +1 -1
- package/packages/mailx-store/package.json +1 -1
- package/packages/mailx-store-web/android-bootstrap.js +1 -1
- package/packages/mailx-store-web/android-bootstrap.js.map +1 -1
- package/packages/mailx-store-web/android-bootstrap.ts +1 -1
- package/packages/mailx-store-web/package.json +1 -1
- package/packages/mailx-store-web/web-service.d.ts +5 -1
- package/packages/mailx-store-web/web-service.d.ts.map +1 -1
- package/packages/mailx-store-web/web-service.js +5 -1
- package/packages/mailx-store-web/web-service.js.map +1 -1
- package/packages/mailx-store-web/web-service.ts +5 -1
- package/packages/mailx-types/mailx-api.d.ts +17 -1
- package/packages/mailx-types/mailx-api.d.ts.map +1 -1
- package/packages/mailx-types/mailx-api.ts +10 -1
- package/packages/mailx-types/mime-build.d.ts.map +1 -1
- package/packages/mailx-types/mime-build.js +42 -30
- package/packages/mailx-types/mime-build.js.map +1 -1
- package/packages/mailx-types/mime-build.ts +51 -32
- package/packages/mailx-types/package.json +1 -1
- /package/packages/mailx-imap/{node_modules.npmglobalize-stash-85680 → node_modules.npmglobalize-stash-77932}/.package-lock.json +0 -0
package/client/app.ts
CHANGED
|
@@ -6066,6 +6066,30 @@ document.addEventListener("mailx-popout-message", (async (e: any) => {
|
|
|
6066
6066
|
draftFolderId: msg.folderId,
|
|
6067
6067
|
draftId: msg.mailxDraftId || "",
|
|
6068
6068
|
};
|
|
6069
|
+
// Reopening a draft must bring its attachments back into compose,
|
|
6070
|
+
// exactly as forward / edit-as-new do. Drafts had none to bring until
|
|
6071
|
+
// saveDraft started including them (2026-08-11); without this, editing
|
|
6072
|
+
// a draft and re-saving would strip the files a second time.
|
|
6073
|
+
if (Array.isArray(msg.attachments) && msg.attachments.length) {
|
|
6074
|
+
const loaded: { filename: string; mimeType: string; dataBase64: string }[] = [];
|
|
6075
|
+
for (const att of msg.attachments) {
|
|
6076
|
+
try {
|
|
6077
|
+
const data = await getAttachment(accountId, msg.uid, att.id, msg.folderId);
|
|
6078
|
+
if (data?.content) {
|
|
6079
|
+
loaded.push({
|
|
6080
|
+
filename: data.filename || att.filename || "attachment",
|
|
6081
|
+
mimeType: data.contentType || att.contentType || "application/octet-stream",
|
|
6082
|
+
dataBase64: data.content,
|
|
6083
|
+
});
|
|
6084
|
+
}
|
|
6085
|
+
} catch (e: any) {
|
|
6086
|
+
// Loud: a dropped attachment here means the next autosave
|
|
6087
|
+
// writes a draft without it.
|
|
6088
|
+
console.error(`[compose] edit draft: failed to load attachment ${att.id} ("${att.filename}"): ${e?.message || e}`);
|
|
6089
|
+
}
|
|
6090
|
+
}
|
|
6091
|
+
if (loaded.length) (init as any).attachments = loaded;
|
|
6092
|
+
}
|
|
6069
6093
|
sessionStorage.setItem("composeInit", JSON.stringify(init));
|
|
6070
6094
|
showComposeOverlay(msg.subject ? `Edit: ${msg.subject}` : "Edit draft");
|
|
6071
6095
|
return;
|
|
@@ -1093,6 +1093,7 @@ __export(api_client_exports, {
|
|
|
1093
1093
|
openInTextEditor: () => openInTextEditor,
|
|
1094
1094
|
openInWord: () => openInWord,
|
|
1095
1095
|
openLocalPath: () => openLocalPath,
|
|
1096
|
+
openPendingAttachment: () => openPendingAttachment,
|
|
1096
1097
|
popoutCompose: () => popoutCompose,
|
|
1097
1098
|
popoutMainWindow: () => popoutMainWindow,
|
|
1098
1099
|
popoutWindow: () => popoutWindow,
|
|
@@ -1656,6 +1657,10 @@ async function openAttachment(accountId, uid, attachmentId, folderId, filename)
|
|
|
1656
1657
|
const fn = ipc().openAttachment;
|
|
1657
1658
|
return fn ? fn(accountId, uid, attachmentId, folderId, filename) : void 0;
|
|
1658
1659
|
}
|
|
1660
|
+
async function openPendingAttachment(filename, mimeType, dataBase64) {
|
|
1661
|
+
const fn = ipc().openPendingAttachment;
|
|
1662
|
+
return fn ? fn(filename, mimeType, dataBase64) : void 0;
|
|
1663
|
+
}
|
|
1659
1664
|
async function getMessageSource(accountId, uid, folderId) {
|
|
1660
1665
|
return ipc().getMessageSource(accountId, uid, folderId);
|
|
1661
1666
|
}
|
|
@@ -6002,7 +6007,13 @@ function getContentSnapshot() {
|
|
|
6002
6007
|
to: toInput?.value || "",
|
|
6003
6008
|
cc: ccInput?.value || "",
|
|
6004
6009
|
bcc: bccInput?.value || "",
|
|
6005
|
-
subject: subjectInput?.value || ""
|
|
6010
|
+
subject: subjectInput?.value || "",
|
|
6011
|
+
// Attaching or removing a file IS a change. Without it here, adding an
|
|
6012
|
+
// attachment to an otherwise-untouched draft left the snapshot equal
|
|
6013
|
+
// and autosave skipped the save entirely. Fingerprint only — the
|
|
6014
|
+
// base64 would make this string megabytes and it is compared on every
|
|
6015
|
+
// 5s tick.
|
|
6016
|
+
atts: attachments.map((a) => `${a.filename}:${a.size}`).join("|")
|
|
6006
6017
|
});
|
|
6007
6018
|
}
|
|
6008
6019
|
function recordContentBaseline() {
|
|
@@ -6050,7 +6061,11 @@ async function saveDraft2() {
|
|
|
6050
6061
|
cc: ccInput.value,
|
|
6051
6062
|
bcc: bccInput.value,
|
|
6052
6063
|
previousDraftUid: draftUid,
|
|
6053
|
-
draftId
|
|
6064
|
+
draftId,
|
|
6065
|
+
// Same shape the send path uses. Omitted until 2026-08-11, which
|
|
6066
|
+
// meant a draft never carried its attachments — reopening one
|
|
6067
|
+
// silently lost them.
|
|
6068
|
+
attachments: attachments.map((a) => ({ filename: a.filename, mimeType: a.mimeType, dataBase64: a.dataBase64 }))
|
|
6054
6069
|
});
|
|
6055
6070
|
if (data?.draftUid) draftUid = data.draftUid;
|
|
6056
6071
|
if (data?.draftId) draftId = data.draftId;
|
|
@@ -6593,7 +6608,25 @@ function renderAttachmentChips() {
|
|
|
6593
6608
|
const a = attachments[i];
|
|
6594
6609
|
const chip = document.createElement("span");
|
|
6595
6610
|
chip.className = "compose-att-chip";
|
|
6596
|
-
|
|
6611
|
+
const open = document.createElement("button");
|
|
6612
|
+
open.type = "button";
|
|
6613
|
+
open.className = "compose-att-open";
|
|
6614
|
+
open.title = `Open ${a.filename}`;
|
|
6615
|
+
open.textContent = `\u{1F4CE} ${a.filename} (${formatSize(a.size)})`;
|
|
6616
|
+
open.addEventListener("click", async () => {
|
|
6617
|
+
const was = open.textContent;
|
|
6618
|
+
open.textContent = `\u{1F4CE} Opening ${a.filename}\u2026`;
|
|
6619
|
+
try {
|
|
6620
|
+
const { openPendingAttachment: openPendingAttachment2 } = await Promise.resolve().then(() => (init_api_client(), api_client_exports));
|
|
6621
|
+
const r = await openPendingAttachment2(a.filename, a.mimeType, a.dataBase64);
|
|
6622
|
+
if (!r?.ok) throw new Error("the host could not open it");
|
|
6623
|
+
} catch (e) {
|
|
6624
|
+
showDraftStatus(`Couldn't open "${a.filename}": ${e?.message || e}`, true);
|
|
6625
|
+
} finally {
|
|
6626
|
+
open.textContent = was;
|
|
6627
|
+
}
|
|
6628
|
+
});
|
|
6629
|
+
chip.appendChild(open);
|
|
6597
6630
|
const rm = document.createElement("button");
|
|
6598
6631
|
rm.type = "button";
|
|
6599
6632
|
rm.title = "Remove attachment";
|
|
@@ -6601,6 +6634,7 @@ function renderAttachmentChips() {
|
|
|
6601
6634
|
rm.addEventListener("click", () => {
|
|
6602
6635
|
attachments.splice(i, 1);
|
|
6603
6636
|
renderAttachmentChips();
|
|
6637
|
+
void saveDraft2();
|
|
6604
6638
|
});
|
|
6605
6639
|
chip.appendChild(rm);
|
|
6606
6640
|
attEl.appendChild(chip);
|