From ee5a8d95165dc19b07349197e22b3d1e57e910da Mon Sep 17 00:00:00 2001 From: rainbownapkin Date: Thu, 5 Dec 2024 03:46:44 -0500 Subject: [PATCH] Replaced window.prompt()/alert() with custom popup --- src/app/channel/channelManager.js | 6 +-- src/app/channel/connectedUser.js | 2 +- ...serBanController.js => popupController.js} | 6 ++- src/routers/popupRouter.js | 8 +--- src/schemas/channel/channelSchema.js | 42 ++++++++++++------- src/utils/loggerUtils.js | 2 +- .../partial/popup/nukeChannel.ejs} | 18 ++++---- .../partial/popup/nukeUser.ejs} | 18 ++++---- www/css/popup/{userBan.css => ban.css} | 0 www/css/popup/delete.css | 13 ++++++ www/css/theme/movie-night.css | 4 ++ www/js/channel/channel.js | 6 +-- www/js/channelSettings.js | 38 +++++++++++++---- www/js/profile.js | 38 +++++++++++++---- 14 files changed, 138 insertions(+), 63 deletions(-) rename src/controllers/{popup/channelUserBanController.js => popupController.js} (87%) rename src/{controllers/popup/placeholderController.js => views/partial/popup/nukeChannel.ejs} (55%) rename src/{controllers/popup/userBanController.js => views/partial/popup/nukeUser.ejs} (55%) rename www/css/popup/{userBan.css => ban.css} (100%) create mode 100644 www/css/popup/delete.css diff --git a/src/app/channel/channelManager.js b/src/app/channel/channelManager.js index b2e4486..8fb8543 100644 --- a/src/app/channel/channelManager.js +++ b/src/app/channel/channelManager.js @@ -51,9 +51,9 @@ module.exports = class{ if(ban != null){ //Toss out banned user's if(ban.expirationDays < 0){ - socket.emit("kick", {type: "Unauthorized", reason: "You have been permanently banned from this channel!"}); + socket.emit("kick", {type: "Banned", reason: "You have been permanently banned from this channel!"}); }else{ - socket.emit("kick", {type: "Unauthorized", reason: `You have been temporarily banned from this channel, and will be unbanned in ${ban.getDaysUntilExpiration()} day(s)!`}); + socket.emit("kick", {type: "Banned", reason: `You have been temporarily banned from this channel, and will be unbanned in ${ban.getDaysUntilExpiration()} day(s)!`}); } socket.disconnect(); return; @@ -72,7 +72,7 @@ module.exports = class{ } }else{ //Toss out anon's - socket.emit("kick", {type: "Unauthorized", reason: "You must log-in to join this channel!"}); + socket.emit("kick", {type: "Disconnected", reason: "You must log-in to join this channel!"}); socket.disconnect(); return; } diff --git a/src/app/channel/connectedUser.js b/src/app/channel/connectedUser.js index f835a62..b4747cd 100644 --- a/src/app/channel/connectedUser.js +++ b/src/app/channel/connectedUser.js @@ -45,7 +45,7 @@ module.exports = class{ } //generic disconnect function, defaults to kick - disconnect(reason, type = "kick"){ + disconnect(reason, type = "Disconnected"){ this.emit("kick",{type, reason}); this.socketCrawl((socket)=>{socket.disconnect()}); } diff --git a/src/controllers/popup/channelUserBanController.js b/src/controllers/popupController.js similarity index 87% rename from src/controllers/popup/channelUserBanController.js rename to src/controllers/popupController.js index 20b7ae1..f8ef490 100644 --- a/src/controllers/popup/channelUserBanController.js +++ b/src/controllers/popupController.js @@ -16,5 +16,9 @@ along with this program. If not, see .*/ //root index functions module.exports.get = async function(req, res){ - res.render('partial/popup/channelUserBan'); + try{ + res.render(`partial/popup${req.url}`, {}); + }catch(err){ + return res.sendStatus(400); + } } \ No newline at end of file diff --git a/src/routers/popupRouter.js b/src/routers/popupRouter.js index a0efa78..c5b51f9 100644 --- a/src/routers/popupRouter.js +++ b/src/routers/popupRouter.js @@ -19,16 +19,12 @@ const { Router } = require('express'); //local imports -const placeholderController = require("../controllers/popup/placeholderController"); -const userBanController = require("../controllers/popup/userBanController"); -const channelUserBanController = require("../controllers/popup/channelUserBanController"); +const popupController = require("../controllers/popupController"); //globals const router = Router(); //routing functions -router.get('/placeholder', placeholderController.get); -router.get('/userBan', userBanController.get); -router.get('/channelUserBan', channelUserBanController.get); +router.get('/*', popupController.get); module.exports = router; diff --git a/src/schemas/channel/channelSchema.js b/src/schemas/channel/channelSchema.js index 8641e9f..41038ce 100644 --- a/src/schemas/channel/channelSchema.js +++ b/src/schemas/channel/channelSchema.js @@ -127,12 +127,15 @@ channelSchema.pre('save', async function (next){ //if the channel is online if(activeChan != null){ - //Get the relevant user connection - const userConn = activeChan.userList.get(foundRank.user.user); - //if the user is online - if(userConn != null){ - //kick the user - userConn.disconnect("Your channel rank has changed!"); + //make sure we're not trying to kick a deleted user + if(foundRank.user != null){ + //Get the relevant user connection + const userConn = activeChan.userList.get(foundRank.user.user); + //if the user is online + if(userConn != null){ + //kick the user + userConn.disconnect("Your channel rank has changed!"); + } } } } @@ -322,17 +325,24 @@ channelSchema.methods.getRankList = async function(){ await this.populate('rankList.user'); //For each rank object in the rank list - this.rankList.forEach(async (rankObj) => { - //Create a new user object from rank object data - const userObj = { - id: rankObj.user.id, - user: rankObj.user.user, - img: rankObj.user.img, - rank: rankObj.rank - } + this.rankList.forEach(async (rankObj, rankObjIndex) => { + //If the use still exists + if(rankObj.user != null){ + //Create a new user object from rank object data + const userObj = { + id: rankObj.user.id, + user: rankObj.user.user, + img: rankObj.user.img, + rank: rankObj.rank + } - //Add our user object to the list - rankList.set(rankObj.user.user, userObj); + //Add our user object to the list + rankList.set(rankObj.user.user, userObj); + }else{ + //Otherwise clean deleted users out of list + this.rankList.splice(rankObjIndex,1); + await this.save(); + } }); //return userList diff --git a/src/utils/loggerUtils.js b/src/utils/loggerUtils.js index d55db00..fc38e50 100644 --- a/src/utils/loggerUtils.js +++ b/src/utils/loggerUtils.js @@ -28,6 +28,6 @@ module.exports.socketExceptionHandler = function(socket, err){ module.exports.socketCriticalExceptionHandler = function(socket, err){ //if not yell at the browser for fucking up, and tell it what it did wrong. - socket.emit("kick", {type: "error", reason: err.message}); + socket.emit("kick", {type: "Disconnected", reason: `Server Error: ${err.message}`}); return socket.disconnect(); } \ No newline at end of file diff --git a/src/controllers/popup/placeholderController.js b/src/views/partial/popup/nukeChannel.ejs similarity index 55% rename from src/controllers/popup/placeholderController.js rename to src/views/partial/popup/nukeChannel.ejs index 4ed74b6..8a7ad30 100644 --- a/src/controllers/popup/placeholderController.js +++ b/src/views/partial/popup/nukeChannel.ejs @@ -1,4 +1,4 @@ -/*Canopy - The next generation of stoner streaming software + + + +
+

WARNING: You are about to nuke channel '[CHANNEL]' off of the face of the fucking planet.
+ Enter '[CHANNEL]' below to confirm:

+ + + +
\ No newline at end of file diff --git a/src/controllers/popup/userBanController.js b/src/views/partial/popup/nukeUser.ejs similarity index 55% rename from src/controllers/popup/userBanController.js rename to src/views/partial/popup/nukeUser.ejs index 911168d..0d1dd16 100644 --- a/src/controllers/popup/userBanController.js +++ b/src/views/partial/popup/nukeUser.ejs @@ -1,4 +1,4 @@ -/*Canopy - The next generation of stoner streaming software + + + +
+

WARNING: You are about to nuke your account off of the face of the fucking planet.
+ Enter your password below to confirm:

+ + + +
\ No newline at end of file diff --git a/www/css/popup/userBan.css b/www/css/popup/ban.css similarity index 100% rename from www/css/popup/userBan.css rename to www/css/popup/ban.css diff --git a/www/css/popup/delete.css b/www/css/popup/delete.css new file mode 100644 index 0000000..5685f04 --- /dev/null +++ b/www/css/popup/delete.css @@ -0,0 +1,13 @@ + #delete-channel-popup-content, #delete-account-popup-content{ + text-align: center; +} + +#delete-channel-popup-prompt, #delete-account-popup-password{ + width: 75%; + margin: 0 auto; +} + +#delete-channel-popup-prompt-span, #delete-account-popup-password-span{ + display: flex; + flex-direction: column; +} \ No newline at end of file diff --git a/www/css/theme/movie-night.css b/www/css/theme/movie-night.css index 6f10926..2d3c480 100644 --- a/www/css/theme/movie-night.css +++ b/www/css/theme/movie-night.css @@ -305,4 +305,8 @@ select.panel-head-element{ color: var(--accent1); box-shadow: 3px 3px 1px var(--bg1-alt0) inset; border-radius: 1em; +} + +#delete-account-popup-title, #delete-channel-popup-title{ + color: var(--accent0-warning); } \ No newline at end of file diff --git a/www/js/channel/channel.js b/www/js/channel/channel.js index 25b9951..baa1759 100644 --- a/www/js/channel/channel.js +++ b/www/js/channel/channel.js @@ -44,11 +44,7 @@ class channel{ }); this.socket.on("kick", (data) => { - if(data.type == "kick"){ - window.alert(`You have been kicked from the channel for the following reason:\n\n${data.reason}`); - }else{ - window.alert(`You have been disconnceted from the channel by the server!\nType: ${data.type}\nReason: ${data.reason}`); - } + new canopyUXUtils.popup(`You have been ${data.type} from the channel for the following reason:
${data.reason}`); }); this.socket.on("clientMetadata", this.handleClientInfo.bind(this)); diff --git a/www/js/channelSettings.js b/www/js/channelSettings.js index 8d862fc..57989a9 100644 --- a/www/js/channelSettings.js +++ b/www/js/channelSettings.js @@ -335,17 +335,41 @@ class deleteBtn{ this.channel = channel; this.delete = document.querySelector("#channel-delete"); - this.delete.addEventListener('click', this.promptDelete.bind(this)); + this.setupInput(); } - 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); + setupInput(){ + this.delete.addEventListener('click', () => {new deleteAccountPopup(this.channel)}); } - async deleteChannel(confirm){ - if(this.channel === confirm){ - utils.ajax.deleteChannel(this.channel, confirm); +} + +class deleteAccountPopup{ + constructor(channel){ + this.channel = channel; + this.popup = new canopyUXUtils.popup("nukeChannel", true, this.asyncConstructor.bind(this)); + } + + asyncConstructor(){ + this.prompt = document.querySelector("#delete-channel-popup-prompt"); + this.label = document.querySelector("#delete-channel-popup-content"); + + //Fill channel label + this.label.innerHTML = this.label.innerHTML.replaceAll("[CHANNEL]", this.channel); + + this.setupInput(); + } + + setupInput(){ + this.prompt.addEventListener("keydown", this.nukeAccount.bind(this)); + } + + async nukeAccount(event){ + if(event.key == "Enter"){ + console.log(this.channel); + if(this.channel === event.target.value){ + await utils.ajax.deleteChannel(this.channel, event.target.value); + } } } } diff --git a/www/js/profile.js b/www/js/profile.js index ab0abd4..49d85e7 100644 --- a/www/js/profile.js +++ b/www/js/profile.js @@ -155,21 +155,41 @@ class passwordResetPrompt{ } } -class deleteAccountPrompt{ +class deleteAccountButton{ constructor(){ this.deleteLink = document.querySelector('#account-settings-delete-link'); - this.setupEvent(); + + this.setupInput(); } - setupEvent(){ - if(this.deleteLink != null){ - this.deleteLink.addEventListener("click",this.deletePrompt); - } + setupInput(){ + this.deleteLink.addEventListener("click",this.deletePrompt.bind(this)); } async deletePrompt(event){ - const pass = window.prompt("Warning: You are about to nuke your account off of the face of the fucking planet, no taksie-backsies.\n \n (todo: replace with dialog that has obscured password input) \n Enter your password to confirm."); - await utils.ajax.deleteAccount(pass); + this.popup = new deleteAccountPopup(); + } +} + +class deleteAccountPopup{ + constructor(){ + this.popup = new canopyUXUtils.popup("nukeUser", true, this.asyncConstructor.bind(this)); + } + + asyncConstructor(){ + this.passwordPrompt = document.querySelector("#delete-account-popup-password"); + + this.setupInput(); + } + + setupInput(){ + this.passwordPrompt.addEventListener("keydown", this.nukeAccount.bind(this)); + } + + async nukeAccount(event){ + if(event.key == "Enter"){ + await utils.ajax.deleteAccount(event.target.value); + } } } @@ -178,4 +198,4 @@ new profileTextEditPrompt("signature"); new profileTextEditPrompt("bio", true); new profileImgEditPrompt(); new passwordResetPrompt(); -new deleteAccountPrompt(); \ No newline at end of file +new deleteAccountButton(); \ No newline at end of file