diff --git a/src/Core/FileTime.Core/Models/IContainer.cs b/src/Core/FileTime.Core/Models/IContainer.cs index 5f73be8..fcd1797 100644 --- a/src/Core/FileTime.Core/Models/IContainer.cs +++ b/src/Core/FileTime.Core/Models/IContainer.cs @@ -10,7 +10,7 @@ namespace FileTime.Core.Models Task?> GetElements(CancellationToken token = default); Task Refresh(); - Task GetByPath(string path); + Task GetByPath(string path, bool acceptDeepestMatch = false); Task CreateContainer(string name); Task CreateElement(string name); diff --git a/src/Core/FileTime.Core/Models/VirtualContainer.cs b/src/Core/FileTime.Core/Models/VirtualContainer.cs index dec2531..6db050d 100644 --- a/src/Core/FileTime.Core/Models/VirtualContainer.cs +++ b/src/Core/FileTime.Core/Models/VirtualContainer.cs @@ -76,7 +76,7 @@ namespace FileTime.Core.Models ?.ToList().AsReadOnly(); } - public async Task GetByPath(string path) => await BaseContainer.GetByPath(path); + public async Task GetByPath(string path, bool acceptDeepestMatch = false) => await BaseContainer.GetByPath(path, acceptDeepestMatch); public IContainer? GetParent() => BaseContainer.GetParent(); diff --git a/src/Core/FileTime.Core/Providers/TopContainer.cs b/src/Core/FileTime.Core/Providers/TopContainer.cs index aa18c23..52387f4 100644 --- a/src/Core/FileTime.Core/Providers/TopContainer.cs +++ b/src/Core/FileTime.Core/Providers/TopContainer.cs @@ -49,7 +49,7 @@ namespace FileTime.Core.Providers public Task Delete() => throw new NotImplementedException(); - public Task GetByPath(string path) => throw new NotImplementedException(); + public Task GetByPath(string path, bool acceptDeepestMatch = false) => throw new NotImplementedException(); public IContainer? GetParent() => null; diff --git a/src/Core/FileTime.Core/Timeline/TimeContainer.cs b/src/Core/FileTime.Core/Timeline/TimeContainer.cs index 236a961..5b85160 100644 --- a/src/Core/FileTime.Core/Timeline/TimeContainer.cs +++ b/src/Core/FileTime.Core/Timeline/TimeContainer.cs @@ -46,7 +46,7 @@ namespace FileTime.Core.Timeline public Task Delete() => Task.CompletedTask; - public async Task GetByPath(string path) + public async Task 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; diff --git a/src/Core/FileTime.Core/Timeline/TimeProvider.cs b/src/Core/FileTime.Core/Timeline/TimeProvider.cs index 1687a3a..75d05fc 100644 --- a/src/Core/FileTime.Core/Timeline/TimeProvider.cs +++ b/src/Core/FileTime.Core/Timeline/TimeProvider.cs @@ -50,7 +50,7 @@ namespace FileTime.Core.Timeline public Task Delete() => throw new NotSupportedException(); - public Task GetByPath(string path) + public Task GetByPath(string path, bool acceptDeepestMatch = false) { throw new NotImplementedException(); } diff --git a/src/GuiApp/Assets/filetime.ico b/src/GuiApp/Assets/filetime.ico new file mode 100644 index 0000000..0285c30 Binary files /dev/null and b/src/GuiApp/Assets/filetime.ico differ diff --git a/src/GuiApp/Assets/filetime.svg b/src/GuiApp/Assets/filetime.svg new file mode 100644 index 0000000..9b844df --- /dev/null +++ b/src/GuiApp/Assets/filetime.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/src/GuiApp/Assets/filetime.xcf b/src/GuiApp/Assets/filetime.xcf new file mode 100644 index 0000000..635c492 Binary files /dev/null and b/src/GuiApp/Assets/filetime.xcf differ diff --git a/src/GuiApp/Assets/filetime2.xcf b/src/GuiApp/Assets/filetime2.xcf new file mode 100644 index 0000000..d4acb62 Binary files /dev/null and b/src/GuiApp/Assets/filetime2.xcf differ diff --git a/src/GuiApp/FileTime.Avalonia/Application/AppState.cs b/src/GuiApp/FileTime.Avalonia/Application/AppState.cs index 9485dee..b670312 100644 --- a/src/GuiApp/FileTime.Avalonia/Application/AppState.cs +++ b/src/GuiApp/FileTime.Avalonia/Application/AppState.cs @@ -16,6 +16,7 @@ namespace FileTime.Avalonia.Application private ObservableCollection _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); diff --git a/src/GuiApp/FileTime.Avalonia/Assets/filetime.ico b/src/GuiApp/FileTime.Avalonia/Assets/filetime.ico new file mode 100644 index 0000000..217f28f Binary files /dev/null and b/src/GuiApp/FileTime.Avalonia/Assets/filetime.ico differ diff --git a/src/GuiApp/FileTime.Avalonia/Assets/filetime2.ico b/src/GuiApp/FileTime.Avalonia/Assets/filetime2.ico new file mode 100644 index 0000000..7a8deea Binary files /dev/null and b/src/GuiApp/FileTime.Avalonia/Assets/filetime2.ico differ diff --git a/src/GuiApp/FileTime.Avalonia/Assets/filetime3.ico b/src/GuiApp/FileTime.Avalonia/Assets/filetime3.ico new file mode 100644 index 0000000..287bda8 Binary files /dev/null and b/src/GuiApp/FileTime.Avalonia/Assets/filetime3.ico differ diff --git a/src/GuiApp/FileTime.Avalonia/FileTime.Avalonia.csproj b/src/GuiApp/FileTime.Avalonia/FileTime.Avalonia.csproj index 6fc54e2..da357e2 100644 --- a/src/GuiApp/FileTime.Avalonia/FileTime.Avalonia.csproj +++ b/src/GuiApp/FileTime.Avalonia/FileTime.Avalonia.csproj @@ -3,12 +3,16 @@ WinExe net6.0 enable + Assets\filetime.ico + + + diff --git a/src/GuiApp/FileTime.Avalonia/Models/Persistence/PersistenceRoot.cs b/src/GuiApp/FileTime.Avalonia/Models/Persistence/PersistenceRoot.cs new file mode 100644 index 0000000..b9c45c1 --- /dev/null +++ b/src/GuiApp/FileTime.Avalonia/Models/Persistence/PersistenceRoot.cs @@ -0,0 +1,7 @@ +namespace FileTime.Avalonia.Models.Persistence +{ + public class PersistenceRoot + { + public TabStates? TabStates { get; set; } + } +} \ No newline at end of file diff --git a/src/GuiApp/FileTime.Avalonia/Models/Persistence/TabState.cs b/src/GuiApp/FileTime.Avalonia/Models/Persistence/TabState.cs new file mode 100644 index 0000000..f132da7 --- /dev/null +++ b/src/GuiApp/FileTime.Avalonia/Models/Persistence/TabState.cs @@ -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; + } + } +} \ No newline at end of file diff --git a/src/GuiApp/FileTime.Avalonia/Models/Persistence/TabStates.cs b/src/GuiApp/FileTime.Avalonia/Models/Persistence/TabStates.cs new file mode 100644 index 0000000..124b881 --- /dev/null +++ b/src/GuiApp/FileTime.Avalonia/Models/Persistence/TabStates.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace FileTime.Avalonia.Models.Persistence +{ + public class TabStates + { + public List? Tabs { get; set; } + public int? ActiveTabNumber { get; set; } + } +} \ No newline at end of file diff --git a/src/GuiApp/FileTime.Avalonia/Services/StatePersistenceService.cs b/src/GuiApp/FileTime.Avalonia/Services/StatePersistenceService.cs new file mode 100644 index 0000000..be30289 --- /dev/null +++ b/src/GuiApp/FileTime.Avalonia/Services/StatePersistenceService.cs @@ -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 _contentProviders; + private readonly LocalContentProvider _localContentProvider; + + public StatePersistenceService( + AppState appState, + ItemNameConverterService itemNameConverterService, + IEnumerable 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(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(); + foreach (var tab in _appState.Tabs) + { + tabStates.Add(new TabState(tab)); + } + + return new TabStates() + { + Tabs = tabStates, + ActiveTabNumber = _appState.SelectedTab.TabNumber + }; + } + + private async Task 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; + } + } +} \ No newline at end of file diff --git a/src/GuiApp/FileTime.Avalonia/Startup.cs b/src/GuiApp/FileTime.Avalonia/Startup.cs index 6a75ab1..4c22887 100644 --- a/src/GuiApp/FileTime.Avalonia/Startup.cs +++ b/src/GuiApp/FileTime.Avalonia/Startup.cs @@ -23,6 +23,7 @@ namespace FileTime.Avalonia serviceCollection = serviceCollection .AddLogging() .AddSingleton() + .AddSingleton() .AddSingleton(); if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) diff --git a/src/GuiApp/FileTime.Avalonia/ViewModels/MainPageViewModel.cs b/src/GuiApp/FileTime.Avalonia/ViewModels/MainPageViewModel.cs index 87fb3d1..ab39212 100644 --- a/src/GuiApp/FileTime.Avalonia/ViewModels/MainPageViewModel.cs +++ b/src/GuiApp/FileTime.Avalonia/ViewModels/MainPageViewModel.cs @@ -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()!; inputInterface.InputHandler = ReadInputs; App.ServiceProvider.GetService(); + await StatePersistence.LoadStatesAsync(); _timeRunner.CommandsChanged += UpdateParalellCommands; InitCommandBindings(); @@ -100,16 +102,21 @@ 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(); - var tab = new Tab(); - await tab.Init(LocalContentProvider); + if (AppState.Tabs.Count == 0) + { + var tab = new Tab(); + await tab.Init(LocalContentProvider); - var tabContainer = new TabContainer(tab, LocalContentProvider, ItemNameConverterService); - await tabContainer.Init(1); - tabContainer.IsSelected = true; - AppState.Tabs.Add(tabContainer); + var tabContainer = new TabContainer(tab, LocalContentProvider, ItemNameConverterService); + await tabContainer.Init(1); + tabContainer.IsSelected = true; + AppState.Tabs.Add(tabContainer); + } var driveInfos = new List(); 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() { diff --git a/src/GuiApp/FileTime.Avalonia/Views/MainWindow.axaml b/src/GuiApp/FileTime.Avalonia/Views/MainWindow.axaml index 782c612..2cea96e 100644 --- a/src/GuiApp/FileTime.Avalonia/Views/MainWindow.axaml +++ b/src/GuiApp/FileTime.Avalonia/Views/MainWindow.axaml @@ -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"> - + + + diff --git a/src/GuiApp/FileTime.Avalonia/Views/MainWindow.axaml.cs b/src/GuiApp/FileTime.Avalonia/Views/MainWindow.axaml.cs index 188e216..59c91db 100644 --- a/src/GuiApp/FileTime.Avalonia/Views/MainWindow.axaml.cs +++ b/src/GuiApp/FileTime.Avalonia/Views/MainWindow.axaml.cs @@ -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(); + } } } \ No newline at end of file diff --git a/src/Providers/FileTime.Providers.Local/LocalContentProvider.cs b/src/Providers/FileTime.Providers.Local/LocalContentProvider.cs index cd52962..22d5838 100644 --- a/src/Providers/FileTime.Providers.Local/LocalContentProvider.cs +++ b/src/Providers/FileTime.Providers.Local/LocalContentProvider.cs @@ -47,7 +47,7 @@ namespace FileTime.Providers.Local _items = _rootContainers.Cast().ToList().AsReadOnly(); } - public async Task GetByPath(string path) + public async Task 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); diff --git a/src/Providers/FileTime.Providers.Local/LocalFolder.cs b/src/Providers/FileTime.Providers.Local/LocalFolder.cs index 5d62216..2e64404 100644 --- a/src/Providers/FileTime.Providers.Local/LocalFolder.cs +++ b/src/Providers/FileTime.Providers.Local/LocalFolder.cs @@ -88,7 +88,7 @@ namespace FileTime.Providers.Local return _elements; } - public async Task GetByPath(string path) + public async Task 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; diff --git a/src/Providers/FileTime.Providers.Smb/SmbContentProvider.cs b/src/Providers/FileTime.Providers.Smb/SmbContentProvider.cs index 4f43d81..830864c 100644 --- a/src/Providers/FileTime.Providers.Smb/SmbContentProvider.cs +++ b/src/Providers/FileTime.Providers.Smb/SmbContentProvider.cs @@ -64,7 +64,7 @@ namespace FileTime.Providers.Smb throw new NotSupportedException(); } - public async Task GetByPath(string path) + public async Task 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; diff --git a/src/Providers/FileTime.Providers.Smb/SmbFolder.cs b/src/Providers/FileTime.Providers.Smb/SmbFolder.cs index 34a5d10..8156c65 100644 --- a/src/Providers/FileTime.Providers.Smb/SmbFolder.cs +++ b/src/Providers/FileTime.Providers.Smb/SmbFolder.cs @@ -51,7 +51,7 @@ namespace FileTime.Providers.Smb public Task Clone() => Task.FromResult((IContainer)this); - public async Task GetByPath(string path) + public async Task 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; diff --git a/src/Providers/FileTime.Providers.Smb/SmbServer.cs b/src/Providers/FileTime.Providers.Smb/SmbServer.cs index f1faca2..9fbe85e 100644 --- a/src/Providers/FileTime.Providers.Smb/SmbServer.cs +++ b/src/Providers/FileTime.Providers.Smb/SmbServer.cs @@ -77,7 +77,7 @@ namespace FileTime.Providers.Smb return Task.CompletedTask; } - public Task GetByPath(string path) + public Task GetByPath(string path, bool acceptDeepestMatch = false) { throw new NotImplementedException(); } diff --git a/src/Providers/FileTime.Providers.Smb/SmbShare.cs b/src/Providers/FileTime.Providers.Smb/SmbShare.cs index 8d1a222..9c09818 100644 --- a/src/Providers/FileTime.Providers.Smb/SmbShare.cs +++ b/src/Providers/FileTime.Providers.Smb/SmbShare.cs @@ -70,7 +70,7 @@ namespace FileTime.Providers.Smb throw new NotImplementedException(); } - public async Task GetByPath(string path) + public async Task 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;