Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit963cda2

Browse files
authored
Merge pull request#380 from coderoad/fix/hints
Fix/hints
2 parents5e6d187 +7dc54c1 commit963cda2

File tree

14 files changed

+273
-187
lines changed

14 files changed

+273
-187
lines changed

‎typings/index.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@ export interface MachineStateSchema {
7676
}
7777
Tutorial:{
7878
states:{
79-
LoadNext:{}
8079
Level:{
8180
states:{
8281
Load:{}
@@ -86,6 +85,7 @@ export interface MachineStateSchema {
8685
TestFail:{}
8786
StepNext:{}
8887
LevelComplete:{}
88+
LoadNext:{}
8989
}
9090
}
9191
Completed:{}

‎web-app/src/App.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@ import * as React from 'react'
22
import{ConfigProvider}from'@alifd/next'
33
importenUSfrom'@alifd/next/lib/locale/en-us'
44
importErrorBoundaryfrom'./components/ErrorBoundary'
5+
importWorkspacefrom'./components/Workspace'
56
importRoutesfrom'./Routes'
67

78
constApp=()=>(
89
<ConfigProviderlocale={enUS}>
910
<ErrorBoundary>
10-
<Routes/>
11+
<Workspace>
12+
<Routes/>
13+
</Workspace>
1114
</ErrorBoundary>
1215
</ConfigProvider>
1316
)

‎web-app/src/Routes.tsx

Lines changed: 34 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,52 @@
11
import*asReactfrom'react'
2-
importuseRouterfrom'./components/Router'
3-
importWorkspacefrom'./components/Workspace'
2+
importuseStateMachinefrom'./services/state/useStateMachine'
3+
import{Router,Route}from'./components/Router'
44
importErrorViewfrom'./components/Error'
55
importLoadingPagefrom'./containers/Loading'
66
importStartPagefrom'./containers/Start'
77
importSelectTutorialPagefrom'./containers/SelectTutorial'
88
importCompletedPagefrom'./containers/Tutorial/CompletedPage'
99
importTutorialPagefrom'./containers/Tutorial'
1010

11+
/*
12+
* NOTE: due to a lack of URLs and a dependency on xstate
13+
* we have to implement a custom router here
14+
*/
1115
constRoutes=()=>{
12-
const{ context,send, Router, Route}=useRouter()
16+
const{ context,route, send}=useStateMachine()
1317

1418
// TODO: handle only full page errors
1519
if(context.error){
16-
return(
17-
<Workspace>
18-
<ErrorViewsend={send}error={context.error}/>
19-
</Workspace>
20-
)
20+
return<ErrorViewsend={send}error={context.error}/>
2121
}
2222

2323
return(
24-
<Workspace>
25-
<Router>
26-
{/* Setup */}
27-
<Routepath={['Setup.Startup','Setup.ValidateSetup']}>
28-
<LoadingPagetext="Launching..."processes={context.processes}/>
29-
</Route>
30-
<Routepath="Setup.Start">
31-
<StartPagesend={send}context={context}/>
32-
</Route>
33-
<Routepath="Setup.SelectTutorial">
34-
<SelectTutorialPagesend={send}context={context}/>
35-
</Route>
36-
<Routepath={['Setup.SetupNewTutorial','Setup.StartTutorial']}>
37-
<LoadingPagetext="Configuring tutorial..."/>
38-
</Route>
39-
{/* Tutorial */}
40-
<Routepath={['Tutorial.LoadNext','Tutorial.Level.Load']}>
41-
<LoadingPagetext="Loading Level..."processes={context.processes}/>
42-
</Route>
43-
<Routepath="Tutorial.Level">
44-
<TutorialPagesend={send}context={context}/>
45-
</Route>
46-
{/* Completed */}
47-
<Routepath="Tutorial.Completed">
48-
<CompletedPagecontext={context}/>
49-
</Route>
50-
</Router>
51-
</Workspace>
24+
<Routerroute={route}>
25+
{/* Setup */}
26+
<Routepaths={{Setup:{Startup:true,ValidateSetup:true}}}>
27+
<LoadingPagetext="Launching..."processes={context.processes}/>
28+
</Route>
29+
<Routepaths={{Setup:{Start:true}}}>
30+
<StartPagesend={send}context={context}/>
31+
</Route>
32+
<Routepaths={{Setup:{SelectTutorial:true}}}>
33+
<SelectTutorialPagesend={send}context={context}/>
34+
</Route>
35+
<Routepaths={{Setup:{SetupNewTutorial:true,StartTutorial:true}}}>
36+
<LoadingPagetext="Configuring tutorial..."/>
37+
</Route>
38+
{/* Tutorial */}
39+
<Routepaths={{Tutorial:{Level:{Load:true}}}}>
40+
<LoadingPagetext="Loading Level..."processes={context.processes}/>
41+
</Route>
42+
<Routepaths={{Tutorial:{Level:true}}}>
43+
<TutorialPagesend={send}context={context}/>
44+
</Route>
45+
{/* Completed */}
46+
<Routepaths={{Tutorial:{Completed:true}}}>
47+
<CompletedPagecontext={context}/>
48+
</Route>
49+
</Router>
5250
)
5351
}
5452

‎web-app/src/components/Router/Route.tsx

Lines changed: 0 additions & 8 deletions
This file was deleted.
Lines changed: 41 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,87 +1,54 @@
11
import*asReactfrom'react'
2-
import*asTfrom'typings'
3-
import{createMachine}from'../../services/state/machine'
4-
import{useMachine}from'../../services/xstate-react'
5-
importRoutefrom'./Route'
62
importonErrorfrom'../../services/sentry/onError'
7-
importloggerfrom'../../services/logger'
83

9-
interfaceOutput{
10-
context:T.MachineContext
11-
send:(action:any)=>void
12-
Router:any
13-
Route:any
4+
interfaceRouterProps{
5+
children:React.ReactChildren|React.ReactChildren[]
6+
route:string
147
}
158

16-
declareletacquireVsCodeApi:any
17-
18-
consteditor=acquireVsCodeApi()
19-
consteditorSend=(action:T.Action)=>{
20-
logger(`TO EXT: "${action.type}"`)
21-
returneditor.postMessage(action)
22-
}
23-
24-
// router finds first state match of <Route path='' />
25-
constuseRouter=():Output=>{
26-
const[state,send]=useMachine<T.MachineContext,any>(createMachine({ editorSend}))
27-
28-
constsendWithLog=(action:T.Action):void=>{
29-
logger(`SEND:${action.type}`,action)
30-
send(action)
31-
}
32-
33-
logger(`STATE:${JSON.stringify(state.value)}`)
34-
35-
// event bus listener
36-
React.useEffect(()=>{
37-
constlistener='message'
38-
// propograte channel event to state machine
39-
consthandler=(event:any)=>{
40-
// NOTE: must call event.data, cannot destructure. VSCode acts odd
41-
constaction=event.data
42-
// ignore browser events from plugins
43-
if(action.source){
44-
return
9+
// check if a route string (eg. 'a.b.c')
10+
// matches a paths object ({ a: { b: { c: true }}})
11+
constmatches=(route:string,paths:object):boolean=>{
12+
constkeys:string[]=route.split('.')
13+
letcurrent:any=paths||{}
14+
// if the key throws, there is no match
15+
for(constkeyofkeys){
16+
constnext=current[key]
17+
if(next){
18+
// exit early if property value is true
19+
if(next===true){
20+
returntrue
4521
}
46-
sendWithLog(action)
47-
}
48-
window.addEventListener(listener,handler)
49-
return()=>{
50-
window.removeEventListener(listener,handler)
22+
current=next
23+
continue
24+
}else{
25+
returnfalse
5126
}
52-
},[])
27+
}
28+
returntrue
29+
}
5330

54-
constRouter=({ children}:any)=>{
55-
constchildArray=React.Children.toArray(children)
56-
for(constchildofchildArray){
57-
// match path
58-
//@ts-ignore
59-
const{ path}=child.props
60-
letpathMatch
61-
if(typeofpath==='string'){
62-
pathMatch=state.matches(path)
63-
}elseif(Array.isArray(path)){
64-
pathMatch=path.some((p)=>state.matches(p))
65-
}else{
66-
thrownewError(`Invalid route path${JSON.stringify(path)}`)
67-
}
68-
if(pathMatch){
69-
//@ts-ignore
70-
returnchild.props.children
71-
}
31+
exportconstRouter=({ children, route}:RouterProps)=>{
32+
//@ts-ignore may accept string as well as element
33+
constchildArray:React.ReactElement[]=React.Children.toArray(children)
34+
for(constchildofchildArray){
35+
// match path
36+
const{ paths}=child.props
37+
letpathMatch=matches(route,paths)
38+
39+
if(pathMatch){
40+
returnchild.props.children
7241
}
73-
constmessage=`No Route matches for${JSON.stringify(state)}`
74-
onError(newError(message))
75-
console.warn(message)
76-
returnnull
7742
}
43+
constmessage=`No Route matches for "${JSON.stringify(route)}"`
44+
onError(newError(message))
45+
console.warn(message)
46+
returnnull
47+
}
7848

79-
return{
80-
context:state.context,
81-
send:sendWithLog,
82-
Router,
83-
Route,
84-
}
49+
interfaceRouteProps{
50+
children:any
51+
paths:object
8552
}
8653

87-
exportdefaultuseRouter
54+
exportconstRoute=({ children}:RouteProps)=>children

‎web-app/src/containers/Tutorial/ContentMenu.tsxrenamed to‎web-app/src/containers/Tutorial/components/ContentMenu.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as React from 'react'
22
import*asTfrom'typings'
33
import*asTTfrom'typings/tutorial'
44
import{Menu}from'@alifd/next'
5-
importIconfrom'../../components/Icon'
5+
importIconfrom'../../../components/Icon'
66

77
interfaceProps{
88
tutorial:TT.Tutorial

‎web-app/src/containers/Tutorial/components/Hints.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,24 @@ const styles = {
1919

2020
interfaceProps{
2121
hints:string[]
22+
hintIndex:number
23+
setHintIndex(value:number):void
2224
}
2325

2426
constHints=(props:Props)=>{
25-
const[hintIndex,setHintIndex]=React.useState(-1)
26-
constisFinalHint=props.hints.length-1===hintIndex
27+
constisFinalHint=props.hints.length-1===props.hintIndex
2728
constnextHint=()=>{
28-
if(!isFinalHint){
29-
setHintIndex((currentHintIndex)=>currentHintIndex+1)
29+
if(isFinalHint){
30+
return
3031
}
32+
props.setHintIndex(props.hintIndex+1)
3133
}
3234
return(
3335
<divstyle={styles.hints}>
3436
<divstyle={styles.hintList}>
3537
{/* only show revealed hints */}
3638
{props.hints.map((h,i)=>{
37-
returni<=hintIndex ?(
39+
returni<=props.hintIndex ?(
3840
<divkey={i}style={styles.hint}>
3941
<Markdown>{h}</Markdown>
4042
</div>

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp