1
0
mirror of synced 2025-01-31 04:13:50 +01:00

Add translation framework and example data

This commit is contained in:
asesidaa 2024-01-22 01:13:13 +08:00
parent 238752a5b3
commit 81b065c358
15 changed files with 269 additions and 6 deletions

View File

@ -134,6 +134,24 @@
<Content Update="wwwroot\data\datatable\wordlist.bin">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\data\datatable-bak\don_cos_reward.bin">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\data\datatable-bak\musicinfo.bin">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\data\datatable-bak\music_order.bin">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\data\datatable-bak\neiro.bin">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\data\datatable-bak\shougou.bin">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Update="wwwroot\data\datatable-bak\wordlist.bin">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>

View File

@ -0,0 +1,62 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace TaikoWebUI.Localization {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class LocalizationResource {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal LocalizationResource() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("TaikoWebUI.Localization.LocalizationResource", typeof(LocalizationResource).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}

View File

@ -0,0 +1,23 @@
<root>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="dashboard" xml:space="preserve">
<value>Dashboard</value>
</data>
<data name="users" xml:space="preserve">
<value>Users</value>
</data>
<data name="edit profile" xml:space="preserve">
<value>Edit Profile</value>
</data>
</root>

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,23 @@
<root>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="dashboard" xml:space="preserve">
<value>主页</value>
</data>
<data name="users" xml:space="preserve">
<value>用户管理</value>
</data>
<data name="edit profile" xml:space="preserve">
<value>编辑档案</value>
</data>
</root>

View File

@ -1,6 +1,6 @@
@page "/"
<h1>Dashboard</h1>
<h1>@Localizer["dashboard"]</h1>
<MudText Class="mt-8">
Welcome to TaikoWebUI!

View File

@ -5,7 +5,7 @@
@page "/Users"
<h1>Users</h1>
<h1>@Localizer["users"]</h1>
<MudGrid Class="my-8">
@if (response is null)
{
@ -94,7 +94,7 @@
<MudButton Href="@($"Users/{user.Baid}/Profile")"
Size="Size.Small" Variant="Variant.Text" StartIcon="@Icons.Material.Filled.Edit"
Color="Color.Primary">
Edit Profile
@Localizer["edit profile"]
</MudButton>
<MudMenu Size="Size.Small"
Dense="true"

View File

@ -1,4 +1,6 @@
using System.Globalization;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.JSInterop;
using MudBlazor.Services;
using TaikoWebUI.Settings;
@ -16,10 +18,30 @@ builder.Services.AddSingleton<IGameDataService, GameDataService>();
builder.Services.Configure<WebUiSettings>(builder.Configuration.GetSection(nameof(WebUiSettings)));
builder.Services.AddScoped<LoginService>();
builder.Services.AddLocalization();
builder.Services.AddSingleton<MudLocalizer, ResXMudLocalizer>();
var host = builder.Build();
var gameDataService = host.Services.GetRequiredService<IGameDataService>();
await gameDataService.InitializeAsync(builder.HostEnvironment.BaseAddress);
CultureInfo culture;
var js = host.Services.GetRequiredService<IJSRuntime>();
var result = await js.InvokeAsync<string?>("blazorCulture.get");
if (result is not null)
{
culture = new CultureInfo(result);
}
else
{
culture = new CultureInfo("en-US");
await js.InvokeVoidAsync("blazorCulture.set", "en-US");
}
CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;
await host.RunAsync();

View File

@ -0,0 +1,17 @@
using TaikoWebUI.Localization;
using Microsoft.Extensions.Localization;
using MudBlazor;
namespace TaikoWebUI;
internal class ResXMudLocalizer : MudLocalizer
{
private IStringLocalizer localization;
public ResXMudLocalizer(IStringLocalizer<LocalizationResource> localizer)
{
localization = localizer;
}
public override LocalizedString this[string key] => localization[key];
}

View File

@ -0,0 +1,35 @@
@using System.Globalization;
@inject NavigationManager NavigationManager
@inject IJSRuntime JSRuntime
<MudMenu Icon="@Icons.Material.Filled.Language" Color="Color.Inherit">
@foreach (var culture in SupportedCultures)
{
<MudMenuItem OnClick="() => RequestCultureChange(culture.Key)">@culture.Value</MudMenuItem>
}
</MudMenu>
@code{
public readonly Dictionary<CultureInfo, string> SupportedCultures = new()
{
{ new CultureInfo("en-US"), "English" },
{ new CultureInfo("zh-Hans"), "简体中文" },
// TODO: Add JP localization?
//{ new CultureInfo("ja"), "日本語" },
};
private void RequestCultureChange(CultureInfo newCulture)
{
if (Equals(CultureInfo.CurrentCulture, newCulture))
{
return;
}
var js = (IJSInProcessRuntime)JSRuntime;
js.InvokeVoid("blazorCulture.set", newCulture.Name);
NavigationManager.NavigateTo(NavigationManager.Uri, forceLoad: true);
}
}

View File

@ -7,6 +7,8 @@
<MudLayout>
<MudAppBar Elevation="0">
<MudIconButton Icon="@Icons.Material.Filled.Menu" Color="Color.Inherit" Edge="Edge.Start" OnClick="@((e) => DrawerToggle())"/>
<MudSpacer/>
<ChooseLanguage/>
</MudAppBar>
<MudDrawer @bind-Open="_drawerOpen" Elevation="1">
<MudDrawerHeader>

View File

@ -1,4 +1,4 @@
<MudNavMenu>
<MudNavLink Href="/" Match="NavLinkMatch.All" Icon="@Icons.Material.Filled.Dashboard">Dashboard</MudNavLink>
<MudNavLink Href="/Users" Match="NavLinkMatch.Prefix" Icon="@Icons.Material.Filled.CreditCard">Users</MudNavLink>
<MudNavLink Href="/" Match="NavLinkMatch.All" Icon="@Icons.Material.Filled.Dashboard">@Localizer["dashboard"]</MudNavLink>
<MudNavLink Href="/Users" Match="NavLinkMatch.Prefix" Icon="@Icons.Material.Filled.CreditCard">@Localizer["users"]</MudNavLink>
</MudNavMenu>

View File

@ -7,6 +7,8 @@
<LangVersion>11</LangVersion>
<WasmEnableSIMD>false</WasmEnableSIMD>
<WasmEnableExceptionHandling>false</WasmEnableExceptionHandling>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
<InvariantGlobalization>false</InvariantGlobalization>
</PropertyGroup>
<ItemGroup>
@ -14,6 +16,8 @@
<PackageReference Include="CodeBeam.MudBlazor.Extensions" Version="6.5.10" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.0-rc.1.23421.29" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.0-rc.1.23421.29" PrivateAssets="all" />
<PackageReference Include="Microsoft.Extensions.Localization" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="8.0.0-rc.1.23419.4" />
<PackageReference Include="MudBlazor" Version="6.10.0" />
<PackageReference Include="SharpZipLib" Version="1.4.2" />
@ -63,5 +67,31 @@
<_ContentIncludedByDefault Remove="Pages\Pages\Users.razor" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Localization\LocalizationResource.en-US.resx">
<SubType>Designer</SubType>
<Generator>ResXFileCodeGenerator</Generator>
<CustomToolNamespace>LocalizationResource</CustomToolNamespace>
</EmbeddedResource>
<EmbeddedResource Update="Localization\LocalizationResource.zh-Hans.resx">
<SubType>Designer</SubType>
<Generator>ResXFileCodeGenerator</Generator>
<CustomToolNamespace>LocalizationResource</CustomToolNamespace>
</EmbeddedResource>
<EmbeddedResource Update="Localization\LocalizationResource.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>LocalizationResource.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<Compile Update="Localization\LocalizationResource.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>LocalizationResource.resx</DependentUpon>
</Compile>
</ItemGroup>
</Project>

View File

@ -14,4 +14,8 @@
@using SharedProject.Models
@using SharedProject.Models.Requests
@using SharedProject.Enums
@using Throw
@using Throw
@using Localization
@using System.Globalization
@using Microsoft.Extensions.Localization
@inject IStringLocalizer<LocalizationResource> Localizer

View File

@ -31,6 +31,12 @@
<script src="_content/MudBlazor/MudBlazor.min.js"></script>
<script src="js/textFit.min.js"></script>
<script src="js/updateTextFit.js"></script>
<script>
window.blazorCulture = {
get: () => localStorage['BlazorCulture'],
set: (value) => localStorage['BlazorCulture'] = value
};
</script>
</body>
</html>