Go to location, Warnings

This commit is contained in:
2022-02-01 13:32:38 +01:00
parent 9824184d90
commit 45ec3ae0b3
10 changed files with 72 additions and 34 deletions

View File

@@ -9,7 +9,7 @@ namespace FileTime.Core.Command
private Func<IContainer, string, Task<IContainer>>? _createContainer;
private TimeRunner? _timeRunner;
public IList<AbsolutePath>? Sources { get; } = new List<AbsolutePath>();
public IList<AbsolutePath> Sources { get; } = new List<AbsolutePath>();
public IContainer? Target { get; set; }

View File

@@ -4,7 +4,7 @@ namespace FileTime.Core.Command
{
public interface ITransportationCommand : ICommand
{
IList<AbsolutePath>? Sources { get; }
IList<AbsolutePath> Sources { get; }
IContainer? Target { get; set;}
TransportMode? TransportMode { get; set; }
}

View File

@@ -5,7 +5,7 @@ namespace FileTime.Core.Command
{
public class MoveCommand : ITransportationCommand
{
public IList<AbsolutePath>? Sources { get; } = new List<AbsolutePath>();
public IList<AbsolutePath> Sources { get; } = new List<AbsolutePath>();
public IContainer? Target { get; set; }
public TransportMode? TransportMode { get; set; } = Command.TransportMode.Merge;

View File

@@ -6,7 +6,9 @@ namespace FileTime.Core.Components
public class Tab
{
private IItem? _currentSelectedItem;
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
private IContainer _currentLocation;
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
private string? _lastPath;
public int CurrentSelectedIndex { get; private set; }

View File

@@ -12,14 +12,18 @@ namespace FileTime.Core.Providers
private readonly IReadOnlyList<IItem>? _items;
private readonly IReadOnlyList<IElement>? _elements = new List<IElement>().AsReadOnly();
#pragma warning disable CS8603 // Possible null reference return.
public string Name => null;
#pragma warning restore CS8603 // Possible null reference return.
public string? FullName => null;
public bool IsHidden => false;
public bool IsLoaded => true;
#pragma warning disable CS8603 // Possible null reference return.
public IContentProvider Provider => null;
#pragma warning restore CS8603 // Possible null reference return.
public bool CanDelete => false;
public bool CanRename => false;

View File

@@ -74,7 +74,7 @@ namespace FileTime.Core.Timeline
}
});
UpdateReadOnlyCommands();
await UpdateReadOnlyCommands();
}
public async Task TryStartCommandRunner()

View File

