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

Commite3ace75

Browse files
authored
Merge pull request#32 from ShMcK/fix/continue
Continue progress
2 parentsdc6655d +4bb125d commite3ace75

File tree

31 files changed

+6919
-6884
lines changed

31 files changed

+6919
-6884
lines changed

‎.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
node_modules
22
.vscode-test/
33
*.vsix
4+
.DS_Store
45

56
# local
67
.env

‎package-lock.json

Lines changed: 453 additions & 107 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎package.json

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,7 @@
3232
"dependencies": {
3333
"@types/mocha":"^5.2.7",
3434
"dotenv":"^8.1.0",
35-
"graphql":"^14.5.4",
36-
"graphql-request":"^1.8.2",
37-
"graphql-tag":"^2.10.1",
35+
"jsdom":"^15.1.1",
3836
"vscode":"^1.1.36",
3937
"xstate":"^4.6.7"
4038
},
@@ -43,15 +41,16 @@
4341
"@types/dotenv":"^6.1.1",
4442
"@types/glob":"^7.1.1",
4543
"@types/graphql":"^14.5.0",
46-
"@types/node":"^12.7.4",
44+
"@types/jsdom":"^12.2.4",
45+
"@types/node":"^12.7.5",
4746
"assert":"^2.0.0",
4847
"concurrently":"^4.1.2",
4948
"glob":"^7.1.4",
5049
"mocha":"^6.2.0",
5150
"prettier":"^1.18.2",
52-
"tslint":"^5.19.0",
51+
"tslint":"^5.20.0",
5352
"tslint-config-prettier":"^1.18.0",
54-
"typescript":"^3.6.2",
53+
"typescript":"^3.6.3",
5554
"vscode-test":"^1.2.0"
5655
},
5756
"engines": {

‎src/Channel.ts

Lines changed: 0 additions & 53 deletions
This file was deleted.

‎src/actions/saveCommit.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import*asgitfrom'../services/git'
2+
3+
asyncfunctionsaveCommit(){
4+
console.log('committing progress')
5+
git.saveCommit('Save progress')
6+
}
7+
8+
exportdefaultsaveCommit

‎src/actions/setupActions.ts

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,20 @@ interface ErrorMessageFilter {
1111
}
1212

1313
// TODO: should be loaded on startup based on language
14-
consterrorMessageFilter:ErrorMessageFilter={
15-
js:{
14+
constcommandErrorMessageFilter:ErrorMessageFilter={
15+
JAVASCRIPT:{
1616
'node-gyp':'Error running npm setup command'
1717
}
1818
}
1919

20-
constsetupActions=async({commands, commits, files}:G.StepActions):Promise<void>=>{
21-
// run commits
22-
for(constcommitofcommits){
23-
awaitgit.loadCommit(commit)
24-
}
25-
26-
// run command
20+
construnCommands=async(commands:string[],language:string)=>{
2721
for(constcommandofcommands){
2822
const{stdout, stderr}=awaitnode.exec(command)
2923
if(stderr){
3024
console.error(stderr)
3125
// language specific error messages from running commands
32-
for(constmessageofObject.keys(errorMessageFilter.js)){
26+
constfilteredMessages=Object.keys(commandErrorMessageFilter[language])
27+
for(constmessageoffilteredMessages){
3328
if(stderr.match(message)){
3429
// ignored error
3530
thrownewError('Error running setup command')
@@ -38,6 +33,17 @@ const setupActions = async ({commands, commits, files}: G.StepActions): Promise<
3833
}
3934
console.log(`run command:${command}`,stdout)
4035
}
36+
}
37+
38+
39+
constsetupActions=async({commands, commits, files}:G.StepActions):Promise<void>=>{
40+
// run commits
41+
for(constcommitofcommits){
42+
awaitgit.loadCommit(commit)
43+
}
44+
45+
// run command
46+
4147

4248
// open files
4349
for(constfilePathoffiles){

‎src/channel/context.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import*asCRfrom'typings'
2+
import*asGfrom'typings/graphql'
3+
import*asvscodefrom'vscode'
4+
5+
importPositionfrom'./state/Position'
6+
importProgressfrom'./state/Progress'
7+
importTutorialfrom'./state/Tutorial'
8+
9+
classContext{
10+
publictutorial:Tutorial
11+
publicposition:Position
12+
publicprogress:Progress
13+
constructor(workspaceState:vscode.Memento){
14+
15+
// state held in one place
16+
this.tutorial=newTutorial(workspaceState)
17+
this.position=newPosition()
18+
this.progress=newProgress()
19+
}
20+
publicsetTutorial=async(workspaceState:vscode.Memento,tutorial:G.Tutorial):Promise<{progress:CR.Progress,position:CR.Position}>=>{
21+
this.tutorial.set(tutorial)
22+
constprogress:CR.Progress=awaitthis.progress.setTutorial(workspaceState,tutorial)
23+
constposition:CR.Position=this.position.setPositionFromProgress(tutorial,progress)
24+
return{progress, position}
25+
}
26+
}
27+
28+
exportdefaultContext

‎src/channel/index.ts

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
import*asCRfrom'typings'
2+
import*asGfrom'typings/graphql'
3+
import*asvscodefrom'vscode'
4+
5+
importContextfrom'./context'
6+
importtutorialConfigfrom'../actions/tutorialConfig'
7+
importsetupActionsfrom'../actions/setupActions'
8+
importsolutionActionsfrom'../actions/solutionActions'
9+
importsaveCommitfrom'../actions/saveCommit'
10+
11+
12+
interfaceChannel{
13+
receive(action:CR.Action):Promise<void>
14+
send(action:CR.Action):Promise<void>
15+
}
16+
17+
interfaceChannelProps{
18+
postMessage:(action:CR.Action)=>Thenable<boolean>
19+
workspaceState:vscode.Memento
20+
}
21+
22+
23+
classChannelimplementsChannel{
24+
privatepostMessage:(action:CR.Action)=>Thenable<boolean>
25+
privateworkspaceState:vscode.Memento
26+
privatecontext:Context
27+
constructor({postMessage, workspaceState}:ChannelProps){
28+
// workspaceState used for local storage
29+
this.workspaceState=workspaceState
30+
this.postMessage=postMessage
31+
this.context=newContext(workspaceState)
32+
}
33+
34+
// receive from webview
35+
publicreceive=async(action:CR.Action)=>{
36+
// action may be an object.type or plain string
37+
constactionType:string=typeofaction==='string' ?action :action.type
38+
39+
console.log('EDITOR RECEIVED:',actionType)
40+
switch(actionType){
41+
// continue from tutorial from local storage
42+
case'EDITOR_TUTORIAL_LOAD':
43+
consttutorial:G.Tutorial|null=this.context.tutorial.get()
44+
45+
// new tutorial
46+
if(!tutorial||!tutorial.id||!tutorial.version){
47+
this.send({type:'NEW_TUTORIAL'})
48+
return
49+
}
50+
51+
// set tutorial
52+
const{position, progress}=awaitthis.context.setTutorial(this.workspaceState,tutorial)
53+
54+
if(progress.complete){
55+
// tutorial is already complete
56+
this.send({type:'NEW_TUTORIAL'})
57+
return
58+
}
59+
60+
// communicate to client the tutorial & stepProgress state
61+
this.send({type:'CONTINUE_TUTORIAL',payload:{tutorial, progress, position}})
62+
63+
return
64+
// clear tutorial local storage
65+
case'TUTORIAL_CLEAR':
66+
// clear current progress/position/tutorial
67+
this.context=newContext(this.workspaceState)
68+
return
69+
// configure test runner, language, git
70+
case'EDITOR_TUTORIAL_CONFIG':
71+
consttutorialData=action.payload.tutorial
72+
this.context.setTutorial(this.workspaceState,tutorialData)
73+
tutorialConfig(tutorialData)
74+
return
75+
case'EDITOR_SYNC_PROGRESS':
76+
// sync client progress on server
77+
this.context.position.set(action.payload.position)
78+
this.context.progress.set(action.payload.progress)
79+
return
80+
// run unit tests on step
81+
case'TEST_RUN':
82+
vscode.commands.executeCommand('coderoad.run_test',action.payload)
83+
return
84+
// load step actions (git commits, commands, open files)
85+
case'SETUP_ACTIONS':
86+
vscode.commands.executeCommand('coderoad.set_current_step',action.payload)
87+
setupActions(action.payload)
88+
return
89+
// load solution step actions (git commits, commands, open files)
90+
case'SOLUTION_ACTIONS':
91+
solutionActions(action.payload)
92+
return
93+
94+
default:
95+
console.log(`No match for action type:${actionType}`)
96+
return
97+
}
98+
}
99+
// send to webview
100+
publicsend=async(action:CR.Action)=>{
101+
102+
switch(action.type){
103+
case'TEST_PASS':
104+
// update local storage stepProgress
105+
constprogress=this.context.progress.setStepComplete(action.payload.stepId)
106+
consttutorial=this.context.tutorial.get()
107+
if(!tutorial){
108+
thrownewError('Error with current tutorial')
109+
}
110+
this.context.position.setPositionFromProgress(tutorial,progress)
111+
saveCommit()
112+
}
113+
114+
constsuccess=awaitthis.postMessage(action)
115+
if(!success){
116+
thrownewError(`Message post failure:${JSON.stringify(action)}`)
117+
}
118+
}
119+
120+
}
121+
122+
exportdefaultChannel
123+

‎src/channel/state/Position.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import*asCRfrom'typings'
2+
import*asGfrom'typings/graphql'
3+
4+
// position
5+
classPosition{
6+
privatevalue:CR.Position
7+
constructor(){
8+
this.value={
9+
levelId:'',
10+
stageId:'',
11+
stepId:'',
12+
}
13+
}
14+
publicget=()=>{
15+
returnthis.value
16+
}
17+
publicset=(value:CR.Position)=>{
18+
this.value=value
19+
}
20+
// calculate the current position based on the saved progress
21+
publicsetPositionFromProgress=(tutorial:G.Tutorial,progress:CR.Progress):CR.Position=>{
22+
23+
// tutorial already completed
24+
// TODO: handle start again?
25+
if(progress.complete){
26+
returnthis.value
27+
}
28+
29+
const{levels}=tutorial.version
30+
31+
constlastLevelIndex:number|undefined=levels.findIndex((l:G.Level)=>progress.levels[l.id])
32+
// TODO: consider all levels complete as progress.complete
33+
if(lastLevelIndex>=levels.length){
34+
thrownewError('Error setting progress level')
35+
}
36+
constcurrentLevel:G.Level=levels[lastLevelIndex+1]
37+
38+
const{stages}=currentLevel
39+
40+
constlastStageIndex:number|undefined=stages.findIndex((s:G.Stage)=>progress.stages[s.id])
41+
if(lastStageIndex>=stages.length){
42+
thrownewError('Error setting progress stage')
43+
}
44+
constcurrentStage:G.Stage=stages[lastStageIndex+1]
45+
46+
const{steps}=currentStage
47+
48+
constlastStepIndex:number|undefined=steps.findIndex((s:G.Step)=>progress.steps[s.id])
49+
if(lastStepIndex>=steps.length){
50+
thrownewError('Error setting progress step')
51+
}
52+
constcurrentStep:G.Step=steps[lastStepIndex+1]
53+
54+
this.value={
55+
levelId:currentLevel.id,
56+
stageId:currentStage.id,
57+
stepId:currentStep.id,
58+
}
59+
returnthis.value
60+
}
61+
}
62+
63+
exportdefaultPosition

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp