Skip to content

Commit af502ed

Browse files
committed
heavy refactoring
1 parent c405101 commit af502ed

File tree

21 files changed

+250
-246
lines changed

21 files changed

+250
-246
lines changed

web-app/src/Routes.tsx

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import * as React from 'react'
2-
import * as CR from 'typings'
2+
import { MachineContext as RootMachineContext } from './services/state/machine'
3+
import { MachineContext as SelectTutorialContext } from './services/state/selectTutorial'
4+
import { MachineContext as PlayTutorialContext } from './services/state/playTutorial'
35
import Router from './components/Router'
46
import Workspace from './components/Workspace'
57
import ContinuePage from './containers/Continue'
@@ -18,29 +20,29 @@ const Routes = () => {
1820
return (
1921
<Workspace>
2022
<Router>
21-
<Route path={['SelectTutorial.Startup', 'SelectTutorial.Authenticate', 'SelectTutorial.NewOrContinue']}>
22-
<LoadingPage text="Launching..." context={{} as CR.MachineContext} />
23+
<Route path={'Initializing'}>
24+
<LoadingPage text="Launching..." context={{} as RootMachineContext} />
2325
</Route>
24-
<Route path="SelectTutorial.SelectTutorial">
25-
<NewPage send={tempSend} context={{} as CR.MachineContext} />
26+
<Route path="Start.SelectTutorial">
27+
<NewPage send={tempSend} context={{} as SelectTutorialContext} />
2628
</Route>
27-
<Route path="SelectTutorial.ContinueTutorial">
28-
<ContinuePage send={tempSend} context={{} as CR.MachineContext} />
29+
<Route path="Start.ContinueTutorial">
30+
<ContinuePage send={tempSend} context={{} as SelectTutorialContext} />
2931
</Route>
30-
<Route path="PlayTutorial.Initialize">
31-
<LoadingPage text="Initializing..." context={{} as CR.MachineContext} />
32+
<Route path="Start.Initialize">
33+
<LoadingPage text="Initializing..." context={{} as SelectTutorialContext} />
3234
</Route>
3335
<Route path="PlayTutorial.LoadNext">
34-
<LoadingPage text="Loading..." context={{} as CR.MachineContext} />
36+
<LoadingPage text="Loading..." context={{} as PlayTutorialContext} />
3537
</Route>
3638
<Route path="PlayTutorial.Summary">
37-
<OverviewPage send={tempSend} context={{} as CR.MachineContext} />
39+
<OverviewPage send={tempSend} context={{} as PlayTutorialContext} />
3840
</Route>
3941
<Route path="PlayTutorial.Level">
40-
<LevelSummaryPage send={tempSend} context={{} as CR.PlayMachineContext} />
42+
<LevelSummaryPage send={tempSend} context={{} as PlayTutorialContext} />
4143
</Route>
4244
<Route path="PlayTutorial.Completed">
43-
<CompletedPage send={tempSend} context={{} as CR.PlayMachineContext} />
45+
<CompletedPage send={tempSend} context={{} as PlayTutorialContext} />
4446
</Route>
4547
</Router>
4648
</Workspace>

web-app/src/components/Debugger/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import * as React from 'react'
2-
import * as T from 'typings'
32
import { css, jsx } from '@emotion/core'
3+
import { MachineContext } from '../../services/state/playTutorial'
44

5-
interface Props extends T.PlayMachineContext {
5+
interface Props extends MachineContext {
66
state: string
77
children: React.ReactElement
88
}

web-app/src/components/Router/index.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,24 @@
11
import * as React from 'react'
2-
import * as CR from 'typings'
32
import channel from '../../services/channel'
43
import messageBusReceiver from '../../services/channel/receiver'
54
import machine from '../../services/state/machine'
65
import { useMachine } from '../../services/xstate-react'
76
import debuggerWrapper from '../Debugger/debuggerWrapper'
87
import Route from './Route'
98
import onError from '../../services/sentry/onError'
9+
import { MachineContext, MachineEvent } from '../../services/state/machine'
1010

1111
interface Props {
1212
children: any
1313
}
1414

1515
interface CloneElementProps {
16-
context: CR.MachineContext
17-
send(action: CR.Action): void
16+
context: MachineContext
17+
send(action: MachineEvent): void
1818
}
1919

20+
// TODO: rewrite router, logic is messy
21+
2022
// router finds first state match of <Route path='' />
2123
const Router = ({ children }: Props): React.ReactElement<CloneElementProps> | null => {
2224
const [state, send] = useMachine(machine, {
@@ -32,6 +34,7 @@ const Router = ({ children }: Props): React.ReactElement<CloneElementProps> | nu
3234

3335
const childArray = React.Children.toArray(children)
3436
for (const child of childArray) {
37+
// @ts-ignore
3538
const { path } = child.props
3639
let pathMatch
3740
if (typeof path === 'string') {
@@ -42,6 +45,7 @@ const Router = ({ children }: Props): React.ReactElement<CloneElementProps> | nu
4245
throw new Error(`Invalid route path ${JSON.stringify(path)}`)
4346
}
4447
if (pathMatch) {
48+
// @ts-ignore
4549
const element = React.cloneElement<CloneElementProps>(child.props.children, { send, context: state.context })
4650
return debuggerWrapper(element, state)
4751
}

web-app/src/containers/Continue/index.tsx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as React from 'react'
2-
import * as CR from 'typings'
32
import * as G from 'typings/graphql'
3+
import { MachineContext, MachineEvent } from '../../services/state/selectTutorial'
44
import { css, jsx } from '@emotion/core'
55
import Button from '../../components/Button'
66
import Card from '../../components/Card'
@@ -47,8 +47,8 @@ export const ContinuePage = (props: Props) => (
4747
)
4848

4949
interface ContainerProps {
50-
context: CR.MachineContext
51-
send(action: CR.Action | string): void
50+
context: MachineContext
51+
send(action: MachineEvent): void
5252
}
5353

5454
const ContinuePageContainer = ({ context, send }: ContainerProps) => {
@@ -59,7 +59,11 @@ const ContinuePageContainer = ({ context, send }: ContainerProps) => {
5959
}
6060

6161
return (
62-
<ContinuePage tutorial={tutorial} onContinue={() => send('TUTORIAL_START')} onNew={() => send('TUTORIAL_SELECT')} />
62+
<ContinuePage
63+
tutorial={tutorial}
64+
onContinue={() => send({ type: 'TUTORIAL_START' })}
65+
onNew={() => send({ type: 'SELECT_NEW_TUTORIAL' })}
66+
/>
6367
)
6468
}
6569

web-app/src/containers/LoadingPage.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
import * as React from 'react'
2-
import * as T from 'typings'
32
import { css, jsx } from '@emotion/core'
43
import Loading from '../components/Loading'
54
import Message from '../components/Message'
65

76
interface Props {
87
text: string
9-
context: T.MachineContext
8+
context: any
109
}
1110

1211
const styles = {

web-app/src/containers/New/index.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import { useQuery } from '@apollo/react-hooks'
22
import * as React from 'react'
3-
import * as T from 'typings'
43
import * as G from 'typings/graphql'
4+
import { MachineContext, MachineEvent } from '../../services/state/selectTutorial'
55
import ErrorView from '../../components/Error'
66
import queryTutorials from '../../services/apollo/queries/tutorials'
77
import LoadingPage from '../LoadingPage'
88
import NewPage from './NewPage'
99

1010
interface ContainerProps {
11-
send(action: T.Action): void
12-
context: T.MachineContext
11+
send(action: MachineEvent): void
12+
context: MachineContext
1313
}
1414

1515
interface TutorialsData {

web-app/src/containers/Overview/index.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
import { useQuery } from '@apollo/react-hooks'
22
import * as React from 'react'
3-
import * as CR from 'typings'
43
import * as G from 'typings/graphql'
54
import ErrorView from '../../components/Error'
65
import queryTutorial from '../../services/apollo/queries/tutorial'
76
import OverviewPage from './OverviewPage'
8-
import { MachineContext } from '../../services/state/selectTutorial'
7+
import { MachineContext, MachineEvent } from '../../services/state/selectTutorial'
98

109
interface PageProps {
1110
context: MachineContext
12-
send(action: CR.Action): void
11+
send(action: MachineEvent): void
1312
}
1413

1514
interface TutorialData {

web-app/src/containers/Tutorial/CompletedPage.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as React from 'react'
2-
import * as CR from 'typings'
2+
import { MachineContext, MachineEvent } from '../../services/state/playTutorial'
33
import { css, jsx } from '@emotion/core'
44
import Button from '../../components/Button'
55

@@ -10,13 +10,13 @@ const styles = {
1010
}
1111

1212
interface Props {
13-
context: CR.MachineContext
14-
send(action: CR.Action | string): void
13+
context: MachineContext
14+
send(action: MachineEvent): void
1515
}
1616

1717
const CompletedPage = (props: Props) => {
1818
const selectNewTutorial = () => {
19-
props.send('SELECT_TUTORIAL')
19+
props.send({ type: 'EXIT' })
2020
}
2121
return (
2222
<div>

web-app/src/containers/Tutorial/LevelPage/index.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ import * as T from 'typings'
33
import * as G from 'typings/graphql'
44
import * as selectors from '../../../services/selectors'
55
import Level from './Level'
6+
import { MachineContext } from '../../../services/state/playTutorial'
67

78
interface PageProps {
8-
context: T.PlayMachineContext
9+
context: MachineContext
910
send(action: T.Action): void
1011
}
1112

@@ -17,7 +18,7 @@ const LevelSummaryPageContainer = (props: PageProps) => {
1718

1819
const onContinue = (): void => {
1920
props.send({
20-
type: 'LEVEL_NEXT',
21+
type: 'NEXT_LEVEL',
2122
payload: {
2223
LevelId: position.levelId,
2324
},

web-app/src/services/channel/index.ts

Lines changed: 10 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
1-
import { Action } from 'typings'
1+
import { MachineEvent } from '../state/machine'
2+
import { MachineEvent as AuthenticateEvent } from '../state/authenticate'
3+
import { MachineEvent as SelectTutorialEvent } from '../state/selectTutorial'
4+
import { MachineEvent as PlayTutorialEvent } from '../state/playTutorial'
25

36
declare let acquireVsCodeApi: any
47

8+
type SendEvent = MachineEvent | AuthenticateEvent | SelectTutorialEvent | PlayTutorialEvent
9+
510
interface ReceivedEvent {
6-
data: Action
11+
data: SendEvent
712
}
813

914
class Channel {
@@ -21,10 +26,10 @@ class Channel {
2126
this.editorSend = editor.postMessage
2227
}
2328

24-
public machineSend = (action: Action | string) => {
29+
public machineSend = (event: SendEvent) => {
2530
/* implemented by `setMachineSend` in router on startup */
2631
}
27-
public editorSend = (action: Action) => {
32+
public editorSend = (event: SendEvent) => {
2833
/* */
2934
}
3035

@@ -40,29 +45,7 @@ class Channel {
4045
return
4146
}
4247

43-
// messages from core
44-
switch (action.type) {
45-
case 'ENV_LOAD':
46-
case 'AUTHENTICATED':
47-
case 'TUTORIAL_LOADED':
48-
case 'NEW_TUTORIAL':
49-
case 'TUTORIAL_CONFIGURED':
50-
case 'CONTINUE_TUTORIAL':
51-
case 'TEST_PASS':
52-
case 'TEST_FAIL':
53-
case 'TEST_RUNNING':
54-
case 'TEST_ERROR':
55-
case 'COMMAND_START':
56-
case 'COMMAND_SUCCESS':
57-
case 'COMMAND_FAIL':
58-
case 'ERROR':
59-
this.machineSend(action)
60-
return
61-
default:
62-
if (action.type) {
63-
console.warn(`Unknown received action ${action.type}`, action)
64-
}
65-
}
48+
this.machineSend(action)
6649
}
6750
}
6851

web-app/src/services/selectors/tutorial.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { createSelector } from 'reselect'
2-
import * as CR from 'typings'
32
import * as G from 'typings/graphql'
43
import onError from '../../services/sentry/onError'
4+
import { MachineContext } from '../../services/state/playTutorial'
55

6-
export const currentTutorial = ({ tutorial }: CR.MachineContext): G.Tutorial => {
6+
export const currentTutorial = ({ tutorial }: MachineContext): G.Tutorial => {
77
if (!tutorial) {
88
const error = new Error('Tutorial not found')
99
onError(error)
@@ -21,7 +21,7 @@ export const currentVersion = createSelector(currentTutorial, (tutorial: G.Tutor
2121
return tutorial.version
2222
})
2323

24-
export const currentLevel = (context: CR.PlayMachineContext): G.Level =>
24+
export const currentLevel = (context: MachineContext): G.Level =>
2525
createSelector(
2626
currentVersion,
2727
(version: G.TutorialVersion): G.Level => {
@@ -41,7 +41,7 @@ export const currentLevel = (context: CR.PlayMachineContext): G.Level =>
4141
},
4242
)(context)
4343

44-
export const currentStep = (context: CR.PlayMachineContext): G.Step =>
44+
export const currentStep = (context: MachineContext): G.Step =>
4545
createSelector(
4646
currentLevel,
4747
(level: G.Level): G.Step => {

web-app/src/services/state/authenticate/actions.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,14 @@ interface AuthenticateVariables {
2222
}
2323

2424
const actions: ActionFunctionMap<MachineContext, MachineEvent> = {
25+
// @ts-ignore
2526
setEnv: assign({
26-
env: (context: CR.MachineContext, event: CR.MachineEvent) => {
27-
return {
28-
...context.env,
29-
...event.payload.env,
30-
}
31-
},
27+
env: (context: MachineContext, event: { type: 'ENV_LOAD'; payload: { env: CR.Environment } }): CR.Environment => ({
28+
...context.env,
29+
...event.payload.env,
30+
}),
3231
}),
33-
authenticate: async (context: CR.MachineContext): Promise<void> => {
32+
authenticate: async (context: MachineContext): Promise<void> => {
3433
const result = await client
3534
.mutate<AuthenticateData, AuthenticateVariables>({
3635
mutation: authenticateMutation,

web-app/src/services/state/machine.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ export type MachineContext = {
1313
env: CR.Environment
1414
error: CR.ErrorMessage | null
1515
tutorial: G.Tutorial | null
16+
position: CR.Position
17+
progress: CR.Progress
1618
}
1719

1820
export type MachineStateSchema = {
@@ -30,6 +32,8 @@ export const machine = Machine<MachineContext, MachineStateSchema, MachineEvent>
3032
error: null,
3133
env: { machineId: '', sessionId: '', token: '' },
3234
tutorial: null,
35+
progress: { levels: {}, steps: {}, complete: false },
36+
position: { levelId: '', stepId: '' },
3337
},
3438
states: {
3539
// load environment
@@ -53,9 +57,10 @@ export const machine = Machine<MachineContext, MachineStateSchema, MachineEvent>
5357
src: selectTutorialMachine,
5458
onDone: 'PlayTutorial',
5559
data: {
56-
env: (context: MachineContext) => context.env,
5760
tutorial: (context: MachineContext) => context.tutorial,
5861
error: null,
62+
position: (context: MachineContext) => context.position,
63+
progress: (context: MachineContext) => context.progress,
5964
},
6065
},
6166
},

0 commit comments

Comments
 (0)