@bobfrankston/rmfmail 1.0.704 → 1.0.705
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 +88 -9
- package/client/app.bundle.js.map +2 -2
- package/client/components/alarms.js +37 -7
- package/client/components/alarms.js.map +1 -1
- package/client/components/alarms.ts +32 -7
- package/client/components/message-list.js +48 -2
- package/client/components/message-list.js.map +1 -1
- package/client/components/message-list.ts +44 -2
- package/client/components/message-viewer.js +27 -0
- package/client/components/message-viewer.js.map +1 -1
- package/client/components/message-viewer.ts +23 -0
- package/client/compose/compose.bundle.js +16 -0
- package/client/compose/compose.bundle.js.map +2 -2
- package/client/compose/compose.js +37 -0
- package/client/compose/compose.js.map +1 -1
- package/client/compose/compose.ts +42 -0
- package/docs/accounts.md +1 -1
- package/package.json +1 -1
- package/packages/mailx-service/index.d.ts.map +1 -1
- package/packages/mailx-service/index.js +14 -0
- package/packages/mailx-service/index.js.map +1 -1
- package/packages/mailx-service/index.ts +15 -0
- package/packages/mailx-settings/docs/accounts.md +1 -1
- /package/packages/mailx-imap/{node_modules.npmglobalize-stash-40924 → node_modules.npmglobalize-stash-34984}/.package-lock.json +0 -0
package/client/app.bundle.js
CHANGED
|
@@ -2113,6 +2113,26 @@ var init_message_viewer = __esm({
|
|
|
2113
2113
|
else
|
|
2114
2114
|
bodyEl.prepend(banner);
|
|
2115
2115
|
});
|
|
2116
|
+
onEvent((ev) => {
|
|
2117
|
+
if (!ev || ev.type !== "draftSaved")
|
|
2118
|
+
return;
|
|
2119
|
+
if (!currentMessage || currentAccountId !== ev.accountId)
|
|
2120
|
+
return;
|
|
2121
|
+
if (currentMessage.uid !== ev.previousDraftUid)
|
|
2122
|
+
return;
|
|
2123
|
+
const newBody = String(ev.bodyHtml || "");
|
|
2124
|
+
currentMessage.bodyHtml = newBody;
|
|
2125
|
+
if (ev.subject)
|
|
2126
|
+
currentMessage.subject = ev.subject;
|
|
2127
|
+
const bodyEl = document.getElementById("mv-body");
|
|
2128
|
+
const iframe = bodyEl?.querySelector("iframe");
|
|
2129
|
+
if (iframe) {
|
|
2130
|
+
iframe.srcdoc = wrapHtmlBody(newBody, !!currentMessage.remoteAllowed);
|
|
2131
|
+
}
|
|
2132
|
+
const subjEl = document.querySelector(".mv-subject");
|
|
2133
|
+
if (subjEl && ev.subject)
|
|
2134
|
+
subjEl.textContent = String(ev.subject);
|
|
2135
|
+
});
|
|
2116
2136
|
}
|
|
2117
2137
|
});
|
|
2118
2138
|
|
|
@@ -3151,6 +3171,15 @@ var init_message_list = __esm({
|
|
|
3151
3171
|
markBodyCached() {
|
|
3152
3172
|
this.el.classList.remove("not-downloaded");
|
|
3153
3173
|
}
|
|
3174
|
+
/** Update the row's date column. Used by the draft-saved listener so
|
|
3175
|
+
* Ctrl+S in compose bumps the time in the Drafts list immediately
|
|
3176
|
+
* rather than waiting for the next IMAP APPEND + sync round-trip. */
|
|
3177
|
+
setDate(epochMs) {
|
|
3178
|
+
this.msg.date = epochMs;
|
|
3179
|
+
const el = this.el.querySelector(".ml-date");
|
|
3180
|
+
if (el)
|
|
3181
|
+
el.textContent = formatDate(epochMs);
|
|
3182
|
+
}
|
|
3154
3183
|
// Visual-state accessors for flag toggles. Read the *visual* state
|
|
3155
3184
|
// (CSS class), not `this.msg.flags`, because the flag array can lag
|
|
3156
3185
|
// the rendered class — auto-mark-as-read removes the `unread` class
|
|
@@ -3394,6 +3423,27 @@ var init_message_list = __esm({
|
|
|
3394
3423
|
},
|
|
3395
3424
|
{ label: "", action: () => {
|
|
3396
3425
|
}, separator: true },
|
|
3426
|
+
// Drafts get an explicit "Edit draft" entry as the primary action —
|
|
3427
|
+
// double-click already opens the row in compose, but the context
|
|
3428
|
+
// menu had no equivalent (Bob 2026-05-13). Detect via \Draft flag
|
|
3429
|
+
// or the Drafts folder context. Edit triggers the same path as
|
|
3430
|
+
// double-click: dispatching popout-message lets app.ts's draft
|
|
3431
|
+
// detection route through to compose.
|
|
3432
|
+
...(() => {
|
|
3433
|
+
const isDraftRow = draftOf(msg) || currentSpecialUse.toLowerCase() === "drafts";
|
|
3434
|
+
if (!isDraftRow)
|
|
3435
|
+
return [];
|
|
3436
|
+
return [
|
|
3437
|
+
{
|
|
3438
|
+
label: "Edit draft",
|
|
3439
|
+
action: () => document.dispatchEvent(new CustomEvent("mailx-popout-message", {
|
|
3440
|
+
detail: { accountId, uid: msg.uid, folderId: msg.folderId, subject: msg.subject }
|
|
3441
|
+
}))
|
|
3442
|
+
},
|
|
3443
|
+
{ label: "", action: () => {
|
|
3444
|
+
}, separator: true }
|
|
3445
|
+
];
|
|
3446
|
+
})(),
|
|
3397
3447
|
{ label: "Reply", action: () => document.dispatchEvent(new CustomEvent("mailx-compose", { detail: { mode: "reply" } })) },
|
|
3398
3448
|
{ label: "Reply All", action: () => document.dispatchEvent(new CustomEvent("mailx-compose", { detail: { mode: "replyAll" } })) },
|
|
3399
3449
|
{ label: "Forward", action: () => document.dispatchEvent(new CustomEvent("mailx-compose", { detail: { mode: "forward" } })) },
|
|
@@ -3444,6 +3494,15 @@ var init_message_list = __esm({
|
|
|
3444
3494
|
showContextMenu(e.clientX, e.clientY, items);
|
|
3445
3495
|
}
|
|
3446
3496
|
};
|
|
3497
|
+
onEvent((ev) => {
|
|
3498
|
+
if (!ev || ev.type !== "draftSaved")
|
|
3499
|
+
return;
|
|
3500
|
+
if (!ev.accountId || ev.previousDraftUid == null)
|
|
3501
|
+
return;
|
|
3502
|
+
const row = rowByKey.get(rowKey(ev.accountId, ev.previousDraftUid));
|
|
3503
|
+
if (row)
|
|
3504
|
+
row.setDate(typeof ev.savedAt === "number" ? ev.savedAt : Date.now());
|
|
3505
|
+
});
|
|
3447
3506
|
}
|
|
3448
3507
|
});
|
|
3449
3508
|
|
|
@@ -4519,23 +4578,43 @@ async function collectDueAlarms(now) {
|
|
|
4519
4578
|
if (!Array.isArray(ev.reminderMinutes) || ev.reminderMinutes.length === 0)
|
|
4520
4579
|
continue;
|
|
4521
4580
|
const offsets = ev.reminderMinutes.map((m) => m * 6e4);
|
|
4581
|
+
const occBaseKey = occKey(ev.uuid, startMs);
|
|
4582
|
+
let pick = null;
|
|
4583
|
+
const eligibleOffsets = [];
|
|
4522
4584
|
for (const offsetMs of offsets) {
|
|
4523
|
-
const occBaseKey = occKey(ev.uuid, startMs);
|
|
4524
4585
|
const key = `${occBaseKey}@${offsetMs}`;
|
|
4525
4586
|
if (dismissed[key])
|
|
4526
4587
|
continue;
|
|
4527
4588
|
const alarm = startMs - offsetMs;
|
|
4528
4589
|
const effective = snoozed[key] || alarm;
|
|
4529
4590
|
if (effective <= now && effective > now - LOOKBACK_MS) {
|
|
4530
|
-
|
|
4531
|
-
|
|
4532
|
-
|
|
4533
|
-
|
|
4534
|
-
|
|
4535
|
-
|
|
4536
|
-
|
|
4537
|
-
|
|
4591
|
+
eligibleOffsets.push(offsetMs);
|
|
4592
|
+
if (!pick || effective > pick.effective) {
|
|
4593
|
+
pick = { offsetMs, effective, key };
|
|
4594
|
+
}
|
|
4595
|
+
}
|
|
4596
|
+
}
|
|
4597
|
+
if (pick) {
|
|
4598
|
+
items.push({
|
|
4599
|
+
uuid: pick.key,
|
|
4600
|
+
kind: "calendar",
|
|
4601
|
+
title: ev.title || "(no title)",
|
|
4602
|
+
alarmMs: pick.effective,
|
|
4603
|
+
whenMs: startMs,
|
|
4604
|
+
htmlLink: ev.htmlLink
|
|
4605
|
+
});
|
|
4606
|
+
let touched = false;
|
|
4607
|
+
for (const offsetMs of eligibleOffsets) {
|
|
4608
|
+
if (offsetMs === pick.offsetMs)
|
|
4609
|
+
continue;
|
|
4610
|
+
const k = `${occBaseKey}@${offsetMs}`;
|
|
4611
|
+
if (!dismissed[k]) {
|
|
4612
|
+
dismissed[k] = true;
|
|
4613
|
+
touched = true;
|
|
4614
|
+
}
|
|
4538
4615
|
}
|
|
4616
|
+
if (touched)
|
|
4617
|
+
saveDismissed(dismissed);
|
|
4539
4618
|
}
|
|
4540
4619
|
}
|
|
4541
4620
|
} catch {
|