Skip to content

Commit

Permalink
Interactive SICP-JS Feature (#1770)
Browse files Browse the repository at this point in the history
* Add SICP toplevel button

* Add Sicp Placeholder Page

* Add SicpDisplay component

* Add sicp XML files

* Add state to sicp component

* Move xml files to xml folder

* Move sicp xml files to data folder

* Add dummy json file

* Add temp json file for testing

* Remove sicp from redux store

* Add function to parse json files

* Add temporary mock data folder

* Add sicp workspace

* Add repl to side content

* Add close button

* Add editor value

* Add non functional autorun button

* Change sicp to fetch files from github

* Remove unnecessary state

* Add table of contents to sicp

* Display code snippets using read only ace editor

* Add parser for images

* Add parser for equations

* Add run functionality

* Replace ITreeNode with TreeNodeInfo

* Add features workspace

* Add parsing functions for symbols and headings

* Fix duplicate key error in ParseJson.tsx

* Change path name from sicp to interactive-sicp

* Add parser for ordered lists

* Move parsing of symbols to sicp repo

* Add parser for epigraph

* Add parser for exercises

* Add id to text containers

* Move subcomponents of sicp from features to pages

* Set only one editor active at a time

* Change url hash to slug

* Update failing tests

* Update workspace reducer test

* Reuse playground as sicp workspace

* Update parser for latex

* Update parser for references

* Add parser for links

* Test deployment to github pages

* Test deployment to github pages

* Add .vscode to .gitignore

* Fix prettier errors

* Update sicp index page

* Add logic for scrolling within sicp component

* Abstract SicpControlBar into its own component

* Move sicp navbar to application navbar component

* Add parser for references

* Update failing tests

* Update parseJson with missing tags

* Add parser for tables

* Rename files for consistency

* Merge Sicp and SicpDisplay components

* Arrange functions in ParseJson.tsx

* Move usingSubst from playground to workspaces

* Add previous and next buttons

* Add loading page when fetching data

* Add better-react-mathjax component

* Remove unused imports

* Fix parsing of LaTeX in snippets

* Add refs to headers

* Simplify parsing of figures

* Fix scaling of images

* Set sicp url as constant in Constants.ts

* Change styling for snippet component

* Simplify sicp routes

* Remove redundant xml files

* Set up links to sicp on sa github

* Add tests for ParseJson.tsx

* Fix failing test

* Fix failing ci

* Revamped loading and error components

* Remove test.json

* Fix broken tests

* Remove unused css

* Add test for index page

* Add comments

* Add error handling

* Switch to mathjax 2 for performance

* Remove redundant test

* Style table of contents

* Fix exercise no solution placeholder message

* Fix epigraphs

* Make code snippets resizeable

* Add tests

* Change styling metaphrase and meta components

* Fix tests

* Change MathJax config

* Update SicpLatex tests

* Move table of contents button to sicp folder

* Add comments to sicp navigation bar

* Remove unused side content type

* Move TOGGLE_USING_SUBST to workspace types

* Update code snippet to remove newlines

* Update toc.json

* Reset workspace whenever new snippet is displayed

* Add max height to snippet

* Update snapshots

* Update styling of index page

* Simplify handling of functions in ParseJson.tsx

* Change ace editor to pre in code snippets

* Add syntax highlighting

* Update syntax highlighting

* Change code snippet text size

* Tweak margin for exercise

* Remove redundant code

* Update failing snapshots

* Make syntax highlighting asynchronous

* Tweak how loading works

* Fix mobile keyboard width

* Fix code snippets overflow

* Fix table of contents overflow on mobile

* Add sicp-js to navbar mobile side menu

* Add sicp js to navbar

* Fix code snippet mobile issues

* Update tests

* Fix prettier issues

Co-authored-by: Martin Henz <henz@comp.nus.edu.sg>
  • Loading branch information
samuelfangjw and martin-henz committed Jun 14, 2021
1 parent 7497693 commit 8ba3df3
Show file tree
Hide file tree
Showing 64 changed files with 4,900 additions and 67 deletions.
5 changes: 4 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,7 @@ REACT_APP_GITHUB_OAUTH_PROXY_URL=

# Keystroke logging
REACT_APP_CADET_LOGGER=
REACT_APP_CADET_LOGGER_INTERVAL=10000
REACT_APP_CADET_LOGGER_INTERVAL=10000

# Link to interative-sicp
REACT_APP_INTERACTIVE_SICP_URL="http://127.0.0.1:8080/"
1 change: 1 addition & 0 deletions .github/workflows/build-development.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ jobs:
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/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:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ terraform*
.env.test.local
.env.production.local
.idea/
.vscode/
cadet-frontend.iml

npm-debug.log*
Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,14 @@
"@sourceacademy/sharedb-ace": "^2.0.2",
"@sourceacademy/sling-client": "^0.0.1",
"@testing-library/user-event": "^13.1.9",
"@types/react-syntax-highlighter": "^13.5.0",
"@types/uuid": "^8.3.0",
"ace-builds": "^1.4.12",
"acorn": "^8.3.0",
"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 Down Expand Up @@ -72,6 +74,7 @@
"react-router-dom": "^5.2.0",
"react-simple-keyboard": "^3.1.42",
"react-sortable-hoc": "^1.11.0",
"react-syntax-highlighter": "^15.4.3",
"react-textarea-autosize": "^8.3.3",
"redux": "^4.1.0",
"redux-mock-store": "^1.5.4",
Expand Down
4 changes: 4 additions & 0 deletions src/commons/application/Application.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import Login from '../../pages/login/LoginContainer';
import MissionControlContainer from '../../pages/missionControl/MissionControlContainer';
import NotFound from '../../pages/notFound/NotFound';
import Playground from '../../pages/playground/PlaygroundContainer';
import Sicp from '../../pages/sicp/Sicp';
import SourcecastContainer from '../../pages/sourcecast/SourcecastContainer';
import NavigationBar from '../navigationBar/NavigationBar';
import Constants from '../utils/Constants';
Expand Down Expand Up @@ -164,6 +165,8 @@ const Application: React.FC<ApplicationProps> = props => {
/>
)}
<Route path="/callback/github" component={GitHubCallback} />
<Route exact path="/interactive-sicp" render={redirectToSicp} />
<Route path="/interactive-sicp/:section" component={Sicp} />
{fullPaths}
<Route
exact={true}
Expand All @@ -181,6 +184,7 @@ const Application: React.FC<ApplicationProps> = props => {
const redirectToPlayground = () => <Redirect to="/playground" />;
const redirectToAcademy = () => <Redirect to="/academy" />;
const redirectToLogin = () => <Redirect to="/login" />;
const redirectToSicp = () => <Redirect to="/interactive-sicp/index" />;

/**
* A user routes to /academy,
Expand Down
5 changes: 4 additions & 1 deletion src/commons/application/ApplicationTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,6 @@ export const defaultAchievement: AchievementState = {
};

export const defaultPlayground: PlaygroundState = {
usingSubst: false,
githubSaveInfo: { repoName: '', filePath: '' }
};

Expand Down Expand Up @@ -276,6 +275,10 @@ export const defaultWorkspaceManager: WorkspaceManagerState = {
timeElapsedBeforePause: 0,
timeResumed: 0
},
sicp: {
...createDefaultWorkspace('sicp'),
usingSubst: false
},
githubAssessment: {
...createDefaultWorkspace('githubAssessment'),
hasUnsavedChanges: false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ exports[`Application renders correctly 1`] = `
<Route path=\\"/githubassessments/missions\\" component={[Function: component]} />
<Route path=\\"/githubassessments/editor\\" component={[Function: C] { displayName: 'withRouter(Connect(GitHubAssessmentWorkspace))', WrappedComponent: [Function: GitHubAssessmentWorkspace], propTypes: { wrappedComponentRef: [Function: bound checkType] { isRequired: [Function: bound checkType] } } }} />
<Route path=\\"/callback/github\\" component={[Function: GitHubCallback]} />
<Route exact={true} path=\\"/interactive-sicp\\" render={[Function: redirectToSicp]} />
<Route path=\\"/interactive-sicp/:section\\" component={[Function: Sicp]} />
<Route path=\\"/academy\\" render={[Function: redirectToLogin]} />
<Route path=\\"/mission-control/:assessmentId(-?\\\\\\\\d+)?/:questionId(\\\\\\\\d+)?\\" render={[Function: toIncubator]} />
<Route path=\\"/login\\" render={[Function (anonymous)]} />
Expand Down
14 changes: 14 additions & 0 deletions src/commons/controlBar/ControlBarCloseButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { IconNames } from '@blueprintjs/icons';

import controlButton from '../ControlButton';

type ControlBarCloseButtonProps = OwnProps;

type OwnProps = {
key: string;
handleClose: () => void;
};

export function ControlBarCloseButton(props: ControlBarCloseButtonProps) {
return controlButton('Close', IconNames.CROSS, props.handleClose);
}
15 changes: 15 additions & 0 deletions src/commons/controlBar/ControlBarShowDependenciesButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { IconNames } from '@blueprintjs/icons';

import controlButton from '../ControlButton';

type ControlBarShowDependenciesButtonProps = OwnProps;

type OwnProps = {
key: string;
buttonText: string;
handleShowDependencies: () => void;
};

export function ControlBarShowDependenciesButton(props: ControlBarShowDependenciesButtonProps) {
return controlButton(props.buttonText, IconNames.CODE, props.handleShowDependencies);
}
2 changes: 1 addition & 1 deletion src/commons/mobileWorkspace/MobileKeyboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const MobileKeyboard: React.FC<MobileKeyboardProps> = props => {
} else {
//do showing
document.getElementById('mobile-keyboard-toggle')!.style.setProperty('display', 'flex');
document.getElementById('mobile-floating-toggle')!.style.setProperty('width', '99vw');
document.getElementById('mobile-floating-toggle')!.style.setProperty('width', '99%');
document.getElementById('mobile-floating-toggle')!.style.setProperty('opacity', '1');
setButtonContent('ᐳ');
setIsKeyoardShown(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,8 +251,8 @@ const MobileSideContent: React.FC<MobileSideContentProps & OwnProps> = props =>
>
{renderedTabs}

{/* Render the bottom ControlBar 'Cog' button only in the Playground Workspace */}
{props.workspaceLocation === 'playground' && (
{/* Render the bottom ControlBar 'Cog' button only in the Playground or Sicp Workspace */}
{(props.workspaceLocation === 'playground' || props.workspaceLocation === 'sicp') && (
<MobileControlBar {...props.mobileControlBarProps} />
)}
</Tabs>
Expand Down
43 changes: 43 additions & 0 deletions src/commons/navigationBar/NavigationBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import classNames from 'classnames';
import * as React from 'react';
import { useMediaQuery } from 'react-responsive';
import { NavLink, Route, Switch } from 'react-router-dom';
import SicpNavigationBar from 'src/commons/navigationBar/subcomponents/SicpNavigationBar';

import { Role } from '../application/ApplicationTypes';
import Dropdown from '../dropdown/Dropdown';
Expand Down Expand Up @@ -98,6 +99,20 @@ const NavigationBar: React.FC<NavigationBarProps> = props => {
<Icon icon={IconNames.BRIEFCASE} />
<div>GitHub Assessments</div>
</NavLink>
<NavLink
activeClassName={Classes.ACTIVE}
className={classNames(
'NavigationBar__link__mobile',
Classes.BUTTON,
Classes.MINIMAL,
Classes.LARGE
)}
to="/interactive-sicp/index"
onClick={() => setMobileSideMenuOpen(false)}
>
<Icon icon={IconNames.BOOK} />
<div>SICP JS</div>
</NavLink>
</Drawer>
</NavbarGroup>
</>
Expand All @@ -119,6 +134,14 @@ const NavigationBar: React.FC<NavigationBarProps> = props => {
<Icon icon={IconNames.BRIEFCASE} />
<div>GitHub Assessments</div>
</NavLink>
<NavLink
activeClassName={Classes.ACTIVE}
className={classNames('NavigationBar__link__mobile', Classes.BUTTON, Classes.MINIMAL)}
to="/interactive-sicp/index"
>
<Icon icon={IconNames.BOOK} />
<div>SICP JS</div>
</NavLink>
</NavbarGroup>
)
) : (
Expand All @@ -131,6 +154,14 @@ const NavigationBar: React.FC<NavigationBarProps> = props => {
<Icon icon={IconNames.CODE} />
<div>Source Academy Playground</div>
</NavLink>
<NavLink
activeClassName={Classes.ACTIVE}
className={classNames('NavigationBar__link__mobile', Classes.BUTTON, Classes.MINIMAL)}
to="/interactive-sicp/index"
>
<Icon icon={IconNames.BOOK} />
<div>SICP JS</div>
</NavLink>
</NavbarGroup>
);

Expand Down Expand Up @@ -201,6 +232,15 @@ const NavigationBar: React.FC<NavigationBarProps> = props => {
</NavLink>
)}

<NavLink
activeClassName={Classes.ACTIVE}
className={classNames('NavigationBar__link', Classes.BUTTON, Classes.MINIMAL)}
to="/interactive-sicp/index"
>
<Icon icon={IconNames.BOOK} />
<div className="navbar-button-text">SICP JS</div>
</NavLink>

{props.role && Constants.enableAchievements && (
<NavLink
activeClassName={Classes.ACTIVE}
Expand Down Expand Up @@ -267,6 +307,9 @@ const NavigationBar: React.FC<NavigationBarProps> = props => {
<GitHubAssessmentsNavigationBar {...props} />
)}
</Route>
<Route path="/interactive-sicp/:section?">
<SicpNavigationBar />
</Route>
<Route>
{!Constants.playgroundOnly && props.role && !isMobileBreakpoint && desktopMenuOpen && (
<AcademyNavigationBar role={props.role} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ exports[`NavigationBar renders "Not logged in" correctly 1`] = `
GitHub Assessments
</div>
</NavLink>
<NavLink activeClassName=\\"bp3-active\\" className=\\"NavigationBar__link bp3-button bp3-minimal\\" to=\\"/interactive-sicp/index\\">
<Blueprint3.Icon icon=\\"book\\" />
<div className=\\"navbar-button-text\\">
SICP JS
</div>
</NavLink>
</Blueprint3.NavbarGroup>
<Blueprint3.NavbarGroup align=\\"right\\">
<NavLink activeClassName=\\"bp3-active\\" className=\\"NavigationBar__link bp3-button bp3-minimal\\" to=\\"/contributors\\">
Expand All @@ -49,6 +55,9 @@ exports[`NavigationBar renders "Not logged in" correctly 1`] = `
<Route path=\\"/githubassessments\\">
<GitHubAssessmentsNavigationBar handleLogOut={[Function: handleLogOut]} handleGitHubLogIn={[Function: handleGitHubLogIn]} handleGitHubLogOut={[Function: handleGitHubLogOut]} title=\\"Source Academy\\" />
</Route>
<Route path=\\"/interactive-sicp/:section?\\">
<SicpNavigationBar />
</Route>
<Route />
</Switch>
</Fragment>"
Expand Down Expand Up @@ -82,6 +91,12 @@ exports[`NavigationBar renders correctly with student role 1`] = `
GitHub Assessments
</div>
</NavLink>
<NavLink activeClassName=\\"bp3-active\\" className=\\"NavigationBar__link bp3-button bp3-minimal\\" to=\\"/interactive-sicp/index\\">
<Blueprint3.Icon icon=\\"book\\" />
<div className=\\"navbar-button-text\\">
SICP JS
</div>
</NavLink>
<NavLink activeClassName=\\"bp3-active\\" className=\\"NavigationBar__link bp3-button bp3-minimal\\" to=\\"/achievement\\">
<Blueprint3.Icon icon=\\"mountain\\" />
<div className=\\"navbar-button-text\\">
Expand Down Expand Up @@ -113,6 +128,9 @@ exports[`NavigationBar renders correctly with student role 1`] = `
<Route path=\\"/githubassessments\\">
<GitHubAssessmentsNavigationBar handleLogOut={[Function: handleLogOut]} handleGitHubLogIn={[Function: handleGitHubLogIn]} handleGitHubLogOut={[Function: handleGitHubLogOut]} role=\\"student\\" title=\\"Source Academy\\" />
</Route>
<Route path=\\"/interactive-sicp/:section?\\">
<SicpNavigationBar />
</Route>
<Route>
<AcademyNavigationBar role=\\"student\\" />
</Route>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,21 @@ const NavigationBarMobileSideMenu: React.FC<NavigationBarMobileSideMenuProps> =
<div className="navbar-button-text">GitHub Assessments</div>
</NavLink>

<NavLink
activeClassName={Classes.ACTIVE}
className={classNames(
'NavigationBar__link_mobile',
Classes.BUTTON,
Classes.MINIMAL,
Classes.LARGE
)}
to="/interactive-sicp/index"
onClick={props.onClose}
>
<Icon icon={IconNames.BOOK} />
<div className="navbar-button-text">SICP JS</div>
</NavLink>

{props.role && Constants.enableAchievements && (
<NavLink
activeClassName={Classes.ACTIVE}
Expand Down
Loading

0 comments on commit 8ba3df3

Please sign in to comment.