Compare commits

..

4 commits

13 changed files with 142 additions and 82 deletions

View file

@ -24,6 +24,11 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. %>
</head>
<body>
<%- include('partial/navbar', {user}); %>
<div id="admin-panel-list-container">
<div id="admin-nav-list">
</div>
<div class="admin-panel-container-div">
<h1 class="panel-title"><%= unescape(channel.name) %> - Channel Settings</h1>
<div class="admin-panel-container-div">
<%- include('partial/channelSettings/info.ejs', {unescape, channel}); %>
@ -34,7 +39,8 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. %>
<%- include('partial/channelSettings/tokeCommandList.ejs'); %>
<%- include('partial/channelSettings/emoteList.ejs'); %>
</div>
<button href="javascript:" class="danger-button" id="chan-delete">Delete Channel</button>
</div>
</div>
<footer>
<%- include('partial/scripts', {user}); %>
<script src="/js/popup/banPopup.js"></script>

View file

@ -13,14 +13,15 @@ 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/>. %>
<div class="admin-list-div">
<div class="admin-list-div" id="chan-ban-list">
<h3 id="channel-ban-title">Channel Bans:</h3>
<div class="control-prompt">
<input placeholder="Add Username..." id="new-ban-input" class="control-prompt">
<button id="new-ban-button" class="danger-button">Ban</button>
</div>
<div class="dynamic-container">
<div class="dynamic-container resizable table-container">
<table id="admin-ban-list-table" class="admin-list-table">
<thead>
<tr class="admin-list-entry-title-row">
<td class="admin-list-entry-item admin-list-entry-img-title"><h3>Img</h3></td>
<td id="admin-user-list-entry-id-title" class="admin-list-entry-item not-first-col"><h3>ID</h3></td>
@ -30,6 +31,10 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. %>
<td id="channel-user-list-entry-expiration-date-title" class="admin-list-entry-item not-first-col"><h3>Expires</h3></td>
<td id="channel-user-list-entry-actions-title" class="admin-list-entry-item not-first-col">&nbsp;</td>
</tr>
</thead>
<tbody>
</tbody>
<%# This is getting filled via AJAX since we need to refresh it when new users are added anywho. %>
</table>
</div>

View file

@ -13,7 +13,7 @@ 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/>. %>
<div id="emote-list-div" class="admin-list-div">
<div id="chan-emote-list" class="admin-list-div">
<h3>Emote List:</h3>
<div class="control-prompt">
<%# Probably not the cleanest way to do this but fuggit %>
@ -23,6 +23,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. %>
<div class="control-prompt">
<input placeholder="Emote Link..." id="new-emote-link-input" class="control-prompt">
</div>
<div class="dynamic-container" id="emote-list">
<div class="dynamic-container resizable" id="emote-list">
</div>
</div>

View file

@ -13,7 +13,7 @@ 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/>. %>
<div class="admin-list-div">
<div class="admin-list-div" id="chan-info-list">
<h3 id="channel-info-title">Channel Info:</h3>
<div class="dynamic-container" id="channel-info-div">
<span class="channel-info-span" id="channel-info-thumbnail-span">

View file

@ -13,7 +13,7 @@ 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/>. %>
<div class="admin-list-div">
<div class="admin-list-div" id="chan-perm-list">
<h3> Permissions:</h3>
<div class="dynamic-container">
<form action="javascript:" class="admin-list-field">

View file

@ -13,7 +13,7 @@ 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/>. %>
<div class="admin-list-div">
<div class="admin-list-div" id="chan-settings-list">
<h3>Channel Preferences:</h3>
<div class="dynamic-container">
<form action="javascript:" class="admin-list-field">
@ -45,7 +45,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. %>
<input type="radio" name="streamType" id="channel-preference-list-stream-type-hls" value="livehls" <% if(channel.settings["streamType"] == "livehls"){ %> checked <% }%> >
<label for="channel-preference-list-stream-type-hls">Self-Hosted (HLS)</label>
</span>
<input <% if(channel.settings["streamType"] != "livehls"){ %> disabled <%}%> id="channel-preference-list-stream-url" placeholder="Stream URL" value="<%= channel.settings["streamURL"] %>">
<input <% if(channel.settings["streamType"] != "livehls"){ %> disabled <%}%> id="channel-preference-list-stream-url" placeholder="HLS Stream URL" value="<%= channel.settings["streamURL"] %>">
</span>
</span>

View file

