Calculate key count for each language.
GitOrigin-RevId: aad64d5cecb70f10e3a1cd013b58c7183ad67d31
This commit is contained in:
parent
0300c3387e
commit
3ac0116988
@ -1722,8 +1722,8 @@ languagePackString key:string value:LanguagePackStringValue = LanguagePackString
|
||||
//@description Contains a list of language pack strings @strings A list of language pack strings
|
||||
languagePackStrings strings:vector<languagePackString> = LanguagePackStrings;
|
||||
|
||||
//@description Contains information about a language @code Language code @name Language name @native_name Language native name
|
||||
languageInfo code:string name:string native_name:string = LanguageInfo;
|
||||
//@description Contains information about a language @code Language code @name Language name @native_name Language native name @local_key_count Total number of locally available non-deleted keys from the language
|
||||
languageInfo code:string name:string native_name:string key_count:int32 = LanguageInfo;
|
||||
|
||||
//@description Contains information about a language pack @languages List of available languages
|
||||
languagePack languages:vector<languageInfo> = LanguagePack;
|
||||
@ -3136,7 +3136,7 @@ getLanguagePackInfo = LanguagePack;
|
||||
//@description Returns strings from a language in the used language pack by their keys @language_code Language code of strings to return @keys Language pack keys of strings to return; may be empty to get all available strings
|
||||
getLanguagePackStrings language_code:string keys:vector<string> = LanguagePackStrings;
|
||||
|
||||
//@description Adds or changes a custom language to the used language pack @info Information about the language. Language code must start with 'X' @strings New language pack strings
|
||||
//@description Adds or changes a custom language to the used language pack @info Information about the language. Language code must start with 'X', consist only of English letters, digits and hyphens and be not longer than 64 characters @strings New language pack strings
|
||||
setCustomLanguage info:languageInfo strings:vector<languagePackString> = Ok;
|
||||
|
||||
//@description Sets new value for a string in a custom language in the used language pack @language_code The code of previously added custom language, must start with 'X' @new_string New language pack string
|
||||
|
Binary file not shown.
@ -42,7 +42,9 @@ struct LanguagePackManager::PluralizedString {
|
||||
struct LanguagePackManager::Language {
|
||||
std::mutex mutex_;
|
||||
std::atomic<int32> version_{-1};
|
||||
std::atomic<int32> key_count_{0};
|
||||
bool is_full_ = false;
|
||||
bool was_loaded_full_ = false;
|
||||
bool has_get_difference_query_ = false;
|
||||
std::unordered_map<string, string> ordinary_strings_;
|
||||
std::unordered_map<string, PluralizedString> pluralized_strings_;
|
||||
@ -77,16 +79,16 @@ bool LanguagePackManager::check_language_pack_name(Slice name) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return name.size() <= 64;
|
||||
}
|
||||
|
||||
bool LanguagePackManager::check_language_code_name(Slice name) {
|
||||
for (auto c : name) {
|
||||
if (c != '-' && !is_alpha(c)) {
|
||||
if (c != '-' && !is_alpha(c) && !is_digit(c)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return name.size() <= 64 && (is_custom_language_code(name) || name.empty() || name.size() >= 2);
|
||||
}
|
||||
|
||||
bool LanguagePackManager::is_custom_language_code(Slice language_code) {
|
||||
@ -115,6 +117,26 @@ static int32 load_database_language_version(SqliteKeyValue *kv) {
|
||||
return to_integer<int32>(str_version);
|
||||
}
|
||||
|
||||
static int32 load_database_language_key_count(SqliteKeyValue *kv) {
|
||||
CHECK(kv != nullptr);
|
||||
if (kv->empty()) {
|
||||
return 0;
|
||||
}
|
||||
string str_key_count = kv->get("!key_count");
|
||||
if (str_key_count.empty()) {
|
||||
// calculate key count once for the database and cache it
|
||||
int key_count = 0;
|
||||
for (auto &str : kv->get_all()) {
|
||||
key_count += str.first[0] != '!' && (str.second[0] == '1' || str.second[0] == '2');
|
||||
}
|
||||
LOG(INFO) << "Set language key count in database to " << key_count;
|
||||
kv->set("!key_count", to_string(key_count));
|
||||
return key_count;
|
||||
}
|
||||
|
||||
return to_integer<int32>(str_key_count);
|
||||
}
|
||||
|
||||
LanguagePackManager::LanguageDatabase *LanguagePackManager::add_language_database(const string &path) {
|
||||
auto it = language_databases_.find(path);
|
||||
if (it != language_databases_.end()) {
|
||||
@ -321,13 +343,14 @@ LanguagePackManager::Language *LanguagePackManager::add_language(LanguageDatabas
|
||||
.init_with_connection(database->database_.clone(), get_database_table_name(language_pack, language_code))
|
||||
.ensure();
|
||||
language->version_ = load_database_language_version(&language->kv_);
|
||||
language->key_count_ = load_database_language_key_count(&language->kv_);
|
||||
}
|
||||
code_it = pack->languages_.emplace(language_code, std::move(language)).first;
|
||||
}
|
||||
return code_it->second.get();
|
||||
}
|
||||
|
||||
bool LanguagePackManager::language_has_string_unsafe(Language *language, const string &key) {
|
||||
bool LanguagePackManager::language_has_string_unsafe(const Language *language, const string &key) {
|
||||
return language->ordinary_strings_.count(key) != 0 || language->pluralized_strings_.count(key) != 0 ||
|
||||
language->deleted_strings_.count(key) != 0;
|
||||
}
|
||||
@ -379,27 +402,26 @@ bool LanguagePackManager::load_language_strings(LanguageDatabase *database, Lang
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG(DEBUG) << "Begin to load a language from database";
|
||||
std::lock_guard<std::mutex> database_lock(database->mutex_);
|
||||
std::lock_guard<std::mutex> language_lock(language->mutex_);
|
||||
if (language->is_full_) {
|
||||
LOG(DEBUG) << "The language was already loaded";
|
||||
LOG(DEBUG) << "The language is full in memory";
|
||||
return true;
|
||||
}
|
||||
if (language->kv_.empty()) {
|
||||
LOG(DEBUG) << "The language has no database";
|
||||
return false;
|
||||
}
|
||||
LOG(DEBUG) << "Begin to load a language from database";
|
||||
if (keys.empty()) {
|
||||
if (language->version_ == -1) {
|
||||
LOG(DEBUG) << "There is nothing to load";
|
||||
if (language->version_ == -1 && language->was_loaded_full_) {
|
||||
LOG(DEBUG) << "The language has already been loaded";
|
||||
return false;
|
||||
}
|
||||
|
||||
auto all_strings = language->kv_.get_all();
|
||||
for (auto &str : all_strings) {
|
||||
if (str.first == "!version") {
|
||||
CHECK(to_integer<int32>(str.second) == language->version_);
|
||||
if (str.first[0] == '!') {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -408,17 +430,26 @@ bool LanguagePackManager::load_language_strings(LanguageDatabase *database, Lang
|
||||
load_language_string_unsafe(language, str.first, str.second);
|
||||
}
|
||||
}
|
||||
language->was_loaded_full_ = true;
|
||||
|
||||
if (language->version_ == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
language->is_full_ = true;
|
||||
language->deleted_strings_.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool have_all = true;
|
||||
for (auto &key : keys) {
|
||||
if (!language_has_string_unsafe(language, key)) {
|
||||
auto value = language->kv_.get(key);
|
||||
if (value.empty()) {
|
||||
if (language->version_ == -1) {
|
||||
LOG(DEBUG) << "Have no string with key " << key << " in the database";
|
||||
return false;
|
||||
have_all = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
// have full language in the database, so this string is just deleted
|
||||
@ -427,7 +458,7 @@ bool LanguagePackManager::load_language_strings(LanguageDatabase *database, Lang
|
||||
load_language_string_unsafe(language, key, value);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return have_all;
|
||||
}
|
||||
|
||||
td_api::object_ptr<td_api::LanguagePackStringValue> LanguagePackManager::get_language_pack_string_value_object(
|
||||
@ -460,7 +491,7 @@ td_api::object_ptr<td_api::languagePackString> LanguagePackManager::get_language
|
||||
}
|
||||
|
||||
td_api::object_ptr<td_api::LanguagePackStringValue> LanguagePackManager::get_language_pack_string_value_object(
|
||||
Language *language, const string &key) {
|
||||
const Language *language, const string &key) {
|
||||
CHECK(language != nullptr);
|
||||
auto ordinary_it = language->ordinary_strings_.find(key);
|
||||
if (ordinary_it != language->ordinary_strings_.end()) {
|
||||
@ -474,8 +505,8 @@ td_api::object_ptr<td_api::LanguagePackStringValue> LanguagePackManager::get_lan
|
||||
return get_language_pack_string_value_object(key);
|
||||
}
|
||||
|
||||
td_api::object_ptr<td_api::languagePackString> LanguagePackManager::get_language_pack_string_object(Language *language,
|
||||
const string &key) {
|
||||
td_api::object_ptr<td_api::languagePackString> LanguagePackManager::get_language_pack_string_object(
|
||||
const Language *language, const string &key) {
|
||||
return td_api::make_object<td_api::languagePackString>(key, get_language_pack_string_value_object(language, key));
|
||||
}
|
||||
|
||||
@ -502,34 +533,48 @@ td_api::object_ptr<td_api::languagePackStrings> LanguagePackManager::get_languag
|
||||
}
|
||||
|
||||
void LanguagePackManager::get_languages(Promise<td_api::object_ptr<td_api::languagePack>> promise) {
|
||||
auto request_promise = PromiseCreator::lambda([actor_id = actor_id(this), language_pack = language_pack_,
|
||||
promise = std::move(promise)](Result<NetQueryPtr> r_query) mutable {
|
||||
auto r_result = fetch_result<telegram_api::langpack_getLanguages>(std::move(r_query));
|
||||
if (r_result.is_error()) {
|
||||
return promise.set_error(r_result.move_as_error());
|
||||
}
|
||||
|
||||
send_closure(actor_id, &LanguagePackManager::on_get_languages, r_result.move_as_ok(), std::move(language_pack),
|
||||
std::move(promise));
|
||||
});
|
||||
send_with_promise(G()->net_query_creator().create(create_storer(telegram_api::langpack_getLanguages(language_pack_))),
|
||||
std::move(request_promise));
|
||||
}
|
||||
|
||||
void LanguagePackManager::on_get_languages(vector<tl_object_ptr<telegram_api::langPackLanguage>> languages,
|
||||
string language_pack,
|
||||
Promise<td_api::object_ptr<td_api::languagePack>> promise) {
|
||||
auto results = make_tl_object<td_api::languagePack>();
|
||||
|
||||
std::lock_guard<std::mutex> packs_lock(database_->mutex_);
|
||||
auto pack_it = database_->language_packs_.find(language_pack_);
|
||||
if (pack_it != database_->language_packs_.end()) {
|
||||
LanguagePack *pack = pack_it->second.get();
|
||||
for (auto &info : pack->language_infos_) {
|
||||
results->languages_.push_back(
|
||||
make_tl_object<td_api::languageInfo>(info.first, info.second.name, info.second.native_name));
|
||||
{
|
||||
std::lock_guard<std::mutex> packs_lock(database_->mutex_);
|
||||
auto pack_it = database_->language_packs_.find(language_pack);
|
||||
if (pack_it != database_->language_packs_.end()) {
|
||||
LanguagePack *pack = pack_it->second.get();
|
||||
for (auto &info : pack->language_infos_) {
|
||||
results->languages_.push_back(
|
||||
make_tl_object<td_api::languageInfo>(info.first, info.second.name, info.second.native_name, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto request_promise = PromiseCreator::lambda(
|
||||
[results = std::move(results), promise = std::move(promise)](Result<NetQueryPtr> r_query) mutable {
|
||||
auto r_result = fetch_result<telegram_api::langpack_getLanguages>(std::move(r_query));
|
||||
if (r_result.is_error()) {
|
||||
return promise.set_error(r_result.move_as_error());
|
||||
}
|
||||
for (auto &language : languages) {
|
||||
results->languages_.push_back(
|
||||
make_tl_object<td_api::languageInfo>(language->lang_code_, language->name_, language->native_name_, 0));
|
||||
}
|
||||
|
||||
auto languages = r_result.move_as_ok();
|
||||
for (auto &language : languages) {
|
||||
results->languages_.push_back(
|
||||
make_tl_object<td_api::languageInfo>(language->lang_code_, language->name_, language->native_name_));
|
||||
}
|
||||
promise.set_value(std::move(results));
|
||||
});
|
||||
send_with_promise(G()->net_query_creator().create(create_storer(telegram_api::langpack_getLanguages(language_pack_))),
|
||||
std::move(request_promise));
|
||||
for (auto &language_info : results->languages_) {
|
||||
auto language = add_language(database_, language_pack, language_info->code_);
|
||||
language_info->key_count_ = language->key_count_;
|
||||
}
|
||||
|
||||
promise.set_value(std::move(results));
|
||||
}
|
||||
|
||||
void LanguagePackManager::get_language_pack_strings(string language_code, vector<string> keys,
|
||||
@ -540,15 +585,12 @@ void LanguagePackManager::get_language_pack_strings(string language_code, vector
|
||||
}
|
||||
}
|
||||
|
||||
Language *language = get_language(database_, language_pack_, language_code);
|
||||
Language *language = add_language(database_, language_pack_, language_code);
|
||||
if (language_has_strings(language, keys)) {
|
||||
return promise.set_value(get_language_pack_strings_object(language, keys));
|
||||
}
|
||||
if (!database_->database_.empty()) {
|
||||
language = add_language(database_, language_pack_, language_code);
|
||||
if (load_language_strings(database_, language, keys)) {
|
||||
return promise.set_value(get_language_pack_strings_object(language, keys));
|
||||
}
|
||||
if (load_language_strings(database_, language, keys)) {
|
||||
return promise.set_value(get_language_pack_strings_object(language, keys));
|
||||
}
|
||||
|
||||
if (keys.empty()) {
|
||||
@ -617,7 +659,8 @@ td_api::object_ptr<td_api::Object> LanguagePackManager::get_language_pack_string
|
||||
std::lock_guard<std::mutex> lock(language->mutex_);
|
||||
return get_language_pack_string_value_object(language, key);
|
||||
}
|
||||
if (!database->database_.empty() && load_language_strings(database, language, keys)) {
|
||||
if (load_language_strings(database, language, keys)) {
|
||||
std::lock_guard<std::mutex> lock(language->mutex_);
|
||||
return get_language_pack_string_value_object(language, key);
|
||||
}
|
||||
return td_api::make_object<td_api::error>(404, "Not Found");
|
||||
@ -632,15 +675,16 @@ bool LanguagePackManager::is_valid_key(Slice key) {
|
||||
return !key.empty();
|
||||
}
|
||||
|
||||
void LanguagePackManager::save_strings_to_database(Language *language, int32 new_version,
|
||||
vector<std::pair<string, string>> strings) {
|
||||
LOG(DEBUG) << "Save to database a language with new version " << new_version;
|
||||
void LanguagePackManager::save_strings_to_database(SqliteKeyValue *kv, int32 new_version, bool new_is_full,
|
||||
int32 new_key_count, vector<std::pair<string, string>> strings) {
|
||||
LOG(DEBUG) << "Save to database a language with new version " << new_version << " and " << strings.size()
|
||||
<< " new strings";
|
||||
if (new_version == -1 && strings.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(database_->mutex_);
|
||||
auto kv = &language->kv_;
|
||||
CHECK(kv != nullptr);
|
||||
if (kv->empty()) {
|
||||
LOG(DEBUG) << "There is no associated database key-value";
|
||||
return;
|
||||
@ -658,7 +702,7 @@ void LanguagePackManager::save_strings_to_database(Language *language, int32 new
|
||||
continue;
|
||||
}
|
||||
|
||||
if (language->is_full_ && str.second == "3") {
|
||||
if (new_is_full && str.second == "3") {
|
||||
kv->erase(str.first);
|
||||
} else {
|
||||
kv->set(str.first, str.second);
|
||||
@ -669,6 +713,10 @@ void LanguagePackManager::save_strings_to_database(Language *language, int32 new
|
||||
LOG(DEBUG) << "Set language version in database to " << new_version;
|
||||
kv->set("!version", to_string(new_version));
|
||||
}
|
||||
if (new_key_count != -1) {
|
||||
LOG(DEBUG) << "Set language key count in database to " << new_key_count;
|
||||
kv->set("!key_count", to_string(new_key_count));
|
||||
}
|
||||
kv->commit_transaction().ensure();
|
||||
}
|
||||
|
||||
@ -679,13 +727,18 @@ void LanguagePackManager::on_get_language_pack_strings(
|
||||
Language *language = get_language(database_, language_pack, language_code);
|
||||
bool is_version_changed = false;
|
||||
int32 new_database_version = -1;
|
||||
int32 new_key_count = -1;
|
||||
bool new_is_full = false;
|
||||
vector<std::pair<string, string>> database_strings;
|
||||
if (language == nullptr || language->version_ < version || !keys.empty()) {
|
||||
if (language == nullptr) {
|
||||
language = add_language(database_, language_pack, language_code);
|
||||
CHECK(language != nullptr);
|
||||
}
|
||||
load_language_strings(database_, language, keys);
|
||||
|
||||
std::lock_guard<std::mutex> lock(language->mutex_);
|
||||
int32 key_count_delta = 0;
|
||||
if (language->version_ < version || !keys.empty()) {
|
||||
vector<td_api::object_ptr<td_api::languagePackString>> strings;
|
||||
if (language->version_ < version && !(is_diff && language->version_ == -1)) {
|
||||
@ -702,11 +755,12 @@ void LanguagePackManager::on_get_language_pack_strings(
|
||||
auto str = static_cast<telegram_api::langPackString *>(result.get());
|
||||
auto it = language->ordinary_strings_.find(str->key_);
|
||||
if (it == language->ordinary_strings_.end()) {
|
||||
key_count_delta++;
|
||||
it = language->ordinary_strings_.emplace(str->key_, std::move(str->value_)).first;
|
||||
} else {
|
||||
it->second = std::move(str->value_);
|
||||
}
|
||||
language->pluralized_strings_.erase(str->key_);
|
||||
key_count_delta -= language->pluralized_strings_.erase(str->key_);
|
||||
language->deleted_strings_.erase(str->key_);
|
||||
if (is_diff) {
|
||||
strings.push_back(get_language_pack_string_object(*it));
|
||||
@ -721,11 +775,12 @@ void LanguagePackManager::on_get_language_pack_strings(
|
||||
std::move(str->many_value_), std::move(str->other_value_)};
|
||||
auto it = language->pluralized_strings_.find(str->key_);
|
||||
if (it == language->pluralized_strings_.end()) {
|
||||
key_count_delta++;
|
||||
it = language->pluralized_strings_.emplace(str->key_, std::move(value)).first;
|
||||
} else {
|
||||
it->second = std::move(value);
|
||||
}
|
||||
language->ordinary_strings_.erase(str->key_);
|
||||
key_count_delta -= language->ordinary_strings_.erase(str->key_);
|
||||
language->deleted_strings_.erase(str->key_);
|
||||
if (is_diff) {
|
||||
strings.push_back(get_language_pack_string_object(*it));
|
||||
@ -738,8 +793,8 @@ void LanguagePackManager::on_get_language_pack_strings(
|
||||
}
|
||||
case telegram_api::langPackStringDeleted::ID: {
|
||||
auto str = static_cast<const telegram_api::langPackStringDeleted *>(result.get());
|
||||
language->ordinary_strings_.erase(str->key_);
|
||||
language->pluralized_strings_.erase(str->key_);
|
||||
key_count_delta -= language->ordinary_strings_.erase(str->key_);
|
||||
key_count_delta -= language->pluralized_strings_.erase(str->key_);
|
||||
language->deleted_strings_.insert(std::move(str->key_));
|
||||
if (is_diff) {
|
||||
strings.push_back(get_language_pack_string_object(str->key_));
|
||||
@ -765,6 +820,11 @@ void LanguagePackManager::on_get_language_pack_strings(
|
||||
}
|
||||
}
|
||||
|
||||
if (key_count_delta != 0) {
|
||||
new_key_count = language->key_count_ + key_count_delta;
|
||||
language->key_count_ = new_key_count;
|
||||
}
|
||||
|
||||
if (is_diff) {
|
||||
send_closure(
|
||||
G()->td(), &Td::send_update,
|
||||
@ -776,10 +836,15 @@ void LanguagePackManager::on_get_language_pack_strings(
|
||||
language->is_full_ = true;
|
||||
language->deleted_strings_.clear();
|
||||
}
|
||||
new_is_full = language->is_full_;
|
||||
}
|
||||
}
|
||||
if (is_custom_language_code(language_code) && new_database_version == -1) {
|
||||
new_database_version = 1;
|
||||
}
|
||||
|
||||
save_strings_to_database(language, new_database_version, std::move(database_strings));
|
||||
save_strings_to_database(&language->kv_, new_database_version, new_is_full, new_key_count,
|
||||
std::move(database_strings));
|
||||
|
||||
if (is_diff) {
|
||||
CHECK(language != nullptr);
|
||||
@ -965,6 +1030,7 @@ Status LanguagePackManager::do_delete_language(string language_code) {
|
||||
}
|
||||
std::lock_guard<std::mutex> language_lock(language->mutex_);
|
||||
language->version_ = -1;
|
||||
language->key_count_ = load_database_language_key_count(&language->kv_);
|
||||
language->is_full_ = false;
|
||||
language->ordinary_strings_.clear();
|
||||
language->pluralized_strings_.clear();
|
||||
|
@ -24,6 +24,8 @@
|
||||
|
||||
namespace td {
|
||||
|
||||
class SqliteKeyValue;
|
||||
|
||||
class LanguagePackManager : public NetQueryCallback {
|
||||
public:
|
||||
explicit LanguagePackManager(ActorShared<> parent) : parent_(std::move(parent)) {
|
||||
@ -90,7 +92,7 @@ class LanguagePackManager : public NetQueryCallback {
|
||||
|
||||
static Language *add_language(LanguageDatabase *database, const string &language_pack, const string &language_code);
|
||||
|
||||
static bool language_has_string_unsafe(Language *language, const string &key);
|
||||
static bool language_has_string_unsafe(const Language *language, const string &key);
|
||||
static bool language_has_strings(Language *language, const vector<string> &keys);
|
||||
|
||||
static void load_language_string_unsafe(Language *language, const string &key, string &value);
|
||||
@ -107,10 +109,10 @@ class LanguagePackManager : public NetQueryCallback {
|
||||
const std::pair<string, PluralizedString> &str);
|
||||
static td_api::object_ptr<td_api::languagePackString> get_language_pack_string_object(const string &str);
|
||||
|
||||
static td_api::object_ptr<td_api::LanguagePackStringValue> get_language_pack_string_value_object(Language *language,
|
||||
const string &key);
|
||||
static td_api::object_ptr<td_api::LanguagePackStringValue> get_language_pack_string_value_object(
|
||||
const Language *language, const string &key);
|
||||
|
||||
static td_api::object_ptr<td_api::languagePackString> get_language_pack_string_object(Language *language,
|
||||
static td_api::object_ptr<td_api::languagePackString> get_language_pack_string_object(const Language *language,
|
||||
const string &key);
|
||||
|
||||
static td_api::object_ptr<td_api::languagePackStrings> get_language_pack_strings_object(Language *language,
|
||||
@ -123,7 +125,8 @@ class LanguagePackManager : public NetQueryCallback {
|
||||
|
||||
static bool is_valid_key(Slice key);
|
||||
|
||||
void save_strings_to_database(Language *language, int32 new_version, vector<std::pair<string, string>> strings);
|
||||
void save_strings_to_database(SqliteKeyValue *kv, int32 new_version, bool new_is_full, int32 new_key_count,
|
||||
vector<std::pair<string, string>> strings);
|
||||
|
||||
void on_get_language_pack_strings(string language_pack, string language_code, int32 version, bool is_diff,
|
||||
vector<string> keys, vector<tl_object_ptr<telegram_api::LangPackString>> results,
|
||||
@ -131,6 +134,9 @@ class LanguagePackManager : public NetQueryCallback {
|
||||
|
||||
void on_failed_get_difference(string language_pack, string language_code);
|
||||
|
||||
void on_get_languages(vector<tl_object_ptr<telegram_api::langPackLanguage>> languages, string language_pack,
|
||||
Promise<td_api::object_ptr<td_api::languagePack>> promise);
|
||||
|
||||
Status do_delete_language(string language_code);
|
||||
|
||||
void on_result(NetQueryPtr query) override;
|
||||
|
@ -1788,7 +1788,7 @@ class CliClient final : public Actor {
|
||||
"DELETED", make_tl_object<td_api::languagePackStringValueDeleted>()));
|
||||
|
||||
send_request(make_tl_object<td_api::setCustomLanguage>(
|
||||
make_tl_object<td_api::languageInfo>(language_code, name, native_name), std::move(strings)));
|
||||
make_tl_object<td_api::languageInfo>(language_code, name, native_name, 3), std::move(strings)));
|
||||
} else if (op == "sclsv" || op == "sclsp" || op == "sclsd") {
|
||||
string language_code;
|
||||
string key;
|
||||
|
Reference in New Issue
Block a user