mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-08-22 02:07:24 +00:00
Fix marking read in new forum layout.
This commit is contained in:
parent
60f6ea3252
commit
87cdc22990
@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_forum_icons.h"
|
||||
#include "data/data_forum_topic.h"
|
||||
#include "data/data_replies_list.h"
|
||||
#include "data/notify/data_notify_settings.h"
|
||||
#include "history/history.h"
|
||||
#include "history/history_item.h"
|
||||
@ -276,6 +277,33 @@ Thread *Forum::activeSubsectionThread() const {
|
||||
return _activeSubsectionTopic;
|
||||
}
|
||||
|
||||
void Forum::markUnreadCountsUnknown(MsgId readTillId) {
|
||||
if (!channel()->useSubsectionTabs()) {
|
||||
return;
|
||||
}
|
||||
for (const auto &[rootId, topic] : _topics) {
|
||||
const auto replies = topic->replies();
|
||||
if (replies->unreadCountCurrent() > 0) {
|
||||
replies->setInboxReadTill(readTillId, std::nullopt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Forum::updateUnreadCounts(
|
||||
MsgId readTillId,
|
||||
const base::flat_map<not_null<ForumTopic*>, int> &counts) {
|
||||
if (!channel()->useSubsectionTabs()) {
|
||||
return;
|
||||
}
|
||||
for (const auto &[rootId, topic] : _topics) {
|
||||
const auto raw = topic.get();
|
||||
const auto replies = raw->replies();
|
||||
const auto i = counts.find(raw);
|
||||
const auto count = (i != end(counts)) ? i->second : 0;
|
||||
replies->setInboxReadTill(readTillId, count);
|
||||
}
|
||||
}
|
||||
|
||||
void Forum::listMessageChanged(HistoryItem *from, HistoryItem *to) {
|
||||
if (from || to) {
|
||||
reorderLastTopics();
|
||||
|
@ -99,6 +99,11 @@ public:
|
||||
void saveActiveSubsectionThread(not_null<Thread*> thread);
|
||||
[[nodiscard]] Thread *activeSubsectionThread() const;
|
||||
|
||||
void markUnreadCountsUnknown(MsgId readTillId);
|
||||
void updateUnreadCounts(
|
||||
MsgId readTillId,
|
||||
const base::flat_map<not_null<ForumTopic*>, int> &counts);
|
||||
|
||||
[[nodiscard]] rpl::lifetime &lifetime() {
|
||||
return _lifetime;
|
||||
}
|
||||
|
@ -713,7 +713,7 @@ void Histories::sendReadRequest(not_null<History*> history, State &state) {
|
||||
} else {
|
||||
Assert(!state->sentReadTill || state->sentReadTill > tillId);
|
||||
}
|
||||
history->validateMonoforumUnread(tillId);
|
||||
history->validateMonoAndForumUnread(tillId);
|
||||
sendReadRequests();
|
||||
finish();
|
||||
};
|
||||
|
@ -33,6 +33,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "data/data_channel_admins.h"
|
||||
#include "data/data_changes.h"
|
||||
#include "data/data_chat_filters.h"
|
||||
#include "data/data_replies_list.h"
|
||||
#include "data/data_send_action.h"
|
||||
#include "data/data_star_gift.h"
|
||||
#include "data/data_emoji_statuses.h"
|
||||
@ -3156,6 +3157,58 @@ void History::applyDialogTopMessage(MsgId topMessageId) {
|
||||
}
|
||||
}
|
||||
|
||||
void History::tryMarkForumIntervalRead(
|
||||
MsgId wasInboxReadBefore,
|
||||
MsgId nowInboxReadBefore) {
|
||||
if (!isForum()
|
||||
|| !peer->asChannel()->useSubsectionTabs()
|
||||
|| (nowInboxReadBefore <= wasInboxReadBefore)) {
|
||||
return;
|
||||
} else if (loadedAtBottom() && nowInboxReadBefore >= minMsgId()) {
|
||||
// Count for each sublist how many messages are still not read.
|
||||
auto counts = base::flat_map<not_null<Data::ForumTopic*>, int>();
|
||||
for (const auto &block : blocks) {
|
||||
for (const auto &message : block->messages) {
|
||||
const auto item = message->data();
|
||||
if (!item->isRegular() || item->id < nowInboxReadBefore) {
|
||||
continue;
|
||||
}
|
||||
if (const auto topic = item->topic()) {
|
||||
++counts[topic];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (const auto forum = peer->forum()) {
|
||||
forum->updateUnreadCounts(nowInboxReadBefore - 1, counts);
|
||||
}
|
||||
} else if (minMsgId() <= wasInboxReadBefore
|
||||
&& maxMsgId() >= nowInboxReadBefore) {
|
||||
// Count for each sublist how many messages were read.
|
||||
for (const auto &block : blocks) {
|
||||
for (const auto &message : block->messages) {
|
||||
const auto item = message->data();
|
||||
if (!item->isRegular() || item->id < wasInboxReadBefore) {
|
||||
continue;
|
||||
} else if (item->id >= nowInboxReadBefore) {
|
||||
break;
|
||||
}
|
||||
if (const auto topic = item->topic()) {
|
||||
const auto replies = topic->replies();
|
||||
const auto unread = replies->unreadCountCurrent();
|
||||
if (unread > 0) {
|
||||
replies->setInboxReadTill(item->id, unread - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// We can't invalidate sublist unread counts here, because no read
|
||||
// request was yet sent to the server (so it can't return correct
|
||||
// values yet), we need to do that after we send read request.
|
||||
_flags |= Flag::MonoAndForumUnreadInvalidatePending;
|
||||
}
|
||||
}
|
||||
|
||||
void History::tryMarkMonoforumIntervalRead(
|
||||
MsgId wasInboxReadBefore,
|
||||
MsgId nowInboxReadBefore) {
|
||||
@ -3201,24 +3254,29 @@ void History::tryMarkMonoforumIntervalRead(
|
||||
// We can't invalidate sublist unread counts here, because no read
|
||||
// request was yet sent to the server (so it can't return correct
|
||||
// values yet), we need to do that after we send read request.
|
||||
_flags |= Flag::MonoforumUnreadInvalidatePending;
|
||||
_flags |= Flag::MonoAndForumUnreadInvalidatePending;
|
||||
}
|
||||
}
|
||||
|
||||
void History::validateMonoforumUnread(MsgId readTillId) {
|
||||
if (!(_flags & Flag::MonoforumUnreadInvalidatePending)) {
|
||||
void History::validateMonoAndForumUnread(MsgId readTillId) {
|
||||
if (!(_flags & Flag::MonoAndForumUnreadInvalidatePending)) {
|
||||
return;
|
||||
}
|
||||
_flags &= ~Flag::MonoforumUnreadInvalidatePending;
|
||||
if (!amMonoforumAdmin()) {
|
||||
return;
|
||||
} else if (const auto monoforum = peer->monoforum()) {
|
||||
monoforum->markUnreadCountsUnknown(readTillId);
|
||||
_flags &= ~Flag::MonoAndForumUnreadInvalidatePending;
|
||||
if (isForum()) {
|
||||
if (const auto forum = peer->forum()) {
|
||||
forum->markUnreadCountsUnknown(readTillId);
|
||||
}
|
||||
} else if (amMonoforumAdmin()) {
|
||||
if (const auto monoforum = peer->monoforum()) {
|
||||
monoforum->markUnreadCountsUnknown(readTillId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void History::setInboxReadTill(MsgId upTo) {
|
||||
if (_inboxReadBefore) {
|
||||
tryMarkForumIntervalRead(*_inboxReadBefore, upTo + 1);
|
||||
tryMarkMonoforumIntervalRead(*_inboxReadBefore, upTo + 1);
|
||||
accumulate_max(*_inboxReadBefore, upTo + 1);
|
||||
} else {
|
||||
|
@ -434,7 +434,10 @@ public:
|
||||
void tryMarkMonoforumIntervalRead(
|
||||
MsgId wasInboxReadBefore,
|
||||
MsgId nowInboxReadBefore);
|
||||
void validateMonoforumUnread(MsgId readTillId);
|
||||
void tryMarkForumIntervalRead(
|
||||
MsgId wasInboxReadBefore,
|
||||
MsgId nowInboxReadBefore);
|
||||
void validateMonoAndForumUnread(MsgId readTillId);
|
||||
|
||||
[[nodiscard]] bool isTopPromoted() const;
|
||||
|
||||
@ -480,7 +483,7 @@ private:
|
||||
FakeUnreadWhileOpened = (1 << 5),
|
||||
HasPinnedMessages = (1 << 6),
|
||||
ResolveChatListMessage = (1 << 7),
|
||||
MonoforumUnreadInvalidatePending = (1 << 8),
|
||||
MonoAndForumUnreadInvalidatePending = (1 << 8),
|
||||
};
|
||||
using Flags = base::flags<Flag>;
|
||||
friend inline constexpr auto is_flag_type(Flag) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user