feat:针对移动端优化

This commit is contained in:
alger
2025-12-19 00:23:24 +08:00
parent 70f1044dd9
commit 8e1259d2aa
18 changed files with 2299 additions and 189 deletions
@@ -21,13 +21,38 @@
<i class="ri-loader-4-line loading-icon"></i>
</div>
<div
class="control-btn absolute top-5 left-5"
class="control-btn absolute left-5"
:class="{ 'pure-mode': config.pureModeEnabled }"
@click="closeMusicFull"
>
<i class="ri-arrow-down-s-line"></i>
</div>
<!-- 右上角设置按钮 -->
<div
class="control-btn absolute right-5 flex items-center gap-2"
:class="[
{ 'pure-mode': config.pureModeEnabled },
hasSleepTimerActive ? '!w-auto !px-2' : ''
]"
>
<!-- 定时器倒计时显示 -->
<div
v-if="hasSleepTimerActive"
class="flex items-center gap-1 px-2 py-1 rounded-full bg-black/30 backdrop-blur-sm text-xs text-white/90"
@click="showPlayerSettings = true"
>
<i class="ri-timer-line text-green-400"></i>
<span class="font-medium tabular-nums">{{ sleepTimerDisplayText }}</span>
</div>
<div @click="showPlayerSettings = true">
<i class="ri-more-2-fill"></i>
</div>
</div>
<!-- 播放设置弹窗 -->
<mobile-player-settings v-model:visible="showPlayerSettings" />
<!-- 全屏歌词页面 - 竖屏模式下 -->
<transition name="fade">
<div v-if="showFullLyrics && !isLandscape" class="fullscreen-lyrics" :class="config.theme">
@@ -368,6 +393,7 @@ import { useWindowSize } from '@vueuse/core';
import { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue';
import { useI18n } from 'vue-i18n';
import MobilePlayerSettings from '@/components/player/MobilePlayerSettings.vue';
import {
allTime,
artistList,
@@ -396,6 +422,55 @@ const playerStore = usePlayerStore();
const play = computed(() => playerStore.isPlay);
const playIcon = computed(() => (play.value ? 'ri-pause-fill' : 'ri-play-fill'));
// 播放设置弹窗
const showPlayerSettings = ref(false);
// 定时器相关
const sleepTimerRefresh = ref(0);
let sleepTimerInterval: ReturnType<typeof setInterval> | null = null;
const hasSleepTimerActive = computed(() => playerStore.hasSleepTimerActive);
const sleepTimerDisplayText = computed(() => {
void sleepTimerRefresh.value; // 触发响应式更新
const timer = playerStore.sleepTimer;
if (timer.type === 'time' && timer.endTime) {
const remaining = Math.max(0, timer.endTime - Date.now());
const totalSeconds = Math.floor(remaining / 1000);
const minutes = Math.floor(totalSeconds / 60);
const seconds = totalSeconds % 60;
return `${minutes}:${seconds.toString().padStart(2, '0')}`;
}
if (timer.type === 'songs' && timer.remainingSongs) {
return `${timer.remainingSongs}`;
}
if (timer.type === 'end') {
return '列表结束';
}
return '';
});
// 启动/停止定时器刷新
watch(
hasSleepTimerActive,
(active) => {
if (active && playerStore.sleepTimer.type === 'time') {
if (!sleepTimerInterval) {
sleepTimerInterval = setInterval(() => {
sleepTimerRefresh.value = Date.now();
}, 1000);
}
} else {
if (sleepTimerInterval) {
clearInterval(sleepTimerInterval);
sleepTimerInterval = null;
}
}
},
{ immediate: true }
);
// 播放模式
const { playMode, playModeIcon, playModeText, togglePlayMode: togglePlayModeBase } = usePlayMode();
// 打开播放列表
@@ -443,9 +518,11 @@ watch(isLandscape, (newVal) => {
}
});
// 显示全屏歌词
// 显示全屏歌词
const showFullLyricScreen = () => {
showFullLyrics.value = true;
// 使用多次延迟尝试滚动,确保能够滚动到当前歌词
nextTick(() => {
scrollToCurrentLyric(true);
@@ -1754,9 +1831,8 @@ const getWordStyle = (lineIndex: number, _wordIndex: number, word: any) => {
}
.fullscreen-header {
@apply pt-8 pb-4 px-6 flex flex-col items-center fixed top-0 left-0 w-full z-10;
@apply pt-16 pb-4 px-6 flex flex-col items-center fixed top-0 left-0 w-full z-10;
background: linear-gradient(to bottom, rgba(0, 0, 0, 0.2) 0%, rgba(0, 0, 0, 0) 100%);
height: 100px;
pointer-events: auto;
.song-title {
@@ -1817,6 +1893,7 @@ const getWordStyle = (lineIndex: number, _wordIndex: number, word: any) => {
@apply w-9 h-9 flex items-center justify-center rounded cursor-pointer transition-all duration-300 z-[9999];
background: rgba(142, 142, 142, 0.192);
backdrop-filter: blur(12px);
top: calc(var(--safe-area-inset-top, 0) + 20px);
i {
@apply text-xl;