UNPKG

@nativescript/imagepicker

Version:

A plugin for the NativeScript framework implementing multiple image picker

253 lines 15.1 kB
import { ImageAsset, Utils, Application, path, knownFolders, ImageSource } from '@nativescript/core'; import { ImagePickerBase } from './common'; import { getFile } from '@nativescript/core/http'; import * as permissions from '@nativescript-community/perms'; export * from './common'; const defaultAssetCollectionSubtypes = NSArray.arrayWithArray([206 /* PHAssetCollectionSubtype.SmartAlbumRecentlyAdded */, 209 /* PHAssetCollectionSubtype.SmartAlbumUserLibrary */, 100 /* PHAssetCollectionSubtype.AlbumMyPhotoStream */, 203 /* PHAssetCollectionSubtype.SmartAlbumFavorites */, 201 /* PHAssetCollectionSubtype.SmartAlbumPanoramas */, 207 /* PHAssetCollectionSubtype.SmartAlbumBursts */, 101 /* PHAssetCollectionSubtype.AlbumCloudShared */, 210 /* PHAssetCollectionSubtype.SmartAlbumSelfPortraits */, 211 /* PHAssetCollectionSubtype.SmartAlbumScreenshots */, 213 /* PHAssetCollectionSubtype.SmartAlbumLivePhotos */]); let copyToAppFolder; let renameFileTo; let augmentedAssetsInfo; let resolveWhenDismissed; let fileMap = {}; export class ImagePicker extends ImagePickerBase { // lazy-load latest frame.topmost() if _hostName is not used get hostView() { return this._hostView; } get hostController() { let vc = Application.ios.rootController; while (vc && vc.presentedViewController) { vc = vc.presentedViewController; } return vc; } constructor(options = {}, hostView) { super(); this._hostView = hostView; const imagePickerController = QBImagePickerController.alloc().init(); imagePickerController.assetCollectionSubtypes = defaultAssetCollectionSubtypes; imagePickerController.mediaType = options.mediaType ? options.mediaType.valueOf() : 0 /* QBImagePickerMediaType.Any */; imagePickerController.allowsMultipleSelection = options.mode !== 'single'; imagePickerController.minimumNumberOfSelection = options.minimumNumberOfSelection || 0; imagePickerController.maximumNumberOfSelection = options.maximumNumberOfSelection || 0; imagePickerController.showsNumberOfSelectedAssets = options.showsNumberOfSelectedAssets || true; imagePickerController.numberOfColumnsInPortrait = options.numberOfColumnsInPortrait || imagePickerController.numberOfColumnsInPortrait; imagePickerController.numberOfColumnsInLandscape = options.numberOfColumnsInLandscape || imagePickerController.numberOfColumnsInLandscape; imagePickerController.prompt = options.prompt || imagePickerController.prompt; copyToAppFolder = options.copyToAppFolder || false; renameFileTo = options.renameFileTo || false; augmentedAssetsInfo = options.augmentedAssetsInfo ?? true; resolveWhenDismissed = options.resolveWhenDismissed ?? false; this._imagePickerController = imagePickerController; } authorize() { console.log('authorizing...'); return permissions.request('photo').then((result) => this.mapResult(result)); } present() { fileMap = {}; return new Promise((resolve, reject) => { this._delegate = ImagePickerControllerDelegate.initWithOwner(this, resolve, reject); this._imagePickerController.delegate = this._delegate; this.hostController.presentViewControllerAnimatedCompletion(this._imagePickerController, true, null); }); } _cleanup() { this._imagePickerController = null; this._delegate = null; } } var ImagePickerControllerDelegate = /** @class */ (function (_super) { __extends(ImagePickerControllerDelegate, _super); function ImagePickerControllerDelegate() { return _super !== null && _super.apply(this, arguments) || this; } ImagePickerControllerDelegate.prototype.qb_imagePickerControllerDidCancel = function (imagePickerController) { var _this = this; imagePickerController.dismissViewControllerAnimatedCompletion(true, function () { if (_this._reject) { _this._reject(new Error('Canceled')); } if (imagePicker) { imagePicker._cleanup(); } imagePicker = null; }); }; ImagePickerControllerDelegate.prototype.qb_imagePickerControllerDidFinishPickingAssets = function (imagePickerController, iosAssets) { return __awaiter(this, void 0, void 0, function () { var _loop_1, i, wasDismissed, closePromise, resolvedFunction, promises, count, _loop_2, key; var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: _loop_1 = function (i) { var asset, phAssetImage, existingFileName, pickerSelection, manager_1, options_1, imageOptions_1; return __generator(this, function (_b) { switch (_b.label) { case 0: asset = new ImageAsset(iosAssets.objectAtIndex(i)); phAssetImage = asset._ios; // this fixes the image aspect ratio in tns-core-modules version < 4.0 if (!asset.options) asset.options = { keepAspectRatio: true }; existingFileName = phAssetImage.valueForKey('filename'); pickerSelection = { asset: asset, type: phAssetImage.mediaType == 2 ? 'video' : 'image', filename: existingFileName, originalFilename: existingFileName, filesize: 0, path: '', }; if (pickerSelection.type == 'video') pickerSelection.duration = parseInt(phAssetImage.duration.toFixed(0)); fileMap[existingFileName] = pickerSelection; if (!(pickerSelection.type == 'video')) return [3 /*break*/, 2]; manager_1 = new PHImageManager(); options_1 = new PHVideoRequestOptions(); options_1.networkAccessAllowed = true; return [4 /*yield*/, new Promise(function (resolve) { manager_1.requestAVAssetForVideoOptionsResultHandler(phAssetImage, options_1, function (urlAsset, audioMix, info) { fileMap[existingFileName].path = urlAsset.URL.toString().replace('file://', ''); resolve(); }); })]; case 1: _b.sent(); return [3 /*break*/, 4]; case 2: imageOptions_1 = new PHContentEditingInputRequestOptions(); imageOptions_1.networkAccessAllowed = true; return [4 /*yield*/, new Promise(function (resolve) { phAssetImage.requestContentEditingInputWithOptionsCompletionHandler(imageOptions_1, function (thing) { fileMap[existingFileName].path = thing.fullSizeImageURL.toString().replace('file://', ''); resolve(); }); })]; case 3: _b.sent(); _b.label = 4; case 4: return [2 /*return*/]; } }); }; i = 0; _a.label = 1; case 1: if (!(i < iosAssets.count)) return [3 /*break*/, 4]; return [5 /*yield**/, _loop_1(i)]; case 2: _a.sent(); _a.label = 3; case 3: i++; return [3 /*break*/, 1]; case 4: wasDismissed = false; closePromise = new Promise(function (resolve) { imagePickerController.dismissViewControllerAnimatedCompletion(true, function () { wasDismissed = true; resolve(); if (imagePicker) { imagePicker._cleanup(); } imagePicker = null; // FIX: possible memory issue when picking images many times. // Not the best solution, but the only one working for now // https://github.com/NativeScript/nativescript-imagepicker/issues/222 setTimeout(Utils.GC, 200); }); }); resolvedFunction = this._resolve; if (!resolvedFunction) return [3 /*break*/, 8]; if (!(!copyToAppFolder && augmentedAssetsInfo === false)) return [3 /*break*/, 7]; if (!(resolveWhenDismissed && !wasDismissed)) return [3 /*break*/, 6]; return [4 /*yield*/, closePromise]; case 5: _a.sent(); _a.label = 6; case 6: return [2 /*return*/, resolvedFunction === null || resolvedFunction === void 0 ? void 0 : resolvedFunction(Object.values(fileMap))]; case 7: promises = []; count = 0; _loop_2 = function (key) { var item = fileMap[key]; var folder = knownFolders.documents(); var extension = item.filename.split('.').pop(); var filename = renameFileTo ? renameFileTo + '.' + extension : item.filename; if (iosAssets.count > 1) filename = renameFileTo ? renameFileTo + '-' + count + '.' + extension : item.filename; fileMap[item.filename].filename = filename; var fileManager = new NSFileManager(); if (copyToAppFolder) { var filePath_1 = path.join(folder.path + '/' + copyToAppFolder, filename); promises.push(getFile('file://' + item.path, filePath_1) .then(function (result) { fileMap[item.originalFilename].path = filePath_1; fileMap[item.originalFilename].filesize = fileManager.attributesOfItemAtPathError(filePath_1).fileSize(); if (item.type == 'video') { return ImageSource.fromAsset(item.asset).then(function (source) { fileMap[item.originalFilename].thumbnail = source; }); } }) .catch(function (error) { console.log('Error copying file: ', error); })); } else { fileMap[item.originalFilename].filesize = fileManager.attributesOfItemAtPathError(fileMap[item.filename].path).fileSize(); if (item.type == 'video') { promises.push(ImageSource.fromAsset(item.asset).then(function (source) { fileMap[item.originalFilename].thumbnail = source; })); } } count++; }; for (key in fileMap) { _loop_2(key); } Promise.all(promises).then(function () { return __awaiter(_this, void 0, void 0, function () { var results, key; return __generator(this, function (_a) { switch (_a.label) { case 0: results = []; for (key in fileMap) { results.push(fileMap[key]); } if (!(resolveWhenDismissed && !wasDismissed)) return [3 /*break*/, 2]; return [4 /*yield*/, closePromise]; case 1: _a.sent(); _a.label = 2; case 2: resolvedFunction === null || resolvedFunction === void 0 ? void 0 : resolvedFunction(results); return [2 /*return*/]; } }); }); }); _a.label = 8; case 8: return [2 /*return*/]; } }); }); }; ImagePickerControllerDelegate.initWithOwner = function (owner, resolve, reject) { var delegate = new ImagePickerControllerDelegate(); delegate.owner = new WeakRef(owner); delegate._resolve = resolve; delegate._reject = reject; return delegate; }; ImagePickerControllerDelegate.ObjCProtocols = [QBImagePickerControllerDelegate]; return ImagePickerControllerDelegate; }(NSObject)); let imagePicker; export function create(options, hostView) { imagePicker = new ImagePicker(options, hostView); return imagePicker; } //# sourceMappingURL=index.ios.js.map