Support search by keywords in getStickers.
This commit is contained in:
parent
75a021e836
commit
e39bd45086
@ -6050,12 +6050,12 @@ sharePhoneNumber user_id:int53 = Ok;
|
||||
getUserProfilePhotos user_id:int53 offset:int32 limit:int32 = ChatPhotos;
|
||||
|
||||
|
||||
//@description Returns stickers from the installed sticker sets that correspond to a given emoji. If the emoji is non-empty, then favorite, recently used or trending stickers may also be returned
|
||||
//@sticker_type Type of the sticker sets to return
|
||||
//@emoji String representation of emoji. If empty, returns all known installed stickers
|
||||
//@description Returns stickers from the installed sticker sets that correspond to a given emoji or can be found by sticker-specific keywords. If the query is non-empty, then favorite, recently used or trending stickers may also be returned
|
||||
//@sticker_type Type of the stickers to return
|
||||
//@query Search query; an emoji or a keyword prefix. If empty, returns all known installed stickers
|
||||
//@limit The maximum number of stickers to be returned
|
||||
//@chat_id Chat identifier for which to return stickers. Available custom emoji may be different for different chats
|
||||
getStickers sticker_type:StickerType emoji:string limit:int32 chat_id:int53 = Stickers;
|
||||
//@chat_id Chat identifier for which to return stickers. Available custom emoji stickers may be different for different chats
|
||||
getStickers sticker_type:StickerType query:string limit:int32 chat_id:int53 = Stickers;
|
||||
|
||||
//@description Searches for stickers from public sticker sets that correspond to a given emoji @emoji String representation of emoji; must be non-empty @limit The maximum number of stickers to be returned; 0-100
|
||||
searchStickers emoji:string limit:int32 = Stickers;
|
||||
|
@ -4199,15 +4199,37 @@ const std::map<string, vector<FileId>> &StickersManager::get_sticker_set_keyword
|
||||
}
|
||||
|
||||
void StickersManager::find_sticker_set_stickers(const StickerSet *sticker_set, const string &query,
|
||||
vector<FileId> &result) {
|
||||
const string &prepared_query, vector<FileId> &result) {
|
||||
auto it = sticker_set->emoji_stickers_map_.find(query);
|
||||
if (it != sticker_set->emoji_stickers_map_.end()) {
|
||||
LOG(INFO) << "Add " << it->second << " stickers from " << sticker_set->id_;
|
||||
append(result, it->second);
|
||||
}
|
||||
|
||||
if (!prepared_query.empty()) {
|
||||
const auto &keywords_map = get_sticker_set_keywords(sticker_set);
|
||||
auto keywords_it = keywords_map.lower_bound(prepared_query);
|
||||
if (keywords_it != keywords_map.end() && begins_with(keywords_it->first, prepared_query)) {
|
||||
FlatHashSet<FileId, FileIdHash> found_sticker_ids;
|
||||
if (it != sticker_set->emoji_stickers_map_.end()) {
|
||||
for (auto file_id : it->second) {
|
||||
found_sticker_ids.insert(file_id);
|
||||
}
|
||||
}
|
||||
do {
|
||||
for (auto file_id : keywords_it->second) {
|
||||
if (found_sticker_ids.insert(file_id).second) {
|
||||
result.push_back(file_id);
|
||||
}
|
||||
}
|
||||
++keywords_it;
|
||||
} while (keywords_it != keywords_map.end() && begins_with(keywords_it->first, prepared_query));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool StickersManager::can_found_sticker_by_query(FileId sticker_id, const string &query) const {
|
||||
bool StickersManager::can_found_sticker_by_query(FileId sticker_id, const string &query,
|
||||
const string &prepared_query) const {
|
||||
const Sticker *s = get_sticker(sticker_id);
|
||||
CHECK(s != nullptr);
|
||||
if (remove_emoji_modifiers(s->alt_) == query) {
|
||||
@ -4218,12 +4240,26 @@ bool StickersManager::can_found_sticker_by_query(FileId sticker_id, const string
|
||||
if (sticker_set == nullptr || !sticker_set->was_loaded_) {
|
||||
return false;
|
||||
}
|
||||
auto map_it = sticker_set->emoji_stickers_map_.find(query);
|
||||
if (map_it != sticker_set->emoji_stickers_map_.end()) {
|
||||
if (td::contains(map_it->second, sticker_id)) {
|
||||
auto it = sticker_set->emoji_stickers_map_.find(query);
|
||||
if (it != sticker_set->emoji_stickers_map_.end()) {
|
||||
if (td::contains(it->second, sticker_id)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!prepared_query.empty()) {
|
||||
const auto &keywords_map = get_sticker_set_keywords(sticker_set);
|
||||
auto keywords_it = keywords_map.lower_bound(prepared_query);
|
||||
if (keywords_it != keywords_map.end() && begins_with(keywords_it->first, prepared_query)) {
|
||||
do {
|
||||
if (td::contains(keywords_it->second, sticker_id)) {
|
||||
return true;
|
||||
}
|
||||
++keywords_it;
|
||||
} while (keywords_it != keywords_map.end() && begins_with(keywords_it->first, prepared_query));
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -4271,7 +4307,7 @@ std::pair<vector<FileId>, vector<FileId>> StickersManager::split_stickers_by_pre
|
||||
return {std::move(regular_sticker_ids), std::move(premium_sticker_ids)};
|
||||
}
|
||||
|
||||
vector<FileId> StickersManager::get_stickers(StickerType sticker_type, string emoji, int32 limit, DialogId dialog_id,
|
||||
vector<FileId> StickersManager::get_stickers(StickerType sticker_type, string query, int32 limit, DialogId dialog_id,
|
||||
bool force, Promise<Unit> &&promise) {
|
||||
if (G()->close_flag()) {
|
||||
promise.set_error(Global::request_aborted_error());
|
||||
@ -4288,20 +4324,20 @@ vector<FileId> StickersManager::get_stickers(StickerType sticker_type, string em
|
||||
CHECK(force == false);
|
||||
load_installed_sticker_sets(
|
||||
sticker_type,
|
||||
PromiseCreator::lambda([actor_id = actor_id(this), sticker_type, emoji = std::move(emoji), limit, dialog_id,
|
||||
PromiseCreator::lambda([actor_id = actor_id(this), sticker_type, query = std::move(query), limit, dialog_id,
|
||||
force, promise = std::move(promise)](Result<Unit> result) mutable {
|
||||
if (result.is_error()) {
|
||||
promise.set_error(result.move_as_error());
|
||||
} else {
|
||||
send_closure(actor_id, &StickersManager::get_stickers, sticker_type, std::move(emoji), limit, dialog_id,
|
||||
send_closure(actor_id, &StickersManager::get_stickers, sticker_type, std::move(query), limit, dialog_id,
|
||||
force, std::move(promise));
|
||||
}
|
||||
}));
|
||||
return {};
|
||||
}
|
||||
|
||||
remove_emoji_modifiers_in_place(emoji);
|
||||
if (!emoji.empty()) {
|
||||
remove_emoji_modifiers_in_place(query);
|
||||
if (!query.empty()) {
|
||||
if (sticker_type == StickerType::Regular) {
|
||||
if (!are_recent_stickers_loaded_[0 /*is_attached*/]) {
|
||||
load_recent_stickers(false, std::move(promise));
|
||||
@ -4320,7 +4356,7 @@ vector<FileId> StickersManager::get_stickers(StickerType sticker_type, string em
|
||||
}
|
||||
|
||||
vector<StickerSetId> examined_sticker_set_ids = installed_sticker_set_ids_[type];
|
||||
if (!emoji.empty() && sticker_type == StickerType::CustomEmoji) {
|
||||
if (!query.empty() && sticker_type == StickerType::CustomEmoji) {
|
||||
append(examined_sticker_set_ids, featured_sticker_set_ids_[type]);
|
||||
}
|
||||
|
||||
@ -4339,7 +4375,7 @@ vector<FileId> StickersManager::get_stickers(StickerType sticker_type, string em
|
||||
}
|
||||
|
||||
vector<FileId> prepend_sticker_ids;
|
||||
if (!emoji.empty() && sticker_type == StickerType::Regular) {
|
||||
if (!query.empty() && sticker_type == StickerType::Regular) {
|
||||
prepend_sticker_ids.reserve(favorite_sticker_ids_.size() + recent_sticker_ids_[0].size());
|
||||
append(prepend_sticker_ids, recent_sticker_ids_[0]);
|
||||
for (auto sticker_id : favorite_sticker_ids_) {
|
||||
@ -4413,7 +4449,7 @@ vector<FileId> StickersManager::get_stickers(StickerType sticker_type, string em
|
||||
|
||||
vector<FileId> result;
|
||||
auto limit_size_t = static_cast<size_t>(limit);
|
||||
if (emoji.empty()) {
|
||||
if (query.empty()) {
|
||||
for (const auto &sticker_set_id : examined_sticker_set_ids) {
|
||||
const StickerSet *sticker_set = get_sticker_set(sticker_set_id);
|
||||
if (sticker_set == nullptr || !sticker_set->was_loaded_) {
|
||||
@ -4427,6 +4463,8 @@ vector<FileId> StickersManager::get_stickers(StickerType sticker_type, string em
|
||||
}
|
||||
}
|
||||
} else {
|
||||
auto prepared_query = utf8_prepare_search_string(query);
|
||||
LOG(INFO) << "Search stickers by " << query << " and keyword " << prepared_query;
|
||||
vector<const StickerSet *> examined_sticker_sets;
|
||||
for (const auto &sticker_set_id : examined_sticker_set_ids) {
|
||||
const StickerSet *sticker_set = get_sticker_set(sticker_set_id);
|
||||
@ -4449,7 +4487,7 @@ vector<FileId> StickersManager::get_stickers(StickerType sticker_type, string em
|
||||
return is_sticker_format_animated(lhs->sticker_format_) && !is_sticker_format_animated(rhs->sticker_format_);
|
||||
});
|
||||
for (auto sticker_set : examined_sticker_sets) {
|
||||
find_sticker_set_stickers(sticker_set, emoji, result);
|
||||
find_sticker_set_stickers(sticker_set, query, prepared_query, result);
|
||||
}
|
||||
|
||||
vector<FileId> sorted;
|
||||
@ -4470,8 +4508,8 @@ vector<FileId> StickersManager::get_stickers(StickerType sticker_type, string em
|
||||
<< (it - result.begin());
|
||||
*it = FileId();
|
||||
is_good = true;
|
||||
} else if (can_found_sticker_by_query(sticker_id, emoji)) {
|
||||
LOG(INFO) << "Found prepend sticker " << sticker_id << " has matching emoji";
|
||||
} else if (can_found_sticker_by_query(sticker_id, query, prepared_query)) {
|
||||
LOG(INFO) << "Found prepend sticker " << sticker_id;
|
||||
is_good = true;
|
||||
}
|
||||
|
||||
|
@ -143,7 +143,7 @@ class StickersManager final : public Actor {
|
||||
tl_object_ptr<telegram_api::InputEncryptedFile> input_file,
|
||||
BufferSlice thumbnail, int32 layer) const;
|
||||
|
||||
vector<FileId> get_stickers(StickerType sticker_type, string emoji, int32 limit, DialogId dialog_id, bool force,
|
||||
vector<FileId> get_stickers(StickerType sticker_type, string query, int32 limit, DialogId dialog_id, bool force,
|
||||
Promise<Unit> &&promise);
|
||||
|
||||
void search_stickers(string emoji, int32 limit, Promise<td_api::object_ptr<td_api::stickers>> &&promise);
|
||||
@ -903,9 +903,10 @@ class StickersManager final : public Actor {
|
||||
|
||||
static const std::map<string, vector<FileId>> &get_sticker_set_keywords(const StickerSet *sticker_set);
|
||||
|
||||
static void find_sticker_set_stickers(const StickerSet *sticker_set, const string &query, vector<FileId> &result);
|
||||
static void find_sticker_set_stickers(const StickerSet *sticker_set, const string &query,
|
||||
const string &prepared_query, vector<FileId> &result);
|
||||
|
||||
bool can_found_sticker_by_query(FileId sticker_id, const string &query) const;
|
||||
bool can_found_sticker_by_query(FileId sticker_id, const string &query, const string &prepared_query) const;
|
||||
|
||||
static string get_emoji_language_code_version_database_key(const string &language_code);
|
||||
|
||||
|
@ -1986,14 +1986,14 @@ class GetScopeNotificationSettingsRequest final : public RequestActor<> {
|
||||
|
||||
class GetStickersRequest final : public RequestActor<> {
|
||||
StickerType sticker_type_;
|
||||
string emoji_;
|
||||
string query_;
|
||||
int32 limit_;
|
||||
DialogId dialog_id_;
|
||||
|
||||
vector<FileId> sticker_ids_;
|
||||
|
||||
void do_run(Promise<Unit> &&promise) final {
|
||||
sticker_ids_ = td_->stickers_manager_->get_stickers(sticker_type_, emoji_, limit_, dialog_id_, get_tries() < 2,
|
||||
sticker_ids_ = td_->stickers_manager_->get_stickers(sticker_type_, query_, limit_, dialog_id_, get_tries() < 2,
|
||||
std::move(promise));
|
||||
}
|
||||
|
||||
@ -2002,11 +2002,11 @@ class GetStickersRequest final : public RequestActor<> {
|
||||
}
|
||||
|
||||
public:
|
||||
GetStickersRequest(ActorShared<Td> td, uint64 request_id, StickerType sticker_type, string &&emoji, int32 limit,
|
||||
GetStickersRequest(ActorShared<Td> td, uint64 request_id, StickerType sticker_type, string &&query, int32 limit,
|
||||
int64 dialog_id)
|
||||
: RequestActor(std::move(td), request_id)
|
||||
, sticker_type_(sticker_type)
|
||||
, emoji_(std::move(emoji))
|
||||
, query_(std::move(query))
|
||||
, limit_(limit)
|
||||
, dialog_id_(dialog_id) {
|
||||
set_tries(4);
|
||||
@ -6887,8 +6887,8 @@ void Td::on_request(uint64 id, td_api::closeSecretChat &request) {
|
||||
|
||||
void Td::on_request(uint64 id, td_api::getStickers &request) {
|
||||
CHECK_IS_USER();
|
||||
CLEAN_INPUT_STRING(request.emoji_);
|
||||
CREATE_REQUEST(GetStickersRequest, get_sticker_type(request.sticker_type_), std::move(request.emoji_), request.limit_,
|
||||
CLEAN_INPUT_STRING(request.query_);
|
||||
CREATE_REQUEST(GetStickersRequest, get_sticker_type(request.sticker_type_), std::move(request.query_), request.limit_,
|
||||
request.chat_id_);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user