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
manage storage in editor Channel
  • Loading branch information
ShMcK committed Sep 14, 2019
commit e49165c884bad4b170ed62458404a92398afa7a6
59 changes: 42 additions & 17 deletions src/Channel.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as CR from 'typings'
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'
Expand All @@ -12,18 +13,23 @@ interface Channel {

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

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

this.currentTutorial = new Storage<{id: string | null, version: string | null}>({
key: 'coderoad:currentTutorial',
storage: workspaceState,
defaultValue: {id: null, version: null}
})
}

// receive from webview
Expand All @@ -33,14 +39,19 @@ class Channel implements Channel {
switch (actionType) {
// continue from tutorial from local storage
case 'TUTORIAL_LOAD_STORED':
const tutorial = await this.storage.tutorial.get()
const stepProgress = await this.storage.stepProgress.get()

console.log('looking at stored')
console.log(JSON.stringify(tutorial))
console.log(JSON.stringify(stepProgress))
const tutorial = await this.currentTutorial.get()

if (tutorial && tutorial.id) {
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 {
this.send({type: 'NEW_TUTORIAL'})
Expand All @@ -49,13 +60,17 @@ class Channel implements Channel {
return
// clear tutorial local storage
case 'TUTORIAL_CLEAR':
this.storage.tutorial.set(null)
this.storage.stepProgress.set({})
this.currentTutorial.set({id: null, version: null})

// reset tutorial progress on clear
if (this.stepProgress) {
this.stepProgress.set({})
}
return
// configure test runner, language, git
case 'TUTORIAL_CONFIG':
tutorialConfig(action.payload)
this.storage.tutorial.set(action.payload)
this.currentTutorial.set(action.payload)
return
// run unit tests on step
case 'TEST_RUN':
Expand All @@ -78,6 +93,16 @@ class Channel implements Channel {
}
// send to webview
public send = async (action: CR.Action) => {

switch (action.type) {
case 'TEST_PASS':
// update local storage stepProgress
// stepProgress.update({
// [action.payload.stepId]: true
// })
return
}

const success = await this.postMessage(action)
if (!success) {
throw new Error(`Message post failure: ${JSON.stringify(action)}`)
Expand Down
10 changes: 4 additions & 6 deletions src/editor/ReactWebView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@ const getNonce = (): string => {

interface ReactWebViewProps {
extensionPath: string
storage: {
tutorial: any
stepProgress: any
}
workspaceState: vscode.Memento
}


Expand All @@ -32,7 +29,7 @@ class ReactWebView {
private disposables: vscode.Disposable[] = []
private channel: Channel

public constructor({extensionPath, storage}: ReactWebViewProps) {
public constructor({extensionPath, workspaceState}: ReactWebViewProps) {
this.extensionPath = extensionPath

// Create and show a new webview panel
Expand All @@ -45,8 +42,9 @@ class ReactWebView {
// This happens when the user closes the panel or when the panel is closed programmatically
this.panel.onDidDispose(this.dispose, this, this.disposables)

// channel connects webview to the editor
this.channel = new Channel({
storage,
workspaceState,
postMessage: (action: Action): Thenable<boolean> => {
return this.panel.webview.postMessage(action)
}
Expand Down
30 changes: 6 additions & 24 deletions src/editor/commands.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import * as G from 'typings/graphql'
import * as vscode from 'vscode'
import Storage from '../services/storage'
import {EditorStorage} from 'typings'
import ReactWebView from './ReactWebView'
import runTest from '../actions/runTest'
import {isEmptyWorkspace} from './workspace'
Expand All @@ -13,25 +12,15 @@ const COMMANDS = {
}

interface CreateCommandProps {
vscodeExt: vscode.ExtensionContext
extensionPath: string
workspaceState: vscode.Memento
}

export const createCommands = ({vscodeExt}: CreateCommandProps) => {
export const createCommands = ({extensionPath, workspaceState}: CreateCommandProps) => {
// React panel webview
let webview: any
let currentStepId = ''

const tutorial = new Storage<G.Tutorial | null>({
key: 'coderoad:tutorial',
storage: vscodeExt.workspaceState
})

const stepProgress = new Storage<{[stepId: string]: boolean}>({
key: 'coderoad:progress',
storage: vscodeExt.workspaceState
})


return {
// initialize
[COMMANDS.START]: async () => {
Expand All @@ -53,11 +42,8 @@ export const createCommands = ({vscodeExt}: CreateCommandProps) => {

// activate machine
webview = new ReactWebView({
extensionPath: vscodeExt.extensionPath,
storage: {
tutorial,
stepProgress
}
extensionPath,
workspaceState,
})
},
// open React webview
Expand Down Expand Up @@ -86,10 +72,6 @@ export const createCommands = ({vscodeExt}: CreateCommandProps) => {
console.log('COMMAND TEST_PASS')
// send test pass message back to client
webview.send({type: 'TEST_PASS', payload})
// update local storage stepProgress
stepProgress.update({
[payload.stepId]: true
})
vscode.window.showInformationMessage('PASS')
},
onFail: () => {
Expand Down
17 changes: 16 additions & 1 deletion src/editor/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,24 @@ class Editor {
}

private activateCommands = (): void => {
// NOTE: local storage must be bound to the vscodeExt.workspaceState

// store current tutorial id & version


// store step progress for current tutorial
// const stepProgress = new Storage<{[stepId: string]: boolean}>({
// key: 'coderoad:progress',
// storage: this.vscodeExt.workspaceState,
// defaultValue: {},
// })

const commands = createCommands({
vscodeExt: this.vscodeExt,
extensionPath: this.vscodeExt.extensionPath,
workspaceState: this.vscodeExt.workspaceState,
})

// register commands
for (const cmd in commands) {
const command: vscode.Disposable = vscode.commands.registerCommand(cmd, commands[cmd])
this.vscodeExt.subscriptions.push(command)
Expand Down
11 changes: 10 additions & 1 deletion src/services/storage/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,18 @@ import * as vscode from 'vscode'
class Storage<T> {
private key: string
private storage: vscode.Memento
constructor({key, storage}: {key: string, storage: vscode.Memento}) {
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)
}
})
}
public get = async (): Promise<T | null> => {
const value: string | undefined = await this.storage.get(this.key)
Expand Down
10 changes: 10 additions & 0 deletions typings/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {send} from 'xstate'
import Storage from '../src/services/storage'
import * as G from './graphql'

export interface TutorialLevel {
Expand Down Expand Up @@ -98,6 +99,10 @@ export interface Progress {
complete: boolean
}

export interface StepProgress {
[stepId: string]: boolean
}

// current tutorial position
export interface Position {
levelId: string
Expand Down Expand Up @@ -176,3 +181,8 @@ interface MessageState {

// todo: type each string param and payload
export type EditorDispatch = (type: string, payload?: MessageData | MessageState | any) => void

export interface EditorStorage {
currentTutorial: Storage<{id: string | null, version: string | null}>
stepProgress: Storage<StepProgress>
}