mirror of
https://github.com/algerkong/AlgerMusicPlayer.git
synced 2026-05-17 02:07:29 +08:00
feat: 优化播放栏,整合高级控制菜单,将定时、均衡器、速度控制改为更多设置按钮显示, 添加定时关闭顶部显示功能
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- 定时关闭倒计时显示区域 -->
|
||||
<div v-if="hasActiveSleepTimer" class="sleep-timer-countdown" @click="handleShowTimer">
|
||||
<i class="iconfont ri-time-line mr-1"></i>
|
||||
<span>{{ formattedRemainingTime }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { usePlayerStore } from '@/store/modules/player';
|
||||
|
||||
const { t } = useI18n();
|
||||
// 定时器状态
|
||||
const playerStore = usePlayerStore();
|
||||
const { sleepTimer } = storeToRefs(playerStore);
|
||||
const hasActiveSleepTimer = computed(() => playerStore.hasSleepTimerActive);
|
||||
const refreshTrigger = ref(0);
|
||||
|
||||
// 倒计时显示
|
||||
const formattedRemainingTime = computed(() => {
|
||||
// 依赖刷新触发器强制更新
|
||||
void refreshTrigger.value;
|
||||
|
||||
if (sleepTimer.value.type !== 'time' || !sleepTimer.value.endTime) {
|
||||
if (sleepTimer.value.type === 'songs' && sleepTimer.value.remainingSongs) {
|
||||
return t('player.sleepTimer.songsRemaining', { count: sleepTimer.value.remainingSongs });
|
||||
}
|
||||
if (sleepTimer.value.type === 'end') {
|
||||
return t('player.sleepTimer.activeUntilEnd');
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
const remaining = Math.max(0, sleepTimer.value.endTime - Date.now());
|
||||
const totalSeconds = Math.floor(remaining / 1000);
|
||||
|
||||
const hours = Math.floor(totalSeconds / 3600);
|
||||
const minutes = Math.floor((totalSeconds % 3600) / 60);
|
||||
const seconds = Math.floor(totalSeconds % 60);
|
||||
|
||||
if (hours > 0) {
|
||||
return `${hours}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
|
||||
} else {
|
||||
return `${minutes}:${seconds.toString().padStart(2, '0')}`;
|
||||
}
|
||||
});
|
||||
|
||||
// 监听剩余时间变化
|
||||
let timerUpdateInterval: number | null = null;
|
||||
|
||||
watch(
|
||||
() => hasActiveSleepTimer.value,
|
||||
(newHasTimer) => {
|
||||
if (newHasTimer && sleepTimer.value.type === 'time') {
|
||||
startTimerUpdate();
|
||||
} else if (!newHasTimer) {
|
||||
stopTimerUpdate();
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
// 启动定时器更新UI
|
||||
function startTimerUpdate() {
|
||||
stopTimerUpdate(); // 先停止之前的计时器
|
||||
|
||||
// 每秒更新UI
|
||||
timerUpdateInterval = window.setInterval(() => {
|
||||
// 更新刷新触发器,强制重新计算
|
||||
refreshTrigger.value = Date.now();
|
||||
}, 1000) as unknown as number;
|
||||
}
|
||||
|
||||
// 停止定时器更新UI
|
||||
function stopTimerUpdate() {
|
||||
if (timerUpdateInterval) {
|
||||
clearInterval(timerUpdateInterval);
|
||||
timerUpdateInterval = null;
|
||||
}
|
||||
}
|
||||
|
||||
const handleShowTimer = () => {
|
||||
playerStore.showSleepTimer = true;
|
||||
};
|
||||
|
||||
// 播放器卸载时清除定时器
|
||||
onUnmounted(() => {
|
||||
stopTimerUpdate();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
.sleep-timer-countdown {
|
||||
@apply fixed top-[28px] left-1/2 transform -translate-x-1/2 -translate-y-full py-1 px-3 rounded-b-lg bg-green-500 text-white text-sm flex items-center;
|
||||
box-shadow: 0 2px 10px rgba(0,0,0,0.15);
|
||||
z-index: 9998;
|
||||
min-width: 80px;
|
||||
text-align: center;
|
||||
animation: fadeInDown 0.3s ease-out;
|
||||
-webkit-app-region: no-drag;
|
||||
|
||||
@keyframes fadeInDown {
|
||||
from {
|
||||
transform: translate(-50%, -150%);
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
transform: translate(-50%, -100%);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
span {
|
||||
font-variant-numeric: tabular-nums;
|
||||
letter-spacing: 0.5px;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user