1
0
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:
Dan Barber 2013-12-04 16:36:19 +00:00
parent 3c7601d681
commit 57bfaa75db
10 changed files with 236 additions and 57 deletions

View File

@ -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'));
});

View 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
}));
}
});

View 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
View 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);

View File

@ -0,0 +1,5 @@
var QueueSong = can.Model.extend({
findAll: 'GET /api/queue'
}, {});

View File

@ -0,0 +1,5 @@
var Status = can.Model.extend({
findOne: 'GET /api/status'
}, {});

View File

@ -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
View 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>

View 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>

View File

@ -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>