From 418c9888c46547b2d4a65c0e9bec39650463fce2 Mon Sep 17 00:00:00 2001 From: hishamco Date: Wed, 2 Dec 2020 01:38:00 +0300 Subject: [PATCH 01/14] Add LocalizationController --- .../Controllers/LocalizationController.cs | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 Oqtane.Server/Controllers/LocalizationController.cs diff --git a/Oqtane.Server/Controllers/LocalizationController.cs b/Oqtane.Server/Controllers/LocalizationController.cs new file mode 100644 index 00000000..f8b7433a --- /dev/null +++ b/Oqtane.Server/Controllers/LocalizationController.cs @@ -0,0 +1,26 @@ +using System.Collections.Generic; +using Microsoft.AspNetCore.Mvc; +using Oqtane.Infrastructure; +using Oqtane.Shared; + +namespace Oqtane.Controllers +{ + [Route(ControllerRoutes.Default)] + public class LocalizationController : Controller + { + private readonly ILocalizationManager _localizationManager; + + public LocalizationController(ILocalizationManager localizationManager) + { + _localizationManager = localizationManager; + } + + // GET: api/localization/getSupportedCultures + [HttpGet("getSupportedCultures")] + public IEnumerable GetSupportedCultures() => _localizationManager.GetSupportedCultures(); + + // GET api/localization/getDefaultCulture + [HttpGet("getDefaultCulture")] + public string GetDefaultCulture() => _localizationManager.GetDefaultCulture(); + } +} From c67e893b6ea8cb5da6917cfed99988737d6d1412 Mon Sep 17 00:00:00 2001 From: hishamco Date: Wed, 2 Dec 2020 01:38:32 +0300 Subject: [PATCH 02/14] Add LocalizationService APIs --- .../Interfaces/ILocalizationService.cs | 11 ++++++++++ Oqtane.Client/Services/LocalizationService.cs | 22 +++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 Oqtane.Client/Services/Interfaces/ILocalizationService.cs create mode 100644 Oqtane.Client/Services/LocalizationService.cs diff --git a/Oqtane.Client/Services/Interfaces/ILocalizationService.cs b/Oqtane.Client/Services/Interfaces/ILocalizationService.cs new file mode 100644 index 00000000..c025ee45 --- /dev/null +++ b/Oqtane.Client/Services/Interfaces/ILocalizationService.cs @@ -0,0 +1,11 @@ +using System.Threading.Tasks; + +namespace Oqtane.Services +{ + public interface ILocalizationService + { + Task GetDefaultCulture(); + + Task GetSupportedCultures(); + } +} diff --git a/Oqtane.Client/Services/LocalizationService.cs b/Oqtane.Client/Services/LocalizationService.cs new file mode 100644 index 00000000..4c658c50 --- /dev/null +++ b/Oqtane.Client/Services/LocalizationService.cs @@ -0,0 +1,22 @@ +using System.Net.Http; +using System.Threading.Tasks; +using Oqtane.Shared; + +namespace Oqtane.Services +{ + public class LocalizationService : ServiceBase, ILocalizationService + { + private readonly SiteState _siteState; + + public LocalizationService(HttpClient http, SiteState siteState) : base(http) + { + _siteState = siteState; + } + + private string Apiurl => CreateApiUrl(_siteState.Alias, "Localization"); + + public async Task GetDefaultCulture() => await GetJsonAsync($"{Apiurl}/getDefaultCulture"); + + public async Task GetSupportedCultures() => await GetJsonAsync($"{Apiurl}/getSupportedCultures"); + } +} From c4d1b16abb16f713a950d37325e4d14bcc68edd1 Mon Sep 17 00:00:00 2001 From: hishamco Date: Wed, 2 Dec 2020 01:52:46 +0300 Subject: [PATCH 03/14] Add LanguageSwitcher component --- Oqtane.Client/Program.cs | 5 ++-- .../Themes/Controls/ControlPanel.razor | 2 ++ .../Themes/Controls/LanguageSwitcher.razor | 30 +++++++++++++++++++ Oqtane.Server/Pages/_Host.cshtml | 6 ++++ Oqtane.Server/Startup.cs | 1 + 5 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 Oqtane.Client/Themes/Controls/LanguageSwitcher.razor diff --git a/Oqtane.Client/Program.cs b/Oqtane.Client/Program.cs index af283cec..7fdfa6bd 100644 --- a/Oqtane.Client/Program.cs +++ b/Oqtane.Client/Program.cs @@ -5,15 +5,15 @@ using System.IO.Compression; using System.Linq; using System.Net.Http; using System.Reflection; -using System.Threading.Tasks; using System.Runtime.Loader; +using System.Threading.Tasks; using Microsoft.AspNetCore.Components.Authorization; using Microsoft.AspNetCore.Components.WebAssembly.Hosting; using Microsoft.Extensions.DependencyInjection; using Oqtane.Modules; using Oqtane.Providers; -using Oqtane.Shared; using Oqtane.Services; +using Oqtane.Shared; namespace Oqtane.Client { @@ -62,6 +62,7 @@ namespace Oqtane.Client builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); + builder.Services.AddScoped(); await LoadClientAssemblies(httpClient); diff --git a/Oqtane.Client/Themes/Controls/ControlPanel.razor b/Oqtane.Client/Themes/Controls/ControlPanel.razor index 02ae862c..0ea20a8a 100644 --- a/Oqtane.Client/Themes/Controls/ControlPanel.razor +++ b/Oqtane.Client/Themes/Controls/ControlPanel.razor @@ -198,6 +198,8 @@ } + + @if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions) || (PageState.Page.IsPersonalizable && PageState.User != null)) { if (PageState.EditMode) diff --git a/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor b/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor new file mode 100644 index 00000000..3b630a7a --- /dev/null +++ b/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor @@ -0,0 +1,30 @@ +@namespace Oqtane.Themes.Controls +@inherits ThemeControlBase +@using System.Globalization +@inject ILocalizationService LocalizationService + +@if (_supportedCultures != null) +{ +
+ + +
+} + +@code{ + private string _selectedCulture; + private string[] _supportedCultures; + + protected override async Task OnParametersSetAsync() + { + _selectedCulture = await JSRuntime.InvokeAsync("oqtaneCulture.get"); + _supportedCultures = await LocalizationService.GetSupportedCultures(); + } +} diff --git a/Oqtane.Server/Pages/_Host.cshtml b/Oqtane.Server/Pages/_Host.cshtml index 2aa0dd9d..92dea6bc 100644 --- a/Oqtane.Server/Pages/_Host.cshtml +++ b/Oqtane.Server/Pages/_Host.cshtml @@ -48,6 +48,12 @@ @if (Configuration.GetSection("Runtime").Value == "WebAssembly") { + } else { diff --git a/Oqtane.Server/Startup.cs b/Oqtane.Server/Startup.cs index b008ee30..b134a19e 100644 --- a/Oqtane.Server/Startup.cs +++ b/Oqtane.Server/Startup.cs @@ -127,6 +127,7 @@ namespace Oqtane services.AddScoped(); services.AddScoped(); services.AddScoped(); + services.AddScoped(); services.AddSingleton(); From 75556070d6138e65e3982de1a5a36f8ef0954a96 Mon Sep 17 00:00:00 2001 From: hishamco Date: Wed, 2 Dec 2020 02:04:34 +0300 Subject: [PATCH 04/14] Ability to change culture --- Oqtane.Client/Oqtane.Client.csproj | 1 + Oqtane.Client/Program.cs | 10 ++++++++++ Oqtane.Client/Themes/Controls/LanguageSwitcher.razor | 12 ++++++++++-- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/Oqtane.Client/Oqtane.Client.csproj b/Oqtane.Client/Oqtane.Client.csproj index 3ce83439..da11a472 100644 --- a/Oqtane.Client/Oqtane.Client.csproj +++ b/Oqtane.Client/Oqtane.Client.csproj @@ -17,6 +17,7 @@ https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.0 Oqtane true + true diff --git a/Oqtane.Client/Program.cs b/Oqtane.Client/Program.cs index 7fdfa6bd..6689db41 100644 --- a/Oqtane.Client/Program.cs +++ b/Oqtane.Client/Program.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; @@ -10,6 +11,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Components.Authorization; using Microsoft.AspNetCore.Components.WebAssembly.Hosting; using Microsoft.Extensions.DependencyInjection; +using Microsoft.JSInterop; using Oqtane.Modules; using Oqtane.Providers; using Oqtane.Services; @@ -89,6 +91,14 @@ namespace Oqtane.Client } var host = builder.Build(); + var jsRuntime = host.Services.GetRequiredService(); + var culture = await jsRuntime.InvokeAsync("oqtaneCulture.get"); + if (culture != null) + { + var cultureInfo = CultureInfo.GetCultureInfo(culture); + CultureInfo.DefaultThreadCurrentCulture = cultureInfo; + CultureInfo.DefaultThreadCurrentUICulture = cultureInfo; + } ServiceActivator.Configure(host.Services); diff --git a/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor b/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor index 3b630a7a..8ce1c52d 100644 --- a/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor +++ b/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor @@ -2,6 +2,7 @@ @inherits ThemeControlBase @using System.Globalization @inject ILocalizationService LocalizationService +@inject NavigationManager NavigationManager @if (_supportedCultures != null) { @@ -12,7 +13,7 @@ @@ -24,7 +25,14 @@ protected override async Task OnParametersSetAsync() { - _selectedCulture = await JSRuntime.InvokeAsync("oqtaneCulture.get"); + _selectedCulture = _selectedCulture = await JSRuntime.InvokeAsync("oqtaneCulture.get"); _supportedCultures = await LocalizationService.GetSupportedCultures(); } + + private async Task SetCultureAsync(string culture) + { + await JSRuntime.InvokeVoidAsync("oqtaneCulture.set", culture); + + NavigationManager.NavigateTo(NavigationManager.Uri, forceLoad: true); + } } From 330499dda5c86c219783fc68a8778d605d238370 Mon Sep 17 00:00:00 2001 From: hishamco Date: Wed, 2 Dec 2020 02:10:01 +0300 Subject: [PATCH 05/14] Use Interop --- Oqtane.Client/Program.cs | 4 ++- .../Themes/Controls/LanguageSwitcher.razor | 6 ++-- Oqtane.Client/UI/Interop.cs | 29 ++++++++++++++++++- Oqtane.Server/Pages/_Host.cshtml | 8 +---- Oqtane.Server/wwwroot/js/interop.js | 6 ++++ 5 files changed, 42 insertions(+), 11 deletions(-) diff --git a/Oqtane.Client/Program.cs b/Oqtane.Client/Program.cs index 6689db41..43dc617a 100644 --- a/Oqtane.Client/Program.cs +++ b/Oqtane.Client/Program.cs @@ -16,6 +16,7 @@ using Oqtane.Modules; using Oqtane.Providers; using Oqtane.Services; using Oqtane.Shared; +using Oqtane.UI; namespace Oqtane.Client { @@ -92,7 +93,8 @@ namespace Oqtane.Client var host = builder.Build(); var jsRuntime = host.Services.GetRequiredService(); - var culture = await jsRuntime.InvokeAsync("oqtaneCulture.get"); + var interop = new Interop(jsRuntime); + var culture = await interop.getCulture(); if (culture != null) { var cultureInfo = CultureInfo.GetCultureInfo(culture); diff --git a/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor b/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor index 8ce1c52d..ddde387b 100644 --- a/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor +++ b/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor @@ -25,13 +25,15 @@ protected override async Task OnParametersSetAsync() { - _selectedCulture = _selectedCulture = await JSRuntime.InvokeAsync("oqtaneCulture.get"); + var interop = new Interop(JSRuntime); + _selectedCulture = await interop.getCulture(); _supportedCultures = await LocalizationService.GetSupportedCultures(); } private async Task SetCultureAsync(string culture) { - await JSRuntime.InvokeVoidAsync("oqtaneCulture.set", culture); + var interop = new Interop(JSRuntime); + await interop.setCulture(culture); NavigationManager.NavigateTo(NavigationManager.Uri, forceLoad: true); } diff --git a/Oqtane.Client/UI/Interop.cs b/Oqtane.Client/UI/Interop.cs index 53b8df4f..83a88ad5 100644 --- a/Oqtane.Client/UI/Interop.cs +++ b/Oqtane.Client/UI/Interop.cs @@ -1,4 +1,4 @@ -using Microsoft.JSInterop; +using Microsoft.JSInterop; using Oqtane.Models; using System.Threading.Tasks; @@ -234,5 +234,32 @@ namespace Oqtane.UI } } + public async Task getCulture() + { + try + { + var culture = await _jsRuntime.InvokeAsync("Oqtane.Interop.getCulture"); + + return culture; + } + catch + { + return null; + } + } + + public Task setCulture(string culture) + { + try + { + _jsRuntime.InvokeVoidAsync("Oqtane.Interop.setCulture", culture); + + return Task.CompletedTask; + } + catch + { + return Task.CompletedTask; + } + } } } diff --git a/Oqtane.Server/Pages/_Host.cshtml b/Oqtane.Server/Pages/_Host.cshtml index 92dea6bc..ecf906e4 100644 --- a/Oqtane.Server/Pages/_Host.cshtml +++ b/Oqtane.Server/Pages/_Host.cshtml @@ -1,4 +1,4 @@ -@page "/" +@page "/" @namespace Oqtane.Pages @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers @using System.Globalization @@ -48,12 +48,6 @@ @if (Configuration.GetSection("Runtime").Value == "WebAssembly") { - } else { diff --git a/Oqtane.Server/wwwroot/js/interop.js b/Oqtane.Server/wwwroot/js/interop.js index 2e4092e4..dc3f0394 100644 --- a/Oqtane.Server/wwwroot/js/interop.js +++ b/Oqtane.Server/wwwroot/js/interop.js @@ -362,5 +362,11 @@ Oqtane.Interop = { setInterval(function () { window.location.href = url; }, wait * 1000); + }, + getCulture: function () { + return window.localStorage['OqtaneCulture']; + }, + setCulture: function (culture) { + window.localStorage['OqtaneCulture'] = culture; } }; From d4dd80ff3252fc432036b7b2098353ddf27bd79d Mon Sep 17 00:00:00 2001 From: hishamco Date: Wed, 2 Dec 2020 02:15:52 +0300 Subject: [PATCH 06/14] Add missing event args --- Oqtane.Client/Themes/Controls/LanguageSwitcher.razor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor b/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor index ddde387b..9c67f24c 100644 --- a/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor +++ b/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor @@ -13,7 +13,7 @@ From fa3cc48fd0a5fc782102a6978acc0934a04610e8 Mon Sep 17 00:00:00 2001 From: hishamco Date: Wed, 2 Dec 2020 02:19:47 +0300 Subject: [PATCH 07/14] Avoid to select the current selected culture --- Oqtane.Client/Themes/Controls/LanguageSwitcher.razor | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor b/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor index 9c67f24c..e14e8a8e 100644 --- a/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor +++ b/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor @@ -32,9 +32,12 @@ private async Task SetCultureAsync(string culture) { - var interop = new Interop(JSRuntime); - await interop.setCulture(culture); + if (culture != CultureInfo.CurrentUICulture.Name) + { + var interop = new Interop(JSRuntime); + await interop.setCulture(culture); - NavigationManager.NavigateTo(NavigationManager.Uri, forceLoad: true); + NavigationManager.NavigateTo(NavigationManager.Uri, forceLoad: true); + } } } From 1b3cc2c44e04414d75158d007841f806e0d0760e Mon Sep 17 00:00:00 2001 From: hishamco Date: Thu, 3 Dec 2020 13:37:18 +0300 Subject: [PATCH 08/14] Interop local storage APIs should be generic --- Oqtane.Client/Program.cs | 2 +- Oqtane.Client/Themes/Controls/LanguageSwitcher.razor | 4 ++-- Oqtane.Client/UI/Interop.cs | 10 +++++----- Oqtane.Server/wwwroot/js/interop.js | 8 ++++---- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Oqtane.Client/Program.cs b/Oqtane.Client/Program.cs index 43dc617a..fcc03099 100644 --- a/Oqtane.Client/Program.cs +++ b/Oqtane.Client/Program.cs @@ -94,7 +94,7 @@ namespace Oqtane.Client var host = builder.Build(); var jsRuntime = host.Services.GetRequiredService(); var interop = new Interop(jsRuntime); - var culture = await interop.getCulture(); + var culture = await interop.GetLocalStorage("OqtaneCulture"); if (culture != null) { var cultureInfo = CultureInfo.GetCultureInfo(culture); diff --git a/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor b/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor index e14e8a8e..4b0a3acd 100644 --- a/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor +++ b/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor @@ -26,7 +26,7 @@ protected override async Task OnParametersSetAsync() { var interop = new Interop(JSRuntime); - _selectedCulture = await interop.getCulture(); + _selectedCulture = await interop.GetLocalStorage("OqtaneCulture"); _supportedCultures = await LocalizationService.GetSupportedCultures(); } @@ -35,7 +35,7 @@ if (culture != CultureInfo.CurrentUICulture.Name) { var interop = new Interop(JSRuntime); - await interop.setCulture(culture); + await interop.SetLocalStorage("OqtaneCulture", culture); NavigationManager.NavigateTo(NavigationManager.Uri, forceLoad: true); } diff --git a/Oqtane.Client/UI/Interop.cs b/Oqtane.Client/UI/Interop.cs index 83a88ad5..10c37d44 100644 --- a/Oqtane.Client/UI/Interop.cs +++ b/Oqtane.Client/UI/Interop.cs @@ -234,13 +234,13 @@ namespace Oqtane.UI } } - public async Task getCulture() + public async Task GetLocalStorage(string name) { try { - var culture = await _jsRuntime.InvokeAsync("Oqtane.Interop.getCulture"); + var value = await _jsRuntime.InvokeAsync("Oqtane.Interop.getLocalStorage", name); - return culture; + return value; } catch { @@ -248,11 +248,11 @@ namespace Oqtane.UI } } - public Task setCulture(string culture) + public Task SetLocalStorage(string name, string value) { try { - _jsRuntime.InvokeVoidAsync("Oqtane.Interop.setCulture", culture); + _jsRuntime.InvokeVoidAsync("Oqtane.Interop.setLocalStorage", name, value); return Task.CompletedTask; } diff --git a/Oqtane.Server/wwwroot/js/interop.js b/Oqtane.Server/wwwroot/js/interop.js index dc3f0394..e71f4b81 100644 --- a/Oqtane.Server/wwwroot/js/interop.js +++ b/Oqtane.Server/wwwroot/js/interop.js @@ -363,10 +363,10 @@ Oqtane.Interop = { window.location.href = url; }, wait * 1000); }, - getCulture: function () { - return window.localStorage['OqtaneCulture']; + getLocalStorage: function (name) { + return window.localStorage[name]; }, - setCulture: function (culture) { - window.localStorage['OqtaneCulture'] = culture; + setLocalStorage: function (name, value) { + window.localStorage[name] = value; } }; From a37eb8a44a68147b7f77e77c0cf3f1c755238c61 Mon Sep 17 00:00:00 2001 From: hishamco Date: Thu, 3 Dec 2020 14:05:49 +0300 Subject: [PATCH 09/14] Introduce Culture model to avoid CultureInfo.DisplayName issue --- .../Interfaces/ILocalizationService.cs | 6 ++++-- Oqtane.Client/Services/LocalizationService.cs | 7 +++++-- .../Themes/Controls/LanguageSwitcher.razor | 7 ++++--- .../Controllers/LocalizationController.cs | 20 +++++++++++++++++-- Oqtane.Shared/Models/Culture.cs | 9 +++++++++ 5 files changed, 40 insertions(+), 9 deletions(-) create mode 100644 Oqtane.Shared/Models/Culture.cs diff --git a/Oqtane.Client/Services/Interfaces/ILocalizationService.cs b/Oqtane.Client/Services/Interfaces/ILocalizationService.cs index c025ee45..8a580cc6 100644 --- a/Oqtane.Client/Services/Interfaces/ILocalizationService.cs +++ b/Oqtane.Client/Services/Interfaces/ILocalizationService.cs @@ -1,11 +1,13 @@ +using System.Collections.Generic; using System.Threading.Tasks; +using Oqtane.Models; namespace Oqtane.Services { public interface ILocalizationService { - Task GetDefaultCulture(); + Task GetDefaultCulture(); - Task GetSupportedCultures(); + Task> GetSupportedCultures(); } } diff --git a/Oqtane.Client/Services/LocalizationService.cs b/Oqtane.Client/Services/LocalizationService.cs index 4c658c50..ea6e5fd8 100644 --- a/Oqtane.Client/Services/LocalizationService.cs +++ b/Oqtane.Client/Services/LocalizationService.cs @@ -1,5 +1,7 @@ +using System.Collections.Generic; using System.Net.Http; using System.Threading.Tasks; +using Oqtane.Models; using Oqtane.Shared; namespace Oqtane.Services @@ -15,8 +17,9 @@ namespace Oqtane.Services private string Apiurl => CreateApiUrl(_siteState.Alias, "Localization"); - public async Task GetDefaultCulture() => await GetJsonAsync($"{Apiurl}/getDefaultCulture"); + public async Task GetDefaultCulture() => await GetJsonAsync($"{Apiurl}/getDefaultCulture"); - public async Task GetSupportedCultures() => await GetJsonAsync($"{Apiurl}/getSupportedCultures"); + public async Task> GetSupportedCultures() + => await GetJsonAsync>($"{Apiurl}/getSupportedCultures"); } } diff --git a/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor b/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor index 4b0a3acd..7c3ca1d2 100644 --- a/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor +++ b/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor @@ -1,6 +1,7 @@ @namespace Oqtane.Themes.Controls @inherits ThemeControlBase -@using System.Globalization +@using System.Globalization +@using Oqtane.Models @inject ILocalizationService LocalizationService @inject NavigationManager NavigationManager @@ -13,7 +14,7 @@ @@ -21,7 +22,7 @@ @code{ private string _selectedCulture; - private string[] _supportedCultures; + private IEnumerable _supportedCultures; protected override async Task OnParametersSetAsync() { diff --git a/Oqtane.Server/Controllers/LocalizationController.cs b/Oqtane.Server/Controllers/LocalizationController.cs index f8b7433a..46e475ef 100644 --- a/Oqtane.Server/Controllers/LocalizationController.cs +++ b/Oqtane.Server/Controllers/LocalizationController.cs @@ -1,6 +1,9 @@ using System.Collections.Generic; +using System.Globalization; +using System.Linq; using Microsoft.AspNetCore.Mvc; using Oqtane.Infrastructure; +using Oqtane.Models; using Oqtane.Shared; namespace Oqtane.Controllers @@ -17,10 +20,23 @@ namespace Oqtane.Controllers // GET: api/localization/getSupportedCultures [HttpGet("getSupportedCultures")] - public IEnumerable GetSupportedCultures() => _localizationManager.GetSupportedCultures(); + public IEnumerable GetSupportedCultures() + => _localizationManager.GetSupportedCultures().Select(c => new Culture { + Name = CultureInfo.GetCultureInfo(c).Name, + DisplayName = CultureInfo.GetCultureInfo(c).DisplayName + }); // GET api/localization/getDefaultCulture [HttpGet("getDefaultCulture")] - public string GetDefaultCulture() => _localizationManager.GetDefaultCulture(); + public Culture GetDefaultCulture() + { + var culture = _localizationManager.GetDefaultCulture(); + + return new Culture + { + Name = CultureInfo.GetCultureInfo(culture).Name, + DisplayName = CultureInfo.GetCultureInfo(culture).DisplayName + }; + } } } diff --git a/Oqtane.Shared/Models/Culture.cs b/Oqtane.Shared/Models/Culture.cs new file mode 100644 index 00000000..78d249d6 --- /dev/null +++ b/Oqtane.Shared/Models/Culture.cs @@ -0,0 +1,9 @@ +namespace Oqtane.Models +{ + public class Culture + { + public string Name { get; set; } + + public string DisplayName { get; set; } + } +} From 5ee38e4ae753f10f8c146f7aded7174014e315d7 Mon Sep 17 00:00:00 2001 From: hishamco Date: Thu, 3 Dec 2020 14:13:01 +0300 Subject: [PATCH 10/14] Add Visible property to control the visibility --- Oqtane.Client/Themes/Controls/LanguageSwitcher.razor | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor b/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor index 7c3ca1d2..c8e7bfb9 100644 --- a/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor +++ b/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor @@ -5,7 +5,7 @@ @inject ILocalizationService LocalizationService @inject NavigationManager NavigationManager -@if (_supportedCultures != null) +@if (_supportedCultures != null && Visible) {
} @code{ - private string _selectedCulture; private IEnumerable _supportedCultures; [Parameter] @@ -29,8 +28,6 @@ protected override async Task OnParametersSetAsync() { - var interop = new Interop(JSRuntime); - _selectedCulture = await interop.GetLocalStorage("OqtaneCulture"); _supportedCultures = await LocalizationService.GetCulturesAsync(); } From 20f1a6175fae476760d71df709020e73345411d5 Mon Sep 17 00:00:00 2001 From: hishamco Date: Thu, 3 Dec 2020 17:15:08 +0300 Subject: [PATCH 13/14] Use cookie everywhere --- Oqtane.Client/Oqtane.Client.csproj | 1 + Oqtane.Client/Program.cs | 4 ++- .../Themes/Controls/LanguageSwitcher.razor | 6 ++-- Oqtane.Client/UI/Interop.cs | 29 ------------------- .../ApplicationBuilderExtensions.cs | 5 +--- Oqtane.Server/Pages/_Host.cshtml | 8 ----- Oqtane.Server/wwwroot/js/interop.js | 6 ---- 7 files changed, 9 insertions(+), 50 deletions(-) diff --git a/Oqtane.Client/Oqtane.Client.csproj b/Oqtane.Client/Oqtane.Client.csproj index da11a472..72024f75 100644 --- a/Oqtane.Client/Oqtane.Client.csproj +++ b/Oqtane.Client/Oqtane.Client.csproj @@ -31,6 +31,7 @@ +
diff --git a/Oqtane.Client/Program.cs b/Oqtane.Client/Program.cs index cc85b9b9..4c2d1201 100644 --- a/Oqtane.Client/Program.cs +++ b/Oqtane.Client/Program.cs @@ -10,6 +10,7 @@ using System.Runtime.Loader; using System.Threading.Tasks; using Microsoft.AspNetCore.Components.Authorization; using Microsoft.AspNetCore.Components.WebAssembly.Hosting; +using Microsoft.AspNetCore.Localization; using Microsoft.Extensions.DependencyInjection; using Microsoft.JSInterop; using Oqtane.Modules; @@ -94,7 +95,8 @@ namespace Oqtane.Client var host = builder.Build(); var jsRuntime = host.Services.GetRequiredService(); var interop = new Interop(jsRuntime); - var culture = await interop.GetLocalStorage("OqtaneCulture"); + var localizationCookie = await interop.GetCookie(CookieRequestCultureProvider.DefaultCookieName); + var culture = CookieRequestCultureProvider.ParseCookieValue(localizationCookie).UICultures[0].Value; var localizationService = host.Services.GetRequiredService(); var cultures = await localizationService.GetCulturesAsync(); diff --git a/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor b/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor index e1d16002..6f748e88 100644 --- a/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor +++ b/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor @@ -1,6 +1,7 @@ @namespace Oqtane.Themes.Controls @inherits ThemeControlBase -@using System.Globalization +@using System.Globalization +@using Microsoft.AspNetCore.Localization; @using Oqtane.Models @inject ILocalizationService LocalizationService @inject NavigationManager NavigationManager @@ -36,7 +37,8 @@ if (culture != CultureInfo.CurrentUICulture.Name) { var interop = new Interop(JSRuntime); - await interop.SetLocalStorage("OqtaneCulture", culture); + var localizationCookieValue = CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(culture)); + await interop.SetCookie(CookieRequestCultureProvider.DefaultCookieName, localizationCookieValue, 360); NavigationManager.NavigateTo(NavigationManager.Uri, forceLoad: true); } diff --git a/Oqtane.Client/UI/Interop.cs b/Oqtane.Client/UI/Interop.cs index 10c37d44..3964b070 100644 --- a/Oqtane.Client/UI/Interop.cs +++ b/Oqtane.Client/UI/Interop.cs @@ -1,5 +1,4 @@ using Microsoft.JSInterop; -using Oqtane.Models; using System.Threading.Tasks; namespace Oqtane.UI @@ -233,33 +232,5 @@ namespace Oqtane.UI return Task.CompletedTask; } } - - public async Task GetLocalStorage(string name) - { - try - { - var value = await _jsRuntime.InvokeAsync("Oqtane.Interop.getLocalStorage", name); - - return value; - } - catch - { - return null; - } - } - - public Task SetLocalStorage(string name, string value) - { - try - { - _jsRuntime.InvokeVoidAsync("Oqtane.Interop.setLocalStorage", name, value); - - return Task.CompletedTask; - } - catch - { - return Task.CompletedTask; - } - } } } diff --git a/Oqtane.Server/Extensions/ApplicationBuilderExtensions.cs b/Oqtane.Server/Extensions/ApplicationBuilderExtensions.cs index 67676d16..81ca19ac 100644 --- a/Oqtane.Server/Extensions/ApplicationBuilderExtensions.cs +++ b/Oqtane.Server/Extensions/ApplicationBuilderExtensions.cs @@ -1,5 +1,4 @@ -using System; -using System.Globalization; +using System; using System.Linq; using System.Reflection; using Microsoft.AspNetCore.Builder; @@ -31,8 +30,6 @@ namespace Oqtane.Extensions var defaultCulture = localizationManager.GetDefaultCulture(); var supportedCultures = localizationManager.GetSupportedCultures(); - CultureInfo.CurrentUICulture = new CultureInfo(defaultCulture); - app.UseRequestLocalization(options => { options.SetDefaultCulture(defaultCulture) .AddSupportedUICultures(supportedCultures) diff --git a/Oqtane.Server/Pages/_Host.cshtml b/Oqtane.Server/Pages/_Host.cshtml index ecf906e4..cf2d69f0 100644 --- a/Oqtane.Server/Pages/_Host.cshtml +++ b/Oqtane.Server/Pages/_Host.cshtml @@ -1,17 +1,9 @@ @page "/" @namespace Oqtane.Pages @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers -@using System.Globalization -@using Microsoft.AspNetCore.Localization @using Microsoft.Extensions.Configuration @inject IConfiguration Configuration @model Oqtane.Pages.HostModel - -@{ - // Set localization cookie - var localizationCookieValue = CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(CultureInfo.CurrentCulture, CultureInfo.CurrentUICulture)); - HttpContext.Response.Cookies.Append(CookieRequestCultureProvider.DefaultCookieName, localizationCookieValue); -} diff --git a/Oqtane.Server/wwwroot/js/interop.js b/Oqtane.Server/wwwroot/js/interop.js index e71f4b81..2e4092e4 100644 --- a/Oqtane.Server/wwwroot/js/interop.js +++ b/Oqtane.Server/wwwroot/js/interop.js @@ -362,11 +362,5 @@ Oqtane.Interop = { setInterval(function () { window.location.href = url; }, wait * 1000); - }, - getLocalStorage: function (name) { - return window.localStorage[name]; - }, - setLocalStorage: function (name, value) { - window.localStorage[name] = value; } }; From 5e293ee2988fd70cb9d87585cda0f6ce657b62c5 Mon Sep 17 00:00:00 2001 From: hishamco Date: Thu, 3 Dec 2020 17:25:01 +0300 Subject: [PATCH 14/14] Fix SupportedCultures bug --- Oqtane.Server/Extensions/ApplicationBuilderExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Oqtane.Server/Extensions/ApplicationBuilderExtensions.cs b/Oqtane.Server/Extensions/ApplicationBuilderExtensions.cs index 81ca19ac..4f43068e 100644 --- a/Oqtane.Server/Extensions/ApplicationBuilderExtensions.cs +++ b/Oqtane.Server/Extensions/ApplicationBuilderExtensions.cs @@ -32,7 +32,7 @@ namespace Oqtane.Extensions app.UseRequestLocalization(options => { options.SetDefaultCulture(defaultCulture) - .AddSupportedUICultures(supportedCultures) + .AddSupportedCultures(supportedCultures) .AddSupportedUICultures(supportedCultures); });