@bobfrankston/rmfmail 1.2.317 → 1.2.319
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/.commitmsg +15 -34
- package/.llm/trusted-lists.md +2 -0
- package/client/app.bundle.js +47 -4
- package/client/app.bundle.js.map +2 -2
- package/client/components/calendar-sidebar.js +54 -3
- package/client/components/calendar-sidebar.js.map +1 -1
- package/client/components/calendar-sidebar.ts +49 -3
- package/client/compose/compose.bundle.js +23 -0
- package/client/compose/compose.bundle.js.map +2 -2
- package/client/compose/editor.js +40 -0
- package/client/compose/editor.js.map +1 -1
- package/client/compose/editor.ts +37 -0
- package/npmchanges.md +62 -0
- package/package.json +5 -5
- package/packages/mailx-imap/package-lock.json +2 -2
- package/packages/mailx-imap/package.json +1 -1
- package/packages/mailx-service/google-sync.d.ts +5 -0
- package/packages/mailx-service/google-sync.d.ts.map +1 -1
- package/packages/mailx-service/google-sync.js +1 -0
- package/packages/mailx-service/google-sync.js.map +1 -1
- package/packages/mailx-service/google-sync.ts +6 -0
- package/packages/mailx-service/index.d.ts +4 -0
- package/packages/mailx-service/index.d.ts.map +1 -1
- package/packages/mailx-service/index.js +19 -8
- package/packages/mailx-service/index.js.map +1 -1
- package/packages/mailx-service/index.ts +23 -8
- package/packages/mailx-service/package.json +1 -1
- package/packages/mailx-settings/package.json +1 -1
- package/packages/mailx-store/package.json +1 -1
- package/packages/mailx-store-web/package.json +1 -1
- package/packages/mailx-types/mailx-api.d.ts +2 -0
- package/packages/mailx-types/mailx-api.d.ts.map +1 -1
- package/packages/mailx-types/mailx-api.ts +2 -1
- package/packages/mailx-types/package.json +1 -1
package/.commitmsg
CHANGED
|
@@ -1,37 +1,18 @@
|
|
|
1
|
-
|
|
1
|
+
Compose: typing after a pasted link no longer extends the link
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Bob 2026-09-10: "there is still a problem in typing after pasting a link.
|
|
4
|
+
It extends the link text rather than acting as regular text."
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
the
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
work from v1.2.316 and the post-create refresh timers are gone with the
|
|
15
|
-
page they served.
|
|
6
|
+
TinyMCE (his editor) turns a pasted URL into an anchor through its smart
|
|
7
|
+
paste and leaves the caret INSIDE the anchor at the end of its text, so
|
|
8
|
+
every character typed next became more link text while the target stayed
|
|
9
|
+
the pasted URL — a link that no longer says what it does. Same when the
|
|
10
|
+
clipboard carries an anchor copied from a page. New
|
|
11
|
+
stepCaretOutOfPastedLink in client/compose/editor.ts: one tick after a
|
|
12
|
+
paste, if the caret is collapsed at the very end of an anchor, it is set
|
|
13
|
+
to just after the anchor; a caret mid-link or outside any link is left
|
|
14
|
+
alone. Contained in mailx's TinyMCE wiring; rmf-tiny untouched.
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
that), and re-renders at local midnight.
|
|
21
|
-
|
|
22
|
-
"Still showing…" had a second cause: the Refresh button said "from
|
|
23
|
-
Google" and only re-read local rows — the daemon's 5-minute throttle made
|
|
24
|
-
it a no-op most of the time. It now calls refreshCalendarNow (v1.2.316)
|
|
25
|
-
and reports when nothing was pulled and why. The window's focus does the
|
|
26
|
-
same, so an edit made in Google Calendar shows on coming back to rmfmail.
|
|
27
|
-
|
|
28
|
-
"How do I edit the calendar list? Perhaps more tooltip help would be
|
|
29
|
-
useful?" Every control in the sidebar header now says what it does and
|
|
30
|
-
what it does not: the calendar rows say that unticking hides a calendar
|
|
31
|
-
here while the list itself is the calendars selected in Google Calendar;
|
|
32
|
-
the ‹ › buttons say the list then stays on that day; New event says it
|
|
33
|
-
saves and how to edit. Event rows: click opens the event in Google
|
|
34
|
-
Calendar to edit; a just-saved row says it is syncing and cannot be
|
|
35
|
-
opened there yet; right-click offers Edit "‹title›" in Google Calendar
|
|
36
|
-
and Delete "‹title›" (local-first, queued to Google), with confirmAt at
|
|
37
|
-
the pointer.
|
|
16
|
+
The Quill branch has the same shape (insertText with a link format, then
|
|
17
|
+
setSelection at its end) and is not changed here — untested, and not the
|
|
18
|
+
editor in use.
|
package/.llm/trusted-lists.md
CHANGED
|
@@ -62,3 +62,5 @@ tests/trust.test.ts, .commitmsg, TODO.md C165, root version 1.2.311. Then rebuil
|
|
|
62
62
|
buildGoogleEventUrl/authuser/post-create timers removed. viewPinned + followToday + midnight rollover.
|
|
63
63
|
Refresh button + window focus call refreshCalendarNow. Tooltips on all sidebar controls; event rows:
|
|
64
64
|
click = edit in Google, right-click = Delete "<title>" (deleteCalendarEvent). Publishing as v1.2.317.
|
|
65
|
+
- v1.2.318: New event Calendar picker (writable calendars via accessRole from listCalendars). Store-sync drain now passes calendarId to create/update/delete (was always "primary" — shared-calendar edits 404'd forever). Google: create/subscribe/share calendars on calendar.google.com; rmfmail lists the ones selected there.
|
|
66
|
+
- v1.2.319: TinyMCE smart-paste left the caret INSIDE the pasted <a>; stepCaretOutOfPastedLink in client/compose/editor.ts moves it after the anchor one tick after paste. Quill path has the same shape (insertText link + setSelection) — untouched, Bob uses TinyMCE.
|
package/client/app.bundle.js
CHANGED
|
@@ -6684,6 +6684,9 @@ function armMidnightRollover() {
|
|
|
6684
6684
|
armMidnightRollover();
|
|
6685
6685
|
}, next.getTime() - now.getTime());
|
|
6686
6686
|
}
|
|
6687
|
+
function writableCalendars(list) {
|
|
6688
|
+
return list.filter((c) => c.accessRole === "owner" || c.accessRole === "writer").sort((a, b) => (a.primary ? 0 : 1) - (b.primary ? 0 : 1) || a.name.localeCompare(b.name));
|
|
6689
|
+
}
|
|
6687
6690
|
function calendarKind(id, primary) {
|
|
6688
6691
|
if (primary)
|
|
6689
6692
|
return "personal";
|
|
@@ -7193,6 +7196,38 @@ function openNewEventDialog() {
|
|
|
7193
7196
|
ta.placeholder = "Lunch with John tomorrow at noon at Joe's Pizza";
|
|
7194
7197
|
const status = document.createElement("div");
|
|
7195
7198
|
status.style.cssText = "min-height:1.2em;font-size:0.85em;color:var(--color-text-muted);";
|
|
7199
|
+
const calRow = document.createElement("label");
|
|
7200
|
+
calRow.style.cssText = "display:flex;align-items:center;gap:8px;font-size:0.9em;";
|
|
7201
|
+
calRow.title = "The calendar this event is saved to. Only calendars you can write to are listed; to add or share a calendar, do that in Google Calendar and press Refresh.";
|
|
7202
|
+
const calSelect = document.createElement("select");
|
|
7203
|
+
calSelect.style.cssText = "flex:1;font:inherit;padding:4px;";
|
|
7204
|
+
calRow.append("Calendar", calSelect);
|
|
7205
|
+
calRow.hidden = true;
|
|
7206
|
+
const fillCalendars = (list) => {
|
|
7207
|
+
const writable = writableCalendars(list);
|
|
7208
|
+
calSelect.innerHTML = "";
|
|
7209
|
+
let last = "";
|
|
7210
|
+
try {
|
|
7211
|
+
last = localStorage.getItem(LAST_CALENDAR_PREF) || "";
|
|
7212
|
+
} catch {
|
|
7213
|
+
}
|
|
7214
|
+
for (const c of writable) {
|
|
7215
|
+
const opt = document.createElement("option");
|
|
7216
|
+
opt.value = c.id;
|
|
7217
|
+
opt.textContent = c.primary ? `${c.name} (personal)` : c.name;
|
|
7218
|
+
if (c.id === last || !last && c.primary)
|
|
7219
|
+
opt.selected = true;
|
|
7220
|
+
calSelect.append(opt);
|
|
7221
|
+
}
|
|
7222
|
+
calRow.hidden = writable.length < 2;
|
|
7223
|
+
};
|
|
7224
|
+
if (calendarList.length)
|
|
7225
|
+
fillCalendars(calendarList);
|
|
7226
|
+
else
|
|
7227
|
+
getCalendars().then((list) => {
|
|
7228
|
+
calendarList = list;
|
|
7229
|
+
fillCalendars(calendarList);
|
|
7230
|
+
}).catch((e) => console.warn("[calendar] calendar list for the picker failed:", e?.message || e));
|
|
7196
7231
|
const btnRow = document.createElement("div");
|
|
7197
7232
|
btnRow.style.cssText = "display:flex;gap:8px;justify-content:flex-end;";
|
|
7198
7233
|
const cancelBtn = document.createElement("button");
|
|
@@ -7202,7 +7237,7 @@ function openNewEventDialog() {
|
|
|
7202
7237
|
createBtn.textContent = "Create";
|
|
7203
7238
|
createBtn.style.cssText = "padding:6px 14px;font-weight:500;";
|
|
7204
7239
|
btnRow.append(cancelBtn, createBtn);
|
|
7205
|
-
panel.append(heading, hint, ta, status, btnRow);
|
|
7240
|
+
panel.append(heading, hint, ta, calRow, status, btnRow);
|
|
7206
7241
|
backdrop.append(panel);
|
|
7207
7242
|
document.body.append(backdrop);
|
|
7208
7243
|
setTimeout(() => ta.focus(), 0);
|
|
@@ -7260,8 +7295,14 @@ function openNewEventDialog() {
|
|
|
7260
7295
|
}
|
|
7261
7296
|
const targets = events.length ? events : [null];
|
|
7262
7297
|
const saved = [];
|
|
7298
|
+
const calendarId = calSelect.value || "primary";
|
|
7299
|
+
const calendarName = calSelect.selectedOptions[0]?.textContent || "";
|
|
7300
|
+
try {
|
|
7301
|
+
localStorage.setItem(LAST_CALENDAR_PREF, calendarId);
|
|
7302
|
+
} catch {
|
|
7303
|
+
}
|
|
7263
7304
|
for (const ev of targets) {
|
|
7264
|
-
const row = eventToLocalRow(ev, text);
|
|
7305
|
+
const row = { ...eventToLocalRow(ev, text), calendarId };
|
|
7265
7306
|
try {
|
|
7266
7307
|
await createCalendarEvent(row);
|
|
7267
7308
|
saved.push(row.title);
|
|
@@ -7274,8 +7315,9 @@ function openNewEventDialog() {
|
|
|
7274
7315
|
}
|
|
7275
7316
|
close();
|
|
7276
7317
|
const st = document.getElementById("status-sync");
|
|
7318
|
+
const where = calendarName && !calRow.hidden ? ` to ${calendarName}` : "";
|
|
7277
7319
|
if (st)
|
|
7278
|
-
st.textContent = saved.length === 1 ? `Saved event: ${saved[0]}` : `Saved ${saved.length} events: ${saved.join("; ")}`;
|
|
7320
|
+
st.textContent = saved.length === 1 ? `Saved event${where}: ${saved[0]}` : `Saved ${saved.length} events${where}: ${saved.join("; ")}`;
|
|
7279
7321
|
await refresh();
|
|
7280
7322
|
});
|
|
7281
7323
|
}
|
|
@@ -7520,7 +7562,7 @@ function initCalendarSidebar() {
|
|
|
7520
7562
|
}
|
|
7521
7563
|
}
|
|
7522
7564
|
}
|
|
7523
|
-
var SIDEBAR_PREF, SHOW_RECURRING_PREF, SHOW_DONE_PREF, HORIZON_DAYS_PREF, HORIZON_DEFAULT_DAYS, HOLIDAY_HORIZON_MS, viewYear, viewMonth, viewDay, viewPinned, lastEvents, lastOverdueTasks, calById, calendarList, hiddenCalendars, selectedTaskUuids, TASK_DELETE_NOTE;
|
|
7565
|
+
var SIDEBAR_PREF, SHOW_RECURRING_PREF, SHOW_DONE_PREF, HORIZON_DAYS_PREF, HORIZON_DEFAULT_DAYS, HOLIDAY_HORIZON_MS, viewYear, viewMonth, viewDay, viewPinned, lastEvents, lastOverdueTasks, LAST_CALENDAR_PREF, calById, calendarList, hiddenCalendars, selectedTaskUuids, TASK_DELETE_NOTE;
|
|
7524
7566
|
var init_calendar_sidebar = __esm({
|
|
7525
7567
|
"client/components/calendar-sidebar.js"() {
|
|
7526
7568
|
"use strict";
|
|
@@ -7538,6 +7580,7 @@ var init_calendar_sidebar = __esm({
|
|
|
7538
7580
|
viewPinned = false;
|
|
7539
7581
|
lastEvents = [];
|
|
7540
7582
|
lastOverdueTasks = [];
|
|
7583
|
+
LAST_CALENDAR_PREF = "mailx.calendar.lastCreateCalendar";
|
|
7541
7584
|
calById = /* @__PURE__ */ new Map();
|
|
7542
7585
|
calendarList = [];
|
|
7543
7586
|
hiddenCalendars = /* @__PURE__ */ new Set();
|