Shared Family calendar and task list; notes default to Family; phone chat and Family card fixes
build-container / build (push) Successful in 4m14s

- Built-in Family calendar everyone with Calendar can edit (data/family)
- Family task list shared by everyone with Tasks
- New notes and lists start shared with the family
- Phone chat sized above the bottom bar and mini player so the message box is visible
- Family page cards no longer overflow on long chat previews
- Tests added and updated

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
nmemmertandClaude Sonnet 5.5 committed 2026-10-26 12:33:23 -04:00
1 parent 0383da87f5
commit 058f410a58
11 files changed
+65 -17

No files matched your search

+4 -2
View File
@@ -228,7 +228,8 @@ const readJ = (f, d) => { try { return JSON.parse(fs.readFileSync(f, 'utf8')); }
const writeJ = (f, v) => atomicWrite(here(f), JSON.stringify(v, null, 2), { mode: 0o600 });
const HEX = /^#[0-9a-f]{6}$/i;
const DEFAULT_COLOR = '#4f7cff', COLORS = [DEFAULT_COLOR, '#2f9e6e', '#e0742b', '#d9453a', '#8a5cf0', '#e5a00d'];
const dirFor = id => users.dirOf(id);
const FAM = 'family', FAMCAL = { id: 'local', name: 'Family', color: '#e0742b', shares: [] }; // the calendar the whole household shares
const dirFor = id => { if (id !== FAM) return users.dirOf(id); const d = path.join(process.env.DATA_DIR || path.join(__dirname, 'data'), 'family'); fs.mkdirSync(d, { recursive: true }); return d; };
const myId = () => users.current().id;
/** A person's own NE Hub calendars. The first one is the original "NE Hub" calendar (id "local"), so older events stay in it. */
@@ -244,7 +245,7 @@ const colorOverrides = () => readJ(here(COLOR_FILE), {});
/** Calendars other people shared with the current person: [{ id: "owner~calId", owner, ownerName, cal, mode }] */
function sharedWithMe() {
const me = myId(), out = [];
const me = myId(), out = users.current() && users.can(users.current(), 'calendar') ? [{ id: FAM + '~local', owner: FAM, ownerName: 'the whole family', cal: FAMCAL, mode: 'edit' }] : [];
for (const u of users.all()) {
if (u.disabled || u.id === me) continue;
for (const c of calsIn(dirFor(u.id))) {
@@ -260,6 +261,7 @@ function resolveCal(id) {
const me = myId();
if (typeof id === 'string' && id.includes('~')) {
const [owner, cid] = id.split('~');
if (owner === FAM) return cid === 'local' && users.can(users.current(), 'calendar') ? { owner: FAM, dir: dirFor(FAM), cal: FAMCAL, cid: 'local', mode: 'edit' } : null;
const u = users.get(owner);
if (!u || u.disabled) return null;
const c = calsIn(dirFor(owner)).find(x => x.id === cid);