diff --git a/Telegram/PrepareWin.bat b/Telegram/PrepareWin.bat index 4d5e7f6c0..0be6ea4da 100644 --- a/Telegram/PrepareWin.bat +++ b/Telegram/PrepareWin.bat @@ -1,10 +1,10 @@ @echo OFF set "AppVersionStrMajor=0.8" -set "AppVersion=8034" -set "AppVersionStrSmall=0.8.34" -set "AppVersionStr=0.8.34" -set "AppVersionStrFull=0.8.34.0" +set "AppVersion=8035" +set "AppVersionStrSmall=0.8.35" +set "AppVersionStr=0.8.35" +set "AppVersionStrFull=0.8.35.0" set "DevChannel=1" if %DevChannel% neq 0 goto preparedev diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index 88f1813df..3db15bb4b 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -132,22 +132,27 @@ void ApiWrap::gotReplyTo(const MTPmessages_Messages &msgs, mtpRequestId req) { } void ApiWrap::requestFullPeer(PeerData *peer) { - if (!peer || _fullRequests.contains(peer)) return; + if (!peer || _fullPeerRequests.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)); + req = MTP::send(MTPmessages_GetFullChat(MTP_int(App::chatFromPeer(peer->id))), rpcDone(&ApiWrap::gotChatFull, peer), rpcFail(&ApiWrap::gotPeerFullFailed, peer)); } else { - req = MTP::send(MTPusers_GetFullUser(peer->asUser()->inputUser), rpcDone(&ApiWrap::gotUserFull, peer), rpcFail(&ApiWrap::gotPeerFailed, peer)); + req = MTP::send(MTPusers_GetFullUser(peer->asUser()->inputUser), rpcDone(&ApiWrap::gotUserFull, peer), rpcFail(&ApiWrap::gotPeerFullFailed, peer)); } - _fullRequests.insert(peer, req); + _fullPeerRequests.insert(peer, req); } void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result) { const MTPDmessages_chatFull &d(result.c_messages_chatFull()); const MTPDchatFull &f(d.vfull_chat.c_chatFull()); - App::feedUsers(d.vusers); - App::feedChats(d.vchats); - App::feedParticipants(f.vparticipants); + + const QVector &vc(d.vchats.c_vector().v); + bool badVersion = (!vc.isEmpty() && vc.at(0).type() == mtpc_chat && vc.at(0).c_chat().vversion.v < peer->asChat()->version); + + App::feedUsers(d.vusers, false); + App::feedChats(d.vchats, false); + App::feedParticipants(f.vparticipants, false, false); const QVector &v(f.vbot_info.c_vector().v); for (QVector::const_iterator i = v.cbegin(), e = v.cend(); i < e; ++i) { switch (i->type()) { @@ -156,6 +161,7 @@ void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result) { UserData *user = App::userLoaded(b.vuser_id.v); if (user) { user->setBotInfo(*i); + App::clearPeerUpdated(user); emit fullPeerUpdated(user); } } break; @@ -167,33 +173,86 @@ void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result) { if (photo) { chat->photoId = photo->id; photo->chat = chat; + } else { + chat->photoId = 0; } chat->invitationUrl = (f.vexported_invite.type() == mtpc_chatInviteExported) ? qs(f.vexported_invite.c_chatInviteExported().vlink) : QString(); } App::main()->gotNotifySetting(MTP_inputNotifyPeer(peer->input), f.vnotify_settings); - _fullRequests.remove(peer); + _fullPeerRequests.remove(peer); + if (badVersion) { + peer->asChat()->version = vc.at(0).c_chat().vversion.v; + requestPeer(peer); + } + App::clearPeerUpdated(peer); emit fullPeerUpdated(peer); + App::emitPeerUpdated(); } void ApiWrap::gotUserFull(PeerData *peer, const MTPUserFull &result) { const MTPDuserFull &d(result.c_userFull()); - App::feedUsers(MTP_vector(1, d.vuser)); + App::feedUsers(MTP_vector(1, d.vuser), false); App::feedPhoto(d.vprofile_photo); - App::feedUserLink(MTP_int(App::userFromPeer(peer->id)), d.vlink.c_contacts_link().vmy_link, d.vlink.c_contacts_link().vforeign_link); + App::feedUserLink(MTP_int(App::userFromPeer(peer->id)), d.vlink.c_contacts_link().vmy_link, d.vlink.c_contacts_link().vforeign_link, false); App::main()->gotNotifySetting(MTP_inputNotifyPeer(peer->input), d.vnotify_settings); peer->asUser()->setBotInfo(d.vbot_info); - _fullRequests.remove(peer); + _fullPeerRequests.remove(peer); + App::clearPeerUpdated(peer); emit fullPeerUpdated(peer); + App::emitPeerUpdated(); +} + +bool ApiWrap::gotPeerFullFailed(PeerData *peer, const RPCError &error) { + if (error.type().startsWith(qsl("FLOOD_WAIT_"))) return false; + + _fullPeerRequests.remove(peer); + return true; +} + +void ApiWrap::requestPeer(PeerData *peer) { + if (!peer || _fullPeerRequests.contains(peer) || _peerRequests.contains(peer)) return; + + mtpRequestId req; + if (peer->chat) { + req = MTP::send(MTPmessages_GetChats(MTP_vector(1, MTP_int(App::chatFromPeer(peer->id)))), rpcDone(&ApiWrap::gotChat, peer), rpcFail(&ApiWrap::gotPeerFailed, peer)); + } else { + req = MTP::send(MTPusers_GetUsers(MTP_vector(1, peer->asUser()->inputUser)), rpcDone(&ApiWrap::gotUser, peer), rpcFail(&ApiWrap::gotPeerFailed, peer)); + } + _peerRequests.insert(peer, req); +} + +void ApiWrap::gotChat(PeerData *peer, const MTPmessages_Chats &result) { + _peerRequests.remove(peer); + + if (result.type() == mtpc_messages_chats) { + const QVector &v(result.c_messages_chats().vchats.c_vector().v); + bool badVersion = (!v.isEmpty() && v.at(0).type() == mtpc_chat && v.at(0).c_chat().vversion.v < peer->asChat()->version); + ChatData *chat = App::feedChats(result.c_messages_chats().vchats); + if (chat == peer) { + if (badVersion) { + peer->asChat()->version = v.at(0).c_chat().vversion.v; + requestPeer(peer); + } + } + } +} + +void ApiWrap::gotUser(PeerData *peer, const MTPVector &result) { + _peerRequests.remove(peer); + + UserData *user = App::feedUsers(result); + if (user == peer) { + } } bool ApiWrap::gotPeerFailed(PeerData *peer, const RPCError &error) { if (error.type().startsWith(qsl("FLOOD_WAIT_"))) return false; - _fullRequests.remove(peer); + _peerRequests.remove(peer); return true; } diff --git a/Telegram/SourceFiles/apiwrap.h b/Telegram/SourceFiles/apiwrap.h index 40c453e09..f73561c4c 100644 --- a/Telegram/SourceFiles/apiwrap.h +++ b/Telegram/SourceFiles/apiwrap.h @@ -31,6 +31,7 @@ public: void requestReplyTo(HistoryReply *reply, MsgId to); void requestFullPeer(PeerData *peer); + void requestPeer(PeerData *peer); void requestWebPageDelayed(WebPageData *page); void clearWebPageRequest(WebPageData *page); @@ -65,9 +66,14 @@ private: void gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result); void gotUserFull(PeerData *peer, const MTPUserFull &result); + bool gotPeerFullFailed(PeerData *peer, const RPCError &err); + typedef QMap PeerRequests; + PeerRequests _fullPeerRequests; + + void gotChat(PeerData *peer, const MTPmessages_Chats &result); + void gotUser(PeerData *peer, const MTPVector &result); bool gotPeerFailed(PeerData *peer, const RPCError &err); - typedef QMap FullRequests; - FullRequests _fullRequests; + PeerRequests _peerRequests; void gotWebPages(const MTPmessages_Messages &result, mtpRequestId req); typedef QMap WebPagesPending; diff --git a/Telegram/SourceFiles/app.cpp b/Telegram/SourceFiles/app.cpp index 82a9e2248..da97b1ad9 100644 --- a/Telegram/SourceFiles/app.cpp +++ b/Telegram/SourceFiles/app.cpp @@ -37,6 +37,9 @@ namespace { typedef QMap MutedPeers; MutedPeers mutedPeers; + typedef QMap UpdatedPeers; + UpdatedPeers updatedPeers; + typedef QHash PhotosData; PhotosData photosData; @@ -330,7 +333,7 @@ namespace App { return (online > now); } - UserData *feedUsers(const MTPVector &users) { + UserData *feedUsers(const MTPVector &users, bool emitPeerUpdated) { UserData *data = 0; const QVector &v(users.c_vector().v); for (QVector::const_iterator i = v.cbegin(), e = v.cend(); i != e; ++i) { @@ -428,19 +431,25 @@ namespace App { if (data->contact < 0 && !data->phone.isEmpty() && int32(data->id & 0xFFFFFFFF) != MTP::authedId()) { data->contact = 0; } - if (data->contact > 0 && !wasContact) { - App::main()->addNewContact(data->id & 0xFFFFFFFF, false); - } else if (wasContact && data->contact <= 0) { - App::main()->removeContact(data); - } + if (App::main()) { + if (data->contact > 0 && !wasContact) { + App::main()->addNewContact(data->id & 0xFFFFFFFF, false); + } else if (wasContact && data->contact <= 0) { + App::main()->removeContact(data); + } - if (App::main()) App::main()->peerUpdated(data); + if (emitPeerUpdated) { + App::main()->peerUpdated(data); + } else { + markPeerUpdated(data); + } + } } return data; } - ChatData *feedChats(const MTPVector &chats) { + ChatData *feedChats(const MTPVector &chats, bool emitPeerUpdated) { ChatData *data = 0; const QVector &v(chats.c_vector().v); for (QVector::const_iterator i = v.cbegin(), e = v.cend(); i != e; ++i) { @@ -507,24 +516,31 @@ namespace App { data->loaded = true; data->updateName(title.trimmed(), QString(), QString()); - if (App::main()) App::main()->peerUpdated(data); + if (App::main()) { + if (emitPeerUpdated) { + App::main()->peerUpdated(data); + } else { + markPeerUpdated(data); + } + } } return data; } - void feedParticipants(const MTPChatParticipants &p, bool requestBotInfos) { + void feedParticipants(const MTPChatParticipants &p, bool requestBotInfos, bool emitPeerUpdated) { + ChatData *chat = 0; switch (p.type()) { case mtpc_chatParticipantsForbidden: { const MTPDchatParticipantsForbidden &d(p.c_chatParticipantsForbidden()); - ChatData *chat = App::chat(d.vchat_id.v); + chat = App::chat(d.vchat_id.v); chat->count = -1; - if (App::main()) App::main()->peerUpdated(chat); } break; + case mtpc_chatParticipants: { const MTPDchatParticipants &d(p.c_chatParticipants()); - ChatData *chat = App::chat(d.vchat_id.v); + chat = App::chat(d.vchat_id.v); chat->admin = d.vadmin_id.v; - if (chat->version <= d.vversion.v) { + if (!requestBotInfos || chat->version <= d.vversion.v) { // !requestBotInfos is true on getFullChat result chat->version = d.vversion.v; const QVector &v(d.vparticipants.c_vector().v); chat->count = v.size(); @@ -568,13 +584,19 @@ namespace App { if (App::main()) App::main()->updateBotKeyboard(); } } - if (App::main()) App::main()->peerUpdated(chat); } } break; } + if (chat && App::main()) { + if (emitPeerUpdated) { + App::main()->peerUpdated(chat); + } else { + markPeerUpdated(chat); + } + } } - void feedParticipantAdd(const MTPDupdateChatParticipantAdd &d) { + void feedParticipantAdd(const MTPDupdateChatParticipantAdd &d, bool emitPeerUpdated) { ChatData *chat = App::chat(d.vchat_id.v); if (chat->version <= d.vversion.v && chat->count >= 0) { chat->version = d.vversion.v; @@ -601,11 +623,17 @@ namespace App { chat->botStatus = 0; chat->count++; } - if (App::main()) App::main()->peerUpdated(chat); + if (App::main()) { + if (emitPeerUpdated) { + App::main()->peerUpdated(chat); + } else { + markPeerUpdated(chat); + } + } } } - void feedParticipantDelete(const MTPDupdateChatParticipantDelete &d) { + void feedParticipantDelete(const MTPDupdateChatParticipantDelete &d, bool emitPeerUpdated) { ChatData *chat = App::chat(d.vchat_id.v); if (chat->version <= d.vversion.v && chat->count > 0) { chat->version = d.vversion.v; @@ -645,7 +673,13 @@ namespace App { chat->botStatus = 0; chat->count--; } - if (App::main()) App::main()->peerUpdated(chat); + if (App::main()) { + if (emitPeerUpdated) { + App::main()->peerUpdated(chat); + } else { + markPeerUpdated(chat); + } + } } } @@ -764,23 +798,30 @@ namespace App { } } - void feedUserLinks(const MTPVector &links) { + void feedUserLinks(const MTPVector &links, bool emitPeerUpdated) { const QVector &v(links.c_vector().v); for (QVector::const_iterator i = v.cbegin(), e = v.cend(); i != e; ++i) { const MTPDcontacts_link &dv(i->c_contacts_link()); - feedUsers(MTP_vector(1, dv.vuser)); + UserData *user = feedUsers(MTP_vector(1, dv.vuser), false); MTPint userId(MTP_int(0)); switch (dv.vuser.type()) { case mtpc_userEmpty: userId = dv.vuser.c_userEmpty().vid; break; case mtpc_user: userId = dv.vuser.c_user().vid; break; } if (userId.v) { - feedUserLink(userId, dv.vmy_link, dv.vforeign_link); + feedUserLink(userId, dv.vmy_link, dv.vforeign_link, false); + } + if (user && App::main()) { + if (emitPeerUpdated) { + App::main()->peerUpdated(user); + } else { + markPeerUpdated(user); + } } } } - void feedUserLink(MTPint userId, const MTPContactLink &myLink, const MTPContactLink &foreignLink) { + void feedUserLink(MTPint userId, const MTPContactLink &myLink, const MTPContactLink &foreignLink, bool emitPeerUpdated) { UserData *user = userLoaded(userId.v); if (user) { bool wasContact = (user->contact > 0); @@ -815,7 +856,32 @@ namespace App { } } user->setName(textOneLine(user->firstName), textOneLine(user->lastName), (user->contact || isServiceUser(user->id) || user->phone.isEmpty()) ? QString() : App::formatPhone(user->phone), textOneLine(user->username)); - if (App::main()) App::main()->peerUpdated(user); + if (App::main()) { + if (emitPeerUpdated) { + App::main()->peerUpdated(user); + } else { + markPeerUpdated(user); + } + } + } + } + + void markPeerUpdated(PeerData *data) { + updatedPeers.insert(data, true); + } + + void clearPeerUpdated(PeerData *data) { + updatedPeers.remove(data); + } + + void emitPeerUpdated() { + if (!updatedPeers.isEmpty() && App::main()) { + UpdatedPeers upd = updatedPeers; + updatedPeers.clear(); + + for (UpdatedPeers::const_iterator i = upd.cbegin(), e = upd.cend(); i != e; ++i) { + App::main()->peerUpdated(i.key()); + } } } @@ -1553,6 +1619,7 @@ namespace App { historyClearMsgs(); randomData.clear(); mutedPeers.clear(); + updatedPeers.clear(); for (PeersData::const_iterator i = peersData.cbegin(), e = peersData.cend(); i != e; ++i) { delete *i; } diff --git a/Telegram/SourceFiles/app.h b/Telegram/SourceFiles/app.h index 829ae4dc4..ea91a47e2 100644 --- a/Telegram/SourceFiles/app.h +++ b/Telegram/SourceFiles/app.h @@ -107,18 +107,23 @@ namespace App { QString onlineText(UserData *user, int32 nowOnServer, bool precise = false); bool onlineColorUse(UserData *user, int32 now); - UserData *feedUsers(const MTPVector &users); // returns last user - ChatData *feedChats(const MTPVector &chats); // returns last chat - void feedParticipants(const MTPChatParticipants &p, bool requestBotInfos = false); - void feedParticipantAdd(const MTPDupdateChatParticipantAdd &d); - void feedParticipantDelete(const MTPDupdateChatParticipantDelete &d); + UserData *feedUsers(const MTPVector &users, bool emitPeerUpdated = true); // returns last user + ChatData *feedChats(const MTPVector &chats, bool emitPeerUpdated = true); // returns last chat + void feedParticipants(const MTPChatParticipants &p, bool requestBotInfos, bool emitPeerUpdated = true); + void feedParticipantAdd(const MTPDupdateChatParticipantAdd &d, bool emitPeerUpdated = true); + void feedParticipantDelete(const MTPDupdateChatParticipantDelete &d, bool emitPeerUpdated = true); void feedMsgs(const MTPVector &msgs, int msgsState = 0); // 2 - new read message, 1 - new unread message, 0 - not new message, -1 - searched message void feedWereRead(const QVector &msgsIds); void feedInboxRead(const PeerId &peer, int32 upTo); void feedOutboxRead(const PeerId &peer, int32 upTo); void feedWereDeleted(const QVector &msgsIds); - void feedUserLinks(const MTPVector &links); - void feedUserLink(MTPint userId, const MTPContactLink &myLink, const MTPContactLink &foreignLink); + void feedUserLinks(const MTPVector &links, bool emitPeerUpdated = true); + void feedUserLink(MTPint userId, const MTPContactLink &myLink, const MTPContactLink &foreignLink, bool emitPeerUpdated = true); + + void markPeerUpdated(PeerData *data); + void clearPeerUpdated(PeerData *data); + void emitPeerUpdated(); + int32 maxMsgId(); ImagePtr image(const MTPPhotoSize &size); diff --git a/Telegram/SourceFiles/application.cpp b/Telegram/SourceFiles/application.cpp index 8f6494c37..8f0f6eee8 100644 --- a/Telegram/SourceFiles/application.cpp +++ b/Telegram/SourceFiles/application.cpp @@ -640,8 +640,8 @@ void Application::checkMapVersion() { psRegisterCustomScheme(); if (Local::oldMapVersion()) { QString versionFeatures; - if (DevChannel && Local::oldMapVersion() < 8034) { - versionFeatures = QString::fromUtf8("\xe2\x80\x94 Forward photos, media and stickers with drag-n-drop\n\xe2\x80\x94 Drag-n-drop text messages by timestamp to forward them\n\xe2\x80\x94 Larger stickers panel");// .replace('@', qsl("@") + QChar(0x200D)); + if (DevChannel && Local::oldMapVersion() < 8035) { + versionFeatures = lang(lng_new_version_minor);// QString::fromUtf8("\xe2\x80\x94 Forward photos, media and stickers with drag-n-drop\n\xe2\x80\x94 Drag-n-drop text messages by timestamp to forward them\n\xe2\x80\x94 Larger stickers panel");// .replace('@', qsl("@") + QChar(0x200D)); } else if (!DevChannel && Local::oldMapVersion() < 8030) { versionFeatures = lang(lng_new_version_text).trimmed(); } diff --git a/Telegram/SourceFiles/config.h b/Telegram/SourceFiles/config.h index edac8ac5d..eff06ad20 100644 --- a/Telegram/SourceFiles/config.h +++ b/Telegram/SourceFiles/config.h @@ -17,8 +17,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org */ #pragma once -static const int32 AppVersion = 8034; -static const wchar_t *AppVersionStr = L"0.8.34"; +static const int32 AppVersion = 8035; +static const wchar_t *AppVersionStr = L"0.8.35"; static const bool DevChannel = true; static const wchar_t *AppNameOld = L"Telegram Win (Unofficial)"; diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index 7766fcdcf..17ca869a3 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -5093,7 +5093,6 @@ void HistoryWidget::onCancel() { } void HistoryWidget::onFullPeerUpdated(PeerData *data) { - peerUpdated(data); if (_list && data == histPeer) { checkMentionDropdown(); _list->updateBotInfo(); diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index b7cbfbfcd..0dc1e01b8 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -369,6 +369,7 @@ _failDifferenceTimeout(1), _lastUpdateTime(0), _cachedX(0), _cachedY(0), _backgr connect(&_bySeqTimer, SIGNAL(timeout()), this, SLOT(getDifference())); connect(&_byPtsTimer, SIGNAL(timeout()), this, SLOT(getDifference())); connect(&_failDifferenceTimer, SIGNAL(timeout()), this, SLOT(getDifferenceForce())); + connect(_api, SIGNAL(fullPeerUpdated(PeerData*)), this, SIGNAL(peerUpdated(PeerData*))); connect(this, SIGNAL(peerUpdated(PeerData*)), &history, SLOT(peerUpdated(PeerData*))); connect(&_topBar, SIGNAL(clicked()), this, SLOT(onTopBarClick())); connect(&history, SIGNAL(peerShown(PeerData*)), this, SLOT(onPeerShown(PeerData*))); @@ -763,14 +764,16 @@ void MainWidget::deleteMessages(const QVector &ids) { void MainWidget::deletedContact(UserData *user, const MTPcontacts_Link &result) { const MTPDcontacts_link &d(result.c_contacts_link()); - App::feedUsers(MTP_vector(1, d.vuser)); - App::feedUserLink(MTP_int(user->id & 0xFFFFFFFF), d.vmy_link, d.vforeign_link); + App::feedUsers(MTP_vector(1, d.vuser), false); + App::feedUserLink(MTP_int(user->id & 0xFFFFFFFF), d.vmy_link, d.vforeign_link, false); + App::emitPeerUpdated(); } void MainWidget::deleteHistoryAndContact(UserData *user, const MTPcontacts_Link &result) { const MTPDcontacts_link &d(result.c_contacts_link()); - App::feedUsers(MTP_vector(1, d.vuser)); - App::feedUserLink(MTP_int(user->id & 0xFFFFFFFF), d.vmy_link, d.vforeign_link); + App::feedUsers(MTP_vector(1, d.vuser), false); + App::feedUserLink(MTP_int(user->id & 0xFFFFFFFF), d.vmy_link, d.vforeign_link, false); + App::emitPeerUpdated(); if ((profile && profile->peer() == user) || (overview && overview->peer() == user) || _stack.contains(user) || history.peer() == user) { showPeer(0); @@ -834,13 +837,13 @@ void MainWidget::checkedHistory(PeerData *peer, const MTPmessages_Messages &resu const QVector *v = 0; if (result.type() == mtpc_messages_messages) { const MTPDmessages_messages &d(result.c_messages_messages()); - App::feedChats(d.vchats); App::feedUsers(d.vusers); + App::feedChats(d.vchats); v = &d.vmessages.c_vector().v; } else if (result.type() == mtpc_messages_messagesSlice) { const MTPDmessages_messagesSlice &d(result.c_messages_messagesSlice()); - App::feedChats(d.vchats); App::feedUsers(d.vusers); + App::feedChats(d.vchats); v = &d.vmessages.c_vector().v; } if (!v) return; @@ -2090,6 +2093,7 @@ void MainWidget::sentDataReceived(uint64 randomId, const MTPmessages_SentMessage void MainWidget::sentUpdatesReceived(const MTPUpdates &result) { handleUpdates(result); + App::emitPeerUpdated(); } void MainWidget::msgUpdated(PeerId peer, const HistoryItem *msg) { @@ -2417,6 +2421,8 @@ void MainWidget::gotState(const MTPupdates_State &state) { dialogs.loadDialogs(); updateOnline(); + + App::emitPeerUpdated(); } void MainWidget::gotDifference(const MTPupdates_Difference &diff) { @@ -2432,6 +2438,8 @@ void MainWidget::gotDifference(const MTPupdates_Difference &diff) { noUpdatesTimer.start(NoUpdatesTimeout); updInited = true; + + App::emitPeerUpdated(); } break; case mtpc_updates_differenceSlice: { const MTPDupdates_differenceSlice &d(diff.c_updates_differenceSlice()); @@ -2444,6 +2452,8 @@ void MainWidget::gotDifference(const MTPupdates_Difference &diff) { MTP_LOG(0, ("getDifference { good - after a slice of difference was received }%1").arg(cTestMode() ? " TESTMODE" : "")); getDifference(); + + App::emitPeerUpdated(); } break; case mtpc_updates_difference: { const MTPDupdates_difference &d(diff.c_updates_difference()); @@ -2471,6 +2481,7 @@ void MainWidget::applySkippedPtsUpdates() { } --updSkipPtsUpdateLevel; clearSkippedPtsUpdates(); + App::emitPeerUpdated(); } void MainWidget::clearSkippedPtsUpdates() { @@ -2500,8 +2511,8 @@ bool MainWidget::updPtsUpdated(int pts, int ptsCount) { // return false if need void MainWidget::feedDifference(const MTPVector &users, const MTPVector &chats, const MTPVector &msgs, const MTPVector &other) { App::wnd()->checkAutoLock(); - App::feedUsers(users); - App::feedChats(chats); + App::feedUsers(users, false); + App::feedChats(chats, false); feedMessageIds(other); App::feedMsgs(msgs, 1); feedUpdates(other, true); @@ -3079,7 +3090,8 @@ void MainWidget::updateReceived(const mtpPrime *from, const mtpPrime *end) { noUpdatesTimer.start(NoUpdatesTimeout); handleUpdates(updates); - } catch(mtpErrorUnexpected &e) { // just some other type + App::emitPeerUpdated(); + } catch (mtpErrorUnexpected &e) { // just some other type } } update(); @@ -3097,8 +3109,8 @@ void MainWidget::handleUpdates(const MTPUpdates &updates) { } } - App::feedChats(d.vchats); - App::feedUsers(d.vusers); + App::feedUsers(d.vusers, false); + App::feedChats(d.vchats, false); feedUpdates(d.vupdates); updSetState(0, d.vdate.v, updQts, d.vseq.v); @@ -3114,8 +3126,8 @@ void MainWidget::handleUpdates(const MTPUpdates &updates) { } } - App::feedChats(d.vchats); - App::feedUsers(d.vusers); + App::feedUsers(d.vusers, false); + App::feedChats(d.vchats, false); feedUpdates(d.vupdates); updSetState(0, d.vdate.v, updQts, d.vseq.v); @@ -3308,17 +3320,17 @@ void MainWidget::feedUpdate(const MTPUpdate &update) { case mtpc_updateChatParticipants: { const MTPDupdateChatParticipants &d(update.c_updateChatParticipants()); - App::feedParticipants(d.vparticipants, true); + App::feedParticipants(d.vparticipants, true, false); } break; case mtpc_updateChatParticipantAdd: { const MTPDupdateChatParticipantAdd &d(update.c_updateChatParticipantAdd()); - App::feedParticipantAdd(d); + App::feedParticipantAdd(d, false); } break; case mtpc_updateChatParticipantDelete: { const MTPDupdateChatParticipantDelete &d(update.c_updateChatParticipantDelete()); - App::feedParticipantDelete(d); + App::feedParticipantDelete(d, false); } break; case mtpc_updateUserStatus: { @@ -3337,7 +3349,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) { case mtpc_userStatusOffline: user->onlineTill = d.vstatus.c_userStatusOffline().vwas_online.v; break; case mtpc_userStatusOnline: user->onlineTill = d.vstatus.c_userStatusOnline().vexpires.v; break; } - if (App::main()) App::main()->peerUpdated(user); + App::markPeerUpdated(user); } if (d.vuser_id.v == MTP::authedId()) { if (d.vstatus.type() == mtpc_userStatusOffline || d.vstatus.type() == mtpc_userStatusEmpty) { @@ -3360,7 +3372,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) { } else { user->setName(textOneLine(user->firstName), textOneLine(user->lastName), user->nameOrPhone, textOneLine(qs(d.vusername))); } - if (App::main()) App::main()->peerUpdated(user); + App::markPeerUpdated(user); } } break; @@ -3374,7 +3386,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) { user->photosCount = -1; user->photos.clear(); } else { - if (user->photoId) { + if (user->photoId && user->photoId != UnknownPeerPhotoId) { if (user->photosCount > 0) ++user->photosCount; user->photos.push_front(App::photo(user->photoId)); } else { @@ -3382,7 +3394,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) { user->photos.clear(); } } - if (App::main()) App::main()->peerUpdated(user); + App::markPeerUpdated(user); if (App::wnd()) App::wnd()->mediaOverviewUpdated(user); } } break; @@ -3399,7 +3411,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) { case mtpc_updateContactLink: { const MTPDupdateContactLink &d(update.c_updateContactLink()); - App::feedUserLink(d.vuser_id, d.vmy_link, d.vforeign_link); + App::feedUserLink(d.vuser_id, d.vmy_link, d.vforeign_link, false); } break; case mtpc_updateNotifySettings: { @@ -3418,7 +3430,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) { if (user) { user->setPhone(qs(d.vphone)); user->setName(user->firstName, user->lastName, (user->contact || isServiceUser(user->id) || user->phone.isEmpty()) ? QString() : App::formatPhone(user->phone), user->username); - if (App::main()) App::main()->peerUpdated(user); + App::markPeerUpdated(user); } } break; diff --git a/Telegram/SourceFiles/mediaview.cpp b/Telegram/SourceFiles/mediaview.cpp index 5ff944ea0..7f1d02ab5 100644 --- a/Telegram/SourceFiles/mediaview.cpp +++ b/Telegram/SourceFiles/mediaview.cpp @@ -682,7 +682,7 @@ void MediaView::showPhoto(PhotoData *photo, PeerData *context) { _photo = photo; _overview = OverviewCount; if (_user) { - if (_user->photos.isEmpty() && _user->photosCount < 0 && _user->photoId) { + if (_user->photos.isEmpty() && _user->photosCount < 0 && _user->photoId && _user->photoId != UnknownPeerPhotoId) { _index = 0; } for (int i = 0, l = _user->photos.size(); i < l; ++i) { diff --git a/Telegram/SourceFiles/profilewidget.cpp b/Telegram/SourceFiles/profilewidget.cpp index 983368798..8581d072b 100644 --- a/Telegram/SourceFiles/profilewidget.cpp +++ b/Telegram/SourceFiles/profilewidget.cpp @@ -77,14 +77,21 @@ ProfileInner::ProfileInner(ProfileWidget *profile, ScrollArea *scroll, const Pee if (_peerUser) { _phoneText = _peerUser->phone.isEmpty() ? QString() : App::formatPhone(_peerUser->phone); - App::api()->requestFullPeer(_peer); - } else if (_peerChat->photoId) { - PhotoData *ph = App::photo(_peerChat->photoId); - if (ph->date) { - _photoLink = TextLinkPtr(new PhotoLink(ph, _peer)); + PhotoData *userPhoto = (_peerUser->photoId && _peerUser->photoId != UnknownPeerPhotoId) ? App::photo(_peerUser->photoId) : 0; + if (userPhoto && userPhoto->date) { + _photoLink = TextLinkPtr(new PhotoLink(userPhoto, _peer)); + } + if ((_peerUser->botInfo && !_peerUser->botInfo->inited) || (_peerUser->photoId == UnknownPeerPhotoId) || (_peerUser->photoId && !userPhoto->date)) { + App::api()->requestFullPeer(_peer); } } else { - App::api()->requestFullPeer(_peer); + PhotoData *chatPhoto = (_peerChat->photoId && _peerChat->photoId != UnknownPeerPhotoId) ? App::photo(_peerChat->photoId) : 0; + if (chatPhoto && chatPhoto->date) { + _photoLink = TextLinkPtr(new PhotoLink(chatPhoto, _peer)); + } + if (_peerChat->photoId == UnknownPeerPhotoId) { + App::api()->requestFullPeer(_peer); + } } // profile @@ -325,7 +332,7 @@ void ProfileInner::chatInviteDone(const MTPExportedChatInvite &result) { void ProfileInner::onFullPeerUpdated(PeerData *peer) { if (peer != _peer) return; if (_peerUser) { - PhotoData *userPhoto = _peerUser->photoId ? App::photo(_peerUser->photoId) : 0; + PhotoData *userPhoto = (_peerUser->photoId && _peerUser->photoId != UnknownPeerPhotoId) ? App::photo(_peerUser->photoId) : 0; if (userPhoto && userPhoto->date) { _photoLink = TextLinkPtr(new PhotoLink(userPhoto, _peer)); } else { @@ -376,9 +383,9 @@ void ProfileInner::peerUpdated(PeerData *data) { PhotoData *photo = 0; if (_peerUser) { _phoneText = _peerUser->phone.isEmpty() ? QString() : App::formatPhone(_peerUser->phone); - if (_peerUser->photoId) photo = App::photo(_peerUser->photoId); + if (_peerUser->photoId && _peerUser->photoId != UnknownPeerPhotoId) photo = App::photo(_peerUser->photoId); } else { - if (_peerChat->photoId) photo = App::photo(_peerChat->photoId); + if (_peerChat->photoId && _peerChat->photoId != UnknownPeerPhotoId) photo = App::photo(_peerChat->photoId); } _photoLink = (photo && photo->date) ? TextLinkPtr(new PhotoLink(photo, _peer)) : TextLinkPtr(); if (_peer->name != _nameCache) { diff --git a/Telegram/SourceFiles/settingswidget.cpp b/Telegram/SourceFiles/settingswidget.cpp index 48a828e56..6a6cad5be 100644 --- a/Telegram/SourceFiles/settingswidget.cpp +++ b/Telegram/SourceFiles/settingswidget.cpp @@ -190,7 +190,7 @@ SettingsInner::SettingsInner(SettingsWidget *parent) : QWidget(parent), { if (self()) { _nameText.setText(st::setNameFont, _nameCache, _textNameOptions); - PhotoData *selfPhoto = self()->photoId ? App::photo(self()->photoId) : 0; + PhotoData *selfPhoto = (self()->photoId && self()->photoId != UnknownPeerPhotoId) ? App::photo(self()->photoId) : 0; if (selfPhoto && selfPhoto->date) _photoLink = TextLinkPtr(new PhotoLink(selfPhoto, self())); MTP::send(MTPusers_GetFullUser(self()->inputUser), rpcDone(&SettingsInner::gotFullSelf), RPCFailHandlerPtr(), 0, 10); onReloadPassword(); @@ -312,7 +312,7 @@ SettingsInner::SettingsInner(SettingsWidget *parent) : QWidget(parent), void SettingsInner::peerUpdated(PeerData *data) { if (self() && data == self()) { - if (self()->photoId) { + if (self()->photoId && self()->photoId != UnknownPeerPhotoId) { PhotoData *selfPhoto = App::photo(self()->photoId); if (selfPhoto->date) { _photoLink = TextLinkPtr(new PhotoLink(selfPhoto, self())); @@ -851,7 +851,7 @@ void SettingsInner::gotFullSelf(const MTPUserFull &selfFull) { if (!self()) return; App::feedPhoto(selfFull.c_userFull().vprofile_photo); App::feedUsers(MTP_vector(1, selfFull.c_userFull().vuser)); - PhotoData *selfPhoto = self()->photoId ? App::photo(self()->photoId) : 0; + PhotoData *selfPhoto = (self()->photoId && self()->photoId != UnknownPeerPhotoId) ? App::photo(self()->photoId) : 0; if (selfPhoto && selfPhoto->date) { _photoLink = TextLinkPtr(new PhotoLink(selfPhoto, self())); } else { diff --git a/Telegram/SourceFiles/structs.cpp b/Telegram/SourceFiles/structs.cpp index 5ffc01f14..fd4a9865f 100644 --- a/Telegram/SourceFiles/structs.cpp +++ b/Telegram/SourceFiles/structs.cpp @@ -133,23 +133,31 @@ void PeerData::updateName(const QString &newName, const QString &newNameOrPhone, } void UserData::setPhoto(const MTPUserProfilePhoto &p) { + PhotoId newPhotoId = photoId; + ImagePtr newPhoto = photo; switch (p.type()) { case mtpc_userProfilePhoto: { const MTPDuserProfilePhoto d(p.c_userProfilePhoto()); - photoId = d.vphoto_id.v; - photo = ImagePtr(160, 160, d.vphoto_small, userDefPhoto(colorIndex)); - // App::feedPhoto(App::photoFromUserPhoto(MTP_int(id & 0xFFFFFFFF), MTP_int(unixtime()), p)); + newPhotoId = d.vphoto_id.v; + newPhoto = ImagePtr(160, 160, d.vphoto_small, userDefPhoto(colorIndex)); + //App::feedPhoto(App::photoFromUserPhoto(MTP_int(id & 0xFFFFFFFF), MTP_int(unixtime()), p)); } break; default: { - photoId = 0; + newPhotoId = 0; if (id == ServiceUserId) { - photo = ImagePtr(QPixmap::fromImage(App::wnd()->iconLarge().scaledToWidth(160, Qt::SmoothTransformation), Qt::ColorOnly), "PNG"); + if (photo->isNull()) { + newPhoto = ImagePtr(QPixmap::fromImage(App::wnd()->iconLarge().scaledToWidth(160, Qt::SmoothTransformation), Qt::ColorOnly), "PNG"); + } } else { - photo = userDefPhoto(colorIndex); + newPhoto = userDefPhoto(colorIndex); } } break; } - emit App::main()->peerPhotoChanged(this); + if (newPhotoId != photoId || newPhoto.v() != photo.v()) { + photoId = newPhotoId; + photo = newPhoto; + emit App::main()->peerPhotoChanged(this); + } } void PeerData::fillNames() { @@ -262,10 +270,10 @@ void UserData::madeAction() { int32 t = unixtime(); if (onlineTill <= 0 && -onlineTill < t) { onlineTill = -t - SetOnlineAfterActivity; - if (App::main()) App::main()->peerUpdated(this); + App::markPeerUpdated(this); } else if (onlineTill > 0 && onlineTill < t + 1) { onlineTill = t + SetOnlineAfterActivity; - if (App::main()) App::main()->peerUpdated(this); + App::markPeerUpdated(this); } } @@ -275,7 +283,7 @@ void ChatData::setPhoto(const MTPChatPhoto &p, const PhotoId &phId) { const MTPDchatPhoto d(p.c_chatPhoto()); photo = ImagePtr(160, 160, d.vphoto_small, chatDefPhoto(colorIndex)); photoFull = ImagePtr(640, 640, d.vphoto_big, chatDefPhoto(colorIndex)); - if (phId) { + if (phId != UnknownPeerPhotoId) { photoId = phId; } } break; diff --git a/Telegram/SourceFiles/structs.h b/Telegram/SourceFiles/structs.h index 8df51561e..15d798796 100644 --- a/Telegram/SourceFiles/structs.h +++ b/Telegram/SourceFiles/structs.h @@ -138,9 +138,11 @@ struct BotInfo { QString startToken, startGroupToken; }; +static const PhotoId UnknownPeerPhotoId = 0xFFFFFFFFFFFFFFFFULL; + struct PhotoData; struct UserData : public PeerData { - UserData(const PeerId &id) : PeerData(id), photoId(0), lnk(new PeerLink(this)), onlineTill(0), contact(-1), photosCount(-1), botInfo(0) { + UserData(const PeerId &id) : PeerData(id), photoId(UnknownPeerPhotoId), lnk(new PeerLink(this)), onlineTill(0), contact(-1), photosCount(-1), botInfo(0) { } void setPhoto(const MTPUserProfilePhoto &photo); void setName(const QString &first, const QString &last, const QString &phoneName, const QString &username); @@ -169,9 +171,9 @@ struct UserData : public PeerData { }; struct ChatData : public PeerData { - ChatData(const PeerId &id) : PeerData(id), count(0), date(0), version(0), left(false), forbidden(true), botStatus(0), photoId(0) { + ChatData(const PeerId &id) : PeerData(id), count(0), date(0), version(0), left(false), forbidden(true), botStatus(0), photoId(UnknownPeerPhotoId) { } - void setPhoto(const MTPChatPhoto &photo, const PhotoId &phId = 0); + void setPhoto(const MTPChatPhoto &photo, const PhotoId &phId = UnknownPeerPhotoId); int32 count; int32 date; int32 version; diff --git a/Telegram/Telegram.plist b/Telegram/Telegram.plist index d5e5a1859..1184d694e 100644 --- a/Telegram/Telegram.plist +++ b/Telegram/Telegram.plist @@ -11,7 +11,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.8.34 + 0.8.35 LSMinimumSystemVersion $(MACOSX_DEPLOYMENT_TARGET) CFBundleSignature diff --git a/Telegram/Telegram.rc b/Telegram/Telegram.rc index 26abef2e6..2f8225ec3 100644 Binary files a/Telegram/Telegram.rc and b/Telegram/Telegram.rc differ diff --git a/Telegram/Telegram.xcodeproj/project.pbxproj b/Telegram/Telegram.xcodeproj/project.pbxproj index ee58b04b3..d761b2b57 100644 --- a/Telegram/Telegram.xcodeproj/project.pbxproj +++ b/Telegram/Telegram.xcodeproj/project.pbxproj @@ -1701,7 +1701,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 0.8.34; + CURRENT_PROJECT_VERSION = 0.8.35; DEBUG_INFORMATION_FORMAT = dwarf; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; @@ -1719,7 +1719,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; COPY_PHASE_STRIP = YES; - CURRENT_PROJECT_VERSION = 0.8.34; + CURRENT_PROJECT_VERSION = 0.8.35; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_OPTIMIZATION_LEVEL = fast; GCC_PREFIX_HEADER = ./SourceFiles/stdafx.h; @@ -1745,10 +1745,10 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = ""; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 0.8.34; + CURRENT_PROJECT_VERSION = 0.8.35; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DYLIB_COMPATIBILITY_VERSION = 0.8; - DYLIB_CURRENT_VERSION = 0.8.34; + DYLIB_CURRENT_VERSION = 0.8.35; ENABLE_STRICT_OBJC_MSGSEND = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; @@ -1888,10 +1888,10 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = ""; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 0.8.34; + CURRENT_PROJECT_VERSION = 0.8.35; DEBUG_INFORMATION_FORMAT = dwarf; DYLIB_COMPATIBILITY_VERSION = 0.8; - DYLIB_CURRENT_VERSION = 0.8.34; + DYLIB_CURRENT_VERSION = 0.8.35; ENABLE_STRICT_OBJC_MSGSEND = YES; FRAMEWORK_SEARCH_PATHS = ""; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; diff --git a/Telegram/Version.sh b/Telegram/Version.sh index 83edfcf15..473ccc404 100755 --- a/Telegram/Version.sh +++ b/Telegram/Version.sh @@ -1,2 +1,2 @@ -echo 0.8 8034 0.8.34 1 +echo 0.8 8035 0.8.35 1 # AppVersionStrMajor AppVersion AppVersionStr DevChannel