MoveCommand

This commit is contained in:
2023-07-04 22:07:11 +02:00
parent 718fd53026
commit 453834646b
17 changed files with 263 additions and 22 deletions

View File

@@ -33,4 +33,16 @@ public abstract class CommandBase : ICommand
protected void SetTotalProgress(int totalProgress) => _totalProgress.OnNext(totalProgress);
protected void SetCurrentProgress(int currentProgress) => _currentProgress.OnNext(currentProgress);
protected IDisposable TrackProgress(IEnumerable<OperationProgress> operationProgresses) =>
operationProgresses
.Select(op => op.Progress.Select(p => (Progress: p, TotalProgress: op.TotalCount)))
.CombineLatest()
.Select(data =>
{
var total = data.Sum(d => d.TotalProgress);
if (total == 0) return 0;
return (int)(data.Sum(d => d.Progress) * 100 / total);
})
.Subscribe(SetTotalProgress);
}

View File

@@ -103,16 +103,8 @@ public class CopyCommand : CommandBase, ITransportationCommand
_operationProgresses.Clear();
_operationProgresses.AddRange(calculateOperation.OperationStatuses);
_operationProgresses
.Select(op => op.Progress.Select(p => (Progress: p, TotalProgress: op.TotalCount)))
.CombineLatest()
.Select(data =>
{
var total = data.Sum(d => d.TotalProgress);
if (total == 0) return 0;
return (int)(data.Sum(d => d.Progress) * 100 / total);
})
.Subscribe(SetTotalProgress);
//TODO: Handle IDisposable
TrackProgress(_operationProgresses);
if (Sources.Count == 1)
@@ -127,6 +119,7 @@ public class CopyCommand : CommandBase, ITransportationCommand
.Subscribe(statuses =>
{
var done = statuses.Count(s => s) + 1;
if(done > statuses.Count) done = statuses.Count;
SetDisplayLabel($"Copy - {done} / {statuses.Count}");
});

View File

@@ -0,0 +1,90 @@
using System.Reactive.Subjects;
using FileTime.Core.ContentAccess;
using FileTime.Core.Timeline;
namespace FileTime.Core.Command.Move;
public class MoveCommand : CommandBase, IExecutableCommand
{
private readonly IContentAccessorFactory _contentAccessorFactory;
private readonly ITimelessContentProvider _timelessContentProvider;
private readonly ICommandSchedulerNotifier _commandSchedulerNotifier;
private readonly List<OperationProgress> _operationProgresses = new();
private readonly BehaviorSubject<OperationProgress?> _currentOperationProgress = new(null);
public IReadOnlyList<ItemToMove> ItemsToMove { get; }
internal MoveCommand(
IEnumerable<ItemToMove> itemsToMove,
IContentAccessorFactory contentAccessorFactory,
ITimelessContentProvider timelessContentProvider,
ICommandSchedulerNotifier commandSchedulerNotifier)
: base("Move")
{
_contentAccessorFactory = contentAccessorFactory;
_timelessContentProvider = timelessContentProvider;
_commandSchedulerNotifier = commandSchedulerNotifier;
ItemsToMove = itemsToMove.ToList().AsReadOnly();
}
public override Task<CanCommandRun> CanRun(PointInTime currentTime)
{
//TODO
return Task.FromResult(CanCommandRun.True);
}
public override Task<PointInTime> SimulateCommand(PointInTime currentTime)
{
//TODO
return Task.FromResult(currentTime);
}
public async Task Execute()
{
Calculate();
await Move();
}
private void Calculate()
{
_operationProgresses.Clear();
_operationProgresses.AddRange(ItemsToMove.Select(i => new OperationProgress(i.Source.Path, 1)));
//TODO: Handle IDisposable
TrackProgress(_operationProgresses);
}
private async Task Move()
{
Dictionary<string, IItemMover> itemMovers = new();
foreach (var itemToMove in ItemsToMove)
{
var currentOperationProgress =_operationProgresses.Find(p => p.Key == itemToMove.Source.Path)!;
_currentOperationProgress.OnNext(currentOperationProgress);
var sourceItem = await _timelessContentProvider.GetItemByFullNameAsync(itemToMove.Source, PointInTime.Present);
var itemMover = GetOrAddItemMover(sourceItem.Provider);
await itemMover.RenameAsync(sourceItem.Provider, itemToMove.Source, itemToMove.Target);
if (itemToMove.Source.GetParent() is { } parent)
await _commandSchedulerNotifier.RefreshContainer(parent);
currentOperationProgress.SetProgress(1);
}
IItemMover GetOrAddItemMover(IContentProvider provider)
{
if (itemMovers.TryGetValue(provider.Name, out var mover))
{
return mover;
}
var itemMover = _contentAccessorFactory.GetItemMover(provider);
itemMovers.Add(provider.Name, itemMover);
return itemMover;
}
}
}

View File

@@ -0,0 +1,24 @@
using FileTime.Core.ContentAccess;
using FileTime.Core.Timeline;
namespace FileTime.Core.Command.Move;
public class MoveCommandFactory
{
private readonly IContentAccessorFactory _contentAccessorFactory;
private readonly ITimelessContentProvider _timelessContentProvider;
private readonly ICommandSchedulerNotifier _commandSchedulerNotifier;
public MoveCommandFactory(
IContentAccessorFactory contentAccessorFactory,
ITimelessContentProvider timelessContentProvider,
ICommandSchedulerNotifier commandSchedulerNotifier)
{
_contentAccessorFactory = contentAccessorFactory;
_timelessContentProvider = timelessContentProvider;
_commandSchedulerNotifier = commandSchedulerNotifier;
}
public MoveCommand GenerateCommand(IEnumerable<ItemToMove> itemsToMove)
=> new(itemsToMove, _contentAccessorFactory, _timelessContentProvider, _commandSchedulerNotifier);
}

View File

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