refactor: improve display of distances

This commit is contained in:
Rainer Killinger
2021-08-10 13:19:14 +02:00
parent bbd20effb6
commit a811bf9f4f
4 changed files with 100 additions and 19 deletions

View File

@@ -15,6 +15,7 @@
import {Component, Input} from '@angular/core'; import {Component, Input} from '@angular/core';
import {SCBuilding, SCFloor, SCPointOfInterest, SCRoom} from '@openstapps/core'; import {SCBuilding, SCFloor, SCPointOfInterest, SCRoom} from '@openstapps/core';
import {PositionService} from '../../../map/position.service'; import {PositionService} from '../../../map/position.service';
import {Subscription, interval} from 'rxjs';
type placeTypes = (SCBuilding | SCRoom | SCPointOfInterest | SCFloor) & { type placeTypes = (SCBuilding | SCRoom | SCPointOfInterest | SCFloor) & {
distance?: number; distance?: number;
@@ -51,6 +52,9 @@ export class PlaceListItemComponent {
this._item = item; this._item = item;
if (!isSCFloor(item)) { if (!isSCFloor(item)) {
this.distance = this.positionService.getDistance(item.geo.point); this.distance = this.positionService.getDistance(item.geo.point);
this.distanceSubscription = interval(10_000).subscribe(_ => {
this.distance = this.positionService.getDistance(item.geo.point);
});
} }
} }
@@ -64,5 +68,7 @@ export class PlaceListItemComponent {
*/ */
distance?: number; distance?: number;
distanceSubscription?: Subscription;
constructor(private positionService: PositionService) {} constructor(private positionService: PositionService) {}
} }

View File

@@ -20,12 +20,8 @@
}} }}
</li> </li>
<li *ngIf="distance"> <li *ngIf="distance">
<ion-icon name="walk"></ion-icon <ion-icon name="walk"></ion-icon>
>{{ {{ distance | metersLocalized }}
distance
| numberLocalized
: 'style:unit,unit:meter,notation:compact'
}}
</li> </li>
</ul> </ul>
</ion-note> </ion-note>
@@ -37,12 +33,8 @@
{{ 'type' | thingTranslate: item }} {{ 'type' | thingTranslate: item }}
</li> </li>
<li *ngIf="distance"> <li *ngIf="distance">
<ion-icon name="walk"></ion-icon <ion-icon name="walk"></ion-icon>
>{{ {{ distance | metersLocalized }}
distance
| numberLocalized
: 'style:unit,unit:meter,notation:compact'
}}
</li> </li>
</ul> </ul>
</ion-note> </ion-note>

View File

