diff --git a/CHANGELOG.md b/CHANGELOG.md index 89f8ec3..b20eef7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/), and this **Table of Contents** - [[Unreleased]](#unreleased) -- [[1.4.2] - (2020-12-04)](#142---2020-12-04) +- [[1.4.2] - (2020-12-18)](#142---2020-12-18) - [[v1.4.1] - (2020-12-03)](#v141---2020-12-03) - [Added](#added) - [Fixed](#fixed) @@ -43,7 +43,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/), and this --- -## [1.4.2] - (2020-12-04) +## [1.4.2] - (2020-12-18) --- diff --git a/website/package-lock.json b/website/package-lock.json index 17ac2cb..ad1122f 100644 --- a/website/package-lock.json +++ b/website/package-lock.json @@ -2614,6 +2614,30 @@ "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", "dev": true }, + "@types/lodash": { + "version": "4.14.165", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.165.tgz", + "integrity": "sha512-tjSSOTHhI5mCHTy/OOXYIhi2Wt1qcbHmuXD1Ha7q70CgI/I71afO4XtLb/cVexki1oVYchpul/TOuu3Arcdxrg==", + "dev": true + }, + "@types/lodash.isequal": { + "version": "4.5.5", + "resolved": "https://registry.npmjs.org/@types/lodash.isequal/-/lodash.isequal-4.5.5.tgz", + "integrity": "sha512-4IKbinG7MGP131wRfceK6W4E/Qt3qssEFLF30LnJbjYiSfHGGRU/Io8YxXrZX109ir+iDETC8hw8QsDijukUVg==", + "dev": true, + "requires": { + "@types/lodash": "*" + } + }, + "@types/lodash.mapvalues": { + "version": "4.6.6", + "resolved": "https://registry.npmjs.org/@types/lodash.mapvalues/-/lodash.mapvalues-4.6.6.tgz", + "integrity": "sha512-Mt9eg3AqwAt5HShuOu8taiIYg0sLl4w3vDi0++E0VtiOtj9DqQHaxVr3wicVop0eDEqr5ENbht7vsLJlkMHL+w==", + "dev": true, + "requires": { + "@types/lodash": "*" + } + }, "@types/minimatch": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", @@ -10599,6 +10623,17 @@ "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", "dev": true }, + "lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=", + "dev": true + }, + "lodash.mapvalues": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz", + "integrity": "sha1-G6+lAF3p3W9PJmaMMMo3IwzJaJw=" + }, "lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", diff --git a/website/package.json b/website/package.json index dd294eb..64bf7b1 100644 --- a/website/package.json +++ b/website/package.json @@ -31,6 +31,7 @@ "@material-ui/icons": "^4.9.1", "@material-ui/lab": "^4.0.0-alpha.56", "@octokit/rest": "^18.0.9", + "lodash.mapvalues": "^4.6.0", "react": "^17.0.1", "react-dom": "^17.0.1", "react-redux": "^7.2.1", @@ -45,16 +46,19 @@ "@testing-library/react": "^11.2.2", "@testing-library/user-event": "^12.5.0", "@types/jest": "^26.0.15", + "@types/lodash.mapvalues": "^4.6.6", "@types/node": "^14.14.10", "@types/react": "^17.0.0", "@types/react-dom": "^17.0.0", "@types/react-redux": "^7.1.9", + "@types/lodash.isequal": "^4.5.5", "@types/react-router-dom": "^5.1.5", "@typescript-eslint/eslint-plugin": "^4.9.0", "@typescript-eslint/parser": "^4.9.0", "react-hot-loader": "^4.12.21", "react-scripts": "4.0.1", "redux-devtools-extension": "^2.13.8", + "lodash.isequal": "^4.5.0", "typescript": "^4.1.2", "web-vitals": "^1.0.1", "workbox-background-sync": "^6.0.2", diff --git a/website/src/App.tsx b/website/src/App.tsx index 12a05f3..5f4bd1f 100644 --- a/website/src/App.tsx +++ b/website/src/App.tsx @@ -5,7 +5,7 @@ import "./markdown.css"; //Redux Imports import { useDispatch } from "react-redux"; -import { getDocs } from "./Redux/thunks"; +import { getAllDocs } from "./Redux/thunks"; //Page Imports import Readme from "./Pages/Readme"; @@ -43,7 +43,7 @@ const App: React.FC = (props) => { const classes = useStyles(); useEffect(() => { - dispatch(getDocs()); + dispatch(getAllDocs()); }); return ( diff --git a/website/src/Components/Header.tsx b/website/src/Components/Header.tsx index 0201ae9..380d819 100644 --- a/website/src/Components/Header.tsx +++ b/website/src/Components/Header.tsx @@ -6,7 +6,7 @@ import { useLocation } from "react-router-dom"; import { useDispatch } from "react-redux"; import { toggleSidebar } from "../Redux/actions"; import { onDemandDataRequest } from "../Redux/thunks"; -import { Page } from "../Redux/thunks/docs.thunks"; +import { DocType } from "../Redux/reducers/docs.reducers"; // Material UI Imports import { @@ -38,13 +38,11 @@ const Header: FC = () => { const root = pathname.split("/")[1]; - let page: Page | undefined = undefined; + let page: DocType | null = null; if (root === "readme" || root === "home" || root === "") page = "readme"; - - if (root === "components") page = "components"; - - if (root === "changelog") page = "changelog"; + else if (root === "components") page = "components"; + else if (root === "changelog") page = "changelog"; const isSizeSmall = useMediaQuery((theme) => theme.breakpoints.down("md") @@ -60,18 +58,16 @@ const Header: FC = () => { )} - {page && ( - - { - dispatch(onDemandDataRequest(page ?? "components")); - }} - > - - - - )} + + { + dispatch(onDemandDataRequest(page)); + }} + > + + + ); diff --git a/website/src/Components/Sidebar.tsx b/website/src/Components/Sidebar.tsx index 7dc211d..10ec651 100644 --- a/website/src/Components/Sidebar.tsx +++ b/website/src/Components/Sidebar.tsx @@ -1,6 +1,7 @@ // React Imports import React, { useState } from "react"; import { Link } from "react-router-dom"; +import isEqual from "lodash.isequal"; //Redux Imports import { useDispatch, useSelector } from "react-redux"; @@ -88,7 +89,8 @@ const SideBar: React.FC = () => { interface ContentsProps {} const Contents: React.FC = () => { - const components = useSelector(getComponents); + const components = useSelector(getComponents, isEqual); + const componentNames = Object.keys(components); const classes = useStyles(); return ( @@ -97,10 +99,10 @@ const Contents: React.FC = () => { - {components && ( + {componentNames.length > 0 && ( ({ + items={componentNames.map((component) => ({ name: component, to: components[component].url, }))} diff --git a/website/src/Pages/Component.tsx b/website/src/Pages/Component.tsx index 9303d5e..76e083c 100644 --- a/website/src/Pages/Component.tsx +++ b/website/src/Pages/Component.tsx @@ -7,7 +7,7 @@ import Alerter from "../Components/Alerter"; //Redux Imports import { useSelector } from "react-redux"; import { - getAreComponentsLoading, + getIsComponentsLoading, getComponents, getIsComponentsError, } from "../Redux/selectors"; @@ -34,7 +34,7 @@ interface ComponentProps {} const Component: FC = () => { const classes = useStyles(); const components = useSelector(getComponents); - const isLoading = useSelector(getAreComponentsLoading); + const isLoading = useSelector(getIsComponentsLoading); const isError = useSelector(getIsComponentsError); const { id } = useParams(); diff --git a/website/src/Redux/actions/docs.actions.ts b/website/src/Redux/actions/docs.actions.ts index 2779573..35d44ac 100644 --- a/website/src/Redux/actions/docs.actions.ts +++ b/website/src/Redux/actions/docs.actions.ts @@ -1,67 +1,31 @@ -import { Components } from "../reducers/docs.reducers"; +import { Components, DocType } from "../reducers/docs.reducers"; -export const LOAD_COMPONENTS_IN_PROGRESS = "LOAD_COMPONENTS_IN_PROGRESS"; -export const loadComponentsInProgress = () => ({ - type: LOAD_COMPONENTS_IN_PROGRESS, - payload: {}, -}); - -export const LOAD_README_IN_PROGRESS = "LOAD_README_IN_PROGRESS"; -export const loadReadmeInProgress = () => ({ - type: LOAD_README_IN_PROGRESS, - payload: {}, -}); - -export const LOAD_CHANGELOG_IN_PROGRESS = "LOAD_CHANGELOG_IN_PROGRESS"; -export const loadChangelogInProgress = () => ({ - type: LOAD_CHANGELOG_IN_PROGRESS, - payload: {}, -}); - -export const LOAD_COMPONENTS_SUCCESS = "LOAD_COMPONENTS_SUCCESS"; -export const loadComponentsSuccess = (components: Components) => ({ - type: LOAD_COMPONENTS_SUCCESS, - payload: { - components, - }, -}); +export const LOAD_DOCS_IN_PROGRESS = "LOAD_DOCS_IN_PROGRESS"; -export const LOAD_README_SUCCESS = "LOAD_README_SUCCESS"; -export const loadReadmeSuccess = (readme: string) => ({ - type: LOAD_README_SUCCESS, +export const loadDocsInProgress = (docType: DocType) => ({ + type: LOAD_DOCS_IN_PROGRESS, payload: { - readme, + docType, }, }); -export const LOAD_CHANGELOG_SUCCESS = "LOAD_CHANGELOG_SUCCESS"; -export const loadChangelogSuccess = (changelog: string) => ({ - type: LOAD_CHANGELOG_SUCCESS, +export const LOAD_DOCS_SUCCESS = "LOAD_DOCS_SUCCESS"; +export const loadDocsSuccess = ( + docType: DocType, + docs: string | Components +) => ({ + type: LOAD_DOCS_SUCCESS, payload: { - changelog, + docType, + docs, }, }); export const LOAD_DOCS_ERROR = "LOAD_DOCS_ERROR"; -export const loadDocsError = (error: string) => ({ +export const loadDocsError = (docType: DocType | null, error: string) => ({ type: LOAD_DOCS_ERROR, - payload: { error }, -}); - -export const LOAD_COMPONENTS_ERROR = "LOAD_COMPONENTS_ERROR"; -export const loadComponentsError = (error: string) => ({ - type: LOAD_COMPONENTS_ERROR, - payload: { error }, -}); - -export const LOAD_README_ERROR = "LOAD_README_ERROR"; -export const loadReadmeError = (error: string) => ({ - type: LOAD_README_ERROR, - payload: { error }, -}); - -export const LOAD_CHANGELOG_ERROR = "LOAD_CHANGELOG_ERROR"; -export const loadChangelogError = (error: string) => ({ - type: LOAD_CHANGELOG_ERROR, - payload: { error }, + payload: { + docType, + error, + }, }); diff --git a/website/src/Redux/actions/index.ts b/website/src/Redux/actions/index.ts index 8865097..0a4803b 100644 --- a/website/src/Redux/actions/index.ts +++ b/website/src/Redux/actions/index.ts @@ -1,27 +1,13 @@ export { //In Progress - LOAD_COMPONENTS_IN_PROGRESS, - loadComponentsInProgress, - LOAD_README_IN_PROGRESS, - loadReadmeInProgress, - LOAD_CHANGELOG_IN_PROGRESS, - loadChangelogInProgress, + LOAD_DOCS_IN_PROGRESS, + loadDocsInProgress, //Success - LOAD_COMPONENTS_SUCCESS, - loadComponentsSuccess, - LOAD_CHANGELOG_SUCCESS, - loadChangelogSuccess, - LOAD_README_SUCCESS, - loadReadmeSuccess, + LOAD_DOCS_SUCCESS, + loadDocsSuccess, //Error LOAD_DOCS_ERROR, loadDocsError, - LOAD_COMPONENTS_ERROR, - loadComponentsError, - LOAD_README_ERROR, - loadReadmeError, - LOAD_CHANGELOG_ERROR, - loadChangelogError, } from "./docs.actions"; export { TOGGLE_SIDEBAR, toggleSidebar } from "./display.actions"; export { diff --git a/website/src/Redux/reducers/docs.reducers.ts b/website/src/Redux/reducers/docs.reducers.ts index a2d0512..1496039 100644 --- a/website/src/Redux/reducers/docs.reducers.ts +++ b/website/src/Redux/reducers/docs.reducers.ts @@ -1,14 +1,8 @@ import { AnyAction } from "redux"; +import mapValues from "lodash.mapvalues"; import { - LOAD_COMPONENTS_IN_PROGRESS, - LOAD_README_IN_PROGRESS, - LOAD_CHANGELOG_IN_PROGRESS, - LOAD_COMPONENTS_SUCCESS, - LOAD_CHANGELOG_SUCCESS, - LOAD_README_SUCCESS, - LOAD_COMPONENTS_ERROR, - LOAD_README_ERROR, - LOAD_CHANGELOG_ERROR, + LOAD_DOCS_IN_PROGRESS, + LOAD_DOCS_SUCCESS, LOAD_DOCS_ERROR, } from "../actions"; @@ -19,28 +13,42 @@ export interface Component { export type Components = Record; +export type DocType = "components" | "readme" | "changelog"; + +export const DOC_TYPES: DocType[] = ["components", "readme", "changelog"]; + export type DocsState = { - components?: Components; - readme?: string; - changelog?: string; - areComponentsLoading: boolean; - isReadmeLoading: boolean; - isChangelogLoading: boolean; - isComponentsError: boolean | string; - isReadmeError: boolean | string; - isChangelogError: boolean | string; - lastComponentsUpdate?: number; - lastReadmeUpdate?: number; - lastChangelogUpdate?: number; + info: { + components: Components; + readme: string; + changelog: string; + }; + loading: Record; + errors: Record; + updates: Record; }; export const initialDocsState: DocsState = { - areComponentsLoading: false, - isReadmeLoading: false, - isChangelogLoading: false, - isComponentsError: false, - isReadmeError: false, - isChangelogError: false, + info: { + components: {}, + readme: "", + changelog: "", + }, + loading: { + components: false, + readme: false, + changelog: false, + }, + errors: { + components: false, + readme: false, + changelog: false, + }, + updates: { + components: undefined, + readme: undefined, + changelog: undefined, + }, }; export const docsReducer = ( @@ -49,88 +57,56 @@ export const docsReducer = ( ): DocsState => { const { type, payload } = action; switch (type) { - case LOAD_COMPONENTS_IN_PROGRESS: { - return { - ...state, - areComponentsLoading: true, - }; - } - case LOAD_README_IN_PROGRESS: { - return { - ...state, - isReadmeLoading: true, - }; - } - case LOAD_CHANGELOG_IN_PROGRESS: { - return { - ...state, - isChangelogLoading: true, - }; - } - case LOAD_COMPONENTS_SUCCESS: { - const { components } = payload; - return { - ...state, - components, - areComponentsLoading: false, - lastComponentsUpdate: Date.now(), - isComponentsError: false, - }; - } - case LOAD_README_SUCCESS: { - const { readme } = payload; + case LOAD_DOCS_IN_PROGRESS: { + const { docType } = payload; return { ...state, - readme, - isReadmeLoading: false, - lastReadmeUpdate: Date.now(), - isReadmeError: false, + loading: { + ...state.loading, + [docType]: true, + }, }; } - case LOAD_CHANGELOG_SUCCESS: { - const { changelog } = payload; + case LOAD_DOCS_SUCCESS: { + const { docType, docs } = payload; return { ...state, - changelog, - isChangelogLoading: false, - lastChangelogUpdate: Date.now(), - isChangelogError: false, + info: { + ...state.info, + [docType]: docs, + }, + errors: { + ...state.errors, + [docType]: false, + }, + updates: { + ...state.updates, + [docType]: Date.now(), + }, + loading: { + ...state.loading, + [docType]: false, + }, }; } case LOAD_DOCS_ERROR: { - const { error } = payload; - return { - ...state, - isComponentsError: error, - areComponentsLoading: false, - isReadmeError: error, - isReadmeLoading: false, - isChangelogError: error, - isChangelogLoading: false, - }; - } - case LOAD_COMPONENTS_ERROR: { - const { error } = payload; - return { - ...state, - isComponentsError: error, - isChangelogLoading: false, - }; - } - case LOAD_README_ERROR: { - const { error } = payload; - return { - ...state, - isReadmeError: error, - isReadmeLoading: false, - }; - } - case LOAD_CHANGELOG_ERROR: { - const { error } = payload; + const { docType, error } = payload; return { ...state, - isChangelogError: error, - isChangelogLoading: false, + errors: + docType === null + ? mapValues(state.errors, () => error) + : { + ...state.errors, + [docType]: error, + }, + loading: + docType === null + ? mapValues(state.loading, () => false) + : { + ...state.loading, + [docType]: false, + }, }; } default: { diff --git a/website/src/Redux/reducers/snackbar.reducers.ts b/website/src/Redux/reducers/snackbar.reducers.ts index 03716ea..151cfd1 100644 --- a/website/src/Redux/reducers/snackbar.reducers.ts +++ b/website/src/Redux/reducers/snackbar.reducers.ts @@ -2,9 +2,6 @@ import { AnyAction } from "redux"; import { SET_SNACKBAR_MESSAGE, HANDLE_SNACKBAR_CLOSE, - LOAD_COMPONENTS_ERROR, - LOAD_README_ERROR, - LOAD_CHANGELOG_ERROR, LOAD_DOCS_ERROR, } from "../actions"; import { Color } from "@material-ui/lab"; @@ -34,9 +31,6 @@ export const snackbarReducer = ( case HANDLE_SNACKBAR_CLOSE: { return { ...state, isOpen: false }; } - case LOAD_COMPONENTS_ERROR: - case LOAD_README_ERROR: - case LOAD_CHANGELOG_ERROR: case LOAD_DOCS_ERROR: { const { error } = payload; return { diff --git a/website/src/Redux/selectors/docs.selectors.ts b/website/src/Redux/selectors/docs.selectors.ts index 4d87ec6..ad3b1a3 100644 --- a/website/src/Redux/selectors/docs.selectors.ts +++ b/website/src/Redux/selectors/docs.selectors.ts @@ -1,24 +1,23 @@ import { State } from "../reducers"; -export const getComponents = (state: State) => state.docs.components; -export const getReadme = (state: State) => state.docs.readme; -export const getChangelog = (state: State) => state.docs.changelog; +export const getComponents = (state: State) => state.docs.info.components; +export const getReadme = (state: State) => state.docs.info.readme; +export const getChangelog = (state: State) => state.docs.info.changelog; -export const getAreComponentsLoading = (state: State) => - state.docs.areComponentsLoading; -export const getIsReadmeLoading = (state: State) => state.docs.isReadmeLoading; +export const getIsComponentsLoading = (state: State) => + state.docs.loading.components; +export const getIsReadmeLoading = (state: State) => state.docs.loading.readme; export const getIsChangelogLoading = (state: State) => - state.docs.isReadmeLoading; + state.docs.loading.changelog; export const getIsComponentsError = (state: State) => - state.docs.isComponentsError; -export const getIsReadmeError = (state: State) => state.docs.isReadmeError; + state.docs.errors.components; +export const getIsReadmeError = (state: State) => state.docs.errors.readme; export const getIsChangelogError = (state: State) => - state.docs.isChangelogError; + state.docs.errors.changelog; export const getLastComponentsUpdate = (state: State) => - state.docs.lastComponentsUpdate; -export const getLastReadmeUpdate = (state: State) => - state.docs.lastReadmeUpdate; + state.docs.updates.components; +export const getLastReadmeUpdate = (state: State) => state.docs.updates.readme; export const getLastChangelogUpdate = (state: State) => - state.docs.lastChangelogUpdate; + state.docs.updates.changelog; diff --git a/website/src/Redux/selectors/index.ts b/website/src/Redux/selectors/index.ts index cb4765e..3a86901 100644 --- a/website/src/Redux/selectors/index.ts +++ b/website/src/Redux/selectors/index.ts @@ -2,7 +2,7 @@ export { getComponents, getReadme, getChangelog, - getAreComponentsLoading, + getIsComponentsLoading, getIsReadmeLoading, getIsChangelogLoading, getIsComponentsError, diff --git a/website/src/Redux/thunks/docs.thunks.ts b/website/src/Redux/thunks/docs.thunks.ts index 39e604a..8073bfc 100644 --- a/website/src/Redux/thunks/docs.thunks.ts +++ b/website/src/Redux/thunks/docs.thunks.ts @@ -1,24 +1,16 @@ import { Octokit } from "@octokit/rest"; -import { ReposGetContentResponseData } from "@octokit/types"; +import { Dispatch } from "react"; +import { AnyAction } from "redux"; +import { ThunkAction } from "redux-thunk"; + +import { State } from "../reducers"; +import { Components, DocType, DOC_TYPES } from "../reducers/docs.reducers"; import { loadDocsError, - loadChangelogError, - loadChangelogInProgress, - loadChangelogSuccess, - loadComponentsError, - loadComponentsInProgress, - loadComponentsSuccess, - loadReadmeError, - loadReadmeInProgress, - loadReadmeSuccess, setSnackbarMessage, + loadDocsInProgress, + loadDocsSuccess, } from "../actions"; - -import { Dispatch } from "react"; -import { AnyAction } from "redux"; -import { State } from "../reducers"; -import { Components } from "../reducers/docs.reducers"; -import { ThunkAction } from "redux-thunk"; import { getIsChangelogError, getIsComponentsError, @@ -27,8 +19,9 @@ import { getLastComponentsUpdate, getLastReadmeUpdate, } from "../selectors"; +import { capitalize } from "@material-ui/core"; -export const getDocs = () => async ( +export const getAllDocs = () => async ( dispatch: Dispatch>, getState: () => State ) => { @@ -50,142 +43,102 @@ export const getDocs = () => async ( dispatch(getComponentsRequest()); if (!lastReadmeUpdate || getDiff(lastReadmeUpdate) > 24) - dispatch(getReadmeRequest()); + dispatch(getDocs("readme")); if (!lastChangelogUpdate || getDiff(lastChangelogUpdate) > 24) - dispatch(getChangelogRequest()); + dispatch(getDocs("changelog")); } catch (e) { - dispatch(loadDocsError("Docs could not be fetched. Please try again")); + dispatch( + loadDocsError(null, "Docs could not be fetched. Please try again") + ); } }; -export const getComponentsRequest = () => async ( +export const getDocs = (docType: DocType) => async ( dispatch: Dispatch>, getState: () => State ) => { try { - dispatch(loadComponentsInProgress()); + if (docType === "components") { + return dispatch(getComponentsRequest()); + } + dispatch(loadDocsInProgress(docType)); + const octokit = new Octokit(); - const { data: componentsData } = await octokit.repos.getContent({ + const { data } = await octokit.repos.getContent({ owner: "YashTotale", repo: "react-hash-scroll", - path: "docs/Components", + path: docType === "readme" ? "README.md" : "CHANGELOG.md", }); - const components: Components = {}; - - for (const component of (componentsData as unknown) as ReposGetContentResponseData[]) { - const { name, download_url } = component; + const res = await fetch(data.download_url); + const text = await res.text(); + const docs = await markdownToHtml(text); - const res = await fetch(download_url); - const text = await res.text(); - - const id = name.slice(0, -3); - - const { data: html } = await octokit.markdown.render({ - text, - mode: "gfm", - context: "YashTotale/react-hash-scroll", - mediaType: { format: "html" }, - }); - - components[id] = { - text: html, - url: id.toLowerCase(), - }; - } - - dispatch(loadComponentsSuccess(components)); + dispatch(loadDocsSuccess(docType, docs)); } catch (e) { dispatch( - loadComponentsError("Components could not be fetched. Please try again") + loadDocsError( + docType, + `${capitalize(docType)} could not be fetched. Please try again` + ) ); } }; -export const getReadmeRequest = () => async ( +const getComponentsRequest = () => async ( dispatch: Dispatch>, getState: () => State ) => { try { - dispatch(loadReadmeInProgress()); + dispatch(loadDocsInProgress("components")); const octokit = new Octokit(); - const { data: readmeData } = await octokit.repos.getContent({ + const { data } = await octokit.repos.getContent({ owner: "YashTotale", repo: "react-hash-scroll", - path: "README.md", + path: "docs/Components", }); - const readmeRes = await fetch(readmeData.download_url); - const readmeText = await readmeRes.text(); - const { data: readme } = await octokit.markdown.render({ - text: readmeText, - mode: "gfm", - context: "YashTotale/react-hash-scroll", - mediaType: { format: "html" }, - }); + const components: Components = {}; - dispatch(loadReadmeSuccess(readme)); - } catch (e) { - dispatch(loadReadmeError("README could not be fetched. Please try again")); - } -}; + ((data as unknown) as typeof data[]).forEach(async (component) => { + const { name, download_url } = component; -export const getChangelogRequest = () => async ( - dispatch: Dispatch>, - getState: () => State -) => { - try { - dispatch(loadChangelogInProgress()); - const octokit = new Octokit(); + const res = await fetch(download_url); + const text = await res.text(); - const { data: changelogData } = await octokit.repos.getContent({ - owner: "YashTotale", - repo: "react-hash-scroll", - path: "CHANGELOG.md", - }); + const html = await markdownToHtml(text); + + const id = name.slice(0, -3); - const changelogRes = await fetch(changelogData.download_url); - const changelogText = await changelogRes.text(); - const { data: changelog } = await octokit.markdown.render({ - text: changelogText, - mode: "gfm", - context: "YashTotale/react-hash-scroll", - mediaType: { format: "html" }, + components[id] = { + text: html, + url: id.toLowerCase(), + }; }); - dispatch(loadChangelogSuccess(changelog)); + dispatch(loadDocsSuccess("components", components)); } catch (e) { dispatch( - loadChangelogError("Changelog could not be fetched. Please try again") + loadDocsError( + "components", + "Components could not be fetched. Please try again" + ) ); } }; -export type Page = "readme" | "changelog" | "components"; - -export const onDemandDataRequest = (page: Page) => async ( +export const onDemandDataRequest = (page: DocType | null) => async ( dispatch: Dispatch>, getState: () => State ) => { - let getLastUpdate; - let request; - let errored; - if (page === "readme") { - getLastUpdate = getLastReadmeUpdate; - request = getReadmeRequest; - errored = getIsReadmeError; - } else if (page === "changelog") { - getLastUpdate = getLastChangelogUpdate; - request = getChangelogRequest; - errored = getIsChangelogError; - } else { - getLastUpdate = getLastComponentsUpdate; - request = getComponentsRequest; - errored = getIsComponentsError; - } + if (page === null) + return DOC_TYPES.forEach((docType) => onDemandDataRequest(docType)); + + const { docRequest, getLastUpdate, isError } = getFuncsForDocType(page); + try { const lastUpdated = getLastUpdate(getState()); @@ -197,7 +150,7 @@ export const onDemandDataRequest = (page: Page) => async ( const diffInMinutes = diff / (1000 * 60); - if (diffInMinutes < 10 && !errored(getState())) { + if (diffInMinutes < 10 && !isError(getState())) { throw new Error( `Please wait at least 10 minutes between requests (${( 10 - diffInMinutes @@ -205,9 +158,48 @@ export const onDemandDataRequest = (page: Page) => async ( ); } - dispatch(request()); + dispatch(docRequest); } } catch (e) { dispatch(setSnackbarMessage(e.message, "error")); } }; + +const markdownToHtml = async (md: string) => { + const octokit = new Octokit(); + + const { data } = await octokit.markdown.render({ + text: md, + mode: "gfm", + context: "YashTotale/react-hash-scroll", + mediaType: { format: "html" }, + }); + + return data; +}; + +const getFuncsForDocType = (docType: DocType) => { + switch (docType) { + case "readme": { + return { + getLastUpdate: getLastReadmeUpdate, + docRequest: getDocs("readme"), + isError: getIsReadmeError, + }; + } + case "components": { + return { + getLastUpdate: getLastComponentsUpdate, + docRequest: getDocs("components"), + isError: getIsComponentsError, + }; + } + case "changelog": { + return { + getLastUpdate: getLastChangelogUpdate, + docRequest: getDocs("changelog"), + isError: getIsChangelogError, + }; + } + } +}; diff --git a/website/src/Redux/thunks/index.ts b/website/src/Redux/thunks/index.ts index d20dfd2..4f6997a 100644 --- a/website/src/Redux/thunks/index.ts +++ b/website/src/Redux/thunks/index.ts @@ -1,7 +1 @@ -export { - getDocs, - getChangelogRequest, - getComponentsRequest, - getReadmeRequest, - onDemandDataRequest, -} from "./docs.thunks"; +export { getDocs, onDemandDataRequest, getAllDocs } from "./docs.thunks";