fix(all): debug
This commit is contained in:
1
auto-imports.d.ts
vendored
1
auto-imports.d.ts
vendored
@@ -5,5 +5,6 @@
|
||||
// Generated by unplugin-auto-import
|
||||
export {}
|
||||
declare global {
|
||||
const ElMessage: typeof import('element-plus/es')['ElMessage']
|
||||
const ElMessageBox: typeof import('element-plus/es')['ElMessageBox']
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import {onMounted} from "vue";
|
||||
import Tooltip from "@/components/Tooltip.vue";
|
||||
import {Icon} from '@iconify/vue';
|
||||
import {useEsc} from "@/hooks/event.ts";
|
||||
|
||||
interface IProps {
|
||||
modelValue: boolean,
|
||||
@@ -25,13 +26,8 @@ function close() {
|
||||
emit('close',)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
window.addEventListener('keyup', (e: KeyboardEvent) => {
|
||||
if (e.key === 'Escape' && props.modelValue) {
|
||||
close()
|
||||
}
|
||||
})
|
||||
})
|
||||
useEsc(close)
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
import {onMounted, reactive, watch} from "vue";
|
||||
import {Article, Sentence, TranslateEngine} from "@/types.ts";
|
||||
import {Article, DefaultArticle, Sentence, TranslateEngine, TranslateType} from "@/types.ts";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import {
|
||||
getNetworkTranslate,
|
||||
@@ -13,6 +13,9 @@ import * as copy from "copy-to-clipboard";
|
||||
import {getSplitTranslateText, splitArticle} from "@/hooks/article.ts";
|
||||
import EditAbleText from "@/components/EditAbleText.vue";
|
||||
import {Icon} from "@iconify/vue";
|
||||
import {cloneDeep} from "lodash-es";
|
||||
import {useRuntimeStore} from "@/stores/runtime.ts";
|
||||
import {useDisableEventListener, useEsc} from "@/hooks/event.ts";
|
||||
|
||||
let article1 = `How does the older investor differ in his approach to investment from the younger investor?
|
||||
There is no shortage of tipsters around offering 'get-rich-quick' opportunities. But if you are a serious private investor, leave the Las Vegas mentality to those with money to fritter. The serious investor needs a proper 'portfolio' -- a well-planned selection of investments, with a definite structure and a clear aim. But exactly how does a newcomer to the stock market go about achieving that?
|
||||
@@ -40,27 +43,27 @@ NIGEL BUXTON The Great Escape from The Weekend Telegraph`
|
||||
|
||||
// article2 = `Economy is one powerful motive for camping? since after the initial outlay upon equipment, or through hiring it, the total expense can be far less than the cost of hotels. But, contrary to a popular assumption, it is far from being the only one, or even the greatest. The man who manoeuvres carelessly into his twenty pounds' worth of space at one of Europe's myriad permanent sites may find himself bumping a Bentley. More likely, Ford Escort will be hub to hub with Renault or Mercedes, but rarely with bicycles made for two.`
|
||||
|
||||
interface IProps {
|
||||
article?: Article
|
||||
}
|
||||
|
||||
let article = reactive<Article>({
|
||||
title: 'A private conversation!',
|
||||
titleTranslate: '',
|
||||
article: article1,
|
||||
customTranslate: ``,
|
||||
networkTranslate: ``,
|
||||
newWords: [],
|
||||
articleAllWords: [],
|
||||
sections: [],
|
||||
isTranslated: false,
|
||||
translateType: 0,
|
||||
const props = withDefaults(defineProps<IProps>(), {
|
||||
article: () => cloneDeep(DefaultArticle)
|
||||
})
|
||||
|
||||
let article = reactive<Article>(props.article)
|
||||
let networkTranslateEngine = $ref('baidu')
|
||||
let progress = $ref(0)
|
||||
const TranslateEngineOptions = [
|
||||
{value: 'baidu', label: '百度'},
|
||||
{value: 'youdao', label: '有道'},
|
||||
]
|
||||
defineEmits(['close'])
|
||||
const emit = defineEmits(['close'])
|
||||
|
||||
useDisableEventListener()
|
||||
useEsc(() => {
|
||||
emit('close')
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
updateSentenceTranslate()
|
||||
@@ -71,6 +74,12 @@ function updateSections() {
|
||||
}
|
||||
|
||||
async function startNetworkTranslate() {
|
||||
if (!article.title.trim()) {
|
||||
return ElMessage.error('请填写标题!')
|
||||
}
|
||||
if (!article.article.trim()) {
|
||||
return ElMessage.error('请填写正文!')
|
||||
}
|
||||
updateSections()
|
||||
article.networkTranslate = ''
|
||||
//注意!!!
|
||||
@@ -87,7 +96,7 @@ async function startNetworkTranslate() {
|
||||
|
||||
function saveSentenceTranslate(sentence: Sentence, val: string) {
|
||||
sentence.translate = val
|
||||
if (article.translateType) {
|
||||
if (article.translateType === TranslateType.custom) {
|
||||
article.customTranslate = getSentenceAllTranslateText(article)
|
||||
} else {
|
||||
article.networkTranslate = getSentenceAllTranslateText(article)
|
||||
@@ -103,7 +112,7 @@ function saveSentenceText(sentence: Sentence, val: string) {
|
||||
function updateSentenceTranslate() {
|
||||
if (article.article.trim()) {
|
||||
updateSections()
|
||||
if (article.translateType) {
|
||||
if (article.translateType === TranslateType.custom) {
|
||||
updateLocalSentenceTranslate(article, article.customTranslate)
|
||||
} else {
|
||||
updateLocalSentenceTranslate(article, article.networkTranslate)
|
||||
@@ -112,7 +121,7 @@ function updateSentenceTranslate() {
|
||||
}
|
||||
|
||||
function appendTranslate(str: string) {
|
||||
if (article.translateType) {
|
||||
if (article.translateType === TranslateType.custom) {
|
||||
article.customTranslate += str
|
||||
} else {
|
||||
article.networkTranslate += str
|
||||
@@ -144,7 +153,7 @@ function onFocus() {
|
||||
}
|
||||
|
||||
function save() {
|
||||
console.log('article',article )
|
||||
console.log('article', article)
|
||||
copy(JSON.stringify(article))
|
||||
}
|
||||
|
||||
@@ -158,7 +167,7 @@ watch(() => article.networkTranslate, (str: string) => {
|
||||
|
||||
watch(() => article.translateType, () => {
|
||||
if (article.article.trim()) {
|
||||
if (article.translateType) {
|
||||
if (article.translateType === TranslateType.custom) {
|
||||
if (article.customTranslate.trim()) {
|
||||
updateLocalSentenceTranslate(article, article.customTranslate)
|
||||
} else {
|
||||
@@ -211,8 +220,8 @@ watch(() => article.translateType, () => {
|
||||
<div class="label">
|
||||
<span>标题:</span>
|
||||
<el-radio-group v-model="article.translateType">
|
||||
<el-radio-button :label="0">网络翻译</el-radio-button>
|
||||
<el-radio-button :label="1">本地翻译</el-radio-button>
|
||||
<el-radio-button :label="TranslateType.custom">本地翻译</el-radio-button>
|
||||
<el-radio-button :label="TranslateType.network">网络翻译</el-radio-button>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<textarea
|
||||
@@ -226,7 +235,7 @@ watch(() => article.translateType, () => {
|
||||
<div class="item basic">
|
||||
<div class="label">
|
||||
<span>正文:</span>
|
||||
<div class="translate-item" v-if="!article.translateType">
|
||||
<div class="translate-item" v-if="article.translateType === TranslateType.network">
|
||||
<el-progress :percentage="progress"
|
||||
:duration="30"
|
||||
:striped="progress !== 100"
|
||||
@@ -245,14 +254,13 @@ watch(() => article.translateType, () => {
|
||||
</el-select>
|
||||
<BaseButton
|
||||
size="small"
|
||||
@click="startNetworkTranslate"
|
||||
:disabled="!article.article.trim()">开始翻译
|
||||
@click="startNetworkTranslate">开始翻译
|
||||
</BaseButton>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<textarea
|
||||
v-if="article.translateType"
|
||||
v-if="article.translateType === TranslateType.custom"
|
||||
v-model="article.customTranslate"
|
||||
:readonly="![100,0].includes(progress)"
|
||||
@blur="onBlur"
|
||||
|
||||
@@ -12,10 +12,18 @@ import Statistics from "@/components/Practice/Statistics.vue";
|
||||
import {emitter, EventKey} from "@/utils/eventBus";
|
||||
import {useSettingStore} from "@/stores/setting";
|
||||
import {cloneDeep} from "lodash-es";
|
||||
import {Article, DefaultArticle} from "@/types.ts";
|
||||
import AddArticle from "@/components/Practice/AddArticle.vue";
|
||||
import {useEventListener, useStartKeyboardEventListener} from "@/hooks/event.ts";
|
||||
import {useRuntimeStore} from "@/stores/runtime.ts";
|
||||
|
||||
const practiceStore = usePracticeStore()
|
||||
const store = useBaseStore()
|
||||
const settingStore = useSettingStore()
|
||||
const runtimeStore = useRuntimeStore()
|
||||
|
||||
let showEditArticle = $ref(false)
|
||||
let editArticle = $ref(cloneDeep(DefaultArticle))
|
||||
|
||||
watch(practiceStore, () => {
|
||||
if (practiceStore.inputNumber < 1) {
|
||||
@@ -1139,24 +1147,30 @@ let articleData = $ref({
|
||||
|
||||
watch(() => store.load, n => {
|
||||
if (n) {
|
||||
getCurrentWords()
|
||||
getCurrentPractice()
|
||||
}
|
||||
})
|
||||
|
||||
function getCurrentWords() {
|
||||
wordData.words = cloneDeep(store.chapter)
|
||||
wordData.index = 0
|
||||
}
|
||||
function getCurrentPractice() {
|
||||
if (store.isArticle) {
|
||||
let article: Article = cloneDeep(store.currentDict.articles[store.currentDict.chapterIndex])
|
||||
if (article?.isTranslated) {
|
||||
articleData.article = article
|
||||
} else {
|
||||
|
||||
function getCurrentArticle() {
|
||||
wordData.words = cloneDeep(store.chapter)
|
||||
wordData.index = 0
|
||||
}
|
||||
} else {
|
||||
wordData.words = cloneDeep(store.chapter)
|
||||
wordData.index = 0
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
|
||||
})
|
||||
|
||||
useStartKeyboardEventListener()
|
||||
|
||||
function write() {
|
||||
console.log('write')
|
||||
settingStore.dictation = true
|
||||
@@ -1166,7 +1180,7 @@ function write() {
|
||||
//TODO 需要判断是否已忽略
|
||||
function repeat() {
|
||||
console.log('repeat')
|
||||
getCurrentWords()
|
||||
getCurrentPractice()
|
||||
emitter.emit(EventKey.resetWord)
|
||||
}
|
||||
|
||||
@@ -1183,7 +1197,7 @@ function next() {
|
||||
<div class="practice">
|
||||
<Toolbar/>
|
||||
<TypeArticle
|
||||
v-if="practiceStore.type === 'article'"
|
||||
v-if="store.isArticle"
|
||||
:article="articleData.article"
|
||||
:sectionIndex="articleData.sectionIndex"
|
||||
:sentenceIndex="articleData.sentenceIndex"
|
||||
@@ -1201,6 +1215,9 @@ function next() {
|
||||
@repeat="repeat"
|
||||
@next="next"
|
||||
/>
|
||||
<AddArticle v-if="showEditArticle"
|
||||
@close="showEditArticle = false"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
@@ -7,7 +7,7 @@ import {usePracticeStore} from "@/stores/practice.ts";
|
||||
import TypeWord from "@/components/Practice/TypeWord.vue";
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
import {usePlayBeep, usePlayCorrect, usePlayKeyboardAudio, usePlayWordAudio} from "@/hooks/sound.ts";
|
||||
import {useEventListener} from "@/hooks/event.ts";
|
||||
import {useEventListener, useOnKeyboardEventListener} from "@/hooks/event.ts";
|
||||
|
||||
let article1 = `How does the older investor differ in his approach to investment from the younger investor?
|
||||
There is no shortage of tipsters around offering 'get-rich-quick' opportunities. But if you are a serious private investor, leave the Las Vegas mentality to those with money to fritter. The serious investor needs a proper 'portfolio' -- a well-planned selection of investments, with a definite structure and a clear aim. But exactly how does a newcomer to the stock market go about achieving that?
|
||||
@@ -304,6 +304,10 @@ function onKeyUp() {
|
||||
}
|
||||
}
|
||||
|
||||
useOnKeyboardEventListener(onKeyDown, onKeyUp)
|
||||
|
||||
// useEventListener('keydown', onKeyDown)
|
||||
// useEventListener('keyup', onKeyUp)
|
||||
|
||||
function playWord(word: ArticleWord) {
|
||||
playWordAudio(word.name)
|
||||
@@ -355,8 +359,6 @@ function otherWord(word: ArticleWord, i: number, i2: number, i3: number) {
|
||||
return str
|
||||
}
|
||||
|
||||
useEventListener('keydown', onKeyDown)
|
||||
useEventListener('keyup', onKeyUp)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -9,7 +9,7 @@ import {cloneDeep} from "lodash-es"
|
||||
import {usePracticeStore} from "@/stores/practice.ts"
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
import {usePlayBeep, usePlayCorrect, usePlayKeyboardAudio, usePlayWordAudio} from "@/hooks/sound.ts";
|
||||
import {useEventListener} from "@/hooks/event.ts";
|
||||
import {useEventListener, useOnKeyboardEventListener} from "@/hooks/event.ts";
|
||||
|
||||
interface IProps {
|
||||
words: Word[],
|
||||
@@ -75,9 +75,6 @@ onMounted(() => {
|
||||
})
|
||||
})
|
||||
|
||||
useEventListener('keydown', onKeyDown)
|
||||
useEventListener('keyup', onKeyUp)
|
||||
|
||||
function next() {
|
||||
if (data.index === data.words.length - 1) {
|
||||
if (data.wrongWords.length) {
|
||||
@@ -201,6 +198,11 @@ async function onKeyDown(e: KeyboardEvent) {
|
||||
}, 200)
|
||||
}
|
||||
}
|
||||
|
||||
useOnKeyboardEventListener(onKeyDown, onKeyUp)
|
||||
// useEventListener('keydown', onKeyDown)
|
||||
// useEventListener('keyup', onKeyUp)
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -5,6 +5,7 @@ import {Icon} from '@iconify/vue';
|
||||
import {watch, ref} from "vue";
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
import {useChangeAllSound, useWatchAllSound} from "@/hooks/sound.ts";
|
||||
import {useDisableEventListener} from "@/hooks/event.ts";
|
||||
|
||||
const tabIndex = $ref(0)
|
||||
const settingStore = useSettingStore()
|
||||
@@ -21,6 +22,7 @@ const emit = defineEmits([
|
||||
'update:modelValue',
|
||||
])
|
||||
|
||||
// useDisableEventListener()
|
||||
useWatchAllSound()
|
||||
|
||||
</script>
|
||||
|
||||
@@ -310,3 +310,4 @@ export function getSplitTranslateText(article: string) {
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import {onMounted, onUnmounted} from "vue";
|
||||
import {emitter, EventKey} from "@/utils/eventBus.ts";
|
||||
import {useRuntimeStore} from "@/stores/runtime.ts";
|
||||
|
||||
export function useWindowClick(cb: () => void) {
|
||||
onMounted(() => {
|
||||
@@ -16,13 +17,49 @@ export function useEventListener(type: string, listener: EventListenerOrEventLis
|
||||
onUnmounted(() => window.removeEventListener(type, listener))
|
||||
}
|
||||
|
||||
export function useEsc(can: boolean) {
|
||||
export function useStartKeyboardEventListener() {
|
||||
const runtimeStore = useRuntimeStore()
|
||||
|
||||
useEventListener('keydown', (e: KeyboardEvent) => {
|
||||
if (!runtimeStore.disableEventListener) {
|
||||
emitter.emit(EventKey.keydown, e)
|
||||
}
|
||||
})
|
||||
useEventListener('keyup', (e: KeyboardEvent) => {
|
||||
if (!runtimeStore.disableEventListener) {
|
||||
emitter.emit(EventKey.keyup, e)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export function useOnKeyboardEventListener(onKeyDown: (e: KeyboardEvent) => void, onKeyUp: (e: KeyboardEvent) => void) {
|
||||
onMounted(() => {
|
||||
emitter.on(EventKey.keydown, onKeyDown)
|
||||
emitter.on(EventKey.keyup, onKeyUp)
|
||||
})
|
||||
onUnmounted(() => {
|
||||
emitter.off(EventKey.keydown, onKeyDown)
|
||||
emitter.off(EventKey.keyup, onKeyUp)
|
||||
})
|
||||
}
|
||||
|
||||
export function useDisableEventListener() {
|
||||
const runtimeStore = useRuntimeStore()
|
||||
onMounted(() => {
|
||||
runtimeStore.disableEventListener = true
|
||||
})
|
||||
onUnmounted(() => {
|
||||
runtimeStore.disableEventListener = false
|
||||
})
|
||||
}
|
||||
|
||||
export function useEsc(close: () => void) {
|
||||
onMounted(() => {
|
||||
window.addEventListener('keyup', (e: KeyboardEvent) => {
|
||||
if (e.key === 'Escape' && can) {
|
||||
if (e.key === 'Escape') {
|
||||
close()
|
||||
}
|
||||
})
|
||||
})
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,53 +1,52 @@
|
||||
import {Article, Sentence, TranslateEngine} from "@/types.ts";
|
||||
import {Article, Sentence, TranslateEngine, TranslateType} from "@/types.ts";
|
||||
import Baidu from "@opentranslate/baidu";
|
||||
import {axiosInstance} from "@/utils/http.ts";
|
||||
import {CnKeyboardMap, EnKeyboardMap, splitCNArticle} from "@/hooks/article.ts";
|
||||
import {getSplitTranslateText, splitArticle} from "@/hooks/article.ts";
|
||||
import {Translator} from "@opentranslate/translator/src/translator.ts";
|
||||
import {cloneDeep} from "lodash-es";
|
||||
|
||||
export function updateLocalSentenceTranslate(article: Article, translate: string) {
|
||||
if (translate.trim()) {
|
||||
let articleTranslate = translate.split('\n')
|
||||
// console.log('articleTranslate', articleTranslate)
|
||||
let count = 0
|
||||
for (let i = 0; i < article.sections.length; i++) {
|
||||
let v = article.sections[i]
|
||||
for (let j = 0; j < v.length; j++) {
|
||||
let sentence = v[j]
|
||||
try {
|
||||
sentence.translate = articleTranslate[count]
|
||||
} catch (e) {
|
||||
console.log('没有对应的翻译', sentence.text)
|
||||
if (translate.trim()) {
|
||||
let articleTranslate = translate.split('\n')
|
||||
// console.log('articleTranslate', articleTranslate)
|
||||
let count = 0
|
||||
for (let i = 0; i < article.sections.length; i++) {
|
||||
let v = article.sections[i]
|
||||
for (let j = 0; j < v.length; j++) {
|
||||
let sentence = v[j]
|
||||
try {
|
||||
sentence.translate = articleTranslate[count]
|
||||
} catch (e) {
|
||||
console.log('没有对应的翻译', sentence.text)
|
||||
}
|
||||
count++
|
||||
}
|
||||
count++
|
||||
}
|
||||
count++
|
||||
}
|
||||
count++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function getSentenceAllTranslateText(article: Article) {
|
||||
let str = ''
|
||||
article.sections.map((v: Sentence[]) => {
|
||||
v.map((w: Sentence, j, arr) => {
|
||||
if (w.translate) {
|
||||
str += w.translate + '\n'
|
||||
}
|
||||
let str = ''
|
||||
article.sections.map((v: Sentence[]) => {
|
||||
v.map((w: Sentence, j, arr) => {
|
||||
if (w.translate) {
|
||||
str += w.translate + '\n'
|
||||
}
|
||||
})
|
||||
str += '\n'
|
||||
})
|
||||
str += '\n'
|
||||
})
|
||||
return str
|
||||
return str
|
||||
}
|
||||
|
||||
export function getSentenceAllText(article: Article) {
|
||||
let str = ''
|
||||
article.sections.map((v: Sentence[]) => {
|
||||
v.map((w: Sentence, j, arr) => {
|
||||
str += w.text
|
||||
let str = ''
|
||||
article.sections.map((v: Sentence[]) => {
|
||||
v.map((w: Sentence, j, arr) => {
|
||||
str += w.text
|
||||
})
|
||||
str += '\n'
|
||||
})
|
||||
str += '\n'
|
||||
})
|
||||
return str
|
||||
return str
|
||||
}
|
||||
|
||||
/***
|
||||
@@ -58,135 +57,162 @@ export function getSentenceAllText(article: Article) {
|
||||
* @param progressCb 进度回调
|
||||
* */
|
||||
export async function getNetworkTranslate(
|
||||
article: Article,
|
||||
translateEngine: TranslateEngine,
|
||||
allShow: boolean = false,
|
||||
progressCb?: (val: number) => void
|
||||
article: Article,
|
||||
translateEngine: TranslateEngine,
|
||||
allShow: boolean = false,
|
||||
progressCb?: (val: number) => void
|
||||
) {
|
||||
if (article.networkTranslate) {
|
||||
updateLocalSentenceTranslate(article, article.networkTranslate)
|
||||
} else {
|
||||
let translator: Translator
|
||||
if (translateEngine === TranslateEngine.Baidu) {
|
||||
translator = new Baidu({
|
||||
axios: axiosInstance as any,
|
||||
config: {
|
||||
appid: "20230910001811857",
|
||||
key: "Xxe_yftQR3K3Ue43NQMC"
|
||||
if (article.networkTranslate) {
|
||||
updateLocalSentenceTranslate(article, article.networkTranslate)
|
||||
} else {
|
||||
let translator: Translator
|
||||
if (translateEngine === TranslateEngine.Baidu) {
|
||||
translator = new Baidu({
|
||||
axios: axiosInstance as any,
|
||||
config: {
|
||||
appid: "20230910001811857",
|
||||
key: "Xxe_yftQR3K3Ue43NQMC"
|
||||
}
|
||||
}) as any
|
||||
}
|
||||
|
||||
|
||||
if (translator) {
|
||||
if (!article.titleTranslate) {
|
||||
translator.translate(article.title, 'en', 'zh-CN').then(r => {
|
||||
article.titleTranslate = r.trans.paragraphs[0]
|
||||
})
|
||||
}
|
||||
|
||||
let promiseList = []
|
||||
let retryCount = 0
|
||||
let retryCountMap = new Map()
|
||||
|
||||
const translate = async (sentence: Sentence) => {
|
||||
try {
|
||||
let r = await translator.translate(sentence.text, 'en', 'zh-CN')
|
||||
if (r) {
|
||||
const cb = () => {
|
||||
sentence.translate = r.trans.paragraphs[0]
|
||||
if (!allShow) {
|
||||
//一次显示所有,顺序会乱
|
||||
article.networkTranslate += sentence.translate + '\n'
|
||||
}
|
||||
}
|
||||
return Promise.resolve(cb)
|
||||
} else {
|
||||
return Promise.reject(() => translate(sentence))
|
||||
}
|
||||
} catch (e) {
|
||||
return Promise.reject(() => translate(sentence))
|
||||
}
|
||||
}
|
||||
|
||||
let total = 0
|
||||
let index = 0
|
||||
article.sections.map(v => total += v.length)
|
||||
|
||||
for (let i = 0; i < article.sections.length; i++) {
|
||||
let v = article.sections[i]
|
||||
for (let j = 0; j < v.length; j++) {
|
||||
let sentence = v[j]
|
||||
let promise = translate(sentence)
|
||||
if (allShow) {
|
||||
promiseList.push(promise)
|
||||
} else {
|
||||
retryCountMap.set(sentence.text, 0)
|
||||
let errResult: any
|
||||
let cb = await promise.catch(err => {
|
||||
errResult = err
|
||||
})
|
||||
|
||||
while (errResult) {
|
||||
let count = retryCountMap.get(sentence.text)
|
||||
if (count > 2) break
|
||||
cb = await errResult().catch(err => {
|
||||
errResult = err
|
||||
})
|
||||
retryCountMap.set(sentence.text, count + 1)
|
||||
}
|
||||
if (cb) cb()
|
||||
index++
|
||||
if (progressCb) {
|
||||
progressCb(Math.floor((index / total) * 100))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (promiseList.length) {
|
||||
let timer = -1
|
||||
let progress = 0
|
||||
if (progressCb) {
|
||||
timer = setInterval(() => {
|
||||
progress++
|
||||
if (progress > 90) {
|
||||
return clearInterval(timer)
|
||||
}
|
||||
progressCb(progress)
|
||||
}, 100)
|
||||
}
|
||||
|
||||
return new Promise(async resolve => {
|
||||
let cbs = []
|
||||
do {
|
||||
if (retryCount > 2) {
|
||||
return resolve(true)
|
||||
}
|
||||
let results = await Promise.allSettled(promiseList)
|
||||
promiseList = []
|
||||
results.map(results => {
|
||||
if (results.status === 'fulfilled') {
|
||||
cbs.push(results.value)
|
||||
} else {
|
||||
promiseList.push(results.reason())
|
||||
}
|
||||
})
|
||||
retryCount++
|
||||
} while (promiseList.length)
|
||||
cbs.map(v => v())
|
||||
article.networkTranslate = getSentenceAllTranslateText(article)
|
||||
|
||||
if (progressCb) {
|
||||
clearInterval(timer)
|
||||
progress = 100
|
||||
progressCb(100)
|
||||
}
|
||||
resolve(true)
|
||||
})
|
||||
} else {
|
||||
article.networkTranslate = getSentenceAllTranslateText(article)
|
||||
}
|
||||
}
|
||||
}) as any
|
||||
}
|
||||
}
|
||||
|
||||
export function test(article: Article) {
|
||||
if (article?.isTranslated) {
|
||||
if (!article.sections?.length) {
|
||||
|
||||
if (translator) {
|
||||
if (!article.titleTranslate) {
|
||||
translator.translate(article.title, 'en', 'zh-CN').then(r => {
|
||||
article.titleTranslate = r.trans.paragraphs[0]
|
||||
})
|
||||
}
|
||||
|
||||
let promiseList = []
|
||||
let retryCount = 0
|
||||
let retryCountMap = new Map()
|
||||
|
||||
const translate = async (sentence: Sentence) => {
|
||||
try {
|
||||
let r = await translator.translate(sentence.text, 'en', 'zh-CN')
|
||||
if (r) {
|
||||
const cb = () => {
|
||||
sentence.translate = r.trans.paragraphs[0]
|
||||
if (!allShow) {
|
||||
//一次显示所有,顺序会乱
|
||||
article.networkTranslate += sentence.translate + '\n'
|
||||
}
|
||||
}
|
||||
return Promise.resolve(cb)
|
||||
} else {
|
||||
return Promise.reject(() => translate(sentence))
|
||||
}
|
||||
} catch (e) {
|
||||
return Promise.reject(() => translate(sentence))
|
||||
}
|
||||
}
|
||||
|
||||
let total = 0
|
||||
let index = 0
|
||||
article.sections.map(v => total += v.length)
|
||||
|
||||
for (let i = 0; i < article.sections.length; i++) {
|
||||
let v = article.sections[i]
|
||||
for (let j = 0; j < v.length; j++) {
|
||||
let sentence = v[j]
|
||||
let promise = translate(sentence)
|
||||
if (allShow) {
|
||||
promiseList.push(promise)
|
||||
} else {
|
||||
retryCountMap.set(sentence.text, 0)
|
||||
let errResult: any
|
||||
let cb = await promise.catch(err => {
|
||||
errResult = err
|
||||
})
|
||||
|
||||
while (errResult) {
|
||||
let count = retryCountMap.get(sentence.text)
|
||||
if (count > 2) break
|
||||
cb = await errResult().catch(err => {
|
||||
errResult = err
|
||||
})
|
||||
retryCountMap.set(sentence.text, count + 1)
|
||||
} else {
|
||||
if (article.translateType !== undefined) {
|
||||
if (article.translateType) {
|
||||
updateLocalSentenceTranslate(article, article.customTranslate)
|
||||
} else {
|
||||
updateLocalSentenceTranslate(article, article.networkTranslate)
|
||||
}
|
||||
if (cb) cb()
|
||||
index++
|
||||
if (progressCb) {
|
||||
progressCb(Math.floor((index / total) * 100))
|
||||
} else {
|
||||
article.sections = splitArticle(article.article)
|
||||
if (article.customTranslate) {
|
||||
article.customTranslate = getSplitTranslateText(article.customTranslate)
|
||||
updateLocalSentenceTranslate(article, article.customTranslate)
|
||||
article.translateType = TranslateType.custom
|
||||
} else {
|
||||
article.networkTranslate = getSplitTranslateText(article.networkTranslate)
|
||||
updateLocalSentenceTranslate(article, article.customTranslate)
|
||||
article.translateType = TranslateType.network
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (promiseList.length) {
|
||||
let timer = -1
|
||||
let progress = 0
|
||||
if (progressCb) {
|
||||
timer = setInterval(() => {
|
||||
progress++
|
||||
if (progress > 90) {
|
||||
return clearInterval(timer)
|
||||
}
|
||||
progressCb(progress)
|
||||
}, 100)
|
||||
}
|
||||
|
||||
return new Promise(async resolve => {
|
||||
let cbs = []
|
||||
do {
|
||||
if (retryCount > 2) {
|
||||
return resolve(true)
|
||||
}
|
||||
let results = await Promise.allSettled(promiseList)
|
||||
promiseList = []
|
||||
results.map(results => {
|
||||
if (results.status === 'fulfilled') {
|
||||
cbs.push(results.value)
|
||||
} else {
|
||||
promiseList.push(results.reason())
|
||||
}
|
||||
})
|
||||
retryCount++
|
||||
} while (promiseList.length)
|
||||
cbs.map(v => v())
|
||||
article.networkTranslate = getSentenceAllTranslateText(article)
|
||||
|
||||
if (progressCb) {
|
||||
clearInterval(timer)
|
||||
progress = 100
|
||||
progressCb(100)
|
||||
}
|
||||
resolve(true)
|
||||
})
|
||||
} else {
|
||||
article.networkTranslate = getSentenceAllTranslateText(article)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,238 +4,238 @@ import {chunk, cloneDeep} from "lodash-es";
|
||||
import {emitter, EventKey} from "@/utils/eventBus.ts"
|
||||
|
||||
export const useBaseStore = defineStore('base', {
|
||||
state: (): State => {
|
||||
return {
|
||||
newWordDict: {
|
||||
name: '生词本',
|
||||
sort: Sort.normal,
|
||||
type: DictType.newDict,
|
||||
originWords: [],
|
||||
articles: [],
|
||||
words: [],
|
||||
chapterWordNumber: 15,
|
||||
chapterWords: [],
|
||||
chapterIndex: 0,
|
||||
chapterWordIndex: 0,
|
||||
statistics: [],
|
||||
url: '',
|
||||
},
|
||||
skipWordDict: {
|
||||
name: '简单词',
|
||||
sort: Sort.normal,
|
||||
type: DictType.skipDict,
|
||||
originWords: [],
|
||||
articles: [],
|
||||
words: [],
|
||||
chapterWordNumber: 15,
|
||||
chapterWords: [],
|
||||
chapterIndex: 0,
|
||||
chapterWordIndex: 0,
|
||||
statistics: [],
|
||||
url: '',
|
||||
},
|
||||
wrongWordDict: {
|
||||
name: '错词本',
|
||||
sort: Sort.normal,
|
||||
type: DictType.wrongDict,
|
||||
originWords: [],
|
||||
articles: [],
|
||||
words: [],
|
||||
chapterWordNumber: 15,
|
||||
chapterWords: [],
|
||||
chapterIndex: 0,
|
||||
chapterWordIndex: 0,
|
||||
statistics: [],
|
||||
url: '',
|
||||
},
|
||||
// dict: {
|
||||
// name: '新概念英语-2',
|
||||
// sort: Sort.normal,
|
||||
// type: DictType.innerDict,
|
||||
// originWords: [],
|
||||
// articles: [],
|
||||
// words: [],
|
||||
// chapterWordNumber: 15,
|
||||
// chapterWords: [],
|
||||
// chapterIndex: 0,
|
||||
// chapterWordIndex: 0,
|
||||
// statistics: [],
|
||||
// url: '/dicts/NCE_2.json',
|
||||
// },
|
||||
dict: {
|
||||
name: '新概念英语-2',
|
||||
sort: Sort.normal,
|
||||
type: DictType.publicArticle,
|
||||
originWords: [],
|
||||
articles: [],
|
||||
words: [],
|
||||
chapterWordNumber: 15,
|
||||
chapterWords: [],
|
||||
chapterIndex: 0,
|
||||
chapterWordIndex: 0,
|
||||
statistics: [],
|
||||
url: '/articles/NCE_2.json',
|
||||
},
|
||||
oldDicts: [],
|
||||
current: {
|
||||
dictType: DictType.publicDict,
|
||||
words: [],
|
||||
index: -1,
|
||||
wrongWords: [],
|
||||
originWrongWords: [],
|
||||
repeatNumber: 0,
|
||||
statistics: {
|
||||
startDate: -1,
|
||||
endDate: -1,
|
||||
spend: -1,
|
||||
total: -1,
|
||||
correctRate: -1,
|
||||
wrongWordNumber: -1,
|
||||
}
|
||||
},
|
||||
sideIsOpen: false,
|
||||
isDictation: true,
|
||||
simpleWords: [
|
||||
'a', 'an', 'of', 'and',
|
||||
'i', 'my', 'you', 'your',
|
||||
'me', 'am', 'is', 'do', 'are',
|
||||
'what', 'who', 'where', 'how', 'no', 'yes',
|
||||
'not', 'did', 'were', 'can', 'could', 'it',
|
||||
'the', 'to'
|
||||
],
|
||||
theme: 'auto',
|
||||
load: false
|
||||
state: (): State => {
|
||||
return {
|
||||
newWordDict: {
|
||||
name: '生词本',
|
||||
sort: Sort.normal,
|
||||
type: DictType.newDict,
|
||||
originWords: [],
|
||||
articles: [],
|
||||
words: [],
|
||||
chapterWordNumber: 15,
|
||||
chapterWords: [],
|
||||
chapterIndex: 0,
|
||||
chapterWordIndex: 0,
|
||||
statistics: [],
|
||||
url: '',
|
||||
},
|
||||
skipWordDict: {
|
||||
name: '简单词',
|
||||
sort: Sort.normal,
|
||||
type: DictType.skipDict,
|
||||
originWords: [],
|
||||
articles: [],
|
||||
words: [],
|
||||
chapterWordNumber: 15,
|
||||
chapterWords: [],
|
||||
chapterIndex: 0,
|
||||
chapterWordIndex: 0,
|
||||
statistics: [],
|
||||
url: '',
|
||||
},
|
||||
wrongWordDict: {
|
||||
name: '错词本',
|
||||
sort: Sort.normal,
|
||||
type: DictType.wrongDict,
|
||||
originWords: [],
|
||||
articles: [],
|
||||
words: [],
|
||||
chapterWordNumber: 15,
|
||||
chapterWords: [],
|
||||
chapterIndex: 0,
|
||||
chapterWordIndex: 0,
|
||||
statistics: [],
|
||||
url: '',
|
||||
},
|
||||
// dict: {
|
||||
// name: '新概念英语-2',
|
||||
// sort: Sort.normal,
|
||||
// type: DictType.innerDict,
|
||||
// originWords: [],
|
||||
// articles: [],
|
||||
// words: [],
|
||||
// chapterWordNumber: 15,
|
||||
// chapterWords: [],
|
||||
// chapterIndex: 0,
|
||||
// chapterWordIndex: 0,
|
||||
// statistics: [],
|
||||
// url: '/dicts/NCE_2.json',
|
||||
// },
|
||||
dict: {
|
||||
name: '新概念英语-2',
|
||||
sort: Sort.normal,
|
||||
type: DictType.publicArticle,
|
||||
originWords: [],
|
||||
articles: [],
|
||||
words: [],
|
||||
chapterWordNumber: 15,
|
||||
chapterWords: [],
|
||||
chapterIndex: 0,
|
||||
chapterWordIndex: 0,
|
||||
statistics: [],
|
||||
url: '/articles/NCE_2.json',
|
||||
},
|
||||
oldDicts: [],
|
||||
current: {
|
||||
dictType: DictType.publicArticle,
|
||||
words: [],
|
||||
index: -1,
|
||||
wrongWords: [],
|
||||
originWrongWords: [],
|
||||
repeatNumber: 0,
|
||||
statistics: {
|
||||
startDate: -1,
|
||||
endDate: -1,
|
||||
spend: -1,
|
||||
total: -1,
|
||||
correctRate: -1,
|
||||
wrongWordNumber: -1,
|
||||
}
|
||||
},
|
||||
sideIsOpen: false,
|
||||
isDictation: true,
|
||||
simpleWords: [
|
||||
'a', 'an', 'of', 'and',
|
||||
'i', 'my', 'you', 'your',
|
||||
'me', 'am', 'is', 'do', 'are',
|
||||
'what', 'who', 'where', 'how', 'no', 'yes',
|
||||
'not', 'did', 'were', 'can', 'could', 'it',
|
||||
'the', 'to'
|
||||
],
|
||||
theme: 'auto',
|
||||
load: false
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
skipWordNames: (state: State) => {
|
||||
return state.skipWordDict.originWords.map(v => v.name.toLowerCase())
|
||||
},
|
||||
getters: {
|
||||
skipWordNames: (state: State) => {
|
||||
return state.skipWordDict.originWords.map(v => v.name.toLowerCase())
|
||||
},
|
||||
skipWordNamesWithSimpleWords: (state: State) => {
|
||||
return state.skipWordDict.originWords.map(v => v.name.toLowerCase()).concat(state.simpleWords)
|
||||
},
|
||||
currentDict(state: State): Dict {
|
||||
switch (state.current.dictType) {
|
||||
case DictType.newDict:
|
||||
return state.newWordDict
|
||||
case DictType.skipDict:
|
||||
return state.skipWordDict
|
||||
case DictType.wrongDict:
|
||||
return state.wrongWordDict
|
||||
case DictType.publicDict:
|
||||
case DictType.publicArticle:
|
||||
case DictType.customDict:
|
||||
return state.dict
|
||||
}
|
||||
},
|
||||
wordIndex(state: State): number {
|
||||
return this.currentDict.wordIndex
|
||||
},
|
||||
chapter(state: State): Word[] {
|
||||
return this.currentDict.chapterWords[this.currentDict.chapterIndex] ?? []
|
||||
},
|
||||
word(state: State): Word {
|
||||
return state.current.words[state.current.index] ?? {
|
||||
trans: [],
|
||||
name: '',
|
||||
usphone: '',
|
||||
ukphone: '',
|
||||
}
|
||||
},
|
||||
dictTitle(state: State) {
|
||||
let title = this.currentDict.name
|
||||
if ([DictType.publicDict, DictType.customDict].includes(this.current.dictType)) {
|
||||
title += ` 第${this.currentDict.chapterIndex + 1}章`
|
||||
}
|
||||
return title
|
||||
skipWordNamesWithSimpleWords: (state: State) => {
|
||||
return state.skipWordDict.originWords.map(v => v.name.toLowerCase()).concat(state.simpleWords)
|
||||
},
|
||||
isArticle(state: State): boolean {
|
||||
return [DictType.publicArticle, DictType.customArticle].includes(state.current.dictType)
|
||||
},
|
||||
currentDict(state: State): Dict {
|
||||
switch (state.current.dictType) {
|
||||
case DictType.newDict:
|
||||
return state.newWordDict
|
||||
case DictType.skipDict:
|
||||
return state.skipWordDict
|
||||
case DictType.wrongDict:
|
||||
return state.wrongWordDict
|
||||
case DictType.publicDict:
|
||||
case DictType.publicArticle:
|
||||
case DictType.customDict:
|
||||
return state.dict
|
||||
}
|
||||
},
|
||||
wordIndex(state: State): number {
|
||||
return this.currentDict.wordIndex
|
||||
},
|
||||
chapter(state: State): Word[] {
|
||||
return this.currentDict.chapterWords[this.currentDict.chapterIndex] ?? []
|
||||
},
|
||||
word(state: State): Word {
|
||||
return state.current.words[state.current.index] ?? {
|
||||
trans: [],
|
||||
name: '',
|
||||
usphone: '',
|
||||
ukphone: '',
|
||||
}
|
||||
},
|
||||
dictTitle(state: State) {
|
||||
let title = this.currentDict.name
|
||||
if ([DictType.publicDict, DictType.customDict].includes(this.current.dictType)) {
|
||||
title += ` 第${this.currentDict.chapterIndex + 1}章`
|
||||
}
|
||||
return title
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
setState(obj: any) {
|
||||
for (const [key, value] of Object.entries(obj)) {
|
||||
this[key] = value
|
||||
}
|
||||
// console.log('this/', this)
|
||||
},
|
||||
setCurrentWord(words: Word[], restart: boolean = false, index: number = 0) {
|
||||
this.current.words = cloneDeep(words)
|
||||
if (restart) {
|
||||
this.current.repeatNumber = 0
|
||||
this.current.originWrongWords = []
|
||||
this.current.statistics = {
|
||||
startDate: Date.now(),
|
||||
endDate: -1,
|
||||
spend: -1,
|
||||
wordNumber: words.length,
|
||||
correctRate: -1,
|
||||
wrongWordNumber: -1,
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
setState(obj: any) {
|
||||
for (const [key, value] of Object.entries(obj)) {
|
||||
this[key] = value
|
||||
}
|
||||
// console.log('this/', this)
|
||||
},
|
||||
setCurrentWord(words: Word[], restart: boolean = false, index: number = 0) {
|
||||
this.current.words = cloneDeep(words)
|
||||
if (restart) {
|
||||
this.current.repeatNumber = 0
|
||||
this.current.originWrongWords = []
|
||||
this.current.statistics = {
|
||||
startDate: Date.now(),
|
||||
endDate: -1,
|
||||
spend: -1,
|
||||
wordNumber: words.length,
|
||||
correctRate: -1,
|
||||
wrongWordNumber: -1,
|
||||
}
|
||||
} else {
|
||||
this.current.repeatNumber++
|
||||
if (!this.current.originWrongWords.length) {
|
||||
this.current.originWrongWords = cloneDeep(this.current.wrongWords)
|
||||
}
|
||||
this.current.statistics.correctRate = -1
|
||||
this.current.statistics.wrongWordNumber = -1
|
||||
}
|
||||
this.current.index = index
|
||||
this.current.wrongWords = []
|
||||
},
|
||||
async init() {
|
||||
// let configStr = localStorage.getItem(SaveKey)
|
||||
// if (configStr) {
|
||||
// let obj: Config = JSON.parse(configStr)
|
||||
// this.setState(obj)
|
||||
// }
|
||||
if (this.current.dictType === DictType.publicDict) {
|
||||
let r = await fetch(`/public/${this.dict.url}`)
|
||||
r.json().then(v => {
|
||||
this.dict.originWords = cloneDeep(v)
|
||||
this.dict.words = cloneDeep(v)
|
||||
this.dict.chapterWords = chunk(this.dict.words, this.dict.chapterWordNumber)
|
||||
this.setCurrentWord(this.chapter, true)
|
||||
this.load = true
|
||||
})
|
||||
}
|
||||
if (this.current.dictType === DictType.publicArticle) {
|
||||
let r = await fetch(`/public/${this.dict.url}`)
|
||||
r.json().then(v => {
|
||||
this.dict.originWords = cloneDeep(v)
|
||||
this.dict.words = cloneDeep(v)
|
||||
this.dict.chapterWords = chunk(this.dict.words, this.dict.chapterWordNumber)
|
||||
this.setCurrentWord(this.chapter, true)
|
||||
this.load = true
|
||||
})
|
||||
}
|
||||
},
|
||||
saveStatistics(statistics: Statistics) {
|
||||
if (statistics.spend > 1000 * 10) {
|
||||
this.currentDict.statistics.push(statistics)
|
||||
}
|
||||
},
|
||||
async changeDict(dict: Dict, chapterIndex: number = dict.chapterIndex, chapterWordIndex: number = dict.chapterWordNumber) {
|
||||
this.saveStatistics()
|
||||
console.log('changeDict', cloneDeep(dict), chapterIndex, chapterWordIndex)
|
||||
this.current.dictType = dict.type
|
||||
if ([DictType.newDict,
|
||||
DictType.skipDict,
|
||||
DictType.wrongDict].includes(dict.type)) {
|
||||
this[dict.type].chapterIndex = chapterIndex
|
||||
this[dict.type].chapterWordIndex = chapterWordIndex
|
||||
} else {
|
||||
this.dict = cloneDeep(dict)
|
||||
if (dict.originWords.length) {
|
||||
let r = await fetch(`/public/${this.dict.url}`)
|
||||
let v = await r.json()
|
||||
this.dict.originWords = cloneDeep(v)
|
||||
this.dict.words = cloneDeep(v)
|
||||
this.dict.chapters = chunk(this.dict.words, this.dict.chapterWordNumber)
|
||||
}
|
||||
this.dict.chapterIndex = chapterIndex
|
||||
this.dict.chapterWordIndex = chapterWordIndex
|
||||
}
|
||||
this.setCurrentWord(this.chapter, true, chapterWordIndex)
|
||||
emitter.emit(EventKey.resetWord)
|
||||
} else {
|
||||
this.current.repeatNumber++
|
||||
if (!this.current.originWrongWords.length) {
|
||||
this.current.originWrongWords = cloneDeep(this.current.wrongWords)
|
||||
}
|
||||
this.current.statistics.correctRate = -1
|
||||
this.current.statistics.wrongWordNumber = -1
|
||||
}
|
||||
this.current.index = index
|
||||
this.current.wrongWords = []
|
||||
},
|
||||
async init() {
|
||||
// let configStr = localStorage.getItem(SaveKey)
|
||||
// if (configStr) {
|
||||
// let obj: Config = JSON.parse(configStr)
|
||||
// this.setState(obj)
|
||||
// }
|
||||
if (this.current.dictType === DictType.publicDict) {
|
||||
let r = await fetch(`/public/${this.dict.url}`)
|
||||
r.json().then(v => {
|
||||
this.dict.originWords = cloneDeep(v)
|
||||
this.dict.words = cloneDeep(v)
|
||||
this.dict.chapterWords = chunk(this.dict.words, this.dict.chapterWordNumber)
|
||||
this.setCurrentWord(this.chapter, true)
|
||||
this.load = true
|
||||
})
|
||||
}
|
||||
if (this.current.dictType === DictType.publicArticle) {
|
||||
let r = await fetch(`/public/${this.dict.url}`)
|
||||
r.json().then(v => {
|
||||
this.dict.articles = cloneDeep(v)
|
||||
this.load = true
|
||||
})
|
||||
}
|
||||
},
|
||||
saveStatistics(statistics: Statistics) {
|
||||
if (statistics.spend > 1000 * 10) {
|
||||
this.currentDict.statistics.push(statistics)
|
||||
}
|
||||
},
|
||||
async changeDict(dict: Dict, chapterIndex: number = dict.chapterIndex, chapterWordIndex: number = dict.chapterWordNumber) {
|
||||
this.saveStatistics()
|
||||
console.log('changeDict', cloneDeep(dict), chapterIndex, chapterWordIndex)
|
||||
this.current.dictType = dict.type
|
||||
if ([DictType.newDict,
|
||||
DictType.skipDict,
|
||||
DictType.wrongDict].includes(dict.type)) {
|
||||
this[dict.type].chapterIndex = chapterIndex
|
||||
this[dict.type].chapterWordIndex = chapterWordIndex
|
||||
} else {
|
||||
this.dict = cloneDeep(dict)
|
||||
if (dict.originWords.length) {
|
||||
let r = await fetch(`/public/${this.dict.url}`)
|
||||
let v = await r.json()
|
||||
this.dict.originWords = cloneDeep(v)
|
||||
this.dict.words = cloneDeep(v)
|
||||
this.dict.chapters = chunk(this.dict.words, this.dict.chapterWordNumber)
|
||||
}
|
||||
this.dict.chapterIndex = chapterIndex
|
||||
this.dict.chapterWordIndex = chapterWordIndex
|
||||
}
|
||||
this.setCurrentWord(this.chapter, true, chapterWordIndex)
|
||||
emitter.emit(EventKey.resetWord)
|
||||
}
|
||||
},
|
||||
})
|
||||
13
src/stores/runtime.ts
Normal file
13
src/stores/runtime.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import {defineStore} from "pinia"
|
||||
|
||||
export interface RuntimeState {
|
||||
disableEventListener: boolean
|
||||
}
|
||||
|
||||
export const useRuntimeStore = defineStore('runtime', {
|
||||
state: (): RuntimeState => {
|
||||
return {
|
||||
disableEventListener: false
|
||||
}
|
||||
},
|
||||
})
|
||||
278
src/types.ts
278
src/types.ts
@@ -1,15 +1,15 @@
|
||||
export type Word = {
|
||||
"name": string,
|
||||
"usphone": string,
|
||||
"ukphone": string,
|
||||
"trans": string[]
|
||||
"name": string,
|
||||
"usphone": string,
|
||||
"ukphone": string,
|
||||
"trans": string[]
|
||||
}
|
||||
|
||||
export const DefaultWord: Word = {
|
||||
name: '',
|
||||
usphone: '',
|
||||
ukphone: '',
|
||||
trans: []
|
||||
name: '',
|
||||
usphone: '',
|
||||
ukphone: '',
|
||||
trans: []
|
||||
}
|
||||
|
||||
export const SaveKey = 'type-word-config'
|
||||
@@ -23,183 +23,201 @@ export type LanguageCategoryType = 'en' | 'ja' | 'de' | 'code'
|
||||
|
||||
|
||||
export type DictionaryResource = {
|
||||
id: string
|
||||
name: string
|
||||
description: string
|
||||
category: string
|
||||
tags: string[]
|
||||
url: string
|
||||
length: number
|
||||
language: LanguageType
|
||||
languageCategory: LanguageCategoryType
|
||||
//override default pronunciation when not undefined
|
||||
defaultPronIndex?: number
|
||||
id: string
|
||||
name: string
|
||||
description: string
|
||||
category: string
|
||||
tags: string[]
|
||||
url: string
|
||||
length: number
|
||||
language: LanguageType
|
||||
languageCategory: LanguageCategoryType
|
||||
//override default pronunciation when not undefined
|
||||
defaultPronIndex?: number
|
||||
}
|
||||
|
||||
export type Dictionary = {
|
||||
id: string
|
||||
name: string
|
||||
description: string
|
||||
category: string
|
||||
tags: string[]
|
||||
url: string
|
||||
length: number
|
||||
language: LanguageType
|
||||
languageCategory: LanguageCategoryType
|
||||
// calculated in the store
|
||||
chapterCount: number
|
||||
//override default pronunciation when not undefined
|
||||
defaultPronIndex?: number
|
||||
id: string
|
||||
name: string
|
||||
description: string
|
||||
category: string
|
||||
tags: string[]
|
||||
url: string
|
||||
length: number
|
||||
language: LanguageType
|
||||
languageCategory: LanguageCategoryType
|
||||
// calculated in the store
|
||||
chapterCount: number
|
||||
//override default pronunciation when not undefined
|
||||
defaultPronIndex?: number
|
||||
}
|
||||
|
||||
export type PronunciationConfig = {
|
||||
name: string
|
||||
pron: PronunciationType
|
||||
name: string
|
||||
pron: PronunciationType
|
||||
}
|
||||
|
||||
export type LanguagePronunciationMapConfig = {
|
||||
defaultPronIndex: number
|
||||
pronunciation: PronunciationConfig[]
|
||||
defaultPronIndex: number
|
||||
pronunciation: PronunciationConfig[]
|
||||
}
|
||||
|
||||
export type LanguagePronunciationMap = {
|
||||
[key in LanguageType]: LanguagePronunciationMapConfig
|
||||
[key in LanguageType]: LanguagePronunciationMapConfig
|
||||
}
|
||||
|
||||
export type SoundResource = {
|
||||
key: string
|
||||
name: string
|
||||
filename: string
|
||||
key: string
|
||||
name: string
|
||||
filename: string
|
||||
}
|
||||
|
||||
export interface DictJson {
|
||||
description: string,
|
||||
category: string,
|
||||
tags: string[],
|
||||
url: string,
|
||||
length: number,
|
||||
language: string,
|
||||
languageCategory: string,
|
||||
description: string,
|
||||
category: string,
|
||||
tags: string[],
|
||||
url: string,
|
||||
length: number,
|
||||
language: string,
|
||||
languageCategory: string,
|
||||
}
|
||||
|
||||
export enum DictType {
|
||||
newDict = 'newDict',
|
||||
skipDict = 'skipDict',
|
||||
wrongDict = 'wrongDict',
|
||||
publicDict = 'publicDict',
|
||||
customDict = 'customDict',
|
||||
publicArticle = 'publicArticle',
|
||||
customArticle = 'customArticle'
|
||||
newDict = 'newDict',
|
||||
skipDict = 'skipDict',
|
||||
wrongDict = 'wrongDict',
|
||||
publicDict = 'publicDict',
|
||||
customDict = 'customDict',
|
||||
publicArticle = 'publicArticle',
|
||||
customArticle = 'customArticle'
|
||||
}
|
||||
|
||||
export const DefaultArticleWord: ArticleWord = {
|
||||
name: '',
|
||||
usphone: '',
|
||||
ukphone: '',
|
||||
trans: [],
|
||||
nextSpace: true,
|
||||
isSymbol: false,
|
||||
symbolPosition: ''
|
||||
name: '',
|
||||
usphone: '',
|
||||
ukphone: '',
|
||||
trans: [],
|
||||
nextSpace: true,
|
||||
isSymbol: false,
|
||||
symbolPosition: ''
|
||||
}
|
||||
|
||||
export interface ArticleWord extends Word {
|
||||
nextSpace: boolean,
|
||||
isSymbol: boolean,
|
||||
symbolPosition: 'start' | 'end' | '',
|
||||
nextSpace: boolean,
|
||||
isSymbol: boolean,
|
||||
symbolPosition: 'start' | 'end' | '',
|
||||
}
|
||||
|
||||
export interface Sentence {
|
||||
text: string,
|
||||
translate: string,
|
||||
words: ArticleWord[]
|
||||
text: string,
|
||||
translate: string,
|
||||
words: ArticleWord[]
|
||||
}
|
||||
|
||||
export enum TranslateType {
|
||||
custom = 0,
|
||||
network = 1
|
||||
}
|
||||
|
||||
export interface Article {
|
||||
title: string,
|
||||
titleTranslate: string,
|
||||
article: string,
|
||||
customTranslate: string,
|
||||
networkTranslate: string,
|
||||
isTranslated: boolean,
|
||||
newWords: Word[],
|
||||
articleAllWords: string[],
|
||||
sections: Sentence[][],
|
||||
translateType: number
|
||||
title: string,
|
||||
titleTranslate: string,
|
||||
article: string,
|
||||
customTranslate: string,
|
||||
networkTranslate: string,
|
||||
isTranslated: boolean,
|
||||
newWords: Word[],
|
||||
articleAllWords: string[],
|
||||
sections: Sentence[][],
|
||||
translateType: TranslateType
|
||||
}
|
||||
|
||||
export const DefaultArticle: Article = {
|
||||
title: '',
|
||||
titleTranslate: '',
|
||||
article: '',
|
||||
customTranslate: '',
|
||||
networkTranslate: '',
|
||||
isTranslated: false,
|
||||
newWords: [],
|
||||
articleAllWords: [],
|
||||
sections: [],
|
||||
translateType: TranslateType.network
|
||||
}
|
||||
|
||||
export interface Dict {
|
||||
name: string,
|
||||
sort: Sort,
|
||||
type: DictType,
|
||||
originWords: Word[],//原始单词
|
||||
words: Word[],
|
||||
chapterWordNumber: number,//章节单词数量
|
||||
chapterWords: Word[][],
|
||||
articles: Article[],
|
||||
chapterIndex: number,
|
||||
chapterWordIndex: number,
|
||||
statistics: Statistics[],
|
||||
url: string,
|
||||
name: string,
|
||||
sort: Sort,
|
||||
type: DictType,
|
||||
originWords: Word[],//原始单词
|
||||
words: Word[],
|
||||
chapterWordNumber: number,//章节单词数量
|
||||
chapterWords: Word[][],
|
||||
articles: Article[],
|
||||
chapterIndex: number,
|
||||
chapterWordIndex: number,
|
||||
statistics: Statistics[],
|
||||
url: string,
|
||||
}
|
||||
|
||||
export interface Statistics {
|
||||
startDate: number,//开始日期
|
||||
endDate: number//结束日期
|
||||
spend: number,//花费时间
|
||||
total: number//单词数量
|
||||
wrongWordNumber: number//错误数
|
||||
correctRate: number//正确率
|
||||
startDate: number,//开始日期
|
||||
endDate: number//结束日期
|
||||
spend: number,//花费时间
|
||||
total: number//单词数量
|
||||
wrongWordNumber: number//错误数
|
||||
correctRate: number//正确率
|
||||
}
|
||||
|
||||
export interface DisplayStatistics extends Statistics {
|
||||
wrongWords: Word[]
|
||||
wrongWords: Word[]
|
||||
}
|
||||
|
||||
export const DefaultDisplayStatistics: DisplayStatistics = {
|
||||
startDate: Date.now(),
|
||||
endDate: -1,
|
||||
spend: -1,
|
||||
total: -1,
|
||||
correctRate: -1,
|
||||
wrongWordNumber: -1,
|
||||
wrongWords: [],
|
||||
startDate: Date.now(),
|
||||
endDate: -1,
|
||||
spend: -1,
|
||||
total: -1,
|
||||
correctRate: -1,
|
||||
wrongWordNumber: -1,
|
||||
wrongWords: [],
|
||||
}
|
||||
|
||||
export enum Sort {
|
||||
normal = 0,
|
||||
random = 1,
|
||||
reverse = 2
|
||||
normal = 0,
|
||||
random = 1,
|
||||
reverse = 2
|
||||
}
|
||||
|
||||
export interface State {
|
||||
newWordDict: Dict,
|
||||
skipWordDict: Dict,
|
||||
wrongWordDict: Dict,
|
||||
dict: Dict,
|
||||
oldDicts: Dict[],
|
||||
current: {
|
||||
dictType: DictType,
|
||||
words: Word[],
|
||||
index: number,
|
||||
wrongWords: Word[],
|
||||
originWrongWords: Word[],
|
||||
repeatNumber: number,
|
||||
statistics: Statistics
|
||||
},
|
||||
simpleWords: string[],
|
||||
sideIsOpen: boolean,
|
||||
isDictation: boolean,
|
||||
theme: string,
|
||||
load: boolean
|
||||
newWordDict: Dict,
|
||||
skipWordDict: Dict,
|
||||
wrongWordDict: Dict,
|
||||
dict: Dict,
|
||||
oldDicts: Dict[],
|
||||
current: {
|
||||
dictType: DictType,
|
||||
words: Word[],
|
||||
index: number,
|
||||
wrongWords: Word[],
|
||||
originWrongWords: Word[],
|
||||
repeatNumber: number,
|
||||
statistics: Statistics
|
||||
},
|
||||
simpleWords: string[],
|
||||
sideIsOpen: boolean,
|
||||
isDictation: boolean,
|
||||
theme: string,
|
||||
load: boolean
|
||||
}
|
||||
|
||||
export const ShortKeyMap = {
|
||||
Show: 'Escape',
|
||||
Ignore: 'Tab',
|
||||
Remove: '`',
|
||||
Collect: 'Enter',
|
||||
Show: 'Escape',
|
||||
Ignore: 'Tab',
|
||||
Remove: '`',
|
||||
Collect: 'Enter',
|
||||
}
|
||||
|
||||
export enum TranslateEngine {
|
||||
Baidu = 0,
|
||||
Baidu = 0,
|
||||
}
|
||||
@@ -6,4 +6,6 @@ export const EventKey = {
|
||||
openSide: 'openSide',
|
||||
openStatModal: 'openStatModal',
|
||||
closeOther: 'closeOther',
|
||||
keydown: 'keydown',
|
||||
keyup: 'keyup',
|
||||
}
|
||||
Reference in New Issue
Block a user