Translated dates based on display language. (#567)
* Updating the app's culture based on the display language and making sure that dates/times are properly translated.
This commit is contained in:
@@ -9,4 +9,5 @@ public interface ITranslationService : IInitializeAsync
|
|||||||
{
|
{
|
||||||
Task InitializeLanguageAsync(AppLanguage language, bool ignoreCurrentLanguageCheck = false);
|
Task InitializeLanguageAsync(AppLanguage language, bool ignoreCurrentLanguageCheck = false);
|
||||||
List<AppLanguageModel> GetAvailableLanguages();
|
List<AppLanguageModel> GetAvailableLanguages();
|
||||||
|
AppLanguageModel CurrentLanguageModel { get; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,4 +2,4 @@
|
|||||||
|
|
||||||
namespace Wino.Core.Domain.Models.Translations;
|
namespace Wino.Core.Domain.Models.Translations;
|
||||||
|
|
||||||
public record AppLanguageModel(AppLanguage Language, string DisplayName);
|
public record AppLanguageModel(AppLanguage Language, string DisplayName, string Code);
|
||||||
|
|||||||
@@ -36,9 +36,6 @@ public static class XamlHelpers
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static Visibility ReverseBoolToVisibilityConverter(bool value) => value ? Visibility.Collapsed : Visibility.Visible;
|
public static Visibility ReverseBoolToVisibilityConverter(bool value) => value ? Visibility.Collapsed : Visibility.Visible;
|
||||||
public static Visibility ReverseVisibilityConverter(Visibility visibility) => visibility == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;
|
public static Visibility ReverseVisibilityConverter(Visibility visibility) => visibility == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;
|
||||||
public static bool ReverseBoolConverter(bool value) => !value;
|
public static bool ReverseBoolConverter(bool value) => !value;
|
||||||
@@ -125,7 +122,7 @@ public static class XamlHelpers
|
|||||||
public static string GetCreationDateString(DateTime date, bool prefer24HourTime)
|
public static string GetCreationDateString(DateTime date, bool prefer24HourTime)
|
||||||
{
|
{
|
||||||
var localTime = date.ToLocalTime();
|
var localTime = date.ToLocalTime();
|
||||||
return $"{localTime.ToLongDateString()} {(prefer24HourTime ? localTime.ToString(TwentyFourHourTimeFormat) : localTime.ToString(TwelveHourTimeFormat))}";
|
return $"{localTime.ToString("D", CultureInfo.DefaultThreadCurrentUICulture)} {(prefer24HourTime ? localTime.ToString(TwentyFourHourTimeFormat) : localTime.ToString(TwelveHourTimeFormat))}";
|
||||||
}
|
}
|
||||||
public static string GetMailGroupDateString(object groupObject)
|
public static string GetMailGroupDateString(object groupObject)
|
||||||
{
|
{
|
||||||
@@ -152,7 +149,10 @@ public static class XamlHelpers
|
|||||||
else if (dateTimeValue == DateTime.Today.AddDays(-1))
|
else if (dateTimeValue == DateTime.Today.AddDays(-1))
|
||||||
return Translator.Yesterday;
|
return Translator.Yesterday;
|
||||||
else
|
else
|
||||||
return dateTimeValue.ToLongDateString();
|
{
|
||||||
|
return dateTimeValue.ToString("D", CultureInfo.DefaultThreadCurrentUICulture);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return dateObject.ToString();
|
return dateObject.ToString();
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using CommunityToolkit.Mvvm.Messaging;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Nito.AsyncEx;
|
using Nito.AsyncEx;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
@@ -11,6 +13,7 @@ using Windows.ApplicationModel.Activation;
|
|||||||
using Windows.ApplicationModel.AppService;
|
using Windows.ApplicationModel.AppService;
|
||||||
using Windows.ApplicationModel.Core;
|
using Windows.ApplicationModel.Core;
|
||||||
using Windows.Foundation.Metadata;
|
using Windows.Foundation.Metadata;
|
||||||
|
using Windows.Globalization;
|
||||||
using Windows.Storage;
|
using Windows.Storage;
|
||||||
using Windows.UI;
|
using Windows.UI;
|
||||||
using Windows.UI.Core.Preview;
|
using Windows.UI.Core.Preview;
|
||||||
@@ -20,11 +23,13 @@ using Windows.UI.Xaml.Controls;
|
|||||||
using Wino.Activation;
|
using Wino.Activation;
|
||||||
using Wino.Core.Domain;
|
using Wino.Core.Domain;
|
||||||
using Wino.Core.Domain.Interfaces;
|
using Wino.Core.Domain.Interfaces;
|
||||||
|
using Wino.Core.Domain.Models.Translations;
|
||||||
|
using Wino.Messaging.Client.Shell;
|
||||||
using Wino.Services;
|
using Wino.Services;
|
||||||
|
|
||||||
namespace Wino.Core.UWP;
|
namespace Wino.Core.UWP;
|
||||||
|
|
||||||
public abstract class WinoApplication : Application
|
public abstract class WinoApplication : Application, IRecipient<LanguageChanged>
|
||||||
{
|
{
|
||||||
public new static WinoApplication Current => (WinoApplication)Application.Current;
|
public new static WinoApplication Current => (WinoApplication)Application.Current;
|
||||||
public const string WinoLaunchLogPrefix = "[Wino Launch] ";
|
public const string WinoLaunchLogPrefix = "[Wino Launch] ";
|
||||||
@@ -215,8 +220,6 @@ public abstract class WinoApplication : Application
|
|||||||
CoreApplication.EnablePrelaunch(true);
|
CoreApplication.EnablePrelaunch(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public virtual async void OnResuming(object sender, object e)
|
public virtual async void OnResuming(object sender, object e)
|
||||||
{
|
{
|
||||||
// App Service connection was lost on suspension.
|
// App Service connection was lost on suspension.
|
||||||
@@ -245,4 +248,16 @@ public abstract class WinoApplication : Application
|
|||||||
string logFilePath = Path.Combine(ApplicationData.Current.LocalFolder.Path, Constants.ClientLogFile);
|
string logFilePath = Path.Combine(ApplicationData.Current.LocalFolder.Path, Constants.ClientLogFile);
|
||||||
LogInitializer.SetupLogger(logFilePath);
|
LogInitializer.SetupLogger(logFilePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual void OnLanguageChanged(AppLanguageModel languageModel)
|
||||||
|
{
|
||||||
|
var newCulture = new CultureInfo(languageModel.Code);
|
||||||
|
|
||||||
|
ApplicationLanguages.PrimaryLanguageOverride = languageModel.Code;
|
||||||
|
|
||||||
|
CultureInfo.DefaultThreadCurrentCulture = newCulture;
|
||||||
|
CultureInfo.DefaultThreadCurrentUICulture = newCulture;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Receive(LanguageChanged message) => OnLanguageChanged(TranslationService.CurrentLanguageModel);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,12 +24,14 @@ using Wino.Mail.Services;
|
|||||||
using Wino.Mail.ViewModels;
|
using Wino.Mail.ViewModels;
|
||||||
using Wino.Messaging.Client.Connection;
|
using Wino.Messaging.Client.Connection;
|
||||||
using Wino.Messaging.Client.Navigation;
|
using Wino.Messaging.Client.Navigation;
|
||||||
|
using Wino.Messaging.Client.Shell;
|
||||||
using Wino.Messaging.Server;
|
using Wino.Messaging.Server;
|
||||||
using Wino.Services;
|
using Wino.Services;
|
||||||
|
|
||||||
namespace Wino;
|
namespace Wino;
|
||||||
|
|
||||||
public sealed partial class App : WinoApplication, IRecipient<NewMailSynchronizationRequested>
|
public sealed partial class App : WinoApplication,
|
||||||
|
IRecipient<NewMailSynchronizationRequested>
|
||||||
{
|
{
|
||||||
private BackgroundTaskDeferral connectionBackgroundTaskDeferral;
|
private BackgroundTaskDeferral connectionBackgroundTaskDeferral;
|
||||||
private BackgroundTaskDeferral toastActionBackgroundTaskDeferral;
|
private BackgroundTaskDeferral toastActionBackgroundTaskDeferral;
|
||||||
@@ -40,7 +42,8 @@ public sealed partial class App : WinoApplication, IRecipient<NewMailSynchroniza
|
|||||||
|
|
||||||
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
|
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
|
||||||
|
|
||||||
WeakReferenceMessenger.Default.Register(this);
|
WeakReferenceMessenger.Default.Register<LanguageChanged>(this);
|
||||||
|
WeakReferenceMessenger.Default.Register<NewMailSynchronizationRequested>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async void OnResuming(object sender, object e)
|
public override async void OnResuming(object sender, object e)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using CommunityToolkit.Mvvm.Messaging;
|
using CommunityToolkit.Mvvm.Messaging;
|
||||||
@@ -20,6 +21,8 @@ public class TranslationService : ITranslationService
|
|||||||
private readonly IPreferencesService _preferencesService;
|
private readonly IPreferencesService _preferencesService;
|
||||||
private bool isInitialized = false;
|
private bool isInitialized = false;
|
||||||
|
|
||||||
|
public AppLanguageModel CurrentLanguageModel { get; private set; }
|
||||||
|
|
||||||
public TranslationService(IPreferencesService preferencesService)
|
public TranslationService(IPreferencesService preferencesService)
|
||||||
{
|
{
|
||||||
_preferencesService = preferencesService;
|
_preferencesService = preferencesService;
|
||||||
@@ -56,6 +59,7 @@ public class TranslationService : ITranslationService
|
|||||||
}
|
}
|
||||||
|
|
||||||
_preferencesService.CurrentLanguage = language;
|
_preferencesService.CurrentLanguage = language;
|
||||||
|
CurrentLanguageModel = GetAvailableLanguages().FirstOrDefault(a => a.Language == language);
|
||||||
|
|
||||||
isInitialized = true;
|
isInitialized = true;
|
||||||
WeakReferenceMessenger.Default.Send(new LanguageChanged());
|
WeakReferenceMessenger.Default.Send(new LanguageChanged());
|
||||||
@@ -65,20 +69,20 @@ public class TranslationService : ITranslationService
|
|||||||
{
|
{
|
||||||
return
|
return
|
||||||
[
|
[
|
||||||
new AppLanguageModel(AppLanguage.Chinese, "Chinese"),
|
new AppLanguageModel(AppLanguage.Chinese, "Chinese", "zh-CN"),
|
||||||
new AppLanguageModel(AppLanguage.Czech, "Czech"),
|
new AppLanguageModel(AppLanguage.Czech, "Czech", "cs-CZ"),
|
||||||
new AppLanguageModel(AppLanguage.Deutsch, "Deutsch"),
|
new AppLanguageModel(AppLanguage.Deutsch, "Deutsch", "de-DE"),
|
||||||
new AppLanguageModel(AppLanguage.English, "English"),
|
new AppLanguageModel(AppLanguage.English, "English", "en-US"),
|
||||||
new AppLanguageModel(AppLanguage.French, "French"),
|
new AppLanguageModel(AppLanguage.French, "French", "fr-FR"),
|
||||||
new AppLanguageModel(AppLanguage.Italian, "Italian"),
|
new AppLanguageModel(AppLanguage.Italian, "Italian", "it-IT"),
|
||||||
new AppLanguageModel(AppLanguage.Greek, "Greek"),
|
new AppLanguageModel(AppLanguage.Greek, "Greek", "el-GR"),
|
||||||
new AppLanguageModel(AppLanguage.Indonesian, "Indonesian"),
|
new AppLanguageModel(AppLanguage.Indonesian, "Indonesian", "id-ID"),
|
||||||
new AppLanguageModel(AppLanguage.Polish, "Polski"),
|
new AppLanguageModel(AppLanguage.Polish, "Polski", "pl-PL"),
|
||||||
new AppLanguageModel(AppLanguage.PortugeseBrazil, "Portugese-Brazil"),
|
new AppLanguageModel(AppLanguage.PortugeseBrazil, "Portugese-Brazil", "pt-BR"),
|
||||||
new AppLanguageModel(AppLanguage.Russian, "Russian"),
|
new AppLanguageModel(AppLanguage.Russian, "Russian", "ru-RU"),
|
||||||
new AppLanguageModel(AppLanguage.Romanian, "Romanian"),
|
new AppLanguageModel(AppLanguage.Romanian, "Romanian", "ro-RO"),
|
||||||
new AppLanguageModel(AppLanguage.Spanish, "Spanish"),
|
new AppLanguageModel(AppLanguage.Spanish, "Spanish", "es-ES"),
|
||||||
new AppLanguageModel(AppLanguage.Turkish, "Turkish")
|
new AppLanguageModel(AppLanguage.Turkish, "Turkish", "tr-TR")
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user