Privacy alpha version
This commit is contained in:
parent
521ec5690d
commit
f60d0f82ce
@ -970,7 +970,7 @@ export default class ChatBubbles {
|
|||||||
});
|
});
|
||||||
|
|
||||||
//if(scrolledDown) this.scrollable.scrollTop = this.scrollable.scrollHeight;
|
//if(scrolledDown) this.scrollable.scrollTop = this.scrollable.scrollHeight;
|
||||||
if(this.messagesQueuePromise && scrolledDown) {
|
if(this.messagesQueuePromise && scrolledDown/* && false */) {
|
||||||
if(this.scrollable.isScrolledDown && !this.scrollable.scrollLocked) {
|
if(this.scrollable.isScrolledDown && !this.scrollable.scrollLocked) {
|
||||||
//this.log('renderNewMessagesByIDs: messagesQueuePromise before will set prev max');
|
//this.log('renderNewMessagesByIDs: messagesQueuePromise before will set prev max');
|
||||||
this.scrollable.scrollTo(this.scrollable.scrollHeight - 1, 'top', false, true);
|
this.scrollable.scrollTo(this.scrollable.scrollHeight - 1, 'top', false, true);
|
||||||
|
15
src/components/radioForm.ts
Normal file
15
src/components/radioForm.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
export default function RadioForm(radios: {container: HTMLElement, input: HTMLInputElement}[], onChange: (value: string) => void) {
|
||||||
|
const form = document.createElement('form');
|
||||||
|
|
||||||
|
radios.forEach(r => {
|
||||||
|
const {container, input} = r;
|
||||||
|
form.append(container);
|
||||||
|
input.addEventListener('change', () => {
|
||||||
|
if(input.checked) {
|
||||||
|
onChange(input.value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return form;
|
||||||
|
}
|
83
src/components/row.ts
Normal file
83
src/components/row.ts
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
import CheckboxField from "./checkbox";
|
||||||
|
import RadioField from "./radioField";
|
||||||
|
import { ripple } from "./ripple";
|
||||||
|
import { SliderSuperTab } from "./slider";
|
||||||
|
import RadioForm from "./radioForm";
|
||||||
|
|
||||||
|
export default class Row {
|
||||||
|
public container: HTMLElement;
|
||||||
|
public title: HTMLDivElement;
|
||||||
|
public subtitle: HTMLElement;
|
||||||
|
|
||||||
|
public checkboxField: ReturnType<typeof CheckboxField>;
|
||||||
|
public radioField: ReturnType<typeof RadioField>;
|
||||||
|
|
||||||
|
constructor(options: Partial<{
|
||||||
|
icon: string,
|
||||||
|
subtitle: string,
|
||||||
|
radioField: Row['radioField'],
|
||||||
|
checkboxField: Row['checkboxField'],
|
||||||
|
title: string,
|
||||||
|
clickable: boolean,
|
||||||
|
navigationTab: SliderSuperTab
|
||||||
|
}> = {}) {
|
||||||
|
this.container = document.createElement('div');
|
||||||
|
this.container.classList.add('row');
|
||||||
|
|
||||||
|
this.subtitle = document.createElement('div');
|
||||||
|
this.subtitle.classList.add('row-subtitle');
|
||||||
|
if(options.subtitle) {
|
||||||
|
this.subtitle.innerHTML = options.subtitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
let havePadding = false;
|
||||||
|
if(options.radioField || options.checkboxField) {
|
||||||
|
havePadding = true;
|
||||||
|
if(options.radioField) {
|
||||||
|
this.radioField = options.radioField;
|
||||||
|
this.container.append(this.radioField.label);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(options.checkboxField) {
|
||||||
|
this.checkboxField = options.checkboxField;
|
||||||
|
this.container.append(this.checkboxField.label);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(options.title) {
|
||||||
|
this.title = document.createElement('div');
|
||||||
|
this.title.classList.add('row-title');
|
||||||
|
this.title.innerHTML = options.title;
|
||||||
|
this.container.append(this.title);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(options.icon) {
|
||||||
|
havePadding = true;
|
||||||
|
this.title.classList.add('tgico', 'tgico-' + options.icon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(havePadding) {
|
||||||
|
this.container.classList.add('row-with-padding');
|
||||||
|
}
|
||||||
|
|
||||||
|
if(options.navigationTab) {
|
||||||
|
this.container.addEventListener('click', () => {
|
||||||
|
options.navigationTab.open();
|
||||||
|
});
|
||||||
|
options.clickable = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(options.clickable) {
|
||||||
|
this.container.classList.add('row-clickable', 'hover-effect');
|
||||||
|
ripple(this.container);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.container.append(this.subtitle);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export const RadioFormFromRows = (rows: Row[], onChange: (value: string) => void) => {
|
||||||
|
return RadioForm(rows.map(r => ({container: r.container, input: r.radioField.input})), onChange);
|
||||||
|
};
|
@ -29,16 +29,15 @@ import apiManagerProxy from "../../lib/mtproto/mtprotoworker";
|
|||||||
import AppSearchSuper from "../appSearchSuper.";
|
import AppSearchSuper from "../appSearchSuper.";
|
||||||
import { DateData, fillTipDates } from "../../helpers/date";
|
import { DateData, fillTipDates } from "../../helpers/date";
|
||||||
import AppGeneralSettingsTab from "./tabs/generalSettings";
|
import AppGeneralSettingsTab from "./tabs/generalSettings";
|
||||||
|
import AppPrivacyAndSecurityTab from "./tabs/privacyAndSecurity";
|
||||||
|
|
||||||
const addMembersTab = new AppAddMembersTab();
|
|
||||||
const contactsTab = new AppContactsTab();
|
const contactsTab = new AppContactsTab();
|
||||||
const archivedTab = new AppArchivedTab();
|
const archivedTab = new AppArchivedTab();
|
||||||
|
|
||||||
export class AppSidebarLeft extends SidebarSlider {
|
export class AppSidebarLeft extends SidebarSlider {
|
||||||
public static SLIDERITEMSIDS = {
|
public static SLIDERITEMSIDS = {
|
||||||
archived: 1,
|
archived: 1,
|
||||||
contacts: 2,
|
contacts: 2
|
||||||
addMembers: 3
|
|
||||||
};
|
};
|
||||||
|
|
||||||
private toolsBtn: HTMLButtonElement;
|
private toolsBtn: HTMLButtonElement;
|
||||||
@ -75,6 +74,7 @@ export class AppSidebarLeft extends SidebarSlider {
|
|||||||
public editFolderTab: AppEditFolderTab;
|
public editFolderTab: AppEditFolderTab;
|
||||||
public includedChatsTab: AppIncludedChatsTab;
|
public includedChatsTab: AppIncludedChatsTab;
|
||||||
public generalSettingsTab: AppGeneralSettingsTab;
|
public generalSettingsTab: AppGeneralSettingsTab;
|
||||||
|
public privacyAndSecurityTab: AppPrivacyAndSecurityTab;
|
||||||
|
|
||||||
//private log = logger('SL');
|
//private log = logger('SL');
|
||||||
|
|
||||||
@ -86,8 +86,7 @@ export class AppSidebarLeft extends SidebarSlider {
|
|||||||
|
|
||||||
Object.assign(this.tabs, {
|
Object.assign(this.tabs, {
|
||||||
[AppSidebarLeft.SLIDERITEMSIDS.archived]: archivedTab,
|
[AppSidebarLeft.SLIDERITEMSIDS.archived]: archivedTab,
|
||||||
[AppSidebarLeft.SLIDERITEMSIDS.contacts]: contactsTab,
|
[AppSidebarLeft.SLIDERITEMSIDS.contacts]: contactsTab
|
||||||
[AppSidebarLeft.SLIDERITEMSIDS.addMembers]: addMembersTab
|
|
||||||
});
|
});
|
||||||
|
|
||||||
//this._selectTab(0); // make first tab as default
|
//this._selectTab(0); // make first tab as default
|
||||||
@ -101,7 +100,6 @@ export class AppSidebarLeft extends SidebarSlider {
|
|||||||
|
|
||||||
this.archivedTab = archivedTab;
|
this.archivedTab = archivedTab;
|
||||||
this.newChannelTab = new AppNewChannelTab(this);
|
this.newChannelTab = new AppNewChannelTab(this);
|
||||||
this.addMembersTab = addMembersTab;
|
|
||||||
this.contactsTab = contactsTab;
|
this.contactsTab = contactsTab;
|
||||||
this.newGroupTab = new AppNewGroupTab(this);
|
this.newGroupTab = new AppNewGroupTab(this);
|
||||||
this.settingsTab = new AppSettingsTab(this);
|
this.settingsTab = new AppSettingsTab(this);
|
||||||
@ -110,6 +108,8 @@ export class AppSidebarLeft extends SidebarSlider {
|
|||||||
this.includedChatsTab = new AppIncludedChatsTab(this);
|
this.includedChatsTab = new AppIncludedChatsTab(this);
|
||||||
this.editProfileTab = new AppEditProfileTab(this);
|
this.editProfileTab = new AppEditProfileTab(this);
|
||||||
this.generalSettingsTab = new AppGeneralSettingsTab(this);
|
this.generalSettingsTab = new AppGeneralSettingsTab(this);
|
||||||
|
this.privacyAndSecurityTab = new AppPrivacyAndSecurityTab(this);
|
||||||
|
this.addMembersTab = new AppAddMembersTab(this);
|
||||||
|
|
||||||
this.menuEl = this.toolsBtn.querySelector('.btn-menu');
|
this.menuEl = this.toolsBtn.querySelector('.btn-menu');
|
||||||
this.newBtnMenu = this.sidebarEl.querySelector('#new-menu');
|
this.newBtnMenu = this.sidebarEl.querySelector('#new-menu');
|
||||||
@ -146,8 +146,15 @@ export class AppSidebarLeft extends SidebarSlider {
|
|||||||
|
|
||||||
[this.newButtons.group, this.buttons.newGroup].forEach(btn => {
|
[this.newButtons.group, this.buttons.newGroup].forEach(btn => {
|
||||||
attachClickEvent(btn, (e) => {
|
attachClickEvent(btn, (e) => {
|
||||||
this.addMembersTab.init(0, 'chat', false, (peerIds) => {
|
this.addMembersTab.open({
|
||||||
this.newGroupTab.init(peerIds);
|
peerId: 0,
|
||||||
|
type: 'chat',
|
||||||
|
skippable: false,
|
||||||
|
takeOut: (peerIds) => {
|
||||||
|
this.newGroupTab.open(peerIds);
|
||||||
|
},
|
||||||
|
title: 'Add Members',
|
||||||
|
placeholder: 'Add People...'
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -429,6 +436,45 @@ export class AppSidebarLeft extends SidebarSlider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class SettingSection {
|
||||||
|
public container: HTMLElement;
|
||||||
|
public content: HTMLElement;
|
||||||
|
public title: HTMLElement;
|
||||||
|
public caption: HTMLElement;
|
||||||
|
|
||||||
|
constructor(name: string, caption?: string) {
|
||||||
|
this.container = document.createElement('div');
|
||||||
|
this.container.classList.add('sidebar-left-section');
|
||||||
|
|
||||||
|
const hr = document.createElement('hr');
|
||||||
|
|
||||||
|
this.content = document.createElement('div');
|
||||||
|
this.content.classList.add('sidebar-left-section-content');
|
||||||
|
|
||||||
|
if(name) {
|
||||||
|
this.title = document.createElement('div');
|
||||||
|
this.title.classList.add('sidebar-left-h2', 'sidebar-left-section-name');
|
||||||
|
this.title.innerHTML = name;
|
||||||
|
this.content.append(this.title);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.container.append(hr, this.content);
|
||||||
|
|
||||||
|
if(caption) {
|
||||||
|
this.caption = document.createElement('div');
|
||||||
|
this.caption.classList.add('sidebar-left-section-caption');
|
||||||
|
this.caption.innerHTML = caption;
|
||||||
|
this.container.append(this.caption);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const generateSection = (appendTo: Scrollable, name: string, caption?: string) => {
|
||||||
|
const section = new SettingSection(name, caption);
|
||||||
|
appendTo.append(section.container);
|
||||||
|
return section.content;
|
||||||
|
};
|
||||||
|
|
||||||
const appSidebarLeft = new AppSidebarLeft();
|
const appSidebarLeft = new AppSidebarLeft();
|
||||||
MOUNT_CLASS_TO && (MOUNT_CLASS_TO.appSidebarLeft = appSidebarLeft);
|
MOUNT_CLASS_TO && (MOUNT_CLASS_TO.appSidebarLeft = appSidebarLeft);
|
||||||
export default appSidebarLeft;
|
export default appSidebarLeft;
|
||||||
|
@ -1,42 +1,44 @@
|
|||||||
import { SliderTab } from "../../slider";
|
import SidebarSlider, { SliderSuperTab } from "../../slider";
|
||||||
import AppSelectPeers from "../../appSelectPeers";
|
import AppSelectPeers from "../../appSelectPeers";
|
||||||
import { putPreloader } from "../../misc";
|
import { putPreloader } from "../../misc";
|
||||||
import appChatsManager from "../../../lib/appManagers/appChatsManager";
|
import Button from "../../button";
|
||||||
import appSidebarLeft, { AppSidebarLeft } from "..";
|
|
||||||
|
|
||||||
export default class AppAddMembersTab implements SliderTab {
|
export default class AppAddMembersTab extends SliderSuperTab {
|
||||||
private container = document.querySelector('.addmembers-container') as HTMLDivElement;
|
private nextBtn: HTMLButtonElement;
|
||||||
private contentDiv = this.container.querySelector('.sidebar-content') as HTMLDivElement;
|
|
||||||
private backBtn = this.container.querySelector('.sidebar-close-button') as HTMLButtonElement;
|
|
||||||
private nextBtn = this.contentDiv.querySelector('.btn-corner') as HTMLButtonElement;
|
|
||||||
private selector: AppSelectPeers;
|
private selector: AppSelectPeers;
|
||||||
private peerType: 'channel' | 'chat';
|
private peerType: 'channel' | 'chat' | 'privacy';
|
||||||
private peerId: number; // always positive
|
private takeOut: (peerIds: number[]) => Promise<any> | any;
|
||||||
private takeOut: (peerIds: number[]) => void
|
|
||||||
private skippable: boolean;
|
private skippable: boolean;
|
||||||
|
|
||||||
constructor() {
|
constructor(slider: SidebarSlider) {
|
||||||
|
super(slider);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected init() {
|
||||||
|
this.nextBtn = Button('btn-corner btn-circle', {icon: 'arrow-next'});
|
||||||
|
this.content.append(this.nextBtn);
|
||||||
|
|
||||||
this.nextBtn.addEventListener('click', () => {
|
this.nextBtn.addEventListener('click', () => {
|
||||||
if(this.skippable) {
|
|
||||||
appSidebarLeft.closeTab(AppSidebarLeft.SLIDERITEMSIDS.addMembers);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const peerIds = this.selector.getSelected();
|
const peerIds = this.selector.getSelected();
|
||||||
if(peerIds.length) {
|
|
||||||
if(this.takeOut) {
|
if(this.skippable) {
|
||||||
this.takeOut(peerIds);
|
this.takeOut(peerIds);
|
||||||
return;
|
this.close();
|
||||||
|
} else {
|
||||||
|
const promise = this.takeOut(peerIds);
|
||||||
|
|
||||||
|
if(promise instanceof Promise) {
|
||||||
|
this.nextBtn.classList.remove('tgico-arrow-next');
|
||||||
|
this.nextBtn.disabled = true;
|
||||||
|
putPreloader(this.nextBtn);
|
||||||
|
this.selector.freezed = true;
|
||||||
|
|
||||||
|
promise.then(() => {
|
||||||
|
this.close();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.nextBtn.classList.remove('tgico-arrow-next');
|
|
||||||
this.nextBtn.disabled = true;
|
|
||||||
putPreloader(this.nextBtn);
|
|
||||||
this.selector.freezed = true;
|
|
||||||
|
|
||||||
appChatsManager.inviteToChannel(this.peerId, peerIds).then(() => {
|
|
||||||
appSidebarLeft.closeTab(AppSidebarLeft.SLIDERITEMSIDS.addMembers);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -48,22 +50,39 @@ export default class AppAddMembersTab implements SliderTab {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(id: number, type: 'channel' | 'chat', skippable: boolean, takeOut?: AppAddMembersTab['takeOut']) {
|
public open(options: {
|
||||||
this.peerId = Math.abs(id);
|
title: string,
|
||||||
this.peerType = type;
|
placeholder: string,
|
||||||
this.takeOut = takeOut;
|
peerId?: number,
|
||||||
this.skippable = skippable;
|
type: AppAddMembersTab['peerType'],
|
||||||
|
takeOut?: AppAddMembersTab['takeOut'],
|
||||||
|
skippable: boolean,
|
||||||
|
selectedPeerIds?: number[]
|
||||||
|
}) {
|
||||||
|
const ret = super.open();
|
||||||
|
|
||||||
|
this.title.innerHTML = options.title;
|
||||||
|
this.peerType = options.type;
|
||||||
|
this.takeOut = options.takeOut;
|
||||||
|
this.skippable = options.skippable;
|
||||||
|
|
||||||
this.onCloseAfterTimeout();
|
this.onCloseAfterTimeout();
|
||||||
this.selector = new AppSelectPeers(this.contentDiv, skippable ? null : (length) => {
|
this.selector = new AppSelectPeers(this.content, this.skippable ? null : (length) => {
|
||||||
this.nextBtn.classList.toggle('is-visible', !!length);
|
this.nextBtn.classList.toggle('is-visible', !!length);
|
||||||
}, ['contacts']);
|
}, ['contacts']);
|
||||||
|
this.selector.input.placeholder = options.placeholder;
|
||||||
|
|
||||||
|
if(options.selectedPeerIds) {
|
||||||
|
options.selectedPeerIds.forEach(peerId => {
|
||||||
|
this.selector.add(peerId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.nextBtn.classList.add('tgico-arrow-next');
|
||||||
this.nextBtn.innerHTML = '';
|
this.nextBtn.innerHTML = '';
|
||||||
this.nextBtn.disabled = false;
|
this.nextBtn.disabled = false;
|
||||||
this.nextBtn.classList.add('tgico-arrow-next');
|
this.nextBtn.classList.toggle('is-visible', this.skippable);
|
||||||
this.nextBtn.classList.toggle('is-visible', skippable);
|
|
||||||
|
|
||||||
appSidebarLeft.selectTab(AppSidebarLeft.SLIDERITEMSIDS.addMembers);
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -96,7 +96,7 @@ export default class AppChatFoldersTab extends SliderSuperTab {
|
|||||||
return div;
|
return div;
|
||||||
}
|
}
|
||||||
|
|
||||||
init() {
|
protected init() {
|
||||||
this.container.classList.add('chat-folders-container');
|
this.container.classList.add('chat-folders-container');
|
||||||
this.title.innerText = 'Chat Folders';
|
this.title.innerText = 'Chat Folders';
|
||||||
|
|
||||||
@ -232,13 +232,8 @@ export default class AppChatFoldersTab extends SliderSuperTab {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onOpen() {
|
onOpen() {
|
||||||
if(this.init) {
|
if(this.animation) {
|
||||||
this.init();
|
this.animation.restart();
|
||||||
this.init = null;
|
|
||||||
} else {
|
|
||||||
if(this.animation) {
|
|
||||||
this.animation.restart();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ export default class AppEditFolderTab extends SliderSuperTab {
|
|||||||
super(appSidebarLeft);
|
super(appSidebarLeft);
|
||||||
}
|
}
|
||||||
|
|
||||||
init() {
|
protected init() {
|
||||||
this.container.classList.add('edit-folder-container');
|
this.container.classList.add('edit-folder-container');
|
||||||
this.caption = document.createElement('div');
|
this.caption = document.createElement('div');
|
||||||
this.caption.classList.add('caption');
|
this.caption.classList.add('caption');
|
||||||
@ -227,13 +227,8 @@ export default class AppEditFolderTab extends SliderSuperTab {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onOpen() {
|
onOpen() {
|
||||||
if(this.init) {
|
if(this.animation) {
|
||||||
this.init();
|
this.animation.restart();
|
||||||
this.init = null;
|
|
||||||
} else {
|
|
||||||
if(this.animation) {
|
|
||||||
this.animation.restart();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ export default class AppEditProfileTab extends SliderSuperTab {
|
|||||||
super(slider);
|
super(slider);
|
||||||
}
|
}
|
||||||
|
|
||||||
public 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.scrollWrapper = this.container.querySelector('.scroll-wrapper');
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { SliderSuperTab } from "../../slider"
|
import { SliderSuperTab } from "../../slider"
|
||||||
import { AppSidebarLeft } from "..";
|
import { AppSidebarLeft, generateSection } from "..";
|
||||||
import RangeSelector from "../../rangeSelector";
|
import RangeSelector from "../../rangeSelector";
|
||||||
import { clamp } from "../../../helpers/number";
|
import { clamp } from "../../../helpers/number";
|
||||||
import Button from "../../button";
|
import Button from "../../button";
|
||||||
@ -8,6 +8,7 @@ import RadioField from "../../radioField";
|
|||||||
import appStateManager from "../../../lib/appManagers/appStateManager";
|
import appStateManager from "../../../lib/appManagers/appStateManager";
|
||||||
import rootScope from "../../../lib/rootScope";
|
import rootScope from "../../../lib/rootScope";
|
||||||
import { isApple } from "../../../helpers/userAgent";
|
import { isApple } from "../../../helpers/userAgent";
|
||||||
|
import Row from "../../row";
|
||||||
|
|
||||||
export class RangeSettingSelector {
|
export class RangeSettingSelector {
|
||||||
public container: HTMLDivElement;
|
public container: HTMLDivElement;
|
||||||
@ -59,28 +60,10 @@ export default class AppGeneralSettingsTab extends SliderSuperTab {
|
|||||||
this.container.classList.add('general-settings-container');
|
this.container.classList.add('general-settings-container');
|
||||||
this.title.innerText = 'General';
|
this.title.innerText = 'General';
|
||||||
|
|
||||||
const generateSection = (name: string) => {
|
const section = generateSection.bind(null, this.scrollable);
|
||||||
const container = document.createElement('div');
|
|
||||||
container.classList.add('sidebar-left-section');
|
|
||||||
|
|
||||||
const hr = document.createElement('hr');
|
|
||||||
const h2 = document.createElement('div');
|
|
||||||
h2.classList.add('sidebar-left-h2', 'sidebar-left-section-name');
|
|
||||||
h2.innerHTML = name;
|
|
||||||
|
|
||||||
const content = document.createElement('div');
|
|
||||||
content.classList.add('sidebar-left-section-content');
|
|
||||||
content.append(h2);
|
|
||||||
|
|
||||||
container.append(hr, content);
|
|
||||||
|
|
||||||
this.scrollable.append(container);
|
|
||||||
|
|
||||||
return content;
|
|
||||||
};
|
|
||||||
|
|
||||||
{
|
{
|
||||||
const container = generateSection('Settings');
|
const container = section('Settings');
|
||||||
|
|
||||||
const range = new RangeSettingSelector('Message Text Size', 1, rootScope.settings.messagesTextSize, 12, 20);
|
const range = new RangeSettingSelector('Message Text Size', 1, rootScope.settings.messagesTextSize, 12, 20);
|
||||||
range.onChange = (value) => {
|
range.onChange = (value) => {
|
||||||
@ -95,67 +78,7 @@ export default class AppGeneralSettingsTab extends SliderSuperTab {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
const container = generateSection('Keyboard');
|
const container = section('Keyboard');
|
||||||
|
|
||||||
class Row {
|
|
||||||
public container: HTMLElement;
|
|
||||||
public title: HTMLDivElement;
|
|
||||||
public subtitle: HTMLElement;
|
|
||||||
|
|
||||||
public checkboxField: ReturnType<typeof CheckboxField>;
|
|
||||||
public radioField: ReturnType<typeof RadioField>;
|
|
||||||
|
|
||||||
constructor(options: Partial<{
|
|
||||||
icon: string,
|
|
||||||
subtitle: string,
|
|
||||||
radioField: Row['radioField'],
|
|
||||||
checkboxField: Row['checkboxField'],
|
|
||||||
title: string,
|
|
||||||
}> = {}) {
|
|
||||||
this.container = document.createElement('div');
|
|
||||||
this.container.classList.add('row');
|
|
||||||
|
|
||||||
this.subtitle = document.createElement('div');
|
|
||||||
this.subtitle.classList.add('row-subtitle');
|
|
||||||
if(options.subtitle) {
|
|
||||||
this.subtitle.innerHTML = options.subtitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
let havePadding = false;
|
|
||||||
if(options.radioField || options.checkboxField) {
|
|
||||||
havePadding = true;
|
|
||||||
if(options.radioField) {
|
|
||||||
this.radioField = options.radioField;
|
|
||||||
this.container.append(this.radioField.label);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(options.checkboxField) {
|
|
||||||
this.checkboxField = options.checkboxField;
|
|
||||||
this.container.append(this.checkboxField.label);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if(options.icon) {
|
|
||||||
havePadding = true;
|
|
||||||
this.container.classList.add('tgico-', options.icon);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(options.title) {
|
|
||||||
this.title = document.createElement('div');
|
|
||||||
this.title.classList.add('row-title');
|
|
||||||
this.title.innerHTML = options.title;
|
|
||||||
this.container.append(this.title);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(havePadding) {
|
|
||||||
this.container.classList.add('row-with-padding');
|
|
||||||
}
|
|
||||||
|
|
||||||
this.container.append(this.subtitle);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
const form = document.createElement('form');
|
const form = document.createElement('form');
|
||||||
|
|
||||||
@ -174,7 +97,7 @@ export default class AppGeneralSettingsTab extends SliderSuperTab {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
const container = generateSection('Auto-Download Media');
|
const container = section('Auto-Download Media');
|
||||||
|
|
||||||
const contactsCheckboxField = CheckboxField('Contacts', 'contacts', false, 'settings.autoDownload.contacts');
|
const contactsCheckboxField = CheckboxField('Contacts', 'contacts', false, 'settings.autoDownload.contacts');
|
||||||
const privateCheckboxField = CheckboxField('Private Chats', 'private', false, 'settings.autoDownload.private');
|
const privateCheckboxField = CheckboxField('Private Chats', 'private', false, 'settings.autoDownload.private');
|
||||||
@ -185,7 +108,7 @@ export default class AppGeneralSettingsTab extends SliderSuperTab {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
const container = generateSection('Auto-Play Media');
|
const container = section('Auto-Play Media');
|
||||||
|
|
||||||
const gifsCheckboxField = CheckboxField('GIFs', 'gifs', false, 'settings.autoPlay.gifs');
|
const gifsCheckboxField = CheckboxField('GIFs', 'gifs', false, 'settings.autoPlay.gifs');
|
||||||
const videosCheckboxField = CheckboxField('Videos', 'videos', false, 'settings.autoPlay.videos');
|
const videosCheckboxField = CheckboxField('Videos', 'videos', false, 'settings.autoPlay.videos');
|
||||||
@ -194,7 +117,7 @@ export default class AppGeneralSettingsTab extends SliderSuperTab {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
const container = generateSection('Stickers');
|
const container = section('Stickers');
|
||||||
|
|
||||||
const suggestCheckboxField = CheckboxField('Suggest Stickers by Emoji', 'suggest', false, 'settings.stickers.suggest');
|
const suggestCheckboxField = CheckboxField('Suggest Stickers by Emoji', 'suggest', false, 'settings.stickers.suggest');
|
||||||
const loopCheckboxField = CheckboxField('Loop Animated Stickers', 'loop', false, 'settings.stickers.loop');
|
const loopCheckboxField = CheckboxField('Loop Animated Stickers', 'loop', false, 'settings.stickers.loop');
|
||||||
|
@ -3,12 +3,10 @@ import { InputFile } from "../../../layer";
|
|||||||
import appChatsManager from "../../../lib/appManagers/appChatsManager";
|
import appChatsManager from "../../../lib/appManagers/appChatsManager";
|
||||||
import Button from "../../button";
|
import Button from "../../button";
|
||||||
import InputField from "../../inputField";
|
import InputField from "../../inputField";
|
||||||
import PopupAvatar from "../../popups/avatar";
|
import { SliderSuperTab } from "../../slider";
|
||||||
import { SliderTab, SliderSuperTab } from "../../slider";
|
|
||||||
import AvatarEdit from "../../avatarEdit";
|
import AvatarEdit from "../../avatarEdit";
|
||||||
|
|
||||||
export default class AppNewChannelTab extends SliderSuperTab {
|
export default class AppNewChannelTab extends SliderSuperTab {
|
||||||
private canvas = this.container.querySelector('.avatar-edit-canvas') as HTMLCanvasElement;
|
|
||||||
private uploadAvatar: () => Promise<InputFile> = null;
|
private uploadAvatar: () => Promise<InputFile> = null;
|
||||||
|
|
||||||
private channelNameInputField: InputField;
|
private channelNameInputField: InputField;
|
||||||
@ -20,7 +18,7 @@ export default class AppNewChannelTab extends SliderSuperTab {
|
|||||||
super(appSidebarLeft);
|
super(appSidebarLeft);
|
||||||
}
|
}
|
||||||
|
|
||||||
private init() {
|
protected init() {
|
||||||
this.container.classList.add('new-channel-container');
|
this.container.classList.add('new-channel-container');
|
||||||
this.title.innerText = 'New Channel';
|
this.title.innerText = 'New Channel';
|
||||||
|
|
||||||
@ -71,7 +69,16 @@ export default class AppNewChannelTab extends SliderSuperTab {
|
|||||||
}
|
}
|
||||||
|
|
||||||
appSidebarLeft.removeTabFromHistory(this.id);
|
appSidebarLeft.removeTabFromHistory(this.id);
|
||||||
appSidebarLeft.addMembersTab.init(channelId, 'channel', true);
|
appSidebarLeft.addMembersTab.open({
|
||||||
|
peerId: channelId,
|
||||||
|
type: 'channel',
|
||||||
|
skippable: true,
|
||||||
|
title: 'Add Members',
|
||||||
|
placeholder: 'Add People...',
|
||||||
|
takeOut: (peerIds) => {
|
||||||
|
return appChatsManager.inviteToChannel(Math.abs(channelId), peerIds);
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -86,11 +93,4 @@ export default class AppNewChannelTab extends SliderSuperTab {
|
|||||||
this.channelDescriptionInputField.value = '';
|
this.channelDescriptionInputField.value = '';
|
||||||
this.nextBtn.disabled = false;
|
this.nextBtn.disabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
onOpen() {
|
|
||||||
if(this.init) {
|
|
||||||
this.init();
|
|
||||||
this.init = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -6,13 +6,10 @@ import appUsersManager from "../../../lib/appManagers/appUsersManager";
|
|||||||
import { SearchGroup } from "../../appSearch";
|
import { SearchGroup } from "../../appSearch";
|
||||||
import Button from "../../button";
|
import Button from "../../button";
|
||||||
import InputField from "../../inputField";
|
import InputField from "../../inputField";
|
||||||
import PopupAvatar from "../../popups/avatar";
|
|
||||||
import Scrollable from "../../scrollable";
|
|
||||||
import { SliderSuperTab } from "../../slider";
|
import { SliderSuperTab } from "../../slider";
|
||||||
import AvatarEdit from "../../avatarEdit";
|
import AvatarEdit from "../../avatarEdit";
|
||||||
|
|
||||||
export default class AppNewGroupTab extends SliderSuperTab {
|
export default class AppNewGroupTab extends SliderSuperTab {
|
||||||
private canvas = this.container.querySelector('.avatar-edit-canvas') as HTMLCanvasElement;
|
|
||||||
private searchGroup = new SearchGroup(' ', 'contacts', true, 'new-group-members disable-hover', false);
|
private searchGroup = new SearchGroup(' ', 'contacts', true, 'new-group-members disable-hover', false);
|
||||||
private avatarEdit: AvatarEdit;
|
private avatarEdit: AvatarEdit;
|
||||||
private uploadAvatar: () => Promise<InputFile> = null;
|
private uploadAvatar: () => Promise<InputFile> = null;
|
||||||
@ -24,7 +21,7 @@ export default class AppNewGroupTab extends SliderSuperTab {
|
|||||||
super(appSidebarLeft);
|
super(appSidebarLeft);
|
||||||
}
|
}
|
||||||
|
|
||||||
private construct() {
|
protected init() {
|
||||||
this.container.classList.add('new-group-container');
|
this.container.classList.add('new-group-container');
|
||||||
this.title.innerText = 'New Group';
|
this.title.innerText = 'New Group';
|
||||||
|
|
||||||
@ -73,10 +70,6 @@ export default class AppNewGroupTab extends SliderSuperTab {
|
|||||||
this.scrollable.append(this.avatarEdit.container, inputWrapper, chatsContainer);
|
this.scrollable.append(this.avatarEdit.container, inputWrapper, chatsContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public onClose() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public onCloseAfterTimeout() {
|
public onCloseAfterTimeout() {
|
||||||
this.searchGroup.clear();
|
this.searchGroup.clear();
|
||||||
this.avatarEdit.clear();
|
this.avatarEdit.clear();
|
||||||
@ -85,36 +78,35 @@ export default class AppNewGroupTab extends SliderSuperTab {
|
|||||||
this.nextBtn.disabled = false;
|
this.nextBtn.disabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(userIds: number[]) {
|
public open(userIds: number[]) {
|
||||||
if(this.construct) {
|
const result = super.open();
|
||||||
this.construct();
|
result.then(() => {
|
||||||
this.construct = null;
|
this.userIds = userIds;
|
||||||
}
|
|
||||||
|
|
||||||
this.userIds = userIds;
|
this.userIds.forEach(userId => {
|
||||||
|
let {dom} = appDialogsManager.addDialogNew({
|
||||||
|
dialog: userId,
|
||||||
|
container: this.searchGroup.list,
|
||||||
|
drawStatus: false,
|
||||||
|
rippleEnabled: false,
|
||||||
|
avatarSize: 48
|
||||||
|
});
|
||||||
|
|
||||||
this.open();
|
let subtitle = '';
|
||||||
this.userIds.forEach(userId => {
|
subtitle = appUsersManager.getUserStatusString(userId);
|
||||||
let {dom} = appDialogsManager.addDialogNew({
|
if(subtitle == 'online') {
|
||||||
dialog: userId,
|
subtitle = `<i>${subtitle}</i>`;
|
||||||
container: this.searchGroup.list,
|
}
|
||||||
drawStatus: false,
|
|
||||||
rippleEnabled: false,
|
if(subtitle) {
|
||||||
avatarSize: 48
|
dom.lastMessageSpan.innerHTML = subtitle;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let subtitle = '';
|
this.searchGroup.nameEl.innerText = this.userIds.length + ' members';
|
||||||
subtitle = appUsersManager.getUserStatusString(userId);
|
this.searchGroup.setActive();
|
||||||
if(subtitle == 'online') {
|
|
||||||
subtitle = `<i>${subtitle}</i>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(subtitle) {
|
|
||||||
dom.lastMessageSpan.innerHTML = subtitle;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.searchGroup.nameEl.innerText = this.userIds.length + ' members';
|
return result;
|
||||||
this.searchGroup.setActive();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
98
src/components/sidebarLeft/tabs/privacyAndSecurity.ts
Normal file
98
src/components/sidebarLeft/tabs/privacyAndSecurity.ts
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
import SidebarSlider, { SliderSuperTab } from "../../slider";
|
||||||
|
import { generateSection } from "..";
|
||||||
|
import Row from "../../row";
|
||||||
|
import { InputPrivacyKey, PrivacyRule } from "../../../layer";
|
||||||
|
import appPrivacyManager from "../../../lib/appManagers/appPrivacyManager";
|
||||||
|
import AppPrivacyPhoneNumberTab from "./privacy/phoneNumber";
|
||||||
|
|
||||||
|
export default class AppPrivacyAndSecurityTab extends SliderSuperTab {
|
||||||
|
constructor(slider: SidebarSlider) {
|
||||||
|
super(slider);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected init() {
|
||||||
|
this.container.classList.add('privacy-container');
|
||||||
|
this.title.innerText = 'Privacy and Security';
|
||||||
|
|
||||||
|
const section = generateSection.bind(null, this.scrollable);
|
||||||
|
|
||||||
|
{
|
||||||
|
const container = section('');
|
||||||
|
|
||||||
|
const blockedUsersRow = new Row({
|
||||||
|
icon: 'deleteuser',
|
||||||
|
title: 'Blocked Users',
|
||||||
|
subtitle: '6 users',
|
||||||
|
clickable: true
|
||||||
|
});
|
||||||
|
|
||||||
|
const twoFactorRow = new Row({
|
||||||
|
icon: 'lock',
|
||||||
|
title: 'Two-Step Verification',
|
||||||
|
subtitle: 'Off',
|
||||||
|
clickable: true
|
||||||
|
});
|
||||||
|
|
||||||
|
const activeSessionRow = new Row({
|
||||||
|
icon: 'activesessions',
|
||||||
|
title: 'Active Sessions',
|
||||||
|
subtitle: '3 devices',
|
||||||
|
clickable: true
|
||||||
|
});
|
||||||
|
|
||||||
|
container.append(blockedUsersRow.container, twoFactorRow.container, activeSessionRow.container);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const container = section('Privacy');
|
||||||
|
|
||||||
|
const rowsByKeys: Partial<{
|
||||||
|
[key in InputPrivacyKey['_']]: Row
|
||||||
|
}> = {};
|
||||||
|
|
||||||
|
const numberVisibilityRow = rowsByKeys['inputPrivacyKeyPhoneNumber'] = new Row({
|
||||||
|
title: 'Who can see my phone number?',
|
||||||
|
subtitle: 'My Contacts',
|
||||||
|
navigationTab: new AppPrivacyPhoneNumberTab(this.slider)
|
||||||
|
});
|
||||||
|
|
||||||
|
const lastSeenTimeRow = rowsByKeys['inputPrivacyKeyStatusTimestamp'] = new Row({
|
||||||
|
title: 'Who can see your Last Seen time?',
|
||||||
|
subtitle: 'Everybody',
|
||||||
|
clickable: true
|
||||||
|
});
|
||||||
|
|
||||||
|
const photoVisibilityRow = rowsByKeys['inputPrivacyKeyProfilePhoto'] = new Row({
|
||||||
|
title: 'Who can see my profile photo?',
|
||||||
|
subtitle: 'Everybody',
|
||||||
|
clickable: true
|
||||||
|
});
|
||||||
|
|
||||||
|
const linkAccountRow = rowsByKeys['inputPrivacyKeyForwards'] = new Row({
|
||||||
|
title: 'Who can add a link to my account when forwarding my messages?',
|
||||||
|
subtitle: 'Everybody',
|
||||||
|
clickable: true
|
||||||
|
});
|
||||||
|
|
||||||
|
const groupChatsAddRow = rowsByKeys['inputPrivacyKeyChatInvite'] = new Row({
|
||||||
|
title: 'Who can add me to group chats?',
|
||||||
|
subtitle: 'Everybody',
|
||||||
|
clickable: true
|
||||||
|
});
|
||||||
|
|
||||||
|
for(const key in rowsByKeys) {
|
||||||
|
const row = rowsByKeys[key as keyof typeof rowsByKeys];
|
||||||
|
appPrivacyManager.getPrivacy(key as keyof typeof rowsByKeys).then(rules => {
|
||||||
|
const details = appPrivacyManager.getPrivacyRulesDetails(rules);
|
||||||
|
const type = details.type === 2 ? 'Everybody' : (details.type === 1 ? 'My Contacts' : 'Nobody');
|
||||||
|
const disallowLength = details.disallowLengths.users + details.disallowLengths.chats;
|
||||||
|
const allowLength = details.allowLengths.users + details.allowLengths.chats;
|
||||||
|
const str = type + (disallowLength || allowLength ? ` (${[-disallowLength, allowLength ? '+' + allowLength : 0].filter(Boolean).join(', ')})` : '');
|
||||||
|
row.subtitle.innerHTML = str;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
container.append(numberVisibilityRow.container, lastSeenTimeRow.container, photoVisibilityRow.container, linkAccountRow.container, groupChatsAddRow.container);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -56,7 +56,7 @@ export default class AppSettingsTab extends SliderSuperTab {
|
|||||||
buttonsDiv.append(this.buttons.folders = Button(className, {icon: 'folder', rippleSquare: true, text: 'Chat Folders'}));
|
buttonsDiv.append(this.buttons.folders = Button(className, {icon: 'folder', rippleSquare: true, text: 'Chat Folders'}));
|
||||||
buttonsDiv.append(this.buttons.general = Button(className, {icon: 'settings', rippleSquare: true, text: 'General Settings'}));
|
buttonsDiv.append(this.buttons.general = Button(className, {icon: 'settings', rippleSquare: true, text: 'General Settings'}));
|
||||||
buttonsDiv.append(this.buttons.notifications = Button(className + ' btn-disabled', {icon: 'unmute', rippleSquare: true, text: 'Notifications'}));
|
buttonsDiv.append(this.buttons.notifications = Button(className + ' btn-disabled', {icon: 'unmute', rippleSquare: true, text: 'Notifications'}));
|
||||||
buttonsDiv.append(this.buttons.privacy = Button(className + ' btn-disabled', {icon: 'lock', rippleSquare: true, text: 'Privacy and Security'}));
|
buttonsDiv.append(this.buttons.privacy = Button(className, {icon: 'lock', rippleSquare: true, text: 'Privacy and Security'}));
|
||||||
buttonsDiv.append(this.buttons.language = Button(className + ' btn-disabled', {icon: 'language', rippleSquare: true, text: 'Language'}));
|
buttonsDiv.append(this.buttons.language = Button(className + ' btn-disabled', {icon: 'language', rippleSquare: true, text: 'Language'}));
|
||||||
|
|
||||||
this.scrollable.append(this.avatarElem, this.nameDiv, this.phoneDiv, buttonsDiv);
|
this.scrollable.append(this.avatarElem, this.nameDiv, this.phoneDiv, buttonsDiv);
|
||||||
@ -78,6 +78,10 @@ export default class AppSettingsTab extends SliderSuperTab {
|
|||||||
this.buttons.general.addEventListener('click', () => {
|
this.buttons.general.addEventListener('click', () => {
|
||||||
appSidebarLeft.generalSettingsTab.open();
|
appSidebarLeft.generalSettingsTab.open();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.buttons.privacy.addEventListener('click', () => {
|
||||||
|
appSidebarLeft.privacyAndSecurityTab.open();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public fillElements() {
|
public fillElements() {
|
||||||
|
@ -2,7 +2,6 @@ import { attachClickEvent } from "../helpers/dom";
|
|||||||
import { horizontalMenu } from "./horizontalMenu";
|
import { horizontalMenu } from "./horizontalMenu";
|
||||||
import ButtonIcon from "./buttonIcon";
|
import ButtonIcon from "./buttonIcon";
|
||||||
import Scrollable from "./scrollable";
|
import Scrollable from "./scrollable";
|
||||||
import { p } from "../mock/srp";
|
|
||||||
|
|
||||||
export interface SliderTab {
|
export interface SliderTab {
|
||||||
onOpen?: () => void,
|
onOpen?: () => void,
|
||||||
@ -23,7 +22,7 @@ export class SliderSuperTab implements SliderTab {
|
|||||||
|
|
||||||
public id: number;
|
public id: number;
|
||||||
|
|
||||||
constructor(protected slider: SidebarSlider) {
|
constructor(protected slider: SidebarSlider, protected destroyable = false) {
|
||||||
this.container = document.createElement('div');
|
this.container = document.createElement('div');
|
||||||
this.container.classList.add('sidebar-slider-item');
|
this.container.classList.add('sidebar-slider-item');
|
||||||
|
|
||||||
@ -51,20 +50,37 @@ export class SliderSuperTab implements SliderTab {
|
|||||||
return this.slider.closeTab(this.id);
|
return this.slider.closeTab(this.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public open() {
|
public async open(...args: any[]) {
|
||||||
|
if(this.init) {
|
||||||
|
const result = this.init();
|
||||||
|
this.init = null;
|
||||||
|
await (result instanceof Promise ? result : Promise.resolve());
|
||||||
|
}
|
||||||
|
|
||||||
return this.slider.selectTab(this);
|
return this.slider.selectTab(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected init(): Promise<any> | any {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// * fix incompability
|
// * fix incompability
|
||||||
public onOpen() {
|
public onOpen() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* public onCloseAfterTimeout() {
|
||||||
|
if(this.destroyable) { // ! WARNING, пока что это будет работать только с самой последней внутренней вкладкой !
|
||||||
|
delete this.slider.tabs[this.id];
|
||||||
|
this.container.remove();
|
||||||
|
}
|
||||||
|
} */
|
||||||
}
|
}
|
||||||
|
|
||||||
const TRANSITION_TIME = 250;
|
const TRANSITION_TIME = 250;
|
||||||
|
|
||||||
export default class SidebarSlider {
|
export default class SidebarSlider {
|
||||||
protected _selectTab: (id: number) => void;
|
protected _selectTab: ReturnType<typeof horizontalMenu>;
|
||||||
public historyTabIds: number[] = [];
|
public historyTabIds: number[] = [];
|
||||||
public tabsContainer: HTMLElement;
|
public tabsContainer: HTMLElement;
|
||||||
|
|
||||||
|
@ -674,7 +674,7 @@ export async function getFilesFromEvent(e: ClipboardEvent | DragEvent, onlyTypes
|
|||||||
return files;
|
return files;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function radiosHandleChange(inputs: HTMLInputElement[], onChange: (value: string) => void) {
|
/* export function radiosHandleChange(inputs: HTMLInputElement[], onChange: (value: string) => void) {
|
||||||
inputs.forEach(input => {
|
inputs.forEach(input => {
|
||||||
input.addEventListener('change', () => {
|
input.addEventListener('change', () => {
|
||||||
if(input.checked) {
|
if(input.checked) {
|
||||||
@ -682,7 +682,7 @@ export function radiosHandleChange(inputs: HTMLInputElement[], onChange: (value:
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
} */
|
||||||
|
|
||||||
export function isSendShortcutPressed(e: KeyboardEvent) {
|
export function isSendShortcutPressed(e: KeyboardEvent) {
|
||||||
if(e.key == 'Enter' && !isTouchSupported) {
|
if(e.key == 'Enter' && !isTouchSupported) {
|
||||||
|
@ -8,7 +8,7 @@ import Scrollable, { ScrollableX, SliceSides } from "../../components/scrollable
|
|||||||
import appSidebarLeft from "../../components/sidebarLeft";
|
import appSidebarLeft from "../../components/sidebarLeft";
|
||||||
import { formatDateAccordingToToday } from "../../helpers/date";
|
import { formatDateAccordingToToday } from "../../helpers/date";
|
||||||
import { escapeRegExp } from "../../helpers/string";
|
import { escapeRegExp } from "../../helpers/string";
|
||||||
import { isApple } from "../../helpers/userAgent";
|
import { isSafari } from "../../helpers/userAgent";
|
||||||
import { logger, LogLevels } from "../logger";
|
import { logger, LogLevels } from "../logger";
|
||||||
import { RichTextProcessor } from "../richtextprocessor";
|
import { RichTextProcessor } from "../richtextprocessor";
|
||||||
import rootScope from "../rootScope";
|
import rootScope from "../rootScope";
|
||||||
@ -745,7 +745,7 @@ export class AppDialogsManager {
|
|||||||
|
|
||||||
const saveLength = 10;
|
const saveLength = 10;
|
||||||
|
|
||||||
const sliceFromStart = isApple ? [] : children.slice(0, Math.max(0, firstIndex - saveLength));
|
const sliceFromStart = isSafari ? [] : children.slice(0, Math.max(0, firstIndex - saveLength));
|
||||||
const sliceFromEnd = children.slice(lastIndex + saveLength);
|
const sliceFromEnd = children.slice(lastIndex + saveLength);
|
||||||
|
|
||||||
/* if(sliceFromStart.length != sliceFromEnd.length) {
|
/* if(sliceFromStart.length != sliceFromEnd.length) {
|
||||||
|
66
src/lib/appManagers/appPrivacyManager.ts
Normal file
66
src/lib/appManagers/appPrivacyManager.ts
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
import { MOUNT_CLASS_TO } from "../mtproto/mtproto_config";
|
||||||
|
import { InputPrivacyKey, PrivacyRule } from "../../layer";
|
||||||
|
import apiManager from "../mtproto/mtprotoworker";
|
||||||
|
import appChatsManager from "./appChatsManager";
|
||||||
|
import appUsersManager from "./appUsersManager";
|
||||||
|
|
||||||
|
export class AppPrivacyManager {
|
||||||
|
constructor() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public getPrivacy(inputKey: InputPrivacyKey['_']) {
|
||||||
|
return apiManager.invokeApi('account.getPrivacy', {
|
||||||
|
key: {
|
||||||
|
_: inputKey
|
||||||
|
}
|
||||||
|
}).then(privacyRules => {
|
||||||
|
appUsersManager.saveApiUsers(privacyRules.users);
|
||||||
|
appChatsManager.saveApiChats(privacyRules.chats);
|
||||||
|
|
||||||
|
console.log('privacy rules', inputKey, privacyRules, privacyRules.rules);
|
||||||
|
|
||||||
|
return privacyRules.rules;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public getPrivacyRulesDetails(rules: PrivacyRule[]) {
|
||||||
|
const types: number[] = [];
|
||||||
|
|
||||||
|
let allowLengths = {users: 0, chats: 0}, disallowLengths = {users: 0, chats: 0};
|
||||||
|
rules.forEach(rule => {
|
||||||
|
switch(rule._) {
|
||||||
|
case 'privacyValueAllowAll':
|
||||||
|
types.push(2);
|
||||||
|
break;
|
||||||
|
case 'privacyValueDisallowAll':
|
||||||
|
types.push(0);
|
||||||
|
break;
|
||||||
|
case 'privacyValueAllowContacts':
|
||||||
|
types.push(1);
|
||||||
|
break;
|
||||||
|
/* case 'privacyValueDisallowContacts':
|
||||||
|
types.push('Except My Contacts');
|
||||||
|
break; */
|
||||||
|
case 'privacyValueAllowChatParticipants':
|
||||||
|
allowLengths.chats += rule.chats.length;
|
||||||
|
break;
|
||||||
|
case 'privacyValueAllowUsers':
|
||||||
|
allowLengths.users += rule.users.length;
|
||||||
|
break;
|
||||||
|
case 'privacyValueDisallowChatParticipants':
|
||||||
|
disallowLengths.chats += rule.chats.length;
|
||||||
|
break;
|
||||||
|
case 'privacyValueDisallowUsers':
|
||||||
|
disallowLengths.users += rule.users.length;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return {type: types[0], disallowLengths, allowLengths};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const appPrivacyManager = new AppPrivacyManager();
|
||||||
|
MOUNT_CLASS_TO && (MOUNT_CLASS_TO.appPrivacyManager = appPrivacyManager);
|
||||||
|
export default appPrivacyManager;
|
@ -853,8 +853,8 @@
|
|||||||
&-section {
|
&-section {
|
||||||
padding: .5rem 0 1rem;
|
padding: .5rem 0 1rem;
|
||||||
|
|
||||||
&-content {
|
&-content, &-caption {
|
||||||
margin: 0 0.125rem;
|
margin: 0 .125rem;
|
||||||
|
|
||||||
@include respond-to(not-handhelds) {
|
@include respond-to(not-handhelds) {
|
||||||
margin: 0 .625rem;
|
margin: 0 .625rem;
|
||||||
@ -865,6 +865,13 @@
|
|||||||
padding: 1rem .875rem;
|
padding: 1rem .875rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&-caption {
|
||||||
|
margin-top: 1rem;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
color: #707579;
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
|
|
||||||
.btn-primary, .checkbox-field, .radio-field {
|
.btn-primary, .checkbox-field, .radio-field {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
@ -884,7 +891,7 @@
|
|||||||
height: 54px;
|
height: 54px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.checkbox-field {
|
.checkbox-field, &-caption {
|
||||||
padding: 0 .875rem;
|
padding: 0 .875rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1117,9 +1117,30 @@ middle-ellipsis-element {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.row {
|
.row {
|
||||||
padding-left: 4.375rem;
|
|
||||||
min-height: 3.375rem;
|
min-height: 3.375rem;
|
||||||
margin-top: 1rem;
|
margin-top: .5rem;
|
||||||
|
position: relative;
|
||||||
|
padding: .5rem .75rem;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
&-with-padding {
|
||||||
|
padding-left: 4.375rem;
|
||||||
|
|
||||||
|
.row-title.tgico:before {
|
||||||
|
position: absolute;
|
||||||
|
left: .75rem;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
color: #707579;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-clickable {
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: $border-radius-medium;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
.radio-field {
|
.radio-field {
|
||||||
&-main {
|
&-main {
|
||||||
@ -1131,6 +1152,12 @@ middle-ellipsis-element {
|
|||||||
&-subtitle {
|
&-subtitle {
|
||||||
color: #707579 !important;
|
color: #707579 !important;
|
||||||
font-size: 14px !important;
|
font-size: 14px !important;
|
||||||
line-height: 1.6;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.hover-effect {
|
||||||
|
html.no-touch &:hover {
|
||||||
|
transition: .2s background-color;
|
||||||
|
background-color: var(--color-gray-hover);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user