mirror of
https://github.com/algerkong/AlgerMusicPlayer.git
synced 2026-04-28 10:57:23 +08:00
Merge pull request #216 from algerkong/feat/search-music-play
✨ feat: 搜索列表添加下一首播放功能,修改播放逻辑搜索的歌曲点击播放不重新覆盖播放列表, 添加全部播放功能
This commit is contained in:
@@ -6,7 +6,8 @@ export default {
|
|||||||
},
|
},
|
||||||
button: {
|
button: {
|
||||||
clear: 'Clear',
|
clear: 'Clear',
|
||||||
back: 'Back'
|
back: 'Back',
|
||||||
|
playAll: 'Play All'
|
||||||
},
|
},
|
||||||
loading: {
|
loading: {
|
||||||
more: 'Loading...',
|
more: 'Loading...',
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ export default {
|
|||||||
},
|
},
|
||||||
button: {
|
button: {
|
||||||
clear: '清空',
|
clear: '清空',
|
||||||
back: '返回'
|
back: '返回',
|
||||||
|
playAll: '播放列表'
|
||||||
},
|
},
|
||||||
loading: {
|
loading: {
|
||||||
more: '加载中...',
|
more: '加载中...',
|
||||||
|
|||||||
@@ -61,6 +61,14 @@
|
|||||||
@click.stop="toggleFavorite"
|
@click.stop="toggleFavorite"
|
||||||
></i>
|
></i>
|
||||||
</div>
|
</div>
|
||||||
|
<n-tooltip v-if="isNext" trigger="hover" :z-index="9999999" :delay="400">
|
||||||
|
<template #trigger>
|
||||||
|
<div class="song-item-operating-next" @click.stop="handlePlayNext">
|
||||||
|
<i class="iconfont ri-skip-forward-fill"></i>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
{{ t('songItem.menu.playNext') }}
|
||||||
|
</n-tooltip>
|
||||||
<div
|
<div
|
||||||
class="song-item-operating-play bg-gray-300 dark:bg-gray-800 animate__animated"
|
class="song-item-operating-play bg-gray-300 dark:bg-gray-800 animate__animated"
|
||||||
:class="{ 'bg-green-600': isPlaying, animate__flipInY: playLoading }"
|
:class="{ 'bg-green-600': isPlaying, animate__flipInY: playLoading }"
|
||||||
@@ -110,6 +118,7 @@ const props = withDefaults(
|
|||||||
selectable?: boolean;
|
selectable?: boolean;
|
||||||
selected?: boolean;
|
selected?: boolean;
|
||||||
canRemove?: boolean;
|
canRemove?: boolean;
|
||||||
|
isNext?: boolean;
|
||||||
}>(),
|
}>(),
|
||||||
{
|
{
|
||||||
mini: false,
|
mini: false,
|
||||||
@@ -117,7 +126,8 @@ const props = withDefaults(
|
|||||||
favorite: true,
|
favorite: true,
|
||||||
selectable: false,
|
selectable: false,
|
||||||
selected: false,
|
selected: false,
|
||||||
canRemove: false
|
canRemove: false,
|
||||||
|
isNext: false
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -475,6 +485,14 @@ const handlePlayNext = () => {
|
|||||||
@apply mr-2 cursor-pointer ml-4 transition-all;
|
@apply mr-2 cursor-pointer ml-4 transition-all;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&-next {
|
||||||
|
@apply mr-2 cursor-pointer transition-all;
|
||||||
|
|
||||||
|
.iconfont {
|
||||||
|
@apply text-xl transition text-gray-500 dark:text-gray-400 hover:text-green-500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.like-active {
|
.like-active {
|
||||||
@apply text-red-500 dark:text-red-500;
|
@apply text-red-500 dark:text-red-500;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,12 @@
|
|||||||
@click="searchDetail = null"
|
@click="searchDetail = null"
|
||||||
></i>
|
></i>
|
||||||
{{ hotKeyword }}
|
{{ hotKeyword }}
|
||||||
|
<div v-if="searchDetail?.songs?.length" class="title-play-all">
|
||||||
|
<div class="play-all-btn" @click="handlePlayAll">
|
||||||
|
<i class="ri-play-circle-fill"></i>
|
||||||
|
<span>{{ t('search.button.playAll') }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-loading="searchDetailLoading" class="search-list-box">
|
<div v-loading="searchDetailLoading" class="search-list-box">
|
||||||
<template v-if="searchDetail">
|
<template v-if="searchDetail">
|
||||||
@@ -46,7 +52,7 @@
|
|||||||
v-for="(item, index) in searchDetail?.bilibili"
|
v-for="(item, index) in searchDetail?.bilibili"
|
||||||
:key="item.bvid"
|
:key="item.bvid"
|
||||||
:class="setAnimationClass('animate__bounceInRight')"
|
:class="setAnimationClass('animate__bounceInRight')"
|
||||||
:style="setAnimationDelay(index, 50)"
|
:style="getSearchListAnimation(index)"
|
||||||
>
|
>
|
||||||
<bilibili-item :item="item" @play="handlePlayBilibili" />
|
<bilibili-item :item="item" @play="handlePlayBilibili" />
|
||||||
</div>
|
</div>
|
||||||
@@ -62,9 +68,9 @@
|
|||||||
v-for="(item, index) in searchDetail?.songs"
|
v-for="(item, index) in searchDetail?.songs"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
:class="setAnimationClass('animate__bounceInRight')"
|
:class="setAnimationClass('animate__bounceInRight')"
|
||||||
:style="setAnimationDelay(index, 50)"
|
:style="getSearchListAnimation(index)"
|
||||||
>
|
>
|
||||||
<song-item :item="item" @play="handlePlay" />
|
<song-item :item="item" @play="handlePlay" :is-next="true" />
|
||||||
</div>
|
</div>
|
||||||
<template v-for="(list, key) in searchDetail">
|
<template v-for="(list, key) in searchDetail">
|
||||||
<template v-if="key.toString() !== 'songs'">
|
<template v-if="key.toString() !== 'songs'">
|
||||||
@@ -73,7 +79,7 @@
|
|||||||
:key="item.id"
|
:key="item.id"
|
||||||
class="mb-3"
|
class="mb-3"
|
||||||
:class="setAnimationClass('animate__bounceInRight')"
|
:class="setAnimationClass('animate__bounceInRight')"
|
||||||
:style="setAnimationDelay(index, 50)"
|
:style="getSearchListAnimation(index)"
|
||||||
>
|
>
|
||||||
<search-item :item="item" />
|
<search-item :item="item" />
|
||||||
</div>
|
</div>
|
||||||
@@ -104,7 +110,7 @@
|
|||||||
v-for="(item, index) in searchHistory"
|
v-for="(item, index) in searchHistory"
|
||||||
:key="index"
|
:key="index"
|
||||||
:class="setAnimationClass('animate__bounceIn')"
|
:class="setAnimationClass('animate__bounceIn')"
|
||||||
:style="setAnimationDelay(index, 50)"
|
:style="getSearchListAnimation(index)"
|
||||||
class="search-history-item"
|
class="search-history-item"
|
||||||
round
|
round
|
||||||
closable
|
closable
|
||||||
@@ -162,6 +168,10 @@ const hasMore = ref(true);
|
|||||||
const isLoadingMore = ref(false);
|
const isLoadingMore = ref(false);
|
||||||
const currentKeyword = ref('');
|
const currentKeyword = ref('');
|
||||||
|
|
||||||
|
const getSearchListAnimation = (index: number) => {
|
||||||
|
return setAnimationDelay(index % ITEMS_PER_PAGE, 50);
|
||||||
|
};
|
||||||
|
|
||||||
// 从 localStorage 加载搜索历史
|
// 从 localStorage 加载搜索历史
|
||||||
const loadSearchHistory = () => {
|
const loadSearchHistory = () => {
|
||||||
const history = localStorage.getItem('searchHistory');
|
const history = localStorage.getItem('searchHistory');
|
||||||
@@ -398,9 +408,9 @@ watch(
|
|||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
const handlePlay = () => {
|
const handlePlay = (item: any) => {
|
||||||
const tracks = searchDetail.value?.songs || [];
|
// 添加到下一首
|
||||||
playerStore.setPlayList(tracks);
|
playerStore.addToNextPlay(item);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 点击搜索历史
|
// 点击搜索历史
|
||||||
@@ -418,6 +428,18 @@ const handlePlayBilibili = (item: IBilibiliSearchResult) => {
|
|||||||
// 使用路由导航到B站播放页面
|
// 使用路由导航到B站播放页面
|
||||||
router.push(`/bilibili/${item.bvid}`);
|
router.push(`/bilibili/${item.bvid}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handlePlayAll = () => {
|
||||||
|
if (!searchDetail.value?.songs?.length) return;
|
||||||
|
|
||||||
|
// 设置播放列表为搜索结果中的所有歌曲
|
||||||
|
playerStore.setPlayList(searchDetail.value.songs);
|
||||||
|
|
||||||
|
// 开始播放第一首歌
|
||||||
|
if (searchDetail.value.songs[0]) {
|
||||||
|
playerStore.setPlay(searchDetail.value.songs[0]);
|
||||||
|
}
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@@ -469,8 +491,21 @@ const handlePlayBilibili = (item: IBilibiliSearchResult) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
@apply text-xl font-bold my-2 mx-4;
|
@apply text-xl font-bold my-2 mx-4 flex items-center;
|
||||||
@apply text-gray-900 dark:text-white;
|
@apply text-gray-900 dark:text-white;
|
||||||
|
|
||||||
|
&-play-all {
|
||||||
|
@apply ml-auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.play-all-btn {
|
||||||
|
@apply flex items-center gap-1 px-3 py-1 rounded-full cursor-pointer transition-all;
|
||||||
|
@apply text-sm font-normal text-gray-900 dark:text-white hover:bg-light-300 dark:hover:bg-dark-300 hover:text-green-500;
|
||||||
|
|
||||||
|
i {
|
||||||
|
@apply text-xl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-history {
|
.search-history {
|
||||||
|
|||||||
Reference in New Issue
Block a user