NativePath, Editor, ToastMessageSink

This commit is contained in:
2022-02-15 19:47:38 +01:00
parent b11d009195
commit 45defb4021
28 changed files with 265 additions and 54 deletions

View File

@@ -12,6 +12,7 @@ namespace FileTime.App.Core.Command
CreateContainer, CreateContainer,
CreateElement, CreateElement,
Cut, Cut,
Edit,
EnterRapidTravel, EnterRapidTravel,
GoToHome, GoToHome,
GoToPath, GoToPath,

View File

@@ -6,6 +6,7 @@ namespace FileTime.Core.Models
{ {
string Name { get; } string Name { get; }
string? FullName { get; } string? FullName { get; }
string? NativePath { get; }
bool IsHidden { get; } bool IsHidden { get; }
bool IsDestroyed { get; } bool IsDestroyed { get; }
SupportsDelete CanDelete { get; } SupportsDelete CanDelete { get; }

View File

@@ -22,6 +22,7 @@ namespace FileTime.Core.Models
public string Name => BaseContainer.Name; public string Name => BaseContainer.Name;
public string? FullName => BaseContainer.FullName; public string? FullName => BaseContainer.FullName;
public string? NativePath => BaseContainer.NativePath;
public bool IsHidden => BaseContainer.IsHidden; public bool IsHidden => BaseContainer.IsHidden;
public bool IsLoaded => BaseContainer.IsLoaded; public bool IsLoaded => BaseContainer.IsLoaded;

View File

@@ -17,6 +17,7 @@ namespace FileTime.Core.Providers
#pragma warning restore CS8603 // Possible null reference return. #pragma warning restore CS8603 // Possible null reference return.
public string? FullName => null; public string? FullName => null;
public string? NativePath => null;
public bool IsHidden => false; public bool IsHidden => false;
public bool IsLoaded => true; public bool IsLoaded => true;

View File

@@ -31,6 +31,9 @@ namespace FileTime.Core.Timeline
public bool IsDestroyed { get; private set; } public bool IsDestroyed { get; private set; }
//FIXME: currently this can be different of the real items NativePath, should be fixed
public string? NativePath => FullName;
public TimeContainer(string name, IContainer parent, IContentProvider contentProvider, IContentProvider virtualContentProvider, PointInTime pointInTime) public TimeContainer(string name, IContainer parent, IContentProvider contentProvider, IContentProvider virtualContentProvider, PointInTime pointInTime)
{ {
_parent = parent; _parent = parent;

View File

@@ -22,6 +22,9 @@ namespace FileTime.Core.Timeline
public string? FullName { get; } public string? FullName { get; }
//FIXME: currently this can be different of the real items NativePath, should be fixed
public string? NativePath => FullName;
public bool IsHidden => false; public bool IsHidden => false;
public SupportsDelete CanDelete => SupportsDelete.True; public SupportsDelete CanDelete => SupportsDelete.True;

View File

@@ -15,6 +15,7 @@ namespace FileTime.Core.Timeline
public string Name => "time"; public string Name => "time";
public string? FullName => null; public string? FullName => null;
public string? NativePath => null;
public bool IsHidden => false; public bool IsHidden => false;

View File

@@ -18,12 +18,12 @@ namespace FileTime.Avalonia
ServiceProvider ??= DependencyInjection ServiceProvider ??= DependencyInjection
.RegisterDefaultServices() .RegisterDefaultServices()
.AddConfiguration() .AddConfiguration()
.InitSerilog() .AddServices()
.RegisterLogging() .RegisterLogging()
.AddViewModels() .AddViewModels()
.AddServices()
.RegisterCommandHandlers() .RegisterCommandHandlers()
.BuildServiceProvider(); .BuildServiceProvider()
.InitSerilog();
var _logger = ServiceProvider.GetService<ILogger<App>>(); var _logger = ServiceProvider.GetService<ILogger<App>>();
_logger?.LogInformation("App initialization completed."); _logger?.LogInformation("App initialization completed.");

View File

@@ -8,32 +8,32 @@ namespace FileTime.Avalonia.Configuration
public static class MainConfiguration public static class MainConfiguration
{ {
private static readonly Lazy<List<CommandBindingConfiguration>> _defaultKeybindings = new(InitDefaultKeyBindings); private static readonly Lazy<List<CommandBindingConfiguration>> _defaultKeybindings = new(InitDefaultKeyBindings);
internal const string KeybindingBaseConfigKey = "KeyBindings";
public static Dictionary<string, string> Configuration { get; } public static Dictionary<string, string> Configuration { get; }
static MainConfiguration() static MainConfiguration()
{ {
Configuration = new(); Configuration = new();
PopulateDefaultKeyBindings(Configuration, _defaultKeybindings.Value, KeybindingBaseConfigKey + ":" + nameof(KeyBindingConfiguration.DefaultKeyBindings)); PopulateDefaultEditorPrograms(Configuration);
PopulateDefaultKeyBindings(Configuration, _defaultKeybindings.Value, SectionNames.KeybindingSectionName + ":" + nameof(KeyBindingConfiguration.DefaultKeyBindings));
} }
private static void PopulateDefaultKeyBindings(Dictionary<string, string> keybindings, List<CommandBindingConfiguration> commandBindingConfigs, string basePath) private static void PopulateDefaultKeyBindings(Dictionary<string, string> configuration, List<CommandBindingConfiguration> commandBindingConfigs, string basePath)
{ {
for (var i = 0; i < commandBindingConfigs.Count; i++) for (var i = 0; i < commandBindingConfigs.Count; i++)
{ {
var baseKey = basePath + $":[{i}]:"; var baseKey = basePath + $":[{i}]:";
var commandBindingConfig = commandBindingConfigs[i]; var commandBindingConfig = commandBindingConfigs[i];
keybindings.Add(baseKey + nameof(CommandBindingConfiguration.Command), commandBindingConfig.Command.ToString()); configuration.Add(baseKey + nameof(CommandBindingConfiguration.Command), commandBindingConfig.Command.ToString());
for (var j = 0; j < commandBindingConfig.Keys.Count; j++) for (var j = 0; j < commandBindingConfig.Keys.Count; j++)
{ {
var key = commandBindingConfig.Keys[j]; var key = commandBindingConfig.Keys[j];
var keyBaseKey = baseKey + $"keys:[{j}]:"; var keyBaseKey = baseKey + $"keys:[{j}]:";
keybindings.Add(keyBaseKey + nameof(KeyConfig.Key), key.Key.ToString()); configuration.Add(keyBaseKey + nameof(KeyConfig.Key), key.Key.ToString());
keybindings.Add(keyBaseKey + nameof(KeyConfig.Shift), key.Shift.ToString()); configuration.Add(keyBaseKey + nameof(KeyConfig.Shift), key.Shift.ToString());
keybindings.Add(keyBaseKey + nameof(KeyConfig.Alt), key.Alt.ToString()); configuration.Add(keyBaseKey + nameof(KeyConfig.Alt), key.Alt.ToString());
keybindings.Add(keyBaseKey + nameof(KeyConfig.Ctrl), key.Ctrl.ToString()); configuration.Add(keyBaseKey + nameof(KeyConfig.Ctrl), key.Ctrl.ToString());
} }
} }
} }
@@ -51,6 +51,7 @@ namespace FileTime.Avalonia.Configuration
new CommandBindingConfiguration(Commands.CreateContainer, new[] { Key.C, Key.C }), new CommandBindingConfiguration(Commands.CreateContainer, new[] { Key.C, Key.C }),
new CommandBindingConfiguration(Commands.CreateElement, new[] { Key.C, Key.E }), new CommandBindingConfiguration(Commands.CreateElement, new[] { Key.C, Key.E }),
new CommandBindingConfiguration(Commands.Cut, new[] { Key.D, Key.D }), new CommandBindingConfiguration(Commands.Cut, new[] { Key.D, Key.D }),
new CommandBindingConfiguration(Commands.Edit, new KeyConfig(Key.F4)),
new CommandBindingConfiguration(Commands.EnterRapidTravel, new KeyConfig(Key.OemComma, shift: true)), new CommandBindingConfiguration(Commands.EnterRapidTravel, new KeyConfig(Key.OemComma, shift: true)),
new CommandBindingConfiguration(Commands.GoToHome, new[] { Key.G, Key.H }), new CommandBindingConfiguration(Commands.GoToHome, new[] { Key.G, Key.H }),
new CommandBindingConfiguration(Commands.GoToPath, new KeyConfig(Key.OemComma, ctrl: true)), new CommandBindingConfiguration(Commands.GoToPath, new KeyConfig(Key.OemComma, ctrl: true)),
@@ -97,5 +98,25 @@ namespace FileTime.Avalonia.Configuration
new CommandBindingConfiguration(Commands.MoveCursorDownPage, Key.PageDown), new CommandBindingConfiguration(Commands.MoveCursorDownPage, Key.PageDown),
}; };
} }
private static void PopulateDefaultEditorPrograms(Dictionary<string, string> configuration)
{
var editorPrograms = new List<ProgramConfiguration>()
{
new ProgramConfiguration(@"c:\Program Files\Notepad++\notepad++1.exe"),
new ProgramConfiguration("notepad.exe"),
};
for (var i = 0; i < editorPrograms.Count; i++)
{
if (editorPrograms[i].Path is not string path) continue;
configuration.Add($"{SectionNames.ProgramsSectionName}:{nameof(ProgramsConfiguration.DefaultEditorPrograms)}:[{i}]:{nameof(ProgramConfiguration.Path)}", path);
if (editorPrograms[i].Arguments is string arguments)
{
configuration.Add($"{SectionNames.ProgramsSectionName}:{nameof(ProgramsConfiguration.DefaultEditorPrograms)}:[{i}]:{nameof(ProgramConfiguration.Arguments)}", arguments);
}
}
}
} }
} }

