From 8d7ae405a6039066eecc9307a2a89d06aefa9ab6 Mon Sep 17 00:00:00 2001 From: qier222 Date: Fri, 13 May 2022 19:30:13 +0800 Subject: [PATCH] =?UTF-8?q?chore:=20=E6=95=B4=E7=90=86electron=E7=9B=AE?= =?UTF-8?q?=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/electron/{ => main}/cache.ts | 2 +- packages/electron/{ => main}/db.ts | 5 +- packages/electron/{ => main}/index.ts | 37 +++++----- packages/electron/{ => main}/ipcMain.ts | 4 +- packages/electron/{ => main}/log.ts | 0 packages/electron/main/menu.ts | 74 +++++++++++++++++++ packages/electron/main/preload.ts | 19 +++++ .../electron/{ => main}/rendererPreload.ts | 0 packages/electron/{ => main}/sentry.ts | 2 +- packages/electron/{ => main}/server.ts | 42 +++++------ packages/electron/{ => main}/tray.ts | 2 +- packages/electron/{ => main}/utils.ts | 25 +++++-- .../electron/{ => main}/windowsTaskbar.ts | 0 packages/electron/preload.ts | 11 --- packages/electron/scripts/build.main.mjs | 5 +- 15 files changed, 160 insertions(+), 68 deletions(-) rename packages/electron/{ => main}/cache.ts (99%) rename packages/electron/{ => main}/db.ts (97%) rename packages/electron/{ => main}/index.ts (86%) rename packages/electron/{ => main}/ipcMain.ts (97%) rename packages/electron/{ => main}/log.ts (100%) create mode 100644 packages/electron/main/menu.ts create mode 100644 packages/electron/main/preload.ts rename packages/electron/{ => main}/rendererPreload.ts (100%) rename packages/electron/{ => main}/sentry.ts (93%) rename packages/electron/{ => main}/server.ts (91%) rename packages/electron/{ => main}/tray.ts (98%) rename packages/electron/{ => main}/utils.ts (58%) rename packages/electron/{ => main}/windowsTaskbar.ts (100%) delete mode 100644 packages/electron/preload.ts diff --git a/packages/electron/cache.ts b/packages/electron/main/cache.ts similarity index 99% rename from packages/electron/cache.ts rename to packages/electron/main/cache.ts index 8146661..2592875 100644 --- a/packages/electron/cache.ts +++ b/packages/electron/main/cache.ts @@ -5,7 +5,7 @@ import { Request, Response } from 'express' import log from './log' import fs from 'fs' import * as musicMetadata from 'music-metadata' -import { APIs, APIsParams, APIsResponse } from '../shared/CacheAPIs' +import { APIs, APIsParams, APIsResponse } from '@/shared/CacheAPIs' import { TablesStructures } from './db' class Cache { diff --git a/packages/electron/db.ts b/packages/electron/main/db.ts similarity index 97% rename from packages/electron/db.ts rename to packages/electron/main/db.ts index a138ba9..366566a 100644 --- a/packages/electron/db.ts +++ b/packages/electron/main/db.ts @@ -3,10 +3,9 @@ import { app } from 'electron' import fs from 'fs' import SQLite3 from 'better-sqlite3' import log from './log' -import { createFileIfNotExist } from './utils' -import pkg from '../../package.json' +import { createFileIfNotExist, dirname } from './utils' +import pkg from '../../../package.json' import { compare, validate } from 'compare-versions' -import { dirname } from './utils' export const enum Tables { Track = 'Track', diff --git a/packages/electron/index.ts b/packages/electron/main/index.ts similarity index 86% rename from packages/electron/index.ts rename to packages/electron/main/index.ts index bf4bbbd..a552d09 100644 --- a/packages/electron/index.ts +++ b/packages/electron/main/index.ts @@ -15,6 +15,7 @@ import { initIpcMain } from './ipcMain' import { createTray, YPMTray } from './tray' import { IpcChannels } from '@/shared/IpcChannels' import { createTaskbar, Thumbar } from './windowsTaskbar' +import { createMenu } from './menu' import { Store as State, initialState } from '@/shared/store' import { isDev, isWindows, isLinux, isMac } from './utils' @@ -63,6 +64,7 @@ class Main { this.handleAppEvents() this.handleWindowEvents() this.createTray() + createMenu(this.win!) this.createThumbar() initIpcMain(this.win, this.tray, this.thumbar, this.store) this.initDevTools() @@ -76,13 +78,9 @@ class Main { const { default: installExtension, REACT_DEVELOPER_TOOLS, - REDUX_DEVTOOLS, // eslint-disable-next-line @typescript-eslint/no-var-requires } = require('electron-devtools-installer') - installExtension(REACT_DEVELOPER_TOOLS.id).catch((err: any) => - log.info('An error occurred: ', err) - ) - installExtension(REDUX_DEVTOOLS.id).catch((err: any) => + installExtension(REACT_DEVELOPER_TOOLS.id).catch((err: unknown) => log.info('An error occurred: ', err) ) @@ -134,25 +132,26 @@ class Main { disableCORS() { if (!this.win) return - function UpsertKeyValue(obj, keyToChange, value) { - const keyToChangeLower = keyToChange.toLowerCase() - for (const key of Object.keys(obj)) { - if (key.toLowerCase() === keyToChangeLower) { - // Reassign old key - obj[key] = value - // Done - return + const upsertKeyValue = ( + object: Record, + keyToChange: string, + value: string[] + ) => { + if (!object) return + for (const key of Object.keys(object)) { + if (key.toLowerCase() === keyToChange.toLowerCase()) { + object[key] = value } } - // Insert at end instead - obj[keyToChange] = value + object[keyToChange] = value } this.win.webContents.session.webRequest.onBeforeSendHeaders( (details, callback) => { const { requestHeaders, url } = details - UpsertKeyValue(requestHeaders, 'Access-Control-Allow-Origin', ['*']) + upsertKeyValue(requestHeaders, 'access-control-allow-origin', ['*']) + // 不加这几个 header 的话,使用 axios 加载 YouTube 音频会很慢 if (url.includes('googlevideo.com')) { requestHeaders['Sec-Fetch-Mode'] = 'no-cors' requestHeaders['Sec-Fetch-Dest'] = 'audio' @@ -166,8 +165,10 @@ class Main { this.win.webContents.session.webRequest.onHeadersReceived( (details, callback) => { const { responseHeaders } = details - UpsertKeyValue(responseHeaders, 'Access-Control-Allow-Origin', ['*']) - UpsertKeyValue(responseHeaders, 'Access-Control-Allow-Headers', ['*']) + if (responseHeaders) { + upsertKeyValue(responseHeaders, 'access-control-allow-origin', ['*']) + upsertKeyValue(responseHeaders, 'access-control-allow-headers', ['*']) + } callback({ responseHeaders, }) diff --git a/packages/electron/ipcMain.ts b/packages/electron/main/ipcMain.ts similarity index 97% rename from packages/electron/ipcMain.ts rename to packages/electron/main/ipcMain.ts index 4feb2f8..b055969 100644 --- a/packages/electron/ipcMain.ts +++ b/packages/electron/main/ipcMain.ts @@ -1,12 +1,12 @@ import { BrowserWindow, ipcMain, app } from 'electron' import { db, Tables } from './db' -import { IpcChannels, IpcChannelsParams } from '../shared/IpcChannels' +import { IpcChannels, IpcChannelsParams } from '@/shared/IpcChannels' import cache from './cache' import log from './log' import fs from 'fs' import Store from 'electron-store' import { TypedElectronStore } from './index' -import { APIs } from '../shared/CacheAPIs' +import { APIs } from '@/shared/CacheAPIs' import { YPMTray } from './tray' import { Thumbar } from './windowsTaskbar' import fastFolderSize from 'fast-folder-size' diff --git a/packages/electron/log.ts b/packages/electron/main/log.ts similarity index 100% rename from packages/electron/log.ts rename to packages/electron/main/log.ts diff --git a/packages/electron/main/menu.ts b/packages/electron/main/menu.ts new file mode 100644 index 0000000..e9ed881 --- /dev/null +++ b/packages/electron/main/menu.ts @@ -0,0 +1,74 @@ +import { + BrowserWindow, + Menu, + MenuItem, + MenuItemConstructorOptions, + shell, +} from 'electron' +import { logsPath, isMac } from './utils' +import { exec } from 'child_process' + +export const createMenu = (win: BrowserWindow) => { + const template: Array = [ + { role: 'appMenu' }, + { role: 'editMenu' }, + { role: 'viewMenu' }, + { role: 'windowMenu' }, + { + label: '帮助', + submenu: [ + { + label: '打开日志文件目录', + click: async () => { + if (isMac) { + exec(`open ${logsPath}`) + } else { + // TODO: 测试Windows和Linux是否能正确打开日志目录 + shell.openPath(logsPath) + } + }, + }, + { + label: '打开开发者工具', + click: async () => { + win.webContents.openDevTools() + }, + }, + { + label: '反馈问题', + click: async () => { + await shell.openExternal( + 'https://github.com/qier222/YesPlayMusic/issues/new' + ) + }, + }, + { type: 'separator' }, + { + label: '访问 GitHub 仓库', + click: async () => { + await shell.openExternal('https://github.com/qier222/YesPlayMusic') + }, + }, + { + label: '访问论坛', + click: async () => { + await shell.openExternal( + 'https://github.com/qier222/YesPlayMusic/discussions' + ) + }, + }, + { + label: '加入交流群', + click: async () => { + await shell.openExternal( + 'https://github.com/qier222/YesPlayMusic/discussions' + ) + }, + }, + ], + }, + ] + + const menu = Menu.buildFromTemplate(template) + Menu.setApplicationMenu(menu) +} diff --git a/packages/electron/main/preload.ts b/packages/electron/main/preload.ts new file mode 100644 index 0000000..149853f --- /dev/null +++ b/packages/electron/main/preload.ts @@ -0,0 +1,19 @@ +import log from './log' +import { app } from 'electron' +import { + createDirIfNotExist, + devUserDataPath, + isDev, + portableUserDataPath, +} from './utils' + +if (isDev) { + createDirIfNotExist(devUserDataPath) + app.setPath('appData', devUserDataPath) +} +if (process.env.PORTABLE_EXECUTABLE_DIR) { + createDirIfNotExist(portableUserDataPath) + app.setPath('appData', portableUserDataPath) +} + +log.info(`[index] userData path: ${app.getPath('userData')}`) diff --git a/packages/electron/rendererPreload.ts b/packages/electron/main/rendererPreload.ts similarity index 100% rename from packages/electron/rendererPreload.ts rename to packages/electron/main/rendererPreload.ts diff --git a/packages/electron/sentry.ts b/packages/electron/main/sentry.ts similarity index 93% rename from packages/electron/sentry.ts rename to packages/electron/main/sentry.ts index 5009efe..ed32894 100644 --- a/packages/electron/sentry.ts +++ b/packages/electron/main/sentry.ts @@ -1,6 +1,6 @@ import * as Sentry from '@sentry/node' import * as Tracing from '@sentry/tracing' -import pkg from '../../package.json' +import pkg from '../../../package.json' import log from './log' log.info(`[sentry] sentry initializing`) diff --git a/packages/electron/server.ts b/packages/electron/main/server.ts similarity index 91% rename from packages/electron/server.ts rename to packages/electron/main/server.ts index b1e7306..f1226d5 100644 --- a/packages/electron/server.ts +++ b/packages/electron/main/server.ts @@ -6,12 +6,12 @@ import cache from './cache' import fileUpload from 'express-fileupload' import path from 'path' import fs from 'fs' -import { db, Tables } from 'db' +import { db, Tables } from './db' import { app } from 'electron' import type { FetchAudioSourceResponse } from '@/shared/api/Track' import UNM from '@unblockneteasemusic/rust-napi' -import { APIs as CacheAPIs } from '../shared/CacheAPIs' -import { isProd } from 'utils' +import { APIs as CacheAPIs } from '@/shared/CacheAPIs' +import { isProd } from './utils' class Server { port = Number( @@ -241,21 +241,21 @@ class Server { }) } - // try { - // const fromCache = await getFromCache(id) - // if (fromCache) { - // res.status(200).send(fromCache) - // return - // } - // } catch (error) { - // log.error(`[server] getFromCache failed: ${String(error)}`) - // } + try { + const fromCache = await getFromCache(id) + if (fromCache) { + res.status(200).send(fromCache) + return + } + } catch (error) { + log.error(`[server] getFromCache failed: ${String(error)}`) + } - // const fromNetease = await getFromNetease(req) - // if (fromNetease?.code === 200 && !fromNetease?.data?.[0].freeTrialInfo) { - // res.status(200).send(fromNetease) - // return - // } + const fromNetease = await getFromNetease(req) + if (fromNetease?.code === 200 && !fromNetease?.data?.[0].freeTrialInfo) { + res.status(200).send(fromNetease) + return + } try { const fromUNM = await getFromUNM(id, req) @@ -267,11 +267,11 @@ class Server { log.error(`[server] getFromNetease failed: ${String(error)}`) } - // if (fromNetease?.data?.[0].freeTrialInfo) { - // fromNetease.data[0].url = '' - // } + if (fromNetease?.data?.[0].freeTrialInfo) { + fromNetease.data[0].url = '' + } - // res.status(fromNetease?.code ?? 500).send(fromNetease) + res.status(fromNetease?.code ?? 500).send(fromNetease) } this.app.get('/netease/song/url', handler) diff --git a/packages/electron/tray.ts b/packages/electron/main/tray.ts similarity index 98% rename from packages/electron/tray.ts rename to packages/electron/main/tray.ts index 4191c7a..0937a1d 100644 --- a/packages/electron/tray.ts +++ b/packages/electron/main/tray.ts @@ -34,7 +34,7 @@ function createNativeImage(filename: string) { } function createMenuTemplate(win: BrowserWindow): MenuItemConstructorOptions[] { - let template: MenuItemConstructorOptions[] = + const template: MenuItemConstructorOptions[] = process.platform === 'linux' ? [ { diff --git a/packages/electron/utils.ts b/packages/electron/main/utils.ts similarity index 58% rename from packages/electron/utils.ts rename to packages/electron/main/utils.ts index aa82106..cee189c 100644 --- a/packages/electron/utils.ts +++ b/packages/electron/main/utils.ts @@ -1,5 +1,23 @@ import fs from 'fs' import path from 'path' +import pkg from '../../../package.json' + +export const isDev = process.env.NODE_ENV === 'development' +export const isProd = process.env.NODE_ENV === 'production' +export const isWindows = process.platform === 'win32' +export const isMac = process.platform === 'darwin' +export const isLinux = process.platform === 'linux' +export const dirname = isDev ? process.cwd() : __dirname +export const devUserDataPath = path.resolve(process.cwd(), '../../tmp/userData') +export const portableUserDataPath = path.resolve( + process.env.PORTABLE_EXECUTABLE_DIR || '', + './YesPlayMusic-UserData' +) +export const logsPath = { + linux: `~/.config/${pkg.productName}/logs`, + darwin: `~/Library/Logs/${pkg.productName}/`, + win32: `%USERPROFILE%\\AppData\\Roaming\\${pkg.productName}\\logs`, +}[process.platform as 'darwin' | 'win32' | 'linux'] export const createDirIfNotExist = (dir: string) => { if (!fs.existsSync(dir)) { @@ -13,10 +31,3 @@ export const createFileIfNotExist = (file: string) => { fs.writeFileSync(file, '') } } - -export const isDev = process.env.NODE_ENV === 'development' -export const isProd = process.env.NODE_ENV === 'production' -export const isWindows = process.platform === 'win32' -export const isMac = process.platform === 'darwin' -export const isLinux = process.platform === 'linux' -export const dirname = isDev ? process.cwd() : __dirname diff --git a/packages/electron/windowsTaskbar.ts b/packages/electron/main/windowsTaskbar.ts similarity index 100% rename from packages/electron/windowsTaskbar.ts rename to packages/electron/main/windowsTaskbar.ts diff --git a/packages/electron/preload.ts b/packages/electron/preload.ts deleted file mode 100644 index 7c6cb37..0000000 --- a/packages/electron/preload.ts +++ /dev/null @@ -1,11 +0,0 @@ -import log from './log' -import path from 'path' -import { app } from 'electron' -import { createDirIfNotExist, isDev } from './utils' - -if (isDev) { - const devUserDataPath = path.resolve(process.cwd(), '../../tmp/userData') - createDirIfNotExist(devUserDataPath) - app.setPath('appData', devUserDataPath) -} -log.info(`[index] userData path: ${app.getPath('userData')}`) diff --git a/packages/electron/scripts/build.main.mjs b/packages/electron/scripts/build.main.mjs index 5c6b120..ed93e12 100644 --- a/packages/electron/scripts/build.main.mjs +++ b/packages/electron/scripts/build.main.mjs @@ -23,13 +23,13 @@ const TAG = '[script/build.main.ts]' const spinner = ora(`${TAG} Main Process Building...`) const options = { - entryPoints: ['./index.ts', './rendererPreload.ts'], + entryPoints: ['./main/index.ts', './main/rendererPreload.ts'], outdir: './dist', platform: 'node', format: 'cjs', bundle: true, - sourcemap: true, define: envForEsbuild, + minify: true, external: [ ...builtinModules.filter( x => !/^_|^(internal|v8|node-inspect)\/|\//.test(x) @@ -95,7 +95,6 @@ if (argv.watch) { ...options.define, 'process.env.NODE_ENV': '"production"', }, - minify: true, }) .then(() => { console.log(TAG, pc.green('Main Process Build Succeeded.'))