@@ -2,126 +2,16 @@ import * as vscode from "vscode";
2
2
// Allow using JSX within this file by overriding our own createElement function
3
3
import React from "../utils/FakeReact" ;
4
4
5
- import Messages , {
6
- MessageType ,
7
- MessageTypeNames ,
8
- sendToFrontend ,
9
- } from "../utils/messages" ;
5
+ import { MessageType , sendToFrontend } from "../utils/messages" ;
10
6
import { LANGUAGES } from "../utils/languages" ;
11
7
import { setWebviewContent } from "../utils/webview" ;
12
8
import config from "../utils/config" ;
13
- import { Editor } from "../utils/editor" ;
14
9
import { FRONTEND_ELEMENT_ID } from "../constants" ;
15
- import { client , SOURCE_ACADEMY_ICON_URI } from "../extension" ;
16
10
import _ from "lodash" ;
17
- import { treeDataProvider } from "../treeview" ;
11
+ import { MessageHandler } from "../utils/messageHandler" ;
12
+ import { SOURCE_ACADEMY_ICON_URI } from "../extension" ;
18
13
19
- let panel : vscode . WebviewPanel | null = null ;
20
- // This needs to be a reference to active
21
- // TODO: Fix this ugly code!
22
- export let activeEditor : Editor | null = null ;
23
-
24
- const messageQueue : MessageType [ ] = [ ] ;
25
- let handling = false ;
26
-
27
- // TODO: Remove panel and handling message logic out of the commands/ directory
28
-
29
- async function handleMessage (
30
- context : vscode . ExtensionContext ,
31
- message : MessageType ,
32
- ) {
33
- messageQueue . push ( message ) ;
34
- if ( handling ) {
35
- return ;
36
- }
37
- handling = true ;
38
-
39
- while ( messageQueue . length > 0 ) {
40
- const message = messageQueue . shift ( ) ! ;
41
- console . log ( `${ Date . now ( ) } Beginning handleMessage: ${ message . type } ` ) ;
42
- switch ( message . type ) {
43
- case MessageTypeNames . ExtensionPing :
44
- sendToFrontend ( panel , Messages . ExtensionPong ( null ) ) ;
45
- break ;
46
- case MessageTypeNames . NewEditor :
47
- activeEditor = await Editor . create (
48
- message . workspaceLocation ,
49
- message . assessmentName ,
50
- message . questionId ,
51
- message . prepend ,
52
- message . initialCode ,
53
- ) ;
54
- activeEditor . uri ;
55
- const info = context . globalState . get ( "info" ) ?? { } ;
56
- if ( activeEditor . uri ) {
57
- // TODO: Write our own wrapper to set nested keys easily, removing lodash
58
- // @ts -ignore
59
- _ . set ( info , `["${ activeEditor . uri } "].chapter` , message . chapter ?? 1 ) ;
60
- // TODO: message.prepend can be undefined in runtime, investigate
61
- const nPrependLines =
62
- message . prepend && message . prepend !== ""
63
- ? message . prepend . split ( "\n" ) . length + 2 // account for start/end markers
64
- : 0 ;
65
- _ . set ( info , `["${ activeEditor . uri } "].prepend` , nPrependLines ) ;
66
- context . globalState . update ( "info" , info ) ;
67
- client . sendRequest ( "source/publishInfo" , info ) ;
68
- }
69
-
70
- panel ?. reveal ( vscode . ViewColumn . Two ) ;
71
- console . log (
72
- `EXTENSION: NewEditor: activeEditor set to ${ activeEditor . assessmentName } _${ activeEditor . questionId } ` ,
73
- ) ;
74
- activeEditor . onChange ( ( editor ) => {
75
- const workspaceLocation = editor . workspaceLocation ;
76
- const code = editor . getText ( ) ;
77
- if ( ! code ) {
78
- return ;
79
- }
80
- if ( editor !== activeEditor ) {
81
- console . log (
82
- `EXTENSION: Editor ${ editor . assessmentName } _${ editor . questionId } is no longer active, skipping onChange` ,
83
- ) ;
84
- }
85
- const message = Messages . Text ( workspaceLocation , code ) ;
86
- console . log ( `Sending message: ${ JSON . stringify ( message ) } ` ) ;
87
- sendToFrontend ( panel , message ) ;
88
- } ) ;
89
- break ;
90
- case MessageTypeNames . ChangeChapter : {
91
- const info = context . globalState . get ( "info" ) ?? { } ;
92
- const uri = vscode . Uri . file ( Editor . getFilePath ( message . assessmentName , message . questionId ) ) . toString ( ) ;
93
-
94
- _ . set ( info , `["${ uri } "].chapter` , message . chapter ?? 1 ) ;
95
- context . globalState . update ( "info" , info ) ;
96
- client . sendRequest ( "source/publishInfo" , info ) ;
97
-
98
- if ( message . variant !== "default" ) {
99
- vscode . window . showInformationMessage ( `The Language Server does not support any variants, the
100
- Language Server will use Source §${ message . chapter } , but it is not guaranteed to be accurate.` )
101
- }
102
-
103
-
104
- break ;
105
- }
106
- // case MessageTypeNames.Text:
107
- // if (!activeEditor) {
108
- // console.log("ERROR: activeEditor is not set");
109
- // break;
110
- // }
111
- // activeEditor.replace(message.code, "Text");
112
- // break;
113
- case MessageTypeNames . NotifyAssessmentsOverview :
114
- const { assessmentOverviews, courseId } = message ;
115
- context . globalState . update ( "assessmentOverviews" , assessmentOverviews ) ;
116
- context . globalState . update ( "courseId" , courseId ) ;
117
- treeDataProvider . refresh ( ) ;
118
- break ;
119
- }
120
- console . log ( `${ Date . now ( ) } Finish handleMessage: ${ message . type } ` ) ;
121
- }
122
-
123
- handling = false ;
124
- }
14
+ let messageHandler = MessageHandler . getInstance ( ) ;
125
15
126
16
export async function showPanel (
127
17
context : vscode . ExtensionContext ,
@@ -135,7 +25,7 @@ export async function showPanel(
135
25
// Get a reference to the active editor (before the focus is switched to our newly created webview)
136
26
// firstEditor = vscode.window.activeTextEditor!;
137
27
138
- panel = vscode . window . createWebviewPanel (
28
+ messageHandler . panel = vscode . window . createWebviewPanel (
139
29
"source-academy-panel" ,
140
30
"Source Academy" ,
141
31
vscode . ViewColumn . Beside ,
@@ -145,18 +35,17 @@ export async function showPanel(
145
35
} ,
146
36
) ;
147
37
148
- panel . webview . onDidReceiveMessage (
149
- ( message : MessageType ) => handleMessage ( context , message ) ,
38
+ messageHandler . panel . webview . onDidReceiveMessage (
39
+ ( message : MessageType ) => messageHandler . handleMessage ( context , message ) ,
150
40
undefined ,
151
41
context . subscriptions ,
152
42
) ;
153
43
154
44
const iframeUrl = new URL ( route ?? "/playground" , config . frontendBaseUrl )
155
45
. href ;
156
46
157
- // equivalent to panel.webview.html = ...
158
47
setWebviewContent (
159
- panel ,
48
+ messageHandler . panel ,
160
49
context ,
161
50
// NOTE: This is not React code, but our FakeReact!
162
51
< div
@@ -176,16 +65,16 @@ export async function showPanel(
176
65
</ div > ,
177
66
) ;
178
67
179
- panel . iconPath = SOURCE_ACADEMY_ICON_URI ;
68
+ messageHandler . panel . iconPath = SOURCE_ACADEMY_ICON_URI ;
180
69
}
181
70
182
- // TODO: Move this to a util file
183
71
export async function sendToFrontendWrapped ( message : MessageType ) {
72
+ sendToFrontend ( messageHandler . panel , message ) ;
184
73
// TODO: This returning of status code shouldn't be necessary after refactor
185
- if ( ! panel ) {
74
+ if ( ! messageHandler . panel ) {
186
75
console . error ( "ERROR: panel is not set" ) ;
187
76
return false ;
188
77
}
189
- sendToFrontend ( panel , message ) ;
78
+ sendToFrontend ( messageHandler . panel , message ) ;
190
79
return true ;
191
80
}
0 commit comments