当前播放开发中...
This commit is contained in:
parent
4ade4395d4
commit
8b42649ba1
@ -34,9 +34,10 @@ const store = useStore();
|
||||
|
||||
//载入localstorage的设置
|
||||
store.commit("loadSettings");
|
||||
store.state.settings.playing = false; //默认停止播放
|
||||
store.commit("loadCaches");
|
||||
|
||||
router.replace('/discover/recommend')
|
||||
// router.replace('/discover/recommend')
|
||||
|
||||
const showPlaying = ref(false); //是否显示播放列表
|
||||
|
||||
|
@ -3,15 +3,15 @@ import pubsub from 'pubsub-js'
|
||||
import Home from "../views/Home.vue";
|
||||
|
||||
const routes = [
|
||||
// {
|
||||
// path: "/",
|
||||
// redirect: "/discover/recommend",
|
||||
// name: "index",
|
||||
// // component: ()=> import('@/views/Home.vue'),
|
||||
// // meta:{
|
||||
// // title:'zmusic',
|
||||
// // }
|
||||
// },
|
||||
{
|
||||
path: "/",
|
||||
redirect: "/discover/recommend",
|
||||
name: "index",
|
||||
// component: ()=> import('@/views/Home.vue'),
|
||||
// meta:{
|
||||
// title:'zmusic',
|
||||
// }
|
||||
},
|
||||
{
|
||||
path: "/discover",
|
||||
name: "discover",
|
||||
|
@ -7,6 +7,8 @@ export default createStore({
|
||||
settings: {
|
||||
currentRoute: "/discover/recommend", //当前路由
|
||||
songId: 0, //歌曲id
|
||||
playing: false, //是否播放
|
||||
playMode: 0, //播放模式:0-3,顺序,循环,单曲,随机。
|
||||
lastPlayed: [], //最近播放
|
||||
playingList: [], //当前播放
|
||||
},
|
||||
@ -53,7 +55,7 @@ export default createStore({
|
||||
//载入settings设置
|
||||
loadSettings(state) {
|
||||
const l = localStorage.getItem("zmusic.settings");
|
||||
if (l) state.settings = JSON.parse(l);
|
||||
if (l) state.settings ={...state.settings, ...JSON.parse(l)};
|
||||
},
|
||||
//保存settings设置
|
||||
saveSettings(state, settings) {
|
||||
@ -64,7 +66,7 @@ export default createStore({
|
||||
//载入caches设置
|
||||
loadCaches(state) {
|
||||
const l = localStorage.getItem("zmusic.caches");
|
||||
if (l) state.caches = JSON.parse(l);
|
||||
if (l) state.caches = {...state.caches, ...JSON.parse(l)}
|
||||
},
|
||||
//保存caches设置
|
||||
saveCaches(state, caches) {
|
||||
@ -81,7 +83,7 @@ export default createStore({
|
||||
//载入theme设置
|
||||
loadTheme(state) {
|
||||
const l = localStorage.getItem("zmusic.theme");
|
||||
if (l) state.theme = JSON.parse(l);
|
||||
if (l) state.theme = {...state.theme, ...JSON.parse(l)};
|
||||
},
|
||||
//保存theme设置
|
||||
saveTheme(state, theme) {
|
||||
@ -98,6 +100,20 @@ export default createStore({
|
||||
state.settings.lastPlayed = p;
|
||||
saveLoaclSettings(state.settings);
|
||||
},
|
||||
addToPlayingList(state, song) {
|
||||
//如果没有,设置为[]
|
||||
if (!state.settings.playingList)
|
||||
state.settings.playingList = [];
|
||||
|
||||
let f = state.settings.playingList.find((item) => {
|
||||
return item.id === song.id;
|
||||
});
|
||||
if (!f) {
|
||||
// console.log("add to playingList");
|
||||
state.settings.playingList.unshift(song)
|
||||
saveLoaclSettings(state.settings);
|
||||
}
|
||||
},
|
||||
},
|
||||
actions: {},
|
||||
modules: {},
|
||||
|
@ -1,10 +1,15 @@
|
||||
<script setup>
|
||||
import { ref, reactive, h, watch, toRaw } from "vue";
|
||||
import {
|
||||
RouterLink,
|
||||
useRoute,
|
||||
useRouter,
|
||||
} from "vue-router";
|
||||
ref,
|
||||
reactive,
|
||||
h,
|
||||
watch,
|
||||
toRaw,
|
||||
onMounted,
|
||||
onUnmounted,
|
||||
nextTick,
|
||||
} from "vue";
|
||||
import { RouterLink, useRoute, useRouter } from "vue-router";
|
||||
import { useStore } from "vuex";
|
||||
import {
|
||||
NButton,
|
||||
@ -22,48 +27,110 @@ import {
|
||||
useMessage,
|
||||
} from "naive-ui";
|
||||
import Play from "@/assets/svgs/Play_.svg";
|
||||
import Add from "@/assets/svgs/Add.svg";
|
||||
import Pause from "@/assets/svgs/Pause.svg";
|
||||
import dayjs from "dayjs";
|
||||
import "dayjs/locale/zh-cn";
|
||||
import duration from "dayjs/plugin/duration";
|
||||
import pubsub from "pubsub-js";
|
||||
|
||||
const store = useStore();
|
||||
const playingList = ref([])
|
||||
const router = useRouter();
|
||||
dayjs.extend(duration);
|
||||
const playingList = ref([]);
|
||||
const wpTable = ref("");
|
||||
const listHeight = ref(0);
|
||||
|
||||
const createColumns = ({ play ,singerInfo }) => {
|
||||
onMounted(() => {
|
||||
window.addEventListener("resize", onResize);
|
||||
// console.log(wpTable.value.clientHeight);
|
||||
listHeight.value = wpTable.value.clientHeight;
|
||||
});
|
||||
const onResize = () => {
|
||||
if (wpTable.value) {
|
||||
listHeight.value = wpTable.value.clientHeight - 40;
|
||||
// console.log(wpTable.value.clientHeight)
|
||||
}
|
||||
};
|
||||
|
||||
const token = pubsub.subscribe("zp", (msg, data) => {
|
||||
switch (msg) {
|
||||
case "zp.togglePlaying":
|
||||
nextTick(() => {
|
||||
onResize();
|
||||
});
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
//卸载组件
|
||||
onUnmounted(() => {
|
||||
pubsub.unsubscribe(token);
|
||||
});
|
||||
|
||||
const createColumns = ({ play, singerInfo }) => {
|
||||
return [
|
||||
{
|
||||
title: "",
|
||||
key: "index",
|
||||
align: "right",
|
||||
width: 20
|
||||
width: 20,
|
||||
render(row) {
|
||||
if (row.id === store.state.settings.songId) {
|
||||
const icon = h(store.state.settings.playing ? Play : Pause);
|
||||
return h(
|
||||
NButton,
|
||||
{
|
||||
text: true,
|
||||
type: "primary",
|
||||
circle: true,
|
||||
size: "tiny",
|
||||
},
|
||||
{
|
||||
default: () =>
|
||||
h(
|
||||
NIcon,
|
||||
{
|
||||
style: {
|
||||
bottom: "-2px",
|
||||
left: "-2px",
|
||||
position: "absolute",
|
||||
},
|
||||
},
|
||||
// [h(store.state.settings.playing ? Play : Pause,{},[])]
|
||||
{ default: () => icon }
|
||||
),
|
||||
}
|
||||
);
|
||||
} else return "";
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "音乐标题",
|
||||
key: "name",
|
||||
align: "left",
|
||||
ellipsis: true,
|
||||
render(row){
|
||||
render(row) {
|
||||
return h(
|
||||
NButton,
|
||||
{
|
||||
style: {
|
||||
marginRight: "6px",
|
||||
},
|
||||
text: true,
|
||||
size: "small",
|
||||
onClick: () => play(row.id),
|
||||
NButton,
|
||||
{
|
||||
style: {
|
||||
marginRight: "6px",
|
||||
},
|
||||
{
|
||||
default: () => row.name,
|
||||
}
|
||||
);
|
||||
}
|
||||
text: true,
|
||||
size: "small",
|
||||
onClick: () => play(row.id),
|
||||
},
|
||||
{
|
||||
default: () => row.name,
|
||||
}
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "歌手",
|
||||
key: "artists",
|
||||
ellipsis: true,
|
||||
width: 120,
|
||||
render(row) {
|
||||
const ars = row.artists.map((ar, idx) => {
|
||||
let r = h(
|
||||
@ -87,62 +154,81 @@ const createColumns = ({ play ,singerInfo }) => {
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "播放时间",
|
||||
key: "date",
|
||||
title: "专辑",
|
||||
key: "album.name",
|
||||
width: 100,
|
||||
render(row){
|
||||
return h('span', [dayjs(row.date).format('YYYY-MM-DD')])
|
||||
}
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: "时长",
|
||||
key: "duration",
|
||||
width: 60,
|
||||
render(row) {
|
||||
return h("span", [
|
||||
dayjs.duration(row.duration).format("mm:ss"),
|
||||
]);
|
||||
},
|
||||
},
|
||||
// {
|
||||
// title: "播放时间",
|
||||
// key: "date",
|
||||
// width: 100,
|
||||
// render(row) {
|
||||
// return h("span", [
|
||||
// dayjs(row.date).format("YYYY-MM-DD"),
|
||||
// ]);
|
||||
// },
|
||||
// },
|
||||
];
|
||||
};
|
||||
|
||||
const columns = createColumns({
|
||||
play(id){
|
||||
pubsub.publish('zp.play', {id, im:true})
|
||||
play(id) {
|
||||
pubsub.publish("zp.play", { id, im: true });
|
||||
},
|
||||
singerInfo(id) {
|
||||
// console.log("歌手页面");
|
||||
router.push("/singer/" + id);
|
||||
},
|
||||
});
|
||||
|
||||
// watch(
|
||||
// () => store.state.settings.playingList,
|
||||
// (val, oldVal) => {
|
||||
// playingList.value = toRaw(store.state.settings.playingList)
|
||||
// },
|
||||
// {
|
||||
// immediate: true,
|
||||
// deep: true,
|
||||
// }
|
||||
// );
|
||||
|
||||
watch(
|
||||
() => store.state.settings.playingList,
|
||||
(val, oldVal) => {
|
||||
playingList.value = toRaw(store.state.settings.playingList);
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
deep: true,
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<n-layout>
|
||||
<n-layout-header
|
||||
style="padding: 6px 12px 0px 12px; font-size: 24px"
|
||||
style="padding: 10px 12px 0px 12px; font-size: 24px"
|
||||
>当前播放
|
||||
</n-layout-header>
|
||||
<n-layout has-sider>
|
||||
<n-layout-content
|
||||
style="padding: 6px 12px; font-size: 12px"
|
||||
>
|
||||
共{{ playingList }}首
|
||||
<n-layout-content style="padding: 6px 12px; font-size: 12px">
|
||||
共{{ playingList.length }}首
|
||||
</n-layout-content>
|
||||
<n-layout-sider width="100" style="padding: 0 12px 6px 12px">
|
||||
<n-button size="tiny">清除列表</n-button>
|
||||
</n-layout-sider>
|
||||
</n-layout>
|
||||
</n-layout>
|
||||
<n-data-table
|
||||
:bordered="false"
|
||||
:single-line="true"
|
||||
:columns="columns"
|
||||
:data="playingList"
|
||||
size="tiny"
|
||||
/>
|
||||
<div class="wp-table" ref="wpTable">
|
||||
<n-data-table
|
||||
:bordered="false"
|
||||
:single-line="true"
|
||||
:columns="columns"
|
||||
:data="playingList"
|
||||
size="small"
|
||||
:max-height="listHeight"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@ -150,6 +236,17 @@ export default {};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.wp-table {
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
top: 76px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
thead {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.n-layout-header,
|
||||
.n-layout-content,
|
||||
.n-layout-side {
|
||||
|
@ -33,7 +33,7 @@ onMounted(() => {
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
console.log("另外一个Unmounted");
|
||||
// console.log("另外一个Unmounted");
|
||||
// audioEl.value.removeEventListener("play", onPlay);
|
||||
// audioEl.value.removeEventListener("pause", onPause);
|
||||
// audioEl.value.removeEventListener("ended", onEnd);
|
||||
@ -46,12 +46,46 @@ const onPause = () => {
|
||||
console.log("onPause");
|
||||
};
|
||||
const onEnd = () => {
|
||||
playing.value = false;
|
||||
playNext(1)
|
||||
// playing.value = false;
|
||||
currentTime = 0;
|
||||
console.log("onEnd");
|
||||
console.log("下一首...");
|
||||
};
|
||||
|
||||
const play = async (id, name, im = true) => {
|
||||
const playNext = async (step) => {
|
||||
let { songId, playingList, playMode , playing} = store.state.settings;
|
||||
let idx = playingList.findIndex((item) => item.id == songId);
|
||||
console.log(idx);
|
||||
switch (playMode) {
|
||||
case 0:
|
||||
idx += step;
|
||||
if (idx > playingList.length - 1) return;
|
||||
if (idx < 0) return
|
||||
break;
|
||||
case 1:
|
||||
idx += step;
|
||||
if (idx > playingList.length - 1) idx = 0;
|
||||
if (idx < 0) idx = playingList.length - 1;
|
||||
break;
|
||||
case 2:
|
||||
break;
|
||||
case 3:
|
||||
break;
|
||||
}
|
||||
console.log(idx);
|
||||
play(playingList[idx].id, playing)
|
||||
};
|
||||
|
||||
const playPrev = async (id, im = true) => {};
|
||||
|
||||
const previous = async () => {
|
||||
playNext(-1);
|
||||
};
|
||||
const forward = async () => {
|
||||
playNext(1);
|
||||
};
|
||||
|
||||
const play = async (id, im = true) => {
|
||||
console.log(id);
|
||||
await getSongUrl(id)
|
||||
.then((res) => {
|
||||
@ -60,13 +94,16 @@ const play = async (id, name, im = true) => {
|
||||
store.commit("saveSettings", {
|
||||
songId: id,
|
||||
});
|
||||
pubsub.publish('zp.getSongInfo', {id: store.state.settings.songId, im})
|
||||
// console.log(audioEl.value.duration);
|
||||
pubsub.publish("zp.getSongInfo", {
|
||||
id: store.state.settings.songId,
|
||||
im,
|
||||
});
|
||||
|
||||
if (im) {
|
||||
audioEl.value.play();
|
||||
playing.value = true;
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
@ -90,7 +127,10 @@ const resume = async () => {
|
||||
}
|
||||
audioEl.value.play();
|
||||
playing.value = true;
|
||||
pubsub.publish('zp.getSongInfo', {id: store.state.settings.songId, im: true})
|
||||
pubsub.publish("zp.getSongInfo", {
|
||||
id: store.state.settings.songId,
|
||||
im: true,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@ -108,9 +148,10 @@ const favorite = () => {
|
||||
|
||||
let interval;
|
||||
watch(playing, (val, old) => {
|
||||
store.state.settings.playing = val;
|
||||
if (val === true) {
|
||||
interval = setInterval(() => {
|
||||
// console.log(audioEl.value.currentTime);
|
||||
// console.log(audioEl.value.duration);
|
||||
currentTime = audioEl.value.currentTime;
|
||||
pubsub.publish("zp.progress", {
|
||||
progress: audioEl.value.currentTime,
|
||||
@ -127,7 +168,7 @@ watch(playing, (val, old) => {
|
||||
const psToken = pubsub.subscribe("zp", (msg, data) => {
|
||||
switch (msg) {
|
||||
case "zp.play":
|
||||
play(data.id, data.name, data.im);
|
||||
play(data.id, data.im);
|
||||
break;
|
||||
case "zp.setProgressScale":
|
||||
setProgressScale(data.scale);
|
||||
@ -149,7 +190,7 @@ onUnmounted(() => {
|
||||
id="songCtrl"
|
||||
align="center"
|
||||
:size="[6]"
|
||||
style="padding-top: 2px;margin: 0 4px"
|
||||
style="padding-top: 2px; margin: 0 4px"
|
||||
>
|
||||
<n-button circle @click="favorite">
|
||||
<template #icon>
|
||||
@ -158,7 +199,7 @@ onUnmounted(() => {
|
||||
</n-icon>
|
||||
</template>
|
||||
</n-button>
|
||||
<n-button circle>
|
||||
<n-button circle @click="previous">
|
||||
<template #icon>
|
||||
<n-icon>
|
||||
<PlaySkipBack />
|
||||
@ -194,7 +235,7 @@ onUnmounted(() => {
|
||||
<!-- </template> -->
|
||||
</n-button>
|
||||
<!-- <n-button circle color="#18a058"> -->
|
||||
<n-button circle>
|
||||
<n-button circle @click="forward">
|
||||
<template #icon>
|
||||
<n-icon>
|
||||
<PlaySkipForward />
|
||||
|
@ -21,7 +21,9 @@ const showInfo = ref(false);
|
||||
const info = reactive({
|
||||
name: "",
|
||||
artists: "",
|
||||
albumPicUrl: "",
|
||||
album: {},
|
||||
duration: 0,
|
||||
mv: 0,
|
||||
});
|
||||
|
||||
//#region 取得歌曲信息
|
||||
@ -31,12 +33,19 @@ const songInfo = (id, im) => {
|
||||
showInfo.value = true;
|
||||
info.name = res.data.songs[0].name;
|
||||
info.artists = res.data.songs[0].ar;
|
||||
info.albumPicUrl = res.data.songs[0].al.picUrl;
|
||||
info.album = res.data.songs[0].al;
|
||||
info.duration = res.data.songs[0].dt;
|
||||
info.mv = res.data.songs[0].mv;
|
||||
currTime.value = '00:00'
|
||||
totalTime.value = zpTime(info.duration)
|
||||
if(im){
|
||||
store.commit('savePlayed', {...{
|
||||
const p = {...{
|
||||
id,
|
||||
date: Date.now(),
|
||||
}, ...toRaw(info)})
|
||||
}, ...toRaw(info)}
|
||||
store.commit('savePlayed', p)
|
||||
|
||||
store.commit('addToPlayingList', p)
|
||||
console.log('savePlayed');
|
||||
}
|
||||
})
|
||||
@ -76,7 +85,7 @@ onUnmounted(() => {
|
||||
<NAvatar
|
||||
:size="40"
|
||||
v-show="showInfo"
|
||||
:src="info.albumPicUrl"
|
||||
:src="info.album.picUrl"
|
||||
></NAvatar>
|
||||
<div class="song" v-show="showInfo">
|
||||
<div class="w-song">
|
||||
|
@ -1,5 +1,6 @@
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { ref, watch, toRaw } from "vue";
|
||||
import {useStore} from 'vuex';
|
||||
import { NButton, NIcon, NSpace } from "naive-ui";
|
||||
import PlaylistMusic from "@/assets/svgs/PlaylistMusic.svg";
|
||||
import VolumeOffOutline from "@/assets/svgs/VolumeOffOutline.svg";
|
||||
@ -9,9 +10,27 @@ import Playlist from "@/assets/svgs/Playlist.svg";
|
||||
import Random from "@/assets/svgs/Random.svg";
|
||||
import pubsub from 'pubsub-js';
|
||||
|
||||
const store = useStore()
|
||||
|
||||
//播放模式:0-3,顺序,循环,单曲,随机。
|
||||
const playMode = ref(0)
|
||||
let playMode = ref(0)
|
||||
|
||||
const chPlayMode = (mode) => {
|
||||
store.commit('saveSettings', {
|
||||
playMode: mode
|
||||
})
|
||||
}
|
||||
|
||||
watch(
|
||||
() => store.state.settings.playMode,
|
||||
(val, oldVal) => {
|
||||
playMode.value = toRaw(store.state.settings.playMode);
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
deep: true,
|
||||
}
|
||||
);
|
||||
|
||||
</script>
|
||||
|
||||
@ -24,28 +43,28 @@ const playMode = ref(0)
|
||||
:size="[6]"
|
||||
style="padding-top: 2px; padding-right: 8px"
|
||||
>
|
||||
<n-button circle v-if="playMode==1">
|
||||
<n-button circle v-if="playMode==1" @click="chPlayMode(2)">
|
||||
<template #icon>
|
||||
<n-icon>
|
||||
<RepeatOutline />
|
||||
</n-icon>
|
||||
</template>
|
||||
</n-button>
|
||||
<n-button circle v-if="playMode==2">
|
||||
<n-button circle v-if="playMode==2" @click="chPlayMode(3)">
|
||||
<template #icon>
|
||||
<n-icon>
|
||||
<RepeatOne />
|
||||
</n-icon>
|
||||
</template>
|
||||
</n-button>
|
||||
<n-button circle v-if="playMode==0">
|
||||
<n-button circle v-if="playMode==0" @click="chPlayMode(1)">
|
||||
<template #icon>
|
||||
<n-icon>
|
||||
<Playlist />
|
||||
</n-icon>
|
||||
</template>
|
||||
</n-button>
|
||||
<n-button circle v-if="playMode==3">
|
||||
<n-button circle v-if="playMode==3" @click="chPlayMode(0)">
|
||||
<template #icon>
|
||||
<n-icon>
|
||||
<Random />
|
||||
|
Loading…
x
Reference in New Issue
Block a user