Skip to content

Commit c3134d8

Browse files
committed
Merge branch 'assessment-redirect-to-game' of github.com:source-academy/frontend into assessment-redirect-to-game
2 parents 1c29226 + bfa84b1 commit c3134d8

File tree

33 files changed

+338
-713
lines changed

33 files changed

+338
-713
lines changed

.gitignore

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ terraform*
2424
.env.test.local
2525
.env.production.local
2626
.idea/
27-
.vscode/
28-
cadet-frontend.iml
2927

3028
npm-debug.log*
3129
.eslintcache
@@ -50,3 +48,6 @@ yarn-error.log
5048

5149
#!.yarn/cache
5250
.pnp.*
51+
52+
# We use .node-version
53+
/.tool-versions

.tool-versions

Lines changed: 0 additions & 1 deletion
This file was deleted.

.vscode/settings.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"editor.defaultFormatter": "esbenp.prettier-vscode",
3+
"eslint.useFlatConfig": true,
4+
"files.insertFinalNewline": true,
5+
"liveServer.settings.file": "/index.html",
6+
"liveServer.settings.NoBrowser": true,
7+
"liveServer.settings.root": "/build"
8+
}

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@ The Source Academy (<https://sourceacademy.org/>) is an immersive online experie
2222

2323
1. Install the version of Node.js as specified in the `.node-version` file
2424

25-
1. Install Python (known working versions: `2.7`, `3.8`, `3.9`, `3.10`) – **Note: Python `3.11` does not work**
26-
2725
1. Clone this repository and navigate to it using your command line
2826

29-
1. Install the version of `yarn` as specified in `package.json`, `packageManager`. On macos, you may need to run `corepack enable`.
27+
1. Install the version of `yarn` as specified in `package.json`, `packageManager`.
28+
29+
> We recommend using `corepack` to manage the version of `yarn`, you may simply run `corepack enable` to complete this step.
3030
3131
1. Run `yarn install` to install dependencies.
3232

eslint.config.js renamed to eslint.config.mjs

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,16 @@
11
// @ts-check
22

3-
// Todo: Use ES module
4-
const eslint = require('@eslint/js');
5-
const tseslint = require('typescript-eslint');
6-
const reactRefresh = require('eslint-plugin-react-refresh');
3+
// import eslint from '@eslint/js';
4+
import { config, configs } from 'typescript-eslint';
5+
import reactPlugin from 'eslint-plugin-react';
6+
import reactHooksPlugin from 'eslint-plugin-react-hooks';
7+
import simpleImportSort from 'eslint-plugin-simple-import-sort'
8+
// import reactRefresh from 'eslint-plugin-react-refresh';
79

8-
const FlatCompat = require('@eslint/eslintrc').FlatCompat;
9-
const compat = new FlatCompat({
10-
baseDirectory: `${__dirname}`
11-
});
12-
13-
module.exports = tseslint.config(
14-
{ ignores: ['eslint.config.js'] },
10+
export default config(
11+
{ ignores: ['eslint.config.mjs'] },
1512
// eslint.configs.recommended,
16-
...tseslint.configs.recommended,
13+
...configs.recommended,
1714
// TODO: Enable when ready
1815
// {
1916
// plugins: {
@@ -23,14 +20,15 @@ module.exports = tseslint.config(
2320
// 'react-refresh/only-export-components': 'warn'
2421
// }
2522
// },
26-
...compat.config({
27-
extends: [
28-
'plugin:react-hooks/recommended'
29-
// "plugin:react/recommended",
30-
// "plugin:react/jsx-runtime"
31-
],
32-
plugins: ['simple-import-sort'],
23+
{
24+
files: ['**/*.ts*'],
25+
plugins: {
26+
'react-hooks': reactHooksPlugin,
27+
'react': reactPlugin,
28+
'simple-import-sort': simpleImportSort
29+
},
3330
rules: {
31+
...reactHooksPlugin.configs['recommended-latest'].rules,
3432
'no-restricted-imports': [
3533
'error',
3634
{
@@ -73,5 +71,5 @@ module.exports = tseslint.config(
7371
],
7472
'simple-import-sort/imports': 'error'
7573
}
76-
})
74+
}
7775
);

package.json

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
"array-move": "^4.0.0",
4949
"browserfs": "^1.4.3",
5050
"classnames": "^2.3.2",
51-
"conductor": "https://github.com/source-academy/conductor.git#0.2.0",
51+
"conductor": "https://github.com/source-academy/conductor.git#0.2.1",
5252
"dayjs": "^1.11.13",
5353
"dompurify": "^3.2.4",
5454
"flexboxgrid": "^6.3.1",
@@ -58,7 +58,7 @@
5858
"i18next-browser-languagedetector": "^8.0.0",
5959
"java-slang": "^1.0.13",
6060
"js-cookie": "^3.0.5",
61-
"js-slang": "^1.0.80",
61+
"js-slang": "^1.0.81",
6262
"js-yaml": "^4.1.0",
6363
"konva": "^9.2.0",
6464
"language-directory": "https://github.com/source-academy/language-directory.git",
@@ -141,7 +141,7 @@
141141
"cross-env": "^7.0.3",
142142
"eslint": "^9.9.0",
143143
"eslint-plugin-react": "^7.35.0",
144-
"eslint-plugin-react-hooks": "5.1.0-canary-cb151849e1-20240424",
144+
"eslint-plugin-react-hooks": "^5.2.0",
145145
"eslint-plugin-react-refresh": "^0.4.9",
146146
"eslint-plugin-simple-import-sort": "^12.1.1",
147147
"https-browserify": "^1.0.0",
@@ -167,9 +167,6 @@
167167
"url": "^0.11.1",
168168
"webpack-bundle-analyzer": "^4.9.0"
169169
},
170-
"resolutions": {
171-
"gl": "^8.0.2"
172-
},
173170
"browserslist": {
174171
"production": [
175172
"Firefox ESR",

src/commons/__tests__/Markdown.tsx

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,30 +22,18 @@ test('Markdown page renders correct Source information', () => {
2222
const source1Default = <Markdown {...mockProps(Chapter.SOURCE_1, Variant.DEFAULT)} />;
2323
expect(source1Default.props.content).toContain('Source \xa71');
2424

25-
const source1Lazy = <Markdown {...mockProps(Chapter.SOURCE_1, Variant.LAZY)} />;
26-
expect(source1Lazy.props.content).toContain('Source \xa71 Lazy');
27-
2825
const source1Wasm = <Markdown {...mockProps(Chapter.SOURCE_1, Variant.WASM)} />;
2926
expect(source1Wasm.props.content).toContain('Source \xa71 WebAssembly');
3027

3128
const source2Default = <Markdown {...mockProps(Chapter.SOURCE_2, Variant.DEFAULT)} />;
3229
expect(source2Default.props.content).toContain('Source \xa72');
3330

34-
const source2Lazy = <Markdown {...mockProps(Chapter.SOURCE_2, Variant.LAZY)} />;
35-
expect(source2Lazy.props.content).toContain('Source \xa72 Lazy');
36-
3731
const source3Default = <Markdown {...mockProps(Chapter.SOURCE_3, Variant.DEFAULT)} />;
3832
expect(source3Default.props.content).toContain('Source \xa73');
3933

40-
const source3NonDet = <Markdown {...mockProps(Chapter.SOURCE_3, Variant.NON_DET)} />;
41-
expect(source3NonDet.props.content).toContain('Source \xa73 Non-Det');
42-
4334
const source3Concurrent = <Markdown {...mockProps(Chapter.SOURCE_3, Variant.CONCURRENT)} />;
4435
expect(source3Concurrent.props.content).toContain('Source \xa73 Concurrent');
4536

4637
const source4Default = <Markdown {...mockProps(Chapter.SOURCE_4, Variant.DEFAULT)} />;
4738
expect(source4Default.props.content).toContain('Source \xa74');
48-
49-
const source4GPU = <Markdown {...mockProps(Chapter.SOURCE_4, Variant.GPU)} />;
50-
expect(source4GPU.props.content).toContain('Source \xa74 GPU');
5139
});

src/commons/application/Application.tsx

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

510
import NavigationBar from '../navigationBar/NavigationBar';
611
import Constants from '../utils/Constants';
712
import { useLocalStorageState, useSession } from '../utils/Hooks';
13+
import WorkspaceActions from '../workspace/WorkspaceActions';
814
import { defaultWorkspaceSettings, WorkspaceSettingsContext } from '../WorkspaceSettingsContext';
915
import SessionActions from './actions/SessionActions';
16+
import VscodeActions from './actions/VscodeActions';
1017

1118
const Application: React.FC = () => {
1219
const dispatch = useDispatch();
@@ -70,6 +77,62 @@ const Application: React.FC = () => {
7077
};
7178
}, [isPWA, isMobile]);
7279

80+
// Effect to handle messages from VS Code
81+
React.useEffect(() => {
82+
if (!window.confirm) {
83+
// Polyfill confirm() to instead show as VS Code notification
84+
// TODO: Pass text as a new Message to the webview
85+
window.confirm = text => {
86+
console.log(`Confirmation automatically accepted: ${text ?? 'No text provided'}`);
87+
return true;
88+
};
89+
}
90+
91+
const message = Messages.ExtensionPing();
92+
sendToWebview(message);
93+
94+
window.addEventListener('message', event => {
95+
const message: MessageType = event.data;
96+
// Only accept messages from the vscode webview
97+
if (!event.origin.startsWith('vscode-webview://')) {
98+
return;
99+
}
100+
// console.log(`FRONTEND: Message from ${event.origin}: ${JSON.stringify(message)}`);
101+
switch (message.type) {
102+
case MessageTypeNames.ExtensionPong:
103+
console.log('Received WebviewStarted message, will set vsc');
104+
dispatch(VscodeActions.setVscode());
105+
106+
if (message.token) {
107+
const token = JSON.parse(message.token.trim());
108+
console.log(`FRONTEND: WebviewStarted: ${token}`);
109+
dispatch(
110+
SessionActions.setTokens({
111+
accessToken: token.accessToken,
112+
refreshToken: token.refreshToken
113+
})
114+
);
115+
dispatch(SessionActions.fetchUserAndCourse());
116+
}
117+
break;
118+
case MessageTypeNames.Text:
119+
const code = message.code;
120+
console.log(`FRONTEND: TextMessage: ${code}`);
121+
// TODO: Don't change ace editor directly
122+
// const elements = document.getElementsByClassName('react-ace');
123+
// if (elements.length === 0) {
124+
// return;
125+
// }
126+
// // @ts-expect-error: ace is not available at compile time
127+
// const editor = ace.edit(elements[0]);
128+
// editor.setValue(code);
129+
dispatch(WorkspaceActions.updateEditorValue('assessment', 0, code));
130+
break;
131+
}
132+
});
133+
// eslint-disable-next-line react-hooks/exhaustive-deps
134+
}, []);
135+
73136
return (
74137
<WorkspaceSettingsContext.Provider value={[workspaceSettings, setWorkspaceSettings]}>
75138
<div className="Application">

src/commons/application/ApplicationTypes.ts

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
import { RouterState } from './types/CommonsTypes';
2222
import { ExternalLibraryName } from './types/ExternalTypes';
2323
import { SessionState } from './types/SessionTypes';
24+
import { VscodeState as VscodeState } from './types/VscodeTypes';
2425

2526
export type OverallState = {
2627
readonly router: RouterState;
@@ -33,6 +34,7 @@ export type OverallState = {
3334
readonly featureFlags: FeatureFlagsState;
3435
readonly fileSystem: FileSystemState;
3536
readonly sideContent: SideContentManagerState;
37+
readonly vscode: VscodeState;
3638
};
3739

3840
export type Story = {
@@ -158,10 +160,7 @@ type LanguageFeatures = Partial<{
158160
const variantDisplay: Map<Variant, string> = new Map([
159161
[Variant.TYPED, 'Typed'],
160162
[Variant.WASM, 'WebAssembly'],
161-
[Variant.NON_DET, 'Non-Det'],
162163
[Variant.CONCURRENT, 'Concurrent'],
163-
[Variant.LAZY, 'Lazy'],
164-
[Variant.GPU, 'GPU'],
165164
[Variant.NATIVE, 'Native'],
166165
[Variant.EXPLICIT_CONTROL, 'Explicit-Control']
167166
]);
@@ -259,23 +258,19 @@ const sourceSubLanguages: Array<Pick<SALanguage, 'chapter' | 'variant'>> = [
259258
{ chapter: Chapter.SOURCE_1, variant: Variant.DEFAULT },
260259
{ chapter: Chapter.SOURCE_1, variant: Variant.TYPED },
261260
{ chapter: Chapter.SOURCE_1, variant: Variant.WASM },
262-
{ chapter: Chapter.SOURCE_1, variant: Variant.LAZY },
263261
{ chapter: Chapter.SOURCE_1, variant: Variant.NATIVE },
264262

265263
{ chapter: Chapter.SOURCE_2, variant: Variant.DEFAULT },
266264
{ chapter: Chapter.SOURCE_2, variant: Variant.TYPED },
267-
{ chapter: Chapter.SOURCE_2, variant: Variant.LAZY },
268265
{ chapter: Chapter.SOURCE_2, variant: Variant.NATIVE },
269266

270267
{ chapter: Chapter.SOURCE_3, variant: Variant.DEFAULT },
271268
{ chapter: Chapter.SOURCE_3, variant: Variant.TYPED },
272269
{ chapter: Chapter.SOURCE_3, variant: Variant.CONCURRENT },
273-
{ chapter: Chapter.SOURCE_3, variant: Variant.NON_DET },
274270
{ chapter: Chapter.SOURCE_3, variant: Variant.NATIVE },
275271

276272
{ chapter: Chapter.SOURCE_4, variant: Variant.DEFAULT },
277273
{ chapter: Chapter.SOURCE_4, variant: Variant.TYPED },
278-
{ chapter: Chapter.SOURCE_4, variant: Variant.GPU },
279274
{ chapter: Chapter.SOURCE_4, variant: Variant.NATIVE },
280275
{ chapter: Chapter.SOURCE_4, variant: Variant.EXPLICIT_CONTROL }
281276
];
@@ -293,8 +288,7 @@ export const sourceLanguages: SALanguage[] = sourceSubLanguages.map(sublang => {
293288
(variant === Variant.DEFAULT || variant === Variant.NATIVE || variant === Variant.TYPED);
294289

295290
// Enable CSE Machine for Source Chapter 3 and above
296-
supportedFeatures.cseMachine =
297-
chapter >= Chapter.SOURCE_3 && variant !== Variant.CONCURRENT && variant !== Variant.NON_DET;
291+
supportedFeatures.cseMachine = chapter >= Chapter.SOURCE_3 && variant !== Variant.CONCURRENT;
298292

299293
// Local imports/exports require Source 2+ as Source 1 does not have lists.
300294
supportedFeatures.multiFile = chapter >= Chapter.SOURCE_2;
@@ -426,7 +420,6 @@ export const createDefaultWorkspace = (workspaceLocation: WorkspaceLocation): Wo
426420
enableDebugging: true,
427421
debuggerContext: {} as DebuggerContext,
428422
lastDebuggerResult: undefined,
429-
lastNonDetResult: null,
430423
files: {}
431424
});
432425

@@ -606,6 +599,10 @@ export const defaultSideContentManager: SideContentManagerState = {
606599
stories: {}
607600
};
608601

602+
export const defaultVscode: VscodeState = {
603+
isVscode: false
604+
};
605+
609606
export const defaultState: OverallState = {
610607
router: defaultRouter,
611608
achievement: defaultAchievement,
@@ -616,5 +613,6 @@ export const defaultState: OverallState = {
616613
workspaces: defaultWorkspaceManager,
617614
featureFlags: defaultFeatureFlags,
618615
fileSystem: defaultFileSystem,
619-
sideContent: defaultSideContentManager
616+
sideContent: defaultSideContentManager,
617+
vscode: defaultVscode
620618
};

src/commons/application/__tests__/ApplicationTypes.ts

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ describe('available Source language configurations', () => {
2727
{ chapter: Chapter.SOURCE_1, variant: Variant.DEFAULT, supports: { substVisualizer: true } },
2828
{ chapter: Chapter.SOURCE_1, variant: Variant.TYPED, supports: { substVisualizer: true } },
2929
{ chapter: Chapter.SOURCE_1, variant: Variant.WASM },
30-
{ chapter: Chapter.SOURCE_1, variant: Variant.LAZY },
3130
{ chapter: Chapter.SOURCE_1, variant: Variant.NATIVE, supports: { substVisualizer: true } },
3231
// Source 2
3332
{
@@ -40,7 +39,6 @@ describe('available Source language configurations', () => {
4039
variant: Variant.TYPED,
4140
supports: { dataVisualizer: true, substVisualizer: true }
4241
},
43-
{ chapter: Chapter.SOURCE_2, variant: Variant.LAZY, supports: { dataVisualizer: true } },
4442
{
4543
chapter: Chapter.SOURCE_2,
4644
variant: Variant.NATIVE,
@@ -62,7 +60,6 @@ describe('available Source language configurations', () => {
6260
variant: Variant.CONCURRENT,
6361
supports: { dataVisualizer: true }
6462
},
65-
{ chapter: Chapter.SOURCE_3, variant: Variant.NON_DET, supports: { dataVisualizer: true } },
6663
{
6764
chapter: Chapter.SOURCE_3,
6865
variant: Variant.NATIVE,
@@ -79,11 +76,6 @@ describe('available Source language configurations', () => {
7976
variant: Variant.TYPED,
8077
supports: { dataVisualizer: true, cseMachine: true }
8178
},
82-
{
83-
chapter: Chapter.SOURCE_4,
84-
variant: Variant.GPU,
85-
supports: { dataVisualizer: true, cseMachine: true }
86-
},
8779
{
8880
chapter: Chapter.SOURCE_4,
8981
variant: Variant.NATIVE,

0 commit comments

Comments
 (0)