Select item upon entering container

This commit is contained in:
2022-05-24 18:40:24 +02:00
parent 8167909781
commit c08e345c2f
10 changed files with 127 additions and 25 deletions

View File

@@ -36,7 +36,7 @@ public static class DynamicDataExtensions
public void OnCompleted() public void OnCompleted()
{ {
Disposable?.Dispose(); Disposable?.Dispose();
_taskCompletionSource.SetResult(default(TTaskResult)); _taskCompletionSource.SetResult(default);
} }
} }
@@ -60,13 +60,12 @@ public static class DynamicDataExtensions
var context = new DisposableContext<IReadOnlyCollection<AbsolutePath>, IEnumerable<AbsolutePath>?>(r => r, var context = new DisposableContext<IReadOnlyCollection<AbsolutePath>, IEnumerable<AbsolutePath>?>(r => r,
taskCompletionSource); taskCompletionSource);
var disposable = stream context.Disposable = stream
.Subscribe( .Subscribe(
context.OnNext, context.OnNext,
context.OnError, context.OnError,
context.OnCompleted context.OnCompleted
); );
context.Disposable = disposable;
return taskCompletionSource.Task; return taskCompletionSource.Task;
} }

View File

@@ -0,0 +1,16 @@
namespace FileTime.Core.Extensions;
public static class TaskExtensions
{
public static async Task<T?> AwaitWithTimeout<T>(this Task<T> task, int timeout, T? defaultValue = default)
{
if (await Task.WhenAny(task, Task.Delay(timeout)) == task)
{
return task.Result;
}
else
{
return defaultValue;
}
}
}

View File

@@ -0,0 +1,54 @@
using FileTime.Core.Models;
namespace FileTime.Core.Helper;
public static class PathHelper
{
public static string GetLongerPath(string? oldPath, string? newPath)
{
var oldPathParts = oldPath?.Split(Constants.SeparatorChar) ?? Array.Empty<string>();
var newPathParts = newPath?.Split(Constants.SeparatorChar) ?? Array.Empty<string>();
var commonPathParts = new List<string>();
var max = oldPathParts.Length > newPathParts.Length ? oldPathParts.Length : newPathParts.Length;
for (var i = 0; i < max; i++)
{
if (newPathParts.Length <= i)
{
commonPathParts.AddRange(oldPathParts.Skip(i));
break;
}
else if (oldPathParts.Length <= i || oldPathParts[i] != newPathParts[i])
{
commonPathParts.AddRange(newPathParts.Skip(i));
break;
}
else if (oldPathParts[i] == newPathParts[i])
{
commonPathParts.Add(oldPathParts[i]);
}
}
return string.Join(Constants.SeparatorChar, commonPathParts);
}
public static string GetCommonPath(string? path1, string? path2)
{
var path1Parts = path1?.Split(Constants.SeparatorChar) ?? Array.Empty<string>();
var path2Parts = path2?.Split(Constants.SeparatorChar) ?? Array.Empty<string>();
var commonPathParts = new List<string>();
var max = path1Parts.Length > path2Parts.Length ? path2Parts.Length : path1Parts.Length;
for (var i = 0; i < max; i++)
{
if (path1Parts[i] != path2Parts[i]) break;
commonPathParts.Add(path1Parts[i]);
}
return string.Join(Constants.SeparatorChar, commonPathParts);
}
}

View File

@@ -9,13 +9,12 @@ public class CommandTimeState
public bool ForceRun { get; set; } public bool ForceRun { get; set; }
public ExecutionState ExecutionState { get; set; } public ExecutionState ExecutionState { get; set; }
public CommandTimeState(ICommand command, PointInTime? startTime) public CommandTimeState(ICommand command)
{ {
Command = command; Command = command;
Task.Run(async () => await UpdateState(startTime)).Wait();
} }
public async Task UpdateState(PointInTime? startPoint) public async Task UpdateStateAsync(PointInTime? startPoint)
{ {
CanRun = startPoint == null ? CanCommandRun.False : await Command.CanRun(startPoint); CanRun = startPoint == null ? CanCommandRun.False : await Command.CanRun(startPoint);
} }

View File

