wip
This commit is contained in:
@@ -32,6 +32,7 @@
|
||||
"mitt": "^3.0.1",
|
||||
"nanoid": "^5.1.5",
|
||||
"pinia": "^3.0.3",
|
||||
"shepherd.js": "^14.5.1",
|
||||
"string-comparison": "^1.3.0",
|
||||
"vue": "^3.5.17",
|
||||
"vue-router": "^4.5.1",
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
@use "anim" as *;
|
||||
@use 'intro.js/minified/introjs.min.css';
|
||||
//@use 'intro.js/minified/introjs.min.css';
|
||||
@use 'shepherd.js/dist/css/shepherd.css';
|
||||
|
||||
.shepherd-enabled.shepherd-element{
|
||||
transform: translateY(30px);
|
||||
}
|
||||
:root {
|
||||
--color-reverse-white: white;
|
||||
--color-reverse-black: black;
|
||||
|
||||
@@ -33,7 +33,7 @@ const studyProgress = $computed(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="book relative overflow-hidden">
|
||||
<div class="book relative overflow-hidden" :id="item?.id">
|
||||
<template v-if="!isAdd">
|
||||
<div>
|
||||
<div class="text-base">{{ item?.name }}</div>
|
||||
|
||||
@@ -175,6 +175,7 @@ async function cancel() {
|
||||
<div class="right">
|
||||
<BaseButton type="info" @click="cancel">{{ cancelButtonText }}</BaseButton>
|
||||
<BaseButton
|
||||
id="dialog-ok"
|
||||
:loading="confirmButtonLoading"
|
||||
@click="ok">{{ confirmButtonText }}
|
||||
</BaseButton>
|
||||
|
||||
@@ -73,4 +73,16 @@ export const PracticeSaveWordKey = {
|
||||
export const PracticeSaveArticleKey = {
|
||||
key: 'PracticeSaveArticle',
|
||||
version: 1
|
||||
}
|
||||
|
||||
export const TourConfig = {
|
||||
useModalOverlay: true,
|
||||
defaultStepOptions: {
|
||||
canClickTarget: false,
|
||||
classes: 'shadow-md bg-purple-dark',
|
||||
cancelIcon: {enabled: true},
|
||||
modalOverlayOpeningPadding: 10,
|
||||
modalOverlayOpeningRadius: 6,
|
||||
},
|
||||
total: 10
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
<script setup lang="tsx">
|
||||
import { DictId } from "@/types/types.ts";
|
||||
import {DictId} from "@/types/types.ts";
|
||||
|
||||
import BasePage from "@/components/BasePage.vue";
|
||||
import { computed, onMounted, reactive, ref, shallowReactive } from "vue";
|
||||
import { useRuntimeStore } from "@/stores/runtime.ts";
|
||||
import { _getDictDataByUrl, _nextTick, convertToWord, isMobile, loadJsLib, sleep, useNav } from "@/utils";
|
||||
import { nanoid } from "nanoid";
|
||||
import {computed, onMounted, reactive, ref, shallowReactive, watch} from "vue";
|
||||
import {useRuntimeStore} from "@/stores/runtime.ts";
|
||||
import {_getDictDataByUrl, _nextTick, convertToWord, isMobile, loadJsLib, sleep, useNav} from "@/utils";
|
||||
import {nanoid} from "nanoid";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import BaseTable from "@/components/BaseTable.vue";
|
||||
import WordItem from "@/components/WordItem.vue";
|
||||
@@ -13,21 +13,22 @@ import Toast from '@/components/base/toast/Toast.ts'
|
||||
import PopConfirm from "@/components/PopConfirm.vue";
|
||||
import BackIcon from "@/components/BackIcon.vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import { useBaseStore } from "@/stores/base.ts";
|
||||
import {useRoute, useRouter} from "vue-router";
|
||||
import {useBaseStore} from "@/stores/base.ts";
|
||||
import EditBook from "@/pages/article/components/EditBook.vue";
|
||||
import { getDefaultDict } from "@/types/func.ts";
|
||||
import {getDefaultDict} from "@/types/func.ts";
|
||||
import BaseInput from "@/components/base/BaseInput.vue";
|
||||
import Textarea from "@/components/base/Textarea.vue";
|
||||
import FormItem from "@/components/base/form/FormItem.vue";
|
||||
import Form from "@/components/base/form/Form.vue";
|
||||
import DeleteIcon from "@/components/icon/DeleteIcon.vue";
|
||||
import { getCurrentStudyWord } from "@/hooks/dict.ts";
|
||||
import {getCurrentStudyWord} from "@/hooks/dict.ts";
|
||||
import PracticeSettingDialog from "@/pages/word/components/PracticeSettingDialog.vue";
|
||||
import { useSettingStore } from "@/stores/setting.ts";
|
||||
import { MessageBox } from "@/utils/MessageBox.tsx";
|
||||
import { AppEnv, Origin, PracticeSaveWordKey } from "@/config/env.ts";
|
||||
import { detail } from "@/apis";
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
import {MessageBox} from "@/utils/MessageBox.tsx";
|
||||
import {AppEnv, Origin, PracticeSaveWordKey, TourConfig} from "@/config/env.ts";
|
||||
import {detail} from "@/apis";
|
||||
import Shepherd from "shepherd.js";
|
||||
|
||||
const runtimeStore = useRuntimeStore()
|
||||
const base = useBaseStore()
|
||||
@@ -384,6 +385,75 @@ function searchWord() {
|
||||
console.log('wordForm.word', wordForm.word)
|
||||
}
|
||||
|
||||
|
||||
watch(() => loading, (val) => {
|
||||
if (!val) return
|
||||
_nextTick(() => {
|
||||
const tour = new Shepherd.Tour(TourConfig);
|
||||
tour.addStep({
|
||||
id: 'step3',
|
||||
text: '点击这里开始学习',
|
||||
attachTo: {element: '#study', on: 'bottom'},
|
||||
buttons: [
|
||||
{
|
||||
text: `下一步(3/${TourConfig.total})`,
|
||||
action() {
|
||||
// localStorage.setItem('shepherd_step', 'step3');
|
||||
tour.next()
|
||||
addMyStudyList()
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
tour.addStep({
|
||||
id: 'step4',
|
||||
text: '点击这里选择学习模式',
|
||||
attachTo: {element: '#mode', on: 'bottom'},
|
||||
beforeShowPromise() {
|
||||
return new Promise((resolve) => {
|
||||
const timer = setInterval(() => {
|
||||
if (document.querySelector('#mode')) {
|
||||
clearInterval(timer);
|
||||
resolve(true);
|
||||
}
|
||||
}, 100);
|
||||
});
|
||||
},
|
||||
buttons: [
|
||||
{
|
||||
text: `下一步(4/${TourConfig.total})`,
|
||||
action: tour.next
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
tour.addStep({
|
||||
id: 'step5',
|
||||
text: '点击这里开始学习',
|
||||
attachTo: {element: '#dialog-ok', on: 'bottom'},
|
||||
buttons: [
|
||||
{
|
||||
text: `下一步(5/${TourConfig.total})`,
|
||||
action() {
|
||||
localStorage.setItem('shepherd_step', 'step6');
|
||||
tour.next()
|
||||
startPractice()
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
const stepId = localStorage.getItem('shepherd_step');
|
||||
if (stepId) {
|
||||
// localStorage.removeItem('shepherd_step');
|
||||
tour.start();
|
||||
tour.show(stepId); // 直接跳到对应步骤
|
||||
}
|
||||
},)
|
||||
})
|
||||
|
||||
|
||||
defineRender(() => {
|
||||
return (
|
||||
<BasePage>
|
||||
@@ -395,7 +465,7 @@ defineRender(() => {
|
||||
<div class="dict-actions flex">
|
||||
<BaseButton loading={studyLoading || loading} type="info"
|
||||
onClick={() => isEdit = true}>编辑</BaseButton>
|
||||
<BaseButton loading={studyLoading || loading} onClick={addMyStudyList}>学习</BaseButton>
|
||||
<BaseButton id="study" loading={studyLoading || loading} onClick={addMyStudyList}>学习</BaseButton>
|
||||
<BaseButton loading={studyLoading || loading} onClick={startTest}>测试</BaseButton>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
<script setup lang="ts">
|
||||
import { groupBy, resourceWrap, useNav } from "@/utils";
|
||||
import {_nextTick, groupBy, resourceWrap, useNav} from "@/utils";
|
||||
import BasePage from "@/components/BasePage.vue";
|
||||
import { DictResource } from "@/types/types.ts";
|
||||
import { useRuntimeStore } from "@/stores/runtime.ts";
|
||||
import {DictResource} from "@/types/types.ts";
|
||||
import {useRuntimeStore} from "@/stores/runtime.ts";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import Empty from "@/components/Empty.vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import DictList from "@/components/list/DictList.vue";
|
||||
import BackIcon from "@/components/BackIcon.vue";
|
||||
import DictGroup from "@/components/list/DictGroup.vue";
|
||||
import { useBaseStore } from "@/stores/base.ts";
|
||||
import { useRouter } from "vue-router";
|
||||
import { computed } from "vue";
|
||||
import { getDefaultDict } from "@/types/func.ts";
|
||||
import { useFetch } from "@vueuse/core";
|
||||
import { DICT_LIST } from "@/config/env.ts";
|
||||
import {useBaseStore} from "@/stores/base.ts";
|
||||
import {useRouter} from "vue-router";
|
||||
import {computed, onMounted, watch} from "vue";
|
||||
import {getDefaultDict} from "@/types/func.ts";
|
||||
import {useFetch} from "@vueuse/core";
|
||||
import {DICT_LIST, TourConfig} from "@/config/env.ts";
|
||||
import BaseInput from "@/components/base/BaseInput.vue";
|
||||
import Shepherd from "shepherd.js";
|
||||
|
||||
const {nav} = useNav()
|
||||
const runtimeStore = useRuntimeStore()
|
||||
@@ -56,7 +57,7 @@ const groupedByCategoryAndTag = $computed(() => {
|
||||
data.push([key, groupByDictTags(value)])
|
||||
}
|
||||
[data[2], data[3]] = [data[3], data[2]];
|
||||
console.log('data',data)
|
||||
console.log('data', data)
|
||||
return data
|
||||
})
|
||||
|
||||
@@ -68,15 +69,46 @@ const searchList = computed<any[]>(() => {
|
||||
let s = searchKey.toLowerCase()
|
||||
return dict_list.value.filter((item) => {
|
||||
return item.id.toLowerCase().includes(s)
|
||||
|| item.name.toLowerCase().includes(s)
|
||||
|| item.category.toLowerCase().includes(s)
|
||||
|| item.tags.join('').replace('所有', '').toLowerCase().includes(s)
|
||||
|| item?.url?.toLowerCase?.().includes?.(s)
|
||||
|| item.name.toLowerCase().includes(s)
|
||||
|| item.category.toLowerCase().includes(s)
|
||||
|| item.tags.join('').replace('所有', '').toLowerCase().includes(s)
|
||||
|| item?.url?.toLowerCase?.().includes?.(s)
|
||||
})
|
||||
}
|
||||
return []
|
||||
})
|
||||
|
||||
watch(dict_list, (val) => {
|
||||
if (!val.length) return
|
||||
let cet4 = val.find(v => v.id === 'cet4')
|
||||
if (!cet4) return
|
||||
_nextTick(() => {
|
||||
const tour = new Shepherd.Tour(TourConfig);
|
||||
tour.addStep({
|
||||
id: 'step2',
|
||||
text: '选一本自己准备学习的词典',
|
||||
attachTo: {element: '#cet4', on: 'bottom'},
|
||||
buttons: [
|
||||
{
|
||||
text: `下一步(2/${TourConfig.total})`,
|
||||
action() {
|
||||
localStorage.setItem('shepherd_step', 'step3');
|
||||
tour.next()
|
||||
selectDict({dict: cet4})
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
const stepId = localStorage.getItem('shepherd_step');
|
||||
if (stepId) {
|
||||
// localStorage.removeItem('shepherd_step');
|
||||
tour.start();
|
||||
tour.show(stepId); // 直接跳到对应步骤
|
||||
}
|
||||
},)
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -91,31 +123,31 @@ const searchList = computed<any[]>(() => {
|
||||
<div class="py-1 flex flex-1 justify-end" v-else>
|
||||
<span class="page-title absolute w-full center">词典列表</span>
|
||||
<BaseIcon
|
||||
title="搜索"
|
||||
@click="showSearchInput = true"
|
||||
class="z-1"
|
||||
icon="fluent:search-24-regular">
|
||||
title="搜索"
|
||||
@click="showSearchInput = true"
|
||||
class="z-1"
|
||||
icon="fluent:search-24-regular">
|
||||
<IconFluentSearch24Regular/>
|
||||
</BaseIcon>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4" v-if="searchKey">
|
||||
<DictList
|
||||
v-if="searchList.length "
|
||||
@selectDict="selectDict"
|
||||
:list="searchList"
|
||||
quantifier="个词"
|
||||
:select-id="'-1'"/>
|
||||
v-if="searchList.length "
|
||||
@selectDict="selectDict"
|
||||
:list="searchList"
|
||||
quantifier="个词"
|
||||
:select-id="'-1'"/>
|
||||
<Empty v-else text="没有相关词典"/>
|
||||
</div>
|
||||
<div class="w-full" v-else>
|
||||
<DictGroup
|
||||
v-for="item in groupedByCategoryAndTag"
|
||||
:select-id="store.currentStudyWordDict.id"
|
||||
@selectDict="selectDict"
|
||||
quantifier="个词"
|
||||
:groupByTag="item[1]"
|
||||
:category="item[0]"
|
||||
v-for="item in groupedByCategoryAndTag"
|
||||
:select-id="store.currentStudyWordDict.id"
|
||||
@selectDict="selectDict"
|
||||
quantifier="个词"
|
||||
:groupByTag="item[1]"
|
||||
:category="item[0]"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -128,37 +160,37 @@ const searchList = computed<any[]>(() => {
|
||||
.dict-list-page {
|
||||
padding: 0.8rem;
|
||||
margin-bottom: 1rem;
|
||||
|
||||
|
||||
.header-section {
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
|
||||
|
||||
.flex.flex-1.gap-4 {
|
||||
width: 100%;
|
||||
|
||||
|
||||
.base-input {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
|
||||
.base-button {
|
||||
padding: 0.5rem 0.8rem;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.py-1.flex.flex-1.justify-end {
|
||||
width: 100%;
|
||||
|
||||
|
||||
.page-title {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
|
||||
.base-icon {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.mt-4 {
|
||||
margin-top: 0.8rem;
|
||||
}
|
||||
@@ -169,24 +201,24 @@ const searchList = computed<any[]>(() => {
|
||||
@media (max-width: 480px) {
|
||||
.dict-list-page {
|
||||
padding: 0.5rem;
|
||||
|
||||
|
||||
.header-section {
|
||||
.flex.flex-1.gap-4 {
|
||||
.base-input {
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
|
||||
.base-button {
|
||||
padding: 0.4rem 0.6rem;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.py-1.flex.flex-1.justify-end {
|
||||
.page-title {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
|
||||
.base-icon {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
@@ -1,29 +1,30 @@
|
||||
<script setup lang="ts">
|
||||
import { useBaseStore } from "@/stores/base.ts";
|
||||
import { useRouter } from "vue-router";
|
||||
import {useBaseStore} from "@/stores/base.ts";
|
||||
import {useRouter} from "vue-router";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import { _getAccomplishDate, _getDictDataByUrl, _nextTick, resourceWrap, shuffle, useNav } from "@/utils";
|
||||
import {_getAccomplishDate, _getDictDataByUrl, _nextTick, resourceWrap, shuffle, useNav} from "@/utils";
|
||||
import BasePage from "@/components/BasePage.vue";
|
||||
import { DictResource, WordPracticeMode } from "@/types/types.ts";
|
||||
import { onMounted, watch } from "vue";
|
||||
import { getCurrentStudyWord } from "@/hooks/dict.ts";
|
||||
import { useRuntimeStore } from "@/stores/runtime.ts";
|
||||
import {DictResource, WordPracticeMode} from "@/types/types.ts";
|
||||
import {onMounted, watch} from "vue";
|
||||
import {getCurrentStudyWord} from "@/hooks/dict.ts";
|
||||
import {useRuntimeStore} from "@/stores/runtime.ts";
|
||||
import Book from "@/components/Book.vue";
|
||||
import PopConfirm from "@/components/PopConfirm.vue";
|
||||
import Progress from '@/components/base/Progress.vue';
|
||||
import Toast from '@/components/base/toast/Toast.ts';
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import { getDefaultDict } from "@/types/func.ts";
|
||||
import {getDefaultDict} from "@/types/func.ts";
|
||||
import DeleteIcon from "@/components/icon/DeleteIcon.vue";
|
||||
import PracticeSettingDialog from "@/pages/word/components/PracticeSettingDialog.vue";
|
||||
import ChangeLastPracticeIndexDialog from "@/pages/word/components/ChangeLastPracticeIndexDialog.vue";
|
||||
import { useSettingStore } from "@/stores/setting.ts";
|
||||
import { useFetch } from "@vueuse/core";
|
||||
import { AppEnv, DICT_LIST, Host, PracticeSaveWordKey } from "@/config/env.ts";
|
||||
import { myDictList } from "@/apis";
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
import {useFetch} from "@vueuse/core";
|
||||
import {AppEnv, DICT_LIST, Host, PracticeSaveWordKey, TourConfig} from "@/config/env.ts";
|
||||
import {myDictList} from "@/apis";
|
||||
import PracticeWordListDialog from "@/pages/word/components/PracticeWordListDialog.vue";
|
||||
import ShufflePracticeSettingDialog from "@/pages/word/components/ShufflePracticeSettingDialog.vue";
|
||||
import introJs from "intro.js";
|
||||
import Shepherd from "shepherd.js";
|
||||
|
||||
|
||||
const store = useBaseStore()
|
||||
@@ -202,7 +203,27 @@ let isNewHost = $ref(window.location.host === Host)
|
||||
|
||||
onMounted(() => {
|
||||
_nextTick(() => {
|
||||
introJs.tour().start();
|
||||
const tour = new Shepherd.Tour(TourConfig);
|
||||
tour.addStep({
|
||||
id: 'step1',
|
||||
text: '点击这里选择一本词典开始学习',
|
||||
attachTo: {
|
||||
element: '#step1',
|
||||
on: 'bottom'
|
||||
},
|
||||
buttons: [
|
||||
{
|
||||
text: `下一步(1/${TourConfig.total})`,
|
||||
action() {
|
||||
// 保存当前步骤(下一页继续执行)
|
||||
localStorage.setItem('shepherd_step', 'step2');
|
||||
tour.next()
|
||||
router.push('/dict-list')
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
tour.start();
|
||||
}, 500)
|
||||
})
|
||||
</script>
|
||||
@@ -221,8 +242,8 @@ onMounted(() => {
|
||||
<IconFluentBookNumber20Filled class="text-xl color-link"/>
|
||||
</div>
|
||||
<div
|
||||
@click="goDictDetail(store.sdict)"
|
||||
class="text-2xl font-bold cursor-pointer">
|
||||
@click="goDictDetail(store.sdict)"
|
||||
class="text-2xl font-bold cursor-pointer">
|
||||
{{ store.sdict.name || '当前无正在学习的词典' }}
|
||||
</div>
|
||||
</div>
|
||||
@@ -248,9 +269,9 @@ onMounted(() => {
|
||||
</div>
|
||||
</BaseButton>
|
||||
<PopConfirm
|
||||
:disabled="!isSaveData"
|
||||
title="当前存在未完成的学习任务,修改会重新生成学习任务,是否继续?"
|
||||
@confirm="check(()=>showChangeLastPracticeIndexDialog = true)">
|
||||
:disabled="!isSaveData"
|
||||
title="当前存在未完成的学习任务,修改会重新生成学习任务,是否继续?"
|
||||
@confirm="check(()=>showChangeLastPracticeIndexDialog = true)">
|
||||
<BaseButton type="info"
|
||||
size="small"
|
||||
v-if="store.sdict.id"
|
||||
@@ -266,7 +287,7 @@ onMounted(() => {
|
||||
|
||||
<div class="flex items-center gap-4 mt-2 flex-1" v-else>
|
||||
<div class="title">请选择一本词典开始学习</div>
|
||||
<BaseButton data-intro='点击这里添加一本词典' type="primary" size="large" @click="router.push('/dict-list')">
|
||||
<BaseButton id="step1" type="primary" size="large" @click="router.push('/dict-list')">
|
||||
<div class="center gap-1">
|
||||
<IconFluentAdd16Regular/>
|
||||
<span>选择词典</span>
|
||||
@@ -299,11 +320,11 @@ onMounted(() => {
|
||||
</div>
|
||||
个单词
|
||||
<PopConfirm
|
||||
:disabled="!isSaveData"
|
||||
title="当前存在未完成的学习任务,修改会重新生成学习任务,是否继续?"
|
||||
@confirm="check(()=>showPracticeSettingDialog = true)">
|
||||
:disabled="!isSaveData"
|
||||
title="当前存在未完成的学习任务,修改会重新生成学习任务,是否继续?"
|
||||
@confirm="check(()=>showPracticeSettingDialog = true)">
|
||||
<BaseButton
|
||||
type="info" size="small">更改
|
||||
type="info" size="small">更改
|
||||
</BaseButton>
|
||||
</PopConfirm>
|
||||
</div>
|
||||
@@ -337,31 +358,31 @@ onMounted(() => {
|
||||
</BaseButton>
|
||||
|
||||
<div
|
||||
v-if="false"
|
||||
class="w-full flex box-border cp color-white">
|
||||
v-if="false"
|
||||
class="w-full flex box-border cp color-white">
|
||||
<div
|
||||
@click="startPractice"
|
||||
class="flex-1 rounded-l-lg center gap-2 py-1 bg-[var(--btn-primary)] hover:opacity-50">
|
||||
@click="startPractice"
|
||||
class="flex-1 rounded-l-lg center gap-2 py-1 bg-[var(--btn-primary)] hover:opacity-50">
|
||||
<span class="line-height-[2]">{{ isSaveData ? '继续学习' : '开始学习' }}</span>
|
||||
<IconFluentArrowCircleRight16Regular class="text-xl"/>
|
||||
</div>
|
||||
|
||||
<div class="relative group">
|
||||
<div
|
||||
class="w-10 rounded-r-lg h-full center bg-[var(--btn-primary)] hover:bg-gray border-solid border-2 border-l-gray border-transparent box-border">
|
||||
class="w-10 rounded-r-lg h-full center bg-[var(--btn-primary)] hover:bg-gray border-solid border-2 border-l-gray border-transparent box-border">
|
||||
<IconFluentChevronDown20Regular/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="space-y-2 pt-2 absolute z-2 right-0 border rounded opacity-0 scale-95
|
||||
class="space-y-2 pt-2 absolute z-2 right-0 border rounded opacity-0 scale-95
|
||||
group-hover:opacity-100 group-hover:scale-100
|
||||
transition-all duration-150 pointer-events-none group-hover:pointer-events-auto"
|
||||
>
|
||||
<div>
|
||||
<BaseButton
|
||||
size="large" type="orange"
|
||||
:loading="loading"
|
||||
@click="check(()=>showShufflePracticeSettingDialog = true)">
|
||||
size="large" type="orange"
|
||||
:loading="loading"
|
||||
@click="check(()=>showShufflePracticeSettingDialog = true)">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="line-height-[2]">随机复习</span>
|
||||
<IconFluentArrowShuffle20Filled class="text-xl"/>
|
||||
@@ -370,9 +391,9 @@ onMounted(() => {
|
||||
</div>
|
||||
<div>
|
||||
<BaseButton
|
||||
size="large" type="orange"
|
||||
:loading="loading"
|
||||
@click="check(()=>showShufflePracticeSettingDialog = true)">
|
||||
size="large" type="orange"
|
||||
:loading="loading"
|
||||
@click="check(()=>showShufflePracticeSettingDialog = true)">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="line-height-[2]">重新学习</span>
|
||||
<IconFluentArrowShuffle20Filled class="text-xl"/>
|
||||
@@ -384,10 +405,10 @@ onMounted(() => {
|
||||
</div>
|
||||
|
||||
<BaseButton
|
||||
v-if="store.sdict.id && store.sdict.lastLearnIndex"
|
||||
size="large" type="orange"
|
||||
:loading="loading"
|
||||
@click="check(()=>showShufflePracticeSettingDialog = true)">
|
||||
v-if="store.sdict.id && store.sdict.lastLearnIndex"
|
||||
size="large" type="orange"
|
||||
:loading="loading"
|
||||
@click="check(()=>showShufflePracticeSettingDialog = true)">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="line-height-[2]">随机复习</span>
|
||||
<IconFluentArrowShuffle20Filled class="text-xl"/>
|
||||
@@ -439,23 +460,23 @@ onMounted(() => {
|
||||
</BasePage>
|
||||
|
||||
<PracticeSettingDialog
|
||||
:show-left-option="false"
|
||||
v-model="showPracticeSettingDialog"
|
||||
@ok="savePracticeSetting"/>
|
||||
:show-left-option="false"
|
||||
v-model="showPracticeSettingDialog"
|
||||
@ok="savePracticeSetting"/>
|
||||
|
||||
<ChangeLastPracticeIndexDialog
|
||||
v-model="showChangeLastPracticeIndexDialog"
|
||||
@ok="saveLastPracticeIndex"
|
||||
v-model="showChangeLastPracticeIndexDialog"
|
||||
@ok="saveLastPracticeIndex"
|
||||
/>
|
||||
|
||||
<PracticeWordListDialog
|
||||
:data="currentStudy"
|
||||
v-model="showPracticeWordListDialog"
|
||||
:data="currentStudy"
|
||||
v-model="showPracticeWordListDialog"
|
||||
/>
|
||||
|
||||
<ShufflePracticeSettingDialog
|
||||
v-model="showShufflePracticeSettingDialog"
|
||||
@ok="onShufflePracticeSettingOk"/>
|
||||
v-model="showShufflePracticeSettingDialog"
|
||||
@ok="onShufflePracticeSettingOk"/>
|
||||
|
||||
</template>
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ watch(() => model.value, (n) => {
|
||||
@ok="changePerDayStudyNumber">
|
||||
<div class="target-modal color-main">
|
||||
<div class="center">
|
||||
<div class="flex gap-4 text-center h-30 w-85">
|
||||
<div class="flex gap-4 text-center h-30 w-85" id="mode">
|
||||
<div class="mode-item" :class="temPracticeMode == 0 && 'active'" @click=" temPracticeMode = 0">
|
||||
<div class="title text-align-center">智能模式</div>
|
||||
<div class="desc mt-2">自动规划学习、复习、听写、默写</div>
|
||||
|
||||
Reference in New Issue
Block a user