@@ -25,7 +25,7 @@ const openingHoursFn = require('opening_hours');
@Injectable() @Injectable()
@Pipe({ @Pipe({
name: 'join', name: 'join',
pure: false, // required to update the value when the promise is resolved pure: true,
}) })
export class ArrayJoinPipe implements PipeTransform { export class ArrayJoinPipe implements PipeTransform {
value = ''; value = '';
@@ -50,7 +50,7 @@ export class ArrayJoinPipe implements PipeTransform {
@Injectable() @Injectable()
@Pipe({ @Pipe({
name: 'sentencecase', name: 'sentencecase',
pure: false, // required to update the value when the promise is resolved pure: true,
}) })
export class SentenceCasePipe implements PipeTransform { export class SentenceCasePipe implements PipeTransform {
value = ''; value = '';
@@ -71,7 +71,7 @@ export class SentenceCasePipe implements PipeTransform {
@Injectable() @Injectable()
@Pipe({ @Pipe({
name: 'split', name: 'split',
pure: false, // required to update the value when the promise is resolved pure: true,
}) })
export class StringSplitPipe implements PipeTransform { export class StringSplitPipe implements PipeTransform {
value = new Array<unknown>(); value = new Array<unknown>();
@@ -96,9 +96,9 @@ export class StringSplitPipe implements PipeTransform {
@Injectable() @Injectable()
@Pipe({ @Pipe({
name: 'openingHours', name: 'openingHours',
pure: false, // required to update the value when the promise is resolved pure: false,
}) })
export class OpeningHoursPipe implements PipeTransform { export class OpeningHoursPipe implements PipeTransform, OnDestroy {
locale: string; locale: string;
onLangChange?: Subscription; onLangChange?: Subscription;
@@ -115,6 +115,10 @@ export class OpeningHoursPipe implements PipeTransform {
} }
} }
ngOnDestroy(): void {
this._dispose();
}
transform(aString: string | unknown): string { transform(aString: string | unknown): string {
this.updateValue(aString); this.updateValue(aString);
this._dispose(); this._dispose();
@@ -165,10 +169,86 @@ export class OpeningHoursPipe implements PipeTransform {
} }
} }
@Injectable()
@Pipe({
name: 'metersLocalized',
pure: false,
})
export class MetersLocalizedPipe implements PipeTransform, OnDestroy {
locale: string;
onLangChange?: Subscription;
value = '';
constructor(private readonly translate: TranslateService) {
this.locale = translate.currentLang;
}
private _dispose(): void {
if (this.onLangChange?.closed === false) {
this.onLangChange?.unsubscribe();
}
}
ngOnDestroy(): void {
this._dispose();
}
transform(value: string | number | unknown): string {
this.updateValue(value);
this._dispose();
if (this.onLangChange?.closed === true) {
this.onLangChange = this.translate.onLangChange.subscribe(
(event: LangChangeEvent) => {
this.locale = event.lang;
this.updateValue(value);
},
);
}
return this.value;
}
updateValue(value: string | number | unknown) {
if (typeof value !== 'string' && typeof value !== 'number') {
logger.warn(`metersLocalized pipe unable to parse input: ${value}`);
return;
}
const imperialLocale = ['US', 'UK', 'LR', 'MM'].some(term =>
this.locale.includes(term),
);
const meters =
typeof value === 'string' ? Number.parseFloat(value) : (value as number);
if (imperialLocale) {
const yards = meters * 1.0936;
const options = {
style: 'unit',
unit: yards >= 1760 ? 'mile' : 'yard',
maximumFractionDigits: yards >= 1760 ? 1 : 0,
} as unknown as Intl.NumberFormatOptions;
this.value = new Intl.NumberFormat(this.locale, options).format(
yards >= 1760 ? yards / 1760 : yards,
);
} else {
const options = {
style: 'unit',
unit: meters >= 1000 ? 'kilometer' : 'meter',
maximumFractionDigits: meters >= 1000 ? 1 : 0,
} as unknown as Intl.NumberFormatOptions;
this.value = new Intl.NumberFormat(this.locale, options).format(
meters >= 1000 ? meters / 1000 : meters,
);
}
}
}
@Injectable() @Injectable()
@Pipe({ @Pipe({
name: 'numberLocalized', name: 'numberLocalized',
pure: false, // required to update the value when the promise is resolved pure: false,
}) })
export class NumberLocalizedPipe implements PipeTransform, OnDestroy { export class NumberLocalizedPipe implements PipeTransform, OnDestroy {
locale: string; locale: string;
@@ -237,7 +317,7 @@ export class NumberLocalizedPipe implements PipeTransform, OnDestroy {
@Injectable() @Injectable()
@Pipe({ @Pipe({
name: 'dateFormat', name: 'dateFormat',
pure: false, // required to update the value when the promise is resolved pure: false,
}) })
export class DateLocalizedFormatPipe implements PipeTransform, OnDestroy { export class DateLocalizedFormatPipe implements PipeTransform, OnDestroy {
locale: string; locale: string;

View File

@@ -18,6 +18,7 @@ import {
ArrayJoinPipe, ArrayJoinPipe,
DateLocalizedFormatPipe, DateLocalizedFormatPipe,
NumberLocalizedPipe, NumberLocalizedPipe,
MetersLocalizedPipe,
SentenceCasePipe, SentenceCasePipe,
StringSplitPipe, StringSplitPipe,
OpeningHoursPipe, OpeningHoursPipe,
@@ -40,6 +41,7 @@ export interface ThingTranslateModuleConfig {
declarations: [ declarations: [
ArrayJoinPipe, ArrayJoinPipe,
NumberLocalizedPipe, NumberLocalizedPipe,
MetersLocalizedPipe,
StringSplitPipe, StringSplitPipe,
ThingPropertyNameTranslatePipe, ThingPropertyNameTranslatePipe,
ThingTranslatePipe, ThingTranslatePipe,
@@ -50,6 +52,7 @@ export interface ThingTranslateModuleConfig {
exports: [ exports: [
ArrayJoinPipe, ArrayJoinPipe,
NumberLocalizedPipe, NumberLocalizedPipe,
MetersLocalizedPipe,
StringSplitPipe, StringSplitPipe,
ThingPropertyNameTranslatePipe, ThingPropertyNameTranslatePipe,
ThingTranslatePipe, ThingTranslatePipe,