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:
parent
a8d1bd9a7e
commit
27388ebc09
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,4 +1,5 @@
|
|||||||
*.swp
|
*.swp
|
||||||
|
go5ears.vim
|
||||||
lib-cov
|
lib-cov
|
||||||
*.seed
|
*.seed
|
||||||
*.log
|
*.log
|
||||||
|
212
js/app.js
212
js/app.js
@ -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()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -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>
|
||||||
|
Loading…
Reference in New Issue
Block a user