Make the app an installable PWA with phone layout and Web Push

Add a generated manifest, icon set, offline page and service worker that never caches authenticated HTML, plus install and update UI. Turn the rail into a drawer below md with container-query internals, dvh and safe-area handling, and reconnect the socket after visibility/network changes. Add Web Push subscriptions, presence-aware delivery, notification settings and tests.
This commit is contained in:
2026-10-19 17:12:16 +01:00
parent 61098a114c
commit dbfe48796b
100 changed files with 3573 additions and 117 deletions
+36
View File
@@ -0,0 +1,36 @@
import { z } from "zod";
const PushEndpointField = z
.string()
.trim()
.min(1, "Missing the device's push endpoint")
.max(2048, "That push endpoint is too long")
.refine(
(value) => value.startsWith("https://"),
"A push endpoint must use https",
);
export const SavePushSubscriptionSchema = z.object({
endpoint: PushEndpointField,
keys: z.object({
p256dh: z.string().trim().min(1).max(200),
auth: z.string().trim().min(1).max(100),
}),
/**
* Sent by the browser, only to label the device in Settings.
*/
user_agent: z.string().max(400).optional(),
platform: z.string().max(100).optional(),
});
export type SavePushSubscriptionRequest = z.infer<
typeof SavePushSubscriptionSchema
>;
export const PushEndpointRequestSchema = z.object({
endpoint: PushEndpointField,
});
export const PushSubscriptionIdRequestSchema = z.object({
id: z.coerce.number().int().positive("Pick a device"),
});