Skip to content

Commit 8fb382e

Browse files
feat: enhance playback speed controls with slider and improve null safety for playMusic
1 parent c08c2cb commit 8fb382e

File tree

2 files changed

+46
-29
lines changed

2 files changed

+46
-29
lines changed

src/renderer/components/player/AdvancedControlsPopover.vue

Lines changed: 36 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -67,23 +67,34 @@
6767
<i class="ri-close-line"></i>
6868
</div>
6969
<h3>{{ t('player.playBar.playbackSpeed') }}</h3>
70-
<div class="speed-options">
71-
<div
72-
v-for="option in playbackRateOptions"
73-
:key="option.key"
74-
class="speed-option"
75-
:class="{ active: playbackRate === option.key }"
76-
@click="selectSpeed(option.key)"
77-
>
78-
{{ option.label }}
70+
<div class="speed-controls">
71+
<div class="speed-options">
72+
<div
73+
v-for="option in playbackRateOptions"
74+
:key="option.key"
75+
class="speed-option"
76+
:class="{ 'active': playbackRate === option.key }"
77+
@click="selectSpeed(option.key)"
78+
>
79+
{{ option.label }}
80+
</div>
81+
</div>
82+
<div class="speed-slider">
83+
<n-slider
84+
:value="playbackRate"
85+
:min="0.25"
86+
:max="2.0"
87+
:step="0.01"
88+
@update:value="selectSpeed"
89+
/>
7990
</div>
8091
</div>
8192
</div>
8293
</n-modal>
8394
</template>
8495

8596
<script lang="ts" setup>
86-
import { DropdownOption } from 'naive-ui';
97+
import { DropdownOption, NSlider } from 'naive-ui';
8798
import { computed, h, ref, watch } from 'vue';
8899
import { useI18n } from 'vue-i18n';
89100
@@ -199,7 +210,6 @@ const handleSelect = (key: string) => {
199210
// 选择播放速度
200211
const selectSpeed = (speed: number) => {
201212
playerStore.setPlaybackRate(speed);
202-
showSpeedModal.value = false;
203213
};
204214
</script>
205215

@@ -278,18 +288,22 @@ const selectSpeed = (speed: number) => {
278288
@apply text-lg font-medium mb-4 text-center;
279289
}
280290
291+
.speed-controls {
292+
@apply my-8 mx-4;
293+
}
281294
.speed-options {
282-
@apply flex flex-wrap justify-center gap-4 my-8 mx-4;
283-
284-
.speed-option {
285-
@apply py-2 px-4 rounded-full cursor-pointer transition-all;
286-
@apply bg-gray-100 dark:bg-gray-800;
287-
@apply hover:bg-green-100 dark:hover:bg-green-900;
288-
289-
&.active {
290-
@apply bg-green-500 text-white;
291-
}
292-
}
295+
@apply flex flex-wrap justify-center gap-4;
296+
}
297+
.speed-slider {
298+
@apply mt-4;
299+
}
300+
.speed-option {
301+
@apply py-2 px-4 rounded-full cursor-pointer transition-all;
302+
@apply bg-gray-100 dark:bg-gray-800;
303+
@apply hover:bg-green-100 dark:hover:bg-green-900;
304+
}
305+
.speed-option.active {
306+
@apply bg-green-500 text-white;
293307
}
294308
}
295309

src/renderer/components/player/PlayBar.vue

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
<div class="music-content">
5959
<div class="music-content-title flex items-center">
6060
<n-ellipsis class="text-ellipsis" line-clamp="1">
61-
{{ playMusic.name }}
61+
{{ playMusic?.name || '' }}
6262
</n-ellipsis>
6363
<span v-if="playbackRate !== 1.0" class="playback-rate-badge"> {{ playbackRate }}x </span>
6464
</div>
@@ -123,15 +123,15 @@
123123
<template #trigger>
124124
<i
125125
class="iconfont ri-netease-cloud-music-line"
126-
:class="{ 'text-green-500': isLyricWindowOpen, 'disabled-icon': !playMusic.id }"
127-
@click="playMusic.id && openLyricWindow()"
126+
:class="{ 'text-green-500': isLyricWindowOpen, 'disabled-icon': !(playMusic?.id) }"
127+
@click="playMusic?.id && openLyricWindow()"
128128
></i>
129129
</template>
130-
{{ playMusic.id ? t('player.playBar.lyric') : t('player.playBar.noSongPlaying') }}
130+
{{ playMusic?.id ? t('player.playBar.lyric') : t('player.playBar.noSongPlaying') }}
131131
</n-tooltip>
132-
<n-tooltip v-if="playMusic.id && isElectron" trigger="hover" :z-index="9999999">
132+
<n-tooltip v-if="playMusic?.id && isElectron" trigger="hover" :z-index="9999999">
133133
<template #trigger>
134-
<reparse-popover v-if="playMusic.id" />
134+
<reparse-popover v-if="playMusic?.id" />
135135
</template>
136136
{{ t('player.playBar.reparse') }}
137137
</n-tooltip>
@@ -191,7 +191,9 @@ const background = ref('#000');
191191
watch(
192192
() => playerStore.playMusic,
193193
async () => {
194-
background.value = playMusic.value.backgroundColor as string;
194+
if (playMusic && playMusic.value && playMusic.value.backgroundColor) {
195+
background.value = playMusic.value.backgroundColor as string;
196+
}
195197
},
196198
{ immediate: true, deep: true }
197199
);
@@ -359,6 +361,7 @@ const setMusicFull = () => {
359361
};
360362
361363
const isFavorite = computed(() => {
364+
if (!playMusic || !playMusic.value) return false;
362365
// 对于B站视频,使用ID匹配函数
363366
if (playMusic.value.source === 'bilibili' && playMusic.value.bilibiliData?.bvid) {
364367
return playerStore.favoriteList.some((id) => isBilibiliIdMatch(id, playMusic.value.id));

0 commit comments

Comments
 (0)