Skip to content

Commit

Permalink
refactor: various fixes, and code quality improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
icyJoseph committed Jul 8, 2020
1 parent 1f40226 commit cbdde42
Show file tree
Hide file tree
Showing 11 changed files with 130 additions and 51 deletions.
37 changes: 20 additions & 17 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ ReactGA.initialize("UA-170794768-1", {

class App extends React.Component {
state = {
currentPage: SECTION_NAMES.LandingPage,
showPoseMessage: false,
showInfo: false,
info: {},
Expand All @@ -40,25 +39,29 @@ class App extends React.Component {

onPageLoad = pageName => {
ReactGA.pageview(window.location.pathname + window.location.search)
this.setState({ currentPage: pageName })

if (pageName === SECTION_NAMES.landingPage) {
this.setState({
currentPage: pageName,
return this.setState({
showInfo: false,
showPoseMessage: false,
})
return
}

this.setState({
currentPage: pageName,
showInfo: false,
showPoseMessage: false,
hexapodParams: { ...this.state.hexapodParams, pose: defaults.DEFAULT_POSE },
})

this.updatePlot(this.state.hexapodParams.dimensions, defaults.DEFAULT_POSE)
return this.setState(
{
showInfo: false,
showPoseMessage: false,
hexapodParams: {
...this.state.hexapodParams,
pose: defaults.DEFAULT_POSE,
},
},
() =>
this.updatePlot(
this.state.hexapodParams.dimensions,
defaults.DEFAULT_POSE
)
)
}

/* * * * * * * * * * * * * *
Expand All @@ -67,7 +70,7 @@ class App extends React.Component {

updatePlot = (dimensions, pose) => {
const newHexapodModel = new VirtualHexapod(dimensions, pose)
this.updatePlotWithHexapod(newHexapodModel)
return this.updatePlotWithHexapod(newHexapodModel)
}

updatePlotWithHexapod = hexapod => {
Expand All @@ -76,7 +79,7 @@ class App extends React.Component {
}

const [data, layout] = getNewPlotParams(hexapod, this.state.plot.latestCameraView)
this.setState({
return this.setState({
plot: {
...this.state.plot,
data,
Expand All @@ -93,7 +96,7 @@ class App extends React.Component {
logCameraView = relayoutData => {
const newCameraView = relayoutData["scene.camera"]
const plot = { ...this.state.plot, latestCameraView: newCameraView }
this.setState({ ...this.state, plot: plot })
return this.setState({ ...this.state, plot: plot })
}

/* * * * * * * * * * * * * *
Expand All @@ -102,7 +105,7 @@ class App extends React.Component {

updateIk = (hexapod, updatedStateParams) => {
this.updatePlotWithHexapod(hexapod)
this.setState({ ...updatedStateParams })
return this.setState({ ...updatedStateParams })
}

updateDimensions = dimensions =>
Expand Down
2 changes: 1 addition & 1 deletion src/components/Nav.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,6 @@ const NavDetailed = React.memo(() => (
</footer>
))

const Nav = React.memo(() => <NavBullets />)
const Nav = NavBullets

export { Nav, NavDetailed }
11 changes: 10 additions & 1 deletion src/components/pages/ForwardKinematicsPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import LegPoseWidget from "./LegPoseWidgets"
import { Card, ToggleSwitch, BasicButton, NumberInputField, Slider } from "../generic"
import { DEFAULT_POSE } from "../../templates"
import { SECTION_NAMES, LEG_NAMES, RESET_LABEL } from "../vars"
import { usePageLoad, useUpdatePose } from "../providers/Handlers"

const renderTwoColumns = cells => (
<>
Expand Down Expand Up @@ -97,4 +98,12 @@ class ForwardKinematicsPage extends Component {
}
}

export default ForwardKinematicsPage
const WithHandlers = props => {
const onMount = usePageLoad()
const onUpdate = useUpdatePose()
return <ForwardKinematicsPage {...props} onMount={onMount} onUpdate={onUpdate} />
}

WithHandlers.displayName = "WithHandlers(ForwardKinematicsPage)"

export default WithHandlers
11 changes: 10 additions & 1 deletion src/components/pages/InverseKinematicsPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { sliderList, Card, BasicButton } from "../generic"
import { solveInverseKinematics } from "../../hexapod"
import { SECTION_NAMES, IK_SLIDERS_LABELS, RESET_LABEL } from "../vars"
import { DEFAULT_IK_PARAMS } from "../../templates"
import { usePageLoad, useUpdateIk } from "../providers/Handlers"

const _updatedStateParamsUnsolved = message => ({
showPoseMessage: false,
Expand Down Expand Up @@ -72,4 +73,12 @@ class InverseKinematicsPage extends Component {
}
}

export default InverseKinematicsPage
const WithHandlers = props => {
const onMount = usePageLoad()
const onUpdate = useUpdateIk()
return <InverseKinematicsPage {...props} onMount={onMount} onUpdate={onUpdate} />
}

WithHandlers.displayName = "WithHandlers(InverseKinematicsPage)"

export default WithHandlers
9 changes: 6 additions & 3 deletions src/components/pages/LandingPage.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import React, { useLayoutEffect } from "react"
import { NavDetailed } from ".."
import { LANDING_PAGE_TITLE, LANDING_PAGE_SUBTITLE, SECTION_NAMES } from "../vars"
import { usePageLoad } from "../providers/Handlers"

function LandingPage() {
const onPageLoad = usePageLoad()

function LandingPage({ onMount }) {
useLayoutEffect(() => {
onMount(SECTION_NAMES.landingPage)
}, [onMount])
onPageLoad(SECTION_NAMES.landingPage)
}, [onPageLoad])

return (
<>
Expand Down
11 changes: 10 additions & 1 deletion src/components/pages/LegPatternPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { Component } from "react"
import { sliderList, Card, BasicButton } from "../generic"
import { DEFAULT_POSE, DEFAULT_PATTERN_PARAMS } from "../../templates"
import { SECTION_NAMES, ANGLE_NAMES, RESET_LABEL } from "../vars"
import { usePageLoad, useUpdatePose } from "../providers/Handlers"

class LegPatternPage extends Component {
pageName = SECTION_NAMES.legPatterns
Expand Down Expand Up @@ -45,4 +46,12 @@ class LegPatternPage extends Component {
)
}

export default LegPatternPage
const WithHandlers = props => {
const onMount = usePageLoad()
const onUpdate = useUpdatePose()
return <LegPatternPage {...props} onMount={onMount} onUpdate={onUpdate} />
}

WithHandlers.displayName = "WithHandlers(LegPatternPage)"

export default WithHandlers
12 changes: 11 additions & 1 deletion src/components/pages/WalkingGaitsPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { sliderList, Card, BasicButton, ToggleSwitch } from "../generic"
import { SECTION_NAMES, RESET_LABEL } from "../vars"
import getWalkSequence from "../../hexapod/solvers/walkSequenceSolver"

import { usePageLoad, useUpdatePose } from "../providers/Handlers"

const SLIDER_LABELS = [
"tz",
"tx",
Expand Down Expand Up @@ -179,4 +181,12 @@ class WalkingGaitsPage extends Component {
}
}

export default WalkingGaitsPage
const WithHandlers = props => {
const onMount = usePageLoad()
const onUpdate = useUpdatePose()
return <WalkingGaitsPage {...props} onMount={onMount} onUpdate={onUpdate} />
}

WithHandlers.displayName = "WithHandlers(WalkingGaitsPage)"

export default WithHandlers
37 changes: 37 additions & 0 deletions src/components/providers/Handlers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React, { createContext, useContext, useMemo } from "react"

const HandlersCtx = createContext()

export function HandlersProvider({
onPageLoad,
updateIk,
updatePose,
updateDimensions,
children,
}) {
const value = useMemo(
() => ({
onPageLoad,
updateIk,
updatePose,
updateDimensions,
}),
[onPageLoad, updateIk, updatePose, updateDimensions]
)
return <HandlersCtx.Provider value={value}>{children}</HandlersCtx.Provider>
}

export const usePageLoad = () => {
const { onPageLoad } = useContext(HandlersCtx)
return useMemo(() => onPageLoad, [onPageLoad])
}

export const useUpdatePose = () => {
const { updatePose } = useContext(HandlersCtx)
return useMemo(() => updatePose, [updatePose])
}

export const useUpdateIk = () => {
const { updateIk } = useContext(HandlersCtx)
return useMemo(() => updateIk, [updateIk])
}
1 change: 1 addition & 0 deletions src/components/vars.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ const HEXAPOD_LINK_PATHS = [
PATHS.inverseKinematics.path,
PATHS.forwardKinematics.path,
PATHS.legPatterns.path,
PATHS.walkingGaits.path,
]

const URL_LINKS = [KOFI_LINK_PROPERTIES, REPO_LINK_PROPERTIES]
Expand Down
23 changes: 11 additions & 12 deletions src/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ import {
SuspenseHexapodPlot,
} from "./loadables"

import { HandlersProvider } from "./components/providers/Handlers"

export const Routes = ({
onPageLoad,
showPoseMessage,
showInfo,
info,
Expand All @@ -24,14 +25,20 @@ export const Routes = ({
hexapodParams,
patternParams,
ikParams,
onPageLoad,
updateIk,
updatePose,
updateDimensions,
onRelayout,
}) => {
const { path } = useRouteMatch()
return (
<>
<HandlersProvider
onPageLoad={onPageLoad}
updateIk={updateIk}
updatePose={updatePose}
updateDimensions={updateDimensions}
>
<div className="main content">
<div className="sidebar column-container cell">
<Route path={HEXAPOD_LINK_PATHS} exact>
Expand All @@ -44,13 +51,11 @@ export const Routes = ({
</Route>
<Switch>
<Route path="/" exact>
<SuspenseLandingPage onMount={onPageLoad} />
<SuspenseLandingPage />
</Route>
<Route path={PATHS.forwardKinematics.path}>
<SuspenseForwardKinematicsPage
params={{ pose: hexapodParams.pose }}
onUpdate={updatePose}
onMount={onPageLoad}
/>
</Route>
<Route path={PATHS.inverseKinematics.path}>
Expand All @@ -59,24 +64,18 @@ export const Routes = ({
dimensions: hexapodParams.dimensions,
ikParams: ikParams,
}}
onUpdate={updateIk}
onMount={onPageLoad}
/>
</Route>
<Route path={PATHS.legPatterns.path}>
<SuspenseLegPatternPage
params={{ patternParams: patternParams }}
onUpdate={updatePose}
onMount={onPageLoad}
/>
</Route>
<Route path={PATHS.walkingGaits.path}>
<SuspenseWalkingGaitsPage
params={{
dimensions: hexapodParams.dimensions,
}}
onUpdate={updatePose}
onMount={onPageLoad}
/>
</Route>
</Switch>
Expand All @@ -98,7 +97,7 @@ export const Routes = ({
<Route path={HEXAPOD_LINK_PATHS} exact>
<NavDetailed />
</Route>
</>
</HandlersProvider>
)
}

Expand Down
27 changes: 13 additions & 14 deletions src/tests/components/App.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from "react"
import { render, screen, fireEvent, act } from "@testing-library/react"
import { render, screen, fireEvent, act, waitFor } from "@testing-library/react"
import App from "../../App"
import { PATH_LINKS, URL_LINKS } from "../../components/vars"

Expand Down Expand Up @@ -145,7 +145,12 @@ const expectEachPage = (
expectToHaveNav()
}

const click = name => fireEvent.click(screen.getByRole("link", { name }))
const click = async name => {
const element = await waitFor(() => screen.getByRole("link", { name }))
await act(async () => {
await fireEvent.click(element)
})
}

/* * * *
Application
Expand All @@ -159,33 +164,27 @@ describe("App", () => {
})

test("Navigates to Leg Patterns page", async () => {
await act(async () => {
click("Leg Patterns")
})
await click("Leg Patterns")
expectEachPage()
expectToHaveDefaultLegPatternsPage()
})

test("Navigates to Inverse Kinematics page", async () => {
await act(async () => {
click("Inverse Kinematics")
})
await click("Inverse Kinematics")

expectEachPage()
expectToHaveDefaultInverseKinematics()
})

test("Navigates to Forward Kinematics page", async () => {
await act(async () => {
click("Forward Kinematics")
})
await click("Forward Kinematics")

expectEachPage({ numberOfResetButtons: 2, numberOfToggleSwitches: 2 })
expectToHaveDefaultForwardKinematics()
})

test("Navigates to Landing Page", async () => {
await act(async () => {
click("Root")
})
await click("Root")

const heading = screen.getByRole("heading", {
name: "Mithi's Bare Minimum Hexapod Robot Simulator",
Expand Down

0 comments on commit cbdde42

Please sign in to comment.