Merge branch 'dev'
commit
5f2cbb30c2
|
@ -99,7 +99,9 @@ jobs:
|
|||
run: npm run build:src
|
||||
|
||||
- name: Build Package dmg
|
||||
run: npm run pack:mac:dmg
|
||||
run: |
|
||||
npm run publish:mac:dmg
|
||||
npm run publish:mac:dmg:arm64
|
||||
env:
|
||||
ELECTRON_CACHE: $HOME/.cache/electron
|
||||
ELECTRON_BUILDERCACHE: $HOME/.cache/electron-builder
|
||||
|
@ -107,8 +109,15 @@ jobs:
|
|||
- name: Upload Artifact dmg
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: lx-music-desktop-mac_dmg
|
||||
path: build/*.dmg
|
||||
name: lx-music-desktop-mac-dmg
|
||||
path: |
|
||||
build/*.dmg
|
||||
!build/*-arm64.dmg
|
||||
- name: Upload Artifact dmg
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: lx-music-desktop-mac-dmg-arm64
|
||||
path: build/*-arm64.dmg
|
||||
|
||||
Linux:
|
||||
name: Linux
|
||||
|
|
|
@ -77,7 +77,9 @@ jobs:
|
|||
run: npm run build:src
|
||||
|
||||
- name: Release package
|
||||
run: npm run publish:mac:dmg:always
|
||||
run: |
|
||||
npm run publish:mac:dmg:always
|
||||
npm run publish:mac:dmg:arm64
|
||||
env:
|
||||
ELECTRON_CACHE: $HOME/.cache/electron
|
||||
ELECTRON_BUILDERCACHE: $HOME/.cache/electron-builder
|
||||
|
|
24
CHANGELOG.md
24
CHANGELOG.md
|
@ -6,6 +6,30 @@ Project versioning adheres to [Semantic Versioning](http://semver.org/).
|
|||
Commit convention is based on [Conventional Commits](http://conventionalcommits.org).
|
||||
Change log format is based on [Keep a Changelog](http://keepachangelog.com/).
|
||||
|
||||
## [1.10.0](https://github.com/lyswhut/lx-music-desktop/compare/v1.9.0...v1.10.0) - 2021-05-19
|
||||
|
||||
lx music移动端已经发布了,使用习惯仍跟桌面版一样,不过功能、界面仍比较简单,有兴趣的可以去体检一下,项目地址:
|
||||
https://github.com/lyswhut/lx-music-mobile#readme
|
||||
|
||||
### 新增
|
||||
|
||||
- 排行榜界面添加播放、收藏整个排行榜功能,可以右击排行榜名字后,在弹出的右键菜单中使用。注:收藏、播放存在分页的排行榜时需等待操作完成后才能切换排行榜,不然会导致操作中断。
|
||||
- 新增Mac arm64位dmg包的构建
|
||||
|
||||
### 修复
|
||||
|
||||
- 修复全局快捷键对桌面歌词无效的问题
|
||||
- 修复快捷键设置框内的提示问题
|
||||
- 修复在当前正常播放的列表中使用稍后播放功能时,播放完后稍后播放的歌曲后不会恢复原来播放位置播放的问题
|
||||
- 修复kw部分歌单无法打开的问题
|
||||
- 修复wy源的歌曲音质匹配问题
|
||||
- 修复mg源歌单标签、排行榜歌曲列表无法加载的问题
|
||||
- 修复了一个歌曲下载失败时不会跳过任务的问题
|
||||
|
||||
### 其他
|
||||
|
||||
- 更新 Electron 到 12.0.8
|
||||
|
||||
## [1.9.0](https://github.com/lyswhut/lx-music-desktop/compare/v1.8.2...v1.9.0) - 2021-04-24
|
||||
|
||||
### 新增
|
||||
|
|
37
FAQ.md
37
FAQ.md
|
@ -8,7 +8,24 @@
|
|||
|
||||
## 歌曲无法试听与下载
|
||||
|
||||
该问题解决顺序如下:
|
||||
### 所有歌曲都提示 `请求异常😮,可以多试几次,若还是不行就换一首吧。。。`
|
||||
|
||||
尝试更换网络,如切换到移动网络,若移动网络还是不行则尝试开关下手机的飞行模式后再试,<br>
|
||||
若使用家庭网络的话,可尝试将光猫断电5分钟左右再通电联网后播放。
|
||||
|
||||
### 提示`getaddrinfo EAI_AGAIN ...`
|
||||
|
||||
尝试在在浏览器打开这个地址`http://ts.tempmusic.tk`,浏览器显示404是正常的,如果不是404那就证明所在网络无法访问接口服务器。
|
||||
若网页无法打开或打开来不是404,则可能是DNS的问题,可以尝试以下办法:
|
||||
|
||||
1. 将DNS改成自动获取试试(注:改完可能需要清理下系统DNS缓存才生效)
|
||||
2. 手动把DNS改一下,不要用360的DNS,可以把DNS改成`114.114.114.114`、`8.8.8.8`(注:改完可能需要清理下系统DNS缓存才生效)
|
||||
|
||||
改完DNS后可能需要重启软件才生效
|
||||
|
||||
### 通用解决方法
|
||||
|
||||
尝试按以下顺序解决:
|
||||
|
||||
1. 尝试更新到最新版本
|
||||
2. 尝试切换其他歌曲(或直接搜索该歌曲),若全部歌曲都无法试听与下载则进行下一步
|
||||
|
@ -55,6 +72,8 @@
|
|||
因此,当 win7 没有使用**AERO**主题时界面将会显示异常,开启AERO的方法请自行百度:`win7开启aero效果`(开启后可看到任务栏变透明)。<br>
|
||||
从`0.14.0`版本起不再强制要求开启透明效果,若你实在不想开启(若非电脑配置太低,墙裂建议开启!),可通过添加运行参数`-dt`来运行程序即可,例如:`.\lx-music-desktop.exe -dt`,添加方法可自行百度“给快捷方式加参数”,该参数的作用是用来控制程序是否使用非透明窗口运行。
|
||||
|
||||
注:启用**AERO**主题后,若软件出现黑边框,则重启软件即可恢复正常。
|
||||
|
||||
对于一些完全无法正常显示界面、开启了AERO后问题仍未解决的情况,请阅读下面的 **软件启动后,界面无法显示** 解决。
|
||||
|
||||
### Linux 下界面异常
|
||||
|
@ -97,7 +116,7 @@
|
|||
|
||||
### Windows 7 系统桌面歌词显示异常
|
||||
|
||||
Windows 7 未开启 Aero 效果时桌面歌词会有问题,详情看下面的 **Windows 7 下界面异常(界面显示不完整)** 方法解决。
|
||||
Windows 7 未开启 Aero 效果时桌面歌词会有问题,详情看上面的 **Windows 7 下界面异常** 方法解决。
|
||||
|
||||
### MAC OS 系统、桌面歌词有残留阴影
|
||||
|
||||
|
@ -113,25 +132,15 @@ Windows 7 未开启 Aero 效果时桌面歌词会有问题,详情看下面的
|
|||
|
||||
其他 Linux 系统未测试,如有异常也是意料之中,目前不打算去处理 Linux 平台的桌面歌词问题,但你可以尝试按照`Linux 下界面异常`的解决方案去解决。
|
||||
|
||||
## 歌曲下载失败
|
||||
|
||||
### 提示 `ENOENT: no such file or directory, mkdir`
|
||||
## 歌曲下载失败,提示 `ENOENT: no such file or directory, mkdir`
|
||||
|
||||
更换下载歌曲目录即可解决(一般是设置的歌曲下载目录没有读写权限导致的)。
|
||||
|
||||
### 提示 `请求异常` 或 `Fail`
|
||||
|
||||
尝试更换网络,如切换到移动网络。
|
||||
|
||||
## 使用软件时导致耳机意外关机
|
||||
|
||||
据反馈,漫步者部分型号的耳机与本软件一起使用时将会导致耳机意外关机,
|
||||
详情看:<https://github.com/lyswhut/lx-music-desktop/issues/457>,
|
||||
若出现该问题可尝试添加`-dhmkh`启动参数解决,启动参数添加方法请自行百度“windows给应用程序加启动参数的方法”。
|
||||
|
||||
### 其他错误
|
||||
|
||||
按照前面的 "歌曲无法试听与下载" 方案解决。
|
||||
若出现该问题可尝试添加`-dhmkh`启动参数解决,启动参数添加方法请自行百度“windows给快捷方式添加启动参数”。
|
||||
|
||||
## 软件安装包说明
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
|
||||
软件变化请查看:[更新日志](https://github.com/lyswhut/lx-music-desktop/blob/master/CHANGELOG.md)<br>
|
||||
软件下载请转到:[发布页面](https://github.com/lyswhut/lx-music-desktop/releases)<br>
|
||||
或者到网盘下载(网盘内有MAC、windows版):`https://www.lanzous.com/b0bf2cfa/` 密码:`glqw`(若链接无法打开请百度:蓝奏云链接打不开)<br>
|
||||
或者到网盘下载(网盘内有MAC、windows版):`https://www.lanzoui.com/b0bf2cfa/` 密码:`glqw`(若链接无法打开请百度:蓝奏云链接打不开)<br>
|
||||
使用常见问题请转至:[常见问题](https://github.com/lyswhut/lx-music-desktop/blob/master/FAQ.md)
|
||||
|
||||
### 源码使用方法
|
||||
|
@ -83,7 +83,7 @@ npm run pack:linux
|
|||
- `-search` 启动软件时自动在搜索框搜索指定的内容,例如:`-search="突然的自我 - 伍佰"`
|
||||
- `-dha` 禁用硬件加速启动(Disable Hardware Acceleration),窗口显示有问题时可以尝试添加此参数启动(v1.6.0起新增)
|
||||
- `-dt` 以非透明模式启动(Disable Transparent),对于未开启AERO效果的win7系统可加此参数启动以确保界面正常显示(注:该参数对桌面歌词无效),原来的`-nt`参数已重命名为`-dt`(v1.6.0起重命名)
|
||||
- `-dhmkh` 禁用硬件媒体密钥处理(Disable Hardware Media Key Handling),此选项将禁用Chromium的Hardware Media Key Handling特性(v1.8.1起新增)
|
||||
- `-dhmkh` 禁用硬件媒体密钥处理(Disable Hardware Media Key Handling),此选项将禁用Chromium的Hardware Media Key Handling特性(v1.9.0起新增)
|
||||
- `-play` 启动时播放指定列表的音乐,参数说明:
|
||||
- `type`:播放类型,目前固定为`songList`
|
||||
- `source`:播放源,可用值为`kw/kg/tx/wy/mg/myList`,其中`kw/kg/tx/wy/mg`对应各源的在线列表,`myList`为本地列表
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
const path = require('path')
|
||||
const webpack = require('webpack')
|
||||
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
|
||||
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')
|
||||
const TerserPlugin = require('terser-webpack-plugin')
|
||||
const CopyWebpackPlugin = require('copy-webpack-plugin')
|
||||
const { merge } = require('webpack-merge')
|
||||
|
@ -36,7 +36,7 @@ module.exports = merge(baseConfig, {
|
|||
optimization: {
|
||||
minimizer: [
|
||||
new TerserPlugin(),
|
||||
new OptimizeCSSAssetsPlugin({}),
|
||||
new CssMinimizerPlugin(),
|
||||
],
|
||||
},
|
||||
performance: {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
const path = require('path')
|
||||
const webpack = require('webpack')
|
||||
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
|
||||
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')
|
||||
const TerserPlugin = require('terser-webpack-plugin')
|
||||
const CopyWebpackPlugin = require('copy-webpack-plugin')
|
||||
const { merge } = require('webpack-merge')
|
||||
|
@ -36,7 +36,7 @@ module.exports = merge(baseConfig, {
|
|||
optimization: {
|
||||
minimizer: [
|
||||
new TerserPlugin(),
|
||||
new OptimizeCSSAssetsPlugin({}),
|
||||
new CssMinimizerPlugin(),
|
||||
],
|
||||
},
|
||||
performance: {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
57
package.json
57
package.json
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "lx-music-desktop",
|
||||
"version": "1.9.0",
|
||||
"version": "1.10.0",
|
||||
"description": "一个免费的音乐查找助手",
|
||||
"main": "./dist/electron/main.js",
|
||||
"productName": "lx-music-desktop",
|
||||
|
@ -27,8 +27,9 @@
|
|||
"pack:linux:deb:armv7l": "cross-env ARCH=armv7l electron-builder -l=deb --armv7l -p never",
|
||||
"pack:linux:rpm": "cross-env ARCH=x64 electron-builder -l=rpm --x64 -p never",
|
||||
"pack:linux:pacman": "cross-env ARCH=x64 electron-builder -l=pacman --x64 -p never",
|
||||
"pack:mac": "node build-config/pack.js && npm run pack:mac:dmg",
|
||||
"pack:mac": "node build-config/pack.js && npm run pack:mac:dmg && npm run pack:mac:dmg:arm64",
|
||||
"pack:mac:dmg": "cross-env electron-builder -m=dmg -p never",
|
||||
"pack:mac:dmg:arm64": "cross-env electron-builder -m=dmg --arm64 -p never",
|
||||
"pack:dir": "node build-config/pack.js && electron-builder --dir",
|
||||
"publish": "node publish",
|
||||
"publish:win:setup:always": "cross-env TARGET=Setup ARCH=x86_64 electron-builder -w=nsis --x64 --ia32 -p always",
|
||||
|
@ -42,6 +43,7 @@
|
|||
"publish:win:7z:arm64": "cross-env TARGET=green ARCH=win_arm64 electron-builder -w=7z --arm64 -p onTagOrDraft",
|
||||
"publish:mac:dmg:always": "electron-builder -m=dmg -p always",
|
||||
"publish:mac:dmg": "electron-builder -m=dmg -p onTagOrDraft",
|
||||
"publish:mac:dmg:arm64": "electron-builder -m=dmg --arm64 -p onTagOrDraft",
|
||||
"publish:linux:deb:x64:always": "cross-env ARCH=x64 electron-builder -l=deb --x64 -p always",
|
||||
"publish:linux:deb:x64": "cross-env ARCH=x64 electron-builder -l=deb --x64 -p onTagOrDraft",
|
||||
"publish:linux:deb:x86": "cross-env ARCH=x86 electron-builder -l=deb --ia32 -p onTagOrDraft",
|
||||
|
@ -60,6 +62,7 @@
|
|||
"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",
|
||||
"dp": "cross-env ELECTRON_GET_USE_PROXY=true GLOBAL_AGENT_HTTPS_PROXY=http://localhost:1081 npm run pack",
|
||||
"up": "cross-env ELECTRON_GET_USE_PROXY=true GLOBAL_AGENT_HTTPS_PROXY=http://localhost:1081 npm update"
|
||||
},
|
||||
"browserslist": [
|
||||
|
@ -156,35 +159,36 @@
|
|||
},
|
||||
"homepage": "https://github.com/lyswhut/lx-music-desktop#readme",
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.13.16",
|
||||
"@babel/core": "^7.14.3",
|
||||
"@babel/plugin-proposal-class-properties": "^7.13.0",
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
||||
"@babel/plugin-transform-modules-umd": "^7.13.0",
|
||||
"@babel/plugin-transform-runtime": "^7.13.15",
|
||||
"@babel/plugin-transform-modules-umd": "^7.14.0",
|
||||
"@babel/plugin-transform-runtime": "^7.14.3",
|
||||
"@babel/polyfill": "^7.12.1",
|
||||
"@babel/preset-env": "^7.13.15",
|
||||
"@babel/preset-env": "^7.14.2",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"babel-loader": "^8.2.2",
|
||||
"babel-minify-webpack-plugin": "^0.3.1",
|
||||
"babel-preset-minify": "^0.5.1",
|
||||
"cfonts": "^2.9.1",
|
||||
"cfonts": "^2.9.2",
|
||||
"chalk": "^4.1.1",
|
||||
"changelog-parser": "^2.8.0",
|
||||
"copy-webpack-plugin": "^8.1.1",
|
||||
"core-js": "^3.11.0",
|
||||
"core-js": "^3.12.1",
|
||||
"cross-env": "^7.0.3",
|
||||
"css-loader": "^5.2.4",
|
||||
"css-minimizer-webpack-plugin": "^3.0.0",
|
||||
"del": "^6.0.0",
|
||||
"electron": "^9.4.4",
|
||||
"electron-builder": "^22.10.5",
|
||||
"electron": "^12.0.8",
|
||||
"electron-builder": "^22.11.4",
|
||||
"electron-debug": "^3.2.0",
|
||||
"electron-devtools-installer": "^3.2.0",
|
||||
"eslint": "^7.25.0",
|
||||
"eslint": "^7.26.0",
|
||||
"eslint-config-standard": "^14.1.1",
|
||||
"eslint-formatter-friendly": "^7.0.0",
|
||||
"eslint-loader": "^4.0.2",
|
||||
"eslint-plugin-html": "^6.1.2",
|
||||
"eslint-plugin-import": "^2.22.1",
|
||||
"eslint-plugin-import": "^2.23.2",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-promise": "^5.1.0",
|
||||
"eslint-plugin-standard": "^4.1.0",
|
||||
|
@ -192,13 +196,12 @@
|
|||
"friendly-errors-webpack-plugin": "^1.7.0",
|
||||
"html-webpack-plugin": "^5.3.1",
|
||||
"less": "^4.1.1",
|
||||
"less-loader": "^8.1.1",
|
||||
"less-loader": "^9.0.0",
|
||||
"less-plugin-clean-css": "^1.5.1",
|
||||
"markdown-it": "^12.0.6",
|
||||
"mini-css-extract-plugin": "^1.5.0",
|
||||
"optimize-css-assets-webpack-plugin": "^5.0.4",
|
||||
"postcss": "^8.2.12",
|
||||
"postcss-loader": "^5.2.0",
|
||||
"mini-css-extract-plugin": "^1.6.0",
|
||||
"postcss": "^8.2.15",
|
||||
"postcss-loader": "^5.3.0",
|
||||
"postcss-pxtorem": "^6.0.0",
|
||||
"pug": "^3.0.2",
|
||||
"pug-loader": "^2.4.0",
|
||||
|
@ -207,13 +210,13 @@
|
|||
"rimraf": "^3.0.2",
|
||||
"spinnies": "^0.5.1",
|
||||
"stylus": "^0.54.8",
|
||||
"stylus-loader": "^5.0.0",
|
||||
"terser-webpack-plugin": "^5.1.1",
|
||||
"stylus-loader": "^6.0.0",
|
||||
"terser-webpack-plugin": "^5.1.2",
|
||||
"url-loader": "^4.1.1",
|
||||
"vue-loader": "^15.9.6",
|
||||
"vue-loader": "^15.9.7",
|
||||
"vue-template-compiler": "^2.6.12",
|
||||
"webpack": "^5.35.1",
|
||||
"webpack-cli": "^4.6.0",
|
||||
"webpack": "^5.37.0",
|
||||
"webpack-cli": "^4.7.0",
|
||||
"webpack-dev-server": "^3.11.2",
|
||||
"webpack-hot-middleware": "^2.25.0",
|
||||
"webpack-merge": "^5.7.3"
|
||||
|
@ -221,18 +224,18 @@
|
|||
"dependencies": {
|
||||
"crypto-js": "^4.0.0",
|
||||
"dnscache": "^1.0.2",
|
||||
"electron-log": "^4.3.4",
|
||||
"electron-store": "^6.0.1",
|
||||
"electron-updater": "^4.3.8",
|
||||
"electron-log": "^4.3.5",
|
||||
"electron-store": "^8.0.0",
|
||||
"electron-updater": "^4.3.9",
|
||||
"iconv-lite": "^0.6.2",
|
||||
"image-size": "^1.0.0",
|
||||
"js-htmlencode": "^0.3.0",
|
||||
"lrc-file-parser": "^1.0.7",
|
||||
"needle": "^2.6.0",
|
||||
"node-id3": "^0.2.2",
|
||||
"node-id3": "^0.2.3",
|
||||
"request": "^2.88.2",
|
||||
"vue": "^2.6.12",
|
||||
"vue-i18n": "^8.24.3",
|
||||
"vue-i18n": "^8.24.4",
|
||||
"vue-router": "^3.5.1",
|
||||
"vuex": "^3.6.2",
|
||||
"vuex-router-sync": "^5.0.0"
|
||||
|
|
|
@ -1,20 +1,21 @@
|
|||
lx music移动端已经发布了,使用习惯仍跟桌面版一样,不过功能、界面仍比较简单,有兴趣的可以去体检一下,项目地址:
|
||||
https://github.com/lyswhut/lx-music-mobile#readme
|
||||
|
||||
### 新增
|
||||
|
||||
- 新增启动参数`-dhmkh`,此参数将禁用Chromium的Hardware Media Key Handling特性,用于解决漫步者部分型号耳机与本程序冲突导致耳机意外关机的问题
|
||||
- 新增Windows arm64位免安装版的构建
|
||||
- 新增黑色皮肤“黑灯瞎火”,有关于皮肤配色的建议欢迎反馈
|
||||
- 新增自动换源下载功能,默认关闭,当无法从歌曲的原始源下载时,将尝试切换到其他源下载,注:此功能不100%保证换源后的歌曲版本与原版一致
|
||||
|
||||
### 优化
|
||||
|
||||
- 程序启动时对数据文件做读取校验,数据出现损坏时自动备份损坏的数据,若出现数据读取错误的弹窗并出现我的列表丢失时可到GitHub或加群反馈
|
||||
- 当设置-代理启用,但主机地址为空的时,将不再使用代理配置进行网络连接,并且在离开设置界面时自动禁用代理
|
||||
- 优化歌曲自动换源匹配
|
||||
- 分离歌词与歌曲列表信息的保存,以减小列表列表文件损坏的几率
|
||||
- 兼容打开咪咕移动端分享的歌单链接,添加打开歌单的信息显示
|
||||
- 排行榜界面添加播放、收藏整个排行榜功能,可以右击排行榜名字后,在弹出的右键菜单中使用。注:收藏、播放存在分页的排行榜时需等待操作完成后才能切换排行榜,不然会导致操作中断。
|
||||
- 新增Mac arm64位dmg包的构建
|
||||
|
||||
### 修复
|
||||
|
||||
- 修复备份与恢复功能在恢复数据时某些设置不立即生效的问题
|
||||
- 修正设置页“搜索设置”部分内容的缩进显示问题
|
||||
- 修复正在播放“稍后播放”的歌曲时,对“稍后播放”前播放的列表进行添加、删除操作会导致切歌的问题
|
||||
- 修复全局快捷键对桌面歌词无效的问题
|
||||
- 修复快捷键设置框内的提示问题
|
||||
- 修复在当前正常播放的列表中使用稍后播放功能时,播放完后稍后播放的歌曲后不会恢复原来播放位置播放的问题
|
||||
- 修复kw部分歌单无法打开的问题
|
||||
- 修复wy源的歌曲音质匹配问题
|
||||
- 修复mg源歌单标签、排行榜歌曲列表无法加载的问题
|
||||
- 修复了一个歌曲下载失败时不会跳过任务的问题
|
||||
|
||||
### 其他
|
||||
|
||||
- 更新 Electron 到 12.0.8
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -28,8 +28,11 @@ require('./env')
|
|||
|
||||
// Is disable hardware acceleration
|
||||
if (global.envParams.cmdParams.dha) app.disableHardwareAcceleration()
|
||||
|
||||
if (global.envParams.cmdParams.dt == null && global.envParams.cmdParams.nt != null) global.envParams.cmdParams.dt = global.envParams.cmdParams.nt
|
||||
if (global.envParams.cmdParams.dhmkh) app.commandLine.appendSwitch('disable-features', 'HardwareMediaKeyHandling')
|
||||
// fix linux transparent fail. https://github.com/electron/electron/issues/25153#issuecomment-843688494
|
||||
if (process.platform == 'linux') app.commandLine.appendSwitch('use-gl', 'desktop')
|
||||
|
||||
// https://github.com/electron/electron/issues/22691
|
||||
app.commandLine.appendSwitch('wm-window-animations-disabled')
|
||||
|
@ -112,7 +115,7 @@ function createWindow() {
|
|||
fullscreenable: false,
|
||||
show: false,
|
||||
webPreferences: {
|
||||
// contextIsolation: true,
|
||||
contextIsolation: false,
|
||||
webSecurity: !isDev,
|
||||
nodeIntegration: true,
|
||||
},
|
||||
|
|
|
@ -2,7 +2,6 @@ const { common: COMMON_EVENT_NAME, winLyric: WIN_LYRIC_EVENT_NAME, hotKey: HOT_K
|
|||
const { mainSend, NAMES: { winLyric: ipcWinLyricNames } } = require('../../../common/ipc')
|
||||
const { desktop_lyric } = require('../../../common/hotKey')
|
||||
const { getLyricWindowBounds } = require('./utils')
|
||||
const { updateSetting } = require('../../utils')
|
||||
|
||||
let isLock = null
|
||||
let isEnable = null
|
||||
|
@ -78,5 +77,5 @@ global.lx_event.hotKey.on(HOT_KEY_EVENT_NAME.keyDown, ({ type, key }) => {
|
|||
}
|
||||
desktopLyricSetting[settingKey] = !desktopLyricSetting[settingKey]
|
||||
|
||||
updateSetting({ desktopLyric: desktopLyricSetting }, null)
|
||||
global.lx_core.setAppConfig({ desktopLyric: desktopLyricSetting }, null)
|
||||
})
|
||||
|
|
|
@ -109,7 +109,7 @@ const createWindow = () => {
|
|||
alwaysOnTop: isAlwaysOnTop,
|
||||
skipTaskbar: true,
|
||||
webPreferences: {
|
||||
// contextIsolation: true,
|
||||
contextIsolation: false,
|
||||
webSecurity: !global.isDev,
|
||||
nodeIntegration: true,
|
||||
},
|
||||
|
|
|
@ -202,7 +202,7 @@ svg(version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/19
|
|||
path(d='M69.148,97.826l17.7-17.651,333,334-17.7,17.652Z')
|
||||
|
||||
g#icon-add-2(fill='currentColor')
|
||||
//- 0 0 1024 1024
|
||||
//- 0 0 512 512
|
||||
path(d='M256,170s-62.469-76.808-141-24C44.762,222.824,84.909,325.08,256,415c21.339-8.361,44-17,44-17,19-6.392,28.155,20.742,16,26-27.589,11.935,5.974-4.141-60,28C-35.524,313.85,43.993,149.031,95,117c86.8-65.89,162,10,162,10s58.158-60.523,140-23c104.032,58.528,64,161.9,45,196-9.152,15.154-39.559-4.159-32-16,20.34-37.888,45.522-107.349-25-150C314.919,103.92,256,170,256,170Z')
|
||||
path(d='M383,368c-8.1.01-24.77-.155-40,0-15.713.16-15.282,34.964,0,35,15.1,0.035,40,0,40,0s-0.068,42.8,0,48c0.208,15.961,32.261,15.791,32-1-0.072-4.649,0-47,0-47s38.008-.031,43,0c15.732,0.046,14.947-33.98-1-34-4.884.093-42,0-42,0s-0.053-28.341,0-46c0.046-15.189-32.028-15.512-32,0C383.027,337.74,382.782,365.139,383,368Z')
|
||||
|
||||
|
|
|
@ -41,7 +41,8 @@ div(:class="$style.player")
|
|||
div(:class="$style.column2")
|
||||
div(:class="$style.progress" v-if="!isShowPlayerDetail")
|
||||
//- div(:class="[$style.progressBar, $style.progressBar1]" :style="{ transform: `scaleX(${progress || 0})` }")
|
||||
div(:class="[$style.progressBar, $style.progressBar2, isActiveTransition ? $style.barTransition : '']" @transitionend="handleTransitionEnd" :style="{ transform: `scaleX(${progress || 0})`, willChange: isPlay || isActiveTransition ? 'transform' : 'auto' }")
|
||||
div(:class="[$style.progressBar, $style.progressBar2, isActiveTransition ? $style.barTransition : '']"
|
||||
@transitionend="handleTransitionEnd" :style="{ transform: `scaleX(${progress || 0})` }")
|
||||
div(:class="$style.progressMask" @click='handleSetProgress' ref="dom_progress")
|
||||
div(:class="$style.column3")
|
||||
span(:class="$style.statusText") {{statusText}}
|
||||
|
@ -604,37 +605,28 @@ export default {
|
|||
if (highQuality && songInfo._types['320k'] && list && list.includes('320k')) type = '320k'
|
||||
return type
|
||||
},
|
||||
setUrl(targetSong, isRefresh, isRetryed = false, retryedSource = [], originMusic = null) {
|
||||
if (!retryedSource.includes(targetSong.source)) retryedSource.push(targetSong.source)
|
||||
|
||||
setUrl(targetSong, isRefresh, isRetryed = false) {
|
||||
let type = this.getPlayType(this.setting.player.highQuality, targetSong)
|
||||
// this.musicInfo.url = await getMusicUrl(targetSong, type)
|
||||
this.status = this.statusText = this.$t('core.player.geting_url')
|
||||
|
||||
return this.getUrl({ musicInfo: targetSong, originMusic, type, isRefresh }).then(url => {
|
||||
if ((targetSong !== this.targetSong && originMusic !== this.targetSong) || this.isPlay) return
|
||||
return this.getUrl({
|
||||
musicInfo: targetSong,
|
||||
type,
|
||||
isRefresh,
|
||||
onToggleSource: () => {
|
||||
this.status = this.statusText = 'Try toggle source...'
|
||||
},
|
||||
}).then(url => {
|
||||
if (targetSong !== this.targetSong || this.isPlay) return
|
||||
audio.src = this.musicInfo.url = url
|
||||
}).catch(err => {
|
||||
// console.log('err', err.message)
|
||||
if (err.message == requestMsg.cancelRequest) return
|
||||
if (!isRetryed) return this.setUrl(targetSong, isRefresh, true, retryedSource, originMusic)
|
||||
if (!originMusic) originMusic = targetSong
|
||||
|
||||
this.status = this.statusText = 'Try toggle source...'
|
||||
|
||||
return this.getOtherSource(originMusic).then(otherSource => {
|
||||
console.log('find otherSource', otherSource)
|
||||
if (otherSource.length) {
|
||||
for (const item of otherSource) {
|
||||
if (retryedSource.includes(item.source) || !this.assertApiSupport(item.source)) continue
|
||||
console.log('try toggle to: ', item.source, item.name, item.singer, item.interval)
|
||||
return this.setUrl(item, isRefresh, false, retryedSource, originMusic)
|
||||
}
|
||||
}
|
||||
this.status = this.statusText = err.message
|
||||
this.addDelayNextTimeout()
|
||||
return Promise.reject(err)
|
||||
})
|
||||
if (!isRetryed) return this.setUrl(targetSong, isRefresh, true)
|
||||
this.status = this.statusText = err.message
|
||||
this.addDelayNextTimeout()
|
||||
return Promise.reject(err)
|
||||
})
|
||||
},
|
||||
setImg(targetSong) {
|
||||
|
@ -1131,7 +1123,7 @@ export default {
|
|||
|
||||
.progress {
|
||||
width: 100%;
|
||||
height: 3px;
|
||||
height: 4px;
|
||||
// overflow: hidden;
|
||||
transition: @transition-theme;
|
||||
transition-property: background-color;
|
||||
|
@ -1164,6 +1156,7 @@ export default {
|
|||
.progress-bar2 {
|
||||
background-color: @color-player-progress-bar2;
|
||||
box-shadow: 0 0 2px rgba(0, 0, 0, 0.3);
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.bar-transition {
|
||||
|
|
|
@ -84,6 +84,10 @@ export default {
|
|||
type: String,
|
||||
default: '列表加载中...',
|
||||
},
|
||||
hideListsMenu: {
|
||||
type: Function,
|
||||
default: () => {},
|
||||
},
|
||||
rowWidth: {
|
||||
type: Object,
|
||||
default() {
|
||||
|
@ -349,6 +353,7 @@ export default {
|
|||
this.listMenu.rightClickItemIndex = index
|
||||
this.listMenu.menuLocation.x = dom_td.offsetLeft + event.offsetX
|
||||
this.listMenu.menuLocation.y = dom_td.offsetParent.offsetTop + dom_td.offsetTop + event.offsetY - this.$refs.dom_scrollContent.scrollTop
|
||||
this.hideListsMenu()
|
||||
this.$nextTick(() => {
|
||||
this.listMenu.isShowItemMenu = true
|
||||
})
|
||||
|
|
|
@ -46,7 +46,7 @@ material-modal(:show="version.showModal" @close="handleClose" v-if="version.newV
|
|||
| 你可以去
|
||||
strong.hover.underline(@click="handleOpenUrl('https://github.com/lyswhut/lx-music-desktop/releases')" tips="点击打开") 软件发布页
|
||||
| 或
|
||||
strong.hover.underline(@click="handleOpenUrl('https://www.lanzous.com/b0bf2cfa/')" tips="点击打开") 网盘
|
||||
strong.hover.underline(@click="handleOpenUrl('https://www.lanzoui.com/b0bf2cfa/')" tips="点击打开") 网盘
|
||||
| (密码:
|
||||
strong.hover(@click="handleCopy('glqw')" tips="点击复制") glqw
|
||||
| ) 下载新版本,
|
||||
|
@ -63,7 +63,7 @@ material-modal(:show="version.showModal" @close="handleClose" v-if="version.newV
|
|||
| 你可以去
|
||||
material-btn(min @click="handleOpenUrl('https://github.com/lyswhut/lx-music-desktop/releases')" tips="点击打开") 软件发布页
|
||||
| 或
|
||||
material-btn(min @click="handleOpenUrl('https://www.lanzous.com/b0bf2cfa/')" tips="点击打开") 网盘
|
||||
material-btn(min @click="handleOpenUrl('https://www.lanzoui.com/b0bf2cfa/')" tips="点击打开") 网盘
|
||||
| (密码:
|
||||
strong.hover(@click="handleCopy('glqw')" tips="点击复制") glqw
|
||||
| )下载新版本,
|
||||
|
@ -84,7 +84,7 @@ material-modal(:show="version.showModal" @close="handleClose" v-if="version.newV
|
|||
| 检查方法:打开
|
||||
material-btn(min @click="handleOpenUrl('https://github.com/lyswhut/lx-music-desktop/releases')" tips="点击打开") 软件发布页
|
||||
| 或
|
||||
material-btn(min @click="handleOpenUrl('https://www.lanzous.com/b0bf2cfa/')" tips="点击打开") 网盘
|
||||
material-btn(min @click="handleOpenUrl('https://www.lanzoui.com/b0bf2cfa/')" tips="点击打开") 网盘
|
||||
| (密码:
|
||||
strong.hover(@click="handleCopy('glqw')" tips="点击复制") glqw
|
||||
| )查看它们的
|
||||
|
@ -117,7 +117,7 @@ material-modal(:show="version.showModal" @close="handleClose" v-if="version.newV
|
|||
| 手动更新可以去
|
||||
strong.hover.underline(@click="handleOpenUrl('https://github.com/lyswhut/lx-music-desktop/releases')" tips="点击打开") 软件发布页
|
||||
| 或
|
||||
strong.hover.underline(@click="handleOpenUrl('https://www.lanzous.com/b0bf2cfa/')" tips="点击打开") 网盘
|
||||
strong.hover.underline(@click="handleOpenUrl('https://www.lanzoui.com/b0bf2cfa/')" tips="点击打开") 网盘
|
||||
| (密码:
|
||||
strong.hover(@click="handleCopy('glqw')" tips="点击复制") glqw
|
||||
| ) 下载,
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"play": "播放",
|
||||
"collect": "收藏"
|
||||
}
|
|
@ -165,12 +165,12 @@ const handleGetMusicUrl = function(musicInfo, type, retryedSource = [], originMu
|
|||
reqPromise = Promise.reject(err)
|
||||
}
|
||||
return reqPromise.catch(err => {
|
||||
if (!retryedSource.includes(musicInfo.source) || !assertApiSupport(musicInfo.source)) retryedSource.push(musicInfo.source)
|
||||
if (!retryedSource.includes(musicInfo.source)) retryedSource.push(musicInfo.source)
|
||||
return this.dispatch('list/getOtherSource', originMusic).then(otherSource => {
|
||||
console.log('find otherSource', otherSource)
|
||||
if (otherSource.length) {
|
||||
for (const item of otherSource) {
|
||||
if (retryedSource.includes(item.source)) continue
|
||||
if (retryedSource.includes(item.source) || !assertApiSupport(item.source)) continue
|
||||
console.log('try toggle to: ', item.source, item.name, item.singer, item.interval)
|
||||
return handleGetMusicUrl.call(this, item, type, retryedSource, originMusic)
|
||||
}
|
||||
|
@ -460,7 +460,7 @@ const actions = {
|
|||
},
|
||||
onFail(response) {
|
||||
if (++tryNum[downloadInfo.key] > 2) {
|
||||
commit('onError', downloadInfo)
|
||||
commit('onError', { downloadInfo, errorMsg: '下载失败' })
|
||||
dispatch('startTask')
|
||||
return
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import music from '../../utils/music'
|
||||
const sourceList = {}
|
||||
const sources = []
|
||||
const cache = new Map()
|
||||
for (const source of music.sources) {
|
||||
const leaderboard = music[source.id].leaderboard
|
||||
if (!leaderboard || !leaderboard.getBoards) continue
|
||||
|
@ -55,10 +56,39 @@ const actions = {
|
|||
let tabId = rootState.setting.leaderboard.tabId
|
||||
let [source, bangId] = tabId.split('__')
|
||||
let key = `${source}${tabId}${page}`
|
||||
if (state.list.length && state.key == key) return true
|
||||
if (state.list.length && state.key == key) return Promise.resolve()
|
||||
commit('clearList')
|
||||
// return (
|
||||
// cache.has(key)
|
||||
// ? Promise.resolve(cache.get(key))
|
||||
// : music[source].leaderboard.getList(bangId, page)
|
||||
// ).then(result => commit('setList', { result, key }))
|
||||
return music[source].leaderboard.getList(bangId, page).then(result => commit('setList', { result, key }))
|
||||
},
|
||||
getListAll({ state, rootState }, id) {
|
||||
// console.log(source, id)
|
||||
let [source, bangId] = id.split('__')
|
||||
const loadData = (id, page) => {
|
||||
let key = `${source}${id}${page}`
|
||||
return cache.has(key)
|
||||
? Promise.resolve(cache.get(key))
|
||||
: music[source].leaderboard.getList(bangId, page).then(result => {
|
||||
cache.set(key, result)
|
||||
return result
|
||||
})
|
||||
}
|
||||
return loadData(id, 1).then(result => {
|
||||
if (result.total <= result.limit) return result.list
|
||||
|
||||
let maxPage = Math.ceil(result.total / result.limit)
|
||||
const load = (loadPage = 2) => {
|
||||
return loadPage == maxPage
|
||||
? loadData(id, loadPage).then(result => result.list)
|
||||
: loadData(id, loadPage).then(result1 => load(++loadPage).then(result2 => [...result1.list, ...result2]))
|
||||
}
|
||||
return load().then(result2 => [...result.list, ...result2])
|
||||
})
|
||||
},
|
||||
}
|
||||
|
||||
// mitations
|
||||
|
@ -72,6 +102,7 @@ const mutations = {
|
|||
state.limit = result.limit
|
||||
state.page = result.page
|
||||
state.key = key
|
||||
cache.set(key, result)
|
||||
},
|
||||
clearList(state) {
|
||||
state.list = []
|
||||
|
|
|
@ -6,7 +6,8 @@ import {
|
|||
getLyric as getStoreLyric,
|
||||
setLyric,
|
||||
setMusicUrl,
|
||||
getMusicUrl,
|
||||
getMusicUrl as getStoreMusicUrl,
|
||||
assertApiSupport,
|
||||
} from '../../utils'
|
||||
|
||||
// state
|
||||
|
@ -66,6 +67,32 @@ const filterList = async({ playedList, listInfo, savePath, commit }) => {
|
|||
return list
|
||||
}
|
||||
|
||||
const getMusicUrl = function(musicInfo, type, onToggleSource, retryedSource = [], originMusic) {
|
||||
// console.log(musicInfo.source)
|
||||
if (!originMusic) originMusic = musicInfo
|
||||
let reqPromise
|
||||
try {
|
||||
reqPromise = music[musicInfo.source].getMusicUrl(musicInfo, type).promise
|
||||
} catch (err) {
|
||||
reqPromise = Promise.reject(err)
|
||||
}
|
||||
return reqPromise.catch(err => {
|
||||
if (!retryedSource.includes(musicInfo.source)) retryedSource.push(musicInfo.source)
|
||||
onToggleSource()
|
||||
return this.dispatch('list/getOtherSource', originMusic).then(otherSource => {
|
||||
console.log('find otherSource', otherSource)
|
||||
if (otherSource.length) {
|
||||
for (const item of otherSource) {
|
||||
if (retryedSource.includes(item.source) || !assertApiSupport(item.source)) continue
|
||||
console.log('try toggle to: ', item.source, item.name, item.singer, item.interval)
|
||||
return getMusicUrl.call(this, item, type, onToggleSource, retryedSource, originMusic)
|
||||
}
|
||||
}
|
||||
return Promise.reject(err)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const getPic = function(musicInfo, retryedSource = [], originMusic) {
|
||||
// console.log(musicInfo.source)
|
||||
if (!originMusic) originMusic = musicInfo
|
||||
|
@ -163,24 +190,17 @@ const getters = {
|
|||
|
||||
// actions
|
||||
const actions = {
|
||||
async getUrl({ commit, state }, { musicInfo, originMusic, type, isRefresh }) {
|
||||
if (!musicInfo._types[type]) {
|
||||
// 兼容旧版酷我源搜索列表过滤128k音质的bug
|
||||
if (!(musicInfo.source == 'kw' && type == '128k')) throw new Error('该歌曲没有可播放的音频')
|
||||
async getUrl({ commit, state }, { musicInfo, type, isRefresh, onToggleSource = () => {} }) {
|
||||
// if (!musicInfo._types[type]) {
|
||||
// // 兼容旧版酷我源搜索列表过滤128k音质的bug
|
||||
// if (!(musicInfo.source == 'kw' && type == '128k')) throw new Error('该歌曲没有可播放的音频')
|
||||
|
||||
// return Promise.reject(new Error('该歌曲没有可播放的音频'))
|
||||
}
|
||||
const cachedUrl = await getMusicUrl(musicInfo, type)
|
||||
// // return Promise.reject(new Error('该歌曲没有可播放的音频'))
|
||||
// }
|
||||
const cachedUrl = await getStoreMusicUrl(musicInfo, type)
|
||||
if (cachedUrl && !isRefresh) return cachedUrl
|
||||
|
||||
let reqPromise
|
||||
try {
|
||||
reqPromise = music[musicInfo.source].getMusicUrl(musicInfo, type).promise
|
||||
} catch (err) {
|
||||
reqPromise = Promise.reject(err)
|
||||
}
|
||||
return reqPromise.then(({ url }) => {
|
||||
if (originMusic) commit('setUrl', { musicInfo: originMusic, url, type })
|
||||
return getMusicUrl.call(this, musicInfo, type, onToggleSource).then(({ url }) => {
|
||||
commit('setUrl', { musicInfo, url, type })
|
||||
return url
|
||||
}).catch(err => {
|
||||
|
@ -412,7 +432,7 @@ const mutations = {
|
|||
playIndex = -1
|
||||
} else {
|
||||
let listId = playMusicInfo.listId
|
||||
if (listId != '__temp__' && listId === state.listInfo.id) playIndex = state.listInfo.list.indexOf(playMusicInfo.musicInfo)
|
||||
if (listId != '__temp__' && !playMusicInfo.isTempPlay && listId === state.listInfo.id) playIndex = state.listInfo.list.indexOf(playMusicInfo.musicInfo)
|
||||
}
|
||||
|
||||
state.playMusicInfo = playMusicInfo
|
||||
|
|
|
@ -105,10 +105,10 @@ const actions = {
|
|||
if (result.total <= result.limit) return filterList(result.list)
|
||||
|
||||
let maxPage = Math.ceil(result.total / result.limit)
|
||||
const loadDetail = (loadPage = 1) => {
|
||||
const loadDetail = (loadPage = 2) => {
|
||||
return loadPage == maxPage
|
||||
? loadData(id, ++loadPage).then(result => result.list)
|
||||
: loadData(id, ++loadPage).then(result1 => loadDetail(loadPage).then(result2 => [...result1.list, ...result2]))
|
||||
? loadData(id, loadPage).then(result => result.list)
|
||||
: loadData(id, loadPage).then(result1 => loadDetail(++loadPage).then(result2 => [...result1.list, ...result2]))
|
||||
}
|
||||
return loadDetail().then(result2 => [...result.list, ...result2]).then(list => filterList(list))
|
||||
})
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { httpGet, cancelHttp, httpFetch } from '../../request'
|
||||
import { httpFetch } from '../../request'
|
||||
import { decodeName, formatPlayTime, sizeFormate } from '../../index'
|
||||
|
||||
let boardList = [{ id: 'kg__8888', name: '酷狗TOP500', bangid: '8888' }, { id: 'kg__6666', name: '酷狗飙升榜', bangid: '6666' }, { id: 'kg__37361', name: '酷狗雷达榜', bangid: '37361' }, { id: 'kg__23784', name: '网络红歌榜', bangid: '23784' }, { id: 'kg__24971', name: 'DJ热歌榜', bangid: '24971' }, { id: 'kg__35811', name: '会员专享热歌榜', bangid: '35811' }, { id: 'kg__31308', name: '华语新歌榜', bangid: '31308' }, { id: 'kg__31310', name: '欧美新歌榜', bangid: '31310' }, { id: 'kg__31311', name: '韩国新歌榜', bangid: '31311' }, { id: 'kg__31312', name: '日本新歌榜', bangid: '31312' }, { id: 'kg__31313', name: '粤语新歌榜', bangid: '31313' }, { id: 'kg__33162', name: 'ACG新歌榜', bangid: '33162' }, { id: 'kg__21101', name: '酷狗分享榜', bangid: '21101' }, { id: 'kg__30972', name: '腾讯音乐人原创榜', bangid: '30972' }, { id: 'kg__22603', name: '5sing音乐榜', bangid: '22603' }, { id: 'kg__33160', name: '电音热歌榜', bangid: '33160' }, { id: 'kg__21335', name: '繁星音乐榜', bangid: '21335' }, { id: 'kg__33161', name: '古风新歌榜', bangid: '33161' }, { id: 'kg__33163', name: '影视金曲榜', bangid: '33163' }, { id: 'kg__33166', name: '欧美金曲榜', bangid: '33166' }, { id: 'kg__33165', name: '粤语金曲榜', bangid: '33165' }, { id: 'kg__36107', name: '小语种热歌榜', bangid: '36107' }, { id: 'kg__4681', name: '美国BillBoard榜', bangid: '4681' }, { id: 'kg__4680', name: '英国单曲榜', bangid: '4680' }, { id: 'kg__4673', name: '日本公信榜', bangid: '4673' }, { id: 'kg__38623', name: '韩国Melon音乐榜', bangid: '38623' }, { id: 'kg__42807', name: 'joox本地热歌榜', bangid: '42807' }, { id: 'kg__42808', name: '台湾KKBOX风云榜', bangid: '42808' }]
|
||||
|
@ -71,30 +71,16 @@ export default {
|
|||
listData: /global\.features = (\[.+\]);/,
|
||||
},
|
||||
_requestBoardsObj: null,
|
||||
_requestObj: null,
|
||||
_cancelPromiseCancelFn: null,
|
||||
_requestDataObj: null,
|
||||
getBoardsData() {
|
||||
if (this._requestBoardsObj) this._requestBoardsObj.cancelHttp()
|
||||
this._requestBoardsObj = httpFetch('http://mobilecdnbj.kugou.com/api/v3/rank/list?version=9108&plat=0&showtype=2&parentid=0&apiver=6&area_code=1&withsong=1')
|
||||
return this._requestBoardsObj.promise
|
||||
},
|
||||
getData(url) {
|
||||
if (this._requestObj != null) {
|
||||
cancelHttp(this._requestObj)
|
||||
this._cancelPromiseCancelFn(new Error('取消http请求'))
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
this._cancelPromiseCancelFn = reject
|
||||
this._requestObj = httpGet(url, (err, resp, body) => {
|
||||
this._requestObj = null
|
||||
this._cancelPromiseCancelFn = null
|
||||
if (err) {
|
||||
console.log(err)
|
||||
reject(err)
|
||||
}
|
||||
resolve(body)
|
||||
})
|
||||
})
|
||||
if (this._requestDataObj) this._requestDataObj.cancelHttp()
|
||||
this._requestDataObj = httpFetch(url)
|
||||
return this._requestDataObj.promise
|
||||
},
|
||||
filterData(rawList) {
|
||||
// console.log(rawList)
|
||||
|
@ -189,7 +175,7 @@ export default {
|
|||
}
|
||||
},
|
||||
getList(bangid, page) {
|
||||
return this.getData(this.getUrl(page, bangid)).then(html => {
|
||||
return this.getData(this.getUrl(page, bangid)).then(({ body: html }) => {
|
||||
let total = html.match(this.regExps.total)
|
||||
if (total) total = parseInt(RegExp.$1)
|
||||
page = html.match(this.regExps.page)
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
import { httpFetch } from '../../request'
|
||||
import { decodeName } from '../../index'
|
||||
import { formatSinger, objStr2JSON } from './util'
|
||||
|
||||
// let requestObj_list
|
||||
let requestObj_listDetail
|
||||
export default {
|
||||
limit_list: 36,
|
||||
limit_song: 1000,
|
||||
filterListDetail(rawList, albumName, albumId) {
|
||||
// console.log(rawList)
|
||||
// console.log(rawList.length, rawList2.length)
|
||||
return rawList.map((item, inedx) => {
|
||||
let formats = item.formats.split('|')
|
||||
let types = []
|
||||
let _types = {}
|
||||
if (formats.includes('MP3128')) {
|
||||
types.push({ type: '128k', size: null })
|
||||
_types['128k'] = {
|
||||
size: null,
|
||||
}
|
||||
}
|
||||
// if (formats.includes('MP3192')) {
|
||||
// types.push({ type: '192k', size: null })
|
||||
// _types['192k'] = {
|
||||
// size: null,
|
||||
// }
|
||||
// }
|
||||
if (formats.includes('MP3H')) {
|
||||
types.push({ type: '320k', size: null })
|
||||
_types['320k'] = {
|
||||
size: null,
|
||||
}
|
||||
}
|
||||
// if (formats.includes('AL')) {
|
||||
// types.push({ type: 'ape', size: null })
|
||||
// _types.ape = {
|
||||
// size: null,
|
||||
// }
|
||||
// }
|
||||
if (formats.includes('ALFLAC')) {
|
||||
types.push({ type: 'flac', size: null })
|
||||
_types.flac = {
|
||||
size: null,
|
||||
}
|
||||
}
|
||||
// types.reverse()
|
||||
return {
|
||||
singer: formatSinger(decodeName(item.artist)),
|
||||
name: decodeName(item.name),
|
||||
albumName,
|
||||
albumId,
|
||||
songmid: item.id,
|
||||
source: 'kw',
|
||||
interval: null,
|
||||
img: item.pic,
|
||||
lrc: null,
|
||||
otherSource: null,
|
||||
types,
|
||||
_types,
|
||||
typeUrl: {},
|
||||
}
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 格式化播放数量
|
||||
* @param {*} num
|
||||
*/
|
||||
formatPlayCount(num) {
|
||||
if (num > 100000000) return parseInt(num / 10000000) / 10 + '亿'
|
||||
if (num > 10000) return parseInt(num / 1000) / 10 + '万'
|
||||
return num
|
||||
},
|
||||
getAlbumListDetail(id, page, retryNum = 0) {
|
||||
if (requestObj_listDetail) {
|
||||
requestObj_listDetail.cancelHttp()
|
||||
}
|
||||
if (retryNum > 2) return Promise.reject(new Error('try max num'))
|
||||
requestObj_listDetail = httpFetch(`http://search.kuwo.cn/r.s?pn=${page - 1}&rn=${this.limit_song}&stype=albuminfo&albumid=${id}&show_copyright_off=0&encoding=utf&vipver=MUSIC_9.1.0`)
|
||||
return requestObj_listDetail.promise.then(({ statusCode, body }) => {
|
||||
if (statusCode !== 200) return this.getAlbumListDetail(id, page, ++retryNum)
|
||||
body = objStr2JSON(body)
|
||||
// console.log(body)
|
||||
if (!body.musiclist) return this.getAlbumListDetail(id, page, ++retryNum)
|
||||
return {
|
||||
list: this.filterListDetail(body.musiclist, body.name, body.albumid),
|
||||
page,
|
||||
limit: this.limit_song,
|
||||
total: parseInt(body.songnum),
|
||||
source: 'kw',
|
||||
info: {
|
||||
name: body.name,
|
||||
img: body.img || body.hts_img,
|
||||
desc: body.info,
|
||||
author: body.artist,
|
||||
// play_count: this.formatPlayCount(body.playnum),
|
||||
},
|
||||
}
|
||||
})
|
||||
},
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
import { httpGet, cancelHttp } from '../../request'
|
||||
import { httpFetch } from '../../request'
|
||||
import tempSearch from './tempSearch'
|
||||
import musicSearch from './musicSearch'
|
||||
import { formatSinger, getToken } from './util'
|
||||
|
@ -64,21 +64,10 @@ const kw = {
|
|||
},
|
||||
|
||||
getMusicInfo(songInfo) {
|
||||
if (this._musicInfoRequestObj != null) {
|
||||
cancelHttp(this._musicInfoRequestObj)
|
||||
this._musicInfoPromiseCancelFn(new Error('取消http请求'))
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
this._musicInfoPromiseCancelFn = reject
|
||||
this._musicInfoRequestObj = httpGet(`http://www.kuwo.cn/api/www/music/musicInfo?mid=${songInfo.songmid}`, (err, resp, body) => {
|
||||
this._musicInfoRequestObj = null
|
||||
this._musicInfoPromiseCancelFn = null
|
||||
if (err) {
|
||||
console.log(err)
|
||||
reject(err)
|
||||
}
|
||||
body.code === 200 ? resolve(body.data) : reject(new Error(body.msg))
|
||||
})
|
||||
if (this._musicInfoRequestObj) this._musicInfoRequestObj.cancelHttp()
|
||||
this._musicInfoRequestObj = httpFetch(`http://www.kuwo.cn/api/www/music/musicInfo?mid=${songInfo.songmid}`)
|
||||
return this._musicInfoRequestObj.promise.then(({ body }) => {
|
||||
return body.code === 200 ? body.data : Promise.reject(new Error(body.msg))
|
||||
})
|
||||
},
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { httpGet, cancelHttp, httpFetch } from '../../request'
|
||||
import { httpFetch } from '../../request'
|
||||
import { formatPlayTime, decodeName } from '../../index'
|
||||
import { formatSinger } from './util'
|
||||
|
||||
|
@ -69,30 +69,16 @@ export default {
|
|||
limit: 100,
|
||||
_requestBoardsObj: null,
|
||||
|
||||
_cancelRequestObj: null,
|
||||
_cancelPromiseCancelFn: null,
|
||||
_requestDataObj: null,
|
||||
getBoardsData() {
|
||||
if (this._requestBoardsObj) this._requestBoardsObj.cancelHttp()
|
||||
this._requestBoardsObj = httpFetch('http://qukudata.kuwo.cn/q.k?op=query&cont=tree&node=2&pn=0&rn=1000&fmt=json&level=2')
|
||||
return this._requestBoardsObj.promise
|
||||
},
|
||||
getData(url) {
|
||||
if (this._cancelRequestObj != null) {
|
||||
cancelHttp(this._cancelRequestObj)
|
||||
this._cancelPromiseCancelFn(new Error('取消http请求'))
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
this._cancelPromiseCancelFn = reject
|
||||
this._cancelRequestObj = httpGet(url, (err, resp) => {
|
||||
this._cancelRequestObj = null
|
||||
this._cancelPromiseCancelFn = null
|
||||
if (err) {
|
||||
console.log(err)
|
||||
reject(err)
|
||||
}
|
||||
resolve(resp)
|
||||
})
|
||||
})
|
||||
if (this._requestDataObj) this._requestDataObj.cancelHttp()
|
||||
this._requestDataObj = httpFetch(url)
|
||||
return this._requestDataObj.promise
|
||||
},
|
||||
filterData(rawList) {
|
||||
// console.log(rawList)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// import '../../polyfill/array.find'
|
||||
// import jshtmlencode from 'js-htmlencode'
|
||||
import { httpGet, cancelHttp } from '../../request'
|
||||
import { httpFetch } from '../../request'
|
||||
import { formatPlayTime, decodeName } from '../../index'
|
||||
// import { debug } from '../../utils/env'
|
||||
import { formatSinger } from './util'
|
||||
|
@ -10,29 +10,15 @@ export default {
|
|||
mInfo: /bitrate:(\d+),format:(\w+),size:([\w.]+)/,
|
||||
},
|
||||
_musicSearchRequestObj: null,
|
||||
_musicSearchPromiseCancelFn: null,
|
||||
limit: 30,
|
||||
total: 0,
|
||||
page: 0,
|
||||
allPage: 1,
|
||||
// cancelFn: null,
|
||||
musicSearch(str, page, limit) {
|
||||
if (this._musicSearchRequestObj != null) {
|
||||
cancelHttp(this._musicSearchRequestObj)
|
||||
this._musicSearchPromiseCancelFn(new Error('取消http请求'))
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
this._musicSearchPromiseCancelFn = reject
|
||||
this._musicSearchRequestObj = httpGet(`http://search.kuwo.cn/r.s?client=kt&all=${encodeURIComponent(str)}&pn=${page - 1}&rn=${limit}&uid=794762570&ver=kwplayer_ar_9.2.2.1&vipver=1&show_copyright_off=1&newver=1&ft=music&cluster=0&strategy=2012&encoding=utf8&rformat=json&vermerge=1&mobi=1&issubtitle=1`, (err, resp, body) => {
|
||||
this._musicSearchRequestObj = null
|
||||
this._musicSearchPromiseCancelFn = null
|
||||
if (err) {
|
||||
console.log(err)
|
||||
reject(err)
|
||||
}
|
||||
resolve(body)
|
||||
})
|
||||
})
|
||||
if (this._musicSearchRequestObj) this._musicSearchRequestObj.cancelHttp()
|
||||
this._musicSearchRequestObj = httpFetch(`http://search.kuwo.cn/r.s?client=kt&all=${encodeURIComponent(str)}&pn=${page - 1}&rn=${limit}&uid=794762570&ver=kwplayer_ar_9.2.2.1&vipver=1&show_copyright_off=1&newver=1&ft=music&cluster=0&strategy=2012&encoding=utf8&rformat=json&vermerge=1&mobi=1&issubtitle=1`)
|
||||
return this._musicSearchRequestObj.promise
|
||||
},
|
||||
// getImg(songId) {
|
||||
// return httpGet(`http://player.kuwo.cn/webmusic/sj/dtflagdate?flag=6&rid=MUSIC_${songId}`)
|
||||
|
@ -127,7 +113,7 @@ export default {
|
|||
if (retryNum > 2) return Promise.reject(new Error('try max num'))
|
||||
if (limit == null) limit = this.limit
|
||||
// http://newlyric.kuwo.cn/newlyric.lrc?62355680
|
||||
return this.musicSearch(str, page, limit).then(result => {
|
||||
return this.musicSearch(str, page, limit).then(({ body: result }) => {
|
||||
// console.log(result)
|
||||
if (!result || (result.TOTAL !== '0' && result.SHOW === '0')) return this.search(str, page, { limit }, ++retryNum)
|
||||
let list = this.handleResult(result.abslist)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { httpFetch } from '../../request'
|
||||
import { formatPlayTime, decodeName } from '../../index'
|
||||
import { formatSinger } from './util'
|
||||
import album from './album'
|
||||
|
||||
export default {
|
||||
_requestObj_tags: null,
|
||||
|
@ -133,7 +134,7 @@ export default {
|
|||
filterList(rawData) {
|
||||
return rawData.map(item => ({
|
||||
play_count: this.formatPlayCount(item.listencnt),
|
||||
id: item.id,
|
||||
id: `digest-${item.digest}__${item.id}`,
|
||||
author: item.uname,
|
||||
name: item.name,
|
||||
// time: item.publish_time,
|
||||
|
@ -144,32 +145,31 @@ export default {
|
|||
}))
|
||||
},
|
||||
filterList2(rawData) {
|
||||
// console.log(rawData)
|
||||
const list = []
|
||||
rawData.forEach(item => {
|
||||
if (!item.label) return
|
||||
list.push(...item.list.map(item => ({
|
||||
play_count: item.play_count === undefined ? null : this.formatPlayCount(item.listencnt),
|
||||
id: item.id,
|
||||
play_count: item.play_count && this.formatPlayCount(item.listencnt),
|
||||
id: `digest-${item.digest}__${item.id}`,
|
||||
author: item.uname,
|
||||
name: item.name,
|
||||
// time: item.publish_time,
|
||||
img: item.img,
|
||||
grade: item.favorcnt / 10,
|
||||
grade: item.favorcnt && item.favorcnt / 10,
|
||||
desc: item.desc,
|
||||
source: 'kw',
|
||||
})))
|
||||
})
|
||||
return list
|
||||
},
|
||||
|
||||
// 获取歌曲列表内的音乐
|
||||
getListDetail(id, page, tryNum = 0) {
|
||||
getListDetailDigest8(id, page, tryNum = 0) {
|
||||
if (this._requestObj_listDetail) {
|
||||
this._requestObj_listDetail.cancelHttp()
|
||||
}
|
||||
if (tryNum > 2) return Promise.reject(new Error('try max num'))
|
||||
|
||||
if ((/[?&:/]/.test(id))) id = id.replace(this.regExps.listDetailLink, '$1')
|
||||
|
||||
this._requestObj_listDetail = httpFetch(this.getListDetailUrl(id, page))
|
||||
return this._requestObj_listDetail.promise.then(({ body }) => {
|
||||
if (body.result !== 'ok') return this.getListDetail(id, page, ++tryNum)
|
||||
|
@ -189,6 +189,66 @@ export default {
|
|||
}
|
||||
})
|
||||
},
|
||||
getListDetailDigest5Info(id, tryNum = 0) {
|
||||
if (this._requestObj_listDetail) {
|
||||
this._requestObj_listDetail.cancelHttp()
|
||||
}
|
||||
if (tryNum > 2) return Promise.reject(new Error('try max num'))
|
||||
this._requestObj_listDetail = httpFetch(`http://qukudata.kuwo.cn/q.k?op=query&cont=ninfo&node=${id}&pn=0&rn=1&fmt=json&src=mbox&level=2`)
|
||||
return this._requestObj_listDetail.promise.then(({ statusCode, body }) => {
|
||||
if (statusCode != 200 || !body.child) return this.getListDetail(id, ++tryNum)
|
||||
// console.log(body)
|
||||
return body.child.length ? body.child[0].sourceid : null
|
||||
})
|
||||
},
|
||||
getListDetailDigest5Music(id, page, tryNum = 0) {
|
||||
if (this._requestObj_listDetail) {
|
||||
this._requestObj_listDetail.cancelHttp()
|
||||
}
|
||||
if (tryNum > 2) return Promise.reject(new Error('try max num'))
|
||||
this._requestObj_listDetail = httpFetch(`http://nplserver.kuwo.cn/pl.svc?op=getlistinfo&pid=${id}&pn=${page - 1}}&rn=${this.limit_song}&encode=utf-8&keyset=pl2012&identity=kuwo&pcmp4=1`)
|
||||
return this._requestObj_listDetail.promise.then(({ body }) => {
|
||||
// console.log(body)
|
||||
if (body.result !== 'ok') return this.getListDetail(id, page, ++tryNum)
|
||||
return {
|
||||
list: this.filterListDetail(body.musiclist),
|
||||
page,
|
||||
limit: body.rn,
|
||||
total: body.total,
|
||||
source: 'kw',
|
||||
info: {
|
||||
name: body.title,
|
||||
img: body.pic,
|
||||
desc: body.info,
|
||||
author: body.uname,
|
||||
play_count: this.formatPlayCount(body.playnum),
|
||||
},
|
||||
}
|
||||
})
|
||||
},
|
||||
async getListDetailDigest5(id, page) {
|
||||
const detailId = await this.getListDetailDigest5Info(id)
|
||||
return this.getListDetailDigest5Music(detailId, page)
|
||||
},
|
||||
|
||||
// 获取歌曲列表内的音乐
|
||||
getListDetail(id, page) {
|
||||
// console.log(id)
|
||||
if ((/[?&:/]/.test(id))) id = id.replace(this.regExps.listDetailLink, '$1')
|
||||
else if (/^digest-/.test(id)) {
|
||||
let [digest, _id] = id.split('__')
|
||||
digest = digest.replace('digest-', '')
|
||||
id = _id
|
||||
switch (digest) {
|
||||
case '8':
|
||||
break
|
||||
case '13': return album.getAlbumListDetail(id, page)
|
||||
case '5':
|
||||
default: return this.getListDetailDigest5(id, page)
|
||||
}
|
||||
}
|
||||
return this.getListDetailDigest8(id, page)
|
||||
},
|
||||
filterListDetail(rawData) {
|
||||
// console.log(rawData)
|
||||
return rawData.map(item => {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { httpFetch } from '../../request'
|
||||
// import { httpFetch } from '../../request'
|
||||
import { decodeName } from '../../index'
|
||||
import { getToken, matchToken } from './util'
|
||||
import { tokenRequest } from './util'
|
||||
|
||||
|
||||
export default {
|
||||
|
@ -8,18 +8,11 @@ export default {
|
|||
relWord: /RELWORD=(.+)/,
|
||||
},
|
||||
requestObj: null,
|
||||
tempSearch(str, token) {
|
||||
async tempSearch(str) {
|
||||
this.cancelTempSearch()
|
||||
this.requestObj = httpFetch(`http://www.kuwo.cn/api/www/search/searchKey?key=${encodeURIComponent(str)}`, {
|
||||
headers: {
|
||||
Referer: 'http://www.kuwo.cn/',
|
||||
csrf: token,
|
||||
cookie: 'kw_token=' + token,
|
||||
},
|
||||
})
|
||||
return this.requestObj.promise.then(({ statusCode, body, headers }) => {
|
||||
if (statusCode != 200) return Promise.reject(new Error('请求失败'))
|
||||
window.kw_token.token = matchToken(headers)
|
||||
this.requestObj = await tokenRequest(`http://www.kuwo.cn/api/www/search/searchKey?key=${encodeURIComponent(str)}`)
|
||||
return this.requestObj.promise.then(({ body }) => {
|
||||
// console.log(body)
|
||||
if (body.code !== 200) return Promise.reject(new Error('请求失败'))
|
||||
return body
|
||||
})
|
||||
|
@ -34,8 +27,6 @@ export default {
|
|||
if (this.requestObj && this.requestObj.cancelHttp) this.requestObj.cancelHttp()
|
||||
},
|
||||
async search(str) {
|
||||
let token = window.kw_token.token
|
||||
if (!token) token = await getToken()
|
||||
return this.tempSearch(str, token).then(result => this.handleResult(result.data))
|
||||
return this.tempSearch(str).then(result => this.handleResult(result.data))
|
||||
},
|
||||
}
|
||||
|
|
|
@ -1,11 +1,29 @@
|
|||
import { httpGet } from '../../request'
|
||||
import { httpGet, httpFetch } from '../../request'
|
||||
import { rendererInvoke, NAMES } from '../../../../common/ipc'
|
||||
|
||||
if (!window.kw_token) {
|
||||
window.kw_token = {
|
||||
token: null,
|
||||
isGetingToken: false,
|
||||
}
|
||||
const kw_token = {
|
||||
token: null,
|
||||
isGetingToken: false,
|
||||
}
|
||||
|
||||
const translationMap = {
|
||||
"{'": '{"',
|
||||
"'}\n": '"}',
|
||||
"'}": '"}',
|
||||
"':'": '":"',
|
||||
"','": '","',
|
||||
"':{'": '":{"',
|
||||
"':['": '":["',
|
||||
"'}],'": '"}],"',
|
||||
"':[{'": '":[{"',
|
||||
"'},'": '"},"',
|
||||
"'},{'": '"},{"',
|
||||
"':[],'": '":[],"',
|
||||
"':{},'": '":{},"',
|
||||
}
|
||||
|
||||
export const objStr2JSON = str => {
|
||||
return JSON.parse(str.replace(/(^{'|'}\n$|'}$|':'|','|':\[{'|'}\],'|':{'|'},'|'},{'|':\['|':\[\],'|':{},')/g, s => translationMap[s]))
|
||||
}
|
||||
|
||||
export const formatSinger = rawData => rawData.replace(/&/g, '、')
|
||||
|
@ -21,17 +39,40 @@ export const matchToken = headers => {
|
|||
const wait = time => new Promise(resolve => setTimeout(() => resolve(), time))
|
||||
|
||||
|
||||
export const getToken = () => new Promise((resolve, reject) => {
|
||||
if (window.kw_token.isGetingToken) return wait(1000).then(() => getToken().then(token => resolve(token)))
|
||||
if (window.kw_token.token) return resolve(window.kw_token.token)
|
||||
window.kw_token.isGetingToken = true
|
||||
export const getToken = (retryNum = 0) => new Promise((resolve, reject) => {
|
||||
if (retryNum > 2) return Promise.reject(new Error('try max num'))
|
||||
|
||||
if (kw_token.isGetingToken) return wait(1000).then(() => getToken(retryNum).then(token => resolve(token)))
|
||||
if (kw_token.token) return resolve(kw_token.token)
|
||||
kw_token.isGetingToken = true
|
||||
httpGet('http://www.kuwo.cn/', (err, resp) => {
|
||||
window.kw_token.isGetingToken = false
|
||||
if (err) return reject(err)
|
||||
kw_token.isGetingToken = false
|
||||
if (err) return getToken(++retryNum)
|
||||
if (resp.statusCode != 200) return reject(new Error('获取失败'))
|
||||
const token = window.kw_token.token = matchToken(resp.headers)
|
||||
const token = kw_token.token = matchToken(resp.headers)
|
||||
resolve(token)
|
||||
})
|
||||
})
|
||||
|
||||
export const decodeLyric = base64Data => rendererInvoke(NAMES.mainWindow.handle_kw_decode_lyric, base64Data)
|
||||
|
||||
export const tokenRequest = async(url, options = {}) => {
|
||||
let token = kw_token.token
|
||||
if (!token) token = await getToken()
|
||||
if (!options.headers) {
|
||||
options.headers = {
|
||||
Referer: 'http://www.kuwo.cn/',
|
||||
csrf: token,
|
||||
cookie: 'kw_token=' + token,
|
||||
}
|
||||
}
|
||||
const requestObj = httpFetch(url, options)
|
||||
requestObj.promise = requestObj.promise.then(resp => {
|
||||
// console.log(resp)
|
||||
if (resp.statusCode == 200) {
|
||||
kw_token.token = matchToken(resp.headers)
|
||||
}
|
||||
return resp
|
||||
})
|
||||
return requestObj
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { apis } from '../api-source'
|
||||
import leaderboard from './leaderboard'
|
||||
import leaderboard from './leaderboard2'
|
||||
import songList from './songList'
|
||||
import musicSearch from './musicSearch'
|
||||
import pic from './pic'
|
||||
|
|
|
@ -0,0 +1,197 @@
|
|||
import { httpFetch } from '../../request'
|
||||
import { formatPlayTime } from '../../index'
|
||||
// import { sizeFormate } from '../../index'
|
||||
// import jshtmlencode from 'js-htmlencode'
|
||||
|
||||
// const boardList = [{ id: 'mg__27553319', name: '咪咕尖叫新歌榜', bangid: '27553319' }, { id: 'mg__27186466', name: '咪咕尖叫热歌榜', bangid: '27186466' }, { id: 'mg__27553408', name: '咪咕尖叫原创榜', bangid: '27553408' }, { id: 'mg__23189800', name: '咪咕港台榜', bangid: '23189800' }, { id: 'mg__23189399', name: '咪咕内地榜', bangid: '23189399' }, { id: 'mg__19190036', name: '咪咕欧美榜', bangid: '19190036' }, { id: 'mg__23189813', name: '咪咕日韩榜', bangid: '23189813' }, { id: 'mg__23190126', name: '咪咕彩铃榜', bangid: '23190126' }, { id: 'mg__15140045', name: '咪咕KTV榜', bangid: '15140045' }, { id: 'mg__15140034', name: '咪咕网络榜', bangid: '15140034' }, { id: 'mg__23217754', name: 'MV榜', bangid: '23217754' }, { id: 'mg__23218151', name: '新专辑榜', bangid: '23218151' }, { id: 'mg__21958042', name: 'iTunes榜', bangid: '21958042' }, { id: 'mg__21975570', name: 'billboard榜', bangid: '21975570' }, { id: 'mg__22272815', name: '台湾Hito中文榜', bangid: '22272815' }, { id: 'mg__22272904', name: '中国TOP排行榜', bangid: '22272904' }, { id: 'mg__22272943', name: '韩国Melon榜', bangid: '22272943' }, { id: 'mg__22273437', name: '英国UK榜', bangid: '22273437' }]
|
||||
const boardList = [
|
||||
{ id: 'mg__27553319', name: '尖叫新歌榜', bangid: '27553319', webId: 'jianjiao_newsong' },
|
||||
{ id: 'mg__27186466', name: '尖叫热歌榜', bangid: '27186466', webId: 'jianjiao_hotsong' },
|
||||
{ id: 'mg__27553408', name: '尖叫原创榜', bangid: '27553408', webId: 'jianjiao_original' },
|
||||
{ id: 'mg__migumusic', name: '音乐榜', bangid: 'migumusic', webId: 'migumusic' },
|
||||
{ id: 'mg__movies', name: '影视榜', bangid: 'movies', webId: 'movies' },
|
||||
{ id: 'mg__23189800', name: '港台榜', bangid: '23189800', webId: 'hktw' },
|
||||
{ id: 'mg__23189399', name: '内地榜', bangid: '23189399', webId: 'mainland' },
|
||||
{ id: 'mg__19190036', name: '欧美榜', bangid: '19190036', webId: 'eur_usa' },
|
||||
{ id: 'mg__23189813', name: '日韩榜', bangid: '23189813', webId: 'jpn_kor' },
|
||||
{ id: 'mg__23190126', name: '彩铃榜', bangid: '23190126', webId: 'coloring' },
|
||||
{ id: 'mg__15140045', name: 'KTV榜', bangid: '15140045', webId: 'ktv' },
|
||||
{ id: 'mg__15140034', name: '网络榜', bangid: '15140034', webId: 'network' },
|
||||
{ id: 'mg__23217754', name: 'MV榜', bangid: '23217754', webId: 'mv' },
|
||||
{ id: 'mg__23218151', name: '新专辑榜', bangid: '23218151', webId: 'newalbum' },
|
||||
{ id: 'mg__21958042', name: '美国iTunes榜', bangid: '21958042', webId: 'itunes' },
|
||||
{ id: 'mg__21975570', name: '美国billboard榜', bangid: '21975570', webId: 'billboard' },
|
||||
{ id: 'mg__22272815', name: '台湾Hito中文榜', bangid: '22272815', webId: 'hito' },
|
||||
{ id: 'mg__22272904', name: '中国TOP排行榜', bangid: '22272904' },
|
||||
{ id: 'mg__22272943', name: '韩国Melon榜', bangid: '22272943', webId: 'mnet' },
|
||||
{ id: 'mg__22273437', name: '英国UK榜', bangid: '22273437', webId: 'uk' },
|
||||
]
|
||||
// const boardList = [
|
||||
// { id: 'mg__jianjiao_newsong', bangid: 'jianjiao_newsong', name: '尖叫新歌榜' },
|
||||
// { id: 'mg__jianjiao_hotsong', bangid: 'jianjiao_hotsong', name: '尖叫热歌榜' },
|
||||
// { id: 'mg__jianjiao_original', bangid: 'jianjiao_original', name: '尖叫原创榜' },
|
||||
// { id: 'mg__migumusic', bangid: 'migumusic', name: '音乐榜' },
|
||||
// { id: 'mg__movies', bangid: 'movies', name: '影视榜' },
|
||||
// { id: 'mg__mainland', bangid: 'mainland', name: '内地榜' },
|
||||
// { id: 'mg__hktw', bangid: 'hktw', name: '港台榜' },
|
||||
// { id: 'mg__eur_usa', bangid: 'eur_usa', name: '欧美榜' },
|
||||
// { id: 'mg__jpn_kor', bangid: 'jpn_kor', name: '日韩榜' },
|
||||
// { id: 'mg__coloring', bangid: 'coloring', name: '彩铃榜' },
|
||||
// { id: 'mg__ktv', bangid: 'ktv', name: 'KTV榜' },
|
||||
// { id: 'mg__network', bangid: 'network', name: '网络榜' },
|
||||
// { id: 'mg__newalbum', bangid: 'newalbum', name: '新专辑榜' },
|
||||
// { id: 'mg__mv', bangid: 'mv', name: 'MV榜' },
|
||||
// { id: 'mg__itunes', bangid: 'itunes', name: '美国iTunes榜' },
|
||||
// { id: 'mg__billboard', bangid: 'billboard', name: '美国billboard榜' },
|
||||
// { id: 'mg__hito', bangid: 'hito', name: 'Hito中文榜' },
|
||||
// { id: 'mg__mnet', bangid: 'mnet', name: '韩国Melon榜' },
|
||||
// { id: 'mg__uk', bangid: 'uk', name: '英国UK榜' },
|
||||
// ]
|
||||
|
||||
export default {
|
||||
limit: 10000,
|
||||
getUrl(id, page) {
|
||||
const targetBoard = boardList.find(board => board.bangid == id)
|
||||
return `https://music.migu.cn/v3/music/top/${targetBoard.webId}`
|
||||
// return `http://m.music.migu.cn/migu/remoting/cms_list_tag?nid=${id}&pageSize=${this.limit}&pageNo=${page - 1}`
|
||||
},
|
||||
successCode: '000000',
|
||||
requestBoardsObj: null,
|
||||
requestObj: null,
|
||||
regExps: {
|
||||
listData: /var listData = (\{.+\})<\/script>/,
|
||||
},
|
||||
getData(url) {
|
||||
if (this.requestObj) this.requestObj.cancelHttp()
|
||||
this.requestObj = httpFetch(url)
|
||||
return this.requestObj.promise
|
||||
},
|
||||
getSinger(singers) {
|
||||
let arr = []
|
||||
singers.forEach(singer => {
|
||||
arr.push(singer.name)
|
||||
})
|
||||
return arr.join('、')
|
||||
},
|
||||
getIntv(interval) {
|
||||
let intvArr = interval.split(':')
|
||||
let intv = 0
|
||||
let unit = 1
|
||||
while (intvArr.length) {
|
||||
intv += (intvArr.pop()) * unit
|
||||
unit *= 60
|
||||
}
|
||||
return parseInt(intv)
|
||||
},
|
||||
formateIntv() {
|
||||
|
||||
},
|
||||
filterData(rawData) {
|
||||
// console.log(JSON.stringify(rawData))
|
||||
// console.log(rawData)
|
||||
let ids = new Set()
|
||||
const list = []
|
||||
rawData.forEach(item => {
|
||||
if (ids.has(item.copyrightId)) return
|
||||
ids.add(item.copyrightId)
|
||||
|
||||
const types = []
|
||||
const _types = {}
|
||||
|
||||
const size = null
|
||||
types.push({ type: '128k', size })
|
||||
_types['128k'] = { size }
|
||||
|
||||
if (item.hq) {
|
||||
const size = null
|
||||
types.push({ type: '320k', size })
|
||||
_types['320k'] = { size }
|
||||
}
|
||||
if (item.sq) {
|
||||
const size = null
|
||||
types.push({ type: 'flac', size })
|
||||
_types.flac = { size }
|
||||
}
|
||||
|
||||
list.push({
|
||||
singer: this.getSinger(item.singers),
|
||||
name: item.name,
|
||||
albumName: item.album && item.album.albumName,
|
||||
albumId: item.album && item.album.albumId,
|
||||
songmid: item.copyrightId,
|
||||
songId: item.id,
|
||||
copyrightId: item.copyrightId,
|
||||
source: 'mg',
|
||||
interval: item.duration ? formatPlayTime(this.getIntv(item.duration)) : null,
|
||||
img: item.mediumPic ? `https:${item.mediumPic}` : null,
|
||||
lrc: null,
|
||||
// lrcUrl: item.lrcUrl,
|
||||
otherSource: null,
|
||||
types,
|
||||
_types,
|
||||
typeUrl: {},
|
||||
})
|
||||
})
|
||||
return list
|
||||
},
|
||||
filterBoardsData(rawList) {
|
||||
// console.log(rawList)
|
||||
let list = []
|
||||
for (const board of rawList) {
|
||||
if (board.template != 'group1') continue
|
||||
for (const item of board.itemList) {
|
||||
if ((item.template != 'row1' && item.template != 'grid1' && !item.actionUrl) || !item.actionUrl.includes('rank-info')) continue
|
||||
|
||||
let data = item.displayLogId.param
|
||||
list.push({
|
||||
id: 'mg__' + data.rankId,
|
||||
name: data.rankName,
|
||||
bangid: String(data.rankId),
|
||||
})
|
||||
}
|
||||
}
|
||||
return list
|
||||
},
|
||||
async getBoards(retryNum = 0) {
|
||||
// if (++retryNum > 3) return Promise.reject(new Error('try max num'))
|
||||
// let response
|
||||
// try {
|
||||
// response = await this.getBoardsData()
|
||||
// } catch (error) {
|
||||
// return this.getBoards(retryNum)
|
||||
// }
|
||||
// // console.log(response.body.data.contentItemList)
|
||||
// if (response.statusCode !== 200 || response.body.code !== this.successCode) return this.getBoards(retryNum)
|
||||
// const list = this.filterBoardsData(response.body.data.contentItemList)
|
||||
// // console.log(list)
|
||||
// // console.log(JSON.stringify(list))
|
||||
// this.list = list
|
||||
// return {
|
||||
// list,
|
||||
// source: 'mg',
|
||||
// }
|
||||
this.list = boardList
|
||||
return {
|
||||
list: boardList,
|
||||
source: 'mg',
|
||||
}
|
||||
},
|
||||
getList(bangid, page, retryNum = 0) {
|
||||
if (++retryNum > 3) return Promise.reject(new Error('try max num'))
|
||||
return this.getData(this.getUrl(bangid, page)).then(({ statusCode, body }) => {
|
||||
if (statusCode !== 200) return this.getList(bangid, page, retryNum)
|
||||
let listData = body.match(this.regExps.listData)
|
||||
if (!listData) return this.getList(bangid, page, retryNum)
|
||||
const datas = JSON.parse(RegExp.$1)
|
||||
// console.log(datas)
|
||||
listData = this.filterData(datas.songs.items)
|
||||
return {
|
||||
total: datas.songs.itemTotal,
|
||||
list: this.filterData(datas.songs.items),
|
||||
limit: this.limit,
|
||||
page,
|
||||
source: 'mg',
|
||||
}
|
||||
})
|
||||
},
|
||||
}
|
File diff suppressed because one or more lines are too long
|
@ -1,4 +1,4 @@
|
|||
import { httpGet, cancelHttp, httpFetch } from '../../request'
|
||||
import { httpFetch } from '../../request'
|
||||
import { formatPlayTime, sizeFormate } from '../../index'
|
||||
|
||||
let boardList = [{ id: 'tx__4', name: '流行指数榜', bangid: '4' }, { id: 'tx__26', name: '热歌榜', bangid: '26' }, { id: 'tx__27', name: '新歌榜', bangid: '27' }, { id: 'tx__62', name: '飙升榜', bangid: '62' }, { id: 'tx__58', name: '说唱榜', bangid: '58' }, { id: 'tx__57', name: '电音榜', bangid: '57' }, { id: 'tx__28', name: '网络歌曲榜', bangid: '28' }, { id: 'tx__5', name: '内地榜', bangid: '5' }, { id: 'tx__3', name: '欧美榜', bangid: '3' }, { id: 'tx__59', name: '香港地区榜', bangid: '59' }, { id: 'tx__16', name: '韩国榜', bangid: '16' }, { id: 'tx__60', name: '抖音排行榜', bangid: '60' }, { id: 'tx__29', name: '影视金曲榜', bangid: '29' }, { id: 'tx__17', name: '日本榜', bangid: '17' }, { id: 'tx__52', name: '腾讯音乐人原创榜', bangid: '52' }, { id: 'tx__36', name: 'K歌金曲榜', bangid: '36' }, { id: 'tx__61', name: '台湾地区榜', bangid: '61' }, { id: 'tx__63', name: 'DJ舞曲榜', bangid: '63' }, { id: 'tx__64', name: '综艺新歌榜', bangid: '64' }, { id: 'tx__65', name: '国风热歌榜', bangid: '65' }, { id: 'tx__66', name: 'ACG新歌榜', bangid: '66' }, { id: 'tx__67', name: '听歌识曲榜', bangid: '67' }, { id: 'tx__70', name: '达人音乐榜', bangid: '70' }]
|
||||
|
@ -86,30 +86,16 @@ export default {
|
|||
periods: {},
|
||||
periodUrl: 'https://c.y.qq.com/node/pc/wk_v15/top.html',
|
||||
_requestBoardsObj: null,
|
||||
_cancelRequestObj: null,
|
||||
_cancelPromiseCancelFn: null,
|
||||
_requestDataObj: null,
|
||||
getBoardsData() {
|
||||
if (this._requestBoardsObj) this._requestBoardsObj.cancelHttp()
|
||||
this._requestBoardsObj = httpFetch('https://c.y.qq.com/v8/fcg-bin/fcg_myqq_toplist.fcg?g_tk=1928093487&inCharset=utf-8&outCharset=utf-8¬ice=0&format=json&uin=0&needNewCode=1&platform=h5')
|
||||
return this._requestBoardsObj.promise
|
||||
},
|
||||
getData(url) {
|
||||
if (this._cancelRequestObj != null) {
|
||||
cancelHttp(this._cancelRequestObj)
|
||||
this._cancelPromiseCancelFn(new Error('取消http请求'))
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
this._cancelPromiseCancelFn = reject
|
||||
this._cancelRequestObj = httpGet(url, (err, resp, body) => {
|
||||
this._cancelRequestObj = null
|
||||
this._cancelPromiseCancelFn = null
|
||||
if (err) {
|
||||
console.log(err)
|
||||
reject(err)
|
||||
}
|
||||
resolve(body)
|
||||
})
|
||||
})
|
||||
if (this._requestDataObj) this._requestDataObj.cancelHttp()
|
||||
this._requestDataObj = httpFetch(url)
|
||||
return this._requestDataObj.promise
|
||||
},
|
||||
getSinger(singers) {
|
||||
let arr = []
|
||||
|
@ -175,9 +161,9 @@ export default {
|
|||
})
|
||||
},
|
||||
getPeriods(bangid) {
|
||||
return this.getData(this.periodUrl).then(html => {
|
||||
return this.getData(this.periodUrl).then(({ body: html }) => {
|
||||
let result = html.match(this.regExps.periodList)
|
||||
if (!result) return Promise.reject()
|
||||
if (!result) return Promise.reject(new Error('get data failed'))
|
||||
result.forEach(item => {
|
||||
let result = item.match(this.regExps.period)
|
||||
if (!result) return
|
||||
|
@ -239,12 +225,11 @@ export default {
|
|||
let info = this.periods[bangid]
|
||||
let p = info ? Promise.resolve(info.period) : this.getPeriods(bangid)
|
||||
return p.then(period => {
|
||||
return this.getData(this.getUrl(bangid, period, this.limit)).then(data => {
|
||||
// console.log(data)
|
||||
if (data.code !== 0) return this.getList(bangid, page, retryNum)
|
||||
return this.getData(this.getUrl(bangid, period, this.limit)).then(resp => {
|
||||
if (resp.body.code !== 0) return this.getList(bangid, page, retryNum)
|
||||
return {
|
||||
total: data.toplist.data.songInfoList.length,
|
||||
list: this.filterData(data.toplist.data.songInfoList),
|
||||
total: resp.body.toplist.data.songInfoList.length,
|
||||
list: this.filterData(resp.body.toplist.data.songInfoList),
|
||||
limit: this.limit,
|
||||
page: 1,
|
||||
source: 'tx',
|
||||
|
|
|
@ -13,7 +13,7 @@ export default {
|
|||
return arr.join('、')
|
||||
},
|
||||
filterList({ songs, privileges }) {
|
||||
// console.log(tracks, privileges)
|
||||
// console.log(songs, privileges)
|
||||
const list = []
|
||||
songs.forEach((item, index) => {
|
||||
const types = []
|
||||
|
@ -38,6 +38,7 @@ export default {
|
|||
size,
|
||||
}
|
||||
}
|
||||
case 192000:
|
||||
case 128000:
|
||||
if (item.l) {
|
||||
size = sizeFormate(item.l.size)
|
||||
|
|
|
@ -24,8 +24,9 @@ export default {
|
|||
offset: limit * (page - 1),
|
||||
}),
|
||||
})
|
||||
return searchRequest.promise.then(({ body }) =>
|
||||
body && body.code === 200
|
||||
return searchRequest.promise.then(({ body }) => {
|
||||
// console.log(body)
|
||||
return body && body.code === 200
|
||||
? musicDetailApi.getList(body.result.songs.map(s => s.id)).then(({ list }) => {
|
||||
this.total = body.result.songCount || 0
|
||||
this.page = page
|
||||
|
@ -41,7 +42,8 @@ export default {
|
|||
},
|
||||
}
|
||||
})
|
||||
: body)
|
||||
: body
|
||||
})
|
||||
},
|
||||
getSinger(singers) {
|
||||
let arr = []
|
||||
|
|
|
@ -139,6 +139,7 @@ export default {
|
|||
size,
|
||||
}
|
||||
}
|
||||
case 192000:
|
||||
case 128000:
|
||||
if (item.l) {
|
||||
size = sizeFormate(item.l.size)
|
||||
|
|
|
@ -109,7 +109,7 @@ export const httpFetch = (url, options = { method: 'get' }) => {
|
|||
export const cancelHttp = requestObj => {
|
||||
// console.log(requestObj)
|
||||
if (!requestObj) return
|
||||
console.log('cancel:', requestObj)
|
||||
// console.log('cancel:', requestObj)
|
||||
if (!requestObj.abort) return
|
||||
requestObj.abort()
|
||||
}
|
||||
|
|
|
@ -11,14 +11,17 @@
|
|||
svg(version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' height='70%' viewBox='0 0 24 24' space='preserve')
|
||||
use(xlink:href='#icon-list-add')
|
||||
ul.scroll(:class="$style.listsContent" ref="dom_lists_list")
|
||||
li(:class="[$style.listsItem, item.id == tabId ? $style.active : null]" :tips="item.name" v-for="item in boardList" :key="item.id" @click="handleToggleList(item.id)")
|
||||
li(:class="[$style.listsItem, item.id == tabId ? $style.active : null, { [$style.clicked]: boardListData.rightClickItemIndex == index }]"
|
||||
:tips="item.name" v-for="(item, index) in boardList" :key="item.id" @click="handleToggleList(item.id)"
|
||||
@contextmenu="handleListsItemRigthClick($event, index)")
|
||||
span(:class="$style.listsLabel") {{item.name}}
|
||||
div(:class="$style.list")
|
||||
material-song-list(v-model="selectedData" :rowWidth="{r1: '5%', r2: 'auto', r3: '22%', r4: '22%', r5: '9%', r6: '15%'}" @action="handleSongListAction" :source="source" :page="page" :limit="info.limit" :total="info.total" :noItem="$t('material.song_list.loding_list')" :list="list")
|
||||
material-song-list(v-model="selectedData" ref="songList" :hideListsMenu="hideListsMenu" :rowWidth="{r1: '5%', r2: 'auto', r3: '22%', r4: '22%', r5: '9%', r6: '15%'}" @action="handleSongListAction" :source="source" :page="page" :limit="info.limit" :total="info.total" :noItem="$t('material.song_list.loding_list')" :list="list")
|
||||
material-download-modal(:show="isShowDownload" :musicInfo="musicInfo" @select="handleAddDownload" @close="isShowDownload = false")
|
||||
material-download-multiple-modal(:show="isShowDownloadMultiple" :list="selectedData" @select="handleAddDownloadMultiple" @close="isShowDownloadMultiple = false")
|
||||
material-list-add-modal(:show="isShowListAdd" :musicInfo="musicInfo" @close="isShowListAdd = false")
|
||||
material-list-add-multiple-modal(:show="isShowListAddMultiple" :musicList="selectedData" @close="handleListAddModalClose")
|
||||
material-menu(:menus="listsItemMenu" :location="boardListData.menuLocation" item-name="name" :isShow="boardListData.isShowItemMenu" @menu-click="handleListsItemMenuClick")
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -38,6 +41,21 @@ export default {
|
|||
isShowDownloadMultiple: false,
|
||||
isShowListAdd: false,
|
||||
isShowListAddMultiple: false,
|
||||
boardListData: {
|
||||
isShowItemMenu: false,
|
||||
itemMenuControl: {
|
||||
rename: true,
|
||||
sync: false,
|
||||
moveup: true,
|
||||
movedown: true,
|
||||
remove: true,
|
||||
},
|
||||
rightClickItemIndex: -1,
|
||||
menuLocation: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
@ -47,6 +65,20 @@ export default {
|
|||
boardList() {
|
||||
return this.source && this.boards[this.source] ? this.boards[this.source] : []
|
||||
},
|
||||
listsItemMenu() {
|
||||
return [
|
||||
{
|
||||
name: this.$t('view.leaderboard.play'),
|
||||
action: 'play',
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
name: this.$t('view.leaderboard.collect'),
|
||||
action: 'collect',
|
||||
disabled: false,
|
||||
},
|
||||
]
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
tabId(n, o) {
|
||||
|
@ -74,9 +106,9 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
...mapMutations(['setLeaderboard']),
|
||||
...mapActions('leaderboard', ['getBoardsList', 'getList']),
|
||||
...mapActions('leaderboard', ['getBoardsList', 'getList', 'getListAll']),
|
||||
...mapActions('download', ['createDownload', 'createDownloadMultiple']),
|
||||
...mapMutations('list', ['listAdd', 'listAddMultiple']),
|
||||
...mapMutations('list', ['listAdd', 'listAddMultiple', 'createUserList']),
|
||||
...mapMutations('player', ['setList', 'setTempPlayList']),
|
||||
handleListBtnClick(info) {
|
||||
switch (info.action) {
|
||||
|
@ -228,6 +260,55 @@ export default {
|
|||
resetSelect() {
|
||||
this.selectedData = []
|
||||
},
|
||||
handleListsItemRigthClick(event, index) {
|
||||
// const board = this.boardList[index]
|
||||
// this.boardListData.itemMenuControl.sync = !!source && !!musicSdk[source].songList
|
||||
// this.boardListData.itemMenuControl.moveup = index > 0
|
||||
// this.boardListData.itemMenuControl.movedown = index < this.userList.length - 1
|
||||
this.boardListData.rightClickItemIndex = index
|
||||
this.boardListData.menuLocation.x = event.currentTarget.offsetLeft + event.offsetX
|
||||
this.boardListData.menuLocation.y = event.currentTarget.offsetTop + event.offsetY - this.$refs.dom_lists_list.scrollTop
|
||||
// this.hideListsMenu()
|
||||
this.$refs.songList.hideListMenu()
|
||||
this.$nextTick(() => {
|
||||
this.boardListData.isShowItemMenu = true
|
||||
})
|
||||
},
|
||||
hideListsMenu() {
|
||||
this.boardListData.isShowItemMenu = false
|
||||
this.boardListData.rightClickItemIndex = -1
|
||||
},
|
||||
async handleListsItemMenuClick(action) {
|
||||
let index = this.boardListData.rightClickItemIndex
|
||||
this.hideListsMenu()
|
||||
this.boardListData.isShowItemMenu = false
|
||||
|
||||
if (action) {
|
||||
const board = this.boardList[index]
|
||||
const list = await this.getListAll(board.id)
|
||||
if (!list.length) return
|
||||
switch (action && action.action) {
|
||||
case 'play':
|
||||
this.setList({
|
||||
list: {
|
||||
list,
|
||||
id: null,
|
||||
},
|
||||
index: 0,
|
||||
})
|
||||
break
|
||||
case 'collect':
|
||||
this.createUserList({
|
||||
name: board.name,
|
||||
id: `board__${this.source}__${board.id}`,
|
||||
list,
|
||||
source: this.source,
|
||||
sourceListId: `board__${board.id}`,
|
||||
})
|
||||
break
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -358,6 +358,9 @@ export default {
|
|||
'sortList',
|
||||
]),
|
||||
...mapActions('songList', ['getListDetailAll']),
|
||||
...mapActions('leaderboard', {
|
||||
getBoardListAll: 'getListAll',
|
||||
}),
|
||||
...mapActions('download', ['createDownload', 'createDownloadMultiple']),
|
||||
...mapMutations('player', {
|
||||
setPlayList: 'setList',
|
||||
|
@ -902,7 +905,15 @@ export default {
|
|||
} else {
|
||||
this.fetchingListStatus[id] = true
|
||||
}
|
||||
return this.getListDetailAll({ source, id: sourceListId }).finally(() => {
|
||||
|
||||
let promise
|
||||
if (/board__/.test(sourceListId)) {
|
||||
const id = sourceListId.replace(/board__/, '')
|
||||
promise = this.getBoardListAll(id)
|
||||
} else {
|
||||
promise = this.getListDetailAll({ source, id: sourceListId })
|
||||
}
|
||||
return promise.finally(() => {
|
||||
this.fetchingListStatus[id] = false
|
||||
})
|
||||
},
|
||||
|
|
|
@ -237,7 +237,7 @@ div(:class="$style.main")
|
|||
span.hover.underline(:tips="$t('view.setting.click_open')" @click="handleOpenUrl('https://github.com/lyswhut/lx-music-desktop#readme')") https://github.com/lyswhut/lx-music-desktop
|
||||
p.small
|
||||
| 最新版网盘下载地址(网盘内有Windows、MAC版):
|
||||
span.hover.underline(:tips="$t('view.setting.click_open')" @click="handleOpenUrl('https://www.lanzous.com/b0bf2cfa/')") 网盘地址
|
||||
span.hover.underline(:tips="$t('view.setting.click_open')" @click="handleOpenUrl('https://www.lanzoui.com/b0bf2cfa/')") 网盘地址
|
||||
| 密码:
|
||||
span.hover(:tips="$t('view.setting.click_copy')" @click="clipboardWriteText('glqw')") glqw
|
||||
p.small
|
||||
|
@ -255,7 +255,6 @@ div(:class="$style.main")
|
|||
span.hover.underline(:tips="$t('view.setting.click_open')" @click="handleOpenUrl('https://github.com/lyswhut/lx-music-desktop/issues')") issue
|
||||
|
||||
br
|
||||
p.small 感谢以前捐赠过的人❤️,现在软件不再接受捐赠,建议把你们的爱心用来支持正版音乐,
|
||||
p.small 由于软件开发的初衷仅是为了对新技术的学习与研究,因此软件直至停止维护都将会一直保持纯净。
|
||||
|
||||
p.small
|
||||
|
@ -983,7 +982,12 @@ export default {
|
|||
await rendererInvoke(NAMES.hotKey.enable, true)
|
||||
window.isEditingHotKey = false
|
||||
this.isEditHotKey = false
|
||||
const prevInput = hotKeyTargetInput
|
||||
hotKeyTargetInput = null
|
||||
if (prevInput.value == this.$t('view.setting.hot_key_tip_input')) {
|
||||
prevInput.value = newHotKey ? this.formatHotKeyName(newHotKey) : ''
|
||||
return
|
||||
}
|
||||
let config = this.hotKeyConfig[type][info.name]
|
||||
let originKey
|
||||
if (newHotKey) {
|
||||
|
|
Loading…
Reference in New Issue