From b394ec0899cbf9f7f7d09e26eb5d05e8ff31e536 Mon Sep 17 00:00:00 2001 From: njzy <njzydark@gmail.com> Date: Wed, 9 Dec 2020 19:50:50 +0800 Subject: [PATCH 1/3] refactor: hide window when close app (#78) fix: window can't be close by shortcutkey fix: tray does not show in Windows --- build/icons/menu@88.png | Bin 0 -> 1084 bytes src/background.js | 29 +++++++++++++++++++++++++---- src/electron/ipcMain.js | 5 +++-- src/electron/menu.js | 1 + src/electron/tray.js | 16 +++++++++++++++- 5 files changed, 44 insertions(+), 7 deletions(-) create mode 100644 build/icons/menu@88.png diff --git a/build/icons/menu@88.png b/build/icons/menu@88.png new file mode 100644 index 0000000000000000000000000000000000000000..cc14a82d1a3de3faff2aaea28d180e0885c8780a GIT binary patch literal 1084 zcmV-C1jGA@P)<h;3K|Lk000e1NJLTq003A3003AB1^@s6ag{JM00009a7bBm000XU z000XU0RWnu7ytkO0drDELIAGL9O(c600d`2O+f$vv5yP<VFdsH1JOxDK~#7F?VS5j z6hRQizq9-w$Y9R|ga|xLKqUdrOF%RLgalL)kRt*#0X-71h(MMIzzEjv+F6}iEURZ< z^Xgw!*B;c~9sAMy?M%-DP!vT`6h%=KMH!eGMxv^!f)3jh&CzCyVh7W5NAaumyRtdX zX0s9_Fqpt3D2w=pVnMNshoZ*7hT@81J(l3kaHdjRR_SqG)pwy+aSti(s&wINJ46p2 zp(FIg@9D5coK_%(uWfCvbvpP9tNiFBvhzcZzGz8@bL7dA9)1@tZ*UU0s!jhp>ZVtY z+*8a+<a_BGTs`;%`HIW1Cp%e%ID<|0-auh?q*?5e!3!u2OX-O&0>6OLu#leUB5(nv z;i>dQ7Z0wW{DC}Jq@5^(E8l(c0Fi1UwTJ>r8&Qd%b1gzqfrCIQ@R${|4aGji+#J6k z4z?sGJ%)_21m>ZdefwvMjVUN`m$X2*h=#m;Tg2JFeo3P9kPT<_DI&+W!2j*flgKBi zt;4BA7!tuh<aqFrVo5Jw<L@YNG(^*iXxWCi9_yRvnrX&1_7I6}MA;6uY=ea^5in7A zG)UxYV;jNxa}qr{_Gi?cl;CV5nXa;B8=TQ40wK9tgb_Lz+eo(9W7)<TJd$)Z&1CZt zYTNKqM9QLEX@q`7FW+KfvZ@D@$e%EA0V&6V`=nNpqrj6+x0M#$qsPoT;Gy;<CM1gt zHsbOK#0QFAGuB;6I)kmOT~K_6haspW1-2$3ar>8rUBDB`S%hT=Clo*7c~)pL8Qgk^ zvDXH%I4AlHW??B<Sgt#KLv0DctbB?(gDpEarZ_@?L@BUk2fTEbC#VFwRxc`nTg|Rx zM6j$O8i6f4_=t%+3w;P)U@L3c3fK~&TDlvoz#;U)hQPPLycGiM<qjeB!iK<iJD6|z zxoOL`dtpD2z}h@%29GrtjQx~52RzDfi+Xt!i(VjnO36vS1!f8)yn0{PXpD?h;Ap0c zPRO8(!Byagh&0iqv>h3ADXpP|(r_(3(M8}ZC=IvL6I}$}Kxw#?p6KGi+$rEKWm4WJ zO+rbrH~5w^<^#P>1r3A?mtCjC8O)e0<{H5qd2&PIK5==2Q%}zP=MGSB6`LE}OnnYV zoV&`rvWE`u%opYYU+b#Nmbaa15oUV+3VCEQU*pPLvolT}+{Wx%!{x@J?`H)Hx0(*j zUE7IX)ig6TpG|*d{+JYOgRg<J_LQ%!kGRaBSw|WDk`B*M7tVJPPn)?!UA*Dm>Q@qV zgMk?Rwzjsv+D15nm(7b=D0{UlilQirq9}@@Ncjziaia>bFNlf&0000<MNUMnLSTYc CN$Z~g literal 0 HcmV?d00001 diff --git a/src/background.js b/src/background.js index 4a84b61..b3649e7 100644 --- a/src/background.js +++ b/src/background.js @@ -17,6 +17,10 @@ const isDevelopment = process.env.NODE_ENV !== "production"; // Keep a global reference of the window object, if you don't, the window will // be closed automatically when the JavaScript object is garbage collected. let win; +// eslint-disable-next-line no-unused-vars +let tray; + +let willQuitApp = false; // ipcMain initIpcMain(win); @@ -39,7 +43,7 @@ function createWindow() { win.setMenuBarVisibility(false); if (process.platform !== "darwin") { - createTray(win); + tray = createTray(win); } if (process.env.WEBPACK_DEV_SERVER_URL) { @@ -60,9 +64,19 @@ function createWindow() { e.preventDefault(); shell.openExternal(url); }); - win.on("closed", () => { - win = null; + win.on("close", (e) => { + if (willQuitApp) { + /* the user tried to quit the app */ + win = null; + } else { + /* the user only tried to close the window */ + e.preventDefault(); + win.hide(); + } }); + // win.on("closed", () => { + // win = null; + // }); return win; } @@ -71,7 +85,7 @@ app.on("window-all-closed", () => { // On macOS it is common for applications and their menu bar // to stay active until the user quits explicitly with Cmd + Q if (process.platform !== "darwin") { - app.quit(); + // app.quit(); } }); @@ -80,9 +94,16 @@ app.on("activate", () => { // dock icon is clicked and there are no other windows open. if (win === null) { createWindow(); + } else { + win.show(); } }); +/** + * 'before-quit' is emitted when Electron receives the signal to exit and wants to start closing windows + */ +app.on("before-quit", () => (willQuitApp = true)); + // This method will be called when Electron has finished // initialization and is ready to create browser windows. // Some APIs can only be used after this event occurs. diff --git a/src/electron/ipcMain.js b/src/electron/ipcMain.js index a631697..83a3ae8 100644 --- a/src/electron/ipcMain.js +++ b/src/electron/ipcMain.js @@ -33,8 +33,9 @@ export function initIpcMain(win) { }); ipcMain.on("close", () => { - win.close(); - app.quit(); + win.hide(); + // win.close(); + // app.quit(); }); ipcMain.on("minimize", () => { diff --git a/src/electron/menu.js b/src/electron/menu.js index 972fc9b..7965400 100644 --- a/src/electron/menu.js +++ b/src/electron/menu.js @@ -128,6 +128,7 @@ export function createMenu(win) { { label: "Window", submenu: [ + { role: "close" }, { role: "minimize" }, { role: "zoom" }, { role: "reload" }, diff --git a/src/electron/tray.js b/src/electron/tray.js index e624c19..04ab51f 100644 --- a/src/electron/tray.js +++ b/src/electron/tray.js @@ -1,5 +1,6 @@ +/* global __static */ import path from "path"; -import { nativeImage, Tray } from "electron"; +import { app, nativeImage, Tray, Menu } from "electron"; export function createTray(win) { let icon = nativeImage @@ -17,5 +18,18 @@ export function createTray(win) { win.show(); } }); + + tray.on("right-click", () => { + const contextMenu = Menu.buildFromTemplate([ + { + label: "Quit", + click: () => { + app.exit(); + }, + }, + ]); + tray.popUpContextMenu(contextMenu); + }); + return tray; } From 993f86710983ba98d3a63cf77a0ad34d63824e9e Mon Sep 17 00:00:00 2001 From: njzy <njzydark@gmail.com> Date: Wed, 9 Dec 2020 19:51:35 +0800 Subject: [PATCH 2/3] fix: the initial music sort error when restart app (#79) --- src/store/index.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/store/index.js b/src/store/index.js index 4caa429..c6a5c9b 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -43,10 +43,11 @@ Howler.volume(store.state.player.volume); // 防止软件第一次打开资源加载2次 Howler.autoUnlock = false; -const currentTrackId = store.state?.player?.currentTrack?.id; -if (currentTrackId) { +const currentTrack = store.state?.player?.currentTrack; +if (currentTrack?.id) { store.dispatch("switchTrack", { - id: currentTrackId, + id: currentTrack.id, + sort: currentTrack.sort, autoplay: false, }); } From 4128d9ac3b0a389bb27731e5eae5c0f31ba51e79 Mon Sep 17 00:00:00 2001 From: njzy <njzydark@gmail.com> Date: Wed, 9 Dec 2020 19:53:19 +0800 Subject: [PATCH 3/3] feat: support cache songs (#80) fix: cache unblock song refactor: play first and then cache it --- src/store/actions.js | 66 ++++++++++++++++++++++++++++++-------------- src/utils/db.js | 34 ++++++++++------------- 2 files changed, 61 insertions(+), 39 deletions(-) diff --git a/src/store/actions.js b/src/store/actions.js index 76305b7..4200e0c 100644 --- a/src/store/actions.js +++ b/src/store/actions.js @@ -1,5 +1,5 @@ import { updateMediaSessionMetaData } from "@/utils/mediaSession"; -import { getTrackDetail, scrobble, getMP3 } from "@/api/track"; +import { getTrackDetail, scrobble, getMP3 as getMP3Api } from "@/api/track"; import { isAccountLoggedIn } from "@/utils/auth"; import { updateHttps } from "@/utils/common"; import localforage from "localforage"; @@ -40,17 +40,18 @@ export default { updateMediaSessionMetaData(track); document.title = `${track.name} · ${track.ar[0].name} - YesPlayMusic`; + let unblockSongUrl = null; if (track.playable === false) { let res = undefined; if (process.env.IS_ELECTRON === true) { res = ipcRenderer.sendSync("unblock-music", track); } if (res?.url) { - commitMP3(res.url); + unblockSongUrl = res.url; } else { dispatch("nextTrack"); + return; } - return; } function commitMP3(mp3) { @@ -59,31 +60,56 @@ export default { dispatch("nextTrack"); }); } + + function getMP3(id) { + return getMP3Api(id).then((data) => { + // 未知情况下会没有返回数据导致报错,增加防范逻辑 + if (data.data[0]) { + const url = updateHttps(data.data[0].url); + commitMP3(url); + return url; + } + }); + } + if (isAccountLoggedIn()) { if (store.state.settings.automaticallyCacheSongs === true) { let tracks = localforage.createInstance({ name: "tracks", }); - tracks.getItem(`${track.id}`).then((t) => { - if (t !== null) { - commitMP3(URL.createObjectURL(t.mp3)); - } else { - cacheTrack(`${track.id}`).then((t) => { - commitMP3(URL.createObjectURL(t.mp3)); - }); - } - }); + tracks + .getItem(`${track.id}`) + .then((t) => { + if (t !== null) { + const blob = new Blob([t.mp3]); + commitMP3(URL.createObjectURL(blob)); + } else { + if (unblockSongUrl) { + commitMP3(unblockSongUrl); + cacheTrack(`${track.id}`, unblockSongUrl); + } else { + getMP3(track.id).then((url) => { + cacheTrack(`${track.id}`, url); + }); + } + } + }) + .catch((err) => { + console.log(err.messaeg); + if (unblockSongUrl) { + commitMP3(unblockSongUrl); + } else { + getMP3(track.id); + } + }); } else { - getMP3(track.id).then((data) => { - // 未知情况下会没有返回数据导致报错,增加防范逻辑 - if (data.data[0]) { - const url = updateHttps(data.data[0].url); - commitMP3(url); - } - }); + getMP3(track.id); } } else { - commitMP3(`https://music.163.com/song/media/outer/url?id=${track.id}`); + commitMP3( + unblockSongUrl || + `https://music.163.com/song/media/outer/url?id=${track.id}` + ); } }); }, diff --git a/src/utils/db.js b/src/utils/db.js index 7c8ffc6..e7bb5bf 100644 --- a/src/utils/db.js +++ b/src/utils/db.js @@ -1,11 +1,10 @@ -// import axios from "axios"; +import axios from "axios"; import localforage from "localforage"; -import { getMP3 } from "@/api/track"; -export function cacheTrack(id) { - // let tracks = localforage.createInstance({ - // name: "tracks", - // }); +export function cacheTrack(id, url) { + let tracks = localforage.createInstance({ + name: "tracks", + }); // TODO: limit cache songs number // tracks.length().then(function (length) { @@ -17,17 +16,14 @@ export function cacheTrack(id) { // }); // TODO: cache track details - return getMP3(id).then((data) => { - // return axios - // .get(data.data[0].url.replace(/^http:/, "https:"), { - // responseType: "blob", - // }) - // .then((data) => { - // tracks.setItem(`${id}`, { mp3: data.data }); - // return { mp3: data.data }; - // }); - return { mp3: data.data[0].url.replace(/^http:/, "https:") }; - }); + return axios + .get(url, { + responseType: "arraybuffer", + }) + .then((response) => { + tracks.setItem(`${id}`, { mp3: response.data }); + return { mp3: response.data }; + }); } export function countDBSize(dbName) { @@ -37,11 +33,11 @@ export function countDBSize(dbName) { let trackSizes = []; return db .iterate((value) => { - trackSizes.push(value.mp3.size); + trackSizes.push(value.mp3.byteLength); }) .then(() => { return { - bytes: trackSizes.reduce((s1, s2) => s1 + s2), + bytes: trackSizes.reduce((s1, s2) => s1 + s2, 0), length: trackSizes.length, }; })