@nativescript/imagepicker
Version:
A plugin for the NativeScript framework implementing multiple image picker
253 lines • 15.1 kB
JavaScript
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