mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-08-22 10:17:10 +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_session.h"
|
||||||
#include "data/data_forum_icons.h"
|
#include "data/data_forum_icons.h"
|
||||||
#include "data/data_forum_topic.h"
|
#include "data/data_forum_topic.h"
|
||||||
|
#include "data/data_replies_list.h"
|
||||||
#include "data/notify/data_notify_settings.h"
|
#include "data/notify/data_notify_settings.h"
|
||||||
#include "history/history.h"
|
#include "history/history.h"
|
||||||
#include "history/history_item.h"
|
#include "history/history_item.h"
|
||||||
@ -276,6 +277,33 @@ Thread *Forum::activeSubsectionThread() const {
|
|||||||
return _activeSubsectionTopic;
|
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) {
|
void Forum::listMessageChanged(HistoryItem *from, HistoryItem *to) {
|
||||||
if (from || to) {
|
if (from || to) {
|
||||||
reorderLastTopics();
|
reorderLastTopics();
|
||||||
|
@ -99,6 +99,11 @@ public:
|
|||||||
void saveActiveSubsectionThread(not_null<Thread*> thread);
|
void saveActiveSubsectionThread(not_null<Thread*> thread);
|
||||||
[[nodiscard]] Thread *activeSubsectionThread() const;
|
[[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() {
|
[[nodiscard]] rpl::lifetime &lifetime() {
|
||||||
return _lifetime;
|
return _lifetime;
|
||||||
}
|
}
|
||||||
|
@ -713,7 +713,7 @@ void Histories::sendReadRequest(not_null<History*> history, State &state) {
|
|||||||
} else {
|
} else {
|
||||||
Assert(!state->sentReadTill || state->sentReadTill > tillId);
|
Assert(!state->sentReadTill || state->sentReadTill > tillId);
|
||||||
}
|
}
|
||||||
history->validateMonoforumUnread(tillId);
|
history->validateMonoAndForumUnread(tillId);
|
||||||
sendReadRequests();
|
sendReadRequests();
|
||||||
finish();
|
finish();
|
||||||
};
|
};
|
||||||
|
@ -33,6 +33,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||||||
#include "data/data_channel_admins.h"
|
#include "data/data_channel_admins.h"
|
||||||
#include "data/data_changes.h"
|
#include "data/data_changes.h"
|
||||||
#include "data/data_chat_filters.h"
|
#include "data/data_chat_filters.h"
|
||||||
|
#include "data/data_replies_list.h"
|
||||||
#include "data/data_send_action.h"
|
#include "data/data_send_action.h"
|
||||||
#include "data/data_star_gift.h"
|
#include "data/data_star_gift.h"
|
||||||
#include "data/data_emoji_statuses.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(
|
void History::tryMarkMonoforumIntervalRead(
|
||||||
MsgId wasInboxReadBefore,
|
MsgId wasInboxReadBefore,
|
||||||
MsgId nowInboxReadBefore) {
|
MsgId nowInboxReadBefore) {
|
||||||
@ -3201,24 +3254,29 @@ void History::tryMarkMonoforumIntervalRead(
|
|||||||
// We can't invalidate sublist unread counts here, because no read
|
// We can't invalidate sublist unread counts here, because no read
|
||||||
// request was yet sent to the server (so it can't return correct
|
// 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.
|
// values yet), we need to do that after we send read request.
|
||||||
_flags |= Flag::MonoforumUnreadInvalidatePending;
|
_flags |= Flag::MonoAndForumUnreadInvalidatePending;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void History::validateMonoforumUnread(MsgId readTillId) {
|
void History::validateMonoAndForumUnread(MsgId readTillId) {
|
||||||
if (!(_flags & Flag::MonoforumUnreadInvalidatePending)) {
|
if (!(_flags & Flag::MonoAndForumUnreadInvalidatePending)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_flags &= ~Flag::MonoforumUnreadInvalidatePending;
|
_flags &= ~Flag::MonoAndForumUnreadInvalidatePending;
|
||||||
if (!amMonoforumAdmin()) {
|
if (isForum()) {
|
||||||
return;
|
if (const auto forum = peer->forum()) {
|
||||||
} else if (const auto monoforum = peer->monoforum()) {
|
forum->markUnreadCountsUnknown(readTillId);
|
||||||
monoforum->markUnreadCountsUnknown(readTillId);
|
}
|
||||||
|
} else if (amMonoforumAdmin()) {
|
||||||
|
if (const auto monoforum = peer->monoforum()) {
|
||||||
|
monoforum->markUnreadCountsUnknown(readTillId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void History::setInboxReadTill(MsgId upTo) {
|
void History::setInboxReadTill(MsgId upTo) {
|
||||||
if (_inboxReadBefore) {
|
if (_inboxReadBefore) {
|
||||||
|
tryMarkForumIntervalRead(*_inboxReadBefore, upTo + 1);
|
||||||
tryMarkMonoforumIntervalRead(*_inboxReadBefore, upTo + 1);
|
tryMarkMonoforumIntervalRead(*_inboxReadBefore, upTo + 1);
|
||||||
accumulate_max(*_inboxReadBefore, upTo + 1);
|
accumulate_max(*_inboxReadBefore, upTo + 1);
|
||||||
} else {
|
} else {
|
||||||
|
@ -434,7 +434,10 @@ public:
|
|||||||
void tryMarkMonoforumIntervalRead(
|
void tryMarkMonoforumIntervalRead(
|
||||||
MsgId wasInboxReadBefore,
|
MsgId wasInboxReadBefore,
|
||||||
MsgId nowInboxReadBefore);
|
MsgId nowInboxReadBefore);
|
||||||
void validateMonoforumUnread(MsgId readTillId);
|
void tryMarkForumIntervalRead(
|
||||||
|
MsgId wasInboxReadBefore,
|
||||||
|
MsgId nowInboxReadBefore);
|
||||||
|
void validateMonoAndForumUnread(MsgId readTillId);
|
||||||
|
|
||||||
[[nodiscard]] bool isTopPromoted() const;
|
[[nodiscard]] bool isTopPromoted() const;
|
||||||
|
|
||||||
@ -480,7 +483,7 @@ private:
|
|||||||
FakeUnreadWhileOpened = (1 << 5),
|
FakeUnreadWhileOpened = (1 << 5),
|
||||||
HasPinnedMessages = (1 << 6),
|
HasPinnedMessages = (1 << 6),
|
||||||
ResolveChatListMessage = (1 << 7),
|
ResolveChatListMessage = (1 << 7),
|
||||||
MonoforumUnreadInvalidatePending = (1 << 8),
|
MonoAndForumUnreadInvalidatePending = (1 << 8),
|
||||||
};
|
};
|
||||||
using Flags = base::flags<Flag>;
|
using Flags = base::flags<Flag>;
|
||||||
friend inline constexpr auto is_flag_type(Flag) {
|
friend inline constexpr auto is_flag_type(Flag) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user