NativePath, Editor, ToastMessageSink
This commit is contained in:
@@ -12,6 +12,7 @@ namespace FileTime.App.Core.Command
|
||||
CreateContainer,
|
||||
CreateElement,
|
||||
Cut,
|
||||
Edit,
|
||||
EnterRapidTravel,
|
||||
GoToHome,
|
||||
GoToPath,
|
||||
|
||||
@@ -6,6 +6,7 @@ namespace FileTime.Core.Models
|
||||
{
|
||||
string Name { get; }
|
||||
string? FullName { get; }
|
||||
string? NativePath { get; }
|
||||
bool IsHidden { get; }
|
||||
bool IsDestroyed { get; }
|
||||
SupportsDelete CanDelete { get; }
|
||||
|
||||
@@ -22,6 +22,7 @@ namespace FileTime.Core.Models
|
||||
public string Name => BaseContainer.Name;
|
||||
|
||||
public string? FullName => BaseContainer.FullName;
|
||||
public string? NativePath => BaseContainer.NativePath;
|
||||
|
||||
public bool IsHidden => BaseContainer.IsHidden;
|
||||
public bool IsLoaded => BaseContainer.IsLoaded;
|
||||
|
||||
@@ -17,6 +17,7 @@ namespace FileTime.Core.Providers
|
||||
#pragma warning restore CS8603 // Possible null reference return.
|
||||
|
||||
public string? FullName => null;
|
||||
public string? NativePath => null;
|
||||
|
||||
public bool IsHidden => false;
|
||||
public bool IsLoaded => true;
|
||||
|
||||
@@ -31,6 +31,9 @@ namespace FileTime.Core.Timeline
|
||||
|
||||
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)
|
||||
{
|
||||
_parent = parent;
|
||||
|
||||
@@ -22,6 +22,9 @@ namespace FileTime.Core.Timeline
|
||||
|
||||
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 SupportsDelete CanDelete => SupportsDelete.True;
|
||||
|
||||
@@ -15,6 +15,7 @@ namespace FileTime.Core.Timeline
|
||||
public string Name => "time";
|
||||
|
||||
public string? FullName => null;
|
||||
public string? NativePath => null;
|
||||
|
||||
public bool IsHidden => false;
|
||||
|
||||
|
||||
@@ -18,12 +18,12 @@ namespace FileTime.Avalonia
|
||||
ServiceProvider ??= DependencyInjection
|
||||
.RegisterDefaultServices()
|
||||
.AddConfiguration()
|
||||
.InitSerilog()
|
||||
.AddServices()
|
||||
.RegisterLogging()
|
||||
.AddViewModels()
|
||||
.AddServices()
|
||||
.RegisterCommandHandlers()
|
||||
.BuildServiceProvider();
|
||||
.BuildServiceProvider()
|
||||
.InitSerilog();
|
||||
|
||||
var _logger = ServiceProvider.GetService<ILogger<App>>();
|
||||
_logger?.LogInformation("App initialization completed.");
|
||||
|
||||
@@ -8,32 +8,32 @@ namespace FileTime.Avalonia.Configuration
|
||||
public static class MainConfiguration
|
||||
{
|
||||
private static readonly Lazy<List<CommandBindingConfiguration>> _defaultKeybindings = new(InitDefaultKeyBindings);
|
||||
internal const string KeybindingBaseConfigKey = "KeyBindings";
|
||||
|
||||
public static Dictionary<string, string> Configuration { get; }
|
||||
|
||||
static MainConfiguration()
|
||||
{
|
||||
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++)
|
||||
{
|
||||
var baseKey = basePath + $":[{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++)
|
||||
{
|
||||
var key = commandBindingConfig.Keys[j];
|
||||
var keyBaseKey = baseKey + $"keys:[{j}]:";
|
||||
keybindings.Add(keyBaseKey + nameof(KeyConfig.Key), key.Key.ToString());
|
||||
keybindings.Add(keyBaseKey + nameof(KeyConfig.Shift), key.Shift.ToString());
|
||||
keybindings.Add(keyBaseKey + nameof(KeyConfig.Alt), key.Alt.ToString());
|
||||
keybindings.Add(keyBaseKey + nameof(KeyConfig.Ctrl), key.Ctrl.ToString());
|
||||
configuration.Add(keyBaseKey + nameof(KeyConfig.Key), key.Key.ToString());
|
||||
configuration.Add(keyBaseKey + nameof(KeyConfig.Shift), key.Shift.ToString());
|
||||
configuration.Add(keyBaseKey + nameof(KeyConfig.Alt), key.Alt.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.CreateElement, new[] { Key.C, Key.E }),
|
||||
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.GoToHome, new[] { Key.G, Key.H }),
|
||||
new CommandBindingConfiguration(Commands.GoToPath, new KeyConfig(Key.OemComma, ctrl: true)),
|
||||
@@ -97,5 +98,25 @@ namespace FileTime.Avalonia.Configuration
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace FileTime.Avalonia.Configuration
|
||||
{
|
||||
public static class SectionNames
|
||||
{
|
||||
internal const string KeybindingSectionName = "KeyBindings";
|
||||
internal const string ProgramsSectionName = "Programs";
|
||||
}
|
||||
}
|
||||
25
src/GuiApp/FileTime.Avalonia/Logging/ToastMessageSink.cs
Normal file
25
src/GuiApp/FileTime.Avalonia/Logging/ToastMessageSink.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Avalonia.Threading;
|
||||
using FileTime.App.Core.Clipboard;
|
||||
using FileTime.App.Core.Command;
|
||||
using FileTime.Avalonia.Application;
|
||||
@@ -17,6 +16,7 @@ using FileTime.Core.Models;
|
||||
using FileTime.Core.Providers;
|
||||
using FileTime.Core.Timeline;
|
||||
using FileTime.Providers.Local;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace FileTime.Avalonia.Services
|
||||
{
|
||||
@@ -27,22 +27,26 @@ namespace FileTime.Avalonia.Services
|
||||
private readonly AppState _appState;
|
||||
private readonly LocalContentProvider _localContentProvider;
|
||||
private readonly ItemNameConverterService _itemNameConverterService;
|
||||
private readonly DialogService _dialogService;
|
||||
private readonly IDialogService _dialogService;
|
||||
private readonly IClipboard _clipboard;
|
||||
private readonly TimeRunner _timeRunner;
|
||||
private readonly IIconProvider _iconProvider;
|
||||
private readonly IEnumerable<IContentProvider> _contentProviders;
|
||||
private readonly Dictionary<Commands, Func<Task>> _commandHandlers;
|
||||
private readonly ProgramsService _programsService;
|
||||
private readonly ILogger<CommandHandlerService> _logger;
|
||||
|
||||
public CommandHandlerService(
|
||||
AppState appState,
|
||||
LocalContentProvider localContentProvider,
|
||||
ItemNameConverterService itemNameConverterService,
|
||||
DialogService dialogService,
|
||||
IDialogService dialogService,
|
||||
IClipboard clipboard,
|
||||
TimeRunner timeRunner,
|
||||
IIconProvider iconProvider,
|
||||
IEnumerable<IContentProvider> contentProviders)
|
||||
IEnumerable<IContentProvider> contentProviders,
|
||||
ProgramsService programsService,
|
||||
ILogger<CommandHandlerService> logger)
|
||||
{
|
||||
_appState = appState;
|
||||
_localContentProvider = localContentProvider;
|
||||
@@ -52,6 +56,8 @@ namespace FileTime.Avalonia.Services
|
||||
_timeRunner = timeRunner;
|
||||
_iconProvider = iconProvider;
|
||||
_contentProviders = contentProviders;
|
||||
_programsService = programsService;
|
||||
_logger = logger;
|
||||
|
||||
_commandHandlers = new Dictionary<Commands, Func<Task>>
|
||||
{
|
||||
@@ -541,7 +547,7 @@ namespace FileTime.Avalonia.Services
|
||||
{
|
||||
if (_appState.SelectedTab.CurrentLocation.Container is LocalFolder localFolder)
|
||||
{
|
||||
var path = localFolder.Directory.FullName;
|
||||
var path = localFolder.NativePath;
|
||||
if (path != null)
|
||||
{
|
||||
Process.Start("explorer.exe", "\"" + path + "\"");
|
||||
@@ -553,23 +559,12 @@ namespace FileTime.Avalonia.Services
|
||||
|
||||
private async Task CopyPath()
|
||||
{
|
||||
string? textToCopy = null;
|
||||
if (_appState.SelectedTab.CurrentLocation.Container is LocalFolder localFolder)
|
||||
{
|
||||
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;
|
||||
}
|
||||
var currentContainer = _appState.SelectedTab.CurrentLocation.Container;
|
||||
var textToCopy = currentContainer.NativePath;
|
||||
|
||||
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()
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ using FileTime.Core.Interactions;
|
||||
|
||||
namespace FileTime.Avalonia.Services
|
||||
{
|
||||
public class DialogService
|
||||
public class DialogService : IDialogService
|
||||
{
|
||||
private readonly AppState _appState;
|
||||
|
||||
@@ -93,10 +93,9 @@ namespace FileTime.Avalonia.Services
|
||||
|
||||
public void ShowToastMessage(string text)
|
||||
{
|
||||
_appState.PopupTexts.Add(text);
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await Dispatcher.UIThread.InvokeAsync(() => _appState.PopupTexts.Add(text));
|
||||
await Task.Delay(5000);
|
||||
await Dispatcher.UIThread.InvokeAsync(() => _appState.PopupTexts.Remove(text));
|
||||
});
|
||||
|
||||
22
src/GuiApp/FileTime.Avalonia/Services/IDialogService.cs
Normal file
22
src/GuiApp/FileTime.Avalonia/Services/IDialogService.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -17,13 +17,13 @@ namespace FileTime.Avalonia.Services
|
||||
private readonly AppState _appState;
|
||||
private readonly KeyboardConfigurationService _keyboardConfigurationService;
|
||||
private readonly CommandHandlerService _commandHandlerService;
|
||||
private readonly DialogService _dialogService;
|
||||
private readonly IDialogService _dialogService;
|
||||
|
||||
public KeyInputHandlerService(
|
||||
AppState appState,
|
||||
KeyboardConfigurationService keyboardConfigurationService,
|
||||
CommandHandlerService commandHandlerService,
|
||||
DialogService dialogService)
|
||||
IDialogService dialogService)
|
||||
{
|
||||
_appState = appState;
|
||||
_keyboardConfigurationService = keyboardConfigurationService;
|
||||
|
||||
42
src/GuiApp/FileTime.Avalonia/Services/ProgramsService.cs
Normal file
42
src/GuiApp/FileTime.Avalonia/Services/ProgramsService.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
using System.IO;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using FileTime.Avalonia.Application;
|
||||
using FileTime.Avalonia.Configuration;
|
||||
using FileTime.Avalonia.IconProviders;
|
||||
using FileTime.Avalonia.Logging;
|
||||
using FileTime.Avalonia.Services;
|
||||
using FileTime.Avalonia.ViewModels;
|
||||
using FileTime.Core.Command;
|
||||
@@ -12,6 +14,7 @@ using FileTime.Providers.Smb;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Serilog;
|
||||
using Serilog.Configuration;
|
||||
|
||||
namespace FileTime.Avalonia
|
||||
{
|
||||
@@ -20,20 +23,22 @@ namespace FileTime.Avalonia
|
||||
internal static IServiceCollection AddViewModels(this IServiceCollection serviceCollection)
|
||||
{
|
||||
return serviceCollection
|
||||
.AddSingleton<AppState>()
|
||||
.AddTransient<MainPageViewModel>()
|
||||
.AddSingleton<IInputInterface, BasicInputHandler>();
|
||||
}
|
||||
internal static IServiceCollection AddServices(this IServiceCollection serviceCollection)
|
||||
{
|
||||
serviceCollection = serviceCollection
|
||||
.AddSingleton<AppState>()
|
||||
.AddSingleton<ItemNameConverterService>()
|
||||
.AddSingleton<StatePersistenceService>()
|
||||
.AddSingleton<CommandHandlerService>()
|
||||
.AddSingleton<KeyboardConfigurationService>()
|
||||
.AddSingleton<KeyInputHandlerService>()
|
||||
.AddSingleton<DialogService>()
|
||||
.AddSingleton<IDialogService, DialogService>()
|
||||
.AddSingleton(new PersistenceSettings(Program.AppDataRoot))
|
||||
.AddSingleton<ProgramsService>()
|
||||
.AddSingleton<ToastMessageSink>()
|
||||
.AddSmbServices()
|
||||
.AddSingleton<IIconProvider, MaterialIconProvider>();
|
||||
|
||||
@@ -74,13 +79,13 @@ namespace FileTime.Avalonia
|
||||
.Build();
|
||||
|
||||
return serviceCollection
|
||||
.Configure<KeyBindingConfiguration>(configuration.GetSection(MainConfiguration.KeybindingBaseConfigKey))
|
||||
.Configure<ProgramsConfiguration>(configuration.GetSection(SectionNames.ProgramsSectionName))
|
||||
.Configure<KeyBindingConfiguration>(configuration.GetSection(SectionNames.KeybindingSectionName))
|
||||
.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()
|
||||
.ReadFrom.Configuration(serviceProvider.GetService<IConfiguration>())
|
||||
.Enrich.FromLogContext()
|
||||
@@ -89,9 +94,17 @@ namespace FileTime.Avalonia
|
||||
fileSizeLimitBytes: 10 * 1024 * 1024,
|
||||
rollOnFileSizeLimit: true,
|
||||
rollingInterval: RollingInterval.Day)
|
||||
.WriteTo.MessageBoxSink(serviceProvider)
|
||||
.CreateLogger();
|
||||
|
||||
return serviceCollection;
|
||||
return serviceProvider;
|
||||
}
|
||||
|
||||
public static LoggerConfiguration MessageBoxSink(
|
||||
this LoggerSinkConfiguration loggerConfiguration,
|
||||
IServiceProvider serviceProvider)
|
||||
{
|
||||
return loggerConfiguration.Sink(serviceProvider.GetService<ToastMessageSink>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace FileTime.Avalonia.ViewModels
|
||||
[Inject(typeof(ILogger<MainPageViewModel>), PropertyName = "_logger")]
|
||||
[Inject(typeof(KeyboardConfigurationService))]
|
||||
[Inject(typeof(CommandHandlerService), PropertyAccessModifier = AccessModifier.Public)]
|
||||
[Inject(typeof(DialogService))]
|
||||
[Inject(typeof(IDialogService), PropertyName = "_dialogService")]
|
||||
[Inject(typeof(KeyInputHandlerService))]
|
||||
public partial class MainPageViewModel : IMainPageViewModelBase
|
||||
{
|
||||
@@ -73,7 +73,7 @@ namespace FileTime.Avalonia.ViewModels
|
||||
|
||||
_timeRunner = App.ServiceProvider.GetService<TimeRunner>()!;
|
||||
var inputInterface = (BasicInputHandler)App.ServiceProvider.GetService<IInputInterface>()!;
|
||||
inputInterface.InputHandler = DialogService.ReadInputs;
|
||||
inputInterface.InputHandler = _dialogService.ReadInputs;
|
||||
App.ServiceProvider.GetService<TopContainer>();
|
||||
await StatePersistence.LoadStatesAsync();
|
||||
|
||||
@@ -246,25 +246,25 @@ namespace FileTime.Avalonia.ViewModels
|
||||
[Command]
|
||||
public async void ProcessInputs()
|
||||
{
|
||||
await DialogService.ProcessInputs();
|
||||
await _dialogService.ProcessInputs();
|
||||
}
|
||||
|
||||
[Command]
|
||||
public void CancelInputs()
|
||||
{
|
||||
DialogService.CancelInputs();
|
||||
_dialogService.CancelInputs();
|
||||
}
|
||||
|
||||
[Command]
|
||||
public void ProcessMessageBox()
|
||||
{
|
||||
DialogService.ProcessMessageBox();
|
||||
_dialogService.ProcessMessageBox();
|
||||
}
|
||||
|
||||
[Command]
|
||||
public void CancelMessageBox()
|
||||
{
|
||||
DialogService.CancelMessageBox();
|
||||
_dialogService.CancelMessageBox();
|
||||
}
|
||||
|
||||
public void ProcessKeyDown(Key key, KeyModifiers keyModifiers, Action<bool> setHandled)
|
||||
|
||||
@@ -19,6 +19,7 @@ namespace FileTime.Providers.Local
|
||||
public string Name { get; } = "local";
|
||||
|
||||
public string? FullName { get; }
|
||||
public string? NativePath => null;
|
||||
public bool IsHidden => false;
|
||||
public bool IsLoaded => true;
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ namespace FileTime.Providers.Local
|
||||
public string Name { get; }
|
||||
|
||||
public string FullName { get; }
|
||||
public string? NativePath => File.FullName;
|
||||
|
||||
public IContentProvider Provider { get; }
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ namespace FileTime.Providers.Local
|
||||
public string Name { get; }
|
||||
|
||||
public string FullName { get; }
|
||||
public string? NativePath => Directory.FullName;
|
||||
|
||||
public bool IsLoaded => _items != null;
|
||||
public SupportsDelete CanDelete { get; }
|
||||
|
||||
@@ -24,6 +24,7 @@ namespace FileTime.Providers.Smb
|
||||
public string Name { get; } = "smb";
|
||||
|
||||
public string? FullName { get; }
|
||||
public string? NativePath => null;
|
||||
|
||||
public bool IsHidden => false;
|
||||
public bool IsLoaded => true;
|
||||
@@ -177,5 +178,7 @@ namespace FileTime.Providers.Smb
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetNativePath(string fullName) => fullName.Replace("/", "\\");
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
using FileTime.Core.Models;
|
||||
using FileTime.Core.Providers;
|
||||
using SMBLibrary.Client;
|
||||
|
||||
namespace FileTime.Providers.Smb
|
||||
{
|
||||
@@ -11,6 +10,7 @@ namespace FileTime.Providers.Smb
|
||||
public string Name { get; }
|
||||
|
||||
public string? FullName { get; }
|
||||
public string? NativePath { get; }
|
||||
|
||||
public bool IsHidden => false;
|
||||
public SupportsDelete CanDelete => SupportsDelete.True;
|
||||
@@ -25,6 +25,7 @@ namespace FileTime.Providers.Smb
|
||||
{
|
||||
Name = name;
|
||||
FullName = parent.FullName + Constants.SeparatorChar + Name;
|
||||
NativePath = SmbContentProvider.GetNativePath(FullName);
|
||||
|
||||
Provider = provider;
|
||||
_parent = parent;
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
using AsyncEvent;
|
||||
using FileTime.Core.Models;
|
||||
using FileTime.Core.Providers;
|
||||
using SMBLibrary;
|
||||
using SMBLibrary.Client;
|
||||
|
||||
namespace FileTime.Providers.Smb
|
||||
{
|
||||
@@ -17,6 +15,7 @@ namespace FileTime.Providers.Smb
|
||||
public string Name { get; }
|
||||
|
||||
public string? FullName { get; }
|
||||
public string? NativePath { get; }
|
||||
|
||||
public bool IsHidden => false;
|
||||
public bool IsLoaded => _items != null;
|
||||
@@ -40,6 +39,7 @@ namespace FileTime.Providers.Smb
|
||||
|
||||
Name = name;
|
||||
FullName = parent?.FullName == null ? Name : parent.FullName + Constants.SeparatorChar + Name;
|
||||
NativePath = SmbContentProvider.GetNativePath(FullName);
|
||||
Provider = contentProvider;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,8 +24,8 @@ namespace FileTime.Providers.Smb
|
||||
public string? Password { get; private set; }
|
||||
|
||||
public string Name { get; }
|
||||
|
||||
public string? FullName { get; }
|
||||
public string? NativePath { get; }
|
||||
|
||||
public bool IsHidden => false;
|
||||
public bool IsLoaded => _items != null;
|
||||
@@ -51,7 +51,7 @@ namespace FileTime.Providers.Smb
|
||||
Password = password;
|
||||
|
||||
Provider = contentProvider;
|
||||
FullName = Name = path;
|
||||
NativePath = FullName = Name = path;
|
||||
}
|
||||
|
||||
public async Task<IReadOnlyList<IItem>?> GetItems(CancellationToken token = default)
|
||||
|
||||
@@ -17,6 +17,7 @@ namespace FileTime.Providers.Smb
|
||||
public string Name { get; }
|
||||
|
||||
public string? FullName { get; }
|
||||
public string? NativePath { get; }
|
||||
|
||||
public bool IsHidden => false;
|
||||
public bool IsLoaded => _items != null;
|
||||
@@ -40,6 +41,7 @@ namespace FileTime.Providers.Smb
|
||||
|
||||
Name = name;
|
||||
FullName = parent?.FullName == null ? Name : parent.FullName + Constants.SeparatorChar + Name;
|
||||
NativePath = SmbContentProvider.GetNativePath(FullName);
|
||||
Provider = contentProvider;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user