2021-08-10 17:17:32 +08:00

103 lines
3.4 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Xml;
using Gallery.Util;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace Gallery.Resources
{
public class Helper
{
private static readonly Dictionary<string, LanguageResource> dict = new();
public static string GetResource(string name, params object[] args)
{
if (!dict.TryGetValue(App.CurrentCulture.PlatformString, out LanguageResource lang))
{
lang = new LanguageResource(App.CurrentCulture);
dict.Add(App.CurrentCulture.PlatformString, lang);
}
if (args == null || args.Length == 0)
{
return lang[name];
}
return string.Format(lang[name], args);
}
private class LanguageResource
{
private readonly Dictionary<string, string> strings;
public string this[string key]
{
get
{
if (strings != null && strings.TryGetValue(key, out string val))
{
return val;
}
return key;
}
}
public LanguageResource(PlatformCulture lang)
{
try
{
const string PROJECT = "Gallery";
const string PLATFORM =
#if __IOS__
"iOS";
#elif __ANDROID__
"Droid";
#endif
var langId = $"{PROJECT}.{PLATFORM}.Resources.Languages.{lang.Language}.xml";
var langCodeId = $"{PROJECT}.{PLATFORM}.Resources.Languages.{lang.LanguageCode}.xml";
var assembly = IntrospectionExtensions.GetTypeInfo(typeof(LanguageResource)).Assembly;
var names = assembly.GetManifestResourceNames();
var name = names.FirstOrDefault(n =>
string.Equals(n, langId, StringComparison.OrdinalIgnoreCase) ||
string.Equals(n, langCodeId, StringComparison.OrdinalIgnoreCase));
if (name == null)
{
name = $"{PROJECT}.{PLATFORM}.Resources.Languages.zh-CN.xml";
}
var xml = new XmlDocument();
using (var stream = assembly.GetManifestResourceStream(name))
{
xml.Load(stream);
}
strings = new Dictionary<string, string>();
foreach (XmlElement ele in xml.DocumentElement)
{
strings[ele.Name] = ele.InnerText;
}
}
catch (Exception ex)
{
// load failed
Log.Error("language.ctor", $"failed to load xml resource: {ex.Message}");
}
}
}
}
[ContentProperty(nameof(Text))]
public class TextExtension : IMarkupExtension
{
public string Text { get; set; }
public object ProvideValue(IServiceProvider serviceProvider)
{
if (Text == null)
{
return string.Empty;
}
return Helper.GetResource(Text);
}
}
}