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

Continue progress#32

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
ShMcK merged 27 commits intomasterfromfix/continue
Sep 23, 2019
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
Show all changes
27 commits
Select commitHold shift + click to select a range
17a71b7
setup storage on server
ShMcKSep 9, 2019
1b99222
continue tutorial progress
ShMcKSep 9, 2019
90e5e97
store tutorial id/version on server
ShMcKSep 9, 2019
e49165c
manage storage in editor Channel
ShMcKSep 14, 2019
0f992bf
setup storage in editor channel
ShMcKSep 15, 2019
f174afa
load progress on server and send to client
ShMcKSep 15, 2019
ecac58b
add continue option to start new
ShMcKSep 15, 2019
33d854c
load stage (not 100%)
ShMcKSep 15, 2019
a54f1d5
save commit on successful test
ShMcKSep 15, 2019
8bea508
setup editor position & progress state
ShMcKSep 15, 2019
83820ab
cleanup deps
ShMcKSep 18, 2019
04d3eca
update deps
ShMcKSep 21, 2019
b1eb6b1
refactor context
ShMcKSep 21, 2019
d1d5384
setup position/progress/tutorial context
ShMcKSep 21, 2019
1a9ccf9
refactor setupActions
ShMcKSep 21, 2019
6217ea6
align channel with context
ShMcKSep 21, 2019
e7b084d
fix build process
ShMcKSep 21, 2019
229c6b8
parse webview from jsdom
ShMcKSep 21, 2019
bab2e54
refactor webview render
ShMcKSep 21, 2019
7bada36
fix webview after webpack build breakage
ShMcKSep 22, 2019
22451c7
fix react web view for latest webpack
ShMcKSep 22, 2019
6f8bee2
add extensive comments to react webview
ShMcKSep 22, 2019
13a4499
clear up CSP issue with GQL
ShMcKSep 22, 2019
ccd088b
fix loading tutorial position
ShMcKSep 22, 2019
30dd21c
fix issues with tutorial init
ShMcKSep 23, 2019
14d4f56
setup editor sync progress (uninitiated)
ShMcKSep 23, 2019
4bb125d
clear tutorial on new
ShMcKSep 23, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions.gitignore
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
node_modules
.vscode-test/
*.vsix
.DS_Store

# local
.env
Expand Down
560 changes: 453 additions & 107 deletionspackage-lock.json
View file
Open in desktop

Large diffs are not rendered by default.

