@bobfrankston/rmfmail 1.0.686 → 1.0.690

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.
Files changed (46) hide show
  1. package/client/app.bundle.js +57 -19
  2. package/client/app.bundle.js.map +2 -2
  3. package/client/app.js +36 -2
  4. package/client/app.js.map +1 -1
  5. package/client/app.ts +36 -2
  6. package/client/components/alarms.js +24 -12
  7. package/client/components/alarms.js.map +1 -1
  8. package/client/components/alarms.ts +23 -11
  9. package/client/components/message-list.js +9 -4
  10. package/client/components/message-list.js.map +1 -1
  11. package/client/components/message-list.ts +9 -4
  12. package/client/components/message-viewer.js +33 -3
  13. package/client/components/message-viewer.js.map +1 -1
  14. package/client/components/message-viewer.ts +33 -3
  15. package/client/compose/compose.bundle.js +7 -0
  16. package/client/compose/compose.bundle.js.map +2 -2
  17. package/client/compose/spellcheck.js +19 -0
  18. package/client/compose/spellcheck.js.map +1 -1
  19. package/client/compose/spellcheck.ts +17 -0
  20. package/package.json +3 -3
  21. package/packages/mailx-imap/index.d.ts.map +1 -1
  22. package/packages/mailx-imap/index.js +66 -9
  23. package/packages/mailx-imap/index.js.map +1 -1
  24. package/packages/mailx-imap/index.ts +63 -9
  25. package/packages/mailx-imap/package-lock.json +2 -2
  26. package/packages/mailx-imap/package.json +1 -1
  27. package/packages/mailx-service/google-sync.d.ts +46 -1
  28. package/packages/mailx-service/google-sync.d.ts.map +1 -1
  29. package/packages/mailx-service/google-sync.js +50 -1
  30. package/packages/mailx-service/google-sync.js.map +1 -1
  31. package/packages/mailx-service/google-sync.ts +91 -1
  32. package/packages/mailx-service/index.d.ts.map +1 -1
  33. package/packages/mailx-service/index.js +79 -6
  34. package/packages/mailx-service/index.js.map +1 -1
  35. package/packages/mailx-service/index.ts +76 -6
  36. package/packages/mailx-service/local-store.d.ts.map +1 -1
  37. package/packages/mailx-service/local-store.js +11 -0
  38. package/packages/mailx-service/local-store.js.map +1 -1
  39. package/packages/mailx-service/local-store.ts +9 -0
  40. package/packages/mailx-store/db.d.ts +7 -0
  41. package/packages/mailx-store/db.d.ts.map +1 -1
  42. package/packages/mailx-store/db.js +46 -5
  43. package/packages/mailx-store/db.js.map +1 -1
  44. package/packages/mailx-store/db.ts +48 -5
  45. package/packages/mailx-store/package.json +1 -1
  46. /package/packages/mailx-imap/{node_modules.npmglobalize-stash-11884 → node_modules.npmglobalize-stash-51400}/.package-lock.json +0 -0
