Merge branch 'master' into local-service

master
kunkka 4 years ago
commit ab46df03de

@ -1,6 +1,6 @@
{
"name": "YesPlayMusic",
"version": "0.1.0",
"version": "0.2.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",

@ -37,3 +37,34 @@ export function newAlbums(params) {
params,
});
}
/**
* 专辑动态信息
* 说明 : 调用此接口 , 传入专辑 id, 可获得专辑动态信息,如是否收藏,收藏数,评论数,分享数
* - id - 专辑id
* @param {number} id
*/
export function albumDynamicDetail(id) {
return request({
url: "/album/detail/dynamic",
method: "get",
params: { id, timestamp: new Date().getTime() },
});
}
/**
* 收藏/取消收藏专辑
* 说明 : 调用此接口,可收藏/取消收藏专辑
* - id - 返专辑 id
* - t - 1 为收藏,其他为取消收藏
* @param {Object} params
* @param {number} params.id
* @param {number} params.t
*/
export function likeAAlbum(params) {
return request({
url: "/album/sub",
method: "post",
params,
});
}

@ -12,6 +12,7 @@ export function getArtist(id) {
method: "get",
params: {
id,
timestamp: new Date().getTime(),
},
}).then((data) => {
data.hotSongs = mapTrackPlayableStatus(data.hotSongs);
@ -71,3 +72,20 @@ export function artistMv(id) {
},
});
}
/**
* 收藏歌手
* 说明 : 调用此接口 , 传入歌手 id, 可收藏歌手
* - id: 歌手 id
* - t: 操作,1 为收藏,其他为取消收藏
* @param {Object} params
* @param {number} params.id
* @param {number} params.t
*/
export function followAArtist(params) {
return request({
url: "/artist/sub",
method: "post",
params,
});
}

@ -36,7 +36,7 @@ export function userPlaylist(params) {
}
/**
* 喜欢音乐列表
* 喜欢音乐列表需要登录
* 说明 : 调用此接口 , 传入用户 id, 可获取已喜欢音乐id列表(id数组)
* - uid: 用户 id
* @param {number} uid
@ -52,8 +52,13 @@ export function userLikedSongsIDs(uid) {
});
}
/**
* 每日签到
* 说明 : 调用此接口可签到获取积分
* - type: 签到类型 , 默认 0, 其中 0 为安卓端签到 ,1 web/PC 签到
* @param {number} type
*/
export function dailySignin(type = 0) {
//可选参数 : type: 签到类型 , 默认 0, 其中 0 为安卓端签到 ,1 为 web/PC 签到
return request({
url: "/daily_signin",
method: "post",
@ -62,3 +67,50 @@ export function dailySignin(type = 0) {
},
});
}
/**
* 获取收藏的专辑需要登录
* 说明 : 调用此接口可获取到用户收藏的专辑
* - limit : 返回数量 , 默认为 30
* - offset : 偏移数量用于分页 , :( 页数 -1)*30, 其中 30 limit 的值 , 默认为 0
* @param {Object} params
* @param {number} params.limit
* @param {number=} params.offset
*/
export function likedAlbums() {
return request({
url: "/album/sublist",
method: "get",
params: {
timestamp: new Date().getTime(),
},
});
}
/**
* 获取收藏的歌手需要登录
* 说明 : 调用此接口可获取到用户收藏的歌手
*/
export function likedArtists() {
return request({
url: "/artist/sublist",
method: "get",
params: {
timestamp: new Date().getTime(),
},
});
}
/**
* 获取收藏的MV需要登录
* 说明 : 调用此接口可获取到用户收藏的MV
*/
export function likedMVs() {
return request({
url: "/mv/sublist",
method: "get",
params: {
timestamp: new Date().getTime(),
},
});
}

