Skip to content

Commit cc18af0

Browse files
committed
Added Danish
1 parent 98c69f3 commit cc18af0

File tree

11 files changed

+132
-60
lines changed

11 files changed

+132
-60
lines changed

SecureFolderFS.AvaloniaUI/ServiceImplementation/LocalizationService.cs

+9-10
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,24 @@
11
using SecureFolderFS.Sdk.Services;
2+
using SecureFolderFS.UI.ServiceImplementation;
23
using System.Collections.Generic;
34
using System.Globalization;
5+
using System.Resources;
46
using System.Threading.Tasks;
57

68
namespace SecureFolderFS.AvaloniaUI.ServiceImplementation
79
{
810
// TODO: Implement localization
911
/// <inheritdoc cref="ILocalizationService"/>
10-
internal sealed class LocalizationService : ILocalizationService
12+
internal sealed class LocalizationService : BaseLocalizationService
1113
{
1214
/// <inheritdoc/>
13-
public CultureInfo CurrentCulture { get; }
15+
protected override ResourceManager ResourceManager { get; }
1416

1517
/// <inheritdoc/>
16-
public IReadOnlyList<CultureInfo> AppLanguages { get; }
18+
public override CultureInfo CurrentCulture { get; }
19+
20+
/// <inheritdoc/>
21+
public override IReadOnlyList<CultureInfo> AppLanguages { get; }
1722

1823
public LocalizationService()
1924
{
@@ -22,13 +27,7 @@ public LocalizationService()
2227
}
2328

2429
/// <inheritdoc/>
25-
public string? GetString(string resourceKey)
26-
{
27-
return resourceKey;
28-
}
29-
30-
/// <inheritdoc/>
31-
public Task SetCultureAsync(CultureInfo cultureInfo)
30+
public override Task SetCultureAsync(CultureInfo cultureInfo)
3231
{
3332
return Task.CompletedTask;
3433
}

SecureFolderFS.Sdk/Extensions/LocalizationExtensions.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public static string ToLocalized(this string resourceKey)
1515
public static string ToLocalized(this string resourceKey, ILocalizationService? localizationService)
1616
{
1717
localizationService = GetLocalizationService(localizationService);
18-
return localizationService?.GetString(resourceKey) ?? string.Empty;
18+
return localizationService?.TryGetString(resourceKey) ?? $"{{{resourceKey}}}";
1919

2020
static ILocalizationService? GetLocalizationService(ILocalizationService? fallback)
2121
{

SecureFolderFS.Sdk/Services/ILocalizationService.cs

+7-4
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,18 @@ public interface ILocalizationService
2020
IReadOnlyList<CultureInfo> AppLanguages { get; }
2121

2222
/// <summary>
23-
/// Gets the localized version for the <paramref name="resourceKey"/>.
23+
/// Tries to gets the localized string for the <paramref name="resourceKey"/>.
2424
/// </summary>
2525
/// <param name="resourceKey">The resource key that associates with translations.</param>
26-
/// <returns>A localized string for the <see cref="CurrentCulture"/>.</returns>
27-
string? GetString(string resourceKey);
26+
/// <returns>If successful, returns a localized string for the <see cref="CurrentCulture"/>; otherwise null.</returns>
27+
string? TryGetString(string resourceKey);
2828

2929
/// <summary>
30-
/// Sets the current language of the app and updates <see cref="CurrentCulture"/>.
30+
/// Sets the current language of the app.
3131
/// </summary>
32+
/// <remarks>
33+
/// This method does not update <see cref="CurrentCulture"/> with the new value.
34+
/// </remarks>
3235
/// <param name="cultureInfo">The language to set.</param>
3336
/// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
3437
Task SetCultureAsync(CultureInfo cultureInfo);

SecureFolderFS.Sdk/ViewModels/Controls/LanguageViewModel.cs

+19-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
using CommunityToolkit.Mvvm.ComponentModel;
2+
using System;
3+
using System.Diagnostics;
24
using System.Globalization;
35

46
namespace SecureFolderFS.Sdk.ViewModels.Controls
@@ -19,9 +21,14 @@ public sealed class LanguageViewModel : ObservableObject
1921
public string DisplayName { get; }
2022

2123
public LanguageViewModel(CultureInfo cultureInfo)
24+
: this(cultureInfo, FormatName(cultureInfo))
25+
{
26+
}
27+
28+
public LanguageViewModel(CultureInfo cultureInfo, string displayName)
2229
{
2330
CultureInfo = cultureInfo;
24-
DisplayName = FormatName(cultureInfo);
31+
DisplayName = displayName;
2532
}
2633

2734
/// <inheritdoc/>
@@ -42,9 +49,18 @@ private static string FormatName(CultureInfo cultureInfo)
4249
return name;
4350

4451
// Get the region to use for the country name
45-
var regionInfo = new RegionInfo(cultureInfo.Name);
52+
try
53+
{
54+
var regionInfo = new RegionInfo(cultureInfo.LCID);
55+
return $"{name} ({regionInfo.DisplayName})";
56+
}
57+
catch (Exception ex)
58+
{
59+
_ = ex;
60+
Debugger.Break();
4661

47-
return $"{name} ({regionInfo.DisplayName})";
62+
return name;
63+
}
4864
}
4965
}
5066
}

SecureFolderFS.Sdk/ViewModels/Views/Settings/GeneralSettingsViewModel.cs

+17-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using SecureFolderFS.Sdk.ViewModels.Controls;
77
using SecureFolderFS.Sdk.ViewModels.Controls.Banners;
88
using System.Collections.ObjectModel;
9+
using System.Globalization;
910
using System.Linq;
1011
using System.Threading;
1112
using System.Threading.Tasks;
@@ -34,6 +35,9 @@ public override async Task InitAsync(CancellationToken cancellationToken = defau
3435
foreach (var item in LocalizationService.AppLanguages)
3536
Languages.Add(new(item));
3637

38+
// Add wildcard language
39+
Languages.Add(new(CultureInfo.InvariantCulture, "Not seeing your language?"));
40+
3741
// Set selected language
3842
SelectedLanguage = Languages.FirstOrDefault(x => x.CultureInfo.Equals(LocalizationService.CurrentCulture));
3943

@@ -49,7 +53,19 @@ private async Task RestartAsync()
4953

5054
async partial void OnSelectedLanguageChanged(LanguageViewModel? value)
5155
{
52-
if (value is not null)
56+
if (value is null)
57+
return;
58+
59+
if (value.CultureInfo.Equals(CultureInfo.InvariantCulture))
60+
{
61+
// Wildcard
62+
await ApplicationService.OpenUriAsync(new("https://github.com/securefolderfs-community/SecureFolderFS/issues/50"));
63+
64+
SelectedLanguage = Languages.FirstOrDefault(x => x.CultureInfo.Equals(LocalizationService.CurrentCulture));
65+
if (SelectedLanguage is not null)
66+
await LocalizationService.SetCultureAsync(SelectedLanguage.CultureInfo);
67+
}
68+
else
5369
{
5470
await LocalizationService.SetCultureAsync(value.CultureInfo);
5571
IsRestartRequired = !LocalizationService.CurrentCulture.Equals(SelectedLanguage?.CultureInfo);

SecureFolderFS.Sdk/ViewModels/Views/Vault/VaultDashboardPageViewModel.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,13 @@ public void Receive(VaultLockedMessage message)
3535
[RelayCommand]
3636
private async Task GoBackAsync()
3737
{
38-
await NavigationService.TryNavigateAsync<VaultOverviewPageViewModel>();
38+
await DashboardNavigationService.TryNavigateAsync<VaultOverviewPageViewModel>();
3939
}
4040

4141
/// <inheritdoc/>
4242
public override void Dispose()
4343
{
44-
NavigationService.Dispose();
44+
DashboardNavigationService.Dispose();
4545
}
4646
}
4747
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
using SecureFolderFS.Sdk.Services;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Diagnostics;
5+
using System.Globalization;
6+
using System.Linq;
7+
using System.Resources;
8+
using System.Threading.Tasks;
9+
10+
namespace SecureFolderFS.UI.ServiceImplementation
11+
{
12+
/// <inheritdoc cref="ILocalizationService"/>
13+
public abstract class BaseLocalizationService : ILocalizationService
14+
{
15+
protected static IReadOnlyList<string> SupportedLanguages = new List<string>()
16+
{
17+
"cz-CZ", "da-DK", "de-DE", "en-US", "es-ES", "fr-FR", "it-IT", "pl-PL", "ru-RU", "ua-UA"
18+
};
19+
20+
protected abstract ResourceManager ResourceManager { get; }
21+
22+
/// <inheritdoc/>
23+
public abstract CultureInfo CurrentCulture { get; }
24+
25+
/// <inheritdoc/>
26+
public abstract IReadOnlyList<CultureInfo> AppLanguages { get; }
27+
28+
/// <inheritdoc/>
29+
public virtual string? TryGetString(string resourceKey)
30+
{
31+
try
32+
{
33+
return ResourceManager.GetString(resourceKey);
34+
}
35+
catch (Exception ex)
36+
{
37+
_ = ex;
38+
Debugger.Break();
39+
40+
return null;
41+
}
42+
}
43+
44+
/// <inheritdoc/>
45+
public abstract Task SetCultureAsync(CultureInfo cultureInfo);
46+
47+
protected static string GetLanguageString(CultureInfo cultureInfo)
48+
{
49+
if (cultureInfo.Name.Contains('-', StringComparison.OrdinalIgnoreCase))
50+
return cultureInfo.Name.Replace('-', '_');
51+
52+
return SupportedLanguages.First(x => x.Contains(cultureInfo.Name)).Replace('-', '_');
53+
}
54+
}
55+
}

SecureFolderFS.WinUI/Localization/ResourceString.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ protected override object ProvideValue()
2323
if (LocalizationService is null)
2424
return $"{{{Name}}}";
2525

26-
return LocalizationService.GetString(Name ?? string.Empty) ?? $"{{{Name}}}";
26+
return LocalizationService.TryGetString(Name ?? string.Empty) ?? $"{{{Name}}}";
2727
}
2828
}
2929
}

