257 lines
8.4 KiB
JavaScript
257 lines
8.4 KiB
JavaScript
/*Canopy - The next generation of stoner streaming software
|
|
Copyright (C) 2024 Rainbownapkin and the TTN Community
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU Affero General Public License as
|
|
published by the Free Software Foundation, either version 3 of the
|
|
License, or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU Affero General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Affero General Public License
|
|
along with this program. If not, see <https://www.gnu.org/licenses/>.*/
|
|
|
|
class channelSettingsPage{
|
|
constructor(){
|
|
//Get channel name off of the URL
|
|
this.channel = window.location.pathname.slice(3).replace('/settings','');
|
|
//Instantiate UX handling objects, making sure to pass the channel name.
|
|
this.deleteBtn = new deleteBtn(this.channel);
|
|
this.rankList = new rankList(this.channel);
|
|
this.prefrenceList = new prefrenceList(this.channel);
|
|
this.permList = new permList(this.channel);
|
|
}
|
|
}
|
|
|
|
class rankList{
|
|
constructor(channel){
|
|
this.channel = channel
|
|
this.table = document.querySelector(".admin-list-table");
|
|
this.userPrompt = document.querySelector("#new-rank-input");
|
|
this.rankSelect = document.querySelector("#new-rank-select");
|
|
|
|
//Load the userlist and setup input
|
|
this.loadList();
|
|
this.setupInput();
|
|
}
|
|
|
|
setupInput(){
|
|
this.userPrompt.addEventListener("keydown", this.submitNewRank.bind(this));
|
|
}
|
|
|
|
resetInput(){
|
|
//These change every time the table is refreshed, so we should reset the property as well.
|
|
this.inputs = document.querySelectorAll(".channel-rank-select");
|
|
|
|
this.inputs.forEach((input) => {
|
|
input.addEventListener("change", this.submitUpdate.bind(this));
|
|
});
|
|
}
|
|
|
|
async loadList(){
|
|
const list = await utils.ajax.getChannelRank(this.channel);
|
|
|
|
this.updateList(list);
|
|
}
|
|
|
|
async submitNewRank(event){
|
|
if(event.key != "Enter" && event.key != null){
|
|
//Bail out if we didn't hit enter
|
|
return;
|
|
}
|
|
|
|
//Send new rank
|
|
this.submitUserRank(this.userPrompt.value, this.rankSelect.value);
|
|
|
|
//Clear out prompt
|
|
this.userPrompt.value = "";
|
|
}
|
|
|
|
async submitUpdate(event){
|
|
const user = event.target.id.replace("channel-rank-select-","");
|
|
const rank = event.target.value;
|
|
|
|
await this.submitUserRank(user, rank);
|
|
}
|
|
|
|
async submitUserRank(user, rank){
|
|
await this.updateList(await utils.ajax.setChannelRank(this.channel, user, rank));
|
|
}
|
|
|
|
async updateList(data){
|
|
//If no data
|
|
if(!data){
|
|
//Do not pass go, do not collect $200
|
|
return;
|
|
}
|
|
//Get rank of logged in user
|
|
const curName = document.querySelector("#username").textContent
|
|
const curUser = data[curName];
|
|
const rankEnum = await utils.ajax.getRankEnum();
|
|
|
|
//clear the table
|
|
this.clearTable();
|
|
|
|
Object.entries(data).forEach((userAr) => {
|
|
//pull user object from entry array
|
|
const user = userAr[1];
|
|
|
|
//Create entry row
|
|
const entryRow = document.createElement('tr');
|
|
entryRow.classList.add("admin-list-entry");
|
|
|
|
//Create IMG cell
|
|
const imgCell = document.createElement('td')
|
|
imgCell.classList.add("admin-list-entry","admin-list-entry-item");
|
|
|
|
//Create IMG node inside of IMG cell
|
|
const imgNode = document.createElement('img');
|
|
imgNode.classList.add("admin-list-entry","admin-list-entry-item");
|
|
imgNode.src = user.img;
|
|
|
|
//append Img Node to Img Cell
|
|
imgCell.appendChild(imgNode);
|
|
|
|
//Create ID cell
|
|
const idCell = document.createElement('td');
|
|
idCell.classList.add("admin-list-entry","admin-list-entry-item","admin-list-entry-not-first-col");
|
|
idCell.innerHTML = user.id;
|
|
|
|
//Create Name cell
|
|
const nameCell = document.createElement('td');
|
|
nameCell.classList.add("admin-list-entry","admin-list-entry-item","admin-list-entry-not-first-col");
|
|
nameCell.innerHTML = user.user;
|
|
|
|
//Create Rank cell
|
|
const rankCell = document.createElement('td');
|
|
rankCell.classList.add("admin-list-entry","admin-list-entry-item","admin-list-entry-not-first-col");
|
|
//If the listed user rank is equal or higher than the signed-in user
|
|
if(rankEnum.indexOf(user.rank) >= rankEnum.indexOf(curUser.rank)){
|
|
rankCell.innerHTML = user.rank;
|
|
}else{
|
|
//Create rank select
|
|
const rankSelect = document.createElement('select');
|
|
rankSelect.id = `channel-rank-select-${user.user}`
|
|
rankSelect.classList.add("channel-rank-select")
|
|
|
|
//for each rank in the enum
|
|
rankEnum.slice().reverse().forEach((rank) => {
|
|
//Create an option for the given rank
|
|
const rankOption = document.createElement('option');
|
|
rankOption.value = rank;
|
|
rankOption.innerHTML = rank;
|
|
rankOption.selected = user.rank == rank;
|
|
rankSelect.appendChild(rankOption);
|
|
});
|
|
|
|
//Set value to current user rank and append it to Rank Cell
|
|
rankCell.appendChild(rankSelect);
|
|
}
|
|
|
|
//Append cells to row
|
|
entryRow.appendChild(imgCell);
|
|
entryRow.appendChild(idCell);
|
|
entryRow.appendChild(nameCell);
|
|
entryRow.appendChild(rankCell);
|
|
|
|
//Append row to table
|
|
this.table.appendChild(entryRow);
|
|
|
|
//reset input events
|
|
this.resetInput();
|
|
});
|
|
}
|
|
|
|
clearTable(){
|
|
//get all non-title table rows
|
|
const rows = this.table.querySelectorAll("tr.admin-list-entry");
|
|
|
|
//for each row
|
|
rows.forEach((row) => {
|
|
//The Lord Yeeteth, and The Lord Yoinketh away...
|
|
row.remove();
|
|
});
|
|
}
|
|
}
|
|
|
|
class prefrenceList{
|
|
constructor(channel){
|
|
this.channel = channel;
|
|
this.inputs = document.querySelectorAll(".channel-preference-list-item");
|
|
}
|
|
|
|
setupInput(){
|
|
this.inputs.forEach((input) => {
|
|
input.addEventListener("change", this.submitUpdate.bind(this));
|
|
});
|
|
}
|
|
|
|
async submitUpdate(event){
|
|
const key = event.target.id.replace("channel-preference-","");
|
|
const value = event.target.checked;
|
|
const settingsMap = new Map([
|
|
[key, value]
|
|
]);
|
|
|
|
this.handleUpdate(await utils.ajax.setChannelSetting(this.channel, settingsMap), event.target, key);
|
|
}
|
|
|
|
handleUpdate(data, target, key){
|
|
if(data){
|
|
target = data[key];
|
|
}
|
|
}
|
|
}
|
|
|
|
class deleteBtn{
|
|
constructor(channel){
|
|
this.channel = channel;
|
|
this.delete = document.querySelector("#channel-delete");
|
|
|
|
this.delete.addEventListener('click', this.promptDelete.bind(this));
|
|
}
|
|
|
|
promptDelete(){
|
|
var confirm = window.prompt(`Warning: You are about to nuke ${this.channel} off of the face of the fucking planet, no taksie-backsies. \n \n Type in ${this.channel} to confirm.`);
|
|
this.deleteChannel(confirm);
|
|
}
|
|
|
|
async deleteChannel(confirm){
|
|
if(this.channel === confirm){
|
|
utils.ajax.deleteChannel(this.channel, confirm);
|
|
}
|
|
}
|
|
}
|
|
|
|
class permList{
|
|
constructor(channel){
|
|
this.channel = channel
|
|
this.inputs = document.querySelectorAll(".channel-perm-select");
|
|
this.setupInput();
|
|
}
|
|
|
|
setupInput(){
|
|
this.inputs.forEach((input) => {
|
|
input.addEventListener("change", this.submitUpdate.bind(this));
|
|
});
|
|
}
|
|
|
|
async submitUpdate(event){
|
|
const key = event.target.id.replace("admin-perm-list-rank-select-","");
|
|
const value = event.target.value;
|
|
const permMap = new Map([
|
|
[key, value]
|
|
]);
|
|
|
|
this.handleUpdate(await utils.ajax.setChannelPermissions(this.channel, permMap), event.target, key);
|
|
}
|
|
|
|
handleUpdate(data, target, key){
|
|
target.value = data[key];
|
|
}
|
|
}
|
|
|
|
new channelSettingsPage(); |