From 6c55104a8ae5df1d2fab7b9234b2e1c08fcb12e7 Mon Sep 17 00:00:00 2001 From: Jose Luis Represa Date: Thu, 22 Apr 2021 13:47:55 +0200 Subject: [PATCH] feat: add connection-change event --- addon/services/network.js | 88 ++++++++++++++--------------- tests/unit/services/network-test.js | 7 +++ 2 files changed, 49 insertions(+), 46 deletions(-) diff --git a/addon/services/network.js b/addon/services/network.js index 60a0e2b..ccd9c93 100644 --- a/addon/services/network.js +++ b/addon/services/network.js @@ -1,4 +1,4 @@ -import { computed } from '@ember/object'; +import { action } from '@ember/object'; import Evented from '@ember/object/evented'; import Service from '@ember/service'; import { STATES, CONFIG } from '../constants'; @@ -7,15 +7,19 @@ import { cancel, later } from '@ember/runloop'; import { getOwner } from '@ember/application'; import { equal, notEmpty, readOnly } from '@ember/object/computed'; import { A } from '@ember/array'; +import { tracked } from '@glimmer/tracking'; export default class NetworkService extends Service.extend(Evented) { - lastReconnectDuration = 0; - lastReconnectStatus = 0; + @tracked lastReconnectDuration = 0; + @tracked lastReconnectStatus = 0; - _timer = null; - _times = 0; - _state = null; - _controllers = null; + @tracked _timer; + @tracked _times; + @tracked _timestamp; + @tracked _state; + @tracked _controllers; + @tracked _config; + @tracked _nextDelay; @readOnly('_state') state; @equal('_state', STATES.ONLINE) isOnline; @@ -45,7 +49,7 @@ export default class NetworkService extends Service.extend(Evented) { if (state !== this._state) { this._clearTimer(); - this.set('_state', state); + this._state = state; this.trigger('change', state); } @@ -54,21 +58,19 @@ export default class NetworkService extends Service.extend(Evented) { init() { super.init(...arguments); - const connection = this._connection; const appConfig = getOwner(this).resolveRegistration('config:environment'); const addonConfig = appConfig['network-state'] || {}; const reconnect = Object.assign({}, CONFIG.reconnect, addonConfig.reconnect); - this.set('_controllers', A()); - this.set('_config', { reconnect }); + this._times = 0; + this._controllers = A(); + this._config = { reconnect }; - const changeNetworkBinding = this._changeNetworkBinding; - - if (connection) { - connection.addEventListener('change', changeNetworkBinding); + if (this._connection) { + this._connection.addEventListener('change', this._changeNetwork); } else { - window.addEventListener('online', changeNetworkBinding); - window.addEventListener('offline', changeNetworkBinding); + window.addEventListener('online', this._changeNetwork); + window.addEventListener('offline', this._changeNetwork); } const onLine = window.navigator.onLine; @@ -83,15 +85,12 @@ export default class NetworkService extends Service.extend(Evented) { willDestroy() { super.willDestroy(...arguments); - const connection = this._connection; - const changeNetworkBinding = this._changeNetworkBinding; - - window.removeEventListener('online', changeNetworkBinding); - window.removeEventListener('offline', changeNetworkBinding); - - if (connection) { - connection.removeEventListener('change', changeNetworkBinding); + if (this._connection) { + this._connection.removeEventListener('change', this._changeNetwork); } + + window.removeEventListener('online', this._changeNetwork); + window.removeEventListener('offline', this._changeNetwork); } get _connection() { @@ -103,22 +102,23 @@ export default class NetworkService extends Service.extend(Evented) { if (timer) { cancel(timer); - this.set('_timer'); + this._timer = undefined; } - this.set('_nextDelay'); - this.set('_times', 0); - this.set('_timestamp'); - } - - @computed('_changeNetwork') - get _changeNetworkBinding() { - return this._changeNetwork.bind(this); + this._nextDelay = undefined; + this._times = 0; + this._timestamp = undefined; } + @action _changeNetwork() { const onLine = window.navigator.onLine; + /* istanbul ignore else */ + if (this._connection) { + this.trigger('connection-change', this._connection); + } + if (!onLine) { this.setState(STATES.OFFLINE); } else { @@ -164,22 +164,20 @@ export default class NetworkService extends Service.extend(Evented) { cancel(timeout); if (!this.isDestroyed && !this.isReconnecting) { - this.setProperties({ - lastReconnectStatus: status, - lastReconnectDuration: performance.now() - start - }); + this.lastReconnectStatus = status; + this.lastReconnectDuration = performance.now() - start; } } } _abortControllers() { - const controllers = this._controllers; + const controllers = [...this._controllers]; controllers.forEach((controller) => { controller.abort(); }); - controllers.clear(); + this._controllers.removeObjects(controllers); } _handleError() { @@ -190,7 +188,7 @@ export default class NetworkService extends Service.extend(Evented) { this.setState(STATES.LIMITED); if (reconnect.auto) { - this.incrementProperty('_times'); + this._times++; this._delayReconnect(); } } else { @@ -217,10 +215,8 @@ export default class NetworkService extends Service.extend(Evented) { const timer = later(this, '_reconnect', delay); - this.setProperties({ - _nextDelay: nextDelay, - _timestamp: Date.now() + delay, - _timer: timer - }); + this._nextDelay = nextDelay; + this._timestamp = Date.now() + delay; + this._timer = timer; } } diff --git a/tests/unit/services/network-test.js b/tests/unit/services/network-test.js index c739e1f..131e715 100644 --- a/tests/unit/services/network-test.js +++ b/tests/unit/services/network-test.js @@ -165,6 +165,13 @@ module('Unit | Services | network', (hooks) => { this.owner.lookup('service:network'); }); + test('it has initial values', function(assert) { + const service = this.owner.lookup('service:network'); + + assert.equal(service.lastReconnectDuration, 0); + assert.equal(service.lastReconnectStatus, 0); + }); + test('it is online', async function(assert) { this.goOnline();