SecureFolderFS.WinUI/Package.appxmanifest

+5-4
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,11 @@
2424
</Dependencies>
2525

2626
<Resources>
27-
<Resource Language="en-US"/>
28-
<Resource Language="pl-PL"/>
29-
<Resource Language="de-DE"/>
30-
<Resource Language="es-ES"/>
27+
<Resource Language="en-US"/>
28+
<Resource Language="pl-PL"/>
29+
<Resource Language="de-DE"/>
30+
<Resource Language="es-ES"/>
31+
<Resource Language="da-DK"/>
3132
</Resources>
3233

3334
<Applications>

SecureFolderFS.WinUI/SecureFolderFS.WinUI.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<TargetFramework>net7.0-windows10.0.22621.0</TargetFramework>
55
<TargetPlatformMinVersion>10.0.19041.0</TargetPlatformMinVersion>
66
<AppxBundleAutoResourcePackageQualifiers>Scale|DXFeatureLevel</AppxBundleAutoResourcePackageQualifiers>
7-
<AppxDefaultResourceQualifiers>Language=en-US;pl-PL;de-DE;es-ES</AppxDefaultResourceQualifiers>
7+
<AppxDefaultResourceQualifiers>Language=en-US;pl-PL;de-DE;es-ES;da-DK</AppxDefaultResourceQualifiers>
88
<TargetPlatformVersion Condition=" '$(TargetPlatformVersion)' == '' ">10.0.22621.0</TargetPlatformVersion>
99
<RootNamespace>SecureFolderFS.WinUI</RootNamespace>
1010
<ApplicationManifest>app.manifest</ApplicationManifest>
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
using SecureFolderFS.Sdk.Services;
2-
using System;
2+
using SecureFolderFS.UI.ServiceImplementation;
33
using System.Collections.Generic;
4-
using System.Diagnostics;
4+
using System.Collections.Immutable;
55
using System.Globalization;
66
using System.Linq;
77
using System.Resources;
@@ -11,55 +11,37 @@
1111
namespace SecureFolderFS.WinUI.ServiceImplementation
1212
{
1313
/// <inheritdoc cref="ILocalizationService"/>
14-
internal sealed class LocalizationService : ILocalizationService
14+
internal sealed class LocalizationService : BaseLocalizationService
1515
{
16-
private ResourceManager ResourceManager { get; set; }
16+
/// <inheritdoc/>
17+
protected override ResourceManager ResourceManager { get; }
1718

1819
/// <inheritdoc/>
19-
public CultureInfo CurrentCulture { get; }
20+
public override CultureInfo CurrentCulture { get; }
2021

2122
/// <inheritdoc/>
22-
public IReadOnlyList<CultureInfo> AppLanguages { get; }
23+
public override IReadOnlyList<CultureInfo> AppLanguages { get; }
2324

2425
public LocalizationService()
2526
{
26-
CurrentCulture = new(ApplicationLanguages.PrimaryLanguageOverride);
27-
AppLanguages = ApplicationLanguages.ManifestLanguages
28-
.Select(x => new CultureInfo(x))
29-
.ToList();
30-
27+
CurrentCulture = new(SupportedLanguages.First(x => x.Contains(ApplicationLanguages.PrimaryLanguageOverride)));
28+
AppLanguages = GetAppLanguages().ToImmutableList();
3129
ResourceManager = new($"SecureFolderFS.UI.Strings.{GetLanguageString(CurrentCulture)}.Resources", typeof(UI.Constants).Assembly);
3230
}
3331

3432
/// <inheritdoc/>
35-
public string? GetString(string resourceKey)
36-
{
37-
try
38-
{
39-
return ResourceManager.GetString(resourceKey);
40-
}
41-
catch (Exception ex)
42-
{
43-
_ = ex;
44-
Debugger.Break();
45-
46-
return null;
47-
}
48-
}
49-
50-
/// <inheritdoc/>
51-
public Task SetCultureAsync(CultureInfo cultureInfo)
33+
public override Task SetCultureAsync(CultureInfo cultureInfo)
5234
{
5335
ApplicationLanguages.PrimaryLanguageOverride = cultureInfo.Name;
5436
return Task.CompletedTask;
5537
}
5638

57-
private static string GetLanguageString(CultureInfo cultureInfo)
39+
private IEnumerable<CultureInfo> GetAppLanguages()
5840
{
59-
if (cultureInfo.Name.Contains('-', StringComparison.OrdinalIgnoreCase))
60-
return cultureInfo.Name.Replace('-', '_');
61-
62-
return $"{cultureInfo.Name}_{cultureInfo.TwoLetterISOLanguageName.ToUpperInvariant()}";
41+
foreach (var item in ApplicationLanguages.ManifestLanguages)
42+
{
43+
yield return new(SupportedLanguages.First(x => x.Contains(item)));
44+
}
6345
}
6446
}
6547
}

0 commit comments

Comments
 (0)