From 38832396bc53fcd2f1df0f4b6158e7bb409242f2 Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 15 Jan 2026 23:35:03 +0400 Subject: [PATCH] Implement smart sorting for settings search results. Sort results by match count (descending), then by parent chain depth (ascending), and finally alphabetically by title. --- .../SourceFiles/settings/settings_search.cpp | 40 ++++++++++++++----- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/Telegram/SourceFiles/settings/settings_search.cpp b/Telegram/SourceFiles/settings/settings_search.cpp index ac975a3e21..ac6c9b64e1 100644 --- a/Telegram/SourceFiles/settings/settings_search.cpp +++ b/Telegram/SourceFiles/settings/settings_search.cpp @@ -34,7 +34,8 @@ namespace { struct SearchResult { Builder::SearchEntry entry; - int score = 0; + int matchCount = 0; + int depth = 0; }; [[nodiscard]] QStringList PrepareEntryWords(const Builder::SearchEntry &entry) { @@ -56,35 +57,54 @@ struct SearchResult { return false; } -[[nodiscard]] int CalculateScore( +[[nodiscard]] int CalculateMatchCount( const Builder::SearchEntry &entry, const QStringList &queryWords) { if (queryWords.isEmpty()) { return 0; } const auto entryWords = PrepareEntryWords(entry); + auto matched = 0; for (const auto &queryWord : queryWords) { - if (!MatchesWord(entryWords, queryWord)) { - return 0; + if (MatchesWord(entryWords, queryWord)) { + ++matched; } } - return 100; + return matched; +} + +[[nodiscard]] int CalculateDepth( + Type sectionId, + const Builder::SearchRegistry ®istry) { + const auto path = registry.sectionPath(sectionId); + if (path.isEmpty()) { + return 0; + } + return path.count(u" > "_q) + 1; } [[nodiscard]] std::vector FilterAndSort( const std::vector &entries, const QString &query) { const auto queryWords = TextUtilities::PrepareSearchWords(query); + const auto ®istry = Builder::SearchRegistry::Instance(); auto results = std::vector(); for (const auto &entry : entries) { - const auto score = CalculateScore(entry, queryWords); - if (score > 0) { - results.push_back({ entry, score }); + const auto matchCount = CalculateMatchCount(entry, queryWords); + if (matchCount > 0) { + results.push_back({ + entry, + matchCount, + CalculateDepth(entry.section, registry), + }); } } ranges::sort(results, [](const SearchResult &a, const SearchResult &b) { - if (a.score != b.score) { - return a.score > b.score; + if (a.matchCount != b.matchCount) { + return a.matchCount > b.matchCount; + } + if (a.depth != b.depth) { + return a.depth < b.depth; } return a.entry.title < b.entry.title; });