mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Allow editing general notification sound.
This commit is contained in:
parent
c71ba2b8e7
commit
0615f21deb
11 changed files with 210 additions and 102 deletions
|
@ -354,6 +354,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_settings_notifications_position" = "Location on the screen";
|
"lng_settings_notifications_position" = "Location on the screen";
|
||||||
"lng_settings_notifications_count" = "Notifications count";
|
"lng_settings_notifications_count" = "Notifications count";
|
||||||
"lng_settings_sound_notify" = "Play sound";
|
"lng_settings_sound_notify" = "Play sound";
|
||||||
|
"lng_settings_sound_notify_off" = "Off";
|
||||||
"lng_settings_alert_windows" = "Flash the taskbar icon";
|
"lng_settings_alert_windows" = "Flash the taskbar icon";
|
||||||
"lng_settings_alert_mac" = "Bounce the dock icon";
|
"lng_settings_alert_mac" = "Bounce the dock icon";
|
||||||
"lng_settings_alert_linux" = "Draw attention to the window";
|
"lng_settings_alert_linux" = "Draw attention to the window";
|
||||||
|
|
|
@ -1763,6 +1763,11 @@ void ApiWrap::updateNotifySettingsDelayed(not_null<const PeerData*> peer) {
|
||||||
_updateNotifySettingsTimer.callOnce(kNotifySettingSaveTimeout);
|
_updateNotifySettingsTimer.callOnce(kNotifySettingSaveTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ApiWrap::updateDefaultNotifySettingsDelayed(Data::DefaultNotify type) {
|
||||||
|
_updateNotifySettingsDefaults.emplace(type);
|
||||||
|
_updateNotifySettingsTimer.callOnce(kNotifySettingSaveTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
void ApiWrap::sendNotifySettingsUpdates() {
|
void ApiWrap::sendNotifySettingsUpdates() {
|
||||||
while (!_updateNotifySettingsPeers.empty()) {
|
while (!_updateNotifySettingsPeers.empty()) {
|
||||||
const auto peer = *_updateNotifySettingsPeers.begin();
|
const auto peer = *_updateNotifySettingsPeers.begin();
|
||||||
|
@ -1772,6 +1777,25 @@ void ApiWrap::sendNotifySettingsUpdates() {
|
||||||
peer->notifySerialize()
|
peer->notifySerialize()
|
||||||
)).afterDelay(_updateNotifySettingsPeers.empty() ? 0 : 10).send();
|
)).afterDelay(_updateNotifySettingsPeers.empty() ? 0 : 10).send();
|
||||||
}
|
}
|
||||||
|
const auto &settings = session().data().notifySettings();
|
||||||
|
while (!_updateNotifySettingsDefaults.empty()) {
|
||||||
|
const auto type = *_updateNotifySettingsDefaults.begin();
|
||||||
|
_updateNotifySettingsDefaults.erase(
|
||||||
|
_updateNotifySettingsDefaults.begin());
|
||||||
|
const auto input = [&] {
|
||||||
|
switch (type) {
|
||||||
|
case Data::DefaultNotify::User: return MTP_inputNotifyUsers();
|
||||||
|
case Data::DefaultNotify::Group: return MTP_inputNotifyChats();
|
||||||
|
case Data::DefaultNotify::Broadcast:
|
||||||
|
return MTP_inputNotifyBroadcasts();
|
||||||
|
}
|
||||||
|
Unexpected("Default notify type in sendNotifySettingsUpdates");
|
||||||
|
}();
|
||||||
|
request(MTPaccount_UpdateNotifySettings(
|
||||||
|
input,
|
||||||
|
settings.defaultSettings(type).serialize()
|
||||||
|
)).afterDelay(_updateNotifySettingsDefaults.empty() ? 0 : 10).send();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApiWrap::saveDraftToCloudDelayed(not_null<History*> history) {
|
void ApiWrap::saveDraftToCloudDelayed(not_null<History*> history) {
|
||||||
|
|
|
@ -30,6 +30,7 @@ namespace Data {
|
||||||
struct UpdatedFileReferences;
|
struct UpdatedFileReferences;
|
||||||
class WallPaper;
|
class WallPaper;
|
||||||
struct ResolvedForwardDraft;
|
struct ResolvedForwardDraft;
|
||||||
|
enum class DefaultNotify;
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
||||||
namespace InlineBots {
|
namespace InlineBots {
|
||||||
|
@ -239,6 +240,7 @@ public:
|
||||||
|
|
||||||
void requestNotifySettings(const MTPInputNotifyPeer &peer);
|
void requestNotifySettings(const MTPInputNotifyPeer &peer);
|
||||||
void updateNotifySettingsDelayed(not_null<const PeerData*> peer);
|
void updateNotifySettingsDelayed(not_null<const PeerData*> peer);
|
||||||
|
void updateDefaultNotifySettingsDelayed(Data::DefaultNotify type);
|
||||||
void saveDraftToCloudDelayed(not_null<History*> history);
|
void saveDraftToCloudDelayed(not_null<History*> history);
|
||||||
|
|
||||||
static int OnlineTillFromStatus(
|
static int OnlineTillFromStatus(
|
||||||
|
@ -595,6 +597,7 @@ private:
|
||||||
base::Timer _topPromotionTimer;
|
base::Timer _topPromotionTimer;
|
||||||
|
|
||||||
base::flat_set<not_null<const PeerData*>> _updateNotifySettingsPeers;
|
base::flat_set<not_null<const PeerData*>> _updateNotifySettingsPeers;
|
||||||
|
base::flat_set<Data::DefaultNotify> _updateNotifySettingsDefaults;
|
||||||
base::Timer _updateNotifySettingsTimer;
|
base::Timer _updateNotifySettingsTimer;
|
||||||
|
|
||||||
std::map<
|
std::map<
|
||||||
|
|
|
@ -951,7 +951,7 @@ void Session::enumerateGroups(Fn<void(not_null<PeerData*>)> action) const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::enumerateChannels(
|
void Session::enumerateBroadcasts(
|
||||||
Fn<void(not_null<ChannelData*>)> action) const {
|
Fn<void(not_null<ChannelData*>)> action) const {
|
||||||
for (const auto &[peerId, peer] : _peers) {
|
for (const auto &[peerId, peer] : _peers) {
|
||||||
if (const auto channel = peer->asChannel()) {
|
if (const auto channel = peer->asChannel()) {
|
||||||
|
|
|
@ -192,7 +192,7 @@ public:
|
||||||
|
|
||||||
void enumerateUsers(Fn<void(not_null<UserData*>)> action) const;
|
void enumerateUsers(Fn<void(not_null<UserData*>)> action) const;
|
||||||
void enumerateGroups(Fn<void(not_null<PeerData*>)> action) const;
|
void enumerateGroups(Fn<void(not_null<PeerData*>)> action) const;
|
||||||
void enumerateChannels(Fn<void(not_null<ChannelData*>)> action) const;
|
void enumerateBroadcasts(Fn<void(not_null<ChannelData*>)> action) const;
|
||||||
[[nodiscard]] UserData *userByPhone(const QString &phone) const;
|
[[nodiscard]] UserData *userByPhone(const QString &phone) const;
|
||||||
[[nodiscard]] PeerData *peerByUsername(const QString &username) const;
|
[[nodiscard]] PeerData *peerByUsername(const QString &username) const;
|
||||||
|
|
||||||
|
|
|
@ -33,8 +33,8 @@ constexpr auto kMaxNotifyCheckDelay = 24 * 3600 * crl::time(1000);
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
NotifySettings::NotifySettings(not_null<Session*> owner)
|
NotifySettings::NotifySettings(not_null<Session*> owner)
|
||||||
: _owner(owner)
|
: _owner(owner)
|
||||||
, _unmuteByFinishedTimer([=] { unmuteByFinished(); }) {
|
, _unmuteByFinishedTimer([=] { unmuteByFinished(); }) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotifySettings::request(not_null<PeerData*> peer) {
|
void NotifySettings::request(not_null<PeerData*> peer) {
|
||||||
|
@ -42,7 +42,7 @@ void NotifySettings::request(not_null<PeerData*> peer) {
|
||||||
peer->session().api().requestNotifySettings(
|
peer->session().api().requestNotifySettings(
|
||||||
MTP_inputNotifyPeer(peer->input));
|
MTP_inputNotifyPeer(peer->input));
|
||||||
}
|
}
|
||||||
if (defaultNotifySettings(peer).settingsUnknown()) {
|
if (defaultSettings(peer).settingsUnknown()) {
|
||||||
peer->session().api().requestNotifySettings(peer->isUser()
|
peer->session().api().requestNotifySettings(peer->isUser()
|
||||||
? MTP_inputNotifyUsers()
|
? MTP_inputNotifyUsers()
|
||||||
: (peer->isChat() || peer->isMegagroup())
|
: (peer->isChat() || peer->isMegagroup())
|
||||||
|
@ -54,49 +54,15 @@ void NotifySettings::request(not_null<PeerData*> peer) {
|
||||||
void NotifySettings::apply(
|
void NotifySettings::apply(
|
||||||
const MTPNotifyPeer ¬ifyPeer,
|
const MTPNotifyPeer ¬ifyPeer,
|
||||||
const MTPPeerNotifySettings &settings) {
|
const MTPPeerNotifySettings &settings) {
|
||||||
const auto goodForUpdate = [&](
|
const auto set = [&](DefaultNotify type) {
|
||||||
not_null<const PeerData*> peer,
|
if (defaultValue(type).settings.change(settings)) {
|
||||||
const PeerNotifySettings &settings) {
|
updateLocal(type);
|
||||||
return !peer->notifySettingsUnknown()
|
}
|
||||||
&& ((!peer->notifyMuteUntil() && settings.muteUntil())
|
|
||||||
|| (!peer->notifySilentPosts() && settings.silentPosts())
|
|
||||||
|| (!peer->notifySound() && settings.sound()));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
switch (notifyPeer.type()) {
|
switch (notifyPeer.type()) {
|
||||||
case mtpc_notifyUsers: {
|
case mtpc_notifyUsers: set(DefaultNotify::User); break;
|
||||||
if (_defaultUser.change(settings)) {
|
case mtpc_notifyChats: set(DefaultNotify::Group); break;
|
||||||
_defaultUserUpdates.fire({});
|
case mtpc_notifyBroadcasts: set(DefaultNotify::Broadcast); break;
|
||||||
|
|
||||||
_owner->enumerateUsers([&](not_null<UserData*> user) {
|
|
||||||
if (goodForUpdate(user, _defaultUser)) {
|
|
||||||
updateLocal(user);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
case mtpc_notifyChats: {
|
|
||||||
if (_defaultChat.change(settings)) {
|
|
||||||
_defaultChatUpdates.fire({});
|
|
||||||
|
|
||||||
_owner->enumerateGroups([&](not_null<PeerData*> peer) {
|
|
||||||
if (goodForUpdate(peer, _defaultChat)) {
|
|
||||||
updateLocal(peer);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
case mtpc_notifyBroadcasts: {
|
|
||||||
if (_defaultBroadcast.change(settings)) {
|
|
||||||
_defaultBroadcastUpdates.fire({});
|
|
||||||
|
|
||||||
_owner->enumerateChannels([&](not_null<ChannelData*> channel) {
|
|
||||||
if (goodForUpdate(channel, _defaultBroadcast)) {
|
|
||||||
updateLocal(channel);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
case mtpc_notifyPeer: {
|
case mtpc_notifyPeer: {
|
||||||
const auto &data = notifyPeer.c_notifyPeer();
|
const auto &data = notifyPeer.c_notifyPeer();
|
||||||
if (const auto peer = _owner->peerLoaded(peerFromMTP(data.vpeer()))) {
|
if (const auto peer = _owner->peerLoaded(peerFromMTP(data.vpeer()))) {
|
||||||
|
@ -134,13 +100,44 @@ void NotifySettings::resetToDefault(not_null<PeerData*> peer) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const PeerNotifySettings &NotifySettings::defaultNotifySettings(
|
auto NotifySettings::defaultValue(DefaultNotify type)
|
||||||
|
-> DefaultValue & {
|
||||||
|
const auto index = static_cast<int>(type);
|
||||||
|
Assert(index >= 0 && index < base::array_size(_defaultValues));
|
||||||
|
return _defaultValues[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
auto NotifySettings::defaultValue(DefaultNotify type) const
|
||||||
|
-> const DefaultValue & {
|
||||||
|
const auto index = static_cast<int>(type);
|
||||||
|
Assert(index >= 0 && index < base::array_size(_defaultValues));
|
||||||
|
return _defaultValues[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
const PeerNotifySettings &NotifySettings::defaultSettings(
|
||||||
not_null<const PeerData*> peer) const {
|
not_null<const PeerData*> peer) const {
|
||||||
return peer->isUser()
|
return defaultSettings(peer->isUser()
|
||||||
? _defaultUser
|
? DefaultNotify::User
|
||||||
: (peer->isChat() || peer->isMegagroup())
|
: (peer->isChat() || peer->isMegagroup())
|
||||||
? _defaultChat
|
? DefaultNotify::Group
|
||||||
: _defaultBroadcast;
|
: DefaultNotify::Broadcast);
|
||||||
|
}
|
||||||
|
|
||||||
|
const PeerNotifySettings &NotifySettings::defaultSettings(
|
||||||
|
DefaultNotify type) const {
|
||||||
|
return defaultValue(type).settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotifySettings::defaultUpdate(
|
||||||
|
DefaultNotify type,
|
||||||
|
std::optional<int> muteForSeconds,
|
||||||
|
std::optional<bool> silentPosts,
|
||||||
|
std::optional<NotifySound> sound) {
|
||||||
|
auto &settings = defaultValue(type).settings;
|
||||||
|
if (settings.change(muteForSeconds, silentPosts, sound)) {
|
||||||
|
updateLocal(type);
|
||||||
|
_owner->session().api().updateDefaultNotifySettingsDelayed(type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotifySettings::updateLocal(not_null<PeerData*> peer) {
|
void NotifySettings::updateLocal(not_null<PeerData*> peer) {
|
||||||
|
@ -193,6 +190,32 @@ void NotifySettings::updateLocal(not_null<PeerData*> peer) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NotifySettings::updateLocal(DefaultNotify type) {
|
||||||
|
defaultValue(type).updates.fire({});
|
||||||
|
|
||||||
|
const auto goodForUpdate = [&](
|
||||||
|
not_null<const PeerData*> peer,
|
||||||
|
const PeerNotifySettings &settings) {
|
||||||
|
return !peer->notifySettingsUnknown()
|
||||||
|
&& ((!peer->notifyMuteUntil() && settings.muteUntil())
|
||||||
|
|| (!peer->notifySilentPosts() && settings.silentPosts())
|
||||||
|
|| (!peer->notifySound() && settings.sound()));
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto callback = [&](not_null<PeerData*> peer) {
|
||||||
|
if (goodForUpdate(peer, defaultSettings(type))) {
|
||||||
|
updateLocal(peer);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
switch (type) {
|
||||||
|
case DefaultNotify::User: _owner->enumerateUsers(callback); break;
|
||||||
|
case DefaultNotify::Group: _owner->enumerateGroups(callback); break;
|
||||||
|
case DefaultNotify::Broadcast:
|
||||||
|
_owner->enumerateBroadcasts(callback);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<DocumentMedia> NotifySettings::lookupRingtone(
|
std::shared_ptr<DocumentMedia> NotifySettings::lookupRingtone(
|
||||||
DocumentId id) const {
|
DocumentId id) const {
|
||||||
if (!id) {
|
if (!id) {
|
||||||
|
@ -252,7 +275,7 @@ bool NotifySettings::isMuted(
|
||||||
if (const auto until = peer->notifyMuteUntil()) {
|
if (const auto until = peer->notifyMuteUntil()) {
|
||||||
return resultFromUntil(*until);
|
return resultFromUntil(*until);
|
||||||
}
|
}
|
||||||
const auto &settings = defaultNotifySettings(peer);
|
const auto &settings = defaultSettings(peer);
|
||||||
if (const auto until = settings.muteUntil()) {
|
if (const auto until = settings.muteUntil()) {
|
||||||
return resultFromUntil(*until);
|
return resultFromUntil(*until);
|
||||||
}
|
}
|
||||||
|
@ -267,7 +290,7 @@ bool NotifySettings::silentPosts(not_null<const PeerData*> peer) const {
|
||||||
if (const auto silent = peer->notifySilentPosts()) {
|
if (const auto silent = peer->notifySilentPosts()) {
|
||||||
return *silent;
|
return *silent;
|
||||||
}
|
}
|
||||||
const auto &settings = defaultNotifySettings(peer);
|
const auto &settings = defaultSettings(peer);
|
||||||
if (const auto silent = settings.silentPosts()) {
|
if (const auto silent = settings.silentPosts()) {
|
||||||
return *silent;
|
return *silent;
|
||||||
}
|
}
|
||||||
|
@ -278,7 +301,7 @@ NotifySound NotifySettings::sound(not_null<const PeerData*> peer) const {
|
||||||
if (const auto sound = peer->notifySound()) {
|
if (const auto sound = peer->notifySound()) {
|
||||||
return *sound;
|
return *sound;
|
||||||
}
|
}
|
||||||
const auto &settings = defaultNotifySettings(peer);
|
const auto &settings = defaultSettings(peer);
|
||||||
if (const auto sound = settings.sound()) {
|
if (const auto sound = settings.sound()) {
|
||||||
return *sound;
|
return *sound;
|
||||||
}
|
}
|
||||||
|
@ -291,7 +314,7 @@ bool NotifySettings::muteUnknown(not_null<const PeerData*> peer) const {
|
||||||
} else if (const auto nonDefault = peer->notifyMuteUntil()) {
|
} else if (const auto nonDefault = peer->notifyMuteUntil()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return defaultNotifySettings(peer).settingsUnknown();
|
return defaultSettings(peer).settingsUnknown();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NotifySettings::silentPostsUnknown(
|
bool NotifySettings::silentPostsUnknown(
|
||||||
|
@ -301,7 +324,7 @@ bool NotifySettings::silentPostsUnknown(
|
||||||
} else if (const auto nonDefault = peer->notifySilentPosts()) {
|
} else if (const auto nonDefault = peer->notifySilentPosts()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return defaultNotifySettings(peer).settingsUnknown();
|
return defaultSettings(peer).settingsUnknown();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NotifySettings::soundUnknown(
|
bool NotifySettings::soundUnknown(
|
||||||
|
@ -311,7 +334,7 @@ bool NotifySettings::soundUnknown(
|
||||||
} else if (const auto nonDefault = peer->notifySound()) {
|
} else if (const auto nonDefault = peer->notifySound()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return defaultNotifySettings(peer).settingsUnknown();
|
return defaultSettings(peer).settingsUnknown();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NotifySettings::settingsUnknown(not_null<const PeerData*> peer) const {
|
bool NotifySettings::settingsUnknown(not_null<const PeerData*> peer) const {
|
||||||
|
@ -320,25 +343,17 @@ bool NotifySettings::settingsUnknown(not_null<const PeerData*> peer) const {
|
||||||
|| soundUnknown(peer);
|
|| soundUnknown(peer);
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl::producer<> NotifySettings::defaultUserNotifyUpdates() const {
|
rpl::producer<> NotifySettings::defaultUpdates(DefaultNotify type) const {
|
||||||
return _defaultUserUpdates.events();
|
return defaultValue(type).updates.events();
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl::producer<> NotifySettings::defaultChatNotifyUpdates() const {
|
rpl::producer<> NotifySettings::defaultUpdates(
|
||||||
return _defaultChatUpdates.events();
|
|
||||||
}
|
|
||||||
|
|
||||||
rpl::producer<> NotifySettings::defaultBroadcastNotifyUpdates() const {
|
|
||||||
return _defaultBroadcastUpdates.events();
|
|
||||||
}
|
|
||||||
|
|
||||||
rpl::producer<> NotifySettings::defaultNotifyUpdates(
|
|
||||||
not_null<const PeerData*> peer) const {
|
not_null<const PeerData*> peer) const {
|
||||||
return peer->isUser()
|
return defaultUpdates(peer->isUser()
|
||||||
? defaultUserNotifyUpdates()
|
? DefaultNotify::User
|
||||||
: (peer->isChat() || peer->isMegagroup())
|
: (peer->isChat() || peer->isMegagroup())
|
||||||
? defaultChatNotifyUpdates()
|
? DefaultNotify::Group
|
||||||
: defaultBroadcastNotifyUpdates();
|
: DefaultNotify::Broadcast);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
|
@ -18,6 +18,12 @@ namespace Data {
|
||||||
class DocumentMedia;
|
class DocumentMedia;
|
||||||
class Session;
|
class Session;
|
||||||
|
|
||||||
|
enum class DefaultNotify {
|
||||||
|
User,
|
||||||
|
Group,
|
||||||
|
Broadcast,
|
||||||
|
};
|
||||||
|
|
||||||
class NotifySettings final {
|
class NotifySettings final {
|
||||||
public:
|
public:
|
||||||
NotifySettings(not_null<Session*> owner);
|
NotifySettings(not_null<Session*> owner);
|
||||||
|
@ -35,12 +41,19 @@ public:
|
||||||
|
|
||||||
std::shared_ptr<DocumentMedia> lookupRingtone(DocumentId id) const;
|
std::shared_ptr<DocumentMedia> lookupRingtone(DocumentId id) const;
|
||||||
|
|
||||||
[[nodiscard]] rpl::producer<> defaultUserNotifyUpdates() const;
|
[[nodiscard]] rpl::producer<> defaultUpdates(DefaultNotify type) const;
|
||||||
[[nodiscard]] rpl::producer<> defaultChatNotifyUpdates() const;
|
[[nodiscard]] rpl::producer<> defaultUpdates(
|
||||||
[[nodiscard]] rpl::producer<> defaultBroadcastNotifyUpdates() const;
|
|
||||||
[[nodiscard]] rpl::producer<> defaultNotifyUpdates(
|
|
||||||
not_null<const PeerData*> peer) const;
|
not_null<const PeerData*> peer) const;
|
||||||
|
|
||||||
|
[[nodiscard]] const PeerNotifySettings &defaultSettings(
|
||||||
|
DefaultNotify type) const;
|
||||||
|
|
||||||
|
void defaultUpdate(
|
||||||
|
DefaultNotify type,
|
||||||
|
std::optional<int> muteForSeconds,
|
||||||
|
std::optional<bool> silentPosts = std::nullopt,
|
||||||
|
std::optional<NotifySound> sound = std::nullopt);
|
||||||
|
|
||||||
[[nodiscard]] bool isMuted(not_null<const PeerData*> peer) const;
|
[[nodiscard]] bool isMuted(not_null<const PeerData*> peer) const;
|
||||||
[[nodiscard]] bool silentPosts(not_null<const PeerData*> peer) const;
|
[[nodiscard]] bool silentPosts(not_null<const PeerData*> peer) const;
|
||||||
[[nodiscard]] NotifySound sound(not_null<const PeerData*> peer) const;
|
[[nodiscard]] NotifySound sound(not_null<const PeerData*> peer) const;
|
||||||
|
@ -50,26 +63,29 @@ public:
|
||||||
[[nodiscard]] bool soundUnknown(not_null<const PeerData*> peer) const;
|
[[nodiscard]] bool soundUnknown(not_null<const PeerData*> peer) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct DefaultValue {
|
||||||
|
PeerNotifySettings settings;
|
||||||
|
rpl::event_stream<> updates;
|
||||||
|
};
|
||||||
|
|
||||||
[[nodiscard]] bool isMuted(
|
[[nodiscard]] bool isMuted(
|
||||||
not_null<const PeerData*> peer,
|
not_null<const PeerData*> peer,
|
||||||
crl::time *changesIn) const;
|
crl::time *changesIn) const;
|
||||||
|
|
||||||
[[nodiscard]] const PeerNotifySettings &defaultNotifySettings(
|
[[nodiscard]] DefaultValue &defaultValue(DefaultNotify type);
|
||||||
|
[[nodiscard]] const DefaultValue &defaultValue(DefaultNotify type) const;
|
||||||
|
[[nodiscard]] const PeerNotifySettings &defaultSettings(
|
||||||
not_null<const PeerData*> peer) const;
|
not_null<const PeerData*> peer) const;
|
||||||
[[nodiscard]] bool settingsUnknown(not_null<const PeerData*> peer) const;
|
[[nodiscard]] bool settingsUnknown(not_null<const PeerData*> peer) const;
|
||||||
|
|
||||||
void unmuteByFinished();
|
void unmuteByFinished();
|
||||||
void unmuteByFinishedDelayed(crl::time delay);
|
void unmuteByFinishedDelayed(crl::time delay);
|
||||||
void updateLocal(not_null<PeerData*> peer);
|
void updateLocal(not_null<PeerData*> peer);
|
||||||
|
void updateLocal(DefaultNotify type);
|
||||||
|
|
||||||
const not_null<Session*> _owner;
|
const not_null<Session*> _owner;
|
||||||
|
|
||||||
PeerNotifySettings _defaultUser;
|
DefaultValue _defaultValues[3];
|
||||||
PeerNotifySettings _defaultChat;
|
|
||||||
PeerNotifySettings _defaultBroadcast;
|
|
||||||
rpl::event_stream<> _defaultUserUpdates;
|
|
||||||
rpl::event_stream<> _defaultChatUpdates;
|
|
||||||
rpl::event_stream<> _defaultBroadcastUpdates;
|
|
||||||
std::unordered_set<not_null<const PeerData*>> _mutedPeers;
|
std::unordered_set<not_null<const PeerData*>> _mutedPeers;
|
||||||
base::Timer _unmuteByFinishedTimer;
|
base::Timer _unmuteByFinishedTimer;
|
||||||
|
|
||||||
|
|
|
@ -793,10 +793,11 @@ HistoryWidget::HistoryWidget(
|
||||||
}
|
}
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
||||||
|
using Type = Data::DefaultNotify;
|
||||||
rpl::merge(
|
rpl::merge(
|
||||||
session().data().notifySettings().defaultUserNotifyUpdates(),
|
session().data().notifySettings().defaultUpdates(Type::User),
|
||||||
session().data().notifySettings().defaultChatNotifyUpdates(),
|
session().data().notifySettings().defaultUpdates(Type::Group),
|
||||||
session().data().notifySettings().defaultBroadcastNotifyUpdates()
|
session().data().notifySettings().defaultUpdates(Type::Broadcast)
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
updateNotifyControls();
|
updateNotifyControls();
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
|
@ -172,7 +172,7 @@ rpl::producer<bool> NotificationsEnabledValue(not_null<PeerData*> peer) {
|
||||||
peer,
|
peer,
|
||||||
UpdateFlag::Notifications
|
UpdateFlag::Notifications
|
||||||
) | rpl::to_empty,
|
) | rpl::to_empty,
|
||||||
peer->owner().notifySettings().defaultNotifyUpdates(peer)
|
peer->owner().notifySettings().defaultUpdates(peer)
|
||||||
) | rpl::map([=] {
|
) | rpl::map([=] {
|
||||||
return !peer->owner().notifySettings().isMuted(peer);
|
return !peer->owner().notifySettings().isMuted(peer);
|
||||||
}) | rpl::distinct_until_changed();
|
}) | rpl::distinct_until_changed();
|
||||||
|
|
|
@ -231,7 +231,9 @@ void FillMuteMenu(
|
||||||
|
|
||||||
menu->addAction(
|
menu->addAction(
|
||||||
tr::lng_mute_menu_sound_select(tr::now),
|
tr::lng_mute_menu_sound_select(tr::now),
|
||||||
[=, show = args.show] { show->showBox(Box(RingtonesBox, peer)); },
|
[=, show = args.show] {
|
||||||
|
show->showBox(Box(PeerRingtonesBox, peer));
|
||||||
|
},
|
||||||
&st::menuIconSoundSelect);
|
&st::menuIconSoundSelect);
|
||||||
|
|
||||||
const auto soundIsNone = peer->owner().notifySettings().sound(peer).none;
|
const auto soundIsNone = peer->owner().notifySettings().sound(peer).none;
|
||||||
|
|
|
@ -30,6 +30,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "main/main_account.h"
|
#include "main/main_account.h"
|
||||||
#include "main/main_domain.h"
|
#include "main/main_domain.h"
|
||||||
#include "api/api_authorizations.h"
|
#include "api/api_authorizations.h"
|
||||||
|
#include "api/api_ringtones.h"
|
||||||
|
#include "data/data_session.h"
|
||||||
|
#include "data/data_document.h"
|
||||||
|
#include "data/notify/data_notify_settings.h"
|
||||||
|
#include "boxes/ringtones_box.h"
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
#include "facades.h"
|
#include "facades.h"
|
||||||
#include "styles/style_settings.h"
|
#include "styles/style_settings.h"
|
||||||
|
@ -824,12 +829,6 @@ void SetupNotificationsContent(
|
||||||
{ &st::settingsIconNotifications, kIconRed },
|
{ &st::settingsIconNotifications, kIconRed },
|
||||||
desktopToggles->events_starting_with(settings.desktopNotify()));
|
desktopToggles->events_starting_with(settings.desktopNotify()));
|
||||||
|
|
||||||
const auto soundToggles = container->lifetime(
|
|
||||||
).make_state<rpl::event_stream<bool>>();
|
|
||||||
const auto sound = addCheckbox(
|
|
||||||
tr::lng_settings_sound_notify(),
|
|
||||||
{ &st::settingsIconSound, kIconLightBlue },
|
|
||||||
soundToggles->events_starting_with(settings.soundNotify()));
|
|
||||||
const auto flashbounceToggles = container->lifetime(
|
const auto flashbounceToggles = container->lifetime(
|
||||||
).make_state<rpl::event_stream<bool>>();
|
).make_state<rpl::event_stream<bool>>();
|
||||||
const auto flashbounce = addCheckbox(
|
const auto flashbounce = addCheckbox(
|
||||||
|
@ -842,6 +841,42 @@ void SetupNotificationsContent(
|
||||||
flashbounceToggles->events_starting_with(
|
flashbounceToggles->events_starting_with(
|
||||||
settings.flashBounceNotify()));
|
settings.flashBounceNotify()));
|
||||||
|
|
||||||
|
const auto soundLabel = container->lifetime(
|
||||||
|
).make_state<rpl::event_stream<QString>>();
|
||||||
|
const auto soundValue = [=] {
|
||||||
|
const auto owner = &controller->session().data();
|
||||||
|
const auto &settings = owner->notifySettings().defaultSettings(
|
||||||
|
Data::DefaultNotify::User);
|
||||||
|
return !Core::App().settings().soundNotify()
|
||||||
|
? Data::NotifySound{ .none = true }
|
||||||
|
: settings.sound().value_or(Data::NotifySound());
|
||||||
|
};
|
||||||
|
const auto label = [=] {
|
||||||
|
const auto now = soundValue();
|
||||||
|
const auto owner = &controller->session().data();
|
||||||
|
return now.none
|
||||||
|
? tr::lng_settings_sound_notify_off(tr::now)
|
||||||
|
: !now.id
|
||||||
|
? tr::lng_ringtones_box_default(tr::now)
|
||||||
|
: ExtractRingtoneName(owner->document(now.id));
|
||||||
|
};
|
||||||
|
controller->session().data().notifySettings().defaultUpdates(
|
||||||
|
Data::DefaultNotify::User
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
soundLabel->fire(label());
|
||||||
|
}, container->lifetime());
|
||||||
|
controller->session().api().ringtones().listUpdates(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
soundLabel->fire(label());
|
||||||
|
}, container->lifetime());
|
||||||
|
|
||||||
|
const auto sound = AddButtonWithLabel(
|
||||||
|
container,
|
||||||
|
tr::lng_settings_sound_notify(),
|
||||||
|
soundLabel->events_starting_with(label()),
|
||||||
|
st::settingsButton,
|
||||||
|
{ &st::settingsIconSound, kIconLightBlue });
|
||||||
|
|
||||||
AddSkip(container);
|
AddSkip(container);
|
||||||
|
|
||||||
const auto checkboxes = SetupNotifyViewOptions(
|
const auto checkboxes = SetupNotifyViewOptions(
|
||||||
|
@ -1012,13 +1047,24 @@ void SetupNotificationsContent(
|
||||||
changed(Change::ViewParams);
|
changed(Change::ViewParams);
|
||||||
}, preview->lifetime());
|
}, preview->lifetime());
|
||||||
|
|
||||||
sound->toggledChanges(
|
sound->setClickedCallback([=] {
|
||||||
) | rpl::filter([](bool checked) {
|
controller->show(Box(RingtonesBox, session, soundValue(), [=](
|
||||||
return (checked != Core::App().settings().soundNotify());
|
Data::NotifySound sound) {
|
||||||
}) | rpl::start_with_next([=](bool checked) {
|
Core::App().settings().setSoundNotify(!sound.none);
|
||||||
Core::App().settings().setSoundNotify(checked);
|
if (!sound.none) {
|
||||||
changed(Change::SoundEnabled);
|
using Type = Data::DefaultNotify;
|
||||||
}, sound->lifetime());
|
const auto owner = &controller->session().data();
|
||||||
|
auto &settings = owner->notifySettings();
|
||||||
|
const auto updateType = [&](Type type) {
|
||||||
|
settings.defaultUpdate(type, {}, {}, sound);
|
||||||
|
};
|
||||||
|
updateType(Type::User);
|
||||||
|
updateType(Type::Group);
|
||||||
|
updateType(Type::Broadcast);
|
||||||
|
}
|
||||||
|
changed(Change::SoundEnabled);
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
flashbounce->toggledChanges(
|
flashbounce->toggledChanges(
|
||||||
) | rpl::filter([](bool checked) {
|
) | rpl::filter([](bool checked) {
|
||||||
|
@ -1057,7 +1103,7 @@ void SetupNotificationsContent(
|
||||||
} else if (change == Change::ViewParams) {
|
} else if (change == Change::ViewParams) {
|
||||||
//
|
//
|
||||||
} else if (change == Change::SoundEnabled) {
|
} else if (change == Change::SoundEnabled) {
|
||||||
soundToggles->fire(Core::App().settings().soundNotify());
|
soundLabel->fire(label());
|
||||||
} else if (change == Change::FlashBounceEnabled) {
|
} else if (change == Change::FlashBounceEnabled) {
|
||||||
flashbounceToggles->fire(
|
flashbounceToggles->fire(
|
||||||
Core::App().settings().flashBounceNotify());
|
Core::App().settings().flashBounceNotify());
|
||||||
|
|
Loading…
Add table
Reference in a new issue