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);
+ }
+}