This commit is contained in:
zyronon
2024-05-30 18:53:26 +08:00
parent 81aa82b609
commit b9a35f5c6d
8 changed files with 118 additions and 134 deletions

2
auto-imports.d.ts vendored
View File

@@ -5,5 +5,5 @@
// Generated by unplugin-auto-import
export {}
declare global {
const ElMessage: typeof import('element-plus/es')['ElMessage']
}

View File

@@ -106,4 +106,27 @@ export function syncMyDictList(dict: Dict, isCustom = true) {
} else {
store.myDictList.push(cloneDeep(dict))
}
}
export function getCurrentStudyWord() {
const store = useBaseStore()
let data = {new: [], review: []}
let c = store.currentStudy.word
let dict = store.currentStudyWordDict;
if (dict.words?.length) {
for (let i = c.lastLearnIndex; i < dict.words.length; i++) {
if (data.new.length >= c.perDayStudyNumber) break
let item = dict.words[i]
if (!store.skipWordNames.includes(item.word.toLowerCase())) {
data.new.push(item)
}
}
if (dict.statistics.length) {
let stat = dict.statistics.reverse()
stat.slice(0, 1).map(({startIndex, endIndex}) => {
let list = dict.words.splice(startIndex, endIndex)
})
}
}
return data
}

View File

