fix: resolve issue #86,#72

This commit is contained in:
zyronon
2025-08-23 16:40:47 +08:00
parent 1b3d3090a0
commit f443190190
6 changed files with 111 additions and 97 deletions

View File

@@ -53,7 +53,6 @@ export function useStartKeyboardEventListener() {
useEventListener('keydown', (e: KeyboardEvent) => {
if (!runtimeStore.disableEventListener) {
e.preventDefault()
let shortcutKey = getShortcutKey(e)
// console.log('shortcutKey', shortcutKey)
@@ -68,10 +67,11 @@ export function useStartKeyboardEventListener() {
}
}
if (shortcutEvent) {
e.preventDefault()
emitter.emit(shortcutEvent, e)
} else {
//非英文模式下,输入区域的 keyCode 均为 229时
if ((e.keyCode >= 65 && e.keyCode <= 90)
if (((e.keyCode >= 65 && e.keyCode <= 90)
|| (e.keyCode >= 48 && e.keyCode <= 57)
|| e.code === 'Space'
|| e.code === 'Slash'
@@ -85,7 +85,9 @@ export function useStartKeyboardEventListener() {
|| e.code === 'Semicolon'
// || e.code === 'Backquote'
|| e.keyCode === 229
) {
//当按下功能键时,不阻止事件传播
) && (!e.ctrlKey && !e.altKey)) {
e.preventDefault()
emitter.emit(EventKey.onTyping, e)
} else {
emitter.emit(EventKey.keydown, e)

View File

@@ -174,13 +174,13 @@ function importOldData() {
<div class="left mt-10">
<div class="tabs">
<div class="tab" :class="tabIndex === 0 && 'active'" @click="tabIndex = 0">
<IconBxHeadphone width="20"/>
<span>音效设置</span>
</div>
<div class="tab" :class="tabIndex === 1 && 'active'" @click="tabIndex = 1">
<IconIconParkOutlineSettingConfig width="20"/>
<span>练习设置</span>
</div>
<div class="tab" :class="tabIndex === 1 && 'active'" @click="tabIndex = 1">
<IconBxHeadphone width="20"/>
<span>音效设置</span>
</div>
<div class="tab" :class="tabIndex === 2 && 'active'" @click="tabIndex = 2">
<IconMaterialSymbolsKeyboardOutline width="20"/>
<span>快捷键设置</span>
@@ -202,71 +202,6 @@ function importOldData() {
<div class="content">
<div class="page-title text-align-center">设置</div>
<div v-if="tabIndex === 0">
<SettingItem mainTitle="所有音效">
<Switch v-model="settingStore.allSound" @change="useChangeAllSound"/>
</SettingItem>
<div class="line"></div>
<SettingItem title="单词/句子自动发音">
<Switch v-model="settingStore.wordSound"/>
</SettingItem>
<SettingItem title="单词/句子发音口音">
<Select v-model="settingStore.wordSoundType"
placeholder="请选择"
class="w-50!"
>
<Option label="美音" value="us"/>
<Option label="英音" value="uk"/>
</Select>
</SettingItem>
<SettingItem title="音量">
<Slider v-model="settingStore.wordSoundVolume"/>
<span class="w-10 pl-5">{{ settingStore.wordSoundVolume }}%</span>
</SettingItem>
<SettingItem title="倍速">
<Slider v-model="settingStore.wordSoundSpeed" :step="0.1" :min="0.5" :max="3"/>
<span class="w-10 pl-5">{{ settingStore.wordSoundSpeed }}</span>
</SettingItem>
<div class="line"></div>
<SettingItem title="按键音">
<Switch v-model="settingStore.keyboardSound"/>
</SettingItem>
<SettingItem title="按键音效">
<Select v-model="settingStore.keyboardSoundFile"
placeholder="请选择"
class="w-50!"
>
<Option
v-for="item in SoundFileOptions"
:key="item.value"
:label="item.label"
:value="item.value"
>
<div class="flex justify-between items-center w-full">
<span>{{ item.label }}</span>
<VolumeIcon
:time="100"
@click="usePlayAudio(getAudioFileUrl(item.value)[0])"/>
</div>
</Option>
</Select>
</SettingItem>
<SettingItem title="音量">
<Slider v-model="settingStore.keyboardSoundVolume"/>
<span class="w-10 pl-5">{{ settingStore.keyboardSoundVolume }}%</span>
</SettingItem>
<div class="line"></div>
<SettingItem title="效果音(输入错误、完成时的音效)">
<Switch v-model="settingStore.effectSound"/>
</SettingItem>
<SettingItem title="音量">
<Slider v-model="settingStore.effectSoundVolume"/>
<span class="w-10 pl-5">{{ settingStore.effectSoundVolume }}%</span>
</SettingItem>
</div>
<div v-if="tabIndex === 1">
<SettingItem title="单词练习模式">
<RadioGroup v-model="settingStore.wordPracticeMode" class="flex-col gap-0!">
<Radio :value="0" label="智能模式,系统自动计算复习单词与默写单词"/>
@@ -298,8 +233,15 @@ function importOldData() {
<Switch v-model="settingStore.disableShowPracticeSettingDialog"/>
</SettingItem>
<SettingItem title="单词输入错误时,清空已输入内容"
>
<Switch v-model="settingStore.inputWrongClear"/>
</SettingItem>
<div class="line" v-if="settingStore.autoNextWord"></div>
<SettingItem title="自动切换下一个单词">
<SettingItem title="自动切换下一个单词"
desc="未开启自动切换时,当输入完成后请使用空格键切换下一个"
>
<Switch v-model="settingStore.autoNextWord"/>
</SettingItem>
@@ -370,6 +312,71 @@ function importOldData() {
v-model="simpleWords" :autosize="{minRows: 6, maxRows: 10}"/>
</SettingItem>
</div>
<div v-if="tabIndex === 1">
<SettingItem mainTitle="所有音效">
<Switch v-model="settingStore.allSound" @change="useChangeAllSound"/>
</SettingItem>
<div class="line"></div>
<SettingItem title="单词/句子自动发音">
<Switch v-model="settingStore.wordSound"/>
</SettingItem>
<SettingItem title="单词/句子发音口音">
<Select v-model="settingStore.wordSoundType"
placeholder="请选择"
class="w-50!"
>
<Option label="美音" value="us"/>
<Option label="英音" value="uk"/>
</Select>
</SettingItem>
<SettingItem title="音量">
<Slider v-model="settingStore.wordSoundVolume"/>
<span class="w-10 pl-5">{{ settingStore.wordSoundVolume }}%</span>
</SettingItem>
<SettingItem title="倍速">
<Slider v-model="settingStore.wordSoundSpeed" :step="0.1" :min="0.5" :max="3"/>
<span class="w-10 pl-5">{{ settingStore.wordSoundSpeed }}</span>
</SettingItem>
<div class="line"></div>
<SettingItem title="按键音">
<Switch v-model="settingStore.keyboardSound"/>
</SettingItem>
<SettingItem title="按键音效">
<Select v-model="settingStore.keyboardSoundFile"
placeholder="请选择"
class="w-50!"
>
<Option
v-for="item in SoundFileOptions"
:key="item.value"
:label="item.label"
:value="item.value"
>
<div class="flex justify-between items-center w-full">
<span>{{ item.label }}</span>
<VolumeIcon
:time="100"
@click="usePlayAudio(getAudioFileUrl(item.value)[0])"/>
</div>
</Option>
</Select>
</SettingItem>
<SettingItem title="音量">
<Slider v-model="settingStore.keyboardSoundVolume"/>
<span class="w-10 pl-5">{{ settingStore.keyboardSoundVolume }}%</span>
</SettingItem>
<div class="line"></div>
<SettingItem title="效果音(输入错误、完成时的音效)">
<Switch v-model="settingStore.effectSound"/>
</SettingItem>
<SettingItem title="音量">
<Slider v-model="settingStore.effectSoundVolume"/>
<span class="w-10 pl-5">{{ settingStore.effectSoundVolume }}%</span>
</SettingItem>
</div>
<div class="body" v-if="tabIndex === 2">
<div class="row">
<label class="main-title">功能</label>

View File

@@ -265,7 +265,6 @@ async function onKeyDown(e: KeyboardEvent) {
}
}
useOnKeyboardEventListener(onKeyDown, onKeyUp)
function repeat() {

View File

@@ -9,6 +9,7 @@ import Tooltip from "@/pages/pc/components/base/Tooltip.vue";
import SentenceHightLightWord from "@/pages/pc/word/components/SentenceHightLightWord.vue";
import {usePracticeStore} from "@/stores/practice.ts";
import {getDefaultWord} from "@/types/func.ts";
import {sleep} from "@/utils";
interface IProps {
word: Word,
@@ -78,10 +79,15 @@ function repeat() {
}
async function onTyping(e: KeyboardEvent) {
if (inputLock) return
console.log('onTyping', inputLock)
inputLock = true
if (inputLock) {
//如果是锁定状态,说明要么输入太快;要么就是设置了不自动跳转,然后输入完了,当这种情况时,监听空格键,按下切换下一个
if (e.code === 'Space' && input.toLowerCase() === props.word.word.toLowerCase()) {
return emit('complete')
}
return
}
let letter = e.key
inputLock = true
let isTypingRight = false
if (settingStore.ignoreCase) {
isTypingRight = letter.toLowerCase() === props.word.word[input.length].toLowerCase()
@@ -93,13 +99,13 @@ async function onTyping(e: KeyboardEvent) {
wrong = ''
playKeyboardAudio()
} else {
emit('wrong')
wrong = letter
playBeep()
volumeIconRef?.play()
setTimeout(() => {
wrong = ''
}, 500)
emit('wrong')
await sleep(500)
if (settingStore.inputWrongClear) input = ''
wrong = ''
}
if (input.toLowerCase() === props.word.word.toLowerCase()) {

View File

@@ -5,9 +5,6 @@ import {SAVE_SETTING_KEY} from "@/utils/const.ts";
import {get} from "idb-keyval";
export interface SettingState {
showToolbar: boolean,
show: boolean,
allSound: boolean,
wordSound: boolean,
wordSoundVolume: number,
@@ -18,22 +15,24 @@ export interface SettingState {
keyboardSoundFile: string,
effectSound: boolean,
effectSoundVolume: number,
repeatCount: number,
repeatCustomCount?: number,
dictation: boolean,
translate: boolean,
showNearWord: boolean
ignoreCase: boolean
allowWordTip: boolean
waitTimeForChangeWord: number
repeatCount: number, //重复次数
repeatCustomCount?: number, //自定义重复次数
dictation: boolean,//显示默写
translate: boolean, //显示翻译
showNearWord: boolean //显示上/下一个词
ignoreCase: boolean //忽略大小写
allowWordTip: boolean //默写时时否允许查看提示
waitTimeForChangeWord: number // 切下一个词的等待时间
fontSize: {
articleForeignFontSize: number,
articleTranslateFontSize: number,
wordForeignFontSize: number,
wordTranslateFontSize: number,
},
showPanel: boolean,
sideExpand: boolean,
showToolbar: boolean, //收起/展开工具栏
showPanel: boolean, // 收起/展开面板
sideExpand: boolean, //收起/展开左侧侧边栏
theme: string,
shortcutKeyMap: Record<string, string>,
first: boolean
@@ -44,11 +43,11 @@ export interface SettingState {
wordPracticeMode: number // 单词练习模式0智能模式1自由模式
disableShowPracticeSettingDialog: boolean // 不默认显示练习设置弹框
autoNextWord: boolean //自动切换下一个单词
inputWrongClear: boolean //单词输入错误,清空已输入内容
}
export const getDefaultSettingState = (): SettingState => ({
showToolbar: true,
show: false,
showPanel: true,
sideExpand: false,
@@ -86,7 +85,8 @@ export const getDefaultSettingState = (): SettingState => ({
ignoreSimpleWord: false,
wordPracticeMode: 0,
disableShowPracticeSettingDialog: false,
autoNextWord: true
autoNextWord: true,
inputWrongClear: false
})
export const useSettingStore = defineStore('setting', {

View File

@@ -14,7 +14,7 @@ export const SAVE_DICT_KEY = {
}
export const SAVE_SETTING_KEY = {
key: 'typing-word-setting',
version: 12
version: 13
}
export const EXPORT_DATA_KEY = {
key: 'typing-word-export',