diff --git a/Telegram/SourceFiles/data/data_chat_filters.cpp b/Telegram/SourceFiles/data/data_chat_filters.cpp index 141cf2a5d..535acc205 100644 --- a/Telegram/SourceFiles/data/data_chat_filters.cpp +++ b/Telegram/SourceFiles/data/data_chat_filters.cpp @@ -377,6 +377,7 @@ void ChatFilters::load(bool force) { api.request(_loadRequestId).cancel(); _loadRequestId = api.request(MTPmessages_GetDialogFilters( )).done([=](const MTPmessages_DialogFilters &result) { + _tagsEnabled = result.data().is_tags_enabled(); received(result.data().vfilters().v); _loadRequestId = 0; }).fail([=] { @@ -388,6 +389,14 @@ void ChatFilters::load(bool force) { }).send(); } +bool ChatFilters::tagsEnabled() const { + return _tagsEnabled.current(); +} + +rpl::producer ChatFilters::tagsEnabledValue() const { + return _tagsEnabled.value(); +} + void ChatFilters::received(const QVector &list) { auto position = 0; auto changed = false; @@ -619,7 +628,8 @@ bool ChatFilters::applyChange(ChatFilter &filter, ChatFilter &&updated) { || pinnedChanged || (filter.title() != updated.title()) || (filter.iconEmoji() != updated.iconEmoji()); - if (!listUpdated && !chatlistChanged) { + const auto colorChanged = filter.colorIndex() != updated.colorIndex(); + if (!listUpdated && !chatlistChanged && !colorChanged) { return false; } const auto wasFilter = std::move(filter); @@ -627,8 +637,9 @@ bool ChatFilters::applyChange(ChatFilter &filter, ChatFilter &&updated) { auto entryToRefreshHeight = (Dialogs::Entry*)(nullptr); if (rulesChanged) { const auto filterList = _owner->chatsFilters().chatsList(id); + const auto areTagsEnabled = tagsEnabled(); const auto tagsExistence = [&](not_null row) { - return entryToRefreshHeight + return (!areTagsEnabled || entryToRefreshHeight) ? false : row->entry()->hasChatsFilterTags(0); }; @@ -672,6 +683,9 @@ bool ChatFilters::applyChange(ChatFilter &filter, ChatFilter &&updated) { if (chatlistChanged) { _isChatlistChanged.fire_copy(id); } + if (colorChanged) { + _tagColorChanged.fire_copy(id); + } if (entryToRefreshHeight) { // Trigger a full refresh of height for the main list. entryToRefreshHeight->updateChatListEntryHeight(); @@ -818,6 +832,10 @@ rpl::producer ChatFilters::isChatlistChanged() const { return _isChatlistChanged.events(); } +rpl::producer ChatFilters::tagColorChanged() const { + return _tagColorChanged.events(); +} + bool ChatFilters::loadNextExceptions(bool chatsListLoaded) { if (_exceptionsLoadRequestId) { return true; diff --git a/Telegram/SourceFiles/data/data_chat_filters.h b/Telegram/SourceFiles/data/data_chat_filters.h index e123ab2c1..42a635809 100644 --- a/Telegram/SourceFiles/data/data_chat_filters.h +++ b/Telegram/SourceFiles/data/data_chat_filters.h @@ -139,6 +139,7 @@ public: [[nodiscard]] const std::vector &list() const; [[nodiscard]] rpl::producer<> changed() const; [[nodiscard]] rpl::producer isChatlistChanged() const; + [[nodiscard]] rpl::producer tagColorChanged() const; [[nodiscard]] bool loaded() const; [[nodiscard]] bool has() const; @@ -185,6 +186,9 @@ public: FilterId id) const; void moreChatsHide(FilterId id, bool localOnly = false); + [[nodiscard]] bool tagsEnabled() const; + [[nodiscard]] rpl::producer tagsEnabledValue() const; + private: struct MoreChatsData { std::vector> missing; @@ -209,6 +213,7 @@ private: base::flat_map> _chatsLists; rpl::event_stream<> _listChanged; rpl::event_stream _isChatlistChanged; + rpl::event_stream _tagColorChanged; mtpRequestId _loadRequestId = 0; mtpRequestId _saveOrderRequestId = 0; mtpRequestId _saveOrderAfterId = 0; @@ -220,6 +225,8 @@ private: rpl::event_stream<> _suggestedUpdated; crl::time _suggestedLastReceived = 0; + rpl::variable _tagsEnabled = false; + std::deque _exceptionsToLoad; mtpRequestId _exceptionsLoadRequestId = 0; diff --git a/Telegram/SourceFiles/dialogs/dialogs_entry.cpp b/Telegram/SourceFiles/dialogs/dialogs_entry.cpp index 957e7f4f5..76d5ebe84 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_entry.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_entry.cpp @@ -415,6 +415,9 @@ void Entry::updateChatListEntryHeight() { } [[nodiscard]] bool Entry::hasChatsFilterTags(FilterId exclude) const { + if (!owner().chatsFilters().tagsEnabled()) { + return false; + } if (exclude) { if (_tagColors.size() == 1) { if (_tagColors.begin()->first == exclude) { diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp index 2fb445fa1..44f672bec 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp @@ -297,6 +297,47 @@ InnerWidget::InnerWidget( refreshWithCollapsedRows(); }, lifetime()); + session().data().chatsFilters().tagsEnabledValue( + ) | rpl::distinct_until_changed() | rpl::start_with_next([=](bool tags) { + _handleChatListEntryTagRefreshesLifetime.destroy(); + if (_shownList->updateHeights(_narrowRatio)) { + refresh(); + } + if (!tags) { + return; + } + using Event = Data::Session::ChatListEntryRefresh; + session().data().chatListEntryRefreshes( + ) | rpl::filter([=](const Event &event) { + if (_waitingAllChatListEntryRefreshesForTags) { + return false; + } + if (event.existenceChanged) { + if (event.key.entry()->inChatList(_filterId)) { + _waitingAllChatListEntryRefreshesForTags = true; + return true; + } + } + return false; + }) | rpl::start_with_next([=](const Event &event) { + Ui::PostponeCall(crl::guard(this, [=] { + _waitingAllChatListEntryRefreshesForTags = false; + if (_shownList->updateHeights(_narrowRatio)) { + refresh(); + } + })); + }, _handleChatListEntryTagRefreshesLifetime); + + session().data().chatsFilters().tagColorChanged( + ) | rpl::start_with_next([=](FilterId filterId) { + const auto it = _chatsFilterTags.find(filterId); + if (it != _chatsFilterTags.end()) { + _chatsFilterTags.erase(it); + update(); + } + }, _handleChatListEntryTagRefreshesLifetime); + }, lifetime()); + session().settings().archiveInMainMenuChanges( ) | rpl::start_with_next([=] { refresh(); @@ -2260,27 +2301,6 @@ void InnerWidget::handleChatListEntryRefreshes() { std::abs(from - to) + event.moved.height); } }, lifetime()); - - session().data().chatListEntryRefreshes( - ) | rpl::filter([=](const Event &event) { - if (_waitingAllChatListEntryRefreshesForTags) { - return false; - } - if (event.existenceChanged) { - if (event.key.entry()->inChatList(_filterId)) { - _waitingAllChatListEntryRefreshesForTags = true; - return true; - } - } - return false; - }) | rpl::start_with_next([=](const Event &event) { - Ui::PostponeCall(crl::guard(this, [=] { - _waitingAllChatListEntryRefreshesForTags = false; - if (_shownList->updateHeights(_narrowRatio)) { - refresh(); - } - })); - }, lifetime()); } void InnerWidget::repaintCollapsedFolderRow(not_null folder) { diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h index 7af57126e..4819d0646 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h @@ -558,6 +558,7 @@ private: std::unordered_map _chatsFilterTags; bool _waitingAllChatListEntryRefreshesForTags = false; + rpl::lifetime _handleChatListEntryTagRefreshesLifetime; Fn _loadMoreCallback; Fn _loadMoreFilteredCallback;