Skip to content

feat: scoped camera #246

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,5 @@ demo*/report/stats.json
!demo-vue/app/app.js
test-results.xml
mochawesome-report/
/**/e2e/reports/
/**/e2e/reports/
package-lock.json
57 changes: 23 additions & 34 deletions src/camera.android.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
import * as typesModule from "tns-core-modules/utils/types";
import * as utilsModule from "tns-core-modules/utils/utils";
import * as applicationModule from "tns-core-modules/application/application";
import * as imageAssetModule from "tns-core-modules/image-asset/image-asset";
import * as trace from "tns-core-modules/trace/trace";
import * as platform from "tns-core-modules/platform/platform";
import { Utils, Application, Device, Trace, ImageAsset } from "@nativescript/core";
import * as permissions from "nativescript-permissions";

let REQUEST_IMAGE_CAPTURE = 3453;
Expand All @@ -23,20 +18,17 @@ export let takePicture = function (options?): Promise<any> {
return;
}

let types: typeof typesModule = require("tns-core-modules/utils/types");
let utils: typeof utilsModule = require("tns-core-modules/utils/utils");

let saveToGallery = true;
let reqWidth = 0;
let reqHeight = 0;
let shouldKeepAspectRatio = true;

let density = utils.layout.getDisplayDensity();
let density = Utils.layout.getDisplayDensity();
if (options) {
saveToGallery = types.isNullOrUndefined(options.saveToGallery) ? saveToGallery : options.saveToGallery;
saveToGallery = Utils.isNullOrUndefined(options.saveToGallery) ? saveToGallery : options.saveToGallery;
reqWidth = options.width ? options.width * density : reqWidth;
reqHeight = options.height ? options.height * density : reqWidth;
shouldKeepAspectRatio = types.isNullOrUndefined(options.keepAspectRatio) ? shouldKeepAspectRatio : options.keepAspectRatio;
shouldKeepAspectRatio = Utils.isNullOrUndefined(options.keepAspectRatio) ? shouldKeepAspectRatio : options.keepAspectRatio;
}

if (!permissions.hasPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
Expand All @@ -57,15 +49,15 @@ export let takePicture = function (options?): Promise<any> {

nativeFile = new java.io.File(picturePath);
} else {
picturePath = utils.ad.getApplicationContext().getExternalFilesDir(null).getAbsolutePath() + "/" + "NSIMG_" + dateStamp + ".jpg";
picturePath = Utils.android.getApplicationContext().getExternalFilesDir(null).getAbsolutePath() + "/" + "NSIMG_" + dateStamp + ".jpg";
nativeFile = new java.io.File(picturePath);
}

let sdkVersionInt = parseInt(platform.device.sdkVersion);
let sdkVersionInt = parseInt(Device.sdkVersion);
if (sdkVersionInt >= 21) {
tempPictureUri = FileProviderPackageName.FileProvider.getUriForFile(
applicationModule.android.context,
applicationModule.android.nativeApp.getPackageName() + ".provider", nativeFile);
Application.android.context,
Application.android.nativeApp.getPackageName() + ".provider", nativeFile);
} else {
tempPictureUri = android.net.Uri.fromFile(nativeFile);
}
Expand All @@ -80,14 +72,12 @@ export let takePicture = function (options?): Promise<any> {
android.hardware.Camera.CameraInfo.CAMERA_FACING_BACK);
}

