mirror of
https://github.com/RealKai42/qwerty-learner.git
synced 2026-04-05 14:29:04 +08:00
feat(Chapter): 添加章节切换功能
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -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>
|
||||
)
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user