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'"
/>
+
{{ $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;