@bobfrankston/rmfmail 1.2.303 → 1.2.305

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.
@@ -34,6 +34,11 @@
34
34
  }
35
35
 
36
36
  .ctx-item:hover { background: var(--color-bg-hover); }
37
+ /* The menu's default action, set by MenuItem.emphasized — "Move here" in the
38
+ right-drag menu, the named action in confirmAt. The flag has been passed
39
+ since the right-drag menu was written and had no rule to render it, so
40
+ nothing ever looked different (2026-09-04). */
41
+ .ctx-emphasized { font-weight: 600; }
37
42
  .ctx-disabled { opacity: 0.4; cursor: default; }
38
43
  .ctx-disabled:hover { background: transparent; }
39
44
  .ctx-sep { height: 1px; background: var(--color-border); margin: var(--gap-xs) 0; }
package/npmchanges.md CHANGED
@@ -1470,3 +1470,105 @@ Untested from here: the 3.3 MB hand-off itself. The bytes are correct and the
1470
1470
  call is wired; whether a payload that size survives one EvaluateJavaScriptAsync
1471
1471
  can only be answered on the device. If it does not, the new log line names it.
1472
1472
 
1473
+ ## v1.2.303 — 2026-09-04
1474
+
1475
+ The phone's star filter was never asked for, and the chip announcing it landed in a 28px column
1476
+
1477
+ "it then says no flagged messages. but there are message flagged" (Bob
1478
+ 2026-09-04, on Android, with the screenshot). There are 260 — 257 in bobma's
1479
+ INBOX alone, and the desktop's own SQL finds every one of them.
1480
+
1481
+ `WebMailxService.getUnifiedInbox` took two parameters. api-client has always
1482
+ called it with four: `(page, pageSize, flaggedOnly, dateBasis)`. `getMessages`
1483
+ took seven and is called with nine, `flaggedOnly` at position 8. The extras
1484
+ fell off the end and JavaScript said nothing — and neither did TypeScript,
1485
+ because an implementation with FEWER parameters satisfies an interface
1486
+ declaring more. Both dropped arguments are on `MessageQuery`, documented, and
1487
+ honoured by the desktop store.
1488
+
1489
+ What was left on the phone was the client's `.flagged-only` CSS rule, which
1490
+ hides unflagged rows in the loaded page. That is precisely the arrangement the
1491
+ desktop comment has warned about since 2026-06-05: a paginated list whose
1492
+ newest 50 messages happen to carry no star shows nothing at all, and every
1493
+ starred message deeper in the mailbox is unreachable. The overlay then counted
1494
+ the rows it was hiding and reported the truth from where it stood — "A 'flagged
1495
+ only' filter is hiding 50 messages" — while the filter that could have found
1496
+ the other 260 had never run.
1497
+
1498
+ Both parameters are now threaded through, and the `\Flagged` predicate lives in
1499
+ one named constant matching desktop's character for character: two backslashes
1500
+ in the SQL literal, because `flags_json` is JSON and the flag is stored
1501
+ escaped. `dateBasis` was dropped by the same omission on the same line, so the
1502
+ phone has been ordering by arrival time while the desktop ordered by the Date:
1503
+ header; it now honours what it is handed. That is a visible change to list
1504
+ order on the phone, and it is the order the client has been asking for all
1505
+ along — say so if you want it left as it was.
1506
+
1507
+ Three tests assert the threading, which is where the bug was. They use a spy
1508
+ db, since the failure was an argument that never arrived, not SQL that got it
1509
+ wrong.
1510
+
1511
+ **The chip, separately.** `#ml-filter-chip` said `display: block; width: 100%`
1512
+ and never said `grid-column: 1 / -1`. `.message-list` is a five-column grid,
1513
+ every other full-width child declares the span, and this one auto-placed into
1514
+ column 1 — the 28px avatar track — so "Showing flagged (★) messages only —
1515
+ click to show everything" came out one word per line down the left edge of the
1516
+ header. `width: 100%` cannot help there; inside a grid it means 100% of a 28px
1517
+ track.
1518
+
1519
+ Not changed: the ★ button sits in the search row, next to Server and
1520
+ Trash/Spam, which is why reaching for search found a list filter. That is a
1521
+ placement judgement, not a bug, so it is yours to call.
1522
+
1523
+ ## v1.2.304 — 2026-09-04
1524
+
1525
+ Ask at the pointer, not in the host's dialog
1526
+
1527
+ "clicking the x is supposed [to] delete the task but seems to do nothing …
1528
+ it eventually puts up a message far from where I clicked" (Bob 2026-09-04,
1529
+ with both screenshots).
1530
+
1531
+ The × handler called the native `confirm()`. In the WebView that is the host's
1532
+ own dialog: titled "msger.localhost says", centred in the window rather than
1533
+ under the pointer, arriving late enough that the click reads as having done
1534
+ nothing — and blocking the WebView event loop the whole time it is up, which is
1535
+ the hazard message-viewer.ts already refuses `alert()` for. Compose reached the
1536
+ same conclusion in its own window and wrote an in-page modal; the main window
1537
+ never got one, so thirteen `confirm()` calls still go to the host.
1538
+
1539
+ `confirmAt(x, y, label)` in context-menu.ts asks the question as a two-item
1540
+ menu at the pointer. Built on showContextMenu rather than as a new modal, so
1541
+ there is one menu, one dismissal path, and one piece of stay-on-screen clamping
1542
+ — that clamping in particular was already solved here for narrow Android
1543
+ screens, and a second implementation would have had to learn it again.
1544
+
1545
+ The label NAMES its target — `Delete "Records. Berkowitz"`, never "OK". By the
1546
+ time a confirmation is read the pointer has moved and the row it came from is
1547
+ no longer obvious; a named action can be checked, and "OK" cannot. The
1548
+ explanation the old dialog text carried ("removes it from Google Tasks — to
1549
+ mark done use the checkbox") is now the item's tooltip: worth having, not worth
1550
+ a dialog.
1551
+
1552
+ Three call sites move: the row ×, the row context menu's Delete, and the batch
1553
+ delete behind the Delete key / trash button. The batch one has no click to
1554
+ anchor to, so it asks over the first selected row — where the tasks are and
1555
+ where the user is looking.
1556
+
1557
+ Two supporting changes:
1558
+
1559
+ `ContextMenuOptions.onClose` — fires whichever way the menu goes away, so a
1560
+ promise-shaped menu can answer "cancelled" instead of hanging forever on a
1561
+ dismissal. An item's click calls closeContextMenu() BEFORE item.action(), so
1562
+ onClose always runs first; confirmAt defers its cancel by one microtask, and
1563
+ since the action is synchronous and completes within the same task, a chosen
1564
+ item has always settled the promise by the time that microtask drains.
1565
+
1566
+ `.ctx-emphasized` now renders. `MenuItem.emphasized` has been passed since the
1567
+ right-drag menu was written ("Move here" as the default action) and no CSS rule
1568
+ ever matched it, so it has never once looked different from its neighbours.
1569
+
1570
+ The other ten `confirm()` calls — rebuild, factory reset, permanent delete,
1571
+ folder move/delete, contact delete, discard draft — are untouched. They are
1572
+ the same dialog with the same problems and they should follow, but each is a
1573
+ destructive action worth reading before it moves.
1574
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bobfrankston/rmfmail",
3
- "version": "1.2.303",
3
+ "version": "1.2.305",
4
4
  "description": "Local-first email client with IMAP sync and standalone native app",
5
5
  "type": "module",
6
6
  "main": "bin/mailx.js",
@@ -35,9 +35,9 @@
35
35
  "@bobfrankston/iflow-direct": "^0.1.68",
36
36
  "@bobfrankston/mailx-host": "^0.1.15",
37
37
  "@bobfrankston/mailx-imap": "^0.1.173",
38
- "@bobfrankston/mailx-store-web": "^0.1.105",
38
+ "@bobfrankston/mailx-store-web": "^0.1.106",
39
39
  "@bobfrankston/mailx-sync": "^0.1.29",
40
- "@bobfrankston/miscinfo": "^1.0.20",
40
+ "@bobfrankston/miscinfo": "^1.0.21",
41
41
  "@bobfrankston/msger": "^0.1.429",
42
42
  "@bobfrankston/node-tcp-transport": "^0.1.10",
43
43
  "@bobfrankston/oauthsupport": "^1.0.35",
@@ -117,9 +117,9 @@
117
117
  "@bobfrankston/iflow-direct": "^0.1.68",
118
118
  "@bobfrankston/mailx-host": "^0.1.15",
119
119
  "@bobfrankston/mailx-imap": "^0.1.173",
120
- "@bobfrankston/mailx-store-web": "^0.1.105",
120
+ "@bobfrankston/mailx-store-web": "^0.1.106",
121
121
  "@bobfrankston/mailx-sync": "^0.1.29",
122
- "@bobfrankston/miscinfo": "^1.0.20",
122
+ "@bobfrankston/miscinfo": "^1.0.21",
123
123
  "@bobfrankston/msger": "^0.1.429",
124
124
  "@bobfrankston/node-tcp-transport": "^0.1.10",
125
125
  "@bobfrankston/oauthsupport": "^1.0.35",