Perfect panel
This commit is contained in:
@@ -2,10 +2,10 @@
|
||||
import {useBaseStore} from "@/stores/base.ts"
|
||||
import WordList from "@/components/WordList.vue"
|
||||
|
||||
import {$ref} from "vue/macros"
|
||||
import {$computed, $ref} from "vue/macros"
|
||||
import {computed, provide, watch} from "vue"
|
||||
import 'swiper/css';
|
||||
import {DictType, Word} from "@/types.ts"
|
||||
import {Dict, DictType, Word} from "@/types.ts"
|
||||
import PopConfirm from "@/components/PopConfirm.vue"
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
@@ -14,6 +14,9 @@ const props = defineProps<{
|
||||
list?: Word[],
|
||||
index: number
|
||||
}>()
|
||||
const emit = defineEmits<{
|
||||
'update:index': [i: number]
|
||||
}>()
|
||||
const store = useBaseStore()
|
||||
const settingStore = useSettingStore()
|
||||
let tabIndex = $ref(0)
|
||||
@@ -22,11 +25,11 @@ provide('tabIndex', computed(() => tabIndex))
|
||||
watch(() => settingStore.showPanel, n => {
|
||||
if (n) {
|
||||
switch (store.current.dictType) {
|
||||
case DictType.newDict:
|
||||
case DictType.newWordDict:
|
||||
return tabIndex = 1;
|
||||
case DictType.skipDict:
|
||||
case DictType.skipWordDict:
|
||||
return tabIndex = 3;
|
||||
case DictType.wrongDict:
|
||||
case DictType.wrongWordDict:
|
||||
return tabIndex = 2;
|
||||
case DictType.publicDict:
|
||||
case DictType.customDict:
|
||||
@@ -34,23 +37,39 @@ watch(() => settingStore.showPanel, n => {
|
||||
}
|
||||
}
|
||||
})
|
||||
const newWordDictActiveIndex = computed(() => {
|
||||
if (store.current.dictType !== DictType.newDict) return -1
|
||||
else return props.index
|
||||
|
||||
const currentDict: Dict = $computed(() => {
|
||||
return store.myDicts[store.current.index]
|
||||
})
|
||||
|
||||
const wrongWordDictActiveIndex = computed(() => {
|
||||
if (store.current.dictType !== DictType.wrongDict) return -1
|
||||
else return props.index
|
||||
const currentData = $computed(() => {
|
||||
if (store.current.dictType !== currentDict.type) return {list: currentDict.chapterWords[currentDict.chapterIndex] ?? [], index: -1}
|
||||
else return props
|
||||
})
|
||||
|
||||
const skipWordDictActiveIndex = computed(() => {
|
||||
if (store.current.dictType !== DictType.skipDict) return -1
|
||||
else return props.index
|
||||
const newWordDictData = $computed(() => {
|
||||
if (store.current.dictType !== DictType.newWordDict) return {list: store.newWordDict.words ?? [], index: -1}
|
||||
else return props
|
||||
})
|
||||
|
||||
function changeIndex(i: number) {
|
||||
const wrongWordDictData = $computed(() => {
|
||||
if (store.current.dictType !== DictType.wrongWordDict) return {list: store.wrongWordDict.words ?? [], index: -1}
|
||||
else return props
|
||||
})
|
||||
|
||||
const skipWordDictData = $computed(() => {
|
||||
if (store.current.dictType !== DictType.skipWordDict) return {list: store.skipWordDict.words ?? [], index: -1}
|
||||
else return props
|
||||
})
|
||||
|
||||
function changeIndex(i: number, dict: Dict) {
|
||||
dict.chapterWordIndex = i
|
||||
console.log('i', i, dict.type)
|
||||
if (store.current.dictType === dict.type) {
|
||||
emit('update:index', i)
|
||||
} else {
|
||||
store.changeDict(dict, dict.chapterIndex, i)
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
@@ -59,11 +78,12 @@ function changeIndex(i: number) {
|
||||
<div class="panel" v-if="settingStore.showPanel">
|
||||
<header>
|
||||
<div class="tabs">
|
||||
<div class="tab" :class="tabIndex === 0 && 'active'" @click="tabIndex = 0">{{ store.dictTitle }}</div>
|
||||
<div class="tab" :class="tabIndex === 0 && 'active'" @click="tabIndex = 0">
|
||||
{{ currentDict.name + ` 第${currentDict.chapterIndex + 1}章` }}
|
||||
</div>
|
||||
<div class="tab" :class="tabIndex === 1 && 'active'" @click="tabIndex = 1">{{ store.newWordDict.name }}</div>
|
||||
<div class="tab" :class="tabIndex === 2 && 'active'" @click="tabIndex = 2">{{
|
||||
store.wrongWordDict.name
|
||||
}}
|
||||
<div class="tab" :class="tabIndex === 2 && 'active'" @click="tabIndex = 2">
|
||||
{{ store.wrongWordDict.name }}
|
||||
</div>
|
||||
<div class="tab" :class="tabIndex === 3 && 'active'" @click="tabIndex = 3">{{ store.skipWordDict.name }}</div>
|
||||
</div>
|
||||
@@ -72,20 +92,20 @@ function changeIndex(i: number) {
|
||||
<div class="slide-list" :class="`step${tabIndex}`">
|
||||
<div class="slide-item">
|
||||
<header>
|
||||
<div class="dict-name">词数:{{ props.list.length }}</div>
|
||||
<div class="dict-name">词数:{{ currentData.list.length }}</div>
|
||||
</header>
|
||||
<div class="content">
|
||||
<WordList
|
||||
class="word-list"
|
||||
@change="(e:number) => store.changeDict(store.currentDict,store.currentDict.chapterIndex,e)"
|
||||
@change="(i:number) => changeIndex(i,currentDict)"
|
||||
:isActive="settingStore.showPanel && tabIndex === 0"
|
||||
:list="props.list??[]"
|
||||
:activeIndex="props.index"/>
|
||||
:list="currentData.list"
|
||||
:activeIndex="currentData.index"/>
|
||||
</div>
|
||||
<footer v-if="![DictType.customDict,DictType.publicDict].includes(store.current.dictType)">
|
||||
<PopConfirm
|
||||
:title="`确认切换?`"
|
||||
@confirm="store.changeDict(store.currentDict)"
|
||||
@confirm="changeIndex(0,currentDict)"
|
||||
>
|
||||
<BaseButton>切换</BaseButton>
|
||||
</PopConfirm>
|
||||
@@ -93,20 +113,20 @@ function changeIndex(i: number) {
|
||||
</div>
|
||||
<div class="slide-item">
|
||||
<header>
|
||||
<div class="dict-name">总词数:{{ store.newWordDict.originWords.length }}</div>
|
||||
<div class="dict-name">总词数:{{ newWordDictData.list.length }}</div>
|
||||
</header>
|
||||
<div class="content">
|
||||
<WordList
|
||||
class="word-list"
|
||||
@change="(e:number) => store.changeDict(store.newWordDict,store.newWordDict.chapterIndex,e)"
|
||||
@change="(i:number) => changeIndex(i,store.newWordDict)"
|
||||
:isActive="settingStore.showPanel && tabIndex === 1"
|
||||
:list="store.newWordDict.words"
|
||||
:activeIndex="newWordDictActiveIndex"/>
|
||||
:list="newWordDictData.list"
|
||||
:activeIndex="newWordDictData.index"/>
|
||||
</div>
|
||||
<footer v-if="store.current.dictType !== DictType.newDict && store.newWordDict.words.length">
|
||||
<footer v-if="store.current.dictType !== DictType.newWordDict && newWordDictData.list.length">
|
||||
<PopConfirm
|
||||
:title="`确认切换?`"
|
||||
@confirm="store.changeDict(store.newWordDict)"
|
||||
@confirm="changeIndex(0,store.newWordDict)"
|
||||
>
|
||||
<BaseButton>切换</BaseButton>
|
||||
</PopConfirm>
|
||||
@@ -115,21 +135,21 @@ function changeIndex(i: number) {
|
||||
<div class="slide-item">
|
||||
<header>
|
||||
<a href="" target="_blank"></a>
|
||||
<div class="dict-name">总词数:{{ store.wrongWordDict.originWords.length }}</div>
|
||||
<div class="dict-name">总词数:{{ wrongWordDictData.list.length }}</div>
|
||||
</header>
|
||||
<div class="content">
|
||||
<WordList
|
||||
class="word-list"
|
||||
@change="(e:number) => store.changeDict(store.wrongWordDict,store.wrongWordDict.chapterIndex,e)"
|
||||
@change="(i:number) => changeIndex(i,store.wrongWordDict)"
|
||||
:isActive="settingStore.showPanel && tabIndex === 2"
|
||||
:list="store.wrongWordDict.words"
|
||||
:activeIndex="wrongWordDictActiveIndex"/>
|
||||
:list="wrongWordDictData.list"
|
||||
:activeIndex="wrongWordDictData.index"/>
|
||||
</div>
|
||||
<footer
|
||||
v-if="store.current.dictType !== DictType.wrongDict && store.wrongWordDict.words.length">
|
||||
v-if="store.current.dictType !== DictType.wrongWordDict && wrongWordDictData.list.length">
|
||||
<PopConfirm
|
||||
:title="`确认切换?`"
|
||||
@confirm="store.changeDict(store.wrongWordDict)"
|
||||
@confirm="changeIndex(0,store.wrongWordDict)"
|
||||
>
|
||||
<BaseButton>切换</BaseButton>
|
||||
</PopConfirm>
|
||||
@@ -137,20 +157,20 @@ function changeIndex(i: number) {
|
||||
</div>
|
||||
<div class="slide-item">
|
||||
<header>
|
||||
<div class="dict-name">总词数:{{ store.skipWordDict.originWords.length }}</div>
|
||||
<div class="dict-name">总词数:{{ skipWordDictData.list.length }}</div>
|
||||
</header>
|
||||
<div class="content">
|
||||
<WordList
|
||||
class="word-list"
|
||||
@change="(e:number) => store.changeDict(store.skipWordDict,store.skipWordDict.chapterIndex,e)"
|
||||
@change="(i:number) => changeIndex(i,store.skipWordDict)"
|
||||
:isActive="settingStore.showPanel && tabIndex === 3"
|
||||
:list="store.skipWordDict.words"
|
||||
:activeIndex="skipWordDictActiveIndex"/>
|
||||
:list="skipWordDictData.list"
|
||||
:activeIndex="skipWordDictData.index"/>
|
||||
</div>
|
||||
<footer v-if="store.current.dictType !== DictType.skipDict && store.skipWordDict.words.length">
|
||||
<footer v-if="store.current.dictType !== DictType.skipWordDict && skipWordDictData.list.length">
|
||||
<PopConfirm
|
||||
:title="`确认切换?`"
|
||||
@confirm="store.changeDict(store.skipWordDict)"
|
||||
@confirm="changeIndex(0,store.skipWordDict)"
|
||||
>
|
||||
<BaseButton>切换</BaseButton>
|
||||
</PopConfirm>
|
||||
|
||||
@@ -130,7 +130,8 @@ function getCurrentPractice() {
|
||||
}
|
||||
} else {
|
||||
wordData.words = cloneDeep(store.chapter)
|
||||
wordData.index = 0
|
||||
wordData.index = store.currentDict.chapterWordIndex
|
||||
console.log('wordData', wordData)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ onMounted(() => {
|
||||
emitter.on(EventKey.openStatModal, (stat: DisplayStatistics) => {
|
||||
currentStat = {...DefaultDisplayStatistics, ...stat}
|
||||
statModalIsOpen = true
|
||||
store.saveStatistics(stat)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ const volumeIconRef: any = $ref()
|
||||
|
||||
watch(() => props.words, () => {
|
||||
data.words = props.words
|
||||
data.index = props.words.length ? 0 : -1
|
||||
data.index = props.index
|
||||
|
||||
practiceStore.wrongWords = []
|
||||
practiceStore.repeatNumber = 0
|
||||
@@ -59,6 +59,13 @@ watch(() => props.words, () => {
|
||||
practiceStore.wrongWordNumber = 0
|
||||
}, {immediate: true})
|
||||
|
||||
watch(() => data.index, (n) => {
|
||||
wrong = input = ''
|
||||
practiceStore.index = n
|
||||
playWordAudio(word.name)
|
||||
volumeIconRef?.play()
|
||||
})
|
||||
|
||||
const word = $computed(() => {
|
||||
return data.words[data.index] ?? {
|
||||
trans: [],
|
||||
@@ -119,15 +126,11 @@ function next(isTyping: boolean = true) {
|
||||
}
|
||||
} else {
|
||||
data.index++
|
||||
practiceStore.index++
|
||||
isTyping && practiceStore.inputWordNumber++
|
||||
console.log('这个词完了')
|
||||
if ([DictType.customDict, DictType.publicDict].includes(store.current.dictType)
|
||||
&& store.skipWordNames.includes(word.name.toLowerCase())) {
|
||||
next()
|
||||
} else {
|
||||
playWordAudio(word.name)
|
||||
volumeIconRef?.play()
|
||||
}
|
||||
}
|
||||
wrong = input = ''
|
||||
@@ -312,7 +315,7 @@ useOnKeyboardEventListener(onKeyDown, onKeyUp)
|
||||
跳过
|
||||
</BaseButton>
|
||||
</div>
|
||||
<Panel :list="data.words" :index="data.index"/>
|
||||
<Panel :list="data.words" v-model:index="data.index"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -47,17 +47,18 @@ export default {
|
||||
render() {
|
||||
let Vnode = this.$slots.default()[0]
|
||||
return <>
|
||||
<Teleport to="body">
|
||||
<Transition name="fade">
|
||||
{
|
||||
this.show && this.title && (
|
||||
<div ref="tip" class="tip">
|
||||
{
|
||||
this.show && this.title && (
|
||||
<Teleport to="body">
|
||||
<Transition name="fade">
|
||||
|
||||
<div ref="tip" className="tip">
|
||||
{this.title}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</Transition>
|
||||
</Teleport>
|
||||
</Transition>
|
||||
</Teleport>
|
||||
)
|
||||
}
|
||||
<Vnode
|
||||
onClick={() => this.show = false}
|
||||
onmouseenter={(e) => this.showPop(e)}
|
||||
|
||||
@@ -29,7 +29,7 @@ const emit = defineEmits<{
|
||||
<div class="right">
|
||||
<VolumeIcon @click="playWordAudio(word.name)"></VolumeIcon>
|
||||
<div class="del"
|
||||
@click="emit('del')"
|
||||
@click.stop="emit('del')"
|
||||
>
|
||||
<Icon
|
||||
icon="fluent:delete-28-regular"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {defineStore} from 'pinia'
|
||||
import {Dict, DictType, SaveDictKey, Sort, Statistics, Word} from "../types.ts"
|
||||
import {Dict, DictType, DisplayStatistics, SaveDictKey, Sort, Statistics, Word} from "../types.ts"
|
||||
import {chunk, cloneDeep} from "lodash-es";
|
||||
import {emitter, EventKey} from "@/utils/eventBus.ts"
|
||||
import {v4 as uuidv4} from 'uuid';
|
||||
@@ -26,7 +26,7 @@ export const useBaseStore = defineStore('base', {
|
||||
newWordDict: {
|
||||
name: '生词本',
|
||||
sort: Sort.normal,
|
||||
type: DictType.newDict,
|
||||
type: DictType.newWordDict,
|
||||
originWords: [],
|
||||
articles: [],
|
||||
words: [],
|
||||
@@ -40,7 +40,7 @@ export const useBaseStore = defineStore('base', {
|
||||
skipWordDict: {
|
||||
name: '简单词',
|
||||
sort: Sort.normal,
|
||||
type: DictType.skipDict,
|
||||
type: DictType.skipWordDict,
|
||||
originWords: [],
|
||||
articles: [],
|
||||
words: [],
|
||||
@@ -54,7 +54,7 @@ export const useBaseStore = defineStore('base', {
|
||||
wrongWordDict: {
|
||||
name: '错词本',
|
||||
sort: Sort.normal,
|
||||
type: DictType.wrongDict,
|
||||
type: DictType.wrongWordDict,
|
||||
originWords: [],
|
||||
articles: [],
|
||||
words: [],
|
||||
@@ -155,11 +155,11 @@ export const useBaseStore = defineStore('base', {
|
||||
},
|
||||
currentDict(state: State): Dict {
|
||||
switch (state.current.dictType) {
|
||||
case DictType.newDict:
|
||||
case DictType.newWordDict:
|
||||
return state.newWordDict
|
||||
case DictType.skipDict:
|
||||
case DictType.skipWordDict:
|
||||
return state.skipWordDict
|
||||
case DictType.wrongDict:
|
||||
case DictType.wrongWordDict:
|
||||
return state.wrongWordDict
|
||||
case DictType.publicDict:
|
||||
case DictType.publicArticle:
|
||||
@@ -204,9 +204,9 @@ export const useBaseStore = defineStore('base', {
|
||||
}
|
||||
|
||||
if ([
|
||||
DictType.newDict,
|
||||
DictType.wrongDict,
|
||||
DictType.skipDict,
|
||||
DictType.newWordDict,
|
||||
DictType.wrongWordDict,
|
||||
DictType.skipWordDict,
|
||||
].includes(this.current.dictType)) {
|
||||
|
||||
} else {
|
||||
@@ -242,8 +242,9 @@ export const useBaseStore = defineStore('base', {
|
||||
}
|
||||
}
|
||||
},
|
||||
saveStatistics(statistics: Statistics) {
|
||||
saveStatistics(statistics: DisplayStatistics) {
|
||||
if (statistics.spend > 1000 * 10) {
|
||||
delete statistics.wrongWords
|
||||
this.currentDict.statistics.push(statistics)
|
||||
}
|
||||
},
|
||||
@@ -252,13 +253,13 @@ export const useBaseStore = defineStore('base', {
|
||||
// this.saveStatistics()
|
||||
console.log('changeDict', cloneDeep(dict), chapterIndex, chapterWordIndex)
|
||||
this.current.dictType = dict.type
|
||||
if ([DictType.newDict,
|
||||
DictType.skipDict,
|
||||
DictType.wrongDict].includes(dict.type)) {
|
||||
if ([DictType.newWordDict,
|
||||
DictType.skipWordDict,
|
||||
DictType.wrongWordDict].includes(dict.type)) {
|
||||
this[dict.type].chapterIndex = chapterIndex
|
||||
this[dict.type].chapterWordIndex = chapterWordIndex
|
||||
} else {
|
||||
let rIndex = this.myDicts.findIndex(v => v.name === dict.name)
|
||||
let rIndex = this.myDicts.findIndex((v: Dict) => v.name === dict.name)
|
||||
if (rIndex > -1) {
|
||||
this.current.index = rIndex
|
||||
} else {
|
||||
|
||||
@@ -49,9 +49,9 @@ export interface Dict {
|
||||
}
|
||||
|
||||
export enum DictType {
|
||||
newDict = 'newDict',
|
||||
skipDict = 'skipDict',
|
||||
wrongDict = 'wrongDict',
|
||||
newWordDict = 'newWordDict',
|
||||
skipWordDict = 'skipWordDict',
|
||||
wrongWordDict = 'wrongWordDict',
|
||||
publicDict = 'publicDict',
|
||||
customDict = 'customDict',
|
||||
publicArticle = 'publicArticle',
|
||||
|
||||
Reference in New Issue
Block a user