diff --git a/Camelotia.Presentation.Avalonia/Views/ProviderView.xaml b/Camelotia.Presentation.Avalonia/Views/ProviderView.xaml
index ea83547..ab10373 100644
--- a/Camelotia.Presentation.Avalonia/Views/ProviderView.xaml
+++ b/Camelotia.Presentation.Avalonia/Views/ProviderView.xaml
@@ -104,6 +104,7 @@
+
@@ -114,16 +115,20 @@
Classes="Rounded"
IsVisible="{Binding CanLogout}"
Command="{Binding Logout}" />
-
+
+
-
-
diff --git a/Camelotia.Presentation.Tests/LocalFileSystemProviderTests.cs b/Camelotia.Presentation.Tests/LocalFileSystemProviderTests.cs
index bf9b0e4..cf4c526 100644
--- a/Camelotia.Presentation.Tests/LocalFileSystemProviderTests.cs
+++ b/Camelotia.Presentation.Tests/LocalFileSystemProviderTests.cs
@@ -47,9 +47,7 @@ namespace Camelotia.Presentation.Tests
foreach (var model in real)
expected.Should().Contain(drive =>
- model.Name == drive.Name &&
- model.IsFolder == false &&
- model.IsDrive);
+ model.Name == drive.Name && model.IsFolder);
}
[Fact]
diff --git a/Camelotia.Presentation.Tests/ProviderViewModelTests.cs b/Camelotia.Presentation.Tests/ProviderViewModelTests.cs
index c56fc9b..2ebed24 100644
--- a/Camelotia.Presentation.Tests/ProviderViewModelTests.cs
+++ b/Camelotia.Presentation.Tests/ProviderViewModelTests.cs
@@ -95,7 +95,7 @@ namespace Camelotia.Presentation.Tests
[Fact]
public void ShouldBeAbleToOpenSelectedPath() => new TestScheduler().With(scheduler =>
{
- var file = new FileModel("foo", Separator + "foo", true, false, string.Empty);
+ var file = new FileModel("foo", Separator + "foo", true, string.Empty);
_provider.Get(Separator).Returns(Enumerable.Repeat(file, 1));
_authViewModel.IsAuthenticated.Returns(true);
_provider.InitialPath.Returns(Separator);
diff --git a/Camelotia.Presentation.Uwp/Views/ProviderView.xaml b/Camelotia.Presentation.Uwp/Views/ProviderView.xaml
index c8305a9..1c5cf9c 100644
--- a/Camelotia.Presentation.Uwp/Views/ProviderView.xaml
+++ b/Camelotia.Presentation.Uwp/Views/ProviderView.xaml
@@ -115,6 +115,7 @@
+
@@ -124,16 +125,19 @@
Style="{StaticResource ButtonRevealStyle}"
Visibility="{x:Bind ViewModel.CanLogout, Mode=OneWay}"
Command="{x:Bind ViewModel.Logout, Mode=OneWay}" />
-
+
+
-
-
diff --git a/Camelotia.Presentation/Interfaces/IProviderViewModel.cs b/Camelotia.Presentation/Interfaces/IProviderViewModel.cs
index d69894b..4c4ec7a 100644
--- a/Camelotia.Presentation/Interfaces/IProviderViewModel.cs
+++ b/Camelotia.Presentation/Interfaces/IProviderViewModel.cs
@@ -16,7 +16,9 @@ namespace Camelotia.Presentation.Interfaces
ICommand DownloadSelectedFile { get; }
ICommand UploadToCurrentPath { get; }
-
+
+ ICommand DeleteSelectedFile { get; }
+
ICommand Refresh { get; }
ICommand Logout { get; }
diff --git a/Camelotia.Presentation/ViewModels/ProviderViewModel.cs b/Camelotia.Presentation/ViewModels/ProviderViewModel.cs
index 4ea9cb2..af088ff 100644
--- a/Camelotia.Presentation/ViewModels/ProviderViewModel.cs
+++ b/Camelotia.Presentation/ViewModels/ProviderViewModel.cs
@@ -24,6 +24,7 @@ namespace Camelotia.Presentation.ViewModels
private readonly ObservableAsPropertyHelper _isCurrentPathEmpty;
private readonly ReactiveCommand _downloadSelectedFile;
private readonly ReactiveCommand _uploadToCurrentPath;
+ private readonly ReactiveCommand _deleteSelectedFile;
private readonly ObservableAsPropertyHelper _currentPath;
private readonly ObservableAsPropertyHelper _hasErrors;
private readonly ObservableAsPropertyHelper _isLoading;
@@ -66,7 +67,7 @@ namespace Camelotia.Presentation.ViewModels
var canOpenCurrentPath = this
.WhenAnyValue(x => x.SelectedFile)
- .Select(file => file != null && (file.IsFolder || file.IsDrive))
+ .Select(file => file != null && file.IsFolder)
.CombineLatest(_refresh.IsExecuting, (folder, busy) => folder && !busy);
_open = ReactiveCommand.Create(
@@ -123,7 +124,7 @@ namespace Camelotia.Presentation.ViewModels
var canDownloadSelectedFile = this
.WhenAnyValue(x => x.SelectedFile)
- .Select(file => file != null && !file.IsFolder && !file.IsDrive)
+ .Select(file => file != null && !file.IsFolder)
.DistinctUntilChanged();
_downloadSelectedFile = ReactiveCommand.CreateFromObservable(
@@ -141,7 +142,7 @@ namespace Camelotia.Presentation.ViewModels
.Subscribe(Console.WriteLine);
this.WhenAnyValue(x => x.SelectedFile)
- .Where(file => file != null && (file.IsFolder || file.IsDrive))
+ .Where(file => file != null && file.IsFolder)
.Buffer(2, 1)
.Select(files => (files.First().Path, files.Last().Path))
.DistinctUntilChanged()
@@ -159,6 +160,16 @@ namespace Camelotia.Presentation.ViewModels
_logout = ReactiveCommand.CreateFromTask(provider.Logout, canLogout);
_canLogout = canLogout
.ToProperty(this, x => x.CanLogout, scheduler: currentThread);
+
+ var canDeleteSelection = this
+ .WhenAnyValue(x => x.SelectedFile)
+ .Select(file => file != null && !file.IsFolder);
+
+ _deleteSelectedFile = ReactiveCommand.CreateFromTask(
+ () => provider.Delete(SelectedFile),
+ canDeleteSelection);
+
+ _deleteSelectedFile.InvokeCommand(Refresh);
Auth = authViewModel;
Activator = new ViewModelActivator();
@@ -183,7 +194,9 @@ namespace Camelotia.Presentation.ViewModels
public ICommand DownloadSelectedFile => _downloadSelectedFile;
public ICommand UploadToCurrentPath => _uploadToCurrentPath;
-
+
+ public ICommand DeleteSelectedFile => _deleteSelectedFile;
+
public bool IsCurrentPathEmpty => _isCurrentPathEmpty.Value;
public IEnumerable Files => _files.Value;
diff --git a/Camelotia.Services/Interfaces/IProvider.cs b/Camelotia.Services/Interfaces/IProvider.cs
index a9ac9f4..aa6a4ee 100644
--- a/Camelotia.Services/Interfaces/IProvider.cs
+++ b/Camelotia.Services/Interfaces/IProvider.cs
@@ -22,6 +22,8 @@ namespace Camelotia.Services.Interfaces
Task DownloadFile(string from, Stream to);
+ Task Delete(FileModel file);
+
IObservable IsAuthorized { get; }
bool SupportsDirectAuth { get; }
diff --git a/Camelotia.Services/Models/FileModel.cs b/Camelotia.Services/Models/FileModel.cs
index 326069e..95347e0 100644
--- a/Camelotia.Services/Models/FileModel.cs
+++ b/Camelotia.Services/Models/FileModel.cs
@@ -2,12 +2,11 @@ namespace Camelotia.Services.Models
{
public sealed class FileModel
{
- public FileModel(string name, string path, bool isFolder, bool isDrive, string size)
+ public FileModel(string name, string path, bool isFolder, string size)
{
Name = name;
Path = path;
IsFolder = isFolder;
- IsDrive = isDrive;
Size = size;
}
@@ -17,8 +16,6 @@ namespace Camelotia.Services.Models
public bool IsFolder { get; }
- public bool IsDrive { get; }
-
public string Size { get; }
}
}
\ No newline at end of file
diff --git a/Camelotia.Services/Providers/LocalFileSystemProvider.cs b/Camelotia.Services/Providers/LocalFileSystemProvider.cs
index 54e8f31..967305b 100644
--- a/Camelotia.Services/Providers/LocalFileSystemProvider.cs
+++ b/Camelotia.Services/Providers/LocalFileSystemProvider.cs
@@ -20,7 +20,7 @@ namespace Camelotia.Services.Providers
public IObservable IsAuthorized { get; } = Observable.Return(true);
public bool SupportsDirectAuth => false;
-
+
public bool SupportsOAuth => false;
public string InitialPath => string.Empty;
@@ -38,19 +38,19 @@ namespace Camelotia.Services.Providers
var driveQuery = from entity in GetAllDrives()
where entity.IsReady
let size = ByteConverter.BytesToString(entity.AvailableFreeSpace)
- select new FileModel(entity.Name, entity.Name, false, true, size);
+ select new FileModel(entity.Name, entity.Name, true, size);
return driveQuery
.ToList()
.AsEnumerable();
}
-
+
if (!Directory.Exists(path))
throw new ArgumentException("Directory doesn't exist.");
-
- var query = from entity in Directory.GetFileSystemEntries(path)
- let isDirectory = IsDirectory(entity)
- let size = isDirectory ? "*" : ByteConverter.BytesToString(new FileInfo(entity).Length)
- select new FileModel(Path.GetFileName(entity), entity, isDirectory, false, size);
+
+ var query = from entity in Directory.GetFileSystemEntries(path)
+ let isDirectory = IsDirectory(entity)
+ let size = isDirectory ? "*" : ByteConverter.BytesToString(new FileInfo(entity).Length)
+ select new FileModel(Path.GetFileName(entity), entity, isDirectory, size);
return query
.ToList()
@@ -60,7 +60,7 @@ namespace Camelotia.Services.Providers
public async Task DownloadFile(string from, Stream to)
{
if (IsDirectory(from)) throw new InvalidOperationException("Can't download directory.");
-
+
using (var fileStream = File.OpenRead(from))
{
fileStream.Seek(0, SeekOrigin.Begin);
@@ -71,7 +71,7 @@ namespace Camelotia.Services.Providers
public async Task UploadFile(string to, Stream from, string name)
{
if (!IsDirectory(to)) throw new InvalidOperationException("Can't upload to a non-directory.");
-
+
var path = Path.Combine(to, name);
using (var fileStream = File.Create(path))
{
@@ -80,6 +80,13 @@ namespace Camelotia.Services.Providers
}
}
+ public Task Delete(FileModel file) => Task.Run(() =>
+ {
+ var isDirectory = IsDirectory(file.Path);
+ if (isDirectory) Directory.Delete(file.Path, false);
+ else File.Delete(file.Path);
+ });
+
private static string GetSizeOnAllDisks()
{
var totalBytes = GetAllDrives()
diff --git a/Camelotia.Services/Providers/VkontakteFileSystemProvider.cs b/Camelotia.Services/Providers/VkontakteFileSystemProvider.cs
index 2eb017c..e58781d 100644
--- a/Camelotia.Services/Providers/VkontakteFileSystemProvider.cs
+++ b/Camelotia.Services/Providers/VkontakteFileSystemProvider.cs
@@ -14,6 +14,7 @@ using VkNet.Enums.Filters;
using VkNet.Model;
using VkNet;
using VkNet.Abstractions;
+using VkNet.Model.Attachments;
namespace Camelotia.Services.Providers
{
@@ -78,19 +79,31 @@ namespace Camelotia.Services.Providers
var size = string.Empty;
if (document.Size.HasValue)
size = ByteConverter.BytesToString(document.Size.Value);
- return new FileModel(document.Title, document.Uri, false, false, size);
+ return new FileModel(document.Title, document.Id.ToString(), false, size);
});
}
public async Task DownloadFile(string from, Stream to)
{
- var isValidUriString = Uri.IsWellFormedUriString(from, UriKind.Absolute);
+ var id = long.Parse(from);
+ var users = await _api.Users.GetAsync(new long[0]);
+ var currentUser = users.First();
+
+ var documents = await _api.Docs.GetByIdAsync(new[] {new Document {Id = id, OwnerId = currentUser.Id}});
+ var document = documents.First();
+ Console.WriteLine (document.Uri);
+
+ var uri = document.Uri;
+ var isValidUriString = Uri.IsWellFormedUriString(uri, UriKind.Absolute);
if (!isValidUriString) throw new InvalidOperationException("Uri is invalid.");
using (var http = new HttpClient())
- using (var response = await http.GetAsync(from).ConfigureAwait(false))
+ using (var response = await http.GetAsync(uri).ConfigureAwait(false))
using (var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))
await stream.CopyToAsync(to).ConfigureAwait(false);
+
+ await to.FlushAsync();
+ to.Close();
}
public async Task UploadFile(string to, Stream from, string name)
@@ -111,7 +124,15 @@ namespace Camelotia.Services.Providers
var error = $"Unable to upload {name}{ext} \n{message}";
throw new Exception(error);
- }
+ }
+ }
+
+ public async Task Delete(FileModel file)
+ {
+ var id = long.Parse(file.Path);
+ var users = await _api.Users.GetAsync(new long[0]);
+ var currentUser = users.First();
+ await _api.Docs.DeleteAsync(currentUser.Id, id);
}
private async void EnsureLoggedInIfTokenSaved()
diff --git a/Camelotia.Services/Providers/YandexFileSystemProvider.cs b/Camelotia.Services/Providers/YandexFileSystemProvider.cs
index c2d19e7..77cda9f 100644
--- a/Camelotia.Services/Providers/YandexFileSystemProvider.cs
+++ b/Camelotia.Services/Providers/YandexFileSystemProvider.cs
@@ -69,7 +69,6 @@ namespace Camelotia.Services.Providers
file.Name,
file.Path.Replace("disk:", ""),
file.Type == "dir",
- false,
ByteConverter.BytesToString(file.Size)));
return models;
@@ -113,6 +112,14 @@ namespace Camelotia.Services.Providers
}
}
+ public async Task Delete(FileModel file)
+ {
+ var encodedPath = WebUtility.UrlEncode(file.Path);
+ var pathUrl = CloudApiGetPathBase + encodedPath;
+ using (var response = await _http.DeleteAsync(pathUrl).ConfigureAwait(false))
+ response.EnsureSuccessStatusCode();
+ }
+
public async Task Logout()
{
await _tokenStorage.WriteToken(null);