/** * @class FeedViewer.FeedPanel * @extends Ext.panel.Panel * * Shows a list of available feeds. Also has the ability to add/remove and load feeds. * * @constructor * Create a new Feed Panel * @param {Object} config The config object */ Ext.define('FeedViewer.FeedPanel', { extend: 'Ext.panel.Panel', alias: 'widget.feedpanel', animCollapse: true, layout: 'fit', title: 'Feeds', initComponent: function(){ Ext.apply(this, { items: this.createView(), dockedItems: [this.createToolbar()] }); this.createMenu(); this.addEvents( /** * @event feedremove Fired when a feed is removed * @param {FeedPanel} this * @param {String} title The title of the feed * @param {String} url The url of the feed */ 'feedremove', /** * @event feedselect Fired when a feed is selected * @param {FeedPanel} this * @param {String} title The title of the feed * @param {String} url The url of the feed */ 'feedselect' ); this.callParent(arguments); }, /** * Create the DataView to be used for the feed list. * @private * @return {Ext.view.View} */ createView: function(){ var view = this.view = Ext.create('widget.dataview', { store: Ext.create('Ext.data.Store', { model: 'Feed', data: this.feeds }), selModel: { mode: 'SINGLE', listeners: { scope: this, selectionchange: this.onSelectionChange } }, listeners: { scope: this, contextmenu: this.onContextMenu, viewready: this.onViewReady }, trackOver: true, cls: 'feed-list', itemSelector: '.feed-list-item', overItemCls: 'feed-list-item-hover', tpl: '
{title}
' }); view.on('render', function() { }, this); return this.view; }, onViewReady: function(){ this.view.getSelectionModel().select(this.view.store.first()); }, /** * Creates the toolbar to be used for controlling feeds. * @private * @return {Ext.toolbar.Toolbar} */ createToolbar: function(){ this.createActions(); this.toolbar = Ext.create('widget.toolbar', { items: [this.addAction, this.removeAction] }); return this.toolbar; }, /** * Create actions to share between toolbar and menu * @private */ createActions: function(){ this.addAction = Ext.create('Ext.Action', { scope: this, handler: this.onAddFeedClick, text: 'Add feed', iconCls: 'feed-add' }); this.removeAction = Ext.create('Ext.Action', { itemId: 'remove', scope: this, handler: this.onRemoveFeedClick, text: 'Remove feed', iconCls: 'feed-remove' }); }, /** * Create the context menu * @private */ createMenu: function(){ this.menu = Ext.create('widget.menu', { items: [{ scope: this, handler: this.onLoadClick, text: 'Load feed', iconCls: 'feed-load' }, this.removeAction, '-', this.addAction], listeners: { hide: function(c){ c.activeFeed = null; } } }); }, /** * Used when view selection changes so we can disable toolbar buttons. * @private */ onSelectionChange: function(){ var selected = this.getSelectedItem(); this.toolbar.getComponent('remove').setDisabled(!selected); this.loadFeed(selected); }, /** * React to the load feed menu click. * @private */ onLoadClick: function(){ this.loadFeed(this.menu.activeFeed); }, /** * Loads a feed. * @private * @param {Ext.data.Model} rec The feed */ loadFeed: function(rec){ if (rec) { this.fireEvent('feedselect', this, rec.get('title'), rec.get('url')); } }, /** * Gets the currently selected record in the view. * @private * @return {Ext.data.Model} Returns the selected model. false if nothing is selected. */ getSelectedItem: function(){ return this.view.getSelectionModel().getSelection()[0] || false; }, /** * Listens for the context menu event on the view * @private */ onContextMenu: function(view, index, el, event){ var menu = this.menu; event.stopEvent(); menu.activeFeed = view.store.getAt(index); menu.showAt(event.getXY()); }, /** * React to a feed being removed * @private */ onRemoveFeedClick: function(){ var active = this.menu.activeFeed || this.getSelectedItem(); this.animateNode(this.view.getNode(active), 1, 0, { scope: this, afteranimate: function(){ this.view.store.remove(active); } }); this.fireEvent('feedremove', this, active.get('title'), active.get('url')); }, /** * React to a feed attempting to be added * @private */ onAddFeedClick: function(){ var win = this.addFeedWindow || (this.addFeedWindow = Ext.create('widget.feedwindow', { listeners: { scope: this, feedvalid: this.onFeedValid } })); win.form.getForm().reset(); win.show(); }, /** * React to a validation on a feed passing * @private * @param {FeedViewer.FeedWindow} win * @param {String} title The title of the feed * @param {String} url The url of the feed */ onFeedValid: function(win, title, url){ var view = this.view, store = view.store, rec; rec = store.add({ url: url, title: title })[0]; this.animateNode(view.getNode(rec), 0, 1); }, /** * Animate a node in the view when it is added/removed * @private * @param {Mixed} el The element to animate * @param {Number} start The start opacity * @param {Number} end The end opacity * @param {Object} listeners (optional) Any listeners */ animateNode: function(el, start, end, listeners){ Ext.create('Ext.fx.Anim', { target: Ext.get(el), duration: 500, from: { opacity: start }, to: { opacity: end }, listeners: listeners }); }, // Inherit docs onDestroy: function(){ Ext.destroy( this.viewNav, this.menu ); this.callParent(arguments); } });