Console base WIP 2

This commit is contained in:
2023-08-07 17:52:47 +02:00
parent b9adbc8272
commit 9a63516aba
18 changed files with 193 additions and 79 deletions

View File

@@ -0,0 +1,3 @@
namespace FileTime.App.Core;
public record AppInitOptions(string AppDataRoot, string EnvironmentName);

View File

@@ -14,6 +14,7 @@
<PackageReference Include="Humanizer.Core" Version="2.14.1" /> <PackageReference Include="Humanizer.Core" Version="2.14.1" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="7.0.1" /> <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="7.0.1" />
<PackageReference Include="Microsoft.Extensions.Options" Version="7.0.0" /> <PackageReference Include="Microsoft.Extensions.Options" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="7.0.0" />
<PackageReference Include="morelinq" Version="3.4.2" /> <PackageReference Include="morelinq" Version="3.4.2" />
<PackageReference Include="MvvmGen" Version="1.2.1" /> <PackageReference Include="MvvmGen" Version="1.2.1" />
<PackageReference Include="ObservableComputations" Version="2.3.0" /> <PackageReference Include="ObservableComputations" Version="2.3.0" />

View File

@@ -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<string>
{
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);
}
}

View File

@@ -1,9 +1,11 @@
using FileTime.App.Core.Configuration;
using FileTime.App.Core.Services; using FileTime.App.Core.Services;
using FileTime.App.Core.Services.UserCommandHandler; using FileTime.App.Core.Services.UserCommandHandler;
using FileTime.App.Core.StartupServices; using FileTime.App.Core.StartupServices;
using FileTime.App.Core.ViewModels; using FileTime.App.Core.ViewModels;
using FileTime.App.Core.ViewModels.ItemPreview; using FileTime.App.Core.ViewModels.ItemPreview;
using FileTime.App.Core.ViewModels.Timeline; using FileTime.App.Core.ViewModels.Timeline;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.DependencyInjection.Extensions;
@@ -11,7 +13,7 @@ namespace FileTime.App.Core;
public static class Startup public static class Startup
{ {
public static IServiceCollection AddCoreAppServices(this IServiceCollection serviceCollection) public static IServiceCollection AddCoreAppServices(this IServiceCollection serviceCollection, IConfigurationRoot configuration)
{ {
serviceCollection.TryAddTransient<ITabViewModel, TabViewModel>(); serviceCollection.TryAddTransient<ITabViewModel, TabViewModel>();
serviceCollection.TryAddTransient<IContainerViewModel, ContainerViewModel>(); serviceCollection.TryAddTransient<IContainerViewModel, ContainerViewModel>();
@@ -34,6 +36,7 @@ public static class Startup
return serviceCollection return serviceCollection
.AddCommandHandlers() .AddCommandHandlers()
.AddConfiguration(configuration)
.AddSingleton<IStartupHandler, DefaultIdentifiableCommandHandlerRegister>() .AddSingleton<IStartupHandler, DefaultIdentifiableCommandHandlerRegister>()
.AddSingleton<IExitHandler, ContainerRefreshHandler>(); .AddSingleton<IExitHandler, ContainerRefreshHandler>();
} }
@@ -46,4 +49,12 @@ public static class Startup
.AddSingleton<IUserCommandHandler, ToolUserCommandHandlerService>() .AddSingleton<IUserCommandHandler, ToolUserCommandHandlerService>()
.AddSingleton<IUserCommandHandler, CommandSchedulerUserCommandHandlerService>(); .AddSingleton<IUserCommandHandler, CommandSchedulerUserCommandHandlerService>();
} }
internal static IServiceCollection AddConfiguration(this IServiceCollection serviceCollection, IConfigurationRoot configuration)
{
return serviceCollection
.Configure<ProgramsConfiguration>(configuration.GetSection(SectionNames.ProgramsSectionName))
.Configure<KeyBindingConfiguration>(configuration.GetSection(SectionNames.KeybindingSectionName))
.AddSingleton<IConfiguration>(configuration);
}
} }

View File

@@ -43,7 +43,7 @@ public static class DependencyInjection
serviceCollection.AddSingleton<IStartupHandler, ITabPersistenceService>(sp => sp.GetRequiredService<ITabPersistenceService>()); serviceCollection.AddSingleton<IStartupHandler, ITabPersistenceService>(sp => sp.GetRequiredService<ITabPersistenceService>());
return serviceCollection return serviceCollection
.AddCoreAppServices() .AddCoreAppServices(configuration)
.AddLocalProviderServices() .AddLocalProviderServices()
.AddLocalAdminProviderServices(configuration) .AddLocalAdminProviderServices(configuration)
.AddRemoteProviderServices() .AddRemoteProviderServices()

