From f5ca1508fb9d95693615bfb9e03bc127bd83be00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thea=20Sch=C3=B6bl?= Date: Tue, 31 Jan 2023 13:39:29 +0100 Subject: [PATCH] fix: translate simple pipe doesn't update on language changes --- .../property-name-translate.pipe.ts | 88 +++++++++++++++ src/app/translation/thing-translate.module.ts | 26 +++-- src/app/translation/thing-translate.pipe.ts | 101 +----------------- src/app/translation/translate-simple.pipe.ts | 71 ++++++++++++ 4 files changed, 173 insertions(+), 113 deletions(-) create mode 100644 src/app/translation/property-name-translate.pipe.ts create mode 100644 src/app/translation/translate-simple.pipe.ts diff --git a/src/app/translation/property-name-translate.pipe.ts b/src/app/translation/property-name-translate.pipe.ts new file mode 100644 index 00000000..4b30b33e --- /dev/null +++ b/src/app/translation/property-name-translate.pipe.ts @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2023 StApps + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ +import {Injectable, OnDestroy, Pipe, PipeTransform} from '@angular/core'; +import {Subscription} from 'rxjs'; +import {TranslateService} from '@ngx-translate/core'; +import {ThingTranslateService} from './thing-translate.service'; +import {isThing, SCThings, SCThingType} from '@openstapps/core'; + +@Injectable() +@Pipe({ + name: 'propertyNameTranslate', + pure: false, // required to update the value when the promise is resolved +}) +export class PropertyNameTranslatePipe implements PipeTransform, OnDestroy { + value: unknown; + + lastKey?: string; + + lastType: string; + + onLangChange: Subscription; + + constructor( + private readonly translate: TranslateService, + private readonly thingTranslate: ThingTranslateService, + ) {} + + updateValue(key: string, type: string): void { + this.value = this.thingTranslate.getPropertyName(type as SCThingType, key); + } + + transform(query: unknown, thingOrType: SCThings | string | unknown): unknown { + if (typeof query !== 'string' || query.length <= 0) { + return query; + } + + if (!isThing(thingOrType) && typeof thingOrType !== 'string') { + throw new SyntaxError( + `Wrong parameter in ThingTranslatePipe. Expected a valid SCThing or String, received: ${thingOrType}`, + ); + } + + // store the params, in case they change + this.lastKey = query; + this.lastType = typeof thingOrType === 'string' ? thingOrType : thingOrType.type; + + this.updateValue(query, this.lastType); + + // if there is a subscription to onLangChange, clean it + this._dispose(); + + if (this.onLangChange?.closed ?? true) { + this.onLangChange = this.translate.onLangChange.subscribe(() => { + if (typeof this.lastKey === 'string') { + this.lastKey = undefined; // we want to make sure it doesn't return the same value until it's been updated + this.updateValue(query, this.lastType); + } + }); + } + + return this.value; + } + + /** + * Clean any existing subscription to change events + */ + private _dispose(): void { + if (this.onLangChange?.closed) { + this.onLangChange?.unsubscribe(); + } + } + + ngOnDestroy(): void { + this._dispose(); + } +} diff --git a/src/app/translation/thing-translate.module.ts b/src/app/translation/thing-translate.module.ts index a4083421..707c75e1 100644 --- a/src/app/translation/thing-translate.module.ts +++ b/src/app/translation/thing-translate.module.ts @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 StApps + * Copyright (C) 2023 StApps * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation, version 3. @@ -17,25 +17,23 @@ import {ModuleWithProviders, NgModule, Provider} from '@angular/core'; import { ArrayJoinPipe, DateLocalizedFormatPipe, - NumberLocalizedPipe, - MetersLocalizedPipe, - SentenceCasePipe, - StringSplitPipe, - OpeningHoursPipe, DurationLocalizedPipe, - ToUnixPipe, EntriesPipe, IsNaNPipe, IsNumericPipe, + MetersLocalizedPipe, + NumberLocalizedPipe, + OpeningHoursPipe, + SentenceCasePipe, + StringSplitPipe, + ToUnixPipe, } from './common-string-pipes'; import {ThingTranslateDefaultParser, ThingTranslateParser} from './thing-translate.parser'; -import { - ThingPropertyNameTranslatePipe, - ThingTranslatePipe, - TranslateSimplePipe, -} from './thing-translate.pipe'; +import {ThingTranslatePipe} from './thing-translate.pipe'; import {ThingTranslateService} from './thing-translate.service'; import {IonIconModule} from '../util/ion-icon/ion-icon.module'; +import {TranslateSimplePipe} from './translate-simple.pipe'; +import {PropertyNameTranslatePipe} from './property-name-translate.pipe'; export interface ThingTranslateModuleConfig { parser?: Provider; @@ -49,7 +47,7 @@ export interface ThingTranslateModuleConfig { NumberLocalizedPipe, MetersLocalizedPipe, StringSplitPipe, - ThingPropertyNameTranslatePipe, + PropertyNameTranslatePipe, ThingTranslatePipe, TranslateSimplePipe, DateLocalizedFormatPipe, @@ -67,7 +65,7 @@ export interface ThingTranslateModuleConfig { NumberLocalizedPipe, MetersLocalizedPipe, StringSplitPipe, - ThingPropertyNameTranslatePipe, + PropertyNameTranslatePipe, ThingTranslatePipe, TranslateSimplePipe, DateLocalizedFormatPipe, diff --git a/src/app/translation/thing-translate.pipe.ts b/src/app/translation/thing-translate.pipe.ts index 81ba7a13..d161f0ce 100644 --- a/src/app/translation/thing-translate.pipe.ts +++ b/src/app/translation/thing-translate.pipe.ts @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 StApps + * Copyright (C) 2023 StApps * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation, version 3. @@ -12,13 +12,11 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ - import {Injectable, OnDestroy, Pipe, PipeTransform} from '@angular/core'; import {TranslateService} from '@ngx-translate/core'; -import {isThing, SCThings, SCThingType, SCThingWithoutReferences} from '@openstapps/core'; +import {isThing, SCThings, SCThingWithoutReferences} from '@openstapps/core'; import {Subscription} from 'rxjs'; import {ThingTranslateService} from './thing-translate.service'; -import {get} from '../_helpers/collections/get'; @Injectable() @Pipe({ @@ -92,98 +90,3 @@ export class ThingTranslatePipe implements PipeTransform, OnDestroy { this._dispose(); } } - -@Injectable() -@Pipe({ - name: 'translateSimple', - pure: true, -}) -export class TranslateSimplePipe implements PipeTransform { - constructor(private readonly translate: TranslateService) {} - - // eslint-disable-next-line @typescript-eslint/ban-types - transform(query: string, value: object | unknown): unknown { - try { - return ( - get( - // eslint-disable-next-line @typescript-eslint/no-explicit-any - (value as any).translations[this.translate.currentLang] ?? value, - query, - ) ?? value - ); - } catch (error) { - console.warn(`${query}: ${error}`); - - return value; - } - } -} - -@Injectable() -@Pipe({ - name: 'propertyNameTranslate', - pure: false, // required to update the value when the promise is resolved -}) -export class ThingPropertyNameTranslatePipe implements PipeTransform, OnDestroy { - value: unknown; - - lastKey?: string; - - lastType: string; - - onLangChange: Subscription; - - constructor( - private readonly translate: TranslateService, - private readonly thingTranslate: ThingTranslateService, - ) {} - - updateValue(key: string, type: string): void { - this.value = this.thingTranslate.getPropertyName(type as SCThingType, key); - } - - transform(query: unknown, thingOrType: SCThings | string | unknown): unknown { - if (typeof query !== 'string' || query.length <= 0) { - return query; - } - - if (!isThing(thingOrType) && typeof thingOrType !== 'string') { - throw new SyntaxError( - `Wrong parameter in ThingTranslatePipe. Expected a valid SCThing or String, received: ${thingOrType}`, - ); - } - - // store the params, in case they change - this.lastKey = query; - this.lastType = typeof thingOrType === 'string' ? thingOrType : thingOrType.type; - - this.updateValue(query, this.lastType); - - // if there is a subscription to onLangChange, clean it - this._dispose(); - - if (this.onLangChange?.closed ?? true) { - this.onLangChange = this.translate.onLangChange.subscribe(() => { - if (typeof this.lastKey === 'string') { - this.lastKey = undefined; // we want to make sure it doesn't return the same value until it's been updated - this.updateValue(query, this.lastType); - } - }); - } - - return this.value; - } - - /** - * Clean any existing subscription to change events - */ - private _dispose(): void { - if (this.onLangChange?.closed) { - this.onLangChange?.unsubscribe(); - } - } - - ngOnDestroy(): void { - this._dispose(); - } -} diff --git a/src/app/translation/translate-simple.pipe.ts b/src/app/translation/translate-simple.pipe.ts new file mode 100644 index 00000000..0108a415 --- /dev/null +++ b/src/app/translation/translate-simple.pipe.ts @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2023 StApps + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ +import {Injectable, OnDestroy, Pipe, PipeTransform} from '@angular/core'; +import {TranslateService} from '@ngx-translate/core'; +import {get} from '../_helpers/collections/get'; +import {Subscription} from 'rxjs'; + +@Injectable() +@Pipe({ + name: 'translateSimple', + pure: false, +}) +export class TranslateSimplePipe implements PipeTransform, OnDestroy { + value: unknown; + + query: unknown; + + thing: unknown; + + onLangChange: Subscription; + + constructor(private readonly translate: TranslateService) {} + + // eslint-disable-next-line @typescript-eslint/ban-types + private updateValue() { + try { + this.value = + get( + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (this.thing as any).translations[this.translate.currentLang] ?? this.thing, + this.query as string, + ) ?? this.thing; + } catch (error) { + console.warn(`${this.query}: ${error}`); + this.value = this.thing; + } + } + + transform( + query: P, + thing: T, + ): P extends keyof T ? T[P] : P | unknown { + // store the params, in case they change + this.query = query; + this.thing = thing; + + this.updateValue(); + + this.onLangChange ??= this.translate.onLangChange.subscribe(() => { + this.updateValue(); + }); + + return this.value as never; + } + + ngOnDestroy(): void { + this.onLangChange?.unsubscribe(); + } +}