Count unread replies locally when possible.

This commit is contained in:
John Preston 2021-08-30 19:22:16 +03:00
parent c39024c7fd
commit 52a6282eb9
5 changed files with 62 additions and 9 deletions

View File

@ -2094,7 +2094,9 @@ void Updates::feedUpdate(const MTPUpdate &update) {
const auto msgId = d.vtop_msg_id().v;
const auto readTillId = d.vread_max_id().v;
const auto item = session().data().message(channelId, msgId);
const auto unreadCount = std::nullopt;
const auto unreadCount = item
? session().data().countUnreadRepliesLocally(item, readTillId)
: std::nullopt;
if (item) {
item->setRepliesInboxReadTill(readTillId, unreadCount);
if (const auto post = item->lookupDiscussionPostOriginal()) {

View File

@ -2360,6 +2360,23 @@ void Session::notifyUnreadBadgeChanged() {
_unreadBadgeChanges.fire({});
}
std::optional<int> Session::countUnreadRepliesLocally(
not_null<HistoryItem*> root,
MsgId afterId) const {
auto result = std::optional<int>();
_unreadRepliesCountRequests.fire({
.root = root,
.afterId = afterId,
.result = &result,
});
return result;
}
auto Session::unreadRepliesCountRequests() const
-> rpl::producer<UnreadRepliesCountRequest> {
return _unreadRepliesCountRequests.events();
}
int Session::computeUnreadBadge(const Dialogs::UnreadState &state) const {
const auto all = Core::App().settings().includeMutedCounter();
return std::max(state.marks - (all ? 0 : state.marksMuted), 0)

View File

@ -430,11 +430,23 @@ public:
[[nodiscard]] int unreadBadge() const;
[[nodiscard]] bool unreadBadgeMuted() const;
[[nodiscard]] int unreadBadgeIgnoreOne(const Dialogs::Key &key) const;
[[nodiscard]] bool unreadBadgeMutedIgnoreOne(const Dialogs::Key &key) const;
[[nodiscard]] bool unreadBadgeMutedIgnoreOne(
const Dialogs::Key &key) const;
[[nodiscard]] int unreadOnlyMutedBadge() const;
[[nodiscard]] rpl::producer<> unreadBadgeChanges() const;
void notifyUnreadBadgeChanged();
[[nodiscard]] std::optional<int> countUnreadRepliesLocally(
not_null<HistoryItem*> root,
MsgId afterId) const;
struct UnreadRepliesCountRequest {
not_null<HistoryItem*> root;
MsgId afterId = 0;
not_null<std::optional<int>*> result;
};
[[nodiscard]] auto unreadRepliesCountRequests() const
-> rpl::producer<UnreadRepliesCountRequest>;
void selfDestructIn(not_null<HistoryItem*> item, crl::time delay);
[[nodiscard]] not_null<PhotoData*> photo(PhotoId id);
@ -855,6 +867,7 @@ private:
rpl::event_stream<DialogsRowReplacement> _dialogsRowReplacements;
rpl::event_stream<ChatListEntryRefresh> _chatListEntryRefreshes;
rpl::event_stream<> _unreadBadgeChanges;
rpl::event_stream<UnreadRepliesCountRequest> _unreadRepliesCountRequests;
Dialogs::MainList _chatsList;
Dialogs::IndexedList _contactsList;

View File

@ -275,6 +275,17 @@ RepliesWidget::RepliesWidget(
_inner->update();
}, lifetime());
_history->session().data().unreadRepliesCountRequests(
) | rpl::filter([=](
const Data::Session::UnreadRepliesCountRequest &request) {
return (request.root.get() == _root);
}) | rpl::start_with_next([=](
const Data::Session::UnreadRepliesCountRequest &request) {
if (const auto result = computeUnreadCountLocally(request.afterId)) {
*request.result = result;
}
}, lifetime());
setupScrollDownButton();
setupComposeControls();
orderWidgets();
@ -1762,6 +1773,20 @@ void RepliesWidget::listSelectionChanged(SelectedItems &&items) {
_topBar->showSelected(state);
}
std::optional<int> RepliesWidget::computeUnreadCountLocally(
MsgId afterId) const {
const auto views = _root ? _root->Get<HistoryMessageViews>() : nullptr;
if (!views) {
return std::nullopt;
}
const auto wasReadTillId = views->repliesInboxReadTillId;
const auto wasUnreadCount = views->repliesUnreadCount;
return _replies->fullUnreadCountAfter(
afterId,
wasReadTillId,
wasUnreadCount);
}
void RepliesWidget::readTill(not_null<HistoryItem*> item) {
if (!_root) {
return;
@ -1771,13 +1796,7 @@ void RepliesWidget::readTill(not_null<HistoryItem*> item) {
if (now < was) {
return;
}
const auto views = _root->Get<HistoryMessageViews>();
const auto wasReadTillId = views ? views->repliesInboxReadTillId : 0;
const auto wasUnreadCount = views ? views->repliesUnreadCount : -1;
const auto unreadCount = _replies->fullUnreadCountAfter(
now,
wasReadTillId,
wasUnreadCount);
const auto unreadCount = computeUnreadCountLocally(now);
const auto fast = item->out() || !unreadCount.has_value();
if (was < now || (fast && now == was)) {
_root->setRepliesInboxReadTill(now, unreadCount);

View File

@ -173,6 +173,8 @@ private:
void setupDragArea();
void sendReadTillRequest();
void readTill(not_null<HistoryItem*> item);
[[nodiscard]] std::optional<int> computeUnreadCountLocally(
MsgId afterId) const;
void setupScrollDownButton();
void scrollDownClicked();