document-picker/windows/RNDocumentPicker/RCTDocumentPickerModule.cs
Genc, Alper Numan 2d27f77718 Change request applied:
* Removed mime type - extensions transform
* index.js refactoring applied
2017-10-23 08:30:11 +03:00

189 lines
6.1 KiB
C#

using Newtonsoft.Json.Linq;
using ReactNative.Bridge;
using System;
using Newtonsoft.Json.Linq;
using ReactNative.Bridge;
using ReactNative.Collections;
using System.Linq;
using System.Collections.Generic;
using Windows.ApplicationModel.Core;
using Windows.UI.Core;
using Windows.UI.Popups;
using Windows.Storage;
using Windows.Storage.Pickers;
using ZXing;
using static System.FormattableString;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace RNDocumentPicker
{
class RCTDocumentPickerModule : ReactContextNativeModuleBase, ILifecycleEventListener
{
private FileOpenPicker _pendingPicker;
private bool _isInForeground;
private static readonly String E_FAILED_TO_SHOW_PICKER = "FAILED_TO_SHOW_PICKER";
private static readonly String E_DOCUMENT_PICKER_CANCELED = "DOCUMENT_PICKER_CANCELED";
private static readonly String E_UNEXPECTED_EXCEPTION = "UNEXPECTED_EXCEPTION";
private static readonly String OPTION_TYPE = "type";
private static readonly String OPTION_MULIPLE = "multiple";
private static readonly String FIELD_URI = "uri";
private static readonly String FIELD_NAME = "name";
private static readonly String FIELD_TYPE = "type";
private static readonly String FIELD_SIZE = "size";
public RCTDocumentPickerModule(ReactContext reactContext)
: base(reactContext)
{
}
public override string Name
{
get
{
return "RNDocumentPicker";
}
}
public override void Initialize()
{
Context.AddLifecycleEventListener(this);
}
public void OnSuspend()
{
_isInForeground = false;
}
public void OnResume()
{
_isInForeground = true;
}
public void OnDestroy()
{
}
[ReactMethod]
public void pick(JObject options, IPromise promise)
{
try
{
FileOpenPicker openPicker = new FileOpenPicker();
openPicker.ViewMode = PickerViewMode.Thumbnail;
openPicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
// Get file type array options
var fileTypeArray = options.Value<JArray>(OPTION_TYPE);
// Init file type filter
if (fileTypeArray != null && fileTypeArray.Count > 0)
{
foreach (String typeString in fileTypeArray)
{
List<String> types = typeString.Split(' ').ToList();
foreach (String type in types)
{
if (Regex.Match(type, "(^[.]+[A-Za-z0-9]*$)|(^[*]$)").Success)
{
openPicker.FileTypeFilter.Add(type);
}
}
}
}
else
{
openPicker.FileTypeFilter.Add("*");
}
RunOnDispatcher(async () =>
{
try
{
if (_isInForeground)
{
var isMultiple = options.Value<bool>(OPTION_MULIPLE);
if (isMultiple)
{
await PickMultipleFileAsync(openPicker, promise);
}
else
{
await PickSingleFileAsync(openPicker, promise);
}
}
else
{
_pendingPicker = openPicker;
}
}
catch (Exception ex)
{
promise.Reject(E_FAILED_TO_SHOW_PICKER, ex.Message);
}
});
}
catch (Exception ex) {
promise.Reject(E_UNEXPECTED_EXCEPTION, ex.Message);
}
}
private async Task<JObject> PrepareFile(StorageFile file)
{
var basicProperties = await file.GetBasicPropertiesAsync();
return new JObject {
{ FIELD_URI, file.Path },
{ FIELD_TYPE, file.ContentType },
{ FIELD_NAME, file.Name },
{ FIELD_SIZE, basicProperties.Size}
};
}
private async Task<bool> PickMultipleFileAsync(FileOpenPicker picker, IPromise promise) {
IReadOnlyList<StorageFile> files = await picker.PickMultipleFilesAsync().AsTask().ConfigureAwait(false);
if (files.Count > 0)
{
JArray jarrayObj = new JArray();
foreach (var file in files) {
jarrayObj.Add(PrepareFile(file).Result);
}
promise.Resolve(jarrayObj);
}
else
{
promise.Reject(E_DOCUMENT_PICKER_CANCELED, "User canceled document picker");
}
return true;
}
private async Task<bool> PickSingleFileAsync(FileOpenPicker picker, IPromise promise) {
var file = await picker.PickSingleFileAsync().AsTask().ConfigureAwait(false);
if (file != null)
{
JArray jarrayObj = new JArray();
jarrayObj.Add(PrepareFile(file).Result);
promise.Resolve(jarrayObj);
}
else
{
promise.Reject(E_DOCUMENT_PICKER_CANCELED, "User canceled document picker");
}
return true;
}
private void OnInvoked(Object error, Object success, ICallback callback)
{
callback.Invoke(error, success);
}
private static async void RunOnDispatcher(DispatchedHandler action)
{
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, action).AsTask().ConfigureAwait(false);
}
}
}