diff --git a/.travis.yml b/.travis.yml index d6e5ed1..8734fc7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ env: global: - - ANDROID_PACKAGE='imagepickerdemo-debug.apk' - - ANDROID_PACKAGE_FOLDER=$TRAVIS_BUILD_DIR/demo/platforms/android/app/build/outputs/apk + - ANDROID_PACKAGE='app-debug.apk' + - ANDROID_PACKAGE_FOLDER=$TRAVIS_BUILD_DIR/demo/platforms/android/app/build/outputs/apk/debug - ANDROID_SAUCE_STORAGE="https://saucelabs.com/rest/v1/storage/$SAUCE_USER/$ANDROID_PACKAGE?overwrite=true" - IOS_PACKAGE='imagepickerdemo.zip' - IOS_PACKAGE_FOLDER=$TRAVIS_BUILD_DIR/demo/platforms/ios/build/emulator @@ -78,7 +78,7 @@ android: components: - tools - platform-tools - - build-tools-26.0.1 + - build-tools-26.0.2 - android-26 - android-23 - extra-android-m2repository diff --git a/README.md b/README.md index 9c33a1c..e54d06c 100644 --- a/README.md +++ b/README.md @@ -6,13 +6,14 @@ [![Build Status](https://travis-ci.org/NativeScript/nativescript-imagepicker.svg?branch=master)](https://travis-ci.org/NativeScript/nativescript-imagepicker) Imagepicker plugin supporting both single and multiple selection. -
Plugin supports **iOS8+** and uses [Photos Framework](https://developer.apple.com/library/prerelease/ios//documentation/Photos/Reference/Photos_Framework/index.html). +
Plugin supports **iOS8+** and uses [QBImagePicker](https://github.com/questbeat/QBImagePicker) cocoa pod.
For **Android** it uses Intents to open the stock images or file pickers. For Android 6 (API 23) and above the permissions to read file storage should be explicitly required. See demo for implementation details. - [Installation](#installation) - [Configuration](#configuration) +- [Migrating from 5.x.x to 6.x.x](#migrating-from-5xx-to-6xx) - [Migrating from 4.x.x to 5.x.x](#migrating-from-4xx-to-5xx) - [Migrating from 3.x.x to 4.x.x](#migrating-from-3xx-to-4xx) - [Usage](#usage) @@ -41,6 +42,9 @@ tns run ## Configuration No additional configuration required! +## Migrating from 5.x.x to 6.x.x +With version **6.x.x** the dependency to the `nativescript-ui-listview` plugin is removed and for iOS the [QBImagePicker](https://github.com/questbeat/QBImagePicker) cocoa pod is used. Now the plugin supports some new features, fixes some bugs and looks super native for iOS. You can remove any dependencies to `nativescript-pro-ui`, `nativescript-ui-listview`, etc. in case you've added them in your app specifically for this plugin. Also the options **doneText**, **cancelText**, **albumsText**, **newestFirst** and the methods **cancel()** and **done()** are no longer applicable. The image picker now returns the basic [{N} ImageAsset class](https://github.com/NativeScript/NativeScript/tree/master/tns-core-modules/image-asset) (and not custom asset as before). + ## Migrating from 4.x.x to 5.x.x With version **5.x.x** major update to the plugin there is a related dependency which needs to be updated inside your project. The plugin uses internally the `nativescript-ui-listview` plugin (part of the NativeScript Pro UI components). Recently the monolithic [NativeScript Pro UI plugin was split in multiple plugins](https://www.nativescript.org/blog/professional-components-from-nativescript-ui-the-big-breakup), each of them representing a single component. Now, instead of the monolithic package, nativescript-imagepicker uses only the component it needs. To use version 5.x.x of the plugin, you need to update any dependencies to `nativescript-pro-ui` in your project with the single component alternatives as described in the [migration guide](http://docs.telerik.com/devtools/nativescript-ui/migration). @@ -116,33 +120,18 @@ context | Option | Platform | Default | Description | | --- | --- | --- | --- | | mode | both | multiple | The mode if the imagepicker. Possible values are `single` for single selection and `multiple` for multiple selection. | -| doneText | iOS | Done | The text of the "Done" button on top right. | -| cancelText | iOS | Cancel | The text of the "Cancel" button on top left. | -| albumsText | iOS | Albums | The title of the "Albums" screen from where the selection of album and images can be done. | -| newestFirst | iOS | false | Set to `true` to sort the images in an album by newest first. | +| minimumNumberOfSelection | iOS | 0 | The minumum number of selected assets. | +| maximumNumberOfSelection | iOS | 0 | The maximum number of selected assets. | +| showsNumberOfSelectedAssets | iOS | True | Display the number of selected assets. | +| prompt | iOS | undefined | Display prompt text when selecting assets. | +| numberOfColumnsInPortrait | iOS | 4 | Set the number of columns in Portrait orientation. | +| numberOfColumnsInLandscape | iOS | 7 | Set the number of columns in Landscape orientation. | +| mediaType | iOS | Any | Choose whether to pick Image/Video/Any type of assets. | + +The **hostView** parameter can be set to the view that hosts the image picker. Applicable in iOS only, intended to be used when open picker from a modal page. * authorize() - request the required permissions. * present() - show the albums to present the user the ability to select images. Returns an array of the selected images. -* cancel() - cancel selection. iOS only. -* done() - confirm the selection is ready. iOS only. - - -### Properties -| Property | Default | Description | -| --- | --- | --- | -| selection | null | An array of selected image assets. | -| albums | null | Albums from where the images are picked. | - - -### Image properties - -Once image is picked some options can be applied to it before it is used: - -| Option | Default | Description | -| --- | --- | --- | -| maxWidth | null | Image max width | -| maxHeight | null | Image max height | -| aspectRatio | fit | iOS only. Possible values are `fit` and `fill`. [Read more](https://developer.apple.com/documentation/photos/phimagecontentmode) | ## Contribute We love PRs! Check out the [contributing guidelines](CONTRIBUTING.md). If you want to contribute, but you are not sure where to start - look for [issues labeled `help wanted`](https://github.com/NativeScript/nativescript-imagepicker/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22). diff --git a/demo-angular/app/app.component.html b/demo-angular/app/app.component.html index 7efff0d..82bbd9a 100644 --- a/demo-angular/app/app.component.html +++ b/demo-angular/app/app.component.html @@ -3,15 +3,19 @@ - - - - - - + + + + + - - + + + + \ No newline at end of file diff --git a/demo-angular/app/app.component.ts b/demo-angular/app/app.component.ts index b35dd6f..bc2a1c6 100644 --- a/demo-angular/app/app.component.ts +++ b/demo-angular/app/app.component.ts @@ -1,6 +1,4 @@ -import { Component, ChangeDetectorRef } from "@angular/core"; -import { ListView } from "tns-core-modules/ui/list-view"; -import { isAndroid } from "tns-core-modules/platform"; +import { Component } from "@angular/core"; import * as imagepicker from "nativescript-imagepicker"; @Component({ @@ -8,44 +6,51 @@ import * as imagepicker from "nativescript-imagepicker"; templateUrl: "app.component.html", }) export class AppComponent { + imageAssets = []; + imageSrc: any; + isSingleMode: boolean = true; + thumbSize: number = 80; + previewSize: number = 300; - items = []; + public onSelectMultipleTap() { + this.isSingleMode = false; - constructor(private _changeDetectionRef: ChangeDetectorRef) { - } - - onSelectMultipleTap() { let context = imagepicker.create({ mode: "multiple" }); this.startSelection(context); } - onSelectSingleTap() { + public onSelectSingleTap() { + this.isSingleMode = true; + let context = imagepicker.create({ mode: "single" }); this.startSelection(context); } - startSelection(context) { - let _that = this; + private startSelection(context) { + let that = this; context .authorize() .then(() => { - _that.items = []; + that.imageAssets = []; + that.imageSrc = null; return context.present(); }) .then((selection) => { - console.log("Selection done:"); - selection.forEach(function (selected) { - console.log("----------------"); - console.log("uri: " + selected.uri); - console.log("fileUri: " + selected.fileUri); + console.log("Selection done: " + JSON.stringify(selection)); + that.imageSrc = that.isSingleMode && selection.length > 0 ? selection[0] : null; + + // set the images to be loaded from the assets with optimal sizes (optimize memory usage) + selection.forEach(function (element) { + element.options.width = that.isSingleMode ? that.previewSize : that.thumbSize; + element.options.height = that.isSingleMode ? that.previewSize : that.thumbSize; }); - _that.items = selection; - _that._changeDetectionRef.detectChanges(); + + that.imageAssets = selection; }).catch(function (e) { console.log(e); }); diff --git a/demo-angular/app/main.ts b/demo-angular/app/main.ts index 639bfd5..5cf76e1 100644 --- a/demo-angular/app/main.ts +++ b/demo-angular/app/main.ts @@ -1,4 +1,4 @@ import { platformNativeScriptDynamic } from "nativescript-angular/platform"; import { AppModule } from "./app.module"; -platformNativeScriptDynamic().bootstrapModule(AppModule); +platformNativeScriptDynamic({ createFrameOnBootstrap: true }).bootstrapModule(AppModule); \ No newline at end of file diff --git a/demo-angular/package.json b/demo-angular/package.json index 1eb9e13..548bd5e 100644 --- a/demo-angular/package.json +++ b/demo-angular/package.json @@ -2,10 +2,10 @@ "nativescript": { "id": "org.nativescript.imagepickerdemoangular", "tns-ios": { - "version": "3.4.0" + "version": "4.0.1" }, "tns-android": { - "version": "3.4.0" + "version": "4.0.0" } }, "dependencies": { @@ -23,7 +23,7 @@ "nativescript-unit-test-runner": "^0.3.4", "reflect-metadata": "~0.1.8", "rxjs": "^5.5.0", - "tns-core-modules": "^3.4.0" + "tns-core-modules": "^4.0.0" }, "devDependencies": { "@angular/compiler-cli": "~5.0.0", @@ -42,7 +42,7 @@ "lazy": "1.0.11", "nativescript-css-loader": "~0.26.0", "nativescript-dev-typescript": "^0.6.0", - "nativescript-dev-webpack": "^0.9.0", + "nativescript-dev-webpack": "^0.10.1", "nativescript-worker-loader": "~0.8.1", "raw-loader": "~0.5.1", "resolve-url-loader": "~2.1.0", @@ -52,7 +52,8 @@ "webpack": "~3.8.1", "webpack-bundle-analyzer": "^2.8.2", "webpack-sources": "~1.0.1", - "zone.js": "^0.8.4" + "zone.js": "^0.8.4", + "uglifyjs-webpack-plugin": "~1.1.6" }, "scripts": { "build.plugin": "cd ../src && npm run build", diff --git a/demo/app/main-page.ts b/demo/app/main-page.ts index 8199a20..2f755ff 100644 --- a/demo/app/main-page.ts +++ b/demo/app/main-page.ts @@ -1,50 +1,10 @@ import { EventData } from 'tns-core-modules/data/observable'; import { Page } from 'tns-core-modules/ui/page'; -import { isAndroid } from "tns-core-modules/platform"; -import * as imagepicker from "nativescript-imagepicker"; +import { MainViewModel } from './main-view-model'; -let list; -let imageSrc; - -export function pageLoaded(args: EventData) { +export function onNavigatingTo(args: EventData) { + let viewModel = new MainViewModel(); let page = args.object; - list = page.getViewById("urls-list"); - imageSrc = page.getViewById("imageSrc"); -} - -export function onSelectMultipleTap(args) { - let context = imagepicker.create({ mode: "multiple" }); - startSelection(context, false); -} - -export function onSelectSingleTap(args) { - let context = imagepicker.create({ mode: "single" }); - startSelection(context, true); -} -function startSelection(context, isSingle) { - context - .authorize() - .then(function() { - list.items = []; - return context.present(); - }) - .then(function(selection) { - console.log("Selection done:"); - selection.forEach(function(selected) { - console.log("----------------"); - console.log("uri: " + selected.uri); - if (isSingle) { - selected.getImage({ maxWidth: 200, maxHeight: 200, aspectRatio: 'fill' }) - .then((imageSource) => { - imageSrc.src = imageSource; - }); - } else { - imageSrc.visibility = 'hidden'; - } - }); - list.items = selection; - }).catch(function (e) { - console.log(e); - }); + page.bindingContext = viewModel; } \ No newline at end of file diff --git a/demo/app/main-page.xml b/demo/app/main-page.xml index 41d50bb..b237af5 100644 --- a/demo/app/main-page.xml +++ b/demo/app/main-page.xml @@ -1,20 +1,18 @@ - + - + - - - - - -