From dd8c526fb776486f83a9f00da8e07ceda41f1521 Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 21 Mar 2019 16:07:32 +0400 Subject: [PATCH] Prepare code for revoking of full history. --- Telegram/SourceFiles/apiwrap.cpp | 70 +++++++++++--- Telegram/SourceFiles/apiwrap.h | 7 +- Telegram/SourceFiles/boxes/confirm_box.h | 1 + .../boxes/peers/edit_peer_info_box.cpp | 2 +- Telegram/SourceFiles/history/history.cpp | 2 +- .../SourceFiles/history/history_widget.cpp | 13 +-- Telegram/SourceFiles/mainwidget.cpp | 91 ------------------- Telegram/SourceFiles/mainwidget.h | 9 -- .../SourceFiles/window/window_peer_menu.cpp | 78 ++++++++-------- 9 files changed, 111 insertions(+), 162 deletions(-) diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index 70aa20ed3..38dfb5b10 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -2335,7 +2335,7 @@ int ApiWrap::OnlineTillFromStatus( Unexpected("Bad UserStatus type."); } -void ApiWrap::clearHistory(not_null peer) { +void ApiWrap::clearHistory(not_null peer, bool revoke) { auto deleteTillId = MsgId(0); if (const auto history = _session->data().historyLoaded(peer)) { if (const auto last = history->lastMessage()) { @@ -2349,7 +2349,7 @@ void ApiWrap::clearHistory(not_null peer) { } if (const auto channel = peer->asChannel()) { if (const auto migrated = peer->migrateFrom()) { - clearHistory(migrated); + clearHistory(migrated, revoke); } if (IsServerMsgId(deleteTillId)) { request(MTPchannels_DeleteHistory( @@ -2358,19 +2358,65 @@ void ApiWrap::clearHistory(not_null peer) { )).send(); } } else { - request(MTPmessages_DeleteHistory( - MTP_flags(MTPmessages_DeleteHistory::Flag::f_just_clear), - peer->input, - MTP_int(0) - )).done([=](const MTPmessages_AffectedHistory &result) { - const auto offset = applyAffectedHistory(peer, result); - if (offset > 0) { - clearHistory(peer); - } - }).send(); + deleteHistory(peer, true, revoke); } } +void ApiWrap::deleteConversation(not_null peer, bool revoke) { + if (const auto history = _session->data().historyLoaded(peer->id)) { + _session->data().setPinnedDialog(history, false); + App::main()->removeDialog(history); + history->clear(); + if (const auto channel = peer->asMegagroup()) { + channel->addFlags(MTPDchannel::Flag::f_left); + if (const auto from = channel->getMigrateFromChat()) { + if (const auto migrated = _session->data().historyLoaded(from)) { + migrated->updateChatListExistence(); + } + } + } else { + history->markFullyLoaded(); + } + } + if (const auto chat = peer->asChat()) { + request(MTPmessages_DeleteChatUser( + chat->inputChat, + _session->user()->inputUser + )).done([=](const MTPUpdates &updates) { + applyUpdates(updates); + deleteHistory(peer, false, revoke); + }).fail([=](const RPCError &error) { + deleteHistory(peer, false, revoke); + }).send(); + return; + } else if (const auto channel = peer->asChannel()) { + channel->ptsWaitingForShortPoll(-1); + leaveChannel(channel); + } else { + deleteHistory(peer, false, revoke); + } +} + +void ApiWrap::deleteHistory(not_null peer, bool justClear, bool revoke) { + using Flag = MTPmessages_DeleteHistory::Flag; + const auto flags = Flag(0) + | (justClear ? Flag::f_just_clear : Flag(0)) + | ((peer->isUser() && revoke) ? Flag::f_revoke : Flag(0)); + request(MTPmessages_DeleteHistory( + MTP_flags(flags), + peer->input, + MTP_int(0) + )).done([=](const MTPmessages_AffectedHistory &result) { + const auto offset = applyAffectedHistory(peer, result); + if (offset > 0) { + deleteHistory(peer, justClear, revoke); + } else if (!justClear && cReportSpamStatuses().contains(peer->id)) { + cRefReportSpamStatuses().remove(peer->id); + Local::writeReportSpamStatuses(); + } + }).send(); +} + int ApiWrap::applyAffectedHistory( not_null peer, const MTPmessages_AffectedHistory &result) { diff --git a/Telegram/SourceFiles/apiwrap.h b/Telegram/SourceFiles/apiwrap.h index bb44fe8a0..d261a89df 100644 --- a/Telegram/SourceFiles/apiwrap.h +++ b/Telegram/SourceFiles/apiwrap.h @@ -211,7 +211,8 @@ public: const MTPUserStatus &status, int currentOnlineTill); - void clearHistory(not_null peer); + void clearHistory(not_null peer, bool revoke); + void deleteConversation(not_null peer, bool revoke); base::Observable &fullPeerUpdated() { return _fullPeerUpdated; @@ -540,6 +541,10 @@ private: UserId userId, const SendOptions &options); + void deleteHistory( + not_null peer, + bool justClear, + bool revoke); void sendReadRequest(not_null peer, MsgId upTo); int applyAffectedHistory( not_null peer, diff --git a/Telegram/SourceFiles/boxes/confirm_box.h b/Telegram/SourceFiles/boxes/confirm_box.h index 122d194c8..f041d8250 100644 --- a/Telegram/SourceFiles/boxes/confirm_box.h +++ b/Telegram/SourceFiles/boxes/confirm_box.h @@ -151,6 +151,7 @@ public: not_null item, bool suggestModerateActions); DeleteMessagesBox(QWidget*, MessageIdsList &&selected); + DeleteMessagesBox(QWidget*, not_null peer, bool deleteChat); void setDeleteConfirmedCallback(Fn callback) { _deleteConfirmedCallback = std::move(callback); diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp index b1a857dfc..5b2ca0552 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp @@ -1109,7 +1109,7 @@ void Controller::deleteChannel() { Ui::hideLayer(); Ui::showChatsList(); if (chat) { - App::main()->deleteAndExit(chat); + chat->session().api().deleteConversation(chat, false); } MTP::send( MTPchannels_DeleteChannel(channel->inputChannel), diff --git a/Telegram/SourceFiles/history/history.cpp b/Telegram/SourceFiles/history/history.cpp index cfcdebd9b..e84a82979 100644 --- a/Telegram/SourceFiles/history/history.cpp +++ b/Telegram/SourceFiles/history/history.cpp @@ -2411,7 +2411,7 @@ void History::dialogEntryApplied() { } } } else { - App::main()->deleteConversation(peer, false); + clear(); } return; } diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index d1f5aff98..6d87894b5 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -4473,16 +4473,11 @@ void HistoryWidget::onReportSpamClear() { Expects(_peer != nullptr); InvokeQueued(App::main(), [peer = _peer] { - if (peer->isUser()) { - App::main()->deleteConversation(peer); - } else if (auto chat = peer->asChat()) { - App::main()->deleteAndExit(chat); - } else if (auto channel = peer->asChannel()) { - if (channel->migrateFrom()) { - App::main()->deleteConversation(channel->migrateFrom()); - } - Auth().api().leaveChannel(channel); + Ui::showChatsList(); + if (const auto from = peer->migrateFrom()) { + peer->session().api().deleteConversation(from, false); } + peer->session().api().deleteConversation(peer, false); }); // Invalidates _peer. diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index b5d0199ac..660f80e47 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -899,45 +899,6 @@ void MainWidget::dialogsActivate() { _dialogs->activate(); } -bool MainWidget::leaveChatFailed(PeerData *peer, const RPCError &error) { - if (MTP::isDefaultHandledError(error)) return false; - - if (error.type() == qstr("USER_NOT_PARTICIPANT") || error.type() == qstr("CHAT_ID_INVALID") || error.type() == qstr("PEER_ID_INVALID")) { // left this chat already - deleteConversation(peer); - return true; - } - return false; -} - -void MainWidget::deleteHistoryAfterLeave(PeerData *peer, const MTPUpdates &updates) { - sentUpdatesReceived(updates); - deleteConversation(peer); -} - -void MainWidget::deleteHistoryPart(DeleteHistoryRequest request, const MTPmessages_AffectedHistory &result) { - auto peer = request.peer; - - auto &d = result.c_messages_affectedHistory(); - if (peer && peer->isChannel()) { - peer->asChannel()->ptsUpdateAndApply(d.vpts.v, d.vpts_count.v); - } else { - ptsUpdateAndApply(d.vpts.v, d.vpts_count.v); - } - - auto offset = d.voffset.v; - if (offset <= 0) { - cRefReportSpamStatuses().remove(peer->id); - Local::writeReportSpamStatuses(); - return; - } - - auto flags = MTPmessages_DeleteHistory::Flags(0); - if (request.justClearHistory) { - flags |= MTPmessages_DeleteHistory::Flag::f_just_clear; - } - MTP::send(MTPmessages_DeleteHistory(MTP_flags(flags), peer->input, MTP_int(0)), rpcDone(&MainWidget::deleteHistoryPart, request)); -} - void MainWidget::deleteMessages( not_null peer, const QVector &ids, @@ -958,62 +919,10 @@ void MainWidget::deleteMessages( } } -void MainWidget::deletedContact(UserData *user, const MTPcontacts_Link &result) { - auto &d(result.c_contacts_link()); - session().data().processUsers(MTP_vector(1, d.vuser)); - App::feedUserLink(MTP_int(peerToUser(user->id)), d.vmy_link, d.vforeign_link); -} - void MainWidget::removeDialog(Dialogs::Key key) { _dialogs->removeDialog(key); } -void MainWidget::deleteConversation( - not_null peer, - bool deleteHistory) { - if (_controller->activeChatCurrent().peer() == peer) { - Ui::showChatsList(); - } - if (const auto history = session().data().historyLoaded(peer->id)) { - session().data().setPinnedDialog(history, false); - removeDialog(history); - if (const auto channel = peer->asMegagroup()) { - channel->addFlags(MTPDchannel::Flag::f_left); - if (const auto from = channel->getMigrateFromChat()) { - if (const auto migrated = session().data().historyLoaded(from)) { - migrated->updateChatListExistence(); - } - } - } - history->clear(); - if (deleteHistory) { - history->markFullyLoaded(); - } - } - if (const auto channel = peer->asChannel()) { - channel->ptsWaitingForShortPoll(-1); - } - if (deleteHistory) { - DeleteHistoryRequest request = { peer, false }; - MTP::send( - MTPmessages_DeleteHistory( - MTP_flags(0), - peer->input, - MTP_int(0)), - rpcDone(&MainWidget::deleteHistoryPart, request)); - } -} - -void MainWidget::deleteAndExit(ChatData *chat) { - PeerData *peer = chat; - MTP::send( - MTPmessages_DeleteChatUser( - chat->inputChat, - session().user()->inputUser), - rpcDone(&MainWidget::deleteHistoryAfterLeave, peer), - rpcFail(&MainWidget::leaveChatFailed, peer)); -} - bool MainWidget::sendMessageFail(const RPCError &error) { if (MTP::isDefaultHandledError(error)) return false; diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index 70b153edd..a559631ff 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -195,17 +195,10 @@ public: void deletePhotoLayer(PhotoData *photo); - bool leaveChatFailed(PeerData *peer, const RPCError &e); - void deleteHistoryAfterLeave(PeerData *peer, const MTPUpdates &updates); void deleteMessages( not_null peer, const QVector &ids, bool revoke); - void deletedContact(UserData *user, const MTPcontacts_Link &result); - void deleteConversation( - not_null peer, - bool deleteHistory = true); - void deleteAndExit(ChatData *chat); bool sendMessageFail(const RPCError &error); @@ -416,8 +409,6 @@ private: // Doesn't call sendHistoryChangeNotifications itself. void feedUpdate(const MTPUpdate &update); - void deleteHistoryPart(DeleteHistoryRequest request, const MTPmessages_AffectedHistory &result); - void usernameResolveDone(QPair msgIdAndStartToken, const MTPcontacts_ResolvedPeer &result); bool usernameResolveFail(QString name, const RPCError &error); diff --git a/Telegram/SourceFiles/window/window_peer_menu.cpp b/Telegram/SourceFiles/window/window_peer_menu.cpp index e7dea0a9c..e28a4358c 100644 --- a/Telegram/SourceFiles/window/window_peer_menu.cpp +++ b/Telegram/SourceFiles/window/window_peer_menu.cpp @@ -570,22 +570,27 @@ void PeerMenuExportChat(not_null peer) { } void PeerMenuDeleteContact(not_null user) { - auto text = lng_sure_delete_contact( + const auto text = lng_sure_delete_contact( lt_contact, App::peerName(user)); - auto deleteSure = [=] { + const auto deleteSure = [=] { Ui::hideLayer(); - MTP::send( - MTPcontacts_DeleteContact(user->inputUser), - App::main()->rpcDone( - &MainWidget::deletedContact, - user.get())); + user->session().api().request(MTPcontacts_DeleteContact( + user->inputUser + )).done([=](const MTPcontacts_Link &result) { + result.match([&](const MTPDcontacts_link &data) { + user->owner().processUser(data.vuser); + App::feedUserLink( + MTP_int(peerToUser(user->id)), + data.vmy_link, + data.vforeign_link); + }); + }).send(); }; - auto box = Box( + Ui::show(Box( text, lang(lng_box_delete), - std::move(deleteSure)); - Ui::show(std::move(box)); + deleteSure)); } void PeerMenuAddContact(not_null user) { @@ -782,32 +787,33 @@ void PeerMenuAddMuteAction( //} Fn ClearHistoryHandler(not_null peer) { - return [peer] { - const auto weak = std::make_shared>(); + return [=] { + const auto weak = std::make_shared>(); const auto text = peer->isSelf() ? lang(lng_sure_delete_saved_messages) : peer->isUser() ? lng_sure_delete_history(lt_contact, peer->name) : lng_sure_delete_group_history(lt_group, peer->name); - auto callback = [=] { - if (auto strong = *weak) { + const auto callback = [=] { + if (const auto strong = *weak) { strong->closeBox(); } - Auth().api().clearHistory(peer); + peer->session().api().clearHistory(peer, false); }; *weak = Ui::show( Box( text, lang(lng_box_delete), st::attentionBoxButton, - std::move(callback)), + callback), LayerOption::KeepOther); }; } Fn DeleteAndLeaveHandler(not_null peer) { - return [peer] { - const auto warningText = peer->isSelf() + return [=] { + const auto weak = std::make_shared>(); + const auto text = peer->isSelf() ? lang(lng_sure_delete_saved_messages) : peer->isUser() ? lng_sure_delete_history(lt_contact, peer->name) @@ -816,38 +822,34 @@ Fn DeleteAndLeaveHandler(not_null peer) { : lang(peer->isMegagroup() ? lng_sure_leave_group : lng_sure_leave_channel); - const auto confirmText = lang(peer->isUser() + const auto confirm = lang(peer->isUser() ? lng_box_delete : lng_box_leave); const auto &confirmStyle = peer->isChannel() ? st::defaultBoxButton : st::attentionBoxButton; - auto callback = [peer] { - Ui::hideLayer(); + const auto callback = [=] { + if (const auto strong = *weak) { + strong->closeBox(); + } const auto controller = App::wnd()->controller(); if (controller->activeChatCurrent().peer() == peer) { Ui::showChatsList(); } - if (peer->isUser()) { - App::main()->deleteConversation(peer); - } else if (const auto chat = peer->asChat()) { - App::main()->deleteAndExit(chat); - } else if (const auto channel = peer->asChannel()) { - // Don't delete old history by default, - // because Android app doesn't. - // - //if (auto migrateFrom = channel->migrateFrom()) { - // App::main()->deleteConversation(migrateFrom); - //} - Auth().api().leaveChannel(channel); - } + // Don't delete old history by default, + // because Android app doesn't. + // + //if (const auto from = peer->migrateFrom()) { + // peer->session().api().deleteConversation(from, false); + //} + peer->session().api().deleteConversation(peer, false); }; - Ui::show( + *weak = Ui::show( Box( - warningText, - confirmText, + text, + confirm, confirmStyle, - std::move(callback)), + callback), LayerOption::KeepOther); }; }