Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 61 additions & 59 deletions AutoDarkModeApp/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,54 +57,60 @@ public App()

InitializeComponent();

Host = Microsoft.Extensions.Hosting.Host.
CreateDefaultBuilder().
UseContentRoot(AppContext.BaseDirectory).
ConfigureServices((context, services) =>
{
// Services
services.AddSingleton<ILocalSettingsService, LocalSettingsService>();
services.AddSingleton<IFileService, FileService>();

services.AddSingleton<IActivationService, ActivationService>();
services.AddSingleton<IPageService, PageService>();
services.AddSingleton<INavigationService, NavigationService>();

services.AddSingleton<IErrorService, ErrorService>();
services.AddSingleton<IGeolocatorService, GeolocatorService>();

// Views and ViewModels
services.AddTransient<ThemePickerViewModel>();
services.AddTransient<ThemePickerPage>();
services.AddTransient<CursorsViewModel>();
services.AddTransient<CursorsPage>();
services.AddTransient<ColorizationViewModel>();
services.AddTransient<ColorizationPage>();
services.AddTransient<SettingsViewModel>();
services.AddTransient<SettingsPage>();
services.AddTransient<AboutViewModel>();
services.AddTransient<AboutPage>();
services.AddTransient<DonationViewModel>();
services.AddTransient<DonationPage>();
services.AddTransient<ScriptsViewModel>();
services.AddTransient<ScriptsPage>();
services.AddTransient<PersonalizationViewModel>();
services.AddTransient<PersonalizationPage>();
services.AddTransient<SystemAreasViewModel>();
services.AddTransient<SystemAreasPage>();
services.AddTransient<ConditionsViewModel>();
services.AddTransient<ConditionsPage>();
services.AddTransient<HotkeysViewModel>();
services.AddTransient<HotkeysPage>();
services.AddTransient<WallpaperPickerViewModel>();
services.AddTransient<WallpaperPickerPage>();
services.AddTransient<TimeViewModel>();
services.AddTransient<TimePage>();

// Configuration
services.Configure<LocalSettingsOptions>(context.Configuration.GetSection(nameof(LocalSettingsOptions)));
}).
Build();
Host = Microsoft
.Extensions.Hosting.Host.CreateDefaultBuilder()
.UseContentRoot(AppContext.BaseDirectory)
.ConfigureServices(
(context, services) =>
{
// Services
services.AddSingleton<ILocalSettingsService, LocalSettingsService>();
services.AddSingleton<IFileService, FileService>();

services.AddSingleton<IActivationService, ActivationService>();
services.AddSingleton<ICloseService, CloseService>();
services.AddSingleton<IPageService, PageService>();
services.AddSingleton<INavigationService, NavigationService>();

services.AddSingleton<IErrorService, ErrorService>();
services.AddSingleton<IGeolocatorService, GeolocatorService>();

// Window
services.AddSingleton<MainWindow>();

// Views and ViewModels
services.AddTransient<ThemePickerViewModel>();
services.AddTransient<ThemePickerPage>();
services.AddTransient<CursorsViewModel>();
services.AddTransient<CursorsPage>();
services.AddTransient<ColorizationViewModel>();
services.AddTransient<ColorizationPage>();
services.AddTransient<SettingsViewModel>();
services.AddTransient<SettingsPage>();
services.AddTransient<AboutViewModel>();
services.AddTransient<AboutPage>();
services.AddTransient<DonationViewModel>();
services.AddTransient<DonationPage>();
services.AddTransient<ScriptsViewModel>();
services.AddTransient<ScriptsPage>();
services.AddTransient<PersonalizationViewModel>();
services.AddTransient<PersonalizationPage>();
services.AddTransient<SystemAreasViewModel>();
services.AddTransient<SystemAreasPage>();
services.AddTransient<ConditionsViewModel>();
services.AddTransient<ConditionsPage>();
services.AddTransient<HotkeysViewModel>();
services.AddTransient<HotkeysPage>();
services.AddTransient<WallpaperPickerViewModel>();
services.AddTransient<WallpaperPickerPage>();
services.AddTransient<TimeViewModel>();
services.AddTransient<TimePage>();

// Configuration
services.Configure<LocalSettingsOptions>(context.Configuration.GetSection(nameof(LocalSettingsOptions)));
}
)
.Build();

UnhandledException += App_UnhandledException;
}
Expand All @@ -129,20 +135,16 @@ protected async override void OnLaunched(LaunchActivatedEventArgs args)

// Set App and Svc language
Microsoft.Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride = await LanguageHelper.GetDefaultLanguageAsync();
var builder = AdmConfigBuilder.Instance();
builder.Load();
try
await Task.Run(() =>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this block changed?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because ActivationService starts to execute after the language is loaded, configuration file loading does not need to block UI threads, and it also unifies asynchronous business logic. (There won't even be performance improvement, but it looks much better visually)

{
builder.Config.Tunable.UICulture = LanguageHelper.SelectedLanguageCode; // save before activation SVC (think of first-launch scenario)
var builder = AdmConfigBuilder.Instance();
builder.Load();
builder.Config.Tunable.UICulture = LanguageHelper.SelectedLanguageCode;
builder.Save();
}
catch (Exception)
{
// We can't show a dialog here
//await App.GetService<IErrorService>().ShowErrorMessage(ex, App.MainWindow.Content.XamlRoot, "Startup", "Failed to force-set Svc language");
}
});

