From 36b702702bceaed98659843eba3ebad362ae867c Mon Sep 17 00:00:00 2001
From: John Preston <johnprestonmail@gmail.com>
Date: Tue, 6 Nov 2018 15:10:20 +0400
Subject: [PATCH] Support [inputN|n]otifyBroadcasts setting.

---
 Telegram/SourceFiles/apiwrap.cpp              |  6 ++++
 Telegram/SourceFiles/app.cpp                  | 15 ++++++++--
 Telegram/SourceFiles/app.h                    |  4 +--
 Telegram/SourceFiles/data/data_session.cpp    | 29 +++++++++++++++++--
 Telegram/SourceFiles/data/data_session.h      |  3 ++
 .../SourceFiles/history/history_widget.cpp    | 11 +++++--
 Telegram/SourceFiles/mainwidget.cpp           |  1 +
 7 files changed, 58 insertions(+), 11 deletions(-)

diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp
index e9488252e..f6c7ccdc1 100644
--- a/Telegram/SourceFiles/apiwrap.cpp
+++ b/Telegram/SourceFiles/apiwrap.cpp
@@ -1898,6 +1898,7 @@ void ApiWrap::requestNotifySettings(const MTPInputNotifyPeer &peer) {
 		switch (peer.type()) {
 		case mtpc_inputNotifyUsers: return peerFromUser(0);
 		case mtpc_inputNotifyChats: return peerFromChat(0);
+		case mtpc_inputNotifyBroadcasts: return peerFromChannel(0);
 		case mtpc_inputNotifyPeer: {
 			const auto &inner = peer.c_inputNotifyPeer().vpeer;
 			switch (inner.type()) {
@@ -2274,6 +2275,11 @@ void ApiWrap::notifySettingReceived(
 	case mtpc_inputNotifyChats:
 		_session->data().applyNotifySetting(MTP_notifyChats(), settings);
 	break;
+	case mtpc_inputNotifyBroadcasts:
+		_session->data().applyNotifySetting(
+			MTP_notifyBroadcasts(),
+			settings);
+	break;
 	case mtpc_inputNotifyPeer: {
 		auto &peer = notifyPeer.c_inputNotifyPeer().vpeer;
 		const auto apply = [&](PeerId peerId) {
diff --git a/Telegram/SourceFiles/app.cpp b/Telegram/SourceFiles/app.cpp
index a2dd6f912..6a6af72d3 100644
--- a/Telegram/SourceFiles/app.cpp
+++ b/Telegram/SourceFiles/app.cpp
@@ -1134,15 +1134,24 @@ namespace App {
 		}
 	}
 
-	void enumerateChatsChannels(
-			Fn<void(not_null<PeerData*>)> action) {
+	void enumerateGroups(Fn<void(not_null<PeerData*>)> action) {
 		for (const auto &[peerId, peer] : peersData) {
-			if (!peer->isUser()) {
+			if (peer->isChat() || peer->isMegagroup()) {
 				action(peer.get());
 			}
 		}
 	}
 
+	void enumerateChannels(Fn<void(not_null<ChannelData*>)> action) {
+		for (const auto &[peerId, peer] : peersData) {
+			if (const auto channel = peer->asChannel()) {
+				if (!channel->isMegagroup()) {
+					action(channel);
+				}
+			}
+		}
+	}
+
 	PeerData *peerByName(const QString &username) {
 		const auto uname = username.trimmed();
 		for (const auto &[peerId, peer] : peersData) {
diff --git a/Telegram/SourceFiles/app.h b/Telegram/SourceFiles/app.h
index c0b580b47..f43005dca 100644
--- a/Telegram/SourceFiles/app.h
+++ b/Telegram/SourceFiles/app.h
@@ -131,8 +131,8 @@ namespace App {
 		return channel(channelId, PeerData::FullLoaded);
 	}
 	void enumerateUsers(Fn<void(not_null<UserData*>)> action);
-	void enumerateChatsChannels(
-		Fn<void(not_null<PeerData*>)> action);
+	void enumerateGroups(Fn<void(not_null<PeerData*>)> action);
+	void enumerateChannels(Fn<void(not_null<ChannelData*>)> action);
 
 	PeerData *peerByName(const QString &username);
 	QString peerName(const PeerData *peer, bool forDialogs = false);
diff --git a/Telegram/SourceFiles/data/data_session.cpp b/Telegram/SourceFiles/data/data_session.cpp
index b7b4562f8..faab5b0e1 100644
--- a/Telegram/SourceFiles/data/data_session.cpp
+++ b/Telegram/SourceFiles/data/data_session.cpp
@@ -1813,7 +1813,9 @@ void Session::requestNotifySettings(not_null<PeerData*> peer) {
 	if (defaultNotifySettings(peer).settingsUnknown()) {
 		_session->api().requestNotifySettings(peer->isUser()
 			? MTP_inputNotifyUsers()
-			: MTP_inputNotifyChats());
+			: (peer->isChat() || peer->isMegagroup())
+			? MTP_inputNotifyChats()
+			: MTP_inputNotifyBroadcasts());
 	}
 }
 
@@ -1840,7 +1842,7 @@ void Session::applyNotifySetting(
 		if (_defaultChatNotifySettings.change(settings)) {
 			_defaultChatNotifyUpdates.fire({});
 
-			App::enumerateChatsChannels([&](not_null<PeerData*> peer) {
+			App::enumerateGroups([&](not_null<PeerData*> peer) {
 				if (!peer->notifySettingsUnknown()
 					&& ((!peer->notifyMuteUntil()
 						&& _defaultChatNotifySettings.muteUntil())
@@ -1851,6 +1853,21 @@ void Session::applyNotifySetting(
 			});
 		}
 	} break;
+	case mtpc_notifyBroadcasts: {
+		if (_defaultBroadcastNotifySettings.change(settings)) {
+			_defaultBroadcastNotifyUpdates.fire({});
+
+			App::enumerateChannels([&](not_null<ChannelData*> channel) {
+				if (!channel->notifySettingsUnknown()
+					&& ((!channel->notifyMuteUntil()
+						&& _defaultBroadcastNotifySettings.muteUntil())
+						|| (!channel->notifySilentPosts()
+							&& _defaultBroadcastNotifySettings.silentPosts()))) {
+					updateNotifySettingsLocal(channel);
+				}
+			});
+		}
+	} break;
 	case mtpc_notifyPeer: {
 		const auto &data = notifyPeer.c_notifyPeer();
 		if (const auto peer = App::peerLoaded(peerFromMTP(data.vpeer))) {
@@ -1937,11 +1954,17 @@ rpl::producer<> Session::defaultChatNotifyUpdates() const {
 	return _defaultChatNotifyUpdates.events();
 }
 
+rpl::producer<> Session::defaultBroadcastNotifyUpdates() const {
+	return _defaultBroadcastNotifyUpdates.events();
+}
+
 rpl::producer<> Session::defaultNotifyUpdates(
 		not_null<const PeerData*> peer) const {
 	return peer->isUser()
 		? defaultUserNotifyUpdates()
-		: defaultChatNotifyUpdates();
+		: (peer->isChat() || peer->isMegagroup())
+		? defaultChatNotifyUpdates()
+		: defaultBroadcastNotifyUpdates();
 }
 
 void Session::serviceNotification(
diff --git a/Telegram/SourceFiles/data/data_session.h b/Telegram/SourceFiles/data/data_session.h
index 7b871bc0f..508654811 100644
--- a/Telegram/SourceFiles/data/data_session.h
+++ b/Telegram/SourceFiles/data/data_session.h
@@ -416,6 +416,7 @@ public:
 	bool notifySettingsUnknown(not_null<const PeerData*> peer) const;
 	rpl::producer<> defaultUserNotifyUpdates() const;
 	rpl::producer<> defaultChatNotifyUpdates() const;
+	rpl::producer<> defaultBroadcastNotifyUpdates() const;
 	rpl::producer<> defaultNotifyUpdates(
 		not_null<const PeerData*> peer) const;
 
@@ -641,8 +642,10 @@ private:
 
 	NotifySettings _defaultUserNotifySettings;
 	NotifySettings _defaultChatNotifySettings;
+	NotifySettings _defaultBroadcastNotifySettings;
 	rpl::event_stream<> _defaultUserNotifyUpdates;
 	rpl::event_stream<> _defaultChatNotifyUpdates;
+	rpl::event_stream<> _defaultBroadcastNotifyUpdates;
 	std::unordered_set<not_null<const PeerData*>> _mutedPeers;
 	base::Timer _unmuteByFinishedTimer;
 
diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp
index 29151a931..ec9640588 100644
--- a/Telegram/SourceFiles/history/history_widget.cpp
+++ b/Telegram/SourceFiles/history/history_widget.cpp
@@ -719,13 +719,17 @@ HistoryWidget::HistoryWidget(
 			}
 		}
 	}));
+
 	rpl::merge(
 		Auth().data().defaultUserNotifyUpdates(),
-		Auth().data().defaultChatNotifyUpdates()
+		Auth().data().defaultChatNotifyUpdates(),
+		Auth().data().defaultBroadcastNotifyUpdates()
 	) | rpl::start_with_next([=] {
 		updateNotifyControls();
 	}, lifetime());
-	subscribe(Auth().data().queryItemVisibility(), [this](const Data::Session::ItemVisibilityQuery &query) {
+
+	subscribe(Auth().data().queryItemVisibility(), [=](
+			const Data::Session::ItemVisibilityQuery &query) {
 		if (_a_show.animating()
 			|| _history != query.item->history()
 			|| !query.item->mainView() || !isVisible()) {
@@ -735,7 +739,8 @@ HistoryWidget::HistoryWidget(
 			auto top = _list->itemTop(view);
 			if (top >= 0) {
 				auto scrollTop = _scroll->scrollTop();
-				if (top + view->height() > scrollTop && top < scrollTop + _scroll->height()) {
+				if (top + view->height() > scrollTop
+					&& top < scrollTop + _scroll->height()) {
 					*query.isVisible = true;
 				}
 			}
diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp
index a09708493..af393c782 100644
--- a/Telegram/SourceFiles/mainwidget.cpp
+++ b/Telegram/SourceFiles/mainwidget.cpp
@@ -3345,6 +3345,7 @@ void MainWidget::mtpPing() {
 void MainWidget::start() {
 	Auth().api().requestNotifySettings(MTP_inputNotifyUsers());
 	Auth().api().requestNotifySettings(MTP_inputNotifyChats());
+	Auth().api().requestNotifySettings(MTP_inputNotifyBroadcasts());
 
 	Local::readSavedPeers();
 	cSetOtherOnline(0);