Perfect panel

This commit is contained in:
zyronon
2023-10-02 22:03:05 +08:00
parent 0d33096a57
commit b4b2de86e5
6 changed files with 123 additions and 43 deletions

2
components.d.ts vendored
View File

@@ -54,6 +54,8 @@ declare module 'vue' {
TypeWord: typeof import('./src/components/Practice/TypeWord.vue')['default']
VolumeIcon: typeof import('./src/components/VolumeIcon.vue')['default']
VolumeSetting: typeof import('./src/components/Toolbar/VolumeSetting.vue')['default']
Word: typeof import('./src/components/Word.vue')['default']
WordItem: typeof import('./src/components/WordItem.vue')['default']
WordList: typeof import('./src/components/WordList.vue')['default']
}
}

View File

@@ -36,34 +36,23 @@ watch(() => settingStore.showPanel, n => {
})
const newWordDictActiveIndex = computed(() => {
if (store.current.dictType !== DictType.newDict) return -1
else {
if (store.current.repeatNumber) {
return store.chapter.findIndex(v => v.name === store.word.name)
}
return store.current.index
}
else return props.index
})
const wrongWordDictActiveIndex = computed(() => {
if (store.current.dictType !== DictType.wrongDict) return -1
else {
if (store.current.repeatNumber) {
return store.chapter.findIndex(v => v.name === store.word.name)
}
return store.current.index
}
else return props.index
})
const skipWordDictActiveIndex = computed(() => {
if (store.current.dictType !== DictType.skipDict) return -1
else {
if (store.current.repeatNumber) {
return store.chapter.findIndex(v => v.name === store.word.name)
}
return store.current.index
}
else return props.index
})
function changeIndex(i: number) {
}
</script>
<template>
<Transition name="fade">
@@ -83,7 +72,7 @@ const skipWordDictActiveIndex = computed(() => {
<div class="slide-list" :class="`step${tabIndex}`">
<div class="slide-item">
<header>
<div class="dict-name">{{ store.currentDict.chapterIndex + 1 }}.</div>
<div class="dict-name">词数{{ props.list.length }}</div>
</header>
<div class="content">
<WordList
@@ -237,11 +226,12 @@ $header-height: 50rem;
.panel {
position: fixed;
left: 0;
top: 0;
top: 10rem;
border-radius: 8rem;
margin-left: calc(50% + (var(--toolbar-width) / 2) + $space);
width: $width;
background: var(--color-second-bg);
height: 100%;
height: calc(100% - 40rem);
display: flex;
flex-direction: column;
transition: all .3s;

View File

@@ -68,7 +68,7 @@ useWatchAllSound()
<div class="row">
<label class="sub-title">倍速</label>
<div class="wrapper">
<el-slider v-model="settingStore.wordSoundSpeed" :step="0.1" :min="1" :max="4"/>
<el-slider v-model="settingStore.wordSoundSpeed" :step="0.1" :min="0.5" :max="4"/>
<span>{{ settingStore.wordSoundSpeed }}</span>
</div>
</div>

View File

@@ -114,7 +114,6 @@ header {
width: var(--toolbar-width);
margin-top: 10rem;
background: var(--color-header-bg);
border-radius: 8rem;
margin-bottom: 30rem;
//position: absolute;

View File

@@ -0,0 +1,96 @@
<script setup lang="ts">
import VolumeIcon from "@/components/VolumeIcon.vue";
import {Icon} from "@iconify/vue";
import {usePlayWordAudio} from "@/hooks/sound.ts";
import {Word} from "@/types.ts";
const playWordAudio = usePlayWordAudio()
const props = defineProps<{
word: Word,
active?: boolean
}>()
const emit = defineEmits<{
del: []
}>()
</script>
<template>
<div class="word-item"
:class="{active}">
<div class="left">
<div class="title">
<span class="word">{{ word.name }}</span>
<span class="phonetic">{{ word.usphone }}</span>
</div>
<div class="translate">{{ word.trans.join('') }}</div>
</div>
<div class="right">
<VolumeIcon @click="playWordAudio(word.name)"></VolumeIcon>
<div class="del"
@click="emit('del')"
>
<Icon
icon="fluent:delete-28-regular"
width="20"
color="#929596"/>
</div>
</div>
</div>
</template>
<style scoped lang="scss">
@import "@/assets/css/colors";
.word-item {
background: var(--color-header-bg);
border-radius: 6rem;
padding: 12rem;
display: flex;
justify-content: space-between;
transition: all .3s;
color: var(--color-font-1);
&.active {
background: $second;
color: white;
}
&:hover {
//background: $dark-main-bg;
//background: $item-hover;
background: rgb(226, 226, 226);
}
.left {
.title {
display: flex;
align-items: center;
gap: 10rem;
.word {
font-size: 24rem;
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace;
display: flex;
}
.phonetic {
font-size: 14rem;
color: gray;
}
}
}
.right {
display: flex;
align-items: center;
flex-direction: column;
gap: 5rem;
.del {
cursor: pointer;
}
}
}
</style>

View File

@@ -1,19 +1,20 @@
<script setup lang="ts">
import {Word} from "../types";
import {watch} from "vue"
import {useBaseStore} from "@/stores/base.ts"
import {Icon} from '@iconify/vue';
import {usePlayWordAudio} from "@/hooks/sound.ts";
import {useSettingStore} from "@/stores/setting.ts";
import WordItem from "@/components/WordItem.vue";
const store = useBaseStore()
const emit = defineEmits(['change'])
const settingStore = useSettingStore()
const emit = defineEmits<{
del: [i: number],
change: [i: number]
}>()
const props = defineProps<{
list: Word[],
activeIndex: number,
isActive: boolean
}>()
const playWordAudio = usePlayWordAudio()
const listRef: HTMLElement = $ref(null as any)
function scrollViewToCenter(index: number) {
@@ -22,7 +23,7 @@ function scrollViewToCenter(index: number) {
}
watch(() => props.activeIndex, (n: any) => {
if (store.sideIsOpen) {
if (settingStore.showPanel) {
scrollViewToCenter(n)
}
})
@@ -43,19 +44,11 @@ watch(() => props.list, () => {
<div class="list" ref="listRef">
<TransitionGroup name="list">
<template v-for="(item,i) in list" :key="i">
<div class="item" @click="$emit('change',i)" :class="activeIndex === i && 'active'">
<div class="left">
<div class="letter">{{ item.name }}</div>
<div class="info">
<div class="translate">{{ item.trans.join('') }}</div>
<div class="phonetic">{{ item.usphone }}</div>
</div>
</div>
<div class="right">
<div class="audio" @click="playWordAudio(item.name)">播放</div>
<Icon icon="fluent:delete-28-regular" width="20" color="#929596"/>
</div>
</div>
<WordItem
@click="emit('change',i)"
@del="emit('del',i)"
:active="activeIndex === i"
:word="item"/>
</template>
</TransitionGroup>
</div>