From c45d9e9860a164e09884b7fb280f130502490125 Mon Sep 17 00:00:00 2001 From: John Preston Date: Mon, 7 Sep 2015 18:53:46 +0300 Subject: [PATCH] fixed crash in showNextNotify, started reportspam button --- Telegram/SourceFiles/app.cpp | 15 +++++- Telegram/SourceFiles/dialogswidget.cpp | 3 +- Telegram/SourceFiles/historywidget.cpp | 73 ++++++++++++++++++++++++++ Telegram/SourceFiles/historywidget.h | 10 ++++ Telegram/SourceFiles/localstorage.cpp | 4 ++ Telegram/SourceFiles/localstorage.h | 2 + Telegram/SourceFiles/mainwidget.cpp | 4 ++ Telegram/SourceFiles/mainwidget.h | 2 + Telegram/SourceFiles/settings.cpp | 3 ++ Telegram/SourceFiles/settings.h | 4 ++ Telegram/SourceFiles/structs.h | 3 +- Telegram/SourceFiles/window.cpp | 8 +-- 12 files changed, 123 insertions(+), 8 deletions(-) diff --git a/Telegram/SourceFiles/app.cpp b/Telegram/SourceFiles/app.cpp index 3c0016f48..7d9385d53 100644 --- a/Telegram/SourceFiles/app.cpp +++ b/Telegram/SourceFiles/app.cpp @@ -566,10 +566,17 @@ namespace App { int32 pversion = chat->participants.isEmpty() ? 1 : (chat->participants.begin().value() + 1); chat->cankick = ChatData::CanKick(); for (QVector::const_iterator i = v.cbegin(), e = v.cend(); i != e; ++i) { - UserData *user = App::userLoaded(i->c_chatParticipant().vuser_id.v); + if (i->type() != mtpc_chatParticipant) continue; + + const MTPDchatParticipant &p(i->c_chatParticipant()); + //if (p.vuser_id.v == MTP::authedId()) { + // chat->inviter = p.vinviter_id.v; // we use inviter only from service msgs + // chat->inviteDate = p.vdate.v; + //} + UserData *user = App::userLoaded(p.vuser_id.v); if (user) { chat->participants[user] = pversion; - if (i->c_chatParticipant().vinviter_id.v == MTP::authedId()) { + if (p.vinviter_id.v == MTP::authedId()) { chat->cankick[user] = true; } } else { @@ -619,6 +626,10 @@ namespace App { ChatData *chat = App::chat(d.vchat_id.v); if (chat->version <= d.vversion.v && chat->count >= 0) { chat->version = d.vversion.v; + //if (d.vuser_id.v == MTP::authedId()) { + // chat->inviter = d.vinviter_id.v; // we use inviter only from service msgs + // chat->inviteDate = unixtime(); // no event date here :( + //} UserData *user = App::userLoaded(d.vuser_id.v); if (user) { if (chat->participants.isEmpty() && chat->count) { diff --git a/Telegram/SourceFiles/dialogswidget.cpp b/Telegram/SourceFiles/dialogswidget.cpp index 58ef6fc7e..8f1b50c39 100644 --- a/Telegram/SourceFiles/dialogswidget.cpp +++ b/Telegram/SourceFiles/dialogswidget.cpp @@ -814,7 +814,6 @@ void DialogsListWidget::peopleReceived(const QString &query, const QVector &contacts) { - cSetContactsReceived(true); for (QVector::const_iterator i = contacts.cbegin(), e = contacts.cend(); i != e; ++i) { int32 uid = i->c_contact().vuser_id.v; addNewContact(uid); @@ -1739,11 +1738,13 @@ void DialogsWidget::loadDialogs() { } void DialogsWidget::contactsReceived(const MTPcontacts_Contacts &contacts) { + cSetContactsReceived(true); if (contacts.type() == mtpc_contacts_contacts) { const MTPDcontacts_contacts &d(contacts.c_contacts_contacts()); App::feedUsers(d.vusers); list.contactsReceived(d.vcontacts.c_vector().v); } + if (App::main()) App::main()->contactsReceived(); } bool DialogsWidget::contactsFailed(const RPCError &error) { diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index 614eb4d68..64b8e57d7 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -2198,6 +2198,7 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent) , _replyTo(0) , _replyToNameVersion(0) , _replyForwardPreviewCancel(this, st::replyCancel) +, _reportSpamStatus(ReportSpamUnknown) , _previewData(0) , _previewRequest(0) , _previewCancelled(false) @@ -2905,6 +2906,76 @@ void HistoryWidget::clearAllLoadRequests() { _preloadRequest = _preloadDownRequest = _firstLoadRequest = 0; } +void HistoryWidget::contactsReceived() { + if (!_peer) return; + updateReportSpamStatus(); + updateControlsVisibility(); +} + +void HistoryWidget::updateReportSpamStatus() { + if (!_peer || cNoReportSpamButton().contains(_peer->id)) { + _reportSpamStatus = ReportSpamNoButton; + return; + } else if (cShowReportSpamButton().contains(_peer->id)) { + _reportSpamStatus = ReportSpamShowButton; + return; + } + if (!cContactsReceived()) { + _reportSpamStatus = ReportSpamUnknown; + } else if (_peer->chat) { + if (_firstLoadRequest && !_peer->asChat()->inviterForSpamReport) { + _reportSpamStatus = ReportSpamUnknown; + } else if (_peer->asChat()->inviterForSpamReport > 0) { + UserData *user = App::userLoaded(_peer->asChat()->inviterForSpamReport); + if (user && user->contact > 0) { + _reportSpamStatus = ReportSpamNoButton; + } else { + _reportSpamStatus = ReportSpamShowButton; + } + } else { + _reportSpamStatus = ReportSpamNoButton; + } + } else { + if (_peer->asUser()->contact > 0) { + _reportSpamStatus = ReportSpamNoButton; + } else { + if (_firstLoadRequest) { + _reportSpamStatus = ReportSpamUnknown; + } else { + bool anyFound = false, outFound = false; + for (int32 i = 0, l = _history->size(); i < l; ++i) { + for (int32 j = 0, c = _history->at(i)->size(); j < c; ++j) { + anyFound = true; + if (_history->at(i)->at(j)->out()) { + outFound = true; + break; + } + } + } + if (anyFound) { + if (outFound) { + _reportSpamStatus = ReportSpamNoButton; + } else { + _reportSpamStatus = ReportSpamShowButton; + } + } else { + _reportSpamStatus = ReportSpamUnknown; + } + } + } + } + if (_reportSpamStatus == ReportSpamShowButton || _reportSpamStatus == ReportSpamNoButton) { + if (_reportSpamStatus == ReportSpamShowButton) { + cRefNoReportSpamButton().remove(_peer->id); + cRefShowReportSpamButton().insert(_peer->id, true); + } else { + cRefNoReportSpamButton().insert(_peer->id, true); + cRefShowReportSpamButton().remove(_peer->id); + } + Local::writeReportSpamStatuses(); + } +} + void HistoryWidget::updateControlsVisibility() { if (!_history || _showAnim.animating()) { _scroll.hide(); @@ -3519,6 +3590,7 @@ bool HistoryWidget::showStep(float64 ms) { } void HistoryWidget::doneShow() { + updateReportSpamStatus(); updateBotKeyboard(); updateControlsVisibility(); updateListSize(0, true); @@ -5167,6 +5239,7 @@ void HistoryWidget::onFullPeerUpdated(PeerData *data) { int32 newScrollTop = _scroll.scrollTop(); if (_list && data == _peer) { checkMentionDropdown(); + updateReportSpamStatus(); int32 lh = _list->height(), st = _scroll.scrollTop(); _list->updateBotInfo(); newScrollTop = st + _list->height() - lh; diff --git a/Telegram/SourceFiles/historywidget.h b/Telegram/SourceFiles/historywidget.h index 0ce5c0c81..2e4d9a994 100644 --- a/Telegram/SourceFiles/historywidget.h +++ b/Telegram/SourceFiles/historywidget.h @@ -478,6 +478,8 @@ public: void clearDelayedShowAt(); void clearAllLoadRequests(); + void contactsReceived(); + ~HistoryWidget(); signals: @@ -585,6 +587,14 @@ private: void drawRecording(Painter &p); void updateField(); + enum ReportSpamStatus { + ReportSpamNoButton, + ReportSpamUnknown, + ReportSpamShowButton, + }; + ReportSpamStatus _reportSpamStatus; + void updateReportSpamStatus(); + QString _previewLinks; WebPageData *_previewData; typedef QMap PreviewCache; diff --git a/Telegram/SourceFiles/localstorage.cpp b/Telegram/SourceFiles/localstorage.cpp index abb7952db..56fab4908 100644 --- a/Telegram/SourceFiles/localstorage.cpp +++ b/Telegram/SourceFiles/localstorage.cpp @@ -2944,6 +2944,10 @@ namespace Local { } } + void writeReportSpamStatuses() { + + } + struct ClearManagerData { QThread *thread; StorageMap images, stickers, audios; diff --git a/Telegram/SourceFiles/localstorage.h b/Telegram/SourceFiles/localstorage.h index 11b3f3871..5b20a3f7a 100644 --- a/Telegram/SourceFiles/localstorage.h +++ b/Telegram/SourceFiles/localstorage.h @@ -147,4 +147,6 @@ namespace Local { void removeSavedPeer(PeerData *peer); void readSavedPeers(); + void writeReportSpamStatuses(); + }; diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 8e273cf68..71aee84fc 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -1967,6 +1967,10 @@ void MainWidget::clearBotStartToken(PeerData *peer) { } } +void MainWidget::contactsReceived() { + history.contactsReceived(); +} + void MainWidget::showPeerHistory(quint64 peerId, qint32 showAtMsgId, bool back) { if (!back && (!peerId || (_stack.size() == 1 && _stack[0]->type() == HistoryStackItem && _stack[0]->peer->id == peerId))) { back = true; diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index 8279caf12..f055081be 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -377,6 +377,8 @@ public: void choosePeer(PeerId peerId, MsgId showAtMsgId); // does offerPeer or showPeerHistory void clearBotStartToken(PeerData *peer); + void contactsReceived(); + ~MainWidget(); signals: diff --git a/Telegram/SourceFiles/settings.cpp b/Telegram/SourceFiles/settings.cpp index 78790d5f0..0e3a122b1 100644 --- a/Telegram/SourceFiles/settings.cpp +++ b/Telegram/SourceFiles/settings.cpp @@ -160,6 +160,9 @@ float64 gSongVolume = 0.9; SavedPeers gSavedPeers; SavedPeersByTime gSavedPeersByTime; +ReportSpamButtons gShowReportSpamButton; +ReportSpamButtons gNoReportSpamButton; + void settingsParseArgs(int argc, char *argv[]) { #ifdef Q_OS_MAC if (QSysInfo::macVersion() < QSysInfo::MV_10_8) { diff --git a/Telegram/SourceFiles/settings.h b/Telegram/SourceFiles/settings.h index ad36a2b1b..a138d0cb2 100644 --- a/Telegram/SourceFiles/settings.h +++ b/Telegram/SourceFiles/settings.h @@ -317,4 +317,8 @@ typedef QMultiMap SavedPeersByTime; DeclareRefSetting(SavedPeers, SavedPeers); DeclareRefSetting(SavedPeersByTime, SavedPeersByTime); +typedef QMap ReportSpamButtons; +DeclareRefSetting(ReportSpamButtons, ShowReportSpamButton); +DeclareRefSetting(ReportSpamButtons, NoReportSpamButton); + void settingsParseArgs(int argc, char *argv[]); diff --git a/Telegram/SourceFiles/structs.h b/Telegram/SourceFiles/structs.h index 32efe1053..5a509c960 100644 --- a/Telegram/SourceFiles/structs.h +++ b/Telegram/SourceFiles/structs.h @@ -208,13 +208,14 @@ 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) { + ChatData(const PeerId &id) : PeerData(id), count(0), date(0), version(0), inviterForSpamReport(0), left(false), forbidden(true), botStatus(0) { } void setPhoto(const MTPChatPhoto &photo, const PhotoId &phId = UnknownPeerPhotoId); int32 count; int32 date; int32 version; int32 admin; + int32 inviterForSpamReport; // > 0 - user who invited me to chat in unread service msg, < 0 - have outgoing message bool left; bool forbidden; typedef QMap Participants; diff --git a/Telegram/SourceFiles/window.cpp b/Telegram/SourceFiles/window.cpp index 8f18cfda6..13931cea0 100644 --- a/Telegram/SourceFiles/window.cpp +++ b/Telegram/SourceFiles/window.cpp @@ -1418,7 +1418,7 @@ void Window::notifyShowNext(NotifyWindow *remove) { HistoryItem *notifyItem = 0; History *notifyHistory = 0; NotifyWaiters::iterator notifyWaiter = notifyWaiters.end(); - for (NotifyWaiters::iterator i = notifyWaiters.begin(); i != notifyWaiters.end(); ++i) { + for (NotifyWaiters::iterator i = notifyWaiters.begin(); i != notifyWaiters.end();) { History *history = i.key(); if (history->currentNotification() && history->currentNotification()->id != i.value().msg) { NotifyWhenMaps::iterator j = notifyWhenMaps.find(history); @@ -1451,6 +1451,7 @@ void Window::notifyShowNext(NotifyWindow *remove) { notifyHistory = history; notifyWaiter = i; } + ++i; } if (notifyItem) { if (next > ms) { @@ -1467,8 +1468,7 @@ void Window::notifyShowNext(NotifyWindow *remove) { uint64 ms = getms(true); History *history = notifyItem->history(); NotifyWhenMaps::iterator j = notifyWhenMaps.find(history); - bool notifyWhenFound = (j != notifyWhenMaps.cend()); - if (!notifyWhenFound) { + if (j == notifyWhenMaps.cend()) { history->clearNotifications(); } else { HistoryItem *nextNotify = 0; @@ -1516,7 +1516,7 @@ void Window::notifyShowNext(NotifyWindow *remove) { if (!history->hasNotification()) { if (notifyWaiter != notifyWaiters.cend()) notifyWaiters.erase(notifyWaiter); - if (notifyWhenFound) notifyWhenMaps.erase(j); + notifyWhenMaps.remove(history); continue; } }