From bd6038720b8a576c156314121ed2c379f0649fae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maxi=20Quo=C3=9F?= Date: Mon, 15 Sep 2025 22:21:00 +0200 Subject: [PATCH] fix: generate manifest in go backend --- backend/pb/handlers.go | 84 ++++++++++++++++++++++++++++++ backend/pb/pb.go | 1 + frontend/src/app.html | 1 - frontend/src/routes/+layout.svelte | 1 + 4 files changed, 86 insertions(+), 1 deletion(-) diff --git a/backend/pb/handlers.go b/backend/pb/handlers.go index a85ca9c7..b1059c53 100644 --- a/backend/pb/handlers.go +++ b/backend/pb/handlers.go @@ -1,7 +1,9 @@ package pb import ( + "encoding/json" "encoding/xml" + "fmt" "net" "net/http" "os" @@ -381,3 +383,85 @@ func asyncCall(e *core.RequestEvent, fn func() *router.ApiError) *router.ApiErro return nil } + +func HandlerWebsiteManifest(e *core.RequestEvent) error { + scheme := "http" + if e.Request.TLS != nil { + scheme = "https" + } + baseUrl := fmt.Sprintf("%s://%s", scheme, e.Request.Host) + + manifest := map[string]any{ + "name": "UpSnap", + "short_name": "UpSnap", + "description": "A simple wake on lan web app written with SvelteKit, Go and PocketBase.", + "theme_color": "#55BCD9", + "background_color": "#55BCD9", + "display": "standalone", + "scope": baseUrl, + "start_url": baseUrl, + "icons": []map[string]string{ + { + "src": "/icon_192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "any", + }, + { + "src": "/icon_512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "any", + }, + { + "src": "/maskable_192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable", + }, + { + "src": "/maskable_512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable", + }, + { + "src": "/gopher.svg", + "sizes": "any", + "type": "image/svg+xml", + }, + }, + } + + publicSettings, err := e.App.FindFirstRecordByFilter("settings_public", "") + if err != nil { + return writeManifest(e, manifest) + } + + // override title if set + if title := publicSettings.GetString("website_title"); title != "" { + manifest["name"] = title + manifest["short_name"] = title + } + + // override icons if set + if favicon := publicSettings.GetString("favicon"); favicon != "" { + + manifest["icons"] = []map[string]string{ + { + "src": fmt.Sprintf("%s/api/files/settings_public/%s/%s", baseUrl, publicSettings.Id, favicon), + "sizes": "any", + "purpose": "any", + }, + } + } + + return writeManifest(e, manifest) +} + +func writeManifest(e *core.RequestEvent, manifest map[string]any) error { + e.Response.Header().Set("Content-Type", "application/manifest+json") + e.Response.Header().Set("Cache-Control", "no-cache, no-store") + enc := json.NewEncoder(e.Response) + return enc.Encode(manifest) +} diff --git a/backend/pb/pb.go b/backend/pb/pb.go index 6c59c2c4..b2021ed8 100644 --- a/backend/pb/pb.go +++ b/backend/pb/pb.go @@ -78,6 +78,7 @@ func StartPocketBase(distDirFS fs.FS) { se.Router.GET("/api/upsnap/scan", HandlerScan).Bind(apis.RequireSuperuserAuth()) se.Router.POST("/api/upsnap/init-superuser", HandlerInitSuperuser) // https://github.com/pocketbase/pocketbase/discussions/6198 se.Router.POST("/api/upsnap/validate-cron", HandlerValidateCron) + se.Router.GET("/api/upsnap/manifest.webmanifest", HandlerWebsiteManifest) if err := importSettings(app); err != nil { return err diff --git a/frontend/src/app.html b/frontend/src/app.html index 31b120e6..26ff9b90 100644 --- a/frontend/src/app.html +++ b/frontend/src/app.html @@ -3,7 +3,6 @@ - %sveltekit.head% +