if (takePictureIntent.resolveActivity(utils.ad.getApplicationContext().getPackageManager()) != null) {

let appModule: typeof applicationModule = require("tns-core-modules/application");
if (takePictureIntent.resolveActivity(Utils.android.getApplicationContext().getPackageManager()) != null) {

// Remove previous listeners if any
appModule.android.off("activityResult");
Application.android.off("activityResult");

appModule.android.on("activityResult", (args) => {
Application.android.on("activityResult", (args) => {
const requestCode = args.requestCode;
const resultCode = args.resultCode;

Expand All @@ -96,17 +86,17 @@ export let takePicture = function (options?): Promise<any> {
try {
let callback = new android.media.MediaScannerConnection.OnScanCompletedListener({
onScanCompleted: function (path, uri) {
if (trace.isEnabled()) {
trace.write(`image from path ${path} has been successfully scanned!`, trace.categories.Debug);
if (Trace.isEnabled()) {
Trace.write(`image from path ${path} has been successfully scanned!`, Trace.categories.Debug);
}
}
});

android.media.MediaScannerConnection.scanFile(appModule.android.context, [picturePath], null, callback);
android.media.MediaScannerConnection.scanFile(Application.android.context, [picturePath], null, callback);
} catch (ex) {
if (trace.isEnabled()) {
trace.write(`An error occurred while scanning file ${picturePath}: ${ex.message}!`,
trace.categories.Debug);
if (Trace.isEnabled()) {
Trace.write(`An error occurred while scanning file ${picturePath}: ${ex.message}!`,
Trace.categories.Debug);
}
}
}
Expand Down Expand Up @@ -135,7 +125,7 @@ export let takePicture = function (options?): Promise<any> {
}
}

let asset = new imageAssetModule.ImageAsset(picturePath);
let asset = new ImageAsset(picturePath);
asset.options = {
width: reqWidth,
height: reqHeight,
Expand All @@ -148,7 +138,7 @@ export let takePicture = function (options?): Promise<any> {
}
});

appModule.android.foregroundActivity.startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
Application.android.foregroundActivity.startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);

}
} catch (e) {
Expand All @@ -160,9 +150,8 @@ export let takePicture = function (options?): Promise<any> {
};

export let isAvailable = function () {
let utils: typeof utilsModule = require("tns-core-modules/utils/utils");

return utils.ad
return Utils.android
.getApplicationContext()
.getPackageManager()
.hasSystemFeature(android.content.pm.PackageManager.FEATURE_CAMERA);
Expand Down Expand Up @@ -213,9 +202,9 @@ let rotateBitmap = function (picturePath, angle) {
out.flush();
out.close();
} catch (ex) {
if (trace.isEnabled()) {
trace.write(`An error occurred while rotating file ${picturePath} (using the original one): ${ex.message}!`,
trace.categories.Debug);
if (Trace.isEnabled()) {
Trace.write(`An error occurred while rotating file ${picturePath} (using the original one): ${ex.message}!`,
Trace.categories.Debug);
}
}
};
49 changes: 21 additions & 28 deletions src/camera.ios.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
import * as types from "tns-core-modules/utils/types";
import * as imageSourceModule from "tns-core-modules/image-source/image-source";
import * as imageAssetModule from "tns-core-modules/image-asset/image-asset";
import * as frameModule from "tns-core-modules/ui/frame/frame";
import * as trace from "tns-core-modules/trace/trace";
import { Utils, ImageSource, ImageAsset, Trace, Frame } from "@nativescript/core";

class UIImagePickerControllerDelegateImpl extends NSObject implements UIImagePickerControllerDelegate {
public static ObjCProtocols = [UIImagePickerControllerDelegate];
Expand Down Expand Up @@ -34,7 +30,7 @@ class UIImagePickerControllerDelegateImpl extends NSObject implements UIImagePic
this._height = options.height;
this._saveToGallery = options.saveToGallery;
this._allowsEditing = options.allowsEditing;
this._keepAspectRatio = types.isNullOrUndefined(options.keepAspectRatio) ? true : options.keepAspectRatio;
this._keepAspectRatio = Utils.isNullOrUndefined(options.keepAspectRatio) ? true : options.keepAspectRatio;
}
return this;
}
Expand All @@ -47,11 +43,10 @@ class UIImagePickerControllerDelegateImpl extends NSObject implements UIImagePic
source = info.valueForKey(UIImagePickerControllerEditedImage);
}
if (source) {
let imageSource: typeof imageSourceModule = require("image-source");
let imageSourceResult = imageSource.fromNativeSource(source);
let imageSourceResult = new ImageSource(source);

if (this._callback) {
let imageAsset: imageAssetModule.ImageAsset;
let imageAsset: ImageAsset;
if (this._saveToGallery) {
PHPhotoLibrary.sharedPhotoLibrary().performChangesCompletionHandler(
() => {
Expand All @@ -77,17 +72,17 @@ class UIImagePickerControllerDelegateImpl extends NSObject implements UIImagePic
// Display waring if the asset was created more than 1s before/after the current date.
console.warn("Image asset returned was created more than 1 second ago");
}
imageAsset = new imageAssetModule.ImageAsset(asset);
imageAsset = new ImageAsset(asset);
this.setImageAssetAndCallCallback(imageAsset);
}

} else {
trace.write("An error ocurred while saving image to gallery: " +
err, trace.categories.Error, trace.messageType.error);
Trace.write("An error ocurred while saving image to gallery: " +
err, Trace.categories.Error, Trace.messageType.error);
}
});
} else {
imageAsset = new imageAssetModule.ImageAsset(imageSourceResult.ios);
imageAsset = new ImageAsset(imageSourceResult.ios);
this.setImageAssetAndCallCallback(imageAsset);
}
}
Expand All @@ -97,7 +92,7 @@ class UIImagePickerControllerDelegateImpl extends NSObject implements UIImagePic
listener = null;
}

private setImageAssetAndCallCallback(imageAsset: imageAssetModule.ImageAsset) {
private setImageAssetAndCallCallback(imageAsset: ImageAsset) {
if (this._keepAspectRatio) {
let pictureWidth = imageAsset.nativeImage ? imageAsset.nativeImage.size.width : imageAsset.ios.pixelWidth;
let pictureHeight = imageAsset.nativeImage ? imageAsset.nativeImage.size.height : imageAsset.ios.pixelHeight;
Expand Down Expand Up @@ -138,9 +133,9 @@ export let takePicture = function (options): Promise<any> {
if (options) {
reqWidth = options.width || 0;
reqHeight = options.height || reqWidth;
keepAspectRatio = types.isNullOrUndefined(options.keepAspectRatio) ? keepAspectRatio : options.keepAspectRatio;
saveToGallery = types.isNullOrUndefined(options.saveToGallery) ? saveToGallery : options.saveToGallery;
allowsEditing = types.isNullOrUndefined(options.allowsEditing) ? allowsEditing : options.allowsEditing;
keepAspectRatio = Utils.isNullOrUndefined(options.keepAspectRatio) ? keepAspectRatio : options.keepAspectRatio;
saveToGallery = Utils.isNullOrUndefined(options.saveToGallery) ? saveToGallery : options.saveToGallery;
allowsEditing = Utils.isNullOrUndefined(options.allowsEditing) ? allowsEditing : options.allowsEditing;
}

let authStatus = PHPhotoLibrary.authorizationStatus();
Expand Down Expand Up @@ -174,9 +169,7 @@ export let takePicture = function (options): Promise<any> {

imagePickerController.modalPresentationStyle = UIModalPresentationStyle.CurrentContext;

let frame: typeof frameModule = require("tns-core-modules/ui/frame");

let topMostFrame = frame.topmost();
let topMostFrame = Frame.topmost();
if (topMostFrame) {
let viewController: UIViewController = topMostFrame.currentPage && topMostFrame.currentPage.ios;
if (viewController) {
Expand Down Expand Up @@ -215,8 +208,8 @@ export let requestPhotosPermissions = function () {
case PHAuthorizationStatus.NotDetermined: {
PHPhotoLibrary.requestAuthorization((auth) => {
if (auth === PHAuthorizationStatus.Authorized) {
if (trace.isEnabled()) {
trace.write("Application can access photo library assets.", trace.categories.Debug);
if (Trace.isEnabled()) {
Trace.write("Application can access photo library assets.", Trace.categories.Debug);
}
resolve();
} else {
Expand All @@ -226,16 +219,16 @@ export let requestPhotosPermissions = function () {
break;
}
case PHAuthorizationStatus.Authorized: {
if (trace.isEnabled()) {
trace.write("Application can access photo library assets.", trace.categories.Debug);
if (Trace.isEnabled()) {
Trace.write("Application can access photo library assets.", Trace.categories.Debug);
}
resolve();
break;
}
case PHAuthorizationStatus.Restricted:
case PHAuthorizationStatus.Denied: {
if (trace.isEnabled()) {
trace.write("Application can not access photo library assets.", trace.categories.Debug);
if (Trace.isEnabled()) {
Trace.write("Application can not access photo library assets.", Trace.categories.Debug);
}
reject();
break;
Expand Down Expand Up @@ -264,8 +257,8 @@ export let requestCameraPermissions = function () {
}
case AVAuthorizationStatus.Restricted:
case AVAuthorizationStatus.Denied: {
if (trace.isEnabled()) {
trace.write("Application can not access Camera assets.", trace.categories.Debug);
if (Trace.isEnabled()) {
Trace.write("Application can not access Camera assets.", Trace.categories.Debug);
}
reject();
break;
Expand Down
4 changes: 2 additions & 2 deletions src/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import imageAsset = require("tns-core-modules/image-asset/image-asset");
import { ImageAsset } from '@nativescript/core';

/**
* Take a photo using the camera.
* @param options - Optional parameter for setting different camera options.
*/
export function takePicture(options?: CameraOptions): Promise<imageAsset.ImageAsset>;
export function takePicture(options?: CameraOptions): Promise<ImageAsset>;

/**
* Check required permissions for using device camera.
Expand Down
12 changes: 6 additions & 6 deletions src/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "nativescript-camera",
"version": "4.5.0",
"name": "@nativescript/camera",
"version": "5.0.0",
"description": "Provides API for using device camera",
"repository": {
"type": "git",
Expand Down Expand Up @@ -46,12 +46,12 @@
"nativescript-permissions": "~1.3.0"
},
"devDependencies": {
"tns-core-modules": "^6.0.0",
"tns-platform-declarations": "^6.0.0",
"typescript": "~3.5.3",
"@nativescript/core": "rc",
"@nativescript/types": "rc",
"typescript": "~3.9.0",
"prompt": "^1.0.0",
"rimraf": "^2.6.2",
"tslint": "~5.11.0"
"tslint": "~6.1.2"
},
"license": "Apache-2.0"
}
4 changes: 2 additions & 2 deletions src/references.d.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
/// <reference path="./node_modules/tns-platform-declarations/ios.d.ts" />
/// <reference path="./node_modules/tns-platform-declarations/android.d.ts" />
/// <reference path="./node_modules/@nativescript/types/ios.d.ts" />
/// <reference path="./node_modules/@nativescript/types/android.d.ts" />