diff --git a/go.mod b/go.mod index c9afc23..251bd2a 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module status-page go 1.25.4 require ( + github.com/klauspost/compress v1.18.2 github.com/pelletier/go-toml/v2 v2.2.4 modernc.org/sqlite v1.40.1 ) diff --git a/go.sum b/go.sum index 8ed8d26..d798820 100644 --- a/go.sum +++ b/go.sum @@ -4,6 +4,8 @@ github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17k github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/klauspost/compress v1.18.2 h1:iiPHWW0YrcFgpBYhsA6D1+fqHssJscY/Tm/y2Uqnapk= +github.com/klauspost/compress v1.18.2/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= diff --git a/src/http.go b/src/http.go index 5e30ca9..31b4d8d 100644 --- a/src/http.go +++ b/src/http.go @@ -1,12 +1,13 @@ package main import ( - "compress/gzip" "html/template" "log" "net/http" "strings" "time" + + "github.com/klauspost/compress/gzhttp" ) type Incident struct { @@ -92,12 +93,7 @@ func index(w http.ResponseWriter, req *http.Request) { return } - // encode response in gzip - w.Header().Set("Content-Encoding", "gzip") - gw := gzip.NewWriter(w) - defer gw.Close() - - if err := tmpl.ExecuteTemplate(gw, "index.html", data); err != nil { + if err := tmpl.ExecuteTemplate(w, "index.html", data); err != nil { log.Printf("template execute error: %v", err) renderError(w, http.StatusInternalServerError, "Internal server error") return @@ -135,12 +131,17 @@ func StartHttpServer() { } // http server - http.HandleFunc("/", index) - http.HandleFunc("/styles.css", styles) - http.HandleFunc("/favicon.ico", favicon) - http.HandleFunc("/robots.txt", robots) - http.Handle("/fonts/", http.StripPrefix("/fonts/", http.FileServer(http.Dir("www/fonts/")))) - if err := http.ListenAndServe(":8888", nil); err != nil { + mux := http.NewServeMux() + mux.HandleFunc("/", index) + mux.HandleFunc("/styles.css", styles) + mux.HandleFunc("/favicon.ico", favicon) + mux.HandleFunc("/robots.txt", robots) + mux.Handle("/fonts/", http.StripPrefix("/fonts/", http.FileServer(http.Dir("www/fonts/")))) + + // wrap with gzip middleware + handler := gzhttp.GzipHandler(mux) + + if err := http.ListenAndServe(":8888", handler); err != nil { log.Fatalf("server failed: %v", err) } } diff --git a/www/fonts/jetbrains-mono-v24-latin-regular.ttf b/www/fonts/jetbrains-mono-v24-latin-regular.ttf new file mode 100644 index 0000000..782d620 Binary files /dev/null and b/www/fonts/jetbrains-mono-v24-latin-regular.ttf differ diff --git a/www/fonts/jetbrains-mono-v24-latin-regular.woff2 b/www/fonts/jetbrains-mono-v24-latin-regular.woff2 new file mode 100644 index 0000000..5858873 Binary files /dev/null and b/www/fonts/jetbrains-mono-v24-latin-regular.woff2 differ diff --git a/www/index.html b/www/index.html index 2d8317d..3d4b830 100644 --- a/www/index.html +++ b/www/index.html @@ -16,6 +16,7 @@ display: flex; flex-direction: column; width: 100%; + height: max-content; max-width: 40rem; padding: 4rem 2rem 1.5rem; background-color: white; @@ -102,6 +103,7 @@ display: flex; flex-direction: column; gap: 2.5rem; + margin-bottom: 4rem; } .info { @@ -560,10 +562,15 @@ const hours = Math.floor(seconds / 3600); const days = Math.floor(seconds / 86400); - if (days >= 1) lastUpdatedText.textContent = `Last updated: ${days}d ago`; - if (hours >= 1) lastUpdatedText.textContent = `Last updated: ${hours}h ago`; - - lastUpdatedText.textContent = `Last updated: ${minutes}m ago`; + if (days >= 1) { + lastUpdatedText.textContent = `Last updated: ${days}d ago`; + } else if (hours >= 1) { + lastUpdatedText.textContent = `Last updated: ${hours}h ago`; + } else if (minutes >= 1) { + lastUpdatedText.textContent = `Last updated: ${minutes}m ago`; + } else { + lastUpdatedText.textContent = `Last updated: now`; + } } update(); diff --git a/www/styles.css b/www/styles.css index 9a04bd5..e52e962 100644 --- a/www/styles.css +++ b/www/styles.css @@ -43,6 +43,15 @@ src: url("/fonts/inter-v20-latin-800.woff2") format("woff2"), url("/fonts/inter-v20-latin-800.ttf") format("truetype"); } +/* jetbrains-mono-regular */ +@font-face { + font-display: swap; + font-family: "JetBrains Mono"; + font-style: normal; + font-weight: 400; + src: url("/fonts/jetbrains-mono-v24-latin-regular.woff2") format("woff2"), url("/fonts/jetbrains-mono-v24-latin-regular.ttf") format("truetype"); +} + /* jetbrains-mono-600 */ @font-face { font-display: swap;