Fix copy overwrites the source files sometimes

This commit is contained in:
2023-07-03 10:05:41 +02:00
parent 4f9e69f2ab
commit c29df77d39
7 changed files with 49 additions and 44 deletions

View File

@@ -62,12 +62,12 @@ public class SearchTask : ISearchTask
{ {
try try
{ {
_container.IsLoading.OnNext(true); _container.StartLoading();
await TraverseTree(_baseContainer); await TraverseTree(_baseContainer);
} }
finally finally
{ {
_container.IsLoading.OnNext(false); _container.StopLoading();
await _searchingLock.WaitAsync(); await _searchingLock.WaitAsync();
_isSearching = false; _isSearching = false;

View File

@@ -8,5 +8,7 @@ public interface IContainer : IItem
IObservable<IChangeSet<AbsolutePath, string>> Items { get; } IObservable<IChangeSet<AbsolutePath, string>> Items { get; }
ReadOnlyObservableCollection<AbsolutePath> ItemsCollection { get; } ReadOnlyObservableCollection<AbsolutePath> ItemsCollection { get; }
IObservable<bool> IsLoading { get; } IObservable<bool> IsLoading { get; }
bool? IsLoaded { get; }
Task WaitForLoaded(CancellationToken token = default);
bool AllowRecursiveDeletion { get; } bool AllowRecursiveDeletion { get; }
} }

View File

@@ -140,10 +140,9 @@ public class CopyCommand : CommandBase, ITransportationCommand
TransportMode transportMode, TransportMode transportMode,
ICopyStrategy copyOperation) ICopyStrategy copyOperation)
{ {
var resolvedTarget = ((IContainer) await target.ResolveAsync()) ?? throw new Exception();
foreach (var source in sources) foreach (var source in sources)
{ {
var resolvedTarget = (IContainer)await target.ResolveAsync() ?? throw new Exception();
var item = await _timelessContentProvider.GetItemByFullNameAsync(source, currentTime); var item = await _timelessContentProvider.GetItemByFullNameAsync(source, currentTime);
if (item is IContainer container) if (item is IContainer container)

View File

@@ -6,6 +6,7 @@ public static class Helper
{ {
public static async Task<string?> GetNewNameAsync(IContainer resolvedTarget, string name, TransportMode transportMode) public static async Task<string?> GetNewNameAsync(IContainer resolvedTarget, string name, TransportMode transportMode)
{ {
await resolvedTarget.WaitForLoaded();
var items = resolvedTarget.ItemsCollection.ToList(); var items = resolvedTarget.ItemsCollection.ToList();
var newName = name; var newName = name;
var targetNameExists = items.Any(i => i.Path.GetName() == newName); var targetNameExists = items.Any(i => i.Path.GetName() == newName);

View File

@@ -44,9 +44,11 @@ public abstract class ContentProviderBase : IContentProvider
public string? Attributes => null; public string? Attributes => null;
protected BehaviorSubject<bool> IsLoading { get; } = new(false); protected BehaviorSubject<bool> IsLoading { get; } = new(false);
public bool AllowRecursiveDeletion => false;
IObservable<bool> IContainer.IsLoading => IsLoading.AsObservable(); IObservable<bool> IContainer.IsLoading => IsLoading.AsObservable();
public bool? IsLoaded => true;
public Task WaitForLoaded(CancellationToken token = default) => Task.CompletedTask;
public bool AllowRecursiveDeletion => false;
public AbsolutePathType Type => AbsolutePathType.Container; public AbsolutePathType Type => AbsolutePathType.Container;
public PointInTime PointInTime { get; } = PointInTime.Eternal; public PointInTime PointInTime { get; } = PointInTime.Eternal;

View File

@@ -27,6 +27,7 @@ public record Container(
ReadOnlyExtensionCollection Extensions, ReadOnlyExtensionCollection Extensions,
IObservable<IChangeSet<AbsolutePath, string>> Items) : IContainer IObservable<IChangeSet<AbsolutePath, string>> Items) : IContainer
{ {
private readonly Lazy<ReadOnlyObservableCollection<AbsolutePath>> _itemsCollectionLazy = private readonly Lazy<ReadOnlyObservableCollection<AbsolutePath>> _itemsCollectionLazy =
new(() => new(() =>
{ {
@@ -34,12 +35,34 @@ public record Container(
return items; return items;
}); });
private readonly CancellationTokenSource _loadingCancellationTokenSource = new(); private readonly CancellationTokenSource _loadingCancellationTokenSource = new();
private readonly BehaviorSubject<bool> _isLoading = new(false);
public CancellationToken LoadingCancellationToken => _loadingCancellationTokenSource.Token; public CancellationToken LoadingCancellationToken => _loadingCancellationTokenSource.Token;
public BehaviorSubject<bool> IsLoading { get; } = new(false); public IObservable<bool> IsLoading => _isLoading.AsObservable();
IObservable<bool> IContainer.IsLoading => IsLoading.AsObservable(); public bool? IsLoaded { get; private set; }
public AbsolutePathType Type => AbsolutePathType.Container; public AbsolutePathType Type => AbsolutePathType.Container;
public ReadOnlyObservableCollection<AbsolutePath> ItemsCollection => _itemsCollectionLazy.Value; public ReadOnlyObservableCollection<AbsolutePath> ItemsCollection => _itemsCollectionLazy.Value;
public void CancelLoading() => _loadingCancellationTokenSource.Cancel(); public async Task WaitForLoaded(CancellationToken token = default)
{
while (IsLoaded != true) await Task.Delay(1, token);
}
public void StartLoading()
{
_isLoading.OnNext(true);
IsLoaded = false;
}
public void StopLoading()
{
_isLoading.OnNext(false);
IsLoaded = true;
}
public void CancelLoading()
{
_loadingCancellationTokenSource.Cancel();
_isLoading.OnNext(false);
IsLoaded = true;
}
} }

View File

@@ -229,28 +229,6 @@ public sealed partial class LocalContentProvider : ContentProviderBase, ILocalCo
Task.Run(() => LoadChildren(container, directoryInfo, children, pointInTime, exceptions)); Task.Run(() => LoadChildren(container, directoryInfo, children, pointInTime, exceptions));
return container; return container;
IObservable<IChangeSet<AbsolutePath, string>>? InitChildren()
{
if (!initializeChildren) return null;
try
{
var items = GetItemsByContainer(directoryInfo, pointInTime);
var result = new SourceCache<AbsolutePath, string>(i => i.Path.Path);
if (items.Count == 0) return (IObservable<IChangeSet<AbsolutePath, string>>?) result.Connect().StartWithEmpty();
result.AddOrUpdate(items);
return (IObservable<IChangeSet<AbsolutePath, string>>?) result.Connect();
}
catch (Exception e)
{
exceptions.Add(e);
}
return null;
}
} }
private void LoadChildren(Container container, private void LoadChildren(Container container,
@@ -259,16 +237,16 @@ public sealed partial class LocalContentProvider : ContentProviderBase, ILocalCo
PointInTime pointInTime, PointInTime pointInTime,
SourceList<Exception> exceptions) SourceList<Exception> exceptions)
{ {
var lockobj = new object(); var lockObj = new object();
var loadingIndicatorCancellation = new CancellationTokenSource(); var loadingIndicatorCancellation = new CancellationTokenSource();
Task.Run(DelayedLoadingIndicator); Task.Run(DelayedLoadingIndicator);
LoadChildren(); LoadChildren();
lock (lockobj) lock (lockObj)
{ {
loadingIndicatorCancellation.Cancel(); loadingIndicatorCancellation.Cancel();
container.IsLoading.OnNext(false); container.StopLoading();
} }
void LoadChildren() void LoadChildren()
@@ -306,10 +284,10 @@ public sealed partial class LocalContentProvider : ContentProviderBase, ILocalCo
{ {
} }
lock (lockobj) lock (lockObj)
{ {
if (token.IsCancellationRequested) return; if (token.IsCancellationRequested) return;
container.IsLoading.OnNext(true); container.StartLoading();
} }
} }
} }