mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2026-01-23 01:53:00 +00:00
feat: change map page feat: add error handling and timeout to location fetching in directions resolves #124 resolves #122
93 lines
3.4 KiB
TypeScript
93 lines
3.4 KiB
TypeScript
import {Directive, HostListener, Input} from '@angular/core';
|
|
import {SCPlaceWithoutReferences, SCThings, SCThingWithoutReferences} from '@openstapps/core';
|
|
import {Device} from '@capacitor/device';
|
|
import {ActionSheetController, ActionSheetOptions, ToastController} from '@ionic/angular';
|
|
import {TranslateService} from '@ngx-translate/core';
|
|
import {ThingTranslateService} from '../../translation/thing-translate.service';
|
|
import {Clipboard} from '@capacitor/clipboard';
|
|
import {PositionService} from './position.service';
|
|
|
|
/**
|
|
* A button that provides navigation options to the user via an action sheet
|
|
* @example
|
|
* <ion-button shape="round" [geoNavigation]="place">
|
|
* <ion-icon name="directions" slot="start"></ion-icon>
|
|
* <ion-label>{{'map.directions.TITLE' | translate}}</ion-label>
|
|
* </ion-button>
|
|
*/
|
|
@Directive({
|
|
selector: '[geoNavigation]',
|
|
standalone: true,
|
|
})
|
|
export class GeoNavigationDirective {
|
|
@Input({required: true}) geoNavigation: SCThingWithoutReferences &
|
|
Pick<SCPlaceWithoutReferences, 'geo' | 'address'>;
|
|
|
|
constructor(
|
|
private actionSheetController: ActionSheetController,
|
|
private translateService: TranslateService,
|
|
private thingTranslate: ThingTranslateService,
|
|
private toastController: ToastController,
|
|
private positionService: PositionService,
|
|
) {}
|
|
|
|
@HostListener('click', ['$event'])
|
|
async presentActionSheet(event: Event) {
|
|
event.stopPropagation();
|
|
const {operatingSystem} = await Device.getInfo();
|
|
const [lon, lat] = this.geoNavigation.geo.point.coordinates;
|
|
|
|
const supportedMapProviders =
|
|
operatingSystem === 'mac' || operatingSystem === 'ios'
|
|
? ['OSM_ROUTING', 'APPLE_MAPS', 'GOOGLE_MAPS']
|
|
: ['OSM_ROUTING', 'GOOGLE_MAPS'];
|
|
const address = this.geoNavigation.address
|
|
? this.translateService.instant(
|
|
'map.directions.ADDRESS',
|
|
this.thingTranslate.get(this.geoNavigation as SCThings, 'address'),
|
|
)
|
|
: `${lat}, ${lon}`;
|
|
|
|
const options: ActionSheetOptions = {
|
|
header: this.translateService.instant('map.directions.TITLE_LONG', {
|
|
name: this.thingTranslate.get(this.geoNavigation as SCThings, 'name'),
|
|
}),
|
|
subHeader: address,
|
|
buttons: [
|
|
{
|
|
text: this.translateService.instant('map.directions.COPY_ADDRESS'),
|
|
role: 'selected',
|
|
handler: async () => {
|
|
await Clipboard.write({string: address});
|
|
this.toastController
|
|
.create({
|
|
message: this.translateService.instant('map.directions.ADDRESS_COPIED'),
|
|
duration: 500,
|
|
})
|
|
.then(toast => toast.present());
|
|
},
|
|
},
|
|
...supportedMapProviders.map(provider => ({
|
|
text: this.translateService.instant(`map.directions.${provider}.TITLE`),
|
|
handler: () => {
|
|
const url: string = this.translateService.instant(`map.directions.${provider}.URL`, {
|
|
lat,
|
|
lon,
|
|
posLat: this.positionService.position?.latitude ?? 0,
|
|
posLon: this.positionService.position?.longitude ?? 0,
|
|
});
|
|
window.open(url.replace(/&?\w+=0,0/, ''), '_blank', 'noreferrer');
|
|
},
|
|
})),
|
|
{
|
|
text: this.translateService.instant('abort'),
|
|
role: 'cancel',
|
|
},
|
|
],
|
|
};
|
|
|
|
const actionSheet = await this.actionSheetController.create(options);
|
|
await actionSheet.present();
|
|
}
|
|
}
|