scroll to selected step

pull/118/head
Jon Eugster 3 years ago
parent 0a2c4552bf
commit 446a33e5e8

@ -2,25 +2,25 @@ import { GameHint } from "./infoview/rpc_api";
import * as React from 'react';
import Markdown from './markdown';
export function Hint({hint, selected, toggleSelection} : {hint: GameHint, selected: boolean, toggleSelection: any}) {
return <div className={"message information" + (selected ? ' selected' : '')} onClick={toggleSelection}>
export function Hint({hint, step, selected, toggleSelection} : {hint: GameHint, step: number, selected: number, toggleSelection: any}) {
return <div className={`message information step-${step}` + (step == selected ? ' selected' : '')} onClick={toggleSelection}>
<Markdown>{hint.text}</Markdown>
</div>
}
export function AdditionalHint({hint, selected, toggleSelection} : {hint: GameHint, selected: boolean, toggleSelection: any}) {
return <div className={"message warning" + (selected ? ' selected' : '')} onClick={toggleSelection}>
export function AdditionalHint({hint, step, selected, toggleSelection} : {hint: GameHint, step: number, selected: number, toggleSelection: any}) {
return <div className={`message warning step-${step}` + (step == selected ? ' selected' : '')} onClick={toggleSelection}>
<Markdown>{hint.text}</Markdown>
</div>
}
export function Hints({hints, showHidden, selected, toggleSelection} : {hints: GameHint[], showHidden: boolean, selected: boolean, toggleSelection: any}) {
export function Hints({hints, showHidden, step, selected, toggleSelection} : {hints: GameHint[], showHidden: boolean, step: number, selected: number, toggleSelection: any}) {
const openHints = hints.filter(hint => !hint.hidden)
const hiddenHints = hints.filter(hint => hint.hidden)
return <>
{openHints.map(hint => <Hint hint={hint} selected={selected} toggleSelection={toggleSelection}/>)}
{showHidden && hiddenHints.map(hint => <AdditionalHint hint={hint} selected={selected} toggleSelection={toggleSelection}/>)}
{openHints.map(hint => <Hint hint={hint} step={step} selected={selected} toggleSelection={toggleSelection}/>)}
{showHidden && hiddenHints.map(hint => <AdditionalHint hint={hint} step={step} selected={selected} toggleSelection={toggleSelection}/>)}
</>
}

@ -235,7 +235,7 @@ export const OtherGoals = React.memo((props: GoalProps2) => {
</>
})
// TODO: deprecated
export const ProofDisplay = React.memo((props : ProofDisplayProps) => {
const { proof } = props
const steps = proof.match(/.+/g)

@ -124,7 +124,6 @@ const InfoDisplayContent = React.memo((props: InfoDisplayContentProps) => {
<div className="goals-section">
{ goals && goals.goals.length > 0 && <>
<MainAssumptions filter={goalFilter} key='mainGoal' goals={goals.goals} />
<ProofDisplay proof={proof}/>
<OtherGoals filter={goalFilter} goals={goals.goals} />
</>}
</div>

@ -314,7 +314,7 @@ export function CommandLineInterface(props: {world: string, level: number, data:
}
}
function selectStep(line: number) {
function toggleSelectStep(line: number) {
return (ev) => {
if (selectedStep == line) {
setSelectedStep(undefined)
@ -326,6 +326,16 @@ export function CommandLineInterface(props: {world: string, level: number, data:
}
}
// Scroll to element if selection changes
React.useEffect(() => {
if (selectedStep) {
Array.from(proofPanelRef.current?.getElementsByClassName(`step-${selectedStep}`)).map((elem) => {
elem.scrollIntoView({block: "center"})
})
}
}, [selectedStep])
const completed = useAppSelector(selectCompleted(gameId, props.world, props.level))
/* Set up updates to the global infoview seither you solved the level with warnings or your last command contains a syntax error Lean can't parseate on editor events. */
@ -378,7 +388,7 @@ export function CommandLineInterface(props: {world: string, level: number, data:
</div>
} else {
return <>
<div className={'step' + (selectedStep == i ? ' selected' : '')} onClick={selectStep(i)}>
<div className={`step step-${i}` + (selectedStep == i ? ' selected' : '')} onClick={toggleSelectStep(i)}>
<Command command={step.command} deleteProof={deleteProof(i)}/>
<Errors errors={step.errors} commandLineMode={true}/>
<GoalsTab proofStep={step}/>

@ -40,6 +40,7 @@ import { changedSelection, codeEdited, selectCode, selectSelections, progressSli
import { DualEditor } from './infoview/main'
import { Hints } from './hints';
import { InputModeContext, MonacoEditorContext, ProofContext, ProofStep, SelectionContext } from './infoview/context';
import { hasInteractiveErrors } from './infoview/command_line';
function Level() {
@ -106,6 +107,15 @@ function PlayableLevel({worldId, levelId}) {
}
}, [commandLineMode])
// Scroll to element if selection changes
React.useEffect(() => {
if (selectedStep) {
Array.from(chatRef.current?.getElementsByClassName(`step-${selectedStep}`)).map((elem) => {
elem.scrollIntoView({block: "center"})
})
}
}, [selectedStep])
/** Unused. Was implementing an undo button, which has been replaced by `deleteProof` inside
* `CommandLineInterface`.
*/
@ -217,7 +227,12 @@ function PlayableLevel({worldId, levelId}) {
</div>
}
{proof.map((step, i) => {
return <Hints hints={step.hints} showHidden={showHiddenHints} selected={i == selectedStep} toggleSelection={toggleSelection(i)}/>
// It the last step has errors, it will have the same hints
// as the second-to-last step. Therefore we should not display them.
if (!(i == proof.length - 1 && hasInteractiveErrors(step.errors))) {
return <Hints hints={step.hints} showHidden={showHiddenHints} step={i}
selected={selectedStep} toggleSelection={toggleSelection(i)}/>
}
})}
{completed &&
<>

Loading…
Cancel
Save