force editor mode if template present
This commit is contained in:
@@ -281,7 +281,7 @@ export function WelcomeAppBar({gameInfo, toggleImpressum, openEraseMenu, openUpl
|
|||||||
/** The top-navigation bar */
|
/** The top-navigation bar */
|
||||||
export function LevelAppBar({
|
export function LevelAppBar({
|
||||||
isLoading, levelTitle, impressum, toggleImpressum,
|
isLoading, levelTitle, impressum, toggleImpressum,
|
||||||
pageNumber = undefined, setPageNumber = undefined}) {
|
pageNumber = undefined, setPageNumber = undefined, lockEditorMode=false}) {
|
||||||
const gameId = React.useContext(GameIdContext)
|
const gameId = React.useContext(GameIdContext)
|
||||||
const {worldId, levelId} = React.useContext(WorldLevelIdContext)
|
const {worldId, levelId} = React.useContext(WorldLevelIdContext)
|
||||||
const gameInfo = useGetGameInfoQuery({game: gameId})
|
const gameInfo = useGetGameInfoQuery({game: gameId})
|
||||||
@@ -295,6 +295,13 @@ export function LevelAppBar({
|
|||||||
|
|
||||||
const [navOpen, setNavOpen] = React.useState(false)
|
const [navOpen, setNavOpen] = React.useState(false)
|
||||||
|
|
||||||
|
function toggleEditor(ev) {
|
||||||
|
if (!lockEditorMode){
|
||||||
|
setTypewriterMode(!typewriterMode)
|
||||||
|
setNavOpen(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return <div className="app-bar" style={isLoading ? {display: "none"} : null} >
|
return <div className="app-bar" style={isLoading ? {display: "none"} : null} >
|
||||||
{mobile ?
|
{mobile ?
|
||||||
<>
|
<>
|
||||||
@@ -388,9 +395,9 @@ export function LevelAppBar({
|
|||||||
<FontAwesomeIcon icon={faHome} /> Leave World
|
<FontAwesomeIcon icon={faHome} /> Leave World
|
||||||
</Button>
|
</Button>
|
||||||
}
|
}
|
||||||
<Button className="btn btn-inverted toggle-width" disabled={levelId <= 0} inverted="true" to=""
|
<Button className="btn btn-inverted toggle-width" disabled={levelId <= 0 || lockEditorMode} inverted="true" to=""
|
||||||
onClick={(ev) => { setTypewriterMode(!typewriterMode); setNavOpen(false) }}
|
onClick={(ev) => toggleEditor(ev)}
|
||||||
title={typewriterMode ? "Editor mode" : "Typewriter mode"}>
|
title={lockEditorMode ? "Editor mode is enforced!" : typewriterMode ? "Editor mode" : "Typewriter mode"}>
|
||||||
<FontAwesomeIcon icon={typewriterMode ? faCode : faTerminal} />
|
<FontAwesomeIcon icon={typewriterMode ? faCode : faTerminal} />
|
||||||
</Button>
|
</Button>
|
||||||
<Button className="btn btn-inverted toggle-width" title="information, Impressum, privacy policy" inverted="true" to="" onClick={(ev) => {toggleImpressum(ev); setNavOpen(false)}}>
|
<Button className="btn btn-inverted toggle-width" title="information, Impressum, privacy policy" inverted="true" to="" onClick={(ev) => {toggleImpressum(ev); setNavOpen(false)}}>
|
||||||
|
|||||||
@@ -21,13 +21,13 @@ import * as monaco from 'monaco-editor/esm/vs/editor/editor.api.js'
|
|||||||
import { GameIdContext } from '../../app';
|
import { GameIdContext } from '../../app';
|
||||||
import { useAppDispatch, useAppSelector } from '../../hooks';
|
import { useAppDispatch, useAppSelector } from '../../hooks';
|
||||||
import { LevelInfo } from '../../state/api';
|
import { LevelInfo } from '../../state/api';
|
||||||
import { changedInventory, levelCompleted, selectCompleted, selectInventory } from '../../state/progress';
|
import { changedInventory, levelCompleted, selectCode, selectCompleted, selectInventory } from '../../state/progress';
|
||||||
import Markdown from '../markdown';
|
import Markdown from '../markdown';
|
||||||
|
|
||||||
import { Infos } from './infos';
|
import { Infos } from './infos';
|
||||||
import { AllMessages, Errors, WithLspDiagnosticsContext } from './messages';
|
import { AllMessages, Errors, WithLspDiagnosticsContext } from './messages';
|
||||||
import { Goal } from './goals';
|
import { Goal } from './goals';
|
||||||
import { DeletedChatContext, InputModeContext, MobileContext, MonacoEditorContext, ProofContext, ProofStep, SelectionContext } from './context';
|
import { DeletedChatContext, InputModeContext, MobileContext, MonacoEditorContext, ProofContext, ProofStep, SelectionContext, WorldLevelIdContext } from './context';
|
||||||
import { Typewriter, hasErrors, hasInteractiveErrors } from './typewriter';
|
import { Typewriter, hasErrors, hasInteractiveErrors } from './typewriter';
|
||||||
import { InteractiveDiagnostic } from '@leanprover/infoview/*';
|
import { InteractiveDiagnostic } from '@leanprover/infoview/*';
|
||||||
import { Button } from '../button';
|
import { Button } from '../button';
|
||||||
@@ -70,7 +70,7 @@ function DualEditorMain({ worldId, levelId, level, worldSize }: { worldId: strin
|
|||||||
'$/game/completed',
|
'$/game/completed',
|
||||||
(params: any) => {
|
(params: any) => {
|
||||||
if (ec.events.changedCursorLocation.current &&
|
if (ec.events.changedCursorLocation.current &&
|
||||||
ec.events.changedCursorLocation.current.uri === params.uri) {
|
ec.events.changedCursorLocation.current.uri === params.uri) {
|
||||||
dispatch(levelCompleted({ game: gameId, world: worldId, level: levelId }))
|
dispatch(levelCompleted({ game: gameId, world: worldId, level: levelId }))
|
||||||
|
|
||||||
// On completion, add the names of all new items to the local storage
|
// On completion, add the names of all new items to the local storage
|
||||||
@@ -116,7 +116,7 @@ function DualEditorMain({ worldId, levelId, level, worldSize }: { worldId: strin
|
|||||||
{typewriterMode ?
|
{typewriterMode ?
|
||||||
<TypewriterInterface world={worldId} level={levelId} data={level} worldSize={worldSize}/>
|
<TypewriterInterface world={worldId} level={levelId} data={level} worldSize={worldSize}/>
|
||||||
:
|
:
|
||||||
<Main key={`${worldId}/${levelId}`} world={worldId} level={levelId} />
|
<Main key={`${worldId}/${levelId}`} world={worldId} level={levelId} data={level} />
|
||||||
}
|
}
|
||||||
</ProgressContext.Provider>
|
</ProgressContext.Provider>
|
||||||
</WithLspDiagnosticsContext>
|
</WithLspDiagnosticsContext>
|
||||||
@@ -141,12 +141,24 @@ function ExerciseStatement({ data }) {
|
|||||||
|
|
||||||
// TODO: This is only used in `EditorInterface`
|
// TODO: This is only used in `EditorInterface`
|
||||||
// while `TypewriterInterface` has this copy-pasted in.
|
// while `TypewriterInterface` has this copy-pasted in.
|
||||||
export function Main(props: { world: string, level: number }) {
|
export function Main(props: { world: string, level: number, data: LevelInfo}) {
|
||||||
const ec = React.useContext(EditorContext);
|
const ec = React.useContext(EditorContext);
|
||||||
const gameId = React.useContext(GameIdContext)
|
const gameId = React.useContext(GameIdContext)
|
||||||
|
const {worldId, levelId} = React.useContext(WorldLevelIdContext)
|
||||||
|
|
||||||
const completed = useAppSelector(selectCompleted(gameId, props.world, props.level))
|
const completed = useAppSelector(selectCompleted(gameId, props.world, props.level))
|
||||||
|
|
||||||
|
console.debug(`template: ${props.data.template}`)
|
||||||
|
|
||||||
|
// React.useEffect (() => {
|
||||||
|
// if (props.data.template) {
|
||||||
|
// let code: string = selectCode(gameId, worldId, levelId)(store.getState())
|
||||||
|
// if (!code.length) {
|
||||||
|
// //models.push(monaco.editor.createModel(code, 'lean4', uri))
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }, [props.data.template])
|
||||||
|
|
||||||
/* Set up updates to the global infoview state on editor events. */
|
/* Set up updates to the global infoview state on editor events. */
|
||||||
const config = useEventResult(ec.events.changedInfoviewConfig) ?? defaultInfoviewConfig;
|
const config = useEventResult(ec.events.changedInfoviewConfig) ?? defaultInfoviewConfig;
|
||||||
|
|
||||||
|
|||||||
@@ -252,6 +252,25 @@ function PlayableLevel({impressum, setImpressum}) {
|
|||||||
const {editor, infoProvider, editorConnection} =
|
const {editor, infoProvider, editorConnection} =
|
||||||
useLevelEditor(codeviewRef, initialCode, initialSelections, onDidChangeContent, onDidChangeSelection)
|
useLevelEditor(codeviewRef, initialCode, initialSelections, onDidChangeContent, onDidChangeSelection)
|
||||||
|
|
||||||
|
useEffect (() => {
|
||||||
|
// Lock editor mode
|
||||||
|
if (level?.data?.template) {
|
||||||
|
setTypewriterMode(false)
|
||||||
|
|
||||||
|
console.debug(`inserting template: ${level.data.template}`)
|
||||||
|
|
||||||
|
// // TODO: This does not work! HERE
|
||||||
|
// // Probably overwritten by a query to the server
|
||||||
|
// editor.executeEdits("command-line", [{
|
||||||
|
// range: editor.getModel().getFullModelRange(),
|
||||||
|
// text: level.data.template,
|
||||||
|
// forceMoveMarkers: false
|
||||||
|
// }])
|
||||||
|
} else {
|
||||||
|
setTypewriterMode(true)
|
||||||
|
}
|
||||||
|
}, [level, levelId, worldId, gameId])
|
||||||
|
|
||||||
/** Unused. Was implementing an undo button, which has been replaced by `deleteProof` inside
|
/** Unused. Was implementing an undo button, which has been replaced by `deleteProof` inside
|
||||||
* `TypewriterInterface`.
|
* `TypewriterInterface`.
|
||||||
*/
|
*/
|
||||||
@@ -355,6 +374,7 @@ function PlayableLevel({impressum, setImpressum}) {
|
|||||||
<MonacoEditorContext.Provider value={editor}>
|
<MonacoEditorContext.Provider value={editor}>
|
||||||
<LevelAppBar
|
<LevelAppBar
|
||||||
isLoading={level.isLoading}
|
isLoading={level.isLoading}
|
||||||
|
lockEditorMode={level.data?.template !== null}
|
||||||
levelTitle={`${mobile ? '' : 'Level '}${levelId} / ${gameInfo.data?.worldSize[worldId]}` +
|
levelTitle={`${mobile ? '' : 'Level '}${levelId} / ${gameInfo.data?.worldSize[worldId]}` +
|
||||||
(level?.data?.title && ` : ${level?.data?.title}`)}
|
(level?.data?.title && ` : ${level?.data?.title}`)}
|
||||||
impressum={impressum}
|
impressum={impressum}
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ partial def findForbiddenTactics (inputCtx : Parser.InputContext)
|
|||||||
for n in ns do
|
for n in ns do
|
||||||
let some (.thmInfo ..) := (← getEnv).find? n
|
let some (.thmInfo ..) := (← getEnv).find? n
|
||||||
| return () -- not a theroem -> ignore
|
| return () -- not a theroem -> ignore
|
||||||
|
-- TODO: Filter thhe theorem we want to proof to avoid structural recursion!
|
||||||
let lemmasAndDefs := levelParams.lemmas ++ levelParams.definitions
|
let lemmasAndDefs := levelParams.lemmas ++ levelParams.definitions
|
||||||
match lemmasAndDefs.find? (fun l => l.name == n) with
|
match lemmasAndDefs.find? (fun l => l.name == n) with
|
||||||
| none => addWarningMessage info s!"You have not unlocked the lemma/definition '{n}' yet!"
|
| none => addWarningMessage info s!"You have not unlocked the lemma/definition '{n}' yet!"
|
||||||
|
|||||||
Reference in New Issue
Block a user