richard-loafle 7a39d2e4aa bug fixed
2020-04-01 17:18:28 +09:00

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();
}
}
}