Skip to content

Commit

Permalink
Merge branch 'master' into github-persistence
Browse files Browse the repository at this point in the history
  • Loading branch information
martin-henz committed Jun 18, 2021
2 parents 76193a2 + 558f213 commit 2d00c77
Show file tree
Hide file tree
Showing 31 changed files with 454 additions and 670 deletions.
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,4 @@ REACT_APP_CADET_LOGGER=
REACT_APP_CADET_LOGGER_INTERVAL=10000

# Link to interative-sicp
REACT_APP_INTERACTIVE_SICP_URL="http://127.0.0.1:8080/"
REACT_APP_INTERACTIVE_SICP_DATA_URL="http://127.0.0.1:8080/"
21 changes: 14 additions & 7 deletions .github/workflows/build-development.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,6 @@ jobs:
run: |
yarn install
yarn run build
ln -s index.html build/playground.html
ln -s index.html build/contributors.html
ln -s index.html build/sourcecast.html
ln -s index.html build/interactive-sicp.html
# the `ln`s above are a hack to make GitHub Pages route /playground
# and /contributors etc to index, instead of 404-ing.
env:
REACT_APP_URL_SHORTENER_SIGNATURE: ${{ secrets.REACT_APP_URL_SHORTENER_SIGNATURE }}
REACT_APP_URL_SHORTENER_DOMAIN: ${{ secrets.REACT_APP_URL_SHORTENER_DOMAIN }}
Expand All @@ -60,7 +54,20 @@ jobs:
PUBLIC_URL: "https://source-academy.github.io"
REACT_APP_GITHUB_OAUTH_PROXY_URL: ${{ secrets.REACT_APP_GITHUB_OAUTH_PROXY_URL }}
REACT_APP_GITHUB_CLIENT_ID: ${{ secrets.REACT_APP_GITHUB_CLIENT_ID }}

