feat: prettier task supported (#40)

* feat: add config to resolve path alias.

* feat: use vue-i18n for language switch

* feat: add .editorconfig for ide

* fix: add no-referrer to avoid CROB

* fix: setCookie and fix typo

* feat: integrate vue-i18n

* feat: player component i18n support

* fix: duplicate key warning in explore page

* fix: like songs number changed in library page

* fire: remove todo

* fix: same text search on enter will cause error

* fix: scrobble error params type

* feat: prettier task supported

* fix: prettier ignore config update

* fix: conflict
master
Hawtim Zhang 4 years ago committed by GitHub
parent 56fe497db9
commit c042faa001
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,4 @@
build
coverage
dist

@ -0,0 +1,13 @@
{
"trailingComma": "es5",
"tabWidth": 2,
"useTabs": false,
"semi": true,
"singleQuote": false,
"jsxSingleQuote": true,
"jsxBracketSameLine": false,
"arrowParens": "always",
"endOfLine": "lf",
"bracketSpacing": true,
"htmlWhitespaceSensitivity": "strict"
}

@ -1,5 +1,3 @@
module.exports = { module.exports = {
presets: [ presets: ["@vue/cli-plugin-babel/preset"],
'@vue/cli-plugin-babel/preset' };
]
}

@ -5,7 +5,13 @@
"scripts": { "scripts": {
"serve": "vue-cli-service serve", "serve": "vue-cli-service serve",
"build": "vue-cli-service build", "build": "vue-cli-service build",
"lint": "vue-cli-service lint" "lint": "vue-cli-service lint",
"prettier": "npx prettier --write ./src"
},
"husky": {
"hooks": {
"pre-commit": "npm run prettier"
}
}, },
"dependencies": { "dependencies": {
"@sentry/browser": "^5.27.0", "@sentry/browser": "^5.27.0",
@ -19,6 +25,7 @@
"js-cookie": "^2.2.1", "js-cookie": "^2.2.1",
"nprogress": "^0.2.0", "nprogress": "^0.2.0",
"plyr": "^3.6.2", "plyr": "^3.6.2",
"prettier": "2.1.2",
"register-service-worker": "^1.7.1", "register-service-worker": "^1.7.1",
"svg-sprite-loader": "^5.0.0", "svg-sprite-loader": "^5.0.0",
"vue": "^2.6.11", "vue": "^2.6.11",
@ -38,6 +45,7 @@
"babel-eslint": "^10.1.0", "babel-eslint": "^10.1.0",
"eslint": "^6.7.2", "eslint": "^6.7.2",
"eslint-plugin-vue": "^6.2.2", "eslint-plugin-vue": "^6.2.2",
"husky": "^4.3.0",
"sass": "^1.26.11", "sass": "^1.26.11",
"sass-loader": "^10.0.2", "sass-loader": "^10.0.2",
"vue-template-compiler": "^2.6.11" "vue-template-compiler": "^2.6.11"

@ -1,22 +1,23 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="referrer" content="no-referrer" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<link rel="icon" href="<%= BASE_URL %>favicon.ico" />
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<head> <body>
<meta charset="utf-8"> <noscript>
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <strong
<meta name="referrer" content="no-referrer"> >We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work
<meta name="viewport" content="width=device-width,initial-scale=1.0"> properly without JavaScript enabled. Please enable it to
<link rel="icon" href="<%= BASE_URL %>favicon.ico"> continue.</strong
<title><%= htmlWebpackPlugin.options.title %></title> >
</head> </noscript>
<div id="app"></div>
<body> <!-- built files will be auto injected -->
<noscript> </body>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled.
Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html> </html>

@ -31,7 +31,7 @@ export default {
components: { components: {
Navbar, Navbar,
Player, Player,
GlobalEvents GlobalEvents,
}, },
methods: { methods: {
play(e) { play(e) {
@ -42,8 +42,8 @@ export default {
if (event.target.tagName === "INPUT") return false; if (event.target.tagName === "INPUT") return false;
if (this.$route.name === "mv") return false; if (this.$route.name === "mv") return false;
return true; return true;
} },
} },
}; };
</script> </script>

@ -6,9 +6,9 @@ export function getArtist(id) {
url: "/artists", url: "/artists",
method: "get", method: "get",
params: { params: {
id id,
} },
}).then(data => { }).then((data) => {
data.hotSongs = mapTrackPlayableStatus(data.hotSongs); data.hotSongs = mapTrackPlayableStatus(data.hotSongs);
return data; return data;
}); });
@ -21,7 +21,7 @@ export function getArtistAlbum(params) {
return request({ return request({
url: "/artist/album", url: "/artist/album",
method: "get", method: "get",
params params,
}); });
} }
@ -35,8 +35,8 @@ export function toplistOfArtists(type = null) {
url: "/toplist/artist", url: "/toplist/artist",
method: "get", method: "get",
params: { params: {
type type,
} },
}); });
} }
@ -45,7 +45,7 @@ export function artistMv(id) {
url: "/artist/mv", url: "/artist/mv",
method: "get", method: "get",
params: { params: {
id id,
} },
}); });
} }

@ -6,7 +6,7 @@ export function recommendPlaylist(params) {
return request({ return request({
url: "/personalized", url: "/personalized",
method: "get", method: "get",
params params,
}); });
} }
export function dailyRecommendPlaylist(params) { export function dailyRecommendPlaylist(params) {
@ -14,7 +14,7 @@ export function dailyRecommendPlaylist(params) {
return request({ return request({
url: "/recommend/resource", url: "/recommend/resource",
method: "get", method: "get",
params params,
}); });
} }
@ -24,8 +24,8 @@ export function getPlaylistDetail(id, noCache = false) {
return request({ return request({
url: "/playlist/detail", url: "/playlist/detail",
method: "get", method: "get",
params params,
}).then(data => { }).then((data) => {
data.playlist.tracks = mapTrackPlayableStatus(data.playlist.tracks); data.playlist.tracks = mapTrackPlayableStatus(data.playlist.tracks);
return data; return data;
}); });
@ -38,7 +38,7 @@ export function highQualityPlaylist(params) {
return request({ return request({
url: "/top/playlist/highquality", url: "/top/playlist/highquality",
method: "get", method: "get",
params params,
}); });
} }
@ -50,21 +50,21 @@ export function topPlaylist(params) {
return request({ return request({
url: "/top/playlist", url: "/top/playlist",
method: "get", method: "get",
params params,
}); });
} }
export function playlistCatlist() { export function playlistCatlist() {
return request({ return request({
url: "/playlist/catlist", url: "/playlist/catlist",
method: "get" method: "get",
}); });
} }
export function toplists() { export function toplists() {
return request({ return request({
url: "/toplist", url: "/toplist",
method: "get" method: "get",
}); });
} }
@ -74,6 +74,6 @@ export function subscribePlaylist(params) {
return request({ return request({
url: "/playlist/subscribe", url: "/playlist/subscribe",
method: "get", method: "get",
params params,
}); });
} }

@ -1,41 +1,40 @@
/* Make clicks pass-through */ /* Make clicks pass-through */
#nprogress { #nprogress {
pointer-events: none; pointer-events: none;
} }
#nprogress .bar { #nprogress .bar {
background: #335eea; background: #335eea;
position: fixed; position: fixed;
z-index: 1031; z-index: 1031;
top: 0; top: 0;
left: 0; left: 0;
width: 100%; width: 100%;
height: 2px; height: 2px;
} }
/* Fancy blur effect */ /* Fancy blur effect */
#nprogress .peg { #nprogress .peg {
display: block; display: block;
position: absolute; position: absolute;
right: 0px; right: 0px;
width: 100px; width: 100px;
height: 100%; height: 100%;
box-shadow: 0 0 10px #335eea, box-shadow: 0 0 10px #335eea, 0 0 5px #335eea;
0 0 5px #335eea; opacity: 1;
opacity: 1.0;
-webkit-transform: rotate(3deg) translate(0px, -4px); -webkit-transform: rotate(3deg) translate(0px, -4px);
-ms-transform: rotate(3deg) translate(0px, -4px); -ms-transform: rotate(3deg) translate(0px, -4px);
transform: rotate(3deg) translate(0px, -4px); transform: rotate(3deg) translate(0px, -4px);
} }
.nprogress-custom-parent { .nprogress-custom-parent {
overflow: hidden; overflow: hidden;
position: relative; position: relative;
} }
.nprogress-custom-parent #nprogress .bar { .nprogress-custom-parent #nprogress .bar {
position: absolute; position: absolute;
} }

File diff suppressed because it is too large Load Diff

@ -1,65 +1,63 @@
/* rail style */ /* rail style */
.vue-slider-rail { .vue-slider-rail {
background-color: #eee; background-color: #eee;
border-radius: 15px; border-radius: 15px;
} }
/* process style */ /* process style */
.vue-slider-process { .vue-slider-process {
background-color: #335eea; background-color: #335eea;
border-radius: 15px; border-radius: 15px;
} }
/* dot style */ /* dot style */
.vue-slider-dot-handle { .vue-slider-dot-handle {
cursor: pointer; cursor: pointer;
width: 100%; width: 100%;
height: 100%; height: 100%;
border-radius: 50%; border-radius: 50%;
background-color: #fff; background-color: #fff;
box-sizing: border-box; box-sizing: border-box;
box-shadow: 0.5px 0.5px 2px 1px rgba(0, 0, 0, 0.12); box-shadow: 0.5px 0.5px 2px 1px rgba(0, 0, 0, 0.12);
visibility: hidden; visibility: hidden;
} }
/* tooltip style */ /* tooltip style */
.vue-slider-dot-tooltip-wrapper { .vue-slider-dot-tooltip-wrapper {
opacity: 0; opacity: 0;
transition: all 1s; transition: all 1s;
} }
.vue-slider-dot-tooltip-wrapper-show { .vue-slider-dot-tooltip-wrapper-show {
opacity: 1; opacity: 1;
} }
.vue-slider-dot-tooltip-inner { .vue-slider-dot-tooltip-inner {
font-size: 14px; font-size: 14px;
white-space: nowrap; white-space: nowrap;
padding: 2px 6px; padding: 2px 6px;
min-width: 20px; min-width: 20px;
text-align: center; text-align: center;
color: #000; color: #000;
border-radius: 5px; border-radius: 5px;
border-color: #fff; border-color: #fff;
background-color: #fff; background-color: #fff;
box-sizing: content-box; box-sizing: content-box;
box-shadow: 0.5px 0.5px 2px 1px rgba(0, 0, 0, 0.08); box-shadow: 0.5px 0.5px 2px 1px rgba(0, 0, 0, 0.08);
} }
/* hover */ /* hover */
.vue-slider:hover .vue-slider-dot-handle, .vue-slider:hover .vue-slider-dot-handle,
.vue-slider:active .vue-slider-dot-handle { .vue-slider:active .vue-slider-dot-handle {
visibility: visible; visibility: visible;
} }
/* volume style */ /* volume style */
.volume-control .vue-slider-process { .volume-control .vue-slider-process {
background-color: rgba(0, 0, 0, 0.8); background-color: rgba(0, 0, 0, 0.8);
border-radius: 15px; border-radius: 15px;
} }
.volume-control:hover .vue-slider-process { .volume-control:hover .vue-slider-process {
background-color: #335eea; background-color: #335eea;
} }

