import {
Pipe,
PipeTransform,
ChangeDetectorRef
} from '@angular/core'
import {
RccTranslationService
} from './translations.service'
import {
extendTranslationKey,
TranslationKey,
Translator
} from '../nong'
/**
* This pipe is just the pipe version of {@link RccTranslationService.translate()}.
* You cannot specify a language. It will always translate to {@link RccTranslationService.activeLanguage}
*/
@Pipe({
name: 'translate',
pure: false
})
export class RccTranslatePipe implements PipeTransform {
protected lastResult : string
protected lastInput : unknown
protected lastParam : Record<string, unknown>
protected lastTranslator : Translator
protected lastHash : string | null
constructor(
private rccTranslationService : RccTranslationService,
private changeDetectorRef : ChangeDetectorRef
){
this.rccTranslationService.activeLanguageChange$
.subscribe( () => this.reset() )
}
reset() : void {
this.lastResult = null
this.lastTranslator = null
this.lastInput = null
this.lastParam = null
this.lastHash = null
}
update(input: unknown, param?:Record<string,unknown>, language?: string): void {
const [text, translator] = this.rccTranslationService.getTranslationData(input, param, language)
const hash = translator
? translator.hash(input, param)
: null // translation failed
this.lastTranslator = translator
this.lastResult = text || String(input)
this.lastInput = input
this.lastHash = hash
}
transform(input: unknown, param?:Record<string,unknown>, language?: string): string {
// Since this pipe is NOT pure, it is probably a good idea to cache results.
// We could do the caching in the .translate() method of RccTranslationService,
// but then all input values would be stored there forever, whereas values stored on the
// pipe should be deleted when the pipe gets destroyed.
if(this.lastInput != input) { this.update(input, param, language); return this.lastResult }
// Translation failed last time, no reason to try again:
if(!this.lastTranslator) return this.lastResult
const hash = this.lastTranslator.hash(input,param)
if(this.lastHash != hash) { this.update(input, param, language); return this.lastResult }
return this.lastResult
}
}
/**
* This pipe is meant for basic replacements in translation strings.
* Occurrences of %_n_ , with _n_ being some integer, will be replaced by the _n_-th parameter, starting at 1.
* Occurrences of %_s_ with _s_ being a single lowercase letter, will be replaced by the parameters in the order of their appearance.
* The replacement text will only include capital letters, digits and underscored, everything else will be stripped off:
* ```
* {{ 'SOME_SCOPE.%s' | fill: paused ? 'player_running':'player_paused' }} // yields 'SOME_SCOPE.PLAYER_PAUSED' if pause is truthy.
*
* {{ 'SOME_SCOPE.GROUP_%2.LABEL_%1' | fill : 'long', 1}} // yields 'SOME_SCOPE.GROUP_1.LABEL_LONG'.
*
* {{ 'SOME_SCOPE.GROUP_%s.LABEL_%t' | fill : 'long', 1}} // yields 'SOME_SCOPE.GROUP_LONG.LABEL_1'.
*
* ```
**/
@Pipe({ name: 'fill' })
export class RccFillPipe implements PipeTransform {
transform(translationKey : TranslationKey, ...content: string[]) : TranslationKey {
return extendTranslationKey(translationKey, ...content)
}
}