diff --git a/src/app/modules/data/list/food-data-list.component.ts b/src/app/modules/data/list/food-data-list.component.ts
index 39995295..4f260d72 100644
--- a/src/app/modules/data/list/food-data-list.component.ts
+++ b/src/app/modules/data/list/food-data-list.component.ts
@@ -13,7 +13,9 @@
* this program. If not, see .
*/
import {Component} from '@angular/core';
+import {MapPosition} from '../../map/position.service';
import {SearchPageComponent} from './search-page.component';
+import {Geolocation} from '@capacitor/geolocation';
/**
* Presents a list of places for eating/drinking
@@ -91,4 +93,28 @@ export class FoodDataListComponent extends SearchPageComponent {
];
}
}
+
+ async ionViewWillEnter() {
+ await super.ionViewWillEnter();
+ this.subscriptions.push(
+ this.positionService
+ .watchCurrentLocation(this.constructor.name, {enableHighAccuracy: false, maximumAge: 1000})
+ .subscribe({
+ next: (position: MapPosition) => {
+ this.positionService.position = position;
+ },
+ error: async _error => {
+ this.positionService.position = undefined;
+ await Geolocation.checkPermissions();
+ },
+ }),
+ );
+ }
+
+ ionViewWillLeave() {
+ void this.positionService.clearWatcher(this.constructor.name);
+ for (const sub of this.subscriptions) {
+ sub.unsubscribe();
+ }
+ }
}
diff --git a/src/app/modules/map/page/map-page.component.ts b/src/app/modules/map/page/map-page.component.ts
index 32a15627..b2628d34 100644
--- a/src/app/modules/map/page/map-page.component.ts
+++ b/src/app/modules/map/page/map-page.component.ts
@@ -260,6 +260,11 @@ export class MapPageComponent {
* Subscribe to needed observables and get the location status when user is entering the page
*/
async ionViewWillEnter() {
+ if (this.positionService.position) {
+ this.position = this.positionService.position;
+ this.positionMarker = MapProvider.getPositionMarker(this.position, 'stapps-device-location', 32);
+ }
+
this.subscriptions.push(
this.dataRoutingService.itemSelectListener().subscribe(async item => {
// in case the list item is clicked
@@ -269,17 +274,19 @@ export class MapPageComponent {
void this.router.navigate(['/data-detail', item.uid]);
}
}),
- this.positionService.watchCurrentLocation({maximumAge: 3000}).subscribe({
- next: (position: MapPosition) => {
- this.position = position;
- this.positionMarker = MapProvider.getPositionMarker(position, 'stapps-device-location', 32);
- },
- error: async _error => {
- this.locationStatus = await Geolocation.checkPermissions();
- // eslint-disable-next-line unicorn/no-null
- this.position = null;
- },
- }),
+ this.positionService
+ .watchCurrentLocation(this.constructor.name, {enableHighAccuracy: true, maximumAge: 1000})
+ .subscribe({
+ next: (position: MapPosition) => {
+ this.position = position;
+ this.positionMarker = MapProvider.getPositionMarker(position, 'stapps-device-location', 32);
+ },
+ error: async _error => {
+ this.locationStatus = await Geolocation.checkPermissions();
+ // eslint-disable-next-line unicorn/no-null
+ this.position = null;
+ },
+ }),
);
// get detailed location status (diagnostics only supports devices)
@@ -290,6 +297,7 @@ export class MapPageComponent {
* Unsubscribe from all subscriptions when user leaves page
*/
ionViewWillLeave() {
+ void this.positionService.clearWatcher(this.constructor.name);
for (const sub of this.subscriptions) {
sub.unsubscribe();
}
diff --git a/src/app/modules/map/page/map-page.html b/src/app/modules/map/page/map-page.html
index 606e7340..52b9aceb 100644
--- a/src/app/modules/map/page/map-page.html
+++ b/src/app/modules/map/page/map-page.html
@@ -96,12 +96,12 @@
-
-
+
+
diff --git a/src/app/modules/map/position.service.spec.ts b/src/app/modules/map/position.service.spec.ts
index 23c376d6..9a165eb9 100644
--- a/src/app/modules/map/position.service.spec.ts
+++ b/src/app/modules/map/position.service.spec.ts
@@ -58,9 +58,30 @@ describe('PositionService', () => {
});
it('should continuously provide (watch) location of the device', done => {
- positionService.watchCurrentLocation().subscribe(location => {
+ positionService.watchCurrentLocation('testCaller').subscribe(location => {
expect(location).toBeDefined();
done();
});
});
+
+ it('should stop to continuously provide (watch) location of the device', done => {
+ positionService.watchers.set(
+ 'clearWatch',
+ new Promise(resolve => {
+ setTimeout(function () {
+ resolve(`watcherID123`);
+ }, 20);
+ }),
+ );
+ positionService
+ .clearWatcher('clearWatch')
+ .then(result => {
+ expect(result).toBeUndefined();
+ done();
+ })
+ .catch(error => {
+ expect(error).toBeUndefined();
+ done();
+ });
+ });
});
diff --git a/src/app/modules/map/position.service.ts b/src/app/modules/map/position.service.ts
index 35eabab2..1a3316f2 100644
--- a/src/app/modules/map/position.service.ts
+++ b/src/app/modules/map/position.service.ts
@@ -45,6 +45,11 @@ export class PositionService {
*/
position?: MapPosition;
+ /**
+ * Map of callers and their running watchers. Both by their ID
+ */
+ watchers: Map> = new Map();
+
/**
* Gets current coordinates information of the device
*
@@ -84,19 +89,19 @@ export class PositionService {
/**
* Watches (continuously gets) current coordinates information of the device
*
+ * @param caller Identifier for later reference. (I.e use of `clearWatcher`)
* @param options Options which define which data should be provided (e.g. how accurate or how old)
*/
- watchCurrentLocation(options: PositionOptions = {}): Observable {
+ watchCurrentLocation(caller: string, options: PositionOptions = {}): Observable {
return new Observable(subscriber => {
- void Geolocation.watchPosition(options, (position, error) => {
+ const watcherID = Geolocation.watchPosition(options, (position, error) => {
if (error) {
subscriber.error(position);
} else {
this.position = {
- heading:
- Number.isNaN(position?.coords.heading) || position?.coords.heading == undefined
- ? undefined
- : position.coords.heading,
+ // TODO use native compass heading instead
+ // waiting for https://github.com/ionic-team/capacitor-plugins/issues/1192
+ heading: undefined,
latitude: position?.coords.latitude ?? 0,
longitude: position?.coords.longitude ?? 0, // TODO: handle null position
};
@@ -104,6 +109,19 @@ export class PositionService {
subscriber.next(this.position);
}
});
+ this.watchers.set(caller, watcherID);
});
}
+
+ /**
+ * Clears watcher for a certain caller
+ *
+ * @param caller Identifier of the caller wanting to clear the watcher
+ */
+ async clearWatcher(caller: string): Promise {
+ const watcherID = await this.watchers.get(caller);
+ if (watcherID) {
+ Geolocation.clearWatch({id: watcherID});
+ }
+ }
}