@bobfrankston/rmfmail 1.1.174 → 1.1.180

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.
@@ -62,6 +62,7 @@ __export(api_client_exports, {
62
62
  getVersion: () => getVersion,
63
63
  hasBccHistoryTo: () => hasBccHistoryTo,
64
64
  hasCcHistoryTo: () => hasCcHistoryTo,
65
+ installConsoleCapture: () => installConsoleCapture,
65
66
  listContacts: () => listContacts,
66
67
  listQueuedOutgoing: () => listQueuedOutgoing,
67
68
  logClientEvent: () => logClientEvent,
@@ -367,6 +368,90 @@ function moveFolderToTrash(accountId, folderId) {
367
368
  function emptyFolder(accountId, folderId) {
368
369
  return ipc().emptyFolder?.(accountId, folderId);
369
370
  }
371
+ function installConsoleCapture() {
372
+ const g = globalThis;
373
+ if (g.__mailxConsoleCaptureInstalled)
374
+ return;
375
+ g.__mailxConsoleCaptureInstalled = true;
376
+ const orig = {
377
+ log: console.log.bind(console),
378
+ info: console.info.bind(console),
379
+ warn: console.warn.bind(console),
380
+ error: console.error.bind(console),
381
+ debug: console.debug.bind(console)
382
+ };
383
+ g._origConsole = orig;
384
+ const serialize = (v) => {
385
+ if (v == null)
386
+ return v;
387
+ const t = typeof v;
388
+ if (t === "string" || t === "number" || t === "boolean")
389
+ return v;
390
+ if (v instanceof Error)
391
+ return { __err: true, message: v.message, stack: v.stack };
392
+ try {
393
+ const s = JSON.stringify(v);
394
+ return s.length > 4096 ? s.slice(0, 4096) + "\u2026[truncated]" : JSON.parse(s);
395
+ } catch {
396
+ try {
397
+ return String(v);
398
+ } catch {
399
+ return "[unserializable]";
400
+ }
401
+ }
402
+ };
403
+ const forward = (level, args) => {
404
+ try {
405
+ logClientEvent(`console.${level}`, { args: args.map(serialize) });
406
+ } catch {
407
+ }
408
+ };
409
+ console.log = (...args) => {
410
+ forward("log", args);
411
+ orig.log(...args);
412
+ };
413
+ console.info = (...args) => {
414
+ forward("info", args);
415
+ orig.info(...args);
416
+ };
417
+ console.warn = (...args) => {
418
+ forward("warn", args);
419
+ orig.warn(...args);
420
+ };
421
+ console.error = (...args) => {
422
+ forward("error", args);
423
+ orig.error(...args);
424
+ };
425
+ console.debug = (...args) => {
426
+ forward("debug", args);
427
+ orig.debug(...args);
428
+ };
429
+ try {
430
+ window.addEventListener("error", (e) => {
431
+ try {
432
+ logClientEvent("window.error", {
433
+ message: e.message,
434
+ filename: e.filename,
435
+ lineno: e.lineno,
436
+ colno: e.colno,
437
+ stack: e.error?.stack || null
438
+ });
439
+ } catch {
440
+ }
441
+ });
442
+ window.addEventListener("unhandledrejection", (e) => {
443
+ try {
444
+ const r = e.reason;
445
+ logClientEvent("window.unhandledrejection", {
446
+ message: r?.message || String(r),
447
+ stack: r?.stack || null
448
+ });
449
+ } catch {
450
+ }
451
+ });
452
+ } catch {
453
+ }
454
+ }
370
455
  function logClientEvent(tag, data) {
371
456
  let delivered = false;
372
457
  try {
@@ -2991,6 +3076,7 @@ async function loadUnifiedInbox(autoSelect = true) {
2991
3076
  if (myGen !== loadGen)
2992
3077
  return;
2993
3078
  totalMessages = result.total;
3079
+ logClientEvent("loadUnifiedInbox", { items: result.items?.length ?? 0, total: result.total, hadCache: !!cached, cacheItems: cached?.items?.length ?? 0 });
2994
3080
  listCache.set(CACHE_KEY_UNIFIED, { items: result.items, total: result.total, timestamp: Date.now() });
2995
3081
  if (cached && listResultsEqual(cached.items, result.items))
2996
3082
  return;
@@ -3202,6 +3288,15 @@ function renderMessages(body, accountId, items) {
3202
3288
  while (tempDiv.firstChild)
3203
3289
  fragment.appendChild(tempDiv.firstChild);
3204
3290
  body.replaceChildren(fragment);
3291
+ if (focusedRow) {
3292
+ const fAcct = focusedRow.accountId;
3293
+ const fUid = focusedRow.msg?.uid;
3294
+ const stillThere = items.some((m) => (m.accountId || accountId) === fAcct && m.uid === fUid);
3295
+ if (!stillThere) {
3296
+ clearViewer();
3297
+ focusedRow = null;
3298
+ }
3299
+ }
3205
3300
  }
3206
3301
  function selectFirst(body) {
3207
3302
  if (window.innerWidth <= 768)
@@ -6718,6 +6813,7 @@ init_mailx_types();
6718
6813
  init_message_viewer();
6719
6814
  init_api_client();
6720
6815
  init_message_state();
6816
+ installConsoleCapture();
6721
6817
  var APP_NAME = "rmfmail";
6722
6818
  function propagateAppName() {
6723
6819
  const set = (id, fn) => {
@@ -9077,6 +9173,33 @@ document.getElementById("message-viewer")?.addEventListener("dblclick", (e) => {
9077
9173
  if (target?.closest("a, button, input, select, textarea, [contenteditable]")) return;
9078
9174
  toggleFullscreenPreview();
9079
9175
  });
9176
+ function focusPaneById(id) {
9177
+ const el = document.getElementById(id);
9178
+ if (!el) return;
9179
+ if (!el.hasAttribute("tabindex")) el.setAttribute("tabindex", "-1");
9180
+ el.focus();
9181
+ el.style.outline = "2px solid var(--color-accent, #3b82f6)";
9182
+ el.style.outlineOffset = "-2px";
9183
+ setTimeout(() => {
9184
+ el.style.outline = "";
9185
+ el.style.outlineOffset = "";
9186
+ }, 600);
9187
+ }
9188
+ document.addEventListener("auxclick", (e) => {
9189
+ if (e.button !== 1) return;
9190
+ const target = e.target;
9191
+ if (!target) return;
9192
+ const ft = target.closest("#folder-tree");
9193
+ const ml = target.closest("#ml-body");
9194
+ const mv = target.closest("#message-viewer");
9195
+ let id = null;
9196
+ if (ft) id = "folder-tree";
9197
+ else if (ml) id = "ml-body";
9198
+ else if (mv) id = "message-viewer";
9199
+ if (!id) return;
9200
+ e.preventDefault();
9201
+ focusPaneById(id);
9202
+ });
9080
9203
  function cyclePaneFocus(reverse) {
9081
9204
  const panes = [
9082
9205
  { id: "folder-tree", el: document.getElementById("folder-tree") },