From 5bfabd24f761f3fd8cd5c746b84e73e833cab6d9 Mon Sep 17 00:00:00 2001 From: zyronon Date: Sun, 31 Aug 2025 01:24:47 +0800 Subject: [PATCH] fix:optimize the input method for article practice --- components.d.ts | 8 - src/assets/css/anim.scss | 22 + src/pages/pc/article/StudyArticle.vue | 16 +- src/pages/pc/article/components/Space.vue | 101 ++++ .../pc/article/components/TypingArticle.vue | 221 +++----- .../pc/article/components/TypingWord.vue | 109 ++++ src/pages/pc/word/StudyWord2.vue | 499 ------------------ src/types/func.ts | 1 + src/types/types.ts | 1 + 9 files changed, 323 insertions(+), 655 deletions(-) create mode 100644 src/pages/pc/article/components/Space.vue create mode 100644 src/pages/pc/article/components/TypingWord.vue delete mode 100644 src/pages/pc/word/StudyWord2.vue diff --git a/components.d.ts b/components.d.ts index 4d91b3bb..13c15e6f 100644 --- a/components.d.ts +++ b/components.d.ts @@ -13,7 +13,6 @@ declare module 'vue' { Close: typeof import('./src/components/icon/Close.vue')['default'] DeleteIcon: typeof import('./src/components/icon/DeleteIcon.vue')['default'] Empty: typeof import('./src/components/Empty.vue')['default'] - IconArcticonsXiaohongshuRednote: typeof import('~icons/arcticons/xiaohongshu-rednote')['default'] IconBxVolume: typeof import('~icons/bx/volume')['default'] IconBxVolumeFull: typeof import('~icons/bx/volume-full')['default'] IconBxVolumeLow: typeof import('~icons/bx/volume-low')['default'] @@ -30,7 +29,6 @@ declare module 'vue' { IconFluentArrowMove20Regular: typeof import('~icons/fluent/arrow-move20-regular')['default'] IconFluentArrowRight16Regular: typeof import('~icons/fluent/arrow-right16-regular')['default'] IconFluentArrowSort20Regular: typeof import('~icons/fluent/arrow-sort20-regular')['default'] - IconFluentArrowSync16Regular: typeof import('~icons/fluent/arrow-sync16-regular')['default'] IconFluentBookLetter20Regular: typeof import('~icons/fluent/book-letter20-regular')['default'] IconFluentCheckmark20Regular: typeof import('~icons/fluent/checkmark20-regular')['default'] IconFluentCheckmarkCircle16Filled: typeof import('~icons/fluent/checkmark-circle16-filled')['default'] @@ -56,7 +54,6 @@ declare module 'vue' { IconFluentPlay20Regular: typeof import('~icons/fluent/play20-regular')['default'] IconFluentQuestionCircle20Regular: typeof import('~icons/fluent/question-circle20-regular')['default'] IconFluentReplay20Regular: typeof import('~icons/fluent/replay20-regular')['default'] - IconFluentScanType20Regular: typeof import('~icons/fluent/scan-type20-regular')['default'] IconFluentSearch20Regular: typeof import('~icons/fluent/search20-regular')['default'] IconFluentSearch24Regular: typeof import('~icons/fluent/search24-regular')['default'] IconFluentSettings20Regular: typeof import('~icons/fluent/settings20-regular')['default'] @@ -68,22 +65,17 @@ declare module 'vue' { IconFluentStar20Filled: typeof import('~icons/fluent/star20-filled')['default'] IconFluentStarAdd16Regular: typeof import('~icons/fluent/star-add16-regular')['default'] IconFluentTextEditStyle20Regular: typeof import('~icons/fluent/text-edit-style20-regular')['default'] - IconFluentTextField20Regular: typeof import('~icons/fluent/text-field20-regular')['default'] IconFluentTextListAbcUppercaseLtr20Regular: typeof import('~icons/fluent/text-list-abc-uppercase-ltr20-regular')['default'] IconFluentTextUnderlineDouble20Regular: typeof import('~icons/fluent/text-underline-double20-regular')['default'] - IconFluentTextWholeWord20Regular: typeof import('~icons/fluent/text-whole-word20-regular')['default'] IconFluentTranslate16Regular: typeof import('~icons/fluent/translate16-regular')['default'] IconFluentTranslateOff16Regular: typeof import('~icons/fluent/translate-off16-regular')['default'] IconFluentWeatherMoon16Regular: typeof import('~icons/fluent/weather-moon16-regular')['default'] IconFluentWeatherSunny16Regular: typeof import('~icons/fluent/weather-sunny16-regular')['default'] - IconIconXiaoHongShu: typeof import('~icons/ic/on-xiao-hong-shu')['default'] IconMaterialSymbolsMail: typeof import('~icons/material-symbols/mail')['default'] - IconMdiGithub: typeof import('~icons/mdi/github')['default'] IconRiTwitterFill: typeof import('~icons/ri/twitter-fill')['default'] IconSimpleIconsGithub: typeof import('~icons/simple-icons/github')['default'] IconSimpleIconsWechat: typeof import('~icons/simple-icons/wechat')['default'] IconSimpleIconsXiaohongshu: typeof import('~icons/simple-icons/xiaohongshu')['default'] - IconStreamlineUltimateColorWechatLogo: typeof import('~icons/streamline-ultimate-color/wechat-logo')['default'] RouterLink: typeof import('vue-router')['RouterLink'] RouterView: typeof import('vue-router')['RouterView'] SlideHorizontal: typeof import('./src/components/slide/SlideHorizontal.vue')['default'] diff --git a/src/assets/css/anim.scss b/src/assets/css/anim.scss index 3ea687d9..3ef6c727 100644 --- a/src/assets/css/anim.scss +++ b/src/assets/css/anim.scss @@ -49,6 +49,28 @@ transform: translate3d(4px, 0, 0); } } +@keyframes shakeBottom { + 10%, + 90% { + transform: translate3d(-1px, 0.3rem, 0); + } + + 20%, + 80% { + transform: translate3d(2px, 0.3rem, 0); + } + + 30%, + 50%, + 70% { + transform: translate3d(-4px, 0.3rem, 0); + } + + 40%, + 60% { + transform: translate3d(4px, 0.3rem, 0); + } +} .go-enter-from { transform: translate3d(100%, 0, 0); diff --git a/src/pages/pc/article/StudyArticle.vue b/src/pages/pc/article/StudyArticle.vue index 1b1282a0..cd2ac8c8 100644 --- a/src/pages/pc/article/StudyArticle.vue +++ b/src/pages/pc/article/StudyArticle.vue @@ -40,6 +40,7 @@ let articleData = $ref({ let showEditArticle = $ref(false) let typingArticleRef = $ref() let loading = $ref(false) +let allWrongWords = new Set() let editArticle = $ref
(getDefaultArticle()) function write() { @@ -128,7 +129,6 @@ onMounted(() => { } }) - useStartKeyboardEventListener() useDisableEventListener(() => loading) @@ -138,6 +138,7 @@ function setArticle(val: Article) { statisticsStore.total = 0 statisticsStore.startDate = Date.now() + allWrongWords = new Set() articleData.list[store.sbook.lastLearnIndex] = val articleData.article = val articleData.sectionIndex = 0 @@ -186,12 +187,15 @@ function edit(val: Article = articleData.article) { } function wrong(word: Word) { - let lowerName = word.word.toLowerCase(); - if (!store.wrong.words.find((v: Word) => v.word.toLowerCase() === lowerName)) { - store.wrong.words.push(word) + let temp = word.word.toLowerCase(); + if (!allWrongWords.has(word.word.toLowerCase())) { + allWrongWords.add(word.word.toLowerCase()) + statisticsStore.wrong++ } - if (!store.allIgnoreWords.includes(lowerName)) { - //todo + + if (!store.wrong.words.find((v: Word) => v.word.toLowerCase() === temp)) { + store.wrong.words.push(word) + store.wrong.length = store.wrong.words.length } } diff --git a/src/pages/pc/article/components/Space.vue b/src/pages/pc/article/components/Space.vue new file mode 100644 index 00000000..ee7acfc3 --- /dev/null +++ b/src/pages/pc/article/components/Space.vue @@ -0,0 +1,101 @@ + + + + + diff --git a/src/pages/pc/article/components/TypingArticle.vue b/src/pages/pc/article/components/TypingArticle.vue index 8a5b265c..929ba5b8 100644 --- a/src/pages/pc/article/components/TypingArticle.vue +++ b/src/pages/pc/article/components/TypingArticle.vue @@ -1,8 +1,7 @@ @@ -426,36 +434,22 @@ let showQuestions = $ref(false) (sectionIndex>=indexI &&sentenceIndex>=indexJ && wordIndex>=indexW && stringIndex>=word.word.length) ?'wrote': ''), - (`${indexI}${indexJ}${indexW}` === currentIndex && !isSpace && wrong )?'word-wrong':'', indexW === 0 && `word${indexI}-${indexJ}` ]"> - - {{ input }} - - {{ wrong }} - {{ indexWord(word) }} - {{ remainderWord(word) }} - + + + - - {{ word.word }} - - - - - + @@ -516,9 +510,11 @@ let showQuestions = $ref(false) .wrote { color: grey; - //color: rgb(22, 163, 74); } +$translate-lh: 3.2; +$article-lh: 2.4; + .typing-article { height: 100%; overflow: auto; @@ -548,28 +544,22 @@ let showQuestions = $ref(false) .article-content { position: relative; - //opacity: 0; } article { - line-height: 1.3; word-break: keep-all; word-wrap: break-word; white-space: pre-wrap; font-family: var(--en-article-family); &.dictation { - .dictation-hide { - opacity: 0; - } - .border-bottom { display: inline-block !important; } } .wrote, .hover-show { - .dictation-hide { + :deep(.hide) { opacity: 1 !important; } @@ -579,16 +569,21 @@ let showQuestions = $ref(false) } .hover-show { + border-radius: 0.2rem; background: var(--color-select-bg); color: white !important; + :deep(.hide) { + opacity: 1 !important; + } + .wrote { color: white !important; } } &.tall { - line-height: 2.4; + line-height: $article-lh; } .section { @@ -596,7 +591,6 @@ let showQuestions = $ref(false) .sentence { transition: all .3s; - } .word { @@ -604,17 +598,17 @@ let showQuestions = $ref(false) .word-wrap { position: relative; + } - .border-bottom { - position: absolute; - width: 100%; - height: 100%; - left: 0; - top: 0; - border-bottom: 2px solid var(--color-article); - display: none; - transform: translateY(-0.2rem); - } + .border-bottom { + position: absolute; + width: 100%; + height: 100%; + left: 0; + top: 0; + border-bottom: 2px solid var(--color-article); + display: none; + transform: translateY(-0.2rem); } } } @@ -628,7 +622,7 @@ let showQuestions = $ref(false) height: 100%; width: 100%; font-size: 1.2rem; - line-height: 3.2; + line-height: $translate-lh; letter-spacing: .2rem; font-family: var(--zh-article-family); font-weight: bold; @@ -646,63 +640,6 @@ let showQuestions = $ref(false) } } } - - .word-space { - position: relative; - display: inline-block; - width: 0.8rem; - height: 1.5rem; - margin: 0 1px; - box-sizing: border-box; - - &.to-bottom { - transform: translateY(0.3rem); - } - - &.wait { - border-bottom: 2px solid var(--color-article); - - &::after { - content: ' '; - position: absolute; - width: 2px; - height: .25rem; - background: var(--color-article); - bottom: 0; - right: 0; - } - - &::before { - content: ' '; - position: absolute; - width: 2px; - height: .26rem; - background: var(--color-article); - bottom: 0; - left: 0; - } - } - } - - .word-start { - color: var(--color-select-bg); - } - - .wrong { - color: rgba(red, 0.6); - } - - .word-wrong { - display: inline-block; - animation: shake 0.82s cubic-bezier(0.36, 0.07, 0.19, 0.97) both; - } - - .bg-wrong { - display: inline-block; - line-height: 1; - background: rgba(red, 0.6); - animation: shake 0.82s cubic-bezier(0.36, 0.07, 0.19, 0.97) both; - } } .cursor { diff --git a/src/pages/pc/article/components/TypingWord.vue b/src/pages/pc/article/components/TypingWord.vue new file mode 100644 index 00000000..ab8a62c9 --- /dev/null +++ b/src/pages/pc/article/components/TypingWord.vue @@ -0,0 +1,109 @@ + + + + diff --git a/src/pages/pc/word/StudyWord2.vue b/src/pages/pc/word/StudyWord2.vue deleted file mode 100644 index 84703a86..00000000 --- a/src/pages/pc/word/StudyWord2.vue +++ /dev/null @@ -1,499 +0,0 @@ - - - - - diff --git a/src/types/func.ts b/src/types/func.ts index 4ba3cd3d..f6943391 100644 --- a/src/types/func.ts +++ b/src/types/func.ts @@ -26,6 +26,7 @@ export function getDefaultArticleWord(val: Partial = {}): ArticleWo nextSpace: true, isSymbol: false, symbolPosition: '', + input: '', ...val }) as ArticleWord } diff --git a/src/types/types.ts b/src/types/types.ts index f5eed54a..0f095978 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -55,6 +55,7 @@ export interface ArticleWord extends Word { nextSpace: boolean, isSymbol: boolean, symbolPosition: 'start' | 'end' | '', + input:string } export interface Sentence {