mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/lyswhut/lx-music-desktop.git
synced 2026-09-20 08:04:00 +08:00
Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d575dd24ca | ||
|
|
e47586cea3 | ||
|
|
1ce63c7550 | ||
|
|
36d69da3b7 | ||
|
|
529be08420 | ||
|
|
ffe11c7015 | ||
|
|
76b796bde7 | ||
|
|
f81715f07f | ||
|
|
ec3f667b75 | ||
|
|
87f0b4fd17 | ||
|
|
c7e95c5166 | ||
|
|
6ea0837cce | ||
|
|
59627e048f | ||
|
|
45fea5726b | ||
|
|
e539f29f6d | ||
|
|
1d2810e98f | ||
|
|
1cbafc9750 | ||
|
|
e675f7ac06 | ||
|
|
9dc9d3b1b7 | ||
|
|
a104ce688e | ||
|
|
2dd1ceb0b9 | ||
|
|
9379328d96 | ||
|
|
d8969c327c | ||
|
|
c3624fb7d6 | ||
|
|
b2de230100 |
23
CHANGELOG.md
23
CHANGELOG.md
@@ -6,6 +6,29 @@ 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/).
|
||||
|
||||
## [0.8.0](https://github.com/lyswhut/lx-music-desktop/compare/v0.7.0...v0.8.0) - 2019-10-19
|
||||
|
||||
#### 新增
|
||||
|
||||
- 新增网易云源歌曲搜索
|
||||
- 新增网易云源歌单
|
||||
- 新增各平台通过输入歌单链接或歌单ID打开歌单详情列表,目前只适配了**网页版歌单链接**,其他方式的歌单链接可能无法解析,但你可想办法获取歌单ID后输入打开。注:各平台歌单ID均为纯数字,若遇到链接里存在歌单ID但无法解析的歌单链接,可以到GitHub提交issue或发送邮件或加群830125506反馈!
|
||||
- 新增音量调整滑动功能,现在支持鼠标左右拖动调整音量了
|
||||
|
||||
#### 优化
|
||||
|
||||
- 优化搜索框搜索体验
|
||||
- 优化音量条交互视觉效果
|
||||
- 缓存歌单详情列表数据
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复QQ源歌单无法翻页Bug
|
||||
- 修复默认列表没有创建时无法显示收藏列表的Bug
|
||||
- 修复网易云128k直接试听
|
||||
- 修复歌曲音质不存在时仍然播放或下载的Bug
|
||||
- 修复调整音量时,调整的位置与鼠标点击的位置不一致的问题
|
||||
|
||||
## [0.7.0](https://github.com/lyswhut/lx-music-desktop/compare/v0.6.2...v0.7.0) - 2019-10-07
|
||||
|
||||
#### 新增
|
||||
|
||||
60
FAQ.md
Normal file
60
FAQ.md
Normal file
@@ -0,0 +1,60 @@
|
||||
# lx-music-desktop 常见问题
|
||||
|
||||
在阅读本常见问题后,仍然无法解决你的问题,请提交issue或者加企鹅群`830125506`反馈,反馈时请**注明**已阅读常见问题!
|
||||
|
||||
## 软件为什么没有桌面歌词与自定义列表功能
|
||||
|
||||
洛雪音乐的最初定位不是作为播放器开发的,它主要用于**查找歌曲**,软件的播放功能仅用于试听,不建议用作为常用播放器使用,因此无桌面、界面歌词,不可自定义列表。
|
||||
|
||||
## 歌曲无法试听与下载
|
||||
|
||||
该问题解决顺序如下:
|
||||
|
||||
1. 尝试更新到最新版本
|
||||
2. 尝试切换其他歌曲(或直接搜索该歌曲),若全部歌曲都无法试听与下载则进行下一步
|
||||
3. 尝试到设置-接口来源切换到其他接口
|
||||
4. 尝试切换网络,比如用手机开热点(目前存在某些网络无法访问接口服务器的情况)
|
||||
5. 若还不行请到这个链接查看详情:<https://github.com/lyswhut/lx-music-desktop/issues/5>
|
||||
6. 若没有在第5条链接中的第一条评论中看到接口无法使用的说明,则应该是你网络无法访问接口服务器的问题,如果接口有问题我会在那里说明。
|
||||
|
||||
想要知道是不是自己网络的问题可以看看`https://ts.tempmusic.tk`能不能在浏览器打开,浏览器显示404是正常的,如果不是404那就证明所在网络无法访问接口服务器。
|
||||
若网页无法打开或打来不是404,则应该是DNS的问题,可以尝试以下办法:
|
||||
|
||||
1. 改成自动获取试试
|
||||
2. 手动把DNS改一下,不要用360的DNS,可以把DNS改成`114.114.114.114`、`8.8.8.8`
|
||||
3. 软件设置里面的代理不要勾起来
|
||||
|
||||
## 软件安装包说明
|
||||
|
||||
软件发布页及网盘中有多个类型的安装文件,以下是对这些类型文件的说明:
|
||||
|
||||
文件名带 `win_` 的是在Windows系统上运行的版本,<br>
|
||||
其中安装版(Setup)可自动更新软件,<br>
|
||||
绿色版(green)为免安装版,自动更新功能不可用;
|
||||
|
||||
以 **`.dmg`** 结尾的文件为 MAC 版本;
|
||||
|
||||
以 **`.AppImage`**、**`.deb`** 结尾的为 Linux 版本。
|
||||
|
||||
带有`x64`的为64位的系统版本,带`x86`的为32位的系统版本;若两个都带有的则为集合版,安装时会自动根据系统位数选择对应的版本安装。
|
||||
|
||||
## 软件更新
|
||||
|
||||
软件启动时若发现新版本时会自动从本仓库下载安装包,下载完毕会弹窗提示更新。<br>
|
||||
若下载未完成时软件被关闭,下次启动软件会再次自动下载。<br>
|
||||
若还是**更新失败**,可能是无法访问GitHub导致的,这时需要手动更新,即下载最新安装包直接覆盖安装即可。<br>
|
||||
注意:**绿色版**的软件自动更新功能**不可用**,建议使用安装版!!<br>
|
||||
注意:**Mac版**、**Linux deb**版不支持自动更新!
|
||||
|
||||
## Windows 7 下界面异常
|
||||
|
||||
当 win7 没有开启**透明效果**时界面将会显示异常,开启方法请自行百度。<br>
|
||||
对于一些开启透明效果后仍然无法正常显示界面的系统,我也不知道是什么原因导致的,只能说正常的系统是没有这个问题的,如果你知道原因导致的欢迎反馈!
|
||||
|
||||
## 安装版安装失败,提示应用未安装
|
||||
|
||||
对于部分电脑出现安装失败的问题我也不懂什么原因,,可以尝试清理下安装文件,或者重启电脑试试。
|
||||
|
||||
## 缺少`xxx.dll`
|
||||
|
||||
这个是电脑缺少某些dll导致的,正常的系统是没有这个问题的,解决办法需自行百度弹出的错误信息看下别人是怎么解决的。
|
||||
50
README.md
50
README.md
@@ -49,11 +49,6 @@
|
||||
或者到网盘下载(网盘内有MAC、windows版):`https://www.lanzous.com/b906260/` 密码:`glqw`<br>
|
||||
使用常见问题请转至:[常见问题](https://github.com/lyswhut/lx-music-desktop#常见问题)
|
||||
|
||||
#### TODO
|
||||
|
||||
- [ ] 新增拉取各大平台歌单
|
||||
- [ ] 新增聚合搜索
|
||||
|
||||
### 源码使用方法
|
||||
|
||||
环境要求:Node.js 12.x
|
||||
@@ -76,50 +71,7 @@ npm run pack
|
||||
|
||||
### 常见问题
|
||||
|
||||
#### 歌曲无法试听与下载
|
||||
|
||||
该问题解决顺序如下:
|
||||
|
||||
1. 尝试更新到最新版本
|
||||
2. 尝试切换其他歌曲(或直接搜索该歌曲),若全部歌曲都无法试听与下载则进行下一步
|
||||
3. 尝试到设置-接口来源切换到其他接口
|
||||
4. 尝试切换网络,比如用手机开热点(目前存在某些网络无法访问接口服务器的情况)
|
||||
5. 若还不行请到这个链接查看详情:<https://github.com/lyswhut/lx-music-desktop/issues/5>
|
||||
6. 若没有在第5条链接中的第一条评论中看到接口无法使用的说明,则应该是你网络无法访问接口服务器的问题,如果接口有问题我会在那里说明。
|
||||
|
||||
#### 软件安装包说明
|
||||
|
||||
软件发布页及网盘中有多个类型的安装文件,以下是对这些类型文件的说明:
|
||||
|
||||
文件名带 `win_` 的是在Windows系统上运行的版本,<br>
|
||||
其中安装版(Setup)可自动更新软件,<br>
|
||||
绿色版(green)为免安装版,自动更新功能不可用;
|
||||
|
||||
以 **`.dmg`** 结尾的文件为 MAC 版本;
|
||||
|
||||
以 **`.AppImage`**、**`.deb`** 结尾的为 Linux 版本。
|
||||
|
||||
带有`x64`的为64位的系统版本,带`x86`的为32位的系统版本;若两个都带有的则为集合版,安装时会自动根据系统位数选择对应的版本安装。
|
||||
|
||||
#### 软件更新
|
||||
|
||||
软件启动时若发现新版本时会自动从本仓库下载安装包,下载完毕会弹窗提示更新。<br>
|
||||
若下载未完成时软件被关闭,下次启动软件会再次自动下载。<br>
|
||||
若还是**更新失败**,可能是无法访问GitHub导致的,这时需要手动更新,即下载最新安装包直接覆盖安装即可。<br>
|
||||
注意:**绿色版**的软件自动更新功能**不可用**,建议使用安装版!!<br>
|
||||
注意:**Mac版**、**Linux deb**版不支持自动更新!
|
||||
|
||||
#### Windows 7 下界面异常
|
||||
|
||||
当 win7 没有开启**透明效果**时界面将会显示异常,开启方法请自行百度。
|
||||
|
||||
#### 安装版安装失败,提示应用未安装
|
||||
|
||||
对于部分电脑出现安装失败的问题我也不懂什么原因,,可以尝试清理下安装文件,或者重启电脑试试。
|
||||
|
||||
#### 缺少`xxx.dll`
|
||||
|
||||
这个是电脑缺少某些dll导致的,正常的系统是没有这个问题的,解决办法需自行百度弹出的错误信息看下别人是怎么解决的。
|
||||
常见问题已移至:<https://github.com/lyswhut/lx-music-desktop/blob/master/FAQ.md>
|
||||
|
||||
### 致谢
|
||||
|
||||
|
||||
253
package-lock.json
generated
253
package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "lx-music-desktop",
|
||||
"version": "0.6.2",
|
||||
"version": "0.7.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@@ -26,18 +26,18 @@
|
||||
}
|
||||
},
|
||||
"@babel/core": {
|
||||
"version": "7.6.2",
|
||||
"resolved": "https://registry.npm.taobao.org/@babel/core/download/@babel/core-7.6.2.tgz",
|
||||
"integrity": "sha1-Bpp3bo1enu//diNryIRVZr0x3ZE=",
|
||||
"version": "7.6.4",
|
||||
"resolved": "https://registry.npm.taobao.org/@babel/core/download/@babel/core-7.6.4.tgz",
|
||||
"integrity": "sha1-br2f4Akl9sPhd7tyahiLX1eAiP8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/code-frame": "^7.5.5",
|
||||
"@babel/generator": "^7.6.2",
|
||||
"@babel/generator": "^7.6.4",
|
||||
"@babel/helpers": "^7.6.2",
|
||||
"@babel/parser": "^7.6.2",
|
||||
"@babel/parser": "^7.6.4",
|
||||
"@babel/template": "^7.6.0",
|
||||
"@babel/traverse": "^7.6.2",
|
||||
"@babel/types": "^7.6.0",
|
||||
"@babel/traverse": "^7.6.3",
|
||||
"@babel/types": "^7.6.3",
|
||||
"convert-source-map": "^1.1.0",
|
||||
"debug": "^4.1.0",
|
||||
"json5": "^2.1.0",
|
||||
@@ -57,40 +57,51 @@
|
||||
}
|
||||
},
|
||||
"@babel/generator": {
|
||||
"version": "7.6.2",
|
||||
"resolved": "https://registry.npm.taobao.org/@babel/generator/download/@babel/generator-7.6.2.tgz",
|
||||
"integrity": "sha1-2sijwt8RgzTCop/zRG2hY2qPjAM=",
|
||||
"version": "7.6.4",
|
||||
"resolved": "https://registry.npm.taobao.org/@babel/generator/download/@babel/generator-7.6.4.tgz?cache=0&sync_timestamp=1570717897603&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fgenerator%2Fdownload%2F%40babel%2Fgenerator-7.6.4.tgz",
|
||||
"integrity": "sha1-pPhDcoe/lnGwf0g7duO7cxvJdnE=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/types": "^7.6.0",
|
||||
"@babel/types": "^7.6.3",
|
||||
"jsesc": "^2.5.1",
|
||||
"lodash": "^4.17.13",
|
||||
"source-map": "^0.5.0"
|
||||
}
|
||||
},
|
||||
"@babel/parser": {
|
||||
"version": "7.6.2",
|
||||
"resolved": "https://registry.npm.taobao.org/@babel/parser/download/@babel/parser-7.6.2.tgz?cache=0&sync_timestamp=1569286082477&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fparser%2Fdownload%2F%40babel%2Fparser-7.6.2.tgz",
|
||||
"integrity": "sha1-IF6cleFro7i5YJBnemfJ1gdbcKE=",
|
||||
"version": "7.6.4",
|
||||
"resolved": "https://registry.npm.taobao.org/@babel/parser/download/@babel/parser-7.6.4.tgz?cache=0&sync_timestamp=1570718702664&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fparser%2Fdownload%2F%40babel%2Fparser-7.6.4.tgz",
|
||||
"integrity": "sha1-y5s2p0ghECgtXLbdQk7JJitHPYE=",
|
||||
"dev": true
|
||||
},
|
||||
"@babel/traverse": {
|
||||
"version": "7.6.2",
|
||||
"resolved": "https://registry.npm.taobao.org/@babel/traverse/download/@babel/traverse-7.6.2.tgz",
|
||||
"integrity": "sha1-sOK/1AHTOc4ObAVpAgbR4RUCziw=",
|
||||
"version": "7.6.3",
|
||||
"resolved": "https://registry.npm.taobao.org/@babel/traverse/download/@babel/traverse-7.6.3.tgz",
|
||||
"integrity": "sha1-ZtfboUawhnA8D7EN1Yi3NkzsR/k=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/code-frame": "^7.5.5",
|
||||
"@babel/generator": "^7.6.2",
|
||||
"@babel/generator": "^7.6.3",
|
||||
"@babel/helper-function-name": "^7.1.0",
|
||||
"@babel/helper-split-export-declaration": "^7.4.4",
|
||||
"@babel/parser": "^7.6.2",
|
||||
"@babel/types": "^7.6.0",
|
||||
"@babel/parser": "^7.6.3",
|
||||
"@babel/types": "^7.6.3",
|
||||
"debug": "^4.1.0",
|
||||
"globals": "^11.1.0",
|
||||
"lodash": "^4.17.13"
|
||||
}
|
||||
},
|
||||
"@babel/types": {
|
||||
"version": "7.6.3",
|
||||
"resolved": "https://registry.npm.taobao.org/@babel/types/download/@babel/types-7.6.3.tgz",
|
||||
"integrity": "sha1-PwfZb4VPmOL71FxksMuULRHougk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"esutils": "^2.0.2",
|
||||
"lodash": "^4.17.13",
|
||||
"to-fast-properties": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npm.taobao.org/debug/download/debug-4.1.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-4.1.1.tgz",
|
||||
@@ -101,9 +112,9 @@
|
||||
}
|
||||
},
|
||||
"json5": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npm.taobao.org/json5/download/json5-2.1.0.tgz",
|
||||
"integrity": "sha1-56DGLEgoXGKNIKELhcibuAfDKFA=",
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npm.taobao.org/json5/download/json5-2.1.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjson5%2Fdownload%2Fjson5-2.1.1.tgz",
|
||||
"integrity": "sha1-gbbLBOm6SW8ccAXQe0NoomOPkLY=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"minimist": "^1.2.0"
|
||||
@@ -357,38 +368,64 @@
|
||||
}
|
||||
},
|
||||
"@babel/generator": {
|
||||
"version": "7.6.2",
|
||||
"resolved": "https://registry.npm.taobao.org/@babel/generator/download/@babel/generator-7.6.2.tgz",
|
||||
"integrity": "sha1-2sijwt8RgzTCop/zRG2hY2qPjAM=",
|
||||
"version": "7.6.4",
|
||||
"resolved": "https://registry.npm.taobao.org/@babel/generator/download/@babel/generator-7.6.4.tgz?cache=0&sync_timestamp=1570717897603&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fgenerator%2Fdownload%2F%40babel%2Fgenerator-7.6.4.tgz",
|
||||
"integrity": "sha1-pPhDcoe/lnGwf0g7duO7cxvJdnE=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/types": "^7.6.0",
|
||||
"@babel/types": "^7.6.3",
|
||||
"jsesc": "^2.5.1",
|
||||
"lodash": "^4.17.13",
|
||||
"source-map": "^0.5.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/types": {
|
||||
"version": "7.6.3",
|
||||
"resolved": "https://registry.npm.taobao.org/@babel/types/download/@babel/types-7.6.3.tgz",
|
||||
"integrity": "sha1-PwfZb4VPmOL71FxksMuULRHougk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"esutils": "^2.0.2",
|
||||
"lodash": "^4.17.13",
|
||||
"to-fast-properties": "^2.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@babel/parser": {
|
||||
"version": "7.6.2",
|
||||
"resolved": "https://registry.npm.taobao.org/@babel/parser/download/@babel/parser-7.6.2.tgz?cache=0&sync_timestamp=1569286082477&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fparser%2Fdownload%2F%40babel%2Fparser-7.6.2.tgz",
|
||||
"integrity": "sha1-IF6cleFro7i5YJBnemfJ1gdbcKE=",
|
||||
"version": "7.6.4",
|
||||
"resolved": "https://registry.npm.taobao.org/@babel/parser/download/@babel/parser-7.6.4.tgz?cache=0&sync_timestamp=1570718702664&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fparser%2Fdownload%2F%40babel%2Fparser-7.6.4.tgz",
|
||||
"integrity": "sha1-y5s2p0ghECgtXLbdQk7JJitHPYE=",
|
||||
"dev": true
|
||||
},
|
||||
"@babel/traverse": {
|
||||
"version": "7.6.2",
|
||||
"resolved": "https://registry.npm.taobao.org/@babel/traverse/download/@babel/traverse-7.6.2.tgz",
|
||||
"integrity": "sha1-sOK/1AHTOc4ObAVpAgbR4RUCziw=",
|
||||
"version": "7.6.3",
|
||||
"resolved": "https://registry.npm.taobao.org/@babel/traverse/download/@babel/traverse-7.6.3.tgz",
|
||||
"integrity": "sha1-ZtfboUawhnA8D7EN1Yi3NkzsR/k=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/code-frame": "^7.5.5",
|
||||
"@babel/generator": "^7.6.2",
|
||||
"@babel/generator": "^7.6.3",
|
||||
"@babel/helper-function-name": "^7.1.0",
|
||||
"@babel/helper-split-export-declaration": "^7.4.4",
|
||||
"@babel/parser": "^7.6.2",
|
||||
"@babel/types": "^7.6.0",
|
||||
"@babel/parser": "^7.6.3",
|
||||
"@babel/types": "^7.6.3",
|
||||
"debug": "^4.1.0",
|
||||
"globals": "^11.1.0",
|
||||
"lodash": "^4.17.13"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/types": {
|
||||
"version": "7.6.3",
|
||||
"resolved": "https://registry.npm.taobao.org/@babel/types/download/@babel/types-7.6.3.tgz",
|
||||
"integrity": "sha1-PwfZb4VPmOL71FxksMuULRHougk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"esutils": "^2.0.2",
|
||||
"lodash": "^4.17.13",
|
||||
"to-fast-properties": "^2.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
@@ -568,9 +605,9 @@
|
||||
}
|
||||
},
|
||||
"@babel/plugin-transform-block-scoping": {
|
||||
"version": "7.6.2",
|
||||
"resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-block-scoping/download/@babel/plugin-transform-block-scoping-7.6.2.tgz",
|
||||
"integrity": "sha1-lsM6uXqa5QDMb1sZ4Ep+ZVM2Cnk=",
|
||||
"version": "7.6.3",
|
||||
"resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-block-scoping/download/@babel/plugin-transform-block-scoping-7.6.3.tgz?cache=0&sync_timestamp=1570565315466&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fplugin-transform-block-scoping%2Fdownload%2F%40babel%2Fplugin-transform-block-scoping-7.6.3.tgz",
|
||||
"integrity": "sha1-boVOUfu6qENRsV1N2v40LzpdVCo=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/helper-plugin-utils": "^7.0.0",
|
||||
@@ -723,9 +760,9 @@
|
||||
}
|
||||
},
|
||||
"@babel/plugin-transform-named-capturing-groups-regex": {
|
||||
"version": "7.6.2",
|
||||
"resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-named-capturing-groups-regex/download/@babel/plugin-transform-named-capturing-groups-regex-7.6.2.tgz",
|
||||
"integrity": "sha1-wcoLuEuU84XKMCw5MuhwsPsOUis=",
|
||||
"version": "7.6.3",
|
||||
"resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-named-capturing-groups-regex/download/@babel/plugin-transform-named-capturing-groups-regex-7.6.3.tgz",
|
||||
"integrity": "sha1-qqbkCd1PsuULbiqR9+OjFJ284M8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"regexpu-core": "^4.6.0"
|
||||
@@ -865,9 +902,9 @@
|
||||
}
|
||||
},
|
||||
"@babel/preset-env": {
|
||||
"version": "7.6.2",
|
||||
"resolved": "https://registry.npm.taobao.org/@babel/preset-env/download/@babel/preset-env-7.6.2.tgz?cache=0&sync_timestamp=1569273953853&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40babel%2Fpreset-env%2Fdownload%2F%40babel%2Fpreset-env-7.6.2.tgz",
|
||||
"integrity": "sha1-q7s+14XH/kIg1MgqU2IdcfwMddM=",
|
||||
"version": "7.6.3",
|
||||
"resolved": "https://registry.npm.taobao.org/@babel/preset-env/download/@babel/preset-env-7.6.3.tgz",
|
||||
"integrity": "sha1-nhvwWi4taHA20kxA5GOdxGzvInE=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/helper-module-imports": "^7.0.0",
|
||||
@@ -886,7 +923,7 @@
|
||||
"@babel/plugin-transform-arrow-functions": "^7.2.0",
|
||||
"@babel/plugin-transform-async-to-generator": "^7.5.0",
|
||||
"@babel/plugin-transform-block-scoped-functions": "^7.2.0",
|
||||
"@babel/plugin-transform-block-scoping": "^7.6.2",
|
||||
"@babel/plugin-transform-block-scoping": "^7.6.3",
|
||||
"@babel/plugin-transform-classes": "^7.5.5",
|
||||
"@babel/plugin-transform-computed-properties": "^7.2.0",
|
||||
"@babel/plugin-transform-destructuring": "^7.6.0",
|
||||
@@ -901,7 +938,7 @@
|
||||
"@babel/plugin-transform-modules-commonjs": "^7.6.0",
|
||||
"@babel/plugin-transform-modules-systemjs": "^7.5.0",
|
||||
"@babel/plugin-transform-modules-umd": "^7.2.0",
|
||||
"@babel/plugin-transform-named-capturing-groups-regex": "^7.6.2",
|
||||
"@babel/plugin-transform-named-capturing-groups-regex": "^7.6.3",
|
||||
"@babel/plugin-transform-new-target": "^7.4.4",
|
||||
"@babel/plugin-transform-object-super": "^7.5.5",
|
||||
"@babel/plugin-transform-parameters": "^7.4.4",
|
||||
@@ -914,12 +951,25 @@
|
||||
"@babel/plugin-transform-template-literals": "^7.4.4",
|
||||
"@babel/plugin-transform-typeof-symbol": "^7.2.0",
|
||||
"@babel/plugin-transform-unicode-regex": "^7.6.2",
|
||||
"@babel/types": "^7.6.0",
|
||||
"@babel/types": "^7.6.3",
|
||||
"browserslist": "^4.6.0",
|
||||
"core-js-compat": "^3.1.1",
|
||||
"invariant": "^2.2.2",
|
||||
"js-levenshtein": "^1.1.3",
|
||||
"semver": "^5.5.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/types": {
|
||||
"version": "7.6.3",
|
||||
"resolved": "https://registry.npm.taobao.org/@babel/types/download/@babel/types-7.6.3.tgz",
|
||||
"integrity": "sha1-PwfZb4VPmOL71FxksMuULRHougk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"esutils": "^2.0.2",
|
||||
"lodash": "^4.17.13",
|
||||
"to-fast-properties": "^2.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@babel/template": {
|
||||
@@ -1626,7 +1676,7 @@
|
||||
"dependencies": {
|
||||
"inherits": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npm.taobao.org/inherits/download/inherits-2.0.1.tgz?cache=0&sync_timestamp=1560975547815&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Finherits%2Fdownload%2Finherits-2.0.1.tgz",
|
||||
"resolved": "https://registry.npm.taobao.org/inherits/download/inherits-2.0.1.tgz",
|
||||
"integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=",
|
||||
"dev": true
|
||||
},
|
||||
@@ -1694,13 +1744,13 @@
|
||||
"dev": true
|
||||
},
|
||||
"autoprefixer": {
|
||||
"version": "9.6.4",
|
||||
"resolved": "https://registry.npm.taobao.org/autoprefixer/download/autoprefixer-9.6.4.tgz?cache=0&sync_timestamp=1570294713985&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fautoprefixer%2Fdownload%2Fautoprefixer-9.6.4.tgz",
|
||||
"integrity": "sha1-5kU75HrzFrKSPq6u2Hhg9SrUt+s=",
|
||||
"version": "9.6.5",
|
||||
"resolved": "https://registry.npm.taobao.org/autoprefixer/download/autoprefixer-9.6.5.tgz?cache=0&sync_timestamp=1571040005147&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fautoprefixer%2Fdownload%2Fautoprefixer-9.6.5.tgz",
|
||||
"integrity": "sha1-mPSv5+k8zPMjKHUV1CYBlhl3Xl4=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"browserslist": "^4.7.0",
|
||||
"caniuse-lite": "^1.0.30000998",
|
||||
"caniuse-lite": "^1.0.30000999",
|
||||
"chalk": "^2.4.2",
|
||||
"normalize-range": "^0.1.2",
|
||||
"num2fraction": "^1.2.2",
|
||||
@@ -1710,7 +1760,7 @@
|
||||
"dependencies": {
|
||||
"browserslist": {
|
||||
"version": "4.7.0",
|
||||
"resolved": "https://registry.npm.taobao.org/browserslist/download/browserslist-4.7.0.tgz?cache=0&sync_timestamp=1567245449635&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbrowserslist%2Fdownload%2Fbrowserslist-4.7.0.tgz",
|
||||
"resolved": "https://registry.npm.taobao.org/browserslist/download/browserslist-4.7.0.tgz",
|
||||
"integrity": "sha1-nuiSJf/AfbA0CfL+5STcgidFihc=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -1726,15 +1776,15 @@
|
||||
"dev": true
|
||||
},
|
||||
"electron-to-chromium": {
|
||||
"version": "1.3.275",
|
||||
"resolved": "https://registry.npm.taobao.org/electron-to-chromium/download/electron-to-chromium-1.3.275.tgz",
|
||||
"integrity": "sha1-GaOENuNCFvUYIPovQybVzhQfo28=",
|
||||
"version": "1.3.282",
|
||||
"resolved": "https://registry.npm.taobao.org/electron-to-chromium/download/electron-to-chromium-1.3.282.tgz?cache=0&sync_timestamp=1570911575715&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Felectron-to-chromium%2Fdownload%2Felectron-to-chromium-1.3.282.tgz",
|
||||
"integrity": "sha1-FhGK6ceaMuqToXWR1bFuKNEPwI0=",
|
||||
"dev": true
|
||||
},
|
||||
"node-releases": {
|
||||
"version": "1.1.34",
|
||||
"resolved": "https://registry.npm.taobao.org/node-releases/download/node-releases-1.1.34.tgz",
|
||||
"integrity": "sha1-ztRlXuG6nDosXcusOF4ZQ0FV/UA=",
|
||||
"version": "1.1.35",
|
||||
"resolved": "https://registry.npm.taobao.org/node-releases/download/node-releases-1.1.35.tgz",
|
||||
"integrity": "sha1-MqdKPNSXqnfyPVCfSDR1/RYOTEg=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"semver": "^6.3.0"
|
||||
@@ -1753,7 +1803,7 @@
|
||||
},
|
||||
"postcss-value-parser": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npm.taobao.org/postcss-value-parser/download/postcss-value-parser-4.0.2.tgz?cache=0&sync_timestamp=1565203765685&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fpostcss-value-parser%2Fdownload%2Fpostcss-value-parser-4.0.2.tgz",
|
||||
"resolved": "https://registry.npm.taobao.org/postcss-value-parser/download/postcss-value-parser-4.0.2.tgz",
|
||||
"integrity": "sha1-SCKCwJpCcG0fyaBptz9E7Ag5Hck=",
|
||||
"dev": true
|
||||
},
|
||||
@@ -2943,7 +2993,7 @@
|
||||
},
|
||||
"buffer": {
|
||||
"version": "4.9.1",
|
||||
"resolved": "https://registry.npm.taobao.org/buffer/download/buffer-4.9.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbuffer%2Fdownload%2Fbuffer-4.9.1.tgz",
|
||||
"resolved": "https://registry.npm.taobao.org/buffer/download/buffer-4.9.1.tgz",
|
||||
"integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -3986,9 +4036,9 @@
|
||||
}
|
||||
},
|
||||
"core-js": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npm.taobao.org/core-js/download/core-js-3.2.1.tgz",
|
||||
"integrity": "sha1-zUHzhTTabMWffbBQ/mcwfemGiwk=",
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npm.taobao.org/core-js/download/core-js-3.3.2.tgz",
|
||||
"integrity": "sha1-zULaHXsLsz7xEya+OnIZNCd860I=",
|
||||
"dev": true
|
||||
},
|
||||
"core-js-compat": {
|
||||
@@ -4865,9 +4915,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"electron": {
|
||||
"version": "6.0.11",
|
||||
"resolved": "https://registry.npm.taobao.org/electron/download/electron-6.0.11.tgz",
|
||||
"integrity": "sha1-ZO/6cTlwRXeaHdv1ExKkHM8m9JE=",
|
||||
"version": "6.0.12",
|
||||
"resolved": "https://registry.npm.taobao.org/electron/download/electron-6.0.12.tgz",
|
||||
"integrity": "sha1-hb8AYeMvZgJWz96VSI8ct1JTvJQ=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "^10.12.18",
|
||||
@@ -8973,9 +9023,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"lrc-file-parser": {
|
||||
"version": "0.1.12",
|
||||
"resolved": "https://registry.npm.taobao.org/lrc-file-parser/download/lrc-file-parser-0.1.12.tgz",
|
||||
"integrity": "sha1-sM/lhxqufWctaW8C2gBXlTjUKZ0="
|
||||
"version": "0.1.14",
|
||||
"resolved": "https://registry.npm.taobao.org/lrc-file-parser/download/lrc-file-parser-0.1.14.tgz",
|
||||
"integrity": "sha1-FW00nV/f01XNJMp/JqYMPeDscgE="
|
||||
},
|
||||
"lru-cache": {
|
||||
"version": "4.1.5",
|
||||
@@ -11982,7 +12032,7 @@
|
||||
},
|
||||
"sha.js": {
|
||||
"version": "2.4.11",
|
||||
"resolved": "https://registry.npm.taobao.org/sha.js/download/sha.js-2.4.11.tgz",
|
||||
"resolved": "https://registry.npm.taobao.org/sha.js/download/sha.js-2.4.11.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsha.js%2Fdownload%2Fsha.js-2.4.11.tgz",
|
||||
"integrity": "sha1-N6XPC4HsvGlD3hCbopYNGyZYSuc=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -12911,9 +12961,9 @@
|
||||
}
|
||||
},
|
||||
"terser": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npm.taobao.org/terser/download/terser-4.3.1.tgz",
|
||||
"integrity": "sha1-CYILyzOYKZxLSNmoau/GUSfQ7WU=",
|
||||
"version": "4.3.8",
|
||||
"resolved": "https://registry.npm.taobao.org/terser/download/terser-4.3.8.tgz",
|
||||
"integrity": "sha1-cH8F8/TBxwyEDmJq3f2xwVihcTY=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"commander": "^2.20.0",
|
||||
@@ -12922,26 +12972,26 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"commander": {
|
||||
"version": "2.20.0",
|
||||
"resolved": "https://registry.npm.taobao.org/commander/download/commander-2.20.0.tgz",
|
||||
"integrity": "sha1-1YuytcHuj4ew00ACfp6U4iLFpCI=",
|
||||
"version": "2.20.3",
|
||||
"resolved": "https://registry.npm.taobao.org/commander/download/commander-2.20.3.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcommander%2Fdownload%2Fcommander-2.20.3.tgz",
|
||||
"integrity": "sha1-/UhehMA+tIgcIHIrpIA16FMa6zM=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"terser-webpack-plugin": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npm.taobao.org/terser-webpack-plugin/download/terser-webpack-plugin-2.1.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fterser-webpack-plugin%2Fdownload%2Fterser-webpack-plugin-2.1.2.tgz",
|
||||
"integrity": "sha1-K5uBR6bxiRg0ggCADPlWDFD3Abs=",
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npm.taobao.org/terser-webpack-plugin/download/terser-webpack-plugin-2.1.3.tgz",
|
||||
"integrity": "sha1-hUMNpxuoimAHK/ZZWJ6vr2oA3CI=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cacache": "^13.0.0",
|
||||
"cacache": "^13.0.1",
|
||||
"find-cache-dir": "^3.0.0",
|
||||
"jest-worker": "^24.9.0",
|
||||
"schema-utils": "^2.4.1",
|
||||
"serialize-javascript": "^2.1.0",
|
||||
"source-map": "^0.6.1",
|
||||
"terser": "^4.3.4",
|
||||
"terser": "^4.3.8",
|
||||
"webpack-sources": "^1.4.3"
|
||||
},
|
||||
"dependencies": {
|
||||
@@ -12971,12 +13021,6 @@
|
||||
"unique-filename": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"commander": {
|
||||
"version": "2.20.1",
|
||||
"resolved": "https://registry.npm.taobao.org/commander/download/commander-2.20.1.tgz",
|
||||
"integrity": "sha1-OGPOPKktCDHc8qEC9ftLWSav0Pk=",
|
||||
"dev": true
|
||||
},
|
||||
"find-cache-dir": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npm.taobao.org/find-cache-dir/download/find-cache-dir-3.0.0.tgz",
|
||||
@@ -13096,17 +13140,6 @@
|
||||
"minipass": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"terser": {
|
||||
"version": "4.3.6",
|
||||
"resolved": "https://registry.npm.taobao.org/terser/download/terser-4.3.6.tgz",
|
||||
"integrity": "sha1-OjauGX1EcOEQaVV7SkvXEvhPmY0=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"commander": "^2.20.0",
|
||||
"source-map": "~0.6.1",
|
||||
"source-map-support": "~0.5.12"
|
||||
}
|
||||
},
|
||||
"webpack-sources": {
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npm.taobao.org/webpack-sources/download/webpack-sources-1.4.3.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack-sources%2Fdownload%2Fwebpack-sources-1.4.3.tgz",
|
||||
@@ -13667,7 +13700,7 @@
|
||||
"dependencies": {
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npm.taobao.org/inherits/download/inherits-2.0.3.tgz?cache=0&sync_timestamp=1560975547815&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Finherits%2Fdownload%2Finherits-2.0.3.tgz",
|
||||
"resolved": "https://registry.npm.taobao.org/inherits/download/inherits-2.0.3.tgz",
|
||||
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
|
||||
"dev": true
|
||||
}
|
||||
@@ -13924,9 +13957,9 @@
|
||||
}
|
||||
},
|
||||
"webpack": {
|
||||
"version": "4.41.0",
|
||||
"resolved": "https://registry.npm.taobao.org/webpack/download/webpack-4.41.0.tgz",
|
||||
"integrity": "sha1-22olS95nF2n3wU6QoaVec2Avxws=",
|
||||
"version": "4.41.2",
|
||||
"resolved": "https://registry.npm.taobao.org/webpack/download/webpack-4.41.2.tgz",
|
||||
"integrity": "sha1-w07Hbao6hGjJthpQM22OMwPc504=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.8.5",
|
||||
@@ -13956,13 +13989,13 @@
|
||||
"dependencies": {
|
||||
"acorn": {
|
||||
"version": "6.3.0",
|
||||
"resolved": "https://registry.npm.taobao.org/acorn/download/acorn-6.3.0.tgz",
|
||||
"resolved": "https://registry.npm.taobao.org/acorn/download/acorn-6.3.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Facorn%2Fdownload%2Facorn-6.3.0.tgz",
|
||||
"integrity": "sha1-AIdQkRn/pPwKAEHR6TpBfmjLhW4=",
|
||||
"dev": true
|
||||
},
|
||||
"cacache": {
|
||||
"version": "12.0.3",
|
||||
"resolved": "https://registry.npm.taobao.org/cacache/download/cacache-12.0.3.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcacache%2Fdownload%2Fcacache-12.0.3.tgz",
|
||||
"resolved": "https://registry.npm.taobao.org/cacache/download/cacache-12.0.3.tgz",
|
||||
"integrity": "sha1-vpmruk4b9d9GHNWiwQcfxDJXM5A=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -13985,7 +14018,7 @@
|
||||
},
|
||||
"eslint-scope": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npm.taobao.org/eslint-scope/download/eslint-scope-4.0.3.tgz?cache=0&sync_timestamp=1563679289211&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-scope%2Fdownload%2Feslint-scope-4.0.3.tgz",
|
||||
"resolved": "https://registry.npm.taobao.org/eslint-scope/download/eslint-scope-4.0.3.tgz",
|
||||
"integrity": "sha1-ygODMxD2iJoyZHgaqC5j65z+eEg=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -14013,7 +14046,7 @@
|
||||
},
|
||||
"terser-webpack-plugin": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npm.taobao.org/terser-webpack-plugin/download/terser-webpack-plugin-1.4.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fterser-webpack-plugin%2Fdownload%2Fterser-webpack-plugin-1.4.1.tgz",
|
||||
"resolved": "https://registry.npm.taobao.org/terser-webpack-plugin/download/terser-webpack-plugin-1.4.1.tgz",
|
||||
"integrity": "sha1-YbGOQOruW+l+dxzbsQ7RKAiIwrQ=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@@ -14030,7 +14063,7 @@
|
||||
},
|
||||
"webpack-sources": {
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npm.taobao.org/webpack-sources/download/webpack-sources-1.4.3.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack-sources%2Fdownload%2Fwebpack-sources-1.4.3.tgz",
|
||||
"resolved": "https://registry.npm.taobao.org/webpack-sources/download/webpack-sources-1.4.3.tgz?cache=0&sync_timestamp=1568302837530&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack-sources%2Fdownload%2Fwebpack-sources-1.4.3.tgz",
|
||||
"integrity": "sha1-7t2OwLko+/HL/plOItLYkPMwqTM=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
|
||||
18
package.json
18
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "lx-music-desktop",
|
||||
"version": "0.7.0",
|
||||
"version": "0.8.0",
|
||||
"description": "一个免费的音乐下载助手",
|
||||
"main": "./dist/electron/main.js",
|
||||
"productName": "lx-music-desktop",
|
||||
@@ -134,11 +134,11 @@
|
||||
},
|
||||
"homepage": "https://github.com/lyswhut/lx-music-desktop#readme",
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.6.2",
|
||||
"@babel/core": "^7.6.4",
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
|
||||
"@babel/polyfill": "^7.6.0",
|
||||
"@babel/preset-env": "^7.6.2",
|
||||
"autoprefixer": "^9.6.4",
|
||||
"@babel/preset-env": "^7.6.3",
|
||||
"autoprefixer": "^9.6.5",
|
||||
"babel-eslint": "^10.0.3",
|
||||
"babel-loader": "^8.0.6",
|
||||
"babel-minify-webpack-plugin": "^0.3.1",
|
||||
@@ -147,12 +147,12 @@
|
||||
"chalk": "^2.4.2",
|
||||
"changelog-parser": "^2.8.0",
|
||||
"copy-webpack-plugin": "^5.0.4",
|
||||
"core-js": "^3.2.1",
|
||||
"core-js": "^3.3.2",
|
||||
"cos-nodejs-sdk-v5": "^2.5.12",
|
||||
"cross-env": "^6.0.3",
|
||||
"css-loader": "^3.2.0",
|
||||
"del": "^5.1.0",
|
||||
"electron": "^6.0.11",
|
||||
"electron": "^6.0.12",
|
||||
"electron-builder": "^21.2.0",
|
||||
"electron-debug": "^3.0.1",
|
||||
"electron-devtools-installer": "^2.2.4",
|
||||
@@ -182,12 +182,12 @@
|
||||
"rimraf": "^3.0.0",
|
||||
"stylus": "^0.54.7",
|
||||
"stylus-loader": "^3.0.2",
|
||||
"terser-webpack-plugin": "^2.1.2",
|
||||
"terser-webpack-plugin": "^2.1.3",
|
||||
"url-loader": "^2.2.0",
|
||||
"vue-loader": "^15.7.1",
|
||||
"vue-style-loader": "^4.1.2",
|
||||
"vue-template-compiler": "^2.6.10",
|
||||
"webpack": "^4.41.0",
|
||||
"webpack": "^4.41.2",
|
||||
"webpack-cli": "^3.3.9",
|
||||
"webpack-dev-server": "^3.8.2",
|
||||
"webpack-hot-middleware": "^2.25.0",
|
||||
@@ -202,7 +202,7 @@
|
||||
"electron-updater": "^4.1.2",
|
||||
"flac-metadata": "^0.1.1",
|
||||
"js-htmlencode": "^0.3.0",
|
||||
"lrc-file-parser": "^0.1.12",
|
||||
"lrc-file-parser": "^0.1.14",
|
||||
"node-downloader-helper": "^1.0.10",
|
||||
"node-id3": "^0.1.11",
|
||||
"request": "^2.88.0",
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
#### 新增
|
||||
|
||||
- 新增“我的收藏”本地播放列表
|
||||
- 新增缓存清理功能,可到**设置-其他**查看与清理软件缓存
|
||||
- 新增QQ音乐源搜索
|
||||
- 新增咪咕源搜索
|
||||
- 新增咪咕源歌单
|
||||
- 新增咪咕源排行榜
|
||||
- 新增我的音乐列表歌曲源显示,默认关闭,可到**设置-列表设置**开启
|
||||
- 新增网易云源歌曲搜索
|
||||
- 新增网易云源歌单
|
||||
- 新增各平台通过输入歌单链接或歌单ID打开歌单详情列表,目前只适配了**网页版歌单链接**,其他方式的歌单链接可能无法解析,但你可想办法获取歌单ID后输入打开。注:各平台歌单ID均为纯数字,若遇到链接里存在歌单ID但无法解析的歌单链接,可以到GitHub提交issue或发送邮件或加群830125506反馈!
|
||||
- 新增音量调整滑动功能,现在支持鼠标左右拖动调整音量了
|
||||
|
||||
#### 优化
|
||||
|
||||
- 优化选择框动画效果
|
||||
- 尝试优化选我的音乐列表内容很多时多选的卡顿问题
|
||||
- 优化搜索框搜索体验
|
||||
- 优化音量条交互视觉效果
|
||||
- 缓存歌单详情列表数据
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复列表延迟显示的Bug
|
||||
- 修复QQ音源128k音质试听
|
||||
- 修复QQ源歌单无法翻页Bug
|
||||
- 修复默认列表没有创建时无法显示收藏列表的Bug
|
||||
- 修复网易云128k直接试听
|
||||
- 修复歌曲音质不存在时仍然播放或下载的Bug
|
||||
- 修复调整音量时,调整的位置与鼠标点击的位置不一致的问题
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
{
|
||||
"version": "0.7.0",
|
||||
"desc": "<h4>新增</h4>\n<ul>\n<li>新增“我的收藏”本地播放列表</li>\n<li>新增缓存清理功能,可到<strong>设置-其他</strong>查看与清理软件缓存</li>\n<li>新增QQ音乐源搜索</li>\n<li>新增咪咕源搜索</li>\n<li>新增咪咕源歌单</li>\n<li>新增咪咕源排行榜</li>\n<li>新增我的音乐列表歌曲源显示,默认关闭,可到<strong>设置-列表设置</strong>开启</li>\n</ul>\n<h4>优化</h4>\n<ul>\n<li>优化选择框动画效果</li>\n<li>尝试优化选我的音乐列表内容很多时多选的卡顿问题</li>\n</ul>\n<h4>修复</h4>\n<ul>\n<li>修复列表延迟显示的Bug</li>\n<li>修复QQ音源128k音质试听</li>\n</ul>\n",
|
||||
"version": "0.8.0",
|
||||
"desc": "<h4>新增</h4>\n<ul>\n<li>新增网易云源歌曲搜索</li>\n<li>新增网易云源歌单</li>\n<li>新增各平台通过输入歌单链接或歌单ID打开歌单详情列表,目前只适配了<strong>网页版歌单链接</strong>,其他方式的歌单链接可能无法解析,但你可想办法获取歌单ID后输入打开。注:各平台歌单ID均为纯数字,若遇到链接里存在歌单ID但无法解析的歌单链接,可以到GitHub提交issue或发送邮件或加群830125506反馈!</li>\n<li>新增音量调整滑动功能,现在支持鼠标左右拖动调整音量了</li>\n</ul>\n<h4>优化</h4>\n<ul>\n<li>优化搜索框搜索体验</li>\n<li>优化音量条交互视觉效果</li>\n<li>缓存歌单详情列表数据</li>\n</ul>\n<h4>修复</h4>\n<ul>\n<li>修复QQ源歌单无法翻页Bug</li>\n<li>修复默认列表没有创建时无法显示收藏列表的Bug</li>\n<li>修复网易云128k直接试听</li>\n<li>修复歌曲音质不存在时仍然播放或下载的Bug</li>\n<li>修复调整音量时,调整的位置与鼠标点击的位置不一致的问题</li>\n</ul>\n",
|
||||
"history": [
|
||||
{
|
||||
"version": "0.7.0",
|
||||
"desc": "<h4>新增</h4>\n<ul>\n<li>新增“我的收藏”本地播放列表</li>\n<li>新增缓存清理功能,可到<strong>设置-其他</strong>查看与清理软件缓存</li>\n<li>新增QQ音乐源搜索</li>\n<li>新增咪咕源搜索</li>\n<li>新增咪咕源歌单</li>\n<li>新增咪咕源排行榜</li>\n<li>新增我的音乐列表歌曲源显示,默认关闭,可到<strong>设置-列表设置</strong>开启</li>\n</ul>\n<h4>优化</h4>\n<ul>\n<li>优化选择框动画效果</li>\n<li>尝试优化选我的音乐列表内容很多时多选的卡顿问题</li>\n</ul>\n<h4>修复</h4>\n<ul>\n<li>修复列表延迟显示的Bug</li>\n<li>修复QQ音源128k音质试听</li>\n</ul>\n"
|
||||
},
|
||||
{
|
||||
"version": "0.6.2",
|
||||
"desc": "<p>祝贺祖国成立70周年~!</p>\n<h4>新增</h4>\n<ul>\n<li>新增QQ音乐源歌单</li>\n</ul>\n<h4>修复</h4>\n<ul>\n<li>修正火影皮肤名字</li>\n<li>修复当试听列表为空时,无法切到其他界面的Bug</li>\n<li>修复百度源搜索结果为空时的接口处理Bug</li>\n<li>恢复<strong>酷狗</strong>其他音质播放</li>\n</ul>\n"
|
||||
|
||||
@@ -164,8 +164,7 @@ export default {
|
||||
initPlayList() {
|
||||
let defaultList = this.electronStore.get('list.defaultList')
|
||||
let loveList = this.electronStore.get('list.loveList')
|
||||
// console.log(defaultList)
|
||||
if (defaultList) this.initList({ defaultList, loveList })
|
||||
this.initList({ defaultList, loveList })
|
||||
},
|
||||
initDownloadList() {
|
||||
let downloadList = this.electronStore.get('download.list')
|
||||
|
||||
@@ -9,8 +9,9 @@ div(:class="$style.player")
|
||||
div(:class="$style.container")
|
||||
div(:class="$style.title" @click="handleCopy(title)" :title="title + '(点击复制)'") {{title}}
|
||||
div(:class="$style.volumeContent")
|
||||
div(:class="$style.volume" @click.stop='handleChangeVolume' :title="`当前音量:${parseInt(volume * 100)}%`")
|
||||
div(:class="$style.volume")
|
||||
div(:class="$style.volumeBar" :style="{ transform: `scaleX(${volume || 0})` }")
|
||||
div(:class="$style.volumeMask" @mousedown="handleVolumeMsDown" ref="dom_volumeMask" :title="`当前音量:${parseInt(volume * 100)}%`")
|
||||
|
||||
//- div(:class="$style.playBtn" @click='handleNext' title="音量")
|
||||
svg(version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' height='100%' viewBox='0 0 291.063 291.064' space='preserve')
|
||||
@@ -48,9 +49,10 @@ div(:class="$style.player")
|
||||
<script>
|
||||
import Lyric from 'lrc-file-parser'
|
||||
import { rendererSend } from '../../../common/icp'
|
||||
import { formatPlayTime2, getRandom, checkPath, setTitle, clipboardWriteText } from '../../utils'
|
||||
import { formatPlayTime2, getRandom, checkPath, setTitle, clipboardWriteText, debounce } from '../../utils'
|
||||
import { mapGetters, mapActions, mapMutations } from 'vuex'
|
||||
import { requestMsg } from '../../utils/message'
|
||||
import { isMac } from '../../../common/utils'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
@@ -80,6 +82,14 @@ export default {
|
||||
delayNextTimeout: null,
|
||||
audioErrorTime: 0,
|
||||
retryNum: 0,
|
||||
isMac,
|
||||
volumeEvent: {
|
||||
isMsDown: false,
|
||||
msDownX: 0,
|
||||
msDownVolume: 0,
|
||||
},
|
||||
handleVolumeMsMoveFn: null,
|
||||
handleVolumeMsUpFn: null,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -111,6 +121,16 @@ export default {
|
||||
this.$nextTick(() => {
|
||||
this.setProgessWidth()
|
||||
})
|
||||
this.handleSaveVolume = debounce(volume => {
|
||||
this.setVolume(volume)
|
||||
}, 300)
|
||||
|
||||
document.addEventListener('mousemove', this.handleVolumeMsMoveFn = this.handleVolumeMsMove.bind(this))
|
||||
document.addEventListener('mouseup', this.handleVolumeMsUpFn = this.handleVolumeMsUp.bind(this))
|
||||
},
|
||||
beforeDestroy() {
|
||||
document.removeEventListener('mousemove', this.handleVolumeMsMoveFn)
|
||||
document.removeEventListener('mouseup', this.handleVolumeMsUpFn)
|
||||
},
|
||||
watch: {
|
||||
changePlay(n) {
|
||||
@@ -442,16 +462,29 @@ export default {
|
||||
clearAppTitle() {
|
||||
setTitle()
|
||||
},
|
||||
handleChangeVolume(e) {
|
||||
handleVolumeMsDown(e) {
|
||||
this.volumeEvent.isMsDown = true
|
||||
this.volumeEvent.isMsMoved = false
|
||||
this.volumeEvent.msDownX = e.clientX
|
||||
|
||||
let val = e.offsetX / 70
|
||||
if (val < 0) val = 0
|
||||
if (val > 1) val = 1
|
||||
if (val > 0.97) val = 1
|
||||
|
||||
this.volume = val
|
||||
this.volumeEvent.msDownVolume = val
|
||||
// console.log(val)
|
||||
if (this.audio) this.audio.volume = this.volume
|
||||
},
|
||||
handleSaveVolume(volume) {
|
||||
this.setVolume(volume)
|
||||
handleVolumeMsUp(e) {
|
||||
this.volumeEvent.isMsDown = false
|
||||
},
|
||||
handleVolumeMsMove(e) {
|
||||
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
|
||||
// console.log(val)
|
||||
},
|
||||
handleCopy(text) {
|
||||
clipboardWriteText(text)
|
||||
@@ -483,6 +516,7 @@ export default {
|
||||
transition: @transition-theme;
|
||||
transition-property: color;
|
||||
flex: none;
|
||||
padding: 2px;
|
||||
|
||||
svg {
|
||||
fill: currentColor;
|
||||
@@ -492,7 +526,7 @@ export default {
|
||||
max-height: 100%;
|
||||
transition: @transition-theme;
|
||||
transition-property: border-color;
|
||||
border: 2px solid @color-theme_2-background_1;
|
||||
// border: 2px solid @color-theme_2-background_1;
|
||||
}
|
||||
}
|
||||
.right {
|
||||
@@ -527,14 +561,20 @@ export default {
|
||||
}
|
||||
|
||||
.volume-content {
|
||||
position: relative;
|
||||
width: 100px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 15px;
|
||||
opacity: .5;
|
||||
transition: opacity @transition-theme;
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.volume {
|
||||
cursor: pointer;
|
||||
// cursor: pointer;
|
||||
width: 100%;
|
||||
height: 0.25em;
|
||||
border-radius: 10px;
|
||||
@@ -561,7 +601,16 @@ export default {
|
||||
transition-duration: 0.2s;
|
||||
background-color: @color-theme;
|
||||
box-shadow: 0 0 2px rgba(0, 0, 0, 0.2);
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
.volume-mask {
|
||||
position: absolute;
|
||||
left: 15px;
|
||||
right: 15px;
|
||||
top: 0;
|
||||
width: 70%;
|
||||
height: 100%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.play-btn {
|
||||
@@ -576,7 +625,7 @@ export default {
|
||||
transition: @transition-theme;
|
||||
transition-property: color;
|
||||
color: @color-theme;
|
||||
transition: opacity 0.2s ease;
|
||||
transition: opacity 0.1s ease;
|
||||
opacity: 1;
|
||||
cursor: pointer;
|
||||
|
||||
@@ -684,9 +733,9 @@ each(@themes, {
|
||||
}
|
||||
.left {
|
||||
color: ~'@{color-@{value}-theme}';
|
||||
img {
|
||||
border-color: ~'@{color-@{value}-theme_2-background_1}';
|
||||
}
|
||||
// img {
|
||||
// border-color: ~'@{color-@{value}-theme_2-background_1}';
|
||||
// }
|
||||
}
|
||||
.play-btn {
|
||||
color: ~'@{color-@{value}-theme}';
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
div(:class="$style.toolbar")
|
||||
//- img(v-if="icon")
|
||||
//- h1 {{title}}
|
||||
material-search-input(:class="$style.input")
|
||||
material-search-input(:class="$style.input"
|
||||
@event="handleEvent" :list="tipList" :visibleList="visibleList"
|
||||
v-model="searchText")
|
||||
div(:class="$style.control")
|
||||
button(type="button" :class="$style.min" title="最小化" @click="min")
|
||||
//- button(type="button" :class="$style.max" @click="max")
|
||||
@@ -11,22 +13,93 @@
|
||||
|
||||
<script>
|
||||
import { rendererSend } from 'common/icp'
|
||||
// import { mapGetters } from 'vuex'
|
||||
import { mapGetters } from 'vuex'
|
||||
import music from '../../utils/music'
|
||||
import { debounce } from '../../utils'
|
||||
export default {
|
||||
// props: {
|
||||
// color: {
|
||||
// type: String,
|
||||
// default: color,
|
||||
// },
|
||||
// icon: {
|
||||
// type: Boolean,
|
||||
// default: false,
|
||||
// },
|
||||
// },
|
||||
data() {
|
||||
return {
|
||||
searchText: '',
|
||||
visibleList: false,
|
||||
tipList: [],
|
||||
tipSearch: null,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// ...mapGetters(['theme']),
|
||||
...mapGetters(['route', 'setting']),
|
||||
...mapGetters('search', {
|
||||
storeSearchText: 'searchText',
|
||||
}),
|
||||
source() {
|
||||
return this.setting.search.tempSearchSource
|
||||
},
|
||||
isAutoClearInput() {
|
||||
return this.setting.odc.isAutoClearSearchInput
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
route(n) {
|
||||
if (this.isAutoClearInput && n.name != 'search' && this.searchText) this.searchText = ''
|
||||
},
|
||||
'storeSearchText'(n) {
|
||||
if (n !== this.searchText) this.searchText = n
|
||||
},
|
||||
searchText(n) {
|
||||
this.handleTipSearch()
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.tipSearch = debounce(() => {
|
||||
if (this.searchText === '') {
|
||||
this.tipList.splice(0, this.tipList.length)
|
||||
music[this.source].tempSearch.cancelTempSearch()
|
||||
return
|
||||
}
|
||||
music[this.source].tempSearch.search(this.searchText).then(list => {
|
||||
this.tipList = list
|
||||
}).catch(() => {})
|
||||
}, 50)
|
||||
},
|
||||
methods: {
|
||||
handleEvent({ action, data }) {
|
||||
switch (action) {
|
||||
case 'focus':
|
||||
if (!this.visibleList) this.visibleList = true
|
||||
if (this.searchText) this.handleTipSearch()
|
||||
break
|
||||
case 'blur':
|
||||
setTimeout(() => {
|
||||
if (this.visibleList) this.visibleList = false
|
||||
}, 50)
|
||||
break
|
||||
case 'submit':
|
||||
this.handleSearch()
|
||||
break
|
||||
case 'listClick':
|
||||
this.searchText = this.tipList[data]
|
||||
this.$nextTick(() => {
|
||||
this.handleSearch()
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
handleTipSearch() {
|
||||
if (!this.visibleList) this.visibleList = true
|
||||
this.tipSearch()
|
||||
},
|
||||
|
||||
handleSearch() {
|
||||
if (this.visibleList) this.visibleList = false
|
||||
setTimeout(() => {
|
||||
this.$router.push({
|
||||
path: 'search',
|
||||
query: {
|
||||
text: this.searchText,
|
||||
},
|
||||
}).catch(_ => _)
|
||||
}, 200)
|
||||
},
|
||||
|
||||
min() {
|
||||
rendererSend('min')
|
||||
},
|
||||
@@ -56,6 +129,9 @@ export default {
|
||||
}
|
||||
.input {
|
||||
-webkit-app-region: no-drag;
|
||||
position: absolute;
|
||||
left: 15px;
|
||||
top: 13px;
|
||||
}
|
||||
|
||||
// img {
|
||||
|
||||
@@ -5,7 +5,7 @@ material-modal(:show="show" :bg-close="bgClose" @close="handleClose")
|
||||
| {{ info.name }}
|
||||
br
|
||||
| {{ info.singer }}
|
||||
material-btn(:class="$style.btn" :title="!checkSource(type.type) && '目前腾讯音源仅支持下载128k音质'" :disabled="!checkSource(type.type)" :key="type.type" @click="handleClick(type.type)" v-for="type in info.types") {{getTypeName(type.type)}} {{ type.type.toUpperCase() }}{{ type.size && ` - ${type.size.toUpperCase()}` }}
|
||||
material-btn(:class="$style.btn" :title="!checkSource(type.type) && '腾讯、网易音源仅支持下载128k音质'" :disabled="!checkSource(type.type)" :key="type.type" @click="handleClick(type.type)" v-for="type in info.types") {{getTypeName(type.type)}} {{ type.type.toUpperCase() }}{{ type.size && ` - ${type.size.toUpperCase()}` }}
|
||||
|
||||
</template>
|
||||
|
||||
@@ -52,7 +52,6 @@ export default {
|
||||
checkSource(type) {
|
||||
switch (this.musicInfo.source) {
|
||||
case 'wy':
|
||||
return false
|
||||
case 'tx':
|
||||
return type == '128k'
|
||||
|
||||
|
||||
@@ -1,31 +1,54 @@
|
||||
<template lang="pug">
|
||||
div(:class="[$style.search, focus ? $style.active : '']")
|
||||
div(:class="[$style.search, focus ? $style.active : '', big ? $style.big : '', small ? $style.small : '']")
|
||||
div(:class="$style.form")
|
||||
input(placeholder="Search for something..." v-model.trim="text"
|
||||
@focus="handleFocus" @blur="handleBlur" @input="handleInput"
|
||||
input(:placeholder="placeholder" v-model.trim="text"
|
||||
@focus="handleFocus" @blur="handleBlur" @input="$emit('input', text)"
|
||||
@change="sendEvent('change')"
|
||||
@keyup.enter="handleSearch")
|
||||
button(type="button" @click="handleSearch")
|
||||
svg(version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' height='100%' viewBox='0 0 30.239 30.239' space='preserve')
|
||||
use(xlink:href='#icon-search')
|
||||
slot
|
||||
svg(version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' height='100%' viewBox='0 0 30.239 30.239' space='preserve')
|
||||
use(xlink:href='#icon-search')
|
||||
//- transition(name="custom-classes-transition"
|
||||
//- enter-active-class="animated flipInX"
|
||||
//- leave-active-class="animated flipOutX")
|
||||
div(:class="$style.list" :style="listStyle")
|
||||
div(v-if="list" :class="$style.list" :style="listStyle")
|
||||
ul(ref="dom_list")
|
||||
li(v-for="(item, index) in list" :key="item" @click="handleTemplistClick(index)")
|
||||
span {{item}}
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import music from '../../utils/music'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: 'Search for something...',
|
||||
},
|
||||
list: {
|
||||
type: Array,
|
||||
},
|
||||
visibleList: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
big: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
small: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isShow: false,
|
||||
text: '',
|
||||
list: [],
|
||||
index: null,
|
||||
focus: false,
|
||||
listStyle: {
|
||||
@@ -33,64 +56,35 @@ export default {
|
||||
},
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['route', 'setting']),
|
||||
...mapGetters('search', ['searchText']),
|
||||
isAutoClearInput() {
|
||||
return this.setting.odc.isAutoClearSearchInput
|
||||
},
|
||||
source() {
|
||||
return this.setting.search.tempSearchSource
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
list(n) {
|
||||
if (!this.visibleList) return
|
||||
this.$nextTick(() => {
|
||||
this.listStyle.height = this.$refs.dom_list.scrollHeight + 'px'
|
||||
})
|
||||
},
|
||||
'searchText'(n) {
|
||||
if (n !== this.text) this.text = n
|
||||
value(n) {
|
||||
this.text = n
|
||||
},
|
||||
route(n) {
|
||||
if (this.isAutoClearInput && n.name != 'search' && this.text) this.text = ''
|
||||
visibleList(n) {
|
||||
n ? this.showList() : this.hideList()
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleTemplistClick(index) {
|
||||
this.text = this.list[index]
|
||||
this.handleSearch()
|
||||
this.sendEvent('listClick', index)
|
||||
},
|
||||
handleFocus() {
|
||||
this.focus = true
|
||||
if (this.text) this.handleInput()
|
||||
this.showList()
|
||||
this.sendEvent('focus')
|
||||
},
|
||||
handleBlur() {
|
||||
setTimeout(() => {
|
||||
this.focus = false
|
||||
this.hideList()
|
||||
}, 200)
|
||||
this.focus = false
|
||||
this.sendEvent('blur')
|
||||
},
|
||||
handleSearch() {
|
||||
this.hideList()
|
||||
this.$router.push({
|
||||
path: 'search',
|
||||
query: {
|
||||
text: this.text,
|
||||
},
|
||||
}).catch(_ => _)
|
||||
},
|
||||
handleInput() {
|
||||
if (this.text === '') {
|
||||
this.list.splice(0, this.list.length)
|
||||
music[this.source].tempSearch.cancelTempSearch()
|
||||
return
|
||||
}
|
||||
if (!this.isShow) this.showList()
|
||||
music[this.source].tempSearch.search(this.text).then(list => {
|
||||
this.list = list
|
||||
}).catch(() => {})
|
||||
this.sendEvent('submit')
|
||||
},
|
||||
showList() {
|
||||
this.isShow = true
|
||||
@@ -100,6 +94,12 @@ export default {
|
||||
this.isShow = false
|
||||
this.listStyle.height = 0
|
||||
},
|
||||
sendEvent(action, data) {
|
||||
this.$emit('event', {
|
||||
action,
|
||||
data,
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -109,9 +109,6 @@ export default {
|
||||
@import '../../assets/styles/layout.less';
|
||||
|
||||
.search {
|
||||
position: absolute;
|
||||
left: 15px;
|
||||
top: 13px;
|
||||
border-radius: 3px;
|
||||
transition: box-shadow .4s ease, background-color @transition-theme;
|
||||
display: flex;
|
||||
@@ -201,6 +198,19 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
.big {
|
||||
width: 500px;
|
||||
// input {
|
||||
// line-height: 30px;
|
||||
// }
|
||||
.form {
|
||||
height: 30px;
|
||||
button {
|
||||
padding: 6px 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
each(@themes, {
|
||||
:global(#container.@{value}) {
|
||||
|
||||
|
||||
@@ -29,9 +29,9 @@ div(:class="$style.songList")
|
||||
td(style="width: 20%; padding-left: 0; padding-right: 0;")
|
||||
material-list-buttons(:index="index" :search-btn="true"
|
||||
:remove-btn="false" @btn-click="handleListBtnClick"
|
||||
:listAdd-btn="item.source == 'kw' || (!isAPITemp && item.source != 'wy')"
|
||||
:play-btn="item.source == 'kw' || (!isAPITemp && item.source != 'wy')"
|
||||
:download-btn="item.source == 'kw' || (!isAPITemp && item.source != 'wy')")
|
||||
:listAdd-btn="item.source == 'kw' || (!isAPITemp)"
|
||||
:play-btn="item.source == 'kw' || (!isAPITemp)"
|
||||
:download-btn="item.source == 'kw' || (!isAPITemp)")
|
||||
//- button.btn-info(type='button' v-if="item._types['128k'] || item._types['192k'] || item._types['320k'] || item._types.flac" @click.stop='openDownloadModal(index)') 下载
|
||||
//- button.btn-secondary(type='button' v-if="item._types['128k'] || item._types['192k'] || item._types['320k']" @click.stop='testPlay(index)') 试听
|
||||
//- button.btn-success(type='button' v-if="(item._types['128k'] || item._types['192k'] || item._types['320k']) && userInfo" @click.stop='showListModal(index)') +
|
||||
@@ -140,7 +140,7 @@ export default {
|
||||
this.clickIndex = index
|
||||
return
|
||||
}
|
||||
this.emitEvent((this.source == 'kw' || (!this.isAPITemp && this.list[index].source != 'wy')) ? 'testPlay' : 'search', index)
|
||||
this.emitEvent((this.source == 'kw' || !this.isAPITemp) ? 'testPlay' : 'search', index)
|
||||
this.clickTime = 0
|
||||
this.clickIndex = -1
|
||||
},
|
||||
|
||||
@@ -75,6 +75,7 @@ const addTask = (list, type, store) => {
|
||||
|
||||
const getUrl = (downloadInfo, isRefresh) => {
|
||||
const url = downloadInfo.musicInfo.typeUrl[downloadInfo.type]
|
||||
if (!downloadInfo.musicInfo._types[downloadInfo.type]) return Promise.reject(new Error('该歌曲没有可下载的音频'))
|
||||
return url && !isRefresh ? Promise.resolve({ url }) : music[downloadInfo.musicInfo.source].getMusicUrl(downloadInfo.musicInfo, downloadInfo.type).promise
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ const getters = {
|
||||
// actions
|
||||
const actions = {
|
||||
getUrl({ commit, state }, { musicInfo, type, isRefresh }) {
|
||||
if (!musicInfo._types[type]) return Promise.reject(new Error('该歌曲没有可播放的音频'))
|
||||
if (urlRequest && urlRequest.cancelHttp) urlRequest.cancelHttp()
|
||||
if (musicInfo.typeUrl[type] && !isRefresh) return Promise.resolve()
|
||||
urlRequest = music[musicInfo.source].getMusicUrl(musicInfo, type)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import music from '../../utils/music'
|
||||
const sortList = {}
|
||||
const sources = []
|
||||
const cache = new Map()
|
||||
for (const source of music.sources) {
|
||||
const songList = music[source.id].songList
|
||||
if (!songList) continue
|
||||
@@ -25,6 +26,7 @@ const state = {
|
||||
page: 1,
|
||||
limit: 30,
|
||||
key: null,
|
||||
info: {},
|
||||
},
|
||||
selectListInfo: {},
|
||||
isVisibleListDetail: false,
|
||||
@@ -60,16 +62,45 @@ const actions = {
|
||||
let tabId = rootState.setting.songList.tagInfo.id
|
||||
let sortId = rootState.setting.songList.sortId
|
||||
// console.log(sortId)
|
||||
let key = `${source}${sortId}${tabId}${page}`
|
||||
if (state.list.list.length && state.list.key == key) return true
|
||||
return music[source].songList.getList(sortId, tabId, page).then(result => commit('setList', { result, key, page }))
|
||||
let key = `slist__${source}__${sortId}__${tabId}__${page}`
|
||||
if (state.list.list.length && state.list.key == key) return
|
||||
return (cache.has(key) ? Promise.resolve(cache.get(key)) : music[source].songList.getList(sortId, tabId, page)).then(result => commit('setList', { result, key, page }))
|
||||
},
|
||||
getListDetail({ state, rootState, commit }, { id, page }) {
|
||||
let source = rootState.setting.songList.source
|
||||
let key = `${source}${id}${page}`
|
||||
let key = `sdetail__${source}__${id}__${page}`
|
||||
if (state.listDetail.list.length && state.listDetail.key == key) return true
|
||||
return music[source].songList.getListDetail(id, page).then(result => commit('setListDetail', { result, key, page }))
|
||||
return (cache.has(key) ? Promise.resolve(cache.get(key)) : music[source].songList.getListDetail(id, page)).then(result => commit('setListDetail', { result, key, page }))
|
||||
},
|
||||
/* getListDetailAll({ state, rootState }, id) {
|
||||
let source = rootState.setting.songList.source
|
||||
let key = `sdetail__${source}__${id}__all`
|
||||
if (cache.has(key)) return Promise.resolve(cache.get(key))
|
||||
music[source].songList.getListDetail(id, 1).then(result => {
|
||||
let data = { list: result.list, id }
|
||||
if (result.total <= result.limit) {
|
||||
data = { list: result.list, id }
|
||||
cache.set(key, data)
|
||||
return data
|
||||
}
|
||||
|
||||
let maxPage = Math.ceil(result.total / result.limit)
|
||||
const loadDetail = (loadPage = 1) => {
|
||||
let task = []
|
||||
let loadNum = 0
|
||||
while (loadPage <= maxPage && loadNum < 3) {
|
||||
task.push(music[source].songList.getListDetail(id, ++loadPage))
|
||||
loadNum++
|
||||
}
|
||||
return loadPage == maxPage
|
||||
? Promise.all(task)
|
||||
: Promise.all(task).then(result => loadDetail(loadPage).then(result2 => [...result, ...result2]))
|
||||
}
|
||||
return loadDetail().then(result2 => {
|
||||
console.log(result2)
|
||||
})
|
||||
})
|
||||
}, */
|
||||
}
|
||||
|
||||
// mitations
|
||||
@@ -83,16 +114,19 @@ const mutations = {
|
||||
state.list.limit = result.limit
|
||||
state.list.page = page
|
||||
state.list.key = key
|
||||
cache.set(key, result)
|
||||
},
|
||||
setListDetail(state, { result, key, page, desc }) {
|
||||
setListDetail(state, { result, key, page }) {
|
||||
state.listDetail.list = result.list
|
||||
state.listDetail.total = result.total
|
||||
state.listDetail.limit = result.limit
|
||||
state.listDetail.page = page
|
||||
state.listDetail.key = key
|
||||
state.listDetail.desc = result.desc
|
||||
state.listDetail.info = result.info || {}
|
||||
cache.set(key, result)
|
||||
},
|
||||
setVisibleListDetail(state, bool) {
|
||||
if (!bool) state.listDetail.list = []
|
||||
state.isVisibleListDetail = bool
|
||||
},
|
||||
setSelectListInfo(state, info) {
|
||||
|
||||
@@ -305,6 +305,24 @@ export const throttle = (fn, delay = 100) => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成防抖函数
|
||||
* @param {*} fn
|
||||
* @param {*} delay
|
||||
*/
|
||||
export const 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)
|
||||
}
|
||||
}
|
||||
|
||||
const async_removeItem = (arr, num, callback) => window.requestAnimationFrame(() => {
|
||||
let len = arr.length
|
||||
if (len > num) {
|
||||
|
||||
@@ -8,7 +8,7 @@ export default {
|
||||
_requestObj_listRecommend: null,
|
||||
_requestObj_listDetail: null,
|
||||
limit_list: 20,
|
||||
limit_song: 25,
|
||||
limit_song: 1000,
|
||||
successCode: 22000,
|
||||
sortList: [
|
||||
{
|
||||
@@ -108,11 +108,12 @@ export default {
|
||||
},
|
||||
|
||||
// 获取标签
|
||||
getTags() {
|
||||
getTags(tryNum = 0) {
|
||||
if (this._requestObj_tags) this._requestObj_tags.cancelHttp()
|
||||
if (tryNum > 2) return Promise.reject(new Error('try max num'))
|
||||
this._requestObj_tags = httpFetch(this.getTagsUrl())
|
||||
return this._requestObj_tags.promise.then(({ body }) => {
|
||||
if (body.error_code !== this.successCode) return this.getTags()
|
||||
if (body.error_code !== this.successCode) return this.getTags(++tryNum)
|
||||
return {
|
||||
hotTag: this.filterInfoHotTag(body.result.hot),
|
||||
tags: this.filterTagInfo(body.result.tags),
|
||||
@@ -141,13 +142,14 @@ export default {
|
||||
},
|
||||
|
||||
// 获取列表数据
|
||||
getList(sortId, tagId, page) {
|
||||
getList(sortId, tagId, page, tryNum = 0) {
|
||||
if (this._requestObj_list) this._requestObj_list.cancelHttp()
|
||||
if (tryNum > 2) return Promise.reject(new Error('try max num'))
|
||||
this._requestObj_list = httpFetch(
|
||||
this.getListUrl(sortId, tagId, page)
|
||||
)
|
||||
return this._requestObj_list.promise.then(({ body }) => {
|
||||
// if (body.error_code !== this.successCode) return this.getList(sortId, tagId, page)
|
||||
if (body.error_code !== this.successCode) return this.getList(sortId, tagId, page, ++tryNum)
|
||||
return {
|
||||
list: this.filterList(body.diyInfo),
|
||||
total: body.nums,
|
||||
@@ -183,13 +185,14 @@ export default {
|
||||
},
|
||||
|
||||
// 获取歌曲列表内的音乐
|
||||
getListDetail(id, page) {
|
||||
getListDetail(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(this.getListDetailUrl(id, page))
|
||||
return this._requestObj_listDetail.promise.then(({ body }) => {
|
||||
if (body.error_code !== this.successCode) return this.getListDetail(id, page)
|
||||
if (body.error_code !== this.successCode) return this.getListDetail(id, page, ++tryNum)
|
||||
let listData = this.filterData(body.result.songlist)
|
||||
return {
|
||||
list: listData,
|
||||
@@ -197,6 +200,13 @@ export default {
|
||||
limit: this.limit_song,
|
||||
total: body.result.song_num,
|
||||
source: 'bd',
|
||||
info: {
|
||||
name: body.result.info.list_title,
|
||||
img: body.result.info.list_pic,
|
||||
desc: body.result.info.list_desc,
|
||||
author: body.result.info.userinfo.username,
|
||||
play_count: this.formatPlayCount(body.result.listen_num),
|
||||
},
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
@@ -37,7 +37,7 @@ export default {
|
||||
requestObj.promise = requestObj.promise.then(({ body }) => {
|
||||
if (body.error_code !== 0) return Promise.reject('图片获取失败')
|
||||
let info = body.data[0].info
|
||||
return info.image.replace('{size}', info.imgsize[0])
|
||||
return info.imgsize ? info.image.replace('{size}', info.imgsize[0]) : info.image
|
||||
})
|
||||
return requestObj
|
||||
},
|
||||
|
||||
@@ -35,6 +35,7 @@ export default {
|
||||
],
|
||||
regExps: {
|
||||
listData: /global\.data = (\[.+\]);/,
|
||||
listInfo: /global = {[\s\S]+?name: "(.+)"[\s\S]+?pic: "(.+)"[\s\S]+?};/,
|
||||
},
|
||||
getInfoUrl(tagId) {
|
||||
return tagId
|
||||
@@ -87,18 +88,20 @@ export default {
|
||||
return result
|
||||
},
|
||||
|
||||
getSongList(sortId, tagId, page) {
|
||||
getSongList(sortId, tagId, page, tryNum = 0) {
|
||||
if (this._requestObj_list) this._requestObj_list.cancelHttp()
|
||||
if (tryNum > 2) return Promise.reject(new Error('try max num'))
|
||||
this._requestObj_list = httpFetch(
|
||||
this.getSongListUrl(sortId, tagId, page)
|
||||
)
|
||||
return this._requestObj_list.promise.then(({ body }) => {
|
||||
if (body.status !== 1) return this.getSongList(sortId, tagId, page)
|
||||
if (body.status !== 1) return this.getSongList(sortId, tagId, page, ++tryNum)
|
||||
return this.filterList(body.special_db)
|
||||
})
|
||||
},
|
||||
getSongListRecommend() {
|
||||
getSongListRecommend(tryNum = 0) {
|
||||
if (this._requestObj_listRecommend) this._requestObj_listRecommend.cancelHttp()
|
||||
if (tryNum > 2) return Promise.reject(new Error('try max num'))
|
||||
this._requestObj_listRecommend = httpFetch(
|
||||
'http://everydayrec.service.kugou.com/guess_special_recommend',
|
||||
{
|
||||
@@ -120,7 +123,7 @@ export default {
|
||||
}
|
||||
)
|
||||
return this._requestObj_listRecommend.promise.then(({ body }) => {
|
||||
if (body.status !== 1) return this.getSongListRecommend()
|
||||
if (body.status !== 1) return this.getSongListRecommend(++tryNum)
|
||||
return this.filterList(body.data.special_list)
|
||||
})
|
||||
},
|
||||
@@ -138,18 +141,34 @@ export default {
|
||||
}))
|
||||
},
|
||||
|
||||
getListDetail(id, page) { // 获取歌曲列表内的音乐
|
||||
getListDetail(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(this.getSongListDetailUrl(id))
|
||||
return this._requestObj_listDetail.promise.then(({ body }) => {
|
||||
let listData = body.match(this.regExps.listData)
|
||||
if (listData) listData = this.filterData(JSON.parse(RegExp.$1))
|
||||
let listInfo = body.match(this.regExps.listInfo)
|
||||
if (!listData) return this.getListDetail(id, page, ++tryNum)
|
||||
listData = this.filterData(JSON.parse(listData[1]))
|
||||
let name
|
||||
let pic
|
||||
if (listInfo) {
|
||||
name = listInfo[1]
|
||||
pic = listInfo[2]
|
||||
}
|
||||
return {
|
||||
list: listData,
|
||||
page: 1,
|
||||
limit: 10000,
|
||||
total: listData.length,
|
||||
source: 'kg',
|
||||
info: {
|
||||
name,
|
||||
img: pic,
|
||||
// desc: body.result.info.list_desc,
|
||||
// author: body.result.info.userinfo.username,
|
||||
// play_count: this.formatPlayCount(body.result.listen_num),
|
||||
},
|
||||
}
|
||||
})
|
||||
},
|
||||
@@ -209,11 +228,12 @@ export default {
|
||||
},
|
||||
|
||||
// 获取列表信息
|
||||
getListInfo(tagId) {
|
||||
getListInfo(tagId, tryNum = 0) {
|
||||
if (this._requestObj_listInfo) this._requestObj_listInfo.cancelHttp()
|
||||
if (tryNum > 2) return Promise.reject(new Error('try max num'))
|
||||
this._requestObj_listInfo = httpFetch(this.getInfoUrl(tagId))
|
||||
return this._requestObj_listInfo.promise.then(({ body }) => {
|
||||
if (body.status !== 1) return this.getListInfo(tagId)
|
||||
if (body.status !== 1) return this.getListInfo(tagId, ++tryNum)
|
||||
return {
|
||||
limit: body.data.params.pagesize,
|
||||
page: body.data.params.p,
|
||||
@@ -246,11 +266,12 @@ export default {
|
||||
},
|
||||
|
||||
// 获取标签
|
||||
getTags() {
|
||||
getTags(tryNum = 0) {
|
||||
if (this._requestObj_tags) this._requestObj_tags.cancelHttp()
|
||||
if (tryNum > 2) return Promise.reject(new Error('try max num'))
|
||||
this._requestObj_tags = httpFetch(this.getInfoUrl())
|
||||
return this._requestObj_tags.promise.then(({ body }) => {
|
||||
if (body.status !== 1) return this.getTags()
|
||||
if (body.status !== 1) return this.getTags(++tryNum)
|
||||
return {
|
||||
hotTag: this.filterInfoHotTag(body.data.hotTag),
|
||||
tags: this.filterTagInfo(body.data.tagids),
|
||||
|
||||
@@ -8,7 +8,7 @@ export default {
|
||||
_requestObj_list: null,
|
||||
_requestObj_listDetail: null,
|
||||
limit_list: 25,
|
||||
limit_song: 100,
|
||||
limit_song: 1000,
|
||||
successCode: 200,
|
||||
sortList: [
|
||||
{
|
||||
@@ -38,20 +38,22 @@ export default {
|
||||
|
||||
// http://nplserver.kuwo.cn/pl.svc?op=getlistinfo&pid=2849349915&pn=0&rn=100&encode=utf8&keyset=pl2012&identity=kuwo&pcmp4=1&vipver=MUSIC_9.0.5.0_W1&newver=1
|
||||
// 获取标签
|
||||
getTag() {
|
||||
getTag(tryNum = 0) {
|
||||
if (this._requestObj_tags) this._requestObj_tags.cancelHttp()
|
||||
if (tryNum > 2) return Promise.reject(new Error('try max num'))
|
||||
this._requestObj_tags = httpFetch(this.tagsUrl)
|
||||
return this._requestObj_tags.promise.then(({ body }) => {
|
||||
if (body.code !== this.successCode) return this.getTag()
|
||||
if (body.code !== this.successCode) return this.getTag(++tryNum)
|
||||
return this.filterTagInfo(body.data)
|
||||
})
|
||||
},
|
||||
// 获取标签
|
||||
getHotTag() {
|
||||
getHotTag(tryNum = 0) {
|
||||
if (this._requestObj_hotTags) this._requestObj_hotTags.cancelHttp()
|
||||
if (tryNum > 2) return Promise.reject(new Error('try max num'))
|
||||
this._requestObj_hotTags = httpFetch(this.hotTagUrl)
|
||||
return this._requestObj_hotTags.promise.then(({ body }) => {
|
||||
if (body.code !== this.successCode) return this.getHotTag()
|
||||
if (body.code !== this.successCode) return this.getHotTag(++tryNum)
|
||||
return this.filterInfoHotTag(body.data[0].data)
|
||||
})
|
||||
},
|
||||
@@ -76,8 +78,9 @@ export default {
|
||||
},
|
||||
|
||||
// 获取列表数据
|
||||
getList(sortId, tagId, page) {
|
||||
getList(sortId, tagId, page, tryNum = 0) {
|
||||
if (this._requestObj_list) this._requestObj_list.cancelHttp()
|
||||
if (tryNum > 2) return Promise.reject(new Error('try max num'))
|
||||
let id
|
||||
let type
|
||||
if (tagId) {
|
||||
@@ -90,7 +93,7 @@ export default {
|
||||
this._requestObj_list = httpFetch(this.getListUrl({ sortId, id, type, page }))
|
||||
return this._requestObj_list.promise.then(({ body }) => {
|
||||
if (!id || type == '10000') {
|
||||
if (body.code !== this.successCode) return this.getListUrl({ sortId, id, type, page })
|
||||
if (body.code !== this.successCode) return this.getList(sortId, id, type, page, ++tryNum)
|
||||
return {
|
||||
list: this.filterList(body.data.data),
|
||||
total: body.data.total,
|
||||
@@ -99,7 +102,7 @@ export default {
|
||||
source: 'kw',
|
||||
}
|
||||
} else if (!body.length) {
|
||||
return this.getListUrl({ sortId, id, type, page })
|
||||
return this.getList(sortId, id, type, page, ++tryNum)
|
||||
}
|
||||
return {
|
||||
list: this.filterList2(body),
|
||||
@@ -153,19 +156,27 @@ export default {
|
||||
},
|
||||
|
||||
// 获取歌曲列表内的音乐
|
||||
getListDetail(id, page) {
|
||||
getListDetail(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(this.getListDetailUrl(id, page))
|
||||
return this._requestObj_listDetail.promise.then(({ body }) => {
|
||||
if (body.result !== 'ok') return this.getListDetail(id, page)
|
||||
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),
|
||||
},
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
@@ -6,7 +6,7 @@ export default {
|
||||
_requestObj_list: null,
|
||||
_requestObj_listDetail: null,
|
||||
limit_list: 10,
|
||||
limit_song: 100,
|
||||
limit_song: 1000,
|
||||
successCode: '000000',
|
||||
sortList: [
|
||||
{
|
||||
@@ -55,17 +55,26 @@ export default {
|
||||
return num
|
||||
},
|
||||
|
||||
getListDetail(id, page) { // 获取歌曲列表内的音乐
|
||||
getListDetail(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(this.getSongListDetailUrl(id, page), { headers: this.defaultHeaders })
|
||||
return this._requestObj_listDetail.promise.then(({ body }) => {
|
||||
if (body.code !== this.successCode) return this.getListDetail(id, page)
|
||||
if (body.code !== this.successCode) return this.getListDetail(id, page, ++tryNum)
|
||||
// console.log(JSON.stringify(body))
|
||||
return {
|
||||
list: this.filterListDetail(body.list),
|
||||
page,
|
||||
limit: this.limit_song,
|
||||
total: body.totalCount,
|
||||
source: 'mg',
|
||||
info: {
|
||||
// name: body.result.info.list_title,
|
||||
// img: body.result.info.list_pic,
|
||||
// desc: body.result.info.list_desc,
|
||||
// author: body.result.info.userinfo.username,
|
||||
// play_count: this.formatPlayCount(body.result.listen_num),
|
||||
},
|
||||
}
|
||||
})
|
||||
},
|
||||
@@ -127,8 +136,9 @@ export default {
|
||||
},
|
||||
|
||||
// 获取列表数据
|
||||
getList(sortId, tagId, page) {
|
||||
getList(sortId, tagId, page, tryNum = 0) {
|
||||
if (this._requestObj_list) this._requestObj_list.cancelHttp()
|
||||
if (tryNum > 2) return Promise.reject(new Error('try max num'))
|
||||
this._requestObj_list = httpFetch(this.getSongListUrl(sortId, tagId, page))
|
||||
// return this._requestObj_list.promise.then(({ statusCode, body }) => {
|
||||
// if (statusCode !== 200) return this.getList(sortId, tagId, page)
|
||||
@@ -150,7 +160,7 @@ export default {
|
||||
// })
|
||||
// })
|
||||
return this._requestObj_list.promise.then(({ body }) => {
|
||||
if (body.retCode !== '100000' || body.retMsg.code !== this.successCode) return this.getList(sortId, tagId, page)
|
||||
if (body.retCode !== '100000' || body.retMsg.code !== this.successCode) return this.getList(sortId, tagId, page, ++tryNum)
|
||||
return {
|
||||
list: this.filterList(body.retMsg.playlist),
|
||||
total: parseInt(body.retMsg.countSize),
|
||||
@@ -175,11 +185,12 @@ export default {
|
||||
},
|
||||
|
||||
// 获取标签
|
||||
getTag() {
|
||||
getTag(tryNum = 0) {
|
||||
if (this._requestObj_tags) this._requestObj_tags.cancelHttp()
|
||||
if (tryNum > 2) return Promise.reject(new Error('try max num'))
|
||||
this._requestObj_tags = httpFetch(this.tagsUrl, { headers: this.defaultHeaders })
|
||||
return this._requestObj_tags.promise.then(({ body }) => {
|
||||
if (body.code !== this.successCode) return this.getTag()
|
||||
if (body.code !== this.successCode) return this.getTag(++tryNum)
|
||||
return this.filterTagInfo(body.columnInfo.contents)
|
||||
})
|
||||
},
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { httpFetch } from '../../request'
|
||||
import { formatPlayTime, sizeFormate } from '../../index'
|
||||
import jshtmlencode from 'js-htmlencode'
|
||||
|
||||
export default {
|
||||
_requestObj_tags: null,
|
||||
@@ -36,7 +37,7 @@ export default {
|
||||
category_id: id,
|
||||
size: this.limit_list,
|
||||
page: page - 1,
|
||||
use_page: page - 1,
|
||||
use_page: 1,
|
||||
},
|
||||
module: 'playlist.PlayListCategoryServer',
|
||||
},
|
||||
@@ -44,7 +45,7 @@ export default {
|
||||
comm: { cv: 1602, ct: 20 },
|
||||
playlist: {
|
||||
method: 'get_playlist_by_tag',
|
||||
param: { id: 10000000, sin: 0, size: this.limit_list, order: sortId, cur_page: page },
|
||||
param: { id: 10000000, sin: this.limit_list * (page - 1), size: this.limit_list, order: sortId, cur_page: page },
|
||||
module: 'playlist.PlayListPlazaServer',
|
||||
},
|
||||
}))}`
|
||||
@@ -55,20 +56,22 @@ export default {
|
||||
|
||||
// http://nplserver.kuwo.cn/pl.svc?op=getlistinfo&pid=2849349915&pn=0&rn=100&encode=utf8&keyset=pl2012&identity=kuwo&pcmp4=1&vipver=MUSIC_9.0.5.0_W1&newver=1
|
||||
// 获取标签
|
||||
getTag() {
|
||||
getTag(tryNum = 0) {
|
||||
if (this._requestObj_tags) this._requestObj_tags.cancelHttp()
|
||||
if (tryNum > 2) return Promise.reject(new Error('try max num'))
|
||||
this._requestObj_tags = httpFetch(this.tagsUrl)
|
||||
return this._requestObj_tags.promise.then(({ body }) => {
|
||||
if (body.code !== this.successCode) return this.getTag()
|
||||
if (body.code !== this.successCode) return this.getTag(++tryNum)
|
||||
return this.filterTagInfo(body.tags.data.v_group)
|
||||
})
|
||||
},
|
||||
// 获取标签
|
||||
getHotTag() {
|
||||
getHotTag(tryNum = 0) {
|
||||
if (this._requestObj_hotTags) this._requestObj_hotTags.cancelHttp()
|
||||
if (tryNum > 2) return Promise.reject(new Error('try max num'))
|
||||
this._requestObj_hotTags = httpFetch(this.hotTagUrl)
|
||||
return this._requestObj_hotTags.promise.then(({ statusCode, body }) => {
|
||||
if (statusCode !== 200) return this.getHotTag()
|
||||
if (statusCode !== 200) return this.getHotTag(++tryNum)
|
||||
return this.filterInfoHotTag(body)
|
||||
})
|
||||
},
|
||||
@@ -102,13 +105,14 @@ export default {
|
||||
},
|
||||
|
||||
// 获取列表数据
|
||||
getList(sortId, tagId, page) {
|
||||
getList(sortId, tagId, page, tryNum = 0) {
|
||||
if (this._requestObj_list) this._requestObj_list.cancelHttp()
|
||||
if (tryNum > 2) return Promise.reject(new Error('try max num'))
|
||||
this._requestObj_list = httpFetch(
|
||||
this.getListUrl(sortId, tagId, page)
|
||||
)
|
||||
return this._requestObj_list.promise.then(({ body }) => {
|
||||
if (body.code !== this.successCode) return this.getList(sortId, tagId, page)
|
||||
if (body.code !== this.successCode) return this.getList(sortId, tagId, page, ++tryNum)
|
||||
return tagId ? this.filterList2(body.playlist.data, page) : this.filterList(body.playlist.data, page)
|
||||
})
|
||||
},
|
||||
@@ -153,7 +157,7 @@ export default {
|
||||
// time: basic.publish_time,
|
||||
img: basic.cover.medium_url || basic.cover.default_url,
|
||||
// grade: basic.favorcnt / 10,
|
||||
desc: basic.desc.replace(/<br>/g, '\n'),
|
||||
desc: jshtmlencode.htmlDecode(basic.desc).replace(/<br>/g, '\n'),
|
||||
source: 'tx',
|
||||
})),
|
||||
total: content.total_cnt,
|
||||
@@ -164,10 +168,11 @@ export default {
|
||||
},
|
||||
|
||||
// 获取歌曲列表内的音乐
|
||||
getListDetail(id) {
|
||||
getListDetail(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(this.getListDetailUrl(id), {
|
||||
headers: {
|
||||
Origin: 'https://y.qq.com',
|
||||
@@ -175,15 +180,21 @@ export default {
|
||||
},
|
||||
})
|
||||
return this._requestObj_listDetail.promise.then(({ body }) => {
|
||||
if (body.code !== this.successCode) return this.getListDetail(id)
|
||||
if (body.code !== this.successCode) return this.getListDetail(id, ++tryNum)
|
||||
const cdlist = body.cdlist[0]
|
||||
return {
|
||||
list: this.filterListDetail(cdlist.songlist),
|
||||
page: 1,
|
||||
limit: cdlist.songlist.length + 1,
|
||||
total: cdlist.songlist.length,
|
||||
desc: cdlist.desc.replace(/<br>/g, '\n'),
|
||||
source: 'tx',
|
||||
info: {
|
||||
name: cdlist.dissname,
|
||||
img: cdlist.logo,
|
||||
desc: jshtmlencode.htmlDecode(cdlist.desc).replace(/<br>/g, '\n'),
|
||||
author: cdlist.nickname,
|
||||
play_count: this.formatPlayCount(cdlist.visitnum),
|
||||
},
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
import { httpFatch } from '../../request'
|
||||
import { requestMsg } from '../../message'
|
||||
import { headers, timeout } from '../options'
|
||||
|
||||
const api_messoer = {
|
||||
getMusicUrl(songInfo, type) {
|
||||
const requestObj = httpFatch(`https://v1.itooi.cn/netease/url?id=${songInfo.songmid}&quality=${type.replace(/k$/, '')}&isRedirect=0`, {
|
||||
method: 'get',
|
||||
timeout,
|
||||
headers,
|
||||
})
|
||||
requestObj.promise = requestObj.promise.then(({ body }) => {
|
||||
return body.code === 200 ? Promise.resolve({ type, url: body.data }) : Promise.reject(new Error(requestMsg.fail))
|
||||
})
|
||||
return requestObj
|
||||
},
|
||||
getPic(songInfo) {
|
||||
const requestObj = httpFatch(`https://v1.itooi.cn/netease/pic?id=${songInfo.songmid}&isRedirect=0`, {
|
||||
method: 'get',
|
||||
timeout,
|
||||
headers,
|
||||
})
|
||||
requestObj.promise = requestObj.promise.then(({ body }) => {
|
||||
return body.code === 200 ? Promise.resolve(body.data) : Promise.reject(new Error(requestMsg.fail))
|
||||
})
|
||||
return requestObj
|
||||
},
|
||||
getLyric(songInfo) {
|
||||
const requestObj = httpFatch(`https://v1.itooi.cn/netease/lrc?id=${songInfo.songmid}&isRedirect=0`, {
|
||||
method: 'get',
|
||||
timeout,
|
||||
headers,
|
||||
})
|
||||
requestObj.promise = requestObj.promise.then(({ body }) => {
|
||||
return body ? Promise.resolve(body) : Promise.reject(new Error(requestMsg.fail))
|
||||
})
|
||||
return requestObj
|
||||
},
|
||||
}
|
||||
|
||||
export default api_messoer
|
||||
@@ -15,8 +15,8 @@ const api_test = {
|
||||
})
|
||||
return requestObj
|
||||
},
|
||||
getPic(songInfo) {
|
||||
const requestObj = httpFetch(`http://ts.tempmusic.tk/pic/wy/${songInfo.songmid}`, {
|
||||
/* getPic(songInfo) {
|
||||
const requestObj = httpFetch(`http://localhost:3100/pic/wy/${songInfo.songmid}`, {
|
||||
method: 'get',
|
||||
timeout,
|
||||
headers,
|
||||
@@ -28,7 +28,7 @@ const api_test = {
|
||||
return requestObj
|
||||
},
|
||||
getLyric(songInfo) {
|
||||
const requestObj = httpFetch(`http://ts.tempmusic.tk/lrc/wy/${songInfo.songmid}`, {
|
||||
const requestObj = httpFetch(`http://localhost:3100/lrc/wy/${songInfo.songmid}`, {
|
||||
method: 'get',
|
||||
timeout,
|
||||
headers,
|
||||
@@ -38,7 +38,7 @@ const api_test = {
|
||||
return body.code === 0 ? Promise.resolve(body.data) : Promise.reject(new Error(requestMsg.fail))
|
||||
})
|
||||
return requestObj
|
||||
},
|
||||
}, */
|
||||
}
|
||||
|
||||
export default api_test
|
||||
|
||||
@@ -1,16 +1,22 @@
|
||||
import leaderboard from './leaderboard'
|
||||
import api_source from '../api-source'
|
||||
import getLyric from './lyric'
|
||||
import getMusicInfo from './musicInfo'
|
||||
import musicSearch from './musicSearch'
|
||||
import songList from './songList'
|
||||
|
||||
const wy = {
|
||||
leaderboard,
|
||||
musicSearch,
|
||||
songList,
|
||||
getMusicUrl(songInfo, type) {
|
||||
return api_source('wy').getMusicUrl(songInfo, type)
|
||||
},
|
||||
getLyric(songInfo) {
|
||||
return api_source('wy').getLyric(songInfo)
|
||||
return getLyric(songInfo.songmid)
|
||||
},
|
||||
getPic(songInfo) {
|
||||
return api_source('wy').getPic(songInfo)
|
||||
return getMusicInfo(songInfo.songmid).then(info => info.al.picUrl)
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
21
src/renderer/utils/music/wy/lyric.js
Normal file
21
src/renderer/utils/music/wy/lyric.js
Normal file
@@ -0,0 +1,21 @@
|
||||
import { httpFetch } from '../../request'
|
||||
import { weapi } from './utils/crypto'
|
||||
|
||||
export default songmid => {
|
||||
const requestObj = httpFetch('http://music.163.com/weapi/song/lyric?csrf_token=', {
|
||||
method: 'post',
|
||||
headers: {
|
||||
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36',
|
||||
Referer: 'https://music.163.com/song?id=' + songmid,
|
||||
origin: 'https://music.163.com',
|
||||
},
|
||||
form: weapi({ id: songmid, lv: -1, tv: -1, csrf_token: '' }),
|
||||
})
|
||||
requestObj.promise = requestObj.promise.then(({ body }) => {
|
||||
// console.log(body)
|
||||
if (body.code !== 200) return Promise.reject('获取歌词失败')
|
||||
return body.lrc.lyric
|
||||
})
|
||||
return requestObj
|
||||
}
|
||||
|
||||
25
src/renderer/utils/music/wy/musicInfo.js
Normal file
25
src/renderer/utils/music/wy/musicInfo.js
Normal file
@@ -0,0 +1,25 @@
|
||||
// https://github.com/Binaryify/NeteaseCloudMusicApi/blob/master/module/song_detail.js
|
||||
import { httpFetch } from '../../request'
|
||||
import { weapi } from './utils/crypto'
|
||||
|
||||
export default songmid => {
|
||||
const requestObj = httpFetch('https://music.163.com/weapi/v3/song/detail', {
|
||||
method: 'post',
|
||||
headers: {
|
||||
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36',
|
||||
Referer: 'https://music.163.com/song?id=' + songmid,
|
||||
origin: 'https://music.163.com',
|
||||
},
|
||||
form: weapi({
|
||||
c: `[{"id":${songmid}}]`,
|
||||
ids: `[${songmid}]`,
|
||||
}),
|
||||
})
|
||||
requestObj.promise = requestObj.promise.then(({ body }) => {
|
||||
// console.log(body)
|
||||
if (body.code !== 200 || !body.songs.length) return Promise.reject('获取歌曲信息失败')
|
||||
return body.songs[0]
|
||||
})
|
||||
return requestObj
|
||||
}
|
||||
|
||||
102
src/renderer/utils/music/wy/musicSearch.js
Normal file
102
src/renderer/utils/music/wy/musicSearch.js
Normal file
@@ -0,0 +1,102 @@
|
||||
import { httpFetch } from '../../request'
|
||||
import { weapi } from './utils/crypto'
|
||||
import { sizeFormate, formatPlayTime } from '../../index'
|
||||
|
||||
let searchRequest
|
||||
export default {
|
||||
limit: 30,
|
||||
total: 0,
|
||||
page: 0,
|
||||
allPage: 1,
|
||||
musicSearch(str, page) {
|
||||
if (searchRequest && searchRequest.cancelHttp) searchRequest.cancelHttp()
|
||||
searchRequest = httpFetch('http://music.163.com/weapi/cloudsearch/get/web?csrf_token=', {
|
||||
method: 'post',
|
||||
form: weapi({
|
||||
s: str,
|
||||
type: 1, // 1: 单曲, 10: 专辑, 100: 歌手, 1000: 歌单, 1002: 用户, 1004: MV, 1006: 歌词, 1009: 电台, 1014: 视频
|
||||
limit: this.limit,
|
||||
offset: this.limit * (page - 1),
|
||||
}),
|
||||
})
|
||||
return searchRequest.promise.then(({ body }) => body)
|
||||
},
|
||||
getSinger(singers) {
|
||||
let arr = []
|
||||
singers.forEach(singer => {
|
||||
arr.push(singer.name)
|
||||
})
|
||||
return arr.join('、')
|
||||
},
|
||||
handleResult(rawList) {
|
||||
// console.log(rawList)
|
||||
return rawList.map(item => {
|
||||
const types = []
|
||||
const _types = {}
|
||||
let size
|
||||
switch (item.privilege.maxbr) {
|
||||
case 999000:
|
||||
size = null
|
||||
types.push({ type: 'flac', size })
|
||||
_types.flac = {
|
||||
size,
|
||||
}
|
||||
case 320000:
|
||||
if (item.h) {
|
||||
size = sizeFormate(item.h.size)
|
||||
types.push({ type: '320k', size })
|
||||
_types['320k'] = {
|
||||
size,
|
||||
}
|
||||
}
|
||||
case 128000:
|
||||
if (item.l) {
|
||||
size = sizeFormate(item.l.size)
|
||||
types.push({ type: '128k', size })
|
||||
_types['128k'] = {
|
||||
size,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
types.reverse()
|
||||
|
||||
return {
|
||||
singer: this.getSinger(item.ar),
|
||||
name: item.name,
|
||||
albumName: item.al.name,
|
||||
albumId: item.al.id,
|
||||
source: 'wy',
|
||||
interval: formatPlayTime(item.dt / 1000),
|
||||
songmid: item.id,
|
||||
img: item.al.picUrl,
|
||||
lrc: null,
|
||||
types,
|
||||
_types,
|
||||
typeUrl: {},
|
||||
}
|
||||
})
|
||||
},
|
||||
search(str, page = 1, { limit } = {}) {
|
||||
if (limit != null) this.limit = limit
|
||||
return this.musicSearch(str, page).then(result => {
|
||||
// console.log(JSON.stringify(result))
|
||||
if (!result || result.code !== 200) return this.search(str, page, { limit })
|
||||
let list = this.handleResult(result.result.songs)
|
||||
|
||||
if (list == null) return this.search(str, page, { limit })
|
||||
|
||||
this.total = result.result.songCount
|
||||
this.page = page
|
||||
this.allPage = Math.ceil(this.total / this.limit)
|
||||
|
||||
return Promise.resolve({
|
||||
list,
|
||||
allPage: this.allPage,
|
||||
limit: this.limit,
|
||||
total: this.total,
|
||||
source: 'wy',
|
||||
})
|
||||
})
|
||||
},
|
||||
}
|
||||
242
src/renderer/utils/music/wy/songList.js
Normal file
242
src/renderer/utils/music/wy/songList.js
Normal file
@@ -0,0 +1,242 @@
|
||||
// https://github.com/Binaryify/NeteaseCloudMusicApi/blob/master/module/playlist_catlist.js
|
||||
// https://github.com/Binaryify/NeteaseCloudMusicApi/blob/master/module/playlist_hot.js
|
||||
// https://github.com/Binaryify/NeteaseCloudMusicApi/blob/master/module/top_playlist.js
|
||||
// https://github.com/Binaryify/NeteaseCloudMusicApi/blob/master/module/playlist_detail.js
|
||||
|
||||
import { weapi, linuxapi } from './utils/crypto'
|
||||
import { httpFetch } from '../../request'
|
||||
import { formatPlayTime, sizeFormate } from '../../index'
|
||||
|
||||
export default {
|
||||
_requestObj_tags: null,
|
||||
_requestObj_hotTags: null,
|
||||
_requestObj_list: null,
|
||||
_requestObj_listDetail: null,
|
||||
limit_list: 30,
|
||||
limit_song: 100000,
|
||||
successCode: 200,
|
||||
sortList: [
|
||||
{
|
||||
name: '最热',
|
||||
id: 'hot',
|
||||
},
|
||||
{
|
||||
name: '最新',
|
||||
id: 'new',
|
||||
},
|
||||
],
|
||||
/**
|
||||
* 格式化播放数量
|
||||
* @param {*} num
|
||||
*/
|
||||
formatPlayCount(num) {
|
||||
if (num > 100000000) return parseInt(num / 10000000) / 10 + '亿'
|
||||
if (num > 10000) return parseInt(num / 1000) / 10 + '万'
|
||||
return num
|
||||
},
|
||||
getSinger(singers) {
|
||||
let arr = []
|
||||
singers.forEach(singer => {
|
||||
arr.push(singer.name)
|
||||
})
|
||||
return arr.join('、')
|
||||
},
|
||||
|
||||
getListDetail(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('https://music.163.com/api/linux/forward', {
|
||||
method: 'post',
|
||||
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36',
|
||||
form: linuxapi({
|
||||
method: 'POST',
|
||||
url: 'https://music.163.com/api/v3/playlist/detail',
|
||||
params: {
|
||||
id,
|
||||
n: this.limit_song,
|
||||
s: 8,
|
||||
},
|
||||
}),
|
||||
})
|
||||
return this._requestObj_listDetail.promise.then(({ body }) => {
|
||||
if (body.code !== this.successCode) return this.getListDetail(id, page, ++tryNum)
|
||||
return {
|
||||
list: this.filterListDetail(body),
|
||||
page,
|
||||
limit: this.limit_song,
|
||||
total: body.playlist.tracks.length,
|
||||
source: 'wy',
|
||||
info: {
|
||||
play_count: this.formatPlayCount(body.playlist.playCount),
|
||||
name: body.playlist.name,
|
||||
img: body.playlist.coverImgUrl,
|
||||
desc: body.playlist.description,
|
||||
author: body.playlist.creator.nickname,
|
||||
},
|
||||
}
|
||||
})
|
||||
},
|
||||
filterListDetail({ playlist: { tracks }, privileges }) {
|
||||
// console.log(tracks, privileges)
|
||||
const list = []
|
||||
tracks.forEach((item, index) => {
|
||||
const types = []
|
||||
const _types = {}
|
||||
let size
|
||||
let privilege = privileges[index]
|
||||
if (privilege.id !== item.id) privilege = privileges.find(p => p.id === item.id)
|
||||
if (!privilege) return
|
||||
|
||||
switch (privilege.maxbr) {
|
||||
case 999000:
|
||||
size = null
|
||||
types.push({ type: 'flac', size })
|
||||
_types.flac = {
|
||||
size,
|
||||
}
|
||||
case 320000:
|
||||
if (item.h) {
|
||||
size = sizeFormate(item.h.size)
|
||||
types.push({ type: '320k', size })
|
||||
_types['320k'] = {
|
||||
size,
|
||||
}
|
||||
}
|
||||
case 128000:
|
||||
if (item.l) {
|
||||
size = sizeFormate(item.l.size)
|
||||
types.push({ type: '128k', size })
|
||||
_types['128k'] = {
|
||||
size,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
types.reverse()
|
||||
|
||||
list.push({
|
||||
singer: this.getSinger(item.ar),
|
||||
name: item.name,
|
||||
albumName: item.al.name,
|
||||
albumId: item.al.id,
|
||||
source: 'wy',
|
||||
interval: formatPlayTime(item.dt / 1000),
|
||||
songmid: item.id,
|
||||
img: item.al.picUrl,
|
||||
lrc: null,
|
||||
types,
|
||||
_types,
|
||||
typeUrl: {},
|
||||
})
|
||||
})
|
||||
return list
|
||||
},
|
||||
|
||||
// 获取列表数据
|
||||
getList(sortId, tagId, page, tryNum = 0) {
|
||||
if (tryNum > 2) return Promise.reject(new Error('try max num'))
|
||||
if (this._requestObj_list) this._requestObj_list.cancelHttp()
|
||||
this._requestObj_list = httpFetch('https://music.163.com/weapi/playlist/list', {
|
||||
method: 'post',
|
||||
form: weapi({
|
||||
cat: tagId || '全部', // 全部,华语,欧美,日语,韩语,粤语,小语种,流行,摇滚,民谣,电子,舞曲,说唱,轻音乐,爵士,乡村,R&B/Soul,古典,民族,英伦,金属,朋克,蓝调,雷鬼,世界音乐,拉丁,另类/独立,New Age,古风,后摇,Bossa Nova,清晨,夜晚,学习,工作,午休,下午茶,地铁,驾车,运动,旅行,散步,酒吧,怀旧,清新,浪漫,性感,伤感,治愈,放松,孤独,感动,兴奋,快乐,安静,思念,影视原声,ACG,儿童,校园,游戏,70后,80后,90后,网络歌曲,KTV,经典,翻唱,吉他,钢琴,器乐,榜单,00后
|
||||
order: sortId, // hot,new
|
||||
limit: this.limit_list,
|
||||
offset: this.limit_list * (page - 1),
|
||||
total: true,
|
||||
}),
|
||||
})
|
||||
return this._requestObj_list.promise.then(({ body }) => {
|
||||
// console.log(JSON.stringify(body))
|
||||
if (body.code !== this.successCode) return this.getList(sortId, tagId, page, ++tryNum)
|
||||
return {
|
||||
list: this.filterList(body.playlists),
|
||||
total: parseInt(body.total),
|
||||
page,
|
||||
limit: this.limit_list,
|
||||
source: 'wy',
|
||||
}
|
||||
})
|
||||
},
|
||||
filterList(rawData) {
|
||||
return rawData.map(item => ({
|
||||
play_count: this.formatPlayCount(item.playCount),
|
||||
id: item.id,
|
||||
author: item.creator.nickname,
|
||||
name: item.name,
|
||||
time: item.createTime,
|
||||
img: item.coverImgUrl,
|
||||
grade: item.grade,
|
||||
desc: item.description,
|
||||
source: 'wy',
|
||||
}))
|
||||
},
|
||||
|
||||
// 获取标签
|
||||
getTag(tryNum = 0) {
|
||||
if (this._requestObj_tags) this._requestObj_tags.cancelHttp()
|
||||
if (tryNum > 2) return Promise.reject(new Error('try max num'))
|
||||
this._requestObj_tags = httpFetch('https://music.163.com/weapi/playlist/catalogue', {
|
||||
method: 'post',
|
||||
form: weapi({}),
|
||||
})
|
||||
return this._requestObj_tags.promise.then(({ body }) => {
|
||||
// console.log(JSON.stringify(body))
|
||||
if (body.code !== this.successCode) return this.getTag(++tryNum)
|
||||
return this.filterTagInfo(body)
|
||||
})
|
||||
},
|
||||
filterTagInfo({ sub, categories }) {
|
||||
const subList = {}
|
||||
for (const item of sub) {
|
||||
if (!subList[item.category]) subList[item.category] = []
|
||||
subList[item.category].push({
|
||||
parent_id: categories[item.category],
|
||||
parent_name: categories[item.category],
|
||||
id: item.name,
|
||||
name: item.name,
|
||||
source: 'wy',
|
||||
})
|
||||
}
|
||||
|
||||
const list = []
|
||||
for (const key of Object.keys(categories)) {
|
||||
list.push({
|
||||
name: categories[key],
|
||||
list: subList[key],
|
||||
source: 'wy',
|
||||
})
|
||||
}
|
||||
return list
|
||||
},
|
||||
|
||||
// 获取热门标签
|
||||
getHotTag(tryNum = 0) {
|
||||
if (this._requestObj_hotTags) this._requestObj_hotTags.cancelHttp()
|
||||
if (tryNum > 2) return Promise.reject(new Error('try max num'))
|
||||
this._requestObj_hotTags = httpFetch('https://music.163.com/weapi/playlist/hottags', {
|
||||
method: 'post',
|
||||
form: weapi({}),
|
||||
})
|
||||
return this._requestObj_hotTags.promise.then(({ body }) => {
|
||||
// console.log(JSON.stringify(body))
|
||||
if (body.code !== this.successCode) return this.getTag(++tryNum)
|
||||
return this.filterHotTagInfo(body.tags)
|
||||
})
|
||||
},
|
||||
filterHotTagInfo(rawList) {
|
||||
return rawList.map(item => ({
|
||||
id: item.playlistTag.name,
|
||||
name: item.playlistTag.name,
|
||||
source: 'wy',
|
||||
}))
|
||||
},
|
||||
|
||||
getTags() {
|
||||
return Promise.all([this.getTag(), this.getHotTag()]).then(([tags, hotTag]) => ({ tags, hotTag, source: 'wy' }))
|
||||
},
|
||||
}
|
||||
|
||||
// getList
|
||||
// getTags
|
||||
// getListDetail
|
||||
33
src/renderer/utils/music/wy/utils/crypto.js
Normal file
33
src/renderer/utils/music/wy/utils/crypto.js
Normal file
@@ -0,0 +1,33 @@
|
||||
// https://github.com/Binaryify/NeteaseCloudMusicApi/blob/master/util/crypto.js
|
||||
import { createCipheriv, publicEncrypt, constants, randomBytes } from 'crypto'
|
||||
const iv = Buffer.from('0102030405060708')
|
||||
const presetKey = Buffer.from('0CoJUm6Qyw8W8jud')
|
||||
const linuxapiKey = Buffer.from('rFgB&h#%2?^eDg:Q')
|
||||
const base62 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
|
||||
const publicKey = '-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDgtQn2JZ34ZC28NWYpAUd98iZ37BUrX/aKzmFbt7clFSs6sXqHauqKWqdtLkF2KexO40H1YTX8z2lSgBBOAxLsvaklV8k4cBFK9snQXE9/DDaFt6Rr7iVZMldczhC0JNgTz+SHXT6CBHuX3e9SdB1Ua44oncaTWz7OBGLbCiK45wIDAQAB\n-----END PUBLIC KEY-----'
|
||||
|
||||
const aesEncrypt = (buffer, mode, key, iv) => {
|
||||
const cipher = createCipheriv('aes-128-' + mode, key, iv)
|
||||
return Buffer.concat([cipher.update(buffer), cipher.final()])
|
||||
}
|
||||
|
||||
const rsaEncrypt = (buffer, key) => {
|
||||
buffer = Buffer.concat([Buffer.alloc(128 - buffer.length), buffer])
|
||||
return publicEncrypt({ key: key, padding: constants.RSA_NO_PADDING }, buffer)
|
||||
}
|
||||
|
||||
export const weapi = object => {
|
||||
const text = JSON.stringify(object)
|
||||
const secretKey = randomBytes(16).map(n => (base62.charAt(n % 62).charCodeAt()))
|
||||
return {
|
||||
params: aesEncrypt(Buffer.from(aesEncrypt(Buffer.from(text), 'cbc', presetKey, iv).toString('base64')), 'cbc', secretKey, iv).toString('base64'),
|
||||
encSecKey: rsaEncrypt(secretKey.reverse(), publicKey).toString('hex'),
|
||||
}
|
||||
}
|
||||
|
||||
export const linuxapi = object => {
|
||||
const text = JSON.stringify(object)
|
||||
return {
|
||||
eparams: aesEncrypt(Buffer.from(text), 'ecb', linuxapiKey, '').toString('hex').toUpperCase(),
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ import request from 'request'
|
||||
import { debugRequest } from './env'
|
||||
import { requestMsg } from './message'
|
||||
import { bHh } from './music/options'
|
||||
import { deflateRawSync } from 'zlib'
|
||||
// import fs from 'fs'
|
||||
|
||||
const defaultHeaders = {
|
||||
@@ -222,6 +223,8 @@ const getProxyInfo = () => window.globalObj.proxy.enable
|
||||
? `http://${window.globalObj.proxy.username}:${window.globalObj.proxy.password}@${window.globalObj.proxy.host}:${window.globalObj.proxy.port};`
|
||||
: undefined
|
||||
|
||||
const regx = /(?:\d\w)+/g
|
||||
|
||||
const fetchData = (url, method, {
|
||||
headers = {},
|
||||
format = 'json',
|
||||
@@ -230,11 +233,13 @@ const fetchData = (url, method, {
|
||||
}, callback) => {
|
||||
// console.log(url, options)
|
||||
console.log('---start---', url)
|
||||
headers = Object.assign({}, headers)
|
||||
if (headers[bHh]) {
|
||||
let s = Buffer.from(bHh, 'hex').toString()
|
||||
s = s.replace(s.substr(-1), '')
|
||||
s = Buffer.from(s, 'base64').toString()
|
||||
headers[s] = !s || parseInt(process.versions.app.split('.').map(n => n.length < 3 ? n.padStart(3, '0') : n).join(''))
|
||||
let v = process.versions.app.split('.').map(n => n.length < 3 ? n.padStart(3, '0') : n).join('')
|
||||
headers[s] = !s || `${deflateRawSync(Buffer.from(JSON.stringify(`${url}${v}`.match(regx), null, 1).concat(v)).toString('base64')).toString('hex')}&${parseInt(v)}`
|
||||
delete headers[bHh]
|
||||
}
|
||||
return request(url, {
|
||||
|
||||
@@ -126,6 +126,7 @@ export default {
|
||||
handleAddDownloadMultiple(type) {
|
||||
switch (this.source) {
|
||||
// case 'kg':
|
||||
case 'tx':
|
||||
case 'wy':
|
||||
type = '128k'
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
table
|
||||
tbody
|
||||
tr(v-for='(item, index) in list' :key='item.songmid'
|
||||
@click="handleDoubleClick(index)" :class="[isPlayList && playIndex === index ? $style.active : '', (isAPITemp && item.source != 'kw') || item.source == 'wy' ? $style.disabled : '']")
|
||||
@click="handleDoubleClick(index)" :class="[isPlayList && playIndex === index ? $style.active : '', (isAPITemp && item.source != 'kw') ? $style.disabled : '']")
|
||||
td.nobreak.center(style="width: 37px;" @click.stop)
|
||||
material-checkbox(:id="index.toString()" v-model="selectdData" :value="item")
|
||||
td.break(style="width: 25%;")
|
||||
@@ -218,7 +218,7 @@ export default {
|
||||
this.clickIndex = -1
|
||||
},
|
||||
testPlay(index) {
|
||||
if ((this.isAPITemp && this.list[index].source != 'kw') || this.list[index].source == 'wy') return
|
||||
if (this.isAPITemp && this.list[index].source != 'kw') return
|
||||
this.setPlayList({ list: this.list, listId: this.listId, index })
|
||||
},
|
||||
handleRemove(index) {
|
||||
@@ -228,7 +228,7 @@ export default {
|
||||
switch (info.action) {
|
||||
case 'download': {
|
||||
const minfo = this.list[info.index]
|
||||
if ((this.isAPITemp && minfo.source != 'kw') || minfo.source == 'wy') return
|
||||
if (this.isAPITemp && minfo.source != 'kw') return
|
||||
this.musicInfo = minfo
|
||||
this.$nextTick(() => {
|
||||
this.isShowDownload = true
|
||||
@@ -261,7 +261,7 @@ export default {
|
||||
this.selectdData = []
|
||||
},
|
||||
handleAddDownloadMultiple(type) {
|
||||
const list = this.setting.apiSource == 'temp' ? this.selectdData.filter(s => s.source == 'kw') : this.selectdData.filter(s => s.source != 'wy')
|
||||
const list = this.setting.apiSource == 'temp' ? this.selectdData.filter(s => s.source == 'kw') : [...this.selectdData]
|
||||
this.createDownloadMultiple({ list, type })
|
||||
this.resetSelect()
|
||||
this.isShowDownloadMultiple = false
|
||||
|
||||
@@ -30,8 +30,8 @@
|
||||
td.break(style="width: 25%;") {{item.albumName}}
|
||||
td(style="width: 15%; padding-left: 0; padding-right: 0;")
|
||||
material-list-buttons(:index="index" :remove-btn="false" :class="$style.listBtn"
|
||||
:play-btn="item.source == 'kw' || (!isAPITemp && item.source != 'wy')"
|
||||
:download-btn="item.source == 'kw' || (!isAPITemp && item.source != 'wy')"
|
||||
:play-btn="item.source == 'kw' || !isAPITemp"
|
||||
:download-btn="item.source == 'kw' || !isAPITemp"
|
||||
@btn-click="handleListBtnClick")
|
||||
td(style="width: 10%;") {{item.interval || '--/--'}}
|
||||
div(:class="$style.pagination")
|
||||
@@ -189,7 +189,7 @@ export default {
|
||||
targetSong = this.selectdData[0]
|
||||
this.listAddMultiple({ id: 'default', list: this.filterList(this.selectdData) })
|
||||
} else {
|
||||
if ((this.isAPITemp && this.listInfo.list[index].source != 'kw') || this.listInfo.list[index].source == 'wy') return
|
||||
if (this.isAPITemp && this.listInfo.list[index].source != 'kw') return
|
||||
targetSong = this.listInfo.list[index]
|
||||
this.listAdd({ id: 'default', musicInfo: targetSong })
|
||||
}
|
||||
@@ -238,7 +238,7 @@ export default {
|
||||
}
|
||||
},
|
||||
filterList(list) {
|
||||
return this.setting.apiSource == 'temp' ? list.filter(s => s.source == 'kw') : list.filter(s => s.source != 'wy')
|
||||
return this.setting.apiSource == 'temp' ? list.filter(s => s.source == 'kw') : [...list]
|
||||
},
|
||||
handleListAddModalClose(isSelect) {
|
||||
if (isSelect) this.resetSelect()
|
||||
|
||||
@@ -262,7 +262,7 @@ export default {
|
||||
// },
|
||||
{
|
||||
id: 'test',
|
||||
label: '测试接口(软件的大部分功能可用,该接口访问速度略慢)',
|
||||
label: '测试接口(几乎软件的所有功能都可用,该接口访问速度略慢)',
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,34 +1,45 @@
|
||||
<template lang="pug">
|
||||
div(:class="$style.container")
|
||||
transition(enter-active-class="animated-fast fadeIn" leave-active-class="animated-fast fadeOut")
|
||||
div(:class="$style.songListDetailContent" v-show="isVisibleListDetail")
|
||||
div(:class="$style.songListDetailContent" v-if="isVisibleListDetail")
|
||||
div(:class="$style.songListHeader")
|
||||
div(:class="$style.songListHeaderLeft")
|
||||
img(:src="selectListInfo.img")
|
||||
span(:class="$style.playNum" v-if="selectListInfo.play_count") {{selectListInfo.play_count}}
|
||||
img(:src="listDetail.info.img || selectListInfo.img")
|
||||
span(:class="$style.playNum" v-if="listDetail.info.play_count || selectListInfo.play_count") {{listDetail.info.play_count || selectListInfo.play_count}}
|
||||
div(:class="$style.songListHeaderMiddle")
|
||||
h3(:title="selectListInfo.name") {{selectListInfo.name}}
|
||||
p(:title="selectListInfo.desc") {{listDetail.desc || selectListInfo.desc}}
|
||||
h3(:title="listDetail.info.name || selectListInfo.name") {{listDetail.info.name || selectListInfo.name}}
|
||||
p(:title="listDetail.info.desc || selectListInfo.desc") {{listDetail.info.desc || selectListInfo.desc}}
|
||||
div(:class="$style.songListHeaderRight")
|
||||
//- material-btn(:class="$style.closeDetailButton" :disabled="detailLoading" @click="addSongListDetail") 添加
|
||||
//- |
|
||||
//- material-btn(:class="$style.closeDetailButton" :disabled="detailLoading" @click="playSongListDetail") 播放
|
||||
//- |
|
||||
material-btn(:class="$style.closeDetailButton" @click="hideListDetail") 返回
|
||||
material-song-list(v-model="selectdData" @action="handleSongListAction" :source="source" :page="listDetail.page" :limit="listDetail.limit" :total="listDetail.total" :list="listDetail.list")
|
||||
transition(enter-active-class="animated-fast fadeIn" leave-active-class="animated-fast fadeOut")
|
||||
div(:class="$style.songListContent" v-show="!isVisibleListDetail")
|
||||
div(:class="$style.songListContainer" v-if="!isVisibleListDetail")
|
||||
div(:class="$style.header")
|
||||
material-tag-list(:class="$style.tagList" :list="tagList" v-model="tagInfo")
|
||||
material-tab(:class="$style.tab" :list="sorts" item-key="id" item-name="name" v-model="sortId")
|
||||
material-select(:class="$style.select" :list="sourceInfo.sources" item-key="id" item-name="name" v-model="source")
|
||||
div.scroll(:class="$style.songList" ref="dom_scrollContent")
|
||||
ul
|
||||
li(:class="$style.item" v-for="(item, index) in listData.list" @click="handleItemClick(index)")
|
||||
div(:class="$style.left")
|
||||
img(:src="item.img")
|
||||
div(:class="$style.right" :src="item.img")
|
||||
h4(:title="item.name") {{item.name}}
|
||||
p(:title="item.desc") {{item.desc}}
|
||||
li(:class="$style.item" style="cursor: default;" v-if="listData.list && listData.list.length && listData.list.length % 3 == 2")
|
||||
div(:class="$style.pagination")
|
||||
material-pagination(:count="listData.total" :limit="listData.limit" :page="listData.page" @btn-click="handleToggleListPage")
|
||||
div(:class="$style.songListContent")
|
||||
transition(enter-active-class="animated-fast fadeIn" leave-active-class="animated-fast fadeOut")
|
||||
div.scroll(:class="$style.songList" v-if="sortId !== 'importSongList'" ref="dom_scrollContent")
|
||||
ul
|
||||
li(:class="$style.item" v-for="(item, index) in listData.list" @click="handleItemClick(index)")
|
||||
div(:class="$style.left")
|
||||
img(:src="item.img")
|
||||
div(:class="$style.right" :src="item.img")
|
||||
h4(:title="item.name") {{item.name}}
|
||||
p(:title="item.desc") {{item.desc}}
|
||||
li(:class="$style.item" style="cursor: default;" v-if="listData.list && listData.list.length && listData.list.length % 3 == 2")
|
||||
div(:class="$style.pagination")
|
||||
material-pagination(:count="listData.total" :limit="listData.limit" :page="listData.page" @btn-click="handleToggleListPage")
|
||||
transition(enter-active-class="animated-fast fadeIn" leave-active-class="animated-fast fadeOut")
|
||||
div(:class="$style.importSongListContent" v-show="sortId === 'importSongList'")
|
||||
material-search-input(v-model="importSongListText" @event="handleImportSongListEvent" big placeholder="输入歌单链接或歌单ID")
|
||||
svg(version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' height='100%' viewBox='0 0 451.846 451.847' space='preserve')
|
||||
use(xlink:href='#icon-right')
|
||||
material-download-modal(:show="isShowDownload" :musicInfo="musicInfo" @select="handleAddDownload" @close="isShowDownload = false")
|
||||
material-download-multiple-modal(:show="isShowDownloadMultiple" :list="selectdData" @select="handleAddDownloadMultiple" @close="isShowDownloadMultiple = false")
|
||||
material-list-add-modal(:show="isShowListAdd" :musicInfo="musicInfo" @close="isShowListAdd = false")
|
||||
@@ -56,6 +67,8 @@ export default {
|
||||
isToggleSource: false,
|
||||
isShowListAdd: false,
|
||||
isShowListAddMultiple: false,
|
||||
importSongListText: '',
|
||||
// detailLoading: true,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -63,7 +76,21 @@ export default {
|
||||
...mapGetters('songList', ['sourceInfo', 'tags', 'listData', 'isVisibleListDetail', 'selectListInfo', 'listDetail']),
|
||||
...mapGetters('list', ['defaultList']),
|
||||
sorts() {
|
||||
return this.source ? this.sourceInfo.sortList[this.source] : []
|
||||
let list
|
||||
list = this.source ? [...this.sourceInfo.sortList[this.source]] : []
|
||||
switch (this.source) {
|
||||
case 'wy':
|
||||
case 'kw':
|
||||
case 'bd':
|
||||
case 'tx':
|
||||
case 'mg':
|
||||
case 'kg':
|
||||
list.push({
|
||||
name: `打开${this.sourceInfo.sources.find(s => s.id == this.source).name}歌单`,
|
||||
id: 'importSongList',
|
||||
})
|
||||
}
|
||||
return list
|
||||
},
|
||||
isAPITemp() {
|
||||
return this.setting.apiSource == 'temp'
|
||||
@@ -76,6 +103,7 @@ export default {
|
||||
sortId(n, o) {
|
||||
this.setSongList({ sortId: n })
|
||||
if (o === undefined && this.listData.page !== 1) return
|
||||
if (n == 'importSongList') return
|
||||
this.$nextTick(() => {
|
||||
this.getList(1).then(() => {
|
||||
this.$nextTick(() => {
|
||||
@@ -88,6 +116,7 @@ export default {
|
||||
tagInfo(n, o) {
|
||||
this.setSongList({ tagInfo: n })
|
||||
if (!o && this.listData.page !== 1) return
|
||||
if (this.sortId == 'importSongList') this.sortId = this.sorts[0] && this.sorts[0].id
|
||||
if (this.isToggleSource) {
|
||||
this.isToggleSource = false
|
||||
return
|
||||
@@ -104,6 +133,7 @@ export default {
|
||||
source(n, o) {
|
||||
this.setSongList({ source: n })
|
||||
if (!this.tags[n]) this.getTags()
|
||||
this.importSongListText = ''
|
||||
if (o) {
|
||||
this.isToggleSource = true
|
||||
this.tagInfo = {
|
||||
@@ -200,6 +230,7 @@ export default {
|
||||
handleAddDownloadMultiple(type) {
|
||||
switch (this.source) {
|
||||
// case 'kg':
|
||||
case 'tx':
|
||||
case 'wy':
|
||||
type = '128k'
|
||||
}
|
||||
@@ -208,6 +239,7 @@ export default {
|
||||
this.isShowDownloadMultiple = false
|
||||
},
|
||||
handleItemClick(index) {
|
||||
// this.detailLoading = true
|
||||
this.setSelectListInfo(this.listData.list[index])
|
||||
this.setVisibleListDetail(true)
|
||||
this.clearListDetail()
|
||||
@@ -252,6 +284,76 @@ export default {
|
||||
if (isSelect) this.resetSelect()
|
||||
this.isShowListAddMultiple = false
|
||||
},
|
||||
handleImportSongListEvent({ action }) {
|
||||
switch (action) {
|
||||
case 'submit':
|
||||
this.handleGetSongListDetail()
|
||||
break
|
||||
case 'blur':
|
||||
this.parseImportSongListInputText()
|
||||
break
|
||||
}
|
||||
},
|
||||
handleGetSongListDetail() {
|
||||
this.parseImportSongListInputText()
|
||||
this.setSelectListInfo({
|
||||
play_count: null,
|
||||
id: this.importSongListText,
|
||||
author: '',
|
||||
name: '',
|
||||
img: null,
|
||||
desc: '',
|
||||
source: this.source,
|
||||
})
|
||||
this.clearListDetail()
|
||||
this.$nextTick(() => {
|
||||
this.setVisibleListDetail(true)
|
||||
this.getListDetail({ id: this.importSongListText, page: 1 })
|
||||
})
|
||||
},
|
||||
parseImportSongListInputText() {
|
||||
if (!/[?&:/]/.test(this.importSongListText)) return
|
||||
const text = this.importSongListText
|
||||
let regx
|
||||
switch (this.source) {
|
||||
case 'wy':
|
||||
regx = /^.+(?:\?|&)id=(\d+)(?:&.*$|#.*$|$)/
|
||||
break
|
||||
case 'tx':
|
||||
// https://y.qq.com/n/yqq/playlist/7217720898.html
|
||||
// https://i.y.qq.com/n2/m/share/details/taoge.html?platform=11&appshare=android_qq&appversion=9050006&id=7217720898&ADTAG=qfshare
|
||||
regx = /\/\/i\.y\.qq\.com/.test(text) ? /^.+(?:\?|&)id=(\d+)(?:&.*$|#.*$|$)/ : /^.+\/(\d+)\.html(?:\?.*|&.*$|#.*$|$)/
|
||||
break
|
||||
case 'kw':
|
||||
// http://www.kuwo.cn/playlist_detail/2886046289
|
||||
regx = /^.+\/playlist_detail\/(\d+)(?:\?.*|&.*$|#.*$|$)/
|
||||
break
|
||||
case 'bd':
|
||||
// http://music.taihe.com/songlist/566347741
|
||||
regx = /^.+\/songlist\/(\d+)(?:\?.*|&.*$|#.*$|$)/
|
||||
break
|
||||
case 'mg':
|
||||
// http://music.migu.cn/v3/music/playlist/161044573?page=1
|
||||
regx = /^.+\/playlist\/(\d+)(?:\?.*|&.*$|#.*$|$)/
|
||||
break
|
||||
case 'kg':
|
||||
// https://www.kugou.com/yy/special/single/1067062.html
|
||||
regx = /^.+\/(\d+)\.html(?:\?.*|&.*$|#.*$|$)/
|
||||
break
|
||||
default:
|
||||
return
|
||||
}
|
||||
this.importSongListText = text.replace(regx, '$1')
|
||||
},
|
||||
/* addSongListDetail() {
|
||||
// this.detailLoading = true
|
||||
// this.getListDetailAll(this.selectListInfo.id).then(() => {
|
||||
// this.detailLoading = false
|
||||
// })
|
||||
},
|
||||
playSongListDetail() {
|
||||
|
||||
}, */
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -280,18 +382,28 @@ export default {
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
.songListContent, .song-list-detail-content {
|
||||
.songListContainer, .song-list-detail-content, .songListContent, .importSongListContent {
|
||||
// flex: auto;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.songListContent {
|
||||
.songListContainer, .songListContent, .importSongListContent {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
height: 100%;
|
||||
// position: relative;
|
||||
}
|
||||
|
||||
.importSongListContent {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
padding-top: 20%;
|
||||
}
|
||||
|
||||
.song-list-header {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
|
||||
Reference in New Issue
Block a user