fix(ui): allow DefaultTheme "Auto" from config (#5190)

* fix(ui): allow DefaultTheme "Auto" from config

When DefaultTheme is set to "Auto" in the server config, the
defaultTheme() function in themeReducer now returns AUTO_THEME_ID
instead of falling through to the DarkTheme fallback.

This allows useCurrentTheme to correctly read prefers-color-scheme
and select Light or Dark theme automatically for new/incognito users.

Adds themeReducer unit tests covering Auto, named-theme, and
unrecognized-value fallback paths.

* chore: format

Signed-off-by: Deluan <deluan@navidrome.org>

---------

Signed-off-by: Deluan <deluan@navidrome.org>
Co-authored-by: Deluan <deluan@navidrome.org>
This commit is contained in:
Tom Boucher
2026-03-15 14:00:21 -04:00
committed by GitHub
parent a887521d7a
commit c42570446b
3 changed files with 38 additions and 0 deletions
+2
View File
@@ -7,6 +7,8 @@ export const M3U_MIME_TYPE = 'audio/x-mpegurl'
export const AUTO_THEME_ID = 'AUTO_THEME_ID' export const AUTO_THEME_ID = 'AUTO_THEME_ID'
export const AUTO_THEME_CONFIG_VALUE = 'Auto'
export const DraggableTypes = { export const DraggableTypes = {
SONG: 'song', SONG: 'song',
ALBUM: 'album', ALBUM: 'album',
+4
View File
@@ -1,8 +1,12 @@
import { CHANGE_THEME } from '../actions' import { CHANGE_THEME } from '../actions'
import { AUTO_THEME_ID, AUTO_THEME_CONFIG_VALUE } from '../consts'
import config from '../config' import config from '../config'
import themes from '../themes' import themes from '../themes'
const defaultTheme = () => { const defaultTheme = () => {
if (config.defaultTheme === AUTO_THEME_CONFIG_VALUE) {
return AUTO_THEME_ID
}
return ( return (
Object.keys(themes).find( Object.keys(themes).find(
(t) => themes[t].themeName === config.defaultTheme, (t) => themes[t].themeName === config.defaultTheme,
+32
View File
@@ -0,0 +1,32 @@
import { describe, it, expect, vi, beforeEach } from 'vitest'
import { AUTO_THEME_ID, AUTO_THEME_CONFIG_VALUE } from '../consts'
describe('themeReducer', () => {
beforeEach(() => {
vi.resetModules()
})
it.each([
{
configTheme: AUTO_THEME_CONFIG_VALUE,
expected: AUTO_THEME_ID,
description: 'is "Auto"',
},
{ configTheme: 'Dark', expected: 'DarkTheme', description: 'is "Dark"' },
{
configTheme: 'NonExistent',
expected: 'DarkTheme',
description: 'is unrecognized',
},
])(
'returns $expected when defaultTheme config $description',
async ({ configTheme, expected }) => {
vi.doMock('../config', () => ({
default: { defaultTheme: configTheme },
}))
const { themeReducer } = await import('./themeReducer')
const result = themeReducer(undefined, { type: 'UNKNOWN' })
expect(result).toBe(expected)
},
)
})