Browse Source

Edit peer start

master
morethanwords 4 years ago
parent
commit
9b92e20968
  1. 58
      src/components/editPeer.ts
  2. 81
      src/components/sidebarLeft/tabs/editProfile.ts
  3. 45
      src/components/sidebarRight/tabs/editGroup.ts
  4. 43
      src/components/sidebarRight/tabs/sharedMedia.ts
  5. 1
      src/index.hbs

58
src/components/editPeer.ts

@ -0,0 +1,58 @@
import { InputFile } from "../layer";
import AvatarEdit from "./avatarEdit";
import AvatarElement from "./avatar";
import InputField from "./inputField";
import ListenerSetter from "../helpers/listenerSetter";
import Button from "./button";
export default class EditPeer {
public nextBtn: HTMLButtonElement;
public uploadAvatar: () => Promise<InputFile>;
public avatarEdit: AvatarEdit;
public avatarElem: AvatarElement;
private inputFields: InputField[];
private listenerSetter: ListenerSetter;
private peerId: number;
constructor(options: {
peerId: number,
inputFields: EditPeer['inputFields'],
listenerSetter: ListenerSetter
}) {
for(let i in options) {
// @ts-ignore
this[i] = options[i];
}
this.nextBtn = Button('btn-circle btn-corner tgico-check');
this.avatarElem = document.createElement('avatar-element') as AvatarElement;
this.avatarElem.classList.add('avatar-placeholder', 'avatar-120');
this.avatarEdit = new AvatarEdit((_upload) => {
this.uploadAvatar = _upload;
this.handleChange();
this.avatarElem.remove();
});
this.avatarElem.setAttribute('peer', '' + this.peerId);
if(!this.avatarElem.parentElement) {
this.avatarEdit.container.append(this.avatarElem);
}
this.inputFields.forEach(inputField => {
this.listenerSetter.add(inputField.input, 'input', this.handleChange);
});
}
public isChanged = () => {
return !!this.uploadAvatar || !!this.inputFields.find(inputField => inputField.isValid());
};
public handleChange = () => {
this.nextBtn.classList.toggle('is-visible', this.isChanged());
};
}

81
src/components/sidebarLeft/tabs/editProfile.ts

@ -1,51 +1,30 @@
import type { InputFile } from "../../../layer";
import appProfileManager from "../../../lib/appManagers/appProfileManager"; import appProfileManager from "../../../lib/appManagers/appProfileManager";
import appUsersManager from "../../../lib/appManagers/appUsersManager"; import appUsersManager from "../../../lib/appManagers/appUsersManager";
import apiManager from "../../../lib/mtproto/mtprotoworker"; import apiManager from "../../../lib/mtproto/mtprotoworker";
import rootScope from "../../../lib/rootScope";
import AvatarElement from "../../avatar";
import InputField from "../../inputField"; import InputField from "../../inputField";
import { SliderSuperTab } from "../../slider"; import { SliderSuperTab } from "../../slider";
import AvatarEdit from "../../avatarEdit";
import Button from "../../button";
import { attachClickEvent } from "../../../helpers/dom"; import { attachClickEvent } from "../../../helpers/dom";
import EditPeer from "../../editPeer";
// TODO: аватарка не поменяется в этой вкладке после изменения почему-то (если поставить в другом клиенте, и потом тут проверить, для этого ещё вышел в чатлист) // TODO: аватарка не поменяется в этой вкладке после изменения почему-то (если поставить в другом клиенте, и потом тут проверить, для этого ещё вышел в чатлист)
export default class AppEditProfileTab extends SliderSuperTab { export default class AppEditProfileTab extends SliderSuperTab {
//private scrollWrapper: HTMLElement;
private nextBtn: HTMLButtonElement;
private firstNameInputField: InputField; private firstNameInputField: InputField;
private lastNameInputField: InputField; private lastNameInputField: InputField;
private bioInputField: InputField; private bioInputField: InputField;
private userNameInputField: InputField; private userNameInputField: InputField;
private userNameInput: HTMLElement; private userNameInput: HTMLElement;
private uploadAvatar: () => Promise<InputFile> = null;
private avatarEdit: AvatarEdit;
private avatarElem: AvatarElement;
private profileUrlContainer: HTMLDivElement; private profileUrlContainer: HTMLDivElement;
private profileUrlAnchor: HTMLAnchorElement; private profileUrlAnchor: HTMLAnchorElement;
private editPeer: EditPeer;
protected init() { protected init() {
this.container.classList.add('edit-profile-container'); this.container.classList.add('edit-profile-container');
this.title.innerText = 'Edit Profile'; this.title.innerText = 'Edit Profile';
//this.scrollWrapper = this.container.querySelector('.scroll-wrapper');
this.nextBtn = Button('btn-circle btn-corner tgico-check');
this.content.append(this.nextBtn);
this.avatarElem = document.createElement('avatar-element') as AvatarElement;
this.avatarElem.classList.add('avatar-placeholder', 'avatar-120');
this.avatarEdit = new AvatarEdit((_upload) => { const inputFields: InputField[] = [];
this.uploadAvatar = _upload;
this.handleChange();
this.avatarElem.remove();
});
this.scrollable.append(this.avatarEdit.container);
{ {
const inputWrapper = document.createElement('div'); const inputWrapper = document.createElement('div');
@ -73,11 +52,20 @@ export default class AppEditProfileTab extends SliderSuperTab {
caption.classList.add('caption'); caption.classList.add('caption');
caption.innerHTML = 'Any details such as age, occupation or city. Example:<br>23 y.o. designer from San Francisco.'; caption.innerHTML = 'Any details such as age, occupation or city. Example:<br>23 y.o. designer from San Francisco.';
inputFields.push(this.firstNameInputField, this.lastNameInputField, this.bioInputField);
this.scrollable.append(inputWrapper, caption); this.scrollable.append(inputWrapper, caption);
} }
this.scrollable.append(document.createElement('hr')); this.scrollable.append(document.createElement('hr'));
this.editPeer = new EditPeer({
peerId: appUsersManager.getSelf().id,
inputFields,
listenerSetter: this.listenerSetter
});
this.content.append(this.editPeer.nextBtn);
this.scrollable.prepend(this.editPeer.avatarEdit.container);
{ {
const h2 = document.createElement('div'); const h2 = document.createElement('div');
h2.classList.add('sidebar-left-h2'); h2.classList.add('sidebar-left-h2');
@ -103,14 +91,12 @@ export default class AppEditProfileTab extends SliderSuperTab {
this.profileUrlContainer = caption.querySelector('.profile-url-container'); this.profileUrlContainer = caption.querySelector('.profile-url-container');
this.profileUrlAnchor = this.profileUrlContainer.lastElementChild as HTMLAnchorElement; this.profileUrlAnchor = this.profileUrlContainer.lastElementChild as HTMLAnchorElement;
inputFields.push(this.userNameInputField);
this.scrollable.append(h2, inputWrapper, caption); this.scrollable.append(h2, inputWrapper, caption);
} }
let userNameLabel = this.userNameInput.nextElementSibling as HTMLLabelElement; let userNameLabel = this.userNameInput.nextElementSibling as HTMLLabelElement;
this.listenerSetter.add(this.firstNameInputField.input, 'input', this.handleChange);
this.listenerSetter.add(this.lastNameInputField.input, 'input', this.handleChange);
this.listenerSetter.add(this.bioInputField.input, 'input', this.handleChange);
this.listenerSetter.add(this.userNameInput, 'input', () => { this.listenerSetter.add(this.userNameInput, 'input', () => {
let value = this.userNameInputField.value; let value = this.userNameInputField.value;
@ -119,7 +105,7 @@ export default class AppEditProfileTab extends SliderSuperTab {
this.userNameInput.classList.remove('valid', 'error'); this.userNameInput.classList.remove('valid', 'error');
userNameLabel.innerText = 'Username (optional)'; userNameLabel.innerText = 'Username (optional)';
this.setProfileUrl(); this.setProfileUrl();
this.handleChange(); this.editPeer.handleChange();
return; return;
} else if(!this.isUsernameValid(value)) { // does not check the last underscore } else if(!this.isUsernameValid(value)) { // does not check the last underscore
this.userNameInput.classList.add('error'); this.userNameInput.classList.add('error');
@ -131,7 +117,7 @@ export default class AppEditProfileTab extends SliderSuperTab {
if(this.userNameInput.classList.contains('error')) { if(this.userNameInput.classList.contains('error')) {
this.setProfileUrl(); this.setProfileUrl();
this.handleChange(); this.editPeer.handleChange();
return; return;
} }
@ -161,13 +147,13 @@ export default class AppEditProfileTab extends SliderSuperTab {
} }
} }
}).then(() => { }).then(() => {
this.handleChange(); this.editPeer.handleChange();
this.setProfileUrl(); this.setProfileUrl();
}); });
}); });
attachClickEvent(this.nextBtn, () => { attachClickEvent(this.editPeer.nextBtn, () => {
this.nextBtn.disabled = true; this.editPeer.nextBtn.disabled = true;
let promises: Promise<any>[] = []; let promises: Promise<any>[] = [];
@ -177,8 +163,8 @@ export default class AppEditProfileTab extends SliderSuperTab {
console.error('updateProfile error:', err); console.error('updateProfile error:', err);
})); }));
if(this.uploadAvatar) { if(this.editPeer.uploadAvatar) {
promises.push(this.uploadAvatar().then(inputFile => { promises.push(this.editPeer.uploadAvatar().then(inputFile => {
appProfileManager.uploadProfilePhoto(inputFile); appProfileManager.uploadProfilePhoto(inputFile);
})); }));
} }
@ -188,7 +174,7 @@ export default class AppEditProfileTab extends SliderSuperTab {
} }
Promise.race(promises).finally(() => { Promise.race(promises).finally(() => {
this.nextBtn.removeAttribute('disabled'); this.editPeer.nextBtn.removeAttribute('disabled');
}); });
}, {listenerSetter: this.listenerSetter}); }, {listenerSetter: this.listenerSetter});
} }
@ -212,34 +198,17 @@ export default class AppEditProfileTab extends SliderSuperTab {
appProfileManager.getProfile(user.id, true).then(userFull => { appProfileManager.getProfile(user.id, true).then(userFull => {
if(userFull.about) { if(userFull.about) {
this.bioInputField.setOriginalValue(userFull.about); this.bioInputField.setOriginalValue(userFull.about);
this.handleChange();
} }
}); });
this.avatarElem.setAttribute('peer', '' + rootScope.myId);
if(!this.avatarElem.parentElement) {
this.avatarEdit.container.append(this.avatarElem);
}
this.uploadAvatar = null;
this.setProfileUrl(); this.setProfileUrl();
this.handleChange(); this.editPeer.handleChange();
} }
public isUsernameValid(username: string) { public isUsernameValid(username: string) {
return ((username.length >= 5 && username.length <= 32) || !username.length) && /^[a-zA-Z0-9_]*$/.test(username); return ((username.length >= 5 && username.length <= 32) || !username.length) && /^[a-zA-Z0-9_]*$/.test(username);
} }
private isChanged() {
return !!this.uploadAvatar
|| this.firstNameInputField.isValid()
|| this.lastNameInputField.isValid()
|| this.bioInputField.isValid()
|| this.userNameInputField.isValid();
}
private setProfileUrl() { private setProfileUrl() {
if(this.userNameInput.classList.contains('error') || !this.userNameInputField.value.length) { if(this.userNameInput.classList.contains('error') || !this.userNameInputField.value.length) {
this.profileUrlContainer.style.display = 'none'; this.profileUrlContainer.style.display = 'none';
@ -250,8 +219,4 @@ export default class AppEditProfileTab extends SliderSuperTab {
this.profileUrlAnchor.href = url; this.profileUrlAnchor.href = url;
} }
} }
private handleChange = () => {
this.nextBtn.classList.toggle('is-visible', this.isChanged());
};
} }

