diff --git a/src/components/appForward.ts b/src/components/appForward.ts
index 278d4594..3d0f6d64 100644
--- a/src/components/appForward.ts
+++ b/src/components/appForward.ts
@@ -1,161 +1,7 @@
import appSidebarRight from "../lib/appManagers/appSidebarRight";
-import Scrollable from "./scrollable_new";
-import appProfileManager from "../lib/appManagers/appProfileManager";
-import { appPeersManager } from "../lib/services";
import appMessagesManager from "../lib/appManagers/appMessagesManager";
-import appDialogsManager from "../lib/appManagers/appDialogsManager";
-import appChatsManager from "../lib/appManagers/appChatsManager";
-import appUsersManager from "../lib/appManagers/appUsersManager";
-import { $rootScope, findUpTag, findUpClassName, cancelEvent } from "../lib/utils";
import { putPreloader } from "./misc";
-
-class AppSelectPeers {
- public container = document.createElement('div');
- private chatList = document.createElement('ul');
- private chatsContainer = document.createElement('div');
- private scrollable: Scrollable;
- private selectedScrollable: Scrollable;
-
- private selectedContainer = document.createElement('div');
- private searchInput = document.createElement('input');
-
- private selected: {[peerID: number]: HTMLDivElement} = {};
-
- public freezed = false;
-
- constructor(private appendTo: HTMLDivElement, private onChange: (length: number) => void) {
- this.container.classList.add('selector');
-
- let topContainer = document.createElement('div');
- topContainer.classList.add('selector-search-container');
-
- this.selectedContainer.classList.add('selector-search');
- this.searchInput.placeholder = 'Select chat';
- this.searchInput.type = 'text';
- this.selectedContainer.append(this.searchInput);
- topContainer.append(this.selectedContainer);
- this.selectedScrollable = new Scrollable(topContainer);
-
- let delimiter = document.createElement('hr');
-
- this.chatsContainer.classList.add('chats-container');
- this.chatsContainer.append(this.chatList);
- this.scrollable = new Scrollable(this.chatsContainer);
-
- // в десктопе - сначала без группы, потом архивные, потом контакты без сообщений
- let offsetIndex = 0;
- appMessagesManager.getConversations(offsetIndex, 50, 0).then(value => {
- let dialogs = value.dialogs;
- let myID = $rootScope.myID;
-
- offsetIndex = dialogs[value.dialogs.length - 1].index || 0;
-
- if(dialogs[0].peerID != myID) {
- dialogs.findAndSplice(d => d.peerID == myID);
- dialogs.unshift({
- peerID: myID,
- pFlags: {}
- } as any);
- }
-
- dialogs.forEach(dialog => {
- let peerID = dialog.peerID;
-
- let {dom} = appDialogsManager.addDialog(dialog, this.chatList, false, false);
- dom.containerEl.insertAdjacentHTML('afterbegin', '
');
-
- let subtitle = '';
- if(peerID < 0) {
- subtitle = appChatsManager.getChatMembersString(-peerID);
- } else if(peerID == myID) {
- subtitle = 'chat with yourself';
- } else {
- subtitle = appUsersManager.getUserStatusString(peerID);
- if(subtitle == 'online') {
- subtitle = `${subtitle}`;
- }
- }
-
- dom.lastMessageSpan.innerHTML = subtitle;
- });
- });
-
- this.chatList.addEventListener('click', (e) => {
- let target = e.target as HTMLElement;
- cancelEvent(e);
-
- if(this.freezed) return;
-
- if(target.tagName != 'LI') {
- target = findUpTag(target, 'LI');
- }
-
- if(!target) return;
-
- let peerID = +target.getAttribute('data-peerID');
- target.classList.toggle('active');
- if(peerID in this.selected) {
- this.remove(peerID);
- } else {
- this.add(peerID);
- }
-
- let checkbox = target.querySelector('input') as HTMLInputElement;
- checkbox.checked = !checkbox.checked;
- });
-
- this.selectedContainer.addEventListener('click', (e) => {
- if(this.freezed) return;
- let target = e.target as HTMLElement;
- target = findUpClassName(target, 'selector-user');
-
- if(!target) return;
-
- let peerID = target.dataset.peerID;
- let li = this.chatList.querySelector('[data-peerid="' + peerID + '"]') as HTMLElement;
- li.click();
- });
-
- this.container.append(topContainer, delimiter, this.chatsContainer);
- appendTo.append(this.container);
- }
-
- private add(peerID: number) {
- let div = document.createElement('div');
- div.classList.add('selector-user', 'scale-in');
- div.dataset.peerID = '' + peerID;
- this.selected[peerID] = div;
-
- let title = appPeersManager.getPeerTitle(peerID, false, true);
-
- let avatarDiv = document.createElement('div');
- avatarDiv.classList.add('user-avatar', 'tgico');
- appProfileManager.putPhoto(avatarDiv, peerID);
-
- div.innerHTML = title;
- div.insertAdjacentElement('afterbegin', avatarDiv);
-
- this.selectedContainer.insertBefore(div, this.searchInput);
- this.selectedScrollable.scrollTop = this.selectedScrollable.scrollHeight;
- this.onChange(Object.keys(this.selected).length);
- }
-
- private remove(peerID: number) {
- let div = this.selected[peerID];
- div.classList.remove('scale-in');
- void div.offsetWidth;
- div.classList.add('scale-out');
- div.addEventListener('animationend', () => {
- delete this.selected[peerID];
- div.remove();
- this.onChange(Object.keys(this.selected).length);
- }, {once: true});
- }
-
- public getSelected() {
- return Object.keys(this.selected).map(p => +p);
- }
-}
+import { AppSelectPeers } from "./appSelectPeers";
class AppForward {
private container = document.getElementById('forward-container') as HTMLDivElement;
diff --git a/src/components/appSearch.ts b/src/components/appSearch.ts
index 5f236775..f4e54b93 100644
--- a/src/components/appSearch.ts
+++ b/src/components/appSearch.ts
@@ -13,10 +13,10 @@ export class SearchGroup {
nameEl: HTMLDivElement;
list: HTMLUListElement;
- constructor(public name: string, public type: string, private clearable = true, className?: string) {
+ constructor(public name: string, public type: string, private clearable = true, className?: string, clickable = true) {
this.list = document.createElement('ul');
this.container = document.createElement('div');
- if(className) this.container.classList.add(className);
+ if(className) this.container.className = className;
this.nameEl = document.createElement('div');
this.nameEl.classList.add('search-group__name');
this.nameEl.innerText = name;
@@ -25,7 +25,9 @@ export class SearchGroup {
this.container.append(this.nameEl, this.list);
this.container.style.display = 'none';
- appDialogsManager.setListClickListener(this.list);
+ if(clickable) {
+ appDialogsManager.setListClickListener(this.list);
+ }
}
clear() {
diff --git a/src/components/appSelectPeers.ts b/src/components/appSelectPeers.ts
new file mode 100644
index 00000000..b9cf489a
--- /dev/null
+++ b/src/components/appSelectPeers.ts
@@ -0,0 +1,214 @@
+import Scrollable from "./scrollable_new";
+import appMessagesManager from "../lib/appManagers/appMessagesManager";
+import { $rootScope, cancelEvent, findUpTag, findUpClassName } from "../lib/utils";
+import appDialogsManager from "../lib/appManagers/appDialogsManager";
+import appChatsManager from "../lib/appManagers/appChatsManager";
+import appUsersManager from "../lib/appManagers/appUsersManager";
+import { appPeersManager } from "../lib/services";
+import appProfileManager from "../lib/appManagers/appProfileManager";
+import appPhotosManager from "../lib/appManagers/appPhotosManager";
+
+export class AppSelectPeers {
+ public container = document.createElement('div');
+ private list = document.createElement('ul');
+ private chatsContainer = document.createElement('div');
+ private scrollable: Scrollable;
+ private selectedScrollable: Scrollable;
+
+ private selectedContainer = document.createElement('div');
+ private input = document.createElement('input');
+
+ private selected: {[peerID: number]: HTMLDivElement} = {};
+
+ public freezed = false;
+
+ private myID = $rootScope.myID;
+
+ private offsetIndex = 0;
+ private promise: Promise;
+
+ private query = '';
+ private cachedContacts: number[];
+
+ constructor(private appendTo: HTMLDivElement, private onChange?: (length: number) => void, private peerType: 'contacts' | 'dialogs' = 'dialogs') {
+ this.container.classList.add('selector');
+
+ let topContainer = document.createElement('div');
+ topContainer.classList.add('selector-search-container');
+
+ this.selectedContainer.classList.add('selector-search');
+ this.input.placeholder = peerType == 'contacts' ? 'Add People...' : 'Select chat';
+ this.input.type = 'text';
+ this.selectedContainer.append(this.input);
+ topContainer.append(this.selectedContainer);
+ this.selectedScrollable = new Scrollable(topContainer);
+
+ let delimiter = document.createElement('hr');
+
+ this.chatsContainer.classList.add('chats-container');
+ this.chatsContainer.append(this.list);
+ this.scrollable = new Scrollable(this.chatsContainer);
+
+ this.list.addEventListener('click', (e) => {
+ let target = e.target as HTMLElement;
+ cancelEvent(e);
+
+ if(this.freezed) return;
+
+ if(target.tagName != 'LI') {
+ target = findUpTag(target, 'LI');
+ }
+
+ if(!target) return;
+
+ let peerID = +target.getAttribute('data-peerID');
+ target.classList.toggle('active');
+ if(peerID in this.selected) {
+ this.remove(peerID);
+ } else {
+ this.add(peerID);
+ }
+
+ let checkbox = target.querySelector('input') as HTMLInputElement;
+ checkbox.checked = !checkbox.checked;
+ });
+
+ this.selectedContainer.addEventListener('click', (e) => {
+ if(this.freezed) return;
+ let target = e.target as HTMLElement;
+ target = findUpClassName(target, 'selector-user');
+
+ if(!target) return;
+
+ let peerID = target.dataset.peerID;
+ let li = this.list.querySelector('[data-peerid="' + peerID + '"]') as HTMLElement;
+ li.click();
+ });
+
+ this.input.addEventListener('input', () => {
+ let value = this.input.value;
+ if(this.query != value) {
+ if(this.peerType == 'contacts') {
+ this.cachedContacts = null;
+ this.promise = null;
+ }
+
+ this.list.innerHTML = '';
+ this.query = value;
+
+ console.log('selectPeers input:', this.query);
+ this.getMoreResults();
+ }
+ });
+
+ this.scrollable.onScrolledBottom = () => {
+ this.getMoreResults();
+ };
+
+ this.container.append(topContainer, delimiter, this.chatsContainer);
+ appendTo.append(this.container);
+
+ this.getMoreResults();
+ }
+
+ private getMoreDialogs() {
+ // в десктопе - сначала без группы, потом архивные, потом контакты без сообщений
+ appMessagesManager.getConversations(this.offsetIndex, 50, 0).then(value => {
+ let dialogs = value.dialogs;
+
+ this.offsetIndex = dialogs[value.dialogs.length - 1].index || 0;
+
+ if(dialogs[0].peerID != this.myID) {
+ dialogs.findAndSplice(d => d.peerID == this.myID);
+ dialogs.unshift({
+ peerID: this.myID,
+ pFlags: {}
+ } as any);
+ }
+
+ this.renderResults(dialogs.map(dialog => dialog.peerID));
+ });
+ }
+
+ private async getMoreContacts() {
+ if(this.promise) return this.promise;
+
+ if(!this.cachedContacts) {
+ this.promise = appUsersManager.getContacts(this.query);
+ this.cachedContacts = (await this.promise).slice();
+ this.cachedContacts.findAndSplice(userID => userID == this.myID); // no my account
+ this.promise = null;
+ }
+
+ if(this.cachedContacts.length) {
+ let pageCount = appPhotosManager.windowH / 72 * 1.25 | 0;
+ let arr = this.cachedContacts.splice(0, pageCount);
+ this.renderResults(arr);
+ }
+ }
+
+ private getMoreResults() {
+ if(this.peerType == 'dialogs') {
+ this.getMoreDialogs();
+ } else {
+ this.getMoreContacts();
+ }
+ }
+
+ private renderResults(peerIDs: number[]) {
+ peerIDs.forEach(peerID => {
+ let {dom} = appDialogsManager.addDialog(peerID, this.list, false, false);
+ dom.containerEl.insertAdjacentHTML('afterbegin', '');
+
+ let subtitle = '';
+ if(peerID < 0) {
+ subtitle = appChatsManager.getChatMembersString(-peerID);
+ } else if(peerID == this.myID) {
+ subtitle = 'chat with yourself';
+ } else {
+ subtitle = appUsersManager.getUserStatusString(peerID);
+ if(subtitle == 'online') {
+ subtitle = `${subtitle}`;
+ }
+ }
+
+ dom.lastMessageSpan.innerHTML = subtitle;
+ });
+ }
+
+ private add(peerID: number) {
+ let div = document.createElement('div');
+ div.classList.add('selector-user', 'scale-in');
+ div.dataset.peerID = '' + peerID;
+ this.selected[peerID] = div;
+
+ let title = appPeersManager.getPeerTitle(peerID, false, true);
+
+ let avatarDiv = document.createElement('div');
+ avatarDiv.classList.add('user-avatar', 'tgico');
+ appProfileManager.putPhoto(avatarDiv, peerID);
+
+ div.innerHTML = title;
+ div.insertAdjacentElement('afterbegin', avatarDiv);
+
+ this.selectedContainer.insertBefore(div, this.input);
+ this.selectedScrollable.scrollTop = this.selectedScrollable.scrollHeight;
+ this.onChange && this.onChange(Object.keys(this.selected).length);
+ }
+
+ private remove(peerID: number) {
+ let div = this.selected[peerID];
+ div.classList.remove('scale-in');
+ void div.offsetWidth;
+ div.classList.add('scale-out');
+ div.addEventListener('animationend', () => {
+ delete this.selected[peerID];
+ div.remove();
+ this.onChange && this.onChange(Object.keys(this.selected).length);
+ }, {once: true});
+ }
+
+ public getSelected() {
+ return Object.keys(this.selected).map(p => +p);
+ }
+}
\ No newline at end of file
diff --git a/src/components/poll.ts b/src/components/poll.ts
new file mode 100644
index 00000000..0b83ed65
--- /dev/null
+++ b/src/components/poll.ts
@@ -0,0 +1,200 @@
+import appPollsManager, { PollResults } from "../lib/appManagers/appPollsManager";
+import { RichTextProcessor } from "../lib/richtextprocessor";
+
+let lineTotalLength = 0;
+const tailLength = 9;
+const times = 10;
+const fullTime = 340;
+const oneTime = fullTime / times;
+
+export default class PollElement extends HTMLElement {
+ private svgLines: SVGSVGElement[];
+ private numberDivs: HTMLDivElement[];
+ private maxOffset = -44.8;
+ private maxLength: number;
+ private maxLengths: number[];
+
+ constructor() {
+ super();
+ // элемент создан
+ }
+
+ connectedCallback() {
+ // браузер вызывает этот метод при добавлении элемента в документ
+ // (может вызываться много раз, если элемент многократно добавляется/удаляется)
+
+ if(!lineTotalLength) {
+ lineTotalLength = (document.getElementById('poll-line') as any as SVGPathElement).getTotalLength();
+ console.log('line total length:', lineTotalLength);
+ }
+
+ let pollID = this.getAttribute('poll-id');
+ let {poll, results} = appPollsManager.getPoll(pollID);
+
+ console.log('pollElement poll:', poll, results);
+
+ let desc = '';
+ if(poll.pFlags) {
+ if(poll.pFlags.closed) {
+ desc = 'Final results';
+ } else {
+ desc = poll.pFlags.public_voters ? 'Public Poll' : 'Anonymous Poll';
+ }
+ }
+
+ let votes = poll.answers.map(answer => {
+ return `
+
+
+
+
+
${RichTextProcessor.wrapEmojiText(answer.text)}
+
+ `;
+ }).join('');
+
+ this.innerHTML = `
+ ${poll.rQuestion}
+ ${desc}
+ ${votes}
+ ${results.total_voters ? results.total_voters + ' voters' : 'No votes'}
+ `;
+
+ let width = this.getBoundingClientRect().width;
+ this.maxLength = width + tailLength + this.maxOffset + -9; // 13 - position left
+ this.performResults(results);
+ }
+
+ disconnectedCallback() {
+ // браузер вызывает этот метод при удалении элемента из документа
+ // (может вызываться много раз, если элемент многократно добавляется/удаляется)
+ }
+
+ static get observedAttributes(): string[] {
+ return [/* массив имён атрибутов для отслеживания их изменений */];
+ }
+
+ attributeChangedCallback(name: string, oldValue: string, newValue: string) {
+ // вызывается при изменении одного из перечисленных выше атрибутов
+ }
+
+ adoptedCallback() {
+ // вызывается, когда элемент перемещается в новый документ
+ // (происходит в document.adoptNode, используется очень редко)
+ }
+
+ performResults(results: PollResults) {
+ const percents = results.results.map(v => v.voters / results.total_voters * 100);
+ this.setResults(percents);
+ }
+
+ setResults(percents: number[]) {
+ if(!this.svgLines) {
+ this.svgLines = Array.from(this.querySelectorAll('.poll-line')) as SVGSVGElement[];
+ this.numberDivs = Array.from(this.querySelectorAll('.poll-answer-percents')) as HTMLDivElement[];
+ }
+
+ let maxValue = Math.max(...percents);
+
+ this.maxLengths = percents.map(p => p / maxValue * this.maxLength);
+
+ /* this.svgLines.forEach((svg, idx) => {
+ this.setLineProgress(idx, 1);
+ }); */
+
+ /* percents = percents.map(p => {
+ return Math.round(p);
+ }); */
+
+ console.log('setResults before percents:', percents);
+
+ let sum = percents.reduce((acc, p) => acc + Math.round(p), 0);
+ if(sum > 100) {
+ let diff = sum - 100;
+ let length = percents.length;
+ for(let i = 0; i < diff; ++i) {
+ let minIndex = -1, minRemainder = 1;
+ for(let k = 0; k < length; ++k) {
+ let remainder = percents[k] % 1;
+ if(remainder >= 0.5 && remainder < minRemainder) {
+ minRemainder = remainder;
+ minIndex = k;
+ }
+ }
+
+ if(minIndex == -1) {
+ throw new Error('lol chto');
+ }
+
+ percents[minIndex] -= minRemainder;
+ }
+ } else {
+ let diff = 100 - sum;
+ let length = percents.length;
+ for(let i = 0; i < diff; ++i) {
+ let minIndex = -1, maxRemainder = 0;
+ for(let k = 0; k < length; ++k) {
+ let remainder = percents[k] % 1;
+ if(remainder < 0.5 && remainder > maxRemainder) {
+ maxRemainder = remainder;
+ minIndex = k;
+ }
+ }
+
+ if(minIndex == -1) {
+ throw new Error('lol chto');
+ }
+
+ percents[minIndex] += 1 - maxRemainder;
+ }
+ }
+
+ console.log('setResults after percents:', percents, sum);
+
+ let start = Date.now();
+ let r = () => {
+ let diff = Date.now() - start;
+ let progress = diff / fullTime;
+ if(progress > 1) progress = 1;
+
+ this.svgLines.forEach((svg, idx) => {
+ this.setLineProgress(idx, progress);
+ });
+
+ if(progress < 1) {
+ window.requestAnimationFrame(r);
+ }
+ };
+ window.requestAnimationFrame(r);
+
+ for(let i = 0; i < times; ++i) {
+ setTimeout(() => {
+ percents.forEach((percents, idx) => {
+ let value = Math.round(percents / times * (i + 1));
+ let div = this.numberDivs[idx];
+ //div.style.opacity = ((i + 1) * 0.10).toFixed(1); // опасити в 10 шагов от 0.1 до 1
+ div.innerText = value + '%';
+ });
+ }, oneTime * i);
+ }
+
+ this.classList.add('is-voted');
+ }
+
+ setLineProgress(index: number, percents: number) {
+ let svg = this.svgLines[index];
+ svg.style.strokeDasharray = (percents * this.maxLengths[index]) + ', 485.9';
+ svg.style.strokeDashoffset = '' + percents * this.maxOffset;
+ }
+
+ // у элемента могут быть ещё другие методы и свойства
+}
+
+customElements.define("poll-element", PollElement);
\ No newline at end of file
diff --git a/src/components/popupAvatar.ts b/src/components/popupAvatar.ts
new file mode 100644
index 00000000..d550c8f7
--- /dev/null
+++ b/src/components/popupAvatar.ts
@@ -0,0 +1,97 @@
+import resizeableImage from "../lib/cropper";
+import apiFileManager from "../lib/mtproto/apiFileManager";
+
+export class PopupAvatar {
+ private container = document.getElementById('popup-avatar');
+ private input = this.container.querySelector('input') as HTMLInputElement;
+ private cropContainer = this.container.querySelector('.crop') as HTMLDivElement;
+ private closeBtn = this.container.querySelector('.popup-close') as HTMLButtonElement;
+ private image = new Image();
+
+ private canvas: HTMLCanvasElement;
+ private blob: Blob;
+ private cropper = {
+ crop: () => {},
+ removeHandlers: () => {}
+ };
+
+ private onCrop: (upload: () => Promise) => void;
+
+ constructor() {
+ this.container.style.display = ''; // need for no blink
+ this.cropContainer.append(this.image);
+
+ this.input.addEventListener('change', (e: any) => {
+ var file = e.target.files[0];
+ if(!file) {
+ return;
+ }
+
+ var reader = new FileReader();
+ reader.onload = (e) => {
+ var contents = e.target.result as string;
+
+ this.image = new Image();
+ this.cropContainer.append(this.image);
+ this.image.src = contents;
+
+ this.image.onload = () => {
+ /* let {w, h} = calcImageInBox(this.image.naturalWidth, this.image.naturalHeight, 460, 554);
+ cropContainer.style.width = w + 'px';
+ cropContainer.style.height = h + 'px'; */
+ this.container.classList.remove('hide');
+ void this.container.offsetWidth; // reflow
+ this.container.classList.add('active');
+
+ this.cropper = resizeableImage(this.image, this.canvas);
+ this.input.value = '';
+ };
+ };
+
+ reader.readAsDataURL(file);
+ }, false);
+
+ // apply
+ this.container.querySelector('.btn-crop').addEventListener('click', () => {
+ this.cropper.crop();
+ this.closeBtn.click();
+
+ this.canvas.toBlob(blob => {
+ this.blob = blob; // save blob to send after reg
+
+ // darken
+ let ctx = this.canvas.getContext('2d');
+ ctx.fillStyle = "rgba(0, 0, 0, 0.3)";
+ ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
+
+ this.resolve();
+ }, 'image/jpeg', 1);
+ });
+
+ this.closeBtn.addEventListener('click', () => {
+ setTimeout(() => {
+ this.cropper.removeHandlers();
+ if(this.image) {
+ this.image.remove();
+ }
+
+ this.container.classList.add('hide');
+ }, 200);
+ });
+ }
+
+ private resolve() {
+ this.onCrop(() => {
+ return apiFileManager.uploadFile(this.blob);
+ });
+ }
+
+ public open(postCanvas: HTMLCanvasElement, onCrop: (upload: () => Promise) => void) {
+ this.canvas = postCanvas;
+ this.onCrop = onCrop;
+
+ this.input.click();
+ }
+}
+
+export default new PopupAvatar();
diff --git a/src/components/wrappers.ts b/src/components/wrappers.ts
index 46ef2c86..5e0d0a47 100644
--- a/src/components/wrappers.ts
+++ b/src/components/wrappers.ts
@@ -15,6 +15,8 @@ import { CancellablePromise } from '../lib/polyfill';
import { renderImageFromUrl } from './misc';
import appMessagesManager from '../lib/appManagers/appMessagesManager';
import { Layouter, RectPart } from './groupedLayout';
+import { Poll, PollResults } from '../lib/appManagers/appPollsManager';
+import PollElement from './poll';
export type MTDocument = {
_: 'document' | 'documentEmpty',
@@ -701,11 +703,11 @@ export function wrapSticker(doc: MTDocument, div: HTMLDivElement, middleware?: (
}
if(!stickerType) {
- console.error('wrong doc for wrapSticker!', doc, div);
+ console.error('wrong doc for wrapSticker!', doc);
return Promise.resolve();
}
- console.log('wrap sticker', doc, div, onlyThumb);
+ //console.log('wrap sticker', doc, div, onlyThumb);
if(doc.thumbs && !div.firstElementChild && (!doc.downloaded || stickerType == 2)) {
let thumb = doc.thumbs[0];
@@ -875,6 +877,10 @@ export function wrapReply(title: string, subtitle: string, message?: any) {
if(media) {
if(message.grouped_id) {
replySubtitle.innerHTML = 'Album';
+ } else if(media._ == 'messageMediaContact') {
+ replySubtitle.innerHTML = 'Contact';
+ } else if(media._ == 'messageMediaPoll') {
+ replySubtitle.innerHTML = media.poll.rReply;
} else if(media.photo) {
replySubtitle.innerHTML = 'Photo';
} else if(media.document && media.document.type) {
@@ -946,7 +952,13 @@ export function wrapAlbum({groupID, attachmentDiv, middleware, uploading, lazyLo
let brSplitted = fillPropertyValue(borderRadius); */
for(let {geometry, sides} of layout) {
- let {size, media, message} = items.shift();
+ let item = items.shift();
+ if(!item) {
+ console.error('no item for layout!');
+ continue;
+ }
+
+ let {size, media, message} = item;
let div = document.createElement('div');
div.classList.add('album-item');
div.dataset.mid = message.mid;
@@ -1041,3 +1053,9 @@ export function wrapAlbum({groupID, attachmentDiv, middleware, uploading, lazyLo
attachmentDiv.append(div);
}
}
+
+export function wrapPoll(poll: Poll, results: PollResults) {
+ let elem = new PollElement();
+ elem.setAttribute('poll-id', poll.id);
+ return elem;
+}
diff --git a/src/format_schema.js b/src/format_schema.js
new file mode 100644
index 00000000..15d7496b
--- /dev/null
+++ b/src/format_schema.js
@@ -0,0 +1,68 @@
+let json = require('./schema');
+
+let top = {};
+/* ['MTProto', 'API'].forEach(key => {
+ let schema = json[key];
+ let out = {constructors: {}, methods: {}};
+
+ ['constructors', 'methods'].forEach(key => {
+ schema[key].forEach(smth => {
+ let id = smth.id;
+
+ if(id < 0) {
+ id = +id + 4294967296;
+ }
+
+ out[key][id] = smth;
+ delete smth.id;
+ });
+ });
+
+ top[key] = out;
+
+ //console.log(out);
+ //process.exit(0);
+}); */
+
+['MTProto', 'API'].forEach(key => {
+ let schema = json[key];
+
+ ['constructors', 'methods'].forEach(key => {
+ schema[key].forEach(smth => {
+ if(+smth.id < 0) {
+ smth.id = +smth.id + 4294967296;
+ }
+ });
+ });
+
+ //console.log(out);
+ //process.exit(0);
+});
+top = json;
+
+/* ['API'].forEach(key => {
+ let schema = json[key];
+ let out = {constructors: {}, methods: {}};
+
+ ['constructors', 'methods'].forEach(key => {
+ schema[key].forEach(smth => {
+ let id = smth.id;
+
+ if(id < 0) {
+ id = id + 4294967296;
+ }
+
+ out[key][id] = smth;
+ delete smth.id;
+ });
+ });
+
+ top[key] = out;
+
+ //console.log(out);
+ //process.exit(0);
+}); */
+
+//console.log(out);
+
+require('fs').writeFileSync('./schema_pretty.json', JSON.stringify(top/* , null, '\t' */));
\ No newline at end of file
diff --git a/src/lib/appManagers/appChatsManager.ts b/src/lib/appManagers/appChatsManager.ts
index f1aa0abc..48f05cec 100644
--- a/src/lib/appManagers/appChatsManager.ts
+++ b/src/lib/appManagers/appChatsManager.ts
@@ -1,9 +1,43 @@
import { $rootScope, isObject, SearchIndexManager, safeReplaceObject, copy, numberWithCommas } from "../utils";
import { RichTextProcessor } from "../richtextprocessor";
import appUsersManager from "./appUsersManager";
+import appPeersManager from "./appPeersManager";
+import apiManager from '../mtproto/mtprotoworker';
+import apiUpdatesManager from "./apiUpdatesManager";
+
+type Channel = {
+ _: 'channel',
+ flags: number,
+ pFlags: Partial<{
+ creator: true,
+ left: true,
+ broadcast: true,
+ verified: true,
+ megagroup: true,
+ restricted: true,
+ signatures: true,
+ min: true,
+ scam: true,
+ has_link: true,
+ has_geo: true,
+ slowmode_enabled: true
+ }>,
+ id: number,
+ access_hash?: string,
+ title: string,
+ username?: string,
+ photo: any,
+ date: number,
+ version: number,
+ restriction_reason?: any,
+ admin_rights?: any,
+ banned_rights?: any,
+ default_banned_rights?: any,
+ participants_count: number
+};
export class AppChatsManager {
- public chats: any = {};
+ public chats: {[id: number]: Channel | any} = {};
public usernames: any = {};
public channelAccess: any = {};
public megagroups: any = {};
@@ -143,8 +177,7 @@ export class AppChatsManager {
public isChannel(id: number) {
var chat = this.chats[id];
- if(chat && (chat._ == 'channel' || chat._ == 'channelForbidden') ||
- this.channelAccess[id]) {
+ if(chat && (chat._ == 'channel' || chat._ == 'channelForbidden') || this.channelAccess[id]) {
return true;
}
return false;
@@ -166,10 +199,6 @@ export class AppChatsManager {
return this.isChannel(id) && !this.isMegagroup(id);
}
- public getChatInput(id: number) {
- return id || 0;
- }
-
public getChannelInput(id: number) {
if(!id) {
return {_: 'inputChannelEmpty'};
@@ -182,6 +211,25 @@ export class AppChatsManager {
};
}
+ public getChatInputPeer(id: number) {
+ return {
+ _: 'inputPeerChat',
+ chat_id: id
+ };
+ }
+
+ public getChannelInputPeer(id: number) {
+ if(!id) {
+ return {_: 'inputPeerEmpty'};
+ }
+
+ return {
+ _: 'inputPeerChannel',
+ channel_id: id,
+ access_hash: this.getChat(id).access_hash || this.channelAccess[id] || 0
+ };
+ }
+
public hasChat(id: number, allowMin?: any) {
var chat = this.chats[id]
return isObject(chat) && (allowMin || !chat.pFlags.min);
@@ -217,7 +265,7 @@ export class AppChatsManager {
var chatFull = copy(fullChat);
var chat = this.getChat(id);
- if (!chatFull.participants_count) {
+ if(!chatFull.participants_count) {
chatFull.participants_count = chat.participants_count;
}
@@ -226,7 +274,7 @@ export class AppChatsManager {
chatFull.participants.participants = this.wrapParticipants(id, chatFull.participants.participants);
}
- if (chatFull.about) {
+ if(chatFull.about) {
chatFull.rAbout = RichTextProcessor.wrapRichText(chatFull.about, {noLinebreaks: true});
}
@@ -240,7 +288,7 @@ export class AppChatsManager {
var chat = this.getChat(id);
var myID = appUsersManager.getSelf().id;
if(this.isChannel(id)) {
- var isAdmin = chat.pFlags.creator || chat.pFlags.editor || chat.pFlags.moderator
+ var isAdmin = chat.pFlags.creator || chat.pFlags.editor || chat.pFlags.moderator;
participants.forEach((participant) => {
participant.canLeave = myID == participant.user_id;
participant.canKick = isAdmin && participant._ == 'channelParticipant';
@@ -249,7 +297,7 @@ export class AppChatsManager {
participant.user = appUsersManager.getUser(participant.user_id);
});
} else {
- var isAdmin = chat.pFlags.creator || chat.pFlags.admins_enabled && chat.pFlags.admin
+ var isAdmin = chat.pFlags.creator || chat.pFlags.admins_enabled && chat.pFlags.admin;
participants.forEach((participant) => {
participant.canLeave = myID == participant.user_id;
participant.canKick = !participant.canLeave && (
@@ -261,8 +309,70 @@ export class AppChatsManager {
participant.user = appUsersManager.getUser(participant.user_id);
});
}
+
return participants;
}
+
+ public createChannel(title: string, about: String): Promise {
+ return apiManager.invokeApi('channels.createChannel', {
+ flags: 1,
+ broadcast: true,
+ title: title,
+ about: about
+ }).then((updates: any) => {
+ apiUpdatesManager.processUpdateMessage(updates);
+
+ return updates.chats[0].id;
+ });
+ }
+
+ public inviteToChannel(id: number, userIDs: number[]) {
+ let input = this.getChannelInput(id);
+ let usersInputs = userIDs.map(u => appUsersManager.getUserInput(u));
+
+ return apiManager.invokeApi('channels.inviteToChannel', {
+ channel: input,
+ users: usersInputs
+ }).then(updates => {
+ apiUpdatesManager.processUpdateMessage(updates);
+ });
+ }
+
+ public createChat(title: string, userIDs: number[]): Promise {
+ return apiManager.invokeApi('messages.createChat', {
+ users: userIDs.map(u => appUsersManager.getUserInput(u)),
+ title: title
+ }).then(updates => {
+ apiUpdatesManager.processUpdateMessage(updates);
+
+ return updates.chats[0].id;
+ });
+ }
+
+ public editPhoto(id: number, inputFile: any) {
+ let isChannel = this.isChannel(id);
+
+ let inputChatPhoto = {
+ _: 'inputChatUploadedPhoto',
+ file: inputFile
+ };
+
+ if(isChannel) {
+ return apiManager.invokeApi('channels.editPhoto', {
+ channel: this.getChannelInputPeer(id),
+ photo: inputChatPhoto
+ }).then(updates => {
+ apiUpdatesManager.processUpdateMessage(updates);
+ });
+ } else {
+ return apiManager.invokeApi('messages.editChatPhoto', {
+ chat_id: id,
+ photo: inputChatPhoto
+ }).then(updates => {
+ apiUpdatesManager.processUpdateMessage(updates);
+ });
+ }
+ }
}
export default new AppChatsManager();
diff --git a/src/lib/appManagers/appDialogsManager.ts b/src/lib/appManagers/appDialogsManager.ts
index 8b009aec..9aa02951 100644
--- a/src/lib/appManagers/appDialogsManager.ts
+++ b/src/lib/appManagers/appDialogsManager.ts
@@ -9,6 +9,7 @@ import { ripple, putPreloader } from "../../components/misc";
import Scrollable from "../../components/scrollable_new";
import appProfileManager from "./appProfileManager";
import { logger } from "../polyfill";
+import appChatsManager from "./appChatsManager";
type DialogDom = {
avatarDiv: HTMLDivElement,
@@ -474,6 +475,12 @@ export class AppDialogsManager {
case 'messageMediaGeo':
lastMessageText += 'Geolocation';
break;
+ case 'messageMediaPoll':
+ lastMessageText += '' + lastMessage.media.poll.rReply + '';
+ break;
+ case 'messageMediaContact':
+ lastMessageText += 'Contact';
+ break;
case 'messageMediaDocument':
let document = lastMessage.media.document;
@@ -724,6 +731,18 @@ export class AppDialogsManager {
let titleSpan = document.createElement('span');
titleSpan.classList.add('user-title');
+ if(peerID < 0) {
+ let chat = appChatsManager.getChat(-peerID);
+ if(chat && chat.pFlags && chat.pFlags.verified) {
+ titleSpan.classList.add('is-verified');
+ }
+ } else {
+ let user = appUsersManager.getUser(peerID);
+ if(user && user.pFlags && user.pFlags.verified) {
+ titleSpan.classList.add('is-verified');
+ }
+ }
+
if(peerID == $rootScope.myID) {
title = onlyFirstName ? 'Saved' : 'Saved Messages';
}
diff --git a/src/lib/appManagers/appImManager.ts b/src/lib/appManagers/appImManager.ts
index 503b2959..d12baf0a 100644
--- a/src/lib/appManagers/appImManager.ts
+++ b/src/lib/appManagers/appImManager.ts
@@ -1,6 +1,6 @@
//import apiManager from '../mtproto/apiManager';
import apiManager from '../mtproto/mtprotoworker';
-import { $rootScope, isElementInViewport, numberWithCommas, findUpClassName, formatNumber, placeCaretAtEnd, findUpTag, langPack } from "../utils";
+import { $rootScope, numberWithCommas, findUpClassName, formatNumber, placeCaretAtEnd, findUpTag, langPack } from "../utils";
import appUsersManager from "./appUsersManager";
import appMessagesManager from "./appMessagesManager";
import appPeersManager from "./appPeersManager";
@@ -17,7 +17,7 @@ import appSidebarLeft from "./appSidebarLeft";
import appChatsManager from "./appChatsManager";
import appMessagesIDsManager from "./appMessagesIDsManager";
import apiUpdatesManager from './apiUpdatesManager';
-import { wrapDocument, wrapPhoto, wrapVideo, wrapSticker, wrapReply, wrapAlbum } from '../../components/wrappers';
+import { wrapDocument, wrapPhoto, wrapVideo, wrapSticker, wrapReply, wrapAlbum, wrapPoll } from '../../components/wrappers';
import ProgressivePreloader from '../../components/preloader';
import { openBtnMenu, formatPhoneNumber } from '../../components/misc';
import { ChatInput } from '../../components/chatInput';
@@ -838,8 +838,21 @@ export class AppImManager {
let [chatOnlines, chatInfo] = results;
let onlines = chatOnlines ? chatOnlines.onlines : 1;
+
+ if(chatInfo._ == 'chatFull' && chatInfo.participants && chatInfo.participants.participants) {
+ let participants = chatInfo.participants.participants;
+
+ onlines = participants.reduce((acc: number, participant: any) => {
+ let user = appUsersManager.getUser(participant.user_id);
+ if(user && user.status && user.status._ == 'userStatusOnline') {
+ return acc + 1;
+ }
+
+ return acc;
+ }, 0);
+ }
- ///////////this.log('chatInfo res:', chatInfo);
+ this.log('chatInfo res:', chatInfo);
if(chatInfo.pinned_msg_id) { // request pinned message
this.pinnedMsgID = chatInfo.pinned_msg_id;
@@ -882,6 +895,9 @@ export class AppImManager {
}
}
}
+ } else {
+ this.subtitleEl.innerText = 'bot';
+ appSidebarRight.profileElements.subtitle.innerText = 'bot';
}
}
@@ -1058,7 +1074,7 @@ export class AppImManager {
this.scroll.scrollTop = this.scroll.scrollHeight;
}
}
-
+
/* this.onScroll();
this.scrollable.onScroll();*/
@@ -1225,7 +1241,8 @@ export class AppImManager {
// reverse means top
public renderMessage(message: any, reverse = false, multipleRender = false, bubble: HTMLDivElement = null, updatePosition = true) {
- //this.log('message to render:', message);
+ this.log('message to render:', message);
+ //return;
if(message.deleted) return;
else if(message.grouped_id) { // will render only last album's message
let storage = appMessagesManager.groupedMessagesStorage[message.grouped_id];
@@ -1278,8 +1295,14 @@ export class AppImManager {
if(_ == "messageActionPhoneCall") {
_ += '.' + action.type;
}
+
// @ts-ignore
- let str = (name.innerText ? name.outerHTML + ' ' : '') + langPack[_];
+ let l = langPack[_];
+ if(!l) {
+ l = '[' + _ + ']';
+ }
+
+ let str = l[0].toUpperCase() == l[0] ? l : (name.innerText ? name.outerHTML + ' ' : '') + l;
bubbleContainer.innerHTML = `${str}
`;
/* if(!updatePosition) {
@@ -1401,7 +1424,7 @@ export class AppImManager {
}
// media
- if(message.media) {
+ if(message.media/* && message.media._ == 'messageMediaPhoto' */) {
let attachmentDiv = document.createElement('div');
attachmentDiv.classList.add('attachment');
@@ -1712,6 +1735,15 @@ export class AppImManager {
break;
}
+
+ case 'messageMediaPoll': {
+ bubble.classList.remove('is-message-empty');
+
+ let pollElement = wrapPoll(message.media.poll, message.media.results);
+ messageDiv.prepend(pollElement);
+
+ break;
+ }
default:
bubble.classList.remove('is-message-empty');
@@ -1877,7 +1909,7 @@ export class AppImManager {
let _history = history.slice();
setTimeout(() => {
this.performHistoryResult(_history, reverse, isBackLimit, 0, resetPromises);
- }, (i + 1) * 2500);
+ }, 0/* (i + 1) * 2500 */);
}
}
@@ -2092,8 +2124,8 @@ export class AppImManager {
this.log('getHistory: slice loadedTimes:', reverse, pageCount, this.loadedTopTimes, this.loadedBottomTimes, ids && ids.length);
- let removeCount = loadCount / 2;
- let safeCount = realLoadCount * 2;
+ //let removeCount = loadCount / 2;
+ let safeCount = Math.min(realLoadCount * 2, 35); // cause i've been runningrunningrunning all day
if(ids && ids.length > safeCount) {
if(reverse) {
//ids = ids.slice(-removeCount);
@@ -2210,48 +2242,50 @@ export class AppImManager {
public handleUpdate(update: any) {
switch(update._) {
case 'updateUserTyping':
- case 'updateChatUserTyping':
- if(this.myID == update.user_id) {
- return;
- }
-
- var peerID = update._ == 'updateUserTyping' ? update.user_id : -update.chat_id;
- this.typingUsers[update.user_id] = peerID;
-
- if(!appUsersManager.hasUser(update.user_id)) {
- if(update.chat_id && appChatsManager.hasChat(update.chat_id) && !appChatsManager.isChannel(update.chat_id)) {
- appProfileManager.getChatFull(update.chat_id);
+ case 'updateChatUserTyping': {
+ if(this.myID == update.user_id) {
+ return;
}
- //return;
- }
-
- appUsersManager.forceUserOnline(update.user_id);
-
- let dialog = appMessagesManager.getDialogByPeerID(peerID)[0];
- let currentPeer = this.peerID == peerID;
-
- if(this.typingTimeouts[peerID]) clearTimeout(this.typingTimeouts[peerID]);
- else if(dialog) {
- appDialogsManager.setTyping(dialog, appUsersManager.getUser(update.user_id));
+ var peerID = update._ == 'updateUserTyping' ? update.user_id : -update.chat_id;
+ this.typingUsers[update.user_id] = peerID;
- if(currentPeer) { // user
- this.setPeerStatus();
+ if(!appUsersManager.hasUser(update.user_id)) {
+ if(update.chat_id && appChatsManager.hasChat(update.chat_id) && !appChatsManager.isChannel(update.chat_id)) {
+ appProfileManager.getChatFull(update.chat_id);
+ }
+
+ //return;
}
- }
-
- this.typingTimeouts[peerID] = setTimeout(() => {
- this.typingTimeouts[peerID] = 0;
- delete this.typingUsers[update.user_id];
- if(dialog) {
- appDialogsManager.unsetTyping(dialog);
+ appUsersManager.forceUserOnline(update.user_id);
+
+ let dialog = appMessagesManager.getDialogByPeerID(peerID)[0];
+ let currentPeer = this.peerID == peerID;
+
+ if(this.typingTimeouts[peerID]) clearTimeout(this.typingTimeouts[peerID]);
+ else if(dialog) {
+ appDialogsManager.setTyping(dialog, appUsersManager.getUser(update.user_id));
+
+ if(currentPeer) { // user
+ this.setPeerStatus();
+ }
}
- // лень просчитывать случаи
- this.setPeerStatus();
- }, 6000);
- break;
+ this.typingTimeouts[peerID] = setTimeout(() => {
+ this.typingTimeouts[peerID] = 0;
+ delete this.typingUsers[update.user_id];
+
+ if(dialog) {
+ appDialogsManager.unsetTyping(dialog);
+ }
+
+ // лень просчитывать случаи
+ this.setPeerStatus();
+ }, 6000);
+
+ break;
+ }
case 'updateNotifySettings': {
let {peer, notify_settings} = update;
diff --git a/src/lib/appManagers/appMessagesManager.ts b/src/lib/appManagers/appMessagesManager.ts
index 07a17001..0abfd945 100644
--- a/src/lib/appManagers/appMessagesManager.ts
+++ b/src/lib/appManagers/appMessagesManager.ts
@@ -21,6 +21,7 @@ import serverTimeManager from "../mtproto/serverTimeManager";
import apiManager from '../mtproto/mtprotoworker';
import appWebPagesManager from "./appWebPagesManager";
import { CancellablePromise, deferredPromise } from "../polyfill";
+import appPollsManager from "./appPollsManager";
const APITIMEOUT = 0;
@@ -1501,7 +1502,10 @@ export class AppMessagesManager {
apiMessage.media.photo = appPhotosManager.savePhoto(apiMessage.media.photo, mediaContext);
//appPhotosManager.savePhoto(apiMessage.media.photo, mediaContext);
}
- break
+ break;
+ case 'messageMediaPoll':
+ appPollsManager.savePoll(apiMessage.media.poll, apiMessage.media.results);
+ break;
case 'messageMediaDocument':
if(apiMessage.media.ttl_seconds) {
apiMessage.media = {_: 'messageMediaUnsupportedWeb'};
diff --git a/src/lib/appManagers/appPeersManager.ts b/src/lib/appManagers/appPeersManager.ts
index b757793d..b1d5e821 100644
--- a/src/lib/appManagers/appPeersManager.ts
+++ b/src/lib/appManagers/appPeersManager.ts
@@ -30,10 +30,12 @@ const AppPeersManager = {
if(peerID >= 0) {
return false;
}
- var chat = appChatsManager.getChat(-peerID);
+
+ let chat = appChatsManager.getChat(-peerID);
if(chat && chat.migrated_to && chat.pFlags.deactivated) {
return AppPeersManager.getPeerID(chat.migrated_to);
}
+
return false;
},
@@ -66,10 +68,11 @@ const AppPeersManager = {
return {_: 'peerUser', user_id: peerID};
}
- var chatID = -peerID;
+ let chatID = -peerID;
if(appChatsManager.isChannel(chatID)) {
return {_: 'peerChannel', channel_id: chatID};
}
+
return {_: 'peerChat', chat_id: chatID};
},
@@ -99,8 +102,8 @@ const AppPeersManager = {
? peerString.user_id
: -(peerString.channel_id || peerString.chat_id);
}
- var isUser = peerString.charAt(0) == 'u';
- var peerParams = peerString.substr(1).split('_');
+ let isUser = peerString.charAt(0) == 'u';
+ let peerParams = peerString.substr(1).split('_');
return isUser ? peerParams[0] : -peerParams[0] || 0;
},
@@ -125,25 +128,52 @@ const AppPeersManager = {
return (peerID > 0) && appUsersManager.isBot(peerID);
},
+ getInputPeer: (peerString: string): any => {
+ var firstChar = peerString.charAt(0);
+ var peerParams = peerString.substr(1).split('_');
+ let id = +peerParams[0];
+
+ if(firstChar == 'u') {
+ appUsersManager.saveUserAccess(id, peerParams[1]);
+
+ return {
+ _: 'inputPeerUser',
+ user_id: id,
+ access_hash: peerParams[1]
+ };
+ } else if(firstChar == 'c' || firstChar == 's') {
+ appChatsManager.saveChannelAccess(id, peerParams[1]);
+ if(firstChar == 's') {
+ appChatsManager.saveIsMegagroup(id);
+ }
+
+ return {
+ _: 'inputPeerChannel',
+ channel_id: id,
+ access_hash: peerParams[1] || 0
+ };
+ } else {
+ return {
+ _: 'inputPeerChat',
+ chat_id: id
+ };
+ }
+ },
+
getInputPeerByID: (peerID: number) => {
- if (!peerID) {
- return {_: 'inputPeerEmpty'}
+ if(!peerID) {
+ return {_: 'inputPeerEmpty'};
}
- if (peerID < 0) {
- var chatID = -peerID
- if (!appChatsManager.isChannel(chatID)) {
- return {
- _: 'inputPeerChat',
- chat_id: chatID
- };
+
+ if(peerID < 0) {
+ let chatID = -peerID;
+ if(!appChatsManager.isChannel(chatID)) {
+ return appChatsManager.getChatInputPeer(chatID);
} else {
- return {
- _: 'inputPeerChannel',
- channel_id: chatID,
- access_hash: appChatsManager.getChat(chatID).access_hash || 0
- };
+ return appChatsManager.getChannelInputPeer(chatID);
}
}
+
return {
_: 'inputPeerUser',
user_id: peerID,
@@ -158,11 +188,11 @@ const AppPeersManager = {
},
getPeerSearchText: (peerID: number) => {
- var text
+ let text;
if(peerID > 0) {
text = '%pu ' + appUsersManager.getUserSearchText(peerID);
} else if(peerID < 0) {
- var chat = appChatsManager.getChat(-peerID);
+ let chat = appChatsManager.getChat(-peerID);
text = '%pg ' + (chat.title || '');
}
return text;
diff --git a/src/lib/appManagers/appPollsManager.ts b/src/lib/appManagers/appPollsManager.ts
new file mode 100644
index 00000000..b0eaa4e4
--- /dev/null
+++ b/src/lib/appManagers/appPollsManager.ts
@@ -0,0 +1,89 @@
+import { RichTextProcessor } from "../richtextprocessor";
+
+export type PollAnswer = {
+ _: 'pollAnswer',
+ text: string,
+ option: Uint8Array
+};
+
+export type PollAnswerVoters = {
+ _: 'pollAnswerVoters',
+ flags: number,
+ option: Uint8Array,
+ voters: number,
+
+ pFlags: Partial<{
+ chosen: true,
+ correct: true
+ }>
+};
+
+export type PollResult = {
+ _: 'pollAnswerVoters',
+ flags: number,
+ option: Uint8Array,
+ voters: number,
+
+ pFlags?: Partial<{chosen: true}>
+};
+
+export type PollResults = {
+ _: 'pollResults',
+ flags: number,
+ results?: Array,
+ total_voters?: number,
+ recent_voters?: number[],
+ solution?: string,
+ solution_entities?: any[],
+
+ pFlags: Partial<{
+ min: true
+ }>,
+};
+
+export type Poll = {
+ _: 'poll',
+ flags: number,
+ question: string,
+ id: string,
+ answers: Array,
+ close_period?: number,
+ close_date?: number
+
+ pFlags?: Partial<{
+ closed: true,
+ public_voters: true,
+ multiple_choice: true,
+ quiz: true
+ }>,
+ rQuestion?: string,
+ rReply?: string,
+};
+
+class AppPollsManager {
+ private polls: {[id: string]: Poll} = {};
+ private results: {[id: string]: PollResults} = {};
+
+ public savePoll(poll: Poll, results: PollResults) {
+ let id = poll.id;
+ if(this.polls[id]) {
+ this.results[id] = results;
+ return;
+ }
+
+ this.polls[id] = poll;
+ this.results[id] = results;
+
+ poll.rQuestion = RichTextProcessor.wrapEmojiText(poll.question);
+ poll.rReply = RichTextProcessor.wrapEmojiText('📊') + ' ' + (poll.rQuestion || 'poll');
+ }
+
+ public getPoll(pollID: string): {poll: Poll, results: PollResults} {
+ return {
+ poll: this.polls[pollID],
+ results: this.results[pollID]
+ };
+ }
+}
+
+export default new AppPollsManager();
\ No newline at end of file
diff --git a/src/lib/appManagers/appSidebarLeft.ts b/src/lib/appManagers/appSidebarLeft.ts
index 1256e798..436ab903 100644
--- a/src/lib/appManagers/appSidebarLeft.ts
+++ b/src/lib/appManagers/appSidebarLeft.ts
@@ -5,17 +5,318 @@ import appImManager from "./appImManager";
//import apiManager from '../mtproto/apiManager';
import apiManager from '../mtproto/mtprotoworker';
import AppSearch, { SearchGroup } from "../../components/appSearch";
-import { horizontalMenu } from "../../components/misc";
+import { horizontalMenu, putPreloader } from "../../components/misc";
import appUsersManager from "./appUsersManager";
import Scrollable from "../../components/scrollable_new";
import appPhotosManager from "./appPhotosManager";
import { appPeersManager } from "../services";
+import popupAvatar from "../../components/popupAvatar";
+import appChatsManager from "./appChatsManager";
+import { AppSelectPeers } from "../../components/appSelectPeers";
const SLIDERITEMSIDS = {
archived: 1,
- contacts: 2
+ contacts: 2,
+ newChannel: 3,
+ addMembers: 4,
+ newGroup: 5,
};
+interface SliderTab {
+ onClose?: () => void,
+ onCloseAfterTimeout?: () => void
+}
+
+class AppAddMembersTab implements SliderTab {
+ private container = document.querySelector('.addmembers-container') as HTMLDivElement;
+ 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 peerType: 'channel' | 'chat';
+ private peerID: number; // always positive
+ private takeOut: (peerIDs: number[]) => void
+
+ constructor() {
+ this.nextBtn.addEventListener('click', () => {
+ let peerIDs = this.selector.getSelected();
+
+ if(peerIDs.length) {
+ if(this.takeOut) {
+ this.takeOut(peerIDs);
+ return;
+ }
+
+ this.nextBtn.classList.remove('tgico-next');
+ this.nextBtn.disabled = true;
+ putPreloader(this.nextBtn);
+ this.selector.freezed = true;
+
+ appChatsManager.inviteToChannel(this.peerID, peerIDs).then(() => {
+ this.backBtn.click();
+ });
+ }
+ });
+ }
+
+ public onCloseAfterTimeout() {
+ if(this.selector) {
+ this.selector.container.remove();
+ this.selector = null;
+ }
+ }
+
+ public init(id: number, type: 'channel' | 'chat', skipable: boolean, takeOut?: AppAddMembersTab['takeOut']) {
+ this.peerID = Math.abs(id);
+ this.peerType = type;
+ this.takeOut = takeOut;
+
+ this.onCloseAfterTimeout();
+ this.selector = new AppSelectPeers(this.contentDiv, skipable ? null : (length) => {
+ if(length) {
+ this.nextBtn.classList.add('is-visible');
+ } else {
+ this.nextBtn.classList.remove('is-visible');
+ }
+ }, 'contacts');
+
+ this.nextBtn.innerHTML = '';
+ this.nextBtn.disabled = false;
+ this.nextBtn.classList.add('tgico-next');
+ if(skipable) {
+ this.nextBtn.classList.add('is-visible');
+ } else {
+ this.nextBtn.classList.remove('is-visible');
+ }
+
+ appSidebarLeft.selectTab(SLIDERITEMSIDS.addMembers);
+ }
+}
+
+class AppNewChannelTab implements SliderTab {
+ private container = document.querySelector('.new-channel-container') as HTMLDivElement;
+ private canvas = this.container.querySelector('.avatar-edit-canvas') as HTMLCanvasElement;
+ private channelNameInput = this.container.querySelector('.new-channel-name') as HTMLInputElement;
+ private channelDescriptionInput = this.container.querySelector('.new-channel-description') as HTMLInputElement;
+ private nextBtn = this.container.querySelector('.btn-corner') as HTMLButtonElement;
+ private backBtn = this.container.querySelector('.sidebar-close-button') as HTMLButtonElement;
+ private uploadAvatar: () => Promise = null;
+
+ constructor() {
+ this.container.querySelector('.avatar-edit').addEventListener('click', () => {
+ popupAvatar.open(this.canvas, (_upload) => {
+ this.uploadAvatar = _upload;
+ });
+ });
+
+ this.channelNameInput.addEventListener('input', () => {
+ let value = this.channelNameInput.value;
+ if(value.length) {
+ this.nextBtn.classList.add('is-visible');
+ } else {
+ this.nextBtn.classList.remove('is-visible');
+ }
+ });
+
+ this.nextBtn.addEventListener('click', () => {
+ let title = this.channelNameInput.value;
+ let about = this.channelDescriptionInput.value;
+
+ this.nextBtn.disabled = true;
+ appChatsManager.createChannel(title, about).then((channelID) => {
+ if(this.uploadAvatar) {
+ this.uploadAvatar().then((inputFile: any) => {
+ appChatsManager.editPhoto(channelID, inputFile);
+ });
+ }
+
+ appSidebarLeft.removeTabFromHistory(SLIDERITEMSIDS.newChannel);
+ appSidebarLeft.addMembersTab.init(channelID, 'channel', true);
+ });
+ });
+ }
+
+ public onCloseAfterTimeout() {
+ let ctx = this.canvas.getContext('2d');
+ ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
+
+ this.uploadAvatar = null;
+ this.channelNameInput.value = '';
+ this.channelDescriptionInput.value = '';
+ this.nextBtn.disabled = false;
+ }
+}
+
+class AppNewGroupTab implements SliderTab {
+ private container = document.querySelector('.new-group-container') as HTMLDivElement;
+ private contentDiv = this.container.querySelector('.sidebar-content') as HTMLDivElement;
+ private canvas = this.container.querySelector('.avatar-edit-canvas') as HTMLCanvasElement;
+ private groupNameInput = this.container.querySelector('.new-group-name') as HTMLInputElement;
+ private nextBtn = this.container.querySelector('.btn-corner') as HTMLButtonElement;
+ private searchGroup = new SearchGroup('', 'contacts', true, 'new-group-members disable-hover', false);
+ private uploadAvatar: () => Promise = null;
+ private userIDs: number[];
+
+ constructor() {
+ this.container.querySelector('.avatar-edit').addEventListener('click', () => {
+ popupAvatar.open(this.canvas, (_upload) => {
+ this.uploadAvatar = _upload;
+ });
+ });
+
+ this.groupNameInput.addEventListener('input', () => {
+ let value = this.groupNameInput.value;
+ if(value.length) {
+ this.nextBtn.classList.add('is-visible');
+ } else {
+ this.nextBtn.classList.remove('is-visible');
+ }
+ });
+
+ this.nextBtn.addEventListener('click', () => {
+ let title = this.groupNameInput.value;
+
+ this.nextBtn.disabled = true;
+ appChatsManager.createChat(title, this.userIDs).then((chatID) => {
+ if(this.uploadAvatar) {
+ this.uploadAvatar().then((inputFile: any) => {
+ appChatsManager.editPhoto(chatID, inputFile);
+ });
+ }
+
+ appSidebarLeft.selectTab(0);
+ });
+ });
+
+ let chatsContainer = document.createElement('div');
+ chatsContainer.classList.add('chats-container');
+ chatsContainer.append(this.searchGroup.container);
+
+ let scrollable = new Scrollable(chatsContainer);
+
+ this.contentDiv.append(chatsContainer);
+ }
+
+ public onClose() {
+
+ }
+
+ public onCloseAfterTimeout() {
+ this.searchGroup.clear();
+
+ let ctx = this.canvas.getContext('2d');
+ ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
+
+ this.uploadAvatar = null;
+ this.groupNameInput.value = '';
+ this.nextBtn.disabled = false;
+ }
+
+ public init(userIDs: number[]) {
+ this.userIDs = userIDs;
+
+ appSidebarLeft.selectTab(SLIDERITEMSIDS.newGroup);
+ this.userIDs.forEach(userID => {
+ let {dom} = appDialogsManager.addDialog(userID, this.searchGroup.list, false, false);
+
+ let subtitle = '';
+ subtitle = appUsersManager.getUserStatusString(userID);
+ if(subtitle == 'online') {
+ subtitle = `${subtitle}`;
+ }
+
+ if(subtitle) {
+ dom.lastMessageSpan.innerHTML = subtitle;
+ }
+ });
+
+ this.searchGroup.nameEl.innerText = this.userIDs.length + ' members';
+ this.searchGroup.setActive();
+ }
+}
+
+class AppContactsTab implements SliderTab {
+ private container = document.getElementById('contacts-container');
+ private list = this.container.querySelector('#contacts') as HTMLUListElement;
+ private scrollable: Scrollable;
+ private promise: Promise;
+ private input = this.container.querySelector('#contacts-search') as HTMLInputElement;
+
+ constructor() {
+ appDialogsManager.setListClickListener(this.list);
+ this.scrollable = new Scrollable(this.list.parentElement);
+
+ let prevValue = '';
+ this.input.addEventListener('input', () => {
+ let value = this.input.value;
+ if(prevValue != value) {
+ this.list.innerHTML = '';
+ this.openContacts(prevValue = value);
+ }
+ });
+
+ // preload contacts
+ appUsersManager.getContacts();
+ }
+
+ // need to clear, and left 1 page for smooth slide
+ public onClose() {
+ let pageCount = appPhotosManager.windowH / 72 * 1.25 | 0;
+ (Array.from(this.list.children) as HTMLElement[]).slice(pageCount).forEach(el => el.remove());
+ }
+
+ public onCloseAfterTimeout() {
+ this.list.innerHTML = '';
+ }
+
+ public openContacts(query?: string) {
+ appSidebarLeft.selectTab(SLIDERITEMSIDS.contacts);
+ if(this.promise) return this.promise;
+ this.scrollable.onScrolledBottom = null;
+
+ this.promise = appUsersManager.getContacts(query).then(contacts => {
+ this.promise = null;
+
+ if(appSidebarLeft.historyTabIDs[appSidebarLeft.historyTabIDs.length - 1] != SLIDERITEMSIDS.contacts) {
+ console.warn('user closed contacts before it\'s loaded');
+ return;
+ }
+
+ let sorted = contacts
+ .map(userID => {
+ let user = appUsersManager.getUser(userID);
+ let status = appUsersManager.getUserStatusForSort(user.status);
+
+ return {user, status};
+ })
+ .sort((a, b) => b.status - a.status);
+
+ let renderPage = () => {
+ let pageCount = appPhotosManager.windowH / 72 * 1.25 | 0;
+ let arr = sorted.splice(0, pageCount); // надо splice!
+
+ arr.forEach(({user}) => {
+ let {dialog, dom} = appDialogsManager.addDialog(user.id, this.list, false);
+
+ let status = appUsersManager.getUserStatusString(user.id);
+ dom.lastMessageSpan.innerHTML = status == 'online' ? `${status}` : status;
+ });
+
+ if(!sorted.length) renderPage = undefined;
+ };
+
+ renderPage();
+ this.scrollable.onScrolledBottom = () => {
+ if(renderPage) {
+ renderPage();
+ } else {
+ this.scrollable.onScrolledBottom = null;
+ }
+ };
+ });
+ }
+}
+
class AppSidebarLeft {
private sidebarEl = document.getElementById('column-left') as HTMLDivElement;
private toolsBtn = this.sidebarEl.querySelector('.sidebar-tools-button') as HTMLButtonElement;
@@ -24,12 +325,32 @@ class AppSidebarLeft {
private searchInput = document.getElementById('global-search') as HTMLInputElement;
private menuEl = this.toolsBtn.querySelector('.btn-menu');
- private savedBtn = this.menuEl.querySelector('.menu-saved');
- private archivedBtn = this.menuEl.querySelector('.menu-archive');
+ private newGroupBtn = this.menuEl.querySelector('.menu-new-group');
private contactsBtn = this.menuEl.querySelector('.menu-contacts');
+ private archivedBtn = this.menuEl.querySelector('.menu-archive');
+ private savedBtn = this.menuEl.querySelector('.menu-saved');
private logOutBtn = this.menuEl.querySelector('.menu-logout');
public archivedCount = this.archivedBtn.querySelector('.archived-count') as HTMLSpanElement;
+ private newBtnMenu = this.sidebarEl.querySelector('#new-menu');
+ private newButtons = {
+ channel: this.newBtnMenu.querySelector('.menu-channel'),
+ group: this.newBtnMenu.querySelector('.menu-group'),
+ privateChat: this.newBtnMenu.querySelector('.menu-private-chat'),
+ };
+
+ public newChannelTab = new AppNewChannelTab();
+ public addMembersTab = new AppAddMembersTab();
+ public contactsTab = new AppContactsTab();
+ public newGroupTab = new AppNewGroupTab();
+
+ private tabs: {[id: number]: SliderTab} = {
+ [SLIDERITEMSIDS.newChannel]: this.newChannelTab,
+ [SLIDERITEMSIDS.contacts]: this.contactsTab,
+ [SLIDERITEMSIDS.addMembers]: this.addMembersTab,
+ [SLIDERITEMSIDS.newGroup]: this.newGroupTab,
+ };
+
//private log = logger('SL');
private searchGroups = {
@@ -42,12 +363,7 @@ class AppSidebarLeft {
private globalSearch = new AppSearch(this.searchContainer, this.searchInput, this.searchGroups);
private _selectTab: (id: number) => void;
- private historyTabIDs: number[] = [];
-
- private contactsList: HTMLUListElement;
- private contactsScrollable: Scrollable;
- private contactsPromise: Promise;
- private contactsInput: HTMLInputElement;
+ public historyTabIDs: number[] = [];
constructor() {
let peopleContainer = document.createElement('div');
@@ -69,8 +385,7 @@ class AppSidebarLeft {
});
this.contactsBtn.addEventListener('click', (e) => {
- this.openContacts();
- this.selectTab(SLIDERITEMSIDS.contacts);
+ this.contactsTab.openContacts();
});
this.logOutBtn.addEventListener('click', (e) => {
@@ -83,12 +398,6 @@ class AppSidebarLeft {
this.searchContainer.classList.remove('hide');
void this.searchContainer.offsetWidth; // reflow
this.searchContainer.classList.add('active');
-
- /* if(!this.globalSearch.searchInput.value) {
- for(let i in this.globalSearch.searchGroups) {
- this.globalSearch.searchGroups[i].clear();
- }
- } */
false && this.searchInput.addEventListener('blur', (e) => {
if(!this.searchInput.value) {
@@ -96,10 +405,6 @@ class AppSidebarLeft {
this.backBtn.classList.remove('active');
this.backBtn.click();
}
-
- /* this.peerID = 0;
- this.loadedCount = 0;
- this.minMsgID = 0; */
}, {once: true});
});
@@ -118,6 +423,18 @@ class AppSidebarLeft {
}, 150);
});
+ this.newButtons.channel.addEventListener('click', (e) => {
+ this.selectTab(SLIDERITEMSIDS.newChannel);
+ });
+
+ [this.newButtons.group, this.newGroupBtn].forEach(btn => {
+ btn.addEventListener('click', (e) => {
+ this.addMembersTab.init(0, 'chat', false, (peerIDs) => {
+ this.newGroupTab.init(peerIDs);
+ });
+ });
+ });
+
$rootScope.$on('dialogs_archived_unread', (e: CustomEvent) => {
this.archivedCount.innerText = '' + e.detail.count;
});
@@ -125,22 +442,14 @@ class AppSidebarLeft {
this._selectTab = horizontalMenu(null, this.sidebarEl.querySelector('.sidebar-slider') as HTMLDivElement, null, null, 420);
this._selectTab(0);
+ let onCloseBtnClick = () => {
+ console.log('sidebar-close-button click:', this.historyTabIDs);
+ let closingID = this.historyTabIDs.pop(); // pop current
+ this.onCloseTab(closingID);
+ this._selectTab(this.historyTabIDs.pop() || 0);
+ };
Array.from(this.sidebarEl.querySelectorAll('.sidebar-close-button') as any as HTMLElement[]).forEach(el => {
- el.addEventListener('click', () => {
- console.log('sidebar-close-button click:', this.historyTabIDs);
- let closingID = this.historyTabIDs.pop(); // pop current
-
- // need to clear, and left 1 page for smooth slide
- if(closingID == SLIDERITEMSIDS.contacts) {
- let pageCount = appPhotosManager.windowH / 72 * 1.25 | 0;
- (Array.from(this.contactsList.children) as HTMLElement[]).slice(pageCount).forEach(el => el.remove());
- setTimeout(() => {
- this.contactsList.innerHTML = '';
- }, 420);
- }
-
- this._selectTab(this.historyTabIDs.pop() || 0);
- });
+ el.addEventListener('click', onCloseBtnClick);
});
appUsersManager.getTopPeers().then(categories => {
@@ -162,80 +471,34 @@ class AppSidebarLeft {
this.searchGroups.people.setActive();
});
});
-
- let contactsContainer = this.sidebarEl.querySelector('#contacts-container');
- this.contactsInput = contactsContainer.querySelector('#contacts-search');
- this.contactsList = contactsContainer.querySelector('#contacts') as HTMLUListElement;
- appDialogsManager.setListClickListener(this.contactsList);
- this.contactsScrollable = new Scrollable(this.contactsList.parentElement);
-
- let prevValue = '';
- this.contactsInput.addEventListener('input', () => {
- let value = this.contactsInput.value;
- if(prevValue != value) {
- this.contactsList.innerHTML = '';
- this.openContacts(prevValue = value);
- }
- });
-
- // preload contacts
- appUsersManager.getContacts();
}
- public openContacts(query?: string) {
- if(this.contactsPromise) return this.contactsPromise;
- this.contactsScrollable.onScrolledBottom = null;
+ public selectTab(id: number) {
+ this.historyTabIDs.push(id);
+ this._selectTab(id);
+ }
- this.contactsPromise = appUsersManager.getContacts(query).then(contacts => {
- this.contactsPromise = null;
+ public removeTabFromHistory(id: number) {
+ this.historyTabIDs.findAndSplice(i => i == id);
+ this.onCloseTab(id);
+ }
- if(this.historyTabIDs[this.historyTabIDs.length - 1] != SLIDERITEMSIDS.contacts) {
- console.warn('user closed contacts before it\'s loaded');
- return;
+ public onCloseTab(id: number) {
+ let tab = this.tabs[id];
+ if(tab) {
+ if('onClose' in tab) {
+ tab.onClose();
}
- let sorted = contacts
- .map(userID => {
- let user = appUsersManager.getUser(userID);
- let status = appUsersManager.getUserStatusForSort(user.status);
-
- return {user, status};
- })
- .sort((a, b) => b.status - a.status);
-
- let renderPage = () => {
- let pageCount = appPhotosManager.windowH / 72 * 1.25 | 0;
- let arr = sorted.splice(0, pageCount);
-
- arr.forEach(({user}) => {
- let {dialog, dom} = appDialogsManager.addDialog(user.id, this.contactsList, false);
-
- let status = appUsersManager.getUserStatusString(user.id);
- dom.lastMessageSpan.innerHTML = status == 'online' ? `${status}` : status;
- });
-
- if(!sorted.length) renderPage = undefined;
- };
-
- renderPage();
- this.contactsScrollable.onScrolledBottom = () => {
- if(renderPage) {
- renderPage();
- } else {
- this.contactsScrollable.onScrolledBottom = null;
- }
- };
- });
- }
-
- public selectTab(id: number) {
- this.historyTabIDs.push(id);
- this._selectTab(id);
+ if('onCloseAfterTimeout' in tab) {
+ setTimeout(() => {
+ tab.onCloseAfterTimeout();
+ }, 420);
+ }
+ }
}
}
const appSidebarLeft = new AppSidebarLeft();
-
(window as any).appSidebarLeft = appSidebarLeft;
-
export default appSidebarLeft;
diff --git a/src/lib/appManagers/appUsersManager.ts b/src/lib/appManagers/appUsersManager.ts
index 62194a5f..d62ff268 100644
--- a/src/lib/appManagers/appUsersManager.ts
+++ b/src/lib/appManagers/appUsersManager.ts
@@ -158,12 +158,19 @@ export class AppUsersManager {
contactsList.sort((userID1: number, userID2: number) => {
const sortName1 = (this.users[userID1] || {}).sortName || '';
const sortName2 = (this.users[userID2] || {}).sortName || '';
+
+ return sortName1.localeCompare(sortName2);
+ });
+
+ /* contactsList.sort((userID1: number, userID2: number) => {
+ const sortName1 = (this.users[userID1] || {}).sortName || '';
+ const sortName2 = (this.users[userID2] || {}).sortName || '';
if(sortName1 == sortName2) {
return 0;
- }
-
+ }
+
return sortName1 > sortName2 ? 1 : -1;
- });
+ }); */
return contactsList;
});
@@ -215,7 +222,8 @@ export class AppUsersManager {
this.usernames[searchUsername] = userID;
}
- apiUser.sortName = apiUser.pFlags.deleted ? '' : SearchIndexManager.cleanSearchText(apiUser.first_name + ' ' + (apiUser.last_name || ''));
+ //apiUser.sortName = apiUser.pFlags.deleted ? '' : SearchIndexManager.cleanSearchText(apiUser.first_name + ' ' + (apiUser.last_name || ''));
+ apiUser.sortName = apiUser.pFlags.deleted ? '' : apiUser.first_name + ' ' + (apiUser.last_name || '');
var nameWords = apiUser.sortName.split(' ');
var firstWord = nameWords.shift();
diff --git a/src/lib/bin_utils.ts b/src/lib/bin_utils.ts
index bc4c4a61..872505fa 100644
--- a/src/lib/bin_utils.ts
+++ b/src/lib/bin_utils.ts
@@ -345,17 +345,17 @@ export function longFromInts(high: number, low: number) {
export function intToUint(val: number | string) {
if(typeof(val) === 'string') val = parseInt(val);
- if(val < 0) {
+ /* if(val < 0) {
val = val + 4294967296;
- }
+ } */
return val;
}
export function uintToInt(val: number) {
- if(val > 2147483647) {
+ /* if(val > 2147483647) {
val = val - 4294967296;
- }
+ } */
return val;
}
diff --git a/src/lib/lottieLoader.ts b/src/lib/lottieLoader.ts
index c73cb8e9..3026aaee 100644
--- a/src/lib/lottieLoader.ts
+++ b/src/lib/lottieLoader.ts
@@ -157,7 +157,5 @@ class LottieLoader {
}
const lottieLoader = new LottieLoader();
-
-//(window as any).LottieLoader = lottieLoader;
-
+(window as any).LottieLoader = lottieLoader;
export default lottieLoader;
diff --git a/src/lib/mtproto/networker.ts b/src/lib/mtproto/networker.ts
index 81a251b2..e9e5310a 100644
--- a/src/lib/mtproto/networker.ts
+++ b/src/lib/mtproto/networker.ts
@@ -227,14 +227,14 @@ class MTPNetworker {
if(!this.connectionInited) { // this will call once for each new session
///////this.log('Wrap api call !this.connectionInited');
- let invokeWithLayer = Schema.API.methods.find((m: any) => m.method == 'invokeWithLayer');
+ let invokeWithLayer = Schema.API.methods.find(m => m.method == 'invokeWithLayer');
if(!invokeWithLayer) throw new Error('no invokeWithLayer!');
serializer.storeInt(+invokeWithLayer.id >>> 0, 'invokeWithLayer');
// @ts-ignore
serializer.storeInt(Schema.layer, 'layer');
- let initConnection = Schema.API.methods.find((m: any) => m.method == 'initConnection');
+ let initConnection = Schema.API.methods.find(m => m.method == 'initConnection');
if(!initConnection) throw new Error('no initConnection!');
serializer.storeInt(+initConnection.id >>> 0, 'initConnection');
@@ -260,7 +260,7 @@ class MTPNetworker {
}
if(options.afterMessageID) {
- let invokeAfterMsg = Schema.API.methods.find((m: any) => m.method == 'invokeAfterMsg');
+ let invokeAfterMsg = Schema.API.methods.find(m => m.method == 'invokeAfterMsg');
if(!invokeAfterMsg) throw new Error('no invokeAfterMsg!');
this.log('Api call options.afterMessageID!');
diff --git a/src/lib/mtproto/schema.ts b/src/lib/mtproto/schema.ts
index 53704def..70fd1994 100644
--- a/src/lib/mtproto/schema.ts
+++ b/src/lib/mtproto/schema.ts
@@ -1,5 +1,33 @@
-export default {
- "MTProto": {"constructors":[{"id":"481674261","predicate":"vector","params":[],"type":"Vector t"},{"id":"85337187","predicate":"resPQ","params":[{"name":"nonce","type":"int128"},{"name":"server_nonce","type":"int128"},{"name":"pq","type":"bytes"},{"name":"server_public_key_fingerprints","type":"Vector"}],"type":"ResPQ"},{"id":"-2083955988","predicate":"p_q_inner_data","params":[{"name":"pq","type":"bytes"},{"name":"p","type":"bytes"},{"name":"q","type":"bytes"},{"name":"nonce","type":"int128"},{"name":"server_nonce","type":"int128"},{"name":"new_nonce","type":"int256"}],"type":"P_Q_inner_data"},{"id":"-1443537003","predicate":"p_q_inner_data_dc","params":[{"name":"pq","type":"bytes"},{"name":"p","type":"bytes"},{"name":"q","type":"bytes"},{"name":"nonce","type":"int128"},{"name":"server_nonce","type":"int128"},{"name":"new_nonce","type":"int256"},{"name":"dc","type":"int"}],"type":"P_Q_inner_data"},{"id":"1013613780","predicate":"p_q_inner_data_temp","params":[{"name":"pq","type":"bytes"},{"name":"p","type":"bytes"},{"name":"q","type":"bytes"},{"name":"nonce","type":"int128"},{"name":"server_nonce","type":"int128"},{"name":"new_nonce","type":"int256"},{"name":"expires_in","type":"int"}],"type":"P_Q_inner_data"},{"id":"1459478408","predicate":"p_q_inner_data_temp_dc","params":[{"name":"pq","type":"bytes"},{"name":"p","type":"bytes"},{"name":"q","type":"bytes"},{"name":"nonce","type":"int128"},{"name":"server_nonce","type":"int128"},{"name":"new_nonce","type":"int256"},{"name":"dc","type":"int"},{"name":"expires_in","type":"int"}],"type":"P_Q_inner_d"},{"id":"2043348061","predicate":"server_DH_params_fail","params":[{"name":"nonce","type":"int128"},{"name":"server_nonce","type":"int128"},{"name":"new_nonce_hash","type":"int128"}],"type":"Server_DH_Params"},{"id":"-790100132","predicate":"server_DH_params_ok","params":[{"name":"nonce","type":"int128"},{"name":"server_nonce","type":"int128"},{"name":"encrypted_answer","type":"bytes"}],"type":"Server_DH_Params"},{"id":"-1249309254","predicate":"server_DH_inner_data","params":[{"name":"nonce","type":"int128"},{"name":"server_nonce","type":"int128"},{"name":"g","type":"int"},{"name":"dh_prime","type":"bytes"},{"name":"g_a","type":"bytes"},{"name":"server_time","type":"int"}],"type":"Server_DH_inner_data"},{"id":"1715713620","predicate":"client_DH_inner_data","params":[{"name":"nonce","type":"int128"},{"name":"server_nonce","type":"int128"},{"name":"retry_id","type":"long"},{"name":"g_b","type":"bytes"}],"type":"Client_DH_Inner_Data"},{"id":"1003222836","predicate":"dh_gen_ok","params":[{"name":"nonce","type":"int128"},{"name":"server_nonce","type":"int128"},{"name":"new_nonce_hash1","type":"int128"}],"type":"Set_client_DH_params_answer"},{"id":"1188831161","predicate":"dh_gen_retry","params":[{"name":"nonce","type":"int128"},{"name":"server_nonce","type":"int128"},{"name":"new_nonce_hash2","type":"int128"}],"type":"Set_client_DH_params_answer"},{"id":"-1499615742","predicate":"dh_gen_fail","params":[{"name":"nonce","type":"int128"},{"name":"server_nonce","type":"int128"},{"name":"new_nonce_hash3","type":"int128"}],"type":"Set_client_DH_params_answer"},{"id":"-212046591","predicate":"rpc_result","params":[{"name":"req_msg_id","type":"long"},{"name":"result","type":"Object"}],"type":"RpcResult"},{"id":"558156313","predicate":"rpc_error","params":[{"name":"error_code","type":"int"},{"name":"error_message","type":"string"}],"type":"RpcError"},{"id":"1579864942","predicate":"rpc_answer_unknown","params":[],"type":"RpcDropAnswer"},{"id":"-847714938","predicate":"rpc_answer_dropped_running","params":[],"type":"RpcDropAnswer"},{"id":"-1539647305","predicate":"rpc_answer_dropped","params":[{"name":"msg_id","type":"long"},{"name":"seq_no","type":"int"},{"name":"bytes","type":"int"}],"type":"RpcDropAnswer"},{"id":"155834844","predicate":"future_salt","params":[{"name":"valid_since","type":"int"},{"name":"valid_until","type":"int"},{"name":"salt","type":"long"}],"type":"FutureSalt"},{"id":"-1370486635","predicate":"future_salts","params":[{"name":"req_msg_id","type":"long"},{"name":"now","type":"int"},{"name":"salts","type":"vector"}],"type":"FutureSalts"},{"id":"880243653","predicate":"pong","params":[{"name":"msg_id","type":"long"},{"name":"ping_id","type":"long"}],"type":"Pong"},{"id":"-1631450872","predicate":"new_session_created","params":[{"name":"first_msg_id","type":"long"},{"name":"unique_id","type":"long"},{"name":"server_salt","type":"long"}],"type":"NewSession"},{"id":"1945237724","predicate":"msg_container","params":[{"name":"messages","type":"vector<%Message>"}],"type":"MessageContainer"},{"id":"1538843921","predicate":"message","params":[{"name":"msg_id","type":"long"},{"name":"seqno","type":"int"},{"name":"bytes","type":"int"},{"name":"body","type":"Object"}],"type":"Message"},{"id":"-530561358","predicate":"msg_copy","params":[{"name":"orig_message","type":"Message"}],"type":"MessageCopy"},{"id":"812830625","predicate":"gzip_packed","params":[{"name":"packed_data","type":"bytes"}],"type":"Object"},{"id":"1658238041","predicate":"msgs_ack","params":[{"name":"msg_ids","type":"Vector"}],"type":"MsgsAck"},{"id":"-1477445615","predicate":"bad_msg_notification","params":[{"name":"bad_msg_id","type":"long"},{"name":"bad_msg_seqno","type":"int"},{"name":"error_code","type":"int"}],"type":"BadMsgNotification"},{"id":"-307542917","predicate":"bad_server_salt","params":[{"name":"bad_msg_id","type":"long"},{"name":"bad_msg_seqno","type":"int"},{"name":"error_code","type":"int"},{"name":"new_server_salt","type":"long"}],"type":"BadMsgNotification"},{"id":"2105940488","predicate":"msg_resend_req","params":[{"name":"msg_ids","type":"Vector"}],"type":"MsgResendReq"},{"id":"-2045723925","predicate":"msg_resend_ans_req","params":[{"name":"msg_ids","type":"Vector"}],"type":"MsgResendReq"},{"id":"-630588590","predicate":"msgs_state_req","params":[{"name":"msg_ids","type":"Vector"}],"type":"MsgsStateReq"},{"id":"81704317","predicate":"msgs_state_info","params":[{"name":"req_msg_id","type":"long"},{"name":"info","type":"bytes"}],"type":"MsgsStateInfo"},{"id":"-1933520591","predicate":"msgs_all_info","params":[{"name":"msg_ids","type":"Vector"},{"name":"info","type":"bytes"}],"type":"MsgsAllInfo"},{"id":"661470918","predicate":"msg_detailed_info","params":[{"name":"msg_id","type":"long"},{"name":"answer_msg_id","type":"long"},{"name":"bytes","type":"int"},{"name":"status","type":"int"}],"type":"MsgDetailedInfo"},{"id":"-2137147681","predicate":"msg_new_detailed_info","params":[{"name":"answer_msg_id","type":"long"},{"name":"bytes","type":"int"},{"name":"status","type":"int"}],"type":"MsgDetailedInfo"},{"id":"1973679973","predicate":"bind_auth_key_inner","params":[{"name":"nonce","type":"long"},{"name":"temp_auth_key_id","type":"long"},{"name":"perm_auth_key_id","type":"long"},{"name":"temp_session_id","type":"long"},{"name":"expires_at","type":"int"}],"type":"BindAuthKeyInner"},{"id":"-161422892","predicate":"destroy_auth_key_ok","params":[],"type":"DestroyAuthKeyRes"},{"id":"178201177","predicate":"destroy_auth_key_none","params":[],"type":"DestroyAuthKeyRes"},{"id":"-368010477","predicate":"destroy_auth_key_fail","params":[],"type":"DestroyAuthKeyRes"},{"id":"-501201412","predicate":"destroy_session_ok","params":[{"name":"session_id","type":"long"}],"type":"DestroySessionRes"},{"id":"1658015945","predicate":"destroy_session_none","params":[{"name":"session_id","type":"long"}],"type":"DestroySessionRes"}],"methods":[{"id":"1615239032","method":"req_pq","params":[{"name":"nonce","type":"int128"}],"type":"ResPQ"},{"id":"-1099002127","method":"req_pq_multi","params":[{"name":"nonce","type":"int128"}],"type":"ResPQ"},{"id":"-686627650","method":"req_DH_params","params":[{"name":"nonce","type":"int128"},{"name":"server_nonce","type":"int128"},{"name":"p","type":"bytes"},{"name":"q","type":"bytes"},{"name":"public_key_fingerprint","type":"long"},{"name":"encrypted_data","type":"bytes"}],"type":"Server_DH_Params"},{"id":"-184262881","method":"set_client_DH_params","params":[{"name":"nonce","type":"int128"},{"name":"server_nonce","type":"int128"},{"name":"encrypted_data","type":"bytes"}],"type":"Set_client_DH_params_answer"},{"id":"1491380032","method":"rpc_drop_answer","params":[{"name":"req_msg_id","type":"long"}],"type":"RpcDropAnswer"},{"id":"-1188971260","method":"get_future_salts","params":[{"name":"num","type":"int"}],"type":"FutureSalts"},{"id":"2059302892","method":"ping","params":[{"name":"ping_id","type":"long"}],"type":"Pong"},{"id":"-213746804","method":"ping_delay_disconnect","params":[{"name":"ping_id","type":"long"},{"name":"disconnect_delay","type":"int"}],"type":"Pong"},{"id":"-1835453025","method":"http_wait","params":[{"name":"max_delay","type":"int"},{"name":"wait_after","type":"int"},{"name":"max_wait","type":"int"}],"type":"HttpWait"},{"id":"-784117408","method":"destroy_auth_key","params":[],"type":"DestroyAuthKeyRes"},{"id":"-414113498","method":"destroy_session","params":[{"name":"session_id","type":"long"}],"type":"DestroySessionRes"}]},
- "API": {"constructors":[{"id":"-1132882121","predicate":"boolFalse","params":[],"type":"Bool"},{"id":"-1720552011","predicate":"boolTrue","params":[],"type":"Bool"},{"id":"1072550713","predicate":"true","params":[],"type":"True"},{"id":"481674261","predicate":"vector","params":[],"type":"Vector t"},{"id":"-994444869","predicate":"error","params":[{"name":"code","type":"int"},{"name":"text","type":"string"}],"type":"Error"},{"id":"1450380236","predicate":"null","params":[],"type":"Null"},{"id":"2134579434","predicate":"inputPeerEmpty","params":[],"type":"InputPeer"},{"id":"2107670217","predicate":"inputPeerSelf","params":[],"type":"InputPeer"},{"id":"396093539","predicate":"inputPeerChat","params":[{"name":"chat_id","type":"int"}],"type":"InputPeer"},{"id":"-1182234929","predicate":"inputUserEmpty","params":[],"type":"InputUser"},{"id":"-138301121","predicate":"inputUserSelf","params":[],"type":"InputUser"},{"id":"-208488460","predicate":"inputPhoneContact","params":[{"name":"client_id","type":"long"},{"name":"phone","type":"string"},{"name":"first_name","type":"string"},{"name":"last_name","type":"string"}],"type":"InputContact"},{"id":"-181407105","predicate":"inputFile","params":[{"name":"id","type":"long"},{"name":"parts","type":"int"},{"name":"name","type":"string"},{"name":"md5_checksum","type":"string"}],"type":"InputFile"},{"id":"-1771768449","predicate":"inputMediaEmpty","params":[],"type":"InputMedia"},{"id":"505969924","predicate":"inputMediaUploadedPhoto","params":[{"name":"flags","type":"#"},{"name":"file","type":"InputFile"},{"name":"stickers","type":"flags.0?Vector"},{"name":"ttl_seconds","type":"flags.1?int"}],"type":"InputMedia"},{"id":"-1279654347","predicate":"inputMediaPhoto","params":[{"name":"flags","type":"#"},{"name":"id","type":"InputPhoto"},{"name":"ttl_seconds","type":"flags.0?int"}],"type":"InputMedia"},{"id":"-104578748","predicate":"inputMediaGeoPoint","params":[{"name":"geo_point","type":"InputGeoPoint"}],"type":"InputMedia"},{"id":"-122978821","predicate":"inputMediaContact","params":[{"name":"phone_number","type":"string"},{"name":"first_name","type":"string"},{"name":"last_name","type":"string"},{"name":"vcard","type":"string"}],"type":"InputMedia"},{"id":"480546647","predicate":"inputChatPhotoEmpty","params":[],"type":"InputChatPhoto"},{"id":"-1837345356","predicate":"inputChatUploadedPhoto","params":[{"name":"file","type":"InputFile"}],"type":"InputChatPhoto"},{"id":"-1991004873","predicate":"inputChatPhoto","params":[{"name":"id","type":"InputPhoto"}],"type":"InputChatPhoto"},{"id":"-457104426","predicate":"inputGeoPointEmpty","params":[],"type":"InputGeoPoint"},{"id":"-206066487","predicate":"inputGeoPoint","params":[{"name":"lat","type":"double"},{"name":"long","type":"double"}],"type":"InputGeoPoint"},{"id":"483901197","predicate":"inputPhotoEmpty","params":[],"type":"InputPhoto"},{"id":"1001634122","predicate":"inputPhoto","params":[{"name":"id","type":"long"},{"name":"access_hash","type":"long"},{"name":"file_reference","type":"bytes"}],"type":"InputPhoto"},{"id":"-539317279","predicate":"inputFileLocation","params":[{"name":"volume_id","type":"long"},{"name":"local_id","type":"int"},{"name":"secret","type":"long"},{"name":"file_reference","type":"bytes"}],"type":"InputFileLocation"},{"id":"-1649296275","predicate":"peerUser","params":[{"name":"user_id","type":"int"}],"type":"Peer"},{"id":"-1160714821","predicate":"peerChat","params":[{"name":"chat_id","type":"int"}],"type":"Peer"},{"id":"-1432995067","predicate":"storage.fileUnknown","params":[],"type":"storage.FileType"},{"id":"1086091090","predicate":"storage.filePartial","params":[],"type":"storage.FileType"},{"id":"8322574","predicate":"storage.fileJpeg","params":[],"type":"storage.FileType"},{"id":"-891180321","predicate":"storage.fileGif","params":[],"type":"storage.FileType"},{"id":"172975040","predicate":"storage.filePng","params":[],"type":"storage.FileType"},{"id":"-1373745011","predicate":"storage.filePdf","params":[],"type":"storage.FileType"},{"id":"1384777335","predicate":"storage.fileMp3","params":[],"type":"storage.FileType"},{"id":"1258941372","predicate":"storage.fileMov","params":[],"type":"storage.FileType"},{"id":"-1278304028","predicate":"storage.fileMp4","params":[],"type":"storage.FileType"},{"id":"276907596","predicate":"storage.fileWebp","params":[],"type":"storage.FileType"},{"id":"537022650","predicate":"userEmpty","params":[{"name":"id","type":"int"}],"type":"User"},{"id":"1326562017","predicate":"userProfilePhotoEmpty","params":[],"type":"UserProfilePhoto"},{"id":"-321430132","predicate":"userProfilePhoto","params":[{"name":"photo_id","type":"long"},{"name":"photo_small","type":"FileLocation"},{"name":"photo_big","type":"FileLocation"},{"name":"dc_id","type":"int"}],"type":"UserProfilePhoto"},{"id":"164646985","predicate":"userStatusEmpty","params":[],"type":"UserStatus"},{"id":"-306628279","predicate":"userStatusOnline","params":[{"name":"expires","type":"int"}],"type":"UserStatus"},{"id":"9203775","predicate":"userStatusOffline","params":[{"name":"was_online","type":"int"}],"type":"UserStatus"},{"id":"-1683826688","predicate":"chatEmpty","params":[{"name":"id","type":"int"}],"type":"Chat"},{"id":"1004149726","predicate":"chat","params":[{"name":"flags","type":"#"},{"name":"creator","type":"flags.0?true"},{"name":"kicked","type":"flags.1?true"},{"name":"left","type":"flags.2?true"},{"name":"deactivated","type":"flags.5?true"},{"name":"id","type":"int"},{"name":"title","type":"string"},{"name":"photo","type":"ChatPhoto"},{"name":"participants_count","type":"int"},{"name":"date","type":"int"},{"name":"version","type":"int"},{"name":"migrated_to","type":"flags.6?InputChannel"},{"name":"admin_rights","type":"flags.14?ChatAdminRights"},{"name":"default_banned_rights","type":"flags.18?ChatBannedRights"}],"type":"Chat"},{"id":"120753115","predicate":"chatForbidden","params":[{"name":"id","type":"int"},{"name":"title","type":"string"}],"type":"Chat"},{"id":"461151667","predicate":"chatFull","params":[{"name":"flags","type":"#"},{"name":"can_set_username","type":"flags.7?true"},{"name":"has_scheduled","type":"flags.8?true"},{"name":"id","type":"int"},{"name":"about","type":"string"},{"name":"participants","type":"ChatParticipants"},{"name":"chat_photo","type":"flags.2?Photo"},{"name":"notify_settings","type":"PeerNotifySettings"},{"name":"exported_invite","type":"ExportedChatInvite"},{"name":"bot_info","type":"flags.3?Vector"},{"name":"pinned_msg_id","type":"flags.6?int"},{"name":"folder_id","type":"flags.11?int"}],"type":"ChatFull"},{"id":"-925415106","predicate":"chatParticipant","params":[{"name":"user_id","type":"int"},{"name":"inviter_id","type":"int"},{"name":"date","type":"int"}],"type":"ChatParticipant"},{"id":"-57668565","predicate":"chatParticipantsForbidden","params":[{"name":"flags","type":"#"},{"name":"chat_id","type":"int"},{"name":"self_participant","type":"flags.0?ChatParticipant"}],"type":"ChatParticipants"},{"id":"1061556205","predicate":"chatParticipants","params":[{"name":"chat_id","type":"int"},{"name":"participants","type":"Vector"},{"name":"version","type":"int"}],"type":"ChatParticipants"},{"id":"935395612","predicate":"chatPhotoEmpty","params":[],"type":"ChatPhoto"},{"id":"1197267925","predicate":"chatPhoto","params":[{"name":"photo_small","type":"FileLocation"},{"name":"photo_big","type":"FileLocation"},{"name":"dc_id","type":"int"}],"type":"ChatPhoto"},{"id":"-2082087340","predicate":"messageEmpty","params":[{"name":"id","type":"int"}],"type":"Message"},{"id":"1160515173","predicate":"message","params":[{"name":"flags","type":"#"},{"name":"out","type":"flags.1?true"},{"name":"mentioned","type":"flags.4?true"},{"name":"media_unread","type":"flags.5?true"},{"name":"silent","type":"flags.13?true"},{"name":"post","type":"flags.14?true"},{"name":"from_scheduled","type":"flags.18?true"},{"name":"legacy","type":"flags.19?true"},{"name":"edit_hide","type":"flags.21?true"},{"name":"id","type":"int"},{"name":"from_id","type":"flags.8?int"},{"name":"to_id","type":"Peer"},{"name":"fwd_from","type":"flags.2?MessageFwdHeader"},{"name":"via_bot_id","type":"flags.11?int"},{"name":"reply_to_msg_id","type":"flags.3?int"},{"name":"date","type":"int"},{"name":"message","type":"string"},{"name":"media","type":"flags.9?MessageMedia"},{"name":"reply_markup","type":"flags.6?ReplyMarkup"},{"name":"entities","type":"flags.7?Vector"},{"name":"views","type":"flags.10?int"},{"name":"edit_date","type":"flags.15?int"},{"name":"post_author","type":"flags.16?string"},{"name":"grouped_id","type":"flags.17?long"},{"name":"restriction_reason","type":"flags.22?Vector"}],"type":"Message"},{"id":"-1642487306","predicate":"messageService","params":[{"name":"flags","type":"#"},{"name":"out","type":"flags.1?true"},{"name":"mentioned","type":"flags.4?true"},{"name":"media_unread","type":"flags.5?true"},{"name":"silent","type":"flags.13?true"},{"name":"post","type":"flags.14?true"},{"name":"legacy","type":"flags.19?true"},{"name":"id","type":"int"},{"name":"from_id","type":"flags.8?int"},{"name":"to_id","type":"Peer"},{"name":"reply_to_msg_id","type":"flags.3?int"},{"name":"date","type":"int"},{"name":"action","type":"MessageAction"}],"type":"Message"},{"id":"1038967584","predicate":"messageMediaEmpty","params":[],"type":"MessageMedia"},{"id":"1766936791","predicate":"messageMediaPhoto","params":[{"name":"flags","type":"#"},{"name":"photo","type":"flags.0?Photo"},{"name":"ttl_seconds","type":"flags.2?int"}],"type":"MessageMedia"},{"id":"1457575028","predicate":"messageMediaGeo","params":[{"name":"geo","type":"GeoPoint"}],"type":"MessageMedia"},{"id":"-873313984","predicate":"messageMediaContact","params":[{"name":"phone_number","type":"string"},{"name":"first_name","type":"string"},{"name":"last_name","type":"string"},{"name":"vcard","type":"string"},{"name":"user_id","type":"int"}],"type":"MessageMedia"},{"id":"-1618676578","predicate":"messageMediaUnsupported","params":[],"type":"MessageMedia"},{"id":"-1230047312","predicate":"messageActionEmpty","params":[],"type":"MessageAction"},{"id":"-1503425638","predicate":"messageActionChatCreate","params":[{"name":"title","type":"string"},{"name":"users","type":"Vector"}],"type":"MessageAction"},{"id":"-1247687078","predicate":"messageActionChatEditTitle","params":[{"name":"title","type":"string"}],"type":"MessageAction"},{"id":"2144015272","predicate":"messageActionChatEditPhoto","params":[{"name":"photo","type":"Photo"}],"type":"MessageAction"},{"id":"-1780220945","predicate":"messageActionChatDeletePhoto","params":[],"type":"MessageAction"},{"id":"1217033015","predicate":"messageActionChatAddUser","params":[{"name":"users","type":"Vector"}],"type":"MessageAction"},{"id":"-1297179892","predicate":"messageActionChatDeleteUser","params":[{"name":"user_id","type":"int"}],"type":"MessageAction"},{"id":"739712882","predicate":"dialog","params":[{"name":"flags","type":"#"},{"name":"pinned","type":"flags.2?true"},{"name":"unread_mark","type":"flags.3?true"},{"name":"peer","type":"Peer"},{"name":"top_message","type":"int"},{"name":"read_inbox_max_id","type":"int"},{"name":"read_outbox_max_id","type":"int"},{"name":"unread_count","type":"int"},{"name":"unread_mentions_count","type":"int"},{"name":"notify_settings","type":"PeerNotifySettings"},{"name":"pts","type":"flags.0?int"},{"name":"draft","type":"flags.1?DraftMessage"},{"name":"folder_id","type":"flags.4?int"}],"type":"Dialog"},{"id":"590459437","predicate":"photoEmpty","params":[{"name":"id","type":"long"}],"type":"Photo"},{"id":"-797637467","predicate":"photo","params":[{"name":"flags","type":"#"},{"name":"has_stickers","type":"flags.0?true"},{"name":"id","type":"long"},{"name":"access_hash","type":"long"},{"name":"file_reference","type":"bytes"},{"name":"date","type":"int"},{"name":"sizes","type":"Vector"},{"name":"dc_id","type":"int"}],"type":"Photo"},{"id":"236446268","predicate":"photoSizeEmpty","params":[{"name":"type","type":"string"}],"type":"PhotoSize"},{"id":"2009052699","predicate":"photoSize","params":[{"name":"type","type":"string"},{"name":"location","type":"FileLocation"},{"name":"w","type":"int"},{"name":"h","type":"int"},{"name":"size","type":"int"}],"type":"PhotoSize"},{"id":"-374917894","predicate":"photoCachedSize","params":[{"name":"type","type":"string"},{"name":"location","type":"FileLocation"},{"name":"w","type":"int"},{"name":"h","type":"int"},{"name":"bytes","type":"bytes"}],"type":"PhotoSize"},{"id":"286776671","predicate":"geoPointEmpty","params":[],"type":"GeoPoint"},{"id":"43446532","predicate":"geoPoint","params":[{"name":"long","type":"double"},{"name":"lat","type":"double"},{"name":"access_hash","type":"long"}],"type":"GeoPoint"},{"id":"1577067778","predicate":"auth.sentCode","params":[{"name":"flags","type":"#"},{"name":"type","type":"auth.SentCodeType"},{"name":"phone_code_hash","type":"string"},{"name":"next_type","type":"flags.1?auth.CodeType"},{"name":"timeout","type":"flags.2?int"}],"type":"auth.SentCode"},{"id":"-855308010","predicate":"auth.authorization","params":[{"name":"flags","type":"#"},{"name":"tmp_sessions","type":"flags.0?int"},{"name":"user","type":"User"}],"type":"auth.Authorization"},{"id":"-543777747","predicate":"auth.exportedAuthorization","params":[{"name":"id","type":"int"},{"name":"bytes","type":"bytes"}],"type":"auth.ExportedAuthorization"},{"id":"-1195615476","predicate":"inputNotifyPeer","params":[{"name":"peer","type":"InputPeer"}],"type":"InputNotifyPeer"},{"id":"423314455","predicate":"inputNotifyUsers","params":[],"type":"InputNotifyPeer"},{"id":"1251338318","predicate":"inputNotifyChats","params":[],"type":"InputNotifyPeer"},{"id":"-1673717362","predicate":"inputPeerNotifySettings","params":[{"name":"flags","type":"#"},{"name":"show_previews","type":"flags.0?Bool"},{"name":"silent","type":"flags.1?Bool"},{"name":"mute_until","type":"flags.2?int"},{"name":"sound","type":"flags.3?string"}],"type":"InputPeerNotifySettings"},{"id":"-1353671392","predicate":"peerNotifySettings","params":[{"name":"flags","type":"#"},{"name":"show_previews","type":"flags.0?Bool"},{"name":"silent","type":"flags.1?Bool"},{"name":"mute_until","type":"flags.2?int"},{"name":"sound","type":"flags.3?string"}],"type":"PeerNotifySettings"},{"id":"-2122045747","predicate":"peerSettings","params":[{"name":"flags","type":"#"},{"name":"report_spam","type":"flags.0?true"},{"name":"add_contact","type":"flags.1?true"},{"name":"block_contact","type":"flags.2?true"},{"name":"share_contact","type":"flags.3?true"},{"name":"need_contacts_exception","type":"flags.4?true"},{"name":"report_geo","type":"flags.5?true"}],"type":"PeerSettings"},{"id":"-1539849235","predicate":"wallPaper","params":[{"name":"id","type":"long"},{"name":"flags","type":"#"},{"name":"creator","type":"flags.0?true"},{"name":"default","type":"flags.1?true"},{"name":"pattern","type":"flags.3?true"},{"name":"dark","type":"flags.4?true"},{"name":"access_hash","type":"long"},{"name":"slug","type":"string"},{"name":"document","type":"Document"},{"name":"settings","type":"flags.2?WallPaperSettings"}],"type":"WallPaper"},{"id":"1490799288","predicate":"inputReportReasonSpam","params":[],"type":"ReportReason"},{"id":"505595789","predicate":"inputReportReasonViolence","params":[],"type":"ReportReason"},{"id":"777640226","predicate":"inputReportReasonPornography","params":[],"type":"ReportReason"},{"id":"-1376497949","predicate":"inputReportReasonChildAbuse","params":[],"type":"ReportReason"},{"id":"-512463606","predicate":"inputReportReasonOther","params":[{"name":"text","type":"string"}],"type":"ReportReason"},{"id":"-302941166","predicate":"userFull","params":[{"name":"flags","type":"#"},{"name":"blocked","type":"flags.0?true"},{"name":"phone_calls_available","type":"flags.4?true"},{"name":"phone_calls_private","type":"flags.5?true"},{"name":"can_pin_message","type":"flags.7?true"},{"name":"has_scheduled","type":"flags.12?true"},{"name":"user","type":"User"},{"name":"about","type":"flags.1?string"},{"name":"settings","type":"PeerSettings"},{"name":"profile_photo","type":"flags.2?Photo"},{"name":"notify_settings","type":"PeerNotifySettings"},{"name":"bot_info","type":"flags.3?BotInfo"},{"name":"pinned_msg_id","type":"flags.6?int"},{"name":"common_chats_count","type":"int"},{"name":"folder_id","type":"flags.11?int"}],"type":"UserFull"},{"id":"-116274796","predicate":"contact","params":[{"name":"user_id","type":"int"},{"name":"mutual","type":"Bool"}],"type":"Contact"},{"id":"-805141448","predicate":"importedContact","params":[{"name":"user_id","type":"int"},{"name":"client_id","type":"long"}],"type":"ImportedContact"},{"id":"1444661369","predicate":"contactBlocked","params":[{"name":"user_id","type":"int"},{"name":"date","type":"int"}],"type":"ContactBlocked"},{"id":"-748155807","predicate":"contactStatus","params":[{"name":"user_id","type":"int"},{"name":"status","type":"UserStatus"}],"type":"ContactStatus"},{"id":"-1219778094","predicate":"contacts.contactsNotModified","params":[],"type":"contacts.Contacts"},{"id":"-353862078","predicate":"contacts.contacts","params":[{"name":"contacts","type":"Vector"},{"name":"saved_count","type":"int"},{"name":"users","type":"Vector"}],"type":"contacts.Contacts"},{"id":"2010127419","predicate":"contacts.importedContacts","params":[{"name":"imported","type":"Vector"},{"name":"popular_invites","type":"Vector"},{"name":"retry_contacts","type":"Vector"},{"name":"users","type":"Vector"}],"type":"contacts.ImportedContacts"},{"id":"471043349","predicate":"contacts.blocked","params":[{"name":"blocked","type":"Vector"},{"name":"users","type":"Vector"}],"type":"contacts.Blocked"},{"id":"-1878523231","predicate":"contacts.blockedSlice","params":[{"name":"count","type":"int"},{"name":"blocked","type":"Vector"},{"name":"users","type":"Vector"}],"type":"contacts.Blocked"},{"id":"364538944","predicate":"messages.dialogs","params":[{"name":"dialogs","type":"Vector