fix bug
This commit is contained in:
@@ -49,14 +49,6 @@ onMounted(() => {
|
||||
})
|
||||
})
|
||||
|
||||
useEventListener('keyup', (e: KeyboardEvent) => {
|
||||
if (e.key === 'Escape') {
|
||||
let lastItem = runtimeStore.modalList.pop()
|
||||
lastItem && lastItem.close()
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import {onMounted, toRef, watch} from "vue";
|
||||
import {onMounted, onUnmounted, watch} from "vue";
|
||||
import Tooltip from "@/components/Tooltip.vue";
|
||||
import {Icon} from '@iconify/vue';
|
||||
import {useEsc} from "@/hooks/event.ts";
|
||||
import {useEventListener} from "@/hooks/event.ts";
|
||||
import {$ref} from "vue/macros";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import {useRuntimeStore} from "@/stores/runtime.ts";
|
||||
@@ -43,6 +43,7 @@ let openTime = $ref(Date.now())
|
||||
let maskRef = $ref<HTMLDivElement>(null)
|
||||
let modalRef = $ref<HTMLDivElement>(null)
|
||||
const runtimeStore = useRuntimeStore()
|
||||
let id = Date.now()
|
||||
|
||||
function close() {
|
||||
if (!visible) {
|
||||
@@ -65,7 +66,10 @@ function close() {
|
||||
emit('close')
|
||||
visible = false
|
||||
resolve(true)
|
||||
runtimeStore.modalList.pop()
|
||||
let rIndex = runtimeStore.modalList.findIndex(item => item.id === id)
|
||||
if (rIndex > 0) {
|
||||
runtimeStore.modalList.splice(rIndex, 1)
|
||||
}
|
||||
}, closeTime)
|
||||
});
|
||||
}
|
||||
@@ -73,10 +77,8 @@ function close() {
|
||||
watch(() => props.modelValue, n => {
|
||||
// console.log('n', n)
|
||||
if (n) {
|
||||
runtimeStore.modalList.push({
|
||||
id: Date.now(),
|
||||
close
|
||||
})
|
||||
id = Date.now()
|
||||
runtimeStore.modalList.push({id, close})
|
||||
zIndex = zIndex + runtimeStore.modalList.length
|
||||
visible = true
|
||||
} else {
|
||||
@@ -88,15 +90,30 @@ onMounted(() => {
|
||||
// console.log('props.modelValue', props.modelValue)
|
||||
if (props.modelValue === undefined) {
|
||||
visible = true
|
||||
runtimeStore.modalList.push({
|
||||
id: Date.now(),
|
||||
close
|
||||
})
|
||||
id = Date.now()
|
||||
runtimeStore.modalList.push({id, close})
|
||||
zIndex = zIndex + runtimeStore.modalList.length
|
||||
}
|
||||
})
|
||||
|
||||
useEsc(close, () => props.modelValue)
|
||||
onUnmounted(() => {
|
||||
if (props.modelValue === undefined) {
|
||||
visible = false
|
||||
let rIndex = runtimeStore.modalList.findIndex(item => item.id === id)
|
||||
if (rIndex > 0) {
|
||||
runtimeStore.modalList.splice(rIndex, 1)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
useEventListener('keyup', (e: KeyboardEvent) => {
|
||||
if (e.key === 'Escape') {
|
||||
let lastItem = runtimeStore.modalList[runtimeStore.modalList.length - 1]
|
||||
if (lastItem?.id === id) {
|
||||
close()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
async function ok() {
|
||||
await close()
|
||||
@@ -252,7 +269,7 @@ $header-height: 60rem;
|
||||
flex-direction: column;
|
||||
transition: transform $time, opacity $time;
|
||||
|
||||
.close{
|
||||
.close {
|
||||
position: absolute;
|
||||
right: 20rem;
|
||||
top: 20rem;
|
||||
|
||||
@@ -85,15 +85,15 @@ $bg-color: rgb(226, 226, 226);
|
||||
|
||||
.pop-confirm-content {
|
||||
position: fixed;
|
||||
background: white;
|
||||
background: var(--color-tooltip-bg);
|
||||
padding: 15rem;
|
||||
box-shadow: 0 0 12px rgba(0, 0, 0, .2);
|
||||
border-radius: 4rem;
|
||||
transform: translate(-50%, calc(-100% - 10rem));
|
||||
box-shadow: 0 0 6px 1px var(--color-tooltip-shadow);
|
||||
z-index: 999;
|
||||
|
||||
.text {
|
||||
color: black;
|
||||
color: var(--color-font-1);
|
||||
text-align: start;
|
||||
font-size: 14rem;
|
||||
width: 150rem;
|
||||
|
||||
@@ -11,6 +11,10 @@ import {useSettingStore} from "@/stores/setting.ts";
|
||||
import Close from "@/components/Close.vue";
|
||||
import Empty from "@/components/Empty.vue";
|
||||
import ArticleList from "@/components/Article/ArticleList.vue";
|
||||
import {useWordOptions} from "@/hooks/dict.ts";
|
||||
import {Icon} from "@iconify/vue";
|
||||
import Tooltip from "@/components/Tooltip.vue";
|
||||
import IconWrapper from "@/components/IconWrapper.vue";
|
||||
|
||||
const store = useBaseStore()
|
||||
const settingStore = useSettingStore()
|
||||
@@ -32,6 +36,11 @@ function changeIndex(i: number, dict: Dict) {
|
||||
})
|
||||
}
|
||||
|
||||
const {
|
||||
delWrongWord,
|
||||
delSimpleWord
|
||||
} = useWordOptions()
|
||||
|
||||
</script>
|
||||
<template>
|
||||
<Transition name="fade">
|
||||
@@ -45,8 +54,8 @@ function changeIndex(i: number, dict: Dict) {
|
||||
<div class="tabs">
|
||||
<div class="tab" :class="tabIndex === 0 && 'active'" @click="tabIndex = 0">当前</div>
|
||||
<div class="tab" :class="tabIndex === 1 && 'active'" @click="tabIndex = 1">{{ store.collect.name }}</div>
|
||||
<div class="tab" :class="tabIndex === 2 && 'active'" @click="tabIndex = 2">{{ store.wrong.name }}</div>
|
||||
<div class="tab" :class="tabIndex === 3 && 'active'" @click="tabIndex = 3">{{ store.simple.name }}</div>
|
||||
<div class="tab" :class="tabIndex === 2 && 'active'" @click="tabIndex = 2">{{ store.simple.name }}</div>
|
||||
<div class="tab" :class="tabIndex === 3 && 'active'" @click="tabIndex = 3">{{ store.wrong.name }}</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="slide">
|
||||
@@ -62,14 +71,18 @@ function changeIndex(i: number, dict: Dict) {
|
||||
<el-radio-button border :label="DictType.word">单词</el-radio-button>
|
||||
<el-radio-button border :label="DictType.article">文章</el-radio-button>
|
||||
</el-radio-group>
|
||||
<div class="dict-name" v-if="practiceType === DictType.word">{{
|
||||
store.collect.words.length
|
||||
}}个单词
|
||||
<div class="dict-name" v-if="practiceType === DictType.word">
|
||||
{{ store.collect.words.length }}个单词
|
||||
</div>
|
||||
<div class="dict-name" v-else> {{ store.collect.articles.length }}篇文章</div>
|
||||
<!-- <Tooltip title="添加">-->
|
||||
<!-- <IconWrapper>-->
|
||||
<!-- <Icon icon="fluent:add-12-regular"/>-->
|
||||
<!-- </IconWrapper>-->
|
||||
<!-- </Tooltip>-->
|
||||
</div>
|
||||
<template v-if="store.current.dictType !== DictType.collect &&
|
||||
(
|
||||
(
|
||||
( practiceType === DictType.word && store.collect.words.length) ||
|
||||
( practiceType === DictType.article && store.collect.articles.length)
|
||||
)">
|
||||
@@ -98,6 +111,27 @@ function changeIndex(i: number, dict: Dict) {
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<div class="slide-item">
|
||||
<div class="panel-page-item" v-if="store.simple.words.length">
|
||||
<header>
|
||||
<div class="dict-name">总词数:{{ store.simple.words.length }}</div>
|
||||
<template v-if="store.current.dictType !== DictType.simple && store.simple.words.length">
|
||||
<PopConfirm
|
||||
:title="`确认切换?`"
|
||||
@confirm="changeIndex(0,store.simple)"
|
||||
>
|
||||
<BaseButton size="small">切换</BaseButton>
|
||||
</PopConfirm>
|
||||
</template>
|
||||
</header>
|
||||
<WordList
|
||||
class="word-list"
|
||||
:show-del="true"
|
||||
@del="delSimpleWord"
|
||||
:list="store.simple.words"/>
|
||||
</div>
|
||||
<Empty v-else/>
|
||||
</div>
|
||||
<div class="slide-item">
|
||||
<div class="panel-page-item" v-if="store.wrong.words.length">
|
||||
<header>
|
||||
@@ -115,29 +149,11 @@ function changeIndex(i: number, dict: Dict) {
|
||||
<WordList
|
||||
class="word-list"
|
||||
:show-del="true"
|
||||
@del="delWrongWord"
|
||||
:list="store.wrong.words"/>
|
||||
</div>
|
||||
<Empty v-else/>
|
||||
</div>
|
||||
<div class="slide-item">
|
||||
<div class="panel-page-item" v-if="store.simple.words.length">
|
||||
<header>
|
||||
<div class="dict-name">总词数:{{ store.simple.words.length }}</div>
|
||||
<template v-if="store.current.dictType !== DictType.simple && store.simple.words.length">
|
||||
<PopConfirm
|
||||
:title="`确认切换?`"
|
||||
@confirm="changeIndex(0,store.simple)"
|
||||
>
|
||||
<BaseButton size="small">切换</BaseButton>
|
||||
</PopConfirm>
|
||||
</template>
|
||||
</header>
|
||||
<WordList
|
||||
class="word-list"
|
||||
:list="store.simple.words"/>
|
||||
</div>
|
||||
<Empty v-else/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -32,28 +32,6 @@ watch(practiceStore, () => {
|
||||
practiceStore.correctRate = 100 - Math.trunc(((practiceStore.wrongWordNumber) / (practiceStore.inputWordNumber)) * 100)
|
||||
})
|
||||
|
||||
function write() {
|
||||
// console.log('write')
|
||||
settingStore.dictation = true
|
||||
repeat()
|
||||
}
|
||||
|
||||
//TODO 需要判断是否已忽略
|
||||
function repeat() {
|
||||
// console.log('repeat')
|
||||
// getCurrentPractice()
|
||||
emitter.emit(EventKey.resetWord)
|
||||
}
|
||||
|
||||
function next() {
|
||||
// console.log('next')
|
||||
store.currentDict.chapterIndex++
|
||||
// repeat()
|
||||
}
|
||||
|
||||
function restart() {
|
||||
store.currentDict.chapterIndex = 0
|
||||
}
|
||||
|
||||
function test() {
|
||||
MessageBox.confirm(
|
||||
@@ -75,12 +53,7 @@ function test() {
|
||||
<PracticeWord v-else/>
|
||||
<Footer/>
|
||||
</div>
|
||||
<Statistics
|
||||
@write="write"
|
||||
@repeat="repeat"
|
||||
@next="next"
|
||||
@restart="restart"
|
||||
/>
|
||||
<Statistics/>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
@@ -4,12 +4,15 @@ import TypingWord from "@/components/Practice/PracticeWord/TypingWord.vue";
|
||||
import {$ref} from "vue/macros";
|
||||
import {chunk, cloneDeep} from "lodash-es";
|
||||
import {useBaseStore} from "@/stores/base.ts";
|
||||
import {onMounted, watch} from "vue";
|
||||
import {onMounted, onUnmounted, watch} from "vue";
|
||||
import {useRuntimeStore} from "@/stores/runtime.ts";
|
||||
import {Word} from "@/types.ts";
|
||||
import {emitter, EventKey} from "@/utils/eventBus.ts";
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
|
||||
const store = useBaseStore()
|
||||
const runtimeStore = useRuntimeStore()
|
||||
const settingStore = useSettingStore()
|
||||
|
||||
let wordData = $ref({
|
||||
words: [],
|
||||
@@ -18,7 +21,6 @@ let wordData = $ref({
|
||||
|
||||
watch([
|
||||
() => store.load,
|
||||
() => store.currentDict.chapterIndex,
|
||||
() => store.currentDict.words,
|
||||
], n => {
|
||||
getCurrentPractice()
|
||||
@@ -37,8 +39,43 @@ function getCurrentPractice() {
|
||||
// console.log('wordData', wordData)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
function write() {
|
||||
// console.log('write')
|
||||
settingStore.dictation = true
|
||||
repeat()
|
||||
}
|
||||
|
||||
//TODO 需要判断是否已忽略
|
||||
function repeat() {
|
||||
// console.log('repeat')
|
||||
emitter.emit(EventKey.resetWord)
|
||||
getCurrentPractice()
|
||||
}
|
||||
|
||||
function next() {
|
||||
// console.log('next')
|
||||
store.currentDict.chapterIndex++
|
||||
repeat()
|
||||
}
|
||||
|
||||
function restart() {
|
||||
store.currentDict.chapterIndex = 0
|
||||
repeat()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
emitter.on(EventKey.next, next)
|
||||
emitter.on(EventKey.write, write)
|
||||
emitter.on(EventKey.repeat, repeat)
|
||||
emitter.on(EventKey.restart, restart)
|
||||
getCurrentPractice()
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
emitter.off(EventKey.next, next)
|
||||
emitter.off(EventKey.write, write)
|
||||
emitter.off(EventKey.repeat, repeat)
|
||||
emitter.off(EventKey.restart, restart)
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
@@ -228,6 +228,12 @@ useOnKeyboardEventListener(onKeyDown, onKeyUp)
|
||||
<div class="title">
|
||||
{{ store.dictTitle }}
|
||||
</div>
|
||||
<Tooltip title="下一章"
|
||||
v-if="store.currentDict.chapterIndex < store.currentDict.chapterWords.length - 1 && !store.isArticle">
|
||||
<IconWrapper>
|
||||
<Icon @click="emitter.emit(EventKey.next)" icon="octicon:arrow-right-24"/>
|
||||
</IconWrapper>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div class="right">
|
||||
{{ data.words.length }}个单词
|
||||
|
||||
@@ -16,13 +16,6 @@ const store = useBaseStore()
|
||||
let statModalIsOpen = $ref(false)
|
||||
let currentStat = reactive<DisplayStatistics>(cloneDeep(DefaultDisplayStatistics))
|
||||
|
||||
const emit = defineEmits([
|
||||
'repeat',
|
||||
'next',
|
||||
'write',
|
||||
'restart'
|
||||
])
|
||||
|
||||
onMounted(() => {
|
||||
emitter.on(EventKey.openStatModal, (stat: DisplayStatistics) => {
|
||||
currentStat = {...DefaultDisplayStatistics, ...stat}
|
||||
@@ -36,7 +29,7 @@ let optionType = $ref('')
|
||||
function options(emitType: 'write' | 'repeat' | 'next' | 'restart') {
|
||||
statModalIsOpen = false
|
||||
optionType = emitType
|
||||
emit(emitType)
|
||||
emitter.emit(EventKey[emitType])
|
||||
}
|
||||
|
||||
const isEnd = $computed(() => {
|
||||
|
||||
@@ -24,7 +24,7 @@ const props = withDefaults(defineProps<{
|
||||
})
|
||||
|
||||
const emit = defineEmits<{
|
||||
del: [i: number],
|
||||
del: [val: Word],
|
||||
change: [i: number]
|
||||
}>()
|
||||
|
||||
@@ -78,7 +78,7 @@ const {
|
||||
:is-simple="isWordSimple(word)"
|
||||
@toggle-simple="toggleWordSimple(word)"
|
||||
:show-del="showDel"
|
||||
@del="delWrongWord(word)"
|
||||
@del="emit('del',word)"
|
||||
>
|
||||
<div class="item-title">
|
||||
<span class="word" :class="!showWord && 'text-shadow'">{{ word.name }}</span>
|
||||
|
||||
@@ -46,11 +46,19 @@ export function useWordOptions() {
|
||||
}
|
||||
}
|
||||
|
||||
function delSimpleWord(val: Word) {
|
||||
let rIndex = store.simple.originWords.findIndex(v => v.name.toLowerCase() === val.name.toLowerCase())
|
||||
if (rIndex > -1) {
|
||||
store.simple.originWords.splice(rIndex, 1)
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
isWordCollect,
|
||||
toggleWordCollect,
|
||||
isWordSimple,
|
||||
toggleWordSimple,
|
||||
delWrongWord
|
||||
delWrongWord,
|
||||
delSimpleWord
|
||||
}
|
||||
}
|
||||
@@ -41,7 +41,7 @@ export function useStartKeyboardEventListener() {
|
||||
|| e.keyCode === 229
|
||||
) {
|
||||
emitter.emit(EventKey.onTyping, e)
|
||||
}else {
|
||||
} else {
|
||||
emitter.emit(EventKey.keydown, e)
|
||||
}
|
||||
}
|
||||
@@ -84,35 +84,3 @@ export function useDisableEventListener(watchVal?: any) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export function useEsc(close: () => void, watchVal?: any) {
|
||||
const runtimeStore = useRuntimeStore()
|
||||
const id = $ref(Date.now())
|
||||
|
||||
watch(watchVal, n => {
|
||||
if (n) {
|
||||
runtimeStore.modalList.push({id, close})
|
||||
} else {
|
||||
let rIndex = runtimeStore.modalList.findIndex(item => item.id === id)
|
||||
if (rIndex > 0) {
|
||||
runtimeStore.modalList.splice(rIndex, 1)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
if (watchVal() === undefined) {
|
||||
runtimeStore.modalList.push({id, close})
|
||||
}
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
if (watchVal() === undefined) {
|
||||
let rIndex = runtimeStore.modalList.findIndex(item => item.id === id)
|
||||
if (rIndex > 0) {
|
||||
runtimeStore.modalList.splice(rIndex, 1)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -10,4 +10,8 @@ export const EventKey = {
|
||||
keydown: 'keydown',
|
||||
keyup: 'keyup',
|
||||
onTyping: 'onTyping',
|
||||
repeat: 'repeat',
|
||||
next: 'next',
|
||||
write: 'write',
|
||||
restart: 'restart'
|
||||
}
|
||||
Reference in New Issue
Block a user