var playlistManager = function() { var pmg = null; var holders = new Array(); function putTracks(holder, tracks, title) { var html = ''; html += ' 0 && tracks[0].plimage != "") { debug.log("PLAYLISTMANAGER",title,"has a background image of",tracks[0].plimage); html += ' image-content="'+tracks[0].plimage+'"'; } var t = decodeURIComponent(title); html += '>'+''; if (!t.match(/ \(by /)) { html += ''+ ''; } html += ''; if (tracks.length == 0) { // Add a blank entry so we've got something to drop onto. Also the dropping doesn't work // without at least one sortable in the target. html += ''; } else { for (var i in tracks) { if (tracks[i].Type == 'stream') { html += ''; } else { html += ''; } html += ''; } else { html += '" />'; } if (!t.match(/ \(by /)) { html += ''; } html += ''; } } html += '
'+t+'
'+tracks[i].Album+''; if (tracks[i].Album == rompr_unknown_stream) { html += '
'+tracks[i].Uri; } html += '
'+tracks[i].Title+''; if (tracks[i].Artist && tracks[i].Artist != 'Spotify' && tracks[i].Artist != 'spotify') { html += '
by '+tracks[i].Artist+''; } if (tracks[i].Album) { html += '
on '+tracks[i].Album+''; } html += '
'; holder.html(html); } function reloadPlaylist(list) { $.ajax({ url: 'plugins/code/playlistmanager.php', type: "POST", data: {action: 'getlist'}, dataType: 'json' }) .done(function(data) { putTracks(holders[list], data[list], list); browser.rePoint(); infobar.markCurrentTrack(); }) .fail(function() { infobar.error(language.gettext('label_general_error')); }); } function getAllPlaylists() { $.ajax({ url: 'plugins/code/playlistmanager.php', type: "POST", data: {action: 'getlist'}, dataType: 'json' }) .done(playlistManager.doMainLayout) .fail(function() { infobar.error(language.gettext('label_general_error')); pmg.slideToggle('fast'); }); } return { open: function() { if (pmg == null) { pmg = browser.registerExtraPlugin("pmg", language.gettext("label_playlistmanager"), playlistManager, 'https://fatg3erman.github.io/RompR/Using-Saved-Playlists#editing-your-saved-playlists'); if (layoutProcessor.supportsDragDrop) { $("#pmgfoldup").append('
'+ '
'+language.gettext("label_playlistmanagertop")+'
'+ '
'); } $("#pmgfoldup").append('
'+ '
'+ ''+ '
'+ ''+ '
'); $("#pmgfoldup").append('
'); getAllPlaylists(); // $('#pmgfoldup .enter').on('keyup', onKeyUp); } else { browser.goToPlugin("pmg"); } }, doMainLayout: function(data) { debug.log("PLAYLISTMANAGER","Got data",data); for (var i in data) { debug.log("PLAYLISTMANAGER",i); holders[i] = $('
', {class: 'tagholder selecotron noselection'}).appendTo($("#playmunger")); putTracks(holders[i], data[i], i); holders[i].sortableTrackList({ items: '.sortable', outsidedrop: playlistManager.dropped, insidedrop: playlistManager.dragstopped, scroll: false, allowdragout: true // scrollparent: '#infopane', // scrollspeed: 80, // scrollzone: 20 }); holders[i].acceptDroppedTracks({ scroll: true, scrollparent: '#infopane' }); } pmg.slideToggle('fast', function() { cement = true; browser.goToPlugin("pmg"); browser.rePoint($("#playmunger"), {itemSelector: '.tagholder', percentPosition: true }); infobar.markCurrentTrack(); pmg.imagesLoaded(browser.rePoint); }); }, handleClick: function(element, event) { if (element.hasClass('clickremplay')) { var list = element.parent().parent().parent().parent().parent().children('input').first().val(); var pos = element.attr('name'); element.makeSpinner(); debug.log("PLAYLISTMANAGER","Removing Track",pos,"from playlist",list); player.controller.deletePlaylistTrack(list,pos, function() { player.controller.reloadPlaylists(); reloadPlaylist(list); }); } else if (element.hasClass('clickdelplaylist')) { var list = element.parent().parent().parent().parent().prev().val(); var holder = element.parent().parent().parent().parent().parent(); debug.log("PLAYLISTMANAGER","Deleting Playlist",list); player.controller.deletePlaylist(list,function() { player.controller.reloadPlaylists(); holder.fadeOut('fast', function() { $("#playmunger").masonry('remove',holder); browser.rePoint(); }); }); } else if (element.hasClass('clickrenplaylist')) { var list = unescapeHtml(element.parent().parent().parent().parent().prev().val()); player.controller.renamePlaylist(list, event, player.controller.doRenamePlaylist); } else if (element.hasClass('clickfoldupplaylist')) { element.parent().parent().parent().children('tr.sortable').slideToggle('fast'); } }, checkToUpdateTheThing: function(list) { // Callback to handle case where track is removed from a playlist via the playlists list if (pmg !== null) { reloadPlaylist(list); } }, dropped: function(event, ui) { event.stopImmediatePropagation(); var tracks = new Array(); var which_playlist = ui.parent().parent().parent().children('input').first().val(); $.each($('.selected').filter(removeOpenItems), function (index, element) { if ($(element).hasClass('directory')) { var uri = decodeURIComponent($(element).children('input').first().attr('name')); debug.log("PLAYLISTMANAGER","Dragged Directory",uri,"to",which_playlist); tracks.push({dir: uri}); } else if (element.hasAttribute('romprid')) { var playlistinfo = playlist.getId($(element).attr('romprid')); tracks.push({uri: playlistinfo.file}); } else { var uri = decodeURIComponent($(element).attr("name")); debug.log("PLAYLISTMANAGER","Dragged",uri,"to",which_playlist); tracks.push({uri: uri}); } }); $('.selected').removeClass('selected'); var moveto = null; var playlistlength = 0; var next = ui.next('.sortable').attr('romprpos'); if (next && next != 'playmanitem_null') { debug.log("PLAYLISTMANAGER","Next Item Is",next); next = next.replace(/playmanitem_/, ''); moveto = next; playlistlength = ui.parent().children('.sortable').last().attr('romprpos'); if (playlistlength && playlistlength != 'playmanitem_null') { playlistlength = parseInt(playlistlength.replace(/playmanitem_/,'')); playlistlength += 1; } } if (tracks.length > 0) { debug.log("PLAYLISTMANAGER","Dragged to position",moveto); player.controller.addTracksToPlaylist(which_playlist,tracks,moveto,playlistlength,function() { player.controller.reloadPlaylists(); player.controller.checkProgress(); reloadPlaylist(which_playlist); }); } }, close: function() { pmg = null; holders = []; cement = false; }, reloadAll: function() { if (pmg) { $("#playmunger").masonry('destroy'); $("#playmunger").empty(); holders = []; pmg.hide(); getAllPlaylists(); } }, dragstopped: function(event, ui) { event.stopImmediatePropagation(); var playlist = ui.parent().parent().parent().children('input').val(); var item = ui.attr('romprpos'); item = item.replace(/playmanitem_/,''); var next = ui.next().attr('romprpos'); if (typeof next == "undefined") { next = ui.prev().attr('romprpos'); } next = next.replace(/playmanitem_/,''); if (next == 'null') next = 0; debug.log("PLAYLISTMANAGER","Dragged item",item,"to position",next,"within playlist",playlist); // Oooh it's daft but the position we have to send is the position AFTER the track has been // taken out of the list but before it's been put back in. if (next > item) next--; player.controller.movePlaylistTracks(playlist,item,next,function() { reloadPlaylist(playlist); player.controller.checkProgress(); player.controller.reloadPlaylists(); }); }, createPlaylist: function() { // We don't need to actually create the playlist at the mpd end because // mpd will create it automatically if we add a track to it. And what's the point // of an empty playlist? var n = $('[name=newplaylistnameinput]').val(); if (n == '') { return false; } var playlist = rawurlencode(n); holders[playlist] = $('
', {class: 'tagholder selecotron noselection'}).prependTo($("#playmunger")); putTracks(holders[playlist],[],playlist); holders[playlist].acceptDroppedTracks({ scroll: true, scrollparent: '#infopane' }); holders[playlist].sortableTrackList({ items: '.sortable', outsidedrop: playlistManager.dropped, insidedrop: playlistManager.dragstopped, scroll: true, allowdragout: true, scrollparent: '#infopane', scrollspeed: 80, scrollzone: 40 }); $("#playmunger").masonry('prepended', holders[playlist]); browser.rePoint(); } } }(); pluginManager.setAction(language.gettext("label_playlistmanager"), playlistManager.open); playlistManager.open();