chore: refactor languages

This commit is contained in:
AlexeyZavar 2024-09-25 19:05:57 +03:00
parent 2b01b63ee1
commit 157b25ea43
9 changed files with 80 additions and 126 deletions

View file

@ -5726,18 +5726,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"ayu_ImportDataSuccess" = "Database imported successfully.";
"ayu_ImportDataFailure" = "Failed to import database.";
"ayu_RegexFilters" = "Message Filters";
"ayu_RegexFiltersAmount_zero" = "%1$d filters";
"ayu_RegexFiltersAmount_one" = "1 filter";
"ayu_RegexFiltersAmount_two" = "%1$d filters";
"ayu_RegexFiltersAmount_few" = "%1$d filters";
"ayu_RegexFiltersAmount_many" = "%1$d filters";
"ayu_RegexFiltersAmount_other" = "%1$d filters";
"ayu_RegexFiltersExcludedAmount_zero" = "%1$d excluded";
"ayu_RegexFiltersExcludedAmount_one" = "1 excluded";
"ayu_RegexFiltersExcludedAmount_two" = "%1$d excluded";
"ayu_RegexFiltersExcludedAmount_few" = "%1$d excluded";
"ayu_RegexFiltersExcludedAmount_many" = "%1$d excluded";
"ayu_RegexFiltersExcludedAmount_other" = "%1$d excluded";
"ayu_RegexFiltersAmount#one" = "1 filter";
"ayu_RegexFiltersAmount#other" = "{count} filters";
"ayu_RegexFiltersExcludedAmount#one" = "1 excluded";
"ayu_RegexFiltersExcludedAmount#other" = "{count} excluded";
"ayu_RegexFiltersHeader" = "Filters";
"ayu_RegexFiltersShared" = "Shared Filters";
"ayu_RegexFiltersExcluded" = "Excluded Filters";
@ -5772,42 +5764,18 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"ayu_FiltersToastFailNoChanges" = "Filters are the same as current.";
"ayu_FiltersToastSuccess" = "Filters successfully imported.";
"ayu_FiltersSheetTitle" = "Apply filter changes?";
"ayu_FiltersSheetNewFilters_zero" = "**%1$d** new filters";
"ayu_FiltersSheetNewFilters_one" = "**1** new filter";
"ayu_FiltersSheetNewFilters_two" = "**%1$d** new filters";
"ayu_FiltersSheetNewFilters_few" = "**%1$d** new filters";
"ayu_FiltersSheetNewFilters_many" = "**%1$d** new filters";
"ayu_FiltersSheetNewFilters_other" = "**%1$d** new filters";
"ayu_FiltersSheetRemovedFilters_zero" = "**%1$d** removed filters";
"ayu_FiltersSheetRemovedFilters_one" = "**1** removed filter";
"ayu_FiltersSheetRemovedFilters_two" = "**%1$d** removed filters";
"ayu_FiltersSheetRemovedFilters_few" = "**%1$d** removed filters";
"ayu_FiltersSheetRemovedFilters_many" = "**%1$d** removed filters";
"ayu_FiltersSheetRemovedFilters_other" = "**%1$d** removed filters";
"ayu_FiltersSheetUpdatedFilters_zero" = "**%1$d** updated filters";
"ayu_FiltersSheetUpdatedFilters_one" = "**1** updated filter";
"ayu_FiltersSheetUpdatedFilters_two" = "**%1$d** updated filters";
"ayu_FiltersSheetUpdatedFilters_few" = "**%1$d** updated filters";
"ayu_FiltersSheetUpdatedFilters_many" = "**%1$d** updated filters";
"ayu_FiltersSheetUpdatedFilters_other" = "**%1$d** updated filters";
"ayu_FiltersSheetNewExclusions_zero" = "**%1$d** new exclusions";
"ayu_FiltersSheetNewExclusions_one" = "**1** new exclusion";
"ayu_FiltersSheetNewExclusions_two" = "**%1$d** new exclusions";
"ayu_FiltersSheetNewExclusions_few" = "**%1$d** new exclusions";
"ayu_FiltersSheetNewExclusions_many" = "**%1$d** new exclusions";
"ayu_FiltersSheetNewExclusions_other" = "**%1$d** new exclusions";
"ayu_FiltersSheetRemovedExclusions_zero" = "**%1$d** removed exclusions";
"ayu_FiltersSheetRemovedExclusions_one" = "**1** removed exclusion";
"ayu_FiltersSheetRemovedExclusions_two" = "**%1$d** removed exclusions";
"ayu_FiltersSheetRemovedExclusions_few" = "**%1$d** removed exclusions";
"ayu_FiltersSheetRemovedExclusions_many" = "**%1$d** removed exclusions";
"ayu_FiltersSheetRemovedExclusions_other" = "**%1$d** removed exclusions";
"ayu_FiltersSheetDialogsToResolve_zero" = "**%1$d** dialogs to resolve";
"ayu_FiltersSheetDialogsToResolve_one" = "**1** dialog to resolve";
"ayu_FiltersSheetDialogsToResolve_two" = "**%1$d** dialogs to resolve";
"ayu_FiltersSheetDialogsToResolve_few" = "**%1$d** dialogs to resolve";
"ayu_FiltersSheetDialogsToResolve_many" = "**%1$d** dialogs to resolve";
"ayu_FiltersSheetDialogsToResolve_other" = "**%1$d** dialogs to resolve";
"ayu_FiltersSheetNewFilters#one" = "**1** new filter";
"ayu_FiltersSheetNewFilters#other" = "**{count}** new filters";
"ayu_FiltersSheetRemovedFilters#one" = "**1** removed filter";
"ayu_FiltersSheetRemovedFilters#other" = "**{count}** removed filters";
"ayu_FiltersSheetUpdatedFilters#one" = "**1** updated filter";
"ayu_FiltersSheetUpdatedFilters#other" = "**{count}** updated filters";
"ayu_FiltersSheetNewExclusions#one" = "**1** new exclusion";
"ayu_FiltersSheetNewExclusions#other" = "**{count}** new exclusions";
"ayu_FiltersSheetRemovedExclusions#one" = "**1** removed exclusion";
"ayu_FiltersSheetRemovedExclusions#other" = "**{count}** removed exclusions";
"ayu_FiltersSheetDialogsToResolve#one" = "**1** dialog to resolve";
"ayu_FiltersSheetDialogsToResolve#other" = "**{count}** dialogs to resolve";
"ayu_FiltersClearPopupTitle" = "Clear filters";
"ayu_FiltersClearPopupText" = "Are you sure you want to clear all filters?";
"ayu_FiltersClearPopupActionText" = "Clear";
@ -5912,8 +5880,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"ayu_AyuForwardStatusLoadingMedia" = "Loading media";
"ayu_AyuForwardStatusForwarding" = "Forwarding messages";
"ayu_AyuForwardStatusFinished" = "Done";
"ayu_AyuForwardStatusSentCount" = "sent %1$d of %2$d";
"ayu_AyuForwardStatusChunkCount" = "chunk %1$d of %2$d";
"ayu_AyuForwardStatusSentCount" = "sent {count1} of {count2}";
"ayu_AyuForwardStatusChunkCount" = "chunk {count1} of {count2}";
"ayu_JumpToBeginning" = "To Beginning";
"ayu_ExpireMediaContextMenuText" = "Burn";
"ayu_ExpiringVoiceMessageNote" = "This voice message can be played as many times as you want.";

