diff options
-rw-r--r-- | main.go | 6 | ||||
-rw-r--r-- | middleware/pipe.go | 14 | ||||
-rw-r--r-- | middleware/theme.go | 42 | ||||
-rw-r--r-- | templates/navbar.templ | 3 | ||||
-rw-r--r-- | templates/root.templ | 2 |
5 files changed, 63 insertions, 4 deletions
@@ -32,7 +32,11 @@ func main() { mux := http.NewServeMux() mux.Handle("GET /favicon.ico", fs) mux.Handle("GET /style.css", fs) - mux.Handle("GET /", middleware.I18n(http.HandlerFunc(finalHandler))) + mux.Handle("GET /", middleware.Pipe( + middleware.I18n, + middleware.Theme, + )(http.HandlerFunc(finalHandler))) + mux.Handle("POST /language", http.HandlerFunc(setUserLanguage)) portStr := ":" + strconv.Itoa(*port) diff --git a/middleware/pipe.go b/middleware/pipe.go new file mode 100644 index 0000000..4b5064d --- /dev/null +++ b/middleware/pipe.go @@ -0,0 +1,14 @@ +package middleware + +import "net/http" + +type Middleware func(http.Handler) http.Handler + +func Pipe(xs ...Middleware) Middleware { + return func(next http.Handler) http.Handler { + for i := len(xs) - 1; i >= 0; i-- { + next = xs[i](next) + } + return next + } +} diff --git a/middleware/theme.go b/middleware/theme.go new file mode 100644 index 0000000..4f14c97 --- /dev/null +++ b/middleware/theme.go @@ -0,0 +1,42 @@ +package middleware + +import ( + "cmp" + "context" + "math" + "net/http" +) + +const defaultTheme = "dark" + +func Theme(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + var userTheme string + + /* Grab the ‘theme’ cookie to figure out what the users current + theme is and add it to the context. If the user doesn’t yet + have a theme cookie or the cookie they have contains an + invalid theme then we fallback to the default theme and + (re)set the cookie. */ + + c, err := r.Cookie("theme") + if err == nil { + switch c.Value { + case "dark", "light": + userTheme = c.Value + } + } + + theme := cmp.Or(userTheme, defaultTheme) + if userTheme == "" { + http.SetCookie(w, &http.Cookie{ + Name: "theme", + Value: theme, + MaxAge: math.MaxInt32, + }) + } + + ctx := context.WithValue(r.Context(), "theme", theme) + next.ServeHTTP(w, r.WithContext(ctx)) + }) +} diff --git a/templates/navbar.templ b/templates/navbar.templ index 5007183..f0d654c 100644 --- a/templates/navbar.templ +++ b/templates/navbar.templ @@ -77,8 +77,7 @@ templ navbar() { fill="none" xmlns="http://www.w3.org/2000/svg" > - <!-- TODO: if theme == dark --> - if true { + if ctx.Value("theme").(string) == "dark" { <path d="M 7.28451 10.3333 C 7.10026 10.8546 diff --git a/templates/root.templ b/templates/root.templ index da63caa..832846e 100644 --- a/templates/root.templ +++ b/templates/root.templ @@ -10,7 +10,7 @@ templ Root(head, body templ.Component) { {{ p := ctx.Value("printer").(i18n.Printer) }} <!DOCTYPE html> - <html lang={ p.Locale.Code } data-theme="dark"> + <html lang={ p.Locale.Code } data-theme={ ctx.Value("theme").(string) }> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> |