diff --git a/src/state/guards/index.ts b/src/state/guards/index.ts index 643cc192..ffd9415e 100644 --- a/src/state/guards/index.ts +++ b/src/state/guards/index.ts @@ -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 }, diff --git a/src/state/index.ts b/src/state/index.ts index 3692c088..0e37cf00 100644 --- a/src/state/index.ts +++ b/src/state/index.ts @@ -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 }) diff --git a/src/state/machine.ts b/src/state/machine.ts index 152d1921..317e3100 100644 --- a/src/state/machine.ts +++ b/src/state/machine.ts @@ -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', }, }, diff --git a/typings/index.d.ts b/typings/index.d.ts index 23eddb78..652c8d25 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -148,7 +148,6 @@ export interface MachineStateSchema { states: { Initialize: {} Summary: {} - LoadCurrent: {} LoadNext: {} Level: {} Stage: { @@ -161,7 +160,7 @@ export interface MachineStateSchema { StageComplete: {} } } - EndTutorial: {} + Completed: {} } } } diff --git a/web-app/src/App.tsx b/web-app/src/App.tsx index f6df1ad4..3f4e80fb 100644 --- a/web-app/src/App.tsx +++ b/web-app/src/App.tsx @@ -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 (
- {/* */} + {debug && }
diff --git a/web-app/src/containers/Tutorial/CompletedPage.tsx b/web-app/src/containers/Tutorial/CompletedPage.tsx new file mode 100644 index 00000000..813290e3 --- /dev/null +++ b/web-app/src/containers/Tutorial/CompletedPage.tsx @@ -0,0 +1,7 @@ +import * as React from 'react' + +const CompletedPage = () => { + return
Tutorial Complete
+} + +export default CompletedPage diff --git a/web-app/src/containers/Tutorial/index.tsx b/web-app/src/containers/Tutorial/index.tsx index 7de78192..7e5e58c7 100644 --- a/web-app/src/containers/Tutorial/index.tsx +++ b/web-app/src/containers/Tutorial/index.tsx @@ -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) => { + + + ) }