@bobfrankston/rmfmail 1.2.5 → 1.2.7
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 +85 -4
- package/client/app.bundle.js.map +2 -2
- package/client/app.js +13 -1
- package/client/app.js.map +1 -1
- package/client/app.ts +11 -1
- package/client/components/alarms.js +75 -1
- package/client/components/alarms.js.map +1 -1
- package/client/components/alarms.ts +63 -1
- package/client/components/message-viewer.js +7 -2
- package/client/components/message-viewer.js.map +1 -1
- package/client/components/message-viewer.ts +7 -2
- package/client/compose/compose.bundle.js +45 -5
- package/client/compose/compose.bundle.js.map +2 -2
- package/client/compose/compose.js +3 -1
- package/client/compose/compose.js.map +1 -1
- package/client/compose/compose.ts +3 -1
- package/client/compose/editor.js +4 -4
- package/client/compose/editor.js.map +1 -1
- package/client/compose/editor.ts +10 -5
- package/client/lib/api-client.js +3 -0
- package/client/lib/api-client.js.map +1 -1
- package/client/lib/api-client.ts +3 -0
- package/client/lib/mailxapi.js +3 -0
- package/client/lib/rmf-tiny.js +47 -0
- package/package.json +5 -5
- package/packages/mailx-imap/index.d.ts.map +1 -1
- package/packages/mailx-imap/index.js +15 -0
- package/packages/mailx-imap/index.js.map +1 -1
- package/packages/mailx-imap/index.ts +15 -0
- package/packages/mailx-imap/package-lock.json +2 -2
- package/packages/mailx-imap/package.json +1 -1
- package/packages/mailx-service/index.d.ts +13 -0
- package/packages/mailx-service/index.d.ts.map +1 -1
- package/packages/mailx-service/index.js +42 -1
- package/packages/mailx-service/index.js.map +1 -1
- package/packages/mailx-service/index.ts +39 -1
- package/packages/mailx-service/jsonrpc.js +2 -0
- package/packages/mailx-service/jsonrpc.js.map +1 -1
- package/packages/mailx-service/jsonrpc.ts +2 -0
- package/packages/mailx-settings/cloud.d.ts +2 -0
- package/packages/mailx-settings/cloud.d.ts.map +1 -1
- package/packages/mailx-settings/cloud.js +45 -0
- package/packages/mailx-settings/cloud.js.map +1 -1
- package/packages/mailx-settings/cloud.ts +32 -0
- package/packages/mailx-settings/index.d.ts +9 -0
- package/packages/mailx-settings/index.d.ts.map +1 -1
- package/packages/mailx-settings/index.js +39 -0
- package/packages/mailx-settings/index.js.map +1 -1
- package/packages/mailx-settings/index.ts +35 -0
- package/test/service-boot.mjs +62 -0
- package/test/sync-worker-isolation.mjs +71 -0
package/client/app.bundle.js
CHANGED
|
@@ -59,6 +59,7 @@ __export(api_client_exports, {
|
|
|
59
59
|
getOutboxStatus: () => getOutboxStatus,
|
|
60
60
|
getPrimaryAccount: () => getPrimaryAccount,
|
|
61
61
|
getPriorityLists: () => getPriorityLists,
|
|
62
|
+
getReminderSound: () => getReminderSound,
|
|
62
63
|
getSettings: () => getSettings,
|
|
63
64
|
getSyncPending: () => getSyncPending,
|
|
64
65
|
getTasks: () => getTasks,
|
|
@@ -576,6 +577,9 @@ function getThreadMessages(accountId, threadId) {
|
|
|
576
577
|
function readJsoncFile(name) {
|
|
577
578
|
return ipc().readJsoncFile?.(name);
|
|
578
579
|
}
|
|
580
|
+
function getReminderSound() {
|
|
581
|
+
return ipc().getReminderSound?.();
|
|
582
|
+
}
|
|
579
583
|
function writeJsoncFile(name, content) {
|
|
580
584
|
return ipc().writeJsoncFile?.(name, content);
|
|
581
585
|
}
|
|
@@ -2237,7 +2241,7 @@ ${csp}
|
|
|
2237
2241
|
// dismissers it sees. The parent's debounced 500 ms show-timer still
|
|
2238
2242
|
// suppresses flicker.
|
|
2239
2243
|
var lastHoveredHref = "";
|
|
2240
|
-
function postLinkHover(href, rect) {
|
|
2244
|
+
function postLinkHover(href, rect, mouse) {
|
|
2241
2245
|
// Only post on transitions to avoid spamming the parent on every
|
|
2242
2246
|
// mousemove inside a link.
|
|
2243
2247
|
if (href === lastHoveredHref) return;
|
|
@@ -2246,6 +2250,11 @@ ${csp}
|
|
|
2246
2250
|
type: "linkHover",
|
|
2247
2251
|
url: href,
|
|
2248
2252
|
rect: rect ? { left: rect.left, top: rect.top, right: rect.right, bottom: rect.bottom } : null,
|
|
2253
|
+
// Cursor position (iframe-viewport coords) so the parent can anchor
|
|
2254
|
+
// the tooltip AT the pointer, not at the link's bottom-left corner \u2014
|
|
2255
|
+
// on a wide link/banner the corner is far from the cursor (Bob
|
|
2256
|
+
// 2026-06-13: "displays the URL far from the cursor").
|
|
2257
|
+
mouse: mouse || null,
|
|
2249
2258
|
}, "*");
|
|
2250
2259
|
}
|
|
2251
2260
|
document.addEventListener("mouseover", function (e) {
|
|
@@ -2254,7 +2263,7 @@ ${csp}
|
|
|
2254
2263
|
var href = a.getAttribute("href") || "";
|
|
2255
2264
|
if (!href || href.charAt(0) === "#" || href.indexOf("javascript:") === 0) return;
|
|
2256
2265
|
var r = a.getBoundingClientRect();
|
|
2257
|
-
postLinkHover(a.href || href, r);
|
|
2266
|
+
postLinkHover(a.href || href, r, { x: e.clientX, y: e.clientY });
|
|
2258
2267
|
}, true);
|
|
2259
2268
|
document.addEventListener("mouseout", function (e) {
|
|
2260
2269
|
var a = e.target && e.target.closest ? e.target.closest("a[href]") : null;
|
|
@@ -5375,6 +5384,68 @@ function alog(tag, data) {
|
|
|
5375
5384
|
} catch {
|
|
5376
5385
|
}
|
|
5377
5386
|
}
|
|
5387
|
+
async function playReminderSound() {
|
|
5388
|
+
const now = Date.now();
|
|
5389
|
+
if (now - _lastSoundAt < 2e3)
|
|
5390
|
+
return;
|
|
5391
|
+
_lastSoundAt = now;
|
|
5392
|
+
try {
|
|
5393
|
+
if (_soundCache === null) {
|
|
5394
|
+
const r = await getReminderSound().catch(() => ({}));
|
|
5395
|
+
if (r?.mute)
|
|
5396
|
+
_soundCache = { mute: true };
|
|
5397
|
+
else if (r?.dataBase64) {
|
|
5398
|
+
const bin = atob(r.dataBase64);
|
|
5399
|
+
const bytes = new Uint8Array(bin.length);
|
|
5400
|
+
for (let i = 0; i < bin.length; i++)
|
|
5401
|
+
bytes[i] = bin.charCodeAt(i);
|
|
5402
|
+
_soundCache = { url: URL.createObjectURL(new Blob([bytes], { type: r.mime || "audio/mpeg" })) };
|
|
5403
|
+
} else
|
|
5404
|
+
_soundCache = {};
|
|
5405
|
+
}
|
|
5406
|
+
if (_soundCache.mute)
|
|
5407
|
+
return;
|
|
5408
|
+
if (_soundCache.url) {
|
|
5409
|
+
const a = new Audio(_soundCache.url);
|
|
5410
|
+
a.play().catch(() => playChime());
|
|
5411
|
+
return;
|
|
5412
|
+
}
|
|
5413
|
+
playChime();
|
|
5414
|
+
} catch {
|
|
5415
|
+
try {
|
|
5416
|
+
playChime();
|
|
5417
|
+
} catch {
|
|
5418
|
+
}
|
|
5419
|
+
}
|
|
5420
|
+
}
|
|
5421
|
+
function playChime() {
|
|
5422
|
+
const Ctx = window.AudioContext || window.webkitAudioContext;
|
|
5423
|
+
if (!Ctx)
|
|
5424
|
+
return;
|
|
5425
|
+
const ctx = new Ctx();
|
|
5426
|
+
const t0 = ctx.currentTime;
|
|
5427
|
+
const tone = (freq, start, dur) => {
|
|
5428
|
+
const o = ctx.createOscillator();
|
|
5429
|
+
const g = ctx.createGain();
|
|
5430
|
+
o.type = "sine";
|
|
5431
|
+
o.frequency.value = freq;
|
|
5432
|
+
g.gain.setValueAtTime(1e-4, t0 + start);
|
|
5433
|
+
g.gain.linearRampToValueAtTime(0.22, t0 + start + 0.02);
|
|
5434
|
+
g.gain.exponentialRampToValueAtTime(1e-4, t0 + start + dur);
|
|
5435
|
+
o.connect(g);
|
|
5436
|
+
g.connect(ctx.destination);
|
|
5437
|
+
o.start(t0 + start);
|
|
5438
|
+
o.stop(t0 + start + dur + 0.05);
|
|
5439
|
+
};
|
|
5440
|
+
tone(880, 0, 0.35);
|
|
5441
|
+
tone(1174.66, 0.16, 0.42);
|
|
5442
|
+
setTimeout(() => {
|
|
5443
|
+
try {
|
|
5444
|
+
ctx.close();
|
|
5445
|
+
} catch {
|
|
5446
|
+
}
|
|
5447
|
+
}, 1300);
|
|
5448
|
+
}
|
|
5378
5449
|
function loadDismissed() {
|
|
5379
5450
|
try {
|
|
5380
5451
|
return JSON.parse(localStorage.getItem(DISMISSED_KEY) || "{}");
|
|
@@ -5652,6 +5723,7 @@ async function firePopupForItem(item) {
|
|
|
5652
5723
|
});
|
|
5653
5724
|
<\/script>
|
|
5654
5725
|
</body></html>`;
|
|
5726
|
+
void playReminderSound();
|
|
5655
5727
|
const title = item.kind === "calendar" ? "Calendar reminder" : "Task reminder";
|
|
5656
5728
|
const hasHost = !!window.mailxapi?.showReminderPopup;
|
|
5657
5729
|
let r;
|
|
@@ -5804,7 +5876,7 @@ function startAlarmPoller() {
|
|
|
5804
5876
|
});
|
|
5805
5877
|
});
|
|
5806
5878
|
}
|
|
5807
|
-
var DISMISSED_KEY, SNOOZED_KEY, LOOKBACK_MS, LOOKAHEAD_MS, POLL_INTERVAL_MS, firedThisSession, openPopups;
|
|
5879
|
+
var DISMISSED_KEY, SNOOZED_KEY, LOOKBACK_MS, LOOKAHEAD_MS, POLL_INTERVAL_MS, _soundCache, _lastSoundAt, firedThisSession, openPopups;
|
|
5808
5880
|
var init_alarms = __esm({
|
|
5809
5881
|
"client/components/alarms.js"() {
|
|
5810
5882
|
"use strict";
|
|
@@ -5814,6 +5886,8 @@ var init_alarms = __esm({
|
|
|
5814
5886
|
LOOKBACK_MS = 60 * 60 * 1e3;
|
|
5815
5887
|
LOOKAHEAD_MS = 2 * 60 * 60 * 1e3;
|
|
5816
5888
|
POLL_INTERVAL_MS = 3e4;
|
|
5889
|
+
_soundCache = null;
|
|
5890
|
+
_lastSoundAt = 0;
|
|
5817
5891
|
firedThisSession = /* @__PURE__ */ new Set();
|
|
5818
5892
|
openPopups = /* @__PURE__ */ new Set();
|
|
5819
5893
|
}
|
|
@@ -9063,7 +9137,14 @@ window.addEventListener("message", (e) => {
|
|
|
9063
9137
|
}
|
|
9064
9138
|
}
|
|
9065
9139
|
const r = data.rect;
|
|
9066
|
-
|
|
9140
|
+
const m = data.mouse;
|
|
9141
|
+
if (iframeRect && m) {
|
|
9142
|
+
const x = Math.max(4, Math.min(window.innerWidth - 528, iframeRect.left + m.x + 12));
|
|
9143
|
+
let y = iframeRect.top + m.y + 18;
|
|
9144
|
+
if (y + 60 > window.innerHeight) y = Math.max(4, iframeRect.top + m.y - 60);
|
|
9145
|
+
pop.style.left = x + "px";
|
|
9146
|
+
pop.style.top = y + "px";
|
|
9147
|
+
} else if (iframeRect && r) {
|
|
9067
9148
|
const x = Math.max(4, Math.min(window.innerWidth - 528, iframeRect.left + r.left));
|
|
9068
9149
|
let y = iframeRect.top + r.bottom + 4;
|
|
9069
9150
|
if (y + 60 > window.innerHeight) y = Math.max(4, iframeRect.top + r.top - 60);
|