View File

@@ -12,15 +12,17 @@ public class App : IApplication
private readonly IConsoleAppState _consoleAppState; private readonly IConsoleAppState _consoleAppState;
private readonly IAppKeyService<Key> _appKeyService; private readonly IAppKeyService<Key> _appKeyService;
private readonly MainWindow _mainWindow; private readonly MainWindow _mainWindow;
private readonly IKeyInputHandlerService _keyInputHandlerService = null!; private readonly IKeyInputHandlerService _keyInputHandlerService;
public App( public App(
ILifecycleService lifecycleService, ILifecycleService lifecycleService,
IKeyInputHandlerService keyInputHandlerService,
IConsoleAppState consoleAppState, IConsoleAppState consoleAppState,
IAppKeyService<Key> appKeyService, IAppKeyService<Key> appKeyService,
MainWindow mainWindow) MainWindow mainWindow)
{ {
_lifecycleService = lifecycleService; _lifecycleService = lifecycleService;
_keyInputHandlerService = keyInputHandlerService;
_consoleAppState = consoleAppState; _consoleAppState = consoleAppState;
_appKeyService = appKeyService; _appKeyService = appKeyService;
_mainWindow = mainWindow; _mainWindow = mainWindow;
@@ -28,6 +30,7 @@ public class App : IApplication
public void Run() public void Run()
{ {
Console.WriteLine("Loading...");
Task.Run(async () => await _lifecycleService.InitStartupHandlersAsync()).Wait(); Task.Run(async () => await _lifecycleService.InitStartupHandlersAsync()).Wait();
_mainWindow.Initialize(); _mainWindow.Initialize();
@@ -41,14 +44,10 @@ public class App : IApplication
Application.RootKeyEvent += e => Application.RootKeyEvent += e =>
{ {
if (e.ToGeneralKeyEventArgs(_appKeyService) is { } args) if (e.ToGeneralKeyEventArgs(_appKeyService) is not { } args) return false;
{ _keyInputHandlerService.HandleKeyInput(args);
_keyInputHandlerService.HandleKeyInput(args);
return args.Handled; return args.Handled;
}
return false;
}; };
Application.Run(); Application.Run();

View File

@@ -12,6 +12,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="7.0.0" /> <PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="7.0.0" />
<PackageReference Include="Serilog" Version="3.0.1" />
<PackageReference Include="Terminal.Gui" Version="1.13.5" /> <PackageReference Include="Terminal.Gui" Version="1.13.5" />
</ItemGroup> </ItemGroup>

View File

@@ -23,16 +23,17 @@ public class KeyInputHandlerService : IKeyInputHandlerService
_defaultModeKeyInputHandler = defaultModeKeyInputHandler; _defaultModeKeyInputHandler = defaultModeKeyInputHandler;
_rapidTravelModeKeyInputHandler = rapidTravelModeKeyInputHandler; _rapidTravelModeKeyInputHandler = rapidTravelModeKeyInputHandler;
} }
public void HandleKeyInput(GeneralKeyEventArgs keyEvent) public void HandleKeyInput(GeneralKeyEventArgs keyEvent)
{ {
var specialKeysStatus = new SpecialKeysStatus(_isAltPressed, _isShiftPressed, _isCtrlPressed); var specialKeysStatus = new SpecialKeysStatus(_isAltPressed, _isShiftPressed, _isCtrlPressed);
if (_appState.ViewMode.Value == ViewMode.Default) if (_appState.ViewMode.Value == ViewMode.Default)
{ {
_defaultModeKeyInputHandler.HandleInputKey(keyEvent, specialKeysStatus); Task.Run(async () => await _defaultModeKeyInputHandler.HandleInputKey(keyEvent, specialKeysStatus)).Wait();
} }
else else
{ {
_rapidTravelModeKeyInputHandler.HandleInputKey(keyEvent, specialKeysStatus); Task.Run(async () => await _rapidTravelModeKeyInputHandler.HandleInputKey(keyEvent, specialKeysStatus)).Wait();
} }
} }
} }

View File

