129 lines
2.9 KiB
TypeScript
129 lines
2.9 KiB
TypeScript
import { Subscription } from 'rxjs';
|
|
|
|
import {
|
|
Pipe,
|
|
PipeTransform,
|
|
Inject,
|
|
OnDestroy,
|
|
ChangeDetectorRef
|
|
} from '@angular/core';
|
|
|
|
import { StringMap, TOptions } from 'i18next';
|
|
|
|
import { I18nService } from '../services/i18n.service';
|
|
|
|
import { UCAP_I18N_NAMESPACE } from '../types/token';
|
|
import { ObjectUtil } from '../utils/object.util';
|
|
|
|
@Pipe({ name: 'ucapI18n', pure: false })
|
|
export class I18nPipe implements PipeTransform, OnDestroy {
|
|
private languageChangedSubscription: Subscription;
|
|
|
|
private value: string;
|
|
private lastKey: string | string[];
|
|
private lastOptions: TOptions<StringMap>;
|
|
|
|
constructor(
|
|
private i18nService: I18nService,
|
|
@Inject(UCAP_I18N_NAMESPACE) private ns: string | string[],
|
|
private changeDetectorRef: ChangeDetectorRef
|
|
) {}
|
|
|
|
ngOnDestroy(): void {
|
|
this.dispose();
|
|
}
|
|
|
|
public transform(
|
|
key: string | string[],
|
|
options?: TOptions<StringMap>
|
|
): string {
|
|
if (
|
|
ObjectUtil.equals(key, this.lastKey) &&
|
|
ObjectUtil.equals(options, this.lastOptions)
|
|
) {
|
|
return this.value;
|
|
}
|
|
|
|
options = options || {};
|
|
|
|
if (!!this.ns) {
|
|
key = this.keyWithPrependNamespace(
|
|
key,
|
|
this.ns,
|
|
this.i18nService.options.nsSeparator
|
|
);
|
|
}
|
|
|
|
this.lastKey = key;
|
|
this.lastOptions = options;
|
|
|
|
this.updateValue(key, options);
|
|
|
|
this.dispose();
|
|
|
|
if (!this.languageChangedSubscription) {
|
|
this.languageChangedSubscription = this.i18nService.languageChanged$.subscribe(
|
|
lng => {
|
|
this.updateValue(key, options);
|
|
}
|
|
);
|
|
}
|
|
|
|
return this.value;
|
|
}
|
|
|
|
private updateValue(key: string | string[], options?: TOptions<StringMap>) {
|
|
this.value = this.i18nService.t(key, options);
|
|
this.changeDetectorRef.markForCheck();
|
|
}
|
|
|
|
private keyWithPrependNamespace(
|
|
key: string | string[],
|
|
ns: string | string[],
|
|
nsSeparator: string | false
|
|
): string[] {
|
|
if (typeof key === 'string') {
|
|
key = [key];
|
|
}
|
|
if (typeof ns === 'string') {
|
|
ns = [ns];
|
|
}
|
|
|
|
if (
|
|
nsSeparator &&
|
|
typeof nsSeparator === 'boolean' &&
|
|
false === nsSeparator
|
|
) {
|
|
return key;
|
|
}
|
|
|
|
const keyWithPrependNamespace = [];
|
|
for (const k of key) {
|
|
if (!this.containsSeparator(k, nsSeparator as string)) {
|
|
keyWithPrependNamespace.push(
|
|
...ns.map(n =>
|
|
this.joinStringsWithSeparator(nsSeparator as string, n, k)
|
|
)
|
|
);
|
|
}
|
|
keyWithPrependNamespace.push(k);
|
|
}
|
|
|
|
return keyWithPrependNamespace;
|
|
}
|
|
|
|
private joinStringsWithSeparator(separator: string, ...str: string[]) {
|
|
return [...str].join(separator);
|
|
}
|
|
|
|
private containsSeparator(key: string, nsSeparator: string) {
|
|
return -1 !== key.indexOf(nsSeparator);
|
|
}
|
|
|
|
private dispose() {
|
|
if (!!this.languageChangedSubscription) {
|
|
this.languageChangedSubscription.unsubscribe();
|
|
}
|
|
}
|
|
}
|