routing for level

This commit is contained in:
Alexander Bentkamp
2022-12-07 12:35:54 +01:00
parent b8a8180d7e
commit 8dbdfb0f4d
7 changed files with 164 additions and 23 deletions
-5
View File
@@ -1,8 +1,6 @@
import * as React from 'react';
import { useState, useEffect } from 'react';
import { MathJaxContext } from "better-react-mathjax";
import * as rpc from 'vscode-ws-jsonrpc';
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api.js'
import { Outlet } from "react-router-dom";
import '@fontsource/roboto/300.css';
@@ -12,9 +10,6 @@ import '@fontsource/roboto/700.css';
import { AppBar, CssBaseline, Toolbar, Typography } from '@mui/material';
import Welcome from './components/Welcome';
import Level from './components/Level';
import GoodBye from './components/GoodBye';
import { useAppSelector } from './hooks';
function App() {
+17
View File
@@ -0,0 +1,17 @@
import * as React from 'react'
import { useRouteError } from "react-router-dom";
export default function ErrorPage() {
const error: any = useRouteError();
console.error(error);
return (
<div id="error-page">
<h1>Oops!</h1>
<p>Sorry, an unexpected error has occurred.</p>
<p>
<i>{error.statusText || error.message}</i>
</p>
</div>
);
}
+22 -9
View File
@@ -6,6 +6,8 @@ import '@fontsource/roboto/500.css';
import '@fontsource/roboto/700.css';
import ReactMarkdown from 'react-markdown';
import { MathJax } from "better-react-mathjax";
import { Link as RouterLink } from 'react-router-dom';
import { Button, FormControlLabel, FormGroup, Switch } from '@mui/material';
import Grid from '@mui/material/Unstable_Grid2';
@@ -20,10 +22,16 @@ import * as monaco from 'monaco-editor/esm/vs/editor/editor.api.js'
import './level.css'
import { ConnectionContext } from '../connection';
import Infoview from './Infoview';
import { useParams } from 'react-router-dom';
import { MonacoServices } from 'monaco-languageclient';
function Level() {
const level = 1
const [index, setIndex] = useState(level) // Level number
const params = useParams();
const levelId = parseInt(params.levelId)
const [tacticDocs, setTacticDocs] = useState([])
const [lemmaDocs, setLemmaDocs] = useState([])
const [editor, setEditor] = useState<monaco.editor.IStandaloneCodeEditor|null>(null)
@@ -64,7 +72,7 @@ function Level() {
useEffect(() => {
// Scroll to top when loading a new level
messagePanelRef.current!.scrollTo(0,0)
}, [level])
}, [levelId])
const connection = React.useContext(ConnectionContext)
@@ -97,12 +105,13 @@ function Level() {
return () => { editor.dispose() }
}, [])
const uri = `file:///level${level}`
const uri = `file:///level${levelId}`
// The next function will be called when the level changes
useEffect(() => {
connection.whenLeanClientStarted((leanClient) => {
if (editor) {
const model = monaco.editor.createModel('', 'lean4', monaco.Uri.parse(uri))
editor.setModel(model)
@@ -112,9 +121,10 @@ function Level() {
new AbbreviationRewriter(new AbbreviationProvider(), model, editor)
leanClient.sendRequest("loadLevel", {world: "TestWorld", level}).then((res) => {
leanClient.sendRequest("loadLevel", {world: "TestWorld", level: levelId}).then((res) => {
// setLevelTitle("Level " + res["index"] + ": " + res["title"])
setIndex(parseInt(res["index"]))
// setIndex(parseInt(res["index"]))
setTacticDocs(res["tactics"])
setLemmaDocs(res["lemmas"])
setIntroduction(res["introduction"])
@@ -124,7 +134,8 @@ function Level() {
return () => { model.dispose(); setReady(false) }
}
})
}, [editor, level, connection])
}, [editor, levelId, connection])
function loadLevel(index) {
setCompleted(false)
@@ -148,8 +159,10 @@ function Level() {
</div>
</Grid>
<Grid xs={4} className="info-panel">
<Button disabled={index <= 1} onClick={() => { loadLevel(index - 1) }} sx={{ ml: 3, mt: 2, mb: 2 }} disableFocusRipple>Previous Level</Button>
<Button disabled={index >= 99} onClick={() => { loadLevel(index + 1) }} sx={{ ml: 3, mt: 2, mb: 2 }} disableFocusRipple>Next Level</Button>
<Button disabled={levelId <= 1} component={RouterLink} to={`/level/${levelId - 1}`} sx={{ ml: 3, mt: 2, mb: 2 }} disableFocusRipple>Previous Level</Button>
<Button disabled={false} component={RouterLink} to={`/level/${levelId + 1}`} sx={{ ml: 3, mt: 2, mb: 2 }} disableFocusRipple>Next Level</Button>
<div style={{display: expertInfoview ? 'block' : 'none' }} ref={infoviewRef} className="infoview vscode-light"></div>
<div style={{display: expertInfoview ? 'none' : 'block' }}>
<Infoview leanClient={connection.getLeanClient()} editor={editor} editorApi={infoProvider?.getApi()} />
+4 -7
View File
@@ -11,6 +11,8 @@ import cytoscape from 'cytoscape'
import klay from 'cytoscape-klay';
import { useSelector, useDispatch } from 'react-redux'
import { fetchGame } from '../game/gameSlice'
import { Link as RouterLink } from 'react-router-dom';
cytoscape.use( klay );
@@ -19,13 +21,8 @@ import { LeanClient } from 'lean4web/client/src/editor/leanclient';
import { ConnectionContext } from '../connection';
import { useAppDispatch, useAppSelector } from '../hooks';
interface WelcomeProps {
setNbLevels: any;
startGame: any;
setConclusion: any;
}
function Welcome({ setNbLevels, startGame, setConclusion }: WelcomeProps) {
function Welcome() {
const dispatch = useAppDispatch()
const worldsRef = useRef<HTMLDivElement>(null)
@@ -94,7 +91,7 @@ function Welcome({ setNbLevels, startGame, setConclusion }: WelcomeProps) {
</Typography>
</Box>
<Box textAlign='center' sx={{ m: 5 }}>
<Button onClick={startGame} variant="contained">Start rescue mission</Button>
<Button component={RouterLink} to="/level/1" variant="contained">Start rescue mission</Button>
</Box>
<div ref={worldsRef} style={{"width": "100%","height": "50em"}} />
</div>
+9 -2
View File
@@ -2,7 +2,6 @@ import * as React from 'react';
import { createRoot } from 'react-dom/client';
import './index.css';
import App from './App';
import Level from './components/Level';
import { ConnectionContext, connection } from './connection'
import { store } from './store';
import { Provider } from 'react-redux';
@@ -11,18 +10,26 @@ import {
RouterProvider,
Route,
} from "react-router-dom";
import "./index.css";
import ErrorPage from './ErrorPage';
import Welcome from './components/Welcome';
import Level from './components/Level';
import { monacoSetup } from 'lean4web/client/src/monacoSetup';
monacoSetup()
const router = createHashRouter([
{
path: "/",
element: <App />,
errorElement: <ErrorPage />,
children: [
{
path: "/",
element: <Welcome />,
},
{
path: "/level/:levelId",
element: <Level />,
},
],