From e509da8fd83e9b325b7742ff39502ac705042acf Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 28 Jan 2022 14:24:07 +0300 Subject: [PATCH] Instantly mark as read visible new reactions. --- Telegram/SourceFiles/data/data_changes.h | 11 +++++--- Telegram/SourceFiles/history/history_item.cpp | 3 ++- .../SourceFiles/history/history_message.cpp | 13 +++++++--- .../SourceFiles/history/history_widget.cpp | 26 +++++++++++++++++++ Telegram/SourceFiles/history/history_widget.h | 1 + 5 files changed, 46 insertions(+), 8 deletions(-) diff --git a/Telegram/SourceFiles/data/data_changes.h b/Telegram/SourceFiles/data/data_changes.h index ee9e58d44..a7249d3fe 100644 --- a/Telegram/SourceFiles/data/data_changes.h +++ b/Telegram/SourceFiles/data/data_changes.h @@ -32,7 +32,7 @@ inline constexpr int CountBit(Flag Last = Flag::LastUsedBit) { ++i; Assert(i != 64); } - return (i + 1); + return i; } } // namespace details @@ -151,8 +151,9 @@ struct MessageUpdate { BotCallbackSent = (1U << 6), NewMaybeAdded = (1U << 7), RepliesUnreadCount = (1U << 8), + NewUnreadReaction = (1U << 9), - LastUsedBit = (1U << 8), + LastUsedBit = (1U << 9), }; using Flags = base::flags; friend inline constexpr auto is_flag_type(Flag) { return true; } @@ -271,9 +272,11 @@ private: void sendNotifications(); private: - static constexpr auto kCount = details::CountBit(); + static constexpr auto kCount = details::CountBit() + 1; - void sendRealtimeNotifications(not_null data, Flags flags); + void sendRealtimeNotifications( + not_null data, + Flags flags); std::array, kCount> _realtimeStreams; base::flat_map, Flags> _updates; diff --git a/Telegram/SourceFiles/history/history_item.cpp b/Telegram/SourceFiles/history/history_item.cpp index e82d5aff6..25dfe6136 100644 --- a/Telegram/SourceFiles/history/history_item.cpp +++ b/Telegram/SourceFiles/history/history_item.cpp @@ -852,8 +852,9 @@ void HistoryItem::updateReactions(const MTPMessageReactions *reactions) { setReactions(reactions); const auto hasUnread = hasUnreadReaction(); if (hasUnread && !hadUnread) { + // This may read the reaction already. addToUnreadThings(HistoryUnreadThings::AddType::New); - if (toContact) { + if (toContact && hasUnreadReaction()) { const auto notification = ItemNotification{ this, ItemNotificationType::Reaction, diff --git a/Telegram/SourceFiles/history/history_message.cpp b/Telegram/SourceFiles/history/history_message.cpp index edb10a470..9f66763a8 100644 --- a/Telegram/SourceFiles/history/history_message.cpp +++ b/Telegram/SourceFiles/history/history_message.cpp @@ -1543,9 +1543,16 @@ void HistoryMessage::addToUnreadThings(HistoryUnreadThings::AddType type) { } if (hasUnreadReaction()) { if (history()->unreadReactions().add(id, type)) { - history()->session().changes().historyUpdated( - history(), - Data::HistoryUpdate::Flag::UnreadReactions); + if (type == HistoryUnreadThings::AddType::New) { + history()->session().changes().messageUpdated( + this, + Data::MessageUpdate::Flag::NewUnreadReaction); + } + if (hasUnreadReaction()) { + history()->session().changes().historyUpdated( + history(), + Data::HistoryUpdate::Flag::UnreadReactions); + } } } } diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index 70948f25a..3449b35de 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -651,6 +651,12 @@ HistoryWidget::HistoryWidget( } }, lifetime()); + session().changes().realtimeMessageUpdates( + MessageUpdateFlag::NewUnreadReaction + ) | rpl::start_with_next([=](const Data::MessageUpdate &update) { + maybeMarkReactionsRead(update.item); + }, lifetime()); + using MediaSwitch = Media::Player::Instance::Switch; Media::Player::instance()->switchToNextEvents( ) | rpl::filter([=](const MediaSwitch &pair) { @@ -2802,6 +2808,26 @@ void HistoryWidget::newItemAdded(not_null item) { _itemRevealPending.emplace(item); } +void HistoryWidget::maybeMarkReactionsRead(not_null item) { + if (!_historyInited || !_list) { + return; + } + const auto view = item->mainView(); + const auto itemTop = _list->itemTop(view); + if (itemTop <= 0 || !doWeReadMentions()) { + return; + } + const auto reactionCenter + = view->reactionButtonParameters({}, {}).center.y(); + const auto visibleTop = _scroll->scrollTop(); + const auto visibleBottom = visibleTop + _scroll->height(); + if (itemTop + reactionCenter < visibleTop + || itemTop + view->height() > visibleBottom) { + return; + } + session().api().markContentsRead(item); +} + void HistoryWidget::unreadCountUpdated() { if (_history->chatListUnreadMark()) { crl::on_main(this, [=, history = _history] { diff --git a/Telegram/SourceFiles/history/history_widget.h b/Telegram/SourceFiles/history/history_widget.h index a11749841..6d5adfdd9 100644 --- a/Telegram/SourceFiles/history/history_widget.h +++ b/Telegram/SourceFiles/history/history_widget.h @@ -423,6 +423,7 @@ private: void cornerButtonsAnimationFinish(); void sendButtonClicked(); void newItemAdded(not_null item); + void maybeMarkReactionsRead(not_null item); void updateCornerButtonsPositions(); void updateHistoryDownVisibility();