Add Web Push notifications, PWA support, and full-screen tablet kiosk

Parents get a real push notification when a kid checks off a task
(false->true transitions only, fire-and-forget, degrades gracefully with
no VAPID keys configured). Dashboard is a fully installable iOS/Android
PWA; each child's kiosk link gets its own dynamic per-token manifest so
"Add to Home Screen" opens straight into their board in standalone mode.

Kiosk view is reworked for tablets: safe-area-aware full-bleed layout,
the whole task row is now tappable (previously only the 24px checkbox
was, well under Apple's touch-target minimum), and app icons are
generated by a small dependency-free PNG encoder (no image tooling
available in this environment).

Push requires real HTTPS (iOS Safari won't allow it otherwise) - README
and UNRAID.md cover VAPID setup and the HTTPS prerequisite.
This commit is contained in:
ort
2026-08-15 16:14:56 -04:00
parent 56d8c4616c
commit 2826a3819c
27 changed files with 792 additions and 14 deletions
+50 -3
View File
@@ -6,10 +6,12 @@ off tasks that are already there.
- Parents: sign up, invite your spouse, create a calendar per child, edit
freely, print, duplicate a calendar for the next week.
- Kids: open their kiosk link on a tablet (add it to the home screen). They
can see the board and check boxes — nothing else.
- Kids: open their kiosk link on a tablet and add it to the home screen — it
launches full-screen with no browser chrome, and they can see the board
and check boxes — nothing else.
- Everything a child checks off shows up on the parents' devices within a
few seconds, no reload needed.
few seconds, no reload needed — and, if push notifications are set up,
as an actual notification too (see below).
## Running it
@@ -52,6 +54,44 @@ Unraid's usual appdata convention.
| `DATA_DIR` | `./data` | Where the SQLite file lives. |
| `COOKIE_SECURE` | `false` | Set `true` once this is behind HTTPS (e.g. a reverse proxy with a real certificate), so cookies are marked secure. Leave `false` for plain-HTTP LAN access, or login cookies won't be sent. |
| `DISABLE_PUBLIC_SIGNUP` | `false` | Set `true` once your household(s) exist, to stop the `/signup.html` page from creating new ones. Existing invite links still work. |
| `VAPID_PUBLIC_KEY` / `VAPID_PRIVATE_KEY` / `VAPID_SUBJECT` | unset | Optional — enables push notifications. See "Push notifications" below. Leave all three unset to skip the feature entirely; the app degrades gracefully (no broken UI). |
## Push notifications
When a kid checks off a task on the kiosk, parents can get a real push
notification instead of only the silent polling-based update. This is
optional — the app works fully without it.
**Requires real HTTPS.** Not "it's nice to have," a hard platform
requirement: Web Push needs a secure context, and iOS Safari specifically
requires a browser-trusted certificate (a self-signed one with a
click-through warning does not count). `http://localhost` is a
spec-defined exception for local development, but LAN access via
`http://<ip>:3007` will never get push working on iOS. See "Exposing this
beyond your home network" below for your HTTPS options — you need one of
those in place first.
Setup, once HTTPS is sorted:
1. Generate a VAPID keypair: `npx web-push generate-vapid-keys` (or
`docker run --rm node:22-alpine npx web-push generate-vapid-keys` if you
don't have Node locally).
2. Set `VAPID_PUBLIC_KEY`, `VAPID_PRIVATE_KEY`, and `VAPID_SUBJECT`
(`mailto:you@example.com` or an `https:` URL) in `.env`, then restart.
3. On the dashboard, each parent clicks "Enable notifications on this
device" — this is per-device, so do it on every phone/computer that
should get notified.
**On iPhone/iPad specifically**: Safari only allows push notifications for
web apps added to the Home Screen — a regular Safari tab can't subscribe at
all. Tap Share → Add to Home Screen on the dashboard first, then open the
app icon from your Home Screen and enable notifications from there. The
dashboard's notification card explains this in place if it detects it's
needed.
Regenerating the VAPID keypair invalidates every existing subscription
(everyone would need to re-enable notifications) — treat it as a one-time
setup step, not something to rotate casually.
## How access works
@@ -76,3 +116,10 @@ secure). If you want access from outside your home:
- Set `SESSION_SECRET` to a real random value (never the dev default).
- Consider setting `DISABLE_PUBLIC_SIGNUP=true` once your family's
household(s) are created.
This same HTTPS setup is also the prerequisite for push notifications (see
above) — a real, browser-trusted certificate, not a self-signed one. Options
that satisfy this: a domain + Let's Encrypt via the reverse proxy itself,
a locally-trusted CA like [mkcert](https://github.com/FiloSottile/mkcert)
with its root profile installed on your devices, or a tunnel (Tailscale
Funnel, Cloudflare Tunnel) that terminates real HTTPS for you.