Browse Source

Pass file extensions to the browser backend in the file picker

pull/10343/head
Max Katz 4 years ago
parent
commit
d1c329e819
  1. 8
      samples/ControlCatalog/Pages/DialogsPage.xaml.cs
  2. 16
      src/Avalonia.Base/Platform/Storage/FilePickerFileType.cs
  3. 2
      src/Browser/Avalonia.Browser/Interop/StorageHelper.cs
  4. 2
      src/Browser/Avalonia.Browser/Storage/BrowserStorageProvider.cs
  5. 4
      src/Browser/Avalonia.Browser/webapp/modules/storage/storageProvider.ts
  6. 4
      src/iOS/Avalonia.iOS/Storage/IOSStorageProvider.cs

8
samples/ControlCatalog/Pages/DialogsPage.xaml.cs

@ -82,7 +82,13 @@ namespace ControlCatalog.Pages
return new List<FilePickerFileType>
{
FilePickerFileTypes.All,
FilePickerFileTypes.TextPlain
FilePickerFileTypes.TextPlain,
new("Binary Log")
{
Patterns = new[] { "*.binlog", "*.buildlog" },
MimeTypes = new[] { "application/binlog", "application/buildlog" },
AppleUniformTypeIdentifiers = new []{ "public.data" }
}
};
}

16
src/Avalonia.Base/Platform/Storage/FilePickerFileType.cs

@ -1,4 +1,6 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace Avalonia.Platform.Storage;
@ -21,7 +23,7 @@ public sealed class FilePickerFileType
/// List of extensions in GLOB format. I.e. "*.png" or "*.*".
/// </summary>
/// <remarks>
/// Used on Windows and Linux systems.
/// Used on Windows, Linux and Browser platforms.
/// </remarks>
public IReadOnlyList<string>? Patterns { get; set; }
@ -29,7 +31,7 @@ public sealed class FilePickerFileType
/// List of extensions in MIME format.
/// </summary>
/// <remarks>
/// Used on Android, Browser and Linux systems.
/// Used on Android, Linux and Browser platforms.
/// </remarks>
public IReadOnlyList<string>? MimeTypes { get; set; }
@ -41,4 +43,14 @@ public sealed class FilePickerFileType
/// See https://developer.apple.com/documentation/uniformtypeidentifiers/system_declared_uniform_type_identifiers.
/// </remarks>
public IReadOnlyList<string>? AppleUniformTypeIdentifiers { get; set; }
internal IReadOnlyList<string>? TryGetExtensions()
{
// Converts random glob pattern to a simple extension name.
// GetExtension should be sufficient here.
// Only exception is "*.*proj" patterns that should be filtered as well.
return Patterns?.Select(Path.GetExtension)
.Where(e => !string.IsNullOrEmpty(e) && !e.Contains('*') && e.StartsWith("."))
.ToArray()!;
}
}

2
src/Browser/Avalonia.Browser/Interop/StorageHelper.cs

@ -54,5 +54,5 @@ internal static partial class StorageHelper
public static partial JSObject[] ItemsArray(JSObject item);
[JSImport("StorageProvider.createAcceptType", AvaloniaModule.StorageModuleName)]
public static partial JSObject CreateAcceptType(string description, string[] mimeTypes);
public static partial JSObject CreateAcceptType(string description, string[] mimeTypes, string[]? extensions);
}

2
src/Browser/Avalonia.Browser/Storage/BrowserStorageProvider.cs

@ -147,7 +147,7 @@ internal class BrowserStorageProvider : IStorageProvider
{
var types = input?
.Where(t => t.MimeTypes?.Any() == true && t != FilePickerFileTypes.All)
.Select(t => StorageHelper.CreateAcceptType(t.Name, t.MimeTypes!.ToArray()))
.Select(t => StorageHelper.CreateAcceptType(t.Name, t.MimeTypes!.ToArray(), t.TryGetExtensions()?.ToArray()))
.ToArray();
if (types?.Length == 0)
{

4
src/Browser/Avalonia.Browser/webapp/modules/storage/storageProvider.ts

@ -62,9 +62,9 @@ export class StorageProvider {
}
}
public static createAcceptType(description: string, mimeTypes: string[]): FilePickerAcceptType {
public static createAcceptType(description: string, mimeTypes: string[], extensions: string[] | undefined): FilePickerAcceptType {
const accept: Record<string, string[]> = {};
mimeTypes.forEach(a => { accept[a] = []; });
mimeTypes.forEach(a => { accept[a] = extensions ?? []; });
return { description, accept };
}
}

4
src/iOS/Avalonia.iOS/Storage/IOSStorageProvider.cs

@ -43,6 +43,10 @@ internal class IOSStorageProvider : IStorageProvider
{
return f.AppleUniformTypeIdentifiers.Select(id => UTType.CreateFromIdentifier(id));
}
if (f.TryGetExtensions() is { } extensions && extensions.Any())
{
return extensions.Select(id => UTType.CreateFromExtension(id.TrimStart('.')));
}
if (f.MimeTypes?.Any() == true)
{
return f.MimeTypes.Select(id => UTType.CreateFromMimeType(id));

Loading…
Cancel
Save