42_ft_transcendence/frontend/static/js/views/SettingsView.js

227 lines
8.0 KiB
JavaScript

import { client, navigateTo } from '../index.js';
import { clear, fill_errors } from '../utils/formUtils.js';
import AbstractAuthenticatedView from './abstracts/AbstractAuthenticatedView.js';
export default class extends AbstractAuthenticatedView
{
constructor(params)
{
super(params, 'Settings');
this.PROFILE_PICTURE_MAX_SIZE = 2 * 1024 * 1024; // 2MB
}
async postInit()
{
this.avatarInit();
this.usernameInit();
// document.getElementById('delete-account-button').onclick = () => this.delete_account();
}
usernameInit() {
const usernameInput = document.getElementById('usernameInput');
const usernameSave = document.getElementById('usernameSave');
usernameInput.oninput = e => {
const value = e.target.value;
if (value != client.me.username && value.length)
usernameSave.classList.remove('disabled');
else
usernameSave.classList.add('disabled');
}
usernameSave.onclick = _ => this.saveUsername();
}
avatarInit() {
const avatar = document.getElementById('avatar');
const avatarInput = document.getElementById('avatarInput');
const avatarUpload = document.getElementById('avatarUpload');
const avatarDelete = document.getElementById('avatarDelete');
avatar.onclick = _ => avatarInput.click();
avatarInput.onchange = function () {
const selectedFile = this.files[0];
if (!selectedFile)
return;
avatar.src = URL.createObjectURL(selectedFile);
avatarUpload.classList.remove('d-none');
}
avatarUpload.onclick = _ => this.saveAvatar();
avatarDelete.onclick = _ => this.deleteAvatar();
}
async displayAvatar() {
let avatar = document.getElementById('avatar');
avatar.src = client.me.avatar_url + '?t=' + new Date().getTime();
console.log(avatar.src);
}
async delete_account()
{
let current_password = document.getElementById('current_password-input').value;
let response_data = await client.account.delete(current_password);
if (response_data === null || response_data === 'user deleted')
{
navigateTo('/login');
return;
}
clear('innerHTML', ['current_password-input']);
fill_errors({'current_password-input': response_data.password}, 'innerHTML');
}
async save_account()
{
let username = document.getElementById('username-input').value;
let new_password = document.getElementById('new_password-input').value;
let current_password = document.getElementById('current_password-input').value;
let data = {};
data.username = username;
if (new_password.length != 0)
data.new_password = new_password;
let response_data = await client.account.update(data, current_password);
if (response_data === null)
{
navigateTo('/login');
return;
}
if (response_data === 'data has been alterate')
response_data = {'save-account': 'saved'};
clear('innerHTML', ['username', 'new_password', 'current_password', 'save-account', 'delete-account']);
fill_errors(response_data, 'innerHTML');
}
async saveUsername()
{
const usernameInput = document.getElementById('usernameInput');
const username = usernameInput.value;
const usernameDetail = document.getElementById('usernameDetail');
if (!username.length || username === client.me.username)
return;
const error = await client.account.updateUsername(username);
if (!error) {
usernameDetail.classList.remove('text-danger');
usernameDetail.classList.add('text-success');
usernameDetail.innerHTML = 'Username Saved.';
setTimeout(_ => usernameDetail.innerHTML = '', 2000);
document.getElementById('usernameSave').classList.add('disabled');
} else {
usernameDetail.classList.remove('text-success');
usernameDetail.classList.add('text-danger');
usernameDetail.innerHTML = error;
document.getElementById('usernameSave').classList.add('disabled');
console.log(error);
}
}
async saveAvatar()
{
const avatarInput = document.getElementById('avatarInput');
const selectedFile = avatarInput.files[0];
const avatarDetail = document.getElementById('avatarDetail');
if (!selectedFile)
return;
if (selectedFile.size > this.PROFILE_PICTURE_MAX_SIZE) {
avatarDetail.classList.remove('text-success');
avatarDetail.classList.add('text-danger');
avatarDetail.innerHTML = 'Image is too large.'; //to translate
return;
}
const error = await client.me.changeAvatar(selectedFile);
if (!error) {
avatarDetail.classList.remove('text-danger');
avatarDetail.classList.add('text-success');
avatarDetail.innerHTML = 'Avatar saved.'; //to translate
setTimeout(_ => avatarDetail.innerHTML = '', 2000);
document.getElementById('avatarDelete').classList.remove('d-none');
document.getElementById('avatarUpload').classList.add('d-none');
avatarInput.value = null;
} else {
avatarDetail.classList.remove('text-success');
avatarDetail.classList.add('text-danger');
avatarDetail.innerHTML = error.avatar[0];
document.getElementById('avatarUpload').classList.add('d-none');
avatarInput.value = null;
console.log(error);
}
this.displayAvatar();
}
async deleteAvatar() {
const avatarDetail = document.getElementById('avatarDetail');
const error = await client.me.deleteAvatar();
if (!error) {
avatarDetail.classList.remove('text-danger');
avatarDetail.classList.add('text-success');
avatarDetail.innerHTML = 'Avatar deleted.'; //to translate
setTimeout(_ => avatarDetail.innerHTML = '', 2000);
document.getElementById('avatarDelete').classList.add('d-none');
} else {
avatarDetail.classList.remove('text-success');
avatarDetail.classList.add('text-danger');
avatarDetail.innerHTML = 'Something went wrong.'; //to translate
}
this.displayAvatar();
}
async getHtml()
{
const avatarUnchanged = client.me.avatar_url === '/static/avatars/default.avif';
return /* HTML */ `
<div class='container col-sm-10 col-8 d-flex rounded border border-2 bg-light-subtle py-3'>
<div class='row col-4 bg-body-tertiary border rounded p-2 m-2 d-flex justify-content-center align-items-center'>
<h2 class='border-bottom'>Avatar</h2>
<img id='avatar' class='rounded p-0' src=${client.me.avatar_url} style='cursor: pointer;'>
<input id='avatarInput' class='d-none' type='file' accept='image/*'>
<div class='d-flex gap-2 mt-1 px-0'>
<span class='my-auto ms-1 me-auto' id='avatarDetail'></span>
<button class='btn btn-primary d-none' id='avatarUpload'>Save</button>
<button class='btn btn-danger${avatarUnchanged ? ' d-none' : ''}' id='avatarDelete'>Delete</button>
</div>
</div>
<div class='flex-grow-1'>
<h1 class='border-bottom ps-1 mb-3'>Account</h1>
<div>
<div class='input-group'>
<div class='form-floating'>
<input type='text' class='form-control' id='usernameInput' placeholder='username' value=${client.me.username}>
<label for='usernameInput'>Username</label>
</div>
<button class='input-group-text btn btn-success disabled' id='usernameSave'>Save</button>
</div>
<span class='form-text' id='usernameDetail'></span>
</div>
</div>
</div>
`;
// <input class='form-control' type='text' placeholder='Username' id='username-input' value=${client.me.username}>
// <h1>Settings</h1>
// <input class='form-control d-inline-block' type='text' placeholder='Username' id='username-input' value=${client.me.username}>
// <span id='username'></span>
// <input type=password placeholder='New Password' id='new_password-input'>
// <span id='new_password'></span>
// <input type=password placeholder='Current Password' id='current_password-input'>
// <span id='current_password'></span>
// <input type='button' value='Save Credentials' id='save-account-button'>
// <span id='save-account'></span>
//
// <input type='button' value='Delete Account' id='delete-account-button'>
// <span id='delete-account'></span>
}
}