diff --git a/td/telegram/AttachMenuManager.cpp b/td/telegram/AttachMenuManager.cpp index 64405ba9d..54f7f15df 100644 --- a/td/telegram/AttachMenuManager.cpp +++ b/td/telegram/AttachMenuManager.cpp @@ -694,7 +694,7 @@ void AttachMenuManager::schedule_ping_web_view() { ping_web_view_timeout_.set_timeout_in(PING_WEB_VIEW_TIMEOUT); } -void AttachMenuManager::get_web_app(UserId bot_user_id, string &&web_app_short_name, +void AttachMenuManager::get_web_app(UserId bot_user_id, const string &web_app_short_name, Promise> &&promise) { TRY_RESULT_PROMISE(promise, input_user, td_->contacts_manager_->get_input_user(bot_user_id)); TRY_RESULT_PROMISE(promise, bot_data, td_->contacts_manager_->get_bot_data(bot_user_id)); @@ -722,10 +722,29 @@ void AttachMenuManager::on_get_web_app(UserId bot_user_id, string web_app_short_ } WebApp web_app(td_, telegram_api::move_object_as(bot_app->app_), DialogId(bot_user_id)); + auto file_ids = web_app.get_file_ids(td_); + if (!file_ids.empty()) { + auto file_source_id = get_web_app_file_source_id(bot_user_id, web_app_short_name); + for (auto file_id : file_ids) { + td_->file_manager_->add_file_source(file_id, file_source_id); + } + } promise.set_value(td_api::make_object(web_app.get_web_app_object(td_), bot_app->request_write_access_, !bot_app->inactive_)); } +void AttachMenuManager::reload_web_app(UserId bot_user_id, const string &web_app_short_name, Promise &&promise) { + get_web_app(bot_user_id, web_app_short_name, + PromiseCreator::lambda( + [promise = std::move(promise)](Result> result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + promise.set_value(Unit()); + } + })); +} + void AttachMenuManager::request_app_web_view(DialogId dialog_id, UserId bot_user_id, string &&web_app_short_name, string &&start_parameter, const td_api::object_ptr &theme, @@ -1133,6 +1152,19 @@ FileSourceId AttachMenuManager::get_attach_menu_bot_file_source_id(UserId user_i return source_id; } +FileSourceId AttachMenuManager::get_web_app_file_source_id(UserId user_id, const string &short_name) { + if (!user_id.is_valid() || !is_active()) { + return FileSourceId(); + } + + auto &source_id = web_app_file_source_ids_[user_id][short_name]; + if (!source_id.is_valid()) { + source_id = td_->file_reference_manager_->create_web_app_file_source(user_id, short_name); + } + VLOG(file_references) << "Return " << source_id << " for web app " << user_id << '/' << short_name; + return source_id; +} + void AttachMenuManager::toggle_bot_is_added_to_attach_menu(UserId user_id, bool is_added, bool allow_write_access, Promise &&promise) { CHECK(is_active()); diff --git a/td/telegram/AttachMenuManager.h b/td/telegram/AttachMenuManager.h index b298e48cd..3983bfb9c 100644 --- a/td/telegram/AttachMenuManager.h +++ b/td/telegram/AttachMenuManager.h @@ -32,9 +32,11 @@ class AttachMenuManager final : public Actor { void init(); - void get_web_app(UserId bot_user_id, string &&web_app_short_name, + void get_web_app(UserId bot_user_id, const string &web_app_short_name, Promise> &&promise); + void reload_web_app(UserId bot_user_id, const string &web_app_short_name, Promise &&promise); + void request_app_web_view(DialogId dialog_id, UserId bot_user_id, string &&web_app_short_name, string &&start_parameter, const td_api::object_ptr &theme, string &&platform, bool allow_write_access, Promise &&promise); @@ -57,6 +59,8 @@ class AttachMenuManager final : public Actor { FileSourceId get_attach_menu_bot_file_source_id(UserId user_id); + FileSourceId get_web_app_file_source_id(UserId user_id, const string &short_name); + void toggle_bot_is_added_to_attach_menu(UserId user_id, bool is_added, bool allow_write_access, Promise &&promise); @@ -165,6 +169,8 @@ class AttachMenuManager final : public Actor { FlatHashMap attach_menu_bot_file_source_ids_; vector> reload_attach_menu_bots_queries_; + FlatHashMap, UserIdHash> web_app_file_source_ids_; + struct OpenedWebView { DialogId dialog_id_; UserId bot_user_id_; diff --git a/td/telegram/FileReferenceManager.cpp b/td/telegram/FileReferenceManager.cpp index dbe278707..7a0fbc2c8 100644 --- a/td/telegram/FileReferenceManager.cpp +++ b/td/telegram/FileReferenceManager.cpp @@ -61,21 +61,22 @@ size_t FileReferenceManager::get_file_reference_error_pos(const Status &error) { /* fileSourceMessage chat_id:int53 message_id:int53 = FileSource; // repaired with get_message_from_server -fileSourceUserProfilePhoto user_id:int32 photo_id:int64 = FileSource; // repaired with photos.getUserPhotos -fileSourceBasicGroupPhoto basic_group_id:int32 = FileSource; // no need to repair -fileSourceSupergroupPhoto supergroup_id:int32 = FileSource; // no need to repair +fileSourceUserProfilePhoto user_id:int53 photo_id:int64 = FileSource; // repaired with photos.getUserPhotos +fileSourceBasicGroupPhoto basic_group_id:int53 = FileSource; // no need to repair +fileSourceSupergroupPhoto supergroup_id:int53 = FileSource; // no need to repair fileSourceWebPage url:string = FileSource; // repaired with messages.getWebPage fileSourceWallpapers = FileSource; // can't be repaired fileSourceSavedAnimations = FileSource; // repaired with messages.getSavedGifs fileSourceRecentStickers is_attached:Bool = FileSource; // repaired with messages.getRecentStickers, not reliable fileSourceFavoriteStickers = FileSource; // repaired with messages.getFavedStickers, not reliable fileSourceBackground background_id:int64 access_hash:int64 = FileSource; // repaired with account.getWallPaper -fileSourceBasicGroupFull basic_group_id:int32 = FileSource; // repaired with messages.getFullChat -fileSourceSupergroupFull supergroup_id:int32 = FileSource; // repaired with messages.getFullChannel +fileSourceBasicGroupFull basic_group_id:int53 = FileSource; // repaired with messages.getFullChat +fileSourceSupergroupFull supergroup_id:int53 = FileSource; // repaired with messages.getFullChannel fileSourceAppConfig = FileSource; // repaired with help.getAppConfig, not reliable fileSourceSavedRingtones = FileSource; // repaired with account.getSavedRingtones fileSourceUserFull = FileSource; // repaired with users.getFullUser -fileSourceAttachmentMenuBot = FileSource; // repaired with messages.getAttachMenuBot +fileSourceAttachmentMenuBot user_id:int53 = FileSource; // repaired with messages.getAttachMenuBot +fileSourceWebApp user_id:int53 short_name:string = FileSource; // repaired with messages.getAttachMenuBot */ FileSourceId FileReferenceManager::get_current_file_source_id() const { @@ -155,6 +156,11 @@ FileSourceId FileReferenceManager::create_attach_menu_bot_file_source(UserId use return add_file_source_id(source, PSLICE() << "attachment menu bot " << user_id); } +FileSourceId FileReferenceManager::create_web_app_file_source(UserId user_id, const string &short_name) { + FileSourceWebApp source{user_id, short_name}; + return add_file_source_id(source, PSLICE() << "web app " << user_id << '/' << short_name); +} + FileReferenceManager::Node &FileReferenceManager::add_node(NodeId node_id) { CHECK(node_id.is_valid()); auto &node = nodes_[node_id]; @@ -360,6 +366,10 @@ void FileReferenceManager::send_query(Destination dest, FileSourceId file_source [&](const FileSourceAttachMenuBot &source) { send_closure_later(G()->attach_menu_manager(), &AttachMenuManager::reload_attach_menu_bot, source.user_id, std::move(promise)); + }, + [&](const FileSourceWebApp &source) { + send_closure_later(G()->attach_menu_manager(), &AttachMenuManager::reload_web_app, source.user_id, + source.short_name, std::move(promise)); })); } diff --git a/td/telegram/FileReferenceManager.h b/td/telegram/FileReferenceManager.h index ce463b7a9..0a23bb8e5 100644 --- a/td/telegram/FileReferenceManager.h +++ b/td/telegram/FileReferenceManager.h @@ -63,6 +63,7 @@ class FileReferenceManager final : public Actor { FileSourceId create_saved_ringtones_file_source(); FileSourceId create_user_full_file_source(UserId user_id); FileSourceId create_attach_menu_bot_file_source(UserId user_id); + FileSourceId create_web_app_file_source(UserId user_id, const string &short_name); using NodeId = FileId; void repair_file_reference(NodeId node_id, Promise<> promise); @@ -164,13 +165,17 @@ class FileReferenceManager final : public Actor { struct FileSourceAttachMenuBot { UserId user_id; }; + struct FileSourceWebApp { + UserId user_id; + string short_name; + }; // append only using FileSource = Variant; + FileSourceSavedRingtones, FileSourceUserFull, FileSourceAttachMenuBot, FileSourceWebApp>; WaitFreeVector file_sources_; int64 query_generation_{0}; diff --git a/td/telegram/FileReferenceManager.hpp b/td/telegram/FileReferenceManager.hpp index e4d958b87..5df56491f 100644 --- a/td/telegram/FileReferenceManager.hpp +++ b/td/telegram/FileReferenceManager.hpp @@ -54,7 +54,11 @@ void FileReferenceManager::store_file_source(FileSourceId file_source_id, Storer [&](const FileSourceChannelFull &source) { td::store(source.channel_id, storer); }, [&](const FileSourceAppConfig &source) {}, [&](const FileSourceSavedRingtones &source) {}, [&](const FileSourceUserFull &source) { td::store(source.user_id, storer); }, - [&](const FileSourceAttachMenuBot &source) { td::store(source.user_id, storer); })); + [&](const FileSourceAttachMenuBot &source) { td::store(source.user_id, storer); }, + [&](const FileSourceWebApp &source) { + td::store(source.user_id, storer); + td::store(source.short_name, storer); + })); } template @@ -130,6 +134,13 @@ FileSourceId FileReferenceManager::parse_file_source(Td *td, ParserT &parser) { td::parse(user_id, parser); return td->attach_menu_manager_->get_attach_menu_bot_file_source_id(user_id); } + case 16: { + UserId user_id; + string short_name; + td::parse(user_id, parser); + td::parse(short_name, parser); + return td->attach_menu_manager_->get_web_app_file_source_id(user_id, short_name); + } default: parser.set_error("Invalid type in FileSource"); return FileSourceId(); diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index dfb7b134f..9630ccfdb 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -7814,8 +7814,7 @@ void Td::on_request(uint64 id, td_api::searchWebApp &request) { CHECK_IS_USER(); CLEAN_INPUT_STRING(request.web_app_short_name_); CREATE_REQUEST_PROMISE(); - attach_menu_manager_->get_web_app(UserId(request.bot_user_id_), std::move(request.web_app_short_name_), - std::move(promise)); + attach_menu_manager_->get_web_app(UserId(request.bot_user_id_), request.web_app_short_name_, std::move(promise)); } void Td::on_request(uint64 id, td_api::getWebAppLinkUrl &request) {