diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 1762927..e24f342 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -12,13 +12,15 @@ import {AgmCoreModule} from "@agm/core";
import {MaterialModule} from "./material.module";
import {CalibrateComponent} from "./map/calibrate/calibrate.component";
import {MatInputModule} from "@angular/material";
+import {PermissionsComponent} from "./permissions/permissions.component";
@NgModule({
declarations: [
AppComponent,
CalibrateComponent,
HomeComponent,
- MapComponent
+ MapComponent,
+ PermissionsComponent
],
imports: [
AgmCoreModule.forRoot({apiKey: 'AIzaSyDFtvCY6nH_HUoTBNf_5b-E8nRweSLYtxE'}),
@@ -31,7 +33,7 @@ import {MatInputModule} from "@angular/material";
MatInputModule,
],
providers: [],
- entryComponents: [CalibrateComponent],
+ entryComponents: [CalibrateComponent, PermissionsComponent],
bootstrap: [AppComponent]
})
export class AppModule {
diff --git a/src/app/material.module.ts b/src/app/material.module.ts
index 0e77e35..2038d84 100644
--- a/src/app/material.module.ts
+++ b/src/app/material.module.ts
@@ -1,6 +1,6 @@
import {
MatBottomSheetModule,
- MatButtonModule, MatDividerModule, MatFormFieldModule,
+ MatButtonModule, MatDialogModule, MatDividerModule, MatFormFieldModule,
MatIconModule, MatInputModule, MatMenuModule, MatSliderModule,
MatSnackBarModule,
MatToolbarModule
@@ -10,6 +10,7 @@ import {NgModule} from "@angular/core";
export const materialModules = [
MatBottomSheetModule,
MatButtonModule,
+ MatDialogModule,
MatDividerModule,
MatFormFieldModule,
MatIconModule,
diff --git a/src/app/permissions/permissions.component.html b/src/app/permissions/permissions.component.html
new file mode 100644
index 0000000..ba55ffd
--- /dev/null
+++ b/src/app/permissions/permissions.component.html
@@ -0,0 +1,10 @@
+
+
+
+
+
diff --git a/src/app/permissions/permissions.component.ts b/src/app/permissions/permissions.component.ts
new file mode 100644
index 0000000..66f145c
--- /dev/null
+++ b/src/app/permissions/permissions.component.ts
@@ -0,0 +1,16 @@
+import { Component, Inject } from "@angular/core";
+import { MAT_DIALOG_DATA } from "@angular/material";
+
+@Component({
+ selector: 'permissions',
+ templateUrl: 'permissions.component.html'
+})
+export class PermissionsComponent {
+ icon: string;
+ message: string;
+
+ constructor(@Inject(MAT_DIALOG_DATA) data) {
+ this.icon = data.icon;
+ this.message = data.message;
+ }
+}
diff --git a/src/app/permissions/permissions.service.ts b/src/app/permissions/permissions.service.ts
new file mode 100644
index 0000000..1885563
--- /dev/null
+++ b/src/app/permissions/permissions.service.ts
@@ -0,0 +1,18 @@
+import {Injectable} from "@angular/core";
+import {MatDialog} from "@angular/material";
+import {PermissionsComponent} from "./permissions.component";
+
+@Injectable({
+ providedIn: 'root'
+})
+export class PermissionsService {
+ constructor(private dialog: MatDialog) { }
+
+ async requestPermission(name: string, icon: string, message: string) {
+ let perm = await navigator['permissions'].query({name: name});
+ if (perm.state == 'prompt') {
+ return await this.dialog.open(PermissionsComponent, {autoFocus: false, data: {icon: icon, message: message}}).afterClosed().toPromise();
+ }
+ return perm.state == 'granted'
+ }
+}
diff --git a/src/app/physics/physics.service.ts b/src/app/physics/physics.service.ts
index 407fb51..d799b44 100644
--- a/src/app/physics/physics.service.ts
+++ b/src/app/physics/physics.service.ts
@@ -1,6 +1,7 @@
import {EventEmitter, Injectable} from '@angular/core';
import {BehaviorSubject, combineLatest} from "rxjs";
import {debounceTime} from "rxjs/operators";
+import {PermissionsService} from "../permissions/permissions.service";
@Injectable({
providedIn: 'root'
@@ -17,53 +18,57 @@ export class PhysicsService {
position = new BehaviorSubject(null);
speed = new BehaviorSubject(null);
- constructor() {
- // Gather physical data
- window.addEventListener('deviceorientation', orientation => this.orientation.next(orientation));
- window.addEventListener('devicemotion', motion => this.motion.next(motion));
- navigator.geolocation.watchPosition(position => this.position.next(position));
+ constructor(permissionsService: PermissionsService) {
+ permissionsService.requestPermission('geolocation', 'gps_fixed', 'Can we use your location?').then(granted => {
+ if(granted) {
+ // Gather physical data
+ window.addEventListener('deviceorientation', orientation => this.orientation.next(orientation));
+ window.addEventListener('devicemotion', motion => this.motion.next(motion));
+ navigator.geolocation.watchPosition(position => this.position.next(position));
- // Calculate speed from motion events
- this.motion.subscribe(event => {
- if (!this.motionTimestamp) return this.motionTimestamp = new Date().getTime();
+ // Calculate speed from motion events
+ this.motion.subscribe(event => {
+ if (!this.motionTimestamp) return this.motionTimestamp = new Date().getTime();
- let currentTime = new Date().getTime();
- let {speedX, speedY, speedZ} = this.speed.value || {speedX: 0, speedY: 0, speedZ: 0};
- this.speed.next({
- speedX: speedX + event.acceleration.x / 1000 * ((currentTime - this.motionTimestamp) / 1000) / 3600,
- speedY: speedY + event.acceleration.y / 1000 * ((currentTime - this.motionTimestamp) / 1000) / 3600,
- speedZ: speedZ + event.acceleration.z / 1000 * ((currentTime - this.motionTimestamp) / 1000) / 3600
- });
- this.motionTimestamp = currentTime;
- });
+ let currentTime = new Date().getTime();
+ let {speedX, speedY, speedZ} = this.speed.value || {speedX: 0, speedY: 0, speedZ: 0};
+ this.speed.next({
+ speedX: speedX + event.acceleration.x / 1000 * ((currentTime - this.motionTimestamp) / 1000) / 3600,
+ speedY: speedY + event.acceleration.y / 1000 * ((currentTime - this.motionTimestamp) / 1000) / 3600,
+ speedZ: speedZ + event.acceleration.z / 1000 * ((currentTime - this.motionTimestamp) / 1000) / 3600
+ });
+ this.motionTimestamp = currentTime;
+ });
- // Combine data into one nice package
- combineLatest(this.position, this.orientation, this.calibrate, this.speed).subscribe(data => {
- if(!data[0]) return;
+ // Combine data into one nice package
+ combineLatest(this.position, this.orientation, this.calibrate, this.speed).subscribe(data => {
+ if(!data[0]) return;
- let info = {
- accuracy: data[0].coords.accuracy,
- altitude: data[0].coords.altitude,
- altitudeAccuracy: data[0].coords.altitudeAccuracy,
- heading: data[0].coords.heading,
- latitude: data[0].coords.latitude,
- longitude: data[0].coords.longitude,
- speed: data[0].coords.speed
- };
+ let info = {
+ accuracy: data[0].coords.accuracy,
+ altitude: data[0].coords.altitude,
+ altitudeAccuracy: data[0].coords.altitudeAccuracy,
+ heading: data[0].coords.heading,
+ latitude: data[0].coords.latitude,
+ longitude: data[0].coords.longitude,
+ speed: data[0].coords.speed
+ };
- if(info.heading == null && !!data[1] && data[1].alpha) {
- if(!data[1].absolute && this.calibrate.value == null) {
- this.requireCalibration.emit();
- this.calibrate.next(0);
- }
+ if(info.heading == null && !!data[1] && data[1].alpha) {
+ if(!data[1].absolute && this.calibrate.value == null) {
+ this.requireCalibration.emit();
+ this.calibrate.next(0);
+ }
- info.heading = data[1].alpha + this.calibrate.value;
- if(info.heading > 360) info.heading -= 360;
- if(info.heading < 0) info.heading += 360;
+ info.heading = data[1].alpha + this.calibrate.value;
+ if(info.heading > 360) info.heading -= 360;
+ if(info.heading < 0) info.heading += 360;
+ }
+ if(info.speed == null && !!data[3]) info.speed = Math.sqrt(data[3].x**2 + data[3].y**2 + data[3].z**2);
+
+ this.info.next(info);
+ })
}
- if(info.speed == null && !!data[3]) info.speed = Math.sqrt(data[3].x**2 + data[3].y**2 + data[3].z**2);
-
- this.info.next(info);
- })
+ });
}
}