tweb/src/components/sidebarLeft/editProfile.ts

199 lines
7.4 KiB
TypeScript

import { SliderTab } from "../slider";
import popupAvatar from "../popupAvatar";
import apiManager from "../../lib/mtproto/mtprotoworker";
import appProfileManager from "../../lib/appManagers/appProfileManager";
import appSidebarLeft from "../../lib/appManagers/appSidebarLeft";
import Scrollable from "../scrollable_new";
import appUsersManager from "../../lib/appManagers/appUsersManager";
import { $rootScope } from "../../lib/utils";
import { InputFile } from "../../layer";
// TODO: аватарка не поменяется в этой вкладке после изменения почему-то (если поставить в другом клиенте, и потом тут проверить, для этого ещё вышел в чатлист)
export default class AppEditProfileTab implements SliderTab {
private container = document.querySelector('.edit-profile-container') as HTMLDivElement;
private scrollWrapper = this.container.querySelector('.scroll-wrapper') as HTMLDivElement;
private nextBtn = this.container.querySelector('.btn-corner') as HTMLButtonElement;
private canvas = this.container.querySelector('.avatar-edit-canvas') as HTMLCanvasElement;
private uploadAvatar: () => Promise<InputFile> = null;
private firstNameInput = this.container.querySelector('.firstname') as HTMLInputElement;
private lastNameInput = this.container.querySelector('.lastname') as HTMLInputElement;
private bioInput = this.container.querySelector('.bio') as HTMLInputElement;
private userNameInput = this.container.querySelector('.username') as HTMLInputElement;
private avatarElem = document.createElement('avatar-element');
private profileUrlContainer = this.container.querySelector('.profile-url-container') as HTMLDivElement;
private profileUrlAnchor = this.profileUrlContainer.lastElementChild as HTMLAnchorElement;
private originalValues = {
firstName: '',
lastName: '',
userName: '',
bio: ''
};
constructor() {
this.container.querySelector('.avatar-edit').addEventListener('click', () => {
popupAvatar.open(this.canvas, (_upload) => {
this.uploadAvatar = _upload;
this.handleChange();
this.avatarElem.remove();
});
});
this.avatarElem.classList.add('avatar-placeholder');
let userNameLabel = this.userNameInput.nextElementSibling as HTMLLabelElement;
this.firstNameInput.addEventListener('input', () => this.handleChange());
this.lastNameInput.addEventListener('input', () => this.handleChange());
this.bioInput.addEventListener('input', () => this.handleChange());
this.userNameInput.addEventListener('input', () => {
let value = this.userNameInput.value;
//console.log('userNameInput:', value);
if(value == this.originalValues.userName || !value.length) {
this.userNameInput.classList.remove('valid', 'error');
userNameLabel.innerText = 'Username (optional)';
this.setProfileUrl();
this.handleChange();
return;
} else if(!this.isUsernameValid(value)) { // does not check the last underscore
this.userNameInput.classList.add('error');
this.userNameInput.classList.remove('valid');
userNameLabel.innerText = 'Username is invalid';
} else {
this.userNameInput.classList.remove('valid', 'error');
}
if(this.userNameInput.classList.contains('error')) {
this.setProfileUrl();
this.handleChange();
return;
}
apiManager.invokeApi('account.checkUsername', {
username: value
}).then(available => {
if(this.userNameInput.value != value) return;
if(available) {
this.userNameInput.classList.add('valid');
this.userNameInput.classList.remove('error');
userNameLabel.innerText = 'Username is available';
} else {
this.userNameInput.classList.add('error');
this.userNameInput.classList.remove('valid');
userNameLabel.innerText = 'Username is already taken';
}
}, (err) => {
if(this.userNameInput.value != value) return;
switch(err.type) {
case 'USERNAME_INVALID': {
this.userNameInput.classList.add('error');
this.userNameInput.classList.remove('valid');
userNameLabel.innerText = 'Username is invalid';
break;
}
}
}).then(() => {
this.handleChange();
this.setProfileUrl();
});
});
this.nextBtn.addEventListener('click', () => {
this.nextBtn.disabled = true;
let promises: Promise<any>[] = [];
promises.push(appProfileManager.updateProfile(this.firstNameInput.value, this.lastNameInput.value, this.bioInput.value).then(() => {
appSidebarLeft.selectTab(0);
}, (err) => {
console.error('updateProfile error:', err);
}));
if(this.uploadAvatar) {
promises.push(this.uploadAvatar().then(inputFile => {
appProfileManager.uploadProfilePhoto(inputFile);
}));
}
if(this.userNameInput.value != this.originalValues.userName && this.userNameInput.classList.contains('valid')) {
promises.push(appProfileManager.updateUsername(this.userNameInput.value));
}
Promise.race(promises).then(() => {
this.nextBtn.disabled = false;
}, () => {
this.nextBtn.disabled = false;
});
});
let scrollable = new Scrollable(this.scrollWrapper as HTMLElement);
}
public fillElements() {
let user = appUsersManager.getSelf();
this.firstNameInput.value = this.originalValues.firstName = user.first_name ?? '';
this.lastNameInput.value = this.originalValues.lastName = user.last_name ?? '';
this.userNameInput.value = this.originalValues.userName = user.username ?? '';
this.userNameInput.classList.remove('valid', 'error');
this.userNameInput.nextElementSibling.innerHTML = 'Username (optional)';
appProfileManager.getProfile(user.id).then(userFull => {
if(userFull.rAbout) {
this.bioInput.value = this.originalValues.bio = userFull.rAbout;
}
});
this.avatarElem.setAttribute('peer', '' + $rootScope.myID);
if(!this.avatarElem.parentElement) {
this.canvas.parentElement.append(this.avatarElem);
}
this.uploadAvatar = null;
this.setProfileUrl();
}
public isUsernameValid(username: string) {
return ((username.length >= 5 && username.length <= 32) || !username.length) && /^[a-zA-Z0-9_]*$/.test(username);
}
private isChanged() {
return !!this.uploadAvatar
|| this.firstNameInput.value != this.originalValues.firstName
|| this.lastNameInput.value != this.originalValues.lastName
|| (this.userNameInput.value != this.originalValues.userName && !this.userNameInput.classList.contains('error'))
|| this.bioInput.value != this.originalValues.bio;
}
private setProfileUrl() {
if(this.userNameInput.classList.contains('error') || !this.userNameInput.value.length) {
this.profileUrlContainer.style.display = 'none';
} else {
this.profileUrlContainer.style.display = '';
let url = 'https://t.me/' + this.userNameInput.value;
this.profileUrlAnchor.innerText = url;
this.profileUrlAnchor.href = url;
}
}
private handleChange() {
if(this.isChanged()) {
this.nextBtn.classList.add('is-visible');
} else {
this.nextBtn.classList.remove('is-visible');
}
}
onCloseAfterTimeout() {
this.nextBtn.classList.remove('is-visible');
}
}