From dc8eb79295a7e337709c5dbfe4e82b2b98cb88c4 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Mon, 30 Aug 2021 22:35:16 +0300 Subject: [PATCH] Moved code of data send actions from Data::Session to separated file. --- Telegram/CMakeLists.txt | 2 + Telegram/SourceFiles/api/api_updates.cpp | 3 +- .../SourceFiles/data/data_send_action.cpp | 153 ++++++++++++++++++ Telegram/SourceFiles/data/data_send_action.h | 81 ++++++++++ Telegram/SourceFiles/data/data_session.cpp | 138 +--------------- Telegram/SourceFiles/data/data_session.h | 58 +------ .../dialogs/dialogs_inner_widget.cpp | 7 +- Telegram/SourceFiles/history/history.cpp | 3 +- .../view/history_view_replies_section.cpp | 9 +- .../history/view/history_view_send_action.cpp | 5 +- .../view/history_view_top_bar_widget.cpp | 5 +- 11 files changed, 265 insertions(+), 199 deletions(-) create mode 100644 Telegram/SourceFiles/data/data_send_action.cpp create mode 100644 Telegram/SourceFiles/data/data_send_action.h diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt index 936f3002b7..c2dca3c6b2 100644 --- a/Telegram/CMakeLists.txt +++ b/Telegram/CMakeLists.txt @@ -422,6 +422,8 @@ PRIVATE data/data_reply_preview.h data/data_search_controller.cpp data/data_search_controller.h + data/data_send_action.cpp + data/data_send_action.h data/data_session.cpp data/data_session.h data/data_scheduled_messages.cpp diff --git a/Telegram/SourceFiles/api/api_updates.cpp b/Telegram/SourceFiles/api/api_updates.cpp index b27b8d0941..d3e80896cc 100644 --- a/Telegram/SourceFiles/api/api_updates.cpp +++ b/Telegram/SourceFiles/api/api_updates.cpp @@ -28,6 +28,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_histories.h" #include "data/data_folder.h" #include "data/data_scheduled_messages.h" +#include "data/data_send_action.h" #include "lang/lang_cloud_manager.h" #include "history/history.h" #include "history/history_item.h" @@ -1017,7 +1018,7 @@ void Updates::handleSendActionUpdate( const auto when = requestingDifference() ? 0 : base::unixtime::now(); - session().data().registerSendAction( + session().data().sendActionManager().registerFor( history, rootId, from->asUser(), diff --git a/Telegram/SourceFiles/data/data_send_action.cpp b/Telegram/SourceFiles/data/data_send_action.cpp new file mode 100644 index 0000000000..77333acf6f --- /dev/null +++ b/Telegram/SourceFiles/data/data_send_action.cpp @@ -0,0 +1,153 @@ +/* +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/data_send_action.h" + +#include "data/data_user.h" +#include "history/history.h" +#include "history/view/history_view_send_action.h" + +namespace Data { + +SendActionManager::SendActionManager() +: _animation([=](crl::time now) { return callback(now); }) { +} + +HistoryView::SendActionPainter *SendActionManager::lookupPainter( + not_null history, + MsgId rootId) { + if (!rootId) { + return history->sendActionPainter(); + } + const auto i = _painters.find(history); + if (i == end(_painters)) { + return nullptr; + } + const auto j = i->second.find(rootId); + if (j == end(i->second)) { + return nullptr; + } + const auto result = j->second.lock(); + if (!result) { + i->second.erase(j); + if (i->second.empty()) { + _painters.erase(i); + } + return nullptr; + } + crl::on_main([copy = result] { + }); + return result.get(); +} + +void SendActionManager::registerFor( + not_null history, + MsgId rootId, + not_null user, + const MTPSendMessageAction &action, + TimeId when) { + if (history->peer->isSelf()) { + return; + } + const auto sendAction = lookupPainter(history, rootId); + if (!sendAction) { + return; + } + if (sendAction->updateNeedsAnimating(user, action)) { + user->madeAction(when); + + if (!_sendActions.contains(std::pair{ history, rootId })) { + _sendActions.emplace(std::pair{ history, rootId }, crl::now()); + _animation.start(); + } + } +} + +auto SendActionManager::repliesPainter( + not_null history, + MsgId rootId) +-> std::shared_ptr { + auto &weak = _painters[history][rootId]; + if (auto strong = weak.lock()) { + return strong; + } + auto result = std::make_shared(history); + weak = result; + return result; +} + +void SendActionManager::repliesPainterRemoved( + not_null history, + MsgId rootId) { + const auto i = _painters.find(history); + if (i == end(_painters)) { + return; + } + const auto j = i->second.find(rootId); + if (j == end(i->second) || j->second.lock()) { + return; + } + i->second.erase(j); + if (i->second.empty()) { + _painters.erase(i); + } +} + +void SendActionManager::repliesPaintersClear( + not_null history, + not_null user) { + auto &map = _painters[history]; + for (auto i = map.begin(); i != map.end();) { + if (auto strong = i->second.lock()) { + strong->clear(user); + ++i; + } else { + i = map.erase(i); + } + } + if (map.empty()) { + _painters.erase(history); + } +} + +bool SendActionManager::callback(crl::time now) { + for (auto i = begin(_sendActions); i != end(_sendActions);) { + const auto sendAction = lookupPainter( + i->first.first, + i->first.second); + if (sendAction && sendAction->updateNeedsAnimating(now)) { + ++i; + } else { + i = _sendActions.erase(i); + } + } + return !_sendActions.empty(); +} + +auto SendActionManager::animationUpdated() const +-> rpl::producer { + return _animationUpdate.events(); +} + +void SendActionManager::updateAnimation(AnimationUpdate &&update) { + _animationUpdate.fire(std::move(update)); +} + +auto SendActionManager::speakingAnimationUpdated() const +-> rpl::producer> { + return _speakingAnimationUpdate.events(); +} + +void SendActionManager::updateSpeakingAnimation(not_null history) { + _speakingAnimationUpdate.fire_copy(history); +} + +void SendActionManager::clear() { + _sendActions.clear(); +} + +} // namespace Data diff --git a/Telegram/SourceFiles/data/data_send_action.h b/Telegram/SourceFiles/data/data_send_action.h new file mode 100644 index 0000000000..a209e12634 --- /dev/null +++ b/Telegram/SourceFiles/data/data_send_action.h @@ -0,0 +1,81 @@ +/* +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 "ui/effects/animations.h" + +class History; + +namespace HistoryView { +class SendActionPainter; +} // namespace HistoryView + +namespace Data { + +class SendActionManager final { +public: + struct AnimationUpdate { + not_null history; + int left = 0; + int width = 0; + int height = 0; + bool textUpdated = false; + }; + explicit SendActionManager(); + + void registerFor( + not_null history, + MsgId rootId, + not_null user, + const MTPSendMessageAction &action, + TimeId when); + + [[nodiscard]] auto animationUpdated() const + -> rpl::producer; + void updateAnimation(AnimationUpdate &&update); + [[nodiscard]] auto speakingAnimationUpdated() const + -> rpl::producer>; + void updateSpeakingAnimation(not_null history); + + using SendActionPainter = HistoryView::SendActionPainter; + [[nodiscard]] std::shared_ptr repliesPainter( + not_null history, + MsgId rootId); + void repliesPainterRemoved( + not_null history, + MsgId rootId); + void repliesPaintersClear( + not_null history, + not_null user); + + void clear(); + +private: + bool callback(crl::time now); + [[nodiscard]] SendActionPainter *lookupPainter( + not_null history, + MsgId rootId); + + // When typing in this history started. + base::flat_map< + std::pair, MsgId>, + crl::time> _sendActions; + Ui::Animations::Basic _animation; + + rpl::event_stream _animationUpdate; + rpl::event_stream> _speakingAnimationUpdate; + + base::flat_map< + not_null, + base::flat_map< + MsgId, + std::weak_ptr>> _painters; + +}; + +} // namespace Data diff --git a/Telegram/SourceFiles/data/data_session.cpp b/Telegram/SourceFiles/data/data_session.cpp index eeefca3669..aab3a1ff6c 100644 --- a/Telegram/SourceFiles/data/data_session.cpp +++ b/Telegram/SourceFiles/data/data_session.cpp @@ -27,7 +27,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/history_item_components.h" #include "history/view/media/history_view_media.h" #include "history/view/history_view_element.h" -#include "history/view/history_view_send_action.h" #include "inline_bots/inline_bot_layout_item.h" #include "storage/storage_account.h" #include "storage/storage_encrypted_file.h" @@ -53,6 +52,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_poll.h" #include "data/data_chat_filters.h" #include "data/data_scheduled_messages.h" +#include "data/data_send_action.h" #include "data/data_cloud_themes.h" #include "data/data_streaming.h" #include "data/data_media_rotation.h" @@ -229,15 +229,13 @@ Session::Session(not_null session) , _contactsNoChatsList(Dialogs::SortMode::Name) , _ttlCheckTimer([=] { checkTTLs(); }) , _selfDestructTimer([=] { checkSelfDestructItems(); }) -, _sendActionsAnimation([=](crl::time now) { - return sendActionsAnimationCallback(now); -}) , _pollsClosingTimer([=] { checkPollsClosings(); }) , _unmuteByFinishedTimer([=] { unmuteByFinished(); }) , _groups(this) , _chatsFilters(std::make_unique(this)) , _scheduledMessages(std::make_unique(this)) , _cloudThemes(std::make_unique(session)) +, _sendActionManager(std::make_unique()) , _streaming(std::make_unique(this)) , _mediaRotation(std::make_unique()) , _histories(std::make_unique(this)) @@ -278,7 +276,7 @@ void Session::clear() { // Optimization: clear notifications before destroying items. Core::App().notifications().clearFromSession(_session); - _sendActions.clear(); + _sendActionManager->clear(); _histories->unloadAll(); _scheduledMessages = nullptr; @@ -1000,117 +998,6 @@ void Session::cancelForwarding(not_null history) { Data::HistoryUpdate::Flag::ForwardDraft); } -HistoryView::SendActionPainter *Session::lookupSendActionPainter( - not_null history, - MsgId rootId) { - if (!rootId) { - return history->sendActionPainter(); - } - const auto i = _sendActionPainters.find(history); - if (i == end(_sendActionPainters)) { - return nullptr; - } - const auto j = i->second.find(rootId); - if (j == end(i->second)) { - return nullptr; - } - const auto result = j->second.lock(); - if (!result) { - i->second.erase(j); - if (i->second.empty()) { - _sendActionPainters.erase(i); - } - return nullptr; - } - crl::on_main([copy = result] { - }); - return result.get(); -} - -void Session::registerSendAction( - not_null history, - MsgId rootId, - not_null user, - const MTPSendMessageAction &action, - TimeId when) { - if (history->peer->isSelf()) { - return; - } - const auto sendAction = lookupSendActionPainter(history, rootId); - if (!sendAction) { - return; - } - if (sendAction->updateNeedsAnimating(user, action)) { - user->madeAction(when); - - if (!_sendActions.contains(std::pair{ history, rootId })) { - _sendActions.emplace(std::pair{ history, rootId }, crl::now()); - _sendActionsAnimation.start(); - } - } -} - -auto Session::repliesSendActionPainter( - not_null history, - MsgId rootId) --> std::shared_ptr { - auto &weak = _sendActionPainters[history][rootId]; - if (auto strong = weak.lock()) { - return strong; - } - auto result = std::make_shared(history); - weak = result; - return result; -} - -void Session::repliesSendActionPainterRemoved( - not_null history, - MsgId rootId) { - const auto i = _sendActionPainters.find(history); - if (i == end(_sendActionPainters)) { - return; - } - const auto j = i->second.find(rootId); - if (j == end(i->second) || j->second.lock()) { - return; - } - i->second.erase(j); - if (i->second.empty()) { - _sendActionPainters.erase(i); - } -} - -void Session::repliesSendActionPaintersClear( - not_null history, - not_null user) { - auto &map = _sendActionPainters[history]; - for (auto i = map.begin(); i != map.end();) { - if (auto strong = i->second.lock()) { - strong->clear(user); - ++i; - } else { - i = map.erase(i); - } - } - if (map.empty()) { - _sendActionPainters.erase(history); - } -} - -bool Session::sendActionsAnimationCallback(crl::time now) { - for (auto i = begin(_sendActions); i != end(_sendActions);) { - const auto sendAction = lookupSendActionPainter( - i->first.first, - i->first.second); - if (sendAction && sendAction->updateNeedsAnimating(now)) { - ++i; - } else { - i = _sendActions.erase(i); - } - } - return !_sendActions.empty(); -} - bool Session::chatsListLoaded(Data::Folder *folder) { return chatsList(folder)->loaded(); } @@ -2301,25 +2188,6 @@ HistoryItem *Session::addNewMessage( return result; } -auto Session::sendActionAnimationUpdated() const --> rpl::producer { - return _sendActionAnimationUpdate.events(); -} - -void Session::updateSendActionAnimation( - SendActionAnimationUpdate &&update) { - _sendActionAnimationUpdate.fire(std::move(update)); -} - -auto Session::speakingAnimationUpdated() const --> rpl::producer> { - return _speakingAnimationUpdate.events(); -} - -void Session::updateSpeakingAnimation(not_null history) { - _speakingAnimationUpdate.fire_copy(history); -} - int Session::unreadBadge() const { return computeUnreadBadge(_chatsList.unreadState()); } diff --git a/Telegram/SourceFiles/data/data_session.h b/Telegram/SourceFiles/data/data_session.h index 8c31ef74ef..c0f6f2b670 100644 --- a/Telegram/SourceFiles/data/data_session.h +++ b/Telegram/SourceFiles/data/data_session.h @@ -17,7 +17,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/history_location_manager.h" #include "base/timer.h" #include "base/flags.h" -#include "ui/effects/animations.h" class Image; class HistoryItem; @@ -31,7 +30,6 @@ namespace HistoryView { struct Group; class Element; class ElementDelegate; -class SendActionPainter; } // namespace HistoryView namespace Main { @@ -52,6 +50,7 @@ class Folder; class LocationPoint; class WallPaper; class ScheduledMessages; +class SendActionManager; class ChatFilters; class CloudThemes; class Streaming; @@ -92,6 +91,9 @@ public: [[nodiscard]] ScheduledMessages &scheduledMessages() const { return *_scheduledMessages; } + [[nodiscard]] SendActionManager &sendActionManager() const { + return *_sendActionManager; + } [[nodiscard]] CloudThemes &cloudThemes() const { return *_cloudThemes; } @@ -192,13 +194,6 @@ public: void cancelForwarding(not_null history); - void registerSendAction( - not_null history, - MsgId rootId, - not_null user, - const MTPSendMessageAction &action, - TimeId when); - [[nodiscard]] rpl::variable &contactsLoaded() { return _contactsLoaded; } @@ -403,31 +398,6 @@ public: MessageFlags localFlags, NewMessageType type); - struct SendActionAnimationUpdate { - not_null history; - int left = 0; - int width = 0; - int height = 0; - bool textUpdated = false; - }; - [[nodiscard]] auto sendActionAnimationUpdated() const - -> rpl::producer; - void updateSendActionAnimation(SendActionAnimationUpdate &&update); - [[nodiscard]] auto speakingAnimationUpdated() const - -> rpl::producer>; - void updateSpeakingAnimation(not_null history); - - using SendActionPainter = HistoryView::SendActionPainter; - [[nodiscard]] std::shared_ptr repliesSendActionPainter( - not_null history, - MsgId rootId); - void repliesSendActionPainterRemoved( - not_null history, - MsgId rootId); - void repliesSendActionPaintersClear( - not_null history, - not_null user); - [[nodiscard]] int unreadBadge() const; [[nodiscard]] bool unreadBadgeMuted() const; [[nodiscard]] int unreadBadgeIgnoreOne(const Dialogs::Key &key) const; @@ -823,11 +793,6 @@ private: const MTPMessageMedia &media, TimeId date); - bool sendActionsAnimationCallback(crl::time now); - [[nodiscard]] SendActionPainter *lookupSendActionPainter( - not_null history, - MsgId rootId); - void setWallpapers(const QVector &data, int32 hash); void checkPollsClosings(); @@ -889,12 +854,6 @@ private: base::Timer _selfDestructTimer; std::vector _selfDestructItems; - // When typing in this history started. - base::flat_map< - std::pair, MsgId>, - crl::time> _sendActions; - Ui::Animations::Basic _sendActionsAnimation; - std::unordered_map< PhotoId, std::unique_ptr> _photos; @@ -984,9 +943,6 @@ private: int>; std::unique_ptr _passportCredentials; - rpl::event_stream _sendActionAnimationUpdate; - rpl::event_stream> _speakingAnimationUpdate; - std::vector _wallpapers; int32 _wallpapersHash = 0; @@ -994,14 +950,10 @@ private: std::unique_ptr _chatsFilters; std::unique_ptr _scheduledMessages; std::unique_ptr _cloudThemes; + std::unique_ptr _sendActionManager; std::unique_ptr _streaming; std::unique_ptr _mediaRotation; std::unique_ptr _histories; - base::flat_map< - not_null, - base::flat_map< - MsgId, - std::weak_ptr>> _sendActionPainters; std::unique_ptr _stickers; MsgId _nonHistoryEntryId = ServerMaxMsgId; diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp index bb173417c8..5c30168d72 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp @@ -32,6 +32,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_cloud_file.h" #include "data/data_changes.h" #include "data/stickers/data_stickers.h" +#include "data/data_send_action.h" #include "base/unixtime.h" #include "lang/lang_keys.h" #include "mainwindow.h" @@ -166,9 +167,9 @@ InnerWidget::InnerWidget( } }, lifetime()); - session().data().sendActionAnimationUpdated( + session().data().sendActionManager().animationUpdated( ) | rpl::start_with_next([=]( - const Data::Session::SendActionAnimationUpdate &update) { + const Data::SendActionManager::AnimationUpdate &update) { using RowPainter = Layout::RowPainter; const auto updateRect = RowPainter::sendActionAnimationRect( update.left, @@ -182,7 +183,7 @@ InnerWidget::InnerWidget( UpdateRowSection::Default | UpdateRowSection::Filtered); }, lifetime()); - session().data().speakingAnimationUpdated( + session().data().sendActionManager().speakingAnimationUpdated( ) | rpl::start_with_next([=](not_null history) { updateDialogRowCornerStatus(history); }, lifetime()); diff --git a/Telegram/SourceFiles/history/history.cpp b/Telegram/SourceFiles/history/history.cpp index 003cb904ca..12e82c7d2f 100644 --- a/Telegram/SourceFiles/history/history.cpp +++ b/Telegram/SourceFiles/history/history.cpp @@ -21,6 +21,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_changes.h" #include "data/data_chat_filters.h" #include "data/data_scheduled_messages.h" +#include "data/data_send_action.h" #include "data/data_folder.h" #include "data/data_photo.h" #include "data/data_channel.h" @@ -1088,7 +1089,7 @@ void History::newItemAdded(not_null item) { if (const auto from = item->from() ? item->from()->asUser() : nullptr) { if (from == item->author()) { _sendActionPainter.clear(from); - owner().repliesSendActionPaintersClear(this, from); + owner().sendActionManager().repliesPaintersClear(this, from); } from->madeAction(item->date()); } diff --git a/Telegram/SourceFiles/history/view/history_view_replies_section.cpp b/Telegram/SourceFiles/history/view/history_view_replies_section.cpp index 679b460979..10478a9e89 100644 --- a/Telegram/SourceFiles/history/view/history_view_replies_section.cpp +++ b/Telegram/SourceFiles/history/view/history_view_replies_section.cpp @@ -52,6 +52,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_channel.h" #include "data/data_replies_list.h" #include "data/data_changes.h" +#include "data/data_send_action.h" #include "storage/storage_media_prepare.h" #include "storage/storage_account.h" #include "inline_bots/inline_bot_result.h" @@ -151,7 +152,9 @@ RepliesWidget::RepliesWidget( , _rootId(rootId) , _root(lookupRoot()) , _areComments(computeAreComments()) -, _sendAction(history->owner().repliesSendActionPainter(history, rootId)) +, _sendAction(history->owner().sendActionManager().repliesPainter( + history, + rootId)) , _topBar(this, controller) , _topBarShadow(this) , _composeControls(std::make_unique( @@ -303,7 +306,9 @@ RepliesWidget::~RepliesWidget() { sendReadTillRequest(); } base::take(_sendAction); - _history->owner().repliesSendActionPainterRemoved(_history, _rootId); + _history->owner().sendActionManager().repliesPainterRemoved( + _history, + _rootId); } void RepliesWidget::orderWidgets() { diff --git a/Telegram/SourceFiles/history/view/history_view_send_action.cpp b/Telegram/SourceFiles/history/view/history_view_send_action.cpp index e5f26dc8d3..23956686c8 100644 --- a/Telegram/SourceFiles/history/view/history_view_send_action.cpp +++ b/Telegram/SourceFiles/history/view/history_view_send_action.cpp @@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/view/history_view_send_action.h" #include "data/data_user.h" +#include "data/data_send_action.h" #include "data/data_session.h" #include "main/main_session.h" #include "history/history.h" @@ -368,7 +369,7 @@ bool SendActionPainter::updateNeedsAnimating(crl::time now, bool force) { if (force || sendActionChanged || (sendActionResult && !anim::Disabled())) { - _history->peer->owner().updateSendActionAnimation({ + _history->peer->owner().sendActionManager().updateAnimation({ _history, _animationLeft, _sendActionAnimation.width(), @@ -379,7 +380,7 @@ bool SendActionPainter::updateNeedsAnimating(crl::time now, bool force) { if (force || speakingChanged || (speakingResult && !anim::Disabled())) { - _history->peer->owner().updateSpeakingAnimation({ + _history->peer->owner().sendActionManager().updateSpeakingAnimation({ _history }); } diff --git a/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp b/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp index 22775a6630..1c45f7b47d 100644 --- a/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp +++ b/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp @@ -44,6 +44,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_chat.h" #include "data/data_user.h" #include "data/data_changes.h" +#include "data/data_send_action.h" #include "base/unixtime.h" #include "support/support_helper.h" #include "apiwrap.h" @@ -124,8 +125,8 @@ TopBarWidget::TopBarWidget( refreshUnreadBadge(); { - using AnimationUpdate = Data::Session::SendActionAnimationUpdate; - session().data().sendActionAnimationUpdated( + using AnimationUpdate = Data::SendActionManager::AnimationUpdate; + session().data().sendActionManager().animationUpdated( ) | rpl::filter([=](const AnimationUpdate &update) { return (update.history == _activeChat.key.history()); }) | rpl::start_with_next([=] {