Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
207 lines
6.2 KiB
JavaScript
207 lines
6.2 KiB
JavaScript
/* global Service */
|
|
'use strict';
|
|
|
|
(function(exports) {
|
|
var toasterEvents = ['init', 'open', 'complete', 'terminate', 'close'];
|
|
var toasterStateTable = {
|
|
'uninit': ['closed', null, null, null, null],
|
|
'closed': [null, 'opening', null, 'uninit', null],
|
|
'opening': [null, null, 'opened', 'uninit', null],
|
|
'opened': [null, null, null, 'uninit', 'closing'],
|
|
'closing': [null, 'opening', 'closed', 'uninit', null]
|
|
};
|
|
/**
|
|
* AttentionToaster is a sub component of AttentionWindow
|
|
* to help the attention window instance to play like a notification toaster
|
|
* and control the toaster's transition state.
|
|
* @param {AppWindow} app The app window installing this sub component.
|
|
*/
|
|
var AttentionToaster = function(app) {
|
|
this.app = app;
|
|
};
|
|
AttentionToaster.prototype = {
|
|
_currentToasterState: 'uninit',
|
|
|
|
TOASTER_TIMEOUT: 5000,
|
|
|
|
RESPAWN_TIMEOUT: 45000,
|
|
|
|
start: function() {
|
|
this.app.element.addEventListener('_closed', this);
|
|
this.app.element.addEventListener('_requestopen', this);
|
|
this.app.element.addEventListener('transitionend', this);
|
|
this.app.element.addEventListener('_secure-appclosed', this);
|
|
this.app.element.addEventListener('_secure-appopened', this);
|
|
this.app.element.addEventListener('_lockscreen-appclosed', this);
|
|
this.app.element.addEventListener('_lockscreen-appopened', this);
|
|
},
|
|
|
|
stop: function() {
|
|
this.app.element.removeEventListener('_closed', this);
|
|
this.app.element.removeEventListener('_requestopen', this);
|
|
this.app.element.removeEventListener('transitionend', this);
|
|
this.app.element.removeEventListener('_secure-appclosed', this);
|
|
this.app.element.removeEventListener('_secure-appopened', this);
|
|
this.app.element.removeEventListener('_lockscreen-appclosed', this);
|
|
this.app.element.removeEventListener('_lockscreen-appopened', this);
|
|
},
|
|
|
|
shouldProcess: function() {
|
|
return this.app && this.app.element && !this.app.isHidden() &&
|
|
!this.app.isActive() && !this.app.isDead();
|
|
},
|
|
|
|
handleEvent: function(evt) {
|
|
if (!this.shouldProcess()) {
|
|
this.app.debug('should not process');
|
|
return;
|
|
}
|
|
|
|
switch (evt.type) {
|
|
case '_lockscreen-appclosed':
|
|
case '_secure-appopened':
|
|
this.processStateChange('close', evt.type);
|
|
break;
|
|
|
|
case '_requestopen':
|
|
this.processStateChange('terminate', evt.type);
|
|
break;
|
|
|
|
case 'transitionend':
|
|
if (evt.target !== this.app.element) {
|
|
return;
|
|
}
|
|
|
|
this.processStateChange('complete', evt.type);
|
|
break;
|
|
|
|
case '_closed':
|
|
window.requestAnimationFrame(() => {
|
|
this.processStateChange('init', evt.type);
|
|
});
|
|
break;
|
|
|
|
case '_lockscreen-appopened':
|
|
case '_secure-appclosed':
|
|
this.processStateChange('open', evt.type);
|
|
break;
|
|
}
|
|
},
|
|
|
|
processStateChange: function(event, reason) {
|
|
if (!this.shouldProcess()) {
|
|
this.app.debug('should not process ' + event);
|
|
return;
|
|
}
|
|
|
|
var eventIndex = toasterEvents.indexOf(event);
|
|
var nextState =
|
|
toasterStateTable[this._currentToasterState][eventIndex];
|
|
|
|
this.app.debug(this._currentToasterState + ' -> ' + nextState);
|
|
|
|
if (!nextState) {
|
|
return;
|
|
}
|
|
|
|
this.app.debug('[toaster] ' +
|
|
this._currentToasterState + '->' + nextState +
|
|
':' + event + ',' + reason);
|
|
this._currentToasterState = nextState;
|
|
this.app.element.setAttribute('toaster-transition-state',
|
|
this._currentToasterState);
|
|
if (typeof(this['_enter_' + nextState]) == 'function') {
|
|
this['_enter_' + nextState](event);
|
|
}
|
|
},
|
|
|
|
_enter_closing: function() {
|
|
if (!this.app || !this.app.element ||
|
|
(Service && Service.query('locked') &&
|
|
!Service.query('getTopMostWindow').isFullScreen())) {
|
|
return;
|
|
}
|
|
|
|
this.app.element.classList.remove('displayed');
|
|
},
|
|
|
|
_enter_closed: function(evt) {
|
|
if (!this.app || !this.app.element) {
|
|
return;
|
|
}
|
|
|
|
if (evt == 'init') {
|
|
this.becomeToaster();
|
|
this.app.tryWaitForFullRepaint(function() {
|
|
this.processStateChange('open', 'repainted');
|
|
}.bind(this));
|
|
} else if (evt == 'complete') {
|
|
this.app && this.app.setVisible(false);
|
|
this.respawnTimer = window.setTimeout(function() {
|
|
this.processStateChange('open', 'respawn');
|
|
}.bind(this), this.RESPAWN_TIMEOUT);
|
|
}
|
|
},
|
|
|
|
_enter_opened: function() {
|
|
if (!this.app || !this.app.element) {
|
|
return;
|
|
}
|
|
|
|
this.app && this.app.setVisible(true);
|
|
this._toasterTimer = window.setTimeout(function() {
|
|
if (Service && Service.query('locked') &&
|
|
!Service.query('getTopMostWindow').isFullScreen()) {
|
|
return;
|
|
}
|
|
|
|
this.processStateChange('close', 'timeout');
|
|
}.bind(this), this.TOASTER_TIMEOUT);
|
|
},
|
|
|
|
_enter_opening: function() {
|
|
if (!this.app || !this.app.element) {
|
|
return;
|
|
}
|
|
|
|
window.clearTimeout(this.respawnTimer);
|
|
this.respawnTimer = null;
|
|
this.app.setVisible(true);
|
|
this.app.element.classList.add('displayed');
|
|
},
|
|
|
|
_enter_uninit: function() {
|
|
if (!this.app || !this.app.element) {
|
|
return;
|
|
}
|
|
|
|
if (this._toasterTimer) {
|
|
window.clearTimeout(this._toasterTimer);
|
|
this._toasterTimer = null;
|
|
}
|
|
this.recoverLayout();
|
|
},
|
|
|
|
recoverLayout: function() {
|
|
if (this.app && this.app.resized) {
|
|
this.app.element.classList.remove('displayed');
|
|
this.app.element.classList.remove('toaster-mode');
|
|
this.app.resized = false;
|
|
this.app.publish('recovering');
|
|
this.app._resize();
|
|
}
|
|
},
|
|
|
|
becomeToaster: function() {
|
|
if (!this.shouldProcess()) {
|
|
return;
|
|
}
|
|
|
|
// Override the resized height anyway
|
|
this.app.element.style.height = this.app.closedHeight + 'px';
|
|
this.app.element.classList.add('toaster-mode');
|
|
this.app.resized = true;
|
|
}
|
|
};
|
|
exports.AttentionToaster = AttentionToaster;
|
|
}(window));
|