Skip to content

Commit 69d7bb2

Browse files
committed
Refactor message handling
1 parent 6aca711 commit 69d7bb2

File tree

2 files changed

+159
-135
lines changed

2 files changed

+159
-135
lines changed

src/commands/showPanel.tsx

Lines changed: 1 addition & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { FRONTEND_ELEMENT_ID } from "../constants";
1616
import { client } from "../extension";
1717
import _ from "lodash";
1818
import { McqPanelWithLogging as McqPanel } from "../webview/components/McqPanel";
19+
import { handleMessage } from "../utils/messageHandler";
1920

2021
let mcqPanel: vscode.WebviewPanel | null = null;
2122

@@ -24,141 +25,6 @@ let panel: vscode.WebviewPanel | null = null;
2425
// TODO: Fix this ugly code!
2526
export let activeEditor: Editor | null = null;
2627

27-
const messageQueue: MessageType[] = [];
28-
let handling = false;
29-
30-
// TODO: Remove panel and handling message logic out of the commands/ directory
31-
32-
async function handleMessage(
33-
context: vscode.ExtensionContext,
34-
message: MessageType,
35-
) {
36-
messageQueue.push(message);
37-
if (handling) {
38-
return;
39-
}
40-
handling = true;
41-
42-
while (messageQueue.length > 0) {
43-
const message = messageQueue.shift()!;
44-
console.log(`${Date.now()} Beginning handleMessage: ${message.type}`);
45-
switch (message.type) {
46-
case MessageTypeNames.ExtensionPing:
47-
sendToFrontend(panel, Messages.ExtensionPong(null));
48-
break;
49-
case MessageTypeNames.MCQQuestion: {
50-
if (mcqPanel === null) {
51-
mcqPanel = vscode.window.createWebviewPanel(
52-
"mcq-question-panel",
53-
`Question ${message.questionId + 1}`,
54-
vscode.ViewColumn.One,
55-
{ enableScripts: true, retainContextWhenHidden: true },
56-
);
57-
58-
mcqPanel.onDidDispose(() => {
59-
mcqPanel = null;
60-
});
61-
}
62-
mcqPanel.title = `Question ${message.questionId + 1}`;
63-
mcqPanel.iconPath = vscode.Uri.joinPath(
64-
context.extensionUri,
65-
"assets",
66-
"icon.png",
67-
);
68-
let activePanel = await McqPanel({
69-
data: {
70-
assessmentName: message.assessmentName ?? "",
71-
questionId: message.questionId,
72-
question: message.question,
73-
choices: message.options,
74-
workspaceLocation: message.workspaceLocation ?? "assessment",
75-
},
76-
});
77-
setWebviewContent(
78-
mcqPanel,
79-
context,
80-
<div
81-
// @ts-ignore: Our FakeReact doesn't modify the style attribute
82-
style="width: 100%; height: calc(100vh - 10px)"
83-
id="mcq-panel"
84-
>
85-
{ReactDOMServer.renderToString(activePanel)}
86-
</div>,
87-
);
88-
mcqPanel.reveal(vscode.ViewColumn.One);
89-
90-
break;
91-
}
92-
93-
case MessageTypeNames.NewEditor:
94-
// console.log(message.questionType + " questionType \n");
95-
// if (message.questionType == "mcq") {
96-
// break;
97-
// }
98-
activeEditor = await Editor.create(
99-
message.workspaceLocation,
100-
message.assessmentName,
101-
message.questionId,
102-
message.prepend,
103-
message.initialCode,
104-
);
105-
activeEditor.uri;
106-
const info = context.globalState.get("info") ?? {};
107-
if (activeEditor.uri) {
108-
// TODO: Write our own wrapper to set nested keys easily, removing lodash
109-
// @ts-ignore
110-
_.set(info, `["${activeEditor.uri}"].chapter`, message.chapter ?? 1);
111-
// TODO: message.prepend can be undefined in runtime, investigate
112-
const nPrependLines =
113-
message.prepend && message.prepend !== ""
114-
? message.prepend.split("\n").length + 2 // account for start/end markers
115-
: 0;
116-
_.set(info, `["${activeEditor.uri}"].prepend`, nPrependLines);
117-
context.globalState.update("info", info);
118-
client.sendRequest("source/publishInfo", info);
119-
}
120-
121-
panel?.reveal(vscode.ViewColumn.Two);
122-
console.log(
123-
`EXTENSION: NewEditor: activeEditor set to ${activeEditor.assessmentName}_${activeEditor.questionId}`,
124-
);
125-
126-
activeEditor.onChange((editor) => {
127-
const workspaceLocation = editor.workspaceLocation;
128-
const code = editor.getText();
129-
if (!code) {
130-
return;
131-
}
132-
if (editor !== activeEditor) {
133-
console.log(
134-
`EXTENSION: Editor ${editor.assessmentName}_${editor.questionId}_${editor.assessmentType} is no longer active, skipping onChange`,
135-
);
136-
}
137-
if (activeEditor) {
138-
console.log("activeEditor keys and values:");
139-
Object.entries(activeEditor).forEach(([key, value]) => {
140-
console.log(`${key}:`, value);
141-
});
142-
}
143-
const message = Messages.Text(workspaceLocation, code);
144-
console.log(`Sending message: ${JSON.stringify(message)}`);
145-
sendToFrontend(panel, message);
146-
});
147-
break;
148-
// case MessageTypeNames.Text:
149-
// if (!activeEditor) {
150-
// console.log("ERROR: activeEditor is not set");
151-
// break;
152-
// }
153-
// activeEditor.replace(message.code, "Text");
154-
// break;
155-
}
156-
console.log(`${Date.now()} Finish handleMessage: ${message.type}`);
157-
}
158-
159-
handling = false;
160-
}
161-
16228
export async function showPanel(context: vscode.ExtensionContext) {
16329
let language: string | undefined = context.workspaceState.get("language");
16430
if (!language) {

src/utils/messageHandler.tsx

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
import * as vscode from "vscode";
2+
// Allow using JSX within this file by overriding our own createElement function
3+
import React from "./FakeReact";
4+
import ReactDOMServer from "react-dom/server";
5+
6+
import Messages, {
7+
MessageType,
8+
MessageTypeNames,
9+
sendToFrontend,
10+
} from "./messages";
11+
import { setWebviewContent } from "./webview";
12+
import { Editor } from "./editor";
13+
import { client } from "../extension";
14+
import _ from "lodash";
15+
import { McqPanelWithLogging as McqPanel } from "../webview/components/McqPanel";
16+
17+
let mcqPanel: vscode.WebviewPanel | null = null;
18+
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+
export async function handleMessage(
28+
context: vscode.ExtensionContext,
29+
message: MessageType,
30+
) {
31+
messageQueue.push(message);
32+
if (handling) {
33+
return;
34+
}
35+
handling = true;
36+
37+
while (messageQueue.length > 0) {
38+
const message = messageQueue.shift()!;
39+
console.log(`${Date.now()} Beginning handleMessage: ${message.type}`);
40+
switch (message.type) {
41+
case MessageTypeNames.ExtensionPing:
42+
sendToFrontend(panel, Messages.ExtensionPong(null));
43+
break;
44+
case MessageTypeNames.MCQQuestion: {
45+
if (mcqPanel === null) {
46+
mcqPanel = vscode.window.createWebviewPanel(
47+
"mcq-question-panel",
48+
`Question ${message.questionId + 1}`,
49+
vscode.ViewColumn.One,
50+
{ enableScripts: true, retainContextWhenHidden: true },
51+
);
52+
53+
mcqPanel.onDidDispose(() => {
54+
mcqPanel = null;
55+
});
56+
}
57+
mcqPanel.title = `Question ${message.questionId + 1}`;
58+
mcqPanel.iconPath = vscode.Uri.joinPath(
59+
context.extensionUri,
60+
"assets",
61+
"icon.png",
62+
);
63+
let activePanel = await McqPanel({
64+
data: {
65+
assessmentName: message.assessmentName ?? "",
66+
questionId: message.questionId,
67+
question: message.question,
68+
choices: message.options,
69+
workspaceLocation: message.workspaceLocation ?? "assessment",
70+
},
71+
});
72+
setWebviewContent(
73+
mcqPanel,
74+
context,
75+
<div
76+
// @ts-ignore: Our FakeReact doesn't modify the style attribute
77+
style="width: 100%; height: calc(100vh - 10px)"
78+
id="mcq-panel"
79+
>
80+
{ReactDOMServer.renderToString(activePanel)}
81+
</div>,
82+
);
83+
mcqPanel.reveal(vscode.ViewColumn.One);
84+
85+
break;
86+
}
87+
case MessageTypeNames.MCQAnswer:
88+
console.log(`Received MCQ answer: ${message.choice}`);
89+
sendToFrontend(panel, message);
90+
break;
91+
case MessageTypeNames.NewEditor:
92+
// console.log(message.questionType + " questionType \n");
93+
// if (message.questionType == "mcq") {
94+
// break;
95+
// }
96+
activeEditor = await Editor.create(
97+
message.workspaceLocation,
98+
message.assessmentName,
99+
message.questionId,
100+
message.prepend,
101+
message.initialCode,
102+
);
103+
activeEditor.uri;
104+
const info = context.globalState.get("info") ?? {};
105+
if (activeEditor.uri) {
106+
// TODO: Write our own wrapper to set nested keys easily, removing lodash
107+
// @ts-ignore
108+
_.set(info, `["${activeEditor.uri}"].chapter`, message.chapter ?? 1);
109+
// TODO: message.prepend can be undefined in runtime, investigate
110+
const nPrependLines =
111+
message.prepend && message.prepend !== ""
112+
? message.prepend.split("\n").length + 2 // account for start/end markers
113+
: 0;
114+
_.set(info, `["${activeEditor.uri}"].prepend`, nPrependLines);
115+
context.globalState.update("info", info);
116+
client.sendRequest("source/publishInfo", info);
117+
}
118+
119+
panel?.reveal(vscode.ViewColumn.Two);
120+
console.log(
121+
`EXTENSION: NewEditor: activeEditor set to ${activeEditor.assessmentName}_${activeEditor.questionId}`,
122+
);
123+
124+
activeEditor.onChange((editor) => {
125+
const workspaceLocation = editor.workspaceLocation;
126+
const code = editor.getText();
127+
if (!code) {
128+
return;
129+
}
130+
if (editor !== activeEditor) {
131+
console.log(
132+
`EXTENSION: Editor ${editor.assessmentName}_${editor.questionId}_${editor.assessmentType} is no longer active, skipping onChange`,
133+
);
134+
}
135+
if (activeEditor) {
136+
console.log("activeEditor keys and values:");
137+
Object.entries(activeEditor).forEach(([key, value]) => {
138+
console.log(`${key}:`, value);
139+
});
140+
}
141+
const message = Messages.Text(workspaceLocation, code);
142+
console.log(`Sending message: ${JSON.stringify(message)}`);
143+
sendToFrontend(panel, message);
144+
});
145+
break;
146+
// case MessageTypeNames.Text:
147+
// if (!activeEditor) {
148+
// console.log("ERROR: activeEditor is not set");
149+
// break;
150+
// }
151+
// activeEditor.replace(message.code, "Text");
152+
// break;
153+
}
154+
console.log(`${Date.now()} Finish handleMessage: ${message.type}`);
155+
}
156+
157+
handling = false;
158+
}

0 commit comments

Comments
 (0)