Perfect panel

This commit is contained in:
zyronon
2023-10-02 23:13:00 +08:00
parent b4b2de86e5
commit d665a60cd3
8 changed files with 104 additions and 77 deletions

View File

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

View File

@@ -130,7 +130,8 @@ function getCurrentPractice() {
}
} else {
wordData.words = cloneDeep(store.chapter)
wordData.index = 0
wordData.index = store.currentDict.chapterWordIndex
console.log('wordData', wordData)
}
}

View File

@@ -26,6 +26,7 @@ onMounted(() => {
emitter.on(EventKey.openStatModal, (stat: DisplayStatistics) => {
currentStat = {...DefaultDisplayStatistics, ...stat}
statModalIsOpen = true
store.saveStatistics(stat)
})
})

View File

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

View File

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

View File

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

View File

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

View File

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