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;
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<Flag>;
friend inline constexpr auto is_flag_type(Flag) { return true; }
@ -271,9 +272,11 @@ private:
void sendNotifications();
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;
base::flat_map<not_null<DataType*>, Flags> _updates;

View file

@ -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,

View file

@ -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);
}
}
}
}

View file

@ -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<HistoryItem*> 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() {
if (_history->chatListUnreadMark()) {
crl::on_main(this, [=, history = _history] {

View file

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