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 //@description A solid background @color A color of the background in RGB24 format
backgroundTypeSolid color:int32 = BackgroundType; 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 //@description Describes a chat background
//@id Unique background identifier //@id Unique background identifier
//@is_default True, if this is one of default backgrounds //@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 //@is_dark True, if the background is dark and is recommended to be used with dark theme
//@name Unique background name //@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 //@type Type of the background
background id:int64 is_default:Bool is_dark:Bool name:string document:document type:BackgroundType = 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; searchBackground name:string = Background;
//@description Changes the background selected by the user; adds background to the list of installed backgrounds //@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 //@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 //@for_dark_theme True, if the background is chosen for dark theme
setBackground background:InputBackground type:BackgroundType for_dark_theme:Bool = Background; 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(); log_event_parse(logevent, logevent_string).ensure();
CHECK(logevent.background_.id.is_valid()); 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) { if (logevent.background_.file_id.is_valid() != needs_file_id) {
LOG(ERROR) << "Failed to load " << logevent.background_.id << " of " << logevent.background_.type; 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)); 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: case BackgroundType::Type::Solid:
url += type.get_color_hex_string(); url += type.get_color_hex_string();
return url; return url;
case BackgroundType::Type::Gradient:
url += type.get_color_hex_string() + '-' + BackgroundType::get_color_hex_string(type.intensity);
return url;
default: default:
UNREACHABLE(); UNREACHABLE();
return url; return url;
@ -427,15 +431,29 @@ BackgroundId BackgroundManager::search_background(const string &name, Promise<Un
return BackgroundId(); return BackgroundId();
} }
if (name.size() <= 6) { if (name.size() <= 13) {
for (auto c : name) { 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)) { if (!is_hex_digit(c)) {
promise.set_error(Status::Error(400, "WALLPAPER_INVALID")); if (c != '-' || have_hyphen || i > 6 || i + 7 < name.size()) {
return BackgroundId(); 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)); BackgroundId background_id;
auto background_id = add_solid_background(color); 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()); promise.set_value(Unit());
return background_id; return background_id;
} }
@ -468,14 +486,15 @@ void BackgroundManager::on_load_background_from_database(string name, string val
loaded_from_database_backgrounds_.insert(name); loaded_from_database_backgrounds_.insert(name);
CHECK(name.size() > 6); CHECK(name.size() > 13);
if (name_to_background_id_.count(name) == 0 && !value.empty()) { if (name_to_background_id_.count(name) == 0 && !value.empty()) {
LOG(INFO) << "Successfully loaded background " << name << " of size " << value.size() << " from database"; LOG(INFO) << "Successfully loaded background " << name << " of size " << value.size() << " from database";
Background background; Background background;
auto status = log_event_parse(background, value); 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()) { !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 { } else {
if (background.name != name) { if (background.name != name) {
LOG(ERROR) << "Expected background " << name << ", but received " << background.name; LOG(ERROR) << "Expected background " << name << ", but received " << background.name;
@ -533,6 +552,24 @@ BackgroundId BackgroundManager::add_solid_background(int32 color) {
return background_id; 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, BackgroundId BackgroundManager::set_background(const td_api::InputBackground *input_background,
const td_api::BackgroundType *background_type, bool for_dark_theme, const td_api::BackgroundType *background_type, bool for_dark_theme,
Promise<Unit> &&promise) { Promise<Unit> &&promise) {
@ -557,6 +594,14 @@ BackgroundId BackgroundManager::set_background(const td_api::InputBackground *in
promise.set_value(Unit()); promise.set_value(Unit());
return background_id; 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) { if (input_background == nullptr) {
promise.set_error(Status::Error(400, "Input background must be non-empty")); 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)); 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()); return query_promise.set_value(Unit());
} }
@ -828,7 +873,7 @@ void BackgroundManager::add_background(const Background &background) {
result->name = background.name; result->name = background.name;
if (result->name.size() > 6) { if (result->name.size() > 13) {
name_to_background_id_.emplace(result->name, result->id); name_to_background_id_.emplace(result->name, result->id);
loaded_from_database_backgrounds_.erase(result->name); // don't needed anymore 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); file_id_to_background_id_.emplace(result->file_id, result->id);
} else { } else {
// if file_source_id is valid, then this is a new background with result->file_id == FileId() // 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()); 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) { 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 || (0 < wallpaper->id_ && wallpaper->id_ <= 0x1000000)) { if (wallpaper->slug_.size() <= 13 || (0 < wallpaper->id_ && wallpaper->id_ <= 0x1000000000000)) {
LOG(ERROR) << "Receive " << to_string(wallpaper); LOG(ERROR) << "Receive " << to_string(wallpaper);
return BackgroundId(); return BackgroundId();
} }
@ -943,7 +988,7 @@ BackgroundId BackgroundManager::on_get_background(BackgroundId expected_backgrou
name_to_background_id_.emplace(expected_background_name, id); 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; LOG(INFO) << "Save " << id << " to database with name " << background.name;
G()->td_db()->get_sqlite_pmc()->set(get_background_name_database_key(background.name), G()->td_db()->get_sqlite_pmc()->set(get_background_name_database_key(background.name),
log_event_store(background).as_slice().str(), Auto()); 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_solid_background(int32 color);
BackgroundId add_gradient_background(int32 top_color, int32 bottom_color);
void add_background(const Background &background); void add_background(const Background &background);
Background *get_background_ref(BackgroundId background_id); Background *get_background_ref(BackgroundId background_id);

View File

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

View File

@ -16,7 +16,7 @@
namespace td { namespace td {
struct BackgroundType { struct BackgroundType {
enum class Type : int32 { Wallpaper, Pattern, Solid }; enum class Type : int32 { Wallpaper, Pattern, Solid, Gradient };
Type type = Type::Solid; Type type = Type::Solid;
bool is_blurred = false; bool is_blurred = false;
bool is_moving = false; bool is_moving = false;
@ -32,8 +32,13 @@ struct BackgroundType {
} }
explicit BackgroundType(int32 color) : type(Type::Solid), color(color) { 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; string get_color_hex_string() const;
static string get_color_hex_string(int32 color);
}; };
bool operator==(const BackgroundType &lhs, const BackgroundType &rhs); 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>(-1));
send_get_background_url(td_api::make_object<td_api::backgroundTypeSolid>(0xABCDEF)); 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::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") { } 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 == "sbgd") { } else if (op == "sbgd") {
@ -2117,6 +2120,13 @@ class CliClient final : public Actor {
} else if (op == "sbgs" || op == "sbgsd") { } else if (op == "sbgs" || op == "sbgsd") {
send_request(td_api::make_object<td_api::setBackground>( send_request(td_api::make_object<td_api::setBackground>(
nullptr, td_api::make_object<td_api::backgroundTypeSolid>(to_integer<int32>(args)), op == "sbgsd")); 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") { } else if (op == "sbgwid" || op == "sbgwidd") {
send_request(td_api::make_object<td_api::setBackground>( 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::inputBackgroundRemote>(to_integer<int64>(args)),