mirror of
https://github.com/imsyy/SPlayer.git
synced 2025-11-25 11:29:26 +08:00
✨ feat: 卡片播放按钮可直接播放 #111
This commit is contained in:
7
components.d.ts
vendored
7
components.d.ts
vendored
@@ -12,6 +12,7 @@ declare module 'vue' {
|
||||
CommentList: typeof import('./src/components/List/CommentList.vue')['default']
|
||||
CountDown: typeof import('./src/components/Player/CountDown.vue')['default']
|
||||
CoverDropdown: typeof import('./src/components/Cover/CoverDropdown.vue')['default']
|
||||
CoverPlayBtn: typeof import('./src/components/Cover/CoverPlayBtn.vue')['default']
|
||||
CreatePlaylist: typeof import('./src/components/Modal/CreatePlaylist.vue')['default']
|
||||
DownloadSong: typeof import('./src/components/Modal/DownloadSong.vue')['default']
|
||||
FullPlayer: typeof import('./src/components/Player/FullPlayer.vue')['default']
|
||||
@@ -46,7 +47,7 @@ declare module 'vue' {
|
||||
NGrid: typeof import('naive-ui')['NGrid']
|
||||
NH1: typeof import('naive-ui')['NH1']
|
||||
NH3: typeof import('naive-ui')['NH3']
|
||||
NH4: (typeof import("naive-ui"))["NH4"]
|
||||
NH4: typeof import('naive-ui')['NH4']
|
||||
NH6: typeof import('naive-ui')['NH6']
|
||||
NIcon: typeof import('naive-ui')['NIcon']
|
||||
NImage: typeof import('naive-ui')['NImage']
|
||||
@@ -63,14 +64,12 @@ declare module 'vue' {
|
||||
NMessageProvider: typeof import('naive-ui')['NMessageProvider']
|
||||
NModal: typeof import('naive-ui')['NModal']
|
||||
NNotificationProvider: typeof import('naive-ui')['NNotificationProvider']
|
||||
NNumberAnimation: (typeof import("naive-ui"))["NNumberAnimation"]
|
||||
NNumberAnimation: typeof import('naive-ui')['NNumberAnimation']
|
||||
NPagination: typeof import('naive-ui')['NPagination']
|
||||
NPopover: typeof import('naive-ui')['NPopover']
|
||||
NProgress: typeof import('naive-ui')['NProgress']
|
||||
NQrCode: typeof import('naive-ui')['NQrCode']
|
||||
NRadio: typeof import('naive-ui')['NRadio']
|
||||
NRadioGroup: typeof import('naive-ui')['NRadioGroup']
|
||||
NResult: (typeof import("naive-ui"))["NResult"]
|
||||
NScrollbar: typeof import('naive-ui')['NScrollbar']
|
||||
NSelect: typeof import('naive-ui')['NSelect']
|
||||
NSkeleton: typeof import('naive-ui')['NSkeleton']
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"chevron-down": "M7.41 8.58L12 13.17l4.59-4.59L18 10l-6 6l-6-6z",
|
||||
"play": "M9.525 18.025q-.5.325-1.012.038T8 17.175V6.825q0-.6.513-.888t1.012.038l8.15 5.175q.45.3.45.85t-.45.85l-8.15 5.175Z",
|
||||
"play-circle": "M10 16.5v-9l6 4.5M12 2A10 10 0 0 0 2 12a10 10 0 0 0 10 10a10 10 0 0 0 10-10A10 10 0 0 0 12 2Z",
|
||||
"pause-circle": "M15 16h-2V8h2m-4 8H9V8h2m1-6A10 10 0 0 0 2 12a10 10 0 0 0 10 10a10 10 0 0 0 10-10A10 10 0 0 0 12 2",
|
||||
"play-next": "m10 16.5l6-4.5l-6-4.5M22 12c0-5.54-4.46-10-10-10c-1.17 0-2.3.19-3.38.56l.7 1.94c.85-.34 1.74-.53 2.68-.53c4.41 0 8.03 3.62 8.03 8.03c0 4.41-3.62 8.03-8.03 8.03c-4.41 0-8.03-3.62-8.03-8.03c0-.94.19-1.88.53-2.72l-1.94-.66C2.19 9.7 2 10.83 2 12c0 5.54 4.46 10 10 10s10-4.46 10-10M5.47 3.97c.85 0 1.53.71 1.53 1.5C7 6.32 6.32 7 5.47 7c-.79 0-1.5-.68-1.5-1.53c0-.79.71-1.5 1.5-1.5Z",
|
||||
"playlist-add": "M4 16q-.425 0-.713-.288T3 15q0-.425.288-.713T4 14h5q.425 0 .713.288T10 15q0 .425-.288.713T9 16H4Zm0-4q-.425 0-.713-.288T3 11q0-.425.288-.713T4 10h9q.425 0 .713.288T14 11q0 .425-.288.713T13 12H4Zm0-4q-.425 0-.713-.288T3 7q0-.425.288-.713T4 6h9q.425 0 .713.288T14 7q0 .425-.288.713T13 8H4Zm13 12q-.425 0-.713-.288T16 19v-3h-3q-.425 0-.713-.288T12 15q0-.425.288-.713T13 14h3v-3q0-.425.288-.713T17 10q.425 0 .713.288T18 11v3h3q.425 0 .713.288T22 15q0 .425-.288.713T21 16h-3v3q0 .425-.288.713T17 20Z",
|
||||
"account-music": "M11 14c1 0 2.05.16 3.2.44c-.81.87-1.2 1.89-1.2 3.06c0 .89.25 1.73.78 2.5H3v-2c0-1.19.91-2.15 2.74-2.88C7.57 14.38 9.33 14 11 14m0-2c-1.08 0-2-.39-2.82-1.17C7.38 10.05 7 9.11 7 8c0-1.08.38-2 1.18-2.82C9 4.38 9.92 4 11 4c1.11 0 2.05.38 2.83 1.18C14.61 6 15 6.92 15 8c0 1.11-.39 2.05-1.17 2.83c-.78.78-1.72 1.17-2.83 1.17m7.5-2H22v2h-2v5.5a2.5 2.5 0 0 1-2.5 2.5a2.5 2.5 0 0 1-2.5-2.5a2.5 2.5 0 0 1 2.5-2.5c.36 0 .69.07 1 .21V10Z",
|
||||
|
||||
146
src/components/Cover/CoverPlayBtn.vue
Normal file
146
src/components/Cover/CoverPlayBtn.vue
Normal file
@@ -0,0 +1,146 @@
|
||||
<!-- 封面列表 - 播放按钮 -->
|
||||
<template>
|
||||
<div class="play-btn" @click.stop>
|
||||
<n-button
|
||||
:loading="playLoading"
|
||||
color="#efefefde"
|
||||
tag="div"
|
||||
type="primary"
|
||||
class="play"
|
||||
size="large"
|
||||
strong
|
||||
secondary
|
||||
circle
|
||||
@click.stop="playAllSongs"
|
||||
>
|
||||
<template #icon>
|
||||
<Transition name="fade" mode="out-in">
|
||||
<n-icon :key="`${isHasSongs}-${playState}`" size="50">
|
||||
<SvgIcon :icon="isHasSongs !== -1 && playState ? 'pause-circle' : 'play-circle'" />
|
||||
</n-icon>
|
||||
</Transition>
|
||||
</template>
|
||||
</n-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { storeToRefs } from "pinia";
|
||||
import { useRouter } from "vue-router";
|
||||
import { getAllPlayList } from "@/api/playlist";
|
||||
import { getAlbumDetail } from "@/api/album";
|
||||
import { getDjProgram } from "@/api/dj";
|
||||
import { musicData, siteStatus } from "@/stores";
|
||||
import { playOrPause, initPlayer } from "@/utils/Player";
|
||||
import formatData from "@/utils/formatData";
|
||||
|
||||
const router = useRouter();
|
||||
const music = musicData();
|
||||
const status = siteStatus();
|
||||
const { playList, playSongData } = storeToRefs(music);
|
||||
const { playIndex, playMode, playHeartbeatMode, playState } = storeToRefs(status);
|
||||
|
||||
const props = defineProps({
|
||||
// id
|
||||
id: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
// 歌单类型
|
||||
type: {
|
||||
type: String,
|
||||
default: "playlist",
|
||||
},
|
||||
});
|
||||
// 播放按钮数据
|
||||
const playLoading = ref(false);
|
||||
const playListData = ref(null);
|
||||
|
||||
// 是否处于当前歌单
|
||||
const isHasSongs = computed(() => {
|
||||
if (!playListData.value) return -1;
|
||||
const songId = music.getPlaySongData?.id;
|
||||
const existingIndex = playListData.value.findIndex((song) => song.id === songId);
|
||||
return existingIndex;
|
||||
});
|
||||
|
||||
// 获取歌单数据
|
||||
const getPlaylistData = async () => {
|
||||
// 为了播放速度,仅加载列表前 500 首
|
||||
console.log(props.type, props.id);
|
||||
// 按列表类别获取数据
|
||||
switch (props.type) {
|
||||
case "playlist": {
|
||||
const result = await getAllPlayList(props.id, 500);
|
||||
return formatData(result.songs, "song");
|
||||
}
|
||||
case "album": {
|
||||
const result = await getAlbumDetail(props.id);
|
||||
return formatData(result.songs, "song");
|
||||
}
|
||||
case "dj": {
|
||||
const result = await getDjProgram(props.id, 500);
|
||||
return formatData(result.programs, "dj");
|
||||
}
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
// 播放歌单
|
||||
const playAllSongs = async () => {
|
||||
try {
|
||||
if (!props.id) return false;
|
||||
// 开启加载状态
|
||||
if (props.type !== "mv") {
|
||||
// 若不处于歌单内
|
||||
if (isHasSongs.value === -1) {
|
||||
playLoading.value = true;
|
||||
// 获取歌单数据
|
||||
playListData.value = await getPlaylistData();
|
||||
console.log(playListData.value);
|
||||
if (!playListData.value) {
|
||||
playLoading.value = false;
|
||||
return $message.error("获取播放列表时出现错误");
|
||||
}
|
||||
console.log("不在歌单内");
|
||||
// 更改模式和歌单
|
||||
playHeartbeatMode.value = false;
|
||||
playMode.value = props.type === "dj" ? "dj" : "normal";
|
||||
playList.value = playListData.value.slice();
|
||||
playSongData.value = playListData.value[0];
|
||||
playIndex.value = 0;
|
||||
// 初始化播放器
|
||||
await initPlayer(true);
|
||||
playLoading.value = false;
|
||||
$message.info("已开始播放", { showIcon: false });
|
||||
}
|
||||
// 若处于歌单内
|
||||
else {
|
||||
console.log("处于歌单内");
|
||||
playSongData.value = playListData.value[isHasSongs.value];
|
||||
playIndex.value = isHasSongs.value;
|
||||
// 播放
|
||||
playOrPause();
|
||||
}
|
||||
} else {
|
||||
// 跳转播放器
|
||||
router.push({
|
||||
path: "/videos-player",
|
||||
query: {
|
||||
id: props.id,
|
||||
},
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("获取播放列表时出现错误:", error);
|
||||
$message.error("获取播放列表时出现错误");
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.play-btn {
|
||||
backdrop-filter: blur(20px);
|
||||
}
|
||||
</style>
|
||||
@@ -56,8 +56,9 @@
|
||||
<n-text class="add-desc">{{ item.desc }}</n-text>
|
||||
</div>
|
||||
<!-- 播放按钮 -->
|
||||
<n-icon class="play">
|
||||
<SvgIcon :icon="type !== 'artist' ? 'play-circle' : 'account-music'" />
|
||||
<CoverPlayBtn v-if="type !== 'artist'" :id="item.id" :type="type" />
|
||||
<n-icon v-else class="play-btn">
|
||||
<SvgIcon icon="account-music" />
|
||||
</n-icon>
|
||||
</div>
|
||||
<!-- 信息 -->
|
||||
@@ -286,14 +287,18 @@ const jumpLink = (data, type) => {
|
||||
-webkit-line-clamp: 2;
|
||||
}
|
||||
}
|
||||
.play {
|
||||
.play-btn {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
right: 8px;
|
||||
bottom: 8px;
|
||||
opacity: 0;
|
||||
color: #efefefde;
|
||||
transform: translateY(6px);
|
||||
font-size: 50px;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
z-index: 3;
|
||||
transition:
|
||||
opacity 0.3s,
|
||||
@@ -356,7 +361,7 @@ const jumpLink = (data, type) => {
|
||||
top: 0;
|
||||
opacity: 1;
|
||||
}
|
||||
.play {
|
||||
.play-btn {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
&:hover {
|
||||
@@ -385,8 +390,8 @@ const jumpLink = (data, type) => {
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
}
|
||||
.play {
|
||||
// display: none;
|
||||
.play-btn {
|
||||
font-size: 50px;
|
||||
right: auto;
|
||||
bottom: auto;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user