From 11eb29b3b8fc471ca47fc5dd6830d7b2056d1ffc Mon Sep 17 00:00:00 2001 From: qier222 Date: Sat, 6 Mar 2021 17:09:08 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20personal=20FM=20(finally=F0=9F=8E=89)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/others.js | 21 +++++ src/assets/icons/fm.svg | 1 + src/assets/icons/lyrics.svg | 1 + src/assets/icons/thumbs-down.svg | 1 + src/components/FMCard.vue | 143 +++++++++++++++++++++++++++++++ src/components/Player.vue | 48 ++++++++--- src/utils/Player.js | 48 ++++++++++- src/views/home.vue | 18 +++- src/views/lyrics.vue | 15 +++- 9 files changed, 280 insertions(+), 16 deletions(-) create mode 100644 src/assets/icons/fm.svg create mode 100644 src/assets/icons/lyrics.svg create mode 100644 src/assets/icons/thumbs-down.svg create mode 100644 src/components/FMCard.vue diff --git a/src/api/others.js b/src/api/others.js index d1027c1..020188c 100644 --- a/src/api/others.js +++ b/src/api/others.js @@ -27,3 +27,24 @@ export function search(params) { return data; }); } + +export function personalFM() { + return request({ + url: "/personal_fm", + method: "get", + params: { + timestamp: new Date().getTime(), + }, + }); +} + +export function fmTrash(id) { + return request({ + url: "/fm_trash", + method: "post", + params: { + timestamp: new Date().getTime(), + id, + }, + }); +} diff --git a/src/assets/icons/fm.svg b/src/assets/icons/fm.svg new file mode 100644 index 0000000..fe760cd --- /dev/null +++ b/src/assets/icons/fm.svg @@ -0,0 +1 @@ + diff --git a/src/assets/icons/lyrics.svg b/src/assets/icons/lyrics.svg new file mode 100644 index 0000000..0b7021a --- /dev/null +++ b/src/assets/icons/lyrics.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/thumbs-down.svg b/src/assets/icons/thumbs-down.svg new file mode 100644 index 0000000..02fe63b --- /dev/null +++ b/src/assets/icons/thumbs-down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/FMCard.vue b/src/components/FMCard.vue new file mode 100644 index 0000000..96fb717 --- /dev/null +++ b/src/components/FMCard.vue @@ -0,0 +1,143 @@ + + + + + diff --git a/src/components/Player.vue b/src/components/Player.vue index 2d6d9d5..d2c7750 100644 --- a/src/components/Player.vue +++ b/src/components/Player.vue @@ -62,9 +62,18 @@
- + @@ -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; + } +} diff --git a/src/utils/Player.js b/src/utils/Player.js index b3ca6a1..bc32d21 100644 --- a/src/utils/Player.js +++ b/src/utils/Player.js @@ -6,6 +6,7 @@ import { cacheTrack } from "@/utils/db"; import { getAlbum } from "@/api/album"; import { getPlaylistDetail } from "@/api/playlist"; import { getArtist } from "@/api/artist"; +import { personalFM, fmTrash } from "@/api/others"; import store from "@/store"; import { isAccountLoggedIn } from "@/utils/auth"; @@ -29,6 +30,8 @@ export default class { this._currentTrack = { id: 86827685 }; this._playNextList = []; // 当这个list不为空时,会优先播放这个list的歌 this._playing = false; + this._isPersonalFM = false; + this._personalFMTrack = { id: 0 }; this._howler = null; Object.defineProperty(this, "_howler", { @@ -99,6 +102,12 @@ export default class { get playNextList() { return this._playNextList; } + get isPersonalFM() { + return this._isPersonalFM; + } + get personalFMTrack() { + return this._personalFMTrack; + } _init() { Howler.autoUnlock = false; @@ -115,6 +124,7 @@ export default class { }); // update audio source and init howler this._initMediaSession(); Howler.volume(this.volume); + this._loadPersonalFMTrack(); } _getNextTrack() { // 返回 [trackID, index] @@ -288,6 +298,12 @@ export default class { this.playNextTrack(); } } + _loadPersonalFMTrack() { + return personalFM().then((result) => { + this._personalFMTrack = result.data[0]; + return this._personalFMTrack; + }); + } currentTrackID() { const { list, current } = this._getListAndCurrent(); @@ -296,11 +312,19 @@ export default class { appendTrack(trackID) { this.list.append(trackID); } - playNextTrack() { + playNextTrack(isFM = false) { + if (this._isPersonalFM || isFM) { + this._isPersonalFM = true; + this._loadPersonalFMTrack().then(() => { + this._replaceCurrentTrack(this._personalFMTrack.id); + }); + return true; + } // TODO: 切换歌曲时增加加载中的状态 const [trackID, index] = this._getNextTrack(); if (trackID === undefined) { this._howler.stop(); + this._playing = false; return false; } this.current = index; @@ -330,10 +354,18 @@ export default class { document.title = "YesPlayMusic"; } play() { + if (this._howler.playing()) return; this._howler.play(); this._playing = true; document.title = `${this._currentTrack.name} · ${this._currentTrack.ar[0].name} - YesPlayMusic`; } + playOrPause() { + if (this._howler.playing()) { + this.pause(); + } else { + this.play(); + } + } seek(time = null) { if (time !== null) this._howler.seek(time); return this._howler === null ? 0 : this._howler.seek(); @@ -357,6 +389,7 @@ export default class { playlistSourceType, autoPlayTrackID = "first" ) { + this._isPersonalFM = false; if (!this._enabled) this._enabled = true; this.list = trackIDs; this.current = 0; @@ -394,6 +427,19 @@ export default class { this._playNextList.push(trackID); if (playNow) this.playNextTrack(); } + playPersonalFM() { + this._isPersonalFM = true; + if (!this._enabled) this._enabled = true; + if (this._currentTrack.id !== this._personalFMTrack.id) { + this._replaceCurrentTrack(this._personalFMTrack.id); + } + this.playOrPause(); + } + moveToFMTrash() { + this._isPersonalFM = true; + this.playNextTrack(); + fmTrash(this._personalFMTrack.id); + } sendSelfToIpcMain() { if (process.env.IS_ELECTRON !== true) return false; diff --git a/src/views/home.vue b/src/views/home.vue index fd719b9..c7b98cb 100644 --- a/src/views/home.vue +++ b/src/views/home.vue @@ -22,6 +22,13 @@ :subText="'copywriter'" />
+
+
For You
+
+ +
+
+
{{ $t("home.recommendArtist") }}
diff --git a/src/views/lyrics.vue b/src/views/lyrics.vue index 2d26f90..c0bed52 100644 --- a/src/views/lyrics.vue +++ b/src/views/lyrics.vue @@ -72,6 +72,7 @@
+
${line.contents[0]}`; } }, + moveToFMTrash() { + this.player.moveToFMTrash(); + }, }, watch: { currentTrack() { @@ -470,7 +483,7 @@ $layoutBreakpoint: 1000px; button { margin: 0 8px; } - button:nth-child(2) .svg-icon { + button#play .svg-icon { height: 28px; width: 28px; padding: 2px;