import {client, lang, navigateTo} from '../index.js'; import {clearElements, 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(); this.passwordInit(); this.deleteInit(); } deleteInit() { const deleteInput = document.getElementById('deleteInput'); document.getElementById('deleteModal').addEventListener('shown.bs.modal', _ => { deleteInput.focus(); }); deleteInput.onkeydown = e => { if (e.key === 'Enter') this.deleteAccount(); } document.getElementById('deleteButton').onclick = this.deleteAccount; } passwordInit() { document.getElementById('currentPasswordInput').onkeydown = e => { if (e.key === 'Enter') this.savePassword(); }; document.getElementById('newPasswordInput').onkeydown = e => { if (e.key === 'Enter') this.savePassword(); }; document.getElementById('newPassword2Input').onkeydown = e => { if (e.key === 'Enter') this.savePassword(); }; document.getElementById('passwordSave').onclick = this.savePassword; } 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(); } async savePassword() { const currentPasswordInput = document.getElementById('currentPasswordInput'); const currentPassword = currentPasswordInput.value; const currentPasswordDetail = document.getElementById('currentPasswordDetail'); const newPasswordInput = document.getElementById('newPasswordInput'); const newPassword = newPasswordInput.value; const newPasswordDetail = document.getElementById('newPasswordDetail'); const newPassword2Input = document.getElementById('newPassword2Input'); const newPassword2 = newPassword2Input.value; const newPassword2Detail = document.getElementById('newPassword2Detail'); const passwordDetail = document.getElementById('passwordDetail'); clearElements('innerHTML', [currentPasswordDetail, newPasswordDetail, newPassword2Detail, passwordDetail ]); currentPasswordInput.classList.remove('is-invalid'); newPasswordInput.classList.remove('is-invalid'); newPassword2Input.classList.remove('is-invalid'); if (!currentPassword.length) { currentPasswordDetail.innerHTML = lang.get('errorEmptyField'); currentPasswordInput.classList.add('is-invalid'); } if (!newPassword.length) { newPasswordDetail.innerHTML = lang.get('errorEmptyField'); newPasswordInput.classList.add('is-invalid'); } if (!newPassword2.length) { newPassword2Detail.innerHTML = lang.get('errorEmptyField'); newPassword2Input.classList.add('is-invalid'); } if (!currentPassword.length || !newPassword.length || !newPassword2.length) return; const error = await client.account.updatePassword(currentPassword, newPassword, newPassword2); if (!error) { passwordDetail.classList.remove('text-danger'); passwordDetail.classList.add('text-success'); passwordDetail.innerHTML = lang.get('passwordSaved'); setTimeout(_ => passwordDetail.innerHTML = '', 3000); clearElements('value', [currentPasswordInput, newPasswordInput, newPassword2Input]); } else { passwordDetail.classList.add('text-danger'); passwordDetail.classList.remove('text-success'); fill_errors(error, 'innerHTML'); if (error.currentPasswordDetail) currentPasswordInput.classList.add('is-invalid'); if (error.newPasswordDetail) newPasswordInput.classList.add('is-invalid'); if (error.newPassword2Detail) newPassword2Input.classList.add('is-invalid'); } } 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', 'd-none'); usernameDetail.classList.add('text-success'); usernameDetail.innerHTML = 'Username Saved.'; setTimeout(_ => usernameDetail.add('d-none'), 2000); document.getElementById('usernameSave').classList.add('disabled'); } else { usernameDetail.classList.remove('text-success', 'd-none'); 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 deleteAccount() { const passwordInput = document.getElementById('deleteInput'); const password = passwordInput.value; const passwordDetail = document.getElementById('deleteDetail'); passwordInput.classList.remove('is-invalid'); passwordDetail.innerHTML = ''; if (!password.length) { passwordInput.classList.add('is-invalid'); passwordDetail.innerHTML = lang.get('errorEmptyField'); return; } const error = await client.account.delete(password); if (!error) { passwordDetail.classList.replace('text-danger', 'text-success'); passwordDetail.innerHTML = 'Account successfully deleted.'; setTimeout(_ => { bootstrap.Modal.getInstance(document.getElementById('deleteModal')).hide(); navigateTo('/login'); }, 2000); return; } passwordInput.classList.add('is-invalid'); passwordDetail.innerHTML = error['password']; } async getHtml() { const avatarUnchanged = client.me.avatar_url === '/static/avatars/default.avif'; return /* HTML */ `

Avatar

Account settings

Change password
`; } }