diff --git a/Telegram/SourceFiles/window/notifications_manager.cpp b/Telegram/SourceFiles/window/notifications_manager.cpp index c23248b2a..529d070e6 100644 --- a/Telegram/SourceFiles/window/notifications_manager.cpp +++ b/Telegram/SourceFiles/window/notifications_manager.cpp @@ -30,12 +30,14 @@ namespace { // not more than one sound in 500ms from one peer - grouping constexpr auto kMinimalAlertDelay = crl::time(500); +constexpr auto kWaitingForAllGroupedDelay = crl::time(1000); } // namespace System::System(AuthSession *session) : _authSession(session) -, _waitTimer([=] { showNext(); }) { +, _waitTimer([=] { showNext(); }) +, _waitForAllGroupedTimer([=] { showGrouped(); }) { createManager(); subscribe(settingsChanged(), [=](ChangeType type) { @@ -211,9 +213,28 @@ void System::checkDelayed() { showNext(); } +void System::showGrouped() { + if (const auto lastItem = App::histItemById(_lastHistoryItemId)) { + _waitForAllGroupedTimer.cancel(); + _manager->showNotification(lastItem, _lastForwardedCount); + _lastForwardedCount = 0; + _lastHistoryItemId = FullMsgId(); + } +} + void System::showNext() { if (App::quitting()) return; + const auto isSameGroup = [=](HistoryItem *item) { + if (!_lastHistoryItemId || !item) { + return false; + } + if (const auto lastItem = App::histItemById(_lastHistoryItemId)) { + return (lastItem->groupId() == item->groupId() || lastItem->author() == item->author()); + } + return false; + }; + auto ms = crl::now(), nextAlert = 0LL; bool alert = false; int32 now = unixtime(); @@ -360,7 +381,33 @@ void System::showNext() { } while (nextNotify); } - _manager->showNotification(notifyItem, forwardedCount); + if (!_lastHistoryItemId && groupedItem) { + _lastHistoryItemId = groupedItem->fullId(); + } + + // If the current notification is grouped. + if (isAlbum || isForwarded) { + // If the previous notification is grouped + // then reset the timer. + if (_waitForAllGroupedTimer.isActive()) { + _waitForAllGroupedTimer.cancel(); + // If this is not the same group + // then show the previous group immediately. + if (!isSameGroup(groupedItem)) { + showGrouped(); + } + } + // We have to wait until all the messages in this group are loaded. + _lastForwardedCount += forwardedCount; + _lastHistoryItemId = groupedItem->fullId(); + _waitForAllGroupedTimer.callOnce(kWaitingForAllGroupedDelay); + } else { + // If the current notification is not grouped + // then there is no reason to wait for the timer + // to show the previous notification. + showGrouped(); + _manager->showNotification(notifyItem, forwardedCount); + } if (!history->hasNotification()) { _waiters.remove(history); diff --git a/Telegram/SourceFiles/window/notifications_manager.h b/Telegram/SourceFiles/window/notifications_manager.h index 29fd165ab..4e94a3cff 100644 --- a/Telegram/SourceFiles/window/notifications_manager.h +++ b/Telegram/SourceFiles/window/notifications_manager.h @@ -79,6 +79,7 @@ public: private: void showNext(); + void showGrouped(); void ensureSoundCreated(); AuthSession *_authSession = nullptr; @@ -99,6 +100,7 @@ private: Waiters _waiters; Waiters _settingWaiters; base::Timer _waitTimer; + base::Timer _waitForAllGroupedTimer; QMap> _whenAlerts; @@ -108,6 +110,9 @@ private: std::unique_ptr _soundTrack; + int _lastForwardedCount = 0; + FullMsgId _lastHistoryItemId; + }; class Manager {