Skip to content

Commit 9345805

Browse files
committed
✨ feat: 优化歌词组件和移动端界面设计
1 parent 6f1909a commit 9345805

File tree

12 files changed

+85
-136
lines changed

12 files changed

+85
-136
lines changed

src/renderer/components/lyric/LyricCorrectionControl.vue

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const { t } = useI18n();
1414

1515
<template>
1616
<div
17-
class="lyric-correction-btns-mac absolute right-0 bottom-4 flex flex-col items-center space-y-1 z-50 select-none transition-opacity duration-200 opacity-0 pointer-events-none"
17+
class="lyric-correction"
1818
>
1919
<n-tooltip placement="right">
2020
<template #trigger>
@@ -46,8 +46,18 @@ const { t } = useI18n();
4646
</div>
4747
</template>
4848

49-
<style scoped>
49+
<style scoped lang="scss">
50+
.lyric-correction {
51+
@apply absolute right-0 bottom-4 flex flex-col items-center space-y-1 z-50 select-none transition-opacity duration-200 opacity-0 pointer-events-none;
52+
}
53+
5054
.lyric-correction-btn {
5155
@apply w-7 h-7 flex items-center justify-center rounded-lg bg-white dark:bg-neutral-800 border border-white/20 dark:border-neutral-700/40 shadow-md backdrop-blur-2xl cursor-pointer transition-all duration-150 text-gray-700 dark:text-gray-200 hover:bg-green-500/80 hover:text-white hover:border-green-400/60 active:scale-95 bg-opacity-40 dark:hover:bg-green-500/80 dark:hover:text-white dark:hover:border-green-400/60 dark:hover:bg-opacity-40;
5256
}
57+
58+
.mobile{
59+
.lyric-correction {
60+
@apply opacity-100;
61+
}
62+
}
5363
</style>

src/renderer/components/lyric/LyricSettings.vue

Lines changed: 0 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -114,47 +114,6 @@
114114
</div>
115115
</div>
116116
</n-tab-pane>
117-
118-
<!-- 移动端设置 -->
119-
<n-tab-pane :name="'mobile'" :tab="t('settings.lyricSettings.tabs.mobile')">
120-
<div class="tab-content" v-if="isMobile">
121-
<div class="section-title">{{ t('settings.lyricSettings.mobileLayout') }}</div>
122-
<n-radio-group v-model:value="config.mobileLayout" name="mobileLayout" class="mb-4">
123-
<n-space>
124-
<n-radio value="default">{{ t('settings.lyricSettings.layoutOptions.default') }}</n-radio>
125-
<n-radio value="ios">{{ t('settings.lyricSettings.layoutOptions.ios') }}</n-radio>
126-
<n-radio value="android">{{ t('settings.lyricSettings.layoutOptions.android') }}</n-radio>
127-
</n-space>
128-
</n-radio-group>
129-
130-
<div class="section-title">{{ t('settings.lyricSettings.mobileCoverStyle') }}</div>
131-
<n-radio-group v-model:value="config.mobileCoverStyle" name="mobileCoverStyle" class="mb-4">
132-
<n-space>
133-
<n-radio value="record">{{ t('settings.lyricSettings.coverOptions.record') }}</n-radio>
134-
<n-radio value="square">{{ t('settings.lyricSettings.coverOptions.square') }}</n-radio>
135-
<n-radio value="full">{{ t('settings.lyricSettings.coverOptions.full') }}</n-radio>
136-
</n-space>
137-
</n-radio-group>
138-
139-
<div class="slider-item">
140-
<span>{{ t('settings.lyricSettings.lyricLines') }}</span>
141-
<n-slider
142-
v-model:value="config.mobileShowLyricLines"
143-
:step="1"
144-
:min="1"
145-
:max="5"
146-
:marks="{
147-
1: '1',
148-
3: '3',
149-
5: '5'
150-
}"
151-
/>
152-
</div>
153-
</div>
154-
<div v-else class="mobile-unavailable">
155-
{{ t('settings.lyricSettings.mobileUnavailable') }}
156-
</div>
157-
</n-tab-pane>
158117
</n-tabs>
159118
</div>
160119
</div>
@@ -165,7 +124,6 @@ import { onMounted, ref, watch } from 'vue';
165124
import { useI18n } from 'vue-i18n';
166125
167126
import { DEFAULT_LYRIC_CONFIG, LyricConfig } from '@/types/lyric';
168-
import { isMobile } from '@/utils';
169127
170128
const { t } = useI18n();
171129
const config = ref<LyricConfig>({ ...DEFAULT_LYRIC_CONFIG });

src/renderer/components/lyric/MusicFullMobile.vue

Lines changed: 60 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,6 @@
2121
<i class="ri-arrow-down-s-line"></i>
2222
</div>
2323

