import { ReactiveCache } from '/imports/reactiveCache' ;
import { Meteor } from 'meteor/meteor' ;
import { ReactiveVar } from 'meteor/reactive-var' ;
import Translation from '/models/translation' ;
import i18next from 'i18next' ;
import sprintf from 'i18next-sprintf-postprocessor' ;
import languages from './languages' ;
const DEFAULT _NAMESPACE = 'translation' ;
const DEFAULT _LANGUAGE = 'en' ;
// Carefully reproduced tap:i18n API
export const TAPi18n = {
i18n : null ,
current : new ReactiveVar ( DEFAULT _LANGUAGE ) ,
async init ( ) {
this . i18n = i18next . createInstance ( ) . use ( sprintf ) ;
await this . i18n . init ( {
fallbackLng : DEFAULT _LANGUAGE ,
cleanCode : true ,
// Show translations debug messages only when DEBUG=true
// OLD: debug: Meteor.isDevelopment,
debug : process . env . DEBUG === 'true' ,
supportedLngs : Object . values ( languages ) . map ( ( { tag } ) => tag ) ,
ns : DEFAULT _NAMESPACE ,
defaultNs : DEFAULT _NAMESPACE ,
postProcess : [ "sprintf" ] ,
// Default values to match tap:i18n behaviour
interpolation : {
prefix : '__' ,
suffix : '__' ,
escapeValue : false ,
} ,
resources : { } ,
} ) ;
// Load the current language data
await TAPi18n . loadLanguage ( DEFAULT _LANGUAGE ) ;
} ,
isLanguageSupported ( language ) {
return Object . values ( languages ) . some ( ( { tag } ) => tag === language ) ;
} ,
getSupportedLanguages ( ) {
return Object . values ( languages ) . map ( ( { name , code , tag } ) => ( { name , code , tag } ) ) ;
} ,
getLanguage ( ) {
return this . current . get ( ) ;
} ,
loadTranslation ( language ) {
return new Promise ( ( resolve , reject ) => {
if ( Meteor . isClient ) {
const translationSubscription = Meteor . subscribe ( 'translation' , { language : language } , 0 , {
onReady ( ) {
resolve ( translationSubscription ) ;
} ,
onError ( error ) {
reject ( error ) ;
}
} ) ;
} else {
resolve ( ) ;
}
} ) ;
} ,
async loadLanguage ( language ) {
if ( language in languages && 'load' in languages [ language ] ) {
let data = await languages [ language ] . load ( ) ;
let custom _translations = [ ] ;
await this . loadTranslation ( language ) ;
custom _translations = ReactiveCache . getTranslations ( { language : language } , { fields : { text : true , translationText : true } } ) ;
if ( custom _translations && custom _translations . length > 0 ) {
data = custom _translations . reduce ( ( acc , cur ) => ( acc [ cur . text ] = cur . translationText , acc ) , data ) ;
}
this . i18n . addResourceBundle ( language , DEFAULT _NAMESPACE , data ) ;
} else {
throw new Error ( ` Language ${ language } is not supported ` ) ;
}
} ,
async setLanguage ( language ) {
await this . loadLanguage ( language ) ;
await this . i18n . changeLanguage ( language ) ;
this . current . set ( language ) ;
} ,
// Return translation by key
_ _ ( key , options , language ) {
this . current . dep . depend ( ) ;
return this . i18n . t ( key , {
... options ,
lng : language ,
} ) ;
}
} ;