import * as React from 'react' import { createContext, useContext, useState } from 'react' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { faDownload, faUpload, faEraser, faBook, faBookOpen, faGlobe, faHome, faArrowRight, faArrowLeft, faXmark, faBars, faCode, faCircleInfo, faTerminal, faGear, IconDefinition, faShield } from '@fortawesome/free-solid-svg-icons' import { GameIdContext } from "../app" import { PageContext, PreferencesContext } from "./infoview/context" import { useGetGameInfoQuery, useLoadLevelQuery } from '../state/api' import { downloadProgress } from './popup/erase' import { useTranslation } from 'react-i18next' import '../css/navigation.css' import { PopupContext } from './popup/popup' import { useSelector } from 'react-redux' import { selectCompleted, selectDifficulty, selectProgress } from '../state/progress' import lean4gameConfig from '../config.json' import { Flag } from './flag' import { useAppSelector } from '../hooks' /** SVG github icon */ function GithubIcon () { return } /** A button to appear in the navigation (both, top bar or dropdown). */ export const NavButton: React.FC<{ icon?: IconDefinition iconElement?: JSX.Element text?: string onClick?: React.MouseEventHandler title?: string href?: string inverted?: boolean disabled?: boolean }> = ({icon, iconElement, text, onClick=()=>{}, title, href=null, inverted=false, disabled=false}) => { return {iconElement ?? (icon && )}{text && <> {text}} } /** Context which manages the dropdown navigation */ const NavigationContext = createContext<{ navOpen: boolean, setNavOpen: React.Dispatch> }>({navOpen: false, setNavOpen: () => {}}) /** Content of the navigation during game selection. */ function NavigationLandingPage () { return
} /** Content of the navigation on Desktop during world selection. */ function DesktopNavigationOverview () { const { t } = useTranslation() const { gameId } = useContext(GameIdContext) const { setPopupContent } = useContext(PopupContext) const gameInfo = useGetGameInfoQuery({game: gameId}) return
{setPopupContent("rules")}} inverted={true} />
{t(gameInfo.data?.title, {ns: gameId})}
} /** Content of the navigation on Mobile during world selection. */ function MobileNavigationOverview () { const { t } = useTranslation() const {page, setPage} = useContext(PageContext) const { setPopupContent } = useContext(PopupContext) return
{setPopupContent("rules")}} inverted={true} />
{page > 0 && setPage(page - 1)} inverted={true} /> } { page < 2 && setPage(page+1)} inverted={true} /> }
} /** Content of the navigation on Desktop in a level. */ function DesktopNavigationLevel () { const { t } = useTranslation() const { gameId, worldId, levelId } = useContext(GameIdContext) const { typewriterMode, setTypewriterMode, lockEditorMode } = useContext(PageContext) const gameInfo = useGetGameInfoQuery({game: gameId}) const levelInfo = useLoadLevelQuery({game: gameId, world: worldId, level: levelId}) const difficulty = useSelector(selectDifficulty(gameId)) const completed = useAppSelector(selectCompleted(gameId, worldId, levelId)) /** toggle input mode if allowed */ function toggleInputMode(ev: React.MouseEvent) { if (!lockEditorMode) { setTypewriterMode(!typewriterMode) console.log('test') } } const worldTitle = gameInfo.data?.worlds.nodes[worldId]?.title const levelTitle = ((levelId == 0) ? t("Introduction") : ( t("Level") + ` ${levelId}` + (gameInfo.data?.worldSize[worldId] ? ` / ${gameInfo.data?.worldSize[worldId]}` : '') + (levelInfo.data?.title ? ` : ${t(levelInfo?.data?.title, {ns: gameId})}` : '') ) ) return
{worldTitle ? `${t("World")}: ${t(worldTitle, {ns: gameId})}` : ''}
{ levelTitle }
{ levelId > 0 && } { levelId == gameInfo.data?.worldSize[worldId] ? : } { levelId > 0 && toggleInputMode(ev)} title={lockEditorMode ? t("Editor mode is enforced!") : typewriterMode ? t("Editor mode") : t("Typewriter mode")} /> }
} /** Content of the navigation on Mobile in a level. */ function MobileNavigationLevel () { const { t } = useTranslation() const {gameId, worldId, levelId} = useContext(GameIdContext) const {page, setPage} = useContext(PageContext) const gameInfo = useGetGameInfoQuery({game: gameId}) const levelInfo = useLoadLevelQuery({game: gameId, world: worldId, level: levelId}) let title = worldId ? ` ${levelId} / ${gameInfo.data?.worldSize[worldId]}`+ (levelInfo?.data?.title && ` : ${t(levelInfo?.data?.title, {ns: gameId})}`) : '' return
{title}
setPage((page == 1) ? 2 : 1)} inverted={true} />
} /** The skeleton of the navigation which is the same across all layouts. */ export function Navigation () { const { t, i18n } = useTranslation() const { gameId, worldId, levelId } = useContext(GameIdContext) const { mobile, language, setLanguage } = useContext(PreferencesContext) const { setPopupContent } = useContext(PopupContext) const { typewriterMode, setTypewriterMode, lockEditorMode } = useContext(PageContext) const gameProgress = useSelector(selectProgress(gameId)) const gameInfo = useGetGameInfoQuery({game: gameId}) const levelInfo = useLoadLevelQuery({game: gameId, world: worldId, level: levelId}) const difficulty = useSelector(selectDifficulty(gameId)) const completed = useAppSelector(selectCompleted(gameId, worldId, levelId)) const [navOpen, setNavOpen] = useState(false) const [langNavOpen, setLangNavOpen] = useState(false) function toggleNav () {setNavOpen(!navOpen); setLangNavOpen(false)} function toggleLangNav () {setLangNavOpen(!langNavOpen); setNavOpen(false)} /** toggle input mode if allowed */ function toggleInputMode(ev: React.MouseEvent) { if (!lockEditorMode) { setTypewriterMode(!typewriterMode) console.log('test') } } return }