Show two hardcoded filters in Ui.

This commit is contained in:
John Preston 2020-02-07 15:34:05 +04:00
parent 71f7aae948
commit 2f1ee6f1fa
15 changed files with 179 additions and 105 deletions

View File

@ -24,6 +24,10 @@ ChatFilter::ChatFilter(
, _flags(flags) {
}
QString ChatFilter::title() const {
return _title;
}
bool ChatFilter::contains(not_null<History*> history) const {
const auto flag = [&] {
const auto peer = history->peer;
@ -43,6 +47,9 @@ bool ChatFilter::contains(not_null<History*> history) const {
Unexpected("Peer type in ChatFilter::contains.");
}
}();
if (history->folder()) {
return false;
}
return false
|| ((_flags & flag)
&& (!(_flags & Flag::NoMuted) || !history->mute())
@ -50,4 +57,34 @@ bool ChatFilter::contains(not_null<History*> history) const {
|| _always.contains(history);
}
ChatFilters::ChatFilters(not_null<Session*> owner) : _owner(owner) {
using Flag = ChatFilter::Flag;
const auto all = Flag::Users
| Flag::SecretChats
| Flag::PrivateGroups
| Flag::PublicGroups
| Flag::Broadcasts
| Flag::Bots;
_list.emplace(
1,
ChatFilter("Unmuted Chats", all | ChatFilter::Flag::NoMuted, {}));
_list.emplace(
2,
ChatFilter("Unread Chats", all | ChatFilter::Flag::NoRead, {}));
}
const base::flat_map<FilterId, ChatFilter> &ChatFilters::list() const {
return _list;
}
void ChatFilters::refreshHistory(not_null<History*> history) {
_refreshHistoryRequests.fire_copy(history);
}
auto ChatFilters::refreshHistoryRequests() const
-> rpl::producer<not_null<History*>> {
return _refreshHistoryRequests.events();
}
} // namespace Data

View File

@ -13,16 +13,19 @@ class History;
namespace Data {
class Session;
class ChatFilter final {
public:
enum class Flag : uchar {
Users = 0x01,
PrivateGroups = 0x02,
PublicGroups = 0x04,
Broadcasts = 0x08,
Bots = 0x10,
NoMuted = 0x20,
NoRead = 0x40,
SecretChats = 0x02,
PrivateGroups = 0x04,
PublicGroups = 0x08,
Broadcasts = 0x10,
Bots = 0x20,
NoMuted = 0x40,
NoRead = 0x80,
};
friend constexpr inline bool is_flag_type(Flag) { return true; };
using Flags = base::flags<Flag>;
@ -33,6 +36,8 @@ public:
Flags flags,
base::flat_set<not_null<History*>> always);
[[nodiscard]] QString title() const;
[[nodiscard]] bool contains(not_null<History*> history) const;
private:
@ -42,4 +47,22 @@ private:
};
class ChatFilters final {
public:
explicit ChatFilters(not_null<Session*> owner);
[[nodiscard]] const base::flat_map<FilterId, ChatFilter> &list() const;
void refreshHistory(not_null<History*> history);
[[nodiscard]] auto refreshHistoryRequests() const
-> rpl::producer<not_null<History*>>;
private:
const not_null<Session*> _owner;
base::flat_map<FilterId, ChatFilter> _list;
rpl::event_stream<not_null<History*>> _refreshHistoryRequests;
};
} // namespace Data

View File

@ -184,6 +184,7 @@ Session::Session(not_null<Main::Session*> session)
Local::cacheBigFilePath(),
Local::cacheBigFileSettings()))
, _chatsList(PinnedDialogsCountMaxValue(session))
, _chatsFilters(this)
, _contactsList(Dialogs::SortMode::Name)
, _contactsNoChatsList(Dialogs::SortMode::Name)
, _selfDestructTimer([=] { checkSelfDestructItems(); })
@ -3347,6 +3348,14 @@ not_null<const Dialogs::MainList*> Session::chatsList(
return folder ? folder->chatsList() : &_chatsList;
}
not_null<ChatFilters*> Session::chatsFilters() {
return &_chatsFilters;
}
not_null<const ChatFilters*> Session::chatsFilters() const {
return &_chatsFilters;
}
not_null<Dialogs::IndexedList*> Session::contactsList() {
return &_contactsList;
}
@ -3355,33 +3364,42 @@ not_null<Dialogs::IndexedList*> Session::contactsNoChatsList() {
return &_contactsNoChatsList;
}
auto Session::refreshChatListEntry(Dialogs::Key key)
auto Session::refreshChatListEntry(
Dialogs::Key key,
FilterId filterIdForResult)
-> RefreshChatListEntryResult {
using namespace Dialogs;
const auto entry = key.entry();
auto result = RefreshChatListEntryResult();
result.changed = !entry->inChatList();
if (result.changed) {
const auto history = key.history();
auto mainListResult = RefreshChatListEntryResult();
mainListResult.changed = !entry->inChatList();
if (mainListResult.changed) {
const auto mainRow = entry->addToChatList(0);
_contactsNoChatsList.del(key, mainRow);
} else {
result.moved = entry->adjustByPosInChatList(0);
mainListResult.moved = entry->adjustByPosInChatList(0);
}
auto result = filterIdForResult
? RefreshChatListEntryResult()
: mainListResult;
for (const auto &[filterId, filter] : _chatsFilters.list()) {
auto filterResult = RefreshChatListEntryResult();
if (history && filter.contains(history)) {
filterResult.changed = !entry->inChatList(filterId);
if (filterResult.changed) {
entry->addToChatList(filterId);
} else {
filterResult.moved = entry->adjustByPosInChatList(filterId);
}
} else if (entry->inChatList(filterId)) {
entry->removeFromChatList(filterId);
filterResult.changed = true;
}
if (filterId == filterIdForResult) {
result = filterResult;
}
}
//if (Global::DialogsFiltersEnabled()) { // #TODO filters
// if (entry->toImportant()) {
// result.importantChanged = !entry->inChatList(Mode::Important);
// if (result.importantChanged) {
// entry->addToChatList(Mode::Important);
// } else {
// result.importantMoved = entry->adjustByPosInChatList(
// Mode::Important);
// }
// } else if (entry->inChatList(Mode::Important)) {
// entry->removeFromChatList(Mode::Important);
// result.importantChanged = true;
// }
//}
return result;
}
@ -3390,9 +3408,9 @@ void Session::removeChatListEntry(Dialogs::Key key) {
const auto entry = key.entry();
entry->removeFromChatList(0);
//if (Global::DialogsFiltersEnabled()) { // #TODO filters
// entry->removeFromChatList(Mode::Important);
//}
for (const auto &[filterId, filter] : _chatsFilters.list()) {
entry->removeFromChatList(filterId);
}
if (_contactsList.contains(key)) {
if (!_contactsNoChatsList.contains(key)) {
_contactsNoChatsList.addByName(key);

View File

@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "dialogs/dialogs_main_list.h"
#include "data/data_groups.h"
#include "data/data_notify_settings.h"
#include "data/data_chat_filters.h"
#include "history/history_location_manager.h"
#include "base/timer.h"
#include "base/flags.h"
@ -621,19 +622,22 @@ public:
//FeedId defaultFeedId() const;
//rpl::producer<FeedId> defaultFeedIdValue() const;
not_null<Dialogs::MainList*> chatsList(Data::Folder *folder = nullptr);
not_null<const Dialogs::MainList*> chatsList(
[[nodiscard]] not_null<Dialogs::MainList*> chatsList(
Data::Folder *folder = nullptr);
[[nodiscard]] not_null<const Dialogs::MainList*> chatsList(
Data::Folder *folder = nullptr) const;
not_null<Dialogs::IndexedList*> contactsList();
not_null<Dialogs::IndexedList*> contactsNoChatsList();
[[nodiscard]] not_null<ChatFilters*> chatsFilters();
[[nodiscard]] not_null<const ChatFilters*> chatsFilters() const;
[[nodiscard]] not_null<Dialogs::IndexedList*> contactsList();
[[nodiscard]] not_null<Dialogs::IndexedList*> contactsNoChatsList();
struct RefreshChatListEntryResult {
bool changed = false;
bool importantChanged = false;
Dialogs::PositionChange moved;
Dialogs::PositionChange importantMoved;
};
RefreshChatListEntryResult refreshChatListEntry(Dialogs::Key key);
RefreshChatListEntryResult refreshChatListEntry(
Dialogs::Key key,
FilterId filterIdForResult);
void removeChatListEntry(Dialogs::Key key);
struct DialogsRowReplacement {
@ -870,6 +874,7 @@ private:
Stickers::SavedGifs _savedGifs;
Dialogs::MainList _chatsList;
ChatFilters _chatsFilters;
Dialogs::IndexedList _contactsList;
Dialogs::IndexedList _contactsNoChatsList;

View File

@ -81,10 +81,12 @@ int PinnedDialogsCount(not_null<Dialogs::IndexedList*> list) {
} // namespace
struct InnerWidget::CollapsedRow {
explicit CollapsedRow(Data::Folder *folder = nullptr) : folder(folder) {
CollapsedRow(Data::Folder *folder, FilterId filterId)
: folder(folder), filterId(filterId) {
}
Data::Folder *folder = nullptr;
FilterId filterId = 0;
BasicRow row;
};
@ -202,6 +204,14 @@ InnerWidget::InnerWidget(
refresh();
}, lifetime());
session().data().chatsFilters()->refreshHistoryRequests(
) | rpl::start_with_next([=](not_null<History*> history) {
if (history->inChatList()
&& !session().data().chatsFilters()->list().empty()) {
refreshDialog(history);
}
}, lifetime());
subscribe(Window::Theme::Background(), [=](const Window::Theme::BackgroundUpdate &data) {
if (data.paletteChanged()) {
Layout::clearUnreadBadgesCache();
@ -281,7 +291,13 @@ void InnerWidget::refreshWithCollapsedRows(bool toTop) {
_collapsedRows.clear();
if (!_openedFolder && Global::DialogsFiltersEnabled()) {
_collapsedRows.push_back(std::make_unique<CollapsedRow>());
if (_filterId) {
_collapsedRows.push_back(std::make_unique<CollapsedRow>(nullptr, 0));
} else {
for (const auto &[filterId, filter] : session().data().chatsFilters()->list()) {
_collapsedRows.push_back(std::make_unique<CollapsedRow>(nullptr, filterId));
}
}
}
const auto list = shownDialogs();
const auto archive = !list->empty()
@ -296,8 +312,8 @@ void InnerWidget::refreshWithCollapsedRows(bool toTop) {
setPressed(nullptr);
}
_skipTopDialogs = 1;
if (!inMainMenu) {
_collapsedRows.push_back(std::make_unique<CollapsedRow>(archive));
if (!inMainMenu && !_filterId) {
_collapsedRows.push_back(std::make_unique<CollapsedRow>(archive, 0));
}
} else {
_skipTopDialogs = 0;
@ -686,12 +702,13 @@ void InnerWidget::paintCollapsedRow(
const auto narrow = (width() <= smallWidth);
const auto text = row->folder
? row->folder->chatListName()
: _filterId // #TODO filters
: _filterId
? (narrow ? "Show" : tr::lng_dialogs_show_all_chats(tr::now))
: (narrow ? "Hide" : tr::lng_dialogs_hide_muted_chats(tr::now));
: session().data().chatsFilters()->list().find(
row->filterId)->second.title();
const auto unread = row->folder
? row->folder->chatListUnreadCount()
: _filterId // #TODO filters
: _filterId
? session().data().unreadOnlyMutedBadge()
: 0;
Layout::PaintCollapsedRow(
@ -1434,17 +1451,12 @@ void InnerWidget::refreshDialog(Key key) {
}
}
const auto result = session().data().refreshChatListEntry(key);
const auto changed = _filterId // #TODO filters
? result.importantChanged
: result.changed;
const auto moved = _filterId // #TODO filters
? result.importantMoved
: result.moved;
const auto result = session().data().refreshChatListEntry(
key,
_filterId);
const auto rowHeight = st::dialogsRowHeight;
const auto from = dialogsOffset() + moved.from * rowHeight;
const auto to = dialogsOffset() + moved.to * rowHeight;
const auto from = dialogsOffset() + result.moved.from * rowHeight;
const auto to = dialogsOffset() + result.moved.to * rowHeight;
if (!_dragging
&& (from != to)
&& (key.entry()->folder() == _openedFolder)) {
@ -1452,7 +1464,7 @@ void InnerWidget::refreshDialog(Key key) {
emit dialogMoved(from, to);
}
if (changed) {
if (result.changed) {
refresh();
} else if (_state == WidgetState::Default && from != to) {
update(
@ -2136,14 +2148,6 @@ void InnerWidget::peerSearchReceived(
refresh();
}
void InnerWidget::notify_historyMuteUpdated(History *history) {
// #TODO filters
if (!Global::DialogsFiltersEnabled() || !history->inChatList()) {
return;
}
refreshDialog(history);
}
Data::Folder *InnerWidget::shownFolder() const {
return _openedFolder;
}
@ -2528,19 +2532,18 @@ bool InnerWidget::chooseCollapsedRow() {
if (row->folder) {
_controller->openFolder(row->folder);
} else {
switchImportantChats();
switchToFilter(row->filterId);
}
return true;
}
void InnerWidget::switchImportantChats() {
void InnerWidget::switchToFilter(FilterId filterId) {
clearSelection();
// #TODO filters
//if (Global::DialogsFilterId() == 0) {
// Global::SetDialogsMode(Mode::Important);
//} else {
// Global::SetDialogsMode(Mode::All);
//}
if (!Global::DialogsFiltersEnabled()
|| !session().data().chatsFilters()->list().contains(filterId)) {
filterId = 0;
}
Global::SetDialogsFilterId(filterId);
_filterId = Global::DialogsFilterId();
Local::writeUserSettings();
refreshWithCollapsedRows(true);

View File

@ -126,8 +126,6 @@ public:
rpl::producer<ChosenRow> chosenRow() const;
void notify_historyMuteUpdated(History *history);
~InnerWidget();
public slots:
@ -176,7 +174,7 @@ private:
void refreshWithCollapsedRows(bool toTop = false);
bool needCollapsedRowsRefresh() const;
bool chooseCollapsedRow();
void switchImportantChats();
void switchToFilter(FilterId filterId);
bool chooseHashtag();
ChosenRow computeChosenRow() const;
bool isSearchResultActive(

View File

@ -49,9 +49,7 @@ void MainList::setLoaded(bool loaded) {
void MainList::clear() {
_all.clear();
for (auto &[filterId, list] : _other) { // #TODO filters _other.clear?..
list.clear();
}
_other.clear();
_unreadState = UnreadState();
}

View File

@ -678,10 +678,6 @@ void Widget::escape() {
}
}
void Widget::notify_historyMuteUpdated(History *history) {
_inner->notify_historyMuteUpdated(history);
}
void Widget::refreshLoadMoreButton(bool mayBlock, bool isBlocked) {
if (!mayBlock) {
_loadMoreChats.destroy();

View File

@ -85,8 +85,6 @@ public:
bool wheelEventFromFloatPlayer(QEvent *e) override;
QRect rectForFloatPlayer() const override;
void notify_historyMuteUpdated(History *history);
~Widget();
signals:

View File

@ -277,10 +277,6 @@ bool switchInlineBotButtonReceived(const QString &query, UserData *samePeerBot,
return false;
}
void historyMuteUpdated(History *history) {
if (MainWidget *m = App::main()) m->notify_historyMuteUpdated(history);
}
void unreadCounterUpdated() {
Global::RefHandleUnreadCounterUpdate().call();
}

View File

@ -89,7 +89,6 @@ void replyMarkupUpdated(const HistoryItem *item);
void inlineKeyboardMoved(const HistoryItem *item, int oldKeyboardTop, int newKeyboardTop);
bool switchInlineBotButtonReceived(const QString &query, UserData *samePeerBot = nullptr, MsgId samePeerReplyTo = 0);
void historyMuteUpdated(History *history);
void unreadCounterUpdated();
enum class ScreenCorner {

View File

@ -838,8 +838,8 @@ void History::setUnreadMentionsCount(int count) {
}
_unreadMentionsCount = count;
const auto has = (count > 0);
if (has != had && Global::DialogsFiltersEnabled()) { // #TODO filters
Notify::historyMuteUpdated(this);
if (has != had) {
owner().chatsFilters()->refreshHistory(this);
updateChatListEntry();
}
}
@ -1782,7 +1782,11 @@ void History::setUnreadCount(int newUnreadCount) {
}
const auto notifier = unreadStateChangeNotifier(true);
const auto wasForBadge = (unreadCountForBadge() > 0);
_unreadCount = newUnreadCount;
if (wasForBadge != (unreadCountForBadge() > 0)) {
owner().chatsFilters()->refreshHistory(this);
}
if (newUnreadCount == 1) {
if (loadedAtBottom()) {
@ -1819,6 +1823,7 @@ void History::setUnreadMark(bool unread) {
_unreadMark = unread;
if (inChatList() && noUnreadMessages) {
owner().chatsFilters()->refreshHistory(this);
updateChatListEntry();
}
Notify::peerUpdatedDelayed(
@ -1844,7 +1849,7 @@ bool History::changeMute(bool newMute) {
_mute = newMute;
if (inChatList()) {
Notify::historyMuteUpdated(this);
owner().chatsFilters()->refreshHistory(this);
updateChatListEntry();
}
Notify::peerUpdatedDelayed(
@ -1920,14 +1925,12 @@ void History::setFolderPointer(Data::Folder *folder) {
}
const auto wasKnown = folderKnown();
const auto wasInList = inChatList();
// #TODO filters
//const auto wasInImportant = wasInList && inChatList(Mode::Important);
//if (wasInList) {
// removeFromChatList(Mode::All);
// if (wasInImportant) {
// removeFromChatList(Mode::Important);
// }
//}
if (wasInList) {
removeFromChatList(0);
for (const auto &[filterId, _] : owner().chatsFilters()->list()) {
removeFromChatList(filterId);
}
}
const auto was = _folder.value_or(nullptr);
_folder = folder;
if (was) {
@ -1935,9 +1938,11 @@ void History::setFolderPointer(Data::Folder *folder) {
}
if (wasInList) {
addToChatList(0);
//if (wasInImportant) { // #TODO filters
// addToChatList(Mode::Important);
//}
for (const auto &[filterId, filter] : owner().chatsFilters()->list()) {
if (filter.contains(this)) {
addToChatList(filterId);
}
}
owner().chatsListChanged(was);
owner().chatsListChanged(folder);
} else if (!wasKnown) {

View File

@ -1453,6 +1453,9 @@ bool HistoryWidget::notify_switchInlineBotButtonReceived(const QString &query, U
}
void HistoryWidget::notify_userIsBotChanged(UserData *user) {
if (const auto history = session().data().history(user)) {
session().data().chatsFilters()->refreshHistory(history);
}
if (_peer && _peer == user) {
_list->notifyIsBotChanged();
_list->updateBotInfo();

View File

@ -783,10 +783,6 @@ void MainWidget::notify_userIsBotChanged(UserData *bot) {
_history->notify_userIsBotChanged(bot);
}
void MainWidget::notify_historyMuteUpdated(History *history) {
_dialogs->notify_historyMuteUpdated(history);
}
void MainWidget::clearHider(not_null<Window::HistoryHider*> instance) {
if (_hider != instance) {
return;

View File

@ -287,7 +287,6 @@ public:
void notify_inlineKeyboardMoved(const HistoryItem *item, int oldKeyboardTop, int newKeyboardTop);
bool notify_switchInlineBotButtonReceived(const QString &query, UserData *samePeerBot, MsgId samePeerReplyTo);
void notify_userIsBotChanged(UserData *bot);
void notify_historyMuteUpdated(History *history);
void closeBothPlayers();