Skip to content

Commit

Permalink
chore: publish plugin updates (#611)
Browse files Browse the repository at this point in the history
* fix(camera): set settings again on callbacks (#595)

* feat(storage): Add removeOld function (#585)

* feat(camera): Return if image was saved to gallery (#599)

* fix(camera): saveToGallery for edited images (#602)

* docs(camera): Add descriptions to CameraSource (#608)

* fix(local-notifications): return schedule on as object (#603)

* chore(release): publish [skip ci]

 - @capacitor/camera@1.1.0
 - @capacitor/local-notifications@1.0.6
 - @capacitor/storage@1.2.0

Co-authored-by: jcesarmobile <jcesarmobile@gmail.com>
Co-authored-by: Ely Lucas <ely@meta-tek.net>
  • Loading branch information
3 people authored Sep 15, 2021
1 parent 6139ae7 commit e647914
Show file tree
Hide file tree
Showing 22 changed files with 204 additions and 36 deletions.
17 changes: 17 additions & 0 deletions camera/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,23 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

# [1.1.0](https://github.com/ionic-team/capacitor-plugins/compare/@capacitor/camera@1.0.5...@capacitor/camera@1.1.0) (2021-09-15)


### Bug Fixes

* **camera:** saveToGallery for edited images ([#602](https://github.com/ionic-team/capacitor-plugins/issues/602)) ([b5ac27d](https://github.com/ionic-team/capacitor-plugins/commit/b5ac27d59181ec3acc2909b2569d8ab45a829b1c))
* **camera:** set settings again on callbacks ([#595](https://github.com/ionic-team/capacitor-plugins/issues/595)) ([908bd68](https://github.com/ionic-team/capacitor-plugins/commit/908bd688767e374cf8e96b3def08bd33dcdfd2aa))


### Features

* **camera:** Return if image was saved to gallery ([#599](https://github.com/ionic-team/capacitor-plugins/issues/599)) ([594af3b](https://github.com/ionic-team/capacitor-plugins/commit/594af3be0982371e6c61e4bdb830c6bbb3963913))





## [1.0.5](https://github.com/ionic-team/capacitor-plugins/compare/@capacitor/camera@1.0.4...@capacitor/camera@1.0.5) (2021-09-01)


Expand Down
27 changes: 14 additions & 13 deletions camera/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,14 +143,15 @@ Request camera and photo album permissions

#### Photo

| Prop | Type | Description | Since |
| ------------------ | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----- |
| **`base64String`** | <code>string</code> | The base64 encoded string representation of the image, if using <a href="#cameraresulttype">CameraResultType.Base64</a>. | 1.0.0 |
| **`dataUrl`** | <code>string</code> | The url starting with 'data:image/jpeg;base64,' and the base64 encoded string representation of the image, if using <a href="#cameraresulttype">CameraResultType.DataUrl</a>. | 1.0.0 |
| **`path`** | <code>string</code> | If using <a href="#cameraresulttype">CameraResultType.Uri</a>, the path will contain a full, platform-specific file URL that can be read later using the Filsystem API. | 1.0.0 |
| **`webPath`** | <code>string</code> | webPath returns a path that can be used to set the src attribute of an image for efficient loading and rendering. | 1.0.0 |
| **`exif`** | <code>any</code> | Exif data, if any, retrieved from the image | 1.0.0 |
| **`format`** | <code>string</code> | The format of the image, ex: jpeg, png, gif. iOS and Android only support jpeg. Web supports jpeg and png. gif is only supported if using file input. | 1.0.0 |
| Prop | Type | Description | Since |
| ------------------ | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----- |
| **`base64String`** | <code>string</code> | The base64 encoded string representation of the image, if using <a href="#cameraresulttype">CameraResultType.Base64</a>. | 1.0.0 |
| **`dataUrl`** | <code>string</code> | The url starting with 'data:image/jpeg;base64,' and the base64 encoded string representation of the image, if using <a href="#cameraresulttype">CameraResultType.DataUrl</a>. | 1.0.0 |
| **`path`** | <code>string</code> | If using <a href="#cameraresulttype">CameraResultType.Uri</a>, the path will contain a full, platform-specific file URL that can be read later using the Filsystem API. | 1.0.0 |
| **`webPath`** | <code>string</code> | webPath returns a path that can be used to set the src attribute of an image for efficient loading and rendering. | 1.0.0 |
| **`exif`** | <code>any</code> | Exif data, if any, retrieved from the image | 1.0.0 |
| **`format`** | <code>string</code> | The format of the image, ex: jpeg, png, gif. iOS and Android only support jpeg. Web supports jpeg and png. gif is only supported if using file input. | 1.0.0 |
| **`saved`** | <code>boolean</code> | Whether if the image was saved to the gallery or not. On Android and iOS, saving to the gallery can fail if the user didn't grant the required permissions. On Web there is no gallery, so always returns false. | 1.1.0 |


#### ImageOptions
Expand Down Expand Up @@ -222,11 +223,11 @@ Request camera and photo album permissions

#### CameraSource

| Members | Value |
| ------------ | --------------------- |
| **`Prompt`** | <code>'PROMPT'</code> |
| **`Camera`** | <code>'CAMERA'</code> |
| **`Photos`** | <code>'PHOTOS'</code> |
| Members | Value | Description |
| ------------ | --------------------- | ------------------------------------------------------------------ |
| **`Prompt`** | <code>'PROMPT'</code> | Prompts the user to select either the photo album or take a photo. |
| **`Camera`** | <code>'CAMERA'</code> | Take a new photo using the camera. |
| **`Photos`** | <code>'PHOTOS'</code> | Pick an existing photo fron the gallery or photo album. |


#### CameraDirection
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ public class CameraPlugin extends Plugin {
private Uri imageFileUri;
private Uri imagePickedContentUri;
private boolean isEdited = false;
private boolean isFirstRequest = true;
private boolean isSaved = false;

private CameraSettings settings = new CameraSettings();

Expand Down Expand Up @@ -145,7 +147,8 @@ private boolean checkCameraPermissions(PluginCall call) {
boolean hasPhotoPerms = getPermissionState(PHOTOS) == PermissionState.GRANTED;

// If we want to save to the gallery, we need two permissions
if (settings.isSaveToGallery() && !(hasCameraPerms && hasPhotoPerms)) {
if (settings.isSaveToGallery() && !(hasCameraPerms && hasPhotoPerms) && isFirstRequest) {
isFirstRequest = false;
String[] aliases;
if (needCameraPerms) {
aliases = new String[] { CAMERA, PHOTOS };
Expand Down Expand Up @@ -256,6 +259,7 @@ public void openPhotos(final PluginCall call) {

@ActivityCallback
public void processCameraImage(PluginCall call, ActivityResult result) {
settings = getSettings(call);
if (imageFileSavePath == null) {
call.reject(IMAGE_PROCESS_NO_FILE_ERROR);
return;
Expand All @@ -276,6 +280,7 @@ public void processCameraImage(PluginCall call, ActivityResult result) {

@ActivityCallback
public void processPickedImage(PluginCall call, ActivityResult result) {
settings = getSettings(call);
Intent data = result.getData();
if (data == null) {
call.reject("No image picked");
Expand Down Expand Up @@ -320,7 +325,7 @@ private void processPickedImage(Uri imageUri, PluginCall call) {
@ActivityCallback
private void processEditedImage(PluginCall call, ActivityResult result) {
isEdited = true;

settings = getSettings(call);
if (result.getResultCode() == Activity.RESULT_CANCELED) {
// User cancelled the edit operation, if this file was picked from photos,
// process the original picked image, otherwise process it as a camera photo
Expand Down Expand Up @@ -389,11 +394,21 @@ private void returnResult(PluginCall call, Bitmap bitmap, Uri u) {

boolean saveToGallery = call.getBoolean("saveToGallery", CameraSettings.DEFAULT_SAVE_IMAGE_TO_GALLERY);
if (saveToGallery && (imageEditedFileSavePath != null || imageFileSavePath != null)) {
isSaved = true;
try {
String fileToSavePath = imageEditedFileSavePath != null ? imageEditedFileSavePath : imageFileSavePath;
File fileToSave = new File(fileToSavePath);
MediaStore.Images.Media.insertImage(getContext().getContentResolver(), fileToSavePath, fileToSave.getName(), "");
String inserted = MediaStore.Images.Media.insertImage(
getContext().getContentResolver(),
fileToSavePath,
fileToSave.getName(),
""
);
if (inserted == null) {
isSaved = false;
}
} catch (FileNotFoundException e) {
isSaved = false;
Logger.error(getLogTag(), IMAGE_GALLERY_SAVE_ERROR, e);
}
}
Expand Down Expand Up @@ -435,6 +450,7 @@ private void returnFileURI(PluginCall call, ExifWrapper exif, Bitmap bitmap, Uri
ret.put("exif", exif.toJson());
ret.put("path", newUri.toString());
ret.put("webPath", FileUtils.getPortablePath(getContext(), bridge.getLocalUrl(), newUri));
ret.put("saved", isSaved);
call.resolve(ret);
} else {
call.reject(UNABLE_TO_PROCESS_IMAGE);
Expand Down Expand Up @@ -567,14 +583,11 @@ private void editImage(PluginCall call, Uri uri, ByteArrayOutputStream bitmapOut

private Intent createEditIntent(Uri origPhotoUri) {
try {
Uri editUri = FileProvider.getUriForFile(
getActivity(),
getContext().getPackageName() + ".fileprovider",
new File(origPhotoUri.getPath())
);
File editFile = new File(origPhotoUri.getPath());
Uri editUri = FileProvider.getUriForFile(getActivity(), getContext().getPackageName() + ".fileprovider", editFile);
Intent editIntent = new Intent(Intent.ACTION_EDIT);
editIntent.setDataAndType(editUri, "image/*");
imageEditedFileSavePath = editUri.toString();
imageEditedFileSavePath = editFile.getAbsolutePath();
int flags = Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
editIntent.addFlags(flags);
editIntent.putExtra(MediaStore.EXTRA_OUTPUT, editUri);
Expand Down
4 changes: 4 additions & 0 deletions camera/ios/Plugin.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
/* Begin PBXBuildFile section */
03FC29A292ACC40490383A1F /* Pods_Plugin.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B2A61DA5A1F2DD4F959604D /* Pods_Plugin.framework */; };
20C0B05DCFC8E3958A738AF2 /* Pods_PluginTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6753A823D3815DB436415E3 /* Pods_PluginTests.framework */; };
2FA5008E26E9143C00127B0B /* ImageSaver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FA5008D26E9143C00127B0B /* ImageSaver.swift */; };
50ADFF92201F53D600D50D53 /* Plugin.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 50ADFF88201F53D600D50D53 /* Plugin.framework */; };
50ADFF97201F53D600D50D53 /* CameraPluginTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50ADFF96201F53D600D50D53 /* CameraPluginTests.swift */; };
50ADFF99201F53D600D50D53 /* CameraPlugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ADFF8B201F53D600D50D53 /* CameraPlugin.h */; settings = {ATTRIBUTES = (Public, ); }; };
Expand All @@ -30,6 +31,7 @@
/* End PBXContainerItemProxy section */

/* Begin PBXFileReference section */
2FA5008D26E9143C00127B0B /* ImageSaver.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageSaver.swift; sourceTree = "<group>"; };
3B2A61DA5A1F2DD4F959604D /* Pods_Plugin.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Plugin.framework; sourceTree = BUILT_PRODUCTS_DIR; };
50ADFF88201F53D600D50D53 /* Plugin.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Plugin.framework; sourceTree = BUILT_PRODUCTS_DIR; };
50ADFF8B201F53D600D50D53 /* CameraPlugin.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CameraPlugin.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -94,6 +96,7 @@
50ADFF8A201F53D600D50D53 /* Plugin */ = {
isa = PBXGroup;
children = (
2FA5008D26E9143C00127B0B /* ImageSaver.swift */,
50ADFF8B201F53D600D50D53 /* CameraPlugin.h */,
50ADFFA72020EE4F00D50D53 /* CameraPlugin.m */,
50E1A94720377CB70090CE1A /* CameraPlugin.swift */,
Expand Down Expand Up @@ -311,6 +314,7 @@
files = (
50E1A94820377CB70090CE1A /* CameraPlugin.swift in Sources */,
50ADFFA82020EE4F00D50D53 /* CameraPlugin.m in Sources */,
2FA5008E26E9143C00127B0B /* ImageSaver.swift in Sources */,
6276AAD7255B3E1400097815 /* CameraTypes.swift in Sources */,
6276AAD3255B3E0E00097815 /* CameraExtensions.swift in Sources */,
);
Expand Down
35 changes: 25 additions & 10 deletions camera/ios/Plugin/CameraPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -186,23 +186,25 @@ extension CameraPlugin: PHPickerViewControllerDelegate {
}

private extension CameraPlugin {
func returnProcessedImage(_ processedImage: ProcessedImage) {
func returnImage(_ processedImage: ProcessedImage, isSaved: Bool) {
guard let jpeg = processedImage.generateJPEG(with: settings.jpegQuality) else {
self.call?.reject("Unable to convert image to jpeg")
return
}

if settings.resultType == CameraResultType.base64 {
call?.resolve([
self.call?.resolve([
"base64String": jpeg.base64EncodedString(),
"exif": processedImage.exifData,
"format": "jpeg"
"format": "jpeg",
"saved": isSaved
])
} else if settings.resultType == CameraResultType.dataURL {
call?.resolve([
"dataUrl": "data:image/jpeg;base64," + jpeg.base64EncodedString(),
"exif": processedImage.exifData,
"format": "jpeg"
"format": "jpeg",
"saved": isSaved
])
} else if settings.resultType == CameraResultType.uri {
guard let fileURL = try? saveTemporaryImage(jpeg),
Expand All @@ -214,11 +216,27 @@ private extension CameraPlugin {
"path": fileURL.absoluteString,
"exif": processedImage.exifData,
"webPath": webURL.absoluteString,
"format": "jpeg"
"format": "jpeg",
"saved": isSaved
])
}
}

func returnProcessedImage(_ processedImage: ProcessedImage) {
// conditionally save the image
if settings.saveToGallery && (processedImage.flags.contains(.edited) == true || processedImage.flags.contains(.gallery) == false) {
_ = ImageSaver(image: processedImage.image) { error in
var isSaved = false
if error == nil {
isSaved = true
}
self.returnImage(processedImage, isSaved: isSaved)
}
} else {
self.returnImage(processedImage, isSaved: false)
}
}

func showPrompt() {
// Build the action sheet
let alert = UIAlertController(title: settings.userPromptText.title, message: nil, preferredStyle: UIAlertController.Style.actionSheet)
Expand Down Expand Up @@ -380,11 +398,8 @@ private extension CameraPlugin {
metadata = asset.imageData
}
// get the result
let result = processedImage(from: image, with: metadata)
// conditionally save the image
if settings.saveToGallery && (flags.contains(.edited) == true || flags.contains(.gallery) == false) {
UIImageWriteToSavedPhotosAlbum(result.image, nil, nil, nil)
}
var result = processedImage(from: image, with: metadata)
result.flags = flags
return result
}

Expand Down
1 change: 1 addition & 0 deletions camera/ios/Plugin/CameraTypes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ internal struct PhotoFlags: OptionSet {
internal struct ProcessedImage {
var image: UIImage
var metadata: [String: Any]
var flags: PhotoFlags = []

var exifData: [String: Any] {
var exifData = metadata["{Exif}"] as? [String: Any]
Expand Down
20 changes: 20 additions & 0 deletions camera/ios/Plugin/ImageSaver.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import UIKit

class ImageSaver: NSObject {

var onResult: ((Error?)->Void) = {_ in }

init(image: UIImage, onResult:@escaping ((Error?)->Void)) {
self.onResult = onResult
super.init()
UIImageWriteToSavedPhotosAlbum(image, self, #selector(saveResult), nil)
}

@objc func saveResult(_ image: UIImage, didFinishSavingWithError error: Error?, contextInfo: UnsafeRawPointer) {
if let error = error {
onResult(error)
} else {
onResult(nil)
}
}
}
2 changes: 1 addition & 1 deletion camera/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@capacitor/camera",
"version": "1.0.5",
"version": "1.1.0",
"description": "The Camera API provides the ability to take a photo with the camera or choose an existing one from the photo album.",
"main": "dist/plugin.cjs.js",
"module": "dist/esm/index.js",
Expand Down
19 changes: 19 additions & 0 deletions camera/src/definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,11 +208,30 @@ export interface Photo {
* @since 1.0.0
*/
format: string;
/**
* Whether if the image was saved to the gallery or not.
*
* On Android and iOS, saving to the gallery can fail if the user didn't
* grant the required permissions.
* On Web there is no gallery, so always returns false.
*
* @since 1.1.0
*/
saved: boolean;
}

export enum CameraSource {
/**
* Prompts the user to select either the photo album or take a photo.
*/
Prompt = 'PROMPT',
/**
* Take a new photo using the camera.
*/
Camera = 'CAMERA',
/**
* Pick an existing photo fron the gallery or photo album.
*/
Photos = 'PHOTOS',
}

Expand Down
3 changes: 3 additions & 0 deletions camera/src/web.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ export class CameraWeb extends WebPlugin implements CameraPlugin {
resolve({
webPath: URL.createObjectURL(photo),
format: format,
saved: false,
});
} else {
reader.readAsDataURL(photo);
Expand All @@ -170,11 +171,13 @@ export class CameraWeb extends WebPlugin implements CameraPlugin {
resolve({
dataUrl: r,
format: format,
saved: false,
});
} else {
resolve({
base64String: r.split(',')[1],
format: format,
saved: false,
});
}
};
Expand Down
11 changes: 11 additions & 0 deletions local-notifications/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,17 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

## [1.0.6](https://github.com/ionic-team/capacitor-plugins/compare/@capacitor/local-notifications@1.0.5...@capacitor/local-notifications@1.0.6) (2021-09-15)


### Bug Fixes

* **local-notifications:** return schedule on as object ([#603](https://github.com/ionic-team/capacitor-plugins/issues/603)) ([ca34b01](https://github.com/ionic-team/capacitor-plugins/commit/ca34b01c73f14bb0ad14e8a501210e42a0e65b04))





## [1.0.5](https://github.com/ionic-team/capacitor-plugins/compare/@capacitor/local-notifications@1.0.4...@capacitor/local-notifications@1.0.5) (2021-09-01)


Expand Down
Loading

0 comments on commit e647914

Please sign in to comment.