diff --git a/.github/workflows/readme.yml b/.github/workflows/readme.yml new file mode 100644 index 00000000..6e26df43 --- /dev/null +++ b/.github/workflows/readme.yml @@ -0,0 +1,20 @@ +name: Translate README + +on: + # 这个选项可以使你手动在 Action tab 页面触发工作流 + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Setup Node.js + uses: actions/setup-node@v1 + with: + node-version: 12.x + # ISO Langusge Codes: https://cloud.google.com/translate/docs/languages + - name: Adding README - English + uses: dephraiim/translate-readme@main + with: + LANG: en diff --git a/Note.md b/Note.md index aa1756fb..170f2d41 100644 --- a/Note.md +++ b/Note.md @@ -55,3 +55,8 @@ http://enpuz.com/ 语法分析工具 footer 的输入数统计有问题,当在列表点一个,然后输入错误之后,不会统计到输入数里面(单词和文章的都有问题) +nce1-16.A polite request.解析出来有问题 + +I found this note on my car: 'Sir, we welcome you to our city. This is a 'No Parking' area. You will enjoy your stay here if you pay attention to our street signs. This note is only a reminder.' If you receive a request like this, you cannot fail to obey it! + +'No Parking' 会被截断 diff --git a/README.md b/README.md index 57411227..abd39835 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,13 @@

- 一个可以在网页上背单词、背文章的网站 + English | 简体中文

+

+ 学习英语,一次敲击,一点进步;记忆不再盲目,学习更高效,开源单词与文章练习工具 +

+

