UI Cleanup - Updated Shared and Shims subtrees.

pull/4/head
Taloth Saldono 9 years ago
parent 019525dd9d
commit d6079a701c

@ -1,15 +1,15 @@
var $ = require('jquery'); var $ = require('jquery');
module.exports = { module.exports = {
get : function(resource){ get : function(resource) {
var url = window.NzbDrone.ApiRoot + '/' + resource; var url = window.NzbDrone.ApiRoot + '/' + resource;
var _data; var _data;
$.ajax({ $.ajax({
url : url, url : url,
async : false async : false
}).done(function(data){ }).done(function(data) {
_data = data; _data = data;
}).error(function(xhr, status, error){ }).error(function(xhr, status, error) {
throw error; throw error;
}); });
return _data; return _data;

@ -3,14 +3,16 @@ var AppLayout = require('../../AppLayout');
var Marionette = require('marionette'); var Marionette = require('marionette');
module.exports = Marionette.AppRouter.extend({ module.exports = Marionette.AppRouter.extend({
initialize : function(){ initialize : function() {
vent.on(vent.Commands.OpenControlPanelCommand, this._openControlPanel, this); vent.on(vent.Commands.OpenControlPanelCommand, this._openControlPanel, this);
vent.on(vent.Commands.CloseControlPanelCommand, this._closeControlPanel, this); vent.on(vent.Commands.CloseControlPanelCommand, this._closeControlPanel, this);
}, },
_openControlPanel : function(view){
_openControlPanel : function(view) {
AppLayout.controlPanelRegion.show(view); AppLayout.controlPanelRegion.show(view);
}, },
_closeControlPanel : function(){
_closeControlPanel : function() {
AppLayout.controlPanelRegion.closePanel(); AppLayout.controlPanelRegion.closePanel();
} }
}); });

@ -1,39 +1,41 @@
var $ = require('jquery'); var $ = require('jquery');
var Backbone = require('backbone'); var Backbone = require('backbone');
var Marionette = require('marionette'); var Marionette = require('marionette');
var region = Marionette.Region.extend({
el : '#control-panel-region',
module.exports = (function(){ constructor : function() {
var region = Marionette.Region.extend({ Backbone.Marionette.Region.prototype.constructor.apply(this, arguments);
el : '#control-panel-region', this.on('show', this.showPanel, this);
constructor : function(){ },
Backbone.Marionette.Region.prototype.constructor.apply(this, arguments);
this.on('show', this.showPanel, this); getEl : function(selector) {
}, var $el = $(selector);
getEl : function(selector){
var $el = $(selector); return $el;
return $el; },
},
showPanel : function(){ showPanel : function() {
$('body').addClass('control-panel-visible'); $('body').addClass('control-panel-visible');
this.$el.animate({ this.$el.animate({
"margin-bottom" : 0, 'margin-bottom' : 0,
"opacity" : 1 'opacity' : 1
}, { }, {
queue : false, queue : false,
duration : 300 duration : 300
}); });
}, },
closePanel : function(){
$('body').removeClass('control-panel-visible'); closePanel : function() {
this.$el.animate({ $('body').removeClass('control-panel-visible');
"margin-bottom" : -100, this.$el.animate({
"opacity" : 0 'margin-bottom' : -100,
}, { 'opacity' : 0
queue : false, }, {
duration : 300 queue : false,
}); duration : 300
this.reset(); });
} this.reset();
}); }
return region; });
}).call(this); module.exports = region;

@ -1,3 +1,5 @@
var Marionette = require('marionette'); var Marionette = require('marionette');
module.exports = Marionette.CompositeView.extend({template : 'Shared/FileBrowser/EmptyViewTemplate'}); module.exports = Marionette.CompositeView.extend({
template : 'Shared/FileBrowser/EmptyViewTemplate'
});

@ -5,12 +5,13 @@ var FileBrowserModel = require('./FileBrowserModel');
module.exports = Backbone.Collection.extend({ module.exports = Backbone.Collection.extend({
model : FileBrowserModel, model : FileBrowserModel,
url : window.NzbDrone.ApiRoot + '/filesystem', url : window.NzbDrone.ApiRoot + '/filesystem',
parse : function(response){
parse : function(response) {
var contents = []; var contents = [];
if(response.parent || response.parent === '') { if (response.parent || response.parent === '') {
var type = 'parent'; var type = 'parent';
var name = '...'; var name = '...';
if(response.parent === '') { if (response.parent === '') {
type = 'computer'; type = 'computer';
name = 'My Computer'; name = 'My Computer';
} }

@ -1,4 +1,4 @@
var _ = require('underscore'); var _ = require('underscore');
var vent = require('vent'); var vent = require('vent');
var Marionette = require('marionette'); var Marionette = require('marionette');
var Backgrid = require('backgrid'); var Backgrid = require('backgrid');
@ -13,19 +13,25 @@ var LoadingView = require('../LoadingView');
require('../../Mixins/DirectoryAutoComplete'); require('../../Mixins/DirectoryAutoComplete');
module.exports = Marionette.Layout.extend({ module.exports = Marionette.Layout.extend({
template : "Shared/FileBrowser/FileBrowserLayoutTemplate", template : 'Shared/FileBrowser/FileBrowserLayoutTemplate',
regions : {browser : "#x-browser"},
ui : { regions : {
path : ".x-path", browser : '#x-browser'
indicator : ".x-indicator" },
ui : {
path : '.x-path',
indicator : '.x-indicator'
}, },
events : {
"typeahead:selected .x-path" : "_pathChanged", events : {
"typeahead:autocompleted .x-path" : "_pathChanged", 'typeahead:selected .x-path' : '_pathChanged',
"keyup .x-path" : "_inputChanged", 'typeahead:autocompleted .x-path' : '_pathChanged',
"click .x-ok" : "_selectPath" 'keyup .x-path' : '_inputChanged',
'click .x-ok' : '_selectPath'
}, },
initialize : function(options){
initialize : function(options) {
this.collection = new FileBrowserCollection(); this.collection = new FileBrowserCollection();
this.collection.showFiles = options.showFiles || false; this.collection.showFiles = options.showFiles || false;
this.collection.showLastModified = options.showLastModified || false; this.collection.showLastModified = options.showLastModified || false;
@ -34,25 +40,30 @@ module.exports = Marionette.Layout.extend({
this.listenTo(this.collection, "sync", this._showGrid); this.listenTo(this.collection, "sync", this._showGrid);
this.listenTo(this.collection, "filebrowser:folderselected", this._rowSelected); this.listenTo(this.collection, "filebrowser:folderselected", this._rowSelected);
}, },
onRender : function(){
onRender : function() {
this.browser.show(new LoadingView()); this.browser.show(new LoadingView());
this.ui.path.directoryAutoComplete(); this.ui.path.directoryAutoComplete();
this._fetchCollection(this.input.val()); this._fetchCollection(this.input.val());
this._updatePath(this.input.val()); this._updatePath(this.input.val());
}, },
_setColumns : function(){
this.columns = [{ _setColumns : function() {
name : "type", this.columns = [
label : "", {
sortable : false, name : "type",
cell : FileBrowserTypeCell label : "",
}, { sortable : false,
name : "name", cell : FileBrowserTypeCell
label : "Name", },
sortable : false, {
cell : FileBrowserNameCell name : "name",
}]; label : "Name",
if(this.collection.showLastModified) { sortable : false,
cell : FileBrowserNameCell
}
];
if (this.collection.showLastModified) {
this.columns.push({ this.columns.push({
name : "lastModified", name : "lastModified",
label : "Last Modified", label : "Last Modified",
@ -60,7 +71,7 @@ module.exports = Marionette.Layout.extend({
cell : RelativeDateCell cell : RelativeDateCell
}); });
} }
if(this.collection.showFiles) { if (this.collection.showFiles) {
this.columns.push({ this.columns.push({
name : "size", name : "size",
label : "Size", label : "Size",
@ -69,17 +80,19 @@ module.exports = Marionette.Layout.extend({
}); });
} }
}, },
_fetchCollection : function(path){
_fetchCollection : function(path) {
this.ui.indicator.show(); this.ui.indicator.show();
var data = {includeFiles : this.collection.showFiles}; var data = { includeFiles : this.collection.showFiles };
if(path) { if (path) {
data.path = path; data.path = path;
} }
this.collection.fetch({data : data}); this.collection.fetch({ data : data });
}, },
_showGrid : function(){
_showGrid : function() {
this.ui.indicator.hide(); this.ui.indicator.hide();
if(this.collection.models.length === 0) { if (this.collection.models.length === 0) {
this.browser.show(new EmptyView()); this.browser.show(new EmptyView());
return; return;
} }
@ -91,27 +104,32 @@ module.exports = Marionette.Layout.extend({
}); });
this.browser.show(grid); this.browser.show(grid);
}, },
_rowSelected : function(model){
_rowSelected : function(model) {
var path = model.get("path"); var path = model.get("path");
this._updatePath(path); this._updatePath(path);
this._fetchCollection(path); this._fetchCollection(path);
}, },
_pathChanged : function(e, path){
_pathChanged : function(e, path) {
this._fetchCollection(path.value); this._fetchCollection(path.value);
this._updatePath(path.value); this._updatePath(path.value);
}, },
_inputChanged : function(){
_inputChanged : function() {
var path = this.ui.path.val(); var path = this.ui.path.val();
if(path === "" || path.endsWith("\\") || path.endsWith("/")) { if (path === "" || path.endsWith("\\") || path.endsWith("/")) {
this._fetchCollection(path); this._fetchCollection(path);
} }
}, },
_updatePath : function(path){
if(path !== undefined || path !== null) { _updatePath : function(path) {
if (path !== undefined || path !== null) {
this.ui.path.val(path); this.ui.path.val(path);
} }
}, },
_selectPath : function(){
_selectPath : function() {
this.input.val(this.ui.path.val()); this.input.val(this.ui.path.val());
this.input.trigger("change"); this.input.trigger("change");
vent.trigger(vent.Commands.CloseFileBrowser); vent.trigger(vent.Commands.CloseFileBrowser);

@ -3,44 +3,48 @@ var Backbone = require('backbone');
var Marionette = require('marionette'); var Marionette = require('marionette');
require('bootstrap'); require('bootstrap');
module.exports = (function(){ var region = Marionette.Region.extend({
var region = Marionette.Region.extend({ el : '#file-browser-modal-region',
el : '#file-browser-modal-region',
constructor : function(){ constructor : function() {
Backbone.Marionette.Region.prototype.constructor.apply(this, arguments); Backbone.Marionette.Region.prototype.constructor.apply(this, arguments);
this.on('show', this.showModal, this); this.on('show', this.showModal, this);
}, },
getEl : function(selector){
var $el = $(selector); getEl : function(selector) {
$el.on('hidden', this.close); var $el = $(selector);
return $el; $el.on('hidden', this.close);
}, return $el;
showModal : function(){ },
this.$el.addClass('modal fade');
this.$el.attr('tabindex', '-1'); showModal : function() {
this.$el.css('z-index', '1060'); this.$el.addClass('modal fade');
this.$el.modal({ this.$el.attr('tabindex', '-1');
show : true, this.$el.css('z-index', '1060');
keyboard : true, this.$el.modal({
backdrop : true show : true,
}); keyboard : true,
this.$el.on('hide.bs.modal', $.proxy(this._closing, this)); backdrop : true
this.$el.on('shown.bs.modal', function(){ });
$('.modal-backdrop:last').css('z-index', 1059); this.$el.on('hide.bs.modal', $.proxy(this._closing, this));
}); this.$el.on('shown.bs.modal', function() {
this.currentView.$el.addClass('modal-dialog'); $('.modal-backdrop:last').css('z-index', 1059);
}, });
closeModal : function(){ this.currentView.$el.addClass('modal-dialog');
$(this.el).modal('hide'); },
this.reset();
}, closeModal : function() {
_closing : function(){ $(this.el).modal('hide');
if(this.$el) { this.reset();
this.$el.off('hide.bs.modal'); },
this.$el.off('shown.bs.modal');
} _closing : function() {
this.reset(); if (this.$el) {
this.$el.off('hide.bs.modal');
this.$el.off('shown.bs.modal');
} }
}); this.reset();
return region; }
}).call(this); });
module.exports = region;

@ -3,11 +3,16 @@ var NzbDroneCell = require('../../Cells/NzbDroneCell');
module.exports = NzbDroneCell.extend({ module.exports = NzbDroneCell.extend({
className : 'file-browser-name-cell', className : 'file-browser-name-cell',
render : function(){
render : function() {
this.$el.empty(); this.$el.empty();
var name = this.model.get(this.column.get('name')); var name = this.model.get(this.column.get('name'));
this.$el.html(name); this.$el.html(name);
this.delegateEvents(); this.delegateEvents();
return this; return this;
} }
}); });

@ -2,17 +2,22 @@ var _ = require('underscore');
var Backgrid = require('backgrid'); var Backgrid = require('backgrid');
module.exports = Backgrid.Row.extend({ module.exports = Backgrid.Row.extend({
className : 'file-browser-row', className : 'file-browser-row',
events : {"click" : '_selectRow'},
events : {
'click' : '_selectRow'
},
_originalInit : Backgrid.Row.prototype.initialize, _originalInit : Backgrid.Row.prototype.initialize,
initialize : function(){
initialize : function() {
this._originalInit.apply(this, arguments); this._originalInit.apply(this, arguments);
}, },
_selectRow : function(){
if(this.model.get('type') === 'file') { _selectRow : function() {
if (this.model.get('type') === 'file') {
this.model.collection.trigger('filebrowser:fileselected', this.model); this.model.collection.trigger('filebrowser:fileselected', this.model);
} } else {
else {
this.model.collection.trigger('filebrowser:folderselected', this.model); this.model.collection.trigger('filebrowser:folderselected', this.model);
} }
} }

@ -3,24 +3,26 @@ var NzbDroneCell = require('../../Cells/NzbDroneCell');
module.exports = NzbDroneCell.extend({ module.exports = NzbDroneCell.extend({
className : 'file-browser-type-cell', className : 'file-browser-type-cell',
render : function(){
render : function() {
this.$el.empty(); this.$el.empty();
var type = this.model.get(this.column.get('name')); var type = this.model.get(this.column.get('name'));
var icon = 'icon-hdd'; var icon = 'icon-hdd';
if(type === 'computer') {
if (type === 'computer') {
icon = 'icon-desktop'; icon = 'icon-desktop';
} } else if (type === 'parent') {
else if(type === 'parent') {
icon = 'icon-level-up'; icon = 'icon-level-up';
} } else if (type === 'folder') {
else if(type === 'folder') {
icon = 'icon-folder-close-alt'; icon = 'icon-folder-close-alt';
} } else if (type === 'file') {
else if(type === 'file') {
icon = 'icon-file-alt'; icon = 'icon-file-alt';
} }
this.$el.html('<i class="{0}"></i>'.format(icon)); this.$el.html('<i class="{0}"></i>'.format(icon));
this.delegateEvents(); this.delegateEvents();
return this; return this;
} }
}); });

@ -3,43 +3,56 @@ var filesize = require('filesize');
var UiSettings = require('./UiSettingsModel'); var UiSettings = require('./UiSettingsModel');
module.exports = { module.exports = {
bytes : function(sourceSize){ bytes : function(sourceSize) {
var size = Number(sourceSize); var size = Number(sourceSize);
if(isNaN(size)) {
if (isNaN(size)) {
return ''; return '';
} }
return filesize(size, { return filesize(size, {
base : 2, base : 2,
round : 1 round : 1
}); });
}, },
relativeDate : function(sourceDate){
if(!sourceDate) { relativeDate : function(sourceDate) {
if (!sourceDate) {
return ''; return '';
} }
var date = moment(sourceDate); var date = moment(sourceDate);
var calendarDate = date.calendar(); var calendarDate = date.calendar();
//TODO: It would be nice to not have to hack this...
var strippedCalendarDate = calendarDate.substring(0, calendarDate.indexOf(' at ')); var strippedCalendarDate = calendarDate.substring(0, calendarDate.indexOf(' at '));
if(strippedCalendarDate) {
if (strippedCalendarDate) {
return strippedCalendarDate; return strippedCalendarDate;
} }
if(date.isAfter(moment())) {
if (date.isAfter(moment())) {
return date.fromNow(true); return date.fromNow(true);
} }
if(date.isBefore(moment().add('years', -1))) {
if (date.isBefore(moment().add('years', -1))) {
return date.format(UiSettings.get('shortDateFormat')); return date.format(UiSettings.get('shortDateFormat'));
} }
return date.fromNow(); return date.fromNow();
}, },
pad : function(n, width, z){
pad : function(n, width, z) {
z = z || '0'; z = z || '0';
n = n + ''; n = n + '';
return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n; return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n;
}, },
number : function(input){
if(!input) { number : function(input) {
if (!input) {
return '0'; return '0';
} }
return input.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); return input.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
} }
}; };

@ -1,116 +1,144 @@
module.exports = function() { module.exports = function() {
var backgrid = this; var Backgrid = this;
backgrid.SonarrHeaderCell = backgrid.HeaderCell.extend({ Backgrid.SonarrHeaderCell = Backgrid.HeaderCell.extend({
events : { events : {
'click' : 'onClick' 'click' : 'onClick'
}, },
_originalInit : backgrid.HeaderCell.prototype.initialize,
initialize : function(options){ _originalInit : Backgrid.HeaderCell.prototype.initialize,
initialize : function(options) {
this._originalInit.call(this, options); this._originalInit.call(this, options);
this.listenTo(this.collection, 'drone:sort', this.render); this.listenTo(this.collection, 'drone:sort', this.render);
}, },
render : function(){
render : function() {
this.$el.empty(); this.$el.empty();
this.$el.append(this.column.get('label')); this.$el.append(this.column.get('label'));
var column = this.column; var column = this.column;
var sortable = backgrid.callByNeed(column.sortable(), column, this.collection); var sortable = Backgrid.callByNeed(column.sortable(), column, this.collection);
if(sortable) {
if (sortable) {
this.$el.addClass('sortable'); this.$el.addClass('sortable');
this.$el.append(' <i class="pull-right"></i>'); this.$el.append(' <i class="pull-right"></i>');
} }
//Do we need this?
this.$el.addClass(column.get('name')); this.$el.addClass(column.get('name'));
if(column.has('className')) {
if (column.has('className')) {
this.$el.addClass(column.get('className')); this.$el.addClass(column.get('className'));
} }
this.delegateEvents(); this.delegateEvents();
this.direction(column.get('direction')); this.direction(column.get('direction'));
if(this.collection.state) {
if (this.collection.state) {
var name = this._getSortMapping().name; var name = this._getSortMapping().name;
var order = this.collection.state.order; var order = this.collection.state.order;
if(name === column.get('name')) {
if (name === column.get('name')) {
this._setSortIcon(order); this._setSortIcon(order);
} } else {
else {
this._removeSortIcon(); this._removeSortIcon();
} }
} }
return this; return this;
}, },
direction : function(dir){
direction : function(dir) {
this.$el.children('i').removeClass('icon-sort-up icon-sort-down'); this.$el.children('i').removeClass('icon-sort-up icon-sort-down');
if(arguments.length) {
if(dir) { if (arguments.length) {
if (dir) {
this._setSortIcon(dir); this._setSortIcon(dir);
} }
this.column.set('direction', dir); this.column.set('direction', dir);
} }
var columnDirection = this.column.get('direction'); var columnDirection = this.column.get('direction');
if(!columnDirection && this.collection.state) {
if (!columnDirection && this.collection.state) {
var name = this._getSortMapping().name; var name = this._getSortMapping().name;
var order = this.collection.state.order; var order = this.collection.state.order;
if(name === this.column.get('name')) {
if (name === this.column.get('name')) {
columnDirection = order; columnDirection = order;
} }
} }
return columnDirection; return columnDirection;
}, },
_getSortMapping : function(){
_getSortMapping : function() {
var sortKey = this.collection.state.sortKey; var sortKey = this.collection.state.sortKey;
if(this.collection._getSortMapping) {
if (this.collection._getSortMapping) {
return this.collection._getSortMapping(sortKey); return this.collection._getSortMapping(sortKey);
} }
return { return {
name : sortKey, name : sortKey,
sortKey : sortKey sortKey : sortKey
}; };
}, },
onClick : function(e){
onClick : function(e) {
e.preventDefault(); e.preventDefault();
var collection = this.collection; var collection = this.collection;
var event = 'backgrid:sort'; var event = 'backgrid:sort';
var column = this.column; var column = this.column;
var sortable = backgrid.callByNeed(column.sortable(), column, collection); var sortable = Backgrid.callByNeed(column.sortable(), column, collection);
if(sortable) { if (sortable) {
var direction = collection.state.order; var direction = collection.state.order;
if(direction === 'ascending' || direction === -1) { if (direction === 'ascending' || direction === -1) {
direction = 'descending'; direction = 'descending';
} } else {
else {
direction = 'ascending'; direction = 'ascending';
} }
if(collection.setSorting) {
if (collection.setSorting) {
collection.setSorting(column.get('name'), direction); collection.setSorting(column.get('name'), direction);
} } else {
else {
collection.state.sortKey = column.get('name'); collection.state.sortKey = column.get('name');
collection.state.order = direction; collection.state.order = direction;
} }
collection.trigger(event, column, direction); collection.trigger(event, column, direction);
} }
}, },
_resetCellDirection : function(columnToSort, direction){
if(columnToSort !== this.column) { _resetCellDirection : function(columnToSort, direction) {
if (columnToSort !== this.column) {
this.direction(null); this.direction(null);
} } else {
else {
this.direction(direction); this.direction(direction);
} }
}, },
_convertDirectionToIcon : function(dir){
if(dir === 'ascending' || dir === -1) { _convertDirectionToIcon : function(dir) {
if (dir === 'ascending' || dir === -1) {
return 'icon-sort-up'; return 'icon-sort-up';
} }
return 'icon-sort-down'; return 'icon-sort-down';
}, },
_setSortIcon : function(dir){
_setSortIcon : function(dir) {
this._removeSortIcon(); this._removeSortIcon();
this.$el.children('i').addClass(this._convertDirectionToIcon(dir)); this.$el.children('i').addClass(this._convertDirectionToIcon(dir));
}, },
_removeSortIcon : function(){
_removeSortIcon : function() {
this.$el.children('i').removeClass('icon-sort-up icon-sort-down'); this.$el.children('i').removeClass('icon-sort-up icon-sort-down');
} }
}); });
return backgrid.SonarrHeaderCell; return Backgrid.SonarrHeaderCell;
}; };

@ -3,42 +3,52 @@ var Marionette = require('marionette');
var Paginator = require('backgrid.paginator'); var Paginator = require('backgrid.paginator');
module.exports = Paginator.extend({ module.exports = Paginator.extend({
template : 'Shared/Grid/PagerTemplate', template : 'Shared/Grid/PagerTemplate',
events : {
"click .pager-btn" : 'changePage', events : {
"click .x-page-number" : '_showPageJumper', 'click .pager-btn' : 'changePage',
"change .x-page-select" : '_jumpToPage', 'click .x-page-number' : '_showPageJumper',
"blur .x-page-select" : 'render' 'change .x-page-select' : '_jumpToPage',
'blur .x-page-select' : 'render'
}, },
windowSize : 1,
windowSize : 1,
fastForwardHandleLabels : { fastForwardHandleLabels : {
first : 'icon-fast-backward', first : 'icon-fast-backward',
prev : 'icon-backward', prev : 'icon-backward',
next : 'icon-forward', next : 'icon-forward',
last : 'icon-fast-forward' last : 'icon-fast-forward'
}, },
changePage : function(e){
changePage : function(e) {
e.preventDefault(); e.preventDefault();
var target = this.$(e.target); var target = this.$(e.target);
if(target.closest('li').hasClass('disabled')) {
if (target.closest('li').hasClass('disabled')) {
return; return;
} }
target.closest('li i').addClass('icon-spinner icon-spin'); target.closest('li i').addClass('icon-spinner icon-spin');
var label = target.attr('data-action'); var label = target.attr('data-action');
var ffLabels = this.fastForwardHandleLabels; var ffLabels = this.fastForwardHandleLabels;
var collection = this.collection; var collection = this.collection;
if(ffLabels) {
if (ffLabels) {
switch (label) { switch (label) {
case 'first': case 'first':
collection.getFirstPage(); collection.getFirstPage();
return; return;
case 'prev': case 'prev':
if(collection.hasPrevious()) { if (collection.hasPrevious()) {
collection.getPreviousPage(); collection.getPreviousPage();
} }
return; return;
case 'next': case 'next':
if(collection.hasNext()) { if (collection.hasNext()) {
collection.getNextPage(); collection.getNextPage();
} }
return; return;
@ -47,14 +57,19 @@ module.exports = Paginator.extend({
return; return;
} }
} }
var state = collection.state; var state = collection.state;
var pageIndex = target.text(); var pageIndex = target.text();
collection.getPage(state.firstPage === 0 ? pageIndex - 1 : pageIndex); collection.getPage(state.firstPage === 0 ? pageIndex - 1 : pageIndex);
}, },
makeHandles : function(){
makeHandles : function() {
var handles = []; var handles = [];
var collection = this.collection; var collection = this.collection;
var state = collection.state; var state = collection.state;
// convert all indices to 0-based here
var firstPage = state.firstPage; var firstPage = state.firstPage;
var lastPage = +state.lastPage; var lastPage = +state.lastPage;
lastPage = Math.max(0, firstPage ? lastPage - 1 : lastPage); lastPage = Math.max(0, firstPage ? lastPage - 1 : lastPage);
@ -62,7 +77,8 @@ module.exports = Paginator.extend({
currentPage = firstPage ? currentPage - 1 : currentPage; currentPage = firstPage ? currentPage - 1 : currentPage;
var windowStart = Math.floor(currentPage / this.windowSize) * this.windowSize; var windowStart = Math.floor(currentPage / this.windowSize) * this.windowSize;
var windowEnd = Math.min(lastPage + 1, windowStart + this.windowSize); var windowEnd = Math.min(lastPage + 1, windowStart + this.windowSize);
if(collection.mode !== 'infinite') {
if (collection.mode !== 'infinite') {
for (var i = windowStart; i < windowEnd; i++) { for (var i = windowStart; i < windowEnd; i++) {
handles.push({ handles.push({
label : i + 1, label : i + 1,
@ -73,30 +89,34 @@ module.exports = Paginator.extend({
}); });
} }
} }
var ffLabels = this.fastForwardHandleLabels; var ffLabels = this.fastForwardHandleLabels;
if(ffLabels) { if (ffLabels) {
if(ffLabels.prev) { if (ffLabels.prev) {
handles.unshift({ handles.unshift({
label : ffLabels.prev, label : ffLabels.prev,
className : collection.hasPrevious() ? void 0 : 'disabled', className : collection.hasPrevious() ? void 0 : 'disabled',
action : 'prev' action : 'prev'
}); });
} }
if(ffLabels.first) {
if (ffLabels.first) {
handles.unshift({ handles.unshift({
label : ffLabels.first, label : ffLabels.first,
className : collection.hasPrevious() ? void 0 : 'disabled', className : collection.hasPrevious() ? void 0 : 'disabled',
action : 'first' action : 'first'
}); });
} }
if(ffLabels.next) {
if (ffLabels.next) {
handles.push({ handles.push({
label : ffLabels.next, label : ffLabels.next,
className : collection.hasNext() ? void 0 : 'disabled', className : collection.hasNext() ? void 0 : 'disabled',
action : 'next' action : 'next'
}); });
} }
if(ffLabels.last) {
if (ffLabels.last) {
handles.push({ handles.push({
label : ffLabels.last, label : ffLabels.last,
className : collection.hasNext() ? void 0 : 'disabled', className : collection.hasNext() ? void 0 : 'disabled',
@ -104,44 +124,59 @@ module.exports = Paginator.extend({
}); });
} }
} }
return handles; return handles;
}, },
render : function(){
render : function() {
this.$el.empty(); this.$el.empty();
var templateFunction = Marionette.TemplateCache.get(this.template); var templateFunction = Marionette.TemplateCache.get(this.template);
this.$el.html(templateFunction({ this.$el.html(templateFunction({
handles : this.makeHandles(), handles : this.makeHandles(),
state : this.collection.state state : this.collection.state
})); }));
this.delegateEvents(); this.delegateEvents();
return this; return this;
}, },
_showPageJumper : function(e){
if($(e.target).is('select')) { _showPageJumper : function(e) {
if ($(e.target).is('select')) {
return; return;
} }
var templateFunction = Marionette.TemplateCache.get('Shared/Grid/JumpToPageTemplate'); var templateFunction = Marionette.TemplateCache.get('Shared/Grid/JumpToPageTemplate');
var state = this.collection.state; var state = this.collection.state;
var currentPage = Math.max(state.currentPage, state.firstPage); var currentPage = Math.max(state.currentPage, state.firstPage);
currentPage = state.firstPage ? currentPage - 1 : currentPage; currentPage = state.firstPage ? currentPage - 1 : currentPage;
var pages = []; var pages = [];
for (var i = 0; i < this.collection.state.lastPage; i++) { for (var i = 0; i < this.collection.state.lastPage; i++) {
if(i === currentPage) { if (i === currentPage) {
pages.push({ pages.push({
page : i + 1, page : i + 1,
current : true current : true
}); });
} } else {
else { pages.push({ page : i + 1 });
pages.push({page : i + 1});
} }
} }
this.$el.find('.x-page-number').html(templateFunction({pages : pages}));
this.$el.find('.x-page-number').html(templateFunction({ pages : pages }));
}, },
_jumpToPage : function(){
_jumpToPage : function() {
var target = this.$el.find('.x-page-select'); var target = this.$el.find('.x-page-select');
//Remove event handlers so the blur event is not triggered
this.undelegateEvents(); this.undelegateEvents();
var selectedPage = parseInt(target.val(), 10); var selectedPage = parseInt(target.val(), 10);
this.$el.find('.x-page-number').html('<i class="icon-spinner icon-spin"></i>'); this.$el.find('.x-page-number').html('<i class="icon-spinner icon-spin"></i>');
this.collection.getPage(selectedPage); this.collection.getPage(selectedPage);
} }

@ -2,23 +2,28 @@ require('messenger');
var messenger = require('messenger'); var messenger = require('messenger');
module.exports = { module.exports = {
show : function(options){ show : function(options) {
if(!options.type) { if (!options.type) {
options.type = 'info'; options.type = 'info';
} }
if(options.hideAfter === undefined) {
if (options.hideAfter === undefined) {
switch (options.type) { switch (options.type) {
case 'info': case 'info':
options.hideAfter = 5; options.hideAfter = 5;
break; break;
case 'success': case 'success':
options.hideAfter = 5; options.hideAfter = 5;
break; break;
default: default:
options.hideAfter = 5; options.hideAfter = 5;
} }
} }
options.hideOnNavigate = options.hideOnNavigate || false; options.hideOnNavigate = options.hideOnNavigate || false;
return messenger().post({ return messenger().post({
message : options.message, message : options.message,
type : options.type, type : options.type,
@ -29,26 +34,33 @@ module.exports = {
hideOnNavigate : options.hideOnNavigate hideOnNavigate : options.hideOnNavigate
}); });
}, },
monitor : function(options){
if(!options.promise) { monitor : function(options) {
if (!options.promise) {
throw 'promise is required'; throw 'promise is required';
} }
if(!options.successMessage) {
if (!options.successMessage) {
throw 'success message is required'; throw 'success message is required';
} }
if(!options.errorMessage) {
if (!options.errorMessage) {
throw 'error message is required'; throw 'error message is required';
} }
var self = this; var self = this;
options.promise.done(function(){
self.show({message : options.successMessage}); options.promise.done(function() {
self.show({ message : options.successMessage });
}); });
options.promise.fail(function(){
options.promise.fail(function() {
self.show({ self.show({
message : options.errorMessage, message : options.errorMessage,
type : 'error' type : 'error'
}); });
}); });
return options.promise; return options.promise;
} }
}; };

@ -10,7 +10,7 @@ var RenamePreviewLayout = require('../../Rename/RenamePreviewLayout');
var FileBrowserLayout = require('../FileBrowser/FileBrowserLayout'); var FileBrowserLayout = require('../FileBrowser/FileBrowserLayout');
module.exports = Marionette.AppRouter.extend({ module.exports = Marionette.AppRouter.extend({
initialize : function(){ initialize : function() {
vent.on(vent.Commands.OpenModalCommand, this._openModal, this); vent.on(vent.Commands.OpenModalCommand, this._openModal, this);
vent.on(vent.Commands.CloseModalCommand, this._closeModal, this); vent.on(vent.Commands.CloseModalCommand, this._closeModal, this);
vent.on(vent.Commands.EditSeriesCommand, this._editSeries, this); vent.on(vent.Commands.EditSeriesCommand, this._editSeries, this);
@ -22,21 +22,26 @@ module.exports = Marionette.AppRouter.extend({
vent.on(vent.Commands.ShowFileBrowser, this._showFileBrowser, this); vent.on(vent.Commands.ShowFileBrowser, this._showFileBrowser, this);
vent.on(vent.Commands.CloseFileBrowser, this._closeFileBrowser, this); vent.on(vent.Commands.CloseFileBrowser, this._closeFileBrowser, this);
}, },
_openModal : function(view){
_openModal : function(view) {
AppLayout.modalRegion.show(view); AppLayout.modalRegion.show(view);
}, },
_closeModal : function(){
_closeModal : function() {
AppLayout.modalRegion.closeModal(); AppLayout.modalRegion.closeModal();
}, },
_editSeries : function(options){
var view = new EditSeriesView({model : options.series}); _editSeries : function(options) {
var view = new EditSeriesView({ model : options.series });
AppLayout.modalRegion.show(view); AppLayout.modalRegion.show(view);
}, },
_deleteSeries : function(options){
var view = new DeleteSeriesView({model : options.series}); _deleteSeries : function(options) {
var view = new DeleteSeriesView({ model : options.series });
AppLayout.modalRegion.show(view); AppLayout.modalRegion.show(view);
}, },
_showEpisode : function(options){
_showEpisode : function(options) {
var view = new EpisodeDetailsLayout({ var view = new EpisodeDetailsLayout({
model : options.episode, model : options.episode,
hideSeriesLink : options.hideSeriesLink, hideSeriesLink : options.hideSeriesLink,
@ -44,23 +49,28 @@ module.exports = Marionette.AppRouter.extend({
}); });
AppLayout.modalRegion.show(view); AppLayout.modalRegion.show(view);
}, },
_showHistory : function(options){
var view = new HistoryDetailsLayout({model : options.model}); _showHistory : function(options) {
var view = new HistoryDetailsLayout({ model : options.model });
AppLayout.modalRegion.show(view); AppLayout.modalRegion.show(view);
}, },
_showLogDetails : function(options){
var view = new LogDetailsView({model : options.model}); _showLogDetails : function(options) {
var view = new LogDetailsView({ model : options.model });
AppLayout.modalRegion.show(view); AppLayout.modalRegion.show(view);
}, },
_showRenamePreview : function(options){
_showRenamePreview : function(options) {
var view = new RenamePreviewLayout(options); var view = new RenamePreviewLayout(options);
AppLayout.modalRegion.show(view); AppLayout.modalRegion.show(view);
}, },
_showFileBrowser : function(options){
_showFileBrowser : function(options) {
var view = new FileBrowserLayout(options); var view = new FileBrowserLayout(options);
AppLayout.fileBrowserModalRegion.show(view); AppLayout.fileBrowserModalRegion.show(view);
}, },
_closeFileBrowser : function(){
_closeFileBrowser : function(options) {
AppLayout.fileBrowserModalRegion.closeModal(); AppLayout.fileBrowserModalRegion.closeModal();
} }
}); });

@ -2,40 +2,49 @@ var $ = require('jquery');
var Backbone = require('backbone'); var Backbone = require('backbone');
var Marionette = require('marionette'); var Marionette = require('marionette');
require('bootstrap'); require('bootstrap');
var region = Marionette.Region.extend({
el : '#modal-region',
module.exports = (function(){ constructor : function() {
var region = Marionette.Region.extend({ Backbone.Marionette.Region.prototype.constructor.apply(this, arguments);
el : '#modal-region', this.on('show', this.showModal, this);
constructor : function(){ },
Backbone.Marionette.Region.prototype.constructor.apply(this, arguments);
this.on('show', this.showModal, this); getEl : function(selector) {
}, var $el = $(selector);
getEl : function(selector){ $el.on('hidden', this.close);
var $el = $(selector); return $el;
$el.on('hidden', this.close); },
return $el;
}, showModal : function() {
showModal : function(){ this.$el.addClass('modal fade');
this.$el.addClass('modal fade');
this.$el.attr('tabindex', '-1'); //need tab index so close on escape works
this.$el.modal({ //https://github.com/twitter/bootstrap/issues/4663
show : true, this.$el.attr('tabindex', '-1');
keyboard : true, this.$el.modal({
backdrop : true show : true,
}); keyboard : true,
this.$el.on('hide.bs.modal', $.proxy(this._closing, this)); backdrop : true
this.currentView.$el.addClass('modal-dialog'); });
},
closeModal : function(){ this.$el.on('hide.bs.modal', $.proxy(this._closing, this));
$(this.el).modal('hide');
this.reset(); this.currentView.$el.addClass('modal-dialog');
}, },
_closing : function(){
if(this.$el) { closeModal : function() {
this.$el.off('hide.bs.modal'); $(this.el).modal('hide');
} this.reset();
this.reset(); },
_closing : function() {
if (this.$el) {
this.$el.off('hide.bs.modal');
} }
});
return region; this.reset();
}).call(this); }
});
module.exports = region;

@ -1,3 +1,5 @@
var Marionette = require('marionette'); var Marionette = require('marionette');
module.exports = Marionette.ItemView.extend({template : 'Shared/NotFoundViewTemplate'}); module.exports = Marionette.ItemView.extend({
template : 'Shared/NotFoundViewTemplate'
});

@ -1,27 +1,28 @@
var vent = require('vent'); var vent = require('vent');
var AppLayout = require('../AppLayout'); var AppLayout = require('../AppLayout');
var Marionette = require('marionette'); var Marionette = require('marionette');
var NotFoundView = require('./NotFoundView'); var NotFoundView = require('./NotFoundView');
var Messenger = require('messenger'); var Messenger = require('messenger');
module.exports = Marionette.AppRouter.extend({ module.exports = Marionette.AppRouter.extend({
initialize : function(){ initialize : function() {
this.listenTo(vent, vent.Events.ServerUpdated, this._onServerUpdated); this.listenTo(vent, vent.Events.ServerUpdated, this._onServerUpdated);
}, },
showNotFound : function(){
showNotFound : function() {
this.setTitle('Not Found'); this.setTitle('Not Found');
this.showMainRegion(new NotFoundView(this)); this.showMainRegion(new NotFoundView(this));
}, },
setTitle : function(title){
setTitle : function(title) {
title = title; title = title;
if(title === 'Sonarr') { if (title === 'Sonarr') {
document.title = 'Sonarr'; document.title = 'Sonarr';
} } else {
else {
document.title = title + ' - Sonarr'; document.title = title + ' - Sonarr';
} }
if(window.NzbDrone.Analytics && window.Piwik) {
if (window.NzbDrone.Analytics && window.Piwik) {
try { try {
var piwik = window.Piwik.getTracker('http://piwik.nzbdrone.com/piwik.php', 1); var piwik = window.Piwik.getTracker('http://piwik.nzbdrone.com/piwik.php', 1);
piwik.setReferrerUrl(''); piwik.setReferrerUrl('');
@ -35,7 +36,8 @@ module.exports = Marionette.AppRouter.extend({
} }
} }
}, },
_onServerUpdated : function(){
_onServerUpdated : function() {
Messenger.show({ Messenger.show({
message : 'Sonarr has been updated', message : 'Sonarr has been updated',
hideAfter : 0, hideAfter : 0,
@ -43,7 +45,7 @@ module.exports = Marionette.AppRouter.extend({
actions : { actions : {
viewChanges : { viewChanges : {
label : 'View Changes', label : 'View Changes',
action : function(){ action : function() {
window.location = window.NzbDrone.UrlBase + '/system/updates'; window.location = window.NzbDrone.UrlBase + '/system/updates';
} }
} }
@ -52,11 +54,11 @@ module.exports = Marionette.AppRouter.extend({
this.pendingUpdate = true; this.pendingUpdate = true;
}, },
showMainRegion : function(view){
if(this.pendingUpdate) { showMainRegion : function(view) {
if (this.pendingUpdate) {
window.location.reload(); window.location.reload();
} } else {
else {
AppLayout.mainRegion.show(view); AppLayout.mainRegion.show(view);
} }
} }

@ -5,9 +5,10 @@ var StatusModel = require('../System/StatusModel');
require('signalR'); require('signalR');
module.exports = { module.exports = {
appInitializer : function(){ appInitializer : function() {
console.log('starting signalR'); console.log('starting signalR');
var getStatus = function(status){
var getStatus = function(status) {
switch (status) { switch (status) {
case 0: case 0:
return 'connecting'; return 'connecting';
@ -21,27 +22,36 @@ module.exports = {
throw 'invalid status ' + status; throw 'invalid status ' + status;
} }
}; };
var tryingToReconnect = false; var tryingToReconnect = false;
var messengerId = 'signalR'; var messengerId = 'signalR';
this.signalRconnection = $.connection(StatusModel.get('urlBase') + '/signalr'); this.signalRconnection = $.connection(StatusModel.get('urlBase') + '/signalr');
this.signalRconnection.stateChanged(function(change){
this.signalRconnection.stateChanged(function(change) {
console.debug('SignalR: [{0}]'.format(getStatus(change.newState))); console.debug('SignalR: [{0}]'.format(getStatus(change.newState)));
}); });
this.signalRconnection.received(function(message){
this.signalRconnection.received(function(message) {
vent.trigger('server:' + message.name, message.body); vent.trigger('server:' + message.name, message.body);
}); });
this.signalRconnection.reconnecting(function(){
if(window.NzbDrone.unloading) { this.signalRconnection.reconnecting(function() {
if (window.NzbDrone.unloading) {
return; return;
} }
tryingToReconnect = true; tryingToReconnect = true;
}); });
this.signalRconnection.reconnected(function(){
this.signalRconnection.reconnected(function() {
tryingToReconnect = false; tryingToReconnect = false;
}); });
this.signalRconnection.disconnected(function(){
if(tryingToReconnect) { this.signalRconnection.disconnected(function() {
if (tryingToReconnect) {
$('<div class="modal-backdrop fade in"></div>').appendTo(document.body); $('<div class="modal-backdrop fade in"></div>').appendTo(document.body);
Messenger.show({ Messenger.show({
id : messengerId, id : messengerId,
type : 'error', type : 'error',
@ -50,7 +60,7 @@ module.exports = {
actions : { actions : {
cancel : { cancel : {
label : 'Reload', label : 'Reload',
action : function(){ action : function() {
window.location.reload(); window.location.reload();
} }
} }
@ -58,7 +68,9 @@ module.exports = {
}); });
} }
}); });
this.signalRconnection.start({transport : ['longPolling']});
this.signalRconnection.start({ transport : ['longPolling'] });
return this; return this;
} }
}; };

@ -2,17 +2,20 @@ var Marionette = require('marionette');
var ButtonView = require('./ButtonView'); var ButtonView = require('./ButtonView');
module.exports = Marionette.CollectionView.extend({ module.exports = Marionette.CollectionView.extend({
className : 'btn-group', className : 'btn-group',
itemView : ButtonView, itemView : ButtonView,
initialize : function(options){
initialize : function(options) {
this.menu = options.menu; this.menu = options.menu;
this.className = 'btn-group'; this.className = 'btn-group';
if(options.menu.collapse) {
if (options.menu.collapse) {
this.className += ' btn-group-collapse'; this.className += ' btn-group-collapse';
} }
}, },
onRender : function(){
if(this.menu.collapse) { onRender : function() {
if (this.menu.collapse) {
this.$el.addClass('btn-group-collapse'); this.$el.addClass('btn-group-collapse');
} }
} }

@ -4,59 +4,77 @@ var _ = require('underscore');
var CommandController = require('../../../Commands/CommandController'); var CommandController = require('../../../Commands/CommandController');
module.exports = Marionette.ItemView.extend({ module.exports = Marionette.ItemView.extend({
template : 'Shared/Toolbar/ButtonTemplate', template : 'Shared/Toolbar/ButtonTemplate',
className : 'btn btn-default btn-icon-only-xs', className : 'btn btn-default btn-icon-only-xs',
ui : {icon : 'i'},
events : {"click" : 'onClick'}, ui : {
initialize : function(){ icon : 'i'
},
events : {
'click' : 'onClick'
},
initialize : function() {
this.storageKey = this.model.get('menuKey') + ':' + this.model.get('key'); this.storageKey = this.model.get('menuKey') + ':' + this.model.get('key');
}, },
onRender : function(){
if(this.model.get('active')) { onRender : function() {
if (this.model.get('active')) {
this.$el.addClass('active'); this.$el.addClass('active');
this.invokeCallback(); this.invokeCallback();
} }
if(!this.model.get('title')) {
if (!this.model.get('title')) {
this.$el.addClass('btn-icon-only'); this.$el.addClass('btn-icon-only');
} }
if(this.model.get('className')) {
if (this.model.get('className')) {
this.$el.addClass(this.model.get('className')); this.$el.addClass(this.model.get('className'));
} }
var command = this.model.get('command'); var command = this.model.get('command');
if(command) { if (command) {
var properties = _.extend({name : command}, this.model.get('properties')); var properties = _.extend({ name : command }, this.model.get('properties'));
CommandController.bindToCommand({ CommandController.bindToCommand({
command : properties, command : properties,
element : this.$el element : this.$el
}); });
} }
}, },
onClick : function(){
if(this.$el.hasClass('disabled')) { onClick : function() {
if (this.$el.hasClass('disabled')) {
return; return;
} }
this.invokeCallback(); this.invokeCallback();
this.invokeRoute(); this.invokeRoute();
this.invokeCommand(); this.invokeCommand();
}, },
invokeCommand : function(){
invokeCommand : function() {
var command = this.model.get('command'); var command = this.model.get('command');
if(command) { if (command) {
CommandController.Execute(command, this.model.get('properties')); CommandController.Execute(command, this.model.get('properties'));
} }
}, },
invokeRoute : function(){
invokeRoute : function() {
var route = this.model.get('route'); var route = this.model.get('route');
if(route) { if (route) {
Backbone.history.navigate(route, {trigger : true}); Backbone.history.navigate(route, { trigger : true });
} }
}, },
invokeCallback : function(){
if(!this.model.ownerContext) { invokeCallback : function() {
if (!this.model.ownerContext) {
throw 'ownerContext must be set.'; throw 'ownerContext must be set.';
} }
var callback = this.model.get('callback'); var callback = this.model.get('callback');
if(callback) { if (callback) {
callback.call(this.model.ownerContext, this); callback.call(this.model.ownerContext, this);
} }
} }

@ -1,4 +1,6 @@
var Backbone = require('backbone'); var Backbone = require('backbone');
var ButtonModel = require('./ButtonModel'); var ButtonModel = require('./ButtonModel');
module.exports = Backbone.Collection.extend({model : ButtonModel}); module.exports = Backbone.Collection.extend({
model : ButtonModel
});

@ -3,9 +3,9 @@ var Backbone = require('backbone');
module.exports = Backbone.Model.extend({ module.exports = Backbone.Model.extend({
defaults : { defaults : {
"target" : '/nzbdrone/route', 'target' : '/nzbdrone/route',
"title" : '', 'title' : '',
"active" : false, 'active' : false,
"tooltip" : undefined 'tooltip' : undefined
} }
}); });

@ -3,26 +3,33 @@ var RadioButtonView = require('./RadioButtonView');
var Config = require('../../../Config'); var Config = require('../../../Config');
module.exports = Marionette.CollectionView.extend({ module.exports = Marionette.CollectionView.extend({
className : 'btn-group', className : 'btn-group',
itemView : RadioButtonView, itemView : RadioButtonView,
attributes : {"data-toggle" : 'buttons'},
initialize : function(options){ attributes : {
'data-toggle' : 'buttons'
},
initialize : function(options) {
this.menu = options.menu; this.menu = options.menu;
this.setActive(); this.setActive();
}, },
setActive : function(){
setActive : function() {
var storedKey = this.menu.defaultAction; var storedKey = this.menu.defaultAction;
if(this.menu.storeState) {
if (this.menu.storeState) {
storedKey = Config.getValue(this.menu.menuKey, storedKey); storedKey = Config.getValue(this.menu.menuKey, storedKey);
} }
if(!storedKey) {
if (!storedKey) {
return; return;
} }
this.collection.each(function(model){ this.collection.each(function(model) {
if(model.get('key').toLocaleLowerCase() === storedKey.toLowerCase()) { if (model.get('key').toLocaleLowerCase() === storedKey.toLowerCase()) {
model.set('active', true); model.set('active', true);
} } else {
else {
model.set('active, false'); model.set('active, false');
} }
}); });

@ -2,35 +2,48 @@ var Marionette = require('marionette');
var Config = require('../../../Config'); var Config = require('../../../Config');
module.exports = Marionette.ItemView.extend({ module.exports = Marionette.ItemView.extend({
template : 'Shared/Toolbar/RadioButtonTemplate', template : 'Shared/Toolbar/RadioButtonTemplate',
className : 'btn btn-default', className : 'btn btn-default',
ui : {icon : 'i'},
events : {"click" : 'onClick'}, ui : {
initialize : function(){ icon : 'i'
},
events : {
'click' : 'onClick'
},
initialize : function() {
this.storageKey = this.model.get('menuKey') + ':' + this.model.get('key'); this.storageKey = this.model.get('menuKey') + ':' + this.model.get('key');
}, },
onRender : function(){
if(this.model.get('active')) { onRender : function() {
if (this.model.get('active')) {
this.$el.addClass('active'); this.$el.addClass('active');
this.invokeCallback(); this.invokeCallback();
} }
if(!this.model.get('title')) {
if (!this.model.get('title')) {
this.$el.addClass('btn-icon-only'); this.$el.addClass('btn-icon-only');
} }
if(this.model.get('tooltip')) {
if (this.model.get('tooltip')) {
this.$el.attr('title', this.model.get('tooltip')); this.$el.attr('title', this.model.get('tooltip'));
} }
}, },
onClick : function(){
onClick : function() {
Config.setValue(this.model.get('menuKey'), this.model.get('key')); Config.setValue(this.model.get('menuKey'), this.model.get('key'));
this.invokeCallback(); this.invokeCallback();
}, },
invokeCallback : function(){
if(!this.model.ownerContext) { invokeCallback : function() {
if (!this.model.ownerContext) {
throw 'ownerContext must be set.'; throw 'ownerContext must be set.';
} }
var callback = this.model.get('callback'); var callback = this.model.get('callback');
if(callback) { if (callback) {
callback.call(this.model.ownerContext, this); callback.call(this.model.ownerContext, this);
} }
} }

@ -6,27 +6,33 @@ module.exports = Marionette.CompositeView.extend({
itemView : ButtonView, itemView : ButtonView,
template : 'Shared/Toolbar/Sorting/SortingButtonCollectionViewTemplate', template : 'Shared/Toolbar/Sorting/SortingButtonCollectionViewTemplate',
itemViewContainer : '.dropdown-menu', itemViewContainer : '.dropdown-menu',
initialize : function(options){
initialize : function(options) {
this.viewCollection = options.viewCollection; this.viewCollection = options.viewCollection;
this.listenTo(this.viewCollection, 'drone:sort', this.sort); this.listenTo(this.viewCollection, 'drone:sort', this.sort);
}, },
itemViewOptions : function(){
return {viewCollection : this.viewCollection}; itemViewOptions : function() {
return {
viewCollection : this.viewCollection
};
}, },
sort : function(sortModel, sortDirection){
sort : function(sortModel, sortDirection) {
var collection = this.viewCollection; var collection = this.viewCollection;
var order; var order;
if(sortDirection === 'ascending') { if (sortDirection === 'ascending') {
order = -1; order = -1;
} } else if (sortDirection === 'descending') {
else if(sortDirection === 'descending') {
order = 1; order = 1;
} } else {
else {
order = null; order = null;
} }
collection.setSorting(sortModel.get('name'), order); collection.setSorting(sortModel.get('name'), order);
collection.fullCollection.sort(); collection.fullCollection.sort();
return this; return this;
} }
}); });

@ -3,53 +3,68 @@ var Marionette = require('marionette');
var _ = require('underscore'); var _ = require('underscore');
module.exports = Marionette.ItemView.extend({ module.exports = Marionette.ItemView.extend({
template : 'Shared/Toolbar/Sorting/SortingButtonViewTemplate', template : 'Shared/Toolbar/Sorting/SortingButtonViewTemplate',
tagName : 'li', tagName : 'li',
ui : {icon : 'i'},
events : {"click" : 'onClick'}, ui : {
initialize : function(options){ icon : 'i'
},
events : {
'click' : 'onClick'
},
initialize : function(options) {
this.viewCollection = options.viewCollection; this.viewCollection = options.viewCollection;
this.listenTo(this.viewCollection, 'drone:sort', this.render); this.listenTo(this.viewCollection, 'drone:sort', this.render);
this.listenTo(this.viewCollection, 'backgrid:sort', this.render); this.listenTo(this.viewCollection, 'backgrid:sort', this.render);
}, },
onRender : function(){
if(this.viewCollection.state) { onRender : function() {
if (this.viewCollection.state) {
var sortKey = this.viewCollection.state.sortKey; var sortKey = this.viewCollection.state.sortKey;
var name = this.viewCollection._getSortMapping(sortKey).name; var name = this.viewCollection._getSortMapping(sortKey).name;
var order = this.viewCollection.state.order; var order = this.viewCollection.state.order;
if(name === this.model.get('name')) {
if (name === this.model.get('name')) {
this._setSortIcon(order); this._setSortIcon(order);
} } else {
else {
this._removeSortIcon(); this._removeSortIcon();
} }
} }
}, },
onClick : function(e){
onClick : function(e) {
e.preventDefault(); e.preventDefault();
var collection = this.viewCollection; var collection = this.viewCollection;
var event = 'drone:sort'; var event = 'drone:sort';
var direction = collection.state.order; var direction = collection.state.order;
if(direction === 'ascending' || direction === -1) { if (direction === 'ascending' || direction === -1) {
direction = 'descending'; direction = 'descending';
} } else {
else {
direction = 'ascending'; direction = 'ascending';
} }
collection.setSorting(this.model.get('name'), direction); collection.setSorting(this.model.get('name'), direction);
collection.trigger(event, this.model, direction); collection.trigger(event, this.model, direction);
}, },
_convertDirectionToIcon : function(dir){
if(dir === 'ascending' || dir === -1) { _convertDirectionToIcon : function(dir) {
if (dir === 'ascending' || dir === -1) {
return 'icon-sort-up'; return 'icon-sort-up';
} }
return 'icon-sort-down'; return 'icon-sort-down';
}, },
_setSortIcon : function(dir){
_setSortIcon : function(dir) {
this._removeSortIcon(); this._removeSortIcon();
this.ui.icon.addClass(this._convertDirectionToIcon(dir)); this.ui.icon.addClass(this._convertDirectionToIcon(dir));
}, },
_removeSortIcon : function(){
_removeSortIcon : function() {
this.ui.icon.removeClass('icon-sort-up icon-sort-down'); this.ui.icon.removeClass('icon-sort-up icon-sort-down');
} }
}); });

@ -7,49 +7,61 @@ var SortingButtonCollectionView = require('./Sorting/SortingButtonCollectionView
var _ = require('underscore'); var _ = require('underscore');
module.exports = Marionette.Layout.extend({ module.exports = Marionette.Layout.extend({
template : 'Shared/Toolbar/ToolbarLayoutTemplate', template : 'Shared/Toolbar/ToolbarLayoutTemplate',
className : 'toolbar', className : 'toolbar',
ui : {
ui : {
left_x : '.x-toolbar-left', left_x : '.x-toolbar-left',
right_x : '.x-toolbar-right' right_x : '.x-toolbar-right'
}, },
initialize : function(options){
if(!options) { initialize : function(options) {
if (!options) {
throw 'options needs to be passed'; throw 'options needs to be passed';
} }
if(!options.context) {
if (!options.context) {
throw 'context needs to be passed'; throw 'context needs to be passed';
} }
this.left = options.left; this.left = options.left;
this.right = options.right; this.right = options.right;
this.toolbarContext = options.context; this.toolbarContext = options.context;
}, },
onShow : function(){
if(this.left) { onShow : function() {
if (this.left) {
_.each(this.left, this._showToolbarLeft, this); _.each(this.left, this._showToolbarLeft, this);
} }
if(this.right) { if (this.right) {
_.each(this.right, this._showToolbarRight, this); _.each(this.right, this._showToolbarRight, this);
} }
}, },
_showToolbarLeft : function(element, index){
_showToolbarLeft : function(element, index) {
this._showToolbar(element, index, 'left'); this._showToolbar(element, index, 'left');
}, },
_showToolbarRight : function(element, index){
_showToolbarRight : function(element, index) {
this._showToolbar(element, index, 'right'); this._showToolbar(element, index, 'right');
}, },
_showToolbar : function(buttonGroup, index, position){
_showToolbar : function(buttonGroup, index, position) {
var groupCollection = new ButtonCollection(); var groupCollection = new ButtonCollection();
_.each(buttonGroup.items, function(button){
if(buttonGroup.storeState && !button.key) { _.each(buttonGroup.items, function(button) {
if (buttonGroup.storeState && !button.key) {
throw 'must provide key for all buttons when storSstate is enabled'; throw 'must provide key for all buttons when storSstate is enabled';
} }
var model = new ButtonModel(button); var model = new ButtonModel(button);
model.set('menuKey', buttonGroup.menuKey); model.set('menuKey', buttonGroup.menuKey);
model.ownerContext = this.toolbarContext; model.ownerContext = this.toolbarContext;
groupCollection.add(model); groupCollection.add(model);
}, this); }, this);
var buttonGroupView; var buttonGroupView;
switch (buttonGroup.type) { switch (buttonGroup.type) {
case 'radio': case 'radio':
{ {
@ -77,13 +89,16 @@ module.exports = Marionette.Layout.extend({
break; break;
} }
} }
var regionId = position + '_' + (index + 1); var regionId = position + '_' + (index + 1);
var region = this[regionId]; var region = this[regionId];
if(!region) {
if (!region) {
var regionClassName = 'x-toolbar-' + position + '-' + (index + 1); var regionClassName = 'x-toolbar-' + position + '-' + (index + 1);
this.ui[position + '_x'].append('<div class="toolbar-group ' + regionClassName + '" />\r\n'); this.ui[position + '_x'].append('<div class="toolbar-group ' + regionClassName + '" />\r\n');
region = this.addRegion(regionId, '.' + regionClassName); region = this.addRegion(regionId, '.' + regionClassName);
} }
region.show(buttonGroupView); region.show(buttonGroupView);
} }
}); });

@ -22,7 +22,7 @@ Tooltip.prototype.getOptions = function(options) {
module.exports = { module.exports = {
appInitializer : function() { appInitializer : function() {
$('body').tooltip({selector : '[title]'}); $('body').tooltip({ selector : '[title]' });
return this; return this;
} }

@ -1,25 +1,29 @@
var Backbone = require('backbone'); var Backbone = require('backbone');
var ApiData = require('./ApiData'); var ApiData = require('./ApiData');
module.exports = (function(){ var UiSettings = Backbone.Model.extend({
var UiSettings = Backbone.Model.extend({ url : window.NzbDrone.ApiRoot + '/config/ui',
url : window.NzbDrone.ApiRoot + '/config/ui',
shortDateTime : function(includeSeconds){ shortDateTime : function(includeSeconds) {
return this.get('shortDateFormat') + ' ' + this.time(true, includeSeconds); return this.get('shortDateFormat') + ' ' + this.time(true, includeSeconds);
}, },
longDateTime : function(includeSeconds){
return this.get('longDateFormat') + ' ' + this.time(true, includeSeconds); longDateTime : function(includeSeconds) {
}, return this.get('longDateFormat') + ' ' + this.time(true, includeSeconds);
time : function(includeMinuteZero, includeSeconds){ },
if(includeSeconds) {
return this.get('timeFormat').replace(/\(?\:mm\)?/, ':mm:ss'); time : function(includeMinuteZero, includeSeconds) {
} if (includeSeconds) {
if(includeMinuteZero) { return this.get('timeFormat').replace(/\(?\:mm\)?/, ':mm:ss');
return this.get('timeFormat').replace('(', '').replace(')', ''); }
} if (includeMinuteZero) {
return this.get('timeFormat').replace(/\(\:mm\)/, ''); return this.get('timeFormat').replace('(', '').replace(')', '');
} }
});
var instance = new UiSettings(ApiData.get('config/ui')); return this.get('timeFormat').replace(/\(\:mm\)/, '');
return instance; }
}).call(this); });
var instance = new UiSettings(ApiData.get('config/ui'));
module.exports = instance;

@ -1,13 +1,13 @@
var $ = require('jquery'); var $ = require('jquery');
var vent = require('vent'); var vent = require('vent');
$(document).ajaxSuccess(function(event, xhr){ $(document).ajaxSuccess(function(event, xhr) {
var version = xhr.getResponseHeader('X-ApplicationVersion'); var version = xhr.getResponseHeader('X-ApplicationVersion');
if(!version || !window.NzbDrone || !window.NzbDrone.Version) { if (!version || !window.NzbDrone || !window.NzbDrone.Version) {
return; return;
} }
if(version !== window.NzbDrone.Version) { if (version !== window.NzbDrone.Version) {
vent.trigger(vent.Events.ServerUpdated); vent.trigger(vent.Events.ServerUpdated);
} }
}); });

@ -1,6 +1,4 @@
require('backgrid');
require('../JsLibraries/backbone.backgrid.selectall');
var backgrid = require('backgrid'); var backgrid = require('backgrid');
require('../JsLibraries/backbone.backgrid.selectall'); require('../JsLibraries/backbone.backgrid.selectall');
module.exports = backgrid.Extension.SelectRowCell; module.exports = backgrid.Extension.SelectRowCell;

@ -1,6 +1,4 @@
require('backbone');
require('../JsLibraries/backbone.collectionview');
window.Backbone = require('backbone'); window.Backbone = require('backbone');
require('../JsLibraries/backbone.collectionview'); require('../JsLibraries/backbone.collectionview');
module.exports = window.Backbone.CollectionView; module.exports = window.Backbone.CollectionView;

@ -1,7 +1,7 @@
var jquery = require('jquery'); var jquery = require('jquery');
var Backbone = require('../JsLibraries/backbone');
var backbone = require('../JsLibraries/backbone'); window.Backbone = Backbone;
window.Backbone = backbone; Backbone.$ = jquery;
backbone.$ = jquery;
module.exports = backbone; module.exports = Backbone;

@ -7,5 +7,4 @@ var asNamedView = require('../Mixins/AsNamedView');
templateMixin.call(window.Marionette.TemplateCache); templateMixin.call(window.Marionette.TemplateCache);
asNamedView.call(window.Marionette.ItemView.prototype); asNamedView.call(window.Marionette.ItemView.prototype);
module.exports = window.Marionette; module.exports = window.Marionette;

@ -1,6 +1,7 @@
require('backbone'); require('backbone');
require('../JsLibraries/backbone.validation'); require('../JsLibraries/backbone.validation');
var $ = require('jquery'); var $ = require('jquery');
var jqueryValidation = require('../jQuery/jquery.validation'); var jqueryValidation = require('../jQuery/jquery.validation');
jqueryValidation.call($); jqueryValidation.call($);

@ -1,6 +1,4 @@
require('../JsLibraries/jquery.signalR');
require('jquery');
require('jquery'); require('jquery');
var signalR = require('../JsLibraries/jquery.signalR'); var signalR = require('../JsLibraries/jquery.signalR');
module.exports = signalR; module.exports = signalR;

@ -1,7 +1,6 @@
require('../JsLibraries/messenger');
require('jquery');
require('jquery'); require('jquery');
var m = require('../JsLibraries/messenger'); var m = require('../JsLibraries/messenger');
window.Messenger.options = {theme : 'flat'};
window.Messenger.options = { theme : 'flat' };
module.exports = window.Messenger; module.exports = window.Messenger;

@ -1,6 +1,4 @@
require('../JsLibraries/moment');
require('backbone');
require('backbone'); require('backbone');
var backgrid = require('../JsLibraries/moment'); var backgrid = require('../JsLibraries/moment');
module.exports = backgrid; module.exports = backgrid;
Loading…
Cancel
Save