angular-t9n
Version:
A translation tool for Angular i18n
89 lines (77 loc) • 3.11 kB
text/typescript
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { BehaviorSubject, combineLatest, Observable } from 'rxjs';
import { filter, map, switchMap, take, tap } from 'rxjs/operators';
import { environment } from '../../environments/environment';
import { RootResponse, TargetResponse } from '../../models';
import { TargetsResponse } from '../../models/targets-response';
import { WebsocketService } from './websocket.service';
({
providedIn: 'root',
})
export class TranslationService {
root: Observable<RootResponse>;
targets: Observable<TargetResponse[]>;
private _rootSubject = new BehaviorSubject<RootResponse | null>(null);
private _targetsSubject = new BehaviorSubject<TargetsResponse | null>(null);
private _targetsMap = new BehaviorSubject(new Map<string, TargetResponse>());
private _targets = this._targetsSubject.pipe(filter((r): r is TargetsResponse => !!r));
constructor(
private _http: HttpClient,
private _websocketService: WebsocketService,
) {
this.root = this._rootSubject.pipe(filter((r): r is RootResponse => !!r));
this.targets = this._targetsMap.pipe(map((t) => Array.from(t.values())));
this.root
.pipe(switchMap((r) => this._http.get<TargetsResponse>(r._links!.targets.href)))
.subscribe((targets) => this._targetsSubject.next(targets));
this._targets
.pipe(switchMap((t) => this._loadTargets(t)))
.subscribe((m) => this._targetsMap.next(m));
this._websocketService.projectChange
.pipe(switchMap(() => this._http.get<RootResponse>(`${environment.translationServer}/api`)))
.subscribe((r) => this._rootSubject.next(r));
}
target(language: string): Observable<TargetResponse | undefined> {
return this._targetsMap.pipe(map((t) => t.get(language)));
}
createTarget(language: string) {
return this._targets.pipe(
take(1),
map((r) => this._targetHref(r, language)),
switchMap((href) => this._http.post<TargetResponse>(href, {})),
tap((t) => this._updateTarget(t)),
);
}
updateTarget(language: string) {
return this._targets.pipe(
map((r) => this._targetHref(r, language)),
switchMap((href) => this._http.get<TargetResponse>(href)),
tap((t) => this._updateTarget(t)),
);
}
private _loadTargets(targetsResponse: TargetsResponse) {
return combineLatest(
targetsResponse.languages
.map((l) => this._targetHref(targetsResponse, l))
.map((href) => this._http.get<TargetResponse>(href)),
).pipe(
map((targets) =>
targets.reduce(
(current, next) => current.set(next.language, next),
new Map<string, TargetResponse>(),
),
),
);
}
private _targetHref(targets: TargetsResponse, language: string) {
return targets._links!.target.href.replace('{language}', language);
}
private _updateTarget(target: TargetResponse) {
const targets = new Map<string, TargetResponse>(this._targetsMap.value).set(
target.language,
target,
);
this._targetsMap.next(targets);
}
}