1
0
mirror of https://github.com/Radarr/Radarr.git synced 2024-11-05 02:22:31 +01:00

MovieIndexPage Stability + MovieEditor fix (#925)

* this fixes some issues where the table
was rendering with incorrect data
prior to it being updated....

it also has the FullCollection fetched when necessary..

this will make the movie Index be accurate even after deleting files
or when returning from the movieEditor..

The footer has been improved and since
FullMovieCollection is now kept up to date the footer changes
as the user performs operations and it shows all the time with proper info
even after deletions or changes made in the movieEditor.

Prior to this it was necessary to totally refresh the page..

switching between movie editor and movie index would give unpredicatable results.

these issues have been fixed

* this is a much better solution...

still testing, but likel ready to be merged

* removing comments

* fix the movieEditor -- client side paging in movieEditor

* major code cleanup, and a slightly better implementation
no need to use FullMovieCollection..

just use moviesCollection.fullCollection when in client mode

* display a message when saving is done

perhaps eventually we can have a spinning status indicator on the
save button.. but that is not necessary right away

* some minor adjustments

* remove parseInt for tmdbId

* fix bugs

* remove some alerts

* accidentally changes this on last commit

* use the same FullMovieList everywhere

* add back alert when save is done
This commit is contained in:
geogolem 2017-02-28 19:46:00 -05:00 committed by Devin Buhl
parent 1c086b057a
commit 392d63fe57
16 changed files with 190 additions and 92 deletions

View File

@ -214,7 +214,10 @@ protected TResource ReadResourceFromRequest(bool skipValidate = false)
private PagingResource<TResource> ReadPagingResourceFromRequest()
{
int pageSize;
int.TryParse(Request.Query.PageSize.ToString(), out pageSize);
if (!int.TryParse(Request.Query.PageSize.ToString(), out pageSize))
{
pageSize = 100000;
}
if (pageSize == 0) pageSize = 10;
int page;

View File

@ -2,7 +2,9 @@ var $ = require('jquery');
var _ = require('underscore');
var SelectAllCell = require('../../Cells/SelectAllCell');
var Backgrid = require('backgrid');
var FullMovieCollection = require('../../Movies/FullMovieCollection');
//var FullMovieCollection = require('../../Movies/FullMovieCollection');
var MoviesCollectionClient = require('../../Movies/MoviesCollectionClient');
module.exports = SelectAllCell.extend({
_originalRender : SelectAllCell.prototype.render,
@ -13,7 +15,7 @@ module.exports = SelectAllCell.extend({
this._originalInit.apply(this, arguments);
var tmdbId = this.model.get('tmdbId');
var existingMovie = FullMovieCollection.where({ tmdbId: tmdbId });
var existingMovie = MoviesCollectionClient.fullCollection.where({ tmdbId: tmdbId });
this.isDuplicate = existingMovie.length > 0 ? true : false;
this.listenTo(this.model, 'change', this._refresh);

View File

@ -1,6 +1,7 @@
var Marionette = require('marionette');
var SearchResultView = require('./SearchResultView');
var FullMovieCollection = require('../Movies/FullMovieCollection');
//var FullMovieCollection = require('../Movies/FullMovieCollection');
var MoviesCollectionClient = require('../Movies/MoviesCollectionClient');
var vent = require('vent');
module.exports = Marionette.CollectionView.extend({
@ -48,7 +49,7 @@ module.exports = Marionette.CollectionView.extend({
appendHtml : function(collectionView, itemView, index) {
var tmdbId = itemView.model.get('tmdbId');
var existingMovies = FullMovieCollection.where({ tmdbId: tmdbId });
var existingMovies = MoviesCollectionClient.fullCollection.where({ tmdbId: tmdbId });
if(existingMovies.length > 0) {
if(this.showExisting) {
if (index < this.showing || index === 0) {

View File

@ -6,7 +6,8 @@ var Marionette = require('marionette');
var Profiles = require('../Profile/ProfileCollection');
var RootFolders = require('./RootFolders/RootFolderCollection');
var RootFolderLayout = require('./RootFolders/RootFolderLayout');
var FullMovieCollection = require('../Movies/FullMovieCollection');
//var FullMovieCollection = require('../Movies/FullMovieCollection');
var MoviesCollectionClient = require('../Movies/MoviesCollectionClient');
var Config = require('../Config');
var Messenger = require('../Shared/Messenger');
var AsValidatedView = require('../Mixins/AsValidatedView');
@ -106,7 +107,7 @@ var view = Marionette.ItemView.extend({
},
_configureTemplateHelpers : function() {
var existingMovies = FullMovieCollection.where({ tmdbId : this.model.get('tmdbId') });
var existingMovies = MoviesCollectionClient.fullCollection.where({ tmdbId : this.model.get('tmdbId') });
if (existingMovies.length > 0) {
this.templateHelpers.existing = existingMovies[0].toJSON();
}
@ -217,7 +218,7 @@ var view = Marionette.ItemView.extend({
});
promise.done(function() {
FullMovieCollection.add(self.model);
MoviesCollectionClient.fullCollection.add(self.model);
self.close();

View File

@ -21,7 +21,7 @@ module.exports = Marionette.ItemView.extend({
var deleteFiles = this.ui.deleteFiles.prop('checked');
var addExclusion = this.ui.addExclusion.prop('checked');
this.ui.indicator.show();
this.model.set('deleted', true);
this.model.destroy({
data : { 'deleteFiles' : deleteFiles,
'addExclusion' : addExclusion },

View File

@ -38,6 +38,7 @@ var view = Marionette.ItemView.extend({
},
_onAfterSave : function() {
this.model.set('saved', true);
this.trigger('saved');
vent.trigger(vent.Commands.CloseModalCommand);
},

View File

@ -36,13 +36,21 @@ module.exports = Marionette.ItemView.extend({
initialize : function(options) {
this.moviesCollection = options.collection;
RootFolders.fetch().done(function() {
RootFolders.synced = true;
});
this.editorGrid = options.editorGrid;
this.listenTo(this.moviesCollection, 'backgrid:selected', this._updateInfo);
this.listenTo(this.moviesCollection, 'backgrid:selected', function(model, selected) {
var m = this.moviesCollection.fullCollection.findWhere({ tmdbId : model.get('tmdbId') });
m.set('selected', selected);
this._updateInfo();
});
this.listenTo(RootFolders, 'all', this.render);
},
@ -51,10 +59,11 @@ module.exports = Marionette.ItemView.extend({
},
_updateAndSave : function() {
var selected = this.editorGrid.getSelectedModels();
//var selected = this.editorGrid.getSelectedModels();
var selected = this.moviesCollection.fullCollection.where({ selected : true });
var monitored = this.ui.monitored.val();
var minAvail = this.ui.minimumAvailability.val();
var minAvail = this.ui.minimumAvailability.val();
var profile = this.ui.profile.val();
var seasonFolder = this.ui.seasonFolder.val();
var rootFolder = this.ui.rootFolder.val();
@ -67,8 +76,8 @@ module.exports = Marionette.ItemView.extend({
}
if (minAvail !=='noChange') {
model.set('minimumAvailability', minAvail);
}
model.set('minimumAvailability', minAvail);
}
if (profile !== 'noChange') {
model.set('profileId', parseInt(profile, 10));
@ -85,11 +94,9 @@ module.exports = Marionette.ItemView.extend({
model.set('rootFolderPath', rootFolderPath.get('path'));
}
model.edited = true;
});
this.moviesCollection.save();
this.moviesCollection.save();
},
_updateInfo : function() {

View File

@ -2,7 +2,7 @@ var vent = require('vent');
var Marionette = require('marionette');
var Backgrid = require('backgrid');
var EmptyView = require('../Index/EmptyView');
var MoviesCollection = require('../MoviesCollection');
var MoviesCollection = require('../MoviesCollectionClient');
var MovieTitleCell = require('../../Cells/MovieTitleCell');
var DownloadedQualityCell = require('../../Cells/DownloadedQualityCell');
var ProfileCell = require('../../Cells/ProfileCell');
@ -12,6 +12,8 @@ var FooterView = require('./MovieEditorFooterView');
var GridPager = require('../../Shared/Grid/Pager');
require('../../Mixins/backbone.signalr.mixin');
//require('../Globals');
window.shownOnce = false;
module.exports = Marionette.Layout.extend({
template : 'Movies/Editor/MovieEditorLayoutTemplate',
@ -79,15 +81,35 @@ module.exports = Marionette.Layout.extend({
},
initialize : function() {
this.movieCollection = MoviesCollection.clone();
this.movieCollection.state = MoviesCollection.state;
this.tableShown = window.shownOnce; //false;
this.movieCollection = MoviesCollection;
this.movieCollection.bindSignalR();
//debugger;
this.listenTo(this.movieCollection, 'save', this.render);
//this.movieCollection.switchMode('client');
this.movieCollection.fullCollection.bindSignalR();
var selected = this.movieCollection.fullCollection.where( { selected : true });
_.each(selected, function(model) {
model.set('selected', false);
});
this.listenTo(this.movieCollection, 'sync', function() {
this._showToolbar();
if (!this.tableShown) {
this._showTable();
this._showPager();
}
});
this.listenTo(this.movieCollection.fullCollection, 'sync', function() {
});
this.listenTo(this.movieCollection, 'save', function() {
window.alert('Done Saving');
});
this.filteringOptions = {
type : 'radio',
storeState : true,
storeState : false,
menuKey : 'serieseditor.filterMode',
defaultAction : 'all',
items : [
@ -135,12 +157,15 @@ module.exports = Marionette.Layout.extend({
}
]
};
window.shownOnce = true;
},
onRender : function() {
this._showToolbar();
this._showTable();
this._showPager();
if (this.tableShown) {
this._showToolbar();
this._showTable();
this._showPager();
}
},
onClose : function() {
@ -150,7 +175,7 @@ module.exports = Marionette.Layout.extend({
_showPager : function(){
var pager = new GridPager({
columns : this.columns,
collection : this.movieCollection,
collection : this.movieCollection
});
var pagerTop = new GridPager({
columns : this.columns,
@ -166,7 +191,7 @@ module.exports = Marionette.Layout.extend({
this.toolbar.close();
return;
}
this.tableShown = true;
this.columns[0].sortedCollection = this.movieCollection;
this.editorGrid = new Backgrid.Grid({
@ -176,7 +201,8 @@ module.exports = Marionette.Layout.extend({
});
this.seriesRegion.show(this.editorGrid);
this._showFooter();
this._showFooter();
},
_showToolbar : function() {
@ -200,7 +226,6 @@ module.exports = Marionette.Layout.extend({
_setFilter : function(buttonContext) {
var mode = buttonContext.model.get('key');
this.movieCollection.setFilterMode(mode);
this.movieCollection.setFilterMode(mode, { reset : false });
}
});

View File

@ -1,7 +1,12 @@
var movieCollection = require('./MoviesCollection');
/*var movieCollection = require('./MoviesCollection');
var fullCollection = movieCollection.clone();
fullCollection.bindSignalR();
fullCollection.state.pageSize = 100000;
fullCollection.fetch({reset : true});
module.exports = fullCollection;
module.exports = fullCollection;*/
var movieCollection = require('./MoviesCollectionClient');
movieCollection.bindSignalR();
module.exports = movieCollection.fullCollection;

View File

@ -1,11 +1,11 @@
<div class="row">
<div class="series-legend legend col-xs-6 col-sm-4">
<ul class='legend-labels'>
<li><span class="progress-bar"></span>Missing, but not yet considered available: {{missingNotAvailable}}</li>
<li><span class="progress-bar-success"></span>Downloaded and imported: {{downloaded}}</li>
<li><span class="progress-bar-gray"></span>Downloaded, but not monitored: {{downloadedNotMonitored}}</li>
<li><span class="progress-bar-danger"></span>Missing and monitored: {{missingMonitored}}</li>
<li><span class="progress-bar-warning"></span>Missing, but not monitored: {{missingNotMonitored}}</li>
<li><span class="progress-bar-success"></span>Downloaded and Monitored: {{downloadedMonitored}}</li>
<li><span class="progress-bar-gray"></span>Downloaded, but not Monitored: {{downloadedNotMonitored}}</li>
<li><span class="progress-bar-warning"></span>Missing, but not Monitored: {{missingNotMonitored}}</li>
<li><span class="progress-bar-danger"></span>Missing, Monitored and considered Available: {{missingMonitoredAvailable}}</li>
<li><span class="progress-bar"></span>Missing, Monitored, but not yet considered Available: {{missingMonitoredNotAvailable}}</li>
</ul>
</div>
<div class="col-xs-5 col-sm-7">
@ -28,8 +28,8 @@
<div class="series-stats col-sm-4">
<dl class="dl-horizontal">
<dt>Available,Monitored&Missing</dt>
<dd>{{missingMonitoredAvailable}}</dd>
<dt>Downloaded</dt>
<dd>{{downloaded}}</dd>
<dt>Monitored</dt>
<dd>{{monitored}}</dd>
</dl>

View File

@ -5,7 +5,7 @@ var PosterCollectionView = require('./Posters/SeriesPostersCollectionView');
var ListCollectionView = require('./Overview/SeriesOverviewCollectionView');
var EmptyView = require('./EmptyView');
var MoviesCollection = require('../MoviesCollection');
var FullMovieCollection = require('../FullMovieCollection');
//var FullMovieCollection = require('../FullMovieCollection');
var InCinemasCell = require('../../Cells/InCinemasCell');
var MovieTitleCell = require('../../Cells/MovieTitleCell');
var TemplatedCell = require('../../Cells/TemplatedCell');
@ -21,6 +21,13 @@ var FooterModel = require('./FooterModel');
var ToolbarLayout = require('../../Shared/Toolbar/ToolbarLayout');
require('../../Mixins/backbone.signalr.mixin');
var MoviesCollectionClient = require('../MoviesCollectionClient');
//this variable prevents double fetching the FullMovieCollection on first load
//var shownOnce = false;
//require('../Globals');
window.shownOnce = false;
module.exports = Marionette.Layout.extend({
template : 'Movies/Index/MoviesIndexLayoutTemplate',
@ -120,35 +127,61 @@ module.exports = Marionette.Layout.extend({
},
initialize : function() {
this.seriesCollection = MoviesCollection.clone();
//this variable prevents us from showing the list before seriesCollection has been fetched the first time
this.renderedOnce = false;
this.seriesCollection = MoviesCollection;//.clone();
this.seriesCollection.bindSignalR();
//this.fullCollection = FullMovieCollection;
//need to add this so the footer gets refreshed
this.listenTo(FullMovieCollection, 'sync', function(model, collection, options) {
//this._renderView();
this._showFooter();
/*var selected = MoviesCollectionClient.fullCollection.where( { saved : true });
_.each(selected, function(model) {
model.set('saved', false);
});*/
//if (window.shownOnce) {
// FullMovieCollection.fetch({reset : true});
//}
this.listenTo(MoviesCollectionClient, 'sync', function(eventName) {
this._showFooter();
window.shownOnce = true;
});
this.listenTo(this.seriesCollection, 'sync', function(model, collection, options) {
//this.seriesCollection.fullCollection.resetFiltered();
this._renderView();
//MoviesCollectionClient.fetch();
this.renderedOnce = true;
});
this.listenTo(MoviesCollection, "sync", function(eventName) {
this.seriesCollection = MoviesCollection.clone();
//this._showTable();
this._renderView();
});
this.listenTo(this.seriesCollection, "change", function(model) {
if (model.get('saved')) {
model.set('saved', false);
this.seriesCollection.fetch();
//FullMovieCollection.fetch({reset : true });
//this._showFooter();
var m = MoviesCollectionClient.fullCollection.findWhere( { tmdbId : model.get('tmdbId') });
m.set('monitored', model.get('monitored'));
m.set('minimumAvailability', model.get('minimumAvailability'));
m.set( {profileId : model.get('profileId') } );
this._showFooter();
}
});
this.listenTo(this.seriesCollection, 'add', function(model, collection, options) {
//this.seriesCollection.fullCollection.resetFiltered();
//this._renderView();
});
this.listenTo(this.seriesCollection, 'remove', function(model, collection, options) {
//this.seriesCollection.fullCollection.resetFiltered();
//this._showTable();
if (model.get('deleted')) {
this.seriesCollection.fetch(); //need to do this so that the page shows a full page and the 'total records' number is updated
//FullMovieCollection.fetch({reset : true}); //need to do this to update the footer
MoviesCollectionClient.fullCollection.remove(model);
this._showFooter();
}
});
this.sortingOptions = {
@ -264,7 +297,10 @@ module.exports = Marionette.Layout.extend({
onShow : function() {
this._showToolbar();
this._fetchCollection();
//if (window.shownOnce) {
this._showFooter();
//}
//this._fetchCollection();
},
_showTable : function() {
@ -274,9 +310,10 @@ module.exports = Marionette.Layout.extend({
className : 'table table-hover'
});
this._showPager();
this._renderView();
//this._showPager();
if (this.renderedOnce) {
this._renderView();
}
},
_showList : function() {
@ -309,19 +346,11 @@ module.exports = Marionette.Layout.extend({
} else {
this.seriesRegion.show(this.currentView);
this.listenTo(this.currentView.collection, "sync", function(eventName){
this._showPager();
//debugger;
});
this._showToolbar();
//this._showFooter();
this._showPager();
}
},
_fetchCollection : function() {
this.seriesCollection.fetch();
},
_setFilter : function(buttonContext) {
var mode = buttonContext.model.get('key');
this.seriesCollection.setFilterMode(mode);
@ -366,7 +395,7 @@ module.exports = Marionette.Layout.extend({
_showFooter : function() {
var footerModel = new FooterModel();
var movies = FullMovieCollection.models.length;
var movies = MoviesCollectionClient.fullCollection.models.length;
//instead of all the counters could do something like this with different query in the where...
//var releasedMovies = FullMovieCollection.where({ 'released' : this.model.get('released') });
// releasedMovies.length
@ -380,12 +409,13 @@ module.exports = Marionette.Layout.extend({
var downloaded =0;
var missingMonitored=0;
var missingNotMonitored=0;
var missingNotAvailable=0;
var missingMonitoredNotAvailable=0;
var missingMonitoredAvailable=0;
var downloadedMonitored=0;
var downloadedNotMonitored=0;
_.each(FullMovieCollection.models, function(model) {
_.each(MoviesCollectionClient.fullCollection.models, function(model) {
if (model.get('status').toLowerCase() === 'released') {
released++;
@ -398,7 +428,10 @@ module.exports = Marionette.Layout.extend({
}
if (model.get('monitored')) {
monitored++;
monitored++;
if (model.get('downloaded')) {
downloadedMonitored++;
}
}
else { //not monitored
if (model.get('downloaded')) {
@ -414,7 +447,9 @@ module.exports = Marionette.Layout.extend({
}
else { //missing
if (!model.get('isAvailable')) {
missingNotAvailable++;
if (model.get('monitored')) {
missingMonitoredNotAvailable++;
}
}
if (model.get('monitored')) {
@ -433,10 +468,11 @@ module.exports = Marionette.Layout.extend({
released : released,
monitored : monitored,
downloaded : downloaded,
downloadedMonitored : downloadedMonitored,
downloadedNotMonitored : downloadedNotMonitored,
missingMonitored : missingMonitored,
missingMonitoredAvailable : missingMonitoredAvailable,
missingNotAvailable : missingNotAvailable,
missingMonitoredNotAvailable : missingMonitoredNotAvailable,
missingNotMonitored : missingNotMonitored
});

View File

@ -8,9 +8,11 @@ module.exports = Backbone.Model.extend({
episodeFileCount : 0,
episodeCount : 0,
isExisting : false,
status : 0
status : 0,
saved : false,
deleted : false
},
getStatus : function() {
var monitored = this.get("monitored");
var status = this.get("status");
@ -20,7 +22,7 @@ module.exports = Backbone.Model.extend({
//var numOfMonths = timeSince / 1000 / 60 / 60 / 24 / 30;
if (status === "announced") {
return "announced"
return "announced";
}
if (status === "inCinemas") {

View File

@ -74,21 +74,27 @@ var Collection = PageableCollection.extend({
save : function() {
var self = this;
var t= self;
if (self.mode === 'client') {
t = self.fullCollection;
}
var proxy = _.extend(new Backbone.Model(), {
id : '',
url : self.url + '/editor',
toJSON : function() {
return self.filter(function(model) {
return t.filter(function(model) {
return model.edited;
});
}
});
this.listenTo(proxy, 'sync', function(proxyModel, models) {
this.add(models, { merge : true });
if (self.mode === 'client') {
this.fullCollection.add(models, { merge : true });
} else {
this.add(models, { merge : true });
}
this.trigger('save', this);
});
@ -166,7 +172,7 @@ var Collection = PageableCollection.extend({
if (model.getStatus() == "inCinemas") {
return 2;
}
if (mode.getStatus() == "announced") {
if (model.getStatus() == "announced") {
return 1;
}
return -1;
@ -249,7 +255,7 @@ var Collection = PageableCollection.extend({
},
comparator: function (model) {
return model.get('sortTitle');
return model.get('sortTitle');
}
});

View File

@ -0,0 +1,7 @@
var movieCollection = require('./MoviesCollection');
var GCCollection = movieCollection.clone();
GCCollection.bindSignalR();
GCCollection.switchMode('client'); //state.pageSize = 100000;
//CCollection.fetch();
module.exports = GCCollection;

View File

@ -1,7 +1,8 @@
var NzbDroneController = require('../Shared/NzbDroneController');
var AppLayout = require('../AppLayout');
var MoviesCollection = require('./MoviesCollection');
var FullMovieCollection = require("./FullMovieCollection");
//var FullMovieCollection = require("./FullMovieCollection");
var MoviesCollectionClient = require('./MoviesCollectionClient');
var MoviesIndexLayout = require('./Index/MoviesIndexLayout');
var MoviesDetailsLayout = require('./Details/MoviesDetailsLayout');
var SeriesDetailsLayout = require('../Series/Details/SeriesDetailsLayout');
@ -23,7 +24,7 @@ module.exports = NzbDroneController.extend({
},
seriesDetails : function(query) {
var series = FullMovieCollection.where({ titleSlug : query });
var series = MoviesCollectionClient.fullCollection.where({ titleSlug : query });
if (series.length !== 0) {
var targetMovie = series[0];
console.log(AppLayout.mainRegion);

View File

@ -2,7 +2,8 @@ var _ = require('underscore');
var $ = require('jquery');
var vent = require('vent');
var Backbone = require('backbone');
var FullMovieCollection = require('../Movies/FullMovieCollection');
//var FullMovieCollection = require('../Movies/FullMovieCollection');
var MoviesCollectionClient = require('../Movies/MoviesCollectionClient');
require('typeahead');
vent.on(vent.Hotkeys.NavbarSearch, function() {
@ -11,7 +12,7 @@ vent.on(vent.Hotkeys.NavbarSearch, function() {
var substringMatcher = function() {
return function findMatches (q, cb) {
var matches = _.select(FullMovieCollection.toJSON(), function(series) {
var matches = _.select(MoviesCollectionClient.fullCollection.toJSON(), function(series) {
return series.title.toLowerCase().indexOf(q.toLowerCase()) > -1;
});
cb(matches);