improve language selection

This commit is contained in:
Jon Eugster
2024-05-16 23:26:50 +02:00
parent c1642cf09b
commit 8b5d6ff2f3
7 changed files with 183 additions and 20 deletions
+13 -3
View File
@@ -17,6 +17,7 @@ import { useSelector } from 'react-redux';
import { changeTypewriterMode, selectOpenedIntro, selectTypewriterMode } from './state/progress';
import { useAppDispatch } from './hooks';
import { Popup, PopupContext } from './components/popup/popup';
import { useGetGameInfoQuery } from './state/api';
export const GameIdContext = React.createContext<{
gameId: string,
@@ -39,6 +40,7 @@ function App() {
const [typewriterInput, setTypewriterInput] = useState("")
const [page, setPage] = useState(0)
const [popupContent, setPopupContent] = useState(null)
const gameInfo = useGetGameInfoQuery({game: gameId})
const openedIntro = useSelector(selectOpenedIntro(gameId))
@@ -49,10 +51,18 @@ function App() {
}
}, [openedIntro])
useEffect(() => {
i18n.changeLanguage(language)
}, [language])
let availableLangs = gameInfo.data?.tile?.languages
if (gameId && availableLangs?.length > 0 && !(availableLangs.includes(language))) {
// if the game is not available in the preferred language, display it in the original
// language
console.log(`using default language: ${availableLangs[0]}`)
i18n.changeLanguage(availableLangs[0])
} else {
console.log(`using language: ${language}`)
i18n.changeLanguage(language)
}
}, [gameId, gameInfo.data?.tile?.languages, language])
return (
<div className="app">
+14
View File
@@ -0,0 +1,14 @@
import * as React from 'react'
import ReactCountryFlag from 'react-country-flag'
import lean4gameConfig from '../config.json'
/** Displays either a flag or the language-code, depending on the settings.
* The argument `iso` is an ISO-language code.
*/
export const Flag : React.FC<{ iso: string, showTitle?: boolean}> = ({iso, showTitle=false}) => {
let lang = lean4gameConfig.newLanguages[iso]
if (lean4gameConfig.useFlags && lang) {
return <ReactCountryFlag countryCode={lang.flag} title={showTitle ? lang.name : null} />
}
return <span>{iso}</span>
}
+4 -8
View File
@@ -19,6 +19,7 @@ import lean4gameConfig from '../config.json'
import i18next from 'i18next';
import { useContext } from 'react';
import { PopupContext } from './popup/popup';
import { Flag } from './flag';
function Tile({gameId, data}: {gameId: string, data: GameTile|undefined}) {
let { t } = useTranslation()
@@ -57,14 +58,9 @@ function Tile({gameId, data}: {gameId: string, data: GameTile|undefined}) {
<td>{t("Language")}</td>
<td>
{data.languages.map((lang) => {
let langOpt = lean4gameConfig.languages.find((e) => e.iso == lang)
if (lean4gameConfig.useFlags) {
return <ReactCountryFlag key={`flag-${lang}`} title={langOpt?.name} countryCode={langOpt?.flag} className="emojiFlag"/>
} else {
return <span key={`flag-text-${lang}`} title={langOpt?.name}>{lang}</span>
}
})}
{data.languages.map((lang) => (
<Flag iso={lang} showTitle={true} />
))}
</td>
</tr>
</tbody>
+40 -6
View File
@@ -1,5 +1,5 @@
import * as React from 'react'
import { createContext, useContext, useState } from 'react'
import { createContext, useContext, useEffect, useState } from 'react'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faDownload, faUpload, faEraser, faBook, faBookOpen, faGlobe, faHome,
faArrowRight, faArrowLeft, faXmark, faBars, faCode,
@@ -13,6 +13,9 @@ import '../css/navigation.css'
import { PopupContext } from './popup/popup'
import { useSelector } from 'react-redux'
import { selectProgress } from '../state/progress'
import ReactCountryFlag from 'react-country-flag'
import lean4gameConfig from '../config.json'
import { Flag } from './flag'
/** SVG github icon */
function GithubIcon () {
@@ -208,17 +211,20 @@ function MobileNavigationLevel () {
</div>
}
/** The skeleton of the navigation which is the same across all layouts. */
export function Navigation () {
const { t } = useTranslation()
const { gameId, worldId } = useContext(GameIdContext)
const { mobile } = useContext(PreferencesContext)
const { mobile, language, setLanguage } = useContext(PreferencesContext)
const { setPopupContent } = useContext(PopupContext)
const gameProgress = useSelector(selectProgress(gameId))
const gameInfo = useGetGameInfoQuery({game: gameId})
const [navOpen, setNavOpen] = useState(false)
function toggleNav () {setNavOpen(!navOpen)}
const [langNavOpen, setLangNavOpen] = useState(false)
function toggleNav () {setNavOpen(!navOpen); setLangNavOpen(false)}
function toggleLangNav () {setLangNavOpen(!langNavOpen); setNavOpen(false)}
return <nav>
<NavigationContext.Provider value={{navOpen, setNavOpen}}>
@@ -238,13 +244,41 @@ export function Navigation () {
<NavButton
iconElement={<GithubIcon />}
title={t("view the Lean game server on Github")}
href='https://github.com/leanprover-community/lean4game'
/>
href='https://github.com/leanprover-community/lean4game' />
}
{(!gameId || gameInfo.data?.tile?.languages.length > 1) &&
// Language button only visible if the game exists in `>1` languages
<NavButton
iconElement={langNavOpen ? null : <Flag iso={language} />}
icon={langNavOpen ? faXmark : null}
title={langNavOpen ? t('close language menu') : t('open language menu')}
onClick={toggleLangNav}
/>
}
<NavButton
icon={navOpen ? faXmark : faBars}
title={navOpen ? t('close menu') : t('open menu')}
onClick={toggleNav} />
{ langNavOpen &&
<div className='dropdown' onClick={toggleLangNav} >
{gameId && gameInfo.data?.tile?.languages ?
// Show all languages the game is available in
gameInfo.data?.tile?.languages.map(iso =>
<NavButton
iconElement={<Flag iso={iso} />}
text={lean4gameConfig.newLanguages[iso]?.name}
onClick={() => {setLanguage(iso)}}
inverted={true} />) :
// Show all languages the interface is available in (e.g. landing page)
Object.entries(lean4gameConfig.newLanguages).map(([iso, val]) =>
<NavButton
iconElement={<Flag iso={iso} />}
text={lean4gameConfig.newLanguages[iso]?.name}
onClick={() => {setLanguage(iso)}}
inverted={true} />)
}
</div>
}
{ navOpen &&
<div className='dropdown' onClick={toggleNav} >
{ gameId && <>
+16 -2
View File
@@ -1,7 +1,7 @@
{
"allGames": [
"leanprover-community/nng4",
"hhu-adam/robo",
"local/Robo",
"djvelleman/stg4",
"trequetrum/lean4game-logic"
],
@@ -23,5 +23,19 @@
"name": "中文"
}
],
"useFlags": false
"newLanguages": {
"en": {
"flag": "GB",
"name": "English"
},
"de": {
"flag": "DE",
"name": "Deutsch"
},
"zh": {
"flag": "CN",
"name": "中文"
}
},
"useFlags": true
}