Add backgroundTypeGradient.

GitOrigin-RevId: db09e39cb4384cd85f53cbc8719b2b2b75206406
This commit is contained in:
levlam 2019-12-21 05:28:07 +03:00
parent a91d296f87
commit 88c5679b13
7 changed files with 107 additions and 21 deletions

View File

@ -2112,13 +2112,16 @@ backgroundTypePattern is_moving:Bool color:int32 intensity:int32 = BackgroundTyp
//@description A solid background @color A color of the background in RGB24 format
backgroundTypeSolid color:int32 = BackgroundType;
//@description A gradient background @top_color A top color of the background in RGB24 format @bottom_color A bottom color of the background in RGB24 format
backgroundTypeGradient top_color:int32 bottom_color:int32 = BackgroundType;
//@description Describes a chat background
//@id Unique background identifier
//@is_default True, if this is one of default backgrounds
//@is_dark True, if the background is dark and is recommended to be used with dark theme
//@name Unique background name
//@document Document with the background; may be null. Null only for solid backgrounds
//@document Document with the background; may be null. Null only for solid and gradient backgrounds
//@type Type of the background
background id:int64 is_default:Bool is_dark:Bool name:string document:document type:BackgroundType = Background;
@ -3956,7 +3959,7 @@ getBackgroundUrl name:string type:BackgroundType = HttpUrl;
searchBackground name:string = Background;
//@description Changes the background selected by the user; adds background to the list of installed backgrounds
//@background The input background to use, null for solid backgrounds
//@background The input background to use, null for solid and gradient backgrounds
//@type Background type; null for default background. The method will return error 404 if type is null
//@for_dark_theme True, if the background is chosen for dark theme
setBackground background:InputBackground type:BackgroundType for_dark_theme:Bool = Background;

Binary file not shown.

View File

