diff --git a/index.html b/index.html index 490a859..c66b21d 100755 --- a/index.html +++ b/index.html @@ -24,12 +24,12 @@ - + + - @@ -224,6 +224,7 @@

Options

+




-
+

@@ -255,8 +256,11 @@
-
- +
+ +
+
+
@@ -296,10 +300,15 @@ - --> +
  • - 2.3.6 + - Added Setting to toggle JSONP (This is for cross-domain requests, aka Subsonic is hosted on a different domain than MiniSub) + - Switched back to URL authentication (Including coverArt) +
  • 12/3/2012 - 2.3.5 - Added keyboard volume controls back. Use the plus (=/+) and minus (-/_) keys - Change Save Current Position to Save Progress, added an indicator next to volume - Fixed Last.fm scrobble feature, this works again! + - Switch to Basic Authentication
  • 11/27/2012 - 2.3.4 - Basic Breadcrumb navigation implemented diff --git a/js/app.js b/js/app.js index db3e75e..427ce61 100755 --- a/js/app.js +++ b/js/app.js @@ -2,50 +2,20 @@ var debug = false; var audio = null; var hostURL = location.href; +var protocol = 'json'; var baseURL; +var baseParams; var apiVersion; var username; var password; var passwordenc; var server; var smwidth; -var currentVersion = '2.3.5'; - -function getCookie(value) { - if ($.cookie(value)) { - return $.cookie(value); - } else { - return false; - } - /* jQuery.cookies.js - if (browserStorageCheck) { - var item = localStorage.getItem(value); - if (item != '' && item != undefined) { - return true; - } else { - return false; - } - } else { - if (debug) { console.log('HTML5::loadStorage not supported on your browser' + html.length + ' characters'); } - } - */ -} -function setCookie(key, value) { - $.cookie(key, value, { expires: 365 }); - /* jQuery.cookies.js - try { - if (debug) { console.log('Saving : ' + key + ':' + value); } - localStorage.setItem(key, value); - } catch (e) { - if (e == QUOTA_EXCEEDED_ERR) { - alert('Quota exceeded!'); - } - } - */ -} +var apiVersion = '1.6.0'; +var currentVersion = '2.3.6'; // Get URL Querystring Parameters -var u = getParameterByName('u'); +var u = getParameterByName('u'); var p = getParameterByName('p'); var s = getParameterByName('s'); if (u && p && s) { @@ -64,9 +34,7 @@ if (u && p && s) { } window.location.href = getPathFromUrl(window.location); } -if (getCookie('Server')) { - baseURL = getCookie('Server') + '/rest'; -} + var applicationName; if (getCookie('ApplicationName')) { applicationName = getCookie('ApplicationName'); @@ -87,65 +55,8 @@ if (getCookie('password')) { setCookie('passwordenc', 'enc:' + HexEncode(getCookie('password'))); setCookie('password', null); } -var auth = makeBaseAuth(username, password.substring(4, password.length).hexDecode()); -var apiVersion = '1.6.0'; - -function loadTabContent(tab) { - var tabid = '#action_' + tab.substring(1, tab.length); - $("ul.tabs li a").removeClass("active"); //Remove any "active" class - $(tabid).addClass("active"); //Add "active" class to selected tab - $(".tabcontent").hide(); //Hide all tab content - window.location.hash = tab; - switch (tab) { - case '#tabLibrary': - if (debug) { console.log("TAG LIBRARY"); } - if (getCookie('MusicFolders')) { - loadArtists(getCookie('MusicFolders'), false); - } else { - loadArtists(); - } - getMusicFolders(); - break; - case '#tabQueue': - if (debug) { console.log("TAG QUEUE"); } - var header = generateSongHeaderHTML(); - $('#CurrentPlaylistContainer thead').html(header); - var count = $('#CurrentPlaylistContainer tbody tr.song').size(); - updateStatus('#status_Current', countCurrentPlaylist('#CurrentPlaylistContainer')); - if (count > 0) { - $('#currentActions a.button').removeClass('disabled'); - } - var songid = $('#CurrentPlaylistContainer tbody tr.playing').attr('childid'); - if (songid !== undefined) { - $('#CurrentPlaylist').scrollTo($('#' + songid), 400); - } - break; - case '#tabPlaylists': - if (debug) { console.log("TAG PLAYLIST"); } - loadPlaylists(); - loadFolders(); - loadAutoPlaylists(); - updateStatus('#status_Playlists', countCurrentPlaylist('#TrackContainer')); - break; - case '#tabPodcasts': - if (debug) { console.log("TAG PODCAST"); } - loadPodcasts(); - updateStatus('#status_Podcasts', countCurrentPlaylist('#PodcastContainer')); - break; - case '#tabVideos': - if (debug) { console.log("TAG VIDEOS"); } - loadVideos(true); - break; - case '#tabPreferences': - getGenres(); - break; - default: - break; - } - $(tab).fadeIn('fast'); //Fade in the active ID content +if (getCookie('Protocol')) { + protocol = 'jsonp'; } - - - - - +var auth = makeBaseAuth(username, password.substring(4, password.length).hexDecode()); +baseParams = 'u=' + username + '&p=' + password + '&f=' + protocol; diff --git a/js/libs/api.js b/js/libs/api.js index cd907b7..82218b0 100755 --- a/js/libs/api.js +++ b/js/libs/api.js @@ -1,726 +1,817 @@ -/* Ajax Global Setup */ -// Inject Basic Auth -$.ajaxSetup({ - beforeSend: function (req) { - req.setRequestHeader('Authorization', auth); - } - //headers: { "Authorization": "Basic " + auth } -}); - -function ping() { - $.ajax({ - url: baseURL + '/ping.view?v=1.6.0&c=' + applicationName + '&f=json', - method: 'GET', - dataType: 'json', - timeout: 10000, - success: function (data) { - if (data["subsonic-response"].status == 'ok') { - apiVersion = data["subsonic-response"].version; - $('#SubsonicVersion').html(apiVersion); - } else { - if (typeof data["subsonic-response"].error != 'undefined') { - alert(data["subsonic-response"].error.message); - } - } - }, - error: function () { - alert('Bad Server'); - } - }); -} -function loadArtists(id, refresh) { - if (debug) { console.log("LOAD ARTISTS"); } - if (refresh) { - $('#ArtistContainer').empty(); - } - var url; - if (id == "all") { - url = baseURL + '/getIndexes.view?v=' + apiVersion + '&c=' + applicationName + '&f=json'; - } else if (id) { - url = baseURL + '/getIndexes.view?v=' + apiVersion + '&c=' + applicationName + '&f=json&musicFolderId=' + id; - } else { - url = baseURL + '/getIndexes.view?v=' + apiVersion + '&c=' + applicationName + '&f=json'; - } - if (debug) { console.log(url); } - var content = $('#ArtistContainer').html(); - if (content === "") { - // Load Artist List + function ping() { $.ajax({ - url: url, + url: baseURL + '/ping.view?' + baseParams + '&v=1.6.0&c=' + applicationName, method: 'GET', - dataType: 'json', + dataType: protocol, timeout: 10000, - done: function () { if (debug) { console.log("DONE!"); } }, - error: function () { if (debug) { console.log("ERROR!"); } }, success: function (data) { - if (debug) { console.log("SUCCESS"); } if (data["subsonic-response"].status == 'ok') { - var indexlist, name; + apiVersion = data["subsonic-response"].version; + $('#SubsonicVersion').html(apiVersion); + } else { + if (typeof data["subsonic-response"].error != 'undefined') { + alert(data["subsonic-response"].error.message); + } + } + }, + error: function () { + alert('Bad Server'); + } + }); + } + function loadArtists(id, refresh) { + if (debug) { console.log("LOAD ARTISTS"); } + if (refresh) { + $('#ArtistContainer').empty(); + } + var url; + if (id == "all") { + url = baseURL + '/getIndexes.view?' + baseParams + '&v=' + apiVersion + '&c=' + applicationName; + } else if (id) { + url = baseURL + '/getIndexes.view?' + baseParams + '&v=' + apiVersion + '&c=' + applicationName + '&musicFolderId=' + id; + } else { + url = baseURL + '/getIndexes.view?' + baseParams + '&v=' + apiVersion + '&c=' + applicationName; + } + if (debug) { console.log(url); } + var content = $('#ArtistContainer').html(); + if (content === "") { + // Load Artist List + $.ajax({ + url: url, + method: 'GET', + dataType: protocol, + timeout: 10000, + done: function () { if (debug) { console.log("DONE!"); } }, + error: function () { if (debug) { console.log("ERROR!"); } }, + success: function (data) { + if (debug) { console.log("SUCCESS"); } + if (data["subsonic-response"].status == 'ok') { + var indexlist, name; - if (typeof data["subsonic-response"].indexes != 'undefined') { - if (typeof data["subsonic-response"].indexes.shortcut != 'undefined') { - var shortcuts = []; - if (data["subsonic-response"].indexes.shortcut.length > 0) { - shortcuts = data["subsonic-response"].indexes.shortcut; - } else { - shortcuts[0] = data["subsonic-response"].indexes.shortcut; - } - var html = '
  • Shortcuts
  • '; - $(html).appendTo("#ArtistContainer"); - $.each(shortcuts, function (i, item) { - if (item.name !== undefined) { - var html = '
  • '; - html += '' + item.name + ''; - html += '
  • '; - $(html).appendTo("#ArtistContainer"); - } - }); - } - - var indexes = []; if (typeof data["subsonic-response"].indexes != 'undefined') { - if (typeof data["subsonic-response"].indexes.index != 'undefined') { - if (data["subsonic-response"].indexes.index.length > 0) { - indexes = data["subsonic-response"].indexes.index; + if (typeof data["subsonic-response"].indexes.shortcut != 'undefined') { + var shortcuts = []; + if (data["subsonic-response"].indexes.shortcut.length > 0) { + shortcuts = data["subsonic-response"].indexes.shortcut; } else { - indexes[0] = data["subsonic-response"].indexes.index; + shortcuts[0] = data["subsonic-response"].indexes.shortcut; } - - - $.each(indexes, function (i, index) { - name = index.name; - $('
  • ' + name + '
  • ').appendTo("#ArtistContainer"); - indexlist += '
  • ' + name + '
  • '; - var artists = []; - if (index.artist.length > 0) { - artists = index.artist; - } else { - artists[0] = index.artist; + var html = '
  • Shortcuts
  • '; + $(html).appendTo("#ArtistContainer"); + $.each(shortcuts, function (i, item) { + if (item.name !== undefined) { + var html = '
  • '; + html += '' + item.name + ''; + html += '
  • '; + $(html).appendTo("#ArtistContainer"); } - $.each(artists, function (i, artist) { - if (artist.name !== undefined) { - var html = ""; - html += '
  • '; - html += '' + artist.name + ''; - html += '
  • '; - $(html).appendTo("#ArtistContainer"); + }); + } + + var indexes = []; + if (typeof data["subsonic-response"].indexes != 'undefined') { + if (typeof data["subsonic-response"].indexes.index != 'undefined') { + if (data["subsonic-response"].indexes.index.length > 0) { + indexes = data["subsonic-response"].indexes.index; + } else { + indexes[0] = data["subsonic-response"].indexes.index; + } + + + $.each(indexes, function (i, index) { + name = index.name; + $('
  • ' + name + '
  • ').appendTo("#ArtistContainer"); + indexlist += '
  • ' + name + '
  • '; + var artists = []; + if (index.artist.length > 0) { + artists = index.artist; + } else { + artists[0] = index.artist; + } + $.each(artists, function (i, artist) { + if (artist.name !== undefined) { + var html = ""; + html += '
  • '; + html += '' + artist.name + ''; + html += '
  • '; + $(html).appendTo("#ArtistContainer"); + } + }); + }); + //$(indexlist).appendTo("#IndexList"); + $("#BottomIndex").empty(); + $(indexlist).appendTo("#BottomIndex"); + } + var indexes = []; + if (data["subsonic-response"].indexes.child !== undefined) { + var rowcolor; + if (data["subsonic-response"].indexes.child.length > 0) { + indexes = data["subsonic-response"].indexes.child; + } else { + indexes[0] = data["subsonic-response"].indexes.child; + } + var appendto = '#AlbumContainer tbody'; + $(appendto).empty(); + $.each(indexes, function (i, child) { + if (child.isVideo != true) { + var html = generateRowHTML(child, appendto); + $(html).appendTo(appendto); } }); - }); - //$(indexlist).appendTo("#IndexList"); - $("#BottomIndex").empty(); - $(indexlist).appendTo("#BottomIndex"); - } - var indexes = []; - if (data["subsonic-response"].indexes.child !== undefined) { - var rowcolor; - if (data["subsonic-response"].indexes.child.length > 0) { - indexes = data["subsonic-response"].indexes.child; - } else { - indexes[0] = data["subsonic-response"].indexes.child; + header = generateSongHeaderHTML(); + } + if (smwidth) { + resizeSMSection(0); } - var appendto = '#AlbumContainer tbody'; - $(appendto).empty(); - $.each(indexes, function (i, child) { - if (child.isVideo != true) { - var html = generateRowHTML(child, appendto); - $(html).appendTo(appendto); - } - }); - header = generateSongHeaderHTML(); } - if (smwidth) { - resizeSMSection(0); - } - } - } else { - var status = data["subsonic-response"].status; - if (status == 'ok') { - alert('Status: ' + status + ', but Subsonic is busy, wait and refresh...'); } else { - alert(msg); + var status = data["subsonic-response"].status; + if (status == 'ok') { + alert('Status: ' + status + ', but Subsonic is busy, wait and refresh...'); + } else { + alert(msg); + } } } } + }); + } + } + function getMusicFolders() { + $.ajax({ + url: baseURL + '/getMusicFolders.view?' + baseParams + '&v=' + apiVersion + '&c=' + applicationName, + method: 'GET', + dataType: protocol, + timeout: 10000, + success: function (data) { + if (data["subsonic-response"].musicFolders.musicFolder !== undefined) { + var folders = []; + if (data["subsonic-response"].musicFolders.musicFolder.length > 0) { + folders = data["subsonic-response"].musicFolders.musicFolder; + } else { + folders[0] = data["subsonic-response"].musicFolders.musicFolder; + } + + var savedMusicFolder = getCookie('MusicFolders') ? getCookie('MusicFolders') : null; + var options = []; + options.push(''); + $.each(folders, function (i, folder) { + if (savedMusicFolder == folder.id && savedMusicFolder != null) { + options.push(''); + } else { + options.push(''); + } + }); + $('#MusicFolders').html(options.join('')); + } else { + } } }); } -} -function getMusicFolders() { - $.ajax({ - url: baseURL + '/getMusicFolders.view?v=' + apiVersion + '&c=' + applicationName + '&f=json', - method: 'GET', - dataType: 'json', - timeout: 10000, - success: function (data) { - if (data["subsonic-response"].musicFolders.musicFolder !== undefined) { - // There is a bug in the API that doesn't return a JSON array for one artist - var folders = []; - if (data["subsonic-response"].musicFolders.musicFolder.length > 0) { - folders = data["subsonic-response"].musicFolders.musicFolder; - } else { - folders[0] = data["subsonic-response"].musicFolders.musicFolder; - } - - var savedMusicFolder = getCookie('MusicFolders') ? getCookie('MusicFolders') : null; - var options = []; - options.push(''); - $.each(folders, function (i, folder) { - if (savedMusicFolder == folder.id && savedMusicFolder != null) { - options.push(''); - } else { - options.push(''); - } - }); - $('#MusicFolders').html(options.join('')); - } else { - } - } - }); -} -function getGenres() { - var genres = 'Acid Rock,Acoustic,Alt Country,Alt/Indie,Alternative & Punk,Alternative Metal,Alternative,AlternRock,Awesome,Bluegrass,Blues,Blues-Rock,Classic Hard Rock,Classic Rock,Comedy,Country,Country-Rock,Dance,Dance-Rock,Deep Funk,Easy Listening,Electronic,Electronica,Electronica/Dance,Folk,Folk/Rock,Funk,Grunge,Hard Rock,Heavy Metal,Holiday,House,Improg,Indie Rock,Indie,International,Irish,Jam Band,Jam,Jazz Fusion,Jazz,Latin,Live Albums,Metal,Music,Oldies,Other,Pop,Pop/Rock,Post Rock,Progressive Rock,Psychedelic Rock,Psychedelic,Punk,R&B,Rap & Hip-Hop,Reggae,Rock & Roll,Rock,Rock/Pop,Roots,Ska,Soft Rock,Soul,Southern Rock,Thrash Metal,Unknown,Vocal,World'; - var genresArr = genres.split(','); - var options = []; - options.push(''); - $.each(genresArr, function (i, genre) { - options.push(''); - }); - $('#Genres').html(options.join('')); -} -function loadAutoPlaylists(refresh) { - if (debug) { console.log("LOAD AUTO PLAYLISTS"); } - if (refresh) { - $('#AutoPlaylistContainer').empty(); - } - var content = $('#AutoPlaylistContainer').html(); - if (content === "") { - var genres = getCookie('AutoPlaylists'); - var genresArr = []; - if (genres) { - genresArr = genres.split(','); - genresArr.unshift('Random'); - genresArr.unshift('Starred'); - } else { - genresArr.push('Starred'); - genresArr.push('Random'); - } + function getGenres() { + var genres = 'Acid Rock,Acoustic,Alt Country,Alt/Indie,Alternative & Punk,Alternative Metal,Alternative,AlternRock,Awesome,Bluegrass,Blues,Blues-Rock,Classic Hard Rock,Classic Rock,Comedy,Country,Country-Rock,Dance,Dance-Rock,Deep Funk,Easy Listening,Electronic,Electronica,Electronica/Dance,Folk,Folk/Rock,Funk,Grunge,Hard Rock,Heavy Metal,Holiday,House,Improg,Indie Rock,Indie,International,Irish,Jam Band,Jam,Jazz Fusion,Jazz,Latin,Live Albums,Metal,Music,Oldies,Other,Pop,Pop/Rock,Post Rock,Progressive Rock,Psychedelic Rock,Psychedelic,Punk,R&B,Rap & Hip-Hop,Reggae,Rock & Roll,Rock,Rock/Pop,Roots,Ska,Soft Rock,Soul,Southern Rock,Thrash Metal,Unknown,Vocal,World'; + var genresArr = genres.split(','); + var options = []; + options.push(''); $.each(genresArr, function (i, genre) { - genre = genre.trim(); - var html = ""; - html += '
  • '; - html += '' + genre + ''; - html += '
    '; - html += '
    '; - html += '
  • '; - $(html).appendTo("#AutoPlaylistContainer"); + options.push(''); + }); + $('#Genres').html(options.join('')); + } + function loadAutoPlaylists(refresh) { + if (debug) { console.log("LOAD AUTO PLAYLISTS"); } + if (refresh) { + $('#AutoPlaylistContainer').empty(); + } + var content = $('#AutoPlaylistContainer').html(); + if (content === "") { + var genres = getCookie('AutoPlaylists'); + var genresArr = []; + if (genres) { + genresArr = genres.split(','); + genresArr.unshift('Random'); + genresArr.unshift('Starred'); + } else { + genresArr.push('Starred'); + genresArr.push('Random'); + } + $.each(genresArr, function (i, genre) { + genre = genre.trim(); + var html = ""; + html += '
  • '; + html += '' + genre + ''; + html += '
    '; + html += '
    '; + html += '
  • '; + $(html).appendTo("#AutoPlaylistContainer"); + }); + } + } + function getAlbums(id, action, appendto) { + $.ajax({ + url: baseURL + '/getMusicDirectory.view?' + baseParams + '&v=' + apiVersion + '&c=' + applicationName + '&id=' + id, + method: 'GET', + dataType: protocol, + timeout: 10000, + success: function (data) { + if (action == '') { + $('#AlbumContainer tbody').empty(); + } + if (action === 'autoplay') { + $('#CurrentPlaylistContainer tbody').empty(); + } + if (action == 'link') { + $('#AlbumContainer tbody').empty(); + $('#action_tabLibrary').trigger('click'); + } + if (data["subsonic-response"].directory.child !== undefined) { + var children = []; + if (data["subsonic-response"].directory.child.length > 0) { + children = data["subsonic-response"].directory.child; + } else { + children[0] = data["subsonic-response"].directory.child; + } + + var isDir = false; + var rowcolor; + var header; + $.each(children, function (i, child) { + var isVideo = false; + if (child.isDir == true) { isDir = true; } + if (child.isVideo == true) { isVideo = true; } + if (!isVideo) { + var html = generateRowHTML(child, appendto); + $(html).appendTo(appendto).hide().fadeIn('fast'); + } + }); + toggleAlbumListNextPrev('#status_Library', false, '', ''); + if (appendto == '#CurrentPlaylistContainer') { + updateMessage(children.length + ' Song(s) Added', true); + } + if (appendto == '#AlbumContainer tbody' && isDir == true) { + header = generateAlbumHeaderHTML(); + $('#songActions a.button').addClass('disabled'); + } + if (appendto == '#AlbumContainer tbody' && isDir == false) { + header = generateSongHeaderHTML(); + $('#songActions a.button').removeClass('disabled'); + } + $("#AlbumContainer thead").html(header); + if (action == 'autoplay') { + autoPlay(); + } + } + } }); } -} -function getAlbums(id, action, appendto) { - $.ajax({ - url: baseURL + '/getMusicDirectory.view?v=' + apiVersion + '&c=' + applicationName + '&f=json&id=' + id, - method: 'GET', - dataType: 'json', - timeout: 10000, - success: function (data) { - if (action == '') { - $('#AlbumContainer tbody').empty(); - } - if (action === 'autoplay') { - $('#CurrentPlaylistContainer tbody').empty(); - } - if (action == 'link') { - $('#AlbumContainer tbody').empty(); - $('#action_tabLibrary').trigger('click'); - } - if (data["subsonic-response"].directory.child !== 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; + /* Currently not being used */ + function getArtist(id, action, appendto) { + $.ajax({ + url: baseURL + '/getArtist.view?' + baseParams + '&v=' + apiVersion + '&c=' + applicationName + '&id=' + id, + method: 'GET', + dataType: protocol, + timeout: 10000, + success: function (data) { + if (action == '') { + $('#AlbumContainer tbody').empty(); } - - var isDir = false; - var rowcolor; - var header; - $.each(children, function (i, child) { - var isVideo = false; - if (child.isDir == true) { isDir = true; } - if (child.isVideo == true) { isVideo = true; } - if (!isVideo) { - var html = generateRowHTML(child, appendto); - $(html).appendTo(appendto).hide().fadeIn('fast'); - } - }); - toggleAlbumListNextPrev('#status_Library', false, '', ''); - if (appendto == '#CurrentPlaylistContainer') { - updateMessage(children.length + ' Song(s) Added', true); + if (action === 'autoplay') { + $('#CurrentPlaylistContainer tbody').empty(); } - if (appendto == '#AlbumContainer tbody' && isDir == true) { - header = generateAlbumHeaderHTML(); - $('#songActions a.button').addClass('disabled'); + if (action == 'link') { + $('#AlbumContainer tbody').empty(); + $('#action_tabLibrary').trigger('click'); } - if (appendto == '#AlbumContainer tbody' && isDir == false) { - header = generateSongHeaderHTML(); - $('#songActions a.button').removeClass('disabled'); - } - $("#AlbumContainer thead").html(header); - if (action == 'autoplay') { - autoPlay(); - } - } - } - }); -} -/* Currently not being used */ -function getArtist(id, action, appendto) { - $.ajax({ - url: baseURL + '/getArtist.view?v=' + apiVersion + '&c=' + applicationName + '&f=json&id=' + id, - method: 'GET', - dataType: 'json', - timeout: 10000, - success: function (data) { - if (action == '') { - $('#AlbumContainer tbody').empty(); - } - if (action === 'autoplay') { - $('#CurrentPlaylistContainer tbody').empty(); - } - if (action == 'link') { - $('#AlbumContainer tbody').empty(); - $('#action_tabLibrary').trigger('click'); - } - if (data["subsonic-response"].artist !== undefined) { - // There is a bug in the API that doesn't return a JSON array for one artist - var children = []; - if (data["subsonic-response"].artist.album.length > 0) { - children = data["subsonic-response"].artist.album; - } else { - children[0] = data["subsonic-response"].artist.album; - } - - var rowcolor; - var header; - $.each(children, function (i, child) { - var html = generateRowHTML(child, appendto); - $(html).appendTo(appendto).hide().fadeIn('fast'); - }); - toggleAlbumListNextPrev('#status_Library', false, '', ''); - if (appendto == '#CurrentPlaylistContainer') { - updateMessage(children.length + ' Song(s) Added', true); - } - if (appendto == '#AlbumContainer tbody') { - header = generateAlbumHeaderHTML(); - $('#songActions a.button').addClass('disabled'); - } - $("#AlbumContainer thead").html(header); - if (action == 'autoplay') { - autoPlay(); - } - } - } - }); -} -function getAlbumListBy(id, offset) { - var size, url; - if (getCookie('AutoAlbumSize')) { - size = getCookie('AutoAlbumSize'); - } else { - size = 15; - } - if (offset > 0) { - url = baseURL + '/getAlbumList.view?v=' + apiVersion + '&c=' + applicationName + '&f=json&size=' + size + '&type=' + id + '&offset=' + offset - } else { - url = baseURL + '/getAlbumList.view?v=' + apiVersion + '&c=' + applicationName + '&f=json&size=' + size + '&type=' + id - } - $.ajax({ - url: url, - method: 'GET', - dataType: 'json', - timeout: 10000, - success: function (data) { - if (data["subsonic-response"].status != 'failed') { - if (typeof data["subsonic-response"].albumList.album != "undefined") { - $("#AlbumContainer tbody").empty(); - var header = generateAlbumHeaderHTML(); - $("#AlbumContainer thead").html(header); - // There is a bug in the API that doesn't return a JSON array for one artist - var albums = []; - if (data["subsonic-response"].albumList.album.length > 0) { - albums = data["subsonic-response"].albumList.album; + if (data["subsonic-response"].artist !== undefined) { + var children = []; + if (data["subsonic-response"].artist.album.length > 0) { + children = data["subsonic-response"].artist.album; } else { - albums[0] = data["subsonic-response"].albumList.album; + children[0] = data["subsonic-response"].artist.album; } var rowcolor; - var html; - $.each(albums, function (i, album) { - // Only show albums, not songs (Rated songs will also be returned in API call, trying to display them will break Back button, disabled for now) - var albumhtml, starred; - if (album.starred !== undefined) { starred = true; } else { starred = false; } - if (album.isDir === true) { - albumhtml = generateAlbumHTML(album.id, album.parent, album.coverArt, album.title, album.artist, album.userRating, starred, album.created); - } - $(albumhtml).appendTo("#AlbumContainer tbody").hide().fadeIn('fast'); + var header; + $.each(children, function (i, child) { + var html = generateRowHTML(child, appendto); + $(html).appendTo(appendto).hide().fadeIn('fast'); }); - $('#BreadCrumbs').empty(); - $('#songActions a.button').addClass('disabled'); - toggleAlbumListNextPrev('#status_Library', true, id, offset); - } else { - updateMessage('Albums failed to load, no music :(', true); - $('#AlbumContainer tbody').empty(); + toggleAlbumListNextPrev('#status_Library', false, '', ''); + if (appendto == '#CurrentPlaylistContainer') { + updateMessage(children.length + ' Song(s) Added', true); + } + if (appendto == '#AlbumContainer tbody') { + header = generateAlbumHeaderHTML(); + $('#songActions a.button').addClass('disabled'); + } + $("#AlbumContainer thead").html(header); + if (action == 'autoplay') { + autoPlay(); + } } } - } - }); -} -function toggleAlbumListNextPrev(el, on, type, offset) { - if (el != '') { - if (on) { - $(el).addClass('on'); - $('#status_Library').data('type', type); - if (offset === undefined) { - $('#status_Library').data('offset', '0'); - } else { - $('#status_Library').data('offset', offset); - } + }); + } + function getAlbumListBy(id, offset) { + var size, url; + if (getCookie('AutoAlbumSize')) { + size = getCookie('AutoAlbumSize'); } else { - $(el).removeClass('on'); - $(el).stop().fadeOut(); - $('#status_Library').data('type', ''); - $('#status_Library').data('offset', '0'); + size = 15; } - } -} -function getRandomSongList(action, appendto, genre, folder) { - if (debug) { console.log('action:' + action + ', appendto:' + appendto + ', genre:' + genre + ', folder:' + folder); } - var size; - if (getCookie('AutoPlaylistSize')) { - size = getCookie('AutoPlaylistSize'); - } else { - size = 25; - } - var genreParams = ''; - if (genre != '' && genre != 'Random') { - genreParams = '&genre=' + genre; - } - folderParams = ''; - if (typeof folder == 'number' && folder == 0 && folder != 'all') { - folderParams = '&musicFolderId=' + folder; - } else if (folder != '' && folder != 'all') { - folderParams = '&musicFolderId=' + folder; - } - if (genre == 'Starred') { - getStarred(action, appendto, 'song'); - } else { - $.ajax({ - url: baseURL + '/getRandomSongs.view?v=' + apiVersion + '&c=' + applicationName + '&f=json&size=' + size + genreParams + folderParams, - method: 'GET', - dataType: 'json', - timeout: 10000, - success: function (data) { - if (data["subsonic-response"].randomSongs.song !== undefined) { - if (appendto == '#TrackContainer tbody') { - $("#TrackContainer tbody").empty(); - var header = generateSongHeaderHTML(); - $("#TrackContainer thead").html(header); - } - if (action == 'autoplay') { - $("#TrackContainer tbody").empty(); - $(appendto).empty(); - } - // There is a bug in the API that doesn't return a JSON array for one artist - var items = []; - if (data["subsonic-response"].randomSongs.song.length > 0) { - items = data["subsonic-response"].randomSongs.song; - } else { - items[0] = data["subsonic-response"].randomSongs.song; - } + if (offset > 0) { + url = baseURL + '/getAlbumList.view?' + baseParams + '&v=' + apiVersion + '&c=' + applicationName + '&size=' + size + '&type=' + id + '&offset=' + offset + } else { + url = baseURL + '/getAlbumList.view?' + baseParams + '&v=' + apiVersion + '&c=' + applicationName + '&size=' + size + '&type=' + id + } + $.ajax({ + url: url, + method: 'GET', + dataType: protocol, + timeout: 10000, + success: function (data) { + if (data["subsonic-response"].status != 'failed') { + if (typeof data["subsonic-response"].albumList.album != "undefined") { + $("#AlbumContainer tbody").empty(); + var header = generateAlbumHeaderHTML(); + $("#AlbumContainer thead").html(header); + var albums = []; + if (data["subsonic-response"].albumList.album.length > 0) { + albums = data["subsonic-response"].albumList.album; + } else { + albums[0] = data["subsonic-response"].albumList.album; + } - var rowcolor; - var html; - $.each(items, function (i, item) { - var track, starred, duration; - if (item.starred !== undefined) { starred = true; } else { starred = false; } - if (item.track === undefined) { track = " "; } else { track = item.track; } - if (item.duration !== undefined) { duration = item.duration; } else { duration = ''; } - html = generateSongHTML(item.id, item.parent, track, item.title, '', item.artist, item.album, item.coverArt, item.userRating, starred, duration); - $(html).appendTo(appendto); - }); - if (appendto === '#TrackContainer tbody') { - updateStatus('#status_Playlists', countCurrentPlaylist('#TrackContainer')); + var rowcolor; + var html; + $.each(albums, function (i, album) { + // Only show albums, not songs (Rated songs will also be returned in API call, trying to display them will break Back button, disabled for now) + var albumhtml, starred; + if (album.starred !== undefined) { starred = true; } else { starred = false; } + if (album.isDir === true) { + albumhtml = generateAlbumHTML(album.id, album.parent, album.coverArt, album.title, album.artist, album.userRating, starred, album.created); + } + $(albumhtml).appendTo("#AlbumContainer tbody").hide().fadeIn('fast'); + }); + $('#BreadCrumbs').empty(); + $('#songActions a.button').addClass('disabled'); + toggleAlbumListNextPrev('#status_Library', true, id, offset); + } else { + updateMessage('Albums failed to load, no music :(', true); + $('#AlbumContainer tbody').empty(); + } } - if (appendto === '#CurrentPlaylistContainer tbody') { - updateMessage(items.length + ' Song(s) Added', true); - updateStatus('#status_Current', countCurrentPlaylist('#CurrentPlaylistContainer')); - } - if (action == 'autoplay' || action == 'autoplayappend') { - autoPlay(); + } + }); + } + function toggleAlbumListNextPrev(el, on, type, offset) { + if (el != '') { + if (on) { + $(el).addClass('on'); + $('#status_Library').data('type', type); + if (offset === undefined) { + $('#status_Library').data('offset', '0'); + } else { + $('#status_Library').data('offset', offset); } } else { - updateStatus('#status_Playlists', ''); - $(appendto).empty(); + $(el).removeClass('on'); + $(el).stop().fadeOut(); + $('#status_Library').data('type', ''); + $('#status_Library').data('offset', '0'); } } - }); } -} -function getStarred(action, appendto, type) { - var size; - if (getCookie('AutoPlaylistSize')) { - size = getCookie('AutoPlaylistSize'); - } else { - size = 25; - } - $.ajax({ - url: baseURL + '/getStarred.view?v=' + apiVersion + '&c=' + applicationName + '&f=json&size=' + size, - method: 'GET', - dataType: 'json', - timeout: 10000, - success: function (data) { - if (data["subsonic-response"].starred !== undefined) { - if (appendto === '#TrackContainer tbody') { - $("#TrackContainer tbody").empty(); - var header = generateSongHeaderHTML(); - $("#TrackContainer thead").html(header); - } - if (action === 'autoplay') { - $("#TrackContainer tbody").empty(); - $(appendto).empty(); - } - // There is a bug in the API that doesn't return a JSON array for one artist - var items = []; - switch (type) { - case 'artist': - if (data["subsonic-response"].starred.artist !== undefined) { - if (data["subsonic-response"].starred.artist.length > 0) { - items = data["subsonic-response"].starred.artist; - } else { - items[0] = data["subsonic-response"].starred.artist; - } + function getRandomSongList(action, appendto, genre, folder) { + if (debug) { console.log('action:' + action + ', appendto:' + appendto + ', genre:' + genre + ', folder:' + folder); } + var size; + if (getCookie('AutoPlaylistSize')) { + size = getCookie('AutoPlaylistSize'); + } else { + size = 25; + } + var genreParams = ''; + if (genre != '' && genre != 'Random') { + genreParams = '&genre=' + genre; + } + folderParams = ''; + if (typeof folder == 'number' && folder == 0 && folder != 'all') { + folderParams = '&musicFolderId=' + folder; + } else if (folder != '' && folder != 'all') { + folderParams = '&musicFolderId=' + folder; + } + if (genre == 'Starred') { + getStarred(action, appendto, 'song'); + } else { + $.ajax({ + url: baseURL + '/getRandomSongs.view?' + baseParams + '&v=' + apiVersion + '&c=' + applicationName + '&size=' + size + genreParams + folderParams, + method: 'GET', + dataType: protocol, + timeout: 10000, + success: function (data) { + if (data["subsonic-response"].randomSongs.song !== undefined) { + if (appendto == '#TrackContainer tbody') { + $("#TrackContainer tbody").empty(); + var header = generateSongHeaderHTML(); + $("#TrackContainer thead").html(header); } - break; - case 'album': - if (data["subsonic-response"].starred.album !== undefined) { - if (data["subsonic-response"].starred.album.length > 0) { - items = data["subsonic-response"].starred.album; - } else { - items[0] = data["subsonic-response"].starred.album; - } + if (action == 'autoplay') { + $("#TrackContainer tbody").empty(); + $(appendto).empty(); } - break; - case 'song': - if (data["subsonic-response"].starred.song !== undefined) { - if (data["subsonic-response"].starred.song.length > 0) { - items = data["subsonic-response"].starred.song; - } else { - items[0] = data["subsonic-response"].starred.song; - } + var items = []; + if (data["subsonic-response"].randomSongs.song.length > 0) { + items = data["subsonic-response"].randomSongs.song; + } else { + items[0] = data["subsonic-response"].randomSongs.song; } - break; - default: - break; - } - var rowcolor; - var html; - $.each(items, function (i, item) { - var track, starred; - if (item.starred !== undefined) { starred = true; } else { starred = false; } - if (item.track === undefined) { track = " "; } else { track = item.track; } - var time = secondsToTime(item.duration); + var rowcolor; + var html; + $.each(items, function (i, item) { + var track, starred, duration; + if (item.starred !== undefined) { starred = true; } else { starred = false; } + if (item.track === undefined) { track = " "; } else { track = item.track; } + if (item.duration !== undefined) { duration = item.duration; } else { duration = ''; } + html = generateSongHTML(item.id, item.parent, track, item.title, '', item.artist, item.album, item.coverArt, item.userRating, starred, duration); + $(html).appendTo(appendto); + }); + if (appendto === '#TrackContainer tbody') { + updateStatus('#status_Playlists', countCurrentPlaylist('#TrackContainer')); + } + if (appendto === '#CurrentPlaylistContainer tbody') { + updateMessage(items.length + ' Song(s) Added', true); + updateStatus('#status_Current', countCurrentPlaylist('#CurrentPlaylistContainer')); + } + if (action == 'autoplay' || action == 'autoplayappend') { + autoPlay(); + } + } else { + updateStatus('#status_Playlists', ''); + $(appendto).empty(); + } + } + }); + } + } + function getStarred(action, appendto, type) { + var size; + if (getCookie('AutoPlaylistSize')) { + size = getCookie('AutoPlaylistSize'); + } else { + size = 25; + } + $.ajax({ + url: baseURL + '/getStarred.view?' + baseParams + '&v=' + apiVersion + '&c=' + applicationName + '&size=' + size, + method: 'GET', + dataType: protocol, + timeout: 10000, + success: function (data) { + if (data["subsonic-response"].starred !== undefined) { + if (appendto === '#TrackContainer tbody') { + $("#TrackContainer tbody").empty(); + var header = generateSongHeaderHTML(); + $("#TrackContainer thead").html(header); + } + if (action === 'autoplay') { + $("#TrackContainer tbody").empty(); + $(appendto).empty(); + } + var items = []; switch (type) { case 'artist': + if (data["subsonic-response"].starred.artist !== undefined) { + if (data["subsonic-response"].starred.artist.length > 0) { + items = data["subsonic-response"].starred.artist; + } else { + items[0] = data["subsonic-response"].starred.artist; + } + } break; case 'album': - html = generateRowHTML(item, appendto); + if (data["subsonic-response"].starred.album !== undefined) { + if (data["subsonic-response"].starred.album.length > 0) { + items = data["subsonic-response"].starred.album; + } else { + items[0] = data["subsonic-response"].starred.album; + } + } break; case 'song': - html = generateRowHTML(item, appendto); + if (data["subsonic-response"].starred.song !== undefined) { + if (data["subsonic-response"].starred.song.length > 0) { + items = data["subsonic-response"].starred.song; + } else { + items[0] = data["subsonic-response"].starred.song; + } + } break; default: break; } - $(html).appendTo(appendto); - }); - if (appendto == '#TrackContainer tbody') { - updateStatus('#status_Playlists', countCurrentPlaylist('#TrackContainer')); + + var rowcolor; + var html; + $.each(items, function (i, item) { + var track, starred; + if (item.starred !== undefined) { starred = true; } else { starred = false; } + if (item.track === undefined) { track = " "; } else { track = item.track; } + var time = secondsToTime(item.duration); + switch (type) { + case 'artist': + break; + case 'album': + html = generateRowHTML(item, appendto); + break; + case 'song': + html = generateRowHTML(item, appendto); + break; + default: + break; + } + $(html).appendTo(appendto); + }); + if (appendto == '#TrackContainer tbody') { + updateStatus('#status_Playlists', countCurrentPlaylist('#TrackContainer')); + } + if (appendto == '#CurrentPlaylistContainer tbody') { + updateMessage(items.length + ' Song(s) Added', true); + } + if (action == 'autoplay') { + autoPlay(); + } + } else { + $(appendto).empty(); } - if (appendto == '#CurrentPlaylistContainer tbody') { - updateMessage(items.length + ' Song(s) Added', true); - } - if (action == 'autoplay') { - autoPlay(); - } - } else { - $(appendto).empty(); } - } - }); -} -var updaterNowPlaying; -var updaterNowPlayingIdList = []; -function updateNowPlaying(showPopup) { - updaterNowPlaying = $.periodic({ period: 4000, decay: 1.5, max_period: 30000 }, function () { + }); + } + var updaterNowPlaying; + var updaterNowPlayingIdList = []; + function updateNowPlaying(showPopup) { + updaterNowPlaying = $.periodic({ period: 4000, decay: 1.5, max_period: 30000 }, function () { + $.ajax({ + periodic: this, + url: baseURL + '/getNowPlaying.view?' + baseParams + '&v=' + apiVersion + '&c=' + applicationName, + method: 'GET', + dataType: protocol, + timeout: 10000, + success: function (data) { + if (data["subsonic-response"].nowPlaying.entry === undefined) { + this.periodic.increment(); + $("#NowPlayingList").empty(); + var chathtml = '
    '; + chathtml += 'Nothing :(
    '; + chathtml += '
    '; + $(chathtml).appendTo("#NowPlayingList"); + } else { + this.periodic.increment(); + if (debug) { console.log('NowPlaying Delay: ' + this.periodic.cur_period); } + $("#NowPlayingList").empty(); + var msgs = []; + if (data["subsonic-response"].nowPlaying.entry.length > 0) { + msgs = data["subsonic-response"].nowPlaying.entry; + } else { + msgs[0] = data["subsonic-response"].nowPlaying.entry; + } + var sorted = msgs.sort(function (a, b) { + return a.minutesAgo - b.minutesAgo; + }); + $.each(sorted, function (i, msg) { + if (!showPopup) { + var chathtml = '
    '; + chathtml += '' + msg.username + '
    '; + chathtml += '' + msg.artist + ' - ' + msg.title + ''; + chathtml += '
    '; + $(chathtml).appendTo("#NowPlayingList"); + } + var coverartSrc; + if (msg.coverArt === undefined) { + coverartSrc = 'images/albumdefault_50.jpg'; + } else { + coverartSrc = baseURL + '/getCoverArt.view?' + baseParams + '&v=' + apiVersion + '&c=' + applicationName + '&size=50&id=' + msg.coverArt; + } + if (getCookie('Notification_NowPlaying')) { + var sid = msg.username + '-' + msg.id; + if (jQuery.inArray(sid, updaterNowPlayingIdList) === -1 && username != msg.username) { + showNotification(coverartSrc, toHTML.un(msg.username + ':' + msg.playerName), toHTML.un(msg.artist + ' - ' + msg.title), 'text', ''); + updaterNowPlayingIdList.push(sid); + } + } + }); + } + } + }); + }); + } + function stopUpdateNowPlaying() { + updaterNowPlaying.cancel(); + } + + function search(type, query) { $.ajax({ - periodic: this, - url: baseURL + '/getNowPlaying.view?v=' + apiVersion + '&c=' + applicationName + '&f=json', + url: baseURL + '/search2.view?' + baseParams + '&v=' + apiVersion + '&c=' + applicationName + '&query=' + query, method: 'GET', - dataType: 'json', + dataType: protocol, timeout: 10000, success: function (data) { - if (data["subsonic-response"].nowPlaying.entry === undefined) { - this.periodic.increment(); - $("#NowPlayingList").empty(); - var chathtml = '
    '; - chathtml += 'Nothing :(
    '; - chathtml += '
    '; - $(chathtml).appendTo("#NowPlayingList"); - } else { - this.periodic.increment(); - if (debug) { console.log('NowPlaying Delay: ' + this.periodic.cur_period); } - $("#NowPlayingList").empty(); - var msgs = []; - if (data["subsonic-response"].nowPlaying.entry.length > 0) { - msgs = data["subsonic-response"].nowPlaying.entry; - } else { - msgs[0] = data["subsonic-response"].nowPlaying.entry; - } - var sorted = msgs.sort(function (a, b) { - return a.minutesAgo - b.minutesAgo; - }); - $.each(sorted, function (i, msg) { - if (!showPopup) { - var chathtml = '
    '; - chathtml += '' + msg.username + '
    '; - chathtml += '' + msg.artist + ' - ' + msg.title + ''; - chathtml += '
    '; - $(chathtml).appendTo("#NowPlayingList"); - } - var coverartSrc; - if (msg.coverArt === undefined) { - coverartSrc = 'images/albumdefault_50.jpg'; - } else { - coverartSrc = baseURL + '/getCoverArt.view?v=' + apiVersion + '&c=' + applicationName + '&f=json&size=50&id=' + msg.coverArt; - } - if (getCookie('Notification_NowPlaying')) { - var sid = msg.username + '-' + msg.id; - if (jQuery.inArray(sid, updaterNowPlayingIdList) === -1 && username != msg.username) { - showNotification(coverartSrc, toHTML.un(msg.username + ':' + msg.playerName), toHTML.un(msg.artist + ' - ' + msg.title), 'text', ''); - updaterNowPlayingIdList.push(sid); + $("#AlbumContainer tbody").empty(); + if (data["subsonic-response"].searchResult2 !== "") { + var header; + var children = []; + if (type === 'song') { + if (data["subsonic-response"].searchResult2.song !== undefined) { + header = generateSongHeaderHTML(); + if (data["subsonic-response"].searchResult2.song.length > 0) { + children = data["subsonic-response"].searchResult2.song; + } else { + children[0] = data["subsonic-response"].searchResult2.song; } + $("#AlbumContainer thead").html(header); } + } + if (type === 'album') { + if (data["subsonic-response"].searchResult2.album !== undefined) { + header = generateAlbumHeaderHTML(); + if (data["subsonic-response"].searchResult2.album.length > 0) { + children = data["subsonic-response"].searchResult2.album; + } else { + children[0] = data["subsonic-response"].searchResult2.album; + } + $("#AlbumContainer thead").html(header); + } + } + $.each(children, function (i, child) { + var starred; + if (child.starred !== undefined) { starred = true; } else { starred = false; } + isDir = child.isDir; + if (isDir === true) { + albumhtml = generateAlbumHTML(child.id, child.parent, child.coverArt, child.title, child.artist, child.userRating, starred, child.created); + } else { + var track, starred, duration; + if (child.starred !== undefined) { starred = true; } else { starred = false; } + if (child.track === undefined) { track = " "; } else { track = child.track; } + if (child.duration !== undefined) { duration = child.duration; } else { duration = ''; } + albumhtml = generateSongHTML(child.id, child.parent, track, child.title, '', child.artist, child.album, child.coverArt, child.userRating, starred, duration); + } + $(albumhtml).appendTo("#AlbumContainer tbody"); }); } } }); - }); -} -function stopUpdateNowPlaying() { - updaterNowPlaying.cancel(); -} + } -function search(type, query) { - $.ajax({ - url: baseURL + '/search2.view?v=' + apiVersion + '&c=' + applicationName + '&f=json&query=' + query, - method: 'GET', - dataType: 'json', - timeout: 10000, - success: function (data) { - $("#AlbumContainer tbody").empty(); - if (data["subsonic-response"].searchResult2 !== "") { - var header; - var children = []; - if (type === 'song') { - if (data["subsonic-response"].searchResult2.song !== undefined) { - header = generateSongHeaderHTML(); - if (data["subsonic-response"].searchResult2.song.length > 0) { - children = data["subsonic-response"].searchResult2.song; - } else { - children[0] = data["subsonic-response"].searchResult2.song; - } - $("#AlbumContainer thead").html(header); - } - } - if (type === 'album') { - if (data["subsonic-response"].searchResult2.album !== undefined) { - header = generateAlbumHeaderHTML(); - if (data["subsonic-response"].searchResult2.album.length > 0) { - children = data["subsonic-response"].searchResult2.album; - } else { - children[0] = data["subsonic-response"].searchResult2.album; - } - $("#AlbumContainer thead").html(header); - } - } - $.each(children, function (i, child) { - var starred; - if (child.starred !== undefined) { starred = true; } else { starred = false; } - isDir = child.isDir; - if (isDir === true) { - albumhtml = generateAlbumHTML(child.id, child.parent, child.coverArt, child.title, child.artist, child.userRating, starred, child.created); + function loadFolders(refresh) { + if (debug) { console.log("LOAD FOLDERS"); } + if (refresh) { + $('#FolderContainer').empty(); + } + var content = $('#FolderContainer').html(); + if (content === "") { + // Load Folders + $.ajax({ + url: baseURL + '/getMusicFolders.view?' + baseParams + '&v=' + apiVersion + '&c=' + applicationName, + method: 'GET', + dataType: protocol, + timeout: 10000, + success: function (data) { + var musicFolders = []; + if (data["subsonic-response"].musicFolders.musicFolder.length > 0) { + musicFolders = data["subsonic-response"].musicFolders.musicFolder; } else { + musicFolders[0] = data["subsonic-response"].musicFolders.musicFolder; + } + $.each(musicFolders, function (i, musicFolder) { + var html = ""; + html += '
  • '; + html += '' + musicFolder.name + ''; + html += '
    '; + html += '
    '; + html += '
  • '; + $(html).appendTo("#FolderContainer"); + }); + } + }); + } + } + function loadPlaylists(refresh) { + if (debug) { console.log("LOAD PLAYLISTS"); } + if (refresh) { + $('#PlaylistContainer').empty(); + } + var content = $('#PlaylistContainer').html(); + if (content === "") { + // Load Playlists + $.ajax({ + url: baseURL + '/getPlaylists.view?' + baseParams + '&v=' + apiVersion + '&c=' + applicationName, + method: 'GET', + dataType: protocol, + timeout: 10000, + success: function (data) { + var playlists = []; + if (data["subsonic-response"].playlists.playlist !== undefined) { + 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 += '
    '; + html += '
    '; + html += '
    '; + html += '
    ' + playlist.name + '
    '; + html += '
  • '; + $(html).appendTo("#PlaylistContainer"); + }); + if (smwidth) { + resizeSMSection(0); + } + } + } + }); + } + } + 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?' + baseParams, + dataType: protocol, + timeout: 10000, + data: { v: apiVersion, c: applicationName, playlistId: playlistid, songId: songs }, + success: function () { + getPlaylist(playlistid); + updateMessage('Playlist Updated!', true); + }, + traditional: true // Fixes POST with an array in JQuery 1.4 + }); + } + } + function getPlaylist(id, action, appendto) { + $.ajax({ + url: baseURL + '/getPlaylist.view?' + baseParams + '&v=' + apiVersion + '&c=' + applicationName + '&id=' + id, + method: 'GET', + dataType: protocol, + timeout: 10000, + 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(); + } + var children = []; + var playlist = data["subsonic-response"].playlist; + if (playlist.entry.length > 0) { + children = playlist.entry; + } else { + children[0] = playlist.entry; + } + + var rowcolor; + var html; + var count = children.length; + $.each(children, function (i, child) { var track, starred, duration; if (child.starred !== undefined) { starred = true; } else { starred = false; } if (child.track === undefined) { track = " "; } else { track = child.track; } if (child.duration !== undefined) { duration = child.duration; } else { duration = ''; } - albumhtml = generateSongHTML(child.id, child.parent, track, child.title, '', child.artist, child.album, child.coverArt, child.userRating, starred, duration); + html = generateSongHTML(child.id, child.parent, track, child.title, '', child.artist, child.album, child.coverArt, child.userRating, starred, duration); + $(html).appendTo(appendto); + }); + if (appendto === '#TrackContainer tbody') { + updateStatus('#status_Playlists', countCurrentPlaylist('#TrackContainer')); + } + if (appendto === '#CurrentPlaylistContainer tbody') { + updateMessage(children.length + ' Song(s) Added', true); + } + if (action === 'autoplay') { + autoPlay(); } - $(albumhtml).appendTo("#AlbumContainer tbody"); - }); - } - } - }); -} - -function loadFolders(refresh) { - if (debug) { console.log("LOAD FOLDERS"); } - if (refresh) { - $('#FolderContainer').empty(); - } - var content = $('#FolderContainer').html(); - if (content === "") { - // Load Folders - $.ajax({ - url: baseURL + '/getMusicFolders.view?v=' + apiVersion + '&c=' + applicationName + '&f=json', - method: 'GET', - dataType: 'json', - timeout: 10000, - success: function (data) { - var musicFolders = []; - if (data["subsonic-response"].musicFolders.musicFolder.length > 0) { - musicFolders = data["subsonic-response"].musicFolders.musicFolder; } else { - musicFolders[0] = data["subsonic-response"].musicFolders.musicFolder; + if (appendto === '#TrackContainer tbody') { + $(appendto).empty(); + updateStatus('#status_Playlists', ''); + } } - $.each(musicFolders, function (i, musicFolder) { - var html = ""; - html += '
  • '; - html += '' + musicFolder.name + ''; - html += '
    '; - html += '
    '; - html += '
  • '; - $(html).appendTo("#FolderContainer"); - }); } }); } -} -function loadPlaylists(refresh) { - if (debug) { console.log("LOAD PLAYLISTS"); } - if (refresh) { - $('#PlaylistContainer').empty(); - } - var content = $('#PlaylistContainer').html(); - if (content === "") { - // Load Playlists + function loadPlaylistsForMenu(menu) { + $('#' + menu).empty(); $.ajax({ - url: baseURL + '/getPlaylists.view?v=' + apiVersion + '&c=' + applicationName + '&f=json', + url: baseURL + '/getPlaylists.view?' + baseParams + '&v=' + apiVersion + '&c=' + applicationName, method: 'GET', - dataType: 'json', + dataType: protocol, timeout: 10000, success: function (data) { var playlists = []; @@ -730,519 +821,410 @@ function loadPlaylists(refresh) { } else { playlists[0] = data["subsonic-response"].playlists.playlist; } - $.each(playlists, function (i, playlist) { - var html = ""; - html += '
  • '; - html += '
    '; - html += '
    '; - html += '
    '; - html += '
    ' + playlist.name + '
    '; - html += '
  • '; - $(html).appendTo("#PlaylistContainer"); - }); - if (smwidth) { - resizeSMSection(0); - } } - } - }); - } -} -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: 'json', - timeout: 10000, - data: { v: apiVersion, c: applicationName, f: "json", playlistId: playlistid, songId: songs }, - success: function () { - getPlaylist(playlistid); - updateMessage('Playlist Updated!', true); - }, - traditional: true // Fixes POST with an array in JQuery 1.4 - }); - } -} -function getPlaylist(id, action, appendto) { - $.ajax({ - url: baseURL + '/getPlaylist.view?v=' + apiVersion + '&c=' + applicationName + '&f=json&id=' + id, - method: 'GET', - dataType: 'json', - timeout: 10000, - 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 = []; - var playlist = data["subsonic-response"].playlist; - if (playlist.entry.length > 0) { - children = playlist.entry; - } else { - children[0] = playlist.entry; - } - - var rowcolor; - var html; - var count = children.length; - $.each(children, function (i, child) { - var track, starred, duration; - if (child.starred !== undefined) { starred = true; } else { starred = false; } - if (child.track === undefined) { track = " "; } else { track = child.track; } - if (child.duration !== undefined) { duration = child.duration; } else { duration = ''; } - html = generateSongHTML(child.id, child.parent, track, child.title, '', child.artist, child.album, child.coverArt, child.userRating, starred, duration); - $(html).appendTo(appendto); + $("+ New
    ").appendTo("#" + menu); + $.each(playlists, function (i, playlist) { + $('' + playlist.name + '
    ').appendTo("#" + menu); }); - if (appendto === '#TrackContainer tbody') { - updateStatus('#status_Playlists', countCurrentPlaylist('#TrackContainer')); - } - if (appendto === '#CurrentPlaylistContainer tbody') { - updateMessage(children.length + ' Song(s) Added', true); - } - if (action === 'autoplay') { - autoPlay(); - } - } else { - if (appendto === '#TrackContainer tbody') { - $(appendto).empty(); - updateStatus('#status_Playlists', ''); - } } - } - }); -} -function loadPlaylistsForMenu(menu) { - $('#' + menu).empty(); - $.ajax({ - url: baseURL + '/getPlaylists.view?v=' + apiVersion + '&c=' + applicationName + '&f=json', - method: 'GET', - dataType: 'json', - timeout: 10000, - success: function (data) { - var playlists = []; - if (data["subsonic-response"].playlists.playlist !== undefined) { - if (data["subsonic-response"].playlists.playlist.length > 0) { - playlists = data["subsonic-response"].playlists.playlist; - } else { - playlists[0] = data["subsonic-response"].playlists.playlist; + }); + } + function newPlaylist() { + var reply = prompt("Choose a name for your new playlist.", ""); + if (reply != 'null' && reply != null && reply != '') { + $.ajax({ + url: baseURL + '/createPlaylist.view?' + baseParams + '&v=' + apiVersion + '&c=' + applicationName + '&name=' + reply, + method: 'GET', + dataType: protocol, + timeout: 10000, + success: function (data) { + loadPlaylists(true); } - } - $("+ New
    ").appendTo("#" + menu); - $.each(playlists, function (i, playlist) { - $('' + playlist.name + '
    ').appendTo("#" + menu); }); } - }); -} -function newPlaylist() { - var reply = prompt("Choose a name for your new playlist.", ""); - if (reply != 'null' && reply != null && reply != '') { + } + function deletePlaylist(id) { $.ajax({ - url: baseURL + '/createPlaylist.view?v=' + apiVersion + '&c=' + applicationName + '&f=json&name=' + reply, + url: baseURL + '/deletePlaylist.view?' + baseParams + '&v=' + apiVersion + '&c=' + applicationName + '&id=' + id, method: 'GET', - dataType: 'json', + dataType: protocol, timeout: 10000, success: function (data) { loadPlaylists(true); + $('#TrackContainer tbody').empty(); } }); } -} -function deletePlaylist(id) { - $.ajax({ - url: baseURL + '/deletePlaylist.view?v=' + apiVersion + '&c=' + applicationName + '&f=json&id=' + id, - method: 'GET', - dataType: 'json', - timeout: 10000, - 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?v=' + apiVersion + '&c=' + applicationName + '&f=json&id=' + playlistid, - method: 'GET', - dataType: 'json', - timeout: 10000, - 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) { - var runningVersion = parseVersionString(apiVersion); - var minimumVersion = parseVersionString('1.8.0'); - if (checkVersion(runningVersion, minimumVersion)) { // is 1.8.0 or newer - $.ajax({ - type: 'GET', - url: baseURL + '/updatePlaylist.view', - dataType: 'json', - timeout: 10000, - data: { v: apiVersion, c: applicationName, f: "json", playlistId: playlistid, songIdToAdd: selected }, - success: function (data) { - // Add logic to show an error if the playlist update fails - // if (data["subsonic-response"].playlist.entry !== undefined) { - $('table.songlist tr.song').each(function () { - $(this).removeClass('selected'); - }); - updateMessage(count + ' Song(s) Added to Playlist', true); - }, - traditional: true // Fixes POST with an array in JQuery 1.4 - }); - } else { - $.ajax({ // Depreciated: 11/5/2012 - type: 'GET', - url: baseURL + '/createPlaylist.view', - dataType: 'json', - timeout: 10000, - data: { v: apiVersion, c: applicationName, f: "json", playlistId: playlistid, songId: currentsongs }, - success: function () { - $('table.songlist tr.song').each(function () { - $(this).removeClass('selected'); - }); - updateMessage(count + ' Song(s) Added to Playlist', true); - }, - traditional: true // Fixes POST with an array in JQuery 1.4 - }); - } - } - } - }); + function addToPlaylist(playlistid, from) { + var selected = []; + var el; + if (from === 'current') { + el = $('#CurrentPlaylist table.songlist tr.selected'); } else { - var reply = prompt("Choose a name for your new playlist.", ""); - if (reply) { + 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({ - type: 'GET', - url: baseURL + '/createPlaylist.view', - dataType: 'json', + url: baseURL + '/getPlaylist.view?' + baseParams + '&v=' + apiVersion + '&c=' + applicationName + '&id=' + playlistid, + method: 'GET', + dataType: protocol, timeout: 10000, - data: { v: apiVersion, c: applicationName, f: "json", name: "" + reply + "", songId: selected }, - success: function () { - $('table.songlist tr.song').each(function () { - $(this).removeClass('selected'); + success: function (data) { + 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++; + } }); - updateMessage('Playlist Created!', true); - }, - traditional: true // Fixes POST with an array in JQuery 1.4 + if (count > 0) { + var runningVersion = parseVersionString(apiVersion); + var minimumVersion = parseVersionString('1.8.0'); + if (checkVersion(runningVersion, minimumVersion)) { // is 1.8.0 or newer + $.ajax({ + type: 'GET', + url: baseURL + '/updatePlaylist.view?' + baseParams, + dataType: protocol, + timeout: 10000, + data: { v: apiVersion, c: applicationName, playlistId: playlistid, songIdToAdd: selected }, + success: function (data) { + // Add logic to show an error if the playlist update fails + // if (data["subsonic-response"].playlist.entry !== undefined) { + $('table.songlist tr.song').each(function () { + $(this).removeClass('selected'); + }); + updateMessage(count + ' Song(s) Added to Playlist', true); + }, + traditional: true // Fixes POST with an array in JQuery 1.4 + }); + } else { + $.ajax({ // Depreciated: 11/5/2012 + type: 'GET', + url: baseURL + '/createPlaylist.view?' + baseParams, + dataType: protocol, + timeout: 10000, + data: { v: apiVersion, c: applicationName, playlistId: playlistid, songId: currentsongs }, + success: function () { + $('table.songlist tr.song').each(function () { + $(this).removeClass('selected'); + }); + updateMessage(count + ' Song(s) Added to Playlist', true); + }, + traditional: true // Fixes POST with an array in JQuery 1.4 + }); + } + } + } + }); + } else { + var reply = prompt("Choose a name for your new playlist.", ""); + if (reply) { + $.ajax({ + type: 'GET', + url: baseURL + '/createPlaylist.view?' + baseParams, + dataType: protocol, + timeout: 10000, + data: { v: apiVersion, c: applicationName, name: "" + reply + "", songId: selected }, + success: function () { + $('table.songlist tr.song').each(function () { + $(this).removeClass('selected'); + }); + updateMessage('Playlist Created!', true); + }, + 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'); + }); + } else { + $('#AlbumContainer tr.selected').each(function (index) { + $(this).clone().appendTo('#CurrentPlaylistContainer tbody'); }); } + $('#CurrentPlaylistContainer tbody tr.song').removeClass('selected'); + updateMessage(count + ' Song(s) Added', true); } - 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'); + function countCurrentPlaylist(container) { + var total = $(container + ' tr.song').size(); + if (total > 0) { + var time = 0; + $(container + ' tr.song').each(function (index) { + var duration = $(this).attr('duration'); + if (duration != '') { + time += parseInt(duration); + } }); + return total + ' song(s), ' + secondsToTime(time) + ' total time'; } else { - $('#AlbumContainer tr.selected').each(function (index) { - $(this).clone().appendTo('#CurrentPlaylistContainer tbody'); - }); + return ''; } - $('#CurrentPlaylistContainer tbody tr.song').removeClass('selected'); - updateMessage(count + ' Song(s) Added', true); } -} -function countCurrentPlaylist(container) { - var total = $(container + ' tr.song').size(); - if (total > 0) { - var time = 0; - $(container + ' tr.song').each(function (index) { - var duration = $(this).attr('duration'); - if (duration != '') { - time += parseInt(duration); - } - }); - return total + ' song(s), ' + secondsToTime(time) + ' total time'; - } else { - return ''; - } -} -function saveCurrentPlaylist() { - if (browserStorageCheck) { - var html = localStorage.getItem('CurrentPlaylist'); - var current = $('#CurrentPlaylistContainer tbody').html(); - if (current != '' && current != html) { - try { - localStorage.setItem('CurrentPlaylist', current); - if (debug) { console.log('Saving Play Queue: ' + current.length + ' characters'); } - } catch (e) { - if (e == QUOTA_EXCEEDED_ERR) { - alert('Quota exceeded!'); + function saveCurrentPlaylist() { + if (browserStorageCheck) { + var html = localStorage.getItem('CurrentPlaylist'); + var current = $('#CurrentPlaylistContainer tbody').html(); + if (current != '' && current != html) { + try { + localStorage.setItem('CurrentPlaylist', current); + if (debug) { console.log('Saving Play Queue: ' + current.length + ' characters'); } + } catch (e) { + if (e == QUOTA_EXCEEDED_ERR) { + alert('Quota exceeded!'); + } } } - } - } else { - if (debug) { console.log('HTML5::loadStorage not supported on your browser' + html.length + ' characters'); } - } -} -function deleteCurrentPlaylist() { - if (browserStorageCheck) { - localStorage.removeItem('CurrentPlaylist'); - setCookie('CurrentSong', null); - if (debug) { console.log('Removing Play Queue'); } - } else { - if (debug) { console.log('HTML5::loadStorage not supported on your browser' + html.length + ' characters'); } - } -} -function loadCurrentPlaylist() { - if (browserStorageCheck) { - var html = localStorage.getItem('CurrentPlaylist'); - if (html != '' && html !== undefined && html !== null) { - $('#CurrentPlaylistContainer tbody').html(html); - if (debug) { console.log('Load Play Queue From localStorage: ' + html.length + ' characters'); } - } - } else { - if (debug) { console.log('HTML5::loadStorage not supported on your browser' + html.length + ' characters'); } - } -} -function saveTrackPosition() { - var el = $('#songdetails_song'); - var songid = el.attr('childid'); - if (songid !== undefined) { - var albumid = el.attr('parentid'); - var position = $("#playdeck").data("jPlayer").status.currentTime; - if (position != null && position >= 5) { - var currentSong = { - songid: songid, - albumid: albumid, - position: position - }; - $('#action_SaveProgress').show(); - setCookie('CurrentSong', JSON.stringify(currentSong)); - saveCurrentPlaylist(); + } else { + if (debug) { console.log('HTML5::loadStorage not supported on your browser' + html.length + ' characters'); } } } - if (debug) { console.log('Saving Track Position: songid:' + songid + ', albumid:' + albumid + ', position:' + position); } -} -function downloadItem(id, type) { - var url; - if (type == 'item' && id) { - reqDownload = 'id=' + id; + function deleteCurrentPlaylist() { + if (browserStorageCheck) { + localStorage.removeItem('CurrentPlaylist'); + setCookie('CurrentSong', null); + if (debug) { console.log('Removing Play Queue'); } + } else { + if (debug) { console.log('HTML5::loadStorage not supported on your browser' + html.length + ' characters'); } + } } - if (type == 'playlist' && id) { - reqDownload = 'playlistUtf8Hex=' + id; + function loadCurrentPlaylist() { + if (browserStorageCheck) { + var html = localStorage.getItem('CurrentPlaylist'); + if (html != '' && html !== undefined && html !== null) { + $('#CurrentPlaylistContainer tbody').html(html); + if (debug) { console.log('Load Play Queue From localStorage: ' + html.length + ' characters'); } + } + } else { + if (debug) { console.log('HTML5::loadStorage not supported on your browser' + html.length + ' characters'); } + } } - if (reqDownload) { - url = baseURL + '/download.view?v=' + apiVersion + '&c=' + applicationName + '&f=json&' + reqDownload; - window.location = url; + function saveTrackPosition() { + var el = $('#songdetails_song'); + var songid = el.attr('childid'); + if (songid !== undefined) { + var albumid = el.attr('parentid'); + var position = $("#playdeck").data("jPlayer").status.currentTime; + if (position != null && position >= 5) { + var currentSong = { + songid: songid, + albumid: albumid, + position: position + }; + $('#action_SaveProgress').show(); + setCookie('CurrentSong', JSON.stringify(currentSong)); + saveCurrentPlaylist(); + } + } + if (debug) { console.log('Saving Track Position: songid:' + songid + ', albumid:' + albumid + ', position:' + position); } + } + function downloadItem(id, type) { + var url; + if (type == 'item' && id) { + reqDownload = 'id=' + id; + } + if (type == 'playlist' && id) { + reqDownload = 'playlistUtf8Hex=' + id; + } + if (reqDownload) { + url = baseURL + '/download.view?' + baseParams + '&v=' + apiVersion + '&c=' + applicationName + '&' + reqDownload; + window.location = url; + } } -} -function loadPodcasts(refresh) { - if (debug) { console.log("LOAD PODCASTS"); } - if (refresh) { - $('#ChannelsContainer').empty(); + function loadPodcasts(refresh) { + if (debug) { console.log("LOAD PODCASTS"); } + if (refresh) { + $('#ChannelsContainer').empty(); + } + var content = $('#ChannelsContainer').html(); + if (content === "") { + // Load Podcasts + $.ajax({ + url: baseURL + '/getPodcasts.view?' + baseParams + '&v=' + apiVersion + '&c=' + applicationName, + method: 'GET', + dataType: protocol, + timeout: 10000, + success: function (data) { + var podcasts = []; + if (data["subsonic-response"].podcasts.channel !== undefined) { + if (data["subsonic-response"].podcasts.channel.length > 0) { + podcasts = data["subsonic-response"].podcasts.channel; + } else { + podcasts[0] = data["subsonic-response"].podcasts.channel; + } + $.each(podcasts, function (i, podcast) { + var albumId = (podcast.episode === undefined || podcast.episode.length <= 0) ? "0" : podcast.episode[0].parent; + + var html = ""; + html += '
  • '; + html += '
    '; + html += '
    '; + html += '
    '; + html += '
    ' + podcast.title + '
    '; + html += '
  • '; + $(html).appendTo("#ChannelsContainer"); + }); + if (smwidth) { + resizeSMSection(0); + } + } + } + }); + } } - var content = $('#ChannelsContainer').html(); - if (content === "") { - // Load Podcasts + function getPodcast(id, action, appendto) { $.ajax({ - url: baseURL + '/getPodcasts.view?v=' + apiVersion + '&c=' + applicationName + '&f=json', + url: baseURL + '/getPodcasts.view?' + baseParams + '&v=' + apiVersion + '&c=' + applicationName, method: 'GET', - dataType: 'json', + dataType: protocol, timeout: 10000, success: function (data) { var podcasts = []; - if (data["subsonic-response"].podcasts.channel !== undefined) { - if (data["subsonic-response"].podcasts.channel.length > 0) { - podcasts = data["subsonic-response"].podcasts.channel; - } else { - podcasts[0] = data["subsonic-response"].podcasts.channel; + if (data["subsonic-response"].podcasts.channel.length > 0) { + podcasts = data["subsonic-response"].podcasts.channel; + } else { + podcasts[0] = data["subsonic-response"].podcasts.channel; + } + var channel = []; + $.each(podcasts, function (i, podcast) { + if (podcast.id == id) { + channel = podcast; } - $.each(podcasts, function (i, podcast) { - var albumId = (podcast.episode === undefined || podcast.episode.length <= 0) ? "0" : podcast.episode[0].parent; + }); - var html = ""; - html += '
  • '; - html += '
    '; - html += '
    '; - html += '
    '; - html += '
    ' + podcast.title + '
    '; - html += '
  • '; - $(html).appendTo("#ChannelsContainer"); + if (channel.episode !== undefined) { + if (appendto === '#PodcastContainer tbody') { + $(appendto).empty(); + var header = generateSongHeaderHTML; + $("#PodcastContainer thead").html(header); + } + if (action === 'autoplay') { + $(appendto).empty(); + } + + var children = channel.episode; + + var rowcolor; + var html; + var count = 0; + $.each(children, function (i, child) { + if (child.status == "skipped") return; // Skip podcasts that are not yet downloaded + var date = parseDate(child.publishDate); + var description = 'Published: ' + date + '\n\n'; + description += child.description; + + var starred, duration, publishdate; + if (child.starred !== undefined) { starred = true; } else { starred = false; } + if (child.duration !== undefined) { duration = child.duration; } else { duration = ''; } + if (child.publishDate !== undefined) { publishdate = child.publishDate.substring(0, child.publishDate.indexOf(" ")); } else { publishdate = ''; } + html = generateSongHTML(child.streamId, child.parent, publishdate, child.title, description, child.artist, child.album, child.coverArt, child.userRating, starred, duration); + $(html).appendTo(appendto); + count++; }); - if (smwidth) { - resizeSMSection(0); + if (appendto === '#PodcastContainer tbody') { + updateStatus('#status_Podcasts', countCurrentPlaylist('#PodcastContainer')); + } + if (appendto === '#CurrentPlaylistContainer tbody') { + updateMessage(count + ' Song(s) Added', true); + } + if (action === 'autoplay') { + autoPlay(); + } + } else { + if (appendto === '#PodcastContainer tbody') { + $(appendto).empty(); } } } }); } -} -function getPodcast(id, action, appendto) { - $.ajax({ - url: baseURL + '/getPodcasts.view?v=' + apiVersion + '&c=' + applicationName + '&f=json', - method: 'GET', - dataType: 'json', - timeout: 10000, - success: function (data) { - var podcasts = []; - if (data["subsonic-response"].podcasts.channel.length > 0) { - podcasts = data["subsonic-response"].podcasts.channel; - } else { - podcasts[0] = data["subsonic-response"].podcasts.channel; - } - var channel = []; - $.each(podcasts, function (i, podcast) { - if (podcast.id == id) { - channel = podcast; + function loadVideos(refresh) { + if (debug) { console.log("LOAD VIDEOS"); } + if (refresh) { + $('#VideosContainer').empty(); + } + var content = $('#VideosContainer').html(); + if (content == "") { + // Load Videos + $.ajax({ + url: baseURL + '/getVideos.view?' + baseParams + '&v=' + apiVersion + '&c=' + applicationName, + method: 'GET', + dataType: protocol, + timeout: 10000, + success: function (data) { + if (data["subsonic-response"].videos != '') { + var videos = []; + if (data["subsonic-response"].videos.video.length > 0) { + videos = data["subsonic-response"].videos.video; + } else { + videos[0] = data["subsonic-response"].videos.video; + } + var rowcolor; + $.each(videos, function (i, video) { + var html; + if (i % 2 === 0) { + rowcolor = 'even'; + } else { + rowcolor = 'odd'; + } + var videoURL = baseURL + '/stream.view?' + baseParams + '&v=' + apiVersion + '&c=' + applicationName + '&id=' + video.id; + html = ''; + html += ''; + //html += ''; + //html += ''; + html += ''; + //html += ''; + html += ''; + html += ''; + html += '' + video.title + ''; + html += ''; + var coverartSrc; + if (video.coverArt === undefined) { + coverartSrc = 'images/albumdefault_25.jpg'; + } else { + coverartSrc = baseURL + '/getCoverArt.view?' + baseParams + '&v=' + apiVersion + '&c=' + applicationName + '&size=25&id=' + video.coverArt; + } + var time = secondsToTime(video.duration); + html += '' + video.album + ''; + html += '' + time + ''; + html += ''; + $(html).appendTo("#VideosContainer"); + }); + } } }); - - if (channel.episode !== undefined) { - if (appendto === '#PodcastContainer tbody') { - $(appendto).empty(); - var header = generateSongHeaderHTML; - $("#PodcastContainer thead").html(header); - } - if (action === 'autoplay') { - $(appendto).empty(); - } - - var children = channel.episode; - - var rowcolor; - var html; - var count = 0; - $.each(children, function (i, child) { - if (child.status == "skipped") return; // Skip podcasts that are not yet downloaded - var date = parseDate(child.publishDate); - var description = 'Published: ' + date + '\n\n'; - description += child.description; - - var starred, duration, publishdate; - if (child.starred !== undefined) { starred = true; } else { starred = false; } - if (child.duration !== undefined) { duration = child.duration; } else { duration = ''; } - if (child.publishDate !== undefined) { publishdate = child.publishDate.substring(0, child.publishDate.indexOf(" ")); } else { publishdate = ''; } - html = generateSongHTML(child.streamId, child.parent, publishdate, child.title, description, child.artist, child.album, child.coverArt, child.userRating, starred, duration); - $(html).appendTo(appendto); - count++; - }); - if (appendto === '#PodcastContainer tbody') { - updateStatus('#status_Podcasts', countCurrentPlaylist('#PodcastContainer')); - } - if (appendto === '#CurrentPlaylistContainer tbody') { - updateMessage(count + ' Song(s) Added', true); - } - if (action === 'autoplay') { - autoPlay(); - } - } else { - if (appendto === '#PodcastContainer tbody') { - $(appendto).empty(); - } - } } - }); -} -function loadVideos(refresh) { - if (debug) { console.log("LOAD VIDEOS"); } - if (refresh) { - $('#VideosContainer').empty(); - } - var content = $('#VideosContainer').html(); - if (content == "") { - // Load Videos - $.ajax({ - url: baseURL + '/getVideos.view?v=' + apiVersion + '&c=' + applicationName + '&f=json', - method: 'GET', - dataType: 'json', - timeout: 10000, - success: function (data) { - if (data["subsonic-response"].videos != '') { - var videos = []; - if (data["subsonic-response"].videos.video.length > 0) { - videos = data["subsonic-response"].videos.video; - } else { - videos[0] = data["subsonic-response"].videos.video; - } - var rowcolor; - $.each(videos, function (i, video) { - var html; - if (i % 2 === 0) { - rowcolor = 'even'; - } else { - rowcolor = 'odd'; - } - var videoURL = baseURL + '/stream.view?v=' + apiVersion + '&c=' + applicationName + '&id=' + video.id; - html = ''; - html += ''; - //html += ''; - //html += ''; - html += ''; - //html += ''; - html += ''; - html += ''; - html += '' + video.title + ''; - html += ''; - var coverartSrc; - if (video.coverArt === undefined) { - coverartSrc = 'images/albumdefault_25.jpg'; - } else { - coverartSrc = baseURL + '/getCoverArt.view?v=' + apiVersion + '&c=' + applicationName + '&f=json&size=25&id=' + video.coverArt; - } - var time = secondsToTime(video.duration); - html += '' + video.album + ''; - html += '' + time + ''; - html += ''; - $(html).appendTo("#VideosContainer"); - }); - } - } - }); - } -} - + } \ No newline at end of file diff --git a/js/libs/chat.js b/js/libs/chat.js index f5b59e2..5128e55 100644 --- a/js/libs/chat.js +++ b/js/libs/chat.js @@ -4,9 +4,9 @@ function updateChatMessages() { updater = $.periodic({ period: 1000, decay: 1.5, max_period: 1800000 }, function () { $.ajax({ periodic: this, - url: baseURL + '/getChatMessages.view?v=' + apiVersion + '&c=' + applicationName + '&f=json&since=' + starttime, + url: baseURL + '/getChatMessages.view?' + baseParams + '&v=' + apiVersion + '&c=' + applicationName + '&since=' + starttime, method: 'GET', - dataType: 'json', + dataType: protocol, timeout: 10000, success: function (data) { if (data["subsonic-response"].chatMessages.chatMessage === undefined) { @@ -49,10 +49,10 @@ function stopUpdateChatMessages() { function addChatMessage(msg) { $.ajax({ type: 'GET', - url: baseURL + '/addChatMessage.view', - dataType: 'json', + url: baseURL + '/addChatMessage.view?' + baseParams, + dataType: protocol, timeout: 10000, - data: { v: apiVersion, c: applicationName, f: "json", message: msg }, + data: { v: apiVersion, c: applicationName, message: msg }, success: function () { updater.reset(); }, diff --git a/js/libs/generators.js b/js/libs/generators.js index af93c88..814b6e8 100755 --- a/js/libs/generators.js +++ b/js/libs/generators.js @@ -33,7 +33,7 @@ function generateAlbumHTML(childid, parentid, coverart, title, artist, rating, s if (coverart == undefined) { html += ''; } else { - html += ''; + html += ''; } html += '' + title + ''; html += '' + artist + ''; @@ -77,7 +77,7 @@ function generateSongHTML(childid, parentid, track, title, description, artist, if (coverart == undefined) { coverartSrc = 'images/albumdefault_25.jpg'; } else { - coverartSrc = baseURL + '/getCoverArt.view?v=' + apiVersion + '&c=' + applicationName + '&f=json&size=25&id=' + coverart; + coverartSrc = baseURL + '/getCoverArt.view?' + baseParams + '&v=' + apiVersion + '&c=' + applicationName + '&size=25&id=' + coverart; } html += '' + album + ''; html += '' + time + ''; diff --git a/js/libs/player.js b/js/libs/player.js index d716c28..ee14cf3 100644 --- a/js/libs/player.js +++ b/js/libs/player.js @@ -5,16 +5,16 @@ function getSongData(el, songid, albumid, position, loadonly) { var minimumVersion = parseVersionString('1.8.0'); if (checkVersion(runningVersion, minimumVersion)) { if (debug) { console.log('apiVersion at or above 1.8.0 using getSong.view'); } - ajaxUrl = baseURL + '/getSong.view?v=' + apiVersion + '&c=' + applicationName + '&f=json&id=' + songid; + ajaxUrl = baseURL + '/getSong.view?' + baseParams + '&v=' + apiVersion + '&c=' + applicationName + '&id=' + songid; } else { if (debug) { console.log('apiVersion below 1.8.0 using getMusicDirectory.view'); } - ajaxUrl = baseURL + '/getMusicDirectory.view?v=' + apiVersion + '&c=' + applicationName + '&f=json&id=' + albumid; // Deprecated: apiVersion 1.8.0 + ajaxUrl = baseURL + '/getMusicDirectory.view?' + baseParams + '&v=' + apiVersion + '&c=' + applicationName + '&id=' + albumid; // Deprecated: apiVersion 1.8.0 } if (debug) { console.log(ajaxUrl) } $.ajax({ url: ajaxUrl, method: 'GET', - dataType: 'json', + dataType: protocol, timeout: 10000, success: function (data) { var title, artist, album, rating, starred, contenttype, suffix; @@ -36,7 +36,6 @@ function getSongData(el, songid, albumid, position, loadonly) { } if (typeof data["subsonic-response"].directory != 'undefined') { // Deprecated: apiVersion 1.8.0 if (typeof data["subsonic-response"].directory.child != '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; @@ -87,8 +86,8 @@ function playSong(el, songid, albumid, title, artist, album, coverart, rating, s coverartSrc = 'images/albumdefault_60.jpg'; coverartFullSrc = ''; } else { - coverartSrc = baseURL + '/getCoverArt.view?v=' + apiVersion + '&c=' + applicationName + '&f=json&size=60&id=' + coverart; - coverartFullSrc = baseURL + '/getCoverArt.view?v=' + apiVersion + '&c=' + applicationName + '&f=json&id=' + coverart; + coverartSrc = baseURL + '/getCoverArt.view?' + baseParams + '&v=' + apiVersion + '&c=' + applicationName + '&size=60&id=' + coverart; + coverartFullSrc = baseURL + '/getCoverArt.view?' + baseParams + '&v=' + apiVersion + '&c=' + applicationName + '&id=' + coverart; } $('#coverartimage').attr('href', coverartFullSrc); $('#coverartimage img').attr('src', coverartSrc); @@ -125,11 +124,11 @@ function playSong(el, songid, albumid, title, artist, album, coverart, rating, s ready: function () { if (suffix == 'oga') { $(this).jPlayer("setMedia", { - oga: baseURL + '/stream.view?v=' + apiVersion + '&c=' + applicationName + '&id=' + songid + '&salt=' + salt, + oga: baseURL + '/stream.view?' + baseParams + '&v=' + apiVersion + '&c=' + applicationName + '&id=' + songid + '&salt=' + salt, }); } else if (suffix == 'mp3') { $(this).jPlayer("setMedia", { - mp3: baseURL + '/stream.view?v=' + apiVersion + '&c=' + applicationName + '&id=' + songid + '&salt=' + salt, + mp3: baseURL + '/stream.view?' + baseParams + '&v=' + apiVersion + '&c=' + applicationName + '&id=' + songid + '&salt=' + salt, }); } if (!loadonly) { @@ -181,11 +180,11 @@ function playSong(el, songid, albumid, title, artist, album, coverart, rating, s for (i = 0; i < data.solutions.length; i++) { var solution = data.solutions[i]; if (data[solution].used) { - spechtml += "" + solution + " is"; + spechtml += "" + solution + " is"; spechtml += " currently being used with"; for (format in data[solution].support) { if (data[solution].support[format]) { - spechtml += " " + format; + spechtml += " " + format + ""; } } spechtml += " support"; @@ -199,7 +198,7 @@ function playSong(el, songid, albumid, title, artist, album, coverart, rating, s scrobbleSong(false); scrobbled = false; - if (getCookie('Notification_Song')) { + if (getCookie('Notification_Song') && !loadonly) { showNotification(coverartSrc, toHTML.un(title), toHTML.un(artist + ' - ' + album), 'text', '#NextTrack'); } if (getCookie('ScrollTitle')) { @@ -242,9 +241,9 @@ function playVideo(id, bitrate) { function scrobbleSong(submission) { var songid = $('#songdetails_song').attr('childid'); $.ajax({ - url: baseURL + '/scrobble.view?v=' + apiVersion + '&c=' + applicationName + '&f=json&id=' + songid + "&submission=" + submission, + url: baseURL + '/scrobble.view?' + baseParams + '&v=' + apiVersion + '&c=' + applicationName + '&id=' + songid + "&submission=" + submission, method: 'GET', - dataType: 'json', + dataType: protocol, timeout: 10000, success: function () { if (submission) { @@ -255,9 +254,9 @@ function scrobbleSong(submission) { } function rateSong(songid, rating) { $.ajax({ - url: baseURL + '/setRating.view?v=' + apiVersion + '&c=' + applicationName + '&f=json&id=' + songid + "&rating=" + rating, + url: baseURL + '/setRating.view?' + baseParams + '&v=' + apiVersion + '&c=' + applicationName + '&id=' + songid + "&rating=" + rating, method: 'GET', - dataType: 'json', + dataType: protocol, timeout: 10000, success: function () { updateMessage('Rating Updated!', true); @@ -268,14 +267,14 @@ function starItem(itemid, starred) { var url; if (itemid !== undefined) { if (starred) { - url = baseURL + '/star.view?v=' + apiVersion + '&c=' + applicationName + '&f=json&id=' + itemid; + url = baseURL + '/star.view?' + baseParams + '&v=' + apiVersion + '&c=' + applicationName + '&id=' + itemid; } else { - url = baseURL + '/unstar.view?v=' + apiVersion + '&c=' + applicationName + '&f=json&id=' + itemid; + url = baseURL + '/unstar.view?' + baseParams + '&v=' + apiVersion + '&c=' + applicationName + '&id=' + itemid; } $.ajax({ url: url, method: 'GET', - dataType: 'json', + dataType: protocol, timeout: 10000, success: function () { updateMessage('Favorite Updated!', true); diff --git a/js/libs/utils.js b/js/libs/utils.js index 6b900d4..335f277 100644 --- a/js/libs/utils.js +++ b/js/libs/utils.js @@ -1,3 +1,36 @@ + +function getCookie(value) { + if ($.cookie(value)) { + return $.cookie(value); + } else { + return false; + } + /* jQuery.cookies.js + if (browserStorageCheck) { + var item = localStorage.getItem(value); + if (item != '' && item != undefined) { + return true; + } else { + return false; + } + } else { + if (debug) { console.log('HTML5::loadStorage not supported on your browser' + html.length + ' characters'); } + } + */ +} +function setCookie(key, value) { + $.cookie(key, value, { expires: 365 }); + /* jQuery.cookies.js + try { + if (debug) { console.log('Saving : ' + key + ':' + value); } + localStorage.setItem(key, value); + } catch (e) { + if (e == QUOTA_EXCEEDED_ERR) { + alert('Quota exceeded!'); + } + } + */ +} /* Reusable Functions */ function clickButton(el) { var el = $(el); diff --git a/js/ui-ready.js b/js/ui-ready.js index c739937..d250968 100755 --- a/js/ui-ready.js +++ b/js/ui-ready.js @@ -1,5 +1,14 @@ $(document).ready(function () { - //User config staff + // Inject Basic Auth + /* + $.ajaxSetup({ + beforeSend: function (req) { + req.setRequestHeader('Authorization', auth); + } + //headers: { "Authorization": "Basic " + auth } + }); + */ + // Fill Preferences from Cookies if (getCookie('username')) { $('#Username').val(getCookie('username')); } //$('#Password').val(getCookie('passwordenc')); if (getCookie('AutoPlaylists')) { $('#AutoPlaylists').val(getCookie('AutoPlaylists')); } @@ -8,6 +17,10 @@ if (getCookie('Server')) { $('#Server').val(getCookie('Server')); } if (getCookie('ApplicationName')) { $('#ApplicationName').val(getCookie('ApplicationName')); } + if (getCookie('Server')) { + baseURL = getCookie('Server') + '/rest'; + } + // Set Preferences defaults if (getCookie('Theme')) { $('#Theme').val(getCookie('Theme')); @@ -45,6 +58,11 @@ } else { $('#ForceFlash').attr('checked', false); } + if (getCookie('Protocol')) { + $('#Protocol').attr('checked', true); + } else { + $('#Protocol').attr('checked', false); + } if (getCookie('AutoPilot')) { setCookie('AutoPilot', null) } @@ -69,6 +87,61 @@ return false; }); + function loadTabContent(tab) { + var tabid = '#action_' + tab.substring(1, tab.length); + $("ul.tabs li a").removeClass("active"); //Remove any "active" class + $(tabid).addClass("active"); //Add "active" class to selected tab + $(".tabcontent").hide(); //Hide all tab content + window.location.hash = tab; + switch (tab) { + case '#tabLibrary': + if (debug) { console.log("TAG LIBRARY"); } + if (getCookie('MusicFolders')) { + loadArtists(getCookie('MusicFolders'), false); + } else { + loadArtists(); + } + getMusicFolders(); + break; + case '#tabQueue': + if (debug) { console.log("TAG QUEUE"); } + var header = generateSongHeaderHTML(); + $('#CurrentPlaylistContainer thead').html(header); + var count = $('#CurrentPlaylistContainer tbody tr.song').size(); + updateStatus('#status_Current', countCurrentPlaylist('#CurrentPlaylistContainer')); + if (count > 0) { + $('#currentActions a.button').removeClass('disabled'); + } + var songid = $('#CurrentPlaylistContainer tbody tr.playing').attr('childid'); + if (songid !== undefined) { + $('#CurrentPlaylist').scrollTo($('#' + songid), 400); + } + break; + case '#tabPlaylists': + if (debug) { console.log("TAG PLAYLIST"); } + loadPlaylists(); + loadFolders(); + loadAutoPlaylists(); + updateStatus('#status_Playlists', countCurrentPlaylist('#TrackContainer')); + break; + case '#tabPodcasts': + if (debug) { console.log("TAG PODCAST"); } + loadPodcasts(); + updateStatus('#status_Podcasts', countCurrentPlaylist('#PodcastContainer')); + break; + case '#tabVideos': + if (debug) { console.log("TAG VIDEOS"); } + loadVideos(true); + break; + case '#tabPreferences': + getGenres(); + break; + default: + break; + } + $(tab).fadeIn('fast'); //Fade in the active ID content + } + // Tabs $('.tabcontent').hide(); //Hide all content if (!getCookie('username') && !getCookie('passwordenc') && !getCookie('Server')) { // Show Preferences @@ -913,7 +986,8 @@ if (applicationname != "") { setCookie('ApplicationName', applicationname); } - location.reload(true); + updateMessage('Preferences Saved...', true); + //location.reload(true); }); $('#Theme').live('change', function () { var theme = $(this).val(); @@ -988,7 +1062,15 @@ } else { setCookie('ForceFlash', null); } - location.reload(true); + //location.reload(true); + }); + $('#Protocol').live('click', function () { + if ($('#Protocol').is(':checked')) { + setCookie('Protocol', '1'); + } else { + setCookie('Protocol', null); + } + //location.reload(true); }); $('#SaveTrackPosition').live('click', function () { if ($('#SaveTrackPosition').is(':checked')) { @@ -1018,7 +1100,7 @@ setCookie('Server', null); setCookie('ApplicationName', null); setCookie('HideAZ', null); - location.reload(true); + //location.reload(true); }); $('#ChangeLogShowMore').live('click', function () { $('ul#ChangeLog li.log').each(function (i, el) { diff --git a/manifest.json b/manifest.json index 68e67ef..bcfafd8 100644 --- a/manifest.json +++ b/manifest.json @@ -2,7 +2,7 @@ "manifest_version": 2, "name": "MiniSub", "description": "MiniSub - HTML5 Mini Player for Subsonic", - "version": "2.3.5", + "version": "2.3.6", "app": { "launch": { "local_path": "index.html" diff --git a/style/Dark.css b/style/Dark.css index bcb0f7b..a29ee4b 100644 --- a/style/Dark.css +++ b/style/Dark.css @@ -309,6 +309,10 @@ fieldset { border: 1px solid #1d1d1d; } +label +{ + color: #D6D469; +} #donate { background: #232323; border: 1px solid #1D1D1D; diff --git a/style/Style.css b/style/Style.css index 22b29a3..144f0aa 100755 --- a/style/Style.css +++ b/style/Style.css @@ -15,7 +15,7 @@ img h3.title { font-weight: bold; - font-size: 14px; + font-size: 16px; font-variant: small-caps; padding: 0; margin: 5px 0; @@ -48,6 +48,7 @@ span.apiversion .even { background: #f4f4f4; } */ .red { color: #E64F4C; } +.codesyntax { font-family: "Courier New"; } .italic { font-style: italic; } .beer { font-size: 17px; } @@ -1365,6 +1366,7 @@ select#MusicFolders label { font-size: 12px; + font-weight: bold; margin: 0 5px; } .inputwrap