Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 29 additions & 2 deletions dark-mode/src/common/containers/App.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,32 @@
import React from 'react';
import React, { useContext, useReducer, useLayoutEffect } from 'react';
import ThemeContext from '../../context';

import themeReducer from '../../reducer';

const DARK_MODE_CLASS = 'dark-mode';

export default function App({ children }) {
return children;
const initialState = useContext(ThemeContext);
const [state, dispatch] = useReducer(themeReducer, initialState);

const {
theme,
} = state;

useLayoutEffect(() => {
switch (theme) {
case 'dark':
document.getElementById('root').classList.add(DARK_MODE_CLASS);
break;
default:
document.getElementById('root').classList.remove(DARK_MODE_CLASS);
break;
}
}, [theme]);

return (
<ThemeContext.Provider value={{ state, dispatch}}>
{children}
</ThemeContext.Provider>
)
}
7 changes: 7 additions & 0 deletions dark-mode/src/context.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import React from 'react';

const initialState = {theme: 'light'};

const ThemeContext = React.createContext(initialState);

export default ThemeContext;
15 changes: 15 additions & 0 deletions dark-mode/src/reducer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const initialState = {
theme: 'light',
};

export default function themeReducer({theme}, action) {
switch (action.type) {
case "SET_THEME":
return {
theme: theme === 'light' ? 'dark' : 'light',
};

default:
return initialState;
}
}
35 changes: 31 additions & 4 deletions dark-mode/src/routes/App/components/App.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,33 @@
import React from 'react';
import React, { useContext } from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faMoon } from '@fortawesome/free-solid-svg-icons';
import { faMoon, faSun } from '@fortawesome/free-solid-svg-icons';
import '../styles/_app.scss';

import ThemeContext from '../../../context';

const themeMap = {
dark: {
color: '#FFA500',
iconType: faSun,
},
light: {
color: null,
iconType: faMoon,
}
}


function App() {
const {dispatch, state} = useContext(ThemeContext);

const {
theme,
} = state;

const handleThemePicker = () => {
dispatch({type: "SET_THEME"})
}

return (
<div className="app">
<div className="level">
Expand All @@ -12,8 +36,11 @@ function App() {
</div>

{/* --The button that should toggle dark mode-- */}
<button className="app__dark-mode-btn icon level-right">
<FontAwesomeIcon icon={faMoon} />
<button
className="app__dark-mode-btn icon level-right"
onClick={handleThemePicker}
>
<FontAwesomeIcon color={themeMap[theme].color} icon={themeMap[theme].iconType} />
</button>

</div>
Expand Down
22 changes: 18 additions & 4 deletions rocket-ship/src/routes/LaunchPad/components/LaunchPad.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,27 @@
import React, { useState } from 'react';
import React, { useState, useLayoutEffect } from 'react';
import '../styles/_launchpad.scss';

export default function LaunchPad({Rocket}) {
const [rerenderCount, triggerRerender] = useState(0);
setTimeout(() => { triggerRerender(rerenderCount + 1); }, 500);
const [start, setStart] = useState(false);

useLayoutEffect(() => {
if (rerenderCount < 10) {
setTimeout(() => { triggerRerender(rerenderCount + 1); }, 500);
}
}, [rerenderCount])

function handleLaunch() {
setStart(true);
if (rerenderCount >= 10) {
triggerRerender(0);
}
}

return (
<div className="launchpad">
<Rocket />
<button onClick={handleLaunch}>Launch</button>
<Rocket start={start} />
</div>
);
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import React, { useState, Component } from 'react';
import RocketCore from './RocketCore';

export function FunctionalRocket() {
const [initialLaunchTime] = useState(Date.now());

export function FunctionalRocket({start}) {
const [initialLaunchTime, setInitialLaunchTime] = useState(Date.now());

React.useLayoutEffect(() => {
if(start) {
setInitialLaunchTime(Date.now());
}
}, [start])

return <RocketCore initialLaunchTime={initialLaunchTime} />;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ const FINAL_POSITION_BOTTOM_VAL = 'calc(400px)';
function timeToPositionPercent(startTime) {
const now = Date.now();
const timeDiff = now - startTime;

if (timeDiff >= MS_TO_TAKEOFF) { return FINAL_POSITION_BOTTOM_VAL; }

return `calc(300px + ${((timeDiff / MS_TO_TAKEOFF) * 100).toFixed(0)}%)`;
}

function generateEmptyListEls(quantity) {
return [...Array(quantity)].map(() => <li />);
return [...Array(quantity)].map((q, index) => <li key={index} />);
}

export default function RocketCore({ initialLaunchTime }) {
Expand Down