修复bug和优化体验

This commit is contained in:
qier222 2020-10-14 21:10:45 +08:00
parent b399d5bbdc
commit 861125ea8c
17 changed files with 120 additions and 72 deletions

View File

@ -8,39 +8,37 @@
<router-view v-if="!$route.meta.keepAlive"></router-view>
</main>
<transition name="slide-up">
<BottomBar
<Player
v-if="this.$store.state.player.enable"
ref="player"
v-show="this.$route.name !== 'mv'"
/></transition>
<GlobalEvents
:filter="(event, handler, eventName) => event.target.tagName !== 'INPUT'"
@keydown.space="play"
/>
<GlobalEvents :filter="globalEventFilter" @keydown.space="play" />
</div>
</template>
<script>
import Navbar from "./components/Navbar.vue";
import BottomBar from "./components/BottomBar.vue";
import Player from "./components/Player.vue";
import GlobalEvents from "vue-global-events";
import { mapState } from "vuex";
export default {
name: "App",
components: {
Navbar,
BottomBar,
Player,
GlobalEvents,
},
computed: {
...mapState(["loading"]),
},
methods: {
play(e) {
e.preventDefault();
this.$refs.player.play();
},
globalEventFilter(event) {
if (event.target.tagName === "INPUT") return false;
if (this.$route.name === "mv") return false;
return true;
},
},
};
</script>

View File