MainWindow = new MainWindow();
MainWindow = App.GetService<MainWindow>();
MainWindow.Closed += async (s, e) => await App.GetService<ICloseService>().CloseAsync();

await App.GetService<IActivationService>().ActivateAsync(args);
}
Expand Down
6 changes: 6 additions & 0 deletions AutoDarkModeApp/Contracts/Services/ICloseService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace AutoDarkModeApp.Contracts.Services;

public interface ICloseService
{
Task CloseAsync();
}
6 changes: 3 additions & 3 deletions AutoDarkModeApp/Helpers/LanguageHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ public static class LanguageHelper
{
public static string SelectedLanguageCode { get; set; } = "en-US"; // equal to <DefaultLanguage>

private static readonly ILocalSettingsService _localSettingsService = App.GetService<ILocalSettingsService>()!;
public static readonly string[] SupportedCultures =
[
// Left-to-Right (LTR) languages
Expand All @@ -23,7 +22,8 @@ public static class LanguageHelper

public static async Task<string> GetDefaultLanguageAsync()
{
var language = await _localSettingsService.ReadSettingAsync<string>("SelectedLanguageCode");
var localSettingsService = App.GetService<ILocalSettingsService>();
var language = await localSettingsService.ReadSettingAsync<string>("SelectedLanguageCode");
if (!string.IsNullOrEmpty(language) && SupportedCultures.Contains(language))
{
SelectedLanguageCode = language;
Expand Down Expand Up @@ -56,7 +56,7 @@ public static async Task<string> GetDefaultLanguageAsync()
}
// else keep the default "en-US"
}
await _localSettingsService.SaveSettingAsync("SelectedLanguageCode", SelectedLanguageCode);
await localSettingsService.SaveSettingAsync("SelectedLanguageCode", SelectedLanguageCode);
}
return SelectedLanguageCode;
}
Expand Down
43 changes: 2 additions & 41 deletions AutoDarkModeApp/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,11 @@ public sealed partial class MainWindow : Window
{
private readonly INavigationService _navigationService;

public MainWindow()
public MainWindow(INavigationService navigationService)
{
_navigationService = App.GetService<INavigationService>();
_navigationService = navigationService;
InitializeComponent();

// TODO: Set the title bar icon by updating /Assets/WindowIcon.ico.
// A custom title bar is required for full window theme and Mica support.
// https://docs.microsoft.com/windows/apps/develop/title-bar?tabs=winui3#full-customization
ExtendsContentIntoTitleBar = true;
SetTitleBar(TitleBar);
TitleBar.Subtitle = Debugger.IsAttached ? "Debug" : "";
Expand Down Expand Up @@ -49,10 +46,7 @@ public MainWindow()

_navigationService.Frame = NavigationFrame;
_navigationService.InitializeNavigationView(NavigationViewControl);

_navigationService.InitializeBreadcrumbBar(BreadcrumBarControl);

Closed += MainWindow_Closed;
}

private void NavViewTitleBar_BackRequested(Microsoft.UI.Xaml.Controls.TitleBar sender, object args)
Expand All @@ -73,37 +67,4 @@ private void ApplySystemThemeToCaptionButtons()
var backgroundHoverColor = TitleBar.ActualTheme == ElementTheme.Dark ? Color.FromArgb(20, 255, 255, 255) : Color.FromArgb(40, 0, 0, 0);
AppWindow.TitleBar.ButtonHoverBackgroundColor = backgroundHoverColor;
}

private async void MainWindow_Closed(object sender, WindowEventArgs args)
{
var presenter = AppWindow.Presenter as OverlappedPresenter;
var position = AppWindow.Position;
var size = AppWindow.Size;
var localSettings = App.GetService<ILocalSettingsService>();
await Task.Run(async () =>
{
if (presenter != null)
{
await localSettings.SaveSettingAsync("WindowState", (int)presenter.State);

if (presenter.State == OverlappedPresenterState.Restored)
{
await localSettings.SaveSettingAsync("X", position.X);
await localSettings.SaveSettingAsync("Y", position.Y);
await localSettings.SaveSettingAsync("Width", size.Width);
await localSettings.SaveSettingAsync("Height", size.Height);
}
}

//TODO: MapLocationFinder will make WinUI app hang on exit, more information on https://github.com/microsoft/microsoft-ui-xaml/issues/10229
try
{
Process.GetCurrentProcess().Kill();
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
});
}
}
26 changes: 26 additions & 0 deletions AutoDarkModeApp/Services/CloseService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using AutoDarkModeApp.Contracts.Services;
using Microsoft.UI.Windowing;

namespace AutoDarkModeApp.Services;

public class CloseService(ILocalSettingsService localSettingsService) : ICloseService
{
public async Task CloseAsync()
{
if (App.MainWindow.AppWindow.Presenter is OverlappedPresenter presenter)
{
var position = App.MainWindow.AppWindow.Position;
var size = App.MainWindow.AppWindow.Size;

await localSettingsService.SaveSettingAsync("WindowState", (int)presenter.State);

if (presenter.State == OverlappedPresenterState.Restored)
{
await localSettingsService.SaveSettingAsync("X", position.X);
await localSettingsService.SaveSettingAsync("Y", position.Y);
await localSettingsService.SaveSettingAsync("Width", size.Width);
await localSettingsService.SaveSettingAsync("Height", size.Height);
}
}
}
}