Chores, Family page, genre search, child accounts, wider Search and Notifications center
build-container / build (push) Successful in 4m6s
build-container / build (push) Successful in 4m6s
- Chores tab with repeats, points and a week/month board - Family page: calendar, chores, shopping, notes, chat and tasks on one start page - Genre search in the Store, Free Books and LibriVox - Child accounts: safe content, daily limit and bedtime, ask a parent - Search now covers notes, chat, contacts, chores, recipes and your books - Notifications center: bell with a per-person list of chat, reminders and announcements - Roadmap, README and tests updated Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
cf292e3bc7
commit
0383da87f5
38 files changed
+720
-79
No files matched your search
@@ -3,13 +3,14 @@
|
||||
const cal = require('./cal');
|
||||
const tasks = require('./tasks');
|
||||
const users = require('./users');
|
||||
const notes = require('./notes'), chat = require('./chat'), contacts = require('./contacts'), recipes = require('./recipes'), choresMod = require('./chores');
|
||||
|
||||
const json = (res, code, obj) => { res.writeHead(code, { 'content-type': 'application/json' }); res.end(JSON.stringify(obj)); };
|
||||
const ymd = d => `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
|
||||
|
||||
async function handle(req, res) {
|
||||
const q = (new URL(req.url, 'http://x').searchParams.get('q') || '').trim().toLowerCase().slice(0, 100);
|
||||
if (q.length < 2) return json(res, 200, { tasks: [], events: [], errors: [] });
|
||||
if (q.length < 2) return json(res, 200, { tasks: [], events: [], notes: [], chat: [], contacts: [], chores: [], recipes: [], errors: [] });
|
||||
const errors = [];
|
||||
let foundTasks = [], foundEvents = [];
|
||||
const me = users.current();
|
||||
@@ -27,7 +28,14 @@ async function handle(req, res) {
|
||||
.sort((a, b) => { const ua = when(a) >= t0, ub = when(b) >= t0; return ua === ub ? (ua ? when(a) - when(b) : when(b) - when(a)) : ua ? -1 : 1; }) // upcoming first (soonest), then recent past
|
||||
.slice(0, 8);
|
||||
} catch (e) { errors.push('Calendar: ' + e.message); }
|
||||
json(res, 200, { tasks: foundTasks, events: foundEvents, errors });
|
||||
// the family parts of the hub
|
||||
const fam = { notes: [], chat: [], contacts: [], chores: [], recipes: [] };
|
||||
if (users.can(me, 'notes')) try { fam.notes = notes.search(me, q); } catch (e) { errors.push('Notes: ' + e.message); }
|
||||
if (users.can(me, 'chat')) try { fam.chat = chat.searchFor(me, q); } catch (e) { errors.push('Chat: ' + e.message); }
|
||||
if (users.can(me, 'contacts')) try { fam.contacts = contacts.load().filter(c => [c.name, c.org, ...c.emails.map(e => e.value), ...c.phones.map(p => p.value)].some(x => String(x || '').toLowerCase().includes(q))).slice(0, 8).map(c => ({ id: c.id, name: c.name, org: c.org, email: (c.emails[0] || {}).value || '', phone: (c.phones[0] || {}).value || '' })); } catch (e) { errors.push('Contacts: ' + e.message); }
|
||||
if (users.can(me, 'chores')) try { fam.chores = choresMod.find(q).slice(0, 8); } catch (e) { errors.push('Chores: ' + e.message); }
|
||||
if (users.can(me, 'recipes')) fam.recipes = await recipes.search(q);
|
||||
json(res, 200, { tasks: foundTasks, events: foundEvents, ...fam, errors });
|
||||
}
|
||||
|
||||
module.exports = { handle };
|
||||
Reference in new issue
Block a user