var Admin = {
beginning:true,
admin_listener: function()
{
socket.on("toast", function(msg)
{
switch(msg) {
case "addedsong":
msg=Helper.rnd(["I added your song", "Your song has been added", "Yay, more songs!", "Thats a cool song!", "I added that song for you", "I see you like adding songs..."])
break;
case "savedsettings":
msg=Helper.rnd(["I've saved your settings", "I stored all your settings", "Your settings have been stored in a safe place"])
break;
case "wrongpass":
msg=Helper.rnd(["That's not the right password!", "Wrong! Better luck next time...", "You seem to have mistyped the password", "Incorrect. Have you tried meditating?","Nope, wrong password!", "Wrong password. The authorities have been notified."])
Crypt.remove_pass(chan.toLowerCase());
Admin.display_logged_out();
w_p = true;
break;
case "shuffled":
msg=Helper.rnd(["♫ You stir me right round, baby. ♫","♫ Stir, stir, stir my boat ♫","I vigorously stirred your playlist!", "I hope you like your list stirred, not shaken.", "I shuffled your playlist with the cosmic background radiation as a seed. Enjoy.", "100% randomized, for your listening pleasure!", "I hope you enjoy your fresh playlist!"])
break;
case "deletesong":
msg=Helper.rnd(["Your song is now in a better place...", "You won't be seeing any more of that video...", "EXTERMINATE! EXTERMINATE! EXTERMINATE!", "I killed it with fire", "Thanks for deleting that song. I didn't like it anyways...", "Removed song securely."])
break;
case "voted":
msg=Helper.rnd(["You voted!", "You vote like a boss", "Voting is the key to democracy", "May you get your song to the very top!", "I love that song! I vouch for you.", "Only you vote that good", "I like the way you vote...", "Up the video goes!", "Voted Zöff for president", "Only 999 more to go!"])
break;
case "alreadyvoted":
msg=Helper.rnd(["You can't vote twice on that song!", "I see you have voted on that song before", "One vote per person!", "I know you want to hear your song, but have patience!", "I'm sorry, but I can't let you vote twice, Dave."])
break;
case "skip":
msg=Helper.rnd(["The song was skipped", "I have skipped a song", "Skipped to the beat", "Skipmaster3000", "They see me skippin', they hatin'"])
break;
case "listhaspass":
msg=Helper.rnd(["I'm sorry, but you have to be an admin to do that!", "Only admins can do that", "You're not allowed to do that, try logging in!", "I can't let you do that", "Please log in to do that"])
break;
case "noskip":
msg=Helper.rnd(["Only Admins can skip songs, peasant!", "You have to log in to skip songs on this channel", "Try clicking the settings icon and logging in before you skip"])
break;
case "alreadyskip":
msg=Helper.rnd(["Skipping is democratic, only one vote per person!", "More people have to vote to skip, not just you!", "Get someone else to skip too! You can't do it on yourself."])
break;
case "notyetskip":
msg="Skipping is disabled the first 10 seconds.";
break;
case "correctpass":
msg="Correct password. You now have access to the sacred realm of The Admin.";
break;
case "changedpass":
msg="Your password has been changed!";
break;
case "suggested":
msg="Your song was suggested!";
break;
case "alreadyplay":
msg="Seems the song you want is already playing. No fooling the system!";
break;
}
Materialize.toast(msg, 4000);
});
socket.on("pw", function(msg)
{
w_p = false;
adminpass = msg;
names = ["vote","addsongs","longsongs","frontpage", "allvideos",
"removeplay", "skip", "shuffle"];
Crypt.set_pass(chan.toLowerCase(), Crypt.decrypt_pass(msg))
for (var i = 0; i < names.length; i++) {
$("input[name="+names[i]+"]").attr("disabled", false);
}
$(".card-action").removeClass("hide");
$("#admin-lock").removeClass("mdi-action-lock");
$("#password").val("");
$("#password").attr("placeholder", "Change channel password")
//if(!window.mobilecheck()){
$(".playlist-tabs-loggedIn").removeClass("hide");
$(".playlist-tabs").addClass("hide");
//$("#top-button").toggleClass("top-button-with-tabs");
//$("#wrapper").toggleClass("tabs_height");
//}
if(!Helper.contains($("#admin-lock").attr("class").split(" "), "mdi-action-lock-open"))
$("#admin-lock").addClass("mdi-action-lock-open clickable");
$('ul.playlist-tabs-loggedIn').tabs('select_tab', $(".playlist-tabs li a.active").attr("href").substring(1));
});
socket.on("conf", function(msg)
{
Crypt.init();
Admin.set_conf(msg[0]);
if(Crypt.get_pass(chan.toLowerCase()) !== undefined && Admin.beginning && Crypt.get_pass(chan.toLowerCase()) != ""){
socket.emit("password", [Crypt.crypt_pass(Crypt.get_pass(chan.toLowerCase())), chan.toLowerCase()]);
Admin.beginning = false;
}
});
},
pass_save: function()
{
if(!w_p)
{
socket.emit('password', [Crypt.crypt_pass(CryptoJS.SHA256(document.getElementById("password").value).toString()), chan.toLowerCase(), Crypt.crypt_pass(Crypt.get_pass(chan.toLowerCase()))]);
}
else
{
socket.emit('password', [Crypt.crypt_pass(CryptoJS.SHA256(document.getElementById("password").value).toString()), chan.toLowerCase()]);
}
},
log_out: function(){
if(Crypt.get_pass(chan.toLowerCase())){
Crypt.remove_pass(chan.toLowerCase());
Admin.display_logged_out();
Materialize.toast("Logged out", 4000);
}else{
Materialize.toast("Not logged in", 4000);
}
},
display_logged_out: function()
{
w_p = true;
adminpass = "";
names = ["vote","addsongs","longsongs","frontpage", "allvideos",
"removeplay", "skip", "shuffle"];
document.getElementById("password").value = "";
for (i = 0; i < names.length; i++) {
$("input[name="+names[i]+"]").attr("disabled", true);
}
if(!Helper.contains($("#admin-lock").attr("class").split(" "), "mdi-action-lock")){
$("#admin-lock").addClass("mdi-action-lock");
}
if(!Helper.contains($(".playlist-tabs-loggedIn").attr("class").split(" "), "hide")){
$(".playlist-tabs-loggedIn").addClass("hide");
$(".playlist-tabs").removeClass("hide");
}
if($(".card-action").length != 0 &&
!Helper.contains($(".card-action").attr("class").split(" "), "hide")){
$(".card-action").addClass("hide");
}
if($(".playlist-tabs-li a.active").attr("href") == "#suggestions")
{
$('ul.playlist-tabs').tabs('select_tab', 'wrapper');
$('ul.playlist-tabs-loggedIn').tabs('select_tab', 'wrapper');
$("#wrapper").removeClass("tabs_height");
} else {
$('ul.playlist-tabs').tabs('select_tab', $(".playlist-tabs-loggedIn li a.active").attr("href").substring(1));
}
$("#admin-lock").removeClass("mdi-action-lock-open clickable");
$("#password").attr("placeholder", "Enter channel password");
//$("#top-button").removeClass("top-button-with-tabs");
},
//function used in html onlick
save: function(){
Admin.submitAdmin(document.getElementById("adminForm").elements);
},
set_conf: function(conf_array)
{
music = conf_array["allvideos"];
longsongs = conf_array["longsongs"];
names = ["vote","addsongs","longsongs","frontpage", "allvideos",
"removeplay", "skip", "shuffle"];
if(conf_array['adminpass'] == "" || !w_p){
hasadmin = false;
if(!window.mobilecheck()){
//$(".playlist-tabs").removeClass("hide");
//$("#wrapper").toggleClass("tabs_height");
}
}
else hasadmin = true;
for (var i = 0; i < names.length; i++)
{
document.getElementsByName(names[i])[0].checked = (conf_array[names[i]] === true);
$("input[name="+names[i]+"]").attr("disabled", hasadmin);
}
if((hasadmin)){
Admin.display_logged_out();
}else if(!hasadmin && Crypt.get_pass(chan.toLowerCase()) === undefined){
$("#password").attr("placeholder", "Create channel password");
}
/*if(conf_array.desc !== undefined)
{
document.getElementById("description").innerHTML = conf_array.desc;
}*/
},
submitAdmin: function(form)
{
voting = form.vote.checked;
addsongs = form.addsongs.checked;
longsongs = form.longsongs.checked;
frontpage = form.frontpage.checked;
allvideos = form.allvideos.checked;
removeplay = form.removeplay.checked;
skipping = form.skip.checked;
shuffling = form.shuffle.checked;
configs = [voting, addsongs, longsongs, frontpage, allvideos,
removeplay, adminpass, skipping, shuffling];
socket.emit("conf", configs);
},
hide_settings: function(){
$('#settings').sideNav('hide');
},
shuffle: function()
{
socket.emit('shuffle', adminpass !== undefined ? adminpass : "");
},
get_admin:function()
{
return [w_p, hasadmin];
}
}
var Chat = {
namechange: function(newName)
{
socket.emit("namechange", newName);
Crypt.set_name(newName);
},
removename: function()
{
socket.emit("removename");
Crypt.remove_name();
},
chat: function(data)
{
if(data.value.length > 150)
return;
if(data.value.startsWith("/name ")){
Chat.namechange(data.value.substring(6));
}else if(data.value.startsWith("/removename")){
Chat.removename();
}
else if($(".chat-tab-li a.active").attr("href") == "#all_chat")
socket.emit("all,chat", data.value);
else
socket.emit("chat", data.value);
data.value = "";
return;
},
allchat_listener: function()
{
socket.on("chat.all", function(inp)
{
//$("#chat-btn").css("color", "grey");
if(!blink_interval_exists && inp[1].substring(0,1) == ":" && !chat_active)
{
$("#favicon").attr("href", "static/images/highlogo.png");
blink_interval_exists = true;
unseen = true;
chat_unseen = true;
if(!blinking) Chat.chat_blink();
//blink_interval = setTimeout(Chat.chat_blink, 2000);
}
if(document.hidden)
{
$("#favicon").attr("href", "static/images/highlogo.png");
}
var color = Helper.intToARGB(Helper.hashCode(inp[0]));
if(color.length < 6) {
for(x = color.length; x < 6; x++){
color = "0" + color;
}
}
color = Helper.hexToRgb(color.substring(0,6));
var color_temp = Helper.rgbToHsl([color.r, color.g, color.b], false);
$("#chatall").append("
"+inp[0]+"");
var in_text = document.createTextNode(inp[1]);
$("#chatall li:last")[0].appendChild(in_text);
document.getElementById("chatall").scrollTop = document.getElementById("chatall").scrollHeight;
});
},
setup_chat_listener: function(channel)
{
socket.on("chat", function(data)
{
if(!blink_interval_exists && data[1].substring(0,1) == ":" && !chat_active)
{
$("#favicon").attr("href", "static/images/highlogo.png");
unseen = true;
chat_unseen = true;
if(!blinking) Chat.chat_blink();
//blink_interval = setTimeout(Chat.chat_blink, 1000);
}
var color = Helper.intToARGB(Helper.hashCode(data[0]));
if(color.length < 6) {
for(x = color.length; x < 6; x++){
color = "0" + color;
}
}
color = Helper.hexToRgb(color.substring(0,6));
var color_temp = Helper.rgbToHsl([color.r, color.g, color.b], false);
$("#chatchannel").append(""+data[0]+"");
var in_text = document.createTextNode(data[1]);
$("#chatchannel li:last")[0].appendChild(in_text);
document.getElementById("chatchannel").scrollTop = document.getElementById("chatchannel").scrollHeight;
});
},
chat_blink: function() {
blinking = true;
$(".chat-link").attr("style", "color: grey !important;");
setTimeout(function () {
$(".chat-link").attr("style", "color: white !important;");
setTimeout(function() {
if(blinking) Chat.chat_blink();
}, 1000);
}, 1000);
}
}
var Crypt = {
conf_pass: undefined,
init: function(){
document.cookie = chan.toLowerCase() + '=; path=/' + chan.toLowerCase() + '; expires=' + new Date(0).toUTCString();
try{
conf_arr = Crypt.decrypt(Crypt.getCookie("_opt"), "_opt");
}catch(err){
conf_arr = Crypt.decrypt(Crypt.create_cookie("_opt"), "_opt");
}
try{
Crypt.conf_pass = Crypt.decrypt(Crypt.getCookie(chan.toLowerCase()), chan.toLowerCase());
}catch(err){
Crypt.conf_pass = Crypt.decrypt(Crypt.create_cookie(chan.toLowerCase()), chan.toLowerCase());
}
Hostcontroller.change_enabled(conf_arr.remote);
if(conf_arr["width"] != 100) Player.set_width(conf_arr["width"]);
if(conf_arr["name"] != undefined && conf_arr["name"] != "") Chat.namechange(conf_arr["name"]);
},
decrypt: function(cookie, name){
if(Crypt.getCookie(name) === undefined) {
cookie = Crypt.create_cookie(name);
}
var decrypted = CryptoJS.AES.decrypt(
cookie,navigator.userAgent+navigator.languages,
{
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
}
);
return $.parseJSON(decrypted.toString(CryptoJS.enc.Utf8));
},
decrypt_pass: function(pass){
var decrypted = CryptoJS.AES.decrypt(
pass,socket.id,
{
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
}
);
return decrypted.toString(CryptoJS.enc.Utf8);
},
encrypt: function(json_formated, cookie){
var to_encrypt = JSON.stringify(json_formated);
var encrypted = CryptoJS.AES.encrypt(
to_encrypt,
navigator.userAgent+navigator.languages,
{
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
}
);
var CookieDate = new Date;
CookieDate.setFullYear(CookieDate.getFullYear( ) +1);
document.cookie = cookie+"="+encrypted.toString()+";expires="+CookieDate.toGMTString()+";path=/;";
},
encrypt_string: function(string){
var encrypted = CryptoJS.AES.encrypt(
string,
socket.id,
{
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
}
);
return encrypted.toString();
},
get_volume: function(){
return Crypt.decrypt(Crypt.getCookie("_opt"), "_opt").volume;
//return conf_arr.volume;
},
set_volume: function(val){
conf_arr.volume = val;
Crypt.encrypt(conf_arr, "_opt");
},
create_cookie: function(name){
if(name == "_opt") cookie_object = {volume: 100, width: 100, remote: true, name: ""};
else cookie_object = {passwords: {}};
var string_it = JSON.stringify(cookie_object);
var encrypted = CryptoJS.AES.encrypt(
string_it,
navigator.userAgent+navigator.languages,
{
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
}
);
var CookieDate = new Date;
CookieDate.setFullYear(CookieDate.getFullYear( ) +1);
document.cookie = name+"="+encrypted.toString()+";expires="+CookieDate.toGMTString()+";path=/;";
//document.cookie = name+"="+encrypted.toString()+";expires="+CookieDate.toGMTString()+";path=/;"
//document.cookie = na"="+encrypted.toString()+";expires="+CookieDate.toGMTString()+";path=/;"
return Crypt.getCookie(name);
},
set_pass: function(chan, pass){
Crypt.conf_pass.passwords[chan] = pass;
Crypt.encrypt(Crypt.conf_pass, chan);
},
remove_pass:function(chan){
delete Crypt.conf_pass.passwords[chan];
Crypt.encrypt(Crypt.conf_pass, chan.toLowerCase());
},
set_name:function(name){
conf_arr.name = name;
Crypt.encrypt(conf_arr, "_opt");
},
remove_name:function(){
conf_arr.name = "";
Crypt.encrypt(conf_arr, "_opt");
},
get_pass: function(chan){
if(Crypt.conf_pass != undefined) return Crypt.conf_pass.passwords[chan];
return undefined;
},
set_remote: function(val){
conf_arr.remote = val;
Crypt.encrypt(conf_arr, "_opt");
},
get_remote: function(val){
return conf_arr.remote;
},
crypt_pass: function(pass){
var encrypted = CryptoJS.AES.encrypt(
pass,
socket.id,
{
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
}
);
return encrypted.toString();
},
get_width: function(){
return conf_arr["width"];
},
set_width: function(val){
conf_arr["width"] = val;
Crypt.encrypt(conf_arr, "_opt");
},
getCookie: function(name) {
var value = "; " + document.cookie;
var parts = value.split("; " + name + "=");
if (parts.length == 2) return parts.pop().split(";").shift();
}
}
window.mobilecheck = function() {
var check = false;
(function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4)))check = true;})(navigator.userAgent||navigator.vendor||window.opera);
return check;
};
var Helper = {
rnd: function(arr)
{
return arr[Math.floor(Math.random() * arr.length)];
},
predicate: function() {
var fields = [],
n_fields = arguments.length,
field, name, cmp;
var default_cmp = function (a, b) {
if (a === b) return 0;
return a < b ? -1 : 1;
},
getCmpFunc = function (primer, reverse) {
var dfc = default_cmp,
// closer in scope
cmp = default_cmp;
if (primer) {
cmp = function (a, b) {
return dfc(primer(a), primer(b));
};
}
if (reverse) {
return function (a, b) {
return -1 * cmp(a, b);
};
}
return cmp;
};
// preprocess sorting options
for (var i = 0; i < n_fields; i++) {
field = arguments[i];
if (typeof field === 'string') {
name = field;
cmp = default_cmp;
} else {
name = field.name;
cmp = getCmpFunc(field.primer, field.reverse);
}
fields.push({
name: name,
cmp: cmp
});
}
// final comparison function
return function (A, B) {
var name, result;
for (var i = 0; i < n_fields; i++) {
result = 0;
field = fields[i];
name = field.name;
result = field.cmp(A[name], B[name]);
if (result !== 0) break;
}
return result;
};
},
hashCode: function(str) { // java String#hashCode
var hash = 0;
for (var i = 0; i < str.length; i++) {
hash = str.charCodeAt(i) + ((hash << 5) - hash);
}
return hash;
},
intToARGB: function(i){
return ((i>>24)&0xFF).toString(16) +
((i>>16)&0xFF).toString(16) +
((i>>8)&0xFF).toString(16) +
(i&0xFF).toString(16);
},
hexToRgb: function(hex) {
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : null;
},
pad: function(n)
{
return n < 10 ? "0"+Math.floor(n) : Math.floor(n);
},
contains: function(a, obj) {
var i = a.length;
while (i--) {
if (a[i] === obj) {
return true;
}
}
return false;
},
sample: function() {
if (Date.now() - lastSample >= SAMPLE_RATE * 2) {
socket.removeAllListeners()
socket.disconnect();
socket.connect();
Player.setup_all_listeners();
}
lastSample = Date.now();
setTimeout(Helper.sample, SAMPLE_RATE);
},
loadjsfile: function(filename)
{
if (filesadded.indexOf("["+filename+"]")==-1){
var fileref=document.createElement('script');
fileref.setAttribute("type","text/javascript");
fileref.setAttribute("src", filename);
document.getElementsByTagName("head")[0].appendChild(fileref);
filesadded+="["+filename+"]";
}
},
msieversion: function() {
var ua = window.navigator.userAgent;
var msie = ua.indexOf("MSIE ");
if (msie > 0 || !!navigator.userAgent.match(/Trident.*rv\:11\./)) // If Internet Explorer, return version number
return true;
else // If another browser, return 0
return false;
},
getRandomInt: function(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
},
rgbToHsl: function(arr, light){
r = arr[0], g = arr[1], b = arr[2];
r /= 255, g /= 255, b /= 255;
var max = Math.max(r, g, b), min = Math.min(r, g, b);
var h, s, l = (max + min) / 2;
if(max == min){
h = s = 0; // achromatic
}else{
var d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch(max){
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
case g: h = (b - r) / d + 2; break;
case b: h = (r - g) / d + 4; break;
}
h /= 6;
}
if(l>0.5 && light)l=0.5; //make sure it isnt too light
else if(l<0.65 && !light)l=0.65;
return "hsl("+Math.floor(h*360)+", "+Math.floor(s*100)+"%, "+Math.floor(l*100)+"%)";
},
componentToHex: function(c) {
var hex = c.toString(16);
return hex.length == 1 ? "0" + hex : hex;
},
rgbToHex: function(r, g, b) {
return "#" + Helper.componentToHex(r) + Helper.componentToHex(g) + Helper.componentToHex(b);
},
upperFirst: function(string){
return string.substring(0,1).toUpperCase()+string.substring(1).toLowerCase();
},
addClass: function(object, toAdd){
if(!Helper.contains($(object).attr("class").split(" "), toAdd)){
$(object).addClass(toAdd);
}
},
send_mail: function(from, message){
if(from != "" && message != ""){
$("#submit-contact-form").addClass("hide");
$("#send-loader").removeClass("hide");
$("#contact-form-from").attr("disabled", "true");
$("#contact-form-message").attr("disabled", "true");
/*
$.ajax({
type: "POST",
data: {from: from, message: message},
url: "/php/mail.php",
success: function(data){
if(data == "success"){
$("#contact-container").empty();
$("#contact-container").html("Mail has been sent, we'll be back with you shortly.")
}else{
$("#contact-container").empty();
$("#contact-container").html("Something went wrong, sorry about that. You could instead try with your own mail-client: contact@zoff.no")
}
}
});*/
var from = $("#contact-form-from").val();
var message = $("#contact-form-message").val();
$("#contact-container").empty();
newWindow = window.open("mailto:contact@zoff.no?Subject=Contact%20Zoff&Body=" + message, "_blank");
$("#contact-container").html("Something went wrong, sorry about that. You could instead try with your own mail-client: contact@zoff.no");
setTimeout(function(){newWindow.close()},500);
}
}
}
$(document).on('submit', '#contact-form', function(e){
e.preventDefault();
var message = $("#contact-form-message").val();
var from = $("#contact-form-from").val();
Helper.send_mail(from, message);
});
Element.prototype.remove = function() {
this.parentElement.removeChild(this);
}
NodeList.prototype.remove = HTMLCollection.prototype.remove = function() {
for(var i = 0, len = this.length; i < len; i++) {
if(this[i] && this[i].parentElement) {
this[i].parentElement.removeChild(this[i]);
}
}
}
String.prototype.startsWith = function(searchString, position) {
position = position || 0;
return this.indexOf(searchString, position) === position;
}
var Hostcontroller = {
enabled: true,
host_listener: function() {
var old_id;
socket.on("id", function(id)
{
if(old_id === undefined) old_id = id;
else
{
socket.removeAllListeners(id);
began = false;
old_id = id;
}
var codeURL = "https://remote."+window.location.hostname+"/"+id;
$("#code-text").text(id)
$("#code-qr").attr("src", "https://chart.googleapis.com/chart?chs=221x221&cht=qr&choe=UTF-8&chld=L|1&chl="+codeURL);
$("#code-link").attr("href", codeURL);
if(!began)
{
began = true;
socket.on(id, function(arr)
{
if(enabled){
if(arr[0] == "volume"){
$("#volume").slider("value", arr[1]);
Player.ytplayer.setVolume(arr[1]);
localStorage.setItem("volume", arr[1]);
Playercontrols.choose_button(arr[1], false);
}else if(arr[0] == "channel"){
socket.emit("change_channel");
Admin.beginning = true;
chan = arr[1].toLowerCase();
$("#chan").html(Helper.upperFirst(chan));
w_p = true;
socket.emit("list", chan.toLowerCase());
/*if(Crypt.get_pass(chan.toLowerCase()) !== undefined && Crypt.get_pass(chan.toLowerCase()) != ""){
socket.emit("password", [Crypt.crypt_pass(Crypt.get_pass(chan.toLowerCase())), chan.toLowerCase()]);
}*/
window.history.pushState("object or string", "Title", "/"+chan.toLowerCase());
}else if(arr[0] == "pause")
Player.ytplayer.pauseVideo()
else if(arr[0] == "play")
Player.ytplayer.playVideo();
else if(arr[0] == "skip")
List.skip();
}
});
}
});
$('input[class=remote_switch_class]').change(function()
{
enabled = document.getElementsByName("remote_switch")[0].checked;
Crypt.set_remote(enabled);
});
},
change_enabled:function(val){
enabled = val;
document.getElementsByName("remote_switch")[0].checked = enabled;
}
}
var List = {
empty: false,
channel_listener: function()
{
socket.on("channel", function(msg){
List.channel_function(msg);
});
},
channel_function: function(msg)
{
switch(msg[0])
{
case "list":
List.populate_list(msg[1]);
break;
case "added":
List.added_song(msg[1]);
break;
case "deleted":
List.deleted_song(msg[1]);
break;
case "vote":
List.voted_song(msg[1], msg[2]);
break;
case "song_change":
List.song_change(msg[1]);
break;
}
},
populate_list: function(msg)
{
if(list_html == undefined) list_html = $("#list-song-html").html();
full_playlist = msg;
List.sortList();
$("#wrapper").empty();
if(full_playlist.length > 1){
$.each(full_playlist, function(j, current_song){
if(!current_song.now_playing){ //check that the song isnt playing
$("#wrapper").append(List.generateSong(current_song, false, lazy_load, true));
}
});
if(lazy_load){
if(window.mobilecheck()) $(".list-image").lazyload({});
else{
$(".list-image").lazyload({container: $("#wrapper")}).removeClass("lazy");
document.getElementById('wrapper').scrollTop += 1;
document.getElementById('wrapper').scrollTop += -1;
}
}
}else{
List.empty = true;
$("#wrapper").append("The playlist is empty.");
}
$("#settings").css("visibility", "visible");
$("#settings").css("opacity", "1");
$("#wrapper").css("opacity", "1");
},
added_song: function(added){
full_playlist.push(added);
List.sortList();
$("#suggested-"+added.id).remove();
if(List.empty){
$("#empty-channel-message").remove();
List.empty = false;
}
List.insertAtIndex(added, true);
},
deleted_song: function(deleted){
var index = List.getIndexOfSong(deleted);
var to_delete = $("#wrapper").children()[index];
try{
to_delete.style.height = 0;
setTimeout(function()
{
$("#"+deleted).remove();
full_playlist.splice(List.getIndexOfSong(deleted), 1);
}, 305);
document.getElementById('wrapper').scrollTop += 1;
document.getElementById('wrapper').scrollTop += -1;
}catch(err){
full_playlist.splice(List.getIndexOfSong(deleted), 1);
if(!List.empty)
$("#wrapper").children()[$("#wrapper").children().length-1].remove();
}
if(full_playlist.length <= 2){
List.empty = true;
$("#wrapper").append("The playlist is empty.");
}
$("#suggested-"+deleted).remove();
Suggestions.checkUserEmpty();
},
voted_song: function(voted, time){
var index_of_song = List.getIndexOfSong(voted);
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();
$("#"+voted).remove();
List.insertAtIndex(song_voted_on, false);
},
song_change: function(time){
var length = full_playlist.length-1;
full_playlist[0].now_playing = true;
full_playlist[0].votes = 0;
full_playlist[0].guids = [];
full_playlist[0].added = time;
full_playlist[length].now_playing = false;
try{
full_playlist.push(full_playlist.shift());
if(!List.empty)
$("#wrapper").children()[0].remove();
List.insertAtIndex(full_playlist[length-1], false);
document.getElementById('wrapper').scrollTop += 1;
document.getElementById('wrapper').scrollTop += -1;
}catch(e){}
},
vote: function(id, vote){
socket.emit('vote', [chan, id, vote, adminpass]);
return true;
},
skip: function(){
socket.emit('skip', {pass: adminpass, id:video_id});
return true;
},
importOldList: function(chan){
var ids="";
var num=0;
playlist_url = "lists/"+chan+".json";
list = $.parseJSON($.ajax({
type: "GET",
url: playlist_url,
async: false
}).responseText);
$.each(list.songs, function(i,data)
{
ids+=data.id+",";
if(num>45){
Search.addVideos(ids);
ids = "";
num = 0;
}
num++;
});
Search.addVideos(ids);
document.getElementById("search").value = "";
},
sortList: function()
{
full_playlist.sort(Helper.predicate({
name: 'votes',
reverse: true
}, 'added'));
},
show: function(){
if(!window.mobilecheck())
{
if(showToggle){
showToggle=false;
$("#toptitle").empty();
$("#chan").addClass("bigChan");
//$("#chan").html("zoff.no/"+encodeURI(chan));
$("#chan").html("zoff.no/"+chan.toLowerCase());
}else{
showToggle=true;
$("#toptitle").html("Zöff");
$("#chan").removeClass("bigChan");
$("#chan").html(chan);
}
}
},
insertAtIndex: function(song_info, transition) {
i = List.getIndexOfSong(song_info.id);
if(i === 0)
$("#wrapper").prepend(List.generateSong(song_info, transition, false, true, false));
else
$("#wrapper > div:nth-child(" + (i) + ")").after(List.generateSong(song_info, transition, false, true, false));
if(transition)
{
setTimeout(function(){
var added = $("#wrapper").children()[i];
$(added).css("height", 66);
},5);
}
},
generateSong: function(song_info, transition, lazy, list, user)
{
var video_id = song_info.id;
var video_title = song_info.title;
var video_votes = song_info.votes;
var video_thumb = "background-image:url('//img.youtube.com/vi/"+video_id+"/mqdefault.jpg');";
var song = $(""+list_html+"
");
var image_attr = "style";
var attr;
var del_attr;
if(transition) song.find("#list-song").css("height", 0);
if(!w_p) song.find(".card-action").removeClass("hide");
if(video_votes == 1)song.find(".vote-text").text("vote");
if(lazy){
video_thumb = "//img.youtube.com/vi/"+video_id+"/mqdefault.jpg";
image_attr = "data-original";
}
if(list){
song.find(".list-votes").text(video_votes);
song.find("#list-song").attr("id", video_id);
song.find(".vote-container").attr("title", video_title);
attr = ".vote-container";
del_attr = "del";
}else if(!list){
song.find(".vote-text").text(song_info.duration);
attr = ".add-suggested";
if(user)
del_attr = "del_user_suggested";
else
del_attr = "del_suggested";
song.find(".vote-container").attr("class", "clickable add-suggested");
song.find(".add-suggested").attr("title", video_title);
song.find("#del").attr("id", del_attr);
song.find(attr).attr("data-video-title", video_title);
song.find(attr).attr("data-video-length", song_info.length);
song.find("#list-song").attr("id", "suggested-" + video_id);
song.find(".list-image").attr("class", song.find(".list-image").attr("class").replace("list-image", "list-suggested-image"));
}
song.find(".list-title").text(video_title);
song.find(".list-title").attr("title", video_title);
//song.find(".vote-container").attr("onclick", "vote('"+video_id+"','pos')");
song.find(attr).attr("data-video-id", video_id);
song.find(".list-image").attr(image_attr,video_thumb);
song.find(".list-suggested-image").attr(image_attr,video_thumb);
song.find("#"+del_attr).attr("data-video-id", video_id);
//song.find("#del").attr("onclick", "vote('"+video_id+"', 'del')");
return song.html();
},
getIndexOfSong: function(id)
{
indexes = $.map(full_playlist, function(obj, index) {
if(obj.id == id) {
return index;
}
});
return indexes[0];
},
scrollTop: function(){
$("#wrapper").scrollTop(0);
},
scrollBottom: function(){
$("#wrapper").scrollTop($("#wrapper")[0].scrollHeight);
}
}
var chan = $("#chan").html();
var w_p = true;
var hasadmin = 0;
var showToggle = true;
var list_html = $("#list-song-html").html();
var blink_interval_exists = false;
var unseen = false;
//var timer = 0;
var api_key = "***REMOVED***";
var searching = false
var time_regex = /P((([0-9]*\.?[0-9]*)Y)?(([0-9]*\.?[0-9]*)M)?(([0-9]*\.?[0-9]*)W)?(([0-9]*\.?[0-9]*)D)?)?(T(([0-9]*\.?[0-9]*)H)?(([0-9]*\.?[0-9]*)M)?(([0-9]*\.?[0-9]*)S)?)?/
var conf = [];
var music = 0;
var frontpage = 1;
var adminpass = "";
var filesadded = "";
var player_ready = false;
var viewers = 1;
var paused = false;
var playing = false;
var SAMPLE_RATE = 6000; // 6 seconds
var lastSample = Date.now();
var began = false;
var i = -1;
var lazy_load = true;
var embed = false;
var autoplay = true;
var durationBegun = false;
var chat_active = false;
var chat_unseen = false;
var blinking = false;
var result_html;
var empty_results_html;
var mobile_beginning;
var timeout_search;
var id;
var full_playlist;
var conf;
var blink_interval;
var tag;
var firstScriptTag;
var title;
var viewers;
var video_id;
var list;
var seekTo;
var song_title;
var previous_video_id;
var socket;
var connection_options = {
'sync disconnect on unload':true,
'secure': true,
'force new connection': true
};
$().ready(function(){
if(!window.fromFront && window.location.pathname != "/") init();
});
function init(){
chan = $("#chan").html();
mobile_beginning = window.mobilecheck();
window.onpopstate = function(e){
onepage_load();
}
share_link_modifier_channel();
if(window.location.hostname == "zoff.no") add = "https://zoff.no";
else add = "localhost";
//setTimeout(function(){
if(Player != undefined) Player.stopInterval= false;
//window.vote = List.vote;
//window.submit = Search.submit;
//window.submitAndClose = Search.submitAndClose;
if(!localStorage["list_update"] || localStorage["list_update"] != "13.06.15")
{
localStorage.setItem("list_update", "13.06.15");
window.location.reload(true);
}
$('ul.playlist-tabs').tabs();
$('ul.playlist-tabs-loggedIn').tabs();
$('.chatTabs').tabs();
$("#settings").sideNav({
menuWidth: 300, // Default is 240
edge: 'right', // Choose the horizontal origin
closeOnClick: false // Closes side-nav on clicks, useful for Angular/Meteor
});
$('.collapsible').collapsible({
accordion : true // A setting that changes the collapsible behavior to expandable instead of the default accordion style
});
result_html = $("#temp-results-container");
empty_results_html = $("#empty-results-container").html();
//awdwad
$(".video-container").resizable({
start: function(event, ui) {
$('iframe').css('pointer-events','none');
},
stop: function(event, ui) {
$('iframe').css('pointer-events','auto');
Crypt.set_width($(this).width());
},
handles: "e",
minWidth: 350
});
/*
if(localStorage[chan.toLowerCase()])
{
if(localStorage[chan.toLowerCase()].length != 64)
localStorage.removeItem(chan.toLowerCase());
else
socket.emit("password", [localStorage[chan.toLowerCase()], chan.toLowerCase()]);
}*/
socket = io.connect(''+add+':8880', connection_options);
Player.setup_youtube_listener(chan);
Admin.admin_listener();
List.channel_listener();
socket.on("get_list", function(){
//setTimeout(function(){
socket.emit('list', chan.toLowerCase());
/*if(Crypt.get_pass(chan.toLowerCase()) != undefined){
socket.emit("password", [Crypt.crypt_pass(Crypt.get_pass(chan.toLowerCase())), chan.toLowerCase()]);
}*/
});
socket.on("suggested", function(params){
var single = true;
if(params.id == undefined)
single = false;
//setTimeout(function(){
Suggestions.catchUserSuggests(params, single);
//}, 1000);
});
socket.on("viewers", function(view)
{
viewers = view;
if(song_title !== undefined)
Player.getTitle(song_title, viewers);
});
if(/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream){
document.getElementById("search").blur();
$("#channel-load").css("display", "none");
} else {
window.onYouTubeIframeAPIReady = Player.onYouTubeIframeAPIReady;
Player.loadPlayer();
}
Chat.setup_chat_listener(chan);
Chat.allchat_listener();
if(!window.mobilecheck()) Hostcontroller.host_listener();
if(!Helper.msieversion() && !window.mobilecheck()) Notification.requestPermission();
git_info = $.ajax({ type: "GET",
url: "https://api.github.com/repos/zoff-music/zoff/commits",
async: false
}).responseText;
git_info = $.parseJSON(git_info);
$("#latest-commit").html("Latest Commit:
"
+ git_info[0].commit.author.date.substring(0,10)
+ ": " + git_info[0].committer.login
+ "
"
+ git_info[0].sha.substring(0,10) + ": "
+ git_info[0].commit.message+"
');
$("#search").attr("placeholder", "Find song on YouTube...");
}
window.init = init;
function searching(event) {
search_input = $(this).val();
if (event.keyCode != 40 && event.keyCode != 38 && event.keyCode != 13 && event.keyCode != 39 && event.keyCode != 37 &&
event.keyCode != 17 && event.keyCode != 16 && event.keyCode != 225 && event.keyCode != 18) {
clearTimeout(timeout_search);
if(search_input.length < 3){$("#results").html("");}
if(event.keyCode == 13){
Search.search(search_input);
}else{
timeout_search = setTimeout(function(){
Search.search(search_input);
}, 1000);
/*i = 0;
timer=100;*/
}
}
}
$(document).keyup(function(e) {
if(event.keyCode == 27){
$("#results").html("");
if(!Helper.contains($("#search-wrapper").attr("class").split(" "), "hide"))
$("#search-wrapper").toggleClass("hide");
if(Helper.contains($("#song-title").attr("class").split(" "), "hide"))
$("#song-title").toggleClass("hide");
if($("#search-btn i").attr('class') == "mdi-navigation-close")
{
$("#search-btn i").toggleClass("mdi-navigation-close");
$("#search-btn i").toggleClass("mdi-action-search");
}
$("#results").toggleClass("hide");
}else if ($("div.result").length > 2){
children = $("#mock-div").children();
if (e.keyCode == 40) {
$(children[i-1]).removeClass("hoverResults");
$(children[i]).addClass("hoverResults");
if(i < children.length -2)
i++;
} else if (e.keyCode == 38) {
if(i > 1)
i--;
$(children[i]).removeClass("hoverResults");
$(children[i-1]).addClass("hoverResults");
} else if(e.keyCode == 13) {
i = 0;
var elem = document.getElementsByClassName("hoverResults")[0];
if (typeof elem.onclick == "function") {
elem.onclick.apply(elem);
}
$("div.hoverResults").removeClass("hoverResults");
$("#results").html('');
document.getElementById("search").value = "";
}
}
});
$('input[class=conf]').change(function()
{
Admin.save();
});
$("#clickme").click(function(){
Player.ytplayer.playVideo();
});
$('#listImport').on("submit", function(){
Search.importPlaylist(document.getElementById("import").value);
});
$(window).focus(function(){
$("#favicon").attr("href", "static/images/favicon.png");
unseen = false;
});
$(document).on("change", "#autoplay", function() {
if(this.checked) {
$("#embed-area").val('