Smb save servers, auth
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
using FileTime.Avalonia.Application;
|
||||
using FileTime.Core.Models;
|
||||
using FileTime.Core.Providers;
|
||||
|
||||
namespace FileTime.Avalonia.Models.Persistence
|
||||
{
|
||||
@@ -11,7 +13,8 @@ namespace FileTime.Avalonia.Models.Persistence
|
||||
|
||||
public TabState(TabContainer tab)
|
||||
{
|
||||
Path = tab.CurrentLocation.Item.FullName;
|
||||
var item = tab.CurrentLocation.Item;
|
||||
Path = item is IContentProvider contentProvider ? Constants.ContentProviderProtocol + contentProvider.Name : item.FullName;
|
||||
Number = tab.TabNumber;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ using FileTime.Core.Components;
|
||||
using FileTime.Core.Providers;
|
||||
using FileTime.Providers.Local;
|
||||
using FileTime.Core.Models;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace FileTime.Avalonia.Services
|
||||
{
|
||||
@@ -23,22 +24,26 @@ namespace FileTime.Avalonia.Services
|
||||
private readonly string _settingsPath;
|
||||
private readonly IEnumerable<IContentProvider> _contentProviders;
|
||||
private readonly LocalContentProvider _localContentProvider;
|
||||
private readonly ILogger<StatePersistenceService> _logger;
|
||||
|
||||
public StatePersistenceService(
|
||||
AppState appState,
|
||||
ItemNameConverterService itemNameConverterService,
|
||||
IEnumerable<IContentProvider> contentProviders,
|
||||
LocalContentProvider localContentProvider)
|
||||
LocalContentProvider localContentProvider,
|
||||
ILogger<StatePersistenceService> logger)
|
||||
{
|
||||
_appState = appState;
|
||||
_itemNameConverterService = itemNameConverterService;
|
||||
_contentProviders = contentProviders;
|
||||
_localContentProvider = localContentProvider;
|
||||
_logger = logger;
|
||||
_settingsPath = Path.Combine(Program.AppDataRoot, "savedState.json");
|
||||
|
||||
_jsonOptions = new JsonSerializerOptions()
|
||||
{
|
||||
PropertyNameCaseInsensitive = true
|
||||
PropertyNameCaseInsensitive = true,
|
||||
WriteIndented = true
|
||||
};
|
||||
}
|
||||
|
||||
@@ -55,7 +60,10 @@ namespace FileTime.Avalonia.Services
|
||||
await RestoreTabs(state.TabStates);
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.LogError(e, "Unkown exception while restoring app state.");
|
||||
}
|
||||
}
|
||||
|
||||
public void SaveStates()
|
||||
@@ -97,33 +105,48 @@ namespace FileTime.Avalonia.Services
|
||||
|
||||
foreach (var tab in tabStates.Tabs)
|
||||
{
|
||||
if (tab.Path == null) continue;
|
||||
|
||||
IItem? pathItem = null;
|
||||
foreach (var contentProvider in _contentProviders)
|
||||
try
|
||||
{
|
||||
if (contentProvider.CanHandlePath(tab.Path))
|
||||
if (tab.Path == null) continue;
|
||||
|
||||
IItem? pathItem = null;
|
||||
if (tab.Path.StartsWith(Constants.ContentProviderProtocol))
|
||||
{
|
||||
pathItem = await contentProvider.GetByPath(tab.Path, true);
|
||||
if (pathItem != null) break;
|
||||
var contentProviderName = tab.Path.Substring(Constants.ContentProviderProtocol.Length);
|
||||
pathItem = _contentProviders.FirstOrDefault(c => c.Name == contentProviderName);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var contentProvider in _contentProviders)
|
||||
{
|
||||
if (contentProvider.CanHandlePath(tab.Path))
|
||||
{
|
||||
pathItem = await contentProvider.GetByPath(tab.Path, true);
|
||||
if (pathItem != null) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var container = pathItem switch
|
||||
{
|
||||
IContainer c => c,
|
||||
IElement e => e.GetParent(),
|
||||
_ => null
|
||||
};
|
||||
|
||||
if (container == null) continue;
|
||||
|
||||
var newTab = new Tab();
|
||||
await newTab.Init(container);
|
||||
|
||||
var newTabContainer = new TabContainer(newTab, _localContentProvider, _itemNameConverterService);
|
||||
await newTabContainer.Init(tab.Number);
|
||||
_appState.Tabs.Add(newTabContainer);
|
||||
}
|
||||
|
||||
var container = pathItem switch
|
||||
catch (Exception e)
|
||||
{
|
||||
IContainer c => c,
|
||||
IElement e => e.GetParent(),
|
||||
_ => null
|
||||
};
|
||||
|
||||
if (container == null) continue;
|
||||
|
||||
var newTab = new Tab();
|
||||
await newTab.Init(container);
|
||||
|
||||
var newTabContainer = new TabContainer(newTab, _localContentProvider, _itemNameConverterService);
|
||||
await newTabContainer.Init(tab.Number);
|
||||
_appState.Tabs.Add(newTabContainer);
|
||||
_logger.LogError(e, "Unkown exception while restoring tab. {0}", JsonSerializer.Serialize(tab, _jsonOptions));
|
||||
}
|
||||
}
|
||||
|
||||
if (_appState.Tabs.FirstOrDefault(t => t.TabNumber == tabStates.ActiveTabNumber) is TabContainer tabContainer)
|
||||
@@ -133,7 +156,10 @@ namespace FileTime.Avalonia.Services
|
||||
|
||||
return true;
|
||||
}
|
||||
catch { }
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.LogError(e, "Unkown exception while restoring tabs.");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ using FileTime.Avalonia.Services;
|
||||
using FileTime.Avalonia.ViewModels;
|
||||
using FileTime.Core.Command;
|
||||
using FileTime.Core.Interactions;
|
||||
using FileTime.Core.Persistence;
|
||||
using FileTime.Providers.Smb;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Serilog;
|
||||
@@ -31,6 +33,8 @@ namespace FileTime.Avalonia
|
||||
.AddSingleton<KeyboardConfigurationService>()
|
||||
.AddSingleton<KeyInputHandlerService>()
|
||||
.AddSingleton<DialogService>()
|
||||
.AddSingleton(new PersistenceSettings(Program.AppDataRoot))
|
||||
.AddSmbServices()
|
||||
.AddSingleton<IIconProvider, MaterialIconProvider>();
|
||||
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
|
||||
@@ -67,12 +67,16 @@ namespace FileTime.Avalonia.ViewModels
|
||||
|
||||
public List<ItemNamePart> DisplayName => ItemNameConverterService.GetDisplayName(this);
|
||||
|
||||
[Obsolete($"This property is for databinding only, use {nameof(GetContainers)} method instead.")]
|
||||
/*[Obsolete($"This property is for databinding only, use {nameof(GetContainers)} method instead.")]
|
||||
public ObservableCollection<ContainerViewModel> Containers
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!_isInitialized) Task.Run(Refresh).Wait();
|
||||
try
|
||||
{
|
||||
if (!_isInitialized) Task.Run(Refresh).Wait();
|
||||
}
|
||||
catch(Exception e) { }
|
||||
return _containers;
|
||||
}
|
||||
set
|
||||
@@ -90,7 +94,11 @@ namespace FileTime.Avalonia.ViewModels
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!_isInitialized) Task.Run(Refresh).Wait();
|
||||
try
|
||||
{
|
||||
if (!_isInitialized) Task.Run(Refresh).Wait();
|
||||
}
|
||||
catch(Exception e) { }
|
||||
return _elements;
|
||||
}
|
||||
set
|
||||
@@ -107,7 +115,11 @@ namespace FileTime.Avalonia.ViewModels
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!_isInitialized) Task.Run(Refresh).Wait();
|
||||
try
|
||||
{
|
||||
if (!_isInitialized) Task.Run(Refresh).Wait();
|
||||
}
|
||||
catch(Exception e) { }
|
||||
return _items;
|
||||
}
|
||||
set
|
||||
@@ -118,6 +130,55 @@ namespace FileTime.Avalonia.ViewModels
|
||||
OnPropertyChanged(nameof(Items));
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
public Task Containers => GetContainers();
|
||||
public Task Elements => GetElements();
|
||||
public Task Items => GetItems();
|
||||
|
||||
public async Task<ObservableCollection<ContainerViewModel>> GetContainers(CancellationToken token = default)
|
||||
{
|
||||
if (!_isInitialized) await Task.Run(async () => await Refresh(false, token: token), token);
|
||||
return _containers;
|
||||
}
|
||||
|
||||
public async Task<ObservableCollection<ElementViewModel>> GetElements(CancellationToken token = default)
|
||||
{
|
||||
if (!_isInitialized) await Task.Run(async () => await Refresh(false, token: token), token);
|
||||
return _elements;
|
||||
}
|
||||
|
||||
public async Task<ObservableCollection<IItemViewModel>> GetItems(CancellationToken token = default)
|
||||
{
|
||||
if (!_isInitialized) await Task.Run(async () => await Refresh(false, token: token), token);
|
||||
return _items;
|
||||
}
|
||||
|
||||
private void SetContainers(ObservableCollection<ContainerViewModel> value)
|
||||
{
|
||||
if (value != _containers)
|
||||
{
|
||||
_containers = value;
|
||||
OnPropertyChanged(nameof(Containers));
|
||||
}
|
||||
}
|
||||
|
||||
private void SetElements(ObservableCollection<ElementViewModel> value)
|
||||
{
|
||||
if (value != _elements)
|
||||
{
|
||||
_elements = value;
|
||||
OnPropertyChanged(nameof(Elements));
|
||||
}
|
||||
}
|
||||
|
||||
private void SetItems(ObservableCollection<IItemViewModel> value)
|
||||
{
|
||||
if (value != _items)
|
||||
{
|
||||
_items = value;
|
||||
OnPropertyChanged(nameof(Items));
|
||||
}
|
||||
}
|
||||
|
||||
public ContainerViewModel(INewItemProcessor newItemProcessor, ContainerViewModel? parent, IContainer container, ItemNameConverterService itemNameConverterService) : this(itemNameConverterService)
|
||||
@@ -211,14 +272,14 @@ namespace FileTime.Avalonia.ViewModels
|
||||
}
|
||||
else
|
||||
{
|
||||
Containers = new ObservableCollection<ContainerViewModel>(newContainers);
|
||||
Elements = new ObservableCollection<ElementViewModel>(newElements);
|
||||
Items = new ObservableCollection<IItemViewModel>(newContainers.Cast<IItemViewModel>().Concat(newElements));
|
||||
SetContainers(new ObservableCollection<ContainerViewModel>(newContainers));
|
||||
SetElements(new ObservableCollection<ElementViewModel>(newElements));
|
||||
SetItems(new ObservableCollection<IItemViewModel>(newContainers.Cast<IItemViewModel>().Concat(newElements)));
|
||||
}
|
||||
|
||||
for (var i = 0; i < Items.Count; i++)
|
||||
for (var i = 0; i < _items.Count; i++)
|
||||
{
|
||||
Items[i].IsAlternative = i % 2 == 1;
|
||||
_items[i].IsAlternative = i % 2 == 1;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -293,7 +354,7 @@ namespace FileTime.Avalonia.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
if(unloadEvents)
|
||||
if (unloadEvents)
|
||||
{
|
||||
Container.Refreshed.Remove(Container_Refreshed);
|
||||
}
|
||||
@@ -303,24 +364,6 @@ namespace FileTime.Avalonia.ViewModels
|
||||
_items.Clear();
|
||||
}
|
||||
|
||||
public async Task<ObservableCollection<ContainerViewModel>> GetContainers(CancellationToken token = default)
|
||||
{
|
||||
if (!_isInitialized) await Task.Run(async () => await Refresh(false, token: token), token);
|
||||
return _containers;
|
||||
}
|
||||
|
||||
public async Task<ObservableCollection<ElementViewModel>> GetElements(CancellationToken token = default)
|
||||
{
|
||||
if (!_isInitialized) await Task.Run(async () => await Refresh(false, token: token), token);
|
||||
return _elements;
|
||||
}
|
||||
|
||||
public async Task<ObservableCollection<IItemViewModel>> GetItems(CancellationToken token = default)
|
||||
{
|
||||
if (!_isInitialized) await Task.Run(async () => await Refresh(false, token: token), token);
|
||||
return _items;
|
||||
}
|
||||
|
||||
private void Dispose()
|
||||
{
|
||||
if (!_disposed)
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
<Rectangle Fill="#01000000"/>
|
||||
|
||||
<StackPanel Margin="20,10" Orientation="Horizontal">
|
||||
<!--TextBlock Text="{Binding AppState.SelectedTab.TabNumber,StringFormat=({0})}" /-->
|
||||
<local:PathPresenter DataContext="{Binding AppState.SelectedTab.CurrentLocation.Container.FullName}"/>
|
||||
<TextBlock
|
||||
Text="{Binding AppState.SelectedTab.SelectedItem.Item.Name}" Foreground="{StaticResource AccentForegroundBrush}" />
|
||||
@@ -222,9 +221,10 @@
|
||||
|
||||
<Grid>
|
||||
<ListBox
|
||||
x:CompileBindings="False"
|
||||
Classes="ContentListView"
|
||||
IsEnabled="False"
|
||||
Items="{Binding AppState.SelectedTab.Parent.Items}">
|
||||
Items="{Binding AppState.SelectedTab.Parent.Items^}">
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<local:ItemView ShowAttributes="False"/>
|
||||
@@ -244,8 +244,9 @@
|
||||
<Grid Grid.Column="2">
|
||||
<ListBox
|
||||
x:Name="CurrentItems"
|
||||
x:CompileBindings="False"
|
||||
IsTabStop="True"
|
||||
Items="{Binding AppState.SelectedTab.CurrentLocation.Items}"
|
||||
Items="{Binding AppState.SelectedTab.CurrentLocation.Items^}"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Hidden"
|
||||
SelectedItem="{Binding AppState.SelectedTab.SelectedItem, Mode=TwoWay}"
|
||||
@@ -258,12 +259,13 @@
|
||||
</ListBox>
|
||||
|
||||
<TextBlock
|
||||
x:CompileBindings="False"
|
||||
x:Name="CurrentEmpty"
|
||||
Margin="10"
|
||||
HorizontalAlignment="Center"
|
||||
FontWeight="Bold"
|
||||
Foreground="{DynamicResource ErrorBrush}"
|
||||
IsVisible="{Binding AppState.SelectedTab.CurrentLocation.Items.Count, Converter={StaticResource EqualityConverter}, ConverterParameter=0}">
|
||||
IsVisible="{Binding AppState.SelectedTab.CurrentLocation.Items^.Count, Converter={StaticResource EqualityConverter}, ConverterParameter=0}">
|
||||
Empty
|
||||
</TextBlock>
|
||||
</Grid>
|
||||
@@ -282,8 +284,9 @@
|
||||
Classes="ContentListView"
|
||||
IsEnabled="False"
|
||||
x:Name="ChildItems"
|
||||
Items="{Binding AppState.SelectedTab.ChildContainer.Items}"
|
||||
IsVisible="{Binding AppState.SelectedTab.ChildContainer.Items.Count, Converter={StaticResource NotEqualsConverter}, ConverterParameter=0}">
|
||||
x:CompileBindings="False"
|
||||
Items="{Binding AppState.SelectedTab.ChildContainer.Items^}"
|
||||
IsVisible="{Binding AppState.SelectedTab.ChildContainer.Items^.Count, Converter={StaticResource NotEqualsConverter}, ConverterParameter=0}">
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<local:ItemView/>
|
||||
@@ -291,7 +294,9 @@
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
|
||||
<Grid IsVisible="{Binding AppState.SelectedTab.ChildContainer.Items.Count, Converter={StaticResource EqualityConverter}, ConverterParameter=0}">
|
||||
<Grid
|
||||
x:CompileBindings="False"
|
||||
IsVisible="{Binding AppState.SelectedTab.ChildContainer.Items^.Count, Converter={StaticResource EqualityConverter}, ConverterParameter=0}">
|
||||
|
||||
<TextBlock
|
||||
x:Name="ChildEmpty"
|
||||
|
||||
Reference in New Issue
Block a user