diff --git a/Telegram/SourceFiles/boxes/peer_list_controllers.cpp b/Telegram/SourceFiles/boxes/peer_list_controllers.cpp index 2b6649ed3..3315dabb3 100644 --- a/Telegram/SourceFiles/boxes/peer_list_controllers.cpp +++ b/Telegram/SourceFiles/boxes/peer_list_controllers.cpp @@ -258,8 +258,8 @@ void ChatsListBoxController::rebuildRows() { ++added; } } - added += appendList(App::main()->dialogsList()); - added += appendList(App::main()->contactsNoDialogsList()); + added += appendList(Auth().data().chatsList()); + added += appendList(Auth().data().contactsNoChatsList()); if (!wasEmpty && added > 0) { // Place dialogs list before contactsNoDialogs list. delegate()->peerListPartitionRows([](const PeerListRow &a) { @@ -327,7 +327,7 @@ void ContactsBoxController::prepare() { } void ContactsBoxController::rebuildRows() { - auto appendList = [this](auto chats) { + const auto appendList = [&](auto chats) { auto count = 0; for (const auto row : chats->all()) { if (const auto history = row->history()) { @@ -340,7 +340,7 @@ void ContactsBoxController::rebuildRows() { } return count; }; - appendList(App::main()->contactsList()); + appendList(Auth().data().contactsList()); checkForEmptyRows(); delegate()->peerListRefreshRows(); } diff --git a/Telegram/SourceFiles/boxes/peers/add_participants_box.cpp b/Telegram/SourceFiles/boxes/peers/add_participants_box.cpp index a716cfbe6..359ebd9cb 100644 --- a/Telegram/SourceFiles/boxes/peers/add_participants_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/add_participants_box.cpp @@ -1061,16 +1061,16 @@ void AddSpecialBoxSearchController::addChatsContacts() { return true; }; - const auto getSmallestIndex = [&]( - Dialogs::IndexedList *list) -> const Dialogs::List* { - if (list->isEmpty()) { + const auto getSmallestIndex = [&](not_null list) + -> const Dialogs::List* { + if (list->empty()) { return nullptr; } auto result = (const Dialogs::List*)nullptr; for (const auto &word : wordList) { const auto found = list->filtered(word[0]); - if (found->empty()) { + if (!found || found->empty()) { return nullptr; } if (!result || result->size() > found->size()) { @@ -1079,9 +1079,9 @@ void AddSpecialBoxSearchController::addChatsContacts() { } return result; }; - const auto dialogsIndex = getSmallestIndex(App::main()->dialogsList()); + const auto dialogsIndex = getSmallestIndex(_peer->owner().chatsList()); const auto contactsIndex = getSmallestIndex( - App::main()->contactsNoDialogsList()); + _peer->owner().contactsNoChatsList()); const auto filterAndAppend = [&](const Dialogs::List *list) { if (!list) { diff --git a/Telegram/SourceFiles/boxes/share_box.cpp b/Telegram/SourceFiles/boxes/share_box.cpp index 9ae0548cc..8562ad57e 100644 --- a/Telegram/SourceFiles/boxes/share_box.cpp +++ b/Telegram/SourceFiles/boxes/share_box.cpp @@ -489,7 +489,7 @@ ShareBox::Inner::Inner( _rowHeight = st::shareRowHeight; setAttribute(Qt::WA_OpaquePaintEvent); - const auto dialogs = App::main()->dialogsList(); + const auto dialogs = Auth().data().chatsList(); const auto self = Auth().user(); if (_filterCallback(self)) { _chatsIndexed->addToEnd(self->owner().history(self)); @@ -670,7 +670,7 @@ void ShareBox::Inner::loadProfilePhotos(int yFrom) { Auth().downloader().clearPriorities(); if (_filter.isEmpty()) { - if (!_chatsIndexed->isEmpty()) { + if (!_chatsIndexed->empty()) { auto i = _chatsIndexed->cfind(yFrom, _rowHeight); for (auto end = _chatsIndexed->cend(); i != end; ++i) { if (((*i)->pos() * _rowHeight) >= yTo) { @@ -769,7 +769,7 @@ void ShareBox::Inner::paintEvent(QPaintEvent *e) { auto indexFrom = rowFrom * _columnCount; auto indexTo = rowTo * _columnCount; if (_filter.isEmpty()) { - if (!_chatsIndexed->isEmpty()) { + if (!_chatsIndexed->empty()) { auto i = _chatsIndexed->cfind(indexFrom, 1); for (auto end = _chatsIndexed->cend(); i != end; ++i) { if (indexFrom >= indexTo) { @@ -949,10 +949,10 @@ void ShareBox::Inner::updateFilter(QString filter) { _filtered.clear(); if (!words.isEmpty()) { const Dialogs::List *toFilter = nullptr; - if (!_chatsIndexed->isEmpty()) { + if (!_chatsIndexed->empty()) { for (fi = fb; fi != fe; ++fi) { - auto found = _chatsIndexed->filtered(fi->at(0)); - if (found->empty()) { + const auto found = _chatsIndexed->filtered(fi->at(0)); + if (!found || found->empty()) { toFilter = nullptr; break; } diff --git a/Telegram/SourceFiles/data/data_folder.cpp b/Telegram/SourceFiles/data/data_folder.cpp index 694097424..451f51bda 100644 --- a/Telegram/SourceFiles/data/data_folder.cpp +++ b/Telegram/SourceFiles/data/data_folder.cpp @@ -33,21 +33,13 @@ namespace Data { //} Folder::Folder(not_null owner, FolderId id) -: Entry(this) +: Entry(owner, this) , _id(id) -, _owner(owner) +, _chatsList(Dialogs::SortMode::Date) , _name(lang(lng_archived_chats)) { indexNameParts(); } -Data::Session &Folder::owner() const { - return *_owner; -} - -AuthSession &Folder::session() const { - return _owner->session(); -} - FolderId Folder::id() const { return _id; } @@ -79,11 +71,11 @@ void Folder::indexNameParts() { } void Folder::registerOne(not_null history) { - if (base::contains(_histories, history)) { + if (_chatsList.contains(history)) { return; } - const auto invisible = empty(_histories); - _histories.push_back(history); + const auto invisible = _chatsList.empty(); + _chatsList.addToEnd(history); //session().storage().invalidate( // #feed // Storage::FeedMessagesInvalidate(_id)); @@ -109,24 +101,22 @@ void Folder::registerOne(not_null history) { session().api().requestDialogEntry(this); } } - if (invisible && !empty(_histories)) { + if (invisible && !_chatsList.empty()) { updateChatListExistence(); - for (const auto history : _histories) { - history->updateChatListExistence(); - } + //for (const auto history : _histories) { // #TODO archived + // history->updateChatListExistence(); + //} } else { history->updateChatListExistence(); } - _owner->notifyFolderUpdated(this, FolderUpdateFlag::List); + owner().notifyFolderUpdated(this, FolderUpdateFlag::List); } void Folder::unregisterOne(not_null history) { - const auto i = ranges::remove(_histories, history); - if (i == end(_histories)) { + if (!_chatsList.contains(history)) { return; } - const auto visible = !empty(_histories); - _histories.erase(i, end(_histories)); + _chatsList.del(history); //session().storage().remove( // #feed // Storage::FeedMessagesRemoveAll(_id, channel->bareId())); @@ -146,15 +136,19 @@ void Folder::unregisterOne(not_null history) { session().api().requestDialogEntry(this); } } - if (visible && empty(_histories)) { + if (_chatsList.empty()) { updateChatListExistence(); - for (const auto history : _histories) { - history->updateChatListExistence(); - } + //for (const auto history : _histories) { // #TODO archive + // history->updateChatListExistence(); + //} } else { history->updateChatListExistence(); } - _owner->notifyFolderUpdated(this, FolderUpdateFlag::List); + owner().notifyFolderUpdated(this, FolderUpdateFlag::List); +} + +not_null Folder::chatsList() { + return &_chatsList; } void Folder::updateChatListMessage(not_null item) { @@ -202,10 +196,6 @@ void Folder::paintUserpic( //} } -const std::vector> &Folder::histories() const { - return _histories; -} - bool Folder::historiesLoaded() const { return _historiesLoaded; } @@ -213,7 +203,7 @@ bool Folder::historiesLoaded() const { void Folder::setHistoriesLoaded(bool loaded) { if (_historiesLoaded != loaded) { _historiesLoaded = loaded; - _owner->notifyFolderUpdated(this, FolderUpdateFlag::List); + owner().notifyFolderUpdated(this, FolderUpdateFlag::List); } } // // #feed @@ -306,8 +296,8 @@ void Folder::requestChatListMessage() { void Folder::recountChatListMessage() { _chatListMessage = std::nullopt; - for (const auto history : _histories) { - if (!history->chatListMessageKnown()) { + for (const auto entry : _chatsList) { + if (entry->history() && !entry->history()->chatListMessageKnown()) { requestChatListMessage(); return; } @@ -317,9 +307,11 @@ void Folder::recountChatListMessage() { void Folder::setChatListMessageFromChannels() { _chatListMessage = nullptr; - for (const auto history : _histories) { - if (const auto last = history->chatListMessage()) { - justUpdateChatListMessage(last); + for (const auto entry : _chatsList) { + if (entry->history()) { + if (const auto last = entry->history()->chatListMessage()) { + justUpdateChatListMessage(last); + } } } updateChatListDate(); @@ -386,15 +378,15 @@ void Folder::changedInChatListHook(Dialogs::Mode list, bool added) { const auto nonMutedCount = count - mutedCount; const auto mutedDelta = added ? mutedCount : -mutedCount; const auto nonMutedDelta = added ? nonMutedCount : -nonMutedCount; - Auth().data().unreadIncrement(nonMutedDelta, false); - Auth().data().unreadIncrement(mutedDelta, true); + owner().unreadIncrement(nonMutedDelta, false); + owner().unreadIncrement(mutedDelta, true); const auto fullMuted = (nonMutedCount == 0); const auto entriesWithUnreadDelta = added ? 1 : -1; const auto mutedEntriesWithUnreadDelta = fullMuted ? entriesWithUnreadDelta : 0; - Auth().data().unreadEntriesChanged( + owner().unreadEntriesChanged( entriesWithUnreadDelta, mutedEntriesWithUnreadDelta); } @@ -419,11 +411,11 @@ void Folder::updateUnreadCounts(PerformUpdate &&performUpdate) { const auto nowFullMuted = (nowUnreadMutedCount > 0) && (nowUnreadCount == nowUnreadMutedCount); - Auth().data().unreadIncrement( + owner().unreadIncrement( (nowUnreadCount - nowUnreadMutedCount) - (wasUnreadCount - wasUnreadMutedCount), false); - Auth().data().unreadIncrement( + owner().unreadIncrement( nowUnreadMutedCount - wasUnreadMutedCount, true); @@ -437,7 +429,7 @@ void Folder::updateUnreadCounts(PerformUpdate &&performUpdate) { : (wasFullMuted && !nowFullMuted) ? -1 : 0; - Auth().data().unreadEntriesChanged( + owner().unreadEntriesChanged( entriesDelta, mutedEntriesDelta); } @@ -483,8 +475,8 @@ void Folder::unreadCountChanged(int unreadCountDelta, int mutedCountDelta) { // if (!_unreadCount || !*_unreadCount) { // if (inChatList(Dialogs::Mode::All)) { // const auto delta = _unreadMark ? 1 : -1; -// _owner->unreadIncrement(delta, mute()); -// _owner->unreadEntriesChanged( +// owner().unreadIncrement(delta, mute()); +// owner().unreadEntriesChanged( // delta, // mute() ? delta : 0); // @@ -518,7 +510,7 @@ bool Folder::useProxyPromotion() const { } bool Folder::shouldBeInChatList() const { - return !empty(_histories); + return !_chatsList.empty(); } int Folder::chatListUnreadCount() const { diff --git a/Telegram/SourceFiles/data/data_folder.h b/Telegram/SourceFiles/data/data_folder.h index 924ae8347..d13ceea35 100644 --- a/Telegram/SourceFiles/data/data_folder.h +++ b/Telegram/SourceFiles/data/data_folder.h @@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #pragma once #include "dialogs/dialogs_entry.h" +#include "dialogs/dialogs_indexed_list.h" #include "data/data_messages.h" class ChannelData; @@ -37,13 +38,12 @@ public: Folder(const Folder &) = delete; Folder &operator=(const Folder &) = delete; - Data::Session &owner() const; - AuthSession &session() const; - FolderId id() const; void registerOne(not_null history); void unregisterOne(not_null history); + not_null chatsList(); + void updateChatListMessage(not_null item); void messageRemoved(not_null item); void historyCleared(not_null history); @@ -86,7 +86,6 @@ public: int y, int size) const override; - const std::vector> &histories() const; bool historiesLoaded() const; void setHistoriesLoaded(bool loaded); //int32 chatsHash() const; @@ -98,16 +97,15 @@ private: void setChatListMessageFromChannels(); bool justUpdateChatListMessage(not_null item); void updateChatListDate(); - void changeChatsList( - const std::vector> &add, - const std::vector> &remove); + //void changeChatsList( + // const std::vector> &add, + // const std::vector> &remove); template void updateUnreadCounts(PerformUpdate &&performUpdate); FolderId _id = 0; - not_null _owner; - std::vector> _histories; + Dialogs::IndexedList _chatsList; bool _settingHistories = false; bool _historiesLoaded = false; diff --git a/Telegram/SourceFiles/data/data_session.cpp b/Telegram/SourceFiles/data/data_session.cpp index 0072fdd6d..8a35539f4 100644 --- a/Telegram/SourceFiles/data/data_session.cpp +++ b/Telegram/SourceFiles/data/data_session.cpp @@ -150,6 +150,10 @@ Session::Session(not_null session) , _bigFileCache(Core::App().databases().get( Local::cacheBigFilePath(), Local::cacheBigFileSettings())) +, _chatsList(Dialogs::SortMode::Date) +, _importantChatsList(Dialogs::SortMode::Date) +, _contactsList(Dialogs::SortMode::Name) +, _contactsNoChatsList(Dialogs::SortMode::Name) , _selfDestructTimer([=] { checkSelfDestructItems(); }) , _sendActionsAnimation([=](crl::time now) { return sendActionsAnimationCallback(now); @@ -161,6 +165,8 @@ Session::Session(not_null session) setupContactViewsViewer(); setupChannelLeavingViewer(); + setupPeerNameViewer(); + setupUserIsContactViewer(); } void Session::clear() { @@ -919,6 +925,49 @@ void Session::setupChannelLeavingViewer() { }, _lifetime); } +void Session::setupPeerNameViewer() { + Notify::PeerUpdateViewer( + Notify::PeerUpdate::Flag::NameChanged + ) | rpl::start_with_next([=](const Notify::PeerUpdate &update) { + const auto peer = update.peer; + const auto &oldLetters = update.oldNameFirstLetters; + _chatsList.peerNameChanged(Dialogs::Mode::All, peer, oldLetters); + if (Global::DialogsModeEnabled()) { + _importantChatsList.peerNameChanged( + Dialogs::Mode::Important, + peer, + oldLetters); + } + _contactsNoChatsList.peerNameChanged(peer, oldLetters); + _contactsList.peerNameChanged(peer, oldLetters); + }, _lifetime); +} + +void Session::setupUserIsContactViewer() { + Notify::PeerUpdateViewer( + Notify::PeerUpdate::Flag::UserIsContact + ) | rpl::filter([=](const Notify::PeerUpdate &update) { + return update.peer->isUser(); + }) | rpl::start_with_next([=](const Notify::PeerUpdate &update) { + const auto user = update.peer->asUser(); + if (user->loadedStatus != PeerData::FullLoaded) { + LOG(("API Error: " + "userIsContactChanged() called for a not loaded user!")); + return; + } + if (user->contactStatus() == UserData::ContactStatus::Contact) { + const auto history = user->owner().history(user->id); + _contactsList.addByName(history); + if (!_chatsList.contains(history)) { + _contactsNoChatsList.addByName(history); + } + } else if (const auto history = user->owner().historyLoaded(user)) { + _contactsNoChatsList.del(history); + _contactsList.del(history); + } + }, _lifetime); +} + Session::~Session() { // Optimization: clear notifications before destroying items. _session->notifications().clearAllFast(); @@ -2829,6 +2878,79 @@ not_null Session::processFolder(const MTPDfolder &data) { // return _defaultFeedId.value(); //} +not_null Session::chatsList() { + return &_chatsList; +} + +not_null Session::importantChatsList() { + return &_importantChatsList; +} + +not_null Session::contactsList() { + return &_contactsList; +} + +not_null Session::contactsNoChatsList() { + return &_contactsNoChatsList; +} + +auto Session::refreshChatListEntry(Dialogs::Key key) +-> RefreshChatListEntryResult { + using namespace Dialogs; + + const auto entry = key.entry(); + auto result = RefreshChatListEntryResult(); + result.changed = !entry->inChatList(Mode::All); + if (result.changed) { + const auto mainRow = entry->addToChatList(Mode::All, &_chatsList); + _contactsNoChatsList.del(key, mainRow); + } else { + result.moved = entry->adjustByPosInChatList( + Mode::All, + &_chatsList); + } + if (Global::DialogsModeEnabled()) { + if (entry->toImportant()) { + result.importantChanged = !entry->inChatList(Mode::Important); + if (result.importantChanged) { + entry->addToChatList(Mode::Important, &_importantChatsList); + } else { + result.importantMoved = entry->adjustByPosInChatList( + Mode::Important, + &_importantChatsList); + } + } else if (entry->inChatList(Mode::Important)) { + entry->removeFromChatList(Mode::Important, &_importantChatsList); + result.importantChanged = true; + } + } + return result; +} + +void Session::removeChatListEntry(Dialogs::Key key) { + using namespace Dialogs; + + const auto entry = key.entry(); + entry->removeFromChatList(Mode::All, &_chatsList); + if (Global::DialogsModeEnabled()) { + entry->removeFromChatList(Mode::Important, &_importantChatsList); + } + if (_contactsList.contains(key)) { + if (!_contactsNoChatsList.contains(key)) { + _contactsNoChatsList.addByName(key); + } + } +} + +void Session::dialogsRowReplaced(DialogsRowReplacement replacement) { + _dialogsRowReplacements.fire(std::move(replacement)); +} + +auto Session::dialogsRowReplacements() const +-> rpl::producer { + return _dialogsRowReplacements.events(); +} + void Session::requestNotifySettings(not_null peer) { if (peer->notifySettingsUnknown()) { _session->api().requestNotifySettings( diff --git a/Telegram/SourceFiles/data/data_session.h b/Telegram/SourceFiles/data/data_session.h index c3d159b4a..c2899254a 100644 --- a/Telegram/SourceFiles/data/data_session.h +++ b/Telegram/SourceFiles/data/data_session.h @@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "storage/storage_databases.h" #include "chat_helpers/stickers.h" #include "dialogs/dialogs_key.h" +#include "dialogs/dialogs_indexed_list.h" #include "data/data_groups.h" #include "data/data_notify_settings.h" #include "history/history_location_manager.h" @@ -508,6 +509,27 @@ public: //FeedId defaultFeedId() const; //rpl::producer defaultFeedIdValue() const; + not_null chatsList(); + not_null importantChatsList(); + not_null contactsList(); + not_null contactsNoChatsList(); + + struct RefreshChatListEntryResult { + bool changed = false; + bool importantChanged = false; + Dialogs::PositionChange moved; + Dialogs::PositionChange importantMoved; + }; + RefreshChatListEntryResult refreshChatListEntry(Dialogs::Key key); + void removeChatListEntry(Dialogs::Key key); + + struct DialogsRowReplacement { + not_null old; + Dialogs::Row *now = nullptr; + }; + void dialogsRowReplaced(DialogsRowReplacement replacement); + rpl::producer dialogsRowReplacements() const; + void requestNotifySettings(not_null peer); void applyNotifySetting( const MTPNotifyPeer ¬ifyPeer, @@ -560,6 +582,8 @@ private: void setupContactViewsViewer(); void setupChannelLeavingViewer(); + void setupPeerNameViewer(); + void setupUserIsContactViewer(); void checkSelfDestructItems(); int computeUnreadBadge( @@ -715,6 +739,7 @@ private: rpl::event_stream _megagroupParticipantRemoved; rpl::event_stream _megagroupParticipantAdded; rpl::event_stream _folderUpdates; + rpl::event_stream _dialogsRowReplacements; rpl::event_stream<> _stickersUpdated; rpl::event_stream<> _savedGifsUpdated; @@ -735,6 +760,11 @@ private: int _unreadEntriesFull = 0; int _unreadEntriesMuted = 0; + Dialogs::IndexedList _chatsList; + Dialogs::IndexedList _importantChatsList; + Dialogs::IndexedList _contactsList; + Dialogs::IndexedList _contactsNoChatsList; + base::Timer _selfDestructTimer; std::vector _selfDestructItems; diff --git a/Telegram/SourceFiles/dialogs/dialogs_entry.cpp b/Telegram/SourceFiles/dialogs/dialogs_entry.cpp index 5903c3f6f..c5d865033 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_entry.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_entry.cpp @@ -9,11 +9,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "dialogs/dialogs_key.h" #include "dialogs/dialogs_indexed_list.h" +#include "data/data_session.h" #include "mainwidget.h" #include "auth_session.h" -#include "styles/style_dialogs.h" #include "history/history_item.h" #include "history/history.h" +#include "styles/style_dialogs.h" // st::dialogsTextWidthMin namespace Dialogs { namespace { @@ -37,11 +38,20 @@ uint64 PinnedDialogPos(int pinnedIndex) { } // namespace -Entry::Entry(const Key &key) +Entry::Entry(not_null owner, const Key &key) : lastItemTextCache(st::dialogsTextWidthMin) +, _owner(owner) , _key(key) { } +Data::Session &Entry::owner() const { + return *_owner; +} + +AuthSession &Entry::session() const { + return _owner->session(); +} + void Entry::cachePinnedIndex(int index) { if (_pinnedIndex != index) { const auto wasPinned = isPinnedDialog(); @@ -93,7 +103,7 @@ void Entry::updateChatListExistence() { void Entry::setChatListExistence(bool exists) { if (const auto main = App::main()) { if (exists && _sortKeyInChatList) { - main->createDialog(_key); + main->refreshDialog(_key); updateChatListEntry(); } else { main->removeDialog(_key); @@ -129,10 +139,10 @@ PositionChange Entry::adjustByPosInChatList( Mode list, not_null indexed) { const auto lnk = mainChatListLink(list); - const auto movedFrom = lnk->pos(); + const auto from = lnk->pos(); indexed->adjustByDate(chatListLinks(list)); - const auto movedTo = lnk->pos(); - return { movedFrom, movedTo }; + const auto to = lnk->pos(); + return { from, to }; } void Entry::setChatListTimeId(TimeId date) { diff --git a/Telegram/SourceFiles/dialogs/dialogs_entry.h b/Telegram/SourceFiles/dialogs/dialogs_entry.h index 6804a2d0b..a73cd9d25 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_entry.h +++ b/Telegram/SourceFiles/dialogs/dialogs_entry.h @@ -11,6 +11,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "dialogs/dialogs_key.h" +class AuthSession; + +namespace Data { +class Session; +} // namespace Data + namespace Dialogs { class Row; @@ -29,17 +35,20 @@ enum class Mode { }; struct PositionChange { - int movedFrom; - int movedTo; + int from = -1; + int to = -1; }; class Entry { public: - Entry(const Key &key); + Entry(not_null owner, const Key &key); Entry(const Entry &other) = delete; Entry &operator=(const Entry &other) = delete; virtual ~Entry() = default; + Data::Session &owner() const; + AuthSession &session() const; + PositionChange adjustByPosInChatList( Mode list, not_null indexed); @@ -116,6 +125,7 @@ private: const RowsByLetter &chatListLinks(Mode list) const; Row *mainChatListLink(Mode list) const; + not_null _owner; Dialogs::Key _key; RowsByLetter _chatListLinks[2]; uint64 _sortKeyInChatList = 0; diff --git a/Telegram/SourceFiles/dialogs/dialogs_indexed_list.cpp b/Telegram/SourceFiles/dialogs/dialogs_indexed_list.cpp index f75ba99d6..2d284f7ab 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_indexed_list.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_indexed_list.cpp @@ -26,11 +26,9 @@ RowsByLetter IndexedList::addToEnd(Key key) { for (const auto ch : key.entry()->chatListFirstLetters()) { auto j = _index.find(ch); if (j == _index.cend()) { - j = _index.emplace( - ch, - std::make_unique(_sortMode)).first; + j = _index.emplace(ch, _sortMode).first; } - result.emplace(ch, j->second->addToEnd(key)); + result.emplace(ch, j->second.addToEnd(key)); } } return result; @@ -45,11 +43,9 @@ Row *IndexedList::addByName(Key key) { for (const auto ch : key.entry()->chatListFirstLetters()) { auto j = _index.find(ch); if (j == _index.cend()) { - j = _index.emplace( - ch, - std::make_unique(_sortMode)).first; + j = _index.emplace(ch, _sortMode).first; } - j->second->addByName(key); + j->second.addByName(key); } return result; } @@ -60,7 +56,7 @@ void IndexedList::adjustByDate(const RowsByLetter &links) { _list.adjustByDate(row); } else { if (auto it = _index.find(ch); it != _index.cend()) { - it->second->adjustByDate(row); + it->second.adjustByDate(row); } } } @@ -70,7 +66,7 @@ void IndexedList::moveToTop(Key key) { if (_list.moveToTop(key)) { for (const auto ch : key.entry()->chatListFirstLetters()) { if (auto it = _index.find(ch); it != _index.cend()) { - it->second->moveToTop(key); + it->second.moveToTop(key); } } } @@ -132,24 +128,22 @@ void IndexedList::adjustByName( } else { toRemove.erase(j); if (auto it = _index.find(ch); it != _index.cend()) { - it->second->adjustByName(key); + it->second.adjustByName(key); } } } for (auto ch : toRemove) { if (auto it = _index.find(ch); it != _index.cend()) { - it->second->del(key, mainRow); + it->second.del(key, mainRow); } } if (!toAdd.empty()) { for (auto ch : toAdd) { auto j = _index.find(ch); if (j == _index.cend()) { - j = _index.emplace( - ch, - std::make_unique(_sortMode)).first; + j = _index.emplace(ch, _sortMode).first; } - j->second->addByName(key); + j->second.addByName(key); } } } @@ -177,17 +171,15 @@ void IndexedList::adjustNames( history->removeChatListEntryByLetter(list, ch); } if (auto it = _index.find(ch); it != _index.cend()) { - it->second->del(key, mainRow); + it->second.del(key, mainRow); } } for (auto ch : toAdd) { auto j = _index.find(ch); if (j == _index.cend()) { - j = _index.emplace( - ch, - std::make_unique(_sortMode)).first; + j = _index.emplace(ch, _sortMode).first; } - auto row = j->second->addToEnd(key); + auto row = j->second.addToEnd(key); if (_sortMode == SortMode::Date) { history->addChatListEntryByLetter(list, ch, row); } @@ -198,7 +190,7 @@ void IndexedList::del(Key key, Row *replacedBy) { if (_list.del(key, replacedBy)) { for (const auto ch : key.entry()->chatListFirstLetters()) { if (auto it = _index.find(ch); it != _index.cend()) { - it->second->del(key, replacedBy); + it->second.del(key, replacedBy); } } } diff --git a/Telegram/SourceFiles/dialogs/dialogs_indexed_list.h b/Telegram/SourceFiles/dialogs/dialogs_indexed_list.h index ec98bc8a6..e19214b2f 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_indexed_list.h +++ b/Telegram/SourceFiles/dialogs/dialogs_indexed_list.h @@ -44,17 +44,15 @@ public: return _list; } const List *filtered(QChar ch) const { - if (auto it = _index.find(ch); it != _index.cend()) { - return it->second.get(); - } - return &_empty; + const auto i = _index.find(ch); + return (i != _index.end()) ? &i->second : nullptr; } ~IndexedList(); // Part of List interface is duplicated here for all() list. int size() const { return all().size(); } - bool isEmpty() const { return all().empty(); } + bool empty() const { return all().empty(); } bool contains(Key key) const { return all().contains(key); } Row *getRow(Key key) const { return all().getRow(key); } Row *rowAtY(int32 y, int32 h) const { return all().rowAtY(y, h); } @@ -83,9 +81,9 @@ private: not_null history, const base::flat_set &oldChars); - SortMode _sortMode; + SortMode _sortMode = SortMode(); List _list, _empty; - base::flat_map> _index; + base::flat_map _index; }; diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp index 662f60eda..f9ced180e 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp @@ -66,12 +66,9 @@ struct DialogsInner::PeerSearchResult { Dialogs::RippleRow row; }; -DialogsInner::DialogsInner(QWidget *parent, not_null controller, QWidget *main) +DialogsInner::DialogsInner(QWidget *parent, not_null controller) : RpWidget(parent) , _controller(controller) -, _dialogs(std::make_unique(Dialogs::SortMode::Date)) -, _contactsNoDialogs(std::make_unique(Dialogs::SortMode::Name)) -, _contacts(std::make_unique(Dialogs::SortMode::Name)) , _pinnedShiftAnimation([=](crl::time now) { return pinnedShiftAnimationCallback(now); }) @@ -84,25 +81,28 @@ DialogsInner::DialogsInner(QWidget *parent, not_null contro #endif // OS_MAC_OLD if (Global::DialogsModeEnabled()) { - _dialogsImportant = std::make_unique(Dialogs::SortMode::Date); _importantSwitch = std::make_unique(); } - connect(main, SIGNAL(dialogRowReplaced(Dialogs::Row*, Dialogs::Row*)), this, SLOT(onDialogRowReplaced(Dialogs::Row*, Dialogs::Row*))); connect(_addContactLnk, SIGNAL(clicked()), App::wnd(), SLOT(onShowAddContact())); _cancelSearchInChat->setClickedCallback([this] { cancelSearchInChat(); }); _cancelSearchInChat->hide(); _cancelSearchFromUser->setClickedCallback([this] { searchFromUserChanged.notify(nullptr); }); _cancelSearchFromUser->hide(); - subscribe(Auth().downloaderTaskFinished(), [this] { update(); }); - subscribe(Auth().data().contactsLoaded(), [this](bool) { refresh(); }); + subscribe(session().downloaderTaskFinished(), [this] { update(); }); + subscribe(session().data().contactsLoaded(), [this](bool) { refresh(); }); - Auth().data().itemRemoved( - ) | rpl::start_with_next( - [this](auto item) { itemRemoved(item); }, - lifetime()); + session().data().itemRemoved( + ) | rpl::start_with_next([=](not_null item) { + itemRemoved(item); + }, lifetime()); - Auth().data().itemRepaintRequest( + session().data().dialogsRowReplacements( + ) | rpl::start_with_next([=](Data::Session::DialogsRowReplacement r) { + dialogRowReplaced(r.old, r.now); + }, lifetime()); + + session().data().itemRepaintRequest( ) | rpl::start_with_next([=](auto item) { const auto history = item->history(); if (history->textCachedFor == item) { @@ -115,7 +115,7 @@ DialogsInner::DialogsInner(QWidget *parent, not_null contro } }, lifetime()); - Auth().data().sendActionAnimationUpdated( + session().data().sendActionAnimationUpdated( ) | rpl::start_with_next([=]( const Data::Session::SendActionAnimationUpdate &update) { using RowPainter = Dialogs::Layout::RowPainter; @@ -148,15 +148,16 @@ DialogsInner::DialogsInner(QWidget *parent, not_null contro stopReorderPinned(); } if (update.flags & UpdateFlag::NameChanged) { - handlePeerNameChange(update.peer, update.oldNameFirstLetters); + this->update(); } if (update.flags & (UpdateFlag::PhotoChanged | UpdateFlag::UserOccupiedChanged)) { this->update(); emit App::main()->dialogsUpdated(); } if (update.flags & UpdateFlag::UserIsContact) { - if (const auto user = update.peer->asUser()) { - userIsContactUpdated(user); + if (update.peer->isUser()) { + // contactsNoChatsList could've changed. + Ui::PostponeCall(this, [=] { refresh(); }); } } if (update.flags & UpdateFlag::MigrationChanged) { @@ -165,7 +166,7 @@ DialogsInner::DialogsInner(QWidget *parent, not_null contro } } })); - Auth().data().folderUpdated( + session().data().folderUpdated( ) | rpl::start_with_next([=](const Data::FolderUpdate &update) { updateDialogRow({ update.folder, FullMsgId() }); }, lifetime()); @@ -183,6 +184,10 @@ DialogsInner::DialogsInner(QWidget *parent, not_null contro setupShortcuts(); } +AuthSession &DialogsInner::session() const { + return _controller->session(); +} + void DialogsInner::handleChatMigration(not_null chat) { const auto channel = chat->migrateTo(); if (!channel) { @@ -200,7 +205,7 @@ void DialogsInner::handleChatMigration(not_null chat) { } int DialogsInner::dialogsOffset() const { - return _dialogsImportant ? st::dialogsImportantBarHeight : 0; + return _importantSwitch ? st::dialogsImportantBarHeight : 0; } int DialogsInner::proxyPromotedCount() const { @@ -256,7 +261,7 @@ void DialogsInner::paintEvent(QPaintEvent *e) { if (_state == State::Default) { auto rows = shownDialogs(); auto dialogsClip = r; - if (_dialogsImportant) { + if (_importantSwitch) { auto selected = isPressed() ? _importantSwitchPressed : _importantSwitchSelected; Dialogs::Layout::paintImportantSwitch(p, Global::DialogsMode(), fullWidth, selected); dialogsClip.translate(0, -st::dialogsImportantBarHeight); @@ -347,7 +352,7 @@ void DialogsInner::paintEvent(QPaintEvent *e) { p.fillRect(dialogsClip, st::dialogsBg); p.setFont(st::noContactsFont); p.setPen(st::noContactsColor); - p.drawText(QRect(0, 0, fullWidth, st::noContactsHeight - (Auth().data().contactsLoaded().value() ? st::noContactsFont->height : 0)), lang(Auth().data().contactsLoaded().value() ? lng_no_chats : lng_contacts_loading), style::al_center); + p.drawText(QRect(0, 0, fullWidth, st::noContactsHeight - (session().data().contactsLoaded().value() ? st::noContactsFont->height : 0)), lang(session().data().contactsLoaded().value() ? lng_no_chats : lng_contacts_loading), style::al_center); } } else if (_state == State::Filtered) { if (!_hashtagResults.empty()) { @@ -741,7 +746,7 @@ void DialogsInner::selectByMouse(QPoint globalPosition) { int w = width(), mouseY = local.y(); clearIrrelevantState(); if (_state == State::Default) { - auto importantSwitchSelected = (_dialogsImportant && mouseY >= 0 && mouseY < dialogsOffset()); + auto importantSwitchSelected = (_importantSwitch && mouseY >= 0 && mouseY < dialogsOffset()); mouseY -= dialogsOffset(); auto selected = importantSwitchSelected ? nullptr : shownDialogs()->rowAtY(mouseY, st::dialogsRowHeight); if (_selected != selected || _importantSwitchSelected != importantSwitchSelected) { @@ -872,7 +877,7 @@ void DialogsInner::checkReorderPinnedStart(QPoint localPosition) { if (updateReorderIndexGetCount() < 2) { _dragging = nullptr; } else { - _pinnedOrder = Auth().data().pinnedDialogsOrder(); + _pinnedOrder = session().data().pinnedDialogsOrder(); _pinnedRows[_draggingIndex].yadd = anim::value(0, localPosition.y() - _dragStart.y()); _pinnedRows[_draggingIndex].animStartTime = crl::now(); _pinnedShiftAnimation.start(); @@ -913,7 +918,7 @@ int DialogsInner::countPinnedIndex(Dialogs::Row *ofRow) { } void DialogsInner::savePinnedOrder() { - const auto &newOrder = Auth().data().pinnedDialogsOrder(); + const auto &newOrder = session().data().pinnedDialogsOrder(); if (newOrder.size() != _pinnedOrder.size()) { return; // Something has changed in the set of pinned chats. } @@ -922,7 +927,7 @@ void DialogsInner::savePinnedOrder() { return; // Something has changed in the set of pinned chats. } } - Auth().api().savePinnedOrder(); + session().api().savePinnedOrder(); } void DialogsInner::finishReorderPinned() { @@ -1187,7 +1192,7 @@ void DialogsInner::resizeEvent(QResizeEvent *e) { _cancelSearchFromUser->moveToLeft(widthForCancelButton - st::dialogsSearchInSkip - _cancelSearchFromUser->width(), st::searchedBarHeight + st::dialogsSearchInHeight + st::lineWidth + (st::dialogsSearchInHeight - st::dialogsCancelSearchInPeer.height) / 2); } -void DialogsInner::onDialogRowReplaced( +void DialogsInner::dialogRowReplaced( Dialogs::Row *oldRow, Dialogs::Row *newRow) { if (_state == State::Filtered) { @@ -1219,66 +1224,41 @@ void DialogsInner::onDialogRowReplaced( } } -void DialogsInner::createDialog(Dialogs::Key key) { +void DialogsInner::refreshDialog(Dialogs::Key key) { if (const auto history = key.history()) { if (history->peer->loadedStatus != PeerData::LoadedStatus::FullLoaded) { LOG(("API Error: " - "DialogsInner::createDialog() called for a non loaded peer!" + "DialogsInner::refreshDialog() called for a non loaded peer!" )); return; } } - const auto entry = key.entry(); - auto creating = !entry->inChatList(Dialogs::Mode::All); - if (creating) { - const auto mainRow = entry->addToChatList( - Dialogs::Mode::All, - _dialogs.get()); - _contactsNoDialogs->del(key, mainRow); - } - if (_dialogsImportant - && !entry->inChatList(Dialogs::Mode::Important) - && entry->toImportant()) { - if (Global::DialogsMode() == Dialogs::Mode::Important) { - creating = true; - } - entry->addToChatList( - Dialogs::Mode::Important, - _dialogsImportant.get()); - } + const auto result = session().data().refreshChatListEntry(key); + const auto changed = (Global::DialogsMode() == Dialogs::Mode::Important) + ? result.importantChanged + : result.changed; + const auto moved = (Global::DialogsMode() == Dialogs::Mode::Important) + ? result.importantMoved + : result.moved; - auto changed = entry->adjustByPosInChatList( - Dialogs::Mode::All, - _dialogs.get()); - - if (_dialogsImportant) { - if (!entry->toImportant()) { - if (Global::DialogsMode() == Dialogs::Mode::Important) { - return; - } - } else { - const auto importantChanged = entry->adjustByPosInChatList( - Dialogs::Mode::Important, - _dialogsImportant.get()); - if (Global::DialogsMode() == Dialogs::Mode::Important) { - changed = importantChanged; - } - } - } - - const auto from = dialogsOffset() + changed.movedFrom * st::dialogsRowHeight; - const auto to = dialogsOffset() + changed.movedTo * st::dialogsRowHeight; + const auto rowHeight = st::dialogsRowHeight; + const auto from = dialogsOffset() + moved.from * rowHeight; + const auto to = dialogsOffset() + moved.to * rowHeight; if (!_dragging && from != to) { // Don't jump in chats list scroll position while dragging. emit dialogMoved(from, to); } - if (creating) { + if (changed) { refresh(); } else if (_state == State::Default && from != to) { - update(0, qMin(from, to), width(), qAbs(from - to) + st::dialogsRowHeight); + update( + 0, + std::min(from, to), + width(), + std::abs(from - to) + rowHeight); } } @@ -1292,24 +1272,11 @@ void DialogsInner::removeDialog(Dialogs::Key key) { if (_pressed && _pressed->key() == key) { setPressed(nullptr); } - const auto entry = key.entry(); - entry->removeFromChatList( - Dialogs::Mode::All, - _dialogs.get()); - if (_dialogsImportant) { - entry->removeFromChatList( - Dialogs::Mode::Important, - _dialogsImportant.get()); - } + session().data().removeChatListEntry(key); if (const auto history = key.history()) { - Auth().notifications().clearFromHistory(history); + session().notifications().clearFromHistory(history); Local::removeSavedPeer(history->peer); } - if (_contacts->contains(key)) { - if (!_contactsNoDialogs->contains(key)) { - _contactsNoDialogs->addByName(key); - } - } const auto i = ranges::find(_filterResults, key, &Dialogs::Row::key); if (i != _filterResults.end()) { if (_filteredSelected == (i - _filterResults.begin()) @@ -1495,8 +1462,8 @@ void DialogsInner::updateSelectedRow(Dialogs::Key key) { Dialogs::IndexedList *DialogsInner::shownDialogs() const { return (Global::DialogsMode() == Dialogs::Mode::Important) - ? _dialogsImportant.get() - : _dialogs.get(); + ? session().data().importantChatsList() + : session().data().chatsList(); } void DialogsInner::leaveEventHook(QEvent *e) { @@ -1527,11 +1494,11 @@ void DialogsInner::clearSelection() { } void DialogsInner::fillSupportSearchMenu(not_null menu) { - const auto all = Auth().settings().supportAllSearchResults(); + const auto all = session().settings().supportAllSearchResults(); const auto text = all ? "Only one from chat" : "Show all messages"; menu->addAction(text, [=] { - Auth().settings().setSupportAllSearchResults(!all); - Auth().saveSettingsDelayed(); + session().settings().setSupportAllSearchResults(!all); + session().saveSettingsDelayed(); }); } @@ -1550,7 +1517,7 @@ void DialogsInner::contextMenuEvent(QContextMenuEvent *e) { } else if (_state == State::Filtered) { if (base::in_range(_filteredSelected, 0, _filterResults.size())) { return { _filterResults[_filteredSelected]->key(), FullMsgId() }; - } else if (Auth().supportMode() + } else if (session().supportMode() && base::in_range(_searchedSelected, 0, _searchResults.size())) { return { _searchResults[_searchedSelected]->item()->history(), @@ -1568,7 +1535,7 @@ void DialogsInner::contextMenuEvent(QContextMenuEvent *e) { } _menu = base::make_unique_q(this); - if (Auth().supportMode() && row.fullId) { + if (session().supportMode() && row.fullId) { fillSupportSearchMenu(_menu.get()); } else if (const auto history = row.key.history()) { Window::FillPeerMenu( @@ -1611,21 +1578,6 @@ void DialogsInner::onParentGeometryChanged() { } } -void DialogsInner::handlePeerNameChange( - not_null peer, - const base::flat_set &oldLetters) { - _dialogs->peerNameChanged(Dialogs::Mode::All, peer, oldLetters); - if (_dialogsImportant) { - _dialogsImportant->peerNameChanged( - Dialogs::Mode::Important, - peer, - oldLetters); - } - _contactsNoDialogs->peerNameChanged(peer, oldLetters); - _contacts->peerNameChanged(peer, oldLetters); - update(); -} - void DialogsInner::applyFilterUpdate(QString newFilter, bool force) { const auto mentionsSearch = (newFilter == qstr("@")); const auto words = mentionsSearch @@ -1645,10 +1597,10 @@ void DialogsInner::applyFilterUpdate(QString newFilter, bool force) { _filterResultsGlobal.clear(); if (!_searchInChat && !words.isEmpty()) { const Dialogs::List *toFilter = nullptr; - if (!_dialogs->isEmpty()) { + if (const auto list = session().data().chatsList(); !list->empty()) { for (fi = fb; fi != fe; ++fi) { - auto found = _dialogs->filtered(fi->at(0)); - if (found->empty()) { + const auto found = list->filtered(fi->at(0)); + if (!found || found->empty()) { toFilter = nullptr; break; } @@ -1658,10 +1610,10 @@ void DialogsInner::applyFilterUpdate(QString newFilter, bool force) { } } const Dialogs::List *toFilterContacts = nullptr; - if (!_contactsNoDialogs->isEmpty()) { + if (const auto list = session().data().contactsNoChatsList(); !list->empty()) { for (fi = fb; fi != fe; ++fi) { - auto found = _contactsNoDialogs->filtered(fi->at(0)); - if (found->empty()) { + const auto found = list->filtered(fi->at(0)); + if (!found || found->empty()) { toFilterContacts = nullptr; break; } @@ -1843,7 +1795,7 @@ void DialogsInner::applyDialog(const MTPDdialog &dialog) { return; } - const auto history = Auth().data().history(peerId); + const auto history = session().data().history(peerId); history->applyDialog(dialog); if (!history->useProxyPromotion() && !history->isPinnedDialog()) { @@ -1852,7 +1804,6 @@ void DialogsInner::applyDialog(const MTPDdialog &dialog) { addSavedPeersAfter(ParseDateTime(date)); } } - _contactsNoDialogs->del(history); if (const auto from = history->peer->migrateFrom()) { if (const auto historyFrom = from->owner().historyLoaded(from)) { removeDialog(historyFrom); @@ -1865,7 +1816,7 @@ void DialogsInner::applyDialog(const MTPDdialog &dialog) { } void DialogsInner::applyFolderDialog(const MTPDdialogFolder &dialog) { - const auto folder = Auth().data().processFolder(dialog.vfolder); + const auto folder = session().data().processFolder(dialog.vfolder); folder->applyDialog(dialog); if (!folder->useProxyPromotion() && !folder->isPinnedDialog()) { @@ -1883,9 +1834,8 @@ void DialogsInner::addSavedPeersAfter(const QDateTime &date) { const auto lastPeer = saved.last(); saved.remove(lastDate, lastPeer); - const auto history = Auth().data().history(lastPeer); + const auto history = session().data().history(lastPeer); history->setChatListTimeId(ServerTimeFromParsed(lastDate)); - _contactsNoDialogs->del(history); } } @@ -1894,8 +1844,8 @@ void DialogsInner::addAllSavedPeers() { } bool DialogsInner::uniqueSearchResults() const { - return Auth().supportMode() - && !Auth().settings().supportAllSearchResults() + return session().supportMode() + && !session().settings().supportAllSearchResults() && !_searchInChat; } @@ -1944,9 +1894,9 @@ bool DialogsInner::searchReceived( auto msgId = IdFromMessage(message); auto peerId = PeerFromMessage(message); auto lastDate = DateFromMessage(message); - if (const auto peer = Auth().data().peerLoaded(peerId)) { + if (const auto peer = session().data().peerLoaded(peerId)) { if (lastDate) { - const auto item = Auth().data().addNewMessage( + const auto item = session().data().addNewMessage( message, NewMessageExisting); const auto history = item->history(); @@ -2015,8 +1965,8 @@ void DialogsInner::peerSearchReceived( _peerSearchQuery = query.toLower().trimmed(); _peerSearchResults.clear(); _peerSearchResults.reserve(result.size()); - for (const auto &mtpPeer : my) { - if (const auto peer = Auth().data().peerLoaded(peerFromMTP(mtpPeer))) { + for (const auto &mtpPeer : my) { + if (const auto peer = session().data().peerLoaded(peerFromMTP(mtpPeer))) { if (alreadyAdded(peer)) { continue; } @@ -2034,7 +1984,7 @@ void DialogsInner::peerSearchReceived( } } for (const auto &mtpPeer : result) { - if (const auto peer = Auth().data().peerLoaded(peerFromMTP(mtpPeer))) { + if (const auto peer = session().data().peerLoaded(peerFromMTP(mtpPeer))) { if (const auto history = peer->owner().historyLoaded(peer)) { if (history->inChatList(Dialogs::Mode::All)) { continue; // skip existing chats @@ -2051,81 +2001,19 @@ void DialogsInner::peerSearchReceived( refresh(); } -void DialogsInner::userIsContactUpdated(not_null user) { - if (user->loadedStatus != PeerData::FullLoaded) { - LOG(("API Error: " - "notify_userIsContactChanged() called for a not loaded user!")); +void DialogsInner::notify_historyMuteUpdated(History *history) { + if (!_importantSwitch || !history->inChatList(Dialogs::Mode::All)) { return; } - if (user->contactStatus() == UserData::ContactStatus::Contact) { - const auto history = user->owner().history(user->id); - _contacts->addByName(history); - if (!shownDialogs()->getRow(history) - && !_dialogs->contains(history)) { - _contactsNoDialogs->addByName(history); - } - } else if (const auto history = user->owner().historyLoaded(user)) { - if (_selected && _selected->history() == history) { - _selected = nullptr; - } - if (_pressed && _pressed->history() == history) { - setPressed(nullptr); - } - _contactsNoDialogs->del(history); - _contacts->del(history); - } - refresh(); -} - -void DialogsInner::notify_historyMuteUpdated(History *history) { - if (!_dialogsImportant || !history->inChatList(Dialogs::Mode::All)) return; - - if (!history->toImportant()) { - if (Global::DialogsMode() == Dialogs::Mode::Important) { - if (_selected && _selected->history() == history) { - _selected = nullptr; - } - if (_pressed && _pressed->history() == history) { - setPressed(nullptr); - } - } - history->removeFromChatList(Dialogs::Mode::Important, _dialogsImportant.get()); - if (Global::DialogsMode() != Dialogs::Mode::Important) { - return; - } - refresh(); - } else { - bool creating = !history->inChatList(Dialogs::Mode::Important); - if (creating) { - history->addToChatList(Dialogs::Mode::Important, _dialogsImportant.get()); - } - - auto changed = history->adjustByPosInChatList(Dialogs::Mode::All, _dialogs.get()); - - if (Global::DialogsMode() != Dialogs::Mode::Important) { - return; - } - - const auto from = dialogsOffset() + changed.movedFrom * st::dialogsRowHeight; - const auto to = dialogsOffset() + changed.movedTo * st::dialogsRowHeight; - if (!_dragging && from != to) { - // Don't jump in chats list scroll position while dragging. - emit dialogMoved(from, to); - } - if (creating) { - refresh(); - } else if (_state == State::Default && from != to) { - update(0, qMin(from, to), width(), qAbs(from - to) + st::dialogsRowHeight); - } - } + refreshDialog(history); } void DialogsInner::refresh(bool toTop) { int32 h = 0; if (_state == State::Default) { - if (shownDialogs()->isEmpty()) { + if (shownDialogs()->empty()) { h = st::noContactsHeight; - if (Auth().data().contactsLoaded().value()) { + if (session().data().contactsLoaded().value()) { if (_addContactLnk->isHidden()) _addContactLnk->show(); } else { if (!_addContactLnk->isHidden()) _addContactLnk->hide(); @@ -2267,16 +2155,16 @@ void DialogsInner::selectSkip(int32 direction) { clearMouseSelection(); if (_state == State::Default) { if (_importantSwitchSelected) { - if (!shownDialogs()->isEmpty() && direction > 0) { + if (!shownDialogs()->empty() && direction > 0) { _selected = *shownDialogs()->cbegin(); _importantSwitchSelected = false; } else { return; } } else if (!_selected) { - if (_dialogsImportant) { + if (_importantSwitch) { _importantSwitchSelected = true; - } else if (!shownDialogs()->isEmpty() && direction > 0) { + } else if (!shownDialogs()->empty() && direction > 0) { _selected = *shownDialogs()->cbegin(); } else { return; @@ -2290,7 +2178,7 @@ void DialogsInner::selectSkip(int32 direction) { auto prev = shownDialogs()->cfind(_selected); if (prev != shownDialogs()->cbegin()) { _selected = *(--prev); - } else if (_dialogsImportant) { + } else if (_importantSwitch) { _importantSwitchSelected = true; _selected = nullptr; } @@ -2382,7 +2270,7 @@ void DialogsInner::selectSkipPage(int32 pixels, int32 direction) { int toSkip = pixels / int(st::dialogsRowHeight); if (_state == State::Default) { if (!_selected) { - if (direction > 0 && !shownDialogs()->isEmpty()) { + if (direction > 0 && !shownDialogs()->empty()) { _selected = *shownDialogs()->cbegin(); _importantSwitchSelected = false; } else { @@ -2397,7 +2285,7 @@ void DialogsInner::selectSkipPage(int32 pixels, int32 direction) { for (auto i = shownDialogs()->cfind(_selected), b = shownDialogs()->cbegin(); i != b && (toSkip--);) { _selected = *(--i); } - if (toSkip && _dialogsImportant) { + if (toSkip && _importantSwitch) { _importantSwitchSelected = true; _selected = nullptr; } @@ -2417,7 +2305,7 @@ void DialogsInner::loadPeerPhotos() { auto yFrom = _visibleTop; auto yTo = _visibleTop + (_visibleBottom - _visibleTop) * (PreloadHeightsCount + 1); - Auth().downloader().clearPriorities(); + session().downloader().clearPriorities(); if (_state == State::Default) { auto otherStart = shownDialogs()->size() * st::dialogsRowHeight; if (yFrom < otherStart) { @@ -2469,7 +2357,7 @@ void DialogsInner::loadPeerPhotos() { bool DialogsInner::switchImportantChats() { if (!_importantSwitchSelected - || !_dialogsImportant + || !_importantSwitch || (_state != State::Default)) { return false; } @@ -2531,7 +2419,7 @@ DialogsInner::ChosenRow DialogsInner::computeChosenRow() const { }; } else if (base::in_range(_peerSearchSelected, 0, _peerSearchResults.size())) { return { - Auth().data().history(_peerSearchResults[_peerSearchSelected]->peer), + session().data().history(_peerSearchResults[_peerSearchSelected]->peer), Data::UnreadMessagePosition }; } else if (base::in_range(_searchedSelected, 0, _searchResults.size())) { @@ -2578,7 +2466,7 @@ bool DialogsInner::chooseRow() { // HistoryFeed::Memento(feed, chosen.message), // Window::SectionShow::Way::ClearStack); } - if (openSearchResult && !Auth().supportMode()) { + if (openSearchResult && !session().supportMode()) { emit clearSearchQuery(); } updateSelectedRow(); @@ -2595,24 +2483,6 @@ bool DialogsInner::chooseRow() { return false; } -void DialogsInner::destroyData() { - _selected = nullptr; - _hashtagSelected = -1; - _hashtagResults.clear(); - _filteredSelected = -1; - _filterResults.clear(); - _filterResultsGlobal.clear(); - _filter.clear(); - _searchedSelected = _peerSearchSelected = -1; - clearSearchResults(); - _contacts = nullptr; - _contactsNoDialogs = nullptr; - _dialogs = nullptr; - if (_dialogsImportant) { - _dialogsImportant = nullptr; - } -} - Dialogs::RowDescriptor DialogsInner::chatListEntryBefore( const Dialogs::RowDescriptor &which) const { if (!which.key) { @@ -2654,7 +2524,7 @@ Dialogs::RowDescriptor DialogsInner::chatListEntryBefore( FullMsgId(NoChannel, ShowAtUnreadMsgId)); } return Dialogs::RowDescriptor( - Auth().data().history(_peerSearchResults.back()->peer), + session().data().history(_peerSearchResults.back()->peer), FullMsgId(NoChannel, ShowAtUnreadMsgId)); } } @@ -2671,7 +2541,7 @@ Dialogs::RowDescriptor DialogsInner::chatListEntryBefore( for (auto b = _peerSearchResults.cbegin(), i = b + 1, e = _peerSearchResults.cend(); i != e; ++i) { if ((*i)->peer == whichHistory->peer) { return Dialogs::RowDescriptor( - Auth().data().history((*(i - 1))->peer), + session().data().history((*(i - 1))->peer), FullMsgId(NoChannel, ShowAtUnreadMsgId)); } } @@ -2727,7 +2597,7 @@ Dialogs::RowDescriptor DialogsInner::chatListEntryAfter( ++i; if (i != e) { return Dialogs::RowDescriptor( - Auth().data().history((*i)->peer), + session().data().history((*i)->peer), FullMsgId(NoChannel, ShowAtUnreadMsgId)); } else if (!_searchResults.empty()) { return Dialogs::RowDescriptor( @@ -2746,7 +2616,7 @@ Dialogs::RowDescriptor DialogsInner::chatListEntryAfter( FullMsgId(NoChannel, ShowAtUnreadMsgId)); } else if (!_peerSearchResults.empty()) { return Dialogs::RowDescriptor( - Auth().data().history(_peerSearchResults.front()->peer), + session().data().history(_peerSearchResults.front()->peer), FullMsgId(NoChannel, ShowAtUnreadMsgId)); } else if (!_searchResults.empty()) { return Dialogs::RowDescriptor( @@ -2774,7 +2644,7 @@ Dialogs::RowDescriptor DialogsInner::chatListEntryFirst() const { FullMsgId(NoChannel, ShowAtUnreadMsgId)); } else if (!_peerSearchResults.empty()) { return Dialogs::RowDescriptor( - Auth().data().history(_peerSearchResults.front()->peer), + session().data().history(_peerSearchResults.front()->peer), FullMsgId(NoChannel, ShowAtUnreadMsgId)); } else if (!_searchResults.empty()) { return Dialogs::RowDescriptor( @@ -2799,7 +2669,7 @@ Dialogs::RowDescriptor DialogsInner::chatListEntryLast() const { _searchResults.back()->item()->fullId()); } else if (!_peerSearchResults.empty()) { return Dialogs::RowDescriptor( - Auth().data().history(_peerSearchResults.back()->peer), + session().data().history(_peerSearchResults.back()->peer), FullMsgId(NoChannel, ShowAtUnreadMsgId)); } else if (!_filterResults.empty()) { return Dialogs::RowDescriptor( @@ -2809,18 +2679,6 @@ Dialogs::RowDescriptor DialogsInner::chatListEntryLast() const { return Dialogs::RowDescriptor(); } -Dialogs::IndexedList *DialogsInner::contactsList() { - return _contacts.get(); -} - -Dialogs::IndexedList *DialogsInner::dialogsList() { - return _dialogs.get(); -} - -Dialogs::IndexedList *DialogsInner::contactsNoDialogsList() { - return _contactsNoDialogs.get(); -} - int32 DialogsInner::lastSearchDate() const { return _lastSearchDate; } @@ -2883,8 +2741,8 @@ void DialogsInner::setupShortcuts() { request->check(Command::ChatLast) && request->handle([=] { return jumpToDialogRow(last); }); - request->check(Command::ChatSelf) && request->handle([] { - App::main()->choosePeer(Auth().userPeerId(), ShowAtUnreadMsgId); + request->check(Command::ChatSelf) && request->handle([=] { + App::main()->choosePeer(session().userPeerId(), ShowAtUnreadMsgId); return true; }); @@ -2906,7 +2764,7 @@ void DialogsInner::setupShortcuts() { return jumpToDialogRow({ row->key(), FullMsgId() }); }); } - if (Auth().supportMode() && row.key.history()) { + if (session().supportMode() && row.key.history()) { request->check( Command::SupportScrollToCurrent ) && request->handle([=] { @@ -2921,7 +2779,7 @@ Dialogs::RowDescriptor DialogsInner::computeJump( const Dialogs::RowDescriptor &to, JumpSkip skip) { auto result = to; - if (Auth().supportMode() && result.key) { + if (session().supportMode() && result.key) { const auto down = (skip == JumpSkip::NextOrEnd) || (skip == JumpSkip::NextOrOriginal); while (!result.key.entry()->chatListUnreadCount() diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h index 4f8e5a5a5..e576f4947 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h @@ -37,7 +37,7 @@ class DialogsInner Q_OBJECT public: - DialogsInner(QWidget *parent, not_null controller, QWidget *main); + DialogsInner(QWidget *parent, not_null controller); void dialogsReceived(const QVector &dialogs); void addSavedPeersAfter(const QDateTime &date); @@ -57,7 +57,7 @@ public: void selectSkip(int32 direction); void selectSkipPage(int32 pixels, int32 direction); - void createDialog(Dialogs::Key key); + void refreshDialog(Dialogs::Key key); void removeDialog(Dialogs::Key key); void repaintDialogRow(Dialogs::Mode list, not_null row); void repaintDialogRow(Dialogs::RowDescriptor row); @@ -69,13 +69,8 @@ public: bool chooseRow(); - void destroyData(); - void scrollToEntry(const Dialogs::RowDescriptor &entry); - Dialogs::IndexedList *contactsList(); - Dialogs::IndexedList *dialogsList(); - Dialogs::IndexedList *contactsNoDialogsList(); int32 lastSearchDate() const; PeerData *lastSearchPeer() const; MsgId lastSearchId() const; @@ -109,7 +104,6 @@ public: public slots: void onParentGeometryChanged(); - void onDialogRowReplaced(Dialogs::Row *oldRow, Dialogs::Row *newRow); signals: void draggingScrollDelta(int delta); @@ -151,6 +145,11 @@ private: Dialogs::Key key; Data::MessagePosition message; }; + + AuthSession &session() const; + + void dialogRowReplaced(Dialogs::Row *oldRow, Dialogs::Row *newRow); + bool switchImportantChats(); bool chooseHashtag(); ChosenRow computeChosenRow() const; @@ -159,7 +158,6 @@ private: const Dialogs::RowDescriptor &entry) const; void clearMouseSelection(bool clearSelection = false); - void userIsContactUpdated(not_null user); void mousePressReleased(QPoint globalPosition, Qt::MouseButton button); void clearIrrelevantState(); void selectByMouse(QPoint globalPosition); @@ -186,9 +184,6 @@ private: || (_peerSearchSelected >= 0) || (_searchedSelected >= 0); } - void handlePeerNameChange( - not_null peer, - const base::flat_set &oldLetters); bool uniqueSearchResults() const; bool hasHistoryInResults(not_null history) const; @@ -289,12 +284,6 @@ private: not_null _controller; - std::unique_ptr _dialogs; - std::unique_ptr _dialogsImportant; - - std::unique_ptr _contactsNoDialogs; - std::unique_ptr _contacts; - bool _mouseSelection = false; std::optional _lastMousePosition; Qt::MouseButton _pressButton = Qt::LeftButton; diff --git a/Telegram/SourceFiles/dialogs/dialogs_list.cpp b/Telegram/SourceFiles/dialogs/dialogs_list.cpp index 40eb2ce51..00e1ac599 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_list.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_list.cpp @@ -9,7 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "dialogs/dialogs_entry.h" #include "dialogs/dialogs_layout.h" -#include "styles/style_dialogs.h" +#include "data/data_session.h" #include "mainwidget.h" namespace Dialogs { @@ -134,9 +134,7 @@ bool List::del(Key key, Row *replacedBy) { } const auto row = i->second.get(); - if (App::main()) { - emit App::main()->dialogRowReplaced(row, replacedBy); - } + row->entry()->owner().dialogsRowReplaced({ row, replacedBy }); const auto index = row->pos(); _rows.erase(_rows.begin() + index); diff --git a/Telegram/SourceFiles/dialogs/dialogs_list.h b/Telegram/SourceFiles/dialogs/dialogs_list.h index 54b82f2d9..b383c39ff 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_list.h +++ b/Telegram/SourceFiles/dialogs/dialogs_list.h @@ -19,6 +19,9 @@ public: List(SortMode sortMode); List(const List &other) = delete; List &operator=(const List &other) = delete; + List(List &&other) = default; + List &operator=(List &&other) = default; + ~List() = default; int size() const { return _rows.size(); diff --git a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp index 8d33fa8c5..203ff7af2 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp @@ -149,7 +149,8 @@ void DialogsWidget::BottomButton::paintEvent(QPaintEvent *e) { } } -DialogsWidget::DialogsWidget(QWidget *parent, not_null controller) : Window::AbstractSectionWidget(parent, controller) +DialogsWidget::DialogsWidget(QWidget *parent, not_null controller) +: Window::AbstractSectionWidget(parent, controller) , _mainMenuToggle(this, st::dialogsMenuToggle) , _filter(this, st::dialogsFilter, langFactory(lng_dlg_filter)) , _chooseFromUser( @@ -162,7 +163,7 @@ DialogsWidget::DialogsWidget(QWidget *parent, not_null cont , _lockUnlock(this, st::dialogsLock) , _scroll(this, st::dialogsScroll) , _scrollToTop(_scroll, st::dialogsToUp) { - _inner = _scroll->setOwnedWidget(object_ptr(this, controller, parent)); + _inner = _scroll->setOwnedWidget(object_ptr(this, controller)); connect(_inner, SIGNAL(draggingScrollDelta(int)), this, SLOT(onDraggingScrollDelta(int))); connect(_inner, SIGNAL(mustScrollTo(int,int)), _scroll, SLOT(scrollToY(int,int))); connect(_inner, SIGNAL(dialogMoved(int,int)), this, SLOT(onDialogMoved(int,int))); @@ -311,17 +312,17 @@ void DialogsWidget::setupConnectingWidget() { } void DialogsWidget::setupSupportMode() { - if (!Auth().supportMode()) { + if (!session().supportMode()) { return; } - Auth().settings().supportChatsTimeSliceValue( + session().settings().supportChatsTimeSliceValue( ) | rpl::start_with_next([=](int seconds) { _dialogsLoadTill = seconds ? std::max(unixtime() - seconds, 0) : 0; refreshLoadMoreButton(); }, lifetime()); - Auth().settings().supportAllSearchResultsValue( + session().settings().supportAllSearchResultsValue( ) | rpl::filter([=] { return !_searchQuery.isEmpty(); }) | rpl::start_with_next([=] { @@ -363,9 +364,9 @@ void DialogsWidget::activate() { _inner->activate(); } -void DialogsWidget::createDialog(Dialogs::Key key) { +void DialogsWidget::refreshDialog(Dialogs::Key key) { const auto creating = !key.entry()->inChatList(Dialogs::Mode::All); - _inner->createDialog(key); + _inner->refreshDialog(key); const auto history = key.history(); if (creating && history && history->peer->migrateFrom()) { if (const auto migrated = history->owner().historyLoaded( @@ -388,7 +389,7 @@ void DialogsWidget::repaintDialogRow(Dialogs::RowDescriptor row) { } void DialogsWidget::jumpToTop() { - if (Auth().supportMode()) { + if (session().supportMode()) { return; } if ((_filter->getLastText().trimmed().isEmpty() && !_searchInChat)) { @@ -528,8 +529,8 @@ void DialogsWidget::dialogsReceived( const auto [dialogsList, messagesList] = [&] { const auto process = [&](const auto &data) { - Auth().data().processUsers(data.vusers); - Auth().data().processChats(data.vchats); + session().data().processUsers(data.vusers); + session().data().processChats(data.vchats); return std::make_tuple(&data.vdialogs.v, &data.vmessages.v); }; switch (dialogs.type()) { @@ -554,11 +555,11 @@ void DialogsWidget::dialogsReceived( refreshLoadMoreButton(); } - Auth().data().moreChatsLoaded().notify(); + session().data().moreChatsLoaded().notify(); if (_dialogsFull && _pinnedDialogsReceived) { - Auth().data().allChatsLoaded().set(true); + session().data().allChatsLoaded().set(true); } - Auth().api().requestContacts(); + session().api().requestContacts(); } void DialogsWidget::updateDialogsOffset( @@ -597,7 +598,7 @@ void DialogsWidget::updateDialogsOffset( if (lastDate) { _dialogsOffsetDate = lastDate; _dialogsOffsetId = lastMsgId; - _dialogsOffsetPeer = Auth().data().peer(lastPeer); + _dialogsOffsetPeer = session().data().peer(lastPeer); } else { _dialogsFull = true; } @@ -632,7 +633,7 @@ void DialogsWidget::loadMoreBlockedByDateChats() { || _loadMoreChats->isHidden()) { return; } - const auto max = Auth().settings().supportChatsTimeSlice(); + const auto max = session().settings().supportChatsTimeSlice(); _dialogsLoadTill = _dialogsOffsetDate ? (_dialogsOffsetDate - max) : (unixtime() - max); @@ -647,18 +648,18 @@ void DialogsWidget::pinnedDialogsReceived( if (_pinnedDialogsRequestId != requestId) return; auto &data = result.c_messages_peerDialogs(); - Auth().data().processUsers(data.vusers); - Auth().data().processChats(data.vchats); + session().data().processUsers(data.vusers); + session().data().processChats(data.vchats); - Auth().data().applyPinnedDialogs(data.vdialogs.v); + session().data().applyPinnedDialogs(data.vdialogs.v); applyReceivedDialogs(data.vdialogs.v, data.vmessages.v); _pinnedDialogsRequestId = 0; _pinnedDialogsReceived = true; - Auth().data().moreChatsLoaded().notify(); + session().data().moreChatsLoaded().notify(); if (_dialogsFull && _pinnedDialogsReceived) { - Auth().data().allChatsLoaded().set(true); + session().data().allChatsLoaded().set(true); } } @@ -1016,8 +1017,8 @@ void DialogsWidget::searchReceived( auto &d = result.c_messages_messages(); if (_searchRequest != 0) { // Don't apply cached data! - Auth().data().processUsers(d.vusers); - Auth().data().processChats(d.vchats); + session().data().processUsers(d.vusers); + session().data().processChats(d.vchats); } auto &msgs = d.vmessages.v; if (!_inner->searchReceived(msgs, type, msgs.size())) { @@ -1033,8 +1034,8 @@ void DialogsWidget::searchReceived( auto &d = result.c_messages_messagesSlice(); if (_searchRequest != 0) { // Don't apply cached data! - Auth().data().processUsers(d.vusers); - Auth().data().processChats(d.vchats); + session().data().processUsers(d.vusers); + session().data().processChats(d.vchats); } auto &msgs = d.vmessages.v; if (!_inner->searchReceived(msgs, type, d.vcount.v)) { @@ -1063,8 +1064,8 @@ void DialogsWidget::searchReceived( } if (_searchRequest != 0) { // Don't apply cached data! - Auth().data().processUsers(d.vusers); - Auth().data().processChats(d.vchats); + session().data().processUsers(d.vusers); + session().data().processChats(d.vchats); } auto &msgs = d.vmessages.v; if (!_inner->searchReceived(msgs, type, d.vcount.v)) { @@ -1110,8 +1111,8 @@ void DialogsWidget::peerSearchReceived( switch (result.type()) { case mtpc_contacts_found: { auto &d = result.c_contacts_found(); - Auth().data().processUsers(d.vusers); - Auth().data().processChats(d.vchats); + session().data().processUsers(d.vusers); + session().data().processChats(d.vchats); _inner->peerSearchReceived(q, d.vmy_results.v, d.vresults.v); } break; } @@ -1566,10 +1567,6 @@ void DialogsWidget::paintEvent(QPaintEvent *e) { } } -void DialogsWidget::destroyData() { - _inner->destroyData(); -} - void DialogsWidget::scrollToEntry(const Dialogs::RowDescriptor &entry) { _inner->scrollToEntry(entry); } @@ -1578,18 +1575,6 @@ void DialogsWidget::removeDialog(Dialogs::Key key) { _inner->removeDialog(key); } -Dialogs::IndexedList *DialogsWidget::contactsList() { - return _inner->contactsList(); -} - -Dialogs::IndexedList *DialogsWidget::dialogsList() { - return _inner->dialogsList(); -} - -Dialogs::IndexedList *DialogsWidget::contactsNoDialogsList() { - return _inner->contactsNoDialogsList(); -} - bool DialogsWidget::onCancelSearch() { bool clearing = !_filter->getLastText().isEmpty(); if (_searchRequest) { diff --git a/Telegram/SourceFiles/dialogs/dialogs_widget.h b/Telegram/SourceFiles/dialogs/dialogs_widget.h index d60a37b52..c149ba790 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_widget.h +++ b/Telegram/SourceFiles/dialogs/dialogs_widget.h @@ -14,12 +14,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/special_buttons.h" class DialogsInner; +class AuthSession; namespace Dialogs { struct RowDescriptor; class Row; class FakeRow; -class IndexedList; class Key; } // namespace Dialogs @@ -60,7 +60,7 @@ public: void loadDialogs(); void loadPinnedDialogs(); - void createDialog(Dialogs::Key key); + void refreshDialog(Dialogs::Key key); void removeDialog(Dialogs::Key key); void repaintDialogRow(Dialogs::Mode list, not_null row); void repaintDialogRow(Dialogs::RowDescriptor row); @@ -76,14 +76,8 @@ public: void showAnimated(Window::SlideDirection direction, const Window::SectionSlideParams ¶ms); void showFast(); - void destroyData(); - void scrollToEntry(const Dialogs::RowDescriptor &entry); - Dialogs::IndexedList *contactsList(); - Dialogs::IndexedList *dialogsList(); - Dialogs::IndexedList *contactsNoDialogsList(); - void searchMessages(const QString &query, Dialogs::Key inChat = {}); void onSearchMore(); diff --git a/Telegram/SourceFiles/history/history.cpp b/Telegram/SourceFiles/history/history.cpp index d2115076c..e1e55c7bf 100644 --- a/Telegram/SourceFiles/history/history.cpp +++ b/Telegram/SourceFiles/history/history.cpp @@ -63,11 +63,10 @@ constexpr auto kSkipCloudDraftsFor = TimeId(3); } // namespace History::History(not_null owner, PeerId peerId) -: Entry(this) +: Entry(owner, this) , peer(owner->peer(peerId)) , cloudDraftTextCache(st::dialogsTextWidthMin) -, _owner(owner) -, _mute(_owner->notifyIsMuted(peer)) +, _mute(owner->notifyIsMuted(peer)) , _sendActionText(st::dialogsTextWidthMin) { if (const auto user = peer->asUser()) { if (user->botInfo) { @@ -329,9 +328,9 @@ void History::draftSavedToCloud() { } HistoryItemsList History::validateForwardDraft() { - auto result = _owner->idsToItems(_forwardDraft); + auto result = owner().idsToItems(_forwardDraft); if (result.size() != _forwardDraft.size()) { - setForwardDraft(_owner->itemsToIds(result)); + setForwardDraft(owner().itemsToIds(result)); } return result; } @@ -561,7 +560,7 @@ bool History::updateSendActionNeedsAnimating(crl::time now, bool force) { } const auto result = (!_typing.empty() || !_sendActions.empty()); if (changed || (result && !anim::Disabled())) { - _owner->updateSendActionAnimation({ + owner().updateSendActionAnimation({ this, _sendActionAnimation.width(), st::normalFont->height, @@ -940,7 +939,7 @@ not_null History::addNewItem( } if (auto megagroup = peer->asMegagroup()) { Notify::peerUpdatedDelayed(peer, Notify::PeerUpdate::Flag::MembersChanged); - _owner->addNewMegagroupParticipant(megagroup, user); + owner().addNewMegagroupParticipant(megagroup, user); } } } @@ -1000,7 +999,7 @@ not_null History::addNewItem( newItemAdded(item); } - _owner->notifyHistoryChangeDelayed(this); + owner().notifyHistoryChangeDelayed(this); return item; } @@ -1028,7 +1027,7 @@ void History::applyServiceChanges( if (!base::contains(mgInfo->lastParticipants, user)) { mgInfo->lastParticipants.push_front(user); Notify::peerUpdatedDelayed(peer, Notify::PeerUpdate::Flag::MembersChanged); - _owner->addNewMegagroupParticipant(megagroup, user); + owner().addNewMegagroupParticipant(megagroup, user); } if (user->botInfo) { peer->asChannel()->mgInfo->bots.insert(user); @@ -1050,7 +1049,7 @@ void History::applyServiceChanges( if (!base::contains(mgInfo->lastParticipants, user)) { mgInfo->lastParticipants.push_front(user); Notify::peerUpdatedDelayed(peer, Notify::PeerUpdate::Flag::MembersChanged); - _owner->addNewMegagroupParticipant(megagroup, user); + owner().addNewMegagroupParticipant(megagroup, user); } if (user->botInfo) { mgInfo->bots.insert(user); @@ -1086,7 +1085,7 @@ void History::applyServiceChanges( mgInfo->lastParticipants.erase(i); Notify::peerUpdatedDelayed(peer, Notify::PeerUpdate::Flag::MembersChanged); } - _owner->removeMegagroupParticipant(megagroup, user); + owner().removeMegagroupParticipant(megagroup, user); if (megagroup->membersCount() > 1) { megagroup->setMembersCount(megagroup->membersCount() - 1); } else { @@ -1114,7 +1113,7 @@ void History::applyServiceChanges( d.vphoto.match([&](const MTPDphoto &data) { const auto &sizes = data.vsizes.v; if (!sizes.isEmpty()) { - auto photo = _owner->processPhoto(data); + auto photo = owner().processPhoto(data); photo->peer = peer; auto &smallSize = sizes.front(); auto &bigSize = sizes.back(); @@ -1662,7 +1661,7 @@ void History::setUnreadCount(int newUnreadCount) { const auto delta = unreadMarkDelta + (unreadCountDelta ? *unreadCountDelta : newUnreadCount); - _owner->unreadIncrement(delta, mute()); + owner().unreadIncrement(delta, mute()); const auto nowUnread = (*_unreadCount > 0) || _unreadMark; const auto entriesDelta = (wasUnread && !nowUnread) @@ -1670,7 +1669,7 @@ void History::setUnreadCount(int newUnreadCount) { : (nowUnread && !wasUnread) ? 1 : 0; - _owner->unreadEntriesChanged( + owner().unreadEntriesChanged( entriesDelta, mute() ? entriesDelta : 0); } @@ -1689,8 +1688,8 @@ void History::setUnreadMark(bool unread) { if (!_unreadCount || !*_unreadCount) { if (inChatList(Dialogs::Mode::All)) { const auto delta = _unreadMark ? 1 : -1; - _owner->unreadIncrement(delta, mute()); - _owner->unreadEntriesChanged( + owner().unreadIncrement(delta, mute()); + owner().unreadEntriesChanged( delta, mute() ? delta : 0); @@ -1746,11 +1745,11 @@ bool History::changeMute(bool newMute) { //} if (inChatList(Dialogs::Mode::All)) { if (const auto count = unreadCountForBadge()) { - _owner->unreadMuteChanged(count, _mute); + owner().unreadMuteChanged(count, _mute); const auto entriesWithUnreadDelta = 0; const auto mutedEntriesWithUnreadDelta = _mute ? 1 : -1; - _owner->unreadEntriesChanged( + owner().unreadEntriesChanged( entriesWithUnreadDelta, mutedEntriesWithUnreadDelta); @@ -2455,7 +2454,7 @@ void History::applyDialog(const MTPDdialog &data) { } } } - _owner->applyNotifySetting( + owner().applyNotifySetting( MTP_notifyPeer(data.vpeer), data.vnotify_settings); @@ -2660,14 +2659,6 @@ void History::resizeToWidth(int newWidth) { _height = y; } -Data::Session &History::owner() const { - return *_owner; -} - -AuthSession &History::session() const { - return _owner->session(); -} - ChannelId History::channelId() const { return peerToChannel(peer->id); } @@ -2964,12 +2955,12 @@ void History::clear(ClearType type) { forgetScrollState(); if (type == ClearType::Unload) { blocks.clear(); - _owner->notifyHistoryUnloaded(this); + owner().notifyHistoryUnloaded(this); lastKeyboardInited = false; _loadedAtTop = _loadedAtBottom = false; } else { notifies.clear(); - _owner->notifyHistoryCleared(this); + owner().notifyHistoryCleared(this); changeUnreadCount(-unreadCount()); if (type == ClearType::DeleteChat) { setLastMessage(nullptr); @@ -2998,7 +2989,7 @@ void History::clear(ClearType type) { //} } } - _owner->notifyHistoryChangeDelayed(this); + owner().notifyHistoryChangeDelayed(this); if (const auto chat = peer->asChat()) { chat->lastAuthors.clear(); @@ -3026,7 +3017,7 @@ void History::clearUpTill(MsgId availableMinId) { } while (!isEmpty()); requestChatListMessage(); - _owner->sendHistoryChangeNotifications(); + owner().sendHistoryChangeNotifications(); } void History::applyGroupAdminChanges( @@ -3041,10 +3032,10 @@ void History::applyGroupAdminChanges( void History::changedInChatListHook(Dialogs::Mode list, bool added) { if (list == Dialogs::Mode::All) { if (const auto delta = unreadCountForBadge() * (added ? 1 : -1)) { - _owner->unreadIncrement(delta, mute()); + owner().unreadIncrement(delta, mute()); const auto entriesDelta = added ? 1 : -1; - _owner->unreadEntriesChanged( + owner().unreadEntriesChanged( entriesDelta, mute() ? entriesDelta : 0); } diff --git a/Telegram/SourceFiles/history/history.h b/Telegram/SourceFiles/history/history.h index be9c43e3c..361bbfee9 100644 --- a/Telegram/SourceFiles/history/history.h +++ b/Telegram/SourceFiles/history/history.h @@ -64,9 +64,6 @@ public: History &operator=(const History &) = delete; ~History(); - Data::Session &owner() const; - AuthSession &session() const; - ChannelId channelId() const; bool isChannel() const; bool isMegagroup() const; @@ -467,7 +464,6 @@ private: void setFolderPointer(Data::Folder *folder); - not_null _owner; Flags _flags = 0; bool _mute = false; int _width = 0; diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index 491d08f7b..3a09164c8 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -6670,10 +6670,6 @@ QRect HistoryWidget::historyRect() const { return _scroll->geometry(); } -void HistoryWidget::destroyData() { - showHistory(0, 0); -} - QPoint HistoryWidget::clampMousePosition(QPoint point) { if (point.x() < 0) { point.setX(0); diff --git a/Telegram/SourceFiles/history/history_widget.h b/Telegram/SourceFiles/history/history_widget.h index b689b425d..d05dd418f 100644 --- a/Telegram/SourceFiles/history/history_widget.h +++ b/Telegram/SourceFiles/history/history_widget.h @@ -153,8 +153,6 @@ public: void updateRecentStickers(); - void destroyData(); - void updateFieldPlaceholder(); void updateStickersByEmoji(); diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 1a0a5f2a2..a732721f8 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -967,18 +967,6 @@ void MainWidget::cacheBackground() { _cachedFor = _willCacheFor; } -Dialogs::IndexedList *MainWidget::contactsList() { - return _dialogs->contactsList(); -} - -Dialogs::IndexedList *MainWidget::dialogsList() { - return _dialogs->dialogsList(); -} - -Dialogs::IndexedList *MainWidget::contactsNoDialogsList() { - return _dialogs->contactsNoDialogsList(); -} - crl::time MainWidget::highlightStartTime(not_null item) const { return _history->highlightStartTime(item); } @@ -1557,8 +1545,8 @@ bool MainWidget::viewsIncrementFail(const RPCError &error, mtpRequestId req) { return false; } -void MainWidget::createDialog(Dialogs::Key key) { - _dialogs->createDialog(key); +void MainWidget::refreshDialog(Dialogs::Key key) { + _dialogs->refreshDialog(key); } void MainWidget::choosePeer(PeerId peerId, MsgId showAtMsgId) { @@ -3489,11 +3477,6 @@ void MainWidget::activate() { App::wnd()->fixOrder(); } -void MainWidget::destroyData() { - _history->destroyData(); - _dialogs->destroyData(); -} - bool MainWidget::isActive() const { return !_isIdle && isVisible() && !_a_show.animating(); } diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index 5acc965f3..b055f255a 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -35,7 +35,6 @@ namespace Dialogs { struct RowDescriptor; class Row; class Key; -class IndexedList; } // namespace Dialogs namespace Media { @@ -124,7 +123,7 @@ public: void activate(); void updateReceived(const mtpPrime *from, const mtpPrime *end); - void createDialog(Dialogs::Key key); + void refreshDialog(Dialogs::Key key); void removeDialog(Dialogs::Key key); void repaintDialogRow(Dialogs::Mode list, not_null row); void repaintDialogRow(Dialogs::RowDescriptor row); @@ -163,7 +162,6 @@ public: const std::optional &oldId); bool onSendSticker(DocumentData *sticker); - void destroyData(); void updateOnlineDisplayIn(int32 msecs); bool isActive() const; @@ -200,10 +198,6 @@ public: bool sendMessageFail(const RPCError &error); - Dialogs::IndexedList *contactsList(); - Dialogs::IndexedList *dialogsList(); - Dialogs::IndexedList *contactsNoDialogsList(); - // While HistoryInner is not HistoryView::ListWidget. crl::time highlightStartTime(not_null item) const; bool historyInSelectionMode() const; @@ -298,7 +292,6 @@ public: ~MainWidget(); signals: - void dialogRowReplaced(Dialogs::Row *oldRow, Dialogs::Row *newRow); void dialogsUpdated(); public slots: diff --git a/Telegram/SourceFiles/window/section_widget.cpp b/Telegram/SourceFiles/window/section_widget.cpp index f86aa679a..e60804d5c 100644 --- a/Telegram/SourceFiles/window/section_widget.cpp +++ b/Telegram/SourceFiles/window/section_widget.cpp @@ -12,9 +12,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "window/section_memento.h" #include "window/window_slide_animation.h" #include "window/themes/window_theme.h" +#include "window/window_controller.h" namespace Window { +AuthSession &AbstractSectionWidget::session() const { + return _controller->session(); +} + SectionWidget::SectionWidget( QWidget *parent, not_null controller) diff --git a/Telegram/SourceFiles/window/section_widget.h b/Telegram/SourceFiles/window/section_widget.h index 5bb550a10..13df024e8 100644 --- a/Telegram/SourceFiles/window/section_widget.h +++ b/Telegram/SourceFiles/window/section_widget.h @@ -10,6 +10,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/rp_widget.h" #include "dialogs/dialogs_key.h" +class AuthSession; + namespace Window { class Controller; @@ -31,10 +33,12 @@ public: AbstractSectionWidget( QWidget *parent, not_null controller) - : RpWidget(parent) - , _controller(controller) { + : RpWidget(parent) + , _controller(controller) { } + AuthSession &session() const; + // Float player interface. virtual bool wheelEventFromFloatPlayer(QEvent *e) { return false;