feat: personal FM (finally🎉)

This commit is contained in:
qier222 2021-03-06 17:09:08 +08:00
parent e169ee19e2
commit 11eb29b3b8
No known key found for this signature in database
GPG key ID: 9C85007ED905F14D
9 changed files with 280 additions and 16 deletions

143
src/components/FMCard.vue Normal file
View file

@ -0,0 +1,143 @@
<template>
<div class="fm">
<img
class="cover"
:src="track.album && track.album.picUrl | resizeImage(512)"
@click="goToAlbum"
/>
<div class="right-part">
<div class="info">
<div class="title">{{ track.name }}</div>
<div class="artist"><ArtistsInLine :artists="track.artists" /></div>
</div>
<div class="controls">
<div class="buttons">
<button-icon @click.native="moveToFMTrash" title="不喜欢"
><svg-icon icon-class="thumbs-down" id="thumbs-down"
/></button-icon>
<button-icon
class="play"
@click.native="play"
:title="$t(isPlaying ? 'player.pause' : 'player.play')"
>
<svg-icon :iconClass="isPlaying ? 'pause' : 'play'"
/></button-icon>
<button-icon @click.native="next" :title="$t('player.next')"
><svg-icon icon-class="next" /></button-icon
></div>
<div class="card-name"><svg-icon icon-class="fm" />私人FM</div>
</div>
</div>
</div>
</template>
<script>
import ButtonIcon from "@/components/ButtonIcon.vue";
import ArtistsInLine from "@/components/ArtistsInLine.vue";
import { mapState } from "vuex";
export default {
name: "FMCard",
components: { ButtonIcon, ArtistsInLine },
computed: {
...mapState(["player"]),
track() {
return this.player.personalFMTrack;
},
isPlaying() {
return this.player.playing && this.player.isPersonalFM;
},
},
methods: {
play() {
this.player.playPersonalFM();
},
next() {
this.player.playNextTrack(true);
},
goToAlbum() {
if (this.track.album.id === 0) return;
this.$router.push({ path: "/album/" + this.track.album.id });
},
moveToFMTrash() {
this.player.moveToFMTrash();
},
},
};
</script>
<style lang="scss" scoped>
.fm {
padding: 1rem;
background: var(--color-secondary-bg);
border-radius: 1rem;
display: flex;
}
.cover {
height: 164px;
clip-path: border-box;
border-radius: 0.75rem;
margin-right: 1.2rem;
border: 1px solid rgb(243, 243, 243);
cursor: pointer;
user-select: none;
}
.right-part {
display: flex;
flex-direction: column;
justify-content: space-between;
color: var(--color-text);
width: 100%;
.title {
font-size: 1.6rem;
font-weight: 600;
margin-bottom: 0.6rem;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
word-break: break-all;
}
.artist {
opacity: 0.68;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
word-break: break-all;
}
.controls {
display: flex;
justify-content: space-between;
align-items: baseline;
margin-left: -0.4rem;
.buttons {
display: flex;
}
.button-icon {
margin: 0 8px 0 0;
}
.svg-icon {
width: 24px;
height: 24px;
}
.svg-icon#thumbs-down {
width: 22px;
height: 22px;
}
.card-name {
font-size: 1rem;
opacity: 0.18;
display: flex;
align-items: center;
font-weight: 600;
user-select: none;
.svg-icon {
width: 18px;
height: 18px;
margin-right: 6px;
}
}
}
}
</style>

View file

@ -62,9 +62,18 @@
<div class="middle-control-buttons">
<div class="blank"></div>
<div class="container" @click.stop>
<button-icon @click.native="previous" :title="$t('player.previous')"
<button-icon
v-show="!player.isPersonalFM"
@click.native="previous"
:title="$t('player.previous')"
><svg-icon icon-class="previous"
/></button-icon>
<button-icon
v-show="player.isPersonalFM"
@click.native="moveToFMTrash"
title="不喜欢"
><svg-icon icon-class="thumbs-down"
/></button-icon>
<button-icon
class="play"
@click.native="play"
@ -84,7 +93,10 @@
<button-icon
@click.native="goToNextTracksPage"
:title="$t('player.nextUp')"
:class="{ active: this.$route.name === 'next' }"
:class="{
active: this.$route.name === 'next',
disabled: player.isPersonalFM,
}"
><svg-icon icon-class="list"
/></button-icon>
<button-icon
@ -94,7 +106,10 @@
: $t('player.repeat')
"
@click.native="repeat"
:class="{ active: player.repeatMode !== 'off' }"
:class="{
active: player.repeatMode !== 'off',
disabled: player.isPersonalFM,
}"
>
<svg-icon
icon-class="repeat"
@ -107,7 +122,7 @@
</button-icon>
<button-icon
@click.native="shuffle"
:class="{ active: player.shuffle }"
:class="{ active: player.shuffle, disabled: player.isPersonalFM }"
:title="$t('player.shuffle')"
><svg-icon icon-class="shuffle"
/></button-icon>
@ -221,9 +236,11 @@ export default {
if (this.player.playPrevTrack()) this.progress = 0;
},
shuffle() {
if (this.player.isPersonalFM) return;
this.player.shuffle = !this.player.shuffle;
},
repeat() {
if (this.player.isPersonalFM) return;
if (this.player.repeatMode === "on") {
this.player.repeatMode = "one";
} else if (this.player.repeatMode === "one") {
@ -240,6 +257,7 @@ export default {
this.progress = value;
},
goToNextTracksPage() {
if (this.player.isPersonalFM) return;
this.$route.name === "next"
? this.$router.go(-1)
: this.$router.push({ name: "next" });
@ -268,6 +286,9 @@ export default {
}
});
},
moveToFMTrash() {
this.player.moveToFMTrash();
},
goToList() {
if (this.player.playlistSource.id === this.data.likedSongPlaylistID)
this.$router.push({ path: "/library/liked-songs" });
@ -351,6 +372,7 @@ export default {
border-radius: 5px;
box-shadow: 0 6px 8px -2px rgba(0, 0, 0, 0.16);
cursor: pointer;
user-select: none;
}
.track-info {
height: 46px;
@ -448,12 +470,14 @@ export default {
margin-left: 16px;
}
// .lyrics-button {
// position: fixed;
// right: 18px;
// .svg-icon {
// height: 20px;
// width: 20px;
// }
// }
.button-icon.disabled {
cursor: default;
opacity: 0.38;
&:hover {
background: none;
}
&:active {
transform: unset;
}
}
</style>