Add Gutenberg search

context-store
Alfred Melch 5 years ago
parent 6cc58a70bd
commit 3bec754ae8

@ -1,7 +1,13 @@
import React from 'react'
import { RsvpReader } from './components/RsvpReader'
import { GutenbergSearch } from './components/GutenbergSearch'
export const App = () => {
return <RsvpReader></RsvpReader>
return (
<>
<RsvpReader></RsvpReader>
<GutenbergSearch></GutenbergSearch>
</>
)
}

@ -0,0 +1,82 @@
import React, { useState, useEffect, useCallback } from 'react'
import axios from 'axios'
import { useDispatch } from 'react-redux'
import { debounce } from 'debounce'
import { setText } from '../store/actions.js'
async function search(searchTerm) {
const regex = new RegExp(searchTerm, 'i')
const result = []
const data = await import('../../data/gutenberg.json').then(
module => module.default
)
for (let entry of data) {
if (regex.test(entry.title[0]) || regex.test(entry.author[0])) {
result.push(entry)
}
if (result.length >= 20) break
}
return result
}
const Book = ({ entry }) => {
const dispatch = useDispatch()
const { author, language, rights, subject, title, id } = entry
const handleClick = async () => {
const url = `https://gutenberg.muperfredi.de/texts/${id}/stripped-body`
const text = await axios.get(url).then(res => res.data.body)
dispatch(setText(text))
}
return (
<div>
<div>
{id} {title.join(' - ')}
</div>
<div>{author[0]}</div>
<div>{language.join(' - ')}</div>
<div>
<button onClick={handleClick}>Load</button>
</div>
<br></br>
</div>
)
}
export const GutenbergSearch = () => {
const [searchTerm, setSearchTerm] = useState('')
const [result, setResult] = useState([])
const [loading, setLoading] = useState(false)
const debouncedSearch = useCallback(
debounce(async term => {
setLoading(true)
await search(term).then(setResult)
setLoading(false)
}, 500),
[]
)
useEffect(() => {
if (searchTerm.length > 0) {
debouncedSearch(searchTerm)
}
}, [searchTerm, debouncedSearch])
return (
<div>
<h2>Search for books in the Gutenberg Project</h2>
<input
value={searchTerm}
onChange={e => setSearchTerm(e.target.value)}
></input>
{loading && 'loading...'}
{result.map(entry => (
<Book key={entry.id} entry={entry} />
))}
{result.length === 0 && <div>'no results to display'</div>}
</div>
)
}

@ -7,7 +7,7 @@ import { Options } from './Options'
import { PlayerControl } from './PlayerControl'
import styles from './RsvpReader.css'
import { PipeMarker, BorderMarker } from './PivotMarker'
import { BorderMarker } from './PivotMarker'
import { Progress } from './Progress'
import { TimeCalc } from './TimeCalc'
@ -30,9 +30,7 @@ export const RsvpReader = () => {
<Options></Options>
<TimeCalc />
</div>
<div className={styles.item}>
<TextOutput />
</div>
<div className={styles.item}>{/* <TextOutput /> */}</div>
</div>
)
}

@ -1,3 +1,5 @@
import 'regenerator-runtime/runtime'
import React from 'react'
import ReactDOM from 'react-dom'
import { Provider } from 'react-redux'

Loading…
Cancel
Save