@bobfrankston/rmfmail 1.1.228 → 1.1.231
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 +4 -1
- package/client/android-bootstrap.bundle.js.map +2 -2
- package/client/app.bundle.js +54 -20
- package/client/app.bundle.js.map +2 -2
- package/client/app.js +42 -7
- package/client/app.js.map +1 -1
- package/client/app.ts +43 -7
- package/client/components/message-viewer.js +30 -9
- package/client/components/message-viewer.js.map +1 -1
- package/client/components/message-viewer.ts +28 -9
- package/client/compose/compose.bundle.js +9 -9
- package/client/compose/compose.bundle.js.map +2 -2
- package/client/compose/compose.js +2 -2
- package/client/compose/compose.js.map +1 -1
- package/client/compose/compose.ts +2 -2
- package/client/lib/api-client.js +7 -7
- package/client/lib/api-client.js.map +1 -1
- package/client/lib/api-client.ts +7 -7
- package/client/lib/mailxapi.js +4 -4
- package/package.json +5 -5
- package/packages/mailx-service/index.d.ts +3 -3
- package/packages/mailx-service/index.d.ts.map +1 -1
- package/packages/mailx-service/index.js +148 -29
- package/packages/mailx-service/index.js.map +1 -1
- package/packages/mailx-service/index.ts +135 -23
- package/packages/mailx-service/jsonrpc.js +3 -3
- package/packages/mailx-service/jsonrpc.js.map +1 -1
- package/packages/mailx-service/jsonrpc.ts +3 -3
- package/packages/mailx-store/db.d.ts.map +1 -1
- package/packages/mailx-store/db.js +30 -8
- package/packages/mailx-store/db.js.map +1 -1
- package/packages/mailx-store/db.ts +27 -8
- package/packages/mailx-types/index.d.ts +7 -3
- package/packages/mailx-types/index.d.ts.map +1 -1
- package/packages/mailx-types/index.js.map +1 -1
- package/packages/mailx-types/index.ts +7 -3
- package/packages/mailx-types/mailx-api.d.ts +1 -1
- package/packages/mailx-types/mailx-api.d.ts.map +1 -1
- package/packages/mailx-types/mailx-api.ts +1 -1
- package/tsconfig.base.json +1 -0
- package/packages/mailx-imap/node_modules.npmglobalize-stash-126048/.package-lock.json +0 -116
package/client/app.bundle.js
CHANGED
|
@@ -329,13 +329,13 @@ function removeUserDictWord(word) {
|
|
|
329
329
|
function flagSenderOrDomain(type, value) {
|
|
330
330
|
return ipc().flagSenderOrDomain?.(type, value) ?? Promise.resolve({ flagged: false });
|
|
331
331
|
}
|
|
332
|
-
function deleteMessage(accountId, uid) {
|
|
333
|
-
return ipc().deleteMessage?.(accountId, uid);
|
|
332
|
+
function deleteMessage(accountId, uid, folderId) {
|
|
333
|
+
return ipc().deleteMessage?.(accountId, uid, folderId);
|
|
334
334
|
}
|
|
335
|
-
function deleteMessages(accountId, uids) {
|
|
335
|
+
function deleteMessages(accountId, uids, folderIds) {
|
|
336
336
|
if (uids.length === 1)
|
|
337
|
-
return deleteMessage(accountId, uids[0]);
|
|
338
|
-
return ipc().deleteMessages?.(accountId, uids);
|
|
337
|
+
return deleteMessage(accountId, uids[0], folderIds?.[0]);
|
|
338
|
+
return ipc().deleteMessages?.(accountId, uids, folderIds);
|
|
339
339
|
}
|
|
340
340
|
function moveMessages(accountId, uids, targetFolderId, targetAccountId) {
|
|
341
341
|
if (uids.length === 1)
|
|
@@ -600,9 +600,9 @@ function setupAccount(name, email, password) {
|
|
|
600
600
|
async function getAttachment(accountId, uid, attachmentId, folderId) {
|
|
601
601
|
return ipc().getAttachment(accountId, uid, attachmentId, folderId);
|
|
602
602
|
}
|
|
603
|
-
async function openAttachment(accountId, uid, attachmentId, folderId) {
|
|
603
|
+
async function openAttachment(accountId, uid, attachmentId, folderId, filename) {
|
|
604
604
|
const fn = ipc().openAttachment;
|
|
605
|
-
return fn ? fn(accountId, uid, attachmentId, folderId) : void 0;
|
|
605
|
+
return fn ? fn(accountId, uid, attachmentId, folderId, filename) : void 0;
|
|
606
606
|
}
|
|
607
607
|
async function getDeviceAccounts() {
|
|
608
608
|
return ipc().getDeviceAccounts?.() ?? [];
|
|
@@ -1816,14 +1816,30 @@ async function showMessage(accountId, uid, folderId, specialUse, isRetry = false
|
|
|
1816
1816
|
attEl.hidden = false;
|
|
1817
1817
|
const saveAttachmentAt = async (idx) => {
|
|
1818
1818
|
const a0 = msg.attachments[idx];
|
|
1819
|
+
const name = a0.filename || "attachment";
|
|
1819
1820
|
try {
|
|
1820
|
-
const data = await getAttachment(accountId, uid,
|
|
1821
|
+
const data = await getAttachment(accountId, uid, a0.id, msg.folderId);
|
|
1821
1822
|
const bytes = Uint8Array.from(atob(data.content), (c) => c.charCodeAt(0));
|
|
1822
1823
|
const blob = new Blob([bytes], { type: data.contentType || "application/octet-stream" });
|
|
1824
|
+
const picker = window.showSaveFilePicker;
|
|
1825
|
+
if (typeof picker === "function") {
|
|
1826
|
+
let handle;
|
|
1827
|
+
try {
|
|
1828
|
+
handle = await picker({ suggestedName: name });
|
|
1829
|
+
} catch (e) {
|
|
1830
|
+
if (e?.name === "AbortError")
|
|
1831
|
+
return;
|
|
1832
|
+
throw e;
|
|
1833
|
+
}
|
|
1834
|
+
const writable = await handle.createWritable();
|
|
1835
|
+
await writable.write(blob);
|
|
1836
|
+
await writable.close();
|
|
1837
|
+
return;
|
|
1838
|
+
}
|
|
1823
1839
|
const url = URL.createObjectURL(blob);
|
|
1824
1840
|
const a = document.createElement("a");
|
|
1825
1841
|
a.href = url;
|
|
1826
|
-
a.download =
|
|
1842
|
+
a.download = name;
|
|
1827
1843
|
a.style.display = "none";
|
|
1828
1844
|
document.body.appendChild(a);
|
|
1829
1845
|
a.click();
|
|
@@ -1832,7 +1848,7 @@ async function showMessage(accountId, uid, folderId, specialUse, isRetry = false
|
|
|
1832
1848
|
URL.revokeObjectURL(url);
|
|
1833
1849
|
}, 5e3);
|
|
1834
1850
|
} catch (err) {
|
|
1835
|
-
window.dispatchEvent(new CustomEvent("mailx-alert", { detail: { message: `Couldn't save "${
|
|
1851
|
+
window.dispatchEvent(new CustomEvent("mailx-alert", { detail: { message: `Couldn't save "${name}": ${err?.message || err}`, key: "attachment-save" } }));
|
|
1836
1852
|
}
|
|
1837
1853
|
};
|
|
1838
1854
|
const saveAllAttachments = async () => {
|
|
@@ -1866,14 +1882,14 @@ async function showMessage(accountId, uid, folderId, specialUse, isRetry = false
|
|
|
1866
1882
|
try {
|
|
1867
1883
|
const bridge = window._nativeBridge;
|
|
1868
1884
|
if (bridge?.openAttachment) {
|
|
1869
|
-
const data2 = await getAttachment(accountId, uid,
|
|
1885
|
+
const data2 = await getAttachment(accountId, uid, att.id, msg.folderId);
|
|
1870
1886
|
await bridge.openAttachment(att.filename, data2.contentType, data2.content);
|
|
1871
1887
|
return;
|
|
1872
1888
|
}
|
|
1873
|
-
const res = await openAttachment(accountId, uid,
|
|
1889
|
+
const res = await openAttachment(accountId, uid, att.id, msg.folderId, att.filename);
|
|
1874
1890
|
if (res)
|
|
1875
1891
|
return;
|
|
1876
|
-
const data = await getAttachment(accountId, uid,
|
|
1892
|
+
const data = await getAttachment(accountId, uid, att.id, msg.folderId);
|
|
1877
1893
|
const bytes = Uint8Array.from(atob(data.content), (c) => c.charCodeAt(0));
|
|
1878
1894
|
const blob = new Blob([bytes], { type: data.contentType });
|
|
1879
1895
|
const url = URL.createObjectURL(blob);
|
|
@@ -1900,7 +1916,7 @@ async function showMessage(accountId, uid, folderId, specialUse, isRetry = false
|
|
|
1900
1916
|
if (!e.dataTransfer)
|
|
1901
1917
|
return;
|
|
1902
1918
|
try {
|
|
1903
|
-
const data = await getAttachment(accountId, uid,
|
|
1919
|
+
const data = await getAttachment(accountId, uid, att.id, msg.folderId);
|
|
1904
1920
|
const bytes = Uint8Array.from(atob(data.content), (c) => c.charCodeAt(0));
|
|
1905
1921
|
const blob = new Blob([bytes], { type: data.contentType || "application/octet-stream" });
|
|
1906
1922
|
const url = URL.createObjectURL(blob);
|
|
@@ -7407,6 +7423,18 @@ function refreshSyncTooltip() {
|
|
|
7407
7423
|
}).join("\n");
|
|
7408
7424
|
}
|
|
7409
7425
|
setInterval(refreshSyncTooltip, 3e4);
|
|
7426
|
+
var syncSettleTimer = null;
|
|
7427
|
+
var SYNC_SETTLE_MS = 4e3;
|
|
7428
|
+
function scheduleSyncedStamp() {
|
|
7429
|
+
if (syncSettleTimer) clearTimeout(syncSettleTimer);
|
|
7430
|
+
syncSettleTimer = setTimeout(() => {
|
|
7431
|
+
syncSettleTimer = null;
|
|
7432
|
+
const el = document.getElementById("status-sync");
|
|
7433
|
+
if (el && (el.textContent || "").startsWith("Syncing")) {
|
|
7434
|
+
el.textContent = `Synced ${(/* @__PURE__ */ new Date()).toLocaleTimeString(void 0, { hour: "2-digit", minute: "2-digit", hour12: false })}`;
|
|
7435
|
+
}
|
|
7436
|
+
}, SYNC_SETTLE_MS);
|
|
7437
|
+
}
|
|
7410
7438
|
var messageList = document.getElementById("message-list");
|
|
7411
7439
|
if (messageList) {
|
|
7412
7440
|
const twoLineThreshold = 600;
|
|
@@ -7993,12 +8021,13 @@ async function deleteSelectedMessages() {
|
|
|
7993
8021
|
}
|
|
7994
8022
|
const byAccount = /* @__PURE__ */ new Map();
|
|
7995
8023
|
for (const msg of snapshot) {
|
|
7996
|
-
const
|
|
7997
|
-
uids.push(msg.uid);
|
|
7998
|
-
|
|
8024
|
+
const g = byAccount.get(msg.accountId) || { uids: [], folderIds: [] };
|
|
8025
|
+
g.uids.push(msg.uid);
|
|
8026
|
+
g.folderIds.push(msg.folderId);
|
|
8027
|
+
byAccount.set(msg.accountId, g);
|
|
7999
8028
|
}
|
|
8000
|
-
for (const [accountId,
|
|
8001
|
-
deleteMessages(accountId, uids).catch((e) => {
|
|
8029
|
+
for (const [accountId, g] of byAccount) {
|
|
8030
|
+
deleteMessages(accountId, g.uids, g.folderIds).catch((e) => {
|
|
8002
8031
|
console.error(`Delete failed for ${accountId}: ${e?.message || e}`);
|
|
8003
8032
|
if (statusSync) statusSync.textContent = `Delete sync issue (${accountId}): ${e?.message || e}`;
|
|
8004
8033
|
});
|
|
@@ -8934,6 +8963,7 @@ onWsEvent((event) => {
|
|
|
8934
8963
|
}
|
|
8935
8964
|
if (statusSync) statusSync.textContent = `Syncing ${event.accountId}: ${label}`;
|
|
8936
8965
|
if (startupStatus) startupStatus.textContent = `Syncing ${event.accountId}: ${label}`;
|
|
8966
|
+
scheduleSyncedStamp();
|
|
8937
8967
|
const syncPath = event.phase?.startsWith("sync:") ? event.phase.slice(5) : null;
|
|
8938
8968
|
document.querySelectorAll(`.ft-folder.ft-syncing[data-account-id="${event.accountId}"]`).forEach((el) => el.classList.remove("ft-syncing"));
|
|
8939
8969
|
if (syncPath && event.progress < 100) {
|
|
@@ -8953,6 +8983,7 @@ onWsEvent((event) => {
|
|
|
8953
8983
|
case "syncComplete":
|
|
8954
8984
|
refreshFolderTree();
|
|
8955
8985
|
recordAccountSync(event.accountId);
|
|
8986
|
+
scheduleSyncedStamp();
|
|
8956
8987
|
break;
|
|
8957
8988
|
case "folderSynced":
|
|
8958
8989
|
for (const entry of event.entries || []) {
|
|
@@ -8977,7 +9008,10 @@ onWsEvent((event) => {
|
|
|
8977
9008
|
syncBtn.disabled = false;
|
|
8978
9009
|
syncBtn.classList.remove("syncing");
|
|
8979
9010
|
}
|
|
8980
|
-
if (statusSync
|
|
9011
|
+
if (statusSync && !(statusSync.textContent || "").startsWith("Sync error")) {
|
|
9012
|
+
statusSync.textContent = "Syncing\u2026";
|
|
9013
|
+
}
|
|
9014
|
+
scheduleSyncedStamp();
|
|
8981
9015
|
break;
|
|
8982
9016
|
}
|
|
8983
9017
|
case "updateAvailable": {
|