diff --git a/js/api.js b/js/api.js
index e73269b..b196d28 100644
--- a/js/api.js
+++ b/js/api.js
@@ -278,3 +278,343 @@ function getRandomSongList(action, appendto) {
}
});
}
+
+function search(type, query) {
+ $.ajax({
+ url: baseURL + '/search2.view?u=' + username + '&p=' + passwordenc + '&v=' + version + '&c=' + applicationName + '&f=jsonp&query=' + query,
+ method: 'GET',
+ dataType: 'jsonp',
+ timeout: 10000,
+ beforeSend: function (req) {
+ req.setRequestHeader('Authorization', auth);
+ },
+ success: function (data) {
+ if (data["subsonic-response"].searchResult2 !== "") {
+ $("#AlbumRows").empty();
+ var header = generateSongHeaderHTML();
+ $("#AlbumHeader").html(header);
+ // There is a bug in the API that doesn't return a JSON array for one artist
+ var children = [];
+ if (data["subsonic-response"].searchResult2.song.length > 0) {
+ children = data["subsonic-response"].searchResult2.song;
+ } else {
+ children[0] = data["subsonic-response"].searchResult2.song;
+ }
+
+ var rowcolor;
+ var albumhtml;
+ $.each(children, function (i, child) {
+ if (i % 2 === 0) {
+ rowcolor = 'even';
+ } else {
+ rowcolor = 'odd';
+ }
+
+ var track;
+ if (child.track === undefined) { track = " "; } else { track = child.track; }
+ var time = secondsToTime(child.duration);
+ albumhtml = generateSongHTML(rowcolor, child.id, child.parent, track, child.title, child.artist, child.album, child.coverArt, child.userRating, time['m'], time['s']);
+ $(albumhtml).appendTo("#AlbumRows");
+ });
+ }
+ }
+ });
+}
+
+function loadPlaylists(refresh) {
+ if (refresh) {
+ $('#PlaylistContainer').empty();
+ }
+ var content = $('#PlaylistContainer').html();
+ if (content === "") {
+ // Load Playlists
+ $.ajax({
+ url: baseURL + '/getPlaylists.view?u=' + username + '&p=' + passwordenc + '&v=' + version + '&c=' + applicationName + '&f=jsonp',
+ method: 'GET',
+ dataType: 'jsonp',
+ timeout: 10000,
+ beforeSend: function (req) {
+ req.setRequestHeader('Authorization', auth);
+ },
+ success: function (data) {
+ var playlists = [];
+ if (data["subsonic-response"].playlists.playlist.length > 0) {
+ playlists = data["subsonic-response"].playlists.playlist;
+ } else {
+ playlists[0] = data["subsonic-response"].playlists.playlist;
+ }
+ $.each(playlists, function (i, playlist) {
+ var html = "";
+ html += '
';
+ html += '' + playlist.name + '';
+ html += '';
+ html += '';
+ html += '';
+ $(html).appendTo("#PlaylistContainer");
+ });
+ }
+ });
+ }
+}
+function loadPlaylistsForMenu(menu) {
+ $('#' + menu).empty();
+ $.ajax({
+ url: baseURL + '/getPlaylists.view?u=' + username + '&p=' + passwordenc + '&v=' + version + '&c=' + applicationName + '&f=jsonp',
+ method: 'GET',
+ dataType: 'jsonp',
+ timeout: 10000,
+ beforeSend: function (req) {
+ req.setRequestHeader('Authorization', auth);
+ },
+ success: function (data) {
+ var playlists = [];
+ if (data["subsonic-response"].playlists.playlist.length > 0) {
+ playlists = data["subsonic-response"].playlists.playlist;
+ } else {
+ playlists[0] = data["subsonic-response"].playlists.playlist;
+ }
+ $.each(playlists, function (i, playlist) {
+ if (menu === 'submenu_AddCurrentToPlaylist') {
+ $("" + playlist.name + "
").appendTo("#" + menu);
+ } else {
+ $("" + playlist.name + "
").appendTo("#" + menu);
+ }
+ });
+ //$("+ New Playlist
").appendTo("#submenu");
+ }
+ });
+}
+function newPlaylist() {
+ var reply = prompt("Choose a name for your new playlist.", "");
+ if (reply) {
+ $.ajax({
+ url: baseURL + '/createPlaylist.view?u=' + username + '&p=' + passwordenc + '&v=' + version + '&c=' + applicationName + '&f=jsonp&name=' + reply,
+ method: 'GET',
+ dataType: 'jsonp',
+ timeout: 10000,
+ beforeSend: function (req) {
+ req.setRequestHeader('Authorization', auth);
+ },
+ success: function (data) {
+ loadPlaylists(true);
+ }
+ });
+ }
+}
+function deletePlaylist(id) {
+ $.ajax({
+ url: baseURL + '/deletePlaylist.view?u=' + username + '&p=' + passwordenc + '&v=' + version + '&c=' + applicationName + '&f=jsonp&id=' + id,
+ method: 'GET',
+ dataType: 'jsonp',
+ timeout: 10000,
+ beforeSend: function (req) {
+ req.setRequestHeader('Authorization', auth);
+ },
+ success: function (data) {
+ loadPlaylists(true);
+ $('#TrackContainer tbody').empty();
+ }
+ });
+}
+function addToPlaylist(playlistid, from) {
+ var selected = [];
+ var el;
+ if (from === 'current') {
+ el = $('#CurrentPlaylist table.songlist tr.selected');
+ } else {
+ el = $('#Albums table.songlist tr.selected');
+ }
+ el.each(function (index) {
+ selected.push($(this).attr('childid'));
+ });
+ if (selected.length > 0) {
+ if (playlistid !== 'new') { // Create new playlist from here, will implement in UI later
+ // Get songs from playlist
+ var currentsongs = [];
+ $.ajax({
+ url: baseURL + '/getPlaylist.view?u=' + username + '&p=' + passwordenc + '&v=' + version + '&c=' + applicationName + '&f=jsonp&id=' + playlistid,
+ method: 'GET',
+ dataType: 'jsonp',
+ timeout: 10000,
+ beforeSend: function (req) {
+ req.setRequestHeader('Authorization', auth);
+ },
+ success: function (data) {
+ // There is a bug in the API that doesn't return a JSON array for one artist
+ var children = [];
+ if (data["subsonic-response"].playlist.entry !== undefined) {
+ if (data["subsonic-response"].playlist.entry.length > 1) {
+ children = data["subsonic-response"].playlist.entry;
+ } else {
+ children[0] = data["subsonic-response"].playlist.entry;
+ }
+ $.each(children, function (i, child) {
+ currentsongs.push(child.id);
+ });
+ }
+ var newsongs = [];
+ var count = 0;
+ $.each(selected, function (i, songid) {
+ if (jQuery.inArray(songid, currentsongs) === -1) {
+ currentsongs.push(songid);
+ count++;
+ }
+ });
+ if (count > 0) {
+ $.ajax({
+ type: 'GET',
+ url: baseURL + '/createPlaylist.view',
+ dataType: 'jsonp',
+ timeout: 10000,
+ data: { u: username, p: passwordenc, v: version, c: applicationName, f: "jsonp", playlistId: playlistid, songId: currentsongs },
+ beforeSend: function (req) {
+ req.setRequestHeader('Authorization', auth);
+ },
+ success: function () {
+ $('table.songlist tr.song').each(function () {
+ $(this).removeClass('selected');
+ });
+ updateMessage('Playlist Updated!');
+ },
+ traditional: true // Fixes POST with an array in JQuery 1.4
+ });
+ }
+ }
+ });
+ } else {
+ $.ajax({
+ type: 'GET',
+ url: baseURL + '/createPlaylist.view',
+ dataType: 'jsonp',
+ timeout: 10000,
+ data: { u: username, p: passwordenc, v: version, c: applicationName, f: "jsonp", name: 'New Playlist', songId: selected },
+ beforeSend: function (req) {
+ req.setRequestHeader('Authorization', auth);
+ },
+ success: function () {
+ $('table.songlist tr.song').each(function () {
+ $(this).removeClass('selected');
+ });
+ updateMessage('Playlist Created!');
+ },
+ traditional: true // Fixes POST with an array in JQuery 1.4
+ });
+ }
+ setTimeout(function () { $('div.submenu').fadeOut(); }, 100);
+ }
+}
+function addToCurrent(addAll) {
+ var count;
+ if (addAll) {
+ count = $('#AlbumContainer tr.song').length;
+ } else {
+ count = $('#AlbumContainer tr.selected').length;
+ }
+ if (count > 0) {
+ if (addAll) {
+ $('#AlbumContainer tr.song').each(function (index) {
+ $(this).clone().appendTo('#CurrentPlaylistContainer tbody');
+ updateMessage(count + ' Song(s) Added');
+ });
+ } else {
+ $('#AlbumContainer tr.selected').each(function (index) {
+ $(this).clone().appendTo('#CurrentPlaylistContainer tbody');
+ updateMessage(count + ' Song(s) Added');
+ });
+ }
+ }
+}
+function downloadItem(id) {
+ var url;
+ if (id) {
+ url = baseURL + '/download.view?u=' + username + '&p=' + passwordenc + '&v=' + version + '&c=' + applicationName + '&f=jsonp&id=' + id;
+ window.location = url;
+ }
+ /*
+ $('table.songlist tr.selected').each(function (index) {
+ id = $(this).attr('childid');
+ if (id) {
+ url = baseURL + '/download.view?u=' + username + '&p=' + passwordenc + '&v=' + version + '&c=' + applicationName + '&f=jsonp&id=' + id;
+ window.location = url;
+ }
+ });
+ */
+}
+function savePlaylist(playlistid) {
+ var songs = [];
+ $('#TrackContainer tr.song').each(function (index) {
+ songs.push($(this).attr('childid'));
+ });
+ if (songs.length > 0) {
+ $.ajax({
+ type: 'GET',
+ url: baseURL + '/createPlaylist.view',
+ dataType: 'jsonp',
+ timeout: 10000,
+ data: { u: username, p: passwordenc, v: version, c: applicationName, f: "jsonp", playlistId: playlistid, songId: songs },
+ beforeSend: function (req) {
+ req.setRequestHeader('Authorization', auth);
+ },
+ success: function () {
+ getPlaylist(playlistid);
+ updateMessage('Playlist Updated!');
+ },
+ traditional: true // Fixes POST with an array in JQuery 1.4
+ });
+ }
+}
+function getPlaylist(id, action, appendto) {
+ $.ajax({
+ url: baseURL + '/getPlaylist.view?u=' + username + '&p=' + passwordenc + '&v=' + version + '&c=' + applicationName + '&f=jsonp&id=' + id,
+ method: 'GET',
+ dataType: 'jsonp',
+ timeout: 10000,
+ beforeSend: function (req) {
+ req.setRequestHeader('Authorization', auth);
+ },
+ success: function (data) {
+ if (data["subsonic-response"].playlist.entry !== undefined) {
+ if (appendto === '#TrackContainer tbody') {
+ $(appendto).empty();
+ var header = generateSongHeaderHTML();
+ $("#TrackContainer thead").html(header);
+ }
+ if (action === 'autoplay') {
+ $(appendto).empty();
+ }
+ // There is a bug in the API that doesn't return a JSON array for one artist
+ var children = [];
+ if (data["subsonic-response"].playlist.entry.length > 0) {
+ children = data["subsonic-response"].playlist.entry;
+ } else {
+ children[0] = data["subsonic-response"].playlist.entry;
+ }
+
+ var rowcolor;
+ var html;
+ $.each(children, function (i, child) {
+ if (i % 2 === 0) {
+ rowcolor = 'even';
+ } else {
+ rowcolor = 'odd';
+ }
+ var track;
+ if (child.track === undefined) { track = " "; } else { track = child.track; }
+ var time = secondsToTime(child.duration);
+ html = generateSongHTML(rowcolor, child.id, child.parent, track, child.title, child.artist, child.album, child.coverArt, child.userRating, time['m'], time['s']);
+ $(html).appendTo(appendto);
+ });
+ if (appendto === '#CurrentPlaylistContainer tbody') {
+ updateMessage(children.length + ' Song(s) Added');
+ }
+ if (action === 'autoplay') {
+ autoPlay();
+ }
+ } else {
+ if (appendto === '#TrackContainer tbody') {
+ $(appendto).empty();
+ }
+ }
+ }
+ });
+}
diff --git a/js/app.js b/js/app.js
index a08fad7..25ddfd1 100644
--- a/js/app.js
+++ b/js/app.js
@@ -62,289 +62,6 @@ function loadTabContent(tab) {
}
}
-var scrobbled = false;
-function playSong(el, songid, albumid) {
- $.ajax({
- url: baseURL + '/getMusicDirectory.view?u=' + username + '&p=' + passwordenc + '&v=' + version + '&c=' + applicationName + '&f=jsonp&id=' + albumid,
- method: 'GET',
- dataType: 'jsonp',
- timeout: 10000,
- beforeSend: function (req) {
- req.setRequestHeader('Authorization', auth);
- },
- success: function (data) {
- var title, artist, album;
- if (data["subsonic-response"].directory !== undefined) {
- // There is a bug in the API that doesn't return a JSON array for one artist
- var children = [];
- if (data["subsonic-response"].directory.child.length > 0) {
- children = data["subsonic-response"].directory.child;
- } else {
- children[0] = data["subsonic-response"].directory.child;
- }
- $.each(children, function (i, child) {
- if (child.id === songid) {
- title = child.title;
- artist = child.artist;
- album = child.album;
- coverart = child.coverArt;
- }
- });
- }
- $('#songdetails_song').html(title);
- $('#songdetails_song').attr('parentid', albumid);
- $('#songdetails_song').attr('childid', songid);
- $('#songdetails_artist').html(artist + ' - ' + album);
- $('#coverartimage').attr('href', baseURL + '/getCoverArt.view?v=' + version + '&c=' + applicationName + '&f=jsonp&id=' + coverart);
- $('#coverartimage img').attr('src', baseURL + '/getCoverArt.view?v=' + version + '&c=' + applicationName + '&f=jsonp&size=50&id=' + coverart);
- $('#playermiddle').css('visibility', 'visible');
- $('#songdetails').css('visibility', 'visible');
- // SoundManager Initialize
- var salt = Math.floor(Math.random() * 100000);
- if (audio) {
- soundManager.destroySound('audio');
- }
- audio = soundManager.createSound({
- id: 'audio',
- url: baseURL + '/stream.view?u=' + username + '&p=' + passwordenc + '&v=' + version + '&c=' + applicationName + '&id=' + songid + '&salt=' + salt,
- stream: true,
- whileloading: function () {
- if (debug) {
- console.log('loaded:' + this.bytesLoaded + ' total:' + this.bytesTotal);
- }
- var percent = this.bytesLoaded / this.bytesTotal;
- var scrubber = $('#audio_wrapper0').find(".scrubber");
- var loaded = $('#audio_wrapper0').find(".loaded");
- loaded.css('width', (scrubber.get(0).offsetWidth * percent) + 'px');
- },
- whileplaying: function () {
- //console.log('position:' + this.position + ' duration:' + this.duration);
- var percent = this.position / this.duration;
- var scrubber = $('#audio_wrapper0').find(".scrubber");
- var progress = $('#audio_wrapper0').find(".progress");
- progress.css('width', (scrubber.get(0).offsetWidth * percent) + 'px');
-
- var played = $('#audio_wrapper0').find(".played");
- var p = (this.duration / 1000) * percent,
- m = Math.floor(p / 60),
- s = Math.floor(p % 60);
- played.html((m < 10 ? '0' : '') + m + ':' + (s < 10 ? '0' : '') + s);
-
- // Scrobble song once percentage is reached
- if (!scrobbled && p > 30 && (percent > 0.5 || p > 480)) {
- scrobbleSong(true);
- }
- },
- onload: function () {
- var duration = $('#audio_wrapper0').find(".duration");
- var dp = this.duration / 1000,
- dm = Math.floor(dp / 60),
- ds = Math.floor(dp % 60);
- duration.html((dm < 10 ? '0' : '') + dm + ':' + (ds < 10 ? '0' : '') + ds);
- },
- onfinish: function () {
- var next = $('#CurrentPlaylistContainer tr.playing').next();
- changeTrack(next);
- }
- });
- audio.play('audio');
-
- $('table.songlist tr.song').removeClass('playing');
- $(el).addClass('playing');
- $('#PlayTrack').find('img').attr('src', 'images/pause_24x32.png');
- $('#PlayTrack').addClass('playing');
- scrobbleSong(false);
- scrobbled = false;
-
- if ($.cookie('EnableNotifications')) {
- showNotification(baseURL + '/getCoverArt.view?v=' + version + '&c=' + applicationName + '&f=jsonp&size=50&id=' + coverart, toHTML.un(title), toHTML.un(artist + ' - ' + album));
- }
- if ($.cookie('ScrollTitle')) {
- scrollTitle(toHTML.un(artist) + ' - ' + toHTML.un(title));
- } else {
- setTitle(toHTML.un(artist) + ' - ' + toHTML.un(title));
- }
- }
- });
-}
-function scrobbleSong(submission) {
- var songid = $('#songdetails_song').attr('childid');
- $.ajax({
- url: baseURL + '/scrobble.view?u=' + username + '&p=' + passwordenc + '&v=' + version + '&c=' + applicationName + '&f=jsonp&id=' + songid + "&submission=" + submission,
- method: 'GET',
- dataType: 'jsonp',
- timeout: 10000,
- beforeSend: function (req) {
- req.setRequestHeader('Authorization', auth);
- },
- success: function () {
- if (submission) {
- scrobbled = true;
- }
- }
- });
-}
-function rateSong(songid, rating) {
- $.ajax({
- url: baseURL + '/setRating.view?u=' + username + '&p=' + passwordenc + '&v=' + version + '&c=' + applicationName + '&f=jsonp&id=' + songid + "&rating=" + rating,
- method: 'GET',
- dataType: 'jsonp',
- timeout: 10000,
- beforeSend: function (req) {
- req.setRequestHeader('Authorization', auth);
- },
- success: function () {
- updateMessage('Rating Updated!');
- }
- });
-}
-function playPauseSong() {
- var el = '#PlayTrack';
- if ($(el).hasClass('playing')) {
- $(el).find('img').attr('src', 'images/play_24x32.png');
- $(el).removeClass('playing');
- $(el).addClass('paused');
- soundManager.pause('audio');
- } else if ($(el).hasClass('paused')) {
- $(el).find('img').attr('src', 'images/pause_24x32.png');
- $(el).removeClass('paused');
- $(el).addClass('playing');
- soundManager.resume('audio');
- } else {
- // Start playing song
- var play = $('#CurrentPlaylistContainer tr.selected').first();
- if (changeTrack(play)) {
- $(el).find('img').attr('src', 'images/pause_24x32.png');
- $(el).addClass('playing');
- } else {
- var first = $('#CurrentPlaylistContainer tr').first();
- changeTrack(first);
- }
- }
-}
-function changeTrack(next) {
- var songid = $(next).attr('childid');
- if (songid !== undefined) {
- var albumid = $(next).attr('parentid');
- playSong(next, songid, albumid);
- return true;
- } else {
- return false;
- }
-}
-function autoPlay() {
- var firstsong = $('#CurrentPlaylistContainer tr.song:first');
- var songid = $(firstsong).attr('childid');
- var albumid = $(firstsong).attr('parentid');
- playSong(firstsong, songid, albumid);
-}
-function search(type, query) {
- $.ajax({
- url: baseURL + '/search2.view?u=' + username + '&p=' + passwordenc + '&v=' + version + '&c=' + applicationName + '&f=jsonp&query=' + query,
- method: 'GET',
- dataType: 'jsonp',
- timeout: 10000,
- beforeSend: function (req) {
- req.setRequestHeader('Authorization', auth);
- },
- success: function (data) {
- if (data["subsonic-response"].searchResult2 !== "") {
- $("#AlbumRows").empty();
- var header = generateSongHeaderHTML();
- $("#AlbumHeader").html(header);
- // There is a bug in the API that doesn't return a JSON array for one artist
- var children = [];
- if (data["subsonic-response"].searchResult2.song.length > 0) {
- children = data["subsonic-response"].searchResult2.song;
- } else {
- children[0] = data["subsonic-response"].searchResult2.song;
- }
-
- var rowcolor;
- var albumhtml;
- $.each(children, function (i, child) {
- if (i % 2 === 0) {
- rowcolor = 'even';
- } else {
- rowcolor = 'odd';
- }
-
- var track;
- if (child.track === undefined) { track = " "; } else { track = child.track; }
- var time = secondsToTime(child.duration);
- albumhtml = generateSongHTML(rowcolor, child.id, child.parent, track, child.title, child.artist, child.album, child.coverArt, child.userRating, time['m'], time['s']);
- $(albumhtml).appendTo("#AlbumRows");
- });
- }
- }
- });
-}
-var starttime;
-var updater;
-function updateChatMessages() {
- updater = $.periodic({ period: 1000, decay: 1.5, max_period: 1800000 }, function () {
- $.ajax({
- periodic: this,
- url: baseURL + '/getChatMessages.view?u=' + username + '&p=' + passwordenc + '&v=' + version + '&c=' + applicationName + '&f=jsonp&since=' + starttime,
- method: 'GET',
- dataType: 'jsonp',
- timeout: 10000,
- beforeSend: function (req) {
- req.setRequestHeader('Authorization', auth);
- },
- success: function (data) {
- if (data["subsonic-response"].chatMessages.chatMessage === undefined) {
- this.periodic.increment();
- } else {
- var msgs = [];
- if (data["subsonic-response"].chatMessages.chatMessage.length > 0) {
- msgs = data["subsonic-response"].chatMessages.chatMessage;
- } else {
- msgs[0] = data["subsonic-response"].chatMessages.chatMessage;
- }
- this.periodic.reset();
- var sorted = msgs.sort(function (a, b) {
- return a.time - b.time;
- });
- var x = 1;
- $.each(sorted, function (i, msg) {
- var chathtml = '';
- chathtml += '' + $.format.date(new Date(parseInt(msg.time, 10)), 'hh:mm:ss a') + ' ';
- chathtml += '' + msg.username + '';
- chathtml += '' + msg.message + '';
- chathtml += '
';
- $(chathtml).appendTo("#ChatMsgs");
- if (x === sorted.length) {
- starttime = msg.time;
- }
- x++;
- });
- $("#ChatMsgs").linkify();
- $("#ChatMsgs").attr({ scrollTop: $("#ChatMsgs").attr("scrollHeight") });
- }
- }
- });
- });
-}
-function stopUpdateChatMessages() {
- updater.cancel();
-}
-function addChatMessage(msg) {
- $.ajax({
- type: 'GET',
- url: baseURL + '/addChatMessage.view',
- dataType: 'jsonp',
- timeout: 10000,
- data: { u: username, p: passwordenc, v: version, c: applicationName, f: "jsonp", message: msg },
- beforeSend: function (req) {
- req.setRequestHeader('Authorization', auth);
- },
- success: function () {
- updater.reset();
- },
- traditional: true // Fixes POST with an array in JQuery 1.4
- });
-}
var updaterNowPlaying;
var updaterNowPlayingData;
function updateNowPlaying() {
@@ -398,301 +115,4 @@ function stopUpdateNowPlaying() {
updaterNowPlaying.cancel();
}
-function loadPlaylists(refresh) {
- if (refresh) {
- $('#PlaylistContainer').empty();
- }
- var content = $('#PlaylistContainer').html();
- if (content === "") {
- // Load Playlists
- $.ajax({
- url: baseURL + '/getPlaylists.view?u=' + username + '&p=' + passwordenc + '&v=' + version + '&c=' + applicationName + '&f=jsonp',
- method: 'GET',
- dataType: 'jsonp',
- timeout: 10000,
- beforeSend: function (req) {
- req.setRequestHeader('Authorization', auth);
- },
- success: function (data) {
- var playlists = [];
- if (data["subsonic-response"].playlists.playlist.length > 0) {
- playlists = data["subsonic-response"].playlists.playlist;
- } else {
- playlists[0] = data["subsonic-response"].playlists.playlist;
- }
- $.each(playlists, function (i, playlist) {
- var html = "";
- html += '';
- html += '' + playlist.name + '';
- html += '';
- html += '';
- html += '';
- $(html).appendTo("#PlaylistContainer");
- });
- }
- });
- }
-}
-function loadPlaylistsForMenu(menu) {
- $('#' + menu).empty();
- $.ajax({
- url: baseURL + '/getPlaylists.view?u=' + username + '&p=' + passwordenc + '&v=' + version + '&c=' + applicationName + '&f=jsonp',
- method: 'GET',
- dataType: 'jsonp',
- timeout: 10000,
- beforeSend: function (req) {
- req.setRequestHeader('Authorization', auth);
- },
- success: function (data) {
- var playlists = [];
- if (data["subsonic-response"].playlists.playlist.length > 0) {
- playlists = data["subsonic-response"].playlists.playlist;
- } else {
- playlists[0] = data["subsonic-response"].playlists.playlist;
- }
- $.each(playlists, function (i, playlist) {
- if (menu === 'submenu_AddCurrentToPlaylist') {
- $("" + playlist.name + "
").appendTo("#" + menu);
- } else {
- $("" + playlist.name + "
").appendTo("#" + menu);
- }
- });
- //$("+ New Playlist
").appendTo("#submenu");
- }
- });
-}
-function newPlaylist() {
- var reply = prompt("Choose a name for your new playlist.", "");
- if (reply) {
- $.ajax({
- url: baseURL + '/createPlaylist.view?u=' + username + '&p=' + passwordenc + '&v=' + version + '&c=' + applicationName + '&f=jsonp&name=' + reply,
- method: 'GET',
- dataType: 'jsonp',
- timeout: 10000,
- beforeSend: function (req) {
- req.setRequestHeader('Authorization', auth);
- },
- success: function (data) {
- loadPlaylists(true);
- }
- });
- }
-}
-function deletePlaylist(id) {
- $.ajax({
- url: baseURL + '/deletePlaylist.view?u=' + username + '&p=' + passwordenc + '&v=' + version + '&c=' + applicationName + '&f=jsonp&id=' + id,
- method: 'GET',
- dataType: 'jsonp',
- timeout: 10000,
- beforeSend: function (req) {
- req.setRequestHeader('Authorization', auth);
- },
- success: function (data) {
- loadPlaylists(true);
- $('#TrackContainer tbody').empty();
- }
- });
-}
-function addToPlaylist(playlistid, from) {
- var selected = [];
- var el;
- if (from === 'current') {
- el = $('#CurrentPlaylist table.songlist tr.selected');
- } else {
- el = $('#Albums table.songlist tr.selected');
- }
- el.each(function (index) {
- selected.push($(this).attr('childid'));
- });
- if (selected.length > 0) {
- if (playlistid !== 'new') { // Create new playlist from here, will implement in UI later
- // Get songs from playlist
- var currentsongs = [];
- $.ajax({
- url: baseURL + '/getPlaylist.view?u=' + username + '&p=' + passwordenc + '&v=' + version + '&c=' + applicationName + '&f=jsonp&id=' + playlistid,
- method: 'GET',
- dataType: 'jsonp',
- timeout: 10000,
- beforeSend: function (req) {
- req.setRequestHeader('Authorization', auth);
- },
- success: function (data) {
- // There is a bug in the API that doesn't return a JSON array for one artist
- var children = [];
- if (data["subsonic-response"].playlist.entry !== undefined) {
- if (data["subsonic-response"].playlist.entry.length > 1) {
- children = data["subsonic-response"].playlist.entry;
- } else {
- children[0] = data["subsonic-response"].playlist.entry;
- }
- $.each(children, function (i, child) {
- currentsongs.push(child.id);
- });
- }
- var newsongs = [];
- var count = 0;
- $.each(selected, function (i, songid) {
- if (jQuery.inArray(songid, currentsongs) === -1) {
- currentsongs.push(songid);
- count++;
- }
- });
- if (count > 0) {
- $.ajax({
- type: 'GET',
- url: baseURL + '/createPlaylist.view',
- dataType: 'jsonp',
- timeout: 10000,
- data: { u: username, p: passwordenc, v: version, c: applicationName, f: "jsonp", playlistId: playlistid, songId: currentsongs },
- beforeSend: function (req) {
- req.setRequestHeader('Authorization', auth);
- },
- success: function () {
- $('table.songlist tr.song').each(function () {
- $(this).removeClass('selected');
- });
- updateMessage('Playlist Updated!');
- },
- traditional: true // Fixes POST with an array in JQuery 1.4
- });
- }
- }
- });
- } else {
- $.ajax({
- type: 'GET',
- url: baseURL + '/createPlaylist.view',
- dataType: 'jsonp',
- timeout: 10000,
- data: { u: username, p: passwordenc, v: version, c: applicationName, f: "jsonp", name: 'New Playlist', songId: selected },
- beforeSend: function (req) {
- req.setRequestHeader('Authorization', auth);
- },
- success: function () {
- $('table.songlist tr.song').each(function () {
- $(this).removeClass('selected');
- });
- updateMessage('Playlist Created!');
- },
- traditional: true // Fixes POST with an array in JQuery 1.4
- });
- }
- setTimeout(function () { $('div.submenu').fadeOut(); }, 100);
- }
-}
-function addToCurrent(addAll) {
- var count;
- if (addAll) {
- count = $('#AlbumContainer tr.song').length;
- } else {
- count = $('#AlbumContainer tr.selected').length;
- }
- if (count > 0) {
- if (addAll) {
- $('#AlbumContainer tr.song').each(function (index) {
- $(this).clone().appendTo('#CurrentPlaylistContainer tbody');
- updateMessage(count + ' Song(s) Added');
- });
- } else {
- $('#AlbumContainer tr.selected').each(function (index) {
- $(this).clone().appendTo('#CurrentPlaylistContainer tbody');
- updateMessage(count + ' Song(s) Added');
- });
- }
- }
-}
-function downloadItem(id) {
- var url;
- if (id) {
- url = baseURL + '/download.view?u=' + username + '&p=' + passwordenc + '&v=' + version + '&c=' + applicationName + '&f=jsonp&id=' + id;
- window.location = url;
- }
- /*
- $('table.songlist tr.selected').each(function (index) {
- id = $(this).attr('childid');
- if (id) {
- url = baseURL + '/download.view?u=' + username + '&p=' + passwordenc + '&v=' + version + '&c=' + applicationName + '&f=jsonp&id=' + id;
- window.location = url;
- }
- });
- */
-}
-function savePlaylist(playlistid) {
- var songs = [];
- $('#TrackContainer tr.song').each(function (index) {
- songs.push($(this).attr('childid'));
- });
- if (songs.length > 0) {
- $.ajax({
- type: 'GET',
- url: baseURL + '/createPlaylist.view',
- dataType: 'jsonp',
- timeout: 10000,
- data: { u: username, p: passwordenc, v: version, c: applicationName, f: "jsonp", playlistId: playlistid, songId: songs },
- beforeSend: function (req) {
- req.setRequestHeader('Authorization', auth);
- },
- success: function () {
- getPlaylist(playlistid);
- updateMessage('Playlist Updated!');
- },
- traditional: true // Fixes POST with an array in JQuery 1.4
- });
- }
-}
-function getPlaylist(id, action, appendto) {
- $.ajax({
- url: baseURL + '/getPlaylist.view?u=' + username + '&p=' + passwordenc + '&v=' + version + '&c=' + applicationName + '&f=jsonp&id=' + id,
- method: 'GET',
- dataType: 'jsonp',
- timeout: 10000,
- beforeSend: function (req) {
- req.setRequestHeader('Authorization', auth);
- },
- success: function (data) {
- if (data["subsonic-response"].playlist.entry !== undefined) {
- if (appendto === '#TrackContainer tbody') {
- $(appendto).empty();
- var header = generateSongHeaderHTML();
- $("#TrackContainer thead").html(header);
- }
- if (action === 'autoplay') {
- $(appendto).empty();
- }
- // There is a bug in the API that doesn't return a JSON array for one artist
- var children = [];
- if (data["subsonic-response"].playlist.entry.length > 0) {
- children = data["subsonic-response"].playlist.entry;
- } else {
- children[0] = data["subsonic-response"].playlist.entry;
- }
-
- var rowcolor;
- var html;
- $.each(children, function (i, child) {
- if (i % 2 === 0) {
- rowcolor = 'even';
- } else {
- rowcolor = 'odd';
- }
- var track;
- if (child.track === undefined) { track = " "; } else { track = child.track; }
- var time = secondsToTime(child.duration);
- html = generateSongHTML(rowcolor, child.id, child.parent, track, child.title, child.artist, child.album, child.coverArt, child.userRating, time['m'], time['s']);
- $(html).appendTo(appendto);
- });
- if (appendto === '#CurrentPlaylistContainer tbody') {
- updateMessage(children.length + ' Song(s) Added');
- }
- if (action === 'autoplay') {
- autoPlay();
- }
- } else {
- if (appendto === '#TrackContainer tbody') {
- $(appendto).empty();
- }
- }
- }
- });
-}
diff --git a/js/chat.js b/js/chat.js
new file mode 100644
index 0000000..2b07f96
--- /dev/null
+++ b/js/chat.js
@@ -0,0 +1,66 @@
+var starttime;
+var updater;
+function updateChatMessages() {
+ updater = $.periodic({ period: 1000, decay: 1.5, max_period: 1800000 }, function () {
+ $.ajax({
+ periodic: this,
+ url: baseURL + '/getChatMessages.view?u=' + username + '&p=' + passwordenc + '&v=' + version + '&c=' + applicationName + '&f=jsonp&since=' + starttime,
+ method: 'GET',
+ dataType: 'jsonp',
+ timeout: 10000,
+ beforeSend: function (req) {
+ req.setRequestHeader('Authorization', auth);
+ },
+ success: function (data) {
+ if (data["subsonic-response"].chatMessages.chatMessage === undefined) {
+ this.periodic.increment();
+ } else {
+ var msgs = [];
+ if (data["subsonic-response"].chatMessages.chatMessage.length > 0) {
+ msgs = data["subsonic-response"].chatMessages.chatMessage;
+ } else {
+ msgs[0] = data["subsonic-response"].chatMessages.chatMessage;
+ }
+ this.periodic.reset();
+ var sorted = msgs.sort(function (a, b) {
+ return a.time - b.time;
+ });
+ var x = 1;
+ $.each(sorted, function (i, msg) {
+ var chathtml = '';
+ chathtml += '' + $.format.date(new Date(parseInt(msg.time, 10)), 'hh:mm:ss a') + ' ';
+ chathtml += '' + msg.username + '';
+ chathtml += '' + msg.message + '';
+ chathtml += '
';
+ $(chathtml).appendTo("#ChatMsgs");
+ if (x === sorted.length) {
+ starttime = msg.time;
+ }
+ x++;
+ });
+ $("#ChatMsgs").linkify();
+ $("#ChatMsgs").attr({ scrollTop: $("#ChatMsgs").attr("scrollHeight") });
+ }
+ }
+ });
+ });
+}
+function stopUpdateChatMessages() {
+ updater.cancel();
+}
+function addChatMessage(msg) {
+ $.ajax({
+ type: 'GET',
+ url: baseURL + '/addChatMessage.view',
+ dataType: 'jsonp',
+ timeout: 10000,
+ data: { u: username, p: passwordenc, v: version, c: applicationName, f: "jsonp", message: msg },
+ beforeSend: function (req) {
+ req.setRequestHeader('Authorization', auth);
+ },
+ success: function () {
+ updater.reset();
+ },
+ traditional: true // Fixes POST with an array in JQuery 1.4
+ });
+}
diff --git a/js/main.js b/js/main.js
index 9f70827..a98b8c1 100644
--- a/js/main.js
+++ b/js/main.js
@@ -1,7 +1,7 @@
require(["jquery", "sm/soundmanager2-jsmin", "jquery.scrollTo-1.4.2-min", "jquery.disable.text.select.pack",
"jquery.cookie", "jquery.base64", "jquery.dateFormat-1.0", "jquery.periodic", "jquery.shuffle",
"fancybox/jquery.fancybox-1.3.4.pack",
- "jquery.linkify-1.0-min", "utils", "api", "generators", "app", "ui-load", "ui-ready"
+ "jquery.linkify-1.0-min", "utils", "api", "generators", "chat", "player", "app", "ui-load", "ui-ready"
], function($) {
$(function() {
diff --git a/js/player.js b/js/player.js
new file mode 100644
index 0000000..0b15410
--- /dev/null
+++ b/js/player.js
@@ -0,0 +1,176 @@
+var scrobbled = false;
+function playSong(el, songid, albumid) {
+ $.ajax({
+ url: baseURL + '/getMusicDirectory.view?u=' + username + '&p=' + passwordenc + '&v=' + version + '&c=' + applicationName + '&f=jsonp&id=' + albumid,
+ method: 'GET',
+ dataType: 'jsonp',
+ timeout: 10000,
+ beforeSend: function (req) {
+ req.setRequestHeader('Authorization', auth);
+ },
+ success: function (data) {
+ var title, artist, album;
+ if (data["subsonic-response"].directory !== undefined) {
+ // There is a bug in the API that doesn't return a JSON array for one artist
+ var children = [];
+ if (data["subsonic-response"].directory.child.length > 0) {
+ children = data["subsonic-response"].directory.child;
+ } else {
+ children[0] = data["subsonic-response"].directory.child;
+ }
+ $.each(children, function (i, child) {
+ if (child.id === songid) {
+ title = child.title;
+ artist = child.artist;
+ album = child.album;
+ coverart = child.coverArt;
+ }
+ });
+ }
+ $('#songdetails_song').html(title);
+ $('#songdetails_song').attr('parentid', albumid);
+ $('#songdetails_song').attr('childid', songid);
+ $('#songdetails_artist').html(artist + ' - ' + album);
+ $('#coverartimage').attr('href', baseURL + '/getCoverArt.view?v=' + version + '&c=' + applicationName + '&f=jsonp&id=' + coverart);
+ $('#coverartimage img').attr('src', baseURL + '/getCoverArt.view?v=' + version + '&c=' + applicationName + '&f=jsonp&size=50&id=' + coverart);
+ $('#playermiddle').css('visibility', 'visible');
+ $('#songdetails').css('visibility', 'visible');
+ // SoundManager Initialize
+ var salt = Math.floor(Math.random() * 100000);
+ if (audio) {
+ soundManager.destroySound('audio');
+ }
+ audio = soundManager.createSound({
+ id: 'audio',
+ url: baseURL + '/stream.view?u=' + username + '&p=' + passwordenc + '&v=' + version + '&c=' + applicationName + '&id=' + songid + '&salt=' + salt,
+ stream: true,
+ whileloading: function () {
+ if (debug) {
+ console.log('loaded:' + this.bytesLoaded + ' total:' + this.bytesTotal);
+ }
+ var percent = this.bytesLoaded / this.bytesTotal;
+ var scrubber = $('#audio_wrapper0').find(".scrubber");
+ var loaded = $('#audio_wrapper0').find(".loaded");
+ loaded.css('width', (scrubber.get(0).offsetWidth * percent) + 'px');
+ },
+ whileplaying: function () {
+ //console.log('position:' + this.position + ' duration:' + this.duration);
+ var percent = this.position / this.duration;
+ var scrubber = $('#audio_wrapper0').find(".scrubber");
+ var progress = $('#audio_wrapper0').find(".progress");
+ progress.css('width', (scrubber.get(0).offsetWidth * percent) + 'px');
+
+ var played = $('#audio_wrapper0').find(".played");
+ var p = (this.duration / 1000) * percent,
+ m = Math.floor(p / 60),
+ s = Math.floor(p % 60);
+ played.html((m < 10 ? '0' : '') + m + ':' + (s < 10 ? '0' : '') + s);
+
+ // Scrobble song once percentage is reached
+ if (!scrobbled && p > 30 && (percent > 0.5 || p > 480)) {
+ scrobbleSong(true);
+ }
+ },
+ onload: function () {
+ var duration = $('#audio_wrapper0').find(".duration");
+ var dp = this.duration / 1000,
+ dm = Math.floor(dp / 60),
+ ds = Math.floor(dp % 60);
+ duration.html((dm < 10 ? '0' : '') + dm + ':' + (ds < 10 ? '0' : '') + ds);
+ },
+ onfinish: function () {
+ var next = $('#CurrentPlaylistContainer tr.playing').next();
+ changeTrack(next);
+ }
+ });
+ audio.play('audio');
+
+ $('table.songlist tr.song').removeClass('playing');
+ $(el).addClass('playing');
+ $('#PlayTrack').find('img').attr('src', 'images/pause_24x32.png');
+ $('#PlayTrack').addClass('playing');
+ scrobbleSong(false);
+ scrobbled = false;
+
+ if ($.cookie('EnableNotifications')) {
+ showNotification(baseURL + '/getCoverArt.view?v=' + version + '&c=' + applicationName + '&f=jsonp&size=50&id=' + coverart, toHTML.un(title), toHTML.un(artist + ' - ' + album));
+ }
+ if ($.cookie('ScrollTitle')) {
+ scrollTitle(toHTML.un(artist) + ' - ' + toHTML.un(title));
+ } else {
+ setTitle(toHTML.un(artist) + ' - ' + toHTML.un(title));
+ }
+ }
+ });
+}
+function scrobbleSong(submission) {
+ var songid = $('#songdetails_song').attr('childid');
+ $.ajax({
+ url: baseURL + '/scrobble.view?u=' + username + '&p=' + passwordenc + '&v=' + version + '&c=' + applicationName + '&f=jsonp&id=' + songid + "&submission=" + submission,
+ method: 'GET',
+ dataType: 'jsonp',
+ timeout: 10000,
+ beforeSend: function (req) {
+ req.setRequestHeader('Authorization', auth);
+ },
+ success: function () {
+ if (submission) {
+ scrobbled = true;
+ }
+ }
+ });
+}
+function rateSong(songid, rating) {
+ $.ajax({
+ url: baseURL + '/setRating.view?u=' + username + '&p=' + passwordenc + '&v=' + version + '&c=' + applicationName + '&f=jsonp&id=' + songid + "&rating=" + rating,
+ method: 'GET',
+ dataType: 'jsonp',
+ timeout: 10000,
+ beforeSend: function (req) {
+ req.setRequestHeader('Authorization', auth);
+ },
+ success: function () {
+ updateMessage('Rating Updated!');
+ }
+ });
+}
+function playPauseSong() {
+ var el = '#PlayTrack';
+ if ($(el).hasClass('playing')) {
+ $(el).find('img').attr('src', 'images/play_24x32.png');
+ $(el).removeClass('playing');
+ $(el).addClass('paused');
+ soundManager.pause('audio');
+ } else if ($(el).hasClass('paused')) {
+ $(el).find('img').attr('src', 'images/pause_24x32.png');
+ $(el).removeClass('paused');
+ $(el).addClass('playing');
+ soundManager.resume('audio');
+ } else {
+ // Start playing song
+ var play = $('#CurrentPlaylistContainer tr.selected').first();
+ if (changeTrack(play)) {
+ $(el).find('img').attr('src', 'images/pause_24x32.png');
+ $(el).addClass('playing');
+ } else {
+ var first = $('#CurrentPlaylistContainer tr').first();
+ changeTrack(first);
+ }
+ }
+}
+function changeTrack(next) {
+ var songid = $(next).attr('childid');
+ if (songid !== undefined) {
+ var albumid = $(next).attr('parentid');
+ playSong(next, songid, albumid);
+ return true;
+ } else {
+ return false;
+ }
+}
+function autoPlay() {
+ var firstsong = $('#CurrentPlaylistContainer tr.song:first');
+ var songid = $(firstsong).attr('childid');
+ var albumid = $(firstsong).attr('parentid');
+ playSong(firstsong, songid, albumid);
+}