From eac0d60628f2dc03377bed2f13e95c50c6c3a5e3 Mon Sep 17 00:00:00 2001 From: zyronon Date: Fri, 15 Dec 2023 02:32:00 +0800 Subject: [PATCH] save --- src/components/dialog/DictDiglog.vue | 3 +- src/components/list/WordList.vue | 2 +- .../mobile/practice/practice-word/Typing.vue | 357 ++++++++++++++++++ .../practice/practice-word/TypingWord.vue | 62 +-- src/pages/pc/dict/components/EditDict.vue | 1 + .../pc/dict/components/WordDictDetail.vue | 1 - .../pc/practice/practice-article/index.vue | 2 +- .../pc/practice/practice-word/Typing.vue | 24 +- .../pc/practice/practice-word/TypingWord.vue | 1 + src/stores/base.ts | 13 +- src/stores/setting.ts | 178 ++++----- src/types.ts | 7 +- 12 files changed, 510 insertions(+), 141 deletions(-) create mode 100644 src/pages/mobile/practice/practice-word/Typing.vue diff --git a/src/components/dialog/DictDiglog.vue b/src/components/dialog/DictDiglog.vue index cd11c249..ccaba5fd 100644 --- a/src/components/dialog/DictDiglog.vue +++ b/src/components/dialog/DictDiglog.vue @@ -82,8 +82,7 @@ async function selectDict(val: { dict: DictResource | Dict, index: number }) { } if (runtimeStore.editDict.type === DictType.article) { if (!runtimeStore.editDict.articles.length) { - let r = await fetch(url) - let v = await r.json() + let v = await getDictFile(url) v.map(s => { s.id = nanoid(6) }) diff --git a/src/components/list/WordList.vue b/src/components/list/WordList.vue index b86a7b14..4be1fd51 100644 --- a/src/components/list/WordList.vue +++ b/src/components/list/WordList.vue @@ -50,7 +50,7 @@ defineExpose({scrollToBottom, scrollToItem})
{{ item.word }} {{ item.phonetic0 }} - +
{{ (v.pos ? v.pos + '.' : '') + v.cn }}
diff --git a/src/pages/mobile/practice/practice-word/Typing.vue b/src/pages/mobile/practice/practice-word/Typing.vue new file mode 100644 index 00000000..4560000f --- /dev/null +++ b/src/pages/mobile/practice/practice-word/Typing.vue @@ -0,0 +1,357 @@ + + + + + \ No newline at end of file diff --git a/src/pages/mobile/practice/practice-word/TypingWord.vue b/src/pages/mobile/practice/practice-word/TypingWord.vue index 5cb5efe0..8cd52e99 100644 --- a/src/pages/mobile/practice/practice-word/TypingWord.vue +++ b/src/pages/mobile/practice/practice-word/TypingWord.vue @@ -8,7 +8,7 @@ import {cloneDeep, reverse, shuffle} from "lodash-es" import {usePracticeStore} from "@/stores/practice.ts" import {useSettingStore} from "@/stores/setting.ts"; import {useOnKeyboardEventListener, useWindowClick} from "@/hooks/event.ts"; -import Typing from "@/pages/pc/practice/practice-word/Typing.vue"; +import Typing from "@/pages/mobile/practice/practice-word/Typing.vue"; import {useRuntimeStore} from "@/stores/runtime.ts"; import {useWordOptions} from "@/hooks/dict.ts"; import BaseIcon from "@/components/BaseIcon.vue"; @@ -21,6 +21,8 @@ import SlideItem from "@/components/slide/SlideItem.vue"; import MobilePanel from "@/pages/mobile/components/MobilePanel.vue"; import router from "@/router.ts"; import {Icon} from "@iconify/vue"; +import IconWrapper from "@/components/IconWrapper.vue"; +import useTheme from "@/hooks/theme.ts"; interface IProps { words: Word[], @@ -42,6 +44,7 @@ const store = useBaseStore() const runtimeStore = useRuntimeStore() const practiceStore = usePracticeStore() const settingStore = useSettingStore() +const {toggleTheme} = useTheme() const { isWordCollect, @@ -80,23 +83,15 @@ watch(data, () => { practiceStore.index = data.index }) -const word = $computed(() => { +const word: Word = $computed(() => { return data.words[data.index] ?? { trans: [], - name: '', - usphone: '', - ukphone: '', + word: '', + phonetic0: '', + phonetic1: '', } }) -const prevWord: Word = $computed(() => { - return data.words?.[data.index - 1] ?? undefined -}) - -const nextWord: Word = $computed(() => { - return data.words?.[data.index + 1] ?? undefined -}) - function next(isTyping: boolean = true) { if (data.index === data.words.length - 1) { @@ -251,14 +246,19 @@ function change(e) { inputRef.value = '' } -function know(isTyping: boolean = false) { - inputRef.blur() +function nextWord() { settingStore.translate = false + settingStore.detail = false setTimeout(() => { - next(isTyping) + next(true) }, 300) } +function complete() { + inputRef.blur() + settingStore.detail = true +} + function unknow() { settingStore.translate = true inputRef.focus() @@ -283,6 +283,12 @@ onMounted(() => { />
+ + + + + { @input="change" type="text">
- 不认识 - 认识 + 下一个 +
@@ -419,10 +427,9 @@ onMounted(() => { height: 100%; display: flex; flex-direction: column; - justify-content: center; + justify-content: space-between; align-items: center; - gap: 10rem; - padding: 10rem; + padding: 0 10rem; box-sizing: border-box; .tool-bar { @@ -437,7 +444,7 @@ onMounted(() => { :deep(.word) { letter-spacing: 0; - font-size: 40rem !important; + font-size: 36rem !important; } .options { @@ -450,12 +457,11 @@ onMounted(() => { .wrapper { width: 80%; display: flex; - flex-direction: column; - gap: 10rem; + gap: 20rem; } - .base-button { - width: 100%; + :deep(.base-button) { + flex: 1; } } } diff --git a/src/pages/pc/dict/components/EditDict.vue b/src/pages/pc/dict/components/EditDict.vue index b03edafb..176acfc4 100644 --- a/src/pages/pc/dict/components/EditDict.vue +++ b/src/pages/pc/dict/components/EditDict.vue @@ -62,6 +62,7 @@ async function onSubmit() { if (props.isAdd) { data.id = 'custom-dict-' + Date.now() + //TODO 允许同名? if (store.myDictList.find(v => v.name === data.name)) { return ElMessage.warning('已有相同名称词典!') } else { diff --git a/src/pages/pc/dict/components/WordDictDetail.vue b/src/pages/pc/dict/components/WordDictDetail.vue index 5dd38f4f..e9c87b6d 100644 --- a/src/pages/pc/dict/components/WordDictDetail.vue +++ b/src/pages/pc/dict/components/WordDictDetail.vue @@ -283,7 +283,6 @@ function syncEditDict2MyDictList() { let wordFormData = $ref({ where: '', type: '', - name: '', id: '', index: 0 }) diff --git a/src/pages/pc/practice/practice-article/index.vue b/src/pages/pc/practice/practice-article/index.vue index 08d8346c..9a7dc54b 100644 --- a/src/pages/pc/practice/practice-article/index.vue +++ b/src/pages/pc/practice/practice-article/index.vue @@ -82,7 +82,7 @@ function setArticle(val: Article) { articleData.article.sections.map((v, i) => { v.map((w, j) => { w.words.map(s => { - if (!store.skipWordNamesWithSimpleWords.includes(s.name.toLowerCase()) && !s.isSymbol) { + if (!store.skipWordNamesWithSimpleWords.includes(s.word.toLowerCase()) && !s.isSymbol) { practiceStore.total++ } }) diff --git a/src/pages/pc/practice/practice-word/Typing.vue b/src/pages/pc/practice/practice-word/Typing.vue index 493a8191..3ee48d84 100644 --- a/src/pages/pc/practice/practice-word/Typing.vue +++ b/src/pages/pc/practice/practice-word/Typing.vue @@ -163,17 +163,17 @@ defineExpose({del, showWord, hideWord, play}) >
{{ (v.pos ? v.pos + '.' : '') + v.cn }} - - - - - - - - - - - + + + + + + + + + + +
@@ -215,6 +215,7 @@ defineExpose({del, showWord, hideWord, play}) justify-content: center; word-break: break-word; position: relative; + color: var(--color-font-2); .phonetic, .translate { font-size: 20rem; @@ -230,7 +231,6 @@ defineExpose({del, showWord, hideWord, play}) position: absolute; transform: translateY(-50%); margin-bottom: 90rem; - color: var(--color-font-2); &:hover { .volumeIcon { diff --git a/src/pages/pc/practice/practice-word/TypingWord.vue b/src/pages/pc/practice/practice-word/TypingWord.vue index 04f04ac0..6f517107 100644 --- a/src/pages/pc/practice/practice-word/TypingWord.vue +++ b/src/pages/pc/practice/practice-word/TypingWord.vue @@ -389,6 +389,7 @@ onUnmounted(() => { position: absolute; top: 0; width: 100%; + z-index: 1; & > div { width: 45%; diff --git a/src/stores/base.ts b/src/stores/base.ts index 40672d2f..23911b4e 100644 --- a/src/stores/base.ts +++ b/src/stores/base.ts @@ -6,7 +6,7 @@ import {useRuntimeStore} from "@/stores/runtime.ts"; import * as localforage from "localforage"; import {nanoid} from "nanoid"; import {SAVE_DICT_KEY, SAVE_SETTING_KEY} from "@/utils/const.ts"; -import {checkAndUpgradeSaveDict} from "@/utils"; +import {checkAndUpgradeSaveDict, getDictFile} from "@/utils"; export interface BaseState { myDictList: Dict[], @@ -120,10 +120,10 @@ export const useBaseStore = defineStore('base', { return this.myDictList[2] }, skipWordNames() { - return this.simple.originWords.map(v => v.name.toLowerCase()) + return this.simple.originWords.map(v => v.word.toLowerCase()) }, skipWordNamesWithSimpleWords() { - return this.simple.originWords.map(v => v.name.toLowerCase()).concat(this.simpleWords) + return this.simple.originWords.map(v => v.word.toLowerCase()).concat(this.simpleWords) }, isArticle(state: BaseState): boolean { //如果是收藏时,特殊判断 @@ -215,8 +215,8 @@ export const useBaseStore = defineStore('base', { let dictResourceUrl = `./dicts/${this.currentDict.language}/${this.currentDict.type}/${this.currentDict.translateLanguage}/${this.currentDict.url}`; if ([DictType.word].includes(this.currentDict.type)) { if (!this.currentDict.originWords.length) { - let r = await fetch(dictResourceUrl) - let v = await r.json() + let v = await getDictFile(dictResourceUrl) + v = v.slice(0,50) v.map(s => { s.id = nanoid(6) }) @@ -228,8 +228,7 @@ export const useBaseStore = defineStore('base', { if ([DictType.article].includes(this.currentDict.type)) { if (!this.currentDict.articles.length) { - let r = await fetch(dictResourceUrl) - let s: any[] = await r.json() + let s = await getDictFile(dictResourceUrl) this.currentDict.articles = cloneDeep(s.map(v => { v.id = nanoid(6) return v diff --git a/src/stores/setting.ts b/src/stores/setting.ts index 8996242f..e2b9d775 100644 --- a/src/stores/setting.ts +++ b/src/stores/setting.ts @@ -5,104 +5,106 @@ import {SAVE_SETTING_KEY} from "@/utils/const.ts"; import {checkAndUpgradeSaveDict, checkAndUpgradeSaveSetting} from "@/utils"; export interface SettingState { - showToolbar: boolean, - show: boolean, + showToolbar: boolean, + show: boolean, - allSound: boolean, - wordSound: boolean, - wordSoundVolume: number, - wordSoundSpeed: number, - wordSoundType: string, - keyboardSound: boolean, - keyboardSoundVolume: number, - keyboardSoundFile: string, - translateSound: boolean, - translateSoundVolume: number, - effectSound: boolean, - effectSoundVolume: number, - repeatCount: number, - repeatCustomCount?: number, - dictation: boolean, - translate: boolean, - showNearWord: boolean - ignoreCase: boolean - allowWordTip: boolean - waitTimeForChangeWord: number - fontSize: { - articleForeignFontSize: number, - articleTranslateFontSize: number, - wordForeignFontSize: number, - wordTranslateFontSize: number, - }, - showPanel: boolean, - theme: string, - collapse: boolean, - chapterWordNumber: number, - shortcutKeyMap: Record, - first: boolean - load: boolean + allSound: boolean, + wordSound: boolean, + wordSoundVolume: number, + wordSoundSpeed: number, + wordSoundType: string, + keyboardSound: boolean, + keyboardSoundVolume: number, + keyboardSoundFile: string, + translateSound: boolean, + translateSoundVolume: number, + effectSound: boolean, + effectSoundVolume: number, + repeatCount: number, + repeatCustomCount?: number, + dictation: boolean, + translate: boolean, + detail: boolean, + showNearWord: boolean + ignoreCase: boolean + allowWordTip: boolean + waitTimeForChangeWord: number + fontSize: { + articleForeignFontSize: number, + articleTranslateFontSize: number, + wordForeignFontSize: number, + wordTranslateFontSize: number, + }, + showPanel: boolean, + theme: string, + collapse: boolean, + chapterWordNumber: number, + shortcutKeyMap: Record, + first: boolean + load: boolean } export const DefaultSettingState = (): SettingState => ({ - showToolbar: true, - show: false, - showPanel: true, + showToolbar: true, + show: false, + showPanel: true, - allSound: true, - wordSound: true, - wordSoundVolume: 100, - wordSoundSpeed: 1, - wordSoundType: 'us', - keyboardSound: true, - keyboardSoundVolume: 100, - keyboardSoundFile: '机械键盘2', - translateSound: true, - translateSoundVolume: 100, - effectSound: true, - effectSoundVolume: 100, - repeatCount: 1, - repeatCustomCount: null, - dictation: false, - translate: true, + allSound: true, + wordSound: true, + wordSoundVolume: 100, + wordSoundSpeed: 1, + wordSoundType: 'us', + keyboardSound: true, + keyboardSoundVolume: 100, + keyboardSoundFile: '机械键盘2', + translateSound: true, + translateSoundVolume: 100, + effectSound: true, + effectSoundVolume: 100, + repeatCount: 1, + repeatCustomCount: null, + dictation: false, + translate: true, + detail: false, - showNearWord: true, - ignoreCase: true, - allowWordTip: true, - fontSize: { - articleForeignFontSize: 48, - articleTranslateFontSize: 20, - wordForeignFontSize: 48, - wordTranslateFontSize: 20, - }, - waitTimeForChangeWord: 300, + showNearWord: true, + ignoreCase: true, + allowWordTip: true, + fontSize: { + articleForeignFontSize: 48, + articleTranslateFontSize: 20, + wordForeignFontSize: 48, + wordTranslateFontSize: 20, + }, + waitTimeForChangeWord: 300, - theme: 'auto', - collapse: false, - chapterWordNumber: DefaultChapterWordNumber, - shortcutKeyMap: cloneDeep(DefaultShortcutKeyMap), - first: true, - load: false + theme: 'auto', + collapse: false, + chapterWordNumber: DefaultChapterWordNumber, + shortcutKeyMap: cloneDeep(DefaultShortcutKeyMap), + first: true, + load: false }) export const DefaultChapterWordNumber = 30 export const useSettingStore = defineStore('setting', { - state: (): SettingState => { - return DefaultSettingState() + state: (): SettingState => { + return DefaultSettingState() + }, + actions: { + setState(obj: any) { + //这样不会丢失watch的值的引用 + merge(this, obj) }, - actions: { - setState(obj: any) { - //这样不会丢失watch的值的引用 - merge(this, obj) - }, - init() { - return new Promise(resolve => { - let configStr = localStorage.getItem(SAVE_SETTING_KEY.key) - if (!configStr) configStr = localStorage.getItem(SAVE_SETTING_KEY.oldKey) - let data = checkAndUpgradeSaveSetting(configStr) - this.setState(data) - localStorage.setItem(SAVE_SETTING_KEY.key, JSON.stringify({val: this.$state, version: SAVE_SETTING_KEY.version})) - this.load = true - resolve(true) - }) - } + init() { + return new Promise(resolve => { + let configStr = localStorage.getItem(SAVE_SETTING_KEY.key) + if (!configStr) configStr = localStorage.getItem(SAVE_SETTING_KEY.oldKey) + let data = checkAndUpgradeSaveSetting(configStr) + this.setState(data) + localStorage.setItem(SAVE_SETTING_KEY.key, JSON.stringify({val: this.$state, version: SAVE_SETTING_KEY.version})) + this.load = true + resolve(true) + }) } + } }) \ No newline at end of file diff --git a/src/types.ts b/src/types.ts index 38ca9e69..0f4fdc13 100644 --- a/src/types.ts +++ b/src/types.ts @@ -10,12 +10,17 @@ export type WordTrans = { en: string } export type Word = { + id?: any, "word": string, "phonetic0": string, "phonetic1": string, "trans": WordTrans[] checked?: boolean, - id?: any, + sentences?: { v: string, tran: string }[], + relWords?: { w: string, tran: string }[], + phrases?: { v: string, tran: string } [], + synos?: { w: string, tran: string } [], + memory?: any, } export const DefaultWord: Word = {