diff --git a/.eslintrc-hound.json b/.eslintrc-hound.json index bbb71918c2..dc71cc4267 100644 --- a/.eslintrc-hound.json +++ b/.eslintrc-hound.json @@ -50,6 +50,7 @@ "no-multi-assign": 0, "radix": 0, "no-alert": 0, + "no-return-await": 0, "prefer-destructuring": 0, "no-restricted-globals": [2, "event"], "prefer-promise-reject-errors": 0, diff --git a/package.json b/package.json index b2bc1b38ff..28c9368242 100644 --- a/package.json +++ b/package.json @@ -77,6 +77,7 @@ "preact": "^8.2.9", "preact-compat": "^3.18.0", "react-big-calendar": "^0.19.1", + "regenerator-runtime": "^0.11.1", "unfetch": "^3.0.0", "web-animations-js": "^2.3.1", "xss": "^1.0.3" diff --git a/public/__init__.py b/public/__init__.py index 1b30218204..553275dfbd 100644 --- a/public/__init__.py +++ b/public/__init__.py @@ -3,13 +3,13 @@ import os from user_agents import parse FAMILY_MIN_VERSION = { - 'Chrome': 54, # Object.values - 'Chrome Mobile': 54, - 'Firefox': 47, # Object.values - 'Firefox Mobile': 47, - 'Opera': 41, # Object.values - 'Edge': 14, # Array.prototype.includes added in 14 - 'Safari': 10, # Many features not supported by 9 + 'Chrome': 55, # Async/await + 'Chrome Mobile': 55, + 'Firefox': 52, # Async/await + 'Firefox Mobile': 52, + 'Opera': 42, # Async/await + 'Edge': 15, # Async/await + 'Safari': 10.1, # Async/await } diff --git a/src/entrypoints/app.js b/src/entrypoints/app.js index f76027bc6d..3aaf3fac62 100644 --- a/src/entrypoints/app.js +++ b/src/entrypoints/app.js @@ -122,27 +122,25 @@ class HomeAssistant extends LocalizeMixin(PolymerElement) { || (hass && hass.connection && (!hass.states || !hass.config))); } - loadResources(fragment) { - getTranslation(fragment).then((result) => { - this._updateResources(result.language, result.data); - }); + async loadResources(fragment) { + const result = await getTranslation(fragment); + this._updateResources(result.language, result.data); } - loadBackendTranslations() { + async loadBackendTranslations() { if (!this.hass.language) return; const language = this.hass.selectedLanguage || this.hass.language; - this.hass.connection.sendMessagePromise({ + const resp = await this.hass.connection.sendMessagePromise({ type: 'frontend/get_translations', language, - }) - .then((resp) => { - // If we've switched selected languages just ignore this response - if ((this.hass.selectedLanguage || this.hass.language) !== language) return; + }); - this._updateResources(language, resp.result.resources); - }); + // If we've switched selected languages just ignore this response + if ((this.hass.selectedLanguage || this.hass.language) !== language) return; + + this._updateResources(language, resp.result.resources); } _updateResources(language, data) { @@ -195,55 +193,55 @@ class HomeAssistant extends LocalizeMixin(PolymerElement) { translationMetadata: translationMetadata, dockedSidebar: false, moreInfoEntityId: null, - callService: (domain, service, serviceData) => - conn.callService(domain, service, serviceData || {}) - .then( - () => { - let message; - let name; - if (serviceData.entity_id && this.hass.states && - this.hass.states[serviceData.entity_id]) { - name = computeStateName(this.hass.states[serviceData.entity_id]); - } - if (service === 'turn_on' && serviceData.entity_id) { - message = this.localize( - 'ui.notification_toast.entity_turned_on', - 'entity', name || serviceData.entity_id - ); - } else if (service === 'turn_off' && serviceData.entity_id) { - message = this.localize( - 'ui.notification_toast.entity_turned_off', - 'entity', name || serviceData.entity_id - ); - } else { - message = this.localize( - 'ui.notification_toast.service_called', - 'service', `${domain}/${service}` - ); - } - notifications.showNotification(message); - }, - function () { - const msg = this.localize( - 'ui.notification_toast.service_call_failed', - 'service', `${domain}/${service}` - ); - notifications.showNotification(msg); - return Promise.reject(); - } - ), - callApi: (method, path, parameters) => { + callService: async (domain, service, serviceData) => { + try { + await conn.callService(domain, service, serviceData || {}); + + let message; + let name; + if (serviceData.entity_id && this.hass.states && + this.hass.states[serviceData.entity_id]) { + name = computeStateName(this.hass.states[serviceData.entity_id]); + } + if (service === 'turn_on' && serviceData.entity_id) { + message = this.localize( + 'ui.notification_toast.entity_turned_on', + 'entity', name || serviceData.entity_id + ); + } else if (service === 'turn_off' && serviceData.entity_id) { + message = this.localize( + 'ui.notification_toast.entity_turned_off', + 'entity', name || serviceData.entity_id + ); + } else { + message = this.localize( + 'ui.notification_toast.service_called', + 'service', `${domain}/${service}` + ); + } + notifications.showNotification(message); + } catch (err) { + const msg = this.localize( + 'ui.notification_toast.service_call_failed', + 'service', `${domain}/${service}` + ); + notifications.showNotification(msg); + throw err; + } + }, + callApi: async (method, path, parameters) => { const host = window.location.protocol + '//' + window.location.host; const auth = conn.options; - return hassCallApi(host, auth, method, path, parameters).catch((err) => { + try { + return await hassCallApi(host, auth, method, path, parameters); + } catch (err) { if (!err || err.status_code !== 401 || !auth.accessToken) throw err; // If we connect with access token and get 401, refresh token and try again - return window.refreshToken().then((accessToken) => { - conn.options.accessToken = accessToken; - return hassCallApi(host, auth, method, path, parameters); - }); - }); + const accessToken = await window.refreshToken(); + conn.options.accessToken = accessToken; + return await hassCallApi(host, auth, method, path, parameters); + } }, }, this.$.storage.getStoredState()); @@ -261,16 +259,16 @@ class HomeAssistant extends LocalizeMixin(PolymerElement) { // If we reconnect after losing connection and access token is no longer // valid. - conn.addEventListener('reconnect-error', (_conn, err) => { + conn.addEventListener('reconnect-error', async (_conn, err) => { if (err !== ERR_INVALID_AUTH) return; disconnected(); this.unsubConnection(); - window.refreshToken().then(accessToken => - this.handleConnectionPromise(window.createHassConnection(null, accessToken))); + const accessToken = await window.refreshToken(); + this.handleConnectionPromise(window.createHassConnection(null, accessToken)); }); conn.addEventListener('disconnected', disconnected); - var unsubEntities; + let unsubEntities; subscribeEntities(conn, (states) => { this._updateHass({ states: states }); @@ -278,7 +276,7 @@ class HomeAssistant extends LocalizeMixin(PolymerElement) { unsubEntities = unsub; }); - var unsubConfig; + let unsubConfig; subscribeConfig(conn, (config) => { this._updateHass({ config: config }); @@ -288,8 +286,7 @@ class HomeAssistant extends LocalizeMixin(PolymerElement) { this._loadPanels(); - var unsubThemes; - + let unsubThemes; this.hass.connection.sendMessagePromise({ type: 'frontend/get_themes', @@ -335,14 +332,14 @@ class HomeAssistant extends LocalizeMixin(PolymerElement) { this.loadTranslationFragment(newPanelUrl); } - handleConnectionPromise(prom) { + async handleConnectionPromise(prom) { if (!prom) return; - prom.then((conn) => { - this.connection = conn; - }, () => { + try { + this.connection = await prom; + } catch (err) { this.connectionPromise = null; - }); + } } handleMoreInfo(ev) { @@ -392,10 +389,11 @@ class HomeAssistant extends LocalizeMixin(PolymerElement) { } } - _loadPanels() { - this.connection.sendMessagePromise({ + async _loadPanels() { + const msg = await this.connection.sendMessagePromise({ type: 'get_panels' - }).then(msg => this._updateHass({ panels: msg.result })); + }); + this._updateHass({ panels: msg.result }); } diff --git a/src/entrypoints/compatibility.js b/src/entrypoints/compatibility.js index 9812f94fd7..9a8bf59a14 100644 --- a/src/entrypoints/compatibility.js +++ b/src/entrypoints/compatibility.js @@ -1,5 +1,6 @@ import 'mdn-polyfills/Array.prototype.includes'; import 'unfetch/polyfill'; +import 'regenerator-runtime/runtime'; import objAssign from 'es6-object-assign'; objAssign.polyfill();