diff --git a/Telegram/SourceFiles/data/data_folder.cpp b/Telegram/SourceFiles/data/data_folder.cpp index ef9e83a17a..a87eeea064 100644 --- a/Telegram/SourceFiles/data/data_folder.cpp +++ b/Telegram/SourceFiles/data/data_folder.cpp @@ -50,7 +50,8 @@ Folder::Folder(not_null owner, FolderId id) &owner->session(), FilterId(), owner->session().serverConfig().pinnedDialogsInFolderMax.value()) -, _name(tr::lng_archived_name(tr::now)) { +, _name(tr::lng_archived_name(tr::now)) +, _chatListNameSortKey(owner->nameSortKey(_name)) { indexNameParts(); session().changes().peerUpdates( @@ -408,4 +409,8 @@ const base::flat_set &Folder::chatListFirstLetters() const { return _nameFirstLetters; } +const QString &Folder::chatListNameSortKey() const { + return _chatListNameSortKey; +} + } // namespace Data diff --git a/Telegram/SourceFiles/data/data_folder.h b/Telegram/SourceFiles/data/data_folder.h index a2442c70b7..ab0c59b955 100644 --- a/Telegram/SourceFiles/data/data_folder.h +++ b/Telegram/SourceFiles/data/data_folder.h @@ -58,6 +58,7 @@ public: bool chatListMessageKnown() const override; void requestChatListMessage() override; const QString &chatListName() const override; + const QString &chatListNameSortKey() const override; const base::flat_set &chatListNameWords() const override; const base::flat_set &chatListFirstLetters() const override; @@ -102,6 +103,7 @@ private: QString _name; base::flat_set _nameWords; base::flat_set _nameFirstLetters; + QString _chatListNameSortKey; std::vector> _lastHistories; HistoryItem *_chatListMessage = nullptr; diff --git a/Telegram/SourceFiles/data/data_session.cpp b/Telegram/SourceFiles/data/data_session.cpp index e3843b692f..c72ad36033 100644 --- a/Telegram/SourceFiles/data/data_session.cpp +++ b/Telegram/SourceFiles/data/data_session.cpp @@ -1156,6 +1156,10 @@ void Session::forgetPassportCredentials() { _passportCredentials = nullptr; } +QString Session::nameSortKey(const QString &name) const { + return TextUtilities::RemoveAccents(name).toLower(); +} + void Session::setupMigrationViewer() { session().changes().peerUpdates( PeerUpdate::Flag::Migration @@ -1203,9 +1207,13 @@ void Session::setupPeerNameViewer() { session().changes().realtimeNameUpdates( ) | rpl::start_with_next([=](const NameUpdate &update) { const auto peer = update.peer; + if (const auto history = historyLoaded(peer)) { + history->refreshChatListNameSortKey(); + } const auto &oldLetters = update.oldFirstLetters; _contactsNoChatsList.peerNameChanged(peer, oldLetters); _contactsList.peerNameChanged(peer, oldLetters); + }, _lifetime); } diff --git a/Telegram/SourceFiles/data/data_session.h b/Telegram/SourceFiles/data/data_session.h index 6914c33d07..1a307076d0 100644 --- a/Telegram/SourceFiles/data/data_session.h +++ b/Telegram/SourceFiles/data/data_session.h @@ -78,6 +78,8 @@ public: return *_session; } + [[nodiscard]] QString nameSortKey(const QString &name) const; + [[nodiscard]] Groups &groups() { return _groups; } diff --git a/Telegram/SourceFiles/dialogs/dialogs_entry.h b/Telegram/SourceFiles/dialogs/dialogs_entry.h index 297313d78a..672d7d5058 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_entry.h +++ b/Telegram/SourceFiles/dialogs/dialogs_entry.h @@ -155,6 +155,7 @@ public: virtual bool chatListMessageKnown() const = 0; virtual void requestChatListMessage() = 0; virtual const QString &chatListName() const = 0; + virtual const QString &chatListNameSortKey() const = 0; virtual const base::flat_set &chatListNameWords() const = 0; virtual const base::flat_set &chatListFirstLetters() const = 0; diff --git a/Telegram/SourceFiles/dialogs/dialogs_list.cpp b/Telegram/SourceFiles/dialogs/dialogs_list.cpp index 51d8f6734a..f325f91ca8 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_list.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_list.cpp @@ -62,20 +62,18 @@ not_null List::addByName(Key key) { void List::adjustByName(not_null row) { Expects(row->pos() >= 0 && row->pos() < _rows.size()); - const auto &name = row->entry()->chatListName(); + const auto &key = row->entry()->chatListNameSortKey(); const auto index = row->pos(); const auto i = _rows.begin() + index; const auto before = std::find_if(i + 1, _rows.end(), [&](Row *row) { - const auto &greater = row->entry()->chatListName(); - return greater.compare(name, Qt::CaseInsensitive) >= 0; + return row->entry()->chatListNameSortKey().compare(key) >= 0; }); if (before != i + 1) { rotate(i, i + 1, before); } else if (i != _rows.begin()) { const auto from = std::make_reverse_iterator(i); const auto after = std::find_if(from, _rows.rend(), [&](Row *row) { - const auto &less = row->entry()->chatListName(); - return less.compare(name, Qt::CaseInsensitive) <= 0; + return row->entry()->chatListNameSortKey().compare(key) <= 0; }).base(); if (after != i) { rotate(after, i, i + 1); diff --git a/Telegram/SourceFiles/history/history.cpp b/Telegram/SourceFiles/history/history.cpp index 8728fe6108..64d10d8f48 100644 --- a/Telegram/SourceFiles/history/history.cpp +++ b/Telegram/SourceFiles/history/history.cpp @@ -62,6 +62,7 @@ History::History(not_null owner, PeerId peerId) , peer(owner->peer(peerId)) , cloudDraftTextCache(st::dialogsTextWidthMin) , _mute(owner->notifyIsMuted(peer)) +, _chatListNameSortKey(owner->nameSortKey(peer->name)) , _sendActionPainter(this) { if (const auto user = peer->asUser()) { if (user->isBot()) { @@ -2019,6 +2020,14 @@ const QString &History::chatListName() const { return peer->name; } +const QString &History::chatListNameSortKey() const { + return _chatListNameSortKey; +} + +void History::refreshChatListNameSortKey() { + _chatListNameSortKey = owner().nameSortKey(peer->name); +} + const base::flat_set &History::chatListNameWords() const { return peer->nameWords(); } diff --git a/Telegram/SourceFiles/history/history.h b/Telegram/SourceFiles/history/history.h index b715e77336..2dfc0837ec 100644 --- a/Telegram/SourceFiles/history/history.h +++ b/Telegram/SourceFiles/history/history.h @@ -365,6 +365,7 @@ public: bool chatListMessageKnown() const override; void requestChatListMessage() override; const QString &chatListName() const override; + const QString &chatListNameSortKey() const override; const base::flat_set &chatListNameWords() const override; const base::flat_set &chatListFirstLetters() const override; void loadUserpic() override; @@ -375,6 +376,8 @@ public: int y, int size) const override; + void refreshChatListNameSortKey(); + void setFakeChatListMessageFrom(const MTPmessages_Messages &data); void checkChatListMessageRemoved(not_null item); @@ -566,6 +569,8 @@ private: // be a migrate message, but _chatListMessage should be the one before. std::optional _chatListMessage; + QString _chatListNameSortKey; + bool _unreadMark = false; bool _fakeUnreadWhileOpened = false;