@ -51,7 +51,11 @@ export default {
},
methods: {
goToMv(id) {
this.$router.push({ path: "/mv/" + id });
let query = {};
if (this.$parent.player !== undefined) {
query = { autoplay: this.$parent.player.playing };
}
this.$router.push({ path: "/mv/" + id, query });
},
getUrl(mv) {
if (mv.cover !== undefined) return mv.cover;

View File

@ -104,6 +104,7 @@
</template>
<script>
import { updateMediaSessionMetaData } from "@/utils/mediaSession";
import { mapState, mapMutations, mapActions } from "vuex";
import "@/assets/css/slider.css";
@ -152,14 +153,18 @@ export default {
},
methods: {
...mapMutations([
"updatePlayingStatus",
"updateShuffleStatus",
"updatePlayerList",
"shuffleTheList",
"updatePlayerState",
"updateRepeatStatus",
]),
...mapActions(["nextTrack", "previousTrack", "playTrackOnListByID"]),
...mapActions([
"nextTrack",
"previousTrack",
"playTrackOnListByID",
"addNextTrackEvent",
]),
play() {
if (this.playing) {
this.howler.pause();
@ -168,6 +173,10 @@ export default {
this.playTrackOnListByID(this.player.currentTrack.id);
}
this.howler.play();
if (this.howler._onend.length === 0) {
this.addNextTrackEvent();
updateMediaSessionMetaData(this.player.currentTrack);
}
}
},
next() {

View File

@ -31,6 +31,9 @@ const routes = [
path: "/artist/:id",
name: "artist",
component: () => import("@/views/artist"),
meta: {
keepAlive: true,
},
},
{
path: "/mv/:id",

View File

@ -4,7 +4,6 @@ import { updateMediaSessionMetaData } from "@/utils/mediaSession";
export default {
switchTrack({ state, dispatch, commit }, track) {
commit("updateCurrentTrack", track);
commit("updatePlayingStatus", true);
if (track.playable === false) {
dispatch("nextTrack");
@ -30,23 +29,21 @@ export default {
if (track.playable === false) return;
context.dispatch("switchTrack", track);
},
nextTrack({ state, dispatch, commit }, realNext = false) {
nextTrack({ state, dispatch }, realNext = false) {
let nextTrack = state.player.list.find(
(track) => track.sort === state.player.currentTrack.sort + 1
);
if (state.player.repeat === "on" && nextTrack === undefined) {
nextTrack = state.player.list.find((t) => t.sort === 0);
}
if (state.player.repeat === "one" && realNext === false) {
nextTrack = state.player.currentTrack;
}
if (state.player.repeat === "off" && nextTrack === undefined) {
commit("updatePlayingStatus", false);
state.howler.stop();
return;
if (nextTrack === undefined) {
if (state.player.repeat !== "off") {
nextTrack = state.player.list.find((t) => t.sort === 0);
} else {
return;
}
}
dispatch("switchTrack", nextTrack);
@ -55,11 +52,18 @@ export default {
let previousTrack = state.player.list.find(
(track) => track.sort === state.player.currentTrack.sort - 1
);
previousTrack =
previousTrack === null || previousTrack === undefined
? state.player.list[-1]
: previousTrack;
if (previousTrack == undefined) {
if (state.player.repeat !== "off") {
previousTrack = state.player.list.reduce((x, y) => (x > y ? x : y));
} else {
previousTrack = state.player.list.find((t) => t.sort === 0);
}
}
dispatch("switchTrack", previousTrack);
},
addNextTrackEvent({ state, dispatch }) {
state.howler.once("end", () => {
dispatch("nextTrack");
});
},
};

View File

@ -1,7 +1,6 @@
import { Howler } from "howler";
const initState = {
loading: true,
Howler: Howler,
howler: null,
contextMenu: {

View File

@ -5,9 +5,6 @@ export default {
updatePlayerState(state, { key, value }) {
state.player[key] = value;
},
updatePlayingStatus(state, status) {
state.player.playing = status;
},
updateCurrentTrack(state, track) {
state.player.currentTrack = track;
},

View File

@ -62,3 +62,8 @@ Vue.filter("formatPlayCount", (count) => {
}
return count;
});
Vue.filter("toHttps", (url) => {
if (!url) return "";
return url.replace(/^http:/, "https:");
});

View File

@ -3,7 +3,7 @@ import { getAlbum } from "@/api/album";
import { getPlaylistDetail } from "@/api/playlist";
import { getTrackDetail } from "@/api/track";
import { getArtist } from "@/api/artist";
import { trackFee } from "@/utils/common";
import { isTrackPlayable } from "@/utils/common";
export function playAList(list, id, type, trackID = "first") {
let filteredList = list.map((track, index) => {
@ -14,7 +14,7 @@ export function playAList(list, id, type, trackID = "first") {
artists: track.ar,
album: track.al,
time: track.dt,
playable: trackFee(track).playable,
playable: isTrackPlayable(track).playable,
};
});

View File

@ -126,7 +126,7 @@ export default {
});
},
computed: {
...mapState(["player", "loading"]),
...mapState(["player"]),
albumTime() {
let time = 0;
this.tracks.map((t) => (time = time + t.dt));

View File

@ -109,6 +109,7 @@ export default {
components: { Cover, ButtonTwoTone, TrackList, CoverRow, MvRow },
data() {
return {
show: false,
artist: {
img1v1Url:
"https://p1.music.126.net/VnZiScyynLG7atLIZ2YPkw==/18686200114669622.jpg",
@ -124,13 +125,9 @@ export default {
size: "",
},
showMorePopTracks: false,
show: false,
mvs: [],
};
},
created() {
this.loadData(this.$route.params.id);
},
computed: {
...mapState(["player"]),
albums() {
@ -153,8 +150,8 @@ export default {
getArtist(id).then((data) => {
this.artist = data.artist;
this.popularTracks = data.hotSongs;
if (next !== undefined) next();
this.popularTracks = mapTrackPlayableStatus(this.popularTracks);
if (next !== undefined) next();
NProgress.done();
this.show = true;
});
@ -176,6 +173,18 @@ export default {
playAList(this.popularTracks, this.artist.id, "artist", trackID);
},
},
created() {
this.loadData(this.$route.params.id);
},
activated() {
if (this.show) {
if (this.artist.id.toString() !== this.$route.params.id) {
this.show = false;
NProgress.start();
this.loadData(this.$route.params.id);
}
}
},
beforeRouteUpdate(to, from, next) {
NProgress.start();
this.artist.img1v1Url =

View File

@ -64,6 +64,7 @@ export default {
},
data() {
return {
show: false,
playlists: [],
activeCategory: "全部",
loadingMore: false,
@ -81,6 +82,7 @@ export default {
},
methods: {
loadData() {
if (!this.show) NProgress.start();
this.activeCategory =
this.$route.query.category === undefined
? "全部"
@ -95,6 +97,7 @@ export default {
this.loadingMore = false;
this.showLoadMoreButton = true;
NProgress.done();
this.show = true;
},
getPlaylist() {
this.loadingMore = true;

View File

@ -1,5 +1,5 @@
<template>
<div class="home">
<div class="home" v-show="show">
<div class="index-row">
<div class="title">
by Apple Music
@ -57,6 +57,7 @@ import { toplists, recommendPlaylist } from "@/api/playlist";
import { toplistOfArtists } from "@/api/artist";
import { byAppleMusic } from "@/utils/staticPlaylist";
import { newAlbums } from "@/api/album";
import NProgress from "nprogress";
import CoverRow from "@/components/CoverRow.vue";
@ -65,6 +66,7 @@ export default {
components: { CoverRow },
data() {
return {
show: false,
recommendPlaylist: { name: "推荐歌单", items: [] },
newReleasesAlbum: { name: "新专速递", items: [] },
topList: {
@ -86,10 +88,13 @@ export default {
},
methods: {
loadData() {
if (!this.show) NProgress.start();
recommendPlaylist({
limit: 10,
}).then((data) => {
this.recommendPlaylist.items = data.result;
NProgress.done();
this.show = true;
});
newAlbums({
area: "EA",

View File

@ -1,5 +1,5 @@
<template>
<div>
<div v-show="show">
<h1>
<img class="head" :src="user.profile.avatarUrl | resizeImage" />{{
user.profile.nickname
@ -59,6 +59,7 @@ import { userDetail, userPlaylist } from "@/api/user";
import { mapTrackPlayableStatus, randomNum } from "@/utils/common";
import { getPlaylistDetail } from "@/api/playlist";
import { playPlaylistByID } from "@/utils/play";
import NProgress from "nprogress";
import TrackList from "@/components/TrackList.vue";
import CoverRow from "@/components/CoverRow.vue";
@ -69,6 +70,7 @@ export default {
components: { SvgIcon, CoverRow, TrackList },
data() {
return {
show: false,
user: {
profile: {
avatarUrl: "",
@ -82,6 +84,7 @@ export default {
};
},
created() {
NProgress.start();
userDetail(this.settings.user.userId).then((data) => {
this.user = data;
});
@ -135,6 +138,7 @@ export default {
let oldTracks = this.likedSongs.tracks;
this.likedSongs = data.playlist;
this.likedSongs.tracks = oldTracks;
this.getMoreLikedSongs();
this.getRandomLyric();
});
@ -144,6 +148,8 @@ export default {
getTrackDetail(TrackIDs.join(",")).then((data) => {
this.likedSongs.tracks = data.songs;
this.likedSongs.tracks = mapTrackPlayableStatus(this.likedSongs.tracks);
NProgress.done();
this.show = true;
});
},
getRandomLyric() {

View File

@ -62,17 +62,16 @@ export default {
Promise.all(requests).then((results) => {
let sources = results.map((result) => {
return {
src: result.data.url,
src: result.data.url.replace(/^http:/, "https:"),
type: "video/mp4",
size: result.data.r,
};
});
console.table(sources);
this.player.source = {
type: "video",
title: this.mv.data.name,
sources: sources,
poster: this.mv.data.cover,
poster: this.mv.data.cover.replace(/^http:/, "https:"),
};
NProgress.done();
});
@ -82,10 +81,6 @@ export default {
});
},
},
created() {
if (this.$route.query.autoplay === "true")
this.videoOptions.autoplay = true;
},
mounted() {
let videoOptions = {
settings: ["quality"],
@ -95,8 +90,12 @@ export default {
options: [1080, 720, 480, 240],
},
};
if (this.$route.query.autoplay === "true") videoOptions.autoplay = true;
this.player = new Plyr(this.$refs.videoPlayer, videoOptions);
this.player.volume = this.$store.state.player.volume;
this.player.on("playing", () => {
this.$store.state.howler.pause();
});
this.getData(this.$route.params.id);
console.log("网易云你这mv音频码率也太糊了吧🙄");
},
@ -149,7 +148,6 @@ export default {
.section-title {
font-size: 18px;
font-weight: 600;
margin-bottom: 16px;
color: rgba(0, 0, 0, 0.88);
}
}

View File

@ -94,6 +94,7 @@ export default {
},
data() {
return {
show: false,
playlist: {
coverImgUrl: "",
creator: {
@ -105,29 +106,10 @@ export default {
tracks: [],
loadingMore: false,
lastLoadedTrackIndex: 9,
show: false,
};
},
created() {
this.id = this.$route.params.id;
getPlaylistDetail(this.id)
.then((data) => {
this.playlist = data.playlist;
this.tracks = data.playlist.tracks;
this.tracks = mapTrackPlayableStatus(this.tracks);
NProgress.done();
this.show = true;
if (this.playlist.trackCount > this.tracks.length) {
window.addEventListener("scroll", this.handleScroll, true);
}
return data;
})
.then(() => {
if (this.playlist.trackCount > this.tracks.length) {
this.loadingMore = true;
this.loadMore();
}
});
this.loadData(this.$route.params.id);
},
destroyed() {
window.removeEventListener("scroll", this.handleScroll, true);
@ -149,6 +131,29 @@ export default {
this.playPlaylistByID();
this.shuffleTheList();
},
loadData(id, next = undefined) {
console.log("loadData");
this.id = id;
getPlaylistDetail(this.id)
.then((data) => {
this.playlist = data.playlist;
this.tracks = data.playlist.tracks;
this.tracks = mapTrackPlayableStatus(this.tracks);
NProgress.done();
if (next !== undefined) next();
this.show = true;
if (this.playlist.trackCount > this.tracks.length) {
window.addEventListener("scroll", this.handleScroll, true);
}
return data;
})
.then(() => {
if (this.playlist.trackCount > this.tracks.length) {
this.loadingMore = true;
this.loadMore();
}
});
},
loadMore() {
let trackIDs = this.playlist.trackIds.filter((t, index) => {
if (

View File

@ -1,5 +1,5 @@
<template>
<div class="search">
<div class="search" v-show="show">
<h1><span>Search for</span> "{{ keywords }}"</h1>
<div class="result" v-if="result !== undefined">
<div class="row">
@ -135,6 +135,7 @@ export default {
},
data() {
return {
show: false,
result: {},
mvs: [],
type: 1,
@ -164,6 +165,7 @@ export default {
search({ keywords: keywords, type: 1018 }).then((data) => {
this.result = data.result;
NProgress.done();
this.show = true;
});
search({ keywords: keywords, type: 1004 }).then((data) => {
this.mvs = data.result.mvs;
@ -174,6 +176,7 @@ export default {
this.getData(this.$route.query.keywords);
},
beforeRouteUpdate(to, from, next) {
this.show = false;
next();
NProgress.start();
this.getData(to.query.keywords);