- name: Create symbolic links
run: |
set -euxo pipefail
ln -s index.html build/playground.html
ln -s index.html build/contributors.html
ln -s index.html build/sourcecast.html
ln -s index.html build/interactive-sicp.html
mkdir -p build/interactive-sicp
declare -a arr=("index" "foreword" "prefaces03" "prefaces84" "prefaces96" "acknowledgements" "1" "1.1" "1.1.1" "1.1.2" "1.1.3" "1.1.4" "1.1.5" "1.1.6" "1.1.7" "1.1.8" "1.2" "1.2.1" "1.2.2" "1.2.3" "1.2.4" "1.2.5" "1.2.6" "1.3" "1.3.1" "1.3.2" "1.3.3" "1.3.4" "2" "2.1" "2.1.1" "2.1.2" "2.1.3" "2.1.4" "2.2" "2.2.1" "2.2.2" "2.2.3" "2.2.4" "2.3" "2.3.1" "2.3.2" "2.3.3" "2.3.4" "2.4" "2.4.1" "2.4.2" "2.4.3" "2.5" "2.5.1" "2.5.2" "2.5.3" "3" "3.1" "3.1.1" "3.1.2" "3.1.3" "3.2" "3.2.1" "3.2.2" "3.2.3" "3.2.4" "3.3" "3.3.1" "3.3.2" "3.3.3" "3.3.4" "3.3.5" "3.4" "3.4.1" "3.4.2" "3.5" "3.5.1" "3.5.2" "3.5.3" "3.5.4" "3.5.5" "4" "4.1" "4.1.1" "4.1.2" "4.1.3" "4.1.4" "4.1.5" "4.1.6" "4.1.7" "4.2" "4.2.1" "4.2.2" "4.2.3" "4.3" "4.3.1" "4.3.2" "4.3.3" "4.4" "4.4.1" "4.4.2" "4.4.3" "4.4.4" "5" "5.1" "5.1.1" "5.1.2" "5.1.3" "5.1.4" "5.1.5" "5.2" "5.2.1" "5.2.2" "5.2.3" "5.2.4" "5.3" "5.3.1" "5.3.2" "5.4" "5.4.1" "5.4.2" "5.4.3" "5.4.4" "5.5" "5.5.1" "5.5.2" "5.5.3" "5.5.4" "5.5.5" "5.5.6" "5.5.7" "references" "making-of")
for i in "${arr[@]}"; do
ln -s ../index.html build/interactive-sicp/$i.html
done
# the `ln`s above are a hack to make GitHub Pages route /playground
# and /contributors etc to index, instead of 404-ing.
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
[![Coverage Status](https://coveralls.io/repos/github/source-academy/cadet-frontend/badge.svg?branch=master)](https://coveralls.io/github/source-academy/cadet-frontend?branch=master)
[![License](https://img.shields.io/github/license/source-academy/cadet-frontend)](https://github.com/source-academy/cadet-frontend/blob/master/LICENSE)

The Source Academy (<https://source-academy.github.io/>) is an immersive online experiential environment for learning programming, developed in the School of Computing at the National University of Singapore. This repository houses the sources for the frontend of the Source Academy, written in ReactJS with Redux.
The Source Academy (<https://source-academy.github.io/>) is an immersive online experiential environment for learning programming. It is developed by a community of learners (also called "Source Academy") who use the book [Structure and Interpretation of Computer Programs, JavaScript Adaptation](https://source-academy.github.io/interactive-sicp) (SICP JS). This repository houses the sources for the frontend of the Source Academy, written in ReactJS with Redux.

## Features
- Playground to write and test programs
Expand All @@ -15,7 +15,7 @@ The Source Academy (<https://source-academy.github.io/>) is an immersive online

## Getting Started

### Installation of Public Edition (playground only, no backend)
### Installation of Source Academy (latest version [available in GitHub Pages](https://source-academy.github.io/))

1. Install a stable version of NodeJS. The active LTS or current version should work fine.
2. Clone this repository and navigate to it using "cd" in your command line or shell tool.
Expand All @@ -25,7 +25,7 @@ The Source Academy (<https://source-academy.github.io/>) is an immersive online

In this edition, you will only see the Playground with all its tools, but no login options or homework submission features. For this edition, there is no need for "Setting up your environment".

### Installation of Course Edition
### Installation of Source Academy @ NUS (access [latest production version here](https://sourceacademy.nus.edu.sg))

1. Install a stable version of NodeJS. The active LTS or current version should work fine.
2. Clone this repository and navigate to it using "cd" in your command line or shell tool.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@
"ag-grid-community": "^25.3.0",
"ag-grid-react": "^25.3.0",
"array-move": "^3.0.1",
"better-react-mathjax": "^1.0.2",
"classnames": "^2.3.1",
"connected-react-router": "^6.9.1",
"flexboxgrid": "^6.3.1",
Expand All @@ -67,6 +66,7 @@
"react-dropzone": "^11.3.2",
"react-hotkeys": "^2.0.0",
"react-konva": "^17.0.2-4",
"react-latex-next": "^2.0.0",
"react-mde": "^11.5.0",
"react-redux": "^7.2.4",
"react-responsive": "^8.2.0",
Expand Down
2 changes: 1 addition & 1 deletion src/commons/__tests__/__snapshots__/Markdown.tsx.snap
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Markdown page renders correctly 1`] = `
"<Memo(Markdown) content=\\"\\\\nWelcome to the Source Academy playground!\\\\n\\\\nThe language [_Source_](https://source-academy.github.io/source/) is the official language of the textbook [_Structure and\\\\nInterpretation of Computer Programs, JavaScript Adaptation_](https://source-academy.github.io/sicp/). You have chosen the sublanguage [_Source §1_](https://source-academy.github.io/source/source_1/).\\\\n\\\\nIn the editor on the left, you can use the [_Ace keyboard shortcuts_](https://github.com/ajaxorg/ace/wiki/Default-Keyboard-Shortcuts) \\\\nand also the [_Source Academy keyboard shortcuts_](https://github.com/source-academy/cadet-frontend/wiki/Source-Academy-Keyboard-Shortcuts).\\\\n\\\\n\\" openLinksInNewWindow={true}>
"<Memo(Markdown) content=\\"\\\\nWelcome to the Source Academy playground!\\\\n\\\\nThe language [_Source_](https://source-academy.github.io/source/) is the official language of the textbook [_Structure and\\\\nInterpretation of Computer Programs, JavaScript Adaptation_](https://source-academy.github.io/interactive-sicp/). You have chosen the sublanguage [_Source §1_](https://source-academy.github.io/source/source_1/).\\\\n\\\\nIn the editor on the left, you can use the [_Ace keyboard shortcuts_](https://github.com/ajaxorg/ace/wiki/Default-Keyboard-Shortcuts) \\\\nand also the [_Source Academy keyboard shortcuts_](https://github.com/source-academy/cadet-frontend/wiki/Source-Academy-Keyboard-Shortcuts).\\\\n\\\\n\\" openLinksInNewWindow={true}>
<div className=\\"md bp3-running-text\\" dangerouslySetInnerHTML={{...}} />
</Memo(Markdown)>"
`;
31 changes: 17 additions & 14 deletions src/commons/controlBar/github/ControlBarGitHubButtons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,21 @@ import { Octokit } from '@octokit/rest';
import * as React from 'react';
import { useMediaQuery } from 'react-responsive';

import { GitHubState } from '../../../features/github/GitHubTypes';
import { GitHubSaveInfo } from '../../../features/github/GitHubTypes';
import controlButton from '../../ControlButton';
import Constants from '../../utils/Constants';

export type ControlBarGitHubButtonsProps = {
loggedInAs: Octokit;
githubSaveInfo: { repoName: string; filePath: string };
githubSaveInfo: GitHubSaveInfo;
isDirty: boolean;
onClickOpen?: () => void;
onClickSave?: () => void;
onClickSaveAs?: () => void;
onClickLogIn?: () => void;
onClickLogOut?: () => void;
};

const stateToIntent: { [state in GitHubState]: Intent } = {
LOGGED_OUT: Intent.NONE,
LOGGED_IN: Intent.NONE
};

/**
* GitHub buttons to be used specifically in the Playground.
* Creates a dropdown upon click.
Expand All @@ -32,16 +28,23 @@ const stateToIntent: { [state in GitHubState]: Intent } = {
*/
export const ControlBarGitHubButtons: React.FC<ControlBarGitHubButtonsProps> = props => {
const isMobileBreakpoint = useMediaQuery({ maxWidth: Constants.mobileBreakpoint });
const isLoggedIn = props.loggedInAs !== undefined;

const filePath = props.githubSaveInfo.filePath || '';
const fileName = (filePath.split('\\').pop() || '').split('/').pop() || '';

const isLoggedIn = props.loggedInAs !== undefined;
const shouldDisableButtons = !isLoggedIn;
const shouldDisableSaveButton =
props.githubSaveInfo.repoName === '' || props.githubSaveInfo.filePath === '';
const hasFilePath = filePath !== '';
const hasOpenFile = isLoggedIn && hasFilePath;

const state: GitHubState = isLoggedIn ? 'LOGGED_IN' : 'LOGGED_OUT';
const mainButtonDisplayText = hasOpenFile ? fileName : 'GitHub';
let mainButtonIntent: Intent = Intent.NONE;
if (hasOpenFile) {
mainButtonIntent = props.isDirty ? Intent.WARNING : Intent.PRIMARY;
}

const mainButton = controlButton('GitHub', IconNames.GIT_BRANCH, null, {
intent: stateToIntent[state]
const mainButton = controlButton(mainButtonDisplayText, IconNames.GIT_BRANCH, null, {
intent: mainButtonIntent
});

const openButton = controlButton(
Expand All @@ -57,7 +60,7 @@ export const ControlBarGitHubButtons: React.FC<ControlBarGitHubButtonsProps> = p
IconNames.FLOPPY_DISK,
props.onClickSave,
undefined,
shouldDisableButtons || shouldDisableSaveButton
shouldDisableButtons || !hasOpenFile
);

const saveAsButton = controlButton(
Expand Down
3 changes: 1 addition & 2 deletions src/commons/gitHubOverlay/FileExplorerDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import {
checkIfFileCanBeOpened,
checkIfFileCanBeSavedAndGetSaveType,
checkIfUserAgreesToOverwriteEditorData,
checkIfUserAgreesToPerformCreatingSave,
checkIfUserAgreesToPerformOverwritingSave,
openFileInEditor,
performCreatingSave,
Expand Down Expand Up @@ -134,7 +133,7 @@ const FileExplorerDialog: React.FC<FileExplorerDialogProps> = props => {
);
}

if (saveType === 'Create' && (await checkIfUserAgreesToPerformCreatingSave())) {
if (saveType === 'Create') {
performCreatingSave(
props.octokit,
githubLoginID,
Expand Down
6 changes: 0 additions & 6 deletions src/commons/gitHubOverlay/__tests__/FileExplorerDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -211,12 +211,6 @@ test('Performing creating save leads to appropriate function being called', asyn
}
);

const checkIfUserAgreesToPerformCreatingSaveMock = jest.spyOn(
GitHubUtils,
'checkIfUserAgreesToPerformCreatingSave'
);
checkIfUserAgreesToPerformCreatingSaveMock.mockImplementation(async () => true);

const performCreatingSaveMock = jest.spyOn(GitHubUtils, 'performCreatingSave');
performCreatingSaveMock.mockImplementation(
async (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ exports[`EnvVisualizer component renders correctly 1`] = `
<br />
The environment model diagram follows a notation introduced in
<a href=\\"https://source-academy.github.io/sicp/chapters/3.2.html\\" rel=\\"noopener noreferrer\\" target=\\"_blank\\">
<a href=\\"https://source-academy.github.io/interactive-sicp/3.2\\" rel=\\"noopener noreferrer\\" target=\\"_blank\\">
<i>
Structure and Interpretation of Computer Programs, JavaScript Adaptation, Chapter 3, Section 2
</i>
Expand Down
12 changes: 6 additions & 6 deletions src/commons/utils/Constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ const googleApiKey = process.env.REACT_APP_GOOGLE_API_KEY;
const googleAppId = process.env.REACT_APP_GOOGLE_APP_ID;
const githubClientId = process.env.REACT_APP_GITHUB_CLIENT_ID || '';
const githubOAuthProxyUrl = process.env.REACT_APP_GITHUB_OAUTH_PROXY_URL || '';
const interactiveSicpUrl =
process.env.REACT_APP_INTERACTIVE_SICP_URL || 'https://source-academy.github.io/sicp/';
const interactiveSicpDataUrl =
process.env.REACT_APP_INTERACTIVE_SICP_DATA_URL || 'https://source-academy.github.io/sicp/'; // data for interactive-sicp (images and json files)

const authProviders: Map<string, { name: string; endpoint: string; isDefault: boolean }> =
new Map();
Expand Down Expand Up @@ -80,9 +80,9 @@ export enum Links {
sourceDocs = 'https://source-academy.github.io/source/',
techSVC = 'mailto:techsvc@comp.nus.edu.sg',
techSVCNumber = '6516 2736',
textbook = 'https://source-academy.github.io/sicp/',
textbookChapter2_2 = 'https://source-academy.github.io/sicp/chapters/2.2.html',
textbookChapter3_2 = 'https://source-academy.github.io/sicp/chapters/3.2.html',
textbook = 'https://source-academy.github.io/interactive-sicp/',
textbookChapter2_2 = 'https://source-academy.github.io/interactive-sicp/2.2',
textbookChapter3_2 = 'https://source-academy.github.io/interactive-sicp/3.2',

aceHotkeys = 'https://github.com/ajaxorg/ace/wiki/Default-Keyboard-Shortcuts',
sourceHotkeys = 'https://github.com/source-academy/cadet-frontend/wiki/Source-Academy-Keyboard-Shortcuts',
Expand Down Expand Up @@ -127,7 +127,7 @@ const Constants = {
sharedbBackendUrl,
disablePeriods,
cadetLoggerInterval,
interactiveSicpUrl
interactiveSicpDataUrl
};

export default Constants;
17 changes: 9 additions & 8 deletions src/features/game/scenes/roomPreview/RoomPreview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,14 +139,15 @@ export default class RoomPreview extends Phaser.Scene {

public createContext() {
this.context = createContext(4, [], 'playground', 'default', {
scene: this,
phaser: Phaser,
preloadImageMap: this.preloadImageMap,
preloadSoundMap: this.preloadSoundMap,
preloadSpritesheetMap: this.preloadSpritesheetMap,
remotePath: Constants.assetsFolder,
screenSize: screenSize,
createAward: (x: number, y: number, key: ItemId) => this.createAward(x, y, key)
game: {
scene: this,
preloadImageMap: this.preloadImageMap,
preloadSoundMap: this.preloadSoundMap,
preloadSpritesheetMap: this.preloadSpritesheetMap,
remotePath: Constants.assetsFolder,
screenSize: screenSize,
createAward: (x: number, y: number, key: ItemId) => this.createAward(x, y, key)
}
});
}

Expand Down
6 changes: 5 additions & 1 deletion src/features/github/GitHubTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,8 @@ export const GITHUB_OPEN_FILE = 'GITHUB_OPEN_FILE';
export const GITHUB_SAVE_FILE = 'GITHUB_SAVE_FILE';
export const GITHUB_SAVE_FILE_AS = 'GITHUB_SAVE_FILE_AS';

export type GitHubState = 'LOGGED_IN' | 'LOGGED_OUT';
export type GitHubSaveInfo = {
repoName: string;
filePath: string;
lastSaved?: Date;
};
20 changes: 3 additions & 17 deletions src/features/github/GitHubUtils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -173,20 +173,6 @@ export async function checkIfUserAgreesToPerformOverwritingSave() {
});
}

export async function checkIfUserAgreesToPerformCreatingSave() {
return await showSimpleConfirmDialog({
contents: (
<div>
<p>Warning: You are creating a new file in the repository.</p>
<p>Please click 'Confirm' to continue, or 'Cancel' to go back.</p>
</div>
),
negativeLabel: 'Cancel',
positiveIntent: 'primary',
positiveLabel: 'Confirm'
});
}

export async function openFileInEditor(
octokit: Octokit,
repoOwner: string,
Expand All @@ -207,7 +193,7 @@ export async function openFileInEditor(
if (content) {
const newEditorValue = Buffer.from(content, 'base64').toString();
store.dispatch(actions.updateEditorValue(newEditorValue, 'playground'));
store.dispatch(actions.playgroundUpdateGitHubSaveInfo(repoName, filePath));
store.dispatch(actions.playgroundUpdateGitHubSaveInfo(repoName, filePath, new Date()));
showSuccessMessage('Successfully loaded file!', 1000);
}
}
Expand Down Expand Up @@ -259,7 +245,7 @@ export async function performOverwritingSave(
committer: { name: githubName, email: githubEmail },
author: { name: githubName, email: githubEmail }
});
store.dispatch(actions.playgroundUpdateGitHubSaveInfo(repoName, filePath));
store.dispatch(actions.playgroundUpdateGitHubSaveInfo(repoName, filePath, new Date()));
showSuccessMessage('Successfully saved file!', 1000);
} catch (err) {
console.error(err);
Expand Down Expand Up @@ -296,7 +282,7 @@ export async function performCreatingSave(
committer: { name: githubName, email: githubEmail },
author: { name: githubName, email: githubEmail }
});
store.dispatch(actions.playgroundUpdateGitHubSaveInfo(repoName, filePath));
store.dispatch(actions.playgroundUpdateGitHubSaveInfo(repoName, filePath, new Date()));
showSuccessMessage('Successfully created file!', 1000);
} catch (err) {
console.error(err);
Expand Down
7 changes: 5 additions & 2 deletions src/features/playground/PlaygroundActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,8 @@ export const changeQueryString = (queryString: string) => action(CHANGE_QUERY_ST
export const playgroundUpdatePersistenceFile = (file?: PersistenceFile) =>
action(PLAYGROUND_UPDATE_PERSISTENCE_FILE, file);

export const playgroundUpdateGitHubSaveInfo = (repoName: string, filePath: string) =>
action(PLAYGROUND_UPDATE_GITHUB_SAVE_INFO, { repoName, filePath });
export const playgroundUpdateGitHubSaveInfo = (
repoName: string,
filePath: string,
lastSaved: Date
) => action(PLAYGROUND_UPDATE_GITHUB_SAVE_INFO, { repoName, filePath, lastSaved });
8 changes: 5 additions & 3 deletions src/features/sicp/SourceTheme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
* Source Theme for use with react-syntax-highlighter.
* Tries to match the Source Theme for Ace Editor in js-slang
*/
const SourceThemeBackground = '#2c3e50';

export const SourceTheme = {
'code[class*="language-"]': {
color: 'white',
background: '#2c3e50',
background: 'transparent',
fontFamily: "'Inconsolata', 'Consolas', monospace",
textAlign: 'left',
whiteSpace: 'pre',
Expand All @@ -24,7 +26,7 @@ export const SourceTheme = {
},
'pre[class*="language-"]': {
color: 'white',
background: '#2c3e50',
background: SourceThemeBackground,
fontFamily: "'Inconsolata', 'Consolas', monospace",
textAlign: 'left',
whiteSpace: 'pre',
Expand All @@ -45,7 +47,7 @@ export const SourceTheme = {
borderRadius: '0.3em'
},
':not(pre) > code[class*="language-"]': {
background: '#2c3e50',
background: 'transparent',
padding: '0.1em',
borderRadius: '0.3em',
whiteSpace: 'normal'
Expand Down
Loading

0 comments on commit 2d00c77

Please sign in to comment.