oficina / estilo Public

Clone
git clone https://amadan.net/oficina/estilo

Plain git — no account needed to clone.

Download

Download this file

1// Package brand serves the suite's app icons from Go, so a page can link
2// any sibling app's icon (the app switcher) without vendoring the file.
3// The artwork itself is brand/svg/, generated by generate.mjs; see README.md.
4package brand
5
6import (
7 "embed"
8 "net/http"
9 "strings"
10)
11
12//go:embed svg/*.svg
13var svgFS embed.FS
14
15// Prefix is the URL path Handler serves under.
16const Prefix = "/static/estilo/brand/"
17
18// files maps a public slug to its master. "meet" is Calls' name before
19// the rename, kept so a page still linking it gets the right icon.
20var files = map[string]string{
21 "oficina": "oficina.svg",
22 "docs": "docs.svg",
23 "sheets": "sheets.svg",
24 "slides": "slides.svg",
25 "calendar": "calendar.svg",
26 "calls": "calls.svg",
27 "meet": "calls.svg",
28 "memoria": "memoria.svg",
29 "fichas": "fichas.svg",
30 "mail": "mail.svg",
31 "files": "files.svg",
32}
33
34// SVG returns the icon for slug, or nil for an unknown slug.
35func SVG(slug string) []byte {
36 name, ok := files[slug]
37 if !ok {
38 return nil
39 }
40 body, err := svgFS.ReadFile("svg/" + name)
41 if err != nil {
42 return nil
43 }
44 return body
45}
46
47// Path is the URL Handler serves slug's icon at.
48func Path(slug string) string { return Prefix + slug + ".svg" }
49
50// Handler serves GET and HEAD for Prefix + "<slug>.svg". Mount it at
51// Prefix. Anything else is 404; the icons are public artwork and need no
52// session.
53func Handler() http.Handler {
54 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
55 slug, ok := strings.CutSuffix(strings.TrimPrefix(r.URL.Path, Prefix), ".svg")
56 body := SVG(slug)
57 if !ok || body == nil || !strings.HasPrefix(r.URL.Path, Prefix) {
58 http.NotFound(w, r)
59 return
60 }
61 if r.Method != http.MethodGet && r.Method != http.MethodHead {
62 w.Header().Set("Allow", "GET, HEAD")
63 http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
64 return
65 }
66 w.Header().Set("Content-Type", "image/svg+xml")
67 w.Header().Set("Cache-Control", "public, max-age=86400")
68 w.Header().Set("X-Content-Type-Options", "nosniff")
69 if r.Method == http.MethodHead {
70 return
71 }
72 _, _ = w.Write(body)
73 })
74}
75