From 9a63516aba474f6c2f782dcc540708a3aa7de133 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81d=C3=A1m=20Kov=C3=A1cs?= Date: Mon, 7 Aug 2023 17:52:47 +0200 Subject: [PATCH] Console base WIP 2 --- .../FileTime.App.Core/AppInitOptions.cs | 3 ++ .../FileTime.App.Core.csproj | 1 + src/AppCommon/FileTime.App.Core/Init.cs | 47 ++++++++++++++++++ src/AppCommon/FileTime.App.Core/Startup.cs | 13 ++++- .../DependencyInjection.cs | 2 +- src/ConsoleApp/FileTime.ConsoleUI.App/App.cs | 15 +++--- .../FileTime.ConsoleUI.App.csproj | 1 + .../KeyInputHandlerService.cs | 7 +-- .../FileTime.ConsoleUI.App/MainWindow.cs | 24 ++++++++-- .../Services/CustomLoggerSink.cs | 19 ++++++++ .../Services/SystemClipboardService.cs | 18 +++++++ .../FileTime.ConsoleUI.App/Startup.cs | 3 ++ src/ConsoleApp/FileTime.ConsoleUI/DI.cs | 48 ++++++++++++++----- .../FileTime.ConsoleUI.csproj | 5 ++ src/ConsoleApp/FileTime.ConsoleUI/Program.cs | 14 +++++- .../Avalonia/FileTime.GuiApp/App.axaml.cs | 1 - .../Avalonia/FileTime.GuiApp/Program.cs | 43 ++--------------- .../Avalonia/FileTime.GuiApp/Startup.cs | 8 ---- 18 files changed, 193 insertions(+), 79 deletions(-) create mode 100644 src/AppCommon/FileTime.App.Core/AppInitOptions.cs create mode 100644 src/AppCommon/FileTime.App.Core/Init.cs create mode 100644 src/ConsoleApp/FileTime.ConsoleUI.App/Services/CustomLoggerSink.cs create mode 100644 src/ConsoleApp/FileTime.ConsoleUI.App/Services/SystemClipboardService.cs diff --git a/src/AppCommon/FileTime.App.Core/AppInitOptions.cs b/src/AppCommon/FileTime.App.Core/AppInitOptions.cs new file mode 100644 index 0000000..552ffef --- /dev/null +++ b/src/AppCommon/FileTime.App.Core/AppInitOptions.cs @@ -0,0 +1,3 @@ +namespace FileTime.App.Core; + +public record AppInitOptions(string AppDataRoot, string EnvironmentName); \ No newline at end of file diff --git a/src/AppCommon/FileTime.App.Core/FileTime.App.Core.csproj b/src/AppCommon/FileTime.App.Core/FileTime.App.Core.csproj index 7b79224..a0ea7e3 100644 --- a/src/AppCommon/FileTime.App.Core/FileTime.App.Core.csproj +++ b/src/AppCommon/FileTime.App.Core/FileTime.App.Core.csproj @@ -14,6 +14,7 @@ + diff --git a/src/AppCommon/FileTime.App.Core/Init.cs b/src/AppCommon/FileTime.App.Core/Init.cs new file mode 100644 index 0000000..28dd812 --- /dev/null +++ b/src/AppCommon/FileTime.App.Core/Init.cs @@ -0,0 +1,47 @@ +using System.Reflection; + +namespace FileTime.App.Core; + +public static class Init +{ + public static AppInitOptions InitDevelopment() + { + var environmentName = "Development"; + + var appDataRoot = Path.Combine(Environment.CurrentDirectory, "appdata"); + + return new(appDataRoot, environmentName); + } + + public static AppInitOptions InitRelease() + { + var environmentName = "Release"; + + var possibleDataRootsPaths = new List + { + Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "FileTime"), + Path.Combine(Assembly.GetEntryAssembly()?.Location ?? ".", "fallbackDataRoot") + }; + + string? appDataRoot = null; + foreach (var possibleAppDataRoot in possibleDataRootsPaths) + { + try + { + var appDataRootDirectory = new DirectoryInfo(possibleAppDataRoot); + if (!appDataRootDirectory.Exists) appDataRootDirectory.Create(); + + //TODO write test + appDataRoot = possibleAppDataRoot; + break; + } + catch + { + } + } + + return new( + appDataRoot ?? throw new UnauthorizedAccessException(), + environmentName); + } +} \ No newline at end of file diff --git a/src/AppCommon/FileTime.App.Core/Startup.cs b/src/AppCommon/FileTime.App.Core/Startup.cs index 285169f..3efaf2f 100644 --- a/src/AppCommon/FileTime.App.Core/Startup.cs +++ b/src/AppCommon/FileTime.App.Core/Startup.cs @@ -1,9 +1,11 @@ +using FileTime.App.Core.Configuration; using FileTime.App.Core.Services; using FileTime.App.Core.Services.UserCommandHandler; using FileTime.App.Core.StartupServices; using FileTime.App.Core.ViewModels; using FileTime.App.Core.ViewModels.ItemPreview; using FileTime.App.Core.ViewModels.Timeline; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; @@ -11,7 +13,7 @@ namespace FileTime.App.Core; public static class Startup { - public static IServiceCollection AddCoreAppServices(this IServiceCollection serviceCollection) + public static IServiceCollection AddCoreAppServices(this IServiceCollection serviceCollection, IConfigurationRoot configuration) { serviceCollection.TryAddTransient(); serviceCollection.TryAddTransient(); @@ -34,6 +36,7 @@ public static class Startup return serviceCollection .AddCommandHandlers() + .AddConfiguration(configuration) .AddSingleton() .AddSingleton(); } @@ -46,4 +49,12 @@ public static class Startup .AddSingleton() .AddSingleton(); } + + internal static IServiceCollection AddConfiguration(this IServiceCollection serviceCollection, IConfigurationRoot configuration) + { + return serviceCollection + .Configure(configuration.GetSection(SectionNames.ProgramsSectionName)) + .Configure(configuration.GetSection(SectionNames.KeybindingSectionName)) + .AddSingleton(configuration); + } } \ No newline at end of file diff --git a/src/AppCommon/FileTime.App.DependencyInjection/DependencyInjection.cs b/src/AppCommon/FileTime.App.DependencyInjection/DependencyInjection.cs index 8ce5933..e7dc504 100644 --- a/src/AppCommon/FileTime.App.DependencyInjection/DependencyInjection.cs +++ b/src/AppCommon/FileTime.App.DependencyInjection/DependencyInjection.cs @@ -43,7 +43,7 @@ public static class DependencyInjection serviceCollection.AddSingleton(sp => sp.GetRequiredService()); return serviceCollection - .AddCoreAppServices() + .AddCoreAppServices(configuration) .AddLocalProviderServices() .AddLocalAdminProviderServices(configuration) .AddRemoteProviderServices() diff --git a/src/ConsoleApp/FileTime.ConsoleUI.App/App.cs b/src/ConsoleApp/FileTime.ConsoleUI.App/App.cs index 4287d59..35aedf8 100644 --- a/src/ConsoleApp/FileTime.ConsoleUI.App/App.cs +++ b/src/ConsoleApp/FileTime.ConsoleUI.App/App.cs @@ -12,15 +12,17 @@ public class App : IApplication private readonly IConsoleAppState _consoleAppState; private readonly IAppKeyService _appKeyService; private readonly MainWindow _mainWindow; - private readonly IKeyInputHandlerService _keyInputHandlerService = null!; + private readonly IKeyInputHandlerService _keyInputHandlerService; public App( ILifecycleService lifecycleService, + IKeyInputHandlerService keyInputHandlerService, IConsoleAppState consoleAppState, IAppKeyService appKeyService, MainWindow mainWindow) { _lifecycleService = lifecycleService; + _keyInputHandlerService = keyInputHandlerService; _consoleAppState = consoleAppState; _appKeyService = appKeyService; _mainWindow = mainWindow; @@ -28,6 +30,7 @@ public class App : IApplication public void Run() { + Console.WriteLine("Loading..."); Task.Run(async () => await _lifecycleService.InitStartupHandlersAsync()).Wait(); _mainWindow.Initialize(); @@ -41,14 +44,10 @@ public class App : IApplication Application.RootKeyEvent += e => { - if (e.ToGeneralKeyEventArgs(_appKeyService) is { } args) - { - _keyInputHandlerService.HandleKeyInput(args); + if (e.ToGeneralKeyEventArgs(_appKeyService) is not { } args) return false; + _keyInputHandlerService.HandleKeyInput(args); - return args.Handled; - } - - return false; + return args.Handled; }; Application.Run(); diff --git a/src/ConsoleApp/FileTime.ConsoleUI.App/FileTime.ConsoleUI.App.csproj b/src/ConsoleApp/FileTime.ConsoleUI.App/FileTime.ConsoleUI.App.csproj index da8e67d..1cea262 100644 --- a/src/ConsoleApp/FileTime.ConsoleUI.App/FileTime.ConsoleUI.App.csproj +++ b/src/ConsoleApp/FileTime.ConsoleUI.App/FileTime.ConsoleUI.App.csproj @@ -12,6 +12,7 @@ + diff --git a/src/ConsoleApp/FileTime.ConsoleUI.App/KeyInputHandling/KeyInputHandlerService.cs b/src/ConsoleApp/FileTime.ConsoleUI.App/KeyInputHandling/KeyInputHandlerService.cs index 1577b66..2eda004 100644 --- a/src/ConsoleApp/FileTime.ConsoleUI.App/KeyInputHandling/KeyInputHandlerService.cs +++ b/src/ConsoleApp/FileTime.ConsoleUI.App/KeyInputHandling/KeyInputHandlerService.cs @@ -16,23 +16,24 @@ public class KeyInputHandlerService : IKeyInputHandlerService public KeyInputHandlerService( IAppState appState, - IDefaultModeKeyInputHandler defaultModeKeyInputHandler, + IDefaultModeKeyInputHandler defaultModeKeyInputHandler, IRapidTravelModeKeyInputHandler rapidTravelModeKeyInputHandler) { _appState = appState; _defaultModeKeyInputHandler = defaultModeKeyInputHandler; _rapidTravelModeKeyInputHandler = rapidTravelModeKeyInputHandler; } + public void HandleKeyInput(GeneralKeyEventArgs keyEvent) { var specialKeysStatus = new SpecialKeysStatus(_isAltPressed, _isShiftPressed, _isCtrlPressed); if (_appState.ViewMode.Value == ViewMode.Default) { - _defaultModeKeyInputHandler.HandleInputKey(keyEvent, specialKeysStatus); + Task.Run(async () => await _defaultModeKeyInputHandler.HandleInputKey(keyEvent, specialKeysStatus)).Wait(); } else { - _rapidTravelModeKeyInputHandler.HandleInputKey(keyEvent, specialKeysStatus); + Task.Run(async () => await _rapidTravelModeKeyInputHandler.HandleInputKey(keyEvent, specialKeysStatus)).Wait(); } } } \ No newline at end of file diff --git a/src/ConsoleApp/FileTime.ConsoleUI.App/MainWindow.cs b/src/ConsoleApp/FileTime.ConsoleUI.App/MainWindow.cs index 383e926..d96feb1 100644 --- a/src/ConsoleApp/FileTime.ConsoleUI.App/MainWindow.cs +++ b/src/ConsoleApp/FileTime.ConsoleUI.App/MainWindow.cs @@ -1,7 +1,9 @@ -using DeclarativeProperty; +using System.Collections.ObjectModel; +using DeclarativeProperty; using FileTime.App.Core.ViewModels; using FileTime.ConsoleUI.App.Controls; using FileTime.Core.Models; +using ObservableComputations; using Terminal.Gui; namespace FileTime.ConsoleUI.App; @@ -17,12 +19,12 @@ public class MainWindow _selectedItemsView = new() {X = 1, Y = 0, Width = Dim.Fill(), Height = Dim.Fill()}; _selectedItemsView.AddKeyBinding(Key.Space, Command.ToggleChecked); - _selectedItemsView.OpenSelectedItem += (e) => + /*_selectedItemsView.OpenSelectedItem += (e) => { if (e.Value is IItemViewModel {BaseItem: IContainer container} && consoleAppState.SelectedTab.Value?.Tab is { } tab) tab.SetCurrentLocation(container); - }; + };*/ } public void Initialize() @@ -32,6 +34,22 @@ public class MainWindow .Map(t => t.CurrentItems) .Switch(); + var selectedItem = _consoleAppState.SelectedTab + .Map(t => t.CurrentSelectedItem) + .Switch(); + + DeclarativePropertyHelpers.CombineLatest( + selectedItem, + selectedsItems, + (selected, items) => Task.FromResult(items.IndexOf(selected))) + .Subscribe((index, _) => + { + if (index == -1) return; + _selectedItemsView.SelectedItem = index; + _selectedItemsView.EnsureSelectedItemVisible(); + _selectedItemsView.SetNeedsDisplay(); + }); + var renderer = new ItemRenderer(selectedsItems, _selectedItemsView); _selectedItemsView.Source = renderer; } diff --git a/src/ConsoleApp/FileTime.ConsoleUI.App/Services/CustomLoggerSink.cs b/src/ConsoleApp/FileTime.ConsoleUI.App/Services/CustomLoggerSink.cs new file mode 100644 index 0000000..a3b0fa3 --- /dev/null +++ b/src/ConsoleApp/FileTime.ConsoleUI.App/Services/CustomLoggerSink.cs @@ -0,0 +1,19 @@ +using System.Diagnostics; +using Serilog.Core; +using Serilog.Events; + +namespace FileTime.ConsoleUI.App.Services; + +public class CustomLoggerSink : ILogEventSink +{ + public void Emit(LogEvent logEvent) + { + if (logEvent.Level >= LogEventLevel.Error) + { + var message = logEvent.RenderMessage(); + if (logEvent.Exception is not null) + message += $" {logEvent.Exception.Message}"; + Debug.WriteLine(message); + } + } +} \ No newline at end of file diff --git a/src/ConsoleApp/FileTime.ConsoleUI.App/Services/SystemClipboardService.cs b/src/ConsoleApp/FileTime.ConsoleUI.App/Services/SystemClipboardService.cs new file mode 100644 index 0000000..d4777b1 --- /dev/null +++ b/src/ConsoleApp/FileTime.ConsoleUI.App/Services/SystemClipboardService.cs @@ -0,0 +1,18 @@ +using FileTime.App.Core.Services; +using FileTime.Core.Models; +using Terminal.Gui; + +namespace FileTime.ConsoleUI.App.Services; + +public class SystemClipboardService : ISystemClipboardService +{ + public Task CopyToClipboardAsync(string text) + { + Clipboard.TrySetClipboardData(text); + return Task.CompletedTask; + } + + public Task> GetFilesAsync() => throw new NotImplementedException(); + + public Task SetFilesAsync(IEnumerable files) => throw new NotImplementedException(); +} \ No newline at end of file diff --git a/src/ConsoleApp/FileTime.ConsoleUI.App/Startup.cs b/src/ConsoleApp/FileTime.ConsoleUI.App/Startup.cs index bf1fc88..1990aad 100644 --- a/src/ConsoleApp/FileTime.ConsoleUI.App/Startup.cs +++ b/src/ConsoleApp/FileTime.ConsoleUI.App/Startup.cs @@ -1,6 +1,7 @@ using FileTime.App.Core.Services; using FileTime.App.Core.ViewModels; using FileTime.ConsoleUI.App.KeyInputHandling; +using FileTime.ConsoleUI.App.Services; using FileTime.Core.Interactions; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; @@ -19,6 +20,8 @@ public static class Startup services.TryAddSingleton(); services.TryAddSingleton(); services.TryAddSingleton, ConsoleAppKeyService>(); + services.TryAddSingleton(); + services.AddSingleton(); return services; } diff --git a/src/ConsoleApp/FileTime.ConsoleUI/DI.cs b/src/ConsoleApp/FileTime.ConsoleUI/DI.cs index f5d41dc..20b9ac5 100644 --- a/src/ConsoleApp/FileTime.ConsoleUI/DI.cs +++ b/src/ConsoleApp/FileTime.ConsoleUI/DI.cs @@ -4,6 +4,7 @@ using FileTime.App.DependencyInjection; using FileTime.App.FrequencyNavigation; using FileTime.App.Search; using FileTime.ConsoleUI.App; +using FileTime.ConsoleUI.App.Services; using FileTime.Providers.Local; using FileTime.Server.Common; using FileTime.Tools.Compression; @@ -13,21 +14,42 @@ using Serilog; namespace FileTime.ConsoleUI; -public class DI +public static class DI { - public static IServiceProvider ServiceProvider { get; set; } = null!; + public static IServiceProvider ServiceProvider { get; private set; } = null!; public static void Initialize(IConfigurationRoot configuration) => ServiceProvider = DependencyInjection - .RegisterDefaultServices(configuration: configuration) - .AddConsoleServices() - .AddLocalProviderServices() - .AddServerCoreServices() - .AddFrequencyNavigation() - .AddCommandPalette() - .AddContainerSizeScanner() - .AddSearch() - .AddCompression() - .AddLogging(loggingBuilder => loggingBuilder.AddSerilog()) - .BuildServiceProvider(); + .RegisterDefaultServices(configuration: configuration) + .AddConsoleServices() + .AddLocalProviderServices() + .AddServerCoreServices() + .AddFrequencyNavigation() + .AddCommandPalette() + .AddContainerSizeScanner() + .AddSearch() + .AddCompression() + .SetupLogging() + .AddLogging(loggingBuilder => loggingBuilder.AddSerilog()) + .BuildServiceProvider(); + + + private static IServiceCollection SetupLogging(this IServiceCollection serviceCollection) => + serviceCollection.AddSerilog( + (serviceProvider, loggerConfiguration) => + { + loggerConfiguration +#if DEBUG || VERBOSE_LOGGING + .MinimumLevel.Verbose() +#endif + .ReadFrom.Configuration(serviceProvider.GetRequiredService()) + .Enrich.FromLogContext() + .WriteTo.File( + Path.Combine(Program.AppDataRoot, "logs", "appLog.log"), + fileSizeLimitBytes: 10 * 1024 * 1024, + rollingInterval: RollingInterval.Day, + rollOnFileSizeLimit: true) + .WriteTo.Sink(serviceProvider.GetRequiredService()); + } + ); } \ No newline at end of file diff --git a/src/ConsoleApp/FileTime.ConsoleUI/FileTime.ConsoleUI.csproj b/src/ConsoleApp/FileTime.ConsoleUI/FileTime.ConsoleUI.csproj index 82a9cbd..dfd6801 100644 --- a/src/ConsoleApp/FileTime.ConsoleUI/FileTime.ConsoleUI.csproj +++ b/src/ConsoleApp/FileTime.ConsoleUI/FileTime.ConsoleUI.csproj @@ -23,6 +23,11 @@ + + + + + diff --git a/src/ConsoleApp/FileTime.ConsoleUI/Program.cs b/src/ConsoleApp/FileTime.ConsoleUI/Program.cs index a971185..b59fbe8 100644 --- a/src/ConsoleApp/FileTime.ConsoleUI/Program.cs +++ b/src/ConsoleApp/FileTime.ConsoleUI/Program.cs @@ -1,9 +1,13 @@ -using FileTime.ConsoleUI; +using FileTime.App.Core; +using FileTime.App.Core.Configuration; +using FileTime.ConsoleUI; using FileTime.ConsoleUI.App; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +(AppDataRoot, EnvironmentName) = Init.InitDevelopment(); var configuration = new ConfigurationBuilder() + .AddInMemoryCollection(MainConfiguration.Configuration) #if DEBUG .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) #endif @@ -11,4 +15,10 @@ var configuration = new ConfigurationBuilder() DI.Initialize(configuration); var app = DI.ServiceProvider.GetRequiredService(); -app.Run(); \ No newline at end of file +app.Run(); + +public partial class Program +{ + public static string AppDataRoot { get; private set; } + public static string EnvironmentName { get; private set; } +} \ No newline at end of file diff --git a/src/GuiApp/Avalonia/FileTime.GuiApp/App.axaml.cs b/src/GuiApp/Avalonia/FileTime.GuiApp/App.axaml.cs index 6336cd5..59a5d62 100644 --- a/src/GuiApp/Avalonia/FileTime.GuiApp/App.axaml.cs +++ b/src/GuiApp/Avalonia/FileTime.GuiApp/App.axaml.cs @@ -29,7 +29,6 @@ public class Application : Avalonia.Application .AddContainerSizeScanner() .AddSearch() .AddCompression() - .AddConfiguration(configuration) .ConfigureFont(configuration) .RegisterLogging() .RegisterServices() diff --git a/src/GuiApp/Avalonia/FileTime.GuiApp/Program.cs b/src/GuiApp/Avalonia/FileTime.GuiApp/Program.cs index 9fe141c..9a26c92 100644 --- a/src/GuiApp/Avalonia/FileTime.GuiApp/Program.cs +++ b/src/GuiApp/Avalonia/FileTime.GuiApp/Program.cs @@ -8,6 +8,7 @@ using System.Runtime.ExceptionServices; using System.Threading.Tasks; using Avalonia; using Avalonia.ReactiveUI; +using FileTime.App.Core; using Serilog; using Serilog.Debugging; @@ -18,43 +19,6 @@ public static class Program public static string AppDataRoot { get; private set; } public static string EnvironmentName { get; private set; } - private static void InitDevelopment() - { - EnvironmentName = "Development"; - - AppDataRoot = Path.Combine(Environment.CurrentDirectory, "appdata"); - } - - private static void InitRelease() - { - EnvironmentName = "Release"; - - var possibleDataRootsPaths = new List - { - Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "FileTime"), - Path.Combine(Assembly.GetEntryAssembly()?.Location ?? ".", "fallbackDataRoot") - }; - - string? appDataRoot = null; - foreach (var possibleAppDataRoot in possibleDataRootsPaths) - { - try - { - var appDataRootDirectory = new DirectoryInfo(possibleAppDataRoot); - if (!appDataRootDirectory.Exists) appDataRootDirectory.Create(); - - //TODO write test - appDataRoot = possibleAppDataRoot; - break; - } - catch - { - } - } - - AppDataRoot = appDataRoot ?? throw new UnauthorizedAccessException(); - } - private static void InitLogging() { SelfLog.Enable(l => Debug.WriteLine(l)); @@ -83,12 +47,13 @@ public static class Program public static void Main(string[] args) { #if DEBUG - InitDevelopment(); + (AppDataRoot, EnvironmentName) = Init.InitDevelopment(); #endif if (AppDataRoot is null) { - InitRelease(); + (AppDataRoot, EnvironmentName) = Init.InitRelease(); } + InitLogging(); Log.Logger.Information("Early app starting..."); diff --git a/src/GuiApp/Avalonia/FileTime.GuiApp/Startup.cs b/src/GuiApp/Avalonia/FileTime.GuiApp/Startup.cs index 8fb9da2..c256a06 100644 --- a/src/GuiApp/Avalonia/FileTime.GuiApp/Startup.cs +++ b/src/GuiApp/Avalonia/FileTime.GuiApp/Startup.cs @@ -105,12 +105,4 @@ public static class Startup return serviceCollection; } - - internal static IServiceCollection AddConfiguration(this IServiceCollection serviceCollection, IConfigurationRoot configuration) - { - return serviceCollection - .Configure(configuration.GetSection(SectionNames.ProgramsSectionName)) - .Configure(configuration.GetSection(SectionNames.KeybindingSectionName)) - .AddSingleton(configuration); - } } \ No newline at end of file