mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-03-03 21:07:53 +00:00
Count unread marks in non-fully loaded folders.
This commit is contained in:
parent
4c571f5bff
commit
5f62c2100c
@ -104,7 +104,7 @@ void Folder::registerOne(not_null<History*> history) {
|
||||
++_chatListViewVersion;
|
||||
if (_chatsList.indexed()->size() == 1) {
|
||||
updateChatListSortPosition();
|
||||
if (!_cloudUnread.messagesCount.has_value()) {
|
||||
if (!_cloudUnread.known) {
|
||||
session().api().requestDialogEntry(this);
|
||||
}
|
||||
} else {
|
||||
@ -337,22 +337,24 @@ void Folder::applyDialog(const MTPDdialogFolder &data) {
|
||||
void Folder::updateCloudUnread(const MTPDdialogFolder &data) {
|
||||
const auto notifier = unreadStateChangeNotifier(!_chatsList.loaded());
|
||||
|
||||
_cloudUnread.messagesCountMuted = data.vunread_muted_messages_count.v;
|
||||
_cloudUnread.messagesCount = _cloudUnread.messagesCountMuted
|
||||
_cloudUnread.messagesMuted = data.vunread_muted_messages_count.v;
|
||||
_cloudUnread.messages = _cloudUnread.messagesMuted
|
||||
+ data.vunread_unmuted_messages_count.v;
|
||||
_cloudUnread.chatsCountMuted = data.vunread_muted_peers_count.v;
|
||||
_cloudUnread.chatsCount = _cloudUnread.chatsCountMuted
|
||||
_cloudUnread.chatsMuted = data.vunread_muted_peers_count.v;
|
||||
_cloudUnread.chats = _cloudUnread.chatsMuted
|
||||
+ data.vunread_unmuted_peers_count.v;
|
||||
_cloudUnread.known = true;
|
||||
}
|
||||
|
||||
Dialogs::UnreadState Folder::chatListUnreadState() const {
|
||||
const auto state = _chatsList.loaded()
|
||||
? _chatsList.unreadState()
|
||||
: _cloudUnread;
|
||||
auto result = Dialogs::UnreadState();
|
||||
result.messagesCount = state.messagesCount;
|
||||
result.messagesCountMuted = result.messagesCount.value_or(0);
|
||||
result.chatsCount = result.chatsCountMuted = state.chatsCount;
|
||||
const auto localUnread = _chatsList.unreadState();
|
||||
auto result = _chatsList.loaded() ? localUnread : _cloudUnread;
|
||||
result.messagesMuted = result.messages;
|
||||
result.chatsMuted = result.chats;
|
||||
|
||||
// We don't know the real value of marked chats counts.
|
||||
result.marksMuted = result.marks = localUnread.marks;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -376,25 +378,18 @@ void Folder::unreadStateChanged(
|
||||
}
|
||||
}
|
||||
|
||||
const auto updateCloudUnread = _cloudUnread.messagesCount.has_value()
|
||||
&& wasState.messagesCount.has_value();
|
||||
const auto updateCloudUnread = _cloudUnread.known && wasState.known;
|
||||
const auto notify = _chatsList.loaded() || updateCloudUnread;
|
||||
const auto notifier = unreadStateChangeNotifier(notify);
|
||||
|
||||
_chatsList.unreadStateChanged(wasState, nowState);
|
||||
if (!_cloudUnread.messagesCount.has_value()
|
||||
|| !wasState.messagesCount.has_value()) {
|
||||
return;
|
||||
}
|
||||
Assert(nowState.messagesCount.has_value());
|
||||
if (updateCloudUnread) {
|
||||
Assert(nowState.known);
|
||||
_cloudUnread += nowState - wasState;
|
||||
|
||||
*_cloudUnread.messagesCount += *nowState.messagesCount
|
||||
- *wasState.messagesCount;
|
||||
_cloudUnread.messagesCountMuted += nowState.messagesCountMuted
|
||||
- wasState.messagesCountMuted;
|
||||
_cloudUnread.chatsCount += nowState.chatsCount - wasState.chatsCount;
|
||||
_cloudUnread.chatsCountMuted += nowState.chatsCountMuted
|
||||
- wasState.chatsCountMuted;
|
||||
// We don't know the real value of marked chats counts.
|
||||
_cloudUnread.marks = _cloudUnread.marksMuted = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Folder::unreadEntryChanged(
|
||||
@ -411,21 +406,21 @@ void Folder::unreadEntryChanged(
|
||||
}
|
||||
}
|
||||
|
||||
const auto updateCloudUnread = _cloudUnread.messagesCount.has_value()
|
||||
&& state.messagesCount.has_value();
|
||||
const auto updateCloudUnread = _cloudUnread.known && state.known;
|
||||
const auto notify = _chatsList.loaded() || updateCloudUnread;
|
||||
const auto notifier = unreadStateChangeNotifier(notify);
|
||||
|
||||
_chatsList.unreadEntryChanged(state, added);
|
||||
if (!_cloudUnread.messagesCount.has_value()
|
||||
|| !state.messagesCount.has_value()) {
|
||||
return;
|
||||
if (updateCloudUnread) {
|
||||
if (added) {
|
||||
_cloudUnread += state;
|
||||
} else {
|
||||
_cloudUnread -= state;
|
||||
}
|
||||
|
||||
// We don't know the real value of marked chats counts.
|
||||
_cloudUnread.marks = _cloudUnread.marksMuted = 0;
|
||||
}
|
||||
const auto delta = (added ? 1 : -1);
|
||||
*_cloudUnread.messagesCount += delta * *state.messagesCount;
|
||||
_cloudUnread.messagesCountMuted += delta * state.messagesCountMuted;
|
||||
_cloudUnread.chatsCount += delta * state.chatsCount;
|
||||
_cloudUnread.chatsCountMuted += delta * state.chatsCountMuted;
|
||||
}
|
||||
|
||||
// #feed
|
||||
@ -450,9 +445,11 @@ bool Folder::shouldBeInChatList() const {
|
||||
}
|
||||
|
||||
int Folder::chatListUnreadCount() const {
|
||||
return session().settings().countUnreadMessages()
|
||||
? chatListUnreadState().messagesCount.value_or(0)
|
||||
: chatListUnreadState().chatsCount;
|
||||
const auto state = chatListUnreadState();
|
||||
return state.marks
|
||||
+ (session().settings().countUnreadMessages()
|
||||
? state.messages
|
||||
: state.chats);
|
||||
}
|
||||
|
||||
bool Folder::chatListUnreadMark() const {
|
||||
|
@ -1578,36 +1578,18 @@ void Session::updateSendActionAnimation(
|
||||
}
|
||||
|
||||
int Session::unreadBadge() const {
|
||||
const auto state = _chatsList.unreadState();
|
||||
return computeUnreadBadge(
|
||||
state.messagesCount.value_or(0),
|
||||
state.messagesCountMuted,
|
||||
state.chatsCount,
|
||||
state.chatsCountMuted);
|
||||
return computeUnreadBadge(_chatsList.unreadState());
|
||||
}
|
||||
|
||||
bool Session::unreadBadgeMuted() const {
|
||||
const auto state = _chatsList.unreadState();
|
||||
return computeUnreadBadgeMuted(
|
||||
state.messagesCount.value_or(0),
|
||||
state.messagesCountMuted,
|
||||
state.chatsCount,
|
||||
state.chatsCountMuted);
|
||||
return computeUnreadBadgeMuted(_chatsList.unreadState());
|
||||
}
|
||||
|
||||
int Session::unreadBadgeIgnoreOne(const Dialogs::Key &key) const {
|
||||
const auto remove = (key && key.entry()->inChatList())
|
||||
? key.entry()->chatListUnreadState()
|
||||
: Dialogs::UnreadState();
|
||||
if (remove.empty()) {
|
||||
return unreadBadge();
|
||||
}
|
||||
const auto state = _chatsList.unreadState();
|
||||
return computeUnreadBadge(
|
||||
state.messagesCount.value_or(0) - remove.messagesCount.value_or(0),
|
||||
state.messagesCountMuted - remove.messagesCountMuted,
|
||||
state.chatsCount - remove.chatsCount,
|
||||
state.chatsCountMuted - remove.chatsCountMuted);
|
||||
return computeUnreadBadge(_chatsList.unreadState() - remove);
|
||||
}
|
||||
|
||||
bool Session::unreadBadgeMutedIgnoreOne(const Dialogs::Key &key) const {
|
||||
@ -1617,46 +1599,33 @@ bool Session::unreadBadgeMutedIgnoreOne(const Dialogs::Key &key) const {
|
||||
const auto remove = (key && key.entry()->inChatList())
|
||||
? key.entry()->chatListUnreadState()
|
||||
: Dialogs::UnreadState();
|
||||
if (remove.empty()) {
|
||||
return unreadBadgeMuted();
|
||||
}
|
||||
const auto state = _chatsList.unreadState();
|
||||
return computeUnreadBadgeMuted(
|
||||
state.messagesCount.value_or(0) - remove.messagesCount.value_or(0),
|
||||
state.messagesCountMuted - remove.messagesCountMuted,
|
||||
state.chatsCount - remove.chatsCount,
|
||||
state.chatsCountMuted - remove.chatsCountMuted);
|
||||
return computeUnreadBadgeMuted(_chatsList.unreadState() - remove);
|
||||
}
|
||||
|
||||
int Session::unreadOnlyMutedBadge() const {
|
||||
const auto state = _chatsList.unreadState();
|
||||
return _session->settings().countUnreadMessages()
|
||||
? state.messagesCountMuted
|
||||
: state.chatsCountMuted;
|
||||
? state.messagesMuted
|
||||
: state.chatsMuted;
|
||||
}
|
||||
|
||||
int Session::computeUnreadBadge(
|
||||
int full,
|
||||
int muted,
|
||||
int entriesFull,
|
||||
int entriesMuted) const {
|
||||
const auto withMuted = _session->settings().includeMutedCounter();
|
||||
return _session->settings().countUnreadMessages()
|
||||
? (full - (withMuted ? 0 : muted))
|
||||
: (entriesFull - (withMuted ? 0 : entriesMuted));
|
||||
int Session::computeUnreadBadge(const Dialogs::UnreadState &state) const {
|
||||
const auto all = _session->settings().includeMutedCounter();
|
||||
return std::max(state.marks - (all ? 0 : state.marksMuted), 0)
|
||||
+ (_session->settings().countUnreadMessages()
|
||||
? std::max(state.messages - (all ? 0 : state.messagesMuted), 0)
|
||||
: std::max(state.chats - (all ? 0 : state.chatsMuted), 0));
|
||||
}
|
||||
|
||||
bool Session::computeUnreadBadgeMuted(
|
||||
int full,
|
||||
int muted,
|
||||
int entriesFull,
|
||||
int entriesMuted) const {
|
||||
const Dialogs::UnreadState &state) const {
|
||||
if (!_session->settings().includeMutedCounter()) {
|
||||
return false;
|
||||
}
|
||||
return _session->settings().countUnreadMessages()
|
||||
? (muted >= full)
|
||||
: (entriesMuted >= entriesFull);
|
||||
return (state.marksMuted >= state.marks)
|
||||
&& (_session->settings().countUnreadMessages()
|
||||
? (state.messagesMuted >= state.messages)
|
||||
: (state.chatsMuted >= state.chats));
|
||||
}
|
||||
|
||||
void Session::unreadStateChanged(
|
||||
|
@ -599,16 +599,8 @@ private:
|
||||
|
||||
void checkSelfDestructItems();
|
||||
|
||||
int computeUnreadBadge(
|
||||
int full,
|
||||
int muted,
|
||||
int entriesFull,
|
||||
int entriesMuted) const;
|
||||
bool computeUnreadBadgeMuted(
|
||||
int full,
|
||||
int muted,
|
||||
int entriesFull,
|
||||
int entriesMuted) const;
|
||||
int computeUnreadBadge(const Dialogs::UnreadState &state) const;
|
||||
bool computeUnreadBadgeMuted(const Dialogs::UnreadState &state) const;
|
||||
|
||||
void applyDialog(Data::Folder *requestFolder, const MTPDdialog &data);
|
||||
void applyDialog(
|
||||
|
@ -41,18 +41,50 @@ struct PositionChange {
|
||||
};
|
||||
|
||||
struct UnreadState {
|
||||
std::optional<int> messagesCount;
|
||||
int messagesCountMuted = 0;
|
||||
int chatsCount = 0;
|
||||
int chatsCountMuted = 0;
|
||||
bool mark = false;
|
||||
bool markMuted = false;
|
||||
int messages = 0;
|
||||
int messagesMuted = 0;
|
||||
int chats = 0;
|
||||
int chatsMuted = 0;
|
||||
int marks = 0;
|
||||
int marksMuted = 0;
|
||||
bool known = false;
|
||||
|
||||
UnreadState &operator+=(const UnreadState &other) {
|
||||
messages += other.messages;
|
||||
messagesMuted += other.messagesMuted;
|
||||
chats += other.chats;
|
||||
chatsMuted += other.chatsMuted;
|
||||
marks += other.marks;
|
||||
marksMuted += other.marksMuted;
|
||||
return *this;
|
||||
}
|
||||
UnreadState &operator-=(const UnreadState &other) {
|
||||
messages -= other.messages;
|
||||
messagesMuted -= other.messagesMuted;
|
||||
chats -= other.chats;
|
||||
chatsMuted -= other.chatsMuted;
|
||||
marks -= other.marks;
|
||||
marksMuted -= other.marksMuted;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool empty() const {
|
||||
return !messagesCount.value_or(0) && !chatsCount && !mark;
|
||||
return !messages && !chats && !marks;
|
||||
}
|
||||
};
|
||||
|
||||
inline UnreadState operator+(const UnreadState &a, const UnreadState &b) {
|
||||
auto result = a;
|
||||
result += b;
|
||||
return result;
|
||||
}
|
||||
|
||||
inline UnreadState operator-(const UnreadState &a, const UnreadState &b) {
|
||||
auto result = a;
|
||||
result -= b;
|
||||
return result;
|
||||
}
|
||||
|
||||
class Entry {
|
||||
public:
|
||||
Entry(not_null<Data::Session*> owner, const Key &key);
|
||||
|
@ -11,41 +11,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "history/history.h"
|
||||
|
||||
namespace Dialogs {
|
||||
namespace {
|
||||
|
||||
UnreadState ApplyMarkToCounters(const UnreadState &state) {
|
||||
auto result = UnreadState();
|
||||
const auto count = state.messagesCount.value_or(0);
|
||||
result.messagesCount = (count > 0)
|
||||
? count
|
||||
: state.mark
|
||||
? 1
|
||||
: 0;
|
||||
result.messagesCountMuted = (state.messagesCountMuted > 0)
|
||||
? state.messagesCountMuted
|
||||
: state.markMuted
|
||||
? 1
|
||||
: 0;
|
||||
result.chatsCount = (state.chatsCount > 0)
|
||||
? state.chatsCount
|
||||
: state.mark
|
||||
? 1
|
||||
: 0;
|
||||
result.chatsCountMuted = (state.chatsCountMuted > 0)
|
||||
? state.chatsCountMuted
|
||||
: state.markMuted
|
||||
? 1
|
||||
: 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
MainList::MainList(rpl::producer<int> pinnedLimit)
|
||||
: _all(SortMode::Date)
|
||||
, _important(SortMode::Date)
|
||||
, _pinned(1) {
|
||||
_unreadState.messagesCount = 0;
|
||||
_unreadState.known = true;
|
||||
|
||||
std::move(
|
||||
pinnedLimit
|
||||
@ -84,27 +55,17 @@ void MainList::clear() {
|
||||
void MainList::unreadStateChanged(
|
||||
const UnreadState &wasState,
|
||||
const UnreadState &nowState) {
|
||||
const auto wasWithMark = ApplyMarkToCounters(wasState);
|
||||
const auto nowWithMark = ApplyMarkToCounters(nowState);
|
||||
*_unreadState.messagesCount += *nowWithMark.messagesCount
|
||||
- *wasWithMark.messagesCount;
|
||||
_unreadState.messagesCountMuted += nowWithMark.messagesCountMuted
|
||||
- wasWithMark.messagesCountMuted;
|
||||
_unreadState.chatsCount += nowWithMark.chatsCount
|
||||
- wasWithMark.chatsCount;
|
||||
_unreadState.chatsCountMuted += nowWithMark.chatsCountMuted
|
||||
- wasWithMark.chatsCountMuted;
|
||||
_unreadState += nowState - wasState;
|
||||
}
|
||||
|
||||
void MainList::unreadEntryChanged(
|
||||
const Dialogs::UnreadState &state,
|
||||
bool added) {
|
||||
const auto withMark = ApplyMarkToCounters(state);
|
||||
const auto delta = (added ? 1 : -1);
|
||||
*_unreadState.messagesCount += delta * *withMark.messagesCount;
|
||||
_unreadState.messagesCountMuted += delta * withMark.messagesCountMuted;
|
||||
_unreadState.chatsCount += delta * withMark.chatsCount;
|
||||
_unreadState.chatsCountMuted += delta * withMark.chatsCountMuted;
|
||||
if (added) {
|
||||
_unreadState += state;
|
||||
} else {
|
||||
_unreadState -= state;
|
||||
}
|
||||
}
|
||||
|
||||
UnreadState MainList::unreadState() const {
|
||||
|
@ -2029,12 +2029,14 @@ bool History::chatListMutedBadge() const {
|
||||
Dialogs::UnreadState History::chatListUnreadState() const {
|
||||
auto result = Dialogs::UnreadState();
|
||||
const auto count = _unreadCount.value_or(0);
|
||||
result.messagesCount = _unreadCount;
|
||||
result.messagesCountMuted = (_unreadCount && mute()) ? count : 0;
|
||||
result.chatsCount = count ? 1 : 0;
|
||||
result.chatsCountMuted = (count && mute()) ? 1 : 0;
|
||||
result.mark = _unreadMark;
|
||||
result.markMuted = mute() ? _unreadMark : false;
|
||||
const auto mark = !count && _unreadMark;
|
||||
result.messages = count;
|
||||
result.messagesMuted = mute() ? count : 0;
|
||||
result.chats = count ? 1 : 0;
|
||||
result.chatsMuted = (count && mute()) ? 1 : 0;
|
||||
result.marks = mark ? 1 : 0;
|
||||
result.marksMuted = (mark && mute()) ? 1 : 0;
|
||||
result.known = _unreadCount.has_value();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user