mirror of
https://github.com/qier222/YesPlayMusic.git
synced 2025-02-17 01:42:46 +08:00
chore: 整理electron目录
This commit is contained in:
parent
ca4725a46e
commit
8d7ae405a6
|
@ -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 {
|
|
@ -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',
|
|
@ -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<string, string | string[]>,
|
||||
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,
|
||||
})
|
|
@ -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'
|
74
packages/electron/main/menu.ts
Normal file
74
packages/electron/main/menu.ts
Normal file
|
@ -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<MenuItemConstructorOptions | MenuItem> = [
|
||||
{ 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)
|
||||
}
|
19
packages/electron/main/preload.ts
Normal file
19
packages/electron/main/preload.ts
Normal file
|
@ -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')}`)
|
|
@ -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`)
|
|
@ -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)
|
|
@ -34,7 +34,7 @@ function createNativeImage(filename: string) {
|
|||
}
|
||||
|
||||
function createMenuTemplate(win: BrowserWindow): MenuItemConstructorOptions[] {
|
||||
let template: MenuItemConstructorOptions[] =
|
||||
const template: MenuItemConstructorOptions[] =
|
||||
process.platform === 'linux'
|
||||
? [
|
||||
{
|
|
@ -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
|
|
@ -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')}`)
|
|
@ -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.'))
|
||||
|
|
Loading…
Reference in New Issue
Block a user