routing for level
This commit is contained in:
@@ -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() {
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
@@ -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()} />
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 />,
|
||||
},
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user