Icon, Tab state persistence
This commit is contained in:
@@ -10,7 +10,7 @@ namespace FileTime.Core.Models
|
||||
Task<IReadOnlyList<IElement>?> GetElements(CancellationToken token = default);
|
||||
|
||||
Task Refresh();
|
||||
Task<IItem?> GetByPath(string path);
|
||||
Task<IItem?> GetByPath(string path, bool acceptDeepestMatch = false);
|
||||
Task<IContainer> CreateContainer(string name);
|
||||
Task<IElement> CreateElement(string name);
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ namespace FileTime.Core.Models
|
||||
?.ToList().AsReadOnly();
|
||||
}
|
||||
|
||||
public async Task<IItem?> GetByPath(string path) => await BaseContainer.GetByPath(path);
|
||||
public async Task<IItem?> GetByPath(string path, bool acceptDeepestMatch = false) => await BaseContainer.GetByPath(path, acceptDeepestMatch);
|
||||
|
||||
public IContainer? GetParent() => BaseContainer.GetParent();
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace FileTime.Core.Providers
|
||||
|
||||
public Task Delete() => throw new NotImplementedException();
|
||||
|
||||
public Task<IItem?> GetByPath(string path) => throw new NotImplementedException();
|
||||
public Task<IItem?> GetByPath(string path, bool acceptDeepestMatch = false) => throw new NotImplementedException();
|
||||
|
||||
public IContainer? GetParent() => null;
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace FileTime.Core.Timeline
|
||||
|
||||
public Task Delete() => Task.CompletedTask;
|
||||
|
||||
public async Task<IItem?> GetByPath(string path)
|
||||
public async Task<IItem?> GetByPath(string path, bool acceptDeepestMatch = false)
|
||||
{
|
||||
var paths = path.Split(Constants.SeparatorChar);
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace FileTime.Core.Timeline
|
||||
|
||||
if (item is IContainer container)
|
||||
{
|
||||
return await container.GetByPath(string.Join(Constants.SeparatorChar, paths.Skip(1)));
|
||||
return await container.GetByPath(string.Join(Constants.SeparatorChar, paths.Skip(1)), acceptDeepestMatch);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace FileTime.Core.Timeline
|
||||
|
||||
public Task Delete() => throw new NotSupportedException();
|
||||
|
||||
public Task<IItem?> GetByPath(string path)
|
||||
public Task<IItem?> GetByPath(string path, bool acceptDeepestMatch = false)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
BIN
src/GuiApp/Assets/filetime.ico
Normal file
BIN
src/GuiApp/Assets/filetime.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
12
src/GuiApp/Assets/filetime.svg
Normal file
12
src/GuiApp/Assets/filetime.svg
Normal file
@@ -0,0 +1,12 @@
|
||||
<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414" viewBox="0 0 24 24" xml:space="preserve"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M10 4H4c-1.11 0-2 .89-2 2v12c0 1.097.903 2 2 2h16c1.097 0 2-.903 2-2V8a2 2 0 0 0-2-2h-8l-2-2z" fill="#FFD767" fill-rule="nonzero"/>
|
||||
<line x1="4" y1="9" x2="7" y2="9" stroke="#444444" stroke-width="2"/>
|
||||
<line x1="8" y1="9" x2="14" y2="9" stroke="#444444" stroke-width="2"/>
|
||||
<line x1="15" y1="9" x2="20" y2="9" stroke="#444444" stroke-width="2"/>
|
||||
|
||||
<line x1="8" y1="13" x2="14" y2="13" stroke="#444444" stroke-width="2"/>
|
||||
<line x1="15" y1="13" x2="20" y2="13" stroke="#444444" stroke-width="2"/>
|
||||
|
||||
<line x1="8" y1="17" x2="14" y2="17" stroke="#444444" stroke-width="2"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 794 B |
BIN
src/GuiApp/Assets/filetime.xcf
Normal file
BIN
src/GuiApp/Assets/filetime.xcf
Normal file
Binary file not shown.
BIN
src/GuiApp/Assets/filetime2.xcf
Normal file
BIN
src/GuiApp/Assets/filetime2.xcf
Normal file
Binary file not shown.
@@ -16,6 +16,7 @@ namespace FileTime.Avalonia.Application
|
||||
private ObservableCollection<TabContainer> _tabs = new();
|
||||
|
||||
[Property]
|
||||
[PropertyCallMethod(nameof(SelectedTabChanged))]
|
||||
private TabContainer _selectedTab;
|
||||
|
||||
[Property]
|
||||
@@ -62,6 +63,14 @@ namespace FileTime.Avalonia.Application
|
||||
}
|
||||
}
|
||||
|
||||
private void SelectedTabChanged()
|
||||
{
|
||||
foreach(var tab in Tabs)
|
||||
{
|
||||
tab.IsSelected = tab == SelectedTab;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task TabItemMarked(TabState tabState, AbsolutePath item)
|
||||
{
|
||||
var tabContainer = Tabs.FirstOrDefault(t => t.TabState == tabState);
|
||||
|
||||
BIN
src/GuiApp/FileTime.Avalonia/Assets/filetime.ico
Normal file
BIN
src/GuiApp/FileTime.Avalonia/Assets/filetime.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 33 KiB |
BIN
src/GuiApp/FileTime.Avalonia/Assets/filetime2.ico
Normal file
BIN
src/GuiApp/FileTime.Avalonia/Assets/filetime2.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 66 KiB |
BIN
src/GuiApp/FileTime.Avalonia/Assets/filetime3.ico
Normal file
BIN
src/GuiApp/FileTime.Avalonia/Assets/filetime3.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 100 KiB |
@@ -3,12 +3,16 @@
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ApplicationIcon>Assets\filetime.ico</ApplicationIcon>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Models\" />
|
||||
<AvaloniaResource Include="Assets\**" />
|
||||
<None Remove=".gitignore" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Assets\filetime.ico" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Avalonia" Version="0.10.12" />
|
||||
<PackageReference Include="Avalonia.Desktop" Version="0.10.12" />
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace FileTime.Avalonia.Models.Persistence
|
||||
{
|
||||
public class PersistenceRoot
|
||||
{
|
||||
public TabStates? TabStates { get; set; }
|
||||
}
|
||||
}
|
||||
18
src/GuiApp/FileTime.Avalonia/Models/Persistence/TabState.cs
Normal file
18
src/GuiApp/FileTime.Avalonia/Models/Persistence/TabState.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using FileTime.Avalonia.Application;
|
||||
|
||||
namespace FileTime.Avalonia.Models.Persistence
|
||||
{
|
||||
public class TabState
|
||||
{
|
||||
public string? Path { get; set; }
|
||||
public int Number { get; set; }
|
||||
|
||||
public TabState() { }
|
||||
|
||||
public TabState(TabContainer tab)
|
||||
{
|
||||
Path = tab.CurrentLocation.Item.FullName;
|
||||
Number = tab.TabNumber;
|
||||
}
|
||||
}
|
||||
}
|
||||
10
src/GuiApp/FileTime.Avalonia/Models/Persistence/TabStates.cs
Normal file
10
src/GuiApp/FileTime.Avalonia/Models/Persistence/TabStates.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FileTime.Avalonia.Models.Persistence
|
||||
{
|
||||
public class TabStates
|
||||
{
|
||||
public List<TabState>? Tabs { get; set; }
|
||||
public int? ActiveTabNumber { get; set; }
|
||||
}
|
||||
}
|
||||
131
src/GuiApp/FileTime.Avalonia/Services/StatePersistenceService.cs
Normal file
131
src/GuiApp/FileTime.Avalonia/Services/StatePersistenceService.cs
Normal file
@@ -0,0 +1,131 @@
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using FileTime.Avalonia.Application;
|
||||
using FileTime.Avalonia.Models.Persistence;
|
||||
using System;
|
||||
using FileTime.Core.Components;
|
||||
using FileTime.Core.Providers;
|
||||
using FileTime.Providers.Local;
|
||||
using FileTime.Core.Models;
|
||||
|
||||
namespace FileTime.Avalonia.Services
|
||||
{
|
||||
public class StatePersistenceService
|
||||
{
|
||||
private readonly AppState _appState;
|
||||
private readonly ItemNameConverterService _itemNameConverterService;
|
||||
private readonly JsonSerializerOptions _jsonOptions;
|
||||
private readonly string _settingsPath;
|
||||
private readonly IEnumerable<IContentProvider> _contentProviders;
|
||||
private readonly LocalContentProvider _localContentProvider;
|
||||
|
||||
public StatePersistenceService(
|
||||
AppState appState,
|
||||
ItemNameConverterService itemNameConverterService,
|
||||
IEnumerable<IContentProvider> contentProviders,
|
||||
LocalContentProvider localContentProvider)
|
||||
{
|
||||
_appState = appState;
|
||||
_itemNameConverterService = itemNameConverterService;
|
||||
_contentProviders = contentProviders;
|
||||
_localContentProvider = localContentProvider;
|
||||
_settingsPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "FileTime", "savedState.json");
|
||||
|
||||
_jsonOptions = new JsonSerializerOptions()
|
||||
{
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
}
|
||||
|
||||
public async Task LoadStatesAsync()
|
||||
{
|
||||
if (!File.Exists(_settingsPath)) return;
|
||||
|
||||
using var stateReader = File.OpenRead(_settingsPath);
|
||||
var state = await JsonSerializer.DeserializeAsync<PersistenceRoot>(stateReader);
|
||||
if (state != null)
|
||||
{
|
||||
await RestoreTabs(state.TabStates);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task SaveStatesAsync()
|
||||
{
|
||||
var state = new PersistenceRoot
|
||||
{
|
||||
TabStates = SerializeTabStates()
|
||||
};
|
||||
var settingsDirectory = new DirectoryInfo(string.Join(Path.DirectorySeparatorChar, _settingsPath.Split(Path.DirectorySeparatorChar)[0..^1]));
|
||||
if (!settingsDirectory.Exists) settingsDirectory.Create();
|
||||
using var stateWriter = File.OpenWrite(_settingsPath);
|
||||
await JsonSerializer.SerializeAsync(stateWriter, state, _jsonOptions);
|
||||
}
|
||||
|
||||
private TabStates SerializeTabStates()
|
||||
{
|
||||
var tabStates = new List<TabState>();
|
||||
foreach (var tab in _appState.Tabs)
|
||||
{
|
||||
tabStates.Add(new TabState(tab));
|
||||
}
|
||||
|
||||
return new TabStates()
|
||||
{
|
||||
Tabs = tabStates,
|
||||
ActiveTabNumber = _appState.SelectedTab.TabNumber
|
||||
};
|
||||
}
|
||||
|
||||
private async Task<bool> RestoreTabs(TabStates? tabStates)
|
||||
{
|
||||
if (tabStates == null
|
||||
|| tabStates.Tabs == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (var tab in tabStates.Tabs)
|
||||
{
|
||||
if (tab.Path == null) continue;
|
||||
|
||||
IItem? pathItem = null;
|
||||
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);
|
||||
}
|
||||
|
||||
if (_appState.Tabs.FirstOrDefault(t => t.TabNumber == tabStates.ActiveTabNumber) is TabContainer tabContainer)
|
||||
{
|
||||
_appState.SelectedTab = tabContainer;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@ namespace FileTime.Avalonia
|
||||
serviceCollection = serviceCollection
|
||||
.AddLogging()
|
||||
.AddSingleton<ItemNameConverterService>()
|
||||
.AddSingleton<StatePersistenceService>()
|
||||
.AddSingleton<IIconProvider, MaterialIconProvider>();
|
||||
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
|
||||
@@ -32,6 +32,7 @@ namespace FileTime.Avalonia.ViewModels
|
||||
[ViewModel]
|
||||
[Inject(typeof(LocalContentProvider))]
|
||||
[Inject(typeof(AppState), PropertyAccessModifier = AccessModifier.Public)]
|
||||
[Inject(typeof(StatePersistenceService), PropertyName = "StatePersistence", PropertyAccessModifier = AccessModifier.Public)]
|
||||
[Inject(typeof(ItemNameConverterService))]
|
||||
public partial class MainPageViewModel
|
||||
{
|
||||
@@ -90,6 +91,7 @@ namespace FileTime.Avalonia.ViewModels
|
||||
var inputInterface = (BasicInputHandler)App.ServiceProvider.GetService<IInputInterface>()!;
|
||||
inputInterface.InputHandler = ReadInputs;
|
||||
App.ServiceProvider.GetService<TopContainer>();
|
||||
await StatePersistence.LoadStatesAsync();
|
||||
|
||||
_timeRunner.CommandsChanged += UpdateParalellCommands;
|
||||
InitCommandBindings();
|
||||
@@ -100,9 +102,13 @@ namespace FileTime.Avalonia.ViewModels
|
||||
_keysToSkip.Add(new KeyWithModifiers[] { new KeyWithModifiers(Key.PageDown) });
|
||||
_keysToSkip.Add(new KeyWithModifiers[] { new KeyWithModifiers(Key.PageUp) });
|
||||
_keysToSkip.Add(new KeyWithModifiers[] { new KeyWithModifiers(Key.F4, alt: true) });
|
||||
_keysToSkip.Add(new KeyWithModifiers[] { new KeyWithModifiers(Key.LWin) });
|
||||
_keysToSkip.Add(new KeyWithModifiers[] { new KeyWithModifiers(Key.RWin) });
|
||||
|
||||
AllShortcut = _commandBindings.Concat(_universalCommandBindings).ToList();
|
||||
|
||||
if (AppState.Tabs.Count == 0)
|
||||
{
|
||||
var tab = new Tab();
|
||||
await tab.Init(LocalContentProvider);
|
||||
|
||||
@@ -110,6 +116,7 @@ namespace FileTime.Avalonia.ViewModels
|
||||
await tabContainer.Init(1);
|
||||
tabContainer.IsSelected = true;
|
||||
AppState.Tabs.Add(tabContainer);
|
||||
}
|
||||
|
||||
var driveInfos = new List<RootDriveInfo>();
|
||||
foreach (var drive in DriveInfo.GetDrives().Where(d => d.DriveType == DriveType.Fixed))
|
||||
@@ -355,11 +362,6 @@ namespace FileTime.Avalonia.ViewModels
|
||||
}
|
||||
|
||||
AppState.SelectedTab = tabContainer;
|
||||
|
||||
foreach (var tab2 in AppState.Tabs)
|
||||
{
|
||||
tab2.IsSelected = tab2.TabNumber == tabContainer!.TabNumber;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task CloseTab()
|
||||
@@ -656,6 +658,42 @@ namespace FileTime.Avalonia.ViewModels
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private Task OpenInDefaultFileExplorer()
|
||||
{
|
||||
if (AppState.SelectedTab.CurrentLocation.Container is LocalFolder localFolder)
|
||||
{
|
||||
var path = localFolder.Directory.FullName;
|
||||
if (path != null)
|
||||
{
|
||||
Process.Start("explorer.exe", "\"" + path + "\"");
|
||||
}
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private async Task CopyPath()
|
||||
{
|
||||
string? textToCopy = null;
|
||||
if (AppState.SelectedTab.CurrentLocation.Container is LocalFolder localFolder)
|
||||
{
|
||||
textToCopy = localFolder.Directory.FullName;
|
||||
}
|
||||
if (AppState.SelectedTab.CurrentLocation.Container is LocalFile localFile)
|
||||
{
|
||||
textToCopy = localFile.File.FullName;
|
||||
}
|
||||
else if (AppState.SelectedTab.CurrentLocation.Container.FullName is string fullName)
|
||||
{
|
||||
textToCopy = fullName;
|
||||
}
|
||||
|
||||
if(textToCopy != null && global::Avalonia.Application.Current?.Clipboard is not null)
|
||||
{
|
||||
await global::Avalonia.Application.Current.Clipboard.SetTextAsync(textToCopy);
|
||||
}
|
||||
}
|
||||
|
||||
private Task ShowAllShortcut2()
|
||||
{
|
||||
ShowAllShortcut = true;
|
||||
@@ -1081,6 +1119,18 @@ namespace FileTime.Avalonia.ViewModels
|
||||
FileTime.App.Core.Command.Commands.Dummy,
|
||||
new KeyWithModifiers[] { new KeyWithModifiers(Key.F1) },
|
||||
ShowAllShortcut2),
|
||||
//TODO REMOVE
|
||||
new CommandBinding(
|
||||
"open in default file browser",
|
||||
FileTime.App.Core.Command.Commands.Dummy,
|
||||
new KeyWithModifiers[] { new KeyWithModifiers(Key.O), new KeyWithModifiers(Key.E) },
|
||||
OpenInDefaultFileExplorer),
|
||||
//TODO REMOVE
|
||||
new CommandBinding(
|
||||
"copy path",
|
||||
FileTime.App.Core.Command.Commands.Dummy,
|
||||
new KeyWithModifiers[] { new KeyWithModifiers(Key.C), new KeyWithModifiers(Key.P) },
|
||||
CopyPath),
|
||||
};
|
||||
var universalCommandBindings = new List<CommandBinding>()
|
||||
{
|
||||
|
||||
@@ -6,12 +6,13 @@
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:vm="using:FileTime.Avalonia.ViewModels"
|
||||
xmlns:local="using:FileTime.Avalonia.Views"
|
||||
Title="FileTime.Avalonia"
|
||||
Title="FileTime"
|
||||
d:DesignHeight="450"
|
||||
d:DesignWidth="800"
|
||||
Icon="/Assets/avalonia-logo.ico"
|
||||
Icon="/Assets/filetime.ico"
|
||||
InputElement.KeyDown="OnKeyDown"
|
||||
InputElement.KeyUp="OnKeyUp"
|
||||
Closed="OnWindowClosed"
|
||||
|
||||
mc:Ignorable="d">
|
||||
<Grid
|
||||
@@ -188,7 +189,10 @@
|
||||
<TextBlock
|
||||
VerticalAlignment="Center" Text="{Binding TabNumber,StringFormat=({0})}" />
|
||||
|
||||
<local:PathPresenter Margin="5,0,0,0" DataContext="{Binding CurrentLocation.Container.FullName}"/>
|
||||
<TextBlock
|
||||
VerticalAlignment="Center" Margin="5,0,0,0" Text="{Binding CurrentLocation.Container.Name}" />
|
||||
|
||||
<!--local:PathPresenter Margin="5,0,0,0" DataContext="{Binding CurrentLocation.Container.FullName}"/-->
|
||||
</StackPanel>
|
||||
|
||||
<Rectangle Fill="{DynamicResource ForegroundBrush}" Grid.Row="1" IsVisible="{Binding IsSelected}"/>
|
||||
|
||||
@@ -6,6 +6,7 @@ using Avalonia.Markup.Xaml;
|
||||
using FileTime.Avalonia.Misc;
|
||||
using FileTime.Avalonia.Models;
|
||||
using FileTime.Avalonia.ViewModels;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace FileTime.Avalonia.Views
|
||||
@@ -107,5 +108,10 @@ namespace FileTime.Avalonia.Views
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnWindowClosed(object sender, EventArgs e)
|
||||
{
|
||||
ViewModel?.StatePersistence.SaveStatesAsync().Wait();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -47,7 +47,7 @@ namespace FileTime.Providers.Local
|
||||
_items = _rootContainers.Cast<IItem>().ToList().AsReadOnly();
|
||||
}
|
||||
|
||||
public async Task<IItem?> GetByPath(string path)
|
||||
public async Task<IItem?> GetByPath(string path, bool acceptDeepestMatch = false)
|
||||
{
|
||||
path = path.Replace(Path.DirectorySeparatorChar, Constants.SeparatorChar).TrimEnd(Constants.SeparatorChar);
|
||||
var pathParts = (IsCaseInsensitive ? path.ToLower() : path).TrimStart(Constants.SeparatorChar).Split(Constants.SeparatorChar);
|
||||
@@ -64,7 +64,7 @@ namespace FileTime.Providers.Local
|
||||
}
|
||||
|
||||
var remainingPath = string.Join(Constants.SeparatorChar, pathParts.Skip(1));
|
||||
return remainingPath.Length == 0 ? rootContainer : await rootContainer.GetByPath(remainingPath);
|
||||
return remainingPath.Length == 0 ? rootContainer : await rootContainer.GetByPath(remainingPath, acceptDeepestMatch);
|
||||
}
|
||||
|
||||
public async Task Refresh() => await Refreshed.InvokeAsync(this, AsyncEventArgs.Empty);
|
||||
|
||||
@@ -88,7 +88,7 @@ namespace FileTime.Providers.Local
|
||||
return _elements;
|
||||
}
|
||||
|
||||
public async Task<IItem?> GetByPath(string path)
|
||||
public async Task<IItem?> GetByPath(string path, bool acceptDeepestMatch = false)
|
||||
{
|
||||
var paths = path.Split(Constants.SeparatorChar);
|
||||
|
||||
@@ -101,7 +101,7 @@ namespace FileTime.Providers.Local
|
||||
|
||||
if (item is IContainer container)
|
||||
{
|
||||
return await container.GetByPath(string.Join(Constants.SeparatorChar, paths.Skip(1)));
|
||||
return await container.GetByPath(string.Join(Constants.SeparatorChar, paths.Skip(1)), acceptDeepestMatch);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace FileTime.Providers.Smb
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public async Task<IItem?> GetByPath(string path)
|
||||
public async Task<IItem?> GetByPath(string path, bool acceptDeepestMatch = false)
|
||||
{
|
||||
if (path == null) return this;
|
||||
|
||||
@@ -78,7 +78,7 @@ namespace FileTime.Providers.Smb
|
||||
}
|
||||
|
||||
var remainingPath = string.Join(Constants.SeparatorChar, pathParts.Skip(1));
|
||||
return remainingPath.Length == 0 ? rootContainer : await rootContainer.GetByPath(remainingPath);
|
||||
return remainingPath.Length == 0 ? rootContainer : await rootContainer.GetByPath(remainingPath, acceptDeepestMatch);
|
||||
}
|
||||
|
||||
public IContainer? GetParent() => _parent;
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace FileTime.Providers.Smb
|
||||
|
||||
public Task<IContainer> Clone() => Task.FromResult((IContainer)this);
|
||||
|
||||
public async Task<IItem?> GetByPath(string path)
|
||||
public async Task<IItem?> GetByPath(string path, bool acceptDeepestMatch = false)
|
||||
{
|
||||
var paths = path.Split(Constants.SeparatorChar);
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace FileTime.Providers.Smb
|
||||
|
||||
if (item is IContainer container)
|
||||
{
|
||||
return await container.GetByPath(string.Join(Constants.SeparatorChar, paths.Skip(1)));
|
||||
return await container.GetByPath(string.Join(Constants.SeparatorChar, paths.Skip(1)), acceptDeepestMatch);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -77,7 +77,7 @@ namespace FileTime.Providers.Smb
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task<IItem?> GetByPath(string path)
|
||||
public Task<IItem?> GetByPath(string path, bool acceptDeepestMatch = false)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ namespace FileTime.Providers.Smb
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public async Task<IItem?> GetByPath(string path)
|
||||
public async Task<IItem?> GetByPath(string path, bool acceptDeepestMatch = false)
|
||||
{
|
||||
var paths = path.Split(Constants.SeparatorChar);
|
||||
|
||||
@@ -83,7 +83,7 @@ namespace FileTime.Providers.Smb
|
||||
|
||||
if (item is IContainer container)
|
||||
{
|
||||
return await container.GetByPath(string.Join(Constants.SeparatorChar, paths.Skip(1)));
|
||||
return await container.GetByPath(string.Join(Constants.SeparatorChar, paths.Skip(1)), acceptDeepestMatch);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user