MTProto autocomplete flags

Chat context menu fixes
Revote & stop poll from context menu
This commit is contained in:
morethanwords 2020-10-10 01:36:06 +03:00
parent a53581c3f0
commit bc4c892880
22 changed files with 534 additions and 530 deletions

View File

@ -0,0 +1,30 @@
import { ripple } from "./ripple";
export type ButtonMenuItemOptions = {icon: string, text: string, onClick: () => void, element?: HTMLElement};
const ButtonMenuItem = (options: ButtonMenuItemOptions) => {
if(options.element) return options.element;
const {icon, text, onClick} = options;
const el = document.createElement('div');
el.className = 'btn-menu-item tgico-' + icon;
el.innerText = text;
ripple(el);
el.addEventListener('click', onClick);
return options.element = el;
};
const ButtonMenu = (buttons: ButtonMenuItemOptions[]) => {
const el = document.createElement('div');
el.classList.add('btn-menu');
const items = buttons.map(ButtonMenuItem);
el.append(...items);
return el;
};
export default ButtonMenu;

View File

@ -2,28 +2,26 @@ import appChatsManager from "../../lib/appManagers/appChatsManager";
import appImManager from "../../lib/appManagers/appImManager"; import appImManager from "../../lib/appManagers/appImManager";
import appMessagesManager from "../../lib/appManagers/appMessagesManager"; import appMessagesManager from "../../lib/appManagers/appMessagesManager";
import appPeersManager from "../../lib/appManagers/appPeersManager"; import appPeersManager from "../../lib/appManagers/appPeersManager";
import appPollsManager from "../../lib/appManagers/appPollsManager";
import $rootScope from "../../lib/rootScope"; import $rootScope from "../../lib/rootScope";
import { findUpClassName } from "../../lib/utils"; import { findUpClassName } from "../../lib/utils";
import { attachContextMenuListener, openBtnMenu, parseMenuButtonsTo, positionMenu } from "../misc"; import ButtonMenu, { ButtonMenuItemOptions } from "../buttonMenu";
import { attachContextMenuListener, openBtnMenu, positionMenu } from "../misc";
import { PopupButton, PopupPeer } from "../popup"; import { PopupButton, PopupPeer } from "../popup";
import appSidebarRight from "../sidebarRight"; import appSidebarRight from "../sidebarRight";
export class ChatContextMenu { export class ChatContextMenu {
private element = document.getElementById('bubble-contextmenu') as HTMLDivElement; private buttons: (ButtonMenuItemOptions & {verify: (peerID: number, msgID: number) => boolean})[];
private buttons: { private element: HTMLElement;
reply: HTMLButtonElement,
edit: HTMLButtonElement,
copy: HTMLButtonElement,
pin: HTMLButtonElement,
forward: HTMLButtonElement,
delete: HTMLButtonElement
} = {} as any;
public msgID: number; public msgID: number;
constructor(private attachTo: HTMLElement) { constructor(private attachTo: HTMLElement) {
parseMenuButtonsTo(this.buttons, this.element.children);
attachContextMenuListener(attachTo, (e) => { attachContextMenuListener(attachTo, (e) => {
if(this.init) {
this.init();
this.init = null;
}
let bubble: HTMLElement = null; let bubble: HTMLElement = null;
try { try {
@ -40,126 +38,186 @@ export class ChatContextMenu {
bubble = bubble.parentElement as HTMLDivElement; // bc container bubble = bubble.parentElement as HTMLDivElement; // bc container
let msgID = +bubble.dataset.mid; const msgID = +bubble.dataset.mid;
if(!msgID) return; if(!msgID) return;
let peerID = $rootScope.selectedPeerID; const peerID = $rootScope.selectedPeerID;
this.msgID = msgID; this.msgID = msgID;
const message = appMessagesManager.getMessage(msgID); this.buttons.forEach(button => {
const good = button.verify(peerID, msgID);
button.element.classList.toggle('hide', !good);
});
this.buttons.copy.style.display = message.message ? '' : 'none'; const side: 'left' | 'right' = bubble.classList.contains('is-in') ? 'left' : 'right';
this.buttons.pin.classList.toggle('hide', peerID < 0 && !appChatsManager.hasRights(-peerID, 'pin'));
this.buttons.edit.style.display = appMessagesManager.canEditMessage(msgID) ? '' : 'none';
this.buttons.reply.classList.toggle('hide', peerID < 0 && !appChatsManager.hasRights(-peerID, 'send'));
this.buttons.delete.classList.toggle('hide', peerID < 0 && appPeersManager.isBroadcast(peerID) && !appChatsManager.hasRights(-peerID, 'deleteRevoke'));
let side: 'left' | 'right' = bubble.classList.contains('is-in') ? 'left' : 'right';
positionMenu(e, this.element, side); positionMenu(e, this.element, side);
openBtnMenu(this.element); openBtnMenu(this.element);
/////this.log('contextmenu', e, bubble, msgID, side); /////this.log('contextmenu', e, bubble, msgID, side);
}); });
this.buttons.copy.addEventListener('click', () => {
let message = appMessagesManager.getMessage(this.msgID);
let str = message ? message.message : '';
var textArea = document.createElement("textarea");
textArea.value = str;
textArea.style.position = "fixed"; //avoid scrolling to bottom
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
try {
document.execCommand('copy');
} catch (err) {
console.error('Oops, unable to copy', err);
}
document.body.removeChild(textArea);
});
this.buttons.delete.addEventListener('click', () => {
let peerID = $rootScope.selectedPeerID;
let firstName = appPeersManager.getPeerTitle(peerID, false, true);
let callback = (revoke: boolean) => {
appMessagesManager.deleteMessages([this.msgID], revoke);
};
let title: string, description: string, buttons: PopupButton[];
title = 'Delete Message?';
description = `Are you sure you want to delete this message?`;
if(peerID == $rootScope.myID) {
buttons = [{
text: 'DELETE',
isDanger: true,
callback: () => callback(false)
}];
} else {
buttons = [{
text: 'DELETE JUST FOR ME',
isDanger: true,
callback: () => callback(false)
}];
if(peerID > 0) {
buttons.push({
text: 'DELETE FOR ME AND ' + firstName,
isDanger: true,
callback: () => callback(true)
});
} else if(appChatsManager.hasRights(-peerID, 'deleteRevoke')) {
buttons.push({
text: 'DELETE FOR ALL',
isDanger: true,
callback: () => callback(true)
});
}
}
buttons.push({
text: 'CANCEL',
isCancel: true
});
let popup = new PopupPeer('popup-delete-chat', {
peerID: peerID,
title: title,
description: description,
buttons: buttons
});
popup.show();
});
this.buttons.reply.addEventListener('click', () => {
const message = appMessagesManager.getMessage(this.msgID);
const chatInputC = appImManager.chatInputC;
chatInputC.setTopInfo(appPeersManager.getPeerTitle(message.fromID, true), message.message, undefined, message);
chatInputC.replyToMsgID = this.msgID;
chatInputC.editMsgID = 0;
});
this.buttons.forward.addEventListener('click', () => {
appSidebarRight.forwardTab.open([this.msgID]);
});
this.buttons.edit.addEventListener('click', () => {
const message = appMessagesManager.getMessage(this.msgID);
const chatInputC = appImManager.chatInputC;
chatInputC.setTopInfo('Editing', message.message, message.message, message);
chatInputC.replyToMsgID = 0;
chatInputC.editMsgID = this.msgID;
});
this.buttons.pin.addEventListener('click', () => {
appMessagesManager.updatePinnedMessage($rootScope.selectedPeerID, this.msgID);
});
} }
private init = () => {
this.buttons = [{
icon: 'reply',
text: 'Reply',
onClick: this.onReplyClick,
verify: (peerID: number) => peerID > 0 || appChatsManager.hasRights(-peerID, 'send')
}, {
icon: 'edit',
text: 'Edit',
onClick: this.onEditClick,
verify: (peerID: number, msgID: number) => appMessagesManager.canEditMessage(msgID)
}, {
icon: 'copy',
text: 'Copy',
onClick: this.onCopyClick,
verify: (peerID: number, msgID: number) => !!appMessagesManager.getMessage(msgID).message
}, {
icon: 'pin',
text: 'Pin',
onClick: this.onPinClick,
verify: (peerID: number) => peerID == $rootScope.myID || (peerID < 0 && appChatsManager.hasRights(-peerID, 'pin'))
}, {
icon: 'revote',
text: 'Revote',
onClick: this.onRetractVote,
verify: (peerID: number, msgID) => {
const message = appMessagesManager.getMessage(msgID);
const poll = message.media?.poll;
return poll && !poll.pFlags.closed;
}
}, {
icon: 'lock',
text: 'Stop poll',
onClick: this.onStopPoll,
verify: (peerID: number, msgID) => {
const message = appMessagesManager.getMessage(msgID);
const poll = message.media?.poll;
return appMessagesManager.canEditMessage(msgID) && message.fromID == $rootScope.myID && message.fwd_from === undefined && poll && !poll.pFlags.closed;
}
}, {
icon: 'forward',
text: 'Forward',
onClick: this.onForwardClick,
verify: () => true
}, {
icon: 'delete danger',
text: 'Delete',
onClick: this.onDeleteClick,
verify: (peerID: number, msgID: number) => peerID > 0 || appMessagesManager.getMessage(msgID).fromID == $rootScope.myID || appChatsManager.hasRights(-peerID, 'deleteRevoke')
}];
this.element = ButtonMenu(this.buttons);
this.element.id = 'bubble-contextmenu';
appImManager.chatInput.parentElement.insertBefore(this.element, appImManager.chatInput);
};
private onReplyClick = () => {
const message = appMessagesManager.getMessage(this.msgID);
const chatInputC = appImManager.chatInputC;
chatInputC.setTopInfo(appPeersManager.getPeerTitle(message.fromID, true), message.message, undefined, message);
chatInputC.replyToMsgID = this.msgID;
chatInputC.editMsgID = 0;
};
private onEditClick = () => {
const message = appMessagesManager.getMessage(this.msgID);
const chatInputC = appImManager.chatInputC;
chatInputC.setTopInfo('Editing', message.message, message.message, message);
chatInputC.replyToMsgID = 0;
chatInputC.editMsgID = this.msgID;
};
private onCopyClick = () => {
let message = appMessagesManager.getMessage(this.msgID);
let str = message ? message.message : '';
var textArea = document.createElement("textarea");
textArea.value = str;
textArea.style.position = "fixed"; //avoid scrolling to bottom
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
try {
document.execCommand('copy');
} catch (err) {
console.error('Oops, unable to copy', err);
}
document.body.removeChild(textArea);
};
private onPinClick = () => {
appMessagesManager.updatePinnedMessage($rootScope.selectedPeerID, this.msgID);
};
private onRetractVote = () => {
appPollsManager.sendVote(this.msgID, []);
};
private onStopPoll = () => {
appPollsManager.stopPoll(this.msgID);
};
private onForwardClick = () => {
appSidebarRight.forwardTab.open([this.msgID]);
};
private onDeleteClick = () => {
let peerID = $rootScope.selectedPeerID;
let firstName = appPeersManager.getPeerTitle(peerID, false, true);
let callback = (revoke: boolean) => {
appMessagesManager.deleteMessages([this.msgID], revoke);
};
let title: string, description: string, buttons: PopupButton[];
title = 'Delete Message?';
description = `Are you sure you want to delete this message?`;
if(peerID == $rootScope.myID) {
buttons = [{
text: 'DELETE',
isDanger: true,
callback: () => callback(false)
}];
} else {
buttons = [{
text: 'DELETE JUST FOR ME',
isDanger: true,
callback: () => callback(false)
}];
if(peerID > 0) {
buttons.push({
text: 'DELETE FOR ME AND ' + firstName,
isDanger: true,
callback: () => callback(true)
});
} else if(appChatsManager.hasRights(-peerID, 'deleteRevoke')) {
buttons.push({
text: 'DELETE FOR ALL',
isDanger: true,
callback: () => callback(true)
});
}
}
buttons.push({
text: 'CANCEL',
isCancel: true
});
let popup = new PopupPeer('popup-delete-chat', {
peerID: peerID,
title: title,
description: description,
buttons: buttons
});
popup.show();
};
} }

View File

@ -1,20 +1,20 @@
import Scrollable from "../scrollable";
import { RichTextProcessor } from "../../lib/richtextprocessor";
import apiManager from "../../lib/mtproto/mtprotoworker";
import appWebPagesManager from "../../lib/appManagers/appWebPagesManager";
import appImManager from "../../lib/appManagers/appImManager";
import { getRichValue, calcImageInBox, cancelEvent } from "../../lib/utils";
import { wrapDocument, wrapReply } from "../wrappers";
import appMessagesManager from "../../lib/appManagers/appMessagesManager";
import { Layouter, RectPart } from "../groupedLayout";
import Recorder from '../../../public/recorder.min'; import Recorder from '../../../public/recorder.min';
import { isTouchSupported } from "../../helpers/touchSupport";
import appDocsManager from "../../lib/appManagers/appDocsManager";
import appImManager from "../../lib/appManagers/appImManager";
import appMessagesManager from "../../lib/appManagers/appMessagesManager";
import appWebPagesManager from "../../lib/appManagers/appWebPagesManager";
import apiManager from "../../lib/mtproto/mtprotoworker";
//import Recorder from '../opus-recorder/dist/recorder.min'; //import Recorder from '../opus-recorder/dist/recorder.min';
import opusDecodeController from "../../lib/opusDecodeController"; import opusDecodeController from "../../lib/opusDecodeController";
import appDocsManager from "../../lib/appManagers/appDocsManager"; import { RichTextProcessor } from "../../lib/richtextprocessor";
import { calcImageInBox, cancelEvent, getRichValue } from "../../lib/utils";
import emoticonsDropdown from "../emoticonsDropdown"; import emoticonsDropdown from "../emoticonsDropdown";
import { Layouter, RectPart } from "../groupedLayout";
import PopupCreatePoll from "../popupCreatePoll"; import PopupCreatePoll from "../popupCreatePoll";
import Scrollable from "../scrollable";
import { toast } from "../toast"; import { toast } from "../toast";
import { isTouchSupported } from "../../helpers/touchSupport"; import { wrapDocument, wrapReply } from "../wrappers";
const RECORD_MIN_TIME = 500; const RECORD_MIN_TIME = 500;
@ -57,7 +57,7 @@ export class ChatInput {
public willSendWebPage: any = null; public willSendWebPage: any = null;
public replyToMsgID = 0; public replyToMsgID = 0;
public editMsgID = 0; public editMsgID = 0;
public noWebPage = false; public noWebPage: true;
private recorder: any; private recorder: any;
private recording = false; private recording = false;
@ -159,7 +159,7 @@ export class ChatInput {
this.setTopInfo(webpage.site_name || webpage.title, webpage.description || webpage.url); this.setTopInfo(webpage.site_name || webpage.title, webpage.description || webpage.url);
this.replyToMsgID = 0; this.replyToMsgID = 0;
this.noWebPage = false; delete this.noWebPage;
this.willSendWebPage = webpage; this.willSendWebPage = webpage;
} }
}); });
@ -744,7 +744,7 @@ export class ChatInput {
if(clearInput) { if(clearInput) {
this.lastUrl = ''; this.lastUrl = '';
this.editMsgID = 0; this.editMsgID = 0;
this.noWebPage = false; delete this.noWebPage;
this.willSendWebPage = null; this.willSendWebPage = null;
this.messageInput.innerText = ''; this.messageInput.innerText = '';

View File

@ -171,8 +171,8 @@ window.addEventListener('resize', () => {
} */ } */
}); });
let openedMenu: HTMLDivElement = null, openedMenuOnClose: () => void = null; let openedMenu: HTMLElement = null, openedMenuOnClose: () => void = null;
export function openBtnMenu(menuElement: HTMLDivElement, onClose?: () => void) { export function openBtnMenu(menuElement: HTMLElement, onClose?: () => void) {
closeBtnMenu(); closeBtnMenu();
openedMenu = menuElement; openedMenu = menuElement;

View File

@ -1,8 +1,8 @@
import appMessagesManager from "../lib/appManagers/appMessagesManager";
import appPollsManager, { Poll } from "../lib/appManagers/appPollsManager";
import $rootScope from "../lib/rootScope";
import { PopupElement } from "./popup"; import { PopupElement } from "./popup";
import Scrollable from "./scrollable"; import Scrollable from "./scrollable";
import appMessagesManager from "../lib/appManagers/appMessagesManager";
import $rootScope from "../lib/rootScope";
import { Poll } from "../lib/appManagers/appPollsManager";
import { toast } from "./toast"; import { toast } from "./toast";
const InputField = (placeholder: string, label: string, name: string) => { const InputField = (placeholder: string, label: string, name: string) => {
@ -74,25 +74,21 @@ export default class PopupCreatePoll extends PopupElement {
//const randomID = [nextRandomInt(0xFFFFFFFF), nextRandomInt(0xFFFFFFFF)]; //const randomID = [nextRandomInt(0xFFFFFFFF), nextRandomInt(0xFFFFFFFF)];
//const randomIDS = bigint(randomID[0]).shiftLeft(32).add(bigint(randomID[1])).toString(); //const randomIDS = bigint(randomID[0]).shiftLeft(32).add(bigint(randomID[1])).toString();
const poll: Partial<Poll> = {}; const poll: Poll = {
poll._ = 'poll'; _: 'poll',
question,
answers: answers.map((value, idx) => {
return {
_: 'pollAnswer',
text: value,
option: new Uint8Array([idx])
};
}),
id: undefined
};
//poll.id = randomIDS; //poll.id = randomIDS;
poll.flags = 0;
poll.question = question;
poll.answers = answers.map((value, idx) => { appMessagesManager.sendOther($rootScope.selectedPeerID, appPollsManager.getInputMediaPoll(poll));
return {
_: 'pollAnswer',
text: value,
option: new Uint8Array([idx])
};
});
appMessagesManager.sendOther($rootScope.selectedPeerID, {
_: 'inputMediaPoll',
flags: 0,
poll
});
}; };
onInput = (e: Event) => { onInput = (e: Event) => {

View File

@ -1,12 +1,12 @@
import { SliderTab } from "../../slider";
import appSidebarLeft, { AppSidebarLeft } from ".."; import appSidebarLeft, { AppSidebarLeft } from "..";
import lottieLoader, { RLottiePlayer } from "../../../lib/lottieLoader";
import appMessagesManager, { MyDialogFilter as DialogFilter } from "../../../lib/appManagers/appMessagesManager";
import { parseMenuButtonsTo } from "../../misc";
import appDialogsManager from "../../../lib/appManagers/appDialogsManager"; import appDialogsManager from "../../../lib/appManagers/appDialogsManager";
import appMessagesManager, { MyDialogFilter as DialogFilter } from "../../../lib/appManagers/appMessagesManager";
import lottieLoader, { RLottiePlayer } from "../../../lib/lottieLoader";
import { copy, deepEqual } from "../../../lib/utils"; import { copy, deepEqual } from "../../../lib/utils";
import { toast } from "../../toast"; import { parseMenuButtonsTo } from "../../misc";
import { ripple } from "../../ripple"; import { ripple } from "../../ripple";
import { SliderTab } from "../../slider";
import { toast } from "../../toast";
const MAX_FOLDER_NAME_LENGTH = 12; const MAX_FOLDER_NAME_LENGTH = 12;
@ -243,7 +243,6 @@ export default class AppEditFolderTab implements SliderTab {
if(filter === undefined) { if(filter === undefined) {
this.setFilter({ this.setFilter({
_: 'dialogFilter', _: 'dialogFilter',
flags: 0,
id: 0, id: 0,
title: '', title: '',
pFlags: {}, pFlags: {},

View File

@ -494,14 +494,6 @@
<div id="bubbles-inner"></div> <div id="bubbles-inner"></div>
<div id="bubbles-go-down" class="tgico-down btn-corner z-depth-1 rp hide"></div> <div id="bubbles-go-down" class="tgico-down btn-corner z-depth-1 rp hide"></div>
</div> </div>
<div class="btn-menu" id="bubble-contextmenu">
<div class="btn-menu-item menu-reply tgico-reply rp">Reply</div>
<div class="btn-menu-item menu-edit tgico-edit rp">Edit</div>
<div class="btn-menu-item menu-copy tgico-copy rp">Copy</div>
<div class="btn-menu-item menu-pin tgico-pin rp">Pin</div>
<div class="btn-menu-item menu-forward tgico-forward rp">Forward</div>
<div class="btn-menu-item menu-delete tgico-delete danger rp">Delete</div>
</div>
<div id="chat-input" style="display: none;"> <div id="chat-input" style="display: none;">
<div class="chat-input-container"> <div class="chat-input-container">
<div class="input-message"> <div class="input-message">

View File

@ -1,29 +1,27 @@
import appMessagesManager from "./appMessagesManager";
import apiManagerProxy from "../mtproto/mtprotoworker";
import appPeersManager from "../appManagers/appPeersManager";
import appMessagesIDsManager from "./appMessagesIDsManager";
import { RichTextProcessor } from "../richtextprocessor";
import { toast } from "../../components/toast"; import { toast } from "../../components/toast";
import appUsersManager from "./appUsersManager";
import appPhotosManager from "./appPhotosManager";
import appDocsManager from "./appDocsManager";
import { BotInlineResult } from "../../layer"; import { BotInlineResult } from "../../layer";
import appPeersManager from "../appManagers/appPeersManager";
import apiManagerProxy from "../mtproto/mtprotoworker";
import { RichTextProcessor } from "../richtextprocessor";
import appDocsManager from "./appDocsManager";
import appMessagesIDsManager from "./appMessagesIDsManager";
import appMessagesManager from "./appMessagesManager";
import appPhotosManager from "./appPhotosManager";
import appUsersManager from "./appUsersManager";
export class AppInlineBotsManager { export class AppInlineBotsManager {
private inlineResults: {[qID: string]: BotInlineResult} = {}; private inlineResults: {[qID: string]: BotInlineResult} = {};
public getInlineResults(peerID: number, botID: number, query = '', offset = '', geo?: any) { public getInlineResults(peerID: number, botID: number, query = '', offset = '', geo?: any) {
return apiManagerProxy.invokeApi('messages.getInlineBotResults', { return apiManagerProxy.invokeApi('messages.getInlineBotResults', {
flags: 0 | (geo ? 1 : 0),
bot: appUsersManager.getUserInput(botID), bot: appUsersManager.getUserInput(botID),
peer: appPeersManager.getInputPeerByID(peerID), peer: appPeersManager.getInputPeerByID(peerID),
query: query, query: query,
geo_point: geo && {_: 'inputGeoPoint', lat: geo['lat'], long: geo['long']}, geo_point: (geo && {_: 'inputGeoPoint', lat: geo['lat'], long: geo['long']}) || undefined,
offset offset
}, {/* timeout: 1, */stopTime: -1, noErrorBox: true}).then(botResults => { }, {/* timeout: 1, */stopTime: -1, noErrorBox: true}).then(botResults => {
const queryID = botResults.query_id; const queryID = botResults.query_id;
/* delete botResults._; /* delete botResults._;
delete botResults.flags;
delete botResults.query_id; */ delete botResults.query_id; */
/* if(botResults.switch_pm) { /* if(botResults.switch_pm) {

View File

@ -1,13 +1,13 @@
//import apiManager from '../mtproto/apiManager'; //import apiManager from '../mtproto/apiManager';
import { logger, LogLevels } from '../logger';
import apiManager from '../mtproto/mtprotoworker'; import apiManager from '../mtproto/mtprotoworker';
import $rootScope from '../rootScope';
//import networkerFactory from '../mtproto/networkerFactory'; //import networkerFactory from '../mtproto/networkerFactory';
import { tsNow } from "../utils"; import { tsNow } from "../utils";
import appPeersManager from "./appPeersManager";
import appUsersManager from "./appUsersManager";
import appChatsManager from "./appChatsManager"; import appChatsManager from "./appChatsManager";
import { logger, LogLevels } from '../logger'; import appPeersManager from "./appPeersManager";
import $rootScope from '../rootScope';
import appStateManager from './appStateManager'; import appStateManager from './appStateManager';
import appUsersManager from "./appUsersManager";
export class ApiUpdatesManager { export class ApiUpdatesManager {
public updatesState: { public updatesState: {
@ -160,7 +160,6 @@ export class ApiUpdatesManager {
_: 'updateNewMessage', _: 'updateNewMessage',
message: { message: {
_: 'message', _: 'message',
flags: updateMessage.flags,
pFlags: updateMessage.pFlags, pFlags: updateMessage.pFlags,
id: updateMessage.id, id: updateMessage.id,
from_id: appPeersManager.getOutputPeer(fromID), from_id: appPeersManager.getOutputPeer(fromID),
@ -207,7 +206,6 @@ export class ApiUpdatesManager {
} }
return apiManager.invokeApi('updates.getDifference', { return apiManager.invokeApi('updates.getDifference', {
flags: 0,
pts: updatesState.pts, pts: updatesState.pts,
date: updatesState.date, date: updatesState.date,
qts: -1 qts: -1

View File

@ -59,7 +59,7 @@ export type Chat = {
default_banned_rights?: any default_banned_rights?: any
}; };
export type ChatRights = 'send' | 'edit_title' | 'edit_photo' | 'invite' | 'pin' | 'deleteRevoke'; export type ChatRights = 'send' | 'edit_title' | 'edit_photo' | 'invite' | 'pin' | 'deleteRevoke' | 'delete';
export class AppChatsManager { export class AppChatsManager {
public chats: {[id: number]: Channel | Chat | any} = {}; public chats: {[id: number]: Channel | Chat | any} = {};

View File

@ -1,12 +1,12 @@
import {RichTextProcessor} from '../richtextprocessor'; import { Document, InputFileLocation, PhotoSize } from '../../layer';
import { isObject, getFileURL, FileURLType, safeReplaceArrayInObject } from '../utils';
import opusDecodeController from '../opusDecodeController';
import { getFileNameByLocation } from '../bin_utils'; import { getFileNameByLocation } from '../bin_utils';
import { MOUNT_CLASS_TO } from '../mtproto/mtproto_config';
import referenceDatabase, { ReferenceContext } from '../mtproto/referenceDatabase';
import opusDecodeController from '../opusDecodeController';
import { RichTextProcessor } from '../richtextprocessor';
import { FileURLType, getFileURL, isObject, safeReplaceArrayInObject } from '../utils';
import appDownloadManager, { DownloadBlob } from './appDownloadManager'; import appDownloadManager, { DownloadBlob } from './appDownloadManager';
import appPhotosManager from './appPhotosManager'; import appPhotosManager from './appPhotosManager';
import { InputFileLocation, Document, PhotoSize } from '../../layer';
import referenceDatabase, { ReferenceContext } from '../mtproto/referenceDatabase';
import { MOUNT_CLASS_TO } from '../mtproto/mtproto_config';
export type MyDocument = Document.document; export type MyDocument = Document.document;
@ -173,7 +173,6 @@ class AppDocsManager {
public getMediaInput(doc: MyDocument) { public getMediaInput(doc: MyDocument) {
return { return {
_: 'inputMediaDocument', _: 'inputMediaDocument',
flags: 0,
id: { id: {
_: 'inputDocument', _: 'inputDocument',
id: doc.id, id: doc.id,

View File

@ -1,49 +1,49 @@
//import apiManager from '../mtproto/apiManager'; //import apiManager from '../mtproto/apiManager';
import apiManager from '../mtproto/mtprotoworker';
import { numberWithCommas, findUpClassName, formatNumber, placeCaretAtEnd, findUpTag, langPack, whichChild, cancelEvent, getObjectKeysAndSort } from "../utils";
import appUsersManager from "./appUsersManager";
import appMessagesManager, { Dialog } from "./appMessagesManager";
import appPeersManager from "./appPeersManager";
import appProfileManager from "./appProfileManager";
import appDialogsManager from "./appDialogsManager";
import { RichTextProcessor } from "../richtextprocessor";
import appPhotosManager from "./appPhotosManager";
import appSidebarRight, { AppSidebarRight, RIGHT_COLUMN_ACTIVE_CLASSNAME } from '../../components/sidebarRight';
import { logger, LogLevels } from "../logger";
import appMediaViewer from "./appMediaViewer";
import appSidebarLeft from "../../components/sidebarLeft";
import appChatsManager, { Channel, Chat } from "./appChatsManager";
import { wrapDocument, wrapPhoto, wrapVideo, wrapSticker, wrapReply, wrapAlbum, wrapPoll } from '../../components/wrappers';
import ProgressivePreloader from '../../components/preloader';
import { formatPhoneNumber, parseMenuButtonsTo } from '../../components/misc';
import { ChatInput } from '../../components/chat/input';
//import Scrollable from '../../components/scrollable';
import Scrollable from '../../components/scrollable';
import BubbleGroups from '../../components/bubbleGroups';
import LazyLoadQueue from '../../components/lazyLoadQueue';
import appDocsManager from './appDocsManager';
import appStickersManager from './appStickersManager';
import AvatarElement from '../../components/avatar';
import appInlineBotsManager from './AppInlineBotsManager';
import StickyIntersector from '../../components/stickyIntersector';
import animationIntersector from '../../components/animationIntersector'; import animationIntersector from '../../components/animationIntersector';
import PopupStickers from '../../components/popupStickers';
import PopupDatePicker from '../../components/popupDatepicker';
import appPollsManager from './appPollsManager';
import { ripple } from '../../components/ripple';
import { horizontalMenu } from '../../components/horizontalMenu';
import AudioElement from '../../components/audio'; import AudioElement from '../../components/audio';
import { InputNotifyPeer, InputPeerNotifySettings } from '../../layer'; import AvatarElement from '../../components/avatar';
import BubbleGroups from '../../components/bubbleGroups';
import { ChatAudio } from '../../components/chat/audio'; import { ChatAudio } from '../../components/chat/audio';
import { ChatContextMenu } from '../../components/chat/contextMenu'; import { ChatContextMenu } from '../../components/chat/contextMenu';
import { ChatInput } from '../../components/chat/input';
import { ChatSearch } from '../../components/chat/search'; import { ChatSearch } from '../../components/chat/search';
import { horizontalMenu } from '../../components/horizontalMenu';
import LazyLoadQueue from '../../components/lazyLoadQueue';
import { formatPhoneNumber, parseMenuButtonsTo } from '../../components/misc';
import PopupDatePicker from '../../components/popupDatepicker';
import PopupStickers from '../../components/popupStickers';
import ProgressivePreloader from '../../components/preloader';
import { ripple } from '../../components/ripple';
//import Scrollable from '../../components/scrollable';
import Scrollable from '../../components/scrollable';
import appSidebarLeft from "../../components/sidebarLeft";
import appSidebarRight, { AppSidebarRight, RIGHT_COLUMN_ACTIVE_CLASSNAME } from '../../components/sidebarRight';
import StickyIntersector from '../../components/stickyIntersector';
import { wrapAlbum, wrapDocument, wrapPhoto, wrapPoll, wrapReply, wrapSticker, wrapVideo } from '../../components/wrappers';
import mediaSizes from '../../helpers/mediaSizes'; import mediaSizes from '../../helpers/mediaSizes';
import { isAndroid, isApple, isSafari } from '../../helpers/userAgent';
import { MOUNT_CLASS_TO } from '../mtproto/mtproto_config';
import $rootScope from '../rootScope';
import { isTouchSupported } from '../../helpers/touchSupport'; import { isTouchSupported } from '../../helpers/touchSupport';
import { isAndroid, isApple, isSafari } from '../../helpers/userAgent';
import { InputNotifyPeer, InputPeerNotifySettings } from '../../layer';
import { logger, LogLevels } from "../logger";
import apiManager from '../mtproto/mtprotoworker';
import { MOUNT_CLASS_TO } from '../mtproto/mtproto_config';
import { RichTextProcessor } from "../richtextprocessor";
import $rootScope from '../rootScope';
import { cancelEvent, findUpClassName, findUpTag, formatNumber, getObjectKeysAndSort, langPack, numberWithCommas, placeCaretAtEnd, whichChild } from "../utils";
import apiUpdatesManager from './apiUpdatesManager'; import apiUpdatesManager from './apiUpdatesManager';
import appChatsManager, { Channel, Chat } from "./appChatsManager";
import appDialogsManager from "./appDialogsManager";
import appDocsManager from './appDocsManager';
import appInlineBotsManager from './AppInlineBotsManager';
import appMediaViewer from "./appMediaViewer";
import appMessagesManager, { Dialog } from "./appMessagesManager";
import appPeersManager from "./appPeersManager";
import appPhotosManager from "./appPhotosManager";
import appPollsManager from './appPollsManager';
import appProfileManager from "./appProfileManager";
import appStickersManager from './appStickersManager';
import appUsersManager from "./appUsersManager";
//console.log('appImManager included33!'); //console.log('appImManager included33!');
@ -2612,9 +2612,7 @@ export class AppImManager {
}; };
let settings: InputPeerNotifySettings = { let settings: InputPeerNotifySettings = {
_: 'inputPeerNotifySettings', _: 'inputPeerNotifySettings'
flags: 0,
mute_until: 0
}; };
let dialog = appMessagesManager.getDialogByPeerID(peerID)[0]; let dialog = appMessagesManager.getDialogByPeerID(peerID)[0];
@ -2624,10 +2622,7 @@ export class AppImManager {
} }
if(!muted) { if(!muted) {
settings.flags |= 1 << 2;
settings.mute_until = 2147483647; settings.mute_until = 2147483647;
} else {
settings.flags |= 2;
} }
apiManager.invokeApi('account.updateNotifySettings', { apiManager.invokeApi('account.updateNotifySettings', {
@ -2640,7 +2635,6 @@ export class AppImManager {
/* return apiManager.invokeApi('account.getNotifySettings', { /* return apiManager.invokeApi('account.getNotifySettings', {
peer: inputNotifyPeer peer: inputNotifyPeer
}).then((settings: any) => { }).then((settings: any) => {
settings.flags |= 2 << 1;
settings.mute_until = 2000000000; // 2147483646 settings.mute_until = 2000000000; // 2147483646
return apiManager.invokeApi('account.updateNotifySettings', { return apiManager.invokeApi('account.updateNotifySettings', {

View File

@ -1,33 +1,32 @@
import { copy, tsNow, safeReplaceObject, listMergeSorted, deepEqual, langPack, getObjectKeysAndSort, limitSymbols } from "../utils";
import appMessagesIDsManager from "./appMessagesIDsManager";
import appChatsManager from "./appChatsManager";
import appUsersManager from "./appUsersManager";
import { RichTextProcessor } from "../richtextprocessor";
import { nextRandomInt, bigint } from "../bin_utils";
//import { telegramMeWebService } from "../mtproto/mtproto";
import apiUpdatesManager from "./apiUpdatesManager";
import appPhotosManager, { MyPhoto } from "./appPhotosManager";
import AppStorage from '../storage';
import appPeersManager from "./appPeersManager";
import ServerTimeManager from "../mtproto/serverTimeManager";
import appDocsManager, {MyDocument} from "./appDocsManager";
import ProgressivePreloader from "../../components/preloader"; import ProgressivePreloader from "../../components/preloader";
import serverTimeManager from "../mtproto/serverTimeManager"; import { CancellablePromise, deferredPromise } from "../../helpers/cancellablePromise";
import { Dialog as MTDialog, DialogFilter, DocumentAttribute, InputMessage, Message, MessagesDialogs, MessagesFilter, MessagesMessages, MessagesPeerDialogs, MethodDeclMap, PhotoSize } from "../../layer";
import { Modify } from "../../types";
import { bigint, nextRandomInt } from "../bin_utils";
import { logger } from "../logger";
import type { ApiFileManager } from '../mtproto/apiFileManager';
//import apiManager from '../mtproto/apiManager'; //import apiManager from '../mtproto/apiManager';
import apiManager from '../mtproto/mtprotoworker'; import apiManager from '../mtproto/mtprotoworker';
import appWebPagesManager from "./appWebPagesManager";
import { CancellablePromise, deferredPromise } from "../../helpers/cancellablePromise";
import appPollsManager from "./appPollsManager";
import searchIndexManager from '../searchIndexManager';
import { Modify } from "../../types";
import { logger, LogLevels } from "../logger";
import type {ApiFileManager} from '../mtproto/apiFileManager';
import appDownloadManager from "./appDownloadManager";
import { DialogFilter, Message, InputMessage, MethodDeclMap, MessagesFilter, PhotoSize, DocumentAttribute, Dialog as MTDialog, MessagesDialogs, MessagesPeerDialogs, MessagesMessages, MessageMedia } from "../../layer";
import referenceDatabase, { ReferenceContext } from "../mtproto/referenceDatabase"; import referenceDatabase, { ReferenceContext } from "../mtproto/referenceDatabase";
import { default as ServerTimeManager, default as serverTimeManager } from "../mtproto/serverTimeManager";
import { RichTextProcessor } from "../richtextprocessor";
import $rootScope from "../rootScope"; import $rootScope from "../rootScope";
import searchIndexManager from '../searchIndexManager';
import AppStorage from '../storage';
import { copy, deepEqual, getObjectKeysAndSort, langPack, limitSymbols, listMergeSorted, safeReplaceObject, tsNow } from "../utils";
//import { telegramMeWebService } from "../mtproto/mtproto";
import apiUpdatesManager from "./apiUpdatesManager";
import appChatsManager from "./appChatsManager";
import appDocsManager, { MyDocument } from "./appDocsManager";
import appDownloadManager from "./appDownloadManager";
import appMessagesIDsManager from "./appMessagesIDsManager";
import appPeersManager from "./appPeersManager";
import appPhotosManager, { MyPhoto } from "./appPhotosManager";
import appPollsManager from "./appPollsManager";
import appStateManager from "./appStateManager"; import appStateManager from "./appStateManager";
import appUsersManager from "./appUsersManager";
import appWebPagesManager from "./appWebPagesManager";
//console.trace('include'); //console.trace('include');
// TODO: если удалить сообщение в непрогруженном диалоге, то при обновлении, из-за стейта, последнего сообщения в чатлисте не будет // TODO: если удалить сообщение в непрогруженном диалоге, то при обновлении, из-за стейта, последнего сообщения в чатлисте не будет
@ -345,31 +344,6 @@ export class FiltersStorage {
public updateDialogFilter(filter: MyDialogFilter, remove = false) { public updateDialogFilter(filter: MyDialogFilter, remove = false) {
const flags = remove ? 0 : 1; const flags = remove ? 0 : 1;
if(!remove) {
filter.flags = 0;
const f: {[k: string]: number} = {
contacts: 0,
non_contacts: 1,
groups: 2,
broadcasts: 3,
bots: 4,
exclude_muted: 11,
exclude_read: 12,
exclude_archived: 13
};
for(const key in f) {
// @ts-ignore
if(filter.pFlags[key]) {
filter.flags |= 1 << f[key];
}
}
if(filter.emoticon) {
filter.flags |= 1 << 25;
}
}
return apiManager.invokeApi('messages.updateDialogFilter', { return apiManager.invokeApi('messages.updateDialogFilter', {
flags, flags,
id: filter.id, id: filter.id,
@ -536,10 +510,15 @@ export class AppMessagesManager {
}); });
$rootScope.$on('webpage_updated', (e) => { $rootScope.$on('webpage_updated', (e) => {
let eventData = e.detail; const eventData = e.detail;
eventData.msgs.forEach((msgID) => { eventData.msgs.forEach((msgID) => {
let message = this.getMessage(msgID) as Message.message; const message = this.getMessage(msgID) as Message.message;
(message.media as MessageMedia.messageMediaWebPage).webpage = appWebPagesManager.getWebPage(eventData.id); // warning if(!message) return;
message.media = {
_: 'messageMediaWebPage',
webpage: appWebPagesManager.getWebPage(eventData.id)
};
$rootScope.$broadcast('message_edit', { $rootScope.$broadcast('message_edit', {
peerID: this.getMessagePeer(message), peerID: this.getMessagePeer(message),
id: message.id, id: message.id,
@ -684,11 +663,12 @@ export class AppMessagesManager {
return sendEntites; return sendEntites;
} }
public editMessage(messageID: number, text: string, options: { public editMessage(messageID: number, text: string, options: Partial<{
noWebPage?: boolean noWebPage: true,
} = {}) { newMedia: any
if(typeof(text) !== 'string' || !this.canEditMessage(messageID)) { }> = {}) {
return Promise.reject(); if(!this.canEditMessage(messageID)) {
return Promise.reject({type: 'MESSAGE_EDIT_FORBIDDEN'});
} }
if(messageID < 0) { if(messageID < 0) {
@ -696,7 +676,7 @@ export class AppMessagesManager {
this.tempFinalizeCallbacks[messageID] = {} this.tempFinalizeCallbacks[messageID] = {}
} }
let promise = new Promise((resolve, reject) => { const promise = new Promise((resolve, reject) => {
this.tempFinalizeCallbacks[messageID].edit = (mid: number) => { this.tempFinalizeCallbacks[messageID].edit = (mid: number) => {
this.log('invoke callback', mid) this.log('invoke callback', mid)
this.editMessage(mid, text).then(resolve, reject); this.editMessage(mid, text).then(resolve, reject);
@ -706,38 +686,27 @@ export class AppMessagesManager {
return promise; return promise;
} }
var entities: any = []; let entities: any[];
text = RichTextProcessor.parseMarkdown(text, entities) if(typeof(text) === 'string') {
entities = [];
var message = this.getMessage(messageID); text = RichTextProcessor.parseMarkdown(text, entities);
var peerID = this.getMessagePeer(message);
var flags = 0;
let noWebPage = options.noWebPage || false;
if(noWebPage) {
flags |= 2;
} }
if(text) { const message = this.getMessage(messageID);
flags |= 8 | 1 << 11; const peerID = this.getMessagePeer(message);
}
/* if(message.media) {
flags |= 1 << 14;
} */
return apiManager.invokeApi('messages.editMessage', { return apiManager.invokeApi('messages.editMessage', {
flags: flags,
peer: appPeersManager.getInputPeerByID(peerID), peer: appPeersManager.getInputPeerByID(peerID),
id: appMessagesIDsManager.getMessageLocalID(messageID), id: appMessagesIDsManager.getMessageLocalID(messageID),
message: text, message: text,
// @ts-ignore media: options.newMedia,
media: message.media, entities: entities ? this.getInputEntities(entities) : undefined,
entities: this.getInputEntities(entities), no_webpage: options.noWebPage,
no_webpage: noWebPage || undefined,
}).then((updates) => { }).then((updates) => {
apiUpdatesManager.processUpdateMessage(updates); apiUpdatesManager.processUpdateMessage(updates);
}, (error) => { }, (error) => {
this.log.error('editMessage error:', error);
if(error && error.type == 'MESSAGE_NOT_MODIFIED') { if(error && error.type == 'MESSAGE_NOT_MODIFIED') {
error.handled = true; error.handled = true;
return; return;
@ -755,9 +724,9 @@ export class AppMessagesManager {
viaBotID: number, viaBotID: number,
queryID: string, queryID: string,
resultID: string, resultID: string,
noWebPage: boolean, noWebPage: true,
reply_markup: any, reply_markup: any,
clearDraft: boolean, clearDraft: true,
webPage: any webPage: any
}> = {}) { }> = {}) {
if(typeof(text) != 'string') { if(typeof(text) != 'string') {
@ -775,18 +744,20 @@ export class AppMessagesManager {
} }
var sendEntites = this.getInputEntities(entities); var sendEntites = this.getInputEntities(entities);
if(!sendEntites.length) {
sendEntites = undefined;
}
var messageID = this.tempID--; var messageID = this.tempID--;
var randomID = [nextRandomInt(0xFFFFFFFF), nextRandomInt(0xFFFFFFFF)]; var randomID = [nextRandomInt(0xFFFFFFFF), nextRandomInt(0xFFFFFFFF)];
var randomIDS = bigint(randomID[0]).shiftLeft(32).add(bigint(randomID[1])).toString(); var randomIDS = bigint(randomID[0]).shiftLeft(32).add(bigint(randomID[1])).toString();
var historyStorage = this.historiesStorage[peerID]; var historyStorage = this.historiesStorage[peerID];
var flags = 0;
var pFlags: any = {}; var pFlags: any = {};
var replyToMsgID = options.replyToMsgID; var replyToMsgID = options.replyToMsgID;
var isChannel = appPeersManager.isChannel(peerID); var isChannel = appPeersManager.isChannel(peerID);
var isMegagroup = isChannel && appPeersManager.isMegagroup(peerID); var isMegagroup = isChannel && appPeersManager.isMegagroup(peerID);
var asChannel = isChannel && !isMegagroup ? true : false; var asChannel = isChannel && !isMegagroup ? true : false;
var message: any; var message: any;
let noWebPage = options.noWebPage || false;
if(historyStorage === undefined) { if(historyStorage === undefined) {
historyStorage = this.historiesStorage[peerID] = {count: null, history: [], pending: []}; historyStorage = this.historiesStorage[peerID] = {count: null, history: [], pending: []};
@ -794,24 +765,16 @@ export class AppMessagesManager {
var fromID = appUsersManager.getSelf().id; var fromID = appUsersManager.getSelf().id;
if(peerID != fromID) { if(peerID != fromID) {
flags |= 2;
pFlags.out = true; pFlags.out = true;
if(!isChannel && !appUsersManager.isBot(peerID)) { if(!isChannel && !appUsersManager.isBot(peerID)) {
flags |= 1;
pFlags.unread = true; pFlags.unread = true;
} }
} }
if(replyToMsgID) {
flags |= 8;
}
if(asChannel) { if(asChannel) {
fromID = 0; fromID = 0;
pFlags.post = true; pFlags.post = true;
} else {
flags |= 256;
} }
message = { message = {
@ -819,7 +782,6 @@ export class AppMessagesManager {
id: messageID, id: messageID,
from_id: appPeersManager.getOutputPeer(fromID), from_id: appPeersManager.getOutputPeer(fromID),
peer_id: appPeersManager.getOutputPeer(peerID), peer_id: appPeersManager.getOutputPeer(peerID),
flags: flags,
pFlags: pFlags, pFlags: pFlags,
date: tsNow(true) + serverTimeManager.serverTimeOffset, date: tsNow(true) + serverTimeManager.serverTimeOffset,
message: text, message: text,
@ -855,53 +817,31 @@ export class AppMessagesManager {
sentRequestOptions.afterMessageID = this.pendingAfterMsgs[peerID].messageID; sentRequestOptions.afterMessageID = this.pendingAfterMsgs[peerID].messageID;
} }
var flags = 0;
if(replyToMsgID) {
flags |= 1;
}
if(asChannel) {
flags |= 16;
}
if(options.clearDraft) {
flags |= 128;
}
if(noWebPage) {
flags |= 2;
}
var apiPromise: any; var apiPromise: any;
if(options.viaBotID) { if(options.viaBotID) {
apiPromise = apiManager.invokeApi('messages.sendInlineBotResult', { apiPromise = apiManager.invokeApi('messages.sendInlineBotResult', {
flags: flags,
peer: appPeersManager.getInputPeerByID(peerID), peer: appPeersManager.getInputPeerByID(peerID),
random_id: randomID as any, random_id: randomID as any,
reply_to_msg_id: appMessagesIDsManager.getMessageLocalID(replyToMsgID), reply_to_msg_id: replyToMsgID ? appMessagesIDsManager.getMessageLocalID(replyToMsgID) : undefined,
query_id: options.queryID, query_id: options.queryID,
id: options.resultID id: options.resultID,
clear_draft: options.clearDraft
}, sentRequestOptions); }, sentRequestOptions);
} else { } else {
if(sendEntites.length) {
flags |= 8;
}
apiPromise = apiManager.invokeApi('messages.sendMessage', { apiPromise = apiManager.invokeApi('messages.sendMessage', {
flags: flags, no_webpage: options.noWebPage,
no_webpage: noWebPage || undefined,
peer: appPeersManager.getInputPeerByID(peerID), peer: appPeersManager.getInputPeerByID(peerID),
message: text, message: text,
random_id: randomID as any, random_id: randomID as any,
reply_to_msg_id: appMessagesIDsManager.getMessageLocalID(replyToMsgID), reply_to_msg_id: replyToMsgID ? appMessagesIDsManager.getMessageLocalID(replyToMsgID) : undefined,
entities: sendEntites entities: sendEntites,
clear_draft: options.clearDraft
}, sentRequestOptions); }, sentRequestOptions);
} }
// this.log(flags, entities) // this.log(flags, entities)
apiPromise.then((updates: any) => { apiPromise.then((updates: any) => {
if(updates._ == 'updateShortSentMessage') { if(updates._ == 'updateShortSentMessage') {
message.flags = updates.flags;
message.date = updates.date; message.date = updates.date;
message.id = updates.id; message.id = updates.id;
message.media = updates.media; message.media = updates.media;
@ -1249,7 +1189,6 @@ export class AppMessagesManager {
const inputMedia = { const inputMedia = {
_: 'inputMediaDocument', _: 'inputMediaDocument',
flags: 0,
id: { id: {
_: 'inputDocument', _: 'inputDocument',
id: id, id: id,
@ -1279,7 +1218,6 @@ export class AppMessagesManager {
case 'photo': case 'photo':
inputMedia = { inputMedia = {
_: 'inputMediaUploadedPhoto', _: 'inputMediaUploadedPhoto',
flags: 0,
file: inputFile file: inputFile
}; };
break; break;
@ -1561,7 +1499,6 @@ export class AppMessagesManager {
if(details.duration) { if(details.duration) {
inputMedia = { inputMedia = {
_: 'inputMediaUploadedDocument', _: 'inputMediaUploadedDocument',
flags: 0,
file: inputFile, file: inputFile,
mime_type: file.type, mime_type: file.type,
attributes: [{ attributes: [{
@ -1576,7 +1513,6 @@ export class AppMessagesManager {
} else { } else {
inputMedia = { inputMedia = {
_: 'inputMediaUploadedPhoto', _: 'inputMediaUploadedPhoto',
flags: 0,
file: inputFile file: inputFile
}; };
} }
@ -1600,7 +1536,6 @@ export class AppMessagesManager {
inputs.push({ inputs.push({
_: 'inputSingleMedia', _: 'inputSingleMedia',
flags: 0,
media: inputMedia, media: inputMedia,
random_id: message.randomID, random_id: message.randomID,
message: caption, message: caption,
@ -1627,7 +1562,7 @@ export class AppMessagesManager {
replyToMsgID: number, replyToMsgID: number,
viaBotID: number, viaBotID: number,
reply_markup: any, reply_markup: any,
clearDraft: boolean, clearDraft: true,
queryID: string queryID: string
resultID: string resultID: string
}> = {}) { }> = {}) {
@ -1724,24 +1659,17 @@ export class AppMessagesManager {
break; */ break; */
} }
let flags = 0;
let pFlags: any = {}; let pFlags: any = {};
if(peerID != fromID) { if(peerID != fromID) {
flags |= 2;
pFlags.out = true; pFlags.out = true;
if(!appUsersManager.isBot(peerID)) { if(!appUsersManager.isBot(peerID)) {
flags |= 1;
pFlags.unread = true; pFlags.unread = true;
} }
} }
if(replyToMsgID) {
flags |= 8;
}
if(asChannel) { if(asChannel) {
fromID = 0; fromID = 0;
pFlags.post = true; pFlags.post = true;
} else {
flags |= 256;
} }
const message: any = { const message: any = {
@ -1749,7 +1677,6 @@ export class AppMessagesManager {
id: messageID, id: messageID,
from_id: appPeersManager.getOutputPeer(fromID), from_id: appPeersManager.getOutputPeer(fromID),
peer_id: appPeersManager.getOutputPeer(peerID), peer_id: appPeersManager.getOutputPeer(peerID),
flags: flags,
pFlags: pFlags, pFlags: pFlags,
date: tsNow(true) + ServerTimeManager.serverTimeOffset, date: tsNow(true) + ServerTimeManager.serverTimeOffset,
message: '', message: '',
@ -1779,17 +1706,6 @@ export class AppMessagesManager {
}; };
message.send = () => { message.send = () => {
let flags = 0;
if(replyToMsgID) {
flags |= 1;
}
if(asChannel) {
flags |= 16;
}
if(options.clearDraft) {
flags |= 128;
}
const sentRequestOptions: any = {}; const sentRequestOptions: any = {};
if(this.pendingAfterMsgs[peerID]) { if(this.pendingAfterMsgs[peerID]) {
sentRequestOptions.afterMessageID = this.pendingAfterMsgs[peerID].messageID; sentRequestOptions.afterMessageID = this.pendingAfterMsgs[peerID].messageID;
@ -1798,23 +1714,24 @@ export class AppMessagesManager {
let apiPromise: Promise<any>; let apiPromise: Promise<any>;
if(options.viaBotID) { if(options.viaBotID) {
apiPromise = apiManager.invokeApi('messages.sendInlineBotResult', { apiPromise = apiManager.invokeApi('messages.sendInlineBotResult', {
flags: flags,
peer: appPeersManager.getInputPeerByID(peerID), peer: appPeersManager.getInputPeerByID(peerID),
random_id: randomID as any, random_id: randomID as any,
reply_to_msg_id: appMessagesIDsManager.getMessageLocalID(replyToMsgID), reply_to_msg_id: replyToMsgID ? appMessagesIDsManager.getMessageLocalID(replyToMsgID) : undefined,
query_id: options.queryID, query_id: options.queryID,
id: options.resultID id: options.resultID,
clear_draft: options.clearDraft
}, sentRequestOptions); }, sentRequestOptions);
} else { } else {
apiPromise = apiManager.invokeApi('messages.sendMedia', { apiPromise = apiManager.invokeApi('messages.sendMedia', {
flags: flags,
peer: appPeersManager.getInputPeerByID(peerID), peer: appPeersManager.getInputPeerByID(peerID),
media: inputMedia, media: inputMedia,
random_id: randomID as any, random_id: randomID as any,
reply_to_msg_id: appMessagesIDsManager.getMessageLocalID(replyToMsgID), reply_to_msg_id: replyToMsgID ? appMessagesIDsManager.getMessageLocalID(replyToMsgID) : undefined,
message: '' message: '',
clear_draft: options.clearDraft
}, sentRequestOptions); }, sentRequestOptions);
} }
apiPromise.then((updates) => { apiPromise.then((updates) => {
if(updates.updates) { if(updates.updates) {
updates.updates.forEach((update: any) => { updates.updates.forEach((update: any) => {
@ -1849,15 +1766,15 @@ export class AppMessagesManager {
} }
public cancelPendingMessage(randomID: string) { public cancelPendingMessage(randomID: string) {
var pendingData = this.pendingByRandomID[randomID]; const pendingData = this.pendingByRandomID[randomID];
this.log('cancelPendingMessage', randomID, pendingData); this.log('cancelPendingMessage', randomID, pendingData);
if(pendingData) { if(pendingData) {
var peerID = pendingData[0]; const peerID = pendingData[0];
var tempID = pendingData[1]; const tempID = pendingData[1];
var historyStorage = this.historiesStorage[peerID]; const historyStorage = this.historiesStorage[peerID];
var pos = historyStorage.pending.indexOf(tempID); const pos = historyStorage.pending.indexOf(tempID);
apiUpdatesManager.processUpdateMessage({ apiUpdatesManager.processUpdateMessage({
_: 'updateShort', _: 'updateShort',
@ -2140,12 +2057,6 @@ export class AppMessagesManager {
var toID = message.peer_id && appPeersManager.getPeerID(message.peer_id) || 0; var toID = message.peer_id && appPeersManager.getPeerID(message.peer_id) || 0;
return toID; return toID;
/* if(toID < 0) {
return toID;
} else if(message.pFlags && message.pFlags.out || message.flags & 2) {
return toID;
}
return message.from_id; */
} }
public getDialogByPeerID(peerID: number): [Dialog, number] | [] { public getDialogByPeerID(peerID: number): [Dialog, number] | [] {
@ -2264,7 +2175,6 @@ export class AppMessagesManager {
public updatePinnedMessage(peerID: number, msgID: number) { public updatePinnedMessage(peerID: number, msgID: number) {
apiManager.invokeApi('messages.updatePinnedMessage', { apiManager.invokeApi('messages.updatePinnedMessage', {
flags: 0,
peer: appPeersManager.getInputPeerByID(peerID), peer: appPeersManager.getInputPeerByID(peerID),
id: msgID id: msgID
}).then(updates => { }).then(updates => {
@ -2679,12 +2589,14 @@ export class AppMessagesManager {
} }
public canMessageBeEdited(message: any) { public canMessageBeEdited(message: any) {
var goodMedias = [ const goodMedias = [
'messageMediaPhoto', 'messageMediaPhoto',
'messageMediaDocument', 'messageMediaDocument',
'messageMediaWebPage', 'messageMediaWebPage',
'messageMediaPending' 'messageMediaPending',
] 'messageMediaPoll'
];
if(message._ != 'message' || if(message._ != 'message' ||
message.deleted || message.deleted ||
message.fwd_from || message.fwd_from ||
@ -2693,6 +2605,7 @@ export class AppMessagesManager {
message.fromID && appUsersManager.isBot(message.fromID)) { message.fromID && appUsersManager.isBot(message.fromID)) {
return false; return false;
} }
if(message.media && if(message.media &&
message.media._ == 'messageMediaDocument' && message.media._ == 'messageMediaDocument' &&
message.media.document.sticker) { message.media.document.sticker) {
@ -2716,7 +2629,7 @@ export class AppMessagesManager {
return true; return true;
} }
if(message.date < tsNow(true) - 2 * 86400 || !message.pFlags.out) { if((message.date < tsNow(true) - (2 * 86400) && message.media?._ != 'messageMediaPoll') || !message.pFlags.out) {
return false; return false;
} }
@ -2817,7 +2730,6 @@ export class AppMessagesManager {
from_id: appPeersManager.getOutputPeer(appUsersManager.getSelf().id), from_id: appPeersManager.getOutputPeer(appUsersManager.getSelf().id),
peer_id: appPeersManager.getOutputPeer(peerID), peer_id: appPeersManager.getOutputPeer(peerID),
deleted: true, deleted: true,
flags: 0,
pFlags: {out: true}, pFlags: {out: true},
date: 0, date: 0,
message: '' message: ''
@ -2903,8 +2815,7 @@ export class AppMessagesManager {
return false; return false;
} }
if(messageReplyMarkup.pFlags.selective && if(messageReplyMarkup.pFlags.selective) {
!(message.flags & 16)) {
return false; return false;
} }
@ -2950,7 +2861,6 @@ export class AppMessagesManager {
historyStorage.reply_markup = { historyStorage.reply_markup = {
_: 'replyKeyboardHide', _: 'replyKeyboardHide',
mid: message.mid, mid: message.mid,
flags: 0,
pFlags: {} pFlags: {}
}; };
// this.log('set', historyStorage.reply_markup) // this.log('set', historyStorage.reply_markup)
@ -3108,7 +3018,6 @@ export class AppMessagesManager {
let apiPromise: Promise<any>; let apiPromise: Promise<any>;
if(peerID || !query) { if(peerID || !query) {
apiPromise = apiManager.invokeApi('messages.search', { apiPromise = apiManager.invokeApi('messages.search', {
flags: 0,
peer: appPeersManager.getInputPeerByID(peerID), peer: appPeersManager.getInputPeerByID(peerID),
q: query || '', q: query || '',
filter: (inputFilter || {_: 'inputMessagesFilterEmpty'}) as any as MessagesFilter, filter: (inputFilter || {_: 'inputMessagesFilterEmpty'}) as any as MessagesFilter,
@ -3137,7 +3046,6 @@ export class AppMessagesManager {
} }
apiPromise = apiManager.invokeApi('messages.searchGlobal', { apiPromise = apiManager.invokeApi('messages.searchGlobal', {
flags: 0,
q: query, q: query,
filter: (inputFilter || {_: 'inputMessagesFilterEmpty'}) as any as MessagesFilter, filter: (inputFilter || {_: 'inputMessagesFilterEmpty'}) as any as MessagesFilter,
min_date: 0, min_date: 0,
@ -3893,7 +3801,6 @@ export class AppMessagesManager {
id: messageID, id: messageID,
from_id: message.from_id, from_id: message.from_id,
peer_id: message.peer_id, peer_id: message.peer_id,
flags: message.flags,
pFlags: message.pFlags, pFlags: message.pFlags,
date: message.date date: message.date
}; };
@ -4026,7 +3933,6 @@ export class AppMessagesManager {
id: messageID, id: messageID,
from_id: appPeersManager.getOutputPeer(fromID), from_id: appPeersManager.getOutputPeer(fromID),
peer_id: appPeersManager.getOutputPeer(peerID), peer_id: appPeersManager.getOutputPeer(peerID),
flags: 0,
pFlags: {unread: true}, pFlags: {unread: true},
date: (update.inbox_date || tsNow(true)) + serverTimeManager.serverTimeOffset, date: (update.inbox_date || tsNow(true)) + serverTimeManager.serverTimeOffset,
message: update.message, message: update.message,
@ -4387,7 +4293,6 @@ export class AppMessagesManager {
id: messageID, id: messageID,
from_id: peerID, from_id: peerID,
peer_id: appPeersManager.getOutputPeer(peerID), peer_id: appPeersManager.getOutputPeer(peerID),
flags: 0,
pFlags: {}, pFlags: {},
date: tsNow(true) + serverTimeManager.serverTimeOffset, date: tsNow(true) + serverTimeManager.serverTimeOffset,
action: { action: {

View File

@ -1,11 +1,11 @@
import { calcImageInBox, isObject, safeReplaceArrayInObject } from "../utils"; import { CancellablePromise } from "../../helpers/cancellablePromise";
import { bytesFromHex, getFileNameByLocation } from "../bin_utils";
import appDownloadManager from "./appDownloadManager";
import { isSafari } from "../../helpers/userAgent"; import { isSafari } from "../../helpers/userAgent";
import { FileLocation, InputFileLocation, Photo, PhotoSize } from "../../layer"; import { FileLocation, InputFileLocation, Photo, PhotoSize } from "../../layer";
import { MyDocument } from "./appDocsManager"; import { bytesFromHex, getFileNameByLocation } from "../bin_utils";
import { CancellablePromise } from "../../helpers/cancellablePromise";
import referenceDatabase, { ReferenceContext } from "../mtproto/referenceDatabase"; import referenceDatabase, { ReferenceContext } from "../mtproto/referenceDatabase";
import { calcImageInBox, isObject, safeReplaceArrayInObject } from "../utils";
import { MyDocument } from "./appDocsManager";
import appDownloadManager from "./appDownloadManager";
export type MyPhoto = Photo.photo; export type MyPhoto = Photo.photo;
@ -303,7 +303,6 @@ export class AppPhotosManager {
public getInput(photo: MyPhoto) { public getInput(photo: MyPhoto) {
return { return {
_: 'inputMediaPhoto', _: 'inputMediaPhoto',
flags: 0,
id: { id: {
_: 'inputPhoto', _: 'inputPhoto',
id: photo.id, id: photo.id,

View File

@ -1,12 +1,13 @@
import { logger, LogLevels } from "../logger";
import apiManager from "../mtproto/mtprotoworker";
import { MOUNT_CLASS_TO } from "../mtproto/mtproto_config";
import { RichTextProcessor } from "../richtextprocessor"; import { RichTextProcessor } from "../richtextprocessor";
import $rootScope from "../rootScope";
import { copy } from "../utils";
import apiUpdatesManager from "./apiUpdatesManager";
import appMessagesManager from './appMessagesManager'; import appMessagesManager from './appMessagesManager';
import appPeersManager from './appPeersManager'; import appPeersManager from './appPeersManager';
import apiManager from "../mtproto/mtprotoworker";
import apiUpdatesManager from "./apiUpdatesManager";
import $rootScope from "../rootScope";
import { logger, LogLevels } from "../logger";
import appUsersManager from "./appUsersManager"; import appUsersManager from "./appUsersManager";
import { MOUNT_CLASS_TO } from "../mtproto/mtproto_config";
export type PollAnswer = { export type PollAnswer = {
_: 'pollAnswer', _: 'pollAnswer',
@ -51,7 +52,6 @@ export type PollResults = {
export type Poll = { export type Poll = {
_: 'poll', _: 'poll',
flags: number,
question: string, question: string,
id: string, id: string,
answers: Array<PollAnswer>, answers: Array<PollAnswer>,
@ -140,6 +140,13 @@ class AppPollsManager {
}; };
} }
public getInputMediaPoll(poll: Poll) {
return {
_: 'inputMediaPoll',
poll
};
}
public sendVote(mid: number, optionIDs: number[]) { public sendVote(mid: number, optionIDs: number[]) {
const message = appMessagesManager.getMessage(mid); const message = appMessagesManager.getMessage(mid);
const poll: Poll = message.media.poll; const poll: Poll = message.media.poll;
@ -204,6 +211,23 @@ class AppPollsManager {
return votesList; return votesList;
}); });
} }
public stopPoll(mid: number) {
const message = appMessagesManager.getMessage(mid);
const poll: Poll = message.media.poll;
if(poll.pFlags.closed) return Promise.resolve();
const newPoll = copy(poll);
newPoll.pFlags.closed = true;
return appMessagesManager.editMessage(mid, undefined, {
newMedia: this.getInputMediaPoll(newPoll)
}).then(() => {
//console.log('stopped poll');
}, err => {
this.log.error('stopPoll error:', err);
});
}
} }
const appPollsManager = new AppPollsManager(); const appPollsManager = new AppPollsManager();

View File

@ -1,10 +1,10 @@
import apiManager from '../mtproto/mtprotoworker'; import { Document, InputFileLocation, InputStickerSet, MessagesRecentStickers, MessagesStickerSet, PhotoSize, StickerSet, StickerSetCovered } from '../../layer';
import appDocsManager from './appDocsManager';
import $rootScope from '../rootScope';
import { StickerSet, InputStickerSet, StickerSetCovered, MessagesRecentStickers, Document, InputFileLocation, MessagesStickerSet, PhotoSize } from '../../layer';
import { Modify } from '../../types'; import { Modify } from '../../types';
import appStateManager from './appStateManager'; import apiManager from '../mtproto/mtprotoworker';
import { MOUNT_CLASS_TO } from '../mtproto/mtproto_config'; import { MOUNT_CLASS_TO } from '../mtproto/mtproto_config';
import $rootScope from '../rootScope';
import appDocsManager from './appDocsManager';
import appStateManager from './appStateManager';
// TODO: если пак будет сохранён и потом обновлён, то недостающие стикеры не подгрузит // TODO: если пак будет сохранён и потом обновлён, то недостающие стикеры не подгрузит
@ -86,7 +86,7 @@ export class AppStickersManager {
public async getRecentStickers(): Promise<Modify<MessagesRecentStickers.messagesRecentStickers, { public async getRecentStickers(): Promise<Modify<MessagesRecentStickers.messagesRecentStickers, {
stickers: Document[] stickers: Document[]
}>> { }>> {
const res = await apiManager.invokeApi('messages.getRecentStickers', {flags: 0, hash: 0}) as MessagesRecentStickers.messagesRecentStickers; const res = await apiManager.invokeApi('messages.getRecentStickers') as MessagesRecentStickers.messagesRecentStickers;
if(res._ == 'messages.recentStickers') { if(res._ == 'messages.recentStickers') {
this.saveStickers(res.stickers); this.saveStickers(res.stickers);

View File

@ -1,5 +1,5 @@
import apiManager from './mtprotoworker';
import { AccountPassword } from '../../layer'; import { AccountPassword } from '../../layer';
import apiManager from './mtprotoworker';
import { MOUNT_CLASS_TO } from './mtproto_config'; import { MOUNT_CLASS_TO } from './mtproto_config';
//import { computeCheck } from "../crypto/srp"; //import { computeCheck } from "../crypto/srp";
@ -16,7 +16,6 @@ export class PasswordManager {
var params: any = { var params: any = {
new_settings: { new_settings: {
_: 'account.passwordInputSettings', _: 'account.passwordInputSettings',
flags: 0,
hint: settings.hint || '' hint: settings.hint || ''
} }
}; };
@ -35,17 +34,14 @@ export class PasswordManager {
secureRandom.nextBytes(saltRandom); secureRandom.nextBytes(saltRandom);
newHashPromise = this.makePasswordHash(newSalt, settings.new_password); newHashPromise = this.makePasswordHash(newSalt, settings.new_password);
params.new_settings.new_salt = newSalt; params.new_settings.new_salt = newSalt;
params.new_settings.flags |= 1;
} else { } else {
if(typeof settings.new_password === 'string') { if(typeof settings.new_password === 'string') {
params.new_settings.flags |= 1;
params.new_settings.new_salt = []; params.new_settings.new_salt = [];
} }
newHashPromise = Promise.resolve([]); newHashPromise = Promise.resolve([]);
} }
if(typeof settings.email === 'string') { if(typeof settings.email === 'string') {
params.new_settings.flags |= 2;
params.new_settings.email = settings.email || ''; params.new_settings.email = settings.email || '';
} }

File diff suppressed because one or more lines are too long

View File

@ -1,12 +1,9 @@
import {bigint, bigStringInt, bytesCmp, bytesToHex, isObject} from '../bin_utils'; import { bigint, bigStringInt, bytesToHex, isObject } from '../bin_utils';
import Schema from './schema';
/// #if MTPROTO_WORKER /// #if MTPROTO_WORKER
// @ts-ignore // @ts-ignore
import {gzipUncompress} from '../crypto/crypto_utils'; import { gzipUncompress } from '../crypto/crypto_utils';
/// #else import Schema, { MTProtoConstructor } from './schema';
// @ts-ignore
import {gzipUncompress} from '../bin_utils';
/// #endif /// #endif
const boolFalse = +Schema.API.constructors.find(c => c.predicate == 'boolFalse').id >>> 0; const boolFalse = +Schema.API.constructors.find(c => c.predicate == 'boolFalse').id >>> 0;
@ -91,13 +88,16 @@ class TLSerialization {
public writeInt(i: number, field: string) { public writeInt(i: number, field: string) {
this.debug && console.log('>>>', i.toString(16), i, field); this.debug && console.log('>>>', i.toString(16), i, field);
const offset = this.offset / 4;
this.checkLength(4); this.checkLength(4);
this.intView[this.offset / 4] = i; this.intView[offset] = i;
this.offset += 4; this.offset += 4;
return offset;
} }
public storeInt(i: number, field?: string) { public storeInt(i: number, field?: string) {
this.writeInt(i, (field || '') + ':int'); return this.writeInt(i, (field || '') + ':int');
} }
public storeBool(i: boolean, field?: string) { public storeBool(i: boolean, field?: string) {
@ -234,42 +234,51 @@ class TLSerialization {
} }
public storeMethod(methodName: string, params: any) { public storeMethod(methodName: string, params: any) {
var schema = this.mtproto ? Schema.MTProto : Schema.API; const schema = this.mtproto ? Schema.MTProto : Schema.API;
var methodData: any = false, const methodData = schema.methods.find(m => m.method == methodName);
i;
for(i = 0; i < schema.methods.length; i++) {
if(schema.methods[i].method == methodName) {
methodData = schema.methods[i];
break;
}
}
if(!methodData) { if(!methodData) {
throw new Error('No method ' + methodName + ' found'); throw new Error('No method ' + methodName + ' found');
} }
this.storeInt(methodData.id, methodName + '[id]'); this.storeInt(methodData.id, methodName + '[id]');
var param, type; const pFlags = params.pFlags;
var i, condType; const flagsOffsets: {[paramName: string]: number} = {};
var fieldBit;
var len = methodData.params.length;
//console.log('storeMethod', len, methodData); //console.log('storeMethod', len, methodData);
for(i = 0; i < len; i++) { for(const param of methodData.params) {
param = methodData.params[i]; let type = param.type;
type = param.type;
if(type.indexOf('?') !== -1) { if(type.indexOf('?') !== -1) {
condType = type.split('?'); const condType = type.split('?');
fieldBit = condType[0].split('.'); const fieldBit = condType[0].split('.');
if(!(params[fieldBit[0]] & (1 << fieldBit[1]))) {
continue; if(!(params[fieldBit[0]] & (1 << +fieldBit[1]))) {
if((condType[1] === 'true' && pFlags && pFlags[param.name]) || params[param.name] !== undefined) {
//console.log('storeMethod autocompleting', methodName, param.name, params[param.name], type);
params[fieldBit[0]] |= 1 << +fieldBit[1];
} else {
continue;
}
} }
//console.log('storeMethod', methodName, fieldBit, params[fieldBit[0]], params, param, condType, !!(params[fieldBit[0]] & (1 << +fieldBit[1])));
type = condType[1]; type = condType[1];
} }
this.storeObject(params[param.name], type, methodName + '[' + param.name + ']'); //console.log('storeMethod', methodName, param.name, params[param.name], type);
const result = this.storeObject(params[param.name], type, methodName + '[' + param.name + ']');
if(type == '#') {
params[param.name] = params[param.name] || 0;
flagsOffsets[param.name] = result as number;
}
} }
for(let paramName in flagsOffsets) {
this.intView[flagsOffsets[paramName]] = params[paramName];
}
return methodData.type; return methodData.type;
} }
@ -277,6 +286,7 @@ class TLSerialization {
//console.log('storeObject', obj, type, field, this.offset, this.getBytes(true).hex); //console.log('storeObject', obj, type, field, this.offset, this.getBytes(true).hex);
switch(type) { switch(type) {
case '#': case '#':
obj = obj || 0;
case 'int': case 'int':
return this.storeInt(obj, field); return this.storeInt(obj, field);
case 'long': case 'long':
@ -321,21 +331,15 @@ class TLSerialization {
throw new Error('Invalid object for type ' + type); throw new Error('Invalid object for type ' + type);
} }
var schema = this.mtproto ? Schema.MTProto : Schema.API; const schema = this.mtproto ? Schema.MTProto : Schema.API;
var predicate = obj['_']; const predicate = obj['_'];
var isBare = false; let isBare = false;
var constructorData: any = false; const constructorData: MTProtoConstructor = schema.constructors.find(c => c.predicate == predicate);
if(isBare = (type.charAt(0) == '%')) { if(isBare = (type.charAt(0) == '%')) {
type = type.substr(1); type = type.substr(1);
} }
for(i = 0; i < schema.constructors.length; i++) {
if(schema.constructors[i].predicate == predicate) {
constructorData = schema.constructors[i];
break;
}
}
if(!constructorData) { if(!constructorData) {
throw new Error('No predicate ' + predicate + ' found'); throw new Error('No predicate ' + predicate + ' found');
} }
@ -347,29 +351,43 @@ class TLSerialization {
if(!isBare) { if(!isBare) {
this.writeInt(constructorData.id, field + '[' + predicate + '][id]'); this.writeInt(constructorData.id, field + '[' + predicate + '][id]');
} }
var param, type: string; const pFlags = obj.pFlags;
var condType; const flagsOffsets: {[paramName: string]: number} = {};
var fieldBit;
var len = constructorData.params.length;
//console.log('storeObject', len, constructorData); //console.log('storeObject', len, constructorData);
for(i = 0; i < len; i++) { for(const param of constructorData.params) {
param = constructorData.params[i]; let type = param.type;
type = param.type;
//console.log('storeObject', param, type); //console.log('storeObject', param, type);
if(type.indexOf('?') !== -1) { if(type.indexOf('?') !== -1) {
condType = type.split('?'); const condType = type.split('?');
fieldBit = condType[0].split('.'); const fieldBit = condType[0].split('.');
//console.log('storeObject fieldBit', fieldBit, obj[fieldBit[0]]); //console.log('storeObject fieldBit', fieldBit, obj[fieldBit[0]]);
if(!(obj[fieldBit[0]] & (1 << +fieldBit[1]))) { if(!(obj[fieldBit[0]] & (1 << +fieldBit[1]))) {
continue; if((condType[1] === 'true' && pFlags && pFlags[param.name]) || obj[param.name] !== undefined) {
//console.log('storeObject autocompleting', param.name, obj[param.name], type);
obj[fieldBit[0]] |= 1 << +fieldBit[1];
} else {
continue;
}
} }
type = condType[1]; type = condType[1];
} }
//console.log('storeObject', param, type); //console.log('storeObject', param, type);
this.storeObject(obj[param.name], type, field + '[' + predicate + '][' + param.name + ']'); const result = this.storeObject(obj[param.name], type, field + '[' + predicate + '][' + param.name + ']');
if(type == '#') {
obj[param.name] = obj[param.name] || 0;
flagsOffsets[param.name] = result as number;
}
}
for(let paramName in flagsOffsets) {
this.intView[flagsOffsets[paramName]] = obj[paramName];
} }
return constructorData.type; return constructorData.type;
@ -767,4 +785,5 @@ class TLDeserialization {
} }
} }
export {TLDeserialization, TLSerialization}; export { TLDeserialization, TLSerialization };

View File

@ -359,15 +359,15 @@ export function whichChild(elem: Node) {
return i; return i;
}; };
export function copy(obj: any) { export function copy<T>(obj: T): T {
//in case of premitives //in case of premitives
if(obj===null || typeof obj !== "object"){ if(obj === null || typeof(obj) !== "object") {
return obj; return obj;
} }
//date objects should be //date objects should be
if(obj instanceof Date){ if(obj instanceof Date) {
return new Date(obj.getTime()); return new Date(obj.getTime()) as any;
} }
//handle Array //handle Array
@ -380,6 +380,7 @@ export function copy(obj: any) {
} }
//lastly, handle objects //lastly, handle objects
// @ts-ignore
let clonedObj = new obj.constructor(); let clonedObj = new obj.constructor();
for(var prop in obj){ for(var prop in obj){
if(obj.hasOwnProperty(prop)){ if(obj.hasOwnProperty(prop)){

View File

@ -1,14 +1,14 @@
import pageSignIn from './pageSignIn'; import mediaSizes from '../helpers/mediaSizes';
import pageSignUp from './pageSignUp';
import pageIm from './pageIm';
import pagePassword from './pagePassword';
import LottieLoader, { RLottiePlayer } from '../lib/lottieLoader'; import LottieLoader, { RLottiePlayer } from '../lib/lottieLoader';
//import CryptoWorker from '../lib/crypto/cryptoworker'; //import CryptoWorker from '../lib/crypto/cryptoworker';
//import apiManager from '../lib/mtproto/apiManager'; //import apiManager from '../lib/mtproto/apiManager';
import apiManager from '../lib/mtproto/mtprotoworker'; import apiManager from '../lib/mtproto/mtprotoworker';
import Page from './page';
import { App } from '../lib/mtproto/mtproto_config'; import { App } from '../lib/mtproto/mtproto_config';
import mediaSizes from '../helpers/mediaSizes'; import Page from './page';
import pageIm from './pageIm';
import pagePassword from './pagePassword';
import pageSignIn from './pageSignIn';
import pageSignUp from './pageSignUp';
let authCode: { let authCode: {
_: string, // 'auth.sentCode' _: string, // 'auth.sentCode'
@ -53,13 +53,11 @@ let onFirstMount = (): Promise<any> => {
codeInput.setAttribute('disabled', 'true'); codeInput.setAttribute('disabled', 'true');
changePhonePromise = apiManager.invokeApi('auth.sendCode', { changePhonePromise = apiManager.invokeApi('auth.sendCode', {
/* flags: 0, */
phone_number: phone_number, phone_number: phone_number,
api_id: App.id, api_id: App.id,
api_hash: App.hash, api_hash: App.hash,
settings: { settings: {
_: 'codeSettings', // that's how we sending Type _: 'codeSettings' // that's how we sending Type
flags: 0
} }
/* lang_code: navigator.language || 'en' */ /* lang_code: navigator.language || 'en' */
}).then((code: any) => { }).then((code: any) => {

View File

@ -1,14 +1,14 @@
import { putPreloader, formatPhoneNumber } from "../components/misc"; import { formatPhoneNumber, putPreloader } from "../components/misc";
import Scrollable from '../components/scrollable'; import Scrollable from '../components/scrollable';
import {RichTextProcessor} from '../lib/richtextprocessor';
import Config from '../lib/config'; import Config from '../lib/config';
import apiManager from "../lib/mtproto/mtprotoworker";
import { App, Modes } from "../lib/mtproto/mtproto_config";
import { RichTextProcessor } from '../lib/richtextprocessor';
import { findUpTag } from "../lib/utils"; import { findUpTag } from "../lib/utils";
import Page from "./page";
import pageAuthCode from "./pageAuthCode"; import pageAuthCode from "./pageAuthCode";
import pageSignQR from './pageSignQR'; import pageSignQR from './pageSignQR';
import apiManager from "../lib/mtproto/mtprotoworker";
import Page from "./page";
import { App, Modes } from "../lib/mtproto/mtproto_config";
type Country = { type Country = {
name: string, name: string,
@ -237,13 +237,11 @@ let onFirstMount = () => {
let phone_number = telEl.value; let phone_number = telEl.value;
apiManager.invokeApi('auth.sendCode', { apiManager.invokeApi('auth.sendCode', {
//flags: 0,
phone_number: phone_number, phone_number: phone_number,
api_id: App.id, api_id: App.id,
api_hash: App.hash, api_hash: App.hash,
settings: { settings: {
_: 'codeSettings', // that's how we sending Type _: 'codeSettings' // that's how we sending Type
flags: 0
} }
//lang_code: navigator.language || 'en' //lang_code: navigator.language || 'en'
}).then((code: any) => { }).then((code: any) => {