This commit is contained in:
zyronon
2023-11-03 18:52:42 +08:00
parent c8413334e5
commit 0933013755
12 changed files with 138 additions and 124 deletions

View File

@@ -49,14 +49,6 @@ onMounted(() => {
})
})
useEventListener('keyup', (e: KeyboardEvent) => {
if (e.key === 'Escape') {
let lastItem = runtimeStore.modalList.pop()
lastItem && lastItem.close()
}
})
onMounted(() => {
})
</script>

View File

@@ -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;

View File

@@ -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;

View File

@@ -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>

View File

@@ -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">

View File

@@ -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>

View File

@@ -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 }}个单词

View File

@@ -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(() => {

View File

@@ -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>

View File

@@ -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
}
}

View File

@@ -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)
}
}
})
}

View File

@@ -10,4 +10,8 @@ export const EventKey = {
keydown: 'keydown',
keyup: 'keyup',
onTyping: 'onTyping',
repeat: 'repeat',
next: 'next',
write: 'write',
restart: 'restart'
}