45
src/components/sidebarRight/tabs/editGroup.ts

@ -0,0 +1,45 @@
import { SliderSuperTab } from "../../slider"
import InputField from "../../inputField";
import EditPeer from "../../editPeer";
export default class AppEditGroupTab extends SliderSuperTab {
private groupNameInputField: InputField;
private descriptionInputField: InputField;
private editPeer: EditPeer;
protected init() {
this.container.classList.add('edit-peer-container', 'edit-group-container');
this.title.innerHTML = 'Edit';
const inputFields: InputField[] = [];
{
const inputWrapper = document.createElement('div');
inputWrapper.classList.add('input-wrapper');
this.groupNameInputField = new InputField({
label: 'Group Name',
name: 'group-name',
maxLength: 70
});
this.descriptionInputField = new InputField({
label: 'Description',
name: 'group-description',
maxLength: 64
});
inputWrapper.append(this.groupNameInputField.container, this.descriptionInputField.container);
inputFields.push(this.groupNameInputField, this.descriptionInputField);
this.scrollable.append(inputWrapper);
}
this.editPeer = new EditPeer({
peerId: -1408712018,
inputFields,
listenerSetter: this.listenerSetter
});
this.content.append(this.editPeer.nextBtn);
this.scrollable.prepend(this.editPeer.avatarEdit.container);
}
}

