SMB, GUI imput handler, ThreadSafe SMB
This commit is contained in:
@@ -3,6 +3,7 @@ using FileTime.Avalonia.Application;
|
||||
using FileTime.Avalonia.Services;
|
||||
using FileTime.Avalonia.ViewModels;
|
||||
using FileTime.Core.Command;
|
||||
using FileTime.Core.Interactions;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace FileTime.Avalonia
|
||||
@@ -13,7 +14,8 @@ namespace FileTime.Avalonia
|
||||
{
|
||||
return serviceCollection
|
||||
.AddSingleton<AppState>()
|
||||
.AddTransient<MainPageViewModel>();
|
||||
.AddTransient<MainPageViewModel>()
|
||||
.AddSingleton<IInputInterface, BasicInputHandler>();
|
||||
}
|
||||
internal static IServiceCollection AddServices(this IServiceCollection serviceCollection)
|
||||
{
|
||||
|
||||
@@ -15,8 +15,9 @@ namespace FileTime.Avalonia.ViewModels
|
||||
{
|
||||
[ViewModel]
|
||||
[Inject(typeof(ItemNameConverterService))]
|
||||
public partial class ContainerViewModel : IItemViewModel
|
||||
public partial class ContainerViewModel : IItemViewModel, IDisposable
|
||||
{
|
||||
private bool _disposed;
|
||||
private bool _isRefreshing;
|
||||
private bool _isInitialized;
|
||||
private INewItemProcessor _newItemProcessor;
|
||||
@@ -128,13 +129,20 @@ namespace FileTime.Avalonia.ViewModels
|
||||
{
|
||||
_isRefreshing = true;
|
||||
|
||||
var containers = (await _container.GetContainers()).Select(c => AdoptOrCreateItem(c, (c2) => new ContainerViewModel(_newItemProcessor, this, c2, ItemNameConverterService))).ToList();
|
||||
var elements = (await _container.GetElements()).Select(e => AdoptOrCreateItem(e, (e2) => new ElementViewModel(e2, this, ItemNameConverterService))).ToList();
|
||||
var containers = (await _container.GetContainers())!.Select(c => AdoptOrReuseOrCreateItem(c, (c2) => new ContainerViewModel(_newItemProcessor, this, c2, ItemNameConverterService))).ToList();
|
||||
var elements = (await _container.GetElements())!.Select(e => AdoptOrReuseOrCreateItem(e, (e2) => new ElementViewModel(e2, this, ItemNameConverterService))).ToList();
|
||||
|
||||
var containersToRemove = _containers.Except(containers);
|
||||
|
||||
_containers.Clear();
|
||||
_elements.Clear();
|
||||
_items.Clear();
|
||||
|
||||
foreach (var containerToRemove in containersToRemove)
|
||||
{
|
||||
containerToRemove?.Dispose();
|
||||
}
|
||||
|
||||
foreach (var container in containers)
|
||||
{
|
||||
if (initializeChildren) await container.Init(false);
|
||||
@@ -161,11 +169,14 @@ namespace FileTime.Avalonia.ViewModels
|
||||
_isRefreshing = false;
|
||||
}
|
||||
|
||||
private TResult AdoptOrCreateItem<T, TResult>(T item, Func<T, TResult> generator) where T : IItem
|
||||
private TResult AdoptOrReuseOrCreateItem<T, TResult>(T item, Func<T, TResult> generator) where T : class, IItem
|
||||
{
|
||||
var itemToAdopt = ChildrenToAdopt.Find(i => i.Item.Name == item.Name);
|
||||
var itemToAdopt = ChildrenToAdopt.Find(i => i.Item == item);
|
||||
if (itemToAdopt is TResult itemViewModel) return itemViewModel;
|
||||
|
||||
var existingViewModel = _items?.FirstOrDefault(i => i.Item == item);
|
||||
if (existingViewModel is TResult itemViewModelToReuse) return itemViewModelToReuse;
|
||||
|
||||
return generator(item);
|
||||
}
|
||||
|
||||
@@ -177,6 +188,7 @@ namespace FileTime.Avalonia.ViewModels
|
||||
foreach (var container in _containers)
|
||||
{
|
||||
container.Unload(true);
|
||||
container.Dispose();
|
||||
container.ChildrenToAdopt.Clear();
|
||||
}
|
||||
}
|
||||
@@ -203,5 +215,25 @@ namespace FileTime.Avalonia.ViewModels
|
||||
if (!_isInitialized) await Task.Run(Refresh);
|
||||
return _items;
|
||||
}
|
||||
|
||||
~ContainerViewModel()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
private void Dispose(bool disposing)
|
||||
{
|
||||
if (!_disposed && disposing)
|
||||
{
|
||||
Container.Refreshed.Remove(Container_Refreshed);
|
||||
}
|
||||
_disposed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ using FileTime.App.Core.Clipboard;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using FileTime.Core.Command;
|
||||
using FileTime.Core.Timeline;
|
||||
using FileTime.Core.Providers;
|
||||
|
||||
namespace FileTime.Avalonia.ViewModels
|
||||
{
|
||||
@@ -40,7 +41,7 @@ namespace FileTime.Avalonia.ViewModels
|
||||
|
||||
private IClipboard _clipboard;
|
||||
private TimeRunner _timeRunner;
|
||||
|
||||
private IEnumerable<IContentProvider>? _contentProviders;
|
||||
private Action? _inputHandler;
|
||||
|
||||
[Property]
|
||||
@@ -67,6 +68,11 @@ namespace FileTime.Avalonia.ViewModels
|
||||
{
|
||||
_clipboard = App.ServiceProvider.GetService<IClipboard>()!;
|
||||
_timeRunner = App.ServiceProvider.GetService<TimeRunner>()!;
|
||||
_contentProviders = App.ServiceProvider.GetService<IEnumerable<IContentProvider>>();
|
||||
var inputInterface = (BasicInputHandler)App.ServiceProvider.GetService<IInputInterface>()!;
|
||||
inputInterface.InputHandler = ReadInputs2;
|
||||
App.ServiceProvider.GetService<TopContainer>();
|
||||
|
||||
_timeRunner.CommandsChanged += (o, e) => OnPropertyChanged(nameof(TimelineCommands));
|
||||
InitCommandBindings();
|
||||
|
||||
@@ -496,6 +502,19 @@ namespace FileTime.Avalonia.ViewModels
|
||||
await _timeRunner.Refresh();
|
||||
}
|
||||
|
||||
private async Task GoToContainer()
|
||||
{
|
||||
var handler = () =>
|
||||
{
|
||||
if (Inputs != null)
|
||||
{
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
ReadInputs(new List<Core.Interactions.InputElement>() { new Core.Interactions.InputElement("Path", InputType.Text) }, handler);
|
||||
}
|
||||
|
||||
[Command]
|
||||
public void ProcessInputs()
|
||||
{
|
||||
@@ -669,6 +688,24 @@ namespace FileTime.Avalonia.ViewModels
|
||||
_inputHandler = inputHandler;
|
||||
}
|
||||
|
||||
public async Task<string?[]> ReadInputs2(IEnumerable<Core.Interactions.InputElement> fields)
|
||||
{
|
||||
var waiting = true;
|
||||
var result = new string[0];
|
||||
ReadInputs(fields.ToList(), () =>
|
||||
{
|
||||
if(Inputs != null)
|
||||
{
|
||||
result = Inputs.Select(i => i.Value).ToArray();
|
||||
}
|
||||
waiting = false;
|
||||
});
|
||||
|
||||
while (waiting) await Task.Delay(100);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void ShowMessageBox(string text, Action inputHandler)
|
||||
{
|
||||
MessageBoxText = text;
|
||||
@@ -847,6 +884,11 @@ namespace FileTime.Avalonia.ViewModels
|
||||
FileTime.App.Core.Command.Commands.Refresh,
|
||||
new KeyWithModifiers[]{new KeyWithModifiers(Key.R)},
|
||||
RefreshCurrentLocation),
|
||||
new CommandBinding(
|
||||
"go to",
|
||||
FileTime.App.Core.Command.Commands.Refresh,
|
||||
new KeyWithModifiers[]{new KeyWithModifiers(Key.L, ctrl: true)},
|
||||
GoToContainer),
|
||||
};
|
||||
var universalCommandBindings = new List<CommandBinding>()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user