mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-07 07:33:52 +02:00
Merge branch 'dev' of https://github.com/telegramdesktop/tdesktop
This commit is contained in:
commit
2f094c2350
58 changed files with 9163 additions and 6354 deletions
|
@ -91,6 +91,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||||
"lng_server_error" = "Internal server error.";
|
"lng_server_error" = "Internal server error.";
|
||||||
"lng_flood_error" = "Too much tries. Please try again later.";
|
"lng_flood_error" = "Too much tries. Please try again later.";
|
||||||
"lng_deleted" = "Unknown";
|
"lng_deleted" = "Unknown";
|
||||||
|
"lng_deleted_message" = "Deleted message";
|
||||||
|
|
||||||
"lng_intro" = "Welcome to the official [a href=\"https://telegram.org/\"]Telegram[/a] desktop app.\nIt's [b]fast[/b] and [b]secure[/b].";
|
"lng_intro" = "Welcome to the official [a href=\"https://telegram.org/\"]Telegram[/a] desktop app.\nIt's [b]fast[/b] and [b]secure[/b].";
|
||||||
"lng_start_msgs" = "START MESSAGING";
|
"lng_start_msgs" = "START MESSAGING";
|
||||||
|
@ -332,6 +333,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||||
"lng_action_created_chat" = "{from} created group «{title}»";
|
"lng_action_created_chat" = "{from} created group «{title}»";
|
||||||
|
|
||||||
"lng_forwarded_from" = "Forwarded from";
|
"lng_forwarded_from" = "Forwarded from";
|
||||||
|
"lng_in_reply_to" = "In reply to";
|
||||||
|
|
||||||
"lng_attach_failed" = "Failed";
|
"lng_attach_failed" = "Failed";
|
||||||
"lng_attach_file" = "File";
|
"lng_attach_file" = "File";
|
||||||
|
@ -385,6 +387,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||||
"lng_context_copy_email" = "Copy email address";
|
"lng_context_copy_email" = "Copy email address";
|
||||||
"lng_context_open_hashtag" = "Search by hashtag";
|
"lng_context_open_hashtag" = "Search by hashtag";
|
||||||
"lng_context_copy_hashtag" = "Copy hashtag";
|
"lng_context_copy_hashtag" = "Copy hashtag";
|
||||||
|
"lng_context_open_mention" = "Open {user} profile";
|
||||||
|
"lng_context_copy_mention" = "Copy mention";
|
||||||
"lng_context_open_image" = "Open Image";
|
"lng_context_open_image" = "Open Image";
|
||||||
"lng_context_save_image" = "Save Image As..";
|
"lng_context_save_image" = "Save Image As..";
|
||||||
"lng_context_forward_image" = "Forward Image";
|
"lng_context_forward_image" = "Forward Image";
|
||||||
|
@ -403,8 +407,9 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||||
"lng_context_forward_file" = "Forward File";
|
"lng_context_forward_file" = "Forward File";
|
||||||
"lng_context_delete_file" = "Delete File";
|
"lng_context_delete_file" = "Delete File";
|
||||||
"lng_context_close_file" = "Close File";
|
"lng_context_close_file" = "Close File";
|
||||||
"lng_context_copy_text" = "Copy Message Text";
|
"lng_context_copy_text" = "Copy Text";
|
||||||
"lng_context_to_msg" = "Go To Message";
|
"lng_context_to_msg" = "Go To Message";
|
||||||
|
"lng_context_reply_msg" = "Reply";
|
||||||
"lng_context_forward_msg" = "Forward Message";
|
"lng_context_forward_msg" = "Forward Message";
|
||||||
"lng_context_delete_msg" = "Delete Message";
|
"lng_context_delete_msg" = "Delete Message";
|
||||||
"lng_context_select_msg" = "Select Message";
|
"lng_context_select_msg" = "Select Message";
|
||||||
|
@ -425,6 +430,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||||
"lng_forward_send_files_confirm" = "Send selected files to {recipient}?";
|
"lng_forward_send_files_confirm" = "Send selected files to {recipient}?";
|
||||||
"lng_forward" = "Forward";
|
"lng_forward" = "Forward";
|
||||||
"lng_forward_send" = "Send";
|
"lng_forward_send" = "Send";
|
||||||
|
"lng_forward_messages" = "{count:_not_used_|Forwarded message|# forwarded messages}";
|
||||||
|
|
||||||
"lng_contact_phone" = "Phone number";
|
"lng_contact_phone" = "Phone number";
|
||||||
"lng_enter_contact_data" = "New Contact";
|
"lng_enter_contact_data" = "New Contact";
|
||||||
|
|
|
@ -784,6 +784,8 @@ msgInSelectOverlay: #358cd44c;
|
||||||
msgStickerOverlay: #358cd47f;
|
msgStickerOverlay: #358cd47f;
|
||||||
msgOutServiceColor: #3a8e26;
|
msgOutServiceColor: #3a8e26;
|
||||||
msgInServiceColor: #0e7acd;
|
msgInServiceColor: #0e7acd;
|
||||||
|
msgOutServiceSelColor: #367570;
|
||||||
|
msgInServiceSelColor: #0e7acd;
|
||||||
msgShadow: 2px;
|
msgShadow: 2px;
|
||||||
msgInShadow: #748ea229;
|
msgInShadow: #748ea229;
|
||||||
msgOutShadow: #3ac34740;
|
msgOutShadow: #3ac34740;
|
||||||
|
@ -794,6 +796,15 @@ msgOutDateColor: #6cc264;
|
||||||
msgInSelectDateColor: #6a9cc5;
|
msgInSelectDateColor: #6a9cc5;
|
||||||
msgOutSelectDateColor: #50a79c;
|
msgOutSelectDateColor: #50a79c;
|
||||||
|
|
||||||
|
msgReplyPadding: margins(6px, 6px, 11px, 6px);
|
||||||
|
msgReplyBarPos: point(1px, 0px);
|
||||||
|
msgReplyBarSize: size(2px, 36px);
|
||||||
|
msgReplyBarSkip: 10px;
|
||||||
|
msgOutReplyBarColor: #5dc452;
|
||||||
|
msgInReplyBarColor: #2fa9e2;
|
||||||
|
msgOutReplyBarSelColor: #4da79f;
|
||||||
|
msgInReplyBarSelColor: #2fa9e2;
|
||||||
|
|
||||||
msgServiceSelectBG: #fff4;
|
msgServiceSelectBG: #fff4;
|
||||||
msgServiceRadius: 2px;
|
msgServiceRadius: 2px;
|
||||||
|
|
||||||
|
@ -878,7 +889,7 @@ introErrLabelTextStyle: textStyle(defaultTextStyle) {
|
||||||
|
|
||||||
mediaMaxWidth: 250px;
|
mediaMaxWidth: 250px;
|
||||||
mediaFont: font(fsize);
|
mediaFont: font(fsize);
|
||||||
mediaPadding: margins(7px, 6px, 11px, 6px);
|
mediaPadding: margins(7px, 6px, 7px, 6px);
|
||||||
mediaThumbSize: 48px;
|
mediaThumbSize: 48px;
|
||||||
mediaNameTop: 3px;
|
mediaNameTop: 3px;
|
||||||
mediaDetailsShift: 3px;
|
mediaDetailsShift: 3px;
|
||||||
|
@ -960,6 +971,24 @@ btnAttachEmoji: iconedButton(btnAttachDocument) {
|
||||||
width: 32px;
|
width: 32px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
replySkip: 52px;
|
||||||
|
replyColor: #377aae;
|
||||||
|
replyHeight: 49px;
|
||||||
|
replyTop: 8px;
|
||||||
|
replyBottom: 6px;
|
||||||
|
replyIconPos: point(13px, 15px);
|
||||||
|
replyIcon: sprite(174px, 195px, 24px, 24px);
|
||||||
|
replyCancel: iconedButton(btnDefIconed) {
|
||||||
|
icon: sprite(165px, 24px, 14px, 14px);
|
||||||
|
iconPos: point(17px, 17px);
|
||||||
|
downIcon: sprite(165px, 24px, 14px, 14px);
|
||||||
|
downIconPos: point(17px, 18px);
|
||||||
|
bgColor: white;
|
||||||
|
overBgColor: white;
|
||||||
|
width: 49px;
|
||||||
|
height: 49px;
|
||||||
|
}
|
||||||
|
|
||||||
historyScroll: flatScroll(scrollDef) {
|
historyScroll: flatScroll(scrollDef) {
|
||||||
barColor: #89a0b47a;
|
barColor: #89a0b47a;
|
||||||
bgColor: #89a0b44c;
|
bgColor: #89a0b44c;
|
||||||
|
@ -1318,6 +1347,7 @@ dropdownShadow: sprite(241px, 46px, 6px, 6px);
|
||||||
dropdownBorder: 1px;
|
dropdownBorder: 1px;
|
||||||
dropdownBorderColor: #ebebeb;
|
dropdownBorderColor: #ebebeb;
|
||||||
dropdownBackground: white;
|
dropdownBackground: white;
|
||||||
|
dropdownDuration: 150;
|
||||||
|
|
||||||
dropdownAttachDocument: iconedButton(btnAttachDocument) {
|
dropdownAttachDocument: iconedButton(btnAttachDocument) {
|
||||||
iconPos: point(14px, 13px);
|
iconPos: point(14px, 13px);
|
||||||
|
@ -1714,3 +1744,13 @@ passcodeSubmit: flatButton(btnIntroNext) {
|
||||||
font: font(19px);
|
font: font(19px);
|
||||||
overFont: font(19px);
|
overFont: font(19px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mentionHeight: 40px;
|
||||||
|
mentionScroll: flatScroll(scrollDef) {
|
||||||
|
topsh: 0;
|
||||||
|
bottomsh: 0;
|
||||||
|
}
|
||||||
|
mentionPadding: margins(8px, 5px, 8px, 5px);
|
||||||
|
mentionTop: 11px;
|
||||||
|
mentionFont: linkFont;
|
||||||
|
mentionPhotoSize: msgPhotoSize;
|
||||||
|
|
181
Telegram/SourceFiles/apiwrap.cpp
Normal file
181
Telegram/SourceFiles/apiwrap.cpp
Normal file
|
@ -0,0 +1,181 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||||
|
|
||||||
|
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
It is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
|
Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||||
|
*/
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "style.h"
|
||||||
|
#include "lang.h"
|
||||||
|
|
||||||
|
#include "application.h"
|
||||||
|
#include "window.h"
|
||||||
|
#include "mainwidget.h"
|
||||||
|
#include "apiwrap.h"
|
||||||
|
|
||||||
|
#include "localstorage.h"
|
||||||
|
|
||||||
|
ApiWrap::ApiWrap(QObject *parent) : QObject(parent) {
|
||||||
|
App::initBackground();
|
||||||
|
|
||||||
|
connect(&_replyToTimer, SIGNAL(timeout()), this, SLOT(resolveReplyTo()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ApiWrap::init() {
|
||||||
|
App::initMedia();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ApiWrap::itemRemoved(HistoryItem *item) {
|
||||||
|
if (HistoryReply *reply = item->toHistoryReply()) {
|
||||||
|
ReplyToRequests::iterator i = _replyToRequests.find(reply->replyToId());
|
||||||
|
if (i != _replyToRequests.cend()) {
|
||||||
|
for (QList<HistoryReply*>::iterator j = i->replies.begin(); j != i->replies.end();) {
|
||||||
|
if ((*j) == reply) {
|
||||||
|
j = i->replies.erase(j);
|
||||||
|
} else {
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i->replies.isEmpty()) {
|
||||||
|
_replyToRequests.erase(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ApiWrap::itemReplaced(HistoryItem *oldItem, HistoryItem *newItem) {
|
||||||
|
if (HistoryReply *reply = oldItem->toHistoryReply()) {
|
||||||
|
ReplyToRequests::iterator i = _replyToRequests.find(reply->replyToId());
|
||||||
|
if (i != _replyToRequests.cend()) {
|
||||||
|
for (QList<HistoryReply*>::iterator j = i->replies.begin(); j != i->replies.end();) {
|
||||||
|
if ((*j) == reply) {
|
||||||
|
if (HistoryReply *newReply = newItem->toHistoryReply()) {
|
||||||
|
*j = newReply;
|
||||||
|
++j;
|
||||||
|
} else {
|
||||||
|
j = i->replies.erase(j);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i->replies.isEmpty()) {
|
||||||
|
_replyToRequests.erase(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ApiWrap::requestReplyTo(HistoryReply *reply, MsgId to) {
|
||||||
|
ReplyToRequest &req(_replyToRequests[to]);
|
||||||
|
req.replies.append(reply);
|
||||||
|
if (!req.req) _replyToTimer.start(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ApiWrap::requestFullPeer(PeerData *peer) {
|
||||||
|
if (_fullRequests.contains(peer)) return;
|
||||||
|
mtpRequestId req;
|
||||||
|
if (peer->chat) {
|
||||||
|
req = MTP::send(MTPmessages_GetFullChat(MTP_int(App::chatFromPeer(peer->id))), rpcDone(&ApiWrap::gotChatFull, peer), rpcFail(&ApiWrap::gotPeerFailed, peer));
|
||||||
|
} else {
|
||||||
|
req = MTP::send(MTPusers_GetFullUser(peer->asUser()->inputUser), rpcDone(&ApiWrap::gotUserFull, peer), rpcFail(&ApiWrap::gotPeerFailed, peer));
|
||||||
|
}
|
||||||
|
_fullRequests.insert(peer, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result) {
|
||||||
|
const MTPDmessages_chatFull &d(result.c_messages_chatFull());
|
||||||
|
App::feedUsers(d.vusers);
|
||||||
|
App::feedChats(d.vchats);
|
||||||
|
App::feedParticipants(d.vfull_chat.c_chatFull().vparticipants);
|
||||||
|
PhotoData *photo = App::feedPhoto(d.vfull_chat.c_chatFull().vchat_photo);
|
||||||
|
if (photo) {
|
||||||
|
ChatData *chat = peer->asChat();
|
||||||
|
if (chat) {
|
||||||
|
chat->photoId = photo->id;
|
||||||
|
photo->chat = chat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
App::main()->gotNotifySetting(MTP_inputNotifyPeer(peer->input), d.vfull_chat.c_chatFull().vnotify_settings);
|
||||||
|
|
||||||
|
_fullRequests.remove(peer);
|
||||||
|
emit fullPeerLoaded(peer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ApiWrap::gotUserFull(PeerData *peer, const MTPUserFull &result) {
|
||||||
|
const MTPDuserFull &d(result.c_userFull());
|
||||||
|
App::feedUsers(MTP_vector<MTPUser>(1, d.vuser));
|
||||||
|
App::feedUserLink(MTP_int(App::userFromPeer(peer->id)), d.vlink.c_contacts_link().vmy_link, d.vlink.c_contacts_link().vforeign_link);
|
||||||
|
App::main()->gotNotifySetting(MTP_inputNotifyPeer(peer->input), d.vnotify_settings);
|
||||||
|
|
||||||
|
_fullRequests.remove(peer);
|
||||||
|
emit fullPeerLoaded(peer);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ApiWrap::gotPeerFailed(PeerData *peer, const RPCError &err) {
|
||||||
|
_fullRequests.remove(peer);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ApiWrap::resolveReplyTo() {
|
||||||
|
if (_replyToRequests.isEmpty()) return;
|
||||||
|
|
||||||
|
QVector<MTPint> ids;
|
||||||
|
ids.reserve(_replyToRequests.size());
|
||||||
|
for (ReplyToRequests::const_iterator i = _replyToRequests.cbegin(), e = _replyToRequests.cend(); i != e; ++i) {
|
||||||
|
if (!i.value().req) {
|
||||||
|
ids.push_back(MTP_int(i.key()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!ids.isEmpty()) {
|
||||||
|
mtpRequestId req = MTP::send(MTPmessages_GetMessages(MTP_vector<MTPint>(ids)), rpcDone(&ApiWrap::gotReplyTo));
|
||||||
|
for (ReplyToRequests::iterator i = _replyToRequests.begin(), e = _replyToRequests.end(); i != e; ++i) {
|
||||||
|
i.value().req = req;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ApiWrap::gotReplyTo(const MTPmessages_Messages &msgs, mtpRequestId req) {
|
||||||
|
switch (msgs.type()) {
|
||||||
|
case mtpc_messages_messages:
|
||||||
|
App::feedUsers(msgs.c_messages_messages().vusers);
|
||||||
|
App::feedChats(msgs.c_messages_messages().vchats);
|
||||||
|
App::feedMsgs(msgs.c_messages_messages().vmessages, -1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case mtpc_messages_messagesSlice:
|
||||||
|
App::feedUsers(msgs.c_messages_messagesSlice().vusers);
|
||||||
|
App::feedChats(msgs.c_messages_messagesSlice().vchats);
|
||||||
|
App::feedMsgs(msgs.c_messages_messagesSlice().vmessages, -1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for (ReplyToRequests::iterator i = _replyToRequests.begin(); i != _replyToRequests.cend();) {
|
||||||
|
if (i.value().req == req) {
|
||||||
|
for (QList<HistoryReply*>::const_iterator j = i.value().replies.cbegin(), e = i.value().replies.cend(); j != e; ++j) {
|
||||||
|
if (*j) {
|
||||||
|
(*j)->updateReplyTo(true);
|
||||||
|
} else {
|
||||||
|
App::main()->updateReplyTo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i = _replyToRequests.erase(i);
|
||||||
|
} else {
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ApiWrap::~ApiWrap() {
|
||||||
|
App::deinitMedia(false);
|
||||||
|
}
|
64
Telegram/SourceFiles/apiwrap.h
Normal file
64
Telegram/SourceFiles/apiwrap.h
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||||
|
|
||||||
|
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
It is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
|
Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
class ApiWrap : public QObject, public RPCSender {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
ApiWrap(QObject *parent);
|
||||||
|
void init();
|
||||||
|
|
||||||
|
void itemRemoved(HistoryItem *item);
|
||||||
|
void itemReplaced(HistoryItem *oldItem, HistoryItem *newItem);
|
||||||
|
|
||||||
|
void requestReplyTo(HistoryReply *reply, MsgId to);
|
||||||
|
|
||||||
|
void requestFullPeer(PeerData *peer);
|
||||||
|
|
||||||
|
~ApiWrap();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
void fullPeerLoaded(PeerData *peer);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
void resolveReplyTo();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void gotReplyTo(const MTPmessages_Messages &result, mtpRequestId req);
|
||||||
|
struct ReplyToRequest {
|
||||||
|
ReplyToRequest() : req(0) {
|
||||||
|
}
|
||||||
|
mtpRequestId req;
|
||||||
|
QList<HistoryReply*> replies;
|
||||||
|
};
|
||||||
|
typedef QMap<MsgId, ReplyToRequest> ReplyToRequests;
|
||||||
|
ReplyToRequests _replyToRequests;
|
||||||
|
SingleTimer _replyToTimer;
|
||||||
|
|
||||||
|
void gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result);
|
||||||
|
void gotUserFull(PeerData *peer, const MTPUserFull &result);
|
||||||
|
bool gotPeerFailed(PeerData *peer, const RPCError &err);
|
||||||
|
typedef QMap<PeerData*, mtpRequestId> FullRequests;
|
||||||
|
FullRequests _fullRequests;
|
||||||
|
|
||||||
|
};
|
|
@ -52,6 +52,8 @@ namespace {
|
||||||
VideoItems videoItems;
|
VideoItems videoItems;
|
||||||
AudioItems audioItems;
|
AudioItems audioItems;
|
||||||
DocumentItems documentItems;
|
DocumentItems documentItems;
|
||||||
|
typedef QMap<HistoryItem*, QMap<HistoryReply*, bool> > RepliesTo;
|
||||||
|
RepliesTo repliesTo;
|
||||||
|
|
||||||
Histories histories;
|
Histories histories;
|
||||||
|
|
||||||
|
@ -118,6 +120,10 @@ namespace App {
|
||||||
return app() ? app()->uploader() : 0;
|
return app() ? app()->uploader() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ApiWrap *api() {
|
||||||
|
return main() ? main()->api() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
void showSettings() {
|
void showSettings() {
|
||||||
Window *w(wnd());
|
Window *w(wnd());
|
||||||
if (w) w->showSettings();
|
if (w) w->showSettings();
|
||||||
|
@ -590,7 +596,7 @@ namespace App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void feedMsgs(const MTPVector<MTPMessage> &msgs, bool newMsgs) {
|
void feedMsgs(const MTPVector<MTPMessage> &msgs, int msgsState) {
|
||||||
const QVector<MTPMessage> &v(msgs.c_vector().v);
|
const QVector<MTPMessage> &v(msgs.c_vector().v);
|
||||||
QMap<int32, int32> msgsIds;
|
QMap<int32, int32> msgsIds;
|
||||||
for (int32 i = 0, l = v.size(); i < l; ++i) {
|
for (int32 i = 0, l = v.size(); i < l; ++i) {
|
||||||
|
@ -598,12 +604,11 @@ namespace App {
|
||||||
switch (msg.type()) {
|
switch (msg.type()) {
|
||||||
case mtpc_message: msgsIds.insert(msg.c_message().vid.v, i); break;
|
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_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;
|
case mtpc_messageService: msgsIds.insert(msg.c_messageService().vid.v, i); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (QMap<int32, int32>::const_iterator i = msgsIds.cbegin(), e = msgsIds.cend(); i != e; ++i) {
|
for (QMap<int32, int32>::const_iterator i = msgsIds.cbegin(), e = msgsIds.cend(); i != e; ++i) {
|
||||||
histories().addToBack(v[*i], newMsgs ? 1 : 0);
|
histories().addToBack(v[*i], msgsState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -646,6 +651,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) {
|
void feedWereDeleted(const QVector<MTPint> &msgsIds) {
|
||||||
bool resized = false;
|
bool resized = false;
|
||||||
for (QVector<MTPint>::const_iterator i = msgsIds.cbegin(), e = msgsIds.cend(); i != e; ++i) {
|
for (QVector<MTPint>::const_iterator i = msgsIds.cbegin(), e = msgsIds.cend(); i != e; ++i) {
|
||||||
|
@ -683,30 +702,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);
|
UserData *user = userLoaded(userId.v);
|
||||||
if (user) {
|
if (user) {
|
||||||
bool wasContact = (user->contact > 0);
|
bool wasContact = (user->contact > 0);
|
||||||
switch (myLink.type()) {
|
switch (myLink.type()) {
|
||||||
case mtpc_contacts_myLinkContact:
|
case mtpc_contactLinkContact:
|
||||||
user->contact = 1;
|
user->contact = 1;
|
||||||
break;
|
break;
|
||||||
case mtpc_contacts_myLinkEmpty:
|
case mtpc_contactLinkHasPhone:
|
||||||
case mtpc_contacts_myLinkRequested:
|
user->contact = 0;
|
||||||
if (myLink.type() == mtpc_contacts_myLinkRequested && myLink.c_contacts_myLinkRequested().vcontact.v) {
|
break;
|
||||||
user->contact = 1;
|
case mtpc_contactLinkNone:
|
||||||
} else {
|
case mtpc_contactLinkUnknown:
|
||||||
switch (foreignLink.type()) {
|
user->contact = -1;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (user->contact > 0) {
|
if (user->contact > 0) {
|
||||||
|
@ -736,7 +745,6 @@ namespace App {
|
||||||
const MTPMessageMedia *media = 0;
|
const MTPMessageMedia *media = 0;
|
||||||
switch (msg.type()) {
|
switch (msg.type()) {
|
||||||
case mtpc_message: media = &msg.c_message().vmedia; break;
|
case mtpc_message: media = &msg.c_message().vmedia; break;
|
||||||
case mtpc_messageForwarded: media = &msg.c_messageForwarded().vmedia; break;
|
|
||||||
}
|
}
|
||||||
if (media) {
|
if (media) {
|
||||||
MsgsData::iterator i = msgsData.find(msgId);
|
MsgsData::iterator i = msgsData.find(msgId);
|
||||||
|
@ -1151,8 +1159,20 @@ namespace App {
|
||||||
result->thumb = thumb;
|
result->thumb = thumb;
|
||||||
result->dc = dc;
|
result->dc = dc;
|
||||||
result->size = size;
|
result->size = size;
|
||||||
} else if (result->thumb->isNull() && !thumb->isNull()) {
|
} else {
|
||||||
result->thumb = thumb;
|
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 +1233,14 @@ namespace App {
|
||||||
return ::histories;
|
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);
|
Histories::const_iterator i = ::histories.constFind(peer);
|
||||||
if (i == ::histories.cend()) {
|
if (i == ::histories.cend()) {
|
||||||
i = App::histories().insert(peer, new History(peer));
|
i = App::histories().insert(peer, new History(peer));
|
||||||
i.value()->setUnreadCount(unreadCnt, false);
|
i.value()->setUnreadCount(unreadCnt, false);
|
||||||
|
if (maxInboxRead) {
|
||||||
|
i.value()->inboxReadTill = maxInboxRead;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return i.value();
|
return i.value();
|
||||||
}
|
}
|
||||||
|
@ -1236,6 +1259,22 @@ namespace App {
|
||||||
}
|
}
|
||||||
|
|
||||||
void itemReplaced(HistoryItem *oldItem, HistoryItem *newItem) {
|
void itemReplaced(HistoryItem *oldItem, HistoryItem *newItem) {
|
||||||
|
if (HistoryReply *r = oldItem->toHistoryReply()) {
|
||||||
|
QMap<HistoryReply*, bool> &replies(::repliesTo[r->replyToMessage()]);
|
||||||
|
replies.remove(r);
|
||||||
|
if (HistoryReply *n = newItem->toHistoryReply()) {
|
||||||
|
replies.insert(n, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RepliesTo::iterator i = ::repliesTo.find(oldItem);
|
||||||
|
if (i != ::repliesTo.cend() && oldItem != newItem) {
|
||||||
|
QMap<HistoryReply*, bool> replies = i.value();
|
||||||
|
::repliesTo.erase(i);
|
||||||
|
::repliesTo[newItem] = replies;
|
||||||
|
for (QMap<HistoryReply*, bool>::iterator i = replies.begin(), e = replies.end(); i != e; ++i) {
|
||||||
|
i.key()->replyToReplaced(oldItem, newItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
newItem->history()->itemReplaced(oldItem, newItem);
|
newItem->history()->itemReplaced(oldItem, newItem);
|
||||||
if (App::main()) App::main()->itemReplaced(oldItem, newItem);
|
if (App::main()) App::main()->itemReplaced(oldItem, newItem);
|
||||||
if (App::hoveredItem() == oldItem) App::hoveredItem(newItem);
|
if (App::hoveredItem() == oldItem) App::hoveredItem(newItem);
|
||||||
|
@ -1294,6 +1333,13 @@ namespace App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
historyItemDetached(item);
|
historyItemDetached(item);
|
||||||
|
RepliesTo::iterator j = ::repliesTo.find(item);
|
||||||
|
if (j != ::repliesTo.cend()) {
|
||||||
|
for (QMap<HistoryReply*, bool>::const_iterator k = j.value().cbegin(), e = j.value().cend(); k != e; ++k) {
|
||||||
|
k.key()->replyToReplaced(item, 0);
|
||||||
|
}
|
||||||
|
::repliesTo.erase(j);
|
||||||
|
}
|
||||||
if (App::main() && !App::quiting()) {
|
if (App::main() && !App::quiting()) {
|
||||||
App::main()->itemRemoved(item);
|
App::main()->itemRemoved(item);
|
||||||
}
|
}
|
||||||
|
@ -1344,12 +1390,28 @@ namespace App {
|
||||||
::videoItems.clear();
|
::videoItems.clear();
|
||||||
::audioItems.clear();
|
::audioItems.clear();
|
||||||
::documentItems.clear();
|
::documentItems.clear();
|
||||||
|
::repliesTo.clear();
|
||||||
lastPhotos.clear();
|
lastPhotos.clear();
|
||||||
lastPhotosMap.clear();
|
lastPhotosMap.clear();
|
||||||
::self = 0;
|
::self = 0;
|
||||||
if (App::wnd()) App::wnd()->updateGlobalMenu();
|
if (App::wnd()) App::wnd()->updateGlobalMenu();
|
||||||
}
|
}
|
||||||
/* // don't delete history without deleting its' peerdata
|
|
||||||
|
void historyRegReply(HistoryReply *reply, HistoryItem *to) {
|
||||||
|
::repliesTo[to].insert(reply, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void historyUnregReply(HistoryReply *reply, HistoryItem *to) {
|
||||||
|
RepliesTo::iterator i = ::repliesTo.find(to);
|
||||||
|
if (i != ::repliesTo.cend()) {
|
||||||
|
i.value().remove(reply);
|
||||||
|
if (i.value().isEmpty()) {
|
||||||
|
::repliesTo.erase(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* // don't delete history without deleting its' peerdata
|
||||||
void deleteHistory(const PeerId &peer) {
|
void deleteHistory(const PeerId &peer) {
|
||||||
Histories::iterator i = ::histories.find(peer);
|
Histories::iterator i = ::histories.find(peer);
|
||||||
if (i != ::histories.end()) {
|
if (i != ::histories.end()) {
|
||||||
|
@ -1644,9 +1706,9 @@ namespace App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void openUserByName(const QString &username) {
|
void openUserByName(const QString &username, bool toProfile) {
|
||||||
if (App::main()) {
|
if (App::main()) {
|
||||||
App::main()->openUserByName(username);
|
App::main()->openUserByName(username, toProfile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ class Application;
|
||||||
class Window;
|
class Window;
|
||||||
class MainWidget;
|
class MainWidget;
|
||||||
class SettingsWidget;
|
class SettingsWidget;
|
||||||
|
class ApiWrap;
|
||||||
class Font;
|
class Font;
|
||||||
class Color;
|
class Color;
|
||||||
class FileUploader;
|
class FileUploader;
|
||||||
|
@ -41,6 +42,7 @@ namespace App {
|
||||||
SettingsWidget *settings();
|
SettingsWidget *settings();
|
||||||
bool passcoded();
|
bool passcoded();
|
||||||
FileUploader *uploader();
|
FileUploader *uploader();
|
||||||
|
ApiWrap *api();
|
||||||
|
|
||||||
void showSettings();
|
void showSettings();
|
||||||
void logOut();
|
void logOut();
|
||||||
|
@ -74,11 +76,13 @@ namespace App {
|
||||||
void feedParticipants(const MTPChatParticipants &p);
|
void feedParticipants(const MTPChatParticipants &p);
|
||||||
void feedParticipantAdd(const MTPDupdateChatParticipantAdd &d);
|
void feedParticipantAdd(const MTPDupdateChatParticipantAdd &d);
|
||||||
void feedParticipantDelete(const MTPDupdateChatParticipantDelete &d);
|
void feedParticipantDelete(const MTPDupdateChatParticipantDelete &d);
|
||||||
void feedMsgs(const MTPVector<MTPMessage> &msgs, bool newMsgs = false);
|
void feedMsgs(const MTPVector<MTPMessage> &msgs, int msgsState = 0); // 2 - new read message, 1 - new unread message, 0 - not new message, -1 - searched message
|
||||||
void feedWereRead(const QVector<MTPint> &msgsIds);
|
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 feedWereDeleted(const QVector<MTPint> &msgsIds);
|
||||||
void feedUserLinks(const MTPVector<MTPcontacts_Link> &links);
|
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);
|
void feedMessageMedia(MsgId msgId, const MTPMessage &msg);
|
||||||
int32 maxMsgId();
|
int32 maxMsgId();
|
||||||
|
|
||||||
|
@ -117,7 +121,7 @@ namespace App {
|
||||||
MTPPhoto photoFromUserPhoto(MTPint userId, MTPint date, const MTPUserProfilePhoto &photo);
|
MTPPhoto photoFromUserPhoto(MTPint userId, MTPint date, const MTPUserProfilePhoto &photo);
|
||||||
|
|
||||||
Histories &histories();
|
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);
|
History *historyLoaded(const PeerId &peer);
|
||||||
HistoryItem *histItemById(MsgId itemId);
|
HistoryItem *histItemById(MsgId itemId);
|
||||||
HistoryItem *historyRegItem(HistoryItem *item);
|
HistoryItem *historyRegItem(HistoryItem *item);
|
||||||
|
@ -125,6 +129,8 @@ namespace App {
|
||||||
void historyUnregItem(HistoryItem *item);
|
void historyUnregItem(HistoryItem *item);
|
||||||
void historyClearMsgs();
|
void historyClearMsgs();
|
||||||
void historyClearItems();
|
void historyClearItems();
|
||||||
|
void historyRegReply(HistoryReply *reply, HistoryItem *to);
|
||||||
|
void historyUnregReply(HistoryReply *reply, HistoryItem *to);
|
||||||
// void deleteHistory(const PeerId &peer);
|
// void deleteHistory(const PeerId &peer);
|
||||||
|
|
||||||
void historyRegRandom(uint64 randomId, MsgId itemId);
|
void historyRegRandom(uint64 randomId, MsgId itemId);
|
||||||
|
@ -179,7 +185,7 @@ namespace App {
|
||||||
void setProxySettings(QTcpSocket &socket);
|
void setProxySettings(QTcpSocket &socket);
|
||||||
|
|
||||||
void searchByHashtag(const QString &tag);
|
void searchByHashtag(const QString &tag);
|
||||||
void openUserByName(const QString &username);
|
void openUserByName(const QString &username, bool toProfile = false);
|
||||||
void openLocalUrl(const QString &url);
|
void openLocalUrl(const QString &url);
|
||||||
|
|
||||||
void initBackground(int32 id = 0, const QImage &p = QImage(), bool nowrite = false);
|
void initBackground(int32 id = 0, const QImage &p = QImage(), bool nowrite = false);
|
||||||
|
|
|
@ -478,7 +478,7 @@ void Application::uploadProfilePhoto(const QImage &tosend, const PeerId &peerId)
|
||||||
int32 filesize = 0;
|
int32 filesize = 0;
|
||||||
QByteArray data;
|
QByteArray data;
|
||||||
|
|
||||||
ReadyLocalMedia ready(ToPreparePhoto, file, filename, filesize, data, id, id, qsl("jpg"), peerId, photo, photoThumbs, MTP_documentEmpty(MTP_long(0)), jpeg, false);
|
ReadyLocalMedia ready(ToPreparePhoto, file, filename, filesize, data, id, id, qsl("jpg"), peerId, photo, photoThumbs, MTP_documentEmpty(MTP_long(0)), jpeg, false, 0);
|
||||||
|
|
||||||
connect(App::uploader(), SIGNAL(photoReady(MsgId, const MTPInputFile &)), App::app(), SLOT(photoUpdated(MsgId, const MTPInputFile &)), Qt::UniqueConnection);
|
connect(App::uploader(), SIGNAL(photoReady(MsgId, const MTPInputFile &)), App::app(), SLOT(photoUpdated(MsgId, const MTPInputFile &)), Qt::UniqueConnection);
|
||||||
|
|
||||||
|
@ -671,30 +671,28 @@ void Application::startApp() {
|
||||||
|
|
||||||
DEBUG_LOG(("Application Info: starting app.."));
|
DEBUG_LOG(("Application Info: starting app.."));
|
||||||
|
|
||||||
Local::ReadMapState state = Local::readMap(QByteArray());
|
|
||||||
if (state == Local::ReadMapPassNeeded) {
|
|
||||||
cSetHasPasscode(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUG_LOG(("Application Info: local map read.."));
|
|
||||||
|
|
||||||
window->createWinId();
|
window->createWinId();
|
||||||
window->init();
|
window->init();
|
||||||
|
|
||||||
DEBUG_LOG(("Application Info: window created.."));
|
DEBUG_LOG(("Application Info: window created.."));
|
||||||
|
|
||||||
if (state != Local::ReadMapPassNeeded) {
|
initImageLinkManager();
|
||||||
|
App::initMedia();
|
||||||
|
|
||||||
|
Local::ReadMapState state = Local::readMap(QByteArray());
|
||||||
|
if (state == Local::ReadMapPassNeeded) {
|
||||||
|
cSetHasPasscode(true);
|
||||||
|
DEBUG_LOG(("Application Info: passcode nneded.."));
|
||||||
|
} else {
|
||||||
|
DEBUG_LOG(("Application Info: local map read.."));
|
||||||
MTP::start();
|
MTP::start();
|
||||||
}
|
}
|
||||||
|
|
||||||
MTP::setStateChangedHandler(mtpStateChanged);
|
MTP::setStateChangedHandler(mtpStateChanged);
|
||||||
MTP::setSessionResetHandler(mtpSessionReset);
|
MTP::setSessionResetHandler(mtpSessionReset);
|
||||||
|
|
||||||
DEBUG_LOG(("Application Info: MTP started.."));
|
DEBUG_LOG(("Application Info: MTP started.."));
|
||||||
|
|
||||||
initImageLinkManager();
|
|
||||||
App::initMedia();
|
|
||||||
|
|
||||||
DEBUG_LOG(("Application Info: showing."));
|
DEBUG_LOG(("Application Info: showing."));
|
||||||
if (state == Local::ReadMapPassNeeded) {
|
if (state == Local::ReadMapPassNeeded) {
|
||||||
window->setupPasscode(false);
|
window->setupPasscode(false);
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 60 KiB |
Binary file not shown.
Before Width: | Height: | Size: 105 KiB After Width: | Height: | Size: 107 KiB |
|
@ -29,6 +29,7 @@ PhotoSendBox::PhotoSendBox(const ReadyLocalMedia &img) : _img(new ReadyLocalMedi
|
||||||
_compressed(this, lang(lng_send_image_compressed), cCompressPastedImage()),
|
_compressed(this, lang(lng_send_image_compressed), cCompressPastedImage()),
|
||||||
_sendButton(this, lang(lng_send_button), st::btnSelectDone),
|
_sendButton(this, lang(lng_send_button), st::btnSelectDone),
|
||||||
_cancelButton(this, lang(lng_cancel), st::btnSelectCancel),
|
_cancelButton(this, lang(lng_cancel), st::btnSelectCancel),
|
||||||
|
_replyTo(img.replyTo),
|
||||||
a_opacity(0, 1) {
|
a_opacity(0, 1) {
|
||||||
connect(&_sendButton, SIGNAL(clicked()), this, SLOT(onSend()));
|
connect(&_sendButton, SIGNAL(clicked()), this, SLOT(onSend()));
|
||||||
connect(&_cancelButton, SIGNAL(clicked()), this, SLOT(onCancel()));
|
connect(&_cancelButton, SIGNAL(clicked()), this, SLOT(onCancel()));
|
||||||
|
@ -95,12 +96,12 @@ PhotoSendBox::PhotoSendBox(const ReadyLocalMedia &img) : _img(new ReadyLocalMedi
|
||||||
resize(_width, _height);
|
resize(_width, _height);
|
||||||
}
|
}
|
||||||
|
|
||||||
PhotoSendBox::PhotoSendBox(const QString &phone, const QString &fname, const QString &lname) : _img(0),
|
PhotoSendBox::PhotoSendBox(const QString &phone, const QString &fname, const QString &lname, MsgId replyTo) : _img(0),
|
||||||
_thumbx(0), _thumby(0), _thumbw(0), _thumbh(0), _namew(0), _textw(0),
|
_thumbx(0), _thumby(0), _thumbw(0), _thumbh(0), _namew(0), _textw(0),
|
||||||
_compressed(this, lang(lng_send_image_compressed), true),
|
_compressed(this, lang(lng_send_image_compressed), true),
|
||||||
_sendButton(this, lang(lng_send_button), st::btnSelectDone),
|
_sendButton(this, lang(lng_send_button), st::btnSelectDone),
|
||||||
_cancelButton(this, lang(lng_cancel), st::btnSelectCancel),
|
_cancelButton(this, lang(lng_cancel), st::btnSelectCancel),
|
||||||
_phone(phone), _fname(fname), _lname(lname),
|
_phone(phone), _fname(fname), _lname(lname), _replyTo(replyTo),
|
||||||
a_opacity(0, 1) {
|
a_opacity(0, 1) {
|
||||||
connect(&_sendButton, SIGNAL(clicked()), this, SLOT(onSend()));
|
connect(&_sendButton, SIGNAL(clicked()), this, SLOT(onSend()));
|
||||||
connect(&_cancelButton, SIGNAL(clicked()), this, SLOT(onCancel()));
|
connect(&_cancelButton, SIGNAL(clicked()), this, SLOT(onCancel()));
|
||||||
|
@ -203,7 +204,7 @@ void PhotoSendBox::animStep(float64 ms) {
|
||||||
|
|
||||||
void PhotoSendBox::onSend(bool ctrlShiftEnter) {
|
void PhotoSendBox::onSend(bool ctrlShiftEnter) {
|
||||||
if (!_img) {
|
if (!_img) {
|
||||||
if (App::main()) App::main()->confirmShareContact(ctrlShiftEnter, _phone, _fname, _lname);
|
if (App::main()) App::main()->confirmShareContact(ctrlShiftEnter, _phone, _fname, _lname, _replyTo);
|
||||||
} else {
|
} else {
|
||||||
if (!_compressed.isHidden()) {
|
if (!_compressed.isHidden()) {
|
||||||
if (_compressed.checked() != cCompressPastedImage()) {
|
if (_compressed.checked() != cCompressPastedImage()) {
|
||||||
|
@ -215,7 +216,7 @@ void PhotoSendBox::onSend(bool ctrlShiftEnter) {
|
||||||
_img->ctrlShiftEnter = ctrlShiftEnter;
|
_img->ctrlShiftEnter = ctrlShiftEnter;
|
||||||
if (App::main()) App::main()->confirmSendImage(*_img);
|
if (App::main()) App::main()->confirmSendImage(*_img);
|
||||||
} else {
|
} else {
|
||||||
if (App::main()) App::main()->confirmSendImageUncompressed(ctrlShiftEnter);
|
if (App::main()) App::main()->confirmSendImageUncompressed(ctrlShiftEnter, _replyTo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
emit closed();
|
emit closed();
|
||||||
|
|
|
@ -26,7 +26,7 @@ class PhotoSendBox : public LayeredWidget {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
PhotoSendBox(const ReadyLocalMedia &img);
|
PhotoSendBox(const ReadyLocalMedia &img);
|
||||||
PhotoSendBox(const QString &phone, const QString &fname, const QString &lname);
|
PhotoSendBox(const QString &phone, const QString &fname, const QString &lname, MsgId replyTo);
|
||||||
void parentResized();
|
void parentResized();
|
||||||
void animStep(float64 ms);
|
void animStep(float64 ms);
|
||||||
void keyPressEvent(QKeyEvent *e);
|
void keyPressEvent(QKeyEvent *e);
|
||||||
|
@ -50,6 +50,7 @@ private:
|
||||||
QPixmap _thumb;
|
QPixmap _thumb;
|
||||||
|
|
||||||
QString _phone, _fname, _lname;
|
QString _phone, _fname, _lname;
|
||||||
|
MsgId _replyTo;
|
||||||
|
|
||||||
anim::fvalue a_opacity;
|
anim::fvalue a_opacity;
|
||||||
|
|
||||||
|
|
|
@ -17,9 +17,9 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
static const int32 AppVersion = 7020;
|
static const int32 AppVersion = 7021;
|
||||||
static const wchar_t *AppVersionStr = L"0.7.20";
|
static const wchar_t *AppVersionStr = L"0.7.21";
|
||||||
static const bool DevChannel = false;
|
static const bool DevChannel = true;
|
||||||
|
|
||||||
static const wchar_t *AppNameOld = L"Telegram Win (Unofficial)";
|
static const wchar_t *AppNameOld = L"Telegram Win (Unofficial)";
|
||||||
static const wchar_t *AppName = L"Telegram Desktop";
|
static const wchar_t *AppName = L"Telegram Desktop";
|
||||||
|
@ -277,7 +277,7 @@ enum {
|
||||||
MaxPhotosInMemory = 50, // try to clear some memory after 50 photos are created
|
MaxPhotosInMemory = 50, // try to clear some memory after 50 photos are created
|
||||||
NoUpdatesTimeout = 180 * 1000, // if nothing is received in 3 min we getDifference
|
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
|
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
|
MemoryForImageCache = 64 * 1024 * 1024, // after 64mb of unpacked images we try to clear some memory
|
||||||
NotifyWindowsCount = 3, // 3 desktop notifies at the same time
|
NotifyWindowsCount = 3, // 3 desktop notifies at the same time
|
||||||
|
|
|
@ -742,7 +742,7 @@ void DialogsListWidget::clearFilter() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogsListWidget::addDialog(const MTPDdialog &dialog) {
|
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::DialogLinks links = dialogs.addToEnd(history);
|
||||||
history->dialogs = links;
|
history->dialogs = links;
|
||||||
contactsNoDialogs.del(history->peer);
|
contactsNoDialogs.del(history->peer);
|
||||||
|
|
|
@ -24,6 +24,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||||
#include "lang.h"
|
#include "lang.h"
|
||||||
|
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
|
#include "apiwrap.h"
|
||||||
|
|
||||||
Dropdown::Dropdown(QWidget *parent) : TWidget(parent),
|
Dropdown::Dropdown(QWidget *parent) : TWidget(parent),
|
||||||
_hiding(false), a_opacity(0), _shadow(st::dropdownShadow) {
|
_hiding(false), a_opacity(0), _shadow(st::dropdownShadow) {
|
||||||
|
@ -160,7 +161,7 @@ void Dropdown::showStart() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Dropdown::animStep(float64 ms) {
|
bool Dropdown::animStep(float64 ms) {
|
||||||
float64 dt = ms / 150;
|
float64 dt = ms / st::dropdownDuration;
|
||||||
bool res = true;
|
bool res = true;
|
||||||
if (dt >= 1) {
|
if (dt >= 1) {
|
||||||
a_opacity.finish();
|
a_opacity.finish();
|
||||||
|
@ -311,7 +312,7 @@ void DragArea::showStart() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DragArea::animStep(float64 ms) {
|
bool DragArea::animStep(float64 ms) {
|
||||||
float64 dt = ms / 150;
|
float64 dt = ms / st::dropdownDuration;
|
||||||
bool res = true;
|
bool res = true;
|
||||||
if (dt >= 1) {
|
if (dt >= 1) {
|
||||||
a_opacity.finish();
|
a_opacity.finish();
|
||||||
|
@ -764,7 +765,7 @@ void EmojiPan::fastHide() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EmojiPan::animStep(float64 ms) {
|
bool EmojiPan::animStep(float64 ms) {
|
||||||
float64 dt = ms / 150;
|
float64 dt = ms / st::dropdownDuration;
|
||||||
bool res = true;
|
bool res = true;
|
||||||
if (dt >= 1) {
|
if (dt >= 1) {
|
||||||
a_opacity.finish();
|
a_opacity.finish();
|
||||||
|
@ -880,6 +881,341 @@ void EmojiPan::onTabChange() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MentionsInner::MentionsInner(MentionsDropdown *parent, MentionRows *rows) : _parent(parent), _rows(rows), _sel(-1), _mouseSel(false) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void MentionsInner::paintEvent(QPaintEvent *e) {
|
||||||
|
QPainter p(this);
|
||||||
|
|
||||||
|
int32 atwidth = st::mentionFont->m.width('@'), availwidth = width() - 2 * st::mentionPadding.left() - st::mentionPhotoSize - 2 * st::mentionPadding.right();
|
||||||
|
|
||||||
|
int32 from = qFloor(e->rect().top() / st::mentionHeight), to = qFloor(e->rect().bottom() / st::mentionHeight) + 1, last = _rows->size();
|
||||||
|
for (int32 i = from; i < to; ++i) {
|
||||||
|
if (i >= last) break;
|
||||||
|
|
||||||
|
if (i == _sel) p.fillRect(0, i * st::mentionHeight, width(), st::mentionHeight, st::dlgHoverBG->b);
|
||||||
|
|
||||||
|
UserData *user = _rows->at(last - i - 1);
|
||||||
|
QString uname = user->username;
|
||||||
|
int32 unamewidth = atwidth + st::mentionFont->m.width(uname), namewidth = user->nameText.maxWidth();
|
||||||
|
if (availwidth < unamewidth + namewidth) {
|
||||||
|
namewidth = (availwidth * namewidth) / (namewidth + unamewidth);
|
||||||
|
unamewidth = availwidth - namewidth;
|
||||||
|
uname = st::mentionFont->m.elidedText('@' + uname, Qt::ElideRight, unamewidth);
|
||||||
|
} else {
|
||||||
|
uname = '@' + uname;
|
||||||
|
}
|
||||||
|
user->photo->load();
|
||||||
|
p.drawPixmap(st::mentionPadding.left(), i * st::mentionHeight + st::mentionPadding.top(), user->photo->pix(st::mentionPhotoSize));
|
||||||
|
user->nameText.drawElided(p, 2 * st::mentionPadding.left() + st::mentionPhotoSize, i * st::mentionHeight + st::mentionTop, namewidth);
|
||||||
|
p.setFont(st::mentionFont->f);
|
||||||
|
p.drawText(2 * st::mentionPadding.left() + st::mentionPhotoSize + namewidth + st::mentionPadding.right(), i * st::mentionHeight + st::mentionTop + st::mentionFont->ascent, uname);
|
||||||
|
}
|
||||||
|
|
||||||
|
p.fillRect(cWideMode() ? st::dlgShadow : 0, _parent->innerTop(), width() - (cWideMode() ? st::dlgShadow : 0), st::titleShadow, st::titleShadowColor->b);
|
||||||
|
p.fillRect(cWideMode() ? st::dlgShadow : 0, _parent->innerBottom() - st::titleShadow, width() - (cWideMode() ? st::dlgShadow : 0), st::titleShadow, st::titleShadowColor->b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MentionsInner::mouseMoveEvent(QMouseEvent *e) {
|
||||||
|
_mousePos = mapToGlobal(e->pos());
|
||||||
|
_mouseSel = true;
|
||||||
|
onUpdateSelected(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MentionsInner::clearSel() {
|
||||||
|
_mouseSel = false;
|
||||||
|
setSel(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MentionsInner::moveSel(int direction) {
|
||||||
|
_mouseSel = false;
|
||||||
|
if (_sel >= _rows->size() || _sel < 0) {
|
||||||
|
if (direction < 0) setSel(_rows->size() - 1, true);
|
||||||
|
return (_sel >= 0 && _sel < _rows->size());
|
||||||
|
}
|
||||||
|
if (_sel > 0 || direction > 0) {
|
||||||
|
setSel((_sel + direction >= _rows->size()) ? -1 : (_sel + direction), true);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MentionsInner::select() {
|
||||||
|
if (_sel >= 0 && _sel < _rows->size()) {
|
||||||
|
emit mentioned(_rows->at(_rows->size() - _sel - 1)->username);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MentionsInner::mousePressEvent(QMouseEvent *e) {
|
||||||
|
_mousePos = mapToGlobal(e->pos());
|
||||||
|
_mouseSel = true;
|
||||||
|
onUpdateSelected(true);
|
||||||
|
if (e->button() == Qt::LeftButton) {
|
||||||
|
select();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MentionsInner::enterEvent(QEvent *e) {
|
||||||
|
setMouseTracking(true);
|
||||||
|
_mousePos = QCursor::pos();
|
||||||
|
onUpdateSelected(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MentionsInner::leaveEvent(QEvent *e) {
|
||||||
|
setMouseTracking(false);
|
||||||
|
if (_sel >= 0) {
|
||||||
|
setSel(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MentionsInner::setSel(int sel, bool scroll) {
|
||||||
|
_sel = sel;
|
||||||
|
parentWidget()->update();
|
||||||
|
if (scroll && _sel >= 0 && _sel < _rows->size()) emit mustScrollTo(_sel * st::mentionHeight, (_sel + 1) * st::mentionHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MentionsInner::onUpdateSelected(bool force) {
|
||||||
|
QPoint mouse(mapFromGlobal(_mousePos));
|
||||||
|
if ((!force && !rect().contains(mouse)) || !_mouseSel) return;
|
||||||
|
|
||||||
|
int w = width(), mouseY = mouse.y();
|
||||||
|
int32 sel = mouseY / int32(st::mentionHeight);
|
||||||
|
if (sel < 0 || sel >= _rows->size()) {
|
||||||
|
sel = -1;
|
||||||
|
}
|
||||||
|
if (sel != _sel) {
|
||||||
|
setSel(sel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MentionsInner::onParentGeometryChanged() {
|
||||||
|
_mousePos = QCursor::pos();
|
||||||
|
if (rect().contains(mapFromGlobal(_mousePos))) {
|
||||||
|
setMouseTracking(true);
|
||||||
|
onUpdateSelected(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MentionsDropdown::MentionsDropdown(QWidget *parent) : QWidget(parent),
|
||||||
|
_scroll(this, st::mentionScroll), _inner(this, &_rows), _chat(0), _hiding(false), a_opacity(0), _shadow(st::dropdownShadow) {
|
||||||
|
_hideTimer.setSingleShot(true);
|
||||||
|
connect(&_hideTimer, SIGNAL(timeout()), this, SLOT(hideStart()));
|
||||||
|
connect(&_inner, SIGNAL(mentioned(QString)), this, SIGNAL(mentioned(QString)));
|
||||||
|
connect(&_inner, SIGNAL(mustScrollTo(int,int)), &_scroll, SLOT(scrollToY(int,int)));
|
||||||
|
|
||||||
|
setFocusPolicy(Qt::NoFocus);
|
||||||
|
_scroll.setFocusPolicy(Qt::NoFocus);
|
||||||
|
_scroll.viewport()->setFocusPolicy(Qt::NoFocus);
|
||||||
|
|
||||||
|
_inner.setGeometry(rect());
|
||||||
|
_scroll.setGeometry(rect());
|
||||||
|
|
||||||
|
_scroll.setWidget(&_inner);
|
||||||
|
_scroll.show();
|
||||||
|
_inner.show();
|
||||||
|
|
||||||
|
connect(&_scroll, SIGNAL(geometryChanged()), &_inner, SLOT(onParentGeometryChanged()));
|
||||||
|
connect(&_scroll, SIGNAL(scrolled()), &_inner, SLOT(onUpdateSelected()));
|
||||||
|
|
||||||
|
if (cPlatform() == dbipMac) {
|
||||||
|
connect(App::wnd()->windowHandle(), SIGNAL(activeChanged()), this, SLOT(onWndActiveChanged()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MentionsDropdown::paintEvent(QPaintEvent *e) {
|
||||||
|
QPainter p(this);
|
||||||
|
|
||||||
|
if (animating()) {
|
||||||
|
p.setOpacity(a_opacity.current());
|
||||||
|
p.drawPixmap(0, 0, _cache);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
p.fillRect(rect(), st::white->b);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void MentionsDropdown::showFiltered(ChatData *chat, QString start) {
|
||||||
|
_chat = chat;
|
||||||
|
start = start.toLower();
|
||||||
|
bool toDown = (_filter != start);
|
||||||
|
if (toDown) {
|
||||||
|
_filter = start;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 now = unixtime();
|
||||||
|
QMultiMap<int32, UserData*> ordered;
|
||||||
|
MentionRows rows;
|
||||||
|
rows.reserve(_chat->participants.isEmpty() ? _chat->lastAuthors.size() : _chat->participants.size());
|
||||||
|
if (_chat->participants.isEmpty()) {
|
||||||
|
if (_chat->count > 0) {
|
||||||
|
App::api()->requestFullPeer(_chat);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (ChatData::Participants::const_iterator i = _chat->participants.cbegin(), e = _chat->participants.cend(); i != e; ++i) {
|
||||||
|
UserData *user = i.key();
|
||||||
|
if (user->username.isEmpty()) continue;
|
||||||
|
if (!_filter.isEmpty() && !user->username.startsWith(_filter, Qt::CaseInsensitive)) continue;
|
||||||
|
ordered.insertMulti(App::onlineForSort(user->onlineTill, now), user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (MentionRows::const_iterator i = _chat->lastAuthors.cbegin(), e = _chat->lastAuthors.cend(); i != e; ++i) {
|
||||||
|
UserData *user = *i;
|
||||||
|
if (user->username.isEmpty()) continue;
|
||||||
|
if (!_filter.isEmpty() && !user->username.startsWith(_filter, Qt::CaseInsensitive)) continue;
|
||||||
|
rows.push_back(user);
|
||||||
|
if (!ordered.isEmpty()) {
|
||||||
|
ordered.remove(App::onlineForSort(user->onlineTill, now), user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!ordered.isEmpty()) {
|
||||||
|
for (QMultiMap<int32, UserData*>::const_iterator i = ordered.cend(), b = ordered.cbegin(); i != b;) {
|
||||||
|
--i;
|
||||||
|
rows.push_back(i.value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rows.isEmpty()) {
|
||||||
|
if (!isHidden()) {
|
||||||
|
hideStart();
|
||||||
|
_rows.clear();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_rows = rows;
|
||||||
|
bool hidden = _hiding || isHidden();
|
||||||
|
if (hidden) {
|
||||||
|
show();
|
||||||
|
_scroll.show();
|
||||||
|
}
|
||||||
|
recount(toDown);
|
||||||
|
if (hidden) {
|
||||||
|
hide();
|
||||||
|
showStart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MentionsDropdown::setBoundings(QRect boundings) {
|
||||||
|
_boundings = boundings;
|
||||||
|
resize(_boundings.width(), height());
|
||||||
|
_scroll.resize(size());
|
||||||
|
_inner.resize(width(), _inner.height());
|
||||||
|
recount();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MentionsDropdown::recount(bool toDown) {
|
||||||
|
int32 h = _rows.size() * st::mentionHeight, oldst = _scroll.scrollTop(), st = oldst;
|
||||||
|
|
||||||
|
if (_inner.height() != h) {
|
||||||
|
st += h - _inner.height();
|
||||||
|
_inner.resize(width(), h);
|
||||||
|
}
|
||||||
|
if (h > _boundings.height()) h = _boundings.height();
|
||||||
|
if (h > 5 * st::mentionHeight) h = 5 * st::mentionHeight;
|
||||||
|
if (height() != h) {
|
||||||
|
st += _scroll.height() - h;
|
||||||
|
setGeometry(0, _boundings.height() - h, width(), h);
|
||||||
|
_scroll.resize(width(), h);
|
||||||
|
} else if (y() != _boundings.height() - h) {
|
||||||
|
move(0, _boundings.height() - h);
|
||||||
|
}
|
||||||
|
if (toDown) st = _scroll.scrollTopMax();
|
||||||
|
if (st != oldst) _scroll.scrollToY(st);
|
||||||
|
if (toDown) _inner.clearSel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MentionsDropdown::fastHide() {
|
||||||
|
if (animating()) {
|
||||||
|
anim::stop(this);
|
||||||
|
}
|
||||||
|
a_opacity = anim::fvalue(0, 0);
|
||||||
|
_hideTimer.stop();
|
||||||
|
hideFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MentionsDropdown::hideStart() {
|
||||||
|
if (!_hiding) {
|
||||||
|
if (_cache.isNull()) {
|
||||||
|
_scroll.show();
|
||||||
|
_cache = myGrab(this, rect());
|
||||||
|
}
|
||||||
|
_scroll.hide();
|
||||||
|
_hiding = true;
|
||||||
|
a_opacity.start(0);
|
||||||
|
anim::start(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MentionsDropdown::hideFinish() {
|
||||||
|
hide();
|
||||||
|
_hiding = false;
|
||||||
|
_filter = qsl("-");
|
||||||
|
_inner.clearSel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MentionsDropdown::showStart() {
|
||||||
|
if (!isHidden() && a_opacity.current() == 1 && !_hiding) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (_cache.isNull()) {
|
||||||
|
_scroll.show();
|
||||||
|
_cache = myGrab(this, rect());
|
||||||
|
}
|
||||||
|
_scroll.hide();
|
||||||
|
_hiding = false;
|
||||||
|
show();
|
||||||
|
a_opacity.start(1);
|
||||||
|
anim::start(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MentionsDropdown::animStep(float64 ms) {
|
||||||
|
float64 dt = ms / st::dropdownDuration;
|
||||||
|
bool res = true;
|
||||||
|
if (dt >= 1) {
|
||||||
|
a_opacity.finish();
|
||||||
|
_cache = QPixmap();
|
||||||
|
if (_hiding) {
|
||||||
|
hideFinish();
|
||||||
|
} else {
|
||||||
|
_scroll.show();
|
||||||
|
_inner.clearSel();
|
||||||
|
}
|
||||||
|
res = false;
|
||||||
|
} else {
|
||||||
|
a_opacity.update(dt, anim::linear);
|
||||||
|
}
|
||||||
|
update();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 MentionsDropdown::innerTop() {
|
||||||
|
return _scroll.scrollTop();
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 MentionsDropdown::innerBottom() {
|
||||||
|
return _scroll.scrollTop() + _scroll.height();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MentionsDropdown::eventFilter(QObject *obj, QEvent *e) {
|
||||||
|
if (isHidden()) return QWidget::eventFilter(obj, e);
|
||||||
|
if (e->type() == QEvent::KeyPress) {
|
||||||
|
QKeyEvent *ev = static_cast<QKeyEvent*>(e);
|
||||||
|
if (ev->key() == Qt::Key_Up) {
|
||||||
|
_inner.moveSel(-1);
|
||||||
|
return true;
|
||||||
|
} else if (ev->key() == Qt::Key_Down) {
|
||||||
|
return _inner.moveSel(1);
|
||||||
|
} else if (ev->key() == Qt::Key_Enter || ev->key() == Qt::Key_Return) {
|
||||||
|
return _inner.select();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QWidget::eventFilter(obj, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
MentionsDropdown::~MentionsDropdown() {
|
||||||
|
}
|
||||||
|
|
||||||
//StickerPanInner::StickerPanInner(QWidget *parent) : QWidget(parent), _emoji(0), _selected(-1), _pressedSel(-1) {
|
//StickerPanInner::StickerPanInner(QWidget *parent) : QWidget(parent), _emoji(0), _selected(-1), _pressedSel(-1) {
|
||||||
// resize(StickerPadPerRow * st::stickerPanSize.width(), EmojiPadRowsPerPage * st::emojiPanSize.height() - st::emojiPanSub);
|
// resize(StickerPadPerRow * st::stickerPanSize.width(), EmojiPadRowsPerPage * st::emojiPanSize.height() - st::emojiPanSub);
|
||||||
// setMouseTracking(true);
|
// setMouseTracking(true);
|
||||||
|
@ -1124,7 +1460,7 @@ void EmojiPan::onTabChange() {
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//bool StickerPan::animStep(float64 ms) {
|
//bool StickerPan::animStep(float64 ms) {
|
||||||
// float64 dt = ms / 150;
|
// float64 dt = ms / st::dropdownDuration;
|
||||||
// bool res = true;
|
// bool res = true;
|
||||||
// if (dt >= 1) {
|
// if (dt >= 1) {
|
||||||
// a_opacity.finish();
|
// a_opacity.finish();
|
||||||
|
|
|
@ -227,6 +227,109 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef QList<UserData*> MentionRows;
|
||||||
|
|
||||||
|
class MentionsDropdown;
|
||||||
|
class MentionsInner : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
MentionsInner(MentionsDropdown *parent, MentionRows *rows);
|
||||||
|
|
||||||
|
void paintEvent(QPaintEvent *e);
|
||||||
|
|
||||||
|
void enterEvent(QEvent *e);
|
||||||
|
void leaveEvent(QEvent *e);
|
||||||
|
|
||||||
|
void mousePressEvent(QMouseEvent *e);
|
||||||
|
void mouseMoveEvent(QMouseEvent *e);
|
||||||
|
|
||||||
|
void clearSel();
|
||||||
|
bool moveSel(int direction);
|
||||||
|
bool select();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
void mentioned(QString username);
|
||||||
|
void mustScrollTo(int scrollToTop, int scrollToBottom);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
void onParentGeometryChanged();
|
||||||
|
void onUpdateSelected(bool force = false);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void setSel(int sel, bool scroll = false);
|
||||||
|
|
||||||
|
MentionsDropdown *_parent;
|
||||||
|
MentionRows *_rows;
|
||||||
|
int32 _sel;
|
||||||
|
bool _mouseSel;
|
||||||
|
QPoint _mousePos;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class MentionsDropdown : public QWidget, public Animated {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
MentionsDropdown(QWidget *parent);
|
||||||
|
|
||||||
|
void paintEvent(QPaintEvent *e);
|
||||||
|
|
||||||
|
void fastHide();
|
||||||
|
|
||||||
|
void showFiltered(ChatData *chat, QString start);
|
||||||
|
void setBoundings(QRect boundings);
|
||||||
|
|
||||||
|
bool animStep(float64 ms);
|
||||||
|
|
||||||
|
int32 innerTop();
|
||||||
|
int32 innerBottom();
|
||||||
|
|
||||||
|
bool eventFilter(QObject *obj, QEvent *e);
|
||||||
|
|
||||||
|
~MentionsDropdown();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
void mentioned(QString username);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
void hideStart();
|
||||||
|
void hideFinish();
|
||||||
|
|
||||||
|
void showStart();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void recount(bool toDown = false);
|
||||||
|
|
||||||
|
QPixmap _cache;
|
||||||
|
MentionRows _rows;
|
||||||
|
|
||||||
|
ScrollArea _scroll;
|
||||||
|
MentionsInner _inner;
|
||||||
|
|
||||||
|
ChatData *_chat;
|
||||||
|
QString _filter;
|
||||||
|
QRect _boundings;
|
||||||
|
|
||||||
|
int32 _width, _height;
|
||||||
|
bool _hiding;
|
||||||
|
|
||||||
|
anim::fvalue a_opacity;
|
||||||
|
|
||||||
|
QTimer _hideTimer;
|
||||||
|
|
||||||
|
BoxShadow _shadow;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
//class StickerPanInner : public QWidget, public Animated {
|
//class StickerPanInner : public QWidget, public Animated {
|
||||||
// Q_OBJECT
|
// Q_OBJECT
|
||||||
//
|
//
|
||||||
|
|
|
@ -180,6 +180,79 @@ EmojiPtr FlatTextarea::getSingleEmoji() const {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FlatTextarea::getMentionStart(QString &start) const {
|
||||||
|
int32 pos = textCursor().position();
|
||||||
|
if (textCursor().anchor() != pos) return false;
|
||||||
|
|
||||||
|
QTextDocument *doc(document());
|
||||||
|
QTextBlock block = doc->findBlock(pos);
|
||||||
|
for (QTextBlock::Iterator iter = block.begin(); !iter.atEnd(); ++iter) {
|
||||||
|
QTextFragment fr(iter.fragment());
|
||||||
|
if (!fr.isValid()) continue;
|
||||||
|
|
||||||
|
int32 p = fr.position(), e = (p + fr.length());
|
||||||
|
if (p >= pos || e < pos) continue;
|
||||||
|
|
||||||
|
QTextCharFormat f = fr.charFormat();
|
||||||
|
if (f.isImageFormat()) continue;
|
||||||
|
|
||||||
|
QString t(fr.text());
|
||||||
|
for (int i = pos - p; i > 0; --i) {
|
||||||
|
if (t.at(i - 1) == '@') {
|
||||||
|
start = t.mid(i, pos - p - i);
|
||||||
|
return (start.isEmpty() || start.at(0).isLetter()) && (i < 2 || !(t.at(i - 2).isLetterOrNumber() || t.at(i - 2) == '_'));
|
||||||
|
}
|
||||||
|
if (pos - p - i > 31) break;
|
||||||
|
if (!t.at(i - 1).isLetterOrNumber() && t.at(i - 1) != '_') break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlatTextarea::onMentionInsert(QString mention) {
|
||||||
|
QTextCursor c(textCursor());
|
||||||
|
int32 pos = c.position();
|
||||||
|
|
||||||
|
QTextDocument *doc(document());
|
||||||
|
QTextBlock block = doc->findBlock(pos);
|
||||||
|
for (QTextBlock::Iterator iter = block.begin(); !iter.atEnd(); ++iter) {
|
||||||
|
QTextFragment fr(iter.fragment());
|
||||||
|
if (!fr.isValid()) continue;
|
||||||
|
|
||||||
|
int32 p = fr.position(), e = (p + fr.length());
|
||||||
|
if (p >= pos || e < pos) continue;
|
||||||
|
|
||||||
|
QTextCharFormat f = fr.charFormat();
|
||||||
|
if (f.isImageFormat()) continue;
|
||||||
|
|
||||||
|
QString t(fr.text());
|
||||||
|
for (int i = pos - p; i > 0; --i) {
|
||||||
|
if (t.at(i - 1) == '@') {
|
||||||
|
if ((i == pos - p || t.at(i).isLetter()) && (i < 2 || !(t.at(i - 2).isLetterOrNumber() || t.at(i - 2) == '_'))) {
|
||||||
|
c.setPosition(p + i, QTextCursor::MoveAnchor);
|
||||||
|
int till = p + i;
|
||||||
|
for (; (till < e) && (till - p - i < mention.size()); ++till) {
|
||||||
|
if (t.at(till - p).toLower() != mention.at(till - p - i).toLower()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (till - p - i == mention.size() && till < e && t.at(till - p) == ' ') {
|
||||||
|
++till;
|
||||||
|
}
|
||||||
|
c.setPosition(till, QTextCursor::KeepAnchor);
|
||||||
|
c.insertText(mention + ' ');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (pos - p - i > 31) break;
|
||||||
|
if (!t.at(i - 1).isLetterOrNumber() && t.at(i - 1) != '_') break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.insertText('@' + mention + ' ');
|
||||||
|
}
|
||||||
|
|
||||||
void FlatTextarea::getSingleEmojiFragment(QString &text, QTextFragment &fragment) const {
|
void FlatTextarea::getSingleEmojiFragment(QString &text, QTextFragment &fragment) const {
|
||||||
int32 end = textCursor().position(), start = end - 1;
|
int32 end = textCursor().position(), start = end - 1;
|
||||||
if (textCursor().anchor() != end) return;
|
if (textCursor().anchor() != end) return;
|
||||||
|
|
|
@ -49,6 +49,7 @@ public:
|
||||||
QSize minimumSizeHint() const;
|
QSize minimumSizeHint() const;
|
||||||
|
|
||||||
EmojiPtr getSingleEmoji() const;
|
EmojiPtr getSingleEmoji() const;
|
||||||
|
bool getMentionStart(QString &start) const;
|
||||||
void removeSingleEmoji();
|
void removeSingleEmoji();
|
||||||
QString getText(int32 start = 0, int32 end = -1) const;
|
QString getText(int32 start = 0, int32 end = -1) const;
|
||||||
bool hasText() const;
|
bool hasText() const;
|
||||||
|
@ -66,6 +67,8 @@ public slots:
|
||||||
void onUndoAvailable(bool avail);
|
void onUndoAvailable(bool avail);
|
||||||
void onRedoAvailable(bool avail);
|
void onRedoAvailable(bool avail);
|
||||||
|
|
||||||
|
void onMentionInsert(QString mention);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
void changed();
|
void changed();
|
||||||
|
|
|
@ -51,7 +51,7 @@ const QPixmap &Image::pix(int32 w, int32 h) const {
|
||||||
checkload();
|
checkload();
|
||||||
|
|
||||||
if (w <= 0 || !width() || !height()) {
|
if (w <= 0 || !width() || !height()) {
|
||||||
w = width() * cIntRetinaFactor();
|
w = width();
|
||||||
} else if (cRetina()) {
|
} else if (cRetina()) {
|
||||||
w *= cIntRetinaFactor();
|
w *= cIntRetinaFactor();
|
||||||
h *= cIntRetinaFactor();
|
h *= cIntRetinaFactor();
|
||||||
|
|
|
@ -132,11 +132,12 @@ namespace {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QRegularExpression reDomain(QString::fromUtf8("(?<![A-Za-z\\$0-9А-Яа-яёЁ\\-\\_%=])(?:([a-zA-Z]+)://)?((?:[A-Za-zА-яА-ЯёЁ0-9\\-\\_]+\\.){1,5}([A-Za-zрф\\-\\d]{2,22})(\\:\\d+)?)"));
|
const QRegularExpression reDomain(QString::fromUtf8("(?<![A-Za-z\\$0-9А-Яа-яёЁ\\-\\_%=\\.])(?:([a-zA-Z]+)://)?((?:[A-Za-zА-яА-ЯёЁ0-9\\-\\_]+\\.){1,5}([A-Za-zрф\\-\\d]{2,22})(\\:\\d+)?)"));
|
||||||
const QRegularExpression reExplicitDomain(QString::fromUtf8("(?<![A-Za-z\\$0-9А-Яа-яёЁ\\-\\_%=])(?:([a-zA-Z]+)://)((?:[A-Za-zА-яА-ЯёЁ0-9\\-\\_]+\\.){0,5}([A-Za-zрф\\-\\d]{2,22})(\\:\\d+)?)"));
|
const QRegularExpression reExplicitDomain(QString::fromUtf8("(?<![A-Za-z\\$0-9А-Яа-яёЁ\\-\\_%=\\.])(?:([a-zA-Z]+)://)((?:[A-Za-zА-яА-ЯёЁ0-9\\-\\_]+\\.){0,5}([A-Za-zрф\\-\\d]{2,22})(\\:\\d+)?)"));
|
||||||
const QRegularExpression reMailName(qsl("[a-zA-Z\\-_\\.0-9]{1,256}$"));
|
const QRegularExpression reMailName(qsl("[a-zA-Z\\-_\\.0-9]{1,256}$"));
|
||||||
const QRegularExpression reMailStart(qsl("^[a-zA-Z\\-_\\.0-9]{1,256}\\@"));
|
const QRegularExpression reMailStart(qsl("^[a-zA-Z\\-_\\.0-9]{1,256}\\@"));
|
||||||
const QRegularExpression reHashtag(qsl("(^|[\\s\\.,:;<>|'\"\\[\\]\\{\\}`\\~\\!\\%\\^\\*\\(\\)\\-\\+=\\x10])#[A-Za-z_\\.0-9]{2,20}([\\s\\.,:;<>|'\"\\[\\]\\{\\}`\\~\\!\\%\\^\\*\\(\\)\\-\\+=\\x10]|$)"));
|
const QRegularExpression reHashtag(qsl("(^|[\\s\\.,:;<>|'\"\\[\\]\\{\\}`\\~\\!\\%\\^\\*\\(\\)\\-\\+=\\x10])#[A-Za-z_\\.0-9]{2,20}([\\s\\.,:;<>|'\"\\[\\]\\{\\}`\\~\\!\\%\\^\\*\\(\\)\\-\\+=\\x10]|$)"));
|
||||||
|
const QRegularExpression reMention(qsl("(^|[\\s\\.,:;<>|'\"\\[\\]\\{\\}`\\~\\!\\%\\^\\*\\(\\)\\-\\+=\\x10])@[A-Za-z_0-9]{5,32}([\\s\\.,:;<>|'\"\\[\\]\\{\\}`\\~\\!\\%\\^\\*\\(\\)\\-\\+=\\x10]|$)"));
|
||||||
QSet<int32> validProtocols, validTopDomains;
|
QSet<int32> validProtocols, validTopDomains;
|
||||||
void initLinkSets();
|
void initLinkSets();
|
||||||
|
|
||||||
|
@ -418,7 +419,10 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void getLinkData(const QString &original, QString &result, int32 &fullDisplayed) {
|
void getLinkData(const QString &original, QString &result, int32 &fullDisplayed) {
|
||||||
if (!original.isEmpty() && original.at(0) == '#') {
|
if (!original.isEmpty() && original.at(0) == '@') {
|
||||||
|
result = original;
|
||||||
|
fullDisplayed = -3; // mention
|
||||||
|
} else if (!original.isEmpty() && original.at(0) == '#') {
|
||||||
result = original;
|
result = original;
|
||||||
fullDisplayed = -2; // hashtag
|
fullDisplayed = -2; // hashtag
|
||||||
} else if (reMailStart.match(original).hasMatch()) {
|
} else if (reMailStart.match(original).hasMatch()) {
|
||||||
|
@ -685,7 +689,9 @@ public:
|
||||||
_t->_links.resize(lnkIndex);
|
_t->_links.resize(lnkIndex);
|
||||||
const TextLinkData &data(links[lnkIndex - maxLnkIndex - 1]);
|
const TextLinkData &data(links[lnkIndex - maxLnkIndex - 1]);
|
||||||
TextLinkPtr lnk;
|
TextLinkPtr lnk;
|
||||||
if (data.fullDisplayed < -1) { // hashtag
|
if (data.fullDisplayed < -2) { // mention
|
||||||
|
lnk = TextLinkPtr(new MentionLink(data.url));
|
||||||
|
} else if (data.fullDisplayed < -1) { // hashtag
|
||||||
lnk = TextLinkPtr(new HashtagLink(data.url));
|
lnk = TextLinkPtr(new HashtagLink(data.url));
|
||||||
} else if (data.fullDisplayed < 0) { // email
|
} else if (data.fullDisplayed < 0) { // email
|
||||||
lnk = TextLinkPtr(new EmailLink(data.url));
|
lnk = TextLinkPtr(new EmailLink(data.url));
|
||||||
|
@ -716,7 +722,7 @@ private:
|
||||||
TextLinkData(const QString &url = QString(), int32 fullDisplayed = 1) : url(url), fullDisplayed(fullDisplayed) {
|
TextLinkData(const QString &url = QString(), int32 fullDisplayed = 1) : url(url), fullDisplayed(fullDisplayed) {
|
||||||
}
|
}
|
||||||
QString url;
|
QString url;
|
||||||
int32 fullDisplayed; // -2 - hashtag, -1 - email
|
int32 fullDisplayed; // -3 - mention, -2 - hashtag, -1 - email
|
||||||
};
|
};
|
||||||
typedef QVector<TextLinkData> TextLinks;
|
typedef QVector<TextLinkData> TextLinks;
|
||||||
TextLinks links;
|
TextLinks links;
|
||||||
|
@ -849,6 +855,12 @@ void TextLink::onClick(Qt::MouseButton button) const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MentionLink::onClick(Qt::MouseButton button) const {
|
||||||
|
if (button == Qt::LeftButton || button == Qt::MiddleButton) {
|
||||||
|
App::openUserByName(_tag.mid(1), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void HashtagLink::onClick(Qt::MouseButton button) const {
|
void HashtagLink::onClick(Qt::MouseButton button) const {
|
||||||
if (button == Qt::LeftButton || button == Qt::MiddleButton) {
|
if (button == Qt::LeftButton || button == Qt::MiddleButton) {
|
||||||
App::searchByHashtag(_tag);
|
App::searchByHashtag(_tag);
|
||||||
|
@ -4137,7 +4149,8 @@ LinkRanges textParseLinks(const QString &text, bool rich) {
|
||||||
QRegularExpressionMatch mDomain = reDomain.match(text, matchOffset);
|
QRegularExpressionMatch mDomain = reDomain.match(text, matchOffset);
|
||||||
QRegularExpressionMatch mExplicitDomain = reExplicitDomain.match(text, matchOffset);
|
QRegularExpressionMatch mExplicitDomain = reExplicitDomain.match(text, matchOffset);
|
||||||
QRegularExpressionMatch mHashtag = reHashtag.match(text, matchOffset);
|
QRegularExpressionMatch mHashtag = reHashtag.match(text, matchOffset);
|
||||||
if (!mDomain.hasMatch() && !mExplicitDomain.hasMatch() && !mHashtag.hasMatch()) break;
|
QRegularExpressionMatch mMention = reMention.match(text, matchOffset);
|
||||||
|
if (!mDomain.hasMatch() && !mExplicitDomain.hasMatch() && !mHashtag.hasMatch() && !mMention.hasMatch()) break;
|
||||||
|
|
||||||
LinkRange link;
|
LinkRange link;
|
||||||
int32 domainOffset = mDomain.hasMatch() ? mDomain.capturedStart() : INT_MAX,
|
int32 domainOffset = mDomain.hasMatch() ? mDomain.capturedStart() : INT_MAX,
|
||||||
|
@ -4145,7 +4158,9 @@ LinkRanges textParseLinks(const QString &text, bool rich) {
|
||||||
explicitDomainOffset = mExplicitDomain.hasMatch() ? mExplicitDomain.capturedStart() : INT_MAX,
|
explicitDomainOffset = mExplicitDomain.hasMatch() ? mExplicitDomain.capturedStart() : INT_MAX,
|
||||||
explicitDomainEnd = mExplicitDomain.hasMatch() ? mExplicitDomain.capturedEnd() : INT_MAX,
|
explicitDomainEnd = mExplicitDomain.hasMatch() ? mExplicitDomain.capturedEnd() : INT_MAX,
|
||||||
hashtagOffset = mHashtag.hasMatch() ? mHashtag.capturedStart() : INT_MAX,
|
hashtagOffset = mHashtag.hasMatch() ? mHashtag.capturedStart() : INT_MAX,
|
||||||
hashtagEnd = mHashtag.hasMatch() ? mHashtag.capturedEnd() : INT_MAX;
|
hashtagEnd = mHashtag.hasMatch() ? mHashtag.capturedEnd() : INT_MAX,
|
||||||
|
mentionOffset = mMention.hasMatch() ? mMention.capturedStart() : INT_MAX,
|
||||||
|
mentionEnd = mMention.hasMatch() ? mMention.capturedEnd() : INT_MAX;
|
||||||
if (mHashtag.hasMatch()) {
|
if (mHashtag.hasMatch()) {
|
||||||
if (!mHashtag.capturedRef(1).isEmpty()) {
|
if (!mHashtag.capturedRef(1).isEmpty()) {
|
||||||
++hashtagOffset;
|
++hashtagOffset;
|
||||||
|
@ -4154,12 +4169,35 @@ LinkRanges textParseLinks(const QString &text, bool rich) {
|
||||||
--hashtagEnd;
|
--hashtagEnd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (mMention.hasMatch()) {
|
||||||
|
if (!mMention.capturedRef(1).isEmpty()) {
|
||||||
|
++mentionOffset;
|
||||||
|
}
|
||||||
|
if (!mMention.capturedRef(2).isEmpty()) {
|
||||||
|
--mentionEnd;
|
||||||
|
}
|
||||||
|
if (!(start + mentionOffset + 1)->isLetter() || !(start + mentionEnd - 1)->isLetterOrNumber()) {
|
||||||
|
mentionOffset = mentionEnd = INT_MAX;
|
||||||
|
if (!mDomain.hasMatch() && !mExplicitDomain.hasMatch() && !mHashtag.hasMatch()) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (explicitDomainOffset < domainOffset) {
|
if (explicitDomainOffset < domainOffset) {
|
||||||
domainOffset = explicitDomainOffset;
|
domainOffset = explicitDomainOffset;
|
||||||
domainEnd = explicitDomainEnd;
|
domainEnd = explicitDomainEnd;
|
||||||
mDomain = mExplicitDomain;
|
mDomain = mExplicitDomain;
|
||||||
}
|
}
|
||||||
if (hashtagOffset < domainOffset) {
|
if (mentionOffset < hashtagOffset && mentionOffset < domainOffset) {
|
||||||
|
if (mentionOffset > nextCmd) {
|
||||||
|
const QChar *after = textSkipCommand(start + nextCmd, start + len);
|
||||||
|
if (after > start + nextCmd && mentionOffset < (after - start)) {
|
||||||
|
nextCmd = offset = matchOffset = after - start;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
link.from = start + mentionOffset;
|
||||||
|
link.len = start + mentionEnd - link.from;
|
||||||
|
} else if (hashtagOffset < domainOffset) {
|
||||||
if (hashtagOffset > nextCmd) {
|
if (hashtagOffset > nextCmd) {
|
||||||
const QChar *after = textSkipCommand(start + nextCmd, start + len);
|
const QChar *after = textSkipCommand(start + nextCmd, start + len);
|
||||||
if (after > start + nextCmd && hashtagOffset < (after - start)) {
|
if (after > start + nextCmd && hashtagOffset < (after - start)) {
|
||||||
|
|
|
@ -301,6 +301,32 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class MentionLink : public ITextLink {
|
||||||
|
public:
|
||||||
|
|
||||||
|
MentionLink(const QString &tag) : _tag(tag) {
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString &text() const {
|
||||||
|
return _tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
void onClick(Qt::MouseButton button) const;
|
||||||
|
|
||||||
|
const QString &readable() const {
|
||||||
|
return _tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString encoded() const {
|
||||||
|
return _tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
QString _tag;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
class HashtagLink : public ITextLink {
|
class HashtagLink : public ITextLink {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -25,10 +25,10 @@ public:
|
||||||
TWidget(QWidget *parent = 0) : QWidget(parent) {
|
TWidget(QWidget *parent = 0) : QWidget(parent) {
|
||||||
}
|
}
|
||||||
TWidget *tparent() {
|
TWidget *tparent() {
|
||||||
return dynamic_cast<TWidget*>(parentWidget());
|
return qobject_cast<TWidget*>(parentWidget());
|
||||||
}
|
}
|
||||||
const TWidget *tparent() const {
|
const TWidget *tparent() const {
|
||||||
return dynamic_cast<const TWidget*>(parentWidget());
|
return qobject_cast<const TWidget*>(parentWidget());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void leaveToChildEvent(QEvent *e) { // e -- from enterEvent() of child TWidget
|
virtual void leaveToChildEvent(QEvent *e) { // e -- from enterEvent() of child TWidget
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -164,6 +164,8 @@ struct ChatData : public PeerData {
|
||||||
Participants participants;
|
Participants participants;
|
||||||
typedef QMap<UserData*, bool> CanKick;
|
typedef QMap<UserData*, bool> CanKick;
|
||||||
CanKick cankick;
|
CanKick cankick;
|
||||||
|
typedef QList<UserData*> LastAuthors;
|
||||||
|
LastAuthors lastAuthors;
|
||||||
ImagePtr photoFull;
|
ImagePtr photoFull;
|
||||||
PhotoId photoId;
|
PhotoId photoId;
|
||||||
// geo
|
// geo
|
||||||
|
@ -176,6 +178,7 @@ struct PhotoData {
|
||||||
}
|
}
|
||||||
void forget() {
|
void forget() {
|
||||||
thumb->forget();
|
thumb->forget();
|
||||||
|
replyPreview->forget();
|
||||||
medium->forget();
|
medium->forget();
|
||||||
full->forget();
|
full->forget();
|
||||||
}
|
}
|
||||||
|
@ -183,7 +186,7 @@ struct PhotoData {
|
||||||
uint64 access;
|
uint64 access;
|
||||||
int32 user;
|
int32 user;
|
||||||
int32 date;
|
int32 date;
|
||||||
ImagePtr thumb;
|
ImagePtr thumb, replyPreview;
|
||||||
ImagePtr medium;
|
ImagePtr medium;
|
||||||
ImagePtr full;
|
ImagePtr full;
|
||||||
ChatData *chat; // for chat photos connection
|
ChatData *chat; // for chat photos connection
|
||||||
|
@ -223,6 +226,7 @@ struct VideoData {
|
||||||
|
|
||||||
void forget() {
|
void forget() {
|
||||||
thumb->forget();
|
thumb->forget();
|
||||||
|
replyPreview->forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
void save(const QString &toFile);
|
void save(const QString &toFile);
|
||||||
|
@ -258,7 +262,7 @@ struct VideoData {
|
||||||
int32 date;
|
int32 date;
|
||||||
int32 duration;
|
int32 duration;
|
||||||
int32 w, h;
|
int32 w, h;
|
||||||
ImagePtr thumb;
|
ImagePtr thumb, replyPreview;
|
||||||
int32 dc, size;
|
int32 dc, size;
|
||||||
// geo, caption
|
// geo, caption
|
||||||
|
|
||||||
|
@ -406,6 +410,7 @@ struct DocumentData {
|
||||||
void forget() {
|
void forget() {
|
||||||
thumb->forget();
|
thumb->forget();
|
||||||
sticker->forget();
|
sticker->forget();
|
||||||
|
replyPreview->forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
void save(const QString &toFile);
|
void save(const QString &toFile);
|
||||||
|
@ -442,8 +447,8 @@ struct DocumentData {
|
||||||
int32 duration;
|
int32 duration;
|
||||||
uint64 access;
|
uint64 access;
|
||||||
int32 date;
|
int32 date;
|
||||||
QString name, mime;
|
QString name, mime, alt; // alt - for stickers
|
||||||
ImagePtr thumb;
|
ImagePtr thumb, replyPreview;
|
||||||
int32 dc;
|
int32 dc;
|
||||||
int32 size;
|
int32 size;
|
||||||
|
|
||||||
|
@ -639,13 +644,13 @@ struct History : public QList<HistoryBlock*> {
|
||||||
|
|
||||||
HistoryItem *createItem(HistoryBlock *block, const MTPmessage &msg, bool newMsg, bool returnExisting = false);
|
HistoryItem *createItem(HistoryBlock *block, const MTPmessage &msg, bool newMsg, bool returnExisting = false);
|
||||||
HistoryItem *createItemForwarded(HistoryBlock *block, MsgId id, HistoryMessage *msg);
|
HistoryItem *createItemForwarded(HistoryBlock *block, MsgId id, HistoryMessage *msg);
|
||||||
HistoryItem *createItemDocument(HistoryBlock *block, MsgId id, bool out, bool unread, QDateTime date, int32 from, DocumentData *doc);
|
HistoryItem *createItemDocument(HistoryBlock *block, MsgId id, int32 flags, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc);
|
||||||
|
|
||||||
HistoryItem *addToBackService(MsgId msgId, QDateTime date, const QString &text, bool out = false, bool unread = false, HistoryMedia *media = 0, bool newMsg = true);
|
HistoryItem *addToBackService(MsgId msgId, QDateTime date, const QString &text, int32 flags = 0, HistoryMedia *media = 0, bool newMsg = true);
|
||||||
HistoryItem *addToBack(const MTPmessage &msg, bool newMsg = true);
|
HistoryItem *addToBack(const MTPmessage &msg, bool newMsg = true);
|
||||||
HistoryItem *addToHistory(const MTPmessage &msg);
|
HistoryItem *addToHistory(const MTPmessage &msg);
|
||||||
HistoryItem *addToBackForwarded(MsgId id, HistoryMessage *item);
|
HistoryItem *addToBackForwarded(MsgId id, HistoryMessage *item);
|
||||||
HistoryItem *addToBackDocument(MsgId id, bool out, bool unread, QDateTime date, int32 from, DocumentData *doc);
|
HistoryItem *addToBackDocument(MsgId id, int32 flags, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc);
|
||||||
|
|
||||||
void addToFront(const QVector<MTPMessage> &slice);
|
void addToFront(const QVector<MTPMessage> &slice);
|
||||||
void addToBack(const QVector<MTPMessage> &slice);
|
void addToBack(const QVector<MTPMessage> &slice);
|
||||||
|
@ -655,7 +660,9 @@ struct History : public QList<HistoryBlock*> {
|
||||||
void newItemAdded(HistoryItem *item);
|
void newItemAdded(HistoryItem *item);
|
||||||
void unregTyping(UserData *from);
|
void unregTyping(UserData *from);
|
||||||
|
|
||||||
|
void inboxRead(int32 upTo);
|
||||||
void inboxRead(HistoryItem *wasRead);
|
void inboxRead(HistoryItem *wasRead);
|
||||||
|
void outboxRead(int32 upTo);
|
||||||
void outboxRead(HistoryItem *wasRead);
|
void outboxRead(HistoryItem *wasRead);
|
||||||
|
|
||||||
void setUnreadCount(int32 newUnreadCount, bool psUpdate = true);
|
void setUnreadCount(int32 newUnreadCount, bool psUpdate = true);
|
||||||
|
@ -709,6 +716,9 @@ struct History : public QList<HistoryBlock*> {
|
||||||
notifies.pop_front();
|
notifies.pop_front();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void popNotification(HistoryItem *item) {
|
||||||
|
if (!notifies.isEmpty() && notifies.back() == item) notifies.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
void itemReplaced(HistoryItem *old, HistoryItem *item) {
|
void itemReplaced(HistoryItem *old, HistoryItem *item) {
|
||||||
if (!notifies.isEmpty()) {
|
if (!notifies.isEmpty()) {
|
||||||
|
@ -726,6 +736,7 @@ struct History : public QList<HistoryBlock*> {
|
||||||
}
|
}
|
||||||
|
|
||||||
QString draft;
|
QString draft;
|
||||||
|
MsgId draftToId;
|
||||||
MessageCursor draftCursor;
|
MessageCursor draftCursor;
|
||||||
int32 lastWidth, lastScrollTop;
|
int32 lastWidth, lastScrollTop;
|
||||||
bool mute;
|
bool mute;
|
||||||
|
@ -1097,11 +1108,13 @@ private:
|
||||||
|
|
||||||
ItemAnimations &itemAnimations();
|
ItemAnimations &itemAnimations();
|
||||||
|
|
||||||
|
class HistoryReply; // dynamic_cast optimize
|
||||||
|
|
||||||
class HistoryMedia;
|
class HistoryMedia;
|
||||||
class HistoryItem : public HistoryElem {
|
class HistoryItem : public HistoryElem {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
HistoryItem(History *history, HistoryBlock *block, MsgId msgId, bool out, bool unread, QDateTime msgDate, int32 from);
|
HistoryItem(History *history, HistoryBlock *block, MsgId msgId, int32 flags, QDateTime msgDate, int32 from);
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
MsgType = 0,
|
MsgType = 0,
|
||||||
|
@ -1116,10 +1129,7 @@ public:
|
||||||
const History *history() const {
|
const History *history() const {
|
||||||
return _history;
|
return _history;
|
||||||
}
|
}
|
||||||
UserData *from() {
|
UserData *from() const {
|
||||||
return _from;
|
|
||||||
}
|
|
||||||
const UserData *from() const {
|
|
||||||
return _from;
|
return _from;
|
||||||
}
|
}
|
||||||
HistoryBlock *block() {
|
HistoryBlock *block() {
|
||||||
|
@ -1135,11 +1145,14 @@ public:
|
||||||
return !_block;
|
return !_block;
|
||||||
}
|
}
|
||||||
bool out() const {
|
bool out() const {
|
||||||
return _out;
|
return _flags & MTPDmessage_flag_out;
|
||||||
}
|
}
|
||||||
bool unread() const {
|
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;
|
return _flags & MTPDmessage_flag_unread;
|
||||||
|
}
|
||||||
|
bool notifyByFrom() const {
|
||||||
|
return _flags & MTPDmessage_flag_notify_by_from;
|
||||||
}
|
}
|
||||||
virtual bool needCheck() const {
|
virtual bool needCheck() const {
|
||||||
return true;
|
return true;
|
||||||
|
@ -1173,6 +1186,12 @@ public:
|
||||||
virtual QString selectedText(uint32 selection) const {
|
virtual QString selectedText(uint32 selection) const {
|
||||||
return qsl("[-]");
|
return qsl("[-]");
|
||||||
}
|
}
|
||||||
|
virtual QString inDialogsText() const {
|
||||||
|
return qsl("-");
|
||||||
|
}
|
||||||
|
virtual QString inReplyText() const {
|
||||||
|
return inDialogsText();
|
||||||
|
}
|
||||||
|
|
||||||
virtual void drawInDialog(QPainter &p, const QRect &r, bool act, const HistoryItem *&cacheFor, Text &cache) const = 0;
|
virtual void drawInDialog(QPainter &p, const QRect &r, bool act, const HistoryItem *&cacheFor, Text &cache) const = 0;
|
||||||
virtual QString notificationHeader() const {
|
virtual QString notificationHeader() const {
|
||||||
|
@ -1197,6 +1216,13 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual HistoryReply *toHistoryReply() { // dynamic_cast optimize
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
virtual const HistoryReply *toHistoryReply() const { // dynamic_cast optimize
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
virtual ~HistoryItem();
|
virtual ~HistoryItem();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -1205,10 +1231,27 @@ protected:
|
||||||
mutable int32 _fromVersion;
|
mutable int32 _fromVersion;
|
||||||
History *_history;
|
History *_history;
|
||||||
HistoryBlock *_block;
|
HistoryBlock *_block;
|
||||||
bool _out, _unread;
|
int32 _flags;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class MessageLink : public ITextLink {
|
||||||
|
public:
|
||||||
|
MessageLink(PeerId peer, MsgId msgid) : _peer(peer), _msgid(msgid) {
|
||||||
|
}
|
||||||
|
void onClick(Qt::MouseButton button) const;
|
||||||
|
PeerId peer() const {
|
||||||
|
return _peer;
|
||||||
|
}
|
||||||
|
MsgId msgid() const {
|
||||||
|
return _msgid;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
PeerId _peer;
|
||||||
|
MsgId _msgid;
|
||||||
|
};
|
||||||
|
|
||||||
HistoryItem *regItem(HistoryItem *item, bool returnExisting = false);
|
HistoryItem *regItem(HistoryItem *item, bool returnExisting = false);
|
||||||
|
|
||||||
class HistoryMedia : public HistoryElem {
|
class HistoryMedia : public HistoryElem {
|
||||||
|
@ -1252,8 +1295,15 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool hasReplyPreview() const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
virtual ImagePtr replyPreview() {
|
||||||
|
return ImagePtr();
|
||||||
|
}
|
||||||
|
|
||||||
int32 currentWidth() const {
|
int32 currentWidth() const {
|
||||||
return w;
|
return qMin(w, _maxw);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -1297,6 +1347,11 @@ public:
|
||||||
return data->full->loading() ? true : !data->medium->loaded();
|
return data->full->loading() ? true : !data->medium->loaded();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool hasReplyPreview() const {
|
||||||
|
return !data->thumb->isNull();
|
||||||
|
}
|
||||||
|
ImagePtr replyPreview();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int16 pixw, pixh;
|
int16 pixw, pixh;
|
||||||
PhotoData *data;
|
PhotoData *data;
|
||||||
|
@ -1328,6 +1383,11 @@ public:
|
||||||
void regItem(HistoryItem *item);
|
void regItem(HistoryItem *item);
|
||||||
void unregItem(HistoryItem *item);
|
void unregItem(HistoryItem *item);
|
||||||
|
|
||||||
|
bool hasReplyPreview() const {
|
||||||
|
return !data->thumb->isNull();
|
||||||
|
}
|
||||||
|
ImagePtr replyPreview();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VideoData *data;
|
VideoData *data;
|
||||||
TextLinkPtr _openl, _savel, _cancell;
|
TextLinkPtr _openl, _savel, _cancell;
|
||||||
|
@ -1401,6 +1461,11 @@ public:
|
||||||
|
|
||||||
void updateFrom(const MTPMessageMedia &media);
|
void updateFrom(const MTPMessageMedia &media);
|
||||||
|
|
||||||
|
bool hasReplyPreview() const {
|
||||||
|
return !data->thumb->isNull();
|
||||||
|
}
|
||||||
|
ImagePtr replyPreview();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
DocumentData *data;
|
DocumentData *data;
|
||||||
|
@ -1447,6 +1512,7 @@ private:
|
||||||
int16 pixw, pixh;
|
int16 pixw, pixh;
|
||||||
DocumentData *data;
|
DocumentData *data;
|
||||||
QString _emoji;
|
QString _emoji;
|
||||||
|
int32 lastw;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1457,7 +1523,6 @@ public:
|
||||||
void initDimensions(const HistoryItem *parent);
|
void initDimensions(const HistoryItem *parent);
|
||||||
|
|
||||||
void draw(QPainter &p, const HistoryItem *parent, bool selected, int32 width) const;
|
void draw(QPainter &p, const HistoryItem *parent, bool selected, int32 width) const;
|
||||||
int32 resize(int32 width, bool dontRecountText = false, const HistoryItem *parent = 0);
|
|
||||||
HistoryMediaType type() const {
|
HistoryMediaType type() const {
|
||||||
return MediaTypeContact;
|
return MediaTypeContact;
|
||||||
}
|
}
|
||||||
|
@ -1558,9 +1623,9 @@ class HistoryMessage : public HistoryItem {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
HistoryMessage(History *history, HistoryBlock *block, const MTPDmessage &msg);
|
HistoryMessage(History *history, HistoryBlock *block, const MTPDmessage &msg);
|
||||||
HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, bool out, bool unread, QDateTime date, int32 from, const QString &msg, const MTPMessageMedia &media);
|
HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, QDateTime date, int32 from, const QString &msg, const MTPMessageMedia &media);
|
||||||
HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, bool out, bool unread, QDateTime date, int32 from, const QString &msg, HistoryMedia *media);
|
HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, QDateTime date, int32 from, const QString &msg, HistoryMedia *media);
|
||||||
HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, bool out, bool unread, QDateTime date, int32 from, DocumentData *doc);
|
HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, QDateTime date, int32 from, DocumentData *doc);
|
||||||
|
|
||||||
void initMedia(const MTPMessageMedia &media, QString ¤tText);
|
void initMedia(const MTPMessageMedia &media, QString ¤tText);
|
||||||
void initMediaFromDocument(DocumentData *doc);
|
void initMediaFromDocument(DocumentData *doc);
|
||||||
|
@ -1591,6 +1656,7 @@ public:
|
||||||
void updateStickerEmoji();
|
void updateStickerEmoji();
|
||||||
|
|
||||||
QString selectedText(uint32 selection) const;
|
QString selectedText(uint32 selection) const;
|
||||||
|
QString inDialogsText() const;
|
||||||
HistoryMedia *getMedia(bool inOverview = false) const;
|
HistoryMedia *getMedia(bool inOverview = false) const;
|
||||||
|
|
||||||
QString time() const {
|
QString time() const {
|
||||||
|
@ -1603,6 +1669,13 @@ public:
|
||||||
return _media ? _media->animating() : false;
|
return _media ? _media->animating() : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual QDateTime dateForwarded() const { // dynamic_cast optimize
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
virtual UserData *fromForwarded() const { // dynamic_cast optimize
|
||||||
|
return from();
|
||||||
|
}
|
||||||
|
|
||||||
~HistoryMessage();
|
~HistoryMessage();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -1620,9 +1693,10 @@ protected:
|
||||||
class HistoryForwarded : public HistoryMessage {
|
class HistoryForwarded : public HistoryMessage {
|
||||||
public:
|
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);
|
HistoryForwarded(History *history, HistoryBlock *block, MsgId id, HistoryMessage *msg);
|
||||||
|
|
||||||
|
void initDimensions(const HistoryItem *parent = 0);
|
||||||
void fwdNameUpdated() const;
|
void fwdNameUpdated() const;
|
||||||
|
|
||||||
void draw(QPainter &p, uint32 selection) const;
|
void draw(QPainter &p, uint32 selection) const;
|
||||||
|
@ -1650,11 +1724,62 @@ protected:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class HistoryReply : public HistoryMessage {
|
||||||
|
public:
|
||||||
|
|
||||||
|
HistoryReply(History *history, HistoryBlock *block, const MTPDmessage &msg);
|
||||||
|
HistoryReply(History *history, HistoryBlock *block, MsgId msgId, int32 flags, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc);
|
||||||
|
|
||||||
|
void initDimensions(const HistoryItem *parent = 0);
|
||||||
|
bool updateReplyTo(bool force = false);
|
||||||
|
void replyToNameUpdated() const;
|
||||||
|
int32 replyToWidth() const;
|
||||||
|
|
||||||
|
TextLinkPtr replyToLink() const;
|
||||||
|
|
||||||
|
MsgId replyToId() const;
|
||||||
|
HistoryItem *replyToMessage() const;
|
||||||
|
void replyToReplaced(HistoryItem *oldItem, HistoryItem *newItem);
|
||||||
|
|
||||||
|
void draw(QPainter &p, uint32 selection) const;
|
||||||
|
void drawReplyTo(QPainter &p, int32 x, int32 y, int32 w, bool selected, bool likeService = false) const;
|
||||||
|
void drawMessageText(QPainter &p, const QRect &trect, uint32 selection) const;
|
||||||
|
int32 resize(int32 width, bool dontRecountText = false, const HistoryItem *parent = 0);
|
||||||
|
bool hasPoint(int32 x, int32 y) const;
|
||||||
|
void getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y) const;
|
||||||
|
void getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x, int32 y) const;
|
||||||
|
|
||||||
|
UserData *replyTo() const {
|
||||||
|
return replyToMsg ? replyToMsg->from() : 0;
|
||||||
|
}
|
||||||
|
QString selectedText(uint32 selection) const;
|
||||||
|
|
||||||
|
HistoryReply *toHistoryReply() { // dynamic_cast optimize
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
const HistoryReply *toHistoryReply() const { // dynamic_cast optimize
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
~HistoryReply();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
MsgId replyToMsgId;
|
||||||
|
HistoryItem *replyToMsg;
|
||||||
|
TextLinkPtr replyToLnk;
|
||||||
|
mutable Text replyToName, replyToText;
|
||||||
|
mutable int32 replyToVersion;
|
||||||
|
mutable int32 _maxReplyWidth;
|
||||||
|
int32 toWidth;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
class HistoryServiceMsg : public HistoryItem {
|
class HistoryServiceMsg : public HistoryItem {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
HistoryServiceMsg(History *history, HistoryBlock *block, const MTPDmessageService &msg);
|
HistoryServiceMsg(History *history, HistoryBlock *block, const MTPDmessageService &msg);
|
||||||
HistoryServiceMsg(History *history, HistoryBlock *block, MsgId msgId, QDateTime date, const QString &msg, bool out = false, bool unread = false, HistoryMedia *media = 0);
|
HistoryServiceMsg(History *history, HistoryBlock *block, MsgId msgId, QDateTime date, const QString &msg, int32 flags = 0, HistoryMedia *media = 0);
|
||||||
|
|
||||||
void initDimensions(const HistoryItem *parent = 0);
|
void initDimensions(const HistoryItem *parent = 0);
|
||||||
|
|
||||||
|
@ -1677,6 +1802,8 @@ public:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
QString selectedText(uint32 selection) const;
|
QString selectedText(uint32 selection) const;
|
||||||
|
QString inDialogsText() const;
|
||||||
|
QString inReplyText() const;
|
||||||
|
|
||||||
HistoryMedia *getMedia(bool inOverview = false) const;
|
HistoryMedia *getMedia(bool inOverview = false) const;
|
||||||
|
|
||||||
|
|
|
@ -638,7 +638,8 @@ void HistoryList::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||||
}
|
}
|
||||||
|
|
||||||
_contextMenuLnk = textlnkOver();
|
_contextMenuLnk = textlnkOver();
|
||||||
PhotoLink *lnkPhoto = dynamic_cast<PhotoLink*>(_contextMenuLnk.data());
|
HistoryItem *item = App::hoveredItem() ? App::hoveredItem() : App::hoveredLinkItem();
|
||||||
|
PhotoLink *lnkPhoto = dynamic_cast<PhotoLink*>(_contextMenuLnk.data());
|
||||||
VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data());
|
VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data());
|
||||||
AudioLink *lnkAudio = dynamic_cast<AudioLink*>(_contextMenuLnk.data());
|
AudioLink *lnkAudio = dynamic_cast<AudioLink*>(_contextMenuLnk.data());
|
||||||
DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data());
|
DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data());
|
||||||
|
@ -647,6 +648,9 @@ void HistoryList::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||||
if (isUponSelected > 0) {
|
if (isUponSelected > 0) {
|
||||||
_menu->addAction(lang(lng_context_copy_selected), this, SLOT(copySelectedText()))->setEnabled(true);
|
_menu->addAction(lang(lng_context_copy_selected), this, SLOT(copySelectedText()))->setEnabled(true);
|
||||||
}
|
}
|
||||||
|
if (item && item->id > 0 && isUponSelected != 2 && isUponSelected != -2) {
|
||||||
|
_menu->addAction(lang(lng_context_reply_msg), historyWidget, SLOT(onReplyToMessage()));
|
||||||
|
}
|
||||||
if (lnkPhoto) {
|
if (lnkPhoto) {
|
||||||
_menu->addAction(lang(lng_context_open_image), this, SLOT(openContextUrl()))->setEnabled(true);
|
_menu->addAction(lang(lng_context_open_image), this, SLOT(openContextUrl()))->setEnabled(true);
|
||||||
_menu->addAction(lang(lng_context_save_image), this, SLOT(saveContextImage()))->setEnabled(true);
|
_menu->addAction(lang(lng_context_save_image), this, SLOT(saveContextImage()))->setEnabled(true);
|
||||||
|
@ -679,7 +683,6 @@ void HistoryList::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||||
App::contextItem(App::hoveredLinkItem());
|
App::contextItem(App::hoveredLinkItem());
|
||||||
}
|
}
|
||||||
} else { // maybe cursor on some text history item?
|
} else { // maybe cursor on some text history item?
|
||||||
HistoryItem *item = App::hoveredItem() ? App::hoveredItem() : App::hoveredLinkItem();
|
|
||||||
bool canDelete = (item && item->itemType() == HistoryItem::MsgType);
|
bool canDelete = (item && item->itemType() == HistoryItem::MsgType);
|
||||||
bool canForward = canDelete && (item->id > 0) && !item->serviceMsg();
|
bool canForward = canDelete && (item->id > 0) && !item->serviceMsg();
|
||||||
|
|
||||||
|
@ -689,11 +692,20 @@ void HistoryList::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||||
if (isUponSelected > 0) {
|
if (isUponSelected > 0) {
|
||||||
if (!_menu) _menu = new ContextMenu(this);
|
if (!_menu) _menu = new ContextMenu(this);
|
||||||
_menu->addAction(lang(lng_context_copy_selected), this, SLOT(copySelectedText()))->setEnabled(true);
|
_menu->addAction(lang(lng_context_copy_selected), this, SLOT(copySelectedText()))->setEnabled(true);
|
||||||
} else if (item && !isUponSelected && !_contextMenuLnk) {
|
if (item && item->id > 0 && isUponSelected != 2) {
|
||||||
QString contextMenuText = item->selectedText(FullItemSel);
|
_menu->addAction(lang(lng_context_reply_msg), historyWidget, SLOT(onReplyToMessage()));
|
||||||
if (!contextMenuText.isEmpty() && (!msg || !msg->getMedia() || msg->getMedia()->type() != MediaTypeSticker)) {
|
}
|
||||||
|
} else {
|
||||||
|
if (item && item->id > 0 && isUponSelected != -2) {
|
||||||
if (!_menu) _menu = new ContextMenu(this);
|
if (!_menu) _menu = new ContextMenu(this);
|
||||||
_menu->addAction(lang(lng_context_copy_text), this, SLOT(copyContextText()))->setEnabled(true);
|
_menu->addAction(lang(lng_context_reply_msg), historyWidget, SLOT(onReplyToMessage()));
|
||||||
|
}
|
||||||
|
if (item && !isUponSelected && !_contextMenuLnk) {
|
||||||
|
QString contextMenuText = item->selectedText(FullItemSel);
|
||||||
|
if (!contextMenuText.isEmpty() && (!msg || !msg->getMedia() || msg->getMedia()->type() != MediaTypeSticker)) {
|
||||||
|
if (!_menu) _menu = new ContextMenu(this);
|
||||||
|
_menu->addAction(lang(lng_context_copy_text), this, SLOT(copyContextText()))->setEnabled(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -705,6 +717,10 @@ void HistoryList::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||||
if (!_menu) _menu = new ContextMenu(historyWidget);
|
if (!_menu) _menu = new ContextMenu(historyWidget);
|
||||||
_menu->addAction(lang(lng_context_open_email), this, SLOT(openContextUrl()))->setEnabled(true);
|
_menu->addAction(lang(lng_context_open_email), this, SLOT(openContextUrl()))->setEnabled(true);
|
||||||
_menu->addAction(lang(lng_context_copy_email), this, SLOT(copyContextUrl()))->setEnabled(true);
|
_menu->addAction(lang(lng_context_copy_email), this, SLOT(copyContextUrl()))->setEnabled(true);
|
||||||
|
} else if (_contextMenuLnk && dynamic_cast<MentionLink*>(_contextMenuLnk.data())) {
|
||||||
|
if (!_menu) _menu = new ContextMenu(historyWidget);
|
||||||
|
_menu->addAction(lng_context_open_mention(lt_user, _contextMenuLnk->encoded()), this, SLOT(openContextUrl()))->setEnabled(true);
|
||||||
|
_menu->addAction(lang(lng_context_copy_mention), this, SLOT(copyContextUrl()))->setEnabled(true);
|
||||||
} else if (_contextMenuLnk && dynamic_cast<HashtagLink*>(_contextMenuLnk.data())) {
|
} else if (_contextMenuLnk && dynamic_cast<HashtagLink*>(_contextMenuLnk.data())) {
|
||||||
if (!_menu) _menu = new ContextMenu(historyWidget);
|
if (!_menu) _menu = new ContextMenu(historyWidget);
|
||||||
_menu->addAction(lang(lng_context_open_hashtag), this, SLOT(openContextUrl()))->setEnabled(true);
|
_menu->addAction(lang(lng_context_open_hashtag), this, SLOT(openContextUrl()))->setEnabled(true);
|
||||||
|
@ -1538,8 +1554,13 @@ HistoryHider::~HistoryHider() {
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryWidget::HistoryWidget(QWidget *parent) : QWidget(parent)
|
HistoryWidget::HistoryWidget(QWidget *parent) : QWidget(parent)
|
||||||
|
, _replyToId(0)
|
||||||
|
, _replyTo(0)
|
||||||
|
, _replyToNameVersion(0)
|
||||||
|
, _replyCancel(this, st::replyCancel)
|
||||||
, _lastStickersUpdate(0)
|
, _lastStickersUpdate(0)
|
||||||
, _stickersUpdateRequest(0)
|
, _stickersUpdateRequest(0)
|
||||||
|
, _loadingMessages(false)
|
||||||
, histRequestsCount(0)
|
, histRequestsCount(0)
|
||||||
, histPeer(0)
|
, histPeer(0)
|
||||||
, _activeHist(0)
|
, _activeHist(0)
|
||||||
|
@ -1551,6 +1572,7 @@ HistoryWidget::HistoryWidget(QWidget *parent) : QWidget(parent)
|
||||||
, hist(0)
|
, hist(0)
|
||||||
, _histInited(false)
|
, _histInited(false)
|
||||||
, _toHistoryEnd(this, st::historyToEnd)
|
, _toHistoryEnd(this, st::historyToEnd)
|
||||||
|
, _attachMention(this)
|
||||||
, _send(this, lang(lng_send_button), st::btnSend)
|
, _send(this, lang(lng_send_button), st::btnSend)
|
||||||
, _attachDocument(this, st::btnAttachDocument)
|
, _attachDocument(this, st::btnAttachDocument)
|
||||||
, _attachPhoto(this, st::btnAttachPhoto)
|
, _attachPhoto(this, st::btnAttachPhoto)
|
||||||
|
@ -1564,8 +1586,6 @@ HistoryWidget::HistoryWidget(QWidget *parent) : QWidget(parent)
|
||||||
, _attachDragPhoto(this)
|
, _attachDragPhoto(this)
|
||||||
, imageLoader(this)
|
, imageLoader(this)
|
||||||
, _synthedTextUpdate(false)
|
, _synthedTextUpdate(false)
|
||||||
, loadingChatId(0)
|
|
||||||
, loadingRequestId(0)
|
|
||||||
, serviceImageCacheSize(0)
|
, serviceImageCacheSize(0)
|
||||||
, confirmImageId(0)
|
, confirmImageId(0)
|
||||||
, confirmWithText(false)
|
, confirmWithText(false)
|
||||||
|
@ -1581,6 +1601,7 @@ HistoryWidget::HistoryWidget(QWidget *parent) : QWidget(parent)
|
||||||
|
|
||||||
connect(&_scroll, SIGNAL(scrolled()), this, SLOT(onListScroll()));
|
connect(&_scroll, SIGNAL(scrolled()), this, SLOT(onListScroll()));
|
||||||
connect(&_toHistoryEnd, SIGNAL(clicked()), this, SLOT(onHistoryToEnd()));
|
connect(&_toHistoryEnd, SIGNAL(clicked()), this, SLOT(onHistoryToEnd()));
|
||||||
|
connect(&_replyCancel, SIGNAL(clicked()), this, SLOT(onReplyCancel()));
|
||||||
connect(&_send, SIGNAL(clicked()), this, SLOT(onSend()));
|
connect(&_send, SIGNAL(clicked()), this, SLOT(onSend()));
|
||||||
connect(&_attachDocument, SIGNAL(clicked()), this, SLOT(onDocumentSelect()));
|
connect(&_attachDocument, SIGNAL(clicked()), this, SLOT(onDocumentSelect()));
|
||||||
connect(&_attachPhoto, SIGNAL(clicked()), this, SLOT(onPhotoSelect()));
|
connect(&_attachPhoto, SIGNAL(clicked()), this, SLOT(onPhotoSelect()));
|
||||||
|
@ -1609,7 +1630,9 @@ HistoryWidget::HistoryWidget(QWidget *parent) : QWidget(parent)
|
||||||
_saveDraftTimer.setSingleShot(true);
|
_saveDraftTimer.setSingleShot(true);
|
||||||
connect(&_saveDraftTimer, SIGNAL(timeout()), this, SLOT(onDraftSave()));
|
connect(&_saveDraftTimer, SIGNAL(timeout()), this, SLOT(onDraftSave()));
|
||||||
connect(_field.verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(onDraftSaveDelayed()));
|
connect(_field.verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(onDraftSaveDelayed()));
|
||||||
connect(&_field, SIGNAL(cursorPositionChanged()), this, SLOT(onDraftSaveDelayed()));
|
connect(&_field, SIGNAL(cursorPositionChanged()), this, SLOT(onFieldCursorChanged()));
|
||||||
|
|
||||||
|
_replyCancel.hide();
|
||||||
|
|
||||||
_scroll.hide();
|
_scroll.hide();
|
||||||
_scroll.move(0, 0);
|
_scroll.move(0, 0);
|
||||||
|
@ -1618,6 +1641,10 @@ HistoryWidget::HistoryWidget(QWidget *parent) : QWidget(parent)
|
||||||
|
|
||||||
_toHistoryEnd.hide();
|
_toHistoryEnd.hide();
|
||||||
|
|
||||||
|
_attachMention.hide();
|
||||||
|
connect(&_attachMention, SIGNAL(mentioned(QString)), &_field, SLOT(onMentionInsert(QString)));
|
||||||
|
_field.installEventFilter(&_attachMention);
|
||||||
|
|
||||||
_field.hide();
|
_field.hide();
|
||||||
_field.resize(width() - _send.width() - _attachDocument.width() - _attachEmoji.width(), _send.height() - 2 * st::sendPadding);
|
_field.resize(width() - _send.width() - _attachDocument.width() - _attachEmoji.width(), _send.height() - 2 * st::sendPadding);
|
||||||
_send.hide();
|
_send.hide();
|
||||||
|
@ -1645,6 +1672,11 @@ HistoryWidget::HistoryWidget(QWidget *parent) : QWidget(parent)
|
||||||
connect(&_attachDragPhoto, SIGNAL(dropped(QDropEvent*)), this, SLOT(onPhotoDrop(QDropEvent*)));
|
connect(&_attachDragPhoto, SIGNAL(dropped(QDropEvent*)), this, SLOT(onPhotoDrop(QDropEvent*)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HistoryWidget::start() {
|
||||||
|
updateRecentStickers();
|
||||||
|
connect(App::api(), SIGNAL(fullPeerLoaded(PeerData*)), this, SLOT(onPeerLoaded(PeerData*)));
|
||||||
|
}
|
||||||
|
|
||||||
void HistoryWidget::onTextChange() {
|
void HistoryWidget::onTextChange() {
|
||||||
updateTyping();
|
updateTyping();
|
||||||
// updateStickerPan();
|
// updateStickerPan();
|
||||||
|
@ -1678,12 +1710,12 @@ void HistoryWidget::onDraftSave(bool delayed) {
|
||||||
writeDraft();
|
writeDraft();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::writeDraft(const QString *text, const MessageCursor *cursor) {
|
void HistoryWidget::writeDraft(MsgId *replyTo, const QString *text, const MessageCursor *cursor) {
|
||||||
bool save = hist && (_saveDraftStart > 0);
|
bool save = hist && (_saveDraftStart > 0);
|
||||||
_saveDraftStart = 0;
|
_saveDraftStart = 0;
|
||||||
_saveDraftTimer.stop();
|
_saveDraftTimer.stop();
|
||||||
if (_saveDraftText) {
|
if (_saveDraftText) {
|
||||||
if (save) Local::writeDraft(hist->peer->id, text ? (*text) : _field.getText());
|
if (save) Local::writeDraft(hist->peer->id, Local::MessageDraft(replyTo ? (*replyTo) : _replyToId, text ? (*text) : _field.getText()));
|
||||||
_saveDraftText = false;
|
_saveDraftText = false;
|
||||||
}
|
}
|
||||||
if (save) Local::writeDraftPositions(hist->peer->id, cursor ? (*cursor) : MessageCursor(_field));
|
if (save) Local::writeDraftPositions(hist->peer->id, cursor ? (*cursor) : MessageCursor(_field));
|
||||||
|
@ -1748,26 +1780,6 @@ void HistoryWidget::activate() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::chatLoaded(const MTPmessages_ChatFull &res) {
|
|
||||||
const MTPDmessages_chatFull &d(res.c_messages_chatFull());
|
|
||||||
PeerId peerId = App::peerFromChat(d.vfull_chat.c_chatFull().vid);
|
|
||||||
if (peerId == loadingChatId) {
|
|
||||||
loadingRequestId = 0;
|
|
||||||
}
|
|
||||||
App::feedUsers(d.vusers);
|
|
||||||
App::feedChats(d.vchats);
|
|
||||||
App::feedParticipants(d.vfull_chat.c_chatFull().vparticipants);
|
|
||||||
PhotoData *photo = App::feedPhoto(d.vfull_chat.c_chatFull().vchat_photo);
|
|
||||||
if (photo) {
|
|
||||||
ChatData *chat = App::peer(peerId)->asChat();
|
|
||||||
if (chat) {
|
|
||||||
chat->photoId = photo->id;
|
|
||||||
photo->chat = chat;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
peerUpdated(App::chat(peerId));
|
|
||||||
}
|
|
||||||
|
|
||||||
void HistoryWidget::updateStickers() {
|
void HistoryWidget::updateStickers() {
|
||||||
if (_lastStickersUpdate && getms(true) < _lastStickersUpdate + StickersUpdateTimeout) return;
|
if (_lastStickersUpdate && getms(true) < _lastStickersUpdate + StickersUpdateTimeout) return;
|
||||||
if (_stickersUpdateRequest) return;
|
if (_stickersUpdateRequest) return;
|
||||||
|
@ -1949,8 +1961,9 @@ void HistoryWidget::showPeer(const PeerId &peer, MsgId msgId, bool force, bool l
|
||||||
if (hist) {
|
if (hist) {
|
||||||
hist->draft = _field.getText();
|
hist->draft = _field.getText();
|
||||||
hist->draftCursor.fillFrom(_field);
|
hist->draftCursor.fillFrom(_field);
|
||||||
|
hist->draftToId = _replyToId;
|
||||||
|
|
||||||
writeDraft(&hist->draft, &hist->draftCursor);
|
writeDraft(&hist->draftToId, &hist->draft, &hist->draftCursor);
|
||||||
|
|
||||||
if (hist->readyForWork() && _scroll.scrollTop() + 1 <= _scroll.scrollTopMax()) {
|
if (hist->readyForWork() && _scroll.scrollTop() + 1 <= _scroll.scrollTopMax()) {
|
||||||
hist->lastWidth = _list->width();
|
hist->lastWidth = _list->width();
|
||||||
|
@ -1961,6 +1974,11 @@ void HistoryWidget::showPeer(const PeerId &peer, MsgId msgId, bool force, bool l
|
||||||
if (hist->unreadBar) hist->unreadBar->destroy();
|
if (hist->unreadBar) hist->unreadBar->destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_replyToId) {
|
||||||
|
_replyTo = 0;
|
||||||
|
_replyToId = 0;
|
||||||
|
_replyCancel.hide();
|
||||||
|
}
|
||||||
_scroll.setWidget(0);
|
_scroll.setWidget(0);
|
||||||
if (_list) _list->deleteLater();
|
if (_list) _list->deleteLater();
|
||||||
_list = 0;
|
_list = 0;
|
||||||
|
@ -2029,18 +2047,25 @@ void HistoryWidget::showPeer(const PeerId &peer, MsgId msgId, bool force, bool l
|
||||||
|
|
||||||
App::main()->peerUpdated(histPeer);
|
App::main()->peerUpdated(histPeer);
|
||||||
|
|
||||||
if (!hist->draft.isEmpty()) {
|
if (hist->draftToId > 0 || !hist->draft.isEmpty()) {
|
||||||
setFieldText(hist->draft);
|
setFieldText(hist->draft);
|
||||||
_field.setFocus();
|
_field.setFocus();
|
||||||
hist->draftCursor.applyTo(_field, &_synthedTextUpdate);
|
hist->draftCursor.applyTo(_field, &_synthedTextUpdate);
|
||||||
|
_replyToId = hist->draftToId;
|
||||||
} else {
|
} else {
|
||||||
QString draft = Local::readDraft(hist->peer->id);
|
Local::MessageDraft draft = Local::readDraft(hist->peer->id);
|
||||||
setFieldText(draft);
|
setFieldText(draft.text);
|
||||||
_field.setFocus();
|
_field.setFocus();
|
||||||
if (!draft.isEmpty()) {
|
if (!draft.text.isEmpty()) {
|
||||||
MessageCursor cur = Local::readDraftPositions(hist->peer->id);
|
MessageCursor cur = Local::readDraftPositions(hist->peer->id);
|
||||||
cur.applyTo(_field, &_synthedTextUpdate);
|
cur.applyTo(_field, &_synthedTextUpdate);
|
||||||
}
|
}
|
||||||
|
_replyToId = draft.replyTo;
|
||||||
|
}
|
||||||
|
if (_replyToId) {
|
||||||
|
updateReplyTo();
|
||||||
|
if (!_replyTo) App::api()->requestReplyTo(0, _replyToId);
|
||||||
|
resizeEvent(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(&_scroll, SIGNAL(geometryChanged()), _list, SLOT(onParentGeometryChanged()));
|
connect(&_scroll, SIGNAL(geometryChanged()), _list, SLOT(onParentGeometryChanged()));
|
||||||
|
@ -2082,7 +2107,9 @@ void HistoryWidget::updateControlsVisibility() {
|
||||||
_scroll.hide();
|
_scroll.hide();
|
||||||
_send.hide();
|
_send.hide();
|
||||||
_toHistoryEnd.hide();
|
_toHistoryEnd.hide();
|
||||||
|
_attachMention.hide();
|
||||||
_field.hide();
|
_field.hide();
|
||||||
|
_replyCancel.hide();
|
||||||
_attachDocument.hide();
|
_attachDocument.hide();
|
||||||
_attachPhoto.hide();
|
_attachPhoto.hide();
|
||||||
_attachEmoji.hide();
|
_attachEmoji.hide();
|
||||||
|
@ -2108,10 +2135,12 @@ void HistoryWidget::updateControlsVisibility() {
|
||||||
_attachEmoji.show();
|
_attachEmoji.show();
|
||||||
if (_field.isHidden()) {
|
if (_field.isHidden()) {
|
||||||
_field.show();
|
_field.show();
|
||||||
|
if (_replyToId) _replyCancel.show();
|
||||||
resizeEvent(0);
|
resizeEvent(0);
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
_attachMention.hide();
|
||||||
_send.hide();
|
_send.hide();
|
||||||
_attachDocument.hide();
|
_attachDocument.hide();
|
||||||
_attachPhoto.hide();
|
_attachPhoto.hide();
|
||||||
|
@ -2133,6 +2162,7 @@ void HistoryWidget::updateControlsVisibility() {
|
||||||
loadMessages();
|
loadMessages();
|
||||||
if (!hist->readyForWork()) {
|
if (!hist->readyForWork()) {
|
||||||
_scroll.hide();
|
_scroll.hide();
|
||||||
|
_attachMention.hide();
|
||||||
_send.hide();
|
_send.hide();
|
||||||
_attachDocument.hide();
|
_attachDocument.hide();
|
||||||
_attachPhoto.hide();
|
_attachPhoto.hide();
|
||||||
|
@ -2141,6 +2171,7 @@ void HistoryWidget::updateControlsVisibility() {
|
||||||
_emojiPan.hide();
|
_emojiPan.hide();
|
||||||
// _stickerPan.hide();
|
// _stickerPan.hide();
|
||||||
_toHistoryEnd.hide();
|
_toHistoryEnd.hide();
|
||||||
|
_replyCancel.hide();
|
||||||
if (!_field.isHidden()) {
|
if (!_field.isHidden()) {
|
||||||
_field.hide();
|
_field.hide();
|
||||||
update();
|
update();
|
||||||
|
@ -2149,7 +2180,7 @@ void HistoryWidget::updateControlsVisibility() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::newUnreadMsg(History *history, MsgId msgId) {
|
void HistoryWidget::newUnreadMsg(History *history, HistoryItem *item) {
|
||||||
if (App::wnd()->historyIsActive()) {
|
if (App::wnd()->historyIsActive()) {
|
||||||
if (hist == history && hist->readyForWork()) {
|
if (hist == history && hist->readyForWork()) {
|
||||||
historyWasRead();
|
historyWasRead();
|
||||||
|
@ -2158,7 +2189,7 @@ void HistoryWidget::newUnreadMsg(History *history, MsgId msgId) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (hist != history) {
|
if (hist != history) {
|
||||||
App::wnd()->notifySchedule(history, msgId);
|
App::wnd()->notifySchedule(history, item);
|
||||||
}
|
}
|
||||||
history->setUnreadCount(history->unreadCount + 1);
|
history->setUnreadCount(history->unreadCount + 1);
|
||||||
}
|
}
|
||||||
|
@ -2168,7 +2199,7 @@ void HistoryWidget::newUnreadMsg(History *history, MsgId msgId) {
|
||||||
if (history->unreadBar) history->unreadBar->destroy();
|
if (history->unreadBar) history->unreadBar->destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
App::wnd()->notifySchedule(history, msgId);
|
App::wnd()->notifySchedule(history, item);
|
||||||
history->setUnreadCount(history->unreadCount + 1);
|
history->setUnreadCount(history->unreadCount + 1);
|
||||||
history->lastWidth = 0;
|
history->lastWidth = 0;
|
||||||
}
|
}
|
||||||
|
@ -2230,10 +2261,6 @@ void HistoryWidget::messagesReceived(const MTPmessages_Messages &messages, mtpRe
|
||||||
from_id = App::peerFromUser(msg.c_message().vfrom_id);
|
from_id = App::peerFromUser(msg.c_message().vfrom_id);
|
||||||
to_id = App::peerFromMTP(msg.c_message().vto_id);
|
to_id = App::peerFromMTP(msg.c_message().vto_id);
|
||||||
break;
|
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:
|
case mtpc_messageService:
|
||||||
from_id = App::peerFromUser(msg.c_messageService().vfrom_id);
|
from_id = App::peerFromUser(msg.c_messageService().vfrom_id);
|
||||||
to_id = App::peerFromMTP(msg.c_messageService().vto_id);
|
to_id = App::peerFromMTP(msg.c_messageService().vto_id);
|
||||||
|
@ -2328,7 +2355,7 @@ bool HistoryWidget::isActive() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::loadMessages() {
|
void HistoryWidget::loadMessages() {
|
||||||
if (!hist) return;
|
if (!hist || _loadingMessages) return;
|
||||||
if (hist->loadedAtTop()) {
|
if (hist->loadedAtTop()) {
|
||||||
if (!hist->readyForWork()) {
|
if (!hist->readyForWork()) {
|
||||||
if (hist->activeMsgId) {
|
if (hist->activeMsgId) {
|
||||||
|
@ -2342,13 +2369,14 @@ void HistoryWidget::loadMessages() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 dh = 0;
|
_loadingMessages = true;
|
||||||
if (histPreload.size()) {
|
if (histPreload.size()) {
|
||||||
bool loaded = hist->readyForWork();
|
bool loaded = hist->readyForWork();
|
||||||
addMessagesToFront(histPreload);
|
addMessagesToFront(histPreload);
|
||||||
histPreload.clear();
|
histPreload.clear();
|
||||||
checkUnreadLoaded(true);
|
checkUnreadLoaded(true);
|
||||||
if (!loaded && hist->readyForWork()) {
|
if (!loaded && hist->readyForWork()) {
|
||||||
|
_loadingMessages = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2365,6 +2393,7 @@ void HistoryWidget::loadMessages() {
|
||||||
} else {
|
} else {
|
||||||
checkUnreadLoaded(true);
|
checkUnreadLoaded(true);
|
||||||
}
|
}
|
||||||
|
_loadingMessages = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::loadMessagesDown() {
|
void HistoryWidget::loadMessagesDown() {
|
||||||
|
@ -2447,7 +2476,7 @@ void HistoryWidget::onHistoryToEnd() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::onSend(bool ctrlShiftEnter) {
|
void HistoryWidget::onSend(bool ctrlShiftEnter, MsgId replyTo) {
|
||||||
if (!hist) return;
|
if (!hist) return;
|
||||||
|
|
||||||
QString text = prepareMessage(_field.getText());
|
QString text = prepareMessage(_field.getText());
|
||||||
|
@ -2455,18 +2484,19 @@ void HistoryWidget::onSend(bool ctrlShiftEnter) {
|
||||||
App::main()->readServerHistory(hist, false);
|
App::main()->readServerHistory(hist, false);
|
||||||
hist->loadAround(0);
|
hist->loadAround(0);
|
||||||
|
|
||||||
App::main()->sendPreparedText(hist, prepareMessage(_field.getText()));
|
App::main()->sendPreparedText(hist, prepareMessage(_field.getText()), replyTo);
|
||||||
|
|
||||||
setFieldText(QString());
|
setFieldText(QString());
|
||||||
_saveDraftText = true;
|
_saveDraftText = true;
|
||||||
_saveDraftStart = getms();
|
_saveDraftStart = getms();
|
||||||
onDraftSave();
|
onDraftSave();
|
||||||
|
|
||||||
|
if (!_attachMention.isHidden()) _attachMention.hideStart();
|
||||||
if (!_attachType.isHidden()) _attachType.hideStart();
|
if (!_attachType.isHidden()) _attachType.hideStart();
|
||||||
if (!_emojiPan.isHidden()) _emojiPan.hideStart();
|
if (!_emojiPan.isHidden()) _emojiPan.hideStart();
|
||||||
// if (!_stickerPan.isHidden()) _stickerPan.hideStart();
|
// if (!_stickerPan.isHidden()) _stickerPan.hideStart();
|
||||||
}
|
}
|
||||||
|
if (replyTo < 0) onReplyCancel();
|
||||||
_field.setFocus();
|
_field.setFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2504,9 +2534,9 @@ mtpRequestId HistoryWidget::onForward(const PeerId &peer, SelectedItemSet toForw
|
||||||
|
|
||||||
MTPstring msgText(MTP_string(msg->selectedText(FullItemSel)));
|
MTPstring msgText(MTP_string(msg->selectedText(FullItemSel)));
|
||||||
|
|
||||||
int32 flags = (histPeer->input.type() == mtpc_inputPeerSelf) ? 0 : (0x01 | 0x02); // unread, out
|
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), MTP_int(unixtime()), msgText, MTP_messageMediaEmpty()));
|
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, msgText, MTP_long(randomId)), App::main()->rpcDone(&MainWidget::sentDataReceived, randomId), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
|
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) {
|
if (newId) {
|
||||||
App::historyRegRandom(randomId, newId);
|
App::historyRegRandom(randomId, newId);
|
||||||
|
@ -2525,11 +2555,15 @@ mtpRequestId HistoryWidget::onForward(const PeerId &peer, SelectedItemSet toForw
|
||||||
App::main()->readServerHistory(hist, false);
|
App::main()->readServerHistory(hist, false);
|
||||||
|
|
||||||
QVector<MTPint> ids;
|
QVector<MTPint> ids;
|
||||||
|
QVector<MTPlong> randomIds;
|
||||||
ids.reserve(toForward.size());
|
ids.reserve(toForward.size());
|
||||||
|
randomIds.reserve(toForward.size());
|
||||||
for (SelectedItemSet::const_iterator i = toForward.cbegin(), e = toForward.cend(); i != e; ++i) {
|
for (SelectedItemSet::const_iterator i = toForward.cbegin(), e = toForward.cend(); i != e; ++i) {
|
||||||
ids.push_back(MTP_int(i.value()->id));
|
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;
|
return hist->sendRequestId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2539,10 +2573,11 @@ void HistoryWidget::onShareContact(const PeerId &peer, UserData *contact) {
|
||||||
App::main()->showPeer(peer, 0, false, true);
|
App::main()->showPeer(peer, 0, false, true);
|
||||||
if (!hist) return;
|
if (!hist) return;
|
||||||
|
|
||||||
shareContact(peer, contact->phone, contact->firstName, contact->lastName, int32(contact->id & 0xFFFFFFFF));
|
shareContact(peer, contact->phone, contact->firstName, contact->lastName, _replyToId, int32(contact->id & 0xFFFFFFFF));
|
||||||
|
onReplyCancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::shareContact(const PeerId &peer, const QString &phone, const QString &fname, const QString &lname, int32 userId) {
|
void HistoryWidget::shareContact(const PeerId &peer, const QString &phone, const QString &fname, const QString &lname, MsgId replyTo, int32 userId) {
|
||||||
History *h = App::history(peer);
|
History *h = App::history(peer);
|
||||||
App::main()->readServerHistory(h, false);
|
App::main()->readServerHistory(h, false);
|
||||||
|
|
||||||
|
@ -2552,10 +2587,10 @@ void HistoryWidget::shareContact(const PeerId &peer, const QString &phone, const
|
||||||
h->loadAround(0);
|
h->loadAround(0);
|
||||||
|
|
||||||
PeerData *p = App::peer(peer);
|
PeerData *p = App::peer(peer);
|
||||||
int32 flags = (p->input.type() == mtpc_inputPeerSelf) ? 0 : (0x01 | 0x02); // unread, out
|
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), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaContact(MTP_string(phone), MTP_string(fname), MTP_string(lname), MTP_int(userId))));
|
if (replyTo) flags |= MTPDmessage::flag_reply_to_msg_id;
|
||||||
|
h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(peer), MTPint(), MTPint(), MTP_int(_replyToId), 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(replyTo), 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);
|
App::historyRegRandom(randomId, newId);
|
||||||
if (hist && histPeer && peer == histPeer->id) {
|
if (hist && histPeer && peer == histPeer->id) {
|
||||||
|
@ -2605,6 +2640,7 @@ void HistoryWidget::animShow(const QPixmap &bgAnimCache, const QPixmap &bgAnimTo
|
||||||
_attachPhoto.hide();
|
_attachPhoto.hide();
|
||||||
_attachEmoji.hide();
|
_attachEmoji.hide();
|
||||||
_field.hide();
|
_field.hide();
|
||||||
|
_replyCancel.hide();
|
||||||
_send.hide();
|
_send.hide();
|
||||||
a_coord = back ? anim::ivalue(-st::introSlideShift, 0) : anim::ivalue(st::introSlideShift, 0);
|
a_coord = back ? anim::ivalue(-st::introSlideShift, 0) : anim::ivalue(st::introSlideShift, 0);
|
||||||
a_alpha = anim::fvalue(0, 1);
|
a_alpha = anim::fvalue(0, 1);
|
||||||
|
@ -2984,20 +3020,39 @@ void HistoryWidget::updateOnlineDisplayTimer() {
|
||||||
|
|
||||||
void HistoryWidget::onFieldResize() {
|
void HistoryWidget::onFieldResize() {
|
||||||
_field.move(_attachDocument.x() + _attachDocument.width(), height() - _field.height() - st::sendPadding);
|
_field.move(_attachDocument.x() + _attachDocument.width(), height() - _field.height() - st::sendPadding);
|
||||||
|
_replyCancel.move(width() - _replyCancel.width(), _field.y() - st::sendPadding - _replyCancel.height());
|
||||||
updateListSize();
|
updateListSize();
|
||||||
|
int backy = _scroll.y() + _scroll.height();
|
||||||
|
update(0, backy, width(), height() - backy);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::onFieldFocused() {
|
void HistoryWidget::onFieldFocused() {
|
||||||
if (_list) _list->clearSelectedItems(true);
|
if (_list) _list->clearSelectedItems(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HistoryWidget::checkMentionDropdown() {
|
||||||
|
if (!hist || !hist->peer->chat) return;
|
||||||
|
|
||||||
|
QString start;
|
||||||
|
if (_field.getMentionStart(start)) {
|
||||||
|
_attachMention.showFiltered(hist->peer->asChat(), start);
|
||||||
|
} else if (!_attachMention.isHidden()) {
|
||||||
|
_attachMention.hideStart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HistoryWidget::onFieldCursorChanged() {
|
||||||
|
checkMentionDropdown();
|
||||||
|
onDraftSaveDelayed();
|
||||||
|
}
|
||||||
|
|
||||||
void HistoryWidget::uploadImage(const QImage &img, bool withText) {
|
void HistoryWidget::uploadImage(const QImage &img, bool withText) {
|
||||||
if (!hist || confirmImageId) return;
|
if (!hist || confirmImageId) return;
|
||||||
|
|
||||||
App::wnd()->activateWindow();
|
App::wnd()->activateWindow();
|
||||||
confirmImage = img;
|
confirmImage = img;
|
||||||
confirmWithText = withText;
|
confirmWithText = withText;
|
||||||
confirmImageId = imageLoader.append(img, histPeer->id, ToPreparePhoto);
|
confirmImageId = imageLoader.append(img, histPeer->id, _replyToId, ToPreparePhoto);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::uploadFile(const QString &file, bool withText) {
|
void HistoryWidget::uploadFile(const QString &file, bool withText) {
|
||||||
|
@ -3005,44 +3060,47 @@ void HistoryWidget::uploadFile(const QString &file, bool withText) {
|
||||||
|
|
||||||
App::wnd()->activateWindow();
|
App::wnd()->activateWindow();
|
||||||
confirmWithText = withText;
|
confirmWithText = withText;
|
||||||
confirmImageId = imageLoader.append(file, histPeer->id, ToPrepareDocument);
|
confirmImageId = imageLoader.append(file, histPeer->id, _replyToId, ToPrepareDocument);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::shareContactConfirmation(const QString &phone, const QString &fname, const QString &lname, bool withText) {
|
void HistoryWidget::shareContactConfirmation(const QString &phone, const QString &fname, const QString &lname, MsgId replyTo, bool withText) {
|
||||||
if (!hist || confirmImageId) return;
|
if (!hist || confirmImageId) return;
|
||||||
|
|
||||||
App::wnd()->activateWindow();
|
App::wnd()->activateWindow();
|
||||||
confirmWithText = withText;
|
confirmWithText = withText;
|
||||||
confirmImageId = 0xFFFFFFFFFFFFFFFFL;
|
confirmImageId = 0xFFFFFFFFFFFFFFFFL;
|
||||||
App::wnd()->showLayer(new PhotoSendBox(phone, fname, lname));
|
App::wnd()->showLayer(new PhotoSendBox(phone, fname, lname, replyTo));
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::uploadConfirmImageUncompressed(bool ctrlShiftEnter) {
|
void HistoryWidget::uploadConfirmImageUncompressed(bool ctrlShiftEnter, MsgId replyTo) {
|
||||||
if (!hist || !confirmImageId || confirmImage.isNull()) return;
|
if (!hist || !confirmImageId || confirmImage.isNull()) return;
|
||||||
|
|
||||||
App::wnd()->activateWindow();
|
App::wnd()->activateWindow();
|
||||||
PeerId peerId = histPeer->id;
|
PeerId peerId = histPeer->id;
|
||||||
if (confirmWithText) {
|
if (confirmWithText) {
|
||||||
onSend(ctrlShiftEnter);
|
onSend(ctrlShiftEnter, replyTo);
|
||||||
}
|
}
|
||||||
imageLoader.append(confirmImage, peerId, ToPrepareDocument, ctrlShiftEnter);
|
imageLoader.append(confirmImage, peerId, replyTo, ToPrepareDocument, ctrlShiftEnter);
|
||||||
confirmImageId = 0;
|
confirmImageId = 0;
|
||||||
confirmWithText = false;
|
confirmWithText = false;
|
||||||
confirmImage = QImage();
|
confirmImage = QImage();
|
||||||
|
onReplyCancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::uploadMedias(const QStringList &files, ToPrepareMediaType type) {
|
void HistoryWidget::uploadMedias(const QStringList &files, ToPrepareMediaType type) {
|
||||||
if (!hist) return;
|
if (!hist) return;
|
||||||
|
|
||||||
App::wnd()->activateWindow();
|
App::wnd()->activateWindow();
|
||||||
imageLoader.append(files, histPeer->id, type);
|
imageLoader.append(files, histPeer->id, _replyToId, type);
|
||||||
|
onReplyCancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::uploadMedia(const QByteArray &fileContent, ToPrepareMediaType type, PeerId peer) {
|
void HistoryWidget::uploadMedia(const QByteArray &fileContent, ToPrepareMediaType type, PeerId peer) {
|
||||||
if (!peer && !hist) return;
|
if (!peer && !hist) return;
|
||||||
|
|
||||||
App::wnd()->activateWindow();
|
App::wnd()->activateWindow();
|
||||||
imageLoader.append(fileContent, peer ? peer : histPeer->id, type);
|
imageLoader.append(fileContent, peer ? peer : histPeer->id, _replyToId, type);
|
||||||
|
onReplyCancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::onPhotoReady() {
|
void HistoryWidget::onPhotoReady() {
|
||||||
|
@ -3062,25 +3120,26 @@ void HistoryWidget::onPhotoReady() {
|
||||||
void HistoryWidget::onPhotoFailed(quint64 id) {
|
void HistoryWidget::onPhotoFailed(quint64 id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::confirmShareContact(bool ctrlShiftEnter, const QString &phone, const QString &fname, const QString &lname) {
|
void HistoryWidget::confirmShareContact(bool ctrlShiftEnter, const QString &phone, const QString &fname, const QString &lname, MsgId replyTo) {
|
||||||
if (!histPeer) return;
|
if (!histPeer) return;
|
||||||
|
|
||||||
PeerId peerId = histPeer->id;
|
PeerId peerId = histPeer->id;
|
||||||
if (0xFFFFFFFFFFFFFFFFL == confirmImageId) {
|
if (0xFFFFFFFFFFFFFFFFL == confirmImageId) {
|
||||||
if (confirmWithText) {
|
if (confirmWithText) {
|
||||||
onSend(ctrlShiftEnter);
|
onSend(ctrlShiftEnter, replyTo);
|
||||||
}
|
}
|
||||||
confirmImageId = 0;
|
confirmImageId = 0;
|
||||||
confirmWithText = false;
|
confirmWithText = false;
|
||||||
confirmImage = QImage();
|
confirmImage = QImage();
|
||||||
}
|
}
|
||||||
shareContact(peerId, phone, fname, lname);
|
shareContact(peerId, phone, fname, lname, replyTo);
|
||||||
|
onReplyCancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::confirmSendImage(const ReadyLocalMedia &img) {
|
void HistoryWidget::confirmSendImage(const ReadyLocalMedia &img) {
|
||||||
if (img.id == confirmImageId) {
|
if (img.id == confirmImageId) {
|
||||||
if (confirmWithText) {
|
if (confirmWithText) {
|
||||||
onSend(img.ctrlShiftEnter);
|
onSend(img.ctrlShiftEnter, img.replyTo);
|
||||||
}
|
}
|
||||||
confirmImageId = 0;
|
confirmImageId = 0;
|
||||||
confirmWithText = false;
|
confirmWithText = false;
|
||||||
|
@ -3101,12 +3160,14 @@ void HistoryWidget::confirmSendImage(const ReadyLocalMedia &img) {
|
||||||
History *h = App::history(img.peer);
|
History *h = App::history(img.peer);
|
||||||
if (img.type == ToPreparePhoto) {
|
if (img.type == ToPreparePhoto) {
|
||||||
h->loadAround(0);
|
h->loadAround(0);
|
||||||
int32 flags = (h->peer->input.type() == mtpc_inputPeerSelf) ? 0 : (0x01 | 0x02); // unread, out
|
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), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaPhoto(img.photo)));
|
if (img.replyTo) flags |= MTPDmessage::flag_reply_to_msg_id;
|
||||||
|
h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(img.peer), MTPint(), MTPint(), MTP_int(img.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaPhoto(img.photo)));
|
||||||
} else if (img.type == ToPrepareDocument) {
|
} else if (img.type == ToPrepareDocument) {
|
||||||
h->loadAround(0);
|
h->loadAround(0);
|
||||||
int32 flags = (h->peer->input.type() == mtpc_inputPeerSelf) ? 0 : (0x01 | 0x02); // unread, out
|
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), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaDocument(img.document)));
|
if (img.replyTo) flags |= MTPDmessage::flag_reply_to_msg_id;
|
||||||
|
h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(img.peer), MTPint(), MTPint(), MTP_int(img.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaDocument(img.document)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hist && histPeer && img.peer == histPeer->id) {
|
if (hist && histPeer && img.peer == histPeer->id) {
|
||||||
|
@ -3132,7 +3193,8 @@ void HistoryWidget::onPhotoUploaded(MsgId newId, const MTPInputFile &file) {
|
||||||
uint64 randomId = MTP::nonce<uint64>();
|
uint64 randomId = MTP::nonce<uint64>();
|
||||||
App::historyRegRandom(randomId, newId);
|
App::historyRegRandom(randomId, newId);
|
||||||
History *hist = item->history();
|
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);
|
MsgId replyTo = item->toHistoryReply() ? item->toHistoryReply()->replyToId() : 0;
|
||||||
|
hist->sendRequestId = MTP::send(MTPmessages_SendMedia(item->history()->peer->input, MTP_int(replyTo), MTP_inputMediaUploadedPhoto(file), MTP_long(randomId)), App::main()->rpcDone(&MainWidget::sentFullDataReceived, randomId), App::main()->rpcFail(&MainWidget::sendPhotoFailed, randomId), 0, 0, hist->sendRequestId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3145,7 +3207,7 @@ namespace {
|
||||||
if (document->type == AnimatedDocument) {
|
if (document->type == AnimatedDocument) {
|
||||||
attributes.push_back(MTP_documentAttributeAnimated());
|
attributes.push_back(MTP_documentAttributeAnimated());
|
||||||
} else if (document->type == StickerDocument) {
|
} else if (document->type == StickerDocument) {
|
||||||
attributes.push_back(MTP_documentAttributeSticker());
|
attributes.push_back(MTP_documentAttributeSticker(MTP_string(document->alt)));
|
||||||
}
|
}
|
||||||
return MTP_vector<MTPDocumentAttribute>(attributes);
|
return MTP_vector<MTPDocumentAttribute>(attributes);
|
||||||
}
|
}
|
||||||
|
@ -3167,7 +3229,8 @@ void HistoryWidget::onDocumentUploaded(MsgId newId, const MTPInputFile &file) {
|
||||||
uint64 randomId = MTP::nonce<uint64>();
|
uint64 randomId = MTP::nonce<uint64>();
|
||||||
App::historyRegRandom(randomId, newId);
|
App::historyRegRandom(randomId, newId);
|
||||||
History *hist = item->history();
|
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);
|
MsgId replyTo = item->toHistoryReply() ? item->toHistoryReply()->replyToId() : 0;
|
||||||
|
hist->sendRequestId = MTP::send(MTPmessages_SendMedia(item->history()->peer->input, MTP_int(replyTo), 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 +3251,8 @@ void HistoryWidget::onThumbDocumentUploaded(MsgId newId, const MTPInputFile &fil
|
||||||
uint64 randomId = MTP::nonce<uint64>();
|
uint64 randomId = MTP::nonce<uint64>();
|
||||||
App::historyRegRandom(randomId, newId);
|
App::historyRegRandom(randomId, newId);
|
||||||
History *hist = item->history();
|
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);
|
MsgId replyTo = item->toHistoryReply() ? item->toHistoryReply()->replyToId() : 0;
|
||||||
|
hist->sendRequestId = MTP::send(MTPmessages_SendMedia(item->history()->peer->input, MTP_int(replyTo), MTP_inputMediaUploadedThumbDocument(file, thumb, MTP_string(document->mime), _composeDocumentAttributes(document)), MTP_long(randomId)), App::main()->rpcDone(&MainWidget::sentFullDataReceived, randomId), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3230,7 +3294,7 @@ void HistoryWidget::resizeEvent(QResizeEvent *e) {
|
||||||
_attachPhoto.move(_attachDocument.x(), _attachDocument.y());
|
_attachPhoto.move(_attachDocument.x(), _attachDocument.y());
|
||||||
|
|
||||||
_field.move(_attachDocument.x() + _attachDocument.width(), height() - _field.height() - st::sendPadding);
|
_field.move(_attachDocument.x() + _attachDocument.width(), height() - _field.height() - st::sendPadding);
|
||||||
|
_replyCancel.move(width() - _replyCancel.width(), _field.y() - st::sendPadding - _replyCancel.height());
|
||||||
updateListSize();
|
updateListSize();
|
||||||
|
|
||||||
_field.resize(width() - _send.width() - _attachDocument.width() - _attachEmoji.width(), _field.height());
|
_field.resize(width() - _send.width() - _attachDocument.width() - _attachEmoji.width(), _field.height());
|
||||||
|
@ -3264,10 +3328,14 @@ void HistoryWidget::resizeEvent(QResizeEvent *e) {
|
||||||
|
|
||||||
void HistoryWidget::itemRemoved(HistoryItem *item) {
|
void HistoryWidget::itemRemoved(HistoryItem *item) {
|
||||||
if (_list) _list->itemRemoved(item);
|
if (_list) _list->itemRemoved(item);
|
||||||
|
if (item == _replyTo) {
|
||||||
|
onReplyCancel();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::itemReplaced(HistoryItem *oldItem, HistoryItem *newItem) {
|
void HistoryWidget::itemReplaced(HistoryItem *oldItem, HistoryItem *newItem) {
|
||||||
if (_list) _list->itemReplaced(oldItem, newItem);
|
if (_list) _list->itemReplaced(oldItem, newItem);
|
||||||
|
if (_replyTo == oldItem) _replyTo = newItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::itemResized(HistoryItem *row) {
|
void HistoryWidget::itemResized(HistoryItem *row) {
|
||||||
|
@ -3279,6 +3347,10 @@ void HistoryWidget::updateScrollColors() {
|
||||||
_scroll.updateColors(App::historyScrollBarColor(), App::historyScrollBgColor(), App::historyScrollBarOverColor(), App::historyScrollBgOverColor());
|
_scroll.updateColors(App::historyScrollBarColor(), App::historyScrollBgColor(), App::historyScrollBarOverColor(), App::historyScrollBgOverColor());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MsgId HistoryWidget::replyToId() const {
|
||||||
|
return _replyToId;
|
||||||
|
}
|
||||||
|
|
||||||
void HistoryWidget::updateListSize(int32 addToY, bool initial, bool loadedDown, HistoryItem *resizedItem) {
|
void HistoryWidget::updateListSize(int32 addToY, bool initial, bool loadedDown, HistoryItem *resizedItem) {
|
||||||
if (!hist || (!_histInited && !initial)) return;
|
if (!hist || (!_histInited && !initial)) return;
|
||||||
|
|
||||||
|
@ -3288,9 +3360,13 @@ void HistoryWidget::updateListSize(int32 addToY, bool initial, bool loadedDown,
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 newScrollHeight = height() - (hist->readyForWork() && (!histPeer->chat || !histPeer->asChat()->forbidden) ? (_field.height() + 2 * st::sendPadding) : 0);
|
int32 newScrollHeight = height() - (hist->readyForWork() && (!histPeer->chat || !histPeer->asChat()->forbidden) ? (_field.height() + 2 * st::sendPadding) : 0);
|
||||||
|
if (_replyToId) {
|
||||||
|
newScrollHeight -= st::replyHeight;
|
||||||
|
}
|
||||||
bool wasAtBottom = _scroll.scrollTop() + 1 > _scroll.scrollTopMax(), needResize = _scroll.width() != width() || _scroll.height() != newScrollHeight;
|
bool wasAtBottom = _scroll.scrollTop() + 1 > _scroll.scrollTopMax(), needResize = _scroll.width() != width() || _scroll.height() != newScrollHeight;
|
||||||
if (needResize) {
|
if (needResize) {
|
||||||
_scroll.resize(width(), newScrollHeight);
|
_scroll.resize(width(), newScrollHeight);
|
||||||
|
_attachMention.setBoundings(_scroll.geometry());
|
||||||
_toHistoryEnd.move((width() - _toHistoryEnd.width()) / 2, _scroll.y() + _scroll.height() - _toHistoryEnd.height() - st::historyToEndSkip);
|
_toHistoryEnd.move((width() - _toHistoryEnd.width()) / 2, _scroll.y() + _scroll.height() - _toHistoryEnd.height() - st::historyToEndSkip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3441,9 +3517,12 @@ void HistoryWidget::onStickerSend(DocumentData *sticker) {
|
||||||
hist->loadAround(0);
|
hist->loadAround(0);
|
||||||
|
|
||||||
bool out = (histPeer->input.type() != mtpc_inputPeerSelf), unread = (histPeer->input.type() != mtpc_inputPeerSelf);
|
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);
|
int32 flags = (histPeer->input.type() != mtpc_inputPeerSelf) ? (MTPDmessage_flag_out | MTPDmessage_flag_unread) : 0;
|
||||||
|
if (_replyToId) flags |= MTPDmessage::flag_reply_to_msg_id;
|
||||||
|
hist->addToBackDocument(newId, flags, _replyToId, 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(_replyToId), 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);
|
||||||
|
onReplyCancel();
|
||||||
|
|
||||||
App::historyRegRandom(randomId, newId);
|
App::historyRegRandom(randomId, newId);
|
||||||
App::main()->historyToDown(hist);
|
App::main()->historyToDown(hist);
|
||||||
|
@ -3451,6 +3530,7 @@ void HistoryWidget::onStickerSend(DocumentData *sticker) {
|
||||||
App::main()->dialogsToUp();
|
App::main()->dialogsToUp();
|
||||||
peerMessagesUpdated(histPeer->id);
|
peerMessagesUpdated(histPeer->id);
|
||||||
|
|
||||||
|
if (!_attachMention.isHidden()) _attachMention.hideStart();
|
||||||
if (!_attachType.isHidden()) _attachType.hideStart();
|
if (!_attachType.isHidden()) _attachType.hideStart();
|
||||||
if (!_emojiPan.isHidden()) _emojiPan.hideStart();
|
if (!_emojiPan.isHidden()) _emojiPan.hideStart();
|
||||||
// if (!_stickerPan.isHidden()) _stickerPan.hideStart();
|
// if (!_stickerPan.isHidden()) _stickerPan.hideStart();
|
||||||
|
@ -3465,18 +3545,56 @@ void HistoryWidget::setFieldText(const QString &text) {
|
||||||
_synthedTextUpdate = false;
|
_synthedTextUpdate = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HistoryWidget::onReplyToMessage() {
|
||||||
|
HistoryItem *to = App::contextItem();
|
||||||
|
if (!to || to->id <= 0) return;
|
||||||
|
|
||||||
|
_replyTo = to;
|
||||||
|
_replyToId = to->id;
|
||||||
|
_replyToText.setText(st::msgFont, _replyTo->inDialogsText(), _textDlgOptions);
|
||||||
|
if (!_field.isHidden()) _replyCancel.show();
|
||||||
|
updateReplyToName();
|
||||||
|
resizeEvent(0);
|
||||||
|
update();
|
||||||
|
|
||||||
|
_saveDraftText = true;
|
||||||
|
_saveDraftStart = getms();
|
||||||
|
onDraftSave();
|
||||||
|
|
||||||
|
_field.setFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HistoryWidget::onReplyCancel() {
|
||||||
|
if (!_replyToId) return;
|
||||||
|
_replyTo = 0;
|
||||||
|
_replyToId = 0;
|
||||||
|
_replyCancel.hide();
|
||||||
|
resizeEvent(0);
|
||||||
|
update();
|
||||||
|
|
||||||
|
_saveDraftText = true;
|
||||||
|
_saveDraftStart = getms();
|
||||||
|
onDraftSave();
|
||||||
|
}
|
||||||
|
|
||||||
void HistoryWidget::onCancel() {
|
void HistoryWidget::onCancel() {
|
||||||
if (App::main()) App::main()->showPeer(0);
|
if (App::main()) App::main()->showPeer(0);
|
||||||
emit cancelled();
|
emit cancelled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HistoryWidget::onPeerLoaded(PeerData *data) {
|
||||||
|
peerUpdated(data);
|
||||||
|
if (data == histPeer) {
|
||||||
|
checkMentionDropdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void HistoryWidget::peerUpdated(PeerData *data) {
|
void HistoryWidget::peerUpdated(PeerData *data) {
|
||||||
if (data && data == histPeer) {
|
if (data && data == histPeer) {
|
||||||
updateListSize();
|
updateListSize();
|
||||||
if (!animating()) updateControlsVisibility();
|
if (!animating()) updateControlsVisibility();
|
||||||
if (data->chat && data->asChat()->count > 0 && data->asChat()->participants.isEmpty() && (!loadingRequestId || loadingChatId != data->id)) {
|
if (data->chat && data->asChat()->count > 0 && data->asChat()->participants.isEmpty()) {
|
||||||
loadingChatId = data->id;
|
App::api()->requestFullPeer(data);
|
||||||
loadingRequestId = MTP::send(MTPmessages_GetFullChat(App::peerToMTP(data->id).c_peerChat().vchat_id), rpcDone(&HistoryWidget::chatLoaded));
|
|
||||||
}
|
}
|
||||||
App::main()->updateOnlineDisplay();
|
App::main()->updateOnlineDisplay();
|
||||||
}
|
}
|
||||||
|
@ -3512,7 +3630,7 @@ void HistoryWidget::onDeleteSelectedSure() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ids.isEmpty()) {
|
if (!ids.isEmpty()) {
|
||||||
MTP::send(MTPmessages_DeleteMessages(MTP_vector<MTPint>(ids)));
|
App::main()->deleteMessages(ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
onClearSelected();
|
onClearSelected();
|
||||||
|
@ -3532,7 +3650,7 @@ void HistoryWidget::onDeleteContextSure() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item->id > 0) {
|
if (item->id > 0) {
|
||||||
MTP::send(MTPmessages_DeleteMessages(MTP_vector<MTPint>(1, MTP_int(item->id))));
|
App::main()->deleteMessages(QVector<MTPint>(1, MTP_int(item->id)));
|
||||||
}
|
}
|
||||||
item->destroy();
|
item->destroy();
|
||||||
if (App::main() && App::main()->peer() == peer()) {
|
if (App::main() && App::main()->peer() == peer()) {
|
||||||
|
@ -3588,6 +3706,65 @@ void HistoryWidget::updateTopBarSelection() {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HistoryWidget::updateReplyTo(bool force) {
|
||||||
|
if (!_replyToId || _replyTo) return;
|
||||||
|
_replyTo = App::histItemById(_replyToId);
|
||||||
|
if (_replyTo) {
|
||||||
|
_replyToText.setText(st::msgFont, _replyTo->inDialogsText(), _textDlgOptions);
|
||||||
|
if (!_field.isHidden()) _replyCancel.show();
|
||||||
|
updateReplyToName();
|
||||||
|
int backy = _scroll.y() + _scroll.height();
|
||||||
|
update(0, backy, width(), height() - backy);
|
||||||
|
} else if (force) {
|
||||||
|
onReplyCancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HistoryWidget::updateReplyToName() {
|
||||||
|
if (!_replyTo) return;
|
||||||
|
_replyToName.setText(st::msgServiceNameFont, App::peerName(_replyTo->from()), _textNameOptions);
|
||||||
|
_replyToNameVersion = _replyTo->from()->nameVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HistoryWidget::drawFieldBackground(QPainter &p) {
|
||||||
|
int32 backy = _field.y() - st::sendPadding, backh = _field.height() + 2 * st::sendPadding;
|
||||||
|
if (_replyToId) {
|
||||||
|
if (_replyTo && _replyTo->from()->nameVersion > _replyToNameVersion) {
|
||||||
|
updateReplyToName();
|
||||||
|
}
|
||||||
|
backy -= st::replyHeight;
|
||||||
|
backh += st::replyHeight;
|
||||||
|
}
|
||||||
|
p.fillRect(0, backy, width(), backh, st::taMsgField.bgColor->b);
|
||||||
|
if (_replyToId) {
|
||||||
|
int32 replyLeft = st::replySkip;
|
||||||
|
p.drawPixmap(QPoint(st::replyIconPos.x(), backy + st::replyIconPos.y()), App::sprite(), st::replyIcon);
|
||||||
|
if (_replyTo) {
|
||||||
|
if (_replyTo->getMedia() && _replyTo->getMedia()->hasReplyPreview()) {
|
||||||
|
ImagePtr replyPreview = _replyTo->getMedia()->replyPreview();
|
||||||
|
if (!replyPreview->isNull()) {
|
||||||
|
QRect to(replyLeft, backy + st::msgReplyPadding.top(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height());
|
||||||
|
if (replyPreview->width() == replyPreview->height()) {
|
||||||
|
p.drawPixmap(to.x(), to.y(), replyPreview->pix());
|
||||||
|
} else {
|
||||||
|
QRect from = (replyPreview->width() > replyPreview->height()) ? QRect((replyPreview->width() - replyPreview->height()) / 2, 0, replyPreview->height(), replyPreview->height()) : QRect(0, (replyPreview->height() - replyPreview->width()) / 2, replyPreview->width(), replyPreview->width());
|
||||||
|
p.drawPixmap(to, replyPreview->pix(), from);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
replyLeft += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x();
|
||||||
|
}
|
||||||
|
p.setPen(st::replyColor->p);
|
||||||
|
_replyToName.drawElided(p, replyLeft, backy + st::msgReplyPadding.top(), width() - replyLeft - _replyCancel.width() - st::msgReplyPadding.right());
|
||||||
|
p.setPen((_replyTo->getMedia() ? st::msgInDateColor : st::msgColor)->p);
|
||||||
|
_replyToText.drawElided(p, replyLeft, backy + st::msgReplyPadding.top() + st::msgServiceNameFont->height, width() - replyLeft - _replyCancel.width() - st::msgReplyPadding.right());
|
||||||
|
} else {
|
||||||
|
p.setFont(st::msgDateFont->f);
|
||||||
|
p.setPen(st::msgInDateColor->p);
|
||||||
|
p.drawText(replyLeft, backy + st::msgReplyPadding.top() + (st::msgReplyBarSize.height() - st::msgDateFont->height) / 2 + st::msgDateFont->ascent, st::msgDateFont->m.elidedText(lang(lng_profile_loading), Qt::ElideRight, width() - replyLeft - _replyCancel.width() - st::msgReplyPadding.right()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void HistoryWidget::paintEvent(QPaintEvent *e) {
|
void HistoryWidget::paintEvent(QPaintEvent *e) {
|
||||||
QPainter p(this);
|
QPainter p(this);
|
||||||
QRect r(e->rect());
|
QRect r(e->rect());
|
||||||
|
@ -3635,7 +3812,7 @@ void HistoryWidget::paintEvent(QPaintEvent *e) {
|
||||||
if (_list) {
|
if (_list) {
|
||||||
if (!_scroll.isHidden()) {
|
if (!_scroll.isHidden()) {
|
||||||
if (!_field.isHidden()) {
|
if (!_field.isHidden()) {
|
||||||
p.fillRect(0, _field.y() - st::sendPadding, width(), _field.height() + 2 * st::sendPadding, st::taMsgField.bgColor->b);
|
drawFieldBackground(p);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
QPoint dogPos((width() - st::msgDogImg.pxWidth()) / 2, ((height() - _field.height() - 2 * st::sendPadding - st::msgDogImg.pxHeight()) * 4) / 9);
|
QPoint dogPos((width() - st::msgDogImg.pxWidth()) / 2, ((height() - _field.height() - 2 * st::sendPadding - st::msgDogImg.pxHeight()) * 4) / 9);
|
||||||
|
|
|
@ -252,6 +252,8 @@ public:
|
||||||
|
|
||||||
HistoryWidget(QWidget *parent);
|
HistoryWidget(QWidget *parent);
|
||||||
|
|
||||||
|
void start();
|
||||||
|
|
||||||
void messagesReceived(const MTPmessages_Messages &messages, mtpRequestId requestId);
|
void messagesReceived(const MTPmessages_Messages &messages, mtpRequestId requestId);
|
||||||
|
|
||||||
void windowShown();
|
void windowShown();
|
||||||
|
@ -269,6 +271,7 @@ public:
|
||||||
void contextMenuEvent(QContextMenuEvent *e);
|
void contextMenuEvent(QContextMenuEvent *e);
|
||||||
|
|
||||||
void updateTopBarSelection();
|
void updateTopBarSelection();
|
||||||
|
void checkMentionDropdown();
|
||||||
|
|
||||||
void paintTopBar(QPainter &p, float64 over, int32 decreaseWidth);
|
void paintTopBar(QPainter &p, float64 over, int32 decreaseWidth);
|
||||||
void topBarShadowParams(int32 &x, float64 &o);
|
void topBarShadowParams(int32 &x, float64 &o);
|
||||||
|
@ -281,7 +284,7 @@ public:
|
||||||
void peerMessagesUpdated();
|
void peerMessagesUpdated();
|
||||||
|
|
||||||
void msgUpdated(PeerId peer, const HistoryItem *msg);
|
void msgUpdated(PeerId peer, const HistoryItem *msg);
|
||||||
void newUnreadMsg(History *history, MsgId msgId);
|
void newUnreadMsg(History *history, HistoryItem *item);
|
||||||
void historyToDown(History *history);
|
void historyToDown(History *history);
|
||||||
void historyWasRead(bool force = true);
|
void historyWasRead(bool force = true);
|
||||||
|
|
||||||
|
@ -295,11 +298,11 @@ public:
|
||||||
void destroyData();
|
void destroyData();
|
||||||
void uploadImage(const QImage &img, bool withText = false);
|
void uploadImage(const QImage &img, bool withText = false);
|
||||||
void uploadFile(const QString &file, bool withText = false); // with confirmation
|
void uploadFile(const QString &file, bool withText = false); // with confirmation
|
||||||
void shareContactConfirmation(const QString &phone, const QString &fname, const QString &lname, bool withText = false);
|
void shareContactConfirmation(const QString &phone, const QString &fname, const QString &lname, MsgId replyTo, bool withText = false);
|
||||||
void uploadConfirmImageUncompressed(bool ctrlShiftEnter);
|
void uploadConfirmImageUncompressed(bool ctrlShiftEnter, MsgId replyTo);
|
||||||
void uploadMedias(const QStringList &files, ToPrepareMediaType type);
|
void uploadMedias(const QStringList &files, ToPrepareMediaType type);
|
||||||
void uploadMedia(const QByteArray &fileContent, ToPrepareMediaType type, PeerId peer = 0);
|
void uploadMedia(const QByteArray &fileContent, ToPrepareMediaType type, PeerId peer = 0);
|
||||||
void confirmShareContact(bool ctrlShiftEnter, const QString &phone, const QString &fname, const QString &lname);
|
void confirmShareContact(bool ctrlShiftEnter, const QString &phone, const QString &fname, const QString &lname, MsgId replyTo);
|
||||||
void confirmSendImage(const ReadyLocalMedia &img);
|
void confirmSendImage(const ReadyLocalMedia &img);
|
||||||
void cancelSendImage();
|
void cancelSendImage();
|
||||||
|
|
||||||
|
@ -312,7 +315,7 @@ public:
|
||||||
void onShareContact(const PeerId &peer, UserData *contact);
|
void onShareContact(const PeerId &peer, UserData *contact);
|
||||||
void onSendPaths(const PeerId &peer);
|
void onSendPaths(const PeerId &peer);
|
||||||
|
|
||||||
void shareContact(const PeerId &peer, const QString &phone, const QString &fname, const QString &lname, int32 userId = 0);
|
void shareContact(const PeerId &peer, const QString &phone, const QString &fname, const QString &lname, MsgId replyTo, int32 userId = 0);
|
||||||
|
|
||||||
PeerData *peer() const;
|
PeerData *peer() const;
|
||||||
PeerData *activePeer() const;
|
PeerData *activePeer() const;
|
||||||
|
@ -343,6 +346,9 @@ public:
|
||||||
|
|
||||||
void updateScrollColors();
|
void updateScrollColors();
|
||||||
|
|
||||||
|
MsgId replyToId() const;
|
||||||
|
void updateReplyTo(bool force = false);
|
||||||
|
|
||||||
~HistoryWidget();
|
~HistoryWidget();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
@ -353,8 +359,11 @@ signals:
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
void onCancel();
|
void onCancel();
|
||||||
|
void onReplyToMessage();
|
||||||
|
void onReplyCancel();
|
||||||
|
|
||||||
void peerUpdated(PeerData *data);
|
void peerUpdated(PeerData *data);
|
||||||
|
void onPeerLoaded(PeerData *data);
|
||||||
|
|
||||||
void cancelTyping();
|
void cancelTyping();
|
||||||
|
|
||||||
|
@ -368,7 +377,7 @@ public slots:
|
||||||
|
|
||||||
void onListScroll();
|
void onListScroll();
|
||||||
void onHistoryToEnd();
|
void onHistoryToEnd();
|
||||||
void onSend(bool ctrlShiftEnter = false);
|
void onSend(bool ctrlShiftEnter = false, MsgId replyTo = -1);
|
||||||
|
|
||||||
void onPhotoSelect();
|
void onPhotoSelect();
|
||||||
void onDocumentSelect();
|
void onDocumentSelect();
|
||||||
|
@ -392,6 +401,7 @@ public slots:
|
||||||
|
|
||||||
void onFieldFocused();
|
void onFieldFocused();
|
||||||
void onFieldResize();
|
void onFieldResize();
|
||||||
|
void onFieldCursorChanged();
|
||||||
void onScrollTimer();
|
void onScrollTimer();
|
||||||
|
|
||||||
void onForwardSelected();
|
void onForwardSelected();
|
||||||
|
@ -409,11 +419,18 @@ public slots:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
MsgId _replyToId;
|
||||||
|
HistoryItem *_replyTo;
|
||||||
|
Text _replyToName, _replyToText;
|
||||||
|
int32 _replyToNameVersion;
|
||||||
|
IconedButton _replyCancel;
|
||||||
|
void updateReplyToName();
|
||||||
|
void drawFieldBackground(QPainter &p);
|
||||||
|
|
||||||
bool messagesFailed(const RPCError &error, mtpRequestId requestId);
|
bool messagesFailed(const RPCError &error, mtpRequestId requestId);
|
||||||
void updateListSize(int32 addToY = 0, bool initial = false, bool loadedDown = false, HistoryItem *resizedItem = 0);
|
void updateListSize(int32 addToY = 0, bool initial = false, bool loadedDown = false, HistoryItem *resizedItem = 0);
|
||||||
void addMessagesToFront(const QVector<MTPMessage> &messages);
|
void addMessagesToFront(const QVector<MTPMessage> &messages);
|
||||||
void addMessagesToBack(const QVector<MTPMessage> &messages);
|
void addMessagesToBack(const QVector<MTPMessage> &messages);
|
||||||
void chatLoaded(const MTPmessages_ChatFull &res);
|
|
||||||
|
|
||||||
void stickersGot(const MTPmessages_AllStickers &stickers);
|
void stickersGot(const MTPmessages_AllStickers &stickers);
|
||||||
bool stickersFailed(const RPCError &error);
|
bool stickersFailed(const RPCError &error);
|
||||||
|
@ -421,7 +438,7 @@ private:
|
||||||
uint64 _lastStickersUpdate;
|
uint64 _lastStickersUpdate;
|
||||||
mtpRequestId _stickersUpdateRequest;
|
mtpRequestId _stickersUpdateRequest;
|
||||||
|
|
||||||
void writeDraft(const QString *text = 0, const MessageCursor *cursor = 0);
|
void writeDraft(MsgId *replyTo = 0, const QString *text = 0, const MessageCursor *cursor = 0);
|
||||||
void setFieldText(const QString &text);
|
void setFieldText(const QString &text);
|
||||||
|
|
||||||
QStringList getMediasFromMime(const QMimeData *d);
|
QStringList getMediasFromMime(const QMimeData *d);
|
||||||
|
@ -429,6 +446,7 @@ private:
|
||||||
|
|
||||||
void updateDragAreas();
|
void updateDragAreas();
|
||||||
|
|
||||||
|
bool _loadingMessages;
|
||||||
int32 histRequestsCount;
|
int32 histRequestsCount;
|
||||||
PeerData *histPeer;
|
PeerData *histPeer;
|
||||||
History *_activeHist;
|
History *_activeHist;
|
||||||
|
@ -446,6 +464,8 @@ private:
|
||||||
|
|
||||||
IconedButton _toHistoryEnd;
|
IconedButton _toHistoryEnd;
|
||||||
|
|
||||||
|
MentionsDropdown _attachMention;
|
||||||
|
|
||||||
FlatButton _send;
|
FlatButton _send;
|
||||||
IconedButton _attachDocument, _attachPhoto, _attachEmoji;
|
IconedButton _attachDocument, _attachPhoto, _attachEmoji;
|
||||||
MessageField _field;
|
MessageField _field;
|
||||||
|
@ -461,9 +481,6 @@ private:
|
||||||
LocalImageLoader imageLoader;
|
LocalImageLoader imageLoader;
|
||||||
bool _synthedTextUpdate;
|
bool _synthedTextUpdate;
|
||||||
|
|
||||||
PeerId loadingChatId;
|
|
||||||
mtpRequestId loadingRequestId;
|
|
||||||
|
|
||||||
int64 serviceImageCacheSize;
|
int64 serviceImageCacheSize;
|
||||||
QImage confirmImage;
|
QImage confirmImage;
|
||||||
PhotoId confirmImageId;
|
PhotoId confirmImageId;
|
||||||
|
|
|
@ -41,6 +41,7 @@ void LocalImageLoaderPrivate::prepareImages() {
|
||||||
ToPrepareMediaType type;
|
ToPrepareMediaType type;
|
||||||
bool animated = false;
|
bool animated = false;
|
||||||
bool ctrlShiftEnter = false;
|
bool ctrlShiftEnter = false;
|
||||||
|
MsgId replyTo = 0;
|
||||||
{
|
{
|
||||||
QMutexLocker lock(loader->toPrepareMutex());
|
QMutexLocker lock(loader->toPrepareMutex());
|
||||||
ToPrepareMedias &list(loader->toPrepareMedias());
|
ToPrepareMedias &list(loader->toPrepareMedias());
|
||||||
|
@ -53,6 +54,7 @@ void LocalImageLoaderPrivate::prepareImages() {
|
||||||
id = list.front().id;
|
id = list.front().id;
|
||||||
type = list.front().type;
|
type = list.front().type;
|
||||||
ctrlShiftEnter = list.front().ctrlShiftEnter;
|
ctrlShiftEnter = list.front().ctrlShiftEnter;
|
||||||
|
replyTo = list.front().replyTo;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (img.isNull()) {
|
if (img.isNull()) {
|
||||||
|
@ -186,7 +188,7 @@ void LocalImageLoaderPrivate::prepareImages() {
|
||||||
if (animated) {
|
if (animated) {
|
||||||
attributes.push_back(MTP_documentAttributeAnimated());
|
attributes.push_back(MTP_documentAttributeAnimated());
|
||||||
} else if (mime == stickerMime && w > 0 && h > 0 && w <= StickerMaxSize && h <= StickerMaxSize && filesize < StickerInMemory) {
|
} 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";
|
thumbFormat = "webp";
|
||||||
thumbExt = qsl("webp");
|
thumbExt = qsl("webp");
|
||||||
}
|
}
|
||||||
|
@ -212,7 +214,7 @@ void LocalImageLoaderPrivate::prepareImages() {
|
||||||
|
|
||||||
{
|
{
|
||||||
QMutexLocker lock(loader->readyMutex());
|
QMutexLocker lock(loader->readyMutex());
|
||||||
loader->readyList().push_back(ReadyLocalMedia(type, file, filename, filesize, data, id, thumbId, thumbExt, peer, photo, photoThumbs, document, jpeg, ctrlShiftEnter));
|
loader->readyList().push_back(ReadyLocalMedia(type, file, filename, filesize, data, id, thumbId, thumbExt, peer, photo, photoThumbs, document, jpeg, ctrlShiftEnter, replyTo));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -234,11 +236,11 @@ LocalImageLoaderPrivate::~LocalImageLoaderPrivate() {
|
||||||
LocalImageLoader::LocalImageLoader(QObject *parent) : QObject(parent), thread(0), priv(0) {
|
LocalImageLoader::LocalImageLoader(QObject *parent) : QObject(parent), thread(0), priv(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalImageLoader::append(const QStringList &files, const PeerId &peer, ToPrepareMediaType t) {
|
void LocalImageLoader::append(const QStringList &files, const PeerId &peer, MsgId replyTo, ToPrepareMediaType t) {
|
||||||
{
|
{
|
||||||
QMutexLocker lock(toPrepareMutex());
|
QMutexLocker lock(toPrepareMutex());
|
||||||
for (QStringList::const_iterator i = files.cbegin(), e = files.cend(); i != e; ++i) {
|
for (QStringList::const_iterator i = files.cbegin(), e = files.cend(); i != e; ++i) {
|
||||||
toPrepare.push_back(ToPrepareMedia(*i, peer, t, false));
|
toPrepare.push_back(ToPrepareMedia(*i, peer, t, false, replyTo));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!thread) {
|
if (!thread) {
|
||||||
|
@ -249,11 +251,11 @@ void LocalImageLoader::append(const QStringList &files, const PeerId &peer, ToPr
|
||||||
emit needToPrepare();
|
emit needToPrepare();
|
||||||
}
|
}
|
||||||
|
|
||||||
PhotoId LocalImageLoader::append(const QByteArray &img, const PeerId &peer, ToPrepareMediaType t) {
|
PhotoId LocalImageLoader::append(const QByteArray &img, const PeerId &peer, MsgId replyTo, ToPrepareMediaType t) {
|
||||||
PhotoId result = 0;
|
PhotoId result = 0;
|
||||||
{
|
{
|
||||||
QMutexLocker lock(toPrepareMutex());
|
QMutexLocker lock(toPrepareMutex());
|
||||||
toPrepare.push_back(ToPrepareMedia(img, peer, t, false));
|
toPrepare.push_back(ToPrepareMedia(img, peer, t, false, replyTo));
|
||||||
result = toPrepare.back().id;
|
result = toPrepare.back().id;
|
||||||
}
|
}
|
||||||
if (!thread) {
|
if (!thread) {
|
||||||
|
@ -265,11 +267,11 @@ PhotoId LocalImageLoader::append(const QByteArray &img, const PeerId &peer, ToPr
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
PhotoId LocalImageLoader::append(const QImage &img, const PeerId &peer, ToPrepareMediaType t, bool ctrlShiftEnter) {
|
PhotoId LocalImageLoader::append(const QImage &img, const PeerId &peer, MsgId replyTo, ToPrepareMediaType t, bool ctrlShiftEnter) {
|
||||||
PhotoId result = 0;
|
PhotoId result = 0;
|
||||||
{
|
{
|
||||||
QMutexLocker lock(toPrepareMutex());
|
QMutexLocker lock(toPrepareMutex());
|
||||||
toPrepare.push_back(ToPrepareMedia(img, peer, t, ctrlShiftEnter));
|
toPrepare.push_back(ToPrepareMedia(img, peer, t, ctrlShiftEnter, replyTo));
|
||||||
result = toPrepare.back().id;
|
result = toPrepare.back().id;
|
||||||
}
|
}
|
||||||
if (!thread) {
|
if (!thread) {
|
||||||
|
@ -281,11 +283,11 @@ PhotoId LocalImageLoader::append(const QImage &img, const PeerId &peer, ToPrepar
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
PhotoId LocalImageLoader::append(const QString &file, const PeerId &peer, ToPrepareMediaType t) {
|
PhotoId LocalImageLoader::append(const QString &file, const PeerId &peer, MsgId replyTo, ToPrepareMediaType t) {
|
||||||
PhotoId result = 0;
|
PhotoId result = 0;
|
||||||
{
|
{
|
||||||
QMutexLocker lock(toPrepareMutex());
|
QMutexLocker lock(toPrepareMutex());
|
||||||
toPrepare.push_back(ToPrepareMedia(file, peer, t, false));
|
toPrepare.push_back(ToPrepareMedia(file, peer, t, false, replyTo));
|
||||||
result = toPrepare.back().id;
|
result = toPrepare.back().id;
|
||||||
}
|
}
|
||||||
if (!thread) {
|
if (!thread) {
|
||||||
|
|
|
@ -25,11 +25,11 @@ enum ToPrepareMediaType {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ToPrepareMedia {
|
struct ToPrepareMedia {
|
||||||
ToPrepareMedia(const QString &file, const PeerId &peer, ToPrepareMediaType t, bool ctrlShiftEnter) : id(MTP::nonce<PhotoId>()), file(file), peer(peer), type(t), ctrlShiftEnter(ctrlShiftEnter) {
|
ToPrepareMedia(const QString &file, const PeerId &peer, ToPrepareMediaType t, bool ctrlShiftEnter, MsgId replyTo) : id(MTP::nonce<PhotoId>()), file(file), peer(peer), type(t), ctrlShiftEnter(ctrlShiftEnter), replyTo(replyTo) {
|
||||||
}
|
}
|
||||||
ToPrepareMedia(const QImage &img, const PeerId &peer, ToPrepareMediaType t, bool ctrlShiftEnter) : id(MTP::nonce<PhotoId>()), img(img), peer(peer), type(t), ctrlShiftEnter(ctrlShiftEnter) {
|
ToPrepareMedia(const QImage &img, const PeerId &peer, ToPrepareMediaType t, bool ctrlShiftEnter, MsgId replyTo) : id(MTP::nonce<PhotoId>()), img(img), peer(peer), type(t), ctrlShiftEnter(ctrlShiftEnter), replyTo(replyTo) {
|
||||||
}
|
}
|
||||||
ToPrepareMedia(const QByteArray &data, const PeerId &peer, ToPrepareMediaType t, bool ctrlShiftEnter) : id(MTP::nonce<PhotoId>()), data(data), peer(peer), type(t), ctrlShiftEnter(ctrlShiftEnter) {
|
ToPrepareMedia(const QByteArray &data, const PeerId &peer, ToPrepareMediaType t, bool ctrlShiftEnter, MsgId replyTo) : id(MTP::nonce<PhotoId>()), data(data), peer(peer), type(t), ctrlShiftEnter(ctrlShiftEnter), replyTo(replyTo) {
|
||||||
}
|
}
|
||||||
PhotoId id;
|
PhotoId id;
|
||||||
QString file;
|
QString file;
|
||||||
|
@ -38,13 +38,14 @@ struct ToPrepareMedia {
|
||||||
PeerId peer;
|
PeerId peer;
|
||||||
ToPrepareMediaType type;
|
ToPrepareMediaType type;
|
||||||
bool ctrlShiftEnter;
|
bool ctrlShiftEnter;
|
||||||
|
MsgId replyTo;
|
||||||
};
|
};
|
||||||
typedef QList<ToPrepareMedia> ToPrepareMedias;
|
typedef QList<ToPrepareMedia> ToPrepareMedias;
|
||||||
|
|
||||||
typedef QMap<int32, QByteArray> LocalFileParts;
|
typedef QMap<int32, QByteArray> LocalFileParts;
|
||||||
struct ReadyLocalMedia {
|
struct ReadyLocalMedia {
|
||||||
ReadyLocalMedia(ToPrepareMediaType type, const QString &file, const QString &filename, int32 filesize, const QByteArray &data, const uint64 &id, const uint64 &thumbId, const QString &thumbExt, const PeerId &peer, const MTPPhoto &photo, const PreparedPhotoThumbs &photoThumbs, const MTPDocument &document, const QByteArray &jpeg, bool ctrlShiftEnter) :
|
ReadyLocalMedia(ToPrepareMediaType type, const QString &file, const QString &filename, int32 filesize, const QByteArray &data, const uint64 &id, const uint64 &thumbId, const QString &thumbExt, const PeerId &peer, const MTPPhoto &photo, const PreparedPhotoThumbs &photoThumbs, const MTPDocument &document, const QByteArray &jpeg, bool ctrlShiftEnter, MsgId replyTo) :
|
||||||
type(type), file(file), filename(filename), filesize(filesize), data(data), thumbExt(thumbExt), id(id), thumbId(thumbId), peer(peer), photo(photo), document(document), photoThumbs(photoThumbs), ctrlShiftEnter(ctrlShiftEnter) {
|
replyTo(replyTo), type(type), file(file), filename(filename), filesize(filesize), data(data), thumbExt(thumbExt), id(id), thumbId(thumbId), peer(peer), photo(photo), document(document), photoThumbs(photoThumbs), ctrlShiftEnter(ctrlShiftEnter) {
|
||||||
if (!jpeg.isEmpty()) {
|
if (!jpeg.isEmpty()) {
|
||||||
int32 size = jpeg.size();
|
int32 size = jpeg.size();
|
||||||
for (int32 i = 0, part = 0; i < size; i += UploadPartSize, ++part) {
|
for (int32 i = 0, part = 0; i < size; i += UploadPartSize, ++part) {
|
||||||
|
@ -54,6 +55,7 @@ struct ReadyLocalMedia {
|
||||||
hashMd5Hex(jpeg.constData(), jpeg.size(), jpeg_md5.data());
|
hashMd5Hex(jpeg.constData(), jpeg.size(), jpeg_md5.data());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
MsgId replyTo;
|
||||||
ToPrepareMediaType type;
|
ToPrepareMediaType type;
|
||||||
QString file, filename;
|
QString file, filename;
|
||||||
int32 filesize;
|
int32 filesize;
|
||||||
|
@ -103,10 +105,10 @@ class LocalImageLoader : public QObject {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
LocalImageLoader(QObject *parent);
|
LocalImageLoader(QObject *parent);
|
||||||
void append(const QStringList &files, const PeerId &peer, ToPrepareMediaType t = ToPrepareAuto);
|
void append(const QStringList &files, const PeerId &peer, MsgId replyTo, ToPrepareMediaType t);
|
||||||
PhotoId append(const QByteArray &img, const PeerId &peer, ToPrepareMediaType t = ToPrepareAuto);
|
PhotoId append(const QByteArray &img, const PeerId &peer, MsgId replyTo, ToPrepareMediaType t);
|
||||||
PhotoId append(const QImage &img, const PeerId &peer, ToPrepareMediaType t = ToPreparePhoto, bool ctrlShiftEnter = false);
|
PhotoId append(const QImage &img, const PeerId &peer, MsgId replyTo, ToPrepareMediaType t, bool ctrlShiftEnter = false);
|
||||||
PhotoId append(const QString &file, const PeerId &peer, ToPrepareMediaType t = ToPrepareAuto);
|
PhotoId append(const QString &file, const PeerId &peer, MsgId replyTo, ToPrepareMediaType t);
|
||||||
|
|
||||||
QMutex *readyMutex();
|
QMutex *readyMutex();
|
||||||
ReadyLocalMedias &readyList();
|
ReadyLocalMedias &readyList();
|
||||||
|
|
|
@ -1558,7 +1558,7 @@ namespace Local {
|
||||||
if (!QDir().exists(_basePath)) QDir().mkpath(_basePath);
|
if (!QDir().exists(_basePath)) QDir().mkpath(_basePath);
|
||||||
|
|
||||||
FileReadDescriptor settingsData;
|
FileReadDescriptor settingsData;
|
||||||
if (!readFile(settingsData, qsl("settings"), SafePath)) {
|
if (!readFile(settingsData, cTestMode() ? qsl("settings_test") : qsl("settings"), SafePath)) {
|
||||||
_readOldSettings();
|
_readOldSettings();
|
||||||
_readOldUserSettings(false); // needed further in _readUserSettings
|
_readOldUserSettings(false); // needed further in _readUserSettings
|
||||||
_readOldMtpData(false); // needed further in _readMtpData
|
_readOldMtpData(false); // needed further in _readMtpData
|
||||||
|
@ -1617,7 +1617,7 @@ namespace Local {
|
||||||
|
|
||||||
if (!QDir().exists(_basePath)) QDir().mkpath(_basePath);
|
if (!QDir().exists(_basePath)) QDir().mkpath(_basePath);
|
||||||
|
|
||||||
FileWriteDescriptor settings(qsl("settings"), SafePath);
|
FileWriteDescriptor settings(cTestMode() ? qsl("settings_test") : qsl("settings"), SafePath);
|
||||||
if (_settingsSalt.isEmpty() || !_settingsKey.created()) {
|
if (_settingsSalt.isEmpty() || !_settingsKey.created()) {
|
||||||
_settingsSalt.resize(LocalEncryptSaltSize);
|
_settingsSalt.resize(LocalEncryptSaltSize);
|
||||||
memset_rand(_settingsSalt.data(), _settingsSalt.size());
|
memset_rand(_settingsSalt.data(), _settingsSalt.size());
|
||||||
|
@ -1735,10 +1735,10 @@ namespace Local {
|
||||||
return _oldMapVersion;
|
return _oldMapVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeDraft(const PeerId &peer, const QString &text) {
|
void writeDraft(const PeerId &peer, const MessageDraft &draft) {
|
||||||
if (!_working()) return;
|
if (!_working()) return;
|
||||||
|
|
||||||
if (text.isEmpty()) {
|
if (draft.replyTo <= 0 && draft.text.isEmpty()) {
|
||||||
DraftsMap::iterator i = _draftsMap.find(peer);
|
DraftsMap::iterator i = _draftsMap.find(peer);
|
||||||
if (i != _draftsMap.cend()) {
|
if (i != _draftsMap.cend()) {
|
||||||
clearKey(i.value());
|
clearKey(i.value());
|
||||||
|
@ -1755,8 +1755,8 @@ namespace Local {
|
||||||
_mapChanged = true;
|
_mapChanged = true;
|
||||||
_writeMap(WriteMapFast);
|
_writeMap(WriteMapFast);
|
||||||
}
|
}
|
||||||
EncryptedDescriptor data(sizeof(quint64) + _stringSize(text));
|
EncryptedDescriptor data(sizeof(quint64) + _stringSize(draft.text) + sizeof(qint32));
|
||||||
data.stream << quint64(peer) << text;
|
data.stream << quint64(peer) << draft.text << qint32(draft.replyTo);
|
||||||
FileWriteDescriptor file(i.value());
|
FileWriteDescriptor file(i.value());
|
||||||
file.writeEncrypted(data);
|
file.writeEncrypted(data);
|
||||||
|
|
||||||
|
@ -1764,24 +1764,26 @@ namespace Local {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString readDraft(const PeerId &peer) {
|
MessageDraft readDraft(const PeerId &peer) {
|
||||||
if (!_draftsNotReadMap.remove(peer)) return QString();
|
if (!_draftsNotReadMap.remove(peer)) return MessageDraft();
|
||||||
|
|
||||||
DraftsMap::iterator j = _draftsMap.find(peer);
|
DraftsMap::iterator j = _draftsMap.find(peer);
|
||||||
if (j == _draftsMap.cend()) {
|
if (j == _draftsMap.cend()) {
|
||||||
return QString();
|
return MessageDraft();
|
||||||
}
|
}
|
||||||
FileReadDescriptor draft;
|
FileReadDescriptor draft;
|
||||||
if (!readEncryptedFile(draft, j.value())) {
|
if (!readEncryptedFile(draft, j.value())) {
|
||||||
clearKey(j.value());
|
clearKey(j.value());
|
||||||
_draftsMap.erase(j);
|
_draftsMap.erase(j);
|
||||||
return QString();
|
return MessageDraft();
|
||||||
}
|
}
|
||||||
|
|
||||||
quint64 draftPeer;
|
quint64 draftPeer;
|
||||||
QString draftText;
|
QString draftText;
|
||||||
|
qint32 draftReplyTo = 0;
|
||||||
draft.stream >> draftPeer >> draftText;
|
draft.stream >> draftPeer >> draftText;
|
||||||
return (draftPeer == peer) ? draftText : QString();
|
if (draft.version >= 7021) draft.stream >> draftReplyTo;
|
||||||
|
return (draftPeer == peer) ? MessageDraft(MsgId(draftReplyTo), draftText) : MessageDraft();
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeDraftPositions(const PeerId &peer, const MessageCursor &cur) {
|
void writeDraftPositions(const PeerId &peer, const MessageCursor &cur) {
|
||||||
|
@ -2092,15 +2094,17 @@ namespace Local {
|
||||||
quint32 size = 0;
|
quint32 size = 0;
|
||||||
for (RecentStickerPack::const_iterator i = recent.cbegin(); i != recent.cend(); ++i) {
|
for (RecentStickerPack::const_iterator i = recent.cbegin(); i != recent.cend(); ++i) {
|
||||||
DocumentData *doc = i->first;
|
DocumentData *doc = i->first;
|
||||||
|
if (doc->status == FileFailed) continue;
|
||||||
|
|
||||||
// id + value + access + date + namelen + name + mimelen + mime + dc + size + width + height + type
|
// 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);
|
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);
|
EncryptedDescriptor data(size);
|
||||||
for (RecentStickerPack::const_iterator i = recent.cbegin(); i != recent.cend(); ++i) {
|
for (RecentStickerPack::const_iterator i = recent.cbegin(); i != recent.cend(); ++i) {
|
||||||
DocumentData *doc = i->first;
|
DocumentData *doc = i->first;
|
||||||
|
if (doc->status == FileFailed) continue;
|
||||||
|
|
||||||
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);
|
FileWriteDescriptor file(_recentStickersKey);
|
||||||
file.writeEncrypted(data);
|
file.writeEncrypted(data);
|
||||||
|
@ -2122,10 +2126,13 @@ namespace Local {
|
||||||
RecentStickerPack recent;
|
RecentStickerPack recent;
|
||||||
while (!stickers.stream.atEnd()) {
|
while (!stickers.stream.atEnd()) {
|
||||||
quint64 id, access;
|
quint64 id, access;
|
||||||
QString name, mime;
|
QString name, mime, alt;
|
||||||
qint32 date, dc, size, width, height, type;
|
qint32 date, dc, size, width, height, type;
|
||||||
qint16 value;
|
qint16 value;
|
||||||
stickers.stream >> id >> value >> access >> date >> name >> mime >> dc >> size >> width >> height >> type;
|
stickers.stream >> id >> value >> access >> date >> name >> mime >> dc >> size >> width >> height >> type;
|
||||||
|
if (stickers.version >= 7021) {
|
||||||
|
stickers.stream >> alt;
|
||||||
|
}
|
||||||
if (read.contains(id)) continue;
|
if (read.contains(id)) continue;
|
||||||
read.insert(id, true);
|
read.insert(id, true);
|
||||||
|
|
||||||
|
@ -2134,7 +2141,7 @@ namespace Local {
|
||||||
if (type == AnimatedDocument) {
|
if (type == AnimatedDocument) {
|
||||||
attributes.push_back(MTP_documentAttributeAnimated());
|
attributes.push_back(MTP_documentAttributeAnimated());
|
||||||
} else if (type == StickerDocument) {
|
} else if (type == StickerDocument) {
|
||||||
attributes.push_back(MTP_documentAttributeSticker());
|
attributes.push_back(MTP_documentAttributeSticker(MTP_string(alt)));
|
||||||
}
|
}
|
||||||
if (width > 0 && height > 0) {
|
if (width > 0 && height > 0) {
|
||||||
attributes.push_back(MTP_documentAttributeImageSize(MTP_int(width), MTP_int(height)));
|
attributes.push_back(MTP_documentAttributeImageSize(MTP_int(width), MTP_int(height)));
|
||||||
|
|
|
@ -100,8 +100,14 @@ namespace Local {
|
||||||
ReadMapState readMap(const QByteArray &pass);
|
ReadMapState readMap(const QByteArray &pass);
|
||||||
int32 oldMapVersion();
|
int32 oldMapVersion();
|
||||||
|
|
||||||
void writeDraft(const PeerId &peer, const QString &text);
|
struct MessageDraft {
|
||||||
QString readDraft(const PeerId &peer);
|
MessageDraft(MsgId replyTo = 0, QString text = QString()) : replyTo(replyTo), text(text) {
|
||||||
|
}
|
||||||
|
MsgId replyTo;
|
||||||
|
QString text;
|
||||||
|
};
|
||||||
|
void writeDraft(const PeerId &peer, const MessageDraft &draft);
|
||||||
|
MessageDraft readDraft(const PeerId &peer);
|
||||||
void writeDraftPositions(const PeerId &peer, const MessageCursor &cur);
|
void writeDraftPositions(const PeerId &peer, const MessageCursor &cur);
|
||||||
MessageCursor readDraftPositions(const PeerId &peer);
|
MessageCursor readDraftPositions(const PeerId &peer);
|
||||||
bool hasDraftPositions(const PeerId &peer);
|
bool hasDraftPositions(const PeerId &peer);
|
||||||
|
|
|
@ -40,7 +40,7 @@ namespace {
|
||||||
QDateTime tm(QDateTime::currentDateTime());
|
QDateTime tm(QDateTime::currentDateTime());
|
||||||
|
|
||||||
QThread *thread = QThread::currentThread();
|
QThread *thread = QThread::currentThread();
|
||||||
MTPThread *mtpThread = dynamic_cast<MTPThread*>(thread);
|
MTPThread *mtpThread = qobject_cast<MTPThread*>(thread);
|
||||||
uint32 threadId = mtpThread ? mtpThread->getThreadId() : 0;
|
uint32 threadId = mtpThread ? mtpThread->getThreadId() : 0;
|
||||||
|
|
||||||
return QString("[%1 %2-%3]").arg(tm.toString("hh:mm:ss.zzz")).arg(QString("%1").arg(threadId, 2, 10, zero)).arg(++logEntry, 7, 10, zero);
|
return QString("[%1 %2-%3]").arg(tm.toString("hh:mm:ss.zzz")).arg(QString("%1").arg(threadId, 2, 10, zero)).arg(++logEntry, 7, 10, zero);
|
||||||
|
|
|
@ -350,11 +350,10 @@ MainWidget *TopBarWidget::main() {
|
||||||
|
|
||||||
MainWidget::MainWidget(Window *window) : QWidget(window), _started(0), failedObjId(0), _dialogsWidth(st::dlgMinWidth),
|
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),
|
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), updSkipPtsUpdateLevel(0), _onlineRequest(0), _lastWasOnline(false), _lastSetOnline(0), _isIdle(false),
|
||||||
_failDifferenceTimeout(1), _lastUpdateTime(0), _cachedX(0), _cachedY(0), _background(0) {
|
_failDifferenceTimeout(1), _lastUpdateTime(0), _cachedX(0), _cachedY(0), _background(0), _api(new ApiWrap(this)) {
|
||||||
setGeometry(QRect(0, st::titleHeight, App::wnd()->width(), App::wnd()->height() - st::titleHeight));
|
setGeometry(QRect(0, st::titleHeight, App::wnd()->width(), App::wnd()->height() - st::titleHeight));
|
||||||
|
|
||||||
App::initBackground();
|
|
||||||
updateScrollColors();
|
updateScrollColors();
|
||||||
|
|
||||||
connect(window, SIGNAL(resized(const QSize &)), this, SLOT(onParentResize(const QSize &)));
|
connect(window, SIGNAL(resized(const QSize &)), this, SLOT(onParentResize(const QSize &)));
|
||||||
|
@ -366,6 +365,7 @@ _failDifferenceTimeout(1), _lastUpdateTime(0), _cachedX(0), _cachedY(0), _backgr
|
||||||
connect(&_onlineUpdater, SIGNAL(timeout()), this, SLOT(updateOnlineDisplay()));
|
connect(&_onlineUpdater, SIGNAL(timeout()), this, SLOT(updateOnlineDisplay()));
|
||||||
connect(&_idleFinishTimer, SIGNAL(timeout()), this, SLOT(checkIdleFinish()));
|
connect(&_idleFinishTimer, SIGNAL(timeout()), this, SLOT(checkIdleFinish()));
|
||||||
connect(&_bySeqTimer, SIGNAL(timeout()), this, SLOT(getDifference()));
|
connect(&_bySeqTimer, SIGNAL(timeout()), this, SLOT(getDifference()));
|
||||||
|
connect(&_byPtsTimer, SIGNAL(timeout()), this, SLOT(getDifference()));
|
||||||
connect(&_failDifferenceTimer, SIGNAL(timeout()), this, SLOT(getDifferenceForce()));
|
connect(&_failDifferenceTimer, SIGNAL(timeout()), this, SLOT(getDifferenceForce()));
|
||||||
connect(this, SIGNAL(peerUpdated(PeerData*)), &history, SLOT(peerUpdated(PeerData*)));
|
connect(this, SIGNAL(peerUpdated(PeerData*)), &history, SLOT(peerUpdated(PeerData*)));
|
||||||
connect(&_topBar, SIGNAL(clicked()), this, SLOT(onTopBarClick()));
|
connect(&_topBar, SIGNAL(clicked()), this, SLOT(onTopBarClick()));
|
||||||
|
@ -400,7 +400,7 @@ _failDifferenceTimeout(1), _lastUpdateTime(0), _cachedX(0), _cachedY(0), _backgr
|
||||||
show();
|
show();
|
||||||
setFocus();
|
setFocus();
|
||||||
|
|
||||||
App::initMedia();
|
_api->init();
|
||||||
}
|
}
|
||||||
|
|
||||||
mtpRequestId MainWidget::onForward(const PeerId &peer, bool forwardSelected) {
|
mtpRequestId MainWidget::onForward(const PeerId &peer, bool forwardSelected) {
|
||||||
|
@ -570,7 +570,7 @@ void MainWidget::deleteHistory(PeerData *peer, const MTPmessages_StatedMessage &
|
||||||
|
|
||||||
void MainWidget::deleteHistoryPart(PeerData *peer, const MTPmessages_AffectedHistory &result) {
|
void MainWidget::deleteHistoryPart(PeerData *peer, const MTPmessages_AffectedHistory &result) {
|
||||||
const MTPDmessages_affectedHistory &d(result.c_messages_affectedHistory());
|
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;
|
int32 offset = d.voffset.v;
|
||||||
if (!MTP::authedId() || offset <= 0) return;
|
if (!MTP::authedId() || offset <= 0) return;
|
||||||
|
@ -578,6 +578,10 @@ void MainWidget::deleteHistoryPart(PeerData *peer, const MTPmessages_AffectedHis
|
||||||
MTP::send(MTPmessages_DeleteHistory(peer->input, d.voffset), rpcDone(&MainWidget::deleteHistoryPart, peer));
|
MTP::send(MTPmessages_DeleteHistory(peer->input, d.voffset), rpcDone(&MainWidget::deleteHistoryPart, peer));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWidget::deleteMessages(const QVector<MTPint> &ids) {
|
||||||
|
MTP::send(MTPmessages_DeleteMessages(MTP_vector<MTPint>(ids)), rpcDone(&MainWidget::msgsWereDeleted));
|
||||||
|
}
|
||||||
|
|
||||||
void MainWidget::deletedContact(UserData *user, const MTPcontacts_Link &result) {
|
void MainWidget::deletedContact(UserData *user, const MTPcontacts_Link &result) {
|
||||||
const MTPDcontacts_link &d(result.c_contacts_link());
|
const MTPDcontacts_link &d(result.c_contacts_link());
|
||||||
App::feedUsers(MTP_vector<MTPUser>(1, d.vuser));
|
App::feedUsers(MTP_vector<MTPUser>(1, d.vuser));
|
||||||
|
@ -779,8 +783,9 @@ DialogsIndexed &MainWidget::contactsList() {
|
||||||
return dialogs.contactsList();
|
return dialogs.contactsList();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::sendPreparedText(History *hist, const QString &text) {
|
void MainWidget::sendPreparedText(History *hist, const QString &text, MsgId replyTo) {
|
||||||
QString sendingText, leftText = text;
|
QString sendingText, leftText = text;
|
||||||
|
if (replyTo < 0) replyTo = history.replyToId();
|
||||||
while (textSplit(sendingText, leftText, MaxMessageSize)) {
|
while (textSplit(sendingText, leftText, MaxMessageSize)) {
|
||||||
MsgId newId = clientMsgId();
|
MsgId newId = clientMsgId();
|
||||||
uint64 randomId = MTP::nonce<uint64>();
|
uint64 randomId = MTP::nonce<uint64>();
|
||||||
|
@ -788,9 +793,10 @@ void MainWidget::sendPreparedText(History *hist, const QString &text) {
|
||||||
App::historyRegRandom(randomId, newId);
|
App::historyRegRandom(randomId, newId);
|
||||||
|
|
||||||
MTPstring msgText(MTP_string(sendingText));
|
MTPstring msgText(MTP_string(sendingText));
|
||||||
int32 flags = (hist->peer->input.type() == mtpc_inputPeerSelf) ? 0 : (0x01 | 0x02); // unread, out
|
int32 flags = (hist->peer->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(hist->peer->id), MTP_int(unixtime()), msgText, MTP_messageMediaEmpty()));
|
if (replyTo) flags |= MTPDmessage::flag_reply_to_msg_id;
|
||||||
hist->sendRequestId = MTP::send(MTPmessages_SendMessage(hist->peer->input, msgText, MTP_long(randomId)), App::main()->rpcDone(&MainWidget::sentDataReceived, randomId), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
|
hist->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(hist->peer->id), MTPint(), MTPint(), MTP_int(replyTo), MTP_int(unixtime()), msgText, MTP_messageMediaEmpty()));
|
||||||
|
hist->sendRequestId = MTP::send(MTPmessages_SendMessage(hist->peer->input, MTP_int(replyTo), msgText, MTP_long(randomId)), App::main()->rpcDone(&MainWidget::sentDataReceived, randomId), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
|
||||||
}
|
}
|
||||||
|
|
||||||
historyToDown(hist);
|
historyToDown(hist);
|
||||||
|
@ -799,10 +805,10 @@ void MainWidget::sendPreparedText(History *hist, const QString &text) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::sendMessage(History *hist, const QString &text) {
|
void MainWidget::sendMessage(History *hist, const QString &text, MsgId replyTo) {
|
||||||
readServerHistory(hist, false);
|
readServerHistory(hist, false);
|
||||||
hist->loadAround(0);
|
hist->loadAround(0);
|
||||||
sendPreparedText(hist, history.prepareMessage(text));
|
sendPreparedText(hist, history.prepareMessage(text), replyTo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::readServerHistory(History *hist, bool force) {
|
void MainWidget::readServerHistory(History *hist, bool force) {
|
||||||
|
@ -811,7 +817,7 @@ void MainWidget::readServerHistory(History *hist, bool force) {
|
||||||
ReadRequests::const_iterator i = _readRequests.constFind(hist->peer);
|
ReadRequests::const_iterator i = _readRequests.constFind(hist->peer);
|
||||||
if (i == _readRequests.cend()) {
|
if (i == _readRequests.cend()) {
|
||||||
hist->inboxRead(0);
|
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)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -872,7 +878,7 @@ void MainWidget::overviewPreloaded(PeerData *peer, const MTPmessages_Messages &r
|
||||||
const MTPDmessages_messages &d(result.c_messages_messages());
|
const MTPDmessages_messages &d(result.c_messages_messages());
|
||||||
App::feedUsers(d.vusers);
|
App::feedUsers(d.vusers);
|
||||||
App::feedChats(d.vchats);
|
App::feedChats(d.vchats);
|
||||||
h->_overviewCount[type] = 0;
|
h->_overviewCount[type] = d.vmessages.c_vector().v.size();
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case mtpc_messages_messagesSlice: {
|
case mtpc_messages_messagesSlice: {
|
||||||
|
@ -936,6 +942,7 @@ void MainWidget::changingMsgId(HistoryItem *row, MsgId newId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::itemRemoved(HistoryItem *item) {
|
void MainWidget::itemRemoved(HistoryItem *item) {
|
||||||
|
api()->itemRemoved(item);
|
||||||
dialogs.itemRemoved(item);
|
dialogs.itemRemoved(item);
|
||||||
if (history.peer() == item->history()->peer) {
|
if (history.peer() == item->history()->peer) {
|
||||||
history.itemRemoved(item);
|
history.itemRemoved(item);
|
||||||
|
@ -944,6 +951,7 @@ void MainWidget::itemRemoved(HistoryItem *item) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::itemReplaced(HistoryItem *oldItem, HistoryItem *newItem) {
|
void MainWidget::itemReplaced(HistoryItem *oldItem, HistoryItem *newItem) {
|
||||||
|
api()->itemReplaced(oldItem, newItem);
|
||||||
dialogs.itemReplaced(oldItem, newItem);
|
dialogs.itemReplaced(oldItem, newItem);
|
||||||
if (history.peer() == newItem->history()->peer) {
|
if (history.peer() == newItem->history()->peer) {
|
||||||
history.itemReplaced(oldItem, newItem);
|
history.itemReplaced(oldItem, newItem);
|
||||||
|
@ -1075,16 +1083,21 @@ void MainWidget::photosLoaded(History *h, const MTPmessages_Messages &msgs, mtpR
|
||||||
|
|
||||||
void MainWidget::partWasRead(PeerData *peer, const MTPmessages_AffectedHistory &result) {
|
void MainWidget::partWasRead(PeerData *peer, const MTPmessages_AffectedHistory &result) {
|
||||||
const MTPDmessages_affectedHistory &d(result.c_messages_affectedHistory());
|
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;
|
int32 offset = d.voffset.v;
|
||||||
if (!MTP::authedId() || offset <= 0) {
|
if (!MTP::authedId() || offset <= 0) {
|
||||||
_readRequests.remove(peer);
|
_readRequests.remove(peer);
|
||||||
} else {
|
} 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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWidget::msgsWereDeleted(const MTPmessages_AffectedMessages &result) {
|
||||||
|
const MTPDmessages_affectedMessages &d(result.c_messages_affectedMessages());
|
||||||
|
updPtsUpdated(d.vpts.v, d.vpts_count.v);
|
||||||
|
}
|
||||||
|
|
||||||
void MainWidget::videoLoadProgress(mtpFileLoader *loader) {
|
void MainWidget::videoLoadProgress(mtpFileLoader *loader) {
|
||||||
VideoData *video = App::video(loader->objId());
|
VideoData *video = App::video(loader->objId());
|
||||||
if (video->loader) {
|
if (video->loader) {
|
||||||
|
@ -1239,7 +1252,10 @@ void MainWidget::documentLoadProgress(mtpFileLoader *loader) {
|
||||||
void MainWidget::documentLoadFailed(mtpFileLoader *loader, bool started) {
|
void MainWidget::documentLoadFailed(mtpFileLoader *loader, bool started) {
|
||||||
loadFailed(loader, started, SLOT(documentLoadRetry()));
|
loadFailed(loader, started, SLOT(documentLoadRetry()));
|
||||||
DocumentData *document = App::document(loader->objId());
|
DocumentData *document = App::document(loader->objId());
|
||||||
if (document && document->loader) document->finish();
|
if (document) {
|
||||||
|
if (document->loader) document->finish();
|
||||||
|
document->status = FileFailed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::documentLoadRetry() {
|
void MainWidget::documentLoadRetry() {
|
||||||
|
@ -1259,16 +1275,18 @@ void MainWidget::updateOnlineDisplay() {
|
||||||
if (App::wnd()->settingsWidget()) App::wnd()->settingsWidget()->updateOnlineDisplay();
|
if (App::wnd()->settingsWidget()) App::wnd()->settingsWidget()->updateOnlineDisplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::confirmShareContact(bool ctrlShiftEnter, const QString &phone, const QString &fname, const QString &lname) {
|
void MainWidget::confirmShareContact(bool ctrlShiftEnter, const QString &phone, const QString &fname, const QString &lname, MsgId replyTo) {
|
||||||
history.confirmShareContact(ctrlShiftEnter, phone, fname, lname);
|
history.confirmShareContact(ctrlShiftEnter, phone, fname, lname, replyTo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::confirmSendImage(const ReadyLocalMedia &img) {
|
void MainWidget::confirmSendImage(const ReadyLocalMedia &img) {
|
||||||
history.confirmSendImage(img);
|
history.confirmSendImage(img);
|
||||||
|
history.onReplyCancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::confirmSendImageUncompressed(bool ctrlShiftEnter) {
|
void MainWidget::confirmSendImageUncompressed(bool ctrlShiftEnter, MsgId replyTo) {
|
||||||
history.uploadConfirmImageUncompressed(ctrlShiftEnter);
|
history.uploadConfirmImageUncompressed(ctrlShiftEnter, replyTo);
|
||||||
|
history.onReplyCancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::cancelSendImage() {
|
void MainWidget::cancelSendImage() {
|
||||||
|
@ -1286,11 +1304,11 @@ void MainWidget::dialogsCancelled() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::serviceNotification(const QString &msg, const MTPMessageMedia &media, bool unread) {
|
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;
|
QString sendingText, leftText = msg;
|
||||||
HistoryItem *item = 0;
|
HistoryItem *item = 0;
|
||||||
while (textSplit(sendingText, leftText, MaxMessageSize)) {
|
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) {
|
if (item) {
|
||||||
history.peerMessagesUpdated(item->history()->peer->id);
|
history.peerMessagesUpdated(item->history()->peer->id);
|
||||||
|
@ -1401,6 +1419,14 @@ ImagePtr MainWidget::newBackgroundThumb() {
|
||||||
return _background ? _background->thumb : ImagePtr();
|
return _background ? _background->thumb : ImagePtr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ApiWrap *MainWidget::api() {
|
||||||
|
return _api;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWidget::updateReplyTo() {
|
||||||
|
history.updateReplyTo(true);
|
||||||
|
}
|
||||||
|
|
||||||
void MainWidget::setInnerFocus() {
|
void MainWidget::setInnerFocus() {
|
||||||
if (hider || !history.peer()) {
|
if (hider || !history.peer()) {
|
||||||
if (hider && hider->wasOffered()) {
|
if (hider && hider->wasOffered()) {
|
||||||
|
@ -1694,15 +1720,11 @@ void MainWidget::sentDataReceived(uint64 randomId, const MTPmessages_SentMessage
|
||||||
|
|
||||||
if (randomId) feedUpdate(MTP_updateMessageID(d.vid, MTP_long(randomId))); // ignore real date
|
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 (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;
|
} break;
|
||||||
|
|
||||||
|
@ -1711,17 +1733,12 @@ void MainWidget::sentDataReceived(uint64 randomId, const MTPmessages_SentMessage
|
||||||
|
|
||||||
if (randomId) feedUpdate(MTP_updateMessageID(d.vid, MTP_long(randomId))); // ignore real date
|
if (randomId) feedUpdate(MTP_updateMessageID(d.vid, MTP_long(randomId))); // ignore real date
|
||||||
|
|
||||||
if (updInited && d.vseq.v) {
|
if (updInited) {
|
||||||
if (d.vseq.v <= updSeq) return;
|
if (!updPtsUpdated(d.vpts.v, d.vpts_count.v)) {
|
||||||
if (d.vseq.v > updSeq + 1) {
|
_byPtsSentMessage.insert(ptsKey(SkippedSentMessage), result);
|
||||||
_bySeqSentMessage.insert(d.vseq.v, result);
|
return;
|
||||||
return _bySeqTimer.start(WaitForSeqTimeout);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (updInited) {
|
|
||||||
updSetState(d.vpts.v, d.vdate.v, updQts, d.vseq.v);
|
|
||||||
}
|
|
||||||
|
|
||||||
App::feedUserLinks(d.vlinks);
|
App::feedUserLinks(d.vlinks);
|
||||||
} break;
|
} break;
|
||||||
};
|
};
|
||||||
|
@ -1739,7 +1756,6 @@ void MainWidget::sentFullDataReceived(uint64 randomId, const MTPmessages_StatedM
|
||||||
switch (msg->type()) {
|
switch (msg->type()) {
|
||||||
case mtpc_message: msgId = msg->c_message().vid.v; break;
|
case mtpc_message: msgId = msg->c_message().vid.v; break;
|
||||||
case mtpc_messageEmpty: msgId = msg->c_messageEmpty().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;
|
case mtpc_messageService: msgId = msg->c_messageService().vid.v; break;
|
||||||
}
|
}
|
||||||
if (msgId) {
|
if (msgId) {
|
||||||
|
@ -1757,18 +1773,16 @@ void MainWidget::sentFullDataReceived(uint64 randomId, const MTPmessages_StatedM
|
||||||
if (msg && msgId) {
|
if (msg && msgId) {
|
||||||
App::feedMessageMedia(msgId, *msg);
|
App::feedMessageMedia(msgId, *msg);
|
||||||
}
|
}
|
||||||
if (updInited && d.vseq.v) {
|
if (updInited) {
|
||||||
if (d.vseq.v <= updSeq) return;
|
if (!updPtsUpdated(d.vpts.v, d.vpts_count.v)) {
|
||||||
if (d.vseq.v > updSeq + 1) {
|
_byPtsStatedMessage.insert(ptsKey(SkippedStatedMessage), result);
|
||||||
_bySeqStatedMessage.insert(d.vseq.v, result);
|
return;
|
||||||
return _bySeqTimer.start(WaitForSeqTimeout);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!randomId) {
|
if (!randomId) {
|
||||||
feedUpdate(MTP_updateNewMessage(d.vmessage, d.vpts));
|
++updSkipPtsUpdateLevel;
|
||||||
}
|
feedUpdate(MTP_updateNewMessage(d.vmessage, d.vpts, d.vpts_count));
|
||||||
if (updInited) {
|
--updSkipPtsUpdateLevel;
|
||||||
updSetState(d.vpts.v, updDate, updQts, d.vseq.v);
|
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
@ -1780,20 +1794,17 @@ void MainWidget::sentFullDataReceived(uint64 randomId, const MTPmessages_StatedM
|
||||||
if (msg && msgId) {
|
if (msg && msgId) {
|
||||||
App::feedMessageMedia(msgId, *msg);
|
App::feedMessageMedia(msgId, *msg);
|
||||||
}
|
}
|
||||||
if (updInited && d.vseq.v) {
|
if (updInited) {
|
||||||
if (d.vseq.v <= updSeq) return;
|
if (!updPtsUpdated(d.vpts.v, d.vpts_count.v)) {
|
||||||
if (d.vseq.v > updSeq + 1) {
|
_byPtsStatedMessage.insert(ptsKey(SkippedStatedMessage), result);
|
||||||
_bySeqStatedMessage.insert(d.vseq.v, result);
|
return;
|
||||||
return _bySeqTimer.start(WaitForSeqTimeout);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!randomId) {
|
if (!randomId) {
|
||||||
feedUpdate(MTP_updateNewMessage(d.vmessage, d.vpts));
|
++updSkipPtsUpdateLevel;
|
||||||
|
feedUpdate(MTP_updateNewMessage(d.vmessage, d.vpts, d.vpts_count));
|
||||||
|
--updSkipPtsUpdateLevel;
|
||||||
}
|
}
|
||||||
if (updInited) {
|
|
||||||
updSetState(d.vpts.v, updDate, updQts, d.vseq.v);
|
|
||||||
}
|
|
||||||
|
|
||||||
App::feedUserLinks(d.vlinks);
|
App::feedUserLinks(d.vlinks);
|
||||||
} break;
|
} break;
|
||||||
};
|
};
|
||||||
|
@ -1803,42 +1814,33 @@ void MainWidget::sentFullDatasReceived(const MTPmessages_StatedMessages &result)
|
||||||
switch (result.type()) {
|
switch (result.type()) {
|
||||||
case mtpc_messages_statedMessages: {
|
case mtpc_messages_statedMessages: {
|
||||||
const MTPDmessages_statedMessages &d(result.c_messages_statedMessages());
|
const MTPDmessages_statedMessages &d(result.c_messages_statedMessages());
|
||||||
if (updInited && d.vseq.v) {
|
if (updInited) {
|
||||||
if (d.vseq.v <= updSeq) return;
|
if (!updPtsUpdated(d.vpts.v, d.vpts_count.v)) {
|
||||||
if (d.vseq.v > updSeq + 1) {
|
_byPtsStatedMessages.insert(ptsKey(SkippedStatedMessages), result);
|
||||||
_bySeqStatedMessages.insert(d.vseq.v, result);
|
return;
|
||||||
return _bySeqTimer.start(WaitForSeqTimeout);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
App::feedUsers(d.vusers);
|
App::feedUsers(d.vusers);
|
||||||
App::feedChats(d.vchats);
|
App::feedChats(d.vchats);
|
||||||
App::feedMsgs(d.vmessages, true);
|
App::feedMsgs(d.vmessages, 1);
|
||||||
history.peerMessagesUpdated();
|
history.peerMessagesUpdated();
|
||||||
|
|
||||||
if (updInited) {
|
|
||||||
updSetState(d.vpts.v, updDate, updQts, d.vseq.v);
|
|
||||||
}
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case mtpc_messages_statedMessagesLinks: {
|
case mtpc_messages_statedMessagesLinks: {
|
||||||
const MTPDmessages_statedMessagesLinks &d(result.c_messages_statedMessagesLinks());
|
const MTPDmessages_statedMessagesLinks &d(result.c_messages_statedMessagesLinks());
|
||||||
|
|
||||||
if (updInited && d.vseq.v) {
|
if (updInited) {
|
||||||
if (d.vseq.v <= updSeq) return;
|
if (!updPtsUpdated(d.vpts.v, d.vpts_count.v)) {
|
||||||
if (d.vseq.v > updSeq + 1) {
|
_byPtsStatedMessages.insert(ptsKey(SkippedStatedMessages), result);
|
||||||
_bySeqStatedMessages.insert(d.vseq.v, result);
|
return;
|
||||||
return _bySeqTimer.start(WaitForSeqTimeout);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
App::feedUsers(d.vusers);
|
App::feedUsers(d.vusers);
|
||||||
App::feedChats(d.vchats);
|
App::feedChats(d.vchats);
|
||||||
App::feedMsgs(d.vmessages, true);
|
App::feedMsgs(d.vmessages, 1);
|
||||||
history.peerMessagesUpdated();
|
history.peerMessagesUpdated();
|
||||||
if (updInited) {
|
|
||||||
updSetState(d.vpts.v, updDate, updQts, d.vseq.v);
|
|
||||||
}
|
|
||||||
|
|
||||||
App::feedUserLinks(d.vlinks);
|
App::feedUserLinks(d.vlinks);
|
||||||
} break;
|
} break;
|
||||||
|
@ -1868,8 +1870,8 @@ void MainWidget::dialogsToUp() {
|
||||||
dialogs.dialogsToUp();
|
dialogs.dialogsToUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::newUnreadMsg(History *hist, MsgId msgId) {
|
void MainWidget::newUnreadMsg(History *hist, HistoryItem *item) {
|
||||||
history.newUnreadMsg(hist, msgId);
|
history.newUnreadMsg(hist, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::historyWasRead() {
|
void MainWidget::historyWasRead() {
|
||||||
|
@ -2133,7 +2135,7 @@ bool MainWidget::updateFail(const RPCError &e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::updSetState(int32 pts, int32 date, int32 qts, int32 seq) {
|
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 (updDate < date) updDate = date;
|
||||||
if (qts && updQts < qts) {
|
if (qts && updQts < qts) {
|
||||||
updQts = qts;
|
updQts = qts;
|
||||||
|
@ -2150,59 +2152,7 @@ void MainWidget::updSetState(int32 pts, int32 date, int32 qts, int32 seq) {
|
||||||
return handleUpdates(v);
|
return handleUpdates(v);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!_bySeqTimer.isActive()) _bySeqTimer.start(WaitForSeqTimeout);
|
if (!_bySeqTimer.isActive()) _bySeqTimer.start(WaitForSkippedTimeout);
|
||||||
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);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2228,7 +2178,7 @@ void MainWidget::gotDifference(const MTPupdates_Difference &diff) {
|
||||||
switch (diff.type()) {
|
switch (diff.type()) {
|
||||||
case mtpc_updates_differenceEmpty: {
|
case mtpc_updates_differenceEmpty: {
|
||||||
const MTPDupdates_differenceEmpty &d(diff.c_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));
|
MTP::setGlobalDoneHandler(rpcDone(&MainWidget::updateReceived));
|
||||||
_lastUpdateTime = getms(true);
|
_lastUpdateTime = getms(true);
|
||||||
|
@ -2256,13 +2206,51 @@ void MainWidget::gotDifference(const MTPupdates_Difference &diff) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::updUpdated(int32 pts, int32 seq) {
|
uint64 MainWidget::ptsKey(PtsSkippedQueue queue) {
|
||||||
if (!updInited) return;
|
return _byPtsQueue.insert(uint64(uint32(updLastPts)) << 32 | uint64(uint32(updPtsCount)), queue).key();
|
||||||
if (seq && (seq < updSeq || seq > updSeq + 1)) {
|
}
|
||||||
_bySeqPart.insert(seq, pts);
|
|
||||||
return _bySeqTimer.start(WaitForSeqTimeout);
|
void MainWidget::applySkippedPtsUpdates() {
|
||||||
|
if (_byPtsTimer.isActive()) _byPtsTimer.stop();
|
||||||
|
if (_byPtsQueue.isEmpty()) return;
|
||||||
|
++updSkipPtsUpdateLevel;
|
||||||
|
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);
|
--updSkipPtsUpdateLevel;
|
||||||
|
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 || updSkipPtsUpdateLevel) 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) {
|
void MainWidget::feedDifference(const MTPVector<MTPUser> &users, const MTPVector<MTPChat> &chats, const MTPVector<MTPMessage> &msgs, const MTPVector<MTPUpdate> &other) {
|
||||||
|
@ -2270,7 +2258,7 @@ void MainWidget::feedDifference(const MTPVector<MTPUser> &users, const MTPVector
|
||||||
App::feedUsers(users);
|
App::feedUsers(users);
|
||||||
App::feedChats(chats);
|
App::feedChats(chats);
|
||||||
feedMessageIds(other);
|
feedMessageIds(other);
|
||||||
App::feedMsgs(msgs, true);
|
App::feedMsgs(msgs, 1);
|
||||||
feedUpdates(other, true);
|
feedUpdates(other, true);
|
||||||
history.peerMessagesUpdated();
|
history.peerMessagesUpdated();
|
||||||
}
|
}
|
||||||
|
@ -2296,19 +2284,18 @@ void MainWidget::getDifference() {
|
||||||
if (!updInited) return;
|
if (!updInited) return;
|
||||||
|
|
||||||
_bySeqUpdates.clear();
|
_bySeqUpdates.clear();
|
||||||
_bySeqSentMessage.clear();
|
|
||||||
_bySeqStatedMessage.clear();
|
|
||||||
_bySeqStatedMessages.clear();
|
|
||||||
_bySeqPart.clear();
|
|
||||||
_bySeqTimer.stop();
|
_bySeqTimer.stop();
|
||||||
|
|
||||||
|
clearSkippedPtsUpdates();
|
||||||
|
_byPtsTimer.stop();
|
||||||
|
|
||||||
noUpdatesTimer.stop();
|
noUpdatesTimer.stop();
|
||||||
_failDifferenceTimer.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;
|
updInited = false;
|
||||||
MTP::setGlobalDoneHandler(RPCDoneHandlerPtr(0));
|
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) {
|
void MainWidget::start(const MTPUser &user) {
|
||||||
|
@ -2330,7 +2317,7 @@ void MainWidget::start(const MTPUser &user) {
|
||||||
_started = true;
|
_started = true;
|
||||||
App::wnd()->sendServiceHistoryRequest();
|
App::wnd()->sendServiceHistoryRequest();
|
||||||
Local::readRecentStickers();
|
Local::readRecentStickers();
|
||||||
history.updateRecentStickers();
|
history.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MainWidget::started() {
|
bool MainWidget::started() {
|
||||||
|
@ -2344,18 +2331,27 @@ void MainWidget::openLocalUrl(const QString &url) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::openUserByName(const QString &username) {
|
void MainWidget::openUserByName(const QString &username, bool toProfile) {
|
||||||
UserData *user = App::userByName(username);
|
UserData *user = App::userByName(username);
|
||||||
if (user) {
|
if (user) {
|
||||||
emit showPeerAsync(user->id, 0, false, true);
|
if (toProfile) {
|
||||||
|
showPeerProfile(user);
|
||||||
|
} else {
|
||||||
|
emit showPeerAsync(user->id, 0, false, true);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
MTP::send(MTPcontacts_ResolveUsername(MTP_string(username)), rpcDone(&MainWidget::usernameResolveDone), rpcFail(&MainWidget::usernameResolveFail, username));
|
MTP::send(MTPcontacts_ResolveUsername(MTP_string(username)), rpcDone(&MainWidget::usernameResolveDone, toProfile), rpcFail(&MainWidget::usernameResolveFail, username));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::usernameResolveDone(const MTPUser &user) {
|
void MainWidget::usernameResolveDone(bool toProfile, const MTPUser &user) {
|
||||||
App::wnd()->hideLayer();
|
App::wnd()->hideLayer();
|
||||||
showPeer(App::feedUsers(MTP_vector<MTPUser>(1, user))->id, 0, false, true);
|
UserData *u = App::feedUsers(MTP_vector<MTPUser>(1, user));
|
||||||
|
if (toProfile) {
|
||||||
|
showPeerProfile(u);
|
||||||
|
} else {
|
||||||
|
showPeer(u->id, 0, false, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MainWidget::usernameResolveFail(QString name, const RPCError &error) {
|
bool MainWidget::usernameResolveFail(QString name, const RPCError &error) {
|
||||||
|
@ -2579,7 +2575,7 @@ MainWidget::~MainWidget() {
|
||||||
|
|
||||||
delete hider;
|
delete hider;
|
||||||
MTP::clearGlobalHandlers();
|
MTP::clearGlobalHandlers();
|
||||||
App::deinitMedia(false);
|
delete _api;
|
||||||
if (App::wnd()) App::wnd()->noMain(this);
|
if (App::wnd()) App::wnd()->noMain(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2666,7 +2662,7 @@ void MainWidget::handleUpdates(const MTPUpdates &updates) {
|
||||||
if (d.vseq.v <= updSeq) return;
|
if (d.vseq.v <= updSeq) return;
|
||||||
if (d.vseq.v > updSeq + 1) {
|
if (d.vseq.v > updSeq + 1) {
|
||||||
_bySeqUpdates.insert(d.vseq.v, updates);
|
_bySeqUpdates.insert(d.vseq.v, updates);
|
||||||
return _bySeqTimer.start(WaitForSeqTimeout);
|
return _bySeqTimer.start(WaitForSkippedTimeout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2674,7 +2670,7 @@ void MainWidget::handleUpdates(const MTPUpdates &updates) {
|
||||||
App::feedUsers(d.vusers);
|
App::feedUsers(d.vusers);
|
||||||
feedUpdates(d.vupdates);
|
feedUpdates(d.vupdates);
|
||||||
|
|
||||||
updSetState(updPts, d.vdate.v, updQts, d.vseq.v);
|
updSetState(0, d.vdate.v, updQts, d.vseq.v);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case mtpc_updatesCombined: {
|
case mtpc_updatesCombined: {
|
||||||
|
@ -2683,7 +2679,7 @@ void MainWidget::handleUpdates(const MTPUpdates &updates) {
|
||||||
if (d.vseq_start.v <= updSeq) return;
|
if (d.vseq_start.v <= updSeq) return;
|
||||||
if (d.vseq_start.v > updSeq + 1) {
|
if (d.vseq_start.v > updSeq + 1) {
|
||||||
_bySeqUpdates.insert(d.vseq_start.v, updates);
|
_bySeqUpdates.insert(d.vseq_start.v, updates);
|
||||||
return _bySeqTimer.start(WaitForSeqTimeout);
|
return _bySeqTimer.start(WaitForSkippedTimeout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2691,7 +2687,7 @@ void MainWidget::handleUpdates(const MTPUpdates &updates) {
|
||||||
App::feedUsers(d.vusers);
|
App::feedUsers(d.vusers);
|
||||||
feedUpdates(d.vupdates);
|
feedUpdates(d.vupdates);
|
||||||
|
|
||||||
updSetState(updPts, d.vdate.v, updQts, d.vseq.v);
|
updSetState(0, d.vdate.v, updQts, d.vseq.v);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case mtpc_updateShort: {
|
case mtpc_updateShort: {
|
||||||
|
@ -2699,47 +2695,38 @@ void MainWidget::handleUpdates(const MTPUpdates &updates) {
|
||||||
|
|
||||||
feedUpdate(d.vupdate);
|
feedUpdate(d.vupdate);
|
||||||
|
|
||||||
updSetState(updPts, d.vdate.v, updQts, updSeq);
|
updSetState(0, d.vdate.v, updQts, updSeq);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case mtpc_updateShortMessage: {
|
case mtpc_updateShortMessage: {
|
||||||
const MTPDupdateShortMessage &d(updates.c_updateShortMessage());
|
const MTPDupdateShortMessage &d(updates.c_updateShortMessage());
|
||||||
if (d.vseq.v) {
|
if (!updPtsUpdated(d.vpts.v, d.vpts_count.v)) {
|
||||||
if (d.vseq.v <= updSeq) return;
|
_byPtsUpdates.insert(ptsKey(SkippedUpdates), updates);
|
||||||
if (d.vseq.v > updSeq + 1) {
|
return;
|
||||||
_bySeqUpdates.insert(d.vseq.v, updates);
|
|
||||||
return _bySeqTimer.start(WaitForSeqTimeout);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (!App::userLoaded(d.vuser_id.v)) return getDifference();
|
||||||
if (!App::userLoaded(d.vfrom_id.v)) return getDifference();
|
bool out = (d.vflags.v & MTPDmessage_flag_out);
|
||||||
int32 flags = 0x01; // unread
|
HistoryItem *item = App::histories().addToBack(MTP_message(d.vflags, d.vid, out ? MTP_int(MTP::authedId()) : d.vuser_id, MTP_peerUser(out ? d.vuser_id : MTP_int(MTP::authedId())), d.vfwd_from_id, d.vfwd_date, d.vreply_to_msg_id, d.vdate, d.vmessage, MTP_messageMediaEmpty()));
|
||||||
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()));
|
|
||||||
if (item) {
|
if (item) {
|
||||||
history.peerMessagesUpdated(item->history()->peer->id);
|
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;
|
} break;
|
||||||
|
|
||||||
case mtpc_updateShortChatMessage: {
|
case mtpc_updateShortChatMessage: {
|
||||||
const MTPDupdateShortChatMessage &d(updates.c_updateShortChatMessage());
|
const MTPDupdateShortChatMessage &d(updates.c_updateShortChatMessage());
|
||||||
if (d.vseq.v) {
|
if (!updPtsUpdated(d.vpts.v, d.vpts_count.v)) {
|
||||||
if (d.vseq.v <= updSeq) return;
|
_byPtsUpdates.insert(ptsKey(SkippedUpdates), updates);
|
||||||
if (d.vseq.v > updSeq + 1) {
|
return;
|
||||||
_bySeqUpdates.insert(d.vseq.v, updates);
|
|
||||||
return _bySeqTimer.start(WaitForSeqTimeout);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (!App::chatLoaded(d.vchat_id.v) || !App::userLoaded(d.vfrom_id.v) || (d.has_fwd_from_id() && !App::userLoaded(d.vfwd_from_id.v))) return getDifference();
|
||||||
if (!App::chatLoaded(d.vchat_id.v) || !App::userLoaded(d.vfrom_id.v)) return getDifference();
|
HistoryItem *item = App::histories().addToBack(MTP_message(d.vflags, d.vid, d.vfrom_id, MTP_peerChat(d.vchat_id), d.vfwd_from_id, d.vfwd_date, d.vreply_to_msg_id, d.vdate, d.vmessage, MTP_messageMediaEmpty()));
|
||||||
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()));
|
|
||||||
if (item) {
|
if (item) {
|
||||||
history.peerMessagesUpdated(item->history()->peer->id);
|
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;
|
} break;
|
||||||
|
|
||||||
case mtpc_updatesTooLong: {
|
case mtpc_updatesTooLong: {
|
||||||
|
@ -2754,11 +2741,14 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
|
||||||
switch (update.type()) {
|
switch (update.type()) {
|
||||||
case mtpc_updateNewMessage: {
|
case mtpc_updateNewMessage: {
|
||||||
const MTPDupdateNewMessage &d(update.c_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);
|
HistoryItem *item = App::histories().addToBack(d.vmessage);
|
||||||
if (item) {
|
if (item) {
|
||||||
history.peerMessagesUpdated(item->history()->peer->id);
|
history.peerMessagesUpdated(item->history()->peer->id);
|
||||||
}
|
}
|
||||||
if (updPts < d.vpts.v) updPts = d.vpts.v;
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case mtpc_updateMessageID: {
|
case mtpc_updateMessageID: {
|
||||||
|
@ -2799,20 +2789,41 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
|
||||||
|
|
||||||
case mtpc_updateReadMessages: {
|
case mtpc_updateReadMessages: {
|
||||||
const MTPDupdateReadMessages &d(update.c_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);
|
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;
|
} break;
|
||||||
|
|
||||||
case mtpc_updateDeleteMessages: {
|
case mtpc_updateDeleteMessages: {
|
||||||
const MTPDupdateDeleteMessages &d(update.c_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);
|
App::feedWereDeleted(d.vmessages.c_vector().v);
|
||||||
history.peerMessagesUpdated();
|
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;
|
} break;
|
||||||
|
|
||||||
case mtpc_updateUserTyping: {
|
case mtpc_updateUserTyping: {
|
||||||
|
@ -2923,7 +2934,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
|
||||||
UserData *user = App::userLoaded(d.vuser_id.v);
|
UserData *user = App::userLoaded(d.vuser_id.v);
|
||||||
if (user) {
|
if (user) {
|
||||||
if (App::history(user->id)->loadedAtBottom()) {
|
if (App::history(user->id)->loadedAtBottom()) {
|
||||||
App::history(user->id)->addToBackService(clientMsgId(), date(d.vdate), lng_action_user_registered(lt_from, user->name), false, true);
|
App::history(user->id)->addToBackService(clientMsgId(), date(d.vdate), lng_action_user_registered(lt_from, user->name), MTPDmessage_flag_unread);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
@ -2953,19 +2964,12 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case mtpc_updateActivation: {
|
|
||||||
const MTPDupdateActivation &d(update.c_updateActivation());
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case mtpc_updateNewGeoChatMessage: {
|
case mtpc_updateNewGeoChatMessage: {
|
||||||
const MTPDupdateNewGeoChatMessage &d(update.c_updateNewGeoChatMessage());
|
const MTPDupdateNewGeoChatMessage &d(update.c_updateNewGeoChatMessage());
|
||||||
// PeerId peer = App::histories().addToBack(d.vmessage);
|
|
||||||
// history.peerMessagesUpdated(peer);
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case mtpc_updateNewEncryptedMessage: {
|
case mtpc_updateNewEncryptedMessage: {
|
||||||
const MTPDupdateNewEncryptedMessage &d(update.c_updateNewEncryptedMessage());
|
const MTPDupdateNewEncryptedMessage &d(update.c_updateNewEncryptedMessage());
|
||||||
// if (d.vqts.v && updQts < d.vqts.v) updQts = d.vqts.v;
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case mtpc_updateEncryptedChatTyping: {
|
case mtpc_updateEncryptedChatTyping: {
|
||||||
|
|
|
@ -17,13 +17,11 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QtWidgets/QWidget>
|
|
||||||
#include "gui/flatbutton.h"
|
|
||||||
|
|
||||||
#include "dialogswidget.h"
|
#include "dialogswidget.h"
|
||||||
#include "historywidget.h"
|
#include "historywidget.h"
|
||||||
#include "profilewidget.h"
|
#include "profilewidget.h"
|
||||||
#include "overviewwidget.h"
|
#include "overviewwidget.h"
|
||||||
|
#include "apiwrap.h"
|
||||||
|
|
||||||
class Window;
|
class Window;
|
||||||
struct DialogRow;
|
struct DialogRow;
|
||||||
|
@ -187,7 +185,7 @@ public:
|
||||||
|
|
||||||
void start(const MTPUser &user);
|
void start(const MTPUser &user);
|
||||||
void openLocalUrl(const QString &str);
|
void openLocalUrl(const QString &str);
|
||||||
void openUserByName(const QString &name);
|
void openUserByName(const QString &name, bool toProfile = false);
|
||||||
void startFull(const MTPVector<MTPUser> &users);
|
void startFull(const MTPVector<MTPUser> &users);
|
||||||
bool started();
|
bool started();
|
||||||
void applyNotifySetting(const MTPNotifyPeer &peer, const MTPPeerNotifySettings &settings, History *history = 0);
|
void applyNotifySetting(const MTPNotifyPeer &peer, const MTPPeerNotifySettings &settings, History *history = 0);
|
||||||
|
@ -213,8 +211,7 @@ public:
|
||||||
void msgUpdated(PeerId peer, const HistoryItem *msg);
|
void msgUpdated(PeerId peer, const HistoryItem *msg);
|
||||||
void historyToDown(History *hist);
|
void historyToDown(History *hist);
|
||||||
void dialogsToUp();
|
void dialogsToUp();
|
||||||
void newUnreadMsg(History *history, MsgId msgId);
|
void newUnreadMsg(History *history, HistoryItem *item);
|
||||||
void updUpdated(int32 pts, int32 seq);
|
|
||||||
void historyWasRead();
|
void historyWasRead();
|
||||||
|
|
||||||
void peerBefore(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg);
|
void peerBefore(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg);
|
||||||
|
@ -230,9 +227,9 @@ public:
|
||||||
void showBackFromStack();
|
void showBackFromStack();
|
||||||
QRect historyRect() const;
|
QRect historyRect() const;
|
||||||
|
|
||||||
void confirmShareContact(bool ctrlShiftEnter, const QString &phone, const QString &fname, const QString &lname);
|
void confirmShareContact(bool ctrlShiftEnter, const QString &phone, const QString &fname, const QString &lname, MsgId replyTo);
|
||||||
void confirmSendImage(const ReadyLocalMedia &img);
|
void confirmSendImage(const ReadyLocalMedia &img);
|
||||||
void confirmSendImageUncompressed(bool ctrlShiftEnter);
|
void confirmSendImageUncompressed(bool ctrlShiftEnter, MsgId replyTo);
|
||||||
void cancelSendImage();
|
void cancelSendImage();
|
||||||
|
|
||||||
void destroyData();
|
void destroyData();
|
||||||
|
@ -263,6 +260,7 @@ public:
|
||||||
bool leaveChatFailed(PeerData *peer, const RPCError &e);
|
bool leaveChatFailed(PeerData *peer, const RPCError &e);
|
||||||
void deleteHistory(PeerData *peer, const MTPmessages_StatedMessage &result);
|
void deleteHistory(PeerData *peer, const MTPmessages_StatedMessage &result);
|
||||||
void deleteHistoryPart(PeerData *peer, const MTPmessages_AffectedHistory &result);
|
void deleteHistoryPart(PeerData *peer, const MTPmessages_AffectedHistory &result);
|
||||||
|
void deleteMessages(const QVector<MTPint> &ids);
|
||||||
void deletedContact(UserData *user, const MTPcontacts_Link &result);
|
void deletedContact(UserData *user, const MTPcontacts_Link &result);
|
||||||
void deleteHistoryAndContact(UserData *user, const MTPcontacts_Link &result);
|
void deleteHistoryAndContact(UserData *user, const MTPcontacts_Link &result);
|
||||||
void clearHistory(PeerData *peer);
|
void clearHistory(PeerData *peer);
|
||||||
|
@ -287,8 +285,8 @@ public:
|
||||||
|
|
||||||
DialogsIndexed &contactsList();
|
DialogsIndexed &contactsList();
|
||||||
|
|
||||||
void sendMessage(History *history, const QString &text);
|
void sendMessage(History *history, const QString &text, MsgId replyTo);
|
||||||
void sendPreparedText(History *hist, const QString &text);
|
void sendPreparedText(History *hist, const QString &text, MsgId replyTo);
|
||||||
|
|
||||||
void readServerHistory(History *history, bool force = true);
|
void readServerHistory(History *history, bool force = true);
|
||||||
|
|
||||||
|
@ -325,6 +323,9 @@ public:
|
||||||
bool chatBackgroundLoading();
|
bool chatBackgroundLoading();
|
||||||
void checkChatBackground();
|
void checkChatBackground();
|
||||||
ImagePtr newBackgroundThumb();
|
ImagePtr newBackgroundThumb();
|
||||||
|
|
||||||
|
ApiWrap *api();
|
||||||
|
void updateReplyTo();
|
||||||
|
|
||||||
~MainWidget();
|
~MainWidget();
|
||||||
|
|
||||||
|
@ -383,6 +384,7 @@ public slots:
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void partWasRead(PeerData *peer, const MTPmessages_AffectedHistory &result);
|
void partWasRead(PeerData *peer, const MTPmessages_AffectedHistory &result);
|
||||||
|
void msgsWereDeleted(const MTPmessages_AffectedMessages &result);
|
||||||
void photosLoaded(History *h, const MTPmessages_Messages &msgs, mtpRequestId req);
|
void photosLoaded(History *h, const MTPmessages_Messages &msgs, mtpRequestId req);
|
||||||
|
|
||||||
bool _started;
|
bool _started;
|
||||||
|
@ -407,7 +409,7 @@ private:
|
||||||
void handleUpdates(const MTPUpdates &updates);
|
void handleUpdates(const MTPUpdates &updates);
|
||||||
bool updateFail(const RPCError &e);
|
bool updateFail(const RPCError &e);
|
||||||
|
|
||||||
void usernameResolveDone(const MTPUser &user);
|
void usernameResolveDone(bool toProfile, const MTPUser &user);
|
||||||
bool usernameResolveFail(QString name, const RPCError &error);
|
bool usernameResolveFail(QString name, const RPCError &error);
|
||||||
|
|
||||||
void hideAll();
|
void hideAll();
|
||||||
|
@ -435,8 +437,10 @@ private:
|
||||||
Dropdown _mediaType;
|
Dropdown _mediaType;
|
||||||
int32 _mediaTypeMask;
|
int32 _mediaTypeMask;
|
||||||
|
|
||||||
int updPts, updDate, updQts, updSeq;
|
int updGoodPts, updLastPts, updPtsCount;
|
||||||
|
int updDate, updQts, updSeq;
|
||||||
bool updInited;
|
bool updInited;
|
||||||
|
int updSkipPtsUpdateLevel;
|
||||||
SingleTimer noUpdatesTimer;
|
SingleTimer noUpdatesTimer;
|
||||||
|
|
||||||
mtpRequestId _onlineRequest;
|
mtpRequestId _onlineRequest;
|
||||||
|
@ -454,11 +458,26 @@ private:
|
||||||
typedef QMap<PeerData*, mtpRequestId> OverviewsPreload;
|
typedef QMap<PeerData*, mtpRequestId> OverviewsPreload;
|
||||||
OverviewsPreload _overviewPreload[OverviewCount], _overviewLoad[OverviewCount];
|
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, MTPUpdates> _bySeqUpdates;
|
||||||
QMap<int32, MTPmessages_SentMessage> _bySeqSentMessage;
|
|
||||||
QMap<int32, MTPmessages_StatedMessage> _bySeqStatedMessage;
|
|
||||||
QMap<int32, MTPmessages_StatedMessages> _bySeqStatedMessages;
|
|
||||||
QMap<int32, int32> _bySeqPart;
|
|
||||||
SingleTimer _bySeqTimer;
|
SingleTimer _bySeqTimer;
|
||||||
|
|
||||||
int32 _failDifferenceTimeout; // growing timeout for getDifference calls, if it fails
|
int32 _failDifferenceTimeout; // growing timeout for getDifference calls, if it fails
|
||||||
|
@ -473,4 +492,6 @@ private:
|
||||||
|
|
||||||
App::WallPaper *_background;
|
App::WallPaper *_background;
|
||||||
|
|
||||||
|
ApiWrap *_api;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -24,6 +24,7 @@ consts = 0
|
||||||
funcsNow = 0
|
funcsNow = 0
|
||||||
enums = [];
|
enums = [];
|
||||||
funcsDict = {};
|
funcsDict = {};
|
||||||
|
funcsList = [];
|
||||||
typesDict = {};
|
typesDict = {};
|
||||||
TypesDict = {};
|
TypesDict = {};
|
||||||
typesList = [];
|
typesList = [];
|
||||||
|
@ -114,30 +115,48 @@ with open('scheme.tl') as f:
|
||||||
|
|
||||||
paramsList = params.strip().split(' ');
|
paramsList = params.strip().split(' ');
|
||||||
prms = {};
|
prms = {};
|
||||||
|
conditions = {};
|
||||||
prmsList = [];
|
prmsList = [];
|
||||||
isTemplate = '';
|
isTemplate = hasFlags = hasTemplate = '';
|
||||||
for param in paramsList:
|
for param in paramsList:
|
||||||
if (re.match(r'^\s*$', param)):
|
if (re.match(r'^\s*$', param)):
|
||||||
continue;
|
continue;
|
||||||
pnametype = re.match(r'([a-z_][a-z0-9_]*):([A-Za-z0-9<>\._]+)', param);
|
templ = re.match(r'^{([A-Za-z]+):Type}$', param);
|
||||||
|
if (templ):
|
||||||
|
hasTemplate = templ.group(1);
|
||||||
|
continue;
|
||||||
|
pnametype = re.match(r'([a-z_][a-z0-9_]*):([A-Za-z0-9<>\._]+|![a-zA-Z]+|\#|[a-z_][a-z0-9_]*\.[0-9]+\?[A-Za-z0-9<>\._]+)$', param);
|
||||||
if (not pnametype):
|
if (not pnametype):
|
||||||
pnametypeX = re.match(r'([a-z_][a-z0-9_]*):!X', param);
|
print('Bad param found: "' + param + '" in line: ' + line);
|
||||||
if (not pnametypeX or isTemplate != ''):
|
continue;
|
||||||
print('Bad param found: "' + param + '" in line: ' + line);
|
pname = pnametype.group(1);
|
||||||
continue;
|
ptypewide = pnametype.group(2);
|
||||||
else:
|
if (re.match(r'^!([a-zA-Z]+)$', ptypewide)):
|
||||||
pname = isTemplate = pnametypeX.group(1);
|
if ('!' + hasTemplate == ptypewide):
|
||||||
|
isTemplate = pname;
|
||||||
ptype = 'TQueryType';
|
ptype = 'TQueryType';
|
||||||
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:
|
else:
|
||||||
print('Bad template type: ' + ptype);
|
print('Bad template param name: "' + param + '" in line: ' + line);
|
||||||
continue;
|
continue;
|
||||||
|
elif (ptypewide == '#'):
|
||||||
|
hasFlags = pname;
|
||||||
|
ptype = 'int';
|
||||||
|
else:
|
||||||
|
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);
|
prmsList.append(pname);
|
||||||
prms[pname] = ptype.replace('.', '_');
|
prms[pname] = ptype.replace('.', '_');
|
||||||
|
|
||||||
|
@ -175,8 +194,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
|
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)):
|
if (len(prms)):
|
||||||
funcsText += '\tMTP' + name + '(' + ', '.join(prmsStr) + ') : ' + ', '.join(prmsInit) + ' {\n\t}\n';
|
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
|
funcsText += '\tuint32 innerLength() const {\n'; # count size
|
||||||
size = [];
|
size = [];
|
||||||
for k in prmsList:
|
for k in prmsList:
|
||||||
|
@ -192,13 +221,19 @@ with open('scheme.tl') as f:
|
||||||
funcsText += '\tvoid read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_' + name + ') {\n'; # read method
|
funcsText += '\tvoid read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons = mtpc_' + name + ') {\n'; # read method
|
||||||
for k in prmsList:
|
for k in prmsList:
|
||||||
v = prms[k];
|
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 += '\t}\n';
|
||||||
|
|
||||||
funcsText += '\tvoid write(mtpBuffer &to) const {\n'; # write method
|
funcsText += '\tvoid write(mtpBuffer &to) const {\n'; # write method
|
||||||
for k in prmsList:
|
for k in prmsList:
|
||||||
v = prms[k];
|
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';
|
funcsText += '\t}\n';
|
||||||
|
|
||||||
if (isTemplate != ''):
|
if (isTemplate != ''):
|
||||||
|
@ -228,9 +263,10 @@ with open('scheme.tl') as f:
|
||||||
funcs = funcs + 1;
|
funcs = funcs + 1;
|
||||||
|
|
||||||
if (not restype in funcsDict):
|
if (not restype in funcsDict):
|
||||||
|
funcsList.append(restype);
|
||||||
funcsDict[restype] = [];
|
funcsDict[restype] = [];
|
||||||
# TypesDict[restype] = resType;
|
# TypesDict[restype] = resType;
|
||||||
funcsDict[restype].append([name, typeid, prmsList, prms]);
|
funcsDict[restype].append([name, typeid, prmsList, prms, hasFlags, conditions]);
|
||||||
else:
|
else:
|
||||||
if (isTemplate != ''):
|
if (isTemplate != ''):
|
||||||
print('Template types not allowed: "' + resType + '" in line: ' + line);
|
print('Template types not allowed: "' + resType + '" in line: ' + line);
|
||||||
|
@ -239,19 +275,21 @@ with open('scheme.tl') as f:
|
||||||
typesList.append(restype);
|
typesList.append(restype);
|
||||||
typesDict[restype] = [];
|
typesDict[restype] = [];
|
||||||
TypesDict[restype] = resType;
|
TypesDict[restype] = resType;
|
||||||
typesDict[restype].append([name, typeid, prmsList, prms]);
|
typesDict[restype].append([name, typeid, prmsList, prms, hasFlags, conditions]);
|
||||||
|
|
||||||
consts = consts + 1;
|
consts = consts + 1;
|
||||||
|
|
||||||
# text serialization: types and funcs
|
# text serialization: types and funcs
|
||||||
def addTextSerialize(dct):
|
def addTextSerialize(lst, dct, dataLetter):
|
||||||
result = '';
|
result = '';
|
||||||
for restype in dct:
|
for restype in lst:
|
||||||
v = dct[restype];
|
v = dct[restype];
|
||||||
for data in v:
|
for data in v:
|
||||||
name = data[0];
|
name = data[0];
|
||||||
prmsList = data[2];
|
prmsList = data[2];
|
||||||
prms = data[3];
|
prms = data[3];
|
||||||
|
hasFlags = data[4];
|
||||||
|
conditions = data[5];
|
||||||
|
|
||||||
if len(result):
|
if len(result):
|
||||||
result += '\n';
|
result += '\n';
|
||||||
|
@ -267,7 +305,12 @@ def addTextSerialize(dct):
|
||||||
stage = 0;
|
stage = 0;
|
||||||
for k in prmsList:
|
for k in prmsList:
|
||||||
v = prms[k];
|
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);
|
vtypeget = re.match(r'^[Vv]ector<MTP([A-Za-z0-9\._]+)>', v);
|
||||||
if (vtypeget):
|
if (vtypeget):
|
||||||
if (not re.match(r'^[A-Z]', v)):
|
if (not re.match(r'^[A-Z]', v)):
|
||||||
|
@ -308,17 +351,20 @@ def addTextSerialize(dct):
|
||||||
result += '); vtypes.push_back(0';
|
result += '); vtypes.push_back(0';
|
||||||
else:
|
else:
|
||||||
result += '0); vtypes.push_back(0';
|
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;
|
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';
|
result += '\t\t\t\t}\n';
|
||||||
else:
|
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';
|
result += '\t\t\tbreak;\n';
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
textSerialize += addTextSerialize(typesDict) + '\n';
|
textSerialize += addTextSerialize(typesList, typesDict, 'D') + '\n';
|
||||||
textSerialize += addTextSerialize(funcsDict);
|
textSerialize += addTextSerialize(funcsList, funcsDict, '');
|
||||||
|
|
||||||
for restype in typesList:
|
for restype in typesList:
|
||||||
v = typesDict[restype];
|
v = typesDict[restype];
|
||||||
|
@ -346,6 +392,8 @@ for restype in typesList:
|
||||||
typeid = data[1];
|
typeid = data[1];
|
||||||
prmsList = data[2];
|
prmsList = data[2];
|
||||||
prms = data[3];
|
prms = data[3];
|
||||||
|
hasFlags = data[4];
|
||||||
|
conditions = data[5];
|
||||||
|
|
||||||
dataText = '';
|
dataText = '';
|
||||||
dataText += '\nclass MTPD' + name + ' : public mtpDataImpl<MTPD' + name + '> {\n'; # data class
|
dataText += '\nclass MTPD' + name + ' : public mtpDataImpl<MTPD' + name + '> {\n'; # data class
|
||||||
|
@ -400,9 +448,14 @@ for restype in typesList:
|
||||||
if (withType):
|
if (withType):
|
||||||
readText += '\t\t';
|
readText += '\t\t';
|
||||||
writeText += '\t\t';
|
writeText += '\t\t';
|
||||||
readText += '\tv.v' + paramName + '.read(from, end);\n';
|
if (paramName in conditions.keys()):
|
||||||
writeText += '\tv.v' + paramName + '.write(to);\n';
|
readText += '\tif (v.has_' + paramName + '()) { v.v' + paramName + '.read(from, end); } else { v.v' + paramName + ' = MTP' + paramType + '(); }\n';
|
||||||
sizeList.append('v.v' + paramName + '.innerLength()');
|
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
|
forwards += 'class MTPD' + name + ';\n'; # data class forward declaration
|
||||||
|
|
||||||
|
@ -422,6 +475,16 @@ for restype in typesList:
|
||||||
sizeFast = '\treturn 0;\n';
|
sizeFast = '\treturn 0;\n';
|
||||||
|
|
||||||
switchLines += 'break;\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
|
dataText += '};\n'; # class ending
|
||||||
|
|
||||||
if (len(prms)):
|
if (len(prms)):
|
||||||
|
@ -586,17 +649,18 @@ for restype in typesList:
|
||||||
|
|
||||||
textSerializeFull = '\nvoid mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpPrime *end, mtpPrime cons, uint32 level, mtpPrime vcons) {\n';
|
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<mtpTypeId> types, vtypes;\n';
|
||||||
textSerializeFull += '\tQVector<int32> stages;\n';
|
textSerializeFull += '\tQVector<int32> stages, flags;\n';
|
||||||
textSerializeFull += '\ttypes.reserve(20); vtypes.reserve(20); stages.reserve(20);\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);\n\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 += '\tconst mtpPrime *start = from;\n';
|
||||||
textSerializeFull += '\tmtpTypeId type = cons, vtype = vcons;\n';
|
textSerializeFull += '\tmtpTypeId type = cons, vtype = vcons;\n';
|
||||||
textSerializeFull += '\tint32 stage = 0;\n';
|
textSerializeFull += '\tint32 stage = 0, flag = 0;\n';
|
||||||
textSerializeFull += '\ttry {\n';
|
textSerializeFull += '\ttry {\n';
|
||||||
textSerializeFull += '\t\twhile (!types.isEmpty()) {\n';
|
textSerializeFull += '\t\twhile (!types.isEmpty()) {\n';
|
||||||
textSerializeFull += '\t\t\ttype = types.back();\n';
|
textSerializeFull += '\t\t\ttype = types.back();\n';
|
||||||
textSerializeFull += '\t\t\tvtype = vtypes.back();\n';
|
textSerializeFull += '\t\t\tvtype = vtypes.back();\n';
|
||||||
textSerializeFull += '\t\t\tstage = stages.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\tif (!type) {\n';
|
||||||
textSerializeFull += '\t\t\t\tif (from >= end) {\n';
|
textSerializeFull += '\t\t\t\tif (from >= end) {\n';
|
||||||
textSerializeFull += '\t\t\t\t\tthrow Exception("from >= end");\n';
|
textSerializeFull += '\t\t\t\t\tthrow Exception("from >= end");\n';
|
||||||
|
@ -608,9 +672,53 @@ textSerializeFull += '\t\t\t\tstart = ++from;\n';
|
||||||
textSerializeFull += '\t\t\t}\n\n';
|
textSerializeFull += '\t\t\t}\n\n';
|
||||||
textSerializeFull += '\t\t\tint32 lev = level + types.size() - 1;\n';
|
textSerializeFull += '\t\t\tint32 lev = level + types.size() - 1;\n';
|
||||||
textSerializeFull += '\t\t\tswitch (type) {\n' + textSerialize + '\n';
|
textSerializeFull += '\t\t\tswitch (type) {\n' + textSerialize + '\n';
|
||||||
|
|
||||||
|
# manual types added here
|
||||||
|
textSerializeFull += '\t\t\tcase mtpc_rpc_result:\n';
|
||||||
|
textSerializeFull += '\t\t\t\tif (stage) {\n';
|
||||||
|
textSerializeFull += '\t\t\t\t\tto.add(",\\n").addSpaces(lev);\n';
|
||||||
|
textSerializeFull += '\t\t\t\t} else {\n';
|
||||||
|
textSerializeFull += '\t\t\t\t\tto.add("{ rpc_result");\n';
|
||||||
|
textSerializeFull += '\t\t\t\t\tto.add("\\n").addSpaces(lev);\n';
|
||||||
|
textSerializeFull += '\t\t\t\t}\n';
|
||||||
|
textSerializeFull += '\t\t\t\tswitch (stage) {\n';
|
||||||
|
textSerializeFull += '\t\t\t\tcase 0: to.add(" req_msg_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;\n';
|
||||||
|
textSerializeFull += '\t\t\t\tcase 1: to.add(" result: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;\n';
|
||||||
|
textSerializeFull += '\t\t\t\tdefault: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;\n';
|
||||||
|
textSerializeFull += '\t\t\t\t}\n';
|
||||||
|
textSerializeFull += '\t\t\tbreak;\n\n';
|
||||||
|
textSerializeFull += '\t\t\tcase mtpc_msg_container:\n';
|
||||||
|
textSerializeFull += '\t\t\t\tif (stage) {\n';
|
||||||
|
textSerializeFull += '\t\t\t\t\tto.add(",\\n").addSpaces(lev);\n';
|
||||||
|
textSerializeFull += '\t\t\t\t} else {\n';
|
||||||
|
textSerializeFull += '\t\t\t\t\tto.add("{ msg_container");\n';
|
||||||
|
textSerializeFull += '\t\t\t\t\tto.add("\\n").addSpaces(lev);\n';
|
||||||
|
textSerializeFull += '\t\t\t\t}\n';
|
||||||
|
textSerializeFull += '\t\t\t\tswitch (stage) {\n';
|
||||||
|
textSerializeFull += '\t\t\t\tcase 0: to.add(" messages: "); ++stages.back(); types.push_back(mtpc_vector); vtypes.push_back(mtpc_core_message); stages.push_back(0); flags.push_back(0); break;\n';
|
||||||
|
textSerializeFull += '\t\t\t\tdefault: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;\n';
|
||||||
|
textSerializeFull += '\t\t\t\t}\n';
|
||||||
|
textSerializeFull += '\t\t\tbreak;\n\n';
|
||||||
|
|
||||||
|
textSerializeFull += '\t\t\tcase mtpc_core_message: {\n';
|
||||||
|
textSerializeFull += '\t\t\t\tif (stage) {\n';
|
||||||
|
textSerializeFull += '\t\t\t\t\tto.add(",\\n").addSpaces(lev);\n';
|
||||||
|
textSerializeFull += '\t\t\t\t} else {\n';
|
||||||
|
textSerializeFull += '\t\t\t\t\tto.add("{ core_message");\n';
|
||||||
|
textSerializeFull += '\t\t\t\t\tto.add("\\n").addSpaces(lev);\n';
|
||||||
|
textSerializeFull += '\t\t\t\t}\n';
|
||||||
|
textSerializeFull += '\t\t\t\tswitch (stage) {\n';
|
||||||
|
textSerializeFull += '\t\t\t\tcase 0: to.add(" msg_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;\n';
|
||||||
|
textSerializeFull += '\t\t\t\tcase 1: to.add(" seq_no: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;\n';
|
||||||
|
textSerializeFull += '\t\t\t\tcase 2: to.add(" bytes: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;\n';
|
||||||
|
textSerializeFull += '\t\t\t\tcase 3: to.add(" body: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;\n';
|
||||||
|
textSerializeFull += '\t\t\t\tdefault: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;\n';
|
||||||
|
textSerializeFull += '\t\t\t\t}\n';
|
||||||
|
textSerializeFull += '\t\t\t\t} break;\n\n';
|
||||||
|
|
||||||
textSerializeFull += '\t\t\tdefault:\n';
|
textSerializeFull += '\t\t\tdefault:\n';
|
||||||
textSerializeFull += '\t\t\t\tmtpTextSerializeCore(to, from, end, type, lev, vtype);\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\tbreak;\n';
|
||||||
textSerializeFull += '\t\t\t}\n';
|
textSerializeFull += '\t\t\t}\n';
|
||||||
textSerializeFull += '\t\t}\n';
|
textSerializeFull += '\t\t}\n';
|
||||||
|
|
|
@ -1426,11 +1426,11 @@ void MTProtoConnectionPrivate::tryToSend() {
|
||||||
mtpRequest pingRequest;
|
mtpRequest pingRequest;
|
||||||
if (dc < _mtp_internal::dcShift) { // main session
|
if (dc < _mtp_internal::dcShift) { // main session
|
||||||
if (!prependOnly && !_pingIdToSend && !_pingId && _pingSent + (MTPPingSendAfterAuto * 1000ULL) <= getms(true)) {
|
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 (_pingIdToSend) {
|
||||||
if (prependOnly || true) {
|
if (prependOnly || dc >= _mtp_internal::dcShift) {
|
||||||
MTPPing ping(MTPping(MTP_long(_pingIdToSend)));
|
MTPPing ping(MTPping(MTP_long(_pingIdToSend)));
|
||||||
uint32 pingSize = ping.innerLength() >> 2; // copy from MTProtoSession::send
|
uint32 pingSize = ping.innerLength() >> 2; // copy from MTProtoSession::send
|
||||||
pingRequest = mtpRequestData::prepare(pingSize);
|
pingRequest = mtpRequestData::prepare(pingSize);
|
||||||
|
@ -1448,7 +1448,7 @@ void MTProtoConnectionPrivate::tryToSend() {
|
||||||
pingRequest->requestId = 0; // dont add to haveSent / wereAcked maps
|
pingRequest->requestId = 0; // dont add to haveSent / wereAcked maps
|
||||||
|
|
||||||
if (dc < _mtp_internal::dcShift && !prependOnly) { // main session
|
if (dc < _mtp_internal::dcShift && !prependOnly) { // main session
|
||||||
// _pingSender.start(MTPPingSendAfter * 1000);
|
_pingSender.start(MTPPingSendAfter * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
_pingId = _pingIdToSend;
|
_pingId = _pingIdToSend;
|
||||||
|
|
|
@ -19,6 +19,13 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
#include "mtproto/mtpCoreTypes.h"
|
#include "mtproto/mtpCoreTypes.h"
|
||||||
#include "mtproto/mtpScheme.h"
|
#include "mtproto/mtpScheme.h"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
MTPDmessage_flag_unread = (1 << 0),
|
||||||
|
MTPDmessage_flag_out = (1 << 1),
|
||||||
|
MTPDmessage_flag_notify_by_from = (1 << 4),
|
||||||
|
};
|
||||||
|
|
||||||
#include "mtproto/mtpPublicRSA.h"
|
#include "mtproto/mtpPublicRSA.h"
|
||||||
#include "mtproto/mtpAuthKey.h"
|
#include "mtproto/mtpAuthKey.h"
|
||||||
|
|
||||||
|
@ -53,6 +60,8 @@ class MTProtoConnectionPrivate;
|
||||||
class MTPSessionData;
|
class MTPSessionData;
|
||||||
|
|
||||||
class MTPThread : public QThread {
|
class MTPThread : public QThread {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MTPThread(QObject *parent = 0);
|
MTPThread(QObject *parent = 0);
|
||||||
uint32 getThreadId() const;
|
uint32 getThreadId() const;
|
||||||
|
|
|
@ -103,31 +103,6 @@ void mtpTextSerializeCore(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||||
to.add("}");
|
to.add("}");
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case mtpc_rpc_result: {
|
|
||||||
to.add("{ rpc_result");
|
|
||||||
to.add("\n").addSpaces(level);
|
|
||||||
to.add(" req_msg_id: "); mtpTextSerializeType(to, from, end, mtpc_long, level + 1); to.add(",\n").addSpaces(level);
|
|
||||||
to.add(" result: "); mtpTextSerializeType(to, from, end, 0, level + 1); to.add(",\n").addSpaces(level);
|
|
||||||
to.add("}");
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case mtpc_msg_container: {
|
|
||||||
to.add("{ msg_container");
|
|
||||||
to.add("\n").addSpaces(level);
|
|
||||||
to.add(" messages: "); mtpTextSerializeType(to, from, end, mtpc_vector, level + 1, mtpc_core_message); to.add(",\n").addSpaces(level);
|
|
||||||
to.add("}");
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case mtpc_core_message: {
|
|
||||||
to.add("{ core_message");
|
|
||||||
to.add("\n").addSpaces(level);
|
|
||||||
to.add(" msg_id: "); mtpTextSerializeType(to, from, end, mtpc_long, level + 1); to.add(",\n").addSpaces(level);
|
|
||||||
to.add(" seq_no: "); mtpTextSerializeType(to, from, end, mtpc_int, level + 1); to.add(",\n").addSpaces(level);
|
|
||||||
to.add(" bytes: "); mtpTextSerializeType(to, from, end, mtpc_int, level + 1); to.add(",\n").addSpaces(level);
|
|
||||||
to.add(" body: "); mtpTextSerializeType(to, from, end, 0, level + 1); to.add(",\n").addSpaces(level);
|
|
||||||
to.add("}");
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case mtpc_gzip_packed: {
|
case mtpc_gzip_packed: {
|
||||||
MTPstring packed(from, end); // read packed string as serialized mtp string type
|
MTPstring packed(from, end); // read packed string as serialized mtp string type
|
||||||
uint32 packedLen = packed.c_string().v.size(), unpackedChunk = packedLen;
|
uint32 packedLen = packed.c_string().v.size(), unpackedChunk = packedLen;
|
||||||
|
|
|
@ -340,8 +340,6 @@ enum {
|
||||||
mtpc_invokeWithLayer17 = 0x50858a19,
|
mtpc_invokeWithLayer17 = 0x50858a19,
|
||||||
mtpc_invokeWithLayer18 = 0x1c900537,
|
mtpc_invokeWithLayer18 = 0x1c900537,
|
||||||
|
|
||||||
mtpc_invokeWithLayer = 0xda9b0d0d, // after 18 layer
|
|
||||||
|
|
||||||
// manually parsed
|
// manually parsed
|
||||||
mtpc_rpc_result = 0xf35c6d01,
|
mtpc_rpc_result = 0xf35c6d01,
|
||||||
mtpc_msg_container = 0x73f1f8dc,
|
mtpc_msg_container = 0x73f1f8dc,
|
||||||
|
@ -370,7 +368,7 @@ static const mtpTypeId mtpLayers[] = {
|
||||||
mtpc_invokeWithLayer17,
|
mtpc_invokeWithLayer17,
|
||||||
mtpc_invokeWithLayer18,
|
mtpc_invokeWithLayer18,
|
||||||
}, mtpLayerMaxSingle = sizeof(mtpLayers) / sizeof(mtpLayers[0]);
|
}, mtpLayerMaxSingle = sizeof(mtpLayers) / sizeof(mtpLayers[0]);
|
||||||
static const mtpPrime mtpCurrentLayer = 22;
|
static const mtpPrime mtpCurrentLayer = 25;
|
||||||
|
|
||||||
template <typename bareT>
|
template <typename bareT>
|
||||||
class MTPBoxed : public 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;
|
fileLocation#53d69076 dc_id:int volume_id:long local_id:int secret:long = FileLocation;
|
||||||
|
|
||||||
userEmpty#200250ba id:int = User;
|
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;
|
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;
|
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;
|
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;
|
chatPhoto#6153276a photo_small:FileLocation photo_big:FileLocation = ChatPhoto;
|
||||||
|
|
||||||
messageEmpty#83e5de54 id:int = Message;
|
messageEmpty#83e5de54 id:int = Message;
|
||||||
message#567699b3 flags:int id: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;
|
||||||
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;
|
|
||||||
messageService#1d86f70e flags:int id:int from_id:int to_id:Peer date:int action:MessageAction = Message;
|
messageService#1d86f70e flags:int id:int from_id:int to_id:Peer date:int action:MessageAction = Message;
|
||||||
|
|
||||||
messageMediaEmpty#3ded6320 = MessageMedia;
|
messageMediaEmpty#3ded6320 = MessageMedia;
|
||||||
|
@ -226,7 +225,7 @@ messageMediaPhoto#c8c45a2a photo:Photo = MessageMedia;
|
||||||
messageMediaVideo#a2d24290 video:Video = MessageMedia;
|
messageMediaVideo#a2d24290 video:Video = MessageMedia;
|
||||||
messageMediaGeo#56e0d474 geo:GeoPoint = MessageMedia;
|
messageMediaGeo#56e0d474 geo:GeoPoint = MessageMedia;
|
||||||
messageMediaContact#5e7d2f39 phone_number:string first_name:string last_name:string user_id:int = 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;
|
messageActionEmpty#b6aef7b0 = MessageAction;
|
||||||
messageActionChatCreate#a6638b9a title:string users:Vector<int> = MessageAction;
|
messageActionChatCreate#a6638b9a title:string users:Vector<int> = MessageAction;
|
||||||
|
@ -236,7 +235,7 @@ messageActionChatDeletePhoto#95e3fbef = MessageAction;
|
||||||
messageActionChatAddUser#5e3cfc4b user_id:int = MessageAction;
|
messageActionChatAddUser#5e3cfc4b user_id:int = MessageAction;
|
||||||
messageActionChatDeleteUser#b2ae9b0c 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;
|
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;
|
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;
|
geoPointEmpty#1117dd5f = GeoPoint;
|
||||||
geoPoint#2049d70c long:double lat:double = 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;
|
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;
|
chatLocated#3631cf4c chat_id:int distance:int = ChatLocated;
|
||||||
|
|
||||||
contacts.foreignLinkUnknown#133421f8 = contacts.ForeignLink;
|
contacts.link#3ace484c my_link:ContactLink foreign_link:ContactLink user:User = contacts.Link;
|
||||||
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.contactsNotModified#b74ba9d2 = contacts.Contacts;
|
contacts.contactsNotModified#b74ba9d2 = contacts.Contacts;
|
||||||
contacts.contacts#6f8b8cb2 contacts:Vector<Contact> users:Vector<User> = 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.messagesSlice#b446ae3 count:int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
|
||||||
|
|
||||||
messages.messageEmpty#3f4e0648 = messages.Message;
|
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#64ff9fd5 chats:Vector<Chat> = messages.Chats;
|
||||||
|
|
||||||
messages.chats#8150cbd8 chats:Vector<Chat> users:Vector<User> = messages.Chats;
|
|
||||||
|
|
||||||
messages.chatFull#e5d7d19c full_chat:ChatFull chats:Vector<Chat> users:Vector<User> = messages.ChatFull;
|
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;
|
inputMessagesFilterEmpty#57e2f66c = MessagesFilter;
|
||||||
inputMessagesFilterPhotos#9609a51c = MessagesFilter;
|
inputMessagesFilterPhotos#9609a51c = MessagesFilter;
|
||||||
inputMessagesFilterVideo#9fc00e65 = MessagesFilter;
|
inputMessagesFilterVideo#9fc00e65 = MessagesFilter;
|
||||||
inputMessagesFilterPhotoVideo#56e9f0e4 = MessagesFilter;
|
inputMessagesFilterPhotoVideo#56e9f0e4 = MessagesFilter;
|
||||||
|
inputMessagesFilterPhotoVideoDocuments#d95e73bb = MessagesFilter;
|
||||||
inputMessagesFilterDocument#9eddf188 = MessagesFilter;
|
inputMessagesFilterDocument#9eddf188 = MessagesFilter;
|
||||||
inputMessagesFilterAudio#cfc87522 = 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;
|
updateMessageID#4e90bfd6 id:int random_id:long = Update;
|
||||||
updateReadMessages#c6649e31 messages:Vector<int> pts:int = Update;
|
updateReadMessages#2e5ab668 messages:Vector<int> pts:int pts_count:int = Update;
|
||||||
updateDeleteMessages#a92bfe26 messages:Vector<int> pts:int = Update;
|
updateDeleteMessages#a20db0e5 messages:Vector<int> pts:int pts_count:int = Update;
|
||||||
updateRestoreMessages#d15de04d messages:Vector<int> pts:int = Update;
|
|
||||||
updateUserTyping#5c486927 user_id:int action:SendMessageAction = Update;
|
updateUserTyping#5c486927 user_id:int action:SendMessageAction = Update;
|
||||||
updateChatUserTyping#9a65ea1f chat_id:int user_id:int action:SendMessageAction = Update;
|
updateChatUserTyping#9a65ea1f chat_id:int user_id:int action:SendMessageAction = Update;
|
||||||
updateChatParticipants#7761198 participants:ChatParticipants = 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;
|
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;
|
updateUserPhoto#95313b0c user_id:int date:int photo:UserProfilePhoto previous:Bool = Update;
|
||||||
updateContactRegistered#2575bbb9 user_id:int date:int = Update;
|
updateContactRegistered#2575bbb9 user_id:int date:int = Update;
|
||||||
updateContactLink#51a48a9a user_id:int my_link:contacts.MyLink foreign_link:contacts.ForeignLink = Update;
|
updateContactLink#9d2e67c5 user_id:int my_link:ContactLink foreign_link:ContactLink = Update;
|
||||||
updateActivation#6f690963 user_id:int = Update;
|
|
||||||
updateNewAuthorization#8f06529a auth_key_id:long date:int device:string location:string = 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;
|
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;
|
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;
|
updatesTooLong#e317af7e = Updates;
|
||||||
updateShortMessage#d3f45784 id:int from_id:int message:string pts:int date:int seq:int = Updates;
|
updateShortMessage#ed5c2127 flags:# id:int user_id:int message:string pts:int pts_count:int date:int fwd_from_id:flags.2?int fwd_date:flags.2?int reply_to_msg_id:flags.3?int = Updates;
|
||||||
updateShortChatMessage#2b2fbd4e id:int from_id:int chat_id:int message:string pts:int date:int seq:int = Updates;
|
updateShortChatMessage#52238b3c flags:# id:int from_id:int chat_id:int message:string pts:int pts_count:int date:int fwd_from_id:flags.2?int fwd_date:flags.2?int reply_to_msg_id:flags.3?int = Updates;
|
||||||
updateShort#78d4dec1 update:Update 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;
|
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;
|
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;
|
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;
|
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;
|
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;
|
inputGeoChat#74d456fa chat_id:int access_hash:long = InputGeoChat;
|
||||||
|
|
||||||
|
@ -542,23 +529,41 @@ account.sentChangePhoneCode#a4f58c4c phone_code_hash:string send_call_timeout:in
|
||||||
|
|
||||||
updateUserPhone#12b9417b user_id:int phone:string = Update;
|
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;
|
documentAttributeImageSize#6c37c15c w:int h:int = DocumentAttribute;
|
||||||
documentAttributeAnimated#11b58939 = DocumentAttribute;
|
documentAttributeAnimated#11b58939 = DocumentAttribute;
|
||||||
documentAttributeSticker#fb0a5727 = DocumentAttribute;
|
documentAttributeSticker#994c9882 alt:string = DocumentAttribute;
|
||||||
documentAttributeVideo#5910cccb duration:int w:int h:int = DocumentAttribute;
|
documentAttributeVideo#5910cccb duration:int w:int h:int = DocumentAttribute;
|
||||||
documentAttributeAudio#51448e5 duration:int = DocumentAttribute;
|
documentAttributeAudio#51448e5 duration:int = DocumentAttribute;
|
||||||
documentAttributeFilename#15590068 file_name:string = 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;
|
stickerPack#12b299d4 emoticon:string documents:Vector<long> = StickerPack;
|
||||||
|
|
||||||
messages.allStickersNotModified#e86602c3 = messages.AllStickers;
|
messages.allStickersNotModified#e86602c3 = messages.AllStickers;
|
||||||
messages.allStickers#dcef3102 hash:string packs:Vector<StickerPack> documents:Vector<Document> = 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---
|
---functions---
|
||||||
|
|
||||||
invokeAfterMsg#cb9f372d msg_id:long query:!X = X;
|
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
|
||||||
|
|
||||||
invokeAfterMsgs#3dc4b4f0 msg_ids:Vector<long> query:!X = X;
|
invokeAfterMsgs#3dc4b4f0 {X:Type} msg_ids:Vector<long> query:!X = X;
|
||||||
|
|
||||||
auth.checkPhone#6fe51dfb phone_number:string = auth.CheckedPhone;
|
auth.checkPhone#6fe51dfb phone_number:string = auth.CheckedPhone;
|
||||||
auth.sendCode#768d5f4d phone_number:string sms_type:int api_id:int api_hash:string lang_code:string = auth.SentCode;
|
auth.sendCode#768d5f4d phone_number:string sms_type:int api_id:int api_hash:string lang_code:string = auth.SentCode;
|
||||||
|
@ -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.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.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.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.deleteHistory#f4f8fb61 peer:InputPeer offset:int = messages.AffectedHistory;
|
||||||
messages.deleteMessages#14f2dd0a id:Vector<int> = Vector<int>;
|
messages.deleteMessages#a5f18925 id:Vector<int> = messages.AffectedMessages;
|
||||||
messages.restoreMessages#395f9d7e id:Vector<int> = Vector<int>;
|
|
||||||
messages.receivedMessages#28abcb68 max_id:int = Vector<int>;
|
messages.receivedMessages#28abcb68 max_id:int = Vector<int>;
|
||||||
messages.setTyping#a3825e50 peer:InputPeer action:SendMessageAction = Bool;
|
messages.setTyping#a3825e50 peer:InputPeer action:SendMessageAction = Bool;
|
||||||
messages.sendMessage#4cde0aab peer:InputPeer message:string random_id:long = messages.SentMessage;
|
messages.sendMessage#1ca852a1 peer:InputPeer reply_to_msg_id:int message:string random_id:long = messages.SentMessage;
|
||||||
messages.sendMedia#a3c85d76 peer:InputPeer media:InputMedia random_id:long = messages.StatedMessage;
|
messages.sendMedia#fcee7fc0 peer:InputPeer reply_to_msg_id:int media:InputMedia random_id:long = messages.StatedMessage;
|
||||||
messages.forwardMessages#514cd10f peer:InputPeer id:Vector<int> = messages.StatedMessages;
|
messages.forwardMessages#ded42045 peer:InputPeer id:Vector<int> random_id:Vector<long> = messages.StatedMessages;
|
||||||
messages.getChats#3c6aa187 id:Vector<int> = messages.Chats;
|
messages.getChats#3c6aa187 id:Vector<int> = messages.Chats;
|
||||||
messages.getFullChat#3b831c66 chat_id:int = messages.ChatFull;
|
messages.getFullChat#3b831c66 chat_id:int = messages.ChatFull;
|
||||||
messages.editChatTitle#b4bc68b5 chat_id:int title:string = messages.StatedMessage;
|
messages.editChatTitle#b4bc68b5 chat_id:int title:string = messages.StatedMessage;
|
||||||
|
@ -664,13 +668,13 @@ messages.receivedQueue#55a5bb66 max_qts:int = Vector<long>;
|
||||||
|
|
||||||
upload.saveBigFilePart#de7b673d file_id:long file_part:int file_total_parts:int bytes:bytes = Bool;
|
upload.saveBigFilePart#de7b673d file_id:long file_part:int file_total_parts:int bytes:bytes = Bool;
|
||||||
|
|
||||||
initConnection#69796de9 api_id:int device_model:string system_version:string app_version:string lang_code:string query:!X = X;
|
initConnection#69796de9 {X:Type} api_id:int device_model:string system_version:string app_version:string lang_code:string query:!X = X;
|
||||||
|
|
||||||
help.getSupport#9cdf08cd = help.Support;
|
help.getSupport#9cdf08cd = help.Support;
|
||||||
|
|
||||||
auth.sendSms#da9f3e8 phone_number:string phone_code_hash:string = Bool;
|
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.checkUsername#2714d86c username:string = Bool;
|
||||||
account.updateUsername#3e0bdd7c username:string = User;
|
account.updateUsername#3e0bdd7c username:string = User;
|
||||||
|
@ -683,9 +687,18 @@ account.deleteAccount#418d4e0b reason:string = Bool;
|
||||||
account.getAccountTTL#8fc711d = AccountDaysTTL;
|
account.getAccountTTL#8fc711d = AccountDaysTTL;
|
||||||
account.setAccountTTL#2442485e ttl:AccountDaysTTL = Bool;
|
account.setAccountTTL#2442485e ttl:AccountDaysTTL = Bool;
|
||||||
|
|
||||||
|
invokeWithLayer#da9b0d0d {X:Type} layer:int query:!X = X;
|
||||||
|
|
||||||
contacts.resolveUsername#bf0131c username:string = User;
|
contacts.resolveUsername#bf0131c username:string = User;
|
||||||
|
|
||||||
account.sendChangePhoneCode#a407a8f4 phone_number:string = account.SentChangePhoneCode;
|
account.sendChangePhoneCode#a407a8f4 phone_number:string = account.SentChangePhoneCode;
|
||||||
account.changePhone#70c32edb phone_number:string phone_code_hash:string phone_code:string = User;
|
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;
|
|
@ -1876,7 +1876,7 @@ void OverviewWidget::onDeleteSelectedSure() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ids.isEmpty()) {
|
if (!ids.isEmpty()) {
|
||||||
MTP::send(MTPmessages_DeleteMessages(MTP_vector<MTPint>(ids)));
|
App::main()->deleteMessages(ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
onClearSelected();
|
onClearSelected();
|
||||||
|
@ -1896,7 +1896,7 @@ void OverviewWidget::onDeleteContextSure() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item->id > 0) {
|
if (item->id > 0) {
|
||||||
MTP::send(MTPmessages_DeleteMessages(MTP_vector<MTPint>(1, MTP_int(item->id))));
|
App::main()->deleteMessages(QVector<MTPint>(1, MTP_int(item->id)));
|
||||||
}
|
}
|
||||||
item->destroy();
|
item->destroy();
|
||||||
if (App::main() && App::main()->peer() == peer()) {
|
if (App::main() && App::main()->peer() == peer()) {
|
||||||
|
|
|
@ -381,11 +381,8 @@ void ProfileInner::reorderParticipants() {
|
||||||
|
|
||||||
bool ProfileInner::event(QEvent *e) {
|
bool ProfileInner::event(QEvent *e) {
|
||||||
if (e->type() == QEvent::MouseMove) {
|
if (e->type() == QEvent::MouseMove) {
|
||||||
QMouseEvent *ev = dynamic_cast<QMouseEvent*>(e);
|
_lastPos = static_cast<QMouseEvent*>(e)->globalPos();
|
||||||
if (ev) {
|
updateSelected();
|
||||||
_lastPos = ev->globalPos();
|
|
||||||
updateSelected();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return QWidget::event(e);
|
return QWidget::event(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ void MacPrivate::darkModeChanged() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacPrivate::notifyClicked(unsigned long long peer) {
|
void MacPrivate::notifyClicked(unsigned long long peer, int msgid) {
|
||||||
History *history = App::history(PeerId(peer));
|
History *history = App::history(PeerId(peer));
|
||||||
|
|
||||||
App::wnd()->showFromTray();
|
App::wnd()->showFromTray();
|
||||||
|
@ -69,15 +69,22 @@ void MacPrivate::notifyClicked(unsigned long long peer) {
|
||||||
App::wnd()->notifyClear();
|
App::wnd()->notifyClear();
|
||||||
} else {
|
} else {
|
||||||
App::wnd()->hideSettings();
|
App::wnd()->hideSettings();
|
||||||
App::main()->showPeer(history->peer->id, false, true);
|
bool tomsg = history->peer->chat && (msgid > 0);
|
||||||
|
if (tomsg) {
|
||||||
|
HistoryItem *item = App::histItemById(msgid);
|
||||||
|
if (!item || !item->notifyByFrom()) {
|
||||||
|
tomsg = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
App::main()->showPeer(history->peer->id, tomsg ? msgid : 0, false, true);
|
||||||
App::wnd()->notifyClear(history);
|
App::wnd()->notifyClear(history);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacPrivate::notifyReplied(unsigned long long peer, const char *str) {
|
void MacPrivate::notifyReplied(unsigned long long peer, int msgid, const char *str) {
|
||||||
History *history = App::history(PeerId(peer));
|
History *history = App::history(PeerId(peer));
|
||||||
|
|
||||||
App::main()->sendMessage(history, QString::fromUtf8(str));
|
App::main()->sendMessage(history, QString::fromUtf8(str), (msgid > 0 && history->peer->chat) ? msgid : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
PsMainWindow::PsMainWindow(QWidget *parent) : QMainWindow(parent),
|
PsMainWindow::PsMainWindow(QWidget *parent) : QMainWindow(parent),
|
||||||
|
@ -488,7 +495,7 @@ void PsMainWindow::psPlatformNotify(HistoryItem *item) {
|
||||||
QPixmap pix = (!App::passcoded() && cNotifyView() <= dbinvShowName) ? item->history()->peer->photo->pix(st::notifyMacPhotoSize) : QPixmap();
|
QPixmap pix = (!App::passcoded() && cNotifyView() <= dbinvShowName) ? item->history()->peer->photo->pix(st::notifyMacPhotoSize) : QPixmap();
|
||||||
QString msg = (!App::passcoded() && cNotifyView() <= dbinvShowPreview) ? item->notificationText() : lang(lng_notification_preview);
|
QString msg = (!App::passcoded() && cNotifyView() <= dbinvShowPreview) ? item->notificationText() : lang(lng_notification_preview);
|
||||||
|
|
||||||
_private.showNotify(item->history()->peer->id, pix, title, subtitle, msg, !App::passcoded() && (cNotifyView() <= dbinvShowPreview));
|
_private.showNotify(item->history()->peer->id, item->id, pix, title, subtitle, msg, !App::passcoded() && (cNotifyView() <= dbinvShowPreview));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PsMainWindow::eventFilter(QObject *obj, QEvent *evt) {
|
bool PsMainWindow::eventFilter(QObject *obj, QEvent *evt) {
|
||||||
|
|
|
@ -34,8 +34,8 @@ public:
|
||||||
|
|
||||||
void activeSpaceChanged();
|
void activeSpaceChanged();
|
||||||
void darkModeChanged();
|
void darkModeChanged();
|
||||||
void notifyClicked(unsigned long long peer);
|
void notifyClicked(unsigned long long peer, int msgid);
|
||||||
void notifyReplied(unsigned long long peer, const char *str);
|
void notifyReplied(unsigned long long peer, int msgid, const char *str);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ public:
|
||||||
|
|
||||||
void updateDelegate();
|
void updateDelegate();
|
||||||
|
|
||||||
void showNotify(uint64 peer, const QPixmap &pix, const QString &title, const QString &subtitle, const QString &msg, bool withReply);
|
void showNotify(uint64 peer, int32 msgId, const QPixmap &pix, const QString &title, const QString &subtitle, const QString &msg, bool withReply);
|
||||||
void clearNotifies(uint64 peer = 0);
|
void clearNotifies(uint64 peer = 0);
|
||||||
|
|
||||||
void enableShadow(WId winId);
|
void enableShadow(WId winId);
|
||||||
|
@ -38,9 +38,9 @@ public:
|
||||||
}
|
}
|
||||||
virtual void darkModeChanged() {
|
virtual void darkModeChanged() {
|
||||||
}
|
}
|
||||||
virtual void notifyClicked(unsigned long long peer) {
|
virtual void notifyClicked(unsigned long long peer, int msgid) {
|
||||||
}
|
}
|
||||||
virtual void notifyReplied(unsigned long long peer, const char *str) {
|
virtual void notifyReplied(unsigned long long peer, int msgid, const char *str) {
|
||||||
}
|
}
|
||||||
|
|
||||||
~PsMacWindowPrivate();
|
~PsMacWindowPrivate();
|
||||||
|
|
|
@ -145,17 +145,21 @@ public:
|
||||||
observerHelper([[ObserverHelper alloc] init:wnd]),
|
observerHelper([[ObserverHelper alloc] init:wnd]),
|
||||||
notifyHandler([[NotifyHandler alloc] init:wnd]) {
|
notifyHandler([[NotifyHandler alloc] init:wnd]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void onNotifyClick(NSUserNotification *notification) {
|
void onNotifyClick(NSUserNotification *notification) {
|
||||||
NSNumber *peerObj = [[notification userInfo] objectForKey:@"peer"];
|
NSDictionary *dict = [notification userInfo];
|
||||||
|
NSNumber *peerObj = [dict objectForKey:@"peer"], *msgObj = [dict objectForKey:@"msgid"];
|
||||||
unsigned long long peerLong = peerObj ? [peerObj unsignedLongLongValue] : 0;
|
unsigned long long peerLong = peerObj ? [peerObj unsignedLongLongValue] : 0;
|
||||||
wnd->notifyClicked(peerLong);
|
int msgId = msgObj ? [msgObj intValue] : 0;
|
||||||
|
wnd->notifyClicked(peerLong, msgId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void onNotifyReply(NSUserNotification *notification) {
|
void onNotifyReply(NSUserNotification *notification) {
|
||||||
NSNumber *peerObj = [[notification userInfo] objectForKey:@"peer"];
|
NSDictionary *dict = [notification userInfo];
|
||||||
|
NSNumber *peerObj = [dict objectForKey:@"peer"], *msgObj = [dict objectForKey:@"msgid"];
|
||||||
unsigned long long peerLong = peerObj ? [peerObj unsignedLongLongValue] : 0;
|
unsigned long long peerLong = peerObj ? [peerObj unsignedLongLongValue] : 0;
|
||||||
wnd->notifyReplied(peerLong, [[[notification response] string] UTF8String]);
|
int msgId = msgObj ? [msgObj intValue] : 0;
|
||||||
|
wnd->notifyReplied(peerLong, msgId, [[[notification response] string] UTF8String]);
|
||||||
}
|
}
|
||||||
|
|
||||||
~PsMacWindowData() {
|
~PsMacWindowData() {
|
||||||
|
@ -272,12 +276,12 @@ void objc_activateWnd(WId winId) {
|
||||||
|
|
||||||
NSImage *qt_mac_create_nsimage(const QPixmap &pm);
|
NSImage *qt_mac_create_nsimage(const QPixmap &pm);
|
||||||
|
|
||||||
void PsMacWindowPrivate::showNotify(uint64 peer, const QPixmap &pix, const QString &title, const QString &subtitle, const QString &msg, bool withReply) {
|
void PsMacWindowPrivate::showNotify(uint64 peer, int32 msgId, const QPixmap &pix, const QString &title, const QString &subtitle, const QString &msg, bool withReply) {
|
||||||
NSUserNotification *notification = [[NSUserNotification alloc] init];
|
NSUserNotification *notification = [[NSUserNotification alloc] init];
|
||||||
NSImage *img = qt_mac_create_nsimage(pix);
|
NSImage *img = qt_mac_create_nsimage(pix);
|
||||||
|
|
||||||
DEBUG_LOG(("Sending notification with userinfo: peer %1 and instance %2").arg(peer).arg(cInstance()));
|
DEBUG_LOG(("Sending notification with userinfo: peer %1, msgId %2 and instance %3").arg(peer).arg(msgId).arg(cInstance()));
|
||||||
[notification setUserInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithUnsignedLongLong:peer],@"peer",[NSNumber numberWithUnsignedLongLong:cInstance()],@"inst",nil]];
|
[notification setUserInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithUnsignedLongLong:peer],@"peer",[NSNumber numberWithInt:msgId],@"msgid",[NSNumber numberWithUnsignedLongLong:cInstance()],@"inst",nil]];
|
||||||
|
|
||||||
[notification setTitle:QNSString(title).s()];
|
[notification setTitle:QNSString(title).s()];
|
||||||
[notification setSubtitle:QNSString(subtitle).s()];
|
[notification setSubtitle:QNSString(subtitle).s()];
|
||||||
|
@ -305,7 +309,8 @@ void PsMacWindowPrivate::clearNotifies(unsigned long long peer) {
|
||||||
if (peer) {
|
if (peer) {
|
||||||
NSArray *notifies = [center deliveredNotifications];
|
NSArray *notifies = [center deliveredNotifications];
|
||||||
for (id notify in notifies) {
|
for (id notify in notifies) {
|
||||||
if ([[[notify userInfo] objectForKey:@"peer"] unsignedLongLongValue] == peer) {
|
NSDictionary *dict = [notify userInfo];
|
||||||
|
if ([[dict objectForKey:@"peer"] unsignedLongLongValue] == peer && [[dict objectForKey:@"inst"] unsignedLongLongValue] == cInstance()) {
|
||||||
[center removeDeliveredNotification:notify];
|
[center removeDeliveredNotification:notify];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -262,6 +262,18 @@ void SingleTimer::start(int msec) {
|
||||||
QTimer::start(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() {
|
uint64 msgid() {
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
|
|
|
@ -114,6 +114,7 @@ public:
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
void start(int msec);
|
void start(int msec);
|
||||||
|
void startIfNotActive(int msec);
|
||||||
void adjust() {
|
void adjust() {
|
||||||
uint64 n = getms(true);
|
uint64 n = getms(true);
|
||||||
if (isActive()) {
|
if (isActive()) {
|
||||||
|
|
|
@ -229,6 +229,7 @@ void NotifyWindow::updatePeerPhoto() {
|
||||||
|
|
||||||
void NotifyWindow::itemRemoved(HistoryItem *del) {
|
void NotifyWindow::itemRemoved(HistoryItem *del) {
|
||||||
if (item == del) {
|
if (item == del) {
|
||||||
|
item = 0;
|
||||||
unlinkHistoryAndNotify();
|
unlinkHistoryAndNotify();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -273,7 +274,7 @@ void NotifyWindow::mousePressEvent(QMouseEvent *e) {
|
||||||
App::wnd()->notifyClear();
|
App::wnd()->notifyClear();
|
||||||
} else {
|
} else {
|
||||||
App::wnd()->hideSettings();
|
App::wnd()->hideSettings();
|
||||||
App::main()->showPeer(peer, 0, false, true);
|
App::main()->showPeer(peer, (history->peer->chat && item && item->notifyByFrom() && item->id > 0) ? item->id : 0, false, true);
|
||||||
}
|
}
|
||||||
e->ignore();
|
e->ignore();
|
||||||
}
|
}
|
||||||
|
@ -484,6 +485,8 @@ void Window::clearPasscode() {
|
||||||
_passcode = 0;
|
_passcode = 0;
|
||||||
if (intro) {
|
if (intro) {
|
||||||
intro->animShow(bg, true);
|
intro->animShow(bg, true);
|
||||||
|
} else if (settings) {
|
||||||
|
settings->animShow(bg, true);
|
||||||
} else {
|
} else {
|
||||||
main->animShow(bg, true);
|
main->animShow(bg, true);
|
||||||
}
|
}
|
||||||
|
@ -593,6 +596,8 @@ void Window::sendServiceHistoryRequest() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::setupMain(bool anim, const MTPUser *self) {
|
void Window::setupMain(bool anim, const MTPUser *self) {
|
||||||
|
Local::readRecentStickers();
|
||||||
|
|
||||||
QPixmap bg = anim ? myGrab(this, QRect(0, st::titleHeight, width(), height() - st::titleHeight)) : QPixmap();
|
QPixmap bg = anim ? myGrab(this, QRect(0, st::titleHeight, width(), height() - st::titleHeight)) : QPixmap();
|
||||||
clearWidgets();
|
clearWidgets();
|
||||||
main = new MainWidget(this);
|
main = new MainWidget(this);
|
||||||
|
@ -1202,16 +1207,33 @@ void Window::quit() {
|
||||||
notifyClearFast();
|
notifyClearFast();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::notifySchedule(History *history, MsgId msgId) {
|
void Window::notifySchedule(History *history, HistoryItem *item) {
|
||||||
if (App::quiting() || !history->currentNotification() || !main) return;
|
if (App::quiting() || !history->currentNotification() || !main) return;
|
||||||
|
|
||||||
|
UserData *notifyByFrom = (history->peer->chat && item->notifyByFrom()) ? item->from() : 0;
|
||||||
|
|
||||||
bool haveSetting = (history->peer->notify != UnknownNotifySettings);
|
bool haveSetting = (history->peer->notify != UnknownNotifySettings);
|
||||||
if (haveSetting) {
|
if (haveSetting) {
|
||||||
if (history->peer->notify != EmptyNotifySettings && history->peer->notify->mute > unixtime()) {
|
if (history->peer->notify != EmptyNotifySettings && history->peer->notify->mute > unixtime()) {
|
||||||
history->clearNotifications();
|
if (notifyByFrom) {
|
||||||
return;
|
haveSetting = (item->from()->notify != UnknownNotifySettings);
|
||||||
|
if (haveSetting) {
|
||||||
|
if (notifyByFrom->notify != EmptyNotifySettings && notifyByFrom->notify->mute > unixtime()) {
|
||||||
|
history->popNotification(item);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
App::wnd()->getNotifySetting(MTP_inputNotifyPeer(notifyByFrom->input));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
history->popNotification(item);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (notifyByFrom && notifyByFrom->notify == UnknownNotifySettings) {
|
||||||
|
App::wnd()->getNotifySetting(MTP_inputNotifyPeer(notifyByFrom->input), 10);
|
||||||
|
}
|
||||||
App::wnd()->getNotifySetting(MTP_inputNotifyPeer(history->peer->input));
|
App::wnd()->getNotifySetting(MTP_inputNotifyPeer(history->peer->input));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1226,19 +1248,19 @@ void Window::notifySchedule(History *history, MsgId msgId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64 when = getms(true) + delay;
|
uint64 when = getms(true) + delay;
|
||||||
notifyWhenAlerts[history].insert(when, NullType());
|
notifyWhenAlerts[history].insert(when, notifyByFrom);
|
||||||
if (cDesktopNotify() && !psSkipDesktopNotify()) {
|
if (cDesktopNotify() && !psSkipDesktopNotify()) {
|
||||||
NotifyWhenMaps::iterator i = notifyWhenMaps.find(history);
|
NotifyWhenMaps::iterator i = notifyWhenMaps.find(history);
|
||||||
if (i == notifyWhenMaps.end()) {
|
if (i == notifyWhenMaps.end()) {
|
||||||
i = notifyWhenMaps.insert(history, NotifyWhenMap());
|
i = notifyWhenMaps.insert(history, NotifyWhenMap());
|
||||||
}
|
}
|
||||||
if (i.value().constFind(msgId) == i.value().cend()) {
|
if (i.value().constFind(item->id) == i.value().cend()) {
|
||||||
i.value().insert(msgId, when);
|
i.value().insert(item->id, when);
|
||||||
}
|
}
|
||||||
NotifyWaiters *addTo = haveSetting ? ¬ifyWaiters : ¬ifySettingWaiters;
|
NotifyWaiters *addTo = haveSetting ? ¬ifyWaiters : ¬ifySettingWaiters;
|
||||||
NotifyWaiters::const_iterator it = addTo->constFind(history);
|
NotifyWaiters::const_iterator it = addTo->constFind(history);
|
||||||
if (it == addTo->cend() || it->when > when) {
|
if (it == addTo->cend() || it->when > when) {
|
||||||
addTo->insert(history, NotifyWaiter(msgId, when));
|
addTo->insert(history, NotifyWaiter(item->id, when, notifyByFrom));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (haveSetting) {
|
if (haveSetting) {
|
||||||
|
@ -1298,6 +1320,13 @@ void Window::notifySettingGot() {
|
||||||
} else {
|
} else {
|
||||||
if (history->peer->notify == EmptyNotifySettings || history->peer->notify->mute <= t) {
|
if (history->peer->notify == EmptyNotifySettings || history->peer->notify->mute <= t) {
|
||||||
notifyWaiters.insert(i.key(), i.value());
|
notifyWaiters.insert(i.key(), i.value());
|
||||||
|
} else if (UserData *from = i.value().notifyByFrom) {
|
||||||
|
if (from->notify == UnknownNotifySettings) {
|
||||||
|
++i;
|
||||||
|
continue;
|
||||||
|
} else if (from->notify == EmptyNotifySettings || from->notify->mute <= t) {
|
||||||
|
notifyWaiters.insert(i.key(), i.value());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
i = notifySettingWaiters.erase(i);
|
i = notifySettingWaiters.erase(i);
|
||||||
}
|
}
|
||||||
|
@ -1321,11 +1350,14 @@ void Window::notifyShowNext(NotifyWindow *remove) {
|
||||||
|
|
||||||
uint64 ms = getms(true), nextAlert = 0;
|
uint64 ms = getms(true), nextAlert = 0;
|
||||||
bool alert = false;
|
bool alert = false;
|
||||||
|
int32 now = unixtime();
|
||||||
for (NotifyWhenAlerts::iterator i = notifyWhenAlerts.begin(); i != notifyWhenAlerts.end();) {
|
for (NotifyWhenAlerts::iterator i = notifyWhenAlerts.begin(); i != notifyWhenAlerts.end();) {
|
||||||
while (!i.value().isEmpty() && i.value().begin().key() <= ms) {
|
while (!i.value().isEmpty() && i.value().begin().key() <= ms) {
|
||||||
|
NotifySettingsPtr n = i.key()->peer->notify, f = i.value().begin().value() ? i.value().begin().value()->notify : UnknownNotifySettings;
|
||||||
i.value().erase(i.value().begin());
|
i.value().erase(i.value().begin());
|
||||||
NotifySettingsPtr n = i.key()->peer->notify;
|
if (n == EmptyNotifySettings || (n != UnknownNotifySettings && n->mute <= now)) {
|
||||||
if (n == EmptyNotifySettings || (n != UnknownNotifySettings && n->mute <= unixtime())) {
|
alert = true;
|
||||||
|
} else if (f == EmptyNotifySettings || (f != UnknownNotifySettings && f->mute <= now)) { // notify by from()
|
||||||
alert = true;
|
alert = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -211,7 +211,7 @@ public:
|
||||||
void quit();
|
void quit();
|
||||||
|
|
||||||
void notifySettingGot();
|
void notifySettingGot();
|
||||||
void notifySchedule(History *history, MsgId msgId);
|
void notifySchedule(History *history, HistoryItem *item);
|
||||||
void notifyClear(History *history = 0);
|
void notifyClear(History *history = 0);
|
||||||
void notifyClearFast();
|
void notifyClearFast();
|
||||||
void notifyShowNext(NotifyWindow *remove = 0);
|
void notifyShowNext(NotifyWindow *remove = 0);
|
||||||
|
@ -315,17 +315,18 @@ private:
|
||||||
typedef QMap<History*, NotifyWhenMap> NotifyWhenMaps;
|
typedef QMap<History*, NotifyWhenMap> NotifyWhenMaps;
|
||||||
NotifyWhenMaps notifyWhenMaps;
|
NotifyWhenMaps notifyWhenMaps;
|
||||||
struct NotifyWaiter {
|
struct NotifyWaiter {
|
||||||
NotifyWaiter(MsgId msg, uint64 when) : msg(msg), when(when) {
|
NotifyWaiter(MsgId msg, uint64 when, UserData *notifyByFrom) : msg(msg), when(when), notifyByFrom(notifyByFrom) {
|
||||||
}
|
}
|
||||||
MsgId msg;
|
MsgId msg;
|
||||||
uint64 when;
|
uint64 when;
|
||||||
|
UserData *notifyByFrom;
|
||||||
};
|
};
|
||||||
typedef QMap<History*, NotifyWaiter> NotifyWaiters;
|
typedef QMap<History*, NotifyWaiter> NotifyWaiters;
|
||||||
NotifyWaiters notifyWaiters;
|
NotifyWaiters notifyWaiters;
|
||||||
NotifyWaiters notifySettingWaiters;
|
NotifyWaiters notifySettingWaiters;
|
||||||
SingleTimer notifyWaitTimer;
|
SingleTimer notifyWaitTimer;
|
||||||
|
|
||||||
typedef QMap<uint64, NullType> NotifyWhenAlert;
|
typedef QMap<uint64, UserData*> NotifyWhenAlert;
|
||||||
typedef QMap<History*, NotifyWhenAlert> NotifyWhenAlerts;
|
typedef QMap<History*, NotifyWhenAlert> NotifyWhenAlerts;
|
||||||
NotifyWhenAlerts notifyWhenAlerts;
|
NotifyWhenAlerts notifyWhenAlerts;
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>0.7.20</string>
|
<string>0.7.21</string>
|
||||||
<key>CFBundleSignature</key>
|
<key>CFBundleSignature</key>
|
||||||
<string>????</string>
|
<string>????</string>
|
||||||
<key>CFBundleURLTypes</key>
|
<key>CFBundleURLTypes</key>
|
||||||
|
|
|
@ -79,6 +79,7 @@ unix {
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
./SourceFiles/main.cpp \
|
./SourceFiles/main.cpp \
|
||||||
./SourceFiles/stdafx.cpp \
|
./SourceFiles/stdafx.cpp \
|
||||||
|
./SourceFiles/apiwrap.cpp \
|
||||||
./SourceFiles/app.cpp \
|
./SourceFiles/app.cpp \
|
||||||
./SourceFiles/application.cpp \
|
./SourceFiles/application.cpp \
|
||||||
./SourceFiles/audio.cpp \
|
./SourceFiles/audio.cpp \
|
||||||
|
@ -158,6 +159,7 @@ SOURCES += \
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
./SourceFiles/stdafx.h \
|
./SourceFiles/stdafx.h \
|
||||||
|
./SourceFiles/apiwrap.h \
|
||||||
./SourceFiles/app.h \
|
./SourceFiles/app.h \
|
||||||
./SourceFiles/application.h \
|
./SourceFiles/application.h \
|
||||||
./SourceFiles/audio.h \
|
./SourceFiles/audio.h \
|
||||||
|
|
Binary file not shown.
|
@ -162,6 +162,10 @@
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="GeneratedFiles\Debug\moc_apiwrap.cpp">
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="GeneratedFiles\Debug\moc_application.cpp">
|
<ClCompile Include="GeneratedFiles\Debug\moc_application.cpp">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||||
|
@ -412,6 +416,10 @@
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="GeneratedFiles\Deploy\moc_apiwrap.cpp">
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="GeneratedFiles\Deploy\moc_application.cpp">
|
<ClCompile Include="GeneratedFiles\Deploy\moc_application.cpp">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||||
|
@ -671,6 +679,10 @@
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="GeneratedFiles\Release\moc_apiwrap.cpp">
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="GeneratedFiles\Release\moc_application.cpp">
|
<ClCompile Include="GeneratedFiles\Release\moc_application.cpp">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||||
|
@ -906,6 +918,7 @@
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="GeneratedFiles\style_auto.cpp" />
|
<ClCompile Include="GeneratedFiles\style_auto.cpp" />
|
||||||
|
<ClCompile Include="SourceFiles\apiwrap.cpp" />
|
||||||
<ClCompile Include="SourceFiles\app.cpp" />
|
<ClCompile Include="SourceFiles\app.cpp" />
|
||||||
<ClCompile Include="SourceFiles\application.cpp" />
|
<ClCompile Include="SourceFiles\application.cpp" />
|
||||||
<ClCompile Include="SourceFiles\audio.cpp" />
|
<ClCompile Include="SourceFiles\audio.cpp" />
|
||||||
|
@ -1058,6 +1071,20 @@
|
||||||
<ClInclude Include="GeneratedFiles\style_auto.h" />
|
<ClInclude Include="GeneratedFiles\style_auto.h" />
|
||||||
<ClInclude Include="GeneratedFiles\style_classes.h" />
|
<ClInclude Include="GeneratedFiles\style_classes.h" />
|
||||||
<ClInclude Include="resource.h" />
|
<ClInclude Include="resource.h" />
|
||||||
|
<CustomBuild Include="SourceFiles\apiwrap.h">
|
||||||
|
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||||
|
<Message Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">Moc%27ing apiwrap.h...</Message>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/apiwrap.h" -DAL_LIBTYPE_STATIC -DCUSTOM_API_ID -DUNICODE -D_WITH_DEBUG -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\OpenSSL-Win32\include" "-I.\..\..\Libraries\libogg-1.3.2\include" "-I.\..\..\Libraries\opus\include" "-I.\..\..\Libraries\opusfile\include" "-I.\..\..\Libraries\openal-soft\include" "-I.\SourceFiles" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I.\..\..\Libraries\QtStatic\qtbase\include\QtCore\5.4.0\QtCore" "-I.\..\..\Libraries\QtStatic\qtbase\include\QtGui\5.4.0\QtGui"</Command>
|
||||||
|
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||||
|
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Moc%27ing apiwrap.h...</Message>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/apiwrap.h" -DAL_LIBTYPE_STATIC -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\OpenSSL-Win32\include" "-I.\..\..\Libraries\libogg-1.3.2\include" "-I.\..\..\Libraries\opus\include" "-I.\..\..\Libraries\opusfile\include" "-I.\..\..\Libraries\openal-soft\include" "-I.\SourceFiles" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I.\..\..\Libraries\QtStatic\qtbase\include\QtCore\5.4.0\QtCore" "-I.\..\..\Libraries\QtStatic\qtbase\include\QtGui\5.4.0\QtGui"</Command>
|
||||||
|
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||||
|
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Moc%27ing apiwrap.h...</Message>
|
||||||
|
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
||||||
|
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/apiwrap.h" -DAL_LIBTYPE_STATIC -DUNICODE -D_WITH_DEBUG -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\OpenSSL-Win32\include" "-I.\..\..\Libraries\libogg-1.3.2\include" "-I.\..\..\Libraries\opus\include" "-I.\..\..\Libraries\opusfile\include" "-I.\..\..\Libraries\openal-soft\include" "-I.\SourceFiles" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I.\..\..\Libraries\QtStatic\qtbase\include\QtCore\5.4.0\QtCore" "-I.\..\..\Libraries\QtStatic\qtbase\include\QtGui\5.4.0\QtGui"</Command>
|
||||||
|
</CustomBuild>
|
||||||
<ClInclude Include="SourceFiles\app.h" />
|
<ClInclude Include="SourceFiles\app.h" />
|
||||||
<CustomBuild Include="SourceFiles\boxes\aboutbox.h">
|
<CustomBuild Include="SourceFiles\boxes\aboutbox.h">
|
||||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Moc%27ing aboutbox.h...</Message>
|
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Moc%27ing aboutbox.h...</Message>
|
||||||
|
|
|
@ -846,6 +846,18 @@
|
||||||
<ClCompile Include="SourceFiles\boxes\passcodebox.cpp">
|
<ClCompile Include="SourceFiles\boxes\passcodebox.cpp">
|
||||||
<Filter>boxes</Filter>
|
<Filter>boxes</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="SourceFiles\apiwrap.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="GeneratedFiles\Deploy\moc_apiwrap.cpp">
|
||||||
|
<Filter>Generated Files\Deploy</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="GeneratedFiles\Debug\moc_apiwrap.cpp">
|
||||||
|
<Filter>Generated Files\Debug</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="GeneratedFiles\Release\moc_apiwrap.cpp">
|
||||||
|
<Filter>Generated Files\Release</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="SourceFiles\stdafx.h">
|
<ClInclude Include="SourceFiles\stdafx.h">
|
||||||
|
@ -1124,6 +1136,9 @@
|
||||||
<CustomBuild Include="SourceFiles\boxes\passcodebox.h">
|
<CustomBuild Include="SourceFiles\boxes\passcodebox.h">
|
||||||
<Filter>boxes</Filter>
|
<Filter>boxes</Filter>
|
||||||
</CustomBuild>
|
</CustomBuild>
|
||||||
|
<CustomBuild Include="SourceFiles\apiwrap.h">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</CustomBuild>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Image Include="SourceFiles\art\icon256.ico" />
|
<Image Include="SourceFiles\art\icon256.ico" />
|
||||||
|
|
|
@ -49,6 +49,8 @@
|
||||||
074FCB8E19D36851004C6EB2 /* contextmenu.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 074FCB8C19D36851004C6EB2 /* contextmenu.cpp */; };
|
074FCB8E19D36851004C6EB2 /* contextmenu.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 074FCB8C19D36851004C6EB2 /* contextmenu.cpp */; };
|
||||||
074FCB9119D36E60004C6EB2 /* moc_contextmenu.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 074FCB9019D36E60004C6EB2 /* moc_contextmenu.cpp */; };
|
074FCB9119D36E60004C6EB2 /* moc_contextmenu.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 074FCB9019D36E60004C6EB2 /* moc_contextmenu.cpp */; };
|
||||||
07539B1D1A1416AF00083EFC /* moc_history.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 07539B1C1A1416AF00083EFC /* moc_history.cpp */; };
|
07539B1D1A1416AF00083EFC /* moc_history.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 07539B1C1A1416AF00083EFC /* moc_history.cpp */; };
|
||||||
|
0764D55A1ABAD6F900FBFEED /* apiwrap.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 0764D5581ABAD6F900FBFEED /* apiwrap.cpp */; };
|
||||||
|
0764D55D1ABAD71B00FBFEED /* moc_apiwrap.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 0764D55C1ABAD71B00FBFEED /* moc_apiwrap.cpp */; };
|
||||||
078A2FCA1A811C5900CCC7A0 /* moc_backgroundbox.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 078A2FC91A811C5900CCC7A0 /* moc_backgroundbox.cpp */; };
|
078A2FCA1A811C5900CCC7A0 /* moc_backgroundbox.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 078A2FC91A811C5900CCC7A0 /* moc_backgroundbox.cpp */; };
|
||||||
078A2FCD1A811CA600CCC7A0 /* backgroundbox.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 078A2FCB1A811CA600CCC7A0 /* backgroundbox.cpp */; };
|
078A2FCD1A811CA600CCC7A0 /* backgroundbox.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 078A2FCB1A811CA600CCC7A0 /* backgroundbox.cpp */; };
|
||||||
07A69332199277BA0099CB9F /* mediaview.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 07A69330199277BA0099CB9F /* mediaview.cpp */; };
|
07A69332199277BA0099CB9F /* mediaview.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 07A69330199277BA0099CB9F /* mediaview.cpp */; };
|
||||||
|
@ -278,6 +280,9 @@
|
||||||
07539B1C1A1416AF00083EFC /* moc_history.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = moc_history.cpp; path = GeneratedFiles/Debug/moc_history.cpp; sourceTree = SOURCE_ROOT; };
|
07539B1C1A1416AF00083EFC /* moc_history.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = moc_history.cpp; path = GeneratedFiles/Debug/moc_history.cpp; sourceTree = SOURCE_ROOT; };
|
||||||
075EB50EB07CF69FD62FB8DF /* /usr/local/Qt-5.4.0/mkspecs/modules/qt_lib_sql_private.pri */ = {isa = PBXFileReference; lastKnownFileType = text; path = "/usr/local/Qt-5.4.0/mkspecs/modules/qt_lib_sql_private.pri"; sourceTree = "<absolute>"; };
|
075EB50EB07CF69FD62FB8DF /* /usr/local/Qt-5.4.0/mkspecs/modules/qt_lib_sql_private.pri */ = {isa = PBXFileReference; lastKnownFileType = text; path = "/usr/local/Qt-5.4.0/mkspecs/modules/qt_lib_sql_private.pri"; sourceTree = "<absolute>"; };
|
||||||
075F99A91A45EEF200915C72 /* lang_es.strings */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = lang_es.strings; path = SourceFiles/langs/lang_es.strings; sourceTree = SOURCE_ROOT; };
|
075F99A91A45EEF200915C72 /* lang_es.strings */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = lang_es.strings; path = SourceFiles/langs/lang_es.strings; sourceTree = SOURCE_ROOT; };
|
||||||
|
0764D5581ABAD6F900FBFEED /* apiwrap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = apiwrap.cpp; path = SourceFiles/apiwrap.cpp; sourceTree = SOURCE_ROOT; };
|
||||||
|
0764D5591ABAD6F900FBFEED /* apiwrap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = apiwrap.h; path = SourceFiles/apiwrap.h; sourceTree = SOURCE_ROOT; };
|
||||||
|
0764D55C1ABAD71B00FBFEED /* moc_apiwrap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = moc_apiwrap.cpp; path = GeneratedFiles/Debug/moc_apiwrap.cpp; sourceTree = SOURCE_ROOT; };
|
||||||
0771C4C94B623FC34BF62983 /* intro.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = intro.cpp; path = SourceFiles/intro/intro.cpp; sourceTree = "<absolute>"; };
|
0771C4C94B623FC34BF62983 /* intro.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = intro.cpp; path = SourceFiles/intro/intro.cpp; sourceTree = "<absolute>"; };
|
||||||
078A2FC91A811C5900CCC7A0 /* moc_backgroundbox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = moc_backgroundbox.cpp; path = GeneratedFiles/Debug/moc_backgroundbox.cpp; sourceTree = SOURCE_ROOT; };
|
078A2FC91A811C5900CCC7A0 /* moc_backgroundbox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = moc_backgroundbox.cpp; path = GeneratedFiles/Debug/moc_backgroundbox.cpp; sourceTree = SOURCE_ROOT; };
|
||||||
078A2FCB1A811CA600CCC7A0 /* backgroundbox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = backgroundbox.cpp; path = SourceFiles/boxes/backgroundbox.cpp; sourceTree = SOURCE_ROOT; };
|
078A2FCB1A811CA600CCC7A0 /* backgroundbox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = backgroundbox.cpp; path = SourceFiles/boxes/backgroundbox.cpp; sourceTree = SOURCE_ROOT; };
|
||||||
|
@ -883,6 +888,7 @@
|
||||||
children = (
|
children = (
|
||||||
5271C394C1E7646D117CE67E /* main.cpp */,
|
5271C394C1E7646D117CE67E /* main.cpp */,
|
||||||
5A5431331A13AA7B07414240 /* stdafx.cpp */,
|
5A5431331A13AA7B07414240 /* stdafx.cpp */,
|
||||||
|
0764D5581ABAD6F900FBFEED /* apiwrap.cpp */,
|
||||||
06E379415713F34B83F99C35 /* app.cpp */,
|
06E379415713F34B83F99C35 /* app.cpp */,
|
||||||
C20F9DD8C7B031B8E20D5653 /* application.cpp */,
|
C20F9DD8C7B031B8E20D5653 /* application.cpp */,
|
||||||
07D7034919B8755A00C4EED2 /* audio.cpp */,
|
07D7034919B8755A00C4EED2 /* audio.cpp */,
|
||||||
|
@ -916,6 +922,7 @@
|
||||||
5E35A03E5F2C51353EBCBF00 /* intro */,
|
5E35A03E5F2C51353EBCBF00 /* intro */,
|
||||||
074968CB1A44D0B800394F46 /* langs */,
|
074968CB1A44D0B800394F46 /* langs */,
|
||||||
6011DDB120E1B2D4803E129A /* stdafx.h */,
|
6011DDB120E1B2D4803E129A /* stdafx.h */,
|
||||||
|
0764D5591ABAD6F900FBFEED /* apiwrap.h */,
|
||||||
C19DF71B273A4843553518F2 /* app.h */,
|
C19DF71B273A4843553518F2 /* app.h */,
|
||||||
09FD01F2BD652EB838A296D8 /* application.h */,
|
09FD01F2BD652EB838A296D8 /* application.h */,
|
||||||
07D7034A19B8755A00C4EED2 /* audio.h */,
|
07D7034A19B8755A00C4EED2 /* audio.h */,
|
||||||
|
@ -1085,6 +1092,7 @@
|
||||||
801973D3334D0FCA849CF485 /* Debug */ = {
|
801973D3334D0FCA849CF485 /* Debug */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
0764D55C1ABAD71B00FBFEED /* moc_apiwrap.cpp */,
|
||||||
07DE92AB1AA4928B00A18F6F /* moc_passcodebox.cpp */,
|
07DE92AB1AA4928B00A18F6F /* moc_passcodebox.cpp */,
|
||||||
07DE92AC1AA4928B00A18F6F /* moc_passcodewidget.cpp */,
|
07DE92AC1AA4928B00A18F6F /* moc_passcodewidget.cpp */,
|
||||||
07DE92A91AA4928200A18F6F /* moc_autolockbox.cpp */,
|
07DE92A91AA4928200A18F6F /* moc_autolockbox.cpp */,
|
||||||
|
@ -1583,11 +1591,13 @@
|
||||||
B2F5B08BFFBBE7E37D3863BB /* moc_button.cpp in Compile Sources */,
|
B2F5B08BFFBBE7E37D3863BB /* moc_button.cpp in Compile Sources */,
|
||||||
B6F50D5FBFAEB16DD0E5B1C3 /* moc_countrycodeinput.cpp in Compile Sources */,
|
B6F50D5FBFAEB16DD0E5B1C3 /* moc_countrycodeinput.cpp in Compile Sources */,
|
||||||
6A8BC88AB464B92706EFE6FF /* moc_countryinput.cpp in Compile Sources */,
|
6A8BC88AB464B92706EFE6FF /* moc_countryinput.cpp in Compile Sources */,
|
||||||
|
0764D55A1ABAD6F900FBFEED /* apiwrap.cpp in Compile Sources */,
|
||||||
07DE92A01AA4923300A18F6F /* passcodewidget.cpp in Compile Sources */,
|
07DE92A01AA4923300A18F6F /* passcodewidget.cpp in Compile Sources */,
|
||||||
B0B88EFE444C0DE673389418 /* moc_flatbutton.cpp in Compile Sources */,
|
B0B88EFE444C0DE673389418 /* moc_flatbutton.cpp in Compile Sources */,
|
||||||
1BD711B4C358EA7D727BF358 /* moc_flatcheckbox.cpp in Compile Sources */,
|
1BD711B4C358EA7D727BF358 /* moc_flatcheckbox.cpp in Compile Sources */,
|
||||||
565F748438E6CE0148C54AFE /* moc_flatinput.cpp in Compile Sources */,
|
565F748438E6CE0148C54AFE /* moc_flatinput.cpp in Compile Sources */,
|
||||||
8B71D1C7BB9DCEE6511219C2 /* moc_flatlabel.cpp in Compile Sources */,
|
8B71D1C7BB9DCEE6511219C2 /* moc_flatlabel.cpp in Compile Sources */,
|
||||||
|
0764D55D1ABAD71B00FBFEED /* moc_apiwrap.cpp in Compile Sources */,
|
||||||
07DE92AD1AA4928B00A18F6F /* moc_passcodebox.cpp in Compile Sources */,
|
07DE92AD1AA4928B00A18F6F /* moc_passcodebox.cpp in Compile Sources */,
|
||||||
FCC949FEA178F9F5D7478027 /* moc_flattextarea.cpp in Compile Sources */,
|
FCC949FEA178F9F5D7478027 /* moc_flattextarea.cpp in Compile Sources */,
|
||||||
3A62C3A2FB56A83C9C3A3AFF /* moc_phoneinput.cpp in Compile Sources */,
|
3A62C3A2FB56A83C9C3A3AFF /* moc_phoneinput.cpp in Compile Sources */,
|
||||||
|
@ -1657,7 +1667,7 @@
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
CURRENT_PROJECT_VERSION = 0.7.20;
|
CURRENT_PROJECT_VERSION = 0.7.21;
|
||||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||||
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
||||||
GCC_OPTIMIZATION_LEVEL = 0;
|
GCC_OPTIMIZATION_LEVEL = 0;
|
||||||
|
@ -1675,7 +1685,7 @@
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
COPY_PHASE_STRIP = YES;
|
COPY_PHASE_STRIP = YES;
|
||||||
CURRENT_PROJECT_VERSION = 0.7.20;
|
CURRENT_PROJECT_VERSION = 0.7.21;
|
||||||
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
||||||
GCC_OPTIMIZATION_LEVEL = fast;
|
GCC_OPTIMIZATION_LEVEL = fast;
|
||||||
GCC_PREFIX_HEADER = ./SourceFiles/stdafx.h;
|
GCC_PREFIX_HEADER = ./SourceFiles/stdafx.h;
|
||||||
|
@ -1701,10 +1711,10 @@
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
CODE_SIGN_IDENTITY = "";
|
CODE_SIGN_IDENTITY = "";
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
CURRENT_PROJECT_VERSION = 0.7.20;
|
CURRENT_PROJECT_VERSION = 0.7.21;
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
DYLIB_COMPATIBILITY_VERSION = 0.7;
|
DYLIB_COMPATIBILITY_VERSION = 0.7;
|
||||||
DYLIB_CURRENT_VERSION = 0.7.20;
|
DYLIB_CURRENT_VERSION = 0.7.21;
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
FRAMEWORK_SEARCH_PATHS = "";
|
FRAMEWORK_SEARCH_PATHS = "";
|
||||||
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
||||||
|
@ -1842,10 +1852,10 @@
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
CODE_SIGN_IDENTITY = "";
|
CODE_SIGN_IDENTITY = "";
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
CURRENT_PROJECT_VERSION = 0.7.20;
|
CURRENT_PROJECT_VERSION = 0.7.21;
|
||||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||||
DYLIB_COMPATIBILITY_VERSION = 0.7;
|
DYLIB_COMPATIBILITY_VERSION = 0.7;
|
||||||
DYLIB_CURRENT_VERSION = 0.7.20;
|
DYLIB_CURRENT_VERSION = 0.7.21;
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
FRAMEWORK_SEARCH_PATHS = "";
|
FRAMEWORK_SEARCH_PATHS = "";
|
||||||
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
||||||
|
|
|
@ -31,7 +31,7 @@ mocables: compiler_moc_header_make_all compiler_moc_source_make_all
|
||||||
|
|
||||||
check: first
|
check: first
|
||||||
|
|
||||||
compilers: GeneratedFiles/qrc_telegram.cpp GeneratedFiles/Debug/moc_application.cpp GeneratedFiles/Debug/moc_audio.cpp GeneratedFiles/Debug/moc_dialogswidget.cpp GeneratedFiles/Debug/moc_dropdown.cpp\
|
compilers: GeneratedFiles/qrc_telegram.cpp GeneratedFiles/Debug/moc_apiwrap.cpp GeneratedFiles/Debug/moc_application.cpp GeneratedFiles/Debug/moc_audio.cpp GeneratedFiles/Debug/moc_dialogswidget.cpp GeneratedFiles/Debug/moc_dropdown.cpp\
|
||||||
GeneratedFiles/Debug/moc_fileuploader.cpp GeneratedFiles/Debug/moc_history.cpp GeneratedFiles/Debug/moc_historywidget.cpp GeneratedFiles/Debug/moc_layerwidget.cpp\
|
GeneratedFiles/Debug/moc_fileuploader.cpp GeneratedFiles/Debug/moc_history.cpp GeneratedFiles/Debug/moc_historywidget.cpp GeneratedFiles/Debug/moc_layerwidget.cpp\
|
||||||
GeneratedFiles/Debug/moc_mediaview.cpp GeneratedFiles/Debug/moc_overviewwidget.cpp GeneratedFiles/Debug/moc_profilewidget.cpp\
|
GeneratedFiles/Debug/moc_mediaview.cpp GeneratedFiles/Debug/moc_overviewwidget.cpp GeneratedFiles/Debug/moc_profilewidget.cpp\
|
||||||
GeneratedFiles/Debug/moc_passcodewidget.cpp\
|
GeneratedFiles/Debug/moc_passcodewidget.cpp\
|
||||||
|
@ -94,9 +94,14 @@ GeneratedFiles/qrc_telegram.cpp: SourceFiles/telegram.qrc \
|
||||||
SourceFiles/art/chatcolor2.png
|
SourceFiles/art/chatcolor2.png
|
||||||
/usr/local/Qt-5.4.0/bin/rcc -name telegram SourceFiles/telegram.qrc -o GeneratedFiles/qrc_telegram.cpp
|
/usr/local/Qt-5.4.0/bin/rcc -name telegram SourceFiles/telegram.qrc -o GeneratedFiles/qrc_telegram.cpp
|
||||||
|
|
||||||
compiler_moc_header_make_all: GeneratedFiles/Debug/moc_application.cpp GeneratedFiles/Debug/moc_audio.cpp GeneratedFiles/Debug/moc_dialogswidget.cpp GeneratedFiles/Debug/moc_dropdown.cpp GeneratedFiles/Debug/moc_fileuploader.cpp GeneratedFiles/Debug/moc_history.cpp GeneratedFiles/Debug/moc_historywidget.cpp GeneratedFiles/Debug/moc_layerwidget.cpp GeneratedFiles/Debug/moc_mediaview.cpp GeneratedFiles/Debug/moc_overviewwidget.cpp GeneratedFiles/Debug/moc_profilewidget.cpp GeneratedFiles/Debug/moc_passcodewidget.cpp GeneratedFiles/Debug/moc_localimageloader.cpp GeneratedFiles/Debug/moc_localstorage.cpp GeneratedFiles/Debug/moc_mainwidget.cpp GeneratedFiles/Debug/moc_settingswidget.cpp GeneratedFiles/Debug/moc_sysbuttons.cpp GeneratedFiles/Debug/moc_title.cpp GeneratedFiles/Debug/moc_types.cpp GeneratedFiles/Debug/moc_window.cpp GeneratedFiles/Debug/moc_mtp.cpp GeneratedFiles/Debug/moc_mtpConnection.cpp GeneratedFiles/Debug/moc_mtpDC.cpp GeneratedFiles/Debug/moc_mtpFileLoader.cpp GeneratedFiles/Debug/moc_mtpSession.cpp GeneratedFiles/Debug/moc_animation.cpp GeneratedFiles/Debug/moc_button.cpp GeneratedFiles/Debug/moc_contextmenu.cpp GeneratedFiles/Debug/moc_countrycodeinput.cpp GeneratedFiles/Debug/moc_countryinput.cpp GeneratedFiles/Debug/moc_flatbutton.cpp GeneratedFiles/Debug/moc_flatcheckbox.cpp GeneratedFiles/Debug/moc_flatinput.cpp GeneratedFiles/Debug/moc_flatlabel.cpp GeneratedFiles/Debug/moc_flattextarea.cpp GeneratedFiles/Debug/moc_switcher.cpp GeneratedFiles/Debug/moc_phoneinput.cpp GeneratedFiles/Debug/moc_scrollarea.cpp GeneratedFiles/Debug/moc_twidget.cpp GeneratedFiles/Debug/moc_aboutbox.cpp GeneratedFiles/Debug/moc_addcontactbox.cpp GeneratedFiles/Debug/moc_addparticipantbox.cpp GeneratedFiles/Debug/moc_autolockbox.cpp GeneratedFiles/Debug/moc_backgroundbox.cpp GeneratedFiles/Debug/moc_confirmbox.cpp GeneratedFiles/Debug/moc_connectionbox.cpp GeneratedFiles/Debug/moc_contactsbox.cpp GeneratedFiles/Debug/moc_downloadpathbox.cpp GeneratedFiles/Debug/moc_emojibox.cpp GeneratedFiles/Debug/moc_languagebox.cpp GeneratedFiles/Debug/moc_newgroupbox.cpp GeneratedFiles/Debug/moc_passcodebox.cpp GeneratedFiles/Debug/moc_photocropbox.cpp GeneratedFiles/Debug/moc_photosendbox.cpp GeneratedFiles/Debug/moc_usernamebox.cpp GeneratedFiles/Debug/moc_intro.cpp GeneratedFiles/Debug/moc_introcode.cpp GeneratedFiles/Debug/moc_introphone.cpp GeneratedFiles/Debug/moc_introsignup.cpp GeneratedFiles/Debug/moc_pspecific_mac.cpp
|
compiler_moc_header_make_all: GeneratedFiles/Debug/moc_apiwrap.cpp GeneratedFiles/Debug/moc_application.cpp GeneratedFiles/Debug/moc_audio.cpp GeneratedFiles/Debug/moc_dialogswidget.cpp GeneratedFiles/Debug/moc_dropdown.cpp GeneratedFiles/Debug/moc_fileuploader.cpp GeneratedFiles/Debug/moc_history.cpp GeneratedFiles/Debug/moc_historywidget.cpp GeneratedFiles/Debug/moc_layerwidget.cpp GeneratedFiles/Debug/moc_mediaview.cpp GeneratedFiles/Debug/moc_overviewwidget.cpp GeneratedFiles/Debug/moc_profilewidget.cpp GeneratedFiles/Debug/moc_passcodewidget.cpp GeneratedFiles/Debug/moc_localimageloader.cpp GeneratedFiles/Debug/moc_localstorage.cpp GeneratedFiles/Debug/moc_mainwidget.cpp GeneratedFiles/Debug/moc_settingswidget.cpp GeneratedFiles/Debug/moc_sysbuttons.cpp GeneratedFiles/Debug/moc_title.cpp GeneratedFiles/Debug/moc_types.cpp GeneratedFiles/Debug/moc_window.cpp GeneratedFiles/Debug/moc_mtp.cpp GeneratedFiles/Debug/moc_mtpConnection.cpp GeneratedFiles/Debug/moc_mtpDC.cpp GeneratedFiles/Debug/moc_mtpFileLoader.cpp GeneratedFiles/Debug/moc_mtpSession.cpp GeneratedFiles/Debug/moc_animation.cpp GeneratedFiles/Debug/moc_button.cpp GeneratedFiles/Debug/moc_contextmenu.cpp GeneratedFiles/Debug/moc_countrycodeinput.cpp GeneratedFiles/Debug/moc_countryinput.cpp GeneratedFiles/Debug/moc_flatbutton.cpp GeneratedFiles/Debug/moc_flatcheckbox.cpp GeneratedFiles/Debug/moc_flatinput.cpp GeneratedFiles/Debug/moc_flatlabel.cpp GeneratedFiles/Debug/moc_flattextarea.cpp GeneratedFiles/Debug/moc_switcher.cpp GeneratedFiles/Debug/moc_phoneinput.cpp GeneratedFiles/Debug/moc_scrollarea.cpp GeneratedFiles/Debug/moc_twidget.cpp GeneratedFiles/Debug/moc_aboutbox.cpp GeneratedFiles/Debug/moc_addcontactbox.cpp GeneratedFiles/Debug/moc_addparticipantbox.cpp GeneratedFiles/Debug/moc_autolockbox.cpp GeneratedFiles/Debug/moc_backgroundbox.cpp GeneratedFiles/Debug/moc_confirmbox.cpp GeneratedFiles/Debug/moc_connectionbox.cpp GeneratedFiles/Debug/moc_contactsbox.cpp GeneratedFiles/Debug/moc_downloadpathbox.cpp GeneratedFiles/Debug/moc_emojibox.cpp GeneratedFiles/Debug/moc_languagebox.cpp GeneratedFiles/Debug/moc_newgroupbox.cpp GeneratedFiles/Debug/moc_passcodebox.cpp GeneratedFiles/Debug/moc_photocropbox.cpp GeneratedFiles/Debug/moc_photosendbox.cpp GeneratedFiles/Debug/moc_usernamebox.cpp GeneratedFiles/Debug/moc_intro.cpp GeneratedFiles/Debug/moc_introcode.cpp GeneratedFiles/Debug/moc_introphone.cpp GeneratedFiles/Debug/moc_introsignup.cpp GeneratedFiles/Debug/moc_pspecific_mac.cpp
|
||||||
compiler_moc_header_clean:
|
compiler_moc_header_clean:
|
||||||
-$(DEL_FILE) GeneratedFiles/Debug/moc_application.cpp GeneratedFiles/Debug/moc_audio.cpp GeneratedFiles/Debug/moc_dialogswidget.cpp GeneratedFiles/Debug/moc_dropdown.cpp GeneratedFiles/Debug/moc_fileuploader.cpp GeneratedFiles/Debug/moc_history.cpp GeneratedFiles/Debug/moc_historywidget.cpp GeneratedFiles/Debug/moc_layerwidget.cpp GeneratedFiles/Debug/moc_mediaview.cpp GeneratedFiles/Debug/moc_overviewwidget.cpp GeneratedFiles/Debug/moc_profilewidget.cpp GeneratedFiles/Debug/moc_passcodewidget.cpp GeneratedFiles/Debug/moc_localimageloader.cpp GeneratedFiles/Debug/moc_localstorage.cpp GeneratedFiles/Debug/moc_mainwidget.cpp GeneratedFiles/Debug/moc_settingswidget.cpp GeneratedFiles/Debug/moc_sysbuttons.cpp GeneratedFiles/Debug/moc_title.cpp GeneratedFiles/Debug/moc_types.cpp GeneratedFiles/Debug/moc_window.cpp GeneratedFiles/Debug/moc_mtp.cpp GeneratedFiles/Debug/moc_mtpConnection.cpp GeneratedFiles/Debug/moc_mtpDC.cpp GeneratedFiles/Debug/moc_mtpFileLoader.cpp GeneratedFiles/Debug/moc_mtpSession.cpp GeneratedFiles/Debug/moc_animation.cpp GeneratedFiles/Debug/moc_button.cpp GeneratedFiles/Debug/moc_contextmenu.cpp GeneratedFiles/Debug/moc_countrycodeinput.cpp GeneratedFiles/Debug/moc_countryinput.cpp GeneratedFiles/Debug/moc_flatbutton.cpp GeneratedFiles/Debug/moc_flatcheckbox.cpp GeneratedFiles/Debug/moc_flatinput.cpp GeneratedFiles/Debug/moc_flatlabel.cpp GeneratedFiles/Debug/moc_flattextarea.cpp GeneratedFiles/Debug/moc_switcher.cpp GeneratedFiles/Debug/moc_phoneinput.cpp GeneratedFiles/Debug/moc_scrollarea.cpp GeneratedFiles/Debug/moc_twidget.cpp GeneratedFiles/Debug/moc_aboutbox.cpp GeneratedFiles/Debug/moc_addcontactbox.cpp GeneratedFiles/Debug/moc_addparticipantbox.cpp GeneratedFiles/Debug/moc_autolockbox.cpp GeneratedFiles/Debug/moc_backgroundbox.cpp GeneratedFiles/Debug/moc_confirmbox.cpp GeneratedFiles/Debug/moc_connectionbox.cpp GeneratedFiles/Debug/moc_contactsbox.cpp GeneratedFiles/Debug/moc_downloadpathbox.cpp GeneratedFiles/Debug/moc_emojibox.cpp GeneratedFiles/Debug/moc_languagebox.cpp GeneratedFiles/Debug/moc_newgroupbox.cpp GeneratedFiles/Debug/moc_passcodebox.cpp GeneratedFiles/Debug/moc_photocropbox.cpp GeneratedFiles/Debug/moc_photosendbox.cpp GeneratedFiles/Debug/moc_usernamedbox.cpp GeneratedFiles/Debug/moc_intro.cpp GeneratedFiles/Debug/moc_introcode.cpp GeneratedFiles/Debug/moc_introphone.cpp GeneratedFiles/Debug/moc_introsignup.cpp GeneratedFiles/Debug/moc_pspecific_mac.cpp
|
-$(DEL_FILE) GeneratedFiles/Debug/moc_apiwrap.cpp GeneratedFiles/Debug/moc_application.cpp GeneratedFiles/Debug/moc_audio.cpp GeneratedFiles/Debug/moc_dialogswidget.cpp GeneratedFiles/Debug/moc_dropdown.cpp GeneratedFiles/Debug/moc_fileuploader.cpp GeneratedFiles/Debug/moc_history.cpp GeneratedFiles/Debug/moc_historywidget.cpp GeneratedFiles/Debug/moc_layerwidget.cpp GeneratedFiles/Debug/moc_mediaview.cpp GeneratedFiles/Debug/moc_overviewwidget.cpp GeneratedFiles/Debug/moc_profilewidget.cpp GeneratedFiles/Debug/moc_passcodewidget.cpp GeneratedFiles/Debug/moc_localimageloader.cpp GeneratedFiles/Debug/moc_localstorage.cpp GeneratedFiles/Debug/moc_mainwidget.cpp GeneratedFiles/Debug/moc_settingswidget.cpp GeneratedFiles/Debug/moc_sysbuttons.cpp GeneratedFiles/Debug/moc_title.cpp GeneratedFiles/Debug/moc_types.cpp GeneratedFiles/Debug/moc_window.cpp GeneratedFiles/Debug/moc_mtp.cpp GeneratedFiles/Debug/moc_mtpConnection.cpp GeneratedFiles/Debug/moc_mtpDC.cpp GeneratedFiles/Debug/moc_mtpFileLoader.cpp GeneratedFiles/Debug/moc_mtpSession.cpp GeneratedFiles/Debug/moc_animation.cpp GeneratedFiles/Debug/moc_button.cpp GeneratedFiles/Debug/moc_contextmenu.cpp GeneratedFiles/Debug/moc_countrycodeinput.cpp GeneratedFiles/Debug/moc_countryinput.cpp GeneratedFiles/Debug/moc_flatbutton.cpp GeneratedFiles/Debug/moc_flatcheckbox.cpp GeneratedFiles/Debug/moc_flatinput.cpp GeneratedFiles/Debug/moc_flatlabel.cpp GeneratedFiles/Debug/moc_flattextarea.cpp GeneratedFiles/Debug/moc_switcher.cpp GeneratedFiles/Debug/moc_phoneinput.cpp GeneratedFiles/Debug/moc_scrollarea.cpp GeneratedFiles/Debug/moc_twidget.cpp GeneratedFiles/Debug/moc_aboutbox.cpp GeneratedFiles/Debug/moc_addcontactbox.cpp GeneratedFiles/Debug/moc_addparticipantbox.cpp GeneratedFiles/Debug/moc_autolockbox.cpp GeneratedFiles/Debug/moc_backgroundbox.cpp GeneratedFiles/Debug/moc_confirmbox.cpp GeneratedFiles/Debug/moc_connectionbox.cpp GeneratedFiles/Debug/moc_contactsbox.cpp GeneratedFiles/Debug/moc_downloadpathbox.cpp GeneratedFiles/Debug/moc_emojibox.cpp GeneratedFiles/Debug/moc_languagebox.cpp GeneratedFiles/Debug/moc_newgroupbox.cpp GeneratedFiles/Debug/moc_passcodebox.cpp GeneratedFiles/Debug/moc_photocropbox.cpp GeneratedFiles/Debug/moc_photosendbox.cpp GeneratedFiles/Debug/moc_usernamedbox.cpp GeneratedFiles/Debug/moc_intro.cpp GeneratedFiles/Debug/moc_introcode.cpp GeneratedFiles/Debug/moc_introphone.cpp GeneratedFiles/Debug/moc_introsignup.cpp GeneratedFiles/Debug/moc_pspecific_mac.cpp
|
||||||
|
GeneratedFiles/Debug/moc_apiwrap.cpp: SourceFiles/types.h \
|
||||||
|
SourceFiles/logs.h \
|
||||||
|
SourceFiles/apiwrap.h
|
||||||
|
/usr/local/Qt-5.4.0/bin/moc $(DEFINES) -D__APPLE__ -D__GNUC__=4 -I/usr/local/Qt-5.4.0/mkspecs/macx-clang -I. -I/usr/local/Qt-5.4.0/include/QtGui/5.4.0/QtGui -I/usr/local/Qt-5.4.0/include/QtCore/5.4.0/QtCore -I/usr/local/Qt-5.4.0/include -I./SourceFiles -I./GeneratedFiles -I../../Libraries/lzma/C -I../../Libraries/libexif-0.6.20 -I/usr/local/Qt-5.4.0/include -I/usr/local/Qt-5.4.0/include/QtMultimedia -I/usr/local/Qt-5.4.0/include/QtWidgets -I/usr/local/Qt-5.4.0/include/QtNetwork -I/usr/local/Qt-5.4.0/include/QtGui -I/usr/local/Qt-5.4.0/include/QtCore -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/c++/4.2.1 -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/c++/4.2.1/backward -I/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/5.1/include -I/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include SourceFiles/apiwrap.h -o GeneratedFiles/Debug/moc_apiwrap.cpp
|
||||||
|
|
||||||
GeneratedFiles/Debug/moc_application.cpp: ../../Libraries/QtStatic/qtbase/include/QtNetwork/QLocalSocket \
|
GeneratedFiles/Debug/moc_application.cpp: ../../Libraries/QtStatic/qtbase/include/QtNetwork/QLocalSocket \
|
||||||
../../Libraries/QtStatic/qtbase/include/QtNetwork/QLocalServer \
|
../../Libraries/QtStatic/qtbase/include/QtNetwork/QLocalServer \
|
||||||
../../Libraries/QtStatic/qtbase/include/QtNetwork/QNetworkReply \
|
../../Libraries/QtStatic/qtbase/include/QtNetwork/QNetworkReply \
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
echo 7020 0.7.20 0
|
echo 7021 0.7.21 1
|
||||||
# AppVersion AppVersionStr DevChannel
|
# AppVersion AppVersionStr DevChannel
|
||||||
|
|
Loading…
Add table
Reference in a new issue