wip on hints
This commit is contained in:
@@ -29,7 +29,7 @@ import { useStore } from 'react-redux';
|
|||||||
import { EditorContext, ConfigContext, ProgressContext, VersionContext } from '../../../node_modules/lean4-infoview/src/infoview/contexts';
|
import { EditorContext, ConfigContext, ProgressContext, VersionContext } from '../../../node_modules/lean4-infoview/src/infoview/contexts';
|
||||||
import { EditorConnection, EditorEvents } from '../../../node_modules/lean4-infoview/src/infoview/editorConnection';
|
import { EditorConnection, EditorEvents } from '../../../node_modules/lean4-infoview/src/infoview/editorConnection';
|
||||||
import { EventEmitter } from '../../../node_modules/lean4-infoview/src/infoview/event';
|
import { EventEmitter } from '../../../node_modules/lean4-infoview/src/infoview/event';
|
||||||
import { Main } from './infoview/main'
|
import { Main, EditorInterface } from './infoview/main'
|
||||||
import type { Location } from 'vscode-languageserver-protocol';
|
import type { Location } from 'vscode-languageserver-protocol';
|
||||||
|
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||||
@@ -43,19 +43,22 @@ import { Alert } from '@mui/material';
|
|||||||
import { GameIdContext } from '../App';
|
import { GameIdContext } from '../App';
|
||||||
|
|
||||||
import { GameHint } from './infoview/rpcApi';
|
import { GameHint } from './infoview/rpcApi';
|
||||||
|
import { Hints } from './infoview/hints';
|
||||||
|
|
||||||
export const MonacoEditorContext = React.createContext<monaco.editor.IStandaloneCodeEditor>(null as any);
|
export const MonacoEditorContext = React.createContext<monaco.editor.IStandaloneCodeEditor>(null as any);
|
||||||
|
|
||||||
// TODO: Not used yet
|
|
||||||
export const HintContext = React.createContext<{
|
export const HintContext = React.createContext<{
|
||||||
|
showHiddenHints : boolean,
|
||||||
|
setShowHiddenHints: React.Dispatch<React.SetStateAction<boolean>>
|
||||||
hints: Array<GameHint>,
|
hints: Array<GameHint>,
|
||||||
setHints: React.Dispatch<React.SetStateAction<Array<GameHint>>>
|
setHints: React.Dispatch<React.SetStateAction<Array<GameHint>>>
|
||||||
}>({
|
}>({
|
||||||
|
showHiddenHints: true,
|
||||||
|
setShowHiddenHints: () => {},
|
||||||
hints: [],
|
hints: [],
|
||||||
setHints: () => {},
|
setHints: () => {},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
export const InputModeContext = React.createContext<{
|
export const InputModeContext = React.createContext<{
|
||||||
commandLineMode: boolean,
|
commandLineMode: boolean,
|
||||||
setCommandLineMode: React.Dispatch<React.SetStateAction<boolean>>,
|
setCommandLineMode: React.Dispatch<React.SetStateAction<boolean>>,
|
||||||
@@ -94,20 +97,6 @@ function ExerciseStatement({data}) {
|
|||||||
</Markdown></div>
|
</Markdown></div>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ref: the codeViewRef. Used to edit the editor's content even if not visible
|
|
||||||
function EditorInterface({data, codeviewRef, hidden, worldId, levelId, editorConnection}) {
|
|
||||||
|
|
||||||
const { commandLineMode, setCommandLineMode } = React.useContext(InputModeContext)
|
|
||||||
|
|
||||||
return <div className={hidden ? 'hidden' : ''}>
|
|
||||||
<div className={`statement ${commandLineMode ? 'hidden' : ''}`}><code>{data?.descrFormat}</code></div>
|
|
||||||
<div ref={codeviewRef} className={'codeview'}></div>
|
|
||||||
{editorConnection && <Main key={`${worldId}/${levelId}`} world={worldId} level={levelId} />}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
|
|
||||||
function ReducedInterface({worldId, levelId, editorConnection}) {
|
function ReducedInterface({worldId, levelId, editorConnection}) {
|
||||||
return <div>
|
return <div>
|
||||||
{/* <button className="btn" onClick={handleUndo} disabled={!canUndo}><FontAwesomeIcon icon={faRotateLeft} /> Undo</button> */}
|
{/* <button className="btn" onClick={handleUndo} disabled={!canUndo}><FontAwesomeIcon icon={faRotateLeft} /> Undo</button> */}
|
||||||
@@ -130,6 +119,7 @@ function PlayableLevel({worldId, levelId}) {
|
|||||||
// The array of all shown hints. This excludes introduction and conclusion
|
// The array of all shown hints. This excludes introduction and conclusion
|
||||||
// TODO: Not used yet
|
// TODO: Not used yet
|
||||||
const [hints, setHints] = useState(Array<GameHint>)
|
const [hints, setHints] = useState(Array<GameHint>)
|
||||||
|
const [showHiddenHints, setShowHiddenHints] = useState(false)
|
||||||
|
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
@@ -239,11 +229,19 @@ function PlayableLevel({worldId, levelId}) {
|
|||||||
<LevelAppBar isLoading={level.isLoading} levelTitle={levelTitle} worldId={worldId} levelId={levelId} />
|
<LevelAppBar isLoading={level.isLoading} levelTitle={levelTitle} worldId={worldId} levelId={levelId} />
|
||||||
<Split minSize={0} snapOffset={200} sizes={[25, 50, 25]} className={`app-content level ${level.isLoading ? 'hidden' : ''}`}>
|
<Split minSize={0} snapOffset={200} sizes={[25, 50, 25]} className={`app-content level ${level.isLoading ? 'hidden' : ''}`}>
|
||||||
<div ref={chatPanelRef} className="chat-panel">
|
<div ref={chatPanelRef} className="chat-panel">
|
||||||
|
<HintContext.Provider value={{showHiddenHints, setShowHiddenHints, hints, setHints}}>
|
||||||
{level?.data?.introduction &&
|
{level?.data?.introduction &&
|
||||||
<div className="message info">
|
<div className="message info">
|
||||||
<Markdown>{level?.data?.introduction}</Markdown>
|
<Markdown>{level?.data?.introduction}</Markdown>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
{/* {openHints.map(hint => <Hint hint={hint} />)}
|
||||||
|
{hiddenHints.length > 0 &&
|
||||||
|
<FormControlLabel
|
||||||
|
control={<Switch checked={showHints} onChange={() => setShowHints((prev) => !prev)} />}
|
||||||
|
label="I need help!"
|
||||||
|
/>}
|
||||||
|
{showHints && hiddenHints.map(hint => <Hint hint={hint} />)} */}
|
||||||
{hints.map(hint =>
|
{hints.map(hint =>
|
||||||
<div className="message info"><Markdown>{hint.text}</Markdown></div>)
|
<div className="message info"><Markdown>{hint.text}</Markdown></div>)
|
||||||
}
|
}
|
||||||
@@ -257,16 +255,17 @@ function PlayableLevel({worldId, levelId}) {
|
|||||||
<Markdown>{level?.data?.conclusion}</Markdown>
|
<Markdown>{level?.data?.conclusion}</Markdown>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
{ hints.map(hint => <div className="message info"><Markdown>{hint.text}</Markdown></div>) }
|
{/* { hints.map(hint => <div className="message info"><Markdown>{hint.text}</Markdown></div>) } */}
|
||||||
|
<Hints hints={hints} showHidden={showHiddenHints}/>
|
||||||
{levelId >= gameInfo.data?.worldSize[worldId] ?
|
{levelId >= gameInfo.data?.worldSize[worldId] ?
|
||||||
<Button to={`/${gameId}`}><FontAwesomeIcon icon={faHome} /></Button> :
|
<Button to={`/${gameId}`}><FontAwesomeIcon icon={faHome} /></Button> :
|
||||||
<Button to={`/${gameId}/world/${worldId}/level/${levelId + 1}`}>
|
<Button to={`/${gameId}/world/${worldId}/level/${levelId + 1}`}>
|
||||||
Next <FontAwesomeIcon icon={faArrowRight} /></Button>}
|
Next <FontAwesomeIcon icon={faArrowRight} /></Button>}
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
</HintContext.Provider>
|
||||||
</div>
|
</div>
|
||||||
<div className="exercise-panel">
|
<div className="exercise-panel">
|
||||||
<HintContext.Provider value={{hints, setHints}}>
|
|
||||||
<EditorContext.Provider value={editorConnection}>
|
<EditorContext.Provider value={editorConnection}>
|
||||||
<MonacoEditorContext.Provider value={editor}>
|
<MonacoEditorContext.Provider value={editor}>
|
||||||
<ExerciseStatement data={level?.data} />
|
<ExerciseStatement data={level?.data} />
|
||||||
@@ -284,7 +283,6 @@ function PlayableLevel({worldId, levelId}) {
|
|||||||
{/* {editorConnection && <Main key={`${worldId}/${levelId}`} world={worldId} level={levelId} />} */}
|
{/* {editorConnection && <Main key={`${worldId}/${levelId}`} world={worldId} level={levelId} />} */}
|
||||||
</MonacoEditorContext.Provider>
|
</MonacoEditorContext.Provider>
|
||||||
</EditorContext.Provider>
|
</EditorContext.Provider>
|
||||||
</HintContext.Provider>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="inventory-panel">
|
<div className="inventory-panel">
|
||||||
{!level.isLoading &&
|
{!level.isLoading &&
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ export const Goal = React.memo((props: GoalProps) => {
|
|||||||
// if (props.goal.isInserted) cn += 'b--inserted '
|
// if (props.goal.isInserted) cn += 'b--inserted '
|
||||||
// if (props.goal.isRemoved) cn += 'b--removed '
|
// if (props.goal.isRemoved) cn += 'b--removed '
|
||||||
|
|
||||||
const hints = <Hints hints={goal.hints} key={goal.mvarId} />
|
// const hints = <Hints hints={goal.hints} key={goal.mvarId} />
|
||||||
const objectHyps = hyps.filter(hyp => !hyp.isAssumption)
|
const objectHyps = hyps.filter(hyp => !hyp.isAssumption)
|
||||||
const assumptionHyps = hyps.filter(hyp => hyp.isAssumption)
|
const assumptionHyps = hyps.filter(hyp => hyp.isAssumption)
|
||||||
const {commandLineMode} = React.useContext(InputModeContext)
|
const {commandLineMode} = React.useContext(InputModeContext)
|
||||||
@@ -172,7 +172,7 @@ export const Goal = React.memo((props: GoalProps) => {
|
|||||||
{assumptionHyps.map((h, i) => <Hyp hyp={h} mvarId={goal.mvarId} key={i} />)}</div> }
|
{assumptionHyps.map((h, i) => <Hyp hyp={h} mvarId={goal.mvarId} key={i} />)}</div> }
|
||||||
{commandLine && commandLineMode && <CommandLine />}
|
{commandLine && commandLineMode && <CommandLine />}
|
||||||
{!filter.reverse && goalLi}
|
{!filter.reverse && goalLi}
|
||||||
{showHints && hints}
|
{/* {showHints && hints} */}
|
||||||
</div>
|
</div>
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -7,21 +7,13 @@ export function Hint({hint} : {hint: GameHint}) {
|
|||||||
return <div className="message info"><Markdown>{hint.text}</Markdown></div>
|
return <div className="message info"><Markdown>{hint.text}</Markdown></div>
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Hints({hints} : {hints: GameHint[]}) {
|
export function Hints({hints, showHidden} : {hints: GameHint[], showHidden: boolean}) {
|
||||||
|
|
||||||
|
|
||||||
const [showHints, setShowHints] = React.useState(false);
|
|
||||||
|
|
||||||
const openHints = hints.filter(hint => !hint.hidden)
|
const openHints = hints.filter(hint => !hint.hidden)
|
||||||
const hiddenHints = hints.filter(hint => hint.hidden)
|
const hiddenHints = hints.filter(hint => hint.hidden)
|
||||||
|
|
||||||
return <>
|
return <>
|
||||||
{openHints.map(hint => <Hint hint={hint} />)}
|
{openHints.map(hint => <Hint hint={hint} />)}
|
||||||
{hiddenHints.length > 0 &&
|
{showHidden && hiddenHints.map(hint => <Hint hint={hint} />)}
|
||||||
<FormControlLabel
|
|
||||||
control={<Switch checked={showHints} onChange={() => setShowHints((prev) => !prev)} />}
|
|
||||||
label="I need help!"
|
|
||||||
/>}
|
|
||||||
{showHints && hiddenHints.map(hint => <Hint hint={hint} />)}
|
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import { GoalsLocation, Locations, LocationsContext } from '../../../../node_mod
|
|||||||
import { InteractiveCode } from '../../../../node_modules/lean4-infoview/src/infoview/interactiveCode'
|
import { InteractiveCode } from '../../../../node_modules/lean4-infoview/src/infoview/interactiveCode'
|
||||||
import { CircularProgress } from '@mui/material';
|
import { CircularProgress } from '@mui/material';
|
||||||
import { InputModeContext, MonacoEditorContext, HintContext } from '../Level'
|
import { InputModeContext, MonacoEditorContext, HintContext } from '../Level'
|
||||||
|
import { Hint } from './hints';
|
||||||
|
|
||||||
|
|
||||||
type InfoStatus = 'updating' | 'error' | 'ready';
|
type InfoStatus = 'updating' | 'error' | 'ready';
|
||||||
@@ -255,6 +256,10 @@ function useIsProcessingAt(p: DocumentPosition): boolean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function InfoAux(props: InfoProps) {
|
function InfoAux(props: InfoProps) {
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
const hintContext = React.useContext(HintContext)
|
||||||
|
|
||||||
const config = React.useContext(ConfigContext)
|
const config = React.useContext(ConfigContext)
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||||
@@ -409,6 +414,11 @@ function InfoAux(props: InfoProps) {
|
|||||||
setDisplayProps(dp => ({ ...dp, status: 'updating' }))
|
setDisplayProps(dp => ({ ...dp, status: 'updating' }))
|
||||||
else if (state.state === 'resolved') {
|
else if (state.state === 'resolved') {
|
||||||
setDisplayProps({ ...state.value, triggerUpdate })
|
setDisplayProps({ ...state.value, triggerUpdate })
|
||||||
|
// if (state.value.goals) {
|
||||||
|
// hintContext.setHints(state.value.goals[0]?.hints)
|
||||||
|
// }
|
||||||
|
// NOT Working
|
||||||
|
|
||||||
} else if (state.state === 'rejected' && state.error !== 'retry') {
|
} else if (state.state === 'rejected' && state.error !== 'retry') {
|
||||||
// The code inside `useAsyncWithTrigger` may only ever reject with a `retry` exception.
|
// The code inside `useAsyncWithTrigger` may only ever reject with a `retry` exception.
|
||||||
console.warn('Unreachable code reached with error: ', state.error)
|
console.warn('Unreachable code reached with error: ', state.error)
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import { ServerVersion } from '../../../../node_modules/lean4-infoview/src/infov
|
|||||||
import { useAppDispatch, useAppSelector } from '../../hooks';
|
import { useAppDispatch, useAppSelector } from '../../hooks';
|
||||||
import { levelCompleted, selectCompleted } from '../../state/progress';
|
import { levelCompleted, selectCompleted } from '../../state/progress';
|
||||||
import { GameIdContext } from '../../App';
|
import { GameIdContext } from '../../App';
|
||||||
|
import { InputModeContext } from '../Level';
|
||||||
|
|
||||||
|
|
||||||
export function Main(props: {world: string, level: number}) {
|
export function Main(props: {world: string, level: number}) {
|
||||||
@@ -101,3 +102,16 @@ export function Main(props: {world: string, level: number}) {
|
|||||||
</ConfigContext.Provider>
|
</ConfigContext.Provider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// `codeviewRef`: the codeViewRef. Used to edit the editor's content even if not visible
|
||||||
|
export function EditorInterface({data, codeviewRef, hidden, worldId, levelId, editorConnection}) {
|
||||||
|
|
||||||
|
const { commandLineMode, setCommandLineMode } = React.useContext(InputModeContext)
|
||||||
|
|
||||||
|
return <div className={hidden ? 'hidden' : ''}>
|
||||||
|
<div className={`statement ${commandLineMode ? 'hidden' : ''}`}><code>{data?.descrFormat}</code></div>
|
||||||
|
<div ref={codeviewRef} className={'codeview'}></div>
|
||||||
|
{editorConnection && <Main key={`${worldId}/${levelId}`} world={worldId} level={levelId} />}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user