allow hot reloading in level
This commit is contained in:
@@ -7,11 +7,8 @@ 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 { Box, Button, CircularProgress, FormControlLabel, FormGroup, Switch } from '@mui/material';
|
||||
import Grid from '@mui/material/Unstable_Grid2';
|
||||
|
||||
import LeftPanel from './LeftPanel';
|
||||
import { AbbreviationProvider } from 'lean4web/client/src/editor/abbreviation/AbbreviationProvider';
|
||||
import { AbbreviationRewriter } from 'lean4web/client/src/editor/abbreviation/rewriter/AbbreviationRewriter';
|
||||
@@ -23,7 +20,6 @@ import './level.css'
|
||||
import { ConnectionContext } from '../connection';
|
||||
import Infoview from './Infoview';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { MonacoServices } from 'monaco-languageclient';
|
||||
import { useLoadLevelQuery } from '../game/api';
|
||||
|
||||
|
||||
@@ -34,9 +30,6 @@ function Level() {
|
||||
const levelId = parseInt(params.levelId)
|
||||
const worldId = params.worldId
|
||||
|
||||
const [editor, setEditor] = useState<monaco.editor.IStandaloneCodeEditor|null>(null)
|
||||
const [infoProvider, setInfoProvider] = useState<null|InfoProvider>(null)
|
||||
const [infoviewApi, setInfoviewApi] = useState(null)
|
||||
const [expertInfoview, setExpertInfoview] = useState(false)
|
||||
|
||||
const codeviewRef = useRef<HTMLDivElement>(null)
|
||||
@@ -50,61 +43,10 @@ function Level() {
|
||||
|
||||
const connection = React.useContext(ConnectionContext)
|
||||
|
||||
useEffect(() => {
|
||||
const editor = monaco.editor.create(codeviewRef.current!, {
|
||||
glyphMargin: true,
|
||||
lightbulb: {
|
||||
enabled: true
|
||||
},
|
||||
unicodeHighlight: {
|
||||
ambiguousCharacters: false,
|
||||
},
|
||||
automaticLayout: true,
|
||||
minimap: {
|
||||
enabled: false
|
||||
},
|
||||
lineNumbersMinChars: 3,
|
||||
'semanticHighlighting.enabled': true,
|
||||
theme: 'vs-code-theme-converted'
|
||||
})
|
||||
|
||||
const infoProvider = new InfoProvider(connection.getLeanClient())
|
||||
const div: HTMLElement = infoviewRef.current!
|
||||
const infoviewApi = renderInfoview(infoProvider.getApi(), div)
|
||||
|
||||
setEditor(editor)
|
||||
setInfoProvider(infoProvider)
|
||||
setInfoviewApi(infoviewApi)
|
||||
|
||||
return () => { editor.dispose() }
|
||||
}, [])
|
||||
|
||||
|
||||
// The next function will be called when the level changes
|
||||
useEffect(() => {
|
||||
connection.startLeanClient().then((leanClient) => {
|
||||
if (editor) {
|
||||
|
||||
const uri = monaco.Uri.parse(`file:///${worldId}/${levelId}`)
|
||||
const model = monaco.editor.getModel(uri) ??
|
||||
monaco.editor.createModel('', 'lean4', uri)
|
||||
|
||||
editor.setModel(model)
|
||||
infoviewApi.serverRestarted(leanClient.initializeResult)
|
||||
infoProvider.openPreview(editor, infoviewApi)
|
||||
|
||||
new AbbreviationRewriter(new AbbreviationProvider(), model, editor)
|
||||
|
||||
|
||||
return () => { model.dispose(); }
|
||||
}
|
||||
})
|
||||
|
||||
}, [editor, levelId, connection])
|
||||
|
||||
|
||||
const level = useLoadLevelQuery({world: worldId, level: levelId})
|
||||
|
||||
const {editor, infoProvider} = useLevelEditor(worldId, levelId, codeviewRef, infoviewRef)
|
||||
|
||||
return <>
|
||||
<Box style={level.isLoading ? null : {display: "none"}} display="flex" alignItems="center" justifyContent="center" sx={{ height: "calc(100vh - 64px)" }}><CircularProgress /></Box>
|
||||
<Grid style={level.isLoading ? {display: "none"} : null} className="level" container sx={{ mt: 3, ml: 1, mr: 1 }} columnSpacing={{ xs: 1, sm: 2, md: 3 }}>
|
||||
@@ -136,3 +78,63 @@ function Level() {
|
||||
}
|
||||
|
||||
export default Level
|
||||
|
||||
|
||||
function useLevelEditor(worldId: string, levelId: number, codeviewRef, infoviewRef) {
|
||||
|
||||
const connection = React.useContext(ConnectionContext)
|
||||
|
||||
const [editor, setEditor] = useState<monaco.editor.IStandaloneCodeEditor|null>(null)
|
||||
const [infoProvider, setInfoProvider] = useState<null|InfoProvider>(null)
|
||||
const [infoviewApi, setInfoviewApi] = useState(null)
|
||||
|
||||
// Create Editor
|
||||
useEffect(() => {
|
||||
const editor = monaco.editor.create(codeviewRef.current!, {
|
||||
glyphMargin: true,
|
||||
lightbulb: {
|
||||
enabled: true
|
||||
},
|
||||
unicodeHighlight: {
|
||||
ambiguousCharacters: false,
|
||||
},
|
||||
automaticLayout: true,
|
||||
minimap: {
|
||||
enabled: false
|
||||
},
|
||||
lineNumbersMinChars: 3,
|
||||
'semanticHighlighting.enabled': true,
|
||||
theme: 'vs-code-theme-converted'
|
||||
})
|
||||
|
||||
const infoProvider = new InfoProvider(connection.getLeanClient())
|
||||
const div: HTMLElement = infoviewRef.current!
|
||||
const infoviewApi = renderInfoview(infoProvider.getApi(), div)
|
||||
|
||||
setEditor(editor)
|
||||
setInfoProvider(infoProvider)
|
||||
setInfoviewApi(infoviewApi)
|
||||
|
||||
}, [])
|
||||
|
||||
// Create model when level changes
|
||||
useEffect(() => {
|
||||
connection.startLeanClient().then((leanClient) => {
|
||||
if (editor) {
|
||||
|
||||
const uri = monaco.Uri.parse(`file:///${worldId}/${levelId}`)
|
||||
const model = monaco.editor.getModel(uri) ??
|
||||
monaco.editor.createModel('', 'lean4', uri)
|
||||
|
||||
editor.setModel(model)
|
||||
infoviewApi.serverRestarted(leanClient.initializeResult)
|
||||
infoProvider.openPreview(editor, infoviewApi)
|
||||
|
||||
new AbbreviationRewriter(new AbbreviationProvider(), model, editor)
|
||||
}
|
||||
})
|
||||
|
||||
}, [editor, levelId, connection])
|
||||
|
||||
return {editor, infoProvider}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user