/*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 .*/ //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{ displayResponseError(await response.json()); } } } //Object Instantiation new profileTextEditPrompt("signature"); new profileTextEditPrompt("bio", true); new profileImgEditPrompt(); new passwordResetPrompt(); new deleteAccountPrompt();