tweb/src/components/sidebarLeft/tabs/activeSessions.ts

179 lines
5.7 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.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'
});
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'
});
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();
}
}