Skip to content

Commit aff6f5f

Browse files
committed
more message util fix
1 parent 7d5ab30 commit aff6f5f

File tree

2 files changed

+56
-21
lines changed

2 files changed

+56
-21
lines changed

src/commons/application/Application.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React from 'react';
22
import { useDispatch } from 'react-redux';
33
import { Outlet } from 'react-router-dom';
4-
import Messages, { MessageType, sendToWebview } from 'src/features/vscode/messages';
4+
import Messages, { MessageType, MessageTypeNames, sendToWebview } from 'src/features/vscode/messages';
55

66
import NavigationBar from '../navigationBar/NavigationBar';
77
import Constants from '../utils/Constants';
@@ -82,7 +82,7 @@ const Application: React.FC = () => {
8282
return true;
8383
};
8484

85-
const message = Messages.WebviewStarted(null);
85+
const message = Messages.ExtensionPing();
8686
sendToWebview(message);
8787

8888
window.addEventListener('message', event => {
@@ -91,9 +91,9 @@ const Application: React.FC = () => {
9191
if (!event.origin.startsWith('vscode-webview://')) {
9292
return;
9393
}
94-
// console.log(`FRONTEND: Message from ${event.origin}: ${JSON.stringify(message)}`);
94+
console.log(`FRONTEND: Message from ${event.origin}: ${JSON.stringify(message)}`);
9595
switch (message.type) {
96-
case 'WebviewStarted':
96+
case MessageTypeNames.ExtensionPong:
9797
console.log('Received WebviewStarted message, will set vsc');
9898
dispatch(VscodeActions.setVscode());
9999

@@ -103,7 +103,7 @@ const Application: React.FC = () => {
103103
dispatch(SessionActions.setTokens({accessToken: token.accessToken, refreshToken: token.refreshToken}));
104104
}
105105
break;
106-
case 'Text':
106+
case MessageTypeNames.Text:
107107
const code = message.code;
108108
console.log(`FRONTEND: TextMessage: ${code}`);
109109
// TODO: Don't change ace editor directly

src/features/vscode/messages.ts

Lines changed: 51 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,36 @@
1-
// This file is copied from https://github.com/source-academy/sa-vscode/blob/main/src/utils/messages.ts
1+
// This file is originally created in https://github.com/source-academy/sa-vscode/blob/main/src/utils/messages.ts
2+
// It also needs to be copied to source-academy/frontend:src/features/vscode/messages.ts
3+
// Ideally it is split into multiple files, but for ease of copying, it is kept as one file.
4+
5+
// ================================================================================
6+
// Message type definitions
7+
// ================================================================================
8+
const Messages = createMessages({
9+
/** Sent from the iframe to the extension */
10+
ExtensionPing: () => ({}),
11+
/** Sent from the extension to the iframe */
12+
ExtensionPong: (token: string | null) => ({ token }),
13+
IsVsc: () => ({}),
14+
NewEditor: (assessmentName: string, questionId: number, code: string) => ({
15+
assessmentName,
16+
questionId,
17+
code,
18+
}),
19+
Text: (code: string) => ({ code }),
20+
});
21+
22+
export default Messages;
23+
24+
// ================================================================================
25+
// Code for type generation
26+
// ================================================================================
27+
28+
// Define BaseMessage to be the base type for all messages, such that all messages have a type field
229
type BaseMessage<T extends string, P extends object> = {
330
type: T;
431
} & P;
532

33+
// A helper function to create messages dynamically from schema (hoisted!)
634
function createMessages<T extends Record<string, (...args: any[]) => object>>(
735
creators: T,
836
): {
@@ -21,27 +49,34 @@ function createMessages<T extends Record<string, (...args: any[]) => object>>(
2149
) as any;
2250
}
2351

24-
const Messages = createMessages({
25-
WebviewStarted: (token: string | null) => ({ token }),
26-
IsVsc: () => ({}),
27-
NewEditor: (assessmentName: string, questionId: number, code: string) => ({
28-
assessmentName,
29-
questionId,
30-
code,
31-
}),
32-
Text: (code: string) => ({ code }),
33-
});
34-
35-
export default Messages;
36-
37-
// Define MessageTypes to map each key in Messages to its specific message type
38-
export type MessageTypes = {
52+
// Define MessageTypes as a map of each key in Messages to its specific message type
53+
type MessageTypes = {
3954
[K in keyof typeof Messages]: ReturnType<(typeof Messages)[K]>;
4055
};
4156

4257
// Define MessageType as a union of all message types
4358
export type MessageType = MessageTypes[keyof MessageTypes];
4459

60+
// Also define MessageTypeNames as an "enum" to avoid hardcoding strings
61+
export const MessageTypeNames = (() =>
62+
({
63+
...Object.keys(Messages)
64+
.filter((k) => isNaN(Number(k)))
65+
.reduce(
66+
(acc, cur) => ({
67+
...acc,
68+
[cur]: cur,
69+
}),
70+
{},
71+
),
72+
}) as {
73+
[k in keyof typeof Messages]: k;
74+
})();
75+
76+
// ================================================================================
77+
// Wrapper functions
78+
// ================================================================================
79+
4580
export const FRONTEND_ELEMENT_ID = "frontend";
4681

4782
export function sendToWebview(message: MessageType) {

0 commit comments

Comments
 (0)