diff --git a/src/AppCommon/FileTime.App.Core/Services/Persistence/TabPersistenceService.cs b/src/AppCommon/FileTime.App.Core/Services/Persistence/TabPersistenceService.cs index d66fe50..48a4ed1 100644 --- a/src/AppCommon/FileTime.App.Core/Services/Persistence/TabPersistenceService.cs +++ b/src/AppCommon/FileTime.App.Core/Services/Persistence/TabPersistenceService.cs @@ -70,7 +70,8 @@ public class TabPersistenceService : ITabPersistenceService foreach (var (requestedTabNumber, nativePath) in _tabsToOpen.TabsToOpen) { - if (await _timelessContentProvider.GetItemByNativePathAsync(nativePath) is not IContainer container) continue; + if (await _timelessContentProvider.GetItemByNativePathAsync(nativePath) is not IContainer container) + continue; containers.Add((requestedTabNumber, container)); } @@ -111,14 +112,16 @@ public class TabPersistenceService : ITabPersistenceService return Task.CompletedTask; } - private async Task> LoadStatesAsync(bool createEmptyIfNecessary, CancellationToken token = default) + private async Task> LoadStatesAsync( + bool createEmptyIfNecessary, + CancellationToken token = default) { if (!File.Exists(_settingsPath) || !_tabPersistenceSettings.LoadState) { if (createEmptyIfNecessary) { var tabViewModel = await CreateEmptyTab(); - return new[] {tabViewModel}; + return new[] { tabViewModel }; } return Enumerable.Empty(); @@ -142,7 +145,7 @@ public class TabPersistenceService : ITabPersistenceService if (createEmptyIfNecessary) { var tabViewModel = await CreateEmptyTab(); - return new[] {tabViewModel}; + return new[] { tabViewModel }; } return Enumerable.Empty(); @@ -162,7 +165,8 @@ public class TabPersistenceService : ITabPersistenceService // ignored } - var tab = await _serviceProvider.GetAsyncInitableResolver(currentDirectory ?? _localContentProvider) + var tab = await _serviceProvider + .GetAsyncInitableResolver(currentDirectory ?? _localContentProvider) .GetRequiredServiceAsync(); var tabViewModel = _serviceProvider.GetInitableResolver(tab, 1).GetRequiredService(); @@ -265,8 +269,7 @@ public class TabPersistenceService : ITabPersistenceService foreach (var tab in _appState.Tabs) { var currentLocation = tab.CurrentLocation.Value; - if (currentLocation is null) continue; - var path = currentLocation.FullName!.Path; + if (currentLocation?.FullName?.Path is not { } path) continue; if (currentLocation.GetExtension()?.RealContainer() is { } realPath) { diff --git a/src/GuiApp/Avalonia/FileTime.GuiApp.App/ViewModels/MainWindowViewModel.cs b/src/GuiApp/Avalonia/FileTime.GuiApp.App/ViewModels/MainWindowViewModel.cs index 544e55f..2a20832 100644 --- a/src/GuiApp/Avalonia/FileTime.GuiApp.App/ViewModels/MainWindowViewModel.cs +++ b/src/GuiApp/Avalonia/FileTime.GuiApp.App/ViewModels/MainWindowViewModel.cs @@ -85,7 +85,11 @@ public partial class MainWindowViewModel : IMainWindowViewModel _modalService.AllModalClosed += (_, _) => FocusDefaultElement?.Invoke(); _instanceMessageHandler.ShowWindow += () => ShowWindow?.Invoke(); - Task.Run(async () => await _lifecycleService.InitStartupHandlersAsync()).Wait(); + Task.Run(async () => + { + await Task.Delay(100); + await _lifecycleService.InitStartupHandlersAsync(); + }); } public void ProcessKeyDown(KeyEventArgs e) diff --git a/src/GuiApp/Avalonia/FileTime.GuiApp.App/Views/MainWindow.axaml.cs b/src/GuiApp/Avalonia/FileTime.GuiApp.App/Views/MainWindow.axaml.cs index 7fed076..71424d2 100644 --- a/src/GuiApp/Avalonia/FileTime.GuiApp.App/Views/MainWindow.axaml.cs +++ b/src/GuiApp/Avalonia/FileTime.GuiApp.App/Views/MainWindow.axaml.cs @@ -51,39 +51,46 @@ public partial class MainWindow : Window, IUiAccessor _initializer = initializer; } - private void OnWindowOpened(object sender, EventArgs e) + private async void OnWindowOpened(object sender, EventArgs e) { - if (DataContext is not MainWindowViewModel && !Design.IsDesignMode) + try { - _initializer?.Invoke(); - - _logger = DI.ServiceProvider.GetService>(); - _modalService = DI.ServiceProvider.GetRequiredService(); - DI.ServiceProvider.GetRequiredService().UiAccessor = this; - - ReadInputContainer.PropertyChanged += ReadInputContainerOnPropertyChanged; - - _logger?.LogInformation( - $"{nameof(MainWindow)} opened, starting {nameof(MainWindowViewModel)} initialization..."); - - try + if (DataContext is not MainWindowViewModel && !Design.IsDesignMode) { - var viewModel = DI.ServiceProvider.GetRequiredService(); - viewModel.FocusDefaultElement = () => Focus(); - viewModel.ShowWindow = Activate; - ViewModel = viewModel; - } - catch (Exception ex) - { - _logger?.LogError(ex, "Error initializing {ViewModel}", nameof(MainWindowViewModel)); - if (DataContext is IMainWindowViewModelBase mainWindowViewModelBase) + await Task.Delay(100); + _initializer?.Invoke(); + + _logger = DI.ServiceProvider.GetService>(); + _modalService = DI.ServiceProvider.GetRequiredService(); + DI.ServiceProvider.GetRequiredService().UiAccessor = this; + + ReadInputContainer.PropertyChanged += ReadInputContainerOnPropertyChanged; + + _logger?.LogInformation( + $"{nameof(MainWindow)} opened, starting {nameof(MainWindowViewModel)} initialization..."); + + try { - mainWindowViewModelBase.FatalError.SetValueSafe( - $"Error initializing {nameof(MainWindowViewModel)}: " + ex.Message - ); + var viewModel = DI.ServiceProvider.GetRequiredService(); + viewModel.FocusDefaultElement = () => Focus(); + viewModel.ShowWindow = Activate; + ViewModel = viewModel; + } + catch (Exception ex) + { + _logger?.LogError(ex, "Error initializing {ViewModel}", nameof(MainWindowViewModel)); + if (DataContext is IMainWindowViewModelBase mainWindowViewModelBase) + { + mainWindowViewModelBase.FatalError.SetValueSafe( + $"Error initializing {nameof(MainWindowViewModel)}: " + ex.Message + ); + } } } } + catch + { + } } private void OnKeyDown(object sender, KeyEventArgs e) diff --git a/src/GuiApp/Avalonia/FileTime.GuiApp/App.axaml.cs b/src/GuiApp/Avalonia/FileTime.GuiApp/App.axaml.cs index 1e079a2..2de7685 100644 --- a/src/GuiApp/Avalonia/FileTime.GuiApp/App.axaml.cs +++ b/src/GuiApp/Avalonia/FileTime.GuiApp/App.axaml.cs @@ -16,6 +16,7 @@ using FileTime.Server; using FileTime.Tools.Compression; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +using Serilog; namespace FileTime.GuiApp; @@ -23,6 +24,7 @@ public class Application : Avalonia.Application { private static void InitializeApp() { + Log.Logger.Information("App initialization starting..."); var configuration = Startup.CreateConfiguration(); var services = DependencyInjection .RegisterDefaultServices(configuration: configuration) @@ -62,6 +64,7 @@ public class Application : Avalonia.Application { if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) { + Log.Logger.Information("Creating MainWindow instance..."); desktop.MainWindow = new MainWindow(InitializeApp) { DataContext = new MainWindowLoadingViewModel(), diff --git a/src/GuiApp/Avalonia/FileTime.GuiApp/Program.cs b/src/GuiApp/Avalonia/FileTime.GuiApp/Program.cs index 5194786..7db8e00 100644 --- a/src/GuiApp/Avalonia/FileTime.GuiApp/Program.cs +++ b/src/GuiApp/Avalonia/FileTime.GuiApp/Program.cs @@ -22,7 +22,7 @@ public static class Program public static string EnvironmentName { get; private set; } = null!; private static ILogger _logger = null!; - + internal static List DirectoriesToOpen { get; } = new(); private static void InitLogging() @@ -41,7 +41,8 @@ public static class Program .WriteTo.File( Path.Combine(logFolder, "appLog.log"), fileSizeLimitBytes: 10 * 1024 * 1024, - outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] [{SourceContext}] {Message:lj}{NewLine}{Exception}", + outputTemplate: + "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] [{SourceContext}] {Message:lj}{NewLine}{Exception}", rollingInterval: RollingInterval.Day, rollOnFileSizeLimit: true) .CreateBootstrapLogger(); @@ -128,15 +129,16 @@ public static class Program { Log.CloseAndFlush(); } - } // Avalonia configuration, don't remove; also used by visual designer. public static AppBuilder BuildAvaloniaApp() => AppBuilder.Configure() .UsePlatformDetect() - .UseReactiveUI() - .LogToTrace(); +#if DEBUG + .LogToTrace() +#endif + ; private static void OnTaskSchedulerUnobservedTaskException(object? sender, UnobservedTaskExceptionEventArgs e) => HandleUnhandledException(sender, e.Exception);