License @@ -17,8 +21,8 @@ TypeWords | Trendshift -![image](/docs/word.png) -![image](/docs/article.png) +![image](/public/word.png) +![image](/public/article.png) ## 在线访问 @@ -28,33 +32,36 @@ ## 功能列表 ### 背单词 + 根据记忆曲线自动计算学习单词,并通过默写加深记忆;提供了音标、发音(美音、英音)、例句、短语、近义词、同根词、词源、错误统计等功能 ### 背文章 + 内置经典教材书籍,练习和背诵文章,逐句输入,自动发音。可以自行添加、导入文章,提供一键翻译、译文对照功能 ### 收藏、错词本、已掌握 + 学习单词时输入错误会自动添加到错词本,方便后续复习。也可以添加到已掌握,以后再遇到这个词会自动跳过,同时也可以将其添加到收藏中,以便巩固复习 ### 词库 -内置了常用的 CET-4 、CET-6 、GMAT 、GRE 、IELTS 、SAT 、TOEFL 、考研英语、专业四级英语、专业八级英语等词库。 尽可能满足大部分用户对背单词的需求,也非常欢迎社区贡献更多的词库。 +内置了常用的 CET-4 、CET-6 、GMAT 、GRE 、IELTS 、SAT 、TOEFL 、考研英语、专业四级英语、专业八级英语等词库。 +尽可能满足大部分用户对背单词的需求,也非常欢迎社区贡献更多的词库。 -## 运行项目 +## 运行 本项目是基于`Vue`开发的,需要 node 环境来运行。 -### 手动安装 - 1. 安装 NodeJS,参考[官方文档](https://nodejs.org/en/download) -2. 本项目只能使用 `git clone` 命令下载项目到本地,直接下载 Github 提供 Download ZIP 功能是无法运行的 +2. 项目文件很大,推荐使用 `git clone --depth 1 https://github.com/zyronon/TypeWords.git` 命令只克隆最近一次提交。直接下载 + Github 提供的 Download ZIP 功能是无法运行的 3. 打开命令行,在项目根目录下,运行`npm install`来下载依赖。 4. 执行`npm start`来启动项目,项目默认地址为[`http://localhost:3000`](http://localhost:3000) 5. 在浏览器中打开[`http://localhost:3000`](http://localhost:3000) 来访问项目。 ## 功能与建议 -目前项目处于开发初期,新功能正在持续添加中,如果你对软件有任何功能与建议,欢迎在 Issues 中提出 -如果你也喜欢本软件的设计思想,欢迎提交 pr,非常感谢你对我们的支持! +目前项目处于开发初期,新功能正在持续添加中,如果你对软件有任何功能与建议,欢迎在 `Issues` 中提出 +如果你也喜欢本软件的设计思想,欢迎提交 `pr`,非常感谢你对我们的支持! diff --git a/TODO.md b/TODO.md deleted file mode 100644 index 99eef008..00000000 --- a/TODO.md +++ /dev/null @@ -1,5 +0,0 @@ - nce1-16.A polite request.解析出来有问题 - -I found this note on my car: 'Sir, we welcome you to our city. This is a 'No Parking' area. You will enjoy your stay here if you pay attention to our street signs. This note is only a reminder.' If you receive a request like this, you cannot fail to obey it! - -'No Parking' 会被截断 \ No newline at end of file diff --git a/components.d.ts b/components.d.ts index b30c8bf6..13c15e6f 100644 --- a/components.d.ts +++ b/components.d.ts @@ -13,69 +13,69 @@ 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'] - IconBasilAddOutline: typeof import('~icons/basil/add-outline')['default'] - IconBasilEditOutline: typeof import('~icons/basil/edit-outline')['default'] - IconBiArrowLeft: typeof import('~icons/bi/arrow-left')['default'] - IconBiArrowRight: typeof import('~icons/bi/arrow-right')['default'] - IconBiKeyboard: typeof import('~icons/bi/keyboard')['default'] - IconBxHeadphone: typeof import('~icons/bx/headphone')['default'] IconBxVolume: typeof import('~icons/bx/volume')['default'] IconBxVolumeFull: typeof import('~icons/bx/volume-full')['default'] IconBxVolumeLow: typeof import('~icons/bx/volume-low')['default'] - IconCarbonCloseOutline: typeof import('~icons/carbon/close-outline')['default'] - IconCarbonMove: typeof import('~icons/carbon/move')['default'] IconEosIconsLoading: typeof import('~icons/eos-icons/loading')['default'] - IconEpMoon: typeof import('~icons/ep/moon')['default'] + IconFluentAdd16Filled: typeof import('~icons/fluent/add16-filled')['default'] + IconFluentAdd16Regular: typeof import('~icons/fluent/add16-regular')['default'] IconFluentAdd20Filled: typeof import('~icons/fluent/add20-filled')['default'] - IconFluentDelete24Regular: typeof import('~icons/fluent/delete24-regular')['default'] - IconFluentReplay16Filled: typeof import('~icons/fluent/replay16-filled')['default'] + IconFluentAdd20Regular: typeof import('~icons/fluent/add20-regular')['default'] + IconFluentAddSquare20Regular: typeof import('~icons/fluent/add-square20-regular')['default'] + IconFluentAppsList24Regular: typeof import('~icons/fluent/apps-list24-regular')['default'] + IconFluentArrowBounce20Regular: typeof import('~icons/fluent/arrow-bounce20-regular')['default'] + IconFluentArrowCircleRight16Regular: typeof import('~icons/fluent/arrow-circle-right16-regular')['default'] + IconFluentArrowLeft16Regular: typeof import('~icons/fluent/arrow-left16-regular')['default'] + 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'] + 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'] + IconFluentCheckmarkCircle16Regular: typeof import('~icons/fluent/checkmark-circle16-regular')['default'] + IconFluentCheckmarkCircle20Filled: typeof import('~icons/fluent/checkmark-circle20-filled')['default'] + IconFluentChevronLeft20Filled: typeof import('~icons/fluent/chevron-left20-filled')['default'] + IconFluentChevronLeft28Filled: typeof import('~icons/fluent/chevron-left28-filled')['default'] + IconFluentDatabasePerson20Regular: typeof import('~icons/fluent/database-person20-regular')['default'] + IconFluentDelete20Regular: typeof import('~icons/fluent/delete20-regular')['default'] + IconFluentDismiss20Regular: typeof import('~icons/fluent/dismiss20-regular')['default'] + IconFluentDismissCircle16Regular: typeof import('~icons/fluent/dismiss-circle16-regular')['default'] + IconFluentDismissCircle20Filled: typeof import('~icons/fluent/dismiss-circle20-filled')['default'] + IconFluentErrorCircle20Filled: typeof import('~icons/fluent/error-circle20-filled')['default'] + IconFluentEye16Regular: typeof import('~icons/fluent/eye16-regular')['default'] + IconFluentEyeOff16Regular: typeof import('~icons/fluent/eye-off16-regular')['default'] + IconFluentHeadphones20Regular: typeof import('~icons/fluent/headphones20-regular')['default'] + IconFluentHome20Regular: typeof import('~icons/fluent/home20-regular')['default'] + IconFluentKeyboardLayoutFloat20Regular: typeof import('~icons/fluent/keyboard-layout-float20-regular')['default'] + IconFluentMailEdit20Regular: typeof import('~icons/fluent/mail-edit20-regular')['default'] + IconFluentMyLocation20Regular: typeof import('~icons/fluent/my-location20-regular')['default'] + IconFluentPaddingLeft20Regular: typeof import('~icons/fluent/padding-left20-regular')['default'] + IconFluentPerson20Regular: typeof import('~icons/fluent/person20-regular')['default'] + 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'] + IconFluentSearch20Regular: typeof import('~icons/fluent/search20-regular')['default'] IconFluentSearch24Regular: typeof import('~icons/fluent/search24-regular')['default'] - IconFormkitLeft: typeof import('~icons/formkit/left')['default'] - IconFormkitRight: typeof import('~icons/formkit/right')['default'] - IconGgArrowsExchange: typeof import('~icons/gg/arrows-exchange')['default'] - IconHugeiconsPlay: typeof import('~icons/hugeicons/play')['default'] - IconIconamoonClose: typeof import('~icons/iconamoon/close')['default'] - IconIconParkOutlineDown: typeof import('~icons/icon-park-outline/down')['default'] - IconIconParkOutlineGoAhead: typeof import('~icons/icon-park-outline/go-ahead')['default'] - IconIconParkOutlineSettingConfig: typeof import('~icons/icon-park-outline/setting-config')['default'] - IconIconParkOutlineSortTwo: typeof import('~icons/icon-park-outline/sort-two')['default'] - IconIcons8RightRound: typeof import('~icons/icons8/right-round')['default'] - IconIcSharpMyLocation: typeof import('~icons/ic/sharp-my-location')['default'] - IconIonCloseOutline: typeof import('~icons/ion/close-outline')['default'] - IconMajesticonsEyeOffLine: typeof import('~icons/majesticons/eye-off-line')['default'] - IconMaterialSymbolsCheckCircleOutlineRounded: typeof import('~icons/material-symbols/check-circle-outline-rounded')['default'] - IconMaterialSymbolsCheckCircleRounded: typeof import('~icons/material-symbols/check-circle-rounded')['default'] - IconMaterialSymbolsKeyboardOutline: typeof import('~icons/material-symbols/keyboard-outline')['default'] - IconMaterialSymbolsLightDictionaryOutlineSharp: typeof import('~icons/material-symbols-light/dictionary-outline-sharp')['default'] - IconMdiAboutCircleOutline: typeof import('~icons/mdi/about-circle-outline')['default'] - IconMdiAlertCircle: typeof import('~icons/mdi/alert-circle')['default'] - IconMdiCheckCircle: typeof import('~icons/mdi/check-circle')['default'] - IconMdiChevronDown: typeof import('~icons/mdi/chevron-down')['default'] - IconMdiClose: typeof import('~icons/mdi/close')['default'] - IconMdiCloseCircle: typeof import('~icons/mdi/close-circle')['default'] - IconMdiDatabaseCogOutline: typeof import('~icons/mdi/database-cog-outline')['default'] - IconMdiEyeOutline: typeof import('~icons/mdi/eye-outline')['default'] - IconMdiInformation: typeof import('~icons/mdi/information')['default'] - IconMdiStar: typeof import('~icons/mdi/star')['default'] - IconMdiStarOutline: typeof import('~icons/mdi/star-outline')['default'] - IconMdiSuccessCircleOutline: typeof import('~icons/mdi/success-circle-outline')['default'] - IconMdiTranslate: typeof import('~icons/mdi/translate')['default'] - IconMdiTranslateOff: typeof import('~icons/mdi/translate-off')['default'] - IconMingcuteLeftLine: typeof import('~icons/mingcute/left-line')['default'] - IconMingcuteRightLine: typeof import('~icons/mingcute/right-line')['default'] - IconMingcuteServiceFill: typeof import('~icons/mingcute/service-fill')['default'] - IconPhArticleNyTimes: typeof import('~icons/ph/article-ny-times')['default'] - IconPhStar: typeof import('~icons/ph/star')['default'] - IconPhStarFill: typeof import('~icons/ph/star-fill')['default'] - IconRiQuestionLine: typeof import('~icons/ri/question-line')['default'] - IconSolarTrashBinMinimalisticLinear: typeof import('~icons/solar/trash-bin-minimalistic-linear')['default'] - IconTablerCheck: typeof import('~icons/tabler/check')['default'] - IconTablerEdit: typeof import('~icons/tabler/edit')['default'] - IconTablerSun: typeof import('~icons/tabler/sun')['default'] - IconTdesignMenuUnfold: typeof import('~icons/tdesign/menu-unfold')['default'] - IconTwemojiEndArrow: typeof import('~icons/twemoji/end-arrow')['default'] - IconTypcnWarningOutline: typeof import('~icons/typcn/warning-outline')['default'] - IconUilSetting: typeof import('~icons/uil/setting')['default'] + IconFluentSettings20Regular: typeof import('~icons/fluent/settings20-regular')['default'] + IconFluentShieldQuestion20Regular: typeof import('~icons/fluent/shield-question20-regular')['default'] + IconFluentSpeakerEdit20Regular: typeof import('~icons/fluent/speaker-edit20-regular')['default'] + IconFluentStar12Regular: typeof import('~icons/fluent/star12-regular')['default'] + IconFluentStar16Filled: typeof import('~icons/fluent/star16-filled')['default'] + IconFluentStar16Regular: typeof import('~icons/fluent/star16-regular')['default'] + 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'] + IconFluentTextListAbcUppercaseLtr20Regular: typeof import('~icons/fluent/text-list-abc-uppercase-ltr20-regular')['default'] + IconFluentTextUnderlineDouble20Regular: typeof import('~icons/fluent/text-underline-double20-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'] + IconMaterialSymbolsMail: typeof import('~icons/material-symbols/mail')['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'] RouterLink: typeof import('vue-router')['RouterLink'] RouterView: typeof import('vue-router')['RouterView'] SlideHorizontal: typeof import('./src/components/slide/SlideHorizontal.vue')['default'] diff --git a/docs/README.en.md b/docs/README.en.md new file mode 100644 index 00000000..ed33e1fc --- /dev/null +++ b/docs/README.en.md @@ -0,0 +1,78 @@ +