@@ -106,15 +106,10 @@ function next(isTyping: boolean = true) {
emitter.emit(EventKey.openStatModal, {})
// emit('complete', {})
} else {
if (props.data.review.length) {
settingStore.dictation = true
statisticsStore.step++
current.words = shuffle(props.data.review.concat(props.data.new))
current.index = 0
} else {
emitter.emit(EventKey.openStatModal, {})
// emit('complete', {})
}
settingStore.dictation = true
statisticsStore.step++
current.words = shuffle(props.data.review.concat(props.data.new))
current.index = 0
}
}
} else {

View File

@@ -15,7 +15,7 @@ import DictModal from "@/pages/pc/components/dialog/DictDiglog.vue";
import {useStartKeyboardEventListener} from "@/hooks/event.ts";
import useTheme from "@/hooks/theme.ts";
import TypingWord from "@/pages/pc/practice/practice-word/TypingWord.vue";
import {syncMyDictList} from "@/hooks/dict.ts";
import {getCurrentStudyWord, syncMyDictList} from "@/hooks/dict.ts";
import {cloneDeep, shuffle} from "lodash-es";
const statisticsStore = usePracticeStore()
@@ -36,33 +36,20 @@ watch(statisticsStore, () => {
function next() {
store.currentStudy.word.lastLearnIndex = store.currentStudy.word.lastLearnIndex + store.currentStudy.word.perDayStudyNumber
repeat()
}
function write() {
// console.log('write')
settingStore.dictation = true
repeat()
emitter.emit(EventKey.resetWord)
getCurrentPractice()
}
//TODO 需要判断是否已忽略
function repeat() {
// console.log('repeat')
settingStore.dictation = false
emitter.emit(EventKey.resetWord)
getCurrentPractice()
data = cloneDeep(data)
}
function prev() {
// console.log('next')
if (store.currentDict.chapterIndex === 0) {
ElMessage.warning('已经在第一章了~')
} else {
store.currentDict.chapterIndex--
repeat()
}
}
function toggleShowTranslate() {
function toggleTranslate() {
settingStore.translate = !settingStore.translate
}
@@ -87,21 +74,12 @@ function togglePanel() {
settingStore.showPanel = !settingStore.showPanel
}
function jumpSpecifiedChapter(val: number) {
store.currentDict.chapterIndex = val
repeat()
}
onMounted(() => {
emitter.on(EventKey.write, write)
emitter.on(EventKey.repeat, repeat)
emitter.on(EventKey.next, next)
emitter.on(EventKey.jumpSpecifiedChapter, jumpSpecifiedChapter)
emitter.on(ShortcutKey.PreviousChapter, prev)
emitter.on(ShortcutKey.RepeatChapter, repeat)
emitter.on(ShortcutKey.DictationChapter, write)
emitter.on(ShortcutKey.ToggleShowTranslate, toggleShowTranslate)
emitter.on(ShortcutKey.ToggleShowTranslate, toggleTranslate)
emitter.on(ShortcutKey.ToggleDictation, toggleDictation)
emitter.on(ShortcutKey.OpenSetting, openSetting)
emitter.on(ShortcutKey.OpenDictDetail, openDictDetail)
@@ -111,15 +89,11 @@ onMounted(() => {
})
onUnmounted(() => {
emitter.off(EventKey.write, write)
emitter.off(EventKey.repeat, repeat)
emitter.off(EventKey.next, next)
emitter.off(EventKey.jumpSpecifiedChapter, jumpSpecifiedChapter)
emitter.off(ShortcutKey.PreviousChapter, prev)
emitter.off(ShortcutKey.RepeatChapter, repeat)
emitter.off(ShortcutKey.DictationChapter, write)
emitter.off(ShortcutKey.ToggleShowTranslate, toggleShowTranslate)
emitter.off(ShortcutKey.ToggleShowTranslate, toggleTranslate)
emitter.off(ShortcutKey.ToggleDictation, toggleDictation)
emitter.off(ShortcutKey.OpenSetting, openSetting)
emitter.off(ShortcutKey.OpenDictDetail, openDictDetail)
@@ -129,7 +103,8 @@ onUnmounted(() => {
})
onMounted(() => {
getCurrentPractice()
settingStore.dictation = false
data = runtimeStore.routeData
emitter.on(EventKey.changeDict, getCurrentPractice)
})
@@ -137,42 +112,18 @@ onUnmounted(() => {
emitter.off(EventKey.changeDict, getCurrentPractice)
})
let wordData = $ref({
words: [],
index: -1
})
let data = $ref({
new: [],
review: []
})
function getCurrentPractice() {
let c = store.currentStudy.word
let wordDict = store.currentStudyWordDict;
if (wordDict.words?.length) {
wordData.index = 0
wordData.words = []
statisticsStore.step = 0
for (let i = c.lastLearnIndex; i < wordDict.words.length; i++) {
if (data.new.length >= c.perDayStudyNumber) break
let item = wordDict.words[i]
if (!store.skipWordNames.includes(item.word.toLowerCase())) {
data.new.push(item)
}
}
emitter.emit(EventKey.resetWord)
}
}
//TODO wait
function sort(list: Word[]) {
store.currentDict.chapterWords[store.currentDict.chapterIndex] = wordData.words = list
wordData.index = 0
syncMyDictList(store.currentDict)
settingStore.dictation = false
data = getCurrentStudyWord()
}
function complete() {
// store.currentStudyWordDict.statistics.push()
}
@@ -184,7 +135,6 @@ useStartKeyboardEventListener()
<Toolbar/>
<div class="flex flex-1">
<TypingWord
@sort="sort"
@complete="complete"
:data="data"/>
</div>

View File

@@ -7,10 +7,11 @@ import {useRouter} from "vue-router";
import BaseIcon from "@/components/BaseIcon.vue";
import {useNav} from "@/utils";
import BasePage from "@/pages/pc/components/BasePage.vue";
import {watch} from "vue";
import {getDefaultDict} from "@/types.ts";
import {onMounted} from "vue";
import {getCurrentStudyWord} from "@/hooks/dict.ts";
const base = useBaseStore()
const store = useBaseStore()
const router = useRouter()
const {nav} = useNav()
@@ -20,71 +21,82 @@ function clickEvent(e) {
let showMore = $ref(false)
const otherWordDictList = $computed(() => {
if (showMore) return base.otherWordDictList
else return base.otherWordDictList.slice(0, 4)
if (showMore) return store.otherWordDictList
else return store.otherWordDictList.slice(0, 4)
})
let currentStudy = $ref({
new: [],
review: []
})
onMounted(() => {
currentStudy = getCurrentStudyWord()
})
</script>
<template>
<BasePage>
<div class="card flex gap-10 items-center">
<div class="flex-1">
<div class="flex gap-5">
<div class="bg-slate-200 px-3 h-14 rounded-md flex items-center">
<span class="text-xl font-bold">{{ base.currentStudyWordDict.name }}</span>
<BaseIcon
title="切换词典"
icon="gg:arrows-exchange"
class="ml-4"
@click="router.push('/dict')"/>
</div>
<div class="flex-1">
<div class="flex gap-3">
<div class="bg-slate-200 w-10 h-10 flex center text-2xl rounded">
0
</div>
<div class="flex-1">
<div class="flex justify-between">
<div class="title">
每日目标
</div>
<div style="color:#ac6ed1;" class="cursor-pointer">
更改目标
</div>
</div>
<div class="text-xs">学习 {{ base.currentStudy.word.perDayStudyNumber }} 个单词</div>
</div>
</div>
<div class="mt-2">
<div>预计完成日期2024-04-01</div>
</div>
</div>
</div>
<div class="mt-4">
<div class="text-sm flex justify-between">
已学习{{ base.currentStudyWordProgress }}%
<span>{{ base.currentStudy.word.lastLearnIndex }} /{{ base.currentStudyWordDict.words.length }}</span>
</div>
<el-progress class="mt-1" :percentage="base.currentStudyWordProgress" :show-text="false"></el-progress>
</div>
</div>
<div class="flex-1">
<div class="flex gap-5">
<div class="bg-slate-200 px-3 h-14 rounded-md flex items-center">
<span class="text-xl font-bold">{{ store.currentStudyWordDict.name }}</span>
<BaseIcon
title="切换词典"
icon="gg:arrows-exchange"
class="ml-4"
@click="router.push('/dict')"/>
</div>
<div class="flex-1 flex flex-col justify-end items-end">
<div class="flex gap-3">
<div class="">
<div class="title">
每日目标
</div>
<div class="flex">
<div style="color:#ac6ed1;" class="cursor-pointer" v-if="false">
更改目标
</div>
<div class="text-xs">学习 {{ store.currentStudy.word.perDayStudyNumber }} 个单词</div>
</div>
</div>
<div class="bg-slate-200 w-10 h-10 flex center text-2xl rounded">
{{ store.currentStudy.word.perDayStudyNumber }}
</div>
</div>
<div class="mt-2">
<div>预计完成日期2024-04-01</div>
</div>
</div>
</div>
<div class="mt-2">
<div class="text-sm flex justify-between">
已学习{{ store.currentStudyWordProgress }}%
<span>{{ store.currentStudy.word.lastLearnIndex }} /{{ store.currentStudyWordDict.words.length }}</span>
</div>
<el-progress class="mt-1" :percentage="store.currentStudyWordProgress" :show-text="false"></el-progress>
</div>
</div>
<div class="w-3/10 flex flex-col gap-4">
<div class="center text-xl">今日任务</div>
<div class="flex">
<div class="flex-1 flex flex-col items-center">
<div class="text-4xl font-bold">10</div>
<div class="text-4xl font-bold">{{ currentStudy.new.length }}</div>
<div class="text">新词数</div>
</div>
<div class="flex-1 flex flex-col items-center">
<div class="text-4xl font-bold">10</div>
<div class="text-4xl font-bold">{{ currentStudy.review.length }}</div>
<div class="text">复习数</div>
</div>
</div>
</div>
<div class="">
<div class="rounded-xl bg-slate-800 flex items-center gap-2 py-3 px-5 text-white cursor-pointer"
@click="router.push('study-word')">
@click="nav('study-word',{},currentStudy)">
<span>开始学习</span>
<Icon icon="icons8:right-round" class="text-2xl"/>
</div>
@@ -98,19 +110,19 @@ const otherWordDictList = $computed(() => {
<div class="grid grid-cols-6 gap-4 mt-4">
<div class="my-dict" @click="nav('edit-word-dict',{type:0})">
<span>收藏</span>
<div class="absolute bottom-4 right-4">{{ base.collectWord.length }}个词</div>
<div class="absolute bottom-4 right-4">{{ store.collectWord.length }}个词</div>
</div>
<div class="my-dict" @click="nav('edit-word-dict',{type:1})">
<span>错词本</span>
<div class="absolute bottom-4 right-4">{{ base.wrong2.length }}个词</div>
<div class="absolute bottom-4 right-4">{{ store.wrong2.length }}个词</div>
</div>
<div class="my-dict" @click="nav('edit-word-dict',{type:2})">
<span>简单词</span>
<div class="absolute bottom-4 right-4">{{ base.simple2.length }}个词</div>
<div class="absolute bottom-4 right-4">{{ store.simple2.length }}个词</div>
</div>
<div class="my-dict" @click="nav('edit-word-dict',{type:3})" >
<div class="my-dict" @click="nav('edit-word-dict',{type:3})">
<span>已掌握</span>
<div class="absolute bottom-4 right-4">{{ base.master.length }}个词</div>
<div class="absolute bottom-4 right-4">{{ store.master.length }}个词</div>
</div>
</div>
</div>
@@ -129,15 +141,15 @@ const otherWordDictList = $computed(() => {
<div class="flex justify-between w-full">
<span>{{ i.name }}</span>
<div class="text-2xl ml-2 flex gap-4">
<BaseIcon title="删除" icon="hugeicons:delete-02" @click="base.delWordDict(i)"/>
<BaseIcon title="学习" icon="nonicons:go-16" @click="base.changeWordDict(getDefaultDict(i))"/>
<BaseIcon title="删除" icon="hugeicons:delete-02" @click="store.delWordDict(i)"/>
<BaseIcon title="学习" icon="nonicons:go-16" @click="store.changeWordDict(getDefaultDict(i))"/>
</div>
</div>
<div class="mt-5 text-sm">已学习5555个单词的1%</div>
<el-progress class="mt-1" :percentage="80" color="white" :show-text="false"></el-progress>
</div>
</div>
<div class="flex justify-center mt-2 text-2xl" v-if="base.otherWordDictList.length > 4">
<div class="flex justify-center mt-2 text-2xl" v-if="store.otherWordDictList.length > 4">
<BaseIcon @click="showMore = !showMore" v-if="showMore" icon="mingcute:up-line"/>
<BaseIcon @click="showMore = !showMore" v-else icon="mingcute:down-line"/>
</div>

View File

@@ -1,5 +1,5 @@
import {defineStore} from 'pinia'
import {Article, DefaultDict, Dict, DictType, DisplayStatistics, Sort, Word} from "../types.ts"
import {Article, DefaultDict, Dict, DictType, DisplayStatistics, getDefaultDict, Sort, Word} from "../types.ts"
import {chunk, cloneDeep, merge, reverse, shuffle} from "lodash-es";
import {emitter, EventKey} from "@/utils/eventBus.ts"
import {useRuntimeStore} from "@/stores/runtime.ts";
@@ -136,7 +136,7 @@ export const DefaultBaseState = (): BaseState => ({
currentStudy: {
word: {
dictIndex: 0,
perDayStudyNumber: 3,
perDayStudyNumber: 5,
lastLearnIndex: 0,
},
article: {
@@ -263,7 +263,7 @@ export const useBaseStore = defineStore('base', {
return this.myDictList[this.current.index] ?? {}
},
currentStudyWordDict(): Dict {
return this.wordDictList[this.currentStudy.word.dictIndex] ?? {}
return this.wordDictList[this.currentStudy.word.dictIndex] ?? getDefaultDict()
},
currentStudyWordProgress(): number {
if (!this.currentStudyWordDict.words?.length) return 0

View File

@@ -9,11 +9,13 @@ export interface RuntimeState {
showDictModal: boolean
showSettingModal: boolean
excludeRoutes: any[]
routeData: any,
}
export const useRuntimeStore = defineStore('runtime', {
state: (): RuntimeState => {
return {
routeData: null,
disableEventListener: false,
modalList: [],
editDict: cloneDeep(DefaultDict),

View File

@@ -5,6 +5,7 @@ import {cloneDeep} from "lodash-es";
import {Dict, DictType} from "@/types.ts";
import {ArchiveReader, libarchiveWasm} from "libarchive-wasm";
import {useRouter} from "vue-router";
import {useRuntimeStore} from "@/stores/runtime.ts";
export function getRandom(a: number, b: number): number {
return Math.random() * (b - a) + a;
@@ -190,11 +191,12 @@ export function getDictFile(url: string) {
export function useNav() {
const router = useRouter()
const runtimeStore = useRuntimeStore()
function nav(path, query = {}, data?: any) {
// if (data) {
// store.routeData = cloneDeep(data)
// }
if (data) {
runtimeStore.routeData = cloneDeep(data)
}
router.push({path, query})
}