CopyCommandFactory, Copy status

This commit is contained in:
2023-07-01 22:04:00 +02:00
parent bd494526f5
commit 01fce38b7d
9 changed files with 111 additions and 42 deletions

View File

@@ -5,11 +5,11 @@ namespace FileTime.App.Core.Services;
public interface IClipboardService public interface IClipboardService
{ {
Type? CommandType { get; } Type? CommandFactoryType { get; }
IReadOnlyList<FullName> Content { get; } IReadOnlyList<FullName> Content { get; }
void AddContent(FullName absolutePath); void AddContent(FullName absolutePath);
void RemoveContent(FullName absolutePath); void RemoveContent(FullName absolutePath);
void Clear(); void Clear();
void SetCommand<T>() where T : ITransportationCommand; void SetCommand<T>() where T : ITransportationCommandFactory;
} }

View File

@@ -7,7 +7,7 @@ public class ClipboardService : IClipboardService
{ {
private List<FullName> _content; private List<FullName> _content;
public IReadOnlyList<FullName> Content { get; private set; } public IReadOnlyList<FullName> Content { get; private set; }
public Type? CommandType { get; private set; } public Type? CommandFactoryType { get; private set; }
public ClipboardService() public ClipboardService()
{ {
@@ -40,11 +40,11 @@ public class ClipboardService : IClipboardService
{ {
_content = new List<FullName>(); _content = new List<FullName>();
Content = _content.AsReadOnly(); Content = _content.AsReadOnly();
CommandType = null; CommandFactoryType = null;
} }
public void SetCommand<T>() where T : ITransportationCommand public void SetCommand<T>() where T : ITransportationCommandFactory
{ {
CommandType = typeof(T); CommandFactoryType = typeof(T);
} }
} }

View File

@@ -84,7 +84,7 @@ public class ItemManipulationUserCommandHandlerService : UserCommandHandlerServi
private Task Copy() private Task Copy()
{ {
_clipboardService.Clear(); _clipboardService.Clear();
_clipboardService.SetCommand<FileTime.Core.Command.Copy.CopyCommand>(); _clipboardService.SetCommand<FileTime.Core.Command.Copy.CopyCommandFactory>();
if ((_markedItems?.Collection?.Count ?? 0) > 0) if ((_markedItems?.Collection?.Count ?? 0) > 0)
{ {
@@ -120,23 +120,15 @@ public class ItemManipulationUserCommandHandlerService : UserCommandHandlerServi
private async Task Paste(TransportMode mode) private async Task Paste(TransportMode mode)
{ {
if (_clipboardService.CommandType is null) if (_clipboardService.CommandFactoryType is null)
{ {
_userCommunicationService.ShowToastMessage("Clipboard is empty."); _userCommunicationService.ShowToastMessage("Clipboard is empty.");
return; return;
} }
var command = (ITransportationCommand) _serviceProvider.GetRequiredService(_clipboardService.CommandType); //TODO: check _currentLocation?.FullName
command.TransportMode = mode; var commandFactory = (ITransportationCommandFactory) _serviceProvider.GetRequiredService(_clipboardService.CommandFactoryType);
var command = commandFactory.GenerateCommand(_clipboardService.Content, mode, _currentLocation?.FullName);
command.Sources.Clear();
foreach (var item in _clipboardService.Content)
{
command.Sources.Add(item);
}
command.Target = _currentLocation?.FullName;
_clipboardService.Clear(); _clipboardService.Clear();

View File

@@ -49,6 +49,7 @@ public static class DependencyInjection
private static IServiceCollection RegisterCommands(this IServiceCollection serviceCollection) private static IServiceCollection RegisterCommands(this IServiceCollection serviceCollection)
{ {
return serviceCollection return serviceCollection
.AddCommands()
.AddTransient<CreateContainerCommand>() .AddTransient<CreateContainerCommand>()
.AddTransient<CreateElementCommand>() .AddTransient<CreateElementCommand>()
.AddTransient<CopyCommand>() .AddTransient<CopyCommand>()

View File

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

View File

@@ -0,0 +1,24 @@
using FileTime.Core.Models;
namespace FileTime.Core.Command;
public interface ITransportationCommandFactory
{
ITransportationCommand GenerateCommand(
IReadOnlyCollection<FullName> sources,
TransportMode mode,
FullName targetFullName);
}
public interface ITransportationCommandFactory<out T> : ITransportationCommandFactory where T : ITransportationCommand
{
new T GenerateCommand(IReadOnlyCollection<FullName> sources,
TransportMode mode,
FullName targetFullName);
ITransportationCommand ITransportationCommandFactory.GenerateCommand(
IReadOnlyCollection<FullName> sources,
TransportMode mode,
FullName targetFullName)
=> GenerateCommand(sources, mode, targetFullName);
}

View File

@@ -14,21 +14,32 @@ public class CopyCommand : CommandBase, ITransportationCommand
private readonly List<OperationProgress> _operationProgresses = new(); private readonly List<OperationProgress> _operationProgresses = new();
private readonly BehaviorSubject<OperationProgress?> _currentOperationProgress = new(null); private readonly BehaviorSubject<OperationProgress?> _currentOperationProgress = new(null);
public IList<FullName> Sources { get; } = new List<FullName>(); public IReadOnlyList<FullName> Sources { get; }
public FullName? Target { get; set; } public FullName Target { get; }
public TransportMode? TransportMode { get; set; } = Command.TransportMode.Merge; public TransportMode TransportMode { get; }
public IObservable<OperationProgress?> CurrentOperationProgress { get; } public IObservable<OperationProgress?> CurrentOperationProgress { get; }
public CopyCommand( public CopyCommand(
ITimelessContentProvider timelessContentProvider, ITimelessContentProvider timelessContentProvider,
ICommandSchedulerNotifier commandSchedulerNotifier) ICommandSchedulerNotifier commandSchedulerNotifier,
: base("Copy") IReadOnlyCollection<FullName>? sources,
TransportMode? mode,
FullName? targetFullName)
: base("Copy - Calculating...")
{ {
_timelessContentProvider = timelessContentProvider; _timelessContentProvider = timelessContentProvider;
_commandSchedulerNotifier = commandSchedulerNotifier; _commandSchedulerNotifier = commandSchedulerNotifier;
CurrentOperationProgress = _currentOperationProgress.AsObservable(); CurrentOperationProgress = _currentOperationProgress.AsObservable();
if (sources is null) throw new ArgumentException(nameof(Sources) + " can not be null");
if (targetFullName is null) throw new ArgumentException(nameof(Target) + " can not be null");
if (mode is null) throw new ArgumentException(nameof(TransportMode) + " can not be null");
Sources = new List<FullName>(sources).AsReadOnly();
TransportMode = mode.Value;
Target = targetFullName;
} }
public override Task<CanCommandRun> CanRun(PointInTime currentTime) public override Task<CanCommandRun> CanRun(PointInTime currentTime)
@@ -39,10 +50,6 @@ public class CopyCommand : CommandBase, ITransportationCommand
public override async Task<PointInTime> SimulateCommand(PointInTime currentTime) public override async Task<PointInTime> SimulateCommand(PointInTime currentTime)
{ {
if (Sources == null) throw new ArgumentException(nameof(Sources) + " can not be null");
if (Target == null) throw new ArgumentException(nameof(Target) + " can not be null");
if (TransportMode == null) throw new ArgumentException(nameof(TransportMode) + " can not be null");
var simulateOperation = new SimulateStrategy(_timelessContentProvider); var simulateOperation = new SimulateStrategy(_timelessContentProvider);
var resolvedTarget = await _timelessContentProvider.GetItemByFullNameAsync(Target, currentTime); var resolvedTarget = await _timelessContentProvider.GetItemByFullNameAsync(Target, currentTime);
@@ -50,7 +57,7 @@ public class CopyCommand : CommandBase, ITransportationCommand
currentTime, currentTime,
Sources, Sources,
new AbsolutePath(_timelessContentProvider, resolvedTarget), new AbsolutePath(_timelessContentProvider, resolvedTarget),
TransportMode.Value, TransportMode,
simulateOperation); simulateOperation);
return currentTime.WithDifferences(simulateOperation.NewDiffs); return currentTime.WithDifferences(simulateOperation.NewDiffs);
@@ -58,10 +65,6 @@ public class CopyCommand : CommandBase, ITransportationCommand
public async Task ExecuteAsync(CopyFunc copy) public async Task ExecuteAsync(CopyFunc copy)
{ {
if (Sources == null) throw new ArgumentException(nameof(Sources) + " can not be null");
if (Target == null) throw new ArgumentException(nameof(Target) + " can not be null");
if (TransportMode == null) throw new ArgumentException(nameof(TransportMode) + " can not be null");
var currentTime = PointInTime.Present; var currentTime = PointInTime.Present;
await CalculateProgressAsync(currentTime); await CalculateProgressAsync(currentTime);
@@ -74,17 +77,13 @@ public class CopyCommand : CommandBase, ITransportationCommand
currentTime, currentTime,
Sources, Sources,
new AbsolutePath(_timelessContentProvider, resolvedTarget), new AbsolutePath(_timelessContentProvider, resolvedTarget),
TransportMode.Value, TransportMode,
copyOperation); copyOperation);
//await TimeRunner.RefreshContainer.InvokeAsync(this, Target); //await TimeRunner.RefreshContainer.InvokeAsync(this, Target);
} }
private async Task CalculateProgressAsync(PointInTime currentTime) private async Task CalculateProgressAsync(PointInTime currentTime)
{ {
if (Sources == null) throw new ArgumentException(nameof(Sources) + " can not be null");
if (Target == null) throw new ArgumentException(nameof(Target) + " can not be null");
if (TransportMode == null) throw new ArgumentException(nameof(TransportMode) + " can not be null");
var calculateOperation = new CalculateStrategy(); var calculateOperation = new CalculateStrategy();
var resolvedTarget = await _timelessContentProvider.GetItemByFullNameAsync(Target, currentTime); var resolvedTarget = await _timelessContentProvider.GetItemByFullNameAsync(Target, currentTime);
@@ -92,7 +91,7 @@ public class CopyCommand : CommandBase, ITransportationCommand
currentTime, currentTime,
Sources, Sources,
new AbsolutePath(_timelessContentProvider, resolvedTarget), new AbsolutePath(_timelessContentProvider, resolvedTarget),
TransportMode.Value, TransportMode,
calculateOperation); calculateOperation);
_operationProgresses.Clear(); _operationProgresses.Clear();
@@ -108,6 +107,24 @@ public class CopyCommand : CommandBase, ITransportationCommand
return (int) (data.Sum(d => d.Progress) * 100 / total); return (int) (data.Sum(d => d.Progress) * 100 / total);
}) })
.Subscribe(SetTotalProgress); .Subscribe(SetTotalProgress);
if (Sources.Count == 1)
{
SetDisplayLabel($"Copy - {Sources.First().GetName()}");
}
else
{
_operationProgresses
.Select(o => o.IsDone)
.CombineLatest()
.Subscribe(statuses =>
{
var done = statuses.Count(s => s) + 1;
SetDisplayLabel($"Copy - {done} / {statuses.Count}");
});
}
} }
private async Task TraverseTree( private async Task TraverseTree(

View File

@@ -0,0 +1,25 @@
using FileTime.Core.Models;
using FileTime.Core.Timeline;
namespace FileTime.Core.Command.Copy;
public class CopyCommandFactory : ITransportationCommandFactory<CopyCommand>
{
private readonly ITimelessContentProvider _timelessContentProvider;
private readonly ICommandSchedulerNotifier _commandSchedulerNotifier;
public CopyCommandFactory(
ITimelessContentProvider timelessContentProvider,
ICommandSchedulerNotifier commandSchedulerNotifier)
{
_timelessContentProvider = timelessContentProvider;
_commandSchedulerNotifier = commandSchedulerNotifier;
}
public CopyCommand GenerateCommand(
IReadOnlyCollection<FullName> sources,
TransportMode mode,
FullName targetFullName)
=> new(_timelessContentProvider, _commandSchedulerNotifier, sources, mode, targetFullName);
}

View File

@@ -0,0 +1,10 @@
using FileTime.Core.Command.Copy;
using Microsoft.Extensions.DependencyInjection;
namespace FileTime.Core.Command;
public static class Startup
{
public static IServiceCollection AddCommands(this IServiceCollection serviceCollection)
=> serviceCollection.AddSingleton<CopyCommandFactory>();
}