+ Type Words +

+ +

+ English | 简体中文 +

+ +
+Practice English, one strike, one step forward +
+
+ A website where one can memorize words and articles on web pages +
+ +

+ License + + + Featured|HelloGitHub +

+ +
+TypeWords | Trendshift +
+ +![image](/public/word.png) +![image](/public/article.png) + +## Online visit + +China: +other: or + +## Feature list + +### Memorize words + +Automatically calculate the learning words based on the memory curve, and deepen memory through dictation; it provides +functions such as phonetic symbols, pronunciation (American, English), examples, phrases, synonyms, same root words, +etymology, error statistics, etc. + +### Memorize the article + +Built-in classic textbooks, practice and recite articles, enter sentence by sentence, and automatically pronounce it. +You can add and import articles by yourself, providing one-click translation and translation comparison functions + +### Favorite, wrong word book, mastered + +Incorrect input when learning words will be automatically added to the wrong word book for easier subsequent review. It +can also be added to mastered, and will automatically skip this word when you encounter it later. It can also be added +to your favorites to consolidate the review. + +### Thesaurus + +It has built-in commonly used CET-4, CET-6, GMAT, GRE, IELTS, SAT, TOEFL, postgraduate entrance examination English, +professional level 4 English, professional level 8 English and other thesis. +It meets the needs of most users for memorizing words as much as possible, and it is also very welcome to contribute +more vocabulary to the community. + +## run + +This project is based on`Vue`Developed, the node environment needs to be run. + +1. Install NodeJS, refer to [Official Documentation](https://nodejs.org/en/download) +2. The project file is large, recommended`git clone --depth 1 https://github.com/zyronon/TypeWords.git` The command + clons only the last commit. Download directly + The Download ZIP function provided by Github cannot run +3. Open the command line, run it in the project root directory`npm install`Come download the dependency. +4. implement`npm start`To start the project, the default address of the project is[ + `http://localhost:3000`](http://localhost:3000) +5. Open in a browser[`http://localhost:3000`](http://localhost:3000)Come to visit the project. + +## Features and suggestions + +The project is currently in the early stage of development and new functions are being added. If you have any functions +and suggestions for the software, please feel free to`Issues`Proposed in +If you also like the design ideas of this software, please submit it`pr`Thank you very much for your support! diff --git a/docs/article.png b/docs/article.png deleted file mode 100644 index bef2b2ca..00000000 Binary files a/docs/article.png and /dev/null differ diff --git a/docs/word.png b/docs/word.png deleted file mode 100644 index f6b0fb66..00000000 Binary files a/docs/word.png and /dev/null differ diff --git a/index.html b/index.html index 23804cd9..059eabdf 100644 --- a/index.html +++ b/index.html @@ -4,7 +4,7 @@ - Type Words - 英语打字练习平台 | 单词跟打 · 文章跟打 + Type Words - 词文记 | 单词跟打 · 文章跟打 @@ -27,6 +27,9 @@ content="Type Words:在线英语练习平台,支持单词跟打、文章练习,提升打字速度与英语水平。"> + + + diff --git a/src/components/icon/VolumeIcon.vue b/src/components/icon/VolumeIcon.vue index 114a4d01..83bbfdec 100644 --- a/src/components/icon/VolumeIcon.vue +++ b/src/components/icon/VolumeIcon.vue @@ -43,7 +43,6 @@ function click() { play() } -let iconList = ['bx:volume', 'bx:volume-low', 'bx:volume-full'] defineExpose({play}) diff --git a/src/config/ENV.ts b/src/config/ENV.ts index e40c01b6..0335c573 100644 --- a/src/config/ENV.ts +++ b/src/config/ENV.ts @@ -1,4 +1,5 @@ export const GITHUB = 'https://github.com/zyronon/TypeWords' +export const ProjectName = 'Type Words' const common = { word_dict_list_version: 1 diff --git a/src/directives/loading.tsx b/src/directives/loading.tsx index a373b1a5..f26bb434 100644 --- a/src/directives/loading.tsx +++ b/src/directives/loading.tsx @@ -30,6 +30,7 @@ const LoadingComponent = { // 自定义指令 export default { mounted(el, binding) { + console.log('el',) const position = getComputedStyle(el).position if (position === 'static' || !position) { el.style.position = 'relative' // 保证 loading 居中 diff --git a/src/hooks/article.ts b/src/hooks/article.ts index 23a3f752..5e0d4a9f 100644 --- a/src/hooks/article.ts +++ b/src/hooks/article.ts @@ -4,6 +4,7 @@ import nlp from "compromise/one"; import {usePlayWordAudio} from "@/hooks/sound.ts"; import {getSentenceAllText, getSentenceAllTranslateText} from "@/hooks/translate.ts"; import {getDefaultArticleWord} from "@/types/func.ts"; +import {useSettingStore} from "@/stores/setting.ts"; interface KeyboardMap { Period: string, @@ -534,6 +535,7 @@ export function getTranslateText(article: Article) { export function usePlaySentenceAudio() { const playWordAudio = usePlayWordAudio() + const settingStore = useSettingStore() let timer = $ref(0) function playSentenceAudio(sentence: Sentence, ref?: HTMLAudioElement, article?: Article) { @@ -543,6 +545,7 @@ export function usePlaySentenceAudio() { ref.pause() } let start = sentence.audioPosition[0]; + ref.volume = settingStore.wordSoundVolume / 100 ref.currentTime = start ref.play() let end = sentence.audioPosition?.[1] diff --git a/src/hooks/dict.ts b/src/hooks/dict.ts index 2a5b71dc..b390db37 100644 --- a/src/hooks/dict.ts +++ b/src/hooks/dict.ts @@ -120,6 +120,7 @@ export function getCurrentStudyWord() { } end++ } + } else { //从start往后取perDay个单词,作为当前练习单词 for (let item of list) { @@ -130,6 +131,7 @@ export function getCurrentStudyWord() { } end++ } + //从start往前取perDay个单词,作为当前复习单词,取到0为止 list = dict.words.slice(0, start).toReversed() for (let item of list) { @@ -142,6 +144,12 @@ export function getCurrentStudyWord() { } } + //如果是自由模式,那么统统设置到new字段里面去 + if (settingStore.wordPracticeMode === 1) { + data.new = data.new.length ? data.new : data.review + data.review = [] + return data + } // 上上次更早的单词 //默认只取start之前的单词 diff --git a/src/hooks/event.ts b/src/hooks/event.ts index 4fbe8351..75d27fd3 100644 --- a/src/hooks/event.ts +++ b/src/hooks/event.ts @@ -53,7 +53,6 @@ export function useStartKeyboardEventListener() { useEventListener('keydown', (e: KeyboardEvent) => { if (!runtimeStore.disableEventListener) { - e.preventDefault() let shortcutKey = getShortcutKey(e) // console.log('shortcutKey', shortcutKey) @@ -68,10 +67,11 @@ export function useStartKeyboardEventListener() { } } if (shortcutEvent) { + e.preventDefault() emitter.emit(shortcutEvent, e) } else { //非英文模式下,输入区域的 keyCode 均为 229时, - if ((e.keyCode >= 65 && e.keyCode <= 90) + if (((e.keyCode >= 65 && e.keyCode <= 90) || (e.keyCode >= 48 && e.keyCode <= 57) || e.code === 'Space' || e.code === 'Slash' @@ -85,7 +85,9 @@ export function useStartKeyboardEventListener() { || e.code === 'Semicolon' // || e.code === 'Backquote' || e.keyCode === 229 - ) { + //当按下功能键时,不阻止事件传播 + ) && (!e.ctrlKey && !e.altKey)) { + e.preventDefault() emitter.emit(EventKey.onTyping, e) } else { emitter.emit(EventKey.keydown, e) diff --git a/src/hooks/sound.ts b/src/hooks/sound.ts index c349dbe4..f000e652 100644 --- a/src/hooks/sound.ts +++ b/src/hooks/sound.ts @@ -1,11 +1,7 @@ import {onMounted, watch, watchEffect} from "vue" import {useSettingStore} from "@/stores/setting.ts"; import {PronunciationApi} from "@/types/types.ts"; -import beep from "@/assets/sound/beep.wav"; -import correct from "@/assets/sound/correct.wav"; - import {SoundFileOptions} from "@/utils/const.ts"; -import {useBaseStore} from "@/stores/base.ts"; export function useSound(audioSrcList?: string[], audioFileLength?: number) { let audioList: HTMLAudioElement[] = $ref([]) @@ -63,7 +59,7 @@ export function usePlayKeyboardAudio() { export function usePlayBeep() { const settingStore = useSettingStore() - const {play} = useSound([beep], 1) + const {play} = useSound([`/sound/beep.wav`], 1) function playAudio() { if (settingStore.effectSound) { @@ -76,7 +72,7 @@ export function usePlayBeep() { export function usePlayCorrect() { const settingStore = useSettingStore() - const {play} = useSound([correct], 1) + const {play} = useSound([`/sound/correct.wav`], 1) function playAudio() { if (settingStore.effectSound) { @@ -135,13 +131,13 @@ export function usePlayAudio(url: string) { export function getAudioFileUrl(name: string) { if (name === '机械键盘') { return [ - `./sound/key-sounds/jixie/机械0.mp3`, - `./sound/key-sounds/jixie/机械1.mp3`, - `./sound/key-sounds/jixie/机械2.mp3`, - `./sound/key-sounds/jixie/机械3.mp3`, + `/sound/key-sounds/jixie/机械0.mp3`, + `/sound/key-sounds/jixie/机械1.mp3`, + `/sound/key-sounds/jixie/机械2.mp3`, + `/sound/key-sounds/jixie/机械3.mp3`, ] } else { - return [`./sound/key-sounds/${name}.mp3`] + return [`/sound/key-sounds/${name}.mp3`] } } diff --git a/src/libs/translate/baidu.ts b/src/libs/translate/baidu.ts index e728a1bf..95add274 100644 --- a/src/libs/translate/baidu.ts +++ b/src/libs/translate/baidu.ts @@ -48,7 +48,7 @@ export interface BaiduConfig { export class Baidu extends Translator { readonly name = "baidu"; - readonly endpoint = "https://api.fanyi.baidu.com/api/trans/vip/translate"; + readonly endpoint = "/baidu"; protected async query( text: string, diff --git a/src/pages/pc/article/ArticleHomePage.vue b/src/pages/pc/article/ArticleHomePage.vue index c0f6c247..ec4af992 100644 --- a/src/pages/pc/article/ArticleHomePage.vue +++ b/src/pages/pc/article/ArticleHomePage.vue @@ -14,6 +14,7 @@ import PopConfirm from "@/pages/pc/components/PopConfirm.vue"; import {onMounted, watch} from "vue"; import {getDefaultDict} from "@/types/func.ts"; import DeleteIcon from "@/components/icon/DeleteIcon.vue"; +import recommendBookList from "@/assets/book-list.json"; const {nav} = useNav() const base = useBaseStore() @@ -96,18 +97,16 @@ async function goBookDetail(val: DictResource) { base.currentBook.name || '请选择书籍开始学习' }} - - + + - +
- 开始学习 - + 开始学习 +
@@ -140,6 +139,22 @@ async function goBookDetail(val: DictResource) { + +
+
+
推荐
+
+
更多
+
+
+ +
+ +
+
diff --git a/src/pages/pc/article/BatchEditArticlePage.vue b/src/pages/pc/article/BatchEditArticlePage.vue index fedcd2a2..b2ac9d05 100644 --- a/src/pages/pc/article/BatchEditArticlePage.vue +++ b/src/pages/pc/article/BatchEditArticlePage.vue @@ -16,7 +16,7 @@ import Toast from '@/pages/pc/components/base/toast/Toast.ts' import {getDefaultArticle} from "@/types/func.ts"; import BackIcon from "@/pages/pc/components/BackIcon.vue"; -const emit = defineEmits<{ +defineEmits<{ importData: [val: Event] exportData: [val: string] }>() diff --git a/src/pages/pc/article/BookDetail.vue b/src/pages/pc/article/BookDetail.vue index 87e1a05d..1794d5ce 100644 --- a/src/pages/pc/article/BookDetail.vue +++ b/src/pages/pc/article/BookDetail.vue @@ -66,7 +66,7 @@ async function init() { if (runtimeStore.editDict.articles.length) { selectArticle = runtimeStore.editDict.articles[0] } - console.log('runtimeStore.editDict',runtimeStore.editDict) + console.log('runtimeStore.editDict', runtimeStore.editDict) } } } @@ -89,7 +89,7 @@ const {
- +
{{ runtimeStore.editDict.name }}
编辑 @@ -113,8 +113,8 @@ const { :class="!isArticleCollect(item)?'collect':'fill'" @click.stop="toggleArticleCollect(item)" :title="!isArticleCollect(item) ? '收藏' : '取消收藏'"> - - + + @@ -146,7 +146,7 @@ const {
- +
{{ runtimeStore.editDict.id ? '修改' : '创建' }}书籍
diff --git a/src/pages/pc/article/StudyArticle.vue b/src/pages/pc/article/StudyArticle.vue index bb47598c..64449e17 100644 --- a/src/pages/pc/article/StudyArticle.vue +++ b/src/pages/pc/article/StudyArticle.vue @@ -22,6 +22,7 @@ import Tooltip from "@/pages/pc/components/base/Tooltip.vue"; import ConflictNotice from "@/pages/pc/components/ConflictNotice.vue"; import {useRoute, useRouter} from "vue-router"; import book_list from "@/assets/book-list.json"; +import PracticeLayout from "@/pages/pc/components/PracticeLayout.vue"; const store = useBaseStore() const settingStore = useSettingStore() @@ -39,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() { @@ -127,7 +129,6 @@ onMounted(() => { } }) - useStartKeyboardEventListener() useDisableEventListener(() => loading) @@ -137,16 +138,19 @@ 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 articleData.sentenceIndex = 0 articleData.wordIndex = 0 articleData.stringIndex = 0 + let ignoreList = [store.allIgnoreWords, store.knownWords][settingStore.ignoreSimpleWord ? 0 : 1] articleData.article.sections.map((v, i) => { v.map((w, j) => { w.words.map(s => { - if (!store.allIgnoreWords.includes(s.word.toLowerCase()) && !s.isSymbol) { + s.input = '' + if (!ignoreList.includes(s.word.toLowerCase()) && !s.isSymbol) { statisticsStore.total++ } }) @@ -184,12 +188,19 @@ 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 (settingStore.ignoreSimpleWord) { + if (this.simpleWords.includes(temp)) return } - if (!store.allIgnoreWords.includes(lowerName)) { - //todo + if (!allWrongWords.has(word.word.toLowerCase())) { + allWrongWords.add(word.word.toLowerCase()) + statisticsStore.wrong++ + } + + if (!store.wrong.words.find((v: Word) => v.word.toLowerCase() === temp)) { + store.wrong.words.push(word) + store.wrong.length = store.wrong.words.length } } @@ -271,193 +282,151 @@ onUnmounted(() => { let audioRef = $ref() const {playSentenceAudio} = usePlaySentenceAudio() +function play2(e) { + if (settingStore.wordSound || e.handle) { + playSentenceAudio(e.sentence, audioRef, articleData.article) + } +} + diff --git a/src/pages/pc/article/components/EditArticle.vue b/src/pages/pc/article/components/EditArticle.vue index 3655bf7b..38402c11 100644 --- a/src/pages/pc/article/components/EditArticle.vue +++ b/src/pages/pc/article/components/EditArticle.vue @@ -16,6 +16,8 @@ import copy from "copy-to-clipboard"; import {Option, Select} from "@/pages/pc/components/base/select"; import Tooltip from "@/pages/pc/components/base/Tooltip.vue"; import InputNumber from "@/pages/pc/components/base/InputNumber.vue"; +import {nanoid} from "nanoid"; + const Dialog = defineAsyncComponent(() => import('@/pages/pc/components/dialog/Dialog.vue')) interface IProps { @@ -38,7 +40,7 @@ let progress = $ref(0) let failCount = $ref(0) let textareaRef = $ref() const TranslateEngineOptions = [ - {value: 'youdao', label: '有道'}, + // {value: 'youdao', label: '有道'}, {value: 'baidu', label: '百度'}, ] @@ -103,7 +105,7 @@ async function startNetworkTranslate() { //这里需要用异步,因为watch了article.networkTranslate,改变networkTranslate了之后,会重新设置article.sections //导致getNetworkTranslate里面拿到的article.sections是废弃的值 setTimeout(async () => { - await getNetworkTranslate(editArticle, TranslateEngine.Baidu, true, (v: number) => { + await getNetworkTranslate(editArticle, TranslateEngine.Baidu, false, (v: number) => { progress = v }) failCount = 0 @@ -143,6 +145,7 @@ function save(option: 'save' | 'saveAndNext') { } let d = cloneDeep(editArticle) + if (!d.id) d.id = nanoid(6) delete d.sections copy(console.json(d, 2)) const saveTemp = () => { @@ -294,7 +297,7 @@ function setStartTime(val: Sentence, i: number, j: number) {
- +