@ -325,7 +325,8 @@ void BackgroundManager::start_up() {
log_event_parse(logevent, logevent_string).ensure();
CHECK(logevent.background_.id.is_valid());
bool needs_file_id = (logevent.background_.type.type != BackgroundType::Type::Solid);
bool needs_file_id = (logevent.background_.type.type != BackgroundType::Type::Solid &&
logevent.background_.type.type != BackgroundType::Type::Gradient);
if (logevent.background_.file_id.is_valid() != needs_file_id) {
LOG(ERROR) << "Failed to load " << logevent.background_.id << " of " << logevent.background_.type;
G()->td_db()->get_binlog_pmc()->erase(get_background_database_key(for_dark_theme));
@ -393,6 +394,9 @@ Result<string> BackgroundManager::get_background_url(const string &name,
case BackgroundType::Type::Solid:
url += type.get_color_hex_string();
return url;
case BackgroundType::Type::Gradient:
url += type.get_color_hex_string() + '-' + BackgroundType::get_color_hex_string(type.intensity);
return url;
default:
UNREACHABLE();
return url;
@ -427,15 +431,29 @@ BackgroundId BackgroundManager::search_background(const string &name, Promise<Un
return BackgroundId();
}
if (name.size() <= 6) {
for (auto c : name) {
if (name.size() <= 13) {
bool have_hyphen = false;
size_t hyphen_pos = 0;
for (size_t i = 0; i < name.size(); i++) {
auto c = name[i];
if (!is_hex_digit(c)) {
promise.set_error(Status::Error(400, "WALLPAPER_INVALID"));
return BackgroundId();
if (c != '-' || have_hyphen || i > 6 || i + 7 < name.size()) {
promise.set_error(Status::Error(400, "WALLPAPER_INVALID"));
return BackgroundId();
}
have_hyphen = true;
hyphen_pos = i;
}
}
int32 color = static_cast<int32>(hex_to_integer<uint32>(name));
auto background_id = add_solid_background(color);
BackgroundId background_id;
if (have_hyphen) {
int32 top_color = static_cast<int32>(hex_to_integer<uint32>(name.substr(0, hyphen_pos)));
int32 bottom_color = static_cast<int32>(hex_to_integer<uint32>(name.substr(hyphen_pos + 1)));
background_id = add_gradient_background(top_color, bottom_color);
} else {
int32 color = static_cast<int32>(hex_to_integer<uint32>(name));
background_id = add_solid_background(color);
}
promise.set_value(Unit());
return background_id;
}
@ -468,14 +486,15 @@ void BackgroundManager::on_load_background_from_database(string name, string val
loaded_from_database_backgrounds_.insert(name);
CHECK(name.size() > 6);
CHECK(name.size() > 13);
if (name_to_background_id_.count(name) == 0 && !value.empty()) {
LOG(INFO) << "Successfully loaded background " << name << " of size " << value.size() << " from database";
Background background;
auto status = log_event_parse(background, value);
if (status.is_error() || background.type.type == BackgroundType::Type::Solid || !background.file_id.is_valid() ||
if (status.is_error() || background.type.type == BackgroundType::Type::Solid ||
background.type.type == BackgroundType::Type::Gradient || !background.file_id.is_valid() ||
!background.id.is_valid()) {
LOG(ERROR) << "Can't load bacground " << name << ": " << status << ' ' << format::as_hex_dump<4>(Slice(value));
LOG(ERROR) << "Can't load background " << name << ": " << status << ' ' << format::as_hex_dump<4>(Slice(value));
} else {
if (background.name != name) {
LOG(ERROR) << "Expected background " << name << ", but received " << background.name;
@ -533,6 +552,24 @@ BackgroundId BackgroundManager::add_solid_background(int32 color) {
return background_id;
}
BackgroundId BackgroundManager::add_gradient_background(int32 top_color, int32 bottom_color) {
CHECK(0 <= top_color && top_color < 0x1000000);
CHECK(0 <= bottom_color && bottom_color < 0x1000000);
BackgroundId background_id((static_cast<int64>(top_color) << 24) + bottom_color + 1);
Background background;
background.id = background_id;
background.is_creator = true;
background.is_default = false;
background.is_dark = (top_color & 0x808080) == 0 && (bottom_color & 0x808080) == 0;
background.type = BackgroundType(top_color, bottom_color);
background.name =
BackgroundType::get_color_hex_string(top_color) + "-" + BackgroundType::get_color_hex_string(bottom_color);
add_background(background);
return background_id;
}
BackgroundId BackgroundManager::set_background(const td_api::InputBackground *input_background,
const td_api::BackgroundType *background_type, bool for_dark_theme,
Promise<Unit> &&promise) {
@ -557,6 +594,14 @@ BackgroundId BackgroundManager::set_background(const td_api::InputBackground *in
promise.set_value(Unit());
return background_id;
}
if (type.type == BackgroundType::Type::Gradient) {
auto background_id = add_gradient_background(type.color, type.intensity);
if (set_background_id_[for_dark_theme] != background_id) {
set_background_id(background_id, type, for_dark_theme);
}
promise.set_value(Unit());
return background_id;
}
if (input_background == nullptr) {
promise.set_error(Status::Error(400, "Input background must be non-empty"));
@ -753,7 +798,7 @@ void BackgroundManager::remove_background(BackgroundId background_id, Promise<Un
std::move(promise));
});
if (background->type.type == BackgroundType::Type::Solid) {
if (background->type.type == BackgroundType::Type::Solid || background->type.type == BackgroundType::Type::Gradient) {
return query_promise.set_value(Unit());
}
@ -828,7 +873,7 @@ void BackgroundManager::add_background(const Background &background) {
result->name = background.name;
if (result->name.size() > 6) {
if (result->name.size() > 13) {
name_to_background_id_.emplace(result->name, result->id);
loaded_from_database_backgrounds_.erase(result->name); // don't needed anymore
}
@ -863,7 +908,7 @@ void BackgroundManager::add_background(const Background &background) {
file_id_to_background_id_.emplace(result->file_id, result->id);
} else {
// if file_source_id is valid, then this is a new background with result->file_id == FileId()
// then background.file_id == FileId(), then this is a solid background, which can't have file_source_id
// then background.file_id == FileId(), then this is a solid or a gradient background, which can't have file_source_id
CHECK(!file_source_id.is_valid());
}
}
@ -903,7 +948,7 @@ BackgroundId BackgroundManager::on_get_background(BackgroundId expected_backgrou
if (expected_background_id.is_valid() && id != expected_background_id) {
LOG(ERROR) << "Expected " << expected_background_id << ", but receive " << to_string(wallpaper);
}
if (wallpaper->slug_.size() <= 6 || (0 < wallpaper->id_ && wallpaper->id_ <= 0x1000000)) {
if (wallpaper->slug_.size() <= 13 || (0 < wallpaper->id_ && wallpaper->id_ <= 0x1000000000000)) {
LOG(ERROR) << "Receive " << to_string(wallpaper);
return BackgroundId();
}
@ -943,7 +988,7 @@ BackgroundId BackgroundManager::on_get_background(BackgroundId expected_backgrou
name_to_background_id_.emplace(expected_background_name, id);
}
if (G()->parameters().use_file_db && background.name.size() > 6) {
if (G()->parameters().use_file_db && background.name.size() > 13) {
LOG(INFO) << "Save " << id << " to database with name " << background.name;
G()->td_db()->get_sqlite_pmc()->set(get_background_name_database_key(background.name),
log_event_store(background).as_slice().str(), Auto());

View File

@ -106,6 +106,8 @@ class BackgroundManager : public Actor {
BackgroundId add_solid_background(int32 color);
BackgroundId add_gradient_background(int32 top_color, int32 bottom_color);
void add_background(const Background &background);
Background *get_background_ref(BackgroundId background_id);

View File

@ -10,7 +10,7 @@
namespace td {
string BackgroundType::get_color_hex_string() const {
string BackgroundType::get_color_hex_string(int32 color) {
string result;
for (int i = 20; i >= 0; i -= 4) {
result += "0123456789abcdef"[(color >> i) & 0xf];
@ -18,6 +18,10 @@ string BackgroundType::get_color_hex_string() const {
return result;
}
string BackgroundType::get_color_hex_string() const {
return get_color_hex_string(color);
}
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;
@ -33,6 +37,9 @@ StringBuilder &operator<<(StringBuilder &string_builder, const BackgroundType &t
<< ' ' << type.intensity << ']';
case BackgroundType::Type::Solid:
return string_builder << "type Solid[" << type.get_color_hex_string() << ']';
case BackgroundType::Type::Gradient:
return string_builder << "type Gradient[" << type.get_color_hex_string() << '-'
<< type.get_color_hex_string(type.intensity) << ']';
default:
UNREACHABLE();
return string_builder;
@ -61,11 +68,22 @@ Result<BackgroundType> get_background_type(const td_api::BackgroundType *type) {
result = BackgroundType(solid->color_);
break;
}
case td_api::backgroundTypeGradient::ID: {
auto gradient = static_cast<const td_api::backgroundTypeGradient *>(type);
result = BackgroundType(gradient->top_color_, gradient->bottom_color_);
break;
}
default:
UNREACHABLE();
}
if (result.intensity < 0 || result.intensity > 100) {
return Status::Error(400, "Wrong intensity value");
if (result.type == BackgroundType::Type::Gradient) {
if (result.intensity < 0 || result.intensity > 0xFFFFFF) {
return Status::Error(400, "Wrong bottom color value");
}
} else {
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");
@ -113,6 +131,8 @@ td_api::object_ptr<td_api::BackgroundType> get_background_type_object(const Back
return td_api::make_object<td_api::backgroundTypePattern>(type.is_moving, type.color, type.intensity);
case BackgroundType::Type::Solid:
return td_api::make_object<td_api::backgroundTypeSolid>(type.color);
case BackgroundType::Type::Gradient:
return td_api::make_object<td_api::backgroundTypeGradient>(type.color, type.intensity);
default:
UNREACHABLE();
return nullptr;
@ -139,6 +159,7 @@ telegram_api::object_ptr<telegram_api::wallPaperSettings> get_input_wallpaper_se
return telegram_api::make_object<telegram_api::wallPaperSettings>(flags, false /*ignored*/, false /*ignored*/,
type.color, type.intensity);
case BackgroundType::Type::Solid:
case BackgroundType::Type::Gradient:
default:
UNREACHABLE();
return nullptr;

View File

@ -16,7 +16,7 @@
namespace td {
struct BackgroundType {
enum class Type : int32 { Wallpaper, Pattern, Solid };
enum class Type : int32 { Wallpaper, Pattern, Solid, Gradient };
Type type = Type::Solid;
bool is_blurred = false;
bool is_moving = false;
@ -32,8 +32,13 @@ struct BackgroundType {
}
explicit BackgroundType(int32 color) : type(Type::Solid), color(color) {
}
BackgroundType(int32 top_color, int32 bottom_color)
: type(Type::Gradient), color(top_color), intensity(bottom_color) {
}
string get_color_hex_string() const;
static string get_color_hex_string(int32 color);
};
bool operator==(const BackgroundType &lhs, const BackgroundType &rhs);

View File

@ -2102,6 +2102,9 @@ class CliClient final : public Actor {
send_get_background_url(td_api::make_object<td_api::backgroundTypeSolid>(-1));
send_get_background_url(td_api::make_object<td_api::backgroundTypeSolid>(0xABCDEF));
send_get_background_url(td_api::make_object<td_api::backgroundTypeSolid>(0x1000000));
send_get_background_url(td_api::make_object<td_api::backgroundTypeGradient>(0xABCDEF, 0xFEDCBA));
send_get_background_url(td_api::make_object<td_api::backgroundTypeGradient>(0, 0));
send_get_background_url(td_api::make_object<td_api::backgroundTypeGradient>(-1, -1));
} else if (op == "sbg") {
send_request(td_api::make_object<td_api::searchBackground>(args));
} else if (op == "sbgd") {
@ -2117,6 +2120,13 @@ class CliClient final : public Actor {
} else if (op == "sbgs" || op == "sbgsd") {
send_request(td_api::make_object<td_api::setBackground>(
nullptr, td_api::make_object<td_api::backgroundTypeSolid>(to_integer<int32>(args)), op == "sbgsd"));
} else if (op == "sbgg" || op == "sbggd") {
string top_color;
string bottom_color;
std::tie(top_color, bottom_color) = split(args);
auto background_type = td_api::make_object<td_api::backgroundTypeGradient>(to_integer<int32>(top_color),
to_integer<int32>(bottom_color));
send_request(td_api::make_object<td_api::setBackground>(nullptr, std::move(background_type), op == "sbggd"));
} else if (op == "sbgwid" || op == "sbgwidd") {
send_request(td_api::make_object<td_api::setBackground>(
td_api::make_object<td_api::inputBackgroundRemote>(to_integer<int64>(args)),