feat: add isTextSelectable switcher

This commit is contained in:
KaiyiWing
2023-04-19 02:32:48 +08:00
parent 0e883f6af7
commit 52646af15e
6 changed files with 47 additions and 7 deletions

View File

@@ -1,4 +1,4 @@
import { phoneticConfigAtom } from '@/store'
import { isTextSelectableAtom, phoneticConfigAtom } from '@/store'
import { Word } from '@/typings'
import { useAtomValue } from 'jotai'
@@ -8,9 +8,14 @@ export type PhoneticProps = {
function Phonetic({ word }: PhoneticProps) {
const phoneticConfig = useAtomValue(phoneticConfigAtom)
const isTextSelectable = useAtomValue(isTextSelectableAtom)
return (
<div className="space-x-5 pt-1 text-center text-sm font-normal text-gray-600 transition-colors duration-300 dark:text-gray-400">
<div
className={`space-x-5 pt-1 text-center text-sm font-normal text-gray-600 transition-colors duration-300 dark:text-gray-400 ${
!isTextSelectable && 'select-none'
}`}
>
{phoneticConfig.type === 'us' && word.usphone && word.usphone.length > 1 && <span>{`AmE: [${word.usphone}]`}</span>}
{phoneticConfig.type === 'uk' && word.ukphone && word.ukphone.length > 1 && <span>{`BrE: [${word.ukphone}]`}</span>}
</div>

View File

@@ -1,8 +1,18 @@
import { isTextSelectableAtom } from '@/store'
import { useAtomValue } from 'jotai'
export type TranslationProps = {
trans: string
}
export default function Translation({ trans }: TranslationProps) {
const isTextSelectable = useAtomValue(isTextSelectableAtom)
return (
<div className="max-w-4xl pb-4 pt-5 font-sans text-lg transition-colors duration-300 dark:text-white dark:text-opacity-80">{trans}</div>
<div
className={`max-w-4xl pb-4 pt-5 font-sans text-lg transition-colors duration-300 dark:text-white dark:text-opacity-80 ${
!isTextSelectable && 'select-none'
}`}
>
{trans}
</div>
)
}

View File

@@ -24,7 +24,7 @@ export type LetterProps = {
const Letter: React.FC<LetterProps> = ({ letter, state = 'normal', visible = true }) => (
<span
className={`m-0 select-none p-0 font-mono text-5xl font-normal ${
className={`m-0 p-0 font-mono text-5xl font-normal ${
stateClassNameMap[(letter === EXPLICIT_SPACE) as unknown as string][state]
} pr-0.8 duration-0 dark:text-opacity-80`}
>

View File

@@ -6,7 +6,7 @@ import style from './index.module.css'
import { EXPLICIT_SPACE } from '@/constants'
import useKeySounds from '@/hooks/useKeySounds'
import { TypingContext, TypingStateActionType } from '@/pages/Typing/store'
import { isIgnoreCaseAtom, pronunciationIsOpenAtom } from '@/store'
import { isIgnoreCaseAtom, isTextSelectableAtom, pronunciationIsOpenAtom } from '@/store'
import { useMixPanelWordLogUploader } from '@/utils'
import { useSaveWordRecord } from '@/utils/db'
import { LetterMistakes } from '@/utils/db/record'
@@ -55,6 +55,7 @@ export default function Word({ word, onFinish }: { word: string; onFinish: () =>
const { state, dispatch } = useContext(TypingContext)!
const [wordState, setWordState] = useImmer<WordState>(structuredClone(initialWordState))
const isTextSelectable = useAtomValue(isTextSelectableAtom)
const isIgnoreCase = useAtomValue(isIgnoreCaseAtom)
const saveWordRecord = useSaveWordRecord()
const wordLogUploader = useMixPanelWordLogUploader(state)
@@ -208,7 +209,9 @@ export default function Word({ word, onFinish }: { word: string; onFinish: () =>
<InputHandler updateInput={updateInput} />
<div className="flex justify-center pb-1 pt-4">
<div className="relative">
<div className={`flex items-center justify-center ${wordState.hasWrong ? style.wrong : ''}`}>
<div
className={`flex items-center ${!isTextSelectable && 'select-none'} justify-center ${wordState.hasWrong ? style.wrong : ''}`}
>
{wordState.displayWord.split('').map((t, index) => {
return (
<Letter

View File

@@ -1,5 +1,5 @@
import styles from './index.module.css'
import { isIgnoreCaseAtom, randomConfigAtom } from '@/store'
import { isIgnoreCaseAtom, isTextSelectableAtom, randomConfigAtom } from '@/store'
import { Switch } from '@headlessui/react'
import { useAtom } from 'jotai'
import { useCallback } from 'react'
@@ -7,6 +7,7 @@ import { useCallback } from 'react'
export default function AdvancedSetting() {
const [randomConfig, setRandomConfig] = useAtom(randomConfigAtom)
const [isIgnoreCase, setIsIgnoreCase] = useAtom(isIgnoreCaseAtom)
const [isTextSelectable, setIsTextSelectable] = useAtom(isTextSelectableAtom)
const onToggleRandom = useCallback(
(checked: boolean) => {
@@ -25,6 +26,13 @@ export default function AdvancedSetting() {
[setIsIgnoreCase],
)
const onToggleTextSelectable = useCallback(
(checked: boolean) => {
setIsTextSelectable(checked)
},
[setIsTextSelectable],
)
return (
<div className={styles.tabContent}>
<div className={styles.section}>
@@ -51,6 +59,18 @@ export default function AdvancedSetting() {
}`}</span>
</div>
</div>
<div className={styles.section}>
<span className={styles.sectionLabel}></span>
<span className={styles.sectionDescription}> </span>
<div className={styles.switchBlock}>
<Switch checked={isTextSelectable} onChange={onToggleTextSelectable} className="switch-root">
<span aria-hidden="true" className="switch-thumb" />
</Switch>
<span className="text-right text-xs font-normal leading-tight text-gray-600">{`选择文本已${
isTextSelectable ? '开启' : '关闭'
}`}</span>
</div>
</div>
</div>
)
}

View File

@@ -53,6 +53,8 @@ export const isLoopSingleWordAtom = atom(false)
export const isIgnoreCaseAtom = atomWithStorage('isIgnoreCase', true)
export const isTextSelectableAtom = atomWithStorage('isTextSelectable', false)
export const phoneticConfigAtom = atomWithStorage('phoneticConfig', {
isOpen: true,
type: 'us' as PhoneticType,