Skip to content

Instantly share code, notes, and snippets.

@jonpitch
Last active September 28, 2018 00:34
Embed
What would you like to do?
new build notifier
<div class="mdc-snackbar mdc-snackbar--align-start" aria-live="assertive" aria-atomic="true" aria-hidden="true">
<div class="mdc-snackbar__text"></div>
<div class="mdc-snackbar__action-wrapper">
<button type="button" class="mdc-snackbar__action-button"></button>
</div>
</div>
import Component from '@ember/component';
import layout from '../templates/components/new-build-notifier';
import { MDCSnackbar } from '@material/snackbar';
import { inject as service } from '@ember/service';
import { set } from '@ember/object';
import { task, timeout } from 'ember-concurrency';
import config from 'ember-get-config';
import { isEmpty } from '@ember/utils';
export default Component.extend({
layout,
intl: service(),
init() {
this._super(...arguments);
set(this, 'pollingInterval', config.APP.newBuildPollingInterval);
},
/**
* Delay attaching the updateHandler to prevent users from
* seeing a new build notification immediately on page load.
*/
setupTask: task(function*() {
const env = config.environment;
const serviceWorkerEnabled = ['staging', 'production'].indexOf(env) !== -1;
const hasServiceWorker = 'serviceWorker' in navigator;
const supportsPromises = 'Promise' in window;
if (serviceWorkerEnabled && hasServiceWorker && supportsPromises) {
yield timeout(this.pollingInterval);
this._attachUpdateHandler();
const polling = this.pollingTask.perform();
set(this, 'polling', polling);
}
}).on('didInsertElement'),
pollingTask: task(function*() {
while (true) {
yield navigator.serviceWorker.register('/sw.js', {
scope: '/'
}).then((reg) => {
reg.update();
});
yield timeout(this.pollingInterval);
}
}),
_attachUpdateHandler() {
window.isUpdateAvailable.then(() => {
if (!isEmpty(this.polling)) {
this.polling.cancel();
}
const intl = this.intl;
const element = this.element.querySelector('.mdc-snackbar');
const snackbar = new MDCSnackbar(element);
const data = {
message: intl.t('components.new-build-notifier.text'),
actionText: intl.t('components.new-build-notifier.action'),
// setTimeout uses 32 bit int
// so Number.MAX_SAFE_INTEGER would not work
timeout: 2147483647,
actionHandler: function () {
window.location.reload(true);
}
};
snackbar.show(data);
});
}
});
import { addSuccessHandler } from 'ember-service-worker/service-worker-registration';
window.isUpdateAvailable =
'Promise' in window
? new Promise(function(resolve) {
addSuccessHandler(function(reg) {
reg.onupdatefound = function() {
const { installing } = reg;
installing.onstatechange = function() {
if (installing.state === 'activated') {
resolve(navigator.serviceWorker.controller !== null);
}
};
};
});
})
: {
then: function () {
return false;
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment