mark most of the game text for translation
This commit is contained in:
@@ -214,6 +214,7 @@ export function WelcomeAppBar({pageNumber, setPageNumber, gameInfo, toggleImpres
|
||||
toggleInfo: any,
|
||||
togglePreferencesPopup: () => void;
|
||||
}) {
|
||||
const { t } = useTranslation()
|
||||
const gameId = React.useContext(GameIdContext)
|
||||
const gameProgress = useAppSelector(selectProgress(gameId))
|
||||
const {mobile} = React.useContext(PreferencesContext)
|
||||
@@ -225,7 +226,7 @@ export function WelcomeAppBar({pageNumber, setPageNumber, gameInfo, toggleImpres
|
||||
<span className="app-bar-title"></span>
|
||||
</div>
|
||||
<div>
|
||||
{!mobile && <span className="app-bar-title">{gameInfo?.title}</span>}
|
||||
{!mobile && <span className="app-bar-title">{t(gameInfo?.title, {ns: gameId})}</span>}
|
||||
</div>
|
||||
<div className="nav-btns">
|
||||
{mobile && <MobileNavButtons pageNumber={pageNumber} setPageNumber={setPageNumber} />}
|
||||
@@ -288,7 +289,7 @@ export function LevelAppBar({isLoading, levelTitle, toggleImpressum, toggleInfo,
|
||||
{/* DESKTOP VERSION */}
|
||||
<div className='app-bar-left'>
|
||||
<HomeButton isDropdown={false} />
|
||||
<span className="app-bar-title">{worldTitle && `${t("World")}: ${worldTitle}`}</span>
|
||||
<span className="app-bar-title">{worldTitle && `${t("World")}: ${t(worldTitle, {ns: gameId})}`}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span className="app-bar-title">{levelTitle}</span>
|
||||
|
||||
@@ -5,22 +5,25 @@ import { DeletedChatContext, ProofContext } from "./infoview/context";
|
||||
import { lastStepHasErrors } from "./infoview/goals";
|
||||
import { Button } from "./button";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { GameIdContext } from "../app";
|
||||
|
||||
/** Plug-in the variable names in a hint. We do this client-side to prepare
|
||||
* for i18n in the future. i.e. one should be able translate the `rawText`
|
||||
* and have the variables substituted just before displaying.
|
||||
*/
|
||||
function getHintText(hint: GameHint): string {
|
||||
const gameId = React.useContext(GameIdContext)
|
||||
let { t } = useTranslation()
|
||||
if (hint.rawText) {
|
||||
// Replace the variable names used in the hint with the ones used by the player
|
||||
// variable names are marked like `«{g}»` inside the text.
|
||||
return hint.rawText.replaceAll(/«\{(.*?)\}»/g, ((_, v) =>
|
||||
return t(hint.rawText, {ns: gameId}).replaceAll(/«\{(.*?)\}»/g, ((_, v) =>
|
||||
// `hint.varNames` contains tuples `[oldName, newName]`
|
||||
(hint.varNames.find(x => x[0] == v))[1]))
|
||||
} else {
|
||||
// hints created in the frontend do not have a `rawText`
|
||||
// TODO: `hint.text` could be removed in theory.
|
||||
return hint.text
|
||||
return t(hint.text, {ns: gameId})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -136,12 +136,15 @@ function DualEditorMain({ worldId, levelId, level, worldSize }: { worldId: strin
|
||||
* If `showLeanStatement` is true, it will additionally display the lean code.
|
||||
*/
|
||||
function ExerciseStatement({ data, showLeanStatement = false }) {
|
||||
let { t } = useTranslation()
|
||||
const gameId = React.useContext(GameIdContext)
|
||||
|
||||
if (!(data?.descrText || data?.descrFormat)) { return <></> }
|
||||
return <>
|
||||
<div className="exercise-statement">
|
||||
{data?.descrText &&
|
||||
<Markdown>
|
||||
{(data?.displayName ? `**Theorem** \`${data?.displayName}\`: ` : '') + data?.descrText}
|
||||
{(data?.displayName ? `**Theorem** \`${data?.displayName}\`: ` : '') + t(data?.descrText, {ns: gameId})}
|
||||
</Markdown>
|
||||
}
|
||||
{data?.descrFormat && showLeanStatement &&
|
||||
|
||||
@@ -140,7 +140,7 @@ export function Documentation({name, type, handleClose}) {
|
||||
<h1 className="doc">{doc.data?.displayName}</h1>
|
||||
<p><code>{doc.data?.statement}</code></p>
|
||||
{/* <code>docstring: {doc.data?.docstring}</code> */}
|
||||
<Markdown>{doc.data?.content}</Markdown>
|
||||
<Markdown>{t(doc.data?.content, {ns: gameId})}</Markdown>
|
||||
</div>
|
||||
}
|
||||
|
||||
|
||||
@@ -173,11 +173,11 @@ function ChatPanel({lastLevel, visible = true}) {
|
||||
{proof?.completed &&
|
||||
<>
|
||||
<div className={`message information recent step-${k}${selectedStep == k ? ' selected' : ''}`} onClick={toggleSelection(k)}>
|
||||
Level completed! 🎉
|
||||
{t("Level completed! 🎉")}
|
||||
</div>
|
||||
{level?.data?.conclusion?.trim() &&
|
||||
<div className={`message information recent step-${k}${selectedStep == k ? ' selected' : ''}`} onClick={toggleSelection(k)}>
|
||||
<Markdown>{level?.data?.conclusion}</Markdown>
|
||||
<Markdown>{t(level?.data?.conclusion, {ns: gameId})}</Markdown>
|
||||
</div>
|
||||
}
|
||||
</>
|
||||
@@ -186,10 +186,10 @@ function ChatPanel({lastLevel, visible = true}) {
|
||||
<div className="button-row">
|
||||
{proof?.completed && (lastLevel ?
|
||||
<Button to={`/${gameId}`}>
|
||||
<FontAwesomeIcon icon={faHome} /> Leave World
|
||||
<FontAwesomeIcon icon={faHome} /> {t("Leave World")}
|
||||
</Button> :
|
||||
<Button to={`/${gameId}/world/${worldId}/level/${levelId + 1}`}>
|
||||
Next <FontAwesomeIcon icon={faArrowRight} />
|
||||
{t("Next")} <FontAwesomeIcon icon={faArrowRight} />
|
||||
</Button>)
|
||||
}
|
||||
<MoreHelpButton />
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
import * as React from 'react'
|
||||
import { Typography } from '@mui/material'
|
||||
import Markdown from '../markdown'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { GameIdContext } from '../../app'
|
||||
|
||||
/** Pop-up that is displaying the Game Info.
|
||||
*
|
||||
@@ -11,12 +13,15 @@ import Markdown from '../markdown'
|
||||
* controlled by the containing element.
|
||||
*/
|
||||
export function InfoPopup ({info, handleClose}: {info: string, handleClose: () => void}) {
|
||||
let { t } = useTranslation()
|
||||
const gameId = React.useContext(GameIdContext)
|
||||
|
||||
return <div className="modal-wrapper">
|
||||
<div className="modal-backdrop" onClick={handleClose} />
|
||||
<div className="modal">
|
||||
<div className="codicon codicon-close modal-close" onClick={handleClose}></div>
|
||||
<Typography variant="body1" component="div" className="welcome-text">
|
||||
<Markdown>{info}</Markdown>
|
||||
<Markdown>{t(info, {ns: gameId})}</Markdown>
|
||||
</Typography>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -113,6 +113,7 @@ export function WorldIcon({world, title, position, completedLevels, difficulty,
|
||||
difficulty: number,
|
||||
worldSize: number
|
||||
}) {
|
||||
const { t } = useTranslation()
|
||||
|
||||
// See level icons. Match radius computed there minus `1.2*r`
|
||||
const N = Math.max(worldSize, NMIN)
|
||||
@@ -151,7 +152,7 @@ export function WorldIcon({world, title, position, completedLevels, difficulty,
|
||||
width={1.42*R} height={1.42*R} transform={"translate("+ -.71*R +","+ -.71*R +")"}>
|
||||
<div className={unlocked && !completed ? "playable-world" : ''}>
|
||||
<p className="world-title" style={{fontSize: fontSize + "px"}}>
|
||||
{title ? title : world}
|
||||
{title ? t(title, {ns: gameId}) : world}
|
||||
</p>
|
||||
</div>
|
||||
</foreignObject>
|
||||
@@ -162,7 +163,7 @@ export function WorldIcon({world, title, position, completedLevels, difficulty,
|
||||
>
|
||||
<div className='world-label' style={{backgroundColor: completed ? darkgreen : unlocked ? darkblue : darkgrey}}>
|
||||
<p className='world-title' style={{fontSize: MINFONT + "px"}}>
|
||||
{title ? title : world}
|
||||
{title ? t(title, {ns: gameId}) : world}
|
||||
</p>
|
||||
</div>
|
||||
</foreignObject>}
|
||||
|
||||
Reference in New Issue
Block a user