@bobfrankston/rmfmail 1.2.231 → 1.2.233

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 (158) hide show
  1. package/client/android-bootstrap.bundle.js +164 -152
  2. package/client/android-bootstrap.bundle.js.map +4 -4
  3. package/client/app.bundle.js +13 -107
  4. package/client/app.bundle.js.map +4 -4
  5. package/client/components/calendar-sidebar.js +1 -1
  6. package/client/components/calendar-sidebar.js.map +1 -1
  7. package/client/components/calendar-sidebar.ts +1 -1
  8. package/client/components/message-list.js +0 -60
  9. package/client/components/message-list.js.map +1 -1
  10. package/client/components/message-list.ts +0 -56
  11. package/client/components/message-viewer.js +3 -2
  12. package/client/components/message-viewer.js.map +1 -1
  13. package/client/components/message-viewer.ts +3 -2
  14. package/client/compose/compose.bundle.js +198 -211
  15. package/client/compose/compose.bundle.js.map +4 -4
  16. package/client/compose/compose.html +0 -8
  17. package/client/compose/compose.js +1 -1
  18. package/client/compose/compose.js.map +1 -1
  19. package/client/compose/compose.ts +1 -1
  20. package/client/compose/editor.js +30 -32
  21. package/client/compose/editor.js.map +1 -1
  22. package/client/compose/editor.ts +27 -29
  23. package/client/compose/ghost-text.js +0 -8
  24. package/client/compose/ghost-text.js.map +1 -1
  25. package/client/compose/ghost-text.ts +0 -6
  26. package/client/compose/spellcheck-core.js +0 -1
  27. package/client/compose/spellcheck-core.js.map +1 -1
  28. package/client/compose/spellcheck-core.ts +0 -1
  29. package/client/index.html +0 -8
  30. package/client/lib/local-service.js +0 -73
  31. package/client/lib/local-service.js.map +1 -1
  32. package/client/lib/local-service.ts +0 -71
  33. package/client/lib/local-store.js +0 -3
  34. package/client/lib/local-store.js.map +1 -1
  35. package/client/lib/local-store.ts +0 -4
  36. package/package.json +1 -3
  37. package/packages/mailx-host/index.d.ts +0 -1
  38. package/packages/mailx-host/index.d.ts.map +1 -1
  39. package/packages/mailx-host/index.js +0 -1
  40. package/packages/mailx-host/index.js.map +1 -1
  41. package/packages/mailx-host/index.ts +0 -1
  42. package/packages/mailx-host/package.json +1 -1
  43. package/packages/mailx-service/index.d.ts.map +1 -1
  44. package/packages/mailx-service/index.js +36 -139
  45. package/packages/mailx-service/index.js.map +1 -1
  46. package/packages/mailx-service/index.ts +36 -148
  47. package/packages/mailx-settings/cloud.d.ts +0 -5
  48. package/packages/mailx-settings/cloud.d.ts.map +1 -1
  49. package/packages/mailx-settings/cloud.js +0 -16
  50. package/packages/mailx-settings/cloud.js.map +1 -1
  51. package/packages/mailx-settings/cloud.ts +0 -12
  52. package/packages/mailx-settings/index.d.ts +0 -3
  53. package/packages/mailx-settings/index.d.ts.map +1 -1
  54. package/packages/mailx-settings/index.js +0 -5
  55. package/packages/mailx-settings/index.js.map +1 -1
  56. package/packages/mailx-settings/index.ts +0 -7
  57. package/packages/mailx-store-web/main-thread-host.d.ts +1 -1
  58. package/packages/mailx-store-web/main-thread-host.d.ts.map +1 -1
  59. package/packages/mailx-store-web/main-thread-host.js +1 -38
  60. package/packages/mailx-store-web/main-thread-host.js.map +1 -1
  61. package/packages/mailx-store-web/main-thread-host.ts +0 -42
  62. package/packages/mailx-store-web/package.json +1 -1
  63. package/packages/mailx-store-web/web-service.d.ts.map +1 -1
  64. package/packages/mailx-store-web/web-service.js +28 -114
  65. package/packages/mailx-store-web/web-service.js.map +1 -1
  66. package/packages/mailx-store-web/web-service.ts +28 -124
  67. package/packages/mailx-store-web/web-settings.d.ts +0 -4
  68. package/packages/mailx-store-web/web-settings.d.ts.map +1 -1
  69. package/packages/mailx-store-web/web-settings.js +0 -29
  70. package/packages/mailx-store-web/web-settings.js.map +1 -1
  71. package/packages/mailx-store-web/web-settings.ts +0 -24
  72. package/packages/mailx-types/index.d.ts +2 -0
  73. package/packages/mailx-types/index.d.ts.map +1 -1
  74. package/packages/mailx-types/index.js +1 -0
  75. package/packages/mailx-types/index.js.map +1 -1
  76. package/packages/mailx-types/index.ts +2 -0
  77. package/packages/mailx-types/mime-build.d.ts +74 -0
  78. package/packages/mailx-types/mime-build.d.ts.map +1 -0
  79. package/packages/mailx-types/mime-build.js +160 -0
  80. package/packages/mailx-types/mime-build.js.map +1 -0
  81. package/packages/mailx-types/mime-build.ts +217 -0
  82. package/packages/mailx-types/package.json +1 -1
  83. package/packages/mailx-types/test/mime-build.test.mjs +200 -0
  84. package/client/components/calendar.js +0 -220
  85. package/client/components/calendar.js.map +0 -1
  86. package/client/components/calendar.ts +0 -213
  87. package/client/components/tasks.js +0 -261
  88. package/client/components/tasks.js.map +0 -1
  89. package/client/components/tasks.ts +0 -234
  90. package/packages/mailx-compose/.gitattributes +0 -10
  91. package/packages/mailx-compose/index.d.ts +0 -21
  92. package/packages/mailx-compose/index.d.ts.map +0 -1
  93. package/packages/mailx-compose/index.js +0 -66
  94. package/packages/mailx-compose/index.js.map +0 -1
  95. package/packages/mailx-compose/index.ts +0 -91
  96. package/packages/mailx-compose/package.json +0 -18
  97. package/packages/mailx-compose/tsconfig.json +0 -9
  98. package/packages/mailx-core/index.d.ts +0 -142
  99. package/packages/mailx-core/index.d.ts.map +0 -1
  100. package/packages/mailx-core/index.js +0 -430
  101. package/packages/mailx-core/index.js.map +0 -1
  102. package/packages/mailx-core/index.ts +0 -450
  103. package/packages/mailx-core/ipc.d.ts +0 -13
  104. package/packages/mailx-core/ipc.d.ts.map +0 -1
  105. package/packages/mailx-core/ipc.js +0 -56
  106. package/packages/mailx-core/ipc.js.map +0 -1
  107. package/packages/mailx-core/ipc.ts +0 -62
  108. package/packages/mailx-core/package.json +0 -18
  109. package/packages/mailx-core/tsconfig.json +0 -9
  110. package/packages/mailx-send/.gitattributes +0 -10
  111. package/packages/mailx-send/README.md +0 -217
  112. package/packages/mailx-send/cli-queue.d.ts +0 -11
  113. package/packages/mailx-send/cli-queue.d.ts.map +0 -1
  114. package/packages/mailx-send/cli-queue.js +0 -59
  115. package/packages/mailx-send/cli-queue.js.map +0 -1
  116. package/packages/mailx-send/cli-queue.ts +0 -62
  117. package/packages/mailx-send/cli-send.d.ts +0 -17
  118. package/packages/mailx-send/cli-send.d.ts.map +0 -1
  119. package/packages/mailx-send/cli-send.js +0 -75
  120. package/packages/mailx-send/cli-send.js.map +0 -1
  121. package/packages/mailx-send/cli-send.ts +0 -83
  122. package/packages/mailx-send/cli.d.ts +0 -22
  123. package/packages/mailx-send/cli.d.ts.map +0 -1
  124. package/packages/mailx-send/cli.js +0 -115
  125. package/packages/mailx-send/cli.js.map +0 -1
  126. package/packages/mailx-send/cli.ts +0 -126
  127. package/packages/mailx-send/index.d.ts +0 -77
  128. package/packages/mailx-send/index.d.ts.map +0 -1
  129. package/packages/mailx-send/index.js +0 -269
  130. package/packages/mailx-send/index.js.map +0 -1
  131. package/packages/mailx-send/index.ts +0 -338
  132. package/packages/mailx-send/mailsend/README.md +0 -133
  133. package/packages/mailx-send/mailsend/cli.d.ts +0 -12
  134. package/packages/mailx-send/mailsend/cli.d.ts.map +0 -1
  135. package/packages/mailx-send/mailsend/cli.js +0 -70
  136. package/packages/mailx-send/mailsend/cli.js.map +0 -1
  137. package/packages/mailx-send/mailsend/cli.ts +0 -81
  138. package/packages/mailx-send/mailsend/index.d.ts +0 -77
  139. package/packages/mailx-send/mailsend/index.d.ts.map +0 -1
  140. package/packages/mailx-send/mailsend/index.js +0 -264
  141. package/packages/mailx-send/mailsend/index.js.map +0 -1
  142. package/packages/mailx-send/mailsend/index.ts +0 -336
  143. package/packages/mailx-send/mailsend/package-lock.json +0 -65
  144. package/packages/mailx-send/mailsend/package.json +0 -26
  145. package/packages/mailx-send/mailsend/tsconfig.json +0 -21
  146. package/packages/mailx-send/package-lock.json +0 -65
  147. package/packages/mailx-send/package.json +0 -37
  148. package/packages/mailx-send/tsconfig.json +0 -21
  149. package/packages/mailx-server/.gitattributes +0 -10
  150. package/packages/mailx-server/index.d.ts +0 -8
  151. package/packages/mailx-server/index.d.ts.map +0 -1
  152. package/packages/mailx-server/index.js +0 -412
  153. package/packages/mailx-server/index.js.map +0 -1
  154. package/packages/mailx-server/index.ts +0 -445
  155. package/packages/mailx-server/package.json +0 -28
  156. package/packages/mailx-server/tsconfig.json +0 -9
  157. package/packages/mailx-server/tsconfig.tsbuildinfo +0 -1
  158. /package/packages/mailx-imap/{node_modules.npmglobalize-stash-7472 → node_modules.npmglobalize-stash-40004}/.package-lock.json +0 -0
