diff --git a/src/cards/ha-card-chooser.js b/src/cards/ha-card-chooser.js index c6fd37d6f4..b7de358718 100644 --- a/src/cards/ha-card-chooser.js +++ b/src/cards/ha-card-chooser.js @@ -1,5 +1,7 @@ import Polymer from '../polymer'; +import dynamicContentUpdater from '../util/dynamic-content-updater'; + require('./ha-camera-card'); require('./ha-entities-card'); require('./ha-introduction-card'); @@ -14,40 +16,10 @@ export default new Polymer({ }, }, - cardDataChanged(newData, oldData) { - const root = Polymer.dom(this); + cardDataChanged(newData) { + if (!newData) return; - if (!newData) { - if (root.lastChild) { - root.removeChild(root.lastChild); - } - return; - } - - const newElement = !oldData || oldData.cardType !== newData.cardType; - let card; - if (newElement) { - if (root.lastChild) { - root.removeChild(root.lastChild); - } - - card = document.createElement(`ha-${newData.cardType}-card`); - } else { - card = root.lastChild; - } - - Object.keys(newData).forEach(key => card[key] = newData[key]); - - if (oldData) { - Object.keys(oldData).forEach(key => { - if (!(key in newData)) { - card[key] = undefined; - } - }); - } - - if (newElement) { - root.appendChild(card); - } + dynamicContentUpdater(this, `HA-${newData.cardType.toUpperCase()}-CARD`, + newData); }, }); diff --git a/src/components/ha-cards.js b/src/components/ha-cards.js index 58ec37cdfe..4b2ea5825f 100644 --- a/src/components/ha-cards.js +++ b/src/components/ha-cards.js @@ -52,10 +52,21 @@ export default new Polymer({ cards: { type: Object, - computed: 'computeCards(columns, states, showIntroduction)', }, }, + observers: [ + 'updateCards(columns, states, showIntroduction)', + ], + + updateCards(columns, states, showIntroduction) { + this.debounce( + 'updateCards', + () => this.cards = this.computeCards(columns, states, showIntroduction), + 0 + ); + }, + computeCards(columns, states, showIntroduction) { const byDomain = states.groupBy(entity => entity.domain); const hasGroup = {}; diff --git a/src/dialogs/more-info-dialog.html b/src/dialogs/more-info-dialog.html index 5e47d1493a..7fdd202a23 100644 --- a/src/dialogs/more-info-dialog.html +++ b/src/dialogs/more-info-dialog.html @@ -44,8 +44,7 @@ is-loading-data="[[isLoadingHistoryData]]"> - + diff --git a/src/more-infos/more-info-camera.html b/src/more-infos/more-info-camera.html index 97496abff9..fcb278a69e 100644 --- a/src/more-infos/more-info-camera.html +++ b/src/more-infos/more-info-camera.html @@ -12,7 +12,7 @@ diff --git a/src/more-infos/more-info-camera.js b/src/more-infos/more-info-camera.js index f8d304646e..687dee36bc 100644 --- a/src/more-infos/more-info-camera.js +++ b/src/more-infos/more-info-camera.js @@ -7,22 +7,19 @@ export default new Polymer({ stateObj: { type: Object, }, - dialogOpen: { - type: Boolean, - }, }, imageLoaded() { this.fire('iron-resize'); }, - computeCameraImageUrl(dialogOpen) { + computeCameraImageUrl(stateObj) { if (__DEMO__) { return '/demo/webcam.jpg'; - } else if (dialogOpen) { + } else if (stateObj) { return `/api/camera_proxy_stream/${this.stateObj.entityId}`; } - // Return an empty image if dialog is not open + // Return an empty image if no stateObj (= dialog not open) return 'data:image/gif;base64,R0lGODlhAQABAAAAACw='; }, }); diff --git a/src/more-infos/more-info-content.js b/src/more-infos/more-info-content.js index 2b49df6261..5b08af1330 100644 --- a/src/more-infos/more-info-content.js +++ b/src/more-infos/more-info-content.js @@ -1,4 +1,6 @@ import Polymer from '../polymer'; + +import dynamicContentUpdater from '../util/dynamic-content-updater'; import stateMoreInfoType from '../util/state-more-info-type'; require('./more-info-default'); @@ -22,46 +24,12 @@ export default new Polymer({ type: Object, observer: 'stateObjChanged', }, - - dialogOpen: { - type: Boolean, - value: false, - observer: 'dialogOpenChanged', - }, }, - dialogOpenChanged(newVal) { - const root = Polymer.dom(this); + stateObjChanged(stateObj) { + if (!stateObj) return; - if (root.lastChild) { - root.lastChild.dialogOpen = newVal; - } - }, - - stateObjChanged(newVal, oldVal) { - const root = Polymer.dom(this); - - if (!newVal) { - if (root.lastChild) { - root.removeChild(root.lastChild); - } - return; - } - - const newMoreInfoType = stateMoreInfoType(newVal); - - if (!oldVal || stateMoreInfoType(oldVal) !== newMoreInfoType) { - if (root.lastChild) { - root.removeChild(root.lastChild); - } - - const moreInfo = document.createElement(`more-info-${newMoreInfoType}`); - moreInfo.stateObj = newVal; - moreInfo.dialogOpen = this.dialogOpen; - root.appendChild(moreInfo); - } else { - root.lastChild.dialogOpen = this.dialogOpen; - root.lastChild.stateObj = newVal; - } + dynamicContentUpdater( + this, `MORE-INFO-${stateMoreInfoType(stateObj).toUpperCase()}`, { stateObj }); }, }); diff --git a/src/state-summary/state-card-content.js b/src/state-summary/state-card-content.js index 71416a2267..4d2b5cc93c 100644 --- a/src/state-summary/state-card-content.js +++ b/src/state-summary/state-card-content.js @@ -1,6 +1,7 @@ import Polymer from '../polymer'; import stateCardType from '../util/state-card-type'; +import dynamicContentUpdater from '../util/dynamic-content-updater'; require('./state-card-configurator'); require('./state-card-display'); @@ -22,28 +23,10 @@ export default new Polymer({ }, }, - stateObjChanged(newVal, oldVal) { - const root = Polymer.dom(this); + stateObjChanged(stateObj) { + if (!stateObj) return; - if (!newVal) { - if (root.lastChild) { - root.removeChild(root.lastChild); - } - return; - } - - const newCardType = stateCardType(newVal); - - if (!oldVal || stateCardType(oldVal) !== newCardType) { - if (root.lastChild) { - root.removeChild(root.lastChild); - } - - const stateCard = document.createElement(`state-card-${newCardType}`); - stateCard.stateObj = newVal; - root.appendChild(stateCard); - } else { - root.lastChild.stateObj = newVal; - } + dynamicContentUpdater( + this, `STATE-CARD-${stateCardType(stateObj).toUpperCase()}`, { stateObj }); }, }); diff --git a/src/util/dynamic-content-updater.js b/src/util/dynamic-content-updater.js new file mode 100644 index 0000000000..4a52f6533b --- /dev/null +++ b/src/util/dynamic-content-updater.js @@ -0,0 +1,22 @@ +import Polymer from '../polymer'; + +export default function dynamicContentUpdater(root, newElementTag, attributes) { + const rootEl = Polymer.dom(root); + + let customEl; + + if (rootEl.lastChild && rootEl.lastChild.tagName === newElementTag) { + customEl = rootEl.lastChild; + } else { + if (rootEl.lastChild) { + rootEl.removeChild(rootEl.lastChild); + } + customEl = document.createElement(newElementTag); + } + + Object.keys(attributes).forEach(key => customEl[key] = attributes[key]); + + if (customEl.parentNode === null) { + rootEl.appendChild(customEl); + } +}