@@ -1,7 +1,9 @@
using DeclarativeProperty; using System.Collections.ObjectModel;
using DeclarativeProperty;
using FileTime.App.Core.ViewModels; using FileTime.App.Core.ViewModels;
using FileTime.ConsoleUI.App.Controls; using FileTime.ConsoleUI.App.Controls;
using FileTime.Core.Models; using FileTime.Core.Models;
using ObservableComputations;
using Terminal.Gui; using Terminal.Gui;
namespace FileTime.ConsoleUI.App; namespace FileTime.ConsoleUI.App;
@@ -17,12 +19,12 @@ public class MainWindow
_selectedItemsView = new() {X = 1, Y = 0, Width = Dim.Fill(), Height = Dim.Fill()}; _selectedItemsView = new() {X = 1, Y = 0, Width = Dim.Fill(), Height = Dim.Fill()};
_selectedItemsView.AddKeyBinding(Key.Space, Command.ToggleChecked); _selectedItemsView.AddKeyBinding(Key.Space, Command.ToggleChecked);
_selectedItemsView.OpenSelectedItem += (e) => /*_selectedItemsView.OpenSelectedItem += (e) =>
{ {
if (e.Value is IItemViewModel {BaseItem: IContainer container} if (e.Value is IItemViewModel {BaseItem: IContainer container}
&& consoleAppState.SelectedTab.Value?.Tab is { } tab) && consoleAppState.SelectedTab.Value?.Tab is { } tab)
tab.SetCurrentLocation(container); tab.SetCurrentLocation(container);
}; };*/
} }
public void Initialize() public void Initialize()
@@ -32,6 +34,22 @@ public class MainWindow
.Map(t => t.CurrentItems) .Map(t => t.CurrentItems)
.Switch(); .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); var renderer = new ItemRenderer(selectedsItems, _selectedItemsView);
_selectedItemsView.Source = renderer; _selectedItemsView.Source = renderer;
} }

View File

@@ -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);
}
}
}

View File

@@ -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<IEnumerable<FullName>> GetFilesAsync() => throw new NotImplementedException();
public Task SetFilesAsync(IEnumerable<FullName> files) => throw new NotImplementedException();
}

View File

@@ -1,6 +1,7 @@
using FileTime.App.Core.Services; using FileTime.App.Core.Services;
using FileTime.App.Core.ViewModels; using FileTime.App.Core.ViewModels;
using FileTime.ConsoleUI.App.KeyInputHandling; using FileTime.ConsoleUI.App.KeyInputHandling;
using FileTime.ConsoleUI.App.Services;
using FileTime.Core.Interactions; using FileTime.Core.Interactions;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.DependencyInjection.Extensions;
@@ -19,6 +20,8 @@ public static class Startup
services.TryAddSingleton<IUserCommunicationService, ConsoleUserCommunicationService>(); services.TryAddSingleton<IUserCommunicationService, ConsoleUserCommunicationService>();
services.TryAddSingleton<IKeyInputHandlerService, KeyInputHandlerService>(); services.TryAddSingleton<IKeyInputHandlerService, KeyInputHandlerService>();
services.TryAddSingleton<IAppKeyService<Key>, ConsoleAppKeyService>(); services.TryAddSingleton<IAppKeyService<Key>, ConsoleAppKeyService>();
services.TryAddSingleton<ISystemClipboardService, SystemClipboardService>();
services.AddSingleton<CustomLoggerSink>();
return services; return services;
} }

View File

@@ -4,6 +4,7 @@ using FileTime.App.DependencyInjection;
using FileTime.App.FrequencyNavigation; using FileTime.App.FrequencyNavigation;
using FileTime.App.Search; using FileTime.App.Search;
using FileTime.ConsoleUI.App; using FileTime.ConsoleUI.App;
using FileTime.ConsoleUI.App.Services;
using FileTime.Providers.Local; using FileTime.Providers.Local;
using FileTime.Server.Common; using FileTime.Server.Common;
using FileTime.Tools.Compression; using FileTime.Tools.Compression;
@@ -13,21 +14,42 @@ using Serilog;
namespace FileTime.ConsoleUI; 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) public static void Initialize(IConfigurationRoot configuration)
=> ServiceProvider = DependencyInjection => ServiceProvider = DependencyInjection
.RegisterDefaultServices(configuration: configuration) .RegisterDefaultServices(configuration: configuration)
.AddConsoleServices() .AddConsoleServices()
.AddLocalProviderServices() .AddLocalProviderServices()
.AddServerCoreServices() .AddServerCoreServices()
.AddFrequencyNavigation() .AddFrequencyNavigation()
.AddCommandPalette() .AddCommandPalette()
.AddContainerSizeScanner() .AddContainerSizeScanner()
.AddSearch() .AddSearch()
.AddCompression() .AddCompression()
.AddLogging(loggingBuilder => loggingBuilder.AddSerilog()) .SetupLogging()
.BuildServiceProvider(); .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<IConfiguration>())
.Enrich.FromLogContext()
.WriteTo.File(
Path.Combine(Program.AppDataRoot, "logs", "appLog.log"),
fileSizeLimitBytes: 10 * 1024 * 1024,
rollingInterval: RollingInterval.Day,
rollOnFileSizeLimit: true)
.WriteTo.Sink(serviceProvider.GetRequiredService<CustomLoggerSink>());
}
);
} }

