Skip to content

Commit 45b5495

Browse files
authored
[Windows] Implementing Folder Picker support (#380)
* Adding Folder Picker support Adding windows folder picker support into react-native-document-picker * Update index.js Removed commented code. * Update index.js Formatting the string returned.
1 parent 493f9ff commit 45b5495

File tree

3 files changed

+95
-16
lines changed

3 files changed

+95
-16
lines changed

index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ declare module 'react-native-document-picker' {
5757
xls: '.xls';
5858
xlsx: '.xlsx';
5959
zip: '.zip .gz';
60+
folder: 'folder';
6061
};
6162
};
6263
type PlatformTypes = {

index.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@ function pick(opts) {
6262
);
6363
}
6464

65+
if (Array.isArray(opts.type) && opts.type.length > 1) {
66+
if (opts.type.includes('folder')) {
67+
throw new TypeError('When type array is folder then other options are not supported');
68+
}
69+
}
70+
6571
if ('mode' in opts && !['import', 'open'].includes(opts.mode)) {
6672
throw new TypeError('Invalid mode option: ' + opts.mode);
6773
}
@@ -140,6 +146,7 @@ const Types = {
140146
xls: '.xls',
141147
xlsx: '.xlsx',
142148
zip: '.zip .gz',
149+
folder: 'folder',
143150
},
144151
};
145152

windows/RNDocumentPicker/RCTDocumentPickerModule.cs

Lines changed: 87 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ class RCTDocumentPickerModule : ReactContextNativeModuleBase, ILifecycleEventLis
2020

2121
private static readonly String E_FAILED_TO_SHOW_PICKER = "FAILED_TO_SHOW_PICKER";
2222
private static readonly String E_DOCUMENT_PICKER_CANCELED = "DOCUMENT_PICKER_CANCELED";
23-
private static readonly String E_UNEXPECTED_EXCEPTION = "UNEXPECTED_EXCEPTION";
23+
private static readonly String E_FOLDER_PICKER_CANCELED = "FOLDER_PICKER_CANCELED";
24+
25+
private static readonly String E_UNEXPECTED_EXCEPTION = "UNEXPECTED_EXCEPTION";
2426

2527
private static readonly String OPTION_TYPE = "type";
2628
private static readonly String CACHE_TYPE = "cache";
@@ -76,11 +78,20 @@ public void pick(JObject options, IPromise promise)
7678
// Get file type array options
7779
var fileTypeArray = options.Value<JArray>(OPTION_TYPE);
7880
var cache = options.Value<Boolean>(CACHE_TYPE);
81+
82+
//if pick called to launch folder picker.
83+
bool isFolderPicker = false;
84+
7985
// Init file type filter
8086
if (fileTypeArray != null && fileTypeArray.Count > 0)
8187
{
8288
foreach (String typeString in fileTypeArray)
8389
{
90+
if(typeString == "folder"){
91+
isFolderPicker = true;
92+
break;
93+
}
94+
8495
List<String> types = typeString.Split(' ').ToList();
8596
foreach (String type in types)
8697
{
@@ -96,33 +107,63 @@ public void pick(JObject options, IPromise promise)
96107
openPicker.FileTypeFilter.Add("*");
97108
}
98109

99-
RunOnDispatcher(async () =>
110+
if(isFolderPicker)
100111
{
101-
try
112+
var openFolderPicker = new FolderPicker();
113+
114+
RunOnDispatcher(async () =>
102115
{
103-
if (_isInForeground)
116+
try
104117
{
105-
var isMultiple = options.Value<bool>(OPTION_MULIPLE);
106-
var readContent = options.Value<bool>(OPTION_READ_CONTENT);
107-
if (isMultiple)
118+
if (_isInForeground)
108119
{
109-
await PickMultipleFileAsync(openPicker, cache, readContent, promise);
120+
openFolderPicker.ViewMode = PickerViewMode.List;
121+
openFolderPicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
122+
openFolderPicker.FileTypeFilter.Add("*");
123+
124+
await PickFolderAsync(openFolderPicker, promise);
110125
}
111126
else
112127
{
113-
await PickSingleFileAsync(openPicker, cache, readContent, promise);
128+
_pendingPicker = openPicker;
114129
}
115130
}
116-
else
131+
catch (Exception ex)
117132
{
118-
_pendingPicker = openPicker;
133+
promise.Reject(E_FAILED_TO_SHOW_PICKER, ex.Message);
119134
}
120-
}
121-
catch (Exception ex)
135+
});
136+
}
137+
else
138+
{
139+
RunOnDispatcher(async () =>
122140
{
123-
promise.Reject(E_FAILED_TO_SHOW_PICKER, ex.Message);
124-
}
125-
});
141+
try
142+
{
143+
if (_isInForeground)
144+
{
145+
var isMultiple = options.Value<bool>(OPTION_MULIPLE);
146+
var readContent = options.Value<bool>(OPTION_READ_CONTENT);
147+
if (isMultiple)
148+
{
149+
await PickMultipleFileAsync(openPicker, cache, readContent, promise);
150+
}
151+
else
152+
{
153+
await PickSingleFileAsync(openPicker, cache, readContent, promise);
154+
}
155+
}
156+
else
157+
{
158+
_pendingPicker = openPicker;
159+
}
160+
}
161+
catch (Exception ex)
162+
{
163+
promise.Reject(E_FAILED_TO_SHOW_PICKER, ex.Message);
164+
}
165+
});
166+
}
126167
}
127168
catch (Exception ex) {
128169
promise.Reject(E_UNEXPECTED_EXCEPTION, ex.Message);
@@ -208,6 +249,36 @@ private async Task<bool> PickSingleFileAsync(FileOpenPicker picker, Boolean cach
208249
return true;
209250
}
210251

252+
private async Task<JObject> PrepareFolder(StorageFolder folder)
253+
{
254+
String base64Content = null;
255+
var basicProperties = await folder.GetBasicPropertiesAsync();
256+
257+
return new JObject {
258+
{ FIELD_URI, folder.Path },
259+
{ FIELD_FILE_COPY_URI, folder.Path },
260+
{ FIELD_NAME, folder.Name },
261+
{ FIELD_SIZE, basicProperties.Size},
262+
{ FIELD_CONTENT, base64Content }
263+
};
264+
}
265+
266+
private async Task<bool> PickFolderAsync(FolderPicker picker, IPromise promise)
267+
{
268+
var folder = await picker.PickSingleFolderAsync().AsTask().ConfigureAwait(false);
269+
if (folder != null)
270+
{
271+
JArray jarrayObj = new JArray();
272+
jarrayObj.Add(PrepareFolder(folder).Result);
273+
promise.Resolve(jarrayObj);
274+
}
275+
else
276+
{
277+
promise.Reject(E_FOLDER_PICKER_CANCELED, "User canceled document picker");
278+
}
279+
280+
return true;
281+
}
211282
private void OnInvoked(Object error, Object success, ICallback callback)
212283
{
213284
callback.Invoke(error, success);

0 commit comments

Comments
 (0)