Parse background parameters in searchBackground.
This commit is contained in:
parent
afb58801ec
commit
3e0e9f5291
@ -397,46 +397,55 @@ static bool is_background_name_local(Slice name) {
|
||||
return name.size() <= 13u || name.find('?') <= 13u || !is_base64url_characters(name.substr(0, name.find('?')));
|
||||
}
|
||||
|
||||
BackgroundId BackgroundManager::search_background(const string &name, Promise<Unit> &&promise) {
|
||||
auto it = name_to_background_id_.find(name);
|
||||
std::pair<BackgroundId, BackgroundType> BackgroundManager::search_background(const string &name,
|
||||
Promise<Unit> &&promise) {
|
||||
auto params_pos = name.find('?');
|
||||
string slug = params_pos >= name.size() ? name : name.substr(0, params_pos);
|
||||
auto it = name_to_background_id_.find(slug);
|
||||
if (it != name_to_background_id_.end()) {
|
||||
CHECK(!is_background_name_local(slug));
|
||||
|
||||
const auto *background = get_background(it->second);
|
||||
CHECK(background != nullptr);
|
||||
promise.set_value(Unit());
|
||||
return it->second;
|
||||
BackgroundType type = background->type;
|
||||
type.apply_parameters_from_link(name);
|
||||
return {it->second, std::move(type)};
|
||||
}
|
||||
|
||||
if (name.empty()) {
|
||||
if (slug.empty()) {
|
||||
promise.set_error(Status::Error(400, "Background name must be non-empty"));
|
||||
return BackgroundId();
|
||||
return {};
|
||||
}
|
||||
|
||||
if (is_background_name_local(name)) {
|
||||
if (is_background_name_local(slug)) {
|
||||
auto r_fill = BackgroundFill::get_background_fill(name);
|
||||
if (r_fill.is_error()) {
|
||||
promise.set_error(r_fill.move_as_error());
|
||||
return BackgroundId();
|
||||
return {};
|
||||
}
|
||||
auto background_id = add_fill_background(r_fill.ok());
|
||||
promise.set_value(Unit());
|
||||
return background_id;
|
||||
return {background_id, BackgroundType(r_fill.ok())};
|
||||
}
|
||||
|
||||
if (G()->parameters().use_file_db && loaded_from_database_backgrounds_.count(name) == 0) {
|
||||
auto &queries = being_loaded_from_database_backgrounds_[name];
|
||||
if (G()->parameters().use_file_db && loaded_from_database_backgrounds_.count(slug) == 0) {
|
||||
auto &queries = being_loaded_from_database_backgrounds_[slug];
|
||||
queries.push_back(std::move(promise));
|
||||
if (queries.size() == 1) {
|
||||
LOG(INFO) << "Trying to load background " << name << " from database";
|
||||
LOG(INFO) << "Trying to load background " << slug << " from database";
|
||||
G()->td_db()->get_sqlite_pmc()->get(
|
||||
get_background_name_database_key(name), PromiseCreator::lambda([name](string value) {
|
||||
get_background_name_database_key(slug), PromiseCreator::lambda([slug](string value) {
|
||||
send_closure(G()->background_manager(), &BackgroundManager::on_load_background_from_database,
|
||||
std::move(name), std::move(value));
|
||||
std::move(slug), std::move(value));
|
||||
}));
|
||||
}
|
||||
return BackgroundId();
|
||||
return {};
|
||||
}
|
||||
|
||||
reload_background_from_server(BackgroundId(), name, telegram_api::make_object<telegram_api::inputWallPaperSlug>(name),
|
||||
reload_background_from_server(BackgroundId(), slug, telegram_api::make_object<telegram_api::inputWallPaperSlug>(slug),
|
||||
std::move(promise));
|
||||
return BackgroundId();
|
||||
return {};
|
||||
}
|
||||
|
||||
void BackgroundManager::on_load_background_from_database(string name, string value) {
|
||||
@ -581,7 +590,7 @@ BackgroundId BackgroundManager::set_background(const td_api::InputBackground *in
|
||||
BackgroundId BackgroundManager::set_background(BackgroundId background_id, const BackgroundType &type,
|
||||
bool for_dark_theme, Promise<Unit> &&promise) {
|
||||
LOG(INFO) << "Set " << background_id << " with " << type;
|
||||
auto *background = get_background(background_id);
|
||||
const auto *background = get_background(background_id);
|
||||
if (background == nullptr) {
|
||||
promise.set_error(Status::Error(400, "Background to set not found"));
|
||||
return BackgroundId();
|
||||
@ -721,7 +730,7 @@ void BackgroundManager::on_uploaded_background_file(FileId file_id, const Backgr
|
||||
return promise.set_error(Status::Error(500, "Receive wrong uploaded background"));
|
||||
}
|
||||
|
||||
auto background = get_background(background_id);
|
||||
const auto *background = get_background(background_id);
|
||||
CHECK(background != nullptr);
|
||||
if (!background->file_id.is_valid()) {
|
||||
td_->file_manager_->cancel_upload(file_id);
|
||||
@ -733,7 +742,7 @@ void BackgroundManager::on_uploaded_background_file(FileId file_id, const Backgr
|
||||
}
|
||||
|
||||
void BackgroundManager::remove_background(BackgroundId background_id, Promise<Unit> &&promise) {
|
||||
auto background = get_background(background_id);
|
||||
const auto *background = get_background(background_id);
|
||||
if (background == nullptr) {
|
||||
return promise.set_error(Status::Error(400, "Background not found"));
|
||||
}
|
||||
@ -1001,18 +1010,21 @@ void BackgroundManager::on_get_backgrounds(Result<telegram_api::object_ptr<teleg
|
||||
}
|
||||
|
||||
td_api::object_ptr<td_api::background> BackgroundManager::get_background_object(BackgroundId background_id,
|
||||
bool for_dark_theme) const {
|
||||
auto background = get_background(background_id);
|
||||
bool for_dark_theme,
|
||||
const BackgroundType *type) const {
|
||||
const auto *background = get_background(background_id);
|
||||
if (background == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
auto type = &background->type;
|
||||
// first check another set_background_id to get correct type if both backgrounds are the same
|
||||
if (background_id == set_background_id_[1 - static_cast<int>(for_dark_theme)]) {
|
||||
type = &set_background_type_[1 - static_cast<int>(for_dark_theme)];
|
||||
}
|
||||
if (background_id == set_background_id_[for_dark_theme]) {
|
||||
type = &set_background_type_[for_dark_theme];
|
||||
if (type == nullptr) {
|
||||
type = &background->type;
|
||||
// first check another set_background_id to get correct type if both backgrounds are the same
|
||||
if (background_id == set_background_id_[1 - static_cast<int>(for_dark_theme)]) {
|
||||
type = &set_background_type_[1 - static_cast<int>(for_dark_theme)];
|
||||
}
|
||||
if (background_id == set_background_id_[for_dark_theme]) {
|
||||
type = &set_background_type_[for_dark_theme];
|
||||
}
|
||||
}
|
||||
return td_api::make_object<td_api::background>(
|
||||
background->id.get(), background->is_default, background->is_dark, background->name,
|
||||
|
@ -40,7 +40,7 @@ class BackgroundManager : public Actor {
|
||||
|
||||
void reload_background(BackgroundId background_id, int64 access_hash, Promise<Unit> &&promise);
|
||||
|
||||
BackgroundId search_background(const string &name, Promise<Unit> &&promise);
|
||||
std::pair<BackgroundId, BackgroundType> search_background(const string &name, Promise<Unit> &&promise);
|
||||
|
||||
BackgroundId set_background(const td_api::InputBackground *input_background,
|
||||
const td_api::BackgroundType *background_type, bool for_dark_theme,
|
||||
@ -50,7 +50,8 @@ class BackgroundManager : public Actor {
|
||||
|
||||
void reset_backgrounds(Promise<Unit> &&promise);
|
||||
|
||||
td_api::object_ptr<td_api::background> get_background_object(BackgroundId background_id, bool for_dark_theme) const;
|
||||
td_api::object_ptr<td_api::background> get_background_object(BackgroundId background_id, bool for_dark_theme,
|
||||
const BackgroundType *type = nullptr) const;
|
||||
|
||||
td_api::object_ptr<td_api::backgrounds> get_backgrounds_object(bool for_dark_theme) const;
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
//
|
||||
#include "td/telegram/BackgroundType.h"
|
||||
|
||||
#include "td/utils/HttpUrl.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/misc.h"
|
||||
#include "td/utils/Slice.h"
|
||||
@ -138,23 +139,28 @@ Result<BackgroundFill> BackgroundFill::get_background_fill(Slice name) {
|
||||
return static_cast<int32>(r_color.ok());
|
||||
};
|
||||
|
||||
size_t hyphen_pos = name.find('-');
|
||||
if (name.find('~') < name.size()) {
|
||||
vector<Slice> color_strings = full_split(name, '~');
|
||||
if (color_strings.size() != 4 && color_strings.size() != 3) {
|
||||
return Status::Error(400, "WALLPAPER_INVALID");
|
||||
}
|
||||
CHECK(color_strings.size() >= 2);
|
||||
if (color_strings.size() == 2) {
|
||||
hyphen_pos = color_strings[0].size();
|
||||
} else {
|
||||
if (color_strings.size() > 4) {
|
||||
return Status::Error(400, "WALLPAPER_INVALID");
|
||||
}
|
||||
|
||||
TRY_RESULT(first_color, get_color(color_strings[0]));
|
||||
TRY_RESULT(second_color, get_color(color_strings[1]));
|
||||
TRY_RESULT(third_color, get_color(color_strings[2]));
|
||||
int32 fourth_color = -1;
|
||||
if (color_strings.size() == 4) {
|
||||
TRY_RESULT_ASSIGN(fourth_color, get_color(color_strings[3]));
|
||||
TRY_RESULT(first_color, get_color(color_strings[0]));
|
||||
TRY_RESULT(second_color, get_color(color_strings[1]));
|
||||
TRY_RESULT(third_color, get_color(color_strings[2]));
|
||||
int32 fourth_color = -1;
|
||||
if (color_strings.size() == 4) {
|
||||
TRY_RESULT_ASSIGN(fourth_color, get_color(color_strings[3]));
|
||||
}
|
||||
return BackgroundFill(first_color, second_color, third_color, fourth_color);
|
||||
}
|
||||
return BackgroundFill(first_color, second_color, third_color, fourth_color);
|
||||
}
|
||||
|
||||
size_t hyphen_pos = name.find('-');
|
||||
if (hyphen_pos < name.size()) {
|
||||
TRY_RESULT(top_color, get_color(name.substr(0, hyphen_pos)));
|
||||
TRY_RESULT(bottom_color, get_color(name.substr(hyphen_pos + 1)));
|
||||
@ -179,14 +185,9 @@ static string get_background_fill_color_hex_string(const BackgroundFill &fill, b
|
||||
switch (fill.get_type()) {
|
||||
case BackgroundFill::Type::Solid:
|
||||
return get_color_hex_string(fill.top_color);
|
||||
case BackgroundFill::Type::Gradient: {
|
||||
string colors = PSTRING() << get_color_hex_string(fill.top_color) << '-'
|
||||
<< get_color_hex_string(fill.bottom_color);
|
||||
if (fill.rotation_angle != 0) {
|
||||
colors += (PSTRING() << (is_first ? '?' : '&') << "rotation=" << fill.rotation_angle);
|
||||
}
|
||||
return colors;
|
||||
}
|
||||
case BackgroundFill::Type::Gradient:
|
||||
return PSTRING() << get_color_hex_string(fill.top_color) << '-' << get_color_hex_string(fill.bottom_color)
|
||||
<< (is_first ? '?' : '&') << "rotation=" << fill.rotation_angle;
|
||||
case BackgroundFill::Type::FreeformGradient: {
|
||||
SliceBuilder sb;
|
||||
sb << get_color_hex_string(fill.top_color) << '~' << get_color_hex_string(fill.bottom_color) << '~'
|
||||
@ -257,6 +258,42 @@ bool operator==(const BackgroundFill &lhs, const BackgroundFill &rhs) {
|
||||
lhs.fourth_color == rhs.fourth_color;
|
||||
}
|
||||
|
||||
void BackgroundType::apply_parameters_from_link(Slice name) {
|
||||
const auto query = parse_url_query(name);
|
||||
|
||||
is_blurred = false;
|
||||
is_moving = false;
|
||||
auto modes = full_split(query.get_arg("mode"), ' ');
|
||||
for (auto &mode : modes) {
|
||||
if (type != Type::Pattern && to_lower(mode) == "blur") {
|
||||
is_blurred = true;
|
||||
}
|
||||
if (to_lower(mode) == "motion") {
|
||||
is_moving = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (type == Type::Pattern) {
|
||||
intensity = -1;
|
||||
auto intensity_arg = query.get_arg("intensity");
|
||||
if (!intensity_arg.empty()) {
|
||||
intensity = to_integer<int32>(intensity_arg);
|
||||
}
|
||||
if (!is_valid_intensity(intensity)) {
|
||||
intensity = 50;
|
||||
}
|
||||
|
||||
auto bg_color = query.get_arg("bg_color");
|
||||
if (!bg_color.empty()) {
|
||||
auto r_fill = BackgroundFill::get_background_fill(
|
||||
PSLICE() << url_encode(bg_color) << "?rotation=" << url_encode(query.get_arg("rotation")));
|
||||
if (r_fill.is_ok()) {
|
||||
fill = r_fill.move_as_ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string BackgroundType::get_link() const {
|
||||
string mode;
|
||||
if (is_blurred) {
|
||||
|
@ -78,6 +78,8 @@ struct BackgroundType {
|
||||
return type == Type::Wallpaper || type == Type::Pattern;
|
||||
}
|
||||
|
||||
void apply_parameters_from_link(Slice name);
|
||||
|
||||
string get_link() const;
|
||||
};
|
||||
|
||||
|
@ -2957,14 +2957,14 @@ class GetBackgroundsRequest : public RequestOnceActor {
|
||||
class SearchBackgroundRequest : public RequestActor<> {
|
||||
string name_;
|
||||
|
||||
BackgroundId background_id_;
|
||||
std::pair<BackgroundId, BackgroundType> background_;
|
||||
|
||||
void do_run(Promise<Unit> &&promise) override {
|
||||
background_id_ = td->background_manager_->search_background(name_, std::move(promise));
|
||||
background_ = td->background_manager_->search_background(name_, std::move(promise));
|
||||
}
|
||||
|
||||
void do_send_result() override {
|
||||
send_result(td->background_manager_->get_background_object(background_id_, false));
|
||||
send_result(td->background_manager_->get_background_object(background_.first, false, &background_.second));
|
||||
}
|
||||
|
||||
public:
|
||||
|
Loading…
x
Reference in New Issue
Block a user