|
1 | | -import { join } from 'path' |
| 1 | +import {join} from 'path' |
2 | 2 | import * as CR from 'typings' |
| 3 | +import * as G from 'typings/graphql' |
3 | 4 | import * as vscode from 'vscode' |
4 | 5 | import ReactWebView from '../ReactWebView' |
5 | | -import { setStorage } from '../storage' |
6 | | -import { isEmptyWorkspace } from '../workspace' |
| 6 | +import {setStorage} from '../storage' |
| 7 | +import {isEmptyWorkspace} from '../workspace' |
7 | 8 | import runTest from './runTest' |
8 | 9 |
|
9 | 10 | const COMMANDS = { |
10 | | - START: 'coderoad.start', |
11 | | - TUTORIAL_LAUNCH: 'coderoad.tutorial_launch', |
12 | | - TUTORIAL_SETUP: 'coderoad.tutorial_setup', |
13 | | - OPEN_WEBVIEW: 'coderoad.open_webview', |
14 | | - SEND_STATE: 'coderoad.send_state', |
15 | | - SEND_DATA: 'coderoad.send_data', |
16 | | - RECEIVE_ACTION: 'coderoad.receive_action', |
17 | | - OPEN_FILE: 'coderoad.open_file', |
18 | | - RUN_TEST: 'coderoad.run_test', |
19 | | - TEST_PASS: 'coderoad.test_pass', |
20 | | - TEST_FAIL: 'coderoad.test_fail', |
| 11 | + START: 'coderoad.start', |
| 12 | + TUTORIAL_LAUNCH: 'coderoad.tutorial_launch', |
| 13 | + TUTORIAL_SETUP: 'coderoad.tutorial_setup', |
| 14 | + OPEN_WEBVIEW: 'coderoad.open_webview', |
| 15 | + SEND_STATE: 'coderoad.send_state', |
| 16 | + SEND_DATA: 'coderoad.send_data', |
| 17 | + RECEIVE_ACTION: 'coderoad.receive_action', |
| 18 | + OPEN_FILE: 'coderoad.open_file', |
| 19 | + RUN_TEST: 'coderoad.run_test', |
| 20 | + TEST_PASS: 'coderoad.test_pass', |
| 21 | + TEST_FAIL: 'coderoad.test_fail', |
21 | 22 | } |
22 | 23 |
|
23 | 24 | interface CreateCommandProps { |
24 | | - context: vscode.ExtensionContext |
25 | | - machine: CR.StateMachine |
26 | | - storage: any |
27 | | - git: any |
28 | | - position: any |
| 25 | + context: vscode.ExtensionContext |
| 26 | + machine: CR.StateMachine |
| 27 | + storage: any |
| 28 | + git: any |
| 29 | + position: any |
29 | 30 | } |
30 | 31 |
|
31 | 32 | const resetLayout = () => { |
32 | | - vscode.commands.executeCommand('vscode.setEditorLayout', { |
33 | | - orientation: 0, |
34 | | - groups: [{ groups: [{}], size: 0.6 }, { groups: [{}], size: 0.4 }], |
35 | | - }) |
| 33 | + vscode.commands.executeCommand('vscode.setEditorLayout', { |
| 34 | + orientation: 0, |
| 35 | + groups: [{groups: [{}], size: 0.6}, {groups: [{}], size: 0.4}], |
| 36 | + }) |
36 | 37 | } |
37 | 38 |
|
38 | | -export const createCommands = ({ context, machine, storage, git, position }: CreateCommandProps) => { |
39 | | - // React panel webview |
40 | | - let webview: any |
| 39 | +export const createCommands = ({context, machine, storage, git, position}: CreateCommandProps) => { |
| 40 | + // React panel webview |
| 41 | + let webview: any |
41 | 42 |
|
42 | | - return { |
43 | | - // initialize |
44 | | - [COMMANDS.START]: () => { |
| 43 | + return { |
| 44 | + // initialize |
| 45 | + [COMMANDS.START]: () => { |
45 | 46 |
|
46 | | - let webviewState: 'INITIALIZING' | 'RESTARTING' |
47 | | - if (!webview) { |
48 | | - webviewState = 'INITIALIZING' |
49 | | - } else if (webview.loaded) { |
50 | | - // already loaded |
51 | | - vscode.window.showInformationMessage('CodeRoad already open') |
52 | | - return |
53 | | - } else { |
54 | | - webviewState = 'RESTARTING' |
55 | | - } |
| 47 | + let webviewState: 'INITIALIZING' | 'RESTARTING' |
| 48 | + if (!webview) { |
| 49 | + webviewState = 'INITIALIZING' |
| 50 | + } else if (webview.loaded) { |
| 51 | + // already loaded |
| 52 | + vscode.window.showInformationMessage('CodeRoad already open') |
| 53 | + return |
| 54 | + } else { |
| 55 | + webviewState = 'RESTARTING' |
| 56 | + } |
56 | 57 |
|
57 | | - setStorage(context.workspaceState) |
| 58 | + setStorage(context.workspaceState) |
58 | 59 |
|
59 | | - // activate machine |
60 | | - webview = new ReactWebView(context.extensionPath) |
61 | | - if (webviewState === 'INITIALIZING') { |
62 | | - machine.activate() |
63 | | - } else if (webviewState === 'RESTARTING') { |
64 | | - setTimeout(() => { |
65 | | - // timeout hack to make data update on new windows |
66 | | - // @ts-ignore |
67 | | - machine.refresh() |
68 | | - }, 1000) |
69 | | - } |
70 | | - }, |
71 | | - // open React webview |
72 | | - [COMMANDS.OPEN_WEBVIEW]: (column: number = vscode.ViewColumn.Two) => { |
73 | | - // setup 1x1 horizontal layout |
74 | | - resetLayout() |
75 | | - const callback = () => { |
76 | | - machine.send('WEBVIEW_INITIALIZED') |
77 | | - } |
78 | | - webview.createOrShow(column, callback) |
79 | | - }, |
80 | | - // launch a new tutorial |
81 | | - // NOTE: may be better to move into action as logic is primarily non-vscode |
82 | | - [COMMANDS.TUTORIAL_LAUNCH]: async ({ tutorial, dispatch }: any) => { |
83 | | - console.log('launch tutorial') |
| 60 | + // activate machine |
| 61 | + webview = new ReactWebView(context.extensionPath) |
| 62 | + if (webviewState === 'INITIALIZING') { |
| 63 | + machine.activate() |
| 64 | + } else if (webviewState === 'RESTARTING') { |
| 65 | + setTimeout(() => { |
| 66 | + // timeout hack to make data update on new windows |
| 67 | + // @ts-ignore |
| 68 | + machine.refresh() |
| 69 | + }, 1000) |
| 70 | + } |
| 71 | + }, |
| 72 | + // open React webview |
| 73 | + [COMMANDS.OPEN_WEBVIEW]: (column: number = vscode.ViewColumn.Two) => { |
| 74 | + // setup 1x1 horizontal layout |
| 75 | + resetLayout() |
| 76 | + const callback = () => { |
| 77 | + machine.send('WEBVIEW_INITIALIZED') |
| 78 | + } |
| 79 | + webview.createOrShow(column, callback) |
| 80 | + }, |
| 81 | + // launch a new tutorial |
| 82 | + // NOTE: may be better to move into action as logic is primarily non-vscode |
| 83 | + [COMMANDS.TUTORIAL_LAUNCH]: async (tutorial: G.Tutorial) => { |
| 84 | + console.log('launch tutorial') |
84 | 85 |
|
85 | | - await isEmptyWorkspace() |
| 86 | + await isEmptyWorkspace() |
86 | 87 |
|
87 | | - await git.gitInitIfNotExists() |
| 88 | + await git.gitInitIfNotExists() |
88 | 89 |
|
89 | | - // TODO: use actual tutorial repo |
90 | | - await Promise.all([git.gitSetupRemote(tutorial.meta.repo), storage.setTutorial(tutorial), storage.resetProgress()]) |
| 90 | + if (!tutorial.repo || !tutorial.repo.uri) { |
| 91 | + throw new Error('Tutorial repo uri not found') |
| 92 | + } |
91 | 93 |
|
92 | | - machine.send('TUTORIAL_LOADED') |
93 | | - }, |
94 | | - [COMMANDS.TUTORIAL_SETUP]: async (tutorial: CR.Tutorial) => { |
95 | | - console.log('tutorial setup', tutorial) |
96 | | - // setup onSave hook |
97 | | - const languageIds = tutorial.meta.languages |
98 | | - console.log(`languageIds: ${languageIds.join(', ')}`) |
99 | | - vscode.workspace.onDidSaveTextDocument((document: vscode.TextDocument) => { |
100 | | - console.log('save document', document) |
101 | | - if (languageIds.includes(document.languageId) && document.uri.scheme === 'file') { |
102 | | - // do work |
103 | | - machine.send('TEST_RUN') |
104 | | - } |
105 | | - }) |
106 | | - }, |
107 | | - // open a file |
108 | | - [COMMANDS.OPEN_FILE]: async (relativeFilePath: string) => { |
109 | | - console.log(`OPEN_FILE ${JSON.stringify(relativeFilePath)}`) |
110 | | - try { |
111 | | - const workspaceRoot = vscode.workspace.rootPath |
112 | | - if (!workspaceRoot) { |
113 | | - throw new Error('No workspace root path') |
114 | | - } |
115 | | - const absoluteFilePath = join(workspaceRoot, relativeFilePath) |
116 | | - const doc = await vscode.workspace.openTextDocument(absoluteFilePath) |
117 | | - await vscode.window.showTextDocument(doc, vscode.ViewColumn.One) |
118 | | - // there are times when intialization leave the panel behind any files opened |
119 | | - // ensure the panel is redrawn on the right side first |
120 | | - webview.createOrShow(vscode.ViewColumn.Two) |
121 | | - } catch (error) { |
122 | | - console.log(`Failed to open file ${relativeFilePath}`, error) |
123 | | - } |
124 | | - }, |
125 | | - // send messages to webview |
126 | | - [COMMANDS.SEND_STATE]: (payload: { data: any; state: any }) => { |
127 | | - webview.postMessage({ type: 'SET_STATE', payload }) |
128 | | - }, |
129 | | - [COMMANDS.SEND_DATA]: (payload: { data: any }) => { |
130 | | - webview.postMessage({ type: 'SET_DATA', payload }) |
131 | | - }, |
132 | | - [COMMANDS.RECEIVE_ACTION]: (action: string | CR.Action) => { |
133 | | - // send received actions from web-app into state machine |
134 | | - machine.send(action) |
135 | | - }, |
136 | | - [COMMANDS.RUN_TEST]: () => { |
137 | | - runTest({ |
138 | | - onSuccess: () => machine.send('TEST_PASS'), |
139 | | - onFail: () => machine.send('TEST_FAIL'), |
140 | | - }) |
141 | | - }, |
142 | | - [COMMANDS.TEST_PASS]: () => { |
143 | | - vscode.window.showInformationMessage('PASS') |
144 | | - }, |
145 | | - [COMMANDS.TEST_FAIL]: () => { |
146 | | - vscode.window.showWarningMessage('FAIL') |
147 | | - }, |
148 | | - } |
| 94 | + // TODO: use actual tutorial repo |
| 95 | + await Promise.all([git.gitSetupRemote(tutorial.repo.uri), storage.setTutorial(tutorial), storage.resetProgress()]) |
| 96 | + |
| 97 | + machine.send('TUTORIAL_LOADED') |
| 98 | + }, |
| 99 | + [COMMANDS.TUTORIAL_SETUP]: async (tutorial: CR.Tutorial) => { |
| 100 | + console.log('tutorial setup', tutorial) |
| 101 | + // setup onSave hook |
| 102 | + const languageIds = tutorial.meta.languages |
| 103 | + console.log(`languageIds: ${languageIds.join(', ')}`) |
| 104 | + vscode.workspace.onDidSaveTextDocument((document: vscode.TextDocument) => { |
| 105 | + console.log('save document', document) |
| 106 | + if (languageIds.includes(document.languageId) && document.uri.scheme === 'file') { |
| 107 | + // do work |
| 108 | + machine.send('TEST_RUN') |
| 109 | + } |
| 110 | + }) |
| 111 | + }, |
| 112 | + // open a file |
| 113 | + [COMMANDS.OPEN_FILE]: async (relativeFilePath: string) => { |
| 114 | + console.log(`OPEN_FILE ${JSON.stringify(relativeFilePath)}`) |
| 115 | + try { |
| 116 | + const workspaceRoot = vscode.workspace.rootPath |
| 117 | + if (!workspaceRoot) { |
| 118 | + throw new Error('No workspace root path') |
| 119 | + } |
| 120 | + const absoluteFilePath = join(workspaceRoot, relativeFilePath) |
| 121 | + const doc = await vscode.workspace.openTextDocument(absoluteFilePath) |
| 122 | + await vscode.window.showTextDocument(doc, vscode.ViewColumn.One) |
| 123 | + // there are times when intialization leave the panel behind any files opened |
| 124 | + // ensure the panel is redrawn on the right side first |
| 125 | + webview.createOrShow(vscode.ViewColumn.Two) |
| 126 | + } catch (error) { |
| 127 | + console.log(`Failed to open file ${relativeFilePath}`, error) |
| 128 | + } |
| 129 | + }, |
| 130 | + // send messages to webview |
| 131 | + [COMMANDS.SEND_STATE]: (payload: {data: any; state: any}) => { |
| 132 | + webview.postMessage({type: 'SET_STATE', payload}) |
| 133 | + }, |
| 134 | + [COMMANDS.SEND_DATA]: (payload: {data: any}) => { |
| 135 | + webview.postMessage({type: 'SET_DATA', payload}) |
| 136 | + }, |
| 137 | + [COMMANDS.RECEIVE_ACTION]: (action: string | CR.Action) => { |
| 138 | + // send received actions from web-app into state machine |
| 139 | + machine.send(action) |
| 140 | + }, |
| 141 | + [COMMANDS.RUN_TEST]: () => { |
| 142 | + runTest({ |
| 143 | + onSuccess: () => machine.send('TEST_PASS'), |
| 144 | + onFail: () => machine.send('TEST_FAIL'), |
| 145 | + }) |
| 146 | + }, |
| 147 | + [COMMANDS.TEST_PASS]: () => { |
| 148 | + vscode.window.showInformationMessage('PASS') |
| 149 | + }, |
| 150 | + [COMMANDS.TEST_FAIL]: () => { |
| 151 | + vscode.window.showWarningMessage('FAIL') |
| 152 | + }, |
| 153 | + } |
149 | 154 | } |
0 commit comments