Skip to content

Commit

Permalink
detypescriptify
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisrzhou committed Aug 9, 2020
1 parent 6cfcf4a commit 222e82a
Show file tree
Hide file tree
Showing 27 changed files with 282 additions and 391 deletions.
5 changes: 2 additions & 3 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,12 @@ module.exports = {
'plugin:react/recommended',
'plugin:@typescript-eslint/recommended',
'prettier',
'prettier/@typescript-eslint',
],
parser: '@typescript-eslint/parser',
plugins: [
'@typescript-eslint',
'prettier',
],
rules: {
'@typescript-eslint/explicit-function-return-type': 'off',
'prettier/prettier': [
'error',
{
Expand All @@ -23,6 +21,7 @@ module.exports = {
useTabs: false,
},
],
'react/prop-types': 'off',
},
settings: {
react: {
Expand Down
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"crawl": "npm run untrack && babel-node ./src/data/crawl.js",
"build": "npm run clean && npm run crawl && react-scripts build",
"clean": "rm -rf build",
"lint": "eslint --ext .js,.jsx,.ts,.tsx, --fix src",
"lint": "eslint --fix .",
"start": "react-scripts start",
"untrack": "git update-index --assume-unchanged ./src/data/data.json"
},
Expand All @@ -40,7 +40,6 @@
"react-dom": "^16.8.6",
"react-globe": "^5.0.1",
"react-scripts": "3.4.1",
"react-spring": "^8.0.19",
"three": "^0.119.1",
"typescript": "^3.4.4"
},
Expand Down
17 changes: 6 additions & 11 deletions src/components/About.tsx → src/components/About.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
import React from 'react';

import Blur from './ui/Blur';
import Button from './ui/Button';
import Link from './ui/Link';
import Fade from './Fade';
import Button from './Button';
import Link from './Link';

interface Props {
onHide: () => void;
shown: boolean;
}

function About({ onHide, shown }: Props): React.ReactElement {
function About({ onHide, shown }) {
return (
<Blur className="about" shown={shown}>
<Fade className="about" shown={shown}>
<div className="about-content">
<h2>About</h2>
<p>
Expand Down Expand Up @@ -48,7 +43,7 @@ function About({ onHide, shown }: Props): React.ReactElement {
</p>
<Button label="Back" onClick={onHide} />
</div>
</Blur>
</Fade>
);
}

Expand Down
2 changes: 1 addition & 1 deletion src/components/App.tsx → src/components/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Globe from './Globe';
import Intro from './Intro';
import Overlay from './Overlay';

function App(): React.ReactElement {
function App() {
return (
<>
<Globe />
Expand Down
11 changes: 11 additions & 0 deletions src/components/Button.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from 'react';

function Button({ label, onClick }) {
return (
<button className="button" onClick={onClick}>
{label}
</button>
);
}

export default Button;
70 changes: 70 additions & 0 deletions src/components/Details.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import React from 'react';

import { getRandomMarker } from '../state/selectors';
import { useStateValue } from '../state/StateProvider';
import Fade from './Fade';
import Button from './Button';

function getSearchURL(city, country, keyword) {
const formattedQuery = `${encodeURIComponent(city)}, ${encodeURIComponent(
country,
)} ${encodeURIComponent(keyword.join('|'))}`.replace(/(%20| )/g, '+');
return `https://www.google.com/search?q=${formattedQuery}`;
}

function Details() {
const [state, dispatch] = useStateValue();
const { keyword, start, focusedMarker } = state;
const randomMarker = getRandomMarker(state);

let content;
if (focusedMarker) {
const { city, countryCode, countryName, value } = focusedMarker;
const url = getSearchURL(city, countryName, keyword);
const relatedTopics = state.relatedTopics[countryCode] || [];
content = (
<>
<div className="header">
<Button
label="Back to globe"
onClick={() => dispatch({ type: 'FOCUS' })}
/>
<Button
label="Random City"
onClick={() => dispatch({ type: 'FOCUS', payload: randomMarker })}
/>
</div>
<div className="content">
<h2>
{city}, {countryName} ({value})
</h2>
<div className="details-content">
RELATED TOPICS
{relatedTopics.map(({ topic, link }) => {
return (
<a
key={topic}
href={`https://trends.google.com${link}`}
rel="noopener noreferrer"
target="_blank">
{topic}
</a>
);
})}
</div>
<a href={url} rel="noopener noreferrer" target="_blank">
View search results
</a>
</div>
</>
);
}

return (
<Fade className="details" shown={start}>
{content}
</Fade>
);
}

export default Details;
72 changes: 0 additions & 72 deletions src/components/Details.tsx

This file was deleted.

30 changes: 30 additions & 0 deletions src/components/Fade.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React, { useEffect, useState } from 'react';

export default function Fade({ children, className, shown }) {
const [shouldRender, setShouldRender] = useState(shown);

useEffect(() => {
if (shown) {
setShouldRender(true);
}
}, [shown]);

const onAnimationEnd = () => {
if (!shown) {
setShouldRender(false);
}
};

return (
shouldRender && (
<div
className={className}
style={{
animation: `${shown ? 'fade-in' : 'fade-out'} 1s`,
}}
onAnimationEnd={onAnimationEnd}>
{children}
</div>
)
);
}
60 changes: 48 additions & 12 deletions src/markerRenderer.ts → src/components/Globe.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,36 @@
import React from 'react';
import ReactGlobe, { tween } from 'react-globe';
import * as THREE from 'three';

import { Marker, tween } from 'react-globe';
import config from '../config';
import { useStateValue } from '../state/StateProvider';
import Fade from './Fade';

function random(scaleFactor: number): number {
import 'tippy.js/dist/tippy.css';
import 'tippy.js/animations/scale.css';

const MARKER_COLOR = '#fcffbe';
const MARKER_COMPANION_COLOR = '#fff9e6';

function random(scaleFactor) {
return Math.random() > 0.5
? scaleFactor * Math.random()
: -scaleFactor * Math.random();
}

const MARKER_COLOR = '#fcffbe';
const MARKER_COMPANION_COLOR = '#fff9e6';

export default function markerRenderer(marker: Marker): THREE.Object3D {
function markerRenderer(marker) {
const size = Math.max(marker.value / 20, 1);
const geometry = new THREE.SphereGeometry(size, 10, 10);
const material = new THREE.MeshBasicMaterial({
color: new THREE.Color(MARKER_COLOR),
});

// add light
const mesh = new THREE.Mesh(geometry, material);
const light = new THREE.PointLight(MARKER_COLOR, 1, 0, 0);
mesh.children = [];
mesh.add(light);

// add companion markers based on size
const companions: THREE.Mesh[] = [];
const companions = [];
for (let i = 0; i < 10; i++) {
const companionGeometry = new THREE.SphereGeometry(
Math.min((size * Math.random()) / 2, 1),
Expand All @@ -41,8 +46,8 @@ export default function markerRenderer(marker: Marker): THREE.Object3D {
mesh.add(companion);
}

companions.forEach((companion, i: number): void => {
function animate(): void {
companions.forEach((companion, i) => {
function animate() {
const from = {
opacity: 0.1,
position: companion.position.clone().toArray(),
Expand All @@ -60,7 +65,7 @@ export default function markerRenderer(marker: Marker): THREE.Object3D {
easingFunction: ['Quadratic', 'InOut'],
onUpdate: () => {
const [x, y, z] = from.position;
const companionMaterial = companion.material as THREE.MeshBasicMaterial;
const companionMaterial = companion.material;
const intensityChange = random(0.05);
if (
light.intensity + intensityChange > 0 &&
Expand All @@ -82,3 +87,34 @@ export default function markerRenderer(marker: Marker): THREE.Object3D {
});
return mesh;
}

const options = {
...config.options,
markerTooltipRenderer: (marker) => `${marker.city} (${marker.value})`,
markerRenderer,
};

function Globe() {
const [state, dispatch] = useStateValue();
const { focusedMarker, start } = state;
const markers = start ? state.markers : [];
const focus =
focusedMarker !== undefined ? focusedMarker.coordinates : undefined;
return (
<Fade className="globe" shown={true}>
<ReactGlobe
globeBackgroundTexture={config.globeBackgroundTexture}
globeCloudsTexture={config.globeCloudsTexture}
globeTexture={config.globeTexture}
height="100vh"
focus={focus}
markers={markers}
width="100vw"
options={options}
onClickMarker={(marker) => dispatch({ type: 'FOCUS', payload: marker })}
/>
</Fade>
);
}

export default Globe;
Loading

0 comments on commit 222e82a

Please sign in to comment.