1
0
mirror of https://github.com/balkian/go5ears.git synced 2024-11-25 14:42:27 +00:00

Added knockout.js and simple controls

This commit is contained in:
J.Fernando Sánchez 2012-10-08 03:09:30 +02:00
parent a8d1bd9a7e
commit 27388ebc09
3 changed files with 195 additions and 87 deletions

1
.gitignore vendored
View File

@ -1,4 +1,5 @@
*.swp *.swp
go5ears.vim
lib-cov lib-cov
*.seed *.seed
*.log *.log

212
js/app.js
View File

@ -1,68 +1,10 @@
$(document).ready(function(){
var audio; var audio;
var playlist;
var tracks; var tracks;
var current; var shuffle = ko.observable(false);
var repeat = ko.observable(false);
function pauseSelected(id,emitter){ var repeatAll = ko.observable(false);
var newUrl = 'play?id='+id; var playlist = ko.observableArray();
console.log("Already playing:"+audio.src);
audio.pause();
$(emitter).addClass('ui-icon ui-icon-play').removeClass('ui-icon-pause');
$(emitter).unbind('click');
$(emitter).click(function(){
playSelected(id,emitter);
});
}
function resumeSelected(id,emitter){
console.log("Resuming:"+audio.src);
audio.play();
$(emitter).addClass('ui-icon ui-icon-pause').removeClass('ui-icon-stop ui-icon-play');
$(emitter).unbind('click');
$(emitter).click(function(){
pauseSelected(id,emitter);
});
}
function playSelected(id,emitter){
if(audio.src.indexOf(id)!=-1){
resumeSelected(id,emitter);
}
else{
console.log("Not playing:"+audio.src);
audio.src = 'play?id='+id;
audio.load();
$(emitter).removeAttr('onClick');
$(".list-controls > span").removeClass('ui-icon-stop ui-icon-pause').addClass('ui-icon-play');
resumeSelected(id,emitter);
}
}
function search(term){
$.ajax({url:'/search?id='+term,
dataType: 'json',
success: function(data){
for(var i=0; i<data.length;i++){
var title = data[i]["title"];
var group = data[i]["group"];
var id = data[i]["id"];
var newLi = toHtml(id,group,title);
$('#searchresults').append(newLi);
}
}
});
};
function addSelected(id,group,title){
$('#playlist').append(toHtml(id,group,title));
}
function toHtml(id,group,title){
return '<li class="ui-state-default">'+
' <div class="list-controls">'+
' <span class="ui-icon ui-icon-play" onClick=\'playSelected("'+id+'",this)\'></span>'+
' <span class="ui-icon ui-icon-circle-plus" onClick=\'addSelected("'+id+'","'+group+'","'+title+'")\'></span>'+
' <a href="play?id='+id+'"><span class="ui-icon ui-icon-arrowthickstop-1-s"></span></a>'+
' </div>'+
' <div class="list-name">'+group+' - '+title+'</div>'+
'</li>';
}
$(function() { $(function() {
$( ".sortable" ).sortable(); $( ".sortable" ).sortable();
@ -75,19 +17,145 @@ $('.accordion .head').click(function() {
return false; return false;
}).next().hide(); }).next().hide();
$(document).ready(function(){
audio = $('audio')[0];
playlist = $('#playlist');
tracks = [];
var champions = { id:"4b9ed95", var champions = { id:"4b9ed95",
title:"We are the champions", title:"We are the champions",
group:"Queen"}; group:"Queen"};
var libertine = { id:"fe7e4f9", var libertine = { id:"fe7e4f9",
title:"Libertine", title:"Libertine",
group:"Kate Ryan"}; group:"Kate Ryan"};
addSelected(libertine["id"],libertine["title"],libertine["group"]);
addSelected(champions["id"],champions["title"],champions["group"]); var playlist = ko.observableArray();
function Song(id, group, title) {
var self = this;
self.id = ko.observable(id);
self.group = ko.observable(group);
self.title = ko.observable(title);
self.isPlaying = ko.observable(false);
// Computed data
self.formattedName = ko.computed(function() {
console.log("Recomputed");
return playlist().indexOf(self)+"/"+playlist().length+" "+self.group() +" - "+self.title();
}, this);
self.playSong = function(){
console.log("Playing song");
playSelected(self);
}
self.pauseSong = function(){
console.log("Pausing song");
pauseSelected(self);
}
}
function PlaylistViewModel() {
// Data
var self = this;
self.results = ko.observableArray([]);
self.queryString = ko.observable();
self.shuffle = shuffle;
self.current = ko.observable();
self.repeat = repeat;
self.repeatAll = repeatAll;
self.playlist = playlist;
self.trackNumber = ko.computed(function(){
console.log("Recomputed");
return this.playlist.indexOf(this.current())+"/"+this.playlist().length;
},this);
self.addSong = function(song){
console.log("Adding song");
addSelected(song);
}
// Operations
self.getResults = function(form) {
// console.log("Form:"+JSON.stringify(form));
$.getJSON("/search?id="+self.queryString(), function(allData) {
var results = $.map(allData, function(item) { console.log(JSON.stringify(item)); return new Song(item.id,item.group,item.title) });
self.results(results);
}); });
}
self.playNext = playNext;
}
playlist.push(new Song(champions.id,champions.group,champions.title));
playlist.push(new Song(libertine.id,libertine.group,libertine.title));
ko.applyBindings(new PlaylistViewModel());
//Audio control
audio = $('audio')[0];
audio.addEventListener('ended', function(){
if(repeatOne){
audio.play();
}
else{
playNext();
}
});
function playNext(){
var now = playlist().indexOf(current);
var next = (now+1)%playlist().length;
console.log("NOW: "+now+", NEXT:"+next);
if(shuffle()){
var rand=Math.floor(Math.random()*playlist().length);
playSelected(playlist()[rand]);
}
else{
if(next>now || repeatAll()){
playSelected(playlist()[next]);
}else{
stop();
}
}
};
function stop(){
audio.src = "";
audio.load();
current.isPlaying(false);
}
function pauseSelected(song){
var id = song.id();
audio.pause();
song.isPlaying(false);
}
function playSelected(song){
var id = song.id();
if(audio.src.indexOf(id)==-1){
audio.src = 'play?id='+id;
audio.load();
}
// else{
// console.log("Not playing:"+audio.src);
// }
audio.play();
song.isPlaying(true);
current = song;
}
function addSelected(song){
playlist.push(new Song(song.id(),song.group(),song.title()));
}
});

View File

@ -6,6 +6,7 @@
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script> <script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript" src="js/jquery-ui-1.8.24.custom.min.js"></script> <script type="text/javascript" src="js/jquery-ui-1.8.24.custom.min.js"></script>
<script type='text/javascript' src='js/knockout-2.1.0.js'></script> <script type='text/javascript' src='js/knockout-2.1.0.js'></script>
<script type='text/javascript' src='https://github.com/downloads/rniemeyer/knockout-sortable/knockout-sortable.js'></script>
<script type='text/javascript' src='js/app.js'></script> <script type='text/javascript' src='js/app.js'></script>
</head> </head>
@ -15,23 +16,61 @@
<p><audio controls="controls" preload="auto" tabindex="0" type="audio/mpeg">No funciona el tag html5</audio></p> <p><audio controls="controls" preload="auto" tabindex="0" type="audio/mpeg">No funciona el tag html5</audio></p>
</div> </div>
<div id="wrapper"> <div id="wrapper">
<div id="results">
<h3>Playlist</h3>
<p><input type="checkbox" data-bind="checked: shuffle" /> Shuffle</p>
<p><input type="checkbox" data-bind="checked: repeatAll" /> RepeatAll</p>
<p><input type="checkbox" data-bind="checked: repeat" /> RepeatOne</p>
<div data-bind="text: trackNumber">:)</div>
<div data-bind="text: current">:D</div>
<a href="#" data-bind="click: playNext">Next!</a>
<ul data-bind="foreach: playlist">
<li data-bind="text: title"></li>
</ul>
</div>
<div id="accordion" class="ui-accordion ui-widget ui-helper-reset ui-accordion-icons"> <div id="accordion" class="ui-accordion ui-widget ui-helper-reset ui-accordion-icons">
<h3 class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-top" role="tab" aria-expanded="true" aria-selected="true" tabindex="0"> <h3 class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-top" role="tab" aria-expanded="true" aria-selected="true" tabindex="0">
<span class="ui-icon ui-icon-triangle-1-s"></span> <span class="ui-icon ui-icon-triangle-1-s"></span>
<a href="#" tabindex="0">Listen</a> <a href="#" tabindex="0">Listen</a>
</h3> </h3>
<div class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content-active" style="height: 14px; display: block; overflow: auto; padding-top: 11px; padding-bottom: 11px; " role="tabpanel"> <div class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content-active" style="height: 14px; display: block; overflow: auto; padding-top: 11px; padding-bottom: 11px; " role="tabpanel">
<ul id="playlist" class="sortable"> <ul id="playlist" class="sortable" data-bind="sortable: playlist">
<li class="ui-state-default" data-bind="sortableItem: { item: $data, parentList: playlist }">
<div class="list-controls">
<span class="ui-icon ui-icon-play" data-bind="click: playSong, visible: ! isPlaying()">Play</span>
<span class="ui-icon ui-icon-pause" data-bind="click: pauseSong, visible: isPlaying()">Play</span>
<span class="ui-icon ui-icon-circle-plus" data-bind="click: $root.addSong">Add</span>
<span class="ui-icon ui-icon-arrowthickstop-1-s"></span>
</div>
<div class="list-name" data-bind="text: formattedName()">
Name - Title
</div>
</li>
</ul> </ul>
</div> <h3 class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-top" role="tab" aria-expanded="true" aria-selected="true" tabindex="0"><span class="ui-icon ui-icon-triangle-1-s"></span> </div> <h3 class="ui-accordion-header ui-helper-reset ui-state-active ui-corner-top" role="tab" aria-expanded="true" aria-selected="true" tabindex="0"><span class="ui-icon ui-icon-triangle-1-s"></span>
<a href="#" tabindex="-1">Search</a> <a href="#" tabindex="-1">Search</a>
</h3> </h3>
<div class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content-active" style="height: 14px; display: block; overflow: auto; padding-top: 11px; padding-bottom: 11px; " role="tabpanel"> <div class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content-active" style="height: 14px; display: block; overflow: auto; padding-top: 11px; padding-bottom: 11px; " role="tabpanel">
<form method="POST" onsubmit="search(this.goearsearch.value); return false"> <form method="POST" action="#" data-bind="submit: getResults">
Search GoEar: <input type="search" name="goearsearch"> Search GoEar: <input type="search" name="goearsearch" data-bind="value: queryString">
</form> </form>
<ul id="searchresults" class="sortable"> <ul id="searchresults" class="sortable" data-bind="foreach: results">
<li class="ui-state-default">
<div class="list-controls">
<span class="ui-icon ui-icon-play" data-bind="click: playSong, visible: ! isPlaying()">Play</span>
<span class="ui-icon ui-icon-pause" data-bind="click: pauseSong, visible: isPlaying()">Play</span>
<span class="ui-icon ui-icon-circle-plus" data-bind="click: $root.addSong">Add</span>
<span class="ui-icon ui-icon-arrowthickstop-1-s"></span>
</div>
<div class="list-name" data-bind="text: formattedName(), click: playSong">
Name - Title
</div>
</li>
</ul> </ul>
</div> </div>
</div> </div>
</div> </div>