Compare commits

..

12 Commits

Author SHA1 Message Date
lyswhut
3fe34545b9 添加自定义源二进制数据传输支持 2023-05-13 11:53:56 +08:00
lyswhut
da4be33a04 添加上限设置 2023-05-12 20:13:35 +08:00
lyswhut
47e2a5a460 更新依赖 2023-05-08 18:07:26 +08:00
lyswhut
04337ef4b8 添加音效用户预设 2023-05-08 18:04:04 +08:00
lyswhut
df58c8eb80 添加强行构建环境变量参数 2023-05-06 16:36:33 +08:00
lyswhut
b0bf1bf4be 添加繁忙重试重试 2023-05-05 19:01:57 +08:00
lyswhut
1a3d84d4c4 更新版本号 2023-05-04 19:15:52 +08:00
lyswhut
735f629ca1 添加更多环境混响音效 2023-05-04 19:14:00 +08:00
lyswhut
9dc927b50b 修复名称显示 2023-05-04 19:13:48 +08:00
lyswhut
47a336eb64 修复 2023-05-03 18:16:53 +08:00
lyswhut
33b66aaea0 改名 2023-05-03 17:56:32 +08:00
lyswhut
7b9eefdf2d 新增音效设置 2023-05-03 17:45:43 +08:00
60 changed files with 1820 additions and 313 deletions

View File

@@ -12,5 +12,6 @@
],
"i18n-ally.sortKeys": true,
"javascript.preferences.importModuleSpecifier": "non-relative",
"typescript.tsdk": "node_modules/typescript/lib"
"typescript.tsdk": "node_modules/typescript/lib",
"vue.codeActions.enabled": false
}

View File

