feat(ui): Allow configuring default dark-mode value (#1015)
* fix: theme flickering * chore(ui): added dark mode tests * feat(ui): Expose new ui.dark-mode parameter to set default theme * refactor(ui): Rename theme variable to themeFromCookie for clarity --------- Co-authored-by: TwiN <twin@linux.com> Co-authored-by: TwiN <chris@twin.sh>
This commit is contained in:
15
api/spa.go
15
api/spa.go
@ -10,8 +10,19 @@ import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func SinglePageApplication(ui *ui.Config) fiber.Handler {
|
||||
func SinglePageApplication(uiConfig *ui.Config) fiber.Handler {
|
||||
return func(c *fiber.Ctx) error {
|
||||
vd := ui.ViewData{UI: uiConfig}
|
||||
{
|
||||
themeFromCookie := string(c.Request().Header.Cookie("theme"))
|
||||
if len(themeFromCookie) > 0 {
|
||||
if themeFromCookie == "dark" {
|
||||
vd.Theme = "dark"
|
||||
}
|
||||
} else if uiConfig.IsDarkMode() { // Since there's no theme cookie, we'll rely on ui.DarkMode
|
||||
vd.Theme = "dark"
|
||||
}
|
||||
}
|
||||
t, err := template.ParseFS(static.FileSystem, static.IndexPath)
|
||||
if err != nil {
|
||||
// This should never happen, because ui.ValidateAndSetDefaults validates that the template works.
|
||||
@ -19,7 +30,7 @@ func SinglePageApplication(ui *ui.Config) fiber.Handler {
|
||||
return c.Status(500).SendString("Failed to parse template. This should never happen, because the template is validated on start.")
|
||||
}
|
||||
c.Set("Content-Type", "text/html")
|
||||
err = t.Execute(c, ui)
|
||||
err = t.Execute(c, vd)
|
||||
if err != nil {
|
||||
// This should never happen, because ui.ValidateAndSetDefaults validates that the template works.
|
||||
logr.Errorf("[api.SinglePageApplication] Failed to execute template. This should never happen, because the template is validated on start. Error: %s", err.Error())
|
||||
|
@ -39,29 +39,50 @@ func TestSinglePageApplication(t *testing.T) {
|
||||
api := New(cfg)
|
||||
router := api.Router()
|
||||
type Scenario struct {
|
||||
Name string
|
||||
Path string
|
||||
ExpectedCode int
|
||||
Gzip bool
|
||||
Name string
|
||||
Path string
|
||||
Gzip bool
|
||||
CookieDarkMode bool
|
||||
UIDarkMode bool
|
||||
ExpectedCode int
|
||||
ExpectedDarkTheme bool
|
||||
}
|
||||
scenarios := []Scenario{
|
||||
{
|
||||
Name: "frontend-home",
|
||||
Path: "/",
|
||||
ExpectedCode: 200,
|
||||
Name: "frontend-home",
|
||||
Path: "/",
|
||||
CookieDarkMode: true,
|
||||
UIDarkMode: false,
|
||||
ExpectedDarkTheme: true,
|
||||
ExpectedCode: 200,
|
||||
},
|
||||
{
|
||||
Name: "frontend-endpoint",
|
||||
Path: "/endpoints/core_frontend",
|
||||
ExpectedCode: 200,
|
||||
Name: "frontend-endpoint-light",
|
||||
Path: "/endpoints/core_frontend",
|
||||
CookieDarkMode: false,
|
||||
UIDarkMode: false,
|
||||
ExpectedDarkTheme: false,
|
||||
ExpectedCode: 200,
|
||||
},
|
||||
{
|
||||
Name: "frontend-endpoint-dark",
|
||||
Path: "/endpoints/core_frontend",
|
||||
CookieDarkMode: false,
|
||||
UIDarkMode: true,
|
||||
ExpectedDarkTheme: true,
|
||||
ExpectedCode: 200,
|
||||
},
|
||||
}
|
||||
for _, scenario := range scenarios {
|
||||
t.Run(scenario.Name, func(t *testing.T) {
|
||||
cfg.UI.DarkMode = &scenario.UIDarkMode
|
||||
request := httptest.NewRequest("GET", scenario.Path, http.NoBody)
|
||||
if scenario.Gzip {
|
||||
request.Header.Set("Accept-Encoding", "gzip")
|
||||
}
|
||||
if scenario.CookieDarkMode {
|
||||
request.Header.Set("Cookie", "theme=dark")
|
||||
}
|
||||
response, err := router.Test(request)
|
||||
if err != nil {
|
||||
return
|
||||
@ -71,9 +92,16 @@ func TestSinglePageApplication(t *testing.T) {
|
||||
t.Errorf("%s %s should have returned %d, but returned %d instead", request.Method, request.URL, scenario.ExpectedCode, response.StatusCode)
|
||||
}
|
||||
body, _ := io.ReadAll(response.Body)
|
||||
if !strings.Contains(string(body), cfg.UI.Title) {
|
||||
strBody := string(body)
|
||||
if !strings.Contains(strBody, cfg.UI.Title) {
|
||||
t.Errorf("%s %s should have contained the title", request.Method, request.URL)
|
||||
}
|
||||
if scenario.ExpectedDarkTheme && !strings.Contains(strBody, "class=\"dark\"") {
|
||||
t.Errorf("%s %s should have responded with dark mode headers", request.Method, request.URL)
|
||||
}
|
||||
if !scenario.ExpectedDarkTheme && strings.Contains(strBody, "class=\"dark\"") {
|
||||
t.Errorf("%s %s should not have responded with dark mode headers", request.Method, request.URL)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user