From 62568daffee5205c760d7542f25c4c5551a646d2 Mon Sep 17 00:00:00 2001 From: John Preston Date: Mon, 4 Dec 2017 21:46:03 +0400 Subject: [PATCH] Refactor NotifySettings in PeerData. --- Telegram/Resources/langs/lang.strings | 1 + Telegram/SourceFiles/apiwrap.cpp | 25 +- Telegram/SourceFiles/app.cpp | 33 +-- Telegram/SourceFiles/app.h | 4 +- .../SourceFiles/boxes/mute_settings_box.cpp | 47 ++-- .../SourceFiles/data/data_notify_settings.cpp | 217 ++++++++++++++++++ .../SourceFiles/data/data_notify_settings.h | 60 +++++ Telegram/SourceFiles/data/data_peer.cpp | 5 +- Telegram/SourceFiles/data/data_peer.h | 83 +++---- .../dialogs/dialogs_inner_widget.cpp | 5 +- Telegram/SourceFiles/history/history.cpp | 30 +-- Telegram/SourceFiles/history/history.h | 2 +- .../SourceFiles/history/history_widget.cpp | 38 ++- .../SourceFiles/info/info_wrap_widget.cpp | 15 +- .../info/profile/info_profile_actions.cpp | 11 +- .../info/profile/info_profile_values.cpp | 3 +- Telegram/SourceFiles/mainwidget.cpp | 168 +++++--------- Telegram/SourceFiles/mainwidget.h | 31 +-- .../window/notifications_manager.cpp | 56 +++-- .../SourceFiles/window/window_peer_menu.cpp | 10 +- Telegram/gyp/telegram_sources.txt | 2 + 21 files changed, 559 insertions(+), 287 deletions(-) create mode 100644 Telegram/SourceFiles/data/data_notify_settings.cpp create mode 100644 Telegram/SourceFiles/data/data_notify_settings.h diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index bd4c433a7230ce..39f2c42302552e 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -975,6 +975,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org "lng_unblock_button" = "Unblock"; "lng_channel_mute" = "Mute"; "lng_channel_unmute" = "Unmute"; +"lng_saved_messages" = "Saved messages"; "lng_dialogs_text_with_from" = "{from_part} {message}"; "lng_dialogs_text_from_wrapped" = "{from}:"; diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index 0bee33c5ba4973..6da68120c4eb01 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -1432,23 +1432,36 @@ void ApiWrap::checkQuitPreventFinished() { } } -PeerData *ApiWrap::notifySettingReceived(MTPInputNotifyPeer notifyPeer, const MTPPeerNotifySettings &settings) { +PeerData *ApiWrap::notifySettingReceived( + MTPInputNotifyPeer notifyPeer, + const MTPPeerNotifySettings &settings) { PeerData *requestedPeer = nullptr; switch (notifyPeer.type()) { - case mtpc_inputNotifyAll: App::main()->applyNotifySetting(MTP_notifyAll(), settings); break; - case mtpc_inputNotifyUsers: App::main()->applyNotifySetting(MTP_notifyUsers(), settings); break; - case mtpc_inputNotifyChats: App::main()->applyNotifySetting(MTP_notifyChats(), settings); break; + case mtpc_inputNotifyAll: + App::main()->applyNotifySetting(MTP_notifyAll(), settings); + break; + case mtpc_inputNotifyUsers: + App::main()->applyNotifySetting(MTP_notifyUsers(), settings); + break; + case mtpc_inputNotifyChats: + App::main()->applyNotifySetting(MTP_notifyChats(), settings); + break; case mtpc_inputNotifyPeer: { auto &peer = notifyPeer.c_inputNotifyPeer().vpeer; switch (peer.type()) { - case mtpc_inputPeerEmpty: App::main()->applyNotifySetting(MTP_notifyPeer(MTP_peerUser(MTP_int(0))), settings); break; + case mtpc_inputPeerEmpty: App::main()->applyNotifySetting( + MTP_notifyPeer(MTP_peerUser(MTP_int(0))), + settings); + break; case mtpc_inputPeerSelf: requestedPeer = App::self(); break; case mtpc_inputPeerUser: requestedPeer = App::user(peerFromUser(peer.c_inputPeerUser().vuser_id)); break; case mtpc_inputPeerChat: requestedPeer = App::chat(peerFromChat(peer.c_inputPeerChat().vchat_id)); break; case mtpc_inputPeerChannel: requestedPeer = App::channel(peerFromChannel(peer.c_inputPeerChannel().vchannel_id)); break; } if (requestedPeer) { - App::main()->applyNotifySetting(MTP_notifyPeer(peerToMTP(requestedPeer->id)), settings); + App::main()->applyNotifySetting( + MTP_notifyPeer(peerToMTP(requestedPeer->id)), + settings); } } break; } diff --git a/Telegram/SourceFiles/app.cpp b/Telegram/SourceFiles/app.cpp index 94f59b4cc7891d..85565b6e7d2fe6 100644 --- a/Telegram/SourceFiles/app.cpp +++ b/Telegram/SourceFiles/app.cpp @@ -60,7 +60,7 @@ namespace { using PeersData = QHash; PeersData peersData; - using MutedPeers = QMap; + using MutedPeers = QMap, bool>; MutedPeers mutedPeers; PhotosData photosData; @@ -195,9 +195,6 @@ namespace { Window::Theme::Background()->reset(); cSetOtherOnline(0); - globalNotifyAllPtr = UnknownNotifySettings; - globalNotifyUsersPtr = UnknownNotifySettings; - globalNotifyChatsPtr = UnknownNotifySettings; clearStorageImages(); if (auto w = wnd()) { w->updateConnectingStatus(); @@ -2598,28 +2595,32 @@ namespace { return QString(); } - void regMuted(PeerData *peer, int32 changeIn) { + void regMuted(not_null peer, TimeMs changeIn) { ::mutedPeers.insert(peer, true); - if (App::main()) App::main()->updateMutedIn(changeIn); + App::main()->updateMutedIn(changeIn); } - void unregMuted(PeerData *peer) { + void unregMuted(not_null peer) { ::mutedPeers.remove(peer); } void updateMuted() { - int32 changeInMin = 0; - for (MutedPeers::iterator i = ::mutedPeers.begin(); i != ::mutedPeers.end();) { - int32 changeIn = 0; - History *h = App::history(i.key()->id); - if (isNotifyMuted(i.key()->notify, &changeIn)) { - h->setMute(true); - if (changeIn && (!changeInMin || changeIn < changeInMin)) { - changeInMin = changeIn; + auto changeInMin = TimeMs(0); + for (auto i = ::mutedPeers.begin(); i != ::mutedPeers.end();) { + const auto history = App::historyLoaded(i.key()->id); + const auto muteFinishesIn = i.key()->notifyMuteFinishesIn(); + if (muteFinishesIn > 0) { + if (history) { + history->changeMute(true); + } + if (!changeInMin || muteFinishesIn < changeInMin) { + changeInMin = muteFinishesIn; } ++i; } else { - h->setMute(false); + if (history) { + history->changeMute(false); + } i = ::mutedPeers.erase(i); } } diff --git a/Telegram/SourceFiles/app.h b/Telegram/SourceFiles/app.h index 531abac00f834d..1f9fb1e3eb52d3 100644 --- a/Telegram/SourceFiles/app.h +++ b/Telegram/SourceFiles/app.h @@ -262,8 +262,8 @@ namespace App { void stopRoundVideoPlayback(); void stopGifItems(); - void regMuted(PeerData *peer, int32 changeIn); - void unregMuted(PeerData *peer); + void regMuted(not_null peer, TimeMs changeIn); + void unregMuted(not_null peer); void updateMuted(); void setProxySettings(QNetworkAccessManager &manager); diff --git a/Telegram/SourceFiles/boxes/mute_settings_box.cpp b/Telegram/SourceFiles/boxes/mute_settings_box.cpp index 7ac54664b810c8..73d5de04040364 100644 --- a/Telegram/SourceFiles/boxes/mute_settings_box.cpp +++ b/Telegram/SourceFiles/boxes/mute_settings_box.cpp @@ -14,16 +14,22 @@ #include "ui/widgets/checkbox.h" #include "ui/widgets/labels.h" +namespace { + +constexpr auto kForeverHours = 24 * 365; + +} // namespace + void MuteSettingsBox::prepare() { setTitle(langFactory(lng_disable_notifications_from_tray)); - int y = 0; + auto y = 0; object_ptr info(this, st::boxLabel); info->setText(lang(lng_mute_box_tip)); info->moveToLeft(st::boxPadding.left(), y); y += info->height() + st::boxLittleSkip; - auto icon = object_ptr( + const auto icon = object_ptr( this, controller(), _peer, @@ -40,27 +46,34 @@ void MuteSettingsBox::prepare() { // the icon is always higher than this chat title y += icon->height() + st::boxMediumSkip; - const int FOREVER = 8760; // in fact, this is mute only for 1 year - auto group = std::make_shared(FOREVER); + // in fact, this is mute only for 1 year + const auto group = std::make_shared(kForeverHours); y += st::boxOptionListPadding.top(); - for (int value : { 1, 4, 18, 72, FOREVER }) { // periods in hours - QString text; - if (value < 24) { - text = lng_mute_duration_hours(lt_count, value); - } else if (value < FOREVER) { - text = lng_rights_chat_banned_day(lt_count, value / 24); - } else { - text = lang(lng_rights_chat_banned_forever); - } - object_ptr option(this, group, value, text); + for (const auto hours : { 1, 4, 18, 72, kForeverHours }) { + const auto text = [&] { + if (hours < 24) { + return lng_mute_duration_hours(lt_count, hours); + } else if (hours < kForeverHours) { + return lng_rights_chat_banned_day(lt_count, hours / 24); + } else { + return lang(lng_rights_chat_banned_forever); + } + }(); + object_ptr option(this, group, hours, text); option->moveToLeft(st::boxPadding.left(), y); y += option->heightNoMargins() + st::boxOptionListSkip; } - y += st::boxOptionListPadding.bottom() - st::boxOptionListSkip + st::defaultCheckbox.margin.bottom(); + y += st::boxOptionListPadding.bottom() + - st::boxOptionListSkip + + st::defaultCheckbox.margin.bottom(); addButton(langFactory(lng_box_ok), [this, group] { - App::main()->updateNotifySetting(_peer, NotifySettingSetMuted, - SilentNotifiesDontChange, group->value() * 3600); + auto muteForSeconds = group->value() * 3600; + App::main()->updateNotifySettings( + _peer, + Data::NotifySettings::MuteChange::Mute, + Data::NotifySettings::SilentPostsChange::Ignore, + muteForSeconds); closeBox(); }); addButton(langFactory(lng_cancel), [this] { closeBox(); }); diff --git a/Telegram/SourceFiles/data/data_notify_settings.cpp b/Telegram/SourceFiles/data/data_notify_settings.cpp new file mode 100644 index 00000000000000..58eda6aef453df --- /dev/null +++ b/Telegram/SourceFiles/data/data_notify_settings.cpp @@ -0,0 +1,217 @@ +/* +This file is part of Telegram Desktop, +the official desktop version of Telegram messaging app, see https://telegram.org + +Telegram Desktop is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +It is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +In addition, as a special exception, the copyright holders give permission +to link the code of portions of this program with the OpenSSL library. + +Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE +Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org +*/ +#include "data/data_notify_settings.h" + +namespace Data { +namespace { + +MTPinputPeerNotifySettings DefaultSettings() { + const auto flags = MTPDpeerNotifySettings::Flag::f_show_previews; + const auto muteValue = TimeId(0); + return MTP_inputPeerNotifySettings( + MTP_flags(mtpCastFlags(flags)), + MTP_int(muteValue), + MTP_string("default")); +} + +} // namespace + +class NotifySettingsValue { +public: + NotifySettingsValue(const MTPDpeerNotifySettings &data); + + using MuteChange = NotifySettings::MuteChange; + using SilentPostsChange = NotifySettings::SilentPostsChange; + + bool change(const MTPDpeerNotifySettings &data); + bool change( + MuteChange mute, + SilentPostsChange silent, + int muteForSeconds); + TimeMs muteFinishesIn() const; + bool silentPosts() const; + MTPinputPeerNotifySettings serialize() const; + +private: + bool change( + MTPDpeerNotifySettings::Flags flags, + TimeId mute, + QString sound); + + MTPDpeerNotifySettings::Flags _flags; + TimeId _mute; + QString _sound; + +}; + +NotifySettingsValue::NotifySettingsValue(const MTPDpeerNotifySettings &data) +: _flags(data.vflags.v) +, _mute(data.vmute_until.v) +, _sound(qs(data.vsound)) { +} + +bool NotifySettingsValue::silentPosts() const { + return _flags & MTPDpeerNotifySettings::Flag::f_silent; +} + +bool NotifySettingsValue::change(const MTPDpeerNotifySettings &data) { + return change(data.vflags.v, data.vmute_until.v, qs(data.vsound)); +} + +bool NotifySettingsValue::change( + MuteChange mute, + SilentPostsChange silent, + int muteForSeconds) { + const auto newFlags = [&] { + auto result = _flags; + if (silent == SilentPostsChange::Silent) { + result |= MTPDpeerNotifySettings::Flag::f_silent; + } else if (silent == SilentPostsChange::Notify) { + result &= ~MTPDpeerNotifySettings::Flag::f_silent; + } + return result; + }(); + const auto newMute = (mute == MuteChange::Mute) + ? (unixtime() + muteForSeconds) + : (mute == MuteChange::Ignore) ? _mute : 0; + const auto newSound = (newMute == 0 && _sound.isEmpty()) + ? qsl("default") + : _sound; + return change(newFlags, newMute, newSound); +} + +bool NotifySettingsValue::change( + MTPDpeerNotifySettings::Flags flags, + TimeId mute, + QString sound) { + if (_flags == flags && _mute == mute && _sound == sound) { + return false; + } + _flags = flags; + _mute = mute; + _sound = sound; + return true; +} + +TimeMs NotifySettingsValue::muteFinishesIn() const { + auto now = unixtime(); + if (_mute > now) { + return (_mute - now + 1) * 1000LL; + } + return 0; +} + +MTPinputPeerNotifySettings NotifySettingsValue::serialize() const { + return MTP_inputPeerNotifySettings( + MTP_flags(mtpCastFlags(_flags)), + MTP_int(_mute), + MTP_string(_sound)); +} + +bool NotifySettings::change(const MTPPeerNotifySettings &settings) { + switch (settings.type()) { + case mtpc_peerNotifySettingsEmpty: { + if (!_known || _value) { + _known = true; + _value = nullptr; + return true; + } + return false; + } break; + + case mtpc_peerNotifySettings: { + auto &data = settings.c_peerNotifySettings(); + if (_value) { + return _value->change(data); + } + _known = true; + _value = std::make_unique(data); + return true; + } break; + } + + Unexpected("Type in NotifySettings::change()"); +} + +NotifySettings::NotifySettings() = default; + +bool NotifySettings::change( + MuteChange mute, + SilentPostsChange silent, + int muteForSeconds) { + Expects(mute != MuteChange::Mute || muteForSeconds > 0); + + if (mute == MuteChange::Ignore && silent == SilentPostsChange::Ignore) { + return false; + } + if (_value) { + return _value->change(mute, silent, muteForSeconds); + } + const auto asEmpty = [&] { + if (mute == MuteChange::Mute) { + return false; + } + if (silent == SilentPostsChange::Silent) { + return false; + } + return true; + }(); + if (asEmpty) { + return change(MTP_peerNotifySettingsEmpty()); + } + const auto flags = MTPDpeerNotifySettings::Flag::f_show_previews + | ((silent == SilentPostsChange::Silent) + ? MTPDpeerNotifySettings::Flag::f_silent + : MTPDpeerNotifySettings::Flag(0)); + const auto muteUntil = (mute == MuteChange::Mute) + ? (unixtime() + muteForSeconds) + : 0; + return change(MTP_peerNotifySettings( + MTP_flags(flags), + MTP_int(muteUntil), + MTP_string("default"))); +} + +TimeMs NotifySettings::muteFinishesIn() const { + return _value + ? _value->muteFinishesIn() + : 0LL; +} + +bool NotifySettings::settingsUnknown() const { + return !_known; +} + +bool NotifySettings::silentPosts() const { + return _value + ? _value->silentPosts() + : false; +} + +MTPinputPeerNotifySettings NotifySettings::serialize() const { + return _value + ? _value->serialize() + : DefaultSettings(); +} + +NotifySettings::~NotifySettings() = default; + +} // namespace Data diff --git a/Telegram/SourceFiles/data/data_notify_settings.h b/Telegram/SourceFiles/data/data_notify_settings.h new file mode 100644 index 00000000000000..99633bfe51f5e7 --- /dev/null +++ b/Telegram/SourceFiles/data/data_notify_settings.h @@ -0,0 +1,60 @@ +/* +This file is part of Telegram Desktop, +the official desktop version of Telegram messaging app, see https://telegram.org + +Telegram Desktop is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +It is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +In addition, as a special exception, the copyright holders give permission +to link the code of portions of this program with the OpenSSL library. + +Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE +Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org +*/ +#pragma once + +namespace Data { + +class NotifySettingsValue; + +class NotifySettings { +public: + NotifySettings(); + + enum class MuteChange { + Ignore, + Mute, + Unmute, + }; + enum class SilentPostsChange { + Ignore, + Silent, + Notify, + }; + + bool change(const MTPPeerNotifySettings &settings); + bool change( + MuteChange mute, + SilentPostsChange silent, + int muteForSeconds); + TimeMs muteFinishesIn() const; + bool settingsUnknown() const; + bool silentPosts() const; + MTPinputPeerNotifySettings serialize() const; + + ~NotifySettings(); + +private: + bool _known = false; + std::unique_ptr _value; + +}; + +} // namespace Data diff --git a/Telegram/SourceFiles/data/data_peer.cpp b/Telegram/SourceFiles/data/data_peer.cpp index 12a61010ba01ba..5ba023b6dde994 100644 --- a/Telegram/SourceFiles/data/data_peer.cpp +++ b/Telegram/SourceFiles/data/data_peer.cpp @@ -259,9 +259,6 @@ EmptyUserpic::~EmptyUserpic() = default; using UpdateFlag = Notify::PeerUpdate::Flag; -NotifySettings globalNotifyAll, globalNotifyUsers, globalNotifyChats; -NotifySettingsPtr globalNotifyAllPtr = UnknownNotifySettings, globalNotifyUsersPtr = UnknownNotifySettings, globalNotifyChatsPtr = UnknownNotifySettings; - PeerClickHandler::PeerClickHandler(not_null peer) : _peer(peer) { } @@ -291,6 +288,8 @@ PeerData::PeerData(const PeerId &id) _userpicEmpty.set(id, QString()); } +PeerData::~PeerData() = default; + void PeerData::updateNameDelayed( const QString &newName, const QString &newNameOrPhone, diff --git a/Telegram/SourceFiles/data/data_peer.h b/Telegram/SourceFiles/data/data_peer.h index c145027aaa06b4..79faee7942dd20 100644 --- a/Telegram/SourceFiles/data/data_peer.h +++ b/Telegram/SourceFiles/data/data_peer.h @@ -22,50 +22,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include "data/data_types.h" #include "data/data_flags.h" - -struct NotifySettings { - NotifySettings() = default; - - bool previews() const { - return flags & MTPDpeerNotifySettings::Flag::f_show_previews; - } - bool silent() const { - return flags & MTPDpeerNotifySettings::Flag::f_silent; - } - - MTPDpeerNotifySettings::Flags flags - = MTPDpeerNotifySettings::Flag::f_show_previews; - TimeId mute = 0; - QString sound = qsl("default"); - -}; -typedef NotifySettings *NotifySettingsPtr; - -static const NotifySettingsPtr UnknownNotifySettings - = NotifySettingsPtr(0); -static const NotifySettingsPtr EmptyNotifySettings - = NotifySettingsPtr(1); -extern NotifySettings globalNotifyAll; -extern NotifySettings globalNotifyUsers; -extern NotifySettings globalNotifyChats; -extern NotifySettingsPtr globalNotifyAllPtr; -extern NotifySettingsPtr globalNotifyUsersPtr; -extern NotifySettingsPtr globalNotifyChatsPtr; - -inline bool isNotifyMuted( - NotifySettingsPtr settings, - TimeId *changeIn = nullptr) { - if (settings != UnknownNotifySettings - && settings != EmptyNotifySettings) { - auto t = unixtime(); - if (settings->mute > t) { - if (changeIn) *changeIn = settings->mute - t + 1; - return true; - } - } - if (changeIn) *changeIn = 0; - return false; -} +#include "data/data_notify_settings.h" int PeerColorIndex(PeerId peerId); int PeerColorIndex(int32 bareId); @@ -142,12 +99,7 @@ class PeerData { PeerData &operator=(const PeerData &other) = delete; public: - virtual ~PeerData() { - if (notify != UnknownNotifySettings - && notify != EmptyNotifySettings) { - delete base::take(notify); - } - } + virtual ~PeerData(); bool isUser() const { return peerIsUser(id); @@ -163,11 +115,32 @@ class PeerData { } bool isVerified() const; bool isMegagroup() const; + + TimeMs notifyMuteFinishesIn() const { + return _notify.muteFinishesIn(); + } + bool notifyChange(const MTPPeerNotifySettings &settings) { + return _notify.change(settings); + } + bool notifyChange( + Data::NotifySettings::MuteChange mute, + Data::NotifySettings::SilentPostsChange silent, + int muteForSeconds) { + return _notify.change(mute, silent, muteForSeconds); + } + bool notifySettingsUnknown() const { + return _notify.settingsUnknown(); + } + bool notifySilentPosts() const { + return _notify.silentPosts(); + } + MTPinputPeerNotifySettings notifySerialize() const { + return _notify.serialize(); + } bool isMuted() const { - return (notify != EmptyNotifySettings) - && (notify != UnknownNotifySettings) - && (notify->mute >= unixtime()); + return (notifyMuteFinishesIn() > 0); } + bool canWrite() const; UserData *asUser(); const UserData *asUser() const; @@ -265,8 +238,6 @@ class PeerData { int nameVersion = 1; - NotifySettingsPtr notify = UnknownNotifySettings; - // if this string is not empty we must not allow to open the // conversation and we must show this string instead virtual QString restrictionReason() const { @@ -296,6 +267,8 @@ class PeerData { private: void fillNames(); + Data::NotifySettings _notify; + ClickHandlerPtr _openLink; NameWords _nameWords; // for filtering NameFirstChars _nameFirstChars; diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp index cfe6556cff2e48..485c1ab032b320 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp @@ -1487,7 +1487,10 @@ void DialogsInner::dialogsReceived(const QVector &added) { } } } - App::main()->applyNotifySetting(MTP_notifyPeer(d.vpeer), d.vnotify_settings, history); + App::main()->applyNotifySetting( + MTP_notifyPeer(d.vpeer), + d.vnotify_settings, + history); if (!history->isPinnedDialog() && !history->lastMsgDate.isNull()) { addSavedPeersAfter(history->lastMsgDate); diff --git a/Telegram/SourceFiles/history/history.cpp b/Telegram/SourceFiles/history/history.cpp index f432588a8dca45..8b4a51466a3992 100644 --- a/Telegram/SourceFiles/history/history.cpp +++ b/Telegram/SourceFiles/history/history.cpp @@ -85,7 +85,7 @@ History::History(const PeerId &peerId) : peer(App::peer(peerId)) , lastItemTextCache(st::dialogsTextWidthMin) , cloudDraftTextCache(st::dialogsTextWidthMin) -, _mute(isNotifyMuted(peer->notify)) +, _mute(peer->isMuted()) , _sendActionText(st::dialogsTextWidthMin) { if (peer->isUser() && peer->asUser()->botInfo) { outboxReadBefore = INT_MAX; @@ -1912,21 +1912,23 @@ void History::setUnreadCount(int newUnreadCount) { } } - void History::setMute(bool newMute) { - if (_mute != newMute) { - _mute = newMute; - if (inChatList(Dialogs::Mode::All)) { - if (_unreadCount) { - App::histories().unreadMuteChanged(_unreadCount, newMute); - Notify::unreadCounterUpdated(); - } - Notify::historyMuteUpdated(this); +bool History::changeMute(bool newMute) { + if (_mute == newMute) { + return false; + } + _mute = newMute; + if (inChatList(Dialogs::Mode::All)) { + if (_unreadCount) { + App::histories().unreadMuteChanged(_unreadCount, newMute); + Notify::unreadCounterUpdated(); } - updateChatListEntry(); - Notify::peerUpdatedDelayed( - peer, - Notify::PeerUpdate::Flag::NotificationsEnabled); + Notify::historyMuteUpdated(this); } + updateChatListEntry(); + Notify::peerUpdatedDelayed( + peer, + Notify::PeerUpdate::Flag::NotificationsEnabled); + return true; } void History::getNextShowFrom(HistoryBlock *block, int i) { diff --git a/Telegram/SourceFiles/history/history.h b/Telegram/SourceFiles/history/history.h index a31f8080498f19..dc87a8890d67ae 100644 --- a/Telegram/SourceFiles/history/history.h +++ b/Telegram/SourceFiles/history/history.h @@ -261,7 +261,7 @@ class History { bool mute() const { return _mute; } - void setMute(bool newMute); + bool changeMute(bool newMute); void getNextShowFrom(HistoryBlock *block, int i); void addUnreadBar(); void destroyUnreadBar(); diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index 370a1ffdf7efda..03b1877ae38769 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -501,9 +501,16 @@ void SilentToggle::mouseReleaseEvent(QMouseEvent *e) { setChecked(!_checked); IconButton::mouseReleaseEvent(e); Ui::Tooltip::Show(0, this); - auto p = App::main() ? App::main()->peer() : nullptr; - if (p && p->isChannel() && p->notify != UnknownNotifySettings) { - App::main()->updateNotifySetting(p, NotifySettingDontChange, _checked ? SilentNotifiesSetSilent : SilentNotifiesSetNotify); + if (const auto peer = App::main() ? App::main()->peer() : nullptr) { + if (peer->isChannel() && !peer->notifySettingsUnknown()) { + const auto silentState = _checked + ? Data::NotifySettings::SilentPostsChange::Silent + : Data::NotifySettings::SilentPostsChange::Notify; + App::main()->updateNotifySettings( + peer, + Data::NotifySettings::MuteChange::Ignore, + silentState); + } } } @@ -695,6 +702,7 @@ HistoryWidget::HistoryWidget(QWidget *parent, not_null cont | UpdateFlag::AdminsChanged | UpdateFlag::MembersChanged | UpdateFlag::UserOnlineChanged + | UpdateFlag::NotificationsEnabled | UpdateFlag::ChannelAmIn; subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(changes, [this](const Notify::PeerUpdate &update) { if (update.peer == _peer) { @@ -711,6 +719,9 @@ HistoryWidget::HistoryWidget(QWidget *parent, not_null cont return; } } + if (update.flags & UpdateFlag::NotificationsEnabled) { + updateNotifySettings(); + } if (update.flags & UpdateFlag::RestrictionReasonChanged) { auto restriction = _peer->restrictionReason(); if (!restriction.isEmpty()) { @@ -1780,7 +1791,7 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re if (_channel) { updateNotifySettings(); - if (_peer->notify == UnknownNotifySettings) { + if (_peer->notifySettingsUnknown()) { Auth().api().requestNotifySetting(_peer); } } @@ -1884,9 +1895,11 @@ void HistoryWidget::updateFieldSubmitSettings() { void HistoryWidget::updateNotifySettings() { if (!_peer || !_peer->isChannel()) return; - _muteUnmute->setText(lang(_history->mute() ? lng_channel_unmute : lng_channel_mute).toUpper()); - if (_peer->notify != UnknownNotifySettings) { - _silent->setChecked(_peer->notify != EmptyNotifySettings && (_peer->notify->flags & MTPDpeerNotifySettings::Flag::f_silent)); + _muteUnmute->setText(lang(_history->mute() + ? lng_channel_unmute + : lng_channel_mute).toUpper()); + if (!_peer->notifySettingsUnknown()) { + _silent->setChecked(_peer->notifySilentPosts()); if (_silent->isHidden() && hasSilentToggle()) { updateControlsVisibility(); } @@ -3025,7 +3038,10 @@ bool HistoryWidget::joinFail(const RPCError &error, mtpRequestId req) { } void HistoryWidget::onMuteUnmute() { - App::main()->updateNotifySetting(_peer, _history->mute() ? NotifySettingSetNotify : NotifySettingSetMuted); + const auto muteState = _history->mute() + ? Data::NotifySettings::MuteChange::Unmute + : Data::NotifySettings::MuteChange::Mute; + App::main()->updateNotifySettings(_peer, muteState); } void HistoryWidget::onBroadcastSilentChange() { @@ -3638,7 +3654,11 @@ bool HistoryWidget::readyToForward() const { } bool HistoryWidget::hasSilentToggle() const { - return _peer && _peer->isChannel() && !_peer->isMegagroup() && _peer->asChannel()->canPublish() && _peer->notify != UnknownNotifySettings; + return _peer + && _peer->isChannel() + && !_peer->isMegagroup() + && _peer->asChannel()->canPublish() + && !_peer->notifySettingsUnknown(); } void HistoryWidget::inlineBotResolveDone(const MTPcontacts_ResolvedPeer &result) { diff --git a/Telegram/SourceFiles/info/info_wrap_widget.cpp b/Telegram/SourceFiles/info/info_wrap_widget.cpp index fd54ce2067b06a..98854f4ea087be 100644 --- a/Telegram/SourceFiles/info/info_wrap_widget.cpp +++ b/Telegram/SourceFiles/info/info_wrap_widget.cpp @@ -357,7 +357,7 @@ void WrapWidget::addProfileMenuButton() { void WrapWidget::addProfileNotificationsButton() { Expects(_topBar != nullptr); - auto peer = _controller->peer(); + const auto peer = _controller->peer(); auto notifications = _topBar->addButton( base::make_unique_q( _topBar, @@ -365,18 +365,17 @@ void WrapWidget::addProfileNotificationsButton() { ? st::infoLayerTopBarNotifications : st::infoTopBarNotifications))); notifications->addClickHandler([peer] { - App::main()->updateNotifySetting( - peer, - peer->isMuted() - ? NotifySettingSetNotify - : NotifySettingSetMuted); + const auto muteState = peer->isMuted() + ? Data::NotifySettings::MuteChange::Unmute + : Data::NotifySettings::MuteChange::Mute; + App::main()->updateNotifySettings(peer, muteState); }); Profile::NotificationsEnabledValue(peer) | rpl::start_with_next([notifications](bool enabled) { - auto iconOverride = enabled + const auto iconOverride = enabled ? &st::infoNotificationsActive : nullptr; - auto rippleOverride = enabled + const auto rippleOverride = enabled ? &st::lightButtonBgOver : nullptr; notifications->setIconOverride(iconOverride, iconOverride); diff --git a/Telegram/SourceFiles/info/profile/info_profile_actions.cpp b/Telegram/SourceFiles/info/profile/info_profile_actions.cpp index ba18d3762749a8..c214b66d978baf 100644 --- a/Telegram/SourceFiles/info/profile/info_profile_actions.cpp +++ b/Telegram/SourceFiles/info/profile/info_profile_actions.cpp @@ -278,7 +278,7 @@ object_ptr DetailsFiller::setupInfo() { } object_ptr DetailsFiller::setupMuteToggle() { - auto peer = _peer; + const auto peer = _peer; auto result = object_ptr