M image/assets/lang/Deutsch.json => image/assets/lang/Deutsch.json +4 -1
@@ 1,4 1,7 @@
{
+ "metadata": {
+ "display_name": "Deutsch"
+ },
"common_add": "HINZUFÜGEN",
"common_open": "ÖFFNEN",
"common_call": "ANRUFEN",
@@ 675,4 678,4 @@
"app_bell_meditation_interval_every_x_minutes": "jede %0 Minuten",
"app_bell_meditation_put_down_and_wait": "<text>Legen Sie Mudita Harmony<br>ab und warten Sie auf den Gong</text>",
"app_bell_meditation_thank_you_for_session": "<text>Danke für<br>die Sitzung</text>"
-}>
\ No newline at end of file
+}
M image/assets/lang/English.json => image/assets/lang/English.json +3 -0
@@ 1,4 1,7 @@
{
+ "metadata": {
+ "display_name": "English"
+ },
"common_add": "ADD",
"common_open": "OPEN",
"common_call": "CALL",
R image/assets/lang/Español.json => image/assets/lang/Espanol.json +4 -1
@@ 1,4 1,7 @@
{
+ "metadata": {
+ "display_name": "Español"
+ },
"common_add": "AÑADIR",
"common_open": "ABRIR",
"common_call": "LLAMAR",
@@ 675,4 678,4 @@
"app_bell_meditation_interval_every_x_minutes": "cada %0 minutos",
"app_bell_meditation_put_down_and_wait": "<text>Posicione Mudita Harmony<br>y espere el gong</text>",
"app_bell_meditation_thank_you_for_session": "<text>Gracias<br>por la sesión</text>"
-}>
\ No newline at end of file
+}
R image/assets/lang/Français.json => image/assets/lang/Francais.json +4 -1
@@ 1,4 1,7 @@
{
+ "metadata": {
+ "display_name": "Français"
+ },
"common_add": "AJOUTER",
"common_open": "OUVRIR",
"common_call": "APPELER",
@@ 645,4 648,4 @@
"app_bell_meditation_interval_every_x_minutes": "toutes les %0 minutes",
"app_bell_meditation_put_down_and_wait": "<text>Posez Mudita Harmony<br>et attendez le gong</text>",
"app_bell_meditation_thank_you_for_session": "<text>Merci<br>pour cette session</text>"
-}>
\ No newline at end of file
+}
M image/assets/lang/Polski.json => image/assets/lang/Polski.json +4 -1
@@ 1,4 1,7 @@
{
+ "metadata": {
+ "display_name": "Polski"
+ },
"common_add": "DODAJ",
"common_open": "OTWÓRZ",
"common_call": "ZADZWOŃ",
@@ 688,4 691,4 @@
"app_bell_meditation_interval_every_x_minutes": "co %0 minuty",
"app_bell_meditation_put_down_and_wait": "<text>Odłóż Mudita Harmony<br>i czekaj na gong</text>",
"app_bell_meditation_thank_you_for_session": "<text>Dziękujemy<br>za sesję</text>"
-}>
\ No newline at end of file
+}
M image/assets/lang/Svenska.json => image/assets/lang/Svenska.json +6 -2
@@ 1,4 1,7 @@
{
+ "metadata": {
+ "display_name": "Svenska"
+ },
"common_add": "LÄGG TILL",
"common_open": "ÖPPNA",
"common_call": "RING",
@@ 276,8 279,9 @@
"app_onboarding_skip_confirm": "<text> SIM-installation krävs för nätverksanslutning. Hoppar du ändå över installationen? </text>",
"app_onboarding_configuration_successful": "<text> Din Mudita Pure <br> </br> är klar att använda. </text>",
"app_onboarding_no_configuration": "<text> Din Mudita Pure har inte konfigurerats. </br> Du kan gå till <br> </br> Inställningar för att konfigurera den. </text>",
- "app_onboarding_update_info": "<text> Den nuvarande versionen av MuditaOS är <br> </br> <token> $ VERSION </token>. Uppdateringar med nya <br> </br> funktioner och korrigeringar visas ofta. <br> </br> För att uppdatera din telefon vänligen <br> </br> besök: </text> <text font = 'gt_pressura' weight = 'bold' size = '27 '> www.mudita.com/updateos </text > <br> </br> <text> och följ instruktionerna. </text> ", "app_settings_title_main": "Inställningar",
- "app_settings_advanced" : "Avancerad",
+ "app_onboarding_update_info": "<text> Den nuvarande versionen av MuditaOS är <br> </br> <token> $ VERSION </token>. Uppdateringar med nya <br> </br> funktioner och korrigeringar visas ofta. <br> </br> För att uppdatera din telefon vänligen <br> </br> besök: </text> <text font = 'gt_pressura' weight = 'bold' size = '27 '> www.mudita.com/updateos </text > <br> </br> <text> och följ instruktionerna. </text> ",
+ "app_settings_title_main": "Inställningar",
+ "app_settings_advanced": "Avancerad",
"app_settings_bt": "Bluetooth",
"app_settings_bluetooth_add_device": "Lägg till enhet",
"app_settings_bluetooth_all_devices": "Alla enheter",
M module-utils/i18n/i18n.cpp => module-utils/i18n/i18n.cpp +71 -34
@@ 4,8 4,11 @@
#include "i18nImpl.hpp"
#include <log/log.hpp>
#include <algorithm>
+#include <optional>
#include <cstdio>
#include <purefs/filesystem_paths.hpp>
+#include <i18n/i18n.hpp>
+#include <utility>
namespace utils
{
@@ 15,6 18,57 @@ namespace utils
{
return str.empty() ? ret : str;
}
+
+ std::optional<json11::Json> loadJSONData(const std::filesystem::path &path)
+ {
+ auto fd = std::fopen(path.c_str(), "r");
+ if (fd == nullptr) {
+ LOG_FATAL("Error during opening file %s", path.c_str());
+ return {};
+ }
+
+ const auto fsize = std::filesystem::file_size(path);
+
+ auto stream = std::make_unique<char[]>(fsize + 1); // +1 for NULL terminator
+
+ std::fread(stream.get(), 1, fsize, fd);
+
+ std::string err;
+ json11::Json js = json11::Json::parse(stream.get(), err);
+
+ std::fclose(fd);
+
+ // Error
+ if (err.length() != 0) {
+ LOG_FATAL("%s", err.c_str());
+ return {};
+ }
+ else {
+ return js;
+ }
+ }
+
+ struct LanguageMetadata
+ {
+ static std::optional<LanguageMetadata> get(const std::filesystem::path &path)
+ {
+ const auto contents = loadJSONData(path);
+ if (not contents) {
+ return {};
+ }
+ const auto contentsValue = *contents;
+ if (contentsValue[metadataKey].is_null() || contentsValue[metadataKey][metadataDisplayKey].is_null()) {
+ return {};
+ }
+
+ return LanguageMetadata{.displayName = contentsValue[metadataKey][metadataDisplayKey].string_value()};
+ }
+ const std::string displayName;
+
+ private:
+ static constexpr auto metadataKey = "metadata";
+ static constexpr auto metadataDisplayKey = "display_name";
+ };
} // namespace
namespace
@@ 65,42 119,22 @@ namespace utils
i18nPrivateInterface localize;
- json11::Json LangLoaderImpl::createJson(const std::string &filename)
- {
- const auto path = localize.getDisplayLanguagePath() / (filename + utils::files::jsonExtension);
- auto fd = std::fopen(path.c_str(), "r");
- if (fd == nullptr) {
- LOG_FATAL("Error during opening file %s", path.c_str());
- return json11::Json();
- }
-
- uint32_t fsize = std::filesystem::file_size(path);
-
- auto stream = std::make_unique<char[]>(fsize + 1); // +1 for NULL terminator
-
- std::fread(stream.get(), 1, fsize, fd);
-
- std::string err;
- json11::Json js = json11::Json::parse(stream.get(), err);
-
- std::fclose(fd);
-
- // Error
- if (err.length() != 0) {
- LOG_FATAL("%s", err.c_str());
- return json11::Json();
- }
- else {
- return js;
- }
- }
-
std::vector<Language> LangLoader::getAvailableDisplayLanguages() const
{
std::vector<std::string> languageNames;
for (const auto &entry : std::filesystem::directory_iterator(getDisplayLanguagePath())) {
- languageNames.push_back(std::filesystem::path(entry.path()).stem());
+ const auto metadata = LanguageMetadata::get(entry.path());
+ if (metadata) {
+ languageNames.push_back(metadata->displayName);
+ }
+ else {
+ /// If metadata is not valid use file name string as a display language
+ languageNames.push_back(std::filesystem::path(entry).stem());
+ }
}
+
+ std::sort(languageNames.begin(), languageNames.end());
+
return languageNames;
}
@@ 151,10 185,11 @@ namespace utils
return false;
}
- else if (json11::Json pack = loader.createJson(lang); pack != json11::Json()) {
+ else if (const auto pack =
+ loadJSONData(localize.getDisplayLanguagePath() / (lang + utils::files::jsonExtension))) {
currentDisplayLanguage = lang;
- changeDisplayLanguage(pack);
+ changeDisplayLanguage(pack.value());
return true;
}
@@ 171,7 206,9 @@ namespace utils
{
cpp_freertos::LockGuard lock(mutex);
currentDisplayLanguage = fallbackLanguageName;
- fallbackLanguage = loader.createJson(fallbackLanguageName);
+ fallbackLanguage =
+ loadJSONData(localize.getDisplayLanguagePath() / (fallbackLanguageName + utils::files::jsonExtension))
+ .value();
}
const std::string &translate(const std::string &text)
M module-utils/i18n/i18nImpl.hpp => module-utils/i18n/i18nImpl.hpp +0 -8
@@ 9,19 9,11 @@
namespace utils
{
-
- class LangLoaderImpl : public LangLoader
- {
- public:
- json11::Json createJson(const std::string &filename);
- };
-
class i18n
{
private:
json11::Json displayLanguage;
json11::Json fallbackLanguage; // backup language if item not found
- LangLoaderImpl loader;
Language fallbackLanguageName = getDefaultLanguage();
Language inputLanguage = fallbackLanguageName;
Language inputLanguageFilename;
M module-utils/i18n/include/i18n/i18n.hpp => module-utils/i18n/include/i18n/i18n.hpp +0 -1
@@ 20,7 20,6 @@ namespace utils
class LangLoader
{
public:
- virtual ~LangLoader() = default;
std::vector<Language> getAvailableDisplayLanguages() const;
std::vector<Language> getAvailableInputLanguages() const;
};
M products/BellHybrid/apps/application-bell-onboarding/presenter/OnBoardingLanguageWindowPresenter.cpp => products/BellHybrid/apps/application-bell-onboarding/presenter/OnBoardingLanguageWindowPresenter.cpp +1 -1
@@ 11,7 11,7 @@ namespace app::OnBoarding
std::vector<std::string> OnBoardingLanguageWindowPresenter::getLanguages()
{
- return languages.getSupportedLanguages();
+ return languages.getAvailableDisplayLanguages();
}
unsigned OnBoardingLanguageWindowPresenter::getSelectedLanguageIndex()
M products/BellHybrid/apps/application-bell-onboarding/presenter/OnBoardingLanguageWindowPresenter.hpp => products/BellHybrid/apps/application-bell-onboarding/presenter/OnBoardingLanguageWindowPresenter.hpp +1 -2
@@ 5,7 5,6 @@
#include <apps-common/BasePresenter.hpp>
#include <apps-common/ApplicationCommon.hpp>
-#include <common/Languages.hpp>
#include <vector>
#include <string>
@@ 33,7 32,7 @@ namespace app::OnBoarding
class OnBoardingLanguageWindowPresenter : public OnBoardingLanguageWindowContract::Presenter
{
private:
- common::Languages languages;
+ utils::LangLoader languages;
app::ApplicationCommon *app;
public:
M products/BellHybrid/apps/application-bell-settings/presenter/advanced/LanguageWindowPresenter.cpp => products/BellHybrid/apps/application-bell-settings/presenter/advanced/LanguageWindowPresenter.cpp +1 -1
@@ 11,7 11,7 @@ namespace app::bell_settings
std::vector<std::string> LanguageWindowPresenter::getLanguages() const
{
- return languages.getSupportedLanguages();
+ return languages.getAvailableDisplayLanguages();
}
std::string LanguageWindowPresenter::getSelectedLanguage() const
M products/BellHybrid/apps/application-bell-settings/presenter/advanced/LanguageWindowPresenter.hpp => products/BellHybrid/apps/application-bell-settings/presenter/advanced/LanguageWindowPresenter.hpp +1 -2
@@ 5,7 5,6 @@
#include <apps-common/BasePresenter.hpp>
#include <apps-common/ApplicationCommon.hpp>
-#include <common/Languages.hpp>
#include <vector>
#include <string>
@@ 33,7 32,7 @@ namespace app::bell_settings
class LanguageWindowPresenter : public LanguageWindowContract::Presenter
{
private:
- common::Languages languages;
+ utils::LangLoader languages;
app::ApplicationCommon *app{};
public:
M products/BellHybrid/apps/common/CMakeLists.txt => products/BellHybrid/apps/common/CMakeLists.txt +0 -1
@@ 42,7 42,6 @@ target_sources(application-bell-common
src/options/OptionBellMenu.cpp
src/options/BellOptionsNavigation.cpp
PUBLIC
- include/common/Languages.hpp
include/common/BellListItemProvider.hpp
include/common/LanguageUtils.hpp
include/common/SoundsRepository.hpp
D products/BellHybrid/apps/common/include/common/Languages.hpp => products/BellHybrid/apps/common/include/common/Languages.hpp +0 -39
@@ 1,39 0,0 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
-// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-
-#pragma once
-
-#include <i18n/i18n.hpp>
-
-#include <algorithm>
-#include <vector>
-#include <array>
-#include <string_view>
-
-namespace common
-{
- class Languages
- {
- public:
- std::vector<Language> getSupportedLanguages() const
- {
- auto languages = loader.getAvailableDisplayLanguages();
- languages.erase(
- std::remove_if(languages.begin(), languages.end(), [this](const auto &lang) { return matcher(lang); }),
- languages.end());
- std::sort(languages.begin(), languages.end());
- return languages;
- }
-
- private:
- bool matcher(const std::string_view language) const
- {
- const auto result = std::find(excludedLanguages.begin(), excludedLanguages.end(), language);
- return result != excludedLanguages.end();
- }
-
- static constexpr std::array<std::string_view, 1> excludedLanguages = {{"Svenska"}};
- utils::LangLoader loader;
- };
-
-} // namespace common