View File

@@ -0,0 +1,16 @@
namespace FileTime.Avalonia.Configuration
{
public class ProgramConfiguration
{
public string? Path { get; set; }
public string? Arguments { get; set; }
public ProgramConfiguration() { }
public ProgramConfiguration(string? path, string? arguments = null)
{
Path = path;
Arguments = arguments;
}
}
}

View File

@@ -0,0 +1,10 @@
using System.Collections.Generic;
namespace FileTime.Avalonia.Configuration
{
public class ProgramsConfiguration
{
public List<ProgramConfiguration> DefaultEditorPrograms { get; set; } = new();
public List<ProgramConfiguration> EditorPrograms { get; set; } = new();
}
}

View File

@@ -0,0 +1,8 @@
namespace FileTime.Avalonia.Configuration
{
public static class SectionNames
{
internal const string KeybindingSectionName = "KeyBindings";
internal const string ProgramsSectionName = "Programs";
}
}

View File

@@ -0,0 +1,25 @@
using FileTime.Avalonia.Services;
using Serilog.Core;
using Serilog.Events;
namespace FileTime.Avalonia.Logging
{
public class ToastMessageSink : ILogEventSink
{
private readonly IDialogService dialogService;
public ToastMessageSink(IDialogService dialogService)
{
this.dialogService = dialogService;
}
public void Emit(LogEvent logEvent)
{
if (logEvent.Level >= LogEventLevel.Error)
{
var message = logEvent.RenderMessage();
dialogService.ShowToastMessage(message);
}
}
}
}

