import { SharedModule } from './shared'
import { SignupModule } from './signup'
import { VideosModule } from './videos'
-import { buildFileLocale, getDefaultLocale } from '../../../shared/models/i18n'
-import { environment } from '../environments/environment'
+import { buildFileLocale, getCompleteLocale, getDefaultLocale, isDefaultLocale } from '../../../shared/models/i18n'
+import { getDevLocale, isOnDevLocale } from '@app/shared/i18n/i18n-utils'
export function metaFactory (serverService: ServerService): MetaLoader {
return new MetaStaticLoader({
{
provide: TRANSLATIONS,
useFactory: (locale) => {
- // On dev mode, test locales
- if (environment.production === false && window.location.search === '?lang=fr') {
- return require(`raw-loader!../locale/target/angular_fr.xml`)
+ // On dev mode, test localization
+ if (isOnDevLocale()) {
+ locale = getDevLocale()
+ return require(`raw-loader!../locale/target/angular_${locale}.xml`)
}
- const fileLocale = buildFileLocale(locale)
-
// Default locale, nothing to translate
- const defaultFileLocale = buildFileLocale(getDefaultLocale())
- if (fileLocale === defaultFileLocale) return ''
+ const completeLocale = getCompleteLocale(locale)
+ if (isDefaultLocale(completeLocale)) return ''
+ const fileLocale = buildFileLocale(locale)
return require(`raw-loader!../locale/target/angular_${fileLocale}.xml`)
},
deps: [ LOCALE_ID ]
import { HttpClient } from '@angular/common/http'
import { Inject, Injectable, LOCALE_ID } from '@angular/core'
import { peertubeLocalStorage } from '@app/shared/misc/peertube-local-storage'
-import { Observable, ReplaySubject } from 'rxjs'
-import { ServerConfig } from '../../../../../shared'
+import { Observable, ReplaySubject, of } from 'rxjs'
+import { getCompleteLocale, 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'
+import { isDefaultLocale } from '../../../../../shared/models/i18n'
+import { getDevLocale, isOnDevLocale, peertubeTranslate } from '@app/shared/i18n/i18n-utils'
@Injectable()
export class ServerService {
private http: HttpClient,
@Inject(LOCALE_ID) private localeId: string
) {
- this.loadConfigLocally()
this.loadServerLocale()
+ this.loadConfigLocally()
}
loadConfig () {
}
private loadServerLocale () {
- const fileLocale = buildFileLocale(environment.production === true ? this.localeId : 'fr')
+ const completeLocale = isOnDevLocale() ? getDevLocale() : getCompleteLocale(this.localeId)
// Default locale, nothing to translate
- const defaultFileLocale = buildFileLocale(getDefaultLocale())
- if (fileLocale === defaultFileLocale) return {}
+ if (isDefaultLocale(completeLocale)) {
+ this.localeObservable = of({}).pipe(share())
+ return
+ }
this.localeObservable = this.http
- .get(ServerService.BASE_LOCALE_URL + fileLocale + '/server.json')
+ .get(ServerService.BASE_LOCALE_URL + completeLocale + '/server.json')
.pipe(share())
}
+import { environment } from '../../../environments/environment'
+
function peertubeTranslate (str: string, translations: { [ id: string ]: string }) {
return translations[str] ? translations[str] : str
}
+function isOnDevLocale () {
+ return environment.production === false && window.location.search === '?lang=fr'
+}
+
+function getDevLocale () {
+ return 'fr'
+}
+
export {
+ getDevLocale,
+ isOnDevLocale,
peertubeTranslate
}
return this.serverService.localeObservable
.pipe(
switchMap(translations => {
- return this.authHttp.get<VideoDetailsServerModel>(VideoService.BASE_VIDEO_URL + uuid)
- .pipe(map(videoHash => ({ videoHash, 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))
import { ServerService } from '@app/core'
import { I18n } from '@ngx-translate/i18n-polyfill'
import { environment } from '../../../environments/environment'
+import { getDevLocale, isOnDevLocale } from '@app/shared/i18n/i18n-utils'
@Component({
selector: 'my-video-watch',
})
if (this.videojsLocaleLoaded === false) {
- await loadLocale(environment.apiUrl, videojs, environment.production === true ? this.localeId : 'fr')
+ await loadLocale(environment.apiUrl, videojs, isOnDevLocale() ? getDevLocale() : this.localeId)
this.videojsLocaleLoaded = true
}
import './peertube-load-progress-bar'
import { videojsUntyped } from './peertube-videojs-typings'
import { buildVideoEmbed, buildVideoLink, copyToClipboard } from './utils'
-import { is18nLocale, isDefaultLocale } from '../../../../shared/models/i18n/i18n'
+import { getCompleteLocale, is18nLocale, isDefaultLocale } from '../../../../shared/models/i18n/i18n'
// Change 'Playback Rate' to 'Speed' (smaller for our settings menu)
videojsUntyped.getComponent('PlaybackRateMenuButton').prototype.controlText_ = 'Speed'
}
function loadLocale (serverUrl: string, videojs: any, locale: string) {
- if (!is18nLocale(locale) || isDefaultLocale(locale)) return undefined
+ const completeLocale = getCompleteLocale(locale)
- return fetch(serverUrl + '/client/locales/' + locale + '/player.json')
+ if (!is18nLocale(completeLocale) || isDefaultLocale(completeLocale)) return Promise.resolve(undefined)
+
+ return fetch(serverUrl + '/client/locales/' + completeLocale + '/player.json')
.then(res => res.json())
- .then(json => videojs.addLanguage(locale, json))
+ .then(json => videojs.addLanguage(completeLocale, json))
}
export {
import { environment } from './environments/environment'
import { hmrBootstrap } from './hmr'
+import { getDevLocale, isOnDevLocale } from '@app/shared/i18n/i18n-utils'
let providers = []
if (environment.production) {
enableProdMode()
}
-if (environment.production === false && window.location.search === '?lang=fr') {
- const translations = require(`raw-loader!./locale/target/angular_fr.xml`)
+// Template translation, should be in the bootstrap step
+if (isOnDevLocale()) {
+ const locale = getDevLocale()
+ const translations = require(`raw-loader!./locale/target/angular_${locale}.xml`)
providers = [
{ provide: TRANSLATIONS, useValue: translations },
import * as xliff12ToJs from 'xliff/xliff12ToJs'
import { unlink, readFileSync, writeFile } from 'fs'
import { join } from 'path'
-import { buildFileLocale, I18N_LOCALES, isDefaultLocale } from '../../shared/models/i18n/i18n'
+import { buildFileLocale, I18N_LOCALES, isDefaultLocale, LOCALE_FILES } from '../../shared/models/i18n/i18n'
import { eachSeries } from 'async'
const sources: string[] = []
.filter(l => isDefaultLocale(l) === false)
.map(l => buildFileLocale(l))
-for (const file of [ 'server', 'player' ]) {
+for (const file of LOCALE_FILES) {
for (const locale of availableLocales) {
sources.push(join(__dirname, '../../../client/src/locale/target/', `${file}_${locale}.xml`))
}
import { join } from 'path'
import * as validator from 'validator'
import { escapeHTML, readFileBufferPromise, root } from '../helpers/core-utils'
-import {
- ACCEPT_HEADERS,
- CONFIG,
- EMBED_SIZE,
- OPENGRAPH_AND_OEMBED_COMMENT,
- STATIC_MAX_AGE,
- STATIC_PATHS
-} from '../initializers'
+import { ACCEPT_HEADERS, CONFIG, EMBED_SIZE, OPENGRAPH_AND_OEMBED_COMMENT, STATIC_MAX_AGE, STATIC_PATHS } from '../initializers'
import { asyncMiddleware } from '../middlewares'
import { VideoModel } from '../models/video/video'
import { VideoPrivacy } from '../../shared/models/videos'
-import { I18N_LOCALES, is18nLocale, getDefaultLocale } from '../../shared/models'
+import { buildFileLocale, getCompleteLocale, getDefaultLocale, is18nLocale } from '../../shared/models'
+import { LOCALE_FILES } from '../../shared/models/i18n/i18n'
const clientsRouter = express.Router()
const locale = req.params.locale
const file = req.params.file
- if (is18nLocale(locale) && [ 'player', 'server' ].indexOf(file) !== -1) {
- return res.sendFile(join(__dirname, `../../../client/dist/locale/${file}_${locale}.json`))
+ if (is18nLocale(locale) && LOCALE_FILES.indexOf(file) !== -1) {
+ const completeLocale = getCompleteLocale(locale)
+ const completeFileLocale = buildFileLocale(completeLocale)
+ return res.sendFile(join(__dirname, `../../../client/dist/locale/${file}_${completeFileLocale}.json`))
}
return res.sendStatus(404)
if (paramLang && is18nLocale(paramLang)) {
lang = paramLang
} else {
- // lang = req.acceptsLanguages(Object.keys(I18N_LOCALES)) || getDefaultLocale()
+ // lang = req.acceptsLanguages(POSSIBLE_LOCALES) || getDefaultLocale()
// Disable auto language for now
lang = getDefaultLocale()
}
- return join(__dirname, '../../../client/dist/' + lang + '/index.html')
+ return join(__dirname, '../../../client/dist/' + buildFileLocale(lang) + '/index.html')
}
function addOpenGraphAndOEmbedTags (htmlStringPage: string, video: VideoModel) {
+export const LOCALE_FILES = [ 'player', 'server' ]
+
export const I18N_LOCALES = {
'en-US': 'English (US)',
fr: 'French'
}
+const I18N_LOCALE_ALIAS = {
+ 'en': 'en-US'
+}
+
+export const POSSIBLE_LOCALES = Object.keys(I18N_LOCALES)
+ .concat(Object.keys(I18N_LOCALE_ALIAS))
+
+const possiblePaths = POSSIBLE_LOCALES.map(l => '/' + l)
+
export function getDefaultLocale () {
return 'en-US'
}
export function isDefaultLocale (locale: string) {
- return locale === getDefaultLocale()
+ return getCompleteLocale(locale) === getCompleteLocale(getDefaultLocale())
}
-const possiblePaths = Object.keys(I18N_LOCALES).map(l => '/' + l)
export function is18nPath (path: string) {
return possiblePaths.indexOf(path) !== -1
}
-const possibleLanguages = Object.keys(I18N_LOCALES)
export function is18nLocale (locale: string) {
- return possibleLanguages.indexOf(locale) !== -1
+ return POSSIBLE_LOCALES.indexOf(locale) !== -1
+}
+
+export function getCompleteLocale (locale: string) {
+ if (!locale) return locale
+
+ if (I18N_LOCALE_ALIAS[locale]) return I18N_LOCALE_ALIAS[locale]
+
+ return locale
}
-// Only use in dev mode, so relax
-// In production, the locale always match with a I18N_LANGUAGES key
export function buildFileLocale (locale: string) {
- if (!is18nLocale(locale)) {
- // Some working examples for development purpose
- if (locale.split('-')[ 0 ] === 'en') return 'en_US'
- else if (locale === 'fr') return 'fr'
- }
+ const completeLocale = getCompleteLocale(locale)
- return locale.replace('-', '_')
+ return completeLocale.replace('-', '_')
}