request geolocation perm
This commit is contained in:
		@@ -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 {
 | 
			
		||||
 
 | 
			
		||||
@@ -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,
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								src/app/permissions/permissions.component.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/app/permissions/permissions.component.html
									
									
									
									
									
										Normal 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>
 | 
			
		||||
							
								
								
									
										16
									
								
								src/app/permissions/permissions.component.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/app/permissions/permissions.component.ts
									
									
									
									
									
										Normal 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;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										18
									
								
								src/app/permissions/permissions.service.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								src/app/permissions/permissions.service.ts
									
									
									
									
									
										Normal 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'
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -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<Position>(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);
 | 
			
		||||
        })
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user