using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Xml; using Xamarin.Forms; using Xamarin.Forms.Xaml; namespace Gallery.Resources { public class ResourceHelper { public static string Title => GetResource(nameof(Title)); public static string Guest => GetResource(nameof(Guest)); public static string Ok => GetResource(nameof(Ok)); public static string Cancel => GetResource(nameof(Cancel)); public static string Yes => GetResource(nameof(Yes)); public static string No => GetResource(nameof(No)); public static string R18 => GetResource(nameof(R18)); public static string SyncNo => GetResource(nameof(SyncNo)); public static string SyncPrompt => GetResource(nameof(SyncPrompt)); public static string SyncAuto => GetResource(nameof(SyncAuto)); public static string Operation => GetResource(nameof(Operation)); public static string SaveOriginal => GetResource(nameof(SaveOriginal)); public static string Share => GetResource(nameof(Share)); public static string UserDetail => GetResource(nameof(UserDetail)); public static string RelatedIllusts => GetResource(nameof(RelatedIllusts)); public static string SaveSuccess => GetResource(nameof(SaveSuccess)); public static string AlreadySavedQuestion => GetResource(nameof(AlreadySavedQuestion)); public static string InvalidUrl => GetResource(nameof(InvalidUrl)); public static string Favorites => GetResource(nameof(Favorites)); public static string FavoritesOperation => GetResource(nameof(FavoritesOperation)); public static string FavoritesReplace => GetResource(nameof(FavoritesReplace)); public static string FavoritesCombine => GetResource(nameof(FavoritesCombine)); public static string ExportVideo => GetResource(nameof(ExportVideo)); public static string CantExportVideo => GetResource(nameof(CantExportVideo)); public static string AlreadySavedVideo => GetResource(nameof(AlreadySavedVideo)); public static string ExportSuccess => GetResource(nameof(ExportSuccess)); public static string FailedResponse => GetResource(nameof(FailedResponse)); public static string ConfirmSyncFavorite => GetResource(nameof(ConfirmSyncFavorite)); public static string ConfirmLogin => GetResource(nameof(ConfirmLogin)); static readonly Dictionary dict = new Dictionary(); 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 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 { #if __IOS__ var langId = $"Gallery.iOS.Resources.Languages.{lang.Language}.xml"; var langCodeId = $"Gallery.iOS.Resources.Languages.{lang.LanguageCode}.xml"; #elif __ANDROID__ var langId = $"Gallery.Droid.Resources.Languages.{lang.Language}.xml"; var langCodeId = $"Gallery.Droid.Resources.Languages.{lang.LanguageCode}.xml"; #endif 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) { #if __IOS__ name = "Gallery.iOS.Resources.Languages.zh-CN.xml"; #elif __ANDROID__ name = "Gallery.Droid.Resources.Languages.zh-CN.xml"; #endif } var xml = new XmlDocument(); using (var stream = assembly.GetManifestResourceStream(name)) { xml.Load(stream); } strings = new Dictionary(); foreach (XmlElement ele in xml.DocumentElement) // .Root.Elements() { strings[ele.Name] = ele.InnerText; // .LocalName Value } } catch (Exception ex) { // load failed App.DebugError("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 ResourceHelper.GetResource(Text); } } }