diff --git a/UI/Series/Details/SeasonLayout.js b/UI/Series/Details/SeasonLayout.js index dd4336487..4bd3fa017 100644 --- a/UI/Series/Details/SeasonLayout.js +++ b/UI/Series/Details/SeasonLayout.js @@ -8,8 +8,8 @@ define( 'Cells/AirDateCell', 'Cells/EpisodeStatusCell', 'Commands/CommandController', - 'Shared/Messenger' - ], function ( Marionette, Backgrid, ToggleCell, EpisodeTitleCell, AirDateCell, EpisodeStatusCell, CommandController, Messenger) { + 'Shared/Actioneer' + ], function ( Marionette, Backgrid, ToggleCell, EpisodeTitleCell, AirDateCell, EpisodeStatusCell, CommandController, Actioneer) { return Marionette.Layout.extend({ template: 'Series/Details/SeasonLayoutTemplate', @@ -94,55 +94,36 @@ define( }, _seasonSearch: function () { - var command = 'seasonSearch'; - - this.idle = false; - - this.ui.seasonSearch.addClass('icon-spinner icon-spin'); - - var properties = { - seriesId : this.model.get('seriesId'), - seasonNumber: this.model.get('seasonNumber') - }; - - var self = this; - var commandPromise = CommandController.Execute(command, properties); - - commandPromise.fail(function (options) { - if (options.readyState === 0 || options.status === 0) { - return; - } - - Messenger.show({ - message: 'Season search failed', - type : 'error' - }); - }); - - commandPromise.always(function () { - if (!self.isClosed) { - self.ui.seasonSearch.removeClass('icon-spinner icon-spin'); - self.idle = true; - } + Actioneer.ExecuteCommand({ + command : 'seasonSearch', + properties : { + seriesId : this.model.get('seriesId'), + seasonNumber: this.model.get('seasonNumber') + }, + element : this.ui.seasonSearch, + failMessage: 'Season search failed' }); }, _seasonMonitored: function () { - var self = this; var name = 'monitored'; this.model.set(name, !this.model.get(name)); - this.ui.seasonMonitored.addClass('icon-spinner icon-spin'); - - var promise = this.model.save(); + Actioneer.SaveModel({ + context : this, + element : this.ui.seasonMonitored, + alwaysCallback: this._afterSeasonMonitored + }); + }, - promise.always(function (){ - _.each(self.episodeCollection.models, function (episode) { - episode.set({ monitored: self.model.get('monitored') }); - }); + _afterSeasonMonitored: function () { + var self = this; - self.render(); + _.each(this.episodeCollection.models, function (episode) { + episode.set({ monitored: self.model.get('monitored') }); }); + + this.render(); }, _setSeasonMonitoredState: function () { @@ -159,36 +140,14 @@ define( }, _seasonRename: function () { - var command = 'renameSeason'; - - this.idle = false; - - this.ui.seasonRename.toggleClass('icon-nd-rename icon-nd-spinner'); - - var properties = { - seriesId : this.model.get('seriesId'), - seasonNumber: this.model.get('seasonNumber') - }; - - var self = this; - var commandPromise = CommandController.Execute(command, properties); - - commandPromise.fail(function (options) { - if (options.readyState === 0 || options.status === 0) { - return; - } - - Messenger.show({ - message: 'Season rename failed', - type : 'error' - }); - }); - - commandPromise.always(function () { - if (!self.isClosed) { - self.ui.seasonRename.toggleClass('icon-nd-rename icon-nd-spinner'); - self.idle = true; - } + Actioneer.ExecuteCommand({ + command : 'renameSeason', + properties : { + seriesId : this.model.get('seriesId'), + seasonNumber: this.model.get('seasonNumber') + }, + element : this.ui.seasonRename, + failMessage: 'Season rename failed' }); } }); diff --git a/UI/Series/Details/SeriesDetailsLayout.js b/UI/Series/Details/SeriesDetailsLayout.js index 3583613ce..845317e7f 100644 --- a/UI/Series/Details/SeriesDetailsLayout.js +++ b/UI/Series/Details/SeriesDetailsLayout.js @@ -8,9 +8,9 @@ define( 'Series/Details/SeasonCollectionView', 'Series/Edit/EditSeriesView', 'Shared/LoadingView', - 'Commands/CommandController', + 'Shared/Actioneer', 'backstrech' - ], function (App, Marionette, EpisodeCollection, SeasonCollection, SeasonCollectionView, EditSeriesView, LoadingView, CommandController) { + ], function (App, Marionette, EpisodeCollection, SeasonCollection, SeasonCollectionView, EditSeriesView, LoadingView, Actioneer) { return Marionette.Layout.extend({ itemViewContainer: '.x-series-seasons', @@ -89,16 +89,13 @@ define( }, _toggleMonitored: function () { - var self = this; var name = 'monitored'; this.model.set(name, !this.model.get(name), { silent: true }); - this.ui.monitored.addClass('icon-spinner icon-spin'); - - var promise = this.model.save(); - - promise.always(function () { - self._setMonitoredState(); + Actioneer.SaveModel({ + context : this, + element : this.ui.monitored, + alwaysCallback: this._setMonitoredState() }); }, @@ -123,13 +120,13 @@ define( }, _refreshSeries: function () { - var self = this; - - this.ui.refresh.addClass('icon-spin'); - var promise = CommandController.Execute('refreshseries', { seriesId: this.model.get('id') }); - - promise.always(function () { - self.ui.refresh.removeClass('icon-spin'); + Actioneer.ExecuteCommand({ + command : 'refreshSeries', + properties : { + seriesId : this.model.get('id') + }, + element : this.ui.refresh, + leaveIcon : true }); }, @@ -141,35 +138,13 @@ define( }, _renameSeries: function () { - var command = 'renameSeries'; - - this.idle = false; - - this.ui.rename.toggleClass('icon-nd-rename icon-nd-spinner'); - - var properties = { - seriesId : this.model.get('id') - }; - - var self = this; - var commandPromise = CommandController.Execute(command, properties); - - commandPromise.fail(function (options) { - if (options.readyState === 0 || options.status === 0) { - return; - } - - Messenger.show({ - message: 'Season rename failed', - type : 'error' - }); - }); - - commandPromise.always(function () { - if (!self.isClosed) { - self.ui.rename.toggleClass('icon-nd-rename icon-nd-spinner'); - self.idle = true; - } + Actioneer.ExecuteCommand({ + command : 'renameSeries', + properties : { + seriesId : this.model.get('id') + }, + element : this.ui.rename, + failMessage: 'Series search failed' }); } }); diff --git a/UI/Shared/Actioneer.js b/UI/Shared/Actioneer.js new file mode 100644 index 000000000..be88033aa --- /dev/null +++ b/UI/Shared/Actioneer.js @@ -0,0 +1,85 @@ +'use strict'; +define(['Commands/CommandController', 'Shared/Messenger'], + function(CommandController, Messenger) { + return { + ExecuteCommand: function (options) { + options.iconClass = this._getIconClass(options.element); + + this._setSpinnerOnElement(options); + + var promise = CommandController.Execute(options.command, options.properties); + this._handlePromise(promise, options); + }, + + SaveModel: function (options) { + options.iconClass = this._getIconClass(options.element); + + this._setSpinnerOnElement(options); + var promise = options.context.model.save(); + + this._handlePromise(promise, options); + }, + + _handlePromise: function (promise, options) { + promise.done(function () { + if (options.successMessage) { + Messenger.show({ + message: options.successMessage + }); + } + + if (options.succesCallback) { + options.successCallback.call(options.context); + } + }); + + promise.fail(function (ajaxOptions) { + if (ajaxOptions.readyState === 0 || ajaxOptions.status === 0) { + return; + } + + if (options.failMessage) { + Messenger.show({ + message: options.failMessage, + type : 'error' + }); + } + + if (options.failCallback) { + options.failCallback.call(options.context); + } + }); + + promise.always(function () { + + if (options.leaveIcon) { + options.element.removeClass('icon-spin'); + } + + else { + options.element.addClass(options.iconClass); + options.element.removeClass('icon-nd-spinner'); + } + + if (options.alwaysCallback) { + options.alwaysCallback.call(options.context); + } + }); + }, + + _getIconClass: function(element) { + return element.attr('class').match(/(?:^|\s)icon\-.+?(?:$|\s)/)[0]; + }, + + _setSpinnerOnElement: function (options) { + if (options.leaveIcon) { + options.element.addClass('icon-spin'); + } + + else { + options.element.removeClass(options.iconClass); + options.element.addClass('icon-nd-spinner'); + } + } + } +});