diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 2c675cdd..4cf9507a 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -3601,9 +3601,13 @@ deleteSavedCredentials = Ok; //@description Returns a user that can be contacted to get support getSupportUser = User; + //@description Returns backgrounds installed by the user getBackgrounds = Backgrounds; +//@description Constructs persistent URL for a background @name Background name @type Background type +getBackgroundUrl name:string type:BackgroundType = HttpUrl; + //@description Returns information about the current localization target. This is an offline request if only_local is true. Can be called before authorization @only_local If true, returns only locally available information without sending network requests getLocalizationTargetInfo only_local:Bool = LocalizationTargetInfo; diff --git a/td/generate/scheme/td_api.tlo b/td/generate/scheme/td_api.tlo index 0605e78d..90c0f889 100644 Binary files a/td/generate/scheme/td_api.tlo and b/td/generate/scheme/td_api.tlo differ diff --git a/td/telegram/BackgroundManager.cpp b/td/telegram/BackgroundManager.cpp index 87ace2ed..b916d5b9 100644 --- a/td/telegram/BackgroundManager.cpp +++ b/td/telegram/BackgroundManager.cpp @@ -9,6 +9,7 @@ #include "td/telegram/td_api.h" #include "td/telegram/telegram_api.h" +#include "td/telegram/ConfigShared.h" #include "td/telegram/DialogId.h" #include "td/telegram/Document.h" #include "td/telegram/DocumentsManager.h" @@ -70,6 +71,91 @@ void BackgroundManager::get_backgrounds(Promise &&promise) { } } +Result BackgroundManager::get_background_type( + td_api::object_ptr type) { + if (type == nullptr) { + return Status::Error(400, "Type must not be empty"); + } + + BackgroundType result; + switch (type->get_id()) { + case td_api::backgroundTypeWallpaper::ID: { + auto wallpaper = td_api::move_object_as(type); + result = BackgroundType(wallpaper->is_blurred_, wallpaper->is_moving_); + break; + } + case td_api::backgroundTypePattern::ID: { + auto pattern = td_api::move_object_as(type); + result = BackgroundType(pattern->is_moving_, pattern->color_, pattern->intensity_); + break; + } + case td_api::backgroundTypeSolid::ID: { + auto solid = td_api::move_object_as(type); + result = BackgroundType(solid->color_); + break; + } + default: + UNREACHABLE(); + } + if (result.intensity < 0 || result.intensity > 100) { + return Status::Error(400, "Wrong intensity value"); + } + if (result.color < 0 || result.color > 0xFFFFFF) { + return Status::Error(400, "Wrong color value"); + } + return result; +} + +Result BackgroundManager::get_background_url(const string &name, + td_api::object_ptr background_type) const { + TRY_RESULT(type, get_background_type(std::move(background_type))); + + vector modes; + if (type.is_blurred) { + modes.emplace_back("blur"); + } + if (type.is_moving) { + modes.emplace_back("motion"); + } + string mode = implode(modes, '+'); + + auto get_color_string = [](int32 color) { + string result; + for (int i = 20; i >= 0; i -= 4) { + result += "0123456789abcdef"[(color >> i) & 0xf]; + } + return result; + }; + + string url = PSTRING() << G()->shared_config().get_option_string("t_me_url", "https://t.me/") << "bg/"; + switch (type.type) { + case BackgroundType::Type::Wallpaper: + url += name; + if (!mode.empty()) { + url += "?mode="; + url += mode; + } + return url; + case BackgroundType::Type::Pattern: + url += name; + url += "?intensity="; + url += to_string(type.intensity); + url += "&bg_color="; + url += get_color_string(type.color); + if (!mode.empty()) { + url += "&mode="; + url += mode; + } + return url; + case BackgroundType::Type::Solid: + url += get_color_string(type.color); + return url; + default: + UNREACHABLE(); + return url; + } +} + BackgroundManager::Background *BackgroundManager::add_background(BackgroundId background_id) { CHECK(background_id.is_valid()); return &backgrounds_[background_id]; diff --git a/td/telegram/BackgroundManager.h b/td/telegram/BackgroundManager.h index 9aaf958a..68676aea 100644 --- a/td/telegram/BackgroundManager.h +++ b/td/telegram/BackgroundManager.h @@ -31,6 +31,9 @@ class BackgroundManager : public Actor { void get_backgrounds(Promise &&promise); + Result get_background_url(const string &name, + td_api::object_ptr background_type) const; + td_api::object_ptr get_background_object(BackgroundId background_id) const; td_api::object_ptr get_backgrounds_object() const; @@ -72,6 +75,8 @@ class BackgroundManager : public Actor { const Background *get_background(BackgroundId background_id) const; + static Result get_background_type(td_api::object_ptr type); + static BackgroundType get_background_type(bool is_pattern, telegram_api::object_ptr settings); diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 812f0991..5a2aea74 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -6944,6 +6944,17 @@ void Td::on_request(uint64 id, const td_api::getBackgrounds &request) { CREATE_NO_ARGS_REQUEST(GetBackgroundsRequest); } +void Td::on_request(uint64 id, td_api::getBackgroundUrl &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.name_); + Result r_url = background_manager_->get_background_url(request.name_, std::move(request.type_)); + if (r_url.is_error()) { + return send_closure(actor_id(this), &Td::send_error, id, r_url.move_as_error()); + } + + send_closure(actor_id(this), &Td::send_result, id, td_api::make_object(r_url.ok())); +} + void Td::on_request(uint64 id, td_api::getRecentlyVisitedTMeUrls &request) { CHECK_IS_USER(); CLEAN_INPUT_STRING(request.referrer_); diff --git a/td/telegram/Td.h b/td/telegram/Td.h index e85d5289..643efd48 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -924,6 +924,8 @@ class Td final : public NetQueryCallback { void on_request(uint64 id, const td_api::getBackgrounds &request); + void on_request(uint64 id, td_api::getBackgroundUrl &request); + void on_request(uint64 id, td_api::getRecentlyVisitedTMeUrls &request); void on_request(uint64 id, td_api::setBotUpdatesStatus &request); diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 2f11ef64..f88e53b6 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -1220,7 +1220,7 @@ class CliClient final : public Actor { } } - void send_message(const string &chat_id, tl_object_ptr &&input_message_content, + void send_message(const string &chat_id, td_api::object_ptr &&input_message_content, bool disable_notification = false, bool from_background = false, int64 reply_to_message_id = 0) { auto chat = as_chat_id(chat_id); auto id = send_request(td_api::make_object( @@ -1228,6 +1228,10 @@ class CliClient final : public Actor { query_id_to_send_message_info_[id].start_time = Time::now(); } + void send_get_background_url(td_api::object_ptr &&background_type) { + send_request(td_api::make_object("asd", std::move(background_type))); + } + void on_cmd(string cmd) { // TODO: need to remove https://en.wikipedia.org/wiki/ANSI_escape_code from cmd cmd.erase(std::remove_if(cmd.begin(), cmd.end(), [](unsigned char c) { return c < 32; }), cmd.end()); @@ -1959,8 +1963,23 @@ class CliClient final : public Actor { send_request(td_api::make_object(to_integer(args))); } else if (op == "daw") { send_request(td_api::make_object()); - } else if (op == "gb") { + } else if (op == "gbgs") { send_request(td_api::make_object()); + } else if (op == "gbgu") { + send_get_background_url(td_api::make_object(false, false)); + send_get_background_url(td_api::make_object(false, true)); + send_get_background_url(td_api::make_object(true, false)); + send_get_background_url(td_api::make_object(true, true)); + send_get_background_url(td_api::make_object(false, -1, 0)); + send_get_background_url(td_api::make_object(true, 0x1000000, 0)); + send_get_background_url(td_api::make_object(false, 0, -1)); + send_get_background_url(td_api::make_object(false, 0, 101)); + send_get_background_url(td_api::make_object(false, 0, 0)); + send_get_background_url(td_api::make_object(true, 0xFFFFFF, 100)); + send_get_background_url(td_api::make_object(true, 0xABCDEF, 49)); + send_get_background_url(td_api::make_object(-1)); + send_get_background_url(td_api::make_object(0xABCDEF)); + send_get_background_url(td_api::make_object(0x1000000)); } else if (op == "gccode") { send_request(td_api::make_object()); } else if (op == "git") { diff --git a/tdutils/td/utils/misc.cpp b/tdutils/td/utils/misc.cpp index 23cbd8a5..7812eb6a 100644 --- a/tdutils/td/utils/misc.cpp +++ b/tdutils/td/utils/misc.cpp @@ -25,7 +25,7 @@ char *str_dup(Slice str) { return res; } -string implode(vector v, char delimiter) { +string implode(const vector &v, char delimiter) { string result; for (auto &str : v) { if (!result.empty()) { diff --git a/tdutils/td/utils/misc.h b/tdutils/td/utils/misc.h index 77b350e3..3a31f189 100644 --- a/tdutils/td/utils/misc.h +++ b/tdutils/td/utils/misc.h @@ -49,7 +49,7 @@ vector full_split(T s, char delimiter = ' ') { } } -string implode(vector v, char delimiter = ' '); +string implode(const vector &v, char delimiter = ' '); namespace detail {