@ -42,7 +42,7 @@ export default {
openMenu(e) { openMenu(e) {
this.showMenu = true; this.showMenu = true;
this.$nextTick( this.$nextTick(
function() { function () {
this.$refs.menu.focus(); this.$refs.menu.focus();
this.setMenu(e.y, e.x); this.setMenu(e.y, e.x);
}.bind(this) }.bind(this)

@ -60,27 +60,27 @@ export default {
name: "CoverRow", name: "CoverRow",
components: { components: {
Cover, Cover,
ExplicitSymbol ExplicitSymbol,
}, },
props: { props: {
items: Array, items: Array,
type: String, type: String,
subText: { subText: {
type: String, type: String,
default: "none" default: "none",
}, },
imageSize: { imageSize: {
type: Number, type: Number,
default: 512 default: 512,
}, },
showPlayButton: { showPlayButton: {
type: Boolean, type: Boolean,
default: false default: false,
}, },
showPlayCount: { showPlayCount: {
type: Boolean, type: Boolean,
default: false default: false,
} },
}, },
methods: { methods: {
getUrl(item) { getUrl(item) {
@ -102,8 +102,8 @@ export default {
item.publishTime item.publishTime
).getFullYear()}`; ).getFullYear()}`;
if (this.subText === "appleMusic") return "by Apple Music"; if (this.subText === "appleMusic") return "by Apple Music";
} },
} },
}; };
</script> </script>

@ -54,13 +54,13 @@ import ButtonIcon from "@/components/ButtonIcon.vue";
export default { export default {
name: "Navbar", name: "Navbar",
components: { components: {
ButtonIcon ButtonIcon,
}, },
data() { data() {
return { return {
inputFocus: false, inputFocus: false,
keywords: "", keywords: "",
langs: ["zh-CN", "en"] langs: ["zh-CN", "en"],
}; };
}, },
methods: { methods: {
@ -77,7 +77,7 @@ export default {
return; return;
this.$router.push({ this.$router.push({
name: "search", name: "search",
query: { keywords: this.keywords } query: { keywords: this.keywords },
}); });
}, },
changeLang() { changeLang() {
@ -89,8 +89,8 @@ export default {
} }
this.$i18n.locale = lang; this.$i18n.locale = lang;
this.$store.commit("changeLang", lang); this.$store.commit("changeLang", lang);
} },
} },
}; };
</script> </script>

@ -131,13 +131,13 @@ export default {
name: "Player", name: "Player",
components: { components: {
ButtonIcon, ButtonIcon,
VueSlider VueSlider,
}, },
data() { data() {
return { return {
interval: null, interval: null,
progress: 0, progress: 0,
oldVolume: 0.5 oldVolume: 0.5,
}; };
}, },
created() { created() {
@ -145,7 +145,7 @@ export default {
this.progress = ~~this.howler.seek(); this.progress = ~~this.howler.seek();
}, 1000); }, 1000);
if (this.isLoggedIn) { if (this.isLoggedIn) {
userLikedSongsIDs(this.settings.user.userId).then(data => { userLikedSongsIDs(this.settings.user.userId).then((data) => {
this.updateLikedSongs(data.ids); this.updateLikedSongs(data.ids);
}); });
} }
@ -162,7 +162,7 @@ export default {
set(value) { set(value) {
this.updatePlayerState({ key: "volume", value }); this.updatePlayerState({ key: "volume", value });
Howler.volume(value); Howler.volume(value);
} },
}, },
playing() { playing() {
if (this.howler.state() === "loading") { if (this.howler.state() === "loading") {
@ -176,7 +176,7 @@ export default {
}, },
isLoggedIn() { isLoggedIn() {
return isLoggedIn(); return isLoggedIn();
} },
}, },
methods: { methods: {
...mapMutations([ ...mapMutations([
@ -184,13 +184,13 @@ export default {
"turnOffShuffleMode", "turnOffShuffleMode",
"updatePlayerState", "updatePlayerState",
"updateRepeatStatus", "updateRepeatStatus",
"updateLikedSongs" "updateLikedSongs",
]), ]),
...mapActions([ ...mapActions([
"nextTrack", "nextTrack",
"previousTrack", "previousTrack",
"playTrackOnListByID", "playTrackOnListByID",
"addNextTrackEvent" "addNextTrackEvent",
]), ]),
play() { play() {
if (this.playing) { if (this.playing) {
@ -259,7 +259,7 @@ export default {
if (this.liked.songs.includes(id)) like = false; if (this.liked.songs.includes(id)) like = false;
likeATrack({ id, like }).then(() => { likeATrack({ id, like }).then(() => {
if (like === false) { if (like === false) {
this.updateLikedSongs(this.liked.songs.filter(d => d !== id)); this.updateLikedSongs(this.liked.songs.filter((d) => d !== id));
} else { } else {
let newLikeSongs = this.liked.songs; let newLikeSongs = this.liked.songs;
newLikeSongs.push(id); newLikeSongs.push(id);
@ -272,7 +272,7 @@ export default {
this.$router.push({ path: "/library/liked-songs" }); this.$router.push({ path: "/library/liked-songs" });
else else
this.$router.push({ this.$router.push({
path: "/" + this.player.listInfo.type + "/" + this.player.listInfo.id path: "/" + this.player.listInfo.type + "/" + this.player.listInfo.id,
}); });
}, },
goToAlbum() { goToAlbum() {
@ -280,8 +280,8 @@ export default {
}, },
goToArtist(id) { goToArtist(id) {
this.$router.push({ path: "/artist/" + id }); this.$router.push({ path: "/artist/" + id });
} },
} },
}; };
</script> </script>

@ -27,7 +27,7 @@ import {
playPlaylistByID, playPlaylistByID,
playAlbumByID, playAlbumByID,
playAList, playAList,
appendTrackToPlayerList appendTrackToPlayerList,
} from "@/utils/play"; } from "@/utils/play";
import TrackListItem from "@/components/TrackListItem.vue"; import TrackListItem from "@/components/TrackListItem.vue";
@ -37,7 +37,7 @@ export default {
name: "TrackList", name: "TrackList",
components: { components: {
TrackListItem, TrackListItem,
ContextMenu ContextMenu,
}, },
props: { props: {
tracks: Array, tracks: Array,
@ -45,17 +45,17 @@ export default {
id: Number, id: Number,
itemWidth: { itemWidth: {
type: Number, type: Number,
default: -1 default: -1,
}, },
dbclickTrackFunc: { dbclickTrackFunc: {
type: String, type: String,
default: "default" default: "default",
} },
}, },
data() { data() {
return { return {
rightClickedTrack: null, rightClickedTrack: null,
listStyles: {} listStyles: {},
}; };
}, },
created() { created() {
@ -66,7 +66,7 @@ export default {
...mapState(["liked"]), ...mapState(["liked"]),
isRightClickedTrackLiked() { isRightClickedTrackLiked() {
return this.liked.songs.includes(this.rightClickedTrack?.id); return this.liked.songs.includes(this.rightClickedTrack?.id);
} },
}, },
methods: { methods: {
...mapMutations(["updateLikedSongs"]), ...mapMutations(["updateLikedSongs"]),
@ -95,7 +95,7 @@ export default {
} else if (this.type === "album") { } else if (this.type === "album") {
playAlbumByID(this.id, trackID); playAlbumByID(this.id, trackID);
} else if (this.type === "tracklist") { } else if (this.type === "tracklist") {
let trackIDs = this.tracks.map(t => t.id); let trackIDs = this.tracks.map((t) => t.id);
playAList(trackIDs, this.tracks[0].ar[0].id, "artist", trackID); playAList(trackIDs, this.tracks[0].ar[0].id, "artist", trackID);
} }
}, },
@ -112,17 +112,17 @@ export default {
let like = true; let like = true;
let likedSongs = this.liked.songs; let likedSongs = this.liked.songs;
if (likedSongs.includes(id)) like = false; if (likedSongs.includes(id)) like = false;
likeATrack({ id, like }).then(data => { likeATrack({ id, like }).then((data) => {
if (data.code !== 200) return; if (data.code !== 200) return;
if (like === false) { if (like === false) {
this.updateLikedSongs(likedSongs.filter(d => d !== id)); this.updateLikedSongs(likedSongs.filter((d) => d !== id));
} else { } else {
likedSongs.push(id); likedSongs.push(id);
this.updateLikedSongs(likedSongs); this.updateLikedSongs(likedSongs);
} }
}); });
} },
} },
}; };
</script> </script>

@ -21,7 +21,10 @@
track.no track.no
}}</span> }}</span>
<button v-show="isPlaying"> <button v-show="isPlaying">
<svg-icon icon-class="volume" style="height:16px;width:16px"></svg-icon> <svg-icon
icon-class="volume"
style="height: 16px; width: 16px"
></svg-icon>
</button> </button>
</div> </div>
<div class="title-and-artist"> <div class="title-and-artist">
@ -59,7 +62,7 @@
icon-class="heart" icon-class="heart"
:style="{ :style="{
visibility: visibility:
focus && !isLiked && track.playable ? 'visible' : 'hidden' focus && !isLiked && track.playable ? 'visible' : 'hidden',
}" }"
></svg-icon> ></svg-icon>
<svg-icon icon-class="heart-solid" v-show="isLiked"></svg-icon> <svg-icon icon-class="heart-solid" v-show="isLiked"></svg-icon>
@ -81,7 +84,7 @@ export default {
name: "TrackListItem", name: "TrackListItem",
components: { ArtistsInLine, ExplicitSymbol }, components: { ArtistsInLine, ExplicitSymbol },
props: { props: {
track: Object track: Object,
}, },
data() { data() {
return { focus: false, trackStyle: {} }; return { focus: false, trackStyle: {} };
@ -123,7 +126,7 @@ export default {
}, },
isLoggedIn() { isLoggedIn() {
return isLoggedIn(); return isLoggedIn();
} },
}, },
methods: { methods: {
goToAlbum() { goToAlbum() {
@ -134,12 +137,12 @@ export default {
}, },
likeThisSong() { likeThisSong() {
this.$parent.likeASong(this.track.id); this.$parent.likeASong(this.track.id);
} },
}, },
created() { created() {
if (this.$parent.itemWidth !== -1) if (this.$parent.itemWidth !== -1)
this.trackStyle = { width: this.$parent.itemWidth + "px" }; this.trackStyle = { width: this.$parent.itemWidth + "px" };
} },
}; };
</script> </script>

@ -11,8 +11,8 @@ const i18n = new VueI18n({
locale: store.state.settings.lang, locale: store.state.settings.lang,
messages: { messages: {
en, en,
"zh-CN": zhCN "zh-CN": zhCN,
} },
}); });
export default i18n; export default i18n;

