Skip to content
Merged
2 changes: 2 additions & 0 deletions src/actions/actionTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ export const EVAL_INTERPRETER_SUCCESS = 'EVAL_INTERPRETER_SUCCESS'
export const HANDLE_CONSOLE_LOG = 'HANDLE_CONSOLE_LOG'

/** Workspace */
export const BROWSE_REPL_HISTORY_DOWN = 'BROWSE_REPL_HISTORY_DOWN'
export const BROWSE_REPL_HISTORY_UP = 'BROWSE_REPL_HISTORY_UP'
export const CHANGE_ACTIVE_TAB = 'CHANGE_ACTIVE_TAB'
export const CHANGE_EDITOR_WIDTH = 'CHANGE_EDITOR_WIDTH'
export const CHANGE_PLAYGROUND_EXTERNAL = 'CHANGE_PLAYGROUND_EXTERNAL'
Expand Down
15 changes: 15 additions & 0 deletions src/actions/workspaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,23 @@ export enum WorkspaceLocations {
assessment = 'assessment',
playground = 'playground'
}

export type WorkspaceLocation = keyof typeof WorkspaceLocations

export const browseReplHistoryDown: ActionCreator<actionTypes.IAction> = (
workspaceLocation: WorkspaceLocation
) => ({
type: actionTypes.BROWSE_REPL_HISTORY_DOWN,
payload: { workspaceLocation }
})

export const browseReplHistoryUp: ActionCreator<actionTypes.IAction> = (
workspaceLocation: WorkspaceLocation
) => ({
type: actionTypes.BROWSE_REPL_HISTORY_UP,
payload: { workspaceLocation }
})

