feat: Set up initial WebClientTpos .NET project structure, including client, server, assets, and documentation.
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
using System.Globalization;
|
||||
using System.Net.Http.Json;
|
||||
using Microsoft.Extensions.Localization;
|
||||
|
||||
namespace WebClientTpos.Client.Localization;
|
||||
|
||||
public class JsonStringLocalizer : IStringLocalizer
|
||||
{
|
||||
private readonly LocalizationCache _cache;
|
||||
private readonly string _resourceName;
|
||||
|
||||
public JsonStringLocalizer(LocalizationCache cache, string resourceName)
|
||||
{
|
||||
_cache = cache;
|
||||
_resourceName = resourceName;
|
||||
}
|
||||
|
||||
// This constructor style is used by the Factory (if we update factory)
|
||||
public JsonStringLocalizer(LocalizationCache cache)
|
||||
{
|
||||
_cache = cache;
|
||||
_resourceName = "Shared";
|
||||
}
|
||||
|
||||
public LocalizedString this[string name]
|
||||
{
|
||||
get
|
||||
{
|
||||
var value = GetString(name);
|
||||
return new LocalizedString(name, value ?? name, resourceNotFound: value == null);
|
||||
}
|
||||
}
|
||||
|
||||
public LocalizedString this[string name, params object[] arguments]
|
||||
{
|
||||
get
|
||||
{
|
||||
var format = GetString(name);
|
||||
var value = string.Format(format ?? name, arguments);
|
||||
return new LocalizedString(name, value, resourceNotFound: format == null);
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<LocalizedString> GetAllStrings(bool includeParentCultures)
|
||||
{
|
||||
// Not fully supported by simple cache
|
||||
return Enumerable.Empty<LocalizedString>();
|
||||
}
|
||||
|
||||
private string? GetString(string name)
|
||||
{
|
||||
return _cache.GetString(name);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using Microsoft.Extensions.Localization;
|
||||
|
||||
namespace WebClientTpos.Client.Localization;
|
||||
|
||||
public class JsonStringLocalizerFactory : IStringLocalizerFactory
|
||||
{
|
||||
private readonly LocalizationCache _cache;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
|
||||
public JsonStringLocalizerFactory(LocalizationCache cache, IServiceProvider serviceProvider)
|
||||
{
|
||||
_cache = cache;
|
||||
_serviceProvider = serviceProvider;
|
||||
}
|
||||
|
||||
public IStringLocalizer Create(Type resourceSource)
|
||||
{
|
||||
return new JsonStringLocalizer(_cache, resourceSource.Name);
|
||||
}
|
||||
|
||||
public IStringLocalizer Create(string baseName, string location)
|
||||
{
|
||||
return new JsonStringLocalizer(_cache, baseName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
using System.Globalization;
|
||||
using System.Net.Http.Json;
|
||||
|
||||
namespace WebClientTpos.Client.Localization;
|
||||
|
||||
public class LocalizationCache
|
||||
{
|
||||
private readonly HttpClient _httpClient;
|
||||
private Dictionary<string, string> _strings = new();
|
||||
private bool _isLoaded;
|
||||
|
||||
public LocalizationCache(HttpClient httpClient)
|
||||
{
|
||||
_httpClient = httpClient;
|
||||
}
|
||||
|
||||
public string? GetString(string key)
|
||||
{
|
||||
if (_strings.TryGetValue(key, out var value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public async Task LoadAsync(CultureInfo culture)
|
||||
{
|
||||
if (_isLoaded) return; // Or check if culture changed
|
||||
|
||||
try
|
||||
{
|
||||
var cultureName = culture.Name;
|
||||
// Map generic "vi" to "vi-VN" if needed, but for now we trust the culture name matches file
|
||||
// Fallback for simple "vi" -> "vi-VN"
|
||||
if (cultureName == "vi") cultureName = "vi-VN";
|
||||
if (cultureName == "en") cultureName = "en-US";
|
||||
|
||||
var loaded = await _httpClient.GetFromJsonAsync<Dictionary<string, string>>($"/locales/{cultureName}.json?v={DateTime.Now.Ticks}");
|
||||
if (loaded != null)
|
||||
{
|
||||
_strings = loaded;
|
||||
_isLoaded = true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Error loading localization for {culture.Name}: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user