177 lines
5.6 KiB
JavaScript
177 lines
5.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");
|
|
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 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.");
|
|
await utils.ajax.deleteAccount(pass);
|
|
}
|
|
}
|
|
|
|
//Object Instantiation
|
|
new profileTextEditPrompt("signature");
|
|
new profileTextEditPrompt("bio", true);
|
|
new profileImgEditPrompt();
|
|
new passwordResetPrompt();
|
|
new deleteAccountPrompt(); |