This commit is contained in:
zyronon
2023-10-23 18:58:33 +08:00
parent 5922475b33
commit 9c6151f5b7
15 changed files with 478 additions and 503 deletions

View File

@@ -45,4 +45,6 @@ A cold welcome 有bug
单词发音,点击第二遍时减速
http://enpuz.com/ 语法分析工具
键盘音效应该多放几遍

File diff suppressed because it is too large Load Diff

View File

@@ -24,14 +24,14 @@ provide('tabIndex', computed(() => tabIndex))
watch(() => settingStore.showPanel, n => {
if (n) {
switch (store.current.dictType) {
case DictType.newWordDict:
case DictType.new:
return tabIndex = 1;
case DictType.skipWordDict:
case DictType.skip:
return tabIndex = 3;
case DictType.wrongWordDict:
case DictType.wrong:
return tabIndex = 2;
case DictType.publicDict:
case DictType.customDict:
case DictType.word:
case DictType.customWord:
return tabIndex = 0;
}
}
@@ -46,23 +46,23 @@ const currentData = $computed(() => {
else return props
})
const newWordDictData = $computed(() => {
if (store.current.dictType !== DictType.newWordDict) return {list: store.newWordDict.words ?? [], index: -1}
const newData = $computed(() => {
if (store.current.dictType !== DictType.new) return {list: store.new.words ?? [], index: -1}
else return props
})
const wrongWordDictData = $computed(() => {
if (store.current.dictType !== DictType.wrongWordDict) return {list: store.wrongWordDict.words ?? [], index: -1}
const wrongData = $computed(() => {
if (store.current.dictType !== DictType.wrong) return {list: store.wrong.words ?? [], index: -1}
else return props
})
const skipWordDictData = $computed(() => {
if (store.current.dictType !== DictType.skipWordDict) return {list: store.skipWordDict.words ?? [], index: -1}
const skipData = $computed(() => {
if (store.current.dictType !== DictType.skip) return {list: store.skip.words ?? [], index: -1}
else return props
})
function changeIndex(i: number, dict: Dict) {
dict.chapterWordIndex = i
dict.wordIndex = i
console.log('i', i, dict.type)
if (store.current.dictType === dict.type) {
emit('update:index', i)
@@ -80,11 +80,11 @@ function changeIndex(i: number, dict: Dict) {
<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 === 1 && 'active'" @click="tabIndex = 1">{{ store.new.name }}</div>
<div class="tab" :class="tabIndex === 2 && 'active'" @click="tabIndex = 2">
{{ store.wrongWordDict.name }}
{{ store.wrong.name }}
</div>
<div class="tab" :class="tabIndex === 3 && 'active'" @click="tabIndex = 3">{{ store.skipWordDict.name }}</div>
<div class="tab" :class="tabIndex === 3 && 'active'" @click="tabIndex = 3">{{ store.skip.name }}</div>
</div>
</header>
<div class="slide">
@@ -101,7 +101,7 @@ function changeIndex(i: number, dict: Dict) {
:list="currentData.list"
:activeIndex="currentData.index"/>
</div>
<footer v-if="![DictType.customDict,DictType.publicDict].includes(store.current.dictType)">
<footer v-if="![DictType.customWord,DictType.word].includes(store.current.dictType)">
<PopConfirm
:title="`确认切换?`"
@confirm="changeIndex(0,currentDict)"
@@ -112,20 +112,20 @@ function changeIndex(i: number, dict: Dict) {
</div>
<div class="slide-item">
<header>
<div class="dict-name">总词数{{ newWordDictData.list.length }}</div>
<div class="dict-name">总词数{{ newData.list.length }}</div>
</header>
<div class="content">
<WordList
class="word-list"
@change="(i:number) => changeIndex(i,store.newWordDict)"
@change="(i:number) => changeIndex(i,store.new)"
:isActive="settingStore.showPanel && tabIndex === 1"
:list="newWordDictData.list"
:activeIndex="newWordDictData.index"/>
:list="newData.list"
:activeIndex="newData.index"/>
</div>
<footer v-if="store.current.dictType !== DictType.newWordDict && newWordDictData.list.length">
<footer v-if="store.current.dictType !== DictType.new && newData.list.length">
<PopConfirm
:title="`确认切换?`"
@confirm="changeIndex(0,store.newWordDict)"
@confirm="changeIndex(0,store.new)"
>
<BaseButton>切换</BaseButton>
</PopConfirm>
@@ -134,21 +134,21 @@ function changeIndex(i: number, dict: Dict) {
<div class="slide-item">
<header>
<a href="" target="_blank"></a>
<div class="dict-name">总词数{{ wrongWordDictData.list.length }}</div>
<div class="dict-name">总词数{{ wrongData.list.length }}</div>
</header>
<div class="content">
<WordList
class="word-list"
@change="(i:number) => changeIndex(i,store.wrongWordDict)"
@change="(i:number) => changeIndex(i,store.wrong)"
:isActive="settingStore.showPanel && tabIndex === 2"
:list="wrongWordDictData.list"
:activeIndex="wrongWordDictData.index"/>
:list="wrongData.list"
:activeIndex="wrongData.index"/>
</div>
<footer
v-if="store.current.dictType !== DictType.wrongWordDict && wrongWordDictData.list.length">
v-if="store.current.dictType !== DictType.wrong && wrongData.list.length">
<PopConfirm
:title="`确认切换?`"
@confirm="changeIndex(0,store.wrongWordDict)"
@confirm="changeIndex(0,store.wrong)"
>
<BaseButton>切换</BaseButton>
</PopConfirm>
@@ -156,20 +156,20 @@ function changeIndex(i: number, dict: Dict) {
</div>
<div class="slide-item">
<header>
<div class="dict-name">总词数{{ skipWordDictData.list.length }}</div>
<div class="dict-name">总词数{{ skipData.list.length }}</div>
</header>
<div class="content">
<WordList
class="word-list"
@change="(i:number) => changeIndex(i,store.skipWordDict)"
@change="(i:number) => changeIndex(i,store.skip)"
:isActive="settingStore.showPanel && tabIndex === 3"
:list="skipWordDictData.list"
:activeIndex="skipWordDictData.index"/>
:list="skipData.list"
:activeIndex="skipData.index"/>
</div>
<footer v-if="store.current.dictType !== DictType.skipWordDict && skipWordDictData.list.length">
<footer v-if="store.current.dictType !== DictType.skip && skipData.list.length">
<PopConfirm
:title="`确认切换?`"
@confirm="changeIndex(0,store.skipWordDict)"
@confirm="changeIndex(0,store.skip)"
>
<BaseButton>切换</BaseButton>
</PopConfirm>

View File

@@ -281,10 +281,10 @@ function onKeyDown(e: KeyboardEvent) {
}
}
} else {
if (!store.wrongWordDict.originWords.find((v: Word) => v.name.toLowerCase() === currentWord.name.toLowerCase())) {
store.wrongWordDict.originWords.push(currentWord)
store.wrongWordDict.words.push(currentWord)
store.wrongWordDict.chapterWords = [store.wrongWordDict.words]
if (!store.wrong.originWords.find((v: Word) => v.name.toLowerCase() === currentWord.name.toLowerCase())) {
store.wrong.originWords.push(currentWord)
store.wrong.words.push(currentWord)
store.wrong.chapterWords = [store.wrong.words]
}
if (!store.skipWordNamesWithSimpleWords.includes(currentWord.name.toLowerCase())) {

View File

@@ -14,6 +14,7 @@ import {Icon} from "@iconify/vue";
import VolumeIcon from "@/components/VolumeIcon.vue";
import Tooltip from "@/components/Tooltip.vue";
import Panel from "@/components/Practice/Panel.vue";
import IconWrapper from "@/components/IconWrapper.vue";
interface IProps {
words: Word[],
@@ -75,19 +76,7 @@ watch(() => data.index, (n) => {
}
})
let allList = $ref([])
const word = $computed(() => {
// let w = data.words[data.index]
// let s = allList.find(s => s.name === w.name)
// if (s) return s
// else return w ?? {
// trans: [],
// name: '',
// usphone: '',
// ukphone: '',
// }
return data.words[data.index] ?? {
trans: [],
name: '',
@@ -151,7 +140,7 @@ function next(isTyping: boolean = true) {
data.index++
isTyping && practiceStore.inputWordNumber++
console.log('这个词完了')
if ([DictType.customDict, DictType.publicDict].includes(store.current.dictType)
if ([DictType.customWord, DictType.word].includes(store.current.dictType)
&& store.skipWordNames.includes(word.name.toLowerCase())) {
next()
}
@@ -171,10 +160,10 @@ function ignore() {
}
function collect() {
if (!store.newWordDict.originWords.find((v: Word) => v.name.toLowerCase() === word.name.toLowerCase())) {
store.newWordDict.originWords.push(word)
store.newWordDict.words.push(word)
store.newWordDict.chapterWords = [store.newWordDict.words]
if (!store.new.originWords.find((v: Word) => v.name.toLowerCase() === word.name.toLowerCase())) {
store.new.originWords.push(word)
store.new.words.push(word)
store.new.chapterWords = [store.new.words]
}
activeBtnIndex = 1
setTimeout(() => {
@@ -184,9 +173,9 @@ function collect() {
function remove() {
if (!store.skipWordNames.includes(word.name.toLowerCase())) {
store.skipWordDict.originWords.push(word)
store.skipWordDict.words.push(word)
store.skipWordDict.chapterWords = [store.skipWordDict.words]
store.skip.originWords.push(word)
store.skip.words.push(word)
store.skip.chapterWords = [store.skip.words]
}
activeBtnIndex = 0
next(false)
@@ -225,10 +214,10 @@ async function onKeyDown(e: KeyboardEvent) {
isWrong = (input + letter) !== word.name.slice(0, input.length + 1)
}
if (isWrong) {
if (!store.wrongWordDict.originWords.find((v: Word) => v.name.toLowerCase() === word.name.toLowerCase())) {
store.wrongWordDict.originWords.push(word)
store.wrongWordDict.words.push(word)
store.wrongWordDict.chapterWords = [store.wrongWordDict.words]
if (!store.wrong.originWords.find((v: Word) => v.name.toLowerCase() === word.name.toLowerCase())) {
store.wrong.originWords.push(word)
store.wrong.words.push(word)
store.wrong.chapterWords = [store.wrong.words]
}
if (!data.wrongWords.find((v: Word) => v.name.toLowerCase() === word.name.toLowerCase())) {
data.wrongWords.push(word)
@@ -305,21 +294,15 @@ useOnKeyboardEventListener(onKeyDown, onKeyUp)
<div class="prev"
@click="prev"
v-if="prevWord">
<Icon icon="bi:arrow-left" width="22"/>
<div class="word">
<div>{{ prevWord.name }}</div>
<div v-show="settingStore.translate">{{ prevWord.trans.join('') }}</div>
</div>
<Icon class="arrow" icon="bi:arrow-left" width="22"/>
<div class="word">{{ prevWord.name }}</div>
</div>
<Tooltip title="快捷键Tab">
<div class="next"
@click="next(false)"
v-if="nextWord">
<div class="word">
<div :class="settingStore.dictation && 'shadow'">{{ nextWord.name }}</div>
<div v-show="settingStore.translate">{{ nextWord.trans.join('') }}</div>
</div>
<Icon icon="bi:arrow-right" width="22"/>
<div class="word" :class="settingStore.dictation && 'shadow'">{{ nextWord.name }}</div>
<Icon class="arrow" icon="bi:arrow-right" width="22"/>
</div>
</Tooltip>
</div>
@@ -329,7 +312,7 @@ useOnKeyboardEventListener(onKeyDown, onKeyUp)
opacity: settingStore.translate ? 1 : 0
}"
>
<div v-for="i in word.trans">{{i}}</div>
<div v-for="i in word.trans">{{ i }}</div>
</div>
<div class="word-wrapper">
<div class="word"
@@ -351,21 +334,27 @@ useOnKeyboardEventListener(onKeyDown, onKeyUp)
</div>
<div class="phonetic">{{ settingStore.wordSoundType === 'us' ? word.usphone : word.ukphone }}</div>
<div class="options">
<BaseButton keyboard="`"
@click="remove"
:active="activeBtnIndex === 0">
忽略
</BaseButton>
<BaseButton keyboard="Enter"
@click="collect"
:active="activeBtnIndex === 1">
收藏
</BaseButton>
<BaseButton keyboard="Tab"
@click="ignore"
:active="activeBtnIndex === 2">
跳过
</BaseButton>
<Tooltip title="忽略(快捷键:`)">
<IconWrapper>
<Icon icon="fluent:delete-20-regular" class="menu"
:active="activeBtnIndex === 0"
@click="remove"/>
</IconWrapper>
</Tooltip>
<Tooltip title="收藏(快捷键Enter)">
<IconWrapper>
<Icon icon="ph:star" class="menu"
@click="collect"
:active="activeBtnIndex === 1"/>
</IconWrapper>
</Tooltip>
<Tooltip title="跳过(快捷键Tab)">
<IconWrapper>
<Icon icon="icon-park-outline:go-ahead" class="menu"
@click="ignore"
:active="activeBtnIndex === 2"/>
</IconWrapper>
</Tooltip>
</div>
<Panel :list="data.words" v-model:index="data.index"/>
</div>
@@ -392,35 +381,35 @@ useOnKeyboardEventListener(onKeyDown, onKeyUp)
top: 0;
width: 100%;
.word {
div {
font-size: 24rem;
margin-bottom: 4rem;
}
& > div {
width: 45%;
align-items: center;
div:last-child {
font-size: 14rem;
.arrow {
min-width: 22rem;
min-height: 22rem;
}
}
.word {
font-size: 24rem;
margin-bottom: 4rem;
}
.prev {
cursor: pointer;
display: flex;
float: left;
align-items: center;
gap: 10rem;
}
.next {
cursor: pointer;
display: flex;
align-items: center;
justify-content: flex-end;
gap: 10rem;
float: right;
.word {
text-align: right;
}
}
.shadow {
@@ -437,7 +426,7 @@ useOnKeyboardEventListener(onKeyDown, onKeyUp)
font-size: 18rem;
}
.phonetic, .translate {
.phonetic, .translate, .options {
font-size: 20rem;
margin-left: -30rem;
transition: all .3s;

View File

@@ -36,7 +36,7 @@ watch(() => props.groupByTag, () => {
</div>
<div class="dict-list">
<div class="dict-item anim"
:class="selectDictName === i.name && 'active'"
:class="selectDictName === i.id && 'active'"
@click="emit('selectDict',i)"
v-for="i in list"
>

View File

@@ -2,7 +2,7 @@
import {dictionaryResources} from '@/assets/dictionary.ts'
import {useBaseStore} from "@/stores/base.ts"
import {watch} from "vue"
import {Dict, DictResource, DictType, languageCategoryOptions, Sort, Word} from "@/types.ts"
import {DefaultDict, Dict, DictResource, DictType, languageCategoryOptions, Sort, Word} from "@/types.ts"
import {chunk, cloneDeep, groupBy} from "lodash-es";
import {$computed, $ref} from "vue/macros";
import Modal from "@/components/Modal/Modal.vue";
@@ -56,48 +56,34 @@ watch(() => props.modelValue, (n: boolean) => {
})
async function selectDict(item: DictResource) {
console.log('item',item)
console.log('item', item)
step = 1
let find = base.myDicts.find((v: Dict) => v.name === item.name)
if (find) {
runtimeStore.editDict = cloneDeep(find)
} else {
let data = {
sort: Sort.normal,
type: DictType.publicDict,
originWords: [],
words: [],
chapterWordNumber: 30,
chapterWords: [],
chapterIndex: 0,
chapterWordIndex: 0,
statistics: [],
articles: [],
let data: Dict = {
...DefaultDict,
...item,
}
if (item.resourceType === 'article') {
data.type = DictType.publicArticle
let r = await fetch(`/dicts/${item.language}/${item.resourceType}/${item.translateLanguage}/${item.url}`)
r.json().then(v => {
console.log('v', v)
data.articles = cloneDeep(v.map(v => {
v.id = uuidv4()
return v
let r = await fetch(`./dicts/${data.language}/${data.type}/${data.translateLanguage}/${item.url}`)
r.json().then(v => {
console.log('v', v)
if (data.type === DictType.article) {
data.articles = cloneDeep(v.map(s => {
s.id = uuidv4()
return s
}))
runtimeStore.editDict = cloneDeep(data)
})
} else {
data.type = DictType.publicDict
let r = await fetch(`/dicts/${item.language}/${item.resourceType}/${item.translateLanguage}/${item.url}`)
r.json().then(v => {
} else {
data.originWords = v
data.words = v
data.chapterWords = chunk(v, data.chapterWordNumber)
runtimeStore.editDict = cloneDeep(data)
console.log(' runtimeStore.editDict', runtimeStore.editDict)
})
}
}
})
}
}
@@ -130,7 +116,7 @@ function groupByDictTags(dictList: DictResource[]) {
const groupByTranslateLanguage = $computed(() => {
let data: any
if (currentLanguage === 'article') {
let articleList = dictionaryResources.filter(v => v.resourceType === 'article')
let articleList = dictionaryResources.filter(v => v.type === 'article')
data = groupBy(articleList, 'translateLanguage')
} else {
data = groupBy(groupByLanguage[currentLanguage], 'translateLanguage')
@@ -191,12 +177,12 @@ const dictIsArticle = $computed(() => {
<div class="translate">
<span>翻译</span>
<el-radio-group v-model="currentTranslateLanguage">
<el-radio v-for="i in translateLanguageList" :label="i">{{ i }}</el-radio>
<el-radio border v-for="i in translateLanguageList" :label="i">{{ i }}</el-radio>
</el-radio-group>
</div>
<DictGroup
v-for="item in groupedByCategoryAndTag"
:select-dict-name="runtimeStore.editDict.name"
:select-dict-name="runtimeStore.editDict.resourceId"
@selectDict="selectDict"
@detail="step = 1"
:groupByTag="item[1]"

View File

@@ -47,44 +47,54 @@ watch(() => settingStore.showToolbar, n => {
{{ store.dictTitle }} {{ practiceStore.repeatNumber ? ' 复习错词' : '' }}
</div>
<div class="options">
<Tooltip title="开关默写模式">
<Tooltip title="收起图标">
<IconWrapper>
<Icon icon="majesticons:eye-off-line"
v-if="settingStore.dictation"
@click="settingStore.dictation = false"/>
<Icon icon="mdi:eye-outline"
v-else
@click="settingStore.dictation = true"/>
<Icon :icon="`system-uicons:window-collapse-${settingStore.collapse?'left':'right'}`"
@click="settingStore.collapse = !settingStore.collapse"/>
</IconWrapper>
</Tooltip>
<TranslateSetting/>
<div class="more" v-if="!settingStore.collapse">
<Tooltip title="开关默写模式">
<IconWrapper>
<Icon icon="majesticons:eye-off-line"
v-if="settingStore.dictation"
@click="settingStore.dictation = false"/>
<Icon icon="mdi:eye-outline"
v-else
@click="settingStore.dictation = true"/>
</IconWrapper>
</Tooltip>
<VolumeSetting/>
<TranslateSetting/>
<RepeatSetting/>
<VolumeSetting/>
<Add/>
<RepeatSetting/>
<Add/>
<Tooltip title="反馈">
<IconWrapper>
<Icon icon="octicon:bug-24" @click="showFeedbackModal = true"/>
</IconWrapper>
</Tooltip>
<Tooltip title="切换主题">
<IconWrapper>
<Icon icon="ep:moon" v-if="settingStore.theme === 'dark'"
@click="toggle"/>
<Icon icon="tabler:sun" v-else @click="toggle"/>
</IconWrapper>
</Tooltip>
</div>
<Tooltip title="反馈">
<IconWrapper>
<Icon icon="octicon:bug-24" @click="showFeedbackModal = true"/>
</IconWrapper>
</Tooltip>
<Tooltip title="设置">
<IconWrapper>
<Icon icon="uil:setting" @click="showSettingModal = true"/>
</IconWrapper>
</Tooltip>
<!-- <div class="base-button" @click="emitter.emit(EventKey.openStatModal)">ok</div>-->
<Tooltip title="切换主题">
<IconWrapper>
<Icon icon="ep:moon" v-if="settingStore.theme === 'dark'"
@click="toggle"/>
<Icon icon="tabler:sun" v-else @click="toggle"/>
</IconWrapper>
</Tooltip>
<!-- <div class="base-button" @click="emitter.emit(EventKey.openStatModal)">ok</div>-->
<Tooltip title="单词本">
<IconWrapper>
@@ -152,6 +162,14 @@ header {
display: flex;
align-items: center;
gap: 10rem;
.more {
display: flex;
gap: 10rem;
align-items: center;
overflow: hidden;
transition: all .3s;
}
}
}

View File

@@ -257,7 +257,7 @@ export function getSplitTranslateText(article: string) {
export function isArticle(type: DictType): boolean {
return [
DictType.publicArticle,
DictType.article,
DictType.customArticle
].includes(type)
}

View File

@@ -1,13 +1,13 @@
import {defineStore} from 'pinia'
import {Dict, DictType, DisplayStatistics, SaveDictKey, Sort, Statistics, Word} from "../types.ts"
import {DefaultDict, 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';
export interface State {
newWordDict: Dict,
skipWordDict: Dict,
wrongWordDict: Dict,
new: Dict,
skip: Dict,
wrong: Dict,
myDicts: Dict[],
current: {
dictType: DictType,
@@ -22,131 +22,87 @@ export interface State {
export const useBaseStore = defineStore('base', {
state: (): State => {
return {
newWordDict: {
id: 'newWordDict',
new: {
...DefaultDict,
id: 'new',
name: '生词本',
sort: Sort.normal,
type: DictType.newWordDict,
originWords: [],
articles: [],
words: [],
chapterWordNumber: 15,
chapterWords: [],
chapterIndex: 0,
chapterWordIndex: 0,
statistics: [],
url: '',
type: DictType.new,
},
skipWordDict: {
id: 'skipWordDict',
skip: {
...DefaultDict,
id: 'skip',
name: '简单词',
sort: Sort.normal,
type: DictType.skipWordDict,
originWords: [],
articles: [],
words: [],
chapterWordNumber: 15,
chapterWords: [],
chapterIndex: 0,
chapterWordIndex: 0,
statistics: [],
url: '',
type: DictType.skip,
},
wrongWordDict: {
id: 'wrongWordDict',
wrong: {
...DefaultDict,
id: 'wrong',
name: '错词本',
sort: Sort.normal,
type: DictType.wrongWordDict,
originWords: [],
articles: [],
words: [],
chapterWordNumber: 15,
chapterWords: [],
chapterIndex: 0,
chapterWordIndex: 0,
statistics: [],
url: '',
type: DictType.wrong,
},
myDicts: [
{
...DefaultDict,
id: '新概念英语2-课文',
name: '新概念英语2-课文',
sort: Sort.normal,
type: DictType.publicArticle,
originWords: [],
articles: [],
words: [],
chapterWordNumber: 15,
chapterWords: [],
chapterIndex: 0,
chapterWordIndex: 0,
statistics: [],
type: DictType.article,
url: 'NCE_2.json',
translateLanguage: 'common',
language: 'en',
resourceType: "article"
},
{
...DefaultDict,
id: '新概念英语2',
name: '新概念英语2',
sort: Sort.normal,
type: DictType.publicDict,
originWords: [],
articles: [],
words: [],
chapterWordNumber: 15,
chapterWords: [],
chapterIndex: 0,
chapterWordIndex: 0,
statistics: [],
type: DictType.word,
url: 'nce-new-2.json',
resourceId: 'nce-new-2',
translateLanguage: 'common',
language: 'en',
resourceType: "word"
}
],
current: {
dictType: DictType.publicDict,
dictType: DictType.word,
// dictType: DictType.publicArticle,
index: 1,
editIndex: 0,
repeatNumber: 0,
},
simpleWords: [
'a', 'an', 'of', 'and',
'i', 'my', 'you', 'your',
'me', 'am', 'is', 'do', 'are',
'a', 'an',
'i', 'my', 'you', 'your', 'me', 'it',
'am', 'is', 'do', 'are', 'did', 'were',
'what', 'who', 'where', 'how', 'no', 'yes',
'not', 'did', 'were', 'can', 'could', 'it',
'the', 'to'
'not', 'can', 'could',
'the', 'to', 'of', 'for', 'and', 'that', 'this','be'
],
load: false
}
},
getters: {
skipWordNames: (state: State) => {
return state.skipWordDict.originWords.map(v => v.name.toLowerCase())
return state.skip.originWords.map(v => v.name.toLowerCase())
},
skipWordNamesWithSimpleWords: (state: State) => {
return state.skipWordDict.originWords.map(v => v.name.toLowerCase()).concat(state.simpleWords)
return state.skip.originWords.map(v => v.name.toLowerCase()).concat(state.simpleWords)
},
isArticle(state: State): boolean {
return [
DictType.publicArticle,
DictType.article,
DictType.customArticle
].includes(state.current.dictType)
},
currentDict(state: State): Dict {
switch (state.current.dictType) {
case DictType.newWordDict:
return state.newWordDict
case DictType.skipWordDict:
return state.skipWordDict
case DictType.wrongWordDict:
return state.wrongWordDict
case DictType.publicDict:
case DictType.publicArticle:
case DictType.customDict:
case DictType.new:
return state.new
case DictType.skip:
return state.skip
case DictType.wrong:
return state.wrong
case DictType.word:
case DictType.article:
case DictType.customWord:
case DictType.customArticle:
return this.myDicts[this.current.index]
}
@@ -166,7 +122,7 @@ export const useBaseStore = defineStore('base', {
},
dictTitle(state: State) {
let title = this.currentDict.name
if ([DictType.publicDict, DictType.customDict].includes(this.current.dictType)) {
if ([DictType.word, DictType.customWord].includes(this.current.dictType)) {
title += `${this.currentDict.chapterIndex + 1}`
}
return title
@@ -187,52 +143,54 @@ export const useBaseStore = defineStore('base', {
}
if ([
DictType.newWordDict,
DictType.wrongWordDict,
DictType.skipWordDict,
DictType.new,
DictType.wrong,
DictType.skip,
].includes(this.current.dictType)) {
} else {
if ([
DictType.publicDict,
DictType.customDict,
DictType.word,
DictType.customWord,
].includes(this.current.dictType)) {
if (!this.currentDict.originWords.length) {
let r = await fetch(`./dicts/${this.currentDict.language}/${this.currentDict.resourceType}/${this.currentDict.translateLanguage}/${this.currentDict.url}`)
// let r = await fetch(`.${this.currentDict.url}`)
let r = await fetch(`./dicts/${this.currentDict.language}/${this.currentDict.type}/${this.currentDict.translateLanguage}/${this.currentDict.url}`)
// let r = await fetch(`.${this.currentDict.url}`)0
r.json().then(v => {
fetch('./translate/en2zh_CN.json').then(r => {
r.json().then((list: Word[]) => {
console.log('list', list)
console.time()
if (this.currentDict.translateLanguage === 'common'){
fetch('./translate/en2zh_CN.json').then(r => {
r.json().then((list: Word[]) => {
console.time()
v.map((w: Word) => {
let res = list.find(a => a.name === w.name)
if (res) {
w = Object.assign(w, res)
}
return w
v.map((w: Word) => {
let res = list.find(a => a.name === w.name)
if (res) w = Object.assign(w, res)
})
this.currentDict.originWords = cloneDeep(v)
this.currentDict.words = cloneDeep(v)
this.currentDict.chapterWords = chunk(this.currentDict.words, this.currentDict.chapterWordNumber)
this.load = true
console.timeEnd()
})
console.log('v', v)
this.currentDict.originWords = cloneDeep(v)
this.currentDict.words = cloneDeep(v)
this.currentDict.chapterWords = chunk(this.currentDict.words, this.currentDict.chapterWordNumber)
this.load = true
console.timeEnd()
})
})
}else{
this.currentDict.originWords = cloneDeep(v)
this.currentDict.words = cloneDeep(v)
this.currentDict.chapterWords = chunk(this.currentDict.words, this.currentDict.chapterWordNumber)
this.load = true
}
})
}
}
if ([
DictType.publicArticle,
DictType.article,
DictType.customArticle,
].includes(this.current.dictType)) {
if (!this.currentDict.articles.length) {
let r = await fetch(`./dicts/${this.currentDict.language}/${this.currentDict.resourceType}/${this.currentDict.translateLanguage}/${this.currentDict.url}`)
let r = await fetch(`./dicts/${this.currentDict.language}/${this.currentDict.type}/${this.currentDict.translateLanguage}/${this.currentDict.url}`)
r.json().then((v: any[]) => {
this.currentDict.articles = cloneDeep(v.map(v => {
v.id = uuidv4()
@@ -255,9 +213,9 @@ export const useBaseStore = defineStore('base', {
// this.saveStatistics()
console.log('changeDict', cloneDeep(dict), chapterIndex, chapterWordIndex)
this.current.dictType = dict.type
if ([DictType.newWordDict,
DictType.skipWordDict,
DictType.wrongWordDict].includes(dict.type)) {
if ([DictType.new,
DictType.skip,
DictType.wrong].includes(dict.type)) {
this[dict.type].chapterIndex = chapterIndex
this[dict.type].chapterWordIndex = chapterWordIndex
} else {

View File

@@ -1,5 +1,5 @@
import {defineStore} from "pinia"
import {Dict, DictType, Sort} from "@/types.ts";
import {DefaultDict, Dict, DictType, Sort} from "@/types.ts";
export interface RuntimeState {
disableEventListener: boolean,
@@ -12,20 +12,7 @@ export const useRuntimeStore = defineStore('runtime', {
return {
disableEventListener: false,
modalList: [],
editDict: {
name: '',
sort: Sort.normal,
type: DictType.publicArticle,
originWords: [],
articles: [],
words: [],
chapterWordNumber: 15,
chapterWords: [],
chapterIndex: 0,
chapterWordIndex: 0,
statistics: [],
url: '',
},
editDict: {...DefaultDict},
}
},
})

View File

@@ -32,6 +32,7 @@ export interface SettingState {
},
showPanel: boolean,
theme: string,
collapse: boolean,
}
export const useSettingStore = defineStore('setting', {
@@ -70,6 +71,7 @@ export const useSettingStore = defineStore('setting', {
waitTimeForChangeWord: 300,
theme: 'auto',
collapse:false,
}
},
})

View File

@@ -1,7 +1,7 @@
import bookFlag from "@/assets/img/flags/book.png";
import enFlag from "@/assets/img/flags/en.png";
import jpFlag from "@/assets/img/flags/ja.png";
import deFlag from "@/assets/img/flags/de.png";
import deFlag from "./assets/img/flags/de.png";
import codeFlag from "@/assets/img/flags/code.png";
export type Word = {
@@ -25,7 +25,6 @@ export const PronunciationApi = 'https://dict.youdao.com/dictvoice?audio='
export type TranslateLanguageType = 'en' | 'zh-CN' | 'ja' | 'de' | 'common' | ''
export type LanguageType = 'en' | 'ja' | 'de' | 'code'
export type ResourceType = 'word' | 'article'
export type DictResource = {
id: string
@@ -36,7 +35,7 @@ export type DictResource = {
url: string
length: number
translateLanguage: TranslateLanguageType
resourceType: ResourceType
type: DictType
language: LanguageType
}
@@ -44,25 +43,29 @@ export interface Dict {
id: string,
name: string,
sort: Sort,
type: DictType,
originWords: Word[],//原始单词
words: Word[],
chapterWordNumber: number,//章节单词数量
chapterWords: Word[][],
chapterIndex: number,//章节下标
wordIndex: number,//单词下标
articles: Article[],
chapterIndex: number,
chapterWordIndex: number,
statistics: Statistics[],
resourceId: string,
type: DictType,
translateLanguage: TranslateLanguageType
language: LanguageType
url: string,
}
export enum DictType {
newWordDict = 'newWordDict',
skipWordDict = 'skipWordDict',
wrongWordDict = 'wrongWordDict',
publicDict = 'publicDict',
customDict = 'customDict',
publicArticle = 'publicArticle',
new = 'new',
skip = 'skip',
wrong = 'wrong',
word = 'word',
customWord = 'customWord',
article = 'article',
customArticle = 'customArticle'
}
@@ -172,3 +175,22 @@ export const languageCategoryOptions = [
{id: 'de', name: '德语', flag: deFlag},
{id: 'code', name: 'Code', flag: codeFlag},
]
export const DefaultDict: Dict = {
id: '',
name: '',
sort: Sort.normal,
originWords: [],//原始单词
words: [],
chapterWordNumber: 30,//章节单词数量
chapterWords: [],
chapterIndex: 0,//章节下标
wordIndex: 0,//单词下标
articles: [],
statistics: [],
resourceId: '',
type: DictType.word,
translateLanguage: 'common',
language: 'en',
url: '',
}

23
src/vite-env.d.ts vendored
View File

@@ -1,11 +1,11 @@
import {ElMessageBox} from "element-plus";
/// <reference types="vite/client" />
/// <reference types="vue/macros-global" />
// declare module '*.json' {
// const src: string
// export default src
// }
declare const LATEST_COMMIT_HASH: string
declare module '*.mp3' {
@@ -17,10 +17,16 @@ declare module '*.wav' {
const src: string;
export default src;
}
declare module '*.png' {
const src: string;
export default src;
}
declare module "*.png";
declare module "*.svg";
declare module "*.jpeg";
declare module "*.jpg";
// declare module '*.png' {
// const src: string;
// export default src;
// }
declare module "*.vue" {
import type {DefineComponent} from 'vue'
@@ -33,7 +39,7 @@ declare module "*.vue" {
// export default Vue
// }
declare module '*.ts';
// declare module '*.ts';
// declare global {
// interface Window {
@@ -42,3 +48,6 @@ declare module '*.ts';
// }
declare var ElMessageBox: ElMessageBox;
/// <reference types="vite/client" />
/// <reference types="vue/macros-global" />

View File

@@ -28,6 +28,7 @@
],
"types": [
"vue/ref-macros",
"vite/client",
"element-plus/global"
],
"baseUrl": "src",
@@ -41,9 +42,10 @@
}
},
"include": [
"src",
"src/**/*.ts",
"src/**/*.d.ts",
"src/**/*.tsx",
"src/**/*.d.ts",
"src/**/*.vue",
"auto-imports.d.ts",
"src/vite-env.d.ts"