View file

@ -17,14 +17,14 @@
namespace AyuInfra {
void initLang() {
QString langPackBaseId = Lang::GetInstance().baseId();
QString langPackId = Lang::GetInstance().id();
if (langPackId.isEmpty()) {
LOG(("Lang ID not found! Re-use old language pack..."));
QString id = Lang::GetInstance().id();
QString baseId = Lang::GetInstance().baseId();
if (id.isEmpty()) {
LOG(("Language ID not found!"));
return;
}
CustomLangPack::initInstance();
CustomLangPack::currentInstance()->fetchCustomLangPack(langPackId, langPackBaseId);
AyuLanguage::init();
AyuLanguage::currentInstance()->fetchLanguage(id, baseId);
}
void initFonts() {

View file

@ -20,49 +20,45 @@ std::map<QString, QString> langMapping = {
{"zh-hant-raw", "zh-hant"},
};
CustomLangPack *CustomLangPack::instance = nullptr;
AyuLanguage *AyuLanguage::instance = nullptr;
CustomLangPack::CustomLangPack() = default;
AyuLanguage::AyuLanguage() = default;
void CustomLangPack::initInstance() {
if (!instance) instance = new CustomLangPack;
void AyuLanguage::init() {
if (!instance) instance = new AyuLanguage;
}
CustomLangPack *CustomLangPack::currentInstance() {
AyuLanguage *AyuLanguage::currentInstance() {
return instance;
}
void CustomLangPack::fetchCustomLangPack(const QString &langPackId, const QString &langPackBaseId) {
LOG(("Current Language pack ID: %1, Base ID: %2").arg(langPackId, langPackBaseId));
void AyuLanguage::fetchLanguage(const QString &id, const QString &baseId) {
auto finalLangPackId = langMapping.contains(id) ? langMapping[id] : id;
auto finalLangPackId = langMapping.contains(langPackId) ? langMapping[langPackId] : langPackId;
const auto proxy = Core::App().settings().proxy().isEnabled()
? Core::App().settings().proxy().selected()
: MTP::ProxyData();
if (proxy.type == MTP::ProxyData::Type::Socks5 || proxy.type == MTP::ProxyData::Type::Http) {
QNetworkProxy LocaleProxy = ToNetworkProxy(ToDirectIpProxy(proxy));
networkManager.setProxy(LocaleProxy);
if (Core::App().settings().proxy().isEnabled()) {
const auto proxy = Core::App().settings().proxy().selected();
if (proxy.type == MTP::ProxyData::Type::Socks5 || proxy.type == MTP::ProxyData::Type::Http) {
const auto networkProxy = ToNetworkProxy(ToDirectIpProxy(Core::App().settings().proxy().selected()));
networkManager.setProxy(networkProxy);
}
}
// using `jsdelivr` since China (...and maybe other?) users have some problems with GitHub
// https://crowdin.com/project/ayugram/discussions/6
QUrl url;
if (!finalLangPackId.isEmpty() && !langPackBaseId.isEmpty() && !needFallback) {
if (!finalLangPackId.isEmpty() && !baseId.isEmpty() && !needFallback) {
url.setUrl(qsl("https://cdn.jsdelivr.net/gh/AyuGram/Languages@l10n_main/values/langs/%1/Shared.json").arg(
finalLangPackId));
} else {
url.setUrl(qsl("https://cdn.jsdelivr.net/gh/AyuGram/Languages@l10n_main/values/langs/%1/Shared.json").arg(
needFallback ? langPackBaseId : finalLangPackId));
needFallback ? baseId : finalLangPackId));
}
_chkReply = networkManager.get(QNetworkRequest(url));
connect(_chkReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(fetchError(QNetworkReply::NetworkError)));
connect(_chkReply, SIGNAL(finished()), this, SLOT(fetchFinished()));
LOG(("Fetching %1 lang pack...").arg(
needFallback ? (langPackBaseId.isEmpty() ? finalLangPackId : langPackBaseId) : finalLangPackId));
}
void CustomLangPack::fetchFinished() {
void AyuLanguage::fetchFinished() {
if (!_chkReply) return;
QString langPackBaseId = Lang::GetInstance().baseId();
@ -70,72 +66,61 @@ void CustomLangPack::fetchFinished() {
auto statusCode = _chkReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
if (statusCode == 404 && !langPackId.isEmpty() && !langPackBaseId.isEmpty() && !needFallback) {
LOG(("AyuGram Language pack not found! Fallback to main language: %1...").arg(langPackBaseId));
LOG(("AyuGram Language not found! Fallback to main language: %1...").arg(langPackBaseId));
needFallback = true;
_chkReply->disconnect();
fetchCustomLangPack("", langPackBaseId);
fetchLanguage("", langPackBaseId);
} else {
QByteArray result = _chkReply->readAll().trimmed();
const auto result = _chkReply->readAll().trimmed();
QJsonParseError error{};
QJsonDocument str = QJsonDocument::fromJson(result, &error);
const auto doc = QJsonDocument::fromJson(result, &error);
if (error.error == QJsonParseError::NoError) {
parseLangFile(str);
applyLanguageJson(doc);
} else {
LOG(("Incorrect JSON File. Fallback to default language: English..."));
loadDefaultLangFile();
LOG(("Incorrect language JSON File."));
}
_chkReply = nullptr;
}
}
void CustomLangPack::fetchError(QNetworkReply::NetworkError e) {
void AyuLanguage::fetchError(QNetworkReply::NetworkError e) {
LOG(("Network error: %1").arg(e));
if (e == QNetworkReply::NetworkError::ContentNotFoundError) {
QString langPackBaseId = Lang::GetInstance().baseId();
QString langPackId = Lang::GetInstance().id();
const auto baseId = Lang::GetInstance().baseId();
const auto id = Lang::GetInstance().id();
if (!langPackId.isEmpty() && !langPackBaseId.isEmpty() && !needFallback) {
LOG(("AyuGram Language pack not found! Fallback to main language: %1...").arg(langPackBaseId));
if (!id.isEmpty() && !baseId.isEmpty() && !needFallback) {
LOG(("AyuGram Language not found! Fallback to main language: %1...").arg(baseId));
needFallback = true;
_chkReply->disconnect();
fetchCustomLangPack("", langPackBaseId);
fetchLanguage("", baseId);
} else {
LOG(("AyuGram Language pack not found! Fallback to default language: English..."));
loadDefaultLangFile();
LOG(("AyuGram Language not found!"));
_chkReply = nullptr;
}
}
}
void CustomLangPack::loadDefaultLangFile() {
QFile file(":/localization/en.json");
if (file.open(QIODevice::ReadOnly)) {
QJsonDocument str = QJsonDocument::fromJson(file.readAll());
QJsonObject json = str.object();
for (const QString &key : json.keys()) {
Lang::GetInstance().applyValue(key.toUtf8(), json.value(key).toString().toUtf8());
}
Lang::GetInstance().updatePluralRules();
file.close();
}
}
void CustomLangPack::parseLangFile(QJsonDocument str) {
QJsonObject json = str.object();
void AyuLanguage::applyLanguageJson(QJsonDocument doc) {
const auto json = doc.object();
for (const QString &brokenKey : json.keys()) {
auto key = qsl("ayu_") + brokenKey;
auto val = json.value(brokenKey).toString().replace(qsl("&amp;"), qsl("&")).toUtf8();
const auto val = json.value(brokenKey).toString().replace(qsl("&amp;"), qsl("&")).toUtf8();
if (key.endsWith("_zero") || key.endsWith("_two") || key.endsWith("_few") || key.endsWith("_many")) {
continue;
}
if (key.endsWith("_one")) {
key = key.replace("_one", "#one");
} else if (key.endsWith("_other")) {
key = key.replace("_other", "#other");
}
Lang::GetInstance().resetValue(key.toUtf8());
Lang::GetInstance().applyValue(key.toUtf8(), val);
if (key.contains("#other")) {
Lang::GetInstance().resetValue(key.toUtf8().replace("#other", "#few"));
Lang::GetInstance().resetValue(key.toUtf8().replace("#other", "#few"));
Lang::GetInstance().applyValue(key.toUtf8().replace("#other", "#few"), val);
Lang::GetInstance().applyValue(key.toUtf8().replace("#other", "#many"), val);
}
}
Lang::GetInstance().updatePluralRules();
}

View file

@ -9,27 +9,26 @@
#include <QtNetwork/QNetworkReply>
#include <QtXml/QDomDocument>
class CustomLangPack : public QObject
class AyuLanguage : public QObject
{
Q_OBJECT
Q_DISABLE_COPY(CustomLangPack)
Q_DISABLE_COPY(AyuLanguage)
public:
static CustomLangPack *currentInstance();
static void initInstance();
static CustomLangPack *instance;
static AyuLanguage *currentInstance();
static void init();
static AyuLanguage *instance;
void fetchCustomLangPack(const QString &langPackId, const QString &langPackBaseId);
void loadDefaultLangFile();
void parseLangFile(QJsonDocument str);
void fetchLanguage(const QString &id, const QString &baseId);
void applyLanguageJson(QJsonDocument doc);
public Q_SLOTS:
void fetchFinished();
void fetchError(QNetworkReply::NetworkError e);
private:
CustomLangPack();
~CustomLangPack() override = default;
AyuLanguage();
~AyuLanguage() override = default;
QNetworkAccessManager networkManager;
QNetworkReply *_chkReply = nullptr;

View file

@ -105,6 +105,7 @@ auto storage = make_storage(
make_column("id", &RegexFilter::id),
make_column("text", &RegexFilter::text),
make_column("enabled", &RegexFilter::enabled),
make_column("reversed", &RegexFilter::reversed),
make_column("caseInsensitive", &RegexFilter::caseInsensitive),
make_column("dialogId", &RegexFilter::dialogId)
),

View file

@ -78,6 +78,7 @@ public:
std::vector<char> id;
std::string text;
bool enabled;
bool reversed;
bool caseInsensitive;
std::unique_ptr<ID> dialogId; // nullable
};

View file

@ -86,7 +86,7 @@ void map(not_null<HistoryItem*> item, AyuMessageBase &message) {
// message.mimeType
}
void addEditedMessage(HistoryMessageEdition &edition, not_null<HistoryItem*> item) {
void addEditedMessage(not_null<HistoryItem *> item) {
EditedMessage message;
map(item, message);

View file

@ -12,7 +12,7 @@
namespace AyuMessages {
void addEditedMessage(HistoryMessageEdition &edition, not_null<HistoryItem*> item);
void addEditedMessage(not_null<HistoryItem *> item);
std::vector<AyuMessageBase> getEditedMessages(not_null<HistoryItem*> item, ID minId, ID maxId, int totalLimit);
bool hasRevisions(not_null<HistoryItem*> item);

View file

@ -2378,7 +2378,7 @@ void Session::updateEditedMessage(const MTPMessage &data) {
goto proceed;
}
AyuMessages::addEditedMessage(edit, existing);
AyuMessages::addEditedMessage(existing);
}
proceed: