-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
New file picker API #7234
Comments
What about:
|
Is IFilePickerFile.Stream supposed to be read only? And writeable at the same time only on supported platforms?
I suppose it's about older browsers including firefox, right? With newer FileAPI it's possible to open file and write to it without "downloading" it https://developer.mozilla.org/en-US/docs/Web/API/File_System_Access_API#writing_to_files |
I think a good design to start defining the API surface is Windows.Storage and Windows.Storage.Pickers. we can deifine like code this: // We may have various providers eg. AppleLocalStorage, DropBoxStorage, ..
public interface IStorageProvider
{
....
}
public interface IStorageItemMeta
{
string Name { get ;}
}
public interface IStorageItemWritableMeta
{
Task SaveAsync(IStorageItem item, CancellationToken token = default);
}
public interface IStoregeItemStringMeta : IStorageItemWritableMeta
{
string Value {get; set; }
}
public interface IStoregeItemDateTimeMeta : IStorageItemWritableMeta
{
DateTimeOffset Value {get; set; }
}
public interface IStoregeItemLongMeta : IStorageItemWritableMeta
{
long Value {get; set; }
}
public interface IContentTypeMeta : IStorageItemMeta
{
}
public interface IStorageItem
{
IStorageProvider Provider { get; }
// Gets the name of the item including the file name extension if there is one.
string Name {get; }
// Gets the full file-system path of the item, if the item has a path.
string? Path {get;}
// Indicates if the file is local, is cached locally, or can be downloaded.
bool IsAvailable {get;}
IReadOnlyList<IStorageItem> Owners {get;}
DateTimeOffset DateCreated { get;}
DateTimeOffset DateModified { get;}
Task<IReadOnlyList<IStoregeItemMeta>> GetMetaAsync(CancellationToken token = default);
bool TryGetMeta(string metaName, out IStoregeItemMeta? meta);
Task DeleteAsync(CancellationToken token = default);
Task RenamAsync(string desiredName, CancellationToken token = default);
}
public interface IFileStorage: IStorageItem
{
Task<Stream> OpenOrCreate(CancellationToken token = default);
bool CanRead {get; }
bool CanWrite {get; }
// Can be AppleUniformTypeIdentifiers , MimeTypes , Extension,
IContentTypeMeta ContentType { get; }
}
public interface IFolderStorage: IStorageItem
{
Task<IStorageItem> GetsItemsAsync (CancellationToken token = default);
Task<bool> TryAddItemAsync(IStorageItem item,CancellationToken token = default);
}
public interface IPickerOperation
{
srting Title {get;set;}
Environment.SpecialFolder SuggestedStartLocation {get;set;}
IIdentity User {get;set;}
}
public interface IFilePicker:IPickerOperation
{
string SuggestedFileName {get;set;}
}
public interface IFileOpenPicker:IFilePicker
{
IEnumerable<IContentTypeMeta> FilterBy {get;set;}
bool CheckExist {get;set;}
Task<IFileStorage?> PickSingleFileAsync(CancellationToken token = default);
Task<IRealOnlyList<IFileStorage>?> PickMultipleFileAsync(CancellationToken token = default);
}
public interface IFileSavePicker:IFilePicker
{
bool CanOverwrite {get;set;}
IReadOnlyList<IContentTypeMeta> FileTypeChoices {get;set;}
Task<IFileStorage?> PickSaveFileAsync(CancellationToken token = default);
}
public interface IFolderPicker:IPickerOperation
{
bool CanCreateNew {get;set;}
Task<IFolderStorage?> PickFolderAsync(CancellationToken token = default);
} |
@workgroupengineering I don't see how exactly does it map to macOS/iOS/Android sandboxes and WASM platform limitations. UWP sandbox is not relevant because it's essentially a dead platform anyway. Note that UWP API compatibility is a non-goal for us while properly mapping to various platform's APIs is. |
The mapping is done via IStorageProvider and IContentTypeMeta. IStorageProvider deals with the creation of the appropriate concrete types of IStorageItem with the respective metadata.
The fact that she is dead does not mean that we cannot learn from good things. It is not necessary to re-invent the wheel every time. Uno supports macOS/iOS/Android/WASM/Linux(GTK/Framebuffer) using UWP API design. Your design seems to me very connected to the macOS world. Having two models for file system access is confusing to the developer. If I make a desktop app I have to use Avalonia.Dialogs. *, If the app has to run in a sandbox I have to use IFilePicker. |
How would that work with
Uno has 3043 We don't want to somewhat implement UWP on top of iOS/macOS. We want to provide an API that meets the requirements of all target platforms and allows the developer to conform with the target platform guidelines. That's why use cases were listed in the initial message of this thread. We do care about supporting those use cases, we do not care about doing int in UWP way. Avalonia is cross-platform-first, neither UWP first nor WPF-first
That's exactly why I'm looking at iOS/macOS, since they've got their sandboxing API right.
Yes, that's because we want to be compatible and conformant to Apple ecosystem since macOS and iOS are our target platforms. We are not willing to ignore Apple guidelines for the sake of having an UWP-like API.
IFilePicker can and will be implemented on top of "full" file dialogs on platforms that do support them. For example on Linux the "bookmark" would simply be a file path. So if one wants their app sandbox/mobile/wasm compatible, they'll use the new file picker that we are trying to design to be sandbox/mobile/wasm-compatible. |
it is responsibility of I*Picker using appropriate IStorageProvider after download.
Uno's repository is a bit complicated, you can't find an answer with a simple search. A lot of code is generated in the compile phase of the source code generators.
You have probably misunderstood my intent, I don't want to force the use of the UWP API, but I want to find together a solution that satisfies as many needs as possible. The UWP API seems like a good place to start. As you say Avalonia and cross platform cannot be guided only by Apple's guidelines but must take the best of all supported platforms. |
According to your link Uno forces you to write to a temporary buffer before actually asking the user to save the file:
Which makes it not possible to do advanced scenarios like streaming content that doesn't fit into the limited RAM allocated for wasm apps. That is why I've introduced The way we are implementing cross-platform features is to first study the way the underlying platforms work, then try to figure out the API set to fit them all, then compare that to what Qt (the only cross-platform UI toolkit I've seen that gets things right) does if the have that feature and only then look at UWP to check if we can follow the least surprise principle and provide something similar. |
I think that provided solution by @kekekeks is good and do what it needs to do. We can holywar a lot about api. Maybe some minor tweaks can be made, but I think that we need focus more on a feature implementation more than a perfect useful api. I think there will be some minor tweaks in the process of implementation... But overall, again, I think all looks good. |
Very interesting I did not know that QT also worked on Android and iOS. I see here the desing of FileDialog and it is very similar to that of Avalonia.Dialogs. In place of a path returns a uri. I think it is useful when I select a file in addition to the uri / path to already return information such as the ContentType, the creation, ecc.. date without necessarily opening the stream to retrieve it. In the case of Wasm, instead of downloading the file, only download the metadata. in any case I would implement an IStorageProvider that would allow the IFilePicker to interface directly to the cloud (drive, dropbox, onedrive). I take this opportunity to wish you a Merry Christmas |
Our current file dialogs are desktop-centric and assume that the app has direct access to the file system, which is not the case for sandboxed environments.
While keeping the current API for desktop platforms, we need to design a new one that would work well with WebAssembly, macOS App Store apps, iOS and Android (possibly with UWP too, but I'm not sure how relevant it is since we don't support XBox and HoloLens anyway).
Main differences of the API would be:
Stream
s instead of file pathscom.adobe.pdf
,org.idpf.epub-container
,public.mp3
Content-Disposition
header. In case of iOS that would be the Share functionThe text was updated successfully, but these errors were encountered: