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;
|
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
|
//@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 sticker sets to return
|
//@sticker_type Type of the stickers to return
|
||||||
//@emoji String representation of emoji. If empty, returns all known installed stickers
|
//@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
|
//@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
|
//@chat_id Chat identifier for which to return stickers. Available custom emoji stickers may be different for different chats
|
||||||
getStickers sticker_type:StickerType emoji:string limit:int32 chat_id:int53 = Stickers;
|
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
|
//@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;
|
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,
|
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);
|
auto it = sticker_set->emoji_stickers_map_.find(query);
|
||||||
if (it != sticker_set->emoji_stickers_map_.end()) {
|
if (it != sticker_set->emoji_stickers_map_.end()) {
|
||||||
LOG(INFO) << "Add " << it->second << " stickers from " << sticker_set->id_;
|
LOG(INFO) << "Add " << it->second << " stickers from " << sticker_set->id_;
|
||||||
append(result, it->second);
|
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);
|
const Sticker *s = get_sticker(sticker_id);
|
||||||
CHECK(s != nullptr);
|
CHECK(s != nullptr);
|
||||||
if (remove_emoji_modifiers(s->alt_) == query) {
|
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_) {
|
if (sticker_set == nullptr || !sticker_set->was_loaded_) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto map_it = sticker_set->emoji_stickers_map_.find(query);
|
auto it = sticker_set->emoji_stickers_map_.find(query);
|
||||||
if (map_it != sticker_set->emoji_stickers_map_.end()) {
|
if (it != sticker_set->emoji_stickers_map_.end()) {
|
||||||
if (td::contains(map_it->second, sticker_id)) {
|
if (td::contains(it->second, sticker_id)) {
|
||||||
return true;
|
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;
|
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)};
|
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) {
|
bool force, Promise<Unit> &&promise) {
|
||||||
if (G()->close_flag()) {
|
if (G()->close_flag()) {
|
||||||
promise.set_error(Global::request_aborted_error());
|
promise.set_error(Global::request_aborted_error());
|
||||||
@ -4288,20 +4324,20 @@ vector<FileId> StickersManager::get_stickers(StickerType sticker_type, string em
|
|||||||
CHECK(force == false);
|
CHECK(force == false);
|
||||||
load_installed_sticker_sets(
|
load_installed_sticker_sets(
|
||||||
sticker_type,
|
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 {
|
force, promise = std::move(promise)](Result<Unit> result) mutable {
|
||||||
if (result.is_error()) {
|
if (result.is_error()) {
|
||||||
promise.set_error(result.move_as_error());
|
promise.set_error(result.move_as_error());
|
||||||
} else {
|
} 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));
|
force, std::move(promise));
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
remove_emoji_modifiers_in_place(emoji);
|
remove_emoji_modifiers_in_place(query);
|
||||||
if (!emoji.empty()) {
|
if (!query.empty()) {
|
||||||
if (sticker_type == StickerType::Regular) {
|
if (sticker_type == StickerType::Regular) {
|
||||||
if (!are_recent_stickers_loaded_[0 /*is_attached*/]) {
|
if (!are_recent_stickers_loaded_[0 /*is_attached*/]) {
|
||||||
load_recent_stickers(false, std::move(promise));
|
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];
|
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]);
|
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;
|
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());
|
prepend_sticker_ids.reserve(favorite_sticker_ids_.size() + recent_sticker_ids_[0].size());
|
||||||
append(prepend_sticker_ids, recent_sticker_ids_[0]);
|
append(prepend_sticker_ids, recent_sticker_ids_[0]);
|
||||||
for (auto sticker_id : favorite_sticker_ids_) {
|
for (auto sticker_id : favorite_sticker_ids_) {
|
||||||
@ -4413,7 +4449,7 @@ vector<FileId> StickersManager::get_stickers(StickerType sticker_type, string em
|
|||||||
|
|
||||||
vector<FileId> result;
|
vector<FileId> result;
|
||||||
auto limit_size_t = static_cast<size_t>(limit);
|
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) {
|
for (const auto &sticker_set_id : examined_sticker_set_ids) {
|
||||||
const StickerSet *sticker_set = get_sticker_set(sticker_set_id);
|
const StickerSet *sticker_set = get_sticker_set(sticker_set_id);
|
||||||
if (sticker_set == nullptr || !sticker_set->was_loaded_) {
|
if (sticker_set == nullptr || !sticker_set->was_loaded_) {
|
||||||
@ -4427,6 +4463,8 @@ vector<FileId> StickersManager::get_stickers(StickerType sticker_type, string em
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} 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;
|
vector<const StickerSet *> examined_sticker_sets;
|
||||||
for (const auto &sticker_set_id : examined_sticker_set_ids) {
|
for (const auto &sticker_set_id : examined_sticker_set_ids) {
|
||||||
const StickerSet *sticker_set = get_sticker_set(sticker_set_id);
|
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_);
|
return is_sticker_format_animated(lhs->sticker_format_) && !is_sticker_format_animated(rhs->sticker_format_);
|
||||||
});
|
});
|
||||||
for (auto sticker_set : examined_sticker_sets) {
|
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;
|
vector<FileId> sorted;
|
||||||
@ -4470,8 +4508,8 @@ vector<FileId> StickersManager::get_stickers(StickerType sticker_type, string em
|
|||||||
<< (it - result.begin());
|
<< (it - result.begin());
|
||||||
*it = FileId();
|
*it = FileId();
|
||||||
is_good = true;
|
is_good = true;
|
||||||
} else if (can_found_sticker_by_query(sticker_id, emoji)) {
|
} else if (can_found_sticker_by_query(sticker_id, query, prepared_query)) {
|
||||||
LOG(INFO) << "Found prepend sticker " << sticker_id << " has matching emoji";
|
LOG(INFO) << "Found prepend sticker " << sticker_id;
|
||||||
is_good = true;
|
is_good = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,7 +143,7 @@ class StickersManager final : public Actor {
|
|||||||
tl_object_ptr<telegram_api::InputEncryptedFile> input_file,
|
tl_object_ptr<telegram_api::InputEncryptedFile> input_file,
|
||||||
BufferSlice thumbnail, int32 layer) const;
|
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);
|
Promise<Unit> &&promise);
|
||||||
|
|
||||||
void search_stickers(string emoji, int32 limit, Promise<td_api::object_ptr<td_api::stickers>> &&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 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);
|
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<> {
|
class GetStickersRequest final : public RequestActor<> {
|
||||||
StickerType sticker_type_;
|
StickerType sticker_type_;
|
||||||
string emoji_;
|
string query_;
|
||||||
int32 limit_;
|
int32 limit_;
|
||||||
DialogId dialog_id_;
|
DialogId dialog_id_;
|
||||||
|
|
||||||
vector<FileId> sticker_ids_;
|
vector<FileId> sticker_ids_;
|
||||||
|
|
||||||
void do_run(Promise<Unit> &&promise) final {
|
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));
|
std::move(promise));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2002,11 +2002,11 @@ class GetStickersRequest final : public RequestActor<> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
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)
|
int64 dialog_id)
|
||||||
: RequestActor(std::move(td), request_id)
|
: RequestActor(std::move(td), request_id)
|
||||||
, sticker_type_(sticker_type)
|
, sticker_type_(sticker_type)
|
||||||
, emoji_(std::move(emoji))
|
, query_(std::move(query))
|
||||||
, limit_(limit)
|
, limit_(limit)
|
||||||
, dialog_id_(dialog_id) {
|
, dialog_id_(dialog_id) {
|
||||||
set_tries(4);
|
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) {
|
void Td::on_request(uint64 id, td_api::getStickers &request) {
|
||||||
CHECK_IS_USER();
|
CHECK_IS_USER();
|
||||||
CLEAN_INPUT_STRING(request.emoji_);
|
CLEAN_INPUT_STRING(request.query_);
|
||||||
CREATE_REQUEST(GetStickersRequest, get_sticker_type(request.sticker_type_), std::move(request.emoji_), request.limit_,
|
CREATE_REQUEST(GetStickersRequest, get_sticker_type(request.sticker_type_), std::move(request.query_), request.limit_,
|
||||||
request.chat_id_);
|
request.chat_id_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user