From f63a912341c646bcdb97b35aa32ada8bc1db67cd Mon Sep 17 00:00:00 2001
From: Deluan <deluan@navidrome.org>
Date: Sun, 18 Apr 2021 13:51:00 -0400
Subject: [PATCH] Add config option to set default theme

---
 conf/configuration.go            |  2 ++
 server/app/serve_index.go        |  5 +++--
 server/app/serve_index_test.go   | 11 +++++++++++
 ui/src/config.js                 |  1 +
 ui/src/reducers/themeReducer.js  | 12 +++++++++++-
 ui/src/themes/useCurrentTheme.js |  9 ++++++++-
 6 files changed, 36 insertions(+), 4 deletions(-)

diff --git a/conf/configuration.go b/conf/configuration.go
index 9293c6f4a..92bf51962 100644
--- a/conf/configuration.go
+++ b/conf/configuration.go
@@ -42,6 +42,7 @@ type configOptions struct {
 	EnableGravatar         bool
 	EnableFavourites       bool
 	EnableStarRating       bool
+	DefaultTheme           string
 	GATrackingID           string
 	AuthRequestLimit       int
 	AuthWindowLength       time.Duration
@@ -147,6 +148,7 @@ func init() {
 	viper.SetDefault("enablegravatar", false)
 	viper.SetDefault("enablefavourites", true)
 	viper.SetDefault("enablestarrating", true)
+	viper.SetDefault("defaulttheme", "Dark")
 	viper.SetDefault("gatrackingid", "")
 	viper.SetDefault("authrequestlimit", 5)
 	viper.SetDefault("authwindowlength", 20*time.Second)
diff --git a/server/app/serve_index.go b/server/app/serve_index.go
index b0dd08c81..2f48f567e 100644
--- a/server/app/serve_index.go
+++ b/server/app/serve_index.go
@@ -40,11 +40,12 @@ func serveIndex(ds model.DataStore, fs fs.FS) http.HandlerFunc {
 			"loginBackgroundURL":      policy.Sanitize(conf.Server.UILoginBackgroundURL),
 			"welcomeMessage":          policy.Sanitize(conf.Server.UIWelcomeMessage),
 			"enableTranscodingConfig": conf.Server.EnableTranscodingConfig,
-			"gaTrackingId":            conf.Server.GATrackingID,
 			"enableDownloads":         conf.Server.EnableDownloads,
 			"enableFavourites":        conf.Server.EnableFavourites,
-			"losslessFormats":         strings.ToUpper(strings.Join(consts.LosslessFormats, ",")),
 			"enableStarRating":        conf.Server.EnableStarRating,
+			"defaultTheme":            conf.Server.DefaultTheme,
+			"gaTrackingId":            conf.Server.GATrackingID,
+			"losslessFormats":         strings.ToUpper(strings.Join(consts.LosslessFormats, ",")),
 			"devActivityPanel":        conf.Server.DevActivityPanel,
 			"devFastAccessCoverArt":   conf.Server.DevFastAccessCoverArt,
 		}
diff --git a/server/app/serve_index_test.go b/server/app/serve_index_test.go
index eae43cfd3..180cc4cdd 100644
--- a/server/app/serve_index_test.go
+++ b/server/app/serve_index_test.go
@@ -147,6 +147,17 @@ var _ = Describe("serveIndex", func() {
 		Expect(config).To(HaveKeyWithValue("enableStarRating", true))
 	})
 
+	It("sets the defaultTheme", func() {
+		conf.Server.DefaultTheme = "Light"
+		r := httptest.NewRequest("GET", "/index.html", nil)
+		w := httptest.NewRecorder()
+
+		serveIndex(ds, fs)(w, r)
+
+		config := extractAppConfig(w.Body.String())
+		Expect(config).To(HaveKeyWithValue("defaultTheme", "Light"))
+	})
+
 	It("sets the gaTrackingId", func() {
 		conf.Server.GATrackingID = "UA-12345"
 		r := httptest.NewRequest("GET", "/index.html", nil)
diff --git a/ui/src/config.js b/ui/src/config.js
index fcc491e8e..8f9a218a4 100644
--- a/ui/src/config.js
+++ b/ui/src/config.js
@@ -16,6 +16,7 @@ const defaultConfig = {
   devActivityPanel: true,
   devFastAccessCoverArt: false,
   enableStarRating: true,
+  defaultTheme: 'Dark',
 }
 
 let config
diff --git a/ui/src/reducers/themeReducer.js b/ui/src/reducers/themeReducer.js
index 2ca36b993..ef5ccc7ce 100644
--- a/ui/src/reducers/themeReducer.js
+++ b/ui/src/reducers/themeReducer.js
@@ -1,7 +1,17 @@
 import { CHANGE_THEME } from '../actions'
+import config from '../config'
+import themes from '../themes'
+
+const defaultTheme = () => {
+  return (
+    Object.keys(themes).find(
+      (t) => themes[t].themeName === config.defaultTheme
+    ) || 'DarkTheme'
+  )
+}
 
 export const themeReducer = (
-  previousState = 'DarkTheme',
+  previousState = defaultTheme(),
   { type, payload }
 ) => {
   if (type === CHANGE_THEME) {
diff --git a/ui/src/themes/useCurrentTheme.js b/ui/src/themes/useCurrentTheme.js
index e25cfd1fd..f38db96c6 100644
--- a/ui/src/themes/useCurrentTheme.js
+++ b/ui/src/themes/useCurrentTheme.js
@@ -2,6 +2,7 @@ import { useSelector } from 'react-redux'
 import useMediaQuery from '@material-ui/core/useMediaQuery'
 import themes from './index'
 import { AUTO_THEME_ID } from '../consts'
+import config from '../config'
 
 export default () => {
   const prefersLightMode = useMediaQuery('(prefers-color-scheme: light)')
@@ -9,6 +10,12 @@ export default () => {
     if (state.theme === AUTO_THEME_ID) {
       return prefersLightMode ? themes.LightTheme : themes.DarkTheme
     }
-    return themes[state.theme] || themes.DarkTheme
+    const themeName =
+      state.theme ||
+      Object.keys(themes).find(
+        (t) => themes[t].themeName === config.defaultTheme
+      ) ||
+      'DarkTheme'
+    return themes[themeName]
   })
 }