diff --git a/README.md b/README.md index 6aa0a8a..6ead2e9 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,22 @@ Change the gui page title, favicon and app icons of your Home Assistant instance - Put your icons in e.g. `/www/favicons/` +## Method 1/2 Integration + +- Go to your Home Assistant configuration and to Integrations + +- Add a "Favicon" integration + +- Enter what you want the title of the Home Assistant interface page to be, and the URL of the icons you wish to change. E.g. `favicon URL: /local/favicons/favicon.ico`, `iOS icon URL: /local/favicons/180x180.png`. + +- Press submit + +- Refresh the page + +![integration](https://user-images.githubusercontent.com/1299821/63462280-d91a7000-c45a-11e9-97af-52f0335cad66.gif) + +## Method 2/2 YAML configuration + - Add the following to your `configuration.yaml`: ```yaml @@ -24,15 +40,13 @@ favicon: title: My Home favicon: /local/favicons/favicon.ico apple: /local/favicons/apple-touch-icon-180x180.png - 32: /local/favicons/favicon-32x32.png - 512: /local/favicons/android-chrome-512x512.png ``` - Restart Home Assistant - Make sure to clear the cache of your browser to get the new icons. -# Options +### Options - `title` - The title to display at the top of the window or browser tab. @@ -40,11 +54,6 @@ favicon: - `apple` - a 180 x 180 px image that will be displayed on your iDevice home screen if you save the link there -- `` - a `` x `` px image that will be displayed wherever it's needed for non-apple devices. - -You can add as few or as many of those you'd like. It's my understanding that the next smaller size will be used if one is requested which doesn't quite fit the need. - -For reference, Home Assistant includes icons of sizes 192, 384, 512 and 1024 px square by default. Specifying even a single size will override all of those. ![it IS charging thankyouverymuch](https://user-images.githubusercontent.com/1299821/62975899-c29d6480-be1b-11e9-9b6b-9d160ef8b439.jpg) diff --git a/custom_components/favicon/.translations/en.json b/custom_components/favicon/.translations/en.json new file mode 100644 index 0000000..6c8d14b --- /dev/null +++ b/custom_components/favicon/.translations/en.json @@ -0,0 +1,30 @@ +{ + "config": { + "title": "Favicon", + "step": { + "config": { + "title": "Favicon changer", + "description": "Set the page title, favicon and/or iOS icons", + "data": { + "title": "Page title", + "favicon": "favicon URL", + "apple": "iOS icon URL" + } + } + }, + "abort": { + "single_instance_allowed": "Only a single configuration of favicon is allowed." + } + }, + "options": { + "step": { + "init": { + "data": { + "title": "Page title", + "favicon": "favicon URL", + "apple": "iOS icon URL" + } + } + } + } +} diff --git a/custom_components/favicon/__init__.py b/custom_components/favicon/__init__.py index d5ac4a4..573e6d3 100644 --- a/custom_components/favicon/__init__.py +++ b/custom_components/favicon/__init__.py @@ -1,4 +1,5 @@ import logging +from collections import defaultdict import homeassistant.components.frontend from homeassistant.components.frontend import _frontend_root @@ -8,46 +9,56 @@ _LOGGER = logging.getLogger(__name__) DOMAIN = "favicon" async def async_setup(hass, config): + if not hass.data.get(DOMAIN): + hass.data[DOMAIN] = defaultdict(int) - favicon = config[DOMAIN].get('favicon') - apple = config[DOMAIN].get('apple') - title = config[DOMAIN].get('title') + if not hass.data[DOMAIN].get("get_template"): + hass.data[DOMAIN]["get_template"] = homeassistant.components.frontend.IndexView.get_template - if favicon or apple or title: - get_template = homeassistant.components.frontend.IndexView.get_template + conf = config.get(DOMAIN) + if not conf: + return True + hass.data[DOMAIN].update(conf) + return apply_hooks(hass) - def new_get_template(self): - tpl = get_template(self) - render = tpl.render - def new_render(*args, **kwargs): - text = render(*args, **kwargs) - if favicon: - text = text.replace("/static/icons/favicon.ico", favicon) - if apple: - text = text.replace("/static/icons/favicon-apple-180x180.png", apple) - if title: - text = text.replace("Home Assistant", f"{title}") - return text - tpl.render = new_render - return tpl +async def async_setup_entry(hass, config_entry): + config_entry.add_update_listener(_update_listener) + config_entry.options = config_entry.data + return await _update_listener(hass, config_entry) - homeassistant.components.frontend.IndexView.get_template = new_get_template +async def async_remove_entry(hass, config_entry): + return remove_hooks(hass) - icons = [] - for size in config[DOMAIN]: - if not isinstance(size, int): - continue - i = config[DOMAIN].get(size) - if i: - icons.append({ - "src": i, - "sizes": f"{size}x{size}", - "type": "image/png", - }) +async def _update_listener(hass, config_entry): + conf = config_entry.options + hass.data[DOMAIN].update(conf) + return apply_hooks(hass) - if icons: - homeassistant.components.frontend.MANIFEST_JSON["icons"] = icons +def apply_hooks(hass): + data = hass.data[DOMAIN] + def _get_template(self): + tpl = data["get_template"](self) + render = tpl.render + + def new_render(*args, **kwargs): + text = render(*args, **kwargs) + if data["favicon"]: + text = text.replace("/static/icons/favicon.ico", data["favicon"]) + if data["apple"]: + text = text.replace("/static/icons/favicon-apple-180x180.png", data["apple"]) + if data["title"]: + text = text.replace("Home Assistant", f"{data['title']}") + return text + + tpl.render = new_render + return tpl + + homeassistant.components.frontend.IndexView.get_template = _get_template return True +def remove_hooks(hass): + data = hass.data[DOMAIN] + homeassistant.components.frontend.IndexView.get_template = data["get_template"] + return True diff --git a/custom_components/favicon/config_flow.py b/custom_components/favicon/config_flow.py new file mode 100644 index 0000000..deec8c8 --- /dev/null +++ b/custom_components/favicon/config_flow.py @@ -0,0 +1,55 @@ +import voluptuous as vol + +from homeassistant import config_entries +from homeassistant.core import callback + +@config_entries.HANDLERS.register("favicon") +class ExampleConfigFlow(config_entries.ConfigFlow): + async def async_step_user(self, user_input=None): + if self._async_current_entries(): + return self.async_abort(reason="single_instance_allowed") + return await self.async_step_config() + + async def async_step_config(self, user_input=None): + if user_input is not None: + return self.async_create_entry( + title="", data=user_input) + + return self.async_show_form( + step_id='config', + data_schema=vol.Schema( + { + vol.Optional('title'): str, + vol.Optional('favicon'): str, + vol.Optional('apple'): str, + } + ), + ) + + @staticmethod + @callback + def async_get_options_flow(config_entry): + return ExampleEditFlow(config_entry) + +class ExampleEditFlow(config_entries.OptionsFlow): + + def __init__(self, config_entry): + self.config_entry = config_entry + + async def async_step_init(self, user_input=None): + if user_input is not None: + return self.async_create_entry(title="", data=user_input) + return self.async_show_form( + step_id='init', + data_schema=vol.Schema( + { + vol.Optional('title', + default=self.config_entry.options.get("title", "")): str, + vol.Optional('favicon', + default=self.config_entry.options.get("favicon", "")): str, + vol.Optional('apple', + default=self.config_entry.options.get("apple", "")): str, + } + ), + ) + diff --git a/custom_components/favicon/manifest.json b/custom_components/favicon/manifest.json index 897b953..832e07c 100644 --- a/custom_components/favicon/manifest.json +++ b/custom_components/favicon/manifest.json @@ -4,5 +4,6 @@ "documentation": "", "dependencies": ["frontend"], "codeowners": [], - "requirements": [] + "requirements": [], + "config_flow": true } diff --git a/info.md b/info.md index 2ddde5c..7b062ff 100644 --- a/info.md +++ b/info.md @@ -14,31 +14,19 @@ Change the favicon and app icons of your Home Assistant instance There are some nice ones available [here](https://github.com/home-assistant/home-assistant-assets/tree/master/Alternates), and you can generate favicons from them using an online tool, such as [this one](https://realfavicongenerator.net/). - Put your icons in e.g. `/www/favicons/` +Note: If you created `/www/` you need to restart Home Assistant once before any icons will be found. -- Add the following to your `configuration.yaml`: +- Go to your Home Assistant configuration and to Integrations -```yaml -favicon: - favicon: /local/favicons/favicon.ico - apple: /local/favicons/apple-touch-icon-180x180.png - 32: /local/favicons/favicon-32x32.png - 512: /local/favicons/android-chrome-512x512.png -``` +- Add a "Favicon" integration -- Restart Home Assistant +- Enter what you want the title of the Home Assistant interface page to be, and the URL of the icons you wish to change. E.g. `favicon URL: /local/favicons/favicon.ico`, `iOS icon URL: /local/favicons/180x180.png`. -- Make sure to clear the cache of your browser to get the new icons. +- Press submit -# Options +- Refresh the page -- `favicon` - an .ico file which is displayed in your browser tab or bookmark menu. +![integration](https://user-images.githubusercontent.com/1299821/63462280-d91a7000-c45a-11e9-97af-52f0335cad66.gif) -- `apple` - a 180 x 180 px image that will be displayed on your iDevice home screen if you save the link there - -- `` - a `` x `` px image that will be displayed wherever it's needed for non-apple devices. - -You can add as few or as many of those you'd like. It's my understanding that the next smaller size will be used if one is requested which doesn't quite fit the need. - -For reference, Home Assistant includes icons of sizes 192, 384, 512 and 1024 px square by default. Specifying even a single size will override all of those. ![iphone](https://user-images.githubusercontent.com/1299821/62975899-c29d6480-be1b-11e9-9b6b-9d160ef8b439.jpg)