Skip to content

Feature/completed #22

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jul 23, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions src/state/guards/index.ts
Original file line number Diff line number Diff line change
@@ -4,22 +4,27 @@ export default {
hasNextStep: (context: CR.MachineContext): boolean => {
const { data, position, progress } = context
const steps = data.stages[position.stageId].stepList
// isn't final step yet
const hasNext = !!position.stepId && (steps[steps.length - 1] !== position.stepId) || !progress.stages[position.stageId]
const stageIncomplete = !progress.stages[position.stageId]
const isNotFinalStep = (!!position.stepId && (steps[steps.length - 1] !== position.stepId))
const hasNext = stageIncomplete || isNotFinalStep
console.log('GUARD: hasNextStep', hasNext)
return hasNext
},
hasNextStage: (context: CR.MachineContext): boolean => {
const { data, position } = context
const { data, position, progress } = context
const stages = data.levels[position.levelId].stageList
const hasNext = !!position.stageId && stages[stages.length - 1] !== position.stageId
const stageComplete = progress.stages[position.stageId]
const isNotFinalStage = !!position.stageId && stages[stages.length - 1] !== position.stageId
const hasNext = stageComplete && isNotFinalStage
console.log('GUARD: hasNextStage', hasNext)
return hasNext
},
hasNextLevel: (context: CR.MachineContext): boolean => {
const { data, position } = context
const { data, position, progress } = context
const levels = data.summary.levelList
const hasNext = !!position.levelId && levels[levels.length - 1] !== position.levelId
const levelComplete = progress.levels[position.levelId]
const isNotFinalLevel = !!position.levelId && levels[levels.length - 1] !== position.levelId
const hasNext = levelComplete && isNotFinalLevel
console.log('GUARD: hasNextLevel', hasNext)
return hasNext
},
19 changes: 16 additions & 3 deletions src/state/index.ts
Original file line number Diff line number Diff line change
@@ -5,6 +5,21 @@ import createMachine from './machine'
// machine interpreter
// https://xstate.js.org/docs/guides/interpretation.html

// convert state into a readable string
const stateToString = (state: string | object, str: string = ''): string => {
if (typeof state === 'object') {
const keys = Object.keys(state)
if (keys && keys.length) {
const key = keys[0]
return stateToString(state[key], str.length ? `${str}.${key}` : key)
}
return str
} else if (typeof state === 'string') {
return state
}
return ''
}

interface Props {
dispatch: CR.EditorDispatch
}
@@ -23,10 +38,8 @@ class StateMachine {
this.service = interpret(machine, this.machineOptions)
// logging
.onTransition(state => {
// console.log('onTransition', state)
if (state.changed) {
// console.log('next state')
// console.log(state.value)
console.log(`STATE: ${stateToString(state.value)}`)
dispatch('coderoad.send_state', { state: state.value, data: state.context })
} else {
dispatch('coderoad.send_data', { data: state.context })
42 changes: 19 additions & 23 deletions src/state/machine.ts
Original file line number Diff line number Diff line change
@@ -47,7 +47,7 @@ export const machine = (dispatch: CR.EditorDispatch) =>
ContinueTutorial: {
onEntry: ['tutorialContinue'],
on: {
TUTORIAL_START: '#tutorial-load-current',
TUTORIAL_START: '#tutorial-load-next',
},
},
},
@@ -57,7 +57,7 @@ export const machine = (dispatch: CR.EditorDispatch) =>
initial: 'Initialize',
onEntry: ['tutorialSetup'],
on: {
WEBVIEW_INITIALIZED: '#tutorial-load-current'
WEBVIEW_INITIALIZED: '#tutorial-load-next'
},
states: {
Initialize: {
@@ -66,28 +66,24 @@ export const machine = (dispatch: CR.EditorDispatch) =>
0: 'Summary',
},
},
LoadCurrent: {
id: 'tutorial-load-current',
// TODO: verify current is not complete
after: {
0: 'Stage',
},
},
LoadNext: {
id: 'tutorial-load-next',
after: {
0: [
{
target: 'Stage',
cond: 'hasNextStage',
},
{
target: 'Level',
cond: 'hasNextLevel',
},
{
target: '#end-tutorial',
},
0: [{
target: 'Stage',
cond: 'hasNextStep',
},
{
target: 'Stage',
cond: 'hasNextStage',
},
{
target: 'Level',
cond: 'hasNextLevel',
},
{
target: '#completed-tutorial',
},
],
},
},
@@ -157,8 +153,8 @@ export const machine = (dispatch: CR.EditorDispatch) =>
},
},
},
EndTutorial: {
id: 'end-tutorial',
Completed: {
id: 'completed-tutorial',
type: 'final',
},
},
3 changes: 1 addition & 2 deletions typings/index.d.ts
Original file line number Diff line number Diff line change
@@ -148,7 +148,6 @@ export interface MachineStateSchema {
states: {
Initialize: {}
Summary: {}
LoadCurrent: {}
LoadNext: {}
Level: {}
Stage: {
@@ -161,7 +160,7 @@ export interface MachineStateSchema {
StageComplete: {}
}
}
EndTutorial: {}
Completed: {}
}
}
}
6 changes: 4 additions & 2 deletions web-app/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as React from 'react'
import * as CR from 'typings'

// import Debugger from './components/Debugger'
import Debugger from './components/Debugger'
import Routes from './Routes'
import DataContext, { initialData, initialState } from './utils/DataContext'
import { send } from './utils/vscode'
@@ -10,6 +10,8 @@ interface ReceivedEvent {
data: CR.Action
}

const debug = false

const App = () => {
const [state, setState] = React.useState(initialState)
const [data, setData]: [CR.MachineContext, (data: CR.MachineContext) => void] = React.useState(initialData)
@@ -51,7 +53,7 @@ const App = () => {
return (
<DataContext.Provider value={value}>
<div>
{/* <Debugger value={value} /> */}
{debug && <Debugger value={value} />}
<Routes state={state} />
</div>
</DataContext.Provider>
7 changes: 7 additions & 0 deletions web-app/src/containers/Tutorial/CompletedPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import * as React from 'react'

const CompletedPage = () => {
return <div>Tutorial Complete</div>
}

export default CompletedPage
4 changes: 4 additions & 0 deletions web-app/src/containers/Tutorial/index.tsx
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@ import LoadingPage from '../LoadingPage'
import SummaryPage from './SummaryPage'
import LevelPage from './LevelPage'
import StagePage from './StagePage'
import CompletedPage from './CompletedPage'

const { Route } = Router

@@ -28,6 +29,9 @@ const Tutorial = (props: Props) => {
<Route path="Tutorial.Stage">
<StagePage send={send} />
</Route>
<Route path="Tutorial.Completed">
<CompletedPage />
</Route>
</Router>
)
}