226 lines
6.8 KiB
JavaScript
226 lines
6.8 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 tokeList{
|
|
constructor(){
|
|
this.tokeList = document.querySelector('#profile-tokes');
|
|
this.tokeListLabel = document.querySelector('.profile-toke-count');
|
|
this.tokeListToggleIcon = document.querySelector('#toggle-toke-list');
|
|
|
|
this.setupInput();
|
|
}
|
|
|
|
setupInput(){
|
|
this.tokeListLabel.addEventListener('click', this.toggleTokeList.bind(this));
|
|
}
|
|
|
|
toggleTokeList(){
|
|
if(this.tokeList.checkVisibility()){
|
|
this.tokeList.style.display = "none";
|
|
this.tokeListToggleIcon.classList.replace("bi-caret-down-fill","bi-caret-left-fill");
|
|
}else{
|
|
this.tokeList.style.display = "block";
|
|
this.tokeListToggleIcon.classList.replace("bi-caret-left-fill","bi-caret-down-fill");
|
|
}
|
|
}
|
|
}
|
|
|
|
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 tokeList();
|
|
new passwordResetPrompt();
|
|
new deleteAccountButton(); |