24-
<n-popover trigger="click" placement="bottom">
25-
<template #trigger>
26-
<div
27-
class="control-btn absolute top-5 right-5"
28-
:class="{ 'pure-mode': config.pureModeEnabled }"
29-
>
30-
<i class="ri-settings-3-line"></i>
31-
</div>
32-
</template>
33-
<lyric-settings ref="lyricSettingsRef" />
34-
</n-popover>
35-
3624
<!-- 全屏歌词页面 -->
3725
<transition name="fade">
3826
<div
@@ -102,7 +90,7 @@
10290
</div>
10391
</div>
10492

105-
<div class="px-2">
93+
<div class="px-2 flex-1 flex flex-col justify-around">
10694
<!-- 歌曲信息 -->
10795
<div class="song-info">
10896
<h1 class="song-title">{{ playMusic.name }}</h1>
@@ -128,9 +116,6 @@
128116
<div v-if="lrcArray.length > 0" class="lyrics-wrapper">
129117
<div v-for="(line, idx) in visibleLyrics" :key="idx" class="lyric-line">
130118
{{ line.text }}
131-
<div v-if="config.showTranslation && line.trText" class="translation">
132-
{{ line.trText }}
133-
</div>
134119
</div>
135120
</div>
136121
<div v-else class="no-lyrics">
@@ -198,7 +183,6 @@
198183
import { computed, onBeforeUnmount, onMounted, ref, watch, nextTick } from 'vue';
199184
import { useI18n } from 'vue-i18n';
200185
201-
import LyricSettings from '@/components/lyric/LyricSettings.vue';
202186
import {
203187
allTime,
204188
artistList,
@@ -459,13 +443,12 @@ const handleThumbTouchEnd = () => {
459443
const currentBackground = ref('');
460444
const animationFrame = ref<number | null>(null);
461445
const isDark = ref(false);
462-
const lyricSettingsRef = ref<InstanceType<typeof LyricSettings>>();
463446
const config = ref<LyricConfig>({ ...DEFAULT_LYRIC_CONFIG });
464447
465448
// 可见歌词计算
466449
const visibleLyrics = computed(() => {
467-
const centerIndex = nowIndex.value + 1;
468-
const numLines = config.value.mobileShowLyricLines;
450+
const centerIndex = nowIndex.value;
451+
const numLines = 3;
469452
const halfLines = Math.floor(numLines / 2);
470453
471454
let startIdx = centerIndex - halfLines;
@@ -490,29 +473,6 @@ const visibleLyrics = computed(() => {
490473
return lrcArray.value.slice(startIdx, endIdx + 1);
491474
});
492475
493-
// 监听设置组件的配置变化
494-
watch(
495-
() => lyricSettingsRef.value?.config,
496-
(newConfig) => {
497-
if (newConfig) {
498-
config.value = newConfig;
499-
}
500-
},
501-
{ deep: true, immediate: true }
502-
);
503-
504-
// 监听本地配置变化,保存到 localStorage
505-
watch(
506-
() => config.value,
507-
(newConfig) => {
508-
localStorage.setItem('music-full-config', JSON.stringify(newConfig));
509-
if (lyricSettingsRef.value) {
510-
lyricSettingsRef.value.config = newConfig;
511-
}
512-
},
513-
{ deep: true }
514-
);
515-
516476
const props = defineProps({
517477
modelValue: {
518478
type: Boolean,
@@ -802,6 +762,7 @@ defineExpose({
802762
padding-top: 100px;
803763
padding-bottom: 200px;
804764
margin-bottom: 180px; /* 确保底部留出足够空间 */
765+
margin-top: 90px;
805766
806767
.lyrics-padding-top {
807768
height: 70px;
@@ -911,11 +872,11 @@ defineExpose({
911872
@apply w-10 h-10 flex items-center justify-center cursor-pointer transition-all duration-200;
912873
913874
i {
914-
@apply text-xl;
875+
@apply text-2xl;
915876
color: var(--text-color-primary);
916877
917878
&.favorite {
918-
@apply text-red-500;
879+
@apply text-red-500 !important;
919880
}
920881
}
921882
@@ -930,7 +891,7 @@ defineExpose({
930891
@apply w-14 h-14 flex items-center justify-center cursor-pointer transition-all duration-200;
931892
932893
i {
933-
@apply text-2xl;
894+
@apply text-3xl;
934895
color: var(--text-color-primary);
935896
}
936897
@@ -963,7 +924,7 @@ defineExpose({
963924
964925
// 封面样式
965926
.cover-container {
966-
@apply relative mb-6 transition-all duration-500;
927+
@apply relative mb-6 transition-all duration-500 border-gray-900;
967928
968929
&.style-changing {
969930
animation: styleChange 0.5s ease;
@@ -974,10 +935,58 @@ defineExpose({
974935
}
975936
976937
&.record-style {
977-
@apply w-72 h-72 rounded-full overflow-hidden;
938+
@apply w-72 h-72 rounded-full overflow-hidden relative;
939+
940+
// 唱片外圈装饰
941+
&::before {
942+
content: '';
943+
@apply absolute top-0 left-0 w-full h-full rounded-full z-10;
944+
background: radial-gradient(circle at center,
945+
transparent 38%,
946+
rgba(0, 0, 0, 0.15) 38%,
947+
rgba(0, 0, 0, 0.15) 39%,
948+
rgba(255, 255, 255, 0.1) 39%,
949+
rgba(255, 255, 255, 0.1) 39.5%,
950+
rgba(0, 0, 0, 0.08) 39.5%,
951+
rgba(0, 0, 0, 0.08) 40.5%,
952+
rgba(0, 0, 0, 0.2) 40.5%,
953+
rgba(0, 0, 0, 0.2) 41.5%,
954+
rgba(0, 0, 0, 0.6) 41.5%,
955+
rgba(0, 0, 0, 0.6) 100%);
956+
pointer-events: none;
957+
animation: spin 20s linear infinite;
958+
animation-play-state: running;
959+
}
960+
961+
&.paused {
962+
&::before, &::after {
963+
animation-play-state: paused;
964+
}
965+
}
966+
967+
.img-wrapper {
968+
@apply rounded-full overflow-hidden border-[40px] border-solid border-black z-0;
969+
width: 90%;
970+
height: 90%;
971+
position: absolute;
972+
top: 50%;
973+
left: 50%;
974+
transform: translate(-50%, -50%);
975+
976+
// 光泽效果
977+
&::after {
978+
content: '';
979+
@apply absolute top-0 left-0 w-full h-full rounded-full z-[2];
980+
background: linear-gradient(135deg,
981+
rgba(255, 255, 255, 0.05) 0%,
982+
rgba(255, 255, 255, 0) 50%,
983+
rgba(0, 0, 0, 0.05) 100%);
984+
pointer-events: none;
985+
}
986+
}
978987
979988
.cover-image {
980-
@apply w-full h-full rounded-full;
989+
@apply w-full h-full rounded-full border-[5px] border-gray-900;
981990
animation: spin 20s linear infinite;
982991
animation-play-state: running;
983992
}
@@ -988,10 +997,10 @@ defineExpose({
988997
}
989998
990999
&.square-style {
991-
@apply w-72 h-72;
1000+
@apply w-72 h-72 shadow-lg rounded-xl overflow-hidden mt-8;
9921001
9931002
.cover-image {
994-
@apply w-full h-full rounded-xl shadow-lg;
1003+
@apply w-full h-full;
9951004
transition: transform 0.3s ease-out;
9961005
9971006
&:active {

src/renderer/layout/components/MusicFullWrapper.vue renamed to src/renderer/components/lyric/MusicFullWrapper.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<script setup lang="ts">
66
import { computed } from 'vue';
77
import { isMobile } from '@/utils';
8-
import MusicFull from '@/layout/components/MusicFull.vue';
8+
import MusicFull from '@/components/lyric/MusicFull.vue';
99
import MusicFullMobile from '@/components/lyric/MusicFullMobile.vue';
1010
1111
// 根据当前设备类型选择需要显示的组件

src/renderer/components/player/MobilePlayBar.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ import { useThrottleFn } from '@vueuse/core';
113113
import { computed, ref, watch } from 'vue';
114114
115115
import { allTime, artistList, nowTime, playMusic, sound, textColors } from '@/hooks/MusicHook';
116-
import MusicFullWrapper from '@/layout/components/MusicFullWrapper.vue';
116+
import MusicFullWrapper from '@/components/lyric/MusicFullWrapper.vue';
117117
import { usePlayerStore } from '@/store/modules/player';
118118
import { useSettingsStore } from '@/store/modules/settings';
119119
import { getImgUrl, secondToMinute, setAnimationClass } from '@/utils';

src/renderer/components/player/PlayBar.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ import {
169169
textColors
170170
} from '@/hooks/MusicHook';
171171
import { useArtist } from '@/hooks/useArtist';
172-
import MusicFullWrapper from '@/layout/components/MusicFullWrapper.vue';
172+
import MusicFullWrapper from '@/components/lyric/MusicFullWrapper.vue';
173173
import { audioService } from '@/services/audioService';
174174
import {
175175
isBilibiliIdMatch,

src/renderer/layout/components/SearchBar.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ const restartApp = () => {
203203
};
204204
205205
const toLogin = () => {
206-
router.push('/login');
206+
router.push('/user');
207207
};
208208
209209
// 页面初始化

src/renderer/layout/components/lrcFull.vue

Lines changed: 0 additions & 24 deletions
This file was deleted.

src/renderer/router/home.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ const layoutRouter = [
8484
title: '设置',
8585
icon: 'ri-settings-3-fill',
8686
keepAlive: true,
87-
noScroll: true
87+
noScroll: true,
88+
back: true
8889
},
8990
component: () => import('@/views/set/index.vue')
9091
}

0 commit comments

Comments
 (0)