Created
June 7, 2019 14:25
-
-
Save gregberge/4996ba3eff93d271b3babff86d1c55f0 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// App.js | |
import React, { useState, useEffect, useRef } from 'react' | |
import { | |
Normalize, | |
Grid, | |
Typography, | |
Row, | |
Col, | |
Button, | |
} from '@smooth-ui/core-sc' | |
import SearchInput from './components/SearchInput' | |
import Catch from './components/Catch' | |
import Card from './components/Card' | |
import { useDebounce } from './components/Debounce' | |
import { MovieSearch } from './components/MovieDb' | |
import { T, useI18n } from './components/I18n' | |
function useEventListener(target, event, handler) { | |
const handlerRef = useRef() | |
useEffect(() => { | |
handlerRef.current = handler | |
}) | |
useEffect(() => { | |
function handleEvent(event) { | |
handlerRef.current(event) | |
} | |
target.addEventListener(event, handleEvent) | |
return () => target.removeEventListener(event, handleEvent) | |
}, [event, target]) | |
} | |
function useActiveKeys() { | |
const activeKeysRef = useRef([]) | |
useEventListener(document, 'keydown', event => { | |
activeKeysRef.current = [ | |
...new Set([...activeKeysRef.current, event.keyCode]), | |
] | |
}) | |
useEventListener(document, 'keyup', event => { | |
activeKeysRef.current = activeKeysRef.current.filter( | |
keyCode => keyCode !== event.keyCode, | |
) | |
}) | |
return activeKeysRef | |
} | |
const keyCodes = { | |
alt: 18, | |
f: 70, | |
} | |
function getShortcutKeys(shortcut) { | |
return shortcut.split('+').map(key => keyCodes[key]) | |
} | |
function useShortcutEffect(shorcut, effect) { | |
const activeKeys = useActiveKeys() | |
useEventListener(document, 'keydown', event => { | |
const shortcutKeys = getShortcutKeys(shorcut) | |
if (shortcutKeys.every(keyCode => activeKeys.current.includes(keyCode))) { | |
effect() | |
event.preventDefault() | |
} | |
}) | |
} | |
export default function App() { | |
const [query, setQuery] = useState('Lord of the Rings') | |
const debouncedQuery = useDebounce(query, 200) | |
const catchRef = React.useRef() | |
const { locale, setLocale } = useI18n() | |
const inputRef = React.useRef() | |
React.useLayoutEffect(() => { | |
console.log('effect') | |
}) | |
React.useEffect(() => { | |
catchRef.current.retry() | |
}, []) | |
React.useEffect(() => { | |
inputRef.current.focus() | |
}, []) | |
useShortcutEffect('alt+f', () => { | |
inputRef.current.focus() | |
}) | |
return ( | |
<> | |
{/* Le composant "Grid" centre dans la page, "py" signifie "padding-top" et "padding-bottom" */} | |
<Grid py={200}> | |
{/* Injection de normalize.css pour avoir un rendu consistant sur tous les navigateurs */} | |
<Normalize /> | |
<Button | |
type="button" | |
onClick={() => setLocale(locale => (locale === 'fr' ? 'en' : 'fr'))} | |
> | |
<T id={locale} /> | |
</Button> | |
{/* "Typography" est un composant avec des variantes de titres prêtes à l'emploi */} | |
<Typography variant="display-1"> | |
<T id="title" /> | |
</Typography> | |
{/* Le composant "SearchInput" */} | |
<SearchInput | |
ref={inputRef} | |
value={query} | |
onChange={event => setQuery(event.target.value)} | |
mb={20} | |
/> | |
<Catch ref={catchRef}> | |
<Row> | |
<MovieSearch query={debouncedQuery}> | |
{movies => | |
movies && | |
movies.map(movie => ( | |
<Col key={movie.id} my={1} xs={12} md={6}> | |
<Card | |
style={{ | |
height: 200, | |
backgroundImage: movie.backdrop_path | |
? `url(https://image.tmdb.org/t/p/original/${ | |
movie.backdrop_path | |
})` | |
: null, | |
}} | |
> | |
<Card.Body> | |
<Card.Title>{movie.title}</Card.Title> | |
<Card.Subtitle> | |
{movie.vote_average} ({movie.vote_count} votes) | |
</Card.Subtitle> | |
</Card.Body> | |
</Card> | |
</Col> | |
)) | |
} | |
</MovieSearch> | |
</Row> | |
</Catch> | |
</Grid> | |
</> | |
) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment