313 lines
10 KiB
TypeScript
313 lines
10 KiB
TypeScript
/*
|
|
* https://github.com/morethanwords/tweb
|
|
* Copyright (C) 2019-2021 Eduard Kuzmenko
|
|
* https://github.com/morethanwords/tweb/blob/master/LICENSE
|
|
*/
|
|
|
|
import {SliderSuperTab} from '../../slider';
|
|
import ButtonMenuToggle from '../../buttonMenuToggle';
|
|
import Button from '../../button';
|
|
import AppPrivacyAndSecurityTab from './privacyAndSecurity';
|
|
import AppGeneralSettingsTab from './generalSettings';
|
|
import AppEditProfileTab from './editProfile';
|
|
import AppChatFoldersTab from './chatFolders';
|
|
import AppNotificationsTab from './notifications';
|
|
import AppLanguageTab from './language';
|
|
import lottieLoader from '../../../lib/rlottie/lottieLoader';
|
|
import PopupPeer from '../../popups/peer';
|
|
import AppDataAndStorageTab from './dataAndStorage';
|
|
import ButtonIcon from '../../buttonIcon';
|
|
import PeerProfile from '../../peerProfile';
|
|
import rootScope from '../../../lib/rootScope';
|
|
import Row from '../../row';
|
|
import AppActiveSessionsTab from './activeSessions';
|
|
import {i18n, LangPackKey} from '../../../lib/langPack';
|
|
import {SliderSuperTabConstructable, SliderSuperTabEventable} from '../../sliderTab';
|
|
import PopupAvatar from '../../popups/avatar';
|
|
import {AccountAuthorizations, Authorization} from '../../../layer';
|
|
import PopupElement from '../../popups';
|
|
import {attachClickEvent} from '../../../helpers/dom/clickEvent';
|
|
import SettingSection from '../../settingSection';
|
|
|
|
export default class AppSettingsTab extends SliderSuperTab {
|
|
private buttons: {
|
|
edit: HTMLButtonElement,
|
|
folders: HTMLButtonElement,
|
|
general: HTMLButtonElement,
|
|
notifications: HTMLButtonElement,
|
|
storage: HTMLButtonElement,
|
|
privacy: HTMLButtonElement,
|
|
} = {} as any;
|
|
private profile: PeerProfile;
|
|
|
|
private languageRow: Row;
|
|
private devicesRow: Row;
|
|
|
|
private authorizations: Authorization.authorization[];
|
|
private getAuthorizationsPromise: Promise<AccountAuthorizations.accountAuthorizations>;
|
|
|
|
public async init() {
|
|
this.container.classList.add('settings-container');
|
|
this.setTitle('Settings');
|
|
|
|
const btnMenu = ButtonMenuToggle({
|
|
listenerSetter: this.listenerSetter,
|
|
direction: 'bottom-left',
|
|
buttons: [{
|
|
icon: 'logout',
|
|
text: 'EditAccount.Logout',
|
|
onClick: () => {
|
|
new PopupPeer('logout', {
|
|
titleLangKey: 'LogOut',
|
|
descriptionLangKey: 'LogOut.Description',
|
|
buttons: [{
|
|
langKey: 'LogOut',
|
|
callback: () => {
|
|
this.managers.apiManager.logOut();
|
|
},
|
|
isDanger: true
|
|
}]
|
|
}).show();
|
|
}
|
|
}]
|
|
});
|
|
|
|
this.buttons.edit = ButtonIcon('edit');
|
|
|
|
this.header.append(this.buttons.edit, btnMenu);
|
|
|
|
this.profile = new PeerProfile(this.managers, this.scrollable, this.listenerSetter, false);
|
|
this.profile.init();
|
|
this.profile.setPeer(rootScope.myId);
|
|
const fillPromise = this.profile.fillProfileElements();
|
|
|
|
const changeAvatarBtn = Button('btn-circle btn-corner z-depth-1 profile-change-avatar', {icon: 'cameraadd'});
|
|
attachClickEvent(changeAvatarBtn, () => {
|
|
const canvas = document.createElement('canvas');
|
|
PopupElement.createPopup(PopupAvatar).open(canvas, (upload) => {
|
|
upload().then((inputFile) => {
|
|
return this.managers.appProfileManager.uploadProfilePhoto(inputFile);
|
|
});
|
|
});
|
|
}, {listenerSetter: this.listenerSetter});
|
|
this.profile.element.lastElementChild.firstElementChild.append(changeAvatarBtn);
|
|
|
|
const updateChangeAvatarBtn = async() => {
|
|
const user = await this.managers.appUsersManager.getSelf();
|
|
changeAvatarBtn.classList.toggle('hide', user.photo?._ !== 'userProfilePhoto');
|
|
};
|
|
|
|
updateChangeAvatarBtn();
|
|
this.listenerSetter.add(rootScope)('avatar_update', ({peerId}) => {
|
|
if(rootScope.myId === peerId) {
|
|
updateChangeAvatarBtn();
|
|
}
|
|
});
|
|
|
|
/* const div = document.createElement('div');
|
|
//div.style.cssText = 'border-radius: 8px; overflow: hidden; width: 396px; height: 264px; flex: 0 0 auto; position: relative; margin: 10rem 0 10rem auto;';
|
|
//div.style.width = '135px';
|
|
//div.style.height = '100px';
|
|
div.style.cssText = 'border-radius: 8px; overflow: hidden; width: 396px; height: 264px; flex: 0 0 auto; position: relative; margin: 10rem auto 10rem 0;';
|
|
div.style.width = '135px';
|
|
div.style.height = '100px';
|
|
|
|
const img = document.createElement('img');
|
|
img.src = 'assets/img/pepe.jpg';
|
|
img.classList.add('media-photo');
|
|
img.style.cssText = 'max-width: 100%;max-height: 100%;';
|
|
|
|
div.append(img);
|
|
|
|
div.addEventListener('click', () => {
|
|
new AppMediaViewer().setSearchContext({peerId: 61004386, inputFilter: 'inputMessagesFilterPhotos'}).openMedia({
|
|
_: 'message',
|
|
mid: 1,
|
|
peerId: 61004386,
|
|
fromId: 61004386,
|
|
message: '',
|
|
media: {
|
|
_: 'messageMediaPhoto',
|
|
photo: {
|
|
_: 'photo',
|
|
url: img.src,
|
|
downloaded: 111,
|
|
sizes: [{
|
|
_: 'photoSize',
|
|
type: 'x',
|
|
w: 618,
|
|
h: 412
|
|
}]
|
|
}
|
|
},
|
|
date: Date.now() / 1000 | 0
|
|
}, img);
|
|
});
|
|
|
|
this.scrollable.append(div); */
|
|
|
|
const buttonsDiv = document.createElement('div');
|
|
buttonsDiv.classList.add('profile-buttons');
|
|
|
|
type ConstructorP<T> = T extends {
|
|
new (...args: any[]): infer U;
|
|
} ? U : never;
|
|
|
|
const m = <T extends SliderSuperTabConstructable>(
|
|
icon: string,
|
|
text: LangPackKey,
|
|
c: T,
|
|
getInitArgs?: () => Promise<Parameters<ConstructorP<T>['init']>>
|
|
): {
|
|
icon: string,
|
|
text: LangPackKey,
|
|
tabConstructor: T,
|
|
getInitArgs?: typeof getInitArgs,
|
|
// args?: ReturnType<typeof getInitArgs>
|
|
args?: any
|
|
} => {
|
|
if(!getInitArgs) {
|
|
const g = (c as any as typeof SliderSuperTab).getInitArgs;
|
|
if(g) {
|
|
// @ts-ignore
|
|
getInitArgs = () => [g(this)];
|
|
}
|
|
}
|
|
|
|
return {
|
|
icon,
|
|
text,
|
|
tabConstructor: c,
|
|
getInitArgs,
|
|
args: getInitArgs?.()
|
|
};
|
|
};
|
|
|
|
// const k = <T extends SliderSuperTabConstructable>(c: T): () => [ReturnType<ConstructorP<T>['getInitArgs']>] => {
|
|
// return () => (c as any).getInitArgs(this);
|
|
// };
|
|
|
|
const b = [
|
|
m('unmute', 'AccountSettings.Notifications', AppNotificationsTab),
|
|
m('data', 'DataSettings', AppDataAndStorageTab),
|
|
m('lock', 'AccountSettings.PrivacyAndSecurity', AppPrivacyAndSecurityTab),
|
|
m('settings', 'Telegram.GeneralSettingsViewController', AppGeneralSettingsTab),
|
|
m('folder', 'AccountSettings.Filters', AppChatFoldersTab)
|
|
];
|
|
|
|
const rows = b.map((item) => {
|
|
const {icon, text: langPackKey, tabConstructor, getInitArgs} = item;
|
|
return new Row({
|
|
titleLangKey: langPackKey,
|
|
icon,
|
|
clickable: async() => {
|
|
const args = item.args ? await item.args : [];
|
|
const tab = this.slider.createTab(tabConstructor as any);
|
|
tab.open(...args);
|
|
|
|
if(tab instanceof SliderSuperTabEventable && getInitArgs) {
|
|
tab.eventListener.addEventListener('destroyAfter', (promise) => {
|
|
item.args = promise.then(() => getInitArgs() as any);
|
|
});
|
|
}
|
|
},
|
|
listenerSetter: this.listenerSetter
|
|
});
|
|
});
|
|
|
|
const languageArgs = AppLanguageTab.getInitArgs();
|
|
rows.push(
|
|
this.devicesRow = new Row({
|
|
titleLangKey: 'Devices',
|
|
titleRightSecondary: ' ',
|
|
icon: 'activesessions',
|
|
clickable: async() => {
|
|
if(!this.authorizations) {
|
|
await this.updateActiveSessions();
|
|
}
|
|
|
|
const tab = this.slider.createTab(AppActiveSessionsTab);
|
|
tab.authorizations = this.authorizations;
|
|
tab.eventListener.addEventListener('destroy', () => {
|
|
this.authorizations = undefined;
|
|
this.updateActiveSessions(true);
|
|
}, {once: true});
|
|
tab.open();
|
|
},
|
|
listenerSetter: this.listenerSetter
|
|
}),
|
|
|
|
this.languageRow = new Row({
|
|
titleLangKey: 'AccountSettings.Language',
|
|
titleRightSecondary: i18n('LanguageName'),
|
|
icon: 'language',
|
|
clickable: () => {
|
|
this.slider.createTab(AppLanguageTab).open(languageArgs);
|
|
},
|
|
listenerSetter: this.listenerSetter
|
|
})
|
|
);
|
|
|
|
buttonsDiv.append(...rows.map((row) => row.container));
|
|
|
|
// const profileSection = new SettingSection({fullWidth: true, noPaddingTop: true});
|
|
// profileSection.content.append(this.profile.element);
|
|
|
|
const buttonsSection = new SettingSection();
|
|
buttonsSection.content.append(buttonsDiv);
|
|
|
|
this.scrollable.append(this.profile.element/* profileSection.container */, buttonsSection.container);
|
|
|
|
const getEditProfileArgs = () => {
|
|
editProfileArgs = AppEditProfileTab.getInitArgs();
|
|
};
|
|
let editProfileArgs: ReturnType<typeof AppEditProfileTab['getInitArgs']>;
|
|
attachClickEvent(this.buttons.edit, () => {
|
|
const tab = this.slider.createTab(AppEditProfileTab);
|
|
tab.open(editProfileArgs);
|
|
}, {listenerSetter: this.listenerSetter});
|
|
getEditProfileArgs();
|
|
// this.listenerSetter.add(rootScope)('user_full_update', (userId) => {
|
|
// if(rootScope.myId.toUserId() === userId) {
|
|
// getEditProfileArgs();
|
|
// }
|
|
// });
|
|
this.listenerSetter.add(rootScope)('user_update', (userId) => {
|
|
if(rootScope.myId.toUserId() === userId) {
|
|
getEditProfileArgs();
|
|
}
|
|
});
|
|
|
|
lottieLoader.loadLottieWorkers();
|
|
|
|
this.updateActiveSessions();
|
|
|
|
(await fillPromise)();
|
|
}
|
|
|
|
private getAuthorizations(overwrite?: boolean) {
|
|
if(this.getAuthorizationsPromise && !overwrite) return this.getAuthorizationsPromise;
|
|
|
|
const promise = this.getAuthorizationsPromise = this.managers.apiManager.invokeApi('account.getAuthorizations')
|
|
.finally(() => {
|
|
if(this.getAuthorizationsPromise === promise) {
|
|
this.getAuthorizationsPromise = undefined;
|
|
}
|
|
});
|
|
|
|
return promise;
|
|
}
|
|
|
|
public updateActiveSessions(overwrite?: boolean) {
|
|
return this.getAuthorizations(overwrite).then((auths) => {
|
|
this.authorizations = auths.authorizations;
|
|
this.devicesRow.titleRight.textContent = '' + this.authorizations.length;
|
|
});
|
|
}
|
|
|
|
public onCloseAfterTimeout() {
|
|
this.profile.destroy();
|
|
return super.onCloseAfterTimeout();
|
|
}
|
|
}
|