mirror of
https://github.com/Radarr/Radarr.git
synced 2026-04-18 21:35:51 -04:00
Moved source code under src folder - massive change
This commit is contained in:
114
src/UI/Episode/EpisodeDetailsLayout.js
Normal file
114
src/UI/Episode/EpisodeDetailsLayout.js
Normal file
@@ -0,0 +1,114 @@
|
||||
'use strict';
|
||||
define(
|
||||
[
|
||||
'marionette',
|
||||
'Episode/Summary/EpisodeSummaryLayout',
|
||||
'Episode/Search/EpisodeSearchLayout',
|
||||
'Series/SeriesCollection'
|
||||
], function (Marionette, SummaryLayout, SearchLayout, SeriesCollection) {
|
||||
|
||||
return Marionette.Layout.extend({
|
||||
template: 'Episode/EpisodeDetailsLayoutTemplate',
|
||||
|
||||
regions: {
|
||||
summary : '#episode-summary',
|
||||
activity: '#episode-activity',
|
||||
search : '#episode-search'
|
||||
},
|
||||
|
||||
ui: {
|
||||
summary : '.x-episode-summary',
|
||||
activity : '.x-episode-activity',
|
||||
search : '.x-episode-search',
|
||||
monitored: '.x-episode-monitored'
|
||||
},
|
||||
|
||||
events: {
|
||||
|
||||
'click .x-episode-summary' : '_showSummary',
|
||||
'click .x-episode-activity' : '_showActivity',
|
||||
'click .x-episode-search' : '_showSearch',
|
||||
'click .x-episode-monitored': '_toggleMonitored'
|
||||
},
|
||||
|
||||
templateHelpers: {},
|
||||
|
||||
initialize: function (options) {
|
||||
this.templateHelpers.hideSeriesLink = options.hideSeriesLink;
|
||||
|
||||
this.series = SeriesCollection.find({ id: this.model.get('seriesId') });
|
||||
this.templateHelpers.series = this.series.toJSON();
|
||||
this.openingTab = options.openingTab || 'summary'
|
||||
},
|
||||
|
||||
onShow: function () {
|
||||
this.searchLayout = new SearchLayout({ model: this.model });
|
||||
|
||||
if (this.openingTab === 'search') {
|
||||
this.searchLayout.startManualSearch = true;
|
||||
this._showSearch();
|
||||
}
|
||||
|
||||
else {
|
||||
this._showSummary();
|
||||
}
|
||||
|
||||
this._setMonitoredState();
|
||||
},
|
||||
|
||||
_showSummary: function (e) {
|
||||
if (e) {
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
this.ui.summary.tab('show');
|
||||
this.summary.show(new SummaryLayout({model: this.model, series: this.series}));
|
||||
},
|
||||
|
||||
_showActivity: function (e) {
|
||||
if (e) {
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
this.ui.activity.tab('show');
|
||||
},
|
||||
|
||||
_showSearch: function (e) {
|
||||
if (e) {
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
this.ui.search.tab('show');
|
||||
this.search.show(this.searchLayout);
|
||||
},
|
||||
|
||||
_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();
|
||||
});
|
||||
},
|
||||
|
||||
_setMonitoredState: function () {
|
||||
var monitored = this.model.get('monitored');
|
||||
|
||||
this.ui.monitored.removeClass('icon-spin icon-spinner');
|
||||
|
||||
if (this.model.get('monitored')) {
|
||||
this.ui.monitored.addClass('icon-bookmark');
|
||||
this.ui.monitored.removeClass('icon-bookmark-empty');
|
||||
}
|
||||
else {
|
||||
this.ui.monitored.addClass('icon-bookmark-empty');
|
||||
this.ui.monitored.removeClass('icon-bookmark');
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
37
src/UI/Episode/EpisodeDetailsLayoutTemplate.html
Normal file
37
src/UI/Episode/EpisodeDetailsLayoutTemplate.html
Normal file
@@ -0,0 +1,37 @@
|
||||
<div class="episode-detail-modal">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
|
||||
<h3>
|
||||
<i class="icon-bookmark x-episode-monitored" title="Toggle monitored status" />
|
||||
{{#if episodeTitle}}
|
||||
{{title}} - {{EpisodeNumber}} - {{episodeTitle}}
|
||||
{{else}}
|
||||
{{series.title}} - {{EpisodeNumber}} - {{title}}
|
||||
{{/if}}
|
||||
</h3>
|
||||
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<ul class="nav nav-tabs" id="myTab">
|
||||
<li><a href="#episode-summary" class="x-episode-summary">Summary</a></li>
|
||||
<!-- <li><a href="#episode-activity" class="x-episode-activity">Activity</a></li>-->
|
||||
<li><a href="#episode-search" class="x-episode-search">Search</a></li>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane" id="episode-summary"/>
|
||||
<!--<div class="tab-pane" id="episode-activity"/>-->
|
||||
<div class="tab-pane" id="episode-search"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
{{#unless hideSeriesLink}}
|
||||
{{#with series}}
|
||||
<a href="{{route}}" class="btn pull-left" data-dismiss="modal">open series</a>
|
||||
{{/with}}
|
||||
{{/unless}}
|
||||
|
||||
<button class="btn" data-dismiss="modal">close</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
11
src/UI/Episode/Search/ButtonsView.js
Normal file
11
src/UI/Episode/Search/ButtonsView.js
Normal file
@@ -0,0 +1,11 @@
|
||||
'use strict';
|
||||
define(
|
||||
[
|
||||
'app',
|
||||
'marionette'
|
||||
], function (App, Marionette) {
|
||||
|
||||
return Marionette.ItemView.extend({
|
||||
template: 'Episode/Search/ButtonsViewTemplate'
|
||||
});
|
||||
});
|
||||
4
src/UI/Episode/Search/ButtonsViewTemplate.html
Normal file
4
src/UI/Episode/Search/ButtonsViewTemplate.html
Normal file
@@ -0,0 +1,4 @@
|
||||
<div class="search-buttons">
|
||||
<button class="btn btn-large btn-block x-search-auto"><i class="icon-rocket"/> Automatic Search</button>
|
||||
<button class="btn btn-large btn-block btn-primary x-search-manual"><i class="icon-user"/> Manual Search</button>
|
||||
</div>
|
||||
84
src/UI/Episode/Search/EpisodeSearchLayout.js
Normal file
84
src/UI/Episode/Search/EpisodeSearchLayout.js
Normal file
@@ -0,0 +1,84 @@
|
||||
'use strict';
|
||||
define(
|
||||
[
|
||||
'app',
|
||||
'marionette',
|
||||
'Episode/Search/ButtonsView',
|
||||
'Episode/Search/ManualLayout',
|
||||
'Release/Collection',
|
||||
'Series/SeriesCollection',
|
||||
'Commands/CommandController',
|
||||
'Shared/LoadingView'
|
||||
], function (App, Marionette, ButtonsView, ManualSearchLayout, ReleaseCollection, SeriesCollection,CommandController, LoadingView) {
|
||||
|
||||
return Marionette.Layout.extend({
|
||||
template: 'Episode/Search/EpisodeSearchLayoutTemplate',
|
||||
|
||||
regions: {
|
||||
main: '#episode-search-region'
|
||||
},
|
||||
|
||||
events: {
|
||||
'click .x-search-auto' : '_searchAuto',
|
||||
'click .x-search-manual': '_searchManual',
|
||||
'click .x-search-back' : '_showButtons'
|
||||
},
|
||||
|
||||
initialize: function () {
|
||||
this.mainView = new ButtonsView();
|
||||
},
|
||||
|
||||
onShow: function () {
|
||||
if (this.startManualSearch) {
|
||||
this._searchManual();
|
||||
}
|
||||
|
||||
else {
|
||||
this._showMainView();
|
||||
}
|
||||
},
|
||||
|
||||
_searchAuto: function (e) {
|
||||
if (e) {
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
CommandController.Execute('episodeSearch', {
|
||||
episodeId: this.model.get('id')
|
||||
});
|
||||
|
||||
App.vent.trigger(App.Commands.CloseModalCommand);
|
||||
},
|
||||
|
||||
_searchManual: function (e) {
|
||||
if (e) {
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
var self = this;
|
||||
|
||||
this.mainView = new LoadingView();
|
||||
this._showMainView();
|
||||
|
||||
var releases = new ReleaseCollection();
|
||||
var promise = releases.fetchEpisodeReleases(this.model.id);
|
||||
|
||||
promise.done(function () {
|
||||
if (!self.isClosed) {
|
||||
self.mainView = new ManualSearchLayout({collection: releases});
|
||||
self._showMainView();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
_showMainView: function () {
|
||||
this.main.show(this.mainView);
|
||||
},
|
||||
|
||||
_showButtons: function () {
|
||||
this.mainView = new ButtonsView();
|
||||
this._showMainView();
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
1
src/UI/Episode/Search/EpisodeSearchLayoutTemplate.html
Normal file
1
src/UI/Episode/Search/EpisodeSearchLayoutTemplate.html
Normal file
@@ -0,0 +1 @@
|
||||
<div id="episode-search-region"></div>
|
||||
79
src/UI/Episode/Search/ManualLayout.js
Normal file
79
src/UI/Episode/Search/ManualLayout.js
Normal file
@@ -0,0 +1,79 @@
|
||||
'use strict';
|
||||
define(
|
||||
[
|
||||
'marionette',
|
||||
'backgrid',
|
||||
'Cells/FileSizeCell',
|
||||
'Cells/QualityCell',
|
||||
'Cells/ApprovalStatusCell',
|
||||
'Release/DownloadReportCell',
|
||||
'Cells/Header/QualityHeaderCell'
|
||||
|
||||
], function (Marionette, Backgrid, FileSizeCell, QualityCell, ApprovalStatusCell, DownloadReportCell, QualityHeaderCell) {
|
||||
|
||||
return Marionette.Layout.extend({
|
||||
template: 'Episode/Search/ManualLayoutTemplate',
|
||||
|
||||
regions: {
|
||||
grid: '#episode-release-grid'
|
||||
},
|
||||
|
||||
columns:
|
||||
[
|
||||
{
|
||||
name : 'age',
|
||||
label : 'Age',
|
||||
sortable: true,
|
||||
cell : Backgrid.IntegerCell
|
||||
},
|
||||
{
|
||||
name : 'title',
|
||||
label : 'Title',
|
||||
sortable: true,
|
||||
cell : Backgrid.StringCell.extend({ className: 'nzb-title-cell' })
|
||||
},
|
||||
{
|
||||
name : 'indexer',
|
||||
label : 'Indexer',
|
||||
sortable: true,
|
||||
cell : Backgrid.StringCell
|
||||
},
|
||||
{
|
||||
name : 'size',
|
||||
label : 'Size',
|
||||
sortable: true,
|
||||
cell : FileSizeCell
|
||||
},
|
||||
{
|
||||
name : 'quality',
|
||||
label : 'Quality',
|
||||
sortable : true,
|
||||
cell : QualityCell,
|
||||
headerCell: QualityHeaderCell
|
||||
},
|
||||
|
||||
{
|
||||
name : 'rejections',
|
||||
label: '',
|
||||
cell : ApprovalStatusCell
|
||||
},
|
||||
{
|
||||
name : 'download',
|
||||
label: '',
|
||||
cell : DownloadReportCell
|
||||
}
|
||||
],
|
||||
|
||||
onShow: function () {
|
||||
if (!this.isClosed) {
|
||||
this.grid.show(new Backgrid.Grid({
|
||||
row : Backgrid.Row,
|
||||
columns : this.columns,
|
||||
collection: this.collection,
|
||||
className : 'table table-hover'
|
||||
}));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
2
src/UI/Episode/Search/ManualLayoutTemplate.html
Normal file
2
src/UI/Episode/Search/ManualLayoutTemplate.html
Normal file
@@ -0,0 +1,2 @@
|
||||
<div id="episode-release-grid"/>
|
||||
<button class="btn x-search-back">Back</button>
|
||||
91
src/UI/Episode/Summary/EpisodeSummaryLayout.js
Normal file
91
src/UI/Episode/Summary/EpisodeSummaryLayout.js
Normal file
@@ -0,0 +1,91 @@
|
||||
'use strict';
|
||||
define(
|
||||
[
|
||||
'app',
|
||||
'marionette',
|
||||
'backgrid',
|
||||
'Series/EpisodeFileModel',
|
||||
'Series/EpisodeFileCollection',
|
||||
'Cells/FileSizeCell',
|
||||
'Cells/QualityCell',
|
||||
'Episode/Summary/NoFileView',
|
||||
'Shared/LoadingView'
|
||||
], function (App, Marionette, Backgrid, EpisodeFileModel, EpisodeFileCollection, FileSizeCell, QualityCell, NoFileView, LoadingView) {
|
||||
|
||||
return Marionette.Layout.extend({
|
||||
template: 'Episode/Summary/EpisodeSummaryLayoutTemplate',
|
||||
|
||||
regions: {
|
||||
overview: '.episode-overview',
|
||||
activity: '.episode-file-info'
|
||||
},
|
||||
|
||||
columns:
|
||||
[
|
||||
{
|
||||
name : 'path',
|
||||
label : 'Path',
|
||||
cell : 'string',
|
||||
sortable: false
|
||||
},
|
||||
{
|
||||
name : 'size',
|
||||
label : 'Size',
|
||||
cell : FileSizeCell,
|
||||
sortable: false
|
||||
},
|
||||
{
|
||||
name : 'quality',
|
||||
label : 'Quality',
|
||||
cell : QualityCell,
|
||||
sortable: false,
|
||||
editable: true
|
||||
}
|
||||
],
|
||||
|
||||
templateHelpers: {},
|
||||
|
||||
initialize: function (options) {
|
||||
if (!this.model.series) {
|
||||
this.templateHelpers.series = options.series.toJSON();
|
||||
}
|
||||
},
|
||||
|
||||
onShow: function () {
|
||||
if (this.model.get('hasFile')) {
|
||||
var episodeFileId = this.model.get('episodeFileId');
|
||||
|
||||
if (App.reqres.hasHandler(App.Reqres.GetEpisodeFileById)) {
|
||||
var episodeFile = App.request(App.Reqres.GetEpisodeFileById, episodeFileId);
|
||||
var episodeFileCollection = new EpisodeFileCollection(episodeFile, { seriesId: this.model.get('seriesId') });
|
||||
this._showTable(episodeFileCollection)
|
||||
}
|
||||
|
||||
else {
|
||||
this.activity.show(new LoadingView());
|
||||
|
||||
var self = this;
|
||||
var newEpisodeFile = new EpisodeFileModel({ id: episodeFileId });
|
||||
var newEpisodeFileCollection = new EpisodeFileCollection(newEpisodeFile, { seriesId: this.model.get('seriesId') });
|
||||
var promise = newEpisodeFile.fetch();
|
||||
|
||||
promise.done(function () {
|
||||
self._showTable(newEpisodeFileCollection);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
this.activity.show(new NoFileView());
|
||||
}
|
||||
},
|
||||
|
||||
_showTable: function (episodeFileCollection) {
|
||||
this.activity.show(new Backgrid.Grid({
|
||||
collection: episodeFileCollection,
|
||||
columns : this.columns,
|
||||
className : 'table table-bordered'
|
||||
}));
|
||||
}
|
||||
});
|
||||
});
|
||||
14
src/UI/Episode/Summary/EpisodeSummaryLayoutTemplate.html
Normal file
14
src/UI/Episode/Summary/EpisodeSummaryLayoutTemplate.html
Normal file
@@ -0,0 +1,14 @@
|
||||
<div class="episode-info">
|
||||
{{#with series}}
|
||||
{{qualityProfile qualityProfileId}}
|
||||
<span class="label label-info">{{network}}</span>
|
||||
{{/with}}
|
||||
<span class="label label-info">{{StartTime airDateUtc}}</span>
|
||||
<span class="label label-info">{{NextAiring airDateUtc}}</span>
|
||||
</div>
|
||||
|
||||
<div class="episode-overview">
|
||||
{{overview}}
|
||||
</div>
|
||||
|
||||
<div class="episode-file-info"></div>
|
||||
11
src/UI/Episode/Summary/NoFileView.js
Normal file
11
src/UI/Episode/Summary/NoFileView.js
Normal file
@@ -0,0 +1,11 @@
|
||||
'use strict';
|
||||
define(
|
||||
[
|
||||
'marionette'
|
||||
], function (Marionette) {
|
||||
|
||||
return Marionette.ItemView.extend({
|
||||
template: 'Episode/Summary/NoFileViewTemplate'
|
||||
});
|
||||
|
||||
});
|
||||
3
src/UI/Episode/Summary/NoFileViewTemplate.html
Normal file
3
src/UI/Episode/Summary/NoFileViewTemplate.html
Normal file
@@ -0,0 +1,3 @@
|
||||
<p class="text-warning">
|
||||
No file available for this episode.
|
||||
</p>
|
||||
Reference in New Issue
Block a user