Make the app installable and deliver existing alert notifications as OS push, alongside the in-app bell. Backend: - PushSubscription model (per-device endpoint + keys, owned by a user) and register/unregister/test endpoints under /api/v2/push, cookie-auth scoped to the user like the subscription routes. - push.py: VAPID key management (env -> data/vapid.json -> generated) and a pywebpush send helper that reports gone endpoints for pruning. No DB coupling. - notify.py: after creating an in-app Notification, dispatch Web Push to the user's devices (guarded — a push failure never affects the in-app write; endpoints reported gone are pruned). - Serve the .webmanifest with the correct media type. Frontend: - manifest.webmanifest + 192/maskable icons; <link rel="manifest"> on all pages. - sw.js: push + notificationclick handlers (push-only; no fetch caching, so it doesn't fight the existing IndexedDB cache). Registered globally in nav.js in secure contexts. - push-client.js + a "Notifications on this device" toggle and test-send on the /alerts page, subscribing through the existing cookie-aware apiFetch. Push and service workers require a secure context, so this is active over HTTPS (or http://localhost) and cleanly no-ops on a plain-HTTP LAN origin.
16 lines
735 B
JSON
16 lines
735 B
JSON
{
|
|
"name": "Thermograph — how unusual is your weather?",
|
|
"short_name": "Thermograph",
|
|
"description": "See how recent weather anywhere on Earth stacks up against ~45 years of local climate history, and get alerts when it turns unusual.",
|
|
"start_url": ".",
|
|
"scope": "./",
|
|
"display": "standalone",
|
|
"background_color": "#171b21",
|
|
"theme_color": "#f0803c",
|
|
"icons": [
|
|
{ "src": "logo.svg", "sizes": "any", "type": "image/svg+xml" },
|
|
{ "src": "logo-192.png", "sizes": "192x192", "type": "image/png", "purpose": "any" },
|
|
{ "src": "logo.png", "sizes": "512x512", "type": "image/png", "purpose": "any" },
|
|
{ "src": "logo-maskable-512.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable" }
|
|
]
|
|
}
|