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

Commit1307578

Browse files
committed
setup routes using objects and route strings
Signed-off-by: shmck <shawn.j.mckay@gmail.com>
1 parent83a55b8 commit1307578

File tree

5 files changed

+135
-120
lines changed

5 files changed

+135
-120
lines changed

‎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: 30 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
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'
@@ -9,47 +9,40 @@ import CompletedPage from './containers/Tutorial/CompletedPage'
99
importTutorialPagefrom'./containers/Tutorial'
1010

1111
constRoutes=()=>{
12-
const{ context,send, Router, Route}=useRouter()
12+
const{ context,route, send}=useStateMachine()
1313

1414
// TODO: handle only full page errors
1515
if(context.error){
16-
return(
17-
<Workspace>
18-
<ErrorViewsend={send}error={context.error}/>
19-
</Workspace>
20-
)
16+
return<ErrorViewsend={send}error={context.error}/>
2117
}
2218

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

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

Lines changed: 0 additions & 8 deletions
This file was deleted.
Lines changed: 37 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,87 +1,50 @@
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)
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+
current=next
19+
continue
20+
}else{
21+
returnfalse
22+
}
3123
}
24+
returntrue
25+
}
3226

33-
console.log(`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
45-
}
46-
sendWithLog(action)
47-
}
48-
window.addEventListener(listener,handler)
49-
return()=>{
50-
window.removeEventListener(listener,handler)
51-
}
52-
},[])
27+
exportconstRouter=({ children, route}:RouterProps)=>{
28+
//@ts-ignore may accept string as well as element
29+
constchildArray:React.ReactElement[]=React.Children.toArray(children)
30+
for(constchildofchildArray){
31+
// match path
32+
const{ paths}=child.props
33+
letpathMatch=matches(route,paths)
5334

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-
}
35+
if(pathMatch){
36+
returnchild.props.children
7237
}
73-
constmessage=`No Route matches for${JSON.stringify(state)}`
74-
onError(newError(message))
75-
console.warn(message)
76-
returnnull
7738
}
39+
constmessage=`No Route matches for "${JSON.stringify(route)}"`
40+
onError(newError(message))
41+
console.warn(message)
42+
returnnull
43+
}
7844

79-
return{
80-
context:state.context,
81-
send:sendWithLog,
82-
Router,
83-
Route,
84-
}
45+
interfaceRouteProps{
46+
children:any
47+
paths:object
8548
}
8649

87-
exportdefaultuseRouter
50+
exportconstRoute=({ children}:RouteProps)=>children
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import*asReactfrom'react'
2+
import*asTfrom'typings'
3+
import{State}from'xstate'
4+
import{createMachine}from'./machine'
5+
import{useMachine}from'../xstate-react'
6+
importloggerfrom'../logger'
7+
8+
interfaceOutput{
9+
context:T.MachineContext
10+
route:string
11+
send:(action:any)=>void
12+
}
13+
14+
declareletacquireVsCodeApi:any
15+
16+
constcreateRouteString=(routeObject:object)=>{
17+
letpaths=[]
18+
constkey=Object.keys(routeObject)[0]
19+
}
20+
21+
consteditor=acquireVsCodeApi()
22+
consteditorSend=(action:T.Action)=>{
23+
logger(`TO EXT: "${action.type}"`)
24+
returneditor.postMessage(action)
25+
}
26+
27+
// router finds first state match of <Route path='' />
28+
constuseStateMachine=():Output=>{
29+
const[state,send]=useMachine<T.MachineContext,any>(createMachine({ editorSend}))
30+
31+
constsendWithLog=(action:T.Action):void=>{
32+
logger(`SEND:${action.type}`,action)
33+
send(action)
34+
}
35+
36+
console.log(`STATE:${JSON.stringify(state.value)}`)
37+
38+
// event bus listener
39+
React.useEffect(()=>{
40+
constlistener='message'
41+
// propograte channel event to state machine
42+
consthandler=(event:any)=>{
43+
// NOTE: must call event.data, cannot destructure. VSCode acts odd
44+
constaction=event.data
45+
// ignore browser events from other extensions
46+
if(action.source){
47+
return
48+
}
49+
sendWithLog(action)
50+
}
51+
window.addEventListener(listener,handler)
52+
return()=>{
53+
window.removeEventListener(listener,handler)
54+
}
55+
},[])
56+
57+
return{
58+
context:state.context,
59+
route:'',
60+
send:sendWithLog,
61+
}
62+
}
63+
64+
exportdefaultuseStateMachine

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp