From b1e3b9688eec11fe97603a5aa1edf69e5d956efe Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Tue, 5 Apr 2022 15:26:18 +0300 Subject: [PATCH] Added initial support of custom sound to notifications. --- Telegram/SourceFiles/apiwrap.cpp | 2 + Telegram/SourceFiles/data/data_file_origin.h | 11 ++++- .../data/notify/data_notify_settings.cpp | 40 +++++++++++++++++++ .../data/notify/data_notify_settings.h | 11 +++++ .../window/notifications_manager.cpp | 25 ++++++++++-- .../window/notifications_manager.h | 1 + 6 files changed, 85 insertions(+), 5 deletions(-) diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index 919794b9d..925e6090d 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -2417,6 +2417,8 @@ void ApiWrap::refreshFileReference( MTP_long(data.themeId), MTP_long(data.accessHash)), MTP_long(0))); + }, [&](Data::FileOriginRingtones data) { + fail(); }, [&](v::null_t) { fail(); }); diff --git a/Telegram/SourceFiles/data/data_file_origin.h b/Telegram/SourceFiles/data/data_file_origin.h index 7d9b5d79e..dec85b46c 100644 --- a/Telegram/SourceFiles/data/data_file_origin.h +++ b/Telegram/SourceFiles/data/data_file_origin.h @@ -96,6 +96,12 @@ struct FileOriginTheme { } }; +struct FileOriginRingtones { + inline bool operator<(const FileOriginRingtones &) const { + return false; + } +}; + struct FileOrigin { using Variant = std::variant< v::null_t, @@ -105,7 +111,8 @@ struct FileOrigin { FileOriginStickerSet, FileOriginSavedGifs, FileOriginWallpaper, - FileOriginTheme>; + FileOriginTheme, + FileOriginRingtones>; FileOrigin() = default; FileOrigin(FileOriginMessage data) : data(data) { @@ -122,6 +129,8 @@ struct FileOrigin { } FileOrigin(FileOriginTheme data) : data(data) { } + FileOrigin(FileOriginRingtones data) : data(data) { + } explicit operator bool() const { return !v::is_null(data); diff --git a/Telegram/SourceFiles/data/notify/data_notify_settings.cpp b/Telegram/SourceFiles/data/notify/data_notify_settings.cpp index bb361c9c6..b387b599b 100644 --- a/Telegram/SourceFiles/data/notify/data_notify_settings.cpp +++ b/Telegram/SourceFiles/data/notify/data_notify_settings.cpp @@ -8,14 +8,18 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/notify/data_notify_settings.h" #include "apiwrap.h" +#include "api/api_ringtones.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_document.h" +#include "data/data_file_origin.h" #include "data/data_peer.h" #include "data/data_session.h" #include "data/data_user.h" +#include "main/main_session.h" #include "history/history.h" #include "main/main_session.h" #include "window/notifications_manager.h" @@ -160,6 +164,42 @@ void NotifySettings::updateLocal(not_null peer) { } else { _mutedPeers.erase(peer); } + + if (const auto sound = peer->notifySound(); sound && sound->id) { + const auto cache = [=](DocumentId id) { + if (const auto document = _owner->document(id)) { + const auto view = document->createMediaView(); + _ringtones.views.emplace(id, view); + document->forceToCache(true); + document->save(Data::FileOriginRingtones(), QString()); + } + }; + if (const auto doc = _owner->document(sound->id); !doc->isNull()) { + cache(sound->id); + } else { + _ringtones.pendingIds.push_back(sound->id); + if (!_ringtones.pendingLifetime) { + // Not requested yet. + _owner->session().api().ringtones().listUpdates( + ) | rpl::start_with_next([=] { + for (const auto &id : base::take(_ringtones.pendingIds)) { + cache(id); + } + _ringtones.pendingLifetime.destroy(); + }, _ringtones.pendingLifetime); + _owner->session().api().ringtones().requestList(); + } + } + } +} + +std::shared_ptr NotifySettings::lookupRingtone( + DocumentId id) const { + if (!id) { + return nullptr; + } + const auto it = _ringtones.views.find(id); + return (it == end(_ringtones.views)) ? nullptr : it->second; } void NotifySettings::unmuteByFinishedDelayed(crl::time delay) { diff --git a/Telegram/SourceFiles/data/notify/data_notify_settings.h b/Telegram/SourceFiles/data/notify/data_notify_settings.h index 54396dfcc..e174b3a2c 100644 --- a/Telegram/SourceFiles/data/notify/data_notify_settings.h +++ b/Telegram/SourceFiles/data/notify/data_notify_settings.h @@ -15,6 +15,7 @@ class PeerData; namespace Data { +class DocumentMedia; class Session; class NotifySettings final { @@ -32,6 +33,8 @@ public: std::optional sound = std::nullopt); void resetToDefault(not_null peer); + std::shared_ptr lookupRingtone(DocumentId id) const; + [[nodiscard]] rpl::producer<> defaultUserNotifyUpdates() const; [[nodiscard]] rpl::producer<> defaultChatNotifyUpdates() const; [[nodiscard]] rpl::producer<> defaultBroadcastNotifyUpdates() const; @@ -70,6 +73,14 @@ private: std::unordered_set> _mutedPeers; base::Timer _unmuteByFinishedTimer; + struct { + base::flat_map< + DocumentId, + std::shared_ptr> views; + std::vector pendingIds; + rpl::lifetime pendingLifetime; + } _ringtones; + }; } // namespace Data diff --git a/Telegram/SourceFiles/window/notifications_manager.cpp b/Telegram/SourceFiles/window/notifications_manager.cpp index 67472115e..510f2d473 100644 --- a/Telegram/SourceFiles/window/notifications_manager.cpp +++ b/Telegram/SourceFiles/window/notifications_manager.cpp @@ -16,6 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/history_item_components.h" #include "lang/lang_keys.h" #include "data/notify/data_notify_settings.h" +#include "data/data_document_media.h" #include "data/data_session.h" #include "data/data_channel.h" #include "data/data_user.h" @@ -467,7 +468,8 @@ void System::showNext() { }; auto ms = crl::now(), nextAlert = crl::time(0); - bool alert = false; + auto alert = false; + std::shared_ptr customSound = nullptr; for (auto i = _whenAlerts.begin(); i != _whenAlerts.end();) { while (!i->second.empty() && i->second.begin()->first <= ms) { const auto peer = i->first->peer; @@ -475,6 +477,9 @@ void System::showNext() { const auto peerUnknown = notifySettings.muteUnknown(peer); const auto peerAlert = !peerUnknown && !notifySettings.isMuted(peer); + const auto peerSoundId = !notifySettings.soundUnknown(peer) + ? notifySettings.sound(peer).id + : 0; const auto from = i->second.begin()->second; const auto fromUnknown = (!from || notifySettings.muteUnknown(from)); @@ -482,6 +487,9 @@ void System::showNext() { && !notifySettings.isMuted(from); if (peerAlert || fromAlert) { alert = true; + if (peerSoundId) { + customSound = notifySettings.lookupRingtone(peerSoundId); + } } while (!i->second.empty() && i->second.begin()->first <= ms + kMinimalAlertDelay) { @@ -508,9 +516,18 @@ void System::showNext() { } } if (settings.soundNotify() && !_manager->skipAudio()) { - ensureSoundCreated(); - _soundTrack->playOnce(); - Media::Player::mixer()->suppressAll(_soundTrack->getLengthMs()); + const auto custom = customSound + && !customSound->bytes().isEmpty(); + if (custom) { + const auto bytes = customSound->bytes(); + _customSoundTrack = Media::Audio::Current().createTrack(); + _customSoundTrack->fillFromData(bytes::make_vector(bytes)); + } else { + ensureSoundCreated(); + } + const auto &track = custom ? _customSoundTrack : _soundTrack; + track->playOnce(); + Media::Player::mixer()->suppressAll(track->getLengthMs()); Media::Player::mixer()->faderOnTimer(); } } diff --git a/Telegram/SourceFiles/window/notifications_manager.h b/Telegram/SourceFiles/window/notifications_manager.h index a6b7fb2bd..62debf726 100644 --- a/Telegram/SourceFiles/window/notifications_manager.h +++ b/Telegram/SourceFiles/window/notifications_manager.h @@ -181,6 +181,7 @@ private: rpl::event_stream _settingsChanged; std::unique_ptr _soundTrack; + std::unique_ptr _customSoundTrack; int _lastForwardedCount = 0; uint64 _lastHistorySessionId = 0;