Track inbox/outbox comments/replies read state.

This commit is contained in:
John Preston 2020-09-22 14:01:49 +03:00
parent e021e0beb3
commit 13ad590a51
10 changed files with 257 additions and 192 deletions

View file

@ -1929,8 +1929,35 @@ void Updates::feedUpdate(const MTPUpdate &update) {
case mtpc_updateReadChannelDiscussionInbox: { case mtpc_updateReadChannelDiscussionInbox: {
const auto &d = update.c_updateReadChannelDiscussionInbox(); const auto &d = update.c_updateReadChannelDiscussionInbox();
const auto channelId = d.vchannel_id().v; const auto channelId = d.vchannel_id().v;
if (const auto item = session().data().message(channelId, d.vtop_msg_id().v)) { const auto msgId = d.vtop_msg_id().v;
item->setCommentsReadTill(d.vread_max_id().v); const auto readTillId = d.vread_max_id().v;
const auto item = session().data().message(channelId, msgId);
if (item) {
item->setRepliesInboxReadTill(readTillId);
if (const auto post = item->lookupDiscussionPostOriginal()) {
post->setRepliesInboxReadTill(readTillId);
}
}
if (const auto broadcastId = d.vbroadcast_id()) {
if (const auto post = session().data().message(
broadcastId->v,
d.vbroadcast_post()->v)) {
post->setRepliesInboxReadTill(readTillId);
}
}
} break;
case mtpc_updateReadChannelDiscussionOutbox: {
const auto &d = update.c_updateReadChannelDiscussionOutbox();
const auto channelId = d.vchannel_id().v;
const auto msgId = d.vtop_msg_id().v;
const auto readTillId = d.vread_max_id().v;
const auto item = session().data().message(channelId, msgId);
if (item) {
item->setRepliesOutboxReadTill(readTillId);
if (const auto post = item->lookupDiscussionPostOriginal()) {
post->setRepliesOutboxReadTill(readTillId);
}
} }
} break; } break;

View file

@ -238,9 +238,7 @@ bool RepliesList::buildFromData(not_null<Viewer*> viewer) {
if (viewer->around != ShowAtUnreadMsgId) { if (viewer->around != ShowAtUnreadMsgId) {
return viewer->around; return viewer->around;
} else if (const auto item = lookupRoot()) { } else if (const auto item = lookupRoot()) {
if (const auto original = item->lookupDiscussionPostOriginal()) { return item->computeRepliesInboxReadTillFull();
return original->computeCommentsReadTillFull();
}
} }
return viewer->around; return viewer->around;
}(); }();
@ -565,11 +563,16 @@ bool RepliesList::processMessagesIsEmpty(const MTPmessages_Messages &result) {
_fullCount = checkedCount; _fullCount = checkedCount;
if (const auto item = lookupRoot()) { if (const auto item = lookupRoot()) {
if (_skippedAfter == 0) {
item->setRepliesMaxId(_list.front());
} else {
item->setRepliesPossibleMaxId(maxId);
}
if (const auto original = item->lookupDiscussionPostOriginal()) { if (const auto original = item->lookupDiscussionPostOriginal()) {
if (_skippedAfter == 0) { if (_skippedAfter == 0) {
original->setCommentsMaxId(_list.front()); original->setRepliesMaxId(_list.front());
} else { } else {
original->setCommentsPossibleMaxId(maxId); original->setRepliesPossibleMaxId(maxId);
} }
} }
} }

View file

@ -198,26 +198,36 @@ public:
[[nodiscard]] virtual bool externalReply() const { [[nodiscard]] virtual bool externalReply() const {
return false; return false;
} }
[[nodiscard]] virtual MsgId repliesInboxReadTill() const {
return MsgId(0);
}
virtual void setRepliesInboxReadTill(MsgId readTillId) {
}
[[nodiscard]] virtual MsgId computeRepliesInboxReadTillFull() const {
return MsgId(0);
}
[[nodiscard]] virtual MsgId repliesOutboxReadTill() const {
return MsgId(0);
}
virtual void setRepliesOutboxReadTill(MsgId readTillId) {
}
[[nodiscard]] virtual MsgId computeRepliesOutboxReadTillFull() const {
return MsgId(0);
}
virtual void setRepliesMaxId(MsgId maxId) {
}
virtual void setRepliesPossibleMaxId(MsgId possibleMaxId) {
}
[[nodiscard]] virtual bool areRepliesUnread() const {
return false;
}
[[nodiscard]] virtual FullMsgId commentsItemId() const { [[nodiscard]] virtual FullMsgId commentsItemId() const {
return FullMsgId(); return FullMsgId();
} }
virtual void setCommentsItemId(FullMsgId id) { virtual void setCommentsItemId(FullMsgId id) {
} }
[[nodiscard]] virtual MsgId commentsReadTill() const {
return MsgId(0);
}
virtual void setCommentsReadTill(MsgId readTillId) {
}
virtual void setCommentsMaxId(MsgId maxId) {
}
virtual void setCommentsPossibleMaxId(MsgId possibleMaxId) {
}
[[nodiscard]] virtual MsgId computeCommentsReadTillFull() const {
return MsgId(0);
}
[[nodiscard]] virtual bool areCommentsUnread() const {
return false;
}
[[nodiscard]] virtual bool needCheck() const; [[nodiscard]] virtual bool needCheck() const;

View file

@ -45,10 +45,11 @@ struct HistoryMessageViews : public RuntimeComponent<HistoryMessageViews, Histor
Part views; Part views;
Part replies; Part replies;
Part repliesSmall; Part repliesSmall;
ChannelId commentsChannelId = 0; MsgId repliesInboxReadTillId = 0;
MsgId repliesOutboxReadTillId = 0;
MsgId repliesMaxId = 0;
ChannelId commentsMegagroupId = 0;
MsgId commentsRootId = 0; MsgId commentsRootId = 0;
MsgId commentsReadTillId = 0;
MsgId commentsMaxId = 0;
}; };
struct HistoryMessageSigned : public RuntimeComponent<HistoryMessageSigned, HistoryItem> { struct HistoryMessageSigned : public RuntimeComponent<HistoryMessageSigned, HistoryItem> {

View file

@ -772,7 +772,7 @@ bool HistoryMessage::checkCommentsLinkedChat(ChannelId id) const {
int HistoryMessage::repliesCount() const { int HistoryMessage::repliesCount() const {
if (const auto views = Get<HistoryMessageViews>()) { if (const auto views = Get<HistoryMessageViews>()) {
if (!checkCommentsLinkedChat(views->commentsChannelId)) { if (!checkCommentsLinkedChat(views->commentsMegagroupId)) {
return 0; return 0;
} }
return std::max(views->replies.count, 0); return std::max(views->replies.count, 0);
@ -782,8 +782,8 @@ int HistoryMessage::repliesCount() const {
bool HistoryMessage::repliesAreComments() const { bool HistoryMessage::repliesAreComments() const {
if (const auto views = Get<HistoryMessageViews>()) { if (const auto views = Get<HistoryMessageViews>()) {
return (views->commentsChannelId != 0) return (views->commentsMegagroupId != 0)
&& checkCommentsLinkedChat(views->commentsChannelId); && checkCommentsLinkedChat(views->commentsMegagroupId);
} }
return HistoryItem::repliesAreComments(); return HistoryItem::repliesAreComments();
} }
@ -797,94 +797,139 @@ bool HistoryMessage::externalReply() const {
return false; return false;
} }
MsgId HistoryMessage::repliesInboxReadTill() const {
if (const auto views = Get<HistoryMessageViews>()) {
return views->repliesInboxReadTillId;
}
return 0;
}
void HistoryMessage::setRepliesInboxReadTill(MsgId readTillId) {
if (const auto views = Get<HistoryMessageViews>()) {
const auto newReadTillId = std::max(readTillId, 1);
if (newReadTillId > views->repliesInboxReadTillId) {
const auto wasUnread = repliesAreComments() && areRepliesUnread();
views->repliesInboxReadTillId = newReadTillId;
if (wasUnread && !areRepliesUnread()) {
history()->owner().requestItemRepaint(this);
}
}
}
}
MsgId HistoryMessage::computeRepliesInboxReadTillFull() const {
const auto views = Get<HistoryMessageViews>();
if (!views) {
return 0;
}
const auto local = views->repliesInboxReadTillId;
const auto group = views->commentsMegagroupId
? history()->owner().historyLoaded(
peerFromChannel(views->commentsMegagroupId))
: history().get();
return group ? std::max(local, group->inboxReadTillId()) : local;
}
MsgId HistoryMessage::repliesOutboxReadTill() const {
if (const auto views = Get<HistoryMessageViews>()) {
return views->repliesOutboxReadTillId;
}
return 0;
}
void HistoryMessage::setRepliesOutboxReadTill(MsgId readTillId) {
if (const auto views = Get<HistoryMessageViews>()) {
const auto newReadTillId = std::max(readTillId, 1);
if (newReadTillId > views->repliesOutboxReadTillId) {
views->repliesOutboxReadTillId = newReadTillId;
if (!repliesAreComments()) {
history()->session().changes().historyUpdated(
history(),
Data::HistoryUpdate::Flag::OutboxRead);
}
}
}
}
MsgId HistoryMessage::computeRepliesOutboxReadTillFull() const {
const auto views = Get<HistoryMessageViews>();
if (!views) {
return 0;
}
const auto local = views->repliesOutboxReadTillId;
const auto group = views->commentsMegagroupId
? history()->owner().historyLoaded(
peerFromChannel(views->commentsMegagroupId))
: history().get();
return group ? std::max(local, group->outboxReadTillId()) : local;
}
void HistoryMessage::setRepliesMaxId(MsgId maxId) {
if (const auto views = Get<HistoryMessageViews>()) {
if (views->repliesMaxId != maxId) {
const auto comments = repliesAreComments();
const auto wasUnread = comments && areRepliesUnread();
views->repliesMaxId = maxId;
if (comments && wasUnread != areRepliesUnread()) {
history()->owner().requestItemRepaint(this);
}
}
}
}
void HistoryMessage::setRepliesPossibleMaxId(MsgId possibleMaxId) {
if (const auto views = Get<HistoryMessageViews>()) {
if (views->repliesMaxId < possibleMaxId) {
const auto comments = repliesAreComments();
const auto wasUnread = comments && areRepliesUnread();
views->repliesMaxId = possibleMaxId;
if (comments && !wasUnread && areRepliesUnread()) {
history()->owner().requestItemRepaint(this);
}
}
}
}
bool HistoryMessage::areRepliesUnread() const {
const auto views = Get<HistoryMessageViews>();
if (!views) {
return false;
}
const auto local = views->repliesInboxReadTillId;
if (views->repliesInboxReadTillId < 2 || views->repliesMaxId <= local) {
return false;
}
const auto group = views->commentsMegagroupId
? history()->owner().historyLoaded(
peerFromChannel(views->commentsMegagroupId))
: history().get();
return !group || (views->repliesMaxId > group->inboxReadTillId());
}
FullMsgId HistoryMessage::commentsItemId() const { FullMsgId HistoryMessage::commentsItemId() const {
if (const auto views = Get<HistoryMessageViews>()) { if (const auto views = Get<HistoryMessageViews>()) {
return FullMsgId(views->commentsChannelId, views->commentsRootId); return FullMsgId(views->commentsMegagroupId, views->commentsRootId);
} }
return FullMsgId(); return FullMsgId();
} }
void HistoryMessage::setCommentsItemId(FullMsgId id) { void HistoryMessage::setCommentsItemId(FullMsgId id) {
if (const auto views = Get<HistoryMessageViews>()) { if (id.channel == _history->channelId()) {
if (views->commentsChannelId == id.channel) { if (id.msg != this->id) {
views->commentsRootId = id.msg; if (const auto reply = Get<HistoryMessageReply>()) {
} reply->replyToMsgTop = id.msg;
}
}
MsgId HistoryMessage::commentsReadTill() const {
if (const auto views = Get<HistoryMessageViews>()) {
return views->commentsReadTillId;
}
return 0;
}
void HistoryMessage::setCommentsReadTill(MsgId readTillId) {
if (const auto views = Get<HistoryMessageViews>()) {
const auto newReadTillId = std::max(readTillId, 1);
if (newReadTillId > views->commentsReadTillId) {
const auto wasUnread = areCommentsUnread();
views->commentsReadTillId = newReadTillId;
if (wasUnread && !areCommentsUnread()) {
history()->owner().requestItemRepaint(this);
} }
} }
} return;
} } else if (const auto views = Get<HistoryMessageViews>()) {
if (views->commentsMegagroupId != id.channel) {
void HistoryMessage::setCommentsMaxId(MsgId maxId) { views->commentsMegagroupId = id.channel;
if (const auto views = Get<HistoryMessageViews>()) { history()->owner().requestItemResize(this);
if (views->commentsMaxId != maxId) {
const auto wasUnread = areCommentsUnread();
views->commentsMaxId = maxId;
if (wasUnread != areCommentsUnread()) {
history()->owner().requestItemRepaint(this);
}
} }
views->commentsRootId = id.msg;
} }
} }
void HistoryMessage::setCommentsPossibleMaxId(MsgId possibleMaxId) {
if (const auto views = Get<HistoryMessageViews>()) {
if (views->commentsMaxId < possibleMaxId) {
const auto wasUnread = areCommentsUnread();
views->commentsMaxId = possibleMaxId;
if (!wasUnread && areCommentsUnread()) {
history()->owner().requestItemRepaint(this);
}
}
}
}
MsgId HistoryMessage::computeCommentsReadTillFull() const {
const auto local = commentsReadTill();
const auto views = Get<HistoryMessageViews>();
if (!views || !views->commentsChannelId) {
return local;
}
const auto group = history()->owner().historyLoaded(
peerFromChannel(views->commentsChannelId));
if (!group) {
return local;
}
return std::max(local, group->inboxReadTillId());
}
bool HistoryMessage::areCommentsUnread() const {
if (const auto views = Get<HistoryMessageViews>()) {
if (views->commentsReadTillId < 2
|| views->commentsMaxId <= views->commentsReadTillId) {
return false;
} else if (!views->commentsChannelId) {
return true;
}
const auto group = history()->owner().historyLoaded(
peerFromChannel(views->commentsChannelId));
return !group || (views->commentsMaxId > group->inboxReadTillId());
}
return false;
}
bool HistoryMessage::updateDependencyItem() { bool HistoryMessage::updateDependencyItem() {
if (const auto reply = Get<HistoryMessageReply>()) { if (const auto reply = Get<HistoryMessageReply>()) {
const auto documentId = reply->replyToDocumentId; const auto documentId = reply->replyToDocumentId;
@ -1555,29 +1600,31 @@ void HistoryMessage::setReplies(const MTPMessageReplies &data) {
}(); }();
const auto count = data.vreplies().v; const auto count = data.vreplies().v;
const auto channelId = data.vchannel_id().value_or_empty(); const auto channelId = data.vchannel_id().value_or_empty();
const auto countChanged = (views->replies.count != count); const auto readTillId = data.vread_max_id()
const auto channelChanged = (views->commentsChannelId != channelId); ? std::max(
{ views->repliesInboxReadTillId, data.vread_max_id()->v, 1 })
: views->repliesInboxReadTillId;
const auto maxId = data.vmax_id().value_or(views->repliesMaxId);
const auto countsChanged = (views->replies.count != count)
|| (views->repliesInboxReadTillId != readTillId)
|| (views->repliesMaxId != maxId);
const auto megagroupChanged = (views->commentsMegagroupId != channelId);
const auto recentChanged = (views->recentRepliers != repliers); const auto recentChanged = (views->recentRepliers != repliers);
if (!countChanged && !channelChanged && !recentChanged) { if (!countsChanged && !megagroupChanged && !recentChanged) {
return; return;
} }
views->replies.count = count; views->replies.count = count;
if (recentChanged) { if (recentChanged) {
views->recentRepliers = repliers; views->recentRepliers = repliers;
} }
views->commentsChannelId = channelId; views->commentsMegagroupId = channelId;
const auto wasUnread = areCommentsUnread(); const auto wasUnread = channelId && areRepliesUnread();
if (const auto till = data.vread_max_id()) { views->repliesInboxReadTillId = readTillId;
views->commentsReadTillId = std::max( views->repliesMaxId = maxId;
{ views->commentsReadTillId, till->v, 1 }); if (channelId && wasUnread != areRepliesUnread()) {
}
if (const auto maxId = data.vmax_id()) {
views->commentsMaxId = maxId->v;
}
if (wasUnread != areCommentsUnread()) {
history()->owner().requestItemRepaint(this); history()->owner().requestItemRepaint(this);
} }
refreshRepliesText(views, channelChanged); refreshRepliesText(views, megagroupChanged);
}); });
} }
@ -1585,7 +1632,7 @@ void HistoryMessage::refreshRepliesText(
not_null<HistoryMessageViews*> views, not_null<HistoryMessageViews*> views,
bool forceResize) { bool forceResize) {
const auto was = views->replies.textWidth; const auto was = views->replies.textWidth;
if (views->commentsChannelId) { if (views->commentsMegagroupId) {
views->replies.text = (views->replies.count > 0) views->replies.text = (views->replies.count > 0)
? tr::lng_comments_open_count( ? tr::lng_comments_open_count(
tr::now, tr::now,
@ -1621,7 +1668,7 @@ void HistoryMessage::changeRepliesCount(int delta, PeerId replier) {
return; return;
} }
views->replies.count = std::max(views->replies.count + delta, 0); views->replies.count = std::max(views->replies.count + delta, 0);
if (replier && views->commentsChannelId) { if (replier && views->commentsMegagroupId) {
if (delta < 0) { if (delta < 0) {
views->recentRepliers.erase( views->recentRepliers.erase(
ranges::remove(views->recentRepliers, replier), ranges::remove(views->recentRepliers, replier),
@ -1691,7 +1738,7 @@ void HistoryMessage::changeReplyToTopCounter(
item->changeRepliesCount(delta, PeerId()); item->changeRepliesCount(delta, PeerId());
}; };
if (const auto views = top->Get<HistoryMessageViews>()) { if (const auto views = top->Get<HistoryMessageViews>()) {
if (views->commentsChannelId) { if (views->commentsMegagroupId) {
// This is a post in channel, we don't track its replies. // This is a post in channel, we don't track its replies.
return; return;
} }

View file

@ -160,14 +160,19 @@ public:
[[nodiscard]] int repliesCount() const override; [[nodiscard]] int repliesCount() const override;
[[nodiscard]] bool repliesAreComments() const override; [[nodiscard]] bool repliesAreComments() const override;
[[nodiscard]] bool externalReply() const override; [[nodiscard]] bool externalReply() const override;
[[nodiscard]] MsgId repliesInboxReadTill() const override;
void setRepliesInboxReadTill(MsgId readTillId) override;
[[nodiscard]] MsgId computeRepliesInboxReadTillFull() const override;
[[nodiscard]] MsgId repliesOutboxReadTill() const override;
void setRepliesOutboxReadTill(MsgId readTillId) override;
[[nodiscard]] MsgId computeRepliesOutboxReadTillFull() const override;
void setRepliesMaxId(MsgId maxId) override;
void setRepliesPossibleMaxId(MsgId possibleMaxId) override;
[[nodiscard]] bool areRepliesUnread() const override;
[[nodiscard]] FullMsgId commentsItemId() const override; [[nodiscard]] FullMsgId commentsItemId() const override;
void setCommentsItemId(FullMsgId id) override; void setCommentsItemId(FullMsgId id) override;
[[nodiscard]] MsgId commentsReadTill() const override;
void setCommentsReadTill(MsgId readTillId) override;
void setCommentsMaxId(MsgId maxId) override;
void setCommentsPossibleMaxId(MsgId possibleMaxId) override;
[[nodiscard]] MsgId computeCommentsReadTillFull() const override;
[[nodiscard]] bool areCommentsUnread() const override;
bool updateDependencyItem() override; bool updateDependencyItem() override;
[[nodiscard]] MsgId dependencyMsgId() const override { [[nodiscard]] MsgId dependencyMsgId() const override {
return replyToId(); return replyToId();

View file

@ -777,7 +777,7 @@ void Message::paintCommentsButton(
views ? views->replies.text : tr::lng_replies_view_original(tr::now), views ? views->replies.text : tr::lng_replies_view_original(tr::now),
views ? views->replies.textWidth : -1); views ? views->replies.textWidth : -1);
if (views && data()->areCommentsUnread()) { if (views && data()->areRepliesUnread()) {
p.setPen(Qt::NoPen); p.setPen(Qt::NoPen);
p.setBrush(outbg ? (selected ? st::msgFileOutBgSelected : st::msgFileOutBg) : (selected ? st::msgFileInBgSelected : st::msgFileInBg)); p.setBrush(outbg ? (selected ? st::msgFileOutBgSelected : st::msgFileOutBg) : (selected ? st::msgFileInBgSelected : st::msgFileInBg));
@ -1707,7 +1707,7 @@ void Message::drawInfo(
const auto iconTop = infoBottom + st::historyViewsTop; const auto iconTop = infoBottom + st::historyViewsTop;
const auto textTop = infoBottom - st::msgDateFont->descent; const auto textTop = infoBottom - st::msgDateFont->descent;
if (views->replies.count > 0 if (views->replies.count > 0
&& !views->commentsChannelId && !views->commentsMegagroupId
&& context() != Context::Replies) { && context() != Context::Replies) {
auto icon = [&] { auto icon = [&] {
if (item->id > 0) { if (item->id > 0) {
@ -1826,7 +1826,7 @@ int Message::infoWidth() const {
+ st::historyViewsWidth; + st::historyViewsWidth;
} }
if (views->replies.count > 0 if (views->replies.count > 0
&& !views->commentsChannelId && !views->commentsMegagroupId
&& context() != Context::Replies) { && context() != Context::Replies) {
result += st::historyViewsSpace result += st::historyViewsSpace
+ views->replies.textWidth + views->replies.textWidth
@ -1877,7 +1877,7 @@ int Message::timeLeft() const {
result += st::historyViewsSpace + views->views.textWidth + st::historyViewsWidth; result += st::historyViewsSpace + views->views.textWidth + st::historyViewsWidth;
} }
if (views->replies.count > 0 if (views->replies.count > 0
&& !views->commentsChannelId && !views->commentsMegagroupId
&& context() != Context::Replies) { && context() != Context::Replies) {
result += st::historyViewsSpace + views->replies.textWidth + st::historyViewsWidth; result += st::historyViewsSpace + views->replies.textWidth + st::historyViewsWidth;
} }

View file

@ -92,13 +92,11 @@ RepliesMemento::RepliesMemento(
TimeId(0), TimeId(0),
FullMsgId(commentsItem->history()->channelId(), commentId) FullMsgId(commentsItem->history()->channelId(), commentId)
}); });
} else if (const auto original = commentsItem->lookupDiscussionPostOriginal()) { } else if (commentsItem->computeRepliesInboxReadTillFull() == MsgId(1)) {
if (original->computeCommentsReadTillFull() == MsgId(1)) { _list.setAroundPosition(Data::MinMessagePosition);
_list.setAroundPosition(Data::MinMessagePosition); _list.setScrollTopState(ListMemento::ScrollTopState{
_list.setScrollTopState(ListMemento::ScrollTopState{ Data::MinMessagePosition
Data::MinMessagePosition });
});
}
} }
} }
@ -128,7 +126,6 @@ RepliesWidget::RepliesWidget(
, _history(history) , _history(history)
, _rootId(rootId) , _rootId(rootId)
, _root(lookupRoot()) , _root(lookupRoot())
, _commentsRoot(lookupCommentsRoot())
, _areComments(computeAreComments()) , _areComments(computeAreComments())
, _topBar(this, controller) , _topBar(this, controller)
, _topBarShadow(this) , _topBarShadow(this)
@ -209,9 +206,6 @@ RepliesWidget::RepliesWidget(
_root = nullptr; _root = nullptr;
updatePinnedVisibility(); updatePinnedVisibility();
} }
if (update.item == _commentsRoot) {
_commentsRoot = nullptr;
}
while (update.item == _replyReturn) { while (update.item == _replyReturn) {
calculateNextReplyReturn(); calculateNextReplyReturn();
} }
@ -228,7 +222,7 @@ RepliesWidget::~RepliesWidget() {
} }
void RepliesWidget::sendReadTillRequest() { void RepliesWidget::sendReadTillRequest() {
if (!_commentsRoot) { if (!_root) {
_readRequestPending = true; _readRequestPending = true;
return; return;
} }
@ -239,16 +233,15 @@ void RepliesWidget::sendReadTillRequest() {
const auto api = &_history->session().api(); const auto api = &_history->session().api();
api->request(base::take(_readRequestId)).cancel(); api->request(base::take(_readRequestId)).cancel();
_readRequestId = api->request(MTPmessages_ReadDiscussion( _readRequestId = api->request(MTPmessages_ReadDiscussion(
_commentsRoot->history()->peer->input, _root->history()->peer->input,
MTP_int(_commentsRoot->id), MTP_int(_root->id),
MTP_int(_commentsRoot->computeCommentsReadTillFull()) MTP_int(_root->computeRepliesInboxReadTillFull())
)).done([=](const MTPBool &) { )).done([=](const MTPBool &) {
}).send(); }).send();
} }
void RepliesWidget::setupRoot() { void RepliesWidget::setupRoot() {
if (_root) { if (_root) {
setupCommentsRoot();
refreshRootView(); refreshRootView();
} else { } else {
const auto channel = _history->peer->asChannel(); const auto channel = _history->peer->asChannel();
@ -256,7 +249,9 @@ void RepliesWidget::setupRoot() {
_root = lookupRoot(); _root = lookupRoot();
if (_root) { if (_root) {
_areComments = computeAreComments(); _areComments = computeAreComments();
setupCommentsRoot(); if (_readRequestPending) {
sendReadTillRequest();
}
} }
updatePinnedVisibility(); updatePinnedVisibility();
refreshRootView(); refreshRootView();
@ -348,34 +343,6 @@ void RepliesWidget::setupRootView() {
}, _rootView->lifetime()); }, _rootView->lifetime());
} }
void RepliesWidget::setupCommentsRoot() {
Expects(_root != nullptr);
const auto postChannel = _root->discussionPostOriginalSender();
if (!postChannel) {
return;
} else if (_commentsRoot) {
if (_readRequestTimer.isActive() || _readRequestPending) {
sendReadTillRequest();
}
} else {
const auto forwarded = _root->Get<HistoryMessageForwarded>();
const auto messageId = forwarded->savedFromMsgId;
const auto done = crl::guard(this, [=](ChannelData*, MsgId) {
_commentsRoot = lookupCommentsRoot();
if (_commentsRoot) {
if (_readRequestTimer.isActive() || _readRequestPending) {
sendReadTillRequest();
}
}
});
_history->session().api().requestMessageData(
postChannel,
messageId,
done);
}
}
void RepliesWidget::refreshRootView() { void RepliesWidget::refreshRootView() {
const auto sender = (_root && _root->discussionPostOriginalSender()) const auto sender = (_root && _root->discussionPostOriginalSender())
? _root->discussionPostOriginalSender() ? _root->discussionPostOriginalSender()
@ -408,12 +375,6 @@ HistoryItem *RepliesWidget::lookupRoot() const {
return _history->owner().message(_history->channelId(), _rootId); return _history->owner().message(_history->channelId(), _rootId);
} }
HistoryItem *RepliesWidget::lookupCommentsRoot() const {
return _root
? _root->lookupDiscussionPostOriginal()
: nullptr;
}
bool RepliesWidget::computeAreComments() const { bool RepliesWidget::computeAreComments() const {
return _root && _root->isDiscussionPost(); return _root && _root->isDiscussionPost();
} }
@ -1550,14 +1511,17 @@ void RepliesWidget::listSelectionChanged(SelectedItems &&items) {
} }
void RepliesWidget::readTill(not_null<HistoryItem*> item) { void RepliesWidget::readTill(not_null<HistoryItem*> item) {
if (!_commentsRoot) { if (!_root) {
return; return;
} }
const auto was = _commentsRoot->computeCommentsReadTillFull(); const auto was = _root->computeRepliesInboxReadTillFull();
const auto now = item->id; const auto now = item->id;
const auto fast = item->out(); const auto fast = item->out();
if (was < now) { if (was < now) {
_commentsRoot->setCommentsReadTill(now); _root->setRepliesInboxReadTill(now);
if (const auto post = _root->lookupDiscussionPostOriginal()) {
post->setRepliesInboxReadTill(now);
}
if (!_readRequestTimer.isActive()) { if (!_readRequestTimer.isActive()) {
_readRequestTimer.callOnce(fast ? 0 : kReadRequestTimeout); _readRequestTimer.callOnce(fast ? 0 : kReadRequestTimeout);
} else if (fast && _readRequestTimer.remainingTime() > 0) { } else if (fast && _readRequestTimer.remainingTime() > 0) {
@ -1578,10 +1542,10 @@ void RepliesWidget::listVisibleItemsChanged(HistoryItemsList &&items) {
MessagesBarData RepliesWidget::listMessagesBar( MessagesBarData RepliesWidget::listMessagesBar(
const std::vector<not_null<Element*>> &elements) { const std::vector<not_null<Element*>> &elements) {
if (!_commentsRoot || elements.empty()) { if (!_root || elements.empty()) {
return {}; return {};
} }
const auto till = _commentsRoot->computeCommentsReadTillFull(); const auto till = _root->computeRepliesInboxReadTillFull();
if (till < 2) { if (till < 2) {
return {}; return {};
} }
@ -1606,7 +1570,6 @@ MessagesBarData RepliesWidget::listMessagesBar(
} }
void RepliesWidget::listContentRefreshed() { void RepliesWidget::listContentRefreshed() {
} }
ClickHandlerPtr RepliesWidget::listDateLink(not_null<Element*> view) { ClickHandlerPtr RepliesWidget::listDateLink(not_null<Element*> view) {

View file

@ -155,7 +155,6 @@ private:
void setupRoot(); void setupRoot();
void setupRootView(); void setupRootView();
void setupCommentsRoot();
void refreshRootView(); void refreshRootView();
void setupDragArea(); void setupDragArea();
void sendReadTillRequest(); void sendReadTillRequest();
@ -184,7 +183,6 @@ private:
[[nodiscard]] SendMenu::Type sendMenuType() const; [[nodiscard]] SendMenu::Type sendMenuType() const;
[[nodiscard]] MsgId replyToId() const; [[nodiscard]] MsgId replyToId() const;
[[nodiscard]] HistoryItem *lookupRoot() const; [[nodiscard]] HistoryItem *lookupRoot() const;
[[nodiscard]] HistoryItem *lookupCommentsRoot() const;
[[nodiscard]] bool computeAreComments() const; [[nodiscard]] bool computeAreComments() const;
void pushReplyReturn(not_null<HistoryItem*> item); void pushReplyReturn(not_null<HistoryItem*> item);
@ -235,7 +233,6 @@ private:
const not_null<History*> _history; const not_null<History*> _history;
const MsgId _rootId = 0; const MsgId _rootId = 0;
HistoryItem *_root = nullptr; HistoryItem *_root = nullptr;
HistoryItem *_commentsRoot = nullptr;
std::shared_ptr<Data::RepliesList> _replies; std::shared_ptr<Data::RepliesList> _replies;
rpl::variable<bool> _areComments = false; rpl::variable<bool> _areComments = false;
QPointer<ListWidget> _inner; QPointer<ListWidget> _inner;

View file

@ -145,14 +145,26 @@ void SessionNavigation::showRepliesForMessage(
item = group->items.front(); item = group->items.front();
} }
if (item) { if (item) {
if (const auto maxId = data.vmax_id()) {
item->setRepliesMaxId(maxId->v);
}
if (const auto readTill = data.vread_inbox_max_id()) {
item->setRepliesInboxReadTill(readTill->v);
}
if (const auto readTill = data.vread_outbox_max_id()) {
item->setRepliesOutboxReadTill(readTill->v);
}
const auto post = _session->data().message(channelId, rootId); const auto post = _session->data().message(channelId, rootId);
if (post) { if (post) {
post->setCommentsItemId(item->fullId()); post->setCommentsItemId(item->fullId());
if (const auto maxId = data.vmax_id()) { if (const auto maxId = data.vmax_id()) {
post->setCommentsMaxId(maxId->v); post->setRepliesMaxId(maxId->v);
} }
if (const auto readTill = data.vread_inbox_max_id()) { if (const auto readTill = data.vread_inbox_max_id()) {
post->setCommentsReadTill(readTill->v); post->setRepliesInboxReadTill(readTill->v);
}
if (const auto readTill = data.vread_outbox_max_id()) {
post->setRepliesOutboxReadTill(readTill->v);
} }
} }
showSection( showSection(