
Fix chat date blinking Fix displaying sent messages to new dialog Scroll to date bubble if message is bigger than viewport Fix releasing keyboard by inline helper Fix clearing self user Fix displaying sent public poll Update contacts counter in dialogs placeholder Improve multiselect animation Disable lottie icon animations if they're disabled Fix changing mtproto transport during authorization
182 lines
5.8 KiB
TypeScript
182 lines
5.8 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 { SettingSection } from "..";
|
|
import Button from "../../button";
|
|
import Row from "../../row";
|
|
import { Authorization } from "../../../layer";
|
|
import { formatDateAccordingToTodayNew } from "../../../helpers/date";
|
|
import { attachContextMenuListener, openBtnMenu, positionMenu } from "../../misc";
|
|
import ButtonMenu from "../../buttonMenu";
|
|
import apiManager from "../../../lib/mtproto/mtprotoworker";
|
|
import { toast } from "../../toast";
|
|
import AppPrivacyAndSecurityTab from "./privacyAndSecurity";
|
|
import I18n from "../../../lib/langPack";
|
|
import PopupPeer from "../../popups/peer";
|
|
import findUpClassName from "../../../helpers/dom/findUpClassName";
|
|
import { attachClickEvent } from "../../../helpers/dom/clickEvent";
|
|
import toggleDisability from "../../../helpers/dom/toggleDisability";
|
|
|
|
export default class AppActiveSessionsTab extends SliderSuperTab {
|
|
public privacyTab: AppPrivacyAndSecurityTab;
|
|
public authorizations: Authorization.authorization[];
|
|
private menuElement: HTMLElement;
|
|
|
|
protected init() {
|
|
this.header.classList.add('with-border');
|
|
this.container.classList.add('active-sessions-container');
|
|
this.setTitle('SessionsTitle');
|
|
|
|
const Session = (auth: Authorization.authorization) => {
|
|
const row = new Row({
|
|
title: [auth.app_name, auth.app_version].join(' '),
|
|
subtitle: [auth.ip, auth.country].join(' - '),
|
|
clickable: true,
|
|
titleRight: auth.pFlags.current ? undefined : formatDateAccordingToTodayNew(new Date(Math.max(auth.date_active, auth.date_created) * 1000))
|
|
});
|
|
|
|
row.container.dataset.hash = '' + auth.hash;
|
|
|
|
const midtitle = document.createElement('div');
|
|
midtitle.classList.add('row-midtitle');
|
|
midtitle.innerHTML = [auth.device_model, auth.system_version || auth.platform].filter(Boolean).join(', ');
|
|
|
|
row.subtitle.parentElement.insertBefore(midtitle, row.subtitle);
|
|
|
|
return row;
|
|
};
|
|
|
|
const authorizations = this.authorizations.slice();
|
|
|
|
{
|
|
const section = new SettingSection({
|
|
name: 'CurrentSession',
|
|
caption: 'ClearOtherSessionsHelp'
|
|
});
|
|
|
|
const auth = authorizations.findAndSplice(auth => auth.pFlags.current);
|
|
const session = Session(auth);
|
|
|
|
section.content.append(session.container);
|
|
|
|
if(authorizations.length) {
|
|
const btnTerminate = Button('btn-primary btn-transparent danger', {icon: 'stop', text: 'TerminateAllSessions'});
|
|
attachClickEvent(btnTerminate, (e) => {
|
|
new PopupPeer('revoke-session', {
|
|
buttons: [{
|
|
langKey: 'Terminate',
|
|
isDanger: true,
|
|
callback: () => {
|
|
const toggle = toggleDisability([btnTerminate], true);
|
|
apiManager.invokeApi('auth.resetAuthorizations').then(value => {
|
|
//toggleDisability([btnTerminate], false);
|
|
btnTerminate.remove();
|
|
otherSection.container.remove();
|
|
this.privacyTab.updateActiveSessions();
|
|
}, onError).finally(() => {
|
|
toggle();
|
|
});
|
|
}
|
|
}],
|
|
titleLangKey: 'AreYouSureSessionsTitle',
|
|
descriptionLangKey: 'AreYouSureSessions'
|
|
}).show();
|
|
});
|
|
|
|
section.content.append(btnTerminate);
|
|
}
|
|
|
|
this.scrollable.append(section.container);
|
|
}
|
|
|
|
if(!authorizations.length) {
|
|
return;
|
|
}
|
|
|
|
const otherSection = new SettingSection({
|
|
name: 'OtherSessions',
|
|
caption: 'SessionsListInfo'
|
|
});
|
|
|
|
authorizations.forEach(auth => {
|
|
otherSection.content.append(Session(auth).container);
|
|
});
|
|
|
|
this.scrollable.append(otherSection.container);
|
|
|
|
const onError = (err: any) => {
|
|
if(err.type === 'FRESH_RESET_AUTHORISATION_FORBIDDEN') {
|
|
toast(I18n.format('RecentSessions.Error.FreshReset', true));
|
|
}
|
|
};
|
|
|
|
let target: HTMLElement;
|
|
const onTerminateClick = () => {
|
|
const hash = target.dataset.hash;
|
|
|
|
new PopupPeer('revoke-session', {
|
|
buttons: [{
|
|
langKey: 'Terminate',
|
|
isDanger: true,
|
|
callback: () => {
|
|
apiManager.invokeApi('account.resetAuthorization', {hash})
|
|
.then(value => {
|
|
if(value) {
|
|
target.remove();
|
|
this.privacyTab.updateActiveSessions();
|
|
}
|
|
}, onError);
|
|
}
|
|
}],
|
|
titleLangKey: 'AreYouSureSessionTitle',
|
|
descriptionLangKey: 'TerminateSessionText'
|
|
}).show();
|
|
};
|
|
|
|
const element = this.menuElement = ButtonMenu([{
|
|
icon: 'stop',
|
|
text: 'Terminate',
|
|
onClick: onTerminateClick
|
|
}]);
|
|
element.id = 'active-sessions-contextmenu';
|
|
element.classList.add('contextmenu');
|
|
|
|
document.getElementById('page-chats').append(element);
|
|
|
|
attachContextMenuListener(this.scrollable.container, (e) => {
|
|
target = findUpClassName(e.target, 'row');
|
|
if(!target || target.dataset.hash === '0') {
|
|
return;
|
|
}
|
|
|
|
if(e instanceof MouseEvent) e.preventDefault();
|
|
// smth
|
|
if(e instanceof MouseEvent) e.cancelBubble = true;
|
|
|
|
positionMenu(e, element);
|
|
openBtnMenu(element);
|
|
});
|
|
|
|
attachClickEvent(this.scrollable.container, (e) => {
|
|
target = findUpClassName(e.target, 'row');
|
|
if(!target || target.dataset.hash === '0') {
|
|
return;
|
|
}
|
|
|
|
onTerminateClick();
|
|
});
|
|
}
|
|
|
|
onCloseAfterTimeout() {
|
|
if(this.menuElement) {
|
|
this.menuElement.remove();
|
|
}
|
|
|
|
return super.onCloseAfterTimeout();
|
|
}
|
|
}
|