@@ -52,7 +52,7 @@ const replaceQrcDecodeLib = async(platform, arch) => {
module.exports = async(context) => {
const { electronPlatformName, arch } = context
await replaceQrcDecodeLib(electronPlatformName, arch)
if (electronPlatformName !== 'linux') return
if (electronPlatformName !== 'linux' || process.env.FORCE) return
const bindingFilePath = path.join(__dirname, '../node_modules/better-sqlite3/binding.gyp')
const bindingBakFilePath = path.join(__dirname, '../node_modules/better-sqlite3/binding.gyp.bak')
switch (arch) {

486
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "lx-music-desktop",
"version": "2.2.2",
"version": "2.3.0-beta.3",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "lx-music-desktop",
"version": "2.2.2",
"version": "2.3.0-beta.3",
"hasInstallScript": true,
"license": "Apache-2.0",
"dependencies": {
@@ -33,8 +33,8 @@
"ws": "^8.13.0"
},
"devDependencies": {
"@babel/core": "^7.21.5",
"@babel/eslint-parser": "^7.21.3",
"@babel/core": "^7.21.8",
"@babel/eslint-parser": "^7.21.8",
"@babel/plugin-proposal-class-properties": "^7.18.6",
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/plugin-transform-modules-umd": "^7.18.6",
@@ -44,26 +44,26 @@
"@types/better-sqlite3": "^7.6.4",
"@types/needle": "^3.2.0",
"@types/tunnel": "^0.0.3",
"@typescript-eslint/eslint-plugin": "^5.59.1",
"@typescript-eslint/parser": "^5.59.1",
"@volar/vue-language-plugin-pug": "^1.6.1",
"@typescript-eslint/eslint-plugin": "^5.59.2",
"@typescript-eslint/parser": "^5.59.2",
"@volar/vue-language-plugin-pug": "^1.6.4",
"babel-loader": "^9.1.2",
"browserslist": "^4.21.5",
"chalk": "^4.1.2",
"changelog-parser": "^3.0.1",
"copy-webpack-plugin": "^11.0.0",
"core-js": "^3.30.1",
"core-js": "^3.30.2",
"cross-env": "^7.0.3",
"css-loader": "^6.7.3",
"css-minimizer-webpack-plugin": "^5.0.0",
"del": "^6.1.1",
"electron": "^22.3.7",
"electron": "^22.3.8",
"electron-builder": "^24.3.0",
"electron-debug": "^3.2.0",
"electron-devtools-installer": "^3.2.0",
"electron-to-chromium": "^1.4.377",
"electron-to-chromium": "^1.4.385",
"electron-updater": "^6.1.0",
"eslint": "^8.39.0",
"eslint": "^8.40.0",
"eslint-config-standard": "^17.0.0",
"eslint-config-standard-with-typescript": "^34.0.1",
"eslint-formatter-friendly": "github:lyswhut/eslint-friendly-formatter#2170d1320e2fad13615a9dcf229669f0bb473a53",
@@ -71,7 +71,7 @@
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-n": "^15.7.0",
"eslint-plugin-promise": "^6.1.1",
"eslint-plugin-vue": "^9.11.0",
"eslint-plugin-vue": "^9.11.1",
"eslint-webpack-plugin": "^4.0.1",
"html-webpack-plugin": "^5.5.1",
"less": "^4.1.3",
@@ -89,15 +89,15 @@
"svg-transform-loader": "^2.0.13",
"svgo-loader": "^4.0.0",
"terser": "^5.17.1",
"terser-webpack-plugin": "^5.3.7",
"terser-webpack-plugin": "^5.3.8",
"ts-loader": "^9.4.2",
"typescript": "^5.0.4",
"vue-eslint-parser": "^9.1.1",
"vue-eslint-parser": "^9.2.1",
"vue-loader": "^17.1.0",
"vue-template-compiler": "^2.7.14",
"webpack": "^5.81.0",
"webpack-cli": "^5.0.2",
"webpack-dev-server": "^4.13.3",
"webpack": "^5.82.0",
"webpack-cli": "^5.1.0",
"webpack-dev-server": "^4.15.0",
"webpack-hot-middleware": "github:lyswhut/webpack-hot-middleware#329c4375134b89d39da23a56a94db651247c74a1",
"webpack-merge": "^5.8.0"
},
@@ -141,9 +141,9 @@
}
},
"node_modules/@babel/core": {
"version": "7.21.5",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.5.tgz",
"integrity": "sha512-9M398B/QH5DlfCOTKDZT1ozXr0x8uBEeFd+dJraGUZGiaNpGCDVGCc14hZexsMblw3XxltJ+6kSvogp9J+5a9g==",
"version": "7.21.8",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.8.tgz",
"integrity": "sha512-YeM22Sondbo523Sz0+CirSPnbj9bG3P0CdHcBZdqUuaeOaYEFbOLoGU7lebvGP6P5J/WE9wOn7u7C4J9HvS1xQ==",
"dev": true,
"dependencies": {
"@ampproject/remapping": "^2.2.0",
@@ -152,7 +152,7 @@
"@babel/helper-compilation-targets": "^7.21.5",
"@babel/helper-module-transforms": "^7.21.5",
"@babel/helpers": "^7.21.5",
"@babel/parser": "^7.21.5",
"@babel/parser": "^7.21.8",
"@babel/template": "^7.20.7",
"@babel/traverse": "^7.21.5",
"@babel/types": "^7.21.5",
@@ -171,9 +171,9 @@
}
},
"node_modules/@babel/eslint-parser": {
"version": "7.21.3",
"resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.21.3.tgz",
"integrity": "sha512-kfhmPimwo6k4P8zxNs8+T7yR44q1LdpsZdE1NkCsVlfiuTPRfnGgjaF8Qgug9q9Pou17u6wneYF0lDCZJATMFg==",
"version": "7.21.8",
"resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.21.8.tgz",
"integrity": "sha512-HLhI+2q+BP3sf78mFUZNCGc10KEmoUqtUT1OCdMZsN+qr4qFeLUod62/zAnF3jNQstwyasDkZnVXwfK2Bml7MQ==",
"dev": true,
"dependencies": {
"@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1",
@@ -639,9 +639,9 @@
}
},
"node_modules/@babel/parser": {
"version": "7.21.5",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.5.tgz",
"integrity": "sha512-J+IxH2IsxV4HbnTrSWgMAQj0UEo61hDA4Ny8h8PCX0MLXiibqHbqIOVneqdocemSBc22VpBKxt4J6FQzy9HarQ==",
"version": "7.21.8",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.8.tgz",
"integrity": "sha512-6zavDGdzG3gUqAdWvlLFfk+36RilI+Pwyuuh7HItyeScCWP3k6i8vKclAQ0bM/0y/Kz/xiwvxhMv9MgTJP5gmA==",
"bin": {
"parser": "bin/babel-parser.js"
},
@@ -2282,14 +2282,14 @@
}
},
"node_modules/@eslint/eslintrc": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.2.tgz",
"integrity": "sha512-3W4f5tDUra+pA+FzgugqL2pRimUTDJWKr7BINqOpkZrC0uYI0NIc0/JFgBROCU07HR6GieA5m3/rsPIhDmCXTQ==",
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz",
"integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==",
"dev": true,
"dependencies": {
"ajv": "^6.12.4",
"debug": "^4.3.2",
"espree": "^9.5.1",
"espree": "^9.5.2",
"globals": "^13.19.0",
"ignore": "^5.2.0",
"import-fresh": "^3.2.1",
@@ -2332,9 +2332,9 @@
}
},
"node_modules/@eslint/js": {
"version": "8.39.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.39.0.tgz",
"integrity": "sha512-kf9RB0Fg7NZfap83B3QOqOGg9QmD9yBudqQXzzOtn3i4y7ZUXe5ONeW34Gwi+TxhH4mvj72R1Zc300KUMa9Bng==",
"version": "8.40.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.40.0.tgz",
"integrity": "sha512-ElyB54bJIhXQYVKjDSvCkPO1iU1tSAeVQJbllWJq1XQSmmA4dgFk8CbiBGpiOPxleE48vDogxCtmMYku4HSVLA==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -3069,15 +3069,15 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "5.59.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.1.tgz",
"integrity": "sha512-AVi0uazY5quFB9hlp2Xv+ogpfpk77xzsgsIEWyVS7uK/c7MZ5tw7ZPbapa0SbfkqE0fsAMkz5UwtgMLVk2BQAg==",
"version": "5.59.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.2.tgz",
"integrity": "sha512-yVrXupeHjRxLDcPKL10sGQ/QlVrA8J5IYOEWVqk0lJaSZP7X5DfnP7Ns3cc74/blmbipQ1htFNVGsHX6wsYm0A==",
"dev": true,
"dependencies": {
"@eslint-community/regexpp": "^4.4.0",
"@typescript-eslint/scope-manager": "5.59.1",
"@typescript-eslint/type-utils": "5.59.1",
"@typescript-eslint/utils": "5.59.1",
"@typescript-eslint/scope-manager": "5.59.2",
"@typescript-eslint/type-utils": "5.59.2",
"@typescript-eslint/utils": "5.59.2",
"debug": "^4.3.4",
"grapheme-splitter": "^1.0.4",
"ignore": "^5.2.0",
@@ -3136,14 +3136,14 @@
"dev": true
},
"node_modules/@typescript-eslint/parser": {
"version": "5.59.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.1.tgz",
"integrity": "sha512-nzjFAN8WEu6yPRDizIFyzAfgK7nybPodMNFGNH0M9tei2gYnYszRDqVA0xlnRjkl7Hkx2vYrEdb6fP2a21cG1g==",
"version": "5.59.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.2.tgz",
"integrity": "sha512-uq0sKyw6ao1iFOZZGk9F8Nro/8+gfB5ezl1cA06SrqbgJAt0SRoFhb9pXaHvkrxUpZaoLxt8KlovHNk8Gp6/HQ==",
"dev": true,
"dependencies": {
"@typescript-eslint/scope-manager": "5.59.1",
"@typescript-eslint/types": "5.59.1",
"@typescript-eslint/typescript-estree": "5.59.1",
"@typescript-eslint/scope-manager": "5.59.2",
"@typescript-eslint/types": "5.59.2",
"@typescript-eslint/typescript-estree": "5.59.2",
"debug": "^4.3.4"
},
"engines": {
@@ -3163,13 +3163,13 @@
}
},
"node_modules/@typescript-eslint/scope-manager": {
"version": "5.59.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.1.tgz",
"integrity": "sha512-mau0waO5frJctPuAzcxiNWqJR5Z8V0190FTSqRw1Q4Euop6+zTwHAf8YIXNwDOT29tyUDrQ65jSg9aTU/H0omA==",
"version": "5.59.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.2.tgz",
"integrity": "sha512-dB1v7ROySwQWKqQ8rEWcdbTsFjh2G0vn8KUyvTXdPoyzSL6lLGkiXEV5CvpJsEe9xIdKV+8Zqb7wif2issoOFA==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "5.59.1",
"@typescript-eslint/visitor-keys": "5.59.1"
"@typescript-eslint/types": "5.59.2",
"@typescript-eslint/visitor-keys": "5.59.2"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -3180,13 +3180,13 @@
}
},
"node_modules/@typescript-eslint/type-utils": {
"version": "5.59.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.1.tgz",
"integrity": "sha512-ZMWQ+Oh82jWqWzvM3xU+9y5U7MEMVv6GLioM3R5NJk6uvP47kZ7YvlgSHJ7ERD6bOY7Q4uxWm25c76HKEwIjZw==",
"version": "5.59.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.2.tgz",
"integrity": "sha512-b1LS2phBOsEy/T381bxkkywfQXkV1dWda/z0PhnIy3bC5+rQWQDS7fk9CSpcXBccPY27Z6vBEuaPBCKCgYezyQ==",
"dev": true,
"dependencies": {
"@typescript-eslint/typescript-estree": "5.59.1",
"@typescript-eslint/utils": "5.59.1",
"@typescript-eslint/typescript-estree": "5.59.2",
"@typescript-eslint/utils": "5.59.2",
"debug": "^4.3.4",
"tsutils": "^3.21.0"
},
@@ -3207,9 +3207,9 @@
}
},
"node_modules/@typescript-eslint/types": {
"version": "5.59.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.1.tgz",
"integrity": "sha512-dg0ICB+RZwHlysIy/Dh1SP+gnXNzwd/KS0JprD3Lmgmdq+dJAJnUPe1gNG34p0U19HvRlGX733d/KqscrGC1Pg==",
"version": "5.59.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.2.tgz",
"integrity": "sha512-LbJ/HqoVs2XTGq5shkiKaNTuVv5tTejdHgfdjqRUGdYhjW1crm/M7og2jhVskMt8/4wS3T1+PfFvL1K3wqYj4w==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -3220,13 +3220,13 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
"version": "5.59.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.1.tgz",
"integrity": "sha512-lYLBBOCsFltFy7XVqzX0Ju+Lh3WPIAWxYpmH/Q7ZoqzbscLiCW00LeYCdsUnnfnj29/s1WovXKh2gwCoinHNGA==",
"version": "5.59.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.2.tgz",
"integrity": "sha512-+j4SmbwVmZsQ9jEyBMgpuBD0rKwi9RxRpjX71Brr73RsYnEr3Lt5QZ624Bxphp8HUkSKfqGnPJp1kA5nl0Sh7Q==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "5.59.1",
"@typescript-eslint/visitor-keys": "5.59.1",
"@typescript-eslint/types": "5.59.2",
"@typescript-eslint/visitor-keys": "5.59.2",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
@@ -3280,17 +3280,17 @@
"dev": true
},
"node_modules/@typescript-eslint/utils": {
"version": "5.59.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.1.tgz",
"integrity": "sha512-MkTe7FE+K1/GxZkP5gRj3rCztg45bEhsd8HYjczBuYm+qFHP5vtZmjx3B0yUCDotceQ4sHgTyz60Ycl225njmA==",
"version": "5.59.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.2.tgz",
"integrity": "sha512-kSuF6/77TZzyGPhGO4uVp+f0SBoYxCDf+lW3GKhtKru/L8k/Hd7NFQxyWUeY7Z/KGB2C6Fe3yf2vVi4V9TsCSQ==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@types/json-schema": "^7.0.9",
"@types/semver": "^7.3.12",
"@typescript-eslint/scope-manager": "5.59.1",
"@typescript-eslint/types": "5.59.1",
"@typescript-eslint/typescript-estree": "5.59.1",
"@typescript-eslint/scope-manager": "5.59.2",
"@typescript-eslint/types": "5.59.2",
"@typescript-eslint/typescript-estree": "5.59.2",
"eslint-scope": "^5.1.1",
"semver": "^7.3.7"
},
@@ -3339,12 +3339,12 @@
"dev": true
},
"node_modules/@typescript-eslint/visitor-keys": {
"version": "5.59.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.1.tgz",
"integrity": "sha512-6waEYwBTCWryx0VJmP7JaM4FpipLsFl9CvYf2foAE8Qh/Y0s+bxWysciwOs0LTBED4JCaNxTZ5rGadB14M6dwA==",
"version": "5.59.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.2.tgz",
"integrity": "sha512-EEpsO8m3RASrKAHI9jpavNv9NlEUebV4qmF1OWxSTtKSFBpC1NCmWazDQHFivRf0O1DV11BA645yrLEVQ0/Lig==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "5.59.1",
"@typescript-eslint/types": "5.59.2",
"eslint-visitor-keys": "^3.3.0"
},
"engines": {
@@ -3440,9 +3440,9 @@
}
},
"node_modules/@volar/vue-language-plugin-pug": {
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/@volar/vue-language-plugin-pug/-/vue-language-plugin-pug-1.6.1.tgz",
"integrity": "sha512-sWYj04ukFBiOaAu4fmGDxnVm/fODSJ2hQtEB0GTAUHGjz9EzaaBjV1gWd8sX6KnerWx6MxYQiy0LIK7z++3h2w==",
"version": "1.6.4",
"resolved": "https://registry.npmjs.org/@volar/vue-language-plugin-pug/-/vue-language-plugin-pug-1.6.4.tgz",
"integrity": "sha512-4OxKJuxlKvQNb+q5ubA8ArT+K+ZUBKg+YgxzFDIBI34mEH2l9u45IbrpYelspenKAdFRF3S1yVpS43ZjVVJ3tQ==",
"dev": true,
"dependencies": {
"@volar-plugins/pug": "2.0.0",
@@ -3710,9 +3710,9 @@
}
},
"node_modules/@webpack-cli/configtest": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.0.1.tgz",
"integrity": "sha512-njsdJXJSiS2iNbQVS0eT8A/KPnmyH4pv1APj2K0d1wrZcBLw+yppxOy4CGqa0OxDJkzfL/XELDhD8rocnIwB5A==",
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.0.tgz",
"integrity": "sha512-K/vuv72vpfSEZoo5KIU0a2FsEoYdW0DUMtMpB5X3LlUwshetMZRZRxB7sCsVji/lFaSxtQQ3aM9O4eMolXkU9w==",
"dev": true,
"engines": {
"node": ">=14.15.0"
@@ -3736,9 +3736,9 @@
}
},
"node_modules/@webpack-cli/serve": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.2.tgz",
"integrity": "sha512-S9h3GmOmzUseyeFW3tYNnWS7gNUuwxZ3mmMq0JyW78Vx1SGKPSkt5bT4pB0rUnVfHjP0EL9gW2bOzmtiTfQt0A==",
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.3.tgz",
"integrity": "sha512-Bwxd73pHuYc0cyl7vulPp2I6kAYtmJPkfUivbts7by6wDAVyFdKzGX3AksbvCRyNVFUJu7o2ZTcWXdT90T3qbg==",
"dev": true,
"engines": {
"node": ">=14.15.0"
@@ -6061,9 +6061,9 @@
}
},
"node_modules/core-js": {
"version": "3.30.1",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.30.1.tgz",
"integrity": "sha512-ZNS5nbiSwDTq4hFosEDqm65izl2CWmLz0hARJMyNQBgkUZMIF51cQiMvIQKA6hvuaeWxQDP3hEedM1JZIgTldQ==",
"version": "3.30.2",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.30.2.tgz",
"integrity": "sha512-uBJiDmwqsbJCWHAwjrx3cvjbMXP7xD72Dmsn5LOJpiRmE3WbBbN5rCqQ2Qh6Ek6/eOrjlWngEynBWo4VxerQhg==",
"hasInstallScript": true,
"funding": {
"type": "opencollective",
@@ -7021,9 +7021,9 @@
}
},
"node_modules/electron": {
"version": "22.3.7",
"resolved": "https://registry.npmjs.org/electron/-/electron-22.3.7.tgz",
"integrity": "sha512-QUuRCl0QJk0w2yPAQXl6sk4YV1b9353w4e1eO/fF2OUmrGQV9Fy2pEpEDV1PIq/JJ/oeVVlI3H07LHpEcNb0TA==",
"version": "22.3.8",
"resolved": "https://registry.npmjs.org/electron/-/electron-22.3.8.tgz",
"integrity": "sha512-h2SWCog2tXnNgBtwIIfT8pq3HR5TUqnSSnCk8/o4Yn6Nmh9x79kcPiRtj1ZY8QcVShxAY3lK9U/gdBNV47FK7g==",
"dev": true,
"hasInstallScript": true,
"dependencies": {
@@ -7263,9 +7263,9 @@
}
},
"node_modules/electron-to-chromium": {
"version": "1.4.377",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.377.tgz",
"integrity": "sha512-H3BYG6DW5Z+l0xcfXaicJGxrpA4kMlCxnN71+iNX+dBLkRMOdVJqFJiAmbNZZKA1zISpRg17JR03qGifXNsJtw==",
"version": "1.4.385",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.385.tgz",
"integrity": "sha512-L9zlje9bIw0h+CwPQumiuVlfMcV4boxRjFIWDcLfFqTZNbkwOExBzfmswytHawObQX4OUhtNv8gIiB21kOurIg==",
"dev": true
},
"node_modules/electron-updater": {
@@ -7578,15 +7578,15 @@
}
},
"node_modules/eslint": {
"version": "8.39.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.39.0.tgz",
"integrity": "sha512-mwiok6cy7KTW7rBpo05k6+p4YVZByLNjAZ/ACB9DRCu4YDRwjXI01tWHp6KAUWelsBetTxKK/2sHB0vdS8Z2Og==",
"version": "8.40.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.40.0.tgz",
"integrity": "sha512-bvR+TsP9EHL3TqNtj9sCNJVAFK3fBN8Q7g5waghxyRsPLIMwL73XSKnZFK0hk/O2ANC+iAoq6PWMQ+IfBAJIiQ==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.4.0",
"@eslint/eslintrc": "^2.0.2",
"@eslint/js": "8.39.0",
"@eslint/eslintrc": "^2.0.3",
"@eslint/js": "8.40.0",
"@humanwhocodes/config-array": "^0.11.8",
"@humanwhocodes/module-importer": "^1.0.1",
"@nodelib/fs.walk": "^1.2.8",
@@ -7597,8 +7597,8 @@
"doctrine": "^3.0.0",
"escape-string-regexp": "^4.0.0",
"eslint-scope": "^7.2.0",
"eslint-visitor-keys": "^3.4.0",
"espree": "^9.5.1",
"eslint-visitor-keys": "^3.4.1",
"espree": "^9.5.2",
"esquery": "^1.4.2",
"esutils": "^2.0.2",
"fast-deep-equal": "^3.1.3",
@@ -7916,9 +7916,9 @@
}
},
"node_modules/eslint-plugin-vue": {
"version": "9.11.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.11.0.tgz",
"integrity": "sha512-bBCJAZnkBV7ATH4Z1E7CvN3nmtS4H7QUU3UBxPdo8WohRU+yHjnQRALpTbxMVcz0e4Mx3IyxIdP5HYODMxK9cQ==",
"version": "9.11.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.11.1.tgz",
"integrity": "sha512-SNtBGDrRkPUFsREswPceqdvZ7YVdWY+iCYiDC+RoxwVieeQ7GJU1FLDlkcaYTOD2os/YuVgI1Fdu8YGM7fmoow==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.3.0",
@@ -8050,9 +8050,9 @@
}
},
"node_modules/eslint/node_modules/eslint-visitor-keys": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz",
"integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==",
"version": "3.4.1",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz",
"integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -8098,14 +8098,14 @@
}
},
"node_modules/espree": {
"version": "9.5.1",
"resolved": "https://registry.npmjs.org/espree/-/espree-9.5.1.tgz",
"integrity": "sha512-5yxtHSZXRSW5pvv3hAlXM5+/Oswi1AUFqBmbibKb5s6bp3rGIDkyXU6xCoyuuLhijr4SFwPrXRoZjz0AZDN9tg==",
"version": "9.5.2",
"resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz",
"integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==",
"dev": true,
"dependencies": {
"acorn": "^8.8.0",
"acorn-jsx": "^5.3.2",
"eslint-visitor-keys": "^3.4.0"
"eslint-visitor-keys": "^3.4.1"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -8115,9 +8115,9 @@
}
},
"node_modules/espree/node_modules/eslint-visitor-keys": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz",
"integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==",
"version": "3.4.1",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz",
"integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -16506,16 +16506,16 @@
}
},
"node_modules/terser-webpack-plugin": {
"version": "5.3.7",
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.7.tgz",
"integrity": "sha512-AfKwIktyP7Cu50xNjXF/6Qb5lBNzYaWpU6YfoX3uZicTx0zTy0stDDCsvjDapKsSDvOeWo5MEq4TmdBy2cNoHw==",
"version": "5.3.8",
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.8.tgz",
"integrity": "sha512-WiHL3ElchZMsK27P8uIUh4604IgJyAW47LVXGbEoB21DbQcZ+OuMpGjVYnEUaqcWM6dO8uS2qUbA7LSCWqvsbg==",
"dev": true,
"dependencies": {
"@jridgewell/trace-mapping": "^0.3.17",
"jest-worker": "^27.4.5",
"schema-utils": "^3.1.1",
"serialize-javascript": "^6.0.1",
"terser": "^5.16.5"
"terser": "^5.16.8"
},
"engines": {
"node": ">= 10.13.0"
@@ -17405,9 +17405,9 @@
}
},
"node_modules/vue-eslint-parser": {
"version": "9.1.1",
"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.1.1.tgz",
"integrity": "sha512-C2aI/r85Q6tYcz4dpgvrs4wH/MqVrRAVIdpYedrxnATDHHkb+TroeRcDpKWGZCx/OcECMWfz7tVwQ8e+Opy6rA==",
"version": "9.2.1",
"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.2.1.tgz",
"integrity": "sha512-tPOex4n6jit4E7h68auOEbDMwE58XiP4dylfaVTCOVCouR45g+QFDBjgIdEU52EXJxKyjgh91dLfN2rxUcV0bQ==",
"dev": true,
"dependencies": {
"debug": "^4.3.4",
@@ -17570,9 +17570,9 @@
}
},
"node_modules/webpack": {
"version": "5.81.0",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.81.0.tgz",
"integrity": "sha512-AAjaJ9S4hYCVODKLQTgG5p5e11hiMawBwV2v8MYLE0C/6UAGLuAF4n1qa9GOwdxnicaP+5k6M5HrLmD4+gIB8Q==",
"version": "5.82.0",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.82.0.tgz",
"integrity": "sha512-iGNA2fHhnDcV1bONdUu554eZx+XeldsaeQ8T67H6KKHl2nUSwX8Zm7cmzOA46ox/X1ARxf7Bjv8wQ/HsB5fxBg==",
"dev": true,
"dependencies": {
"@types/eslint-scope": "^3.7.3",
@@ -17617,15 +17617,15 @@
}
},
"node_modules/webpack-cli": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.0.2.tgz",
"integrity": "sha512-4y3W5Dawri5+8dXm3+diW6Mn1Ya+Dei6eEVAdIduAmYNLzv1koKVAqsfgrrc9P2mhrYHQphx5htnGkcNwtubyQ==",
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.0.tgz",
"integrity": "sha512-a7KRJnCxejFoDpYTOwzm5o21ZXMaNqtRlvS183XzGDUPRdVEzJNImcQokqYZ8BNTnk9DkKiuWxw75+DCCoZ26w==",
"dev": true,
"dependencies": {
"@discoveryjs/json-ext": "^0.5.0",
"@webpack-cli/configtest": "^2.0.1",
"@webpack-cli/configtest": "^2.1.0",
"@webpack-cli/info": "^2.0.1",
"@webpack-cli/serve": "^2.0.2",
"@webpack-cli/serve": "^2.0.3",
"colorette": "^2.0.14",
"commander": "^10.0.1",
"cross-spawn": "^7.0.3",
@@ -17694,9 +17694,9 @@
}
},
"node_modules/webpack-dev-server": {
"version": "4.13.3",
"resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.13.3.tgz",
"integrity": "sha512-KqqzrzMRSRy5ePz10VhjyL27K2dxqwXQLP5rAKwRJBPUahe7Z2bBWzHw37jeb8GCPKxZRO79ZdQUAPesMh/Nug==",
"version": "4.15.0",
"resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.0.tgz",
"integrity": "sha512-HmNB5QeSl1KpulTBQ8UT4FPrByYyaLxpJoQ0+s7EvUrMc16m0ZS1sgb1XGqzmgCPk0c9y+aaXxn11tbLzuM7NQ==",
"dev": true,
"dependencies": {
"@types/bonjour": "^3.5.9",
@@ -18097,9 +18097,9 @@
"dev": true
},
"@babel/core": {
"version": "7.21.5",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.5.tgz",
"integrity": "sha512-9M398B/QH5DlfCOTKDZT1ozXr0x8uBEeFd+dJraGUZGiaNpGCDVGCc14hZexsMblw3XxltJ+6kSvogp9J+5a9g==",
"version": "7.21.8",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.8.tgz",
"integrity": "sha512-YeM22Sondbo523Sz0+CirSPnbj9bG3P0CdHcBZdqUuaeOaYEFbOLoGU7lebvGP6P5J/WE9wOn7u7C4J9HvS1xQ==",
"dev": true,
"requires": {
"@ampproject/remapping": "^2.2.0",
@@ -18108,7 +18108,7 @@
"@babel/helper-compilation-targets": "^7.21.5",
"@babel/helper-module-transforms": "^7.21.5",
"@babel/helpers": "^7.21.5",
"@babel/parser": "^7.21.5",
"@babel/parser": "^7.21.8",
"@babel/template": "^7.20.7",
"@babel/traverse": "^7.21.5",
"@babel/types": "^7.21.5",
@@ -18120,9 +18120,9 @@
}
},
"@babel/eslint-parser": {
"version": "7.21.3",
"resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.21.3.tgz",
"integrity": "sha512-kfhmPimwo6k4P8zxNs8+T7yR44q1LdpsZdE1NkCsVlfiuTPRfnGgjaF8Qgug9q9Pou17u6wneYF0lDCZJATMFg==",
"version": "7.21.8",
"resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.21.8.tgz",
"integrity": "sha512-HLhI+2q+BP3sf78mFUZNCGc10KEmoUqtUT1OCdMZsN+qr4qFeLUod62/zAnF3jNQstwyasDkZnVXwfK2Bml7MQ==",
"dev": true,
"requires": {
"@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1",
@@ -18474,9 +18474,9 @@
}
},
"@babel/parser": {
"version": "7.21.5",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.5.tgz",
"integrity": "sha512-J+IxH2IsxV4HbnTrSWgMAQj0UEo61hDA4Ny8h8PCX0MLXiibqHbqIOVneqdocemSBc22VpBKxt4J6FQzy9HarQ=="
"version": "7.21.8",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.8.tgz",
"integrity": "sha512-6zavDGdzG3gUqAdWvlLFfk+36RilI+Pwyuuh7HItyeScCWP3k6i8vKclAQ0bM/0y/Kz/xiwvxhMv9MgTJP5gmA=="
},
"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": {
"version": "7.18.6",
@@ -19604,14 +19604,14 @@
"dev": true
},
"@eslint/eslintrc": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.2.tgz",
"integrity": "sha512-3W4f5tDUra+pA+FzgugqL2pRimUTDJWKr7BINqOpkZrC0uYI0NIc0/JFgBROCU07HR6GieA5m3/rsPIhDmCXTQ==",
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz",
"integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==",
"dev": true,
"requires": {
"ajv": "^6.12.4",
"debug": "^4.3.2",
"espree": "^9.5.1",
"espree": "^9.5.2",
"globals": "^13.19.0",
"ignore": "^5.2.0",
"import-fresh": "^3.2.1",
@@ -19638,9 +19638,9 @@
}
},
"@eslint/js": {
"version": "8.39.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.39.0.tgz",
"integrity": "sha512-kf9RB0Fg7NZfap83B3QOqOGg9QmD9yBudqQXzzOtn3i4y7ZUXe5ONeW34Gwi+TxhH4mvj72R1Zc300KUMa9Bng==",
"version": "8.40.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.40.0.tgz",
"integrity": "sha512-ElyB54bJIhXQYVKjDSvCkPO1iU1tSAeVQJbllWJq1XQSmmA4dgFk8CbiBGpiOPxleE48vDogxCtmMYku4HSVLA==",
"dev": true
},
"@gar/promisify": {
@@ -20276,15 +20276,15 @@
}
},
"@typescript-eslint/eslint-plugin": {
"version": "5.59.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.1.tgz",
"integrity": "sha512-AVi0uazY5quFB9hlp2Xv+ogpfpk77xzsgsIEWyVS7uK/c7MZ5tw7ZPbapa0SbfkqE0fsAMkz5UwtgMLVk2BQAg==",
"version": "5.59.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.2.tgz",
"integrity": "sha512-yVrXupeHjRxLDcPKL10sGQ/QlVrA8J5IYOEWVqk0lJaSZP7X5DfnP7Ns3cc74/blmbipQ1htFNVGsHX6wsYm0A==",
"dev": true,
"requires": {
"@eslint-community/regexpp": "^4.4.0",
"@typescript-eslint/scope-manager": "5.59.1",
"@typescript-eslint/type-utils": "5.59.1",
"@typescript-eslint/utils": "5.59.1",
"@typescript-eslint/scope-manager": "5.59.2",
"@typescript-eslint/type-utils": "5.59.2",
"@typescript-eslint/utils": "5.59.2",
"debug": "^4.3.4",
"grapheme-splitter": "^1.0.4",
"ignore": "^5.2.0",
@@ -20320,53 +20320,53 @@
}
},
"@typescript-eslint/parser": {
"version": "5.59.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.1.tgz",
"integrity": "sha512-nzjFAN8WEu6yPRDizIFyzAfgK7nybPodMNFGNH0M9tei2gYnYszRDqVA0xlnRjkl7Hkx2vYrEdb6fP2a21cG1g==",
"version": "5.59.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.2.tgz",
"integrity": "sha512-uq0sKyw6ao1iFOZZGk9F8Nro/8+gfB5ezl1cA06SrqbgJAt0SRoFhb9pXaHvkrxUpZaoLxt8KlovHNk8Gp6/HQ==",
"dev": true,
"requires": {
"@typescript-eslint/scope-manager": "5.59.1",
"@typescript-eslint/types": "5.59.1",
"@typescript-eslint/typescript-estree": "5.59.1",
"@typescript-eslint/scope-manager": "5.59.2",
"@typescript-eslint/types": "5.59.2",
"@typescript-eslint/typescript-estree": "5.59.2",
"debug": "^4.3.4"
}
},
"@typescript-eslint/scope-manager": {
"version": "5.59.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.1.tgz",
"integrity": "sha512-mau0waO5frJctPuAzcxiNWqJR5Z8V0190FTSqRw1Q4Euop6+zTwHAf8YIXNwDOT29tyUDrQ65jSg9aTU/H0omA==",
"version": "5.59.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.2.tgz",
"integrity": "sha512-dB1v7ROySwQWKqQ8rEWcdbTsFjh2G0vn8KUyvTXdPoyzSL6lLGkiXEV5CvpJsEe9xIdKV+8Zqb7wif2issoOFA==",
"dev": true,
"requires": {
"@typescript-eslint/types": "5.59.1",
"@typescript-eslint/visitor-keys": "5.59.1"
"@typescript-eslint/types": "5.59.2",
"@typescript-eslint/visitor-keys": "5.59.2"
}
},
"@typescript-eslint/type-utils": {
"version": "5.59.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.1.tgz",
"integrity": "sha512-ZMWQ+Oh82jWqWzvM3xU+9y5U7MEMVv6GLioM3R5NJk6uvP47kZ7YvlgSHJ7ERD6bOY7Q4uxWm25c76HKEwIjZw==",
"version": "5.59.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.2.tgz",
"integrity": "sha512-b1LS2phBOsEy/T381bxkkywfQXkV1dWda/z0PhnIy3bC5+rQWQDS7fk9CSpcXBccPY27Z6vBEuaPBCKCgYezyQ==",
"dev": true,
"requires": {
"@typescript-eslint/typescript-estree": "5.59.1",
"@typescript-eslint/utils": "5.59.1",
"@typescript-eslint/typescript-estree": "5.59.2",
"@typescript-eslint/utils": "5.59.2",
"debug": "^4.3.4",
"tsutils": "^3.21.0"
}
},
"@typescript-eslint/types": {
"version": "5.59.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.1.tgz",
"integrity": "sha512-dg0ICB+RZwHlysIy/Dh1SP+gnXNzwd/KS0JprD3Lmgmdq+dJAJnUPe1gNG34p0U19HvRlGX733d/KqscrGC1Pg==",
"version": "5.59.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.2.tgz",
"integrity": "sha512-LbJ/HqoVs2XTGq5shkiKaNTuVv5tTejdHgfdjqRUGdYhjW1crm/M7og2jhVskMt8/4wS3T1+PfFvL1K3wqYj4w==",
"dev": true
},
"@typescript-eslint/typescript-estree": {
"version": "5.59.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.1.tgz",
"integrity": "sha512-lYLBBOCsFltFy7XVqzX0Ju+Lh3WPIAWxYpmH/Q7ZoqzbscLiCW00LeYCdsUnnfnj29/s1WovXKh2gwCoinHNGA==",
"version": "5.59.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.2.tgz",
"integrity": "sha512-+j4SmbwVmZsQ9jEyBMgpuBD0rKwi9RxRpjX71Brr73RsYnEr3Lt5QZ624Bxphp8HUkSKfqGnPJp1kA5nl0Sh7Q==",
"dev": true,
"requires": {
"@typescript-eslint/types": "5.59.1",
"@typescript-eslint/visitor-keys": "5.59.1",
"@typescript-eslint/types": "5.59.2",
"@typescript-eslint/visitor-keys": "5.59.2",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
@@ -20401,17 +20401,17 @@
}
},
"@typescript-eslint/utils": {
"version": "5.59.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.1.tgz",
"integrity": "sha512-MkTe7FE+K1/GxZkP5gRj3rCztg45bEhsd8HYjczBuYm+qFHP5vtZmjx3B0yUCDotceQ4sHgTyz60Ycl225njmA==",
"version": "5.59.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.2.tgz",
"integrity": "sha512-kSuF6/77TZzyGPhGO4uVp+f0SBoYxCDf+lW3GKhtKru/L8k/Hd7NFQxyWUeY7Z/KGB2C6Fe3yf2vVi4V9TsCSQ==",
"dev": true,
"requires": {
"@eslint-community/eslint-utils": "^4.2.0",
"@types/json-schema": "^7.0.9",
"@types/semver": "^7.3.12",
"@typescript-eslint/scope-manager": "5.59.1",
"@typescript-eslint/types": "5.59.1",
"@typescript-eslint/typescript-estree": "5.59.1",
"@typescript-eslint/scope-manager": "5.59.2",
"@typescript-eslint/types": "5.59.2",
"@typescript-eslint/typescript-estree": "5.59.2",
"eslint-scope": "^5.1.1",
"semver": "^7.3.7"
},
@@ -20443,12 +20443,12 @@
}
},
"@typescript-eslint/visitor-keys": {
"version": "5.59.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.1.tgz",
"integrity": "sha512-6waEYwBTCWryx0VJmP7JaM4FpipLsFl9CvYf2foAE8Qh/Y0s+bxWysciwOs0LTBED4JCaNxTZ5rGadB14M6dwA==",
"version": "5.59.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.2.tgz",
"integrity": "sha512-EEpsO8m3RASrKAHI9jpavNv9NlEUebV4qmF1OWxSTtKSFBpC1NCmWazDQHFivRf0O1DV11BA645yrLEVQ0/Lig==",
"dev": true,
"requires": {
"@typescript-eslint/types": "5.59.1",
"@typescript-eslint/types": "5.59.2",
"eslint-visitor-keys": "^3.3.0"
},
"dependencies": {
@@ -20521,9 +20521,9 @@
}
},
"@volar/vue-language-plugin-pug": {
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/@volar/vue-language-plugin-pug/-/vue-language-plugin-pug-1.6.1.tgz",
"integrity": "sha512-sWYj04ukFBiOaAu4fmGDxnVm/fODSJ2hQtEB0GTAUHGjz9EzaaBjV1gWd8sX6KnerWx6MxYQiy0LIK7z++3h2w==",
"version": "1.6.4",
"resolved": "https://registry.npmjs.org/@volar/vue-language-plugin-pug/-/vue-language-plugin-pug-1.6.4.tgz",
"integrity": "sha512-4OxKJuxlKvQNb+q5ubA8ArT+K+ZUBKg+YgxzFDIBI34mEH2l9u45IbrpYelspenKAdFRF3S1yVpS43ZjVVJ3tQ==",
"dev": true,
"requires": {
"@volar-plugins/pug": "2.0.0",
@@ -20788,9 +20788,9 @@
}
},
"@webpack-cli/configtest": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.0.1.tgz",
"integrity": "sha512-njsdJXJSiS2iNbQVS0eT8A/KPnmyH4pv1APj2K0d1wrZcBLw+yppxOy4CGqa0OxDJkzfL/XELDhD8rocnIwB5A==",
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.0.tgz",
"integrity": "sha512-K/vuv72vpfSEZoo5KIU0a2FsEoYdW0DUMtMpB5X3LlUwshetMZRZRxB7sCsVji/lFaSxtQQ3aM9O4eMolXkU9w==",
"dev": true,
"requires": {}
},
@@ -20802,9 +20802,9 @@
"requires": {}
},
"@webpack-cli/serve": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.2.tgz",
"integrity": "sha512-S9h3GmOmzUseyeFW3tYNnWS7gNUuwxZ3mmMq0JyW78Vx1SGKPSkt5bT4pB0rUnVfHjP0EL9gW2bOzmtiTfQt0A==",
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.3.tgz",
"integrity": "sha512-Bwxd73pHuYc0cyl7vulPp2I6kAYtmJPkfUivbts7by6wDAVyFdKzGX3AksbvCRyNVFUJu7o2ZTcWXdT90T3qbg==",
"dev": true,
"requires": {}
},
@@ -22595,9 +22595,9 @@
}
},
"core-js": {
"version": "3.30.1",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.30.1.tgz",
"integrity": "sha512-ZNS5nbiSwDTq4hFosEDqm65izl2CWmLz0hARJMyNQBgkUZMIF51cQiMvIQKA6hvuaeWxQDP3hEedM1JZIgTldQ=="
"version": "3.30.2",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.30.2.tgz",
"integrity": "sha512-uBJiDmwqsbJCWHAwjrx3cvjbMXP7xD72Dmsn5LOJpiRmE3WbBbN5rCqQ2Qh6Ek6/eOrjlWngEynBWo4VxerQhg=="
},
"core-js-compat": {
"version": "3.27.1",
@@ -23280,9 +23280,9 @@
}
},
"electron": {
"version": "22.3.7",
"resolved": "https://registry.npmjs.org/electron/-/electron-22.3.7.tgz",
"integrity": "sha512-QUuRCl0QJk0w2yPAQXl6sk4YV1b9353w4e1eO/fF2OUmrGQV9Fy2pEpEDV1PIq/JJ/oeVVlI3H07LHpEcNb0TA==",
"version": "22.3.8",
"resolved": "https://registry.npmjs.org/electron/-/electron-22.3.8.tgz",
"integrity": "sha512-h2SWCog2tXnNgBtwIIfT8pq3HR5TUqnSSnCk8/o4Yn6Nmh9x79kcPiRtj1ZY8QcVShxAY3lK9U/gdBNV47FK7g==",
"dev": true,
"requires": {
"@electron/get": "^2.0.0",
@@ -23485,9 +23485,9 @@
}
},
"electron-to-chromium": {
"version": "1.4.377",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.377.tgz",
"integrity": "sha512-H3BYG6DW5Z+l0xcfXaicJGxrpA4kMlCxnN71+iNX+dBLkRMOdVJqFJiAmbNZZKA1zISpRg17JR03qGifXNsJtw==",
"version": "1.4.385",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.385.tgz",
"integrity": "sha512-L9zlje9bIw0h+CwPQumiuVlfMcV4boxRjFIWDcLfFqTZNbkwOExBzfmswytHawObQX4OUhtNv8gIiB21kOurIg==",
"dev": true
},
"electron-updater": {
@@ -23731,15 +23731,15 @@
"dev": true
},
"eslint": {
"version": "8.39.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.39.0.tgz",
"integrity": "sha512-mwiok6cy7KTW7rBpo05k6+p4YVZByLNjAZ/ACB9DRCu4YDRwjXI01tWHp6KAUWelsBetTxKK/2sHB0vdS8Z2Og==",
"version": "8.40.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.40.0.tgz",
"integrity": "sha512-bvR+TsP9EHL3TqNtj9sCNJVAFK3fBN8Q7g5waghxyRsPLIMwL73XSKnZFK0hk/O2ANC+iAoq6PWMQ+IfBAJIiQ==",
"dev": true,
"requires": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.4.0",
"@eslint/eslintrc": "^2.0.2",
"@eslint/js": "8.39.0",
"@eslint/eslintrc": "^2.0.3",
"@eslint/js": "8.40.0",
"@humanwhocodes/config-array": "^0.11.8",
"@humanwhocodes/module-importer": "^1.0.1",
"@nodelib/fs.walk": "^1.2.8",
@@ -23750,8 +23750,8 @@
"doctrine": "^3.0.0",
"escape-string-regexp": "^4.0.0",
"eslint-scope": "^7.2.0",
"eslint-visitor-keys": "^3.4.0",
"espree": "^9.5.1",
"eslint-visitor-keys": "^3.4.1",
"espree": "^9.5.2",
"esquery": "^1.4.2",
"esutils": "^2.0.2",
"fast-deep-equal": "^3.1.3",
@@ -23789,9 +23789,9 @@
}
},
"eslint-visitor-keys": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz",
"integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==",
"version": "3.4.1",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz",
"integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==",
"dev": true
},
"estraverse": {
@@ -24020,9 +24020,9 @@
"requires": {}
},
"eslint-plugin-vue": {
"version": "9.11.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.11.0.tgz",
"integrity": "sha512-bBCJAZnkBV7ATH4Z1E7CvN3nmtS4H7QUU3UBxPdo8WohRU+yHjnQRALpTbxMVcz0e4Mx3IyxIdP5HYODMxK9cQ==",
"version": "9.11.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.11.1.tgz",
"integrity": "sha512-SNtBGDrRkPUFsREswPceqdvZ7YVdWY+iCYiDC+RoxwVieeQ7GJU1FLDlkcaYTOD2os/YuVgI1Fdu8YGM7fmoow==",
"dev": true,
"requires": {
"@eslint-community/eslint-utils": "^4.3.0",
@@ -24099,20 +24099,20 @@
}
},
"espree": {
"version": "9.5.1",
"resolved": "https://registry.npmjs.org/espree/-/espree-9.5.1.tgz",
"integrity": "sha512-5yxtHSZXRSW5pvv3hAlXM5+/Oswi1AUFqBmbibKb5s6bp3rGIDkyXU6xCoyuuLhijr4SFwPrXRoZjz0AZDN9tg==",
"version": "9.5.2",
"resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz",
"integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==",
"dev": true,
"requires": {
"acorn": "^8.8.0",
"acorn-jsx": "^5.3.2",
"eslint-visitor-keys": "^3.4.0"
"eslint-visitor-keys": "^3.4.1"
},
"dependencies": {
"eslint-visitor-keys": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz",
"integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==",
"version": "3.4.1",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz",
"integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==",
"dev": true
}
}
@@ -30546,16 +30546,16 @@
}
},
"terser-webpack-plugin": {
"version": "5.3.7",
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.7.tgz",
"integrity": "sha512-AfKwIktyP7Cu50xNjXF/6Qb5lBNzYaWpU6YfoX3uZicTx0zTy0stDDCsvjDapKsSDvOeWo5MEq4TmdBy2cNoHw==",
"version": "5.3.8",
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.8.tgz",
"integrity": "sha512-WiHL3ElchZMsK27P8uIUh4604IgJyAW47LVXGbEoB21DbQcZ+OuMpGjVYnEUaqcWM6dO8uS2qUbA7LSCWqvsbg==",
"dev": true,
"requires": {
"@jridgewell/trace-mapping": "^0.3.17",
"jest-worker": "^27.4.5",
"schema-utils": "^3.1.1",
"serialize-javascript": "^6.0.1",
"terser": "^5.16.5"
"terser": "^5.16.8"
},
"dependencies": {
"jest-worker": {
@@ -31235,9 +31235,9 @@
}
},
"vue-eslint-parser": {
"version": "9.1.1",
"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.1.1.tgz",
"integrity": "sha512-C2aI/r85Q6tYcz4dpgvrs4wH/MqVrRAVIdpYedrxnATDHHkb+TroeRcDpKWGZCx/OcECMWfz7tVwQ8e+Opy6rA==",
"version": "9.2.1",
"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.2.1.tgz",
"integrity": "sha512-tPOex4n6jit4E7h68auOEbDMwE58XiP4dylfaVTCOVCouR45g+QFDBjgIdEU52EXJxKyjgh91dLfN2rxUcV0bQ==",
"dev": true,
"requires": {
"debug": "^4.3.4",
@@ -31355,9 +31355,9 @@
}
},
"webpack": {
"version": "5.81.0",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.81.0.tgz",
"integrity": "sha512-AAjaJ9S4hYCVODKLQTgG5p5e11hiMawBwV2v8MYLE0C/6UAGLuAF4n1qa9GOwdxnicaP+5k6M5HrLmD4+gIB8Q==",
"version": "5.82.0",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.82.0.tgz",
"integrity": "sha512-iGNA2fHhnDcV1bONdUu554eZx+XeldsaeQ8T67H6KKHl2nUSwX8Zm7cmzOA46ox/X1ARxf7Bjv8wQ/HsB5fxBg==",
"dev": true,
"requires": {
"@types/eslint-scope": "^3.7.3",
@@ -31400,15 +31400,15 @@
}
},
"webpack-cli": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.0.2.tgz",
"integrity": "sha512-4y3W5Dawri5+8dXm3+diW6Mn1Ya+Dei6eEVAdIduAmYNLzv1koKVAqsfgrrc9P2mhrYHQphx5htnGkcNwtubyQ==",
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.0.tgz",
"integrity": "sha512-a7KRJnCxejFoDpYTOwzm5o21ZXMaNqtRlvS183XzGDUPRdVEzJNImcQokqYZ8BNTnk9DkKiuWxw75+DCCoZ26w==",
"dev": true,
"requires": {
"@discoveryjs/json-ext": "^0.5.0",
"@webpack-cli/configtest": "^2.0.1",
"@webpack-cli/configtest": "^2.1.0",
"@webpack-cli/info": "^2.0.1",
"@webpack-cli/serve": "^2.0.2",
"@webpack-cli/serve": "^2.0.3",
"colorette": "^2.0.14",
"commander": "^10.0.1",
"cross-spawn": "^7.0.3",
@@ -31442,9 +31442,9 @@
}
},
"webpack-dev-server": {
"version": "4.13.3",
"resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.13.3.tgz",
"integrity": "sha512-KqqzrzMRSRy5ePz10VhjyL27K2dxqwXQLP5rAKwRJBPUahe7Z2bBWzHw37jeb8GCPKxZRO79ZdQUAPesMh/Nug==",
"version": "4.15.0",
"resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.0.tgz",
"integrity": "sha512-HmNB5QeSl1KpulTBQ8UT4FPrByYyaLxpJoQ0+s7EvUrMc16m0ZS1sgb1XGqzmgCPk0c9y+aaXxn11tbLzuM7NQ==",
"dev": true,
"requires": {
"@types/bonjour": "^3.5.9",

View File

@@ -1,6 +1,6 @@
{
"name": "lx-music-desktop",
"version": "2.2.2",
"version": "2.3.0-beta.3",
"description": "一个免费的音乐查找助手",
"main": "./dist/main.js",
"productName": "lx-music-desktop",
@@ -205,8 +205,8 @@
},
"homepage": "https://github.com/lyswhut/lx-music-desktop#readme",
"devDependencies": {
"@babel/core": "^7.21.5",
"@babel/eslint-parser": "^7.21.3",
"@babel/core": "^7.21.8",
"@babel/eslint-parser": "^7.21.8",
"@babel/plugin-proposal-class-properties": "^7.18.6",
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/plugin-transform-modules-umd": "^7.18.6",
@@ -216,26 +216,26 @@
"@types/better-sqlite3": "^7.6.4",
"@types/needle": "^3.2.0",
"@types/tunnel": "^0.0.3",
"@typescript-eslint/eslint-plugin": "^5.59.1",
"@typescript-eslint/parser": "^5.59.1",
"@volar/vue-language-plugin-pug": "^1.6.1",
"@typescript-eslint/eslint-plugin": "^5.59.2",
"@typescript-eslint/parser": "^5.59.2",
"@volar/vue-language-plugin-pug": "^1.6.4",
"babel-loader": "^9.1.2",
"browserslist": "^4.21.5",
"chalk": "^4.1.2",
"changelog-parser": "^3.0.1",
"copy-webpack-plugin": "^11.0.0",
"core-js": "^3.30.1",
"core-js": "^3.30.2",
"cross-env": "^7.0.3",
"css-loader": "^6.7.3",
"css-minimizer-webpack-plugin": "^5.0.0",
"del": "^6.1.1",
"electron": "^22.3.7",
"electron": "^22.3.8",
"electron-builder": "^24.3.0",
"electron-debug": "^3.2.0",
"electron-devtools-installer": "^3.2.0",
"electron-to-chromium": "^1.4.377",
"electron-to-chromium": "^1.4.385",
"electron-updater": "^6.1.0",
"eslint": "^8.39.0",
"eslint": "^8.40.0",
"eslint-config-standard": "^17.0.0",
"eslint-config-standard-with-typescript": "^34.0.1",
"eslint-formatter-friendly": "github:lyswhut/eslint-friendly-formatter#2170d1320e2fad13615a9dcf229669f0bb473a53",
@@ -243,7 +243,7 @@
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-n": "^15.7.0",
"eslint-plugin-promise": "^6.1.1",
"eslint-plugin-vue": "^9.11.0",
"eslint-plugin-vue": "^9.11.1",
"eslint-webpack-plugin": "^4.0.1",
"html-webpack-plugin": "^5.5.1",
"less": "^4.1.3",
@@ -261,15 +261,15 @@
"svg-transform-loader": "^2.0.13",
"svgo-loader": "^4.0.0",
"terser": "^5.17.1",
"terser-webpack-plugin": "^5.3.7",
"terser-webpack-plugin": "^5.3.8",
"ts-loader": "^9.4.2",
"typescript": "^5.0.4",
"vue-eslint-parser": "^9.1.1",
"vue-eslint-parser": "^9.2.1",
"vue-loader": "^17.1.0",
"vue-template-compiler": "^2.7.14",
"webpack": "^5.81.0",
"webpack-cli": "^5.0.2",
"webpack-dev-server": "^4.13.3",
"webpack": "^5.82.0",
"webpack-cli": "^5.1.0",
"webpack-dev-server": "^4.15.0",
"webpack-hot-middleware": "github:lyswhut/webpack-hot-middleware#329c4375134b89d39da23a56a94db651247c74a1",
"webpack-merge": "^5.8.0"
},

View File

@@ -1,4 +1,7 @@
### 修复
### 新增
- 修复在低版本Linux amd64系统上无法启动的问题glibc版本要求过高导致的采用内置预编译二进制文件的方式解决
- 修复添加歌曲弹窗默认列表名字显示问题
- 新增音效设置实验性功能支持10段均衡器设置、内置的一些环境混响音效、3D立体环绕音效
### 其他
- 更新 electron 到 v22.3.8

View File

@@ -10,6 +10,7 @@ export const STORE_NAMES = {
LRC_RAW: 'lyrics',
LRC_EDITED: 'lyrics_edited',
THEME: 'theme',
SOUND_EFFECT: 'sound_effect',
} as const
export const APP_EVENT_NAMES = {

View File

@@ -40,6 +40,22 @@ const defaultSetting: LX.AppSetting = {
'player.waitPlayEndStop': true,
'player.waitPlayEndStopTime': '',
'player.autoSkipOnError': true,
'player.soundEffect.convolution.fileName': '',
'player.soundEffect.convolution.mainGain': 10,
'player.soundEffect.convolution.sendGain': 0,
'player.soundEffect.biquadFilter.hz31': 0,
'player.soundEffect.biquadFilter.hz62': 0,
'player.soundEffect.biquadFilter.hz125': 0,
'player.soundEffect.biquadFilter.hz250': 0,
'player.soundEffect.biquadFilter.hz500': 0,
'player.soundEffect.biquadFilter.hz1000': 0,
'player.soundEffect.biquadFilter.hz2000': 0,
'player.soundEffect.biquadFilter.hz4000': 0,
'player.soundEffect.biquadFilter.hz8000': 0,
'player.soundEffect.biquadFilter.hz16000': 0,
'player.soundEffect.panner.enable': false,
'player.soundEffect.panner.soundR': 5,
'player.soundEffect.panner.speed': 25,
'playDetail.isZoomActiveLrc': false,
'playDetail.isShowLyricProgressSetting': false,

View File

@@ -90,6 +90,10 @@ const modules = {
get_other_source_count: 'get_other_source_count',
get_data: 'get_data',
save_data: 'save_data',
get_sound_effect_eq_preset: 'get_sound_effect_eq_preset',
save_sound_effect_eq_preset: 'save_sound_effect_eq_preset',
get_sound_effect_convolution_preset: 'get_sound_effect_convolution_preset',
save_sound_effect_convolution_preset: 'save_sound_effect_convolution_preset',
get_hot_key: 'get_hot_key',
import_user_api: 'import_user_api',

View File

@@ -163,6 +163,86 @@ declare global {
*/
'player.waitPlayEndStopTime': string
/**
* 环境音效文件名
*/
'player.soundEffect.convolution.fileName': string | null
/**
* 环境音效原始输出增益
*/
'player.soundEffect.convolution.mainGain': number
/**
* 环境音效输出增益
*/
'player.soundEffect.convolution.sendGain': number
/**
* 均衡器 31hz 值
*/
'player.soundEffect.biquadFilter.hz31': number
/**
* 均衡器 62hz 值
*/
'player.soundEffect.biquadFilter.hz62': number
/**
* 均衡器 125hz 值
*/
'player.soundEffect.biquadFilter.hz125': number
/**
* 均衡器 250hz 值
*/
'player.soundEffect.biquadFilter.hz250': number
/**
* 均衡器 500hz 值
*/
'player.soundEffect.biquadFilter.hz500': number
/**
* 均衡器 1000hz 值
*/
'player.soundEffect.biquadFilter.hz1000': number
/**
* 均衡器 2000hz 值
*/
'player.soundEffect.biquadFilter.hz2000': number
/**
* 均衡器 4000hz 值
*/
'player.soundEffect.biquadFilter.hz4000': number
/**
* 均衡器 8000hz 值
*/
'player.soundEffect.biquadFilter.hz8000': number
/**
* 均衡器 16000hz 值
*/
'player.soundEffect.biquadFilter.hz16000': number
/**
* 3D立体环绕是否启用
*/
'player.soundEffect.panner.enable': boolean
/**
* 3D立体环绕声音距离
*/
'player.soundEffect.panner.soundR': number
/**
* 3D立体环绕速度
*/
'player.soundEffect.panner.speed': number
/**
* 是否启用音频加载失败时自动切歌
*/

25
src/common/types/sound_effect.d.ts vendored Normal file
View File

@@ -0,0 +1,25 @@
declare namespace LX {
namespace SoundEffect {
interface EQPreset {
id: string
name: string
hz31: number
hz62: number
hz125: number
hz250: number
hz500: number
hz1000: number
hz2000: number
hz4000: number
hz8000: number
hz16000: number
}
interface ConvolutionPreset {
id: string
name: string
source: string
mainGain: number
sendGain: number
}
}
}

View File

@@ -9,10 +9,10 @@
"btn_save": "Save",
"cancel_button_text": "Cancel",
"close": "Close",
"comment__location": "From{location}",
"comment__hot_load_error": "Hot comments failed to load, click to try to reload",
"comment__hot_loading": "Hot comments are loading",
"comment__hot_title": "Hot Comment",
"comment__location": "From{location}",
"comment__new_load_error": "The latest comment failed to load, click to try to reload",
"comment__new_loading": "Latest comments are loading",
"comment__new_title": "Latest comment",
@@ -78,8 +78,6 @@
"history_search": "History Searches",
"import": "Import",
"leaderboard": "Charts",
"list__name_default": "Default",
"list__name_love": "Love",
"list__add_to": "Add to ...",
"list__collect": "Collect",
"list__copy_name": "Copy name",
@@ -95,6 +93,8 @@
"list__move_to": "Move to ...",
"list__movedown": "Movedown",
"list__moveup": "Move up",
"list__name_default": "Default",
"list__name_love": "Love",
"list__new_list_btn": "New List",
"list__new_list_input": "New list...",
"list__pause": "Pause Task",
@@ -208,6 +208,7 @@
"player__end": "Stopped",
"player__error": "Error loading music. Switch to next song after 5 seconds",
"player__geting_url": "Getting music link...",
"player__geting_url_delay_retry": "The service is busy, try again in {time} seconds...",
"player__hide_detail_tip": "Hide detail page (Right-click in the view to quickly hide the details page)",
"player__loading": "Music loading...",
"player__music_album": "Album: ",
@@ -227,6 +228,41 @@
"player__playing": "Now playing...",
"player__prev": "Prev",
"player__refresh_url": "Music URL expired, refreshing...",
"player__sound_effect": "Sound settings (experimental)",
"player__sound_effect_biquad_filter": "Equalizer",
"player__sound_effect_biquad_filter_preset_classical": "Classical",
"player__sound_effect_biquad_filter_preset_dance": "Dance",
"player__sound_effect_biquad_filter_preset_electronic": "Electronic",
"player__sound_effect_biquad_filter_preset_pop": "Pop",
"player__sound_effect_biquad_filter_preset_rock": "Rock",
"player__sound_effect_biquad_filter_preset_slow": "Slow",
"player__sound_effect_biquad_filter_preset_soft": "Soft",
"player__sound_effect_biquad_filter_preset_subwoofer": "Subwoofer",
"player__sound_effect_biquad_filter_preset_vocal": "Vocal",
"player__sound_effect_biquad_filter_reset_btn": "Reset",
"player__sound_effect_biquad_filter_save_btn": "Save preset as",
"player__sound_effect_biquad_filter_save_input": "New presets...",
"player__sound_effect_convolution": "Ambient reverb sound effect",
"player__sound_effect_convolution_file_bright_hall": "Hall",
"player__sound_effect_convolution_file_cardiod_35_10_spread": "Rock",
"player__sound_effect_convolution_file_cinema_diningroom": "Cinema",
"player__sound_effect_convolution_file_dining_living_true_stereo": "Dining Room",
"player__sound_effect_convolution_file_feedback_spring": "Feedback Spring",
"player__sound_effect_convolution_file_living_bedroom_leveled": "Bathroom",
"player__sound_effect_convolution_file_matrix_1": "Matrix",
"player__sound_effect_convolution_file_matrix_2": "Matrix 2",
"player__sound_effect_convolution_file_s2_r4_bd": "Church",
"player__sound_effect_convolution_file_s3_r1_bd": "Stereo",
"player__sound_effect_convolution_file_spreader25_125ms": "Indoor 2",
"player__sound_effect_convolution_file_spreader50_65ms": "Indoor",
"player__sound_effect_convolution_file_telephone": "Telephone",
"player__sound_effect_convolution_file_tim_omni_35_10_magnetic": "Rock 2",
"player__sound_effect_convolution_main_gain": "Original Audio Gain",
"player__sound_effect_convolution_send_gain": "Ambient Sound Effect Gain",
"player__sound_effect_panner": "3D stereo surround (need to use headphones)",
"player__sound_effect_panner_enabled": "enable",
"player__sound_effect_panner_sound_r": "Sound distance",
"player__sound_effect_panner_sound_speed": "Surround speed",
"player__stop": "Paused",
"player__volume": "Volume: ",
"player__volume_mute_label": "Mute",
@@ -450,7 +486,7 @@
"setting__play_mediaDevice": "Audio output",
"setting__play_mediaDevice_remove_stop_play": "Pause the song when the current sound output device is changed",
"setting__play_mediaDevice_title": "Select a media device for audio output",
"setting__play_media_device_error_tip": "This function conflicts with the audio visualization function. You have enabled audio visualization when you started the software this time. This setting is temporarily unavailable. Please restart the software and then modify this setting.",
"setting__play_media_device_error_tip": "This function conflicts with advanced audio functions (audio visualization, sound effect settings). These functions have been enabled when you start the software this time. This setting is not available for now. Please close these functions and restart the software before modifying this setting.",
"setting__play_media_device_tip": "This feature conflicts with Audio Visualization, both cannot be enabled at the same time, would you like to turn Audio Visualization off and apply the selected audio output settings?",
"setting__play_quality": "Priority playback of 320K quality songs (if available)",
"setting__play_save_play_time": "Remember playback progress",

View File

@@ -72,7 +72,7 @@ const createI18n = (): I18n => {
return message
},
getMessage(key: keyof Message, val?: TranslateValues): string {
let targetMessage = this.message[key] ?? this.messages[this.fallbackLocale][key] ?? ''
let targetMessage = this.message[key] ?? this.messages[this.fallbackLocale][key] ?? key
return val ? this.fillMessage(targetMessage, val) : targetMessage
},
t(key: keyof Message, val?: TranslateValues): string {

View File

@@ -9,10 +9,10 @@
"btn_save": "保存",
"cancel_button_text": "我不",
"close": "关闭",
"comment__location": "来自{location}",
"comment__hot_load_error": "热门评论加载失败,点击尝试重新加载",
"comment__hot_loading": "热门评论加载中",
"comment__hot_title": "热门评论",
"comment__location": "来自{location}",
"comment__new_load_error": "最新评论加载失败,点击尝试重新加载",
"comment__new_loading": "最新评论加载中",
"comment__new_title": "最新评论",
@@ -78,8 +78,6 @@
"history_search": "历史搜索",
"import": "导入",
"leaderboard": "排行榜",
"list__name_default": "试听列表",
"list__name_love": "我的收藏",
"list__add_to": "添加到...",
"list__collect": "收藏",
"list__copy_name": "复制歌曲名",
@@ -95,6 +93,8 @@
"list__move_to": "移动到...",
"list__movedown": "下移",
"list__moveup": "上移",
"list__name_default": "试听列表",
"list__name_love": "我的收藏",
"list__new_list_btn": "新建列表",
"list__new_list_input": "新列表...",
"list__pause": "暂停任务",
@@ -208,6 +208,7 @@
"player__end": "播放完毕",
"player__error": "音频加载出错5 秒后切换下一首",
"player__geting_url": "歌曲链接获取中...",
"player__geting_url_delay_retry": "服务繁忙,{time}秒后重试...",
"player__hide_detail_tip": "隐藏详情页(界面内右键双击可快速隐藏详情页)",
"player__loading": "音乐加载中...",
"player__music_album": "专辑名:",
@@ -227,6 +228,40 @@
"player__playing": "播放中...",
"player__prev": "上一首",
"player__refresh_url": "URL过期正在刷新URL...",
"player__sound_effect": "音效设置(实验性)",
"player__sound_effect_biquad_filter": "均衡器",
"player__sound_effect_biquad_filter_preset_classical": "古典",
"player__sound_effect_biquad_filter_preset_dance": "舞曲",
"player__sound_effect_biquad_filter_preset_electronic": "电子乐",
"player__sound_effect_biquad_filter_preset_pop": "流行",
"player__sound_effect_biquad_filter_preset_rock": "摇滚",
"player__sound_effect_biquad_filter_preset_slow": "慢歌",
"player__sound_effect_biquad_filter_preset_soft": "柔和",
"player__sound_effect_biquad_filter_preset_subwoofer": "重低音",
"player__sound_effect_biquad_filter_preset_vocal": "人声",
"player__sound_effect_biquad_filter_reset_btn": "重置",
"player__sound_effect_biquad_filter_save_btn": "另存预设",
"player__sound_effect_biquad_filter_save_input": "新预设...",
"player__sound_effect_convolution": "环境混响音效",
"player__sound_effect_convolution_file_bright_hall": "大厅",
"player__sound_effect_convolution_file_cardiod_35_10_spread": "心形扩散",
"player__sound_effect_convolution_file_cinema_diningroom": "电影院",
"player__sound_effect_convolution_file_dining_living_true_stereo": "餐厅",
"player__sound_effect_convolution_file_feedback_spring": "反馈弹簧",
"player__sound_effect_convolution_file_living_bedroom_leveled": "卫生间",
"player__sound_effect_convolution_file_matrix_1": "矩阵混响",
"player__sound_effect_convolution_file_matrix_2": "矩阵混响2",
"player__sound_effect_convolution_file_s2_r4_bd": "教堂",
"player__sound_effect_convolution_file_s3_r1_bd": "立体声",
"player__sound_effect_convolution_file_spreader50_65ms": "室内",
"player__sound_effect_convolution_file_telephone": "电话",
"player__sound_effect_convolution_file_tim_omni_35_10_magnetic": "磁性立体声",
"player__sound_effect_convolution_main_gain": "原始音频增益",
"player__sound_effect_convolution_send_gain": "环境音效增益",
"player__sound_effect_panner": "3D立体环绕需使用耳机",
"player__sound_effect_panner_enabled": "启用",
"player__sound_effect_panner_sound_r": "声音距离",
"player__sound_effect_panner_sound_speed": "环绕速度",
"player__stop": "暂停播放",
"player__volume": "当前音量:",
"player__volume_mute_label": "静音",
@@ -450,7 +485,7 @@
"setting__play_mediaDevice": "音频输出",
"setting__play_mediaDevice_remove_stop_play": "当前的声音输出设备被改变时暂停播放歌曲",
"setting__play_mediaDevice_title": "选择声音输出的媒体设备",
"setting__play_media_device_error_tip": "此功能与音频可视化功能冲突,你本次启动软件时已启用过音频可视化,此设置暂不可用,请 重启 软件后,再来修改此设置。",
"setting__play_media_device_error_tip": "此功能与高级音频功能(音频可视化、音效设置)冲突,你本次启动软件时已启用这些功能,此设置暂不可用,请 关闭这些功能 并 重启 软件后,再来修改此设置。",
"setting__play_media_device_tip": "此功能与音频可视化功能冲突,两者无法同时启用,是否将音频可视化关闭 并 应用所选音频输出设置?",
"setting__play_quality": "优先播放320K品质的歌曲如果可用",
"setting__play_save_play_time": "记住播放进度",

View File

@@ -9,10 +9,10 @@
"btn_save": "保存",
"cancel_button_text": "取消",
"close": "關閉",
"comment__location": "來自{location}",
"comment__hot_load_error": "熱門評論加載失敗,點擊嘗試重新加載",
"comment__hot_loading": "熱門評論加載中",
"comment__hot_title": "熱門評論",
"comment__location": "來自{location}",
"comment__new_load_error": "最新評論加載失敗,點擊嘗試重新加載",
"comment__new_loading": "最新評論加載中",
"comment__new_title": "最新評論",
@@ -78,8 +78,6 @@
"history_search": "歷史搜索",
"import": "導入",
"leaderboard": "排行榜",
"list__name_default": "試聽清單",
"list__name_love": "我的收藏",
"list__add_to": "添加到...",
"list__collect": "收藏",
"list__copy_name": "複製歌曲名",
@@ -95,6 +93,8 @@
"list__move_to": "移動到...",
"list__movedown": "下移",
"list__moveup": "上移",
"list__name_default": "試聽清單",
"list__name_love": "我的收藏",
"list__new_list_btn": "新建列表",
"list__new_list_input": "新列表...",
"list__pause": "暫停任務",
@@ -209,6 +209,7 @@
"player__end": "播放完畢",
"player__error": "音頻加載出錯5 秒後切換下一首",
"player__geting_url": "歌曲鏈接獲取中...",
"player__geting_url_delay_retry": "服務繁忙,{time}秒後重試...",
"player__hide_detail_tip": "隱藏詳情頁(界面內右鍵雙擊可快速隱藏詳情頁)",
"player__loading": "音樂加載中...",
"player__music_name": "歌曲名:",
@@ -227,6 +228,41 @@
"player__playing": "播放中...",
"player__prev": "上一首",
"player__refresh_url": "URL過期正在刷新URL...",
"player__sound_effect": "音效設置(實驗性)",
"player__sound_effect_biquad_filter": "均衡器",
"player__sound_effect_biquad_filter_preset_classical": "古典",
"player__sound_effect_biquad_filter_preset_dance": "舞曲",
"player__sound_effect_biquad_filter_preset_electronic": "電子樂",
"player__sound_effect_biquad_filter_preset_pop": "流行",
"player__sound_effect_biquad_filter_preset_rock": "搖滾",
"player__sound_effect_biquad_filter_preset_slow": "慢歌",
"player__sound_effect_biquad_filter_preset_soft": "柔和",
"player__sound_effect_biquad_filter_preset_subwoofer": "重低音",
"player__sound_effect_biquad_filter_preset_vocal": "人聲",
"player__sound_effect_biquad_filter_reset_btn": "重置",
"player__sound_effect_biquad_filter_save_btn": "另存預設",
"player__sound_effect_biquad_filter_save_input": "新預設...",
"player__sound_effect_convolution": "環境混響音效",
"player__sound_effect_convolution_file_bright_hall": "大廳",
"player__sound_effect_convolution_file_cardiod_35_10_spread": "搖滾",
"player__sound_effect_convolution_file_cinema_diningroom": "電影院",
"player__sound_effect_convolution_file_dining_living_true_stereo": "餐廳",
"player__sound_effect_convolution_file_feedback_spring": "反饋彈簧",
"player__sound_effect_convolution_file_living_bedroom_leveled": "衛生間",
"player__sound_effect_convolution_file_matrix_1": "矩陣",
"player__sound_effect_convolution_file_matrix_2": "矩陣2",
"player__sound_effect_convolution_file_s2_r4_bd": "教堂",
"player__sound_effect_convolution_file_s3_r1_bd": "立體聲",
"player__sound_effect_convolution_file_spreader25_125ms": "室內2",
"player__sound_effect_convolution_file_spreader50_65ms": "室內",
"player__sound_effect_convolution_file_telephone": "電話",
"player__sound_effect_convolution_file_tim_omni_35_10_magnetic": "搖滾2",
"player__sound_effect_convolution_main_gain": "原始音頻增益",
"player__sound_effect_convolution_send_gain": "環境音效增益",
"player__sound_effect_panner": "3D立體環繞需使用耳機",
"player__sound_effect_panner_enabled": "啟用",
"player__sound_effect_panner_sound_r": "聲音距離",
"player__sound_effect_panner_sound_speed": "環繞速度",
"player__stop": "暫停播放",
"player__volume": "當前音量:",
"player__volume_mute_label": "靜音",
@@ -450,7 +486,7 @@
"setting__play_mediaDevice": "音頻輸出",
"setting__play_mediaDevice_remove_stop_play": "當前的聲音輸出設備被改變時暫停播放歌曲",
"setting__play_mediaDevice_title": "選擇聲音輸出的媒體設備",
"setting__play_media_device_error_tip": "此功能與音頻可視化功能衝突,你本次啟動軟件時已啟用過音頻可視化,此設置暫不可用,請 重啟 軟件後,再來修改此設置。",
"setting__play_media_device_error_tip": "此功能與高級音頻功能(音頻可視化、音效設置)衝突,你本次啟動軟件時已啟用這些功能,此設置暫不可用,請 關閉這些功能 並 重啟 軟件後,再來修改此設置。",
"setting__play_media_device_tip": "此功能與音頻可視化功能衝突,兩者無法同時啟用,是否將音頻可視化關閉 並 應用所選音頻輸出設置?",
"setting__play_quality": "優先播放320K品質的歌曲如果可用",
"setting__play_save_play_time": "記住播放進度",

View File

@@ -140,11 +140,15 @@ const handleShowUpdateAlert = (data, resolve, reject) => {
contextBridge.exposeInMainWorld('lx', {
EVENT_NAMES,
request(url, { method = 'get', timeout, headers, body, form, formData }, callback) {
request(url, { method = 'get', timeout, headers, body, form, formData, bodyBinaryBase64 }, callback) {
let options = { headers }
let data
if (body) {
data = body
} else if (bodyBinaryBase64) {
try {
data = Buffer.from(bodyBinaryBase64, 'base64')
} catch {}
} else if (form) {
data = form
// data.content_type = 'application/x-www-form-urlencoded'
@@ -253,7 +257,7 @@ contextBridge.exposeInMainWorld('lx', {
},
},
},
version: '1.3.0',
version: '1.4.0',
// removeEvent(eventName, handler) {
// if (!eventNames.includes(eventName)) return Promise.reject(new Error('The event is not supported: ' + eventName))
// let handlers

View File

@@ -9,6 +9,7 @@ import sync from './sync'
import data from './data'
import music from './music'
import download from './download'
import soundEffect from './soundEffect'
import { sendEvent } from '../main'
export * from './app'
@@ -33,6 +34,7 @@ export default () => {
data()
music()
download()
soundEffect()
global.lx.event_app.on('updated_config', (keys, setting) => {
sendConfigChange(setting)

View File

@@ -0,0 +1,20 @@
import { STORE_NAMES } from '@common/constants'
import { WIN_MAIN_RENDERER_EVENT_NAME } from '@common/ipcNames'
import { mainOn, mainHandle } from '@common/mainIpc'
import getStore from '@main/utils/store'
export default () => {
mainHandle<LX.SoundEffect.EQPreset[]>(WIN_MAIN_RENDERER_EVENT_NAME.get_sound_effect_eq_preset, async() => {
return getStore(STORE_NAMES.SOUND_EFFECT).get('eqPreset') as LX.SoundEffect.EQPreset[] | null ?? []
})
mainOn<LX.SoundEffect.EQPreset[]>(WIN_MAIN_RENDERER_EVENT_NAME.save_sound_effect_eq_preset, ({ params }) => {
getStore(STORE_NAMES.SOUND_EFFECT).set('eqPreset', params)
})
mainHandle<LX.SoundEffect.ConvolutionPreset[]>(WIN_MAIN_RENDERER_EVENT_NAME.get_sound_effect_convolution_preset, async() => {
return getStore(STORE_NAMES.SOUND_EFFECT).get('convolutionPreset') as LX.SoundEffect.ConvolutionPreset[] | null ?? []
})
mainOn<LX.SoundEffect.ConvolutionPreset[]>(WIN_MAIN_RENDERER_EVENT_NAME.save_sound_effect_convolution_preset, ({ params }) => {
getStore(STORE_NAMES.SOUND_EFFECT).set('convolutionPreset', params)
})
}

View File

@@ -10,3 +10,4 @@ import '@common/types/player'
import '@common/types/desktop_lyric'
import '@common/types/theme'
import '@common/types/ipc_main'
import '@common/types/sound_effect'

View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path
fill="currentColor"
d="M8 13C6.14 13 4.59 14.28 4.14 16H2V18H4.14C4.59 19.72 6.14 21 8 21S11.41 19.72 11.86 18H22V16H11.86C11.41 14.28 9.86 13 8 13M8 19C6.9 19 6 18.1 6 17C6 15.9 6.9 15 8 15S10 15.9 10 17C10 18.1 9.1 19 8 19M19.86 6C19.41 4.28 17.86 3 16 3S12.59 4.28 12.14 6H2V8H12.14C12.59 9.72 14.14 11 16 11S19.41 9.72 19.86 8H22V6H19.86M16 9C14.9 9 14 8.1 14 7C14 5.9 14.9 5 16 5S18 5.9 18 7C18 8.1 17.1 9 16 9Z" />
</svg>

After

Width:  |  Height:  |  Size: 505 B

View File

@@ -56,6 +56,7 @@ const popupStyle = reactive({
const arrowHeight = 9
const arrowWidth = 8
const sidePadding = 50
watch(() => props.visible, (visible) => {
if (!visible || !dom_content.value || !props.btnEl) return
@@ -63,24 +64,24 @@ watch(() => props.visible, (visible) => {
const maxHeight = document.body.clientHeight
const elTop = rect.top - window.lx.rootOffset
const bottomTopVal = elTop + rect.height
const contentHeight = dom_content.value.scrollHeight + arrowHeight + 10
const contentHeight = dom_content.value.scrollHeight + arrowHeight + sidePadding
if (bottomTopVal + contentHeight < maxHeight || (contentHeight > elTop && elTop <= maxHeight - bottomTopVal)) {
isShowTop.value = false
popupStyle.top = bottomTopVal + arrowHeight + 'px'
popupStyle.maxHeight = maxHeight - bottomTopVal - arrowHeight - 10 + 'px'
popupStyle.maxHeight = maxHeight - bottomTopVal - arrowHeight - sidePadding + 'px'
} else {
isShowTop.value = true
let maxContentHeight = elTop - arrowHeight - 10
popupStyle.top = (elTop - (elTop < contentHeight ? elTop : contentHeight) + 10) + 'px'
let maxContentHeight = elTop - arrowHeight - sidePadding
popupStyle.top = (elTop - (elTop < contentHeight ? elTop : contentHeight) + sidePadding) + 'px'
popupStyle.maxHeight = maxContentHeight + 'px'
}
const maxWidth = document.body.clientWidth - 20
let center = dom_content.value.clientWidth / 2
let left = rect.left + rect.width / 2 - window.lx.rootOffset - center
if (left < 10) {
center -= 10 - left
left = 10
if (left < sidePadding) {
center -= sidePadding - left
left = sidePadding
} else if (left + dom_content.value.clientWidth > maxWidth) {
let newLeft = maxWidth - dom_content.value.clientWidth
center = center + left - newLeft

View File

@@ -0,0 +1,92 @@
<template>
<base-btn min :class="[$style.newPreset, {[$style.editing]: isEditing}]" :aria-label="$t('player__sound_effect_biquad_filter_save_btn')" @click="handleEditing($event)">
<svg-icon name="plus" />
<base-input ref="input" :class="$style.newPresetInput" :value="newPresetName" :placeholder="$t('player__sound_effect_biquad_filter_save_input')" @keyup.enter="handleSave($event)" @blur="handleSave($event)" />
</base-btn>
</template>
<script setup>
import { ref, nextTick } from '@common/utils/vueTools'
import { appSetting } from '@renderer/store/setting'
import { saveUserConvolutionPreset } from '@renderer/store/soundEffect'
const isEditing = ref(false)
const input = ref(false)
const newPresetName = ref('')
const handleEditing = () => {
if (isEditing.value) return
// if (!this.newPresetName) this.newPresetName = this.listName
isEditing.value = true
nextTick(() => {
input.value.$el.focus()
})
}
const handleSave = (event) => {
let name = event.target.value.trim()
newPresetName.value = event.target.value = ''
isEditing.value = false
if (!name) return
if (name.length > 20) name = name.substring(0, 20)
saveUserConvolutionPreset({
id: Date.now().toString(),
name,
source: appSetting['player.soundEffect.convolution.fileName'],
mainGain: appSetting['player.soundEffect.convolution.mainGain'],
sendGain: appSetting['player.soundEffect.convolution.sendGain'],
})
}
</script>
<style lang="less" module>
@import '@renderer/assets/styles/layout.less';
.newPreset {
position: relative;
border: 1px dashed var(--color-primary-font-hover);
// background-color: var(--color-main-background);
color: var(--color-primary-font-hover);
opacity: .7;
height: 22px;
&.editing {
opacity: 1;
width: 90px;
svg {
display: none;
}
.newPresetInput {
display: block;
}
}
:global {
.svg-icon {
vertical-align: 0;
}
}
}
.newPresetInput {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
// line-height: 16px;
background: none !important;
font-size: 12px;
text-align: center;
font-family: inherit;
box-sizing: border-box;
padding: 0 3px;
border-radius: 0;
display: none;
&::placeholder {
font-size: 12px;
}
}
</style>

View File

@@ -0,0 +1,99 @@
<template>
<base-btn min :class="[$style.newPreset, {[$style.editing]: isEditing}]" :aria-label="$t('player__sound_effect_biquad_filter_save_btn')" @click="handleEditing($event)">
<svg-icon name="plus" />
<base-input ref="input" :class="$style.newPresetInput" :value="newPresetName" :placeholder="$t('player__sound_effect_biquad_filter_save_input')" @keyup.enter="handleSave($event)" @blur="handleSave($event)" />
</base-btn>
</template>
<script setup>
import { ref, nextTick } from '@common/utils/vueTools'
import { appSetting } from '@renderer/store/setting'
import { saveUserEQPreset } from '@renderer/store/soundEffect'
const isEditing = ref(false)
const input = ref(false)
const newPresetName = ref('')
const handleEditing = () => {
if (isEditing.value) return
// if (!this.newPresetName) this.newPresetName = this.listName
isEditing.value = true
nextTick(() => {
input.value.$el.focus()
})
}
const handleSave = (event) => {
let name = event.target.value.trim()
newPresetName.value = event.target.value = ''
isEditing.value = false
if (!name) return
if (name.length > 20) name = name.substring(0, 20)
saveUserEQPreset({
id: Date.now().toString(),
name,
hz31: appSetting['player.soundEffect.biquadFilter.hz31'],
hz62: appSetting['player.soundEffect.biquadFilter.hz62'],
hz125: appSetting['player.soundEffect.biquadFilter.hz125'],
hz250: appSetting['player.soundEffect.biquadFilter.hz250'],
hz500: appSetting['player.soundEffect.biquadFilter.hz500'],
hz1000: appSetting['player.soundEffect.biquadFilter.hz1000'],
hz2000: appSetting['player.soundEffect.biquadFilter.hz2000'],
hz4000: appSetting['player.soundEffect.biquadFilter.hz4000'],
hz8000: appSetting['player.soundEffect.biquadFilter.hz8000'],
hz16000: appSetting['player.soundEffect.biquadFilter.hz16000'],
})
}
</script>
<style lang="less" module>
@import '@renderer/assets/styles/layout.less';
.newPreset {
position: relative;
border: 1px dashed var(--color-primary-font-hover);
// background-color: var(--color-main-background);
color: var(--color-primary-font-hover);
opacity: .7;
height: 22px;
&.editing {
opacity: 1;
width: 90px;
svg {
display: none;
}
.newPresetInput {
display: block;
}
}
:global {
.svg-icon {
vertical-align: 0;
}
}
}
.newPresetInput {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
// line-height: 16px;
background: none !important;
font-size: 12px;
text-align: center;
font-family: inherit;
box-sizing: border-box;
padding: 0 3px;
border-radius: 0;
display: none;
&::placeholder {
font-size: 12px;
}
}
</style>

View File

@@ -0,0 +1,145 @@
<template>
<div :class="$style.contnet">
<h3 class="player__sound_effect_title">{{ $t('player__sound_effect_convolution') }}</h3>
<div :class="$style.convolution">
<div :class="$style.convolutionList">
<base-checkbox
v-for="item in convolutions"
:id="`player__convolution_${item.name}`"
:key="item.name"
:class="$style.checkbox"
:model-value="appSetting['player.soundEffect.convolution.fileName']"
:label="$t(`player__sound_effect_convolution_file_${item.name}`)"
:value="item.source"
@update:model-value="updateConvolution($event)"
/>
</div>
<div :class="$style.sliderList">
<div :class="$style.sliderItem">
<span :class="$style.label">{{ $t('player__sound_effect_convolution_main_gain') }}</span>
<base-slider-bar :class="$style.slider" :value="appSetting['player.soundEffect.convolution.mainGain']" :min="0" :max="50" @change="handleUpdateMainGain" />
<span :class="[$style.value]">{{ appSetting['player.soundEffect.convolution.mainGain'] * 10 }}%</span>
</div>
<div :class="$style.sliderItem">
<span :class="$style.label">{{ $t('player__sound_effect_convolution_send_gain') }}</span>
<base-slider-bar :class="$style.slider" :value="appSetting['player.soundEffect.convolution.sendGain']" :min="0" :max="50" @change="handleUpdateSendGain" />
<span :class="[$style.value]">{{ appSetting['player.soundEffect.convolution.sendGain'] * 10 }}%</span>
</div>
</div>
</div>
<div :class="['scroll', $style.saveList]">
<base-btn v-for="item in userPresetList" :key="item.id" min @click="handleSetPreset(item)" @contextmenu="handleRemovePreset(item.id)">{{ item.name }}</base-btn>
<AddConvolutionPresetBtn v-if="userPresetList.length < 31" />
</div>
</div>
</template>
<script setup>
import { ref, onMounted } from '@common/utils/vueTools'
import { appSetting, updateSetting } from '@renderer/store/setting'
import { convolutions } from '@renderer/plugins/player'
import AddConvolutionPresetBtn from './AddConvolutionPresetBtn'
import { getUserConvolutionPresetList, removeUserConvolutionPreset } from '@renderer/store/soundEffect'
const updateConvolution = val => {
const target = convolutions.find(c => c.source == val)
const setting = {
'player.soundEffect.convolution.fileName': val,
}
if (target) {
setting['player.soundEffect.convolution.mainGain'] = target.mainGain * 10
setting['player.soundEffect.convolution.sendGain'] = target.sendGain * 10
}
updateSetting(setting)
}
const handleUpdateMainGain = (value) => {
updateSetting({ 'player.soundEffect.convolution.mainGain': Math.round(value) })
}
const handleUpdateSendGain = (value) => {
updateSetting({ 'player.soundEffect.convolution.sendGain': Math.round(value) })
}
const handleSetPreset = (item) => {
updateSetting({
'player.soundEffect.convolution.fileName': item.source,
'player.soundEffect.convolution.mainGain': item.mainGain,
'player.soundEffect.convolution.sendGain': item.sendGain,
})
}
const userPresetList = ref([])
const handleRemovePreset = id => {
removeUserConvolutionPreset(id)
}
onMounted(() => {
getUserConvolutionPresetList().then(list => {
userPresetList.value = list
})
})
</script>
<style lang="less" module>
@import '@renderer/assets/styles/layout.less';
.contnet {
display: flex;
flex-flow: column nowrap;
gap: 3px;
min-height: 0;
}
.convolution {
display: flex;
flex-flow: column wrap;
gap: 15px;
width: 100%;
}
.convolutionList {
display: flex;
flex-flow: row wrap;
gap: 8px;
width: 100%;
}
.checkbox {
margin-right: 10px;
font-size: 12px;
}
.sliderList {
display: flex;
flex-flow: column nowrap;
gap: 15px;
width: 100%;
}
.sliderItem {
display: flex;
flex-flow: row nowrap;
gap: 8px;
}
.slider {
flex: auto;
}
.label {
flex: none;
// width: 50px;
font-size: 12px;
}
.value {
flex: none;
width: 40px;
font-size: 12px;
text-align: center;
&.active {
color: var(--color-primary-font);
}
}
.saveList {
display: flex;
flex-flow: row wrap;
margin-top: 10px;
gap: 10px;
}
</style>

View File

@@ -0,0 +1,126 @@
<template>
<div :class="$style.contnet">
<div class="player__sound_effect_title" :class="$style.header">
<h3>{{ $t('player__sound_effect_panner') }}</h3>
<base-checkbox
id="player__sound_effect_panner_enabled"
:class="$style.checkbox"
:label="$t('player__sound_effect_panner_enabled')"
:model-value="appSetting['player.soundEffect.panner.enable']"
@update:model-value="updateEnabled"
/>
</div>
<div :class="$style.eqList">
<div :class="$style.eqItem">
<span :class="$style.label">{{ $t('player__sound_effect_panner_sound_speed') }}</span>
<base-slider-bar :class="$style.slider" :value="appSetting['player.soundEffect.panner.speed']" :min="1" :max="50" @change="handleUpdateSpeed" />
<span :class="[$style.value, { [$style.active]: appSetting['player.soundEffect.panner.speed'] != 25 }]">{{ appSetting['player.soundEffect.panner.speed'] }}</span>
</div>
<div :class="$style.eqItem">
<span :class="$style.label">{{ $t('player__sound_effect_panner_sound_r') }}</span>
<base-slider-bar :class="$style.slider" :value="appSetting['player.soundEffect.panner.soundR']" :min="1" :max="30" @change="handleUpdateSoundR" />
<span :class="[$style.value, { [$style.active]: appSetting['player.soundEffect.panner.soundR'] != 5 }]">{{ appSetting['player.soundEffect.panner.soundR'] }}</span>
</div>
</div>
</div>
</template>
<script setup>
// import { reactive } from '@common/utils/vueTools'
import { appSetting, updateSetting } from '@renderer/store/setting'
// const setting = reactive({
// enabled: false,
// soundR: 5,
// speed: 25,
// })
const updateEnabled = (enabled) => {
// console.log(enabled)
updateSetting({ 'player.soundEffect.panner.enable': enabled })
}
const handleUpdateSoundR = (value) => {
updateSetting({ 'player.soundEffect.panner.soundR': Math.round(value) })
}
const handleUpdateSpeed = (value) => {
updateSetting({ 'player.soundEffect.panner.speed': Math.round(value) })
}
</script>
<style lang="less" module>
@import '@renderer/assets/styles/layout.less';
.contnet {
padding-top: 15px;
position: relative;
display: flex;
flex-flow: column nowrap;
gap: 8px;
&:before {
.mixin-after;
position: absolute;
top: 0;
height: 1px;
width: 100%;
border-top: 1px dashed var(--color-primary-light-100-alpha-700);
}
}
.header {
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
align-items: center;
padding-bottom: 5px;
// padding-top: 5px;
}
.eqList {
display: flex;
flex-flow: column nowrap;
gap: 15px;
width: 100%;
}
.eqItem {
display: flex;
flex-flow: row nowrap;
gap: 8px;
}
.label {
flex: none;
// width: 50px;
font-size: 12px;
}
.value {
flex: none;
width: 40px;
font-size: 12px;
text-align: center;
&.active {
color: var(--color-primary-font);
}
}
.footer {
display: flex;
flex-flow: row nowrap;
// justify-content: space-between;
justify-content: center;
align-items: center;
// font-size: 13px;
span {
line-height: 1;
}
}
.slider {
flex: auto;
}
.checkbox {
margin-right: 10px;
font-size: 13px;
}
</style>

View File

@@ -0,0 +1,163 @@
<template>
<div :class="$style.contnet">
<div class="player__sound_effect_title" :class="$style.header">
<h3>{{ $t('player__sound_effect_biquad_filter') }}</h3>
<base-btn min @click="handleReset">{{ $t('player__sound_effect_biquad_filter_reset_btn') }}</base-btn>
</div>
<div :class="$style.eqList">
<div v-for="(v, i) in freqs" :key="v" :class="$style.eqItem">
<span :class="$style.label">{{ labels[i] }}</span>
<base-slider-bar :class="$style.slider" :value="appSetting[`player.soundEffect.biquadFilter.hz${v}`]" :min="-15" :max="15" @change="handleUpdate(v, $event)" />
<span :class="$style.value">{{ appSetting[`player.soundEffect.biquadFilter.hz${v}`] }}db</span>
</div>
</div>
<div :class="['scroll', $style.saveList]">
<!-- <base-btn min @click="handleSetPreset(item)">{{ $t(`player__sound_effect_biquad_filter_preset_slow`) }}</base-btn> -->
<base-btn v-for="item in freqsPreset" :key="item.name" min @click="handleSetPreset(item)">{{ $t(`player__sound_effect_biquad_filter_preset_${item.name}`) }}</base-btn>
<base-btn v-for="item in userPresetList" :key="item.id" min @click="handleSetPreset(item)" @contextmenu="handleRemovePreset(item.id)">{{ item.name }}</base-btn>
<AddEQPresetBtn v-if="userPresetList.length < 31" />
</div>
<!-- <div :class="$style.footer">
<base-btn min @click="handleReset">{{ $t('player__sound_effect_biquad_filter_reset_btn') }}</base-btn>
</div> -->
</div>
</template>
<script setup>
import { onMounted, ref } from '@common/utils/vueTools'
import { freqs, freqsPreset } from '@renderer/plugins/player'
import { appSetting, updateSetting } from '@renderer/store/setting'
import AddEQPresetBtn from './AddEQPresetBtn'
import { getUserEQPresetList, removeUserEQPreset } from '@renderer/store/soundEffect'
const labels = freqs.map(num => num < 1000 ? num : `${num / 1000}k`)
const handleUpdate = (key, value) => {
value = Math.round(value)
// values[index] = value
updateSetting({ [`player.soundEffect.biquadFilter.hz${key}`]: value })
// console.log(index, event.target.value, bfs)
}
const handleReset = () => {
const setting = {}
for (const key of freqs) {
setting[`player.soundEffect.biquadFilter.hz${key}`] = 0
}
updateSetting(setting)
}
const handleSetPreset = (item) => {
updateSetting({
'player.soundEffect.biquadFilter.hz31': item.hz31,
'player.soundEffect.biquadFilter.hz62': item.hz62,
'player.soundEffect.biquadFilter.hz125': item.hz125,
'player.soundEffect.biquadFilter.hz250': item.hz250,
'player.soundEffect.biquadFilter.hz500': item.hz500,
'player.soundEffect.biquadFilter.hz1000': item.hz1000,
'player.soundEffect.biquadFilter.hz2000': item.hz2000,
'player.soundEffect.biquadFilter.hz4000': item.hz4000,
'player.soundEffect.biquadFilter.hz8000': item.hz8000,
'player.soundEffect.biquadFilter.hz16000': item.hz16000,
})
}
const userPresetList = ref([])
const handleRemovePreset = id => {
removeUserEQPreset(id)
}
onMounted(() => {
getUserEQPresetList().then(list => {
userPresetList.value = list
})
})
</script>
<style lang="less" module>
@import '@renderer/assets/styles/layout.less';
.contnet {
display: flex;
flex-flow: column nowrap;
gap: 8px;
min-height: 0;
}
.header {
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
align-items: center;
padding-bottom: 5px;
// padding-top: 5px;
}
.eqList {
display: flex;
flex-flow: row wrap;
// gap: 15px;
width: 100%;
justify-content: space-between;
position: relative;
&:before {
.mixin-after;
position: absolute;
left: 50%;
height: 100%;
border-left: 1px dashed var(--color-primary-light-100-alpha-700);
}
}
.eqItem {
display: flex;
flex-flow: row nowrap;
width: 50%;
gap: 8px;
margin-bottom: 15px;
box-sizing: border-box;
&:nth-child(odd) {
padding-right: 10px;
}
&:nth-child(even) {
padding-left: 10px;
}
&:nth-last-child(1), &:nth-last-child(2) {
margin-bottom: 0;
}
}
.label {
flex: none;
width: 40px;
font-size: 12px;
text-align: center;
}
.value {
flex: none;
width: 40px;
font-size: 12px;
text-align: center;
}
.footer {
display: flex;
flex-flow: row nowrap;
// justify-content: space-between;
justify-content: center;
align-items: center;
// font-size: 13px;
span {
line-height: 1;
}
}
.slider {
flex: auto;
}
.saveList {
display: flex;
flex-flow: row wrap;
margin-top: 10px;
gap: 10px;
}
</style>

View File

@@ -0,0 +1,134 @@
<template>
<button :class="$style.btn" :aria-label="$t('player__sound_effect')" @click="visible = true">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" width="90%" viewBox="0 0 24 24" space="preserve">
<use xlink:href="#icon-tune-variant" />
</svg>
</button>
<material-modal :show="visible" bg-close="bg-close" :teleport="teleport" @close="visible = false">
<!-- <main :class="$style.main"> -->
<!-- <h2 :class="$style.title">{{ $t('theme_edit_modal__title') }}</h2> -->
<div :class="$style.content">
<div :class="$style.row">
<AudioConvolution />
<AudioPanner />
</div>
<div :class="$style.row">
<BiquadFilter />
</div>
</div>
<!-- </main> -->
</material-modal>
</template>
<script setup>
import { ref } from '@common/utils/vueTools'
// import useNextTogglePlay from '@renderer/utils/compositions/useNextTogglePlay'
// import useToggleDesktopLyric from '@renderer/utils/compositions/useToggleDesktopLyric'
// import { musicInfo, playMusicInfo } from '@renderer/store/player/state'
// import { saveVolumeIsMute } from '@renderer/store/setting'
// import { volume, isMute } from '@renderer/store/player/volume'
// import fs from 'node:fs'
import BiquadFilter from './BiquadFilter'
import AudioPanner from './AudioPanner'
import AudioConvolution from './AudioConvolution'
defineProps({
teleport: {
type: String,
default: '#root',
},
})
const visible = ref(false)
</script>
<style lang="less" module>
@import '@renderer/assets/styles/layout.less';
.btn {
position: relative;
// color: var(--color-button-font);
justify-content: center;
align-items: center;
transition: color @transition-normal;
cursor: pointer;
background-color: transparent;
border: none;
width: 24px;
display: flex;
flex-flow: column nowrap;
padding: 0;
svg {
transition: opacity @transition-fast;
opacity: .6;
filter: drop-shadow(0 0 1px rgba(0, 0, 0, 0.2));
}
&:hover {
svg {
opacity: .9;
}
}
&:active {
svg {
opacity: 1;
}
}
}
.main {
min-width: 300px;
// max-height: 100%;
// overflow: hidden;
display: flex;
flex-flow: column nowrap;
justify-content: center;
min-height: 0;
}
// .title {
// flex: none;
// font-size: 16px;
// color: var(--color-font);
// line-height: 1.3;
// text-align: center;
// padding: 10px;
// }
.content {
display: flex;
flex-flow: row nowrap;
padding: 0 15px;
margin: 15px 0;
gap: 30px;
position: relative;
min-height: 0;
&:before {
.mixin-after;
position: absolute;
left: 50%;
height: 100%;
border-left: 1px dashed var(--color-primary-light-100-alpha-700);
}
// width: 400px;
:global {
// .player__sound_effect_contnet {
// display: flex;
// }
.player__sound_effect_title {
// margin-bottom: 10px;
font-size: 14px;
padding-bottom: 8px;
}
}
}
.row {
width: 50%;
display: flex;
gap: 15px;
flex-flow: column nowrap;
}
</style>

View File

@@ -14,6 +14,7 @@ div(:class="$style.footerLeftControlBtns")
button(:class="[$style.footerLeftControlBtn, {[$style.active]: isShowPlayComment}]" @click="toggleVisibleComment" :aria-label="$t('comment__show')")
svg(version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' width='95%' viewBox='0 0 24 24' space='preserve')
use(xlink:href='#icon-comment')
common-sound-effect-btn
common-playback-rate-btn
common-volume-btn
common-toggle-play-mode-btn

View File

@@ -9,6 +9,7 @@ import {
} from '@renderer/utils/ipc'
import { appSetting } from '@renderer/store/setting'
import { langS2T, toNewMusicInfo, toOldMusicInfo } from '@renderer/utils'
import { requestMsg } from '@renderer/utils/message'
const getOtherSourcePromises = new Map()
@@ -187,6 +188,7 @@ export const getOnlineOtherSourceMusicUrl = async({ musicInfos, quality, onToggl
return { musicInfo, url, quality: type, isFromCache: false }
// eslint-disable-next-line @typescript-eslint/promise-function-async
}).catch((err: any) => {
if (err.message == requestMsg.tooManyRequests) throw err
console.log(err)
return getOnlineOtherSourceMusicUrl({ musicInfos, quality, onToggleSource, isRefresh, retryedSource })
})
@@ -220,7 +222,7 @@ export const handleGetOnlineMusicUrl = async({ musicInfo, quality, onToggleSourc
return { musicInfo, url, quality: type, isFromCache: false }
}).catch(async(err: any) => {
console.log(err)
if (!allowToggleSource) throw err
if (!allowToggleSource || err.message == requestMsg.tooManyRequests) throw err
onToggleSource()
// eslint-disable-next-line @typescript-eslint/promise-function-async
return await getOtherSource(musicInfo).then(otherSource => {

View File

@@ -52,12 +52,36 @@ const { addDelayNextTimeout: addLoadTimeout, clearDelayNextTimeout: clearLoadTim
* 检查音乐信息是否已更改
*/
const diffCurrentMusicInfo = (curMusicInfo: LX.Music.MusicInfo | LX.Download.ListItem): boolean => {
return curMusicInfo !== playMusicInfo.musicInfo || isPlay.value
// return curMusicInfo !== playMusicInfo.musicInfo || isPlay.value
return gettingUrlId != curMusicInfo.id || curMusicInfo.id != playMusicInfo.musicInfo?.id || isPlay.value
}
let cancelDelayRetry: (() => void) | null = null
const delayRetry = async(musicInfo: LX.Music.MusicInfo | LX.Download.ListItem, isRefresh = false): Promise<string | null> => {
// if (cancelDelayRetry) cancelDelayRetry()
return new Promise<string | null>((resolve, reject) => {
const time = getRandom(2, 6)
setAllStatus(window.i18n.t('player__geting_url_delay_retry', { time }))
const tiemout = setTimeout(() => {
getMusicPlayUrl(musicInfo, isRefresh, true).then((result) => {
cancelDelayRetry = null
resolve(result)
}).catch(async(err: any) => {
cancelDelayRetry = null
reject(err)
})
}, time * 1000)
cancelDelayRetry = () => {
clearTimeout(tiemout)
cancelDelayRetry = null
resolve(null)
}
})
}
const getMusicPlayUrl = async(musicInfo: LX.Music.MusicInfo | LX.Download.ListItem, isRefresh = false, isRetryed = false): Promise<string | null> => {
// this.musicInfo.url = await getMusicPlayUrl(targetSong, type)
setAllStatus(window.i18n.t('player__geting_url'))
if (appSetting['player.autoSkipOnError']) addLoadTimeout()
// const type = getPlayType(appSetting['player.highQuality'], musicInfo)
@@ -79,6 +103,8 @@ const getMusicPlayUrl = async(musicInfo: LX.Music.MusicInfo | LX.Download.ListIt
diffCurrentMusicInfo(musicInfo) ||
err.message == requestMsg.cancelRequest) return null
if (err.message == requestMsg.tooManyRequests) return delayRetry(musicInfo, isRefresh)
if (!isRetryed) return getMusicPlayUrl(musicInfo, isRefresh, true)
throw err
@@ -86,7 +112,9 @@ const getMusicPlayUrl = async(musicInfo: LX.Music.MusicInfo | LX.Download.ListIt
}
export const setMusicUrl = (musicInfo: LX.Music.MusicInfo | LX.Download.ListItem, isRefresh?: boolean) => {
if (appSetting['player.autoSkipOnError']) addLoadTimeout()
// if (appSetting['player.autoSkipOnError']) addLoadTimeout()
if (!diffCurrentMusicInfo(musicInfo)) return
if (cancelDelayRetry) cancelDelayRetry()
gettingUrlId = musicInfo.id
void getMusicPlayUrl(musicInfo, isRefresh).then((url) => {
if (!url) return
@@ -152,8 +180,7 @@ const handlePlay = () => {
}
const musicInfo = playMusicInfo.musicInfo
if (!musicInfo || gettingUrlId == musicInfo.id) return
gettingUrlId &&= ''
if (!musicInfo) return
setStop()
window.app_event.pause()

View File

@@ -31,6 +31,7 @@ import useWatchList from './useWatchList'
import { HOTKEY_PLAYER } from '@common/hotKey'
import { playNext, pause, playPrev, togglePlay } from '@renderer/core/player'
import usePlaybackRate from './usePlaybackRate'
import useSoundEffect from './useSoundEffect'
export default () => {
@@ -41,6 +42,7 @@ export default () => {
usePlayEvent()
useLyric()
useVolume()
useSoundEffect()
usePlaybackRate()
useWatchList()

View File

@@ -0,0 +1,152 @@
import { watch } from '@common/utils/vueTools'
import {
freqs,
getAudioContext,
getBiquadFilter,
setConvolver,
setPannerSoundR,
setPannerSpeed,
startPanner,
stopPanner,
setConvolverMainGain,
setConvolverSendGain,
} from '@renderer/plugins/player'
import { appSetting } from '@renderer/store/setting'
const cache = new Map<string, AudioBuffer>()
const loadBuffer = async(name: string) => new Promise<AudioBuffer>((resolve, reject) => {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const path = require('@static/medias/filters/' + name) as string
if (cache.has(path)) {
resolve(cache.get(path) as AudioBuffer)
return
}
// Load buffer asynchronously
let request = new XMLHttpRequest()
request.open('GET', path, true)
request.responseType = 'arraybuffer'
request.onload = function() {
// Asynchronously decode the audio file data in request.response
void getAudioContext().decodeAudioData(request.response, (buffer) => {
if (!buffer) {
reject(new Error('error decoding file data: ' + path))
return
}
cache.set(path, buffer)
resolve(buffer)
},
function(error) {
reject(error)
console.error('decodeAudioData error', error)
})
}
request.onerror = function() {
reject(new Error('XHR error'))
}
request.send()
})
export default () => {
console.log(appSetting['player.soundEffect.panner.enable'])
if (appSetting['player.soundEffect.panner.enable']) startPanner()
setPannerSoundR(appSetting['player.soundEffect.panner.soundR'] / 10)
setPannerSpeed(2 * (appSetting['player.soundEffect.panner.speed'] / 10))
if (freqs.some(v => appSetting[`player.soundEffect.biquadFilter.hz${v}`] != 0)) {
const bfs = getBiquadFilter()
for (const item of freqs) {
bfs.get(`hz${item}`)!.gain.value = appSetting[`player.soundEffect.biquadFilter.hz${item}`]
}
}
if (appSetting['player.soundEffect.convolution.fileName']) {
void loadBuffer(appSetting['player.soundEffect.convolution.fileName']).then((buffer) => {
setConvolver(buffer, appSetting['player.soundEffect.convolution.mainGain'] / 10, appSetting['player.soundEffect.convolution.sendGain'] / 10)
})
}
watch(() => appSetting['player.soundEffect.panner.enable'], (enable) => {
if (enable) {
startPanner()
} else {
stopPanner()
}
})
watch(() => appSetting['player.soundEffect.panner.soundR'], (soundR) => {
setPannerSoundR(soundR / 10)
})
watch(() => appSetting['player.soundEffect.panner.speed'], (speed) => {
setPannerSpeed(2 * (speed / 10))
})
watch(() => appSetting['player.soundEffect.convolution.fileName'], (fileName) => {
setTimeout(() => {
if (fileName) {
void loadBuffer(fileName).then((buffer) => {
setConvolver(buffer, appSetting['player.soundEffect.convolution.mainGain'] / 10, appSetting['player.soundEffect.convolution.sendGain'] / 10)
})
} else {
setConvolver(null, 0, 0)
}
})
})
watch(() => appSetting['player.soundEffect.convolution.mainGain'], (mainGain) => {
setConvolverMainGain(mainGain / 10)
})
watch(() => appSetting['player.soundEffect.convolution.sendGain'], (sendGain) => {
setConvolverSendGain(sendGain / 10)
})
watch(() => appSetting['player.soundEffect.biquadFilter.hz31'], (hz31) => {
const bfs = getBiquadFilter()
bfs.get('hz31')!.gain.value = hz31
})
watch(() => appSetting['player.soundEffect.biquadFilter.hz62'], (hz62) => {
const bfs = getBiquadFilter()
bfs.get('hz62')!.gain.value = hz62
})
watch(() => appSetting['player.soundEffect.biquadFilter.hz125'], (hz125) => {
const bfs = getBiquadFilter()
bfs.get('hz125')!.gain.value = hz125
})
watch(() => appSetting['player.soundEffect.biquadFilter.hz250'], (hz250) => {
const bfs = getBiquadFilter()
bfs.get('hz250')!.gain.value = hz250
})
watch(() => appSetting['player.soundEffect.biquadFilter.hz500'], (hz500) => {
const bfs = getBiquadFilter()
bfs.get('hz500')!.gain.value = hz500
})
watch(() => appSetting['player.soundEffect.biquadFilter.hz1000'], (hz1000) => {
const bfs = getBiquadFilter()
bfs.get('hz1000')!.gain.value = hz1000
})
watch(() => appSetting['player.soundEffect.biquadFilter.hz2000'], (hz2000) => {
const bfs = getBiquadFilter()
bfs.get('hz2000')!.gain.value = hz2000
})
watch(() => appSetting['player.soundEffect.biquadFilter.hz4000'], (hz4000) => {
const bfs = getBiquadFilter()
bfs.get('hz4000')!.gain.value = hz4000
})
watch(() => appSetting['player.soundEffect.biquadFilter.hz8000'], (hz8000) => {
const bfs = getBiquadFilter()
bfs.get('hz8000')!.gain.value = hz8000
})
watch(() => appSetting['player.soundEffect.biquadFilter.hz16000'], (hz16000) => {
const bfs = getBiquadFilter()
bfs.get('hz16000')!.gain.value = hz16000
})
// window.key_event.on(HOTKEY_PLAYER.volume_up.action, hotkeyVolumeUp)
// window.key_event.on(HOTKEY_PLAYER.volume_down.action, hotkeyVolumeDown)
// window.app_event.on('setPlaybackRate', handleSetPlaybackRate)
// onBeforeUnmount(() => {
// // window.key_event.off(HOTKEY_PLAYER.volume_up.action, hotkeyVolumeUp)
// // window.key_event.off(HOTKEY_PLAYER.volume_down.action, hotkeyVolumeDown)
// window.app_event.off('setPlaybackRate', handleSetPlaybackRate)
// })
}

View File

@@ -2,6 +2,50 @@ let audio: HTMLAudioElement | null = null
let audioContext: AudioContext
let mediaSource: MediaElementAudioSourceNode
let analyser: AnalyserNode
// https://developer.mozilla.org/en-US/docs/Web/API/BaseAudioContext
// https://benzleung.gitbooks.io/web-audio-api-mini-guide/content/chapter5-1.html
export const freqs = [31, 62, 125, 250, 500, 1000, 2000, 4000, 8000, 16000] as const
type Freqs = (typeof freqs)[number]
let biquads: Map<`hz${Freqs}`, BiquadFilterNode>
export const freqsPreset = [
{ name: 'pop', hz31: 6, hz62: 5, hz125: -3, hz250: -2, hz500: 5, hz1000: 4, hz2000: -4, hz4000: -3, hz8000: 6, hz16000: 4 },
{ name: 'dance', hz31: 4, hz62: 3, hz125: -4, hz250: -6, hz500: 0, hz1000: 0, hz2000: 3, hz4000: 4, hz8000: 4, hz16000: 5 },
{ name: 'rock', hz31: 7, hz62: 6, hz125: 2, hz250: 1, hz500: -3, hz1000: -4, hz2000: 2, hz4000: 1, hz8000: 4, hz16000: 5 },
{ name: 'classical', hz31: 6, hz62: 7, hz125: 1, hz250: 2, hz500: -1, hz1000: 1, hz2000: -4, hz4000: -6, hz8000: -7, hz16000: -8 },
{ name: 'vocal', hz31: -5, hz62: -6, hz125: -4, hz250: -3, hz500: 3, hz1000: 4, hz2000: 5, hz4000: 4, hz8000: -3, hz16000: -3 },
{ name: 'slow', hz31: 5, hz62: 4, hz125: 2, hz250: 0, hz500: -2, hz1000: 0, hz2000: 3, hz4000: 6, hz8000: 7, hz16000: 8 },
{ name: 'electronic', hz31: 6, hz62: 5, hz125: 0, hz250: -5, hz500: -4, hz1000: 0, hz2000: 6, hz4000: 8, hz8000: 8, hz16000: 7 },
{ name: 'subwoofer', hz31: 8, hz62: 7, hz125: 5, hz250: 4, hz500: 0, hz1000: 0, hz2000: 0, hz4000: 0, hz8000: 0, hz16000: 0 },
{ name: 'soft', hz31: -5, hz62: -5, hz125: -4, hz250: -4, hz500: 3, hz1000: 2, hz2000: 4, hz4000: 4, hz8000: 0, hz16000: 0 },
] as const
export const convolutions = [
{ name: 'telephone', mainGain: 0.0, sendGain: 3.0, source: 'filter-telephone.wav' }, // 电话
{ name: 's2_r4_bd', mainGain: 1.8, sendGain: 0.9, source: 's2_r4_bd.wav' }, // 教堂
{ name: 'bright_hall', mainGain: 0.8, sendGain: 2.4, source: 'bright-hall.wav' },
{ name: 'cinema_diningroom', mainGain: 0.6, sendGain: 2.3, source: 'cinema-diningroom.wav' },
{ name: 'dining_living_true_stereo', mainGain: 0.6, sendGain: 1.8, source: 'dining-living-true-stereo.wav' },
{ name: 'living_bedroom_leveled', mainGain: 0.6, sendGain: 2.1, source: 'living-bedroom-leveled.wav' },
{ name: 'spreader50_65ms', mainGain: 1, sendGain: 2.5, source: 'spreader50-65ms.wav' },
// { name: 'spreader25_125ms', mainGain: 1, sendGain: 2.5, source: 'spreader25-125ms.wav' },
// { name: 'backslap', mainGain: 1.8, sendGain: 0.8, source: 'backslap1.wav' },
{ name: 's3_r1_bd', mainGain: 1.8, sendGain: 0.8, source: 's3_r1_bd.wav' },
{ name: 'matrix_1', mainGain: 1.5, sendGain: 0.9, source: 'matrix-reverb1.wav' },
{ name: 'matrix_2', mainGain: 1.3, sendGain: 1, source: 'matrix-reverb2.wav' },
{ name: 'cardiod_35_10_spread', mainGain: 1.8, sendGain: 0.6, source: 'cardiod-35-10-spread.wav' },
{ name: 'tim_omni_35_10_magnetic', mainGain: 1, sendGain: 0.2, source: 'tim-omni-35-10-magnetic.wav' },
// { name: 'spatialized', mainGain: 1.8, sendGain: 0.8, source: 'spatialized8.wav' },
// { name: 'zing_long_stereo', mainGain: 0.8, sendGain: 1.8, source: 'zing-long-stereo.wav' },
{ name: 'feedback_spring', mainGain: 1.8, sendGain: 0.8, source: 'feedback-spring.wav' },
// { name: 'tim_omni_rear_blend', mainGain: 1.8, sendGain: 0.8, source: 'tim-omni-rear-blend.wav' },
] as const
let convolver: ConvolverNode
let convolverSourceGainNode: GainNode
let convolverOutputGainNode: GainNode
let convolverDynamicsCompressor: DynamicsCompressorNode
let gainNode: GainNode
let panner: PannerNode
export const soundR = 0.5
export const createAudio = () => {
if (audio) return
@@ -11,21 +55,168 @@ export const createAudio = () => {
audio.preload = 'auto'
}
export const getAnalyser = (): AnalyserNode | null => {
if (!audio) throw new Error('audio not defined')
const initAnalyser = () => {
analyser = audioContext.createAnalyser()
analyser.fftSize = 256
}
if (audioContext == null) {
audioContext = new window.AudioContext()
mediaSource = audioContext.createMediaElementSource(audio)
analyser = audioContext.createAnalyser()
analyser.fftSize = 256
mediaSource.connect(analyser)
analyser.connect(audioContext.destination)
const initBiquadFilter = () => {
biquads = new Map()
let i
for (const item of freqs) {
const filter = audioContext.createBiquadFilter()
biquads.set(`hz${item}`, filter)
filter.type = 'peaking'
filter.frequency.value = item
filter.Q.value = 1.4
filter.gain.value = 0
}
for (i = 1; i < freqs.length; i++) {
(biquads.get(`hz${freqs[i - 1]}`) as BiquadFilterNode).connect(biquads.get(`hz${freqs[i]}`) as BiquadFilterNode)
}
}
const initConvolver = () => {
convolverSourceGainNode = audioContext.createGain()
convolverOutputGainNode = audioContext.createGain()
convolverDynamicsCompressor = audioContext.createDynamicsCompressor()
convolver = audioContext.createConvolver()
convolver.connect(convolverOutputGainNode)
convolverSourceGainNode.connect(convolverDynamicsCompressor)
convolverOutputGainNode.connect(convolverDynamicsCompressor)
}
const initPanner = () => {
panner = audioContext.createPanner()
}
const initGain = () => {
gainNode = audioContext.createGain()
}
const initAdvancedAudioFeatures = () => {
if (audioContext) return
if (!audio) throw new Error('audio not defined')
audioContext = new window.AudioContext()
mediaSource = audioContext.createMediaElementSource(audio)
initAnalyser()
mediaSource.connect(analyser)
// analyser.connect(audioContext.destination)
initBiquadFilter()
analyser.connect(biquads.get(`hz${freqs[0]}`) as BiquadFilterNode)
initConvolver()
const lastBiquadFilter = (biquads.get(`hz${freqs.at(-1) as Freqs}`) as BiquadFilterNode)
lastBiquadFilter.connect(convolverSourceGainNode)
lastBiquadFilter.connect(convolver)
initPanner()
convolverDynamicsCompressor.connect(panner)
initGain()
panner.connect(gainNode)
gainNode.connect(audioContext.destination)
}
export const getAudioContext = () => {
initAdvancedAudioFeatures()
return audioContext
}
export const getAnalyser = (): AnalyserNode | null => {
initAdvancedAudioFeatures()
return analyser
}
export const hasInitedAnalyser = (): boolean => audioContext != null
export const getBiquadFilter = () => {
initAdvancedAudioFeatures()
return biquads
}
// let isConvolverConnected = false
export const setConvolver = (buffer: AudioBuffer | null, mainGain: number, sendGain: number) => {
initAdvancedAudioFeatures()
convolver.buffer = buffer
// console.log(mainGain, sendGain)
if (buffer) {
convolverSourceGainNode.gain.value = mainGain
convolverOutputGainNode.gain.value = sendGain
} else {
convolverSourceGainNode.gain.value = 1
convolverOutputGainNode.gain.value = 0
}
}
export const setConvolverMainGain = (gain: number) => {
if (convolverSourceGainNode.gain.value == gain) return
// console.log(gain)
convolverSourceGainNode.gain.value = gain
}
export const setConvolverSendGain = (gain: number) => {
if (convolverOutputGainNode.gain.value == gain) return
// console.log(gain)
convolverOutputGainNode.gain.value = gain
}
let pannerInfo = {
x: 0,
y: 0,
z: 0,
soundR: 0.5,
rad: 0,
speed: 1,
intv: null as NodeJS.Timeout | null,
}
const setPannerXYZ = (nx: number, ny: number, nz: number) => {
pannerInfo.x = nx
pannerInfo.y = ny
pannerInfo.z = nz
// console.log(pannerInfo)
panner.positionX.value = nx * pannerInfo.soundR
panner.positionY.value = ny * pannerInfo.soundR
panner.positionZ.value = nz * pannerInfo.soundR
}
export const setPannerSoundR = (r: number) => {
pannerInfo.soundR = r
}
export const setPannerSpeed = (speed: number) => {
pannerInfo.speed = speed
if (pannerInfo.intv) startPanner()
}
export const stopPanner = () => {
if (pannerInfo.intv) {
clearInterval(pannerInfo.intv)
pannerInfo.intv = null
pannerInfo.rad = 0
}
panner.positionX.value = 0
panner.positionY.value = 0
panner.positionZ.value = 0
}
export const startPanner = () => {
initAdvancedAudioFeatures()
if (pannerInfo.intv) {
clearInterval(pannerInfo.intv)
pannerInfo.intv = null
pannerInfo.rad = 0
}
pannerInfo.intv = setInterval(() => {
pannerInfo.rad += 1
if (pannerInfo.rad > 360) pannerInfo.rad -= 360
setPannerXYZ(Math.sin(pannerInfo.rad * Math.PI / 180), Math.cos(pannerInfo.rad * Math.PI / 180), Math.cos(pannerInfo.rad * Math.PI / 180))
}, pannerInfo.speed * 10)
}
export const hasInitedAdvancedAudioFeatures = (): boolean => audioContext != null
export const setResource = (src: string) => {
if (audio) audio.src = src

View File

@@ -0,0 +1,56 @@
import { reactive, toRaw } from '@common/utils/vueTools'
import { getUserSoundEffectConvolutionPresetList, getUserSoundEffectEQPresetList, saveUserSoundEffectConvolutionPresetList, saveUserSoundEffectEQPresetList } from '@renderer/utils/ipc'
let userEqPresetList: LX.SoundEffect.EQPreset[] | null = null
export const getUserEQPresetList = async() => {
if (userEqPresetList == null) {
userEqPresetList = reactive(await getUserSoundEffectEQPresetList())
}
return userEqPresetList
}
export const saveUserEQPreset = async(preset: LX.SoundEffect.EQPreset) => {
if (userEqPresetList == null) {
userEqPresetList = reactive(await getUserSoundEffectEQPresetList())
}
const target = userEqPresetList.find(p => p.id == preset.id)
if (target) Object.assign(target, preset)
else userEqPresetList.push(preset)
saveUserSoundEffectEQPresetList(toRaw(userEqPresetList))
}
export const removeUserEQPreset = async(id: string) => {
if (userEqPresetList == null) {
userEqPresetList = reactive(await getUserSoundEffectEQPresetList())
}
const index = userEqPresetList.findIndex(p => p.id == id)
if (index < 0) return
userEqPresetList.splice(index, 1)
saveUserSoundEffectEQPresetList(toRaw(userEqPresetList))
}
let userConvolutionPresetList: LX.SoundEffect.ConvolutionPreset[] | null = null
export const getUserConvolutionPresetList = async() => {
if (userEqPresetList == null) {
userConvolutionPresetList = reactive(await getUserSoundEffectConvolutionPresetList())
}
return userConvolutionPresetList
}
export const saveUserConvolutionPreset = async(preset: LX.SoundEffect.ConvolutionPreset) => {
if (userConvolutionPresetList == null) {
userConvolutionPresetList = reactive(await getUserSoundEffectConvolutionPresetList())
}
const target = userConvolutionPresetList.find(p => p.id == preset.id)
if (target) Object.assign(target, preset)
else userConvolutionPresetList.push(preset)
saveUserSoundEffectConvolutionPresetList(toRaw(userConvolutionPresetList))
}
export const removeUserConvolutionPreset = async(id: string) => {
if (userConvolutionPresetList == null) {
userConvolutionPresetList = reactive(await getUserSoundEffectConvolutionPresetList())
}
const index = userConvolutionPresetList.findIndex(p => p.id == id)
if (index < 0) return
userConvolutionPresetList.splice(index, 1)
saveUserSoundEffectConvolutionPresetList(toRaw(userConvolutionPresetList))
}

View File

@@ -13,3 +13,4 @@ import '@common/types/desktop_lyric'
import '@common/types/ipc_renderer'
import '@common/types/config_files'
import '@common/types/music_metadata'
import '@common/types/sound_effect'

View File

@@ -291,6 +291,22 @@ export const getSystemFonts = async() => {
})
}
export const getUserSoundEffectEQPresetList = async() => {
return await rendererInvoke<LX.SoundEffect.EQPreset[]>(WIN_MAIN_RENDERER_EVENT_NAME.get_sound_effect_eq_preset)
}
export const saveUserSoundEffectEQPresetList = (list: LX.SoundEffect.EQPreset[]) => {
rendererSend<LX.SoundEffect.EQPreset[]>(WIN_MAIN_RENDERER_EVENT_NAME.save_sound_effect_eq_preset, list)
}
export const getUserSoundEffectConvolutionPresetList = async() => {
return await rendererInvoke<LX.SoundEffect.ConvolutionPreset[]>(WIN_MAIN_RENDERER_EVENT_NAME.get_sound_effect_convolution_preset)
}
export const saveUserSoundEffectConvolutionPresetList = (list: LX.SoundEffect.ConvolutionPreset[]) => {
rendererSend<LX.SoundEffect.ConvolutionPreset[]>(WIN_MAIN_RENDERER_EVENT_NAME.save_sound_effect_convolution_preset, list)
}
export const allHotKeys = markRaw({
local: [

View File

@@ -5,4 +5,5 @@ export const requestMsg = {
// unachievable: '哦No😱...接口无法访问了!已帮你切换到临时接口,重试下看能不能播放吧~',
notConnectNetwork: '无法连接到服务器',
cancelRequest: '取消http请求',
tooManyRequests: '服务器繁忙',
} as const

View File

@@ -13,7 +13,11 @@ const api_test = {
family: 4,
})
requestObj.promise = requestObj.promise.then(({ body }) => {
return body.code === 0 ? Promise.resolve({ type, url: body.data }) : Promise.reject(new Error(requestMsg.fail))
switch (body.code) {
case 0: return Promise.resolve({ type, url: body.data })
case 429: return Promise.reject(new Error(requestMsg.tooManyRequests))
default: return Promise.reject(new Error(requestMsg.fail))
}
})
return requestObj
},

View File

@@ -13,7 +13,11 @@ const api_test = {
family: 4,
})
requestObj.promise = requestObj.promise.then(({ body }) => {
return body.code === 0 ? Promise.resolve({ type, url: body.data }) : Promise.reject(new Error(requestMsg.fail))
switch (body.code) {
case 0: return Promise.resolve({ type, url: body.data })
case 429: return Promise.reject(new Error(requestMsg.tooManyRequests))
default: return Promise.reject(new Error(requestMsg.fail))
}
})
return requestObj
},

View File

@@ -1,4 +1,5 @@
import { httpFetch } from '../../request'
import { requestMsg } from '../../message'
import { headers, timeout } from '../options'
import { dnsLookup } from '../utils'
@@ -12,7 +13,11 @@ const api_temp = {
family: 4,
})
requestObj.promise = requestObj.promise.then(({ body }) => {
return body.code === 0 ? Promise.resolve({ type, url: body.data }) : Promise.reject(new Error(body.msg))
switch (body.code) {
case 0: return Promise.resolve({ type, url: body.data })
case 429: return Promise.reject(new Error(requestMsg.tooManyRequests))
default: return Promise.reject(new Error(body.msg))
}
})
return requestObj
},

View File

@@ -24,7 +24,11 @@ const api_test = {
family: 4,
})
requestObj.promise = requestObj.promise.then(({ body }) => {
return body.code === 0 ? Promise.resolve({ type, url: body.data }) : Promise.reject(new Error(requestMsg.fail))
switch (body.code) {
case 0: return Promise.resolve({ type, url: body.data })
case 429: return Promise.reject(new Error(requestMsg.tooManyRequests))
default: return Promise.reject(new Error(requestMsg.fail))
}
})
return requestObj
},

View File

@@ -13,7 +13,11 @@ const api_test = {
family: 4,
})
requestObj.promise = requestObj.promise.then(({ body }) => {
return body.code === 0 ? Promise.resolve({ type, url: body.data }) : Promise.reject(new Error(requestMsg.fail))
switch (body.code) {
case 0: return Promise.resolve({ type, url: body.data })
case 429: return Promise.reject(new Error(requestMsg.tooManyRequests))
default: return Promise.reject(new Error(requestMsg.fail))
}
})
return requestObj
},

View File

@@ -13,7 +13,11 @@ const api_messoer = {
family: 4,
})
requestObj.promise = requestObj.promise.then(({ body }) => {
return body.code === 0 ? Promise.resolve({ type, url: body.data }) : Promise.reject(new Error(requestMsg.fail))
switch (body.code) {
case 0: return Promise.resolve({ type, url: body.data })
case 429: return Promise.reject(new Error(requestMsg.tooManyRequests))
default: return Promise.reject(new Error(requestMsg.fail))
}
})
return requestObj
},

View File

@@ -244,7 +244,7 @@ export default {
userName: item.Nick ? item.Nick.substring(1) : '',
images: item.Pic ? [item.Pic] : [],
avatar: item.Avatar,
location: item.Location ? ('来自' + item.Location) : '',
location: item.Location ? item.Location : '',
userId: item.EncryptUin,
likedCount: item.PraiseNum,
reply: item.SubComments

View File

@@ -13,7 +13,11 @@ const api_test = {
family: 4,
})
requestObj.promise = requestObj.promise.then(({ body }) => {
return body.code === 0 ? Promise.resolve({ type, url: body.data }) : Promise.reject(new Error(requestMsg.fail))
switch (body.code) {
case 0: return Promise.resolve({ type, url: body.data })
case 429: return Promise.reject(new Error(requestMsg.tooManyRequests))
default: return Promise.reject(new Error(requestMsg.fail))
}
})
return requestObj
},

View File

@@ -18,7 +18,7 @@
<ul ref="dom_lists_list" class="scroll" :class="[$style.listsContent, { [$style.sortable]: isModDown }]">
<li
class="default-list" :class="[$style.listsItem, {[$style.active]: defaultList.id == listId}, {[$style.clicked]: rightClickItemIndex == -2}, {[$style.fetching]: fetchingListStatus[defaultList.id]}]"
:aria-label="defaultList.name" :aria-selected="defaultList.id == listId"
:aria-label="$t(defaultList.name)" :aria-selected="defaultList.id == listId"
@contextmenu="handleListsItemRigthClick($event, -2)" @click="handleListToggle(defaultList.id)"
>
<!-- <div v-if="defaultList.id == listId" :class="$style.activeIcon">
@@ -35,7 +35,7 @@
</li>
<li
class="default-list" :class="[$style.listsItem, {[$style.active]: loveList.id == listId}, {[$style.clicked]: rightClickItemIndex == -1}, {[$style.fetching]: fetchingListStatus[loveList.id]}]"
:aria-label="loveList.name" :aria-selected="loveList.id == listId"
:aria-label="$t(loveList.name)" :aria-selected="loveList.id == listId"
@contextmenu="handleListsItemRigthClick($event, -1)" @click="handleListToggle(loveList.id)"
>
<span :class="$style.listsLabel">

View File

@@ -29,7 +29,7 @@ dd(:aria-label="$t('setting__play_mediaDevice_title')")
<script>
import { ref, onBeforeUnmount, watch } from '@common/utils/vueTools'
import { hasInitedAnalyser } from '@renderer/plugins/player'
import { hasInitedAdvancedAudioFeatures } from '@renderer/plugins/player'
import { dialog } from '@renderer/plugins/Dialog'
import { useI18n } from '@renderer/plugins/i18n'
import { appSetting, updateSetting } from '@renderer/store/setting'
@@ -56,7 +56,7 @@ export default {
const mediaDeviceId = ref(appSetting['player.mediaDeviceId'])
const handleMediaDeviceIdChnage = async() => {
if (hasInitedAnalyser()) {
if (hasInitedAdvancedAudioFeatures()) {
await dialog({
message: t('setting__play_media_device_error_tip'),
confirmButtonText: t('alert_button_text'),

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.