Added internationalization of factory names

This commit is contained in:
Sebastian Seedorf
2022-08-19 19:33:38 +02:00
parent 33a5b10fe3
commit f826537aec
11 changed files with 91 additions and 29 deletions

View File

@@ -0,0 +1,61 @@
import { createContext, FC, useContext, useMemo } from 'react'
import { EnrichedEntity } from '../../../src/types'
import { ReactNodeLike } from 'prop-types'
import { factories } from './prepare'
import { useLocale } from '../../../src/hooks/useLocale'
import de from '../../../res/translation-de.json'
import nl from '../../../res/translation-nl.json'
import { Dict } from '../../../src/types'
const factoryNames: Record<'de' | 'nl', Dict<string>> = {
de,
nl
}
interface Props {
children: ReactNodeLike
}
interface FactoryContextType {
factories: EnrichedEntity[]
findFactory(uid: string): EnrichedEntity | undefined
}
const defaultValues: FactoryContextType = {
factories: [],
findFactory() {
return undefined
}
}
const FactoryContext = createContext<FactoryContextType>(defaultValues)
export const useFactories = () => useContext(FactoryContext)
export const FactoryProvider: FC<Props> = ({ children }) => {
const locale = useLocale()
const internationalizedFactories = useMemo(() => {
if (locale !== 'en')
factories.map(
factory => (factory.name = factoryNames[locale]?.[factory.href] ?? factory.name)
)
return factories
}, [locale])
const findFactory = useMemo(() => {
const detailsMap = Object.fromEntries(
factories.map((detail: EnrichedEntity) => [detail.href, detail])
)
return (uid: string): EnrichedEntity | undefined => {
return detailsMap[uid]
}
}, [])
const value: FactoryContextType = useMemo(
() => ({
factories: internationalizedFactories,
findFactory
}),
[findFactory, internationalizedFactories]
)
return <FactoryContext.Provider value={value}>{children}</FactoryContext.Provider>
}

View File

@@ -1,7 +1,7 @@
import { EnrichedEntity, Entity } from '../types' import { EnrichedEntity, Entity } from '../../../src/types'
import details from '../../res/details.json' import details from '../../../res/details.json'
import manual from '../../res/manual.json' import manual from '../../../res/manual.json'
import exclude from '../../res/exclude.json' import exclude from '../../../res/exclude.json'
const manualEntities = manual as Entity[] const manualEntities = manual as Entity[]
const manualKeys = new Set(manualEntities.map(entity => entity.href)) const manualKeys = new Set(manualEntities.map(entity => entity.href))
@@ -9,7 +9,7 @@ const detailEntities = (details as Entity[]).filter(detail => !manualKeys.has(de
const joined = [...detailEntities, ...manualEntities] const joined = [...detailEntities, ...manualEntities]
const factories = joined export const factories = joined
.map((detail: EnrichedEntity) => { .map((detail: EnrichedEntity) => {
detail.usedBy = joined.filter(f => detail.usedBy = joined.filter(f =>
Object.keys(f.recipe?.prerequisites ?? {}).includes(detail.href) Object.keys(f.recipe?.prerequisites ?? {}).includes(detail.href)
@@ -17,14 +17,3 @@ const factories = joined
return detail return detail
}) })
.filter(detail => !(exclude as string[]).includes(detail.href)) .filter(detail => !(exclude as string[]).includes(detail.href))
const detailsMap = Object.fromEntries(
factories.map((detail: EnrichedEntity) => [detail.href, detail])
)
export const useFactories = () => ({
factories,
findFactory: (uid: string): EnrichedEntity | undefined => {
return detailsMap[uid]
}
})

View File

@@ -1,8 +1,8 @@
import { FC, HTMLProps, useMemo } from 'react' import { FC, HTMLProps, useMemo } from 'react'
import { Entity } from '../../../src/types' import { Entity } from '../../../src/types'
import { useFactories } from '../../../src/hooks/useFactories'
import styles from './EntityIcon.module.css' import styles from './EntityIcon.module.css'
import cx from 'classnames' import cx from 'classnames'
import { useFactories } from '../../contexts/FactoryProvider'
interface Props extends Omit<HTMLProps<HTMLSpanElement>, 'value'> { interface Props extends Omit<HTMLProps<HTMLSpanElement>, 'value'> {
value: Entity | string value: Entity | string

View File

@@ -1,11 +1,11 @@
import { FC, HTMLProps, memo, useMemo } from 'react' import { FC, HTMLProps, memo, useMemo } from 'react'
import { EnrichedEntity } from '../../../src/types' import { EnrichedEntity } from '../../../src/types'
import { useFactories } from '../../../src/hooks/useFactories'
import styles from './EntitySpan.module.css' import styles from './EntitySpan.module.css'
import { RecipeSpan } from '../Recipe/Recipe' import { RecipeSpan } from '../Recipe/Recipe'
import { LeftClickIcon } from '../LeftClickIcon/LeftClickIcon' import { LeftClickIcon } from '../LeftClickIcon/LeftClickIcon'
import cx from 'classnames' import cx from 'classnames'
import { EntityIcon } from '../EntityIcon/EntityIcon' import { EntityIcon } from '../EntityIcon/EntityIcon'
import { useFactories } from '../../contexts/FactoryProvider'
interface Props extends Omit<HTMLProps<HTMLSpanElement>, 'value'> { interface Props extends Omit<HTMLProps<HTMLSpanElement>, 'value'> {
value: EnrichedEntity | string value: EnrichedEntity | string

View File

@@ -2,8 +2,8 @@ import { FC, memo, useCallback, useEffect, useMemo } from 'react'
import Select, { ActionMeta, CSSObjectWithLabel } from 'react-select' import Select, { ActionMeta, CSSObjectWithLabel } from 'react-select'
import { isNonNullable } from '../../../src/utils' import { isNonNullable } from '../../../src/utils'
import styles from './FactorySelect.module.css' import styles from './FactorySelect.module.css'
import { useFactories } from '../../../src/hooks/useFactories'
import { EntitySpan } from '../EntitySpan/EntitySpan' import { EntitySpan } from '../EntitySpan/EntitySpan'
import { useFactories } from '../../contexts/FactoryProvider'
interface Props { interface Props {
id: string id: string

View File

@@ -1,6 +1,5 @@
import { FC, memo, useCallback, useMemo, useState } from 'react' import { FC, memo, useCallback, useMemo, useState } from 'react'
import { FactorySelect } from '../FactorySelect/FactorySelect' import { FactorySelect } from '../FactorySelect/FactorySelect'
import { useFactories } from '../../../src/hooks/useFactories'
import { EnrichedEntity, Group } from '../../../src/types' import { EnrichedEntity, Group } from '../../../src/types'
import styles from './GroupBox.module.css' import styles from './GroupBox.module.css'
import { EntitySpan } from '../EntitySpan/EntitySpan' import { EntitySpan } from '../EntitySpan/EntitySpan'
@@ -9,6 +8,7 @@ import { calculateInputs } from '../../../src/calculateInputs'
import { fixedEncodeURIComponent, uniquify } from '../../../src/utils' import { fixedEncodeURIComponent, uniquify } from '../../../src/utils'
import Link from 'next/link' import Link from 'next/link'
import { useRouter } from 'next/router' import { useRouter } from 'next/router'
import { useFactories } from '../../contexts/FactoryProvider'
interface Props { interface Props {
group: Group group: Group

View File

@@ -1,7 +1,6 @@
import { FC, useMemo, useRef, useState } from 'react' import { FC, useMemo, useRef, useState } from 'react'
import { GroupBox } from './GroupBox/GroupBox' import { GroupBox } from './GroupBox/GroupBox'
import styles from './Home.module.css' import styles from './Home.module.css'
import { useFactories } from '../../src/hooks/useFactories'
import { EnrichedEntity } from '../../src/types' import { EnrichedEntity } from '../../src/types'
import { EntitySpan } from './EntitySpan/EntitySpan' import { EntitySpan } from './EntitySpan/EntitySpan'
import { useGroups } from '../contexts/GroupProvider' import { useGroups } from '../contexts/GroupProvider'
@@ -10,6 +9,7 @@ import { download, streamToArrayBuffer } from '../../src/download'
import Link from 'next/link' import Link from 'next/link'
import { useRouter } from 'next/router' import { useRouter } from 'next/router'
import { I18n } from '../shared/I18n/I18n' import { I18n } from '../shared/I18n/I18n'
import { useFactories } from '../contexts/FactoryProvider'
export const Home: FC = () => { export const Home: FC = () => {
const { query } = useRouter() const { query } = useRouter()

View File

@@ -1,6 +1,5 @@
import { useRouter } from 'next/router' import { useRouter } from 'next/router'
import { useGroups } from '../contexts/GroupProvider' import { useGroups } from '../contexts/GroupProvider'
import { useFactories } from '../../src/hooks/useFactories'
import { FC, useMemo } from 'react' import { FC, useMemo } from 'react'
import { calculateInputs } from '../../src/calculateInputs' import { calculateInputs } from '../../src/calculateInputs'
import { DetailGraphNode, NodeDetails } from './NodeDetails/NodeDetails' import { DetailGraphNode, NodeDetails } from './NodeDetails/NodeDetails'
@@ -9,6 +8,7 @@ import { EnrichedEntity } from '../../src/types'
import Head from 'next/head' import Head from 'next/head'
import { ScrollContainer } from './ScrollContainer/ScrollContainer' import { ScrollContainer } from './ScrollContainer/ScrollContainer'
import { ProducingGraph } from './ProducingGraph/ProducingGraph' import { ProducingGraph } from './ProducingGraph/ProducingGraph'
import { useFactories } from '../contexts/FactoryProvider'
export const PageDetails: FC = () => { export const PageDetails: FC = () => {
const { const {

View File

@@ -1,11 +1,11 @@
import { useGroups } from '../contexts/GroupProvider' import { useGroups } from '../contexts/GroupProvider'
import { useFactories } from '../../src/hooks/useFactories'
import { FC, useMemo } from 'react' import { FC, useMemo } from 'react'
import { calculateInputs } from '../../src/calculateInputs' import { calculateInputs } from '../../src/calculateInputs'
import Head from 'next/head' import Head from 'next/head'
import { ScrollContainer } from './ScrollContainer/ScrollContainer' import { ScrollContainer } from './ScrollContainer/ScrollContainer'
import { ProducingGraph } from './ProducingGraph/ProducingGraph' import { ProducingGraph } from './ProducingGraph/ProducingGraph'
import { NodeOverview, OverviewGraphNode } from './NodeOverview/NodeOverview' import { NodeOverview, OverviewGraphNode } from './NodeOverview/NodeOverview'
import { useFactories } from '../contexts/FactoryProvider'
export const PageOverview: FC = () => { export const PageOverview: FC = () => {
const { exportedFactories, baseFactories, groups } = useGroups() const { exportedFactories, baseFactories, groups } = useGroups()

View File

@@ -5,17 +5,21 @@ import Head from 'next/head'
import { useRouter } from 'next/router' import { useRouter } from 'next/router'
import { IntlProvider } from 'react-intl' import { IntlProvider } from 'react-intl'
import { useMessages } from '../src/i18n' import { useMessages } from '../src/i18n'
import { FactoryProvider } from '../components/contexts/FactoryProvider'
import { useLocale } from '../src/hooks/useLocale'
const MyApp: FC<AppProps> = ({ Component, pageProps }) => { const MyApp: FC<AppProps> = ({ Component, pageProps }) => {
const { basePath, locale: _locale } = useRouter() const { basePath } = useRouter()
const messages = useMessages() const messages = useMessages()
const locale = _locale ?? '' in messages ? (_locale as keyof typeof messages) : 'en' const locale = useLocale()
return ( return (
<IntlProvider locale={locale} messages={messages[locale]}> <IntlProvider locale={locale} messages={messages[locale]}>
<FactoryProvider>
<Head> <Head>
<link rel='icon' href={`${basePath}/favicon.ico`} /> <link rel='icon' href={`${basePath}/favicon.ico`} />
</Head> </Head>
<Component {...pageProps} /> <Component {...pageProps} />
</FactoryProvider>
</IntlProvider> </IntlProvider>
) )
} }

8
src/hooks/useLocale.ts Normal file
View File

@@ -0,0 +1,8 @@
import { useRouter } from 'next/router'
import { useMessages } from '../i18n'
export const useLocale = () => {
const { locale: _locale } = useRouter()
const messages = useMessages()
return _locale ?? '' in messages ? (_locale as keyof typeof messages) : 'en'
}