Move chats / contacts lists to Data::Session.

This commit is contained in:
John Preston 2019-04-16 18:05:56 +04:00
parent 2862070348
commit 0c0d6bc411
25 changed files with 441 additions and 496 deletions

View File

@ -258,8 +258,8 @@ void ChatsListBoxController::rebuildRows() {
++added; ++added;
} }
} }
added += appendList(App::main()->dialogsList()); added += appendList(Auth().data().chatsList());
added += appendList(App::main()->contactsNoDialogsList()); added += appendList(Auth().data().contactsNoChatsList());
if (!wasEmpty && added > 0) { if (!wasEmpty && added > 0) {
// Place dialogs list before contactsNoDialogs list. // Place dialogs list before contactsNoDialogs list.
delegate()->peerListPartitionRows([](const PeerListRow &a) { delegate()->peerListPartitionRows([](const PeerListRow &a) {
@ -327,7 +327,7 @@ void ContactsBoxController::prepare() {
} }
void ContactsBoxController::rebuildRows() { void ContactsBoxController::rebuildRows() {
auto appendList = [this](auto chats) { const auto appendList = [&](auto chats) {
auto count = 0; auto count = 0;
for (const auto row : chats->all()) { for (const auto row : chats->all()) {
if (const auto history = row->history()) { if (const auto history = row->history()) {
@ -340,7 +340,7 @@ void ContactsBoxController::rebuildRows() {
} }
return count; return count;
}; };
appendList(App::main()->contactsList()); appendList(Auth().data().contactsList());
checkForEmptyRows(); checkForEmptyRows();
delegate()->peerListRefreshRows(); delegate()->peerListRefreshRows();
} }

View File

@ -1061,16 +1061,16 @@ void AddSpecialBoxSearchController::addChatsContacts() {
return true; return true;
}; };
const auto getSmallestIndex = [&]( const auto getSmallestIndex = [&](not_null<Dialogs::IndexedList*> list)
Dialogs::IndexedList *list) -> const Dialogs::List* { -> const Dialogs::List* {
if (list->isEmpty()) { if (list->empty()) {
return nullptr; return nullptr;
} }
auto result = (const Dialogs::List*)nullptr; auto result = (const Dialogs::List*)nullptr;
for (const auto &word : wordList) { for (const auto &word : wordList) {
const auto found = list->filtered(word[0]); const auto found = list->filtered(word[0]);
if (found->empty()) { if (!found || found->empty()) {
return nullptr; return nullptr;
} }
if (!result || result->size() > found->size()) { if (!result || result->size() > found->size()) {
@ -1079,9 +1079,9 @@ void AddSpecialBoxSearchController::addChatsContacts() {
} }
return result; return result;
}; };
const auto dialogsIndex = getSmallestIndex(App::main()->dialogsList()); const auto dialogsIndex = getSmallestIndex(_peer->owner().chatsList());
const auto contactsIndex = getSmallestIndex( const auto contactsIndex = getSmallestIndex(
App::main()->contactsNoDialogsList()); _peer->owner().contactsNoChatsList());
const auto filterAndAppend = [&](const Dialogs::List *list) { const auto filterAndAppend = [&](const Dialogs::List *list) {
if (!list) { if (!list) {

View File

@ -489,7 +489,7 @@ ShareBox::Inner::Inner(
_rowHeight = st::shareRowHeight; _rowHeight = st::shareRowHeight;
setAttribute(Qt::WA_OpaquePaintEvent); setAttribute(Qt::WA_OpaquePaintEvent);
const auto dialogs = App::main()->dialogsList(); const auto dialogs = Auth().data().chatsList();
const auto self = Auth().user(); const auto self = Auth().user();
if (_filterCallback(self)) { if (_filterCallback(self)) {
_chatsIndexed->addToEnd(self->owner().history(self)); _chatsIndexed->addToEnd(self->owner().history(self));
@ -670,7 +670,7 @@ void ShareBox::Inner::loadProfilePhotos(int yFrom) {
Auth().downloader().clearPriorities(); Auth().downloader().clearPriorities();
if (_filter.isEmpty()) { if (_filter.isEmpty()) {
if (!_chatsIndexed->isEmpty()) { if (!_chatsIndexed->empty()) {
auto i = _chatsIndexed->cfind(yFrom, _rowHeight); auto i = _chatsIndexed->cfind(yFrom, _rowHeight);
for (auto end = _chatsIndexed->cend(); i != end; ++i) { for (auto end = _chatsIndexed->cend(); i != end; ++i) {
if (((*i)->pos() * _rowHeight) >= yTo) { if (((*i)->pos() * _rowHeight) >= yTo) {
@ -769,7 +769,7 @@ void ShareBox::Inner::paintEvent(QPaintEvent *e) {
auto indexFrom = rowFrom * _columnCount; auto indexFrom = rowFrom * _columnCount;
auto indexTo = rowTo * _columnCount; auto indexTo = rowTo * _columnCount;
if (_filter.isEmpty()) { if (_filter.isEmpty()) {
if (!_chatsIndexed->isEmpty()) { if (!_chatsIndexed->empty()) {
auto i = _chatsIndexed->cfind(indexFrom, 1); auto i = _chatsIndexed->cfind(indexFrom, 1);
for (auto end = _chatsIndexed->cend(); i != end; ++i) { for (auto end = _chatsIndexed->cend(); i != end; ++i) {
if (indexFrom >= indexTo) { if (indexFrom >= indexTo) {
@ -949,10 +949,10 @@ void ShareBox::Inner::updateFilter(QString filter) {
_filtered.clear(); _filtered.clear();
if (!words.isEmpty()) { if (!words.isEmpty()) {
const Dialogs::List *toFilter = nullptr; const Dialogs::List *toFilter = nullptr;
if (!_chatsIndexed->isEmpty()) { if (!_chatsIndexed->empty()) {
for (fi = fb; fi != fe; ++fi) { for (fi = fb; fi != fe; ++fi) {
auto found = _chatsIndexed->filtered(fi->at(0)); const auto found = _chatsIndexed->filtered(fi->at(0));
if (found->empty()) { if (!found || found->empty()) {
toFilter = nullptr; toFilter = nullptr;
break; break;
} }

View File

@ -33,21 +33,13 @@ namespace Data {
//} //}
Folder::Folder(not_null<Data::Session*> owner, FolderId id) Folder::Folder(not_null<Data::Session*> owner, FolderId id)
: Entry(this) : Entry(owner, this)
, _id(id) , _id(id)
, _owner(owner) , _chatsList(Dialogs::SortMode::Date)
, _name(lang(lng_archived_chats)) { , _name(lang(lng_archived_chats)) {
indexNameParts(); indexNameParts();
} }
Data::Session &Folder::owner() const {
return *_owner;
}
AuthSession &Folder::session() const {
return _owner->session();
}
FolderId Folder::id() const { FolderId Folder::id() const {
return _id; return _id;
} }
@ -79,11 +71,11 @@ void Folder::indexNameParts() {
} }
void Folder::registerOne(not_null<History*> history) { void Folder::registerOne(not_null<History*> history) {
if (base::contains(_histories, history)) { if (_chatsList.contains(history)) {
return; return;
} }
const auto invisible = empty(_histories); const auto invisible = _chatsList.empty();
_histories.push_back(history); _chatsList.addToEnd(history);
//session().storage().invalidate( // #feed //session().storage().invalidate( // #feed
// Storage::FeedMessagesInvalidate(_id)); // Storage::FeedMessagesInvalidate(_id));
@ -109,24 +101,22 @@ void Folder::registerOne(not_null<History*> history) {
session().api().requestDialogEntry(this); session().api().requestDialogEntry(this);
} }
} }
if (invisible && !empty(_histories)) { if (invisible && !_chatsList.empty()) {
updateChatListExistence(); updateChatListExistence();
for (const auto history : _histories) { //for (const auto history : _histories) { // #TODO archived
history->updateChatListExistence(); // history->updateChatListExistence();
} //}
} else { } else {
history->updateChatListExistence(); history->updateChatListExistence();
} }
_owner->notifyFolderUpdated(this, FolderUpdateFlag::List); owner().notifyFolderUpdated(this, FolderUpdateFlag::List);
} }
void Folder::unregisterOne(not_null<History*> history) { void Folder::unregisterOne(not_null<History*> history) {
const auto i = ranges::remove(_histories, history); if (!_chatsList.contains(history)) {
if (i == end(_histories)) {
return; return;
} }
const auto visible = !empty(_histories); _chatsList.del(history);
_histories.erase(i, end(_histories));
//session().storage().remove( // #feed //session().storage().remove( // #feed
// Storage::FeedMessagesRemoveAll(_id, channel->bareId())); // Storage::FeedMessagesRemoveAll(_id, channel->bareId()));
@ -146,15 +136,19 @@ void Folder::unregisterOne(not_null<History*> history) {
session().api().requestDialogEntry(this); session().api().requestDialogEntry(this);
} }
} }
if (visible && empty(_histories)) { if (_chatsList.empty()) {
updateChatListExistence(); updateChatListExistence();
for (const auto history : _histories) { //for (const auto history : _histories) { // #TODO archive
history->updateChatListExistence(); // history->updateChatListExistence();
} //}
} else { } else {
history->updateChatListExistence(); history->updateChatListExistence();
} }
_owner->notifyFolderUpdated(this, FolderUpdateFlag::List); owner().notifyFolderUpdated(this, FolderUpdateFlag::List);
}
not_null<Dialogs::IndexedList*> Folder::chatsList() {
return &_chatsList;
} }
void Folder::updateChatListMessage(not_null<HistoryItem*> item) { void Folder::updateChatListMessage(not_null<HistoryItem*> item) {
@ -202,10 +196,6 @@ void Folder::paintUserpic(
//} //}
} }
const std::vector<not_null<History*>> &Folder::histories() const {
return _histories;
}
bool Folder::historiesLoaded() const { bool Folder::historiesLoaded() const {
return _historiesLoaded; return _historiesLoaded;
} }
@ -213,7 +203,7 @@ bool Folder::historiesLoaded() const {
void Folder::setHistoriesLoaded(bool loaded) { void Folder::setHistoriesLoaded(bool loaded) {
if (_historiesLoaded != loaded) { if (_historiesLoaded != loaded) {
_historiesLoaded = loaded; _historiesLoaded = loaded;
_owner->notifyFolderUpdated(this, FolderUpdateFlag::List); owner().notifyFolderUpdated(this, FolderUpdateFlag::List);
} }
} }
// // #feed // // #feed
@ -306,8 +296,8 @@ void Folder::requestChatListMessage() {
void Folder::recountChatListMessage() { void Folder::recountChatListMessage() {
_chatListMessage = std::nullopt; _chatListMessage = std::nullopt;
for (const auto history : _histories) { for (const auto entry : _chatsList) {
if (!history->chatListMessageKnown()) { if (entry->history() && !entry->history()->chatListMessageKnown()) {
requestChatListMessage(); requestChatListMessage();
return; return;
} }
@ -317,9 +307,11 @@ void Folder::recountChatListMessage() {
void Folder::setChatListMessageFromChannels() { void Folder::setChatListMessageFromChannels() {
_chatListMessage = nullptr; _chatListMessage = nullptr;
for (const auto history : _histories) { for (const auto entry : _chatsList) {
if (const auto last = history->chatListMessage()) { if (entry->history()) {
justUpdateChatListMessage(last); if (const auto last = entry->history()->chatListMessage()) {
justUpdateChatListMessage(last);
}
} }
} }
updateChatListDate(); updateChatListDate();
@ -386,15 +378,15 @@ void Folder::changedInChatListHook(Dialogs::Mode list, bool added) {
const auto nonMutedCount = count - mutedCount; const auto nonMutedCount = count - mutedCount;
const auto mutedDelta = added ? mutedCount : -mutedCount; const auto mutedDelta = added ? mutedCount : -mutedCount;
const auto nonMutedDelta = added ? nonMutedCount : -nonMutedCount; const auto nonMutedDelta = added ? nonMutedCount : -nonMutedCount;
Auth().data().unreadIncrement(nonMutedDelta, false); owner().unreadIncrement(nonMutedDelta, false);
Auth().data().unreadIncrement(mutedDelta, true); owner().unreadIncrement(mutedDelta, true);
const auto fullMuted = (nonMutedCount == 0); const auto fullMuted = (nonMutedCount == 0);
const auto entriesWithUnreadDelta = added ? 1 : -1; const auto entriesWithUnreadDelta = added ? 1 : -1;
const auto mutedEntriesWithUnreadDelta = fullMuted const auto mutedEntriesWithUnreadDelta = fullMuted
? entriesWithUnreadDelta ? entriesWithUnreadDelta
: 0; : 0;
Auth().data().unreadEntriesChanged( owner().unreadEntriesChanged(
entriesWithUnreadDelta, entriesWithUnreadDelta,
mutedEntriesWithUnreadDelta); mutedEntriesWithUnreadDelta);
} }
@ -419,11 +411,11 @@ void Folder::updateUnreadCounts(PerformUpdate &&performUpdate) {
const auto nowFullMuted = (nowUnreadMutedCount > 0) const auto nowFullMuted = (nowUnreadMutedCount > 0)
&& (nowUnreadCount == nowUnreadMutedCount); && (nowUnreadCount == nowUnreadMutedCount);
Auth().data().unreadIncrement( owner().unreadIncrement(
(nowUnreadCount - nowUnreadMutedCount) (nowUnreadCount - nowUnreadMutedCount)
- (wasUnreadCount - wasUnreadMutedCount), - (wasUnreadCount - wasUnreadMutedCount),
false); false);
Auth().data().unreadIncrement( owner().unreadIncrement(
nowUnreadMutedCount - wasUnreadMutedCount, nowUnreadMutedCount - wasUnreadMutedCount,
true); true);
@ -437,7 +429,7 @@ void Folder::updateUnreadCounts(PerformUpdate &&performUpdate) {
: (wasFullMuted && !nowFullMuted) : (wasFullMuted && !nowFullMuted)
? -1 ? -1
: 0; : 0;
Auth().data().unreadEntriesChanged( owner().unreadEntriesChanged(
entriesDelta, entriesDelta,
mutedEntriesDelta); mutedEntriesDelta);
} }
@ -483,8 +475,8 @@ void Folder::unreadCountChanged(int unreadCountDelta, int mutedCountDelta) {
// if (!_unreadCount || !*_unreadCount) { // if (!_unreadCount || !*_unreadCount) {
// if (inChatList(Dialogs::Mode::All)) { // if (inChatList(Dialogs::Mode::All)) {
// const auto delta = _unreadMark ? 1 : -1; // const auto delta = _unreadMark ? 1 : -1;
// _owner->unreadIncrement(delta, mute()); // owner().unreadIncrement(delta, mute());
// _owner->unreadEntriesChanged( // owner().unreadEntriesChanged(
// delta, // delta,
// mute() ? delta : 0); // mute() ? delta : 0);
// //
@ -518,7 +510,7 @@ bool Folder::useProxyPromotion() const {
} }
bool Folder::shouldBeInChatList() const { bool Folder::shouldBeInChatList() const {
return !empty(_histories); return !_chatsList.empty();
} }
int Folder::chatListUnreadCount() const { int Folder::chatListUnreadCount() const {

View File

@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#pragma once #pragma once
#include "dialogs/dialogs_entry.h" #include "dialogs/dialogs_entry.h"
#include "dialogs/dialogs_indexed_list.h"
#include "data/data_messages.h" #include "data/data_messages.h"
class ChannelData; class ChannelData;
@ -37,13 +38,12 @@ public:
Folder(const Folder &) = delete; Folder(const Folder &) = delete;
Folder &operator=(const Folder &) = delete; Folder &operator=(const Folder &) = delete;
Data::Session &owner() const;
AuthSession &session() const;
FolderId id() const; FolderId id() const;
void registerOne(not_null<History*> history); void registerOne(not_null<History*> history);
void unregisterOne(not_null<History*> history); void unregisterOne(not_null<History*> history);
not_null<Dialogs::IndexedList*> chatsList();
void updateChatListMessage(not_null<HistoryItem*> item); void updateChatListMessage(not_null<HistoryItem*> item);
void messageRemoved(not_null<HistoryItem*> item); void messageRemoved(not_null<HistoryItem*> item);
void historyCleared(not_null<History*> history); void historyCleared(not_null<History*> history);
@ -86,7 +86,6 @@ public:
int y, int y,
int size) const override; int size) const override;
const std::vector<not_null<History*>> &histories() const;
bool historiesLoaded() const; bool historiesLoaded() const;
void setHistoriesLoaded(bool loaded); void setHistoriesLoaded(bool loaded);
//int32 chatsHash() const; //int32 chatsHash() const;
@ -98,16 +97,15 @@ private:
void setChatListMessageFromChannels(); void setChatListMessageFromChannels();
bool justUpdateChatListMessage(not_null<HistoryItem*> item); bool justUpdateChatListMessage(not_null<HistoryItem*> item);
void updateChatListDate(); void updateChatListDate();
void changeChatsList( //void changeChatsList(
const std::vector<not_null<PeerData*>> &add, // const std::vector<not_null<PeerData*>> &add,
const std::vector<not_null<PeerData*>> &remove); // const std::vector<not_null<PeerData*>> &remove);
template <typename PerformUpdate> template <typename PerformUpdate>
void updateUnreadCounts(PerformUpdate &&performUpdate); void updateUnreadCounts(PerformUpdate &&performUpdate);
FolderId _id = 0; FolderId _id = 0;
not_null<Data::Session*> _owner; Dialogs::IndexedList _chatsList;
std::vector<not_null<History*>> _histories;
bool _settingHistories = false; bool _settingHistories = false;
bool _historiesLoaded = false; bool _historiesLoaded = false;

View File

@ -150,6 +150,10 @@ Session::Session(not_null<AuthSession*> session)
, _bigFileCache(Core::App().databases().get( , _bigFileCache(Core::App().databases().get(
Local::cacheBigFilePath(), Local::cacheBigFilePath(),
Local::cacheBigFileSettings())) Local::cacheBigFileSettings()))
, _chatsList(Dialogs::SortMode::Date)
, _importantChatsList(Dialogs::SortMode::Date)
, _contactsList(Dialogs::SortMode::Name)
, _contactsNoChatsList(Dialogs::SortMode::Name)
, _selfDestructTimer([=] { checkSelfDestructItems(); }) , _selfDestructTimer([=] { checkSelfDestructItems(); })
, _sendActionsAnimation([=](crl::time now) { , _sendActionsAnimation([=](crl::time now) {
return sendActionsAnimationCallback(now); return sendActionsAnimationCallback(now);
@ -161,6 +165,8 @@ Session::Session(not_null<AuthSession*> session)
setupContactViewsViewer(); setupContactViewsViewer();
setupChannelLeavingViewer(); setupChannelLeavingViewer();
setupPeerNameViewer();
setupUserIsContactViewer();
} }
void Session::clear() { void Session::clear() {
@ -919,6 +925,49 @@ void Session::setupChannelLeavingViewer() {
}, _lifetime); }, _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() { Session::~Session() {
// Optimization: clear notifications before destroying items. // Optimization: clear notifications before destroying items.
_session->notifications().clearAllFast(); _session->notifications().clearAllFast();
@ -2829,6 +2878,79 @@ not_null<Folder*> Session::processFolder(const MTPDfolder &data) {
// return _defaultFeedId.value(); // return _defaultFeedId.value();
//} //}
not_null<Dialogs::IndexedList*> Session::chatsList() {
return &_chatsList;
}
not_null<Dialogs::IndexedList*> Session::importantChatsList() {
return &_importantChatsList;
}
not_null<Dialogs::IndexedList*> Session::contactsList() {
return &_contactsList;
}
not_null<Dialogs::IndexedList*> 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<DialogsRowReplacement> {
return _dialogsRowReplacements.events();
}
void Session::requestNotifySettings(not_null<PeerData*> peer) { void Session::requestNotifySettings(not_null<PeerData*> peer) {
if (peer->notifySettingsUnknown()) { if (peer->notifySettingsUnknown()) {
_session->api().requestNotifySettings( _session->api().requestNotifySettings(

View File

@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "storage/storage_databases.h" #include "storage/storage_databases.h"
#include "chat_helpers/stickers.h" #include "chat_helpers/stickers.h"
#include "dialogs/dialogs_key.h" #include "dialogs/dialogs_key.h"
#include "dialogs/dialogs_indexed_list.h"
#include "data/data_groups.h" #include "data/data_groups.h"
#include "data/data_notify_settings.h" #include "data/data_notify_settings.h"
#include "history/history_location_manager.h" #include "history/history_location_manager.h"
@ -508,6 +509,27 @@ public:
//FeedId defaultFeedId() const; //FeedId defaultFeedId() const;
//rpl::producer<FeedId> defaultFeedIdValue() const; //rpl::producer<FeedId> defaultFeedIdValue() const;
not_null<Dialogs::IndexedList*> chatsList();
not_null<Dialogs::IndexedList*> importantChatsList();
not_null<Dialogs::IndexedList*> contactsList();
not_null<Dialogs::IndexedList*> 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<Dialogs::Row*> old;
Dialogs::Row *now = nullptr;
};
void dialogsRowReplaced(DialogsRowReplacement replacement);
rpl::producer<DialogsRowReplacement> dialogsRowReplacements() const;
void requestNotifySettings(not_null<PeerData*> peer); void requestNotifySettings(not_null<PeerData*> peer);
void applyNotifySetting( void applyNotifySetting(
const MTPNotifyPeer &notifyPeer, const MTPNotifyPeer &notifyPeer,
@ -560,6 +582,8 @@ private:
void setupContactViewsViewer(); void setupContactViewsViewer();
void setupChannelLeavingViewer(); void setupChannelLeavingViewer();
void setupPeerNameViewer();
void setupUserIsContactViewer();
void checkSelfDestructItems(); void checkSelfDestructItems();
int computeUnreadBadge( int computeUnreadBadge(
@ -715,6 +739,7 @@ private:
rpl::event_stream<MegagroupParticipant> _megagroupParticipantRemoved; rpl::event_stream<MegagroupParticipant> _megagroupParticipantRemoved;
rpl::event_stream<MegagroupParticipant> _megagroupParticipantAdded; rpl::event_stream<MegagroupParticipant> _megagroupParticipantAdded;
rpl::event_stream<FolderUpdate> _folderUpdates; rpl::event_stream<FolderUpdate> _folderUpdates;
rpl::event_stream<DialogsRowReplacement> _dialogsRowReplacements;
rpl::event_stream<> _stickersUpdated; rpl::event_stream<> _stickersUpdated;
rpl::event_stream<> _savedGifsUpdated; rpl::event_stream<> _savedGifsUpdated;
@ -735,6 +760,11 @@ private:
int _unreadEntriesFull = 0; int _unreadEntriesFull = 0;
int _unreadEntriesMuted = 0; int _unreadEntriesMuted = 0;
Dialogs::IndexedList _chatsList;
Dialogs::IndexedList _importantChatsList;
Dialogs::IndexedList _contactsList;
Dialogs::IndexedList _contactsNoChatsList;
base::Timer _selfDestructTimer; base::Timer _selfDestructTimer;
std::vector<FullMsgId> _selfDestructItems; std::vector<FullMsgId> _selfDestructItems;

View File

@ -9,11 +9,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "dialogs/dialogs_key.h" #include "dialogs/dialogs_key.h"
#include "dialogs/dialogs_indexed_list.h" #include "dialogs/dialogs_indexed_list.h"
#include "data/data_session.h"
#include "mainwidget.h" #include "mainwidget.h"
#include "auth_session.h" #include "auth_session.h"
#include "styles/style_dialogs.h"
#include "history/history_item.h" #include "history/history_item.h"
#include "history/history.h" #include "history/history.h"
#include "styles/style_dialogs.h" // st::dialogsTextWidthMin
namespace Dialogs { namespace Dialogs {
namespace { namespace {
@ -37,11 +38,20 @@ uint64 PinnedDialogPos(int pinnedIndex) {
} // namespace } // namespace
Entry::Entry(const Key &key) Entry::Entry(not_null<Data::Session*> owner, const Key &key)
: lastItemTextCache(st::dialogsTextWidthMin) : lastItemTextCache(st::dialogsTextWidthMin)
, _owner(owner)
, _key(key) { , _key(key) {
} }
Data::Session &Entry::owner() const {
return *_owner;
}
AuthSession &Entry::session() const {
return _owner->session();
}
void Entry::cachePinnedIndex(int index) { void Entry::cachePinnedIndex(int index) {
if (_pinnedIndex != index) { if (_pinnedIndex != index) {
const auto wasPinned = isPinnedDialog(); const auto wasPinned = isPinnedDialog();
@ -93,7 +103,7 @@ void Entry::updateChatListExistence() {
void Entry::setChatListExistence(bool exists) { void Entry::setChatListExistence(bool exists) {
if (const auto main = App::main()) { if (const auto main = App::main()) {
if (exists && _sortKeyInChatList) { if (exists && _sortKeyInChatList) {
main->createDialog(_key); main->refreshDialog(_key);
updateChatListEntry(); updateChatListEntry();
} else { } else {
main->removeDialog(_key); main->removeDialog(_key);
@ -129,10 +139,10 @@ PositionChange Entry::adjustByPosInChatList(
Mode list, Mode list,
not_null<IndexedList*> indexed) { not_null<IndexedList*> indexed) {
const auto lnk = mainChatListLink(list); const auto lnk = mainChatListLink(list);
const auto movedFrom = lnk->pos(); const auto from = lnk->pos();
indexed->adjustByDate(chatListLinks(list)); indexed->adjustByDate(chatListLinks(list));
const auto movedTo = lnk->pos(); const auto to = lnk->pos();
return { movedFrom, movedTo }; return { from, to };
} }
void Entry::setChatListTimeId(TimeId date) { void Entry::setChatListTimeId(TimeId date) {

View File

@ -11,6 +11,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "dialogs/dialogs_key.h" #include "dialogs/dialogs_key.h"
class AuthSession;
namespace Data {
class Session;
} // namespace Data
namespace Dialogs { namespace Dialogs {
class Row; class Row;
@ -29,17 +35,20 @@ enum class Mode {
}; };
struct PositionChange { struct PositionChange {
int movedFrom; int from = -1;
int movedTo; int to = -1;
}; };
class Entry { class Entry {
public: public:
Entry(const Key &key); Entry(not_null<Data::Session*> owner, const Key &key);
Entry(const Entry &other) = delete; Entry(const Entry &other) = delete;
Entry &operator=(const Entry &other) = delete; Entry &operator=(const Entry &other) = delete;
virtual ~Entry() = default; virtual ~Entry() = default;
Data::Session &owner() const;
AuthSession &session() const;
PositionChange adjustByPosInChatList( PositionChange adjustByPosInChatList(
Mode list, Mode list,
not_null<IndexedList*> indexed); not_null<IndexedList*> indexed);
@ -116,6 +125,7 @@ private:
const RowsByLetter &chatListLinks(Mode list) const; const RowsByLetter &chatListLinks(Mode list) const;
Row *mainChatListLink(Mode list) const; Row *mainChatListLink(Mode list) const;
not_null<Data::Session*> _owner;
Dialogs::Key _key; Dialogs::Key _key;
RowsByLetter _chatListLinks[2]; RowsByLetter _chatListLinks[2];
uint64 _sortKeyInChatList = 0; uint64 _sortKeyInChatList = 0;

View File

@ -26,11 +26,9 @@ RowsByLetter IndexedList::addToEnd(Key key) {
for (const auto ch : key.entry()->chatListFirstLetters()) { for (const auto ch : key.entry()->chatListFirstLetters()) {
auto j = _index.find(ch); auto j = _index.find(ch);
if (j == _index.cend()) { if (j == _index.cend()) {
j = _index.emplace( j = _index.emplace(ch, _sortMode).first;
ch,
std::make_unique<List>(_sortMode)).first;
} }
result.emplace(ch, j->second->addToEnd(key)); result.emplace(ch, j->second.addToEnd(key));
} }
} }
return result; return result;
@ -45,11 +43,9 @@ Row *IndexedList::addByName(Key key) {
for (const auto ch : key.entry()->chatListFirstLetters()) { for (const auto ch : key.entry()->chatListFirstLetters()) {
auto j = _index.find(ch); auto j = _index.find(ch);
if (j == _index.cend()) { if (j == _index.cend()) {
j = _index.emplace( j = _index.emplace(ch, _sortMode).first;
ch,
std::make_unique<List>(_sortMode)).first;
} }
j->second->addByName(key); j->second.addByName(key);
} }
return result; return result;
} }
@ -60,7 +56,7 @@ void IndexedList::adjustByDate(const RowsByLetter &links) {
_list.adjustByDate(row); _list.adjustByDate(row);
} else { } else {
if (auto it = _index.find(ch); it != _index.cend()) { 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)) { if (_list.moveToTop(key)) {
for (const auto ch : key.entry()->chatListFirstLetters()) { for (const auto ch : key.entry()->chatListFirstLetters()) {
if (auto it = _index.find(ch); it != _index.cend()) { 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 { } else {
toRemove.erase(j); toRemove.erase(j);
if (auto it = _index.find(ch); it != _index.cend()) { if (auto it = _index.find(ch); it != _index.cend()) {
it->second->adjustByName(key); it->second.adjustByName(key);
} }
} }
} }
for (auto ch : toRemove) { for (auto ch : toRemove) {
if (auto it = _index.find(ch); it != _index.cend()) { if (auto it = _index.find(ch); it != _index.cend()) {
it->second->del(key, mainRow); it->second.del(key, mainRow);
} }
} }
if (!toAdd.empty()) { if (!toAdd.empty()) {
for (auto ch : toAdd) { for (auto ch : toAdd) {
auto j = _index.find(ch); auto j = _index.find(ch);
if (j == _index.cend()) { if (j == _index.cend()) {
j = _index.emplace( j = _index.emplace(ch, _sortMode).first;
ch,
std::make_unique<List>(_sortMode)).first;
} }
j->second->addByName(key); j->second.addByName(key);
} }
} }
} }
@ -177,17 +171,15 @@ void IndexedList::adjustNames(
history->removeChatListEntryByLetter(list, ch); history->removeChatListEntryByLetter(list, ch);
} }
if (auto it = _index.find(ch); it != _index.cend()) { if (auto it = _index.find(ch); it != _index.cend()) {
it->second->del(key, mainRow); it->second.del(key, mainRow);
} }
} }
for (auto ch : toAdd) { for (auto ch : toAdd) {
auto j = _index.find(ch); auto j = _index.find(ch);
if (j == _index.cend()) { if (j == _index.cend()) {
j = _index.emplace( j = _index.emplace(ch, _sortMode).first;
ch,
std::make_unique<List>(_sortMode)).first;
} }
auto row = j->second->addToEnd(key); auto row = j->second.addToEnd(key);
if (_sortMode == SortMode::Date) { if (_sortMode == SortMode::Date) {
history->addChatListEntryByLetter(list, ch, row); history->addChatListEntryByLetter(list, ch, row);
} }
@ -198,7 +190,7 @@ void IndexedList::del(Key key, Row *replacedBy) {
if (_list.del(key, replacedBy)) { if (_list.del(key, replacedBy)) {
for (const auto ch : key.entry()->chatListFirstLetters()) { for (const auto ch : key.entry()->chatListFirstLetters()) {
if (auto it = _index.find(ch); it != _index.cend()) { if (auto it = _index.find(ch); it != _index.cend()) {
it->second->del(key, replacedBy); it->second.del(key, replacedBy);
} }
} }
} }

View File

@ -44,17 +44,15 @@ public:
return _list; return _list;
} }
const List *filtered(QChar ch) const { const List *filtered(QChar ch) const {
if (auto it = _index.find(ch); it != _index.cend()) { const auto i = _index.find(ch);
return it->second.get(); return (i != _index.end()) ? &i->second : nullptr;
}
return &_empty;
} }
~IndexedList(); ~IndexedList();
// Part of List interface is duplicated here for all() list. // Part of List interface is duplicated here for all() list.
int size() const { return all().size(); } 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); } bool contains(Key key) const { return all().contains(key); }
Row *getRow(Key key) const { return all().getRow(key); } Row *getRow(Key key) const { return all().getRow(key); }
Row *rowAtY(int32 y, int32 h) const { return all().rowAtY(y, h); } Row *rowAtY(int32 y, int32 h) const { return all().rowAtY(y, h); }
@ -83,9 +81,9 @@ private:
not_null<History*> history, not_null<History*> history,
const base::flat_set<QChar> &oldChars); const base::flat_set<QChar> &oldChars);
SortMode _sortMode; SortMode _sortMode = SortMode();
List _list, _empty; List _list, _empty;
base::flat_map<QChar, std::unique_ptr<List>> _index; base::flat_map<QChar, List> _index;
}; };

View File

@ -66,12 +66,9 @@ struct DialogsInner::PeerSearchResult {
Dialogs::RippleRow row; Dialogs::RippleRow row;
}; };
DialogsInner::DialogsInner(QWidget *parent, not_null<Window::Controller*> controller, QWidget *main) DialogsInner::DialogsInner(QWidget *parent, not_null<Window::Controller*> controller)
: RpWidget(parent) : RpWidget(parent)
, _controller(controller) , _controller(controller)
, _dialogs(std::make_unique<Dialogs::IndexedList>(Dialogs::SortMode::Date))
, _contactsNoDialogs(std::make_unique<Dialogs::IndexedList>(Dialogs::SortMode::Name))
, _contacts(std::make_unique<Dialogs::IndexedList>(Dialogs::SortMode::Name))
, _pinnedShiftAnimation([=](crl::time now) { , _pinnedShiftAnimation([=](crl::time now) {
return pinnedShiftAnimationCallback(now); return pinnedShiftAnimationCallback(now);
}) })
@ -84,25 +81,28 @@ DialogsInner::DialogsInner(QWidget *parent, not_null<Window::Controller*> contro
#endif // OS_MAC_OLD #endif // OS_MAC_OLD
if (Global::DialogsModeEnabled()) { if (Global::DialogsModeEnabled()) {
_dialogsImportant = std::make_unique<Dialogs::IndexedList>(Dialogs::SortMode::Date);
_importantSwitch = std::make_unique<ImportantSwitch>(); _importantSwitch = std::make_unique<ImportantSwitch>();
} }
connect(main, SIGNAL(dialogRowReplaced(Dialogs::Row*, Dialogs::Row*)), this, SLOT(onDialogRowReplaced(Dialogs::Row*, Dialogs::Row*)));
connect(_addContactLnk, SIGNAL(clicked()), App::wnd(), SLOT(onShowAddContact())); connect(_addContactLnk, SIGNAL(clicked()), App::wnd(), SLOT(onShowAddContact()));
_cancelSearchInChat->setClickedCallback([this] { cancelSearchInChat(); }); _cancelSearchInChat->setClickedCallback([this] { cancelSearchInChat(); });
_cancelSearchInChat->hide(); _cancelSearchInChat->hide();
_cancelSearchFromUser->setClickedCallback([this] { searchFromUserChanged.notify(nullptr); }); _cancelSearchFromUser->setClickedCallback([this] { searchFromUserChanged.notify(nullptr); });
_cancelSearchFromUser->hide(); _cancelSearchFromUser->hide();
subscribe(Auth().downloaderTaskFinished(), [this] { update(); }); subscribe(session().downloaderTaskFinished(), [this] { update(); });
subscribe(Auth().data().contactsLoaded(), [this](bool) { refresh(); }); subscribe(session().data().contactsLoaded(), [this](bool) { refresh(); });
Auth().data().itemRemoved( session().data().itemRemoved(
) | rpl::start_with_next( ) | rpl::start_with_next([=](not_null<const HistoryItem*> item) {
[this](auto item) { itemRemoved(item); }, itemRemoved(item);
lifetime()); }, 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) { ) | rpl::start_with_next([=](auto item) {
const auto history = item->history(); const auto history = item->history();
if (history->textCachedFor == item) { if (history->textCachedFor == item) {
@ -115,7 +115,7 @@ DialogsInner::DialogsInner(QWidget *parent, not_null<Window::Controller*> contro
} }
}, lifetime()); }, lifetime());
Auth().data().sendActionAnimationUpdated( session().data().sendActionAnimationUpdated(
) | rpl::start_with_next([=]( ) | rpl::start_with_next([=](
const Data::Session::SendActionAnimationUpdate &update) { const Data::Session::SendActionAnimationUpdate &update) {
using RowPainter = Dialogs::Layout::RowPainter; using RowPainter = Dialogs::Layout::RowPainter;
@ -148,15 +148,16 @@ DialogsInner::DialogsInner(QWidget *parent, not_null<Window::Controller*> contro
stopReorderPinned(); stopReorderPinned();
} }
if (update.flags & UpdateFlag::NameChanged) { if (update.flags & UpdateFlag::NameChanged) {
handlePeerNameChange(update.peer, update.oldNameFirstLetters); this->update();
} }
if (update.flags & (UpdateFlag::PhotoChanged | UpdateFlag::UserOccupiedChanged)) { if (update.flags & (UpdateFlag::PhotoChanged | UpdateFlag::UserOccupiedChanged)) {
this->update(); this->update();
emit App::main()->dialogsUpdated(); emit App::main()->dialogsUpdated();
} }
if (update.flags & UpdateFlag::UserIsContact) { if (update.flags & UpdateFlag::UserIsContact) {
if (const auto user = update.peer->asUser()) { if (update.peer->isUser()) {
userIsContactUpdated(user); // contactsNoChatsList could've changed.
Ui::PostponeCall(this, [=] { refresh(); });
} }
} }
if (update.flags & UpdateFlag::MigrationChanged) { if (update.flags & UpdateFlag::MigrationChanged) {
@ -165,7 +166,7 @@ DialogsInner::DialogsInner(QWidget *parent, not_null<Window::Controller*> contro
} }
} }
})); }));
Auth().data().folderUpdated( session().data().folderUpdated(
) | rpl::start_with_next([=](const Data::FolderUpdate &update) { ) | rpl::start_with_next([=](const Data::FolderUpdate &update) {
updateDialogRow({ update.folder, FullMsgId() }); updateDialogRow({ update.folder, FullMsgId() });
}, lifetime()); }, lifetime());
@ -183,6 +184,10 @@ DialogsInner::DialogsInner(QWidget *parent, not_null<Window::Controller*> contro
setupShortcuts(); setupShortcuts();
} }
AuthSession &DialogsInner::session() const {
return _controller->session();
}
void DialogsInner::handleChatMigration(not_null<ChatData*> chat) { void DialogsInner::handleChatMigration(not_null<ChatData*> chat) {
const auto channel = chat->migrateTo(); const auto channel = chat->migrateTo();
if (!channel) { if (!channel) {
@ -200,7 +205,7 @@ void DialogsInner::handleChatMigration(not_null<ChatData*> chat) {
} }
int DialogsInner::dialogsOffset() const { int DialogsInner::dialogsOffset() const {
return _dialogsImportant ? st::dialogsImportantBarHeight : 0; return _importantSwitch ? st::dialogsImportantBarHeight : 0;
} }
int DialogsInner::proxyPromotedCount() const { int DialogsInner::proxyPromotedCount() const {
@ -256,7 +261,7 @@ void DialogsInner::paintEvent(QPaintEvent *e) {
if (_state == State::Default) { if (_state == State::Default) {
auto rows = shownDialogs(); auto rows = shownDialogs();
auto dialogsClip = r; auto dialogsClip = r;
if (_dialogsImportant) { if (_importantSwitch) {
auto selected = isPressed() ? _importantSwitchPressed : _importantSwitchSelected; auto selected = isPressed() ? _importantSwitchPressed : _importantSwitchSelected;
Dialogs::Layout::paintImportantSwitch(p, Global::DialogsMode(), fullWidth, selected); Dialogs::Layout::paintImportantSwitch(p, Global::DialogsMode(), fullWidth, selected);
dialogsClip.translate(0, -st::dialogsImportantBarHeight); dialogsClip.translate(0, -st::dialogsImportantBarHeight);
@ -347,7 +352,7 @@ void DialogsInner::paintEvent(QPaintEvent *e) {
p.fillRect(dialogsClip, st::dialogsBg); p.fillRect(dialogsClip, st::dialogsBg);
p.setFont(st::noContactsFont); p.setFont(st::noContactsFont);
p.setPen(st::noContactsColor); 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) { } else if (_state == State::Filtered) {
if (!_hashtagResults.empty()) { if (!_hashtagResults.empty()) {
@ -741,7 +746,7 @@ void DialogsInner::selectByMouse(QPoint globalPosition) {
int w = width(), mouseY = local.y(); int w = width(), mouseY = local.y();
clearIrrelevantState(); clearIrrelevantState();
if (_state == State::Default) { if (_state == State::Default) {
auto importantSwitchSelected = (_dialogsImportant && mouseY >= 0 && mouseY < dialogsOffset()); auto importantSwitchSelected = (_importantSwitch && mouseY >= 0 && mouseY < dialogsOffset());
mouseY -= dialogsOffset(); mouseY -= dialogsOffset();
auto selected = importantSwitchSelected ? nullptr : shownDialogs()->rowAtY(mouseY, st::dialogsRowHeight); auto selected = importantSwitchSelected ? nullptr : shownDialogs()->rowAtY(mouseY, st::dialogsRowHeight);
if (_selected != selected || _importantSwitchSelected != importantSwitchSelected) { if (_selected != selected || _importantSwitchSelected != importantSwitchSelected) {
@ -872,7 +877,7 @@ void DialogsInner::checkReorderPinnedStart(QPoint localPosition) {
if (updateReorderIndexGetCount() < 2) { if (updateReorderIndexGetCount() < 2) {
_dragging = nullptr; _dragging = nullptr;
} else { } else {
_pinnedOrder = Auth().data().pinnedDialogsOrder(); _pinnedOrder = session().data().pinnedDialogsOrder();
_pinnedRows[_draggingIndex].yadd = anim::value(0, localPosition.y() - _dragStart.y()); _pinnedRows[_draggingIndex].yadd = anim::value(0, localPosition.y() - _dragStart.y());
_pinnedRows[_draggingIndex].animStartTime = crl::now(); _pinnedRows[_draggingIndex].animStartTime = crl::now();
_pinnedShiftAnimation.start(); _pinnedShiftAnimation.start();
@ -913,7 +918,7 @@ int DialogsInner::countPinnedIndex(Dialogs::Row *ofRow) {
} }
void DialogsInner::savePinnedOrder() { void DialogsInner::savePinnedOrder() {
const auto &newOrder = Auth().data().pinnedDialogsOrder(); const auto &newOrder = session().data().pinnedDialogsOrder();
if (newOrder.size() != _pinnedOrder.size()) { if (newOrder.size() != _pinnedOrder.size()) {
return; // Something has changed in the set of pinned chats. 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. return; // Something has changed in the set of pinned chats.
} }
} }
Auth().api().savePinnedOrder(); session().api().savePinnedOrder();
} }
void DialogsInner::finishReorderPinned() { 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); _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 *oldRow,
Dialogs::Row *newRow) { Dialogs::Row *newRow) {
if (_state == State::Filtered) { 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 (const auto history = key.history()) {
if (history->peer->loadedStatus if (history->peer->loadedStatus
!= PeerData::LoadedStatus::FullLoaded) { != PeerData::LoadedStatus::FullLoaded) {
LOG(("API Error: " LOG(("API Error: "
"DialogsInner::createDialog() called for a non loaded peer!" "DialogsInner::refreshDialog() called for a non loaded peer!"
)); ));
return; return;
} }
} }
const auto entry = key.entry(); const auto result = session().data().refreshChatListEntry(key);
auto creating = !entry->inChatList(Dialogs::Mode::All); const auto changed = (Global::DialogsMode() == Dialogs::Mode::Important)
if (creating) { ? result.importantChanged
const auto mainRow = entry->addToChatList( : result.changed;
Dialogs::Mode::All, const auto moved = (Global::DialogsMode() == Dialogs::Mode::Important)
_dialogs.get()); ? result.importantMoved
_contactsNoDialogs->del(key, mainRow); : result.moved;
}
if (_dialogsImportant
&& !entry->inChatList(Dialogs::Mode::Important)
&& entry->toImportant()) {
if (Global::DialogsMode() == Dialogs::Mode::Important) {
creating = true;
}
entry->addToChatList(
Dialogs::Mode::Important,
_dialogsImportant.get());
}
auto changed = entry->adjustByPosInChatList( const auto rowHeight = st::dialogsRowHeight;
Dialogs::Mode::All, const auto from = dialogsOffset() + moved.from * rowHeight;
_dialogs.get()); const auto to = dialogsOffset() + moved.to * rowHeight;
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;
if (!_dragging && from != to) { if (!_dragging && from != to) {
// Don't jump in chats list scroll position while dragging. // Don't jump in chats list scroll position while dragging.
emit dialogMoved(from, to); emit dialogMoved(from, to);
} }
if (creating) { if (changed) {
refresh(); refresh();
} else if (_state == State::Default && from != to) { } 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) { if (_pressed && _pressed->key() == key) {
setPressed(nullptr); setPressed(nullptr);
} }
const auto entry = key.entry(); session().data().removeChatListEntry(key);
entry->removeFromChatList(
Dialogs::Mode::All,
_dialogs.get());
if (_dialogsImportant) {
entry->removeFromChatList(
Dialogs::Mode::Important,
_dialogsImportant.get());
}
if (const auto history = key.history()) { if (const auto history = key.history()) {
Auth().notifications().clearFromHistory(history); session().notifications().clearFromHistory(history);
Local::removeSavedPeer(history->peer); 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); const auto i = ranges::find(_filterResults, key, &Dialogs::Row::key);
if (i != _filterResults.end()) { if (i != _filterResults.end()) {
if (_filteredSelected == (i - _filterResults.begin()) if (_filteredSelected == (i - _filterResults.begin())
@ -1495,8 +1462,8 @@ void DialogsInner::updateSelectedRow(Dialogs::Key key) {
Dialogs::IndexedList *DialogsInner::shownDialogs() const { Dialogs::IndexedList *DialogsInner::shownDialogs() const {
return (Global::DialogsMode() == Dialogs::Mode::Important) return (Global::DialogsMode() == Dialogs::Mode::Important)
? _dialogsImportant.get() ? session().data().importantChatsList()
: _dialogs.get(); : session().data().chatsList();
} }
void DialogsInner::leaveEventHook(QEvent *e) { void DialogsInner::leaveEventHook(QEvent *e) {
@ -1527,11 +1494,11 @@ void DialogsInner::clearSelection() {
} }
void DialogsInner::fillSupportSearchMenu(not_null<Ui::PopupMenu*> menu) { void DialogsInner::fillSupportSearchMenu(not_null<Ui::PopupMenu*> menu) {
const auto all = Auth().settings().supportAllSearchResults(); const auto all = session().settings().supportAllSearchResults();
const auto text = all ? "Only one from chat" : "Show all messages"; const auto text = all ? "Only one from chat" : "Show all messages";
menu->addAction(text, [=] { menu->addAction(text, [=] {
Auth().settings().setSupportAllSearchResults(!all); session().settings().setSupportAllSearchResults(!all);
Auth().saveSettingsDelayed(); session().saveSettingsDelayed();
}); });
} }
@ -1550,7 +1517,7 @@ void DialogsInner::contextMenuEvent(QContextMenuEvent *e) {
} else if (_state == State::Filtered) { } else if (_state == State::Filtered) {
if (base::in_range(_filteredSelected, 0, _filterResults.size())) { if (base::in_range(_filteredSelected, 0, _filterResults.size())) {
return { _filterResults[_filteredSelected]->key(), FullMsgId() }; return { _filterResults[_filteredSelected]->key(), FullMsgId() };
} else if (Auth().supportMode() } else if (session().supportMode()
&& base::in_range(_searchedSelected, 0, _searchResults.size())) { && base::in_range(_searchedSelected, 0, _searchResults.size())) {
return { return {
_searchResults[_searchedSelected]->item()->history(), _searchResults[_searchedSelected]->item()->history(),
@ -1568,7 +1535,7 @@ void DialogsInner::contextMenuEvent(QContextMenuEvent *e) {
} }
_menu = base::make_unique_q<Ui::PopupMenu>(this); _menu = base::make_unique_q<Ui::PopupMenu>(this);
if (Auth().supportMode() && row.fullId) { if (session().supportMode() && row.fullId) {
fillSupportSearchMenu(_menu.get()); fillSupportSearchMenu(_menu.get());
} else if (const auto history = row.key.history()) { } else if (const auto history = row.key.history()) {
Window::FillPeerMenu( Window::FillPeerMenu(
@ -1611,21 +1578,6 @@ void DialogsInner::onParentGeometryChanged() {
} }
} }
void DialogsInner::handlePeerNameChange(
not_null<PeerData*> peer,
const base::flat_set<QChar> &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) { void DialogsInner::applyFilterUpdate(QString newFilter, bool force) {
const auto mentionsSearch = (newFilter == qstr("@")); const auto mentionsSearch = (newFilter == qstr("@"));
const auto words = mentionsSearch const auto words = mentionsSearch
@ -1645,10 +1597,10 @@ void DialogsInner::applyFilterUpdate(QString newFilter, bool force) {
_filterResultsGlobal.clear(); _filterResultsGlobal.clear();
if (!_searchInChat && !words.isEmpty()) { if (!_searchInChat && !words.isEmpty()) {
const Dialogs::List *toFilter = nullptr; const Dialogs::List *toFilter = nullptr;
if (!_dialogs->isEmpty()) { if (const auto list = session().data().chatsList(); !list->empty()) {
for (fi = fb; fi != fe; ++fi) { for (fi = fb; fi != fe; ++fi) {
auto found = _dialogs->filtered(fi->at(0)); const auto found = list->filtered(fi->at(0));
if (found->empty()) { if (!found || found->empty()) {
toFilter = nullptr; toFilter = nullptr;
break; break;
} }
@ -1658,10 +1610,10 @@ void DialogsInner::applyFilterUpdate(QString newFilter, bool force) {
} }
} }
const Dialogs::List *toFilterContacts = nullptr; const Dialogs::List *toFilterContacts = nullptr;
if (!_contactsNoDialogs->isEmpty()) { if (const auto list = session().data().contactsNoChatsList(); !list->empty()) {
for (fi = fb; fi != fe; ++fi) { for (fi = fb; fi != fe; ++fi) {
auto found = _contactsNoDialogs->filtered(fi->at(0)); const auto found = list->filtered(fi->at(0));
if (found->empty()) { if (!found || found->empty()) {
toFilterContacts = nullptr; toFilterContacts = nullptr;
break; break;
} }
@ -1843,7 +1795,7 @@ void DialogsInner::applyDialog(const MTPDdialog &dialog) {
return; return;
} }
const auto history = Auth().data().history(peerId); const auto history = session().data().history(peerId);
history->applyDialog(dialog); history->applyDialog(dialog);
if (!history->useProxyPromotion() && !history->isPinnedDialog()) { if (!history->useProxyPromotion() && !history->isPinnedDialog()) {
@ -1852,7 +1804,6 @@ void DialogsInner::applyDialog(const MTPDdialog &dialog) {
addSavedPeersAfter(ParseDateTime(date)); addSavedPeersAfter(ParseDateTime(date));
} }
} }
_contactsNoDialogs->del(history);
if (const auto from = history->peer->migrateFrom()) { if (const auto from = history->peer->migrateFrom()) {
if (const auto historyFrom = from->owner().historyLoaded(from)) { if (const auto historyFrom = from->owner().historyLoaded(from)) {
removeDialog(historyFrom); removeDialog(historyFrom);
@ -1865,7 +1816,7 @@ void DialogsInner::applyDialog(const MTPDdialog &dialog) {
} }
void DialogsInner::applyFolderDialog(const MTPDdialogFolder &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); folder->applyDialog(dialog);
if (!folder->useProxyPromotion() && !folder->isPinnedDialog()) { if (!folder->useProxyPromotion() && !folder->isPinnedDialog()) {
@ -1883,9 +1834,8 @@ void DialogsInner::addSavedPeersAfter(const QDateTime &date) {
const auto lastPeer = saved.last(); const auto lastPeer = saved.last();
saved.remove(lastDate, lastPeer); saved.remove(lastDate, lastPeer);
const auto history = Auth().data().history(lastPeer); const auto history = session().data().history(lastPeer);
history->setChatListTimeId(ServerTimeFromParsed(lastDate)); history->setChatListTimeId(ServerTimeFromParsed(lastDate));
_contactsNoDialogs->del(history);
} }
} }
@ -1894,8 +1844,8 @@ void DialogsInner::addAllSavedPeers() {
} }
bool DialogsInner::uniqueSearchResults() const { bool DialogsInner::uniqueSearchResults() const {
return Auth().supportMode() return session().supportMode()
&& !Auth().settings().supportAllSearchResults() && !session().settings().supportAllSearchResults()
&& !_searchInChat; && !_searchInChat;
} }
@ -1944,9 +1894,9 @@ bool DialogsInner::searchReceived(
auto msgId = IdFromMessage(message); auto msgId = IdFromMessage(message);
auto peerId = PeerFromMessage(message); auto peerId = PeerFromMessage(message);
auto lastDate = DateFromMessage(message); auto lastDate = DateFromMessage(message);
if (const auto peer = Auth().data().peerLoaded(peerId)) { if (const auto peer = session().data().peerLoaded(peerId)) {
if (lastDate) { if (lastDate) {
const auto item = Auth().data().addNewMessage( const auto item = session().data().addNewMessage(
message, message,
NewMessageExisting); NewMessageExisting);
const auto history = item->history(); const auto history = item->history();
@ -2015,8 +1965,8 @@ void DialogsInner::peerSearchReceived(
_peerSearchQuery = query.toLower().trimmed(); _peerSearchQuery = query.toLower().trimmed();
_peerSearchResults.clear(); _peerSearchResults.clear();
_peerSearchResults.reserve(result.size()); _peerSearchResults.reserve(result.size());
for (const auto &mtpPeer : my) { for (const auto &mtpPeer : my) {
if (const auto peer = Auth().data().peerLoaded(peerFromMTP(mtpPeer))) { if (const auto peer = session().data().peerLoaded(peerFromMTP(mtpPeer))) {
if (alreadyAdded(peer)) { if (alreadyAdded(peer)) {
continue; continue;
} }
@ -2034,7 +1984,7 @@ void DialogsInner::peerSearchReceived(
} }
} }
for (const auto &mtpPeer : result) { 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 (const auto history = peer->owner().historyLoaded(peer)) {
if (history->inChatList(Dialogs::Mode::All)) { if (history->inChatList(Dialogs::Mode::All)) {
continue; // skip existing chats continue; // skip existing chats
@ -2051,81 +2001,19 @@ void DialogsInner::peerSearchReceived(
refresh(); refresh();
} }
void DialogsInner::userIsContactUpdated(not_null<UserData*> user) { void DialogsInner::notify_historyMuteUpdated(History *history) {
if (user->loadedStatus != PeerData::FullLoaded) { if (!_importantSwitch || !history->inChatList(Dialogs::Mode::All)) {
LOG(("API Error: "
"notify_userIsContactChanged() called for a not loaded user!"));
return; return;
} }
if (user->contactStatus() == UserData::ContactStatus::Contact) { refreshDialog(history);
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);
}
}
} }
void DialogsInner::refresh(bool toTop) { void DialogsInner::refresh(bool toTop) {
int32 h = 0; int32 h = 0;
if (_state == State::Default) { if (_state == State::Default) {
if (shownDialogs()->isEmpty()) { if (shownDialogs()->empty()) {
h = st::noContactsHeight; h = st::noContactsHeight;
if (Auth().data().contactsLoaded().value()) { if (session().data().contactsLoaded().value()) {
if (_addContactLnk->isHidden()) _addContactLnk->show(); if (_addContactLnk->isHidden()) _addContactLnk->show();
} else { } else {
if (!_addContactLnk->isHidden()) _addContactLnk->hide(); if (!_addContactLnk->isHidden()) _addContactLnk->hide();
@ -2267,16 +2155,16 @@ void DialogsInner::selectSkip(int32 direction) {
clearMouseSelection(); clearMouseSelection();
if (_state == State::Default) { if (_state == State::Default) {
if (_importantSwitchSelected) { if (_importantSwitchSelected) {
if (!shownDialogs()->isEmpty() && direction > 0) { if (!shownDialogs()->empty() && direction > 0) {
_selected = *shownDialogs()->cbegin(); _selected = *shownDialogs()->cbegin();
_importantSwitchSelected = false; _importantSwitchSelected = false;
} else { } else {
return; return;
} }
} else if (!_selected) { } else if (!_selected) {
if (_dialogsImportant) { if (_importantSwitch) {
_importantSwitchSelected = true; _importantSwitchSelected = true;
} else if (!shownDialogs()->isEmpty() && direction > 0) { } else if (!shownDialogs()->empty() && direction > 0) {
_selected = *shownDialogs()->cbegin(); _selected = *shownDialogs()->cbegin();
} else { } else {
return; return;
@ -2290,7 +2178,7 @@ void DialogsInner::selectSkip(int32 direction) {
auto prev = shownDialogs()->cfind(_selected); auto prev = shownDialogs()->cfind(_selected);
if (prev != shownDialogs()->cbegin()) { if (prev != shownDialogs()->cbegin()) {
_selected = *(--prev); _selected = *(--prev);
} else if (_dialogsImportant) { } else if (_importantSwitch) {
_importantSwitchSelected = true; _importantSwitchSelected = true;
_selected = nullptr; _selected = nullptr;
} }
@ -2382,7 +2270,7 @@ void DialogsInner::selectSkipPage(int32 pixels, int32 direction) {
int toSkip = pixels / int(st::dialogsRowHeight); int toSkip = pixels / int(st::dialogsRowHeight);
if (_state == State::Default) { if (_state == State::Default) {
if (!_selected) { if (!_selected) {
if (direction > 0 && !shownDialogs()->isEmpty()) { if (direction > 0 && !shownDialogs()->empty()) {
_selected = *shownDialogs()->cbegin(); _selected = *shownDialogs()->cbegin();
_importantSwitchSelected = false; _importantSwitchSelected = false;
} else { } else {
@ -2397,7 +2285,7 @@ void DialogsInner::selectSkipPage(int32 pixels, int32 direction) {
for (auto i = shownDialogs()->cfind(_selected), b = shownDialogs()->cbegin(); i != b && (toSkip--);) { for (auto i = shownDialogs()->cfind(_selected), b = shownDialogs()->cbegin(); i != b && (toSkip--);) {
_selected = *(--i); _selected = *(--i);
} }
if (toSkip && _dialogsImportant) { if (toSkip && _importantSwitch) {
_importantSwitchSelected = true; _importantSwitchSelected = true;
_selected = nullptr; _selected = nullptr;
} }
@ -2417,7 +2305,7 @@ void DialogsInner::loadPeerPhotos() {
auto yFrom = _visibleTop; auto yFrom = _visibleTop;
auto yTo = _visibleTop + (_visibleBottom - _visibleTop) * (PreloadHeightsCount + 1); auto yTo = _visibleTop + (_visibleBottom - _visibleTop) * (PreloadHeightsCount + 1);
Auth().downloader().clearPriorities(); session().downloader().clearPriorities();
if (_state == State::Default) { if (_state == State::Default) {
auto otherStart = shownDialogs()->size() * st::dialogsRowHeight; auto otherStart = shownDialogs()->size() * st::dialogsRowHeight;
if (yFrom < otherStart) { if (yFrom < otherStart) {
@ -2469,7 +2357,7 @@ void DialogsInner::loadPeerPhotos() {
bool DialogsInner::switchImportantChats() { bool DialogsInner::switchImportantChats() {
if (!_importantSwitchSelected if (!_importantSwitchSelected
|| !_dialogsImportant || !_importantSwitch
|| (_state != State::Default)) { || (_state != State::Default)) {
return false; return false;
} }
@ -2531,7 +2419,7 @@ DialogsInner::ChosenRow DialogsInner::computeChosenRow() const {
}; };
} else if (base::in_range(_peerSearchSelected, 0, _peerSearchResults.size())) { } else if (base::in_range(_peerSearchSelected, 0, _peerSearchResults.size())) {
return { return {
Auth().data().history(_peerSearchResults[_peerSearchSelected]->peer), session().data().history(_peerSearchResults[_peerSearchSelected]->peer),
Data::UnreadMessagePosition Data::UnreadMessagePosition
}; };
} else if (base::in_range(_searchedSelected, 0, _searchResults.size())) { } else if (base::in_range(_searchedSelected, 0, _searchResults.size())) {
@ -2578,7 +2466,7 @@ bool DialogsInner::chooseRow() {
// HistoryFeed::Memento(feed, chosen.message), // HistoryFeed::Memento(feed, chosen.message),
// Window::SectionShow::Way::ClearStack); // Window::SectionShow::Way::ClearStack);
} }
if (openSearchResult && !Auth().supportMode()) { if (openSearchResult && !session().supportMode()) {
emit clearSearchQuery(); emit clearSearchQuery();
} }
updateSelectedRow(); updateSelectedRow();
@ -2595,24 +2483,6 @@ bool DialogsInner::chooseRow() {
return false; 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( Dialogs::RowDescriptor DialogsInner::chatListEntryBefore(
const Dialogs::RowDescriptor &which) const { const Dialogs::RowDescriptor &which) const {
if (!which.key) { if (!which.key) {
@ -2654,7 +2524,7 @@ Dialogs::RowDescriptor DialogsInner::chatListEntryBefore(
FullMsgId(NoChannel, ShowAtUnreadMsgId)); FullMsgId(NoChannel, ShowAtUnreadMsgId));
} }
return Dialogs::RowDescriptor( return Dialogs::RowDescriptor(
Auth().data().history(_peerSearchResults.back()->peer), session().data().history(_peerSearchResults.back()->peer),
FullMsgId(NoChannel, ShowAtUnreadMsgId)); 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) { for (auto b = _peerSearchResults.cbegin(), i = b + 1, e = _peerSearchResults.cend(); i != e; ++i) {
if ((*i)->peer == whichHistory->peer) { if ((*i)->peer == whichHistory->peer) {
return Dialogs::RowDescriptor( return Dialogs::RowDescriptor(
Auth().data().history((*(i - 1))->peer), session().data().history((*(i - 1))->peer),
FullMsgId(NoChannel, ShowAtUnreadMsgId)); FullMsgId(NoChannel, ShowAtUnreadMsgId));
} }
} }
@ -2727,7 +2597,7 @@ Dialogs::RowDescriptor DialogsInner::chatListEntryAfter(
++i; ++i;
if (i != e) { if (i != e) {
return Dialogs::RowDescriptor( return Dialogs::RowDescriptor(
Auth().data().history((*i)->peer), session().data().history((*i)->peer),
FullMsgId(NoChannel, ShowAtUnreadMsgId)); FullMsgId(NoChannel, ShowAtUnreadMsgId));
} else if (!_searchResults.empty()) { } else if (!_searchResults.empty()) {
return Dialogs::RowDescriptor( return Dialogs::RowDescriptor(
@ -2746,7 +2616,7 @@ Dialogs::RowDescriptor DialogsInner::chatListEntryAfter(
FullMsgId(NoChannel, ShowAtUnreadMsgId)); FullMsgId(NoChannel, ShowAtUnreadMsgId));
} else if (!_peerSearchResults.empty()) { } else if (!_peerSearchResults.empty()) {
return Dialogs::RowDescriptor( return Dialogs::RowDescriptor(
Auth().data().history(_peerSearchResults.front()->peer), session().data().history(_peerSearchResults.front()->peer),
FullMsgId(NoChannel, ShowAtUnreadMsgId)); FullMsgId(NoChannel, ShowAtUnreadMsgId));
} else if (!_searchResults.empty()) { } else if (!_searchResults.empty()) {
return Dialogs::RowDescriptor( return Dialogs::RowDescriptor(
@ -2774,7 +2644,7 @@ Dialogs::RowDescriptor DialogsInner::chatListEntryFirst() const {
FullMsgId(NoChannel, ShowAtUnreadMsgId)); FullMsgId(NoChannel, ShowAtUnreadMsgId));
} else if (!_peerSearchResults.empty()) { } else if (!_peerSearchResults.empty()) {
return Dialogs::RowDescriptor( return Dialogs::RowDescriptor(
Auth().data().history(_peerSearchResults.front()->peer), session().data().history(_peerSearchResults.front()->peer),
FullMsgId(NoChannel, ShowAtUnreadMsgId)); FullMsgId(NoChannel, ShowAtUnreadMsgId));
} else if (!_searchResults.empty()) { } else if (!_searchResults.empty()) {
return Dialogs::RowDescriptor( return Dialogs::RowDescriptor(
@ -2799,7 +2669,7 @@ Dialogs::RowDescriptor DialogsInner::chatListEntryLast() const {
_searchResults.back()->item()->fullId()); _searchResults.back()->item()->fullId());
} else if (!_peerSearchResults.empty()) { } else if (!_peerSearchResults.empty()) {
return Dialogs::RowDescriptor( return Dialogs::RowDescriptor(
Auth().data().history(_peerSearchResults.back()->peer), session().data().history(_peerSearchResults.back()->peer),
FullMsgId(NoChannel, ShowAtUnreadMsgId)); FullMsgId(NoChannel, ShowAtUnreadMsgId));
} else if (!_filterResults.empty()) { } else if (!_filterResults.empty()) {
return Dialogs::RowDescriptor( return Dialogs::RowDescriptor(
@ -2809,18 +2679,6 @@ Dialogs::RowDescriptor DialogsInner::chatListEntryLast() const {
return Dialogs::RowDescriptor(); 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 { int32 DialogsInner::lastSearchDate() const {
return _lastSearchDate; return _lastSearchDate;
} }
@ -2883,8 +2741,8 @@ void DialogsInner::setupShortcuts() {
request->check(Command::ChatLast) && request->handle([=] { request->check(Command::ChatLast) && request->handle([=] {
return jumpToDialogRow(last); return jumpToDialogRow(last);
}); });
request->check(Command::ChatSelf) && request->handle([] { request->check(Command::ChatSelf) && request->handle([=] {
App::main()->choosePeer(Auth().userPeerId(), ShowAtUnreadMsgId); App::main()->choosePeer(session().userPeerId(), ShowAtUnreadMsgId);
return true; return true;
}); });
@ -2906,7 +2764,7 @@ void DialogsInner::setupShortcuts() {
return jumpToDialogRow({ row->key(), FullMsgId() }); return jumpToDialogRow({ row->key(), FullMsgId() });
}); });
} }
if (Auth().supportMode() && row.key.history()) { if (session().supportMode() && row.key.history()) {
request->check( request->check(
Command::SupportScrollToCurrent Command::SupportScrollToCurrent
) && request->handle([=] { ) && request->handle([=] {
@ -2921,7 +2779,7 @@ Dialogs::RowDescriptor DialogsInner::computeJump(
const Dialogs::RowDescriptor &to, const Dialogs::RowDescriptor &to,
JumpSkip skip) { JumpSkip skip) {
auto result = to; auto result = to;
if (Auth().supportMode() && result.key) { if (session().supportMode() && result.key) {
const auto down = (skip == JumpSkip::NextOrEnd) const auto down = (skip == JumpSkip::NextOrEnd)
|| (skip == JumpSkip::NextOrOriginal); || (skip == JumpSkip::NextOrOriginal);
while (!result.key.entry()->chatListUnreadCount() while (!result.key.entry()->chatListUnreadCount()

View File

@ -37,7 +37,7 @@ class DialogsInner
Q_OBJECT Q_OBJECT
public: public:
DialogsInner(QWidget *parent, not_null<Window::Controller*> controller, QWidget *main); DialogsInner(QWidget *parent, not_null<Window::Controller*> controller);
void dialogsReceived(const QVector<MTPDialog> &dialogs); void dialogsReceived(const QVector<MTPDialog> &dialogs);
void addSavedPeersAfter(const QDateTime &date); void addSavedPeersAfter(const QDateTime &date);
@ -57,7 +57,7 @@ public:
void selectSkip(int32 direction); void selectSkip(int32 direction);
void selectSkipPage(int32 pixels, int32 direction); void selectSkipPage(int32 pixels, int32 direction);
void createDialog(Dialogs::Key key); void refreshDialog(Dialogs::Key key);
void removeDialog(Dialogs::Key key); void removeDialog(Dialogs::Key key);
void repaintDialogRow(Dialogs::Mode list, not_null<Dialogs::Row*> row); void repaintDialogRow(Dialogs::Mode list, not_null<Dialogs::Row*> row);
void repaintDialogRow(Dialogs::RowDescriptor row); void repaintDialogRow(Dialogs::RowDescriptor row);
@ -69,13 +69,8 @@ public:
bool chooseRow(); bool chooseRow();
void destroyData();
void scrollToEntry(const Dialogs::RowDescriptor &entry); void scrollToEntry(const Dialogs::RowDescriptor &entry);
Dialogs::IndexedList *contactsList();
Dialogs::IndexedList *dialogsList();
Dialogs::IndexedList *contactsNoDialogsList();
int32 lastSearchDate() const; int32 lastSearchDate() const;
PeerData *lastSearchPeer() const; PeerData *lastSearchPeer() const;
MsgId lastSearchId() const; MsgId lastSearchId() const;
@ -109,7 +104,6 @@ public:
public slots: public slots:
void onParentGeometryChanged(); void onParentGeometryChanged();
void onDialogRowReplaced(Dialogs::Row *oldRow, Dialogs::Row *newRow);
signals: signals:
void draggingScrollDelta(int delta); void draggingScrollDelta(int delta);
@ -151,6 +145,11 @@ private:
Dialogs::Key key; Dialogs::Key key;
Data::MessagePosition message; Data::MessagePosition message;
}; };
AuthSession &session() const;
void dialogRowReplaced(Dialogs::Row *oldRow, Dialogs::Row *newRow);
bool switchImportantChats(); bool switchImportantChats();
bool chooseHashtag(); bool chooseHashtag();
ChosenRow computeChosenRow() const; ChosenRow computeChosenRow() const;
@ -159,7 +158,6 @@ private:
const Dialogs::RowDescriptor &entry) const; const Dialogs::RowDescriptor &entry) const;
void clearMouseSelection(bool clearSelection = false); void clearMouseSelection(bool clearSelection = false);
void userIsContactUpdated(not_null<UserData*> user);
void mousePressReleased(QPoint globalPosition, Qt::MouseButton button); void mousePressReleased(QPoint globalPosition, Qt::MouseButton button);
void clearIrrelevantState(); void clearIrrelevantState();
void selectByMouse(QPoint globalPosition); void selectByMouse(QPoint globalPosition);
@ -186,9 +184,6 @@ private:
|| (_peerSearchSelected >= 0) || (_peerSearchSelected >= 0)
|| (_searchedSelected >= 0); || (_searchedSelected >= 0);
} }
void handlePeerNameChange(
not_null<PeerData*> peer,
const base::flat_set<QChar> &oldLetters);
bool uniqueSearchResults() const; bool uniqueSearchResults() const;
bool hasHistoryInResults(not_null<History*> history) const; bool hasHistoryInResults(not_null<History*> history) const;
@ -289,12 +284,6 @@ private:
not_null<Window::Controller*> _controller; not_null<Window::Controller*> _controller;
std::unique_ptr<Dialogs::IndexedList> _dialogs;
std::unique_ptr<Dialogs::IndexedList> _dialogsImportant;
std::unique_ptr<Dialogs::IndexedList> _contactsNoDialogs;
std::unique_ptr<Dialogs::IndexedList> _contacts;
bool _mouseSelection = false; bool _mouseSelection = false;
std::optional<QPoint> _lastMousePosition; std::optional<QPoint> _lastMousePosition;
Qt::MouseButton _pressButton = Qt::LeftButton; Qt::MouseButton _pressButton = Qt::LeftButton;

View File

@ -9,7 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "dialogs/dialogs_entry.h" #include "dialogs/dialogs_entry.h"
#include "dialogs/dialogs_layout.h" #include "dialogs/dialogs_layout.h"
#include "styles/style_dialogs.h" #include "data/data_session.h"
#include "mainwidget.h" #include "mainwidget.h"
namespace Dialogs { namespace Dialogs {
@ -134,9 +134,7 @@ bool List::del(Key key, Row *replacedBy) {
} }
const auto row = i->second.get(); const auto row = i->second.get();
if (App::main()) { row->entry()->owner().dialogsRowReplaced({ row, replacedBy });
emit App::main()->dialogRowReplaced(row, replacedBy);
}
const auto index = row->pos(); const auto index = row->pos();
_rows.erase(_rows.begin() + index); _rows.erase(_rows.begin() + index);

View File

@ -19,6 +19,9 @@ public:
List(SortMode sortMode); List(SortMode sortMode);
List(const List &other) = delete; List(const List &other) = delete;
List &operator=(const List &other) = delete; List &operator=(const List &other) = delete;
List(List &&other) = default;
List &operator=(List &&other) = default;
~List() = default;
int size() const { int size() const {
return _rows.size(); return _rows.size();

View File

@ -149,7 +149,8 @@ void DialogsWidget::BottomButton::paintEvent(QPaintEvent *e) {
} }
} }
DialogsWidget::DialogsWidget(QWidget *parent, not_null<Window::Controller*> controller) : Window::AbstractSectionWidget(parent, controller) DialogsWidget::DialogsWidget(QWidget *parent, not_null<Window::Controller*> controller)
: Window::AbstractSectionWidget(parent, controller)
, _mainMenuToggle(this, st::dialogsMenuToggle) , _mainMenuToggle(this, st::dialogsMenuToggle)
, _filter(this, st::dialogsFilter, langFactory(lng_dlg_filter)) , _filter(this, st::dialogsFilter, langFactory(lng_dlg_filter))
, _chooseFromUser( , _chooseFromUser(
@ -162,7 +163,7 @@ DialogsWidget::DialogsWidget(QWidget *parent, not_null<Window::Controller*> cont
, _lockUnlock(this, st::dialogsLock) , _lockUnlock(this, st::dialogsLock)
, _scroll(this, st::dialogsScroll) , _scroll(this, st::dialogsScroll)
, _scrollToTop(_scroll, st::dialogsToUp) { , _scrollToTop(_scroll, st::dialogsToUp) {
_inner = _scroll->setOwnedWidget(object_ptr<DialogsInner>(this, controller, parent)); _inner = _scroll->setOwnedWidget(object_ptr<DialogsInner>(this, controller));
connect(_inner, SIGNAL(draggingScrollDelta(int)), this, SLOT(onDraggingScrollDelta(int))); connect(_inner, SIGNAL(draggingScrollDelta(int)), this, SLOT(onDraggingScrollDelta(int)));
connect(_inner, SIGNAL(mustScrollTo(int,int)), _scroll, SLOT(scrollToY(int,int))); connect(_inner, SIGNAL(mustScrollTo(int,int)), _scroll, SLOT(scrollToY(int,int)));
connect(_inner, SIGNAL(dialogMoved(int,int)), this, SLOT(onDialogMoved(int,int))); connect(_inner, SIGNAL(dialogMoved(int,int)), this, SLOT(onDialogMoved(int,int)));
@ -311,17 +312,17 @@ void DialogsWidget::setupConnectingWidget() {
} }
void DialogsWidget::setupSupportMode() { void DialogsWidget::setupSupportMode() {
if (!Auth().supportMode()) { if (!session().supportMode()) {
return; return;
} }
Auth().settings().supportChatsTimeSliceValue( session().settings().supportChatsTimeSliceValue(
) | rpl::start_with_next([=](int seconds) { ) | rpl::start_with_next([=](int seconds) {
_dialogsLoadTill = seconds ? std::max(unixtime() - seconds, 0) : 0; _dialogsLoadTill = seconds ? std::max(unixtime() - seconds, 0) : 0;
refreshLoadMoreButton(); refreshLoadMoreButton();
}, lifetime()); }, lifetime());
Auth().settings().supportAllSearchResultsValue( session().settings().supportAllSearchResultsValue(
) | rpl::filter([=] { ) | rpl::filter([=] {
return !_searchQuery.isEmpty(); return !_searchQuery.isEmpty();
}) | rpl::start_with_next([=] { }) | rpl::start_with_next([=] {
@ -363,9 +364,9 @@ void DialogsWidget::activate() {
_inner->activate(); _inner->activate();
} }
void DialogsWidget::createDialog(Dialogs::Key key) { void DialogsWidget::refreshDialog(Dialogs::Key key) {
const auto creating = !key.entry()->inChatList(Dialogs::Mode::All); const auto creating = !key.entry()->inChatList(Dialogs::Mode::All);
_inner->createDialog(key); _inner->refreshDialog(key);
const auto history = key.history(); const auto history = key.history();
if (creating && history && history->peer->migrateFrom()) { if (creating && history && history->peer->migrateFrom()) {
if (const auto migrated = history->owner().historyLoaded( if (const auto migrated = history->owner().historyLoaded(
@ -388,7 +389,7 @@ void DialogsWidget::repaintDialogRow(Dialogs::RowDescriptor row) {
} }
void DialogsWidget::jumpToTop() { void DialogsWidget::jumpToTop() {
if (Auth().supportMode()) { if (session().supportMode()) {
return; return;
} }
if ((_filter->getLastText().trimmed().isEmpty() && !_searchInChat)) { if ((_filter->getLastText().trimmed().isEmpty() && !_searchInChat)) {
@ -528,8 +529,8 @@ void DialogsWidget::dialogsReceived(
const auto [dialogsList, messagesList] = [&] { const auto [dialogsList, messagesList] = [&] {
const auto process = [&](const auto &data) { const auto process = [&](const auto &data) {
Auth().data().processUsers(data.vusers); session().data().processUsers(data.vusers);
Auth().data().processChats(data.vchats); session().data().processChats(data.vchats);
return std::make_tuple(&data.vdialogs.v, &data.vmessages.v); return std::make_tuple(&data.vdialogs.v, &data.vmessages.v);
}; };
switch (dialogs.type()) { switch (dialogs.type()) {
@ -554,11 +555,11 @@ void DialogsWidget::dialogsReceived(
refreshLoadMoreButton(); refreshLoadMoreButton();
} }
Auth().data().moreChatsLoaded().notify(); session().data().moreChatsLoaded().notify();
if (_dialogsFull && _pinnedDialogsReceived) { if (_dialogsFull && _pinnedDialogsReceived) {
Auth().data().allChatsLoaded().set(true); session().data().allChatsLoaded().set(true);
} }
Auth().api().requestContacts(); session().api().requestContacts();
} }
void DialogsWidget::updateDialogsOffset( void DialogsWidget::updateDialogsOffset(
@ -597,7 +598,7 @@ void DialogsWidget::updateDialogsOffset(
if (lastDate) { if (lastDate) {
_dialogsOffsetDate = lastDate; _dialogsOffsetDate = lastDate;
_dialogsOffsetId = lastMsgId; _dialogsOffsetId = lastMsgId;
_dialogsOffsetPeer = Auth().data().peer(lastPeer); _dialogsOffsetPeer = session().data().peer(lastPeer);
} else { } else {
_dialogsFull = true; _dialogsFull = true;
} }
@ -632,7 +633,7 @@ void DialogsWidget::loadMoreBlockedByDateChats() {
|| _loadMoreChats->isHidden()) { || _loadMoreChats->isHidden()) {
return; return;
} }
const auto max = Auth().settings().supportChatsTimeSlice(); const auto max = session().settings().supportChatsTimeSlice();
_dialogsLoadTill = _dialogsOffsetDate _dialogsLoadTill = _dialogsOffsetDate
? (_dialogsOffsetDate - max) ? (_dialogsOffsetDate - max)
: (unixtime() - max); : (unixtime() - max);
@ -647,18 +648,18 @@ void DialogsWidget::pinnedDialogsReceived(
if (_pinnedDialogsRequestId != requestId) return; if (_pinnedDialogsRequestId != requestId) return;
auto &data = result.c_messages_peerDialogs(); auto &data = result.c_messages_peerDialogs();
Auth().data().processUsers(data.vusers); session().data().processUsers(data.vusers);
Auth().data().processChats(data.vchats); session().data().processChats(data.vchats);
Auth().data().applyPinnedDialogs(data.vdialogs.v); session().data().applyPinnedDialogs(data.vdialogs.v);
applyReceivedDialogs(data.vdialogs.v, data.vmessages.v); applyReceivedDialogs(data.vdialogs.v, data.vmessages.v);
_pinnedDialogsRequestId = 0; _pinnedDialogsRequestId = 0;
_pinnedDialogsReceived = true; _pinnedDialogsReceived = true;
Auth().data().moreChatsLoaded().notify(); session().data().moreChatsLoaded().notify();
if (_dialogsFull && _pinnedDialogsReceived) { 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(); auto &d = result.c_messages_messages();
if (_searchRequest != 0) { if (_searchRequest != 0) {
// Don't apply cached data! // Don't apply cached data!
Auth().data().processUsers(d.vusers); session().data().processUsers(d.vusers);
Auth().data().processChats(d.vchats); session().data().processChats(d.vchats);
} }
auto &msgs = d.vmessages.v; auto &msgs = d.vmessages.v;
if (!_inner->searchReceived(msgs, type, msgs.size())) { if (!_inner->searchReceived(msgs, type, msgs.size())) {
@ -1033,8 +1034,8 @@ void DialogsWidget::searchReceived(
auto &d = result.c_messages_messagesSlice(); auto &d = result.c_messages_messagesSlice();
if (_searchRequest != 0) { if (_searchRequest != 0) {
// Don't apply cached data! // Don't apply cached data!
Auth().data().processUsers(d.vusers); session().data().processUsers(d.vusers);
Auth().data().processChats(d.vchats); session().data().processChats(d.vchats);
} }
auto &msgs = d.vmessages.v; auto &msgs = d.vmessages.v;
if (!_inner->searchReceived(msgs, type, d.vcount.v)) { if (!_inner->searchReceived(msgs, type, d.vcount.v)) {
@ -1063,8 +1064,8 @@ void DialogsWidget::searchReceived(
} }
if (_searchRequest != 0) { if (_searchRequest != 0) {
// Don't apply cached data! // Don't apply cached data!
Auth().data().processUsers(d.vusers); session().data().processUsers(d.vusers);
Auth().data().processChats(d.vchats); session().data().processChats(d.vchats);
} }
auto &msgs = d.vmessages.v; auto &msgs = d.vmessages.v;
if (!_inner->searchReceived(msgs, type, d.vcount.v)) { if (!_inner->searchReceived(msgs, type, d.vcount.v)) {
@ -1110,8 +1111,8 @@ void DialogsWidget::peerSearchReceived(
switch (result.type()) { switch (result.type()) {
case mtpc_contacts_found: { case mtpc_contacts_found: {
auto &d = result.c_contacts_found(); auto &d = result.c_contacts_found();
Auth().data().processUsers(d.vusers); session().data().processUsers(d.vusers);
Auth().data().processChats(d.vchats); session().data().processChats(d.vchats);
_inner->peerSearchReceived(q, d.vmy_results.v, d.vresults.v); _inner->peerSearchReceived(q, d.vmy_results.v, d.vresults.v);
} break; } break;
} }
@ -1566,10 +1567,6 @@ void DialogsWidget::paintEvent(QPaintEvent *e) {
} }
} }
void DialogsWidget::destroyData() {
_inner->destroyData();
}
void DialogsWidget::scrollToEntry(const Dialogs::RowDescriptor &entry) { void DialogsWidget::scrollToEntry(const Dialogs::RowDescriptor &entry) {
_inner->scrollToEntry(entry); _inner->scrollToEntry(entry);
} }
@ -1578,18 +1575,6 @@ void DialogsWidget::removeDialog(Dialogs::Key key) {
_inner->removeDialog(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 DialogsWidget::onCancelSearch() {
bool clearing = !_filter->getLastText().isEmpty(); bool clearing = !_filter->getLastText().isEmpty();
if (_searchRequest) { if (_searchRequest) {

View File

@ -14,12 +14,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/special_buttons.h" #include "ui/special_buttons.h"
class DialogsInner; class DialogsInner;
class AuthSession;
namespace Dialogs { namespace Dialogs {
struct RowDescriptor; struct RowDescriptor;
class Row; class Row;
class FakeRow; class FakeRow;
class IndexedList;
class Key; class Key;
} // namespace Dialogs } // namespace Dialogs
@ -60,7 +60,7 @@ public:
void loadDialogs(); void loadDialogs();
void loadPinnedDialogs(); void loadPinnedDialogs();
void createDialog(Dialogs::Key key); void refreshDialog(Dialogs::Key key);
void removeDialog(Dialogs::Key key); void removeDialog(Dialogs::Key key);
void repaintDialogRow(Dialogs::Mode list, not_null<Dialogs::Row*> row); void repaintDialogRow(Dialogs::Mode list, not_null<Dialogs::Row*> row);
void repaintDialogRow(Dialogs::RowDescriptor row); void repaintDialogRow(Dialogs::RowDescriptor row);
@ -76,14 +76,8 @@ public:
void showAnimated(Window::SlideDirection direction, const Window::SectionSlideParams &params); void showAnimated(Window::SlideDirection direction, const Window::SectionSlideParams &params);
void showFast(); void showFast();
void destroyData();
void scrollToEntry(const Dialogs::RowDescriptor &entry); void scrollToEntry(const Dialogs::RowDescriptor &entry);
Dialogs::IndexedList *contactsList();
Dialogs::IndexedList *dialogsList();
Dialogs::IndexedList *contactsNoDialogsList();
void searchMessages(const QString &query, Dialogs::Key inChat = {}); void searchMessages(const QString &query, Dialogs::Key inChat = {});
void onSearchMore(); void onSearchMore();

View File

@ -63,11 +63,10 @@ constexpr auto kSkipCloudDraftsFor = TimeId(3);
} // namespace } // namespace
History::History(not_null<Data::Session*> owner, PeerId peerId) History::History(not_null<Data::Session*> owner, PeerId peerId)
: Entry(this) : Entry(owner, this)
, peer(owner->peer(peerId)) , peer(owner->peer(peerId))
, cloudDraftTextCache(st::dialogsTextWidthMin) , cloudDraftTextCache(st::dialogsTextWidthMin)
, _owner(owner) , _mute(owner->notifyIsMuted(peer))
, _mute(_owner->notifyIsMuted(peer))
, _sendActionText(st::dialogsTextWidthMin) { , _sendActionText(st::dialogsTextWidthMin) {
if (const auto user = peer->asUser()) { if (const auto user = peer->asUser()) {
if (user->botInfo) { if (user->botInfo) {
@ -329,9 +328,9 @@ void History::draftSavedToCloud() {
} }
HistoryItemsList History::validateForwardDraft() { HistoryItemsList History::validateForwardDraft() {
auto result = _owner->idsToItems(_forwardDraft); auto result = owner().idsToItems(_forwardDraft);
if (result.size() != _forwardDraft.size()) { if (result.size() != _forwardDraft.size()) {
setForwardDraft(_owner->itemsToIds(result)); setForwardDraft(owner().itemsToIds(result));
} }
return result; return result;
} }
@ -561,7 +560,7 @@ bool History::updateSendActionNeedsAnimating(crl::time now, bool force) {
} }
const auto result = (!_typing.empty() || !_sendActions.empty()); const auto result = (!_typing.empty() || !_sendActions.empty());
if (changed || (result && !anim::Disabled())) { if (changed || (result && !anim::Disabled())) {
_owner->updateSendActionAnimation({ owner().updateSendActionAnimation({
this, this,
_sendActionAnimation.width(), _sendActionAnimation.width(),
st::normalFont->height, st::normalFont->height,
@ -940,7 +939,7 @@ not_null<HistoryItem*> History::addNewItem(
} }
if (auto megagroup = peer->asMegagroup()) { if (auto megagroup = peer->asMegagroup()) {
Notify::peerUpdatedDelayed(peer, Notify::PeerUpdate::Flag::MembersChanged); Notify::peerUpdatedDelayed(peer, Notify::PeerUpdate::Flag::MembersChanged);
_owner->addNewMegagroupParticipant(megagroup, user); owner().addNewMegagroupParticipant(megagroup, user);
} }
} }
} }
@ -1000,7 +999,7 @@ not_null<HistoryItem*> History::addNewItem(
newItemAdded(item); newItemAdded(item);
} }
_owner->notifyHistoryChangeDelayed(this); owner().notifyHistoryChangeDelayed(this);
return item; return item;
} }
@ -1028,7 +1027,7 @@ void History::applyServiceChanges(
if (!base::contains(mgInfo->lastParticipants, user)) { if (!base::contains(mgInfo->lastParticipants, user)) {
mgInfo->lastParticipants.push_front(user); mgInfo->lastParticipants.push_front(user);
Notify::peerUpdatedDelayed(peer, Notify::PeerUpdate::Flag::MembersChanged); Notify::peerUpdatedDelayed(peer, Notify::PeerUpdate::Flag::MembersChanged);
_owner->addNewMegagroupParticipant(megagroup, user); owner().addNewMegagroupParticipant(megagroup, user);
} }
if (user->botInfo) { if (user->botInfo) {
peer->asChannel()->mgInfo->bots.insert(user); peer->asChannel()->mgInfo->bots.insert(user);
@ -1050,7 +1049,7 @@ void History::applyServiceChanges(
if (!base::contains(mgInfo->lastParticipants, user)) { if (!base::contains(mgInfo->lastParticipants, user)) {
mgInfo->lastParticipants.push_front(user); mgInfo->lastParticipants.push_front(user);
Notify::peerUpdatedDelayed(peer, Notify::PeerUpdate::Flag::MembersChanged); Notify::peerUpdatedDelayed(peer, Notify::PeerUpdate::Flag::MembersChanged);
_owner->addNewMegagroupParticipant(megagroup, user); owner().addNewMegagroupParticipant(megagroup, user);
} }
if (user->botInfo) { if (user->botInfo) {
mgInfo->bots.insert(user); mgInfo->bots.insert(user);
@ -1086,7 +1085,7 @@ void History::applyServiceChanges(
mgInfo->lastParticipants.erase(i); mgInfo->lastParticipants.erase(i);
Notify::peerUpdatedDelayed(peer, Notify::PeerUpdate::Flag::MembersChanged); Notify::peerUpdatedDelayed(peer, Notify::PeerUpdate::Flag::MembersChanged);
} }
_owner->removeMegagroupParticipant(megagroup, user); owner().removeMegagroupParticipant(megagroup, user);
if (megagroup->membersCount() > 1) { if (megagroup->membersCount() > 1) {
megagroup->setMembersCount(megagroup->membersCount() - 1); megagroup->setMembersCount(megagroup->membersCount() - 1);
} else { } else {
@ -1114,7 +1113,7 @@ void History::applyServiceChanges(
d.vphoto.match([&](const MTPDphoto &data) { d.vphoto.match([&](const MTPDphoto &data) {
const auto &sizes = data.vsizes.v; const auto &sizes = data.vsizes.v;
if (!sizes.isEmpty()) { if (!sizes.isEmpty()) {
auto photo = _owner->processPhoto(data); auto photo = owner().processPhoto(data);
photo->peer = peer; photo->peer = peer;
auto &smallSize = sizes.front(); auto &smallSize = sizes.front();
auto &bigSize = sizes.back(); auto &bigSize = sizes.back();
@ -1662,7 +1661,7 @@ void History::setUnreadCount(int newUnreadCount) {
const auto delta = unreadMarkDelta + (unreadCountDelta const auto delta = unreadMarkDelta + (unreadCountDelta
? *unreadCountDelta ? *unreadCountDelta
: newUnreadCount); : newUnreadCount);
_owner->unreadIncrement(delta, mute()); owner().unreadIncrement(delta, mute());
const auto nowUnread = (*_unreadCount > 0) || _unreadMark; const auto nowUnread = (*_unreadCount > 0) || _unreadMark;
const auto entriesDelta = (wasUnread && !nowUnread) const auto entriesDelta = (wasUnread && !nowUnread)
@ -1670,7 +1669,7 @@ void History::setUnreadCount(int newUnreadCount) {
: (nowUnread && !wasUnread) : (nowUnread && !wasUnread)
? 1 ? 1
: 0; : 0;
_owner->unreadEntriesChanged( owner().unreadEntriesChanged(
entriesDelta, entriesDelta,
mute() ? entriesDelta : 0); mute() ? entriesDelta : 0);
} }
@ -1689,8 +1688,8 @@ void History::setUnreadMark(bool unread) {
if (!_unreadCount || !*_unreadCount) { if (!_unreadCount || !*_unreadCount) {
if (inChatList(Dialogs::Mode::All)) { if (inChatList(Dialogs::Mode::All)) {
const auto delta = _unreadMark ? 1 : -1; const auto delta = _unreadMark ? 1 : -1;
_owner->unreadIncrement(delta, mute()); owner().unreadIncrement(delta, mute());
_owner->unreadEntriesChanged( owner().unreadEntriesChanged(
delta, delta,
mute() ? delta : 0); mute() ? delta : 0);
@ -1746,11 +1745,11 @@ bool History::changeMute(bool newMute) {
//} //}
if (inChatList(Dialogs::Mode::All)) { if (inChatList(Dialogs::Mode::All)) {
if (const auto count = unreadCountForBadge()) { if (const auto count = unreadCountForBadge()) {
_owner->unreadMuteChanged(count, _mute); owner().unreadMuteChanged(count, _mute);
const auto entriesWithUnreadDelta = 0; const auto entriesWithUnreadDelta = 0;
const auto mutedEntriesWithUnreadDelta = _mute ? 1 : -1; const auto mutedEntriesWithUnreadDelta = _mute ? 1 : -1;
_owner->unreadEntriesChanged( owner().unreadEntriesChanged(
entriesWithUnreadDelta, entriesWithUnreadDelta,
mutedEntriesWithUnreadDelta); mutedEntriesWithUnreadDelta);
@ -2455,7 +2454,7 @@ void History::applyDialog(const MTPDdialog &data) {
} }
} }
} }
_owner->applyNotifySetting( owner().applyNotifySetting(
MTP_notifyPeer(data.vpeer), MTP_notifyPeer(data.vpeer),
data.vnotify_settings); data.vnotify_settings);
@ -2660,14 +2659,6 @@ void History::resizeToWidth(int newWidth) {
_height = y; _height = y;
} }
Data::Session &History::owner() const {
return *_owner;
}
AuthSession &History::session() const {
return _owner->session();
}
ChannelId History::channelId() const { ChannelId History::channelId() const {
return peerToChannel(peer->id); return peerToChannel(peer->id);
} }
@ -2964,12 +2955,12 @@ void History::clear(ClearType type) {
forgetScrollState(); forgetScrollState();
if (type == ClearType::Unload) { if (type == ClearType::Unload) {
blocks.clear(); blocks.clear();
_owner->notifyHistoryUnloaded(this); owner().notifyHistoryUnloaded(this);
lastKeyboardInited = false; lastKeyboardInited = false;
_loadedAtTop = _loadedAtBottom = false; _loadedAtTop = _loadedAtBottom = false;
} else { } else {
notifies.clear(); notifies.clear();
_owner->notifyHistoryCleared(this); owner().notifyHistoryCleared(this);
changeUnreadCount(-unreadCount()); changeUnreadCount(-unreadCount());
if (type == ClearType::DeleteChat) { if (type == ClearType::DeleteChat) {
setLastMessage(nullptr); setLastMessage(nullptr);
@ -2998,7 +2989,7 @@ void History::clear(ClearType type) {
//} //}
} }
} }
_owner->notifyHistoryChangeDelayed(this); owner().notifyHistoryChangeDelayed(this);
if (const auto chat = peer->asChat()) { if (const auto chat = peer->asChat()) {
chat->lastAuthors.clear(); chat->lastAuthors.clear();
@ -3026,7 +3017,7 @@ void History::clearUpTill(MsgId availableMinId) {
} while (!isEmpty()); } while (!isEmpty());
requestChatListMessage(); requestChatListMessage();
_owner->sendHistoryChangeNotifications(); owner().sendHistoryChangeNotifications();
} }
void History::applyGroupAdminChanges( void History::applyGroupAdminChanges(
@ -3041,10 +3032,10 @@ void History::applyGroupAdminChanges(
void History::changedInChatListHook(Dialogs::Mode list, bool added) { void History::changedInChatListHook(Dialogs::Mode list, bool added) {
if (list == Dialogs::Mode::All) { if (list == Dialogs::Mode::All) {
if (const auto delta = unreadCountForBadge() * (added ? 1 : -1)) { if (const auto delta = unreadCountForBadge() * (added ? 1 : -1)) {
_owner->unreadIncrement(delta, mute()); owner().unreadIncrement(delta, mute());
const auto entriesDelta = added ? 1 : -1; const auto entriesDelta = added ? 1 : -1;
_owner->unreadEntriesChanged( owner().unreadEntriesChanged(
entriesDelta, entriesDelta,
mute() ? entriesDelta : 0); mute() ? entriesDelta : 0);
} }

View File

@ -64,9 +64,6 @@ public:
History &operator=(const History &) = delete; History &operator=(const History &) = delete;
~History(); ~History();
Data::Session &owner() const;
AuthSession &session() const;
ChannelId channelId() const; ChannelId channelId() const;
bool isChannel() const; bool isChannel() const;
bool isMegagroup() const; bool isMegagroup() const;
@ -467,7 +464,6 @@ private:
void setFolderPointer(Data::Folder *folder); void setFolderPointer(Data::Folder *folder);
not_null<Data::Session*> _owner;
Flags _flags = 0; Flags _flags = 0;
bool _mute = false; bool _mute = false;
int _width = 0; int _width = 0;

View File

@ -6670,10 +6670,6 @@ QRect HistoryWidget::historyRect() const {
return _scroll->geometry(); return _scroll->geometry();
} }
void HistoryWidget::destroyData() {
showHistory(0, 0);
}
QPoint HistoryWidget::clampMousePosition(QPoint point) { QPoint HistoryWidget::clampMousePosition(QPoint point) {
if (point.x() < 0) { if (point.x() < 0) {
point.setX(0); point.setX(0);

View File

@ -153,8 +153,6 @@ public:
void updateRecentStickers(); void updateRecentStickers();
void destroyData();
void updateFieldPlaceholder(); void updateFieldPlaceholder();
void updateStickersByEmoji(); void updateStickersByEmoji();

View File

@ -967,18 +967,6 @@ void MainWidget::cacheBackground() {
_cachedFor = _willCacheFor; _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<const HistoryItem*> item) const { crl::time MainWidget::highlightStartTime(not_null<const HistoryItem*> item) const {
return _history->highlightStartTime(item); return _history->highlightStartTime(item);
} }
@ -1557,8 +1545,8 @@ bool MainWidget::viewsIncrementFail(const RPCError &error, mtpRequestId req) {
return false; return false;
} }
void MainWidget::createDialog(Dialogs::Key key) { void MainWidget::refreshDialog(Dialogs::Key key) {
_dialogs->createDialog(key); _dialogs->refreshDialog(key);
} }
void MainWidget::choosePeer(PeerId peerId, MsgId showAtMsgId) { void MainWidget::choosePeer(PeerId peerId, MsgId showAtMsgId) {
@ -3489,11 +3477,6 @@ void MainWidget::activate() {
App::wnd()->fixOrder(); App::wnd()->fixOrder();
} }
void MainWidget::destroyData() {
_history->destroyData();
_dialogs->destroyData();
}
bool MainWidget::isActive() const { bool MainWidget::isActive() const {
return !_isIdle && isVisible() && !_a_show.animating(); return !_isIdle && isVisible() && !_a_show.animating();
} }

View File

@ -35,7 +35,6 @@ namespace Dialogs {
struct RowDescriptor; struct RowDescriptor;
class Row; class Row;
class Key; class Key;
class IndexedList;
} // namespace Dialogs } // namespace Dialogs
namespace Media { namespace Media {
@ -124,7 +123,7 @@ public:
void activate(); void activate();
void updateReceived(const mtpPrime *from, const mtpPrime *end); void updateReceived(const mtpPrime *from, const mtpPrime *end);
void createDialog(Dialogs::Key key); void refreshDialog(Dialogs::Key key);
void removeDialog(Dialogs::Key key); void removeDialog(Dialogs::Key key);
void repaintDialogRow(Dialogs::Mode list, not_null<Dialogs::Row*> row); void repaintDialogRow(Dialogs::Mode list, not_null<Dialogs::Row*> row);
void repaintDialogRow(Dialogs::RowDescriptor row); void repaintDialogRow(Dialogs::RowDescriptor row);
@ -163,7 +162,6 @@ public:
const std::optional<FullMsgId> &oldId); const std::optional<FullMsgId> &oldId);
bool onSendSticker(DocumentData *sticker); bool onSendSticker(DocumentData *sticker);
void destroyData();
void updateOnlineDisplayIn(int32 msecs); void updateOnlineDisplayIn(int32 msecs);
bool isActive() const; bool isActive() const;
@ -200,10 +198,6 @@ public:
bool sendMessageFail(const RPCError &error); bool sendMessageFail(const RPCError &error);
Dialogs::IndexedList *contactsList();
Dialogs::IndexedList *dialogsList();
Dialogs::IndexedList *contactsNoDialogsList();
// While HistoryInner is not HistoryView::ListWidget. // While HistoryInner is not HistoryView::ListWidget.
crl::time highlightStartTime(not_null<const HistoryItem*> item) const; crl::time highlightStartTime(not_null<const HistoryItem*> item) const;
bool historyInSelectionMode() const; bool historyInSelectionMode() const;
@ -298,7 +292,6 @@ public:
~MainWidget(); ~MainWidget();
signals: signals:
void dialogRowReplaced(Dialogs::Row *oldRow, Dialogs::Row *newRow);
void dialogsUpdated(); void dialogsUpdated();
public slots: public slots:

View File

@ -12,9 +12,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "window/section_memento.h" #include "window/section_memento.h"
#include "window/window_slide_animation.h" #include "window/window_slide_animation.h"
#include "window/themes/window_theme.h" #include "window/themes/window_theme.h"
#include "window/window_controller.h"
namespace Window { namespace Window {
AuthSession &AbstractSectionWidget::session() const {
return _controller->session();
}
SectionWidget::SectionWidget( SectionWidget::SectionWidget(
QWidget *parent, QWidget *parent,
not_null<Window::Controller*> controller) not_null<Window::Controller*> controller)

View File

@ -10,6 +10,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/rp_widget.h" #include "ui/rp_widget.h"
#include "dialogs/dialogs_key.h" #include "dialogs/dialogs_key.h"
class AuthSession;
namespace Window { namespace Window {
class Controller; class Controller;
@ -31,10 +33,12 @@ public:
AbstractSectionWidget( AbstractSectionWidget(
QWidget *parent, QWidget *parent,
not_null<Window::Controller*> controller) not_null<Window::Controller*> controller)
: RpWidget(parent) : RpWidget(parent)
, _controller(controller) { , _controller(controller) {
} }
AuthSession &session() const;
// Float player interface. // Float player interface.
virtual bool wheelEventFromFloatPlayer(QEvent *e) { virtual bool wheelEventFromFloatPlayer(QEvent *e) {
return false; return false;