@bobfrankston/rmfmail 1.0.666 → 1.0.668
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/TODO.md +2 -0
- package/bin/mailx.js +114 -111
- package/bin/mailx.js.map +1 -1
- package/bin/mailx.ts +117 -95
- package/client/app.bundle.js +143 -13
- package/client/app.bundle.js.map +2 -2
- package/client/components/alarms.js +138 -16
- package/client/components/alarms.js.map +1 -1
- package/client/components/alarms.ts +138 -17
- package/client/components/calendar-sidebar.js +39 -3
- package/client/components/calendar-sidebar.js.map +1 -1
- package/client/components/calendar-sidebar.ts +39 -2
- package/client/compose/compose.bundle.js.map +1 -1
- package/client/index.html +6 -0
- package/client/lib/api-client.ts +1 -1
- package/client/styles/components.css +4 -0
- package/package.json +1 -1
- package/packages/mailx-host/index.d.ts +5 -0
- package/packages/mailx-host/index.d.ts.map +1 -1
- package/packages/mailx-host/index.js +5 -0
- package/packages/mailx-host/index.js.map +1 -1
- package/packages/mailx-host/index.ts +5 -0
- package/packages/mailx-host/package.json +1 -1
- package/packages/mailx-service/index.d.ts +1 -0
- package/packages/mailx-service/index.d.ts.map +1 -1
- package/packages/mailx-service/index.js +95 -9
- package/packages/mailx-service/index.js.map +1 -1
- package/packages/mailx-service/index.ts +93 -10
- package/packages/mailx-service/local-store.d.ts +4 -0
- package/packages/mailx-service/local-store.d.ts.map +1 -1
- package/packages/mailx-service/local-store.js +55 -1
- package/packages/mailx-service/local-store.js.map +1 -1
- package/packages/mailx-service/local-store.ts +51 -1
- package/packages/mailx-store/db.d.ts +1 -0
- package/packages/mailx-store/db.d.ts.map +1 -1
- package/packages/mailx-store/db.js +11 -4
- package/packages/mailx-store/db.js.map +1 -1
- package/packages/mailx-store/db.ts +13 -5
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* hidden — alarm won't fire until user returns, which matches Thunderbird's
|
|
18
18
|
* behavior (focus-gated). OS-level notifications are a separate follow-up.
|
|
19
19
|
*/
|
|
20
|
-
import { getCalendarEvents, getTasks, showReminderPopup } from "../lib/api-client.js";
|
|
20
|
+
import { getCalendarEvents, getTasks, showReminderPopup, deleteCalendarEvent } from "../lib/api-client.js";
|
|
21
21
|
const DISMISSED_KEY = "mailx-alarm-dismissed"; // { uuid: true }
|
|
22
22
|
const SNOOZED_KEY = "mailx-alarm-snoozed"; // { uuid: epoch-ms-end }
|
|
23
23
|
const CAL_LEAD_MS = 10 * 60 * 1000; // 10 min before cal event start
|
|
@@ -199,34 +199,131 @@ async function firePopupForItem(item) {
|
|
|
199
199
|
if (openPopups.has(item.uuid))
|
|
200
200
|
return;
|
|
201
201
|
openPopups.add(item.uuid);
|
|
202
|
+
// Buttons map to msger's `buttons` array for the keyboard-default
|
|
203
|
+
// detection in template mode; in rawHtml we render our own controls,
|
|
204
|
+
// but the array still flows back as the default-button fallback if
|
|
205
|
+
// the user closes the window without picking. Order = priority.
|
|
206
|
+
const buttons = ["snooze", "Dismiss"];
|
|
207
|
+
if (item.htmlLink)
|
|
208
|
+
buttons.push("Open");
|
|
209
|
+
if (item.kind === "calendar")
|
|
210
|
+
buttons.push("Delete");
|
|
211
|
+
// rawHtml mode. msger's design intent is that we deliver any HTML
|
|
212
|
+
// form and the parent process receives whatever `window.ipc.postMessage`
|
|
213
|
+
// serializes — `MessageBoxResult` includes a `form: serde_json::Value`
|
|
214
|
+
// field for exactly this. We mirror Thunderbird's snooze popup: a
|
|
215
|
+
// row of preset chips PLUS a custom "N units" form. Snooze submits
|
|
216
|
+
// `{button:"snooze", form:{minutes:N}}` so the daemon can handle any
|
|
217
|
+
// duration; Dismiss/Open/Delete still discriminate by button label.
|
|
218
|
+
const icon = item.kind === "calendar" ? "📅" : "☑";
|
|
219
|
+
const kindLabel = item.kind === "calendar" ? "Calendar event" : "Task due";
|
|
220
|
+
// Presets in minutes. Tuned to TBird's defaults — covers the common
|
|
221
|
+
// "give me 15 more minutes" through "remind me tomorrow morning."
|
|
222
|
+
const presets = [
|
|
223
|
+
{ label: "5m", minutes: 5 },
|
|
224
|
+
{ label: "15m", minutes: 15 },
|
|
225
|
+
{ label: "30m", minutes: 30 },
|
|
226
|
+
{ label: "1h", minutes: 60 },
|
|
227
|
+
{ label: "2h", minutes: 120 },
|
|
228
|
+
{ label: "1d", minutes: 60 * 24 },
|
|
229
|
+
];
|
|
230
|
+
const presetChips = presets.map(p => `<button type="button" class="chip" data-snooze-min="${p.minutes}">${p.label}</button>`).join("");
|
|
231
|
+
const actionBtns = ["Dismiss"];
|
|
232
|
+
if (item.htmlLink)
|
|
233
|
+
actionBtns.push("Open");
|
|
234
|
+
if (item.kind === "calendar")
|
|
235
|
+
actionBtns.push("Delete");
|
|
236
|
+
const actionHtml = actionBtns.map(b => `<button type="button" class="action" data-btn="${escapeHtml(b)}">${escapeHtml(b)}</button>`).join("");
|
|
202
237
|
const html = `<!DOCTYPE html>
|
|
203
238
|
<html><head><meta charset="utf-8"><style>
|
|
204
|
-
body {
|
|
205
|
-
|
|
206
|
-
.
|
|
207
|
-
.
|
|
239
|
+
html, body { height: 100%; }
|
|
240
|
+
body { font: 13px system-ui, sans-serif; margin: 0; padding: 14px 16px; background: #fff; color: #222; display:flex; flex-direction:column; box-sizing:border-box; gap: 8px; }
|
|
241
|
+
.icon { display: inline-block; width: 20px; text-align: center; margin-right: 4px; }
|
|
242
|
+
.title { font-size: 1.1em; font-weight: 600; }
|
|
243
|
+
.when { color: #555; font-size: 0.95em; }
|
|
208
244
|
.kind { color: #888; font-size: 0.85em; }
|
|
245
|
+
.spacer { flex: 1; }
|
|
246
|
+
.row { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
|
|
247
|
+
.row-label { color: #555; font-size: 0.85em; margin-right: 2px; }
|
|
248
|
+
button { font: 13px system-ui, sans-serif; cursor: pointer; }
|
|
249
|
+
.chip { padding: 3px 9px; border: 1px solid #ccc; border-radius: 12px; background: #f7f7f7; color: #222; }
|
|
250
|
+
.chip:hover { background: #e8f0fe; border-color: #0066cc; color: #0066cc; }
|
|
251
|
+
.custom { display: flex; align-items: center; gap: 4px; }
|
|
252
|
+
.custom input[type=number] { width: 48px; padding: 2px 4px; border: 1px solid #ccc; border-radius: 3px; font: inherit; }
|
|
253
|
+
.custom select { padding: 2px 4px; border: 1px solid #ccc; border-radius: 3px; font: inherit; background: #fff; }
|
|
254
|
+
.custom button.ok { padding: 2px 8px; border: 1px solid #0066cc; border-radius: 3px; background: #0066cc; color: #fff; }
|
|
255
|
+
.custom button.ok:hover { background: #0052a3; }
|
|
256
|
+
.actions { display: flex; gap: 8px; justify-content: flex-end; margin-top: 4px; }
|
|
257
|
+
.actions button.action { padding: 5px 14px; border: none; border-radius: 4px; background: #0066cc; color: #fff; min-width: 70px; }
|
|
258
|
+
.actions button.action:hover { background: #0052a3; }
|
|
259
|
+
.actions button.action[data-btn="Delete"] { background: #b00; }
|
|
260
|
+
.actions button.action[data-btn="Delete"]:hover { background: #800; }
|
|
209
261
|
</style></head><body>
|
|
210
|
-
<div class="title"><span class="icon">${
|
|
262
|
+
<div class="title"><span class="icon">${icon}</span>${escapeHtml(item.title)}</div>
|
|
211
263
|
<div class="when">${escapeHtml(formatWhen(item.whenMs))}</div>
|
|
212
|
-
<div class="kind">${
|
|
264
|
+
<div class="kind">${kindLabel}</div>
|
|
265
|
+
<div class="row">
|
|
266
|
+
<span class="row-label">Snooze:</span>
|
|
267
|
+
${presetChips}
|
|
268
|
+
</div>
|
|
269
|
+
<div class="row custom">
|
|
270
|
+
<span class="row-label">Custom:</span>
|
|
271
|
+
<input type="number" id="customN" value="5" min="1" max="999">
|
|
272
|
+
<select id="customUnit">
|
|
273
|
+
<option value="1">minutes</option>
|
|
274
|
+
<option value="60">hours</option>
|
|
275
|
+
<option value="1440">days</option>
|
|
276
|
+
</select>
|
|
277
|
+
<button type="button" class="ok" id="customGo">Snooze</button>
|
|
278
|
+
</div>
|
|
279
|
+
<div class="spacer"></div>
|
|
280
|
+
<div class="actions">${actionHtml}</div>
|
|
281
|
+
<script>
|
|
282
|
+
function send(payload) {
|
|
283
|
+
try { window.ipc.postMessage(JSON.stringify(payload)); }
|
|
284
|
+
catch (e) { try { window.close(); } catch (_) {} }
|
|
285
|
+
}
|
|
286
|
+
// Preset chips → snooze N minutes
|
|
287
|
+
document.querySelectorAll("button[data-snooze-min]").forEach(function(b) {
|
|
288
|
+
b.addEventListener("click", function() {
|
|
289
|
+
var m = parseInt(b.getAttribute("data-snooze-min"), 10) || 15;
|
|
290
|
+
send({ button: "snooze", form: { minutes: m } });
|
|
291
|
+
});
|
|
292
|
+
});
|
|
293
|
+
// Custom snooze form → snooze N * unit-multiplier minutes
|
|
294
|
+
var customGo = document.getElementById("customGo");
|
|
295
|
+
var customN = document.getElementById("customN");
|
|
296
|
+
var customUnit = document.getElementById("customUnit");
|
|
297
|
+
function submitCustom() {
|
|
298
|
+
var n = parseInt(customN.value, 10);
|
|
299
|
+
if (!isFinite(n) || n < 1) n = 5;
|
|
300
|
+
var mult = parseInt(customUnit.value, 10) || 1;
|
|
301
|
+
send({ button: "snooze", form: { minutes: n * mult } });
|
|
302
|
+
}
|
|
303
|
+
customGo.addEventListener("click", submitCustom);
|
|
304
|
+
customN.addEventListener("keydown", function(e) { if (e.key === "Enter") submitCustom(); });
|
|
305
|
+
// Action buttons (Dismiss/Open/Delete) → discriminate by label.
|
|
306
|
+
document.querySelectorAll("button[data-btn]").forEach(function(b) {
|
|
307
|
+
b.addEventListener("click", function() {
|
|
308
|
+
send({ button: b.getAttribute("data-btn") });
|
|
309
|
+
});
|
|
310
|
+
});
|
|
311
|
+
</script>
|
|
213
312
|
</body></html>`;
|
|
214
|
-
// Button labels. Open opens the htmlLink (Google Calendar editor)
|
|
215
|
-
// and clears all local alarm state so the next poll tick treats the
|
|
216
|
-
// event as a fresh entry — if the user moves the start time during
|
|
217
|
-
// the edit, the new alarm fires off the new time, not the old one.
|
|
218
|
-
// Tasks have no htmlLink so Open is skipped for them.
|
|
219
|
-
const buttons = ["Snooze 15m", "Snooze 1h", "Dismiss"];
|
|
220
|
-
if (item.htmlLink)
|
|
221
|
-
buttons.push("Open");
|
|
222
313
|
const title = item.kind === "calendar" ? "Calendar reminder" : "Task reminder";
|
|
223
314
|
const hasHost = !!window.mailxapi?.showReminderPopup;
|
|
315
|
+
// Result now carries an optional `form` object — see msger's
|
|
316
|
+
// MessageBoxResult.form (serde_json::Value passthrough). Snooze
|
|
317
|
+
// chips/inputs send `{ button: "snooze", form: { minutes: N } }`.
|
|
224
318
|
let r;
|
|
225
319
|
try {
|
|
226
320
|
if (hasHost) {
|
|
227
321
|
r = await showReminderPopup({
|
|
228
322
|
title, html, buttons,
|
|
229
|
-
|
|
323
|
+
// Sized for the new snooze form (chips row + custom input
|
|
324
|
+
// row + action buttons) plus title/when/kind. Width fits
|
|
325
|
+
// "5m 15m 30m 1h 2h 1d" on one line in Segoe UI.
|
|
326
|
+
size: { width: 560, height: 300 },
|
|
230
327
|
});
|
|
231
328
|
}
|
|
232
329
|
else {
|
|
@@ -270,6 +367,18 @@ async function firePopupForItem(item) {
|
|
|
270
367
|
firedThisSession.delete(item.uuid);
|
|
271
368
|
snoozeItem(item, 2);
|
|
272
369
|
break;
|
|
370
|
+
case "snooze": {
|
|
371
|
+
// Generic snooze, duration in `form.minutes`. Falls back to
|
|
372
|
+
// 15 min if the form is malformed or missing the value (the
|
|
373
|
+
// chip / custom-form JS always populates it, so this is just
|
|
374
|
+
// defense-in-depth).
|
|
375
|
+
const m = Math.max(1, Math.floor(r.form?.minutes ?? 15));
|
|
376
|
+
snoozeItem(item, m);
|
|
377
|
+
break;
|
|
378
|
+
}
|
|
379
|
+
// Legacy literal labels — retained so a pre-upgrade popup whose
|
|
380
|
+
// bundle still says "Snooze 15m" / "Snooze 1h" continues to work
|
|
381
|
+
// through a daemon-side rebuild without a UI restart.
|
|
273
382
|
case "Snooze 15m":
|
|
274
383
|
snoozeItem(item, 15);
|
|
275
384
|
break;
|
|
@@ -283,6 +392,19 @@ async function firePopupForItem(item) {
|
|
|
283
392
|
saveDismissed(m);
|
|
284
393
|
}
|
|
285
394
|
break;
|
|
395
|
+
case "Delete":
|
|
396
|
+
// Remove the event server-side. Local row gets the pending-delete
|
|
397
|
+
// mark inside the service; reconcile picks it up. Also dismiss
|
|
398
|
+
// the alarm so it can't re-fire on a stale local row before the
|
|
399
|
+
// delete propagates.
|
|
400
|
+
{
|
|
401
|
+
const m = loadDismissed();
|
|
402
|
+
m[item.uuid] = true;
|
|
403
|
+
saveDismissed(m);
|
|
404
|
+
}
|
|
405
|
+
firedThisSession.delete(item.uuid);
|
|
406
|
+
deleteCalendarEvent(item.uuid).catch((e) => console.error(` [alarm] delete failed for ${item.uuid}: ${e?.message || e}`));
|
|
407
|
+
break;
|
|
286
408
|
default:
|
|
287
409
|
// User closed the window via X / Esc / "closed" / "dismissed"
|
|
288
410
|
// without picking a labeled button. Treat as a 15-minute
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"alarms.js","sourceRoot":"","sources":["alarms.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"alarms.js","sourceRoot":"","sources":["alarms.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* behavior (focus-gated). OS-level notifications are a separate follow-up.
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
-
import { getCalendarEvents, getTasks, showReminderPopup } from "../lib/api-client.js";
|
|
21
|
+
import { getCalendarEvents, getTasks, showReminderPopup, deleteCalendarEvent } from "../lib/api-client.js";
|
|
22
22
|
|
|
23
23
|
const DISMISSED_KEY = "mailx-alarm-dismissed"; // { uuid: true }
|
|
24
24
|
const SNOOZED_KEY = "mailx-alarm-snoozed"; // { uuid: epoch-ms-end }
|
|
@@ -192,35 +192,134 @@ async function firePopupForItem(item: AlarmItem): Promise<void> {
|
|
|
192
192
|
if (openPopups.has(item.uuid)) return;
|
|
193
193
|
openPopups.add(item.uuid);
|
|
194
194
|
|
|
195
|
+
// Buttons map to msger's `buttons` array for the keyboard-default
|
|
196
|
+
// detection in template mode; in rawHtml we render our own controls,
|
|
197
|
+
// but the array still flows back as the default-button fallback if
|
|
198
|
+
// the user closes the window without picking. Order = priority.
|
|
199
|
+
const buttons: string[] = ["snooze", "Dismiss"];
|
|
200
|
+
if (item.htmlLink) buttons.push("Open");
|
|
201
|
+
if (item.kind === "calendar") buttons.push("Delete");
|
|
202
|
+
|
|
203
|
+
// rawHtml mode. msger's design intent is that we deliver any HTML
|
|
204
|
+
// form and the parent process receives whatever `window.ipc.postMessage`
|
|
205
|
+
// serializes — `MessageBoxResult` includes a `form: serde_json::Value`
|
|
206
|
+
// field for exactly this. We mirror Thunderbird's snooze popup: a
|
|
207
|
+
// row of preset chips PLUS a custom "N units" form. Snooze submits
|
|
208
|
+
// `{button:"snooze", form:{minutes:N}}` so the daemon can handle any
|
|
209
|
+
// duration; Dismiss/Open/Delete still discriminate by button label.
|
|
210
|
+
const icon = item.kind === "calendar" ? "📅" : "☑";
|
|
211
|
+
const kindLabel = item.kind === "calendar" ? "Calendar event" : "Task due";
|
|
212
|
+
// Presets in minutes. Tuned to TBird's defaults — covers the common
|
|
213
|
+
// "give me 15 more minutes" through "remind me tomorrow morning."
|
|
214
|
+
const presets: Array<{ label: string; minutes: number }> = [
|
|
215
|
+
{ label: "5m", minutes: 5 },
|
|
216
|
+
{ label: "15m", minutes: 15 },
|
|
217
|
+
{ label: "30m", minutes: 30 },
|
|
218
|
+
{ label: "1h", minutes: 60 },
|
|
219
|
+
{ label: "2h", minutes: 120 },
|
|
220
|
+
{ label: "1d", minutes: 60 * 24 },
|
|
221
|
+
];
|
|
222
|
+
const presetChips = presets.map(p =>
|
|
223
|
+
`<button type="button" class="chip" data-snooze-min="${p.minutes}">${p.label}</button>`
|
|
224
|
+
).join("");
|
|
225
|
+
const actionBtns: string[] = ["Dismiss"];
|
|
226
|
+
if (item.htmlLink) actionBtns.push("Open");
|
|
227
|
+
if (item.kind === "calendar") actionBtns.push("Delete");
|
|
228
|
+
const actionHtml = actionBtns.map(b =>
|
|
229
|
+
`<button type="button" class="action" data-btn="${escapeHtml(b)}">${escapeHtml(b)}</button>`
|
|
230
|
+
).join("");
|
|
231
|
+
|
|
195
232
|
const html = `<!DOCTYPE html>
|
|
196
233
|
<html><head><meta charset="utf-8"><style>
|
|
197
|
-
body {
|
|
198
|
-
|
|
199
|
-
.
|
|
200
|
-
.
|
|
234
|
+
html, body { height: 100%; }
|
|
235
|
+
body { font: 13px system-ui, sans-serif; margin: 0; padding: 14px 16px; background: #fff; color: #222; display:flex; flex-direction:column; box-sizing:border-box; gap: 8px; }
|
|
236
|
+
.icon { display: inline-block; width: 20px; text-align: center; margin-right: 4px; }
|
|
237
|
+
.title { font-size: 1.1em; font-weight: 600; }
|
|
238
|
+
.when { color: #555; font-size: 0.95em; }
|
|
201
239
|
.kind { color: #888; font-size: 0.85em; }
|
|
240
|
+
.spacer { flex: 1; }
|
|
241
|
+
.row { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
|
|
242
|
+
.row-label { color: #555; font-size: 0.85em; margin-right: 2px; }
|
|
243
|
+
button { font: 13px system-ui, sans-serif; cursor: pointer; }
|
|
244
|
+
.chip { padding: 3px 9px; border: 1px solid #ccc; border-radius: 12px; background: #f7f7f7; color: #222; }
|
|
245
|
+
.chip:hover { background: #e8f0fe; border-color: #0066cc; color: #0066cc; }
|
|
246
|
+
.custom { display: flex; align-items: center; gap: 4px; }
|
|
247
|
+
.custom input[type=number] { width: 48px; padding: 2px 4px; border: 1px solid #ccc; border-radius: 3px; font: inherit; }
|
|
248
|
+
.custom select { padding: 2px 4px; border: 1px solid #ccc; border-radius: 3px; font: inherit; background: #fff; }
|
|
249
|
+
.custom button.ok { padding: 2px 8px; border: 1px solid #0066cc; border-radius: 3px; background: #0066cc; color: #fff; }
|
|
250
|
+
.custom button.ok:hover { background: #0052a3; }
|
|
251
|
+
.actions { display: flex; gap: 8px; justify-content: flex-end; margin-top: 4px; }
|
|
252
|
+
.actions button.action { padding: 5px 14px; border: none; border-radius: 4px; background: #0066cc; color: #fff; min-width: 70px; }
|
|
253
|
+
.actions button.action:hover { background: #0052a3; }
|
|
254
|
+
.actions button.action[data-btn="Delete"] { background: #b00; }
|
|
255
|
+
.actions button.action[data-btn="Delete"]:hover { background: #800; }
|
|
202
256
|
</style></head><body>
|
|
203
|
-
<div class="title"><span class="icon">${
|
|
257
|
+
<div class="title"><span class="icon">${icon}</span>${escapeHtml(item.title)}</div>
|
|
204
258
|
<div class="when">${escapeHtml(formatWhen(item.whenMs))}</div>
|
|
205
|
-
<div class="kind">${
|
|
259
|
+
<div class="kind">${kindLabel}</div>
|
|
260
|
+
<div class="row">
|
|
261
|
+
<span class="row-label">Snooze:</span>
|
|
262
|
+
${presetChips}
|
|
263
|
+
</div>
|
|
264
|
+
<div class="row custom">
|
|
265
|
+
<span class="row-label">Custom:</span>
|
|
266
|
+
<input type="number" id="customN" value="5" min="1" max="999">
|
|
267
|
+
<select id="customUnit">
|
|
268
|
+
<option value="1">minutes</option>
|
|
269
|
+
<option value="60">hours</option>
|
|
270
|
+
<option value="1440">days</option>
|
|
271
|
+
</select>
|
|
272
|
+
<button type="button" class="ok" id="customGo">Snooze</button>
|
|
273
|
+
</div>
|
|
274
|
+
<div class="spacer"></div>
|
|
275
|
+
<div class="actions">${actionHtml}</div>
|
|
276
|
+
<script>
|
|
277
|
+
function send(payload) {
|
|
278
|
+
try { window.ipc.postMessage(JSON.stringify(payload)); }
|
|
279
|
+
catch (e) { try { window.close(); } catch (_) {} }
|
|
280
|
+
}
|
|
281
|
+
// Preset chips → snooze N minutes
|
|
282
|
+
document.querySelectorAll("button[data-snooze-min]").forEach(function(b) {
|
|
283
|
+
b.addEventListener("click", function() {
|
|
284
|
+
var m = parseInt(b.getAttribute("data-snooze-min"), 10) || 15;
|
|
285
|
+
send({ button: "snooze", form: { minutes: m } });
|
|
286
|
+
});
|
|
287
|
+
});
|
|
288
|
+
// Custom snooze form → snooze N * unit-multiplier minutes
|
|
289
|
+
var customGo = document.getElementById("customGo");
|
|
290
|
+
var customN = document.getElementById("customN");
|
|
291
|
+
var customUnit = document.getElementById("customUnit");
|
|
292
|
+
function submitCustom() {
|
|
293
|
+
var n = parseInt(customN.value, 10);
|
|
294
|
+
if (!isFinite(n) || n < 1) n = 5;
|
|
295
|
+
var mult = parseInt(customUnit.value, 10) || 1;
|
|
296
|
+
send({ button: "snooze", form: { minutes: n * mult } });
|
|
297
|
+
}
|
|
298
|
+
customGo.addEventListener("click", submitCustom);
|
|
299
|
+
customN.addEventListener("keydown", function(e) { if (e.key === "Enter") submitCustom(); });
|
|
300
|
+
// Action buttons (Dismiss/Open/Delete) → discriminate by label.
|
|
301
|
+
document.querySelectorAll("button[data-btn]").forEach(function(b) {
|
|
302
|
+
b.addEventListener("click", function() {
|
|
303
|
+
send({ button: b.getAttribute("data-btn") });
|
|
304
|
+
});
|
|
305
|
+
});
|
|
306
|
+
</script>
|
|
206
307
|
</body></html>`;
|
|
207
308
|
|
|
208
|
-
// Button labels. Open opens the htmlLink (Google Calendar editor)
|
|
209
|
-
// and clears all local alarm state so the next poll tick treats the
|
|
210
|
-
// event as a fresh entry — if the user moves the start time during
|
|
211
|
-
// the edit, the new alarm fires off the new time, not the old one.
|
|
212
|
-
// Tasks have no htmlLink so Open is skipped for them.
|
|
213
|
-
const buttons: string[] = ["Snooze 15m", "Snooze 1h", "Dismiss"];
|
|
214
|
-
if (item.htmlLink) buttons.push("Open");
|
|
215
|
-
|
|
216
309
|
const title = item.kind === "calendar" ? "Calendar reminder" : "Task reminder";
|
|
217
310
|
const hasHost = !!(window as any).mailxapi?.showReminderPopup;
|
|
218
|
-
|
|
311
|
+
// Result now carries an optional `form` object — see msger's
|
|
312
|
+
// MessageBoxResult.form (serde_json::Value passthrough). Snooze
|
|
313
|
+
// chips/inputs send `{ button: "snooze", form: { minutes: N } }`.
|
|
314
|
+
let r: { button: string; form?: { minutes?: number } };
|
|
219
315
|
try {
|
|
220
316
|
if (hasHost) {
|
|
221
317
|
r = await showReminderPopup({
|
|
222
318
|
title, html, buttons,
|
|
223
|
-
|
|
319
|
+
// Sized for the new snooze form (chips row + custom input
|
|
320
|
+
// row + action buttons) plus title/when/kind. Width fits
|
|
321
|
+
// "5m 15m 30m 1h 2h 1d" on one line in Segoe UI.
|
|
322
|
+
size: { width: 560, height: 300 },
|
|
224
323
|
});
|
|
225
324
|
} else {
|
|
226
325
|
r = await showInWebViewPopup({ title, html, buttons });
|
|
@@ -256,11 +355,33 @@ async function firePopupForItem(item: AlarmItem): Promise<void> {
|
|
|
256
355
|
firedThisSession.delete(item.uuid);
|
|
257
356
|
snoozeItem(item, 2);
|
|
258
357
|
break;
|
|
358
|
+
case "snooze": {
|
|
359
|
+
// Generic snooze, duration in `form.minutes`. Falls back to
|
|
360
|
+
// 15 min if the form is malformed or missing the value (the
|
|
361
|
+
// chip / custom-form JS always populates it, so this is just
|
|
362
|
+
// defense-in-depth).
|
|
363
|
+
const m = Math.max(1, Math.floor(r.form?.minutes ?? 15));
|
|
364
|
+
snoozeItem(item, m);
|
|
365
|
+
break;
|
|
366
|
+
}
|
|
367
|
+
// Legacy literal labels — retained so a pre-upgrade popup whose
|
|
368
|
+
// bundle still says "Snooze 15m" / "Snooze 1h" continues to work
|
|
369
|
+
// through a daemon-side rebuild without a UI restart.
|
|
259
370
|
case "Snooze 15m": snoozeItem(item, 15); break;
|
|
260
371
|
case "Snooze 1h": snoozeItem(item, 60); break;
|
|
261
372
|
case "Dismiss":
|
|
262
373
|
{ const m = loadDismissed(); m[item.uuid] = true; saveDismissed(m); }
|
|
263
374
|
break;
|
|
375
|
+
case "Delete":
|
|
376
|
+
// Remove the event server-side. Local row gets the pending-delete
|
|
377
|
+
// mark inside the service; reconcile picks it up. Also dismiss
|
|
378
|
+
// the alarm so it can't re-fire on a stale local row before the
|
|
379
|
+
// delete propagates.
|
|
380
|
+
{ const m = loadDismissed(); m[item.uuid] = true; saveDismissed(m); }
|
|
381
|
+
firedThisSession.delete(item.uuid);
|
|
382
|
+
deleteCalendarEvent(item.uuid).catch((e: any) =>
|
|
383
|
+
console.error(` [alarm] delete failed for ${item.uuid}: ${e?.message || e}`));
|
|
384
|
+
break;
|
|
264
385
|
default:
|
|
265
386
|
// User closed the window via X / Esc / "closed" / "dismissed"
|
|
266
387
|
// without picking a labeled button. Treat as a 15-minute
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* All storage goes through the service-side two-way cache (calendar_events
|
|
14
14
|
* and tasks tables); this file does not use localStorage for data.
|
|
15
15
|
*/
|
|
16
|
-
import { getCalendarEvents, getTasks, createTask, updateTask, deleteTask, reauthGoogleScopes, } from "../lib/api-client.js";
|
|
16
|
+
import { getCalendarEvents, getTasks, createTask, updateTask, deleteTask, reauthGoogleScopes, getSettings, saveSettings, } from "../lib/api-client.js";
|
|
17
17
|
import { showContextMenu } from "./context-menu.js";
|
|
18
18
|
const SIDEBAR_PREF = "mailx-calendar-sidebar-on";
|
|
19
19
|
const SHOW_RECURRING_PREF = "mailx-cal-show-recurring";
|
|
@@ -90,6 +90,7 @@ async function fetchUpcoming(from) {
|
|
|
90
90
|
source: r.providerId ? "google" : "local",
|
|
91
91
|
recurringEventId: r.recurringEventId,
|
|
92
92
|
htmlLink: r.htmlLink,
|
|
93
|
+
isHoliday: !!r.isHoliday,
|
|
93
94
|
}));
|
|
94
95
|
}
|
|
95
96
|
function formatDayHeader(d, today, tomorrow) {
|
|
@@ -191,8 +192,14 @@ function renderEvents(events) {
|
|
|
191
192
|
}
|
|
192
193
|
const recurMark = e.recurringEventId ? `<span class="cal-side-event-recur" title="Recurring event">↻</span>` : "";
|
|
193
194
|
const link = e.htmlLink || "";
|
|
194
|
-
|
|
195
|
-
|
|
195
|
+
const holidayAttr = e.isHoliday ? ' data-holiday="1"' : "";
|
|
196
|
+
// Holidays don't get the Google Calendar deep-link (it's read-only) —
|
|
197
|
+
// suppress data-link and the "Click to open" hint for those rows.
|
|
198
|
+
const clickable = !e.isHoliday;
|
|
199
|
+
const titleAttr = clickable && link ? 'title="Click to open in Google Calendar"' : "";
|
|
200
|
+
const dataLink = clickable ? `data-link="${escapeHtml(link)}"` : "";
|
|
201
|
+
html += `<div class="cal-side-event" data-id="${e.id}"${holidayAttr} ${dataLink} ${titleAttr}>
|
|
202
|
+
<span class="cal-side-event-dot ${e.isHoliday ? "h" : (e.source === "google" ? "g" : "l")}"></span>
|
|
196
203
|
<span class="cal-side-event-time">${escapeHtml(formatTime(e))}</span>
|
|
197
204
|
<span class="cal-side-event-title">${escapeHtml(e.title)}${recurMark}</span>
|
|
198
205
|
</div>`;
|
|
@@ -624,6 +631,35 @@ export function initCalendarSidebar() {
|
|
|
624
631
|
refresh();
|
|
625
632
|
});
|
|
626
633
|
}
|
|
634
|
+
// Holiday-calendar toggles. Each lives in service settings (not
|
|
635
|
+
// localStorage) because the daemon's refresh loop decides which
|
|
636
|
+
// calendars to pull — the preference has to round-trip to it.
|
|
637
|
+
// Two separate Google public calendars today: US federal holidays
|
|
638
|
+
// and Jewish holidays. Generalization to arbitrary user-supplied
|
|
639
|
+
// calendars is filed as Q140 (low priority unless the audience
|
|
640
|
+
// broadens beyond Bob).
|
|
641
|
+
const wireHolidayCheckbox = (cbId, settingsKey) => {
|
|
642
|
+
const cb = document.getElementById(cbId);
|
|
643
|
+
if (!cb || cb.__wired)
|
|
644
|
+
return;
|
|
645
|
+
cb.__wired = true;
|
|
646
|
+
getSettings().then((s) => {
|
|
647
|
+
cb.checked = !!s?.calendar?.[settingsKey];
|
|
648
|
+
}).catch(() => { });
|
|
649
|
+
cb.addEventListener("change", async () => {
|
|
650
|
+
try {
|
|
651
|
+
const s = await getSettings();
|
|
652
|
+
s.calendar = { ...(s.calendar || {}), [settingsKey]: cb.checked };
|
|
653
|
+
await saveSettings(s);
|
|
654
|
+
}
|
|
655
|
+
catch (e) {
|
|
656
|
+
console.error(`[cal] ${settingsKey} save failed:`, e);
|
|
657
|
+
}
|
|
658
|
+
refresh();
|
|
659
|
+
});
|
|
660
|
+
};
|
|
661
|
+
wireHolidayCheckbox("cal-side-show-holidays", "showHolidays");
|
|
662
|
+
wireHolidayCheckbox("cal-side-show-jewish-holidays", "showJewishHolidays");
|
|
627
663
|
// Horizon input — how many days ahead to list events. Bounded 1..365.
|
|
628
664
|
const horizonInput = document.getElementById("cal-side-horizon");
|
|
629
665
|
if (horizonInput && !horizonInput.__wired) {
|