16
16
#include < winrt/Windows.Web.Http.Headers.h>
17
17
#include < winrt/Windows.ApplicationModel.h>
18
18
#include < winrt/Windows.Foundation.h>
19
+ #include < winrt/Windows.Storage.Pickers.h>
20
+ #include < winrt/Windows.Storage.AccessCache.h>
19
21
20
22
#include " RNFSException.h"
21
23
@@ -24,6 +26,7 @@ using namespace winrt::ReactNativeFs;
24
26
using namespace winrt ::Windows::ApplicationModel;
25
27
using namespace winrt ::Windows::Storage;
26
28
using namespace winrt ::Windows::Storage::Streams;
29
+ using namespace winrt ::Windows::Storage::Pickers;
27
30
using namespace winrt ::Windows::Foundation;
28
31
using namespace winrt ::Windows::Web::Http;
29
32
@@ -1127,6 +1130,164 @@ IAsyncAction ReactNativeModule::ProcessUploadRequestAsync(ReactPromise<JSValueOb
1127
1130
}
1128
1131
}
1129
1132
1133
+ void ReactNativeModule::pickFile (JSValueObject options, ReactPromise<JSValueArray> promise) noexcept
1134
+ {
1135
+ m_reactContext.UIDispatcher ().Post ([this , options = std::move (options), promise = std::move (promise)]() mutable {
1136
+ try
1137
+ {
1138
+ // read options
1139
+ std::string pickerType = " multipleFiles" ; // Default value
1140
+ if (options.find (" pickerType" ) != options.end ())
1141
+ {
1142
+ pickerType = options[" pickerType" ].AsString ();
1143
+ }
1144
+
1145
+ std::vector<std::wstring> fileTypes;
1146
+ if (options.find (" fileExtensions" ) != options.end ())
1147
+ {
1148
+ for (const auto & mimeType : options[" fileExtensions" ].AsArray ())
1149
+ {
1150
+ fileTypes.push_back (std::wstring (winrt::to_hstring (mimeType.AsString ())));
1151
+ }
1152
+ }
1153
+
1154
+ // folder picker
1155
+ if (pickerType == " folder" )
1156
+ {
1157
+ FolderPicker picker;
1158
+ picker.SuggestedStartLocation (PickerLocationId::DocumentsLibrary);
1159
+ picker.FileTypeFilter ().Append (L" *" );
1160
+
1161
+ picker.PickSingleFolderAsync ().Completed ([promise = std::move (promise)](IAsyncOperation<StorageFolder> const & operation, AsyncStatus const status) mutable {
1162
+ try
1163
+ {
1164
+ if (status == AsyncStatus::Completed)
1165
+ {
1166
+ StorageFolder folder = operation.GetResults ();
1167
+ if (folder)
1168
+ {
1169
+ JSValueArray result;
1170
+ result.push_back (JSValueObject{
1171
+ {" name" , winrt::to_string (folder.Name ())},
1172
+ {" path" , winrt::to_string (folder.Path ())}
1173
+ });
1174
+ promise.Resolve (std::move (result));
1175
+ }
1176
+ else
1177
+ {
1178
+ promise.Reject (" No folder was picked." );
1179
+ }
1180
+ }
1181
+ else
1182
+ {
1183
+ promise.Reject (" Folder picker operation was not completed." );
1184
+ }
1185
+ }
1186
+ catch (const hresult_error& ex)
1187
+ {
1188
+ promise.Reject (winrt::to_string (ex.message ()).c_str ());
1189
+ }
1190
+ });
1191
+ }
1192
+
1193
+ // file picker
1194
+ else
1195
+ {
1196
+ FileOpenPicker picker;
1197
+ picker.ViewMode (PickerViewMode::Thumbnail);
1198
+ picker.SuggestedStartLocation (PickerLocationId::DocumentsLibrary);
1199
+
1200
+ if (!fileTypes.empty ())
1201
+ {
1202
+ for (const auto & fileType : fileTypes)
1203
+ {
1204
+ picker.FileTypeFilter ().Append (fileType);
1205
+ }
1206
+ }
1207
+ else
1208
+ {
1209
+ picker.FileTypeFilter ().Append (L" *" );
1210
+ }
1211
+
1212
+ // single files
1213
+ if (pickerType == " singleFile" )
1214
+ {
1215
+ picker.PickSingleFileAsync ().Completed ([promise = std::move (promise)](IAsyncOperation<StorageFile> const & operation, AsyncStatus const status) mutable {
1216
+ try
1217
+ {
1218
+ if (status == AsyncStatus::Completed)
1219
+ {
1220
+ StorageFile file = operation.GetResults ();
1221
+ if (file)
1222
+ {
1223
+ JSValueArray result;
1224
+ result.push_back (winrt::to_string (file.Path ()));
1225
+ promise.Resolve (std::move (result));
1226
+ }
1227
+ else
1228
+ {
1229
+ promise.Reject (" No file was picked." );
1230
+ }
1231
+ }
1232
+ else
1233
+ {
1234
+ promise.Reject (" File picker operation was not completed." );
1235
+ }
1236
+ }
1237
+ catch (const hresult_error& ex)
1238
+ {
1239
+ promise.Reject (winrt::to_string (ex.message ()).c_str ());
1240
+ }
1241
+ });
1242
+ }
1243
+
1244
+ // multiple files
1245
+ else if (pickerType == " multipleFiles" )
1246
+ {
1247
+ picker.PickMultipleFilesAsync ().Completed ([promise = std::move (promise)](IAsyncOperation<IVectorView<StorageFile>> const & operation, AsyncStatus const status) mutable {
1248
+ try
1249
+ {
1250
+ if (status == AsyncStatus::Completed)
1251
+ {
1252
+ auto files = operation.GetResults ();
1253
+ if (files.Size () > 0 )
1254
+ {
1255
+ JSValueArray result;
1256
+ for (const auto & file : files)
1257
+ {
1258
+ result.push_back (winrt::to_string (file.Path ()));
1259
+ }
1260
+ promise.Resolve (std::move (result));
1261
+ }
1262
+ else
1263
+ {
1264
+ promise.Reject (" No files were picked." );
1265
+ }
1266
+ }
1267
+ else
1268
+ {
1269
+ promise.Reject (" File picker operation was not completed." );
1270
+ }
1271
+ }
1272
+ catch (const hresult_error& ex)
1273
+ {
1274
+ promise.Reject (winrt::to_string (ex.message ()).c_str ());
1275
+ }
1276
+ });
1277
+ }
1278
+ else
1279
+ {
1280
+ promise.Reject (" Invalid pickerType option." );
1281
+ }
1282
+ }
1283
+ }
1284
+ catch (const hresult_error& ex)
1285
+ {
1286
+ promise.Reject (winrt::to_string (ex.message ()).c_str ());
1287
+ }
1288
+ });
1289
+ }
1290
+
1130
1291
void ReactNativeModule::addListener (std::string eventName) noexcept
1131
1292
{
1132
1293
// Keep: Required for RN built in Event Emitter Calls.
0 commit comments