Skip to content

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 our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
setup storage in editor channel
  • Loading branch information
ShMcK committed Sep 15, 2019
commit 0f992bf4e441a754c2aebd90ee327550d5fb5d85
124 changes: 94 additions & 30 deletions src/Channel.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import * as CR from 'typings'
import * as G from 'typings/graphql'
import * as vscode from 'vscode'

import Storage from './services/storage'
import tutorialConfig from './actions/tutorialConfig'
import setupActions from './actions/setupActions'
import solutionActions from './actions/solutionActions'


interface Channel {
receive(action: CR.Action): Promise<void>
send(action: CR.Action): Promise<void>
Expand All @@ -18,17 +20,25 @@ interface ChannelProps {

class Channel implements Channel {
private postMessage: (action: CR.Action) => Thenable<boolean>
private currentTutorial: Storage<{id: string | null, version: string | null}>
private stepProgress: Storage<CR.StepProgress> | undefined
private currentTutorial: Storage<G.Tutorial | null>
private stepProgress: Storage<CR.StepProgress>
private workspaceState: vscode.Memento
constructor({postMessage, workspaceState}: ChannelProps) {
this.postMessage = postMessage
this.workspaceState = workspaceState

this.currentTutorial = new Storage<{id: string | null, version: string | null}>({
// local storage of current tutorial for continuing tutorials
this.currentTutorial = new Storage<G.Tutorial | null>({
key: 'coderoad:currentTutorial',
storage: workspaceState,
defaultValue: {id: null, version: null}
defaultValue: null,
})

// initialized for consistent typings. unused
this.stepProgress = new Storage<CR.StepProgress>({
key: 'coderoad:stepProgress',
storage: this.workspaceState,
defaultValue: {}
})
}

Expand All @@ -38,39 +48,94 @@ class Channel implements Channel {
console.log('RECEIVED:', actionType)
switch (actionType) {
// continue from tutorial from local storage
case 'TUTORIAL_LOAD_STORED':
const tutorial = await this.currentTutorial.get()
case 'EDITOR_TUTORIAL_LOAD':
const tutorial: G.Tutorial | null = await this.currentTutorial.get()

if (tutorial && tutorial.id && tutorial.version) {
this.stepProgress = new Storage<CR.StepProgress>({
key: `coderoad:stepProgress:${tutorial.id}:${tutorial.version}`,
storage: this.workspaceState,
defaultValue: {}
})
const stepProgress = await this.stepProgress.get()
console.log('looking at stored')
console.log(JSON.stringify(tutorial))
console.log(JSON.stringify(stepProgress))
// communicate to client the tutorial & stepProgress state
this.send({type: 'CONTINUE_TUTORIAL', payload: {tutorial, stepProgress}})
} else {
// new tutorial
if (!tutorial || !tutorial.id || !tutorial.version) {
this.send({type: 'NEW_TUTORIAL'})
return
}

// continue tutorial
// setup progress for specific tutorial
this.stepProgress = new Storage<CR.StepProgress>({
key: `coderoad:stepProgress:${tutorial.id}:${tutorial.version}`,
storage: this.workspaceState,
defaultValue: {}
})
const stepProgress = await this.stepProgress.get()
console.log('looking at stored')
console.log(JSON.stringify(tutorial))
console.log(JSON.stringify(stepProgress))
const progress: CR.Progress = {
steps: stepProgress,
stages: {},
levels: {},
complete: false
}

const position: CR.Position = {
stepId: '',
stageId: '',
levelId: '',
}

// calculate progress from tutorial & stepProgress
for (const level of tutorial.version.levels) {
for (const stage of level.stages) {
// set stage progress
const stageComplete: boolean = stage.steps.every((step: G.Step) => {
return stepProgress[step.id]
})
if (stageComplete) {
progress.stages[stage.id] = true
} else if (!position.stageId.length) {
// set stage amd step position
position.stageId = stage.id
// @ts-ignore
position.stepId = stage.steps.find((step: G.Step) => !stepProgress[step.id]).id
}
}
// set level progress
const levelComplete: boolean = level.stages.every((stage: G.Stage) => {
return progress.stages[stage.id]
})
if (levelComplete) {
progress.levels[level.id] = true
} else if (!position.levelId.length) {
position.levelId = level.id
}
}
// set tutorial progress
progress.complete = tutorial.version.levels.every((level: G.Level) => {
return progress.levels[level.id]
})
// communicate to client the tutorial & stepProgress state
this.send({type: 'CONTINUE_TUTORIAL', payload: {tutorial, progress, position}})

return
// clear tutorial local storage
case 'TUTORIAL_CLEAR':
this.currentTutorial.set({id: null, version: null})
this.currentTutorial.set(null)

// reset tutorial progress on clear
if (this.stepProgress) {
this.stepProgress.set({})
}
this.stepProgress.set({})
return
// configure test runner, language, git
case 'TUTORIAL_CONFIG':
tutorialConfig(action.payload)
this.currentTutorial.set(action.payload)
case 'EDITOR_TUTORIAL_CONFIG':
const tutorialInfo = action.payload.tutorial
console.log('tutorialConfig', JSON.stringify(tutorialInfo))
if (!this.stepProgress) {
// setup progress for new tutorials
this.stepProgress = new Storage<CR.StepProgress>({
key: `coderoad:stepProgress:${tutorialInfo.id}:${tutorialInfo.version.version}`,
storage: this.workspaceState,
defaultValue: {}
})
}
tutorialConfig(tutorialInfo)
this.currentTutorial.set(tutorialInfo)
return
// run unit tests on step
case 'TEST_RUN':
Expand All @@ -97,10 +162,9 @@ class Channel implements Channel {
switch (action.type) {
case 'TEST_PASS':
// update local storage stepProgress
// stepProgress.update({
// [action.payload.stepId]: true
// })
return
this.stepProgress.update({
[action.payload.stepId]: true
})
}

const success = await this.postMessage(action)
Expand Down
1 change: 0 additions & 1 deletion src/editor/commands.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import * as vscode from 'vscode'
import {EditorStorage} from 'typings'
import ReactWebView from './ReactWebView'
import runTest from '../actions/runTest'
import {isEmptyWorkspace} from './workspace'
Expand Down
28 changes: 13 additions & 15 deletions src/services/storage/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,38 +9,36 @@ import * as vscode from 'vscode'
class Storage<T> {
private key: string
private storage: vscode.Memento
constructor({key, storage, defaultValue}: {key: string, storage: vscode.Memento, defaultValue?: T}) {
private defaultValue: T
constructor({key, storage, defaultValue}: {key: string, storage: vscode.Memento, defaultValue: T}) {
this.storage = storage
this.key = key
// set default if none exists
if (!defaultValue) {
return
}
this.get().then((value: T | null) => {
if (!value) {
this.set(defaultValue)
}
})
this.defaultValue = defaultValue
}
public get = async (): Promise<T | null> => {
public get = async (): Promise<T> => {
const value: string | undefined = await this.storage.get(this.key)
// console.log(`STORAGE.get ${this.key} : ${JSON.stringify(value)}`)
console.log(`STORAGE.get ${this.key} : ${value}`)
if (value) {
return JSON.parse(value)
}
return null
return this.defaultValue
}
public set = (value: T): void => {
const stringValue = JSON.stringify(value)
// console.log(`STORAGE.set ${this.key} ${JSON.stringify(value)}`)
console.log(`STORAGE.set ${this.key} ${JSON.stringify(value)}`)
this.storage.update(this.key, stringValue)
}
public update = async (value: T): Promise<void> => {
const current = await this.get()
this.set({
const next = JSON.stringify({
...current,
...value,
})
console.log(`STORAGE.update ${this.key} ${next}`)
this.storage.update(this.key, next)
}
public reset = () => {
this.set(this.defaultValue)
}
}

Expand Down