mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-18 23:27:09 +02:00
Show comments unread status.
This commit is contained in:
parent
040f29abe6
commit
59abe95754
9 changed files with 155 additions and 63 deletions
|
@ -169,7 +169,9 @@ bool RepliesList::buildFromData(not_null<Viewer*> viewer) {
|
|||
if (viewer->around != ShowAtUnreadMsgId) {
|
||||
return viewer->around;
|
||||
} else if (const auto item = lookupRoot()) {
|
||||
return item->repliesReadTill();
|
||||
if (const auto original = item->lookupDiscussionPostOriginal()) {
|
||||
return original->commentsReadTill();
|
||||
}
|
||||
}
|
||||
return viewer->around;
|
||||
}();
|
||||
|
@ -439,9 +441,9 @@ bool RepliesList::processMessagesIsEmpty(const MTPmessages_Messages &result) {
|
|||
return true;
|
||||
}
|
||||
|
||||
const auto id = IdFromMessage(list.front());
|
||||
const auto maxId = IdFromMessage(list.front());
|
||||
const auto wasSize = int(_list.size());
|
||||
const auto toFront = (wasSize > 0) && (id > _list.front());
|
||||
const auto toFront = (wasSize > 0) && (maxId > _list.front());
|
||||
const auto clientFlags = MTPDmessage_ClientFlags();
|
||||
const auto type = NewMessageType::Existing;
|
||||
auto refreshed = std::vector<MsgId>();
|
||||
|
@ -488,6 +490,17 @@ bool RepliesList::processMessagesIsEmpty(const MTPmessages_Messages &result) {
|
|||
_skippedBefore = checkedCount - *_skippedAfter - nowSize;
|
||||
}
|
||||
_fullCount = checkedCount;
|
||||
|
||||
if (const auto item = lookupRoot()) {
|
||||
if (const auto original = item->lookupDiscussionPostOriginal()) {
|
||||
if (_skippedAfter == 0) {
|
||||
original->setCommentsMaxId(_list.front());
|
||||
} else {
|
||||
original->setCommentsPossibleMaxId(maxId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -256,6 +256,21 @@ bool HistoryItem::isDiscussionPost() const {
|
|||
return (discussionPostOriginalSender() != nullptr);
|
||||
}
|
||||
|
||||
HistoryItem *HistoryItem::lookupDiscussionPostOriginal() const {
|
||||
if (!history()->peer->isMegagroup()) {
|
||||
return nullptr;
|
||||
}
|
||||
const auto forwarded = Get<HistoryMessageForwarded>();
|
||||
if (!forwarded
|
||||
|| !forwarded->savedFromPeer
|
||||
|| !forwarded->savedFromMsgId) {
|
||||
return nullptr;
|
||||
}
|
||||
return _history->owner().message(
|
||||
forwarded->savedFromPeer->asChannel(),
|
||||
forwarded->savedFromMsgId);
|
||||
}
|
||||
|
||||
PeerData *HistoryItem::displayFrom() const {
|
||||
if (const auto sender = discussionPostOriginalSender()) {
|
||||
return sender;
|
||||
|
|
|
@ -206,6 +206,18 @@ public:
|
|||
}
|
||||
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 bool areCommentsUnread() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
[[nodiscard]] virtual bool needCheck() const;
|
||||
|
||||
|
@ -267,11 +279,6 @@ public:
|
|||
}
|
||||
virtual void changeRepliesCount(int delta, PeerId replier) {
|
||||
}
|
||||
virtual void setRepliesReadTill(MsgId readTillId) {
|
||||
}
|
||||
[[nodiscard]] virtual MsgId repliesReadTill() const {
|
||||
return MsgId(0);
|
||||
}
|
||||
virtual void setReplyToTop(MsgId replyToTop) {
|
||||
}
|
||||
virtual void setRealId(MsgId newId);
|
||||
|
@ -356,6 +363,7 @@ public:
|
|||
|
||||
[[nodiscard]] ChannelData *discussionPostOriginalSender() const;
|
||||
[[nodiscard]] bool isDiscussionPost() const;
|
||||
[[nodiscard]] HistoryItem *lookupDiscussionPostOriginal() const;
|
||||
[[nodiscard]] PeerData *displayFrom() const;
|
||||
|
||||
[[nodiscard]] virtual std::unique_ptr<HistoryView::Element> createView(
|
||||
|
|
|
@ -46,7 +46,8 @@ struct HistoryMessageViews : public RuntimeComponent<HistoryMessageViews, Histor
|
|||
Part replies;
|
||||
ChannelId commentsChannelId = 0;
|
||||
MsgId commentsRootId = 0;
|
||||
MsgId repliesReadTillId = 0;
|
||||
MsgId commentsReadTillId = 0;
|
||||
MsgId commentsMaxId = 0;
|
||||
};
|
||||
|
||||
struct HistoryMessageSigned : public RuntimeComponent<HistoryMessageSigned, HistoryItem> {
|
||||
|
|
|
@ -814,6 +814,58 @@ void HistoryMessage::setCommentsItemId(FullMsgId id) {
|
|||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HistoryMessage::setCommentsMaxId(MsgId maxId) {
|
||||
if (const auto views = Get<HistoryMessageViews>()) {
|
||||
if (views->commentsMaxId != maxId) {
|
||||
const auto wasUnread = areCommentsUnread();
|
||||
views->commentsMaxId = maxId;
|
||||
if (wasUnread != areCommentsUnread()) {
|
||||
history()->owner().requestItemRepaint(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool HistoryMessage::areCommentsUnread() const {
|
||||
if (const auto views = Get<HistoryMessageViews>()) {
|
||||
return (views->commentsReadTillId > 1)
|
||||
&& (views->commentsMaxId > views->commentsReadTillId);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HistoryMessage::updateDependencyItem() {
|
||||
if (const auto reply = Get<HistoryMessageReply>()) {
|
||||
const auto documentId = reply->replyToDocumentId;
|
||||
|
@ -1531,6 +1583,17 @@ void HistoryMessage::setReplies(const MTPMessageReplies &data) {
|
|||
views->recentRepliers = repliers;
|
||||
}
|
||||
views->commentsChannelId = channelId;
|
||||
const auto wasUnread = areCommentsUnread();
|
||||
if (const auto till = data.vread_max_id()) {
|
||||
views->commentsReadTillId = std::max(
|
||||
{ views->commentsReadTillId, till->v, 1 });
|
||||
}
|
||||
if (const auto maxId = data.vmax_id()) {
|
||||
views->commentsMaxId = maxId->v;
|
||||
}
|
||||
if (wasUnread != areCommentsUnread()) {
|
||||
history()->owner().requestItemRepaint(this);
|
||||
}
|
||||
refreshRepliesText(views, channelChanged);
|
||||
});
|
||||
}
|
||||
|
@ -1585,22 +1648,6 @@ void HistoryMessage::changeRepliesCount(int delta, PeerId replier) {
|
|||
refreshRepliesText(views);
|
||||
}
|
||||
|
||||
void HistoryMessage::setRepliesReadTill(MsgId readTillId) {
|
||||
auto views = Get<HistoryMessageViews>();
|
||||
if (!views) {
|
||||
AddComponents(HistoryMessageViews::Bit());
|
||||
views = Get<HistoryMessageViews>();
|
||||
}
|
||||
views->repliesReadTillId = std::max(readTillId, 1);
|
||||
}
|
||||
|
||||
MsgId HistoryMessage::repliesReadTill() const {
|
||||
if (const auto views = Get<HistoryMessageViews>()) {
|
||||
return views->repliesReadTillId;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void HistoryMessage::setReplyToTop(MsgId replyToTop) {
|
||||
const auto reply = Get<HistoryMessageReply>();
|
||||
if (!reply
|
||||
|
@ -1662,15 +1709,8 @@ void HistoryMessage::changeReplyToTopCounter(
|
|||
}
|
||||
}
|
||||
changeFor(top);
|
||||
if (const auto sender = top->discussionPostOriginalSender()) {
|
||||
if (const auto forwarded = top->Get<HistoryMessageForwarded>()) {
|
||||
const auto id = FullMsgId(
|
||||
sender->bareId(),
|
||||
forwarded->savedFromMsgId);
|
||||
if (const auto original = history()->owner().message(id)) {
|
||||
changeFor(original);
|
||||
}
|
||||
}
|
||||
if (const auto original = top->lookupDiscussionPostOriginal()) {
|
||||
changeFor(original);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -136,8 +136,6 @@ public:
|
|||
void setForwardsCount(int count) override;
|
||||
void setReplies(const MTPMessageReplies &data) override;
|
||||
void changeRepliesCount(int delta, PeerId replier) override;
|
||||
void setRepliesReadTill(MsgId readTillId) override;
|
||||
MsgId repliesReadTill() const override;
|
||||
void setReplyToTop(MsgId replyToTop) override;
|
||||
void setRealId(MsgId newId) override;
|
||||
void incrementReplyToTopCounter() override;
|
||||
|
@ -173,6 +171,11 @@ public:
|
|||
[[nodiscard]] bool externalReply() const override;
|
||||
[[nodiscard]] FullMsgId commentsItemId() const 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]] bool areCommentsUnread() const override;
|
||||
bool updateDependencyItem() override;
|
||||
[[nodiscard]] MsgId dependencyMsgId() const override {
|
||||
return replyToId();
|
||||
|
|
|
@ -373,7 +373,9 @@ QSize Message::performCountOptimalSize() {
|
|||
+ st::historyCommentsSkipRight
|
||||
+ st::historyCommentsSkipText
|
||||
+ st::historyCommentsOpenOutSelected.width()
|
||||
+ st::historyCommentsSkipRight;
|
||||
+ st::historyCommentsSkipRight
|
||||
+ st::mediaUnreadSkip
|
||||
+ st::mediaUnreadSize;
|
||||
accumulate_max(maxWidth, added + views->replies.textWidth);
|
||||
} else if (item->externalReply()) {
|
||||
const auto added = st::historyCommentsIn.width()
|
||||
|
@ -718,12 +720,23 @@ void Message::paintCommentsButton(
|
|||
p.setPen(outbg ? (selected ? st::msgFileThumbLinkOutFgSelected : st::msgFileThumbLinkOutFg) : (selected ? st::msgFileThumbLinkInFgSelected : st::msgFileThumbLinkInFg));
|
||||
p.setFont(st::semiboldFont);
|
||||
|
||||
const auto textTop = top + (st::historyCommentsButtonHeight - st::semiboldFont->height) / 2;
|
||||
p.drawTextLeft(
|
||||
left,
|
||||
top + (st::historyCommentsButtonHeight - st::semiboldFont->height) / 2,
|
||||
textTop,
|
||||
width,
|
||||
views ? views->replies.text : tr::lng_replies_view_original(tr::now),
|
||||
views ? views->replies.textWidth : -1);
|
||||
|
||||
if (views && data()->areCommentsUnread()) {
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(outbg ? (selected ? st::msgFileOutBgSelected : st::msgFileOutBg) : (selected ? st::msgFileInBgSelected : st::msgFileInBg));
|
||||
|
||||
{
|
||||
PainterHighQualityEnabler hq(p);
|
||||
p.drawEllipse(style::rtlrect(left + views->replies.textWidth + st::mediaUnreadSkip, textTop + st::mediaUnreadTop, st::mediaUnreadSize, st::mediaUnreadSize, width));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Message::paintFromName(
|
||||
|
|
|
@ -84,11 +84,13 @@ bool CanSendFiles(not_null<const QMimeData*> data) {
|
|||
|
||||
RepliesMemento::RepliesMemento(not_null<HistoryItem*> commentsItem)
|
||||
: RepliesMemento(commentsItem->history(), commentsItem->id) {
|
||||
if (commentsItem->repliesReadTill() == MsgId(1)) {
|
||||
_list.setAroundPosition(Data::MinMessagePosition);
|
||||
_list.setScrollTopState(ListMemento::ScrollTopState{
|
||||
Data::MinMessagePosition
|
||||
});
|
||||
if (const auto original = commentsItem->lookupDiscussionPostOriginal()) {
|
||||
if (original->commentsReadTill() == MsgId(1)) {
|
||||
_list.setAroundPosition(Data::MinMessagePosition);
|
||||
_list.setScrollTopState(ListMemento::ScrollTopState{
|
||||
Data::MinMessagePosition
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -215,7 +217,7 @@ RepliesWidget::~RepliesWidget() {
|
|||
}
|
||||
|
||||
void RepliesWidget::sendReadTillRequest() {
|
||||
if (!_commentsRoot || !_root) {
|
||||
if (!_commentsRoot) {
|
||||
return;
|
||||
}
|
||||
if (_readRequestTimer.isActive()) {
|
||||
|
@ -226,9 +228,8 @@ void RepliesWidget::sendReadTillRequest() {
|
|||
_readRequestId = api->request(MTPmessages_ReadDiscussion(
|
||||
_commentsRoot->history()->peer->input,
|
||||
MTP_int(_commentsRoot->id),
|
||||
MTP_int(_root->repliesReadTill())
|
||||
MTP_int(_commentsRoot->commentsReadTill())
|
||||
)).done([=](const MTPBool &) {
|
||||
|
||||
}).send();
|
||||
}
|
||||
|
||||
|
@ -307,14 +308,9 @@ HistoryItem *RepliesWidget::lookupRoot() const {
|
|||
}
|
||||
|
||||
HistoryItem *RepliesWidget::lookupCommentsRoot() const {
|
||||
if (!computeAreComments()) {
|
||||
return nullptr;
|
||||
}
|
||||
const auto forwarded = _root->Get<HistoryMessageForwarded>();
|
||||
Assert(forwarded != nullptr);
|
||||
return _history->owner().message(
|
||||
forwarded->savedFromPeer->asChannel(),
|
||||
forwarded->savedFromMsgId);
|
||||
return _root
|
||||
? _root->lookupDiscussionPostOriginal()
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
bool RepliesWidget::computeAreComments() const {
|
||||
|
@ -1446,12 +1442,12 @@ void RepliesWidget::listSelectionChanged(SelectedItems &&items) {
|
|||
}
|
||||
|
||||
void RepliesWidget::readTill(MsgId tillId) {
|
||||
if (!_root) {
|
||||
if (!_commentsRoot) {
|
||||
return;
|
||||
}
|
||||
const auto now = _root->repliesReadTill();
|
||||
const auto now = _commentsRoot->commentsReadTill();
|
||||
if (now < tillId) {
|
||||
_root->setRepliesReadTill(tillId);
|
||||
_commentsRoot->setCommentsReadTill(tillId);
|
||||
if (!_readRequestTimer.isActive()) {
|
||||
_readRequestTimer.callOnce(kReadRequestTimeout);
|
||||
}
|
||||
|
@ -1470,10 +1466,10 @@ void RepliesWidget::listVisibleItemsChanged(HistoryItemsList &&items) {
|
|||
|
||||
std::optional<int> RepliesWidget::listUnreadBarView(
|
||||
const std::vector<not_null<Element*>> &elements) {
|
||||
if (!_root) {
|
||||
if (!_commentsRoot) {
|
||||
return std::nullopt;
|
||||
}
|
||||
const auto till = _root->repliesReadTill();
|
||||
const auto till = _commentsRoot->commentsReadTill();
|
||||
if (till < 2) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
@ -1481,7 +1477,7 @@ std::optional<int> RepliesWidget::listUnreadBarView(
|
|||
const auto item = elements[i]->data();
|
||||
if (item->id > till) {
|
||||
if (item->out()) {
|
||||
_root->setRepliesReadTill(item->id);
|
||||
_commentsRoot->setCommentsReadTill(item->id);
|
||||
_readRequestTimer.callOnce(kReadRequestTimeout);
|
||||
} else {
|
||||
return i;
|
||||
|
|
|
@ -147,9 +147,12 @@ void SessionNavigation::showRepliesForMessage(
|
|||
const auto post = _session->data().message(channelId, rootId);
|
||||
if (post) {
|
||||
post->setCommentsItemId(item->fullId());
|
||||
}
|
||||
if (const auto readTill = data.vread_max_id()) {
|
||||
item->setRepliesReadTill(readTill->v);
|
||||
if (const auto maxId = data.vmax_id()) {
|
||||
post->setCommentsMaxId(maxId->v);
|
||||
}
|
||||
if (const auto readTill = data.vread_max_id()) {
|
||||
post->setCommentsReadTill(readTill->v);
|
||||
}
|
||||
}
|
||||
showSection(
|
||||
HistoryView::RepliesMemento(item));
|
||||
|
|
Loading…
Add table
Reference in a new issue