mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-16 14:17:12 +02:00
Track and display unread count in discussions.
This commit is contained in:
parent
85e4c8527b
commit
c39024c7fd
12 changed files with 271 additions and 45 deletions
|
@ -2094,17 +2094,18 @@ 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;
|
||||
if (item) {
|
||||
item->setRepliesInboxReadTill(readTillId);
|
||||
item->setRepliesInboxReadTill(readTillId, unreadCount);
|
||||
if (const auto post = item->lookupDiscussionPostOriginal()) {
|
||||
post->setRepliesInboxReadTill(readTillId);
|
||||
post->setRepliesInboxReadTill(readTillId, unreadCount);
|
||||
}
|
||||
}
|
||||
if (const auto broadcastId = d.vbroadcast_id()) {
|
||||
if (const auto post = session().data().message(
|
||||
broadcastId->v,
|
||||
d.vbroadcast_post()->v)) {
|
||||
post->setRepliesInboxReadTill(readTillId);
|
||||
post->setRepliesInboxReadTill(readTillId, unreadCount);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
|
|
@ -134,16 +134,17 @@ struct MessageUpdate {
|
|||
enum class Flag : uint32 {
|
||||
None = 0,
|
||||
|
||||
Edited = (1U << 0),
|
||||
Destroyed = (1U << 1),
|
||||
DialogRowRepaint = (1U << 2),
|
||||
DialogRowRefresh = (1U << 3),
|
||||
NewAdded = (1U << 4),
|
||||
ReplyMarkup = (1U << 5),
|
||||
BotCallbackSent = (1U << 6),
|
||||
NewMaybeAdded = (1U << 7),
|
||||
Edited = (1U << 0),
|
||||
Destroyed = (1U << 1),
|
||||
DialogRowRepaint = (1U << 2),
|
||||
DialogRowRefresh = (1U << 3),
|
||||
NewAdded = (1U << 4),
|
||||
ReplyMarkup = (1U << 5),
|
||||
BotCallbackSent = (1U << 6),
|
||||
NewMaybeAdded = (1U << 7),
|
||||
RepliesUnreadCount = (1U << 8),
|
||||
|
||||
LastUsedBit = (1U << 7),
|
||||
LastUsedBit = (1U << 7),
|
||||
};
|
||||
using Flags = base::flags<Flag>;
|
||||
friend inline constexpr auto is_flag_type(Flag) { return true; }
|
||||
|
|
|
@ -101,6 +101,15 @@ rpl::producer<MessagesSlice> RepliesList::source(
|
|||
_partLoaded.events(
|
||||
) | rpl::start_with_next(pushDelayed, lifetime);
|
||||
|
||||
_history->session().data().channelDifferenceTooLong(
|
||||
) | rpl::filter([=](not_null<ChannelData*> channel) {
|
||||
if (_history->peer != channel || !_skippedAfter.has_value()) {
|
||||
return false;
|
||||
}
|
||||
_skippedAfter = std::nullopt;
|
||||
return true;
|
||||
}) | rpl::start_with_next(pushDelayed, lifetime);
|
||||
|
||||
push();
|
||||
return lifetime;
|
||||
};
|
||||
|
@ -169,6 +178,64 @@ rpl::producer<int> RepliesList::fullCount() const {
|
|||
return _fullCount.value() | rpl::filter_optional();
|
||||
}
|
||||
|
||||
std::optional<int> RepliesList::fullUnreadCountAfter(
|
||||
MsgId readTillId,
|
||||
MsgId wasReadTillId,
|
||||
std::optional<int> wasUnreadCountAfter) const {
|
||||
Expects(readTillId >= wasReadTillId);
|
||||
|
||||
readTillId = std::max(readTillId, _rootId);
|
||||
wasReadTillId = std::max(wasReadTillId, _rootId);
|
||||
const auto backLoaded = (_skippedBefore == 0);
|
||||
const auto frontLoaded = (_skippedAfter == 0);
|
||||
const auto fullLoaded = backLoaded && frontLoaded;
|
||||
const auto allUnread = (readTillId == _rootId)
|
||||
|| (fullLoaded && _list.empty());
|
||||
const auto countIncoming = [&](auto from, auto till) {
|
||||
auto &owner = _history->owner();
|
||||
const auto channelId = _history->channelId();
|
||||
auto count = 0;
|
||||
for (auto i = from; i != till; ++i) {
|
||||
if (!owner.message(channelId, *i)->out()) {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
};
|
||||
if (allUnread && fullLoaded) {
|
||||
// Should not happen too often unless the list is empty.
|
||||
return countIncoming(begin(_list), end(_list));
|
||||
} else if (frontLoaded && !_list.empty() && readTillId >= _list.front()) {
|
||||
// Always "count by local data" if read till the end.
|
||||
return 0;
|
||||
} else if (wasReadTillId == readTillId) {
|
||||
// Otherwise don't recount the same value over and over.
|
||||
return wasUnreadCountAfter;
|
||||
} else if (frontLoaded && !_list.empty() && readTillId >= _list.back()) {
|
||||
// And count by local data if it is available and read-till changed.
|
||||
return countIncoming(
|
||||
begin(_list),
|
||||
ranges::lower_bound(_list, readTillId, std::greater<>()));
|
||||
} else if (_list.empty()) {
|
||||
return std::nullopt;
|
||||
} else if (wasUnreadCountAfter.has_value()
|
||||
&& (frontLoaded || readTillId <= _list.front())
|
||||
&& (backLoaded || wasReadTillId >= _list.back())) {
|
||||
// Count how many were read since previous value.
|
||||
const auto from = ranges::lower_bound(
|
||||
_list,
|
||||
readTillId,
|
||||
std::greater<>());
|
||||
const auto till = ranges::lower_bound(
|
||||
from,
|
||||
end(_list),
|
||||
wasReadTillId,
|
||||
std::greater<>());
|
||||
return std::max(*wasUnreadCountAfter - countIncoming(from, till), 0);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
void RepliesList::injectRootMessageAndReverse(not_null<Viewer*> viewer) {
|
||||
injectRootMessage(viewer);
|
||||
ranges::reverse(viewer->slice.ids);
|
||||
|
|
|
@ -31,6 +31,11 @@ public:
|
|||
|
||||
[[nodiscard]] rpl::producer<int> fullCount() const;
|
||||
|
||||
[[nodiscard]] std::optional<int> fullUnreadCountAfter(
|
||||
MsgId readTillId,
|
||||
MsgId wasReadTillId,
|
||||
std::optional<int> wasUnreadCountAfter) const;
|
||||
|
||||
private:
|
||||
struct Viewer;
|
||||
|
||||
|
|
|
@ -223,7 +223,9 @@ public:
|
|||
[[nodiscard]] virtual MsgId repliesInboxReadTill() const {
|
||||
return MsgId(0);
|
||||
}
|
||||
virtual void setRepliesInboxReadTill(MsgId readTillId) {
|
||||
virtual void setRepliesInboxReadTill(
|
||||
MsgId readTillId,
|
||||
std::optional<int> unreadCount) {
|
||||
}
|
||||
[[nodiscard]] virtual MsgId computeRepliesInboxReadTillFull() const {
|
||||
return MsgId(0);
|
||||
|
@ -316,7 +318,10 @@ public:
|
|||
}
|
||||
virtual void clearReplies() {
|
||||
}
|
||||
virtual void changeRepliesCount(int delta, PeerId replier) {
|
||||
virtual void changeRepliesCount(
|
||||
int delta,
|
||||
PeerId replier,
|
||||
std::optional<bool> unread) {
|
||||
}
|
||||
virtual void setReplyToTop(MsgId replyToTop) {
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@ struct HistoryMessageViews : public RuntimeComponent<HistoryMessageViews, Histor
|
|||
MsgId repliesInboxReadTillId = 0;
|
||||
MsgId repliesOutboxReadTillId = 0;
|
||||
MsgId repliesMaxId = 0;
|
||||
int repliesUnreadCount = -1; // unknown
|
||||
ChannelId commentsMegagroupId = 0;
|
||||
MsgId commentsRootId = 0;
|
||||
};
|
||||
|
|
|
@ -816,16 +816,30 @@ MsgId HistoryMessage::repliesInboxReadTill() const {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void HistoryMessage::setRepliesInboxReadTill(MsgId readTillId) {
|
||||
void HistoryMessage::setRepliesInboxReadTill(
|
||||
MsgId readTillId,
|
||||
std::optional<int> unreadCount) {
|
||||
if (const auto views = Get<HistoryMessageViews>()) {
|
||||
const auto newReadTillId = std::max(readTillId, 1);
|
||||
if (newReadTillId > views->repliesInboxReadTillId) {
|
||||
const auto ignore = (newReadTillId < views->repliesInboxReadTillId);
|
||||
if (ignore) {
|
||||
return;
|
||||
}
|
||||
const auto changed = (newReadTillId > views->repliesInboxReadTillId);
|
||||
if (changed) {
|
||||
const auto wasUnread = repliesAreComments() && areRepliesUnread();
|
||||
views->repliesInboxReadTillId = newReadTillId;
|
||||
if (wasUnread && !areRepliesUnread()) {
|
||||
history()->owner().requestItemRepaint(this);
|
||||
}
|
||||
}
|
||||
const auto wasUnreadCount = (views->repliesUnreadCount >= 0)
|
||||
? std::make_optional(views->repliesUnreadCount)
|
||||
: std::nullopt;
|
||||
if (unreadCount != wasUnreadCount
|
||||
&& (changed || unreadCount.has_value())) {
|
||||
setUnreadRepliesCount(views, unreadCount.value_or(-1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1808,10 +1822,27 @@ void HistoryMessage::refreshRepliesText(
|
|||
}
|
||||
}
|
||||
|
||||
void HistoryMessage::changeRepliesCount(int delta, PeerId replier) {
|
||||
void HistoryMessage::changeRepliesCount(
|
||||
int delta,
|
||||
PeerId replier,
|
||||
std::optional<bool> unread) {
|
||||
const auto views = Get<HistoryMessageViews>();
|
||||
const auto limit = HistoryMessageViews::kMaxRecentRepliers;
|
||||
if (!views || views->replies.count < 0) {
|
||||
if (!views) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Update unread count.
|
||||
if (!unread) {
|
||||
setUnreadRepliesCount(views, -1);
|
||||
} else if (views->repliesUnreadCount >= 0 && *unread) {
|
||||
setUnreadRepliesCount(
|
||||
views,
|
||||
std::max(views->repliesUnreadCount + delta, 0));
|
||||
}
|
||||
|
||||
// Update full count.
|
||||
if (views->replies.count < 0) {
|
||||
return;
|
||||
}
|
||||
views->replies.count = std::max(views->replies.count + delta, 0);
|
||||
|
@ -1830,6 +1861,19 @@ void HistoryMessage::changeRepliesCount(int delta, PeerId replier) {
|
|||
refreshRepliesText(views);
|
||||
}
|
||||
|
||||
void HistoryMessage::setUnreadRepliesCount(
|
||||
not_null<HistoryMessageViews*> views,
|
||||
int count) {
|
||||
// Track unread count in discussion forwards, not in the channel posts.
|
||||
if (views->repliesUnreadCount == count || views->commentsMegagroupId) {
|
||||
return;
|
||||
}
|
||||
views->repliesUnreadCount = count;
|
||||
history()->session().changes().messageUpdated(
|
||||
this,
|
||||
Data::MessageUpdate::Flag::RepliesUnreadCount);
|
||||
}
|
||||
|
||||
void HistoryMessage::setReplyToTop(MsgId replyToTop) {
|
||||
const auto reply = Get<HistoryMessageReply>();
|
||||
if (!reply
|
||||
|
@ -1877,19 +1921,23 @@ void HistoryMessage::changeReplyToTopCounter(
|
|||
if (!top) {
|
||||
return;
|
||||
}
|
||||
const auto changeFor = [&](not_null<HistoryItem*> item) {
|
||||
if (const auto from = displayFrom()) {
|
||||
item->changeRepliesCount(delta, from->id);
|
||||
return;
|
||||
}
|
||||
item->changeRepliesCount(delta, PeerId());
|
||||
};
|
||||
auto unread = out() ? std::make_optional(false) : std::nullopt;
|
||||
if (const auto views = top->Get<HistoryMessageViews>()) {
|
||||
if (views->commentsMegagroupId) {
|
||||
// This is a post in channel, we don't track its replies.
|
||||
return;
|
||||
}
|
||||
if (views->repliesInboxReadTillId > 0) {
|
||||
unread = !out() && (id > views->repliesInboxReadTillId);
|
||||
}
|
||||
}
|
||||
const auto changeFor = [&](not_null<HistoryItem*> item) {
|
||||
if (const auto from = displayFrom()) {
|
||||
item->changeRepliesCount(delta, from->id, unread);
|
||||
} else {
|
||||
item->changeRepliesCount(delta, PeerId(), unread);
|
||||
}
|
||||
};
|
||||
changeFor(top);
|
||||
if (const auto original = top->lookupDiscussionPostOriginal()) {
|
||||
changeFor(original);
|
||||
|
|
|
@ -133,7 +133,10 @@ public:
|
|||
void setForwardsCount(int count) override;
|
||||
void setReplies(const MTPMessageReplies &data) override;
|
||||
void clearReplies() override;
|
||||
void changeRepliesCount(int delta, PeerId replier) override;
|
||||
void changeRepliesCount(
|
||||
int delta,
|
||||
PeerId replier,
|
||||
std::optional<bool> unread) override;
|
||||
void setReplyToTop(MsgId replyToTop) override;
|
||||
void setPostAuthor(const QString &author) override;
|
||||
void setRealId(MsgId newId) override;
|
||||
|
@ -181,7 +184,9 @@ public:
|
|||
[[nodiscard]] bool externalReply() const override;
|
||||
|
||||
[[nodiscard]] MsgId repliesInboxReadTill() const override;
|
||||
void setRepliesInboxReadTill(MsgId readTillId) override;
|
||||
void setRepliesInboxReadTill(
|
||||
MsgId readTillId,
|
||||
std::optional<int> unreadCount) override;
|
||||
[[nodiscard]] MsgId computeRepliesInboxReadTillFull() const override;
|
||||
[[nodiscard]] MsgId repliesOutboxReadTill() const override;
|
||||
void setRepliesOutboxReadTill(MsgId readTillId) override;
|
||||
|
@ -250,6 +255,9 @@ private:
|
|||
void refreshRepliesText(
|
||||
not_null<HistoryMessageViews*> views,
|
||||
bool forceResize = false);
|
||||
void setUnreadRepliesCount(
|
||||
not_null<HistoryMessageViews*> views,
|
||||
int count);
|
||||
|
||||
static void FillForwardedInfo(
|
||||
CreateConfig &config,
|
||||
|
|
|
@ -160,7 +160,6 @@ private:
|
|||
bool _scrollDownIsShown = false;
|
||||
object_ptr<Ui::HistoryDownButton> _scrollDown;
|
||||
|
||||
Data::MessagesSlice _lastSlice;
|
||||
int _messagesCount = -1;
|
||||
|
||||
};
|
||||
|
|
|
@ -247,16 +247,24 @@ RepliesWidget::RepliesWidget(
|
|||
data.progress);
|
||||
}, lifetime());
|
||||
|
||||
using MessageUpdateFlag = Data::MessageUpdate::Flag;
|
||||
_history->session().changes().messageUpdates(
|
||||
Data::MessageUpdate::Flag::Destroyed
|
||||
MessageUpdateFlag::Destroyed
|
||||
| MessageUpdateFlag::RepliesUnreadCount
|
||||
) | rpl::start_with_next([=](const Data::MessageUpdate &update) {
|
||||
if (update.item == _root) {
|
||||
_root = nullptr;
|
||||
updatePinnedVisibility();
|
||||
controller->showBackFromStack();
|
||||
}
|
||||
while (update.item == _replyReturn) {
|
||||
calculateNextReplyReturn();
|
||||
if (update.flags & MessageUpdateFlag::Destroyed) {
|
||||
if (update.item == _root) {
|
||||
_root = nullptr;
|
||||
updatePinnedVisibility();
|
||||
controller->showBackFromStack();
|
||||
}
|
||||
while (update.item == _replyReturn) {
|
||||
calculateNextReplyReturn();
|
||||
}
|
||||
return;
|
||||
} else if ((update.item == _root)
|
||||
&& (update.flags & MessageUpdateFlag::RepliesUnreadCount)) {
|
||||
refreshUnreadCountBadge();
|
||||
}
|
||||
}, lifetime());
|
||||
|
||||
|
@ -302,12 +310,15 @@ void RepliesWidget::sendReadTillRequest() {
|
|||
_readRequestPending = false;
|
||||
const auto api = &_history->session().api();
|
||||
api->request(base::take(_readRequestId)).cancel();
|
||||
|
||||
_readRequestId = api->request(MTPmessages_ReadDiscussion(
|
||||
_root->history()->peer->input,
|
||||
MTP_int(_root->id),
|
||||
MTP_int(_root->computeRepliesInboxReadTillFull())
|
||||
)).done([=](const MTPBool &) {
|
||||
}).send();
|
||||
)).done(crl::guard(this, [=](const MTPBool &) {
|
||||
_readRequestId = 0;
|
||||
reloadUnreadCountIfNeeded();
|
||||
})).send();
|
||||
}
|
||||
|
||||
void RepliesWidget::setupRoot() {
|
||||
|
@ -317,6 +328,7 @@ void RepliesWidget::setupRoot() {
|
|||
_root = lookupRoot();
|
||||
if (_root) {
|
||||
_areComments = computeAreComments();
|
||||
refreshUnreadCountBadge();
|
||||
if (_readRequestPending) {
|
||||
sendReadTillRequest();
|
||||
}
|
||||
|
@ -370,6 +382,19 @@ bool RepliesWidget::computeAreComments() const {
|
|||
return _root && _root->isDiscussionPost();
|
||||
}
|
||||
|
||||
std::optional<int> RepliesWidget::computeUnreadCount() const {
|
||||
if (!_root) {
|
||||
return std::nullopt;
|
||||
}
|
||||
const auto views = _root->Get<HistoryMessageViews>();
|
||||
if (!views) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return (views->repliesUnreadCount >= 0)
|
||||
? std::make_optional(views->repliesUnreadCount)
|
||||
: std::nullopt;
|
||||
}
|
||||
|
||||
void RepliesWidget::setupComposeControls() {
|
||||
auto slowmodeSecondsLeft = session().changes().peerFlagsValue(
|
||||
_history->peer,
|
||||
|
@ -1143,6 +1168,7 @@ void RepliesWidget::setupScrollDownButton() {
|
|||
_scrollDown->setClickedCallback([=] {
|
||||
scrollDownClicked();
|
||||
});
|
||||
refreshUnreadCountBadge();
|
||||
base::install_event_filter(_scrollDown, [=](not_null<QEvent*> event) {
|
||||
if (event->type() != QEvent::Wheel) {
|
||||
return base::EventFilterResult::Continue;
|
||||
|
@ -1154,6 +1180,56 @@ void RepliesWidget::setupScrollDownButton() {
|
|||
updateScrollDownVisibility();
|
||||
}
|
||||
|
||||
void RepliesWidget::refreshUnreadCountBadge() {
|
||||
if (!_root) {
|
||||
return;
|
||||
} else if (const auto count = computeUnreadCount()) {
|
||||
_scrollDown->setUnreadCount(*count);
|
||||
} else if (!_readRequestPending
|
||||
&& !_readRequestTimer.isActive()
|
||||
&& !_readRequestId) {
|
||||
reloadUnreadCountIfNeeded();
|
||||
}
|
||||
}
|
||||
|
||||
void RepliesWidget::reloadUnreadCountIfNeeded() {
|
||||
const auto views = _root ? _root->Get<HistoryMessageViews>() : nullptr;
|
||||
if (!views || views->repliesUnreadCount >= 0) {
|
||||
return;
|
||||
} else if (views->repliesInboxReadTillId
|
||||
< _root->computeRepliesInboxReadTillFull()) {
|
||||
_readRequestTimer.callOnce(0);
|
||||
} else if (!_reloadUnreadCountRequestId) {
|
||||
const auto session = &_history->session();
|
||||
const auto fullId = _root->fullId();
|
||||
const auto apply = [session, fullId](int readTill, int unreadCount) {
|
||||
if (const auto root = session->data().message(fullId)) {
|
||||
root->setRepliesInboxReadTill(readTill, unreadCount);
|
||||
if (const auto post = root->lookupDiscussionPostOriginal()) {
|
||||
post->setRepliesInboxReadTill(readTill, unreadCount);
|
||||
}
|
||||
}
|
||||
};
|
||||
const auto weak = Ui::MakeWeak(this);
|
||||
_reloadUnreadCountRequestId = session->api().request(
|
||||
MTPmessages_GetDiscussionMessage(
|
||||
_history->peer->input,
|
||||
MTP_int(_rootId))
|
||||
).done([=](const MTPmessages_DiscussionMessage &result) {
|
||||
if (weak) {
|
||||
_reloadUnreadCountRequestId = 0;
|
||||
}
|
||||
result.match([&](const MTPDmessages_discussionMessage &data) {
|
||||
session->data().processUsers(data.vusers());
|
||||
session->data().processChats(data.vchats());
|
||||
apply(
|
||||
data.vread_inbox_max_id().value_or_empty(),
|
||||
data.vunread_count().v);
|
||||
});
|
||||
}).send();
|
||||
}
|
||||
}
|
||||
|
||||
void RepliesWidget::scrollDownClicked() {
|
||||
if (QGuiApplication::keyboardModifiers() == Qt::ControlModifier) {
|
||||
showAtEnd();
|
||||
|
@ -1692,11 +1768,21 @@ void RepliesWidget::readTill(not_null<HistoryItem*> item) {
|
|||
}
|
||||
const auto was = _root->computeRepliesInboxReadTillFull();
|
||||
const auto now = item->id;
|
||||
const auto fast = item->out();
|
||||
if (was < now) {
|
||||
_root->setRepliesInboxReadTill(now);
|
||||
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 fast = item->out() || !unreadCount.has_value();
|
||||
if (was < now || (fast && now == was)) {
|
||||
_root->setRepliesInboxReadTill(now, unreadCount);
|
||||
if (const auto post = _root->lookupDiscussionPostOriginal()) {
|
||||
post->setRepliesInboxReadTill(now);
|
||||
post->setRepliesInboxReadTill(now, unreadCount);
|
||||
}
|
||||
if (!_readRequestTimer.isActive()) {
|
||||
_readRequestTimer.callOnce(fast ? 0 : kReadRequestTimeout);
|
||||
|
|
|
@ -198,6 +198,7 @@ private:
|
|||
[[nodiscard]] MsgId replyToId() const;
|
||||
[[nodiscard]] HistoryItem *lookupRoot() const;
|
||||
[[nodiscard]] bool computeAreComments() const;
|
||||
[[nodiscard]] std::optional<int> computeUnreadCount() const;
|
||||
void orderWidgets();
|
||||
|
||||
void pushReplyReturn(not_null<HistoryItem*> item);
|
||||
|
@ -208,6 +209,8 @@ private:
|
|||
void recountChatWidth();
|
||||
void replyToMessage(FullMsgId itemId);
|
||||
void refreshTopBarActiveChat();
|
||||
void refreshUnreadCountBadge();
|
||||
void reloadUnreadCountIfNeeded();
|
||||
|
||||
void uploadFile(const QByteArray &fileContent, SendMediaType type);
|
||||
bool confirmSendingFiles(
|
||||
|
@ -276,13 +279,13 @@ private:
|
|||
bool _scrollDownIsShown = false;
|
||||
object_ptr<Ui::HistoryDownButton> _scrollDown;
|
||||
|
||||
Data::MessagesSlice _lastSlice;
|
||||
bool _choosingAttach = false;
|
||||
|
||||
base::Timer _readRequestTimer;
|
||||
bool _readRequestPending = false;
|
||||
mtpRequestId _readRequestId = 0;
|
||||
|
||||
mtpRequestId _reloadUnreadCountRequestId = 0;
|
||||
bool _loaded = false;
|
||||
|
||||
};
|
||||
|
|
|
@ -399,7 +399,8 @@ void SessionNavigation::showRepliesForMessage(
|
|||
item->setRepliesMaxId(maxId->v);
|
||||
}
|
||||
item->setRepliesInboxReadTill(
|
||||
data.vread_inbox_max_id().value_or_empty());
|
||||
data.vread_inbox_max_id().value_or_empty(),
|
||||
data.vunread_count().v);
|
||||
item->setRepliesOutboxReadTill(
|
||||
data.vread_outbox_max_id().value_or_empty());
|
||||
const auto post = _session->data().message(channelId, rootId);
|
||||
|
@ -409,7 +410,8 @@ void SessionNavigation::showRepliesForMessage(
|
|||
post->setRepliesMaxId(maxId->v);
|
||||
}
|
||||
post->setRepliesInboxReadTill(
|
||||
data.vread_inbox_max_id().value_or_empty());
|
||||
data.vread_inbox_max_id().value_or_empty(),
|
||||
data.vunread_count().v);
|
||||
post->setRepliesOutboxReadTill(
|
||||
data.vread_outbox_max_id().value_or_empty());
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue