@bobfrankston/rmfmail 1.0.499 → 1.0.500
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.js +86 -1
- package/client/app.js.map +1 -1
- package/client/app.ts +71 -1
- package/client/components/message-list.js +34 -1
- package/client/components/message-list.js.map +1 -1
- package/client/components/message-list.ts +31 -1
- package/client/components/message-viewer.js +58 -14
- package/client/components/message-viewer.js.map +1 -1
- package/client/components/message-viewer.ts +56 -14
- package/client/index.html +9 -4
- package/client/lib/api-client.js +9 -0
- package/client/lib/api-client.js.map +1 -1
- package/client/lib/api-client.ts +12 -0
- package/client/lib/mailxapi.js +9 -0
- package/client/styles/components.css +47 -0
- package/package.json +1 -1
- package/packages/mailx-service/index.d.ts +16 -0
- package/packages/mailx-service/index.d.ts.map +1 -1
- package/packages/mailx-service/index.js +70 -0
- package/packages/mailx-service/index.js.map +1 -1
- package/packages/mailx-service/index.ts +50 -0
- package/packages/mailx-service/jsonrpc.js +8 -0
- package/packages/mailx-service/jsonrpc.js.map +1 -1
- package/packages/mailx-service/jsonrpc.ts +8 -0
- package/packages/mailx-store/db.d.ts +13 -0
- package/packages/mailx-store/db.d.ts.map +1 -1
- package/packages/mailx-store/db.js +31 -0
- package/packages/mailx-store/db.js.map +1 -1
- package/packages/mailx-store/db.ts +33 -1
- package/packages/mailx-store-web/android-bootstrap.js +12 -0
- package/packages/mailx-store-web/android-bootstrap.js.map +1 -1
- package/packages/mailx-store-web/android-bootstrap.ts +10 -0
- package/packages/mailx-store-web/web-jsonrpc.js +10 -0
- package/packages/mailx-store-web/web-jsonrpc.js.map +1 -1
- package/packages/mailx-store-web/web-jsonrpc.ts +10 -0
- package/packages/mailx-store-web/web-service.d.ts +17 -0
- package/packages/mailx-store-web/web-service.d.ts.map +1 -1
- package/packages/mailx-store-web/web-service.js +107 -4
- package/packages/mailx-store-web/web-service.js.map +1 -1
- package/packages/mailx-store-web/web-service.ts +100 -4
- package/packages/mailx-store-web/web-settings.d.ts +2 -0
- package/packages/mailx-store-web/web-settings.d.ts.map +1 -1
- package/packages/mailx-store-web/web-settings.js +2 -0
- package/packages/mailx-store-web/web-settings.js.map +1 -1
- package/packages/mailx-store-web/web-settings.ts +2 -0
package/client/app.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Wires together all UI components and WebSocket connection.
|
|
4
4
|
*/
|
|
5
5
|
import { initFolderTree, refreshFolderTree, updateFolderCounts, setFolderSynced, getFolderSynced, setOutboxTotal } from "./components/folder-tree.js";
|
|
6
|
-
import { initMessageList, loadMessages, loadUnifiedInbox, loadSearchResults, reloadCurrentFolder, clearSearchMode, getSelectedMessages, markBodiesCached, getCurrentFocused, releaseFocus, removeMessagesAndReconcile, setRowFlagged, scrollFocusedIntoView } from "./components/message-list.js";
|
|
6
|
+
import { initMessageList, loadMessages, loadUnifiedInbox, loadSearchResults, reloadCurrentFolder, clearSearchMode, getSelectedMessages, markBodiesCached, getCurrentFocused, releaseFocus, removeMessagesAndReconcile, setRowFlagged, scrollFocusedIntoView, refreshPriorityIndex } from "./components/message-list.js";
|
|
7
7
|
import { showMessage, getCurrentMessage, initViewer, popOutCurrentMessage, toggleFullscreenPreview, showPreviewBodyMenu } from "./components/message-viewer.js";
|
|
8
8
|
import { connectWebSocket, onWsEvent, triggerSync, syncAccount, reauthenticate, getAccounts, getFolders, deleteMessages, undeleteMessage, restartServer, getSyncPending, getVersion, getSettings, saveSettings, getAutocompleteSettings, saveAutocompleteSettings, repairAccounts, updateFlags, markAsSpamMessages, logClientEvent, sendMessage as apiSendMessage } from "./lib/api-client.js";
|
|
9
9
|
import * as messageState from "./lib/message-state.js";
|
|
@@ -1294,6 +1294,11 @@ function applyTheme(theme) {
|
|
|
1294
1294
|
const radio = document.getElementById(`opt-theme-${theme}`);
|
|
1295
1295
|
if (radio)
|
|
1296
1296
|
radio.checked = true;
|
|
1297
|
+
// Update the submenu's "current" badge so the user sees the choice
|
|
1298
|
+
// without expanding.
|
|
1299
|
+
const cur = document.getElementById("theme-submenu-current");
|
|
1300
|
+
if (cur)
|
|
1301
|
+
cur.textContent = theme.charAt(0).toUpperCase() + theme.slice(1);
|
|
1297
1302
|
}
|
|
1298
1303
|
// Restore saved theme + wire the Settings radios. Defaults to "system".
|
|
1299
1304
|
(() => {
|
|
@@ -1310,6 +1315,24 @@ function applyTheme(theme) {
|
|
|
1310
1315
|
applyTheme(t);
|
|
1311
1316
|
});
|
|
1312
1317
|
}
|
|
1318
|
+
// Wire the submenu toggle. Click to expand; click outside / on a radio closes.
|
|
1319
|
+
const togBtn = document.getElementById("theme-submenu-toggle");
|
|
1320
|
+
const popout = document.getElementById("theme-submenu-popout");
|
|
1321
|
+
if (togBtn && popout) {
|
|
1322
|
+
togBtn.addEventListener("click", (e) => {
|
|
1323
|
+
e.stopPropagation();
|
|
1324
|
+
const open = popout.hidden;
|
|
1325
|
+
popout.hidden = !open;
|
|
1326
|
+
togBtn.setAttribute("aria-expanded", String(open));
|
|
1327
|
+
});
|
|
1328
|
+
// Close on radio change so the menu doesn't linger after the choice.
|
|
1329
|
+
popout.querySelectorAll('input[type="radio"]').forEach(r => {
|
|
1330
|
+
r.addEventListener("change", () => {
|
|
1331
|
+
popout.hidden = true;
|
|
1332
|
+
togBtn.setAttribute("aria-expanded", "false");
|
|
1333
|
+
});
|
|
1334
|
+
});
|
|
1335
|
+
}
|
|
1313
1336
|
})();
|
|
1314
1337
|
// Highlight the current rail target. For now just inbox is the default; once
|
|
1315
1338
|
// calendar/tasks ship, update this on view change.
|
|
@@ -1329,6 +1352,47 @@ document.addEventListener("mailx-compose", ((e) => {
|
|
|
1329
1352
|
}
|
|
1330
1353
|
}));
|
|
1331
1354
|
document.addEventListener("mailx-delete", () => deleteSelectedMessages());
|
|
1355
|
+
// Share / mailto intents (Android-side: MainActivity routes share-sheet
|
|
1356
|
+
// invocations and mailto: links here. Desktop has no equivalent today —
|
|
1357
|
+
// MSIX / Windows share-target requires packaging changes we deferred).
|
|
1358
|
+
// Payload: { action, text, subject, mailto }. Mailto URLs are parsed
|
|
1359
|
+
// (RFC 2368: mailto:to?subject=...&body=...&cc=...&bcc=...) and used to
|
|
1360
|
+
// pre-fill compose. Plain shares (text/url) drop into the body / subject.
|
|
1361
|
+
document.addEventListener("mailx-share-intent", ((e) => {
|
|
1362
|
+
const detail = e.detail || {};
|
|
1363
|
+
const init = { mode: "new", to: [], cc: [], bcc: [], subject: "", bodyHtml: "" };
|
|
1364
|
+
if (detail.mailto) {
|
|
1365
|
+
try {
|
|
1366
|
+
const url = new URL(detail.mailto);
|
|
1367
|
+
const to = decodeURIComponent(url.pathname).split(",").map((s) => s.trim()).filter(Boolean);
|
|
1368
|
+
init.to = to;
|
|
1369
|
+
const sp = url.searchParams;
|
|
1370
|
+
const subj = sp.get("subject");
|
|
1371
|
+
if (subj)
|
|
1372
|
+
init.subject = subj;
|
|
1373
|
+
const body = sp.get("body");
|
|
1374
|
+
if (body)
|
|
1375
|
+
init.bodyHtml = `<p>${body.replace(/\n/g, "<br>")}</p>`;
|
|
1376
|
+
const cc = sp.get("cc");
|
|
1377
|
+
if (cc)
|
|
1378
|
+
init.cc = cc.split(",").map(s => s.trim()).filter(Boolean);
|
|
1379
|
+
const bcc = sp.get("bcc");
|
|
1380
|
+
if (bcc)
|
|
1381
|
+
init.bcc = bcc.split(",").map(s => s.trim()).filter(Boolean);
|
|
1382
|
+
}
|
|
1383
|
+
catch { /* malformed mailto: — drop the URL into body so user can fix */
|
|
1384
|
+
init.bodyHtml = `<p>${escapeHtml(detail.mailto)}</p>`;
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1387
|
+
else {
|
|
1388
|
+
if (detail.subject)
|
|
1389
|
+
init.subject = detail.subject;
|
|
1390
|
+
if (detail.text)
|
|
1391
|
+
init.bodyHtml = `<p>${escapeHtml(String(detail.text)).replace(/\n/g, "<br>")}</p>`;
|
|
1392
|
+
}
|
|
1393
|
+
sessionStorage.setItem("composeInit", JSON.stringify(init));
|
|
1394
|
+
showComposeOverlay(init.subject || "Compose");
|
|
1395
|
+
}));
|
|
1332
1396
|
// ── Search ──
|
|
1333
1397
|
let searchTimeout;
|
|
1334
1398
|
const searchInput = document.getElementById("search-input");
|
|
@@ -1785,6 +1849,10 @@ if (splitter) {
|
|
|
1785
1849
|
}
|
|
1786
1850
|
// ── WebSocket for live updates ──
|
|
1787
1851
|
connectWebSocket();
|
|
1852
|
+
// Priority-sender index — fetch once on load. Refreshed on the contacts
|
|
1853
|
+
// configChanged event (below) so changes from another device propagate
|
|
1854
|
+
// without a full reload.
|
|
1855
|
+
refreshPriorityIndex().catch(() => { });
|
|
1788
1856
|
onWsEvent((event) => {
|
|
1789
1857
|
const statusSync = document.getElementById("status-sync");
|
|
1790
1858
|
const startupStatus = document.getElementById("startup-status");
|
|
@@ -3172,6 +3240,23 @@ optFlagged?.addEventListener("change", () => {
|
|
|
3172
3240
|
localStorage.setItem("mailx-flagged", String(optFlagged.checked));
|
|
3173
3241
|
reloadCurrentFolder();
|
|
3174
3242
|
});
|
|
3243
|
+
// Priority-senders-only filter — same pattern as flagged-only. Adds
|
|
3244
|
+
// .priority-only to the list body; CSS hides any row without .priority.
|
|
3245
|
+
const optPriorityOnly = document.getElementById("opt-priority-only");
|
|
3246
|
+
if (optPriorityOnly) {
|
|
3247
|
+
optPriorityOnly.checked = localStorage.getItem("mailx-priority-only") === "true";
|
|
3248
|
+
const body0 = document.getElementById("ml-body");
|
|
3249
|
+
if (optPriorityOnly.checked)
|
|
3250
|
+
body0?.classList.add("priority-only");
|
|
3251
|
+
optPriorityOnly.addEventListener("change", () => {
|
|
3252
|
+
const body = document.getElementById("ml-body");
|
|
3253
|
+
if (optPriorityOnly.checked)
|
|
3254
|
+
body?.classList.add("priority-only");
|
|
3255
|
+
else
|
|
3256
|
+
body?.classList.remove("priority-only");
|
|
3257
|
+
localStorage.setItem("mailx-priority-only", String(optPriorityOnly.checked));
|
|
3258
|
+
});
|
|
3259
|
+
}
|
|
3175
3260
|
// Folder counts toggle
|
|
3176
3261
|
optFolderCounts?.addEventListener("change", () => {
|
|
3177
3262
|
const tree = document.getElementById("folder-tree");
|