Skip to content

Commit

Permalink
chore: Start implementing a PHPickerResult-based file type
Browse files Browse the repository at this point in the history
  • Loading branch information
MartinZikmund committed Nov 22, 2024
1 parent c84629f commit 735ee53
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 22 deletions.
5 changes: 4 additions & 1 deletion src/Uno.UI/Resources/Strings/cs-CZ/Resources.resw
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@
<data name="StorageProviderIosSecurityScopedDisplayName" xml:space="preserve">
<value>iOS Security Scoped</value>
</data>
<data name="StorageProviderIosPHPickerDisplayName" xml:space="preserve">
<value>iOS PHPicker</value>
</data>
<data name="StorageProviderLocalDisplayName" xml:space="preserve">
<value>Tento počítač</value>
</data>
Expand All @@ -135,4 +138,4 @@
<data name="StorageProviderWasmNativeDisplayName" xml:space="preserve">
<value>JS File Access API</value>
</data>
</root>
</root>
3 changes: 3 additions & 0 deletions src/Uno.UI/Resources/Strings/en/Resources.resw
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@
<data name="StorageProviderIosSecurityScopedDisplayName" xml:space="preserve">
<value>iOS Security Scoped</value>
</data>
<data name="StorageProviderIosPHPickerDisplayName" xml:space="preserve">
<value>iOS PHPicker</value>
</data>
<data name="StorageProviderLocalDisplayName" xml:space="preserve">
<value>This PC</value>
</data>
Expand Down
2 changes: 2 additions & 0 deletions src/Uno.UWP/Storage/Internal/StorageProviders.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ internal static class StorageProviders

#if __IOS__
public static StorageProvider IosSecurityScoped { get; } = new StorageProvider("iossecurityscoped", "StorageProviderIosSecurityScopedDisplayName");

public static StorageProvider IosPHPicker { get; } = new("iosphpicker", "StorageProviderIosPHPickerDisplayName");
#endif
}
}
17 changes: 0 additions & 17 deletions src/Uno.UWP/Storage/Pickers/FileOpenPicker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,21 +100,4 @@ private void ValidateConfiguration()
}
#endif
}

