diff --git a/components.d.ts b/components.d.ts
index 5c6c762f..64f01a5e 100644
--- a/components.d.ts
+++ b/components.d.ts
@@ -56,8 +56,10 @@ declare module 'vue' {
Toolbar: typeof import('./src/components/Toolbar/Toolbar.vue')['default']
Tooltip: typeof import('./src/components/Tooltip.vue')['default']
TranslateSetting: typeof import('./src/components/Toolbar/TranslateSetting.vue')['default']
+ Typing: typeof import('./src/components/Practice/PracticeWord/Typing.vue')['default']
TypingArticle: typeof import('./src/components/Practice/PracticeArticle/TypingArticle.vue')['default']
TypingWord: typeof import('./src/components/Practice/PracticeWord/TypingWord.vue')['default']
+ TypingWord2: typeof import('./src/components/Practice/PracticeWord/TypingWord2.vue')['default']
VolumeIcon: typeof import('./src/components/VolumeIcon.vue')['default']
VolumeSetting: typeof import('./src/components/Toolbar/VolumeSetting.vue')['default']
WordItem: typeof import('./src/components/WordItem.vue')['default']
diff --git a/src/components/Practice/PracticeWord/Typing.vue b/src/components/Practice/PracticeWord/Typing.vue
new file mode 100644
index 00000000..1b5ae5b5
--- /dev/null
+++ b/src/components/Practice/PracticeWord/Typing.vue
@@ -0,0 +1,198 @@
+
+
+
+
+
+
+
+ {{ input }}
+ {{ wrong }}
+
+ {{
+ displayWord.split('').map(() => '_').join('')
+ }}
+ {{ displayWord }}
+
+ {{ displayWord }}
+
+
+
+
{{ settingStore.wordSoundType === 'us' ? word.usphone : word.ukphone }}
+
+
+
+
\ No newline at end of file
diff --git a/src/components/Practice/PracticeWord/TypingWord.vue b/src/components/Practice/PracticeWord/TypingWord.vue
index c1f48c87..1a604d6e 100644
--- a/src/components/Practice/PracticeWord/TypingWord.vue
+++ b/src/components/Practice/PracticeWord/TypingWord.vue
@@ -12,8 +12,8 @@ import {useOnKeyboardEventListener} from "@/hooks/event.ts";
import {Icon} from "@iconify/vue";
import VolumeIcon from "@/components/VolumeIcon.vue";
import Tooltip from "@/components/Tooltip.vue";
-import WordPanel from "./WordPanel.vue";
import Options from "@/components/Practice/Options.vue";
+import Typing from "@/components/Practice/PracticeWord/Typing.vue";
interface IProps {
words: Word[],
@@ -34,20 +34,10 @@ let data = $ref({
let input = $ref('')
let wrong = $ref('')
-let showFullWord = $ref(false)
-//输入锁定,因为跳转到下一个单词有延时,如果重复在延时期间内重复输入,导致会跳转N次
-let inputLock = $ref(false)
-let wordRepeatCount = $ref(0)
const store = useBaseStore()
const practiceStore = usePracticeStore()
const settingStore = useSettingStore()
-const playBeep = usePlayBeep()
-const playCorrect = usePlayCorrect()
-const playKeyboardAudio = usePlayKeyboardAudio()
-const playWordAudio = usePlayWordAudio()
-const volumeIconRef: any = $ref()
-
watch(() => props.words, () => {
data.words = props.words
data.index = props.index
@@ -63,17 +53,6 @@ watch(() => props.words, () => {
practiceStore.wrongWordNumber = 0
}, {immediate: true})
-watch(() => data.index, (n) => {
- wrong = input = ''
- practiceStore.index = n
- wordRepeatCount = 0
- inputLock = false
- if (settingStore.wordSound) {
- playWordAudio(word.name)
- volumeIconRef?.play()
- }
-})
-
const word = $computed(() => {
return data.words[data.index] ?? {
trans: [],
@@ -91,15 +70,7 @@ const nextWord: Word = $computed(() => {
return data.words?.[data.index + 1] ?? undefined
})
-let resetWord = $computed(() => {
- return word.name.slice(input.length + wrong.length)
-})
-
-
onMounted(() => {
- emitter.on(EventKey.resetWord, () => {
- wrong = input = ''
- })
})
@@ -108,6 +79,7 @@ function next(isTyping: boolean = true) {
if (data.wrongWords.length) {
console.log('当前背完了,但还有错词')
data.words = cloneDeep(data.wrongWords)
+ //如果原始错词没值就复制当前错词的,因为第一遍错词是最多的,后续的练习都是从错词中练习
if (!data.originWrongWords.length) {
data.originWrongWords = cloneDeep(data.wrongWords)
}
@@ -171,114 +143,46 @@ function remove() {
}
function onKeyUp(e: KeyboardEvent) {
- showFullWord = false
+ // showFullWord = false
}
-function repeat() {
- setTimeout(() => {
- wrong = input = ''
- wordRepeatCount++
- inputLock = false
-
- if (settingStore.wordSound) {
- playWordAudio(word.name)
- volumeIconRef?.play()
- }
- }, settingStore.waitTimeForChangeWord)
+function wordWrong() {
+ if (!store.wrong.originWords.find((v: Word) => v.name.toLowerCase() === word.name.toLowerCase())) {
+ store.wrong.originWords.push(word)
+ store.wrong.words.push(word)
+ store.wrong.chapterWords = [store.wrong.words]
+ }
+ if (!data.wrongWords.find((v: Word) => v.name.toLowerCase() === word.name.toLowerCase())) {
+ data.wrongWords.push(word)
+ practiceStore.wrongWordNumber++
+ }
}
async function onKeyDown(e: KeyboardEvent) {
- //TODO 还有横杠
- //非英文模式下,输入区域的 keyCode 均为 229时,
- if ((e.keyCode >= 65 && e.keyCode <= 90)
- || (e.keyCode >= 48 && e.keyCode <= 57)
- || e.code === 'Space'
- || e.code === 'Slash'
- || e.code === 'Quote'
- || e.code === 'Comma'
- || e.code === 'BracketLeft'
- || e.code === 'BracketRight'
- || e.code === 'Period'
- || e.code === 'Minus'
- || e.code === 'Equal'
- || e.code === 'Semicolon'
- || e.code === 'Backquote'
- || e.keyCode === 229
- ) {
- if (inputLock) return
- inputLock = true
- let letter = e.key
- let isWrong = false
- if (settingStore.ignoreCase) {
- isWrong = (input + letter).toLowerCase() !== word.name.toLowerCase().slice(0, input.length + 1)
- } else {
- isWrong = (input + letter) !== word.name.slice(0, input.length + 1)
- }
- if (isWrong) {
- if (!store.wrong.originWords.find((v: Word) => v.name.toLowerCase() === word.name.toLowerCase())) {
- store.wrong.originWords.push(word)
- store.wrong.words.push(word)
- store.wrong.chapterWords = [store.wrong.words]
- }
- if (!data.wrongWords.find((v: Word) => v.name.toLowerCase() === word.name.toLowerCase())) {
- data.wrongWords.push(word)
- practiceStore.wrongWordNumber++
- }
- wrong = letter
- playKeyboardAudio()
- playBeep()
- setTimeout(() => {
+ // console.log('e', e)
+ switch (e.key) {
+ case 'Backspace':
+ if (wrong) {
wrong = ''
- }, 500)
- } else {
- input += letter
- wrong = ''
- playKeyboardAudio()
- }
- if (input.toLowerCase() === word.name.toLowerCase()) {
- playCorrect()
- if (settingStore.repeatCount == 100) {
- if (settingStore.repeatCustomCount <= wordRepeatCount + 1) {
- setTimeout(next, settingStore.waitTimeForChangeWord)
- } else {
- repeat()
- }
} else {
- if (settingStore.repeatCount <= wordRepeatCount + 1) {
- setTimeout(next, settingStore.waitTimeForChangeWord)
- } else {
- repeat()
- }
+ input = input.slice(0, -1)
}
- } else {
- inputLock = false
- }
- } else {
- // console.log('e', e)
- switch (e.key) {
- case 'Backspace':
- if (wrong) {
- wrong = ''
- } else {
- input = input.slice(0, -1)
- }
- break
- case ShortKeyMap.Collect:
- collect()
- break
- case ShortKeyMap.Remove:
- remove()
- break
- case ShortKeyMap.Ignore:
- skip()
- e.preventDefault()
- break
- case ShortKeyMap.Show:
- if (settingStore.allowWordTip) {
- showFullWord = true
- }
- break
- }
+ break
+ case ShortKeyMap.Collect:
+ collect()
+ break
+ case ShortKeyMap.Remove:
+ remove()
+ break
+ case ShortKeyMap.Ignore:
+ skip()
+ e.preventDefault()
+ break
+ case ShortKeyMap.Show:
+ if (settingStore.allowWordTip) {
+ // showFullWord = true
+ }
+ break
}
}
@@ -304,33 +208,11 @@ useOnKeyboardEventListener(onKeyDown, onKeyUp)
-
-
-
- {{ input }}
- {{ wrong }}
-
- {{
- resetWord.split('').map(v => '_').join('')
- }}
- {{ resetWord }}
-
- {{ resetWord }}
-
-
-
- {{ settingStore.wordSoundType === 'us' ? word.usphone : word.ukphone }}
+
\ No newline at end of file
diff --git a/src/components/Practice/PracticeWord/TypingWord2.vue b/src/components/Practice/PracticeWord/TypingWord2.vue
new file mode 100644
index 00000000..77be7201
--- /dev/null
+++ b/src/components/Practice/PracticeWord/TypingWord2.vue
@@ -0,0 +1,431 @@
+
+
+
+
+
+
+
+
{{ prevWord.name }}
+
+
+
+
{{ nextWord.name }}
+
+
+
+
+
+
+
+ {{ input }}
+ {{ wrong }}
+
+ {{
+ resetWord.split('').map(v => '_').join('')
+ }}
+ {{ resetWord }}
+
+ {{ resetWord }}
+
+
+
+
{{ settingStore.wordSoundType === 'us' ? word.usphone : word.ukphone }}
+
+
+
+
+
\ No newline at end of file
diff --git a/src/components/VolumeIcon.vue b/src/components/VolumeIcon.vue
index 2cce9daa..3b50747c 100644
--- a/src/components/VolumeIcon.vue
+++ b/src/components/VolumeIcon.vue
@@ -6,6 +6,7 @@ import IconWrapper from "@/components/IconWrapper.vue";
const props = withDefaults(defineProps<{
time?: number,
simple?: boolean
+ cb?: Function
}>(), {
time: 400,
simple: false
@@ -15,22 +16,21 @@ let count = $ref(0)
const emit = defineEmits(['click'])
function play(time = props.time) {
+ if (count === 0) {
+ props?.cb()
+ }
+ count++
setTimeout(() => {
if (step === 2) {
- if (count === 0) {
- play(time + 100)
+ if (count === 1) {
step = 0
+ play(time + 100)
} else {
count = 0
}
} else {
step++
- if (step === 2) {
- count++
- play(time + 100)
- } else {
- play(time + 100)
- }
+ play(time + 100)
}
}, time)
}
diff --git a/src/hooks/event.ts b/src/hooks/event.ts
index 9b6df2fe..fa17137f 100644
--- a/src/hooks/event.ts
+++ b/src/hooks/event.ts
@@ -23,7 +23,26 @@ export function useStartKeyboardEventListener() {
useEventListener('keydown', (e: KeyboardEvent) => {
if (!runtimeStore.disableEventListener) {
- emitter.emit(EventKey.keydown, e)
+ //非英文模式下,输入区域的 keyCode 均为 229时,
+ if ((e.keyCode >= 65 && e.keyCode <= 90)
+ || (e.keyCode >= 48 && e.keyCode <= 57)
+ || e.code === 'Space'
+ || e.code === 'Slash'
+ || e.code === 'Quote'
+ || e.code === 'Comma'
+ || e.code === 'BracketLeft'
+ || e.code === 'BracketRight'
+ || e.code === 'Period'
+ || e.code === 'Minus'
+ || e.code === 'Equal'
+ || e.code === 'Semicolon'
+ || e.code === 'Backquote'
+ || e.keyCode === 229
+ ) {
+ emitter.emit(EventKey.onTyping, e)
+ }else {
+ emitter.emit(EventKey.keydown, e)
+ }
}
})
useEventListener('keyup', (e: KeyboardEvent) => {
diff --git a/src/utils/eventBus.ts b/src/utils/eventBus.ts
index ba74fd5f..8a88faa8 100644
--- a/src/utils/eventBus.ts
+++ b/src/utils/eventBus.ts
@@ -9,4 +9,5 @@ export const EventKey = {
closeOther: 'closeOther',
keydown: 'keydown',
keyup: 'keyup',
+ onTyping: 'onTyping',
}
\ No newline at end of file