@@ -31,7 +31,8 @@ public class ParallelCommands
var currentTime = startTime; var currentTime = startTime;
foreach (var command in commands) foreach (var command in commands)
{ {
CommandTimeState commandTimeState = new(command, currentTime); var commandTimeState = new CommandTimeState(command);
await commandTimeState.UpdateStateAsync(currentTime);
if (currentTime != null) if (currentTime != null)
{ {
var canRun = await command.CanRun(currentTime); var canRun = await command.CanRun(currentTime);
@@ -53,7 +54,9 @@ public class ParallelCommands
public async Task AddCommand(ICommand command) public async Task AddCommand(ICommand command)
{ {
_commands.Add(new CommandTimeState(command, Result)); var commandTimeState = new CommandTimeState(command);
await commandTimeState.UpdateStateAsync(Result);
_commands.Add(commandTimeState);
if (Result != null) if (Result != null)
{ {
Result = await command.SimulateCommand(Result); Result = await command.SimulateCommand(Result);
@@ -63,15 +66,15 @@ public class ParallelCommands
public async Task<PointInTime?> RefreshResult(PointInTime? startPoint) public async Task<PointInTime?> RefreshResult(PointInTime? startPoint)
{ {
var result = startPoint; var result = startPoint;
foreach (var command in _commands) foreach (var commandTimeState in _commands)
{ {
await command.UpdateState(result); await commandTimeState.UpdateStateAsync(result);
if (result != null) if (result != null)
{ {
var canRun = await command.Command.CanRun(result); var canRun = await commandTimeState.Command.CanRun(result);
if (canRun == CanCommandRun.True || (canRun == CanCommandRun.Forcable && command.ForceRun)) if (canRun == CanCommandRun.True || (canRun == CanCommandRun.Forcable && commandTimeState.ForceRun))
{ {
result = await command.Command.SimulateCommand(result); result = await commandTimeState.Command.SimulateCommand(result);
} }
else else
{ {

View File

@@ -41,7 +41,7 @@ public abstract class CreateItemBase : IExecutableCommand, IInitable<FullName, s
var parent = await ResolveParentAsync(); var parent = await ResolveParentAsync();
if (parent is not IContainer parentContainer) return CanCommandRun.False; if (parent is not IContainer parentContainer) return CanCommandRun.False;
var items = await parentContainer.Items.GetItemsAsync(); var items = await parentContainer.Items.GetItemsAsync().AwaitWithTimeout(10, Enumerable.Empty<AbsolutePath>());
if (items is null) return CanCommandRun.Forcable; if (items is null) return CanCommandRun.Forcable;
var existingItem = items.FirstOrDefault(i => i.Path.GetName() == NewItemName); var existingItem = items.FirstOrDefault(i => i.Path.GetName() == NewItemName);

View File

@@ -2,6 +2,7 @@ using System.Reactive.Linq;
using System.Reactive.Subjects; using System.Reactive.Subjects;
using DynamicData; using DynamicData;
using DynamicData.Alias; using DynamicData.Alias;
using FileTime.Core.Helper;
using FileTime.Core.Models; using FileTime.Core.Models;
using FileTime.Core.Timeline; using FileTime.Core.Timeline;
@@ -14,6 +15,7 @@ public class Tab : ITab
private readonly BehaviorSubject<IContainer?> _currentLocationForced = new(null); private readonly BehaviorSubject<IContainer?> _currentLocationForced = new(null);
private readonly BehaviorSubject<AbsolutePath?> _currentSelectedItem = new(null); private readonly BehaviorSubject<AbsolutePath?> _currentSelectedItem = new(null);
private readonly SourceList<ItemFilter> _itemFilters = new(); private readonly SourceList<ItemFilter> _itemFilters = new();
private FullName? _lastDeepestSelected;
private AbsolutePath? _currentSelectedItemCached; private AbsolutePath? _currentSelectedItemCached;
private PointInTime _currentPointInTime; private PointInTime _currentPointInTime;
@@ -77,6 +79,11 @@ public class Tab : ITab
{ {
_currentSelectedItemCached = s; _currentSelectedItemCached = s;
_currentSelectedItem.OnNext(s); _currentSelectedItem.OnNext(s);
if (s is not null)
{
_lastDeepestSelected = new FullName(PathHelper.GetLongerPath(_lastDeepestSelected?.Path, s.Path.Path));
}
}); });
} }
@@ -89,8 +96,32 @@ public class Tab : ITab
private AbsolutePath? GetSelectedItemByItems(IEnumerable<IItem> items) private AbsolutePath? GetSelectedItemByItems(IEnumerable<IItem> items)
{ {
//TODO: if (!items.Any()) return null;
return new AbsolutePath(_timelessContentProvider, items.First());
var newSelectedItem = new AbsolutePath(_timelessContentProvider, items.First());
if (_lastDeepestSelected is not null)
{
var parentPath = items.First().FullName?.GetParent()?.Path;
if (parentPath is not null && _lastDeepestSelected.Path.StartsWith(parentPath))
{
var itemNameToSelect = _lastDeepestSelected.Path
.Split(Constants.SeparatorChar)
.Skip((parentPath?.Split(Constants.SeparatorChar).Length) ?? 0)
.FirstOrDefault();
var itemToSelect = items.FirstOrDefault(i => i.FullName?.GetName() == itemNameToSelect);
if (itemToSelect != null)
{
newSelectedItem = new AbsolutePath(_timelessContentProvider, itemToSelect);
}
}
}
_lastDeepestSelected = new FullName(PathHelper.GetLongerPath(_lastDeepestSelected?.Path, newSelectedItem.Path.Path));
return newSelectedItem;
} }
public void SetCurrentLocation(IContainer newLocation) => _currentLocation.OnNext(newLocation); public void SetCurrentLocation(IContainer newLocation) => _currentLocation.OnNext(newLocation);

View File

@@ -27,7 +27,7 @@ public class LocalCommandExecutor : ILocalCommandExecutor
{ {
await _commandRunner.RunCommandAsync(context.Command); await _commandRunner.RunCommandAsync(context.Command);
} }
catch(Exception ex){} catch (Exception ex) { }
CommandFinished.Invoke(this, context.Command); CommandFinished.Invoke(this, context.Command);
} }