View File

@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Avalonia.Threading;
using FileTime.App.Core.Clipboard; using FileTime.App.Core.Clipboard;
using FileTime.App.Core.Command; using FileTime.App.Core.Command;
using FileTime.Avalonia.Application; using FileTime.Avalonia.Application;
@@ -17,6 +16,7 @@ using FileTime.Core.Models;
using FileTime.Core.Providers; using FileTime.Core.Providers;
using FileTime.Core.Timeline; using FileTime.Core.Timeline;
using FileTime.Providers.Local; using FileTime.Providers.Local;
using Microsoft.Extensions.Logging;
namespace FileTime.Avalonia.Services namespace FileTime.Avalonia.Services
{ {
@@ -27,22 +27,26 @@ namespace FileTime.Avalonia.Services
private readonly AppState _appState; private readonly AppState _appState;
private readonly LocalContentProvider _localContentProvider; private readonly LocalContentProvider _localContentProvider;
private readonly ItemNameConverterService _itemNameConverterService; private readonly ItemNameConverterService _itemNameConverterService;
private readonly DialogService _dialogService; private readonly IDialogService _dialogService;
private readonly IClipboard _clipboard; private readonly IClipboard _clipboard;
private readonly TimeRunner _timeRunner; private readonly TimeRunner _timeRunner;
private readonly IIconProvider _iconProvider; private readonly IIconProvider _iconProvider;
private readonly IEnumerable<IContentProvider> _contentProviders; private readonly IEnumerable<IContentProvider> _contentProviders;
private readonly Dictionary<Commands, Func<Task>> _commandHandlers; private readonly Dictionary<Commands, Func<Task>> _commandHandlers;
private readonly ProgramsService _programsService;
private readonly ILogger<CommandHandlerService> _logger;
public CommandHandlerService( public CommandHandlerService(
AppState appState, AppState appState,
LocalContentProvider localContentProvider, LocalContentProvider localContentProvider,
ItemNameConverterService itemNameConverterService, ItemNameConverterService itemNameConverterService,
DialogService dialogService, IDialogService dialogService,
IClipboard clipboard, IClipboard clipboard,
TimeRunner timeRunner, TimeRunner timeRunner,
IIconProvider iconProvider, IIconProvider iconProvider,
IEnumerable<IContentProvider> contentProviders) IEnumerable<IContentProvider> contentProviders,
ProgramsService programsService,
ILogger<CommandHandlerService> logger)
{ {
_appState = appState; _appState = appState;
_localContentProvider = localContentProvider; _localContentProvider = localContentProvider;
@@ -52,6 +56,8 @@ namespace FileTime.Avalonia.Services
_timeRunner = timeRunner; _timeRunner = timeRunner;
_iconProvider = iconProvider; _iconProvider = iconProvider;
_contentProviders = contentProviders; _contentProviders = contentProviders;
_programsService = programsService;
_logger = logger;
_commandHandlers = new Dictionary<Commands, Func<Task>> _commandHandlers = new Dictionary<Commands, Func<Task>>
{ {
@@ -541,7 +547,7 @@ namespace FileTime.Avalonia.Services
{ {
if (_appState.SelectedTab.CurrentLocation.Container is LocalFolder localFolder) if (_appState.SelectedTab.CurrentLocation.Container is LocalFolder localFolder)
{ {
var path = localFolder.Directory.FullName; var path = localFolder.NativePath;
if (path != null) if (path != null)
{ {
Process.Start("explorer.exe", "\"" + path + "\""); Process.Start("explorer.exe", "\"" + path + "\"");
@@ -553,23 +559,12 @@ namespace FileTime.Avalonia.Services
private async Task CopyPath() private async Task CopyPath()
{ {
string? textToCopy = null; var currentContainer = _appState.SelectedTab.CurrentLocation.Container;
if (_appState.SelectedTab.CurrentLocation.Container is LocalFolder localFolder) var textToCopy = currentContainer.NativePath;
{
textToCopy = localFolder.Directory.FullName;
}
if (_appState.SelectedTab.CurrentLocation.Container is LocalFile localFile)
{
textToCopy = localFile.File.FullName;
}
else if (_appState.SelectedTab.CurrentLocation.Container.FullName is string fullName)
{
textToCopy = fullName;
}
if (textToCopy != null && global::Avalonia.Application.Current?.Clipboard is not null) if (textToCopy != null && global::Avalonia.Application.Current?.Clipboard is global::Avalonia.Input.Platform.IClipboard clipboard)
{ {
await global::Avalonia.Application.Current.Clipboard.SetTextAsync(textToCopy); await clipboard.SetTextAsync(textToCopy);
} }
} }
@@ -783,6 +778,46 @@ namespace FileTime.Avalonia.Services
private Task Edit() private Task Edit()
{ {
if (_appState.SelectedTab.SelectedItem?.Item is IElement element && element.NativePath is string filePath)
{
var getNext = false;
while (true)
{
try
{
var editorProgram = _programsService.GetEditorProgram(getNext);
if (editorProgram is null)
{
break;
}
else if (editorProgram.Path is string executablePath)
{
if (string.IsNullOrWhiteSpace(editorProgram.Arguments))
{
Process.Start(executablePath, "\"" + filePath + "\"");
}
else
{
var parts = editorProgram.Arguments.Split("%%1");
var arguments = string.Join("%%1", parts.Select(p => p.Replace("%1", "\"" + filePath + "\""))).Replace("%%1", "%1");
Process.Start(executablePath, arguments);
}
}
//TODO: else
break;
}
catch (System.ComponentModel.Win32Exception e)
{
_logger.LogError(e, "Error while running editor program, possible the executable path does not exists.");
}
catch (Exception e)
{
_logger.LogError(e, "Unkown error while running editor program.");
}
getNext = true;
}
}
//TODO: else
return Task.CompletedTask; return Task.CompletedTask;
} }
} }

View File

@@ -9,7 +9,7 @@ using FileTime.Core.Interactions;
namespace FileTime.Avalonia.Services namespace FileTime.Avalonia.Services
{ {
public class DialogService public class DialogService : IDialogService
{ {
private readonly AppState _appState; private readonly AppState _appState;
@@ -93,10 +93,9 @@ namespace FileTime.Avalonia.Services
public void ShowToastMessage(string text) public void ShowToastMessage(string text)
{ {
_appState.PopupTexts.Add(text);
Task.Run(async () => Task.Run(async () =>
{ {
await Dispatcher.UIThread.InvokeAsync(() => _appState.PopupTexts.Add(text));
await Task.Delay(5000); await Task.Delay(5000);
await Dispatcher.UIThread.InvokeAsync(() => _appState.PopupTexts.Remove(text)); await Dispatcher.UIThread.InvokeAsync(() => _appState.PopupTexts.Remove(text));
}); });

View File

@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using FileTime.Avalonia.Misc;
using FileTime.Core.Interactions;
namespace FileTime.Avalonia.Services
{
public interface IDialogService
{
void CancelInputs();
void CancelMessageBox();
void ClearInputs();
Task ProcessInputs();
void ProcessMessageBox();
void ReadInputs(List<InputElement> inputs, Action<List<InputElementWrapper>> inputHandler);
void ReadInputs(List<InputElement> inputs, Func<List<InputElementWrapper>, Task> inputHandler);
Task<string?[]> ReadInputs(IEnumerable<InputElement> fields);
void ShowMessageBox(string text, Func<Task> inputHandler);
void ShowToastMessage(string text);
}
}

View File

@@ -17,13 +17,13 @@ namespace FileTime.Avalonia.Services
private readonly AppState _appState; private readonly AppState _appState;
private readonly KeyboardConfigurationService _keyboardConfigurationService; private readonly KeyboardConfigurationService _keyboardConfigurationService;
private readonly CommandHandlerService _commandHandlerService; private readonly CommandHandlerService _commandHandlerService;
private readonly DialogService _dialogService; private readonly IDialogService _dialogService;
public KeyInputHandlerService( public KeyInputHandlerService(
AppState appState, AppState appState,
KeyboardConfigurationService keyboardConfigurationService, KeyboardConfigurationService keyboardConfigurationService,
CommandHandlerService commandHandlerService, CommandHandlerService commandHandlerService,
DialogService dialogService) IDialogService dialogService)
{ {
_appState = appState; _appState = appState;
_keyboardConfigurationService = keyboardConfigurationService; _keyboardConfigurationService = keyboardConfigurationService;

View File

@@ -0,0 +1,42 @@
using System.Collections.Generic;
using FileTime.Avalonia.Configuration;
using Microsoft.Extensions.Options;
namespace FileTime.Avalonia.Services
{
public class ProgramsService
{
private readonly List<ProgramConfiguration> _editorPrograms;
private int lastGoodEditorProgramIndex;
public ProgramsService(IOptions<ProgramsConfiguration> configuration)
{
var config = configuration.Value;
_editorPrograms = config.EditorPrograms.Count == 0 ? config.DefaultEditorPrograms : config.EditorPrograms;
}
public ProgramConfiguration? GetEditorProgram(bool getNext = false)
{
if (getNext)
{
lastGoodEditorProgramIndex++;
}
if (lastGoodEditorProgramIndex < 0)
{
lastGoodEditorProgramIndex = 0;
}
if (_editorPrograms.Count <= lastGoodEditorProgramIndex)
{
ResetLastGoodEditor();
return null;
}
return _editorPrograms[lastGoodEditorProgramIndex];
}
public void ResetLastGoodEditor()
{
lastGoodEditorProgramIndex = -1;
}
}
}

View File

@@ -1,8 +1,10 @@
using System.IO; using System;
using System.IO;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using FileTime.Avalonia.Application; using FileTime.Avalonia.Application;
using FileTime.Avalonia.Configuration; using FileTime.Avalonia.Configuration;
using FileTime.Avalonia.IconProviders; using FileTime.Avalonia.IconProviders;
using FileTime.Avalonia.Logging;
using FileTime.Avalonia.Services; using FileTime.Avalonia.Services;
using FileTime.Avalonia.ViewModels; using FileTime.Avalonia.ViewModels;
using FileTime.Core.Command; using FileTime.Core.Command;
@@ -12,6 +14,7 @@ using FileTime.Providers.Smb;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Serilog; using Serilog;
using Serilog.Configuration;
namespace FileTime.Avalonia namespace FileTime.Avalonia
{ {
@@ -20,20 +23,22 @@ namespace FileTime.Avalonia
internal static IServiceCollection AddViewModels(this IServiceCollection serviceCollection) internal static IServiceCollection AddViewModels(this IServiceCollection serviceCollection)
{ {
return serviceCollection return serviceCollection
.AddSingleton<AppState>()
.AddTransient<MainPageViewModel>() .AddTransient<MainPageViewModel>()
.AddSingleton<IInputInterface, BasicInputHandler>(); .AddSingleton<IInputInterface, BasicInputHandler>();
} }
internal static IServiceCollection AddServices(this IServiceCollection serviceCollection) internal static IServiceCollection AddServices(this IServiceCollection serviceCollection)
{ {
serviceCollection = serviceCollection serviceCollection = serviceCollection
.AddSingleton<AppState>()
.AddSingleton<ItemNameConverterService>() .AddSingleton<ItemNameConverterService>()
.AddSingleton<StatePersistenceService>() .AddSingleton<StatePersistenceService>()
.AddSingleton<CommandHandlerService>() .AddSingleton<CommandHandlerService>()
.AddSingleton<KeyboardConfigurationService>() .AddSingleton<KeyboardConfigurationService>()
.AddSingleton<KeyInputHandlerService>() .AddSingleton<KeyInputHandlerService>()
.AddSingleton<DialogService>() .AddSingleton<IDialogService, DialogService>()
.AddSingleton(new PersistenceSettings(Program.AppDataRoot)) .AddSingleton(new PersistenceSettings(Program.AppDataRoot))
.AddSingleton<ProgramsService>()
.AddSingleton<ToastMessageSink>()
.AddSmbServices() .AddSmbServices()
.AddSingleton<IIconProvider, MaterialIconProvider>(); .AddSingleton<IIconProvider, MaterialIconProvider>();
@@ -74,13 +79,13 @@ namespace FileTime.Avalonia
.Build(); .Build();
return serviceCollection return serviceCollection
.Configure<KeyBindingConfiguration>(configuration.GetSection(MainConfiguration.KeybindingBaseConfigKey)) .Configure<ProgramsConfiguration>(configuration.GetSection(SectionNames.ProgramsSectionName))
.Configure<KeyBindingConfiguration>(configuration.GetSection(SectionNames.KeybindingSectionName))
.AddSingleton<IConfiguration>(configuration); .AddSingleton<IConfiguration>(configuration);
} }
internal static IServiceCollection InitSerilog(this IServiceCollection serviceCollection) internal static IServiceProvider InitSerilog(this IServiceProvider serviceProvider)
{ {
using var serviceProvider = serviceCollection.BuildServiceProvider();
Log.Logger = new LoggerConfiguration() Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(serviceProvider.GetService<IConfiguration>()) .ReadFrom.Configuration(serviceProvider.GetService<IConfiguration>())
.Enrich.FromLogContext() .Enrich.FromLogContext()
@@ -89,9 +94,17 @@ namespace FileTime.Avalonia
fileSizeLimitBytes: 10 * 1024 * 1024, fileSizeLimitBytes: 10 * 1024 * 1024,
rollOnFileSizeLimit: true, rollOnFileSizeLimit: true,
rollingInterval: RollingInterval.Day) rollingInterval: RollingInterval.Day)
.WriteTo.MessageBoxSink(serviceProvider)
.CreateLogger(); .CreateLogger();
return serviceCollection; return serviceProvider;
}
public static LoggerConfiguration MessageBoxSink(
this LoggerSinkConfiguration loggerConfiguration,
IServiceProvider serviceProvider)
{
return loggerConfiguration.Sink(serviceProvider.GetService<ToastMessageSink>());
} }
} }
} }

View File

@@ -33,7 +33,7 @@ namespace FileTime.Avalonia.ViewModels
[Inject(typeof(ILogger<MainPageViewModel>), PropertyName = "_logger")] [Inject(typeof(ILogger<MainPageViewModel>), PropertyName = "_logger")]
[Inject(typeof(KeyboardConfigurationService))] [Inject(typeof(KeyboardConfigurationService))]
[Inject(typeof(CommandHandlerService), PropertyAccessModifier = AccessModifier.Public)] [Inject(typeof(CommandHandlerService), PropertyAccessModifier = AccessModifier.Public)]
[Inject(typeof(DialogService))] [Inject(typeof(IDialogService), PropertyName = "_dialogService")]
[Inject(typeof(KeyInputHandlerService))] [Inject(typeof(KeyInputHandlerService))]
public partial class MainPageViewModel : IMainPageViewModelBase public partial class MainPageViewModel : IMainPageViewModelBase
{ {
@@ -73,7 +73,7 @@ namespace FileTime.Avalonia.ViewModels
_timeRunner = App.ServiceProvider.GetService<TimeRunner>()!; _timeRunner = App.ServiceProvider.GetService<TimeRunner>()!;
var inputInterface = (BasicInputHandler)App.ServiceProvider.GetService<IInputInterface>()!; var inputInterface = (BasicInputHandler)App.ServiceProvider.GetService<IInputInterface>()!;
inputInterface.InputHandler = DialogService.ReadInputs; inputInterface.InputHandler = _dialogService.ReadInputs;
App.ServiceProvider.GetService<TopContainer>(); App.ServiceProvider.GetService<TopContainer>();
await StatePersistence.LoadStatesAsync(); await StatePersistence.LoadStatesAsync();
@@ -246,25 +246,25 @@ namespace FileTime.Avalonia.ViewModels
[Command] [Command]
public async void ProcessInputs() public async void ProcessInputs()
{ {
await DialogService.ProcessInputs(); await _dialogService.ProcessInputs();
} }
[Command] [Command]
public void CancelInputs() public void CancelInputs()
{ {
DialogService.CancelInputs(); _dialogService.CancelInputs();
} }
[Command] [Command]
public void ProcessMessageBox() public void ProcessMessageBox()
{ {
DialogService.ProcessMessageBox(); _dialogService.ProcessMessageBox();
} }
[Command] [Command]
public void CancelMessageBox() public void CancelMessageBox()
{ {
DialogService.CancelMessageBox(); _dialogService.CancelMessageBox();
} }
public void ProcessKeyDown(Key key, KeyModifiers keyModifiers, Action<bool> setHandled) public void ProcessKeyDown(Key key, KeyModifiers keyModifiers, Action<bool> setHandled)

View File

@@ -19,6 +19,7 @@ namespace FileTime.Providers.Local
public string Name { get; } = "local"; public string Name { get; } = "local";
public string? FullName { get; } public string? FullName { get; }
public string? NativePath => null;
public bool IsHidden => false; public bool IsHidden => false;
public bool IsLoaded => true; public bool IsLoaded => true;

View File

@@ -14,6 +14,7 @@ namespace FileTime.Providers.Local
public string Name { get; } public string Name { get; }
public string FullName { get; } public string FullName { get; }
public string? NativePath => File.FullName;
public IContentProvider Provider { get; } public IContentProvider Provider { get; }

View File

@@ -22,6 +22,7 @@ namespace FileTime.Providers.Local
public string Name { get; } public string Name { get; }
public string FullName { get; } public string FullName { get; }
public string? NativePath => Directory.FullName;
public bool IsLoaded => _items != null; public bool IsLoaded => _items != null;
public SupportsDelete CanDelete { get; } public SupportsDelete CanDelete { get; }

View File

@@ -24,6 +24,7 @@ namespace FileTime.Providers.Smb
public string Name { get; } = "smb"; public string Name { get; } = "smb";
public string? FullName { get; } public string? FullName { get; }
public string? NativePath => null;
public bool IsHidden => false; public bool IsHidden => false;
public bool IsLoaded => true; public bool IsLoaded => true;
@@ -177,5 +178,7 @@ namespace FileTime.Providers.Smb
} }
} }
} }
public static string GetNativePath(string fullName) => fullName.Replace("/", "\\");
} }
} }

View File

@@ -1,6 +1,5 @@
using FileTime.Core.Models; using FileTime.Core.Models;
using FileTime.Core.Providers; using FileTime.Core.Providers;
using SMBLibrary.Client;
namespace FileTime.Providers.Smb namespace FileTime.Providers.Smb
{ {
@@ -11,6 +10,7 @@ namespace FileTime.Providers.Smb
public string Name { get; } public string Name { get; }
public string? FullName { get; } public string? FullName { get; }
public string? NativePath { get; }
public bool IsHidden => false; public bool IsHidden => false;
public SupportsDelete CanDelete => SupportsDelete.True; public SupportsDelete CanDelete => SupportsDelete.True;
@@ -25,6 +25,7 @@ namespace FileTime.Providers.Smb
{ {
Name = name; Name = name;
FullName = parent.FullName + Constants.SeparatorChar + Name; FullName = parent.FullName + Constants.SeparatorChar + Name;
NativePath = SmbContentProvider.GetNativePath(FullName);
Provider = provider; Provider = provider;
_parent = parent; _parent = parent;

View File

@@ -1,8 +1,6 @@
using AsyncEvent; using AsyncEvent;
using FileTime.Core.Models; using FileTime.Core.Models;
using FileTime.Core.Providers; using FileTime.Core.Providers;
using SMBLibrary;
using SMBLibrary.Client;
namespace FileTime.Providers.Smb namespace FileTime.Providers.Smb
{ {
@@ -17,6 +15,7 @@ namespace FileTime.Providers.Smb
public string Name { get; } public string Name { get; }
public string? FullName { get; } public string? FullName { get; }
public string? NativePath { get; }
public bool IsHidden => false; public bool IsHidden => false;
public bool IsLoaded => _items != null; public bool IsLoaded => _items != null;
@@ -40,6 +39,7 @@ namespace FileTime.Providers.Smb
Name = name; Name = name;
FullName = parent?.FullName == null ? Name : parent.FullName + Constants.SeparatorChar + Name; FullName = parent?.FullName == null ? Name : parent.FullName + Constants.SeparatorChar + Name;
NativePath = SmbContentProvider.GetNativePath(FullName);
Provider = contentProvider; Provider = contentProvider;
} }

View File

@@ -24,8 +24,8 @@ namespace FileTime.Providers.Smb
public string? Password { get; private set; } public string? Password { get; private set; }
public string Name { get; } public string Name { get; }
public string? FullName { get; } public string? FullName { get; }
public string? NativePath { get; }
public bool IsHidden => false; public bool IsHidden => false;
public bool IsLoaded => _items != null; public bool IsLoaded => _items != null;
@@ -51,7 +51,7 @@ namespace FileTime.Providers.Smb
Password = password; Password = password;
Provider = contentProvider; Provider = contentProvider;
FullName = Name = path; NativePath = FullName = Name = path;
} }
public async Task<IReadOnlyList<IItem>?> GetItems(CancellationToken token = default) public async Task<IReadOnlyList<IItem>?> GetItems(CancellationToken token = default)

View File

@@ -17,6 +17,7 @@ namespace FileTime.Providers.Smb
public string Name { get; } public string Name { get; }
public string? FullName { get; } public string? FullName { get; }
public string? NativePath { get; }
public bool IsHidden => false; public bool IsHidden => false;
public bool IsLoaded => _items != null; public bool IsLoaded => _items != null;
@@ -40,6 +41,7 @@ namespace FileTime.Providers.Smb
Name = name; Name = name;
FullName = parent?.FullName == null ? Name : parent.FullName + Constants.SeparatorChar + Name; FullName = parent?.FullName == null ? Name : parent.FullName + Constants.SeparatorChar + Name;
NativePath = SmbContentProvider.GetNativePath(FullName);
Provider = contentProvider; Provider = contentProvider;
} }