Add td_api::searchInstalledStickerSets and td_api::searchStickerSets.

GitOrigin-RevId: 6abcb03bbbd79e3d1dc8156ac684de7100b85170
This commit is contained in:
levlam 2018-03-06 01:44:11 +03:00
parent 43e0d385f2
commit 17ea2cb2b6
8 changed files with 223 additions and 6 deletions

View File

@ -2515,9 +2515,15 @@ getAttachedStickerSets file_id:int32 = StickerSets;
//@description Returns information about a sticker set by its identifier @set_id Identifier of the sticker set //@description Returns information about a sticker set by its identifier @set_id Identifier of the sticker set
getStickerSet set_id:int64 = StickerSet; getStickerSet set_id:int64 = StickerSet;
//@description Searches for a sticker set by its short name @name Name of the sticker set //@description Searches for a sticker set by its name @name Name of the sticker set
searchStickerSet name:string = StickerSet; searchStickerSet name:string = StickerSet;
//@description Searches for installed sticker sets by looking for specified query in their title and name @is_masks Pass true to return mask sticker sets; pass false to return ordinary sticker sets @query Query to search for @limit Maximum number of sticker sets to return
searchInstalledStickerSets is_masks:Bool query:string limit:int32 = StickerSets;
//@description Searches for ordinary sticker sets by looking for specified query in their title and name. Excludes installed sticker sets from the results @query Query to search for
searchStickerSets query:string = StickerSets;
//@description Installs/uninstalls or activates/archives a sticker set @set_id Identifier of the sticker set @is_installed The new value of is_installed @is_archived The new value of is_archived. A sticker set can't be installed and archived simultaneously //@description Installs/uninstalls or activates/archives a sticker set @set_id Identifier of the sticker set @is_installed The new value of is_installed @is_archived The new value of is_archived. A sticker set can't be installed and archived simultaneously
changeStickerSet set_id:int64 is_installed:Bool is_archived:Bool = Ok; changeStickerSet set_id:int64 is_installed:Bool is_archived:Bool = Ok;

Binary file not shown.

View File

