Instantly mark as read visible new reactions.

This commit is contained in:
John Preston 2022-01-28 14:24:07 +03:00
parent f6bfe2c9a8
commit e509da8fd8
5 changed files with 46 additions and 8 deletions

View file

@ -32,7 +32,7 @@ inline constexpr int CountBit(Flag Last = Flag::LastUsedBit) {
++i; ++i;
Assert(i != 64); Assert(i != 64);
} }
return (i + 1); return i;
} }
} // namespace details } // namespace details
@ -151,8 +151,9 @@ struct MessageUpdate {
BotCallbackSent = (1U << 6), BotCallbackSent = (1U << 6),
NewMaybeAdded = (1U << 7), NewMaybeAdded = (1U << 7),
RepliesUnreadCount = (1U << 8), RepliesUnreadCount = (1U << 8),
NewUnreadReaction = (1U << 9),
LastUsedBit = (1U << 8), LastUsedBit = (1U << 9),
}; };
using Flags = base::flags<Flag>; using Flags = base::flags<Flag>;
friend inline constexpr auto is_flag_type(Flag) { return true; } friend inline constexpr auto is_flag_type(Flag) { return true; }
@ -271,9 +272,11 @@ private:
void sendNotifications(); void sendNotifications();
private: private:
static constexpr auto kCount = details::CountBit<Flag>(); static constexpr auto kCount = details::CountBit<Flag>() + 1;
void sendRealtimeNotifications(not_null<DataType*> data, Flags flags); void sendRealtimeNotifications(
not_null<DataType*> data,
Flags flags);
std::array<rpl::event_stream<UpdateType>, kCount> _realtimeStreams; std::array<rpl::event_stream<UpdateType>, kCount> _realtimeStreams;
base::flat_map<not_null<DataType*>, Flags> _updates; base::flat_map<not_null<DataType*>, Flags> _updates;

View file

@ -852,8 +852,9 @@ void HistoryItem::updateReactions(const MTPMessageReactions *reactions) {
setReactions(reactions); setReactions(reactions);
const auto hasUnread = hasUnreadReaction(); const auto hasUnread = hasUnreadReaction();
if (hasUnread && !hadUnread) { if (hasUnread && !hadUnread) {
// This may read the reaction already.
addToUnreadThings(HistoryUnreadThings::AddType::New); addToUnreadThings(HistoryUnreadThings::AddType::New);
if (toContact) { if (toContact && hasUnreadReaction()) {
const auto notification = ItemNotification{ const auto notification = ItemNotification{
this, this,
ItemNotificationType::Reaction, ItemNotificationType::Reaction,

View file

@ -1543,9 +1543,16 @@ void HistoryMessage::addToUnreadThings(HistoryUnreadThings::AddType type) {
} }
if (hasUnreadReaction()) { if (hasUnreadReaction()) {
if (history()->unreadReactions().add(id, type)) { if (history()->unreadReactions().add(id, type)) {
history()->session().changes().historyUpdated( if (type == HistoryUnreadThings::AddType::New) {
history(), history()->session().changes().messageUpdated(
Data::HistoryUpdate::Flag::UnreadReactions); this,
Data::MessageUpdate::Flag::NewUnreadReaction);
}
if (hasUnreadReaction()) {
history()->session().changes().historyUpdated(
history(),
Data::HistoryUpdate::Flag::UnreadReactions);
}
} }
} }
} }

View file

@ -651,6 +651,12 @@ HistoryWidget::HistoryWidget(
} }
}, lifetime()); }, lifetime());
session().changes().realtimeMessageUpdates(
MessageUpdateFlag::NewUnreadReaction
) | rpl::start_with_next([=](const Data::MessageUpdate &update) {
maybeMarkReactionsRead(update.item);
}, lifetime());
using MediaSwitch = Media::Player::Instance::Switch; using MediaSwitch = Media::Player::Instance::Switch;
Media::Player::instance()->switchToNextEvents( Media::Player::instance()->switchToNextEvents(
) | rpl::filter([=](const MediaSwitch &pair) { ) | rpl::filter([=](const MediaSwitch &pair) {
@ -2802,6 +2808,26 @@ void HistoryWidget::newItemAdded(not_null<HistoryItem*> item) {
_itemRevealPending.emplace(item); _itemRevealPending.emplace(item);
} }
void HistoryWidget::maybeMarkReactionsRead(not_null<HistoryItem*> 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() { void HistoryWidget::unreadCountUpdated() {
if (_history->chatListUnreadMark()) { if (_history->chatListUnreadMark()) {
crl::on_main(this, [=, history = _history] { crl::on_main(this, [=, history = _history] {

View file

@ -423,6 +423,7 @@ private:
void cornerButtonsAnimationFinish(); void cornerButtonsAnimationFinish();
void sendButtonClicked(); void sendButtonClicked();
void newItemAdded(not_null<HistoryItem*> item); void newItemAdded(not_null<HistoryItem*> item);
void maybeMarkReactionsRead(not_null<HistoryItem*> item);
void updateCornerButtonsPositions(); void updateCornerButtonsPositions();
void updateHistoryDownVisibility(); void updateHistoryDownVisibility();