Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix #1138 File saver and Folder picker #1142

Merged
merged 3 commits into from
May 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -77,18 +77,12 @@ static AndroidUri EnsurePhysicalPath(AndroidUri? uri)

static async Task<string> SaveDocument(AndroidUri uri, Stream stream, CancellationToken cancellationToken)
{
var parcelFileDescriptor = Application.Context.ContentResolver?.OpenFileDescriptor(uri, "w");
var fileOutputStream = new FileOutputStream(parcelFileDescriptor?.FileDescriptor);
using var parcelFileDescriptor = Application.Context.ContentResolver?.OpenFileDescriptor(uri, "wt");
using var fileOutputStream = new FileOutputStream(parcelFileDescriptor?.FileDescriptor);
await using var memoryStream = new MemoryStream();

stream.Seek(0, SeekOrigin.Begin);
await stream.CopyToAsync(memoryStream, cancellationToken).ConfigureAwait(false);
await fileOutputStream.WriteAsync(memoryStream.ToArray()).WaitAsync(cancellationToken).ConfigureAwait(false);

fileOutputStream.Close();
parcelFileDescriptor?.Close();
var split = uri.Path?.Split(':') ?? throw new FolderPickerException("Unable to resolve path.");

return $"{Android.OS.Environment.ExternalStorageDirectory}/{split[^1]}";
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Runtime.Versioning;
using Microsoft.Maui.ApplicationModel;

namespace CommunityToolkit.Maui.Storage;

Expand Down Expand Up @@ -31,17 +32,27 @@ async Task<string> InternalSaveAsync(string initialPath, string fileName, Stream
await WriteStream(stream, fileUrl.Path ?? throw new Exception("Path cannot be null."), cancellationToken);

cancellationToken.ThrowIfCancellationRequested();
taskCompetedSource = new TaskCompletionSource<string>();
taskCompetedSource?.TrySetCanceled(CancellationToken.None);
var tcs = taskCompetedSource = new (cancellationToken);

documentPickerViewController = new UIDocumentPickerViewController(new[] { fileUrl });
documentPickerViewController.DirectoryUrl = NSUrl.FromString(initialPath);
documentPickerViewController = new(new[] { fileUrl })
{
DirectoryUrl = NSUrl.FromString(initialPath)
};
documentPickerViewController.DidPickDocumentAtUrls += DocumentPickerViewControllerOnDidPickDocumentAtUrls;
documentPickerViewController.WasCancelled += DocumentPickerViewControllerOnWasCancelled;

var currentViewController = Microsoft.Maui.Platform.UIApplicationExtensions.GetKeyWindow(UIApplication.SharedApplication)?.RootViewController;
currentViewController?.PresentViewController(documentPickerViewController, true, null);
var currentViewController = Platform.GetCurrentUIViewController();
if (currentViewController is not null)
{
currentViewController.PresentViewController(documentPickerViewController, true, null);
}
else
{
throw new FileSaveException("Unable to get a window where to present the file saver UI.");
}

return await taskCompetedSource.Task.WaitAsync(cancellationToken).ConfigureAwait(false);
return await tcs.Task.WaitAsync(cancellationToken).ConfigureAwait(false);
}

Task<string> InternalSaveAsync(string fileName, Stream stream, CancellationToken cancellationToken)
Expand All @@ -51,15 +62,15 @@ Task<string> InternalSaveAsync(string fileName, Stream stream, CancellationToken

void DocumentPickerViewControllerOnWasCancelled(object? sender, EventArgs e)
{
taskCompetedSource?.SetException(new FolderPickerException("Operation cancelled."));
taskCompetedSource?.SetException(new FileSaveException("Operation cancelled."));
InternalDispose();
}

void DocumentPickerViewControllerOnDidPickDocumentAtUrls(object? sender, UIDocumentPickedAtUrlsEventArgs e)
{
try
{
taskCompetedSource?.SetResult(e.Urls[0].Path ?? throw new FileSaveException("Unable to retrieve the path of the saved file."));
taskCompetedSource?.TrySetResult(e.Urls[0].Path ?? throw new FileSaveException("Unable to retrieve the path of the saved file."));
}
finally
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Runtime.Versioning;
using CommunityToolkit.Maui.Core.Primitives;
using Microsoft.Maui.ApplicationModel;
using UniformTypeIdentifiers;

namespace CommunityToolkit.Maui.Storage;
Expand Down Expand Up @@ -37,12 +38,20 @@ async Task<Folder> InternalPickAsync(string initialPath, CancellationToken cance
{
cancellationToken.ThrowIfCancellationRequested();
documentPickerViewController.DirectoryUrl = NSUrl.FromString(initialPath);
var currentViewController = Microsoft.Maui.Platform.UIApplicationExtensions.GetKeyWindow(UIApplication.SharedApplication)?.RootViewController;
var currentViewController = Platform.GetCurrentUIViewController();

taskCompetedSource = new TaskCompletionSource<Folder>();
currentViewController?.PresentViewController(documentPickerViewController, true, null);
taskCompetedSource?.TrySetCanceled(CancellationToken.None);
var tcs = taskCompetedSource = new ();
if (currentViewController is not null)
{
currentViewController.PresentViewController(documentPickerViewController, true, null);
}
else
{
throw new FolderPickerException("Unable to get a window where to present the folder picker UI.");
}

return await taskCompetedSource.Task.WaitAsync(cancellationToken).ConfigureAwait(false);
return await tcs.Task.WaitAsync(cancellationToken).ConfigureAwait(false);
}

Task<Folder> InternalPickAsync(CancellationToken cancellationToken)
Expand Down