Skip to content

Commit

Permalink
feat(unvisible): 添加默写模式,并在用户完成一个章节后询问是否默写本章节
Browse files Browse the repository at this point in the history
  • Loading branch information
RealKai42 committed Feb 2, 2021
1 parent ad0f04e commit 7756924
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 14 deletions.
8 changes: 5 additions & 3 deletions src/components/Letter/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ import React from 'react'

export type LetterState = 'normal' | 'correct' | 'wrong'

const Letter: React.FC<LetterProps> = ({ letter, state }) => {
const Letter: React.FC<LetterProps> = ({ letter, state, visible }) => {
let stateClassName = ''

const defaultClassName = visible ? 'text-gray-600' : 'text-transparent'
switch (state) {
case 'normal':
stateClassName = 'text-gray-600'
stateClassName = defaultClassName
break
case 'correct':
stateClassName = 'text-green-600'
Expand All @@ -16,7 +17,7 @@ const Letter: React.FC<LetterProps> = ({ letter, state }) => {
stateClassName = 'text-red-600'
break
default:
stateClassName = 'text-gray-600'
stateClassName = defaultClassName
}

return <span className={`m-0 p-0 text-5xl font-mono font-normal ${stateClassName}`}>{letter}</span>
Expand All @@ -27,4 +28,5 @@ export default Letter
export type LetterProps = {
letter: string
state: LetterState
visible: boolean
}
26 changes: 26 additions & 0 deletions src/components/Modals/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ type ModalsProps = {
secondButtonClassName?: string
firstButtonOnclick: (e: MouseEvent) => void
secondButtonOnclick: (e: MouseEvent) => void
thirdButton?: string
thirdButtonOnclick?: (e: MouseEvent) => void
thirdButtonHotkey?: string
}

const Modals: React.FC<ModalsProps> = ({
Expand All @@ -25,6 +28,9 @@ const Modals: React.FC<ModalsProps> = ({
secondButtonClassName,
firstButtonOnclick,
secondButtonOnclick,
thirdButton,
thirdButtonOnclick,
thirdButtonHotkey = '',
}) => {
useHotkeys('enter', () => {
const e: MouseEvent = (null as unknown) as MouseEvent
Expand All @@ -36,6 +42,11 @@ const Modals: React.FC<ModalsProps> = ({
secondButtonOnclick(e)
})

useHotkeys(thirdButtonHotkey, () => {
const e: MouseEvent = (null as unknown) as MouseEvent
if (thirdButtonOnclick) thirdButtonOnclick(e)
})

return (
<div className="fixed z-10 inset-0 overflow-y-auto">
<div className="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
Expand Down Expand Up @@ -117,6 +128,21 @@ const Modals: React.FC<ModalsProps> = ({
<span className="py-1 px-3 text-gray-500 text-xs">快捷键 Shift + Enter</span>
</div>
</div>

{thirdButton && thirdButtonOnclick && (
<div className="group relative">
<button
type="button"
className={`mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm ${secondButtonClassName}`}
onClick={thirdButtonOnclick}
>
{thirdButton}
</button>
<div className="invisible group-hover:visible absolute bottom-full left-1/2 w-40 -ml-20 pl-3 flex items-center justify-center">
<span className="py-1 px-3 text-gray-500 text-xs">快捷键 {thirdButtonHotkey}</span>
</div>
</div>
)}
</div>
</div>
)}
Expand Down
5 changes: 3 additions & 2 deletions src/components/Word/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Letter, { LetterState } from '../Letter'
import { isLegal, isChineseSymbol } from '../../utils/utils'
import useSounds from 'hooks/useSounds'

const Word: React.FC<WordProps> = ({ word = 'defaultWord', onFinish, isStart }) => {
const Word: React.FC<WordProps> = ({ word = 'defaultWord', onFinish, isStart, wordVisible = true }) => {
word = word.replaceAll(' ', '_')
const [inputWord, setInputWord] = useState('')
const [statesList, setStatesList] = useState<LetterState[]>([])
Expand Down Expand Up @@ -78,7 +78,7 @@ const Word: React.FC<WordProps> = ({ word = 'defaultWord', onFinish, isStart })
return (
<div className="py-4">
{word.split('').map((t, index) => {
return <Letter key={`${index}-${t}`} letter={t} state={statesList[index]} />
return <Letter key={`${index}-${t}`} visible={wordVisible} letter={t} state={statesList[index]} />
})}
</div>
)
Expand All @@ -88,6 +88,7 @@ export type WordProps = {
word: string
onFinish: Function
isStart: boolean
wordVisible: boolean
}
export default Word

Expand Down
4 changes: 2 additions & 2 deletions src/icon.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { library } from '@fortawesome/fontawesome-svg-core'
import { faKeyboard } from '@fortawesome/free-regular-svg-icons'
import { faBookReader, faEnvelope, faVolumeMute, faVolumeUp } from '@fortawesome/free-solid-svg-icons'
import { faBookReader, faEnvelope, faVolumeMute, faVolumeUp, faEye, faEyeSlash } from '@fortawesome/free-solid-svg-icons'
import { faGithub } from '@fortawesome/free-brands-svg-icons'

library.add(faKeyboard, faBookReader, faGithub, faEnvelope, faVolumeUp, faVolumeMute)
library.add(faKeyboard, faBookReader, faGithub, faEnvelope, faVolumeUp, faVolumeMute, faEye, faEyeSlash)
50 changes: 45 additions & 5 deletions src/pages/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,20 @@ const App: React.FC = () => {

const [cookies, setCookies] = useCookies()
const [sound, toggleSound] = useSoundState()
const [wordVisible, setWordVisible] = useState<boolean>(true)

const {
modalState,
title: modalTitle,
content: modalContent,
firstButton: modalFirstBtn,
secondButton: modalSecondBtn,
thirdButton: modalThirdBtn,
thirdBtnHotkey,
setThirdBtnHotkey,
firstButtonOnclick: modalFirstBtnOnclick,
secondButtonOnclick: modalSecondBtnOnclick,
thirdButtonOnclick: modalThirdBtnOnclick,
setModalState,
setMessage: setModalMessage,
setHandler: setModalHandler,
Expand All @@ -88,6 +93,9 @@ const App: React.FC = () => {
)

useHotkeys('ctrl+m', toggleSound, [sound])
useHotkeys('ctrl+v', () => {
setWordVisible((visibleWord) => !visibleWord)
})

useEffect(() => {
// 首次加载时,读取 cookies
Expand Down Expand Up @@ -159,12 +167,20 @@ const App: React.FC = () => {
// 用户完成当前章节
if (chapter === chapterListLength - 1) {
setModalState(true)
setModalMessage('提示', '您已完成最后一个章节', '重复本章节', '重置到第一章节')
setModalHandler(modalHandlerGenerator(chapter, 0, false), modalHandlerGenerator(0, 0, false))
setModalMessage('提示', '您已完成最后一个章节', '重复本章节', '重置到第一章节', '默写本章节')
setThirdBtnHotkey('v')
setModalHandler(modalHandlerGenerator(chapter, 0, false), modalHandlerGenerator(0, 0, false), () => {
modalHandlerGenerator(chapter, 0, false)()
setWordVisible(false)
})
} else {
setModalState(true)
setModalMessage('提示', '您已完成本章节', '下一章节', '重复本章节')
setModalHandler(modalHandlerGenerator(chapter + 1, 0, false), modalHandlerGenerator(chapter, 0, false))
setModalMessage('提示', '您已完成本章节', '下一章节', '重复本章节', '默写本章节')
setThirdBtnHotkey('v')
setModalHandler(modalHandlerGenerator(chapter + 1, 0, false), modalHandlerGenerator(chapter, 0, false), () => {
modalHandlerGenerator(chapter, 0, false)()
setWordVisible(false)
})
}
} else {
setOrder((order) => order + 1)
Expand Down Expand Up @@ -200,8 +216,11 @@ const App: React.FC = () => {
content={modalContent}
firstButton={modalFirstBtn}
secondButton={modalSecondBtn}
thirdButton={modalThirdBtn}
thirdButtonHotkey={thirdBtnHotkey}
firstButtonOnclick={modalFirstBtnOnclick}
secondButtonOnclick={modalSecondBtnOnclick}
thirdButtonOnclick={modalThirdBtnOnclick}
/>
)}
{isLoading && <Loading />}
Expand Down Expand Up @@ -256,6 +275,21 @@ const App: React.FC = () => {
</div>
</div>

<div className="group relative">
<button
className={`${wordVisible ? 'text-indigo-400' : 'text-gray-400'} text-lg focus:outline-none`}
onClick={(e) => {
setWordVisible(!wordVisible)
e.currentTarget.blur()
}}
>
<FontAwesomeIcon icon={wordVisible ? 'eye' : 'eye-slash'} fixedWidth />
</button>
<div className="invisible group-hover:visible absolute top-full left-1/2 w-44 -ml-20 pt-2 flex items-center justify-center">
<span className="py-1 px-3 text-gray-500 text-xs">开关英语显示(Ctrl + V)</span>
</div>
</div>

<div className="group relative">
<button
className={`${
Expand All @@ -275,7 +309,13 @@ const App: React.FC = () => {

<Main>
<div className="container flex mx-auto flex-col items-center justify-center">
<Word key={`word-${wordList[order].name}`} word={wordList[order].name} onFinish={onFinish} isStart={isStart} />
<Word
key={`word-${wordList[order].name}`}
word={wordList[order].name}
onFinish={onFinish}
isStart={isStart}
wordVisible={wordVisible}
/>
<Translation key={`trans-${wordList[order].name}`} trans={wordList[order].trans.join(';')} />
<Speed correctCount={correctCount} inputCount={inputCount} isStart={isStart} />
</div>
Expand Down
21 changes: 19 additions & 2 deletions src/utils/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,47 @@ export const useModals = (initialState: boolean, initialTitle: string) => {
const [content, setContent] = useState('')
const [firstButton, setFirstButton] = useState('')
const [secondButton, setSecondButton] = useState('')
const [thirdButton, setThirdButton] = useState('')
const [firstButtonOnclick, setFirstButtonOnclick] = useState<(e: MouseEvent) => void>(() => {})
const [secondButtonOnclick, setSecondButtonOnclick] = useState<(e: MouseEvent) => void>(() => {})
const [thirdButtonOnclick, setThirdButtonOnclick] = useState<(e: MouseEvent) => void>(() => {})
const [thirdBtnHotkey, setThirdBtnHotkey] = useState('')

const setMessage = (title: string, content: string, firstButton: string, secondButton: string) => {
const setMessage = (title: string, content: string, firstButton: string, secondButton: string, thirdButton?: string) => {
setTitle(title)
setContent(content)
setFirstButton(firstButton)
setSecondButton(secondButton)
if (thirdButton) {
setThirdButton(thirdButton)
}
}

const setHandler = (firstButton: (e: MouseEvent) => void, secondButton: (e: MouseEvent) => void) => {
const setHandler = (
firstButton: (e: MouseEvent) => void,
secondButton: (e: MouseEvent) => void,
thirdButton?: (e: MouseEvent) => void,
) => {
setFirstButtonOnclick(() => firstButton)
setSecondButtonOnclick(() => secondButton)
if (thirdButton) {
setThirdButtonOnclick(() => thirdButton)
}
}
return {
modalState,
title,
content,
firstButton,
secondButton,
thirdButton,
thirdBtnHotkey,
firstButtonOnclick,
secondButtonOnclick,
thirdButtonOnclick,
setModalState,
setMessage,
setHandler,
setThirdBtnHotkey,
}
}

1 comment on commit 7756924

@vercel
Copy link

@vercel vercel bot commented on 7756924 Feb 2, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.