diff --git a/server/public/assets/css/style.css b/server/public/assets/css/style.css index a7b3e8f1..4886e031 100755 --- a/server/public/assets/css/style.css +++ b/server/public/assets/css/style.css @@ -2036,7 +2036,7 @@ nav ul li:hover, nav ul li.active { transition: all .1s ease; } -.vote-container{ +.vote-container, .deleted-vote-container{ height: 100%; width: 90%; } @@ -2766,6 +2766,11 @@ nav ul li:hover, nav ul li.active { border: none; } +.disabled-vote{ + cursor: not-allowed !important; + background: rgba(255,255,255,.2); +} + .hide { display:none !important; diff --git a/server/public/assets/js/channel.js b/server/public/assets/js/channel.js index 72938431..50c3f6cf 100644 --- a/server/public/assets/js/channel.js +++ b/server/public/assets/js/channel.js @@ -34,10 +34,10 @@ var Channel = { if(cast_ready_connect || chromecastAvailable || chromecastReady) { Helper.addClass(".volume-container", "volume-container-cast"); } - if(!embed) { - document.querySelector("#main-container").insertAdjacentHTML("beforeend", "keyboard_arrow_right"); - document.querySelector("#hide-playlist").style.left = (document.querySelector("#video-container").offsetWidth - document.querySelector("#hide-playlist").offsetWidth) + "px"; - } + if(!embed) { + document.querySelector("#main-container").insertAdjacentHTML("beforeend", "keyboard_arrow_right"); + document.querySelector("#hide-playlist").style.left = (document.querySelector("#video-container").offsetWidth - document.querySelector("#hide-playlist").offsetWidth) + "px"; + } //Player.soundcloud_player = document.querySelector("#soundcloud_player"); } List.calculate_song_heights(); @@ -117,9 +117,6 @@ var Channel = { draggable: Helper.mobilecheck(), onOpenStart: function(el) { Helper.addClass(".hamburger-sidenav", "open"); - try { - M.Collapsible.getInstance(document.querySelector(".settings-collapsible")).open(1); - } catch(e) {} }, onCloseStart: function(el) { Helper.removeClass(".hamburger-sidenav", "open"); @@ -182,6 +179,7 @@ var Channel = { } if(!Helper.mobilecheck() && (document.querySelectorAll("#alreadychannel").length === 0 || !Hostcontroller.old_id || document.getElementById("code-text").innerText.toUpperCase() == "ABBADUR")) setup_host_initialization(); setup_suggested_listener(); + if(!Helper.mobilecheck()) Helper.removeClass(".intelligent-accordion", "hide-on-small-only"); if(document.querySelectorAll("#alreadychannel").length === 0 || Helper.mobilecheck()){ setup_now_playing_listener(); get_list_listener(); diff --git a/server/public/assets/js/crypt.js b/server/public/assets/js/crypt.js index 5c427a4c..9805e47d 100755 --- a/server/public/assets/js/crypt.js +++ b/server/public/assets/js/crypt.js @@ -20,13 +20,29 @@ var Crypt = { } catch(err) { conf_arr = Crypt.decrypt(Crypt.create_cookie("_opt"), "_opt"); } - + if(window.location.pathname != "/") { + change_intelligent(Crypt.get_intelligent_list_enabled()); Hostcontroller.change_enabled(conf_arr.remote); if(conf_arr.width != 100) Player.set_width(conf_arr.width); } }, + get_intelligent_list_enabled: function() { + if(conf_arr.hasOwnProperty("intelligent")) { + return conf_arr.intelligent; + } else { + conf_arr.intelligent = false; + Crypt.encrypt(conf_arr, "_opt"); + return false; + } + }, + + set_intelligent_list_enabled: function(enabled) { + conf_arr.intelligent = enabled; + Crypt.encrypt(conf_arr, "_opt"); + }, + decrypt: function(cookie, name) { if(Crypt.getCookie(name) === undefined) { cookie = Crypt.create_cookie(name); diff --git a/server/public/assets/js/embed.js b/server/public/assets/js/embed.js index 7d150890..740732cd 100755 --- a/server/public/assets/js/embed.js +++ b/server/public/assets/js/embed.js @@ -3,6 +3,7 @@ var timed_remove_check; var gotten_np = false; var song_title = ""; var paused = false; +var intelligentList = false; var client = false; var _VERSION; try { @@ -19,6 +20,8 @@ if(window.location.hostname == "localhost" || window.location.hostname == "clien } var SC_player; var durationTimeout; +var intelligentQueue = []; +var deleted_elements = 0; var sc_need_initialization = true; var sc_initialized = false; var startTime = 0; diff --git a/server/public/assets/js/functions.js b/server/public/assets/js/functions.js index c94e41f3..f0aa3031 100644 --- a/server/public/assets/js/functions.js +++ b/server/public/assets/js/functions.js @@ -611,6 +611,44 @@ function loadChromecastVideo() { }); } +function enable_intelligent_list() { + if(Crypt.get_intelligent_list_enabled()) { + intelligentList = true; + } +} + +function change_intelligent(enabled) { + document.querySelector(".intelligent_switch_class").checked = enabled; +} + +function clearIntelligentQueue() { + intelligentList = false; + for(var i = 0; i < intelligentQueue.length; i++) { + var currentElement = intelligentQueue[i]; + if(currentElement.type == "vote") { + Helper.removeElement("#"+currentElement.element.id); + List.insertAtIndex(currentElement.element, false); + } else if(currentElement.type == "delete") { + List.deleted_song(currentElement.element.id, false, true, currentElement.index); + deleted_elements += 1; + } else if(currentElement.type == "add") { + List.insertAtIndex(currentElement.element, true); + Helper.css(document.querySelector("#wrapper").children[List.page + List.can_fit], "display", "none"); + if(document.querySelector("#wrapper").children.length > List.page + List.can_fit){ + Helper.css(".next_page_hide", "display", "none"); + Helper.removeClass(".next_page", "hide"); + Helper.css(".last_page_hide", "display", "none"); + Helper.css(".next_page", "display", "inline-flex"); + Helper.css(".last_page", "display", "inline-flex"); + } else { + Helper.css(".next_page_hide", "display", "inline-flex"); + Helper.css(".next_page", "display", "none"); + } + } + } + intelligentQueue = []; +} + function updateChromecastMetadata() { if(!chromecastAvailable) return; var image = {url:'https://img.youtube.com/vi/'+video_id+'/mqdefault.jpg', heigth: 180, width: 320}; diff --git a/server/public/assets/js/hostcontroller.js b/server/public/assets/js/hostcontroller.js index e53ba090..c3d20749 100755 --- a/server/public/assets/js/hostcontroller.js +++ b/server/public/assets/js/hostcontroller.js @@ -35,7 +35,7 @@ var Hostcontroller = { host_on_action: function(arr) { if(client) return; - if(enabled){ + if(Hostcontroller.enabled){ if(arr.type == "volume") { try { Playercontrols.visualVolume(arr.value); @@ -75,9 +75,9 @@ var Hostcontroller = { change_enabled:function(val){ if(client) return; - enabled = val; + Hostcontroller.enabled = val; try { - document.querySelector(".remote_switch_class").checked = enabled; + document.querySelector(".remote_switch_class").checked = Hostcontroller.enabled; }catch(e) {} } }; diff --git a/server/public/assets/js/list.js b/server/public/assets/js/list.js index 552c7b26..2d5a3831 100755 --- a/server/public/assets/js/list.js +++ b/server/public/assets/js/list.js @@ -121,8 +121,9 @@ var List = { insertAtIndex: function(song_info, transition, change) { if(document.querySelector("#wrapper") == null) return; var i = List.getIndexOfSong(song_info.id); - var display = "none"; + if(i == -1) return; if(!song_info.now_playing){ + var display = "none"; if(i >= List.page && i < List.page + (List.can_fit)) display = "inline-flex" var add = List.generateSong(song_info, transition, false, true, false, display, false); if(i === 0) { @@ -397,79 +398,105 @@ var List = { if(document.querySelectorAll("#empty-channel-message").length > 0) { document.querySelector("#empty-channel-message").remove(); } - List.insertAtIndex(added, true); - Helper.css(document.querySelector("#wrapper").children[List.page + List.can_fit], "display", "none"); - if(document.querySelector("#wrapper").children.length > List.page + List.can_fit){ - Helper.css(".next_page_hide", "display", "none"); - Helper.removeClass(".next_page", "hide"); - Helper.css(".last_page_hide", "display", "none"); - Helper.css(".next_page", "display", "inline-flex"); - Helper.css(".last_page", "display", "inline-flex"); + if(intelligentList) { + intelligentQueue.push({ + type: "add", + element: added, + }); } else { - Helper.css(".next_page_hide", "display", "inline-flex"); - Helper.css(".next_page", "display", "none"); + List.insertAtIndex(added, true); + Helper.css(document.querySelector("#wrapper").children[List.page + List.can_fit], "display", "none"); + if(document.querySelector("#wrapper").children.length > List.page + List.can_fit){ + Helper.css(".next_page_hide", "display", "none"); + Helper.removeClass(".next_page", "hide"); + Helper.css(".last_page_hide", "display", "none"); + Helper.css(".next_page", "display", "inline-flex"); + Helper.css(".last_page", "display", "inline-flex"); + } else { + Helper.css(".next_page_hide", "display", "inline-flex"); + Helper.css(".next_page", "display", "none"); + } } } }, - deleted_song: function(deleted, removed) { + deleted_song: function(deleted, removed, intelligentSecond, deleted_index) { try{ var index = List.getIndexOfSong(deleted); - //if(!removed) to_delete.style.height = 0; - var nextToChange; - if(index < List.page && document.querySelector("#wrapper").children.length - (List.page + 2) >= 0){ - //Helper.css(document.querySelector("#wrapper").children[List.page], "height", 0 + "px"); - nextToChange = document.querySelector("#wrapper").children[List.page]; - //Helper.css(document.querySelector("#wrapper").children[List.page], "display", "inline-flex"); - //Helper.css(document.querySelector("#wrapper").children[List.page], "height", List.element_height + "px"); - } else if(document.querySelector("#wrapper").children.length > List.page + (List.can_fit)){ - //Helper.css(document.querySelector("#wrapper").children[List.page + (List.can_fit)], "height", 0 + "px"); - nextToChange = document.querySelector("#wrapper").children[List.page + (List.can_fit)]; - //Helper.css(document.querySelector("#wrapper").children[List.page + (List.can_fit)], "display", "inline-flex"); - //Helper.css(document.querySelector("#wrapper").children[List.page + (List.can_fit)], "height", List.element_height + "px"); - } - if(List.page >= document.querySelector("#wrapper").children.length - 1){ - List.dynamicContentPage(-1); - Helper.css(".next_page_hide", "display", "inline-flex"); - Helper.css(".next_page", "display", "none"); - Helper.css(".last_page_hide", "display", "inline-flex"); - Helper.css(".last_page", "display", "none"); - } else if(List.page + List.can_fit + 1 >= document.querySelector("#wrapper").children.length - 1){ - Helper.css(".next_page_hide", "display", "inline-flex"); - Helper.css(".next_page", "display", "none"); - Helper.css(".last_page_hide", "display", "inline-flex"); - Helper.css(".last_page", "display", "none"); - } + if(intelligentList && !intelligentSecond) { + intelligentQueue.push({ + type: "delete", + element: full_playlist[index], + index: index, + }); + if(index != -1) full_playlist.splice(index, 1); + var this_element = document.getElementById(deleted); + Helper.addClass(this_element, "disabled-vote"); + this_element.querySelector(".vote-span").innerText = "Deleted"; + Helper.addClass(this_element.querySelector(".vote-container"), "deleted-vote-container"); + Helper.removeClass(this_element.querySelector(".vote-container"), "clickable"); + Helper.removeClass(this_element.querySelector(".vote-container"), "vote-container"); + return; + } else { + //if(!removed) to_delete.style.height = 0; + var nextToChange; + if(index == -1) index = deleted_index; + if(index < List.page && document.querySelector("#wrapper").children.length - (List.page + 2) >= 0){ + //Helper.css(document.querySelector("#wrapper").children[List.page], "height", 0 + "px"); + nextToChange = document.querySelector("#wrapper").children[List.page]; + //Helper.css(document.querySelector("#wrapper").children[List.page], "display", "inline-flex"); + //Helper.css(document.querySelector("#wrapper").children[List.page], "height", List.element_height + "px"); + } else if(document.querySelector("#wrapper").children.length > List.page + (List.can_fit)){ + //Helper.css(document.querySelector("#wrapper").children[List.page + (List.can_fit)], "height", 0 + "px"); + nextToChange = document.querySelector("#wrapper").children[List.page + (List.can_fit)]; + //Helper.css(document.querySelector("#wrapper").children[List.page + (List.can_fit)], "display", "inline-flex"); + //Helper.css(document.querySelector("#wrapper").children[List.page + (List.can_fit)], "height", List.element_height + "px"); + } + if(List.page >= document.querySelector("#wrapper").children.length - 1){ + List.dynamicContentPage(-1); + Helper.css(".next_page_hide", "display", "inline-flex"); + Helper.css(".next_page", "display", "none"); + Helper.css(".last_page_hide", "display", "inline-flex"); + Helper.css(".last_page", "display", "none"); + } else if(List.page + List.can_fit + 1 >= document.querySelector("#wrapper").children.length - 1){ + Helper.css(".next_page_hide", "display", "inline-flex"); + Helper.css(".next_page", "display", "none"); + Helper.css(".last_page_hide", "display", "inline-flex"); + Helper.css(".last_page", "display", "none"); + } - if(List.page <= index && List.page - List.can_fit <= index) { - Helper.addClass("#" + deleted, "side_away"); + if(List.page <= index && List.page - List.can_fit <= index) { + Helper.addClass("#" + deleted, "side_away"); - //document.getElementById(deleted).querySelector(".mobile-delete").remove(); - Helper.css("#" + deleted, "transform", "translateX(-100%)"); - setTimeout(function() { - Helper.removeElement("#" + deleted); - /*var wrapperChildren = [].slice.call(document.querySelector("#wrapper").children); - if(wrapperChildren.length > List.can_fit) { - Helper.css(wrapperChildren[List.can_fit], "display", "inline-flex"); - }*/ + //document.getElementById(deleted).querySelector(".mobile-delete").remove(); + Helper.css("#" + deleted, "transform", "translateX(-100%)"); + setTimeout(function() { + Helper.removeElement("#" + deleted); + /*var wrapperChildren = [].slice.call(document.querySelector("#wrapper").children); + if(wrapperChildren.length > List.can_fit) { + Helper.css(wrapperChildren[List.can_fit], "display", "inline-flex"); + }*/ + if(nextToChange != undefined) { + Helper.css(nextToChange, "display", "inline-flex"); + Helper.css(nextToChange, "height", List.element_height + "px"); + } + }, 300); + } else { + Helper.removeElement("#"+deleted); if(nextToChange != undefined) { Helper.css(nextToChange, "display", "inline-flex"); Helper.css(nextToChange, "height", List.element_height + "px"); } - }, 300); - } else { - Helper.removeElement("#"+deleted); - if(nextToChange != undefined) { - Helper.css(nextToChange, "display", "inline-flex"); - Helper.css(nextToChange, "height", List.element_height + "px"); } + var index = List.getIndexOfSong(deleted); + if(index != -1) full_playlist.splice(index, 1); + Player.sendNext({title: full_playlist[0].title, videoId: full_playlist[0].id, source: full_playlist[0].source, thumbnail: full_playlist[0].thumbnail}); + //} } - full_playlist.splice(List.getIndexOfSong(deleted), 1); - Player.sendNext({title: full_playlist[0].title, videoId: full_playlist[0].id, source: full_playlist[0].source, thumbnail: full_playlist[0].thumbnail}); - //} } catch(err) { - full_playlist.splice(List.getIndexOfSong(deleted), 1); + var index = List.getIndexOfSong(deleted); + if(index != -1) full_playlist.splice(index, 1); if(!List.empty){ try { document.getElementById(deleted).remove(); @@ -503,14 +530,25 @@ var List = { voted_song: function(voted, time) { var index_of_song = List.getIndexOfSong(voted); + if(index_of_song == -1) return; var song_voted_on = full_playlist[index_of_song]; full_playlist[index_of_song].votes += 1; full_playlist[index_of_song].added = time; - List.sortList(); - Helper.removeElement("#"+voted); - List.insertAtIndex(song_voted_on, false); + + if(intelligentList) { + document.getElementById(voted).querySelector(".list-votes").innerText = full_playlist[index_of_song].votes; + intelligentQueue.push({ + type: "vote", + element: song_voted_on + }); + List.sortList(); + } else { + List.sortList(); + Helper.removeElement("#"+voted); + List.insertAtIndex(song_voted_on, false); + } }, song_change_prev: function(time) { @@ -537,16 +575,29 @@ var List = { song_change: function(time, remove) { try{ var length = full_playlist.length - 1; - document.querySelector("#wrapper").children[0].remove(); + if(full_playlist.length <= 1) { List.empty = true; Helper.setHtml("#wrapper", "The playlist is empty."); } - + var newLast = full_playlist[0]; full_playlist[0].now_playing = true; full_playlist[0].votes = 0; full_playlist[0].guids = []; full_playlist[0].added = time; + var i = intelligentQueue.length + + while (i--) { + var current = intelligentQueue[i]; + if (current.type == "delete") { + intelligentQueue.splice(i, 1); + Helper.removeElement("#" + current.element.id); + deleted_elements += 1; + } + } + try { + document.getElementById(full_playlist[0].id).remove(); + } catch(e) {}; if(!remove){ full_playlist[length].now_playing = false; } else { @@ -559,13 +610,21 @@ var List = { full_playlist.push(full_playlist.shift()); if(!remove){ - List.insertAtIndex(full_playlist[document.querySelector("#wrapper").children.length], false, true); + if(full_playlist.length >= 2) { + var index = full_playlist.length - 2; + List.insertAtIndex(full_playlist[index], false, true); + } } - /*var wrapperChildren = [].slice.call(document.querySelector("#wrapper").children); - if(wrapperChildren.length > List.can_fit) { - //Helper.css(wrapperChildren[List.can_fit], "display", "inline-flex"); - }*/ - } catch(e) {} + var wrapperChildren = [].slice.call(document.querySelector("#wrapper").children); + if(wrapperChildren.length >= List.can_fit && deleted_elements > 0) { + for(var i = 0; i < deleted_elements + 1; i++) { + //Helper.css(wrapperChildren[List.can_fit - 2], "display", "inline-flex"); + Helper.css(wrapperChildren[List.page + List.can_fit - 1 - i], "display", "inline-flex"); + } + } + deleted_elements = 0; + } catch(e) { + } }, vote: function(id, vote) { @@ -1276,7 +1335,7 @@ var List = { for(var i = 0; i < full_playlist.length; i++) { if(full_playlist[i].id == id) return i; } - - } catch(e) {} + return -1; + } catch(e) {return -1;} } }; diff --git a/server/public/assets/js/listeners.js b/server/public/assets/js/listeners.js index 75cbf139..26bede0e 100755 --- a/server/public/assets/js/listeners.js +++ b/server/public/assets/js/listeners.js @@ -17,6 +17,9 @@ var scUsingWidget = false; var SC_player; var previewing = false; var sc_initialized = false; +var intelligentQueue = []; +var intelligentList = false; +var deleted_elements = 0; var soundcloud_enabled = true; var local_new_channel = false; var sc_need_initialization = true; @@ -902,10 +905,23 @@ function addDynamicListeners() { addListener("change", '.remote_switch_class', function() { - Hostcontroller.change_enabled(document.getElementsByName("remote_switch")[0].checked); + var enabled = document.getElementsByName("remote_switch")[0].checked; + Hostcontroller.change_enabled(enabled); Crypt.set_remote(enabled); }); + addListener("change", '.intelligent_switch_class', function() + { + var enabled = document.getElementsByName("intelligent_switch")[0].checked; + change_intelligent(enabled); + Crypt.set_intelligent_list_enabled(enabled); + if(enabled) { + toast("Enabled intelligent playlist!"); + } else { + toast("Disabled intelligent playlist."); + } + }); + addListener("change", '.offline_switch_class', function() { offline = document.getElementsByName("offline_switch")[0].checked; @@ -1853,6 +1869,31 @@ function addDynamicListeners() { image_timeout = setTimeout(function(){ that.querySelector(".card-reveal").setAttribute("style", "display: none;"); }, 100); + } else if(!Helper.mobilecheck() && Crypt.get_intelligent_list_enabled()){ + try { + if(event.target.id == "wrapper" && event.relatedTarget.id != "context-menu-overlay" && event.relatedTarget.className.indexOf("context-menu-list") == -1 && event.relatedTarget.className.indexOf("context-menu-item") == -1) { + clearIntelligentQueue(); + } else if(event.target.id == "context-menu-overlay" || event.relatedTarget.className.indexOf("context-menu-list") >= 0 || event.relatedTarget.className.indexOf("context-menu-item") >= 0) { + var related = event.relatedTarget; + if(related.id == "wrapper" || related.className.indexOf("context-menu-list") >= 0 || related.className.indexOf("context-menu-item") >= 0) { + enable_intelligent_list(); + return; + } + var parent = related.parentElement; + while(parent != null) { + try { + if(parent.id == "wrapper" || parent.className.indexOf("context-menu-list") >= 0 || parent.className.indexOf("context-menu-item") >= 0) { + enable_intelligent_list(); + return; + } + } catch(e){} + try { + parent = parent.parentElement; + } catch(e){break;} + } + clearIntelligentQueue(); + } + } catch(e) {} } }, true); @@ -1865,6 +1906,8 @@ function addDynamicListeners() { image_timeout = setTimeout(function(){ that.querySelector(".card-reveal").setAttribute("style", "display: block;transform: translateY(-100%);"); }, 50); + } else if(event.target.id == "wrapper") { + enable_intelligent_list(); } }, true); diff --git a/server/public/partials/channel/panel.handlebars b/server/public/partials/channel/panel.handlebars index 6543fffe..071a0876 100755 --- a/server/public/partials/channel/panel.handlebars +++ b/server/public/partials/channel/panel.handlebars @@ -4,7 +4,7 @@ +
  • +
    Intelligent Playlist + sentiment_satisfied_alt +
    +
    +
      +
    • + + Intelligent + +
      + +
      +
      +
      +

      + When enabling intelligent playlist, playlist elements are not updated and moved around when the playlist is in focus. If things are jumping too much around in the playlist when voting, you should enable this. +

      +
      +
      +
    • +
    +
    +
  • {{#unless client}}
  • Remote Control