@ -3735,7 +3735,7 @@ std::pair<int32, vector<UserId>> ContactsManager::search_contacts(const string &
} }
promise.set_value(Unit()); promise.set_value(Unit());
return {narrow_cast<int32>(result.first), user_ids}; return {narrow_cast<int32>(result.first), std::move(user_ids)};
} }
void ContactsManager::set_profile_photo(const tl_object_ptr<td_api::InputFile> &input_photo, Promise<Unit> &&promise) { void ContactsManager::set_profile_photo(const tl_object_ptr<td_api::InputFile> &input_photo, Promise<Unit> &&promise) {

View File

@ -408,6 +408,33 @@ class GetStickerSetQuery : public Td::ResultHandler {
} }
}; };
class SearchStickerSetsQuery : public Td::ResultHandler {
string query_;
public:
void send(string query) {
query_ = std::move(query);
send_query(G()->net_query_creator().create(
create_storer(telegram_api::messages_searchStickerSets(0, false /*ignored*/, query_, 0))));
}
void on_result(uint64 id, BufferSlice packet) override {
auto result_ptr = fetch_result<telegram_api::messages_searchStickerSets>(packet);
if (result_ptr.is_error()) {
return on_error(id, result_ptr.move_as_error());
}
auto ptr = result_ptr.move_as_ok();
LOG(INFO) << "Receive result for search sticker sets: " << to_string(ptr);
td->stickers_manager_->on_find_sticker_sets_success(query_, std::move(ptr));
}
void on_error(uint64 id, Status status) override {
LOG(ERROR) << "Receive error for search sticker sets: " << status;
td->stickers_manager_->on_find_sticker_sets_fail(query_, std::move(status));
}
};
class InstallStickerSetQuery : public Td::ResultHandler { class InstallStickerSetQuery : public Td::ResultHandler {
Promise<Unit> promise_; Promise<Unit> promise_;
int64 set_id_; int64 set_id_;
@ -1379,6 +1406,10 @@ int64 StickersManager::on_get_sticker_set(tl_object_ptr<telegram_api::stickerSet
LOG(INFO) << "Sticker set " << set_id << " title has changed"; LOG(INFO) << "Sticker set " << set_id << " title has changed";
s->title = std::move(set->title_); s->title = std::move(set->title_);
s->is_changed = true; s->is_changed = true;
if (installed_sticker_sets_hints_[s->is_masks].has_key(set_id)) {
installed_sticker_sets_hints_[s->is_masks].add(set_id, s->title + " " + s->short_name);
}
} }
if (s->short_name != set->short_name_) { if (s->short_name != set->short_name_) {
LOG(ERROR) << "Sticker set " << set_id << " short name has changed from \"" << s->short_name << "\" to \"" LOG(ERROR) << "Sticker set " << set_id << " short name has changed from \"" << s->short_name << "\" to \""
@ -1386,6 +1417,10 @@ int64 StickersManager::on_get_sticker_set(tl_object_ptr<telegram_api::stickerSet
short_name_to_sticker_set_id_.erase(clean_username(s->short_name)); short_name_to_sticker_set_id_.erase(clean_username(s->short_name));
s->short_name = std::move(set->short_name_); s->short_name = std::move(set->short_name_);
s->is_changed = true; s->is_changed = true;
if (installed_sticker_sets_hints_[s->is_masks].has_key(set_id)) {
installed_sticker_sets_hints_[s->is_masks].add(set_id, s->title + " " + s->short_name);
}
} }
if (s->sticker_count != set->count_ || s->hash != set->hash_) { if (s->sticker_count != set->count_ || s->hash != set->hash_) {
@ -1608,6 +1643,7 @@ void StickersManager::on_get_installed_sticker_sets(bool is_masks,
vector<int64> installed_sticker_set_ids; vector<int64> installed_sticker_set_ids;
vector<int32> hashes; vector<int32> hashes;
vector<int64> sticker_set_ids; vector<int64> sticker_set_ids;
std::reverse(stickers->sets_.begin(), stickers->sets_.end()); // apply installed sticker sets in reverse order
for (auto &set : stickers->sets_) { for (auto &set : stickers->sets_) {
hashes.push_back(set->hash_); hashes.push_back(set->hash_);
sticker_set_ids.push_back(set->id_); sticker_set_ids.push_back(set->id_);
@ -1633,6 +1669,9 @@ void StickersManager::on_get_installed_sticker_sets(bool is_masks,
sets_to_load.push_back(set_id); sets_to_load.push_back(set_id);
} }
} }
std::reverse(hashes.begin(), hashes.end());
std::reverse(installed_sticker_set_ids.begin(), installed_sticker_set_ids.end());
std::reverse(sticker_set_ids.begin(), sticker_set_ids.end());
if (!sets_to_load.empty()) { if (!sets_to_load.empty()) {
load_sticker_sets(std::move(sets_to_load), Auto()); load_sticker_sets(std::move(sets_to_load), Auto());
@ -1906,6 +1945,97 @@ int64 StickersManager::search_sticker_set(const string &short_name_to_search, Pr
return sticker_set->id; return sticker_set->id;
} }
std::pair<int32, vector<int64>> StickersManager::search_installed_sticker_sets(bool is_masks, const string &query,
int32 limit, Promise<Unit> &&promise) {
LOG(INFO) << "Search installed " << (is_masks ? "masks " : "") << "sticker sets with query = \"" << query
<< "\" and limit = " << limit;
if (limit < 0) {
promise.set_error(Status::Error(400, "Limit must be non-negative"));
return {};
}
if (!are_installed_sticker_sets_loaded_[is_masks]) {
load_installed_sticker_sets(is_masks, std::move(promise));
return {};
}
reload_installed_sticker_sets(is_masks, false);
std::pair<size_t, vector<int64>> result = installed_sticker_sets_hints_[is_masks].search(query, limit);
promise.set_value(Unit());
return {narrow_cast<int32>(result.first), std::move(result.second)};
}
vector<int64> StickersManager::search_sticker_sets(const string &query, Promise<Unit> &&promise) {
auto q = clean_name(query, 1000);
auto it = found_sticker_sets_.find(q);
if (it != found_sticker_sets_.end()) {
promise.set_value(Unit());
return it->second;
}
auto &promises = search_sticker_sets_queries_[q];
promises.push_back(std::move(promise));
if (promises.size() == 1u) {
td_->create_handler<SearchStickerSetsQuery>()->send(std::move(q));
}
return {};
}
void StickersManager::on_find_sticker_sets_success(
const string &query, tl_object_ptr<telegram_api::messages_FoundStickerSets> &&sticker_sets) {
CHECK(sticker_sets != nullptr);
switch (sticker_sets->get_id()) {
case telegram_api::messages_foundStickerSetsNotModified::ID:
return on_find_sticker_sets_fail(query, Status::Error(500, "Receive messages.foundStickerSetsNotModified"));
case telegram_api::messages_foundStickerSets::ID: {
auto found_stickers_sets = move_tl_object_as<telegram_api::messages_foundStickerSets>(sticker_sets);
vector<int64> &sticker_set_ids = found_sticker_sets_[query];
CHECK(sticker_set_ids.empty());
for (auto &sticker_set : found_stickers_sets->sets_) {
int64 set_id = on_get_sticker_set_covered(std::move(sticker_set), true);
if (set_id == 0) {
continue;
}
update_sticker_set(get_sticker_set(set_id));
sticker_set_ids.push_back(set_id);
}
send_update_installed_sticker_sets();
break;
}
default:
UNREACHABLE();
}
auto it = search_sticker_sets_queries_.find(query);
CHECK(it != search_sticker_sets_queries_.end());
CHECK(!it->second.empty());
auto promises = std::move(it->second);
search_sticker_sets_queries_.erase(it);
for (auto &promise : promises) {
promise.set_value(Unit());
}
}
void StickersManager::on_find_sticker_sets_fail(const string &query, Status &&error) {
CHECK(found_sticker_sets_.count(query) == 0);
auto it = search_sticker_sets_queries_.find(query);
CHECK(it != search_sticker_sets_queries_.end());
CHECK(!it->second.empty());
auto promises = std::move(it->second);
search_sticker_sets_queries_.erase(it);
for (auto &promise : promises) {
promise.set_error(error.clone());
}
}
void StickersManager::change_sticker_set(int64 set_id, bool is_installed, bool is_archived, Promise<Unit> &&promise) { void StickersManager::change_sticker_set(int64 set_id, bool is_installed, bool is_archived, Promise<Unit> &&promise) {
if (is_installed && is_archived) { if (is_installed && is_archived) {
return promise.set_error(Status::Error(400, "Sticker set can't be installed and archived simultaneously")); return promise.set_error(Status::Error(400, "Sticker set can't be installed and archived simultaneously"));
@ -1965,8 +2095,11 @@ void StickersManager::on_update_sticker_set(StickerSet *sticker_set, bool is_ins
need_update_installed_sticker_sets_[sticker_set->is_masks] = true; need_update_installed_sticker_sets_[sticker_set->is_masks] = true;
if (is_added) { if (is_added) {
installed_sticker_sets_hints_[sticker_set->is_masks].add(sticker_set->id,
sticker_set->title + " " + sticker_set->short_name);
sticker_set_ids.insert(sticker_set_ids.begin(), sticker_set->id); sticker_set_ids.insert(sticker_set_ids.begin(), sticker_set->id);
} else { } else {
installed_sticker_sets_hints_[sticker_set->is_masks].remove(sticker_set->id);
sticker_set_ids.erase(std::remove(sticker_set_ids.begin(), sticker_set_ids.end(), sticker_set->id), sticker_set_ids.erase(std::remove(sticker_set_ids.begin(), sticker_set_ids.end(), sticker_set->id),
sticker_set_ids.end()); sticker_set_ids.end());
} }
@ -2069,13 +2202,14 @@ void StickersManager::on_load_installed_sticker_sets_finished(bool is_masks, vec
} }
} }
if (need_reload) { if (need_reload) {
LOG(ERROR) << "Reload installed sticker sets, because only " << installed_sticker_set_ids_[is_masks].size() LOG(ERROR) << "Reload installed " << (is_masks ? "masks " : "") << "sticker sets, because only "
<< " of " << installed_sticker_set_ids.size() << " are really installed"; << installed_sticker_set_ids_[is_masks].size() << " of " << installed_sticker_set_ids.size()
<< " are really installed";
reload_installed_sticker_sets(is_masks, true); reload_installed_sticker_sets(is_masks, true);
} else if (!old_installed_sticker_set_ids.empty() && } else if (!old_installed_sticker_set_ids.empty() &&
old_installed_sticker_set_ids != installed_sticker_set_ids_[is_masks]) { old_installed_sticker_set_ids != installed_sticker_set_ids_[is_masks]) {
LOG(ERROR) << "Reload installed sticker sets, because they has changed from " << old_installed_sticker_set_ids LOG(ERROR) << "Reload installed " << (is_masks ? "masks " : "") << "sticker sets, because they has changed from "
<< " to " << installed_sticker_set_ids_[is_masks]; << old_installed_sticker_set_ids << " to " << installed_sticker_set_ids_[is_masks];
reload_installed_sticker_sets(is_masks, true); reload_installed_sticker_sets(is_masks, true);
} }

View File

@ -17,6 +17,7 @@
#include "td/utils/buffer.h" #include "td/utils/buffer.h"
#include "td/utils/common.h" #include "td/utils/common.h"
#include "td/utils/Hints.h"
#include "td/utils/Status.h" #include "td/utils/Status.h"
#include "td/telegram/td_api.h" #include "td/telegram/td_api.h"
@ -74,6 +75,11 @@ class StickersManager : public Actor {
int64 search_sticker_set(const string &short_name_to_search, Promise<Unit> &&promise); int64 search_sticker_set(const string &short_name_to_search, Promise<Unit> &&promise);
std::pair<int32, vector<int64>> search_installed_sticker_sets(bool is_masks, const string &query, int32 limit,
Promise<Unit> &&promise);
vector<int64> search_sticker_sets(const string &query, Promise<Unit> &&promise);
void change_sticker_set(int64 set_id, bool is_installed, bool is_archived, Promise<Unit> &&promise); void change_sticker_set(int64 set_id, bool is_installed, bool is_archived, Promise<Unit> &&promise);
void view_featured_sticker_sets(const vector<int64> &sticker_set_ids); void view_featured_sticker_sets(const vector<int64> &sticker_set_ids);
@ -192,6 +198,11 @@ class StickersManager : public Actor {
void on_uploaded_sticker_file(FileId file_id, tl_object_ptr<telegram_api::MessageMedia> media, void on_uploaded_sticker_file(FileId file_id, tl_object_ptr<telegram_api::MessageMedia> media,
Promise<Unit> &&promise); Promise<Unit> &&promise);
void on_find_sticker_sets_success(const string &query,
tl_object_ptr<telegram_api::messages_FoundStickerSets> &&sticker_sets);
void on_find_sticker_sets_fail(const string &query, Status &&error);
private: private:
static constexpr int32 MAX_FEATURED_STICKER_SET_VIEW_DELAY = 5; static constexpr int32 MAX_FEATURED_STICKER_SET_VIEW_DELAY = 5;
static constexpr size_t RECENT_STICKERS_LIMIT = 30; static constexpr size_t RECENT_STICKERS_LIMIT = 30;
@ -450,6 +461,11 @@ class StickersManager : public Actor {
std::unordered_map<FileId, vector<int64>, FileIdHash> attached_sticker_sets_; std::unordered_map<FileId, vector<int64>, FileIdHash> attached_sticker_sets_;
Hints installed_sticker_sets_hints_[2]; // search installed sticker sets by their title and name
std::unordered_map<string, vector<int64>> found_sticker_sets_;
std::unordered_map<string, vector<Promise<Unit>>> search_sticker_sets_queries_;
std::unordered_set<int64> pending_viewed_featured_sticker_set_ids_; std::unordered_set<int64> pending_viewed_featured_sticker_set_ids_;
Timeout pending_featured_sticker_set_views_timeout_; Timeout pending_featured_sticker_set_views_timeout_;

View File

@ -2873,6 +2873,47 @@ class SearchStickerSetRequest : public RequestActor<> {
} }
}; };
class SearchInstalledStickerSetsRequest : public RequestActor<> {
bool is_masks_;
string query_;
int32 limit_;
std::pair<int32, vector<int64>> sticker_set_ids_;
void do_run(Promise<Unit> &&promise) override {
sticker_set_ids_ =
td->stickers_manager_->search_installed_sticker_sets(is_masks_, query_, limit_, std::move(promise));
}
void do_send_result() override {
send_result(td->stickers_manager_->get_sticker_sets_object(sticker_set_ids_.first, sticker_set_ids_.second, 5));
}
public:
SearchInstalledStickerSetsRequest(ActorShared<Td> td, uint64 request_id, bool is_masks, string &&query, int32 limit)
: RequestActor(std::move(td), request_id), is_masks_(is_masks), query_(std::move(query)), limit_(limit) {
}
};
class SearchStickerSetsRequest : public RequestActor<> {
string query_;
vector<int64> sticker_set_ids_;
void do_run(Promise<Unit> &&promise) override {
sticker_set_ids_ = td->stickers_manager_->search_sticker_sets(query_, std::move(promise));
}
void do_send_result() override {
send_result(td->stickers_manager_->get_sticker_sets_object(-1, sticker_set_ids_, 5));
}
public:
SearchStickerSetsRequest(ActorShared<Td> td, uint64 request_id, string &&query)
: RequestActor(std::move(td), request_id), query_(std::move(query)) {
}
};
class ChangeStickerSetRequest : public RequestOnceActor { class ChangeStickerSetRequest : public RequestOnceActor {
int64 set_id_; int64 set_id_;
bool is_installed_; bool is_installed_;
@ -6253,6 +6294,18 @@ void Td::on_request(uint64 id, td_api::searchStickerSet &request) {
CREATE_REQUEST(SearchStickerSetRequest, std::move(request.name_)); CREATE_REQUEST(SearchStickerSetRequest, std::move(request.name_));
} }
void Td::on_request(uint64 id, td_api::searchInstalledStickerSets &request) {
CHECK_AUTH();
CLEAN_INPUT_STRING(request.query_);
CREATE_REQUEST(SearchInstalledStickerSetsRequest, request.is_masks_, std::move(request.query_), request.limit_);
}
void Td::on_request(uint64 id, td_api::searchStickerSets &request) {
CHECK_AUTH();
CLEAN_INPUT_STRING(request.query_);
CREATE_REQUEST(SearchStickerSetsRequest, std::move(request.query_));
}
void Td::on_request(uint64 id, const td_api::changeStickerSet &request) { void Td::on_request(uint64 id, const td_api::changeStickerSet &request) {
CHECK_AUTH(); CHECK_AUTH();
CHECK_IS_USER(); CHECK_IS_USER();

View File

@ -657,6 +657,10 @@ class Td final : public NetQueryCallback {
void on_request(uint64 id, td_api::searchStickerSet &request); void on_request(uint64 id, td_api::searchStickerSet &request);
void on_request(uint64 id, td_api::searchInstalledStickerSets &request);
void on_request(uint64 id, td_api::searchStickerSets &request);
void on_request(uint64 id, const td_api::changeStickerSet &request); void on_request(uint64 id, const td_api::changeStickerSet &request);
void on_request(uint64 id, const td_api::viewTrendingStickerSets &request); void on_request(uint64 id, const td_api::viewTrendingStickerSets &request);

View File

@ -1618,6 +1618,10 @@ class CliClient final : public Actor {
send_request(make_tl_object<td_api::removeTopChat>(get_top_chat_category(category), as_chat_id(chat_id))); send_request(make_tl_object<td_api::removeTopChat>(get_top_chat_category(category), as_chat_id(chat_id)));
} else if (op == "sss") { } else if (op == "sss") {
send_request(make_tl_object<td_api::searchStickerSet>(args)); send_request(make_tl_object<td_api::searchStickerSet>(args));
} else if (op == "siss") {
send_request(make_tl_object<td_api::searchInstalledStickerSets>(false, args, 2));
} else if (op == "ssss") {
send_request(make_tl_object<td_api::searchStickerSets>(args));
} else if (op == "css") { } else if (op == "css") {
string set_id; string set_id;
string is_installed; string is_installed;