@ -4,26 +4,26 @@ export default {
home: "Home", home: "Home",
explore: "Explore", explore: "Explore",
library: "Library", library: "Library",
search: "Search" search: "Search",
}, },
footer: { footer: {
settings: "Settings" settings: "Settings",
}, },
home: { home: {
recommendPlaylist: "Recommended Playlists", recommendPlaylist: "Recommended Playlists",
recommendArtist: "Recommended Artists", recommendArtist: "Recommended Artists",
newAlbum: "Latest Albums", newAlbum: "Latest Albums",
seeMore: "SEE MORE", seeMore: "SEE MORE",
charts: "Charts" charts: "Charts",
}, },
library: { library: {
sLibrary: "'s Library", sLibrary: "'s Library",
likedSongs: "Liked Songs", likedSongs: "Liked Songs",
sLikedSongs: "'s LikedSongs" sLikedSongs: "'s LikedSongs",
}, },
explore: { explore: {
explore: "Explore", explore: "Explore",
loadMore: "Load More" loadMore: "Load More",
}, },
artist: { artist: {
latestRelease: "Latest Releases", latestRelease: "Latest Releases",
@ -34,14 +34,14 @@ export default {
albums: "Albums", albums: "Albums",
withAlbums: "Albums", withAlbums: "Albums",
artist: "Artist", artist: "Artist",
videos: "Music Videos" videos: "Music Videos",
}, },
album: { album: {
released: "Released" released: "Released",
}, },
playlist: { playlist: {
playlist: "Playlists", playlist: "Playlists",
updatedAt: "Updated at" updatedAt: "Updated at",
}, },
login: { login: {
accessToAll: "Access to all data", accessToAll: "Access to all data",
@ -62,14 +62,14 @@ export default {
loginWithPhone: "Login with Phone", loginWithPhone: "Login with Phone",
notice: `YesPlayMusic promises not to save any of your account information to the cloud.<br /> notice: `YesPlayMusic promises not to save any of your account information to the cloud.<br />
Your password will be MD5 encrypted locally and then transmitted to NetEase Cloud API.<br /> Your password will be MD5 encrypted locally and then transmitted to NetEase Cloud API.<br />
YesPlayMusic is not the official website of NetEase Cloud Music, please consider carefully before entering account information. You can also go to <a href="https://github.com/qier222/YesPlayMusic">YesPlayMusic's GitHub repository</a> to build and use the self-hosted NetEase Cloud Music API.` YesPlayMusic is not the official website of NetEase Cloud Music, please consider carefully before entering account information. You can also go to <a href="https://github.com/qier222/YesPlayMusic">YesPlayMusic's GitHub repository</a> to build and use the self-hosted NetEase Cloud Music API.`,
}, },
mv: { mv: {
moreVideo: "More Videos" moreVideo: "More Videos",
}, },
next: { next: {
nowPlaying: "Now Playing", nowPlaying: "Now Playing",
nextUp: "Next Up" nextUp: "Next Up",
}, },
player: { player: {
like: "Like", like: "Like",
@ -80,10 +80,10 @@ export default {
play: "Play", play: "Play",
pause: "Pause", pause: "Pause",
mute: "Mute", mute: "Mute",
nextUp: "Next Up" nextUp: "Next Up",
}, },
modal: { modal: {
close: "Close" close: "Close",
}, },
search: { search: {
artist: "Artists", artist: "Artists",
@ -92,9 +92,9 @@ export default {
mv: "MVs", mv: "MVs",
playlist: "Playlists", playlist: "Playlists",
noResult: "No Results", noResult: "No Results",
searchFor: "Search for" searchFor: "Search for",
}, },
common: { common: {
songs: "Songs", songs: "Songs",
} },
}; };

@ -4,26 +4,26 @@ export default {
home: "首页", home: "首页",
explore: "发现", explore: "发现",
library: "资料库", library: "资料库",
search: "搜索" search: "搜索",
}, },
footer: { footer: {
settings: "设置" settings: "设置",
}, },
home: { home: {
recommendPlaylist: "推荐歌单", recommendPlaylist: "推荐歌单",
recommendArtist: "推荐歌手", recommendArtist: "推荐歌手",
newAlbum: "新专速递", newAlbum: "新专速递",
seeMore: "更多", seeMore: "更多",
charts: "排行榜" charts: "排行榜",
}, },
library: { library: {
sLibrary: "的资料库", sLibrary: "的资料库",
likedSongs: "我喜欢的歌", likedSongs: "我喜欢的歌",
sLikedSongs: "喜欢的歌" sLikedSongs: "喜欢的歌",
}, },
explore: { explore: {
explore: "发现", explore: "发现",
loadMore: "加载更多" loadMore: "加载更多",
}, },
artist: { artist: {
latestRelease: "最新发布", latestRelease: "最新发布",
@ -34,14 +34,14 @@ export default {
albums: "专辑", albums: "专辑",
withAlbums: "张专辑", withAlbums: "张专辑",
artist: "歌手", artist: "歌手",
videos: "个视频" videos: "个视频",
}, },
album: { album: {
released: "发行于" released: "发行于",
}, },
playlist: { playlist: {
playlist: "歌单", playlist: "歌单",
updatedAt: "最后更新于" updatedAt: "最后更新于",
}, },
login: { login: {
accessToAll: "可访问全部数据", accessToAll: "可访问全部数据",
@ -67,14 +67,14 @@ export default {
<a href="https://github.com/qier222/YesPlayMusic" <a href="https://github.com/qier222/YesPlayMusic"
>YesPlayMusic GitHub 源代码仓库</a >YesPlayMusic GitHub 源代码仓库</a
> >
自行构建并使用自托管的网易云 API` 自行构建并使用自托管的网易云 API`,
}, },
mv: { mv: {
moreVideo: "更多视频" moreVideo: "更多视频",
}, },
next: { next: {
nowPlaying: "正在播放", nowPlaying: "正在播放",
nextUp: "即将播放" nextUp: "即将播放",
}, },
player: { player: {
like: "喜欢", like: "喜欢",
@ -85,10 +85,10 @@ export default {
play: "播放", play: "播放",
pause: "暂停", pause: "暂停",
mute: "静音", mute: "静音",
nextUp: "播放列表" nextUp: "播放列表",
}, },
modal: { modal: {
close: "关闭" close: "关闭",
}, },
search: { search: {
artist: "歌手", artist: "歌手",
@ -97,9 +97,9 @@ export default {
mv: "视频", mv: "视频",
playlist: "歌单", playlist: "歌单",
noResult: "暂无结果", noResult: "暂无结果",
searchFor: "搜索" searchFor: "搜索",
}, },
common: { common: {
songs: "首歌", songs: "首歌",
} },
}; };

@ -15,7 +15,7 @@ import { Integrations } from "@sentry/tracing";
Vue.use(VueAnalytics, { Vue.use(VueAnalytics, {
id: "UA-180189423-1", id: "UA-180189423-1",
router router,
}); });
Vue.config.productionTip = false; Vue.config.productionTip = false;
@ -30,14 +30,14 @@ if (process.env.VUE_APP_ENABLE_SENTRY === "true") {
integrations: [ integrations: [
new VueIntegration({ new VueIntegration({
Vue, Vue,
tracing: true tracing: true,
}), }),
new Integrations.BrowserTracing() new Integrations.BrowserTracing(),
], ],
// We recommend adjusting this value in production, or using tracesSampler // We recommend adjusting this value in production, or using tracesSampler
// for finer control // for finer control
tracesSampleRate: 1.0 tracesSampleRate: 1.0,
}); });
} }
@ -45,5 +45,5 @@ new Vue({
i18n, i18n,
store, store,
router, router,
render: h => h(App) render: (h) => h(App),
}).$mount("#app"); }).$mount("#app");

@ -1,32 +1,34 @@
/* eslint-disable no-console */ /* eslint-disable no-console */
import { register } from 'register-service-worker' import { register } from "register-service-worker";
if (process.env.NODE_ENV === 'production') { if (process.env.NODE_ENV === "production") {
register(`${process.env.BASE_URL}service-worker.js`, { register(`${process.env.BASE_URL}service-worker.js`, {
ready () { ready() {
console.log( console.log(
'App is being served from cache by a service worker.\n' + "App is being served from cache by a service worker.\n" +
'For more details, visit https://goo.gl/AFskqB' "For more details, visit https://goo.gl/AFskqB"
) );
}, },
registered () { registered() {
console.log('Service worker has been registered.') console.log("Service worker has been registered.");
}, },
cached () { cached() {
console.log('Content has been cached for offline use.') console.log("Content has been cached for offline use.");
}, },
updatefound () { updatefound() {
console.log('New content is downloading.') console.log("New content is downloading.");
}, },
updated () { updated() {
console.log('New content is available; please refresh.') console.log("New content is available; please refresh.");
}, },
offline () { offline() {
console.log('No internet connection found. App is running in offline mode.') console.log(
"No internet connection found. App is running in offline mode."
);
},
error(error) {
console.error("Error during service worker registration:", error);
}, },
error (error) { });
console.error('Error during service worker registration:', error)
}
})
} }

@ -4,27 +4,27 @@ import { isLoggedIn } from "@/utils/auth";
export default { export default {
switchTrack({ state, dispatch, commit }, basicTrack) { switchTrack({ state, dispatch, commit }, basicTrack) {
getTrackDetail(basicTrack.id).then(data => { getTrackDetail(basicTrack.id).then((data) => {
let track = data.songs[0]; let track = data.songs[0];
track.sort = basicTrack.sort; track.sort = basicTrack.sort;
// 获取当前的播放时间。初始化为 loading 状态时返回 howler 的实例而不是浮点数时间,比如 1.332 // 获取当前的播放时间。初始化为 loading 状态时返回 howler 的实例而不是浮点数时间,比如 1.332
let time = state.howler.seek(); let time = state.howler.seek();
let currentTime = 0 let currentTime = 0;
if (time === 0) { if (time === 0) {
// state.howler._duration 可以获得当前实例的播放时长 // state.howler._duration 可以获得当前实例的播放时长
currentTime = 180 currentTime = 180;
} }
if (time.toString() === '[object Object]') { if (time.toString() === "[object Object]") {
currentTime = 0 currentTime = 0;
} }
if (time > 0) { if (time > 0) {
currentTime = time currentTime = time;
} }
scrobble({ scrobble({
id: state.player.currentTrack.id, id: state.player.currentTrack.id,
sourceid: state.player.listInfo.id, sourceid: state.player.listInfo.id,
time: currentTime time: currentTime,
}) });
commit("updateCurrentTrack", track); commit("updateCurrentTrack", track);
updateMediaSessionMetaData(track); updateMediaSessionMetaData(track);
document.title = `${track.name} · ${track.ar[0].name} - YesPlayMusic`; document.title = `${track.name} · ${track.ar[0].name} - YesPlayMusic`;
@ -42,7 +42,7 @@ export default {
} }
if (isLoggedIn) { if (isLoggedIn) {
getMP3(track.id).then(data => { getMP3(track.id).then((data) => {
commitMP3(data.data[0].url.replace(/^http:/, "https:")); commitMP3(data.data[0].url.replace(/^http:/, "https:"));
}); });
} else { } else {
@ -53,24 +53,24 @@ export default {
playFirstTrackOnList({ state, dispatch }) { playFirstTrackOnList({ state, dispatch }) {
dispatch( dispatch(
"switchTrack", "switchTrack",
state.player.list.find(t => t.sort === 0) state.player.list.find((t) => t.sort === 0)
); );
}, },
playTrackOnListByID({ state, commit, dispatch }, trackID) { playTrackOnListByID({ state, commit, dispatch }, trackID) {
let track = state.player.list.find(t => t.id === trackID); let track = state.player.list.find((t) => t.id === trackID);
dispatch("switchTrack", track); dispatch("switchTrack", track);
if (state.player.shuffle) { if (state.player.shuffle) {
// 当随机模式开启时双击列表的一首歌进行播放此时要把这首歌的sort调到第一(0),这样用户就能随机播放完整的歌单 // 当随机模式开启时双击列表的一首歌进行播放此时要把这首歌的sort调到第一(0),这样用户就能随机播放完整的歌单
let otherTrack = state.player.list.find(t => t.sort === 0); let otherTrack = state.player.list.find((t) => t.sort === 0);
commit("switchSortBetweenTwoTracks", { commit("switchSortBetweenTwoTracks", {
trackID1: track.id, trackID1: track.id,
trackID2: otherTrack.id trackID2: otherTrack.id,
}); });
} }
}, },
nextTrack({ state, dispatch }, realNext = false) { nextTrack({ state, dispatch }, realNext = false) {
let nextTrack = state.player.list.find( let nextTrack = state.player.list.find(
track => track.sort === state.player.currentTrack.sort + 1 (track) => track.sort === state.player.currentTrack.sort + 1
); );
if (state.player.repeat === "one" && realNext === false) { if (state.player.repeat === "one" && realNext === false) {
@ -79,7 +79,7 @@ export default {
if (nextTrack === undefined) { if (nextTrack === undefined) {
if (state.player.repeat !== "off") { if (state.player.repeat !== "off") {
nextTrack = state.player.list.find(t => t.sort === 0); nextTrack = state.player.list.find((t) => t.sort === 0);
} else { } else {
return; return;
} }
@ -89,13 +89,13 @@ export default {
}, },
previousTrack({ state, dispatch }) { previousTrack({ state, dispatch }) {
let previousTrack = state.player.list.find( let previousTrack = state.player.list.find(
track => track.sort === state.player.currentTrack.sort - 1 (track) => track.sort === state.player.currentTrack.sort - 1
); );
if (previousTrack == undefined) { if (previousTrack == undefined) {
if (state.player.repeat !== "off") { if (state.player.repeat !== "off") {
previousTrack = state.player.list.reduce((x, y) => (x > y ? x : y)); previousTrack = state.player.list.reduce((x, y) => (x > y ? x : y));
} else { } else {
previousTrack = state.player.list.find(t => t.sort === 0); previousTrack = state.player.list.find((t) => t.sort === 0);
} }
} }
dispatch("switchTrack", previousTrack); dispatch("switchTrack", previousTrack);
@ -104,5 +104,5 @@ export default {
state.howler.once("end", () => { state.howler.once("end", () => {
dispatch("nextTrack"); dispatch("nextTrack");
}); });
} },
}; };

@ -13,7 +13,7 @@ if (localStorage.getItem("appVersion") === null) {
window.location.reload(); window.location.reload();
} }
const saveToLocalStorage = store => { const saveToLocalStorage = (store) => {
store.subscribe((mutation, state) => { store.subscribe((mutation, state) => {
// console.log(mutation); // console.log(mutation);
localStorage.setItem("player", JSON.stringify(state.player)); localStorage.setItem("player", JSON.stringify(state.player));
@ -26,15 +26,15 @@ const store = new Vuex.Store({
state: state, state: state,
mutations, mutations,
actions, actions,
plugins: [saveToLocalStorage] plugins: [saveToLocalStorage],
}); });
store.state.howler = new Howl({ store.state.howler = new Howl({
src: [ src: [
`https://music.163.com/song/media/outer/url?id=${store.state.player.currentTrack.id}` `https://music.163.com/song/media/outer/url?id=${store.state.player.currentTrack.id}`,
], ],
html5: true, html5: true,
format: ["mp3"] format: ["mp3"],
}); });
Howler.volume(store.state.player.volume); Howler.volume(store.state.player.volume);

