Skip to content

Commit

Permalink
Add server localization
Browse files Browse the repository at this point in the history
  • Loading branch information
Chocobozzz committed Jun 6, 2018
1 parent f07d638 commit 7ce44a7
Show file tree
Hide file tree
Showing 12 changed files with 1,080 additions and 471 deletions.
76 changes: 52 additions & 24 deletions client/src/app/core/server/server.service.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,28 @@
import { tap } from 'rxjs/operators'
import { map, share, switchMap, tap } from 'rxjs/operators'
import { HttpClient } from '@angular/common/http'
import { Injectable } from '@angular/core'
import { Inject, Injectable, LOCALE_ID } from '@angular/core'
import { peertubeLocalStorage } from '@app/shared/misc/peertube-local-storage'
import { ReplaySubject } from 'rxjs'
import { Observable, ReplaySubject } from 'rxjs'
import { ServerConfig } from '../../../../../shared'
import { About } from '../../../../../shared/models/server/about.model'
import { environment } from '../../../environments/environment'
import { VideoConstant, VideoPrivacy } from '../../../../../shared/models/videos'
import { buildFileLocale, getDefaultLocale } from '../../../../../shared/models/i18n'
import { peertubeTranslate } from '@app/shared/i18n/i18n-utils'

@Injectable()
export class ServerService {
private static BASE_CONFIG_URL = environment.apiUrl + '/api/v1/config/'
private static BASE_VIDEO_URL = environment.apiUrl + '/api/v1/videos/'
private static BASE_LOCALE_URL = environment.apiUrl + '/client/locales/'
private static CONFIG_LOCAL_STORAGE_KEY = 'server-config'

configLoaded = new ReplaySubject<boolean>(1)
videoPrivaciesLoaded = new ReplaySubject<boolean>(1)
videoCategoriesLoaded = new ReplaySubject<boolean>(1)
videoLicencesLoaded = new ReplaySubject<boolean>(1)
videoLanguagesLoaded = new ReplaySubject<boolean>(1)
localeObservable: Observable<any>

private config: ServerConfig = {
instance: {
Expand Down Expand Up @@ -64,8 +68,12 @@ export class ServerService {
private videoLanguages: Array<VideoConstant<string>> = []
private videoPrivacies: Array<VideoConstant<VideoPrivacy>> = []

constructor (private http: HttpClient) {
constructor (
private http: HttpClient,
@Inject(LOCALE_ID) private localeId: string
) {
this.loadConfigLocally()
this.loadServerLocale()
}

loadConfig () {
Expand Down Expand Up @@ -124,26 +132,46 @@ export class ServerService {
notifier: ReplaySubject<boolean>,
sort = false
) {
return this.http.get(ServerService.BASE_VIDEO_URL + attributeName)
.subscribe(data => {
Object.keys(data)
.forEach(dataKey => {
hashToPopulate.push({
id: dataKey,
label: data[dataKey]
})
})

if (sort === true) {
hashToPopulate.sort((a, b) => {
if (a.label < b.label) return -1
if (a.label === b.label) return 0
return 1
})
}

notifier.next(true)
})
this.localeObservable
.pipe(
switchMap(translations => {
return this.http.get(ServerService.BASE_VIDEO_URL + attributeName)
.pipe(map(data => ({ data, translations })))
})
)
.subscribe(({ data, translations }) => {
Object.keys(data)
.forEach(dataKey => {
const label = data[ dataKey ]

hashToPopulate.push({
id: dataKey,
label: peertubeTranslate(label, translations)
})
})

if (sort === true) {
hashToPopulate.sort((a, b) => {
if (a.label < b.label) return -1
if (a.label === b.label) return 0
return 1
})
}

notifier.next(true)
})
}

private loadServerLocale () {
const fileLocale = buildFileLocale(environment.production === true ? this.localeId : 'fr')

// Default locale, nothing to translate
const defaultFileLocale = buildFileLocale(getDefaultLocale())
if (fileLocale === defaultFileLocale) return {}

this.localeObservable = this.http
.get(ServerService.BASE_LOCALE_URL + fileLocale + '/server.json')
.pipe(share())
}

private saveConfigLocally (config: ServerConfig) {
Expand Down
7 changes: 7 additions & 0 deletions client/src/app/shared/i18n/i18n-utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
function peertubeTranslate (str: string, translations: { [ id: string ]: string }) {
return translations[str] ? translations[str] : str
}

export {
peertubeTranslate
}
4 changes: 2 additions & 2 deletions client/src/app/shared/video/video-details.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ export class VideoDetails extends Video implements VideoDetailsServerModel {
likesPercent: number
dislikesPercent: number

constructor (hash: VideoDetailsServerModel) {
super(hash)
constructor (hash: VideoDetailsServerModel, translations = {}) {
super(hash, translations)

this.descriptionPath = hash.descriptionPath
this.files = hash.files
Expand Down
8 changes: 7 additions & 1 deletion client/src/app/shared/video/video.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { VideoConstant } from '../../../../../shared/models/videos/video.model'
import { getAbsoluteAPIUrl } from '../misc/utils'
import { ServerConfig } from '../../../../../shared/models'
import { Actor } from '@app/shared/actor/actor.model'
import { peertubeTranslate } from '@app/shared/i18n/i18n-utils'

export class Video implements VideoServerModel {
by: string
Expand Down Expand Up @@ -68,7 +69,7 @@ export class Video implements VideoServerModel {
minutes.toString() + ':' + secondsPadding + seconds.toString()
}

constructor (hash: VideoServerModel) {
constructor (hash: VideoServerModel, translations = {}) {
const absoluteAPIUrl = getAbsoluteAPIUrl()

this.createdAt = new Date(hash.createdAt.toString())
Expand Down Expand Up @@ -98,6 +99,11 @@ export class Video implements VideoServerModel {

this.by = Actor.CREATE_BY_STRING(hash.account.name, hash.account.host)
this.accountAvatarUrl = Actor.GET_ACTOR_AVATAR_URL(this.account)

this.category.label = peertubeTranslate(this.category.label, translations)
this.licence.label = peertubeTranslate(this.licence.label, translations)
this.language.label = peertubeTranslate(this.language.label, translations)
this.privacy.label = peertubeTranslate(this.privacy.label, translations)
}

isVideoNSFWForUser (user: User, serverConfig: ServerConfig) {
Expand Down
56 changes: 34 additions & 22 deletions client/src/app/shared/video/video.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { catchError, map } from 'rxjs/operators'
import { catchError, map, switchMap } from 'rxjs/operators'
import { HttpClient, HttpParams, HttpRequest } from '@angular/common/http'
import { Injectable } from '@angular/core'
import { Observable } from 'rxjs'
Expand All @@ -24,6 +24,7 @@ import { Account } from '@app/shared/account/account.model'
import { AccountService } from '@app/shared/account/account.service'
import { VideoChannel } from '../../../../../shared/models/videos'
import { VideoChannelService } from '@app/shared/video-channel/video-channel.service'
import { ServerService } from '@app/core'

@Injectable()
export class VideoService {
Expand All @@ -33,17 +34,22 @@ export class VideoService {
constructor (
private authHttp: HttpClient,
private restExtractor: RestExtractor,
private restService: RestService
private restService: RestService,
private serverService: ServerService
) {}

getVideoViewUrl (uuid: string) {
return VideoService.BASE_VIDEO_URL + uuid + '/views'
}

getVideo (uuid: string): Observable<VideoDetails> {
return this.authHttp.get<VideoDetailsServerModel>(VideoService.BASE_VIDEO_URL + uuid)
return this.serverService.localeObservable
.pipe(
map(videoHash => new VideoDetails(videoHash)),
switchMap(translations => {
return this.authHttp.get<VideoDetailsServerModel>(VideoService.BASE_VIDEO_URL + uuid)
.pipe(map(videoHash => ({ videoHash, translations })))
}),
map(({ videoHash, translations }) => new VideoDetails(videoHash, translations)),
catchError(res => this.restExtractor.handleError(res))
)
}
Expand Down Expand Up @@ -102,9 +108,10 @@ export class VideoService {
let params = new HttpParams()
params = this.restService.addRestGetParams(params, pagination, sort)

return this.authHttp.get(UserService.BASE_USERS_URL + '/me/videos', { params })
return this.authHttp
.get<ResultList<Video>>(UserService.BASE_USERS_URL + '/me/videos', { params })
.pipe(
map(this.extractVideos),
switchMap(res => this.extractVideos(res)),
catchError(res => this.restExtractor.handleError(res))
)
}
Expand All @@ -120,9 +127,9 @@ export class VideoService {
params = this.restService.addRestGetParams(params, pagination, sort)

return this.authHttp
.get(AccountService.BASE_ACCOUNT_URL + account.nameWithHost + '/videos', { params })
.get<ResultList<Video>>(AccountService.BASE_ACCOUNT_URL + account.nameWithHost + '/videos', { params })
.pipe(
map(this.extractVideos),
switchMap(res => this.extractVideos(res)),
catchError(res => this.restExtractor.handleError(res))
)
}
Expand All @@ -138,9 +145,9 @@ export class VideoService {
params = this.restService.addRestGetParams(params, pagination, sort)

return this.authHttp
.get(VideoChannelService.BASE_VIDEO_CHANNEL_URL + videoChannel.uuid + '/videos', { params })
.get<ResultList<Video>>(VideoChannelService.BASE_VIDEO_CHANNEL_URL + videoChannel.uuid + '/videos', { params })
.pipe(
map(this.extractVideos),
switchMap(res => this.extractVideos(res)),
catchError(res => this.restExtractor.handleError(res))
)
}
Expand All @@ -160,9 +167,9 @@ export class VideoService {
}

return this.authHttp
.get(VideoService.BASE_VIDEO_URL, { params })
.get<ResultList<Video>>(VideoService.BASE_VIDEO_URL, { params })
.pipe(
map(this.extractVideos),
switchMap(res => this.extractVideos(res)),
catchError(res => this.restExtractor.handleError(res))
)
}
Expand Down Expand Up @@ -230,7 +237,7 @@ export class VideoService {
return this.authHttp
.get<ResultList<VideoServerModel>>(url, { params })
.pipe(
map(this.extractVideos),
switchMap(res => this.extractVideos(res)),
catchError(res => this.restExtractor.handleError(res))
)
}
Expand Down Expand Up @@ -287,14 +294,19 @@ export class VideoService {
}

private extractVideos (result: ResultList<VideoServerModel>) {
const videosJson = result.data
const totalVideos = result.total
const videos = []

for (const videoJson of videosJson) {
videos.push(new Video(videoJson))
}

return { videos, totalVideos }
return this.serverService.localeObservable
.pipe(
map(translations => {
const videosJson = result.data
const totalVideos = result.total
const videos: Video[] = []

for (const videoJson of videosJson) {
videos.push(new Video(videoJson, translations))
}

return { videos, totalVideos }
})
)
}
}
Loading

0 comments on commit 7ce44a7

Please sign in to comment.