@bobfrankston/rmfmail 1.0.679 → 1.0.681
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/bin/build-quill.js +35 -0
- package/client/app.bundle.js +34 -17
- package/client/app.bundle.js.map +2 -2
- package/client/app.js +67 -26
- package/client/app.js.map +1 -1
- package/client/app.ts +67 -28
- package/client/compose/compose.bundle.js +62 -2
- package/client/compose/compose.bundle.js.map +2 -2
- package/client/compose/compose.js +51 -3
- package/client/compose/compose.js.map +1 -1
- package/client/compose/compose.ts +47 -3
- package/client/lib/quill/quill.js +3 -0
- package/client/lib/quill/quill.snow.css +10 -0
- package/client/lib/rmf-tiny.js +21 -0
- package/docs/accounts.md +7 -2
- package/package.json +4 -4
- package/packages/mailx-service/index.d.ts.map +1 -1
- package/packages/mailx-service/index.js +11 -6
- package/packages/mailx-service/index.js.map +1 -1
- package/packages/mailx-service/index.ts +19 -11
- package/packages/mailx-service/local-store.d.ts.map +1 -1
- package/packages/mailx-service/local-store.js +9 -0
- package/packages/mailx-service/local-store.js.map +1 -1
- package/packages/mailx-service/local-store.ts +9 -0
- package/packages/mailx-settings/index.d.ts +1 -1
- package/packages/mailx-settings/index.d.ts.map +1 -1
- package/packages/mailx-settings/index.js +12 -6
- package/packages/mailx-settings/index.js.map +1 -1
- package/packages/mailx-settings/index.ts +12 -6
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Copy node_modules/quill/dist/{quill.js,quill.snow.css} → client/lib/quill/
|
|
3
|
+
// so compose can load Quill from disk instead of jsdelivr CDN. The CDN
|
|
4
|
+
// fetch was a 100-500 ms (network-dependent) tax on every compose open,
|
|
5
|
+
// since iframes ran a fresh `await loadScript(jsdelivr…)` chain even on
|
|
6
|
+
// warm starts. Local copy = single msger-protocol fetch = ~30 ms.
|
|
7
|
+
//
|
|
8
|
+
// Same shape as build-tinymce.js (sibling script). Build runs after
|
|
9
|
+
// `npm install`, before bundling, so the assets are present when the
|
|
10
|
+
// browser first reaches them.
|
|
11
|
+
import fs from "node:fs";
|
|
12
|
+
import path from "node:path";
|
|
13
|
+
|
|
14
|
+
const root = path.resolve(import.meta.dirname, "..");
|
|
15
|
+
const srcDir = path.join(root, "node_modules", "quill", "dist");
|
|
16
|
+
const dstDir = path.join(root, "client", "lib", "quill");
|
|
17
|
+
|
|
18
|
+
if (!fs.existsSync(srcDir)) {
|
|
19
|
+
console.error(`build-quill: source not found at ${srcDir} — run npm install first`);
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Only the two files the editor actually loads — Quill's other dist
|
|
24
|
+
// artifacts (bubble theme, core-only build, sourcemaps) aren't on the
|
|
25
|
+
// runtime path and would just bloat the client tree.
|
|
26
|
+
const files = ["quill.js", "quill.snow.css"];
|
|
27
|
+
fs.mkdirSync(dstDir, { recursive: true });
|
|
28
|
+
let totalBytes = 0;
|
|
29
|
+
for (const name of files) {
|
|
30
|
+
const s = path.join(srcDir, name);
|
|
31
|
+
const d = path.join(dstDir, name);
|
|
32
|
+
fs.copyFileSync(s, d);
|
|
33
|
+
totalBytes += fs.statSync(d).size;
|
|
34
|
+
}
|
|
35
|
+
console.log(`build-quill: copied ${files.length} files (${(totalBytes / 1024).toFixed(1)} KB) → client/lib/quill/`);
|
package/client/app.bundle.js
CHANGED
|
@@ -5758,9 +5758,11 @@ function updateBadge(count) {
|
|
|
5758
5758
|
async function updateNewMessageCount() {
|
|
5759
5759
|
try {
|
|
5760
5760
|
const accounts = await getAccounts();
|
|
5761
|
+
const folderLists = await Promise.all(
|
|
5762
|
+
accounts.map((acct) => getFolders(acct.id).catch(() => []))
|
|
5763
|
+
);
|
|
5761
5764
|
let totalUnread = 0;
|
|
5762
|
-
for (const
|
|
5763
|
-
const folders = await getFolders(acct.id);
|
|
5765
|
+
for (const folders of folderLists) {
|
|
5764
5766
|
const inbox = folders.find((f) => f.specialUse === "inbox");
|
|
5765
5767
|
if (inbox) totalUnread += inbox.unreadCount || 0;
|
|
5766
5768
|
}
|
|
@@ -5822,9 +5824,11 @@ document.addEventListener("visibilitychange", () => {
|
|
|
5822
5824
|
window.addEventListener("focus", stopTitleFlash);
|
|
5823
5825
|
function markAsSeen() {
|
|
5824
5826
|
getAccounts().then(async (accounts) => {
|
|
5827
|
+
const folderLists = await Promise.all(
|
|
5828
|
+
accounts.map((acct) => getFolders(acct.id).catch(() => []))
|
|
5829
|
+
);
|
|
5825
5830
|
let total = 0;
|
|
5826
|
-
for (const
|
|
5827
|
-
const folders = await getFolders(acct.id);
|
|
5831
|
+
for (const folders of folderLists) {
|
|
5828
5832
|
const inbox = folders.find((f) => f.specialUse === "inbox");
|
|
5829
5833
|
if (inbox) total += inbox.unreadCount || 0;
|
|
5830
5834
|
}
|
|
@@ -6166,9 +6170,13 @@ async function openCompose(mode) {
|
|
|
6166
6170
|
console.warn(`[compose] ${mode} \u2014 no message selected`);
|
|
6167
6171
|
return;
|
|
6168
6172
|
}
|
|
6169
|
-
const
|
|
6170
|
-
const accountId = current?.accountId || accounts[0]?.id || "";
|
|
6173
|
+
const accountsP = getAccounts();
|
|
6171
6174
|
const msg = current?.message;
|
|
6175
|
+
const titlePrefix = mode === "reply" ? "Reply" : mode === "replyAll" ? "Reply All" : mode === "forward" ? "Forward" : "Compose";
|
|
6176
|
+
const titleSubject = mode === "new" ? "" : msg?.subject || "";
|
|
6177
|
+
const frame = showComposeOverlay(titleSubject ? `${titlePrefix}: ${titleSubject}` : titlePrefix);
|
|
6178
|
+
const accounts = await accountsP;
|
|
6179
|
+
const accountId = current?.accountId || accounts[0]?.id || "";
|
|
6172
6180
|
const rePrefix = /^(re|fwd?):\s*/i;
|
|
6173
6181
|
const cleanSubject = msg ? msg.subject.replace(rePrefix, "") : "";
|
|
6174
6182
|
const init = {
|
|
@@ -6180,7 +6188,7 @@ async function openCompose(mode) {
|
|
|
6180
6188
|
bodyHtml: "",
|
|
6181
6189
|
inReplyTo: "",
|
|
6182
6190
|
references: [],
|
|
6183
|
-
accounts: accounts.map((a) => ({ id: a.id, name: a.name, email: a.email, signature: a.signature }))
|
|
6191
|
+
accounts: accounts.map((a) => ({ id: a.id, name: a.name, email: a.email, signature: a.signature, sig: a.sig }))
|
|
6184
6192
|
};
|
|
6185
6193
|
const account = accounts.find((a) => a.id === accountId);
|
|
6186
6194
|
const explicitDomains = (account?.identityDomains || []).map((d) => d.toLowerCase());
|
|
@@ -6234,9 +6242,10 @@ async function openCompose(mode) {
|
|
|
6234
6242
|
init.fromAddress = detectReplyFrom();
|
|
6235
6243
|
}
|
|
6236
6244
|
sessionStorage.setItem("composeInit", JSON.stringify(init));
|
|
6237
|
-
|
|
6238
|
-
|
|
6239
|
-
|
|
6245
|
+
try {
|
|
6246
|
+
frame?.contentWindow?.postMessage({ type: "compose-init-ready" }, "*");
|
|
6247
|
+
} catch {
|
|
6248
|
+
}
|
|
6240
6249
|
}
|
|
6241
6250
|
function showComposeOverlay(title = "Compose") {
|
|
6242
6251
|
const wrapper = document.createElement("div");
|
|
@@ -6357,6 +6366,7 @@ function showComposeOverlay(title = "Compose") {
|
|
|
6357
6366
|
wrapper.appendChild(frame);
|
|
6358
6367
|
if (!isSmall) addComposeResizeHandles(wrapper, frame);
|
|
6359
6368
|
document.body.appendChild(wrapper);
|
|
6369
|
+
return frame;
|
|
6360
6370
|
}
|
|
6361
6371
|
function installDragShield(cursor) {
|
|
6362
6372
|
const shield = document.createElement("div");
|
|
@@ -7574,7 +7584,9 @@ onWsEvent((event) => {
|
|
|
7574
7584
|
}
|
|
7575
7585
|
});
|
|
7576
7586
|
async function openComposeFromMailto(m) {
|
|
7577
|
-
const
|
|
7587
|
+
const accountsP = getAccounts();
|
|
7588
|
+
const frame = showComposeOverlay(m.subject ? `Compose: ${m.subject}` : "Compose");
|
|
7589
|
+
const accounts = await accountsP;
|
|
7578
7590
|
const accountId = accounts[0]?.id || "";
|
|
7579
7591
|
const escape = (s) => s.replace(/[&<>]/g, (c) => ({ "&": "&", "<": "<", ">": ">" })[c]);
|
|
7580
7592
|
const bodyHtml = m.body ? "<p>" + escape(m.body).replace(/\r?\n/g, "</p><p>") + "</p>" : "";
|
|
@@ -7588,10 +7600,13 @@ async function openComposeFromMailto(m) {
|
|
|
7588
7600
|
bodyHtml,
|
|
7589
7601
|
inReplyTo: m.inReplyTo,
|
|
7590
7602
|
references: m.inReplyTo ? [m.inReplyTo] : [],
|
|
7591
|
-
accounts: accounts.map((a) => ({ id: a.id, name: a.name, email: a.email, signature: a.signature }))
|
|
7603
|
+
accounts: accounts.map((a) => ({ id: a.id, name: a.name, email: a.email, signature: a.signature, sig: a.sig }))
|
|
7592
7604
|
};
|
|
7593
7605
|
sessionStorage.setItem("composeInit", JSON.stringify(init));
|
|
7594
|
-
|
|
7606
|
+
try {
|
|
7607
|
+
frame?.contentWindow?.postMessage({ type: "compose-init-ready" }, "*");
|
|
7608
|
+
} catch {
|
|
7609
|
+
}
|
|
7595
7610
|
}
|
|
7596
7611
|
window.addEventListener("keydown", (e) => {
|
|
7597
7612
|
if (!e.ctrlKey || e.altKey || e.metaKey) return;
|
|
@@ -8955,16 +8970,18 @@ function renderOutboxStatus(s) {
|
|
|
8955
8970
|
setInterval(async () => {
|
|
8956
8971
|
try {
|
|
8957
8972
|
const { getOutboxStatus: getOutboxStatus2, getDiagnostics: getDiagnostics2 } = await Promise.resolve().then(() => (init_api_client(), api_client_exports));
|
|
8958
|
-
|
|
8959
|
-
|
|
8973
|
+
const [outbox, diag] = await Promise.all([getOutboxStatus2(), getDiagnostics2()]);
|
|
8974
|
+
renderOutboxStatus(outbox);
|
|
8975
|
+
renderDiagnosticsBadge(diag);
|
|
8960
8976
|
} catch {
|
|
8961
8977
|
}
|
|
8962
8978
|
}, 15e3);
|
|
8963
8979
|
(async () => {
|
|
8964
8980
|
try {
|
|
8965
8981
|
const { getOutboxStatus: getOutboxStatus2, getDiagnostics: getDiagnostics2 } = await Promise.resolve().then(() => (init_api_client(), api_client_exports));
|
|
8966
|
-
|
|
8967
|
-
|
|
8982
|
+
const [outbox, diag] = await Promise.all([getOutboxStatus2(), getDiagnostics2()]);
|
|
8983
|
+
renderOutboxStatus(outbox);
|
|
8984
|
+
renderDiagnosticsBadge(diag);
|
|
8968
8985
|
} catch {
|
|
8969
8986
|
}
|
|
8970
8987
|
})();
|