新增桌面歌词
parent
25fc0226aa
commit
2a81d41c2c
|
@ -7,6 +7,7 @@ const Spinnies = require('spinnies')
|
|||
|
||||
const mainConfig = require('./main/webpack.config.prod')
|
||||
const rendererConfig = require('./renderer/webpack.config.prod')
|
||||
const rendererLyricConfig = require('./renderer-lyric/webpack.config.prod')
|
||||
|
||||
const errorLog = chalk.bgRed.white(' ERROR ') + ' '
|
||||
const okayLog = chalk.bgGreen.white(' OKAY ') + ' '
|
||||
|
@ -18,6 +19,7 @@ function build() {
|
|||
const spinners = new Spinnies({ color: 'blue' })
|
||||
spinners.add('main', { text: 'main building' })
|
||||
spinners.add('renderer', { text: 'renderer building' })
|
||||
spinners.add('renderer-lyric', { text: 'renderer-lyric building' })
|
||||
let results = ''
|
||||
|
||||
// m.on('success', () => {
|
||||
|
@ -52,6 +54,15 @@ function build() {
|
|||
console.error(`\n${err}\n`)
|
||||
process.exit(1)
|
||||
}),
|
||||
pack(rendererLyricConfig).then(result => {
|
||||
results += result + '\n\n'
|
||||
spinners.succeed('renderer-lyric', { text: 'renderer-lyric build success!' })
|
||||
}).catch(err => {
|
||||
spinners.fail('renderer-lyric', { text: 'renderer-lyric build fail :(' })
|
||||
console.log(`\n ${errorLog}failed to build renderer-lyric process`)
|
||||
console.error(`\n${err}\n`)
|
||||
process.exit(1)
|
||||
}),
|
||||
]).then(handleSuccess)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,22 +1,27 @@
|
|||
const path = require('path')
|
||||
const webpack = require('webpack')
|
||||
const HTMLPlugin = require('html-webpack-plugin')
|
||||
const VueLoaderPlugin = require('vue-loader/lib/plugin')
|
||||
const HTMLPlugin = require('html-webpack-plugin')
|
||||
|
||||
const vueLoaderConfig = require('../vue-loader.config')
|
||||
|
||||
|
||||
module.exports = {
|
||||
target: 'web',
|
||||
entry: path.join(__dirname, '../../src/renderer/main.js'),
|
||||
target: 'electron-renderer',
|
||||
entry: {
|
||||
'renderer-lyric': path.join(__dirname, '../../src/renderer-lyric/main.js'),
|
||||
},
|
||||
output: {
|
||||
path: path.join(__dirname, '../../dist/web'),
|
||||
filename: '[name].js',
|
||||
libraryTarget: 'commonjs2',
|
||||
path: path.join(__dirname, '../../dist/electron'),
|
||||
publicPath: './',
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': path.join(__dirname, '../../src/renderer'),
|
||||
common: path.join(__dirname, '../../src/common'),
|
||||
},
|
||||
extensions: ['*', '.js', '.vue', '.json', '.css'],
|
||||
extensions: ['*', '.js', '.json', '.vue', '.node'],
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
|
@ -57,22 +62,26 @@ module.exports = {
|
|||
},
|
||||
{
|
||||
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
|
||||
use: {
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
limit: 10000,
|
||||
name: 'imgs/[name].[ext]',
|
||||
},
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
limit: 10000,
|
||||
name: 'imgs/[name]--[folder].[ext]',
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
limit: 10000,
|
||||
name: 'media/[name]--[folder].[ext]',
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
|
||||
use: {
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
limit: 10000,
|
||||
name: 'fonts/[name].[ext]',
|
||||
},
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
limit: 10000,
|
||||
name: 'fonts/[name]--[folder].[ext]',
|
||||
},
|
||||
},
|
||||
],
|
||||
|
@ -81,17 +90,13 @@ module.exports = {
|
|||
maxEntrypointSize: 300000,
|
||||
},
|
||||
plugins: [
|
||||
new VueLoaderPlugin(),
|
||||
new HTMLPlugin({
|
||||
filename: 'index.html',
|
||||
template: path.resolve(__dirname, '../../src/index.pug'),
|
||||
nodeModules: false,
|
||||
filename: 'lyric.html',
|
||||
template: path.join(__dirname, '../../src/renderer-lyric/index.pug'),
|
||||
isProd: process.env.NODE_ENV == 'production',
|
||||
browser: process.browser,
|
||||
__dirname,
|
||||
}),
|
||||
new webpack.DefinePlugin({
|
||||
'process.env.IS_WEB': 'true',
|
||||
}),
|
||||
new VueLoaderPlugin(),
|
||||
],
|
||||
}
|
|
@ -1,8 +1,9 @@
|
|||
const path = require('path')
|
||||
const webpack = require('webpack')
|
||||
const merge = require('webpack-merge')
|
||||
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
|
||||
|
||||
const merge = require('webpack-merge')
|
||||
|
||||
const baseConfig = require('./webpack.config.base')
|
||||
|
||||
const { mergeCSSLoaderDev } = require('../utils')
|
||||
|
@ -10,10 +11,6 @@ const { mergeCSSLoaderDev } = require('../utils')
|
|||
module.exports = merge(baseConfig, {
|
||||
mode: 'development',
|
||||
devtool: 'eval-source-map',
|
||||
output: {
|
||||
filename: '[name].js',
|
||||
path: path.join(__dirname, '../../dist/web'),
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
|
@ -30,7 +27,7 @@ module.exports = merge(baseConfig, {
|
|||
}),
|
||||
},
|
||||
{
|
||||
test: /\.styl$/,
|
||||
test: /\.styl(:?us)?$/,
|
||||
oneOf: mergeCSSLoaderDev({
|
||||
loader: 'stylus-loader',
|
||||
options: {
|
||||
|
@ -41,14 +38,16 @@ module.exports = merge(baseConfig, {
|
|||
],
|
||||
},
|
||||
plugins: [
|
||||
new webpack.HotModuleReplacementPlugin(),
|
||||
new webpack.NoEmitOnErrorsPlugin(),
|
||||
new FriendlyErrorsPlugin(),
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': {
|
||||
NODE_ENV: '"development"',
|
||||
ELECTRON_DISABLE_SECURITY_WARNINGS: 'true',
|
||||
},
|
||||
__static: `"${path.join(__dirname, '../../src/static').replace(/\\/g, '\\\\')}"`,
|
||||
}),
|
||||
new FriendlyErrorsPlugin(),
|
||||
new webpack.HotModuleReplacementPlugin(),
|
||||
new webpack.NoEmitOnErrorsPlugin(),
|
||||
],
|
||||
performance: {
|
||||
hints: false,
|
|
@ -1,21 +1,25 @@
|
|||
const path = require('path')
|
||||
const webpack = require('webpack')
|
||||
const CopyWebpackPlugin = require('copy-webpack-plugin')
|
||||
const merge = require('webpack-merge')
|
||||
const TerserPlugin = require('terser-webpack-plugin')
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
|
||||
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
|
||||
const TerserPlugin = require('terser-webpack-plugin')
|
||||
const CopyWebpackPlugin = require('copy-webpack-plugin')
|
||||
const merge = require('webpack-merge')
|
||||
|
||||
const baseConfig = require('./webpack.config.base')
|
||||
|
||||
const { mergeCSSLoaderProd } = require('../utils')
|
||||
const { dependencies } = require('../../package.json')
|
||||
|
||||
let whiteListedModules = ['vue']
|
||||
|
||||
|
||||
module.exports = merge(baseConfig, {
|
||||
mode: 'production',
|
||||
devtool: false,
|
||||
output: {
|
||||
filename: '[name].[chunkhash:8].js',
|
||||
},
|
||||
externals: [
|
||||
...Object.keys(dependencies || {}).filter(d => !whiteListedModules.includes(d)),
|
||||
],
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
|
@ -32,7 +36,7 @@ module.exports = merge(baseConfig, {
|
|||
}),
|
||||
},
|
||||
{
|
||||
test: /\.styl$/,
|
||||
test: /\.styl(:?us)?$/,
|
||||
oneOf: mergeCSSLoaderProd({
|
||||
loader: 'stylus-loader',
|
||||
options: {
|
||||
|
@ -43,20 +47,21 @@ module.exports = merge(baseConfig, {
|
|||
],
|
||||
},
|
||||
plugins: [
|
||||
new CopyWebpackPlugin([
|
||||
{
|
||||
from: path.join(__dirname, '../../src/static'),
|
||||
to: path.join(__dirname, '../dist/web/static'),
|
||||
ignore: ['.*'],
|
||||
},
|
||||
]),
|
||||
new CopyWebpackPlugin({
|
||||
patterns: [
|
||||
{
|
||||
from: path.join(__dirname, '../../src/static'),
|
||||
to: path.join(__dirname, '../../dist/electron/static'),
|
||||
},
|
||||
],
|
||||
}),
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': {
|
||||
NODE_ENV: '"production"',
|
||||
},
|
||||
}),
|
||||
new MiniCssExtractPlugin({
|
||||
filename: '[name].[contentHash:8].css',
|
||||
filename: '[name].css',
|
||||
}),
|
||||
new webpack.NamedChunksPlugin(),
|
||||
],
|
||||
|
@ -69,26 +74,14 @@ module.exports = merge(baseConfig, {
|
|||
}),
|
||||
new OptimizeCSSAssetsPlugin({}),
|
||||
],
|
||||
splitChunks: {
|
||||
cacheGroups: {
|
||||
// chunks: 'all',
|
||||
vendors: {
|
||||
test: /[\\/]node_modules[\\/]/,
|
||||
name: 'vendors',
|
||||
enforce: true,
|
||||
chunks: 'all',
|
||||
},
|
||||
styles: {
|
||||
name: 'styles',
|
||||
test: /\.(css|less)$/,
|
||||
chunks: 'all',
|
||||
enforce: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
runtimeChunk: true,
|
||||
},
|
||||
performance: {
|
||||
hints: 'warning',
|
||||
},
|
||||
node: {
|
||||
__dirname: false,
|
||||
__filename: false,
|
||||
},
|
||||
})
|
||||
|
||||
|
|
@ -92,7 +92,7 @@ module.exports = {
|
|||
plugins: [
|
||||
new HTMLPlugin({
|
||||
filename: 'index.html',
|
||||
template: path.join(__dirname, '../../src/index.pug'),
|
||||
template: path.join(__dirname, '../../src/renderer/index.pug'),
|
||||
isProd: process.env.NODE_ENV == 'production',
|
||||
browser: process.browser,
|
||||
__dirname,
|
||||
|
|
|
@ -12,6 +12,7 @@ const webpackHotMiddleware = require('webpack-hot-middleware')
|
|||
|
||||
const mainConfig = require('./main/webpack.config.dev')
|
||||
const rendererConfig = require('./renderer/webpack.config.dev')
|
||||
const rendererLyricConfig = require('./renderer-lyric/webpack.config.dev')
|
||||
|
||||
let electronProcess = null
|
||||
let manualRestart = false
|
||||
|
@ -65,6 +66,53 @@ function startRenderer() {
|
|||
})
|
||||
}
|
||||
|
||||
function startRendererLyric() {
|
||||
return new Promise((resolve, reject) => {
|
||||
// rendererConfig.entry.renderer = [path.join(__dirname, 'dev-client')].concat(rendererConfig.entry.renderer)
|
||||
// rendererConfig.mode = 'development'
|
||||
const compiler = webpack(rendererLyricConfig)
|
||||
hotMiddleware = webpackHotMiddleware(compiler, {
|
||||
log: false,
|
||||
heartbeat: 2500,
|
||||
})
|
||||
|
||||
compiler.hooks.compilation.tap('compilation', compilation => {
|
||||
// console.log(Object.keys(compilation.hooks))
|
||||
HtmlWebpackPlugin.getHooks(compilation).beforeEmit.tapAsync('html-webpack-plugin-after-emit', (data, cb) => {
|
||||
hotMiddleware.publish({ action: 'reload' })
|
||||
cb()
|
||||
})
|
||||
})
|
||||
|
||||
compiler.hooks.done.tap('done', stats => {
|
||||
// logStats('Renderer', 'Compile done')
|
||||
// logStats('Renderer', stats)
|
||||
})
|
||||
|
||||
const server = new WebpackDevServer(
|
||||
compiler,
|
||||
{
|
||||
contentBase: path.join(__dirname, '../'),
|
||||
quiet: true,
|
||||
hot: true,
|
||||
historyApiFallback: true,
|
||||
clientLogLevel: 'warning',
|
||||
overlay: {
|
||||
errors: true,
|
||||
},
|
||||
before(app, ctx) {
|
||||
app.use(hotMiddleware)
|
||||
ctx.middleware.waitUntilValid(() => {
|
||||
resolve()
|
||||
})
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
server.listen(9081)
|
||||
})
|
||||
}
|
||||
|
||||
function startMain() {
|
||||
return new Promise((resolve, reject) => {
|
||||
// mainConfig.entry.main = [path.join(__dirname, '../src/main/index.dev.js')].concat(mainConfig.entry.main)
|
||||
|
@ -140,6 +188,7 @@ function init() {
|
|||
const spinners = new Spinnies({ color: 'blue' })
|
||||
spinners.add('main', { text: 'main compiling' })
|
||||
spinners.add('renderer', { text: 'renderer compiling' })
|
||||
spinners.add('renderer-lyric', { text: 'renderer-lyric compiling' })
|
||||
function handleSuccess(name) {
|
||||
spinners.succeed(name, { text: name + ' compile success!' })
|
||||
}
|
||||
|
@ -149,6 +198,7 @@ function init() {
|
|||
|
||||
Promise.all([
|
||||
startRenderer().then(() => handleSuccess('renderer')).catch(() => handleFail('renderer')),
|
||||
startRendererLyric().then(() => handleSuccess('renderer-lyric')).catch(() => handleFail('renderer-lyric')),
|
||||
startMain().then(() => handleSuccess('main')).catch(() => handleFail('main')),
|
||||
]).then(startElectron).catch(err => {
|
||||
console.error(err)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
50
package.json
50
package.json
|
@ -40,7 +40,13 @@
|
|||
"publish:linux:deb:x86": "cross-env ARCH=x86 electron-builder -l=deb --ia32 -p onTagOrDraft",
|
||||
"publish:linux:rpm": "cross-env ARCH=x64 electron-builder -l=rpm -p onTagOrDraft",
|
||||
"publish:linux:pacman": "cross-env ARCH=x64 electron-builder -l=pacman -p onTagOrDraft",
|
||||
"pack:linux": "node build-config/pack.js && electron-builder -l",
|
||||
"pack:linux": "node build-config/pack.js && npm run pack:linux:deb && npm run pack:linux:appImage && npm run pack:linux:rpm && npm run pack:linux:pacman",
|
||||
"pack:linux:appImage": "cross-env ARCH=x64 electron-builder -l=AppImage",
|
||||
"pack:linux:deb": "npm run pack:linux:deb:x64 && npm run pack:linux:deb:x86",
|
||||
"pack:linux:deb:x64": "cross-env ARCH=x64 electron-builder -l=deb --x64",
|
||||
"pack:linux:deb:x86": "cross-env ARCH=x86 electron-builder -l=deb --ia32",
|
||||
"pack:linux:rpm": "cross-env ARCH=x64 electron-builder -l=rpm",
|
||||
"pack:linux:pacman": "cross-env ARCH=x64 electron-builder -l=pacman",
|
||||
"pack:mac": "node build-config/pack.js && electron-builder -m=dmg",
|
||||
"pack:dir": "node build-config/pack.js && electron-builder --dir",
|
||||
"dev": "node build-config/runner-dev.js",
|
||||
|
@ -49,8 +55,8 @@
|
|||
"clean": "rimraf dist && rimraf build",
|
||||
"build:main": "cross-env NODE_ENV=production webpack --config build-config/main/webpack.config.prod.js --progress --hide-modules",
|
||||
"build:renderer": "cross-env NODE_ENV=production webpack --config build-config/renderer/webpack.config.prod.js --progress --hide-modules",
|
||||
"build:web": "npm run clean:web && cross-env NODE_ENV=production webpack --config build-config/web/webpack.config.prod.js --progress --hide-modules",
|
||||
"build": "npm run clean:electron && npm run build:main && npm run build:renderer",
|
||||
"build:renderer-lyric": "cross-env NODE_ENV=production webpack --config build-config/renderer-lyric/webpack.config.prod.js --progress --hide-modules",
|
||||
"build": "npm run clean:electron && npm run build:main && npm run build:renderer && npm run build:renderer-lyric",
|
||||
"lint": "eslint --ext .js,.vue -f ./node_modules/eslint-formatter-friendly src",
|
||||
"lint:fix": "eslint --ext .js,.vue -f ./node_modules/eslint-formatter-friendly --fix src"
|
||||
},
|
||||
|
@ -154,10 +160,10 @@
|
|||
},
|
||||
"homepage": "https://github.com/lyswhut/lx-music-desktop#readme",
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.9.6",
|
||||
"@babel/core": "^7.10.2",
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
||||
"@babel/polyfill": "^7.8.7",
|
||||
"@babel/preset-env": "^7.9.6",
|
||||
"@babel/polyfill": "^7.10.1",
|
||||
"@babel/preset-env": "^7.10.2",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"babel-loader": "^8.1.0",
|
||||
"babel-minify-webpack-plugin": "^0.3.1",
|
||||
|
@ -166,36 +172,36 @@
|
|||
"cfonts": "^2.8.2",
|
||||
"chalk": "^4.0.0",
|
||||
"changelog-parser": "^2.8.0",
|
||||
"copy-webpack-plugin": "^6.0.1",
|
||||
"copy-webpack-plugin": "^6.0.2",
|
||||
"core-js": "^3.6.5",
|
||||
"cos-nodejs-sdk-v5": "^2.5.20",
|
||||
"cos-nodejs-sdk-v5": "^2.6.0",
|
||||
"cross-env": "^7.0.2",
|
||||
"css-loader": "^3.5.3",
|
||||
"del": "^5.1.0",
|
||||
"electron": "^9.0.0",
|
||||
"electron-builder": "^22.6.1",
|
||||
"electron": "^9.0.3",
|
||||
"electron-builder": "^22.7.0",
|
||||
"electron-debug": "^3.1.0",
|
||||
"electron-devtools-installer": "^3.0.0",
|
||||
"eslint": "^7.1.0",
|
||||
"eslint": "^7.2.0",
|
||||
"eslint-config-standard": "^14.1.1",
|
||||
"eslint-formatter-friendly": "^7.0.0",
|
||||
"eslint-loader": "^4.0.2",
|
||||
"eslint-plugin-html": "^6.0.2",
|
||||
"eslint-plugin-import": "^2.20.2",
|
||||
"eslint-plugin-import": "^2.21.1",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-promise": "^4.2.1",
|
||||
"eslint-plugin-standard": "^4.0.1",
|
||||
"file-loader": "^6.0.0",
|
||||
"friendly-errors-webpack-plugin": "^1.7.0",
|
||||
"html-webpack-plugin": "^4.3.0",
|
||||
"less": "^3.11.1",
|
||||
"less": "^3.11.3",
|
||||
"less-loader": "^6.1.0",
|
||||
"markdown-it": "^11.0.0",
|
||||
"mini-css-extract-plugin": "^0.9.0",
|
||||
"optimize-css-assets-webpack-plugin": "^5.0.3",
|
||||
"postcss-loader": "^3.0.0",
|
||||
"postcss-pxtorem": "^5.1.1",
|
||||
"pug": "^2.0.4",
|
||||
"pug": "^3.0.0",
|
||||
"pug-loader": "^2.4.0",
|
||||
"pug-plain-loader": "^1.0.0",
|
||||
"raw-loader": "^4.0.1",
|
||||
|
@ -203,7 +209,7 @@
|
|||
"spinnies": "^0.5.1",
|
||||
"stylus": "^0.54.7",
|
||||
"stylus-loader": "^3.0.2",
|
||||
"terser-webpack-plugin": "^3.0.1",
|
||||
"terser-webpack-plugin": "^3.0.3",
|
||||
"url-loader": "^4.1.0",
|
||||
"vue-loader": "^15.9.2",
|
||||
"vue-style-loader": "^4.1.2",
|
||||
|
@ -217,19 +223,19 @@
|
|||
"dependencies": {
|
||||
"crypto-js": "^4.0.0",
|
||||
"dnscache": "^1.0.2",
|
||||
"electron-log": "^4.2.0",
|
||||
"electron-store": "^5.1.1",
|
||||
"electron-log": "^4.2.1",
|
||||
"electron-store": "^5.2.0",
|
||||
"electron-updater": "^4.3.1",
|
||||
"iconv-lite": "^0.5.1",
|
||||
"iconv-lite": "^0.6.0",
|
||||
"image-size": "^0.8.3",
|
||||
"js-htmlencode": "^0.3.0",
|
||||
"lrc-file-parser": "^1.0.3",
|
||||
"lrc-file-parser": "^1.0.5",
|
||||
"needle": "^2.5.0",
|
||||
"node-id3": "^0.1.16",
|
||||
"node-id3": "^0.1.17",
|
||||
"request": "^2.88.2",
|
||||
"vue": "^2.6.11",
|
||||
"vue-i18n": "^8.17.7",
|
||||
"vue-router": "^3.2.0",
|
||||
"vue-i18n": "^8.18.2",
|
||||
"vue-router": "^3.3.2",
|
||||
"vuex": "^3.4.0",
|
||||
"vuex-router-sync": "^5.0.0"
|
||||
}
|
||||
|
|
|
@ -8,16 +8,11 @@ module.exports = {
|
|||
unitPrecision: 5,
|
||||
propList: [
|
||||
'font', 'font-size',
|
||||
'line-height',
|
||||
'letter-spacing',
|
||||
'padding', 'margin',
|
||||
'padding-left', 'padding-right',
|
||||
'padding-top', 'padding-bottom',
|
||||
'margin-left', 'margin-right',
|
||||
'margin-top', 'margin-bottom',
|
||||
'padding-*', 'margin-*',
|
||||
'height', 'width',
|
||||
'max-width', 'max-height',
|
||||
'min-width', 'min-height',
|
||||
'*-height', '*-width',
|
||||
'flex', '::-webkit-scrollbar',
|
||||
'top', 'left', 'bottom', 'right',
|
||||
'border-radius',
|
||||
|
|
|
@ -6,11 +6,14 @@
|
|||
- 新增自定义列表,创建列表的按钮在表头`#`左侧,鼠标移上去才会显示;编辑列表名字时,按`ESC`键可快速取消编辑,按回车键或使输入框失去焦点即可保存列表名字,右击列表可编辑已创建的列表,“试听列表”与“我的收藏”两个列表固定不可编辑
|
||||
- 改变排行榜布局,新增更多排行榜
|
||||
- 新增我的列表右键菜单复制歌曲名选项
|
||||
- 新增桌面歌词,默认关闭,可到设置或者托盘菜单开启;调整字体大小、透明度时,鼠标左击按钮正常调整,右击微调;已知windows下贴边拖拽调整歌词窗口大小时可能会导致窗口变黑,这时只需将窗口拖屏幕离边缘再拖回去即可;Windows 7未开启Aero效果时桌面歌词会有问题,详情看常见问题解决;Linux版桌面歌词有问题,以后再尝试优化;
|
||||
- 新增“清热板蓝”皮肤
|
||||
|
||||
### 优化
|
||||
|
||||
- 改进歌曲切换时的歌词滚动效果
|
||||
- 优化批量添加、删除播放列表的歌曲操作逻辑,大幅提升流畅度
|
||||
- 改进歌单列表展示
|
||||
|
||||
### 修复
|
||||
|
||||
|
@ -22,6 +25,7 @@
|
|||
- 修复错误更新试听列表外的歌曲时间的问题
|
||||
- 修复网易音乐源歌单、排行榜歌曲列表加载显示的数量与实际不对的问题
|
||||
- 修复歌曲图片链接没有扩展名的情况下无法嵌入图片的问题
|
||||
- 修复无法检测最新版本时弹窗提示的显示
|
||||
|
||||
### 更变
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import path from 'path'
|
||||
import os from 'os'
|
||||
const path = require('path')
|
||||
const os = require('os')
|
||||
|
||||
const defaultSetting = {
|
||||
version: '1.0.26',
|
||||
version: '1.0.29',
|
||||
player: {
|
||||
togglePlayMethod: 'listLoop',
|
||||
highQuality: false,
|
||||
|
@ -11,6 +11,21 @@ const defaultSetting = {
|
|||
mediaDeviceId: 'default',
|
||||
isMediaDeviceRemovedStopPlay: false,
|
||||
},
|
||||
desktopLyric: {
|
||||
enable: false,
|
||||
isLock: false,
|
||||
isAlwaysOnTop: false,
|
||||
width: 600,
|
||||
height: 700,
|
||||
x: -1,
|
||||
y: -1,
|
||||
theme: 'green',
|
||||
style: {
|
||||
fontSize: 125,
|
||||
opacity: 80,
|
||||
isZoomActiveLrc: true,
|
||||
},
|
||||
},
|
||||
list: {
|
||||
isShowAlbumName: true,
|
||||
isShowSource: true,
|
||||
|
@ -26,7 +41,7 @@ const defaultSetting = {
|
|||
},
|
||||
leaderboard: {
|
||||
source: 'kw',
|
||||
tabId: 'kwbiaosb',
|
||||
tabId: 'kw__16',
|
||||
},
|
||||
songList: {
|
||||
source: 'kg',
|
||||
|
@ -79,4 +94,5 @@ const overwriteSetting = {
|
|||
if (new Date().getMonth() < 2) defaultSetting.themeId = 9
|
||||
|
||||
|
||||
export { defaultSetting, overwriteSetting }
|
||||
exports.defaultSetting = defaultSetting
|
||||
exports.overwriteSetting = overwriteSetting
|
|
@ -1,4 +1,5 @@
|
|||
const { ipcMain, ipcRenderer } = require('electron')
|
||||
const names = require('./ipcNames')
|
||||
|
||||
|
||||
exports.mainOn = (event, callback) => {
|
||||
|
@ -15,6 +16,9 @@ exports.mainHandleOnce = (name, callback) => {
|
|||
ipcMain.handleOnce(name, callback)
|
||||
}
|
||||
|
||||
exports.mainSend = (window, name, params) => {
|
||||
window.webContents.send(name, params)
|
||||
}
|
||||
|
||||
exports.rendererSend = (name, params) => {
|
||||
ipcRenderer.send(name, params)
|
||||
|
@ -29,3 +33,5 @@ exports.rendererOn = (name, callback) => {
|
|||
exports.rendererOnce = (name, callback) => {
|
||||
ipcRenderer.once(name, callback)
|
||||
}
|
||||
|
||||
exports.NAMES = names
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
const names = {
|
||||
mainWindow: {
|
||||
focus: 'focus',
|
||||
close: 'close',
|
||||
min: 'min',
|
||||
max: 'max',
|
||||
set_app_name: 'set_app_name',
|
||||
clear_cache: 'clear_cache',
|
||||
get_cache_size: 'get_cache_size',
|
||||
get_env_params: 'get_env_params',
|
||||
|
||||
set_music_meta: 'set_music_meta',
|
||||
progress: 'progress',
|
||||
change_tray: 'change_tray',
|
||||
quit_update: 'quit_update',
|
||||
update_available: 'update_available',
|
||||
update_error: 'update_error',
|
||||
update_progress: 'update_progress',
|
||||
update_downloaded: 'update_downloaded',
|
||||
update_not_available: 'update_not_available',
|
||||
set_ignore_mouse_events: 'set_ignore_mouse_events',
|
||||
set_app_setting: 'set_app_setting',
|
||||
set_window_size: 'set_window_size',
|
||||
show_save_dialog: 'show_save_dialog',
|
||||
|
||||
handle_request: 'handle_request',
|
||||
cancel_request: 'cancel_request',
|
||||
|
||||
handle_xm_verify_open: 'handle_xm_verify_open',
|
||||
handle_xm_verify_close: 'handle_xm_verify_close',
|
||||
select_dir: 'select_dir',
|
||||
|
||||
restart_window: 'restart_window',
|
||||
|
||||
handle_kw_decode_lyric: 'handle_kw_decode_lyric',
|
||||
get_lyric_info: 'get_lyric_info',
|
||||
set_lyric_info: 'set_lyric_info',
|
||||
set_config: 'set_config',
|
||||
},
|
||||
winLyric: {
|
||||
close: 'close',
|
||||
set_lyric_info: 'set_lyric_info',
|
||||
get_lyric_info: 'get_lyric_info',
|
||||
set_lyric_config: 'set_lyric_config',
|
||||
get_lyric_config: 'get_lyric_config',
|
||||
set_win_bounds: 'set_win_bounds',
|
||||
},
|
||||
}
|
||||
|
||||
for (const item of Object.keys(names)) {
|
||||
let name = names[item]
|
||||
for (const key of Object.keys(name)) {
|
||||
name[key] = `${item}_${name[key]}`
|
||||
}
|
||||
}
|
||||
|
||||
exports.mainWindow = names.mainWindow
|
||||
exports.winLyric = names.winLyric
|
|
@ -1,8 +1,170 @@
|
|||
const log = require('electron-log')
|
||||
const Store = require('electron-store')
|
||||
const { defaultSetting, overwriteSetting } = require('./defaultSetting')
|
||||
const apiSource = require('../renderer/utils/music/api-source-info')
|
||||
|
||||
exports.isLinux = process.platform == 'linux'
|
||||
exports.isWin = process.platform == 'win32'
|
||||
exports.isMac = process.platform == 'darwin'
|
||||
|
||||
|
||||
/**
|
||||
* 生成节流函数
|
||||
* @param {*} fn
|
||||
* @param {*} delay
|
||||
*/
|
||||
exports.throttle = (fn, delay = 100) => {
|
||||
let timer = null
|
||||
let _args = null
|
||||
return function(...args) {
|
||||
_args = args
|
||||
if (timer) return
|
||||
timer = setTimeout(() => {
|
||||
timer = null
|
||||
fn.apply(this, _args)
|
||||
}, delay)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成防抖函数
|
||||
* @param {*} fn
|
||||
* @param {*} delay
|
||||
*/
|
||||
exports.debounce = (fn, delay = 100) => {
|
||||
let timer = null
|
||||
let _args = null
|
||||
return function(...args) {
|
||||
_args = args
|
||||
if (timer) clearTimeout(timer)
|
||||
timer = setTimeout(() => {
|
||||
timer = null
|
||||
fn.apply(this, _args)
|
||||
}, delay)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
exports.log = log
|
||||
|
||||
|
||||
exports.checkVersion = (currentVer, targetVer) => {
|
||||
// console.log(currentVer)
|
||||
// console.log(targetVer)
|
||||
currentVer = currentVer.split('.')
|
||||
targetVer = targetVer.split('.')
|
||||
let maxLen = Math.max(currentVer.length, targetVer.length)
|
||||
if (currentVer.length < maxLen) {
|
||||
for (let index = 0, len = maxLen - currentVer.length; index < len; index++) {
|
||||
currentVer.push(0)
|
||||
}
|
||||
}
|
||||
if (targetVer.length < maxLen) {
|
||||
for (let index = 0, len = maxLen - targetVer.length; index < len; index++) {
|
||||
targetVer.push(0)
|
||||
}
|
||||
}
|
||||
for (let index = 0; index < currentVer.length; index++) {
|
||||
if (parseInt(currentVer[index]) < parseInt(targetVer[index])) return true
|
||||
if (parseInt(currentVer[index]) > parseInt(targetVer[index])) return false
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
exports.isObject = item => item && typeof item === 'object' && !Array.isArray(item)
|
||||
|
||||
/**
|
||||
* 对象深度合并
|
||||
* @param {} target 要合并源对象
|
||||
* @param {} source 要合并目标对象
|
||||
*/
|
||||
exports.objectDeepMerge = (target, source, mergedObj) => {
|
||||
if (!mergedObj) {
|
||||
mergedObj = new Set()
|
||||
mergedObj.add(target)
|
||||
}
|
||||
let base = {}
|
||||
Object.keys(source).forEach(item => {
|
||||
if (exports.isObject(source[item])) {
|
||||
if (mergedObj.has(source[item])) return
|
||||
if (!exports.isObject(target[item])) target[item] = {}
|
||||
mergedObj.add(source[item])
|
||||
exports.objectDeepMerge(target[item], source[item], mergedObj)
|
||||
return
|
||||
}
|
||||
base[item] = source[item]
|
||||
})
|
||||
Object.assign(target, base)
|
||||
}
|
||||
|
||||
exports.mergeSetting = (setting, version) => {
|
||||
const defaultVersion = defaultSetting.version
|
||||
if (!version) {
|
||||
if (setting) {
|
||||
version = setting.version
|
||||
delete setting.version
|
||||
}
|
||||
}
|
||||
|
||||
if (!setting) {
|
||||
setting = defaultSetting
|
||||
} else if (exports.checkVersion(version, defaultVersion)) {
|
||||
exports.objectDeepMerge(defaultSetting, setting)
|
||||
exports.objectDeepMerge(defaultSetting, overwriteSetting)
|
||||
setting = defaultSetting
|
||||
}
|
||||
|
||||
if (!apiSource.some(api => api.id === setting.apiSource && !api.disabled)) {
|
||||
let api = apiSource.find(api => !api.disabled)
|
||||
if (api) setting.apiSource = api.id
|
||||
}
|
||||
|
||||
return { setting, version: defaultVersion }
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化设置
|
||||
* @param {*} setting
|
||||
*/
|
||||
exports.initSetting = () => {
|
||||
const electronStore_list = new Store({
|
||||
name: 'playList',
|
||||
})
|
||||
const electronStore_config = new Store({
|
||||
name: 'config',
|
||||
})
|
||||
let setting = electronStore_config.get('setting')
|
||||
if (!electronStore_config.get('version') && setting) { // 迁移配置
|
||||
electronStore_config.set('version', electronStore_config.get('setting.version'))
|
||||
electronStore_config.delete('setting.version')
|
||||
const list = electronStore_config.get('list')
|
||||
if (list) {
|
||||
if (list.defaultList) electronStore_list.set('defaultList', list.defaultList)
|
||||
if (list.loveList) electronStore_list.set('loveList', list.loveList)
|
||||
electronStore_config.delete('list')
|
||||
}
|
||||
const downloadList = electronStore_config.get('download')
|
||||
if (downloadList) {
|
||||
if (downloadList.list) electronStore_list.set('downloadList', downloadList.list)
|
||||
electronStore_config.delete('download')
|
||||
}
|
||||
}
|
||||
|
||||
// 迁移列表滚动位置设置 ~0.18.3
|
||||
if (setting && setting.list.scroll) {
|
||||
let scroll = setting.list.scroll
|
||||
electronStore_list.set('defaultList.location', scroll.locations.defaultList || 0)
|
||||
electronStore_list.set('loveList.location', scroll.locations.loveList || 0)
|
||||
electronStore_config.delete('setting.list.scroll')
|
||||
electronStore_config.set('setting.list.isSaveScrollLocation', scroll.enable)
|
||||
}
|
||||
|
||||
const { version: settingVersion, setting: newSetting } = exports.mergeSetting(setting, electronStore_config.get('version'))
|
||||
|
||||
// 重置 ^0.18.2 排行榜ID
|
||||
if (!newSetting.leaderboard.tabId.includes('__')) newSetting.leaderboard.tabId = 'kw__16'
|
||||
|
||||
electronStore_config.set('version', settingVersion)
|
||||
electronStore_config.set('setting', newSetting)
|
||||
return newSetting
|
||||
}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
const parseEnv = () => {
|
||||
const params = {}
|
||||
const rx = /^-\w+/
|
||||
for (let param of process.argv) {
|
||||
if (!rx.test(param)) continue
|
||||
param = param.substring(1)
|
||||
let index = param.indexOf('=')
|
||||
if (index < 0) {
|
||||
params[param] = true
|
||||
} else {
|
||||
params[param.substring(0, index)] = param.substring(index + 1)
|
||||
}
|
||||
}
|
||||
return params
|
||||
}
|
||||
|
||||
global.envParams.cmdParams = parseEnv()
|
|
@ -0,0 +1,4 @@
|
|||
global.envParams = {}
|
||||
|
||||
require('./cmdParams')
|
||||
require('./screen')
|
|
@ -0,0 +1,11 @@
|
|||
const { app, screen } = require('electron')
|
||||
|
||||
const initScreenParams = () => {
|
||||
global.envParams.workAreaSize = screen.getPrimaryDisplay().workAreaSize
|
||||
}
|
||||
|
||||
|
||||
app.on('ready', () => {
|
||||
screen.on('display-metrics-changed', initScreenParams)
|
||||
initScreenParams()
|
||||
})
|
|
@ -0,0 +1,9 @@
|
|||
const { common: COMMON_EVENT_NAME, mainWindow: MAIN_WINDOW_EVENT_NAME } = require('./events/_name')
|
||||
const { mainSend, NAMES: { mainWindow: ipcMainWindowNames } } = require('./../common/ipc')
|
||||
|
||||
|
||||
global.lx_event.common.on(COMMON_EVENT_NAME.config, name => {
|
||||
if (MAIN_WINDOW_EVENT_NAME.name === name) return
|
||||
if (global.modals.mainWindow) mainSend(global.modals.mainWindow, ipcMainWindowNames.set_config, global.appSetting)
|
||||
})
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
const { EventEmitter } = require('events')
|
||||
const { common: COMMON_EVENT_NAME } = require('./_name')
|
||||
const { updateSetting } = require('../utils')
|
||||
|
||||
class Common extends EventEmitter {
|
||||
initSetting() {
|
||||
this.emit(COMMON_EVENT_NAME.initConfig)
|
||||
this.emit(COMMON_EVENT_NAME.config, null)
|
||||
}
|
||||
|
||||
setAppConfig(config, name) {
|
||||
if (config) updateSetting(config)
|
||||
this.emit(COMMON_EVENT_NAME.config, name)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Common
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
const { EventEmitter } = require('events')
|
||||
const { mainWindow: MAIN_WINDOW_EVENT_NAME } = require('./_name')
|
||||
|
||||
class MainWindow extends EventEmitter {
|
||||
setLyricInfo(info) {
|
||||
this.emit(MAIN_WINDOW_EVENT_NAME.setLyricInfo, info)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = MainWindow
|
|
@ -1,5 +1,23 @@
|
|||
exports.common = {
|
||||
initConfig: 'initConfig',
|
||||
config: 'config',
|
||||
}
|
||||
|
||||
exports.mainWindow = {
|
||||
name: 'mainWindow',
|
||||
setLyricInfo: 'setLyricInfo',
|
||||
destroy: 'destroy',
|
||||
}
|
||||
|
||||
exports.tray = {
|
||||
name: 'tray',
|
||||
create: 'create',
|
||||
destroy: 'destroy',
|
||||
}
|
||||
|
||||
exports.winLyric = {
|
||||
name: 'winLyric',
|
||||
create: 'create',
|
||||
close: 'close',
|
||||
inited: 'inited',
|
||||
}
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
global.lx_event = {}
|
||||
|
||||
const Tray = require('./tray')
|
||||
const Common = require('./Common')
|
||||
const MainWindow = require('./MainWindow')
|
||||
const Tray = require('./Tray')
|
||||
const WinLyric = require('./WinLyric')
|
||||
|
||||
if (!global.lx_event.common) global.lx_event.common = new Common()
|
||||
if (!global.lx_event.mainWindow) global.lx_event.mainWindow = new MainWindow()
|
||||
if (!global.lx_event.tray) global.lx_event.tray = new Tray()
|
||||
if (!global.lx_event.winLyric) global.lx_event.winLyric = new WinLyric()
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
const { EventEmitter } = require('events')
|
||||
const { winLyric: WIN_LYRIC_EVENT_NAME } = require('./_name')
|
||||
// const { updateSetting } = require('../utils')
|
||||
|
||||
class WinLyric extends EventEmitter {
|
||||
create() {
|
||||
this.emit(WIN_LYRIC_EVENT_NAME.create)
|
||||
}
|
||||
|
||||
close() {
|
||||
this.emit(WIN_LYRIC_EVENT_NAME.close)
|
||||
}
|
||||
|
||||
inited() {
|
||||
this.emit(WIN_LYRIC_EVENT_NAME.inited)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = WinLyric
|
|
@ -6,14 +6,15 @@ if (!app.requestSingleInstanceLock()) {
|
|||
app.quit()
|
||||
return
|
||||
}
|
||||
if (!global.modals) global.modals = {}
|
||||
app.on('second-instance', (event, argv, cwd) => {
|
||||
if (global.mainWindow) {
|
||||
if (global.mainWindow.isMinimized()) {
|
||||
global.mainWindow.restore()
|
||||
} else if (global.mainWindow.isVisible()) {
|
||||
global.mainWindow.focus()
|
||||
if (global.modals.mainWindow) {
|
||||
if (global.modals.mainWindow.isMinimized()) {
|
||||
global.modals.mainWindow.restore()
|
||||
} else if (global.modals.mainWindow.isVisible()) {
|
||||
global.modals.mainWindow.focus()
|
||||
} else {
|
||||
global.mainWindow.show()
|
||||
global.modals.mainWindow.show()
|
||||
}
|
||||
} else {
|
||||
app.quit()
|
||||
|
@ -21,11 +22,10 @@ app.on('second-instance', (event, argv, cwd) => {
|
|||
})
|
||||
|
||||
const isDev = global.isDev = process.env.NODE_ENV !== 'production'
|
||||
require('./env')
|
||||
const { navigationUrlWhiteList } = require('../common/config')
|
||||
const { getAppSetting, parseEnv, getWindowSizeInfo } = require('./utils')
|
||||
const { isMac, isLinux } = require('../common/utils')
|
||||
|
||||
global.envParams = parseEnv()
|
||||
const { getWindowSizeInfo } = require('./utils')
|
||||
const { isMac, isLinux, initSetting } = require('../common/utils')
|
||||
|
||||
|
||||
// https://github.com/electron/electron/issues/22691
|
||||
|
@ -67,6 +67,7 @@ app.on('web-contents-created', (event, contents) => {
|
|||
|
||||
require('../common/error')
|
||||
require('./events')
|
||||
require('./event')
|
||||
require('./rendererEvents')
|
||||
const winEvent = require('./rendererEvents/winEvent')
|
||||
const autoUpdate = require('./utils/autoUpdate')
|
||||
|
@ -88,7 +89,7 @@ function createWindow() {
|
|||
/**
|
||||
* Initial window options
|
||||
*/
|
||||
global.mainWindow = new BrowserWindow({
|
||||
global.modals.mainWindow = new BrowserWindow({
|
||||
height: windowSizeInfo.height,
|
||||
useContentSize: true,
|
||||
width: windowSizeInfo.width,
|
||||
|
@ -107,32 +108,32 @@ function createWindow() {
|
|||
},
|
||||
})
|
||||
|
||||
global.mainWindow.loadURL(winURL)
|
||||
global.modals.mainWindow.loadURL(winURL)
|
||||
|
||||
winEvent(global.mainWindow)
|
||||
winEvent(global.modals.mainWindow)
|
||||
// mainWindow.webContents.openDevTools()
|
||||
|
||||
if (!isDev) autoUpdate()
|
||||
}
|
||||
|
||||
function init() {
|
||||
global.appSetting = getAppSetting()
|
||||
global.appSetting = initSetting()
|
||||
global.lx_event.common.initSetting()
|
||||
createWindow()
|
||||
global.lx_event.tray.create()
|
||||
}
|
||||
|
||||
app.on('ready', init)
|
||||
|
||||
app.on('activate', () => {
|
||||
if (global.mainWindow) {
|
||||
if (global.mainWindow.isMinimized()) {
|
||||
global.mainWindow.restore()
|
||||
} else if (global.mainWindow.isVisible()) {
|
||||
global.mainWindow.focus()
|
||||
if (global.modals.mainWindow) {
|
||||
if (global.modals.mainWindow.isMinimized()) {
|
||||
global.modals.mainWindow.restore()
|
||||
} else if (global.modals.mainWindow.isVisible()) {
|
||||
global.modals.mainWindow.focus()
|
||||
} else {
|
||||
global.mainWindow.show()
|
||||
global.modals.mainWindow.show()
|
||||
}
|
||||
} else if (global.mainWindow === null) {
|
||||
} else if (global.modals.mainWindow === null) {
|
||||
init()
|
||||
}
|
||||
})
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
require('./appMenu')
|
||||
require('./winLyric')
|
||||
require('./tray')
|
||||
|
|
|
@ -1,27 +1,30 @@
|
|||
const { app, Tray, Menu } = require('electron')
|
||||
const { isWin } = require('../../common/utils')
|
||||
const { tray: TRAY_EVENT_NAME } = require('../events/_name')
|
||||
const { tray: TRAY_EVENT_NAME, common: COMMON_EVENT_NAME } = require('../events/_name')
|
||||
const path = require('path')
|
||||
global.lx_event.tray.on(TRAY_EVENT_NAME.create, () => {
|
||||
createTray()
|
||||
})
|
||||
global.lx_event.tray.on(TRAY_EVENT_NAME.destroy, () => {
|
||||
destroyTray()
|
||||
let isEnableTray = null
|
||||
global.lx_event.common.on(COMMON_EVENT_NAME.config, sourceName => {
|
||||
if (sourceName === TRAY_EVENT_NAME.name) return
|
||||
if (isEnableTray !== global.appSetting.tray.isToTray) {
|
||||
isEnableTray = global.appSetting.tray.isToTray
|
||||
global.appSetting.tray.isToTray ? createTray() : destroyTray()
|
||||
}
|
||||
createMenu(global.modals.tray)
|
||||
})
|
||||
|
||||
const createTray = () => {
|
||||
if ((global.tray && !global.tray.isDestroyed()) || !global.appSetting.tray || !global.appSetting.tray.isShow) return
|
||||
if ((global.modals.tray && !global.modals.tray.isDestroyed()) || !global.appSetting.tray || !global.appSetting.tray.isShow) return
|
||||
|
||||
const iconPath = path.join(global.__static, 'images/tray', isWin ? 'trayTemplate@2x.ico' : 'trayTemplate.png')
|
||||
|
||||
// 托盘
|
||||
global.tray = new Tray(iconPath)
|
||||
global.modals.tray = new Tray(iconPath)
|
||||
|
||||
global.tray.setToolTip('洛雪音乐助手')
|
||||
if (isWin) createMenu(global.tray)
|
||||
global.tray.setIgnoreDoubleClickEvents(true)
|
||||
global.tray.on('click', () => {
|
||||
const mainWindow = global.mainWindow
|
||||
global.modals.tray.setToolTip('洛雪音乐助手')
|
||||
createMenu(global.modals.tray)
|
||||
global.modals.tray.setIgnoreDoubleClickEvents(true)
|
||||
global.modals.tray.on('click', () => {
|
||||
const mainWindow = global.modals.mainWindow
|
||||
if (!mainWindow) return
|
||||
mainWindow.isVisible()
|
||||
? mainWindow.focus()
|
||||
|
@ -30,21 +33,55 @@ const createTray = () => {
|
|||
}
|
||||
|
||||
const destroyTray = () => {
|
||||
if (!global.tray) return
|
||||
global.tray.destroy()
|
||||
global.tray = null
|
||||
if (!global.modals.tray) return
|
||||
global.modals.tray.destroy()
|
||||
global.modals.tray = null
|
||||
}
|
||||
|
||||
const createMenu = tray => {
|
||||
const contextMenu = Menu.buildFromTemplate([
|
||||
{
|
||||
label: '退出',
|
||||
click() {
|
||||
global.isQuitting = true
|
||||
app.quit()
|
||||
},
|
||||
if (!global.modals.tray || !isWin) return
|
||||
let menu = []
|
||||
menu.push(global.appSetting.desktopLyric.enable ? {
|
||||
label: '关闭桌面歌词',
|
||||
click() {
|
||||
global.lx_event.common.setAppConfig({ desktopLyric: { enable: false } }, TRAY_EVENT_NAME.name)
|
||||
},
|
||||
])
|
||||
} : {
|
||||
label: '开启桌面歌词',
|
||||
click() {
|
||||
global.lx_event.common.setAppConfig({ desktopLyric: { enable: true } }, TRAY_EVENT_NAME.name)
|
||||
},
|
||||
})
|
||||
menu.push(global.appSetting.desktopLyric.isLock ? {
|
||||
label: '解锁桌面歌词',
|
||||
click() {
|
||||
global.lx_event.common.setAppConfig({ desktopLyric: { isLock: false } }, TRAY_EVENT_NAME.name)
|
||||
},
|
||||
} : {
|
||||
label: '锁定桌面歌词',
|
||||
click() {
|
||||
global.lx_event.common.setAppConfig({ desktopLyric: { isLock: true } }, TRAY_EVENT_NAME.name)
|
||||
},
|
||||
})
|
||||
menu.push(global.appSetting.desktopLyric.isAlwaysOnTop ? {
|
||||
label: '取消置顶',
|
||||
click() {
|
||||
global.lx_event.common.setAppConfig({ desktopLyric: { isAlwaysOnTop: false } }, TRAY_EVENT_NAME.name)
|
||||
},
|
||||
} : {
|
||||
label: '置顶歌词',
|
||||
click() {
|
||||
global.lx_event.common.setAppConfig({ desktopLyric: { isAlwaysOnTop: true } }, TRAY_EVENT_NAME.name)
|
||||
},
|
||||
})
|
||||
menu.push({
|
||||
label: '退出',
|
||||
click() {
|
||||
global.isQuitting = true
|
||||
app.quit()
|
||||
},
|
||||
})
|
||||
const contextMenu = Menu.buildFromTemplate(menu)
|
||||
tray.setContextMenu(contextMenu)
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
const { common: COMMON_EVENT_NAME, winLyric: WIN_LYRIC_EVENT_NAME, mainWindow: MAIN_WINDOW_EVENT_NAME } = require('../../events/_name')
|
||||
const { mainSend, NAMES: { winLyric: ipcWinLyricNames } } = require('../../../common/ipc')
|
||||
|
||||
let isLock = null
|
||||
let isEnable = null
|
||||
let isAlwaysOnTop = null
|
||||
const setLrcConfig = isForceSet => {
|
||||
let desktopLyric = global.appSetting.desktopLyric
|
||||
if (isEnable != desktopLyric.enable) {
|
||||
isEnable = desktopLyric.enable
|
||||
if (desktopLyric.enable) {
|
||||
global.lx_event.winLyric.create()
|
||||
} else {
|
||||
global.lx_event.winLyric.close()
|
||||
}
|
||||
}
|
||||
if (global.modals.lyricWindow) {
|
||||
mainSend(global.modals.lyricWindow, ipcWinLyricNames.set_lyric_config, desktopLyric)
|
||||
if (isForceSet || isLock != desktopLyric.isLock) {
|
||||
isLock = desktopLyric.isLock
|
||||
if (desktopLyric.isLock) {
|
||||
global.modals.lyricWindow.setIgnoreMouseEvents(true, { forward: false })
|
||||
} else {
|
||||
global.modals.lyricWindow.setIgnoreMouseEvents(false)
|
||||
}
|
||||
}
|
||||
if (isForceSet || isAlwaysOnTop != desktopLyric.isAlwaysOnTop) {
|
||||
isAlwaysOnTop = desktopLyric.isAlwaysOnTop
|
||||
global.modals.lyricWindow.setAlwaysOnTop(desktopLyric.isAlwaysOnTop, 'screen-saver')
|
||||
}
|
||||
}
|
||||
}
|
||||
global.lx_event.common.on(COMMON_EVENT_NAME.config, name => {
|
||||
if (WIN_LYRIC_EVENT_NAME.name === name) return
|
||||
setLrcConfig(false)
|
||||
})
|
||||
global.lx_event.winLyric.on(WIN_LYRIC_EVENT_NAME.inited, () => setLrcConfig(true))
|
||||
|
||||
global.lx_event.mainWindow.on(MAIN_WINDOW_EVENT_NAME.setLyricInfo, info => {
|
||||
if (!global.modals.lyricWindow) return
|
||||
mainSend(global.modals.lyricWindow, ipcWinLyricNames.set_lyric_info, info)
|
||||
})
|
|
@ -0,0 +1,122 @@
|
|||
const { BrowserWindow } = require('electron')
|
||||
const { winLyric: WIN_LYRIC_EVENT_NAME } = require('../../events/_name')
|
||||
const { debounce } = require('../../../common/utils')
|
||||
|
||||
require('./event')
|
||||
require('./rendererEvent')
|
||||
|
||||
global.lx_event.winLyric.on(WIN_LYRIC_EVENT_NAME.create, () => {
|
||||
createWindow()
|
||||
})
|
||||
global.lx_event.winLyric.on(WIN_LYRIC_EVENT_NAME.close, () => {
|
||||
closeWindow()
|
||||
})
|
||||
|
||||
let winURL = global.isDev ? 'http://localhost:9081/lyric.html' : `file://${__dirname}/lyric.html`
|
||||
|
||||
const setLyricsConfig = debounce(config => {
|
||||
// if (x != null) bounds.x = x
|
||||
// if (y != null) bounds.y = y
|
||||
// if (width != null) bounds.width = width
|
||||
// if (height != null) bounds.height = height
|
||||
global.lx_event.common.setAppConfig({ desktopLyric: config }, WIN_LYRIC_EVENT_NAME.name)
|
||||
}, 500)
|
||||
|
||||
const winEvent = lyricWindow => {
|
||||
// let bounds
|
||||
// lyricWindow.on('close', event => {
|
||||
// if (global.isQuitting || !global.appSetting.tray.isToTray || (!isWin && !global.isTrafficLightClose)) {
|
||||
// lyricWindow.setProgressBar(-1)
|
||||
// return
|
||||
// }
|
||||
|
||||
// if (global.isTrafficLightClose) global.isTrafficLightClose = false
|
||||
// event.preventDefault()
|
||||
// lyricWindow.hide()
|
||||
// })
|
||||
|
||||
lyricWindow.on('closed', () => {
|
||||
lyricWindow = global.modals.lyricWindow = null
|
||||
})
|
||||
|
||||
|
||||
lyricWindow.on('move', event => {
|
||||
// bounds = lyricWindow.getBounds()
|
||||
// console.log(bounds)
|
||||
setLyricsConfig(lyricWindow.getBounds())
|
||||
})
|
||||
|
||||
lyricWindow.on('resize', event => {
|
||||
// bounds = lyricWindow.getBounds()
|
||||
// console.log(bounds)
|
||||
setLyricsConfig(lyricWindow.getBounds())
|
||||
})
|
||||
|
||||
// lyricWindow.on('restore', () => {
|
||||
// lyricWindow.webContents.send('restore')
|
||||
// })
|
||||
// lyricWindow.on('focus', () => {
|
||||
// lyricWindow.webContents.send('focus')
|
||||
// })
|
||||
|
||||
lyricWindow.once('ready-to-show', () => {
|
||||
lyricWindow.show()
|
||||
let config = global.appSetting.desktopLyric
|
||||
global.modals.lyricWindow.setBounds({
|
||||
height: config.height,
|
||||
width: config.width,
|
||||
y: config.y,
|
||||
x: config.x,
|
||||
})
|
||||
global.lx_event.winLyric.inited()
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
const createWindow = () => {
|
||||
if (global.modals.lyricWindow) return
|
||||
if (!global.appSetting.desktopLyric.enable) return
|
||||
// const windowSizeInfo = getWindowSizeInfo(global.appSetting)
|
||||
const { x, y, width, height, isAlwaysOnTop } = global.appSetting.desktopLyric
|
||||
let { width: screenWidth, height: screenHeight } = global.envParams.workAreaSize
|
||||
screenWidth += 16
|
||||
screenHeight += 16
|
||||
/**
|
||||
* Initial window options
|
||||
*/
|
||||
global.modals.lyricWindow = new BrowserWindow({
|
||||
height: height > screenHeight ? screenHeight : height,
|
||||
width: width > screenWidth ? screenWidth : width,
|
||||
x: Math.max(-8, screenWidth < (width + x) ? screenWidth - width : x),
|
||||
y: Math.max(-8, screenHeight < (height + y) ? screenHeight - height : y),
|
||||
minWidth: 300,
|
||||
minHeight: 300,
|
||||
useContentSize: true,
|
||||
frame: false,
|
||||
transparent: true,
|
||||
enableRemoteModule: false,
|
||||
// icon: path.join(global.__static, isWin ? 'icons/256x256.ico' : 'icons/512x512.png'),
|
||||
resizable: false,
|
||||
minimizable: false,
|
||||
maximizable: false,
|
||||
fullscreenable: false,
|
||||
show: false,
|
||||
alwaysOnTop: isAlwaysOnTop,
|
||||
skipTaskbar: true,
|
||||
webPreferences: {
|
||||
// contextIsolation: true,
|
||||
webSecurity: !global.isDev,
|
||||
nodeIntegration: true,
|
||||
},
|
||||
})
|
||||
|
||||
global.modals.lyricWindow.loadURL(winURL)
|
||||
|
||||
winEvent(global.modals.lyricWindow)
|
||||
// mainWindow.webContents.openDevTools()
|
||||
}
|
||||
|
||||
const closeWindow = () => {
|
||||
if (!global.modals.lyricWindow) return
|
||||
global.modals.lyricWindow.close()
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
const {
|
||||
mainOn,
|
||||
mainHandle,
|
||||
mainSend,
|
||||
NAMES: {
|
||||
mainWindow: ipcMainWindowNames,
|
||||
winLyric: ipcWinLyricNames,
|
||||
},
|
||||
} = require('../../../common/ipc')
|
||||
const { winLyric: WIN_LYRIC_EVENT_NAME } = require('../../events/_name')
|
||||
|
||||
mainOn(ipcWinLyricNames.get_lyric_info, (event, action) => {
|
||||
if (!global.modals.mainWindow) return
|
||||
mainSend(global.modals.mainWindow, ipcMainWindowNames.get_lyric_info, {
|
||||
name: ipcWinLyricNames.set_lyric_info,
|
||||
modal: 'lyricWindow',
|
||||
action,
|
||||
})
|
||||
})
|
||||
|
||||
mainOn(ipcWinLyricNames.set_lyric_config, (event, config) => {
|
||||
global.lx_event.common.setAppConfig({ desktopLyric: config }, WIN_LYRIC_EVENT_NAME.name)
|
||||
})
|
||||
|
||||
mainHandle(ipcWinLyricNames.get_lyric_config, async() => {
|
||||
return global.appSetting.desktopLyric
|
||||
})
|
||||
|
||||
let bounds
|
||||
let winX
|
||||
let winY
|
||||
let wasW
|
||||
let wasY
|
||||
mainOn(ipcWinLyricNames.set_win_bounds, (event, { x = 0, y = 0, w = 0, h = 0 }) => {
|
||||
if (!global.modals.lyricWindow) return
|
||||
bounds = global.modals.lyricWindow.getBounds()
|
||||
wasW = global.envParams.workAreaSize.width
|
||||
wasY = global.envParams.workAreaSize.height + 8
|
||||
|
||||
bounds.width = w + bounds.width
|
||||
bounds.height = h + bounds.height
|
||||
if (bounds.width > wasW - 8) {
|
||||
bounds.width = wasW - 8
|
||||
} else if (bounds.width < 300) {
|
||||
bounds.width = 300
|
||||
}
|
||||
if (bounds.height > wasY) {
|
||||
bounds.height = wasY + 8
|
||||
} else if (bounds.height < 120) {
|
||||
bounds.height = 120
|
||||
}
|
||||
|
||||
|
||||
if (x != 0) {
|
||||
winX = bounds.x + x
|
||||
if (winX > wasW - bounds.width + 8) {
|
||||
winX = wasW - bounds.width + 8
|
||||
} else if (winX < -8) {
|
||||
winX = -8
|
||||
}
|
||||
bounds.x = winX
|
||||
}
|
||||
if (y != 0) {
|
||||
winY = bounds.y + y
|
||||
if (winY > wasY - bounds.height) {
|
||||
winY = wasY - bounds.height
|
||||
} else if (winY < -8) {
|
||||
winY = -8
|
||||
}
|
||||
bounds.y = winY
|
||||
}
|
||||
|
||||
// console.log(bounds)
|
||||
global.modals.lyricWindow.setBounds(bounds)
|
||||
})
|
|
@ -1,9 +1,9 @@
|
|||
const { mainOn } = require('../../common/ipc')
|
||||
const { mainOn, NAMES: { mainWindow: ipcMainWindowNames } } = require('../../common/ipc')
|
||||
const { app } = require('electron')
|
||||
const { name: defaultName } = require('../../../package.json')
|
||||
|
||||
|
||||
mainOn('appName', (event, params) => {
|
||||
mainOn(ipcMainWindowNames.set_app_name, (event, params) => {
|
||||
if (params == null) {
|
||||
app.setName(defaultName)
|
||||
} else {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
const { mainHandle } = require('../../common/ipc')
|
||||
const { mainHandle, NAMES: { mainWindow: ipcMainWindowNames } } = require('../../common/ipc')
|
||||
|
||||
mainHandle('clearCache', async(event, options) => {
|
||||
if (!global.mainWindow) throw new Error('mainwindow is undefined')
|
||||
return global.mainWindow.webContents.session.clearCache()
|
||||
mainHandle(ipcMainWindowNames.clear_cache, async(event, options) => {
|
||||
if (!global.modals.mainWindow) throw new Error('mainWindow is undefined')
|
||||
return global.modals.mainWindow.webContents.session.clearCache()
|
||||
})
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
const { mainHandle } = require('../../common/ipc')
|
||||
const { mainHandle, NAMES: { mainWindow: ipcMainWindowNames } } = require('../../common/ipc')
|
||||
|
||||
mainHandle('getCacheSize', async(event, options) => {
|
||||
if (!global.mainWindow) throw new Error('mainwindow is undefined')
|
||||
return global.mainWindow.webContents.session.getCacheSize()
|
||||
mainHandle(ipcMainWindowNames.get_cache_size, async(event, options) => {
|
||||
if (!global.modals.mainWindow) throw new Error('mainWindow is undefined')
|
||||
return global.modals.mainWindow.webContents.session.getCacheSize()
|
||||
})
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
const { mainHandle } = require('../../common/ipc')
|
||||
const { mainHandle, NAMES: { mainWindow: ipcMainWindowNames } } = require('../../common/ipc')
|
||||
|
||||
mainHandle('getEnvParams', async(event, options) => {
|
||||
return global.envParams
|
||||
mainHandle(ipcMainWindowNames.get_env_params, async(event, options) => {
|
||||
return global.envParams.cmdParams
|
||||
})
|
||||
|
||||
|
|
|
@ -11,8 +11,8 @@ require('./clearCache')
|
|||
require('./getCacheSize')
|
||||
require('./setIgnoreMouseEvent')
|
||||
require('./getEnvParams')
|
||||
require('./tray')
|
||||
require('./updateSetting')
|
||||
require('./setAppSetting')
|
||||
require('./setLyricInfo')
|
||||
|
||||
require('./xm_verify')
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
const { inflate } = require('zlib')
|
||||
const iconv = require('iconv-lite')
|
||||
const { mainHandle } = require('../../common/ipc')
|
||||
const { mainHandle, NAMES: { mainWindow: ipcMainWindowNames } } = require('../../common/ipc')
|
||||
|
||||
const handleInflate = data => new Promise((resolve, reject) => {
|
||||
inflate(data, (err, result) => {
|
||||
|
@ -38,8 +38,8 @@ const decodeLyric = async(buf, isGetLyricx) => {
|
|||
return iconv.decode(Buffer.from(output), 'gb18030')
|
||||
}
|
||||
|
||||
mainHandle('kw_decodeLyric', async(event, { lrcBase64, isGetLyricx }) => {
|
||||
if (!global.mainWindow) throw new Error('mainwindow is undefined')
|
||||
mainHandle(ipcMainWindowNames.handle_kw_decode_lyric, async(event, { lrcBase64, isGetLyricx }) => {
|
||||
if (!global.modals.mainWindow) throw new Error('mainWindow is undefined')
|
||||
const lrc = await decodeLyric(Buffer.from(lrcBase64, 'base64'), isGetLyricx)
|
||||
return Buffer.from(lrc).toString('base64')
|
||||
})
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
const { mainOn } = require('../../common/ipc')
|
||||
const { mainOn, NAMES: { mainWindow: ipcMainWindowNames } } = require('../../common/ipc')
|
||||
const { setMeta } = require('../utils/musicMeta')
|
||||
|
||||
mainOn('setMusicMeta', (event, { filePath, meta }) => {
|
||||
mainOn(ipcMainWindowNames.set_music_meta, (event, { filePath, meta }) => {
|
||||
setMeta(filePath, meta)
|
||||
})
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
const { mainOn } = require('../../common/ipc')
|
||||
const { mainOn, NAMES: { mainWindow: ipcMainWindowNames } } = require('../../common/ipc')
|
||||
|
||||
|
||||
mainOn('progress', (event, params) => {
|
||||
mainOn(ipcMainWindowNames.progress, (event, params) => {
|
||||
// console.log(params)
|
||||
global.mainWindow && global.mainWindow.setProgressBar(params.status, {
|
||||
global.modals.mainWindow && global.modals.mainWindow.setProgressBar(params.status, {
|
||||
mode: params.mode || 'normal',
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
const request = require('request')
|
||||
|
||||
const { mainOn } = require('../../common/ipc')
|
||||
const { mainOn, NAMES: { mainWindow: ipcMainWindowNames } } = require('../../common/ipc')
|
||||
|
||||
const tasks = []
|
||||
|
||||
mainOn('request', (event, options) => {
|
||||
mainOn(ipcMainWindowNames.handle_request, (event, options) => {
|
||||
// console.log(args)
|
||||
if (!options) return
|
||||
let index = fetchData(options, (err, resp) => {
|
||||
|
@ -19,7 +19,7 @@ mainOn('request', (event, options) => {
|
|||
event.returnValue = index
|
||||
})
|
||||
|
||||
mainOn('cancelRequest', (event, index) => {
|
||||
mainOn(ipcMainWindowNames.cancel_request, (event, index) => {
|
||||
if (index == null) return
|
||||
let r = tasks[index]
|
||||
if (r == null) return
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
const { mainOn } = require('../../common/ipc')
|
||||
const { mainOn, NAMES: { mainWindow: ipcMainWindowNames } } = require('../../common/ipc')
|
||||
|
||||
|
||||
mainOn('restartWindow', (event, name) => {
|
||||
mainOn(ipcMainWindowNames.restart_window, (event, name) => {
|
||||
console.log(name)
|
||||
switch (name) {
|
||||
case 'main':
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
const { mainHandle } = require('../../common/ipc')
|
||||
const { mainHandle, NAMES: { mainWindow: ipcMainWindowNames } } = require('../../common/ipc')
|
||||
const { dialog } = require('electron')
|
||||
|
||||
mainHandle('selectDir', async(event, options) => {
|
||||
if (!global.mainWindow) throw new Error('mainwindow is undefined')
|
||||
return dialog.showOpenDialog(global.mainWindow, options)
|
||||
mainHandle(ipcMainWindowNames.select_dir, async(event, options) => {
|
||||
if (!global.modals.mainWindow) throw new Error('mainWindow is undefined')
|
||||
return dialog.showOpenDialog(global.modals.mainWindow, options)
|
||||
})
|
||||
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
const { mainWindow: MAIN_WINDOW_EVENT_NAME } = require('../events/_name')
|
||||
const { mainOn, NAMES: { mainWindow: ipcMainWindowNames } } = require('../../common/ipc')
|
||||
|
||||
mainOn(ipcMainWindowNames.set_app_setting, (event, config) => {
|
||||
if (!config) return
|
||||
global.lx_event.common.setAppConfig(config, MAIN_WINDOW_EVENT_NAME.name)
|
||||
})
|
|
@ -1,8 +1,8 @@
|
|||
const { mainOn } = require('../../common/ipc')
|
||||
const { mainOn, NAMES: { mainWindow: ipcMainWindowNames } } = require('../../common/ipc')
|
||||
|
||||
mainOn('setIgnoreMouseEvents', (event, isIgnored) => {
|
||||
if (!global.mainWindow) return
|
||||
mainOn(ipcMainWindowNames.set_ignore_mouse_events, (event, isIgnored) => {
|
||||
if (!global.modals.mainWindow) return
|
||||
isIgnored
|
||||
? global.mainWindow.setIgnoreMouseEvents(true, { forward: true })
|
||||
: global.mainWindow.setIgnoreMouseEvents(false)
|
||||
? global.modals.mainWindow.setIgnoreMouseEvents(true, { forward: true })
|
||||
: global.modals.mainWindow.setIgnoreMouseEvents(false)
|
||||
})
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
const { mainOn, mainSend, NAMES: { mainWindow: ipcMainWindowNames } } = require('../../common/ipc')
|
||||
|
||||
|
||||
mainOn(ipcMainWindowNames.set_lyric_info, (event, info) => {
|
||||
if (info.info == null) {
|
||||
global.lx_event.mainWindow.setLyricInfo(info)
|
||||
return
|
||||
}
|
||||
mainSend(global.modals[info.info.modal], info.info.name, info)
|
||||
})
|
|
@ -1,7 +1,7 @@
|
|||
const { mainOn } = require('../../common/ipc')
|
||||
const { mainOn, NAMES: { mainWindow: ipcMainWindowNames } } = require('../../common/ipc')
|
||||
|
||||
mainOn('setWindowSize', (event, options) => {
|
||||
if (!global.mainWindow) return
|
||||
global.mainWindow.setBounds(options)
|
||||
mainOn(ipcMainWindowNames.set_window_size, (event, options) => {
|
||||
if (!global.modals.mainWindow) return
|
||||
global.modals.mainWindow.setBounds(options)
|
||||
})
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
const { mainHandle } = require('../../common/ipc')
|
||||
const { mainHandle, NAMES: { mainWindow: ipcMainWindowNames } } = require('../../common/ipc')
|
||||
const { dialog } = require('electron')
|
||||
|
||||
mainHandle('showSaveDialog', async(event, options) => {
|
||||
if (!global.mainWindow) throw new Error('mainwindow is undefined')
|
||||
return dialog.showSaveDialog(global.mainWindow, options)
|
||||
mainHandle(ipcMainWindowNames.show_save_dialog, async(event, options) => {
|
||||
if (!global.modals.mainWindow) throw new Error('mainWindow is undefined')
|
||||
return dialog.showSaveDialog(global.modals.mainWindow, options)
|
||||
})
|
||||
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
const { app } = require('electron')
|
||||
const { mainOn } = require('../../common/ipc')
|
||||
const { mainOn, NAMES: { mainWindow: ipcMainWindowNames } } = require('../../common/ipc')
|
||||
|
||||
mainOn('min', event => {
|
||||
if (global.mainWindow) {
|
||||
global.mainWindow.minimize()
|
||||
mainOn(ipcMainWindowNames.min, event => {
|
||||
if (global.modals.mainWindow) {
|
||||
global.modals.mainWindow.minimize()
|
||||
}
|
||||
})
|
||||
mainOn('max', event => {
|
||||
if (global.mainWindow) {
|
||||
global.mainWindow.maximize()
|
||||
mainOn(ipcMainWindowNames.max, event => {
|
||||
if (global.modals.mainWindow) {
|
||||
global.modals.mainWindow.maximize()
|
||||
}
|
||||
})
|
||||
mainOn('close', (event, isForce) => {
|
||||
mainOn(ipcMainWindowNames.close, (event, isForce) => {
|
||||
if (isForce) return app.exit(0)
|
||||
global.isTrafficLightClose = true
|
||||
if (global.mainWindow) global.mainWindow.close()
|
||||
if (global.modals.mainWindow) global.modals.mainWindow.close()
|
||||
})
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
// const { app } = require('electron')
|
||||
const { mainOn } = require('../../common/ipc')
|
||||
|
||||
mainOn('changeTray', (event, setting) => {
|
||||
global.appSetting.tray = setting
|
||||
if (setting.isToTray) {
|
||||
global.lx_event.tray.create()
|
||||
} else {
|
||||
global.lx_event.tray.destroy()
|
||||
}
|
||||
})
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
const { mainOn } = require('../../common/ipc')
|
||||
|
||||
|
||||
mainOn('updateAppSetting', (event, setting) => {
|
||||
if (!setting) return
|
||||
global.appSetting = setting
|
||||
})
|
|
@ -1,4 +1,5 @@
|
|||
const { isWin } = require('../../common/utils')
|
||||
const { mainSend, NAMES: { mainWindow: ipcMainWindowNames } } = require('../../common/ipc')
|
||||
global.isQuitting = false
|
||||
global.isTrafficLightClose = false // 是否点击软件上的关闭按钮关闭
|
||||
|
||||
|
@ -6,6 +7,7 @@ module.exports = mainWindow => {
|
|||
mainWindow.on('close', event => {
|
||||
if (global.isQuitting || !global.appSetting.tray.isToTray || (!isWin && !global.isTrafficLightClose)) {
|
||||
mainWindow.setProgressBar(-1)
|
||||
global.lx_event.winLyric.close()
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -15,14 +17,14 @@ module.exports = mainWindow => {
|
|||
})
|
||||
|
||||
mainWindow.on('closed', () => {
|
||||
mainWindow = global.mainWindow = null
|
||||
mainWindow = global.modals.mainWindow = null
|
||||
})
|
||||
|
||||
// mainWindow.on('restore', () => {
|
||||
// mainWindow.webContents.send('restore')
|
||||
// })
|
||||
mainWindow.on('focus', () => {
|
||||
mainWindow.webContents.send('focus')
|
||||
mainSend(mainWindow, ipcMainWindowNames.focus)
|
||||
})
|
||||
|
||||
mainWindow.once('ready-to-show', () => {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
const { BrowserView } = require('electron')
|
||||
const { mainHandle } = require('../../../common/ipc')
|
||||
const { mainHandle, NAMES: { mainWindow: ipcMainWindowNames } } = require('../../../common/ipc')
|
||||
const { getWindowSizeInfo } = require('../../utils')
|
||||
|
||||
let view
|
||||
|
@ -9,16 +9,16 @@ let rejectFn
|
|||
const closeView = async() => {
|
||||
if (!view) return
|
||||
// await view.webContents.session.clearCache()
|
||||
if (global.mainWindow) global.mainWindow.removeBrowserView(view)
|
||||
if (global.modals.mainWindow) global.modals.mainWindow.removeBrowserView(view)
|
||||
await view.webContents.session.clearStorageData()
|
||||
view.destroy()
|
||||
view = null
|
||||
}
|
||||
|
||||
mainHandle('xm_verify_open', (event, url) => new Promise((resolve, reject) => {
|
||||
if (!global.mainWindow) return reject(new Error('mainwindow is undefined'))
|
||||
mainHandle(ipcMainWindowNames.handle_xm_verify_open, (event, url) => new Promise((resolve, reject) => {
|
||||
if (!global.modals.mainWindow) return reject(new Error('mainWindow is undefined'))
|
||||
if (view) {
|
||||
global.mainWindow.removeBrowserView(view)
|
||||
global.modals.mainWindow.removeBrowserView(view)
|
||||
view.destroy()
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,7 @@ mainHandle('xm_verify_open', (event, url) => new Promise((resolve, reject) => {
|
|||
})
|
||||
})
|
||||
|
||||
global.mainWindow.setBrowserView(view)
|
||||
global.modals.mainWindow.setBrowserView(view)
|
||||
const windowSizeInfo = getWindowSizeInfo(global.appSetting)
|
||||
view.setBounds({ x: (windowSizeInfo.width - 380) / 2, y: ((windowSizeInfo.height - 320 + 52) / 2), width: 380, height: 320 })
|
||||
view.webContents.loadURL(url, {
|
||||
|
@ -57,7 +57,7 @@ mainHandle('xm_verify_open', (event, url) => new Promise((resolve, reject) => {
|
|||
// view.webContents.openDevTools()
|
||||
}))
|
||||
|
||||
mainHandle('xm_verify_close', async() => {
|
||||
mainHandle(ipcMainWindowNames.handle_xm_verify_close, async() => {
|
||||
await closeView()
|
||||
if (!rejectFn) return
|
||||
if (!isActioned) rejectFn(new Error('canceled verify'))
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
const { BrowserWindow } = require('electron')
|
||||
const { mainHandle } = require('../../../common/ipc')
|
||||
const { mainHandle, NAMES: { mainWindow: ipcMainWindowNames } } = require('../../../common/ipc')
|
||||
const { getWindowSizeInfo } = require('../../utils')
|
||||
|
||||
let win
|
||||
|
@ -7,7 +7,7 @@ let win
|
|||
const closeWin = async() => {
|
||||
if (!win) return
|
||||
// await win.webContents.session.clearCache()
|
||||
// if (global.mainWindow) global.mainWindow.removeBrowserView(win)
|
||||
// if (global.modals.mainWindow) global.modals.mainWindow.removeBrowserView(win)
|
||||
if (win.isDestroyed()) {
|
||||
win = null
|
||||
return
|
||||
|
@ -17,16 +17,16 @@ const closeWin = async() => {
|
|||
win = null
|
||||
}
|
||||
|
||||
mainHandle('xm_verify_open', (event, url) => new Promise((resolve, reject) => {
|
||||
if (!global.mainWindow) return reject(new Error('mainwindow is undefined'))
|
||||
mainHandle(ipcMainWindowNames.handle_xm_verify_open, (event, url) => new Promise((resolve, reject) => {
|
||||
if (!global.modals.mainWindow) return reject(new Error('mainWindow is undefined'))
|
||||
if (win) win.destroy()
|
||||
|
||||
let isActioned = false
|
||||
|
||||
const mainWindowSizeInfo = global.mainWindow.getBounds()
|
||||
const mainWindowSizeInfo = global.modals.mainWindow.getBounds()
|
||||
const windowSizeInfo = getWindowSizeInfo(global.appSetting)
|
||||
win = new BrowserWindow({
|
||||
parent: global.mainWindow,
|
||||
parent: global.modals.mainWindow,
|
||||
width: 460,
|
||||
height: 370,
|
||||
resizable: false,
|
||||
|
@ -72,6 +72,6 @@ mainHandle('xm_verify_open', (event, url) => new Promise((resolve, reject) => {
|
|||
// win.webContents.openDevTools()
|
||||
}))
|
||||
|
||||
mainHandle('xm_verify_close', async() => {
|
||||
mainHandle(ipcMainWindowNames.handle_xm_verify_close, async() => {
|
||||
await closeWin()
|
||||
})
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
const { log } = require('../../common/utils')
|
||||
const { autoUpdater } = require('electron-updater')
|
||||
const { mainOn } = require('../../common/ipc')
|
||||
const { mainOn, mainSend, NAMES: { mainWindow: ipcMainWindowNames } } = require('../../common/ipc')
|
||||
|
||||
autoUpdater.logger = log
|
||||
// autoUpdater.autoDownload = false
|
||||
|
@ -61,9 +61,10 @@ function sendStatusToWindow(text) {
|
|||
|
||||
let waitEvent = []
|
||||
const handleSendEvent = action => {
|
||||
if (global.mainWindow) {
|
||||
if (global.modals.mainWindow) {
|
||||
setTimeout(() => { // 延迟发送事件,过早发送可能渲染进程还没启动完成
|
||||
global.mainWindow.webContents.send(action.type, action.info)
|
||||
if (!global.modals.mainWindow) return
|
||||
mainSend(global.modals.mainWindow, action.type, action.info)
|
||||
}, 2000)
|
||||
} else {
|
||||
waitEvent.push(action)
|
||||
|
@ -75,7 +76,8 @@ module.exports = () => {
|
|||
if (waitEvent.length) {
|
||||
waitEvent.forEach((event, index) => {
|
||||
setTimeout(() => { // 延迟发送事件,过早发送可能渲染进程还没启动完成
|
||||
global.mainWindow.webContents.send(event.type, event.info)
|
||||
if (!global.modals.mainWindow) return
|
||||
mainSend(global.modals.mainWindow, event.type, event.info)
|
||||
}, 2000 * (index + 1))
|
||||
})
|
||||
waitEvent = []
|
||||
|
@ -89,28 +91,28 @@ module.exports = () => {
|
|||
})
|
||||
autoUpdater.on('update-available', info => {
|
||||
sendStatusToWindow('Update available.')
|
||||
handleSendEvent({ type: 'update-available', info })
|
||||
handleSendEvent({ type: ipcMainWindowNames.update_available, info })
|
||||
})
|
||||
autoUpdater.on('update-not-available', info => {
|
||||
sendStatusToWindow('Update not available.')
|
||||
handleSendEvent({ type: 'update-not-available', info })
|
||||
handleSendEvent({ type: ipcMainWindowNames.update_not_available, info })
|
||||
})
|
||||
autoUpdater.on('error', err => {
|
||||
sendStatusToWindow('Error in auto-updater.')
|
||||
handleSendEvent({ type: 'update-error', info: err.message })
|
||||
handleSendEvent({ type: ipcMainWindowNames.update_error, info: err.message })
|
||||
})
|
||||
autoUpdater.on('download-progress', progressObj => {
|
||||
let log_message = 'Download speed: ' + progressObj.bytesPerSecond
|
||||
log_message = log_message + ' - Downloaded ' + progressObj.percent + '%'
|
||||
log_message = log_message + ' (' + progressObj.transferred + '/' + progressObj.total + ')'
|
||||
sendStatusToWindow(log_message)
|
||||
handleSendEvent({ type: 'update-progress', info: progressObj })
|
||||
handleSendEvent({ type: ipcMainWindowNames.update_progress, info: progressObj })
|
||||
})
|
||||
autoUpdater.on('update-downloaded', info => {
|
||||
sendStatusToWindow('Update downloaded.')
|
||||
handleSendEvent({ type: 'update-downloaded', info })
|
||||
handleSendEvent({ type: ipcMainWindowNames.update_downloaded, info })
|
||||
})
|
||||
mainOn('quit-update', () => {
|
||||
mainOn(ipcMainWindowNames.quit_update, () => {
|
||||
global.isQuitting = true
|
||||
|
||||
setTimeout(() => {
|
||||
|
|
|
@ -1,35 +1,19 @@
|
|||
const Store = require('electron-store')
|
||||
const { windowSizeList } = require('../../common/config')
|
||||
const { objectDeepMerge } = require('../../common/utils')
|
||||
|
||||
exports.getWindowSizeInfo = ({ windowSizeId = 1 } = {}) => {
|
||||
return windowSizeList.find(i => i.id === windowSizeId) || windowSizeList[0]
|
||||
}
|
||||
|
||||
exports.getAppSetting = () => {
|
||||
let electronStore = new Store()
|
||||
const defaultSetting = {
|
||||
windowSizeId: 1,
|
||||
tray: {
|
||||
isShow: false,
|
||||
isToTray: false,
|
||||
},
|
||||
}
|
||||
return Object.assign(defaultSetting, electronStore.get('setting') || {})
|
||||
const electronStore_config = new Store({
|
||||
name: 'config',
|
||||
})
|
||||
return electronStore_config.get('setting')
|
||||
}
|
||||
|
||||
exports.parseEnv = () => {
|
||||
const params = {}
|
||||
const rx = /^-\w+/
|
||||
for (let param of process.argv) {
|
||||
if (!rx.test(param)) continue
|
||||
param = param.substring(1)
|
||||
let index = param.indexOf('=')
|
||||
if (index < 0) {
|
||||
params[param] = true
|
||||
} else {
|
||||
params[param.substring(0, index)] = param.substring(index + 1)
|
||||
}
|
||||
}
|
||||
return params
|
||||
}
|
||||
|
||||
exports.updateSetting = settings => {
|
||||
objectDeepMerge(global.appSetting, settings)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,324 @@
|
|||
<template lang="pug">
|
||||
#container(:class="[theme, lrcConfig.isLock ? 'lock' : null]")
|
||||
#main
|
||||
transition(enter-active-class="animated-fast fadeIn" leave-active-class="animated-fast fadeOut")
|
||||
.control-bar(v-show="!lrcConfig.isLock")
|
||||
core-control-bar(:lrcConfig="lrcConfig" :themes="themeList")
|
||||
core-lyric(:lrcConfig="lrcConfig")
|
||||
div.resize-left(@mousedown.self="handleMouseDown('left', $event)")
|
||||
div.resize-top(@mousedown.self="handleMouseDown('top', $event)")
|
||||
div.resize-right(@mousedown.self="handleMouseDown('right', $event)")
|
||||
div.resize-bottom(@mousedown.self="handleMouseDown('bottom', $event)")
|
||||
div.resize-top-left(@mousedown.self="handleMouseDown('top-left', $event)")
|
||||
div.resize-top-right(@mousedown.self="handleMouseDown('top-right', $event)")
|
||||
div.resize-bottom-left(@mousedown.self="handleMouseDown('bottom-left', $event)")
|
||||
div.resize-bottom-right(@mousedown.self="handleMouseDown('bottom-right', $event)")
|
||||
core-icons
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { rendererOn, rendererInvoke, rendererSend, NAMES } from '../common/ipc'
|
||||
|
||||
window.ELECTRON_DISABLE_SECURITY_WARNINGS = process.env.ELECTRON_DISABLE_SECURITY_WARNINGS
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
resize: {
|
||||
origin: null,
|
||||
msDownX: 0,
|
||||
msDownY: 0,
|
||||
},
|
||||
lrcConfig: {
|
||||
enable: false,
|
||||
isLock: false,
|
||||
isAlwaysOnTop: false,
|
||||
width: 600,
|
||||
height: 700,
|
||||
x: -1,
|
||||
y: -1,
|
||||
theme: 0,
|
||||
style: {
|
||||
fontSize: 125,
|
||||
opacity: 80,
|
||||
isZoomActiveLrc: true,
|
||||
},
|
||||
},
|
||||
themeList: [
|
||||
{
|
||||
id: 0,
|
||||
name: '绿意盎然',
|
||||
className: 'green',
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
name: '绿意盎然',
|
||||
className: 'yellow',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: '绿意盎然',
|
||||
className: 'blue',
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '绿意盎然',
|
||||
className: 'red',
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: '绿意盎然',
|
||||
className: 'pink',
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
name: '绿意盎然',
|
||||
className: 'purple',
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
name: '绿意盎然',
|
||||
className: 'orange',
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
name: '绿意盎然',
|
||||
className: 'grey',
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
name: '绿意盎然',
|
||||
className: 'ming',
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
name: '绿意盎然',
|
||||
className: 'blue2',
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
theme() {
|
||||
let theme = this.themeList.find(t => t.id == this.lrcConfig.theme) || this.themeList[0]
|
||||
return theme.className
|
||||
},
|
||||
},
|
||||
created() {
|
||||
rendererOn(NAMES.winLyric.set_lyric_config, (event, config) => this.lrcConfig = config)
|
||||
rendererInvoke(NAMES.winLyric.get_lyric_config).then(config => this.lrcConfig = config)
|
||||
},
|
||||
mounted() {
|
||||
document.addEventListener('mousemove', this.handleMouseMove)
|
||||
document.addEventListener('mouseup', this.handleMouseUp)
|
||||
},
|
||||
beforeDestroy() {
|
||||
document.removeEventListener('mousemove', this.handleMouseMove)
|
||||
document.removeEventListener('mouseup', this.handleMouseUp)
|
||||
},
|
||||
methods: {
|
||||
handleMouseDown(origin, event) {
|
||||
this.handleMouseUp()
|
||||
this.resize.origin = origin
|
||||
this.resize.msDownX = event.clientX
|
||||
this.resize.msDownY = event.clientY
|
||||
},
|
||||
handleMouseUp() {
|
||||
this.resize.origin = null
|
||||
},
|
||||
handleMouseMove(event) {
|
||||
if (!this.resize.origin) return
|
||||
// if (!event.target.classList.contains('resize-' + this.resize.origin)) return
|
||||
// console.log(event.target)
|
||||
let bounds = {}
|
||||
let temp
|
||||
switch (this.resize.origin) {
|
||||
case 'left':
|
||||
temp = event.clientX - this.resize.msDownX
|
||||
bounds.w = -temp
|
||||
bounds.x = temp
|
||||
break
|
||||
case 'right':
|
||||
bounds.w = event.clientX - this.resize.msDownX
|
||||
this.resize.msDownX += bounds.w
|
||||
break
|
||||
case 'top':
|
||||
temp = event.clientY - this.resize.msDownY
|
||||
bounds.y = temp
|
||||
bounds.h = -temp
|
||||
break
|
||||
case 'bottom':
|
||||
bounds.h = event.clientY - this.resize.msDownY
|
||||
this.resize.msDownY += bounds.h
|
||||
break
|
||||
case 'top-left':
|
||||
temp = event.clientX - this.resize.msDownX
|
||||
bounds.w = -temp
|
||||
bounds.x = temp
|
||||
temp = event.clientY - this.resize.msDownY
|
||||
bounds.y = temp
|
||||
bounds.h = -temp
|
||||
break
|
||||
case 'top-right':
|
||||
temp = event.clientY - this.resize.msDownY
|
||||
bounds.y = temp
|
||||
bounds.h = -temp
|
||||
bounds.w = event.clientX - this.resize.msDownX
|
||||
this.resize.msDownX += bounds.w
|
||||
break
|
||||
case 'bottom-left':
|
||||
temp = event.clientX - this.resize.msDownX
|
||||
bounds.w = -temp
|
||||
bounds.x = temp
|
||||
bounds.h = event.clientY - this.resize.msDownY
|
||||
this.resize.msDownY += bounds.h
|
||||
break
|
||||
case 'bottom-right':
|
||||
bounds.w = event.clientX - this.resize.msDownX
|
||||
this.resize.msDownX += bounds.w
|
||||
bounds.h = event.clientY - this.resize.msDownY
|
||||
this.resize.msDownY += bounds.h
|
||||
break
|
||||
}
|
||||
// console.log(bounds)
|
||||
rendererSend(NAMES.winLyric.set_win_bounds, bounds)
|
||||
},
|
||||
handleMouseOver() {
|
||||
// this.handleMouseUp()
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
@import './assets/styles/index.less';
|
||||
@import './assets/styles/layout.less';
|
||||
|
||||
body {
|
||||
user-select: none;
|
||||
height: 100vh;
|
||||
box-sizing: border-box;
|
||||
color: #fff;
|
||||
opacity: .8;
|
||||
}
|
||||
|
||||
#container {
|
||||
padding: 8px;
|
||||
box-sizing: border-box;
|
||||
height: 100%;
|
||||
&.lock {
|
||||
#main {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.resize-left {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
width: 10px;
|
||||
cursor: ew-resize;
|
||||
// background-color: rgba(0, 0, 0, 1);
|
||||
}
|
||||
.resize-right {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
width: 10px;
|
||||
cursor: ew-resize;
|
||||
}
|
||||
.resize-top {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
height: 10px;
|
||||
width: 100%;
|
||||
cursor: ns-resize;
|
||||
}
|
||||
.resize-bottom {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
height: 10px;
|
||||
width: 100%;
|
||||
cursor: ns-resize;
|
||||
}
|
||||
.resize-top-left {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
cursor: nwse-resize;
|
||||
// background-color: rgba(0, 0, 0, 1);
|
||||
}
|
||||
.resize-top-right {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
cursor: nesw-resize;
|
||||
// background-color: rgba(0, 0, 0, 1);
|
||||
}
|
||||
.resize-top-left {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
cursor: nwse-resize;
|
||||
// background-color: rgba(0, 0, 0, 1);
|
||||
}
|
||||
.resize-bottom-left {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
cursor: nesw-resize;
|
||||
// background-color: rgba(0, 0, 0, 1);
|
||||
}
|
||||
.resize-bottom-right {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
cursor: nwse-resize;
|
||||
// background-color: rgba(0, 0, 0, 1);
|
||||
}
|
||||
|
||||
#main {
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
height: 100%;
|
||||
transition: background-color @transition-theme;
|
||||
min-height: 0;
|
||||
border-radius: @radius-border;
|
||||
overflow: hidden;
|
||||
background-color: rgba(0, 0, 0, .2);
|
||||
|
||||
&:hover {
|
||||
.control-bar {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.control-bar {
|
||||
position: absolute;
|
||||
border-top-left-radius: @radius-border;
|
||||
border-top-right-radius: @radius-border;
|
||||
overflow: hidden;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
opacity: 0;
|
||||
transition: opacity @transition-theme;
|
||||
z-index: 1;
|
||||
}
|
||||
</style>
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,325 @@
|
|||
@red-50: #ffebee;
|
||||
@red-100: #ffcdd2;
|
||||
@red-200: #ef9a9a;
|
||||
@red-300: #e57373;
|
||||
@red-400: #ef5350;
|
||||
@red-500: #f44336;
|
||||
@red-600: #e53935;
|
||||
@red-700: #d32f2f;
|
||||
@red-800: #c62828;
|
||||
@red-900: #b71c1c;
|
||||
@red-A100: #ff8a80;
|
||||
@red-A200: #ff5252;
|
||||
@red-A400: #ff1744;
|
||||
@red-A700: #d50000;
|
||||
@red: @red-500;
|
||||
|
||||
|
||||
@pink-50: #fce4ec;
|
||||
@pink-100: #f8bbd0;
|
||||
@pink-200: #f48fb1;
|
||||
@pink-300: #f06292;
|
||||
@pink-400: #ec407a;
|
||||
@pink-500: #e91e63;
|
||||
@pink-600: #d81b60;
|
||||
@pink-700: #c2185b;
|
||||
@pink-800: #ad1457;
|
||||
@pink-900: #880e4f;
|
||||
@pink-A100: #ff80ab;
|
||||
@pink-A200: #ff4081;
|
||||
@pink-A400: #f50057;
|
||||
@pink-A700: #c51162;
|
||||
@pink: @pink-500;
|
||||
|
||||
|
||||
@purple-50: #f3e5f5;
|
||||
@purple-100: #e1bee7;
|
||||
@purple-200: #ce93d8;
|
||||
@purple-300: #ba68c8;
|
||||
@purple-400: #ab47bc;
|
||||
@purple-500: #9c27b0;
|
||||
@purple-600: #8e24aa;
|
||||
@purple-700: #7b1fa2;
|
||||
@purple-800: #6a1b9a;
|
||||
@purple-900: #4a148c;
|
||||
@purple-A100: #ea80fc;
|
||||
@purple-A200: #e040fb;
|
||||
@purple-A400: #d500f9;
|
||||
@purple-A700: #aa00ff;
|
||||
@purple: @purple-500;
|
||||
|
||||
|
||||
@deep-purple-50: #ede7f6;
|
||||
@deep-purple-100: #d1c4e9;
|
||||
@deep-purple-200: #b39ddb;
|
||||
@deep-purple-300: #9575cd;
|
||||
@deep-purple-400: #7e57c2;
|
||||
@deep-purple-500: #673ab7;
|
||||
@deep-purple-600: #5e35b1;
|
||||
@deep-purple-700: #512da8;
|
||||
@deep-purple-800: #4527a0;
|
||||
@deep-purple-900: #311b92;
|
||||
@deep-purple-A100: #b388ff;
|
||||
@deep-purple-A200: #7c4dff;
|
||||
@deep-purple-A400: #651fff;
|
||||
@deep-purple-A700: #6200ea;
|
||||
@deep-purple: @deep-purple-500;
|
||||
|
||||
|
||||
@indigo-50: #e8eaf6;
|
||||
@indigo-100: #c5cae9;
|
||||
@indigo-200: #9fa8da;
|
||||
@indigo-300: #7986cb;
|
||||
@indigo-400: #5c6bc0;
|
||||
@indigo-500: #3f51b5;
|
||||
@indigo-600: #3949ab;
|
||||
@indigo-700: #303f9f;
|
||||
@indigo-800: #283593;
|
||||
@indigo-900: #1a237e;
|
||||
@indigo-A100: #8c9eff;
|
||||
@indigo-A200: #536dfe;
|
||||
@indigo-A400: #3d5afe;
|
||||
@indigo-A700: #304ffe;
|
||||
@indigo: @indigo-500;
|
||||
|
||||
|
||||
@blue-50: #e3f2fd;
|
||||
@blue-100: #bbdefb;
|
||||
@blue-200: #90caf9;
|
||||
@blue-300: #64b5f6;
|
||||
@blue-400: #42a5f5;
|
||||
@blue-500: #2196f3;
|
||||
@blue-600: #1e88e5;
|
||||
@blue-700: #1976d2;
|
||||
@blue-800: #1565c0;
|
||||
@blue-900: #0d47a1;
|
||||
@blue-A100: #82b1ff;
|
||||
@blue-A200: #448aff;
|
||||
@blue-A400: #2979ff;
|
||||
@blue-A700: #2962ff;
|
||||
@blue: @blue-500;
|
||||
|
||||
|
||||
@light-blue-50: #e1f5fe;
|
||||
@light-blue-100: #b3e5fc;
|
||||
@light-blue-200: #81d4fa;
|
||||
@light-blue-300: #4fc3f7;
|
||||
@light-blue-400: #29b6f6;
|
||||
@light-blue-500: #03a9f4;
|
||||
@light-blue-600: #039be5;
|
||||
@light-blue-700: #0288d1;
|
||||
@light-blue-800: #0277bd;
|
||||
@light-blue-900: #01579b;
|
||||
@light-blue-A100: #80d8ff;
|
||||
@light-blue-A200: #40c4ff;
|
||||
@light-blue-A400: #00b0ff;
|
||||
@light-blue-A700: #0091ea;
|
||||
@light-blue: @light-blue-500;
|
||||
|
||||
|
||||
@cyan-50: #e0f7fa;
|
||||
@cyan-100: #b2ebf2;
|
||||
@cyan-200: #80deea;
|
||||
@cyan-300: #4dd0e1;
|
||||
@cyan-400: #26c6da;
|
||||
@cyan-500: #00bcd4;
|
||||
@cyan-600: #00acc1;
|
||||
@cyan-700: #0097a7;
|
||||
@cyan-800: #00838f;
|
||||
@cyan-900: #006064;
|
||||
@cyan-A100: #84ffff;
|
||||
@cyan-A200: #18ffff;
|
||||
@cyan-A400: #00e5ff;
|
||||
@cyan-A700: #00b8d4;
|
||||
@cyan: @cyan-500;
|
||||
|
||||
|
||||
@teal-50: #e0f2f1;
|
||||
@teal-100: #b2dfdb;
|
||||
@teal-200: #80cbc4;
|
||||
@teal-300: #4db6ac;
|
||||
@teal-400: #26a69a;
|
||||
@teal-500: #009688;
|
||||
@teal-600: #00897b;
|
||||
@teal-700: #00796b;
|
||||
@teal-800: #00695c;
|
||||
@teal-900: #004d40;
|
||||
@teal-A100: #a7ffeb;
|
||||
@teal-A200: #64ffda;
|
||||
@teal-A400: #1de9b6;
|
||||
@teal-A700: #00bfa5;
|
||||
@teal: @teal-500;
|
||||
|
||||
|
||||
@green-50: #e8f5e9;
|
||||
@green-100: #c8e6c9;
|
||||
@green-200: #a5d6a7;
|
||||
@green-300: #81c784;
|
||||
@green-400: #66bb6a;
|
||||
@green-500: #4caf50;
|
||||
@green-600: #43a047;
|
||||
@green-700: #388e3c;
|
||||
@green-800: #2e7d32;
|
||||
@green-900: #1b5e20;
|
||||
@green-A100: #b9f6ca;
|
||||
@green-A200: #69f0ae;
|
||||
@green-A400: #00e676;
|
||||
@green-A700: #00c853;
|
||||
@green: @green-500;
|
||||
|
||||
|
||||
@light-green-50: #f1f8e9;
|
||||
@light-green-100: #dcedc8;
|
||||
@light-green-200: #c5e1a5;
|
||||
@light-green-300: #aed581;
|
||||
@light-green-400: #9ccc65;
|
||||
@light-green-500: #8bc34a;
|
||||
@light-green-600: #7cb342;
|
||||
@light-green-700: #689f38;
|
||||
@light-green-800: #558b2f;
|
||||
@light-green-900: #33691e;
|
||||
@light-green-A100: #ccff90;
|
||||
@light-green-A200: #b2ff59;
|
||||
@light-green-A400: #76ff03;
|
||||
@light-green-A700: #64dd17;
|
||||
@light-green: @light-green-500;
|
||||
|
||||
|
||||
@lime-50: #f9fbe7;
|
||||
@lime-100: #f0f4c3;
|
||||
@lime-200: #e6ee9c;
|
||||
@lime-300: #dce775;
|
||||
@lime-400: #d4e157;
|
||||
@lime-500: #cddc39;
|
||||
@lime-600: #c0ca33;
|
||||
@lime-700: #afb42b;
|
||||
@lime-800: #9e9d24;
|
||||
@lime-900: #827717;
|
||||
@lime-A100: #f4ff81;
|
||||
@lime-A200: #eeff41;
|
||||
@lime-A400: #c6ff00;
|
||||
@lime-A700: #aeea00;
|
||||
@lime: @lime-500;
|
||||
|
||||
|
||||
@yellow-50: #fffde7;
|
||||
@yellow-100: #fff9c4;
|
||||
@yellow-200: #fff59d;
|
||||
@yellow-300: #fff176;
|
||||
@yellow-400: #ffee58;
|
||||
@yellow-500: #fec60a;
|
||||
@yellow-600: #fdd835;
|
||||
@yellow-700: #fbc02d;
|
||||
@yellow-800: #f9a825;
|
||||
@yellow-900: #f57f17;
|
||||
@yellow-A100: #ffff8d;
|
||||
@yellow-A200: #ffff00;
|
||||
@yellow-A400: #ffea00;
|
||||
@yellow-A700: #ffd600;
|
||||
@yellow: @yellow-700;
|
||||
|
||||
|
||||
@amber-50: #fff8e1;
|
||||
@amber-100: #ffecb3;
|
||||
@amber-200: #ffe082;
|
||||
@amber-300: #ffd54f;
|
||||
@amber-400: #ffca28;
|
||||
@amber-500: #ffc107;
|
||||
@amber-600: #ffb300;
|
||||
@amber-700: #ffa000;
|
||||
@amber-800: #ff8f00;
|
||||
@amber-900: #ff6f00;
|
||||
@amber-A100: #ffe57f;
|
||||
@amber-A200: #ffd740;
|
||||
@amber-A400: #ffc400;
|
||||
@amber-A700: #ffab00;
|
||||
@amber: @amber-500;
|
||||
|
||||
|
||||
@orange-50: #fff3e0;
|
||||
@orange-100: #ffe0b2;
|
||||
@orange-200: #ffcc80;
|
||||
@orange-300: #ffb74d;
|
||||
@orange-400: #ffa726;
|
||||
@orange-500: #ff9800;
|
||||
@orange-600: #fb8c00;
|
||||
@orange-700: #f57c00;
|
||||
@orange-800: #ef6c00;
|
||||
@orange-900: #e65100;
|
||||
@orange-A100: #ffd180;
|
||||
@orange-A200: #ffab40;
|
||||
@orange-A400: #ff9100;
|
||||
@orange-A700: #ff6d00;
|
||||
@orange: @orange-500;
|
||||
|
||||
|
||||
@deep-orange-50: #fbe9e7;
|
||||
@deep-orange-100: #ffccbc;
|
||||
@deep-orange-200: #ffab91;
|
||||
@deep-orange-300: #ff8a65;
|
||||
@deep-orange-400: #ff7043;
|
||||
@deep-orange-500: #ff5722;
|
||||
@deep-orange-600: #f4511e;
|
||||
@deep-orange-700: #e64a19;
|
||||
@deep-orange-800: #d84315;
|
||||
@deep-orange-900: #bf360c;
|
||||
@deep-orange-A100: #ff9e80;
|
||||
@deep-orange-A200: #ff6e40;
|
||||
@deep-orange-A400: #ff3d00;
|
||||
@deep-orange-A700: #dd2c00;
|
||||
@deep-orange: @deep-orange-500;
|
||||
|
||||
|
||||
@brown-50: #efebe9;
|
||||
@brown-100: #d7ccc8;
|
||||
@brown-200: #bcaaa4;
|
||||
@brown-300: #a1887f;
|
||||
@brown-400: #8d6e63;
|
||||
@brown-500: #795548;
|
||||
@brown-600: #6d4c41;
|
||||
@brown-700: #5d4037;
|
||||
@brown-800: #4e342e;
|
||||
@brown-900: #3e2723;
|
||||
@brown-A100: #d7ccc8;
|
||||
@brown-A200: #bcaaa4;
|
||||
@brown-A400: #8d6e63;
|
||||
@brown-A700: #5d4037;
|
||||
@brown: @brown-500;
|
||||
|
||||
|
||||
@grey-50: #fafafa;
|
||||
@grey-100: #f5f5f5;
|
||||
@grey-200: #eeeeee;
|
||||
@grey-300: #e0e0e0;
|
||||
@grey-400: #bdbdbd;
|
||||
@grey-500: #9e9e9e; @rgb-grey-500: "158, 158, 158";
|
||||
@grey-600: #757575;
|
||||
@grey-700: #616161;
|
||||
@grey-800: #424242;
|
||||
@grey-900: #212121;
|
||||
@grey-A100: #f5f5f5;
|
||||
@grey-A200: #eeeeee;
|
||||
@grey-A400: #bdbdbd;
|
||||
@grey-A700: #616161;
|
||||
@grey: @grey-500;
|
||||
|
||||
|
||||
@blue-grey-50: #eceff1;
|
||||
@blue-grey-100: #cfd8dc;
|
||||
@blue-grey-200: #b0bec5;
|
||||
@blue-grey-300: #90a4ae;
|
||||
@blue-grey-400: #78909c;
|
||||
@blue-grey-500: #607d8b;
|
||||
@blue-grey-600: #546e7a;
|
||||
@blue-grey-700: #455a64;
|
||||
@blue-grey-800: #37474f;
|
||||
@blue-grey-900: #263238;
|
||||
@blue-grey-A100: #cfd8dc;
|
||||
@blue-grey-A200: #b0bec5;
|
||||
@blue-grey-A400: #78909c;
|
||||
@blue-grey-A700: #455a64;
|
||||
@blue-grey: @blue-grey-500;
|
||||
|
||||
|
||||
@black: #000000; @rgb-black: "0,0,0";
|
||||
@white: #ffffff; @rgb-white: "255,255,255";
|
|
@ -0,0 +1,56 @@
|
|||
@import './reset.less';
|
||||
@import './animate.less';
|
||||
*, *::after, *::before {
|
||||
-webkit-user-drag: none;
|
||||
}
|
||||
|
||||
html {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.nobreak {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.auto-hidden {
|
||||
.mixin-ellipsis-1;
|
||||
}
|
||||
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.break {
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.select {
|
||||
user-select: text;
|
||||
}
|
||||
.no-select {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
|
||||
small {
|
||||
font-size: .8em;
|
||||
}
|
||||
.small {
|
||||
font-size: .9em;
|
||||
}
|
||||
strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.underline {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
svg {
|
||||
transition: @transition-theme;
|
||||
transition-property: fill;
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
@import './variables.less';
|
||||
|
||||
|
||||
/*自动隐藏文字*/
|
||||
.mixin-ellipsis-1() {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.mixin-ellipsis() {
|
||||
display: -webkit-box;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
white-space: normal !important;
|
||||
-webkit-line-clamp: 1;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
.mixin-ellipsis-2() {
|
||||
display: -webkit-box;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
white-space: normal !important;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
html, body, div, span, applet, object, iframe,
|
||||
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
||||
a, abbr, acronym, address, big, cite, code,
|
||||
del, dfn, em, img, ins, kbd, q, s, samp,
|
||||
small, strike, strong, sub, sup, tt, var,
|
||||
b, u, i, center,
|
||||
dl, dt, dd, ol, ul, li,
|
||||
fieldset, form, label, legend,
|
||||
table, caption, tbody, tfoot, thead, tr, th, td,
|
||||
article, aside, canvas, details, embed,
|
||||
figure, figcaption, footer, header, hgroup,
|
||||
menu, nav, output, ruby, section, summary,
|
||||
time, mark, audio, video {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
font-size: 100%;
|
||||
font: inherit;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
/* HTML5 display-role reset for older browsers */
|
||||
article, aside, details, figcaption, figure,
|
||||
footer, header, hgroup, menu, nav, section {
|
||||
display: block;
|
||||
}
|
||||
body {
|
||||
line-height: 1;
|
||||
}
|
||||
ol, ul {
|
||||
list-style: none;
|
||||
}
|
||||
blockquote, q {
|
||||
quotes: none;
|
||||
}
|
||||
blockquote:before, blockquote:after,
|
||||
q:before, q:after {
|
||||
content: '';
|
||||
content: none;
|
||||
}
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
@import './colors.less';
|
||||
|
||||
@themes: green, yellow, blue, red, pink, purple, orange, grey, ming, blue2;
|
||||
|
||||
|
||||
// Colors
|
||||
// @color-theme: #03a678;
|
||||
@color-theme: #07c556;
|
||||
@color-theme_2: rgba(255, 255, 255, 1);
|
||||
@color-theme-lyric: @color-theme_2;
|
||||
@color-theme-lyric_2:@color-theme;
|
||||
|
||||
@color-green-theme: #07c556;
|
||||
@color-green-theme_2: rgba(255, 255, 255, 1);
|
||||
@color-green-theme-lyric: @color-green-theme_2;
|
||||
@color-green-theme-lyric_2: @color-green-theme;
|
||||
|
||||
@color-yellow-theme: #fffa12;
|
||||
@color-yellow-theme_2: rgba(255, 255, 255, 1);
|
||||
@color-yellow-theme-lyric: @color-yellow-theme_2;
|
||||
@color-yellow-theme-lyric_2: @color-yellow-theme;
|
||||
|
||||
@color-blue-theme: #19b5fe;
|
||||
@color-blue-theme_2: rgba(255, 255, 255, 1);
|
||||
@color-blue-theme-lyric: @color-blue-theme_2;
|
||||
@color-blue-theme-lyric_2: @color-blue-theme;
|
||||
|
||||
@color-red-theme: #ff1222;
|
||||
@color-red-theme_2: rgba(255, 255, 255, 1);
|
||||
@color-red-theme-lyric: @color-red-theme_2;
|
||||
@color-red-theme-lyric_2: @color-red-theme;
|
||||
|
||||
@color-pink-theme: #f1828d;
|
||||
@color-pink-theme_2: rgba(255, 255, 255, 1);
|
||||
@color-pink-theme-lyric: @color-pink-theme_2;
|
||||
@color-pink-theme-lyric_2: @color-pink-theme;
|
||||
|
||||
@color-purple-theme: #c851d4;
|
||||
@color-purple-theme_2: rgba(255, 255, 255, 1);
|
||||
@color-purple-theme-lyric: @color-purple-theme_2;
|
||||
@color-purple-theme-lyric_2: @color-purple-theme;
|
||||
|
||||
@color-orange-theme: #ffad12;
|
||||
@color-orange-theme_2: rgba(255, 255, 255, 1);
|
||||
@color-orange-theme-lyric: @color-orange-theme_2;
|
||||
@color-orange-theme-lyric_2: @color-orange-theme;
|
||||
|
||||
@color-grey-theme: #bdc3c7;
|
||||
@color-grey-theme_2: rgba(255, 255, 255, 1);
|
||||
@color-grey-theme-lyric: @color-grey-theme_2;
|
||||
@color-grey-theme-lyric_2: @color-grey-theme;
|
||||
|
||||
@color-ming-theme: #336e7b;
|
||||
@color-ming-theme_2: rgba(255, 255, 255, 1);
|
||||
@color-ming-theme-lyric: @color-ming-theme_2;
|
||||
@color-ming-theme-lyric_2: @color-ming-theme;
|
||||
|
||||
@color-blue2-theme: #6b7bd8;
|
||||
@color-blue2-theme_2: rgba(255, 255, 255, 1);
|
||||
@color-blue2-theme-lyric: @color-blue2-theme_2;
|
||||
@color-blue2-theme-lyric_2: @color-blue2-theme;
|
||||
|
||||
|
||||
// Width
|
||||
@width-app-left: 6.6%;
|
||||
|
||||
// Height
|
||||
@height-toolbar: 54px;
|
||||
@height-player: 60px;
|
||||
|
||||
|
||||
// Shadow
|
||||
@shadow-app: 8px;
|
||||
|
||||
|
||||
// Radius
|
||||
@radius-progress-border: 5px;
|
||||
@radius-border: 4px;
|
||||
|
||||
@transition-theme: .4s ease;
|
||||
|
||||
@form-radius: 3px;
|
|
@ -0,0 +1,62 @@
|
|||
<template lang="pug">
|
||||
input(:class="$style.input" :type="type" :placeholder="placeholder" v-model.trim="text" :disabled="disabled"
|
||||
@focus="$emit('focus', $event)" @blur="$emit('blur', $event)" @input="$emit('input', text)" @change="$emit('change', text)"
|
||||
@keyup.enter="submit")
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
value: {
|
||||
type: [String, Number],
|
||||
default: '',
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: 'text',
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
text: '',
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
value(n) {
|
||||
this.text = n
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleInput() {
|
||||
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" module>
|
||||
@import '../../assets/styles/layout.less';
|
||||
|
||||
.input {
|
||||
background: none;
|
||||
border: none;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, .7);
|
||||
outline: none;
|
||||
color: #fff;
|
||||
// height: 28px;
|
||||
box-sizing: border-box;
|
||||
transition: border-color @transition-theme;
|
||||
&:focus {
|
||||
border-color: rgba(255, 255, 255, 1);
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
|
@ -0,0 +1,119 @@
|
|||
<template lang="pug">
|
||||
div(:class="$style.quantity")
|
||||
button(:class="[$style.btn, $style.minus]" @click="handleMinusClick") -
|
||||
input(:class="$style.input" ref="dom_input" :value="text" :disabled="disabled" @focus="$emit('focus', $event)" @blur="$emit('blur', $event)" @input="handleInput"
|
||||
@change="$emit('change', text)" @keyup.enter="submit" type="number" :min="min" :max="max")
|
||||
button(:class="[$style.btn, $style.add]" @click="handleAddClick") +
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
min: {
|
||||
type: Number,
|
||||
},
|
||||
max: {
|
||||
type: Number,
|
||||
},
|
||||
step: {
|
||||
type: Number,
|
||||
default: 20,
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
value: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
text: 0,
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
value(n) {
|
||||
this.text = n
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.text = this.value
|
||||
},
|
||||
methods: {
|
||||
handleInput() {
|
||||
let num = parseInt(this.$refs.dom_input.value)
|
||||
console.log(this.$refs.dom_input.value)
|
||||
if (Number.isNaN(num)) num = this.text
|
||||
if (this.min != null && this.min > num) {
|
||||
num = this.min
|
||||
} else if (this.max != null && this.max < num) {
|
||||
num = this.max
|
||||
}
|
||||
this.text = this.$refs.dom_input.value = num
|
||||
this.$emit('input', this.text)
|
||||
},
|
||||
handleMinusClick() {
|
||||
let num = this.text - this.step
|
||||
this.$refs.dom_input.value = this.min == null ? num : Math.max(num, this.min)
|
||||
this.handleInput()
|
||||
},
|
||||
handleAddClick() {
|
||||
let num = this.text + this.step
|
||||
this.$refs.dom_input.value = this.max == null ? num : Math.min(num, this.max)
|
||||
this.handleInput()
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" module>
|
||||
@import '../../assets/styles/layout.less';
|
||||
.quantity {
|
||||
display: flex;
|
||||
width: 160px;
|
||||
opacity: .9;
|
||||
}
|
||||
|
||||
.input::-webkit-inner-spin-button,
|
||||
.input::-webkit-outer-spin-button {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.input,
|
||||
.btn {
|
||||
height: 30px;
|
||||
text-align: center;
|
||||
background: transparent;
|
||||
border: 1px solid #fff;
|
||||
color: #fff;
|
||||
outline: none;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.input {
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
width: 60px;
|
||||
position: relative;
|
||||
// font-weight: 900;
|
||||
}
|
||||
|
||||
.btn {
|
||||
width: 30px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.minus {
|
||||
border-top-left-radius: 4px;
|
||||
border-bottom-left-radius: 4px;
|
||||
}
|
||||
.add {
|
||||
border-top-right-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
}
|
||||
|
||||
</style>
|
|
@ -0,0 +1,277 @@
|
|||
<template lang="pug">
|
||||
div(:class="$style.container")
|
||||
transition(enter-active-class="animated-fast fadeIn" leave-active-class="animated fadeOut")
|
||||
div(:class="$style.btns" v-show="!isShowThemeList")
|
||||
button(:class="$style.btn" @click="handleClose" :title="$t('desktopLyric.close')")
|
||||
svg(version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' height='20px' viewBox='0 0 24 24' space='preserve')
|
||||
use(xlink:href='#icon-close')
|
||||
button(:class="$style.btn" @click="handleLock" :title="$t('desktopLyric.' + (lrcConfig.isLock ? 'unlock' : 'lock'))")
|
||||
svg(v-if="config.isLock" version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' height='20px' viewBox='0 0 24 24' space='preserve')
|
||||
use(xlink:href='#icon-unlock')
|
||||
svg(v-else version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' height='20px' viewBox='0 0 24 24' space='preserve')
|
||||
use(xlink:href='#icon-lock')
|
||||
button(:class="$style.btn" :title="$t('desktopLyric.theme')" @click="isShowThemeList = true")
|
||||
svg(version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' height='20px' viewBox='0 0 24 24' space='preserve')
|
||||
use(xlink:href='#icon-theme')
|
||||
button(:class="$style.btn" @click="handleFontChange('increase', 10)" @contextmenu="handleFontChange('increase', 1)" :title="$t('desktopLyric.font_increase')")
|
||||
svg(version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' height='20px' viewBox='0 0 24 24' space='preserve')
|
||||
use(xlink:href='#icon-font-increase')
|
||||
button(:class="$style.btn" @click="handleFontChange('decrease', 10)" @contextmenu="handleFontChange('decrease', 1)" :title="$t('desktopLyric.font_decrease')")
|
||||
svg(version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' height='20px' viewBox='0 0 24 24' space='preserve')
|
||||
use(xlink:href='#icon-font-decrease')
|
||||
button(:class="$style.btn" @click="handleOpactiyChange('increase', 10)" @contextmenu="handleOpactiyChange('increase', 2)" :title="$t('desktopLyric.opactiy_increase')")
|
||||
svg(version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' height='20px' viewBox='0 0 24 24' space='preserve')
|
||||
use(xlink:href='#icon-opactiy-increase')
|
||||
button(:class="$style.btn" @click="handleOpactiyChange('decrease', 10)" @contextmenu="handleOpactiyChange('decrease', 2)" :title="$t('desktopLyric.opactiy_decrease')")
|
||||
svg(version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' height='20px' viewBox='0 0 24 24' space='preserve')
|
||||
use(xlink:href='#icon-opactiy-decrease')
|
||||
|
||||
//- button(:class="$style.btn" v-text="lrcConfig.style.isZoomActiveLrc ? '取消缩放' : '缩放歌词'" @click="handleZoomLrc")
|
||||
button(:class="$style.btn" @click="handleZoomLrc" :title="$t('desktopLyric.' + (lrcConfig.style.isZoomActiveLrc ? 'lrc_active_zoom_off' : 'lrc_active_zoom_on'))")
|
||||
svg(v-if="config.style.isZoomActiveLrc" version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' height='20px' viewBox='0 0 24 24' space='preserve')
|
||||
use(xlink:href='#icon-vibrate-off')
|
||||
svg(v-else version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' height='20px' viewBox='0 0 24 24' space='preserve')
|
||||
use(xlink:href='#icon-vibrate')
|
||||
|
||||
button(:class="$style.btn" @click="handleAlwaysOnTop" :title="$t('desktopLyric.' + (lrcConfig.isAlwaysOnTop ? 'win_top_off' : 'win_top_on'))")
|
||||
svg(v-if="config.isAlwaysOnTop" version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' height='20px' viewBox='0 0 24 24' space='preserve')
|
||||
use(xlink:href='#icon-top-off')
|
||||
svg(v-else version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' height='20px' viewBox='0 0 24 24' space='preserve')
|
||||
use(xlink:href='#icon-top-on')
|
||||
//- base-quantity(v-model="config.style.fontSize" :min="30" :step="2" :max="1000" @input="sendEvent")
|
||||
//- base-quantity(v-model="config.style.opacity" :min="5" :step="5" :max="100" @input="sendEvent")
|
||||
transition(enter-active-class="animated slideInDown" leave-active-class="animated-fast slideOutUp")
|
||||
div(:class="$style.themes" v-show="isShowThemeList")
|
||||
ul(:class="$style.themeList")
|
||||
li(:class="$style.btnBack")
|
||||
button(:class="$style.btn" @click="isShowThemeList = false" :title="$t('desktopLyric.back')")
|
||||
svg(version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' height='20px' viewBox='0 0 512 512' space='preserve')
|
||||
use(xlink:href='#icon-back')
|
||||
li(:class="[$style.themeItem, theme.className, lrcConfig.theme == theme.id ? $style.active : null]" v-for="theme in themes" @click="handleToggleTheme(theme)")
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { rendererSend, NAMES } from '../../../common/ipc'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
lrcConfig: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {
|
||||
enable: false,
|
||||
isLock: false,
|
||||
isAlwaysOnTop: false,
|
||||
width: 600,
|
||||
height: 700,
|
||||
x: -1,
|
||||
y: -1,
|
||||
theme: '',
|
||||
style: {
|
||||
fontSize: 125,
|
||||
opacity: 80,
|
||||
isZoomActiveLrc: true,
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
themes: {
|
||||
type: Array,
|
||||
default() {
|
||||
return []
|
||||
},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
config: {
|
||||
enable: false,
|
||||
isLock: false,
|
||||
isAlwaysOnTop: false,
|
||||
theme: 0,
|
||||
style: {
|
||||
fontSize: 125,
|
||||
opacity: 80,
|
||||
isZoomActiveLrc: true,
|
||||
},
|
||||
},
|
||||
isShowThemeList: false,
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
lrcConfig: {
|
||||
handler(n) {
|
||||
this.config = JSON.parse(JSON.stringify(n))
|
||||
},
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.config = JSON.parse(JSON.stringify(this.lrcConfig))
|
||||
},
|
||||
methods: {
|
||||
sendEvent() {
|
||||
rendererSend(NAMES.winLyric.set_lyric_config, this.config)
|
||||
},
|
||||
handleClose() {
|
||||
this.config.enable = false
|
||||
this.sendEvent()
|
||||
},
|
||||
handleLock() {
|
||||
this.config.isLock = true
|
||||
this.sendEvent()
|
||||
},
|
||||
handleAlwaysOnTop() {
|
||||
this.config.isAlwaysOnTop = !this.config.isAlwaysOnTop
|
||||
this.sendEvent()
|
||||
},
|
||||
handleZoomLrc() {
|
||||
this.config.style.isZoomActiveLrc = !this.config.style.isZoomActiveLrc
|
||||
this.sendEvent()
|
||||
},
|
||||
handleFontChange(action, step) {
|
||||
let num
|
||||
switch (action) {
|
||||
case 'increase':
|
||||
num = Math.min(this.config.style.fontSize + step, 1000)
|
||||
break
|
||||
case 'decrease':
|
||||
num = Math.max(this.config.style.fontSize - step, 30)
|
||||
break
|
||||
}
|
||||
if (this.config.style.fontSize == num) return
|
||||
this.config.style.fontSize = num
|
||||
this.sendEvent()
|
||||
},
|
||||
handleOpactiyChange(action, step) {
|
||||
let num
|
||||
switch (action) {
|
||||
case 'increase':
|
||||
num = Math.min(this.config.style.opacity + step, 100)
|
||||
break
|
||||
case 'decrease':
|
||||
num = Math.max(this.config.style.opacity - step, 6)
|
||||
break
|
||||
}
|
||||
if (this.config.style.opacity == num) return
|
||||
this.config.style.opacity = num
|
||||
this.sendEvent()
|
||||
},
|
||||
handleToggleTheme(theme) {
|
||||
this.config.theme = theme.id
|
||||
this.sendEvent()
|
||||
},
|
||||
// handleUpdateSetting() {
|
||||
// this.sendEvent()
|
||||
// },
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" module>
|
||||
@import '../../assets/styles/layout.less';
|
||||
|
||||
@bar-height: 38px;
|
||||
|
||||
.container {
|
||||
position: relative;
|
||||
// height: 50px;
|
||||
transition: opacity @transition-theme;
|
||||
// opacity: 0;
|
||||
// &:hover {
|
||||
// opacity: 1;
|
||||
// }
|
||||
}
|
||||
|
||||
.btns {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
align-items: center;
|
||||
background-color: rgba(0, 0, 0, 0.7);
|
||||
}
|
||||
|
||||
.btn {
|
||||
min-height: @bar-height;
|
||||
padding: 0 10px;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
outline: none;
|
||||
background: none;
|
||||
color: #fff;
|
||||
transition: color @transition-theme;
|
||||
&:hover {
|
||||
color: @color-theme;
|
||||
}
|
||||
}
|
||||
|
||||
.themes {
|
||||
width: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.7);
|
||||
|
||||
&:global(.slideInDown), &:global(.slideOutUp) {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.theme-list {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
min-height: @bar-height;
|
||||
padding-top: (@bar-height - 24px) / 2;
|
||||
padding-left: (@bar-height - 24px) / 2;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.btnBack {
|
||||
margin-top: -(@bar-height - 24px) / 2;
|
||||
margin-left: -(@bar-height - 24px) / 2;
|
||||
}
|
||||
|
||||
.theme-item {
|
||||
display: block;
|
||||
margin-bottom: (@bar-height - 24px) / 2;
|
||||
margin-right: (@bar-height - 24px) / 2;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: @radius-border;
|
||||
border: 2px solid transparent;
|
||||
box-sizing: border-box;
|
||||
padding: 2px;
|
||||
cursor: pointer;
|
||||
transition: border-color @transition-theme;
|
||||
&.active {
|
||||
border-color: @color-theme;
|
||||
}
|
||||
&:after {
|
||||
display: block;
|
||||
content: ' ';
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: @radius-border;
|
||||
}
|
||||
each(@themes, {
|
||||
&:global(.@{value}) {
|
||||
&:after {
|
||||
background-color: ~'@{color-@{value}-theme}';
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
each(@themes, {
|
||||
:global(#container.@{value}) {
|
||||
.btn {
|
||||
&:hover {
|
||||
color: ~'@{color-@{value}-theme}';
|
||||
}
|
||||
}
|
||||
.theme-item {
|
||||
&.active {
|
||||
border-color: ~'@{color-@{value}-theme}';
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
</style>
|
|
@ -0,0 +1,59 @@
|
|||
<template lang="pug">
|
||||
svg(version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' style="display: none;")
|
||||
defs
|
||||
g#icon-close(fill='currentColor')
|
||||
// 0 0 24 24
|
||||
path(d='M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z')
|
||||
|
||||
g#icon-unlock(fill='currentColor')
|
||||
// 0 0 24 24
|
||||
path(d='M18,20V10H6V20H18M18,8A2,2 0 0,1 20,10V20A2,2 0 0,1 18,22H6C4.89,22 4,21.1 4,20V10A2,2 0 0,1 6,8H15V6A3,3 0 0,0 12,3A3,3 0 0,0 9,6H7A5,5 0 0,1 12,1A5,5 0 0,1 17,6V8H18M12,17A2,2 0 0,1 10,15A2,2 0 0,1 12,13A2,2 0 0,1 14,15A2,2 0 0,1 12,17Z')
|
||||
|
||||
g#icon-lock(fill='currentColor')
|
||||
// 0 0 24 24
|
||||
path(d='M12,17C10.89,17 10,16.1 10,15C10,13.89 10.89,13 12,13A2,2 0 0,1 14,15A2,2 0 0,1 12,17M18,20V10H6V20H18M18,8A2,2 0 0,1 20,10V20A2,2 0 0,1 18,22H6C4.89,22 4,21.1 4,20V10C4,8.89 4.89,8 6,8H7V6A5,5 0 0,1 12,1A5,5 0 0,1 17,6V8H18M12,3A3,3 0 0,0 9,6V8H15V6A3,3 0 0,0 12,3Z')
|
||||
|
||||
g#icon-font-decrease(fill='currentColor')
|
||||
// 0 0 24 24
|
||||
path(d='M5.12,14L7.5,7.67L9.87,14M6.5,5L1,19H3.25L4.37,16H10.62L11.75,19H14L8.5,5H6.5M18,17L23,11.93L21.59,10.5L19,13.1V7H17V13.1L14.41,10.5L13,11.93L18,17Z')
|
||||
|
||||
g#icon-font-increase(fill='currentColor')
|
||||
// 0 0 24 24
|
||||
path(d='M5.12,14L7.5,7.67L9.87,14M6.5,5L1,19H3.25L4.37,16H10.62L11.75,19H14L8.5,5H6.5M18,7L13,12.07L14.41,13.5L17,10.9V17H19V10.9L21.59,13.5L23,12.07L18,7Z')
|
||||
|
||||
g#icon-opactiy-increase(fill='currentColor')
|
||||
// 0 0 24 24
|
||||
path(d="M12,6A6,6 0 0,1 18,12C18,14.22 16.79,16.16 15,17.2V19A1,1 0 0,1 14,20H10A1,1 0 0,1 9,19V17.2C7.21,16.16 6,14.22 6,12A6,6 0 0,1 12,6M14,21V22A1,1 0 0,1 13,23H11A1,1 0 0,1 10,22V21H14M20,11H23V13H20V11M1,11H4V13H1V11M13,1V4H11V1H13M4.92,3.5L7.05,5.64L5.63,7.05L3.5,4.93L4.92,3.5M16.95,5.63L19.07,3.5L20.5,4.93L18.37,7.05L16.95,5.63Z")
|
||||
//- path(d='M17.66,8L12,2.35L6.34,8C4.78,9.56 4,11.64 4,13.64C4,15.64 4.78,17.75 6.34,19.31C7.9,20.87 9.95,21.66 12,21.66C14.05,21.66 16.1,20.87 17.66,19.31C19.22,17.75 20,15.64 20,13.64C20,11.64 19.22,9.56 17.66,8M6,14C6,12 6.62,10.73 7.76,9.6L12,5.27L16.24,9.65C17.38,10.77 18,12 18,14H6Z')
|
||||
|
||||
g#icon-opactiy-decrease(fill='currentColor')
|
||||
// 0 0 24 24
|
||||
path(d="M20,11H23V13H20V11M1,11H4V13H1V11M13,1V4H11V1H13M4.92,3.5L7.05,5.64L5.63,7.05L3.5,4.93L4.92,3.5M16.95,5.63L19.07,3.5L20.5,4.93L18.37,7.05L16.95,5.63M12,6A6,6 0 0,1 18,12C18,14.22 16.79,16.16 15,17.2V19A1,1 0 0,1 14,20H10A1,1 0 0,1 9,19V17.2C7.21,16.16 6,14.22 6,12A6,6 0 0,1 12,6M14,21V22A1,1 0 0,1 13,23H11A1,1 0 0,1 10,22V21H14M11,18H13V15.87C14.73,15.43 16,13.86 16,12A4,4 0 0,0 12,8A4,4 0 0,0 8,12C8,13.86 9.27,15.43 11,15.87V18Z")
|
||||
|
||||
g#icon-top-on(fill='currentColor')
|
||||
// 0 0 24 24
|
||||
path(d="M16,12V4H17V2H7V4H8V12L6,14V16H11.2V22H12.8V16H18V14L16,12Z")
|
||||
//- path(d='M17.66,8L12,2.35L6.34,8C4.78,9.56 4,11.64 4,13.64C4,15.64 4.78,17.75 6.34,19.31C7.9,20.87 9.95,21.66 12,21.66C14.05,21.66 16.1,20.87 17.66,19.31C19.22,17.75 20,15.64 20,13.64C20,11.64 19.22,9.56 17.66,8M6,14C6,12 6.62,10.73 7.76,9.6L12,5.27L16.24,9.65C17.38,10.77 18,12 18,14H6Z')
|
||||
|
||||
g#icon-top-off(fill='currentColor')
|
||||
// 0 0 24 24
|
||||
path(d="M2,5.27L3.28,4L20,20.72L18.73,22L12.8,16.07V22H11.2V16H6V14L8,12V11.27L2,5.27M16,12L18,14V16H17.82L8,6.18V4H7V2H17V4H16V12Z")
|
||||
|
||||
g#icon-theme(fill='currentColor')
|
||||
// 0 0 24 24
|
||||
path(d='M17.5,12A1.5,1.5 0 0,1 16,10.5A1.5,1.5 0 0,1 17.5,9A1.5,1.5 0 0,1 19,10.5A1.5,1.5 0 0,1 17.5,12M14.5,8A1.5,1.5 0 0,1 13,6.5A1.5,1.5 0 0,1 14.5,5A1.5,1.5 0 0,1 16,6.5A1.5,1.5 0 0,1 14.5,8M9.5,8A1.5,1.5 0 0,1 8,6.5A1.5,1.5 0 0,1 9.5,5A1.5,1.5 0 0,1 11,6.5A1.5,1.5 0 0,1 9.5,8M6.5,12A1.5,1.5 0 0,1 5,10.5A1.5,1.5 0 0,1 6.5,9A1.5,1.5 0 0,1 8,10.5A1.5,1.5 0 0,1 6.5,12M12,3A9,9 0 0,0 3,12A9,9 0 0,0 12,21A1.5,1.5 0 0,0 13.5,19.5C13.5,19.11 13.35,18.76 13.11,18.5C12.88,18.23 12.73,17.88 12.73,17.5A1.5,1.5 0 0,1 14.23,16H16A5,5 0 0,0 21,11C21,6.58 16.97,3 12,3Z')
|
||||
|
||||
g#icon-vibrate(fill='currentColor')
|
||||
// 0 0 24 24
|
||||
path(d="M16,19H8V5H16M16.5,3H7.5A1.5,1.5 0 0,0 6,4.5V19.5A1.5,1.5 0 0,0 7.5,21H16.5A1.5,1.5 0 0,0 18,19.5V4.5A1.5,1.5 0 0,0 16.5,3M19,17H21V7H19M22,9V15H24V9M3,17H5V7H3M0,15H2V9H0V15Z")
|
||||
|
||||
g#icon-vibrate-off(fill='currentColor')
|
||||
// 0 0 24 24
|
||||
path(d="M8.2,5L6.55,3.35C6.81,3.12 7.15,3 7.5,3H16.5A1.5,1.5 0 0,1 18,4.5V14.8L16,12.8V5H8.2M0,15H2V9H0V15M21,17V7H19V15.8L20.2,17H21M3,17H5V7H3V17M18,17.35L22.11,21.46L20.84,22.73L18,19.85C17.83,20.54 17.21,21 16.5,21H7.5A1.5,1.5 0 0,1 6,19.5V7.89L1.11,3L2.39,1.73L6.09,5.44L8,7.34L16,15.34L18,17.34V17.35M16,17.89L8,9.89V19H16V17.89M22,9V15H24V9H22Z")
|
||||
|
||||
|
||||
g#icon-back(fill='currentColor')
|
||||
// 0 0 512 512
|
||||
path(d='M511.563,434.259c-1.728-142.329-124.42-258.242-277.087-263.419V95.999c0-17.645-14.342-31.999-31.974-31.999 c-7.931,0-15.591,3.042-21.524,8.562c0,0-134.828,124.829-173.609,163.755C2.623,241.109,0,248.088,0,255.994 c0,7.906,2.623,14.885,7.369,19.687c38.781,38.915,173.609,163.745,173.609,163.745c5.933,5.521,13.593,8.562,21.524,8.562 c17.631,0,31.974-14.354,31.974-31.999v-74.591c153.479,2.156,255.792,50.603,255.792,95.924c0,5.896,4.767,10.666,10.658,10.666 c0.167,0.021,0.333,0.01,0.416,0c5.891,0,10.658-4.771,10.658-10.666C512,436.259,511.854,435.228,511.563,434.259z')
|
||||
</template>
|
||||
|
|
@ -0,0 +1,327 @@
|
|||
<template lang="pug">
|
||||
div(:class="[$style.lyric, lyricEvent.isMsDown ? $style.draging : null]" :style="lrcStyles" @mousedown="handleLyricMouseDown" ref="dom_lyric")
|
||||
div(:class="$style.lyricSpace")
|
||||
div(v-for="(info, index) in lyricLines" :key="index" :class="[$style.lineContent, lyric.line == index ? (lrcConfig.style.isZoomActiveLrc ? $style.lrcActiveZoom : $style.lrcActive) : null]")
|
||||
p(:class="$style.lrcLine") {{info.text}}
|
||||
div(:class="$style.lyricSpace")
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { rendererOn, rendererSend, NAMES } from '../../../common/ipc'
|
||||
import { scrollTo } from '../../../renderer/utils'
|
||||
import Lyric from 'lrc-file-parser'
|
||||
|
||||
let cancelScrollFn = null
|
||||
|
||||
export default {
|
||||
props: {
|
||||
lrcConfig: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {
|
||||
style: {
|
||||
fontSize: 125,
|
||||
opacity: 80,
|
||||
isZoomActiveLrc: true,
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
musicInfo: {
|
||||
songmid: null,
|
||||
name: '^',
|
||||
singer: '^',
|
||||
album: null,
|
||||
},
|
||||
lyric: {
|
||||
line: 0,
|
||||
lines: [],
|
||||
},
|
||||
dom_lines: [],
|
||||
clickTime: 0,
|
||||
lyricEvent: {
|
||||
isMsDown: false,
|
||||
msDownY: 0,
|
||||
msDownScrollY: 0,
|
||||
isStopScroll: false,
|
||||
timeout: null,
|
||||
},
|
||||
winEvent: {
|
||||
isMsDown: false,
|
||||
msDownX: 0,
|
||||
msDownY: 0,
|
||||
},
|
||||
_lyricLines: [],
|
||||
lyricLines: [],
|
||||
isSetedLines: false,
|
||||
isPlay: false,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
lrcStyles() {
|
||||
return {
|
||||
fontSize: this.lrcConfig.style.fontSize / 100 + 'rem',
|
||||
opacity: this.lrcConfig.style.opacity / 100,
|
||||
}
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
'lyric.lines': {
|
||||
handler(n, o) {
|
||||
this.isSetedLines = true
|
||||
if (o) {
|
||||
this._lyricLines = n
|
||||
if (n.length) {
|
||||
this.lyricLines = n
|
||||
this.$nextTick(() => {
|
||||
this.dom_lines = this.$refs.dom_lyric.querySelectorAll('p')
|
||||
this.handleScrollLrc()
|
||||
})
|
||||
} else {
|
||||
if (cancelScrollFn) {
|
||||
cancelScrollFn()
|
||||
cancelScrollFn = null
|
||||
}
|
||||
cancelScrollFn = scrollTo(this.$refs.dom_lyric, 0, 300, () => {
|
||||
if (this.lyricLines === this._lyricLines && this._lyricLines.length) return
|
||||
this.lyricLines = this._lyricLines
|
||||
this.$nextTick(() => {
|
||||
this.dom_lines = this.$refs.dom_lyric.querySelectorAll('p')
|
||||
this.handleScrollLrc()
|
||||
})
|
||||
}, 50)
|
||||
}
|
||||
} else {
|
||||
this.lyricLines = n
|
||||
this.$nextTick(() => {
|
||||
this.dom_lines = this.$refs.dom_lyric.querySelectorAll('p')
|
||||
this.handleScrollLrc()
|
||||
})
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
'lyric.line': {
|
||||
handler(n) {
|
||||
if (n < 0) return
|
||||
if (n == 0 && this.isSetedLines) return this.isSetedLines = false
|
||||
this.handleScrollLrc()
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
},
|
||||
created() {
|
||||
rendererOn(NAMES.winLyric.set_lyric_info, (event, data) => this.handleSetInfo(data))
|
||||
window.lrc = new Lyric({
|
||||
onPlay: (line, text) => {
|
||||
this.lyric.text = text
|
||||
this.lyric.line = line
|
||||
// console.log(line, text)
|
||||
},
|
||||
onSetLyric: lines => { // listening lyrics seting event
|
||||
// console.log(lines) // lines is array of all lyric text
|
||||
this.lyric.lines = lines
|
||||
this.lyric.line = 0
|
||||
},
|
||||
offset: 100,
|
||||
})
|
||||
},
|
||||
mounted() {
|
||||
document.addEventListener('mousemove', this.handleMouseMsMove)
|
||||
document.addEventListener('mouseup', this.handleMouseMsUp)
|
||||
rendererSend(NAMES.winLyric.get_lyric_info, 'info')
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.clearLyricScrollTimeout()
|
||||
document.removeEventListener('mousemove', this.handleMouseMsMove)
|
||||
document.removeEventListener('mouseup', this.handleMouseMsUp)
|
||||
},
|
||||
methods: {
|
||||
handleSetInfo({ type, data }) {
|
||||
// console.log(type, data)
|
||||
switch (type) {
|
||||
case 'lyric':
|
||||
window.lrc.setLyric(data)
|
||||
break
|
||||
case 'play':
|
||||
this.isPlay = true
|
||||
window.lrc.play(data)
|
||||
break
|
||||
case 'pause':
|
||||
this.isPlay = false
|
||||
window.lrc.pause()
|
||||
break
|
||||
case 'info':
|
||||
// console.log('info', data)
|
||||
window.lrc.setLyric(data.lyric)
|
||||
this.$nextTick(() => {
|
||||
this.lyric.line = data.line
|
||||
rendererSend(NAMES.winLyric.get_lyric_info, 'status')
|
||||
})
|
||||
case 'music_info':
|
||||
this.musicInfo.name = data.name
|
||||
this.musicInfo.songmid = data.songmid
|
||||
this.musicInfo.singer = data.singer
|
||||
this.musicInfo.album = data.album
|
||||
break
|
||||
|
||||
case 'status':
|
||||
// console.log('status', data)
|
||||
this.isPlay = data.isPlay
|
||||
this.lyric.line = data.line
|
||||
if (data.isPlay) window.lrc.play(data.played_time)
|
||||
break
|
||||
|
||||
default:
|
||||
break
|
||||
}
|
||||
// console.log(data)
|
||||
},
|
||||
handleResize() {
|
||||
this.setProgressWidth()
|
||||
},
|
||||
handleScrollLrc() {
|
||||
if (!this.dom_lines.length) return
|
||||
if (cancelScrollFn) {
|
||||
cancelScrollFn()
|
||||
cancelScrollFn = null
|
||||
}
|
||||
if (this.lyricEvent.isStopScroll) return
|
||||
let dom_p = this.dom_lines[this.lyric.line]
|
||||
cancelScrollFn = scrollTo(this.$refs.dom_lyric, dom_p ? (dom_p.offsetTop - this.$refs.dom_lyric.clientHeight * 0.38) : 0)
|
||||
},
|
||||
handleLyricMouseDown(e) {
|
||||
if (e.target.classList.contains(this.$style.lrcLine)) {
|
||||
this.lyricEvent.isMsDown = true
|
||||
this.lyricEvent.msDownY = e.clientY
|
||||
this.lyricEvent.msDownScrollY = this.$refs.dom_lyric.scrollTop
|
||||
} else {
|
||||
this.winEvent.isMsDown = true
|
||||
this.winEvent.msDownX = e.clientX
|
||||
this.winEvent.msDownY = e.clientY
|
||||
}
|
||||
},
|
||||
handleMouseMsUp(e) {
|
||||
this.lyricEvent.isMsDown = false
|
||||
this.winEvent.isMsDown = false
|
||||
},
|
||||
handleMouseMsMove(e) {
|
||||
if (this.lyricEvent.isMsDown) {
|
||||
if (!this.lyricEvent.isStopScroll) this.lyricEvent.isStopScroll = true
|
||||
if (cancelScrollFn) {
|
||||
cancelScrollFn()
|
||||
cancelScrollFn = null
|
||||
}
|
||||
this.$refs.dom_lyric.scrollTop = this.lyricEvent.msDownScrollY + this.lyricEvent.msDownY - e.clientY
|
||||
this.startLyricScrollTimeout()
|
||||
} else if (this.winEvent.isMsDown) {
|
||||
rendererSend(NAMES.winLyric.set_win_bounds, { x: e.clientX - this.winEvent.msDownX, y: e.clientY - this.winEvent.msDownY })
|
||||
}
|
||||
|
||||
// if (this.volumeEvent.isMsDown) {
|
||||
// let val = this.volumeEvent.msDownValue + (e.clientX - this.volumeEvent.msDownX) / 70
|
||||
// this.volume = val < 0 ? 0 : val > 1 ? 1 : val
|
||||
// if (this.audio) this.audio.volume = this.volume
|
||||
// }
|
||||
|
||||
// console.log(val)
|
||||
},
|
||||
startLyricScrollTimeout() {
|
||||
this.clearLyricScrollTimeout()
|
||||
this.lyricEvent.timeout = setTimeout(() => {
|
||||
this.lyricEvent.timeout = null
|
||||
this.lyricEvent.isStopScroll = false
|
||||
if (!this.isPlay) return
|
||||
this.handleScrollLrc()
|
||||
}, 3000)
|
||||
},
|
||||
clearLyricScrollTimeout() {
|
||||
if (!this.lyricEvent.timeout) return
|
||||
clearTimeout(this.lyricEvent.timeout)
|
||||
this.lyricEvent.timeout = null
|
||||
},
|
||||
close() {
|
||||
rendererSend(NAMES.winLyric.close)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" module>
|
||||
@import '../../assets/styles/layout.less';
|
||||
|
||||
.lyric {
|
||||
text-align: center;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
font-size: 68px;
|
||||
padding: 0 5px;
|
||||
opacity: .6;
|
||||
transition: opacity @transition-theme;
|
||||
&.draging {
|
||||
.lrc-line {
|
||||
cursor: grabbing;
|
||||
}
|
||||
}
|
||||
}
|
||||
.lrc-line {
|
||||
display: inline-block;
|
||||
padding: 8px 0;
|
||||
line-height: 1.2;
|
||||
overflow-wrap: break-word;
|
||||
transition: @transition-theme;
|
||||
transition-property: color, font-size, text-shadow;
|
||||
cursor: grab;
|
||||
// font-weight: bold;
|
||||
// background-clip: text;
|
||||
color: @color-theme-lyric;
|
||||
text-shadow: 1px 1px 2px #000;
|
||||
// background: linear-gradient(@color-theme-lyric, @color-theme-lyric);
|
||||
// background-clip: text;
|
||||
// -webkit-background-clip: text;
|
||||
// -webkit-text-fill-color: #fff;
|
||||
// -webkit-text-stroke: thin #124628;
|
||||
}
|
||||
.lyric-space {
|
||||
height: 70%;
|
||||
}
|
||||
.lrc-active {
|
||||
|
||||
.lrc-line {
|
||||
color: @color-theme-lyric_2;
|
||||
// background: linear-gradient(@color-theme-lyric, @color-theme-lyric_2);
|
||||
// background-clip: text;
|
||||
// -webkit-background-clip: text;
|
||||
// -webkit-text-fill-color: @color-theme-lyric_2;
|
||||
// -webkit-text-stroke: thin #124628;
|
||||
}
|
||||
}
|
||||
.lrc-active-zoom {
|
||||
.lrc-active;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
.footer {
|
||||
flex: 0 0 100px;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
|
||||
each(@themes, {
|
||||
:global(#container.@{value}) {
|
||||
.lrc-line {
|
||||
color: ~'@{color-@{value}-theme-lyric}';
|
||||
}
|
||||
.lrc-active, .lrc-active-zoom {
|
||||
.lrc-line {
|
||||
color: ~'@{color-@{value}-theme-lyric_2}';
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
</style>
|
|
@ -0,0 +1,13 @@
|
|||
import Vue from 'vue'
|
||||
import upperFirst from 'lodash/upperFirst'
|
||||
import camelCase from 'lodash/camelCase'
|
||||
|
||||
const requireComponent = require.context('./', true, /\.vue$/)
|
||||
|
||||
requireComponent.keys().forEach(fileName => {
|
||||
const componentConfig = requireComponent(fileName)
|
||||
|
||||
const componentName = upperFirst(camelCase(fileName.replace(/^\.\//, '').replace(/\.\w+$/, '')))
|
||||
|
||||
Vue.component(componentName, componentConfig.default || componentConfig)
|
||||
})
|
|
@ -0,0 +1,10 @@
|
|||
html(lang="cn")
|
||||
head
|
||||
meta(charset="UTF-8")
|
||||
meta(name="viewport" content="width=device-width, initial-scale=1.0")
|
||||
meta(http-equiv="X-UA-Compatible" content="ie=edge")
|
||||
title 桌面歌词-洛雪音乐助手
|
||||
|
||||
body
|
||||
#root
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
import Vue from 'vue'
|
||||
|
||||
import i18n from './plugins/i18n'
|
||||
|
||||
import './components'
|
||||
|
||||
import App from './App'
|
||||
|
||||
import '../common/error'
|
||||
|
||||
Vue.config.productionTip = false
|
||||
|
||||
new Vue({
|
||||
i18n,
|
||||
el: '#root',
|
||||
render: h => h(App),
|
||||
})
|
|
@ -0,0 +1,22 @@
|
|||
/**
|
||||
* Vue i18n
|
||||
*
|
||||
* @library
|
||||
*
|
||||
* http://kazupon.github.io/vue-i18n/en/
|
||||
*/
|
||||
|
||||
// Lib imports
|
||||
import Vue from 'vue'
|
||||
import VueI18n from 'vue-i18n'
|
||||
import messages from '../../renderer/lang'
|
||||
|
||||
Vue.use(VueI18n)
|
||||
|
||||
const i18n = window.i18n = new VueI18n({
|
||||
locale: 'cns',
|
||||
fallbackLocale: 'cns',
|
||||
messages,
|
||||
})
|
||||
|
||||
export default i18n
|
|
@ -24,7 +24,7 @@
|
|||
<script>
|
||||
import dnscache from 'dnscache'
|
||||
import { mapMutations, mapGetters, mapActions } from 'vuex'
|
||||
import { rendererOn, rendererSend, rendererInvoke } from '../common/ipc'
|
||||
import { rendererOn, rendererSend, rendererInvoke, NAMES } from '../common/ipc'
|
||||
import { isLinux } from '../common/utils'
|
||||
import music from './utils/music'
|
||||
import { throttle, openUrl } from './utils'
|
||||
|
@ -73,7 +73,6 @@ export default {
|
|||
created() {
|
||||
this.saveSetting = throttle(n => {
|
||||
window.electronStore_config.set('setting', n)
|
||||
rendererSend('updateAppSetting', n)
|
||||
})
|
||||
this.saveDefaultList = throttle(n => {
|
||||
window.electronStore_list.set('defaultList', n)
|
||||
|
@ -98,7 +97,8 @@ export default {
|
|||
},
|
||||
watch: {
|
||||
setting: {
|
||||
handler(n) {
|
||||
handler(n, o) {
|
||||
rendererSend(NAMES.mainWindow.set_app_setting, n)
|
||||
this.saveSetting(n)
|
||||
},
|
||||
deep: true,
|
||||
|
@ -144,16 +144,16 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
...mapActions(['getVersionInfo']),
|
||||
...mapMutations(['setNewVersion', 'setVersionModalVisible', 'setDownloadProgress', 'setSetting']),
|
||||
...mapMutations(['setNewVersion', 'setVersionModalVisible', 'setDownloadProgress', 'setSetting', 'setDesktopLyricConfig']),
|
||||
...mapMutations('list', ['initList']),
|
||||
...mapMutations('download', ['updateDownloadList']),
|
||||
init() {
|
||||
document.documentElement.style.fontSize = this.windowSizeActive.fontSize
|
||||
|
||||
rendererInvoke('getEnvParams').then(this.handleEnvParamsInit)
|
||||
rendererInvoke(NAMES.mainWindow.get_env_params).then(this.handleEnvParamsInit)
|
||||
|
||||
document.body.addEventListener('click', this.handleBodyClick, true)
|
||||
rendererOn('update-available', (e, info) => {
|
||||
rendererOn(NAMES.mainWindow.update_available, (e, info) => {
|
||||
// this.showUpdateModal(true)
|
||||
// console.log(info)
|
||||
this.setVersionModalVisible({ isDownloading: true })
|
||||
|
@ -168,7 +168,7 @@ export default {
|
|||
})
|
||||
})
|
||||
})
|
||||
rendererOn('update-error', (event, err) => {
|
||||
rendererOn(NAMES.mainWindow.update_error, (event, err) => {
|
||||
// console.log(err)
|
||||
this.clearUpdateTimeout()
|
||||
this.setVersionModalVisible({ isError: true })
|
||||
|
@ -176,11 +176,11 @@ export default {
|
|||
this.showUpdateModal()
|
||||
})
|
||||
})
|
||||
rendererOn('update-progress', (event, progress) => {
|
||||
rendererOn(NAMES.mainWindow.update_progress, (event, progress) => {
|
||||
// console.log(progress)
|
||||
this.setDownloadProgress(progress)
|
||||
})
|
||||
rendererOn('update-downloaded', info => {
|
||||
rendererOn(NAMES.mainWindow.update_downloaded, info => {
|
||||
// console.log(info)
|
||||
this.clearUpdateTimeout()
|
||||
this.setVersionModalVisible({ isDownloaded: true })
|
||||
|
@ -188,7 +188,7 @@ export default {
|
|||
this.showUpdateModal()
|
||||
})
|
||||
})
|
||||
rendererOn('update-not-available', (e, info) => {
|
||||
rendererOn(NAMES.mainWindow.update_not_available, (event, info) => {
|
||||
this.clearUpdateTimeout()
|
||||
this.setNewVersion({
|
||||
version: info.version,
|
||||
|
@ -196,6 +196,14 @@ export default {
|
|||
})
|
||||
this.setVersionModalVisible({ isLatestVer: true })
|
||||
})
|
||||
|
||||
rendererOn(NAMES.mainWindow.set_config, (event, config) => {
|
||||
// console.log(config)
|
||||
// this.setDesktopLyricConfig(config)
|
||||
// console.log('set_config', JSON.stringify(this.setting) === JSON.stringify(config))
|
||||
this.setSetting(Object.assign({}, this.setting, config))
|
||||
window.eventHub.$emit('set_config', config)
|
||||
})
|
||||
// 更新超时定时器
|
||||
this.updateTimeout = setTimeout(() => {
|
||||
this.updateTimeout = null
|
||||
|
@ -217,13 +225,13 @@ export default {
|
|||
},
|
||||
enableIgnoreMouseEvents() {
|
||||
if (this.isNt) return
|
||||
rendererSend('setIgnoreMouseEvents', false)
|
||||
rendererSend(NAMES.mainWindow.set_ignore_mouse_events, false)
|
||||
// console.log('content enable')
|
||||
},
|
||||
dieableIgnoreMouseEvents() {
|
||||
if (this.isNt) return
|
||||
// console.log('content disable')
|
||||
rendererSend('setIgnoreMouseEvents', true)
|
||||
rendererSend(NAMES.mainWindow.set_ignore_mouse_events, true)
|
||||
},
|
||||
|
||||
initData() { // 初始化数据
|
||||
|
@ -234,6 +242,8 @@ export default {
|
|||
let defaultList = window.electronStore_list.get('defaultList') || this.defaultList
|
||||
let loveList = window.electronStore_list.get('loveList') || this.loveList
|
||||
let userList = window.electronStore_list.get('userList') || this.userList
|
||||
if (!defaultList.list) defaultList.list = []
|
||||
if (!loveList.list) loveList.list = []
|
||||
this.initList({ defaultList, loveList, userList })
|
||||
},
|
||||
initDownloadList() {
|
||||
|
@ -270,6 +280,7 @@ export default {
|
|||
let len = Math.max(newVer.length, currentVer.length)
|
||||
newVer.padStart(len, '0')
|
||||
currentVer.padStart(len, '0')
|
||||
if (result.version == '0.0.0') return this.setVersionModalVisible({ isUnknow: true })
|
||||
if (parseInt(newVer) <= parseInt(currentVer)) return this.setVersionModalVisible({ isLatestVer: true })
|
||||
|
||||
if (result.version === this.setting.ignoreVersion) return
|
||||
|
@ -344,6 +355,10 @@ export default {
|
|||
@import './assets/styles/index.less';
|
||||
@import './assets/styles/layout.less';
|
||||
|
||||
html, body {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
body {
|
||||
user-select: none;
|
||||
height: 100vh;
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 353 KiB |
Binary file not shown.
Before Width: | Height: | Size: 181 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.1 MiB |
|
@ -1,6 +1,6 @@
|
|||
@import './colors.less';
|
||||
|
||||
@themes: green, yellow, blue, red, pink, purple, orange, grey, ming, mid_autumn, naruto, happy_new_year;
|
||||
@themes: green, yellow, blue, red, pink, purple, orange, grey, ming, blue2, mid_autumn, naruto, happy_new_year;
|
||||
|
||||
|
||||
// Colors
|
||||
|
@ -21,7 +21,8 @@
|
|||
@color-theme_2-active: fadeout(lighten(@color-theme, 10%), 70%);
|
||||
@color-theme_2-font: darken(@color-theme_2, 70%);
|
||||
@color-theme_2-font-label: fadeout(@color-theme_2-font, 40%);
|
||||
@color-theme_2-line: lighten(@color-theme, 35%);
|
||||
@color-theme_2-line: transparent;
|
||||
// @color-theme_2-line: lighten(@color-theme, 35%);
|
||||
@color-theme-sidebar: @color-theme;
|
||||
@color-btn: lighten(@color-theme, 5%);
|
||||
@color-btn-background: fadeout(lighten(@color-theme, 35%), 70%);
|
||||
|
@ -88,7 +89,8 @@
|
|||
@color-green-theme_2-active: fadeout(lighten(@color-green-theme, 10%), 70%);
|
||||
@color-green-theme_2-font: darken(@color-green-theme_2, 70%);
|
||||
@color-green-theme_2-font-label: fadeout(@color-green-theme_2-font, 40%);
|
||||
@color-green-theme_2-line: lighten(@color-green-theme, 45%);
|
||||
@color-green-theme_2-line: transparent;
|
||||
// @color-green-theme_2-line: lighten(@color-green-theme, 45%);
|
||||
@color-green-theme-sidebar: @color-green-theme;
|
||||
@color-green-btn: lighten(@color-green-theme, 5%);
|
||||
@color-green-btn-background: fadeout(lighten(@color-green-theme, 35%), 70%);
|
||||
|
@ -144,7 +146,8 @@
|
|||
@color-yellow-theme_2-active: fadeout(lighten(@color-yellow-theme, 10%), 60%);
|
||||
@color-yellow-theme_2-font: darken(@color-yellow-theme_2, 70%);
|
||||
@color-yellow-theme_2-font-label: fadeout(@color-yellow-theme_2-font, 40%);
|
||||
@color-yellow-theme_2-line: lighten(@color-yellow-theme, 28%);
|
||||
@color-yellow-theme_2-line: transparent;
|
||||
// @color-yellow-theme_2-line: lighten(@color-yellow-theme, 28%);
|
||||
@color-yellow-theme-sidebar: @color-yellow-theme;
|
||||
@color-yellow-btn: darken(@color-yellow-theme, 5%);
|
||||
@color-yellow-btn-background: fadeout(lighten(@color-yellow-theme, 25%), 60%);
|
||||
|
@ -199,7 +202,8 @@
|
|||
@color-orange-theme_2-active: fadeout(darken(@color-orange-theme, 5%), 70%);
|
||||
@color-orange-theme_2-font: darken(@color-orange-theme_2, 70%);
|
||||
@color-orange-theme_2-font-label: fadeout(@color-orange-theme_2-font, 40%);
|
||||
@color-orange-theme_2-line: lighten(@color-orange-theme, 36%);
|
||||
@color-orange-theme_2-line: transparent;
|
||||
// @color-orange-theme_2-line: lighten(@color-orange-theme, 36%);
|
||||
@color-orange-theme-sidebar: @color-orange-theme;
|
||||
@color-orange-btn: lighten(@color-orange-theme, 5%);
|
||||
@color-orange-btn-background: fadeout(lighten(@color-orange-theme, 25%), 60%);
|
||||
|
@ -254,7 +258,8 @@
|
|||
@color-blue-theme_2-active: fadeout(lighten(@color-blue-theme, 10%), 70%);
|
||||
@color-blue-theme_2-font: darken(@color-blue-theme_2, 70%);
|
||||
@color-blue-theme_2-font-label: fadeout(@color-blue-theme_2-font, 40%);
|
||||
@color-blue-theme_2-line: lighten(@color-blue-theme, 42%);
|
||||
@color-blue-theme_2-line: transparent;
|
||||
// @color-blue-theme_2-line: lighten(@color-blue-theme, 42%);
|
||||
@color-blue-theme-sidebar: @color-blue-theme;
|
||||
@color-blue-btn: lighten(@color-blue-theme, 5%);
|
||||
@color-blue-btn-background: fadeout(lighten(@color-blue-theme, 35%), 50%);
|
||||
|
@ -309,7 +314,8 @@
|
|||
@color-red-theme_2-background_2: fadeout(@color-red-theme_2-background_1, 2%);
|
||||
@color-red-theme_2-font: darken(@color-red-theme_2, 70%);
|
||||
@color-red-theme_2-font-label: fadeout(@color-red-theme_2-font, 40%);
|
||||
@color-red-theme_2-line: lighten(@color-red-theme, 42%);
|
||||
@color-red-theme_2-line: transparent;
|
||||
// @color-red-theme_2-line: lighten(@color-red-theme, 42%);
|
||||
@color-red-theme-sidebar: @color-red-theme;
|
||||
@color-red-btn: lighten(@color-red-theme, 5%);
|
||||
@color-red-btn-background: fadeout(lighten(@color-red-theme, 35%), 70%);
|
||||
|
@ -366,7 +372,8 @@
|
|||
@color-pink-theme_2-active: fadeout(lighten(@color-pink-theme, 10%), 60%);
|
||||
@color-pink-theme_2-font: darken(@color-pink-theme_2, 70%);
|
||||
@color-pink-theme_2-font-label: fadeout(@color-pink-theme_2-font, 40%);
|
||||
@color-pink-theme_2-line: lighten(@color-pink-theme, 25%);
|
||||
@color-pink-theme_2-line: transparent;
|
||||
// @color-pink-theme_2-line: lighten(@color-pink-theme, 25%);
|
||||
@color-pink-theme-sidebar: @color-pink-theme;
|
||||
@color-pink-btn: darken(@color-pink-theme, 3%);
|
||||
@color-pink-btn-background: fadeout(lighten(@color-pink-theme, 20%), 50%);
|
||||
|
@ -421,7 +428,8 @@
|
|||
@color-purple-theme_2-active: fadeout(lighten(@color-purple-theme, 10%), 70%);
|
||||
@color-purple-theme_2-font: darken(@color-purple-theme_2, 70%);
|
||||
@color-purple-theme_2-font-label: fadeout(@color-purple-theme_2-font, 40%);
|
||||
@color-purple-theme_2-line: lighten(@color-purple-theme, 43%);
|
||||
@color-purple-theme_2-line: transparent;
|
||||
// @color-purple-theme_2-line: lighten(@color-purple-theme, 43%);
|
||||
@color-purple-theme-sidebar: @color-purple-theme;
|
||||
@color-purple-btn: lighten(@color-purple-theme, 5%);
|
||||
@color-purple-btn-background: fadeout(lighten(@color-purple-theme, 35%), 70%);
|
||||
|
@ -476,7 +484,8 @@
|
|||
@color-grey-theme_2-active: fadeout(lighten(@color-grey-theme, 10%), 70%);
|
||||
@color-grey-theme_2-font: darken(@color-grey-theme_2, 70%);
|
||||
@color-grey-theme_2-font-label: fadeout(@color-grey-theme_2-font, 40%);
|
||||
@color-grey-theme_2-line: lighten(@color-grey-theme, 47%);
|
||||
@color-grey-theme_2-line: transparent;
|
||||
// @color-grey-theme_2-line: lighten(@color-grey-theme, 47%);
|
||||
@color-grey-theme-sidebar: @color-grey-theme;
|
||||
@color-grey-btn: lighten(@color-grey-theme, 5%);
|
||||
@color-grey-btn-background: fadeout(lighten(@color-grey-theme, 35%), 70%);
|
||||
|
@ -532,7 +541,8 @@
|
|||
@color-ming-theme_2-background_2: fadeout(@color-ming-theme_2-background_1, 2%);
|
||||
@color-ming-theme_2-font: darken(@color-ming-theme_2, 70%);
|
||||
@color-ming-theme_2-font-label: fadeout(@color-ming-theme_2-font, 40%);
|
||||
@color-ming-theme_2-line: lighten(@color-ming-theme, 60%);
|
||||
@color-ming-theme_2-line: transparent;
|
||||
// @color-ming-theme_2-line: lighten(@color-ming-theme, 60%);
|
||||
@color-ming-theme-sidebar: @color-ming-theme;
|
||||
@color-ming-btn: lighten(@color-ming-theme, 5%);
|
||||
@color-ming-btn-background: fadeout(lighten(@color-ming-theme, 35%), 75%);
|
||||
|
@ -574,22 +584,81 @@
|
|||
@color-ming-badge-info: #6376a2;
|
||||
@color-ming-badge-info-font: #fff;
|
||||
|
||||
|
||||
@color-blue2-theme: #4f62d0;
|
||||
@color-blue2-theme-bgimg: none;
|
||||
@color-blue2-theme-bgposition: center;
|
||||
@color-blue2-theme-bgsize: auto auto;
|
||||
@color-blue2-theme-hover: fadeout(lighten(@color-blue2-theme, 10%), 30%);
|
||||
@color-blue2-theme-active: fadeout(darken(@color-blue2-theme, 20%), 60%);
|
||||
@color-blue2-theme-font: #fff;
|
||||
@color-blue2-theme-font-label: lighten(@color-blue2-theme, 35%);
|
||||
@color-blue2-theme_2: #fff;
|
||||
@color-blue2-theme_2-background_1: #fff;
|
||||
@color-blue2-theme_2-background_2: fadeout(@color-blue2-theme_2-background_1, 2%);
|
||||
@color-blue2-theme_2-hover: fadeout(lighten(@color-blue2-theme, 10%), 80%);
|
||||
@color-blue2-theme_2-active: fadeout(lighten(@color-blue2-theme, 10%), 70%);
|
||||
@color-blue2-theme_2-font: darken(@color-blue2-theme_2, 70%);
|
||||
@color-blue2-theme_2-font-label: fadeout(@color-blue2-theme_2-font, 40%);
|
||||
@color-blue2-theme_2-line: transparent;
|
||||
// @color-blue2-theme_2-line: lighten(@color-blue2-theme, 47%);
|
||||
@color-blue2-theme-sidebar: @color-blue2-theme;
|
||||
@color-blue2-btn: lighten(@color-blue2-theme, 5%);
|
||||
@color-blue2-btn-background: fadeout(lighten(@color-blue2-theme, 30%), 70%);
|
||||
@color-blue2-btn-hover: fadeout(lighten(@color-blue2-theme, 5%), 70%);
|
||||
@color-blue2-btn-active: fadeout(darken(@color-blue2-theme, 5%), 70%);
|
||||
@color-blue2-btn-select: fadeout(lighten(@color-blue2-theme, 5%), 50%);
|
||||
@color-blue2-pagination-background: fadeout(lighten(@color-blue2-theme, 35%), 30%);
|
||||
@color-blue2-pagination-hover: fadeout(lighten(@color-blue2-theme, 10%), 70%);
|
||||
@color-blue2-pagination-active: fadeout(darken(@color-blue2-theme, 10%), 70%);
|
||||
@color-blue2-pagination-select: fadeout(lighten(@color-blue2-theme, 10%), 50%);
|
||||
@color-blue2-search-form-background: fadeout(lighten(@color-blue2-theme, 35%), 10%);
|
||||
@color-blue2-search-list-hover: fadeout(darken(@color-blue2-theme, 10%), 70%);
|
||||
@color-blue2-scrollbar-track: fadeout(lighten(@color-blue2-theme, 10%), 75%);
|
||||
@color-blue2-scrollbar-thumb: fadeout(lighten(@color-blue2-theme, 10%), 50%);
|
||||
@color-blue2-scrollbar-thumb-hover: fadeout(lighten(@color-blue2-theme, 10%), 35%);
|
||||
@color-blue2-player-pic-c1: fadeout(@color-blue2-theme_2, 50%);
|
||||
@color-blue2-player-pic-c2: darken(@color-blue2-theme_2, 30%);
|
||||
@color-blue2-player-progress: darken(@color-blue2-theme_2, 6%);
|
||||
@color-blue2-player-progress-bar1: darken(@color-blue2-theme_2, 12%);
|
||||
@color-blue2-player-progress-bar2: lighten(@color-blue2-theme, 12%);
|
||||
@color-blue2-player-status-text: lighten(@color-blue2-theme_2-font, 10%);
|
||||
@color-blue2-player-detail-play-btn: lighten(@color-blue2-theme, 7%);
|
||||
@color-blue2-tab-btn-background: fadeout(lighten(@color-blue2-theme, 10%), 80%);
|
||||
@color-blue2-tab-btn-background-hover: @color-blue2-theme_2-hover;
|
||||
@color-blue2-tab-border-top: fadeout(lighten(@color-blue2-theme, 5%), 50%);
|
||||
@color-blue2-tab-border-bottom: lighten(@color-blue2-theme, 5%);
|
||||
@color-blue2-hideBtn: #3bc2b2;
|
||||
@color-blue2-minBtn: #85c43b;
|
||||
@color-blue2-maxBtn: #e7aa36;
|
||||
@color-blue2-closeBtn: #ea6e4d;
|
||||
@color-blue2-hideBtn-hover: fadeout(@color-hideBtn, 10%);
|
||||
@color-blue2-minBtn-hover: fadeout(@color-blue2-minBtn, 10%);
|
||||
@color-blue2-maxBtn-hover: fadeout(@color-blue2-maxBtn, 10%);
|
||||
@color-blue2-closeBtn-hover: fadeout(@color-blue2-closeBtn, 10%);
|
||||
@color-blue2-badge-success: lighten(@color-blue2-theme, 15%);
|
||||
@color-blue2-badge-success-font: #fff;
|
||||
@color-blue2-badge-info: #6376a2;
|
||||
@color-blue2-badge-info-font: #fff;
|
||||
|
||||
|
||||
@color-mid_autumn-theme: rgba(74, 55, 82, 1);
|
||||
@color-mid_autumn-theme-bgimg: url(../images/jqbg.jpg);
|
||||
@color-mid_autumn-theme-bgposition: center;
|
||||
@color-mid_autumn-theme-bgsize: auto 100%;
|
||||
@color-mid_autumn-theme-bgsize: cover;
|
||||
@color-mid_autumn-theme-hover: fadeout(lighten(@color-mid_autumn-theme, 10%), 40%);
|
||||
@color-mid_autumn-theme-active: fadeout(lighten(@color-mid_autumn-theme, 15%), 60%);
|
||||
@color-mid_autumn-theme-font: rgba(246, 233, 255, 0.9);
|
||||
@color-mid_autumn-theme-font-label: fadeout(lighten(@color-mid_autumn-theme, 20%), 20%);
|
||||
@color-mid_autumn-theme_2: rgba(255, 255, 255, .93);
|
||||
@color-mid_autumn-theme_2: rgba(255, 255, 255, .9);
|
||||
@color-mid_autumn-theme_2-background_1: #eeedef;
|
||||
@color-mid_autumn-theme_2-background_2: fadeout(@color-mid_autumn-theme_2-background_1, 2%);
|
||||
@color-mid_autumn-theme_2-hover: fadeout(lighten(@color-mid_autumn-theme, 15%), 80%);
|
||||
@color-mid_autumn-theme_2-active: fadeout(lighten(@color-mid_autumn-theme, 15%), 70%);
|
||||
@color-mid_autumn-theme_2-font: darken(@color-mid_autumn-theme_2, 70%);
|
||||
@color-mid_autumn-theme_2-font-label: desaturate(lighten(@color-mid_autumn-theme, 30%), 45%);
|
||||
@color-mid_autumn-theme_2-line: lighten(@color-mid_autumn-theme, 63%);
|
||||
@color-mid_autumn-theme_2-line: transparent;
|
||||
// @color-mid_autumn-theme_2-line: lighten(@color-mid_autumn-theme, 63%);
|
||||
@color-mid_autumn-theme-sidebar: rgba(255, 255, 255, 0);
|
||||
@color-mid_autumn-btn: lighten(@color-mid_autumn-theme, 10%);
|
||||
@color-mid_autumn-btn-background: fadeout(lighten(@color-mid_autumn-theme, 35%), 70%);
|
||||
|
@ -630,9 +699,9 @@
|
|||
@color-mid_autumn-badge-info-font: #fff;
|
||||
|
||||
@color-naruto-theme: rgb(87, 144, 167);
|
||||
@color-naruto-theme-bgimg: url(../images/myzcbg.jpeg);
|
||||
@color-naruto-theme-bgimg: url(../images/myzcbg.jpg);
|
||||
@color-naruto-theme-bgposition: center;
|
||||
@color-naruto-theme-bgsize: auto 100%;
|
||||
@color-naruto-theme-bgsize: cover;
|
||||
@color-naruto-theme-hover: fadeout(lighten(@color-naruto-theme, 10%), 45%);
|
||||
@color-naruto-theme-active: fadeout(lighten(@color-naruto-theme, 15%), 60%);
|
||||
@color-naruto-theme-font: rgba(67, 118, 148, 0.9);
|
||||
|
@ -644,7 +713,8 @@
|
|||
@color-naruto-theme_2-active: fadeout(lighten(@color-naruto-theme, 10%), 65%);
|
||||
@color-naruto-theme_2-font: darken(@color-naruto-theme_2, 80%);
|
||||
@color-naruto-theme_2-font-label: desaturate(lighten(@color-naruto-theme, 10%), 45%);
|
||||
@color-naruto-theme_2-line: fadeout(lighten(@color-naruto-theme, 36%), 70%);
|
||||
@color-naruto-theme_2-line: transparent;
|
||||
// @color-naruto-theme_2-line: fadeout(lighten(@color-naruto-theme, 36%), 70%);
|
||||
@color-naruto-theme-sidebar: rgba(255, 255, 255, .3);
|
||||
@color-naruto-btn: lighten(@color-naruto-theme, 2%);
|
||||
@color-naruto-btn-background: fadeout(lighten(@color-naruto-theme, 35%), 70%);
|
||||
|
@ -687,7 +757,7 @@
|
|||
@color-happy_new_year-theme: rgb(252, 57, 57);
|
||||
@color-happy_new_year-theme-bgimg: url(../images/xnkl.jpg);
|
||||
@color-happy_new_year-theme-bgposition: center;
|
||||
@color-happy_new_year-theme-bgsize: auto 100%;
|
||||
@color-happy_new_year-theme-bgsize: cover;
|
||||
@color-happy_new_year-theme-hover: fadeout(lighten(@color-happy_new_year-theme, 10%), 45%);
|
||||
@color-happy_new_year-theme-active: fadeout(lighten(@color-happy_new_year-theme, 15%), 60%);
|
||||
@color-happy_new_year-theme-font: rgba(255, 255, 255, 0.9);
|
||||
|
@ -699,7 +769,8 @@
|
|||
@color-happy_new_year-theme_2-active: fadeout(lighten(@color-happy_new_year-theme, 10%), 55%);
|
||||
@color-happy_new_year-theme_2-font: darken(@color-happy_new_year-theme_2, 90%);
|
||||
@color-happy_new_year-theme_2-font-label: desaturate(darken(@color-happy_new_year-theme, 5%), 50%);
|
||||
@color-happy_new_year-theme_2-line: fadeout(lighten(@color-happy_new_year-theme, 16%), 70%);
|
||||
@color-happy_new_year-theme_2-line: transparent;
|
||||
// @color-happy_new_year-theme_2-line: fadeout(lighten(@color-happy_new_year-theme, 16%), 70%);
|
||||
@color-happy_new_year-theme-sidebar: rgba(119, 37, 18, 0.1);
|
||||
@color-happy_new_year-btn: desaturate(@color-happy_new_year-theme, 10%);
|
||||
@color-happy_new_year-btn-background: fadeout(lighten(@color-happy_new_year-theme, 15%), 60%);
|
||||
|
|
|
@ -55,18 +55,19 @@ div(:class="$style.player")
|
|||
|
||||
<script>
|
||||
import Lyric from 'lrc-file-parser'
|
||||
import { rendererSend } from '../../../common/ipc'
|
||||
import { rendererSend, rendererOn, NAMES } from '../../../common/ipc'
|
||||
import { formatPlayTime2, getRandom, checkPath, setTitle, clipboardWriteText, debounce, assertApiSupport } from '../../utils'
|
||||
import { mapGetters, mapActions, mapMutations } from 'vuex'
|
||||
import { requestMsg } from '../../utils/message'
|
||||
import { isMac } from '../../../common/utils'
|
||||
import path from 'path'
|
||||
|
||||
let audio
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
show: true,
|
||||
audio: null,
|
||||
volume: 0,
|
||||
nowPlayTime: 0,
|
||||
maxPlayTime: 0,
|
||||
|
@ -135,6 +136,32 @@ export default {
|
|||
this.setVolume(volume)
|
||||
}, 300)
|
||||
|
||||
rendererOn(NAMES.mainWindow.get_lyric_info, (event, info) => {
|
||||
switch (info.action) {
|
||||
case 'info':
|
||||
this.handleUpdateWinLyricInfo('info', {
|
||||
songmid: this.musicInfo.songmid,
|
||||
singer: this.musicInfo.singer,
|
||||
name: this.musicInfo.name,
|
||||
album: this.musicInfo.album,
|
||||
lyric: this.musicInfo.lrc,
|
||||
isPlay: this.isPlay,
|
||||
line: this.lyric.line,
|
||||
played_time: audio.currentTime * 1000,
|
||||
}, info)
|
||||
break
|
||||
case 'status':
|
||||
this.handleUpdateWinLyricInfo('status', {
|
||||
isPlay: this.isPlay,
|
||||
line: this.lyric.line,
|
||||
played_time: audio.currentTime * 1000,
|
||||
}, info)
|
||||
break
|
||||
|
||||
default:
|
||||
break
|
||||
}
|
||||
})
|
||||
navigator.mediaDevices.addEventListener('devicechange', this.handleMediaListChange)
|
||||
document.addEventListener('mousemove', this.handleVolumeMsMove)
|
||||
document.addEventListener('mouseup', this.handleVolumeMsUp)
|
||||
|
@ -157,7 +184,7 @@ export default {
|
|||
this.play()
|
||||
},
|
||||
'setting.player.togglePlayMethod'(n) {
|
||||
this.audio.loop = n === 'singleLoop'
|
||||
audio.loop = n === 'singleLoop'
|
||||
},
|
||||
'setting.player.mediaDeviceId'(n) {
|
||||
this.setMediaDevice()
|
||||
|
@ -204,40 +231,40 @@ export default {
|
|||
...mapMutations('list', ['updateMusicInfo']),
|
||||
...mapMutations(['setMediaDeviceId']),
|
||||
init() {
|
||||
this.audio = document.createElement('audio')
|
||||
audio = new window.Audio()
|
||||
this.setMediaDevice()
|
||||
this.volume = this.audio.volume = this.setting.player.volume
|
||||
this.audio.controls = false
|
||||
this.audio.autoplay = true
|
||||
this.audio.preload = 'auto'
|
||||
this.audio.loop = this.setting.player.togglePlayMethod === 'singleLoop'
|
||||
this.volume = audio.volume = this.setting.player.volume
|
||||
audio.controls = false
|
||||
audio.autoplay = true
|
||||
audio.preload = 'auto'
|
||||
audio.loop = this.setting.player.togglePlayMethod === 'singleLoop'
|
||||
|
||||
this.audio.addEventListener('playing', () => {
|
||||
audio.addEventListener('playing', () => {
|
||||
console.log('开始播放')
|
||||
this.statusText = this.$t('core.player.playing')
|
||||
this.status = ''
|
||||
this.startPlay()
|
||||
})
|
||||
this.audio.addEventListener('pause', () => {
|
||||
audio.addEventListener('pause', () => {
|
||||
console.log('暂停播放')
|
||||
window.lrc.pause()
|
||||
this.stopPlay()
|
||||
// this.status = this.statusText = this.$t('core.player.stop')
|
||||
})
|
||||
this.audio.addEventListener('ended', () => {
|
||||
audio.addEventListener('ended', () => {
|
||||
console.log('播放完毕')
|
||||
this.stopPlay()
|
||||
this.status = this.statusText = this.$t('core.player.end')
|
||||
this.handleNext()
|
||||
})
|
||||
this.audio.addEventListener('error', () => {
|
||||
// console.log('code', this.audio.error.code)
|
||||
audio.addEventListener('error', () => {
|
||||
// console.log('code', audio.error.code)
|
||||
if (!this.musicInfo.songmid) return
|
||||
console.log('出错')
|
||||
this.stopPlay()
|
||||
if (this.listId != 'download' && this.audio.error.code !== 1 && this.retryNum < 2) { // 若音频URL无效则尝试刷新2次URL
|
||||
if (this.listId != 'download' && audio.error.code !== 1 && this.retryNum < 2) { // 若音频URL无效则尝试刷新2次URL
|
||||
// console.log(this.retryNum)
|
||||
if (!this.audioErrorTime) this.audioErrorTime = this.audio.currentTime // 记录出错的播放时间
|
||||
if (!this.audioErrorTime) this.audioErrorTime = audio.currentTime // 记录出错的播放时间
|
||||
this.retryNum++
|
||||
this.setUrl(this.list[this.playIndex], true)
|
||||
this.status = this.statusText = this.$t('core.player.refresh_url')
|
||||
|
@ -248,37 +275,37 @@ export default {
|
|||
this.status = this.statusText = this.$t('core.player.error')
|
||||
this.addDelayNextTimeout()
|
||||
})
|
||||
this.audio.addEventListener('loadeddata', () => {
|
||||
this.maxPlayTime = this.audio.duration
|
||||
audio.addEventListener('loadeddata', () => {
|
||||
this.maxPlayTime = audio.duration
|
||||
if (this.audioErrorTime) {
|
||||
this.audio.currentTime = this.audioErrorTime
|
||||
audio.currentTime = this.audioErrorTime
|
||||
this.audioErrorTime = 0
|
||||
}
|
||||
if (!this.targetSong.interval && this.listId != 'download') this.updateMusicInfo({ id: this.listId, index: this.playIndex, data: { interval: formatPlayTime2(this.maxPlayTime) } })
|
||||
this.status = this.statusText = this.$t('core.player.loading')
|
||||
})
|
||||
this.audio.addEventListener('loadstart', () => {
|
||||
audio.addEventListener('loadstart', () => {
|
||||
this.status = this.statusText = this.$t('core.player.loading')
|
||||
})
|
||||
this.audio.addEventListener('canplay', () => {
|
||||
audio.addEventListener('canplay', () => {
|
||||
console.log('加载完成开始播放')
|
||||
if (this.mediaBuffer.playTime) {
|
||||
let playTime = this.mediaBuffer.playTime
|
||||
this.mediaBuffer.playTime = 0
|
||||
this.audio.currentTime = playTime
|
||||
audio.currentTime = playTime
|
||||
}
|
||||
if (this.mediaBuffer.timeout) {
|
||||
this.clearBufferTimeout()
|
||||
}
|
||||
// if (this.musicInfo.lrc) window.lrc.play(this.audio.currentTime * 1000)
|
||||
// if (this.musicInfo.lrc) window.lrc.play(audio.currentTime * 1000)
|
||||
this.status = this.statusText = this.$t('core.player.loading')
|
||||
})
|
||||
// this.audio.addEventListener('canplaythrough', () => {
|
||||
// audio.addEventListener('canplaythrough', () => {
|
||||
// console.log('音乐加载完毕')
|
||||
// // if (this.musicInfo.lyric.orgLrc) this.musicInfo.lyric.lrc.play(this.audio.currentTime * 1000)
|
||||
// // if (this.musicInfo.lyric.orgLrc) this.musicInfo.lyric.lrc.play(audio.currentTime * 1000)
|
||||
// this.status = this.statusText = '播放中...'
|
||||
// })
|
||||
this.audio.addEventListener('emptied', () => {
|
||||
audio.addEventListener('emptied', () => {
|
||||
this.mediaBuffer.playTime = 0
|
||||
this.clearBufferTimeout()
|
||||
|
||||
|
@ -286,11 +313,11 @@ export default {
|
|||
// this.status = this.statusText = '媒介资源元素突然为空,网络错误?'
|
||||
})
|
||||
|
||||
this.audio.addEventListener('timeupdate', () => {
|
||||
this.nowPlayTime = this.audio.currentTime
|
||||
audio.addEventListener('timeupdate', () => {
|
||||
this.nowPlayTime = audio.currentTime
|
||||
})
|
||||
|
||||
this.audio.addEventListener('waiting', () => {
|
||||
audio.addEventListener('waiting', () => {
|
||||
// this.musicInfo.lyric.lrc.pause()
|
||||
// console.log('缓冲中...')
|
||||
this.stopPlay()
|
||||
|
@ -330,11 +357,12 @@ export default {
|
|||
this.musicInfo.singer = targetSong.musicInfo.singer
|
||||
this.musicInfo.name = targetSong.musicInfo.name
|
||||
this.musicInfo.album = targetSong.albumName
|
||||
this.audio.src = filePath
|
||||
audio.src = filePath
|
||||
// console.log(filePath)
|
||||
this.setImg(targetSong.musicInfo)
|
||||
this.setLrc(targetSong.musicInfo)
|
||||
} else {
|
||||
if (!this.assertApiSupport(targetSong.source)) return this.handleNext()
|
||||
this.musicInfo.songmid = targetSong.songmid
|
||||
this.musicInfo.singer = targetSong.singer
|
||||
this.musicInfo.name = targetSong.name
|
||||
|
@ -343,6 +371,12 @@ export default {
|
|||
this.setImg(targetSong)
|
||||
this.setLrc(targetSong)
|
||||
}
|
||||
this.handleUpdateWinLyricInfo('music_info', {
|
||||
songmid: this.musicInfo.songmid,
|
||||
singer: this.musicInfo.singer,
|
||||
name: this.musicInfo.name,
|
||||
album: this.musicInfo.album,
|
||||
})
|
||||
},
|
||||
checkDelayNextTimeout() {
|
||||
// console.log(this.delayNextTimeout)
|
||||
|
@ -423,13 +457,15 @@ export default {
|
|||
},
|
||||
startPlay() {
|
||||
this.isPlay = true
|
||||
if (this.musicInfo.lrc) window.lrc.play(this.audio.currentTime * 1000)
|
||||
if (this.musicInfo.lrc) window.lrc.play(audio.currentTime * 1000)
|
||||
this.handleUpdateWinLyricInfo('play', audio.currentTime * 1000)
|
||||
this.setAppTitle()
|
||||
this.sendProgressEvent(this.progress, 'normal')
|
||||
},
|
||||
stopPlay() {
|
||||
this.isPlay = false
|
||||
window.lrc.pause()
|
||||
this.handleUpdateWinLyricInfo('pause')
|
||||
this.sendProgressEvent(this.progress, 'paused')
|
||||
this.clearAppTitle()
|
||||
},
|
||||
|
@ -437,7 +473,7 @@ export default {
|
|||
this.setProgress(event.offsetX / this.pregessWidth)
|
||||
},
|
||||
setProgress(pregress) {
|
||||
if (!this.audio.src) return
|
||||
if (!audio.src) return
|
||||
const time = pregress * this.maxPlayTime
|
||||
if (this.audioErrorTime) this.audioErrorTime = time
|
||||
if (this.mediaBuffer.playTime) {
|
||||
|
@ -445,9 +481,9 @@ export default {
|
|||
this.mediaBuffer.playTime = time
|
||||
this.startBuffering()
|
||||
}
|
||||
this.audio.currentTime = time
|
||||
audio.currentTime = time
|
||||
|
||||
if (!this.isPlay) this.audio.play()
|
||||
if (!this.isPlay) audio.play()
|
||||
},
|
||||
setProgressWidth() {
|
||||
this.pregessWidth = parseInt(
|
||||
|
@ -455,12 +491,12 @@ export default {
|
|||
)
|
||||
},
|
||||
togglePlay() {
|
||||
if (!this.audio.src) return
|
||||
if (!audio.src) return
|
||||
if (this.isPlay) {
|
||||
this.audio.pause()
|
||||
audio.pause()
|
||||
this.clearBufferTimeout()
|
||||
} else {
|
||||
this.audio.play()
|
||||
audio.play()
|
||||
}
|
||||
},
|
||||
imgError(e) {
|
||||
|
@ -479,7 +515,7 @@ export default {
|
|||
this.status = this.statusText = this.$t('core.player.geting_url')
|
||||
|
||||
return this.getUrl({ musicInfo: targetSong, type, isRefresh }).then(() => {
|
||||
this.audio.src = this.musicInfo.url = targetSong.typeUrl[type]
|
||||
audio.src = this.musicInfo.url = targetSong.typeUrl[type]
|
||||
}).catch(err => {
|
||||
// console.log('err', err.message)
|
||||
if (err.message == requestMsg.cancelRequest) return
|
||||
|
@ -510,16 +546,21 @@ export default {
|
|||
lrcP
|
||||
.then(() => {
|
||||
window.lrc.setLyric(this.musicInfo.lrc)
|
||||
if (this.isPlay && (this.musicInfo.url || this.listId == 'download')) window.lrc.play(this.audio.currentTime * 1000)
|
||||
this.handleUpdateWinLyricInfo('lyric', this.musicInfo.lrc)
|
||||
if (this.isPlay && (this.musicInfo.url || this.listId == 'download')) {
|
||||
window.lrc.play(audio.currentTime * 1000)
|
||||
this.handleUpdateWinLyricInfo('play', audio.currentTime * 1000)
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.handleUpdateWinLyricInfo('lyric', this.musicInfo.lrc)
|
||||
this.status = this.statusText = this.$t('core.player.lyric_error')
|
||||
})
|
||||
},
|
||||
handleRemoveMusic() {
|
||||
this.stopPlay()
|
||||
this.audio.src = null
|
||||
this.audio.removeAttribute('src')
|
||||
audio.src = null
|
||||
audio.removeAttribute('src')
|
||||
this.statusText = '^-^'
|
||||
this.musicInfo.img = null
|
||||
this.status = this.musicInfo.name = this.musicInfo.singer = ''
|
||||
|
@ -531,10 +572,12 @@ export default {
|
|||
this.lyric.lines = []
|
||||
this.lyric.line = -1
|
||||
this.lyric.text = 0
|
||||
this.handleUpdateWinLyricInfo('lines', [])
|
||||
this.handleUpdateWinLyricInfo('line', 0)
|
||||
},
|
||||
sendProgressEvent(status, mode) {
|
||||
// console.log(status)
|
||||
this.setting.player.isShowTaskProgess && rendererSend('progress', {
|
||||
this.setting.player.isShowTaskProgess && rendererSend(NAMES.mainWindow.progress, {
|
||||
status: status < 0.01 ? 0.01 : status,
|
||||
mode: mode || 'normal',
|
||||
})
|
||||
|
@ -556,7 +599,7 @@ export default {
|
|||
this.volume = val
|
||||
this.volumeEvent.msDownVolume = val
|
||||
// console.log(val)
|
||||
if (this.audio) this.audio.volume = this.volume
|
||||
if (audio) audio.volume = this.volume
|
||||
},
|
||||
handleVolumeMsUp(e) {
|
||||
this.volumeEvent.isMsDown = false
|
||||
|
@ -565,7 +608,7 @@ export default {
|
|||
if (!this.volumeEvent.isMsDown) return
|
||||
let val = this.volumeEvent.msDownVolume + (e.clientX - this.volumeEvent.msDownX) / 70
|
||||
this.volume = val < 0 ? 0 : val > 1 ? 1 : val
|
||||
if (this.audio) this.audio.volume = this.volume
|
||||
if (audio) audio.volume = this.volume
|
||||
// console.log(val)
|
||||
},
|
||||
handleCopy(text) {
|
||||
|
@ -597,18 +640,18 @@ export default {
|
|||
if (this.mediaBuffer.timeout) return
|
||||
this.mediaBuffer.timeout = setTimeout(() => {
|
||||
this.mediaBuffer.timeout = null
|
||||
if (!this.mediaBuffer.playTime) this.mediaBuffer.playTime = this.audio.currentTime
|
||||
let skipTime = this.audio.currentTime + getRandom(3, 6)
|
||||
if (skipTime > this.maxPlayTime) skipTime = (this.maxPlayTime - this.audio.currentTime) / 2
|
||||
if (!this.mediaBuffer.playTime) this.mediaBuffer.playTime = audio.currentTime
|
||||
let skipTime = audio.currentTime + getRandom(3, 6)
|
||||
if (skipTime > this.maxPlayTime) skipTime = (this.maxPlayTime - audio.currentTime) / 2
|
||||
if (skipTime - this.mediaBuffer.playTime < 1 || this.maxPlayTime - skipTime < 1) {
|
||||
this.mediaBuffer.playTime = 0
|
||||
this.handleNext()
|
||||
return
|
||||
}
|
||||
this.startBuffering()
|
||||
this.audio.currentTime = skipTime
|
||||
audio.currentTime = skipTime
|
||||
console.log(this.mediaBuffer.playTime)
|
||||
console.log(this.audio.currentTime)
|
||||
console.log(audio.currentTime)
|
||||
}, 3000)
|
||||
},
|
||||
clearBufferTimeout() {
|
||||
|
@ -634,7 +677,7 @@ export default {
|
|||
|
||||
this.prevDeviceLabel = label
|
||||
// console.log(device)
|
||||
this.audio.setSinkId(mediaDeviceId).catch(err => {
|
||||
audio.setSinkId(mediaDeviceId).catch(err => {
|
||||
console.log(err)
|
||||
this.setMediaDeviceId('default')
|
||||
})
|
||||
|
@ -680,6 +723,13 @@ export default {
|
|||
assertApiSupport(source) {
|
||||
return assertApiSupport(source)
|
||||
},
|
||||
handleUpdateWinLyricInfo(type, data, info) {
|
||||
rendererSend(NAMES.mainWindow.set_lyric_info, {
|
||||
type,
|
||||
data,
|
||||
info,
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
|
||||
<script>
|
||||
import { mapGetters, mapMutations } from 'vuex'
|
||||
import { rendererSend } from 'common/ipc'
|
||||
import { rendererSend, NAMES } from 'common/ipc'
|
||||
import { scrollTo } from '../../utils'
|
||||
|
||||
let cancelScrollFn = null
|
||||
|
@ -119,14 +119,14 @@ export default {
|
|||
},
|
||||
},
|
||||
watch: {
|
||||
'musicInfo.img': {
|
||||
handler(n) {
|
||||
if (n) {
|
||||
this.bgStyle.backgroundImage = `url(${n})`
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
},
|
||||
// 'musicInfo.img': {
|
||||
// handler(n) {
|
||||
// if (n) {
|
||||
// this.bgStyle.backgroundImage = `url(${n})`
|
||||
// }
|
||||
// },
|
||||
// immediate: true,
|
||||
// },
|
||||
'lyric.lines': {
|
||||
handler(n, o) {
|
||||
this.isSetedLines = true
|
||||
|
@ -299,13 +299,13 @@ export default {
|
|||
this.lyricEvent.timeout = null
|
||||
},
|
||||
min() {
|
||||
rendererSend('min')
|
||||
rendererSend(NAMES.mainWindow.min)
|
||||
},
|
||||
max() {
|
||||
rendererSend('max')
|
||||
rendererSend(NAMES.mainWindow.max)
|
||||
},
|
||||
close() {
|
||||
rendererSend('close')
|
||||
rendererSend(NAMES.mainWindow.close)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { rendererSend } from 'common/ipc'
|
||||
import { rendererSend, NAMES } from 'common/ipc'
|
||||
import { mapGetters, mapMutations } from 'vuex'
|
||||
import music from '../../utils/music'
|
||||
import { debounce } from '../../utils'
|
||||
|
@ -113,13 +113,13 @@ export default {
|
|||
},
|
||||
|
||||
min() {
|
||||
rendererSend('min')
|
||||
rendererSend(NAMES.mainWindow.min)
|
||||
},
|
||||
max() {
|
||||
rendererSend('max')
|
||||
rendererSend(NAMES.mainWindow.max)
|
||||
},
|
||||
close() {
|
||||
rendererSend('close')
|
||||
rendererSend(NAMES.mainWindow.close)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ material-modal(:show="!setting.isAgreePact || globalObj.isShowPact" @close="hand
|
|||
|
||||
<script>
|
||||
import { mapGetters, mapMutations } from 'vuex'
|
||||
import { rendererSend } from '../../../common/ipc'
|
||||
import { rendererSend, NAMES } from '../../../common/ipc'
|
||||
import { openUrl } from '../../utils'
|
||||
export default {
|
||||
data() {
|
||||
|
@ -98,7 +98,7 @@ export default {
|
|||
this.setAgreePact()
|
||||
},
|
||||
handleClose(isExit) {
|
||||
if (isExit) return rendererSend('close', true)
|
||||
if (isExit) return rendererSend(NAMES.mainWindow.close, true)
|
||||
this.globalObj.isShowPact = false
|
||||
},
|
||||
openUrl(url) {
|
||||
|
|
|
@ -127,7 +127,7 @@ material-modal(:show="version.showModal" @close="handleClose" v-if="version.newV
|
|||
|
||||
<script>
|
||||
import { mapGetters, mapMutations } from 'vuex'
|
||||
import { rendererSend } from '../../../common/ipc'
|
||||
import { rendererSend, NAMES } from '../../../common/ipc'
|
||||
import { checkVersion, openUrl, clipboardWriteText, sizeFormate } from '../../utils'
|
||||
|
||||
export default {
|
||||
|
@ -165,7 +165,7 @@ export default {
|
|||
handleRestartClick(event) {
|
||||
this.handleClose()
|
||||
event.target.disabled = true
|
||||
rendererSend('quit-update')
|
||||
rendererSend(NAMES.mainWindow.quit_update)
|
||||
},
|
||||
handleCopy(text) {
|
||||
clipboardWriteText(text)
|
||||
|
|
|
@ -139,7 +139,7 @@ export default {
|
|||
margin-bottom: 15px;
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
padding: 0 10px;
|
||||
padding: 0 10px !important;
|
||||
width: 150px;
|
||||
.mixin-ellipsis-1;
|
||||
}
|
||||
|
|
|
@ -136,7 +136,7 @@ export default {
|
|||
margin-bottom: 15px;
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
padding: 0 10px;
|
||||
padding: 0 10px !important;
|
||||
width: 150px;
|
||||
.mixin-ellipsis-1;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import Vue from 'vue'
|
||||
import keyBind from '../utils/keyBind'
|
||||
import { rendererOn } from '../../common/ipc'
|
||||
import { rendererOn, NAMES } from '../../common/ipc'
|
||||
|
||||
const eventHub = window.eventHub = new Vue()
|
||||
|
||||
|
@ -12,7 +12,7 @@ eventHub.$on('bindKey', () => {
|
|||
})
|
||||
eventHub.$on('unbindKey', keyBind.unbindKey)
|
||||
|
||||
rendererOn('focus', () => {
|
||||
rendererOn(NAMES.mainWindow.focus, () => {
|
||||
keyBind.clearDownKeys()
|
||||
eventHub.$emit('focus')
|
||||
})
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"close": "关闭",
|
||||
"back": "返回",
|
||||
"lock": "锁定歌词",
|
||||
"unlock": "解锁歌词",
|
||||
"theme": "主题配色",
|
||||
"font_increase": "增加字体大小",
|
||||
"font_decrease": "减小字体大小",
|
||||
"opactiy_increase": "减小透明度",
|
||||
"opactiy_decrease": "增加透明度",
|
||||
"lrc_active_zoom_on": "缩放当前播放的歌词",
|
||||
"lrc_active_zoom_off": "取消缩放当前播放的歌词",
|
||||
"win_top_on": "置顶歌词界面",
|
||||
"win_top_off": "取消置顶歌词界面"
|
||||
}
|
|
@ -8,6 +8,7 @@
|
|||
"theme_purple": "重斤球紫",
|
||||
"theme_grey": "灰常美丽",
|
||||
"theme_ming": "青出于黑",
|
||||
"theme_blue2": "清热版蓝",
|
||||
"theme_mid_autumn": "月里嫦娥",
|
||||
"theme_naruto": "木叶之村",
|
||||
"theme_happy_new_year": "新年快乐",
|
||||
|
|
|
@ -41,6 +41,11 @@
|
|||
"play_mediaDevice_remove_stop_play": "音频输出设备被改变时是否暂停播放",
|
||||
"play_mediaDevice_remove_stop_play_title": "当前的声音输出设备被改变时是否暂停播放歌曲",
|
||||
|
||||
"desktop_lyric": "桌面歌词设置",
|
||||
"desktop_lyric_enable": "显示歌词",
|
||||
"desktop_lyric_lock": "锁定歌词",
|
||||
"desktop_lyric_always_on_top": "使歌词总是在其他窗口之上",
|
||||
|
||||
"search": "搜索设置",
|
||||
"search_hot_title": "是否显示热门搜索",
|
||||
"search_hot": "热门搜索",
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"close": "關閉",
|
||||
"back": "返回",
|
||||
"lock": "鎖定歌詞",
|
||||
"unlock": "解鎖歌詞",
|
||||
"theme": "主題配色",
|
||||
"font_increase": "增加字體大小",
|
||||
"font_decrease": "減小字體大小",
|
||||
"opactiy_increase": "減小透明度",
|
||||
"opactiy_decrease": "增加透明度",
|
||||
"lrc_active_zoom_on": "縮放當前播放的歌詞",
|
||||
"lrc_active_zoom_off": "取消縮放當前播放的歌詞",
|
||||
"win_top_on": "置頂歌詞界面",
|
||||
"win_top_off": "取消置頂歌詞界面"
|
||||
}
|
|
@ -8,6 +8,7 @@
|
|||
"theme_purple": "重斤球紫",
|
||||
"theme_grey": "灰常美麗",
|
||||
"theme_ming": "青出於黑",
|
||||
"theme_blue2": "清熱版藍",
|
||||
"theme_mid_autumn": "月裡嫦娥",
|
||||
"theme_naruto": "木葉之村",
|
||||
"theme_happy_new_year": "新年快樂",
|
||||
|
|
|
@ -39,6 +39,10 @@
|
|||
"play_mediaDevice": "音頻輸出",
|
||||
"play_mediaDevice_remove_stop_play": "音頻輸出設備被改變時是否暫停播放",
|
||||
"play_mediaDevice_remove_stop_play_title": "當前的聲音輸出設備被改變時是否暫停播放歌曲",
|
||||
"desktop_lyric": "桌面歌詞設置",
|
||||
"desktop_lyric_enable": "顯示歌詞",
|
||||
"desktop_lyric_lock": "鎖定歌詞",
|
||||
"desktop_lyric_always_on_top": "使歌詞總是在其他窗口之上",
|
||||
"search": "搜索設置",
|
||||
"search_hot_title": "是否顯示熱門搜索",
|
||||
"search_hot": "熱門搜索",
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"close": "Close",
|
||||
"back": "Back",
|
||||
"lock": "Lock Lyrics",
|
||||
"unlock": "Unlock Lyrics",
|
||||
"theme": "Theme Color",
|
||||
"font_increase": "Increase font size",
|
||||
"font_decrease": "Reduce font size",
|
||||
"opactiy_increase": "Decrease Transparency",
|
||||
"opactiy_decrease": "Increase Transparency",
|
||||
"lrc_active_zoom_on": "Zoom the currently playing lyrics",
|
||||
"lrc_active_zoom_off": "Unzoom the currently playing lyrics",
|
||||
"win_top_on": "Top lyrics interface",
|
||||
"win_top_off": "Cancel the top lyrics interface"
|
||||
}
|
|
@ -8,6 +8,7 @@
|
|||
"theme_purple": "Purple",
|
||||
"theme_grey": "Grey",
|
||||
"theme_ming": "Ming",
|
||||
"theme_blue2": "Purple Blue",
|
||||
"theme_mid_autumn": "Mid-Autumn",
|
||||
"theme_naruto": "Naruto",
|
||||
"theme_happy_new_year": "New Year",
|
||||
|
|
|
@ -41,6 +41,11 @@
|
|||
"play_mediaDevice_remove_stop_play": "Whether to pause playback when the audio output device is changed",
|
||||
"play_mediaDevice_remove_stop_play_title": "Whether to pause the song when the current sound output device is changed",
|
||||
|
||||
"desktop_lyric": "Desktop Lyric Settings",
|
||||
"desktop_lyric_enable": "Display lyrics",
|
||||
"desktop_lyric_lock": "Lock lyrics",
|
||||
"desktop_lyric_always_on_top": "Make the lyrics always above other windows",
|
||||
|
||||
"search": "Search",
|
||||
"search_hot_title": "Select whether to show popular searches",
|
||||
"search_hot": "Top Searches",
|
||||
|
|
|
@ -51,4 +51,7 @@ export default {
|
|||
setPrevSelectListId(state, val) {
|
||||
state.setting.list.prevSelectListId = val
|
||||
},
|
||||
setDesktopLyricConfig(state, config) {
|
||||
state.setting.desktopLyric = Object.assign(state.setting.desktopLyric, config)
|
||||
},
|
||||
}
|
||||
|
|
|
@ -1,47 +1,18 @@
|
|||
|
||||
// const isDev = process.env.NODE_ENV === 'development'
|
||||
import Store from 'electron-store'
|
||||
import { updateSetting } from '../utils'
|
||||
import { windowSizeList } from '../../common/config'
|
||||
import { version } from '../../../package.json'
|
||||
const electronStore_list = window.electronStore_list = new Store({
|
||||
|
||||
window.electronStore_list = new Store({
|
||||
name: 'playList',
|
||||
})
|
||||
const electronStore_config = window.electronStore_config = new Store({
|
||||
name: 'config',
|
||||
})
|
||||
let setting = electronStore_config.get('setting')
|
||||
if (!electronStore_config.get('version') && setting) { // 迁移配置
|
||||
electronStore_config.set('version', electronStore_config.get('setting.version'))
|
||||
electronStore_config.delete('setting.version')
|
||||
const list = electronStore_config.get('list')
|
||||
if (list) {
|
||||
if (list.defaultList) electronStore_list.set('defaultList', list.defaultList)
|
||||
if (list.loveList) electronStore_list.set('loveList', list.loveList)
|
||||
electronStore_config.delete('list')
|
||||
}
|
||||
const downloadList = electronStore_config.get('download')
|
||||
if (downloadList) {
|
||||
if (downloadList.list) electronStore_list.set('downloadList', downloadList.list)
|
||||
electronStore_config.delete('download')
|
||||
}
|
||||
}
|
||||
let settingVersion = electronStore_config.get('version')
|
||||
|
||||
// 迁移列表滚动位置设置 ^0.18.3
|
||||
if (setting && setting.list.scroll) {
|
||||
let scroll = setting.list.scroll
|
||||
const electronStore_list = window.electronStore_list = new Store({
|
||||
name: 'playList',
|
||||
})
|
||||
electronStore_list.set('defaultList.location', scroll.locations.defaultList || 0)
|
||||
electronStore_list.set('loveList.location', scroll.locations.loveList || 0)
|
||||
electronStore_config.delete('setting.list.scroll')
|
||||
electronStore_config.set('setting.list.isSaveScrollLocation', scroll.enable)
|
||||
}
|
||||
|
||||
const { version: settingVersion, setting: newSetting } = updateSetting(setting, electronStore_config.get('version'))
|
||||
electronStore_config.set('version', settingVersion)
|
||||
electronStore_config.set('setting', setting)
|
||||
process.versions.app = version
|
||||
|
||||
window.i18n.locale = setting.langId
|
||||
|
@ -93,6 +64,11 @@ export default {
|
|||
name: '青出于黑',
|
||||
class: 'ming',
|
||||
},
|
||||
{
|
||||
id: 12,
|
||||
name: '青出于黑',
|
||||
class: 'blue2',
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
name: '月里嫦娥',
|
||||
|
@ -122,7 +98,7 @@ export default {
|
|||
downloadProgress: null,
|
||||
},
|
||||
userInfo: null,
|
||||
setting: newSetting,
|
||||
setting,
|
||||
settingVersion,
|
||||
|
||||
windowSizeList,
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
import fs from 'fs'
|
||||
import { shell, clipboard } from 'electron'
|
||||
import crypto from 'crypto'
|
||||
import { rendererSend, rendererInvoke } from '../../common/ipc'
|
||||
import { defaultSetting, overwriteSetting } from '../config/defaultSetting'
|
||||
import apiSource from '../config/api-source'
|
||||
import { rendererSend, rendererInvoke, NAMES } from '../../common/ipc'
|
||||
|
||||
/**
|
||||
* 获取两个数之间的随机整数,大于等于min,小于max
|
||||
|
@ -133,13 +131,13 @@ export const checkPath = (path) => new Promise(resolve => {
|
|||
* 选择路径
|
||||
* @param {*} 选项
|
||||
*/
|
||||
export const selectDir = options => rendererInvoke('selectDir', options)
|
||||
export const selectDir = options => rendererInvoke(NAMES.mainWindow.select_dir, options)
|
||||
|
||||
/**
|
||||
* 打开保存对话框
|
||||
* @param {*} 选项
|
||||
*/
|
||||
export const openSaveDir = options => rendererInvoke('showSaveDialog', options)
|
||||
export const openSaveDir = options => rendererInvoke(NAMES.mainWindow.show_save_dialog, options)
|
||||
|
||||
/**
|
||||
* 在资源管理器中打开目录
|
||||
|
@ -176,20 +174,21 @@ export const isObject = item => item && typeof item === 'object' && !Array.isArr
|
|||
|
||||
/**
|
||||
* 对象深度合并
|
||||
* 注意:循环引用的对象会出现死循环
|
||||
* @param {} target 要合并源对象
|
||||
* @param {} source 要合并目标对象
|
||||
*/
|
||||
export const objectDeepMerge = (target, source) => {
|
||||
export const objectDeepMerge = (target, source, mergedObj) => {
|
||||
if (!mergedObj) {
|
||||
mergedObj = new Set()
|
||||
mergedObj.add(target)
|
||||
}
|
||||
let base = {}
|
||||
Object.keys(source).forEach(item => {
|
||||
if (Array.isArray(source[item])) {
|
||||
let arr = Array.isArray(target[item]) ? target[item] : []
|
||||
target[item] = arr.concat(source[item])
|
||||
return
|
||||
} else if (isObject(source[item])) {
|
||||
if (isObject(source[item])) {
|
||||
if (mergedObj.has(source[item])) return
|
||||
if (!isObject(target[item])) target[item] = {}
|
||||
objectDeepMerge(target[item], source[item])
|
||||
mergedObj.add(source[item])
|
||||
objectDeepMerge(target[item], source[item], mergedObj)
|
||||
return
|
||||
}
|
||||
base[item] = source[item]
|
||||
|
@ -197,35 +196,6 @@ export const objectDeepMerge = (target, source) => {
|
|||
Object.assign(target, base)
|
||||
}
|
||||
|
||||
/**
|
||||
* 升级设置
|
||||
* @param {*} setting
|
||||
*/
|
||||
export const updateSetting = (setting, version) => {
|
||||
const defaultVersion = defaultSetting.version
|
||||
if (!version) {
|
||||
if (setting) {
|
||||
version = setting.version
|
||||
delete setting.version
|
||||
}
|
||||
}
|
||||
|
||||
if (!setting) {
|
||||
setting = defaultSetting
|
||||
} else if (checkVersion(version, defaultVersion)) {
|
||||
objectDeepMerge(defaultSetting, setting)
|
||||
objectDeepMerge(defaultSetting, overwriteSetting)
|
||||
setting = defaultSetting
|
||||
}
|
||||
|
||||
if (!apiSource.some(api => api.id === setting.apiSource && !api.disabled)) {
|
||||
let api = apiSource.find(api => !api.disabled)
|
||||
if (api) setting.apiSource = api.id
|
||||
}
|
||||
|
||||
return { setting, version: defaultVersion }
|
||||
}
|
||||
|
||||
/**
|
||||
* 在浏览器打开URL
|
||||
* @param {*} url
|
||||
|
@ -267,7 +237,7 @@ export const clipboardReadText = str => clipboard.readText()
|
|||
* @param {*} meta
|
||||
*/
|
||||
export const setMeta = (filePath, meta) => {
|
||||
rendererSend('setMusicMeta', { filePath, meta })
|
||||
rendererSend(NAMES.mainWindow.set_music_meta, { filePath, meta })
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -357,19 +327,19 @@ export const findParentNode = (target, tagName) => target.tagName == tagName ? t
|
|||
/**
|
||||
* 获取缓存大小
|
||||
*/
|
||||
export const getCacheSize = () => rendererInvoke('getCacheSize')
|
||||
export const getCacheSize = () => rendererInvoke(NAMES.mainWindow.get_cache_size)
|
||||
|
||||
/**
|
||||
* 清除缓存
|
||||
*/
|
||||
export const clearCache = () => rendererInvoke('clearCache')
|
||||
export const clearCache = () => rendererInvoke(NAMES.mainWindow.clear_cache)
|
||||
|
||||
/**
|
||||
* 设置窗口大小
|
||||
* @param {*} width
|
||||
* @param {*} height
|
||||
*/
|
||||
export const setWindowSize = (width, height) => rendererSend('setWindowSize', { width, height })
|
||||
export const setWindowSize = (width, height) => rendererSend(NAMES.mainWindow.set_window_size, { width, height })
|
||||
|
||||
|
||||
export const getProxyInfo = () => window.globalObj.proxy.enable
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Support qualitys: 128k 320k flac wav
|
||||
|
||||
export default [
|
||||
module.exports = [
|
||||
{
|
||||
id: 'test',
|
||||
name: '测试接口',
|
|
@ -1,9 +1,9 @@
|
|||
import apiSource from '../../config/api-source'
|
||||
import apiSourceInfo from './api-source-info'
|
||||
|
||||
const apiList = {}
|
||||
const supportQuality = {}
|
||||
|
||||
for (const api of apiSource) {
|
||||
for (const api of apiSourceInfo) {
|
||||
supportQuality[api.id] = api.supportQualitys
|
||||
for (const source of Object.keys(api.supportQualitys)) {
|
||||
apiList[`${api.id}_api_${source}`] = require(`./${source}/api-${api.id}`).default
|
||||
|
|
|
@ -7,7 +7,7 @@ export default {
|
|||
_requestObj_list: null,
|
||||
_requestObj_listRecommend: null,
|
||||
_requestObj_listDetail: null,
|
||||
limit_list: 20,
|
||||
limit_list: 30,
|
||||
limit_song: 10000,
|
||||
successCode: 22000,
|
||||
sortList: [
|
||||
|
|
|
@ -7,7 +7,7 @@ export default {
|
|||
_requestObj_hotTags: null,
|
||||
_requestObj_list: null,
|
||||
_requestObj_listDetail: null,
|
||||
limit_list: 25,
|
||||
limit_list: 36,
|
||||
limit_song: 10000,
|
||||
successCode: 200,
|
||||
sortList: [
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { httpGet } from '../../request'
|
||||
import { rendererInvoke } from '../../../../common/ipc'
|
||||
import { rendererInvoke, NAMES } from '../../../../common/ipc'
|
||||
|
||||
if (!window.kw_token) {
|
||||
window.kw_token = {
|
||||
|
@ -34,4 +34,4 @@ export const getToken = () => new Promise((resolve, reject) => {
|
|||
})
|
||||
})
|
||||
|
||||
export const decodeLyric = base64Data => rendererInvoke('kw_decodeLyric', base64Data)
|
||||
export const decodeLyric = base64Data => rendererInvoke(NAMES.mainWindow.handle_kw_decode_lyric, base64Data)
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue