Skip to content

Commit a3ec765

Browse files
committed
Merge remote-tracking branch 'origin/main' into fix/geolocation
2 parents 1d157c9 + a5924fd commit a3ec765

File tree

20 files changed

+330
-212
lines changed

20 files changed

+330
-212
lines changed

apps/demo-angular/src/plugin-demos/imagepicker.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<ListView [items]="imageAssets" *ngIf="!isSingleMode">
66
<ng-template let-image="item" let-i="index">
77
<GridLayout columns="auto, *">
8-
<Image [width]="thumbSize" [height]="thumbSize" [src]="image" stretch="aspectFill"></Image>
8+
<Image [width]="thumbSize" [height]="thumbSize" [src]="image.asset" stretch="aspectFill"></Image>
99
<Label col="1" [text]="'image ' + i"></Label>
1010
</GridLayout>
1111
</ng-template>

apps/demo-angular/src/plugin-demos/imagepicker.component.ts

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import { Component, NgZone } from '@angular/core';
2-
import { ImageAsset } from '@nativescript/core';
3-
import * as imagepicker from '@nativescript/imagepicker';
2+
import { ImageAsset, ImageSource } from '@nativescript/core';
3+
import { ImagePicker, create, ImagePickerSelection } from '@nativescript/imagepicker';
44

55
@Component({
66
selector: 'demo-imagepicker',
77
templateUrl: 'imagepicker.component.html',
88
})
99
export class ImagepickerComponent {
10-
imageAssets = [];
11-
imageSrc: any;
10+
imageAssets: ImagePickerSelection[] = [];
11+
imageSrc: ImageAsset | ImageSource;
1212
isSingleMode: boolean = true;
1313
thumbSize: number = 80;
1414
previewSize: number = 300;
@@ -18,7 +18,7 @@ export class ImagepickerComponent {
1818
public onSelectMultipleTap() {
1919
this.isSingleMode = false;
2020

21-
let context = imagepicker.create({
21+
let context = create({
2222
mode: 'multiple',
2323
});
2424
this.startSelection(context);
@@ -27,36 +27,40 @@ export class ImagepickerComponent {
2727
public onSelectSingleTap() {
2828
this.isSingleMode = true;
2929

30-
let context = imagepicker.create({
30+
let context = create({
3131
mode: 'single',
3232
});
3333
this.startSelection(context);
3434
}
3535

36-
private startSelection(context) {
36+
private startSelection(context: ImagePicker) {
3737
context
3838
.authorize()
39-
.then(() => {
39+
.then((authResult) => {
4040
this._ngZone.run(() => {
4141
this.imageAssets = [];
4242
this.imageSrc = null;
4343
});
44-
return context.present();
45-
})
46-
.then((selection) => {
47-
this._ngZone.run(() => {
48-
console.log('Selection done: ' + JSON.stringify(selection));
49-
this.imageSrc = this.isSingleMode && selection.length > 0 ? selection[0] : null;
44+
if (authResult.authorized) {
45+
return context.present().then((selection) => {
46+
this._ngZone.run(() => {
47+
console.log('Selection done: ' + JSON.stringify(selection));
48+
this.imageSrc = this.isSingleMode && selection.length > 0 ? selection[0].asset : null;
5049

51-
// set the images to be loaded from the assets with optimal sizes (optimize memory usage)
52-
selection.forEach((el: ImageAsset) => {
53-
el.options.width = this.isSingleMode ? this.previewSize : this.thumbSize;
54-
el.options.height = this.isSingleMode ? this.previewSize : this.thumbSize;
55-
});
50+
// set the images to be loaded from the assets with optimal sizes (optimize memory usage)
51+
selection.forEach((el) => {
52+
el.asset.options.width = this.isSingleMode ? this.previewSize : this.thumbSize;
53+
el.asset.options.height = this.isSingleMode ? this.previewSize : this.thumbSize;
54+
});
5655

57-
this.imageAssets = selection;
58-
});
56+
this.imageAssets = selection;
57+
});
58+
});
59+
} else {
60+
console.log('Unauthorised');
61+
}
5962
})
63+
6064
.catch(function (e) {
6165
console.log(e);
6266
});

packages/appavailability/README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,23 @@ For example, to query for `twitter://`, `whatsapp://` and `fb://`, edit `app/App
7474
</array>
7575
```
7676

77+
## Android Query Permission
78+
79+
Starting from Android API level 30 (Android 11), you must explicitly declare your app's intent to interact with other apps in the Android manifest file `AndroidManifest.xml`.
80+
81+
```xml
82+
<manifest>
83+
<queries>
84+
<package android:name="com.whatsapp" />
85+
</queries>
86+
87+
<application ...>
88+
</application>
89+
</manifest>
90+
```
91+
92+
Replace `com.whatsapp` with the package name of the app you want to interact with.
93+
7794
## API
7895

7996
| Methods| Return Type| Description|

packages/google-maps/index.android.ts

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1356,26 +1356,36 @@ export class Polygon extends OverLayBase implements IPolygon {
13561356
}
13571357
}
13581358

1359-
get holes(): Coordinate[] {
1360-
const array: androidNative.Array<com.google.android.gms.maps.model.LatLng> = this.native.getHoles().toArray();
1361-
const holes: Coordinate[] = [];
1359+
get holes(): Coordinate[][] {
1360+
const array: androidNative.Array<java.util.List<com.google.android.gms.maps.model.LatLng>> = this.native.getHoles().toArray();
1361+
const holes: Coordinate[][] = [];
13621362
for (let i = 0; i < array.length; i++) {
1363-
const hole = array[i];
1364-
holes.push({
1365-
lat: hole.latitude,
1366-
lng: hole.longitude,
1367-
});
1363+
const nativeHole = array[i].toArray();
1364+
const hole: Coordinate[] = [];
1365+
for (let j = 0; j < nativeHole.length; j++) {
1366+
hole.push({
1367+
lat: nativeHole[j].latitude,
1368+
lng: nativeHole[j].longitude,
1369+
});
1370+
}
1371+
holes.push(hole);
13681372
}
13691373
return holes;
13701374
}
13711375

1372-
set holes(value) {
1376+
set holes(value: Coordinate[][]) {
13731377
if (Array.isArray(value)) {
1374-
const nativeArray = new java.util.ArrayList<com.google.android.gms.maps.model.LatLng>();
1378+
const nativeHoles = new java.util.ArrayList<java.util.ArrayList<com.google.android.gms.maps.model.LatLng>>();
13751379
value.forEach((hole) => {
1376-
nativeArray.add(new com.google.android.gms.maps.model.LatLng(hole.lat, hole.lng));
1380+
if (Array.isArray(hole) && hole.length) {
1381+
const nativeHole = new java.util.ArrayList<com.google.android.gms.maps.model.LatLng>();
1382+
hole.forEach((coordinate) => {
1383+
nativeHole.add(new com.google.android.gms.maps.model.LatLng(coordinate.lat, coordinate.lng));
1384+
});
1385+
nativeHoles.add(nativeHole);
1386+
}
13771387
});
1378-
this.native.setHoles(nativeArray);
1388+
this.native.setHoles(nativeHoles);
13791389
}
13801390
}
13811391

packages/google-maps/index.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -494,7 +494,7 @@ export class Circle implements ICircle {
494494

495495
export interface IPolygon {
496496
points: Coordinate[];
497-
holes: Coordinate[];
497+
holes: Coordinate[][];
498498
tappable: boolean;
499499
strokeWidth: number;
500500
strokeColor: Color | string;
@@ -512,7 +512,7 @@ export interface PolygonOptions extends Partial<IPolygon> {}
512512
export class Polygon implements IPolygon {
513513
fillColor: Color | string;
514514
geodesic: boolean;
515-
holes: Coordinate[];
515+
holes: Coordinate[][];
516516
points: Coordinate[];
517517
strokeColor: Color | string;
518518
strokeJointType: JointType;

packages/google-maps/index.ios.ts

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1336,31 +1336,39 @@ export class Polygon extends OverLayBase implements IPolygon {
13361336
this.native.path = points;
13371337
}
13381338

1339-
get holes(): Coordinate[] {
1339+
get holes(): Coordinate[][] {
13401340
const nativeHoles = this.native?.holes;
13411341
const count = nativeHoles?.count || 0;
1342-
const holes: Coordinate[] = [];
1342+
const holes: Coordinate[][] = [];
13431343
for (let i = 0; i < count; i++) {
1344-
const hole = nativeHoles.objectAtIndex(i);
1345-
const coord = hole.coordinateAtIndex(0);
1346-
holes.push({
1347-
lat: coord.latitude,
1348-
lng: coord.longitude,
1349-
});
1344+
const nativeHole = nativeHoles.objectAtIndex(i);
1345+
const hole: Coordinate[] = [];
1346+
for (let j = 0; j < nativeHole.count(); j++) {
1347+
const coord = nativeHole.coordinateAtIndex(j);
1348+
hole.push({
1349+
lat: coord.latitude,
1350+
lng: coord.longitude,
1351+
});
1352+
}
1353+
holes.push(hole);
13501354
}
13511355
return holes;
13521356
}
13531357

1354-
set holes(value) {
1355-
const holes = [];
1358+
set holes(value: Coordinate[][]) {
1359+
const nativeHoles = [];
13561360
if (Array.isArray(value)) {
13571361
value.forEach((hole) => {
1358-
const path = GMSMutablePath.path();
1359-
path.addCoordinate(CLLocationCoordinate2DMake(hole.lat, hole.lng));
1360-
holes.push(path);
1362+
if (Array.isArray(hole) && hole.length) {
1363+
const path = GMSMutablePath.path();
1364+
hole.forEach((coordinate) => {
1365+
path.addCoordinate(CLLocationCoordinate2DMake(coordinate.lat, coordinate.lng));
1366+
});
1367+
nativeHoles.push(path);
1368+
}
13611369
});
13621370
}
1363-
this.native.holes = holes as any;
1371+
this.native.holes = nativeHoles as any;
13641372
}
13651373

13661374
get tappable(): boolean {

packages/google-maps/utils/index.android.ts

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ export function intoNativeMarkerOptions(options: MarkerOptions) {
7676
opts.icon(com.google.android.gms.maps.model.BitmapDescriptorFactory.defaultMarker(hueFromColor(color)));
7777
}
7878

79-
if(typeof options?.opacity === 'number') {
79+
if (typeof options?.opacity === 'number') {
8080
opts.alpha(options.opacity);
8181
}
8282

@@ -153,14 +153,15 @@ export function intoNativePolygonOptions(options: PolygonOptions) {
153153
}
154154

155155
if (Array.isArray(options?.holes)) {
156-
const holes = new java.util.ArrayList();
157156
options.holes.forEach((hole) => {
158-
holes.add(new com.google.android.gms.maps.model.LatLng(hole.lat, hole.lng));
157+
if (Array.isArray(hole) && hole.length) {
158+
const nativeHole = new java.util.ArrayList<com.google.android.gms.maps.model.LatLng>();
159+
hole.forEach((coordinate) => {
160+
nativeHole.add(new com.google.android.gms.maps.model.LatLng(coordinate.lat, coordinate.lng));
161+
});
162+
opts.addHole(nativeHole);
163+
}
159164
});
160-
161-
if (options.holes.length) {
162-
opts.addHole(holes);
163-
}
164165
}
165166

166167
if (typeof options?.tappable === 'boolean') {
@@ -275,10 +276,7 @@ export function intoNativeGroundOverlayOptions(options: GroundOverlayOptions) {
275276
}
276277

277278
if (options?.bounds) {
278-
opts.positionFromBounds(new com.google.android.gms.maps.model.LatLngBounds(
279-
new com.google.android.gms.maps.model.LatLng(options.bounds.southwest.lat, options.bounds.southwest.lng),
280-
new com.google.android.gms.maps.model.LatLng(options.bounds.northeast.lat, options.bounds.northeast.lng)
281-
));
279+
opts.positionFromBounds(new com.google.android.gms.maps.model.LatLngBounds(new com.google.android.gms.maps.model.LatLng(options.bounds.southwest.lat, options.bounds.southwest.lng), new com.google.android.gms.maps.model.LatLng(options.bounds.northeast.lat, options.bounds.northeast.lng)));
282280
}
283281

284282
if (typeof options?.transparency) {

packages/google-maps/utils/index.ios.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -144,12 +144,17 @@ export function intoNativePolygonOptions(options: PolygonOptions) {
144144
const opts = path ? GMSPolygon.polygonWithPath(path) : GMSPolygon.new();
145145

146146
if (Array.isArray(options?.holes)) {
147-
if (options.holes.length) {
148-
opts.holes = options.holes.map((hole) => {
149-
const res = GMSMutablePath.path();
150-
res.addCoordinate(CLLocationCoordinate2DMake(hole.lat, hole.lng));
151-
}) as any;
152-
}
147+
const nativeHoles = NSMutableArray.new<GMSMutablePath>();
148+
options.holes.forEach((hole) => {
149+
if (Array.isArray(hole) && hole.length) {
150+
const path = GMSMutablePath.path();
151+
hole.forEach((coordinate) => {
152+
path.addCoordinate(CLLocationCoordinate2DMake(coordinate.lat, coordinate.lng));
153+
});
154+
nativeHoles.addObject(path);
155+
}
156+
});
157+
opts.holes = nativeHoles;
153158
}
154159

155160
if (typeof options?.tappable === 'boolean') {

packages/google-signin/README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ Make sure you've filled out all the required fields in the console for [OAuth co
8585
2. Select `GoogleService-Info.plist` from the file manager.
8686
3. Select the `Runner` target from the dialog that appears.
8787

88-
4. Add the `CFBundleURLTypes` attributes below to the `App_Resources/iOS/Info.plist` file.
88+
4. Add the `CFBundleURLTypes` and `GIDClientID` attributes below to the `App_Resources/iOS/Info.plist` file.
8989

9090
```xml
9191
<!-- Google Sign-in Section -->
@@ -102,6 +102,9 @@ Make sure you've filled out all the required fields in the console for [OAuth co
102102
</array>
103103
</dict>
104104
</array>
105+
<key>GIDClientID</key>
106+
<!-- Copied from GoogleService-Info.plist key CLIENT_ID -->
107+
<string><749673967192-c24phj29u2otpict36e71ocjo2g5i3hs.apps.googleusercontent.com/string>
105108
<!-- End of the Google Sign-in Section -->
106109
```
107110

packages/imagepicker/README.md

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ Install the plugin by running the following command in the root directory of you
2929
npm install @nativescript/imagepicker
3030
```
3131

32+
**Note: Version 3.0 contains breaking changes:**
33+
* authorize() now returns a `Promise<AuthorizationResult>` for both android and ios.
34+
* In the returned result from `present()` each `result[i].thumbnail` is now an `ImageSource`.
35+
* `result[i].duration` is now typed correctly as a `number`.
36+
3237
**Note: Version 2.0 contains breaking changes. In order supply more information about your selection, the ImageSource asset is nested in the response so you'll need to update your code to use `result.asset` instead of `result` as your src for your Images.**
3338

3439
## Android required permissions
@@ -97,22 +102,25 @@ The `present` method resolves with the selected media assets that can you to pro
97102
```ts
98103
imagePickerObj
99104
.authorize()
100-
.then(function() {
101-
return imagePickerObj.present();
102-
})
103-
.then(function(selection) {
104-
selection.forEach(function(selected) {
105-
this.imageSource = selected.asset;
106-
this.type = selected.type;
107-
this.filesize = selected.filesize;
108-
//etc
109-
});
110-
list.items = selection;
111-
}).catch(function (e) {
105+
.then((authResult) => {
106+
if(authResult.authorized) {
107+
return imagePickerObj.present()
108+
.then(function(selection) {
109+
selection.forEach(function(selected) {
110+
this.imageSource = selected.asset;
111+
this.type = selected.type;
112+
this.filesize = selected.filesize;
113+
//etc
114+
});
115+
});
116+
} else {
117+
// process authorization not granted.
118+
}
119+
})
120+
.catch(function (e) {
112121
// process error
113122
});
114123
```
115-
> **Note** To request permissions for Android 6+ (API 23+), use [nativescript-permissions](https://www.npmjs.com/package/nativescript-permissions) plugin.
116124

117125
### Demo
118126
You can play with the plugin on StackBlitz at any of the following links:
@@ -131,8 +139,8 @@ The class that provides the media selection API. It offers the following methods
131139
| Method | Returns | Description
132140
|:-------|:--------|:-----------
133141
| `constructor(options: Options)` | `ImagePicker` | Instanciates the ImagePicker class with the optional `options` parameter. See [Options](#options)
134-
| `authorize()` | `Promise<void>` | Requests the required permissions. Call it before calling `present()`. In case of a failed authorization, consider notifying the user for degraded functionality.
135-
| `present()` | `Promise<ImageAsset[]>` | Presents the image picker UI.
142+
| `authorize()` | `Promise<AuthorizationResult>` | Requests the required permissions. Call it before calling `present()`. In case of a failed authorization, consider notifying the user for degraded functionality. The returned `AuthorizationResult` will have it's `authorized` property set to `true` if permission has been granted.
143+
| `present()` | `Promise<ImagePickerSelection[]>` | Presents the image picker UI.
136144
| `create(options: Options, hostView: View)` | `ImagePicker` | Creates an instance of the ImagePicker class. The `hostView` parameter can be set to the view that hosts the image picker. Intended to be used when opening the picker from a modal page.
137145

138146
### Options

0 commit comments

Comments
 (0)