@@ -187,6 +247,7 @@ const Sicp: React.FC = () => {
>
+ {languageToggle}
{loading ? (
{loadingComponent}
) : section === 'index' ? (
diff --git a/src/pages/sicp/subcomponents/SicpToc.tsx b/src/pages/sicp/subcomponents/SicpToc.tsx
index 84fbced81f..5f2c3a99b2 100644
--- a/src/pages/sicp/subcomponents/SicpToc.tsx
+++ b/src/pages/sicp/subcomponents/SicpToc.tsx
@@ -1,9 +1,15 @@
import { Tree, TreeNodeInfo } from '@blueprintjs/core';
+import { NonIdealState, Spinner } from '@blueprintjs/core';
import { cloneDeep } from 'lodash';
import React, { useState } from 'react';
import { useNavigate } from 'react-router';
+import Constants from 'src/commons/utils/Constants';
+import { readSicpLangLocalStorage } from 'src/features/sicp/utils/SicpUtils';
-import toc from '../../../features/sicp/data/toc.json';
+import fallbackToc from '../../../features/sicp/data/toc.json';
+
+const baseUrl = Constants.sicpBackendUrl + 'json/';
+const loadingComponent = } />;
type TocProps = OwnProps;
@@ -14,8 +20,9 @@ type OwnProps = {
/**
* Table of contents of SICP.
*/
-const SicpToc: React.FC = props => {
- const [sidebarContent, setSidebarContent] = useState(toc as TreeNodeInfo[]);
+
+const Toc: React.FC<{ toc: TreeNodeInfo[]; props: TocProps }> = ({ toc, props }) => {
+ const [sidebarContent, setSidebarContent] = useState(toc);
const navigate = useNavigate();
const handleNodeExpand = (_node: TreeNodeInfo, path: integer[]) => {
@@ -40,15 +47,61 @@ const SicpToc: React.FC = props => {
[navigate, props]
);
+ return (
+
+ );
+};
+
+const SicpToc: React.FC = props => {
+ const [lang, setLang] = useState(readSicpLangLocalStorage());
+ const [toc, setToc] = useState([] as TreeNodeInfo[]);
+ const [loading, setLoading] = useState(true);
+ const [error, setError] = useState(false);
+
+ React.useEffect(() => {
+ const handleLangChange = () => {
+ setLang(readSicpLangLocalStorage());
+ };
+ window.addEventListener('sicp-tb-lang-change', handleLangChange);
+ return () => window.removeEventListener('sicp-tb-lang-change', handleLangChange);
+ }, []);
+
+ React.useEffect(() => {
+ setLoading(true);
+ fetch(baseUrl + lang + '/toc.json')
+ .then(response => {
+ if (!response.ok) {
+ throw Error(response.statusText);
+ }
+ return response.json();
+ })
+ .then(json => {
+ setToc(json as TreeNodeInfo[]);
+ })
+ .catch(error => {
+ console.log(error);
+ setError(true);
+ })
+ .finally(() => {
+ setLoading(false);
+ });
+ }, [lang]);
+
return (
-
+ {loading ? (
+
{loadingComponent}
+ ) : error ? (
+
+ ) : (
+
+ )}
);
};
diff --git a/src/routes/routerConfig.tsx b/src/routes/routerConfig.tsx
index bcf5d326fe..0441990f9f 100644
--- a/src/routes/routerConfig.tsx
+++ b/src/routes/routerConfig.tsx
@@ -50,6 +50,7 @@ const commonChildrenRoutes: RouteObject[] = [
{ path: 'contributors', lazy: Contributors },
{ path: 'callback/github', lazy: GitHubCallback },
{ path: 'sicpjs/:section?', lazy: Sicp },
+ { path: 'sicpjs/:param_lang/:section?', lazy: Sicp },
{ path: 'features', lazy: Features }
];