@ -1,11 +1,11 @@
const initState = { const initState = {
howler: null, howler: null,
liked: { liked: {
songs: [] songs: [],
}, },
contextMenu: { contextMenu: {
clickObjectID: 0, clickObjectID: 0,
showMenu: false showMenu: false,
}, },
player: { player: {
enable: false, enable: false,
@ -26,51 +26,51 @@ const initState = {
"https://p1.music.126.net/kHNNN-VxufjlBtyNPIP3kg==/109951165306614548.jpg", "https://p1.music.126.net/kHNNN-VxufjlBtyNPIP3kg==/109951165306614548.jpg",
tns: [], tns: [],
pic_str: "109951165306614548", pic_str: "109951165306614548",
pic: 109951165306614540 pic: 109951165306614540,
}, },
time: 196022, time: 196022,
playable: true playable: true,
}, },
notShuffledList: [], notShuffledList: [],
list: [], list: [],
listInfo: { listInfo: {
type: "", type: "",
id: "" id: "",
} },
}, },
settings: { settings: {
playlistCategories: [ playlistCategories: [
{ {
name: "全部", name: "全部",
enable: true enable: true,
}, },
{ {
name: "推荐歌单", name: "推荐歌单",
enable: true enable: true,
}, },
{ {
name: "精品歌单", name: "精品歌单",
enable: true enable: true,
}, },
{ {
name: "官方", name: "官方",
enable: true enable: true,
}, },
{ {
name: "流行", name: "流行",
enable: true enable: true,
}, },
{ {
name: "电子", name: "电子",
enable: true enable: true,
}, },
{ {
name: "摇滚", name: "摇滚",
enable: true enable: true,
}, },
{ {
name: "ACG", name: "ACG",
enable: true enable: true,
}, },
// { // {
// name: "最新专辑", // name: "最新专辑",
@ -78,14 +78,14 @@ const initState = {
// }, // },
{ {
name: "排行榜", name: "排行榜",
enable: true enable: true,
} },
], ],
user: { user: {
id: 0 id: 0,
}, },
lang: null lang: null,
} },
}; };
export default initState; export default initState;

