feat(all): change icon import way,auto import js lib

This commit is contained in:
zyronon
2023-09-12 15:53:23 +08:00
parent bef50ac958
commit a2b1d7b492
29 changed files with 5355 additions and 758 deletions

View File

@@ -9,22 +9,18 @@
import {onMounted} from "vue"
const canvas = $ref()
let ctx = null
const canvas = $ref<HTMLCanvasElement>()
onMounted(() => {
console.log('canvas;', canvas)
// ctx = canvas.getContext('2d')
let ocas = document.createElement("canvas");
let octx = ocas.getContext("2d");
let ctx = canvas.getContext("2d");
ocas.width = canvas.width = window.innerWidth;
ocas.height = canvas.height = window.innerHeight;
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
let maxRadius = 1,
stars = [];
let Star = function (x, y, r) {
let Star = function (x: number, y: number, r: number) {
this.x = x;
this.y = y;
this.r = r;
@@ -54,7 +50,7 @@ onMounted(() => {
drawBg()
function drawMoon() {
let moon = document.getElementById("moon");
let moon: HTMLImageElement = document.getElementById("moon");
let centerX = canvas.width - 200,
centerY = 100,
width = 80;

View File

@@ -1,8 +1,8 @@
<script setup lang="ts">
import {KeyboardOne} from "@icon-park/vue-next";
import Tooltip from "@/components/Tooltip.vue";
import {Icon} from "@iconify/vue";
const props = defineProps<{
defineProps<{
keyboard?: string,
active?: boolean
}>()
@@ -18,7 +18,7 @@ defineEmits(['click'])
:class="active && 'active'">
<span><slot></slot></span>
<div class="key-notice" v-if="keyboard">
<keyboard-one theme="outline" size="14" fill="#ffffff" :strokeWidth="2"/>
<Icon icon="bi:keyboard" width="14" color="#ffffff"/>
<span class="key">{{ keyboard }}</span>
</div>
</div>

View File

@@ -1,13 +1,13 @@
<script setup lang="ts">
import {ArrowLeft} from '@icon-park/vue-next'
import {Icon} from "@iconify/vue";
import {computed, inject} from "vue"
import WordList from "@/components/WordList.vue"
import {useBaseStore} from "@/stores/base.ts"
const store = useBaseStore()
const back = inject('back')
const stepIndex = inject('stepIndex')
const tabIndex = inject('tabIndex')
const back: () => void = inject('back')
const stepIndex: any = inject('stepIndex')
const tabIndex: any = inject('tabIndex')
const isActive = computed(() => {
return stepIndex.value === 2 && tabIndex.value === 0 && store.sideIsOpen
})
@@ -17,10 +17,10 @@ const isActive = computed(() => {
<template>
<div class="chapter-detail page">
<header>
<arrow-left @click="back" theme="outline" size="20" fill="#929596" :strokeWidth="2"/>
<Icon icon="octicon:arrow-right-24" @click="back" width="20" color="#929596"/>
<div class="dict-name">16.</div>
</header>
<WordList :isActive="isActive" :word-list="store.chapter" :activeIndex="store.wordIndex"></WordList>
<WordList :isActive="isActive" :list="store.chapter" :activeIndex="store.wordIndex"></WordList>
</div>
</template>

View File

@@ -2,8 +2,8 @@
import {Word} from "@/types.ts"
const props = defineProps<{
list: Word[],
defineProps<{
list: Word[][],
activeIndex: number
}>()
@@ -18,7 +18,7 @@ function next() {
<div class="list">
<div class="item" :class="activeIndex === index && 'active'"
v-for="(item,index) in list" @click="$emit('update:activeIndex', index)">
<div class="title">{{ index + 1 }} {{item.length}}</div>
<div class="title">{{ index + 1 }} {{ item.length }}</div>
</div>
</div>
</template>

View File

@@ -1,7 +1,7 @@
<script setup lang="ts">
import {inject} from "vue"
const next = inject('next')
const next: () => void = inject('next')
</script>

View File

@@ -3,7 +3,7 @@ export default {
render() {
let Vnode = this.$slots.default()[0]
return (
<div class="icon-wrapper">
<div class="icon-wrapper hvr-grow">
<Vnode
/>
</div>

View File

@@ -1,16 +1,18 @@
<script setup lang="ts">
import {Close} from "@icon-park/vue-next"
import {onMounted} from "vue";
import Tooltip from "@/components/Tooltip.vue";
import {Icon} from '@iconify/vue';
interface IProps {
modelValue: boolean,
showClose?: boolean,
title?: string,
subTitle?: string,
}
const props = withDefaults(defineProps<IProps>(), {
modelValue: true,
showClose: true,
})
const emit = defineEmits([
@@ -39,10 +41,11 @@ onMounted(() => {
<div class="modal-mask" @click="close"></div>
<div class="modal">
<Tooltip title="关闭">
<Close @click="close"
class="close"
theme="outline" size="20" fill="#929596"
:strokeWidth="2"/>
<Icon @click="close"
v-if="showClose"
class="close hvr-grow pointer"
width="20" color="#929596"
icon="ion:close-outline"/>
</Tooltip>
<div class="modal-header" v-if="props.title">
<div class="title">{{ props.title }}</div>

View File

@@ -1,7 +1,6 @@
<script setup lang="ts">
import Modal from "@/components/Modal/Modal.vue";
import {useBaseStore} from "@/stores/base.ts";
import {Like, ShareThree, Tea} from '@icon-park/vue-next'
import Ring from "@/components/Ring.vue";
import Tooltip from "@/components/Tooltip.vue";
import Fireworks from "@/components/Fireworks.vue";
@@ -9,7 +8,8 @@ import BaseButton from "@/components/BaseButton.vue";
import {DefaultStatistics, Statistics} from "@/types.ts";
import {emitter, EventKey} from "@/utils/eventBus.ts";
import {onMounted, reactive} from "vue";
import {cloneDeep} from "lodash";
import {cloneDeep} from "lodash-es";
import {Icon} from '@iconify/vue';
const store = useBaseStore()
let statModalIsOpen = $ref(false)
@@ -75,19 +75,16 @@ function next() {
</div>
<div class="notice" v-if="!store.current.originWrongWords.length">
<!-- <div class="notice">-->
<like theme="filled" size="20" fill="#ffffff" :strokeWidth="2"/>
<Icon class="hvr-grow pointer" icon="flat-color-icons:like" width="20" color="#929596"/>
表现不错全对了
</div>
</div>
<div class="shares">
<Tooltip title="分享给朋友">
<share-three theme="outline" size="20" fill="#929596" :strokeWidth="2"/>
<Icon class="hvr-grow pointer" icon="ph:share-light" width="20" color="#929596"/>
</Tooltip>
<Tooltip title="分享给朋友">
<tea theme="outline" size="20" fill="#929596" :strokeWidth="2"/>
</Tooltip>
<Tooltip title="分享给朋友">
<share-three theme="outline" size="20" fill="#929596" :strokeWidth="2"/>
<Tooltip title="请我喝杯咖啡">
<Icon class="hvr-grow pointer" icon="twemoji:teacup-without-handle" width="20" color="#929596"/>
</Tooltip>
</div>
</div>

View File

@@ -4,8 +4,8 @@ import {$computed, $ref} from "vue/macros"
import {onMounted, onUnmounted} from "vue"
import {useBaseStore} from "@/stores/base.ts"
import Tooltip from "@/components/Tooltip.vue"
import {Down} from "@icon-park/vue-next"
import {usePracticeStore} from "@/components/Practice/usePracticeStore.ts";
import {Icon} from "@iconify/vue";
const practiceStore = usePracticeStore()
const store = useBaseStore()
@@ -16,7 +16,7 @@ function format(val: number, suffix: string = '', check: number = -1) {
const progress = $computed(() => {
if (!practiceStore.total) return 0
if (practiceStore.inputNumber>practiceStore.total) return 100
if (practiceStore.inputNumber > practiceStore.total) return 100
return ((practiceStore.inputNumber / practiceStore.total) * 100)
})
@@ -37,11 +37,11 @@ onUnmounted(() => {
<template>
<div class="footer" :class="!store.setting.showToolbar && 'hide'">
<Tooltip :title="store.setting.showToolbar?'收起':'展开'">
<Down
@click="store.setting.showToolbar = !store.setting.showToolbar"
class="arrow"
:class="!store.setting.showToolbar && 'down'"
theme="outline" size="24" fill="#999"/>
<Icon icon="icon-park-outline:down"
@click="store.setting.showToolbar = !store.setting.showToolbar"
class="arrow"
:class="!store.setting.showToolbar && 'down'"
width="24" color="#999"/>
</Tooltip>
<div class="bottom">
<el-progress :percentage="progress"

View File

@@ -1,273 +0,0 @@
<script setup lang="ts">
import {computed, onMounted, onUnmounted, provide, watch} from "vue"
import 快速打字的机械键盘声音Mp3 from '../assets/sound/key-sounds/快速打字的机械键盘声音.mp3'
import 键盘快速打字的声音Mp3 from '../assets/sound/key-sounds/键盘快速打字的声音.mp3'
import 电话打字的声音Mp3 from '../assets/sound/key-sounds/电话打字的声音.mp3'
import 老式机械 from '../assets/sound/key-sounds/老式机械.mp3'
import 机械0 from '../assets/sound/key-sounds/jixie/机械0.mp3'
import 机械1 from '../assets/sound/key-sounds/jixie/机械1.mp3'
import 机械2 from '../assets/sound/key-sounds/jixie/机械2.mp3'
import 机械3 from '../assets/sound/key-sounds/jixie/机械3.mp3'
import beep from '../assets/sound/beep.wav'
import correct from '../assets/sound/correct.wav'
import {$computed, $ref} from "vue/macros"
import {useSound} from "@/hooks/useSound.ts"
import {useBaseStore} from "@/stores/base.ts"
import {DictType, SaveKey, ShortKeyMap, Word} from "../types";
import {usePlayWordAudio} from "@/hooks/usePlayWordAudio.ts"
import useTheme from "@/hooks/useTheme.ts";
import Tooltip from "@/components/Tooltip.vue";
import BaseButton from "@/components/BaseButton.vue";
import {
Down,
Delete,
} from "@icon-park/vue-next"
import {emitter, EventKey} from "@/utils/eventBus.ts"
import {cloneDeep} from "lodash"
let input = $ref('')
let wrong = $ref('')
let showFullWord = $ref(false)
let activeIndex = $ref(-1)
const store = useBaseStore()
// const [playKeySound, setAudio] = useSound([机械0, 机械1, 机械2, 机械3], 1)
// const [playKeySound, setAudio] = useSound([老式机械], 3)
const [playKeySound, setAudio] = useSound([电话打字的声音Mp3], 3)
const [playBeep] = useSound([beep], 1)
const [playCorrect] = useSound([correct], 1)
const [playAudio] = usePlayWordAudio()
interface IProps {
total: number,
startDate: number
inputNumber: number
wrongNumber: number
correctRate: number
}
const props = withDefaults(defineProps<IProps>(), {
total: 0,
startDate: Date.now(),
inputNumber: 0,
wrongNumber: 0,
correctRate: 0,
})
const resetWord = $computed(() => {
return store.word.name.slice(input.length + wrong.length)
})
onMounted(() => {
window.addEventListener('keydown', onKeyDown)
window.addEventListener('keyup', onKeyUp)
emitter.on(EventKey.resetWord, () => {
input = ''
})
})
onUnmounted(() => {
// console.log('onUnmounted')
window.removeEventListener('keydown', onKeyDown)
window.removeEventListener('keyup', onKeyUp)
})
function next() {
if (store.current.index === store.current.words.length - 1) {
if (store.current.wrongWords.length) {
store.setCurrentWord(store.current.wrongWords)
} else {
if (store.currentDict.chapterIndex !== store.currentDict.chapterWords.length - 1) {
console.log('这一章节完了')
emitter.emit(EventKey.openStatModal)
} else {
console.log('这本书完了')
emitter.emit(EventKey.openStatModal)
}
}
} else {
store.current.index++
console.log('这个词完了')
}
if ([DictType.customDict, DictType.innerDict].includes(store.current.dictType) && store.skipWordNames.includes(store.word.name.toLowerCase())) {
next()
}
if (store.current.index) {
store.current.statistics.wrongWordNumber = store.current.wrongWords.length
store.current.statistics.correctRate = Math.trunc(((store.current.index - store.current.wrongWords.length) / (store.current.index)) * 100)
} else {
store.current.statistics.wrongWordNumber = -1
store.current.statistics.correctRate = -1
}
wrong = input = ''
}
function onKeyUp(e: KeyboardEvent) {
showFullWord = false
}
async function onKeyDown(e: KeyboardEvent) {
//TODO 还有横杠
if ((e.keyCode >= 65 && e.keyCode <= 90) || e.code === 'Space') {
let letter = e.key
if ((input + letter).toLowerCase() === store.word.name.toLowerCase().slice(0, input.length + 1)) {
input += letter
wrong = ''
playKeySound()
} else {
if (!store.wrongWordDict.originWords.find((v: Word) => v.name.toLowerCase() === store.word.name.toLowerCase())) {
store.wrongWordDict.originWords.push(store.word)
store.wrongWordDict.words.push(store.word)
store.wrongWordDict.chapterWords = [store.wrongWordDict.words]
}
if (!store.current.wrongWords.find((v: Word) => v.name.toLowerCase() === store.word.name.toLowerCase())) {
store.current.wrongWords.push(store.word)
}
store.current.statistics.correctRate = Math.trunc(((store.current.index + 1 - store.current.wrongWords.length) / (store.current.index + 1)) * 100)
wrong = letter
playKeySound()
playBeep()
setTimeout(() => {
wrong = ''
// wrong = input = ''
}, 500)
}
if (input.toLowerCase() === store.word.name.toLowerCase()) {
playCorrect()
setTimeout(next, 300)
}
} else {
// console.log('e', e)
switch (e.key) {
case 'Backspace':
if (wrong) {
wrong = ''
} else {
input = input.slice(0, -1)
}
break
case ShortKeyMap.Collect:
if (!store.newWordDict.originWords.find((v: Word) => v.name === store.word.name)) {
store.newWordDict.originWords.push(store.word)
store.newWordDict.words.push(store.word)
store.newWordDict.chapterWords = [store.newWordDict.words]
}
activeIndex = 1
break
case ShortKeyMap.Remove:
if (!store.skipWordNames.includes(store.word.name)) {
store.skipWordDict.originWords.push(store.word)
store.skipWordDict.words.push(store.word)
store.skipWordDict.chapterWords = [store.skipWordDict.words]
}
activeIndex = 0
next()
break
case ShortKeyMap.Ignore:
e.preventDefault()
activeIndex = 2
next()
break
case ShortKeyMap.Show:
showFullWord = true
break
}
setTimeout(() => {
activeIndex = -1
}, 200)
}
}
const {toggle} = useTheme()
</script>
<template>
<div class="type-word">
<div class="translate">{{ store.word.trans.join('') }}</div>
<div class="word-wrapper">
<div class="word" :class="wrong && 'is-wrong'">
<span class="input" v-if="input">{{ input }}</span>
<span class="wrong" v-if="wrong">{{ wrong }}</span>
<template v-if="store.isDictation">
<span class="letter" v-if="!showFullWord"
@mouseenter="showFullWord = true">{{ resetWord.split('').map(v => '_').join('') }}</span>
<span class="letter" v-else @mouseleave="showFullWord = false">{{ resetWord }}</span>
</template>
<span class="letter" v-else>{{ resetWord }}</span>
</div>
<div class="audio" @click="playAudio(store.word.name)">播放</div>
</div>
<div class="phonetic">{{ store.word.usphone }}</div>
<div class="options">
<BaseButton keyboard="`" :active="activeIndex === 0">
忽略
</BaseButton>
<BaseButton keyboard="Enter" :active="activeIndex === 1">
收藏
</BaseButton>
<BaseButton keyboard="Tab" :active="activeIndex === 2">
下一个
</BaseButton>
</div>
</div>
</template>
<style scoped lang="scss">
@import "@/assets/css/colors.scss";
.type-word {
display: flex;
//display: none;
align-items: center;
justify-content: center;
flex-direction: column;
font-size: 14rem;
color: gray;
gap: 2rem;
.options {
margin-top: 10rem;
display: flex;
gap: 15rem;
font-size: 18rem;
}
.phonetic, .translate {
font-size: 20rem;
margin-left: -30rem;
}
.word-wrapper {
display: flex;
align-items: center;
gap: 10rem;
.word {
font-size: 48rem;
line-height: 1;
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace;
letter-spacing: 5rem;
.input {
color: rgb(22, 163, 74);
}
.wrong {
color: rgba(red, 0.6);
}
&.is-wrong {
animation: shake 0.82s cubic-bezier(0.36, 0.07, 0.19, 0.97) both;
}
}
}
}
</style>

View File

@@ -2,7 +2,7 @@
import {usePlayWordAudio} from "@/hooks/usePlayWordAudio.ts"
import {computed, nextTick, onMounted, reactive, watch} from "vue"
import {cloneDeep} from "lodash"
import {cloneDeep} from "lodash-es"
import 快速打字的机械键盘声音Mp3 from '../..//assets/sound/key-sounds/快速打字的机械键盘声音.mp3'
import 键盘快速打字的声音Mp3 from '../..//assets/sound/key-sounds/键盘快速打字的声音.mp3'
import 电话打字的声音Mp3 from '../..//assets/sound/key-sounds/电话打字的声音.mp3'
@@ -500,6 +500,7 @@ function otherWord(word: ArticleWord, i: number, i2: number, i3: number) {
}
.article-wrapper {
opacity: 0;
header {
.title {
@@ -508,6 +509,7 @@ function otherWord(word: ArticleWord, i: number, i2: number, i3: number) {
font-size: 36rem;
font-weight: 500;
word-spacing: 3rem;
opacity: 0;
}
.options {
@@ -528,6 +530,7 @@ function otherWord(word: ArticleWord, i: number, i2: number, i3: number) {
.article-content {
position: relative;
opacity: 0;
}
article {

View File

@@ -18,12 +18,8 @@ import {usePlayWordAudio} from "@/hooks/usePlayWordAudio.ts"
import useTheme from "@/hooks/useTheme.ts";
import Tooltip from "@/components/Tooltip.vue";
import BaseButton from "@/components/BaseButton.vue";
import {
Down,
Delete,
} from "@icon-park/vue-next"
import {emitter, EventKey} from "@/utils/eventBus.ts"
import {cloneDeep} from "lodash"
import {cloneDeep} from "lodash-es"
import {usePracticeStore} from "@/components/Practice/usePracticeStore.ts"
import {useEventListener} from "@/hooks/useEvent.ts";
@@ -66,7 +62,7 @@ watchEffect(() => {
practiceStore.inputNumber = 0
practiceStore.wrongNumber = 0
practiceStore.repeatNumber = 0
practiceStore.total = props.words.length
practiceStore.total = props.words.length
practiceStore.wrongWords = []
practiceStore.startDate = Date.now()
})

View File

@@ -1,15 +1,15 @@
<script setup lang="ts">
import {childrenEnglish} from '@/assets/dictionary.ts'
import {ArrowLeft, ArrowRight, Close} from '@icon-park/vue-next'
import {useBaseStore} from "@/stores/base.ts"
import {watch} from "vue"
import {Dict, DictType, Sort, Word} from "@/types.ts"
import {chunk} from "lodash";
import {chunk} from "lodash-es";
import {$computed, $ref} from "vue/macros";
import WordList from "@/components/WordList.vue";
import ChapterList from "@/components/ChapterList.vue"
import Modal from "@/components/Modal/Modal.vue";
import BaseButton from "@/components/BaseButton.vue";
import {Icon} from '@iconify/vue';
const store = useBaseStore()
@@ -29,7 +29,7 @@ let currentSelectDict: Dict = $ref(store.currentDict)
let step = $ref(0)
const currentSelectChapter: Word[] = $computed(() => {
return currentSelectDict.chapterList?.[currentSelectDict.chapterIndex] ?? []
return currentSelectDict.chapterWords?.[currentSelectDict.chapterIndex] ?? []
})
watch(() => props.modelValue, (n: boolean) => {
@@ -39,19 +39,21 @@ watch(() => props.modelValue, (n: boolean) => {
async function selectDict(item: Dict) {
currentSelectDict = {
...item,
type: DictType.innerDict,
sort: Sort.normal,
wordList: [],
chapterList: [],
chapterIndex: 0,
type: DictType.innerDict,
originWords: [],
words: [],
chapterWordNumber: 15,
wordIndex: 0,
dictStatistics: []
chapterWords: [],
chapterIndex: 0,
chapterWordIndex: 0,
statistics: []
}
let r = await fetch(`/public/${item.url}`)
r.json().then(v => {
currentSelectDict.wordList = v
currentSelectDict.chapterList = chunk(v, currentSelectDict.chapterWordNumber)
currentSelectDict.originWords = v
currentSelectDict.words = v
currentSelectDict.chapterWords = chunk(v, currentSelectDict.chapterWordNumber)
})
}
@@ -66,16 +68,17 @@ function close() {
}
function resetChapterList() {
currentSelectDict.chapterList = chunk(currentSelectDict.wordList, currentSelectDict.chapterWordNumber)
currentSelectDict.chapterWords = chunk(currentSelectDict.words, currentSelectDict.chapterWordNumber)
}
</script>
<template>
<Modal :modelValue="props.modelValue"
:show-close="false"
@close="close">
<div class="slide">
<div class="slide-list" :class="`step${step}`">
<div class="dict-page">
<div class="slide-list" :class="`step${step}`">
<div class="dict-page">
<header>
<div class="tabs">
<div class="tab">
@@ -88,7 +91,10 @@ function resetChapterList() {
<span>德语</span>
</div>
</div>
<Close @click="close" theme="outline" size="20" fill="#929596" :strokeWidth="2"/>
<Icon @click="close"
class="hvr-grow pointer"
width="20" color="#929596"
icon="ion:close-outline"/>
</header>
<div class="page-content">
<div class="dict-list-wrapper">
@@ -104,11 +110,9 @@ function resetChapterList() {
<div class="desc">{{ i.description }}</div>
<div class="num">{{ i.length }}</div>
<arrow-right v-if="currentSelectDict.name === i.name"
@click.stop="step = 1"
class="go"
theme="outline" size="20" fill="#ffffff"
:strokeWidth="2"/>
<Icon icon="octicon:arrow-right-24" v-if="currentSelectDict.name === i.name"
@click.stop="step = 1"
class="go" width="20" color="#929596"/>
</div>
</div>
</div>
@@ -125,7 +129,7 @@ function resetChapterList() {
</div>
<ChapterList
class="chapter-list"
:list="currentSelectDict.chapterList"
:list="currentSelectDict.chapterWords"
v-model:active-index="currentSelectDict.chapterIndex"
/>
<div class="footer">
@@ -134,19 +138,20 @@ function resetChapterList() {
</div>
</div>
</div>
<div class="dict-detail-page">
<div class="dict-detail-page">
<header>
<div class="left">
<arrow-left
@click="step = 0"
class="go" theme="outline" size="20" fill="#ffffff"
:strokeWidth="2"/>
<Icon icon="octicon:arrow-left-24"
@click.stop="step = 0"
class="go" width="20" color="#ffffff"/>
<div class="title">
词典详情
</div>
</div>
<Close @click="close" theme="outline" size="20" fill="#929596"
:strokeWidth="2"/>
<Icon @click="close"
class="hvr-grow pointer"
width="20" color="#929596"
icon="ion:close-outline"/>
</header>
<div class="page-content">
<div class="dict-info">
@@ -157,7 +162,7 @@ function resetChapterList() {
</div>
</div>
<div class="chapter-wrapper">
<ChapterList :list="currentSelectDict.chapterList"
<ChapterList :list="currentSelectDict.chapterWords"
v-model:active-index="currentSelectDict.chapterIndex"
/>
</div>

View File

@@ -1,6 +1,5 @@
<script setup lang="ts">
import Modal from "@/components/Modal/Modal.vue"
import {HeadphoneSound, SettingConfig} from "@icon-park/vue-next"
import {useBaseStore} from "@/stores/base.ts"
import BaseButton from "@/components/BaseButton.vue";
import {GITHUB} from "@/config/ENV.ts";

View File

@@ -1,7 +1,7 @@
<script setup lang="ts">
import Modal from "@/components/Modal/Modal.vue"
import {HeadphoneSound, SettingConfig} from "@icon-park/vue-next"
import {useBaseStore} from "@/stores/base.ts"
import {Icon} from '@iconify/vue';
const tabIndex = $ref(0)
const store = useBaseStore()
@@ -27,11 +27,11 @@ const emit = defineEmits([
<div class="setting-modal">
<div class="tabs">
<div class="tab" :class="tabIndex === 0 && 'active'" @click="tabIndex = 0">
<headphone-sound theme="filled" size="20" fill="#0C8CE9" :strokeWidth="2"/>
<Icon icon="bx:headphone" width="20" color="#0C8CE9"/>
<span>音效设置</span>
</div>
<div class="tab" :class="tabIndex === 1 && 'active'" @click="tabIndex = 1">
<setting-config theme="filled" size="20" fill="#0C8CE9" :strokeWidth="2"/>
<Icon icon="icon-park-outline:setting-config" width="20" color="#0C8CE9"/>
<span>其他设置</span>
</div>
</div>
@@ -239,6 +239,9 @@ const emit = defineEmits([
cursor: pointer;
padding: 10rem 15rem;
border-radius: 8rem;
display: flex;
align-items: center;
gap: 10rem;
&.active {
background: whitesmoke;

View File

@@ -1,36 +1,14 @@
<script setup lang="ts">
import Tooltip from "@/components/Tooltip.vue"
import {
DatabaseFail,
Down,
MenuFold,
Moon,
PreviewCloseOne,
PreviewOpen,
SettingTwo,
SunOne,
VolumeNotice,
Bug,
UploadOne
} from "@icon-park/vue-next"
import useTheme from "@/hooks/useTheme.ts"
import {useBaseStore} from "@/stores/base.ts"
import SettingModal from "@/components/Toolbar/SettingModal.vue"
import FeedbackModal from "@/components/Toolbar/FeedbackModal.vue"
import DictModal from "@/components/Toolbar/DictModal.vue"
import {Icon} from '@iconify/vue';
import IconWrapper from "@/components/IconWrapper.vue";
import IconCog6Tooth from '~icons/heroicons/cog-6-tooth-solid'
import IconLanguage from '~icons/tabler/language'
import IconLanguageOff from '~icons/tabler/language-off'
import IconEye from '~icons/heroicons/eye-solid'
import IconCheck from '~icons/tabler/check'
import IconEyeSlash from '~icons/heroicons/eye-slash-solid'
import IconRepeat from '~icons/tabler/repeat'
import IconRepeatOff from '~icons/tabler/repeat-off'
import {emitter, EventKey} from "@/utils/eventBus.ts"
import {watch} from "vue"
@@ -56,69 +34,69 @@ watch(() => store.setting.showToolbar, n => {
<template>
<header ref="headerRef">
<div class="info" @click="showDictModal = true">
{{ store.dictTitle }}
{{ store.dictTitle }}
</div>
<div class="options">
<Tooltip title="切换主题">
<IconWrapper>
<moon v-if="store.theme === 'dark'"
<Icon icon="ep:moon" v-if="store.theme === 'dark'"
@click="toggle"/>
<sun-one v-else @click="toggle"/>
<Icon icon="tabler:sun" v-else @click="toggle"/>
</IconWrapper>
</Tooltip>
<Tooltip title="音效设置">
<IconWrapper>
<volume-notice/>
<Icon icon="icon-park-outline:volume-notice"/>
</IconWrapper>
</Tooltip>
<Tooltip title="设置单词循环">
<IconWrapper>
<IconRepeat></IconRepeat>
<Icon icon="tabler:repeat"/>
</IconWrapper>
</Tooltip>
<Tooltip title="开关默写模式">
<IconWrapper>
<IconEyeSlash v-if="store.isDictation" @click="store.isDictation = false"></IconEyeSlash>
<IconEye v-else @click="store.isDictation = true"></IconEye>
<Icon icon="majesticons:eye-off-line" v-if="store.isDictation" @click="store.isDictation = false"/>
<Icon icon="mdi:eye-outline" v-else @click="store.isDictation = true"/>
</IconWrapper>
</Tooltip>
<Tooltip title="开关释义显示">
<IconWrapper>
<IconLanguage></IconLanguage>
<!-- <IconLanguageOff></IconLanguageOff>-->
<Icon icon="heroicons-outline:translate"/>
</IconWrapper>
</Tooltip>
<Tooltip title="反馈">
<IconWrapper>
<upload-one/>
<Icon icon="ic:outline-cloud-upload"/>
</IconWrapper>
</Tooltip>
<Tooltip title="反馈">
<IconWrapper>
<bug @click="showFeedbackModal = true"/>
<Icon icon="octicon:bug-24" @click="showFeedbackModal = true"/>
</IconWrapper>
</Tooltip>
<Tooltip title="设置">
<IconWrapper>
<IconCog6Tooth @click="showSettingModal = true"></IconCog6Tooth>
<Icon icon="uil:setting" @click="showSettingModal = true"/>
</IconWrapper>
</Tooltip>
<div class="my-button" @click="emitter.emit(EventKey.openStatModal)">ok</div>
<Tooltip title="单词本">
<IconWrapper>
<menu-fold class="menu" @click="emitter.emit(EventKey.openSide)"/>
<Icon icon="tdesign:menu-unfold" class="menu" @click="emitter.emit(EventKey.openSide)"/>
</IconWrapper>
</Tooltip>
</div>
<Tooltip :title="store.setting.showToolbar?'收起':'展开'">
<down
@click="store.setting.showToolbar = !store.setting.showToolbar"
class="arrow"
:class="!store.setting.showToolbar && 'down'"
theme="outline" size="24" fill="#999"/>
<Icon icon="icon-park-outline:down"
@click="store.setting.showToolbar = !store.setting.showToolbar"
class="arrow"
:class="!store.setting.showToolbar && 'down'"
width="24" color="#999"/>
</Tooltip>
</header>
<DictModal v-model="showDictModal"/>

View File

@@ -3,7 +3,7 @@ import {Word} from "../types";
import {usePlayWordAudio} from "../hooks/usePlayWordAudio";
import {watch} from "vue"
import {useBaseStore} from "@/stores/base.ts"
import {Delete} from "@icon-park/vue-next"
import {Icon} from '@iconify/vue';
const store = useBaseStore()
const emit = defineEmits(['change'])
@@ -53,7 +53,7 @@ watch(() => props.list, () => {
</div>
<div class="right">
<div class="audio" @click="playAudio(item.name)">播放</div>
<delete theme="outline" size="20" fill="#929596" :strokeWidth="2"/>
<Icon icon="fluent:delete-28-regular" width="20" color="#929596"/>
</div>
</div>
</template>