129 lines
4.4 KiB
Plaintext
129 lines
4.4 KiB
Plaintext
@using Microsoft.AspNetCore.Components.Routing
|
|
@inject Atomx.Admin.Client.Services.ILocalizationProvider LocalizationProvider
|
|
@inject NavigationManager Navigation
|
|
|
|
<div @key="LocalizationProvider.CurrentCulture">
|
|
<Router AppAssembly="typeof(Program).Assembly">
|
|
<Found Context="routeData">
|
|
<CascadingValue Value="routeData">
|
|
<AuthorizeRouteView RouteData="routeData" DefaultLayout="typeof(Layout.MainLayout)">
|
|
<NotAuthorized>
|
|
<RedirectToLogin />
|
|
</NotAuthorized>
|
|
</AuthorizeRouteView>
|
|
</CascadingValue>
|
|
<FocusOnNavigate RouteData="routeData" Selector="h1" />
|
|
</Found>
|
|
</Router>
|
|
</div>
|
|
<AntContainer />
|
|
|
|
@code {
|
|
private bool _initialized;
|
|
|
|
protected override async Task OnInitializedAsync()
|
|
{
|
|
// Subscribe to language changes to remount router when needed
|
|
if (LocalizationProvider != null)
|
|
{
|
|
LocalizationProvider.LanguageChanged += OnLanguageChanged;
|
|
}
|
|
|
|
// Subscribe to navigation events so client-side nav to /zh/... or /en/... triggers culture change
|
|
Navigation.LocationChanged += OnLocationChanged;
|
|
|
|
// Try detect first URL segment as short culture (e.g. /zh/ or /en/) and set culture before first render
|
|
try
|
|
{
|
|
var relative = Navigation.ToBaseRelativePath(Navigation.Uri).Trim('/');
|
|
var segments = string.IsNullOrEmpty(relative) ? Array.Empty<string>() : relative.Split('/', StringSplitOptions.RemoveEmptyEntries);
|
|
var first = segments.FirstOrDefault();
|
|
var mapping = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
|
|
{
|
|
{ "zh", "zh-Hans" },
|
|
{ "en", "en-US" }
|
|
};
|
|
|
|
if (!string.IsNullOrEmpty(first) && mapping.TryGetValue(first, out var mapped))
|
|
{
|
|
try
|
|
{
|
|
if (OperatingSystem.IsBrowser())
|
|
{
|
|
await LocalizationProvider.SetCultureAsync(mapped);
|
|
}
|
|
else
|
|
{
|
|
if (LocalizationProvider is Atomx.Admin.Client.Services.LocalizationProvider concrete)
|
|
{
|
|
concrete.SetCultureForServer(mapped);
|
|
}
|
|
}
|
|
}
|
|
catch { }
|
|
}
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
private async void OnLocationChanged(object? sender, LocationChangedEventArgs args)
|
|
{
|
|
try
|
|
{
|
|
var relative = Navigation.ToBaseRelativePath(args.Location).Trim('/');
|
|
var segments = string.IsNullOrEmpty(relative) ? Array.Empty<string>() : relative.Split('/', StringSplitOptions.RemoveEmptyEntries);
|
|
var first = segments.FirstOrDefault();
|
|
if (string.IsNullOrEmpty(first)) return;
|
|
|
|
var mapping = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
|
|
{
|
|
{ "zh", "zh-Hans" },
|
|
{ "en", "en-US" }
|
|
};
|
|
|
|
if (mapping.TryGetValue(first, out var mapped))
|
|
{
|
|
// if culture already set to same, skip
|
|
if (string.Equals(LocalizationProvider.CurrentCulture, mapped, StringComparison.OrdinalIgnoreCase)) return;
|
|
|
|
// Call async set; ignore errors
|
|
await LocalizationProvider.SetCultureAsync(mapped);
|
|
|
|
// Trigger router remount via StateHasChanged
|
|
_ = InvokeAsync(StateHasChanged);
|
|
}
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
|
{
|
|
if (firstRender && !_initialized)
|
|
{
|
|
_initialized = true;
|
|
try
|
|
{
|
|
if (LocalizationProvider != null)
|
|
{
|
|
await LocalizationProvider.InitializeAsync();
|
|
}
|
|
}
|
|
catch { }
|
|
}
|
|
}
|
|
|
|
private void OnLanguageChanged(object? s, string culture)
|
|
{
|
|
// Remount router via @key by triggering StateHasChanged
|
|
_ = InvokeAsync(StateHasChanged);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
if (LocalizationProvider != null)
|
|
{
|
|
LocalizationProvider.LanguageChanged -= OnLanguageChanged;
|
|
}
|
|
Navigation.LocationChanged -= OnLocationChanged;
|
|
}
|
|
} |