Ryujinx/Ryujinx.Ava/Common/Locale/LocaleManager.cs
Andrey Sukharev 4ce4299ca2
Use source generated json serializers in order to improve code trimming (#4094)
* Use source generated json serializers in order to improve code trimming

* Use strongly typed github releases model to fetch updates instead of raw Newtonsoft.Json parsing

* Use separate model for LogEventArgs serialization

* Make dynamic object formatter static. Fix string builder pooling.

* Do not inherit json version of LogEventArgs from EventArgs

* Fix extra space in object formatting

* Write log json directly to stream instead of using buffer writer

* Rebase fixes

* Rebase fixes

* Rebase fixes

* Enforce block-scoped namespaces in the solution. Convert style for existing code

* Apply suggestions from code review

Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>

* Rebase indent fix

* Fix indent

* Delete unnecessary json properties

* Rebase fix

* Remove overridden json property names as they are handled in the options

* Apply suggestions from code review

Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>

* Use default json options in github api calls

* Indentation and spacing fixes

---------

Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>
2023-03-21 19:41:19 -03:00

146 lines
5 KiB
C#

using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Common;
using Ryujinx.Common.Utilities;
using Ryujinx.Ui.Common.Configuration;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Globalization;
namespace Ryujinx.Ava.Common.Locale
{
class LocaleManager : BaseModel
{
private const string DefaultLanguageCode = "en_US";
private Dictionary<LocaleKeys, string> _localeStrings;
private Dictionary<LocaleKeys, string> _localeDefaultStrings;
private readonly ConcurrentDictionary<LocaleKeys, object[]> _dynamicValues;
public static LocaleManager Instance { get; } = new LocaleManager();
public LocaleManager()
{
_localeStrings = new Dictionary<LocaleKeys, string>();
_localeDefaultStrings = new Dictionary<LocaleKeys, string>();
_dynamicValues = new ConcurrentDictionary<LocaleKeys, object[]>();
Load();
}
public void Load()
{
// Load the system Language Code.
string localeLanguageCode = CultureInfo.CurrentCulture.Name.Replace('-', '_');
// If the view is loaded with the UI Previewer detached, then override it with the saved one or default.
if (Program.PreviewerDetached)
{
if (!string.IsNullOrEmpty(ConfigurationState.Instance.Ui.LanguageCode.Value))
{
localeLanguageCode = ConfigurationState.Instance.Ui.LanguageCode.Value;
}
else
{
localeLanguageCode = DefaultLanguageCode;
}
}
// Load en_US as default, if the target language translation is incomplete.
LoadDefaultLanguage();
LoadLanguage(localeLanguageCode);
}
public string this[LocaleKeys key]
{
get
{
// Check if the locale contains the key.
if (_localeStrings.TryGetValue(key, out string value))
{
// Check if the localized string needs to be formatted.
if (_dynamicValues.TryGetValue(key, out var dynamicValue))
{
try
{
return string.Format(value, dynamicValue);
}
catch (Exception)
{
// If formatting failed use the default text instead.
if (_localeDefaultStrings.TryGetValue(key, out value))
{
try
{
return string.Format(value, dynamicValue);
}
catch (Exception)
{
// If formatting the default text failed return the key.
return key.ToString();
}
}
}
}
return value;
}
// If the locale doesn't contain the key return the default one.
if (_localeDefaultStrings.TryGetValue(key, out string defaultValue))
{
return defaultValue;
}
// If the locale text doesn't exist return the key.
return key.ToString();
}
set
{
_localeStrings[key] = value;
OnPropertyChanged();
}
}
public string UpdateAndGetDynamicValue(LocaleKeys key, params object[] values)
{
_dynamicValues[key] = values;
OnPropertyChanged("Item");
return this[key];
}
private void LoadDefaultLanguage()
{
_localeDefaultStrings = LoadJsonLanguage();
}
public void LoadLanguage(string languageCode)
{
foreach (var item in LoadJsonLanguage(languageCode))
{
this[item.Key] = item.Value;
}
}
private Dictionary<LocaleKeys, string> LoadJsonLanguage(string languageCode = DefaultLanguageCode)
{
var localeStrings = new Dictionary<LocaleKeys, string>();
string languageJson = EmbeddedResources.ReadAllText($"Ryujinx.Ava/Assets/Locales/{languageCode}.json");
var strings = JsonHelper.Deserialize(languageJson, CommonJsonContext.Default.StringDictionary);
foreach (var item in strings)
{
if (Enum.TryParse<LocaleKeys>(item.Key, out var key))
{
localeStrings[key] = item.Value;
}
}
return localeStrings;
}
}
}