Moved out data of notify settings to separated module.

This commit is contained in:
23rd 2022-04-01 13:18:07 +03:00 committed by John Preston
parent 5a3bbfbf62
commit 36bb23c54c
16 changed files with 380 additions and 286 deletions

View File

@ -395,6 +395,8 @@ PRIVATE
core/version.h
countries/countries_manager.cpp
countries/countries_manager.h
data/notify/data_notify_settings.cpp
data/notify/data_notify_settings.h
data/notify/data_peer_notify_settings.cpp
data/notify/data_peer_notify_settings.h
data/stickers/data_stickers_set.cpp

View File

@ -17,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "mtproto/mtp_instance.h"
#include "mtproto/mtproto_config.h"
#include "mtproto/mtproto_dc_options.h"
#include "data/notify/data_notify_settings.h"
#include "data/stickers/data_stickers.h"
#include "data/data_session.h"
#include "data/data_user.h"
@ -1906,7 +1907,9 @@ void Updates::feedUpdate(const MTPUpdate &update) {
case mtpc_updateNotifySettings: {
auto &d = update.c_updateNotifySettings();
session().data().applyNotifySetting(d.vpeer(), d.vnotify_settings());
session().data().notifySettings().applyNotifySetting(
d.vpeer(),
d.vnotify_settings());
} break;
case mtpc_updateDcOptions: {

View File

@ -27,6 +27,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "api/api_views.h"
#include "api/api_confirm_phone.h"
#include "api/api_unread_things.h"
#include "data/notify/data_notify_settings.h"
#include "data/stickers/data_stickers.h"
#include "data/data_drafts.h"
#include "data/data_changes.h"
@ -2089,22 +2090,23 @@ void ApiWrap::clearModifyRequest(const QString &key) {
void ApiWrap::applyNotifySettings(
MTPInputNotifyPeer notifyPeer,
const MTPPeerNotifySettings &settings) {
auto &notifySettings = _session->data().notifySettings();
switch (notifyPeer.type()) {
case mtpc_inputNotifyUsers:
_session->data().applyNotifySetting(MTP_notifyUsers(), settings);
notifySettings.applyNotifySetting(MTP_notifyUsers(), settings);
break;
case mtpc_inputNotifyChats:
_session->data().applyNotifySetting(MTP_notifyChats(), settings);
notifySettings.applyNotifySetting(MTP_notifyChats(), settings);
break;
case mtpc_inputNotifyBroadcasts:
_session->data().applyNotifySetting(
notifySettings.applyNotifySetting(
MTP_notifyBroadcasts(),
settings);
break;
case mtpc_inputNotifyPeer: {
auto &peer = notifyPeer.c_inputNotifyPeer().vpeer();
const auto apply = [&](PeerId peerId) {
_session->data().applyNotifySetting(
notifySettings.applyNotifySetting(
MTP_notifyPeer(peerToMTP(peerId)),
settings);
};

View File

@ -9,6 +9,7 @@ Copyright (C) 2017, Nicholas Guriev <guriev-ns@ya.ru>
#include "lang/lang_keys.h"
#include "main/main_session.h"
#include "data/notify/data_notify_settings.h"
#include "data/data_session.h"
#include "data/data_peer.h"
#include "ui/special_buttons.h"
@ -75,7 +76,7 @@ void MuteSettingsBox::prepare() {
_save = [=] {
const auto muteForSeconds = group->value() * 3600;
_peer->owner().updateNotifySettings(
_peer->owner().notifySettings().updateNotifySettings(
_peer,
muteForSeconds);
closeBox();

View File

@ -36,6 +36,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "passport/passport_form_controller.h"
#include "lang/lang_keys.h" // tr::lng_deleted(tr::now) in user name
#include "data/stickers/data_stickers.h"
#include "data/notify/data_notify_settings.h"
#include "data/data_changes.h"
#include "data/data_group_call.h"
#include "data/data_media_types.h"
@ -70,8 +71,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Data {
namespace {
constexpr auto kMaxNotifyCheckDelay = 24 * 3600 * crl::time(1000);
using ViewElement = HistoryView::Element;
// s: box 100x100
@ -232,7 +231,6 @@ Session::Session(not_null<Main::Session*> session)
, _ttlCheckTimer([=] { checkTTLs(); })
, _selfDestructTimer([=] { checkSelfDestructItems(); })
, _pollsClosingTimer([=] { checkPollsClosings(); })
, _unmuteByFinishedTimer([=] { unmuteByFinished(); })
, _groups(this)
, _chatsFilters(std::make_unique<ChatFilters>(this))
, _scheduledMessages(std::make_unique<ScheduledMessages>(this))
@ -243,7 +241,8 @@ Session::Session(not_null<Main::Session*> session)
, _histories(std::make_unique<Histories>(this))
, _stickers(std::make_unique<Stickers>(this))
, _sponsoredMessages(std::make_unique<SponsoredMessages>(this))
, _reactions(std::make_unique<Reactions>(this)) {
, _reactions(std::make_unique<Reactions>(this))
, _notifySettings(std::make_unique<NotifySettings>(this)) {
_cache->open(_session->local().cacheKey());
_bigFileCache->open(_session->local().cacheBigFileKey());
@ -2222,81 +2221,6 @@ Session::SentData Session::messageSentData(uint64 randomId) const {
return (i != end(_sentMessagesData)) ? i->second : SentData();
}
PeerNotifySettings &Session::defaultNotifySettings(
not_null<const PeerData*> peer) {
return peer->isUser()
? _defaultUserNotifySettings
: (peer->isChat() || peer->isMegagroup())
? _defaultChatNotifySettings
: _defaultBroadcastNotifySettings;
}
const PeerNotifySettings &Session::defaultNotifySettings(
not_null<const PeerData*> peer) const {
return peer->isUser()
? _defaultUserNotifySettings
: (peer->isChat() || peer->isMegagroup())
? _defaultChatNotifySettings
: _defaultBroadcastNotifySettings;
}
void Session::updateNotifySettingsLocal(not_null<PeerData*> peer) {
const auto history = historyLoaded(peer->id);
auto changesIn = crl::time(0);
const auto muted = notifyIsMuted(peer, &changesIn);
if (history && history->changeMute(muted)) {
// Notification already sent.
} else {
session().changes().peerUpdated(
peer,
PeerUpdate::Flag::Notifications);
}
if (muted) {
_mutedPeers.emplace(peer);
unmuteByFinishedDelayed(changesIn);
if (history) {
Core::App().notifications().clearIncomingFromHistory(history);
}
} else {
_mutedPeers.erase(peer);
}
}
void Session::unmuteByFinishedDelayed(crl::time delay) {
accumulate_min(delay, kMaxNotifyCheckDelay);
if (!_unmuteByFinishedTimer.isActive()
|| _unmuteByFinishedTimer.remainingTime() > delay) {
_unmuteByFinishedTimer.callOnce(delay);
}
}
void Session::unmuteByFinished() {
auto changesInMin = crl::time(0);
for (auto i = begin(_mutedPeers); i != end(_mutedPeers);) {
const auto history = historyLoaded((*i)->id);
auto changesIn = crl::time(0);
const auto muted = notifyIsMuted(*i, &changesIn);
if (muted) {
if (history) {
history->changeMute(true);
}
if (!changesInMin || changesInMin > changesIn) {
changesInMin = changesIn;
}
++i;
} else {
if (history) {
history->changeMute(false);
}
i = _mutedPeers.erase(i);
}
}
if (changesInMin) {
unmuteByFinishedDelayed(changesInMin);
}
}
HistoryItem *Session::addNewMessage(
const MTPMessage &data,
MessageFlags localFlags,
@ -3874,135 +3798,15 @@ auto Session::dialogsRowReplacements() const
return _dialogsRowReplacements.events();
}
void Session::requestNotifySettings(not_null<PeerData*> peer) {
if (peer->notifySettingsUnknown()) {
_session->api().requestNotifySettings(
MTP_inputNotifyPeer(peer->input));
}
if (defaultNotifySettings(peer).settingsUnknown()) {
_session->api().requestNotifySettings(peer->isUser()
? MTP_inputNotifyUsers()
: (peer->isChat() || peer->isMegagroup())
? MTP_inputNotifyChats()
: MTP_inputNotifyBroadcasts());
}
}
void Session::applyNotifySetting(
const MTPNotifyPeer &notifyPeer,
const MTPPeerNotifySettings &settings) {
const auto goodForUpdate = [&](
not_null<const PeerData*> peer,
const PeerNotifySettings &settings) {
return !peer->notifySettingsUnknown()
&& ((!peer->notifyMuteUntil() && settings.muteUntil())
|| (!peer->notifySilentPosts() && settings.silentPosts())
|| (!peer->notifySoundIsNone() && settings.soundIsNone()));
};
switch (notifyPeer.type()) {
case mtpc_notifyUsers: {
if (_defaultUserNotifySettings.change(settings)) {
_defaultUserNotifyUpdates.fire({});
enumerateUsers([&](not_null<UserData*> user) {
if (goodForUpdate(user, _defaultUserNotifySettings)) {
updateNotifySettingsLocal(user);
}
});
}
} break;
case mtpc_notifyChats: {
if (_defaultChatNotifySettings.change(settings)) {
_defaultChatNotifyUpdates.fire({});
enumerateGroups([&](not_null<PeerData*> peer) {
if (goodForUpdate(peer, _defaultChatNotifySettings)) {
updateNotifySettingsLocal(peer);
}
});
}
} break;
case mtpc_notifyBroadcasts: {
if (_defaultBroadcastNotifySettings.change(settings)) {
_defaultBroadcastNotifyUpdates.fire({});
enumerateChannels([&](not_null<ChannelData*> channel) {
if (goodForUpdate(channel, _defaultBroadcastNotifySettings)) {
updateNotifySettingsLocal(channel);
}
});
}
} break;
case mtpc_notifyPeer: {
const auto &data = notifyPeer.c_notifyPeer();
if (const auto peer = peerLoaded(peerFromMTP(data.vpeer()))) {
if (peer->notifyChange(settings)) {
updateNotifySettingsLocal(peer);
}
}
} break;
}
}
void Session::updateNotifySettings(
not_null<PeerData*> peer,
std::optional<int> muteForSeconds,
std::optional<bool> silentPosts,
std::optional<bool> soundIsNone) {
if (peer->notifyChange(muteForSeconds, silentPosts, soundIsNone)) {
updateNotifySettingsLocal(peer);
_session->api().updateNotifySettingsDelayed(peer);
}
}
void Session::resetNotifySettingsToDefault(not_null<PeerData*> peer) {
const auto empty = MTP_peerNotifySettings(
MTP_flags(0),
MTPBool(),
MTPBool(),
MTPint(),
MTPNotificationSound(),
MTPNotificationSound(),
MTPNotificationSound());
if (peer->notifyChange(empty)) {
updateNotifySettingsLocal(peer);
_session->api().updateNotifySettingsDelayed(peer);
}
}
bool Session::notifyIsMuted(not_null<const PeerData*> peer) const {
return notifyIsMuted(peer, nullptr);
}
bool Session::notifyIsMuted(
not_null<const PeerData*> peer,
crl::time *changesIn) const {
const auto resultFromUntil = [&](TimeId until) {
const auto now = base::unixtime::now();
const auto result = (until > now) ? (until - now) : 0;
if (changesIn) {
*changesIn = (result > 0)
? std::min(result * crl::time(1000), kMaxNotifyCheckDelay)
: kMaxNotifyCheckDelay;
}
return (result > 0);
};
if (const auto until = peer->notifyMuteUntil()) {
return resultFromUntil(*until);
}
const auto &settings = defaultNotifySettings(peer);
if (const auto until = settings.muteUntil()) {
return resultFromUntil(*until);
}
return true;
return notifySettings().notifyIsMuted(peer, nullptr);
}
bool Session::notifySilentPosts(not_null<const PeerData*> peer) const {
if (const auto silent = peer->notifySilentPosts()) {
return *silent;
}
const auto &settings = defaultNotifySettings(peer);
const auto &settings = notifySettings().defaultNotifySettings(peer);
if (const auto silent = settings.silentPosts()) {
return *silent;
}
@ -4013,7 +3817,7 @@ bool Session::notifySoundIsNone(not_null<const PeerData*> peer) const {
if (const auto soundIsNone = peer->notifySoundIsNone()) {
return *soundIsNone;
}
const auto &settings = defaultNotifySettings(peer);
const auto &settings = notifySettings().defaultNotifySettings(peer);
if (const auto soundIsNone = settings.soundIsNone()) {
return *soundIsNone;
}
@ -4026,7 +3830,7 @@ bool Session::notifyMuteUnknown(not_null<const PeerData*> peer) const {
} else if (const auto nonDefault = peer->notifyMuteUntil()) {
return false;
}
return defaultNotifySettings(peer).settingsUnknown();
return notifySettings().defaultNotifySettings(peer).settingsUnknown();
}
bool Session::notifySilentPostsUnknown(
@ -4036,7 +3840,7 @@ bool Session::notifySilentPostsUnknown(
} else if (const auto nonDefault = peer->notifySilentPosts()) {
return false;
}
return defaultNotifySettings(peer).settingsUnknown();
return notifySettings().defaultNotifySettings(peer).settingsUnknown();
}
bool Session::notifySoundIsNoneUnknown(not_null<const PeerData*> peer) const {
@ -4045,7 +3849,7 @@ bool Session::notifySoundIsNoneUnknown(not_null<const PeerData*> peer) const {
} else if (const auto nonDefault = peer->notifySoundIsNone()) {
return false;
}
return defaultNotifySettings(peer).settingsUnknown();
return notifySettings().defaultNotifySettings(peer).settingsUnknown();
}
bool Session::notifySettingsUnknown(not_null<const PeerData*> peer) const {
@ -4054,27 +3858,6 @@ bool Session::notifySettingsUnknown(not_null<const PeerData*> peer) const {
|| notifySoundIsNoneUnknown(peer);
}
rpl::producer<> Session::defaultUserNotifyUpdates() const {
return _defaultUserNotifyUpdates.events();
}
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()
: (peer->isChat() || peer->isMegagroup())
? defaultChatNotifyUpdates()
: defaultBroadcastNotifyUpdates();
}
void Session::serviceNotification(
const TextWithEntities &message,
const MTPMessageMedia &media) {

View File

@ -13,7 +13,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "dialogs/dialogs_main_list.h"
#include "data/data_groups.h"
#include "data/data_cloud_file.h"
#include "data/notify/data_peer_notify_settings.h"
#include "history/history_location_manager.h"
#include "base/timer.h"
#include "base/flags.h"
@ -62,6 +61,7 @@ class DocumentMedia;
class PhotoMedia;
class Stickers;
class GroupCall;
class NotifySettings;
class Session final {
public:
@ -117,6 +117,9 @@ public:
[[nodiscard]] Reactions &reactions() const {
return *_reactions;
}
[[nodiscard]] NotifySettings &notifySettings() const {
return *_notifySettings;
}
[[nodiscard]] MsgId nextNonHistoryEntryId() {
return ++_nonHistoryEntryId;
@ -659,16 +662,6 @@ public:
void dialogsRowReplaced(DialogsRowReplacement replacement);
rpl::producer<DialogsRowReplacement> dialogsRowReplacements() const;
void requestNotifySettings(not_null<PeerData*> peer);
void applyNotifySetting(
const MTPNotifyPeer &notifyPeer,
const MTPPeerNotifySettings &settings);
void updateNotifySettings(
not_null<PeerData*> peer,
std::optional<int> muteForSeconds,
std::optional<bool> silentPosts = std::nullopt,
std::optional<bool> soundIsNone = std::nullopt);
void resetNotifySettingsToDefault(not_null<PeerData*> peer);
bool notifyIsMuted(not_null<const PeerData*> peer) const;
bool notifySilentPosts(not_null<const PeerData*> peer) const;
bool notifySoundIsNone(not_null<const PeerData*> peer) const;
@ -676,11 +669,6 @@ public:
bool notifySilentPostsUnknown(not_null<const PeerData*> peer) const;
bool notifySoundIsNoneUnknown(not_null<const PeerData*> peer) const;
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;
void serviceNotification(
const TextWithEntities &message,
@ -712,10 +700,6 @@ public:
private:
using Messages = std::unordered_map<MsgId, not_null<HistoryItem*>>;
bool notifyIsMuted(
not_null<const PeerData*> peer,
crl::time *changesIn) const;
void suggestStartExport();
void setupMigrationViewer();
@ -822,13 +806,6 @@ private:
void setPinnedFromDialog(const Dialogs::Key &key, bool pinned);
PeerNotifySettings &defaultNotifySettings(not_null<const PeerData*> peer);
const PeerNotifySettings &defaultNotifySettings(
not_null<const PeerData*> peer) const;
void unmuteByFinished();
void unmuteByFinishedDelayed(crl::time delay);
void updateNotifySettingsLocal(not_null<PeerData*> peer);
template <typename Method>
void enumerateItemViews(
not_null<const HistoryItem*> item,
@ -976,15 +953,6 @@ private:
History *_topPromoted = nullptr;
PeerNotifySettings _defaultUserNotifySettings;
PeerNotifySettings _defaultChatNotifySettings;
PeerNotifySettings _defaultBroadcastNotifySettings;
rpl::event_stream<> _defaultUserNotifyUpdates;
rpl::event_stream<> _defaultChatNotifyUpdates;
rpl::event_stream<> _defaultBroadcastNotifyUpdates;
std::unordered_set<not_null<const PeerData*>> _mutedPeers;
base::Timer _unmuteByFinishedTimer;
std::unordered_map<PeerId, std::unique_ptr<PeerData>> _peers;
MessageIdsList _mimeForwardIds;
@ -1010,6 +978,7 @@ private:
const std::unique_ptr<Stickers> _stickers;
std::unique_ptr<SponsoredMessages> _sponsoredMessages;
const std::unique_ptr<Reactions> _reactions;
const std::unique_ptr<NotifySettings> _notifySettings;
MsgId _nonHistoryEntryId = ServerMaxMsgId.bare + ScheduledMsgIdsRange;

View File

@ -0,0 +1,253 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "data/notify/data_notify_settings.h"
#include "apiwrap.h"
#include "base/unixtime.h"
#include "core/application.h"
#include "data/data_changes.h"
#include "data/data_channel.h"
#include "data/data_chat.h"
#include "data/data_peer.h"
#include "data/data_session.h"
#include "data/data_user.h"
#include "history/history.h"
#include "main/main_session.h"
#include "window/notifications_manager.h"
namespace Data {
namespace {
constexpr auto kMaxNotifyCheckDelay = 24 * 3600 * crl::time(1000);
} // namespace
NotifySettings::NotifySettings(not_null<Session*> owner)
: _owner(owner)
, _unmuteByFinishedTimer([=] { unmuteByFinished(); }) {
}
void NotifySettings::requestNotifySettings(not_null<PeerData*> peer) {
if (peer->notifySettingsUnknown()) {
peer->session().api().requestNotifySettings(
MTP_inputNotifyPeer(peer->input));
}
if (defaultNotifySettings(peer).settingsUnknown()) {
peer->session().api().requestNotifySettings(peer->isUser()
? MTP_inputNotifyUsers()
: (peer->isChat() || peer->isMegagroup())
? MTP_inputNotifyChats()
: MTP_inputNotifyBroadcasts());
}
}
void NotifySettings::applyNotifySetting(
const MTPNotifyPeer &notifyPeer,
const MTPPeerNotifySettings &settings) {
const auto goodForUpdate = [&](
not_null<const PeerData*> peer,
const PeerNotifySettings &settings) {
return !peer->notifySettingsUnknown()
&& ((!peer->notifyMuteUntil() && settings.muteUntil())
|| (!peer->notifySilentPosts() && settings.silentPosts())
|| (!peer->notifySoundIsNone() && settings.soundIsNone()));
};
switch (notifyPeer.type()) {
case mtpc_notifyUsers: {
if (_defaultUserNotifySettings.change(settings)) {
_defaultUserNotifyUpdates.fire({});
_owner->enumerateUsers([&](not_null<UserData*> user) {
if (goodForUpdate(user, _defaultUserNotifySettings)) {
updateNotifySettingsLocal(user);
}
});
}
} break;
case mtpc_notifyChats: {
if (_defaultChatNotifySettings.change(settings)) {
_defaultChatNotifyUpdates.fire({});
_owner->enumerateGroups([&](not_null<PeerData*> peer) {
if (goodForUpdate(peer, _defaultChatNotifySettings)) {
updateNotifySettingsLocal(peer);
}
});
}
} break;
case mtpc_notifyBroadcasts: {
if (_defaultBroadcastNotifySettings.change(settings)) {
_defaultBroadcastNotifyUpdates.fire({});
_owner->enumerateChannels([&](not_null<ChannelData*> channel) {
if (goodForUpdate(channel, _defaultBroadcastNotifySettings)) {
updateNotifySettingsLocal(channel);
}
});
}
} break;
case mtpc_notifyPeer: {
const auto &data = notifyPeer.c_notifyPeer();
if (const auto peer = _owner->peerLoaded(peerFromMTP(data.vpeer()))) {
if (peer->notifyChange(settings)) {
updateNotifySettingsLocal(peer);
}
}
} break;
}
}
void NotifySettings::updateNotifySettings(
not_null<PeerData*> peer,
std::optional<int> muteForSeconds,
std::optional<bool> silentPosts,
std::optional<bool> soundIsNone) {
if (peer->notifyChange(muteForSeconds, silentPosts, soundIsNone)) {
updateNotifySettingsLocal(peer);
peer->session().api().updateNotifySettingsDelayed(peer);
}
}
void NotifySettings::resetNotifySettingsToDefault(not_null<PeerData*> peer) {
const auto empty = MTP_peerNotifySettings(
MTP_flags(0),
MTPBool(),
MTPBool(),
MTPint(),
MTPNotificationSound(),
MTPNotificationSound(),
MTPNotificationSound());
if (peer->notifyChange(empty)) {
updateNotifySettingsLocal(peer);
peer->session().api().updateNotifySettingsDelayed(peer);
}
}
PeerNotifySettings &NotifySettings::defaultNotifySettings(
not_null<const PeerData*> peer) {
return peer->isUser()
? _defaultUserNotifySettings
: (peer->isChat() || peer->isMegagroup())
? _defaultChatNotifySettings
: _defaultBroadcastNotifySettings;
}
const PeerNotifySettings &NotifySettings::defaultNotifySettings(
not_null<const PeerData*> peer) const {
return peer->isUser()
? _defaultUserNotifySettings
: (peer->isChat() || peer->isMegagroup())
? _defaultChatNotifySettings
: _defaultBroadcastNotifySettings;
}
void NotifySettings::updateNotifySettingsLocal(not_null<PeerData*> peer) {
const auto history = _owner->historyLoaded(peer->id);
auto changesIn = crl::time(0);
const auto muted = notifyIsMuted(peer, &changesIn);
if (history && history->changeMute(muted)) {
// Notification already sent.
} else {
peer->session().changes().peerUpdated(
peer,
PeerUpdate::Flag::Notifications);
}
if (muted) {
_mutedPeers.emplace(peer);
unmuteByFinishedDelayed(changesIn);
if (history) {
Core::App().notifications().clearIncomingFromHistory(history);
}
} else {
_mutedPeers.erase(peer);
}
}
void NotifySettings::unmuteByFinishedDelayed(crl::time delay) {
accumulate_min(delay, kMaxNotifyCheckDelay);
if (!_unmuteByFinishedTimer.isActive()
|| _unmuteByFinishedTimer.remainingTime() > delay) {
_unmuteByFinishedTimer.callOnce(delay);
}
}
void NotifySettings::unmuteByFinished() {
auto changesInMin = crl::time(0);
for (auto i = begin(_mutedPeers); i != end(_mutedPeers);) {
const auto history = _owner->historyLoaded((*i)->id);
auto changesIn = crl::time(0);
const auto muted = notifyIsMuted(*i, &changesIn);
if (muted) {
if (history) {
history->changeMute(true);
}
if (!changesInMin || changesInMin > changesIn) {
changesInMin = changesIn;
}
++i;
} else {
if (history) {
history->changeMute(false);
}
i = _mutedPeers.erase(i);
}
}
if (changesInMin) {
unmuteByFinishedDelayed(changesInMin);
}
}
bool NotifySettings::notifyIsMuted(
not_null<const PeerData*> peer,
crl::time *changesIn) const {
const auto resultFromUntil = [&](TimeId until) {
const auto now = base::unixtime::now();
const auto result = (until > now) ? (until - now) : 0;
if (changesIn) {
*changesIn = (result > 0)
? std::min(result * crl::time(1000), kMaxNotifyCheckDelay)
: kMaxNotifyCheckDelay;
}
return (result > 0);
};
if (const auto until = peer->notifyMuteUntil()) {
return resultFromUntil(*until);
}
const auto &settings = defaultNotifySettings(peer);
if (const auto until = settings.muteUntil()) {
return resultFromUntil(*until);
}
return true;
}
rpl::producer<> NotifySettings::defaultUserNotifyUpdates() const {
return _defaultUserNotifyUpdates.events();
}
rpl::producer<> NotifySettings::defaultChatNotifyUpdates() const {
return _defaultChatNotifyUpdates.events();
}
rpl::producer<> NotifySettings::defaultBroadcastNotifyUpdates() const {
return _defaultBroadcastNotifyUpdates.events();
}
rpl::producer<> NotifySettings::defaultNotifyUpdates(
not_null<const PeerData*> peer) const {
return peer->isUser()
? defaultUserNotifyUpdates()
: (peer->isChat() || peer->isMegagroup())
? defaultChatNotifyUpdates()
: defaultBroadcastNotifyUpdates();
}
} // namespace Data

View File

@ -0,0 +1,67 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "data/notify/data_peer_notify_settings.h"
#include "base/timer.h"
class PeerData;
namespace Data {
class Session;
class NotifySettings final {
public:
NotifySettings(not_null<Session*> owner);
void requestNotifySettings(not_null<PeerData*> peer);
void applyNotifySetting(
const MTPNotifyPeer &notifyPeer,
const MTPPeerNotifySettings &settings);
void updateNotifySettings(
not_null<PeerData*> peer,
std::optional<int> muteForSeconds,
std::optional<bool> silentPosts = std::nullopt,
std::optional<bool> soundIsNone = std::nullopt);
void resetNotifySettingsToDefault(not_null<PeerData*> peer);
[[nodiscard]] rpl::producer<> defaultUserNotifyUpdates() const;
[[nodiscard]] rpl::producer<> defaultChatNotifyUpdates() const;
[[nodiscard]] rpl::producer<> defaultBroadcastNotifyUpdates() const;
[[nodiscard]] rpl::producer<> defaultNotifyUpdates(
not_null<const PeerData*> peer) const;
[[nodiscard]] bool notifyIsMuted(
not_null<const PeerData*> peer,
crl::time *changesIn) const;
[[nodiscard]] PeerNotifySettings &defaultNotifySettings(
not_null<const PeerData*> peer);
[[nodiscard]] const PeerNotifySettings &defaultNotifySettings(
not_null<const PeerData*> peer) const;
private:
void unmuteByFinished();
void unmuteByFinishedDelayed(crl::time delay);
void updateNotifySettingsLocal(not_null<PeerData*> peer);
const not_null<Session*> _owner;
PeerNotifySettings _defaultUserNotifySettings;
PeerNotifySettings _defaultChatNotifySettings;
PeerNotifySettings _defaultBroadcastNotifySettings;
rpl::event_stream<> _defaultUserNotifyUpdates;
rpl::event_stream<> _defaultChatNotifyUpdates;
rpl::event_stream<> _defaultBroadcastNotifyUpdates;
std::unordered_set<not_null<const PeerData*>> _mutedPeers;
base::Timer _unmuteByFinishedTimer;
};
} // namespace Data

View File

@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/history_inner_widget.h"
#include "history/history_unread_things.h"
#include "dialogs/dialogs_indexed_list.h"
#include "data/notify/data_notify_settings.h"
#include "data/stickers/data_stickers.h"
#include "data/data_drafts.h"
#include "data/data_session.h"
@ -2553,7 +2554,7 @@ void History::applyDialog(
}
}
}
owner().applyNotifySetting(
owner().notifySettings().applyNotifySetting(
MTP_notifyPeer(data.vpeer()),
data.vnotify_settings());

View File

@ -52,6 +52,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/qt/qt_key_modifiers.h"
#include "base/unixtime.h"
#include "base/call_delayed.h"
#include "data/notify/data_notify_settings.h"
#include "data/data_changes.h"
#include "data/data_drafts.h"
#include "data/data_session.h"
@ -789,9 +790,9 @@ HistoryWidget::HistoryWidget(
}, lifetime());
rpl::merge(
session().data().defaultUserNotifyUpdates(),
session().data().defaultChatNotifyUpdates(),
session().data().defaultBroadcastNotifyUpdates()
session().data().notifySettings().defaultUserNotifyUpdates(),
session().data().notifySettings().defaultChatNotifyUpdates(),
session().data().notifySettings().defaultBroadcastNotifyUpdates()
) | rpl::start_with_next([=] {
updateNotifyControls();
}, lifetime());
@ -2237,7 +2238,7 @@ void HistoryWidget::showHistory(
if (_peer->isChannel()) {
updateNotifyControls();
session().data().requestNotifySettings(_peer);
session().data().notifySettings().requestNotifySettings(_peer);
refreshSilentToggle();
} else if (_peer->isRepliesChat()) {
updateNotifyControls();
@ -3850,7 +3851,9 @@ void HistoryWidget::toggleMuteUnmute() {
const auto muteForSeconds = _history->mute()
? 0
: Data::PeerNotifySettings::kDefaultMutePeriod;
session().data().updateNotifySettings(_peer, muteForSeconds);
session().data().notifySettings().updateNotifySettings(
_peer,
muteForSeconds);
}
void HistoryWidget::reportSelectedMessages() {

View File

@ -17,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/text/text_utilities.h"
#include "ui/boxes/confirm_box.h"
#include "ui/layers/generic_box.h"
#include "data/notify/data_notify_settings.h"
#include "data/data_peer.h"
#include "data/data_user.h"
#include "data/data_chat.h"
@ -473,7 +474,7 @@ void ContactStatus::setupUnarchiveHandler(not_null<PeerData*> peer) {
_bar.entity()->unarchiveClicks(
) | rpl::start_with_next([=] {
Window::ToggleHistoryArchived(peer->owner().history(peer), false);
peer->owner().resetNotifySettingsToDefault(peer);
peer->owner().notifySettings().resetNotifySettingsToDefault(peer);
if (const auto settings = peer->settings()) {
const auto flags = PeerSetting::AutoArchived
| PeerSetting::BlockContact

View File

@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/text/format_values.h" // Ui::FormatPhone
#include "ui/text/text_utilities.h"
#include "lang/lang_keys.h"
#include "data/notify/data_notify_settings.h"
#include "data/data_peer_values.h"
#include "data/data_shared_media.h"
#include "data/data_message_reactions.h"
@ -171,7 +172,7 @@ rpl::producer<bool> NotificationsEnabledValue(not_null<PeerData*> peer) {
peer,
UpdateFlag::Notifications
) | rpl::to_empty,
peer->owner().defaultNotifyUpdates(peer)
peer->owner().notifySettings().defaultNotifyUpdates(peer)
) | rpl::map([=] {
return !peer->owner().notifyIsMuted(peer);
}) | rpl::distinct_until_changed();

View File

@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "menu/menu_mute.h"
#include "data/notify/data_notify_settings.h"
#include "data/data_peer.h"
#include "data/data_session.h"
#include "info/profile/info_profile_values.h"
@ -77,7 +78,7 @@ MuteItem::MuteItem(
}, lifetime());
setClickedCallback([=] {
peer->owner().updateNotifySettings(
peer->owner().notifySettings().updateNotifySettings(
peer,
_isMuted ? 0 : Data::PeerNotifySettings::kDefaultMutePeriod);
});
@ -119,7 +120,9 @@ void MuteBox(not_null<Ui::GenericBox*> box, not_null<PeerData*> peer) {
: tr::lng_mute_menu_mute();
}) | rpl::flatten_latest();
const auto confirm = box->addButton(std::move(confirmText), [=] {
peer->owner().updateNotifySettings(peer, state->lastSeconds);
peer->owner().notifySettings().updateNotifySettings(
peer,
state->lastSeconds);
box->closeBox();
});
box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
@ -139,7 +142,8 @@ void FillMuteMenu(
: tr::lng_mute_menu_sound_off(tr::now),
[=] {
const auto soundIsNone = peer->owner().notifySoundIsNone(peer);
peer->owner().updateNotifySettings(peer, {}, {}, !soundIsNone);
auto &notifySettings = peer->owner().notifySettings();
notifySettings.updateNotifySettings(peer, {}, {}, !soundIsNone);
},
soundIsNone ? &st::menuIconSoundOn : &st::menuIconSoundOff);

View File

@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/image/image_prepare.h"
#include "ui/empty_userpic.h"
#include "ui/ui_utility.h"
#include "data/notify/data_notify_settings.h"
#include "data/data_photo.h"
#include "data/data_session.h"
#include "data/data_folder.h"
@ -864,7 +865,7 @@ void SilentToggle::mouseReleaseEvent(QMouseEvent *e) {
setChecked(!_checked);
RippleButton::mouseReleaseEvent(e);
Ui::Tooltip::Show(0, this);
_channel->owner().updateNotifySettings(
_channel->owner().notifySettings().updateNotifySettings(
_channel,
std::nullopt,
_checked);

View File

@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/history.h"
#include "history/history_item_components.h"
#include "lang/lang_keys.h"
#include "data/notify/data_notify_settings.h"
#include "data/data_session.h"
#include "data/data_channel.h"
#include "data/data_user.h"
@ -196,12 +197,13 @@ System::SkipState System::computeSkipState(
}
if (messageNotification) {
history->owner().requestNotifySettings(history->peer);
history->owner().notifySettings().requestNotifySettings(
history->peer);
} else if (notifyBy->blockStatus() == PeerData::BlockStatus::Unknown) {
notifyBy->updateFull();
}
if (notifyBy) {
history->owner().requestNotifySettings(notifyBy);
history->owner().notifySettings().requestNotifySettings(notifyBy);
}
if (messageNotification

View File

@ -52,6 +52,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "info/info_memento.h"
#include "info/info_controller.h"
#include "info/profile/info_profile_values.h"
#include "data/notify/data_notify_settings.h"
#include "data/data_changes.h"
#include "data/data_session.h"
#include "data/data_folder.h"
@ -130,7 +131,7 @@ void PeerMenuAddMuteSubmenuAction(
not_null<Window::SessionController*> controller,
not_null<PeerData*> peer,
const PeerMenuCallback &addAction) {
peer->owner().requestNotifySettings(peer);
peer->owner().notifySettings().requestNotifySettings(peer);
const auto isMuted = peer->owner().notifyIsMuted(peer);
if (isMuted) {
const auto text = tr::lng_context_unmute(tr::now)
@ -138,7 +139,7 @@ void PeerMenuAddMuteSubmenuAction(
+ Ui::FormatMuteForTiny(peer->notifyMuteUntil().value_or(0)
- base::unixtime::now());
addAction(text, [=] {
peer->owner().updateNotifySettings(peer, 0);
peer->owner().notifySettings().updateNotifySettings(peer, 0);
}, &st::menuIconUnmute);
} else {
const auto show = std::make_shared<Window::Show>(controller);
@ -1422,7 +1423,7 @@ void PeerMenuAddMuteAction(
not_null<PeerData*> peer,
const PeerMenuCallback &addAction) {
// There is no async to make weak from controller.
peer->owner().requestNotifySettings(peer);
peer->owner().notifySettings().requestNotifySettings(peer);
const auto muteText = [](bool isUnmuted) {
return isUnmuted
? tr::lng_context_mute(tr::now)
@ -1434,7 +1435,7 @@ void PeerMenuAddMuteAction(
Box<MuteSettingsBox>(peer),
Ui::LayerOption::CloseOther);
} else {
peer->owner().updateNotifySettings(peer, 0);
peer->owner().notifySettings().updateNotifySettings(peer, 0);
}
}, (peer->owner().notifyIsMuted(peer)
? &st::menuIconUnmute