mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-19 15:26:36 +00:00
Add theme-choosing UI to config panel (#363)
* Add theme-choosing UI to config panel * Add Backend-selected option * Use Object.assign to change hass * Fix #368 - support theme-color update.
This commit is contained in:
parent
1ea7137c78
commit
ebc0c776e2
@ -8,6 +8,7 @@
|
|||||||
<!-- <link rel="import" href="./group/ha-config-section-group.html"> -->
|
<!-- <link rel="import" href="./group/ha-config-section-group.html"> -->
|
||||||
<link rel="import" href="./hassbian/ha-config-section-hassbian.html">
|
<link rel="import" href="./hassbian/ha-config-section-hassbian.html">
|
||||||
<link rel="import" href="./z-wave/ha-config-section-zwave.html">
|
<link rel="import" href="./z-wave/ha-config-section-zwave.html">
|
||||||
|
<link rel="import" href="themes/ha-config-section-themes.html">
|
||||||
|
|
||||||
<dom-module id="ha-panel-config">
|
<dom-module id="ha-panel-config">
|
||||||
<template>
|
<template>
|
||||||
@ -53,6 +54,14 @@
|
|||||||
hass='[[hass]]'
|
hass='[[hass]]'
|
||||||
></ha-config-section-core>
|
></ha-config-section-core>
|
||||||
|
|
||||||
|
<template is='dom-if' if='[[computeIsThemesLoaded(hass)]]'>
|
||||||
|
<div class='border'></div>
|
||||||
|
<ha-config-section-themes
|
||||||
|
is-wide='[[isWide]]'
|
||||||
|
hass='[[hass]]'
|
||||||
|
></ha-config-section-themes>
|
||||||
|
</template>
|
||||||
|
|
||||||
<template is='dom-if' if='[[computeIsHassbianLoaded(hass)]]'>
|
<template is='dom-if' if='[[computeIsHassbianLoaded(hass)]]'>
|
||||||
<div class='border'></div>
|
<div class='border'></div>
|
||||||
<ha-config-section-hassbian
|
<ha-config-section-hassbian
|
||||||
@ -120,5 +129,10 @@ Polymer({
|
|||||||
computeIsZwaveLoaded: function (hass) {
|
computeIsZwaveLoaded: function (hass) {
|
||||||
return window.hassUtil.isComponentLoaded(hass, 'config.zwave');
|
return window.hassUtil.isComponentLoaded(hass, 'config.zwave');
|
||||||
},
|
},
|
||||||
|
|
||||||
|
computeIsThemesLoaded: function (hass) {
|
||||||
|
return hass.themes && hass.themes.themes &&
|
||||||
|
Object.keys(hass.themes.themes).length;
|
||||||
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
85
panels/config/themes/ha-config-section-themes.html
Normal file
85
panels/config/themes/ha-config-section-themes.html
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
<link rel="import" href="../../../bower_components/polymer/polymer.html">
|
||||||
|
<link rel="import" href="../../../bower_components/paper-card/paper-card.html">
|
||||||
|
<link rel="import" href="../../../bower_components/paper-dropdown-menu/paper-dropdown-menu.html">
|
||||||
|
<link rel='import' href='../../../bower_components/paper-listbox/paper-listbox.html'>
|
||||||
|
<link rel='import' href='../../../bower_components/paper-item/paper-item.html'>
|
||||||
|
|
||||||
|
<link rel="import" href="../ha-config-section.html">
|
||||||
|
|
||||||
|
<dom-module id="ha-config-section-themes">
|
||||||
|
<template>
|
||||||
|
<ha-config-section is-wide='[[isWide]]'>
|
||||||
|
<span slot='header'>Set a theme</span>
|
||||||
|
<span slot='introduction'>
|
||||||
|
Choose 'default' to use whatever theme the backend chooses or pick a theme for this device.
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<paper-card>
|
||||||
|
<div class='card-content'>
|
||||||
|
<paper-dropdown-menu label='Theme' vertical-align='bottom'>
|
||||||
|
<paper-listbox
|
||||||
|
slot="dropdown-content"
|
||||||
|
selected='{{selectedTheme}}'
|
||||||
|
>
|
||||||
|
<template is='dom-repeat' items='[[themes]]' as='theme'>
|
||||||
|
<paper-item>[[theme]]</paper-item>
|
||||||
|
</template>
|
||||||
|
</paper-listbox>
|
||||||
|
</paper-dropdown-menu>
|
||||||
|
</div>
|
||||||
|
</paper-card>
|
||||||
|
</ha-config-section>
|
||||||
|
</template>
|
||||||
|
</dom-module>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
Polymer({
|
||||||
|
is: 'ha-config-section-themes',
|
||||||
|
|
||||||
|
properties: {
|
||||||
|
hass: {
|
||||||
|
type: Object,
|
||||||
|
},
|
||||||
|
|
||||||
|
isWide: {
|
||||||
|
type: Boolean,
|
||||||
|
},
|
||||||
|
|
||||||
|
themes: {
|
||||||
|
type: Array,
|
||||||
|
computed: 'computeThemes(hass)',
|
||||||
|
},
|
||||||
|
|
||||||
|
selectedTheme: {
|
||||||
|
type: Number,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
ready: function () {
|
||||||
|
if (this.hass.selectedTheme && this.themes.indexOf(this.hass.selectedTheme) > 0) {
|
||||||
|
this.selectedTheme = this.themes.indexOf(this.hass.selectedTheme);
|
||||||
|
} else if (!this.hass.selectedTheme) {
|
||||||
|
this.selectedTheme = 0;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
observers: [
|
||||||
|
'selectionChanged(hass, selectedTheme)',
|
||||||
|
],
|
||||||
|
|
||||||
|
computeThemes: function (hass) {
|
||||||
|
if (!hass) return [];
|
||||||
|
return ['Backend-selected', 'default'].concat(Object.keys(hass.themes.themes).sort());
|
||||||
|
},
|
||||||
|
|
||||||
|
selectionChanged: function (hass, selection) {
|
||||||
|
if (selection > 0 && selection < this.themes.length) {
|
||||||
|
if (hass.selectedTheme !== this.themes[selection]) {
|
||||||
|
this.fire('settheme', this.themes[selection]);
|
||||||
|
}
|
||||||
|
} else if (selection === 0 && hass.selectedTheme !== '') {
|
||||||
|
this.fire('settheme', '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
@ -85,6 +85,10 @@ Polymer({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
listeners: {
|
||||||
|
settheme: 'setTheme',
|
||||||
|
},
|
||||||
|
|
||||||
computeShowMain: function (hass, iconsLoaded) {
|
computeShowMain: function (hass, iconsLoaded) {
|
||||||
return hass && hass.states && hass.config && iconsLoaded;
|
return hass && hass.states && hass.config && iconsLoaded;
|
||||||
},
|
},
|
||||||
@ -158,13 +162,13 @@ Polymer({
|
|||||||
}, this.$.storage.getStoredState());
|
}, this.$.storage.getStoredState());
|
||||||
|
|
||||||
var reconnected = () => {
|
var reconnected = () => {
|
||||||
this.hass = Object.assign({}, this.hass, { connected: true });
|
this._updateHass({ connected: true });
|
||||||
};
|
};
|
||||||
|
|
||||||
conn.addEventListener('ready', reconnected);
|
conn.addEventListener('ready', reconnected);
|
||||||
|
|
||||||
var disconnected = () => {
|
var disconnected = () => {
|
||||||
this.hass = Object.assign({}, this.hass, { connected: false });
|
this._updateHass({ connected: false });
|
||||||
};
|
};
|
||||||
|
|
||||||
conn.addEventListener('disconnected', disconnected);
|
conn.addEventListener('disconnected', disconnected);
|
||||||
@ -172,7 +176,7 @@ Polymer({
|
|||||||
var unsubEntities;
|
var unsubEntities;
|
||||||
|
|
||||||
window.HAWS.subscribeEntities(conn, (states) => {
|
window.HAWS.subscribeEntities(conn, (states) => {
|
||||||
this.hass = Object.assign({}, this.hass, { states: states });
|
this._updateHass({ states: states });
|
||||||
}).then(function (unsub) {
|
}).then(function (unsub) {
|
||||||
unsubEntities = unsub;
|
unsubEntities = unsub;
|
||||||
});
|
});
|
||||||
@ -180,7 +184,7 @@ Polymer({
|
|||||||
var unsubConfig;
|
var unsubConfig;
|
||||||
|
|
||||||
window.HAWS.subscribeConfig(conn, (config) => {
|
window.HAWS.subscribeConfig(conn, (config) => {
|
||||||
this.hass = Object.assign({}, this.hass, { config: config });
|
this._updateHass({ config: config });
|
||||||
}).then(function (unsub) {
|
}).then(function (unsub) {
|
||||||
unsubConfig = unsub;
|
unsubConfig = unsub;
|
||||||
});
|
});
|
||||||
@ -188,12 +192,12 @@ Polymer({
|
|||||||
var unsubThemes;
|
var unsubThemes;
|
||||||
|
|
||||||
this.hass.callApi('get', 'themes').then((themes) => {
|
this.hass.callApi('get', 'themes').then((themes) => {
|
||||||
this.hass.themes = themes;
|
this._updateHass({ themes: themes });
|
||||||
window.hassUtil.applyThemesOnElement(this, themes);
|
window.hassUtil.applyThemesOnElement(this, themes, this.hass.selectedTheme, true);
|
||||||
});
|
});
|
||||||
conn.subscribeEvents((event) => {
|
conn.subscribeEvents((event) => {
|
||||||
this.hass.themes = event.data;
|
this._updateHass({ themes: event.data });
|
||||||
window.hassUtil.applyThemesOnElement(this, event.data);
|
window.hassUtil.applyThemesOnElement(this, event.data, this.hass.selectedTheme, true);
|
||||||
}, 'themes_updated').then(function (unsub) {
|
}, 'themes_updated').then(function (unsub) {
|
||||||
unsubThemes = unsub;
|
unsubThemes = unsub;
|
||||||
});
|
});
|
||||||
@ -220,16 +224,12 @@ Polymer({
|
|||||||
handleMoreInfo: function (ev) {
|
handleMoreInfo: function (ev) {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
|
|
||||||
this.hass = Object.assign(
|
this._updateHass({ moreInfoEntityId: ev.detail.entityId });
|
||||||
{}, this.hass,
|
|
||||||
{ moreInfoEntityId: ev.detail.entityId });
|
|
||||||
},
|
},
|
||||||
|
|
||||||
handleDockSidebar: function (ev) {
|
handleDockSidebar: function (ev) {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
this.hass = Object.assign(
|
this._updateHass({ dockedSidebar: ev.detail.dock });
|
||||||
{}, this.hass,
|
|
||||||
{ dockedSidebar: ev.detail.dock });
|
|
||||||
this.$.storage.storeState();
|
this.$.storage.storeState();
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -253,5 +253,15 @@ Polymer({
|
|||||||
ready: function () {
|
ready: function () {
|
||||||
this.loadIcons();
|
this.loadIcons();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setTheme: function (event) {
|
||||||
|
this._updateHass({ selectedTheme: event.detail });
|
||||||
|
window.hassUtil.applyThemesOnElement(this, this.hass.themes, this.hass.selectedTheme, true);
|
||||||
|
this.$.storage.storeState();
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateHass: function (obj) {
|
||||||
|
this.hass = Object.assign({}, this.hass, obj);
|
||||||
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
(function () {
|
(function () {
|
||||||
var STORED_STATE = [
|
var STORED_STATE = [
|
||||||
'dockedSidebar',
|
'dockedSidebar',
|
||||||
|
'selectedTheme',
|
||||||
];
|
];
|
||||||
|
|
||||||
Polymer({
|
Polymer({
|
||||||
|
@ -492,25 +492,34 @@ window.hassUtil.computeLocationName = function (hass) {
|
|||||||
return hass && hass.config.core.location_name;
|
return hass && hass.config.core.location_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
window.hassUtil.applyThemesOnElement = function (element, themes, localTheme) {
|
window.hassUtil.applyThemesOnElement = function (element, themes, localTheme, updateMeta) {
|
||||||
if (!element._themes) {
|
if (!element._themes) {
|
||||||
element._themes = {};
|
element._themes = {};
|
||||||
}
|
}
|
||||||
var themeName = themes.default_theme;
|
let themeName = themes.default_theme;
|
||||||
if (localTheme === 'default' || (localTheme && themes.themes[localTheme])) {
|
if (localTheme === 'default' || (localTheme && themes.themes[localTheme])) {
|
||||||
themeName = localTheme;
|
themeName = localTheme;
|
||||||
}
|
}
|
||||||
if (themeName === 'default') {
|
const styles = Object.assign({}, element._themes);
|
||||||
element.updateStyles(element._themes);
|
if (themeName !== 'default') {
|
||||||
return;
|
|
||||||
}
|
|
||||||
var theme = themes.themes[themeName];
|
var theme = themes.themes[themeName];
|
||||||
var styles = Object.assign({}, element._themes);
|
Object.keys(theme).forEach((key) => {
|
||||||
Object.keys(theme).forEach(function (key) {
|
|
||||||
var prefixedKey = '--' + key;
|
var prefixedKey = '--' + key;
|
||||||
element._themes[prefixedKey] = '';
|
element._themes[prefixedKey] = '';
|
||||||
styles[prefixedKey] = theme[key];
|
styles[prefixedKey] = theme[key];
|
||||||
});
|
});
|
||||||
|
}
|
||||||
element.updateStyles(styles);
|
element.updateStyles(styles);
|
||||||
|
|
||||||
|
if (!updateMeta) return;
|
||||||
|
|
||||||
|
const meta = document.querySelector('meta[name=theme-color]');
|
||||||
|
if (meta) {
|
||||||
|
if (!meta.hasAttribute('default-content')) {
|
||||||
|
meta.setAttribute('default-content', meta.getAttribute('content'));
|
||||||
|
}
|
||||||
|
const themeColor = styles['--primary-color'] || meta.getAttribute('default-content');
|
||||||
|
meta.setAttribute('content', themeColor);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user