43
src/components/sidebarRight/tabs/sharedMedia.ts

@ -15,6 +15,7 @@ import { attachClickEvent, cancelEvent } from "../../../helpers/dom";
import appSidebarRight from ".."; import appSidebarRight from "..";
import { TransitionSlider } from "../../transition"; import { TransitionSlider } from "../../transition";
import appNotificationsManager from "../../../lib/appManagers/appNotificationsManager"; import appNotificationsManager from "../../../lib/appManagers/appNotificationsManager";
import AppEditGroupTab from "./editGroup";
let setText = (text: string, el: HTMLDivElement) => { let setText = (text: string, el: HTMLDivElement) => {
window.requestAnimationFrame(() => { window.requestAnimationFrame(() => {
@ -34,6 +35,7 @@ let setText = (text: string, el: HTMLDivElement) => {
export default class AppSharedMediaTab implements SliderTab { export default class AppSharedMediaTab implements SliderTab {
public container: HTMLElement; public container: HTMLElement;
public closeBtn: HTMLButtonElement; public closeBtn: HTMLButtonElement;
public editBtn: HTMLElement;
private peerId = 0; private peerId = 0;
private threadId = 0; private threadId = 0;
@ -68,6 +70,7 @@ export default class AppSharedMediaTab implements SliderTab {
this.container = document.getElementById('shared-media-container'); this.container = document.getElementById('shared-media-container');
this.closeBtn = this.container.querySelector('.sidebar-header .btn-icon'); this.closeBtn = this.container.querySelector('.sidebar-header .btn-icon');
this.closeBtn.classList.add('sidebar-close-button'); this.closeBtn.classList.add('sidebar-close-button');
this.editBtn = this.container.querySelector('.sidebar-header .tgico-edit');
this.profileContentEl = this.container.querySelector('.profile-content'); this.profileContentEl = this.container.querySelector('.profile-content');
this.profileElements = { this.profileElements = {
@ -98,8 +101,6 @@ export default class AppSharedMediaTab implements SliderTab {
const rect = this.searchSuper.nav.getBoundingClientRect(); const rect = this.searchSuper.nav.getBoundingClientRect();
if(!rect.width) return; if(!rect.width) return;
//console.log('daddy issues', this.searchSuper.nav.getBoundingClientRect());
const top = rect.top; const top = rect.top;
const isSharedMedia = top <= HEADER_HEIGHT; const isSharedMedia = top <= HEADER_HEIGHT;
closeIcon.classList.toggle('state-back', isSharedMedia); closeIcon.classList.toggle('state-back', isSharedMedia);
@ -108,26 +109,8 @@ export default class AppSharedMediaTab implements SliderTab {
if(!isSharedMedia) { if(!isSharedMedia) {
this.searchSuper.goingHard = {}; this.searchSuper.goingHard = {};
} }
//this.searchSuper.container.style.position = 'relative';
//this.searchSuper.container.style.zIndex = '500';
//this.scroll.container.style.overflowY = isSharedMedia ? 'hidden' : '';
//this.scroll.container.style.zIndex = '1';
//this.searchSuper.tabs[this.searchSuper.type].style.overflowY = isSharedMedia ? '' : 'hidden';
}; };
//this.scroll.container.style.overflowY = 'hidden';
/* this.scroll.container.addEventListener('scroll', (e) => {
this.searchSuper.tabs[this.searchSuper.type].scrollTop = this.scroll.container.scrollTop + 1;
console.log('writings on the wall', e, this.scroll.container.scrollTop, this.searchSuper.scrollable.container.scrollTop);
}); */
/* this.scroll.container.addEventListener('wheel', (e) => {
cancelEvent(e);
this.scroll.scrollTop += e.deltaY;
}); */
const transition = TransitionSlider(this.closeBtn.nextElementSibling as HTMLElement, 'slide-fade', 400, null, false); const transition = TransitionSlider(this.closeBtn.nextElementSibling as HTMLElement, 'slide-fade', 400, null, false);
transition(0); transition(0);
@ -142,6 +125,16 @@ export default class AppSharedMediaTab implements SliderTab {
} }
}); });
attachClickEvent(this.editBtn, (e) => {
if(appPeersManager.isAnyGroup(this.peerId)) {
new AppEditGroupTab(appSidebarRight).open();
} else if(this.peerId > 0) {
} else {
}
});
this.container.prepend(this.closeBtn.parentElement); this.container.prepend(this.closeBtn.parentElement);
this.profileElements.notificationsCheckbox.addEventListener('change', () => { this.profileElements.notificationsCheckbox.addEventListener('change', () => {
@ -175,10 +168,6 @@ export default class AppSharedMediaTab implements SliderTab {
this.setPeerStatusInterval = window.setInterval(this.setPeerStatus, 60e3); this.setPeerStatusInterval = window.setInterval(this.setPeerStatus, 60e3);
/* this.closeBtn.addEventListener('click', () => {
this.toggleSidebar(false);
}); */
this.searchSuper = new AppSearchSuper([{ this.searchSuper = new AppSearchSuper([{
inputFilter: 'inputMessagesFilterPhotoVideo', inputFilter: 'inputMessagesFilterPhotoVideo',
name: 'Media' name: 'Media'
@ -280,6 +269,7 @@ export default class AppSharedMediaTab implements SliderTab {
this.profileElements.notificationsRow.style.display = ''; this.profileElements.notificationsRow.style.display = '';
this.profileElements.notificationsCheckbox.checked = true; this.profileElements.notificationsCheckbox.checked = true;
this.profileElements.notificationsStatus.innerText = 'Enabled'; this.profileElements.notificationsStatus.innerText = 'Enabled';
this.editBtn.style.display = 'none';
this.searchSuper.cleanupHTML(); this.searchSuper.cleanupHTML();
this.searchSuper.selectTab(0, false); this.searchSuper.selectTab(0, false);
@ -381,14 +371,11 @@ export default class AppSharedMediaTab implements SliderTab {
if(peerId === rootScope.myId) title = 'Saved Messages'; if(peerId === rootScope.myId) title = 'Saved Messages';
else title = appPeersManager.getPeerTitle(peerId); else title = appPeersManager.getPeerTitle(peerId);
this.profileElements.name.innerHTML = title; this.profileElements.name.innerHTML = title;
this.editBtn.style.display = '';
this.setPeerStatus(true); this.setPeerStatus(true);
} }
/* onOpen() {
this.scroll.onScroll();
} */
onOpenAfterTimeout() { onOpenAfterTimeout() {
this.scroll.onScroll(); this.scroll.onScroll();
} }

1
src/index.hbs

@ -148,6 +148,7 @@
<div class="transition slide-fade"> <div class="transition slide-fade">
<div class="transition-item"> <div class="transition-item">
<div class="sidebar-header__title">Info</div> <div class="sidebar-header__title">Info</div>
<div class="btn-icon tgico-edit"></div>
<div class="btn-icon tgico-more"></div> <div class="btn-icon tgico-more"></div>
</div> </div>
<div class="transition-item"> <div class="transition-item">

Loading…
Cancel
Save