mirror of
https://github.com/danbee/mpd-client
synced 2025-03-04 08:39:09 +00:00
Organise the shit out of everything.
This commit is contained in:
parent
3c7601d681
commit
57bfaa75db
@ -1,39 +1,12 @@
|
|||||||
var QueueSong = can.Model({
|
|
||||||
findAll: 'GET /api/queue'
|
|
||||||
}, {});
|
|
||||||
|
|
||||||
var queueSongs = new can.List();
|
|
||||||
|
|
||||||
// Update the queue display when the queueSongs list changes
|
|
||||||
queueSongs.bind('change', function(event) {
|
|
||||||
$('#queue').html(can.view('queueTemplate',
|
|
||||||
{ songs: this }));
|
|
||||||
});
|
|
||||||
|
|
||||||
// Get the songs currently in the queue
|
|
||||||
QueueSong.findAll({}, function(songs) {
|
|
||||||
queueSongs.replace(songs);
|
|
||||||
}, function(xhr) {
|
|
||||||
console.log("An error occured with the request.");
|
|
||||||
});
|
|
||||||
|
|
||||||
var updatePlaying = function(queue, index) {
|
|
||||||
queue.forEach(function(element) {
|
|
||||||
element.attr('playing', false);
|
|
||||||
});
|
|
||||||
item = queue.attr(index);
|
|
||||||
item.attr('playing', true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set up necessary events and startup stuff
|
// Set up necessary events and startup stuff
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
// Bind transport click events.
|
|
||||||
$('#transport').on('click', '#controls button', function(e) {
|
$.when(QueueSong.findAll(), Status.findOne()).then(function(queueSongs, status) {
|
||||||
e.preventDefault();
|
new Transport('#transport');
|
||||||
var action = $(e.currentTarget).data('action');
|
new Queue('#queue', {
|
||||||
can.ajax({ url: '/api/control/'+action, type: 'PUT' });
|
queueSongs: queueSongs,
|
||||||
|
status: status
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Render transport
|
|
||||||
$('#transport').html(can.view('transportTemplate'));
|
|
||||||
});
|
});
|
||||||
|
|||||||
10
assets/js/controls/queue.js
Normal file
10
assets/js/controls/queue.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
var Queue = can.Control.extend({
|
||||||
|
|
||||||
|
init: function(element, options) {
|
||||||
|
element.html(can.view('views/queue.ejs', {
|
||||||
|
queueSongs: options.queueSongs,
|
||||||
|
status: options.status
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
16
assets/js/controls/transport.js
Normal file
16
assets/js/controls/transport.js
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
var Transport = can.Control.extend({
|
||||||
|
|
||||||
|
init: function(element) {
|
||||||
|
element.html(can.view('views/transport.ejs'));
|
||||||
|
},
|
||||||
|
|
||||||
|
sendCommand: function(command) {
|
||||||
|
can.ajax({ url: '/api/control/'+command, type: 'PUT' });
|
||||||
|
},
|
||||||
|
|
||||||
|
'button click': function(element, event) {
|
||||||
|
var command = $(element).data('command');
|
||||||
|
this.sendCommand(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
174
assets/js/libs/can.ejs.js
Executable file
174
assets/js/libs/can.ejs.js
Executable file
@ -0,0 +1,174 @@
|
|||||||
|
/*!
|
||||||
|
* CanJS - 2.0.3
|
||||||
|
* http://canjs.us/
|
||||||
|
* Copyright (c) 2013 Bitovi
|
||||||
|
* Tue, 26 Nov 2013 18:21:40 GMT
|
||||||
|
* Licensed MIT
|
||||||
|
* Includes: can/view/ejs
|
||||||
|
* Download from: http://canjs.com
|
||||||
|
*/
|
||||||
|
(function(can) {
|
||||||
|
// ## ejs.js
|
||||||
|
// `can.EJS`
|
||||||
|
// _Embedded JavaScript Templates._
|
||||||
|
|
||||||
|
// Helper methods.
|
||||||
|
var extend = can.extend,
|
||||||
|
EJS = function(options) {
|
||||||
|
// Supports calling EJS without the constructor
|
||||||
|
// This returns a function that renders the template.
|
||||||
|
if (this.constructor != EJS) {
|
||||||
|
var ejs = new EJS(options);
|
||||||
|
return function(data, helpers) {
|
||||||
|
return ejs.render(data, helpers);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
// If we get a `function` directly, it probably is coming from
|
||||||
|
// a `steal`-packaged view.
|
||||||
|
if (typeof options == "function") {
|
||||||
|
this.template = {
|
||||||
|
fn: options
|
||||||
|
};
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Set options on self.
|
||||||
|
extend(this, options);
|
||||||
|
this.template = this.scanner.scan(this.text, this.name);
|
||||||
|
};
|
||||||
|
|
||||||
|
can.EJS = EJS;
|
||||||
|
|
||||||
|
|
||||||
|
EJS.prototype.
|
||||||
|
|
||||||
|
render = function(object, extraHelpers) {
|
||||||
|
object = object || {};
|
||||||
|
return this.template.fn.call(object, object, new EJS.Helpers(object, extraHelpers || {}));
|
||||||
|
};
|
||||||
|
|
||||||
|
extend(EJS.prototype, {
|
||||||
|
|
||||||
|
scanner: new can.view.Scanner({
|
||||||
|
text: {
|
||||||
|
outStart: 'with(_VIEW) { with (_CONTEXT) {',
|
||||||
|
outEnd: "}}",
|
||||||
|
argNames: '_CONTEXT,_VIEW'
|
||||||
|
},
|
||||||
|
|
||||||
|
tokens: [
|
||||||
|
["templateLeft", "<%%"], // Template
|
||||||
|
["templateRight", "%>"], // Right Template
|
||||||
|
["returnLeft", "<%=="], // Return Unescaped
|
||||||
|
["escapeLeft", "<%="], // Return Escaped
|
||||||
|
["commentLeft", "<%#"], // Comment
|
||||||
|
["left", "<%"], // Run --- this is hack for now
|
||||||
|
["right", "%>"], // Right -> All have same FOR Mustache ...
|
||||||
|
["returnRight", "%>"]
|
||||||
|
],
|
||||||
|
helpers: [
|
||||||
|
|
||||||
|
{
|
||||||
|
name: /\s*\(([\$\w]+)\)\s*->([^\n]*)/,
|
||||||
|
fn: function(content) {
|
||||||
|
var quickFunc = /\s*\(([\$\w]+)\)\s*->([^\n]*)/,
|
||||||
|
parts = content.match(quickFunc);
|
||||||
|
|
||||||
|
return "can.proxy(function(__){var " + parts[1] + "=can.$(__);" + parts[2] + "}, this);";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
transform: function(source) {
|
||||||
|
return source.replace(/<%([\s\S]+?)%>/gm, function(whole, part) {
|
||||||
|
var brackets = [],
|
||||||
|
foundBracketPair,
|
||||||
|
i;
|
||||||
|
|
||||||
|
// Look for brackets (for removing self-contained blocks)
|
||||||
|
part.replace(/[{}]/gm, function(bracket, offset) {
|
||||||
|
brackets.push([bracket, offset]);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Remove bracket pairs from the list of replacements
|
||||||
|
do {
|
||||||
|
foundBracketPair = false;
|
||||||
|
for (i = brackets.length - 2; i >= 0; i--) {
|
||||||
|
if (brackets[i][0] == '{' && brackets[i + 1][0] == '}') {
|
||||||
|
brackets.splice(i, 2);
|
||||||
|
foundBracketPair = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (foundBracketPair);
|
||||||
|
|
||||||
|
// Unmatched brackets found, inject EJS tags
|
||||||
|
if (brackets.length >= 2) {
|
||||||
|
var result = ['<%'],
|
||||||
|
bracket,
|
||||||
|
last = 0;
|
||||||
|
for (i = 0; bracket = brackets[i]; i++) {
|
||||||
|
result.push(part.substring(last, last = bracket[1]));
|
||||||
|
if ((bracket[0] == '{' && i < brackets.length - 1) || (bracket[0] == '}' && i > 0)) {
|
||||||
|
result.push(bracket[0] == '{' ? '{ %><% ' : ' %><% }');
|
||||||
|
} else {
|
||||||
|
result.push(bracket[0]);
|
||||||
|
}
|
||||||
|
++last;
|
||||||
|
}
|
||||||
|
result.push(part.substring(last), '%>');
|
||||||
|
return result.join('');
|
||||||
|
}
|
||||||
|
// Otherwise return the original
|
||||||
|
else {
|
||||||
|
return '<%' + part + '%>';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
EJS.Helpers = function(data, extras) {
|
||||||
|
this._data = data;
|
||||||
|
this._extras = extras;
|
||||||
|
extend(this, extras);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
EJS.Helpers.prototype = {
|
||||||
|
// TODO Deprecated!!
|
||||||
|
list: function(list, cb) {
|
||||||
|
|
||||||
|
can.each(list, function(item, i) {
|
||||||
|
cb(item, i, list)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
each: function(list, cb) {
|
||||||
|
// Normal arrays don't get live updated
|
||||||
|
if (can.isArray(list)) {
|
||||||
|
this.list(list, cb);
|
||||||
|
} else {
|
||||||
|
can.view.lists(list, cb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Options for `steal`'s build.
|
||||||
|
can.view.register({
|
||||||
|
suffix: "ejs",
|
||||||
|
// returns a `function` that renders the view.
|
||||||
|
script: function(id, src) {
|
||||||
|
return "can.EJS(function(_CONTEXT,_VIEW) { " + new EJS({
|
||||||
|
text: src,
|
||||||
|
name: id
|
||||||
|
}).template.out + " })";
|
||||||
|
},
|
||||||
|
renderer: function(id, text) {
|
||||||
|
return EJS({
|
||||||
|
text: text,
|
||||||
|
name: id
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return can;
|
||||||
|
})(can);
|
||||||
5
assets/js/models/queueSongs.js
Normal file
5
assets/js/models/queueSongs.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
var QueueSong = can.Model.extend({
|
||||||
|
|
||||||
|
findAll: 'GET /api/queue'
|
||||||
|
|
||||||
|
}, {});
|
||||||
5
assets/js/models/status.js
Normal file
5
assets/js/models/status.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
var Status = can.Model.extend({
|
||||||
|
|
||||||
|
findOne: 'GET /api/status'
|
||||||
|
|
||||||
|
}, {});
|
||||||
@ -1,6 +1,8 @@
|
|||||||
//= require ./libs/jquery-1.10.2.min
|
//= require ./libs/jquery-1.10.2.min
|
||||||
//= require ./libs/handlebars-1.0.0
|
|
||||||
//= require ./libs/can.jquery.min.js
|
//= require ./libs/can.jquery.min.js
|
||||||
|
//= require ./libs/can.ejs.js
|
||||||
|
|
||||||
//= require ./application.js
|
//= require_tree ./models/
|
||||||
|
//= require_tree ./controls/
|
||||||
//= require ./router.js
|
//= require ./router.js
|
||||||
|
//= require ./application.js
|
||||||
|
|||||||
8
public/views/queue.ejs
Normal file
8
public/views/queue.ejs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<h2>Queue</h2>
|
||||||
|
<ul id="queue">
|
||||||
|
<% list(queueSongs, function(song) { %>
|
||||||
|
<li id="<%= song.attr('id') %>"<%= song.attr('id') == status.songid ? ' class="playing"' : '' %>>
|
||||||
|
<%= song.attr('artist') %> - <%= song.attr('title') %>
|
||||||
|
</li>
|
||||||
|
<% }) %>
|
||||||
|
</ul>
|
||||||
7
public/views/transport.ejs
Normal file
7
public/views/transport.ejs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<div id="controls">
|
||||||
|
<button data-command="previous">previous</button>
|
||||||
|
<button data-command="play">play</button>
|
||||||
|
<button data-command="pause">pause</button>
|
||||||
|
<button data-command="stop">stop</button>
|
||||||
|
<button data-command="next">next</button>
|
||||||
|
</div>
|
||||||
@ -13,27 +13,6 @@
|
|||||||
|
|
||||||
<div id="transport"></div>
|
<div id="transport"></div>
|
||||||
|
|
||||||
<script type="text/mustache" id="queueTemplate">
|
|
||||||
<h2>Queue</h2>
|
|
||||||
<ul id="queue">
|
|
||||||
{{#songs}}
|
|
||||||
<li id="{{ id }}"{{#playing}} class="playing"{{/playing}}>{{ artist }} - {{ title }}</li>
|
|
||||||
{{/songs}} {{^songs}}
|
|
||||||
<li>Play queue empty</li>
|
|
||||||
{{/songs}}
|
|
||||||
</ul>
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script type="text/mustache-handlebars" id="transportTemplate">
|
|
||||||
<div id="controls">
|
|
||||||
<button data-action="previous">previous</button>
|
|
||||||
<button data-action="play">play</button>
|
|
||||||
<button data-action="pause">pause</button>
|
|
||||||
<button data-action="stop">stop</button>
|
|
||||||
<button data-action="next">next</button>
|
|
||||||
</div>
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<%= javascript_tag 'mpd-client' %>
|
<%= javascript_tag 'mpd-client' %>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user