canopy/www/js/profile.js

201 lines
6 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");
if(this.field == "img"){
this.prompt.placeholder = this.content.src;
}else{
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 updated_content = (await utils.ajax.updateProfile(updateObj))[this.field];
//Update label
if(updated_content != null){
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"){
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 != null){
//Return user homepage after good pass change, as we've probably been logged out by the server for security.
window.location.pathname = '/';
}
}
}
}
}
class deleteAccountButton{
constructor(){
this.deleteLink = document.querySelector('#account-settings-delete-button');
this.setupInput();
}
setupInput(){
this.deleteLink.addEventListener("click",this.deletePrompt.bind(this));
}
async deletePrompt(event){
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);
}
}
}
//Object Instantiation
new profileTextEditPrompt("signature");
new profileTextEditPrompt("bio", true);
new profileImgEditPrompt();
new passwordResetPrompt();
new deleteAccountButton();