11 changes: 5 additions & 6 deletionspackage.json
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -32,9 +32,7 @@
"dependencies": {
"@types/mocha": "^5.2.7",
"dotenv": "^8.1.0",
"graphql": "^14.5.4",
"graphql-request": "^1.8.2",
"graphql-tag": "^2.10.1",
"jsdom": "^15.1.1",
"vscode": "^1.1.36",
"xstate": "^4.6.7"
},
Expand All@@ -43,15 +41,16 @@
"@types/dotenv": "^6.1.1",
"@types/glob": "^7.1.1",
"@types/graphql": "^14.5.0",
"@types/node": "^12.7.4",
"@types/jsdom": "^12.2.4",
"@types/node": "^12.7.5",
"assert": "^2.0.0",
"concurrently": "^4.1.2",
"glob": "^7.1.4",
"mocha": "^6.2.0",
"prettier": "^1.18.2",
"tslint": "^5.19.0",
"tslint": "^5.20.0",
"tslint-config-prettier": "^1.18.0",
"typescript": "^3.6.2",
"typescript": "^3.6.3",
"vscode-test": "^1.2.0"
},
"engines": {
Expand Down
53 changes: 0 additions & 53 deletionssrc/Channel.ts
View file
Open in desktop

This file was deleted.

8 changes: 8 additions & 0 deletionssrc/actions/saveCommit.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
import * as git from '../services/git'

async function saveCommit() {
console.log('committing progress')
git.saveCommit('Save progress')
}

export default saveCommit
26 changes: 16 additions & 10 deletionssrc/actions/setupActions.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -11,25 +11,20 @@ interface ErrorMessageFilter {
}

// TODO: should be loaded on startup based on language
consterrorMessageFilter: ErrorMessageFilter = {
js: {
constcommandErrorMessageFilter: ErrorMessageFilter = {
JAVASCRIPT: {
'node-gyp': 'Error running npm setup command'
}
}

const setupActions = async ({commands, commits, files}: G.StepActions): Promise<void> => {
// run commits
for (const commit of commits) {
await git.loadCommit(commit)
}

// run command
const runCommands = async (commands: string[], language: string) => {
for (const command of commands) {
const {stdout, stderr} = await node.exec(command)
if (stderr) {
console.error(stderr)
// language specific error messages from running commands
for (const message of Object.keys(errorMessageFilter.js)) {
const filteredMessages = Object.keys(commandErrorMessageFilter[language])
for (const message of filteredMessages) {
if (stderr.match(message)) {
// ignored error
throw new Error('Error running setup command')
Expand All@@ -38,6 +33,17 @@ const setupActions = async ({commands, commits, files}: G.StepActions): Promise<
}
console.log(`run command: ${command}`, stdout)
}
}


const setupActions = async ({commands, commits, files}: G.StepActions): Promise<void> => {
// run commits
for (const commit of commits) {
await git.loadCommit(commit)
}

// run command


// open files
for (const filePath of files) {
Expand Down
28 changes: 28 additions & 0 deletionssrc/channel/context.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
import * as CR from 'typings'
import * as G from 'typings/graphql'
import * as vscode from 'vscode'

import Position from './state/Position'
import Progress from './state/Progress'
import Tutorial from './state/Tutorial'

class Context {
public tutorial: Tutorial
public position: Position
public progress: Progress
constructor(workspaceState: vscode.Memento) {

// state held in one place
this.tutorial = new Tutorial(workspaceState)
this.position = new Position()
this.progress = new Progress()
}
public setTutorial = async (workspaceState: vscode.Memento, tutorial: G.Tutorial): Promise<{progress: CR.Progress, position: CR.Position}> => {
this.tutorial.set(tutorial)
const progress: CR.Progress = await this.progress.setTutorial(workspaceState, tutorial)
const position: CR.Position = this.position.setPositionFromProgress(tutorial, progress)
return {progress, position}
}
}

export default Context
123 changes: 123 additions & 0 deletionssrc/channel/index.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
import * as CR from 'typings'
import * as G from 'typings/graphql'
import * as vscode from 'vscode'

import Context from './context'
import tutorialConfig from '../actions/tutorialConfig'
import setupActions from '../actions/setupActions'
import solutionActions from '../actions/solutionActions'
import saveCommit from '../actions/saveCommit'


interface Channel {
receive(action: CR.Action): Promise<void>
send(action: CR.Action): Promise<void>
}

interface ChannelProps {
postMessage: (action: CR.Action) => Thenable<boolean>
workspaceState: vscode.Memento
}


class Channel implements Channel {
private postMessage: (action: CR.Action) => Thenable<boolean>
private workspaceState: vscode.Memento
private context: Context
constructor({postMessage, workspaceState}: ChannelProps) {
// workspaceState used for local storage
this.workspaceState = workspaceState
this.postMessage = postMessage
this.context = new Context(workspaceState)
}

// receive from webview
public receive = async (action: CR.Action) => {
// action may be an object.type or plain string
const actionType: string = typeof action === 'string' ? action : action.type

console.log('EDITOR RECEIVED:', actionType)
switch (actionType) {
// continue from tutorial from local storage
case 'EDITOR_TUTORIAL_LOAD':
const tutorial: G.Tutorial | null = this.context.tutorial.get()

// new tutorial
if (!tutorial || !tutorial.id || !tutorial.version) {
this.send({type: 'NEW_TUTORIAL'})
return
}

// set tutorial
const {position, progress} = await this.context.setTutorial(this.workspaceState, tutorial)

if (progress.complete) {
// tutorial is already complete
this.send({type: 'NEW_TUTORIAL'})
return
}

// communicate to client the tutorial & stepProgress state
this.send({type: 'CONTINUE_TUTORIAL', payload: {tutorial, progress, position}})

return
// clear tutorial local storage
case 'TUTORIAL_CLEAR':
// clear current progress/position/tutorial
this.context = new Context(this.workspaceState)
return
// configure test runner, language, git
case 'EDITOR_TUTORIAL_CONFIG':
const tutorialData = action.payload.tutorial
this.context.setTutorial(this.workspaceState, tutorialData)
tutorialConfig(tutorialData)
return
case 'EDITOR_SYNC_PROGRESS':
// sync client progress on server
this.context.position.set(action.payload.position)
this.context.progress.set(action.payload.progress)
return
// run unit tests on step
case 'TEST_RUN':
vscode.commands.executeCommand('coderoad.run_test', action.payload)
return
// load step actions (git commits, commands, open files)
case 'SETUP_ACTIONS':
vscode.commands.executeCommand('coderoad.set_current_step', action.payload)
setupActions(action.payload)
return
// load solution step actions (git commits, commands, open files)
case 'SOLUTION_ACTIONS':
solutionActions(action.payload)
return

default:
console.log(`No match for action type: ${actionType}`)
return
}
}
// send to webview
public send = async (action: CR.Action) => {

switch (action.type) {
case 'TEST_PASS':
// update local storage stepProgress
const progress = this.context.progress.setStepComplete(action.payload.stepId)
const tutorial = this.context.tutorial.get()
if (!tutorial) {
throw new Error('Error with current tutorial')
}
this.context.position.setPositionFromProgress(tutorial, progress)
saveCommit()
}

const success = await this.postMessage(action)
if (!success) {
throw new Error(`Message post failure: ${JSON.stringify(action)}`)
}
}

}

export default Channel

63 changes: 63 additions & 0 deletionssrc/channel/state/Position.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
import * as CR from 'typings'
import * as G from 'typings/graphql'

// position
class Position {
private value: CR.Position
constructor() {
this.value = {
levelId: '',
stageId: '',
stepId: '',
}
}
public get = () => {
return this.value
}
public set = (value: CR.Position) => {
this.value = value
}
// calculate the current position based on the saved progress
public setPositionFromProgress = (tutorial: G.Tutorial, progress: CR.Progress): CR.Position => {

// tutorial already completed
// TODO: handle start again?
if (progress.complete) {
return this.value
}

const {levels} = tutorial.version

const lastLevelIndex: number | undefined = levels.findIndex((l: G.Level) => progress.levels[l.id])
// TODO: consider all levels complete as progress.complete
if (lastLevelIndex >= levels.length) {
throw new Error('Error setting progress level')
}
const currentLevel: G.Level = levels[lastLevelIndex + 1]

const {stages} = currentLevel

const lastStageIndex: number | undefined = stages.findIndex((s: G.Stage) => progress.stages[s.id])
if (lastStageIndex >= stages.length) {
throw new Error('Error setting progress stage')
}
const currentStage: G.Stage = stages[lastStageIndex + 1]

const {steps} = currentStage

const lastStepIndex: number | undefined = steps.findIndex((s: G.Step) => progress.steps[s.id])
if (lastStepIndex >= steps.length) {
throw new Error('Error setting progress step')
}
const currentStep: G.Step = steps[lastStepIndex + 1]

this.value = {
levelId: currentLevel.id,
stageId: currentStage.id,
stepId: currentStep.id,
}
return this.value
}
}

export default Position
Loading

[8]ページ先頭

©2009-2025 Movatter.jp