canopy/www/js/profile.js
2024-11-17 17:37:07 -05:00

185 lines
5.9 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/>.*/
//Base Class
class profileEditPrompt{
constructor(field, content, useTextArea = false){
this.field = field;
this.useTextArea = useTextArea;
this.content = content;
this.link = document.querySelector(`#profile-${field}-edit`);
//Bail out if something ain't right
if(!this.link || !this.content){
return;
}
this.setupPrompt();
}
setupPrompt(){
if(this.link != null){
this.link.addEventListener("click", this.prompt.bind(this));
}
}
prompt(){
//Create input element
if(this.useTextArea){
this.prompt = document.createElement("textArea");
}else{
this.prompt = document.createElement("input");
}
//Setup properties
this.prompt.id = `profile-${this.field}-prompt`;
this.prompt.classList.add("profile-edit-prompt");
this.prompt.placeholder = this.content.innerHTML;
//Setup event listener
this.prompt.addEventListener("keydown", this.update.bind(this));
//replace label
this.content.replaceWith(this.prompt);
}
async update(event){
if((!event || event.key == "Enter") && this.prompt.value){
//setup object
var updateObj = {};
updateObj[this.field] = this.prompt.value;
//contact server, and collect response
var response = await utils.ajax.updateProfile(updateObj);
var updated_content = (await response.json())[this.field];
//Update label
if(response.status == 200){
if(this.field == "img"){
this.content.src = updated_content;
}else{
this.content.innerHTML = updated_content;
}
}
this.finish();
}else if(event.key == "Escape" || event.key == "Enter"){
console.log(response);
this.finish();
}
}
finish(){
this.prompt.replaceWith(this.content);
}
}
class profileTextEditPrompt extends profileEditPrompt{
constructor(field, useTextArea = false){
//Get content based on field name
var content = document.querySelector(`#profile-${field}-content`);
//Derived Constructor
super(field, content, useTextArea);
}
prompt(){
super.prompt();
}
async update(event){
await super.update(event)
}
}
//Child Classes
class profileImgEditPrompt extends profileEditPrompt{
constructor(){
//Get content based on field name
var content = document.querySelector(`#profile-img`);
//Derived constructor
super("img", content, false);
}
}
class passwordResetPrompt{
constructor(){
this.oldPassNode = document.querySelector('#account-settings-password-reset-old');
this.newPassNode = document.querySelector('#account-settings-password-reset-new');
this.confirmPassNode = document.querySelector('#account-settings-password-reset-confirm');
this.setupInput(this.oldPassNode);
this.setupInput(this.newPassNode);
this.setupInput(this.confirmPassNode);
}
setupInput(node){
if(node != null){
node.addEventListener("keydown", this.update.bind(this));
}
}
async update(event){
var hasVal = (this.oldPassNode.value && this.newPassNode.value && this.confirmPassNode.value);
if((!event || event.key == "Enter") && hasVal){
if(this.newPassNode.value == this.confirmPassNode.value){
const updateObj = {};
updateObj.passChange = {
oldPass: this.oldPassNode.value,
newPass: this.newPassNode.value,
confirmPass: this.confirmPassNode.value
};
const response = await utils.ajax.updateProfile(updateObj);
if(response.status == 200){
//Return user homepage after good pass change, as we've probably been logged out by the server for security.
window.location.pathname = '/';
}
}
}
}
}
class deleteAccountPrompt{
constructor(){
this.deleteLink = document.querySelector('#account-settings-delete-link');
this.setupEvent();
}
setupEvent(){
if(this.deleteLink != null){
this.deleteLink.addEventListener("click",this.deletePrompt);
}
}
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.");
const response = await utils.ajax.deleteAccount(pass);
if(response.status == 200){
window.location.pathname = '/';
}else{
utils.ux.displayResponseError(await response.json());
}
}
}
//Object Instantiation
new profileTextEditPrompt("signature");
new profileTextEditPrompt("bio", true);
new profileImgEditPrompt();
new passwordResetPrompt();
new deleteAccountPrompt();