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
|
||||
$(document).ready(function() {
|
||||
// Bind transport click events.
|
||||
$('#transport').on('click', '#controls button', function(e) {
|
||||
e.preventDefault();
|
||||
var action = $(e.currentTarget).data('action');
|
||||
can.ajax({ url: '/api/control/'+action, type: 'PUT' });
|
||||
|
||||
$.when(QueueSong.findAll(), Status.findOne()).then(function(queueSongs, status) {
|
||||
new Transport('#transport');
|
||||
new Queue('#queue', {
|
||||
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/handlebars-1.0.0
|
||||
//= require ./libs/can.jquery.min.js
|
||||
//= require ./libs/can.ejs.js
|
||||
|
||||
//= require ./application.js
|
||||
//= require_tree ./models/
|
||||
//= require_tree ./controls/
|
||||
//= 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>
|
||||
|
||||
<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' %>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user