@ -13,12 +13,12 @@ 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/>. %>
<div id="toke-command-list-div" class="admin-list-div">
<div id="chan-toke-list" class="admin-list-div">
<h3>Toke Command List:</h3>
<div class="control-prompt">
!<input placeholder="Add Command..." id="new-toke-command-input" class="control-prompt">
<button id="new-toke-command-button" class="positive-button">Add</button>
</div>
<div class="dynamic-container toke-command-list">
<div class="dynamic-container toke-command-list resizable">
</div>
</div>

View file

@ -13,7 +13,7 @@ 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/>. %>
<div class="admin-list-div">
<div class="admin-list-div" id="chan-user-list">
<h3 id="channel-rank-title">Channel Ranks:</h3>
<sup id="channel-rank-sup">Users set to default channel rank 'user' will NOT be listed below.</sup>
<div class="control-prompt">
@ -24,14 +24,18 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. %>
<% }); %>
</select>
</div>
<div class="dynamic-container">
<table class="admin-list-table">
<div class="dynamic-container resizable table-container">
<table class="admin-list-table" id="admin-rank-list-table">
<thead>
<tr class="admin-list-entry-title-row">
<td class="admin-list-entry-item admin-list-entry-img-title"><h3>Img</h3></td>
<td id="admin-user-list-entry-id-title" class="admin-list-entry-item not-first-col"><h3>ID</h3></td>
<td class="admin-list-entry-item not-first-col"><h3>Name</h3></td>
<td id="channel-user-list-entry-rank-title" class="admin-list-entry-item not-first-col"><h3>Rank</h3></td>
</tr>
</thead>
<tbody>
</tbody>
<%# This is getting filled via AJAX since we need to refresh it when new users are added anywho. %>
</table>
</div>

View file

@ -47,7 +47,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. %>
<br>
<br>
<h2>Pros/Cons of WebRTC:</h2>
WebRTC connections come in two flavors, STUN and TURN. STUN uses an intermediary server, to make a connection through your firewall, to another established peer. For certain connections, some users, suchas those on a CGNAT, will require a TURN server to relay the connection. At the current moment, ourfore.st only supplies STUN servers, however we do plan on looking into TURN relay servers in the future.
WebRTC connections come in two flavors, STUN and TURN. STUN uses an intermediary server, to make a connection through your firewall, to another established peer. Some users, such as those on a CGNAT, will require a TURN server to relay the connection.
<br>
<br>
This means that each viewer uses up part of a streamers bandwidth, comparitively to HLS, in which the streaming-server takes the load of multiple connections off of the streamers connection (assuming they're it's not hosted on the same connection.) Furthermore, WebRTC's video-chat roots prioritizes real-time communication over video/audio quality. That being said, WebRTC requires no extra setup, and no extra software other than this website and your browser.

View file

@ -284,7 +284,7 @@ a.admin-list-entry-item{
border-bottom: 1px var(--accent1) solid;
}
#admin-nav-list button:not(.positive-button, :hover){
#admin-nav-list button:not(.positive-button, :hover, .danger-button){
background-color: var(--bg1);
color: var(--accent1);
}

View file

@ -304,7 +304,7 @@ a.admin-list-entry-item{
border-bottom: 1px var(--accent1) solid;
}
#admin-nav-list button:not(.positive-button, :hover){
#admin-nav-list button:not(.positive-button, :hover, .danger-button){
background-image: var(--bg1-gradient);
}

View file

@ -27,7 +27,83 @@ class channelSettingsPage{
this.livestreamPreferences = new livestreamPreferences(this.channel);
this.tokeCommandList = new tokeCommandList(this.channel);
this.emoteList = new emoteList(this.channel);
this.deleteBtn = new deleteBtn(this.channel);
//Setup nav buttons
this.navButtons = new chanAdminNavButtons(this.channel);
}
}
class chanAdminNavButtons{
constructor(channel){
//Take down channel
this.channel = channel;
//Grab nav list
this.navList = document.querySelector("#admin-nav-list");
//Create empty map to do a holdem buttons
this.buttons = new Map();
//Build out options map
this.options = new Map([
["Channel Info", document.querySelector("#chan-info-list")],
["Ranked Users", document.querySelector("#chan-user-list")],
["Bans", document.querySelector("#chan-ban-list")],
["Preferences", document.querySelector("#chan-settings-list")],
["Permissions", document.querySelector("#chan-perm-list")],
["Toke Commands", document.querySelector("#chan-toke-list")],
["Emotes", document.querySelector("#chan-emote-list")],
["Delete Channel", null]
]);
//Render out buttons
this.renderButtons();
//Select the first option in the options map
this.displayOption(Array.from(this.options.keys())[0]);
}
renderButtons(){
//For erry list in the admin panel
for(const option of this.options.keys()){
//Create a button for it
const button = document.createElement('button');
button.innerText = option;
//If this aint the Delete Channel button
if(option != "Delete Channel"){
//Attatch an event listener to handle users clickin' der button
button.addEventListener('click',()=>{this.displayOption(option)});
}else{
//Attatch an event listener to blaire the fuckin' defcon five nukem alarm
button.addEventListener('click', () => {new deleteChannelPopup(this.channel)});
button.classList.add('danger-button');
}
//Drop button in the buttons map
this.buttons.set(option, button);
//Add that shit
this.navList.appendChild(button);
}
}
displayOption(selectedOption){
//For every option
for(const option of this.options.keys()){
//If this is the Delete Channel button
if(option == "Delete Channel"){
//ignorem
break;
}
//If we're on the selected option
if(option == selectedOption){
this.options.get(option).style.display = 'flex';
this.buttons.get(option).classList.add('positive-button');
}else{
this.options.get(option).style.display = 'none';
this.buttons.get(option).classList.remove('positive-button');
}
}
}
}
@ -131,7 +207,7 @@ class chanInfo{
class rankList{
constructor(channel){
this.channel = channel
this.table = document.querySelector(".admin-list-table");
this.tbody = document.querySelector("#admin-rank-list-table tbody");
this.userPrompt = document.querySelector("#new-rank-input");
this.rankSelect = document.querySelector("#new-rank-select");
@ -186,7 +262,7 @@ class rankList{
const rankEnum = await utils.ajax.getRankEnum();
//clear the table
this.clearTable();
this.tbody.innerHTML = "";
//For each user in the list
Object.entries(data).forEach((userAr) => {
@ -220,7 +296,7 @@ class rankList{
}
//Generate row and append to table
this.table.appendChild(utils.ux.newTableRow([
this.tbody.appendChild(utils.ux.newTableRow([
imgNode,
user.id,
user.user,
@ -228,23 +304,12 @@ class rankList{
]));
});
}
clearTable(){
//get all non-title table rows
const rows = this.table.querySelectorAll("tr.gen-row");
//for each row
rows.forEach((row) => {
//The Lord Yeeteth, and The Lord Yoinketh away...
row.remove();
});
}
}
class banList{
constructor(channel){
this.channel = channel;
this.table = document.querySelector("#admin-ban-list-table");
this.tbody = document.querySelector("#admin-ban-list-table tbody");
this.banPrompt = document.querySelector("#new-ban-input");
this.banButton = document.querySelector("#new-ban-button");
@ -261,13 +326,6 @@ class banList{
this.updateList(data);
}
clearList(){
const oldRows = this.table.querySelectorAll('tr.gen-row');
oldRows.forEach((row) => {
row.remove();
});
}
async ban(event){
new chanBanUserPopup(this.channel, this.banPrompt.value, this.updateList.bind(this));
}
@ -284,7 +342,8 @@ class banList{
updateList(bans){
//for each ban listed
this.clearList();
this.tbody.innerHTML = "";
bans.forEach((ban)=>{
//Create IMG node
const imgNode = document.createElement('img');
@ -306,7 +365,7 @@ class banList{
const expirationString = ban.expirationDays < 0 ? "Never" : `${new Date(ban.expirationDate).toDateString()}<br>(${ban.daysUntilExpiration} day(s) left)`;
//Generate row and append to table
this.table.appendChild(utils.ux.newTableRow([
this.tbody.appendChild(utils.ux.newTableRow([
imgNode,
ban.user.id,
ban.user.user,
@ -659,21 +718,7 @@ class emoteList{
}
}
class deleteBtn{
constructor(channel){
this.channel = channel;
this.delete = document.querySelector("#chan-delete");
this.setupInput();
}
setupInput(){
this.delete.addEventListener('click', () => {new deleteAccountPopup(this.channel)});
}
}
class deleteAccountPopup{
class deleteChannelPopup{
constructor(channel){
this.channel = channel;
this.popup = new canopyUXUtils.popup("nukeChannel", true, this.asyncConstructor.bind(this));

View file

@ -16,7 +16,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. -->
<link rel="stylesheet" type="text/css" href="/css/popup/delete.css">
<h3 id="delete-channel-popup-title" class="popup-title">Delete Channel</h3>
<div>
<p id="delete-channel-popup-content">WARNING: You are about to nuke channel '[CHANNEL]' off of the face of the fucking planet.<br>
<p id="delete-channel-popup-content">WARNING: You are about to nuke the channel '[CHANNEL]' off of the face of the fucking planet.<br>
Enter '[CHANNEL]' below to confirm:</p>
<span id="delete-channel-popup-prompt-span">
<input type="text" id="delete-channel-popup-prompt">