Ignore accents in contacts list sorting.

This commit is contained in:
John Preston 2021-02-19 15:54:27 +04:00
parent 0a678ae8bd
commit f9f52302bb
8 changed files with 36 additions and 6 deletions

View File

@ -50,7 +50,8 @@ Folder::Folder(not_null<Data::Session*> 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<QChar> &Folder::chatListFirstLetters() const {
return _nameFirstLetters;
}
const QString &Folder::chatListNameSortKey() const {
return _chatListNameSortKey;
}
} // namespace Data

View File

@ -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<QString> &chatListNameWords() const override;
const base::flat_set<QChar> &chatListFirstLetters() const override;
@ -102,6 +103,7 @@ private:
QString _name;
base::flat_set<QString> _nameWords;
base::flat_set<QChar> _nameFirstLetters;
QString _chatListNameSortKey;
std::vector<not_null<History*>> _lastHistories;
HistoryItem *_chatListMessage = nullptr;

View File

@ -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);
}

View File

@ -78,6 +78,8 @@ public:
return *_session;
}
[[nodiscard]] QString nameSortKey(const QString &name) const;
[[nodiscard]] Groups &groups() {
return _groups;
}

View File

@ -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<QString> &chatListNameWords() const = 0;
virtual const base::flat_set<QChar> &chatListFirstLetters() const = 0;

View File

@ -62,20 +62,18 @@ not_null<Row*> List::addByName(Key key) {
void List::adjustByName(not_null<Row*> 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);

View File

@ -62,6 +62,7 @@ History::History(not_null<Data::Session*> 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<QString> &History::chatListNameWords() const {
return peer->nameWords();
}

View File

@ -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<QString> &chatListNameWords() const override;
const base::flat_set<QChar> &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<HistoryItem*> item);
@ -566,6 +569,8 @@ private:
// be a migrate message, but _chatListMessage should be the one before.
std::optional<HistoryItem*> _chatListMessage;
QString _chatListNameSortKey;
bool _unreadMark = false;
bool _fakeUnreadWhileOpened = false;