You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							494 lines
						
					
					
						
							11 KiB
						
					
					
				
			
		
		
	
	
							494 lines
						
					
					
						
							11 KiB
						
					
					
				| /*jslint laxbreak:true */
 | |
| /*jslint laxcomma:true */
 | |
| /*jslint loopfunc:true */
 | |
| /*jslint strict:true */
 | |
| /*jslint browser:true */
 | |
| /*jslint devel:true */
 | |
| define([
 | |
| 	"underscore"
 | |
| 	, "jquery"
 | |
| 	, "backbone"
 | |
| 	, "bootstrap"
 | |
| 
 | |
| 	, "text!../../templates/view-list.html"
 | |
| 
 | |
| 	, "jquery-ui"
 | |
| 	, "jquery-event-drag"
 | |
| 	, "jquery-clone-styles"
 | |
| 
 | |
| 	, "datatables"
 | |
| 	, "dt-scroller"
 | |
| 	, "dt-tabletools"
 | |
| 	, "dt-colreorder"
 | |
| ]
 | |
| , function (
 | |
| _
 | |
| , $
 | |
| , Backbone
 | |
| , Bootstrap
 | |
| 
 | |
| , tmplListView
 | |
| ) {
 | |
| 	"use strict";
 | |
| 
 | |
| 	var List	= Backbone.View.extend({
 | |
| 		options:			{
 | |
| 			type:	"playlist"
 | |
| 		}
 | |
| 
 | |
| 	, dataTable:			null
 | |
| 
 | |
| 	, tableSchemaDefaults:	{
 | |
| 
 | |
| 	}
 | |
| 
 | |
| 	, tableSchema:			[
 | |
| 		{	// Now playing column
 | |
| 			mData:				null
 | |
| 			, sTitle:			""
 | |
| 			, sDefaultContent:	""
 | |
| 			, bSortable:		false
 | |
| 			, bSearchable:		false
 | |
| 			, sWidth:			"15px"
 | |
| 			, fnCreatedCell:	function(nTd, sData, oData, iRow, iCol) {
 | |
| 				var span	= document.createElement("span");
 | |
| 				nTd.appendChild(span);
 | |
| 			}
 | |
| 		}
 | |
| 		, {
 | |
| 			mData:				"dmap_itemname"
 | |
| 			, sTitle:			"Title"
 | |
| 			, sDefaultContent:	"Unknown"
 | |
| 		}
 | |
| 		, {
 | |
| 			mData:				"daap_songartist"
 | |
| 			, sTitle:			"Artist"
 | |
| 			, sDefaultContent:	"Unknown"
 | |
| 			, aDataSort:		[2, 6, 3, 5, 4]
 | |
| 		}
 | |
| 		, {
 | |
| 			mData:				"daap_songalbum"
 | |
| 			, sTitle:			"Album"
 | |
| 			, sDefaultContent:	"Unknown"
 | |
| 			, aDataSort:		[3, 6, 5, 4]
 | |
| 		}
 | |
| 		, {
 | |
| 			mData:				"daap_songtracknumber"
 | |
| 			, sTitle:			"Track"
 | |
| 			, sClass:			"center"
 | |
| 			, sDefaultContent:	""
 | |
| 			/*, sType:			"numeric"*/
 | |
| 			, sWidth:			"75px"
 | |
| 			, mRender:			function(data, type, full) {
 | |
| 				if (data === "") {
 | |
| 					return "";
 | |
| 				} else if (full.daap_songtrackcount) {
 | |
| 					return data + " of " + full.daap_songtrackcount;
 | |
| 				} else {
 | |
| 					return data;
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		, {
 | |
| 			mData:				"daap_songdiscnumber"
 | |
| 			, sTitle:			"Disc"
 | |
| 			, sClass:			"center"
 | |
| 			, sDefaultContent:	"Unknown"
 | |
| 			/*, sType:			"numeric"*/
 | |
| 			, sWidth:			"50px"
 | |
| 			, mRender:			function(data, type, full) {
 | |
| 				if (data === "") {
 | |
| 					return "";
 | |
| 				} else if (full.daap_songdisccount) {
 | |
| 					return data + " of " + full.daap_songdisccount;
 | |
| 				} else {
 | |
| 					return data;
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		, {
 | |
| 			mData:				"daap_songyear"
 | |
| 			, sTitle:			"Year"
 | |
| 			, sClass:			"center"
 | |
| 			, sDefaultContent:	""
 | |
| 			, sType:			"numeric"
 | |
| 			, sWidth:			"50px"
 | |
| 		}
 | |
| 		, {
 | |
| 			mData:				"daap_songgenre"
 | |
| 			, sTitle:			"Genre"
 | |
| 			, sClass:			"center"
 | |
| 			, sDefaultContent:	""
 | |
| 			, bVisible:			false
 | |
| 		}
 | |
| 		, {
 | |
| 			mData:				"daap_songtime"
 | |
| 			, sTitle:			"Time"
 | |
| 			, sClass:			"center"
 | |
| 			, sDefaultContent:	""
 | |
| 			/*, sType:			"numeric"*/
 | |
| 			, sWidth:			"75px"
 | |
| 			, bVisible:			true
 | |
| 			, mRender:			function(data, type, full) {
 | |
| 				if (data !== "") {
 | |
| 					return songMSTimeFormat(data);
 | |
| 				} else {
 | |
| 					return data;
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		, {
 | |
| 			mData:				"daap_songuserrating"
 | |
| 			, sTitle:			"Rating"
 | |
| 			, sClass:			"center"
 | |
| 			, sType:			"numeric"
 | |
| 			, sDefaultContent:	""
 | |
| 			, bVisible:			false
 | |
| 		}
 | |
| 		, {
 | |
| 			mData:				"dmap_itemid"
 | |
| 			, sTitle:			"ID"
 | |
| 			, sClass:			"center"
 | |
| 			, sDefaultContent:	""
 | |
| 			, bVisible:			false
 | |
| 		}
 | |
| 	]
 | |
| 
 | |
| 	, detailsFields:	[
 | |
| 		{
 | |
| 			title:		"Title"
 | |
| 			, field:	"dmap_itemname"
 | |
| 		}
 | |
| 		, {
 | |
| 			title:		"Artist"
 | |
| 			, field:	"daap_songartist"
 | |
| 		}
 | |
| 		, {
 | |
| 			title:		"Album"
 | |
| 			, field:	"daap_songalbum"
 | |
| 		}
 | |
| 		, {
 | |
| 			title:		"Composer"
 | |
| 			, field:	"daap_songcomposer"
 | |
| 		}
 | |
| 		, {
 | |
| 			title:		"Genre"
 | |
| 			, field:	"daap_songgenre"
 | |
| 		}
 | |
| 		, {
 | |
| 			title:		"Track Number"
 | |
| 			, field:	"daap_songtracknumber"
 | |
| 			, render:	function(data, full) {
 | |
| 				var value	= data;
 | |
| 
 | |
| 				if (data === "") {
 | |
| 					value	= "Unknown";
 | |
| 				}
 | |
| 
 | |
| 				if (typeof full.daap_songtrackcount !== "undefined") {
 | |
| 					value	+= " of " + full.daap_songtrackcount;
 | |
| 				}
 | |
| 
 | |
| 				return value;
 | |
| 			}
 | |
| 		}
 | |
| 		, {
 | |
| 			title:		"Disc Number"
 | |
| 			, field:	"daap_songdiscnumber"
 | |
| 			, render:	function(data, full) {
 | |
| 				var value	= data;
 | |
| 
 | |
| 				if (typeof full.daap_songdisccount !== "undefined") {
 | |
| 					value	+= " of " + full.daap_songdisccount;
 | |
| 				}
 | |
| 
 | |
| 				return value;
 | |
| 			}
 | |
| 		}
 | |
| 		, {
 | |
| 			title:		"Year"
 | |
| 			, field:	"daap_songyear"
 | |
| 		}
 | |
| 		, {
 | |
| 			title:		"Rating"
 | |
| 			, field:	"daap_songuserrating"
 | |
| 		}
 | |
| 		, {
 | |
| 			title:		"Compilation"
 | |
| 			, field:	"daap_songcompilation"
 | |
| 			, defaults:	"No"
 | |
| 			, render:	function (data, full) {
 | |
| 				return (data == 1 ? "Yes" : "No");
 | |
| 			}
 | |
| 		}
 | |
| 		, {
 | |
| 			title:		"Duration"
 | |
| 			, field:	"daap_songtime"
 | |
| 			, render:	function (data, full) {
 | |
| 				return songMSTimeFormat(data);
 | |
| 			}
 | |
| 		}
 | |
| 		, {
 | |
| 			title:		"BPM"
 | |
| 			, field:	"daap_songbeatsperminute"
 | |
| 		}
 | |
| 		, {
 | |
| 			title:		"Bit Rate"
 | |
| 			, field:	"daap_songbitrate"
 | |
| 			, render:	function (data, full) {
 | |
| 				if (data > 0) {
 | |
| 					data += "kbps";
 | |
| 				}
 | |
| 
 | |
| 				return data;
 | |
| 			}
 | |
| 		}
 | |
| 		, {
 | |
| 			title:		"Sample Rate"
 | |
| 			, field:	"daap_songsamplerate"
 | |
| 			, render:	function (data, full) {
 | |
| 				if (data !== "") {
 | |
| 					if (data > 1000) {
 | |
| 						data = (data / 1000) + "k";
 | |
| 					}
 | |
| 
 | |
| 					data += "Hz";
 | |
| 				}
 | |
| 
 | |
| 				return data;
 | |
| 			}
 | |
| 		}
 | |
| 		, {
 | |
| 			title:		"Date added"
 | |
| 			, field:	"daap_songdateadded"
 | |
| 		}
 | |
| 	]
 | |
| 
 | |
| 	, tableSort:	[]
 | |
| 
 | |
| 		, initialize:	function (options) {
 | |
| 			_.bindAll(this
 | |
| 				, "resize"
 | |
| 				, "render"
 | |
| 				, "show"
 | |
| 				, "hide"
 | |
| 			);
 | |
| 
 | |
| 			var that	= this
 | |
| 			;
 | |
| 
 | |
| 			if (options && options.el) {
 | |
| 				$(options.el).html(tmplListView);
 | |
| 			} else {
 | |
| 				options					= options || {};
 | |
| 				options.el				= document.createElement("div");
 | |
| 
 | |
| 				options.el.id			= "__view-playlist";
 | |
| 				options.el.className	= "playlist-view-container";
 | |
| 
 | |
| 				$(options.el).html(tmplListView);
 | |
| 
 | |
| 				this.el					= options.el;
 | |
| 				this.$el				= $(this.el);
 | |
| 			}
 | |
| 
 | |
| 			List.__super__.initialize.apply(this, arguments);
 | |
| 
 | |
| 			if (that.options.type === "playlist" && that.options.collection) {
 | |
| 				that.options.collection.fetch();
 | |
| 				that.options.collection.on("add", function __fnPlaylistAddRow(model) {
 | |
| 					if (that.dataTable) {
 | |
| 						that.dataTable.fnAddData(model.toJSON(), that.$el.is(":visible"));
 | |
| 					}
 | |
| 				});
 | |
| 			}
 | |
| 
 | |
| 			return this;
 | |
| 		}
 | |
| 
 | |
| 		// FIXME: Sometimes the parent element's size is 0 and resizing fails.
 | |
| 		, resize:		function () {
 | |
| 			var that			= this
 | |
| 			,	parentEl		= that.options.parentEl || that.$el.parent()
 | |
| 			,	parentWidth		= parentEl.innerWidth()
 | |
| 			,	parentHeight	= parentEl.innerHeight()
 | |
| 			;
 | |
| console.log(parentWidth, that.$el.innerWidth(), parentHeight, that.$el, parentEl);
 | |
| 			that.$el.find(".dataTables_scrollBody").height(that.$el.innerHeight() - 20);
 | |
| 			that.$el.width(parentWidth);
 | |
| 			that.$el.find(".dataTables_wrapper").width(parentWidth);
 | |
| 			that.$el.find(".dataTables_scrollBody").width(parentWidth);
 | |
| 			that.$el.find(".dataTables_scroll").width(parentWidth);
 | |
| 			that.$el.find(".dataTables_scrollHeadInner").width(parentWidth);
 | |
| 			that.$el.find(".dataTables_scrollHeadInner table").width(parentWidth);
 | |
| 			that.$el.parent().find("span[resizer='north']").width(parentWidth);
 | |
| 		}
 | |
| 
 | |
| 		, render:		function () {
 | |
| 			var that			= this
 | |
| 			,	initialHeight	= that.$el.innerHeight() - 20
 | |
| 			,	dataTableOpts	= {
 | |
| 				sScrollY:			initialHeight + "px"
 | |
| 				, sDom:				"RTrtS"
 | |
| 				, oColReorder:		{
 | |
| 					iFixedColumns:	1
 | |
| 				}
 | |
| 				, bInfo:			false
 | |
| 				, bLengthChange:	false
 | |
| 				, bAutoWidth:		false
 | |
| 				, bFilter:			true
 | |
| 				, bDeferRender:		true
 | |
| 				, bStateSave:		false//true
 | |
| 				, bScrollCollapse:	true
 | |
| 				, bJQueryUI:		true
 | |
| 				, sHeightMatch:		"auto"
 | |
| 				, sEmptyTable:		""
 | |
| 				//, bProcessing:		true
 | |
| 				//, bServerSide:		true
 | |
| 
 | |
| 				, aaData:			that.collection.toJSON()
 | |
| 
 | |
| 				, aoColumns:		that.tableSchema
 | |
| 
 | |
| 				, oTableTools:		{
 | |
| 					sRowSelect:			"single"
 | |
| 					, sSelectedClass:	"selected"
 | |
| 					, aButtons:			[]
 | |
| 				}
 | |
| 
 | |
| 				, fnCreatedRow: function(nRow, aData, iDataIndex) {
 | |
| 					if (that.options.type !== "playlist") {
 | |
| 						$(nRow).draggable({
 | |
| 							scope:				"list-item"
 | |
| 							, stack:			"droppable"
 | |
| 							, cursor:			"copy"
 | |
| 							, revert:			"invalid"
 | |
| 							, containment:		"window"
 | |
| 							, revertDuration:	200
 | |
| 							, scroll:			false
 | |
| 
 | |
| 							, start: function(event, ui) {
 | |
| 								$(this).fadeTo("fast", 0.5);
 | |
| 							}
 | |
| 
 | |
| 							, stop: function(event, ui) {
 | |
| 								$(this).fadeTo(0, 1);
 | |
| 							}
 | |
| 
 | |
| 							, helper:	function (event) {
 | |
| 								var dragEl	= $('<div class="drag-table-item"><table></table></div>')
 | |
| 										.find("table")
 | |
| 										.append(
 | |
| 											$(this)
 | |
| 											.closest("tr")
 | |
| 											.clone()
 | |
| 											//.css($(this).getStyleObject())
 | |
| 											.addClass("selected")
 | |
| 										)
 | |
| 										.parent()
 | |
| 								;
 | |
| 
 | |
| 								//console.debug("Extracting draggable", this, dragEl);
 | |
| 								return dragEl.prependTo('body').css('zIndex',10000).show();
 | |
| 								//return dragEl
 | |
| 								//		.appendTo("body")
 | |
| 								//		.css("zIndex", "5000")
 | |
| 								//		.show();
 | |
| 							}
 | |
| 						})
 | |
| 						.data("hostname",	that.options.client.hostname)
 | |
| 						.data("dbId",		that.options.client.dbId)
 | |
| 						.data("item",		aData.id)
 | |
| 						;
 | |
| 					}
 | |
| 					// create a view for the row
 | |
| 					//var rowModel = that.collection.get(aData.id);
 | |
| 					//view.rows.push(new DtRowView({id: aData.id, el: nRow, model: rowModel}));
 | |
| 				}
 | |
| 
 | |
| 				, fnServerData: function(sSource, aoData, fnCallback, settings) {
 | |
| 					console.log(sSource, aoData, fnCallback, settings);
 | |
| 				}
 | |
| /*
 | |
| 					// function used to populate the DataTable with the current
 | |
| 					// content of the collection
 | |
| 					var populateTable = function()
 | |
| 					{
 | |
| 					// clear out old row views
 | |
| 					var rows = [];
 | |
| 
 | |
| 					// these 'meta' attributes are set by the collection's parse method
 | |
| 					var totalSize = that.collection.meta('totalSize');
 | |
| 					var filteredSize = that.collection.meta('filteredSize');
 | |
| 
 | |
| 					return fnCallback({iTotalRecords: totalSize,
 | |
| 						iTotalDisplayRecords: filteredSize,
 | |
| 						aaData: that.collection.toJSON()});
 | |
| 					};
 | |
| 
 | |
| 					aoData.shift(); // ignore sEcho
 | |
| 					var params = $.param(aoData);
 | |
| 
 | |
| 					if (params != that.constraint)
 | |
| 					{
 | |
| 						// trigger param:change event with new parameters. Pass in
 | |
| 						// populateTable function so fnCallback can be called after
 | |
| 						// the data has been refreshed. Note that we cannot just call
 | |
| 						// <a href="/ref#fnDraw">fnDraw</a> on the collection reset event since closure state
 | |
| 						// in the fnCallback passed to this method would be lost.
 | |
| 						that.trigger("param:change", params, populateTable);
 | |
| 					}
 | |
| 					else
 | |
| 					{
 | |
| 						// no filter change, just populate the table
 | |
| 						populateTable();
 | |
| 					}
 | |
| 				}
 | |
|  */
 | |
| 			}
 | |
| 			;
 | |
| 
 | |
| 			// Default sorting order
 | |
| 			if (that.options.type !== "playlist") {
 | |
| 				dataTableOpts.aaSorting		= [[2, "asc"], [6, "asc"], [3, "asc"], [5, "asc"], [4, "asc"]];
 | |
| 			} else {
 | |
| 				var schemaLastItem			= (that.tableSchema.length - 1);
 | |
| 				dataTableOpts.aaSorting		= [[schemaLastItem, "asc"]];
 | |
| 				that.tableSchema[schemaLastItem].mData	= "order";
 | |
| 
 | |
| 				for (var i = 0; i < schemaLastItem; i++) {
 | |
| 					that.tableSchema[i].bSortable	= false;
 | |
| 				}
 | |
| 
 | |
| 				dataTableOpts.aoColumns		= that.tableSchema;
 | |
| 			}
 | |
| 
 | |
| 			this.dataTable	= this.$el.find("table:first").dataTable(dataTableOpts);
 | |
| 
 | |
| 		}
 | |
| 
 | |
| 		, show:		function () {
 | |
| 			var that	= this
 | |
| 			;
 | |
| 
 | |
| 			if (!that.dataTable) {
 | |
| 				that.render();
 | |
| 			}
 | |
| 
 | |
| 			that.$el.show();
 | |
| 
 | |
| 			that.dataTable.fnDraw();
 | |
| 
 | |
| 			that.resize();
 | |
| 		}
 | |
| 
 | |
| 		, hide:		function () {
 | |
| 			var that	= this
 | |
| 			;
 | |
| 
 | |
| 			this.$el.hide();
 | |
| 		}
 | |
| 	});
 | |
| 
 | |
| 	return List;
 | |
| }); |