wip
This commit is contained in:
@@ -461,7 +461,7 @@ a {
|
||||
.book {
|
||||
@extend .anim;
|
||||
@apply p-3 rounded-md relative cursor-pointer bg-third hover:bg-card-active flex flex-col justify-between shrink-0;
|
||||
$w: 6rem;
|
||||
$w: 7rem;
|
||||
width: $w;
|
||||
height: calc($w * 1.4);
|
||||
}
|
||||
|
||||
@@ -21,13 +21,11 @@ defineEmits<{
|
||||
}>()
|
||||
|
||||
const progress = $computed(() => {
|
||||
if (props.item?.complete) return 100
|
||||
return Number(((props.item?.lastLearnIndex / props.item?.length) * 100).toFixed())
|
||||
})
|
||||
|
||||
const studyProgress = $computed(() => {
|
||||
if (!props.showProgress) return
|
||||
if (props.item.complete) return props.item?.length + '/'
|
||||
return props.item?.lastLearnIndex ? props.item?.lastLearnIndex + '/' : ''
|
||||
})
|
||||
</script>
|
||||
@@ -41,14 +39,14 @@ const studyProgress = $computed(() => {
|
||||
<div>{{ studyProgress }}{{ item?.length }}{{ quantifier }}</div>
|
||||
</div>
|
||||
<div class="absolute bottom-2 left-3 right-3">
|
||||
<Progress v-if="(item?.lastLearnIndex || item.complete) && showProgress" class="mt-1"
|
||||
<Progress v-if="(item?.lastLearnIndex) && showProgress" class="mt-1"
|
||||
:percentage="progress"
|
||||
:show-text="false"></Progress>
|
||||
</div>
|
||||
<Checkbox v-if="showCheckbox"
|
||||
:model-value="checked"
|
||||
@change="$emit('check')"
|
||||
class="absolute left-3 bottom-3"/>
|
||||
class="absolute left-3 bottom-3 z-2"/>
|
||||
<div class="custom z-1" v-if="item.custom">自定义</div>
|
||||
<div class="custom bg-red! color-white z-1" v-else-if="item.update">更新中</div>
|
||||
</div>
|
||||
|
||||
@@ -189,7 +189,7 @@ const sentence = $computed(() => {
|
||||
|
||||
<div class="bg-gray-900/30 py-4 center flex-col rounded-2xl">
|
||||
<div class="text-center mb-2 text-xl">
|
||||
我在 {{ APP_NAME }} 学习了 {{ studyStats.time }}
|
||||
我学习了{{ studyStats.time }} {{ baseStore.sdict.name }}
|
||||
</div>
|
||||
<!-- Progress Overview -->
|
||||
<div class="w-90/100 flex items-center gap-space">
|
||||
|
||||
@@ -216,7 +216,7 @@ const simpleWords = $computed({
|
||||
<div class="line"></div>
|
||||
<SettingItem mainTitle="自动切换"/>
|
||||
<SettingItem title="自动切换下一个单词"
|
||||
desc="仅在 **跟写** 时生效,听写、辨认、默写均不会自动切换,需要手动按 **空格键** 切换"
|
||||
desc="仅在 **跟写** 时生效,听写、自测、默写均不会自动切换,需要手动按 **空格键** 切换"
|
||||
>
|
||||
<Switch v-model="settingStore.autoNextWord"/>
|
||||
</SettingItem>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { loadJsLib, shakeCommonDict } from "@/utils";
|
||||
import {loadJsLib, shakeCommonDict} from "@/utils";
|
||||
import {
|
||||
APP_NAME,
|
||||
APP_VERSION,
|
||||
@@ -10,13 +10,13 @@ import {
|
||||
SAVE_DICT_KEY,
|
||||
SAVE_SETTING_KEY
|
||||
} from "@/config/env.ts";
|
||||
import { get } from "idb-keyval";
|
||||
import { saveAs } from "file-saver";
|
||||
import {get} from "idb-keyval";
|
||||
import {saveAs} from "file-saver";
|
||||
import dayjs from "dayjs";
|
||||
import Toast from "@/components/base/toast/Toast.ts";
|
||||
import { useBaseStore } from "@/stores/base.ts";
|
||||
import { useSettingStore } from "@/stores/setting.ts";
|
||||
import { ref } from "vue";
|
||||
import {useBaseStore} from "@/stores/base.ts";
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
import {ref} from "vue";
|
||||
|
||||
export function useExport() {
|
||||
const store = useBaseStore()
|
||||
@@ -24,7 +24,7 @@ export function useExport() {
|
||||
|
||||
let loading = ref(false)
|
||||
|
||||
async function exportData(notice = '导出成功!') {
|
||||
async function exportData(notice = '导出成功!', fileName = `${APP_NAME}-User-Data-${dayjs().format('YYYY-MM-DD HH-mm-ss')}.zip`) {
|
||||
if (loading.value) return
|
||||
loading.value = true
|
||||
try {
|
||||
@@ -77,7 +77,7 @@ export function useExport() {
|
||||
mp3.file(rec.id + ".mp3", rec.file);
|
||||
}
|
||||
let content = await zip.generateAsync({type: "blob"})
|
||||
saveAs(content, `${APP_NAME}-User-Data-${dayjs().format('YYYY-MM-DD HH-mm-ss')}.zip`);
|
||||
saveAs(content, fileName);
|
||||
notice && Toast.success(notice)
|
||||
return content
|
||||
} catch (e) {
|
||||
|
||||
@@ -1,14 +1,21 @@
|
||||
<script setup lang="ts">
|
||||
import { nextTick, onMounted, ref, watch } from "vue";
|
||||
import { useSettingStore } from "@/stores/setting.ts";
|
||||
import { getAudioFileUrl, usePlayAudio } from "@/hooks/sound.ts";
|
||||
import { getShortcutKey, useEventListener } from "@/hooks/event.ts";
|
||||
import { checkAndUpgradeSaveDict, checkAndUpgradeSaveSetting, cloneDeep, loadJsLib, shakeCommonDict } from "@/utils";
|
||||
import { DefaultShortcutKeyMap, ShortcutKey, WordPracticeMode } from "@/types/types.ts";
|
||||
import {nextTick, onMounted, ref, watch} from "vue";
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
import {getAudioFileUrl, usePlayAudio} from "@/hooks/sound.ts";
|
||||
import {getShortcutKey, useEventListener} from "@/hooks/event.ts";
|
||||
import {
|
||||
checkAndUpgradeSaveDict,
|
||||
checkAndUpgradeSaveSetting,
|
||||
cloneDeep,
|
||||
loadJsLib,
|
||||
shakeCommonDict,
|
||||
sleep
|
||||
} from "@/utils";
|
||||
import {DefaultShortcutKeyMap, ShortcutKey, WordPracticeMode} from "@/types/types.ts";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import VolumeIcon from "@/components/icon/VolumeIcon.vue";
|
||||
import { useBaseStore } from "@/stores/base.ts";
|
||||
import { saveAs } from "file-saver";
|
||||
import {useBaseStore} from "@/stores/base.ts";
|
||||
import {saveAs} from "file-saver";
|
||||
import {
|
||||
APP_NAME, APP_VERSION, EMAIL,
|
||||
EXPORT_DATA_KEY, GITHUB, Host,
|
||||
@@ -20,7 +27,7 @@ import {
|
||||
import dayjs from "dayjs";
|
||||
import BasePage from "@/components/BasePage.vue";
|
||||
import Toast from '@/components/base/toast/Toast.ts'
|
||||
import { Option, Select } from "@/components/base/select";
|
||||
import {Option, Select} from "@/components/base/select";
|
||||
import Switch from "@/components/base/Switch.vue";
|
||||
import Slider from "@/components/base/Slider.vue";
|
||||
import RadioGroup from "@/components/base/radio/RadioGroup.vue";
|
||||
@@ -29,10 +36,10 @@ import InputNumber from "@/components/base/InputNumber.vue";
|
||||
import PopConfirm from "@/components/PopConfirm.vue";
|
||||
import Textarea from "@/components/base/Textarea.vue";
|
||||
import SettingItem from "@/pages/setting/SettingItem.vue";
|
||||
import { get, set } from "idb-keyval";
|
||||
import { useRuntimeStore } from "@/stores/runtime.ts";
|
||||
import { useUserStore } from "@/stores/user.ts";
|
||||
import { useExport } from "@/hooks/export.ts";
|
||||
import {get, set} from "idb-keyval";
|
||||
import {useRuntimeStore} from "@/stores/runtime.ts";
|
||||
import {useUserStore} from "@/stores/user.ts";
|
||||
import {useExport} from "@/hooks/export.ts";
|
||||
import MigrateDialog from "@/components/MigrateDialog.vue";
|
||||
|
||||
const emit = defineEmits<{
|
||||
@@ -99,7 +106,7 @@ useEventListener('keydown', (e: KeyboardEvent) => {
|
||||
} else {
|
||||
// 忽略单独的修饰键
|
||||
if (shortcutKey === 'Ctrl+' || shortcutKey === 'Alt+' || shortcutKey === 'Shift+' ||
|
||||
e.key === 'Control' || e.key === 'Alt' || e.key === 'Shift') {
|
||||
e.key === 'Control' || e.key === 'Alt' || e.key === 'Shift') {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -174,6 +181,7 @@ let importLoading = $ref(false)
|
||||
const {loading: exportLoading, exportData} = useExport()
|
||||
|
||||
function importJson(str: string, notice: boolean = true) {
|
||||
importLoading = true
|
||||
let obj = {
|
||||
version: -1,
|
||||
val: {
|
||||
@@ -223,10 +231,15 @@ function importJson(str: string, notice: boolean = true) {
|
||||
notice && Toast.success('导入成功!')
|
||||
} catch (err) {
|
||||
return Toast.error('导入失败!')
|
||||
}finally {
|
||||
importLoading = false
|
||||
}
|
||||
}
|
||||
|
||||
async function importData(e) {
|
||||
importLoading = true
|
||||
await exportData('已自动备份数据', 'TypeWords数据备份.zip')
|
||||
await sleep(1500)
|
||||
let file = e.target.files[0]
|
||||
if (!file) return
|
||||
if (file.name.endsWith(".json")) {
|
||||
@@ -240,7 +253,6 @@ async function importData(e) {
|
||||
reader.readAsText(file);
|
||||
} else if (file.name.endsWith(".zip")) {
|
||||
try {
|
||||
importLoading = true
|
||||
const JSZip = await loadJsLib('JSZip', `${Origin}/libs/jszip.min.js`);
|
||||
const zip = await JSZip.loadAsync(file);
|
||||
|
||||
@@ -276,6 +288,7 @@ async function importData(e) {
|
||||
} else {
|
||||
Toast.error("不支持的文件类型");
|
||||
}
|
||||
importLoading = false
|
||||
}
|
||||
|
||||
let isNewHost = $ref(window.location.host === Host)
|
||||
@@ -335,7 +348,7 @@ function transferOk() {
|
||||
<input ref="shortcutInput" :value="item[1]?item[1]:'未设置快捷键'" readonly type="text"
|
||||
@blur="handleInputBlur">
|
||||
<span @click.stop="editShortcutKey = ''">按键盘进行设置,<span
|
||||
class="text-red!">设置完成点击这里</span></span>
|
||||
class="text-red!">设置完成点击这里</span></span>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div v-if="item[1]">{{ item[1] }}</div>
|
||||
@@ -362,7 +375,7 @@ function transferOk() {
|
||||
|
||||
<div class="line my-3"></div>
|
||||
|
||||
<div>请注意,导入数据后将<b class="text-red"> 完全覆盖 </b>当前所有数据,请谨慎操作。
|
||||
<div>请注意,导入数据后将<b class="text-red"> 完全覆盖 </b>当前所有数据,请谨慎操作。执行导入操作时,会先自动备份当前数据到您的电脑中,供您随时恢复
|
||||
</div>
|
||||
<div class="flex gap-space mt-3">
|
||||
<div class="import hvr-grow">
|
||||
@@ -462,7 +475,7 @@ function transferOk() {
|
||||
<div class="mb-2">
|
||||
<div>
|
||||
<div>日期:2025/11/16</div>
|
||||
<div>内容:辨认单词时,不认识单词可以直接输入,自动标识为错误单词,无需按2</div>
|
||||
<div>内容:自测单词时,不认识单词可以直接输入,自动标识为错误单词,无需按2</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -518,7 +531,7 @@ function transferOk() {
|
||||
<ol>
|
||||
<li>
|
||||
<div class="title"><b>智能模式优化</b></div>
|
||||
<div class="desc">练习时新增四种练习模式:学习、辨认、听写、默写。</div>
|
||||
<div class="desc">练习时新增四种练习模式:学习、自测、听写、默写。</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="title"><b>学习模式</b></div>
|
||||
@@ -531,7 +544,7 @@ function transferOk() {
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="title"><b>辨认模式(新增)</b></div>
|
||||
<div class="title"><b>自测模式(新增)</b></div>
|
||||
<div class="desc">
|
||||
<ul>
|
||||
<li>仅在复习已学单词时出现。</li>
|
||||
@@ -620,8 +633,8 @@ function transferOk() {
|
||||
</BasePage>
|
||||
|
||||
<MigrateDialog
|
||||
v-model="showTransfer"
|
||||
@ok="transferOk"
|
||||
v-model="showTransfer"
|
||||
@ok="transferOk"
|
||||
/>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -359,9 +359,9 @@ async function next(isTyping: boolean = true) {
|
||||
return goNextStep(shuffle(taskWords.write), WordPracticeType.Listen, '开始听写之前')
|
||||
}
|
||||
|
||||
//开始辨认之前
|
||||
//开始自测之前
|
||||
if (statStore.step === 5) {
|
||||
return goNextStep(taskWords.write, WordPracticeType.Identify, '开始辨认之前')
|
||||
return goNextStep(taskWords.write, WordPracticeType.Identify, '开始自测之前')
|
||||
}
|
||||
|
||||
//开始默写上次
|
||||
@@ -374,9 +374,9 @@ async function next(isTyping: boolean = true) {
|
||||
return goNextStep(shuffle(taskWords.review), WordPracticeType.Listen, '开始听写上次')
|
||||
}
|
||||
|
||||
//开始辨认昨日
|
||||
//开始自测昨日
|
||||
if (statStore.step === 2) {
|
||||
return goNextStep(taskWords.review, WordPracticeType.Identify, '开始辨认昨日')
|
||||
return goNextStep(taskWords.review, WordPracticeType.Identify, '开始自测昨日')
|
||||
}
|
||||
|
||||
//开始默写新词
|
||||
|
||||
@@ -4,7 +4,7 @@ import { useRouter } from "vue-router";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import {
|
||||
_getAccomplishDate,
|
||||
_getDictDataByUrl,
|
||||
_getDictDataByUrl, _getStudyProgress,
|
||||
_nextTick,
|
||||
isMobile,
|
||||
loadJsLib,
|
||||
@@ -446,9 +446,14 @@ let isNewHost = $ref(window.location.host === Host)
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex gap-4 flex-wrap mt-4">
|
||||
<Book :is-add="false" quantifier="个词" :item="item" :checked="selectIds.includes(item.id)"
|
||||
@check="() => toggleSelect(item)" :show-checkbox="isManageDict && j >= 3"
|
||||
v-for="(item, j) in store.word.bookList" @click="goDictDetail(item)"/>
|
||||
<Book :is-add="false"
|
||||
quantifier="个词"
|
||||
:item="item"
|
||||
:checked="selectIds.includes(item.id)"
|
||||
@check="() => toggleSelect(item)"
|
||||
:show-checkbox="isManageDict && j >= 3"
|
||||
v-for="(item, j) in store.word.bookList"
|
||||
@click="goDictDetail(item)"/>
|
||||
<Book :is-add="true" @click="router.push('/dict-list')"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -51,7 +51,7 @@ function getStepStr(step: number) {
|
||||
str += `默写新词`
|
||||
break
|
||||
case 3:
|
||||
str += `辨认上次学习`
|
||||
str += `自测上次学习`
|
||||
break
|
||||
case 4:
|
||||
str += '听写上次学习'
|
||||
@@ -60,7 +60,7 @@ function getStepStr(step: number) {
|
||||
str += '默写上次学习'
|
||||
break
|
||||
case 6:
|
||||
str += '辨认之前学习'
|
||||
str += '自测之前学习'
|
||||
break
|
||||
case 7:
|
||||
str += '听写之前学习'
|
||||
@@ -96,6 +96,11 @@ const progress = $computed(() => {
|
||||
</Tooltip>
|
||||
|
||||
<div class="bottom">
|
||||
<Progress :percentage="progress"
|
||||
:stroke-width="8"
|
||||
color="#69b1ff"
|
||||
:show-text="false"/>
|
||||
|
||||
<div class="flex justify-between items-center">
|
||||
<div class="stat">
|
||||
<div class="row">
|
||||
@@ -246,7 +251,7 @@ const progress = $computed(() => {
|
||||
|
||||
.arrow {
|
||||
position: absolute;
|
||||
top: -60%;
|
||||
top: -40%;
|
||||
left: 50%;
|
||||
cursor: pointer;
|
||||
transition: all .5s;
|
||||
@@ -255,7 +260,7 @@ const progress = $computed(() => {
|
||||
font-size: 1.2rem;
|
||||
|
||||
&.down {
|
||||
top: -120%;
|
||||
top: -90%;
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
import { _getAccomplishDays } from "@/utils";
|
||||
import {_getAccomplishDays} from "@/utils";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import Checkbox from "@/components/base/checkbox/Checkbox.vue";
|
||||
import Slider from "@/components/base/Slider.vue";
|
||||
import { defineAsyncComponent, watch } from "vue";
|
||||
import { useSettingStore } from "@/stores/setting.ts";
|
||||
import {defineAsyncComponent, watch} from "vue";
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
import Toast from "@/components/base/toast/Toast.ts";
|
||||
import ChangeLastPracticeIndexDialog from "@/pages/word/components/ChangeLastPracticeIndexDialog.vue";
|
||||
import Tooltip from "@/components/base/Tooltip.vue";
|
||||
import { useRuntimeStore } from "@/stores/runtime.ts";
|
||||
import {useRuntimeStore} from "@/stores/runtime.ts";
|
||||
import BaseInput from "@/components/base/BaseInput.vue";
|
||||
|
||||
const Dialog = defineAsyncComponent(() => import('@/components/dialog/Dialog.vue'))
|
||||
|
||||
@@ -56,9 +57,11 @@ watch(() => model.value, (n) => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Dialog v-model="model" title="学习设置" :footer="true"
|
||||
<Dialog
|
||||
v-model="model"
|
||||
title="学习设置" :footer="true"
|
||||
@ok="changePerDayStudyNumber">
|
||||
<div class="target-modal color-main" id="mode">
|
||||
<div class="target-modal color-main" id="mode">
|
||||
<div class="center">
|
||||
<div class="flex gap-4 text-center h-30 w-85">
|
||||
<div class="mode-item" :class="temPracticeMode == 0 && 'active'" @click=" temPracticeMode = 0">
|
||||
@@ -71,15 +74,22 @@ watch(() => model.value, (n) => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="text-center mt-2 mb-8">
|
||||
<span>从第<span class="text-3xl mx-2 lh">{{ tempLastLearnIndex }}</span>个开始,</span>
|
||||
<span>每日<span class="text-3xl mx-2 lh">{{ tempPerDayStudyNumber }}</span>个,</span>
|
||||
<div class="text-center mt-4 mb-8 flex gap-1 items-end justify-center">
|
||||
<span>从第</span>
|
||||
<div class="w-18">
|
||||
<BaseInput v-model="tempLastLearnIndex"/>
|
||||
</div>
|
||||
<span>个开始,每日</span>
|
||||
<div class="w-18">
|
||||
<BaseInput v-model="tempPerDayStudyNumber"/>
|
||||
</div>
|
||||
<span>个,</span>
|
||||
<span>预计<span
|
||||
class="text-3xl mx-2 lh">{{
|
||||
class="text-3xl mx-2 inner">{{
|
||||
_getAccomplishDays(runtimeStore.editDict.length - tempLastLearnIndex, tempPerDayStudyNumber)
|
||||
}}</span>天完成</span>
|
||||
</div>
|
||||
|
||||
<div class="flex mb-4 gap-space">
|
||||
<span class="shrink-0">每日学习</span>
|
||||
<Slider :min="10"
|
||||
@@ -121,18 +131,19 @@ watch(() => model.value, (n) => {
|
||||
<style scoped lang="scss">
|
||||
|
||||
.target-modal {
|
||||
width: 30rem;
|
||||
width: 35rem;
|
||||
padding: 0 var(--space);
|
||||
|
||||
.lh {
|
||||
:deep(.inner){
|
||||
font-size: 2rem;
|
||||
color: rgb(176, 116, 211)
|
||||
}
|
||||
|
||||
.mode-item{
|
||||
.mode-item {
|
||||
@apply w-50% border border-blue border-solid p-2 rounded-lg cursor-pointer;
|
||||
}
|
||||
|
||||
.active{
|
||||
.active {
|
||||
@apply bg-blue color-white;
|
||||
}
|
||||
}
|
||||
@@ -143,53 +154,53 @@ watch(() => model.value, (n) => {
|
||||
width: 90vw !important;
|
||||
max-width: 400px;
|
||||
padding: 0 1rem;
|
||||
|
||||
|
||||
// 模式选择
|
||||
.center .flex.gap-4 {
|
||||
width: 100%;
|
||||
flex-direction: column;
|
||||
height: auto;
|
||||
gap: 0.8rem;
|
||||
|
||||
|
||||
.mode-item {
|
||||
width: 100%;
|
||||
padding: 1rem;
|
||||
|
||||
|
||||
.title {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
|
||||
.desc {
|
||||
font-size: 0.85rem;
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 统计显示
|
||||
.text-center {
|
||||
font-size: 0.9rem;
|
||||
|
||||
|
||||
.text-3xl {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 滑块控件
|
||||
.flex.mb-4, .flex.mb-6 {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 0.5rem;
|
||||
|
||||
|
||||
span {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
||||
.flex-1 {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 按钮
|
||||
.base-button {
|
||||
width: 100%;
|
||||
@@ -202,10 +213,10 @@ watch(() => model.value, (n) => {
|
||||
.target-modal {
|
||||
width: 95vw !important;
|
||||
padding: 0 0.5rem;
|
||||
|
||||
|
||||
.text-center {
|
||||
font-size: 0.8rem;
|
||||
|
||||
|
||||
.text-3xl {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
@@ -222,7 +222,7 @@ async function onTyping(e: KeyboardEvent) {
|
||||
updateCurrentWordInfo();
|
||||
inputLock = false
|
||||
} else if (settingStore.wordPracticeType === WordPracticeType.Identify && !showWordResult) {
|
||||
//当辨认模式下,按1和2会单独处理,如果按其他键则自动默认为不认识
|
||||
//当自测模式下,按1和2会单独处理,如果按其他键则自动默认为不认识
|
||||
showWordResult = true
|
||||
emit('wrong')
|
||||
if (settingStore.wordSound) volumeIconRef?.play()
|
||||
@@ -409,7 +409,7 @@ useEvents([
|
||||
<template>
|
||||
<div class="typing-word" ref="typingWordRef" v-if="word.word.length">
|
||||
<div class="flex flex-col items-center">
|
||||
<div class="flex gap-1 mt-26">
|
||||
<div class="flex gap-1 mt-30">
|
||||
<div class="phonetic"
|
||||
:class="!(!settingStore.dictation || showFullWord || showWordResult) && 'word-shadow'"
|
||||
v-if="settingStore.soundType === 'us' && word.phonetic0">[{{ word.phonetic0 }}]
|
||||
@@ -481,7 +481,7 @@ useEvents([
|
||||
</div>
|
||||
<div class="other anim"
|
||||
v-opacity="![WordPracticeType.Listen,WordPracticeType.Dictation,WordPracticeType.Identify].includes(settingStore.wordPracticeType) || showFullWord || showWordResult">
|
||||
<div class="line-white my-2"></div>
|
||||
<div class="line-white my-3"></div>
|
||||
<template v-if="word?.sentences?.length">
|
||||
<div class="flex flex-col gap-3">
|
||||
<div class="sentence" v-for="item in word.sentences">
|
||||
@@ -492,10 +492,10 @@ useEvents([
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="line-white my-2 mb-5"></div>
|
||||
</template>
|
||||
|
||||
<template v-if="word?.phrases?.length">
|
||||
<div class="line-white my-3"></div>
|
||||
<div class="flex">
|
||||
<div class="label">短语</div>
|
||||
<div class="flex flex-col">
|
||||
@@ -508,11 +508,11 @@ useEvents([
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="line-white mt-3 mb-2"></div>
|
||||
</template>
|
||||
|
||||
<template v-if="(settingStore.translate || !settingStore.dictation)">
|
||||
<template v-if="word?.synos?.length">
|
||||
<div class="line-white my-3"></div>
|
||||
<div class="flex">
|
||||
<div class='label'>同近义词</div>
|
||||
<div class="flex flex-col gap-3">
|
||||
@@ -531,13 +531,14 @@ useEvents([
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="line-white my-2"></div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<div class="anim"
|
||||
v-opacity="(settingStore.translate && !settingStore.dictation) || showFullWord || showWordResult">
|
||||
<template v-if="word?.etymology?.length">
|
||||
<div class="line-white my-3"></div>
|
||||
|
||||
<div class="flex">
|
||||
<div class="label">词源</div>
|
||||
<div class="text-base">
|
||||
|
||||
@@ -86,7 +86,6 @@ export const useBaseStore = defineStore('base', {
|
||||
},
|
||||
currentStudyProgress(): number {
|
||||
if (!this.sdict.length) return 0
|
||||
if (this.sdict.complete) return 100
|
||||
return _getStudyProgress(this.sdict.lastLearnIndex, this.sdict.length)
|
||||
},
|
||||
getDictCompleteDate(): number {
|
||||
@@ -191,11 +190,12 @@ export const useBaseStore = defineStore('base', {
|
||||
let rIndex = this.article.bookList.findIndex((v: Dict) => v.id === val.id)
|
||||
if (rIndex > -1) {
|
||||
this.article.studyIndex = rIndex
|
||||
this.article.bookList[this.article.studyIndex] = getDefaultDict(val)
|
||||
// this.article.bookList[this.article.studyIndex].articles = shallowReactive(val.articles)
|
||||
// this.article.bookList[this.article.studyIndex].cover = val.cover
|
||||
// this.article.bookList[this.article.studyIndex].name = val.name
|
||||
// this.article.bookList[this.article.studyIndex].description = val.description
|
||||
//不要整个等于,不然统计没了
|
||||
// this.article.bookList[this.article.studyIndex] = getDefaultDict(val)
|
||||
this.article.bookList[this.article.studyIndex].articles = shallowReactive(val.articles)
|
||||
this.article.bookList[this.article.studyIndex].cover = val.cover
|
||||
this.article.bookList[this.article.studyIndex].name = val.name
|
||||
this.article.bookList[this.article.studyIndex].description = val.description
|
||||
} else {
|
||||
this.article.bookList.push(getDefaultDict(val))
|
||||
this.article.studyIndex = this.article.bookList.length - 1
|
||||
|
||||
Reference in New Issue
Block a user