Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions api/web.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,17 @@ var webOverlayHTML []byte
//go:embed web/favicon.svg
var webFaviconSVG []byte

// PWA manifest + icons: lets browsers install the web UI as a standalone
// app (fullscreen from a home-screen icon on phones/tablets, its own window
// on desktop). No service worker on purpose — the UI is meaningless without
// the live server, so offline caching would only mislead.
//
//go:embed web/manifest.json
var webManifestJSON []byte

//go:embed web/icon-192.png web/icon-512.png
var webIconsFS embed.FS

// webFontsFS holds the self-hosted woff2 fonts (Geist Mono + VT323), served at
// /fonts/. Bundled into the binary so the UI needs no external font CDN —
// important since it usually runs offline on the CDJ link-local network.
Expand Down Expand Up @@ -45,6 +56,21 @@ func RegisterWebUI(mux *http.ServeMux) {
w.Write(webOverlayHTML)
})

mux.HandleFunc("/manifest.json", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/manifest+json")
w.Header().Set("Cache-Control", "public, max-age=86400")
w.Write(webManifestJSON)
})
for _, name := range []string{"icon-192.png", "icon-512.png"} {
name := name
mux.HandleFunc("/"+name, func(w http.ResponseWriter, r *http.Request) {
data, _ := webIconsFS.ReadFile("web/" + name)
w.Header().Set("Content-Type", "image/png")
w.Header().Set("Cache-Control", "public, max-age=86400")
w.Write(data)
})
}

// App icon (vinyl + the null ∅), used as the browser-tab favicon.
mux.HandleFunc("/favicon.svg", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "image/svg+xml")
Expand Down
Binary file added api/web/icon-192.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added api/web/icon-512.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions api/web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
<link rel="manifest" href="/manifest.json">
<meta name="theme-color" content="#0c0c0f">
<link rel="apple-touch-icon" href="/icon-192.png">
<title>Vynull · DJ LINK</title>
<style>
/* Self-hosted fonts (no external CDN — works offline on the link-local net). */
Expand Down
13 changes: 13 additions & 0 deletions api/web/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "Vynull",
"short_name": "Vynull",
"description": "DJ library manager — browse, edit, and serve your library to CDJs over Pro DJ Link.",
"start_url": "/",
"display": "standalone",
"background_color": "#0c0c0f",
"theme_color": "#0c0c0f",
"icons": [
{ "src": "/icon-192.png", "sizes": "192x192", "type": "image/png" },
{ "src": "/icon-512.png", "sizes": "512x512", "type": "image/png" }
]
}
Loading