Allow yourself to add favorite words and articles for practice
This commit is contained in:
@@ -30,7 +30,7 @@ const DefaultDictForm = {
|
||||
tags: [],
|
||||
translateLanguage: 'zh-CN',
|
||||
language: 'en',
|
||||
type: DictType.customWord
|
||||
type: DictType.word
|
||||
}
|
||||
let dictForm: any = $ref(cloneDeep(DefaultDictForm))
|
||||
const dictFormRef = $ref<FormInstance>()
|
||||
@@ -156,9 +156,9 @@ onMounted(() => {
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="类型">
|
||||
<el-select v-model="dictForm.type" placeholder="请选择选项">
|
||||
<el-option label="单词" :value="DictType.customWord"/>
|
||||
<el-option label="文章" :value="DictType.customArticle"/>
|
||||
<el-select v-model="dictForm.type" placeholder="请选择选项" :disabled="dictForm.id">
|
||||
<el-option label="单词" :value="DictType.word"/>
|
||||
<el-option label="文章" :value="DictType.article"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<div class="flex-center">
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import {useBaseStore} from "@/stores/base.ts"
|
||||
|
||||
import {$ref} from "vue/macros"
|
||||
import {computed, onMounted, provide, watch} from "vue"
|
||||
import {$computed, $ref} from "vue/macros"
|
||||
import {computed, onMounted, onUnmounted, provide, watch} from "vue"
|
||||
import {Dict, DictType, ShortcutKey} from "@/types.ts"
|
||||
import PopConfirm from "@/components/PopConfirm.vue"
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
@@ -20,6 +20,7 @@ import {useRuntimeStore} from "@/stores/runtime.ts";
|
||||
import {cloneDeep} from "lodash-es";
|
||||
import WordList from "@/components/list/WordList.vue";
|
||||
import ArticleList from "@/components/list/ArticleList.vue";
|
||||
import Slide from "@/components/Slide.vue";
|
||||
|
||||
const router = useRouter()
|
||||
const store = useBaseStore()
|
||||
@@ -36,8 +37,8 @@ watch(() => settingStore.showPanel, n => {
|
||||
|
||||
let practiceType = $ref(DictType.word)
|
||||
|
||||
function changeIndex(i: number, dict: Dict) {
|
||||
store.changeDict(dict, dict.chapterIndex, i, practiceType)
|
||||
function changeIndex(dict: Dict) {
|
||||
store.changeDict(dict, dict.chapterIndex, dict.wordIndex, practiceType)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
@@ -46,6 +47,10 @@ onMounted(() => {
|
||||
})
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
emitter.off(EventKey.changeDict)
|
||||
})
|
||||
|
||||
const {
|
||||
delWrongWord,
|
||||
delSimpleWord,
|
||||
@@ -53,7 +58,6 @@ const {
|
||||
} = useWordOptions()
|
||||
|
||||
const {
|
||||
isArticleCollect,
|
||||
toggleArticleCollect
|
||||
} = useArticleOptions()
|
||||
|
||||
@@ -67,6 +71,19 @@ function addSimple() {
|
||||
router.push({path: '/dict', query: {type: 'addWordOrArticle'}})
|
||||
}
|
||||
|
||||
const showCollectToggleButton = $computed(() => {
|
||||
if (store.currentDict.type === DictType.collect) {
|
||||
if (store.current.practiceType !== practiceType) {
|
||||
return (practiceType === DictType.word && store.collect.words.length) ||
|
||||
(practiceType === DictType.article && store.collect.articles.length)
|
||||
}
|
||||
} else {
|
||||
return (practiceType === DictType.word && store.collect.words.length) ||
|
||||
(practiceType === DictType.article && store.collect.articles.length)
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
</script>
|
||||
<template>
|
||||
<Transition name="fade">
|
||||
@@ -87,140 +104,126 @@ function addSimple() {
|
||||
<div class="tab" :class="tabIndex === 3 && 'active'" @click="tabIndex = 3">{{ store.wrong.name }}</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="slide">
|
||||
<div class="slide-list" :class="`step${tabIndex}`">
|
||||
<div class="slide-item">
|
||||
<slot :active="tabIndex === 0 && settingStore.showPanel"></slot>
|
||||
</div>
|
||||
<div class="slide-item">
|
||||
<div class="panel-page-item">
|
||||
<div class="list-header">
|
||||
<div class="left">
|
||||
<el-radio-group v-model="practiceType">
|
||||
<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">
|
||||
{{ store.collect.words.length }}个单词
|
||||
</div>
|
||||
<div class="dict-name" v-if="practiceType === DictType.article && store.collect.articles.length">
|
||||
{{ store.collect.articles.length }}篇文章
|
||||
</div>
|
||||
<Tooltip title="添加">
|
||||
<IconWrapper>
|
||||
<Icon icon="fluent:add-12-regular" @click="addCollect"/>
|
||||
</IconWrapper>
|
||||
</Tooltip>
|
||||
<Slide :slide-count="4" :step="tabIndex">
|
||||
<div class="slide-item">
|
||||
<slot :active="tabIndex === 0 && settingStore.showPanel"></slot>
|
||||
</div>
|
||||
<div class="slide-item">
|
||||
<div class="panel-page-item">
|
||||
<div class="list-header">
|
||||
<div class="left">
|
||||
<el-radio-group v-model="practiceType">
|
||||
<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">
|
||||
{{ store.collect.words.length }}个单词
|
||||
</div>
|
||||
<template v-if="store.currentDict.type !== DictType.collect &&
|
||||
(
|
||||
( practiceType === DictType.word && store.collect.words.length) ||
|
||||
( practiceType === DictType.article && store.collect.articles.length)
|
||||
)">
|
||||
<PopConfirm
|
||||
:title="`确认切换?`"
|
||||
@confirm="changeIndex(0,store.collect)"
|
||||
>
|
||||
<BaseButton size="small">切换</BaseButton>
|
||||
</PopConfirm>
|
||||
</template>
|
||||
<div class="dict-name" v-if="practiceType === DictType.article && store.collect.articles.length">
|
||||
{{ store.collect.articles.length }}篇文章
|
||||
</div>
|
||||
<BaseIcon icon="fluent:add-12-regular" title="添加" @click="addCollect"/>
|
||||
</div>
|
||||
<template v-if="practiceType === DictType.word">
|
||||
<WordList
|
||||
v-if="store.collect.words.length"
|
||||
class="word-list"
|
||||
:list="store.collect.words">
|
||||
<template v-slot:suffix="{item,index}">
|
||||
<BaseIcon
|
||||
class="del"
|
||||
@click="toggleWordCollect(item)"
|
||||
title="移除"
|
||||
icon="solar:trash-bin-minimalistic-linear"/>
|
||||
</template>
|
||||
</WordList>
|
||||
<Empty v-else/>
|
||||
</template>
|
||||
<template v-else>
|
||||
<ArticleList
|
||||
v-if="store.collect.articles.length"
|
||||
v-model:list="store.collect.articles">
|
||||
<template v-slot:suffix="{item,index}">
|
||||
<BaseIcon
|
||||
class="del"
|
||||
@click="toggleArticleCollect(item)"
|
||||
title="移除"
|
||||
icon="solar:trash-bin-minimalistic-linear"/>
|
||||
</template>
|
||||
</ArticleList>
|
||||
<Empty v-else/>
|
||||
<template v-if="showCollectToggleButton">
|
||||
<PopConfirm
|
||||
:title="`确认切换?`"
|
||||
@confirm="changeIndex( store.collect)"
|
||||
>
|
||||
<BaseButton size="small">切换</BaseButton>
|
||||
</PopConfirm>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<div class="slide-item">
|
||||
<div class="panel-page-item">
|
||||
<div class="list-header">
|
||||
<div class="left">
|
||||
<div class="dict-name">总词数:{{ store.simple.words.length }}</div>
|
||||
<Tooltip title="添加">
|
||||
<IconWrapper>
|
||||
<Icon icon="fluent:add-12-regular" @click="addSimple"/>
|
||||
</IconWrapper>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<template v-if="store.currentDict.type !== DictType.simple && store.simple.words.length">
|
||||
<PopConfirm
|
||||
:title="`确认切换?`"
|
||||
@confirm="changeIndex(0,store.simple)"
|
||||
>
|
||||
<BaseButton size="small">切换</BaseButton>
|
||||
</PopConfirm>
|
||||
</template>
|
||||
</div>
|
||||
<template v-if="practiceType === DictType.word">
|
||||
<WordList
|
||||
v-if="store.simple.words.length"
|
||||
v-if="store.collect.words.length"
|
||||
class="word-list"
|
||||
:list="store.simple.words">
|
||||
:list="store.collect.words">
|
||||
<template v-slot:suffix="{item,index}">
|
||||
<BaseIcon
|
||||
class="del"
|
||||
@click="delSimpleWord(item)"
|
||||
@click="toggleWordCollect(item)"
|
||||
title="移除"
|
||||
icon="solar:trash-bin-minimalistic-linear"/>
|
||||
</template>
|
||||
</WordList>
|
||||
<Empty v-else/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="slide-item">
|
||||
<div class="panel-page-item" v-if="store.wrong.words.length">
|
||||
<div class="list-header">
|
||||
<div class="dict-name">总词数:{{ store.wrong.words.length }}</div>
|
||||
<template
|
||||
v-if="store.currentDict.type !== DictType.wrong && store.wrong.words.length">
|
||||
<PopConfirm
|
||||
:title="`确认切换?`"
|
||||
@confirm="changeIndex(0,store.wrong)"
|
||||
>
|
||||
<BaseButton size="small">切换</BaseButton>
|
||||
</PopConfirm>
|
||||
</template>
|
||||
</div>
|
||||
<WordList
|
||||
class="word-list"
|
||||
:list="store.wrong.words">
|
||||
<template v-slot="{item,index}">
|
||||
</template>
|
||||
<template v-else>
|
||||
<ArticleList
|
||||
v-if="store.collect.articles.length"
|
||||
:list="store.collect.articles">
|
||||
<template v-slot:suffix="{item,index}">
|
||||
<BaseIcon
|
||||
class="del"
|
||||
@click="delWrongWord(item)"
|
||||
@click="toggleArticleCollect(item)"
|
||||
title="移除"
|
||||
icon="solar:trash-bin-minimalistic-linear"/>
|
||||
</template>
|
||||
</WordList>
|
||||
</ArticleList>
|
||||
<Empty v-else/>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<div class="slide-item">
|
||||
<div class="panel-page-item">
|
||||
<div class="list-header">
|
||||
<div class="left">
|
||||
<div class="dict-name">总词数:{{ store.simple.words.length }}</div>
|
||||
<BaseIcon icon="fluent:add-12-regular" title="添加" @click="addSimple"/>
|
||||
</div>
|
||||
<template v-if="store.currentDict.type !== DictType.simple && store.simple.words.length">
|
||||
<PopConfirm
|
||||
:title="`确认切换?`"
|
||||
@confirm="changeIndex( store.simple)"
|
||||
>
|
||||
<BaseButton size="small">切换</BaseButton>
|
||||
</PopConfirm>
|
||||
</template>
|
||||
</div>
|
||||
<WordList
|
||||
v-if="store.simple.words.length"
|
||||
class="word-list"
|
||||
:list="store.simple.words">
|
||||
<template v-slot:suffix="{item,index}">
|
||||
<BaseIcon
|
||||
class="del"
|
||||
@click="delSimpleWord(item)"
|
||||
title="移除"
|
||||
icon="solar:trash-bin-minimalistic-linear"/>
|
||||
</template>
|
||||
</WordList>
|
||||
<Empty v-else/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="slide-item">
|
||||
<div class="panel-page-item" v-if="store.wrong.words.length">
|
||||
<div class="list-header">
|
||||
<div class="dict-name">总词数:{{ store.wrong.words.length }}</div>
|
||||
<template
|
||||
v-if="store.currentDict.type !== DictType.wrong && store.wrong.words.length">
|
||||
<PopConfirm
|
||||
:title="`确认切换?`"
|
||||
@confirm="changeIndex( store.wrong)"
|
||||
>
|
||||
<BaseButton size="small">切换</BaseButton>
|
||||
</PopConfirm>
|
||||
</template>
|
||||
</div>
|
||||
<WordList
|
||||
class="word-list"
|
||||
:list="store.wrong.words">
|
||||
<template v-slot="{item,index}">
|
||||
<BaseIcon
|
||||
class="del"
|
||||
@click="delWrongWord(item)"
|
||||
title="移除"
|
||||
icon="solar:trash-bin-minimalistic-linear"/>
|
||||
</template>
|
||||
</WordList>
|
||||
</div>
|
||||
<Empty v-else/>
|
||||
</div>
|
||||
</Slide>
|
||||
</div>
|
||||
</Transition>
|
||||
</template>
|
||||
@@ -228,60 +231,34 @@ function addSimple() {
|
||||
@import "@/assets/css/variable";
|
||||
|
||||
$header-height: 50rem;
|
||||
.slide-item {
|
||||
width: var(--panel-width);
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.slide {
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
|
||||
.slide-list {
|
||||
width: 400%;
|
||||
height: 100%;
|
||||
> header {
|
||||
padding: 0 var(--space);
|
||||
height: $header-height;
|
||||
position: relative;
|
||||
display: flex;
|
||||
transition: all .5s;
|
||||
|
||||
.slide-item {
|
||||
width: var(--panel-width);
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
> header {
|
||||
padding: 0 var(--space);
|
||||
height: $header-height;
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 10rem;
|
||||
font-size: 16rem;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.content {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
padding-bottom: var(--space);
|
||||
}
|
||||
|
||||
footer {
|
||||
padding-right: var(--space);
|
||||
margin-bottom: 10rem;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 10rem;
|
||||
font-size: 16rem;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.step1 {
|
||||
transform: translate3d(-25%, 0, 0);
|
||||
.content {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
padding-bottom: var(--space);
|
||||
}
|
||||
|
||||
.step2 {
|
||||
transform: translate3d(-50%, 0, 0);
|
||||
}
|
||||
|
||||
.step3 {
|
||||
transform: translate3d(-75%, 0, 0);
|
||||
footer {
|
||||
padding-right: var(--space);
|
||||
margin-bottom: 10rem;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -331,7 +308,6 @@ $header-height: 50rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -62,21 +62,6 @@ function repeat() {
|
||||
practiceRef.getCurrentPractice()
|
||||
}
|
||||
|
||||
function next() {
|
||||
// console.log('next')
|
||||
if (store.isArticle) {
|
||||
if (store.currentDict.chapterIndex >= store.currentDict.articles.length - 1) {
|
||||
store.currentDict.chapterIndex = 0
|
||||
} else store.currentDict.chapterIndex++
|
||||
} else {
|
||||
if (store.currentDict.chapterIndex >= store.currentDict.chapterWords.length - 1) {
|
||||
store.currentDict.chapterIndex = 0
|
||||
} else store.currentDict.chapterIndex++
|
||||
}
|
||||
|
||||
repeat()
|
||||
}
|
||||
|
||||
function prev() {
|
||||
// console.log('next')
|
||||
if (store.currentDict.chapterIndex === 0) {
|
||||
@@ -118,12 +103,10 @@ function jumpSpecifiedChapter(val: number) {
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
emitter.on(EventKey.next, next)
|
||||
emitter.on(EventKey.write, write)
|
||||
emitter.on(EventKey.repeat, repeat)
|
||||
emitter.on(EventKey.jumpSpecifiedChapter, jumpSpecifiedChapter)
|
||||
|
||||
emitter.on(ShortcutKey.NextChapter, next)
|
||||
emitter.on(ShortcutKey.PreviousChapter, prev)
|
||||
emitter.on(ShortcutKey.RepeatChapter, repeat)
|
||||
emitter.on(ShortcutKey.DictationChapter, write)
|
||||
@@ -137,12 +120,10 @@ onMounted(() => {
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
emitter.off(EventKey.next, next)
|
||||
emitter.off(EventKey.write, write)
|
||||
emitter.off(EventKey.repeat, repeat)
|
||||
emitter.off(EventKey.jumpSpecifiedChapter, jumpSpecifiedChapter)
|
||||
|
||||
emitter.off(ShortcutKey.NextChapter, next)
|
||||
emitter.off(ShortcutKey.PreviousChapter, prev)
|
||||
emitter.off(ShortcutKey.RepeatChapter, repeat)
|
||||
emitter.off(ShortcutKey.DictationChapter, write)
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
import {cloneDeep} from "lodash-es";
|
||||
import TypingWord from "@/pages/practice/practice-word/TypingWord.vue";
|
||||
import Panel from "../Panel.vue";
|
||||
import {onMounted, watch} from "vue";
|
||||
import {onMounted, onUnmounted, watch} from "vue";
|
||||
import {renewSectionTexts, renewSectionTranslates} from "@/hooks/translate.ts";
|
||||
import {MessageBox} from "@/utils/MessageBox.tsx";
|
||||
import {useBaseStore} from "@/stores/base.ts";
|
||||
@@ -40,6 +40,7 @@ let wordData = $ref({
|
||||
index: -1
|
||||
})
|
||||
let articleData = $ref({
|
||||
articles: [],
|
||||
article: cloneDeep(DefaultArticle),
|
||||
sectionIndex: 0,
|
||||
sentenceIndex: 0,
|
||||
@@ -49,18 +50,38 @@ let articleData = $ref({
|
||||
let showEditArticle = $ref(false)
|
||||
let editArticle = $ref<Article>(cloneDeep(DefaultArticle))
|
||||
|
||||
watch([
|
||||
// () => store.load,
|
||||
() => store.currentDict.articles,
|
||||
], n => {
|
||||
function next() {
|
||||
if (store.currentDict.chapterIndex >= articleData.articles.length - 1) {
|
||||
store.currentDict.chapterIndex = 0
|
||||
} else store.currentDict.chapterIndex++
|
||||
|
||||
emitter.emit(EventKey.resetWord)
|
||||
getCurrentPractice()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
init()
|
||||
emitter.on(EventKey.changeDict, init)
|
||||
emitter.on(EventKey.next, next)
|
||||
emitter.on(ShortcutKey.NextChapter, next)
|
||||
})
|
||||
|
||||
onMounted(getCurrentPractice)
|
||||
onUnmounted(() => {
|
||||
emitter.off(EventKey.changeDict, init)
|
||||
emitter.off(EventKey.next, next)
|
||||
emitter.off(ShortcutKey.NextChapter, next)
|
||||
})
|
||||
|
||||
function init() {
|
||||
if (!store.currentDict.articles.length) return
|
||||
articleData.articles = cloneDeep(store.currentDict.articles)
|
||||
getCurrentPractice()
|
||||
}
|
||||
|
||||
function setArticle(val: Article) {
|
||||
store.currentDict.articles[store.currentDict.chapterIndex] = cloneDeep(val)
|
||||
articleData.article = cloneDeep(val)
|
||||
let tempVal = cloneDeep(val)
|
||||
articleData.articles[store.currentDict.chapterIndex] = tempVal
|
||||
articleData.article = tempVal
|
||||
practiceStore.inputWordNumber = 0
|
||||
practiceStore.wrongWordNumber = 0
|
||||
practiceStore.repeatNumber = 0
|
||||
@@ -81,11 +102,10 @@ function setArticle(val: Article) {
|
||||
function getCurrentPractice() {
|
||||
// console.log('store.currentDict',store.currentDict)
|
||||
// return
|
||||
if (!store.currentDict.articles.length) return
|
||||
tabIndex = 0
|
||||
articleData.article = cloneDeep(DefaultArticle)
|
||||
|
||||
let currentArticle = store.currentDict.articles[store.currentDict.chapterIndex]
|
||||
let currentArticle = articleData.articles [store.currentDict.chapterIndex]
|
||||
let tempArticle = {...DefaultArticle, ...currentArticle}
|
||||
// console.log('article', tempArticle)
|
||||
if (tempArticle.sections.length) {
|
||||
@@ -153,7 +173,10 @@ function getCurrentPractice() {
|
||||
function saveArticle(val: Article) {
|
||||
console.log('saveArticle', val)
|
||||
showEditArticle = false
|
||||
// articleData.article = cloneDeep(store.currentDict.articles[store.currentDict.chapterIndex])
|
||||
let rIndex = store.currentDict.articles.findIndex(v => v.id === val.id)
|
||||
if (rIndex > -1) {
|
||||
store.currentDict.articles[rIndex] = cloneDeep(val)
|
||||
}
|
||||
setArticle(val)
|
||||
}
|
||||
|
||||
@@ -213,8 +236,8 @@ function nextWord(word: ArticleWord) {
|
||||
}
|
||||
}
|
||||
|
||||
function changePracticeArticle(val: ArticleItem) {
|
||||
let rIndex = store.currentDict.articles.findIndex(v => v.id === val.item.id)
|
||||
function handleChangeChapterIndex(val: ArticleItem) {
|
||||
let rIndex = articleData.articles.findIndex(v => v.id === val.item.id)
|
||||
if (rIndex > -1) {
|
||||
store.currentDict.chapterIndex = rIndex
|
||||
getCurrentPractice()
|
||||
@@ -274,18 +297,18 @@ defineExpose({getCurrentPractice})
|
||||
@click="emitter.emit(EventKey.openDictModal,'list')"
|
||||
icon="carbon:change-catalog"/>
|
||||
<div class="title">
|
||||
{{ store.dictTitle }}
|
||||
{{ store.currentDict.name }}
|
||||
</div>
|
||||
<Tooltip
|
||||
:title="`下一章(快捷键:${settingStore.shortcutKeyMap[ShortcutKey.NextChapter]})`"
|
||||
v-if="store.currentDict.chapterIndex < store.currentDict.articles.length - 1">
|
||||
v-if="store.currentDict.chapterIndex < articleData.articles .length - 1">
|
||||
<IconWrapper>
|
||||
<Icon @click="emitter.emit(EventKey.next)" icon="octicon:arrow-right-24"/>
|
||||
</IconWrapper>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div class="right">
|
||||
{{ store.currentDict.articles.length }}篇文章
|
||||
{{ articleData.articles.length }}篇文章
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -295,9 +318,9 @@ defineExpose({getCurrentPractice})
|
||||
:show-border="true"
|
||||
:show-translate="settingStore.translate"
|
||||
@title="e => emitter.emit(EventKey.openArticleContentModal,e.item)"
|
||||
@click="changePracticeArticle"
|
||||
@click="handleChangeChapterIndex"
|
||||
:active-id="articleData.article.id"
|
||||
:list="store.currentDict.articles">
|
||||
:list="articleData.articles ">
|
||||
<template v-slot:suffix="{item,index}">
|
||||
<BaseIcon
|
||||
v-if="!isArticleCollect(item)"
|
||||
|
||||
@@ -140,7 +140,7 @@ function next(isTyping: boolean = true) {
|
||||
data.index++
|
||||
isTyping && practiceStore.inputWordNumber++
|
||||
console.log('这个词完了')
|
||||
if ([DictType.customWord, DictType.word].includes(store.currentDict.type)
|
||||
if ([DictType.word].includes(store.currentDict.type)
|
||||
&& store.skipWordNames.includes(word.name.toLowerCase())) {
|
||||
next()
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import {chunk, cloneDeep} from "lodash-es";
|
||||
import {useBaseStore} from "@/stores/base.ts";
|
||||
import {onMounted, onUnmounted, watch} from "vue";
|
||||
import {useRuntimeStore} from "@/stores/runtime.ts";
|
||||
import {Word} from "@/types.ts";
|
||||
import {ShortcutKey, Word} from "@/types.ts";
|
||||
import {emitter, EventKey} from "@/utils/eventBus.ts";
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
import {syncMyDictList} from "@/hooks/dict.ts";
|
||||
@@ -20,12 +20,6 @@ let wordData = $ref({
|
||||
index: -1
|
||||
})
|
||||
|
||||
watch([
|
||||
() => store.currentDict.words,
|
||||
], n => {
|
||||
getCurrentPractice()
|
||||
})
|
||||
|
||||
function getCurrentPractice() {
|
||||
if (store.chapter.length) {
|
||||
wordData.words = store.chapter
|
||||
@@ -37,6 +31,9 @@ function getCurrentPractice() {
|
||||
if (res) w = Object.assign(w, res)
|
||||
}
|
||||
})
|
||||
|
||||
wordData.words = cloneDeep(store.chapter)
|
||||
emitter.emit(EventKey.resetWord)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +43,26 @@ function sort(list: Word[]) {
|
||||
syncMyDictList(store.currentDict)
|
||||
}
|
||||
|
||||
onMounted(getCurrentPractice)
|
||||
function next() {
|
||||
if (store.currentDict.chapterIndex >= store.currentDict.chapterWords.length - 1) {
|
||||
store.currentDict.chapterIndex = 0
|
||||
} else store.currentDict.chapterIndex++
|
||||
|
||||
getCurrentPractice()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getCurrentPractice()
|
||||
emitter.on(EventKey.changeDict, getCurrentPractice)
|
||||
emitter.on(EventKey.next, next)
|
||||
emitter.on(ShortcutKey.NextChapter, next)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
emitter.off(EventKey.changeDict, getCurrentPractice)
|
||||
emitter.off(EventKey.next, next)
|
||||
emitter.off(ShortcutKey.NextChapter, next)
|
||||
})
|
||||
|
||||
defineExpose({getCurrentPractice})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user