request geolocation perm

This commit is contained in:
ztimson 2019-07-11 14:54:08 -04:00
parent 197ff18efd
commit 3b0d69b4c9
6 changed files with 96 additions and 44 deletions

View File

@ -12,13 +12,15 @@ import {AgmCoreModule} from "@agm/core";
import {MaterialModule} from "./material.module"; import {MaterialModule} from "./material.module";
import {CalibrateComponent} from "./map/calibrate/calibrate.component"; import {CalibrateComponent} from "./map/calibrate/calibrate.component";
import {MatInputModule} from "@angular/material"; import {MatInputModule} from "@angular/material";
import {PermissionsComponent} from "./permissions/permissions.component";
@NgModule({ @NgModule({
declarations: [ declarations: [
AppComponent, AppComponent,
CalibrateComponent, CalibrateComponent,
HomeComponent, HomeComponent,
MapComponent MapComponent,
PermissionsComponent
], ],
imports: [ imports: [
AgmCoreModule.forRoot({apiKey: 'AIzaSyDFtvCY6nH_HUoTBNf_5b-E8nRweSLYtxE'}), AgmCoreModule.forRoot({apiKey: 'AIzaSyDFtvCY6nH_HUoTBNf_5b-E8nRweSLYtxE'}),
@ -31,7 +33,7 @@ import {MatInputModule} from "@angular/material";
MatInputModule, MatInputModule,
], ],
providers: [], providers: [],
entryComponents: [CalibrateComponent], entryComponents: [CalibrateComponent, PermissionsComponent],
bootstrap: [AppComponent] bootstrap: [AppComponent]
}) })
export class AppModule { export class AppModule {

View File

@ -1,6 +1,6 @@
import { import {
MatBottomSheetModule, MatBottomSheetModule,
MatButtonModule, MatDividerModule, MatFormFieldModule, MatButtonModule, MatDialogModule, MatDividerModule, MatFormFieldModule,
MatIconModule, MatInputModule, MatMenuModule, MatSliderModule, MatIconModule, MatInputModule, MatMenuModule, MatSliderModule,
MatSnackBarModule, MatSnackBarModule,
MatToolbarModule MatToolbarModule
@ -10,6 +10,7 @@ import {NgModule} from "@angular/core";
export const materialModules = [ export const materialModules = [
MatBottomSheetModule, MatBottomSheetModule,
MatButtonModule, MatButtonModule,
MatDialogModule,
MatDividerModule, MatDividerModule,
MatFormFieldModule, MatFormFieldModule,
MatIconModule, MatIconModule,

View File

@ -0,0 +1,10 @@
<div mat-dialog-content>
<div class="d-flex">
<div><mat-icon class="mr-2">{{icon}}</mat-icon></div>
<div><p class="d-inline">{{message}}</p></div>
</div>
</div>
<div mat-dialog-actions class="float-right">
<button mat-button [mat-dialog-close]="false">No Thanks</button>
<button mat-button [mat-dialog-close]="true">Ok</button>
</div>

View File

@ -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;
}
}

View File

@ -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'
}
}

View File

@ -1,6 +1,7 @@
import {EventEmitter, Injectable} from '@angular/core'; import {EventEmitter, Injectable} from '@angular/core';
import {BehaviorSubject, combineLatest} from "rxjs"; import {BehaviorSubject, combineLatest} from "rxjs";
import {debounceTime} from "rxjs/operators"; import {debounceTime} from "rxjs/operators";
import {PermissionsService} from "../permissions/permissions.service";
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
@ -17,53 +18,57 @@ export class PhysicsService {
position = new BehaviorSubject<Position>(null); position = new BehaviorSubject<Position>(null);
speed = new BehaviorSubject(null); speed = new BehaviorSubject(null);
constructor() { constructor(permissionsService: PermissionsService) {
// Gather physical data permissionsService.requestPermission('geolocation', 'gps_fixed', 'Can we use your location?').then(granted => {
window.addEventListener('deviceorientation', orientation => this.orientation.next(orientation)); if(granted) {
window.addEventListener('devicemotion', motion => this.motion.next(motion)); // Gather physical data
navigator.geolocation.watchPosition(position => this.position.next(position)); 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 // Calculate speed from motion events
this.motion.subscribe(event => { this.motion.subscribe(event => {
if (!this.motionTimestamp) return this.motionTimestamp = new Date().getTime(); if (!this.motionTimestamp) return this.motionTimestamp = new Date().getTime();
let currentTime = new Date().getTime(); let currentTime = new Date().getTime();
let {speedX, speedY, speedZ} = this.speed.value || {speedX: 0, speedY: 0, speedZ: 0}; let {speedX, speedY, speedZ} = this.speed.value || {speedX: 0, speedY: 0, speedZ: 0};
this.speed.next({ this.speed.next({
speedX: speedX + event.acceleration.x / 1000 * ((currentTime - this.motionTimestamp) / 1000) / 3600, speedX: speedX + event.acceleration.x / 1000 * ((currentTime - this.motionTimestamp) / 1000) / 3600,
speedY: speedY + event.acceleration.y / 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 speedZ: speedZ + event.acceleration.z / 1000 * ((currentTime - this.motionTimestamp) / 1000) / 3600
}); });
this.motionTimestamp = currentTime; this.motionTimestamp = currentTime;
}); });
// Combine data into one nice package // Combine data into one nice package
combineLatest(this.position, this.orientation, this.calibrate, this.speed).subscribe(data => { combineLatest(this.position, this.orientation, this.calibrate, this.speed).subscribe(data => {
if(!data[0]) return; if(!data[0]) return;
let info = { let info = {
accuracy: data[0].coords.accuracy, accuracy: data[0].coords.accuracy,
altitude: data[0].coords.altitude, altitude: data[0].coords.altitude,
altitudeAccuracy: data[0].coords.altitudeAccuracy, altitudeAccuracy: data[0].coords.altitudeAccuracy,
heading: data[0].coords.heading, heading: data[0].coords.heading,
latitude: data[0].coords.latitude, latitude: data[0].coords.latitude,
longitude: data[0].coords.longitude, longitude: data[0].coords.longitude,
speed: data[0].coords.speed speed: data[0].coords.speed
}; };
if(info.heading == null && !!data[1] && data[1].alpha) { if(info.heading == null && !!data[1] && data[1].alpha) {
if(!data[1].absolute && this.calibrate.value == null) { if(!data[1].absolute && this.calibrate.value == null) {
this.requireCalibration.emit(); this.requireCalibration.emit();
this.calibrate.next(0); this.calibrate.next(0);
} }
info.heading = data[1].alpha + this.calibrate.value; info.heading = data[1].alpha + this.calibrate.value;
if(info.heading > 360) info.heading -= 360; if(info.heading > 360) info.heading -= 360;
if(info.heading < 0) 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);
})
} }
} }