diff --git a/src/Core/FileTime.Core/Models/SupportsDelete.cs b/src/Core/FileTime.Core/Models/SupportsDelete.cs index 4648023..18ffc99 100644 --- a/src/Core/FileTime.Core/Models/SupportsDelete.cs +++ b/src/Core/FileTime.Core/Models/SupportsDelete.cs @@ -2,8 +2,8 @@ namespace FileTime.Core.Models { public enum SupportsDelete { + False, True, HardDeleteOnly, - False } } \ No newline at end of file diff --git a/src/Core/FileTime.Core/Providers/AbstractContainer.cs b/src/Core/FileTime.Core/Providers/AbstractContainer.cs index d94b423..ede3481 100644 --- a/src/Core/FileTime.Core/Providers/AbstractContainer.cs +++ b/src/Core/FileTime.Core/Providers/AbstractContainer.cs @@ -46,7 +46,7 @@ namespace FileTime.Core.Providers Exceptions = _exceptions.AsReadOnly(); } - public abstract Task CanOpenAsync(); + public virtual Task CanOpenAsync() => Task.FromResult(_exceptions.Count == 0); public abstract Task CloneAsync(); @@ -61,6 +61,7 @@ namespace FileTime.Core.Providers _items = null; _containers = null; _elements = null; + IsLoaded = false; IsDestroyed = true; Refreshed = new AsyncEventHandler(); } @@ -93,6 +94,7 @@ namespace FileTime.Core.Providers public virtual async Task RefreshAsync(CancellationToken token = default) { + _exceptions.Clear(); var containers = new List(); var elements = new List(); foreach (var item in await RefreshItems(token)) @@ -118,8 +120,10 @@ namespace FileTime.Core.Providers _containers = containers.OrderBy(c => c.Name).ToList().AsReadOnly(); _elements = elements.OrderBy(e => e.Name).ToList().AsReadOnly(); _items = _containers.Cast().Concat(_elements).ToList().AsReadOnly(); + IsLoaded = true; if (Refreshed != null) await Refreshed.InvokeAsync(this, AsyncEventArgs.Empty, token); } + public abstract Task> RefreshItems(CancellationToken token = default); public abstract Task Rename(string newName); @@ -129,6 +133,9 @@ namespace FileTime.Core.Providers _items = null; _containers = null; _elements = null; + IsLoaded = false; } + + protected void AddException(Exception e) => _exceptions.Add(e); } } \ No newline at end of file diff --git a/src/Core/FileTime.Core/Providers/TopContainer.cs b/src/Core/FileTime.Core/Providers/TopContainer.cs index 937225e..c722135 100644 --- a/src/Core/FileTime.Core/Providers/TopContainer.cs +++ b/src/Core/FileTime.Core/Providers/TopContainer.cs @@ -1,5 +1,3 @@ - -using System; using AsyncEvent; using FileTime.Core.Models; diff --git a/src/Providers/FileTime.Providers.Local/LocalFolder.cs b/src/Providers/FileTime.Providers.Local/LocalFolder.cs index e6b3a3e..ee57801 100644 --- a/src/Providers/FileTime.Providers.Local/LocalFolder.cs +++ b/src/Providers/FileTime.Providers.Local/LocalFolder.cs @@ -1,55 +1,25 @@ using System.Runtime.InteropServices; -using AsyncEvent; using FileTime.Core.Models; using FileTime.Core.Providers; using FileTime.Providers.Local.Interop; namespace FileTime.Providers.Local { - public class LocalFolder : IContainer + public class LocalFolder : AbstractContainer { - private IReadOnlyList? _items; - private IReadOnlyList? _containers; - private IReadOnlyList? _elements; - private readonly List _exceptions; - private readonly IContainer? _parent; - - public bool IsHidden => (Directory.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden; public DirectoryInfo Directory { get; } - public LocalContentProvider Provider { get; } - IContentProvider IItem.Provider => Provider; - - public string Name { get; } - - public string FullName { get; } - public string? NativePath => Directory.FullName; - - public bool IsLoaded => _items != null; - public SupportsDelete CanDelete { get; } - public bool CanRename => true; - - public AsyncEventHandler Refreshed { get; private set; } = new(); public string Attributes => GetAttributes(); public DateTime CreatedAt => Directory.CreationTime; - public IReadOnlyList Exceptions { get; } - public bool IsDestroyed { get; private set; } - - public bool SupportsDirectoryLevelSoftDelete { get; } - - public LocalFolder(DirectoryInfo directory, LocalContentProvider contentProvider, IContainer? parent) + public LocalFolder(DirectoryInfo directory, LocalContentProvider contentProvider, IContainer parent) + : base(contentProvider, parent, directory.Name.TrimEnd(Path.DirectorySeparatorChar)) { Directory = directory; - _parent = parent; - - _exceptions = new List(); - Exceptions = _exceptions.AsReadOnly(); - - Name = directory.Name.TrimEnd(Path.DirectorySeparatorChar); - FullName = parent?.FullName == null ? Name : parent.FullName + Constants.SeparatorChar + Name; - Provider = contentProvider; + NativePath = Directory.FullName; + IsHidden = (Directory.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden; + CanRename = true; //TODO: Linux soft delete SupportsDirectoryLevelSoftDelete = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); @@ -58,58 +28,28 @@ namespace FileTime.Providers.Local : SupportsDelete.HardDeleteOnly; } - public IContainer? GetParent() => _parent; + public override Task CloneAsync() => Task.FromResult((IContainer)new LocalFolder(Directory, Provider, GetParent()!)); - public Task CloneAsync() => Task.FromResult((IContainer)new LocalFolder(Directory, Provider, _parent)); - - public async Task RefreshAsync(CancellationToken token = default) + public override Task> RefreshItems(CancellationToken token = default) { - if (_items != null) - { - foreach (var item in _items) - { - item.Destroy(); - } - } - - _containers = new List(); - _elements = new List(); - _items = new List(); - _exceptions.Clear(); - try { - if (token.IsCancellationRequested) return; - _containers = Directory.GetDirectories().Select(d => new LocalFolder(d, Provider, this)).OrderBy(d => d.Name).ToList().AsReadOnly(); + if (token.IsCancellationRequested) return Task.FromResult(Enumerable.Empty()); + var containers = Directory.GetDirectories().Select(d => new LocalFolder(d, Provider, this)).OrderBy(d => d.Name).ToList().AsReadOnly(); - if (token.IsCancellationRequested) return; - _elements = Directory.GetFiles().Select(f => new LocalFile(f, this, Provider)).OrderBy(f => f.Name).ToList().AsReadOnly(); + if (token.IsCancellationRequested) return Task.FromResult(Enumerable.Empty()); + var elements = Directory.GetFiles().Select(f => new LocalFile(f, this, Provider)).OrderBy(f => f.Name).ToList().AsReadOnly(); - if (token.IsCancellationRequested) return; + if (token.IsCancellationRequested) return Task.FromResult(Enumerable.Empty()); + + return Task.FromResult(containers.Cast().Concat(elements)); } catch (Exception e) { - _exceptions.Add(e); + AddException(e); } - _items = _containers.Cast().Concat(_elements).ToList().AsReadOnly(); - if (Refreshed != null) await Refreshed.InvokeAsync(this, AsyncEventArgs.Empty, token); - } - - public async Task?> GetItems(CancellationToken token = default) - { - if (_items == null) await RefreshAsync(token); - return _items; - } - public async Task?> GetContainers(CancellationToken token = default) - { - if (_containers == null) await RefreshAsync(token); - return _containers; - } - public async Task?> GetElements(CancellationToken token = default) - { - if (_elements == null) await RefreshAsync(token); - return _elements; + return Task.FromResult(Enumerable.Empty()); } public async Task GetByPath(string path, bool acceptDeepestMatch = false) @@ -131,25 +71,25 @@ namespace FileTime.Providers.Local return null; } - public async Task CreateContainerAsync(string name) + public override async Task CreateContainerAsync(string name) { Directory.CreateSubdirectory(name); await RefreshAsync(); - return _containers!.FirstOrDefault(c => Provider.NormalizePath(c.Name) == Provider.NormalizePath(name))!; + return (await GetContainers())!.FirstOrDefault(c => Provider.NormalizePath(c.Name) == Provider.NormalizePath(name))!; } - public async Task CreateElementAsync(string name) + public override async Task CreateElementAsync(string name) { using (File.Create(Path.Combine(Directory.FullName, name))) { } await RefreshAsync(); - return _elements!.FirstOrDefault(e => Provider.NormalizePath(e.Name) == Provider.NormalizePath(name))!; + return (await GetElements())!.FirstOrDefault(e => Provider.NormalizePath(e.Name) == Provider.NormalizePath(name))!; } - public async Task IsExistsAsync(string name) => (await GetItems())?.Any(i => Provider.NormalizePath(i.Name) == Provider.NormalizePath(name)) ?? false; + public override async Task IsExistsAsync(string name) => (await GetItems())?.Any(i => Provider.NormalizePath(i.Name) == Provider.NormalizePath(name)) ?? false; - public Task Delete(bool hardDelete = false) + public override Task Delete(bool hardDelete = false) { if (hardDelete) { @@ -161,12 +101,12 @@ namespace FileTime.Providers.Local } return Task.CompletedTask; } - public async Task Rename(string newName) + public override async Task Rename(string newName) { - if (_parent is LocalFolder parentFolder) + if (GetParent() is LocalFolder parentFolder) { System.IO.Directory.Move(Directory.FullName, Path.Combine(parentFolder.Directory.FullName, newName)); - await _parent.RefreshAsync(); + await parentFolder.RefreshAsync(); } } @@ -185,22 +125,5 @@ namespace FileTime.Providers.Local + ((Directory.Attributes & FileAttributes.System) == FileAttributes.System ? "s" : "-"); } } - public Task CanOpenAsync() => Task.FromResult(true); - - public void Destroy() - { - _items = null; - _containers = null; - _elements = null; - IsDestroyed = true; - Refreshed = new AsyncEventHandler(); - } - - public void Unload() - { - _items = null; - _containers = null; - _elements = null; - } } } \ No newline at end of file diff --git a/src/Providers/FileTime.Providers.Sftp/SftpFolder.cs b/src/Providers/FileTime.Providers.Sftp/SftpFolder.cs index df43e29..a4f7bf1 100644 --- a/src/Providers/FileTime.Providers.Sftp/SftpFolder.cs +++ b/src/Providers/FileTime.Providers.Sftp/SftpFolder.cs @@ -12,7 +12,6 @@ namespace FileTime.Providers.Sftp _server = server; NativePath = FullName; } - public override Task CanOpenAsync() => Task.FromResult(true); public override Task CloneAsync() { diff --git a/src/Providers/FileTime.Providers.Sftp/SftpServer.cs b/src/Providers/FileTime.Providers.Sftp/SftpServer.cs index c198805..a009c5e 100644 --- a/src/Providers/FileTime.Providers.Sftp/SftpServer.cs +++ b/src/Providers/FileTime.Providers.Sftp/SftpServer.cs @@ -35,8 +35,6 @@ namespace FileTime.Providers.Sftp public override async Task> RefreshItems(CancellationToken token = default) => await ListDirectory(""); - public override Task CanOpenAsync() => Task.FromResult(true); - public override Task CloneAsync() => Task.FromResult((IContainer)this); public override Task CreateContainerAsync(string name) @@ -78,8 +76,7 @@ namespace FileTime.Providers.Sftp isClientNull = _client == null; } - int reTries = 0; - while (isClientNull) + for (int reTries = 0; isClientNull; reTries++) { if (!await RefreshSftpClient()) { @@ -95,7 +92,6 @@ namespace FileTime.Providers.Sftp { throw new Exception($"Could not connect to server {Name} after {reTries} retry"); } - reTries++; } return _client!; } diff --git a/src/Providers/FileTime.Providers.Smb/SmbFolder.cs b/src/Providers/FileTime.Providers.Smb/SmbFolder.cs index 2c5975c..21f5cb2 100644 --- a/src/Providers/FileTime.Providers.Smb/SmbFolder.cs +++ b/src/Providers/FileTime.Providers.Smb/SmbFolder.cs @@ -1,80 +1,47 @@ -using AsyncEvent; using FileTime.Core.Models; using FileTime.Core.Providers; using SMBLibrary; namespace FileTime.Providers.Smb { - public class SmbFolder : IContainer + public class SmbFolder : AbstractContainer { - private IReadOnlyList? _items; - private IReadOnlyList? _containers; - private IReadOnlyList? _elements; - private readonly IContainer? _parent; private readonly SmbClientContext _smbClientContext; - public string Name { get; } - public string? FullName { get; } - public string? NativePath { get; } - - public bool IsHidden => false; - public bool IsLoaded => _items != null; - - public SmbContentProvider Provider { get; } - IContentProvider IItem.Provider => Provider; public SmbShare SmbShare { get; } - public SupportsDelete CanDelete => SupportsDelete.True; - public bool CanRename => true; - - public AsyncEventHandler Refreshed { get; } = new(); - public IReadOnlyList Exceptions { get; } = new List().AsReadOnly(); - - public bool IsDestroyed { get; private set; } - - public bool SupportsDirectoryLevelSoftDelete => false; public SmbFolder(string name, SmbContentProvider contentProvider, SmbShare smbShare, IContainer parent, SmbClientContext smbClientContext) + : base(contentProvider, parent, name) { - _parent = parent; _smbClientContext = smbClientContext; SmbShare = smbShare; - - Name = name; - FullName = parent.FullName! + Constants.SeparatorChar + Name; NativePath = parent.NativePath + SmbContentProvider.GetNativePathSeparator() + name; - Provider = contentProvider; + CanDelete = SupportsDelete.True; + CanRename = true; } - public async Task CreateContainerAsync(string name) + public override async Task CreateContainerAsync(string name) { var path = FullName![(SmbShare.FullName!.Length + 1)..] + Constants.SeparatorChar + name; await SmbShare.CreateContainerWithPathAsync(path.Replace("/", "\\")); await RefreshAsync(); - return _containers!.FirstOrDefault(e => e.Name == name)!; + return (await GetContainers())!.FirstOrDefault(e => e.Name == name)!; } - public async Task CreateElementAsync(string name) + public override async Task CreateElementAsync(string name) { var path = FullName![(SmbShare.FullName!.Length + 1)..] + Constants.SeparatorChar + name; await SmbShare.CreateElementWithPathAsync(path.Replace("/", "\\")); await RefreshAsync(); - return _elements!.FirstOrDefault(e => e.Name == name)!; + return (await GetElements())!.FirstOrDefault(e => e.Name == name)!; } - public Task CloneAsync() => Task.FromResult((IContainer)this); + public override Task CloneAsync() => Task.FromResult((IContainer)new SmbFolder(Name, Provider, SmbShare, GetParent(), _smbClientContext)); - public IContainer? GetParent() => _parent; - - public async Task IsExistsAsync(string name) - { - var items = await GetItems(); - return items?.Any(i => i.Name == name) ?? false; - } - - public async Task Delete(bool hardDelete = false) + public override async Task Delete(bool hardDelete = false) { await _smbClientContext.RunWithSmbClientAsync(client => { @@ -103,62 +70,23 @@ namespace FileTime.Providers.Smb status = fileStore.Disconnect(); }); } - public Task Rename(string newName) + public override Task Rename(string newName) { throw new NotImplementedException(); } - public async Task RefreshAsync(CancellationToken token = default) + public override async Task> RefreshItems(CancellationToken token = default) { - var containers = new List(); - var elements = new List(); - try { var path = FullName![(SmbShare.FullName!.Length + 1)..]; - (containers, elements) = await SmbShare.ListFolder(this, path, token); + var (containers, elements) = await SmbShare.ListFolder(this, path, token); + + return containers.Cast().Concat(elements); } catch { } - _containers = containers.AsReadOnly(); - _elements = elements.AsReadOnly(); - - if (_items != null) - { - foreach (var item in _items) - { - item.Destroy(); - } - } - - _items = _containers.Cast().Concat(_elements).ToList().AsReadOnly(); - await Refreshed.InvokeAsync(this, AsyncEventArgs.Empty, token); - } - - public async Task?> GetItems(CancellationToken token = default) - { - if (_items == null) await RefreshAsync(token); - return _items; - } - public async Task?> GetContainers(CancellationToken token = default) - { - if (_containers == null) await RefreshAsync(token); - return _containers; - } - public async Task?> GetElements(CancellationToken token = default) - { - if (_elements == null) await RefreshAsync(token); - return _elements; - } - public Task CanOpenAsync() => Task.FromResult(true); - - public void Destroy() => IsDestroyed = true; - - public void Unload() - { - _items = null; - _containers = null; - _elements = null; + return Enumerable.Empty(); } private string GetPathFromShare() => FullName![(SmbShare.FullName!.Length + 1)..].Replace("/", "\\"); diff --git a/src/Providers/FileTime.Providers.Smb/SmbServer.cs b/src/Providers/FileTime.Providers.Smb/SmbServer.cs index 6bcde52..e4ef80d 100644 --- a/src/Providers/FileTime.Providers.Smb/SmbServer.cs +++ b/src/Providers/FileTime.Providers.Smb/SmbServer.cs @@ -1,6 +1,5 @@ using System.Net; using System.Runtime.InteropServices; -using AsyncEvent; using FileTime.Core.Interactions; using FileTime.Core.Models; using FileTime.Core.Providers; @@ -9,87 +8,46 @@ using SMBLibrary.Client; namespace FileTime.Providers.Smb { - public class SmbServer : IContainer + public class SmbServer : AbstractContainer { internal const int MAXRETRIES = 5; private bool _reenterCredentials; - - private IReadOnlyList? _shares; - private IReadOnlyList? _items; - private readonly IReadOnlyList? _elements = new List().AsReadOnly(); private ISMBClient? _client; private readonly object _clientGuard = new(); private bool _refreshingClient; private readonly IInputInterface _inputInterface; private readonly SmbClientContext _smbClientContext; - private readonly List _exceptions = new(); public string? Username { get; private set; } public string? Password { get; private set; } - public string Name { get; } - public string? FullName { get; } - public string? NativePath { get; } - - public bool IsHidden => false; - public bool IsLoaded => _items != null; - - public SmbContentProvider Provider { get; } - - IContentProvider IItem.Provider => Provider; - public SupportsDelete CanDelete => SupportsDelete.True; - public bool CanRename => false; - public IReadOnlyList Exceptions { get; } - - public AsyncEventHandler Refreshed { get; } = new(); - - public bool SupportsDirectoryLevelSoftDelete => false; - - public bool IsDestroyed => false; - - public SmbServer(string path, SmbContentProvider contentProvider, IInputInterface inputInterface, string? username = null, string? password = null) + public SmbServer(string name, SmbContentProvider contentProvider, IInputInterface inputInterface, string? username = null, string? password = null) + : base(contentProvider, contentProvider, name) { _inputInterface = inputInterface; _smbClientContext = new SmbClientContext(GetSmbClient, DisposeSmbClient); - Exceptions = _exceptions.AsReadOnly(); Username = username; Password = password; + CanDelete = SupportsDelete.True; - Provider = contentProvider; - Name = path; FullName = contentProvider.Protocol + Name; NativePath = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "\\\\" + Name : contentProvider.Protocol + Name; } - public async Task?> GetItems(CancellationToken token = default) - { - if (_shares == null) await RefreshAsync(token); - return _shares; - } - public async Task?> GetContainers(CancellationToken token = default) - { - if (_shares == null) await RefreshAsync(token); - return _shares; - } - public Task?> GetElements(CancellationToken token = default) - { - return Task.FromResult(_elements); - } - - public Task CreateContainerAsync(string name) + public override Task CreateContainerAsync(string name) { throw new NotSupportedException(); } - public Task CreateElementAsync(string name) + public override Task CreateElementAsync(string name) { throw new NotSupportedException(); } - public Task Delete(bool hardDelete = false) + public override Task Delete(bool hardDelete = false) { return Task.CompletedTask; } @@ -114,31 +72,23 @@ namespace FileTime.Providers.Smb return null; } - public IContainer? GetParent() => Provider; - - public Task IsExistsAsync(string name) - { - throw new NotImplementedException(); - } - - public async Task RefreshAsync(CancellationToken token = default) + public override async Task> RefreshItems(CancellationToken token = default) { try { - _exceptions.Clear(); - List shares = await _smbClientContext.RunWithSmbClientAsync((client) => client.ListShares(out var status), _shares == null ? 1 : MAXRETRIES); + var shares = await _smbClientContext.RunWithSmbClientAsync((client) => client.ListShares(out var status), IsLoaded ? MAXRETRIES : 1); - _shares = shares.ConvertAll(s => new SmbShare(s, Provider, this, _smbClientContext)).AsReadOnly(); - _items = _shares.Cast().ToList().AsReadOnly(); - await Refreshed.InvokeAsync(this, AsyncEventArgs.Empty, token); + return shares.Select(s => new SmbShare(s, Provider, this, _smbClientContext)); } catch (Exception e) { - _exceptions.Add(e); + AddException(e); } + + return Enumerable.Empty(); } - public Task CloneAsync() => Task.FromResult((IContainer)this); + public override Task CloneAsync() => Task.FromResult((IContainer)this); private void DisposeSmbClient() { @@ -156,8 +106,7 @@ namespace FileTime.Providers.Smb isClientNull = _client == null; } - int reTries = 0; - while (isClientNull) + for (var reTries = 0; isClientNull; reTries++) { if (!await RefreshSmbClient()) { @@ -173,7 +122,6 @@ namespace FileTime.Providers.Smb { throw new Exception($"Could not connect to server {Name} after {reTries} retry"); } - reTries++; } return _client!; } @@ -235,11 +183,7 @@ namespace FileTime.Providers.Smb return true; } - public Task Rename(string newName) => throw new NotSupportedException(); - public Task CanOpenAsync() => Task.FromResult(true); - - public void Destroy() { } - - public void Unload() { } + public override Task Rename(string newName) => throw new NotSupportedException(); + public override Task CanOpenAsync() => Task.FromResult(true); } } \ No newline at end of file diff --git a/src/Providers/FileTime.Providers.Smb/SmbShare.cs b/src/Providers/FileTime.Providers.Smb/SmbShare.cs index 74379ce..046f6d3 100644 --- a/src/Providers/FileTime.Providers.Smb/SmbShare.cs +++ b/src/Providers/FileTime.Providers.Smb/SmbShare.cs @@ -1,4 +1,3 @@ -using AsyncEvent; using FileTime.Core.Models; using FileTime.Core.Providers; using SMBLibrary; @@ -6,67 +5,24 @@ using SMBLibrary.Client; namespace FileTime.Providers.Smb { - public class SmbShare : IContainer + public class SmbShare : AbstractContainer { - private IReadOnlyList? _items; - private IReadOnlyList? _containers; - private IReadOnlyList? _elements; private readonly SmbClientContext _smbClientContext; - private readonly IContainer? _parent; - - public string Name { get; } - - public string? FullName { get; } - public string? NativePath { get; } - - public bool IsHidden => false; - public bool IsLoaded => _items != null; - - public SmbContentProvider Provider { get; } - IContentProvider IItem.Provider => Provider; - public SupportsDelete CanDelete => SupportsDelete.False; - public bool CanRename => false; - - public AsyncEventHandler Refreshed { get; } = new(); - public IReadOnlyList Exceptions { get; } = new List().AsReadOnly(); - - public bool IsDestroyed => false; - - public bool SupportsDirectoryLevelSoftDelete => false; public SmbShare(string name, SmbContentProvider contentProvider, IContainer parent, SmbClientContext smbClientContext) + : base(contentProvider, parent, name) { - _parent = parent; _smbClientContext = smbClientContext; - - Name = name; - FullName = parent.FullName! + Constants.SeparatorChar + Name; NativePath = parent.NativePath + SmbContentProvider.GetNativePathSeparator() + name; - Provider = contentProvider; + CanDelete = SupportsDelete.False; } - public async Task?> GetItems(CancellationToken token = default) - { - if (_items == null) await RefreshAsync(token); - return _items; - } - public async Task?> GetContainers(CancellationToken token = default) - { - if (_containers == null) await RefreshAsync(token); - return _containers; - } - public async Task?> GetElements(CancellationToken token = default) - { - if (_elements == null) await RefreshAsync(token); - return _elements; - } - - public async Task CreateContainerAsync(string name) + public override async Task CreateContainerAsync(string name) { await CreateContainerWithPathAsync(name); await RefreshAsync(); - return _containers!.FirstOrDefault(e => e.Name == name)!; + return (await GetContainers())!.FirstOrDefault(e => e.Name == name)!; } internal async Task CreateContainerWithPathAsync(string path) { @@ -101,12 +57,12 @@ namespace FileTime.Providers.Smb }); } - public async Task CreateElementAsync(string name) + public override async Task CreateElementAsync(string name) { await CreateElementWithPathAsync(name); await RefreshAsync(); - return _elements!.FirstOrDefault(e => e.Name == name)!; + return (await GetElements())!.FirstOrDefault(e => e.Name == name)!; } internal async Task CreateElementWithPathAsync(string path) { @@ -141,45 +97,24 @@ namespace FileTime.Providers.Smb }); } - public Task Delete(bool hardDelete = false) + public override Task Delete(bool hardDelete = false) { throw new NotSupportedException(); } - public IContainer? GetParent() => _parent; + public override Task CloneAsync() => Task.FromResult((IContainer)this); - public Task CloneAsync() => Task.FromResult((IContainer)this); - - public async Task IsExistsAsync(string name) + public override async Task> RefreshItems(CancellationToken token = default) { - var items = await GetItems(); - return items?.Any(i => i.Name == name) ?? false; - } - - public async Task RefreshAsync(CancellationToken token = default) - { - var containers = new List(); - var elements = new List(); - try { - (containers, elements) = await ListFolder(this, string.Empty, token); + var (containers, elements) = await ListFolder(this, string.Empty, token); + + return containers.Cast().Concat(elements); } catch { } - if (_items != null) - { - foreach (var item in _items) - { - item.Destroy(); - } - } - - _containers = containers.AsReadOnly(); - _elements = elements.AsReadOnly(); - - _items = _containers.Cast().Concat(_elements).ToList().AsReadOnly(); - await Refreshed.InvokeAsync(this, AsyncEventArgs.Empty, token); + return Enumerable.Empty(); } public async Task<(List containers, List elements)> ListFolder(IContainer parent, string folderName, CancellationToken token = default) @@ -228,16 +163,6 @@ namespace FileTime.Providers.Smb return client.TreeConnect(Name, out status); } - public Task Rename(string newName) => throw new NotSupportedException(); - public Task CanOpenAsync() => Task.FromResult(true); - - public void Destroy() { } - - public void Unload() - { - _items = null; - _containers = null; - _elements = null; - } + public override Task Rename(string newName) => throw new NotSupportedException(); } } \ No newline at end of file