@@ -1264,8 +1264,54 @@ export class MailxService {
1264
1264
  * Tight loop = 429 quota burn. */
1265
1265
  async refreshCalendarEvents(accountId, fromMs, toMs) {
1266
1266
  const tp = await this.primaryTokenProvider("calendar");
1267
- const events = await gsync.listCalendarEvents(tp, fromMs, toMs);
1268
- console.log(` [calendar] pulled ${events.length} events from ${new Date(fromMs).toISOString().slice(0, 10)} to ${new Date(toMs).toISOString().slice(0, 10)}`);
1267
+ // Enumerate ALL of the user's `selected` calendars (the ones shown
1268
+ // in Google's web UI) and pull events from each. Earlier code
1269
+ // hard-coded `primary` only — so any event living on a secondary
1270
+ // calendar (a personal "Statin" reminder, a shared work cal, a
1271
+ // sports schedule) was invisible to mailx. Bob 2026-05-12:
1272
+ // "you're still not showing me and alerting me about recurring
1273
+ // events." Thunderbird and Google's own UI walk the entire
1274
+ // calendarList; mailx now does too. Failing to list calendars
1275
+ // falls back to primary so single-calendar users still work.
1276
+ let calendarsToFetch = [{ id: "primary", label: "primary", defaultReminderMinutes: [] }];
1277
+ try {
1278
+ const all = await gsync.listCalendars(tp);
1279
+ const selected = all.filter(c => c.selected);
1280
+ if (selected.length > 0) {
1281
+ calendarsToFetch = selected.map(c => ({
1282
+ id: c.id, label: c.summary || c.id,
1283
+ defaultReminderMinutes: c.defaultReminderMinutes,
1284
+ }));
1285
+ console.log(` [calendar] enumerated ${all.length} calendars, ${selected.length} selected`);
1286
+ }
1287
+ else {
1288
+ console.log(` [calendar] no selected calendars — falling back to primary`);
1289
+ }
1290
+ }
1291
+ catch (e) {
1292
+ console.warn(` [calendar] listCalendars failed (${e?.message || e}) — falling back to primary`);
1293
+ }
1294
+ const fetchResults = await Promise.all(calendarsToFetch.map(async (c) => {
1295
+ try {
1296
+ const ev = await gsync.listCalendarEvents(tp, fromMs, toMs, c.id);
1297
+ console.log(` [calendar] pulled ${ev.length} events from "${c.label}" (${new Date(fromMs).toISOString().slice(0, 10)} to ${new Date(toMs).toISOString().slice(0, 10)})`);
1298
+ return { events: ev, calendarId: c.id, defaultReminderMinutes: c.defaultReminderMinutes };
1299
+ }
1300
+ catch (e) {
1301
+ console.warn(` [calendar] fetch from "${c.label}" failed: ${e?.message || e}`);
1302
+ return { events: [], calendarId: c.id, defaultReminderMinutes: c.defaultReminderMinutes };
1303
+ }
1304
+ }));
1305
+ // Flatten with each event remembering its source calendar's default
1306
+ // reminder list, so calendarEventToLocal can apply the right
1307
+ // defaults when `reminders.useDefault === true`.
1308
+ const eventsWithDefaults = [];
1309
+ for (const fr of fetchResults) {
1310
+ for (const ev of fr.events) {
1311
+ eventsWithDefaults.push({ ev, defaultReminderMinutes: fr.defaultReminderMinutes });
1312
+ }
1313
+ }
1314
+ const events = eventsWithDefaults.map(x => x.ev);
1269
1315
  // Holiday calendars (Q131 + Bob 2026-05-11 second-toggle request).
1270
1316
  // Each enabled toggle pulls a separate Google public calendar; rows
1271
1317
  // are tagged with the source `calendar_id` so toggling one off only
@@ -1327,8 +1373,8 @@ export class MailxService {
1327
1373
  // so an event whose start moves outside the prior query range doesn't
1328
1374
  // get a second row on the next pull.
1329
1375
  const seenProviderIds = new Set();
1330
- for (const ev of events) {
1331
- const local = gsync.calendarEventToLocal(ev, accountId);
1376
+ for (const { ev, defaultReminderMinutes } of eventsWithDefaults) {
1377
+ const local = gsync.calendarEventToLocal(ev, accountId, defaultReminderMinutes);
1332
1378
  seenProviderIds.add(ev.id);
1333
1379
  const existing = this.db.getCalendarEventByProviderId(accountId, ev.id);
1334
1380
  if (existing && calendarRowEquals(existing, local) && !existing.isHoliday)
@@ -1461,8 +1507,35 @@ export class MailxService {
1461
1507
  }
1462
1508
  async refreshTasks(accountId, includeCompleted) {
1463
1509
  const tp = await this.primaryTokenProvider("tasks");
1464
- const tasks = await gsync.listTasks(tp, "@default", includeCompleted);
1465
- console.log(` [tasks] pulled ${tasks.length} tasks`);
1510
+ // Enumerate every task list (Google Reminders since late 2023 live
1511
+ // here, and users can have many lists — "My Tasks", "Reminders",
1512
+ // custom ones). Earlier code only queried `@default`, so reminders
1513
+ // filed elsewhere were invisible. Bob 2026-05-12. Falling back to
1514
+ // a single `@default` query keeps single-list users working when
1515
+ // the listTaskLists call fails.
1516
+ let lists = [{ id: "@default", title: "@default" }];
1517
+ try {
1518
+ const all = await gsync.listTaskLists(tp);
1519
+ if (all.length > 0) {
1520
+ lists = all;
1521
+ console.log(` [tasks] enumerated ${all.length} task list(s)`);
1522
+ }
1523
+ }
1524
+ catch (e) {
1525
+ console.warn(` [tasks] listTaskLists failed (${e?.message || e}) — falling back to @default`);
1526
+ }
1527
+ const fetchResults = await Promise.all(lists.map(async (l) => {
1528
+ try {
1529
+ const t = await gsync.listTasks(tp, l.id, includeCompleted);
1530
+ console.log(` [tasks] pulled ${t.length} tasks from "${l.title}"`);
1531
+ return t;
1532
+ }
1533
+ catch (e) {
1534
+ console.warn(` [tasks] fetch from "${l.title}" failed: ${e?.message || e}`);
1535
+ return [];
1536
+ }
1537
+ }));
1538
+ const tasks = [].concat(...fetchResults);
1466
1539
  const existing = this.db.getTasks(accountId, true);
1467
1540
  let changed = false;
1468
1541
  const seen = new Set();