mirror of
https://github.com/qier222/YesPlayMusic.git
synced 2024-11-23 07:03:14 +08:00
fix: bugs
This commit is contained in:
parent
872fd73b05
commit
4f4f2b09e3
|
@ -100,6 +100,7 @@ img {
|
||||||
border-radius: 0.75em;
|
border-radius: 0.75em;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
aspect-ratio: 1 / 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cover-hover {
|
.cover-hover {
|
||||||
|
@ -156,6 +157,7 @@ img {
|
||||||
z-index: -1;
|
z-index: -1;
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
border-radius: 0.75em;
|
border-radius: 0.75em;
|
||||||
|
aspect-ratio: 1 / 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fade-enter-active,
|
.fade-enter-active,
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
:imageUrl="getImageUrl(item)"
|
:imageUrl="getImageUrl(item)"
|
||||||
:type="type"
|
:type="type"
|
||||||
:id="item.id"
|
:id="item.id"
|
||||||
:playButtonSize="type === 'artist' ? 26 : 22"
|
:playButtonSize="type === 'artist' ? 26 : playButtonSize"
|
||||||
/>
|
/>
|
||||||
<div class="text">
|
<div class="text">
|
||||||
<div class="info" v-if="showPlayCount">
|
<div class="info" v-if="showPlayCount">
|
||||||
|
@ -55,6 +55,7 @@ export default {
|
||||||
showPlayCount: { type: Boolean, default: false },
|
showPlayCount: { type: Boolean, default: false },
|
||||||
columnNumber: { type: Number, default: 5 },
|
columnNumber: { type: Number, default: 5 },
|
||||||
gap: { type: String, default: "44px 24px" },
|
gap: { type: String, default: "44px 24px" },
|
||||||
|
playButtonSize: { type: Number, default: 22 },
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
rowStyles() {
|
rowStyles() {
|
||||||
|
|
|
@ -21,8 +21,16 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapMutations, mapState } from "vuex";
|
import { mapMutations, mapState, mapActions } from "vuex";
|
||||||
import { dailyRecommendTracks } from "@/api/playlist";
|
import { dailyRecommendTracks } from "@/api/playlist";
|
||||||
|
import { isAccountLoggedIn } from "@/utils/auth";
|
||||||
|
import { sample } from "lodash";
|
||||||
|
|
||||||
|
const defaultCovers = [
|
||||||
|
"https://p2.music.126.net/0-Ybpa8FrDfRgKYCTJD8Xg==/109951164796696795.jpg",
|
||||||
|
"https://p2.music.126.net/QxJA2mr4hhb9DZyucIOIQw==/109951165422200291.jpg",
|
||||||
|
"https://p1.music.126.net/AhYP9TET8l-VSGOpWAKZXw==/109951165134386387.jpg",
|
||||||
|
];
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "DailyTracksCard",
|
name: "DailyTracksCard",
|
||||||
|
@ -31,26 +39,33 @@ export default {
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(["dailyTracks"]),
|
...mapState(["dailyTracks"]),
|
||||||
|
coverUrl() {
|
||||||
|
return this.dailyTracks[0]?.al.picUrl || sample(defaultCovers);
|
||||||
|
},
|
||||||
cardStyles() {
|
cardStyles() {
|
||||||
return {
|
return {
|
||||||
background:
|
background: `no-repeat url("${this.coverUrl}?param=1024y1024") center/cover`,
|
||||||
this.dailyTracks.length !== 0
|
|
||||||
? `no-repeat url("${this.dailyTracks[0].al.picUrl}?param=1024y1024") center/cover`
|
|
||||||
: "",
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
...mapActions(["showToast"]),
|
||||||
...mapMutations(["updateDailyTracks"]),
|
...mapMutations(["updateDailyTracks"]),
|
||||||
loadDailyTracks() {
|
loadDailyTracks() {
|
||||||
dailyRecommendTracks().then((result) => {
|
dailyRecommendTracks()
|
||||||
|
.then((result) => {
|
||||||
this.updateDailyTracks(result.data.dailySongs);
|
this.updateDailyTracks(result.data.dailySongs);
|
||||||
});
|
})
|
||||||
|
.catch(() => {});
|
||||||
},
|
},
|
||||||
goToDailyTracks() {
|
goToDailyTracks() {
|
||||||
this.$router.push({ name: "dailySongs" });
|
this.$router.push({ name: "dailySongs" });
|
||||||
},
|
},
|
||||||
playDailyTracks() {
|
playDailyTracks() {
|
||||||
|
if (!isAccountLoggedIn()) {
|
||||||
|
this.showToast("此操作需要登录网易云账号");
|
||||||
|
return;
|
||||||
|
}
|
||||||
let trackIDs = this.dailyTracks.map((t) => t.id);
|
let trackIDs = this.dailyTracks.map((t) => t.id);
|
||||||
this.$store.state.player.replacePlaylist(
|
this.$store.state.player.replacePlaylist(
|
||||||
trackIDs,
|
trackIDs,
|
||||||
|
|
|
@ -124,8 +124,8 @@ export default {
|
||||||
return isLooseLoggedIn();
|
return isLooseLoggedIn();
|
||||||
},
|
},
|
||||||
avatarUrl() {
|
avatarUrl() {
|
||||||
return this.data.user.avatarUrl
|
return this.data?.user?.avatarUrl && this.isLooseLoggedIn
|
||||||
? `${this.data.user.avatarUrl}?param=512y512`
|
? `${this.data?.user?.avatarUrl}?param=512y512`
|
||||||
: "http://s4.music.126.net/style/web2/img/default/default_avatar.jpg?param=60y60";
|
: "http://s4.music.126.net/style/web2/img/default/default_avatar.jpg?param=60y60";
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
17
src/main.js
17
src/main.js
|
@ -13,6 +13,23 @@ import * as Sentry from "@sentry/browser";
|
||||||
import { Vue as VueIntegration } from "@sentry/integrations";
|
import { Vue as VueIntegration } from "@sentry/integrations";
|
||||||
import { Integrations } from "@sentry/tracing";
|
import { Integrations } from "@sentry/tracing";
|
||||||
|
|
||||||
|
window.resetApp = () => {
|
||||||
|
localStorage.clear();
|
||||||
|
indexedDB.deleteDatabase("yesplaymusic");
|
||||||
|
document.cookie.split(";").forEach(function (c) {
|
||||||
|
document.cookie = c
|
||||||
|
.replace(/^ +/, "")
|
||||||
|
.replace(/=.*/, "=;expires=" + new Date().toUTCString() + ";path=/");
|
||||||
|
});
|
||||||
|
return "已重置应用,请刷新页面(按Ctrl/Command + R)";
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
"如出现问题,可尝试在本页输入 %cresetApp()%c 然后按回车重置应用。",
|
||||||
|
"background: #eaeffd;color:#335eea;padding: 4px 6px;border-radius:3px;",
|
||||||
|
"background:unset;color:unset;"
|
||||||
|
);
|
||||||
|
|
||||||
Vue.use(VueAnalytics, {
|
Vue.use(VueAnalytics, {
|
||||||
id: "UA-180189423-1",
|
id: "UA-180189423-1",
|
||||||
router,
|
router,
|
||||||
|
|
|
@ -2,7 +2,7 @@ import Vue from "vue";
|
||||||
import VueRouter from "vue-router";
|
import VueRouter from "vue-router";
|
||||||
import NProgress from "nprogress";
|
import NProgress from "nprogress";
|
||||||
import "@/assets/css/nprogress.css";
|
import "@/assets/css/nprogress.css";
|
||||||
import { isLooseLoggedIn } from "@/utils/auth";
|
import { isLooseLoggedIn, isAccountLoggedIn } from "@/utils/auth";
|
||||||
|
|
||||||
NProgress.configure({ showSpinner: false, trickleSpeed: 100 });
|
NProgress.configure({ showSpinner: false, trickleSpeed: 100 });
|
||||||
|
|
||||||
|
@ -122,6 +122,9 @@ const routes = [
|
||||||
path: "/daily/songs",
|
path: "/daily/songs",
|
||||||
name: "dailySongs",
|
name: "dailySongs",
|
||||||
component: () => import("@/views/dailyTracks.vue"),
|
component: () => import("@/views/dailyTracks.vue"),
|
||||||
|
meta: {
|
||||||
|
requireAccountLogin: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/lastfm/callback",
|
path: "/lastfm/callback",
|
||||||
|
@ -147,6 +150,13 @@ VueRouter.prototype.push = function push(location) {
|
||||||
|
|
||||||
router.beforeEach((to, from, next) => {
|
router.beforeEach((to, from, next) => {
|
||||||
// 需要登录的逻辑
|
// 需要登录的逻辑
|
||||||
|
if (to.meta.requireAccountLogin) {
|
||||||
|
if (isAccountLoggedIn()) {
|
||||||
|
next();
|
||||||
|
} else {
|
||||||
|
next({ path: "/login/account" });
|
||||||
|
}
|
||||||
|
}
|
||||||
if (to.meta.requireLogin) {
|
if (to.meta.requireLogin) {
|
||||||
if (isLooseLoggedIn()) {
|
if (isLooseLoggedIn()) {
|
||||||
next();
|
next();
|
||||||
|
|
|
@ -160,9 +160,12 @@ export default class {
|
||||||
this._shuffledList = shuffle(list);
|
this._shuffledList = shuffle(list);
|
||||||
if (firstTrackID !== "first") this._shuffledList.unshift(firstTrackID);
|
if (firstTrackID !== "first") this._shuffledList.unshift(firstTrackID);
|
||||||
}
|
}
|
||||||
async _scrobble(track, time, complete = false) {
|
async _scrobble(track, time, completed = false) {
|
||||||
|
console.debug(
|
||||||
|
`[debug][Player.js] scrobble track 👉 ${track.name} by ${track.ar[0].name} 👉 time:${time} completed: ${completed}`
|
||||||
|
);
|
||||||
const trackDuration = ~~(track.dt / 1000);
|
const trackDuration = ~~(track.dt / 1000);
|
||||||
time = complete ? trackDuration : time;
|
time = completed ? trackDuration : ~~time;
|
||||||
scrobble({
|
scrobble({
|
||||||
id: track.id,
|
id: track.id,
|
||||||
sourceid: this.playlistSource.id,
|
sourceid: this.playlistSource.id,
|
||||||
|
@ -247,7 +250,9 @@ export default class {
|
||||||
autoplay = true,
|
autoplay = true,
|
||||||
ifUnplayableThen = "playNextTrack"
|
ifUnplayableThen = "playNextTrack"
|
||||||
) {
|
) {
|
||||||
if (autoplay) this._scrobble(this.currentTrack, this._howler?.seek(), true);
|
if (autoplay) {
|
||||||
|
this._scrobble(this.currentTrack, this._howler.seek());
|
||||||
|
}
|
||||||
return getTrackDetail(id).then((data) => {
|
return getTrackDetail(id).then((data) => {
|
||||||
let track = data.songs[0];
|
let track = data.songs[0];
|
||||||
this._currentTrack = track;
|
this._currentTrack = track;
|
||||||
|
@ -267,8 +272,11 @@ export default class {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
_cacheNextTrack() {
|
_cacheNextTrack() {
|
||||||
const nextTrack = this._getNextTrack();
|
let nextTrackID = this._isPersonalFM
|
||||||
getTrackDetail(nextTrack[0]).then((data) => {
|
? this._personalFMNextTrack.id
|
||||||
|
: this._getNextTrack()[0];
|
||||||
|
if (!nextTrackID) return;
|
||||||
|
getTrackDetail(nextTrackID).then((data) => {
|
||||||
let track = data.songs[0];
|
let track = data.songs[0];
|
||||||
this._getAudioSource(track);
|
this._getAudioSource(track);
|
||||||
});
|
});
|
||||||
|
@ -342,7 +350,8 @@ export default class {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_nextTrackCallback() {
|
_nextTrackCallback() {
|
||||||
if (!this.isPersonalFM && this.repeatMode === "one") {
|
this._scrobble(this._currentTrack, 0, true);
|
||||||
|
if (this.repeatMode === "one") {
|
||||||
this._replaceCurrentTrack(this._currentTrack.id);
|
this._replaceCurrentTrack(this._currentTrack.id);
|
||||||
} else {
|
} else {
|
||||||
this.playNextTrack();
|
this.playNextTrack();
|
||||||
|
@ -464,11 +473,7 @@ export default class {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setOutputDevice() {
|
setOutputDevice() {
|
||||||
if (
|
if (this._howler._sounds.length <= 0 || !this._howler._sounds[0]._node) {
|
||||||
process.env.IS_ELECTRON !== true ||
|
|
||||||
this._howler._sounds.length <= 0 ||
|
|
||||||
!this._howler._sounds[0]._node
|
|
||||||
) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this._howler._sounds[0]._node.setSinkId(store.state.settings.outputDevice);
|
this._howler._sounds[0]._node.setSinkId(store.state.settings.outputDevice);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="search" v-show="show">
|
<div class="search" v-show="show">
|
||||||
<div class="row" v-show="artists.length > 0 || albums.length > 0">
|
<div class="row" v-show="artists.length > 0 || albums.length > 0">
|
||||||
<div class="artists">
|
<div class="artists" v-show="artists.length > 0">
|
||||||
<div class="section-title" v-show="artists.length > 0"
|
<div class="section-title" v-show="artists.length > 0"
|
||||||
>{{ $t("search.artist")
|
>{{ $t("search.artist")
|
||||||
}}<router-link :to="`/search/${keywords}/artists`">{{
|
}}<router-link :to="`/search/${keywords}/artists`">{{
|
||||||
|
@ -30,6 +30,7 @@
|
||||||
:columnNumber="3"
|
:columnNumber="3"
|
||||||
subTextFontSize="14px"
|
subTextFontSize="14px"
|
||||||
gap="34px 24px"
|
gap="34px 24px"
|
||||||
|
:playButtonSize="26"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -68,6 +69,7 @@
|
||||||
:columnNumber="6"
|
:columnNumber="6"
|
||||||
subTextFontSize="14px"
|
subTextFontSize="14px"
|
||||||
gap="34px 24px"
|
gap="34px 24px"
|
||||||
|
:playButtonSize="26"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="settings">
|
<div class="settings">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="user" v-if="data.user.nickname !== undefined">
|
<div class="user" v-if="showUserInfo">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<img class="avatar" :src="data.user.avatarUrl" />
|
<img class="avatar" :src="data.user.avatarUrl" />
|
||||||
<div class="info">
|
<div class="info">
|
||||||
|
@ -317,7 +317,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapState } from "vuex";
|
import { mapState } from "vuex";
|
||||||
import { doLogout } from "@/utils/auth";
|
import { isLooseLoggedIn, doLogout } from "@/utils/auth";
|
||||||
import { auth as lastfmAuth } from "@/api/lastfm";
|
import { auth as lastfmAuth } from "@/api/lastfm";
|
||||||
import { changeAppearance, bytesToSize } from "@/utils/common";
|
import { changeAppearance, bytesToSize } from "@/utils/common";
|
||||||
import { countDBSize, clearDB } from "@/utils/db";
|
import { countDBSize, clearDB } from "@/utils/db";
|
||||||
|
@ -351,6 +351,10 @@ export default {
|
||||||
version() {
|
version() {
|
||||||
return pkg.version;
|
return pkg.version;
|
||||||
},
|
},
|
||||||
|
showUserInfo() {
|
||||||
|
return isLooseLoggedIn() && this.data.user.nickname;
|
||||||
|
},
|
||||||
|
|
||||||
lang: {
|
lang: {
|
||||||
get() {
|
get() {
|
||||||
return this.settings.lang;
|
return this.settings.lang;
|
||||||
|
@ -517,11 +521,11 @@ export default {
|
||||||
value,
|
value,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
},
|
||||||
isLastfmConnected() {
|
isLastfmConnected() {
|
||||||
return this.lastfm.key !== undefined;
|
return this.lastfm.key !== undefined;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
getAllOutputDevices() {
|
getAllOutputDevices() {
|
||||||
navigator.mediaDevices.enumerateDevices().then((devices) => {
|
navigator.mediaDevices.enumerateDevices().then((devices) => {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user