Skip to content

Commit 31640bb

Browse files
committed
✨ feat: 搜索列表添加下一首播放功能,修改播放逻辑搜索的歌曲点击播放不重新覆盖播放列表, 添加全部播放功能
1 parent 10f4473 commit 31640bb

File tree

4 files changed

+67
-12
lines changed

4 files changed

+67
-12
lines changed

src/i18n/lang/en-US/search.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ export default {
66
},
77
button: {
88
clear: 'Clear',
9-
back: 'Back'
9+
back: 'Back',
10+
playAll: 'Play All'
1011
},
1112
loading: {
1213
more: 'Loading...',

src/i18n/lang/zh-CN/search.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ export default {
66
},
77
button: {
88
clear: '清空',
9-
back: '返回'
9+
back: '返回',
10+
playAll: '播放列表'
1011
},
1112
loading: {
1213
more: '加载中...',

src/renderer/components/common/SongItem.vue

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,14 @@
6161
@click.stop="toggleFavorite"
6262
></i>
6363
</div>
64+
<n-tooltip v-if="isNext" trigger="hover" :z-index="9999999" :delay="400">
65+
<template #trigger>
66+
<div class="song-item-operating-next" @click.stop="handlePlayNext">
67+
<i class="iconfont ri-skip-forward-fill"></i>
68+
</div>
69+
</template>
70+
{{ t('songItem.menu.playNext') }}
71+
</n-tooltip>
6472
<div
6573
class="song-item-operating-play bg-gray-300 dark:bg-gray-800 animate__animated"
6674
:class="{ 'bg-green-600': isPlaying, animate__flipInY: playLoading }"
@@ -110,14 +118,16 @@ const props = withDefaults(
110118
selectable?: boolean;
111119
selected?: boolean;
112120
canRemove?: boolean;
121+
isNext?: boolean;
113122
}>(),
114123
{
115124
mini: false,
116125
list: false,
117126
favorite: true,
118127
selectable: false,
119128
selected: false,
120-
canRemove: false
129+
canRemove: false,
130+
isNext: false
121131
}
122132
);
123133
@@ -475,6 +485,14 @@ const handlePlayNext = () => {
475485
@apply mr-2 cursor-pointer ml-4 transition-all;
476486
}
477487
488+
&-next {
489+
@apply mr-2 cursor-pointer transition-all;
490+
491+
.iconfont {
492+
@apply text-xl transition text-gray-500 dark:text-gray-400 hover:text-green-500;
493+
}
494+
}
495+
478496
.like-active {
479497
@apply text-red-500 dark:text-red-500;
480498
}

src/renderer/views/search/index.vue

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@
3737
@click="searchDetail = null"
3838
></i>
3939
{{ hotKeyword }}
40+
<div v-if="searchDetail?.songs?.length" class="title-play-all">
41+
<div class="play-all-btn" @click="handlePlayAll">
42+
<i class="ri-play-circle-fill"></i>
43+
<span>{{ t('search.button.playAll') }}</span>
44+
</div>
45+
</div>
4046
</div>
4147
<div v-loading="searchDetailLoading" class="search-list-box">
4248
<template v-if="searchDetail">
@@ -46,7 +52,7 @@
4652
v-for="(item, index) in searchDetail?.bilibili"
4753
:key="item.bvid"
4854
:class="setAnimationClass('animate__bounceInRight')"
49-
:style="setAnimationDelay(index, 50)"
55+
:style="getSearchListAnimation(index)"
5056
>
5157
<bilibili-item :item="item" @play="handlePlayBilibili" />
5258
</div>
@@ -62,9 +68,9 @@
6268
v-for="(item, index) in searchDetail?.songs"
6369
:key="item.id"
6470
:class="setAnimationClass('animate__bounceInRight')"
65-
:style="setAnimationDelay(index, 50)"
71+
:style="getSearchListAnimation(index)"
6672
>
67-
<song-item :item="item" @play="handlePlay" />
73+
<song-item :item="item" @play="handlePlay" :is-next="true" />
6874
</div>
6975
<template v-for="(list, key) in searchDetail">
7076
<template v-if="key.toString() !== 'songs'">
@@ -73,7 +79,7 @@
7379
:key="item.id"
7480
class="mb-3"
7581
:class="setAnimationClass('animate__bounceInRight')"
76-
:style="setAnimationDelay(index, 50)"
82+
:style="getSearchListAnimation(index)"
7783
>
7884
<search-item :item="item" />
7985
</div>
@@ -104,7 +110,7 @@
104110
v-for="(item, index) in searchHistory"
105111
:key="index"
106112
:class="setAnimationClass('animate__bounceIn')"
107-
:style="setAnimationDelay(index, 50)"
113+
:style="getSearchListAnimation(index)"
108114
class="search-history-item"
109115
round
110116
closable
@@ -162,6 +168,10 @@ const hasMore = ref(true);
162168
const isLoadingMore = ref(false);
163169
const currentKeyword = ref('');
164170
171+
const getSearchListAnimation = (index: number) => {
172+
return setAnimationDelay(index % ITEMS_PER_PAGE, 50);
173+
};
174+
165175
// 从 localStorage 加载搜索历史
166176
const loadSearchHistory = () => {
167177
const history = localStorage.getItem('searchHistory');
@@ -398,9 +408,9 @@ watch(
398408
{ immediate: true }
399409
);
400410
401-
const handlePlay = () => {
402-
const tracks = searchDetail.value?.songs || [];
403-
playerStore.setPlayList(tracks);
411+
const handlePlay = (item: any) => {
412+
// 添加到下一首
413+
playerStore.addToNextPlay(item);
404414
};
405415
406416
// 点击搜索历史
@@ -418,6 +428,18 @@ const handlePlayBilibili = (item: IBilibiliSearchResult) => {
418428
// 使用路由导航到B站播放页面
419429
router.push(`/bilibili/${item.bvid}`);
420430
};
431+
432+
const handlePlayAll = () => {
433+
if (!searchDetail.value?.songs?.length) return;
434+
435+
// 设置播放列表为搜索结果中的所有歌曲
436+
playerStore.setPlayList(searchDetail.value.songs);
437+
438+
// 开始播放第一首歌
439+
if (searchDetail.value.songs[0]) {
440+
playerStore.setPlay(searchDetail.value.songs[0]);
441+
}
442+
};
421443
</script>
422444

423445
<style lang="scss" scoped>
@@ -469,8 +491,21 @@ const handlePlayBilibili = (item: IBilibiliSearchResult) => {
469491
}
470492
471493
.title {
472-
@apply text-xl font-bold my-2 mx-4;
494+
@apply text-xl font-bold my-2 mx-4 flex items-center;
473495
@apply text-gray-900 dark:text-white;
496+
497+
&-play-all {
498+
@apply ml-auto;
499+
}
500+
}
501+
502+
.play-all-btn {
503+
@apply flex items-center gap-1 px-3 py-1 rounded-full cursor-pointer transition-all;
504+
@apply text-sm font-normal text-gray-900 dark:text-white hover:bg-light-300 dark:hover:bg-dark-300 hover:text-green-500;
505+
506+
i {
507+
@apply text-xl;
508+
}
474509
}
475510
476511
.search-history {

0 commit comments

Comments
 (0)