@ -49,10 +49,13 @@ export default {
<style lang="scss" scoped>
button {
height: 40px;
min-width: 40px;
display: flex;
align-items: center;
justify-content: center;
font-size: 18px;
line-height: 18px;
font-weight: 600;
background-color: var(--color-primary-bg);
color: var(--color-primary);

@ -76,8 +76,9 @@ export default {
created() {
this.shadowStyle = {
height: `${this.size}px`,
width: `${this.size}px`,
width: `${~~(this.size * 0.96)}px`,
top: `${this.shadowMargin}px`,
right: `${~~(this.size * 0.02)}px`,
borderRadius: `${this.radius}px`,
};
this.playButtonStyle = {
@ -165,6 +166,13 @@ export default {
height: 208px;
transform: scale(0.98);
}
[data-theme="dark"] {
.shadow {
filter: blur(16px) brightness(68%);
transform: scale(0.96);
}
}
.play-button {
opacity: 0;
display: flex;

@ -95,8 +95,12 @@ export default {
if (this.subText === "creator") return "by " + item.creator.nickname;
if (this.subText === "releaseYear")
return new Date(item.publishTime).getFullYear();
if (this.subText === "artist")
return `<a href="/#/artist/${item.artist.id}">${item.artist.name}</a>`;
if (this.subText === "artist") {
if (item.artist !== undefined)
return `<a href="/#/artist/${item.artist.id}">${item.artist.name}</a>`;
if (item.artists !== undefined)
return `<a href="/#/artist/${item.artists[0].id}">${item.artists[0].name}</a>`;
}
if (this.subText === "albumType+releaseYear") {
let albumType = item.type;
if (item.type === "EP/Single") {

@ -1,34 +1,27 @@
<template>
<div class="mv-row">
<div class="mv" v-for="mv in mvs" :key="mv.id">
<div class="mv" v-for="mv in mvs" :key="getID(mv)">
<div class="cover-container">
<img
class="cover"
:src="getUrl(mv)"
@mouseover="hoverVideoID = mv.id"
@mouseover="hoverVideoID = getID(mv)"
@mouseleave="hoverVideoID = 0"
@click="goToMv(mv.id)"
@click="goToMv(getID(mv))"
/>
<transition name="fade">
<img
class="shadow"
v-show="hoverVideoID === mv.id"
v-show="hoverVideoID === getID(mv)"
:src="getUrl(mv)"
/>
</transition>
</div>
<div class="info">
<div class="title">
<router-link :to="'/mv/' + mv.id">{{ mv.name }}</router-link>
</div>
<div class="artist">
<router-link
v-if="subtitle === 'artist'"
:to="'/artist/' + mv.artistId"
>{{ mv.artistName }}</router-link
>
<span v-if="subtitle === 'publishTime'">{{ mv.publishTime }}</span>
<router-link :to="'/mv/' + getID(mv)">{{ getTitle(mv) }}</router-link>
</div>
<div class="artist" v-html="getSubtitle(mv)"></div>
</div>
</div>
</div>
@ -62,6 +55,30 @@ export default {
if (mv.imgurl16v9 !== undefined) return mv.imgurl16v9;
if (mv.coverUrl !== undefined) return mv.coverUrl;
},
getID(mv) {
if (mv.id !== undefined) return mv.id;
if (mv.vid !== undefined) return mv.vid;
},
getTitle(mv) {
if (mv.name !== undefined) return mv.name;
if (mv.title !== undefined) return mv.title;
},
getSubtitle(mv) {
if (this.subtitle === "artist") {
let artistName = "null";
let artistID = 0;
if (mv.artistName !== undefined) {
artistName = mv.artistName;
artistID = mv.artistId;
} else if (mv.creator !== undefined) {
artistName = mv.creator[0].userName;
artistID = mv.creator[0].userId;
}
return `<a href="/artist/${artistID}">${artistName}</a>`;
} else if (this.subtitle === "publishTime") {
return mv.publishTime;
}
},
},
};
</script>

@ -137,8 +137,7 @@ nav {
left: 12px;
}
&:hover {
background: var(--color-primary-bg);
color: var(--color-primary);
background: var(--color-secondary-bg);
}
&:active {
transform: scale(0.92);

@ -146,13 +146,13 @@ export default {
this.progress = ~~this.howler.seek();
}, 1000);
if (isAccountLoggedIn()) {
userLikedSongsIDs(this.settings.user.userId).then((data) => {
userLikedSongsIDs(this.data.user.userId).then((data) => {
this.updateLikedSongs(data.ids);
});
}
},
computed: {
...mapState(["player", "howler", "settings", "liked", "accountLogin"]),
...mapState(["player", "howler", "settings", "liked", "data"]),
currentTrack() {
return this.player.currentTrack;
},
@ -175,6 +175,9 @@ export default {
let max = ~~(this.currentTrack.dt / 1000);
return max > 1 ? max - 1 : max;
},
accountLogin() {
return isAccountLoggedIn();
},
},
methods: {
...mapMutations([
@ -266,7 +269,7 @@ export default {
});
},
goToList() {
if (this.player.listInfo.id === this.settings.user.likedSongPlaylistID)
if (this.player.listInfo.id === this.data.likedSongPlaylistID)
this.$router.push({ path: "/library/liked-songs" });
else
this.$router.push({

@ -3,10 +3,18 @@
<ContextMenu ref="menu">
<div class="item" @click="play">Play</div>
<div class="item" @click="playNext">Play Next</div>
<div class="item" @click="like" v-show="!isRightClickedTrackLiked">
<div
class="item"
@click="like"
v-show="!isRightClickedTrackLiked && accountLogin"
>
Save to my Liked Songs
</div>
<div class="item" @click="like" v-show="isRightClickedTrackLiked">
<div
class="item"
@click="like"
v-show="isRightClickedTrackLiked && accountLogin"
>
Remove from my Liked Songs
</div>
</ContextMenu>
@ -29,6 +37,7 @@ import {
playAList,
appendTrackToPlayerList,
} from "@/utils/play";
import { isAccountLoggedIn } from "@/utils/auth";
import TrackListItem from "@/components/TrackListItem.vue";
import ContextMenu from "@/components/ContextMenu.vue";
@ -67,6 +76,9 @@ export default {
isRightClickedTrackLiked() {
return this.liked.songs.includes(this.rightClickedTrack?.id);
},
accountLogin() {
return isAccountLoggedIn();
},
},
methods: {
...mapMutations(["updateLikedSongs"]),

@ -78,7 +78,7 @@
</template>
<script>
import { mapState } from "vuex";
import { isAccountLoggedIn } from "@/utils/auth";
import ArtistsInLine from "@/components/ArtistsInLine.vue";
import ExplicitSymbol from "@/components/ExplicitSymbol.vue";
@ -93,7 +93,6 @@ export default {
return { focus: false, trackStyle: {} };
},
computed: {
...mapState(["accountLogin"]),
imgUrl() {
if (this.track.al !== undefined) return this.track.al.picUrl;
if (this.track.album !== undefined) return this.track.album.picUrl;
@ -128,6 +127,9 @@ export default {
if (this.isPlaying) trackClass.push("playing");
return trackClass;
},
accountLogin() {
return isAccountLoggedIn();
},
},
methods: {
goToAlbum() {

@ -118,7 +118,7 @@ const router = new VueRouter({
router.beforeEach((to, from, next) => {
// 需要登录的逻辑
if (to.meta.requireLogin) {
if (store.state.settings.user.nickname === undefined) {
if (store.state.data.user.nickname === undefined) {
next({ path: "/login" });
}
if (isLooseLoggedIn()) {

@ -3,22 +3,28 @@ import Vuex from "vuex";
import state from "./state";
import mutations from "./mutations";
import actions from "./actions";
import initState from "./initState";
import initLocalStorage from "./initLocalStorage";
import { Howl, Howler } from "howler";
import { changeAppearance } from "@/utils/common";
import updateApp from "@/utils/updateApp";
import pack from "../../package.json";
if (localStorage.getItem("appVersion") === null) {
localStorage.setItem("player", JSON.stringify(initState.player));
localStorage.setItem("settings", JSON.stringify(initState.settings));
localStorage.setItem("appVersion", "0.1");
localStorage.setItem("player", JSON.stringify(initLocalStorage.player));
localStorage.setItem("settings", JSON.stringify(initLocalStorage.settings));
localStorage.setItem("data", JSON.stringify(initLocalStorage.data));
localStorage.setItem("appVersion", pack.version);
window.location.reload();
}
updateApp();
const saveToLocalStorage = (store) => {
store.subscribe((mutation, state) => {
// console.log(mutation);
localStorage.setItem("player", JSON.stringify(state.player));
localStorage.setItem("settings", JSON.stringify(state.settings));
localStorage.setItem("data", JSON.stringify(state.data));
});
};

@ -1,14 +1,4 @@
const initState = {
howler: null,
accountLogin: false,
usernameLogin: false,
liked: {
songs: [],
},
contextMenu: {
clickObjectID: 0,
showMenu: false,
},
export default {
player: {
enable: false,
show: true,
@ -83,16 +73,16 @@ const initState = {
enable: true,
},
],
user: {
id: 0,
},
lang: null,
appearance: "auto",
musicQuality: 320000,
showGithubIcon: true,
showPlaylistsByAppleMusic: true,
},
data: {
user: {},
likedSongPlaylistID: 0,
lastRefreshCookieDate: 0,
loginMode: null,
},
};
export default initState;

@ -81,22 +81,6 @@ export default {
return track;
});
},
updateAccountLogin(state, status) {
state.accountLogin = status;
},
updateUsernameLogin(state, status) {
state.usernameLogin = status;
},
updateLogout() {
this.commit("updateAccountLogin", false);
this.commit("updateUsernameLogin", false);
},
updateUser(state, user) {
state.settings.user = user;
},
updateUserInfo(state, { key, value }) {
state.settings.user[key] = value;
},
updateLikedSongs(state, trackIDs) {
state.liked.songs = trackIDs;
},
@ -119,4 +103,7 @@ export default {
updateSettings(state, { key, value }) {
state.settings[key] = value;
},
updateData(state, { key, value }) {
state.data[key] = value;
},
};

@ -1,7 +1,5 @@
export default {
howler: null,
accountLogin: false,
usernameLogin: false,
liked: {
songs: [],
},
@ -11,4 +9,5 @@ export default {
},
player: JSON.parse(localStorage.getItem("player")),
settings: JSON.parse(localStorage.getItem("settings")),
data: JSON.parse(localStorage.getItem("data")),
};

@ -4,14 +4,12 @@ import store from "@/store";
export function doLogout() {
logout();
// 移除前端本地用来认证登录的字段
Cookies.remove("loginMode");
// 网易云的接口会自动移除该 cookies
// Cookies.remove("MUSIC_U");
// 更新状态仓库中的用户信息
store.commit("updateUser", { id: 0 });
store.commit("updateData", { key: "user", value: {} });
// 更新状态仓库中的登录状态
store.commit("updateLogout");
store.commit("updateData", { key: "loginMode", value: null });
}
// MUSIC_U 只有在账户登录的情况下才有
@ -23,16 +21,13 @@ export function isLoggedIn() {
export function isAccountLoggedIn() {
return (
Cookies.get("MUSIC_U") !== undefined &&
Cookies.get("loginMode") === "account"
store.state.data.loginMode === "account"
);
}
// 用户名搜索(用户数据为只读)
export function isUsernameLoggedIn() {
return (
Cookies.get("MUSIC_U") === undefined &&
Cookies.get("loginMode") === "username"
);
return store.state.data.loginMode === "username";
}
// 账户登录或者用户名搜索都判断为登录,宽松检查

@ -10,7 +10,7 @@ export function isTrackPlayable(track) {
reason: "",
};
if (track.fee === 1 || track.privilege?.fee === 1) {
if (isAccountLoggedIn() && store.state.settings.user.vipType === 11) {
if (isAccountLoggedIn() && store.state.data.user.vipType === 11) {
result.playable = true;
} else {
result.playable = false;
@ -80,13 +80,13 @@ export function updateHttps(url) {
}
export function dailyTask() {
let lastDate = store.state.settings.lastRefreshCookieDate;
let lastDate = store.state.data.lastRefreshCookieDate;
if (
isAccountLoggedIn() &&
(lastDate === undefined || lastDate !== dayjs().date())
) {
console.log("execute dailyTask");
store.commit("updateSettings", {
store.commit("updateData", {
key: "lastRefreshCookieDate",
value: dayjs().date(),
});

@ -0,0 +1,28 @@
import pack from "../../package.json";
function updateTo_0_2_0() {
// 0.1 to 0.2.0
// 移动 settings 内的 user 数据到 data
let settings = JSON.parse(localStorage.getItem("settings"));
let data = {
likedSongPlaylistID: settings.user.likedSongPlaylistID,
lastRefreshCookieDate: settings.lastRefreshCookieDate,
};
delete settings.user.likedSongPlaylistID;
delete settings.lastRefreshCookieDate;
data.user = settings.user;
delete settings.user;
localStorage.setItem("settings", JSON.stringify(settings));
localStorage.setItem("data", JSON.stringify(data));
localStorage.setItem("appVersion", "0.2.0");
window.location.reload();
}
export default function () {
while (localStorage.getItem("appVersion") !== pack.version) {
let currentVersion = localStorage.getItem("appVersion");
if (currentVersion === "0.1") {
updateTo_0_2_0();
}
}
}

@ -41,6 +41,15 @@
>
{{ $t("play") }}
</ButtonTwoTone>
<ButtonTwoTone
v-if="accountLogin"
shape="round"
:iconClass="dynamicDetail.isSub ? 'heart-solid' : 'heart'"
:iconButton="true"
:horizontalPadding="0"
@click.native="likeAlbum"
>
</ButtonTwoTone>
</div>
</div>
</div>
@ -93,8 +102,9 @@ import { mapMutations, mapActions, mapState } from "vuex";
import { getArtistAlbum } from "@/api/artist";
import { getTrackDetail } from "@/api/track";
import { playAlbumByID } from "@/utils/play";
import { getAlbum } from "@/api/album";
import { getAlbum, albumDynamicDetail, likeAAlbum } from "@/api/album";
import NProgress from "nprogress";
import { isAccountLoggedIn } from "@/utils/auth";
import ExplicitSymbol from "@/components/ExplicitSymbol.vue";
import ButtonTwoTone from "@/components/ButtonTwoTone.vue";
@ -124,18 +134,22 @@ export default {
showFullDescription: false,
show: false,
moreAlbums: [],
dynamicDetail: {},
};
},
created() {
this.loadData(this.$route.params.id);
},
computed: {
...mapState(["player"]),
...mapState(["player", "data"]),
albumTime() {
let time = 0;
this.tracks.map((t) => (time = time + t.dt));
return time;
},
accountLogin() {
return isAccountLoggedIn();
},
filteredMoreAlbums() {
let moreAlbums = this.moreAlbums.filter((a) => a.id !== this.album.id);
let realAlbums = moreAlbums.filter((a) => a.type === "专辑");
@ -159,6 +173,15 @@ export default {
}
playAlbumByID(id, trackID);
},
likeAlbum() {
likeAAlbum({
id: this.album.id,
t: this.dynamicDetail.isSub ? 0 : 1,
}).then((data) => {
if (data.code === 200)
this.dynamicDetail.isSub = !this.dynamicDetail.isSub;
});
},
loadData(id) {
getAlbum(id).then((data) => {
this.album = data.album;
@ -179,6 +202,9 @@ export default {
}
);
});
albumDynamicDetail(id).then((data) => {
this.dynamicDetail = data;
});
},
},
beforeRouteUpdate(to, from, next) {
@ -235,6 +261,13 @@ export default {
opacity: 0.88;
}
}
.buttons {
margin-top: 32px;
display: flex;
button {
margin-right: 16px;
}
}
}
}

@ -16,6 +16,10 @@
<ButtonTwoTone @click.native="playPopularSongs()" :iconClass="`play`">
{{ $t("play") }}
</ButtonTwoTone>
<ButtonTwoTone @click.native="followArtist" color="grey">
<span v-if="artist.followed">Following</span>
<span v-else>Follow</span>
</ButtonTwoTone>
</div>
</div>
</div>
@ -94,7 +98,12 @@
<script>
import { mapMutations, mapActions, mapState } from "vuex";
import { getArtist, getArtistAlbum, artistMv } from "@/api/artist";
import {
getArtist,
getArtistAlbum,
artistMv,
followAArtist,
} from "@/api/artist";
import { playAList } from "@/utils/play";
import NProgress from "nprogress";
@ -168,6 +177,14 @@ export default {
let trackIDs = this.popularTracks.map((t) => t.id);
playAList(trackIDs, this.artist.id, "artist", trackID);
},
followArtist() {
followAArtist({
id: this.artist.id,
t: this.artist.followed ? 0 : 1,
}).then((data) => {
if (data.code === 200) this.artist.followed = !this.artist.followed;
});
},
},
created() {
this.loadData(this.$route.params.id);

@ -40,16 +40,65 @@
</div>
</div>
<div class="playlists" v-if="playlists.length > 1">
<div class="title">{{ $t("playlist.playlist") }}</div>
<div>
<div class="section-two" id="liked">
<div class="tabs">
<div
class="tab"
:class="{ active: currentTab === 'playlists' }"
@click="updateCurrentTab('playlists')"
>
Playlists
</div>
<div
class="tab"
:class="{ active: currentTab === 'albums' }"
@click="updateCurrentTab('albums')"
>
Albums
</div>
<div
class="tab"
:class="{ active: currentTab === 'artists' }"
@click="updateCurrentTab('artists')"
>
Artists
</div>
<div
class="tab"
:class="{ active: currentTab === 'mvs' }"
@click="updateCurrentTab('mvs')"
>
MVs
</div>
</div>
<div v-show="currentTab === 'playlists'">
<div v-if="playlists.length > 1">
<CoverRow
:items="playlists.slice(1)"
type="playlist"
subText="creator"
:showPlayButton="true"
/>
</div>
</div>
<div v-show="currentTab === 'albums'">
<CoverRow
:items="playlists.slice(1)"
type="playlist"
subText="creator"
:items="albums"
type="album"
subText="artist"
:showPlayButton="true"
/>
</div>
<div v-show="currentTab === 'artists'">
<CoverRow :items="artists" type="artist" :showPlayButton="true" />
</div>
<div v-show="currentTab === 'mvs'">
<MvRow :mvs="mvs" />
</div>
</div>
</div>
</template>
@ -57,7 +106,13 @@
<script>
import { mapState } from "vuex";
import { getTrackDetail, getLyric } from "@/api/track";
import { userDetail, userPlaylist } from "@/api/user";
import {
userDetail,
userPlaylist,
likedAlbums,
likedArtists,
likedMVs,
} from "@/api/user";
import { randomNum, dailyTask } from "@/utils/common";
import { getPlaylistDetail } from "@/api/playlist";
import { playPlaylistByID } from "@/utils/play";
@ -65,11 +120,12 @@ import NProgress from "nprogress";
import TrackList from "@/components/TrackList.vue";
import CoverRow from "@/components/CoverRow.vue";
import MvRow from "@/components/MvRow.vue";
import SvgIcon from "@/components/SvgIcon.vue";
export default {
name: "Library",
components: { SvgIcon, CoverRow, TrackList },
components: { SvgIcon, CoverRow, TrackList, MvRow },
data() {
return {
show: false,
@ -88,11 +144,15 @@ export default {
likedSongs: [],
likedSongIDs: [],
lyric: undefined,
currentTab: "playlists",
albums: [],
artists: [],
mvs: [],
};
},
created() {
NProgress.start();
userDetail(this.settings.user.userId).then((data) => {
userDetail(this.data.user.userId).then((data) => {
this.user = data;
});
},
@ -101,7 +161,7 @@ export default {
dailyTask();
},
computed: {
...mapState(["settings"]),
...mapState(["data"]),
likedSongsInState() {
return this.$store.state.liked.songs;
},
@ -129,18 +189,38 @@ export default {
playLikedSongs() {
playPlaylistByID(this.playlists[0].id, "first", true);
},
updateCurrentTab(tab) {
this.currentTab = tab;
document
.getElementById("liked")
.scrollIntoView({ block: "start", behavior: "smooth" });
if (tab === "albums") {
if (this.albums.length === 0) this.loadLikedAlbums();
} else if (tab === "artists") {
if (this.artists.length === 0) this.loadLikedArtists();
} else if (tab === "mvs") {
if (this.mvs.length === 0) this.loadLikedMVs();
}
},
goToLikedSongsList() {
this.$router.push({ path: "/library/liked-songs" });
},
loadData() {
if (this.hasMorePlaylists) {
if (this.hasMorePlaylists && this.currentTab === "playlists") {
this.getUserPlaylists();
}
if (this.currentTab === "albums") {
this.loadLikedAlbums();
} else if (this.currentTab === "artists") {
this.loadLikedArtists();
} else if (this.currentTab === "mvs") {
this.loadLikedMVs();
}
this.getLikedSongs();
},
getUserPlaylists(replace = false) {
userPlaylist({
uid: this.settings.user.userId,
uid: this.data.user.userId,
offset: this.playlists.length === 0 ? 0 : this.playlists.length - 1,
timestamp: new Date().getTime(),
}).then((data) => {
@ -153,19 +233,17 @@ export default {
});
},
getLikedSongs(getLyric = true) {
getPlaylistDetail(this.settings.user.likedSongPlaylistID, true).then(
(data) => {
this.likedSongsPlaylist = data.playlist;
let TrackIDs = data.playlist.trackIds.slice(0, 20).map((t) => t.id);
this.likedSongIDs = TrackIDs;
getTrackDetail(this.likedSongIDs.join(",")).then((data) => {
this.likedSongs = data.songs;
NProgress.done();
this.show = true;
});
if (getLyric) this.getRandomLyric();
}
);
getPlaylistDetail(this.data.likedSongPlaylistID, true).then((data) => {
this.likedSongsPlaylist = data.playlist;
let TrackIDs = data.playlist.trackIds.slice(0, 20).map((t) => t.id);
this.likedSongIDs = TrackIDs;
getTrackDetail(this.likedSongIDs.join(",")).then((data) => {
this.likedSongs = data.songs;
NProgress.done();
this.show = true;
});
if (getLyric) this.getRandomLyric();
});
},
getRandomLyric() {
getLyric(
@ -174,6 +252,21 @@ export default {
if (data.lrc !== undefined) this.lyric = data.lrc.lyric;
});
},
loadLikedAlbums() {
likedAlbums().then((data) => {
this.albums = data.data;
});
},
loadLikedArtists() {
likedArtists().then((data) => {
this.artists = data.data;
});
},
loadLikedMVs() {
likedMVs().then((data) => {
this.mvs = data.data;
});
},
},
watch: {
likedSongsInState() {
@ -280,14 +373,37 @@ h1 {
}
}
.playlists {
.section-two {
// margin-top: 42px;
// padding-top: 14px;
// border-top: 1px solid rgba(128, 128, 128, 0.18);
margin-top: 54px;
.title {
color: var(--color-text);
opacity: 0.88;
margin-bottom: 8px;
font-size: 24px;
min-height: calc(100vh - 182px);
}
.tabs {
display: flex;
flex-wrap: wrap;
font-size: 18px;
color: var(--color-text);
margin-bottom: 6px;
.tab {
font-weight: 600;
padding: 8px 14px;
margin: 10px 14px 6px 0;
border-radius: 8px;
cursor: pointer;
user-select: none;
transition: 0.2s;
opacity: 0.68;
&:hover {
opacity: 0.88;
background-color: var(--color-secondary-bg);
}
}
.tab.active {
opacity: 0.88;
background-color: var(--color-secondary-bg);
}
}
</style>

@ -89,7 +89,6 @@ import { loginWithPhone, loginWithEmail } from "@/api/auth";
import md5 from "crypto-js/md5";
import { mapMutations } from "vuex";
import { userPlaylist } from "@/api/user";
import Cookies from "js-cookie";
export default {
name: "Login",
@ -112,15 +111,14 @@ export default {
NProgress.done();
},
methods: {
...mapMutations(["updateUser", "updateUserInfo", "updateAccountLogin"]),
...mapMutations(["updateData"]),
afterLogin() {
this.updateAccountLogin(true);
Cookies.set("loginMode", "account", { expires: 3650 });
this.updateData({ key: "loginMode", value: "account" });
userPlaylist({
uid: this.$store.state.settings.user.userId,
uid: this.$store.state.data.user.userId,
limit: 1,
}).then((data) => {
this.updateUserInfo({
this.updateData({
key: "likedSongPlaylistID",
value: data.playlist[0].id,
});
@ -163,7 +161,7 @@ export default {
})
.then((data) => {
if (data.code !== 502) {
this.updateUser(data.profile);
this.updateData({ key: "user", value: data.profile });
this.afterLogin();
}
})
@ -180,7 +178,7 @@ export default {
})
.then((data) => {
if (data.code !== 502) {
this.updateUser(data.profile);
this.updateData({ key: "user", value: data.profile });
this.afterLogin();
}
})

@ -52,7 +52,6 @@
import { mapMutations } from "vuex";
import NProgress from "nprogress";
import { search } from "@/api/others";
import Cookies from "js-cookie";
import { userPlaylist } from "@/api/user";
import { throttle } from "@/utils/common";
@ -74,7 +73,7 @@ export default {
NProgress.done();
},
methods: {
...mapMutations(["updateUser", "updateUserInfo", "updateUsernameLogin"]),
...mapMutations(["updateData"]),
search() {
if (!this.keyword) return;
search({ keywords: this.keyword, limit: 9, type: 1002 }).then((data) => {
@ -83,14 +82,13 @@ export default {
});
},
confirm() {
this.updateUser(this.activeUser);
this.updateUsernameLogin(true);
Cookies.set("loginMode", "username", { expires: 3650 });
this.updateData({ key: "user", value: this.activeUser });
this.updateData({ key: "loginMode", value: "username" });
userPlaylist({
uid: this.activeUser.userId,
limit: 1,
}).then((data) => {
this.updateUserInfo({
this.updateData({
key: "likedSongPlaylistID",
value: data.playlist[0].id,
});

@ -45,9 +45,7 @@
{{ $t("play") }}
</ButtonTwoTone>
<ButtonTwoTone
v-if="
accountLogin && playlist.creator.userId !== settings.user.userId
"
v-if="accountLogin && playlist.creator.userId !== data.user.userId"
shape="round"
:iconClass="playlist.subscribed ? 'heart-solid' : 'heart'"
:iconButton="true"
@ -61,8 +59,8 @@
<div class="user-info" v-else>
<h1>
<img class="avatar" :src="settings.user.avatarUrl | resizeImage" />{{
settings.user.nickname
<img class="avatar" :src="data.user.avatarUrl | resizeImage" />{{
data.user.nickname
}}{{ $t("library.sLikedSongs") }}
</h1>
</div>
@ -92,6 +90,7 @@ import NProgress from "nprogress";
import { getPlaylistDetail, subscribePlaylist } from "@/api/playlist";
import { playAList } from "@/utils/play";
import { getTrackDetail } from "@/api/track";
import { isAccountLoggedIn } from "@/utils/auth";
import ButtonTwoTone from "@/components/ButtonTwoTone.vue";
import TrackList from "@/components/TrackList.vue";
@ -122,7 +121,7 @@ export default {
},
created() {
if (this.$route.name === "likedSongs") {
this.loadData(this.settings.user.likedSongPlaylistID);
this.loadData(this.data.user.likedSongPlaylistID);
} else {
this.loadData(this.$route.params.id);
}
@ -131,10 +130,13 @@ export default {
window.removeEventListener("scroll", this.handleScroll, true);
},
computed: {
...mapState(["player", "settings", "accountLogin"]),
...mapState(["player", "data"]),
isLikeSongsPage() {
return this.$route.name === "likedSongs";
},
accountLogin() {
return isAccountLoggedIn();
},
},
methods: {
...mapMutations(["appendTrackToPlayerList"]),

File diff suppressed because one or more lines are too long
Loading…
Cancel
Save