@@ -13,7 +13,7 @@ namespace FileTime.Avalonia
{
public static IServiceProvider ServiceProvider { get; private set; }
public App()
static App()
{
ServiceProvider ??= DependencyInjection
.RegisterDefaultServices()

View File

@@ -41,8 +41,8 @@ namespace FileTime.Avalonia.ViewModels
private IClipboard _clipboard;
private TimeRunner _timeRunner;
private IEnumerable<IContentProvider>? _contentProviders;
private Action? _inputHandler;
private IEnumerable<IContentProvider> _contentProviders;
private Func<Task>? _inputHandler;
[Property]
private string _text;
@@ -68,7 +68,7 @@ namespace FileTime.Avalonia.ViewModels
{
_clipboard = App.ServiceProvider.GetService<IClipboard>()!;
_timeRunner = App.ServiceProvider.GetService<TimeRunner>()!;
_contentProviders = App.ServiceProvider.GetService<IEnumerable<IContentProvider>>();
_contentProviders = App.ServiceProvider.GetService<IEnumerable<IContentProvider>>()!;
var inputInterface = (BasicInputHandler)App.ServiceProvider.GetService<IInputInterface>()!;
inputInterface.InputHandler = ReadInputs2;
App.ServiceProvider.GetService<TopContainer>();
@@ -107,12 +107,12 @@ namespace FileTime.Avalonia.ViewModels
RootDriveInfos = driveInfos.OrderBy(d => d.Name).ToList();
}
private async Task<IContainer> GetContainerForWindowsDrive(DriveInfo drive)
private async Task<IContainer?> GetContainerForWindowsDrive(DriveInfo drive)
{
return (await LocalContentProvider.GetRootContainers()).FirstOrDefault(d => d.Name == drive.Name.TrimEnd(Path.DirectorySeparatorChar));
}
private async Task<IContainer> GetContainerForLinuxDrive(DriveInfo drive)
private async Task<IContainer?> GetContainerForLinuxDrive(DriveInfo drive)
{
return await LocalContentProvider.GetByPath(drive.Name) as IContainer;
}
@@ -274,13 +274,13 @@ namespace FileTime.Avalonia.ViewModels
public Task CreateContainer()
{
var handler = () =>
var handler = async () =>
{
if (Inputs != null)
{
var container = AppState.SelectedTab.CurrentLocation.Container;
var createContainerCommand = new CreateContainerCommand(new Core.Models.AbsolutePath(container), Inputs[0].Value);
_timeRunner.AddCommand(createContainerCommand).Wait();
await _timeRunner.AddCommand(createContainerCommand);
Inputs = null;
}
};
@@ -292,13 +292,13 @@ namespace FileTime.Avalonia.ViewModels
public Task CreateElement()
{
var handler = () =>
var handler = async () =>
{
if (Inputs != null)
{
var container = AppState.SelectedTab.CurrentLocation.Container;
var createElementCommand = new CreateElementCommand(new Core.Models.AbsolutePath(container), Inputs[0].Value);
_timeRunner.AddCommand(createElementCommand).Wait();
await _timeRunner.AddCommand(createElementCommand);
Inputs = null;
}
};
@@ -346,7 +346,7 @@ namespace FileTime.Avalonia.ViewModels
public async Task Delete()
{
IList<Core.Models.AbsolutePath>? itemsToDelete = null;
IList<AbsolutePath>? itemsToDelete = null;
var askForDelete = false;
var questionText = "";
var shouldDelete = false;
@@ -403,11 +403,11 @@ namespace FileTime.Avalonia.ViewModels
}
else if (shouldDelete)
{
HandleDelete();
await HandleDelete();
}
}
void HandleDelete()
async Task HandleDelete()
{
var deleteCommand = new DeleteCommand();
@@ -416,7 +416,7 @@ namespace FileTime.Avalonia.ViewModels
deleteCommand.ItemsToDelete.Add(itemToDelete);
}
_timeRunner.AddCommand(deleteCommand).Wait();
await _timeRunner.AddCommand(deleteCommand);
_clipboard.Clear();
}
}
@@ -465,12 +465,12 @@ namespace FileTime.Avalonia.ViewModels
var selectedItem = AppState.SelectedTab.SelectedItem?.Item;
if (selectedItem != null)
{
var handler = () =>
var handler = async () =>
{
if (Inputs != null)
{
var renameCommand = new RenameCommand(new Core.Models.AbsolutePath(selectedItem), Inputs[0].Value);
_timeRunner.AddCommand(renameCommand).Wait();
await _timeRunner.AddCommand(renameCommand);
}
};
@@ -502,23 +502,45 @@ namespace FileTime.Avalonia.ViewModels
await _timeRunner.Refresh();
}
private async Task GoToContainer()
private Task GoToContainer()
{
var handler = () =>
var handler = async () =>
{
if (Inputs != null)
{
var path = Inputs[0].Value;
foreach (var contentProvider in _contentProviders)
{
if (contentProvider.CanHandlePath(path))
{
var possibleContainer = await contentProvider.GetByPath(path);
if (possibleContainer is IContainer container)
{
AppState.SelectedTab.OpenContainer(container).Wait();
}
//TODO: multiple possible content provider handler
return;
}
}
}
};
ReadInputs(new List<Core.Interactions.InputElement>() { new Core.Interactions.InputElement("Path", InputType.Text) }, handler);
return Task.CompletedTask;
}
[Command]
public void ProcessInputs()
public async void ProcessInputs()
{
_inputHandler?.Invoke();
try
{
if (_inputHandler != null)
{
await _inputHandler.Invoke();
}
}
catch { }
Inputs = null;
_inputHandler = null;
@@ -683,6 +705,10 @@ namespace FileTime.Avalonia.ViewModels
}
private void ReadInputs(List<Core.Interactions.InputElement> inputs, Action inputHandler)
{
ReadInputs(inputs, () => { inputHandler(); return Task.CompletedTask; });
}
private void ReadInputs(List<Core.Interactions.InputElement> inputs, Func<Task> inputHandler)
{
Inputs = inputs.Select(i => new InputElementWrapper(i, i.DefaultValue)).ToList();
_inputHandler = inputHandler;
@@ -692,13 +718,13 @@ namespace FileTime.Avalonia.ViewModels
{
var waiting = true;
var result = new string[0];
ReadInputs(fields.ToList(), () =>
{
if(Inputs != null)
ReadInputs(fields.ToList(), () =>
{
if (Inputs != null)
{
result = Inputs.Select(i => i.Value).ToArray();
}
waiting = false;
waiting = false;
});
while (waiting) await Task.Delay(100);
@@ -706,7 +732,7 @@ namespace FileTime.Avalonia.ViewModels
return result;
}
private void ShowMessageBox(string text, Action inputHandler)
private void ShowMessageBox(string text, Func<Task> inputHandler)
{
MessageBoxText = text;
_inputHandler = inputHandler;

View File

@@ -42,7 +42,7 @@ namespace FileTime.Avalonia.Views
{
if (_inputElementWrapper == null)
{
e.Handled = e.Handled || await ViewModel?.ProcessKeyDown(e.Key, e.KeyModifiers);
e.Handled = e.Handled || await ViewModel!.ProcessKeyDown(e.Key, e.KeyModifiers);
}
}
@@ -50,7 +50,7 @@ namespace FileTime.Avalonia.Views
{
if (_inputElementWrapper == null)
{
e.Handled = e.Handled || await ViewModel?.ProcessKeyUp(e.Key, e.KeyModifiers);
e.Handled = e.Handled || await ViewModel!.ProcessKeyUp(e.Key, e.KeyModifiers);
}
}

View File

@@ -48,11 +48,13 @@ namespace FileTime.Providers.Local
public async Task<IItem?> GetByPath(string path)
{
path = path.Replace(Path.DirectorySeparatorChar, Constants.SeparatorChar).TrimEnd(Constants.SeparatorChar);
var pathParts = (IsCaseInsensitive ? path.ToLower() : path).TrimStart(Constants.SeparatorChar).Split(Constants.SeparatorChar);
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && pathParts.Length == 1 && pathParts[0] == "") return this;
var rootContainer = _rootContainers.FirstOrDefault(c => NormalizePath(c.Name) == NormalizePath(pathParts[0]));
var normalizedRootContainerName = NormalizePath(pathParts[0]);
var rootContainer = _rootContainers.FirstOrDefault(c => NormalizePath(c.Name) == normalizedRootContainerName);
if (rootContainer == null)
{
@@ -77,7 +79,11 @@ namespace FileTime.Providers.Local
internal string NormalizePath(string path) => IsCaseInsensitive ? path.ToLower() : path;
public bool CanHandlePath(string path) => _rootContainers.Any(r => path.StartsWith(r.Name));
public bool CanHandlePath(string path)
{
var normalizedPath = NormalizePath(path);
return _rootContainers.Any(r => normalizedPath.StartsWith(NormalizePath(r.Name)));
}
public void SetParent(IContainer container) => _parent = container;
public Task<IReadOnlyList<IContainer>> GetRootContainers(CancellationToken token = default) => Task.FromResult(_rootContainers);