import { LoopReducer , Loop } from 'redux-loop' ; import * as actions from '@client/i18n/actions' ; import { getDefaultLanguage , getAvailableLanguages } from '@client/i18n/utils' ; import * as offlineActions from '@client/offline/actions' ; import { ILocation } from '@client/offline/reducer' ; export interface IntlMessages { [ key ] : string ; } export interface ILanguage { lang : string ; displayName : string ; messages : IntlMessages ; } export interface ILanguageState { [ key ] : ILanguage ; } export type IntlState = { language : string ; messages : IntlMessages ; languages : ILanguageState ; } ; interface ISupportedLanguages { code : string ; language : string ; } const supportedLanguages = [ { code : 'en' , language : 'English' } , { code : 'bn' , language : 'বাংলা' } ] ; export const initLanguages = ( ) => { const initLanguages = { } ; getAvailableLanguages ( ) . forEach ( ( lang ) => { const languageDescription = supportedLanguages . find ( ( obj ) => obj . code === lang ) as ISupportedLanguages ; initLanguages [ lang ] = { lang , displayName : languageDescription . language , messages : { } } ; } ) ; return initLanguages ; } ; const DEFAULT_MESSAGES = { default : 'default' } ; export const initialState = { language : getDefaultLanguage ( ) , messages : DEFAULT_MESSAGES , languages : initLanguages ( ) } ; export const formatLocationLanguageState = ( locations , languages ) : ILanguageState => { const primaryLocationMessages = { } ; const secondaryLocationMessages = { } ; locations . forEach ( ( location ) => { primaryLocationMessages [ `location.${ location . id }` ] = location . name ; if ( Object . keys ( languages ) . length === 2 ) { secondaryLocationMessages [ `location.${ location . id }` ] = location . alias ; } } ) ; Object . keys ( languages ) . forEach ( ( key , index ) => { const language = languages [ key ] ; language . messages = { ... language . messages , ... ( index === 1 ? secondaryLocationMessages : primaryLocationMessages ) } ; } ) ; return languages ; } ; const getNextMessages = ( language , languages ) : IntlMessages => { return languages [ language ] . messages ; } ; export const intlReducer = ( state = initialState , action ) : IntlState | Loop < IntlState , actions . Action | offlineActions . Action > => { switch ( action . type ) { case actions . CHANGE_LANGUAGE : const messages = getNextMessages ( action . payload . language , state . languages ) ; return { ... state , language : action . payload . language , messages } ; case offlineActions . READY : case offlineActions . UPDATED : const languages = action . payload . languages ; const loadedLanguagesState = languages . reduce ( ( indexedByLang , language ) => ( { ... indexedByLang , [ language . lang ] : language } ) , { } ) ; const languagesWithLocations = formatLocationLanguageState ( Object . values ( action . payload . locations ) , loadedLanguagesState ) ; const languagesWithFacilities = formatLocationLanguageState ( Object . values ( action . payload . facilities ) , languagesWithLocations ) ; const updatedMessages = { ... getNextMessages ( state . language , state . languages ) , ... languagesWithFacilities [ state . language ] . messages } ; return { ... state , messages : updatedMessages , languages : languagesWithFacilities } ; default : return state ; } } ;