export const changeActiveTab: ActionCreator<actionTypes.IAction> = (
activeTab: number,
workspaceLocation: WorkspaceLocation
Expand Down
4 changes: 4 additions & 0 deletions src/components/Playground.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ export interface IStateProps {
}

export interface IDispatchProps {
handleBrowseHistoryDown: () => void
handleBrowseHistoryUp: () => void
handleChangeActiveTab: (activeTab: number) => void
handleChapterSelect: (chapter: any, changeEvent: any) => void
handleEditorEval: () => void
Expand Down Expand Up @@ -85,6 +87,8 @@ class Playground extends React.Component<IPlaygroundProps, PlaygroundState> {
replProps: {
output: this.props.output,
replValue: this.props.replValue,
handleBrowseHistoryDown: this.props.handleBrowseHistoryDown,
handleBrowseHistoryUp: this.props.handleBrowseHistoryUp,
handleReplEval: this.props.handleReplEval,
handleReplValueChange: this.props.handleReplValueChange
},
Expand Down
6 changes: 4 additions & 2 deletions src/components/__tests__/Playground.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@ const baseProps = {
externalLibrary: 'none',
output: [],
replValue: '',
handleChapterSelect: (chapter: any, e: any) => {},
handleExternalSelect: (external: any, e: any) => {},
handleBrowseHistoryDown: () => {},
handleBrowseHistoryUp: () => {},
handleChangeActiveTab: (n: number) => {},
handleChapterSelect: (chapter: any, e: any) => {},
handleEditorEval: () => {},
handleEditorValueChange: () => {},
handleEditorWidthChange: (widthChange: number) => {},
handleExternalSelect: (external: any, e: any) => {},
handleGenerateLz: () => {},
handleInterruptEval: () => {},
handleReplEval: () => {},
Expand Down
12 changes: 8 additions & 4 deletions src/components/academy/grading/GradingWorkspace.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,15 @@ export type OwnProps = {
}

export type DispatchProps = {
handleGradingFetch: (submissionId: number) => void
handleBrowseHistoryDown: () => void
handleBrowseHistoryUp: () => void
handleChangeActiveTab: (activeTab: number) => void
handleChapterSelect: (chapter: any, changeEvent: any) => void
handleClearContext: (chapter: number, externals: string[]) => void
handleEditorEval: () => void
handleEditorValueChange: (val: string) => void
handleEditorWidthChange: (widthChange: number) => void
handleGradingFetch: (submissionId: number) => void
handleInterruptEval: () => void
handleReplEval: () => void
handleReplOutputClear: () => void
Expand Down Expand Up @@ -101,10 +103,12 @@ class GradingWorkspace extends React.Component<GradingWorkspaceProps> {
sideContentHeight: this.props.sideContentHeight,
sideContentProps: this.sideContentProps(this.props, questionId),
replProps: {
output: this.props.output,
replValue: this.props.replValue,
handleBrowseHistoryDown: this.props.handleBrowseHistoryDown,
handleBrowseHistoryUp: this.props.handleBrowseHistoryUp,
handleReplEval: this.props.handleReplEval,
handleReplValueChange: this.props.handleReplValueChange
handleReplValueChange: this.props.handleReplValueChange,
output: this.props.output,
replValue: this.props.replValue
}
}
return (
Expand Down
11 changes: 8 additions & 3 deletions src/components/assessment/AssessmentWorkspace.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ export type OwnProps = {

export type DispatchProps = {
handleAssessmentFetch: (assessmentId: number) => void
handleBrowseHistoryDown: () => void
handleBrowseHistoryUp: () => void
handleChangeActiveTab: (activeTab: number) => void
handleChapterSelect: (chapter: any, changeEvent: any) => void
handleClearContext: (chapter: number, externals: string[]) => void
Expand Down Expand Up @@ -123,10 +125,12 @@ class AssessmentWorkspace extends React.Component<
sideContentHeight: this.props.sideContentHeight,
sideContentProps: this.sideContentProps(this.props, questionId),
replProps: {
output: this.props.output,
replValue: this.props.replValue,
handleBrowseHistoryDown: this.props.handleBrowseHistoryDown,
handleBrowseHistoryUp: this.props.handleBrowseHistoryUp,
handleReplEval: this.props.handleReplEval,
handleReplValueChange: this.props.handleReplValueChange
handleReplValueChange: this.props.handleReplValueChange,
output: this.props.output,
replValue: this.props.replValue
}
}
return (
Expand Down Expand Up @@ -199,6 +203,7 @@ class AssessmentWorkspace extends React.Component<
handleInterruptEval: this.props.handleInterruptEval,
handleReplEval: this.props.handleReplEval,
handleReplOutputClear: this.props.handleReplOutputClear,
handleReplValueChange: this.props.handleReplValueChange,
hasChapterSelect: false,
hasDoneButton: questionId === this.props.assessment!.questions.length - 1,
hasNextButton: questionId < this.props.assessment!.questions.length - 1,
Expand Down
2 changes: 2 additions & 0 deletions src/components/assessment/__tests__/AssessmentWorkspace.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ const defaultProps: AssessmentWorkspaceProps = {
closeDate: '2048-06-18T05:24:26.026Z',
editorWidth: '50%',
handleAssessmentFetch: (assessmentId: number) => {},
handleBrowseHistoryDown: () => {},
handleBrowseHistoryUp: () => {},
handleChangeActiveTab: (activeTab: number) => {},
handleChapterSelect: (chapter: any, changeEvent: any) => {},
handleClearContext: (chapter: number, externals: string[]) => {},
Expand Down
2 changes: 2 additions & 0 deletions src/components/workspace/Repl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import ReplInput, { IReplInputProps } from './ReplInput'
export interface IReplProps {
output: InterpreterOutput[]
replValue: string
handleBrowseHistoryDown: () => void
handleBrowseHistoryUp: () => void
handleReplEval: () => void
handleReplValueChange: (newCode: string) => void
}
Expand Down
36 changes: 32 additions & 4 deletions src/components/workspace/ReplInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,27 @@ import 'brace/theme/terminal'

export interface IReplInputProps {
replValue: string
handleBrowseHistoryDown: () => void
handleBrowseHistoryUp: () => void
handleReplValueChange: (newCode: string) => void
handleReplEval: () => void
}

class ReplInput extends React.PureComponent<IReplInputProps, {}> {
private replInputBottom: HTMLDivElement
private execBrowseHistoryDown: () => void
private execBrowseHistoryUp: () => void
private execEvaluate: () => void

constructor(props: IReplInputProps) {
super(props)
this.execBrowseHistoryDown = props.handleBrowseHistoryDown
this.execBrowseHistoryUp = props.handleBrowseHistoryUp
this.execEvaluate = () => {
this.replInputBottom.scrollIntoView()
this.props.handleReplEval()
}
}

public componentDidUpdate() {
if (this.replInputBottom.clientWidth >= window.innerWidth - 50) {
Expand Down Expand Up @@ -41,16 +56,29 @@ class ReplInput extends React.PureComponent<IReplInputProps, {}> {
value={this.props.replValue}
onChange={this.props.handleReplValueChange}
commands={[
{
name: 'browseHistoryDown',
bindKey: {
win: 'Down',
mac: 'Down'
},
exec: this.execBrowseHistoryDown
},
{
name: 'browseHistoryUp',
bindKey: {
win: 'Up',
mac: 'Up'
},
exec: this.execBrowseHistoryUp
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Logic here looks good. The multi-line issue is already addressed, so not going to mention it here

{
name: 'evaluate',
bindKey: {
win: 'Shift-Enter',
mac: 'Shift-Enter'
},
exec: () => {
this.replInputBottom.scrollIntoView()
this.props.handleReplEval()
}
exec: this.execEvaluate
}
]}
minLines={1}
Expand Down
8 changes: 5 additions & 3 deletions src/components/workspace/__tests__/Repl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,13 @@ const mockErrorOutput: ErrorOutput = {

test('Repl renders correctly', () => {
const props = {
output: [mockResultOutput, mockCodeOutput, mockErrorOutput, mockRunningOutput],
replValue: '',
handleBrowseHistoryDown: () => {},
handleBrowseHistoryUp: () => {},
handleReplValueChange: (newCode: string) => {},
handleReplEval: () => {},
handleReplOutputClear: () => {}
handleReplOutputClear: () => {},
output: [mockResultOutput, mockCodeOutput, mockErrorOutput, mockRunningOutput],
replValue: ''
}
const app = <Repl {...props} />
const tree = shallow(app)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ exports[`Repl renders correctly 1`] = `
<Component output={{...}} />
<Component output={{...}} />
<HotKeys className=\\"repl-input-parent row pt-card pt-elevation-0\\" handlers={{...}}>
<ReplInput output={{...}} replValue=\\"\\" handleReplValueChange={[Function: handleReplValueChange]} handleReplEval={[Function: handleReplEval]} handleReplOutputClear={[Function: handleReplOutputClear]} />
<ReplInput handleBrowseHistoryDown={[Function: handleBrowseHistoryDown]} handleBrowseHistoryUp={[Function: handleBrowseHistoryUp]} handleReplValueChange={[Function: handleReplValueChange]} handleReplEval={[Function: handleReplEval]} handleReplOutputClear={[Function: handleReplOutputClear]} output={{...}} replValue=\\"\\" />
</HotKeys>
</div>
</div>"
Expand Down
4 changes: 4 additions & 0 deletions src/containers/PlaygroundContainer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { bindActionCreators, Dispatch } from 'redux'

import {
beginInterruptExecution,
browseReplHistoryDown,
browseReplHistoryUp,
changeActiveTab,
changeEditorWidth,
changeSideContentHeight,
Expand Down Expand Up @@ -38,6 +40,8 @@ const location: WorkspaceLocation = 'playground'
const mapDispatchToProps: MapDispatchToProps<IDispatchProps, {}> = (dispatch: Dispatch<any>) =>
bindActionCreators(
{
handleBrowseHistoryDown: () => browseReplHistoryDown(location),
handleBrowseHistoryUp: () => browseReplHistoryUp(location),
handleChangeActiveTab: (activeTab: number) => changeActiveTab(activeTab, location),
handleChapterSelect: (chapter: any, changeEvent: any) =>
chapterSelect(chapter, changeEvent, location),
Expand Down
6 changes: 5 additions & 1 deletion src/containers/academy/grading/GradingWorkspaceContainer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { bindActionCreators, Dispatch } from 'redux'

import {
beginInterruptExecution,
browseReplHistoryDown,
browseReplHistoryUp,
changeActiveTab,
changeEditorWidth,
changeSideContentHeight,
Expand Down Expand Up @@ -52,7 +54,8 @@ const mapStateToProps: MapStateToProps<StateProps, OwnProps, IState> = (state, p
const mapDispatchToProps: MapDispatchToProps<DispatchProps, {}> = (dispatch: Dispatch<any>) =>
bindActionCreators<DispatchProps>(
{
handleGradingFetch: fetchGrading,
handleBrowseHistoryDown: () => browseReplHistoryDown(location),
handleBrowseHistoryUp: () => browseReplHistoryUp(location),
handleChangeActiveTab: (activeTab: number) => changeActiveTab(activeTab, location),
handleChapterSelect: (chapter: any, changeEvent: any) =>
chapterSelect(chapter, changeEvent, location),
Expand All @@ -61,6 +64,7 @@ const mapDispatchToProps: MapDispatchToProps<DispatchProps, {}> = (dispatch: Dis
handleEditorEval: () => evalEditor(location),
handleEditorValueChange: (val: string) => updateEditorValue(val, location),
handleEditorWidthChange: (widthChange: number) => changeEditorWidth(widthChange, location),
handleGradingFetch: fetchGrading,
handleInterruptEval: () => beginInterruptExecution(location),
handleReplEval: () => evalRepl(location),
handleReplOutputClear: () => clearReplOutput(location),
Expand Down
4 changes: 4 additions & 0 deletions src/containers/assessment/AssessmentWorkspaceContainer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { bindActionCreators, Dispatch } from 'redux'

import {
beginInterruptExecution,
browseReplHistoryDown,
browseReplHistoryUp,
changeActiveTab,
changeEditorWidth,
changeSideContentHeight,
Expand Down Expand Up @@ -48,6 +50,8 @@ const mapDispatchToProps: MapDispatchToProps<DispatchProps, {}> = (dispatch: Dis
bindActionCreators<DispatchProps>(
{
handleAssessmentFetch: fetchAssessment,
handleBrowseHistoryDown: () => browseReplHistoryDown(location),
handleBrowseHistoryUp: () => browseReplHistoryUp(location),
handleChangeActiveTab: (activeTab: number) => changeActiveTab(activeTab, location),
handleChapterSelect: (chapter: any, changeEvent: any) =>
chapterSelect(chapter, changeEvent, location),
Expand Down
12 changes: 12 additions & 0 deletions src/reducers/states.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ interface IWorkspaceState {
readonly editorValue: string
readonly editorWidth: string
readonly output: InterpreterOutput[]
readonly replHistory: ReplHistory
readonly replValue: string
readonly sideContentActiveTab: number
readonly sideContentHeight?: number
Expand All @@ -65,6 +66,13 @@ export interface ISessionState {
readonly username?: string
}

type ReplHistory = {
browseIndex: null | number // [0, 49] if browsing, else null
records: string[]
}

export const maxBrowseIndex = 50

/**
* An output while the program is still being run in the interpreter. As a
* result, there are no return values or SourceErrors yet. However, there could
Expand Down Expand Up @@ -189,6 +197,10 @@ export const createDefaultWorkspace = (location: WorkspaceLocation): IWorkspaceS
editorValue: defaultEditorValue,
editorWidth: '50%',
output: [],
replHistory: {
browseIndex: null,
records: []
},
replValue: '',
sideContentActiveTab: 0,
externals: []
Expand Down
Loading