diff --git a/NzbDrone.ncrunchsolution b/NzbDrone.ncrunchsolution index 6cb47a29a..444b34b1d 100644 --- a/NzbDrone.ncrunchsolution +++ b/NzbDrone.ncrunchsolution @@ -2,6 +2,7 @@ 1 False true + true UseDynamicAnalysis Disabled Disabled diff --git a/UI/AddSeries/AddSeriesLayout.js b/UI/AddSeries/AddSeriesLayout.js index 6f32ea754..b81a54f42 100644 --- a/UI/AddSeries/AddSeriesLayout.js +++ b/UI/AddSeries/AddSeriesLayout.js @@ -1,14 +1,16 @@ "use strict"; -define([ - 'app', - 'Quality/QualityProfileCollection', - 'AddSeries/RootFolders/RootFolderCollection', - 'AddSeries/RootFolders/RootFolderView', - 'AddSeries/AddSeriesView', - 'AddSeries/Existing/ImportSeriesView' -], - function (app, qualityProfileCollection, rootFolderCollection) { - NzbDrone.AddSeries.AddSeriesLayout = Backbone.Marionette.Layout.extend({ +define( + [ + 'app', + 'marionette', + 'AddSeries/RootFolders/Layout', + 'AddSeries/Existing/CollectionView', + 'AddSeries/AddSeriesView', + 'Quality/QualityProfileCollection', + 'AddSeries/RootFolders/Collection' + ], function (App, Marionette, RootFolderLayout, ExistingSeriesCollectionView, AddSeriesView, qualityProfileCollection, rootFolderCollection) { + + return Marionette.Layout.extend({ template: 'AddSeries/addSeriesLayoutTemplate', regions: { @@ -20,25 +22,24 @@ define([ }, initialize: function () { - this.rootFolderLayout = new NzbDrone.AddSeries.RootFolders.Layout(); + this.rootFolderLayout = new RootFolderLayout(); this.rootFolderLayout.on('folderSelected', this._folderSelected, this); + qualityProfileCollection.fetch(); + rootFolderCollection.fetch(); }, - _folderSelected: function (options) { - NzbDrone.modalRegion.closeModal(); - this.workspace.show(new NzbDrone.AddSeries.Existing.ListView({model: options.model})); + onShow: function () { + this.workspace.show(new AddSeriesView()); }, - onRender: function () { - qualityProfileCollection.fetch(); - rootFolderCollection.fetch(); - - this.workspace.show(new NzbDrone.AddSeries.AddSeriesView()); + _folderSelected: function (options) { + App.modalRegion.closeModal(); + this.workspace.show(new ExistingSeriesCollectionView({model: options.model})); }, _importSeries: function () { - NzbDrone.modalRegion.show(this.rootFolderLayout); + App.modalRegion.show(this.rootFolderLayout); } }); }); diff --git a/UI/AddSeries/AddSeriesView.js b/UI/AddSeries/AddSeriesView.js index df2fd8ceb..018c973f0 100644 --- a/UI/AddSeries/AddSeriesView.js +++ b/UI/AddSeries/AddSeriesView.js @@ -1,63 +1,68 @@ "use strict"; -define(['app', - 'AddSeries/RootFolders/RootFolderCollection', - 'AddSeries/SearchResultView', - 'Shared/SpinnerView', - 'AddSeries/Collection'], function () { - NzbDrone.AddSeries.AddSeriesView = Backbone.Marionette.Layout.extend({ - template: 'AddSeries/AddSeriesTemplate', - - ui: { - seriesSearch: '.x-series-search' - }, - - regions: { - searchResult: '#search-result' - }, - - initialize: function () { - this.collection = new NzbDrone.AddSeries.Collection(); - }, - - onRender: function () { - var self = this; - - this.ui.seriesSearch - .data('timeout', null) - .keyup(function () { +define( + [ + 'marionette', + 'AddSeries/Collection', + 'AddSeries/SearchResultCollectionView', + 'Shared/SpinnerView', + 'app', + 'AddSeries/RootFolders/Collection', + 'AddSeries/SearchResultView', + 'Shared/SpinnerView' + ], function (Marionette, AddSeriesCollection, SearchResultCollectionView, SpinnerView) { + return Marionette.Layout.extend({ + template: 'AddSeries/AddSeriesTemplate', + + ui: { + seriesSearch: '.x-series-search' + }, + + regions: { + searchResult: '#search-result' + }, + + initialize: function () { + this.collection = new AddSeriesCollection(); + }, + + onRender: function () { + var self = this; + + this.ui.seriesSearch.data('timeout', null).keyup(function () { window.clearTimeout(self.$el.data('timeout')); self.$el.data('timeout', window.setTimeout(self.search, 500, self)); }); - this.resultView = new NzbDrone.AddSeries.SearchResultCollectionView({ collection: this.collection }); - }, + this.resultView = new SearchResultCollectionView({ collection: this.collection }); + }, - search: function (context) { + search: function (context) { - context.abortExistingRequest(); + context.abortExistingRequest(); - var term = context.ui.seriesSearch.val(); - context.collection.reset(); + var term = context.ui.seriesSearch.val(); + context.collection.reset(); - if (term === '') { - context.searchResult.close(); - } else { - context.searchResult.show(new NzbDrone.Shared.SpinnerView()); + if (term === '') { + context.searchResult.close(); + } + else { + context.searchResult.show(new SpinnerView()); - context.currentSearchRequest = context.collection.fetch({ - data : { term: term }, - success: function () { - context.searchResult.show(context.resultView); - } - }); - } - }, + context.currentSearchRequest = context.collection.fetch({ + data : { term: term }, + success: function () { + context.searchResult.show(context.resultView); + } + }); + } + }, - abortExistingRequest: function () { - if (this.currentSearchRequest && this.currentSearchRequest.readyState > 0 && this.currentSearchRequest.readyState < 4) { - console.log('aborting previous pending search request.'); - this.currentSearchRequest.abort(); + abortExistingRequest: function () { + if (this.currentSearchRequest && this.currentSearchRequest.readyState > 0 && this.currentSearchRequest.readyState < 4) { + console.log('aborting previous pending search request.'); + this.currentSearchRequest.abort(); + } } - } + }); }); -}); diff --git a/UI/AddSeries/Collection.js b/UI/AddSeries/Collection.js index 7bb974fe2..c0c59b434 100644 --- a/UI/AddSeries/Collection.js +++ b/UI/AddSeries/Collection.js @@ -1,16 +1,21 @@ "use strict"; -define(['app', 'Series/SeriesModel'], function () { - NzbDrone.AddSeries.Collection = Backbone.Collection.extend({ - url : NzbDrone.Constants.ApiRoot + '/series/lookup', - model: NzbDrone.Series.SeriesModel, +define( + [ + 'App', + 'backbone', + 'Series/SeriesModel' + ], function (App, Backbone, SeriesModel) { + return Backbone.Collection.extend({ + url : Constants.ApiRoot + '/series/lookup', + model: SeriesModel, - parse: function (response) { + parse: function (response) { - _.each(response, function (model) { - model.id = undefined; - }); + _.each(response, function (model) { + model.id = undefined; + }); - return response; - } + return response; + } + }); }); -}); diff --git a/UI/AddSeries/Existing/CollectionView.js b/UI/AddSeries/Existing/CollectionView.js new file mode 100644 index 000000000..7198bfb68 --- /dev/null +++ b/UI/AddSeries/Existing/CollectionView.js @@ -0,0 +1,40 @@ +'use strict'; +define( + [ + 'marionette', + 'AddSeries/Existing/CompositeView', + 'AddSeries/Existing/UnmappedFolderCollection' + ], function (Marionette, UnmappedFolderCompositeView, UnmappedFolderCollection) { + + return Marionette.CollectionView.extend({ + + itemView: UnmappedFolderCompositeView, + + initialize: function () { + this.collection = new UnmappedFolderCollection(); + this.refreshItems(); + }, + + refreshItems: function () { + this.collection.importItems(this.model); + }, + + showCollection: function () { + this._showAndSearch(0); + }, + + _showAndSearch: function (index) { + + var model = this.collection.at(index); + if (model) { + var that = this; + var currentIndex = index; + this.addItemView(model, this.getItemView(), index); + $.when(this.children.findByModel(model).search()).then(function () { + that._showAndSearch(currentIndex + 1); + }); + } + } + + }); + }); diff --git a/UI/AddSeries/Existing/CompositeView.js b/UI/AddSeries/Existing/CompositeView.js new file mode 100644 index 000000000..339a8bb2d --- /dev/null +++ b/UI/AddSeries/Existing/CompositeView.js @@ -0,0 +1,106 @@ +'use strict'; +define( + [ + 'marionette', + 'AddSeries/Collection', + 'AddSeries/SearchResultView' + ], function (Marionette, AddSeriesCollection, SearchResultView) { + + return Marionette.CompositeView.extend({ + + template : 'AddSeries/Existing/UnmappedFolderCompositeViewTemplate', + itemViewContainer: '.x-folder-name-match-results', + itemView : SearchResultView, + + events: { + 'click .x-btn-search' : 'search', + 'click .x-load-more' : '_loadMore', + 'keydown .x-txt-search': 'keyDown' + }, + + ui: { + searchButton: '.x-btn-search', + searchText : '.x-txt-search', + searchBar : '.x-search-bar', + loadMore : '.x-load-more' + }, + + initialize: function () { + this.collection = new AddSeriesCollection(); + + this.on("item:removed", function () { + this.close(); + }, this); + }, + + onRender: function () { + this.ui.loadMore.show(); + }, + + search: function () { + var icon = this.ui.searchButton.find('icon'); + icon.removeClass('icon-search').addClass('icon-spin icon-spinner disabled'); + + var self = this; + var deferred = $.Deferred(); + + this.collection.reset(); + + this.searchCollection = new AddSeriesCollection(); + + this.searchCollection.fetch({ + data : { term: this.ui.searchText.val() }, + success: function () { + icon.removeClass('icon-spin icon-spinner disabled').addClass('icon-search'); + deferred.resolve(); + self.collection.add(self.searchCollection.shift()); + + if (self.showall) { + self._showAll(); + } + + }, + fail : function () { + icon.removeClass('icon-spin icon-spinner disabled').addClass('icon-search'); + deferred.reject(); + } + }); + + return deferred.promise(); + }, + + + keyDown: function (e) { + //Check for enter being pressed + var code = (e.keyCode ? e.keyCode :e.which); + if (code === 13) { + this.search(); + } + }, + + _loadMore: function () { + this.showall = true; + + this.ui.searchBar.fadeIn(); + this.ui.loadMore.fadeOut(); + + this._showAll(); + }, + + _showAll: function () { + var self = this; + this.searchCollection.each(function (searchResult) { + self.collection.add(searchResult); + }); + }, + + itemViewOptions: function () { + return { + rootFolder: this.model.get('rootFolder'), + folder : this.model.get('folder').path, + isExisting: true + }; + } + }); + + }); diff --git a/UI/AddSeries/Existing/ImportSeriesView.js b/UI/AddSeries/Existing/ImportSeriesView.js deleted file mode 100644 index b508e218f..000000000 --- a/UI/AddSeries/Existing/ImportSeriesView.js +++ /dev/null @@ -1,139 +0,0 @@ -'use strict'; -define([ - 'app', 'AddSeries/RootFolders/RootFolderCollection', - 'AddSeries/Existing/UnmappedFolderModel', - 'AddSeries/Collection', - 'AddSeries/SearchResultView', - 'Series/SeriesModel'], function () { - - NzbDrone.AddSeries.Existing.UnmappedFolderCompositeView = Backbone.Marionette.CompositeView.extend({ - - template : 'AddSeries/Existing/UnmappedFolderCompositeViewTemplate', - itemViewContainer: '.x-folder-name-match-results', - itemView : NzbDrone.AddSeries.SearchResultView, - - events: { - 'click .x-btn-search' : 'search', - 'click .x-load-more' : '_loadMore', - 'keydown .x-txt-search': 'keyDown' - }, - - ui: { - searchButton: '.x-btn-search', - searchText : '.x-txt-search', - searchBar : '.x-search-bar', - loadMore : '.x-load-more' - }, - - initialize: function () { - this.collection = new NzbDrone.AddSeries.Collection(); - this.collection.bind('reset', this.collectionReset, this); - - this.on("item:removed", function () { - this.close(); - }, this); - }, - - onRender: function () { - this.ui.loadMore.show(); - }, - - search: function () { - var icon = this.ui.searchButton.find('icon'); - icon.removeClass('icon-search').addClass('icon-spin icon-spinner disabled'); - - var self = this; - var deferred = $.Deferred(); - - this.collection.reset(); - - this.searchCollection = new NzbDrone.AddSeries.Collection(); - - this.searchCollection.fetch({ - data : { term: this.ui.searchText.val() }, - success: function () { - icon.removeClass('icon-spin icon-spinner disabled').addClass('icon-search'); - deferred.resolve(); - self.collection.add(self.searchCollection.shift()); - - if (self.showall) { - self._showAll(); - } - - }, - fail : function () { - icon.removeClass('icon-spin icon-spinner disabled').addClass('icon-search'); - deferred.reject(); - } - }); - - return deferred.promise(); - }, - - - keyDown: function (e) { - //Check for enter being pressed - var code = (e.keyCode ? e.keyCode :e.which); - if (code === 13) { - this.search(); - } - }, - - _loadMore: function () { - this.showall = true; - - this.ui.searchBar.fadeIn(); - this.ui.loadMore.fadeOut(); - - this._showAll(); - }, - - _showAll: function () { - var self = this; - this.searchCollection.each(function (searchResult) { - self.collection.add(searchResult); - }); - }, - - itemViewOptions: function () { - return { - rootFolder : this.model.get('rootFolder'), - folder : this.model.get('folder').path, - isExisting : true - }; - } - }); - - NzbDrone.AddSeries.Existing.ListView = Backbone.Marionette.CollectionView.extend({ - - itemView: NzbDrone.AddSeries.Existing.UnmappedFolderCompositeView, - - initialize: function () { - this.collection = new NzbDrone.AddSeries.Existing.UnmappedFolderCollection(); - this.refreshItems(); - }, - - refreshItems: function () { - this.collection.importItems(this.model); - }, - - showCollection: function () { - this.showAndSearch(0); - }, - - showAndSearch: function (index) { - - var model = this.collection.at(index); - if (model) { - var that = this; - var currentIndex = index; - this.addItemView(model, this.getItemView(), index); - $.when(this.children.findByModel(model).search()) - .then(function () { - that.showAndSearch(currentIndex + 1); - }); - } - } - - }); -}); diff --git a/UI/AddSeries/Existing/UnmappedFolderCollection.js b/UI/AddSeries/Existing/UnmappedFolderCollection.js new file mode 100644 index 000000000..a6328a521 --- /dev/null +++ b/UI/AddSeries/Existing/UnmappedFolderCollection.js @@ -0,0 +1,23 @@ +'use strict'; +define( + [ + 'backbone', + 'AddSeries/Existing/UnmappedFolderModel' + ], function (Backbone, UnmappedFolderModel) { + return Backbone.Collection.extend({ + model: UnmappedFolderModel, + + importItems: function (rootFolderModel) { + + this.reset(); + var rootFolder = rootFolderModel; + + _.each(rootFolderModel.get('unmappedFolders'), function (folder) { + this.push(new UnmappedFolderModel({ + rootFolder: rootFolder, + folder : folder + })); + }, this); + } + }); + }); diff --git a/UI/AddSeries/Existing/UnmappedFolderModel.js b/UI/AddSeries/Existing/UnmappedFolderModel.js index 58815c535..f78c6d2cd 100644 --- a/UI/AddSeries/Existing/UnmappedFolderModel.js +++ b/UI/AddSeries/Existing/UnmappedFolderModel.js @@ -1,21 +1,10 @@ 'use strict'; -define(['app'], function () { +define( + [ + 'backbone' + ], function (Backbone) { + return Backbone.Model.extend({ - NzbDrone.AddSeries.Existing.UnmappedFolderModel = Backbone.Model.extend({ + }); }); - - NzbDrone.AddSeries.Existing.UnmappedFolderCollection = Backbone.Collection.extend({ - model: NzbDrone.AddSeries.Existing.UnmappedFolderModel, - - importItems: function (rootFolderModel) { - - this.reset(); - var rootFolder = rootFolderModel;//.get('path'); - - _.each(rootFolderModel.get('unmappedFolders'), function (folder) { - this.push(new NzbDrone.AddSeries.Existing.UnmappedFolderModel({ rootFolder: rootFolder, folder: folder})); - }, this); - } - }); -}); diff --git a/UI/AddSeries/RootFolders/Collection.js b/UI/AddSeries/RootFolders/Collection.js new file mode 100644 index 000000000..91bb78cac --- /dev/null +++ b/UI/AddSeries/RootFolders/Collection.js @@ -0,0 +1,15 @@ +"use strict"; +define( + [ + 'app', + 'AddSeries/RootFolders/Model', + 'mixins/backbone.signalr.mixin' + ], function () { + + var rootFolderCollection = Backbone.Collection.extend({ + url : NzbDrone.Constants.ApiRoot + '/rootfolder', + model: NzbDrone.AddSeries.RootFolders.RootFolderModel + }); + + return new rootFolderCollection().BindSignalR(); + }); diff --git a/UI/AddSeries/RootFolders/CollectionView.js b/UI/AddSeries/RootFolders/CollectionView.js new file mode 100644 index 000000000..06220c45a --- /dev/null +++ b/UI/AddSeries/RootFolders/CollectionView.js @@ -0,0 +1,16 @@ +"use strict"; + +define( + [ + 'marionette', + 'AddSeries/RootFolders/ItemView' + ], function (Marionette, RootFolderItemView) { + + + return Marionette.CollectionView.extend({ + itemView: RootFolderItemView, + + tagName : 'table', + className: 'table table-hover' + }); + }); diff --git a/UI/AddSeries/RootFolders/ItemView.js b/UI/AddSeries/RootFolders/ItemView.js new file mode 100644 index 000000000..7636ebd45 --- /dev/null +++ b/UI/AddSeries/RootFolders/ItemView.js @@ -0,0 +1,27 @@ +"use strict"; + +define( + [ + 'marionette' + ], function (Marionette) { + + return Marionette.ItemView.extend({ + + template: 'AddSeries/RootFolders/RootFolderItemTemplate', + tagName : 'tr', + + events: { + 'click .x-remove': 'removeFolder', + 'click .x-folder': 'folderSelected' + }, + + removeFolder: function () { + this.model.destroy({ wait: true }); + this.model.collection.remove(this.model); + }, + + folderSelected: function () { + this.trigger('folderSelected', this.model); + } + }); + }); diff --git a/UI/AddSeries/RootFolders/Layout.js b/UI/AddSeries/RootFolders/Layout.js new file mode 100644 index 000000000..6d4f18ce7 --- /dev/null +++ b/UI/AddSeries/RootFolders/Layout.js @@ -0,0 +1,57 @@ +"use strict"; + +define( + [ + 'marionette', + 'AddSeries/RootFolders/CollectionView', + 'AddSeries/RootFolders/Model', + 'AddSeries/RootFolders/Collection', + 'Mixins/AutoComplete' + ], function (Marionette, RootFolderCollectionView, RootFolderCollection, RootFolderModel) { + + return Marionette.Layout.extend({ + template: 'AddSeries/RootFolders/LayoutTemplate', + + ui: { + pathInput: '.x-path input' + }, + + regions: { + currentDirs: '#current-dirs' + }, + + events: { + 'click .x-add': 'addFolder' + }, + + initialize: function () { + this.collection = RootFolderCollection; + this.rootfolderListView = new RootFolderCollectionView({ collection: RootFolderCollection }); + this.rootfolderListView.on('itemview:folderSelected', this._onFolderSelected, this); + }, + + + onRender: function () { + + this.currentDirs.show(this.rootfolderListView); + this.ui.pathInput.autoComplete('/directories'); + }, + + _onFolderSelected: function (options) { + this.trigger('folderSelected', options); + }, + + addFolder: function () { + var newDir = new RootFolderModel({ + Path: this.ui.pathInput.val() + }); + + RootFolderCollection.create(newDir, { + wait: true, success: function () { + RootFolderCollection.fetch(); + } + }); + } + }); + + }); diff --git a/UI/AddSeries/RootFolders/RootFolderModel.js b/UI/AddSeries/RootFolders/Model.js similarity index 98% rename from UI/AddSeries/RootFolders/RootFolderModel.js rename to UI/AddSeries/RootFolders/Model.js index e3f6b40b3..9719c997f 100644 --- a/UI/AddSeries/RootFolders/RootFolderModel.js +++ b/UI/AddSeries/RootFolders/Model.js @@ -11,4 +11,4 @@ define(['app'], function () { freeSpace: 0 } }); -}); \ No newline at end of file +}); diff --git a/UI/AddSeries/RootFolders/RootFolderCollection.js b/UI/AddSeries/RootFolders/RootFolderCollection.js deleted file mode 100644 index d6d20c471..000000000 --- a/UI/AddSeries/RootFolders/RootFolderCollection.js +++ /dev/null @@ -1,10 +0,0 @@ -"use strict"; -define(['app', 'AddSeries/RootFolders/RootFolderModel','mixins/backbone.signalr.mixin'], function () { - - var rootFolderCollection = Backbone.Collection.extend({ - url : NzbDrone.Constants.ApiRoot + '/rootfolder', - model: NzbDrone.AddSeries.RootFolders.RootFolderModel - }); - - return new rootFolderCollection().BindSignalR(); -}); diff --git a/UI/AddSeries/RootFolders/RootFolderTemplateHelper.js b/UI/AddSeries/RootFolders/RootFolderTemplateHelper.js index 85f6a7aeb..d49483b42 100644 --- a/UI/AddSeries/RootFolders/RootFolderTemplateHelper.js +++ b/UI/AddSeries/RootFolders/RootFolderTemplateHelper.js @@ -1,11 +1,13 @@ 'use strict'; -define(['app', 'AddSeries/RootFolders/RootFolderCollection','handlebars'], function (app, rootFolders, Handlebars) { +define( + [ + 'AddSeries/RootFolders/Collection', + 'handlebars' + ], function (rootFolders, Handlebars) { - Handlebars.registerHelper('rootFolderSelection', function () { - //TODO: We should be able to pass in the context, either an object or a property - - var templateFunction = Marionette.TemplateCache.get('AddSeries/RootFolders/RootFolderSelectionTemplate'); - return new Handlebars.SafeString(templateFunction(rootFolders.toJSON())); + Handlebars.registerHelper('rootFolderSelection', function () { + var templateFunction = Marionette.TemplateCache.get('AddSeries/RootFolders/RootFolderSelectionTemplate'); + return new Handlebars.SafeString(templateFunction(rootFolders.toJSON())); + }); }); -}); diff --git a/UI/AddSeries/RootFolders/RootFolderView.js b/UI/AddSeries/RootFolders/RootFolderView.js deleted file mode 100644 index 6b18a0b62..000000000 --- a/UI/AddSeries/RootFolders/RootFolderView.js +++ /dev/null @@ -1,79 +0,0 @@ -"use strict"; - -define(['app', 'AddSeries/RootFolders/RootFolderCollection', 'Mixins/AutoComplete'], function (app, rootFolders) { - - NzbDrone.AddSeries.RootFolderItemView = Backbone.Marionette.ItemView.extend({ - - template: 'AddSeries/RootFolders/RootFolderItemTemplate', - tagName : 'tr', - - events: { - 'click .x-remove': 'removeFolder', - 'click .x-folder': 'folderSelected' - }, - - removeFolder: function () { - this.model.destroy({ wait: true }); - this.model.collection.remove(this.model); - }, - - folderSelected: function () { - this.trigger('folderSelected', this.model); - } - }); - - NzbDrone.AddSeries.RootDirListView = Backbone.Marionette.CollectionView.extend({ - itemView: NzbDrone.AddSeries.RootFolderItemView, - - tagName : 'table', - className: 'table table-hover' - }); - - NzbDrone.AddSeries.RootFolders.Layout = Backbone.Marionette.Layout.extend({ - template: 'AddSeries/RootFolders/LayoutTemplate', - - ui: { - pathInput: '.x-path input' - }, - - regions: { - currentDirs: '#current-dirs' - }, - - events: { - 'click .x-add': 'addFolder' - }, - - initialize: function () { - this.collection = rootFolders; - this.rootfolderListView = new NzbDrone.AddSeries.RootDirListView({ collection: rootFolders }); - this.rootfolderListView.on('itemview:folderSelected', this._onFolderSelected, this); - }, - - - onRender: function () { - - this.currentDirs.show(this.rootfolderListView); - this.ui.pathInput.autoComplete('/directories'); - }, - - _onFolderSelected: function (options) { - this.trigger('folderSelected', options); - }, - - addFolder: function () { - var newDir = new NzbDrone.AddSeries.RootFolders.RootFolderModel( - { - Path: this.ui.pathInput.val() - }); - - - rootFolders.create(newDir, { - wait: true, success: function () { - rootFolders.fetch(); - } - }); - } - }); - -}); diff --git a/UI/AddSeries/SearchResultCollectionView.js b/UI/AddSeries/SearchResultCollectionView.js new file mode 100644 index 000000000..986ba60c6 --- /dev/null +++ b/UI/AddSeries/SearchResultCollectionView.js @@ -0,0 +1,16 @@ +'use strict'; +define( + [ + 'marionette', + 'AddSeries/SearchResultView' + ], function (Marionette, SearchResultView) { + + return Marionette.CollectionView.extend({ + + itemView : SearchResultView, + initialize: function () { + this.listenTo(this.collection, 'reset', this.render); + } + + }); + }); diff --git a/UI/AddSeries/SearchResultView.js b/UI/AddSeries/SearchResultView.js index df1b5404b..242370f7d 100644 --- a/UI/AddSeries/SearchResultView.js +++ b/UI/AddSeries/SearchResultView.js @@ -1,101 +1,95 @@ 'use strict'; -define(['app', - 'Quality/QualityProfileCollection', - 'Config', - 'Series/SeriesCollection', - 'AddSeries/RootFolders/RootFolderTemplateHelper', - 'Quality/QualityProfileTemplateHelper'], function (app, qualityProfiles) { - - NzbDrone.AddSeries.SearchResultView = Backbone.Marionette.ItemView.extend({ - - template: "AddSeries/SearchResultTemplate", - - ui: { - qualityProfile: '.x-quality-profile', - rootFolder : '.x-root-folder', - addButton : '.x-add', - overview : '.x-overview' - }, - - events: { - 'click .x-add' : 'addSeries', - 'change .x-quality-profile': '_qualityProfileChanged' - }, - - initialize: function () { - - if (!this.model) { - throw 'model is required'; - } - - this.model.set('isExisting', this.options.isExisting); - this.model.set('path', this.options.folder); - - NzbDrone.vent.on(NzbDrone.Config.Events.ConfigUpdatedEvent, this._onConfigUpdated, this); - }, +define( + [ + 'app', + 'marionette', + 'Config', + 'Series/SeriesCollection', + 'Shared/Messenger', + 'Quality/QualityProfileCollection' + ], function (App, Marionette, Config, SeriesCollection, Messenger, QualityProfiles) { + + return Marionette.ItemView.extend({ + + template: "AddSeries/SearchResultTemplate", + + ui: { + qualityProfile: '.x-quality-profile', + rootFolder : '.x-root-folder', + addButton : '.x-add', + overview : '.x-overview' + }, + + events: { + 'click .x-add' : 'addSeries', + 'change .x-quality-profile': '_qualityProfileChanged' + }, + + initialize: function () { + + if (!this.model) { + throw 'model is required'; + } + this.model.set('isExisting', this.options.isExisting); + this.model.set('path', this.options.folder); - _onConfigUpdated: function (options) { + App.vent.on(Config.Events.ConfigUpdatedEvent, this._onConfigUpdated, this); + }, - if (options.key === NzbDrone.Config.Keys.DefaultQualityProfileId) { - this.$('.x-quality-profile').val(options.value); - } - }, - _qualityProfileChanged: function () { - NzbDrone.Config.SetValue(NzbDrone.Config.Keys.DefaultQualityProfileId, this.ui.qualityProfile.val()); - }, + _onConfigUpdated: function (options) { - onRender: function () { - this.listenTo(this.model, 'change', this.render); + if (options.key === Config.Keys.DefaultQualityProfileId) { + this.$('.x-quality-profile').val(options.value); + } + }, - var defaultQuality = NzbDrone.Config.GetValue(NzbDrone.Config.Keys.DefaultQualityProfileId); + _qualityProfileChanged: function () { + Config.SetValue(Config.Keys.DefaultQualityProfileId, this.ui.qualityProfile.val()); + }, - if (qualityProfiles.get(defaultQuality)) { - this.ui.qualityProfile.val(defaultQuality); - } - }, + onRender: function () { + this.listenTo(this.model, 'change', this.render); + var defaultQuality = Config.GetValue(Config.Keys.DefaultQualityProfileId); - addSeries: function () { - var icon = this.ui.addButton.find('icon'); - icon.removeClass('icon-plus').addClass('icon-spin icon-spinner disabled'); + if (QualityProfiles.get(defaultQuality)) { + this.ui.qualityProfile.val(defaultQuality); + } + }, - var quality = this.ui.qualityProfile.val(); - var rootFolderPath = this.ui.rootFolder.children(':selected').text(); - this.model.set('qualityProfileId', quality); - this.model.set('rootFolderPath', rootFolderPath); + addSeries: function () { + var icon = this.ui.addButton.find('icon'); + icon.removeClass('icon-plus').addClass('icon-spin icon-spinner disabled'); - var self = this; + var quality = this.ui.qualityProfile.val(); + var rootFolderPath = this.ui.rootFolder.children(':selected').text(); - this.model.save(undefined, { - url : NzbDrone.Series.SeriesCollection.prototype.url, - success: function () { - self.close(); - icon.removeClass('icon-spin icon-spinner disabled').addClass('icon-search'); - NzbDrone.Shared.Messenger.show({ - message: 'Added: ' + self.model.get('title') - }); + this.model.set('qualityProfileId', quality); + this.model.set('rootFolderPath', rootFolderPath); - NzbDrone.vent.trigger(NzbDrone.Events.SeriesAdded, { series: self.model }); - self.model.collection.remove(self.model); - }, - fail : function () { - icon.removeClass('icon-spin icon-spinner disabled').addClass('icon-search'); - } - }); - } - }); + var self = this; + this.model.save(undefined, { + url : SeriesCollection.prototype.url, + success: function () { + self.close(); + icon.removeClass('icon-spin icon-spinner disabled').addClass('icon-search'); + Messenger.show({ + message: 'Added: ' + self.model.get('title') + }); - NzbDrone.AddSeries.SearchResultCollectionView = Backbone.Marionette.CollectionView.extend({ + App.vent.trigger(App.Events.SeriesAdded, { series: self.model }); + self.model.collection.remove(self.model); + }, + fail : function () { + icon.removeClass('icon-spin icon-spinner disabled').addClass('icon-search'); + } + }); + } + }); - itemView : NzbDrone.AddSeries.SearchResultView, - initialize: function () { - this.listenTo(this.collection, 'reset', this.render); - } }); - -}); diff --git a/UI/Config.js b/UI/Config.js index ec6e83fb9..50a6e9120 100644 --- a/UI/Config.js +++ b/UI/Config.js @@ -1,37 +1,42 @@ "use strict"; -define(['app'], function () { +define( + [ + 'app' + ], function () { - NzbDrone.Config = { - Events: { - ConfigUpdatedEvent: 'ConfigUpdatedEvent' - }, - Keys : { - DefaultQualityProfileId: 'DefaultQualityProfileId' - } - }; + NzbDrone.Config = { + Events: { + ConfigUpdatedEvent: 'ConfigUpdatedEvent' + }, + Keys : { + DefaultQualityProfileId: 'DefaultQualityProfileId' + } + }; - NzbDrone.Config.GetValue = function (key, defaultValue) { + NzbDrone.Config.GetValue = function (key, defaultValue) { - var storeValue = localStorage.getItem(key); + var storeValue = localStorage.getItem(key); - if (!storeValue) { - return defaultValue; - } + if (!storeValue) { + return defaultValue; + } - return storeValue.toString(); - }; + return storeValue.toString(); + }; - NzbDrone.Config.SetValue = function (key, value) { + NzbDrone.Config.SetValue = function (key, value) { - console.log('Config: [{0}] => [{1}] '.format(key, value)); + console.log('Config: [{0}] => [{1}] '.format(key, value)); - if (NzbDrone.Config.GetValue(key) === value.toString()) { - return; - } + if (NzbDrone.Config.GetValue(key) === value.toString()) { + return; + } - localStorage.setItem(key, value); - NzbDrone.vent.trigger(NzbDrone.Config.Events.ConfigUpdatedEvent, {key: key, value: value}); + localStorage.setItem(key, value); + NzbDrone.vent.trigger(NzbDrone.Config.Events.ConfigUpdatedEvent, {key: key, value: value}); - }; + }; -}); + return NzbDrone.Config; + + }); diff --git a/UI/RouteBinder.js b/UI/RouteBinder.js index bbd7d4874..6710099a8 100644 --- a/UI/RouteBinder.js +++ b/UI/RouteBinder.js @@ -1,12 +1,15 @@ "use strict"; -define(['app'], function () { +define(function () { //This module will automatically route all links through backbone router rather than //causing links to reload pages. var routeBinder = { - bind: function () { + bind: function (router) { + + this._router = router; + $(document).on('click', 'a[href]', this._handleClick); }, @@ -44,7 +47,7 @@ define(['app'], function () { if (!href.startsWith('http')) { - NzbDrone.Router.navigate(href, { trigger: true }); + this._router.navigate(href, { trigger: true }); } else { diff --git a/UI/Router.js b/UI/Router.js new file mode 100644 index 000000000..37df317cd --- /dev/null +++ b/UI/Router.js @@ -0,0 +1,29 @@ +"use strict"; +require( + [ + 'marionette', + 'Controller' + ], function (Marionette, Controller) { + + return Marionette.AppRouter.extend({ + + controller: Controller, + appRoutes : { + '' : 'series', + 'series' : 'series', + 'series/index' : 'series', + 'series/add' : 'addSeries', + 'series/add/:action(/:query)': 'addSeries', + 'series/details/:query' : 'seriesDetails', + 'calendar' : 'calendar', + 'settings' : 'settings', + 'settings/:action(/:query)' : 'settings', + 'missing' : 'missing', + 'history' : 'history', + 'logs' : 'logs', + 'rss' : 'rss', + ':whatever' : 'notFound' + } + }); + }); + diff --git a/UI/Routing.js b/UI/Routing.js deleted file mode 100644 index fd28b0a16..000000000 --- a/UI/Routing.js +++ /dev/null @@ -1,34 +0,0 @@ -"use strict"; -require(['Controller', 'RouteBinder', 'Shared/Footer/View'], function (Controller, RouteBinder, FooterView) { - - NzbDrone.Router = Backbone.Marionette.AppRouter.extend({ - - controller: Controller, - appRoutes : { - '' : 'series', - 'series' : 'series', - 'series/index' : 'series', - 'series/add' : 'addSeries', - 'series/add/:action(/:query)': 'addSeries', - 'series/details/:query' : 'seriesDetails', - 'calendar' : 'calendar', - 'settings' : 'settings', - 'settings/:action(/:query)' : 'settings', - 'missing' : 'missing', - 'history' : 'history', - 'logs' : 'logs', - 'rss' : 'rss', - ':whatever' : 'notFound' - } - }); - - NzbDrone.addInitializer(function () { - - NzbDrone.Router = new NzbDrone.Router(); - Backbone.history.start({ pushState: true }); - - RouteBinder.bind(); - NzbDrone.footerRegion.show(new FooterView()); - }); -}); - diff --git a/UI/ServerStatus.js b/UI/ServerStatus.js index 1ce174ef4..a23f90837 100644 --- a/UI/ServerStatus.js +++ b/UI/ServerStatus.js @@ -1,7 +1,7 @@ var statusText = $.ajax({ type : "GET", - url : 'api/system/status', - async: false, + url : '/api/system/status', + async: false }).responseText; window.ServerStatus = JSON.parse(statusText); diff --git a/UI/Shared/FormatHelpers.js b/UI/Shared/FormatHelpers.js index 367077071..87cf95eb8 100644 --- a/UI/Shared/FormatHelpers.js +++ b/UI/Shared/FormatHelpers.js @@ -32,4 +32,6 @@ define(['app'], function () { return date.format('{MM}/{dd}/{yyyy}'); }; + + return NzbDrone.Shared.FormatHelpers; }); diff --git a/UI/Shared/SpinnerView.js b/UI/Shared/SpinnerView.js index 704e71517..785657699 100644 --- a/UI/Shared/SpinnerView.js +++ b/UI/Shared/SpinnerView.js @@ -1,10 +1,15 @@ "use strict"; -define(['app'], function () { - NzbDrone.Shared.SpinnerView = Backbone.Marionette.ItemView.extend({ - template : 'Shared/SpinnerTemplate', - className: 'nz-spinner row' +define( + [ + 'app' + ], function () { + NzbDrone.Shared.SpinnerView = Backbone.Marionette.ItemView.extend({ + template : 'Shared/SpinnerTemplate', + className: 'nz-spinner row' + }); + + return NzbDrone.Shared.SpinnerView; }); -}); diff --git a/UI/Shared/TemplateHelpers.js b/UI/Shared/TemplateHelpers.js index 2865974d3..6a2881e62 100644 --- a/UI/Shared/TemplateHelpers.js +++ b/UI/Shared/TemplateHelpers.js @@ -1,6 +1,6 @@ "use strict"; -define(['app','handlebars'], function (App,Handlebars) { +define(['app','handlebars','Shared/FormatHelpers'], function (App,Handlebars) { Handlebars.registerHelper('partial', function (templateName) { //TODO: We should be able to pass in the context, either an object or a property diff --git a/UI/Shared/Toolbar/Radio/RadioButtonCollectionView.js b/UI/Shared/Toolbar/Radio/RadioButtonCollectionView.js index 3a97c518a..f0c387cc8 100644 --- a/UI/Shared/Toolbar/Radio/RadioButtonCollectionView.js +++ b/UI/Shared/Toolbar/Radio/RadioButtonCollectionView.js @@ -1,34 +1,39 @@ "use strict"; -define(['app', 'Shared/Toolbar/Radio/RadioButtonView', 'Config'], function () { - NzbDrone.Shared.Toolbar.RadioButtonCollectionView = Backbone.Marionette.CollectionView.extend({ - className: 'btn-group', - itemView : NzbDrone.Shared.Toolbar.RadioButtonView, +define( + [ + 'app', + 'Shared/Toolbar/Radio/RadioButtonView', + 'Config' + ], function (App, RadioButtonView, Config) { + NzbDrone.Shared.Toolbar.RadioButtonCollectionView = Backbone.Marionette.CollectionView.extend({ + className: 'btn-group', + itemView : NzbDrone.Shared.Toolbar.RadioButtonView, - attributes: { - 'data-toggle': 'buttons-radio' - }, + attributes: { + 'data-toggle': 'buttons-radio' + }, - initialize: function (options) { - this.menu = options.menu; + initialize: function (options) { + this.menu = options.menu; - if (this.menu.storeState) { - this.setActive(); - } - }, + if (this.menu.storeState) { + this.setActive(); + } + }, - setActive: function () { - var storedKey = NzbDrone.Config.GetValue(this.menu.menuKey, this.menu.defaultAction); + setActive: function () { + var storedKey = Config.GetValue(this.menu.menuKey, this.menu.defaultAction); - this.collection.each(function (model) { - if (model.get('key').toLocaleLowerCase() === storedKey.toLowerCase()) { - model.set('active', true); - } - else { - model.set('active, false'); - } - }); - } + this.collection.each(function (model) { + if (model.get('key').toLocaleLowerCase() === storedKey.toLowerCase()) { + model.set('active', true); + } + else { + model.set('active, false'); + } + }); + } + }); }); -}); diff --git a/UI/app.js b/UI/app.js index 35fe8b317..b7cd9f031 100644 --- a/UI/app.js +++ b/UI/app.js @@ -1,7 +1,7 @@ "use strict"; require.config({ - urlArgs: 'bust=' + window.ServerStatus.version, + urlArgs: 'v=' + window.ServerStatus.version, paths: { 'backbone' : 'JsLibraries/backbone', @@ -22,6 +22,7 @@ require.config({ 'marionette' : 'JsLibraries/backbone.marionette', 'signalR' : 'JsLibraries/jquery.signalR', 'libs' : 'JsLibraries/' + }, shim: { @@ -147,9 +148,10 @@ define( [ 'marionette', 'shared/modal/region', + 'router', 'Instrumentation/StringFormat', 'Instrumentation/ErrorHandler' - ], function (Marionette, ModalRegion) { + ], function (Marionette, ModalRegion, Router, RouteBinder) { require( [ @@ -234,6 +236,13 @@ define( window.NzbDrone.start(); + NzbDrone.Router = new Router(); + Backbone.history.start({ pushState: true }); + + RouteBinder.bind(NzbDrone.Router); + //NzbDrone.footerRegion.show(new FooterView()); + + window.require( [ 'Routing'