feat(Chapter): 添加章节切换功能

This commit is contained in:
KaiyiWing
2021-01-30 15:31:36 +08:00
parent 607930a256
commit e29718b32a
3 changed files with 67 additions and 21 deletions

View File

@@ -13,6 +13,7 @@
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",
"@types/jest": "^26.0.15",
"@types/lodash": "^4.14.168",
"@types/node": "^12.0.0",
"@types/react": "^16.9.53",
"@types/react-dom": "^16.9.8",
@@ -24,6 +25,7 @@
"eslint-plugin-react-hooks": "^4.2.0",
"husky": "^4.3.8",
"lint-staged": "^10.5.3",
"lodash": "^4.17.20",
"postcss": "^7",
"prettier": "^2.2.1",
"react": "^17.0.1",

View File

@@ -1,4 +1,5 @@
import React, { useEffect, useState, useCallback, ChangeEvent } from 'react'
import _ from 'lodash'
import Header from 'components/Header'
import Main from 'components/Main'
import Footer from 'components/Footer'
@@ -11,13 +12,25 @@ import { useHotkeys } from 'react-hotkeys-hook'
import cet4Dict from 'assets/CET4_N.json'
import cet6Dict from 'assets/CET6_N.json'
type WordType = {
name: string
trans: string[]
}
const App: React.FC = () => {
const [order, setOrder] = useState(0)
const [selectDict, setSelectDic] = useState('cet4')
const [dict, setDict] = useState(cet4Dict)
const [inputCount, setInputCount] = useState(0)
const [correctCount, setCorrectCount] = useState(0)
const [isStart, setIsStart] = useState(false)
const chapterLength = 15
const [order, setOrder] = useState<number>(0)
const [selectDict, setSelectDic] = useState<string>('cet4')
const [dict, setDict] = useState<Array<WordType>>(cet4Dict)
const [inputCount, setInputCount] = useState<number>(0)
const [correctCount, setCorrectCount] = useState<number>(0)
const [isStart, setIsStart] = useState<boolean>(false)
const [chapterListLength, setChapterListLength] = useState<number>(10)
const [chapter, setChapter] = useState<number>(0)
const [wordList, setWordList] = useState<Array<WordType>>(dict.slice(chapter * chapterLength, (chapter + 1) * chapterLength))
useHotkeys('enter', () => {
onChangeStart()
@@ -25,24 +38,26 @@ const App: React.FC = () => {
useEffect(() => {
const onKeydown = (e: KeyboardEvent) => {
const char = e.key
if (isLegal(char)) {
if (isLegal(e.key)) {
setInputCount((count) => count + 1)
}
}
if (isStart) {
window.addEventListener('keydown', onKeydown)
}
if (isStart) window.addEventListener('keydown', onKeydown)
return () => {
if (isStart) {
window.removeEventListener('keydown', onKeydown)
}
if (isStart) window.removeEventListener('keydown', onKeydown)
}
}, [isStart])
useEffect(() => {
setChapterListLength(Math.ceil(dict.length / chapterLength))
}, [dict])
const onChangeChapter = (e: ChangeEvent<HTMLSelectElement>) => {
const value = parseInt(e.target.value)
setChapter(value)
setWordList(dict.slice(value * chapterLength, (value + 1) * chapterLength))
}
const onFinish = () => {
setOrder((order) => (order + 1 < dict.length ? order + 1 : order))
setCorrectCount((count) => (count += dict[order].name.length))
@@ -51,30 +66,52 @@ const App: React.FC = () => {
const onChangeDict = (e: ChangeEvent<HTMLSelectElement>) => {
const value = e.target.value
setSelectDic(value)
switch (value) {
case 'cet4':
setDict(cet4Dict)
setWordList(cet4Dict.slice(chapter * chapterLength, (chapter + 1) * chapterLength))
break
case 'cet6':
setDict(cet6Dict)
setWordList(cet6Dict.slice(chapter * chapterLength, (chapter + 1) * chapterLength))
break
default:
setDict(cet4Dict)
setWordList(cet4Dict.slice(chapter * chapterLength, (chapter + 1) * chapterLength))
}
}
const onChangeStart = useCallback(() => {
setIsStart((isStart) => !isStart)
}, [])
return (
<div className="h-screen w-full pb-4 flex flex-col items-center">
<Header>
<div>
<select value={selectDict} onChange={onChangeDict}>
<option value="cet4">CET-4</option>
<option value="cet6">CET-6</option>
<option value="cet4" key="cet4">
CET-4
</option>
<option value="cet6" key="cet6">
CET-6
</option>
</select>
</div>
<div>
<select value={chapter} onChange={onChangeChapter}>
{_.range(chapterListLength).map((i) => {
return (
<option value={i} key={i}>
Chap. {i}
</option>
)
})}
</select>
</div>
<div className="group relative">
<button
className={`${
@@ -89,14 +126,16 @@ const App: React.FC = () => {
</div>
</div>
</Header>
<Main>
<div className="container flex mx-auto flex-col items-center justify-center">
<Word key={`word-${dict[order].name}`} word={dict[order].name} onFinish={onFinish} isStart={isStart} />
<Translation key={`trans-${dict[order].name}`} trans={dict[order].trans[0]} />
<Word key={`word-${wordList[order].name}`} word={wordList[order].name} onFinish={onFinish} isStart={isStart} />
<Translation key={`trans-${wordList[order].name}`} trans={wordList[order].trans[0]} />
<Speed correctCount={correctCount} inputCount={inputCount} isStart={isStart} />
</div>
</Main>
<Footer />
</div>
)

View File

@@ -1802,6 +1802,11 @@
resolved "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4=
"@types/lodash@^4.14.168":
version "4.14.168"
resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.168.tgz#fe24632e79b7ade3f132891afff86caa5e5ce008"
integrity sha512-oVfRvqHV/V6D1yifJbVRU3TMp8OT6o6BG+U9MkwuJ3U8/CsDHvalRpsxBqivn71ztOFZBTfJMvETbqHiaNSj7Q==
"@types/minimatch@*":
version "3.0.3"
resolved "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"