@bobfrankston/rmfmail 1.1.93 → 1.1.95

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.ts CHANGED
@@ -956,7 +956,10 @@ function showComposeOverlay(title = "Compose"): HTMLIFrameElement {
956
956
  // CSS `resize:both` only gives a single lower-right grip. To allow
957
957
  // dragging any edge or corner, we omit it here and attach eight
958
958
  // manual handles via addComposeResizeHandles() below.
959
- wrapper.style.cssText = "position:fixed;bottom:0;right:16px;width:min(900px,55vw);height:min(700px,70vh);z-index:1000;border-radius:8px 8px 0 0;box-shadow:0 -4px 24px rgba(0,0,0,0.3);display:flex;flex-direction:column;overflow:hidden;";
959
+ // Open horizontally centred, near the top not docked to the
960
+ // lower-right corner (Bob 2026-05-18). The title bar still drags it
961
+ // anywhere; this is just the initial placement.
962
+ wrapper.style.cssText = "position:fixed;top:48px;left:calc((100vw - min(900px,55vw)) / 2);width:min(900px,55vw);height:min(700px,70vh);z-index:1000;border-radius:8px;box-shadow:0 4px 24px rgba(0,0,0,0.3);display:flex;flex-direction:column;overflow:hidden;";
960
963
  }
961
964
 
962
965
  // Title bar — drag to move; right-side cluster holds discard, popout, close.
@@ -55,13 +55,14 @@ function render() {
55
55
  const plus = document.createElement("button");
56
56
  plus.className = "view-tab-new";
57
57
  plus.textContent = "+";
58
- plus.title = "New tab (All Inboxes)";
58
+ plus.title = "New tab (Ctrl+T)";
59
59
  plus.addEventListener("click", () => openTab({ kind: "unified" }, "All Inboxes", true));
60
60
  stripEl.appendChild(plus);
61
- // Strip is shown only with 2+ tabs (Thunderbird model) a lone tab is
62
- // just "the window" and a full-width strip for it is wasted space. With
63
- // one tab, open another via Ctrl+T (wired in app.ts).
64
- stripEl.hidden = tabs.length < 2;
61
+ // Strip stays visible even with a single tab so the "+" button is a
62
+ // discoverable affordance for opening another (Bob 2026-05-18: with the
63
+ // strip hidden there was no hint that Ctrl+T creates a tab). Hidden only
64
+ // before the first tab exists — nothing to show yet.
65
+ stripEl.hidden = tabs.length < 1;
65
66
  }
66
67
  /** Wire the strip. `apply` is the app.ts callback that loads a tab's view. */
