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 msgId = d.vtop_msg_id().v;
const auto readTillId = d.vread_max_id().v; const auto readTillId = d.vread_max_id().v;
const auto item = session().data().message(channelId, msgId); 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) { if (item) {
item->setRepliesInboxReadTill(readTillId, unreadCount); item->setRepliesInboxReadTill(readTillId, unreadCount);
if (const auto post = item->lookupDiscussionPostOriginal()) { if (const auto post = item->lookupDiscussionPostOriginal()) {

View file

@ -2360,6 +2360,23 @@ void Session::notifyUnreadBadgeChanged() {
_unreadBadgeChanges.fire({}); _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 { int Session::computeUnreadBadge(const Dialogs::UnreadState &state) const {
const auto all = Core::App().settings().includeMutedCounter(); const auto all = Core::App().settings().includeMutedCounter();
return std::max(state.marks - (all ? 0 : state.marksMuted), 0) return std::max(state.marks - (all ? 0 : state.marksMuted), 0)

View file

@ -430,11 +430,23 @@ public:
[[nodiscard]] int unreadBadge() const; [[nodiscard]] int unreadBadge() const;
[[nodiscard]] bool unreadBadgeMuted() const; [[nodiscard]] bool unreadBadgeMuted() const;
[[nodiscard]] int unreadBadgeIgnoreOne(const Dialogs::Key &key) 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]] int unreadOnlyMutedBadge() const;
[[nodiscard]] rpl::producer<> unreadBadgeChanges() const; [[nodiscard]] rpl::producer<> unreadBadgeChanges() const;
void notifyUnreadBadgeChanged(); 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); void selfDestructIn(not_null<HistoryItem*> item, crl::time delay);
[[nodiscard]] not_null<PhotoData*> photo(PhotoId id); [[nodiscard]] not_null<PhotoData*> photo(PhotoId id);
@ -855,6 +867,7 @@ private:
rpl::event_stream<DialogsRowReplacement> _dialogsRowReplacements; rpl::event_stream<DialogsRowReplacement> _dialogsRowReplacements;
rpl::event_stream<ChatListEntryRefresh> _chatListEntryRefreshes; rpl::event_stream<ChatListEntryRefresh> _chatListEntryRefreshes;
rpl::event_stream<> _unreadBadgeChanges; rpl::event_stream<> _unreadBadgeChanges;
rpl::event_stream<UnreadRepliesCountRequest> _unreadRepliesCountRequests;
Dialogs::MainList _chatsList; Dialogs::MainList _chatsList;
Dialogs::IndexedList _contactsList; Dialogs::IndexedList _contactsList;

View file

@ -275,6 +275,17 @@ RepliesWidget::RepliesWidget(
_inner->update(); _inner->update();
}, lifetime()); }, 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(); setupScrollDownButton();
setupComposeControls(); setupComposeControls();
orderWidgets(); orderWidgets();
@ -1762,6 +1773,20 @@ void RepliesWidget::listSelectionChanged(SelectedItems &&items) {
_topBar->showSelected(state); _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) { void RepliesWidget::readTill(not_null<HistoryItem*> item) {
if (!_root) { if (!_root) {
return; return;
@ -1771,13 +1796,7 @@ void RepliesWidget::readTill(not_null<HistoryItem*> item) {
if (now < was) { if (now < was) {
return; return;
} }
const auto views = _root->Get<HistoryMessageViews>(); const auto unreadCount = computeUnreadCountLocally(now);
const auto wasReadTillId = views ? views->repliesInboxReadTillId : 0;
const auto wasUnreadCount = views ? views->repliesUnreadCount : -1;
const auto unreadCount = _replies->fullUnreadCountAfter(
now,
wasReadTillId,
wasUnreadCount);
const auto fast = item->out() || !unreadCount.has_value(); const auto fast = item->out() || !unreadCount.has_value();
if (was < now || (fast && now == was)) { if (was < now || (fast && now == was)) {
_root->setRepliesInboxReadTill(now, unreadCount); _root->setRepliesInboxReadTill(now, unreadCount);

View file

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