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.
529 lines
12 KiB
529 lines
12 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();
|
|
|
|
that._setPlayOrder();
|
|
}
|
|
|
|
, hide: function () {
|
|
var that = this
|
|
;
|
|
|
|
this.$el.hide();
|
|
}
|
|
|
|
, _setPlayOrder: function () {
|
|
var that = this
|
|
, playIndex = []
|
|
;
|
|
|
|
playIndex = _.map(that.dataTable.fnSettings().aiDisplay, function (id, index) {
|
|
var itemData = that.dataTable.fnGetData(id)
|
|
, itemIndex = {}
|
|
;
|
|
|
|
if (that.options.type === "playlist") {
|
|
itemIndex.hostname = itemData.server;
|
|
itemIndex.dbId = itemData.database;
|
|
itemIndex.playlist = true;
|
|
} else {
|
|
itemIndex.hostname = that.options.client.hostname;
|
|
itemIndex.dbId = that.options.client.dbId;
|
|
itemIndex.playlist = null;
|
|
}
|
|
|
|
itemIndex.dmap_itemname = itemData["dmap_itemname"];
|
|
itemIndex.daap_songartist = itemData["daap_songartist"];
|
|
itemIndex.daap_songtime = itemData["daap_songtime"];
|
|
|
|
itemIndex.type = itemData["daap_songformat"];
|
|
itemIndex.id = itemData["dmap_persistantid"] || itemData["dmap_itemid"] || itemData["dmap_containeritemid"] || itemData["id"];
|
|
|
|
return itemIndex;
|
|
});
|
|
|
|
that.trigger("action:playorder", playIndex);
|
|
}
|
|
});
|
|
|
|
return List;
|
|
}); |