View File

@@ -23,6 +23,11 @@
<PackageReference Include="Microsoft.Extensions.Configuration" Version="7.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="7.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" />
<PackageReference Include="Serilog" Version="3.0.1" />
<PackageReference Include="Serilog.Extensions.Hosting" Version="7.0.0" />
<PackageReference Include="Serilog.Extensions.Logging" Version="7.0.0" />
<PackageReference Include="Serilog.Settings.Configuration" Version="7.0.0" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -1,9 +1,13 @@
using FileTime.ConsoleUI; using FileTime.App.Core;
using FileTime.App.Core.Configuration;
using FileTime.ConsoleUI;
using FileTime.ConsoleUI.App; using FileTime.ConsoleUI.App;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
(AppDataRoot, EnvironmentName) = Init.InitDevelopment();
var configuration = new ConfigurationBuilder() var configuration = new ConfigurationBuilder()
.AddInMemoryCollection(MainConfiguration.Configuration)
#if DEBUG #if DEBUG
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
#endif #endif
@@ -12,3 +16,9 @@ DI.Initialize(configuration);
var app = DI.ServiceProvider.GetRequiredService<IApplication>(); var app = DI.ServiceProvider.GetRequiredService<IApplication>();
app.Run(); app.Run();
public partial class Program
{
public static string AppDataRoot { get; private set; }
public static string EnvironmentName { get; private set; }
}

View File

@@ -29,7 +29,6 @@ public class Application : Avalonia.Application
.AddContainerSizeScanner() .AddContainerSizeScanner()
.AddSearch() .AddSearch()
.AddCompression() .AddCompression()
.AddConfiguration(configuration)
.ConfigureFont(configuration) .ConfigureFont(configuration)
.RegisterLogging() .RegisterLogging()
.RegisterServices() .RegisterServices()

View File

@@ -8,6 +8,7 @@ using System.Runtime.ExceptionServices;
using System.Threading.Tasks; using System.Threading.Tasks;
using Avalonia; using Avalonia;
using Avalonia.ReactiveUI; using Avalonia.ReactiveUI;
using FileTime.App.Core;
using Serilog; using Serilog;
using Serilog.Debugging; using Serilog.Debugging;
@@ -18,43 +19,6 @@ public static class Program
public static string AppDataRoot { get; private set; } public static string AppDataRoot { get; private set; }
public static string EnvironmentName { 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<string>
{
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() private static void InitLogging()
{ {
SelfLog.Enable(l => Debug.WriteLine(l)); SelfLog.Enable(l => Debug.WriteLine(l));
@@ -83,12 +47,13 @@ public static class Program
public static void Main(string[] args) public static void Main(string[] args)
{ {
#if DEBUG #if DEBUG
InitDevelopment(); (AppDataRoot, EnvironmentName) = Init.InitDevelopment();
#endif #endif
if (AppDataRoot is null) if (AppDataRoot is null)
{ {
InitRelease(); (AppDataRoot, EnvironmentName) = Init.InitRelease();
} }
InitLogging(); InitLogging();
Log.Logger.Information("Early app starting..."); Log.Logger.Information("Early app starting...");

View File

@@ -105,12 +105,4 @@ public static class Startup
return serviceCollection; return serviceCollection;
} }
internal static IServiceCollection AddConfiguration(this IServiceCollection serviceCollection, IConfigurationRoot configuration)
{
return serviceCollection
.Configure<ProgramsConfiguration>(configuration.GetSection(SectionNames.ProgramsSectionName))
.Configure<KeyBindingConfiguration>(configuration.GetSection(SectionNames.KeybindingSectionName))
.AddSingleton<IConfiguration>(configuration);
}
} }