/** * A 'Toast' is a simple modal message that is displayed on the screen and then automatically closed by a timeout or by a user tapping * outside of the toast itself. Think about it like a text only alert box that will self destruct. **A Toast should not be instantiated manually** * but creating by calling 'Ext.toast(message, timeout)'. This will create one reusable toast container and content will be swapped out as * toast messages are queued or displayed. * * # Simple Toast * * @example miniphone * Ext.toast('Hello Sencha!'); // Toast will close in 1000 milliseconds (default) * * # Toast with Timeout * * @example miniphone * Ext.toast('Hello Sencha!', 5000); // Toast will close in 5000 milliseconds * * # Toast with config * * @example miniphone * Ext.toast({message: 'Hello Sencha!', timeout: 2000}); // Toast will close in 2000 milliseconds * * # Multiple Toasts queued * * @example miniphone * Ext.toast('Hello Sencha!'); * Ext.toast('Hello Sencha Again!'); * Ext.toast('Hello Sencha One More Time!'); */ Ext.define('Ext.Toast', { extend: 'Ext.Sheet', requires: [ 'Ext.util.InputBlocker' ], config: { /** * @cfg * @inheritdoc */ ui: 'dark', /** * @cfg * @inheritdoc */ baseCls: Ext.baseCSSPrefix + 'toast', /** * @cfg * @inheritdoc */ showAnimation: { type: 'popIn', duration: 250, easing: 'ease-out' }, /** * @cfg * @inheritdoc */ hideAnimation: { type: 'popOut', duration: 250, easing: 'ease-out' }, /** * Override the default `zIndex` so it is normally always above floating components. */ zIndex: 999, /** * @cfg {String} message * The message to be displayed in the {@link Ext.Toast}. * @accessor */ message: null, /** * @cfg {Number} timeout * The amount of time in milliseconds to wait before destroying the toast automatically */ timeout: 1000, /** * @cfg{Boolean/Object} animation * The animation that should be used between toast messages when they are queued up */ messageAnimation: true, /** * @cfg * @inheritdoc */ hideOnMaskTap: true, /** * @private */ modal: true, /** * @cfg * @inheritdoc */ layout: { type: 'vbox', pack: 'center' } }, /** * @private */ applyMessage: function(config) { config = { html: config, cls: this.getBaseCls() + '-text' }; return Ext.factory(config, Ext.Component, this._message); }, /** * @private */ updateMessage: function(newMessage) { if (newMessage) { this.add(newMessage); } }, /** * @private */ applyTimeout: function(timeout) { if (this._timeoutID) { clearTimeout(this._timeoutID); if (!Ext.isEmpty(timeout)) { this._timeoutID = setTimeout(Ext.bind(this.onTimeout, this), timeout); } } return timeout; }, /** * @internal */ next: Ext.emptyFn, /** * @private */ show: function(config) { var me = this, timeout = config.timeout, msgAnimation = me.getMessageAnimation(), message = me.getMessage(); if (me.isRendered() && me.isHidden() === false) { config.timeout = null; message.onAfter({ hiddenchange: function() { me.setMessage(config.message); message = me.getMessage(); message.onAfter({ hiddenchange: function() { // Forces applyTimeout to create a timer this._timeoutID = true; me.setTimeout(timeout); }, scope: me, single: true }); message.show(msgAnimation); }, scope: me, single: true }); message.hide(msgAnimation); } else { Ext.util.InputBlocker.blockInputs(); me.setConfig(config); //if it has not been added to a container, add it to the Viewport. if (!me.getParent() && Ext.Viewport) { Ext.Viewport.add(me); } if (!Ext.isEmpty(timeout)) { me._timeoutID = setTimeout(Ext.bind(me.onTimeout, me), timeout); } me.callParent(arguments); } }, /** * @private */ hide: function(animation) { clearTimeout(this._timeoutID); if (!this.next()) { this.callParent(arguments); } }, /** * @private */ onTimeout: function() { this.hide(); } }, function(Toast) { var _queue = [], _isToasting = false; function next() { var config = _queue.shift(); if (config) { _isToasting = true; this.show(config); } else { _isToasting = false; } return _isToasting; } function getInstance() { if (!Ext.Toast._instance) { Ext.Toast._instance = Ext.create('Ext.Toast'); Ext.Toast._instance.next = next; } return Ext.Toast._instance; } Ext.toast = function(message, timeout) { var toast = getInstance(), config = message; if (Ext.isString(message)) { config = { message: message, timeout: timeout }; } if (config.timeout === undefined) { config.timeout = Ext.Toast.prototype.config.timeout; } _queue.push(config); if (!_isToasting) { toast.next(); } return toast; } });