mirror of
https://github.com/KevinMidboe/zoff.git
synced 2025-10-29 18:00:23 +00:00
Added function for rules, and moved thumbnail/data somewhat around for better readability
This commit is contained in:
@@ -190,6 +190,17 @@ module.exports = function() {
|
||||
Suggestions.description(msg, coll, guid, offline, socket);
|
||||
});
|
||||
|
||||
socket.on('suggest_rules', function(msg){
|
||||
if(msg.hasOwnProperty("channel") && msg.channel.indexOf("?") > -1){
|
||||
var _list = msg.channel.substring(0, msg.channel.indexOf("?"));
|
||||
msg.channel = _list;
|
||||
}
|
||||
if(msg.hasOwnProperty("channel")) {
|
||||
msg.channel = Functions.encodeChannelName(msg.channel);
|
||||
}
|
||||
Suggestions.rules(msg, coll, guid, offline, socket);
|
||||
});
|
||||
|
||||
socket.on("namechange", function(msg) {
|
||||
if(msg.hasOwnProperty("channel") && msg.channel.indexOf("?") > -1){
|
||||
var _list = msg.channel.substring(0, msg.channel.indexOf("?"));
|
||||
|
||||
@@ -120,5 +120,64 @@ function description(msg, coll, guid, offline, socket) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function rules(msg, coll, guid, offline, socket) {
|
||||
if(msg.rules && msg.channel && msg.rules.length < 250){
|
||||
if(typeof(msg.channel) != "string" || typeof(msg.rules) != "string") {
|
||||
var result = {
|
||||
channel: {
|
||||
expected: "string",
|
||||
got: msg.hasOwnProperty("channel") ? typeof(msg.channel) : undefined,
|
||||
},
|
||||
pass: {
|
||||
expected: "string",
|
||||
got: msg.hasOwnProperty("pass") ? typeof(msg.pass) : undefined,
|
||||
},
|
||||
rules: {
|
||||
expected: "string",
|
||||
got: msg.hasOwnProperty("rules") ? typeof(msg.rules) : undefined,
|
||||
},
|
||||
adminpass: {
|
||||
expected: "string",
|
||||
got: msg.hasOwnProperty("adminpass") ? typeof(msg.adminpass) : undefined,
|
||||
},
|
||||
};
|
||||
socket.emit("update_required", result);
|
||||
return;
|
||||
}
|
||||
//coll = coll.replace(/ /g,'');
|
||||
Functions.getSessionAdminUser(Functions.getSession(socket), coll, function(userpass, adminpass, gotten) {
|
||||
if(userpass != "" || msg.pass == undefined) {
|
||||
msg.pass = userpass;
|
||||
} else if(msg.hasOwnProperty("pass")) {
|
||||
msg.pass = crypto.createHash('sha256').update(Functions.decrypt_string(msg.pass)).digest("base64");
|
||||
}
|
||||
if(adminpass != "" || msg.adminpass == undefined) {
|
||||
msg.adminpass = Functions.hash_pass(adminpass);
|
||||
} else {
|
||||
msg.adminpass = Functions.hash_pass(Functions.hash_pass(Functions.decrypt_string(msg.adminpass), true));
|
||||
}
|
||||
var channel = msg.channel.toLowerCase();
|
||||
var hash = msg.adminpass;
|
||||
db.collection(channel + "_settings").find({id: "config"}, function(err, docs){
|
||||
if(docs.length > 0 && (docs[0].userpass == undefined || docs[0].userpass == "" || (msg.hasOwnProperty('pass') && docs[0].userpass == msg.pass))) {
|
||||
if(docs !== null && docs.length !== 0 && docs[0].adminpass !== "" && docs[0].adminpass == hash){
|
||||
db.collection("suggested_rules").update({channel: channel}, {$set:{rules: msg.rules}}, {upsert:true}, function(err, docs){
|
||||
Notifications.requested_change("rules", msg.rules, channel);
|
||||
socket.emit("toast", "suggested_rules");
|
||||
});
|
||||
}
|
||||
} else {
|
||||
socket.emit("auth_required");
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
socket.emit("toast", "rules_denied");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
module.exports.thumbnail = thumbnail;
|
||||
module.exports.description = description;
|
||||
module.exports.rules = rules;
|
||||
|
||||
@@ -12,7 +12,14 @@ function toast(text, length, classes) {
|
||||
}
|
||||
|
||||
window.addEventListener("DOMContentLoaded", function() {
|
||||
M.Tabs.init(document.querySelector("ul.tabs"));
|
||||
M.Tabs.init(document.querySelector(".tabs_admin"), {
|
||||
onShow: function() {
|
||||
if(this.index == 2) {
|
||||
M.Tabs.getInstance(document.querySelector(".tabs_admin_info")).updateTabIndicator();
|
||||
}
|
||||
}
|
||||
});
|
||||
M.Tabs.init(document.querySelector(".tabs_admin_info"));
|
||||
api_token_list = document.querySelector("#api_token_list").cloneNode(true);
|
||||
document.querySelector("#api_token_list").remove();
|
||||
loaded();
|
||||
@@ -207,6 +214,7 @@ addListener("click", ".approve_thumbnails", function(event) {
|
||||
that.parentElement.remove();
|
||||
var length = parseInt(document.querySelector(".thumbnails-badge").innerText);
|
||||
length = length - 1;
|
||||
increaseInfo(-1);
|
||||
document.querySelector(".thumbnails-badge").innerText = length;
|
||||
if(length <= 0){
|
||||
addClass(".thumbnails-badge", "hide");
|
||||
@@ -244,6 +252,7 @@ addListener("click", ".deny_thumbnails", function(event) {
|
||||
that.parentElement.remove();
|
||||
var length = parseInt(document.querySelector(".thumbnails-badge").innerText);
|
||||
length = length - 1;
|
||||
increaseInfo(-1);
|
||||
document.querySelector(".thumbnails-badge").innerText = length;
|
||||
if(length <= 0){
|
||||
addClass(".thumbnails-badge", "hide");
|
||||
@@ -279,6 +288,7 @@ addListener("click", ".approve_descriptions", function(event) {
|
||||
that.parentElement.remove();
|
||||
var length = parseInt(document.querySelector(".descriptions-badge").innerText);
|
||||
length = length - 1;
|
||||
increaseInfo(-1);
|
||||
document.querySelector(".descriptions-badge").innerText = length;
|
||||
if(length <= 0){
|
||||
addClass(".descriptions-badge", "hide");
|
||||
@@ -314,6 +324,7 @@ addListener("click", ".deny_descriptions", function(event) {
|
||||
that.parentElement.remove();
|
||||
var length = parseInt(document.querySelector(".descriptions-badge").innerText);
|
||||
length = length - 1;
|
||||
increaseInfo(-1);
|
||||
document.querySelector(".descriptions-badge").innerText = length;
|
||||
if(length <= 0){
|
||||
addClass(".descriptions-badge", "hide");
|
||||
@@ -326,6 +337,78 @@ addListener("click", ".deny_descriptions", function(event) {
|
||||
});
|
||||
});
|
||||
|
||||
addListener("click", ".approve_rules", function(event) {
|
||||
this.preventDefault();
|
||||
var that = event;
|
||||
var channel = that.getAttribute("data-channel");
|
||||
if(!channel) {
|
||||
toast("Something went wrong...", 2000, "red lighten");
|
||||
return;
|
||||
}
|
||||
|
||||
ajax({
|
||||
type: "POST",
|
||||
url: "/api/approve_rules",
|
||||
data: {
|
||||
channel: channel
|
||||
},
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
success: function(response){
|
||||
if(response){
|
||||
that.parentElement.remove();
|
||||
var length = parseInt(document.querySelector(".rules-badge").innerText);
|
||||
length = length - 1;
|
||||
increaseInfo(-1);
|
||||
document.querySelector(".rules-badge").innerText = length;
|
||||
if(length <= 0){
|
||||
addClass(".rules-badge", "hide");
|
||||
}
|
||||
toast("Approved rules!", 2000, "green lighten");
|
||||
} else {
|
||||
toast("Something went wrong...", 2000, "red lighten");
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
addListener("click", ".deny_rules", function(event) {
|
||||
this.preventDefault();
|
||||
var that = event;
|
||||
var channel = that.getAttribute("data-channel");
|
||||
if(!channel) {
|
||||
toast("Something went wrong...", 2000, "red lighten");
|
||||
return;
|
||||
}
|
||||
|
||||
ajax({
|
||||
type: "POST",
|
||||
url: "/api/deny_rules",
|
||||
data: {
|
||||
channel: channel
|
||||
},
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
success: function(response){
|
||||
if(response){
|
||||
that.parentElement.remove();
|
||||
var length = parseInt(document.querySelector(".rules-badge").innerText);
|
||||
length = length - 1;
|
||||
increaseInfo(-1);
|
||||
document.querySelector(".rules-badge").innerText = length;
|
||||
if(length <= 0){
|
||||
addClass(".rules-badge", "hide");
|
||||
}
|
||||
toast("Denied description!", 2000, "green lighten");
|
||||
} else {
|
||||
toast("Something went wrong...", 2000, "red lighten");
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
addListener("click", "#remove_description_button", function(event) {
|
||||
this.preventDefault();
|
||||
var that = event;
|
||||
@@ -353,6 +436,34 @@ addListener("click", "#remove_description_button", function(event) {
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
addListener("click", "#remove_rules_button", function(event) {
|
||||
this.preventDefault();
|
||||
var that = event;
|
||||
var channel = document.querySelector("#remove_rules").value;
|
||||
if(!channel) {
|
||||
toast("Something went wrong...", 2000, "red lighten");
|
||||
return;
|
||||
}
|
||||
ajax({
|
||||
type: "POST",
|
||||
url: "/api/remove_rules",
|
||||
data: {
|
||||
channel: channel
|
||||
},
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
success: function(response){
|
||||
if(response){
|
||||
toast("Removed rules!", 2000, "green lighten");
|
||||
} else {
|
||||
toast("Something went wrong...", 2000, "red lighten");
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
addListener("click", "#remove_thumbnail_button", function(event) {
|
||||
this.preventDefault();
|
||||
var that = event;
|
||||
@@ -558,12 +669,30 @@ function add_to_tab(dest, resp){
|
||||
for(var x = 0; x < resp.length; x++){
|
||||
if(dest == "thumbnails"){
|
||||
document.querySelector("#" + dest + "_cont").insertAdjacentHTML("beforeend", "<div><div class='col s4 m3'>" + decodeChannelName(resp[x].channel) + "</div><input type='text' readonly class='col s4 m6 thumbnail_link' value='" + resp[x].thumbnail + "'><a class='btn green waves-effect col s2 m1 approve_" + dest + "' href='#' data-channel='" + resp[x].channel + "'><i class='material-icons'>check</i></a><a class='btn red waves-effect col s2 m1 deny_" + dest + "' href='#' data-channel='" + resp[x].channel + "'>X</a></div>");
|
||||
} else {
|
||||
} else if(dest == "descriptions"){
|
||||
document.querySelector("#" + dest + "_cont").insertAdjacentHTML("beforeend", "<div><div class='col s4 m3'>" + decodeChannelName(resp[x].channel) + "</div><input type='text' readonly class='col s4 m6' value='" + resp[x].description + "'><a class='btn green waves-effect col s2 m1 approve_" + dest + "' href='#' data-channel='" + resp[x].channel + "'><i class='material-icons'>check</i></a><a class='btn red waves-effect col s2 m1 deny_" + dest + "' href='#' data-channel='" + resp[x].channel + "'>X</a></div>");
|
||||
} else {
|
||||
resp[x].rules = resp[x].rules.replace(/\n/g, " /n\\ ");
|
||||
document.querySelector("#" + dest + "_cont").insertAdjacentHTML("beforeend", "<div><div class='col s4 m3'>" + decodeChannelName(resp[x].channel) + "</div><input type='text' readonly class='col s4 m6' value='" + resp[x].rules + "'><a class='btn green waves-effect col s2 m1 approve_" + dest + "' href='#' data-channel='" + resp[x].channel + "'><i class='material-icons'>check</i></a><a class='btn red waves-effect col s2 m1 deny_" + dest + "' href='#' data-channel='" + resp[x].channel + "'>X</a></div>");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function increaseInfo(num) {
|
||||
removeClass(".info-badge", "hide");
|
||||
try {
|
||||
var currentNumber = parseInt(document.querySelector(".info-badge").innerText);
|
||||
if(isNaN(currentNumber)) currentNumber = 0;
|
||||
document.querySelector(".info-badge").innerText = currentNumber + num;
|
||||
currentNumber += num;
|
||||
if(currentNumber <= 0) {
|
||||
addClass(".info-badge", "hide");
|
||||
}
|
||||
} catch(e) {
|
||||
document.querySelector(".info-badge").innerText = 1;
|
||||
}
|
||||
}
|
||||
|
||||
function loaded() {
|
||||
ajax({
|
||||
type: "GET",
|
||||
@@ -625,6 +754,7 @@ function loaded() {
|
||||
document.querySelector("#frontpage_pinned").innerHTML = output_pinned;
|
||||
document.querySelector("#remove_thumbnail").innerHTML = document.querySelector("#frontpage_pinned").cloneNode(true).innerHTML;
|
||||
document.querySelector("#remove_description").innerHTML = document.querySelector("#frontpage_pinned").cloneNode(true).innerHTML;
|
||||
document.querySelector("#remove_rules").innerHTML = document.querySelector("#frontpage_pinned").cloneNode(true).innerHTML;
|
||||
document.querySelector("#delete_list_name").innerHTML = document.querySelector("#frontpage_pinned").cloneNode(true).innerHTML;
|
||||
document.querySelector("#delete_userpass_name").innerHTML = document.querySelector("#frontpage_pinned").cloneNode(true).innerHTML;
|
||||
document.querySelector("#delete_channel_name").innerHTML = document.querySelector("#frontpage_pinned").cloneNode(true).innerHTML;
|
||||
@@ -665,6 +795,7 @@ function loaded() {
|
||||
if(response.length > 0){
|
||||
removeClass(".thumbnails-badge", "hide");
|
||||
document.querySelector(".thumbnails-badge").innerText = response.length;
|
||||
increaseInfo(response.length);
|
||||
}
|
||||
add_to_tab("thumbnails", response);
|
||||
}
|
||||
@@ -680,10 +811,27 @@ function loaded() {
|
||||
if(response.length > 0){
|
||||
removeClass(".descriptions-badge", "hide");
|
||||
document.querySelector(".descriptions-badge").innerText = response.length;
|
||||
increaseInfo(response.length);
|
||||
}
|
||||
add_to_tab("descriptions", response);
|
||||
}
|
||||
});
|
||||
|
||||
ajax({
|
||||
type: "GET",
|
||||
url: "/api/rules",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
success: function(response){
|
||||
if(response.length > 0){
|
||||
removeClass(".rules-badge", "hide");
|
||||
document.querySelector(".rules-badge").innerText = response.length;
|
||||
increaseInfo(response.length);
|
||||
}
|
||||
add_to_tab("rules", response);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function predicate() {
|
||||
|
||||
@@ -25,6 +25,10 @@ a {
|
||||
outline: 0 !important;
|
||||
}
|
||||
|
||||
.initial-line-height {
|
||||
line-height: initial;
|
||||
}
|
||||
|
||||
.error-code-container {
|
||||
background: lightgrey;
|
||||
border: 1px solid darkgrey;
|
||||
@@ -1362,8 +1366,11 @@ margin:-1px;
|
||||
.suggest-songs:nth-child(odd) {background: rgba(204,204,204,0.40)}
|
||||
.suggest-songs:nth-child(even) {background: #FFF}
|
||||
|
||||
.suggest-songs {
|
||||
.info_change_button_container, .suggest-songs {
|
||||
padding-top:20px;
|
||||
}
|
||||
.suggest-songs {
|
||||
|
||||
border-bottom:1px solid black;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ var Admin = {
|
||||
Admin.logged_in = msg;
|
||||
if(!msg) return;
|
||||
w_p = false;
|
||||
|
||||
M.Modal.init(document.getElementById("channel_info"));
|
||||
if(Admin.logged_in) {
|
||||
Helper.css("#thumbnail_form", "display", "inline-block");
|
||||
Helper.css("#description_form", "display", "inline-block");
|
||||
@@ -179,15 +179,34 @@ var Admin = {
|
||||
Helper.addClass(".change_user_pass", "hide");
|
||||
//Crypt.remove_userpass(chan.toLowerCase());
|
||||
}
|
||||
var updated = false;
|
||||
|
||||
if(conf_array.thumbnail != undefined && conf_array.thumbnail != "") {
|
||||
document.getElementById("thumbnail_image").innerHTML = "<img id='thumbnail_image_channel' src='" + conf_array.thumbnail + "' alt='thumbnail' />";
|
||||
document.getElementById("thumbnail_input").value = conf_array.thumbnail;
|
||||
updated = true;
|
||||
}
|
||||
|
||||
if(conf_array.description != undefined && conf_array.description != "") {
|
||||
document.getElementById("description_area").innerHTML = conf_array.description;
|
||||
document.getElementById("description_input").value = conf_array.description;
|
||||
updated = true;
|
||||
}
|
||||
|
||||
if(conf_array.rules != undefined && conf_array.rules != "") {
|
||||
var existingRules = document.querySelector(".rules-container");
|
||||
if(existingRules) existingRules.remove();
|
||||
var rules = conf_array.rules.split("\n");
|
||||
var elementToAdd = "<li class='rules-container'><div class='row'><div class='col s10 offset-s1'><h4 class='center-align'>Rules</h4>";
|
||||
for(var i = 0; i < rules.length; i++) {
|
||||
elementToAdd += "<p class='initial-line-height'>" + rules[i] + "</p>";
|
||||
}
|
||||
elementToAdd += "</div></div>";
|
||||
document.querySelector(".channel_info_container").insertAdjacentHTML("afterend", elementToAdd);
|
||||
document.getElementById("rules_input").value = conf_array.rules;
|
||||
updated = true;
|
||||
}
|
||||
if(updated) M.updateTextFields();
|
||||
},
|
||||
|
||||
submitAdmin: function(form, userpass_changed) {
|
||||
|
||||
@@ -21,6 +21,21 @@ function removeAllListeners() {
|
||||
socket.removeEventListener(id);
|
||||
}
|
||||
|
||||
function sendDescription() {
|
||||
emit("suggest_description", {channel: chan, description: document.getElementById("description_input").value});
|
||||
document.getElementById("description_input").value = "";
|
||||
}
|
||||
|
||||
function sendThumbnail() {
|
||||
emit("suggest_thumbnail", {channel: chan, thumbnail: document.getElementById("thumbnail_input").value});
|
||||
document.getElementById("thumbnail_input").value = "";
|
||||
}
|
||||
|
||||
function sendRules() {
|
||||
emit("suggest_rules", {channel: chan, rules: document.getElementById("rules_input").value});
|
||||
document.getElementById("rules_input").value = "";
|
||||
}
|
||||
|
||||
function resizeFunction() {
|
||||
if(chan && !Helper.mobilecheck()){
|
||||
if(document.querySelector("#wrapper") == null) return;
|
||||
@@ -1072,6 +1087,12 @@ function toast(msg, _class) {
|
||||
case "other_list_pass":
|
||||
msg = "The other list has a pass, can't import the songs..";
|
||||
break;
|
||||
case "suggested_rules":
|
||||
msg = "Your rules have been suggested";
|
||||
break;
|
||||
case "rules_denied":
|
||||
msg = "Your rules will be denied";
|
||||
break;
|
||||
case "nolist":
|
||||
msg = "There is no list with that name";
|
||||
break;
|
||||
|
||||
@@ -433,6 +433,11 @@ function addDynamicListeners() {
|
||||
}
|
||||
});
|
||||
|
||||
addListener("click", ".info_change_button", function(event) {
|
||||
this.preventDefault();
|
||||
M.Modal.getInstance(document.querySelector("#channel_info")).open();
|
||||
});
|
||||
|
||||
addListener("click", "#hide-playlist", function(event) {
|
||||
this.preventDefault();
|
||||
fullVideo(!hiddenPlaylist);
|
||||
@@ -506,16 +511,34 @@ function addDynamicListeners() {
|
||||
}
|
||||
});
|
||||
|
||||
addListener("submit", "#thumbnail_form", function(event){
|
||||
addListener("click", ".description_input_send", function(event) {
|
||||
this.preventDefault();
|
||||
emit("suggest_thumbnail", {channel: chan, thumbnail: document.getElementById("chan_thumbnail").value});
|
||||
document.getElementById("chan_thumbnail").value = "";
|
||||
sendDescription();
|
||||
});
|
||||
|
||||
addListener("submit", "#description_form", function(event){
|
||||
addListener("click", ".rules_input_send", function(event) {
|
||||
this.preventDefault();
|
||||
emit("suggest_description", {channel: chan, description: document.getElementById("chan_description").value});
|
||||
document.getElementById("chan_description").value = "";
|
||||
sendRules();
|
||||
});
|
||||
|
||||
addListener("click", ".thumbnail_input_send", function(event) {
|
||||
this.preventDefault();
|
||||
sendThumbnail();
|
||||
});
|
||||
|
||||
addListener("submit", "#thumbnail_input_form", function(event){
|
||||
this.preventDefault();
|
||||
sendThumbnail();
|
||||
});
|
||||
|
||||
addListener("submit", "#description_input_form", function(event){
|
||||
this.preventDefault();
|
||||
sendDescription();
|
||||
});
|
||||
|
||||
addListener("submit", "#rules_input_form", function(event){
|
||||
this.preventDefault();
|
||||
sendRules();
|
||||
});
|
||||
|
||||
addListener("click", "#playpause-overlay", function(){
|
||||
@@ -1639,8 +1662,9 @@ function addDynamicListeners() {
|
||||
document.querySelector("#text-chat-input") != document.activeElement &&
|
||||
document.querySelector("#password") != document.activeElement &&
|
||||
document.querySelector("#user-pass-input") != document.activeElement &&
|
||||
document.querySelector("#chan_thumbnail") != document.activeElement &&
|
||||
document.querySelector("#chan_description") != document.activeElement &&
|
||||
document.querySelector("#thumbnail_input") != document.activeElement &&
|
||||
document.querySelector("#rules_input") != document.activeElement &&
|
||||
document.querySelector("#description_input") != document.activeElement &&
|
||||
document.querySelector("#contact-form-from") != document.activeElement &&
|
||||
document.querySelector("#contact-form-message") != document.activeElement &&
|
||||
document.querySelector("#remote_channel") != document.activeElement &&
|
||||
|
||||
@@ -11,194 +11,219 @@
|
||||
</nav>
|
||||
</header>
|
||||
<main class="container center-align admin_panel">
|
||||
<div class="row">
|
||||
<h2 class="col s11">Admin</h2>
|
||||
<a href="#" id="refresh_all" class="col s1"><h2><i class="material-icons">refresh</i></h2></a>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col s12 m10">
|
||||
<ul class="tabs tabs_admin">
|
||||
<li class="tab col s2"><a class="active" href="#general">General</a></li>
|
||||
<li class="tab col s2"><a href="#api_keys">API<span class="new admin-panel hide"></span></a></li>
|
||||
<li class="tab col s3"><a href="#thumbnails">Thumbnails<span class="new thumbnails-badge badge admin-panel hide"></span></a></li>
|
||||
<li class="tab col s3"><a href="#descriptions">Descriptions<span class="new descriptions-badge badge admin-panel hide"></span></a></li>
|
||||
<li class="tab col s2"><a href="#names">Names</a></li>
|
||||
</ul>
|
||||
<div id="general" class="col s12">
|
||||
<div class="preloader-wrapper big active">
|
||||
<div class="spinner-layer spinner-zoff-only">
|
||||
<div class="circle-clipper left">
|
||||
<div class="circle"></div>
|
||||
</div><div class="gap-patch">
|
||||
<div class="circle"></div>
|
||||
</div><div class="circle-clipper right">
|
||||
<div class="circle"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="channel_things hide">
|
||||
<form id="change_pinned">
|
||||
<div class="row">
|
||||
<div class="input-field col s8 m10">
|
||||
<select id="frontpage_pinned">
|
||||
<option value="" disabled>Channels</option>
|
||||
</select>
|
||||
<label>Change Pinned</label>
|
||||
</div>
|
||||
<div class="col s2">
|
||||
<a href="#" id="change_pinned_button" class="btn green waves-effect">UPDATE</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<form id="delete_list">
|
||||
<div class="row">
|
||||
<div class="input-field col s8 m10">
|
||||
<select id="delete_list_name">
|
||||
<option value="" disabled>Channels</option>
|
||||
</select>
|
||||
<label>Delete Admin</label>
|
||||
</div>
|
||||
<div class="col s2">
|
||||
<a href="#" id="delete_admin_button" class="btn orange waves-effect">UPDATE</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<form id="delete_userpass">
|
||||
<div class="row">
|
||||
<div class="input-field col s8 m10">
|
||||
<select id="delete_userpass_name">
|
||||
<option value="" disabled>Channels</option>
|
||||
</select>
|
||||
<label>Delete Userpass</label>
|
||||
</div>
|
||||
<div class="col s2">
|
||||
<a href="#" id="delete_userpass_button" class="btn blue waves-effect">UPDATE</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<form id="delete_channel">
|
||||
<div class="row">
|
||||
<div class="input-field col s8 m10">
|
||||
<select id="delete_channel_name">
|
||||
<option value="" disabled>Channels</option>
|
||||
</select>
|
||||
<label>Delete Channel</label>
|
||||
</div>
|
||||
<div class="col s2">
|
||||
<a href="#" id="delete_channel_button" class="btn red waves-effect">DELETE</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<div class="row">
|
||||
<h2 class="col s11">Admin</h2>
|
||||
<a href="#" id="refresh_all" class="col s1"><h2><i class="material-icons">refresh</i></h2></a>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col s12 m10">
|
||||
<ul class="tabs tabs_admin">
|
||||
<li class="tab col s3"><a class="active" href="#general">General</a></li>
|
||||
<li class="tab col s3"><a href="#api_keys">API<span class="new admin-panel hide"></span></a></li>
|
||||
<li class="tab col s3"><a href="#info">Info<span class="new info-badge badge admin-panel hide"></span></a></li>
|
||||
<li class="tab col s3"><a href="#names">Names</a></li>
|
||||
</ul>
|
||||
<div id="general" class="col s12">
|
||||
<div class="preloader-wrapper big active">
|
||||
<div class="spinner-layer spinner-zoff-only">
|
||||
<div class="circle-clipper left">
|
||||
<div class="circle"></div>
|
||||
</div><div class="gap-patch">
|
||||
<div class="circle"></div>
|
||||
</div><div class="circle-clipper right">
|
||||
<div class="circle"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="channel_things hide">
|
||||
<form id="change_pinned">
|
||||
<div class="row">
|
||||
<div class="input-field col s8 m10">
|
||||
<select id="frontpage_pinned">
|
||||
<option value="" disabled>Channels</option>
|
||||
</select>
|
||||
<label>Change Pinned</label>
|
||||
</div>
|
||||
<div class="col s2">
|
||||
<a href="#" id="change_pinned_button" class="btn green waves-effect">UPDATE</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<form id="delete_list">
|
||||
<div class="row">
|
||||
<div class="input-field col s8 m10">
|
||||
<select id="delete_list_name">
|
||||
<option value="" disabled>Channels</option>
|
||||
</select>
|
||||
<label>Delete Admin</label>
|
||||
</div>
|
||||
<div class="col s2">
|
||||
<a href="#" id="delete_admin_button" class="btn orange waves-effect">UPDATE</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<form id="delete_userpass">
|
||||
<div class="row">
|
||||
<div class="input-field col s8 m10">
|
||||
<select id="delete_userpass_name">
|
||||
<option value="" disabled>Channels</option>
|
||||
</select>
|
||||
<label>Delete Userpass</label>
|
||||
</div>
|
||||
<div class="col s2">
|
||||
<a href="#" id="delete_userpass_button" class="btn blue waves-effect">UPDATE</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<form id="delete_channel">
|
||||
<div class="row">
|
||||
<div class="input-field col s8 m10">
|
||||
<select id="delete_channel_name">
|
||||
<option value="" disabled>Channels</option>
|
||||
</select>
|
||||
<label>Delete Channel</label>
|
||||
</div>
|
||||
<div class="col s2">
|
||||
<a href="#" id="delete_channel_button" class="btn red waves-effect">DELETE</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="row">
|
||||
<div class="input-field col s8 m10">
|
||||
<input type="text" readonly id="new_token" />
|
||||
<div class="row">
|
||||
<div class="input-field col s8 m10">
|
||||
<input type="text" readonly id="new_token" />
|
||||
</div>
|
||||
<div class="col s2">
|
||||
<a href="#" id="get_token" class="btn waves-effect">TOKEN</a>
|
||||
<a href="#" id="remove_token" class="btn red waves-effect hide">REMOVE</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s2">
|
||||
<a href="#" id="get_token" class="btn waves-effect">TOKEN</a>
|
||||
<a href="#" id="remove_token" class="btn red waves-effect hide">REMOVE</a>
|
||||
<div id="api_keys" class="col s12" style="display:none;">
|
||||
<div class="row header-api-fields">
|
||||
<div class="col s3">
|
||||
Name
|
||||
</div>
|
||||
<div class="col s3">
|
||||
Origin
|
||||
</div>
|
||||
<div class="col s1">
|
||||
Usage
|
||||
</div>
|
||||
<div class="col s1">
|
||||
Limit
|
||||
</div>
|
||||
</div>
|
||||
<div class="row api_token_container" id="api_token_list">
|
||||
<div class="col s3 api_token_name truncate">
|
||||
</div>
|
||||
<div class="col s3 api_token_origin truncate">
|
||||
</div>
|
||||
<div class="col s1 api_token_usage">
|
||||
</div>
|
||||
<input class="api_token_limit col s1" type="number" />
|
||||
<div class="col s1 api_token_activated">
|
||||
<i class="material-icons check hide">check</i>
|
||||
<i class="material-icons uncheck hide">close</i>
|
||||
</div>
|
||||
<a href="#" class="btn waves-effect green col s1 update_api_token"><i class="material-icons check">check</i></a>
|
||||
<a href="#" class="btn waves-effect red col s1 delete_api_token">X</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="api_keys" class="col s12" style="display:none;">
|
||||
<div class="row header-api-fields">
|
||||
<div class="col s3">
|
||||
Name
|
||||
</div>
|
||||
<div class="col s3">
|
||||
Origin
|
||||
</div>
|
||||
<div class="col s1">
|
||||
Usage
|
||||
</div>
|
||||
<div class="col s1">
|
||||
Limit
|
||||
</div>
|
||||
</div>
|
||||
<div class="row api_token_container" id="api_token_list">
|
||||
<div class="col s3 api_token_name truncate">
|
||||
</div>
|
||||
<div class="col s3 api_token_origin truncate">
|
||||
</div>
|
||||
<div class="col s1 api_token_usage">
|
||||
</div>
|
||||
<input class="api_token_limit col s1" type="number" />
|
||||
<div class="col s1 api_token_activated">
|
||||
<i class="material-icons check hide">check</i>
|
||||
<i class="material-icons uncheck hide">close</i>
|
||||
<div id="info" class="col s12" style="display:none;">
|
||||
<div class="row">
|
||||
<div class="col s12 tabs_margin">
|
||||
<ul class="tabs tabs_admin_info">
|
||||
<li class="tab col s4"><a class="active" href="#thumbnails">Thumbnails<span class="new thumbnails-badge badge admin-panel hide"></span></a></li>
|
||||
<li class="tab col s4"><a href="#descriptions">Descriptions<span class="new descriptions-badge badge admin-panel hide"></span></a></li>
|
||||
<li class="tab col s4"><a href="#rules">Rules<span class="new rules-badge badge admin-panel hide"></span></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="thumbnails" class="col s12">
|
||||
<div class="row">
|
||||
<div class="input-field col s8 m10">
|
||||
<select id="remove_thumbnail">
|
||||
<option value="" disabled>Channels</option>
|
||||
</select>
|
||||
<label>Remove Thumbnail</label>
|
||||
</div>
|
||||
<div class="col s2">
|
||||
<a href="#" id="remove_thumbnail_button" class="btn red waves-effect">REMOVE</a>
|
||||
</div>
|
||||
<div id="thumbnails_cont" class="col s12">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="descriptions" class="col s12">
|
||||
<div class="row">
|
||||
<div class="input-field col s8 m10">
|
||||
<select id="remove_description">
|
||||
<option value="" disabled>Channels</option>
|
||||
</select>
|
||||
<label>Remove Description</label>
|
||||
</div>
|
||||
<div class="col s2">
|
||||
<a href="#" id="remove_description_button" class="btn red waves-effect">REMOVE</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="descriptions_cont" class="col s12">
|
||||
</div>
|
||||
</div>
|
||||
<div id="rules" class="col s12">
|
||||
<div class="row">
|
||||
<div class="input-field col s8 m10">
|
||||
<select id="remove_rules">
|
||||
<option value="" disabled>Channels</option>
|
||||
</select>
|
||||
<label>Remove Rules</label>
|
||||
</div>
|
||||
<div class="col s2">
|
||||
<a href="#" id="remove_rules_button" class="btn red waves-effect">REMOVE</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="rules_cont" class="col s12">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a href="#" class="btn waves-effect green col s1 update_api_token"><i class="material-icons check">check</i></a>
|
||||
<a href="#" class="btn waves-effect red col s1 delete_api_token">X</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="thumbnails" class="col s12" style="display:none;">
|
||||
<div class="row">
|
||||
<div class="input-field col s8 m10">
|
||||
<select id="remove_thumbnail">
|
||||
<option value="" disabled>Channels</option>
|
||||
</select>
|
||||
<label>Remove Thumbnail</label>
|
||||
</div>
|
||||
<div class="col s2">
|
||||
<a href="#" id="remove_thumbnail_button" class="btn red waves-effect">REMOVE</a>
|
||||
</div>
|
||||
<div id="thumbnails_cont" class="col s12">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="descriptions" class="col s12" style="display:none;">
|
||||
<div class="row">
|
||||
<div class="input-field col s8 m10">
|
||||
<select id="remove_description">
|
||||
<option value="" disabled>Channels</option>
|
||||
</select>
|
||||
<label>Remove Description</label>
|
||||
</div>
|
||||
<div class="col s2">
|
||||
<a href="#" id="remove_description_button" class="btn red waves-effect">REMOVE</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="descriptions_cont" class="col s12">
|
||||
</div>
|
||||
</div>
|
||||
<div id="names" class="col s12" style="display:none;">
|
||||
<div class="row names-container">
|
||||
<div id="names" class="col s12">
|
||||
<div class="row names-container">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s10 m2 left-align" id="listeners">
|
||||
<div class="row">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s10 m2 left-align" id="listeners">
|
||||
<div class="row">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<footer class="page-footer cursor-default">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col l6 s12">
|
||||
<h5 class="white-text">Zoff</h5>
|
||||
<p class="grey-text text-lighten-4">The shared YouTube and SoundCloud radio</p>
|
||||
<p class="grey-text text-lighten-4">
|
||||
Being built around the YouTube and SoundCloud API
|
||||
it enables the creation of collaborative and shared live playlists,
|
||||
with billions of videos and songs to choose from, all for free and without registration.
|
||||
<br />
|
||||
Enjoy!
|
||||
</p>
|
||||
</div>
|
||||
<div class="col l4 offset-l2 s12 valign-wrapper">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer-copyright">
|
||||
<div class="container">
|
||||
© {{year}}
|
||||
<a href="http://nixo.no">Nixo</a> &
|
||||
<a href="http://kasperrt.no">KasperRT</a>
|
||||
<br>
|
||||
All Rights Reserved.
|
||||
<div class="row">
|
||||
<div class="col l6 s12">
|
||||
<h5 class="white-text">Zoff</h5>
|
||||
<p class="grey-text text-lighten-4">The shared YouTube and SoundCloud radio</p>
|
||||
<p class="grey-text text-lighten-4">
|
||||
Being built around the YouTube and SoundCloud API
|
||||
it enables the creation of collaborative and shared live playlists,
|
||||
with billions of videos and songs to choose from, all for free and without registration.
|
||||
<br />
|
||||
Enjoy!
|
||||
</p>
|
||||
</div>
|
||||
<div class="col l4 offset-l2 s12 valign-wrapper">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer-copyright">
|
||||
<div class="container">
|
||||
© {{year}}
|
||||
<a href="http://nixo.no">Nixo</a> &
|
||||
<a href="http://kasperrt.no">KasperRT</a>
|
||||
<br>
|
||||
All Rights Reserved.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
@@ -48,11 +48,11 @@
|
||||
margin-right: 2px;
|
||||
}
|
||||
|
||||
.tabs_admin{
|
||||
.tabs_admin, .tabs_margin{
|
||||
margin-bottom:20px;
|
||||
}
|
||||
|
||||
.tabs_admin .indicator{
|
||||
.tabs_admin .indicator, .tabs_admin_info .indicator{
|
||||
width: initial !important;
|
||||
background: black !important;
|
||||
}
|
||||
|
||||
@@ -53,6 +53,43 @@
|
||||
<a href="#!" class=" modal-action modal-close waves-effect waves-green btn-flat">Close</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="channel_info" class="modal">
|
||||
<div class="modal-content">
|
||||
<h5>Channel Info</h5>
|
||||
<p>Here you can add a thumbnail for the channel, description or rules. The description and thumbnail will be visible from the frontpage, and the sidebar, but the rules will only be visible from the sidebar when in the channel.</p>
|
||||
<p>Remember, all thumbnails, descriptions and rules has to be approved by a site-administrator before it will be visible to visitors.</p>
|
||||
<div class="row">
|
||||
<form id="thumbnail_input_form" class="col s12">
|
||||
<div class="input-field col s8">
|
||||
<input id="thumbnail_input" name="user-pass" type="text" autocomplete="off" />
|
||||
<label for="thumbnail_input" class="noselect">Thumbnail</label>
|
||||
</div>
|
||||
<a class="col offset-s1 s3 btn waves-effect white-text thumbnail_input_send">Send</a>
|
||||
</form>
|
||||
</div>
|
||||
<div class="row">
|
||||
<form id="description_input_form" class="col s12">
|
||||
<div class="input-field col s8">
|
||||
<input id="description_input" name="user-pass" type="text" autocomplete="off" />
|
||||
<label for="description_input" class="noselect">Description</label>
|
||||
</div>
|
||||
<a class="col offset-s1 s3 btn waves-effect orange white-text description_input_send">Send</a>
|
||||
</form>
|
||||
</div>
|
||||
<div class="row">
|
||||
<form id="rules_input_form" class="col s12">
|
||||
<div class="input-field col s8">
|
||||
<textarea id="rules_input" class="materialize-textarea"></textarea>
|
||||
<label for="rules_input">Rules</label>
|
||||
</div>
|
||||
<a class="col offset-s1 s3 btn waves-effect green white-text rules_input_send">Send</a>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a href="#!" id="abort-channel-login" class="modal-action modal-close waves-effect waves-green btn-flat close-user-password">Close</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="user_password" class="modal">
|
||||
<div class="modal-content">
|
||||
<h5>Locked Channel</h5>
|
||||
|
||||
@@ -8,22 +8,8 @@
|
||||
<div class="collapsible-header bold waves-effect">Channel Info
|
||||
<i class="material-icons">info_outline</i>
|
||||
</div>
|
||||
<div class="collapsible-body">
|
||||
<div class="collapsible-body info_collapsible">
|
||||
<ul>
|
||||
<li>
|
||||
<form id="thumbnail_form" style="display:none;">
|
||||
<div class="input-field col s12 admin-information">
|
||||
<input type="text" placeholder="Channel thumbnail" name="chan_thumbnail" id="chan_thumbnail" autocomplete="off" />
|
||||
</div>
|
||||
</form>
|
||||
</li>
|
||||
<li>
|
||||
<form id="description_form" style="display:none;">
|
||||
<div class="input-field col s12 admin-information">
|
||||
<input type="text" placeholder="Channel description" name="chan_description" id="chan_description" autocomplete="off" maxlength="100" data-length="100" />
|
||||
</div>
|
||||
</form>
|
||||
</li>
|
||||
<li class="channel_info_container">
|
||||
<div id="thumbnail_image">
|
||||
</div>
|
||||
@@ -31,6 +17,11 @@
|
||||
This channel doesn't have a description yet.
|
||||
</div>
|
||||
</li>
|
||||
<li class="white-bg">
|
||||
<div class="row info_change_button_container">
|
||||
<a href="#" class="info_change_button col s8 offset-s2 btn orange waves-effect">Change</a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
@@ -43,6 +43,16 @@ router.route('/api/descriptions').get(function(req, res){
|
||||
}
|
||||
});
|
||||
|
||||
router.route('/api/rules').get(function(req, res){
|
||||
if(req.isAuthenticated()){
|
||||
db.collection("suggested_rules").find(function(err, docs){
|
||||
res.json(docs);
|
||||
});
|
||||
} else {
|
||||
res.send(false);
|
||||
}
|
||||
});
|
||||
|
||||
router.route('/api/approve_thumbnail').post(function(req, res){
|
||||
if(req.isAuthenticated()){
|
||||
var channel = req.body.channel;
|
||||
@@ -72,6 +82,45 @@ router.route('/api/deny_thumbnail').post(function(req, res){
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
router.route('/api/approve_rules').post(function(req, res){
|
||||
if(req.isAuthenticated()){
|
||||
var channel = req.body.channel;
|
||||
db.collection("suggested_rules").find({channel: channel}, function(err, docs){
|
||||
var rules = docs[0].rules;
|
||||
db.collection(channel + "_settings").update({views:{$exists:true}}, {$set:{rules: rules}}, {upsert: true}, function(err, docs){
|
||||
db.collection("suggested_rules").remove({channel: channel}, function(err, docs){
|
||||
res.send(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
res.send(false);
|
||||
}
|
||||
});
|
||||
|
||||
router.route('/api/deny_rules').post(function(req, res){
|
||||
if(req.isAuthenticated()){
|
||||
var channel = req.body.channel;
|
||||
db.collection("suggested_rules").remove({channel: channel},function(err, docs){
|
||||
res.send(true);
|
||||
});
|
||||
} else {
|
||||
res.send(false);
|
||||
}
|
||||
});
|
||||
|
||||
router.route('/api/remove_rules').post(function(req, res){
|
||||
if(req.isAuthenticated()){
|
||||
var channel = req.body.channel;
|
||||
db.collection(channel + "_settings").update({views:{$exists:true}}, {$set:{rules: ""}}, function(err, docs){
|
||||
res.send(true);
|
||||
});
|
||||
} else {
|
||||
res.send(false);
|
||||
}
|
||||
});
|
||||
|
||||
router.route('/api/approve_description').post(function(req, res){
|
||||
if(req.isAuthenticated()){
|
||||
var channel = req.body.channel;
|
||||
|
||||
Reference in New Issue
Block a user