mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-01-03 21:32:16 +00:00
layer 25 support started
This commit is contained in:
parent
200bbc47d7
commit
39acdd8725
@ -598,7 +598,6 @@ namespace App {
|
||||
switch (msg.type()) {
|
||||
case mtpc_message: msgsIds.insert(msg.c_message().vid.v, i); break;
|
||||
case mtpc_messageEmpty: msgsIds.insert(msg.c_messageEmpty().vid.v, i); break;
|
||||
case mtpc_messageForwarded: msgsIds.insert(msg.c_messageForwarded().vid.v, i); break;
|
||||
case mtpc_messageService: msgsIds.insert(msg.c_messageService().vid.v, i); break;
|
||||
}
|
||||
}
|
||||
@ -646,6 +645,20 @@ namespace App {
|
||||
}
|
||||
}
|
||||
|
||||
void feedInboxRead(const PeerId &peer, int32 upTo) {
|
||||
History *h = App::historyLoaded(peer);
|
||||
if (h) {
|
||||
h->inboxRead(upTo);
|
||||
}
|
||||
}
|
||||
|
||||
void feedOutboxRead(const PeerId &peer, int32 upTo) {
|
||||
History *h = App::historyLoaded(peer);
|
||||
if (h) {
|
||||
h->outboxRead(upTo);
|
||||
}
|
||||
}
|
||||
|
||||
void feedWereDeleted(const QVector<MTPint> &msgsIds) {
|
||||
bool resized = false;
|
||||
for (QVector<MTPint>::const_iterator i = msgsIds.cbegin(), e = msgsIds.cend(); i != e; ++i) {
|
||||
@ -683,30 +696,20 @@ namespace App {
|
||||
}
|
||||
}
|
||||
|
||||
void feedUserLink(MTPint userId, const MTPcontacts_MyLink &myLink, const MTPcontacts_ForeignLink &foreignLink) {
|
||||
void feedUserLink(MTPint userId, const MTPContactLink &myLink, const MTPContactLink &foreignLink) {
|
||||
UserData *user = userLoaded(userId.v);
|
||||
if (user) {
|
||||
bool wasContact = (user->contact > 0);
|
||||
switch (myLink.type()) {
|
||||
case mtpc_contacts_myLinkContact:
|
||||
case mtpc_contactLinkContact:
|
||||
user->contact = 1;
|
||||
break;
|
||||
case mtpc_contacts_myLinkEmpty:
|
||||
case mtpc_contacts_myLinkRequested:
|
||||
if (myLink.type() == mtpc_contacts_myLinkRequested && myLink.c_contacts_myLinkRequested().vcontact.v) {
|
||||
user->contact = 1;
|
||||
} else {
|
||||
switch (foreignLink.type()) {
|
||||
case mtpc_contacts_foreignLinkRequested:
|
||||
if (foreignLink.c_contacts_foreignLinkRequested().vhas_phone.v) {
|
||||
user->contact = 0;
|
||||
} else {
|
||||
user->contact = -1;
|
||||
}
|
||||
break;
|
||||
default: user->contact = -1; break;
|
||||
}
|
||||
}
|
||||
case mtpc_contactLinkHasPhone:
|
||||
user->contact = 0;
|
||||
break;
|
||||
case mtpc_contactLinkNone:
|
||||
case mtpc_contactLinkUnknown:
|
||||
user->contact = -1;
|
||||
break;
|
||||
}
|
||||
if (user->contact > 0) {
|
||||
@ -736,7 +739,6 @@ namespace App {
|
||||
const MTPMessageMedia *media = 0;
|
||||
switch (msg.type()) {
|
||||
case mtpc_message: media = &msg.c_message().vmedia; break;
|
||||
case mtpc_messageForwarded: media = &msg.c_messageForwarded().vmedia; break;
|
||||
}
|
||||
if (media) {
|
||||
MsgsData::iterator i = msgsData.find(msgId);
|
||||
@ -1151,8 +1153,20 @@ namespace App {
|
||||
result->thumb = thumb;
|
||||
result->dc = dc;
|
||||
result->size = size;
|
||||
} else if (result->thumb->isNull() && !thumb->isNull()) {
|
||||
result->thumb = thumb;
|
||||
} else {
|
||||
if (result->thumb->isNull() && !thumb->isNull()) {
|
||||
result->thumb = thumb;
|
||||
}
|
||||
if (result->alt.isEmpty()) {
|
||||
for (QVector<MTPDocumentAttribute>::const_iterator i = attributes.cbegin(), e = attributes.cend(); i != e; ++i) {
|
||||
if (i->type() == mtpc_documentAttributeSticker) {
|
||||
const MTPDdocumentAttributeSticker &d(i->c_documentAttributeSticker());
|
||||
if (d.valt.c_string().v.length() > 0) {
|
||||
result->alt = qs(d.valt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1213,11 +1227,14 @@ namespace App {
|
||||
return ::histories;
|
||||
}
|
||||
|
||||
History *history(const PeerId &peer, int32 unreadCnt) {
|
||||
History *history(const PeerId &peer, int32 unreadCnt, int32 maxInboxRead) {
|
||||
Histories::const_iterator i = ::histories.constFind(peer);
|
||||
if (i == ::histories.cend()) {
|
||||
i = App::histories().insert(peer, new History(peer));
|
||||
i.value()->setUnreadCount(unreadCnt, false);
|
||||
if (maxInboxRead) {
|
||||
i.value()->inboxReadTill = maxInboxRead;
|
||||
}
|
||||
}
|
||||
return i.value();
|
||||
}
|
||||
|
@ -76,9 +76,11 @@ namespace App {
|
||||
void feedParticipantDelete(const MTPDupdateChatParticipantDelete &d);
|
||||
void feedMsgs(const MTPVector<MTPMessage> &msgs, bool newMsgs = false);
|
||||
void feedWereRead(const QVector<MTPint> &msgsIds);
|
||||
void feedInboxRead(const PeerId &peer, int32 upTo);
|
||||
void feedOutboxRead(const PeerId &peer, int32 upTo);
|
||||
void feedWereDeleted(const QVector<MTPint> &msgsIds);
|
||||
void feedUserLinks(const MTPVector<MTPcontacts_Link> &links);
|
||||
void feedUserLink(MTPint userId, const MTPcontacts_MyLink &myLink, const MTPcontacts_ForeignLink &foreignLink);
|
||||
void feedUserLink(MTPint userId, const MTPContactLink &myLink, const MTPContactLink &foreignLink);
|
||||
void feedMessageMedia(MsgId msgId, const MTPMessage &msg);
|
||||
int32 maxMsgId();
|
||||
|
||||
@ -117,7 +119,7 @@ namespace App {
|
||||
MTPPhoto photoFromUserPhoto(MTPint userId, MTPint date, const MTPUserProfilePhoto &photo);
|
||||
|
||||
Histories &histories();
|
||||
History *history(const PeerId &peer, int32 unreadCnt = 0);
|
||||
History *history(const PeerId &peer, int32 unreadCnt = 0, int32 maxInboxRead = 0);
|
||||
History *historyLoaded(const PeerId &peer);
|
||||
HistoryItem *histItemById(MsgId itemId);
|
||||
HistoryItem *historyRegItem(HistoryItem *item);
|
||||
|
@ -277,7 +277,7 @@ enum {
|
||||
MaxPhotosInMemory = 50, // try to clear some memory after 50 photos are created
|
||||
NoUpdatesTimeout = 180 * 1000, // if nothing is received in 3 min we getDifference
|
||||
NoUpdatesAfterSleepTimeout = 60 * 1000, // if nothing is received in 1 min when was a sleepmode we getDifference
|
||||
WaitForSeqTimeout = 1000, // 1s wait for skipped seq in updates
|
||||
WaitForSkippedTimeout = 1000, // 1s wait for skipped seq or pts in updates
|
||||
|
||||
MemoryForImageCache = 64 * 1024 * 1024, // after 64mb of unpacked images we try to clear some memory
|
||||
NotifyWindowsCount = 3, // 3 desktop notifies at the same time
|
||||
|
@ -742,7 +742,7 @@ void DialogsListWidget::clearFilter() {
|
||||
}
|
||||
|
||||
void DialogsListWidget::addDialog(const MTPDdialog &dialog) {
|
||||
History *history = App::history(App::peerFromMTP(dialog.vpeer), dialog.vunread_count.v);
|
||||
History *history = App::history(App::peerFromMTP(dialog.vpeer), dialog.vunread_count.v, dialog.vread_inbox_max_id.v);
|
||||
History::DialogLinks links = dialogs.addToEnd(history);
|
||||
history->dialogs = links;
|
||||
contactsNoDialogs.del(history->peer);
|
||||
|
@ -749,7 +749,11 @@ void DocumentData::setattributes(const QVector<MTPDocumentAttribute> &attributes
|
||||
dimensions = QSize(d.vw.v, d.vh.v);
|
||||
} break;
|
||||
case mtpc_documentAttributeAnimated: if (type == FileDocument || type == StickerDocument) type = AnimatedDocument; break;
|
||||
case mtpc_documentAttributeSticker: if (type == FileDocument) type = StickerDocument; break;
|
||||
case mtpc_documentAttributeSticker: {
|
||||
const MTPDdocumentAttributeSticker &d(attributes[i].c_documentAttributeSticker());
|
||||
if (type == FileDocument) type = StickerDocument;
|
||||
alt = qs(d.valt);
|
||||
} break;
|
||||
case mtpc_documentAttributeVideo: {
|
||||
const MTPDdocumentAttributeVideo &d(attributes[i].c_documentAttributeVideo());
|
||||
type = VideoDocument;
|
||||
@ -1164,10 +1168,6 @@ HistoryItem *Histories::addToBack(const MTPmessage &msg, int msgState) {
|
||||
from_id = App::peerFromUser(msg.c_message().vfrom_id);
|
||||
to_id = App::peerFromMTP(msg.c_message().vto_id);
|
||||
break;
|
||||
case mtpc_messageForwarded:
|
||||
from_id = App::peerFromUser(msg.c_messageForwarded().vfrom_id);
|
||||
to_id = App::peerFromMTP(msg.c_messageForwarded().vto_id);
|
||||
break;
|
||||
case mtpc_messageService:
|
||||
from_id = App::peerFromUser(msg.c_messageService().vfrom_id);
|
||||
to_id = App::peerFromMTP(msg.c_messageService().vto_id);
|
||||
@ -1206,11 +1206,11 @@ HistoryItem *History::createItem(HistoryBlock *block, const MTPmessage &msg, boo
|
||||
break;
|
||||
|
||||
case mtpc_message:
|
||||
result = new HistoryMessage(this, block, msg.c_message());
|
||||
break;
|
||||
|
||||
case mtpc_messageForwarded:
|
||||
result = new HistoryForwarded(this, block, msg.c_messageForwarded());
|
||||
if (msg.c_message().has_fwd_date() || msg.c_message().has_fwd_from_id()) {
|
||||
result = new HistoryForwarded(this, block, msg.c_message());
|
||||
} else {
|
||||
result = new HistoryMessage(this, block, msg.c_message());
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_messageService: {
|
||||
@ -1615,13 +1615,13 @@ void History::addToBack(const QVector<MTPMessage> &slice) {
|
||||
}
|
||||
}
|
||||
|
||||
void History::inboxRead(HistoryItem *wasRead) {
|
||||
void History::inboxRead(int32 upTo) {
|
||||
if (unreadCount) {
|
||||
if (wasRead && loadedAtBottom()) App::main()->historyToDown(this);
|
||||
if (upTo && loadedAtBottom()) App::main()->historyToDown(this);
|
||||
setUnreadCount(0);
|
||||
}
|
||||
if (!isEmpty()) {
|
||||
int32 till = (wasRead ? wasRead : back()->back())->id;
|
||||
int32 till = upTo ? upTo : back()->back()->id;
|
||||
if (inboxReadTill < till) inboxReadTill = till;
|
||||
}
|
||||
if (!dialogs.isEmpty()) {
|
||||
@ -1631,13 +1631,21 @@ void History::inboxRead(HistoryItem *wasRead) {
|
||||
clearNotifications();
|
||||
}
|
||||
|
||||
void History::outboxRead(HistoryItem *wasRead) {
|
||||
void History::inboxRead(HistoryItem *wasRead) {
|
||||
return inboxRead(wasRead ? wasRead->id : 0);
|
||||
}
|
||||
|
||||
void History::outboxRead(int32 upTo) {
|
||||
if (!isEmpty()) {
|
||||
int32 till = wasRead->id;
|
||||
int32 till = upTo ? upTo : back()->back()->id;
|
||||
if (outboxReadTill < till) outboxReadTill = till;
|
||||
}
|
||||
}
|
||||
|
||||
void History::outboxRead(HistoryItem *wasRead) {
|
||||
return outboxRead(wasRead ? wasRead->id : 0);
|
||||
}
|
||||
|
||||
void History::setUnreadCount(int32 newUnreadCount, bool psUpdate) {
|
||||
if (unreadCount != newUnreadCount) {
|
||||
if (!unreadCount && newUnreadCount == 1 && loadedAtBottom()) {
|
||||
@ -3061,6 +3069,10 @@ HistorySticker::HistorySticker(DocumentData *document, int32 width) : HistoryMed
|
||||
}
|
||||
|
||||
bool HistorySticker::updateStickerEmoji() {
|
||||
if (!data->alt.isEmpty()) {
|
||||
_emoji = data->alt;
|
||||
return true;
|
||||
}
|
||||
const EmojiStickersMap &stickers(cEmojiStickers());
|
||||
EmojiStickersMap::const_iterator i = stickers.constFind(data);
|
||||
QString emoji = (i == stickers.cend()) ? QString() : textEmojiString(i.value());
|
||||
@ -3923,7 +3935,7 @@ HistoryMedia *HistoryImageLink::clone() const {
|
||||
}
|
||||
|
||||
HistoryMessage::HistoryMessage(History *history, HistoryBlock *block, const MTPDmessage &msg) :
|
||||
HistoryItem(history, block, msg.vid.v, (msg.vflags.v & 0x02), (msg.vflags.v & 0x01), ::date(msg.vdate), msg.vfrom_id.v)
|
||||
HistoryItem(history, block, msg.vid.v, (msg.vflags.v & MTPDmessage_flag_out), (msg.vflags.v & MTPDmessage_flag_unread), ::date(msg.vdate), msg.vfrom_id.v)
|
||||
, _text(st::msgMinWidth)
|
||||
, _textWidth(0)
|
||||
, _textHeight(0)
|
||||
@ -4357,7 +4369,7 @@ HistoryMessage::~HistoryMessage() {
|
||||
delete _media;
|
||||
}
|
||||
|
||||
HistoryForwarded::HistoryForwarded(History *history, HistoryBlock *block, const MTPDmessageForwarded &msg) : HistoryMessage(history, block, msg.vid.v, (msg.vflags.v & 0x02), (msg.vflags.v & 0x01), ::date(msg.vdate), msg.vfrom_id.v, textClean(qs(msg.vmessage)), msg.vmedia)
|
||||
HistoryForwarded::HistoryForwarded(History *history, HistoryBlock *block, const MTPDmessage &msg) : HistoryMessage(history, block, msg.vid.v, (msg.vflags.v & MTPDmessage_flag_out), (msg.vflags.v & MTPDmessage_flag_unread), ::date(msg.vdate), msg.vfrom_id.v, textClean(qs(msg.vmessage)), msg.vmedia)
|
||||
, fwdDate(::date(msg.vfwd_date))
|
||||
, fwdFrom(App::user(msg.vfwd_from_id.v))
|
||||
, fwdFromName(4096)
|
||||
@ -4602,7 +4614,7 @@ void HistoryServiceMsg::setMessageByAction(const MTPmessageAction &action) {
|
||||
}
|
||||
|
||||
HistoryServiceMsg::HistoryServiceMsg(History *history, HistoryBlock *block, const MTPDmessageService &msg) :
|
||||
HistoryItem(history, block, msg.vid.v, (msg.vflags.v & 0x02), (msg.vflags.v & 0x01), ::date(msg.vdate), msg.vfrom_id.v)
|
||||
HistoryItem(history, block, msg.vid.v, (msg.vflags.v & MTPDmessage_flag_out), (msg.vflags.v & MTPDmessage_flag_unread), ::date(msg.vdate), msg.vfrom_id.v)
|
||||
, _text(st::msgMinWidth)
|
||||
, _media(0)
|
||||
{
|
||||
|
@ -442,7 +442,7 @@ struct DocumentData {
|
||||
int32 duration;
|
||||
uint64 access;
|
||||
int32 date;
|
||||
QString name, mime;
|
||||
QString name, mime, alt; // alt - for stickers
|
||||
ImagePtr thumb;
|
||||
int32 dc;
|
||||
int32 size;
|
||||
@ -655,7 +655,9 @@ struct History : public QList<HistoryBlock*> {
|
||||
void newItemAdded(HistoryItem *item);
|
||||
void unregTyping(UserData *from);
|
||||
|
||||
void inboxRead(int32 upTo);
|
||||
void inboxRead(HistoryItem *wasRead);
|
||||
void outboxRead(int32 upTo);
|
||||
void outboxRead(HistoryItem *wasRead);
|
||||
|
||||
void setUnreadCount(int32 newUnreadCount, bool psUpdate = true);
|
||||
@ -1138,7 +1140,7 @@ public:
|
||||
return _out;
|
||||
}
|
||||
bool unread() const {
|
||||
if ((_out && (id > 0 && id < _history->outboxReadTill)) || (!_out && id > 0 && id < _history->inboxReadTill)) return false;
|
||||
if ((_out && (id > 0 && id <= _history->outboxReadTill)) || (!_out && id > 0 && id <= _history->inboxReadTill)) return false;
|
||||
return _unread;
|
||||
}
|
||||
virtual bool needCheck() const {
|
||||
@ -1620,7 +1622,7 @@ protected:
|
||||
class HistoryForwarded : public HistoryMessage {
|
||||
public:
|
||||
|
||||
HistoryForwarded(History *history, HistoryBlock *block, const MTPDmessageForwarded &msg);
|
||||
HistoryForwarded(History *history, HistoryBlock *block, const MTPDmessage &msg);
|
||||
HistoryForwarded(History *history, HistoryBlock *block, MsgId id, HistoryMessage *msg);
|
||||
|
||||
void fwdNameUpdated() const;
|
||||
|
@ -2230,10 +2230,6 @@ void HistoryWidget::messagesReceived(const MTPmessages_Messages &messages, mtpRe
|
||||
from_id = App::peerFromUser(msg.c_message().vfrom_id);
|
||||
to_id = App::peerFromMTP(msg.c_message().vto_id);
|
||||
break;
|
||||
case mtpc_messageForwarded:
|
||||
from_id = App::peerFromUser(msg.c_messageForwarded().vfrom_id);
|
||||
to_id = App::peerFromMTP(msg.c_messageForwarded().vto_id);
|
||||
break;
|
||||
case mtpc_messageService:
|
||||
from_id = App::peerFromUser(msg.c_messageService().vfrom_id);
|
||||
to_id = App::peerFromMTP(msg.c_messageService().vto_id);
|
||||
@ -2504,9 +2500,9 @@ mtpRequestId HistoryWidget::onForward(const PeerId &peer, SelectedItemSet toForw
|
||||
|
||||
MTPstring msgText(MTP_string(msg->selectedText(FullItemSel)));
|
||||
|
||||
int32 flags = (histPeer->input.type() == mtpc_inputPeerSelf) ? 0 : (0x01 | 0x02); // unread, out
|
||||
hist->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(histPeer->id), MTP_int(unixtime()), msgText, MTP_messageMediaEmpty()));
|
||||
hist->sendRequestId = MTP::send(MTPmessages_SendMessage(histPeer->input, msgText, MTP_long(randomId)), App::main()->rpcDone(&MainWidget::sentDataReceived, randomId), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
|
||||
int32 flags = (histPeer->input.type() == mtpc_inputPeerSelf) ? 0 : (MTPDmessage_flag_unread | MTPDmessage_flag_out);
|
||||
hist->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(histPeer->id), MTPint(), MTPint(), MTPint(), MTP_int(unixtime()), msgText, MTP_messageMediaEmpty()));
|
||||
hist->sendRequestId = MTP::send(MTPmessages_SendMessage(histPeer->input, MTP_int(0), msgText, MTP_long(randomId)), App::main()->rpcDone(&MainWidget::sentDataReceived, randomId), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
|
||||
}
|
||||
if (newId) {
|
||||
App::historyRegRandom(randomId, newId);
|
||||
@ -2525,11 +2521,15 @@ mtpRequestId HistoryWidget::onForward(const PeerId &peer, SelectedItemSet toForw
|
||||
App::main()->readServerHistory(hist, false);
|
||||
|
||||
QVector<MTPint> ids;
|
||||
QVector<MTPlong> randomIds;
|
||||
ids.reserve(toForward.size());
|
||||
randomIds.reserve(toForward.size());
|
||||
for (SelectedItemSet::const_iterator i = toForward.cbegin(), e = toForward.cend(); i != e; ++i) {
|
||||
ids.push_back(MTP_int(i.value()->id));
|
||||
randomIds.push_back(MTP_long(MTP::nonce<uint64>()));
|
||||
//App::historyRegRandom()
|
||||
}
|
||||
hist->sendRequestId = MTP::send(MTPmessages_ForwardMessages(toPeer->input, MTP_vector<MTPint>(ids)), App::main()->rpcDone(&MainWidget::forwardDone, peer), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
|
||||
hist->sendRequestId = MTP::send(MTPmessages_ForwardMessages(toPeer->input, MTP_vector<MTPint>(ids), MTP_vector<MTPlong>(randomIds)), App::main()->rpcDone(&MainWidget::forwardDone, peer), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
|
||||
return hist->sendRequestId;
|
||||
}
|
||||
|
||||
@ -2552,10 +2552,10 @@ void HistoryWidget::shareContact(const PeerId &peer, const QString &phone, const
|
||||
h->loadAround(0);
|
||||
|
||||
PeerData *p = App::peer(peer);
|
||||
int32 flags = (p->input.type() == mtpc_inputPeerSelf) ? 0 : (0x01 | 0x02); // unread, out
|
||||
h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(peer), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaContact(MTP_string(phone), MTP_string(fname), MTP_string(lname), MTP_int(userId))));
|
||||
int32 flags = (p->input.type() == mtpc_inputPeerSelf) ? 0 : (MTPDmessage_flag_unread | MTPDmessage_flag_out); // unread, out
|
||||
h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(peer), MTPint(), MTPint(), MTPint(), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaContact(MTP_string(phone), MTP_string(fname), MTP_string(lname), MTP_int(userId))));
|
||||
|
||||
h->sendRequestId = MTP::send(MTPmessages_SendMedia(p->input, MTP_inputMediaContact(MTP_string(phone), MTP_string(fname), MTP_string(lname)), MTP_long(randomId)), App::main()->rpcDone(&MainWidget::sentFullDataReceived, randomId), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
|
||||
h->sendRequestId = MTP::send(MTPmessages_SendMedia(p->input, MTP_int(0), MTP_inputMediaContact(MTP_string(phone), MTP_string(fname), MTP_string(lname)), MTP_long(randomId)), App::main()->rpcDone(&MainWidget::sentFullDataReceived, randomId), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
|
||||
|
||||
App::historyRegRandom(randomId, newId);
|
||||
if (hist && histPeer && peer == histPeer->id) {
|
||||
@ -3101,12 +3101,12 @@ void HistoryWidget::confirmSendImage(const ReadyLocalMedia &img) {
|
||||
History *h = App::history(img.peer);
|
||||
if (img.type == ToPreparePhoto) {
|
||||
h->loadAround(0);
|
||||
int32 flags = (h->peer->input.type() == mtpc_inputPeerSelf) ? 0 : (0x01 | 0x02); // unread, out
|
||||
h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(img.peer), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaPhoto(img.photo)));
|
||||
int32 flags = (h->peer->input.type() == mtpc_inputPeerSelf) ? 0 : (MTPDmessage_flag_unread | MTPDmessage_flag_out); // unread, out
|
||||
h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(img.peer), MTPint(), MTPint(), MTPint(), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaPhoto(img.photo)));
|
||||
} else if (img.type == ToPrepareDocument) {
|
||||
h->loadAround(0);
|
||||
int32 flags = (h->peer->input.type() == mtpc_inputPeerSelf) ? 0 : (0x01 | 0x02); // unread, out
|
||||
h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(img.peer), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaDocument(img.document)));
|
||||
int32 flags = (h->peer->input.type() == mtpc_inputPeerSelf) ? 0 : (MTPDmessage_flag_unread | MTPDmessage_flag_out); // unread, out
|
||||
h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(img.peer), MTPint(), MTPint(), MTPint(), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaDocument(img.document)));
|
||||
}
|
||||
|
||||
if (hist && histPeer && img.peer == histPeer->id) {
|
||||
@ -3132,7 +3132,7 @@ void HistoryWidget::onPhotoUploaded(MsgId newId, const MTPInputFile &file) {
|
||||
uint64 randomId = MTP::nonce<uint64>();
|
||||
App::historyRegRandom(randomId, newId);
|
||||
History *hist = item->history();
|
||||
hist->sendRequestId = MTP::send(MTPmessages_SendMedia(item->history()->peer->input, MTP_inputMediaUploadedPhoto(file), MTP_long(randomId)), App::main()->rpcDone(&MainWidget::sentFullDataReceived, randomId), App::main()->rpcFail(&MainWidget::sendPhotoFailed, randomId), 0, 0, hist->sendRequestId);
|
||||
hist->sendRequestId = MTP::send(MTPmessages_SendMedia(item->history()->peer->input, MTP_int(0), MTP_inputMediaUploadedPhoto(file), MTP_long(randomId)), App::main()->rpcDone(&MainWidget::sentFullDataReceived, randomId), App::main()->rpcFail(&MainWidget::sendPhotoFailed, randomId), 0, 0, hist->sendRequestId);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3145,7 +3145,7 @@ namespace {
|
||||
if (document->type == AnimatedDocument) {
|
||||
attributes.push_back(MTP_documentAttributeAnimated());
|
||||
} else if (document->type == StickerDocument) {
|
||||
attributes.push_back(MTP_documentAttributeSticker());
|
||||
attributes.push_back(MTP_documentAttributeSticker(MTP_string(document->alt)));
|
||||
}
|
||||
return MTP_vector<MTPDocumentAttribute>(attributes);
|
||||
}
|
||||
@ -3167,7 +3167,7 @@ void HistoryWidget::onDocumentUploaded(MsgId newId, const MTPInputFile &file) {
|
||||
uint64 randomId = MTP::nonce<uint64>();
|
||||
App::historyRegRandom(randomId, newId);
|
||||
History *hist = item->history();
|
||||
hist->sendRequestId = MTP::send(MTPmessages_SendMedia(item->history()->peer->input, MTP_inputMediaUploadedDocument(file, MTP_string(document->mime), _composeDocumentAttributes(document)), MTP_long(randomId)), App::main()->rpcDone(&MainWidget::sentFullDataReceived, randomId), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
|
||||
hist->sendRequestId = MTP::send(MTPmessages_SendMedia(item->history()->peer->input, MTP_int(0), MTP_inputMediaUploadedDocument(file, MTP_string(document->mime), _composeDocumentAttributes(document)), MTP_long(randomId)), App::main()->rpcDone(&MainWidget::sentFullDataReceived, randomId), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3188,7 +3188,7 @@ void HistoryWidget::onThumbDocumentUploaded(MsgId newId, const MTPInputFile &fil
|
||||
uint64 randomId = MTP::nonce<uint64>();
|
||||
App::historyRegRandom(randomId, newId);
|
||||
History *hist = item->history();
|
||||
hist->sendRequestId = MTP::send(MTPmessages_SendMedia(item->history()->peer->input, MTP_inputMediaUploadedThumbDocument(file, thumb, MTP_string(document->mime), _composeDocumentAttributes(document)), MTP_long(randomId)), App::main()->rpcDone(&MainWidget::sentFullDataReceived, randomId), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
|
||||
hist->sendRequestId = MTP::send(MTPmessages_SendMedia(item->history()->peer->input, MTP_int(0), MTP_inputMediaUploadedThumbDocument(file, thumb, MTP_string(document->mime), _composeDocumentAttributes(document)), MTP_long(randomId)), App::main()->rpcDone(&MainWidget::sentFullDataReceived, randomId), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3443,7 +3443,7 @@ void HistoryWidget::onStickerSend(DocumentData *sticker) {
|
||||
bool out = (histPeer->input.type() != mtpc_inputPeerSelf), unread = (histPeer->input.type() != mtpc_inputPeerSelf);
|
||||
hist->addToBackDocument(newId, out, unread, date(MTP_int(unixtime())), MTP::authedId(), sticker);
|
||||
|
||||
hist->sendRequestId = MTP::send(MTPmessages_SendMedia(histPeer->input, MTP_inputMediaDocument(MTP_inputDocument(MTP_long(sticker->id), MTP_long(sticker->access))), MTP_long(randomId)), App::main()->rpcDone(&MainWidget::sentFullDataReceived, randomId), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
|
||||
hist->sendRequestId = MTP::send(MTPmessages_SendMedia(histPeer->input, MTP_int(0), MTP_inputMediaDocument(MTP_inputDocument(MTP_long(sticker->id), MTP_long(sticker->access))), MTP_long(randomId)), App::main()->rpcDone(&MainWidget::sentFullDataReceived, randomId), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
|
||||
|
||||
App::historyRegRandom(randomId, newId);
|
||||
App::main()->historyToDown(hist);
|
||||
|
@ -186,7 +186,7 @@ void LocalImageLoaderPrivate::prepareImages() {
|
||||
if (animated) {
|
||||
attributes.push_back(MTP_documentAttributeAnimated());
|
||||
} else if (mime == stickerMime && w > 0 && h > 0 && w <= StickerMaxSize && h <= StickerMaxSize && filesize < StickerInMemory) {
|
||||
attributes.push_back(MTP_documentAttributeSticker());
|
||||
attributes.push_back(MTP_documentAttributeSticker(MTP_string("")));
|
||||
thumbFormat = "webp";
|
||||
thumbExt = qsl("webp");
|
||||
}
|
||||
|
@ -2093,14 +2093,14 @@ namespace Local {
|
||||
for (RecentStickerPack::const_iterator i = recent.cbegin(); i != recent.cend(); ++i) {
|
||||
DocumentData *doc = i->first;
|
||||
|
||||
// id + value + access + date + namelen + name + mimelen + mime + dc + size + width + height + type
|
||||
size += sizeof(quint64) + sizeof(qint16) + sizeof(quint64) + sizeof(qint32) + _stringSize(doc->name) + _stringSize(doc->mime) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32);
|
||||
// id + value + access + date + namelen + name + mimelen + mime + dc + size + width + height + type + alt
|
||||
size += sizeof(quint64) + sizeof(qint16) + sizeof(quint64) + sizeof(qint32) + _stringSize(doc->name) + _stringSize(doc->mime) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + _stringSize(doc->alt);
|
||||
}
|
||||
EncryptedDescriptor data(size);
|
||||
for (RecentStickerPack::const_iterator i = recent.cbegin(); i != recent.cend(); ++i) {
|
||||
DocumentData *doc = i->first;
|
||||
|
||||
data.stream << quint64(doc->id) << qint16(i->second) << quint64(doc->access) << qint32(doc->date) << doc->name << doc->mime << qint32(doc->dc) << qint32(doc->size) << qint32(doc->dimensions.width()) << qint32(doc->dimensions.height()) << qint32(doc->type);
|
||||
data.stream << quint64(doc->id) << qint16(i->second) << quint64(doc->access) << qint32(doc->date) << doc->name << doc->mime << qint32(doc->dc) << qint32(doc->size) << qint32(doc->dimensions.width()) << qint32(doc->dimensions.height()) << qint32(doc->type) << doc->alt;
|
||||
}
|
||||
FileWriteDescriptor file(_recentStickersKey);
|
||||
file.writeEncrypted(data);
|
||||
@ -2122,10 +2122,13 @@ namespace Local {
|
||||
RecentStickerPack recent;
|
||||
while (!stickers.stream.atEnd()) {
|
||||
quint64 id, access;
|
||||
QString name, mime;
|
||||
QString name, mime, alt;
|
||||
qint32 date, dc, size, width, height, type;
|
||||
qint16 value;
|
||||
stickers.stream >> id >> value >> access >> date >> name >> mime >> dc >> size >> width >> height >> type;
|
||||
if (stickers.version >= AppVersion) {
|
||||
stickers.stream >> alt;
|
||||
}
|
||||
if (read.contains(id)) continue;
|
||||
read.insert(id, true);
|
||||
|
||||
@ -2134,7 +2137,7 @@ namespace Local {
|
||||
if (type == AnimatedDocument) {
|
||||
attributes.push_back(MTP_documentAttributeAnimated());
|
||||
} else if (type == StickerDocument) {
|
||||
attributes.push_back(MTP_documentAttributeSticker());
|
||||
attributes.push_back(MTP_documentAttributeSticker(MTP_string(alt)));
|
||||
}
|
||||
if (width > 0 && height > 0) {
|
||||
attributes.push_back(MTP_documentAttributeImageSize(MTP_int(width), MTP_int(height)));
|
||||
|
@ -350,7 +350,7 @@ MainWidget *TopBarWidget::main() {
|
||||
|
||||
MainWidget::MainWidget(Window *window) : QWidget(window), _started(0), failedObjId(0), _dialogsWidth(st::dlgMinWidth),
|
||||
dialogs(this), history(this), profile(0), overview(0), _topBar(this), _forwardConfirm(0), hider(0), _mediaType(this), _mediaTypeMask(0),
|
||||
updPts(0), updDate(0), updQts(-1), updSeq(0), updInited(false), _onlineRequest(0), _lastWasOnline(false), _lastSetOnline(0), _isIdle(false),
|
||||
updGoodPts(0), updLastPts(0), updPtsCount(0), updDate(0), updQts(-1), updSeq(0), updInited(false), _onlineRequest(0), _lastWasOnline(false), _lastSetOnline(0), _isIdle(false),
|
||||
_failDifferenceTimeout(1), _lastUpdateTime(0), _cachedX(0), _cachedY(0), _background(0) {
|
||||
setGeometry(QRect(0, st::titleHeight, App::wnd()->width(), App::wnd()->height() - st::titleHeight));
|
||||
|
||||
@ -366,6 +366,7 @@ _failDifferenceTimeout(1), _lastUpdateTime(0), _cachedX(0), _cachedY(0), _backgr
|
||||
connect(&_onlineUpdater, SIGNAL(timeout()), this, SLOT(updateOnlineDisplay()));
|
||||
connect(&_idleFinishTimer, SIGNAL(timeout()), this, SLOT(checkIdleFinish()));
|
||||
connect(&_bySeqTimer, SIGNAL(timeout()), this, SLOT(getDifference()));
|
||||
connect(&_byPtsTimer, SIGNAL(timeout()), this, SLOT(getDifference()));
|
||||
connect(&_failDifferenceTimer, SIGNAL(timeout()), this, SLOT(getDifferenceForce()));
|
||||
connect(this, SIGNAL(peerUpdated(PeerData*)), &history, SLOT(peerUpdated(PeerData*)));
|
||||
connect(&_topBar, SIGNAL(clicked()), this, SLOT(onTopBarClick()));
|
||||
@ -570,7 +571,7 @@ void MainWidget::deleteHistory(PeerData *peer, const MTPmessages_StatedMessage &
|
||||
|
||||
void MainWidget::deleteHistoryPart(PeerData *peer, const MTPmessages_AffectedHistory &result) {
|
||||
const MTPDmessages_affectedHistory &d(result.c_messages_affectedHistory());
|
||||
App::main()->updUpdated(d.vpts.v, d.vseq.v);
|
||||
updPtsUpdated(d.vpts.v, d.vpts_count.v);
|
||||
|
||||
int32 offset = d.voffset.v;
|
||||
if (!MTP::authedId() || offset <= 0) return;
|
||||
@ -788,9 +789,9 @@ void MainWidget::sendPreparedText(History *hist, const QString &text) {
|
||||
App::historyRegRandom(randomId, newId);
|
||||
|
||||
MTPstring msgText(MTP_string(sendingText));
|
||||
int32 flags = (hist->peer->input.type() == mtpc_inputPeerSelf) ? 0 : (0x01 | 0x02); // unread, out
|
||||
hist->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(hist->peer->id), MTP_int(unixtime()), msgText, MTP_messageMediaEmpty()));
|
||||
hist->sendRequestId = MTP::send(MTPmessages_SendMessage(hist->peer->input, msgText, MTP_long(randomId)), App::main()->rpcDone(&MainWidget::sentDataReceived, randomId), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
|
||||
int32 flags = (hist->peer->input.type() == mtpc_inputPeerSelf) ? 0 : (MTPDmessage_flag_unread | MTPDmessage_flag_out), replyToMsgId = 0;
|
||||
hist->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(hist->peer->id), MTPint(), MTPint(), MTPint(), MTP_int(unixtime()), msgText, MTP_messageMediaEmpty()));
|
||||
hist->sendRequestId = MTP::send(MTPmessages_SendMessage(hist->peer->input, MTP_int(replyToMsgId), msgText, MTP_long(randomId)), App::main()->rpcDone(&MainWidget::sentDataReceived, randomId), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
|
||||
}
|
||||
|
||||
historyToDown(hist);
|
||||
@ -811,7 +812,7 @@ void MainWidget::readServerHistory(History *hist, bool force) {
|
||||
ReadRequests::const_iterator i = _readRequests.constFind(hist->peer);
|
||||
if (i == _readRequests.cend()) {
|
||||
hist->inboxRead(0);
|
||||
_readRequests.insert(hist->peer, MTP::send(MTPmessages_ReadHistory(hist->peer->input, MTP_int(0), MTP_int(0), MTP_bool(true)), rpcDone(&MainWidget::partWasRead, hist->peer)));
|
||||
_readRequests.insert(hist->peer, MTP::send(MTPmessages_ReadHistory(hist->peer->input, MTP_int(0), MTP_int(0)), rpcDone(&MainWidget::partWasRead, hist->peer)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1075,13 +1076,13 @@ void MainWidget::photosLoaded(History *h, const MTPmessages_Messages &msgs, mtpR
|
||||
|
||||
void MainWidget::partWasRead(PeerData *peer, const MTPmessages_AffectedHistory &result) {
|
||||
const MTPDmessages_affectedHistory &d(result.c_messages_affectedHistory());
|
||||
App::main()->updUpdated(d.vpts.v, d.vseq.v);
|
||||
updPtsUpdated(d.vpts.v, d.vpts_count.v);
|
||||
|
||||
int32 offset = d.voffset.v;
|
||||
if (!MTP::authedId() || offset <= 0) {
|
||||
_readRequests.remove(peer);
|
||||
} else {
|
||||
_readRequests[peer] = MTP::send(MTPmessages_ReadHistory(peer->input, MTP_int(0), MTP_int(offset), MTP_bool(true)), rpcDone(&MainWidget::partWasRead, peer));
|
||||
_readRequests[peer] = MTP::send(MTPmessages_ReadHistory(peer->input, MTP_int(0), MTP_int(offset)), rpcDone(&MainWidget::partWasRead, peer));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1286,11 +1287,11 @@ void MainWidget::dialogsCancelled() {
|
||||
}
|
||||
|
||||
void MainWidget::serviceNotification(const QString &msg, const MTPMessageMedia &media, bool unread) {
|
||||
int32 flags = unread ? 0x01 : 0; // unread
|
||||
int32 flags = unread ? MTPDmessage_flag_unread : 0;
|
||||
QString sendingText, leftText = msg;
|
||||
HistoryItem *item = 0;
|
||||
while (textSplit(sendingText, leftText, MaxMessageSize)) {
|
||||
item = App::histories().addToBack(MTP_message(MTP_int(flags), MTP_int(clientMsgId()), MTP_int(ServiceUserId), MTP_peerUser(MTP_int(MTP::authedId())), MTP_int(unixtime()), MTP_string(sendingText), media), unread ? 1 : 2);
|
||||
item = App::histories().addToBack(MTP_message(MTP_int(flags), MTP_int(clientMsgId()), MTP_int(ServiceUserId), MTP_peerUser(MTP_int(MTP::authedId())), MTPint(), MTPint(), MTPint(), MTP_int(unixtime()), MTP_string(sendingText), media), unread ? 1 : 2);
|
||||
}
|
||||
if (item) {
|
||||
history.peerMessagesUpdated(item->history()->peer->id);
|
||||
@ -1694,15 +1695,11 @@ void MainWidget::sentDataReceived(uint64 randomId, const MTPmessages_SentMessage
|
||||
|
||||
if (randomId) feedUpdate(MTP_updateMessageID(d.vid, MTP_long(randomId))); // ignore real date
|
||||
|
||||
if (updInited && d.vseq.v) {
|
||||
if (d.vseq.v <= updSeq) return;
|
||||
if (d.vseq.v > updSeq + 1) {
|
||||
_bySeqSentMessage.insert(d.vseq.v, result);
|
||||
return _bySeqTimer.start(WaitForSeqTimeout);
|
||||
}
|
||||
}
|
||||
if (updInited) {
|
||||
updSetState(d.vpts.v, d.vdate.v, updQts, d.vseq.v);
|
||||
if (!updPtsUpdated(d.vpts.v, d.vpts_count.v)) {
|
||||
_byPtsSentMessage.insert(ptsKey(SkippedSentMessage), result);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
@ -1711,17 +1708,12 @@ void MainWidget::sentDataReceived(uint64 randomId, const MTPmessages_SentMessage
|
||||
|
||||
if (randomId) feedUpdate(MTP_updateMessageID(d.vid, MTP_long(randomId))); // ignore real date
|
||||
|
||||
if (updInited && d.vseq.v) {
|
||||
if (d.vseq.v <= updSeq) return;
|
||||
if (d.vseq.v > updSeq + 1) {
|
||||
_bySeqSentMessage.insert(d.vseq.v, result);
|
||||
return _bySeqTimer.start(WaitForSeqTimeout);
|
||||
if (updInited) {
|
||||
if (!updPtsUpdated(d.vpts.v, d.vpts_count.v)) {
|
||||
_byPtsSentMessage.insert(ptsKey(SkippedSentMessage), result);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (updInited) {
|
||||
updSetState(d.vpts.v, d.vdate.v, updQts, d.vseq.v);
|
||||
}
|
||||
|
||||
App::feedUserLinks(d.vlinks);
|
||||
} break;
|
||||
};
|
||||
@ -1739,7 +1731,6 @@ void MainWidget::sentFullDataReceived(uint64 randomId, const MTPmessages_StatedM
|
||||
switch (msg->type()) {
|
||||
case mtpc_message: msgId = msg->c_message().vid.v; break;
|
||||
case mtpc_messageEmpty: msgId = msg->c_messageEmpty().vid.v; break;
|
||||
case mtpc_messageForwarded: msgId = msg->c_messageForwarded().vid.v; break;
|
||||
case mtpc_messageService: msgId = msg->c_messageService().vid.v; break;
|
||||
}
|
||||
if (msgId) {
|
||||
@ -1757,18 +1748,14 @@ void MainWidget::sentFullDataReceived(uint64 randomId, const MTPmessages_StatedM
|
||||
if (msg && msgId) {
|
||||
App::feedMessageMedia(msgId, *msg);
|
||||
}
|
||||
if (updInited && d.vseq.v) {
|
||||
if (d.vseq.v <= updSeq) return;
|
||||
if (d.vseq.v > updSeq + 1) {
|
||||
_bySeqStatedMessage.insert(d.vseq.v, result);
|
||||
return _bySeqTimer.start(WaitForSeqTimeout);
|
||||
if (updInited) {
|
||||
if (!updPtsUpdated(d.vpts.v, d.vpts_count.v)) {
|
||||
_byPtsStatedMessage.insert(ptsKey(SkippedStatedMessage), result);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!randomId) {
|
||||
feedUpdate(MTP_updateNewMessage(d.vmessage, d.vpts));
|
||||
}
|
||||
if (updInited) {
|
||||
updSetState(d.vpts.v, updDate, updQts, d.vseq.v);
|
||||
feedUpdate(MTP_updateNewMessage(d.vmessage, d.vpts, d.vpts_count));
|
||||
}
|
||||
} break;
|
||||
|
||||
@ -1780,20 +1767,15 @@ void MainWidget::sentFullDataReceived(uint64 randomId, const MTPmessages_StatedM
|
||||
if (msg && msgId) {
|
||||
App::feedMessageMedia(msgId, *msg);
|
||||
}
|
||||
if (updInited && d.vseq.v) {
|
||||
if (d.vseq.v <= updSeq) return;
|
||||
if (d.vseq.v > updSeq + 1) {
|
||||
_bySeqStatedMessage.insert(d.vseq.v, result);
|
||||
return _bySeqTimer.start(WaitForSeqTimeout);
|
||||
if (updInited) {
|
||||
if (!updPtsUpdated(d.vpts.v, d.vpts_count.v)) {
|
||||
_byPtsStatedMessage.insert(ptsKey(SkippedStatedMessage), result);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!randomId) {
|
||||
feedUpdate(MTP_updateNewMessage(d.vmessage, d.vpts));
|
||||
feedUpdate(MTP_updateNewMessage(d.vmessage, d.vpts, d.vpts_count));
|
||||
}
|
||||
if (updInited) {
|
||||
updSetState(d.vpts.v, updDate, updQts, d.vseq.v);
|
||||
}
|
||||
|
||||
App::feedUserLinks(d.vlinks);
|
||||
} break;
|
||||
};
|
||||
@ -1803,11 +1785,10 @@ void MainWidget::sentFullDatasReceived(const MTPmessages_StatedMessages &result)
|
||||
switch (result.type()) {
|
||||
case mtpc_messages_statedMessages: {
|
||||
const MTPDmessages_statedMessages &d(result.c_messages_statedMessages());
|
||||
if (updInited && d.vseq.v) {
|
||||
if (d.vseq.v <= updSeq) return;
|
||||
if (d.vseq.v > updSeq + 1) {
|
||||
_bySeqStatedMessages.insert(d.vseq.v, result);
|
||||
return _bySeqTimer.start(WaitForSeqTimeout);
|
||||
if (updInited) {
|
||||
if (!updPtsUpdated(d.vpts.v, d.vpts_count.v)) {
|
||||
_byPtsStatedMessages.insert(ptsKey(SkippedStatedMessages), result);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1815,20 +1796,15 @@ void MainWidget::sentFullDatasReceived(const MTPmessages_StatedMessages &result)
|
||||
App::feedChats(d.vchats);
|
||||
App::feedMsgs(d.vmessages, true);
|
||||
history.peerMessagesUpdated();
|
||||
|
||||
if (updInited) {
|
||||
updSetState(d.vpts.v, updDate, updQts, d.vseq.v);
|
||||
}
|
||||
} break;
|
||||
|
||||
case mtpc_messages_statedMessagesLinks: {
|
||||
const MTPDmessages_statedMessagesLinks &d(result.c_messages_statedMessagesLinks());
|
||||
|
||||
if (updInited && d.vseq.v) {
|
||||
if (d.vseq.v <= updSeq) return;
|
||||
if (d.vseq.v > updSeq + 1) {
|
||||
_bySeqStatedMessages.insert(d.vseq.v, result);
|
||||
return _bySeqTimer.start(WaitForSeqTimeout);
|
||||
if (updInited) {
|
||||
if (!updPtsUpdated(d.vpts.v, d.vpts_count.v)) {
|
||||
_byPtsStatedMessages.insert(ptsKey(SkippedStatedMessages), result);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1836,9 +1812,6 @@ void MainWidget::sentFullDatasReceived(const MTPmessages_StatedMessages &result)
|
||||
App::feedChats(d.vchats);
|
||||
App::feedMsgs(d.vmessages, true);
|
||||
history.peerMessagesUpdated();
|
||||
if (updInited) {
|
||||
updSetState(d.vpts.v, updDate, updQts, d.vseq.v);
|
||||
}
|
||||
|
||||
App::feedUserLinks(d.vlinks);
|
||||
} break;
|
||||
@ -2133,7 +2106,7 @@ bool MainWidget::updateFail(const RPCError &e) {
|
||||
}
|
||||
|
||||
void MainWidget::updSetState(int32 pts, int32 date, int32 qts, int32 seq) {
|
||||
if (updPts < pts) updPts = pts;
|
||||
if (pts) updGoodPts = updLastPts = updPtsCount = pts;
|
||||
if (updDate < date) updDate = date;
|
||||
if (qts && updQts < qts) {
|
||||
updQts = qts;
|
||||
@ -2150,59 +2123,7 @@ void MainWidget::updSetState(int32 pts, int32 date, int32 qts, int32 seq) {
|
||||
return handleUpdates(v);
|
||||
}
|
||||
} else {
|
||||
if (!_bySeqTimer.isActive()) _bySeqTimer.start(WaitForSeqTimeout);
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (QMap<int32, MTPmessages_SentMessage>::iterator i = _bySeqSentMessage.begin(); i != _bySeqSentMessage.end();) {
|
||||
int32 s = i.key();
|
||||
if (s <= seq + 1) {
|
||||
MTPmessages_SentMessage v = i.value();
|
||||
i = _bySeqSentMessage.erase(i);
|
||||
if (s == seq + 1) {
|
||||
return sentDataReceived(0, v);
|
||||
}
|
||||
} else {
|
||||
if (!_bySeqTimer.isActive()) _bySeqTimer.start(WaitForSeqTimeout);
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (QMap<int32, MTPmessages_StatedMessage>::iterator i = _bySeqStatedMessage.begin(); i != _bySeqStatedMessage.end();) {
|
||||
int32 s = i.key();
|
||||
if (s <= seq + 1) {
|
||||
MTPmessages_StatedMessage v = i.value();
|
||||
i = _bySeqStatedMessage.erase(i);
|
||||
if (s == seq + 1) {
|
||||
return sentFullDataReceived(0, v);
|
||||
}
|
||||
} else {
|
||||
if (!_bySeqTimer.isActive()) _bySeqTimer.start(WaitForSeqTimeout);
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (QMap<int32, MTPmessages_StatedMessages>::iterator i = _bySeqStatedMessages.begin(); i != _bySeqStatedMessages.end();) {
|
||||
int32 s = i.key();
|
||||
if (s <= seq + 1) {
|
||||
MTPmessages_StatedMessages v = i.value();
|
||||
i = _bySeqStatedMessages.erase(i);
|
||||
if (s == seq + 1) {
|
||||
return sentFullDatasReceived(v);
|
||||
}
|
||||
} else {
|
||||
if (!_bySeqTimer.isActive()) _bySeqTimer.start(WaitForSeqTimeout);
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (QMap<int32, int32>::iterator i = _bySeqPart.begin(); i != _bySeqPart.end();) {
|
||||
int32 s = i.key();
|
||||
if (s <= seq + 1) {
|
||||
int32 v = i.value();
|
||||
i = _bySeqPart.erase(i);
|
||||
if (s == seq + 1) {
|
||||
return updUpdated(v, s);
|
||||
}
|
||||
} else {
|
||||
if (!_bySeqTimer.isActive()) _bySeqTimer.start(WaitForSeqTimeout);
|
||||
if (!_bySeqTimer.isActive()) _bySeqTimer.start(WaitForSkippedTimeout);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -2228,7 +2149,7 @@ void MainWidget::gotDifference(const MTPupdates_Difference &diff) {
|
||||
switch (diff.type()) {
|
||||
case mtpc_updates_differenceEmpty: {
|
||||
const MTPDupdates_differenceEmpty &d(diff.c_updates_differenceEmpty());
|
||||
updSetState(updPts, d.vdate.v, updQts, d.vseq.v);
|
||||
updSetState(updGoodPts, d.vdate.v, updQts, d.vseq.v);
|
||||
|
||||
MTP::setGlobalDoneHandler(rpcDone(&MainWidget::updateReceived));
|
||||
_lastUpdateTime = getms(true);
|
||||
@ -2256,13 +2177,49 @@ void MainWidget::gotDifference(const MTPupdates_Difference &diff) {
|
||||
};
|
||||
}
|
||||
|
||||
void MainWidget::updUpdated(int32 pts, int32 seq) {
|
||||
if (!updInited) return;
|
||||
if (seq && (seq < updSeq || seq > updSeq + 1)) {
|
||||
_bySeqPart.insert(seq, pts);
|
||||
return _bySeqTimer.start(WaitForSeqTimeout);
|
||||
uint64 MainWidget::ptsKey(PtsSkippedQueue queue) {
|
||||
return _byPtsQueue.insert(uint64(uint32(updLastPts)) << 32 | uint64(uint32(updPtsCount)), queue).key();
|
||||
}
|
||||
|
||||
void MainWidget::applySkippedPtsUpdates() {
|
||||
if (_byPtsTimer.isActive()) _byPtsTimer.stop();
|
||||
if (_byPtsQueue.isEmpty()) return;
|
||||
for (QMap<uint64, PtsSkippedQueue>::const_iterator i = _byPtsQueue.cbegin(), e = _byPtsQueue.cend(); i != e; ++i) {
|
||||
switch (i.value()) {
|
||||
case SkippedUpdate: feedUpdate(_byPtsUpdate.value(i.key())); break;
|
||||
case SkippedUpdates: handleUpdates(_byPtsUpdates.value(i.key())); break;
|
||||
case SkippedSentMessage: sentDataReceived(0, _byPtsSentMessage.value(i.key())); break;
|
||||
case SkippedStatedMessage: sentFullDataReceived(0, _byPtsStatedMessage.value(i.key())); break;
|
||||
case SkippedStatedMessages: sentFullDatasReceived(_byPtsStatedMessages.value(i.key())); break;
|
||||
}
|
||||
}
|
||||
updSetState(pts, 0, 0, seq);
|
||||
clearSkippedPtsUpdates();
|
||||
}
|
||||
|
||||
void MainWidget::clearSkippedPtsUpdates() {
|
||||
_byPtsQueue.clear();
|
||||
_byPtsUpdate.clear();
|
||||
_byPtsUpdates.clear();
|
||||
_byPtsSentMessage.clear();
|
||||
_byPtsStatedMessage.clear();
|
||||
_byPtsStatedMessages.clear();
|
||||
}
|
||||
|
||||
bool MainWidget::updPtsUpdated(int pts, int ptsCount) { // return false if need to save that update and apply later
|
||||
if (!updInited) return true;
|
||||
|
||||
updLastPts = qMax(updLastPts, pts);
|
||||
updPtsCount += ptsCount;
|
||||
if (updLastPts == updPtsCount) {
|
||||
applySkippedPtsUpdates();
|
||||
updGoodPts = updLastPts;
|
||||
return true;
|
||||
} else if (updLastPts < updPtsCount) {
|
||||
_byPtsTimer.startIfNotActive(1);
|
||||
} else {
|
||||
_byPtsTimer.startIfNotActive(WaitForSkippedTimeout);
|
||||
}
|
||||
return !ptsCount;
|
||||
}
|
||||
|
||||
void MainWidget::feedDifference(const MTPVector<MTPUser> &users, const MTPVector<MTPChat> &chats, const MTPVector<MTPMessage> &msgs, const MTPVector<MTPUpdate> &other) {
|
||||
@ -2296,19 +2253,18 @@ void MainWidget::getDifference() {
|
||||
if (!updInited) return;
|
||||
|
||||
_bySeqUpdates.clear();
|
||||
_bySeqSentMessage.clear();
|
||||
_bySeqStatedMessage.clear();
|
||||
_bySeqStatedMessages.clear();
|
||||
_bySeqPart.clear();
|
||||
_bySeqTimer.stop();
|
||||
|
||||
clearSkippedPtsUpdates();
|
||||
_byPtsTimer.stop();
|
||||
|
||||
noUpdatesTimer.stop();
|
||||
_failDifferenceTimer.stop();
|
||||
|
||||
LOG(("Getting difference for %1, %2").arg(updPts).arg(updDate));
|
||||
LOG(("Getting difference for %1, %2").arg(updGoodPts).arg(updDate));
|
||||
updInited = false;
|
||||
MTP::setGlobalDoneHandler(RPCDoneHandlerPtr(0));
|
||||
MTP::send(MTPupdates_GetDifference(MTP_int(updPts), MTP_int(updDate), MTP_int(updQts)), rpcDone(&MainWidget::gotDifference), rpcFail(&MainWidget::failDifference));
|
||||
MTP::send(MTPupdates_GetDifference(MTP_int(updGoodPts), MTP_int(updDate), MTP_int(updQts)), rpcDone(&MainWidget::gotDifference), rpcFail(&MainWidget::failDifference));
|
||||
}
|
||||
|
||||
void MainWidget::start(const MTPUser &user) {
|
||||
@ -2666,7 +2622,7 @@ void MainWidget::handleUpdates(const MTPUpdates &updates) {
|
||||
if (d.vseq.v <= updSeq) return;
|
||||
if (d.vseq.v > updSeq + 1) {
|
||||
_bySeqUpdates.insert(d.vseq.v, updates);
|
||||
return _bySeqTimer.start(WaitForSeqTimeout);
|
||||
return _bySeqTimer.start(WaitForSkippedTimeout);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2674,7 +2630,7 @@ void MainWidget::handleUpdates(const MTPUpdates &updates) {
|
||||
App::feedUsers(d.vusers);
|
||||
feedUpdates(d.vupdates);
|
||||
|
||||
updSetState(updPts, d.vdate.v, updQts, d.vseq.v);
|
||||
updSetState(0, d.vdate.v, updQts, d.vseq.v);
|
||||
} break;
|
||||
|
||||
case mtpc_updatesCombined: {
|
||||
@ -2683,7 +2639,7 @@ void MainWidget::handleUpdates(const MTPUpdates &updates) {
|
||||
if (d.vseq_start.v <= updSeq) return;
|
||||
if (d.vseq_start.v > updSeq + 1) {
|
||||
_bySeqUpdates.insert(d.vseq_start.v, updates);
|
||||
return _bySeqTimer.start(WaitForSeqTimeout);
|
||||
return _bySeqTimer.start(WaitForSkippedTimeout);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2691,7 +2647,7 @@ void MainWidget::handleUpdates(const MTPUpdates &updates) {
|
||||
App::feedUsers(d.vusers);
|
||||
feedUpdates(d.vupdates);
|
||||
|
||||
updSetState(updPts, d.vdate.v, updQts, d.vseq.v);
|
||||
updSetState(0, d.vdate.v, updQts, d.vseq.v);
|
||||
} break;
|
||||
|
||||
case mtpc_updateShort: {
|
||||
@ -2699,47 +2655,41 @@ void MainWidget::handleUpdates(const MTPUpdates &updates) {
|
||||
|
||||
feedUpdate(d.vupdate);
|
||||
|
||||
updSetState(updPts, d.vdate.v, updQts, updSeq);
|
||||
updSetState(0, d.vdate.v, updQts, updSeq);
|
||||
} break;
|
||||
|
||||
case mtpc_updateShortMessage: {
|
||||
const MTPDupdateShortMessage &d(updates.c_updateShortMessage());
|
||||
if (d.vseq.v) {
|
||||
if (d.vseq.v <= updSeq) return;
|
||||
if (d.vseq.v > updSeq + 1) {
|
||||
_bySeqUpdates.insert(d.vseq.v, updates);
|
||||
return _bySeqTimer.start(WaitForSeqTimeout);
|
||||
}
|
||||
if (!updPtsUpdated(d.vpts.v, d.vpts_count.v)) {
|
||||
_byPtsUpdates.insert(ptsKey(SkippedUpdates), updates);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!App::userLoaded(d.vfrom_id.v)) return getDifference();
|
||||
int32 flags = 0x01; // unread
|
||||
HistoryItem *item = App::histories().addToBack(MTP_message(MTP_int(flags), d.vid, d.vfrom_id, MTP_peerUser(MTP_int(MTP::authedId())), d.vdate, d.vmessage, MTP_messageMediaEmpty()));
|
||||
int32 flags = MTPDmessage_flag_unread;
|
||||
HistoryItem *item = App::histories().addToBack(MTP_message(MTP_int(flags), d.vid, d.vfrom_id, MTP_peerUser(MTP_int(MTP::authedId())), MTPint(), MTPint(), MTPint(), d.vdate, d.vmessage, MTP_messageMediaEmpty()));
|
||||
if (item) {
|
||||
history.peerMessagesUpdated(item->history()->peer->id);
|
||||
}
|
||||
|
||||
updSetState(d.vpts.v, d.vdate.v, updQts, d.vseq.v);
|
||||
updSetState(0, d.vdate.v, updQts, updSeq);
|
||||
} break;
|
||||
|
||||
case mtpc_updateShortChatMessage: {
|
||||
const MTPDupdateShortChatMessage &d(updates.c_updateShortChatMessage());
|
||||
if (d.vseq.v) {
|
||||
if (d.vseq.v <= updSeq) return;
|
||||
if (d.vseq.v > updSeq + 1) {
|
||||
_bySeqUpdates.insert(d.vseq.v, updates);
|
||||
return _bySeqTimer.start(WaitForSeqTimeout);
|
||||
}
|
||||
if (!updPtsUpdated(d.vpts.v, d.vpts_count.v)) {
|
||||
_byPtsUpdates.insert(ptsKey(SkippedUpdates), updates);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!App::chatLoaded(d.vchat_id.v) || !App::userLoaded(d.vfrom_id.v)) return getDifference();
|
||||
int32 flags = 0x01; // unread
|
||||
HistoryItem *item = App::histories().addToBack(MTP_message(MTP_int(flags), d.vid, d.vfrom_id, MTP_peerChat(d.vchat_id), d.vdate, d.vmessage, MTP_messageMediaEmpty()));
|
||||
int32 flags = MTPDmessage_flag_unread; // unread
|
||||
HistoryItem *item = App::histories().addToBack(MTP_message(MTP_int(flags), d.vid, d.vfrom_id, MTP_peerChat(d.vchat_id), MTPint(), MTPint(), MTPint(), d.vdate, d.vmessage, MTP_messageMediaEmpty()));
|
||||
if (item) {
|
||||
history.peerMessagesUpdated(item->history()->peer->id);
|
||||
}
|
||||
|
||||
updSetState(d.vpts.v, d.vdate.v, updQts, d.vseq.v);
|
||||
updSetState(0, d.vdate.v, updQts, updSeq);
|
||||
} break;
|
||||
|
||||
case mtpc_updatesTooLong: {
|
||||
@ -2754,11 +2704,14 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
|
||||
switch (update.type()) {
|
||||
case mtpc_updateNewMessage: {
|
||||
const MTPDupdateNewMessage &d(update.c_updateNewMessage());
|
||||
if (!updPtsUpdated(d.vpts.v, d.vpts_count.v)) {
|
||||
_byPtsUpdate.insert(ptsKey(SkippedUpdate), update);
|
||||
return;
|
||||
}
|
||||
HistoryItem *item = App::histories().addToBack(d.vmessage);
|
||||
if (item) {
|
||||
history.peerMessagesUpdated(item->history()->peer->id);
|
||||
}
|
||||
if (updPts < d.vpts.v) updPts = d.vpts.v;
|
||||
} break;
|
||||
|
||||
case mtpc_updateMessageID: {
|
||||
@ -2799,20 +2752,41 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
|
||||
|
||||
case mtpc_updateReadMessages: {
|
||||
const MTPDupdateReadMessages &d(update.c_updateReadMessages());
|
||||
if (!updPtsUpdated(d.vpts.v, d.vpts_count.v)) {
|
||||
_byPtsUpdate.insert(ptsKey(SkippedUpdate), update);
|
||||
return;
|
||||
}
|
||||
App::feedWereRead(d.vmessages.c_vector().v);
|
||||
if (updPts < d.vpts.v) updPts = d.vpts.v;
|
||||
} break;
|
||||
|
||||
case mtpc_updateReadHistoryInbox: {
|
||||
const MTPDupdateReadHistoryInbox &d(update.c_updateReadHistoryInbox());
|
||||
if (!updPtsUpdated(d.vpts.v, d.vpts_count.v)) {
|
||||
_byPtsUpdate.insert(ptsKey(SkippedUpdate), update);
|
||||
return;
|
||||
}
|
||||
App::feedInboxRead(App::peerFromMTP(d.vpeer), d.vmax_id.v);
|
||||
} break;
|
||||
|
||||
case mtpc_updateReadHistoryOutbox: {
|
||||
const MTPDupdateReadHistoryOutbox &d(update.c_updateReadHistoryOutbox());
|
||||
if (!updPtsUpdated(d.vpts.v, d.vpts_count.v)) {
|
||||
_byPtsUpdate.insert(ptsKey(SkippedUpdate), update);
|
||||
return;
|
||||
}
|
||||
PeerId peer = App::peerFromMTP(d.vpeer);
|
||||
App::feedOutboxRead(peer, d.vmax_id.v);
|
||||
if (history.peer() && history.peer()->id == peer) history.update();
|
||||
} break;
|
||||
|
||||
case mtpc_updateDeleteMessages: {
|
||||
const MTPDupdateDeleteMessages &d(update.c_updateDeleteMessages());
|
||||
if (!updPtsUpdated(d.vpts.v, d.vpts_count.v)) {
|
||||
_byPtsUpdate.insert(ptsKey(SkippedUpdate), update);
|
||||
return;
|
||||
}
|
||||
App::feedWereDeleted(d.vmessages.c_vector().v);
|
||||
history.peerMessagesUpdated();
|
||||
if (updPts < d.vpts.v) updPts = d.vpts.v;
|
||||
} break;
|
||||
|
||||
case mtpc_updateRestoreMessages: {
|
||||
const MTPDupdateRestoreMessages &d(update.c_updateRestoreMessages());
|
||||
if (updPts < d.vpts.v) updPts = d.vpts.v;
|
||||
} break;
|
||||
|
||||
case mtpc_updateUserTyping: {
|
||||
@ -2953,19 +2927,12 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
|
||||
}
|
||||
} break;
|
||||
|
||||
case mtpc_updateActivation: {
|
||||
const MTPDupdateActivation &d(update.c_updateActivation());
|
||||
} break;
|
||||
|
||||
case mtpc_updateNewGeoChatMessage: {
|
||||
const MTPDupdateNewGeoChatMessage &d(update.c_updateNewGeoChatMessage());
|
||||
// PeerId peer = App::histories().addToBack(d.vmessage);
|
||||
// history.peerMessagesUpdated(peer);
|
||||
} break;
|
||||
|
||||
case mtpc_updateNewEncryptedMessage: {
|
||||
const MTPDupdateNewEncryptedMessage &d(update.c_updateNewEncryptedMessage());
|
||||
// if (d.vqts.v && updQts < d.vqts.v) updQts = d.vqts.v;
|
||||
} break;
|
||||
|
||||
case mtpc_updateEncryptedChatTyping: {
|
||||
|
@ -214,7 +214,6 @@ public:
|
||||
void historyToDown(History *hist);
|
||||
void dialogsToUp();
|
||||
void newUnreadMsg(History *history, MsgId msgId);
|
||||
void updUpdated(int32 pts, int32 seq);
|
||||
void historyWasRead();
|
||||
|
||||
void peerBefore(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg);
|
||||
@ -435,7 +434,8 @@ private:
|
||||
Dropdown _mediaType;
|
||||
int32 _mediaTypeMask;
|
||||
|
||||
int updPts, updDate, updQts, updSeq;
|
||||
int updGoodPts, updLastPts, updPtsCount;
|
||||
int updDate, updQts, updSeq;
|
||||
bool updInited;
|
||||
SingleTimer noUpdatesTimer;
|
||||
|
||||
@ -454,11 +454,26 @@ private:
|
||||
typedef QMap<PeerData*, mtpRequestId> OverviewsPreload;
|
||||
OverviewsPreload _overviewPreload[OverviewCount], _overviewLoad[OverviewCount];
|
||||
|
||||
enum PtsSkippedQueue {
|
||||
SkippedUpdate,
|
||||
SkippedUpdates,
|
||||
SkippedSentMessage,
|
||||
SkippedStatedMessage,
|
||||
SkippedStatedMessages
|
||||
};
|
||||
uint64 ptsKey(PtsSkippedQueue queue);
|
||||
void applySkippedPtsUpdates();
|
||||
void clearSkippedPtsUpdates();
|
||||
bool updPtsUpdated(int pts, int ptsCount);
|
||||
QMap<uint64, PtsSkippedQueue> _byPtsQueue;
|
||||
QMap<uint64, MTPUpdate> _byPtsUpdate;
|
||||
QMap<uint64, MTPUpdates> _byPtsUpdates;
|
||||
QMap<uint64, MTPmessages_SentMessage> _byPtsSentMessage;
|
||||
QMap<uint64, MTPmessages_StatedMessage> _byPtsStatedMessage;
|
||||
QMap<uint64, MTPmessages_StatedMessages> _byPtsStatedMessages;
|
||||
SingleTimer _byPtsTimer;
|
||||
|
||||
QMap<int32, MTPUpdates> _bySeqUpdates;
|
||||
QMap<int32, MTPmessages_SentMessage> _bySeqSentMessage;
|
||||
QMap<int32, MTPmessages_StatedMessage> _bySeqStatedMessage;
|
||||
QMap<int32, MTPmessages_StatedMessages> _bySeqStatedMessages;
|
||||
QMap<int32, int32> _bySeqPart;
|
||||
SingleTimer _bySeqTimer;
|
||||
|
||||
int32 _failDifferenceTimeout; // growing timeout for getDifference calls, if it fails
|
||||
|
@ -114,30 +114,40 @@ with open('scheme.tl') as f:
|
||||
|
||||
paramsList = params.strip().split(' ');
|
||||
prms = {};
|
||||
conditions = {};
|
||||
prmsList = [];
|
||||
isTemplate = '';
|
||||
isTemplate = hasFlags = '';
|
||||
for param in paramsList:
|
||||
if (re.match(r'^\s*$', param)):
|
||||
continue;
|
||||
pnametype = re.match(r'([a-z_][a-z0-9_]*):([A-Za-z0-9<>\._]+)', param);
|
||||
pnametype = re.match(r'([a-z_][a-z0-9_]*):([A-Za-z0-9<>\._]+|!X|\#|[a-z_][a-z0-9_]*\.[0-9]+\?[A-Za-z0-9<>\._]+)$', param);
|
||||
if (not pnametype):
|
||||
pnametypeX = re.match(r'([a-z_][a-z0-9_]*):!X', param);
|
||||
if (not pnametypeX or isTemplate != ''):
|
||||
print('Bad param found: "' + param + '" in line: ' + line);
|
||||
continue;
|
||||
else:
|
||||
pname = isTemplate = pnametypeX.group(1);
|
||||
ptype = 'TQueryType';
|
||||
print('Bad param found: "' + param + '" in line: ' + line);
|
||||
continue;
|
||||
pname = pnametype.group(1);
|
||||
ptypewide = pnametype.group(2);
|
||||
if (ptypewide == '!X'):
|
||||
isTemplate = pname;
|
||||
ptype = 'TQueryType';
|
||||
elif (ptypewide == '#'):
|
||||
hasFlags = pname;
|
||||
ptype = 'int';
|
||||
else:
|
||||
pname = pnametype.group(1);
|
||||
ptype = pnametype.group(2);
|
||||
if (ptype.find('<') >= 0):
|
||||
templ = re.match(r'^([vV]ector<)([A-Za-z0-9\._]+)>$', ptype);
|
||||
if (templ):
|
||||
ptype = templ.group(1) + 'MTP' + templ.group(2).replace('.', '_') + '>';
|
||||
else:
|
||||
print('Bad template type: ' + ptype);
|
||||
continue;
|
||||
ptype = ptypewide;
|
||||
if (ptype.find('?') >= 0):
|
||||
pmasktype = re.match(r'([a-z_][a-z0-9_]*)\.([0-9]+)\?([A-Za-z0-9<>\._]+)', ptype);
|
||||
if (not pmasktype or pmasktype.group(1) != hasFlags):
|
||||
print('Bad param found: "' + param + '" in line: ' + line);
|
||||
continue;
|
||||
ptype = pmasktype.group(3);
|
||||
conditions[pname] = pmasktype.group(2);
|
||||
elif (ptype.find('<') >= 0):
|
||||
templ = re.match(r'^([vV]ector<)([A-Za-z0-9\._]+)>$', ptype);
|
||||
if (templ):
|
||||
ptype = templ.group(1) + 'MTP' + templ.group(2).replace('.', '_') + '>';
|
||||
else:
|
||||
print('Bad template type: ' + ptype);
|
||||
continue;
|
||||
prmsList.append(pname);
|
||||
prms[pname] = ptype.replace('.', '_');
|
||||
|
||||
@ -175,8 +185,18 @@ with open('scheme.tl') as f:
|
||||
funcsText += '\tMTP' + name + '(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_' + name + ') {\n\t\tread(from, end, cons);\n\t}\n'; # stream constructor
|
||||
if (len(prms)):
|
||||
funcsText += '\tMTP' + name + '(' + ', '.join(prmsStr) + ') : ' + ', '.join(prmsInit) + ' {\n\t}\n';
|
||||
funcsText += '\n';
|
||||
|
||||
if (len(conditions)):
|
||||
funcsText += '\n';
|
||||
funcsText += '\tenum {\n';
|
||||
for paramName in conditions.keys():
|
||||
funcsText += '\t\tflag_' + paramName + ' = (1 << ' + conditions[paramName] + '),\n';
|
||||
funcsText += '\t};\n';
|
||||
funcsText += '\n';
|
||||
for paramName in conditions.keys():
|
||||
funcsText += '\tbool has_' + paramName + '() const { return v' + hasFlags + '.v & flag_' + paramName + '; }\n';
|
||||
|
||||
funcsText += '\n';
|
||||
funcsText += '\tuint32 innerLength() const {\n'; # count size
|
||||
size = [];
|
||||
for k in prmsList:
|
||||
@ -192,13 +212,19 @@ with open('scheme.tl') as f:
|
||||
funcsText += '\tvoid read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_' + name + ') {\n'; # read method
|
||||
for k in prmsList:
|
||||
v = prms[k];
|
||||
funcsText += '\t\tv' + k + '.read(from, end);\n';
|
||||
if (k in conditions.keys()):
|
||||
funcsText += '\t\tif (has_' + k + '()) { v' + k + '.read(from, end); } else { v' + k + ' = MTP' + v + '(); }\n';
|
||||
else:
|
||||
funcsText += '\t\tv' + k + '.read(from, end);\n';
|
||||
funcsText += '\t}\n';
|
||||
|
||||
funcsText += '\tvoid write(mtpBuffer &to) const {\n'; # write method
|
||||
for k in prmsList:
|
||||
v = prms[k];
|
||||
funcsText += '\t\tv' + k + '.write(to);\n';
|
||||
if (k in conditions.keys()):
|
||||
funcsText += '\t\tif (has_' + k + '()) v' + k + '.write(to);\n';
|
||||
else:
|
||||
funcsText += '\t\tv' + k + '.write(to);\n';
|
||||
funcsText += '\t}\n';
|
||||
|
||||
if (isTemplate != ''):
|
||||
@ -230,7 +256,7 @@ with open('scheme.tl') as f:
|
||||
if (not restype in funcsDict):
|
||||
funcsDict[restype] = [];
|
||||
# TypesDict[restype] = resType;
|
||||
funcsDict[restype].append([name, typeid, prmsList, prms]);
|
||||
funcsDict[restype].append([name, typeid, prmsList, prms, hasFlags, conditions]);
|
||||
else:
|
||||
if (isTemplate != ''):
|
||||
print('Template types not allowed: "' + resType + '" in line: ' + line);
|
||||
@ -239,12 +265,12 @@ with open('scheme.tl') as f:
|
||||
typesList.append(restype);
|
||||
typesDict[restype] = [];
|
||||
TypesDict[restype] = resType;
|
||||
typesDict[restype].append([name, typeid, prmsList, prms]);
|
||||
typesDict[restype].append([name, typeid, prmsList, prms, hasFlags, conditions]);
|
||||
|
||||
consts = consts + 1;
|
||||
|
||||
# text serialization: types and funcs
|
||||
def addTextSerialize(dct):
|
||||
def addTextSerialize(dct, dataLetter):
|
||||
result = '';
|
||||
for restype in dct:
|
||||
v = dct[restype];
|
||||
@ -252,6 +278,8 @@ def addTextSerialize(dct):
|
||||
name = data[0];
|
||||
prmsList = data[2];
|
||||
prms = data[3];
|
||||
hasFlags = data[4];
|
||||
conditions = data[5];
|
||||
|
||||
if len(result):
|
||||
result += '\n';
|
||||
@ -267,7 +295,12 @@ def addTextSerialize(dct):
|
||||
stage = 0;
|
||||
for k in prmsList:
|
||||
v = prms[k];
|
||||
result += '\t\t\t\tcase ' + str(stage) + ': to.add(" ' + k + ': "); ++stages.back(); types.push_back(';
|
||||
result += '\t\t\t\tcase ' + str(stage) + ': to.add(" ' + k + ': "); ++stages.back(); ';
|
||||
if (k == hasFlags):
|
||||
result += 'if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; ';
|
||||
if (k in conditions.keys()):
|
||||
result += 'if (flag & MTP' + dataLetter + name + '::flag_' + k + ') { ';
|
||||
result += 'types.push_back(';
|
||||
vtypeget = re.match(r'^[Vv]ector<MTP([A-Za-z0-9\._]+)>', v);
|
||||
if (vtypeget):
|
||||
if (not re.match(r'^[A-Z]', v)):
|
||||
@ -308,17 +341,20 @@ def addTextSerialize(dct):
|
||||
result += '); vtypes.push_back(0';
|
||||
else:
|
||||
result += '0); vtypes.push_back(0';
|
||||
result += '); stages.push_back(0); break;\n';
|
||||
result += '); stages.push_back(0); flags.push_back(0); ';
|
||||
if (k in conditions.keys()):
|
||||
result += '} else { to.add("[ SKIPPED BY BIT ' + conditions[k] + ' IN FIELD ' + hasFlags + ' ]"); } ';
|
||||
result += 'break;\n';
|
||||
stage = stage + 1;
|
||||
result += '\t\t\t\tdefault: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); break;\n';
|
||||
result += '\t\t\t\tdefault: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;\n';
|
||||
result += '\t\t\t\t}\n';
|
||||
else:
|
||||
result += '\t\t\t\tto.add("{ ' + name + ' }"); types.pop_back(); vtypes.pop_back(); stages.pop_back();\n';
|
||||
result += '\t\t\t\tto.add("{ ' + name + ' }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();\n';
|
||||
result += '\t\t\tbreak;\n';
|
||||
return result;
|
||||
|
||||
textSerialize += addTextSerialize(typesDict) + '\n';
|
||||
textSerialize += addTextSerialize(funcsDict);
|
||||
textSerialize += addTextSerialize(typesDict, 'D') + '\n';
|
||||
textSerialize += addTextSerialize(funcsDict, '');
|
||||
|
||||
for restype in typesList:
|
||||
v = typesDict[restype];
|
||||
@ -346,6 +382,8 @@ for restype in typesList:
|
||||
typeid = data[1];
|
||||
prmsList = data[2];
|
||||
prms = data[3];
|
||||
hasFlags = data[4];
|
||||
conditions = data[5];
|
||||
|
||||
dataText = '';
|
||||
dataText += '\nclass MTPD' + name + ' : public mtpDataImpl<MTPD' + name + '> {\n'; # data class
|
||||
@ -400,9 +438,14 @@ for restype in typesList:
|
||||
if (withType):
|
||||
readText += '\t\t';
|
||||
writeText += '\t\t';
|
||||
readText += '\tv.v' + paramName + '.read(from, end);\n';
|
||||
writeText += '\tv.v' + paramName + '.write(to);\n';
|
||||
sizeList.append('v.v' + paramName + '.innerLength()');
|
||||
if (paramName in conditions.keys()):
|
||||
readText += '\tif (v.has_' + paramName + '()) { v.v' + paramName + '.read(from, end); } else { v.v' + paramName + ' = MTP' + paramType + '(); }\n';
|
||||
writeText += '\tif (v.has_' + paramName + '()) v.v' + paramName + '.write(to);\n';
|
||||
sizeList.append('(v.has_' + paramName + '() ? v.v' + paramName + '.innerLength() : 0)');
|
||||
else:
|
||||
readText += '\tv.v' + paramName + '.read(from, end);\n';
|
||||
writeText += '\tv.v' + paramName + '.write(to);\n';
|
||||
sizeList.append('v.v' + paramName + '.innerLength()');
|
||||
|
||||
forwards += 'class MTPD' + name + ';\n'; # data class forward declaration
|
||||
|
||||
@ -422,6 +465,16 @@ for restype in typesList:
|
||||
sizeFast = '\treturn 0;\n';
|
||||
|
||||
switchLines += 'break;\n';
|
||||
|
||||
if (len(conditions)):
|
||||
dataText += '\n';
|
||||
dataText += '\tenum {\n';
|
||||
for paramName in conditions.keys():
|
||||
dataText += '\t\tflag_' + paramName + ' = (1 << ' + conditions[paramName] + '),\n';
|
||||
dataText += '\t};\n';
|
||||
dataText += '\n';
|
||||
for paramName in conditions.keys():
|
||||
dataText += '\tbool has_' + paramName + '() const { return v' + hasFlags + '.v & flag_' + paramName + '; }\n';
|
||||
dataText += '};\n'; # class ending
|
||||
|
||||
if (len(prms)):
|
||||
@ -586,17 +639,18 @@ for restype in typesList:
|
||||
|
||||
textSerializeFull = '\nvoid mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpPrime *end, mtpPrime cons, uint32 level, mtpPrime vcons) {\n';
|
||||
textSerializeFull += '\tQVector<mtpTypeId> types, vtypes;\n';
|
||||
textSerializeFull += '\tQVector<int32> stages;\n';
|
||||
textSerializeFull += '\ttypes.reserve(20); vtypes.reserve(20); stages.reserve(20);\n';
|
||||
textSerializeFull += '\ttypes.push_back(mtpTypeId(cons)); vtypes.push_back(mtpTypeId(vcons)); stages.push_back(0);\n\n';
|
||||
textSerializeFull += '\tQVector<int32> stages, flags;\n';
|
||||
textSerializeFull += '\ttypes.reserve(20); vtypes.reserve(20); stages.reserve(20); flags.reserve(20);\n';
|
||||
textSerializeFull += '\ttypes.push_back(mtpTypeId(cons)); vtypes.push_back(mtpTypeId(vcons)); stages.push_back(0); flags.push_back(0);\n\n';
|
||||
textSerializeFull += '\tconst mtpPrime *start = from;\n';
|
||||
textSerializeFull += '\tmtpTypeId type = cons, vtype = vcons;\n';
|
||||
textSerializeFull += '\tint32 stage = 0;\n';
|
||||
textSerializeFull += '\tint32 stage = 0, flag = 0;\n';
|
||||
textSerializeFull += '\ttry {\n';
|
||||
textSerializeFull += '\t\twhile (!types.isEmpty()) {\n';
|
||||
textSerializeFull += '\t\t\ttype = types.back();\n';
|
||||
textSerializeFull += '\t\t\tvtype = vtypes.back();\n';
|
||||
textSerializeFull += '\t\t\tstage = stages.back();\n';
|
||||
textSerializeFull += '\t\t\tflag = flags.back();\n';
|
||||
textSerializeFull += '\t\t\tif (!type) {\n';
|
||||
textSerializeFull += '\t\t\t\tif (from >= end) {\n';
|
||||
textSerializeFull += '\t\t\t\t\tthrow Exception("from >= end");\n';
|
||||
@ -610,7 +664,7 @@ textSerializeFull += '\t\t\tint32 lev = level + types.size() - 1;\n';
|
||||
textSerializeFull += '\t\t\tswitch (type) {\n' + textSerialize + '\n';
|
||||
textSerializeFull += '\t\t\tdefault:\n';
|
||||
textSerializeFull += '\t\t\t\tmtpTextSerializeCore(to, from, end, type, lev, vtype);\n';
|
||||
textSerializeFull += '\t\t\t\ttypes.pop_back(); vtypes.pop_back(); stages.pop_back();\n';
|
||||
textSerializeFull += '\t\t\t\ttypes.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();\n';
|
||||
textSerializeFull += '\t\t\tbreak;\n';
|
||||
textSerializeFull += '\t\t\t}\n';
|
||||
textSerializeFull += '\t\t}\n';
|
||||
|
@ -1426,11 +1426,11 @@ void MTProtoConnectionPrivate::tryToSend() {
|
||||
mtpRequest pingRequest;
|
||||
if (dc < _mtp_internal::dcShift) { // main session
|
||||
if (!prependOnly && !_pingIdToSend && !_pingId && _pingSent + (MTPPingSendAfterAuto * 1000ULL) <= getms(true)) {
|
||||
//_pingIdToSend = MTP::nonce<mtpPingId>(); // temp disable ping_delay_disconnect, needed only for main dc session
|
||||
_pingIdToSend = MTP::nonce<mtpPingId>();
|
||||
}
|
||||
}
|
||||
if (_pingIdToSend) {
|
||||
if (prependOnly || true) {
|
||||
if (prependOnly || dc >= _mtp_internal::dcShift) {
|
||||
MTPPing ping(MTPping(MTP_long(_pingIdToSend)));
|
||||
uint32 pingSize = ping.innerLength() >> 2; // copy from MTProtoSession::send
|
||||
pingRequest = mtpRequestData::prepare(pingSize);
|
||||
@ -1448,7 +1448,7 @@ void MTProtoConnectionPrivate::tryToSend() {
|
||||
pingRequest->requestId = 0; // dont add to haveSent / wereAcked maps
|
||||
|
||||
if (dc < _mtp_internal::dcShift && !prependOnly) { // main session
|
||||
// _pingSender.start(MTPPingSendAfter * 1000);
|
||||
_pingSender.start(MTPPingSendAfter * 1000);
|
||||
}
|
||||
|
||||
_pingId = _pingIdToSend;
|
||||
|
@ -19,6 +19,12 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
#include "mtproto/mtpCoreTypes.h"
|
||||
#include "mtproto/mtpScheme.h"
|
||||
|
||||
enum {
|
||||
MTPDmessage_flag_unread = (1 << 0),
|
||||
MTPDmessage_flag_out = (1 << 1),
|
||||
};
|
||||
|
||||
#include "mtproto/mtpPublicRSA.h"
|
||||
#include "mtproto/mtpAuthKey.h"
|
||||
|
||||
|
@ -340,8 +340,6 @@ enum {
|
||||
mtpc_invokeWithLayer17 = 0x50858a19,
|
||||
mtpc_invokeWithLayer18 = 0x1c900537,
|
||||
|
||||
mtpc_invokeWithLayer = 0xda9b0d0d, // after 18 layer
|
||||
|
||||
// manually parsed
|
||||
mtpc_rpc_result = 0xf35c6d01,
|
||||
mtpc_msg_container = 0x73f1f8dc,
|
||||
@ -370,7 +368,7 @@ static const mtpTypeId mtpLayers[] = {
|
||||
mtpc_invokeWithLayer17,
|
||||
mtpc_invokeWithLayer18,
|
||||
}, mtpLayerMaxSingle = sizeof(mtpLayers) / sizeof(mtpLayers[0]);
|
||||
static const mtpPrime mtpCurrentLayer = 22;
|
||||
static const mtpPrime mtpCurrentLayer = 25;
|
||||
|
||||
template <typename bareT>
|
||||
class MTPBoxed : public bareT {
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -189,7 +189,7 @@ fileLocationUnavailable#7c596b46 volume_id:long local_id:int secret:long = FileL
|
||||
fileLocation#53d69076 dc_id:int volume_id:long local_id:int secret:long = FileLocation;
|
||||
|
||||
userEmpty#200250ba id:int = User;
|
||||
userSelf#7007b451 id:int first_name:string last_name:string username:string phone:string photo:UserProfilePhoto status:UserStatus inactive:Bool = User;
|
||||
userSelf#1c60e608 id:int first_name:string last_name:string username:string phone:string photo:UserProfilePhoto status:UserStatus = User;
|
||||
userContact#cab35e18 id:int first_name:string last_name:string username:string access_hash:long phone:string photo:UserProfilePhoto status:UserStatus = User;
|
||||
userRequest#d9ccc4ef id:int first_name:string last_name:string username:string access_hash:long phone:string photo:UserProfilePhoto status:UserStatus = User;
|
||||
userForeign#75cf7a8 id:int first_name:string last_name:string username:string access_hash:long photo:UserProfilePhoto status:UserStatus = User;
|
||||
@ -217,8 +217,7 @@ chatPhotoEmpty#37c1011c = ChatPhoto;
|
||||
chatPhoto#6153276a photo_small:FileLocation photo_big:FileLocation = ChatPhoto;
|
||||
|
||||
messageEmpty#83e5de54 id:int = Message;
|
||||
message#567699b3 flags:int id:int from_id:int to_id:Peer date:int message:string media:MessageMedia = Message;
|
||||
messageForwarded#a367e716 flags:int id:int fwd_from_id:int fwd_date:int from_id:int to_id:Peer date:int message:string media:MessageMedia = Message;
|
||||
message#a7ab1991 flags:# id:int from_id:int to_id:Peer fwd_from_id:flags.2?int fwd_date:flags.2?int reply_to_msg_id:flags.3?int date:int message:string media:MessageMedia = Message;
|
||||
messageService#1d86f70e flags:int id:int from_id:int to_id:Peer date:int action:MessageAction = Message;
|
||||
|
||||
messageMediaEmpty#3ded6320 = MessageMedia;
|
||||
@ -226,7 +225,7 @@ messageMediaPhoto#c8c45a2a photo:Photo = MessageMedia;
|
||||
messageMediaVideo#a2d24290 video:Video = MessageMedia;
|
||||
messageMediaGeo#56e0d474 geo:GeoPoint = MessageMedia;
|
||||
messageMediaContact#5e7d2f39 phone_number:string first_name:string last_name:string user_id:int = MessageMedia;
|
||||
messageMediaUnsupported#29632a36 bytes:bytes = MessageMedia;
|
||||
messageMediaUnsupported#9f84f49e = MessageMedia;
|
||||
|
||||
messageActionEmpty#b6aef7b0 = MessageAction;
|
||||
messageActionChatCreate#a6638b9a title:string users:Vector<int> = MessageAction;
|
||||
@ -236,7 +235,7 @@ messageActionChatDeletePhoto#95e3fbef = MessageAction;
|
||||
messageActionChatAddUser#5e3cfc4b user_id:int = MessageAction;
|
||||
messageActionChatDeleteUser#b2ae9b0c user_id:int = MessageAction;
|
||||
|
||||
dialog#ab3a99ac peer:Peer top_message:int unread_count:int notify_settings:PeerNotifySettings = Dialog;
|
||||
dialog#c1dd804a peer:Peer top_message:int read_inbox_max_id:int unread_count:int notify_settings:PeerNotifySettings = Dialog;
|
||||
|
||||
photoEmpty#2331b22d id:long = Photo;
|
||||
photo#22b56751 id:long access_hash:long user_id:int date:int caption:string geo:GeoPoint sizes:Vector<PhotoSize> = Photo;
|
||||
@ -251,7 +250,7 @@ video#388fa391 id:long access_hash:long user_id:int date:int caption:string dura
|
||||
geoPointEmpty#1117dd5f = GeoPoint;
|
||||
geoPoint#2049d70c long:double lat:double = GeoPoint;
|
||||
|
||||
auth.checkedPhone#e300cc3b phone_registered:Bool phone_invited:Bool = auth.CheckedPhone;
|
||||
auth.checkedPhone#811ea28e phone_registered:Bool = auth.CheckedPhone;
|
||||
|
||||
auth.sentCode#efed51d9 phone_registered:Bool phone_code_hash:string send_call_timeout:int is_password:Bool = auth.SentCode;
|
||||
|
||||
@ -291,15 +290,7 @@ contactStatus#d3680c61 user_id:int status:UserStatus = ContactStatus;
|
||||
|
||||
chatLocated#3631cf4c chat_id:int distance:int = ChatLocated;
|
||||
|
||||
contacts.foreignLinkUnknown#133421f8 = contacts.ForeignLink;
|
||||
contacts.foreignLinkRequested#a7801f47 has_phone:Bool = contacts.ForeignLink;
|
||||
contacts.foreignLinkMutual#1bea8ce1 = contacts.ForeignLink;
|
||||
|
||||
contacts.myLinkEmpty#d22a1c60 = contacts.MyLink;
|
||||
contacts.myLinkRequested#6c69efee contact:Bool = contacts.MyLink;
|
||||
contacts.myLinkContact#c240ebd9 = contacts.MyLink;
|
||||
|
||||
contacts.link#eccea3f5 my_link:contacts.MyLink foreign_link:contacts.ForeignLink user:User = contacts.Link;
|
||||
contacts.link#3ace484c my_link:ContactLink foreign_link:ContactLink user:User = contacts.Link;
|
||||
|
||||
contacts.contactsNotModified#b74ba9d2 = contacts.Contacts;
|
||||
contacts.contacts#6f8b8cb2 contacts:Vector<Contact> users:Vector<User> = contacts.Contacts;
|
||||
@ -318,34 +309,31 @@ messages.messages#8c718e87 messages:Vector<Message> chats:Vector<Chat> users:Vec
|
||||
messages.messagesSlice#b446ae3 count:int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
|
||||
|
||||
messages.messageEmpty#3f4e0648 = messages.Message;
|
||||
messages.message#ff90c417 message:Message chats:Vector<Chat> users:Vector<User> = messages.Message;
|
||||
|
||||
messages.statedMessages#969478bb messages:Vector<Message> chats:Vector<Chat> users:Vector<User> pts:int seq:int = messages.StatedMessages;
|
||||
messages.statedMessages#7d84b48 messages:Vector<Message> chats:Vector<Chat> users:Vector<User> pts:int pts_count:int = messages.StatedMessages;
|
||||
|
||||
messages.statedMessage#d07ae726 message:Message chats:Vector<Chat> users:Vector<User> pts:int seq:int = messages.StatedMessage;
|
||||
messages.statedMessage#96240c6a message:Message chats:Vector<Chat> users:Vector<User> pts:int pts_count:int = messages.StatedMessage;
|
||||
|
||||
messages.sentMessage#d1f4d35c id:int date:int pts:int seq:int = messages.SentMessage;
|
||||
messages.sentMessage#900eac40 id:int date:int pts:int pts_count:int = messages.SentMessage;
|
||||
|
||||
messages.chat#40e9002a chat:Chat users:Vector<User> = messages.Chat;
|
||||
|
||||
messages.chats#8150cbd8 chats:Vector<Chat> users:Vector<User> = messages.Chats;
|
||||
messages.chats#64ff9fd5 chats:Vector<Chat> = messages.Chats;
|
||||
|
||||
messages.chatFull#e5d7d19c full_chat:ChatFull chats:Vector<Chat> users:Vector<User> = messages.ChatFull;
|
||||
|
||||
messages.affectedHistory#b7de36f2 pts:int seq:int offset:int = messages.AffectedHistory;
|
||||
messages.affectedHistory#b45c69d1 pts:int pts_count:int offset:int = messages.AffectedHistory;
|
||||
|
||||
inputMessagesFilterEmpty#57e2f66c = MessagesFilter;
|
||||
inputMessagesFilterPhotos#9609a51c = MessagesFilter;
|
||||
inputMessagesFilterVideo#9fc00e65 = MessagesFilter;
|
||||
inputMessagesFilterPhotoVideo#56e9f0e4 = MessagesFilter;
|
||||
inputMessagesFilterPhotoVideoDocuments#d95e73bb = MessagesFilter;
|
||||
inputMessagesFilterDocument#9eddf188 = MessagesFilter;
|
||||
inputMessagesFilterAudio#cfc87522 = MessagesFilter;
|
||||
|
||||
updateNewMessage#13abdb3 message:Message pts:int = Update;
|
||||
updateNewMessage#1f2b0afd message:Message pts:int pts_count:int = Update;
|
||||
updateMessageID#4e90bfd6 id:int random_id:long = Update;
|
||||
updateReadMessages#c6649e31 messages:Vector<int> pts:int = Update;
|
||||
updateDeleteMessages#a92bfe26 messages:Vector<int> pts:int = Update;
|
||||
updateRestoreMessages#d15de04d messages:Vector<int> pts:int = Update;
|
||||
updateReadMessages#2e5ab668 messages:Vector<int> pts:int pts_count:int = Update;
|
||||
updateDeleteMessages#a20db0e5 messages:Vector<int> pts:int pts_count:int = Update;
|
||||
updateUserTyping#5c486927 user_id:int action:SendMessageAction = Update;
|
||||
updateChatUserTyping#9a65ea1f chat_id:int user_id:int action:SendMessageAction = Update;
|
||||
updateChatParticipants#7761198 participants:ChatParticipants = Update;
|
||||
@ -353,8 +341,7 @@ updateUserStatus#1bfbd823 user_id:int status:UserStatus = Update;
|
||||
updateUserName#a7332b73 user_id:int first_name:string last_name:string username:string = Update;
|
||||
updateUserPhoto#95313b0c user_id:int date:int photo:UserProfilePhoto previous:Bool = Update;
|
||||
updateContactRegistered#2575bbb9 user_id:int date:int = Update;
|
||||
updateContactLink#51a48a9a user_id:int my_link:contacts.MyLink foreign_link:contacts.ForeignLink = Update;
|
||||
updateActivation#6f690963 user_id:int = Update;
|
||||
updateContactLink#9d2e67c5 user_id:int my_link:ContactLink foreign_link:ContactLink = Update;
|
||||
updateNewAuthorization#8f06529a auth_key_id:long date:int device:string location:string = Update;
|
||||
|
||||
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
|
||||
@ -364,8 +351,8 @@ updates.difference#f49ca0 new_messages:Vector<Message> new_encrypted_messages:Ve
|
||||
updates.differenceSlice#a8fb1981 new_messages:Vector<Message> new_encrypted_messages:Vector<EncryptedMessage> other_updates:Vector<Update> chats:Vector<Chat> users:Vector<User> intermediate_state:updates.State = updates.Difference;
|
||||
|
||||
updatesTooLong#e317af7e = Updates;
|
||||
updateShortMessage#d3f45784 id:int from_id:int message:string pts:int date:int seq:int = Updates;
|
||||
updateShortChatMessage#2b2fbd4e id:int from_id:int chat_id:int message:string pts:int date:int seq:int = Updates;
|
||||
updateShortMessage#b87da3b1 id:int from_id:int message:string pts:int pts_count:int date:int = Updates;
|
||||
updateShortChatMessage#20e85ded id:int from_id:int chat_id:int message:string pts:int pts_count:int date:int = Updates;
|
||||
updateShort#78d4dec1 update:Update date:int = Updates;
|
||||
updatesCombined#725b04c3 updates:Vector<Update> users:Vector<User> chats:Vector<Chat> date:int seq_start:int seq:int = Updates;
|
||||
updates#74ae4240 updates:Vector<Update> users:Vector<User> chats:Vector<Chat> date:int seq:int = Updates;
|
||||
@ -379,7 +366,7 @@ upload.file#96a18d5 type:storage.FileType mtime:int bytes:bytes = upload.File;
|
||||
|
||||
dcOption#2ec2a43c id:int hostname:string ip_address:string port:int = DcOption;
|
||||
|
||||
config#2e54dd74 date:int test_mode:Bool this_dc:int dc_options:Vector<DcOption> chat_size_max:int broadcast_size_max:int = Config;
|
||||
config#3e6f732a date:int expires:int test_mode:Bool this_dc:int dc_options:Vector<DcOption> chat_size_max:int broadcast_size_max:int online_update_period_ms:int offline_blur_timeout_ms:int offline_idle_timeout_ms:int online_cloud_timeout_ms:int notify_cloud_delay_ms:int notify_default_delay_ms:int chat_big_size:int disabled_features:Vector<DisabledFeature> = Config;
|
||||
|
||||
nearestDc#8e1a1775 country:string this_dc:int nearest_dc:int = NearestDc;
|
||||
|
||||
@ -388,11 +375,11 @@ help.noAppUpdate#c45a6536 = help.AppUpdate;
|
||||
|
||||
help.inviteText#18cb9f78 message:string = help.InviteText;
|
||||
|
||||
messages.statedMessagesLinks#3e74f5c6 messages:Vector<Message> chats:Vector<Chat> users:Vector<User> links:Vector<contacts.Link> pts:int seq:int = messages.StatedMessages;
|
||||
messages.statedMessagesLinks#51be5d19 messages:Vector<Message> chats:Vector<Chat> users:Vector<User> pts:int pts_count:int links:Vector<contacts.Link> seq:int = messages.StatedMessages;
|
||||
|
||||
messages.statedMessageLink#a9af2881 message:Message chats:Vector<Chat> users:Vector<User> links:Vector<contacts.Link> pts:int seq:int = messages.StatedMessage;
|
||||
messages.statedMessageLink#948a288 message:Message chats:Vector<Chat> users:Vector<User> pts:int pts_count:int links:Vector<contacts.Link> seq:int = messages.StatedMessage;
|
||||
|
||||
messages.sentMessageLink#e9db4a3f id:int date:int pts:int seq:int links:Vector<contacts.Link> = messages.SentMessage;
|
||||
messages.sentMessageLink#e923400d id:int date:int pts:int pts_count:int links:Vector<contacts.Link> seq:int = messages.SentMessage;
|
||||
|
||||
inputGeoChat#74d456fa chat_id:int access_hash:long = InputGeoChat;
|
||||
|
||||
@ -542,18 +529,36 @@ account.sentChangePhoneCode#a4f58c4c phone_code_hash:string send_call_timeout:in
|
||||
|
||||
updateUserPhone#12b9417b user_id:int phone:string = Update;
|
||||
|
||||
account.noPassword#5770e7a9 new_salt:bytes = account.Password;
|
||||
account.password#739e5f72 current_salt:bytes new_salt:bytes hint:string = account.Password;
|
||||
|
||||
documentAttributeImageSize#6c37c15c w:int h:int = DocumentAttribute;
|
||||
documentAttributeAnimated#11b58939 = DocumentAttribute;
|
||||
documentAttributeSticker#fb0a5727 = DocumentAttribute;
|
||||
documentAttributeSticker#994c9882 alt:string = DocumentAttribute;
|
||||
documentAttributeVideo#5910cccb duration:int w:int h:int = DocumentAttribute;
|
||||
documentAttributeAudio#51448e5 duration:int = DocumentAttribute;
|
||||
documentAttributeFilename#15590068 file_name:string = DocumentAttribute;
|
||||
|
||||
messages.stickersNotModified#f1749a22 = messages.Stickers;
|
||||
messages.stickers#8a8ecd32 hash:string stickers:Vector<Document> = messages.Stickers;
|
||||
|
||||
stickerPack#12b299d4 emoticon:string documents:Vector<long> = StickerPack;
|
||||
|
||||
messages.allStickersNotModified#e86602c3 = messages.AllStickers;
|
||||
messages.allStickers#dcef3102 hash:string packs:Vector<StickerPack> documents:Vector<Document> = messages.AllStickers;
|
||||
|
||||
disabledFeature#ae636f24 feature:string description:string = DisabledFeature;
|
||||
|
||||
updateReadHistoryInbox#9961fd5c peer:Peer max_id:int pts:int pts_count:int = Update;
|
||||
updateReadHistoryOutbox#2f2f21bf peer:Peer max_id:int pts:int pts_count:int = Update;
|
||||
|
||||
messages.affectedMessages#84d19185 pts:int pts_count:int = messages.AffectedMessages;
|
||||
|
||||
contactLinkUnknown#5f4f9247 = ContactLink;
|
||||
contactLinkNone#feedd3ad = ContactLink;
|
||||
contactLinkHasPhone#268f3f59 = ContactLink;
|
||||
contactLinkContact#d502c2d0 = ContactLink;
|
||||
|
||||
---functions---
|
||||
|
||||
invokeAfterMsg#cb9f372d msg_id:long query:!X = X;
|
||||
@ -600,15 +605,14 @@ messages.getMessages#4222fa74 id:Vector<int> = messages.Messages;
|
||||
messages.getDialogs#eccf1df6 offset:int max_id:int limit:int = messages.Dialogs;
|
||||
messages.getHistory#92a1df2f peer:InputPeer offset:int max_id:int limit:int = messages.Messages;
|
||||
messages.search#7e9f2ab peer:InputPeer q:string filter:MessagesFilter min_date:int max_date:int offset:int max_id:int limit:int = messages.Messages;
|
||||
messages.readHistory#eed884c6 peer:InputPeer max_id:int offset:int read_contents:Bool = messages.AffectedHistory;
|
||||
messages.readHistory#b04f2510 peer:InputPeer max_id:int offset:int = messages.AffectedHistory;
|
||||
messages.deleteHistory#f4f8fb61 peer:InputPeer offset:int = messages.AffectedHistory;
|
||||
messages.deleteMessages#14f2dd0a id:Vector<int> = Vector<int>;
|
||||
messages.restoreMessages#395f9d7e id:Vector<int> = Vector<int>;
|
||||
messages.deleteMessages#a5f18925 id:Vector<int> = messages.AffectedMessages;
|
||||
messages.receivedMessages#28abcb68 max_id:int = Vector<int>;
|
||||
messages.setTyping#a3825e50 peer:InputPeer action:SendMessageAction = Bool;
|
||||
messages.sendMessage#4cde0aab peer:InputPeer message:string random_id:long = messages.SentMessage;
|
||||
messages.sendMedia#a3c85d76 peer:InputPeer media:InputMedia random_id:long = messages.StatedMessage;
|
||||
messages.forwardMessages#514cd10f peer:InputPeer id:Vector<int> = messages.StatedMessages;
|
||||
messages.sendMessage#1ca852a1 peer:InputPeer reply_to_msg_id:int message:string random_id:long = messages.SentMessage;
|
||||
messages.sendMedia#fcee7fc0 peer:InputPeer reply_to_msg_id:int media:InputMedia random_id:long = messages.StatedMessage;
|
||||
messages.forwardMessages#ded42045 peer:InputPeer id:Vector<int> random_id:Vector<long> = messages.StatedMessages;
|
||||
messages.getChats#3c6aa187 id:Vector<int> = messages.Chats;
|
||||
messages.getFullChat#3b831c66 chat_id:int = messages.ChatFull;
|
||||
messages.editChatTitle#b4bc68b5 chat_id:int title:string = messages.StatedMessage;
|
||||
@ -670,7 +674,7 @@ help.getSupport#9cdf08cd = help.Support;
|
||||
|
||||
auth.sendSms#da9f3e8 phone_number:string phone_code_hash:string = Bool;
|
||||
|
||||
messages.readMessageContents#354b5bc2 id:Vector<int> = Vector<int>;
|
||||
messages.readMessageContents#36a73f77 id:Vector<int> = messages.AffectedMessages;
|
||||
|
||||
account.checkUsername#2714d86c username:string = Bool;
|
||||
account.updateUsername#3e0bdd7c username:string = User;
|
||||
@ -683,9 +687,18 @@ account.deleteAccount#418d4e0b reason:string = Bool;
|
||||
account.getAccountTTL#8fc711d = AccountDaysTTL;
|
||||
account.setAccountTTL#2442485e ttl:AccountDaysTTL = Bool;
|
||||
|
||||
invokeWithLayer#da9b0d0d layer:int query:!X = X;
|
||||
|
||||
contacts.resolveUsername#bf0131c username:string = User;
|
||||
|
||||
account.sendChangePhoneCode#a407a8f4 phone_number:string = account.SentChangePhoneCode;
|
||||
account.changePhone#70c32edb phone_number:string phone_code_hash:string phone_code:string = User;
|
||||
account.getPassword#548a30f5 = account.Password;
|
||||
account.setPassword#dd2a4d8f current_password_hash:bytes new_salt:bytes new_password_hash:bytes hint:string = Bool;
|
||||
|
||||
messages.getAllStickers#aa3bc868 hash:string = messages.AllStickers;
|
||||
auth.checkPassword#a63011e password_hash:bytes = auth.Authorization;
|
||||
|
||||
messages.getStickers#ae22e045 emoticon:string hash:string = messages.Stickers;
|
||||
messages.getAllStickers#aa3bc868 hash:string = messages.AllStickers;
|
||||
|
||||
account.updateDeviceLocked#38df3532 period:int = Bool;
|
@ -262,6 +262,18 @@ void SingleTimer::start(int msec) {
|
||||
QTimer::start(msec);
|
||||
}
|
||||
|
||||
void SingleTimer::startIfNotActive(int msec) {
|
||||
if (isActive()) {
|
||||
int remains = remainingTime();
|
||||
if (remains > msec) {
|
||||
start(msec);
|
||||
} else if (!remains) {
|
||||
start(1);
|
||||
}
|
||||
} else {
|
||||
start(msec);
|
||||
}
|
||||
}
|
||||
|
||||
uint64 msgid() {
|
||||
#ifdef Q_OS_WIN
|
||||
|
@ -114,6 +114,7 @@ public:
|
||||
public slots:
|
||||
|
||||
void start(int msec);
|
||||
void startIfNotActive(int msec);
|
||||
void adjust() {
|
||||
uint64 n = getms(true);
|
||||
if (isActive()) {
|
||||
|
@ -593,6 +593,8 @@ void Window::sendServiceHistoryRequest() {
|
||||
}
|
||||
|
||||
void Window::setupMain(bool anim, const MTPUser *self) {
|
||||
Local::readRecentStickers();
|
||||
|
||||
QPixmap bg = anim ? myGrab(this, QRect(0, st::titleHeight, width(), height() - st::titleHeight)) : QPixmap();
|
||||
clearWidgets();
|
||||
main = new MainWidget(this);
|
||||
|
Loading…
Reference in New Issue
Block a user