From d59850139319c8d0bcbb3978c2d8b49afa56c504 Mon Sep 17 00:00:00 2001 From: nmemmert <67961292+nmemmert@users.noreply.github.com> Date: Fri, 23 Oct 2026 09:55:23 -0400 Subject: [PATCH] Home: the Tasks card lists what is overdue or due this week from every list, with a tick --- public/sw.js | 2 +- public/tasks.js | 15 +++++++++++---- tasks.js | 6 ++++++ 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/public/sw.js b/public/sw.js index a8c73d3..e9b8da0 100644 --- a/public/sw.js +++ b/public/sw.js @@ -1,5 +1,5 @@ // App-shell cache only; Seafile/API traffic always goes to the network. -const CACHE = 'hub-v25'; +const CACHE = 'hub-v26'; const SHARE = 'hub-share'; // files shared into the app from other apps, held until the person picks a folder const SHELL = ['/icon.svg', '/manifest.webmanifest', '/icons/icon-192.png', '/icons/apple-touch-icon.png']; diff --git a/public/tasks.js b/public/tasks.js index a7386b7..8103047 100644 --- a/public/tasks.js +++ b/public/tasks.js @@ -111,13 +111,20 @@ async function taskPoll() { try { const s = await jfetch('/api/tasks/summary?today=' + ymd(new Date())), n = (s.overdue || 0) + (s.today || 0); if (n !== taskDue) { taskDue = n; renderNav(); } } catch {} } -// Home: a card only when something is overdue or due today +// Home: the tasks that are overdue, due today or due this week, from every list (NE Hub and iCloud), with a tick to finish each async function renderTasksCard(el) { if (!el) return; try { - const s = await jfetch('/api/tasks/summary?today=' + ymd(new Date())), n = s.overdue + s.today; - if (!n || !document.body.contains(el)) return; - el.innerHTML = `

Tasks

${icon('check')}${n} task${n === 1 ? '' : 's'} need${n === 1 ? 's' : ''} attention${s.overdue ? s.overdue + ' overdue' : ''}${s.overdue && s.today ? ' · ' : ''}${s.today ? s.today + ' due today' : ''}${icon('chev', 'chev')}`; + const r = await jfetch('/api/tasks/upcoming?today=' + ymd(new Date())); + if (!document.body.contains(el)) return; if (!r.tasks.length) { el.innerHTML = ''; return; } + const rows = r.tasks.map((t, i) => { const du = dueInfo(t.due); + return `
${esc(t.title)}${esc(du.text)}${t.listName ? ' · ' + esc(t.listName) : ''}
`; }).join(''); + el.innerHTML = `

Tasks

${rows}

${r.total > r.tasks.length ? 'All ' + r.total + ' coming up' : 'All tasks'}

`; + el.querySelectorAll('button[data-h]').forEach(b => b.onclick = async () => { + const t = r.tasks[+b.dataset.h]; b.disabled = true; + try { await jfetch('/api/tasks/toggle', { method: 'POST', body: JSON.stringify({ list: t.list, id: t.id, href: t.href, done: true }) }); taskPoll(); renderTasksCard(el); } + catch (err) { b.disabled = false; toast(err.message); } + }); } catch {} } diff --git a/tasks.js b/tasks.js index 7a649cd..4184ff1 100644 --- a/tasks.js +++ b/tasks.js @@ -152,6 +152,12 @@ async function handle(req, res) { if (!/^\d{4}-\d{2}-\d{2}$/.test(from) || !/^\d{4}-\d{2}-\d{2}$/.test(to)) throw new Error('Bad date range'); return json(res, 200, (await allTasks()).filter(x => !x.done && !x.parent && x.due && x.due >= from && x.due <= to).slice(0, 500)); } + if (p === '/api/tasks/upcoming' && req.method === 'GET') { // for the Home card: what is overdue, due today or due in the next week, from every list + const today = q.get('today') || new Date().toISOString().slice(0, 10); if (!/^\d{4}-\d{2}-\d{2}$/.test(today)) throw new Error('Bad date'); + const end = new Date(today + 'T00:00:00Z'); end.setUTCDate(end.getUTCDate() + 7); const last = end.toISOString().slice(0, 10); + const rows = (await allTasks()).filter(x => !x.done && !x.parent && x.due && x.due <= last).sort((a, b) => a.due.localeCompare(b.due) || a.title.localeCompare(b.title)); + return json(res, 200, { total: rows.length, tasks: rows.slice(0, 8) }); + } if (p === '/api/tasks/summary' && req.method === 'GET') { // for the Home card: open tasks that are overdue or due today const today = q.get('today') || new Date().toISOString().slice(0, 10), out = { overdue: 0, today: 0, open: 0 }; const count = list => list.forEach(t => { if (t.done) return; out.open++; if (t.due && t.due < today) out.overdue++; else if (t.due === today) out.today++; });