@ -13,7 +13,7 @@ export default {
state.howler = new Howl({ state.howler = new Howl({
src: [mp3], src: [mp3],
autoplay: true, autoplay: true,
html5: true html5: true,
}); });
state.howler.play(); state.howler.play();
}, },
@ -28,7 +28,7 @@ export default {
state.player.repeat = status; state.player.repeat = status;
}, },
appendTrackToPlayerList(state, { track, playNext = false }) { appendTrackToPlayerList(state, { track, playNext = false }) {
let existTrack = state.player.list.find(t => t.id === track.id); let existTrack = state.player.list.find((t) => t.id === track.id);
if ( if (
(existTrack === null || existTrack === undefined) && (existTrack === null || existTrack === undefined) &&
playNext === false playNext === false
@ -38,7 +38,7 @@ export default {
} }
// 把track加入到正在播放歌曲的下一首位置 // 把track加入到正在播放歌曲的下一首位置
state.player.list = state.player.list.map(t => { state.player.list = state.player.list.map((t) => {
if (t.sort > state.player.currentTrack.sort) { if (t.sort > state.player.currentTrack.sort) {
t.sort = t.sort + 1; t.sort = t.sort + 1;
} }
@ -54,10 +54,10 @@ export default {
state.player.shuffle = true; state.player.shuffle = true;
let newSorts = shuffleAList( let newSorts = shuffleAList(
state.player.list.filter(t => t.sort > state.player.currentTrack.sort) state.player.list.filter((t) => t.sort > state.player.currentTrack.sort)
); );
state.player.list = state.player.list.map(track => { state.player.list = state.player.list.map((track) => {
if (newSorts[track.id] !== undefined) track.sort = newSorts[track.id]; if (newSorts[track.id] !== undefined) track.sort = newSorts[track.id];
return track; return track;
}); });
@ -68,7 +68,7 @@ export default {
JSON.stringify(state.player.notShuffledList) JSON.stringify(state.player.notShuffledList)
); );
state.player.currentTrack.sort = state.player.list.find( state.player.currentTrack.sort = state.player.list.find(
t => t.id === state.player.currentTrack.id (t) => t.id === state.player.currentTrack.id
).sort; ).sort;
}, },
shuffleTheListBeforePlay(state) { shuffleTheListBeforePlay(state) {
@ -76,7 +76,7 @@ export default {
JSON.stringify(state.player.list) JSON.stringify(state.player.list)
); );
let newSorts = shuffleAList(state.player.list); let newSorts = shuffleAList(state.player.list);
state.player.list = state.player.list.map(track => { state.player.list = state.player.list.map((track) => {
track.sort = newSorts[track.id]; track.sort = newSorts[track.id];
return track; return track;
}); });
@ -91,10 +91,10 @@ export default {
state.liked.songs = trackIDs; state.liked.songs = trackIDs;
}, },
switchSortBetweenTwoTracks(state, { trackID1, trackID2 }) { switchSortBetweenTwoTracks(state, { trackID1, trackID2 }) {
let t1 = state.player.list.find(t => t.id === trackID1); let t1 = state.player.list.find((t) => t.id === trackID1);
let t2 = state.player.list.find(t => t.id === trackID2); let t2 = state.player.list.find((t) => t.id === trackID2);
let sorts = [t1.sort, t2.sort]; let sorts = [t1.sort, t2.sort];
state.player.list = state.player.list.map(t => { state.player.list = state.player.list.map((t) => {
if (t.id === t1.id) t.sort = sorts[1]; if (t.id === t1.id) t.sort = sorts[1];
if (t.id === t2.id) t.sort = sorts[0]; if (t.id === t2.id) t.sort = sorts[0];
return t; return t;
@ -102,5 +102,5 @@ export default {
}, },
changeLang(state, lang) { changeLang(state, lang) {
state.settings.lang = lang; state.settings.lang = lang;
} },
}; };

@ -4,7 +4,7 @@ import store from "@/store";
export function isTrackPlayable(track) { export function isTrackPlayable(track) {
let result = { let result = {
playable: true, playable: true,
reason: "" reason: "",
}; };
if (track.fee === 1 || track.privilege?.fee === 1) { if (track.fee === 1 || track.privilege?.fee === 1) {
if (isLoggedIn && store.state.settings.user.vipType === 11) { if (isLoggedIn && store.state.settings.user.vipType === 11) {
@ -27,7 +27,7 @@ export function isTrackPlayable(track) {
} }
export function mapTrackPlayableStatus(tracks) { export function mapTrackPlayableStatus(tracks) {
return tracks.map(t => { return tracks.map((t) => {
let result = isTrackPlayable(t); let result = isTrackPlayable(t);
t.playable = result.playable; t.playable = result.playable;
t.reason = result.reason; t.reason = result.reason;
@ -47,13 +47,13 @@ export function randomNum(minNum, maxNum) {
} }
export function shuffleAList(list) { export function shuffleAList(list) {
let sortsList = list.map(t => t.sort); let sortsList = list.map((t) => t.sort);
for (let i = 1; i < sortsList.length; i++) { for (let i = 1; i < sortsList.length; i++) {
const random = Math.floor(Math.random() * (i + 1)); const random = Math.floor(Math.random() * (i + 1));
[sortsList[i], sortsList[random]] = [sortsList[random], sortsList[i]]; [sortsList[i], sortsList[random]] = [sortsList[random], sortsList[i]];
} }
let newSorts = {}; let newSorts = {};
list.map(track => { list.map((track) => {
newSorts[track.id] = sortsList.pop(); newSorts[track.id] = sortsList.pop();
}); });
return newSorts; return newSorts;
@ -65,6 +65,8 @@ export function throttle(fn, time) {
if (isRun) return; if (isRun) return;
isRun = true; isRun = true;
fn.apply(this, arguments); fn.apply(this, arguments);
setTimeout(() => { isRun = false }, time); setTimeout(() => {
} isRun = false;
}, time);
};
} }

@ -12,10 +12,7 @@ Vue.filter("formatTime", (Milliseconds, format = "HH:MM:SS") => {
let time = dayjs.duration(Milliseconds); let time = dayjs.duration(Milliseconds);
let hours = time.hours().toString(); let hours = time.hours().toString();
let mins = time.minutes().toString(); let mins = time.minutes().toString();
let seconds = time let seconds = time.seconds().toString().padStart(2, "0");
.seconds()
.toString()
.padStart(2, "0");
if (format === "HH:MM:SS") { if (format === "HH:MM:SS") {
return hours !== "0" return hours !== "0"
@ -24,7 +21,9 @@ Vue.filter("formatTime", (Milliseconds, format = "HH:MM:SS") => {
} else if (format === "Human") { } else if (format === "Human") {
const hoursUnit = locale.locale === "zh-CN" ? "小时" : "hr"; const hoursUnit = locale.locale === "zh-CN" ? "小时" : "hr";
const minitesUnit = locale.locale === "zh-CN" ? "分钟" : "min"; const minitesUnit = locale.locale === "zh-CN" ? "分钟" : "min";
return hours !== "0" ? `${hours} ${hoursUnit} ${mins} ${minitesUnit}` : `${mins} ${minitesUnit}`; return hours !== "0"
? `${hours} ${hoursUnit} ${mins} ${minitesUnit}`
: `${mins} ${minitesUnit}`;
} }
}); });
@ -56,7 +55,7 @@ Vue.filter("resizeImage", (imgUrl, size = 512) => {
return `${httpsImgUrl}?param=${size}y${size}`; return `${httpsImgUrl}?param=${size}y${size}`;
}); });
Vue.filter("formatPlayCount", count => { Vue.filter("formatPlayCount", (count) => {
if (!count) return ""; if (!count) return "";
if (locale.locale === "zh-CN") { if (locale.locale === "zh-CN") {
if (count > 100000000) { if (count > 100000000) {
@ -83,7 +82,7 @@ Vue.filter("formatPlayCount", count => {
} }
}); });
Vue.filter("toHttps", url => { Vue.filter("toHttps", (url) => {
if (!url) return ""; if (!url) return "";
return url.replace(/^http:/, "https:"); return url.replace(/^http:/, "https:");
}); });

@ -2,16 +2,16 @@ import store from "@/store";
export function initMediaSession() { export function initMediaSession() {
if ("mediaSession" in navigator) { if ("mediaSession" in navigator) {
navigator.mediaSession.setActionHandler("play", function() { navigator.mediaSession.setActionHandler("play", function () {
store.state.howler.play(); store.state.howler.play();
}); });
navigator.mediaSession.setActionHandler("pause", function() { navigator.mediaSession.setActionHandler("pause", function () {
store.state.howler.pause(); store.state.howler.pause();
}); });
navigator.mediaSession.setActionHandler("previoustrack", function() { navigator.mediaSession.setActionHandler("previoustrack", function () {
store.dispatch("previousTrack"); store.dispatch("previousTrack");
}); });
navigator.mediaSession.setActionHandler("nexttrack", function() { navigator.mediaSession.setActionHandler("nexttrack", function () {
store.dispatch("nextTrack"); store.dispatch("nextTrack");
}); });
navigator.mediaSession.setActionHandler("stop", () => { navigator.mediaSession.setActionHandler("stop", () => {

@ -3,18 +3,18 @@ import axios from "axios";
const service = axios.create({ const service = axios.create({
baseURL: process.env.VUE_APP_NETEASE_API_URL, baseURL: process.env.VUE_APP_NETEASE_API_URL,
withCredentials: true, withCredentials: true,
timeout: 15000 timeout: 15000,
}); });
const errors = new Map([ const errors = new Map([
[401, "The token you are using has expired."], [401, "The token you are using has expired."],
[502, null], [502, null],
[301, "You must login to use this feature."], [301, "You must login to use this feature."],
[-1, "An unexpected error has occurred: "] [-1, "An unexpected error has occurred: "],
]); ]);
service.interceptors.response.use( service.interceptors.response.use(
response => { (response) => {
const res = response.data; const res = response.data;
if (res.code !== 200) { if (res.code !== 200) {
@ -30,7 +30,7 @@ service.interceptors.response.use(
return res; return res;
} }
}, },
error => { (error) => {
const errMsg = `error: ${error}`; const errMsg = `error: ${error}`;
console.log(errMsg); console.log(errMsg);

@ -27,13 +27,14 @@
<span :title="album.publishTime | formatDate">{{ <span :title="album.publishTime | formatDate">{{
new Date(album.publishTime).getFullYear() new Date(album.publishTime).getFullYear()
}}</span> }}</span>
<span> · {{ album.size }} {{ $t("common.songs") }}</span>, <span> · {{ album.size }} {{ $t("common.songs") }}</span
>,
{{ albumTime | formatTime("Human") }} {{ albumTime | formatTime("Human") }}
</div> </div>
<div class="description" @click="showFullDescription = true"> <div class="description" @click="showFullDescription = true">
{{ album.description }} {{ album.description }}
</div> </div>
<div class="buttons" style="margin-top:32px"> <div class="buttons" style="margin-top: 32px">
<ButtonTwoTone <ButtonTwoTone
@click.native="playAlbumByID(album.id)" @click.native="playAlbumByID(album.id)"
:iconClass="`play`" :iconClass="`play`"
@ -63,7 +64,7 @@
<div class="description-full" @click.stop> <div class="description-full" @click.stop>
<span>{{ album.description }}</span> <span>{{ album.description }}</span>
<span class="close" @click="showFullDescription = false"> <span class="close" @click="showFullDescription = false">
{{ $t('modal.close') }} {{ $t("modal.close") }}
</span> </span>
</div> </div>
</div> </div>
@ -89,7 +90,7 @@ export default {
Cover, Cover,
ButtonTwoTone, ButtonTwoTone,
TrackList, TrackList,
ExplicitSymbol ExplicitSymbol,
}, },
data() { data() {
return { return {
@ -97,27 +98,27 @@ export default {
id: 0, id: 0,
picUrl: "", picUrl: "",
artist: { artist: {
id: 0 id: 0,
} },
}, },
tracks: [], tracks: [],
showFullDescription: false, showFullDescription: false,
show: false show: false,
}; };
}, },
created() { created() {
getAlbum(this.$route.params.id) getAlbum(this.$route.params.id)
.then(data => { .then((data) => {
this.album = data.album; this.album = data.album;
this.tracks = data.songs; this.tracks = data.songs;
NProgress.done(); NProgress.done();
this.show = true; this.show = true;
return this.tracks; return this.tracks;
}) })
.then(tracks => { .then((tracks) => {
// to get explicit mark // to get explicit mark
let trackIDs = tracks.map(t => t.id); let trackIDs = tracks.map((t) => t.id);
getTrackDetail(trackIDs.join(",")).then(data => { getTrackDetail(trackIDs.join(",")).then((data) => {
this.tracks = data.songs; this.tracks = data.songs;
}); });
}); });
@ -126,20 +127,20 @@ export default {
...mapState(["player"]), ...mapState(["player"]),
albumTime() { albumTime() {
let time = 0; let time = 0;
this.tracks.map(t => (time = time + t.dt)); this.tracks.map((t) => (time = time + t.dt));
return time; return time;
} },
}, },
methods: { methods: {
...mapMutations(["appendTrackToPlayerList"]), ...mapMutations(["appendTrackToPlayerList"]),
...mapActions(["playFirstTrackOnList", "playTrackOnListByID"]), ...mapActions(["playFirstTrackOnList", "playTrackOnListByID"]),
playAlbumByID(id, trackID = "first") { playAlbumByID(id, trackID = "first") {
if (this.tracks.find(t => t.playable !== false) === undefined) { if (this.tracks.find((t) => t.playable !== false) === undefined) {
return; return;
} }
playAlbumByID(id, trackID); playAlbumByID(id, trackID);
} },
} },
}; };
</script> </script>

@ -112,7 +112,7 @@ export default {
show: false, show: false,
artist: { artist: {
img1v1Url: img1v1Url:
"https://p1.music.126.net/VnZiScyynLG7atLIZ2YPkw==/18686200114669622.jpg" "https://p1.music.126.net/VnZiScyynLG7atLIZ2YPkw==/18686200114669622.jpg",
}, },
popularTracks: [], popularTracks: [],
albumsData: [], albumsData: [],
@ -122,52 +122,52 @@ export default {
id: 0, id: 0,
name: "", name: "",
type: "", type: "",
size: "" size: "",
}, },
showMorePopTracks: false, showMorePopTracks: false,
mvs: [] mvs: [],
}; };
}, },
computed: { computed: {
...mapState(["player"]), ...mapState(["player"]),
albums() { albums() {
return this.albumsData.filter(a => a.type === "专辑"); return this.albumsData.filter((a) => a.type === "专辑");
}, },
eps() { eps() {
return this.albumsData.filter(a => return this.albumsData.filter((a) =>
["EP/Single", "EP", "Single"].includes(a.type) ["EP/Single", "EP", "Single"].includes(a.type)
); );
} },
}, },
methods: { methods: {
...mapMutations(["appendTrackToPlayerList"]), ...mapMutations(["appendTrackToPlayerList"]),
...mapActions(["playFirstTrackOnList", "playTrackOnListByID"]), ...mapActions(["playFirstTrackOnList", "playTrackOnListByID"]),
loadData(id, next = undefined) { loadData(id, next = undefined) {
getArtist(id).then(data => { getArtist(id).then((data) => {
this.artist = data.artist; this.artist = data.artist;
this.popularTracks = data.hotSongs; this.popularTracks = data.hotSongs;
if (next !== undefined) next(); if (next !== undefined) next();
NProgress.done(); NProgress.done();
this.show = true; this.show = true;
}); });
getArtistAlbum({ id: id, limit: 200 }).then(data => { getArtistAlbum({ id: id, limit: 200 }).then((data) => {
this.albumsData = data.hotAlbums; this.albumsData = data.hotAlbums;
this.latestRelease = data.hotAlbums[0]; this.latestRelease = data.hotAlbums[0];
}); });
artistMv(id).then(data => { artistMv(id).then((data) => {
this.mvs = data.mvs; this.mvs = data.mvs;
}); });
}, },
goToAlbum(id) { goToAlbum(id) {
this.$router.push({ this.$router.push({
name: "album", name: "album",
params: { id } params: { id },
}); });
}, },
playPopularSongs(trackID = "first") { playPopularSongs(trackID = "first") {
let trackIDs = this.popularTracks.map(t => t.id); let trackIDs = this.popularTracks.map((t) => t.id);
playAList(trackIDs, this.artist.id, "artist", trackID); playAList(trackIDs, this.artist.id, "artist", trackID);
} },
}, },
created() { created() {
this.loadData(this.$route.params.id); this.loadData(this.$route.params.id);
@ -186,7 +186,7 @@ export default {
this.artist.img1v1Url = this.artist.img1v1Url =
"https://p1.music.126.net/VnZiScyynLG7atLIZ2YPkw==/18686200114669622.jpg"; "https://p1.music.126.net/VnZiScyynLG7atLIZ2YPkw==/18686200114669622.jpg";
this.loadData(to.params.id, next); this.loadData(to.params.id, next);
} },
}; };
</script> </script>

@ -1,6 +1,6 @@
<template> <template>
<div class="explore"> <div class="explore">
<h1>{{ $t('explore.explore') }}</h1> <h1>{{ $t("explore.explore") }}</h1>
<div class="buttons"> <div class="buttons">
<div <div
class="button" class="button"
@ -35,7 +35,7 @@
@click.native="getPlaylist" @click.native="getPlaylist"
color="grey" color="grey"
:loading="loadingMore" :loading="loadingMore"
>{{ $t('explore.loadMore') }}</ButtonTwoTone >{{ $t("explore.loadMore") }}</ButtonTwoTone
> >
</div> </div>
</div> </div>
@ -102,28 +102,26 @@ export default {
getPlaylist() { getPlaylist() {
this.loadingMore = true; this.loadingMore = true;
if (this.activeCategory === "推荐歌单") { if (this.activeCategory === "推荐歌单") {
return this.getRecommendPlayList() return this.getRecommendPlayList();
} }
if (this.activeCategory === "精品歌单") { if (this.activeCategory === "精品歌单") {
return this.getHighQualityPlaylist() return this.getHighQualityPlaylist();
} }
if (this.activeCategory === "排行榜") { if (this.activeCategory === "排行榜") {
return this.getTopLists() return this.getTopLists();
} }
return this.getTopPlayList() return this.getTopPlayList();
}, },
getRecommendPlayList() { getRecommendPlayList() {
recommendPlaylist({ limit: 100 }).then(data => { recommendPlaylist({ limit: 100 }).then((data) => {
this.playlists = [] this.playlists = [];
this.updatePlaylist(data.result); this.updatePlaylist(data.result);
}); });
}, },
getHighQualityPlaylist() { getHighQualityPlaylist() {
let playlists = this.playlists; let playlists = this.playlists;
let before = let before =
playlists.length !== 0 playlists.length !== 0 ? playlists[playlists.length - 1].updateTime : 0;
? playlists[playlists.length - 1].updateTime
: 0;
highQualityPlaylist({ limit: 50, before }).then((data) => { highQualityPlaylist({ limit: 50, before }).then((data) => {
this.updatePlaylist(data.playlists); this.updatePlaylist(data.playlists);
this.hasMore = data.more; this.hasMore = data.more;
@ -131,7 +129,7 @@ export default {
}, },
getTopLists() { getTopLists() {
toplists().then((data) => { toplists().then((data) => {
this.playlists = [] this.playlists = [];
this.updatePlaylist(data.list); this.updatePlaylist(data.list);
}); });
}, },
@ -139,11 +137,11 @@ export default {
topPlaylist({ topPlaylist({
cat: this.activeCategory, cat: this.activeCategory,
offset: this.playlists.length, offset: this.playlists.length,
}).then(data => { }).then((data) => {
this.updatePlaylist(data.playlists); this.updatePlaylist(data.playlists);
this.hasMore = data.more; this.hasMore = data.more;
}); });
} },
}, },
activated() { activated() {
this.loadData(); this.loadData();

@ -1,9 +1,7 @@
<template> <template>
<div class="home" v-show="show"> <div class="home" v-show="show">
<div class="index-row"> <div class="index-row">
<div class="title"> <div class="title"> by Apple Music </div>
by Apple Music
</div>
<CoverRow <CoverRow
:type="'playlist'" :type="'playlist'"
:items="byAppleMusic" :items="byAppleMusic"
@ -70,36 +68,36 @@ export default {
newReleasesAlbum: { items: [] }, newReleasesAlbum: { items: [] },
topList: { topList: {
items: [], items: [],
ids: [19723756, 180106, 60198, 3812895, 60131] ids: [19723756, 180106, 60198, 3812895, 60131],
}, },
recommendArtists: { recommendArtists: {
items: [], items: [],
indexs: [] indexs: [],
} },
}; };
}, },
computed: { computed: {
byAppleMusic() { byAppleMusic() {
return byAppleMusic; return byAppleMusic;
} },
}, },
methods: { methods: {
loadData() { loadData() {
if (!this.show) NProgress.start(); if (!this.show) NProgress.start();
recommendPlaylist({ recommendPlaylist({
limit: 10 limit: 10,
}).then(data => { }).then((data) => {
this.recommendPlaylist.items = data.result; this.recommendPlaylist.items = data.result;
NProgress.done(); NProgress.done();
this.show = true; this.show = true;
}); });
newAlbums({ newAlbums({
area: "EA", area: "EA",
limit: 10 limit: 10,
}).then(data => { }).then((data) => {
this.newReleasesAlbum.items = data.albums; this.newReleasesAlbum.items = data.albums;
}); });
toplistOfArtists(2).then(data => { toplistOfArtists(2).then((data) => {
let indexs = []; let indexs = [];
while (indexs.length < 5) { while (indexs.length < 5) {
let tmp = ~~(Math.random() * 100); let tmp = ~~(Math.random() * 100);
@ -110,16 +108,16 @@ export default {
indexs.includes(index) indexs.includes(index)
); );
}); });
toplists().then(data => { toplists().then((data) => {
this.topList.items = data.list.filter(l => this.topList.items = data.list.filter((l) =>
this.topList.ids.includes(l.id) this.topList.ids.includes(l.id)
); );
}); });
} },
}, },
activated() { activated() {
this.loadData(); this.loadData();
} },
}; };
</script> </script>

@ -76,23 +76,23 @@ export default {
user: { user: {
profile: { profile: {
avatarUrl: "", avatarUrl: "",
nickname: "" nickname: "",
} },
}, },
playlists: [], playlists: [],
hasMorePlaylists: true, hasMorePlaylists: true,
likedSongsPlaylist: { likedSongsPlaylist: {
id: 0, id: 0,
trackCount: 0 trackCount: 0,
}, },
likedSongs: [], likedSongs: [],
likedSongIDs: [], likedSongIDs: [],
lyric: undefined lyric: undefined,
}; };
}, },
created() { created() {
NProgress.start(); NProgress.start();
userDetail(this.settings.user.userId).then(data => { userDetail(this.settings.user.userId).then((data) => {
this.user = data; this.user = data;
}); });
}, },
@ -107,7 +107,7 @@ export default {
pickedLyric() { pickedLyric() {
if (this.lyric === undefined) return ""; if (this.lyric === undefined) return "";
let lyric = this.lyric.split("\n"); let lyric = this.lyric.split("\n");
lyric = lyric.filter(l => { lyric = lyric.filter((l) => {
if (l.includes("作词") || l.includes("作曲")) { if (l.includes("作词") || l.includes("作曲")) {
return false; return false;
} }
@ -120,9 +120,9 @@ export default {
return [ return [
lyric[lineIndex].split("]")[1], lyric[lineIndex].split("]")[1],
lyric[lineIndex + 1].split("]")[1], lyric[lineIndex + 1].split("]")[1],
lyric[lineIndex + 2].split("]")[1] lyric[lineIndex + 2].split("]")[1],
]; ];
} },
}, },
methods: { methods: {
playLikedSongs() { playLikedSongs() {
@ -141,8 +141,8 @@ export default {
userPlaylist({ userPlaylist({
uid: this.settings.user.userId, uid: this.settings.user.userId,
offset: this.playlists.length === 0 ? 0 : this.playlists.length - 1, offset: this.playlists.length === 0 ? 0 : this.playlists.length - 1,
timestamp: new Date().getTime() timestamp: new Date().getTime(),
}).then(data => { }).then((data) => {
if (replace) { if (replace) {
this.playlists = data.playlist; this.playlists = data.playlist;
} else { } else {
@ -153,11 +153,11 @@ export default {
}, },
getLikedSongs(getLyric = true) { getLikedSongs(getLyric = true) {
getPlaylistDetail(this.settings.user.likedSongPlaylistID, true).then( getPlaylistDetail(this.settings.user.likedSongPlaylistID, true).then(
data => { (data) => {
this.likedSongsPlaylist = data.playlist; this.likedSongsPlaylist = data.playlist;
let TrackIDs = data.playlist.trackIds.slice(0, 20).map(t => t.id); let TrackIDs = data.playlist.trackIds.slice(0, 20).map((t) => t.id);
this.likedSongIDs = TrackIDs; this.likedSongIDs = TrackIDs;
getTrackDetail(this.likedSongIDs.join(",")).then(data => { getTrackDetail(this.likedSongIDs.join(",")).then((data) => {
this.likedSongs = data.songs; this.likedSongs = data.songs;
NProgress.done(); NProgress.done();
this.show = true; this.show = true;
@ -169,16 +169,16 @@ export default {
getRandomLyric() { getRandomLyric() {
getLyric( getLyric(
this.likedSongIDs[randomNum(0, this.likedSongIDs.length - 1)] this.likedSongIDs[randomNum(0, this.likedSongIDs.length - 1)]
).then(data => { ).then((data) => {
if (data.lrc !== undefined) this.lyric = data.lrc.lyric; if (data.lrc !== undefined) this.lyric = data.lrc.lyric;
}); });
} },
}, },
watch: { watch: {
likedSongsInState() { likedSongsInState() {
this.getLikedSongs(false); this.getLikedSongs(false);
} },
} },
}; };
</script> </script>

@ -14,8 +14,8 @@
> >
<div class="container" :class="{ active: activeCard === 1 }"> <div class="container" :class="{ active: activeCard === 1 }">
<div class="title-info"> <div class="title-info">
<div class="title">{{ $t('login.loginText') }}</div> <div class="title">{{ $t("login.loginText") }}</div>
<div class="info">{{ $t('login.accessToAll') }}</div> <div class="info">{{ $t("login.accessToAll") }}</div>
</div> </div>
<svg-icon icon-class="arrow-right"></svg-icon> <svg-icon icon-class="arrow-right"></svg-icon>
</div> </div>
@ -28,8 +28,8 @@
> >
<div class="container" :class="{ active: activeCard === 2 }"> <div class="container" :class="{ active: activeCard === 2 }">
<div class="title-info"> <div class="title-info">
<div class="title">{{ $t('login.search') }}</div> <div class="title">{{ $t("login.search") }}</div>
<div class="info">{{ $t('login.readonly') }}</div> <div class="info">{{ $t("login.readonly") }}</div>
</div> </div>
<svg-icon icon-class="arrow-right"></svg-icon> <svg-icon icon-class="arrow-right"></svg-icon>
</div> </div>

@ -102,7 +102,7 @@ export default {
email: "", email: "",
password: "", password: "",
smsCode: "", smsCode: "",
inputFocus: "" inputFocus: "",
}; };
}, },
created() { created() {
@ -118,11 +118,11 @@ export default {
Cookies.set("loginMode", "account", { expires: 3650 }); Cookies.set("loginMode", "account", { expires: 3650 });
userPlaylist({ userPlaylist({
uid: this.$store.state.settings.user.userId, uid: this.$store.state.settings.user.userId,
limit: 1 limit: 1,
}).then(data => { }).then((data) => {
this.updateUserInfo({ this.updateUserInfo({
key: "likedSongPlaylistID", key: "likedSongPlaylistID",
value: data.playlist[0].id value: data.playlist[0].id,
}); });
this.$router.push({ path: "/library" }); this.$router.push({ path: "/library" });
}); });
@ -143,15 +143,15 @@ export default {
countrycode: this.countryCode.replace("+", "").replace(/\s/g, ""), countrycode: this.countryCode.replace("+", "").replace(/\s/g, ""),
phone: this.phoneNumber.replace(/\s/g, ""), phone: this.phoneNumber.replace(/\s/g, ""),
password: "fakePassword", password: "fakePassword",
md5_password: md5(this.password).toString() md5_password: md5(this.password).toString(),
}) })
.then(data => { .then((data) => {
if (data.code !== 502) { if (data.code !== 502) {
this.updateUser(data.profile); this.updateUser(data.profile);
this.afterLogin(); this.afterLogin();
} }
}) })
.catch(error => { .catch((error) => {
this.processing = false; this.processing = false;
alert(error); alert(error);
}); });
@ -169,21 +169,21 @@ export default {
loginWithEmail({ loginWithEmail({
email: this.email.replace(/\s/g, ""), email: this.email.replace(/\s/g, ""),
password: "fakePassword", password: "fakePassword",
md5_password: md5(this.password).toString() md5_password: md5(this.password).toString(),
}) })
.then(data => { .then((data) => {
if (data.code !== 502) { if (data.code !== 502) {
this.updateUser(data.profile); this.updateUser(data.profile);
this.afterLogin(); this.afterLogin();
} }
}) })
.catch(error => { .catch((error) => {
this.processing = false; this.processing = false;
alert(error); alert(error);
}); });
} }
} },
} },
}; };
</script> </script>

@ -1,7 +1,7 @@
<template> <template>
<div class="login"> <div class="login">
<div> <div>
<div class="title">{{ $t('login.usernameLogin') }}</div> <div class="title">{{ $t("login.usernameLogin") }}</div>
<div class="sestion"> <div class="sestion">
<div class="search-box"> <div class="search-box">
<div class="container"> <div class="container">
@ -53,7 +53,7 @@ import NProgress from "nprogress";
import { search } from "@/api/others"; import { search } from "@/api/others";
import Cookies from "js-cookie"; import Cookies from "js-cookie";
import { userPlaylist } from "@/api/user"; import { userPlaylist } from "@/api/user";
import { throttle } from '@/utils/common'; import { throttle } from "@/utils/common";
import ButtonTwoTone from "@/components/ButtonTwoTone.vue"; import ButtonTwoTone from "@/components/ButtonTwoTone.vue";
@ -97,7 +97,7 @@ export default {
}, },
throttleSearch: throttle(function () { throttleSearch: throttle(function () {
this.search(); this.search();
}, 500) }, 500),
}, },
}; };
</script> </script>

@ -1,6 +1,6 @@
<template> <template>
<div class="newAlbum"> <div class="newAlbum">
<h1>{{ $t("home.newAlbum")}}</h1> <h1>{{ $t("home.newAlbum") }}</h1>
<div class="playlist-row"> <div class="playlist-row">
<div class="playlists"> <div class="playlists">

@ -24,11 +24,11 @@ import TrackList from "@/components/TrackList.vue";
export default { export default {
name: "Next", name: "Next",
components: { components: {
TrackList TrackList,
}, },
data() { data() {
return { return {
tracks: [] tracks: [],
}; };
}, },
computed: { computed: {
@ -41,58 +41,60 @@ export default {
}, },
sortedTracks() { sortedTracks() {
function compare(property) { function compare(property) {
return function(obj1, obj2) { return function (obj1, obj2) {
var value1 = obj1[property]; var value1 = obj1[property];
var value2 = obj2[property]; var value2 = obj2[property];
return value1 - value2; return value1 - value2;
}; };
} }
return this.tracks return this.tracks
.filter(t => this.player.list.find(t2 => t2.id === t.id) !== undefined) .filter(
.filter(t => t.sort > this.player.currentTrack.sort) (t) => this.player.list.find((t2) => t2.id === t.id) !== undefined
)
.filter((t) => t.sort > this.player.currentTrack.sort)
.sort(compare("sort")); .sort(compare("sort"));
} },
}, },
watch: { watch: {
currentTrack() { currentTrack() {
this.loadTracks(); this.loadTracks();
}, },
playerShuffle() { playerShuffle() {
this.tracks = this.tracks.map(t => { this.tracks = this.tracks.map((t) => {
t.sort = this.player.list.find(t2 => t.id === t2.id).sort; t.sort = this.player.list.find((t2) => t.id === t2.id).sort;
return t; return t;
}); });
} },
}, },
methods: { methods: {
...mapActions(["playTrackOnListByID"]), ...mapActions(["playTrackOnListByID"]),
loadTracks() { loadTracks() {
console.time("loadTracks"); console.time("loadTracks");
let loadedTrackIDs = this.tracks.map(t => t.id); let loadedTrackIDs = this.tracks.map((t) => t.id);
let basicTracks = this.player.list let basicTracks = this.player.list
.filter( .filter(
t => (t) =>
t.sort > this.player.currentTrack.sort && t.sort > this.player.currentTrack.sort &&
t.sort <= this.player.currentTrack.sort + 100 t.sort <= this.player.currentTrack.sort + 100
) )
.filter(t => loadedTrackIDs.includes(t.id) === false); .filter((t) => loadedTrackIDs.includes(t.id) === false);
let trackIDs = basicTracks.map(t => t.id); let trackIDs = basicTracks.map((t) => t.id);
if (trackIDs.length > 0) { if (trackIDs.length > 0) {
getTrackDetail(trackIDs.join(",")).then(data => { getTrackDetail(trackIDs.join(",")).then((data) => {
let newTracks = data.songs.map(t => { let newTracks = data.songs.map((t) => {
t.sort = this.player.list.find(t2 => t2.id == t.id).sort; t.sort = this.player.list.find((t2) => t2.id == t.id).sort;
return t; return t;
}); });
this.tracks.push(...newTracks); this.tracks.push(...newTracks);
}); });
} }
console.timeEnd("loadTracks"); console.timeEnd("loadTracks");
} },
}, },
activated() { activated() {
this.loadTracks(); this.loadTracks();
} },
}; };
</script> </script>

@ -13,31 +13,29 @@
<div class="artist"> <div class="artist">
Playlist by Playlist by
<span <span
style="font-weight:600" style="font-weight: 600"
v-if=" v-if="
[ [
5277771961, 5277771961,
5277965913, 5277965913,
5277969451, 5277969451,
5277778542, 5277778542,
5278068783 5278068783,
].includes(playlist.id) ].includes(playlist.id)
" "
>Apple Music</span >Apple Music</span
> >
<a <a
v-else v-else
:href=" :href="`https://music.163.com/#/user/home?id=${playlist.creator.userId}`"
`https://music.163.com/#/user/home?id=${playlist.creator.userId}`
"
target="blank" target="blank"
>{{ playlist.creator.nickname }}</a >{{ playlist.creator.nickname }}</a
> >
</div> </div>
<div class="date-and-count"> <div class="date-and-count">
{{ $t("playlist.updatedAt") }} {{ $t("playlist.updatedAt") }}
{{ playlist.updateTime | formatDate }} · {{ playlist.updateTime | formatDate }} · {{ playlist.trackCount }}
{{ playlist.trackCount }} {{ $t("common.songs") }} {{ $t("common.songs") }}
</div> </div>
<div class="description" @click="showFullDescription = true"> <div class="description" @click="showFullDescription = true">
{{ playlist.description }} {{ playlist.description }}
@ -80,7 +78,7 @@
<div class="description-full" @click.stop> <div class="description-full" @click.stop>
<span>{{ playlist.description }}</span> <span>{{ playlist.description }}</span>
<span class="close" @click="showFullDescription = false"> <span class="close" @click="showFullDescription = false">
{{ $t('modal.close') }} {{ $t("modal.close") }}
</span> </span>
</div> </div>
</div> </div>
@ -105,7 +103,7 @@ export default {
components: { components: {
Cover, Cover,
ButtonTwoTone, ButtonTwoTone,
TrackList TrackList,
}, },
data() { data() {
return { return {
@ -113,14 +111,14 @@ export default {
playlist: { playlist: {
coverImgUrl: "", coverImgUrl: "",
creator: { creator: {
userId: "" userId: "",
}, },
trackIds: [] trackIds: [],
}, },
showFullDescription: false, showFullDescription: false,
tracks: [], tracks: [],
loadingMore: false, loadingMore: false,
lastLoadedTrackIndex: 9 lastLoadedTrackIndex: 9,
}; };
}, },
created() { created() {
@ -140,23 +138,23 @@ export default {
}, },
isLikeSongsPage() { isLikeSongsPage() {
return this.$route.name === "likedSongs"; return this.$route.name === "likedSongs";
} },
}, },
methods: { methods: {
...mapMutations(["appendTrackToPlayerList"]), ...mapMutations(["appendTrackToPlayerList"]),
...mapActions(["playFirstTrackOnList", "playTrackOnListByID"]), ...mapActions(["playFirstTrackOnList", "playTrackOnListByID"]),
playPlaylistByID(trackID = "first") { playPlaylistByID(trackID = "first") {
let trackIDs = this.playlist.trackIds.map(t => t.id); let trackIDs = this.playlist.trackIds.map((t) => t.id);
playAList(trackIDs, this.playlist.id, "playlist", trackID); playAList(trackIDs, this.playlist.id, "playlist", trackID);
}, },
likePlaylist() { likePlaylist() {
subscribePlaylist({ subscribePlaylist({
id: this.playlist.id, id: this.playlist.id,
t: this.playlist.subscribed ? 2 : 1 t: this.playlist.subscribed ? 2 : 1,
}).then(data => { }).then((data) => {
if (data.code === 200) if (data.code === 200)
this.playlist.subscribed = !this.playlist.subscribed; this.playlist.subscribed = !this.playlist.subscribed;
getPlaylistDetail(this.id, true).then(data => { getPlaylistDetail(this.id, true).then((data) => {
this.playlist = data.playlist; this.playlist = data.playlist;
}); });
}); });
@ -164,7 +162,7 @@ export default {
loadData(id, next = undefined) { loadData(id, next = undefined) {
this.id = id; this.id = id;
getPlaylistDetail(this.id, true) getPlaylistDetail(this.id, true)
.then(data => { .then((data) => {
this.playlist = data.playlist; this.playlist = data.playlist;
this.tracks = data.playlist.tracks; this.tracks = data.playlist.tracks;
NProgress.done(); NProgress.done();
@ -191,8 +189,8 @@ export default {
) )
return t; return t;
}); });
trackIDs = trackIDs.map(t => t.id); trackIDs = trackIDs.map((t) => t.id);
getTrackDetail(trackIDs.join(",")).then(data => { getTrackDetail(trackIDs.join(",")).then((data) => {
this.tracks.push(...data.songs); this.tracks.push(...data.songs);
this.lastLoadedTrackIndex += trackIDs.length; this.lastLoadedTrackIndex += trackIDs.length;
this.loadingMore = false; this.loadingMore = false;
@ -213,8 +211,8 @@ export default {
this.loadingMore = true; this.loadingMore = true;
this.loadMore(); this.loadMore();
} }
} },
} },
}; };
</script> </script>

@ -132,7 +132,7 @@ export default {
components: { components: {
Cover, Cover,
TrackList, TrackList,
MvRow MvRow,
}, },
data() { data() {
return { return {
@ -141,7 +141,7 @@ export default {
mvs: [], mvs: [],
type: 1, type: 1,
limit: 30, limit: 30,
offset: 0 offset: 0,
}; };
}, },
computed: { computed: {
@ -155,26 +155,26 @@ export default {
}, },
isExistResult() { isExistResult() {
return Object.keys(this.result).length; return Object.keys(this.result).length;
} },
}, },
methods: { methods: {
goToAlbum(id) { goToAlbum(id) {
this.$router.push({ name: "album", params: { id } }); this.$router.push({ name: "album", params: { id } });
}, },
playTrackInSearchResult(id) { playTrackInSearchResult(id) {
let track = this.tracks.find(t => t.id === id); let track = this.tracks.find((t) => t.id === id);
appendTrackToPlayerList(track, true); appendTrackToPlayerList(track, true);
}, },
getData(keywords) { getData(keywords) {
search({ keywords: keywords, type: 1018 }).then(data => { search({ keywords: keywords, type: 1018 }).then((data) => {
this.result = data.result; this.result = data.result;
NProgress.done(); NProgress.done();
this.show = true; this.show = true;
}); });
search({ keywords: keywords, type: 1004 }).then(data => { search({ keywords: keywords, type: 1004 }).then((data) => {
this.mvs = data.result.mvs; this.mvs = data.result.mvs;
}); });
} },
}, },
created() { created() {
this.getData(this.$route.query.keywords); this.getData(this.$route.query.keywords);
@ -184,7 +184,7 @@ export default {
next(); next();
NProgress.start(); NProgress.start();
this.getData(to.query.keywords); this.getData(to.query.keywords);
} },
}; };
</script> </script>

@ -31,10 +31,7 @@ module.exports = {
}, },
chainWebpack(config) { chainWebpack(config) {
config.module.rules.delete("svg"); config.module.rules.delete("svg");
config.module config.module.rule("svg").exclude.add(resolve("src/assets/icons")).end();
.rule("svg")
.exclude.add(resolve("src/assets/icons"))
.end();
config.module config.module
.rule("icons") .rule("icons")
.test(/\.svg$/) .test(/\.svg$/)

@ -1115,6 +1115,11 @@
resolved "https://registry.npm.taobao.org/@types/normalize-package-data/download/@types/normalize-package-data-2.4.0.tgz?cache=0&sync_timestamp=1596839391651&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fnormalize-package-data%2Fdownload%2F%40types%2Fnormalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" resolved "https://registry.npm.taobao.org/@types/normalize-package-data/download/@types/normalize-package-data-2.4.0.tgz?cache=0&sync_timestamp=1596839391651&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fnormalize-package-data%2Fdownload%2F%40types%2Fnormalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e"
integrity sha1-5IbQ2XOW15vu3QpuM/RTT/a0lz4= integrity sha1-5IbQ2XOW15vu3QpuM/RTT/a0lz4=
"@types/parse-json@^4.0.0":
version "4.0.0"
resolved "https://registry.npm.taobao.org/@types/parse-json/download/@types/parse-json-4.0.0.tgz?cache=0&sync_timestamp=1596839394119&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fparse-json%2Fdownload%2F%40types%2Fparse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0"
integrity sha1-L4u0QUNNFjs1+4/9zNcTiSf/uMA=
"@types/q@^1.5.1": "@types/q@^1.5.1":
version "1.5.4" version "1.5.4"
resolved "https://registry.npm.taobao.org/@types/q/download/@types/q-1.5.4.tgz#15925414e0ad2cd765bfef58842f7e26a7accb24" resolved "https://registry.npm.taobao.org/@types/q/download/@types/q-1.5.4.tgz#15925414e0ad2cd765bfef58842f7e26a7accb24"
@ -2411,7 +2416,7 @@ chalk@^3.0.0:
ansi-styles "^4.1.0" ansi-styles "^4.1.0"
supports-color "^7.1.0" supports-color "^7.1.0"
chalk@^4.1.0: chalk@^4.0.0, chalk@^4.1.0:
version "4.1.0" version "4.1.0"
resolved "https://registry.npm.taobao.org/chalk/download/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" resolved "https://registry.npm.taobao.org/chalk/download/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a"
integrity sha1-ThSHCmGNni7dl92DRf2dncMVZGo= integrity sha1-ThSHCmGNni7dl92DRf2dncMVZGo=
@ -2480,6 +2485,11 @@ ci-info@^1.5.0:
resolved "https://registry.npm.taobao.org/ci-info/download/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" resolved "https://registry.npm.taobao.org/ci-info/download/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497"
integrity sha1-LKINu5zrMtRSSmgzAzE/AwSx5Jc= integrity sha1-LKINu5zrMtRSSmgzAzE/AwSx5Jc=
ci-info@^2.0.0:
version "2.0.0"
resolved "https://registry.npm.taobao.org/ci-info/download/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46"
integrity sha1-Z6npZL4xpR4V5QENWObxKDQAL0Y=
cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3:
version "1.0.4" version "1.0.4"
resolved "https://registry.npm.taobao.org/cipher-base/download/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" resolved "https://registry.npm.taobao.org/cipher-base/download/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de"
@ -2677,6 +2687,11 @@ commondir@^1.0.1:
resolved "https://registry.npm.taobao.org/commondir/download/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" resolved "https://registry.npm.taobao.org/commondir/download/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=
compare-versions@^3.6.0:
version "3.6.0"
resolved "https://registry.npm.taobao.org/compare-versions/download/compare-versions-3.6.0.tgz#1a5689913685e5a87637b8d3ffca75514ec41d62"
integrity sha1-GlaJkTaF5ah2N7jT/8p1UU7EHWI=
component-emitter@^1.2.1: component-emitter@^1.2.1:
version "1.3.0" version "1.3.0"
resolved "https://registry.npm.taobao.org/component-emitter/download/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" resolved "https://registry.npm.taobao.org/component-emitter/download/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0"
@ -2836,6 +2851,17 @@ cosmiconfig@^5.0.0:
js-yaml "^3.13.1" js-yaml "^3.13.1"
parse-json "^4.0.0" parse-json "^4.0.0"
cosmiconfig@^7.0.0:
version "7.0.0"
resolved "https://registry.npm.taobao.org/cosmiconfig/download/cosmiconfig-7.0.0.tgz?cache=0&sync_timestamp=1596310819353&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcosmiconfig%2Fdownload%2Fcosmiconfig-7.0.0.tgz#ef9b44d773959cae63ddecd122de23853b60f8d3"
integrity sha1-75tE13OVnK5j3ezRIt4jhTtg+NM=
dependencies:
"@types/parse-json" "^4.0.0"
import-fresh "^3.2.1"
parse-json "^5.0.0"
path-type "^4.0.0"
yaml "^1.10.0"
create-ecdh@^4.0.0: create-ecdh@^4.0.0:
version "4.0.4" version "4.0.4"
resolved "https://registry.npm.taobao.org/create-ecdh/download/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" resolved "https://registry.npm.taobao.org/create-ecdh/download/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e"
@ -4034,6 +4060,13 @@ find-up@^4.0.0, find-up@^4.1.0:
locate-path "^5.0.0" locate-path "^5.0.0"
path-exists "^4.0.0" path-exists "^4.0.0"
find-versions@^3.2.0:
version "3.2.0"
resolved "https://registry.npm.taobao.org/find-versions/download/find-versions-3.2.0.tgz#10297f98030a786829681690545ef659ed1d254e"
integrity sha1-ECl/mAMKeGgpaBaQVF72We0dJU4=
dependencies:
semver-regex "^2.0.0"
flat-cache@^2.0.1: flat-cache@^2.0.1:
version "2.0.1" version "2.0.1"
resolved "https://registry.npm.taobao.org/flat-cache/download/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" resolved "https://registry.npm.taobao.org/flat-cache/download/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0"
@ -4615,6 +4648,22 @@ human-signals@^1.1.1:
resolved "https://registry.npm.taobao.org/human-signals/download/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" resolved "https://registry.npm.taobao.org/human-signals/download/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3"
integrity sha1-xbHNFPUK6uCatsWf5jujOV/k36M= integrity sha1-xbHNFPUK6uCatsWf5jujOV/k36M=
husky@^4.3.0:
version "4.3.0"
resolved "https://registry.npm.taobao.org/husky/download/husky-4.3.0.tgz?cache=0&sync_timestamp=1602813564105&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhusky%2Fdownload%2Fhusky-4.3.0.tgz#0b2ec1d66424e9219d359e26a51c58ec5278f0de"
integrity sha1-Cy7B1mQk6SGdNZ4mpRxY7FJ48N4=
dependencies:
chalk "^4.0.0"
ci-info "^2.0.0"
compare-versions "^3.6.0"
cosmiconfig "^7.0.0"
find-versions "^3.2.0"
opencollective-postinstall "^2.0.2"
pkg-dir "^4.2.0"
please-upgrade-node "^3.2.0"
slash "^3.0.0"
which-pm-runs "^1.0.0"
iconv-lite@0.4.24, iconv-lite@^0.4.24: iconv-lite@0.4.24, iconv-lite@^0.4.24:
version "0.4.24" version "0.4.24"
resolved "https://registry.npm.taobao.org/iconv-lite/download/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" resolved "https://registry.npm.taobao.org/iconv-lite/download/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
@ -4674,7 +4723,7 @@ import-fresh@^2.0.0:
caller-path "^2.0.0" caller-path "^2.0.0"
resolve-from "^3.0.0" resolve-from "^3.0.0"
import-fresh@^3.0.0: import-fresh@^3.0.0, import-fresh@^3.2.1:
version "3.2.1" version "3.2.1"
resolved "https://registry.npm.taobao.org/import-fresh/download/import-fresh-3.2.1.tgz?cache=0&sync_timestamp=1589682760620&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fimport-fresh%2Fdownload%2Fimport-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" resolved "https://registry.npm.taobao.org/import-fresh/download/import-fresh-3.2.1.tgz?cache=0&sync_timestamp=1589682760620&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fimport-fresh%2Fdownload%2Fimport-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66"
integrity sha1-Yz/2GFBueTr1rJG/SLcmd+FcvmY= integrity sha1-Yz/2GFBueTr1rJG/SLcmd+FcvmY=
@ -6129,6 +6178,11 @@ open@^6.3.0:
dependencies: dependencies:
is-wsl "^1.1.0" is-wsl "^1.1.0"
opencollective-postinstall@^2.0.2:
version "2.0.3"
resolved "https://registry.npm.taobao.org/opencollective-postinstall/download/opencollective-postinstall-2.0.3.tgz#7a0fff978f6dbfa4d006238fbac98ed4198c3259"
integrity sha1-eg//l49tv6TQBiOPusmO1BmMMlk=
opener@^1.5.1: opener@^1.5.1:
version "1.5.2" version "1.5.2"
resolved "https://registry.npm.taobao.org/opener/download/opener-1.5.2.tgz?cache=0&sync_timestamp=1598733244715&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fopener%2Fdownload%2Fopener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598" resolved "https://registry.npm.taobao.org/opener/download/opener-1.5.2.tgz?cache=0&sync_timestamp=1598733244715&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fopener%2Fdownload%2Fopener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598"
@ -6380,6 +6434,11 @@ path-type@^3.0.0:
dependencies: dependencies:
pify "^3.0.0" pify "^3.0.0"
path-type@^4.0.0:
version "4.0.0"
resolved "https://registry.npm.taobao.org/path-type/download/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
integrity sha1-hO0BwKe6OAr+CdkKjBgNzZ0DBDs=
pbkdf2@^3.0.3: pbkdf2@^3.0.3:
version "3.1.1" version "3.1.1"
resolved "https://registry.npm.taobao.org/pbkdf2/download/pbkdf2-3.1.1.tgz#cb8724b0fada984596856d1a6ebafd3584654b94" resolved "https://registry.npm.taobao.org/pbkdf2/download/pbkdf2-3.1.1.tgz#cb8724b0fada984596856d1a6ebafd3584654b94"
@ -6442,13 +6501,20 @@ pkg-dir@^3.0.0:
dependencies: dependencies:
find-up "^3.0.0" find-up "^3.0.0"
pkg-dir@^4.1.0: pkg-dir@^4.1.0, pkg-dir@^4.2.0:
version "4.2.0" version "4.2.0"
resolved "https://registry.npm.taobao.org/pkg-dir/download/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" resolved "https://registry.npm.taobao.org/pkg-dir/download/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3"
integrity sha1-8JkTPfft5CLoHR2ESCcO6z5CYfM= integrity sha1-8JkTPfft5CLoHR2ESCcO6z5CYfM=
dependencies: dependencies:
find-up "^4.0.0" find-up "^4.0.0"
please-upgrade-node@^3.2.0:
version "3.2.0"
resolved "https://registry.npm.taobao.org/please-upgrade-node/download/please-upgrade-node-3.2.0.tgz#aeddd3f994c933e4ad98b99d9a556efa0e2fe942"
integrity sha1-rt3T+ZTJM+StmLmdmlVu+g4v6UI=
dependencies:
semver-compare "^1.0.0"
plyr@^3.6.2: plyr@^3.6.2:
version "3.6.2" version "3.6.2"
resolved "https://registry.yarnpkg.com/plyr/-/plyr-3.6.2.tgz#5a55b608acd161262de1cc75ca843aa64355a051" resolved "https://registry.yarnpkg.com/plyr/-/plyr-3.6.2.tgz#5a55b608acd161262de1cc75ca843aa64355a051"
@ -6882,6 +6948,11 @@ prepend-http@^1.0.0:
resolved "https://registry.npm.taobao.org/prepend-http/download/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" resolved "https://registry.npm.taobao.org/prepend-http/download/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc"
integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=
prettier@2.1.2:
version "2.1.2"
resolved "https://registry.npm.taobao.org/prettier/download/prettier-2.1.2.tgz?cache=0&sync_timestamp=1600215482255&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fprettier%2Fdownload%2Fprettier-2.1.2.tgz#3050700dae2e4c8b67c4c3f666cdb8af405e1ce5"
integrity sha1-MFBwDa4uTItnxMP2Zs24r0BeHOU=
prettier@^1.18.2: prettier@^1.18.2:
version "1.19.1" version "1.19.1"
resolved "https://registry.npm.taobao.org/prettier/download/prettier-1.19.1.tgz?cache=0&sync_timestamp=1600215482255&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fprettier%2Fdownload%2Fprettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" resolved "https://registry.npm.taobao.org/prettier/download/prettier-1.19.1.tgz?cache=0&sync_timestamp=1600215482255&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fprettier%2Fdownload%2Fprettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb"
@ -7448,6 +7519,16 @@ selfsigned@^1.10.7:
dependencies: dependencies:
node-forge "^0.10.0" node-forge "^0.10.0"
semver-compare@^1.0.0:
version "1.0.0"
resolved "https://registry.npm.taobao.org/semver-compare/download/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc"
integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w=
semver-regex@^2.0.0:
version "2.0.0"
resolved "https://registry.npm.taobao.org/semver-regex/download/semver-regex-2.0.0.tgz#a93c2c5844539a770233379107b38c7b4ac9d338"
integrity sha1-qTwsWERTmncCMzeRB7OMe0rJ0zg=
"semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0: "semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0:
version "5.7.1" version "5.7.1"
resolved "https://registry.npm.taobao.org/semver/download/semver-5.7.1.tgz?cache=0&sync_timestamp=1589682805026&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsemver%2Fdownload%2Fsemver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" resolved "https://registry.npm.taobao.org/semver/download/semver-5.7.1.tgz?cache=0&sync_timestamp=1589682805026&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsemver%2Fdownload%2Fsemver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
@ -7606,6 +7687,11 @@ slash@^2.0.0:
resolved "https://registry.npm.taobao.org/slash/download/slash-2.0.0.tgz?cache=0&sync_timestamp=1589682715547&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fslash%2Fdownload%2Fslash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" resolved "https://registry.npm.taobao.org/slash/download/slash-2.0.0.tgz?cache=0&sync_timestamp=1589682715547&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fslash%2Fdownload%2Fslash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44"
integrity sha1-3lUoUaF1nfOo8gZTVEL17E3eq0Q= integrity sha1-3lUoUaF1nfOo8gZTVEL17E3eq0Q=
slash@^3.0.0:
version "3.0.0"
resolved "https://registry.npm.taobao.org/slash/download/slash-3.0.0.tgz?cache=0&sync_timestamp=1589682715547&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fslash%2Fdownload%2Fslash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
integrity sha1-ZTm+hwwWWtvVJAIg2+Nh8bxNRjQ=
slice-ansi@^2.1.0: slice-ansi@^2.1.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.npm.taobao.org/slice-ansi/download/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" resolved "https://registry.npm.taobao.org/slice-ansi/download/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636"
@ -8898,6 +8984,11 @@ which-module@^2.0.0:
resolved "https://registry.npm.taobao.org/which-module/download/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" resolved "https://registry.npm.taobao.org/which-module/download/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"
integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=
which-pm-runs@^1.0.0:
version "1.0.0"
resolved "https://registry.npm.taobao.org/which-pm-runs/download/which-pm-runs-1.0.0.tgz#670b3afbc552e0b55df6b7780ca74615f23ad1cb"
integrity sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=
which@^1.2.9: which@^1.2.9:
version "1.3.1" version "1.3.1"
resolved "https://registry.npm.taobao.org/which/download/which-1.3.1.tgz?cache=0&sync_timestamp=1589682812246&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwhich%2Fdownload%2Fwhich-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" resolved "https://registry.npm.taobao.org/which/download/which-1.3.1.tgz?cache=0&sync_timestamp=1589682812246&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwhich%2Fdownload%2Fwhich-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
@ -9121,6 +9212,11 @@ yallist@^4.0.0:
resolved "https://registry.npm.taobao.org/yallist/download/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" resolved "https://registry.npm.taobao.org/yallist/download/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
integrity sha1-m7knkNnA7/7GO+c1GeEaNQGaOnI= integrity sha1-m7knkNnA7/7GO+c1GeEaNQGaOnI=
yaml@^1.10.0:
version "1.10.0"
resolved "https://registry.npm.taobao.org/yaml/download/yaml-1.10.0.tgz#3b593add944876077d4d683fee01081bd9fff31e"
integrity sha1-O1k63ZRIdgd9TWg/7gEIG9n/8x4=
yargs-parser@^13.1.2: yargs-parser@^13.1.2:
version "13.1.2" version "13.1.2"
resolved "https://registry.npm.taobao.org/yargs-parser/download/yargs-parser-13.1.2.tgz?cache=0&sync_timestamp=1600655138204&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fyargs-parser%2Fdownload%2Fyargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" resolved "https://registry.npm.taobao.org/yargs-parser/download/yargs-parser-13.1.2.tgz?cache=0&sync_timestamp=1600655138204&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fyargs-parser%2Fdownload%2Fyargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38"

Loading…
Cancel
Save