Small optimization
This commit is contained in:
@@ -84,7 +84,7 @@ onMounted(() => {
|
||||
}
|
||||
}
|
||||
|
||||
drawMoon()
|
||||
// drawMoon()
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
<script setup lang="ts">
|
||||
import {Icon} from '@iconify/vue';
|
||||
import {ref, watch} from "vue";
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
import {getAudioFileUrl, useChangeAllSound, usePlayAudio, useWatchAllSound} from "@/hooks/sound.ts";
|
||||
import {getShortcutKey, useDisableEventListener, useEventListener} from "@/hooks/event.ts";
|
||||
import {$computed, $ref} from "vue/macros";
|
||||
import {cloneDeep} from "lodash-es";
|
||||
import {DefaultShortcutKeyMap, Dict, DictType, ShortcutKey} from "@/types.ts";
|
||||
import { Icon } from '@iconify/vue';
|
||||
import { ref, watch } from "vue";
|
||||
import { useSettingStore } from "@/stores/setting.ts";
|
||||
import { getAudioFileUrl, useChangeAllSound, usePlayAudio, useWatchAllSound } from "@/hooks/sound.ts";
|
||||
import { getShortcutKey, useDisableEventListener, useEventListener } from "@/hooks/event.ts";
|
||||
import { $computed, $ref } from "vue/macros";
|
||||
import { cloneDeep } from "lodash-es";
|
||||
import { DefaultShortcutKeyMap, Dict, DictType, ShortcutKey } from "@/types.ts";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import {APP_NAME, EXPORT_DATA_KEY, SAVE_DICT_KEY, SAVE_SETTING_KEY, SoundFileOptions} from "@/utils/const.ts";
|
||||
import { APP_NAME, EXPORT_DATA_KEY, SAVE_DICT_KEY, SAVE_SETTING_KEY, SoundFileOptions } from "@/utils/const.ts";
|
||||
import VolumeIcon from "@/components/icon/VolumeIcon.vue";
|
||||
import {BaseState, useBaseStore} from "@/stores/base.ts";
|
||||
import { BaseState, useBaseStore } from "@/stores/base.ts";
|
||||
import * as copy from "copy-to-clipboard";
|
||||
import {saveAs} from "file-saver";
|
||||
import {checkAndUpgradeSaveDict, checkAndUpgradeSaveSetting, shakeCommonDict} from "@/utils";
|
||||
import {dayjs} from "element-plus";
|
||||
import { saveAs } from "file-saver";
|
||||
import { checkAndUpgradeSaveDict, checkAndUpgradeSaveSetting, shakeCommonDict } from "@/utils";
|
||||
import { dayjs } from "element-plus";
|
||||
|
||||
|
||||
const emit = defineEmits<{
|
||||
@@ -344,7 +344,20 @@ function importData(e) {
|
||||
<label class="item-title">其他设置</label>
|
||||
</div>
|
||||
<div class="row">
|
||||
<label class="sub-title">切换下一个单词时间</label>
|
||||
<label class="sub-title">是否自动切换到下一个单词</label>
|
||||
<div class="wrapper">
|
||||
<el-switch v-model="settingStore.autoNext"
|
||||
inline-prompt
|
||||
active-text="开"
|
||||
inactive-text="关"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="desc">
|
||||
关闭后,当完成单词输入时,需要再次按下空格键切换下一个
|
||||
</div>
|
||||
<div class="row">
|
||||
<label class="sub-title">自动切换下一个单词延迟</label>
|
||||
<div class="wrapper">
|
||||
<el-input-number v-model="settingStore.waitTimeForChangeWord"
|
||||
:min="0"
|
||||
@@ -353,6 +366,20 @@ function importData(e) {
|
||||
<span>毫秒</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<label class="sub-title">默写时是否显示单词长度</label>
|
||||
<div class="wrapper">
|
||||
<el-switch v-model="settingStore.dictationShowWordLength"
|
||||
inline-prompt
|
||||
active-text="开"
|
||||
inactive-text="关"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="desc">
|
||||
默写时用下划线 _ 来显示每个字符。关闭后,用空格代替,用户将无法判断单词长度
|
||||
</div>
|
||||
</div>
|
||||
<div class="body" v-if="tabIndex === 2">
|
||||
<div class="row">
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
<script setup lang="ts">
|
||||
import {DefaultWord, ShortcutKey, Word} from "@/types.ts";
|
||||
import { DefaultWord, ShortcutKey, Word } from "@/types.ts";
|
||||
import VolumeIcon from "@/components/icon/VolumeIcon.vue";
|
||||
import {$computed, $ref} from "vue/macros";
|
||||
import {useBaseStore} from "@/stores/base.ts";
|
||||
import {usePracticeStore} from "@/stores/practice.ts";
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
import {usePlayBeep, usePlayCorrect, usePlayKeyboardAudio, usePlayWordAudio, useTTsPlayAudio} from "@/hooks/sound.ts";
|
||||
import {emitter, EventKey} from "@/utils/eventBus.ts";
|
||||
import {cloneDeep} from "lodash-es";
|
||||
import {onUnmounted, watch, onMounted} from "vue";
|
||||
import { $computed, $ref } from "vue/macros";
|
||||
import { useBaseStore } from "@/stores/base.ts";
|
||||
import { usePracticeStore } from "@/stores/practice.ts";
|
||||
import { useSettingStore } from "@/stores/setting.ts";
|
||||
import { usePlayBeep, usePlayCorrect, usePlayKeyboardAudio, usePlayWordAudio, useTTsPlayAudio } from "@/hooks/sound.ts";
|
||||
import { emitter, EventKey } from "@/utils/eventBus.ts";
|
||||
import { cloneDeep } from "lodash-es";
|
||||
import { onUnmounted, watch, onMounted } from "vue";
|
||||
import Tooltip from "@/components/Tooltip.vue";
|
||||
|
||||
interface IProps {
|
||||
@@ -27,6 +27,7 @@ const emit = defineEmits<{
|
||||
let input = $ref('')
|
||||
let wrong = $ref('')
|
||||
let showFullWord = $ref(false)
|
||||
let waitNext = $ref(false)
|
||||
//输入锁定,因为跳转到下一个单词有延时,如果重复在延时期间内重复输入,导致会跳转N次
|
||||
let inputLock = false
|
||||
let wordRepeatCount = 0
|
||||
@@ -79,6 +80,13 @@ function repeat() {
|
||||
}
|
||||
|
||||
async function onTyping(e: KeyboardEvent) {
|
||||
if (waitNext) {
|
||||
if (e.code === 'Space') {
|
||||
emit('next')
|
||||
waitNext = false
|
||||
}
|
||||
return
|
||||
}
|
||||
if (inputLock) return
|
||||
inputLock = true
|
||||
let letter = e.key
|
||||
@@ -110,13 +118,23 @@ async function onTyping(e: KeyboardEvent) {
|
||||
playCorrect()
|
||||
if (settingStore.repeatCount == 100) {
|
||||
if (settingStore.repeatCustomCount <= wordRepeatCount + 1) {
|
||||
setTimeout(() => emit('next'), settingStore.waitTimeForChangeWord)
|
||||
if (settingStore.autoNext) {
|
||||
setTimeout(() => emit('next'), settingStore.waitTimeForChangeWord)
|
||||
} else {
|
||||
waitNext = true
|
||||
inputLock = false
|
||||
}
|
||||
} else {
|
||||
repeat()
|
||||
}
|
||||
} else {
|
||||
if (settingStore.repeatCount <= wordRepeatCount + 1) {
|
||||
setTimeout(() => emit('next'), settingStore.waitTimeForChangeWord)
|
||||
if (settingStore.autoNext) {
|
||||
setTimeout(() => emit('next'), settingStore.waitTimeForChangeWord)
|
||||
} else {
|
||||
waitNext = true
|
||||
inputLock = false
|
||||
}
|
||||
} else {
|
||||
repeat()
|
||||
}
|
||||
@@ -139,6 +157,8 @@ function del() {
|
||||
function showWord() {
|
||||
if (settingStore.allowWordTip) {
|
||||
showFullWord = true
|
||||
//如果默写情况下,看了提示也视为输入错误
|
||||
emit('wrong')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,17 +183,17 @@ defineExpose({del, showWord, hideWord, play})
|
||||
>
|
||||
<div class="translate-item" v-for="(v,i) in word.trans">
|
||||
<span>{{ v }}</span>
|
||||
<!-- <div class="volumeIcon">-->
|
||||
<!-- <Tooltip-->
|
||||
<!-- v-if="i === word.trans.length - 1"-->
|
||||
<!-- :title="`发音(快捷键:${settingStore.shortcutKeyMap[ShortcutKey.PlayTranslatePronunciation]})`"-->
|
||||
<!-- >-->
|
||||
<!-- <VolumeIcon-->
|
||||
<!-- ref="volumeTranslateIconRef"-->
|
||||
<!-- :simple="true"-->
|
||||
<!-- :cb="()=>ttsPlayAudio(word.trans.join(';'))"/>-->
|
||||
<!-- </Tooltip>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="volumeIcon">-->
|
||||
<!-- <Tooltip-->
|
||||
<!-- v-if="i === word.trans.length - 1"-->
|
||||
<!-- :title="`发音(快捷键:${settingStore.shortcutKeyMap[ShortcutKey.PlayTranslatePronunciation]})`"-->
|
||||
<!-- >-->
|
||||
<!-- <VolumeIcon-->
|
||||
<!-- ref="volumeTranslateIconRef"-->
|
||||
<!-- :simple="true"-->
|
||||
<!-- :cb="()=>ttsPlayAudio(word.trans.join(';'))"/>-->
|
||||
<!-- </Tooltip>-->
|
||||
<!-- </div>-->
|
||||
</div>
|
||||
</div>
|
||||
<div class="word-wrapper">
|
||||
@@ -185,10 +205,10 @@ defineExpose({del, showWord, hideWord, play})
|
||||
<span class="wrong" v-if="wrong">{{ wrong }}</span>
|
||||
<template v-if="settingStore.dictation">
|
||||
<span class="letter" v-if="!showFullWord"
|
||||
@mouseenter="settingStore.allowWordTip && (showFullWord = true)">{{
|
||||
displayWord.split('').map(() => '_').join('')
|
||||
@mouseenter="showWord">{{
|
||||
displayWord.split('').map(() => settingStore.dictationShowWordLength ? '_' : ' ').join('')
|
||||
}}</span>
|
||||
<span class="letter" v-else @mouseleave="showFullWord = false">{{ displayWord }}</span>
|
||||
<span class="letter" v-else @mouseleave="hideWord">{{ displayWord }}</span>
|
||||
</template>
|
||||
<span class="letter" v-else>{{ displayWord }}</span>
|
||||
</div>
|
||||
@@ -198,7 +218,7 @@ defineExpose({del, showWord, hideWord, play})
|
||||
<VolumeIcon ref="volumeIconRef" :simple="true" :cb="() => playWordAudio(word.name)"/>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div class="phonetic" v-if="settingStore.wordSoundType === 'us' && word.usphone">[{{ word.usphone}}]</div>
|
||||
<div class="phonetic" v-if="settingStore.wordSoundType === 'us' && word.usphone">[{{ word.usphone }}]</div>
|
||||
<div class="phonetic" v-if="settingStore.wordSoundType === 'uk' && word.ukphone">[{{ word.ukphone }}]</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
<script setup lang="ts">
|
||||
import {onMounted, onUnmounted, watch} from "vue"
|
||||
import {$computed, $ref} from "vue/macros"
|
||||
import {useBaseStore} from "@/stores/base.ts"
|
||||
import {DefaultDisplayStatistics, DictType, ShortcutKey, Sort, Word} from "../../../types.ts";
|
||||
import {emitter, EventKey} from "@/utils/eventBus.ts"
|
||||
import {cloneDeep, reverse, shuffle} from "lodash-es"
|
||||
import {usePracticeStore} from "@/stores/practice.ts"
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
import {useOnKeyboardEventListener, useWindowClick} from "@/hooks/event.ts";
|
||||
import {Icon} from "@iconify/vue";
|
||||
import { onMounted, onUnmounted, watch } from "vue"
|
||||
import { $computed, $ref } from "vue/macros"
|
||||
import { useBaseStore } from "@/stores/base.ts"
|
||||
import { DefaultDisplayStatistics, DictType, ShortcutKey, Sort, Word } from "../../../types.ts";
|
||||
import { emitter, EventKey } from "@/utils/eventBus.ts"
|
||||
import { cloneDeep, reverse, shuffle } from "lodash-es"
|
||||
import { usePracticeStore } from "@/stores/practice.ts"
|
||||
import { useSettingStore } from "@/stores/setting.ts";
|
||||
import { useOnKeyboardEventListener, useWindowClick } from "@/hooks/event.ts";
|
||||
import { Icon } from "@iconify/vue";
|
||||
import Tooltip from "@/components/Tooltip.vue";
|
||||
import Options from "@/pages/practice/Options.vue";
|
||||
import Typing from "@/pages/practice/practice-word/Typing.vue";
|
||||
import Panel from "@/pages/practice/Panel.vue";
|
||||
import IconWrapper from "@/components/IconWrapper.vue";
|
||||
import {useRuntimeStore} from "@/stores/runtime.ts";
|
||||
import {syncMyDictList, useWordOptions} from "@/hooks/dict.ts";
|
||||
import { useRuntimeStore } from "@/stores/runtime.ts";
|
||||
import { syncMyDictList, useWordOptions } from "@/hooks/dict.ts";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import WordList from "@/components/list/WordList.vue";
|
||||
import Empty from "@/components/Empty.vue";
|
||||
@@ -99,7 +99,6 @@ const nextWord: Word = $computed(() => {
|
||||
|
||||
function next(isTyping: boolean = true) {
|
||||
if (data.index === data.words.length - 1) {
|
||||
|
||||
//复制当前错词,因为第一遍错词是最多的,后续的练习都是从错词中练习
|
||||
if (stat.total === -1) {
|
||||
let now = Date.now()
|
||||
@@ -140,8 +139,7 @@ function next(isTyping: boolean = true) {
|
||||
data.index++
|
||||
isTyping && practiceStore.inputWordNumber++
|
||||
console.log('这个词完了')
|
||||
if ([DictType.word].includes(store.currentDict.type)
|
||||
&& store.skipWordNames.includes(word.name.toLowerCase())) {
|
||||
if (store.skipWordNames.includes(word.name.toLowerCase())) {
|
||||
next()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,108 +1,114 @@
|
||||
import {defineStore} from "pinia"
|
||||
import {cloneDeep, merge} from "lodash-es";
|
||||
import {DefaultShortcutKeyMap} from "@/types.ts";
|
||||
import {SAVE_SETTING_KEY} from "@/utils/const.ts";
|
||||
import {checkAndUpgradeSaveDict, checkAndUpgradeSaveSetting} from "@/utils";
|
||||
import { defineStore } from "pinia"
|
||||
import { cloneDeep, merge } from "lodash-es";
|
||||
import { DefaultShortcutKeyMap } from "@/types.ts";
|
||||
import { SAVE_SETTING_KEY } from "@/utils/const.ts";
|
||||
import { checkAndUpgradeSaveDict, checkAndUpgradeSaveSetting } from "@/utils";
|
||||
|
||||
export interface SettingState {
|
||||
showToolbar: boolean,
|
||||
show: boolean,
|
||||
showToolbar: boolean,
|
||||
show: boolean,
|
||||
|
||||
allSound: boolean,
|
||||
wordSound: boolean,
|
||||
wordSoundVolume: number,
|
||||
wordSoundSpeed: number,
|
||||
wordSoundType: string,
|
||||
keyboardSound: boolean,
|
||||
keyboardSoundVolume: number,
|
||||
keyboardSoundFile: string,
|
||||
translateSound: boolean,
|
||||
translateSoundVolume: number,
|
||||
effectSound: boolean,
|
||||
effectSoundVolume: 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,
|
||||
theme: string,
|
||||
collapse: boolean,
|
||||
chapterWordNumber: number,
|
||||
shortcutKeyMap: Record<string, string>,
|
||||
first: boolean
|
||||
load: boolean
|
||||
allSound: boolean,
|
||||
wordSound: boolean,
|
||||
wordSoundVolume: number,
|
||||
wordSoundSpeed: number,
|
||||
wordSoundType: string,
|
||||
keyboardSound: boolean,
|
||||
keyboardSoundVolume: number,
|
||||
keyboardSoundFile: string,
|
||||
translateSound: boolean,
|
||||
translateSoundVolume: number,
|
||||
effectSound: boolean,
|
||||
effectSoundVolume: number,
|
||||
repeatCount: number,
|
||||
repeatCustomCount?: number,
|
||||
dictation: boolean,
|
||||
translate: boolean,
|
||||
showNearWord: boolean
|
||||
ignoreCase: boolean
|
||||
allowWordTip: boolean
|
||||
waitTimeForChangeWord: number
|
||||
autoNext: boolean
|
||||
dictationShowWordLength: boolean//默写时显示单词长度,即用下划线 _ 来显示每个字符
|
||||
fontSize: {
|
||||
articleForeignFontSize: number,
|
||||
articleTranslateFontSize: number,
|
||||
wordForeignFontSize: number,
|
||||
wordTranslateFontSize: number,
|
||||
},
|
||||
showPanel: boolean,
|
||||
theme: string,
|
||||
collapse: boolean,
|
||||
chapterWordNumber: number,
|
||||
shortcutKeyMap: Record<string, string>,
|
||||
first: boolean
|
||||
load: boolean
|
||||
}
|
||||
|
||||
export const DefaultSettingState = (): SettingState => ({
|
||||
showToolbar: true,
|
||||
show: false,
|
||||
showPanel: true,
|
||||
showToolbar: true,
|
||||
show: false,
|
||||
showPanel: true,
|
||||
|
||||
allSound: true,
|
||||
wordSound: true,
|
||||
wordSoundVolume: 100,
|
||||
wordSoundSpeed: 1,
|
||||
wordSoundType: 'us',
|
||||
keyboardSound: true,
|
||||
keyboardSoundVolume: 100,
|
||||
keyboardSoundFile: '机械键盘2',
|
||||
translateSound: true,
|
||||
translateSoundVolume: 100,
|
||||
effectSound: true,
|
||||
effectSoundVolume: 100,
|
||||
repeatCount: 1,
|
||||
repeatCustomCount: null,
|
||||
dictation: false,
|
||||
translate: true,
|
||||
allSound: true,
|
||||
wordSound: true,
|
||||
wordSoundVolume: 100,
|
||||
wordSoundSpeed: 1,
|
||||
wordSoundType: 'us',
|
||||
keyboardSound: true,
|
||||
keyboardSoundVolume: 100,
|
||||
keyboardSoundFile: '机械键盘2',
|
||||
translateSound: true,
|
||||
translateSoundVolume: 100,
|
||||
effectSound: true,
|
||||
effectSoundVolume: 100,
|
||||
repeatCount: 1,
|
||||
repeatCustomCount: null,
|
||||
dictation: false,
|
||||
translate: true,
|
||||
|
||||
showNearWord: true,
|
||||
ignoreCase: true,
|
||||
allowWordTip: true,
|
||||
fontSize: {
|
||||
articleForeignFontSize: 48,
|
||||
articleTranslateFontSize: 20,
|
||||
wordForeignFontSize: 48,
|
||||
wordTranslateFontSize: 20,
|
||||
},
|
||||
waitTimeForChangeWord: 300,
|
||||
|
||||
theme: 'auto',
|
||||
collapse: false,
|
||||
chapterWordNumber: DefaultChapterWordNumber,
|
||||
shortcutKeyMap: cloneDeep(DefaultShortcutKeyMap),
|
||||
first: true,
|
||||
load: false
|
||||
showNearWord: true,
|
||||
ignoreCase: true,
|
||||
allowWordTip: true,
|
||||
fontSize: {
|
||||
articleForeignFontSize: 48,
|
||||
articleTranslateFontSize: 20,
|
||||
wordForeignFontSize: 48,
|
||||
wordTranslateFontSize: 20,
|
||||
},
|
||||
waitTimeForChangeWord: 300,
|
||||
autoNext: true,
|
||||
dictationShowWordLength: true,
|
||||
theme: 'auto',
|
||||
collapse: false,
|
||||
chapterWordNumber: DefaultChapterWordNumber,
|
||||
shortcutKeyMap: cloneDeep(DefaultShortcutKeyMap),
|
||||
first: true,
|
||||
load: false
|
||||
})
|
||||
export const DefaultChapterWordNumber = 30
|
||||
export const useSettingStore = defineStore('setting', {
|
||||
state: (): SettingState => {
|
||||
return DefaultSettingState()
|
||||
state: (): SettingState => {
|
||||
return DefaultSettingState()
|
||||
},
|
||||
actions: {
|
||||
setState(obj: any) {
|
||||
//这样不会丢失watch的值的引用
|
||||
merge(this, obj)
|
||||
},
|
||||
actions: {
|
||||
setState(obj: any) {
|
||||
//这样不会丢失watch的值的引用
|
||||
merge(this, obj)
|
||||
},
|
||||
init() {
|
||||
return new Promise(resolve => {
|
||||
let configStr = localStorage.getItem(SAVE_SETTING_KEY.key)
|
||||
if (!configStr) configStr = localStorage.getItem(SAVE_SETTING_KEY.oldKey)
|
||||
let data = checkAndUpgradeSaveSetting(configStr)
|
||||
this.setState(data)
|
||||
localStorage.setItem(SAVE_SETTING_KEY.key, JSON.stringify({val: this.$state, version: SAVE_SETTING_KEY.version}))
|
||||
this.load = true
|
||||
resolve(true)
|
||||
})
|
||||
}
|
||||
init() {
|
||||
return new Promise(resolve => {
|
||||
let configStr = localStorage.getItem(SAVE_SETTING_KEY.key)
|
||||
if (!configStr) configStr = localStorage.getItem(SAVE_SETTING_KEY.oldKey)
|
||||
let data = checkAndUpgradeSaveSetting(configStr)
|
||||
this.setState(data)
|
||||
localStorage.setItem(SAVE_SETTING_KEY.key, JSON.stringify({
|
||||
val: this.$state,
|
||||
version: SAVE_SETTING_KEY.version
|
||||
}))
|
||||
this.load = true
|
||||
resolve(true)
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user