Add td_api::setBackground.
GitOrigin-RevId: e0c38213b41942ed8a5163ca7eb4ea61caa71d7b
This commit is contained in:
parent
e39b4fae83
commit
652d2a9570
@ -1969,6 +1969,16 @@ background id:int64 is_default:Bool is_dark:Bool name:string document:document t
|
|||||||
backgrounds backgrounds:vector<background> = Backgrounds;
|
backgrounds backgrounds:vector<background> = Backgrounds;
|
||||||
|
|
||||||
|
|
||||||
|
//@class InputBackground @description Contains information about background to set
|
||||||
|
|
||||||
|
//@description A background from a local file
|
||||||
|
//@background Background file to use. Only inputFileLocal and inputFileGenerated are supported. The file nust be in JPEG format for wallpapers and in PNG format for patterns
|
||||||
|
inputBackgroundLocal background:InputFile = InputBackground;
|
||||||
|
|
||||||
|
//@description A background from the server @background_id The background identifier
|
||||||
|
inputBackgroundRemote background_id:int64 = InputBackground;
|
||||||
|
|
||||||
|
|
||||||
//@description Contains a list of hashtags @hashtags A list of hashtags
|
//@description Contains a list of hashtags @hashtags A list of hashtags
|
||||||
hashtags hashtags:vector<string> = Hashtags;
|
hashtags hashtags:vector<string> = Hashtags;
|
||||||
|
|
||||||
@ -3611,6 +3621,9 @@ getBackgroundUrl name:string type:BackgroundType = HttpUrl;
|
|||||||
//@description Searches for a background by its name @name The name of the background
|
//@description Searches for a background by its name @name The name of the background
|
||||||
searchBackground name:string = Background;
|
searchBackground name:string = Background;
|
||||||
|
|
||||||
|
//@description Sets background as a chosen by the user background @background The input background to use, null for solid backgrounds @type Background type
|
||||||
|
setBackground background:InputBackground type:BackgroundType = Background;
|
||||||
|
|
||||||
|
|
||||||
//@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
|
//@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;
|
getLocalizationTargetInfo only_local:Bool = LocalizationTargetInfo;
|
||||||
|
Binary file not shown.
@ -24,6 +24,8 @@
|
|||||||
#include "td/utils/common.h"
|
#include "td/utils/common.h"
|
||||||
#include "td/utils/misc.h"
|
#include "td/utils/misc.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
|
|
||||||
class GetBackgroundQuery : public Td::ResultHandler {
|
class GetBackgroundQuery : public Td::ResultHandler {
|
||||||
@ -84,7 +86,105 @@ class GetBackgroundsQuery : public Td::ResultHandler {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class InstallBackgroundQuery : public Td::ResultHandler {
|
||||||
|
Promise<Unit> promise_;
|
||||||
|
BackgroundId background_id_;
|
||||||
|
BackgroundType type_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit InstallBackgroundQuery(Promise<Unit> &&promise) : promise_(std::move(promise)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void send(BackgroundId background_id, int64 access_hash, const BackgroundType &type) {
|
||||||
|
background_id_ = background_id;
|
||||||
|
type_ = type;
|
||||||
|
send_query(G()->net_query_creator().create(create_storer(telegram_api::account_installWallPaper(
|
||||||
|
telegram_api::make_object<telegram_api::inputWallPaper>(background_id.get(), access_hash),
|
||||||
|
get_input_wallpaper_settings(type)))));
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_result(uint64 id, BufferSlice packet) override {
|
||||||
|
auto result_ptr = fetch_result<telegram_api::account_installWallPaper>(packet);
|
||||||
|
if (result_ptr.is_error()) {
|
||||||
|
return on_error(id, result_ptr.move_as_error());
|
||||||
|
}
|
||||||
|
|
||||||
|
td->background_manager_->set_background_id(background_id_, type_);
|
||||||
|
LOG_IF(INFO, !result_ptr.ok()) << "Receive false from account.installWallPaper";
|
||||||
|
promise_.set_value(Unit());
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_error(uint64 id, Status status) override {
|
||||||
|
promise_.set_error(std::move(status));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class UploadBackgroundQuery : public Td::ResultHandler {
|
||||||
|
Promise<Unit> promise_;
|
||||||
|
FileId file_id_;
|
||||||
|
BackgroundType type_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit UploadBackgroundQuery(Promise<Unit> &&promise) : promise_(std::move(promise)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void send(FileId file_id, tl_object_ptr<telegram_api::InputFile> &&input_file, const BackgroundType &type) {
|
||||||
|
CHECK(input_file != nullptr);
|
||||||
|
file_id_ = file_id;
|
||||||
|
type_ = type;
|
||||||
|
string mime_type = type.type == BackgroundType::Type::Pattern ? "image/png" : "image/jpeg";
|
||||||
|
send_query(G()->net_query_creator().create(create_storer(
|
||||||
|
telegram_api::account_uploadWallPaper(std::move(input_file), mime_type, get_input_wallpaper_settings(type)))));
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_result(uint64 id, BufferSlice packet) override {
|
||||||
|
auto result_ptr = fetch_result<telegram_api::account_uploadWallPaper>(packet);
|
||||||
|
if (result_ptr.is_error()) {
|
||||||
|
return on_error(id, result_ptr.move_as_error());
|
||||||
|
}
|
||||||
|
|
||||||
|
td->background_manager_->on_uploaded_background_file(file_id_, type_, result_ptr.move_as_ok(), std::move(promise_));
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_error(uint64 id, Status status) override {
|
||||||
|
CHECK(status.is_error());
|
||||||
|
CHECK(file_id_.is_valid());
|
||||||
|
if (begins_with(status.message(), "FILE_PART_") && ends_with(status.message(), "_MISSING")) {
|
||||||
|
// TODO td->background_manager_->on_upload_background_file_part_missing(file_id_, to_integer<int32>(status.message().substr(10)));
|
||||||
|
// return;
|
||||||
|
} else {
|
||||||
|
if (status.code() != 429 && status.code() < 500 && !G()->close_flag()) {
|
||||||
|
td->file_manager_->delete_partial_remote_location(file_id_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
td->file_manager_->cancel_upload(file_id_);
|
||||||
|
promise_.set_error(std::move(status));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class BackgroundManager::UploadBackgroundFileCallback : public FileManager::UploadCallback {
|
||||||
|
public:
|
||||||
|
void on_upload_ok(FileId file_id, tl_object_ptr<telegram_api::InputFile> input_file) override {
|
||||||
|
send_closure_later(G()->background_manager(), &BackgroundManager::on_upload_background_file, file_id,
|
||||||
|
std::move(input_file));
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_upload_encrypted_ok(FileId file_id, tl_object_ptr<telegram_api::InputEncryptedFile> input_file) override {
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_upload_secure_ok(FileId file_id, tl_object_ptr<telegram_api::InputSecureFile> input_file) override {
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_upload_error(FileId file_id, Status error) override {
|
||||||
|
send_closure_later(G()->background_manager(), &BackgroundManager::on_upload_background_file_error, file_id,
|
||||||
|
std::move(error));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
BackgroundManager::BackgroundManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::move(parent)) {
|
BackgroundManager::BackgroundManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::move(parent)) {
|
||||||
|
upload_background_file_callback_ = std::make_shared<UploadBackgroundFileCallback>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BackgroundManager::tear_down() {
|
void BackgroundManager::tear_down() {
|
||||||
@ -116,14 +216,6 @@ Result<string> BackgroundManager::get_background_url(const string &name,
|
|||||||
}
|
}
|
||||||
string mode = implode(modes, '+');
|
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/";
|
string url = PSTRING() << G()->shared_config().get_option_string("t_me_url", "https://t.me/") << "bg/";
|
||||||
switch (type.type) {
|
switch (type.type) {
|
||||||
case BackgroundType::Type::Wallpaper:
|
case BackgroundType::Type::Wallpaper:
|
||||||
@ -138,14 +230,14 @@ Result<string> BackgroundManager::get_background_url(const string &name,
|
|||||||
url += "?intensity=";
|
url += "?intensity=";
|
||||||
url += to_string(type.intensity);
|
url += to_string(type.intensity);
|
||||||
url += "&bg_color=";
|
url += "&bg_color=";
|
||||||
url += get_color_string(type.color);
|
url += type.get_color_hex_string();
|
||||||
if (!mode.empty()) {
|
if (!mode.empty()) {
|
||||||
url += "&mode=";
|
url += "&mode=";
|
||||||
url += mode;
|
url += mode;
|
||||||
}
|
}
|
||||||
return url;
|
return url;
|
||||||
case BackgroundType::Type::Solid:
|
case BackgroundType::Type::Solid:
|
||||||
url += get_color_string(type.color);
|
url += type.get_color_hex_string();
|
||||||
return url;
|
return url;
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
@ -180,6 +272,196 @@ BackgroundId BackgroundManager::search_background(const string &name, Promise<Un
|
|||||||
return BackgroundId();
|
return BackgroundId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result<FileId> BackgroundManager::prepare_input_file(const tl_object_ptr<td_api::InputFile> &input_file) {
|
||||||
|
auto r_file_id = td_->file_manager_->get_input_file_id(FileType::Background, input_file, {}, false, false);
|
||||||
|
if (r_file_id.is_error()) {
|
||||||
|
return Status::Error(400, r_file_id.error().message());
|
||||||
|
}
|
||||||
|
auto file_id = r_file_id.move_as_ok();
|
||||||
|
|
||||||
|
FileView file_view = td_->file_manager_->get_file_view(file_id);
|
||||||
|
if (file_view.is_encrypted()) {
|
||||||
|
return Status::Error(400, "Can't use encrypted file");
|
||||||
|
}
|
||||||
|
if (!file_view.has_local_location() && !file_view.has_generate_location()) {
|
||||||
|
return Status::Error(400, "Need local or generate location to upload background");
|
||||||
|
}
|
||||||
|
return std::move(file_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
BackgroundId BackgroundManager::set_background(const td_api::InputBackground *input_background,
|
||||||
|
const td_api::BackgroundType *background_type, Promise<Unit> &&promise) {
|
||||||
|
auto r_type = get_background_type(background_type);
|
||||||
|
if (r_type.is_error()) {
|
||||||
|
promise.set_error(r_type.move_as_error());
|
||||||
|
return BackgroundId();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto type = r_type.move_as_ok();
|
||||||
|
if (type.type == BackgroundType::Type::Solid) {
|
||||||
|
auto color = type.color;
|
||||||
|
CHECK(0 <= color && color < 0x1000000);
|
||||||
|
BackgroundId id(static_cast<int64>(color));
|
||||||
|
if (set_background_id_ != id) {
|
||||||
|
auto *background = add_background(id);
|
||||||
|
background->id = id;
|
||||||
|
background->access_hash = 0;
|
||||||
|
background->is_creator = true;
|
||||||
|
background->is_default = false;
|
||||||
|
background->is_dark = (color & 0x808080) == 0;
|
||||||
|
background->type = type;
|
||||||
|
background->name = type.get_color_hex_string();
|
||||||
|
background->file_id = FileId();
|
||||||
|
background->file_source_id = FileSourceId();
|
||||||
|
|
||||||
|
set_background_id(id, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
promise.set_value(Unit());
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input_background == nullptr) {
|
||||||
|
promise.set_error(Status::Error(400, "Input background must be non-empty"));
|
||||||
|
return BackgroundId();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (input_background->get_id()) {
|
||||||
|
case td_api::inputBackgroundLocal::ID: {
|
||||||
|
auto background_local = static_cast<const td_api::inputBackgroundLocal *>(input_background);
|
||||||
|
auto r_file_id = prepare_input_file(background_local->background_);
|
||||||
|
if (r_file_id.is_error()) {
|
||||||
|
promise.set_error(r_file_id.move_as_error());
|
||||||
|
return BackgroundId();
|
||||||
|
}
|
||||||
|
auto file_id = r_file_id.move_as_ok();
|
||||||
|
LOG(INFO) << "Receive file " << file_id << " for input background";
|
||||||
|
|
||||||
|
auto it = file_id_to_background_id_.find(file_id);
|
||||||
|
if (it != file_id_to_background_id_.end()) {
|
||||||
|
return set_background(it->second, type, std::move(promise));
|
||||||
|
}
|
||||||
|
|
||||||
|
upload_background_file(file_id, type, std::move(promise));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case td_api::inputBackgroundRemote::ID: {
|
||||||
|
auto background_remote = static_cast<const td_api::inputBackgroundRemote *>(input_background);
|
||||||
|
return set_background(BackgroundId(background_remote->background_id_), type, std::move(promise));
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
return BackgroundId();
|
||||||
|
}
|
||||||
|
|
||||||
|
BackgroundId BackgroundManager::set_background(BackgroundId background_id, const BackgroundType &type,
|
||||||
|
Promise<Unit> &&promise) {
|
||||||
|
auto *background = get_background(background_id);
|
||||||
|
if (background == nullptr) {
|
||||||
|
promise.set_error(Status::Error(400, "Background to set not found"));
|
||||||
|
return BackgroundId();
|
||||||
|
}
|
||||||
|
if (background->type.type != type.type) {
|
||||||
|
promise.set_error(Status::Error(400, "Background type mismatch"));
|
||||||
|
return BackgroundId();
|
||||||
|
}
|
||||||
|
if (set_background_id_ == background_id) {
|
||||||
|
promise.set_value(Unit());
|
||||||
|
return background_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG(INFO) << "Install " << background_id << " with " << type;
|
||||||
|
td_->create_handler<InstallBackgroundQuery>(std::move(promise))->send(background_id, background->access_hash, type);
|
||||||
|
return BackgroundId();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BackgroundManager::set_background_id(BackgroundId background_id, const BackgroundType &type) {
|
||||||
|
if (background_id == set_background_id_ && set_background_type_ == type) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
set_background_id_ = background_id;
|
||||||
|
set_background_type_ = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BackgroundManager::upload_background_file(FileId file_id, const BackgroundType &type, Promise<Unit> &&promise) {
|
||||||
|
auto upload_file_id = td_->file_manager_->dup_file_id(file_id);
|
||||||
|
|
||||||
|
being_uploaded_files_[upload_file_id] = {type, std::move(promise)};
|
||||||
|
LOG(INFO) << "Ask to upload background file " << upload_file_id;
|
||||||
|
td_->file_manager_->upload(upload_file_id, upload_background_file_callback_, 1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BackgroundManager::on_upload_background_file(FileId file_id, tl_object_ptr<telegram_api::InputFile> input_file) {
|
||||||
|
LOG(INFO) << "Background file " << file_id << " has been uploaded";
|
||||||
|
|
||||||
|
auto it = being_uploaded_files_.find(file_id);
|
||||||
|
CHECK(it != being_uploaded_files_.end());
|
||||||
|
|
||||||
|
auto type = it->second.type;
|
||||||
|
auto promise = std::move(it->second.promise);
|
||||||
|
|
||||||
|
being_uploaded_files_.erase(it);
|
||||||
|
|
||||||
|
do_upload_background_file(file_id, type, std::move(input_file), std::move(promise));
|
||||||
|
}
|
||||||
|
|
||||||
|
void BackgroundManager::on_upload_background_file_error(FileId file_id, Status status) {
|
||||||
|
if (G()->close_flag()) {
|
||||||
|
// do not fail upload if closing
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG(WARNING) << "Background file " << file_id << " has upload error " << status;
|
||||||
|
CHECK(status.is_error());
|
||||||
|
|
||||||
|
auto it = being_uploaded_files_.find(file_id);
|
||||||
|
CHECK(it != being_uploaded_files_.end());
|
||||||
|
|
||||||
|
auto promise = std::move(it->second.promise);
|
||||||
|
|
||||||
|
being_uploaded_files_.erase(it);
|
||||||
|
|
||||||
|
promise.set_error(Status::Error(status.code() > 0 ? status.code() : 500,
|
||||||
|
status.message())); // TODO CHECK that status has always a code
|
||||||
|
}
|
||||||
|
|
||||||
|
void BackgroundManager::do_upload_background_file(FileId file_id, const BackgroundType &type,
|
||||||
|
tl_object_ptr<telegram_api::InputFile> &&input_file,
|
||||||
|
Promise<Unit> &&promise) {
|
||||||
|
if (input_file == nullptr) {
|
||||||
|
FileView file_view = td_->file_manager_->get_file_view(file_id);
|
||||||
|
file_id = file_view.file_id();
|
||||||
|
auto it = file_id_to_background_id_.find(file_id);
|
||||||
|
if (it != file_id_to_background_id_.end()) {
|
||||||
|
set_background(it->second, type, std::move(promise));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return promise.set_error(Status::Error(500, "Failed to reupload background"));
|
||||||
|
}
|
||||||
|
|
||||||
|
td_->create_handler<UploadBackgroundQuery>(std::move(promise))->send(file_id, std::move(input_file), type);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BackgroundManager::on_uploaded_background_file(FileId file_id, const BackgroundType &type,
|
||||||
|
telegram_api::object_ptr<telegram_api::wallPaper> wallpaper,
|
||||||
|
Promise<Unit> &&promise) {
|
||||||
|
CHECK(wallpaper != nullptr);
|
||||||
|
|
||||||
|
BackgroundId background_id = on_get_background(BackgroundId(), std::move(wallpaper));
|
||||||
|
if (!background_id.is_valid()) {
|
||||||
|
td_->file_manager_->cancel_upload(file_id);
|
||||||
|
return promise.set_error(Status::Error(500, "Receive wrong uploaded background"));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto background = get_background(background_id);
|
||||||
|
CHECK(background != nullptr);
|
||||||
|
LOG_STATUS(td_->file_manager_->merge(background->file_id, file_id));
|
||||||
|
set_background_id(background_id, type);
|
||||||
|
promise.set_value(Unit());
|
||||||
|
}
|
||||||
|
|
||||||
BackgroundManager::Background *BackgroundManager::add_background(BackgroundId background_id) {
|
BackgroundManager::Background *BackgroundManager::add_background(BackgroundId background_id) {
|
||||||
CHECK(background_id.is_valid());
|
CHECK(background_id.is_valid());
|
||||||
auto *result = &backgrounds_[background_id];
|
auto *result = &backgrounds_[background_id];
|
||||||
@ -223,6 +505,10 @@ BackgroundId BackgroundManager::on_get_background(BackgroundId expected_backgrou
|
|||||||
if (expected_background_id.is_valid() && id != expected_background_id) {
|
if (expected_background_id.is_valid() && id != expected_background_id) {
|
||||||
LOG(ERROR) << "Expected " << expected_background_id << ", but receive " << to_string(wallpaper);
|
LOG(ERROR) << "Expected " << expected_background_id << ", but receive " << to_string(wallpaper);
|
||||||
}
|
}
|
||||||
|
if (wallpaper->slug_.size() <= 6) {
|
||||||
|
LOG(ERROR) << "Receive " << to_string(wallpaper);
|
||||||
|
return BackgroundId();
|
||||||
|
}
|
||||||
|
|
||||||
int32 document_id = wallpaper->document_->get_id();
|
int32 document_id = wallpaper->document_->get_id();
|
||||||
if (document_id == telegram_api::documentEmpty::ID) {
|
if (document_id == telegram_api::documentEmpty::ID) {
|
||||||
@ -260,8 +546,10 @@ BackgroundId BackgroundManager::on_get_background(BackgroundId expected_backgrou
|
|||||||
name_to_background_id_.emplace(background->name, id);
|
name_to_background_id_.emplace(background->name, id);
|
||||||
}
|
}
|
||||||
if (background->file_id != document.file_id) {
|
if (background->file_id != document.file_id) {
|
||||||
LOG_IF(ERROR, background->file_id.is_valid())
|
if (background->file_id.is_valid()) {
|
||||||
<< "Background file has changed from " << background->file_id << " to " << document.file_id;
|
LOG(ERROR) << "Background file has changed from " << background->file_id << " to " << document.file_id;
|
||||||
|
file_id_to_background_id_.erase(background->file_id);
|
||||||
|
}
|
||||||
if (!background->file_source_id.is_valid()) {
|
if (!background->file_source_id.is_valid()) {
|
||||||
background->file_source_id =
|
background->file_source_id =
|
||||||
td_->file_reference_manager_->create_background_file_source(id, background->access_hash);
|
td_->file_reference_manager_->create_background_file_source(id, background->access_hash);
|
||||||
@ -270,6 +558,7 @@ BackgroundId BackgroundManager::on_get_background(BackgroundId expected_backgrou
|
|||||||
td_->file_manager_->add_file_source(file_id, background->file_source_id);
|
td_->file_manager_->add_file_source(file_id, background->file_source_id);
|
||||||
}
|
}
|
||||||
background->file_id = document.file_id;
|
background->file_id = document.file_id;
|
||||||
|
file_id_to_background_id_.emplace(background->file_id, id);
|
||||||
}
|
}
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
@ -280,7 +569,7 @@ void BackgroundManager::on_get_backgrounds(Result<telegram_api::object_ptr<teleg
|
|||||||
reset_to_empty(pending_get_backgrounds_queries_);
|
reset_to_empty(pending_get_backgrounds_queries_);
|
||||||
|
|
||||||
if (result.is_error()) {
|
if (result.is_error()) {
|
||||||
// do not clear installed_backgrounds_
|
// do not clear installed_background_ids_
|
||||||
|
|
||||||
auto error = result.move_as_error();
|
auto error = result.move_as_error();
|
||||||
for (auto &promise : promises) {
|
for (auto &promise : promises) {
|
||||||
@ -298,12 +587,12 @@ void BackgroundManager::on_get_backgrounds(Result<telegram_api::object_ptr<teleg
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
installed_backgrounds_.clear();
|
installed_background_ids_.clear();
|
||||||
auto wallpapers = telegram_api::move_object_as<telegram_api::account_wallPapers>(wallpapers_ptr);
|
auto wallpapers = telegram_api::move_object_as<telegram_api::account_wallPapers>(wallpapers_ptr);
|
||||||
for (auto &wallpaper : wallpapers->wallpapers_) {
|
for (auto &wallpaper : wallpapers->wallpapers_) {
|
||||||
auto background_id = on_get_background(BackgroundId(), std::move(wallpaper));
|
auto background_id = on_get_background(BackgroundId(), std::move(wallpaper));
|
||||||
if (background_id.is_valid()) {
|
if (background_id.is_valid()) {
|
||||||
installed_backgrounds_.push_back(background_id);
|
installed_background_ids_.push_back(background_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -317,14 +606,28 @@ td_api::object_ptr<td_api::background> BackgroundManager::get_background_object(
|
|||||||
if (background == nullptr) {
|
if (background == nullptr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
auto type = &background->type;
|
||||||
|
if (background_id == set_background_id_) {
|
||||||
|
type = &set_background_type_;
|
||||||
|
}
|
||||||
return td_api::make_object<td_api::background>(
|
return td_api::make_object<td_api::background>(
|
||||||
background->id.get(), background->is_default, background->is_dark, background->name,
|
background->id.get(), background->is_default, background->is_dark, background->name,
|
||||||
td_->documents_manager_->get_document_object(background->file_id), get_background_type_object(background->type));
|
td_->documents_manager_->get_document_object(background->file_id), get_background_type_object(*type));
|
||||||
}
|
}
|
||||||
|
|
||||||
td_api::object_ptr<td_api::backgrounds> BackgroundManager::get_backgrounds_object() const {
|
td_api::object_ptr<td_api::backgrounds> BackgroundManager::get_backgrounds_object() const {
|
||||||
return td_api::make_object<td_api::backgrounds>(transform(
|
auto background_ids = installed_background_ids_;
|
||||||
installed_backgrounds_, [this](BackgroundId background_id) { return get_background_object(background_id); }));
|
if (set_background_id_.is_valid()) {
|
||||||
|
auto it = std::find(background_ids.begin(), background_ids.end(), set_background_id_);
|
||||||
|
if (it != background_ids.end()) {
|
||||||
|
// move set background to the first place
|
||||||
|
std::rotate(background_ids.begin(), it, it + 1);
|
||||||
|
} else {
|
||||||
|
background_ids.insert(background_ids.begin(), set_background_id_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return td_api::make_object<td_api::backgrounds>(
|
||||||
|
transform(background_ids, [this](BackgroundId background_id) { return get_background_object(background_id); }));
|
||||||
}
|
}
|
||||||
|
|
||||||
FileSourceId BackgroundManager::get_background_file_source_id(BackgroundId background_id, int64 access_hash) {
|
FileSourceId BackgroundManager::get_background_file_source_id(BackgroundId background_id, int64 access_hash) {
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "td/utils/common.h"
|
#include "td/utils/common.h"
|
||||||
#include "td/utils/Status.h"
|
#include "td/utils/Status.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
@ -39,6 +40,11 @@ class BackgroundManager : public Actor {
|
|||||||
|
|
||||||
BackgroundId search_background(const string &name, Promise<Unit> &&promise);
|
BackgroundId search_background(const string &name, Promise<Unit> &&promise);
|
||||||
|
|
||||||
|
BackgroundId set_background(const td_api::InputBackground *input_background,
|
||||||
|
const td_api::BackgroundType *background_type, Promise<Unit> &&promise);
|
||||||
|
|
||||||
|
void set_background_id(BackgroundId background_id, const BackgroundType &type);
|
||||||
|
|
||||||
td_api::object_ptr<td_api::background> get_background_object(BackgroundId background_id) const;
|
td_api::object_ptr<td_api::background> get_background_object(BackgroundId background_id) const;
|
||||||
|
|
||||||
td_api::object_ptr<td_api::backgrounds> get_backgrounds_object() const;
|
td_api::object_ptr<td_api::backgrounds> get_backgrounds_object() const;
|
||||||
@ -48,6 +54,10 @@ class BackgroundManager : public Actor {
|
|||||||
|
|
||||||
FileSourceId get_background_file_source_id(BackgroundId background_id, int64 access_hash);
|
FileSourceId get_background_file_source_id(BackgroundId background_id, int64 access_hash);
|
||||||
|
|
||||||
|
void on_uploaded_background_file(FileId file_id, const BackgroundType &type,
|
||||||
|
telegram_api::object_ptr<telegram_api::wallPaper> wallpaper,
|
||||||
|
Promise<Unit> &&promise);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Background {
|
struct Background {
|
||||||
BackgroundId id;
|
BackgroundId id;
|
||||||
@ -61,6 +71,8 @@ class BackgroundManager : public Actor {
|
|||||||
FileSourceId file_source_id;
|
FileSourceId file_source_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class UploadBackgroundFileCallback;
|
||||||
|
|
||||||
void tear_down() override;
|
void tear_down() override;
|
||||||
|
|
||||||
void reload_background_from_server(BackgroundId background_id,
|
void reload_background_from_server(BackgroundId background_id,
|
||||||
@ -75,6 +87,19 @@ class BackgroundManager : public Actor {
|
|||||||
|
|
||||||
void on_get_backgrounds(Result<telegram_api::object_ptr<telegram_api::account_WallPapers>> result);
|
void on_get_backgrounds(Result<telegram_api::object_ptr<telegram_api::account_WallPapers>> result);
|
||||||
|
|
||||||
|
Result<FileId> prepare_input_file(const tl_object_ptr<td_api::InputFile> &input_file);
|
||||||
|
|
||||||
|
BackgroundId set_background(BackgroundId background_id, const BackgroundType &type, Promise<Unit> &&promise);
|
||||||
|
|
||||||
|
void upload_background_file(FileId file_id, const BackgroundType &type, Promise<Unit> &&promise);
|
||||||
|
|
||||||
|
void on_upload_background_file(FileId file_id, tl_object_ptr<telegram_api::InputFile> input_file);
|
||||||
|
|
||||||
|
void on_upload_background_file_error(FileId file_id, Status status);
|
||||||
|
|
||||||
|
void do_upload_background_file(FileId file_id, const BackgroundType &type,
|
||||||
|
tl_object_ptr<telegram_api::InputFile> &&input_file, Promise<Unit> &&promise);
|
||||||
|
|
||||||
std::unordered_map<BackgroundId, Background, BackgroundIdHash> backgrounds_;
|
std::unordered_map<BackgroundId, Background, BackgroundIdHash> backgrounds_;
|
||||||
|
|
||||||
std::unordered_map<BackgroundId, std::pair<int64, FileSourceId>, BackgroundIdHash>
|
std::unordered_map<BackgroundId, std::pair<int64, FileSourceId>, BackgroundIdHash>
|
||||||
@ -82,10 +107,23 @@ class BackgroundManager : public Actor {
|
|||||||
|
|
||||||
std::unordered_map<string, BackgroundId> name_to_background_id_;
|
std::unordered_map<string, BackgroundId> name_to_background_id_;
|
||||||
|
|
||||||
vector<BackgroundId> installed_backgrounds_;
|
std::unordered_map<FileId, BackgroundId, FileIdHash> file_id_to_background_id_;
|
||||||
|
|
||||||
|
BackgroundId set_background_id_;
|
||||||
|
BackgroundType set_background_type_;
|
||||||
|
|
||||||
|
vector<BackgroundId> installed_background_ids_;
|
||||||
|
|
||||||
vector<Promise<Unit>> pending_get_backgrounds_queries_;
|
vector<Promise<Unit>> pending_get_backgrounds_queries_;
|
||||||
|
|
||||||
|
std::shared_ptr<UploadBackgroundFileCallback> upload_background_file_callback_;
|
||||||
|
|
||||||
|
struct UploadedFileInfo {
|
||||||
|
BackgroundType type;
|
||||||
|
Promise<Unit> promise;
|
||||||
|
};
|
||||||
|
std::unordered_map<FileId, UploadedFileInfo, FileIdHash> being_uploaded_files_;
|
||||||
|
|
||||||
Td *td_;
|
Td *td_;
|
||||||
ActorShared<> parent_;
|
ActorShared<> parent_;
|
||||||
};
|
};
|
||||||
|
@ -8,6 +8,35 @@
|
|||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
|
|
||||||
|
string BackgroundType::get_color_hex_string() const {
|
||||||
|
string result;
|
||||||
|
for (int i = 20; i >= 0; i -= 4) {
|
||||||
|
result += "0123456789abcdef"[(color >> i) & 0xf];
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const BackgroundType &lhs, const BackgroundType &rhs) {
|
||||||
|
return lhs.type == rhs.type && lhs.is_blurred == rhs.is_blurred && lhs.is_moving == rhs.is_moving &&
|
||||||
|
lhs.color == rhs.color && lhs.intensity == rhs.intensity;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder &operator<<(StringBuilder &string_builder, const BackgroundType &type) {
|
||||||
|
switch (type.type) {
|
||||||
|
case BackgroundType::Type::Wallpaper:
|
||||||
|
return string_builder << "type Wallpaper[" << (type.is_blurred ? "blurred" : "") << ' '
|
||||||
|
<< (type.is_moving ? "moving" : "") << ']';
|
||||||
|
case BackgroundType::Type::Pattern:
|
||||||
|
return string_builder << "type Pattern[" << (type.is_moving ? "moving" : "") << ' ' << type.get_color_hex_string()
|
||||||
|
<< ' ' << type.intensity << ']';
|
||||||
|
case BackgroundType::Type::Solid:
|
||||||
|
return string_builder << "type Solid[" << type.get_color_hex_string() << ']';
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
return string_builder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Result<BackgroundType> get_background_type(const td_api::BackgroundType *type) {
|
Result<BackgroundType> get_background_type(const td_api::BackgroundType *type) {
|
||||||
if (type == nullptr) {
|
if (type == nullptr) {
|
||||||
return Status::Error(400, "Type must not be empty");
|
return Status::Error(400, "Type must not be empty");
|
||||||
@ -88,4 +117,30 @@ td_api::object_ptr<td_api::BackgroundType> get_background_type_object(const Back
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
telegram_api::object_ptr<telegram_api::wallPaperSettings> get_input_wallpaper_settings(const BackgroundType &type) {
|
||||||
|
int32 flags = 0;
|
||||||
|
if (type.is_blurred) {
|
||||||
|
flags |= telegram_api::wallPaperSettings::BLUR_MASK;
|
||||||
|
}
|
||||||
|
if (type.is_moving) {
|
||||||
|
flags |= telegram_api::wallPaperSettings::MOTION_MASK;
|
||||||
|
}
|
||||||
|
if (type.color != 0) {
|
||||||
|
flags |= telegram_api::wallPaperSettings::BACKGROUND_COLOR_MASK;
|
||||||
|
}
|
||||||
|
if (type.intensity) {
|
||||||
|
flags |= telegram_api::wallPaperSettings::INTENSITY_MASK;
|
||||||
|
}
|
||||||
|
switch (type.type) {
|
||||||
|
case BackgroundType::Type::Wallpaper:
|
||||||
|
case BackgroundType::Type::Pattern:
|
||||||
|
return telegram_api::make_object<telegram_api::wallPaperSettings>(flags, false /*ignored*/, false /*ignored*/,
|
||||||
|
type.color, type.intensity);
|
||||||
|
case BackgroundType::Type::Solid:
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include "td/utils/common.h"
|
#include "td/utils/common.h"
|
||||||
#include "td/utils/Status.h"
|
#include "td/utils/Status.h"
|
||||||
|
#include "td/utils/StringBuilder.h"
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
|
|
||||||
@ -31,12 +32,20 @@ struct BackgroundType {
|
|||||||
}
|
}
|
||||||
explicit BackgroundType(int32 color) : type(Type::Solid), color(color) {
|
explicit BackgroundType(int32 color) : type(Type::Solid), color(color) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string get_color_hex_string() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool operator==(const BackgroundType &lhs, const BackgroundType &rhs);
|
||||||
|
|
||||||
|
StringBuilder &operator<<(StringBuilder &string_builder, const BackgroundType &type);
|
||||||
|
|
||||||
Result<BackgroundType> get_background_type(const td_api::BackgroundType *type);
|
Result<BackgroundType> get_background_type(const td_api::BackgroundType *type);
|
||||||
|
|
||||||
BackgroundType get_background_type(bool is_pattern, telegram_api::object_ptr<telegram_api::wallPaperSettings> settings);
|
BackgroundType get_background_type(bool is_pattern, telegram_api::object_ptr<telegram_api::wallPaperSettings> settings);
|
||||||
|
|
||||||
td_api::object_ptr<td_api::BackgroundType> get_background_type_object(const BackgroundType &type);
|
td_api::object_ptr<td_api::BackgroundType> get_background_type_object(const BackgroundType &type);
|
||||||
|
|
||||||
|
telegram_api::object_ptr<telegram_api::wallPaperSettings> get_input_wallpaper_settings(const BackgroundType &type);
|
||||||
|
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
@ -719,6 +719,7 @@ class UploadStickerFileQuery : public Td::ResultHandler {
|
|||||||
} else if (FileReferenceManager::is_file_reference_error(status)) {
|
} else if (FileReferenceManager::is_file_reference_error(status)) {
|
||||||
LOG(ERROR) << "Receive file reference error for UploadStickerFileQuery";
|
LOG(ERROR) << "Receive file reference error for UploadStickerFileQuery";
|
||||||
}
|
}
|
||||||
|
td->file_manager_->cancel_upload(file_id_);
|
||||||
promise_.set_error(std::move(status));
|
promise_.set_error(std::move(status));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -2918,6 +2918,31 @@ class SearchBackgroundRequest : public RequestActor<> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SetBackgroundRequest : public RequestActor<> {
|
||||||
|
td_api::object_ptr<td_api::InputBackground> input_background_;
|
||||||
|
td_api::object_ptr<td_api::BackgroundType> background_type_;
|
||||||
|
|
||||||
|
BackgroundId background_id_;
|
||||||
|
|
||||||
|
void do_run(Promise<Unit> &&promise) override {
|
||||||
|
background_id_ =
|
||||||
|
td->background_manager_->set_background(input_background_.get(), background_type_.get(), std::move(promise));
|
||||||
|
}
|
||||||
|
|
||||||
|
void do_send_result() override {
|
||||||
|
send_result(td->background_manager_->get_background_object(background_id_));
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
SetBackgroundRequest(ActorShared<Td> td, uint64 request_id,
|
||||||
|
td_api::object_ptr<td_api::InputBackground> &&input_background,
|
||||||
|
td_api::object_ptr<td_api::BackgroundType> background_type)
|
||||||
|
: RequestActor(std::move(td), request_id)
|
||||||
|
, input_background_(std::move(input_background))
|
||||||
|
, background_type_(std::move(background_type)) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class GetRecentlyVisitedTMeUrlsRequest : public RequestActor<tl_object_ptr<td_api::tMeUrls>> {
|
class GetRecentlyVisitedTMeUrlsRequest : public RequestActor<tl_object_ptr<td_api::tMeUrls>> {
|
||||||
string referrer_;
|
string referrer_;
|
||||||
|
|
||||||
@ -6980,6 +7005,11 @@ void Td::on_request(uint64 id, td_api::searchBackground &request) {
|
|||||||
CREATE_REQUEST(SearchBackgroundRequest, std::move(request.name_));
|
CREATE_REQUEST(SearchBackgroundRequest, std::move(request.name_));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Td::on_request(uint64 id, td_api::setBackground &request) {
|
||||||
|
CHECK_IS_USER();
|
||||||
|
CREATE_REQUEST(SetBackgroundRequest, std::move(request.background_), std::move(request.type_));
|
||||||
|
}
|
||||||
|
|
||||||
void Td::on_request(uint64 id, td_api::getRecentlyVisitedTMeUrls &request) {
|
void Td::on_request(uint64 id, td_api::getRecentlyVisitedTMeUrls &request) {
|
||||||
CHECK_IS_USER();
|
CHECK_IS_USER();
|
||||||
CLEAN_INPUT_STRING(request.referrer_);
|
CLEAN_INPUT_STRING(request.referrer_);
|
||||||
|
@ -928,6 +928,8 @@ class Td final : public NetQueryCallback {
|
|||||||
|
|
||||||
void on_request(uint64 id, td_api::searchBackground &request);
|
void on_request(uint64 id, td_api::searchBackground &request);
|
||||||
|
|
||||||
|
void on_request(uint64 id, td_api::setBackground &request);
|
||||||
|
|
||||||
void on_request(uint64 id, td_api::getRecentlyVisitedTMeUrls &request);
|
void on_request(uint64 id, td_api::getRecentlyVisitedTMeUrls &request);
|
||||||
|
|
||||||
void on_request(uint64 id, td_api::setBotUpdatesStatus &request);
|
void on_request(uint64 id, td_api::setBotUpdatesStatus &request);
|
||||||
|
@ -1982,6 +1982,25 @@ class CliClient final : public Actor {
|
|||||||
send_get_background_url(td_api::make_object<td_api::backgroundTypeSolid>(0x1000000));
|
send_get_background_url(td_api::make_object<td_api::backgroundTypeSolid>(0x1000000));
|
||||||
} else if (op == "sbg") {
|
} else if (op == "sbg") {
|
||||||
send_request(td_api::make_object<td_api::searchBackground>(args));
|
send_request(td_api::make_object<td_api::searchBackground>(args));
|
||||||
|
} else if (op == "sbgw") {
|
||||||
|
send_request(td_api::make_object<td_api::setBackground>(
|
||||||
|
td_api::make_object<td_api::inputBackgroundLocal>(as_input_file(args)),
|
||||||
|
td_api::make_object<td_api::backgroundTypeWallpaper>(true, true)));
|
||||||
|
} else if (op == "sbgp") {
|
||||||
|
send_request(td_api::make_object<td_api::setBackground>(
|
||||||
|
td_api::make_object<td_api::inputBackgroundLocal>(as_input_file(args)),
|
||||||
|
td_api::make_object<td_api::backgroundTypePattern>(true, 0xabcdef, 49)));
|
||||||
|
} else if (op == "sbgs") {
|
||||||
|
send_request(td_api::make_object<td_api::setBackground>(
|
||||||
|
nullptr, td_api::make_object<td_api::backgroundTypeSolid>(to_integer<int32>(args))));
|
||||||
|
} else if (op == "sbgwid") {
|
||||||
|
send_request(td_api::make_object<td_api::setBackground>(
|
||||||
|
td_api::make_object<td_api::inputBackgroundRemote>(to_integer<int64>(args)),
|
||||||
|
td_api::make_object<td_api::backgroundTypeWallpaper>(true, true)));
|
||||||
|
} else if (op == "sbgpid") {
|
||||||
|
send_request(td_api::make_object<td_api::setBackground>(
|
||||||
|
td_api::make_object<td_api::inputBackgroundRemote>(to_integer<int64>(args)),
|
||||||
|
td_api::make_object<td_api::backgroundTypePattern>(true, 0xabcdef, 49)));
|
||||||
} else if (op == "gccode") {
|
} else if (op == "gccode") {
|
||||||
send_request(td_api::make_object<td_api::getCountryCode>());
|
send_request(td_api::make_object<td_api::getCountryCode>());
|
||||||
} else if (op == "git") {
|
} else if (op == "git") {
|
||||||
|
@ -2240,7 +2240,7 @@ void FileManager::resume_upload(FileId file_id, std::vector<int> bad_parts, std:
|
|||||||
}
|
}
|
||||||
FileView file_view(node);
|
FileView file_view(node);
|
||||||
if (file_view.has_active_upload_remote_location() && file_view.get_type() != FileType::Thumbnail &&
|
if (file_view.has_active_upload_remote_location() && file_view.get_type() != FileType::Thumbnail &&
|
||||||
file_view.get_type() != FileType::EncryptedThumbnail) {
|
file_view.get_type() != FileType::EncryptedThumbnail && file_view.get_type() != FileType::Background) {
|
||||||
LOG(INFO) << "File " << file_id << " is already uploaded";
|
LOG(INFO) << "File " << file_id << " is already uploaded";
|
||||||
if (callback) {
|
if (callback) {
|
||||||
callback->on_upload_ok(file_id, nullptr);
|
callback->on_upload_ok(file_id, nullptr);
|
||||||
@ -2491,7 +2491,8 @@ void FileManager::run_upload(FileNodePtr node, std::vector<int> bad_parts) {
|
|||||||
|
|
||||||
CHECK(node->upload_id_ == 0);
|
CHECK(node->upload_id_ == 0);
|
||||||
if (file_view.has_alive_remote_location() && !file_view.has_active_upload_remote_location() &&
|
if (file_view.has_alive_remote_location() && !file_view.has_active_upload_remote_location() &&
|
||||||
file_view.get_type() != FileType::Thumbnail && file_view.get_type() != FileType::EncryptedThumbnail) {
|
file_view.get_type() != FileType::Thumbnail && file_view.get_type() != FileType::EncryptedThumbnail &&
|
||||||
|
file_view.get_type() != FileType::Background) {
|
||||||
QueryId id = queries_container_.create(Query{file_id, Query::UploadWaitFileReference});
|
QueryId id = queries_container_.create(Query{file_id, Query::UploadWaitFileReference});
|
||||||
node->upload_id_ = id;
|
node->upload_id_ = id;
|
||||||
if (node->upload_was_update_file_reference_) {
|
if (node->upload_was_update_file_reference_) {
|
||||||
|
Loading…
Reference in New Issue
Block a user