From 86a4a388c3dd1a215b3d06240be5f81d3d8d9577 Mon Sep 17 00:00:00 2001
From: John Preston <johnprestonmail@gmail.com>
Date: Sun, 13 Mar 2016 18:45:00 +0300
Subject: [PATCH] ban / report / deleteAll done in MainWidget instead of
 RichDeleteMessageBox

---
 Telegram/SourceFiles/app.h                |   9 ++
 Telegram/SourceFiles/boxes/confirmbox.cpp | 154 +++-------------------
 Telegram/SourceFiles/boxes/confirmbox.h   |  11 --
 Telegram/SourceFiles/history.h            |   6 +
 Telegram/SourceFiles/mainwidget.cpp       |  59 ++++++++-
 Telegram/SourceFiles/mainwidget.h         |   9 +-
 6 files changed, 92 insertions(+), 156 deletions(-)

diff --git a/Telegram/SourceFiles/app.h b/Telegram/SourceFiles/app.h
index 4fabd34d8..aeaaf5c87 100644
--- a/Telegram/SourceFiles/app.h
+++ b/Telegram/SourceFiles/app.h
@@ -144,6 +144,15 @@ namespace App {
 	History *historyFromDialog(const PeerId &peer, int32 unreadCnt, int32 maxInboxRead);
 	History *historyLoaded(const PeerId &peer);
 	HistoryItem *histItemById(ChannelId channelId, MsgId itemId);
+	inline History *history(const PeerData *peer) {
+		return history(peer->id);
+	}
+	inline History *historyLoaded(const PeerData *peer) {
+		return historyLoaded(peer->id);
+	}
+	inline HistoryItem *histItemById(const ChannelData *channel, MsgId itemId) {
+		return histItemById(channel ? peerToChannel(channel->id) : 0, itemId);
+	}
 	inline HistoryItem *histItemById(const FullMsgId &msgId) {
 		return histItemById(msgId.channel, msgId.msg);
 	}
diff --git a/Telegram/SourceFiles/boxes/confirmbox.cpp b/Telegram/SourceFiles/boxes/confirmbox.cpp
index 5c9e5f152..b73b15d89 100644
--- a/Telegram/SourceFiles/boxes/confirmbox.cpp
+++ b/Telegram/SourceFiles/boxes/confirmbox.cpp
@@ -444,11 +444,9 @@ RichDeleteMessageBox::RichDeleteMessageBox(ChannelData *channel, UserData *from,
 , _reportSpam(this, lang(lng_report_spam), false)
 , _deleteAll(this, lang(lng_delete_all_from), false)
 , _delete(this, lang(lng_box_delete), st::defaultBoxButton)
-, _cancel(this, lang(lng_cancel), st::cancelBoxButton)
-, _deleteRequestId(0)
-, _banRequestId(0)
-, _reportRequestId(0)
-, _deleteAllRequestId(0) {
+, _cancel(this, lang(lng_cancel), st::cancelBoxButton) {
+	t_assert(_channel != nullptr);
+
 	_text.resizeToWidth(st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right());
 	setMaxHeight(st::boxPadding.top() + _text.height() + st::boxMediumSkip + _banUser.height() + st::boxLittleSkip + _reportSpam.height() + st::boxLittleSkip + _deleteAll.height() + st::boxPadding.bottom() + st::boxButtonPadding.top() + _delete.height() + st::boxButtonPadding.bottom());
 
@@ -466,54 +464,26 @@ void RichDeleteMessageBox::resizeEvent(QResizeEvent *e) {
 }
 
 void RichDeleteMessageBox::onDelete() {
-	if (_deleteRequestId || _banRequestId || _reportRequestId || _deleteAllRequestId) return;
-
-	HistoryItem *item = App::histItemById(_channel ? peerToChannel(_channel->id) : 0, _msgId);
-	if (!item || item->type() != HistoryItemMsg) {
-		Ui::hideLayer();
-		return;
+	if (_banUser.checked()) {
+		MTP::send(MTPchannels_KickFromChannel(_channel->inputChannel, _from->inputUser, MTP_boolTrue()), App::main()->rpcDone(&MainWidget::sentUpdatesReceived));
 	}
-
-	QVector<MTPint> toDelete(1, MTP_int(item->id));
-	History *h = item->history();
-	bool deleteItem = (item->id > 0), lastDeleted = (h->lastMsg == item);
-	bool banUser = _banUser.checked(), reportSpam = _reportSpam.checked(), deleteAll = _deleteAll.checked();
-
-	item->destroy();
-	if (deleteItem) {
-		_deleteRequestId = MTP::send(MTPchannels_DeleteMessages(_channel->inputChannel, MTP_vector<MTPint>(1, MTP_int(item->id))), rpcDone(&RichDeleteMessageBox::deleteDone), rpcFail(&RichDeleteMessageBox::deleteFail));
+	if (_reportSpam.checked()) {
+		MTP::send(MTPchannels_ReportSpam(_channel->inputChannel, _from->inputUser, MTP_vector<MTPint>(1, MTP_int(_msgId))));
 	}
-	if (banUser) {
-		_banRequestId = MTP::send(MTPchannels_KickFromChannel(_channel->inputChannel, _from->inputUser, MTP_boolTrue()), rpcDone(&RichDeleteMessageBox::banDone), rpcFail(&RichDeleteMessageBox::deleteFail));
+	if (_deleteAll.checked()) {
+		App::main()->deleteAllFromUser(_channel, _from);
 	}
-	if (reportSpam) {
-		_reportRequestId = MTP::send(MTPchannels_ReportSpam(_channel->inputChannel, _from->inputUser, MTP_vector<MTPint>(1, MTP_int(item->id))), rpcDone(&RichDeleteMessageBox::reportDone), rpcFail(&RichDeleteMessageBox::deleteFail));
-	}
-	if (deleteAll) {
-		QVector<MsgId> toDestroy;
-		for (History::Blocks::const_iterator i = h->blocks.cbegin(), e = h->blocks.cend(); i != e; ++i) {
-			for (HistoryBlock::Items::const_iterator j = (*i)->items.cbegin(), n = (*i)->items.cend(); j != n; ++j) {
-				if ((*j)->from() == _from && (*j)->type() == HistoryItemMsg && (*j)->canDelete()) {
-					toDestroy.push_back((*j)->id);
-				}
-			}
+	if (auto item = App::histItemById(_channel ? peerToChannel(_channel->id) : 0, _msgId)) {
+		bool wasLast = (item->history()->lastMsg == item);
+		item->destroy();
+		if (_msgId > 0) {
+			App::main()->deleteMessages(_channel, QVector<MTPint>(1, MTP_int(_msgId)));
+		} else if (wasLast) {
+			App::main()->checkPeerHistory(_channel);
 		}
-		for (QVector<MsgId>::const_iterator i = toDestroy.cbegin(), e = toDestroy.cend(); i != e; ++i) {
-			if (HistoryItem *item = App::histItemById(peerToChannel(_channel->id), *i)) {
-				if (item == h->lastMsg) {
-					lastDeleted = true;
-				}
-				item->destroy();
-			}
-		}
-		_deleteAllRequestId = MTP::send(MTPchannels_DeleteUserHistory(_channel->inputChannel, _from->inputUser), rpcDone(&RichDeleteMessageBox::deleteAllPart), rpcFail(&RichDeleteMessageBox::deleteFail));
 	}
-
-	if (!deleteItem && !deleteAll && lastDeleted && !h->lastMsg) {
-		App::main()->checkPeerHistory(h->peer);
-	}
-
 	Notify::historyItemsResized();
+	Ui::hideLayer();
 }
 
 void RichDeleteMessageBox::showAll() {
@@ -533,93 +503,3 @@ void RichDeleteMessageBox::hideAll() {
 	_delete.hide();
 	_cancel.hide();
 }
-
-void RichDeleteMessageBox::deleteDone(const MTPmessages_AffectedMessages &result, mtpRequestId req) {
-	const MTPDmessages_affectedMessages &d(result.c_messages_affectedMessages());
-	if (_channel->ptsUpdated(d.vpts.v, d.vpts_count.v)) {
-		_channel->ptsApplySkippedUpdates();
-		App::emitPeerUpdated();
-	}
-	if (History *h = App::historyLoaded(_channel->id)) {
-		if (!h->lastMsg && App::main()) {
-			App::main()->checkPeerHistory(_channel);
-		}
-	}
-	if (req == _deleteRequestId) {
-		_deleteRequestId = 0;
-	} else if (req == _banRequestId) {
-		_banRequestId = 0;
-	} else if (req == _reportRequestId) {
-		_reportRequestId = 0;
-	} else if (req == _deleteAllRequestId) {
-		_deleteAllRequestId = 0;
-	}
-	checkFinished();
-}
-
-void RichDeleteMessageBox::banDone(const MTPUpdates &result, mtpRequestId req) {
-	if (App::main()) {
-		App::main()->sentUpdatesReceived(result);
-	}
-	if (req == _banRequestId) {
-		_banRequestId = 0;
-	}
-	checkFinished();
-}
-
-void RichDeleteMessageBox::reportDone(const MTPBool &result, mtpRequestId req) {
-	if (req == _reportRequestId) {
-		_reportRequestId = 0;
-	}
-	checkFinished();
-}
-
-void RichDeleteMessageBox::deleteAllPart(const MTPmessages_AffectedHistory &result, mtpRequestId req) {
-	const MTPDmessages_affectedHistory &d(result.c_messages_affectedHistory());
-	if (_channel->ptsUpdated(d.vpts.v, d.vpts_count.v)) {
-		_channel->ptsApplySkippedUpdates();
-		App::emitPeerUpdated();
-	}
-	if (req == _deleteRequestId) {
-		_deleteRequestId = 0;
-	} else if (req == _banRequestId) {
-		_banRequestId = 0;
-	} else if (req == _reportRequestId) {
-		_reportRequestId = 0;
-	} else if (req == _deleteAllRequestId) {
-		_deleteAllRequestId = 0;
-	}
-
-	int32 offset = d.voffset.v;
-	if (offset > 0) {
-		_deleteAllRequestId = MTP::send(MTPchannels_DeleteUserHistory(_channel->inputChannel, _from->inputUser), rpcDone(&RichDeleteMessageBox::deleteAllPart), rpcFail(&RichDeleteMessageBox::deleteFail));
-		return;
-	}
-
-	if (History *h = App::historyLoaded(_channel->id)) {
-		if (!h->lastMsg && App::main()) {
-			App::main()->checkPeerHistory(_channel);
-		}
-	}
-	checkFinished();
-}
-
-bool RichDeleteMessageBox::deleteFail(const RPCError &error, mtpRequestId req) {
-	if (mtpIsFlood(error)) return false;
-	if (req == _deleteRequestId) {
-		_deleteRequestId = 0;
-	} else if (req == _banRequestId) {
-		_banRequestId = 0;
-	} else if (req == _reportRequestId) {
-		_reportRequestId = 0;
-	} else if (req == _deleteAllRequestId) {
-		_deleteAllRequestId = 0;
-	}
-	checkFinished();
-	return true;
-}
-
-void RichDeleteMessageBox::checkFinished() {
-	if (_deleteRequestId || _banRequestId || _reportRequestId || _deleteAllRequestId) return;
-	Ui::hideLayer();
-}
\ No newline at end of file
diff --git a/Telegram/SourceFiles/boxes/confirmbox.h b/Telegram/SourceFiles/boxes/confirmbox.h
index 6937b2c10..05b8febf3 100644
--- a/Telegram/SourceFiles/boxes/confirmbox.h
+++ b/Telegram/SourceFiles/boxes/confirmbox.h
@@ -220,15 +220,6 @@ protected:
 
 private:
 
-	void deleteDone(const MTPmessages_AffectedMessages &result, mtpRequestId req);
-	void banDone(const MTPUpdates &result, mtpRequestId req);
-	void reportDone(const MTPBool &result, mtpRequestId req);
-	void deleteAllPart(const MTPmessages_AffectedHistory &result, mtpRequestId req);
-
-	bool deleteFail(const RPCError &error, mtpRequestId req);
-
-	void checkFinished();
-
 	ChannelData *_channel;
 	UserData *_from;
 	MsgId _msgId;
@@ -238,6 +229,4 @@ private:
 
 	BoxButton _delete, _cancel;
 
-	mtpRequestId _deleteRequestId, _banRequestId, _reportRequestId, _deleteAllRequestId;
-
 };
diff --git a/Telegram/SourceFiles/history.h b/Telegram/SourceFiles/history.h
index abc72437f..928c2d9c4 100644
--- a/Telegram/SourceFiles/history.h
+++ b/Telegram/SourceFiles/history.h
@@ -1096,6 +1096,12 @@ public:
 
 	bool canEdit(const QDateTime &cur) const;
 
+	bool suggestBanReportDeleteAll() const {
+		auto channel = history()->peer->asChannel();
+		if (!channel || (!channel->amEditor() && !channel->amCreator())) return false;
+		return !isPost() && !out() && from()->isUser() && toHistoryMessage();
+	}
+
 	bool hasDirectLink() const {
 		return id > 0 && _history->peer->isChannel() && _history->peer->asChannel()->isPublic() && !_history->peer->isMegagroup();
 	}
diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp
index 471d941f6..6b51634d3 100644
--- a/Telegram/SourceFiles/mainwidget.cpp
+++ b/Telegram/SourceFiles/mainwidget.cpp
@@ -909,10 +909,9 @@ void MainWidget::forwardLayer(int32 forwardSelected) {
 
 void MainWidget::deleteLayer(int32 selectedCount) {
 	if (selectedCount == -1 && !overview) {
-		if (HistoryItem *item = App::contextItem()) {
-			ChannelData *channel = item->history()->peer->asChannel();
-			if (channel && !item->isPost() && !item->out() && item->from()->isUser() && (channel->amCreator() || channel->amEditor())) {
-				Ui::showLayer(new RichDeleteMessageBox(channel, item->from()->asUser(), item->id));
+		if (auto item = App::contextItem()) {
+			if (item->suggestBanReportDeleteAll()) {
+				Ui::showLayer(new RichDeleteMessageBox(item->history()->peer->asChannel(), item->from()->asUser(), item->id));
 				return;
 			}
 		}
@@ -992,9 +991,16 @@ void MainWidget::deleteHistoryAfterLeave(PeerData *peer, const MTPUpdates &updat
 
 void MainWidget::deleteHistoryPart(PeerData *peer, const MTPmessages_AffectedHistory &result) {
 	const MTPDmessages_affectedHistory &d(result.c_messages_affectedHistory());
-	if (ptsUpdated(d.vpts.v, d.vpts_count.v)) {
-		ptsApplySkippedUpdates();
-		App::emitPeerUpdated();
+	if (peer && peer->isChannel()) {
+		if (peer->asChannel()->ptsUpdated(d.vpts.v, d.vpts_count.v)) {
+			peer->asChannel()->ptsApplySkippedUpdates();
+			App::emitPeerUpdated();
+		}
+	} else {
+		if (ptsUpdated(d.vpts.v, d.vpts_count.v)) {
+			ptsApplySkippedUpdates();
+			App::emitPeerUpdated();
+		}
 	}
 
 	int32 offset = d.voffset.v;
@@ -1057,6 +1063,45 @@ void MainWidget::deleteConversation(PeerData *peer, bool deleteHistory) {
 	}
 }
 
+void MainWidget::deleteAllFromUser(ChannelData *channel, UserData *from) {
+	t_assert(channel != nullptr && from != nullptr);
+
+	QVector<MsgId> toDestroy;
+	if (auto history = App::historyLoaded(channel->id)) {
+		for (auto i = history->blocks.cbegin(), e = history->blocks.cend(); i != e; ++i) {
+			for (auto j = (*i)->items.cbegin(), n = (*i)->items.cend(); j != n; ++j) {
+				if ((*j)->from() == from && (*j)->type() == HistoryItemMsg && (*j)->canDelete()) {
+					toDestroy.push_back((*j)->id);
+				}
+			}
+		}
+		for (auto i = toDestroy.cbegin(), e = toDestroy.cend(); i != e; ++i) {
+			if (auto item = App::histItemById(peerToChannel(channel->id), *i)) {
+				item->destroy();
+			}
+		}
+	}
+	MTP::send(MTPchannels_DeleteUserHistory(channel->inputChannel, from->inputUser), rpcDone(&MainWidget::deleteAllFromUserPart, { channel, from }));
+}
+
+void MainWidget::deleteAllFromUserPart(DeleteAllFromUserParams params, const MTPmessages_AffectedHistory &result) {
+	const MTPDmessages_affectedHistory &d(result.c_messages_affectedHistory());
+	if (params.channel->ptsUpdated(d.vpts.v, d.vpts_count.v)) {
+		params.channel->ptsApplySkippedUpdates();
+		App::emitPeerUpdated();
+	}
+
+	int32 offset = d.voffset.v;
+	if (!MTP::authedId()) return;
+	if (offset > 0) {
+		MTP::send(MTPchannels_DeleteUserHistory(params.channel->inputChannel, params.from->inputUser), rpcDone(&MainWidget::deleteAllFromUserPart, params));
+	} else if (auto h = App::historyLoaded(params.channel)) {
+		if (!h->lastMsg) {
+			checkPeerHistory(params.channel);
+		}
+	}
+}
+
 void MainWidget::clearHistory(PeerData *peer) {
 	if (History *h = App::historyLoaded(peer->id)) {
 		if (h->lastMsg) {
diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h
index ada84278a..30e40dbc3 100644
--- a/Telegram/SourceFiles/mainwidget.h
+++ b/Telegram/SourceFiles/mainwidget.h
@@ -306,11 +306,11 @@ public:
 
 	bool leaveChatFailed(PeerData *peer, const RPCError &e);
 	void deleteHistoryAfterLeave(PeerData *peer, const MTPUpdates &updates);
-	void deleteHistoryPart(PeerData *peer, const MTPmessages_AffectedHistory &result);
 	void deleteMessages(PeerData *peer, const QVector<MTPint> &ids);
 	void deletedContact(UserData *user, const MTPcontacts_Link &result);
 	void deleteConversation(PeerData *peer, bool deleteHistory = true);
 	void clearHistory(PeerData *peer);
+	void deleteAllFromUser(ChannelData *channel, UserData *from);
 
 	void addParticipants(PeerData *chatOrChannel, const QVector<UserData*> &users);
 	bool addParticipantFail(UserData *user, const RPCError &e);
@@ -562,6 +562,13 @@ private:
 	void feedUpdateVector(const MTPVector<MTPUpdate> &updates, bool skipMessageIds = false);
 	void feedMessageIds(const MTPVector<MTPUpdate> &updates);
 
+	void deleteHistoryPart(PeerData *peer, const MTPmessages_AffectedHistory &result);
+	struct DeleteAllFromUserParams {
+		ChannelData *channel;
+		UserData *from;
+	};
+	void deleteAllFromUserPart(DeleteAllFromUserParams params, const MTPmessages_AffectedHistory &result);
+
 	void updateReceived(const mtpPrime *from, const mtpPrime *end);
 	bool updateFail(const RPCError &e);