mirror of
https://github.com/algerkong/AlgerMusicPlayer.git
synced 2026-04-24 16:27:23 +08:00
Merge pull request #403 from Hellodwadawd12312312/main
feat: 使用滑块增强播放速度控制并改进空安全
This commit is contained in:
@@ -67,15 +67,26 @@
|
|||||||
<i class="ri-close-line"></i>
|
<i class="ri-close-line"></i>
|
||||||
</div>
|
</div>
|
||||||
<h3>{{ t('player.playBar.playbackSpeed') }}</h3>
|
<h3>{{ t('player.playBar.playbackSpeed') }}</h3>
|
||||||
<div class="speed-options">
|
<div class="speed-controls">
|
||||||
<div
|
<div class="speed-options">
|
||||||
v-for="option in playbackRateOptions"
|
<div
|
||||||
:key="option.key"
|
v-for="option in playbackRateOptions"
|
||||||
class="speed-option"
|
:key="option.key"
|
||||||
:class="{ active: playbackRate === option.key }"
|
class="speed-option"
|
||||||
@click="selectSpeed(option.key)"
|
:class="{ 'active': playbackRate === option.key }"
|
||||||
>
|
@click="selectSpeed(option.key)"
|
||||||
{{ option.label }}
|
>
|
||||||
|
{{ option.label }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="speed-slider">
|
||||||
|
<n-slider
|
||||||
|
:value="playbackRate"
|
||||||
|
:min="0.25"
|
||||||
|
:max="2.0"
|
||||||
|
:step="0.01"
|
||||||
|
@update:value="selectSpeed"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -83,7 +94,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { DropdownOption } from 'naive-ui';
|
import { DropdownOption, NSlider } from 'naive-ui';
|
||||||
import { computed, h, ref, watch } from 'vue';
|
import { computed, h, ref, watch } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
|
||||||
@@ -199,7 +210,6 @@ const handleSelect = (key: string) => {
|
|||||||
// 选择播放速度
|
// 选择播放速度
|
||||||
const selectSpeed = (speed: number) => {
|
const selectSpeed = (speed: number) => {
|
||||||
playerStore.setPlaybackRate(speed);
|
playerStore.setPlaybackRate(speed);
|
||||||
showSpeedModal.value = false;
|
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -278,18 +288,22 @@ const selectSpeed = (speed: number) => {
|
|||||||
@apply text-lg font-medium mb-4 text-center;
|
@apply text-lg font-medium mb-4 text-center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.speed-controls {
|
||||||
|
@apply my-8 mx-4;
|
||||||
|
}
|
||||||
.speed-options {
|
.speed-options {
|
||||||
@apply flex flex-wrap justify-center gap-4 my-8 mx-4;
|
@apply flex flex-wrap justify-center gap-4;
|
||||||
|
}
|
||||||
.speed-option {
|
.speed-slider {
|
||||||
@apply py-2 px-4 rounded-full cursor-pointer transition-all;
|
@apply mt-4;
|
||||||
@apply bg-gray-100 dark:bg-gray-800;
|
}
|
||||||
@apply hover:bg-green-100 dark:hover:bg-green-900;
|
.speed-option {
|
||||||
|
@apply py-2 px-4 rounded-full cursor-pointer transition-all;
|
||||||
&.active {
|
@apply bg-gray-100 dark:bg-gray-800;
|
||||||
@apply bg-green-500 text-white;
|
@apply hover:bg-green-100 dark:hover:bg-green-900;
|
||||||
}
|
}
|
||||||
}
|
.speed-option.active {
|
||||||
|
@apply bg-green-500 text-white;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,7 +58,7 @@
|
|||||||
<div class="music-content">
|
<div class="music-content">
|
||||||
<div class="music-content-title flex items-center">
|
<div class="music-content-title flex items-center">
|
||||||
<n-ellipsis class="text-ellipsis" line-clamp="1">
|
<n-ellipsis class="text-ellipsis" line-clamp="1">
|
||||||
{{ playMusic.name }}
|
{{ playMusic?.name || '' }}
|
||||||
</n-ellipsis>
|
</n-ellipsis>
|
||||||
<span v-if="playbackRate !== 1.0" class="playback-rate-badge"> {{ playbackRate }}x </span>
|
<span v-if="playbackRate !== 1.0" class="playback-rate-badge"> {{ playbackRate }}x </span>
|
||||||
</div>
|
</div>
|
||||||
@@ -123,15 +123,15 @@
|
|||||||
<template #trigger>
|
<template #trigger>
|
||||||
<i
|
<i
|
||||||
class="iconfont ri-netease-cloud-music-line"
|
class="iconfont ri-netease-cloud-music-line"
|
||||||
:class="{ 'text-green-500': isLyricWindowOpen, 'disabled-icon': !playMusic.id }"
|
:class="{ 'text-green-500': isLyricWindowOpen, 'disabled-icon': !(playMusic?.id) }"
|
||||||
@click="playMusic.id && openLyricWindow()"
|
@click="playMusic?.id && openLyricWindow()"
|
||||||
></i>
|
></i>
|
||||||
</template>
|
</template>
|
||||||
{{ playMusic.id ? t('player.playBar.lyric') : t('player.playBar.noSongPlaying') }}
|
{{ playMusic?.id ? t('player.playBar.lyric') : t('player.playBar.noSongPlaying') }}
|
||||||
</n-tooltip>
|
</n-tooltip>
|
||||||
<n-tooltip v-if="playMusic.id && isElectron" trigger="hover" :z-index="9999999">
|
<n-tooltip v-if="playMusic?.id && isElectron" trigger="hover" :z-index="9999999">
|
||||||
<template #trigger>
|
<template #trigger>
|
||||||
<reparse-popover v-if="playMusic.id" />
|
<reparse-popover v-if="playMusic?.id" />
|
||||||
</template>
|
</template>
|
||||||
{{ t('player.playBar.reparse') }}
|
{{ t('player.playBar.reparse') }}
|
||||||
</n-tooltip>
|
</n-tooltip>
|
||||||
@@ -191,7 +191,9 @@ const background = ref('#000');
|
|||||||
watch(
|
watch(
|
||||||
() => playerStore.playMusic,
|
() => playerStore.playMusic,
|
||||||
async () => {
|
async () => {
|
||||||
background.value = playMusic.value.backgroundColor as string;
|
if (playMusic && playMusic.value && playMusic.value.backgroundColor) {
|
||||||
|
background.value = playMusic.value.backgroundColor as string;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{ immediate: true, deep: true }
|
{ immediate: true, deep: true }
|
||||||
);
|
);
|
||||||
@@ -359,6 +361,7 @@ const setMusicFull = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const isFavorite = computed(() => {
|
const isFavorite = computed(() => {
|
||||||
|
if (!playMusic || !playMusic.value) return false;
|
||||||
// 对于B站视频,使用ID匹配函数
|
// 对于B站视频,使用ID匹配函数
|
||||||
if (playMusic.value.source === 'bilibili' && playMusic.value.bilibiliData?.bvid) {
|
if (playMusic.value.source === 'bilibili' && playMusic.value.bilibiliData?.bvid) {
|
||||||
return playerStore.favoriteList.some((id) => isBilibiliIdMatch(id, playMusic.value.id));
|
return playerStore.favoriteList.some((id) => isBilibiliIdMatch(id, playMusic.value.id));
|
||||||
|
|||||||
Reference in New Issue
Block a user