@@ -1,213 +0,0 @@
1
- /**
2
- * Calendar pane — Thunderbird Lightning "Today Pane" style.
3
- *
4
- * Phase-1 scope (this commit): a usable mini-month + upcoming-events list
5
- * sourced from a local-only event store. Google Calendar sync is a separate
6
- * step (oauthsupport scope is already wired; the dispatcher branch + provider
7
- * are owed). UI lands first so the data layer can be slotted in without
8
- * UX rework.
9
- */
10
-
11
- interface CalEvent {
12
- id: string;
13
- title: string;
14
- start: number; // ms since epoch
15
- end: number;
16
- allDay?: boolean;
17
- location?: string;
18
- notes?: string;
19
- source?: "local" | "google";
20
- }
21
-
22
- const LOCAL_STORE_KEY = "mailx-cal-events-v1";
23
- let isOpen = false;
24
-
25
- function loadEvents(): CalEvent[] {
26
- try {
27
- const raw = localStorage.getItem(LOCAL_STORE_KEY);
28
- if (!raw) return [];
29
- const arr = JSON.parse(raw);
30
- return Array.isArray(arr) ? arr : [];
31
- } catch { return []; }
32
- }
33
- function saveEvents(events: CalEvent[]): void {
34
- try { localStorage.setItem(LOCAL_STORE_KEY, JSON.stringify(events)); } catch { /* */ }
35
- }
36
-
37
- export async function openCalendar(): Promise<void> {
38
- if (isOpen) return;
39
- isOpen = true;
40
-
41
- const backdrop = document.createElement("div");
42
- backdrop.className = "mailx-modal-backdrop";
43
- const panel = document.createElement("div");
44
- panel.className = "mailx-modal mailx-modal-wide";
45
- panel.innerHTML = `
46
- <div class="mailx-modal-title">
47
- <span class="mailx-modal-title-text">Calendar</span>
48
- <button type="button" class="mailx-modal-close" id="cal-close" title="Close (Esc)" aria-label="Close">&times;</button>
49
- </div>
50
- <div class="cal-grid">
51
- <div class="cal-month" id="cal-month"></div>
52
- <div class="cal-upcoming">
53
- <div class="cal-section-title">Upcoming</div>
54
- <div id="cal-events"></div>
55
- <button type="button" class="mailx-modal-btn mailx-modal-btn-primary" id="cal-new" style="margin-top:12px;">+ New event</button>
56
- </div>
57
- </div>
58
- <div class="mailx-modal-buttons">
59
- <span class="mailx-modal-spacer"></span>
60
- <span class="cal-source-note">Local-only · Google Calendar sync pending</span>
61
- <button type="button" class="mailx-modal-btn" data-action="close">Close</button>
62
- </div>`;
63
- backdrop.appendChild(panel);
64
- document.body.appendChild(backdrop);
65
-
66
- const monthEl = panel.querySelector<HTMLElement>("#cal-month")!;
67
- const eventsEl = panel.querySelector<HTMLElement>("#cal-events")!;
68
-
69
- let viewYear = new Date().getFullYear();
70
- let viewMonth = new Date().getMonth();
71
- let selectedDay = new Date();
72
- let events = loadEvents();
73
-
74
- const renderMonth = () => {
75
- const first = new Date(viewYear, viewMonth, 1);
76
- const lastDay = new Date(viewYear, viewMonth + 1, 0).getDate();
77
- const firstWeekday = first.getDay();
78
- const monthName = first.toLocaleDateString(undefined, { month: "long", year: "numeric" });
79
- const today = new Date();
80
- const isToday = (y: number, m: number, d: number) =>
81
- y === today.getFullYear() && m === today.getMonth() && d === today.getDate();
82
- const eventsByDay = new Map<string, CalEvent[]>();
83
- for (const e of events) {
84
- const d = new Date(e.start);
85
- const k = `${d.getFullYear()}-${d.getMonth()}-${d.getDate()}`;
86
- const arr = eventsByDay.get(k) || [];
87
- arr.push(e);
88
- eventsByDay.set(k, arr);
89
- }
90
- let html = `
91
- <div class="cal-nav">
92
- <button type="button" class="cal-nav-btn" data-nav="prev">‹</button>
93
- <span class="cal-nav-title">${monthName}</span>
94
- <button type="button" class="cal-nav-btn" data-nav="today">Today</button>
95
- <button type="button" class="cal-nav-btn" data-nav="next">›</button>
96
- </div>
97
- <div class="cal-month-grid">
98
- ${["S","M","T","W","T","F","S"].map(d => `<span class="cal-dow">${d}</span>`).join("")}`;
99
- for (let i = 0; i < firstWeekday; i++) html += `<span class="cal-day cal-day-blank"></span>`;
100
- for (let d = 1; d <= lastDay; d++) {
101
- const k = `${viewYear}-${viewMonth}-${d}`;
102
- const hasEv = eventsByDay.has(k);
103
- const sel = selectedDay.getFullYear() === viewYear && selectedDay.getMonth() === viewMonth && selectedDay.getDate() === d;
104
- const cls = ["cal-day"];
105
- if (isToday(viewYear, viewMonth, d)) cls.push("cal-day-today");
106
- if (sel) cls.push("cal-day-selected");
107
- if (hasEv) cls.push("cal-day-has-event");
108
- html += `<button type="button" class="${cls.join(" ")}" data-day="${d}">${d}</button>`;
109
- }
110
- html += `</div>`;
111
- monthEl.innerHTML = html;
112
- monthEl.querySelectorAll<HTMLButtonElement>("[data-day]").forEach(b => {
113
- b.addEventListener("click", () => {
114
- selectedDay = new Date(viewYear, viewMonth, +b.dataset.day!);
115
- renderMonth();
116
- renderEvents();
117
- });
118
- });
119
- monthEl.querySelectorAll<HTMLButtonElement>(".cal-nav-btn").forEach(b => {
120
- b.addEventListener("click", () => {
121
- const nav = b.dataset.nav;
122
- if (nav === "prev") {
123
- if (--viewMonth < 0) { viewMonth = 11; viewYear--; }
124
- } else if (nav === "next") {
125
- if (++viewMonth > 11) { viewMonth = 0; viewYear++; }
126
- } else if (nav === "today") {
127
- const t = new Date();
128
- viewYear = t.getFullYear(); viewMonth = t.getMonth(); selectedDay = t;
129
- }
130
- renderMonth();
131
- renderEvents();
132
- });
133
- });
134
- };
135
-
136
- const renderEvents = () => {
137
- const dayStart = new Date(selectedDay.getFullYear(), selectedDay.getMonth(), selectedDay.getDate()).getTime();
138
- const horizon = dayStart + 30 * 86400_000;
139
- const upcoming = events
140
- .filter(e => e.start >= dayStart && e.start < horizon)
141
- .sort((a, b) => a.start - b.start);
142
- if (upcoming.length === 0) {
143
- eventsEl.innerHTML = `<div class="cal-empty">No events in the next 30 days from ${selectedDay.toLocaleDateString()}.</div>`;
144
- return;
145
- }
146
- const fmt = (e: CalEvent) => {
147
- const d = new Date(e.start);
148
- const date = d.toLocaleDateString(undefined, { weekday: "short", month: "short", day: "numeric" });
149
- const time = e.allDay ? "all day" : d.toLocaleTimeString(undefined, { hour: "numeric", minute: "2-digit" });
150
- return `${date} · ${time}`;
151
- };
152
- eventsEl.innerHTML = upcoming.map(e => `
153
- <div class="cal-event" data-id="${e.id}">
154
- <div class="cal-event-time">${fmt(e)}</div>
155
- <div class="cal-event-title">${escapeHtml(e.title)}</div>
156
- ${e.location ? `<div class="cal-event-loc">${escapeHtml(e.location)}</div>` : ""}
157
- <button type="button" class="cal-event-del" title="Delete">×</button>
158
- </div>`).join("");
159
- eventsEl.querySelectorAll<HTMLElement>(".cal-event").forEach(row => {
160
- row.querySelector(".cal-event-del")?.addEventListener("click", () => {
161
- const id = row.dataset.id!;
162
- events = events.filter(e => e.id !== id);
163
- saveEvents(events);
164
- renderEvents();
165
- renderMonth();
166
- });
167
- });
168
- };
169
-
170
- panel.querySelector<HTMLButtonElement>("#cal-new")?.addEventListener("click", () => {
171
- const title = prompt("Event title:");
172
- if (!title) return;
173
- const dateStr = prompt(
174
- "Date and time (YYYY-MM-DD HH:MM, or YYYY-MM-DD for all-day):",
175
- // Local date components — toISOString() is the UTC date, which
176
- // pre-fills the wrong day for users east of UTC.
177
- `${selectedDay.getFullYear()}-${String(selectedDay.getMonth() + 1).padStart(2, "0")}-${String(selectedDay.getDate()).padStart(2, "0")} 09:00`
178
- );
179
- if (!dateStr) return;
180
- const allDay = !/\d{1,2}:\d{2}/.test(dateStr);
181
- const start = Date.parse(dateStr.replace(" ", "T"));
182
- if (isNaN(start)) { alert("Couldn't parse that date."); return; }
183
- const ev: CalEvent = {
184
- id: `cal-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
185
- title, start, end: start + (allDay ? 86400_000 : 3600_000),
186
- allDay, source: "local",
187
- };
188
- events.push(ev);
189
- saveEvents(events);
190
- renderMonth();
191
- renderEvents();
192
- });
193
-
194
- const close = () => {
195
- backdrop.remove();
196
- document.removeEventListener("keydown", onKey, true);
197
- isOpen = false;
198
- };
199
- const onKey = (e: KeyboardEvent) => {
200
- if (e.key === "Escape") { e.stopPropagation(); e.preventDefault(); close(); }
201
- };
202
- document.addEventListener("keydown", onKey, true);
203
- panel.querySelector<HTMLButtonElement>("#cal-close")!.addEventListener("click", close);
204
- panel.querySelector<HTMLButtonElement>('[data-action="close"]')!.addEventListener("click", close);
205
- backdrop.addEventListener("mousedown", (e) => { if (e.target === backdrop) close(); });
206
-
207
- renderMonth();
208
- renderEvents();
209
- }
210
-
211
- function escapeHtml(s: string): string {
212
- return s.replace(/[&<>"']/g, c => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", "\"": "&quot;", "'": "&#39;" }[c]!));
213
- }
@@ -1,261 +0,0 @@
1
- /**
2
- * Tasks pane — goal is "better than Thunderbird" on tasks.
3
- *
4
- * Phase-1 features (this commit):
5
- * - Local-only task store with priority, due-date, snooze, tags, notes
6
- * - Inline edit, drag-to-reorder by priority, mark complete with strikethrough
7
- * - Filter by status (active/completed/all), tag, due-soon
8
- * - "Snooze until" (defer-to-date) — Thunderbird Lightning has nothing here
9
- * - Quick add from email subject (composeInit-style, hooked from message viewer
10
- * right-click later)
11
- *
12
- * Phase-2 (later):
13
- * - Google Tasks sync (oauthsupport scope ready)
14
- * - CalDAV VTODO interop
15
- * - Task-from-email contextmenu
16
- * - Reminders that share the calendar/mail alarm subsystem
17
- */
18
- const STORE_KEY = "mailx-tasks-v1";
19
- let isOpen = false;
20
- function loadTasks() {
21
- try {
22
- const raw = localStorage.getItem(STORE_KEY);
23
- if (!raw)
24
- return [];
25
- const arr = JSON.parse(raw);
26
- return Array.isArray(arr) ? arr : [];
27
- }
28
- catch {
29
- return [];
30
- }
31
- }
32
- function saveTasks(tasks) {
33
- try {
34
- localStorage.setItem(STORE_KEY, JSON.stringify(tasks));
35
- }
36
- catch { /* */ }
37
- }
38
- export async function openTasks() {
39
- if (isOpen)
40
- return;
41
- isOpen = true;
42
- const backdrop = document.createElement("div");
43
- backdrop.className = "mailx-modal-backdrop";
44
- const panel = document.createElement("div");
45
- panel.className = "mailx-modal mailx-modal-wide";
46
- panel.innerHTML = `
47
- <div class="mailx-modal-title">
48
- <span class="mailx-modal-title-text">Tasks</span>
49
- <button type="button" class="mailx-modal-close" id="tk-close" title="Close (Esc)" aria-label="Close">&times;</button>
50
- </div>
51
- <div class="tk-toolbar">
52
- <input type="text" id="tk-quickadd" class="mailx-modal-input" placeholder="Add task — Enter to commit, prefix !!=high !=med ?=low, @tag, due:YYYY-MM-DD" autocomplete="off">
53
- </div>
54
- <div class="tk-filters">
55
- <button type="button" class="tk-filter-btn" data-filter="active">Active</button>
56
- <button type="button" class="tk-filter-btn" data-filter="due-soon">Due soon</button>
57
- <button type="button" class="tk-filter-btn" data-filter="completed">Completed</button>
58
- <button type="button" class="tk-filter-btn" data-filter="all">All</button>
59
- <span class="tk-spacer"></span>
60
- <span id="tk-count" class="tk-count"></span>
61
- </div>
62
- <div class="tk-list" id="tk-list"></div>
63
- <div class="mailx-modal-buttons">
64
- <span class="mailx-modal-spacer"></span>
65
- <span class="cal-source-note">Local-only · Google Tasks sync pending</span>
66
- <button type="button" class="mailx-modal-btn" data-action="close">Close</button>
67
- </div>`;
68
- backdrop.appendChild(panel);
69
- document.body.appendChild(backdrop);
70
- const quickAdd = panel.querySelector("#tk-quickadd");
71
- const listEl = panel.querySelector("#tk-list");
72
- const countEl = panel.querySelector("#tk-count");
73
- let tasks = loadTasks();
74
- let filter = "active";
75
- const setFilter = (f) => {
76
- filter = f;
77
- panel.querySelectorAll(".tk-filter-btn").forEach(b => b.classList.toggle("tk-filter-active", b.dataset.filter === f));
78
- render();
79
- };
80
- panel.querySelectorAll(".tk-filter-btn").forEach(b => b.addEventListener("click", () => setFilter(b.dataset.filter)));
81
- setFilter("active");
82
- const parseQuickAdd = (line) => {
83
- const t = {
84
- id: `tk-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
85
- title: "", priority: 0, createdAt: Date.now(),
86
- };
87
- const tags = [];
88
- const words = line.split(/\s+/);
89
- const titleParts = [];
90
- for (const w of words) {
91
- if (w === "!!") {
92
- t.priority = 3;
93
- continue;
94
- }
95
- if (w === "!") {
96
- t.priority = 2;
97
- continue;
98
- }
99
- if (w === "?") {
100
- t.priority = 1;
101
- continue;
102
- }
103
- if (w.startsWith("@") && w.length > 1) {
104
- tags.push(w.slice(1));
105
- continue;
106
- }
107
- const dueMatch = w.match(/^due:(\S+)$/i);
108
- if (dueMatch) {
109
- const parsed = Date.parse(dueMatch[1]);
110
- if (!isNaN(parsed))
111
- t.due = parsed;
112
- continue;
113
- }
114
- titleParts.push(w);
115
- }
116
- t.title = titleParts.join(" ").trim();
117
- if (tags.length)
118
- t.tags = tags;
119
- return t;
120
- };
121
- quickAdd.addEventListener("keydown", (e) => {
122
- if (e.key !== "Enter")
123
- return;
124
- const v = quickAdd.value.trim();
125
- if (!v)
126
- return;
127
- const t = parseQuickAdd(v);
128
- if (!t.title) {
129
- alert("Task needs a title.");
130
- return;
131
- }
132
- tasks.push(t);
133
- saveTasks(tasks);
134
- quickAdd.value = "";
135
- render();
136
- });
137
- const render = () => {
138
- const now = Date.now();
139
- let visible = tasks.slice();
140
- if (filter === "active")
141
- visible = visible.filter(t => !t.completed && (!t.snoozeUntil || t.snoozeUntil <= now));
142
- else if (filter === "completed")
143
- visible = visible.filter(t => !!t.completed);
144
- else if (filter === "due-soon")
145
- visible = visible.filter(t => !t.completed && t.due && t.due <= now + 7 * 86400_000);
146
- // Sort: priority desc, then due asc (none last), then created asc.
147
- visible.sort((a, b) => {
148
- if ((b.priority || 0) !== (a.priority || 0))
149
- return (b.priority || 0) - (a.priority || 0);
150
- const ad = a.due || Number.MAX_SAFE_INTEGER;
151
- const bd = b.due || Number.MAX_SAFE_INTEGER;
152
- if (ad !== bd)
153
- return ad - bd;
154
- return a.createdAt - b.createdAt;
155
- });
156
- countEl.textContent = `${visible.length} of ${tasks.length}`;
157
- if (visible.length === 0) {
158
- listEl.innerHTML = `<div class="tk-empty">Nothing matches the ${filter} filter.</div>`;
159
- return;
160
- }
161
- const dueLabel = (ms) => {
162
- if (!ms)
163
- return "";
164
- const d = new Date(ms);
165
- const today = new Date();
166
- today.setHours(0, 0, 0, 0);
167
- const dt = new Date(ms);
168
- dt.setHours(0, 0, 0, 0);
169
- const days = Math.round((dt.getTime() - today.getTime()) / 86400_000);
170
- if (days < 0)
171
- return `${-days}d overdue`;
172
- if (days === 0)
173
- return "today";
174
- if (days === 1)
175
- return "tomorrow";
176
- if (days < 7)
177
- return `${days}d`;
178
- return d.toLocaleDateString();
179
- };
180
- const prioLabel = (p) => p === 3 ? "‼" : p === 2 ? "!" : p === 1 ? "·" : "";
181
- listEl.innerHTML = visible.map(t => `
182
- <div class="tk-row${t.completed ? " tk-done" : ""}" data-id="${t.id}">
183
- <input type="checkbox" class="tk-check" ${t.completed ? "checked" : ""}>
184
- <span class="tk-prio tk-prio-${t.priority}">${prioLabel(t.priority)}</span>
185
- <span class="tk-title" contenteditable="plaintext-only">${escapeHtml(t.title)}</span>
186
- ${t.tags?.length ? `<span class="tk-tags">${t.tags.map(x => `#${escapeHtml(x)}`).join(" ")}</span>` : ""}
187
- <span class="tk-due${t.due && t.due < now && !t.completed ? " tk-overdue" : ""}">${dueLabel(t.due)}</span>
188
- <button type="button" class="tk-snooze" title="Snooze 1d / 1w (right-click)">⏰</button>
189
- <button type="button" class="tk-del" title="Delete">×</button>
190
- </div>`).join("");
191
- listEl.querySelectorAll(".tk-row").forEach(row => {
192
- const id = row.dataset.id;
193
- const t = tasks.find(x => x.id === id);
194
- row.querySelector(".tk-check").addEventListener("change", (e) => {
195
- const ck = e.target;
196
- t.completed = ck.checked ? Date.now() : undefined;
197
- saveTasks(tasks);
198
- render();
199
- });
200
- row.querySelector(".tk-del").addEventListener("click", () => {
201
- if (!confirm(`Delete task "${t.title}"?`))
202
- return;
203
- tasks = tasks.filter(x => x.id !== id);
204
- saveTasks(tasks);
205
- render();
206
- });
207
- row.querySelector(".tk-snooze").addEventListener("click", () => {
208
- t.snoozeUntil = Date.now() + 86400_000; // 1d
209
- saveTasks(tasks);
210
- render();
211
- });
212
- row.querySelector(".tk-snooze").addEventListener("contextmenu", (e) => {
213
- e.preventDefault();
214
- t.snoozeUntil = Date.now() + 7 * 86400_000; // 1w
215
- saveTasks(tasks);
216
- render();
217
- });
218
- const titleEl = row.querySelector(".tk-title");
219
- titleEl.addEventListener("blur", () => {
220
- const v = (titleEl.textContent || "").trim();
221
- if (v && v !== t.title) {
222
- t.title = v;
223
- saveTasks(tasks);
224
- }
225
- });
226
- titleEl.addEventListener("keydown", (e) => {
227
- if (e.key === "Enter") {
228
- e.preventDefault();
229
- titleEl.blur();
230
- }
231
- });
232
- });
233
- };
234
- const close = () => {
235
- backdrop.remove();
236
- document.removeEventListener("keydown", onKey, true);
237
- isOpen = false;
238
- };
239
- // Esc always closes. Earlier guard blocked Esc when focus was in the
240
- // quickadd input, which made the panel feel stuck — user hits Esc to
241
- // dismiss and nothing happens. Blur-on-Esc before close is the right
242
- // behavior: the close handler is idempotent and the input loses focus
243
- // when the backdrop goes away anyway.
244
- const onKey = (e) => {
245
- if (e.key === "Escape") {
246
- e.stopPropagation();
247
- e.preventDefault();
248
- close();
249
- }
250
- };
251
- document.addEventListener("keydown", onKey, true);
252
- panel.querySelector("#tk-close").addEventListener("click", close);
253
- panel.querySelector('[data-action="close"]').addEventListener("click", close);
254
- backdrop.addEventListener("mousedown", (e) => { if (e.target === backdrop)
255
- close(); });
256
- quickAdd.focus();
257
- }
258
- function escapeHtml(s) {
259
- return s.replace(/[&<>"']/g, c => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", "\"": "&quot;", "'": "&#39;" }[c]));
260
- }
261
- //# sourceMappingURL=tasks.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"tasks.js","sourceRoot":"","sources":["tasks.ts"],"names":[],"mappings":"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"}