67
68
  export function initTabs(strip, apply) {
@@ -1 +1 @@
1
- {"version":3,"file":"tabs.js","sourceRoot":"","sources":["tabs.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tabs.js","sourceRoot":"","sources":["tabs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAaH,MAAM,WAAW,GAAG,iBAAiB,CAAC;AACtC,IAAI,IAAI,GAAc,EAAE,CAAC;AACzB,IAAI,QAAQ,GAAG,EAAE,CAAC;AAClB,IAAI,OAAO,GAAuB,IAAI,CAAC;AACvC;8EAC8E;AAC9E,IAAI,SAAS,GAA2B,GAAG,EAAE,GAAS,CAAC,CAAC;AACxD,IAAI,OAAO,GAAG,CAAC,CAAC;AAChB,SAAS,KAAK,KAAa,OAAO,IAAI,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAEpD,SAAS,OAAO;IACZ,IAAI,CAAC;QACD,cAAc,CAAC,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;IAC5E,CAAC;IAAC,MAAM,CAAC,CAAC,iEAAiE,CAAC,CAAC;AACjF,CAAC;AAED,SAAS,MAAM;IACX,IAAI,CAAC,OAAO;QAAE,OAAO;IACrB,OAAO,CAAC,SAAS,GAAG,EAAE,CAAC;IACvB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACrB,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC3C,IAAI,CAAC,SAAS,GAAG,UAAU,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACrE,IAAI,CAAC,OAAO,CAAC,KAAK,GAAG,GAAG,CAAC,EAAE,CAAC;QAC5B,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAC7C,KAAK,CAAC,SAAS,GAAG,gBAAgB,CAAC;QACnC,KAAK,CAAC,WAAW,GAAG,GAAG,CAAC,KAAK,IAAI,QAAQ,CAAC;QAC1C,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QACxB,mEAAmE;QACnE,oDAAoD;QACpD,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClB,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;YAC/C,KAAK,CAAC,SAAS,GAAG,gBAAgB,CAAC;YACnC,KAAK,CAAC,WAAW,GAAG,GAAG,CAAC;YACxB,KAAK,CAAC,KAAK,GAAG,WAAW,CAAC;YAC1B,KAAK,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACnF,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;QACD,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QACvD,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IACD,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IAC9C,IAAI,CAAC,SAAS,GAAG,cAAc,CAAC;IAChC,IAAI,CAAC,WAAW,GAAG,GAAG,CAAC;IACvB,IAAI,CAAC,KAAK,GAAG,kBAAkB,CAAC;IAChC,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,aAAa,EAAE,IAAI,CAAC,CAAC,CAAC;IACxF,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IAC1B,oEAAoE;IACpE,wEAAwE;IACxE,yEAAyE;IACzE,qDAAqD;IACrD,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;AACrC,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,QAAQ,CAAC,KAAkB,EAAE,KAA6B;IACtE,OAAO,GAAG,KAAK,CAAC;IAChB,SAAS,GAAG,KAAK,CAAC;IAClB,IAAI,CAAC;QACD,MAAM,GAAG,GAAG,cAAc,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAChD,IAAI,GAAG,EAAE,CAAC;YACN,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA0C,CAAC;YACxE,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACpD,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;gBACnB,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBACzC,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;oBACnB,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;oBACjD,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,OAAO;wBAAE,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC;gBAC5D,CAAC;YACL,CAAC;QACL,CAAC;IACL,CAAC;IAAC,MAAM,CAAC,CAAC,2BAA2B,CAAC,CAAC;IACvC,MAAM,EAAE,CAAC;AACb,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,SAAS;IACrB,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAC,IAAI,IAAI,CAAC;AACrD,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,OAAO,CAAC,IAAa,EAAE,KAAa,EAAE,UAAU,GAAG,IAAI;IACnE,MAAM,GAAG,GAAY,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAClD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACf,IAAI,UAAU;QAAE,QAAQ,GAAG,GAAG,CAAC,EAAE,CAAC;IAClC,OAAO,EAAE,CAAC;IACV,MAAM,EAAE,CAAC;IACT,IAAI,UAAU;QAAE,SAAS,CAAC,GAAG,CAAC,CAAC;AACnC,CAAC;AAED,mDAAmD;AACnD,MAAM,UAAU,QAAQ,CAAC,EAAU;IAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;IACxC,IAAI,CAAC,GAAG,IAAI,EAAE,KAAK,QAAQ;QAAE,OAAO;IACpC,QAAQ,GAAG,EAAE,CAAC;IACd,OAAO,EAAE,CAAC;IACV,MAAM,EAAE,CAAC;IACT,SAAS,CAAC,GAAG,CAAC,CAAC;AACnB,CAAC;AAED;uDACuD;AACvD,MAAM,UAAU,QAAQ,CAAC,EAAU;IAC/B,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO;IAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7C,IAAI,GAAG,GAAG,CAAC;QAAE,OAAO;IACpB,MAAM,SAAS,GAAG,EAAE,KAAK,QAAQ,CAAC;IAClC,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IACpB,IAAI,SAAS,EAAE,CAAC;QACZ,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;QACxC,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC;QACnB,OAAO,EAAE,CAAC;QACV,MAAM,EAAE,CAAC;QACT,SAAS,CAAC,IAAI,CAAC,CAAC;IACpB,CAAC;SAAM,CAAC;QACJ,OAAO,EAAE,CAAC;QACV,MAAM,EAAE,CAAC;IACb,CAAC;AACL,CAAC;AAED;;;;;gEAKgE;AAChE,MAAM,UAAU,aAAa,CAAC,IAAa,EAAE,KAAa;IACtD,IAAI,GAAG,GAAG,SAAS,EAAE,CAAC;IACtB,IAAI,CAAC,GAAG,EAAE,CAAC;QACP,GAAG,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QACnC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACf,QAAQ,GAAG,GAAG,CAAC,EAAE,CAAC;IACtB,CAAC;SAAM,CAAC;QACJ,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;QAChB,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC;IACtB,CAAC;IACD,OAAO,EAAE,CAAC;IACV,MAAM,EAAE,CAAC;AACb,CAAC"}
@@ -67,13 +67,14 @@ function render(): void {
67
67
  const plus = document.createElement("button");
68
68
  plus.className = "view-tab-new";
69
69
  plus.textContent = "+";
70
- plus.title = "New tab (All Inboxes)";
70
+ plus.title = "New tab (Ctrl+T)";
71
71
  plus.addEventListener("click", () => openTab({ kind: "unified" }, "All Inboxes", true));
72
72
  stripEl.appendChild(plus);
73
- // Strip is shown only with 2+ tabs (Thunderbird model) a lone tab is
74
- // just "the window" and a full-width strip for it is wasted space. With
75
- // one tab, open another via Ctrl+T (wired in app.ts).
76
- stripEl.hidden = tabs.length < 2;
73
+ // Strip stays visible even with a single tab so the "+" button is a
74
+ // discoverable affordance for opening another (Bob 2026-05-18: with the
75
+ // strip hidden there was no hint that Ctrl+T creates a tab). Hidden only
76
+ // before the first tab exists — nothing to show yet.
77
+ stripEl.hidden = tabs.length < 1;
77
78
  }
78
79
 
79
80
  /** Wire the strip. `apply` is the app.ts callback that loads a tab's view. */
package/npmchanges.md CHANGED
@@ -240,3 +240,37 @@ falling back to (uid, folderId) only for uuid-less envelopes (thread
240
240
  popup). The local store/.eml files were never corrupt — this was purely
241
241
  a viewer identity-check bug.
242
242
 
243
+ ## v1.1.93 — 2026-05-18
244
+
245
+ Search: index full message bodies, not just the preview snippet
246
+
247
+ Body-text search only ever covered messages the user had opened. At sync
248
+ time the FTS body_text was seeded with the short `preview` snippet; the
249
+ full text was backfilled only when LocalStore.getMessage parsed a body
250
+ on view — and even that backfill keyed on the legacy messages.folder_id
251
+ column via a (account,folder,uid) lookup that could miss the row, so a
252
+ word buried in an opened message's body still wasn't found (Bob:
253
+ "mcdade" in a message body, search found nothing).
254
+
255
+ Two fixes:
256
+ - updateFtsBody(rowId, text) keys on the FTS rowid (= messages.id)
257
+ directly — no fragile folder lookup. store.ts passes envelope.id.
258
+ - The IMAP sync path now indexes the full body into FTS right after
259
+ upsertMessage. extractPreview already parsed `source`, so the body
260
+ text is free — every synced message is body-searchable without the
261
+ user opening it first.
262
+
263
+ Existing already-synced messages stay preview-only until re-synced
264
+ (mailx -repair re-indexes them).
265
+
266
+ ## v1.1.94 — 2026-05-19
267
+
268
+ Tabs: keep the strip visible with one tab so "+" is discoverable
269
+
270
+ The view-tab strip was hidden until a 2nd tab existed — but with it
271
+ hidden there was no hint that tabs exist or that Ctrl+T creates one
272
+ (Bob: "there needs to be some indicator that ^t creates a tab"). The
273
+ strip now stays visible with a single tab, showing that tab plus the
274
+ "+" button; its tooltip names the Ctrl+T shortcut. Hidden only before
275
+ the very first tab is seeded.
276
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bobfrankston/rmfmail",
3
- "version": "1.1.93",
3
+ "version": "1.1.95",
4
4
  "description": "Local-first email client with IMAP sync and standalone native app",
5
5
  "type": "module",
6
6
  "main": "bin/mailx.js",
@@ -39,7 +39,7 @@
39
39
  "dependencies": {
40
40
  "@bobfrankston/iflow-direct": "^0.1.50",
41
41
  "@bobfrankston/mailx-host": "^0.1.13",
42
- "@bobfrankston/mailx-imap": "^0.1.51",
42
+ "@bobfrankston/mailx-imap": "^0.1.52",
43
43
  "@bobfrankston/mailx-store-web": "^0.1.21",
44
44
  "@bobfrankston/mailx-sync": "^0.1.19",
45
45
  "@bobfrankston/miscinfo": "^1.0.12",
@@ -119,7 +119,7 @@
119
119
  "dependencies": {
120
120
  "@bobfrankston/iflow-direct": "^0.1.50",
121
121
  "@bobfrankston/mailx-host": "^0.1.13",
122
- "@bobfrankston/mailx-imap": "^0.1.51",
122
+ "@bobfrankston/mailx-imap": "^0.1.52",
123
123
  "@bobfrankston/mailx-store-web": "^0.1.21",
124
124
  "@bobfrankston/mailx-sync": "^0.1.19",
125
125
  "@bobfrankston/miscinfo": "^1.0.12",