public static class FileOpenPickerExtensions
{
/// <summary>
/// Sets the file limit a user can select when picking multiple files.
/// </summary>
/// <param name="limit">The maximum number of files that the user can pick.</param>
#if !__IOS__
[global::Uno.NotImplemented]
#endif
public static void SetMultipleFilesLimit(this FileOpenPicker picker, int limit)
{
#if __IOS__
picker.SetMultipleFileLimit(limit);
#endif
}
}
}
8 changes: 4 additions & 4 deletions src/Uno.UWP/Storage/Pickers/FileOpenPicker.iOS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ namespace Windows.Storage.Pickers
public partial class FileOpenPicker
{
private int _multipleFileLimit;
private bool _isReadOnly;

private Task<StorageFile?> PickSingleFileTaskAsync(CancellationToken token)
{
Expand Down Expand Up @@ -53,10 +54,9 @@ private Task<IReadOnlyList<StorageFile>> PickMultipleFilesTaskAsync(Cancellation
return tcs.Task;
}

internal void SetMultipleFileLimit(int limit)
{
_multipleFileLimit = limit;
}
internal void SetMultipleFileLimit(int limit) => _multipleFileLimit = limit;

internal void SetReadOnlyMode(bool readOnly) => _isReadOnly = readOnly;

private UIViewController GetViewController(bool multiple, int limit, TaskCompletionSource<StorageFile?[]> completionSource)
{
Expand Down
38 changes: 38 additions & 0 deletions src/Uno.UWP/Storage/Pickers/FileOpenPickerExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#nullable enable

namespace Windows.Storage.Pickers;

/// <summary>
/// Contains Uno Platform-specific extesions for the <see cref="FileOpenPicker"/> class.
/// </summary>
public static class FileOpenPickerExtensions
{
/// <summary>
/// Sets the file limit a user can select when picking multiple files.
/// </summary>
/// <param name="limit">The maximum number of files that the user can pick.</param>
#if !__IOS__
[global::Uno.NotImplemented]
#endif
public static void SetMultipleFilesLimit(this FileOpenPicker picker, int limit)
{
#if __IOS__
picker.SetMultipleFileLimit(limit);
#endif
}

/// <summary>
///
/// </summary>
/// <param name="picker"></param>
/// <param name="readOnly"></param>
#if !__IOS__
[global::Uno.NotImplemented]
#endif
public static void SetReadOnlyMode(this FileOpenPicker picker, bool readOnly)
{
#if __IOS__
picker.SetReadOnlyMode(readOnly);
#endif
}
}
61 changes: 61 additions & 0 deletions src/Uno.UWP/Storage/StorageFile.iOS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using System.Linq;
using MobileCoreServices;
using SystemPath = System.IO.Path;
using PhotosUI;

namespace Windows.Storage
{
Expand All @@ -21,6 +22,9 @@ public partial class StorageFile
internal static StorageFile GetFromSecurityScopedUrl(NSUrl nsUrl, StorageFolder? parent) =>
new StorageFile(new SecurityScopedFile(nsUrl, parent));

internal static StorageFile GetFromPHPickerResult(PHPickerResult result, StorageFolder? parent) =>
new StorageFile(new PHPickerResultFile(result, parent));

internal class SecurityScopedFile : ImplementationBase
{
private readonly NSUrl _nsUrl;
Expand Down Expand Up @@ -95,5 +99,62 @@ protected override bool IsEqual(ImplementationBase implementation) =>
implementation is SecurityScopedFile file &&
file._nsUrl.FilePathUrl?.Path == _nsUrl.FilePathUrl?.Path;
}

internal class PHPickerResultFile : ImplementationBase
{
private PHPickerResult _phPickerResult;
private StorageFolder? _parent;

public PHPickerResultFile(PHPickerResult phPickerResult, StorageFolder? parent) : base(string.Empty)
{
if (phPickerResult is null)
{
throw new ArgumentNullException(nameof(phPickerResult));
}

_phPickerResult = phPickerResult;
_parent = parent;
}

public override StorageProvider Provider => StorageProviders.IosPHPicker;

public override DateTimeOffset DateCreated
{
get
{
var itemProvider = _phPickerResult.ItemProvider;

if (itemProvider.HasItemConformingTo(UTType.Image))
{
var fileUrl = await GetFileUrlAsync(itemProvider);

if (fileUrl != null)
{
var attributes = NSFileManager.DefaultManager.GetAttributes(fileUrl.Path, out NSError error);
if (error != null)
{
throw new IOException($"Error retrieving file attributes: {error.LocalizedDescription}");
}

var creationDate = attributes.CreationDate;
return creationDate?.ToDateTimeOffset()
?? throw new InvalidOperationException("Creation date not found.");
}
}

throw new InvalidOperationException("Item does not conform to a supported type.");
}
}

public override Task DeleteAsync(CancellationToken ct, StorageDeleteOption options) => throw new NotImplementedException();
public override Task<BasicProperties> GetBasicPropertiesAsync(CancellationToken ct) => throw new NotImplementedException();
public override Task<StorageFolder?> GetParentAsync(CancellationToken ct) => throw new NotImplementedException();
public override Task<IRandomAccessStreamWithContentType> OpenAsync(CancellationToken ct, FileAccessMode accessMode, StorageOpenOptions options) => throw new NotImplementedException();
public override Task<StorageStreamTransaction> OpenTransactedWriteAsync(CancellationToken ct, StorageOpenOptions option) => throw new NotImplementedException();
protected override bool IsEqual(ImplementationBase implementation)
{
implementation is PHPickerResultFile file && file._phPickerResult.ItemProvider.Load
}
}
}
}

0 comments on commit 735ee53

Please sign in to comment.