From d8ff52e55bf2f1595a5dc73ea43e83b1853266b0 Mon Sep 17 00:00:00 2001 From: Philip Allgaier Date: Tue, 25 May 2021 13:26:24 +0200 Subject: [PATCH] Add support for custom themes to use dark mode (#46532) --- homeassistant/components/frontend/__init__.py | 34 +++++++++++++++++-- tests/components/frontend/test_init.py | 28 +++++++++++++++ 2 files changed, 59 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/frontend/__init__.py b/homeassistant/components/frontend/__init__.py index ed339b9dc8b..1b104982026 100644 --- a/homeassistant/components/frontend/__init__.py +++ b/homeassistant/components/frontend/__init__.py @@ -36,6 +36,9 @@ mimetypes.add_type("application/javascript", ".js") DOMAIN = "frontend" CONF_THEMES = "themes" +CONF_THEMES_MODES = "modes" +CONF_THEMES_LIGHT = "light" +CONF_THEMES_DARK = "dark" CONF_EXTRA_HTML_URL = "extra_html_url" CONF_EXTRA_HTML_URL_ES5 = "extra_html_url_es5" CONF_EXTRA_MODULE_URL = "extra_module_url" @@ -66,14 +69,39 @@ PRIMARY_COLOR = "primary-color" _LOGGER = logging.getLogger(__name__) +EXTENDED_THEME_SCHEMA = vol.Schema( + { + # Theme variables that apply to all modes + cv.string: cv.string, + # Mode specific theme variables + vol.Optional(CONF_THEMES_MODES): vol.Schema( + { + vol.Optional(CONF_THEMES_LIGHT): vol.Schema({cv.string: cv.string}), + vol.Optional(CONF_THEMES_DARK): vol.Schema({cv.string: cv.string}), + } + ), + } +) + +THEME_SCHEMA = vol.Schema( + { + cv.string: ( + vol.Any( + # Legacy theme scheme + {cv.string: cv.string}, + # New extended schema with mode support + EXTENDED_THEME_SCHEMA, + ) + ) + } +) + CONFIG_SCHEMA = vol.Schema( { DOMAIN: vol.Schema( { vol.Optional(CONF_FRONTEND_REPO): cv.isdir, - vol.Optional(CONF_THEMES): vol.Schema( - {cv.string: {cv.string: cv.string}} - ), + vol.Optional(CONF_THEMES): THEME_SCHEMA, vol.Optional(CONF_EXTRA_MODULE_URL): vol.All( cv.ensure_list, [cv.string] ), diff --git a/tests/components/frontend/test_init.py b/tests/components/frontend/test_init.py index fe624452475..9746fc6d838 100644 --- a/tests/components/frontend/test_init.py +++ b/tests/components/frontend/test_init.py @@ -26,6 +26,25 @@ from tests.common import async_capture_events, async_fire_time_changed MOCK_THEMES = { "happy": {"primary-color": "red", "app-header-background-color": "blue"}, "dark": {"primary-color": "black"}, + "light_only": { + "primary-color": "blue", + "modes": { + "light": {"secondary-color": "black"}, + }, + }, + "dark_only": { + "primary-color": "blue", + "modes": { + "dark": {"secondary-color": "white"}, + }, + }, + "light_and_dark": { + "primary-color": "blue", + "modes": { + "light": {"secondary-color": "black"}, + "dark": {"secondary-color": "white"}, + }, + }, } CONFIG_THEMES = {DOMAIN: {CONF_THEMES: MOCK_THEMES}} @@ -279,6 +298,15 @@ async def test_themes_set_dark_theme(hass, themes_ws_client): assert msg["result"]["default_dark_theme"] is None + await hass.services.async_call( + DOMAIN, "set_theme", {"name": "light_and_dark", "mode": "dark"}, blocking=True + ) + + await themes_ws_client.send_json({"id": 8, "type": "frontend/get_themes"}) + msg = await themes_ws_client.receive_json() + + assert msg["result"]["default_dark_theme"] == "light_and_dark" + async def test_themes_set_dark_theme_wrong_name(hass, frontend, themes_ws_client): """Test frontend.set_theme service called with mode dark and wrong name."""