From 21f3a7b07fe1cf6637ab8ad21d01ec97b8b50f82 Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 24 Jan 2023 19:15:43 +0400 Subject: [PATCH] Find emoji by words for stickers search. --- .../chat_helpers/emoji_list_widget.cpp | 35 +--------------- .../chat_helpers/stickers_list_footer.cpp | 41 +++++++++++++++++++ .../chat_helpers/stickers_list_footer.h | 4 ++ .../chat_helpers/stickers_list_widget.cpp | 8 +--- .../data/stickers/data_stickers.cpp | 4 +- 5 files changed, 50 insertions(+), 42 deletions(-) diff --git a/Telegram/SourceFiles/chat_helpers/emoji_list_widget.cpp b/Telegram/SourceFiles/chat_helpers/emoji_list_widget.cpp index dda4dda40..6d9f6ff92 100644 --- a/Telegram/SourceFiles/chat_helpers/emoji_list_widget.cpp +++ b/Telegram/SourceFiles/chat_helpers/emoji_list_widget.cpp @@ -46,7 +46,6 @@ namespace { constexpr auto kCollapsedRows = 3; constexpr auto kAppearDuration = 0.3; -constexpr auto kPlainSearchLimit = 32; constexpr auto kCustomSearchLimit = 256; using Core::RecentEmojiId; @@ -519,39 +518,7 @@ void EmojiListWidget::applyNextSearchQuery() { } std::vector EmojiListWidget::collectPlainSearchResults() { - auto result = std::vector(); - const auto pushPlain = [&](EmojiPtr emoji) { - if (result.size() < kPlainSearchLimit - && _searchEmoji.emplace(emoji).second) { - result.push_back(emoji); - } - if (const auto original = emoji->original(); original != emoji) { - _searchEmoji.emplace(original); - } - }; - auto refreshed = false; - auto &keywords = Core::App().emojiKeywords(); - for (const auto &entry : _searchQuery) { - if (const auto emoji = Ui::Emoji::Find(entry)) { - pushPlain(emoji); - if (result.size() >= kPlainSearchLimit) { - return result; - } - } else if (!entry.isEmpty()) { - if (!refreshed) { - refreshed = true; - keywords.refresh(); - } - const auto list = keywords.queryMine(entry); - for (const auto &entry : list) { - pushPlain(entry.emoji); - if (result.size() >= kPlainSearchLimit) { - return result; - } - } - } - } - return result; + return SearchEmoji(_searchQuery, _searchEmoji); } void EmojiListWidget::appendPremiumSearchResults() { diff --git a/Telegram/SourceFiles/chat_helpers/stickers_list_footer.cpp b/Telegram/SourceFiles/chat_helpers/stickers_list_footer.cpp index 70e3eec83..604a15652 100644 --- a/Telegram/SourceFiles/chat_helpers/stickers_list_footer.cpp +++ b/Telegram/SourceFiles/chat_helpers/stickers_list_footer.cpp @@ -7,8 +7,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "chat_helpers/stickers_list_footer.h" +#include "chat_helpers/emoji_keywords.h" #include "chat_helpers/stickers_emoji_pack.h" #include "chat_helpers/stickers_lottie.h" +#include "core/application.h" #include "data/stickers/data_stickers_set.h" #include "data/stickers/data_stickers.h" #include "data/stickers/data_custom_emoji.h" @@ -36,6 +38,7 @@ namespace ChatHelpers { namespace { constexpr auto kEmojiSectionSetIdBase = uint64(0x77FF'FFFF'FFFF'FFF0ULL); +constexpr auto kEmojiSearchLimit = 32; using EmojiSection = Ui::Emoji::Section; @@ -145,6 +148,44 @@ rpl::producer> GifSectionsValue( }) | rpl::flatten_latest(); } +[[nodiscard]] std::vector SearchEmoji( + const std::vector &query, + base::flat_set &outResultSet) { + auto result = std::vector(); + const auto pushPlain = [&](EmojiPtr emoji) { + if (result.size() < kEmojiSearchLimit + && outResultSet.emplace(emoji).second) { + result.push_back(emoji); + } + if (const auto original = emoji->original(); original != emoji) { + outResultSet.emplace(original); + } + }; + auto refreshed = false; + auto &keywords = Core::App().emojiKeywords(); + for (const auto &entry : query) { + if (const auto emoji = Ui::Emoji::Find(entry)) { + pushPlain(emoji); + if (result.size() >= kEmojiSearchLimit) { + return result; + } + } else if (!entry.isEmpty()) { + if (!refreshed) { + refreshed = true; + keywords.refresh(); + } + const auto list = keywords.queryMine(entry); + for (const auto &entry : list) { + pushPlain(entry.emoji); + if (result.size() >= kEmojiSearchLimit) { + return result; + } + } + } + } + return result; +} + StickerIcon::StickerIcon(uint64 setId) : setId(setId) { } diff --git a/Telegram/SourceFiles/chat_helpers/stickers_list_footer.h b/Telegram/SourceFiles/chat_helpers/stickers_list_footer.h index b9938362c..1a08f6853 100644 --- a/Telegram/SourceFiles/chat_helpers/stickers_list_footer.h +++ b/Telegram/SourceFiles/chat_helpers/stickers_list_footer.h @@ -63,6 +63,10 @@ struct GifSection { [[nodiscard]] rpl::producer> GifSectionsValue( not_null session); +[[nodiscard]] std::vector SearchEmoji( + const std::vector &query, + base::flat_set &outResultSet); + struct StickerIcon { explicit StickerIcon(uint64 setId); StickerIcon( diff --git a/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp b/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp index 49a97cc5e..2227bb499 100644 --- a/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp +++ b/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp @@ -2557,17 +2557,13 @@ void StickersListWidget::beforeHiding() { void StickersListWidget::setupSearch() { const auto session = &_controller->session(); _search = MakeSearch(this, st(), [=](std::vector &&query) { - auto emoji = query | ranges::views::transform([](const QString &k) { - return Ui::Emoji::Find(k); - }) | ranges::views::filter([](EmojiPtr emoji) { - return (emoji != nullptr); - }) | ranges::to_vector; + auto set = base::flat_set(); auto text = ranges::accumulate(query, QString(), []( QString a, QString b) { return a.isEmpty() ? b : (a + ' ' + b); }); - searchForSets(std::move(text), std::move(emoji)); + searchForSets(std::move(text), SearchEmoji(query, set)); }, session); } diff --git a/Telegram/SourceFiles/data/stickers/data_stickers.cpp b/Telegram/SourceFiles/data/stickers/data_stickers.cpp index 80d6ab959..4b778d0b1 100644 --- a/Telegram/SourceFiles/data/stickers/data_stickers.cpp +++ b/Telegram/SourceFiles/data/stickers/data_stickers.cpp @@ -1273,11 +1273,11 @@ std::vector> Stickers::getListByEmoji( for (const auto document : *list) { const auto sticker = document->sticker(); if (!sticker) { - return; + continue; } else if (!single) { const auto main = Ui::Emoji::Find(sticker->alt); if (!main || !all.contains(main)) { - return; + continue; } } const auto installDate = my ? set->installDate : TimeId(0);