diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7239ede2..d309bd8b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,20 @@ Project versioning adheres to [Semantic Versioning](http://semver.org/).
Commit convention is based on [Conventional Commits](http://conventionalcommits.org).
Change log format is based on [Keep a Changelog](http://keepachangelog.com/).
+## [1.3.0](https://github.com/lyswhut/lx-music-desktop/compare/v1.2.2...v1.3.0) - 2020-11-01
+
+### 新增
+
+- 播放详情页新增歌曲评论加载显示(某些平台暂不支持显示子评论)
+
+### 优化
+
+- 修改播放详情页的歌曲图片的显示效果
+
+### 修复
+
+- 修复小芸源音乐搜索结果最多只有20条搜索结果的问题
+
## [1.2.2](https://github.com/lyswhut/lx-music-desktop/compare/v1.2.1...v1.2.2) - 2020-10-18
### 修复
diff --git a/README.md b/README.md
index 93febdc8..a9d6fd8e 100644
--- a/README.md
+++ b/README.md
@@ -100,7 +100,7 @@ npm run pack:linux
5. 由于使用本项目产生的包括由于本协议或由于使用或无法使用本项目而引起的任何性质的任何直接、间接、特殊、偶然或结果性损害(包括但不限于因商誉损失、停工、计算机故障或故障引起的损害赔偿,或任何及所有其他商业损害或损失)由使用者负责。
6. 本项目完全免费,且开源发布于 GitHub 面向全世界人用作对技术的学习交流,本项目不对项目内的技术可能存在违反当地法律法规的行为作保证,**禁止在违反当地法律法规的情况下使用本项目**,对于使用者在明知或不知当地法律法规不允许的情况下使用本项目所造成的任何违法违规行为由使用者承担,本项目不承担由此造成的任何直接、间接、特殊、偶然或结果性责任。
-若你使用了本项目,将代表你接收以上协议。
+若你使用了本项目,将代表你接受以上协议。
音乐平台不易,请尊重版权,支持正版。
若对此有疑问请 mail to: lyswhut+qq.com (请将`+`替换成`@`)
diff --git a/package-lock.json b/package-lock.json
index 0e5b9c0f..6ee40562 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "lx-music-desktop",
- "version": "1.2.1",
+ "version": "1.3.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -2716,9 +2716,9 @@
}
},
"@eslint/eslintrc": {
- "version": "0.1.3",
- "resolved": "https://registry.npm.taobao.org/@eslint/eslintrc/download/@eslint/eslintrc-0.1.3.tgz?cache=0&sync_timestamp=1598984683755&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40eslint%2Feslintrc%2Fdownload%2F%40eslint%2Feslintrc-0.1.3.tgz",
- "integrity": "sha1-fRorI1hVLMBINMCXm9QnU2LjcIU=",
+ "version": "0.2.1",
+ "resolved": "https://registry.npm.taobao.org/@eslint/eslintrc/download/@eslint/eslintrc-0.2.1.tgz?cache=0&sync_timestamp=1603766307701&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40eslint%2Feslintrc%2Fdownload%2F%40eslint%2Feslintrc-0.2.1.tgz",
+ "integrity": "sha1-9yBpwzBGGgZoTRGThENeEqXXbjw=",
"dev": true,
"requires": {
"ajv": "^6.12.4",
@@ -3009,9 +3009,9 @@
"dev": true
},
"@vue/component-compiler-utils": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/@vue/component-compiler-utils/-/component-compiler-utils-3.1.2.tgz",
- "integrity": "sha512-QLq9z8m79mCinpaEeSURhnNCN6djxpHw0lpP/bodMlt5kALfONpryMthvnrQOlTcIKoF+VoPi+lPHUYeDFPXug==",
+ "version": "3.2.0",
+ "resolved": "https://registry.npm.taobao.org/@vue/component-compiler-utils/download/@vue/component-compiler-utils-3.2.0.tgz",
+ "integrity": "sha1-j4UYLO7Sjps8dTE95mn4MWbRHl0=",
"dev": true,
"requires": {
"consolidate": "^0.15.1",
@@ -3027,8 +3027,8 @@
"dependencies": {
"lru-cache": {
"version": "4.1.5",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
- "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
+ "resolved": "https://registry.npm.taobao.org/lru-cache/download/lru-cache-4.1.5.tgz?cache=0&sync_timestamp=1594427567713&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Flru-cache%2Fdownload%2Flru-cache-4.1.5.tgz",
+ "integrity": "sha1-i75Q6oW+1ZvJ4z3KuCNe6bz0Q80=",
"dev": true,
"requires": {
"pseudomap": "^1.0.2",
@@ -3037,8 +3037,8 @@
},
"source-map": {
"version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.6.1.tgz",
+ "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=",
"dev": true
},
"yallist": {
@@ -5837,8 +5837,8 @@
},
"consolidate": {
"version": "0.15.1",
- "resolved": "https://registry.npmjs.org/consolidate/-/consolidate-0.15.1.tgz",
- "integrity": "sha512-DW46nrsMJgy9kqAbPt5rKaCr7uFtpo4mSUvLHIUbJEjm0vo+aY5QLwBUq3FK4tRnJr/X0Psc0C4jf/h+HtXSMw==",
+ "resolved": "https://registry.npm.taobao.org/consolidate/download/consolidate-0.15.1.tgz?cache=0&sync_timestamp=1599596647062&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fconsolidate%2Fdownload%2Fconsolidate-0.15.1.tgz",
+ "integrity": "sha1-IasEMjXHGgfUXZqtmFk7DbpWurc=",
"dev": true,
"requires": {
"bluebird": "^3.1.1"
@@ -7081,9 +7081,9 @@
}
},
"electron": {
- "version": "9.3.2",
- "resolved": "https://registry.npm.taobao.org/electron/download/electron-9.3.2.tgz?cache=0&sync_timestamp=1602791331702&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Felectron%2Fdownload%2Felectron-9.3.2.tgz",
- "integrity": "sha1-r6KULiZC7iW0IrkPFJf32bvuxVA=",
+ "version": "9.3.3",
+ "resolved": "https://registry.npm.taobao.org/electron/download/electron-9.3.3.tgz",
+ "integrity": "sha1-maZhnV32j5dpel0dgu86imP83zY=",
"dev": true,
"requires": {
"@electron/get": "^1.0.1",
@@ -7092,9 +7092,9 @@
},
"dependencies": {
"@types/node": {
- "version": "12.12.68",
- "resolved": "https://registry.npm.taobao.org/@types/node/download/@types/node-12.12.68.tgz?cache=0&sync_timestamp=1602874228094&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fnode%2Fdownload%2F%40types%2Fnode-12.12.68.tgz",
- "integrity": "sha1-3VrPSlKkWP8dnvT9ZkBvugr7uzM=",
+ "version": "12.19.2",
+ "resolved": "https://registry.npm.taobao.org/@types/node/download/@types/node-12.19.2.tgz",
+ "integrity": "sha1-lWXtXHK6lgOPw63WQ+3V54IFmOc=",
"dev": true
}
}
@@ -7521,13 +7521,13 @@
"dev": true
},
"eslint": {
- "version": "7.11.0",
- "resolved": "https://registry.npm.taobao.org/eslint/download/eslint-7.11.0.tgz",
- "integrity": "sha1-qvLSOgtfHWUqCO2s6gwZ9/rcCzs=",
+ "version": "7.12.1",
+ "resolved": "https://registry.npm.taobao.org/eslint/download/eslint-7.12.1.tgz?cache=0&sync_timestamp=1603768145986&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint%2Fdownload%2Feslint-7.12.1.tgz",
+ "integrity": "sha1-vZqB+memz9UWVs24iBLOSczsWAE=",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
- "@eslint/eslintrc": "^0.1.3",
+ "@eslint/eslintrc": "^0.2.1",
"ajv": "^6.10.0",
"chalk": "^4.0.0",
"cross-spawn": "^7.0.2",
@@ -8060,9 +8060,9 @@
"dev": true
},
"eslint-plugin-standard": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-4.0.1.tgz",
- "integrity": "sha512-v/KBnfyaOMPmZc/dmc6ozOdWqekGp7bBGq4jLAecEfPGmfKiWS4sA8sC0LqiV9w5qmXAtXVn4M3p1jSyhY85SQ==",
+ "version": "4.0.2",
+ "resolved": "https://registry.npm.taobao.org/eslint-plugin-standard/download/eslint-plugin-standard-4.0.2.tgz?cache=0&sync_timestamp=1603323739415&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Feslint-plugin-standard%2Fdownload%2Feslint-plugin-standard-4.0.2.tgz",
+ "integrity": "sha1-AhIRqfB35jpoR+e7mrQkcyesjgw=",
"dev": true
},
"eslint-scope": {
@@ -8629,9 +8629,9 @@
}
},
"file-loader": {
- "version": "6.1.1",
- "resolved": "https://registry.npm.taobao.org/file-loader/download/file-loader-6.1.1.tgz",
- "integrity": "sha1-pvKd+z9ZM6HDULLbqiCsW+BTm6o=",
+ "version": "6.2.0",
+ "resolved": "https://registry.npm.taobao.org/file-loader/download/file-loader-6.2.0.tgz?cache=0&sync_timestamp=1603816843418&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffile-loader%2Fdownload%2Ffile-loader-6.2.0.tgz",
+ "integrity": "sha1-uu98+OGEDfMl5DkLRISHlIDuvk0=",
"dev": true,
"requires": {
"loader-utils": "^2.0.0",
@@ -10380,9 +10380,9 @@
"dev": true
},
"image-size": {
- "version": "0.9.1",
- "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.9.1.tgz",
- "integrity": "sha512-yBo6xGGjiWtApYroCGR9wTvaIgande5vmAfTYIld5ss5kN4tyDG5lrW1qGomOXgB05ss7GLXLpDYXEiFqSqkzg==",
+ "version": "0.9.3",
+ "resolved": "https://registry.npm.taobao.org/image-size/download/image-size-0.9.3.tgz?cache=0&sync_timestamp=1603729042810&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fimage-size%2Fdownload%2Fimage-size-0.9.3.tgz",
+ "integrity": "sha1-9+/OawoWSbRLm8Q7nZpazyciZLY=",
"requires": {
"queue": "6.0.1"
}
@@ -11514,8 +11514,8 @@
},
"merge-source-map": {
"version": "1.1.0",
- "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz",
- "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==",
+ "resolved": "https://registry.npm.taobao.org/merge-source-map/download/merge-source-map-1.1.0.tgz",
+ "integrity": "sha1-L93n5gIJOfcJBqaPLXrmheTIxkY=",
"dev": true,
"requires": {
"source-map": "^0.6.1"
@@ -11523,8 +11523,8 @@
"dependencies": {
"source-map": {
"version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "resolved": "https://registry.npm.taobao.org/source-map/download/source-map-0.6.1.tgz",
+ "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=",
"dev": true
}
}
@@ -11945,21 +11945,11 @@
"dev": true
},
"node-id3": {
- "version": "0.1.19",
- "resolved": "https://registry.npm.taobao.org/node-id3/download/node-id3-0.1.19.tgz",
- "integrity": "sha1-cQAMuCna3HYQAKSBAV5T88ydqto=",
+ "version": "0.2.1",
+ "resolved": "https://registry.npm.taobao.org/node-id3/download/node-id3-0.2.1.tgz",
+ "integrity": "sha1-QYNSONdoe4dbCMzguxYMXOoLurw=",
"requires": {
- "iconv-lite": "0.5.1"
- },
- "dependencies": {
- "iconv-lite": {
- "version": "0.5.1",
- "resolved": "https://registry.npm.taobao.org/iconv-lite/download/iconv-lite-0.5.1.tgz?cache=0&sync_timestamp=1594184250387&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ficonv-lite%2Fdownload%2Ficonv-lite-0.5.1.tgz",
- "integrity": "sha1-skJdPHsY9yGfLKZj0QO925FxjWQ=",
- "requires": {
- "safer-buffer": ">= 2.1.2 < 3"
- }
- }
+ "iconv-lite": "0.6.2"
}
},
"node-libs-browser": {
@@ -13374,8 +13364,8 @@
},
"prettier": {
"version": "1.19.1",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz",
- "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==",
+ "resolved": "https://registry.npm.taobao.org/prettier/download/prettier-1.19.1.tgz?cache=0&sync_timestamp=1600215482255&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fprettier%2Fdownload%2Fprettier-1.19.1.tgz",
+ "integrity": "sha1-99f1/4qc2HKnvkyhQglZVqYHl8s=",
"dev": true,
"optional": true
},
@@ -13740,8 +13730,8 @@
},
"queue": {
"version": "6.0.1",
- "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.1.tgz",
- "integrity": "sha512-AJBQabRCCNr9ANq8v77RJEv73DPbn55cdTb+Giq4X0AVnNVZvMHlYp7XlQiN+1npCZj1DuSmaA2hYVUUDgxFDg==",
+ "resolved": "https://registry.npm.taobao.org/queue/download/queue-6.0.1.tgz",
+ "integrity": "sha1-q9WlsDdpEvBwolcp4Lan1WVoN5E=",
"requires": {
"inherits": "~2.0.3"
}
@@ -15540,9 +15530,9 @@
}
},
"stylus-loader": {
- "version": "4.1.1",
- "resolved": "https://registry.npm.taobao.org/stylus-loader/download/stylus-loader-4.1.1.tgz",
- "integrity": "sha1-DpT11idJMqLa0FTRpzazIUasepk=",
+ "version": "4.2.0",
+ "resolved": "https://registry.npm.taobao.org/stylus-loader/download/stylus-loader-4.2.0.tgz?cache=0&sync_timestamp=1603977404318&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstylus-loader%2Fdownload%2Fstylus-loader-4.2.0.tgz",
+ "integrity": "sha1-7EzzQIpS0H5tPBX/4aDlwkhLrMc=",
"dev": true,
"requires": {
"fast-glob": "^3.2.4",
@@ -15554,7 +15544,7 @@
"dependencies": {
"ajv": {
"version": "6.12.6",
- "resolved": "https://registry.npm.taobao.org/ajv/download/ajv-6.12.6.tgz?cache=0&sync_timestamp=1602353715225&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fajv%2Fdownload%2Fajv-6.12.6.tgz",
+ "resolved": "https://registry.npm.taobao.org/ajv/download/ajv-6.12.6.tgz?cache=0&sync_timestamp=1603561547443&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fajv%2Fdownload%2Fajv-6.12.6.tgz",
"integrity": "sha1-uvWmLoArB9l3A0WG+MO69a3ybfQ=",
"dev": true,
"requires": {
@@ -15566,7 +15556,7 @@
},
"ajv-keywords": {
"version": "3.5.2",
- "resolved": "https://registry.npm.taobao.org/ajv-keywords/download/ajv-keywords-3.5.2.tgz?cache=0&sync_timestamp=1595908717940&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fajv-keywords%2Fdownload%2Fajv-keywords-3.5.2.tgz",
+ "resolved": "https://registry.npm.taobao.org/ajv-keywords/download/ajv-keywords-3.5.2.tgz?cache=0&sync_timestamp=1603566069729&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fajv-keywords%2Fdownload%2Fajv-keywords-3.5.2.tgz",
"integrity": "sha1-MfKdpatuANHC0yms97WSlhTVAU0=",
"dev": true
},
@@ -16716,19 +16706,19 @@
},
"vue-hot-reload-api": {
"version": "2.3.4",
- "resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz",
- "integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==",
+ "resolved": "https://registry.npm.taobao.org/vue-hot-reload-api/download/vue-hot-reload-api-2.3.4.tgz",
+ "integrity": "sha1-UylVzB6yCKPZkLOp+acFdGV+CPI=",
"dev": true
},
"vue-i18n": {
- "version": "8.22.0",
- "resolved": "https://registry.npm.taobao.org/vue-i18n/download/vue-i18n-8.22.0.tgz?cache=0&sync_timestamp=1602001179053&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue-i18n%2Fdownload%2Fvue-i18n-8.22.0.tgz",
- "integrity": "sha1-ZAM4Gm6rHSKeUVpirdspsv86v+0="
+ "version": "8.22.1",
+ "resolved": "https://registry.npm.taobao.org/vue-i18n/download/vue-i18n-8.22.1.tgz",
+ "integrity": "sha1-ud0Jihfh9a25G9+WEfA4UxDafLE="
},
"vue-loader": {
- "version": "15.9.3",
- "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.9.3.tgz",
- "integrity": "sha512-Y67VnGGgVLH5Voostx8JBZgPQTlDQeOVBLOEsjc2cXbCYBKexSKEpOA56x0YZofoDOTszrLnIShyOX1p9uCEHA==",
+ "version": "15.9.4",
+ "resolved": "https://registry.npm.taobao.org/vue-loader/download/vue-loader-15.9.4.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue-loader%2Fdownload%2Fvue-loader-15.9.4.tgz",
+ "integrity": "sha1-wuzvihoIAqx2xtaGZBtd3lIq4mc=",
"dev": true,
"requires": {
"@vue/component-compiler-utils": "^3.1.0",
@@ -16739,14 +16729,14 @@
}
},
"vue-router": {
- "version": "3.4.7",
- "resolved": "https://registry.npm.taobao.org/vue-router/download/vue-router-3.4.7.tgz",
- "integrity": "sha1-vxibr9FvTk73g8SmJQowkPLB+hs="
+ "version": "3.4.8",
+ "resolved": "https://registry.npm.taobao.org/vue-router/download/vue-router-3.4.8.tgz?cache=0&sync_timestamp=1603710629657&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue-router%2Fdownload%2Fvue-router-3.4.8.tgz",
+ "integrity": "sha1-LAYmHTXYB1iTRwNS1C1wtih7gZQ="
},
"vue-style-loader": {
"version": "4.1.2",
- "resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.2.tgz",
- "integrity": "sha512-0ip8ge6Gzz/Bk0iHovU9XAUQaFt/G2B61bnWa2tCcqqdgfHs1lF9xXorFbE55Gmy92okFT+8bfmySuUOu13vxQ==",
+ "resolved": "https://registry.npm.taobao.org/vue-style-loader/download/vue-style-loader-4.1.2.tgz",
+ "integrity": "sha1-3t80mAbyXOtOZPOtfApE+6c1/Pg=",
"dev": true,
"requires": {
"hash-sum": "^1.0.2",
@@ -16765,8 +16755,8 @@
},
"vue-template-es2015-compiler": {
"version": "1.9.1",
- "resolved": "https://registry.npmjs.org/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz",
- "integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==",
+ "resolved": "https://registry.npm.taobao.org/vue-template-es2015-compiler/download/vue-template-es2015-compiler-1.9.1.tgz",
+ "integrity": "sha1-HuO8mhbsv1EYvjNLsV+cRvgvWCU=",
"dev": true
},
"vuex": {
@@ -17590,9 +17580,9 @@
}
},
"webpack-merge": {
- "version": "5.2.0",
- "resolved": "https://registry.npm.taobao.org/webpack-merge/download/webpack-merge-5.2.0.tgz?cache=0&sync_timestamp=1602063120051&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwebpack-merge%2Fdownload%2Fwebpack-merge-5.2.0.tgz",
- "integrity": "sha1-McvMlU+Pic1LBsqNl6OFSffz8Mk=",
+ "version": "5.3.0",
+ "resolved": "https://registry.npm.taobao.org/webpack-merge/download/webpack-merge-5.3.0.tgz",
+ "integrity": "sha1-qA30TTX6us5oC/QwoZ/ansSe2Os=",
"dev": true,
"requires": {
"clone-deep": "^4.0.1",
diff --git a/package.json b/package.json
index bd609886..10800582 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "lx-music-desktop",
- "version": "1.2.2",
+ "version": "1.3.0",
"description": "一个免费的音乐下载助手",
"main": "./dist/electron/main.js",
"productName": "lx-music-desktop",
@@ -176,11 +176,11 @@
"cross-env": "^7.0.2",
"css-loader": "^4.3.0",
"del": "^6.0.0",
- "electron": "^9.3.2",
+ "electron": "^9.3.3",
"electron-builder": "^22.9.1",
"electron-debug": "^3.1.0",
"electron-devtools-installer": "^3.1.1",
- "eslint": "^7.11.0",
+ "eslint": "^7.12.1",
"eslint-config-standard": "^14.1.1",
"eslint-formatter-friendly": "^7.0.0",
"eslint-loader": "^4.0.2",
@@ -188,8 +188,8 @@
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^4.2.1",
- "eslint-plugin-standard": "^4.0.1",
- "file-loader": "^6.1.1",
+ "eslint-plugin-standard": "^4.0.2",
+ "file-loader": "^6.2.0",
"friendly-errors-webpack-plugin": "^1.7.0",
"html-webpack-plugin": "^4.5.0",
"less": "^3.12.2",
@@ -206,16 +206,16 @@
"rimraf": "^3.0.2",
"spinnies": "^0.5.1",
"stylus": "^0.54.8",
- "stylus-loader": "^4.1.1",
+ "stylus-loader": "^4.2.0",
"terser-webpack-plugin": "^4.2.3",
"url-loader": "^4.1.1",
- "vue-loader": "^15.9.3",
+ "vue-loader": "^15.9.4",
"vue-template-compiler": "^2.6.12",
"webpack": "^4.44.2",
"webpack-cli": "^3.3.12",
"webpack-dev-server": "^3.11.0",
"webpack-hot-middleware": "^2.25.0",
- "webpack-merge": "^5.2.0"
+ "webpack-merge": "^5.3.0"
},
"dependencies": {
"crypto-js": "^4.0.0",
@@ -224,15 +224,15 @@
"electron-store": "^6.0.1",
"electron-updater": "^4.3.5",
"iconv-lite": "^0.6.2",
- "image-size": "^0.9.1",
+ "image-size": "^0.9.3",
"js-htmlencode": "^0.3.0",
"lrc-file-parser": "^1.0.5",
"needle": "^2.5.2",
- "node-id3": "^0.1.19",
+ "node-id3": "^0.2.1",
"request": "^2.88.2",
"vue": "^2.6.12",
- "vue-i18n": "^8.22.0",
- "vue-router": "^3.4.7",
+ "vue-i18n": "^8.22.1",
+ "vue-router": "^3.4.8",
"vuex": "^3.5.1",
"vuex-router-sync": "^5.0.0"
}
diff --git a/publish/changeLog.md b/publish/changeLog.md
index 3390a8ac..b183e271 100644
--- a/publish/changeLog.md
+++ b/publish/changeLog.md
@@ -1,3 +1,11 @@
+### 新增
+
+- 播放详情页新增歌曲评论加载显示(某些平台暂不支持显示子评论)
+
+### 优化
+
+- 修改播放详情页的歌曲图片的显示效果
+
### 修复
-- 降级 Electron 到 9.x.x 版本修复 Linux 版桌面歌词窗口变白的问题
+- 修复小芸源音乐搜索结果最多只有20条搜索结果的问题
diff --git a/publish/version.json b/publish/version.json
index 6f2deeb7..8b4d3a97 100644
--- a/publish/version.json
+++ b/publish/version.json
@@ -1 +1 @@
-{"version":"1.2.2","desc":"
修复
\n\n- 降级 Electron 到 9.x.x 版本修复 Linux 版桌面歌词窗口变白的问题
\n
\n","history":[{"version":"1.2.1","desc":"优化
\n\n- Linux版的软件界面默认使用圆角与阴影,顺便修复了桌面歌词窗口变白的问题,已在Ubuntu 18.10测试正常,若显示异常可尝试添加
-nt参数启动 \n
\n修复
\n\n- 修复聚合搜索的分页问题
\n- 修复代理输入框输入的内容不生效的问题
\n
\n"},{"version":"1.2.0","desc":"提前祝大家中秋&国庆快乐~
\n新增
\n\n- 播放控制栏开启/关闭桌面歌词按钮 新增右击按钮时锁定/解锁桌面歌词功能
\n
\n优化
\n\n- 优化我的列表滚动条位置的保存逻辑
\n- 更新设置-备份与恢复功能的描述
\n- 优化软件内鼠标悬停的提示界面
\n
\n修复
\n\n- 修复桌面歌词窗口不允许拖出桌面之外的位置计算偏移Bug
\n- 修复网易云KTV嗨榜无法加载的问题
\n- 修复初始化搜索历史列表功能
\n- 修复重启软件后试听列表与收藏列表无法恢复上次的滚动位置的问题
\n- 修复歌曲封面无法嵌入的Bug
\n- 修复酷狗歌词格式问题
\n- 修复关闭切换动画时从搜索候选列表点击内容无效的问题
\n
\n其他
\n\n- 更新 Electron 到 v10.1.3
\n
\n"},{"version":"1.1.1","desc":"修复
\n\n"},{"version":"1.1.0","desc":"新增
\n\n- 在歌单详情界面新增播放当前歌单按钮、收藏歌单按钮,注:播放歌单不会将歌曲添加到试听列表
\n- 新增
不允许将歌词窗口拖出主屏幕之外的设置项,默认开启,在连接多个屏幕时想要拖动到其他屏幕时可关闭此设置 \n- 新增大部分平台的歌词翻译,感谢 @InoriHimea 提供的krc解码算法
\n- 新增
显示歌词翻译设置,默认开启,仅支持某些平台,注:无论该设置是否开启,嵌入或下载歌词时都不会带上翻译 \n- 新增
显示切换动画设置,默认开启,关闭时将基本禁用软件内的所有切换动画 \n- 播放状态栏新增桌面歌词的开关、播放模式的切换、歌曲的收藏按钮,Thanks to @andylow for the icon!
\n
\n修复
\n\n- 修复使用全局快捷键还原窗口时,窗口没有获取焦点的问题
\n- 修复我的列表搜索对最后一个字符的匹配问题
\n- 修复窗口在
较小模式下最小化/关闭按钮不居中的问题 \n
\n优化
\n\n- 桌面歌词当前播放行改为上下居中
\n- 为区分静音状态,静音时音量条会变淡,调整音量条时将会取消静音
\n- 优化随机播放机制,现在通过
下一曲切换歌曲时,直到播放完整个列表之前将不会再随机到之前播放过的歌曲,并且通过上一曲可以正确播放上一首歌曲 \n- 当下载目录没有写入权限时将显示没有写入权限的提示
\n
\n移除
\n\n- 移除默认的全局声音媒体快捷键接管
\n- 移除对百度音乐的支持,因百度音乐原有的大部分API失效,而且该平台相对其他平台来说音乐太少了,可有可无,以后再看情况恢复
\n
\n其他
\n\n"},{"version":"1.0.1","desc":"优化
\n\n修复
\n\n- 修复在 Windows 系统下缩放比非100%时,拖动桌面歌词会自动加大桌面歌词窗口的问题
\n
\n"},{"version":"1.0.0","desc":"新增
\n\n- 新增
rpm、pacman包的构建(未测试可用性) \n- 新增因系统音频设备列表改变导致的当前音频输出设备改变时是否暂停播放的设置,默认关闭
\n- 新增歌曲列表右击菜单
\n- 新增自定义列表,创建列表的按钮在表头
#左侧,鼠标移上去才会显示;编辑列表名字时,按ESC键可快速取消编辑,按回车键或使输入框失去焦点即可保存列表名字,右击列表可编辑已创建的列表,“试听列表”与“我的收藏”两个列表固定不可编辑 \n- 改变排行榜布局,新增更多排行榜
\n- 新增我的列表右键菜单复制歌曲名选项
\n- 新增桌面歌词,默认关闭,可到设置或者托盘菜单开启(建议使用全局快捷键控制);调整字体大小、透明度时,鼠标左击按钮正常调整,右击微调;Windows 7未开启Aero效果时桌面歌词会有问题,详情看常见问题解决;Linux版桌面歌词有问题,以后再尝试优化;
\n- 新增“清热板蓝”皮肤
\n- 新增软件最小化、关闭按钮位置设置,MAC版默认为左边,非MAC为右边,不想用默认的可到设置修改
\n- 新增快捷键设置,软件内快捷键默认开启,全局快捷键默认关闭(注:若想开启蓝牙耳机切歌需开启全局快捷键,当快捷键被中划线划掉时,表示当前快捷键被其他程序占用导致注册失败)
\n- 新增首次运行时自动根据当前系统使用的语言设置软件显示的语言
\n- 新增歌词区域的触摸板、鼠标滚轮等对歌词滚动的支持
\n- 为了方便支持正版资源,歌曲列表右击菜单新增跳转到当前歌曲源官方详情页菜单(注意:在本版本之前添加的虾米源歌曲无法跳转详情页,需要移除后重新搜索添加)
\n- 新增我的列表内歌曲搜索,在我的列表按
ctrl+f将显示搜索框;鼠标滑过或键盘上下方向键选择搜索结果;鼠标点击或按回车键定位选中的歌曲;按ctrl键的情况下鼠标点击或按回车键确认定位歌曲时,将会在定位歌曲结束后播放该歌曲(搜索框激活的情况下按esc可快速清空搜索框/关闭搜索框) \n- 新增托盘图标样式设置,可到设置-其他切换
\n- 新增开关下载功能控制,默认关闭,可到设置-下载设置开启
\n- 新增将歌词嵌入音频文件中,默认关闭,可到设置-下载设置开启
\n- 新增当列表文件损坏时对损坏文件的备份,若出现该情况可打开
%HOMEPATH%\\AppData\\Roaming\\lx-music-desktop找到playList.json.bak尝试手动修复列表文件,列表文件以JSON格式存储 \n- 新增在歌单详情列表按退格(Backspace)键可快速返回歌单列表
\n
\n优化
\n\n- 改进歌曲切换时的歌词滚动效果
\n- 优化批量添加、删除播放列表的歌曲操作逻辑,大幅提升批量添加、删除列表歌曲的流畅度
\n- 改进歌单列表展示
\n- 改进聚合搜索的搜索结果排序,修复当某些源搜索失败时导致其他源无法显示结果的问题,现在聚合搜索已达到最初的理想效果,为了使排序更精确,建议同时输入 歌曲名 歌手名 搜索(歌曲名在前歌手名在后),欢迎体验~!
\n- 压缩备份数据文件大小
\n
\n修复
\n\n- 修复按住
Ctrl等键触发多选机制时不松开按键的情况下切换到其他窗口后再松开按键,这时切回软件不按按键都处在多选模式的问题 \n- 修复Linux版开启托盘无法退出的问题
\n- 修复某些情况下可能导致的音源输出问题
\n- 修复某些情况下无法开始下载任务的问题
\n- 修复 tab 组件边框溢出问题
\n- 修复错误更新试听列表外的歌曲时间的问题
\n- 修复网易音乐源歌单、排行榜歌曲列表加载显示的数量与实际不对的问题,同时支持加载大于1000首歌的歌单(歌曲大于1000首会分页),注意:目前软件一下子显示太多歌曲时会卡顿,不建议在同一列表内添加太多歌曲
\n- 修复歌曲图片链接没有扩展名的情况下无法嵌入图片的问题
\n- 修复无法检测最新版本时弹窗提示的显示
\n- 修复某些情况下从托盘还原窗口后无法操作的问题
\n- 修复Linux下无法
ctrl+a全选的问题 \n- 修复主题背景图片覆盖不全的问题
\n- 修复聚合搜索音源标签的皮肤配色问题
\n
\n更变
\n\n- 修改设置-列表-是否显示歌曲源的默认设置为选中(该变更不影响之前的设置)
\n- 移除浮动按钮,现在在多选完成后可鼠标右击随意一项在弹出的右键菜单中进行原来悬浮按钮的操作
\n- 为了避免出现误会,现在下载弹窗中不可用的音质将直接隐藏
\n- 更改初始设置的搜索设置为聚合搜索(该变更不影响之前的设置)
\n
\n其他
\n\n"},{"version":"0.18.2","desc":"修复
\n\n- 修复开启托盘时,可能导致无法自动更新的问题
\n
\n"},{"version":"0.18.1","desc":"优化
\n\n- win下的托盘图标使用更大的图片
\n- 加长软件协议的强制停留时间
\n
\n修复
\n\n"},{"version":"0.18.0","desc":"新增
\n\n- 新增FLAC格式音乐标签信息写入与封面嵌入(因128k以外的音质已失效,目前该功能用不上了)
\n- 添加软件启动时是否自动聚焦搜索框的设置
\n- 新增托盘设置,默认关闭,可到设置开启,感谢 @LasyIsLazy 提交的PR
\n- 新增打开酷狗源用户歌单
\n- 新增使用协议
\n- 新增虾米音源
\n- 新增新皮肤“粉妆玉琢”、“青出于黑”,可去体验下~
\n- 新增“超大”、“巨大”窗口尺寸
\n- 新增播放详情页(退出详情页可点击右上角退出按钮或者在播放详情页任意地方鼠标快速右击两次)
\n
\n优化
\n\n- 略微加深音量条底色
\n- 优化其他界面细节
\n- 优化英语翻译,感谢 @CPCer
\n- 优化程序的流畅度
\n
\n更变
\n\n- 下载列表的歌曲下载、播放将随设置中的保存路径改变而改变,不再固定指向其初始位置
\n- 移除列表多选框,现在多选需要键盘配合,想要多选前需按下
Shift或Ctrl键然后再鼠标点击想要选中的内容即可触发多选机制,其中Shift键用于连续选择,Ctrl键用于不连续选择,Ctrl+a用于快速全选。例子一:想要选中1-5项,则先按下Shift键后,鼠标点击第一项,再点击第五项即可完成选择;例子二:想要选中1项与第3项,则先按下Ctrl键后,鼠标点击第一项,再点击第三项即可完成选择;例子三:想要选中当前列表的全部内容,键盘先按下Ctrl键不放,然后按a键,即可完成选择。用Shift或Ctrl选择时,鼠标点击未选中的内容会将其选中,点击已选择的内容会将其取消选择,若想全部取消选择,在不按Shift或Alt键的情况下,随意点击列表里的一项内容即可全部取消选择。(P.S:Ctrl键对应Mac OS上的Command键) \n- 现在进度条的封面图左击改为打开播放详情页,在列表定位歌曲改为右击
\n
\n修复
\n\n- 修复网易源某些歌曲提示没有可播放的音质的问题
\n- 修复下载管理刷新URL失败时不标记任务下载失败的问题
\n- 修复列表导出的文字描述,感谢 @CPCer
\n- 修复歌曲切换方式无法取消勾选的问题
\n- 修复打开歌单详情的情况下切到其他界面再切回来报错的问题
\n- 修正播放列表浮动按钮错误的文字提示
\n
\n移除
\n\n- 因128k以外的音质失效,So 禁止所有128k外的音质下载
\n
\n其他
\n更新 Electron 到 8.2.5
\n"},{"version":"0.17.0","desc":"新增
\n\n- 新增多语言设置,目前软件内置了简体中文、繁体中文、英语三种语言,欢迎提交PR翻译更多语言!
\n- 新增无法打开外部歌单FAQ
\n- 新增启动参数
search,使用例子:.\\lx-music-desktop.exe -search="突然的自我 - 伍佰" \n- 新增音频输出设置
\n- 新增软件内的包括字体在内的界面内容大小调整,现在当窗口大小切换到“较小/大/较大”时,软件内的元素将会适当减小或加大,窗口大小的“小”与“中”内的元素将保持之前的大小暂不做改变
\n- 新增音源别名,默认将显示别名,想要显示回原名可到设置切换(免责声明:别名仅是本软件用于描述各音源的标签,其名字归版权方所有)
\n- 新增发现新版本更新失败弹窗的忽略提醒按钮,忽略提醒后,以后同一个版本再失败时将不会弹窗提醒,但仍可到设置-版本更新手动点开更新弹窗查看或恢复提醒
\n- 新增热搜词,默认关闭,可到设置开启
\n- 新增历史搜索记录,默认关闭,可到设置开启(右击单个历史记录标签可移除所点击的记录)
\n
\n优化
\n\n- 优化月里嫦娥皮肤侧栏鼠标悬浮颜色
\n- 优化播放进度条的动画效果
\n- 现在添加下载任务时,后面添加的任务会在列表顶部插入
\n- 优化歌单打开机制,现在歌单加载失败时会提示加载失败了,并且支持直接打开企鹅、酷我手机分享出来的歌单了
\n- 优化右上角最小化/关闭按钮布局
\n
\n修复
\n\n- 修复歌单详情处于加载状态时无法返回的问题
\n- 修复鼠标右击复制列表内容时会复制音质标签的问题
\n- 修复
0.6.2及以前的版本导出的“所有数据”内的歌曲列表无法导入的问题 \n- 修复下载列表在某些情况下无法取消全选的问题
\n
\n其他
\n\n"},{"version":"0.16.0","desc":"新增
\n\n- 允许选中列表内歌曲名、歌手名、专辑名内的文字,选中后可使用键盘快捷键进行复制
\n- 新增在列表可选内容区域鼠标右击时自动复制列表已选文字的功能
\n- 新增在搜索框鼠标右击时自动粘贴剪贴板的文本到搜索框中
\n- 任务下载失败时将显示搜索按钮,方便在其他源搜索该歌曲
\n
\n优化
\n\n- 优化木叶之村主题翻页器背景颜色
\n- 优化各个主题音质标签颜色
\n- 优化其他一些界面细节及用户交互效果
\n
\n修复
\n\n- 修复启用透明窗口鼠标不穿透的bug
\n- 修复大窗口时设置的音乐来源选项不换行的问题
\n- 修复某些情况下暂停任务会自动开始任务的问题
\n- 修复移除暂停、错误的任务时不删除未下载完成的文件的问题
\n- 修复酷狗源歌单热门标签歌单列表无法加载问题
\n- 修复QQ源歌单热门标签歌单列表无法加载问题
\n
\n其他
\n\n"},{"version":"0.15.0","desc":"洛雪提前祝大家新年快乐、身体健康、阖家幸福!
\n修复
\n\n- 修复歌曲下载列表无法加载的问题
\n- 修复歌曲下载任务数大于最大下载任务数的问题
\n- 修复某些情况下歌曲下载错误的问题
\n- 修复下载列表数据没有被迁移直接被丢弃的问题
\n
\n"},{"version":"0.14.1","desc":"洛雪提前祝大家新年快乐、身体健康、阖家幸福!
\n修复
\n\n- 修复由于旧版配置文件迁移出错导致的软件界面无法显示的问题
\n
\n"},{"version":"0.14.0","desc":"洛雪提前祝大家新年快乐、身体健康、阖家幸福!
\n新增
\n\n- 新增各大平台歌单热门标签显示(显示在歌单界面的第一个下拉标签菜单中)
\n- 恢复QQ音乐源128k音质试听
\n- 新增不强制win7开启透明效果即可使用,但要配置运行参数
-nt,例如:.\\lx-music-desktop.exe -nt,添加方法可自行百度“给快捷方式加参数” \n- 新增“新年快乐”主题,可自行切换体验
\n
\n优化
\n\n- 减淡各个主题的歌曲列表分隔线颜色
\n- 在线音乐列表音质标签优化,当歌曲有无损音质时隐藏高品质标签
\n- 更新改进的歌词播放插件,现在歌词的播放显示将更准确
\n
\n修复
\n\n- 修复咪咕源无法搜索的问题
\n- 修复更新弹窗底部文字颜色没有适配当前主题颜色的问题
\n- 修复导入设置窗口大小、代理设置不立即生效的问题
\n- 修复在线音乐列表获取失败时无限循环请求的问题
\n
\n其他
\n\n- 将软件设置与播放列表分离存储成两个文件
\n- 更新 Electron 到 7.1.9
\n
\n"},{"version":"0.13.1","desc":"修复
\n\n其他
\n\n- 由于electron 7.1.3 - 7.1.5 的自动更新功能存在Bug,现降级到7.1.2
\n
\n"},{"version":"0.13.0","desc":"新增
\n\n- 新增搜索框搜索建议键盘上下方向键选择功能
\n- 聚合搜索新增音源显示
\n- 新增“离开搜索界面时清空搜索列表”设置选项,默认关闭,可到设置-强迫症设置开启
\n
\n优化
\n\n修复
\n\n- 修复存在弹出层时,搜索建议列表被弹出层覆盖的问题
\n- 修复搜索、排行榜、歌单列表多选框从不定状态到选中的Bug
\n
\n移除
\n\n其他
\n\n- 更新electron到7.1.5
\n- 更新vue到2.6.11
\n
\n"},{"version":"0.12.1","desc":"优化
\n\n- 优化定位歌曲时的列表滚动机制
\n- 优化链接点击效果
\n
\n修复
\n\n- 修复使用酷我源下载歌曲时,当歌曲无封面时下载报错的问题
\n- 修复酷我源排行榜、歌单详情列表里的歌曲音质匹配问题(原来无论歌曲有无高品、无损都会显示有)
\n- 禁止外部链接在软件内打开,将所有外部链接从默认浏览器打开
\n
\n其他
\n\n"},{"version":"0.12.0","desc":"由于新下载库仍然没有完成,但下载功能已经可用,so 移除之前使用的第三方下载库,暂时把新下载库的下载模块直接加入本程序,若出现下载问题欢迎反馈!
\n新增
\n\n- 新增下载功能对代理设置的支持,现在若在软件设置了代理服务器,下载功能也将会走代理网络了
\n
\n优化
\n\n- 新下载模块将对恢复下载的任务进行字节校验,用于解决下载进度超过100%后仍然下载的问题
\n- 注意:目前仍然无法暂停处于链接获取状态中的任务
\n
\n修复
\n\n- 修复Linux deb版本
.desktop桌面文件缺少图标的问题,新增中文名称显示、软件分类,感谢@lowy的反馈! \n- 修复下载列表歌曲状态分类列表操作Bug
\n- 修复歌曲封面下载失败时仍然执行嵌入封面操作导致报错的问题
\n- 跳过重复添加相同歌曲名与扩展名的歌曲,例如你之前下载了A歌曲的128k音质,现在想要下载它的320k音质,但由于两者都是MP3格式,会因为重名导致之前的128k音质被覆盖但列表中仍然显示两种音质的问题(但实际上都是指向后面的320k音质)
\n
\n"},{"version":"0.11.0","desc":"新增
\n\n- 新增歌曲缓冲定时器,尝试用于解决网络正常但是歌曲缓冲过久的问题
\n- 新增下载管理的任务状态分类
\n- 添加杀毒软件提示有病毒或恶意行为的说明,可到常见问题拉到最后查看(常见问题可在开源地址找到)
\n
\n优化
\n\n- 优化更新弹窗机制及其内容描述,对于可以自动更新的版本,现在可以看到软件的下载进度了
\n
\n"},{"version":"0.10.0","desc":"优化
\n\n- 大幅减少程序播放时对CPU与GPU的使用,经测试CPU使用减少60%以上,GPU使用减少90%以上,这应该能解决MAC系统上的温度上涨的问题
\n
\n修复
\n\n- 修复酷我源搜索提示、排行榜无法获取的问题
\n- 修复咪咕源无法播放的问题
\n
\n"},{"version":"0.9.1","desc":"修复
\n\n"},{"version":"0.9.0","desc":"新增
\n\n- 新增窗口大小设置,若觉得软件窗口小可以到设置页调大点
\n- 新增定位当前播放歌曲,点击播放栏左侧的歌曲图片可在播放列表定位当前播放的歌曲(该功能对播放下载列表的歌曲无效)
\n
\n修复
\n\n- 修复搜索提示失效的问题
\n- 修复从歌单或列表点击搜索按钮搜索目标歌曲时,搜索框未聚焦仍然弹出候选搜索列表的问题
\n
\n"},{"version":"0.8.2","desc":"修复
\n\n- 兼容旧版酷我源搜索列表过滤128k音质的bug(注:0.8.1版本仅修复了酷我源的歌曲过滤问题,该修复仅对以后添加的歌曲有效,如果是之前添加的歌曲仍会出现这个问题,现修复对之前旧列表数据的兼容处理)
\n
\n"},{"version":"0.8.1","desc":"修复
\n\n- 修复酷我源搜索歌曲结果未添加128k音质导致播放128k音质时显示“该歌曲没有可播放的音频”的问题
\n
\n"},{"version":"0.8.0","desc":"新增
\n\n- 新增网易云源歌曲搜索
\n- 新增网易云源歌单
\n- 新增各平台通过输入歌单链接或歌单ID打开歌单详情列表,目前只适配了网页版歌单链接,其他方式的歌单链接可能无法解析,但你可想办法获取歌单ID后输入打开。注:各平台歌单ID均为纯数字,若遇到链接里存在歌单ID但无法解析的歌单链接,可以到GitHub提交issue或发送邮件或加群830125506反馈!
\n- 新增音量调整滑动功能,现在支持鼠标左右拖动调整音量了
\n
\n优化
\n\n- 优化搜索框搜索体验
\n- 优化音量条交互视觉效果
\n- 缓存歌单详情列表数据
\n
\n修复
\n\n- 修复QQ源歌单无法翻页Bug
\n- 修复默认列表没有创建时无法显示收藏列表的Bug
\n- 修复网易云128k直接试听
\n- 修复歌曲音质不存在时仍然播放或下载的Bug
\n- 修复调整音量时,调整的位置与鼠标点击的位置不一致的问题
\n
\n"},{"version":"0.7.0","desc":"新增
\n\n- 新增“我的收藏”本地播放列表
\n- 新增缓存清理功能,可到设置-其他查看与清理软件缓存
\n- 新增QQ音乐源搜索
\n- 新增咪咕源搜索
\n- 新增咪咕源歌单
\n- 新增咪咕源排行榜
\n- 新增我的音乐列表歌曲源显示,默认关闭,可到设置-列表设置开启
\n
\n优化
\n\n- 优化选择框动画效果
\n- 尝试优化选我的音乐列表内容很多时多选的卡顿问题
\n
\n修复
\n\n- 修复列表延迟显示的Bug
\n- 修复QQ音源128k音质试听
\n
\n"},{"version":"0.6.2","desc":"祝贺祖国成立70周年~!
\n新增
\n\n修复
\n\n- 修正火影皮肤名字
\n- 修复当试听列表为空时,无法切到其他界面的Bug
\n- 修复百度源搜索结果为空时的接口处理Bug
\n- 恢复酷狗其他音质播放
\n
\n"},{"version":"0.6.1","desc":"新增
\n\n- 新增试听列表滚动条位置恢复设置(可自动恢复到上次离开时的列表滚动位置),本功能默认开启,若不需要可到设置-列表设置将其关闭
\n- 新增 《海贼王》 皮肤,喜欢个性化的可以试试~
\n
\n优化
\n\n- 新增DNS解析缓存,加快请求速度
\n- 优化代码逻辑,减少软件对系统资源的占用
\n- 优化新版本信息检测,尽量减少弹出版本获取失败弹窗弹出的概率
\n- 优化下拉列表动画效果
\n
\n修复
\n\n- 修复请求超时的逻辑处理Bug,尝试修复请求无法取消导致的正在播放的歌曲与界面显示的信息不一致的问题
\n- 修复其他一些小Bug
\n
\n移除
\n\n- 移除
192k 音质 \n- 移除酷我音源
ape 音质,无损推荐 flac 格式 \n
\n"},{"version":"0.6.0","desc":"新增
\n\n- 新增音乐聚合搜索,目前支持酷我、酷狗、百度源搜索
\n- 新增代理功能
\n
\n优化
\n\n- 优化从《梦里嫦娥》皮肤切换到其他皮肤时侧栏动画的切换效果
\n
\n修复
\n\n- 修复试听列表没有歌曲时会显示列表加载中的Bug
\n- 修复切换歌单列表详情时的UI Bug
\n
\n"},{"version":"0.5.5","desc":"新增
\n\n- 月是故乡明,祝大家中秋快乐🥮~~新增个性皮肤**《月里嫦娥》**,时间仓促,皮肤还不是很完善,可以试试喜不喜欢~😉
\n- 新增 MAC 版本退出快捷键支持
\n- 新增点击播放器中的歌曲标题可以复制标题的功能(遇到好听的歌曲方便分享)
\n
\n修复
\n\n- 修复 MAC 系统下软件关闭时再次从 dock 打开时报错的Bug
\n- 修复下载的歌曲文件名中包含命名规则不允许的符号时下载失败的问题(若歌曲名包含这些符号会自动将其移除)
\n- 修复 MAC 版本不能复制粘贴的问题
\n
\n"},{"version":"0.5.4","desc":"移除
\n\n- 下载的FLAC文件在修改歌曲信息后,软件无法播放,但使用本地播放器可以播放
\n- 为了稳妥起见,暂时移除FLAC格式的meta信息修改
\n- MP3格式无此问题
\n
\n"},{"version":"0.5.3","desc":"优化
\n\n修复
\n\n- 修复试听酷狗源的音乐仍然获取320k音质导致获取失败的Bug
\n
\n"},{"version":"0.5.2","desc":"新增
\n\n- 新增强迫症设置-离开搜索界面时是否清空搜索框
\n- 设置-关于板块新增常见问题链接
\n- 歌单左上角的分类按钮添加一个向下图标,方便识别该按钮为下拉框(该按钮可选择歌单类型,请自行尝试)
\n
\n优化
\n\n- 略微优化最小化按钮字符
\n- 优化试听列表的加载体验,当歌曲数过多时列表将延迟加载
\n
\n修复
\n\n移除
\n\n- 因接口失效,移除网易云音源,酷狗音源仅支持播放128k音质
\n
\n"},{"version":"0.5.1","desc":"新增
\n\n- 新增右上角最小化/关闭按钮鼠标滑过符号
\n- 新增下载列表定位文件按钮
\n
\n修复
\n\n- 修复百度源歌单全部分类无法加载的问题
\n- 修复更新弹窗无法弹出的问题
\n
\n"},{"version":"0.5.0","desc":"新增
\n\n- 新增封面嵌入(默认开启,可到设置-下载设置关闭)
\n- 新增歌词下载(默认关闭,可到设置-下载设置开启)
\n- 新增单例应用功能(实现软件单开功能,禁止软件多开)
\n
\n优化
\n\n修复
\n\n- 修复歌单无法翻页的问题
\n- 修复在某些情况下,添加下载歌曲导致下载列表崩溃的问题
\n- 修复版本更新弹窗Bug
\n- 修复酷狗歌单推荐歌单出现在其他分类中的Bug
\n
\n"},{"version":"0.4.0","desc":"新增
\n\n- 新增歌单功能,目前支持酷我、酷狗、百度源歌单
\n- 在设置界面-关于洛雪音乐说明部分新增最新版网盘下载地址与打赏地址
\n- 新增酷狗 电音热歌榜、DJ热歌榜
\n- 新增版本更新超时功能,对于部分无法访问GitHub的用户做更新超时提醒
\n
\n移除
\n\n- 注意:0.4.0以前的版本即将失效,请更新到0.4.0版本
\n
\n"},{"version":"0.3.5","desc":"新增
\n\n- 新增测试接口,该接口同样速度较慢,但软件的大部分功能可用,请自行切换到该接口,找接口辛苦,且用且珍惜!
\n
\n优化
\n\n- 取消需要刷新URL时windows任务栏进度显示错误状态(现显示为暂停状态)
\n
\n修复
\n\n- 修复使用临时接口时在试听列表双击灰色歌曲仍然会进行播放的Bug
\n- 修复歌词加载Bug
\n
\n"},{"version":"0.3.4","desc":"优化
\n\n- 减少接口不稳定带来的影响,适当增加请求等待时间
\n
\n修复
\n\n- 修复播放过程中URL过期不会刷新URL的问题
\n
\n"},{"version":"0.3.3","desc":"修复
\n\n- messoer的接口已经关闭,暂时切换到临时接口使用,部分功能受限。。。
\n- 修复设置界面更新出错时仍然显示更新下载中的问题
\n- 修复手动定位播放进度条时存在偏差的问题
\n- 屏蔽播放器中没有歌曲时对进度条的点击
\n
\n"},{"version":"0.3.2","desc":"新增
\n\n"},{"version":"0.3.1","desc":"修复
\n\n"},{"version":"0.3.0","desc":"新增
\n\n- 新增MAC及Linux版本(需要的可自行下载)
\n- 新增音量调整
\n- 新增任务栏播放进度条控制选项(现在可在设置界面关闭在任务栏显示的播放进度)
\n- 新增更新出错时的弹窗提示
\n- 从该版本起,非安装版也会有更新弹窗提醒了,但仍然需要手动下载新版本更新,版本信息可到设置页面查看
\n
\n修复
\n\n- 强制把临时接口设置回
messoer 接口 \n
\n"},{"version":"0.2.3","desc":"新增
\n\n- 新增任务栏程序标题改变功能(播放歌曲时任务栏标题将显示当前播放的歌曲)
\n
\n修复
\n\n- 使用临时接口时,试听列表中的下载按钮仍然能点击的Bug
\n- 修复某些情况下歌曲链接未能缓存的问题
\n
\n移除
\n\n- 移除临时接口(因服务器被攻击,本接口已关闭)
\n- 移除列表栏设置的隐藏专辑栏选项(感觉这个设置并没有什么luan用,并且还会打破布局)
\n
\n"},{"version":"0.2.2","desc":"修复
\n\n- 修复下载过程中出错重试5次都失败后不会自动开始下一个任务的Bug
\n- 修复播放到一半URL过期时不会刷新URL直接播放下一首的问题
\n
\n"},{"version":"0.2.1","desc":"优化
\n\n- 新增歌曲URL存储,当URL无效时才重新获取,以减少接口不稳定的影响
\n
\n修复
\n\n- 修复歌曲加载无法加载时自动切换混乱的Bug
\n- 修复移除列表最后一首歌曲时播放器不停止播放的问题
\n
\n"},{"version":"0.2.0","desc":"新增
\n\n- 新增百度音乐排行榜及其音乐直接试听与下载
\n- 新增网易云排行榜音乐直接试听与下载(目前仅支持128k音质)
\n- 新增酷狗排行榜音乐直接试听与下载(目前仅支持128k音质)
\n
\n修复
\n\n- 修复更新弹窗历史版本描述多余的换行问题
\n- 修复歌曲无法播放的情况下歌词仍会播放的问题
\n
\n"},{"version":"0.1.6","desc":"修复
\n\n"},{"version":"0.1.5","desc":"新增
\n\n- 新增搜索列表批量试听与下载功能
\n- 新增排行榜列表批量试听与下载功能
\n- 新增试听列表批量移除与下载功能
\n- 新增下载列表批量开始、暂停与移除功能
\n
\n优化
\n\n"},{"version":"0.1.4","desc":"新增
\n\n- 新增音乐来源切换,可到设置页面-基本设置 look look !
\n- 为搜索结果列表添加多选功能。
\nP.S:暂时没想好多选后的操作按钮放哪… \n
\n优化
\n\n- 重构与改进checkbox组件,使其支持不定选中状态
\n- 完善上一个版本的http请求封装并切换部分请求到该方法上
\n- 优化其他一些细节
\n
\n"},{"version":"0.1.3","desc":"新增
\n\n修复
\n\n- 修复安装包许可协议乱码问题
\n- messoer 提供的接口已挂,暂时切换到临时接口!
\n
\n移除
\n\n- 由于messoer接口无法使用,QQ音乐排行榜直接播放/下载功能暂时关闭
\n
\n"},{"version":"0.1.2","desc":"修复
\n\n"},{"version":"0.1.1","desc":"新增
\n\n- QQ音乐排行榜直接试听与下载(该接口貌似不太稳定,且用且珍惜!)
\n
\n优化
\n\n- 优化http请求机制
\n- 更新关于本软件说明
\n
\n修复
\n\n- 修复当上一个歌曲链接正在获取时切换歌曲请求不会取消的问题
\n- 修复切换歌曲时仍然播放上一首歌曲的问题
\n
\n"},{"version":"0.1.0","desc":"0.1.0版本发布"}]}
+{"version":"1.3.0","desc":"新增
\n\n- 播放详情页新增歌曲评论加载显示(某些平台暂不支持显示子评论)
\n
\n优化
\n\n修复
\n\n- 修复小芸源音乐搜索结果最多只有20条搜索结果的问题
\n
\n","history":[{"version":"1.2.2","desc":"修复
\n\n- 降级 Electron 到 9.x.x 版本修复 Linux 版桌面歌词窗口变白的问题
\n
\n"},{"version":"1.2.1","desc":"优化
\n\n- Linux版的软件界面默认使用圆角与阴影,顺便修复了桌面歌词窗口变白的问题,已在Ubuntu 18.10测试正常,若显示异常可尝试添加
-nt参数启动 \n
\n修复
\n\n- 修复聚合搜索的分页问题
\n- 修复代理输入框输入的内容不生效的问题
\n
\n"},{"version":"1.2.0","desc":"提前祝大家中秋&国庆快乐~
\n新增
\n\n- 播放控制栏开启/关闭桌面歌词按钮 新增右击按钮时锁定/解锁桌面歌词功能
\n
\n优化
\n\n- 优化我的列表滚动条位置的保存逻辑
\n- 更新设置-备份与恢复功能的描述
\n- 优化软件内鼠标悬停的提示界面
\n
\n修复
\n\n- 修复桌面歌词窗口不允许拖出桌面之外的位置计算偏移Bug
\n- 修复网易云KTV嗨榜无法加载的问题
\n- 修复初始化搜索历史列表功能
\n- 修复重启软件后试听列表与收藏列表无法恢复上次的滚动位置的问题
\n- 修复歌曲封面无法嵌入的Bug
\n- 修复酷狗歌词格式问题
\n- 修复关闭切换动画时从搜索候选列表点击内容无效的问题
\n
\n其他
\n\n- 更新 Electron 到 v10.1.3
\n
\n"},{"version":"1.1.1","desc":"修复
\n\n"},{"version":"1.1.0","desc":"新增
\n\n- 在歌单详情界面新增播放当前歌单按钮、收藏歌单按钮,注:播放歌单不会将歌曲添加到试听列表
\n- 新增
不允许将歌词窗口拖出主屏幕之外的设置项,默认开启,在连接多个屏幕时想要拖动到其他屏幕时可关闭此设置 \n- 新增大部分平台的歌词翻译,感谢 @InoriHimea 提供的krc解码算法
\n- 新增
显示歌词翻译设置,默认开启,仅支持某些平台,注:无论该设置是否开启,嵌入或下载歌词时都不会带上翻译 \n- 新增
显示切换动画设置,默认开启,关闭时将基本禁用软件内的所有切换动画 \n- 播放状态栏新增桌面歌词的开关、播放模式的切换、歌曲的收藏按钮,Thanks to @andylow for the icon!
\n
\n修复
\n\n- 修复使用全局快捷键还原窗口时,窗口没有获取焦点的问题
\n- 修复我的列表搜索对最后一个字符的匹配问题
\n- 修复窗口在
较小模式下最小化/关闭按钮不居中的问题 \n
\n优化
\n\n- 桌面歌词当前播放行改为上下居中
\n- 为区分静音状态,静音时音量条会变淡,调整音量条时将会取消静音
\n- 优化随机播放机制,现在通过
下一曲切换歌曲时,直到播放完整个列表之前将不会再随机到之前播放过的歌曲,并且通过上一曲可以正确播放上一首歌曲 \n- 当下载目录没有写入权限时将显示没有写入权限的提示
\n
\n移除
\n\n- 移除默认的全局声音媒体快捷键接管
\n- 移除对百度音乐的支持,因百度音乐原有的大部分API失效,而且该平台相对其他平台来说音乐太少了,可有可无,以后再看情况恢复
\n
\n其他
\n\n"},{"version":"1.0.1","desc":"优化
\n\n修复
\n\n- 修复在 Windows 系统下缩放比非100%时,拖动桌面歌词会自动加大桌面歌词窗口的问题
\n
\n"},{"version":"1.0.0","desc":"新增
\n\n- 新增
rpm、pacman包的构建(未测试可用性) \n- 新增因系统音频设备列表改变导致的当前音频输出设备改变时是否暂停播放的设置,默认关闭
\n- 新增歌曲列表右击菜单
\n- 新增自定义列表,创建列表的按钮在表头
#左侧,鼠标移上去才会显示;编辑列表名字时,按ESC键可快速取消编辑,按回车键或使输入框失去焦点即可保存列表名字,右击列表可编辑已创建的列表,“试听列表”与“我的收藏”两个列表固定不可编辑 \n- 改变排行榜布局,新增更多排行榜
\n- 新增我的列表右键菜单复制歌曲名选项
\n- 新增桌面歌词,默认关闭,可到设置或者托盘菜单开启(建议使用全局快捷键控制);调整字体大小、透明度时,鼠标左击按钮正常调整,右击微调;Windows 7未开启Aero效果时桌面歌词会有问题,详情看常见问题解决;Linux版桌面歌词有问题,以后再尝试优化;
\n- 新增“清热板蓝”皮肤
\n- 新增软件最小化、关闭按钮位置设置,MAC版默认为左边,非MAC为右边,不想用默认的可到设置修改
\n- 新增快捷键设置,软件内快捷键默认开启,全局快捷键默认关闭(注:若想开启蓝牙耳机切歌需开启全局快捷键,当快捷键被中划线划掉时,表示当前快捷键被其他程序占用导致注册失败)
\n- 新增首次运行时自动根据当前系统使用的语言设置软件显示的语言
\n- 新增歌词区域的触摸板、鼠标滚轮等对歌词滚动的支持
\n- 为了方便支持正版资源,歌曲列表右击菜单新增跳转到当前歌曲源官方详情页菜单(注意:在本版本之前添加的虾米源歌曲无法跳转详情页,需要移除后重新搜索添加)
\n- 新增我的列表内歌曲搜索,在我的列表按
ctrl+f将显示搜索框;鼠标滑过或键盘上下方向键选择搜索结果;鼠标点击或按回车键定位选中的歌曲;按ctrl键的情况下鼠标点击或按回车键确认定位歌曲时,将会在定位歌曲结束后播放该歌曲(搜索框激活的情况下按esc可快速清空搜索框/关闭搜索框) \n- 新增托盘图标样式设置,可到设置-其他切换
\n- 新增开关下载功能控制,默认关闭,可到设置-下载设置开启
\n- 新增将歌词嵌入音频文件中,默认关闭,可到设置-下载设置开启
\n- 新增当列表文件损坏时对损坏文件的备份,若出现该情况可打开
%HOMEPATH%\\AppData\\Roaming\\lx-music-desktop找到playList.json.bak尝试手动修复列表文件,列表文件以JSON格式存储 \n- 新增在歌单详情列表按退格(Backspace)键可快速返回歌单列表
\n
\n优化
\n\n- 改进歌曲切换时的歌词滚动效果
\n- 优化批量添加、删除播放列表的歌曲操作逻辑,大幅提升批量添加、删除列表歌曲的流畅度
\n- 改进歌单列表展示
\n- 改进聚合搜索的搜索结果排序,修复当某些源搜索失败时导致其他源无法显示结果的问题,现在聚合搜索已达到最初的理想效果,为了使排序更精确,建议同时输入 歌曲名 歌手名 搜索(歌曲名在前歌手名在后),欢迎体验~!
\n- 压缩备份数据文件大小
\n
\n修复
\n\n- 修复按住
Ctrl等键触发多选机制时不松开按键的情况下切换到其他窗口后再松开按键,这时切回软件不按按键都处在多选模式的问题 \n- 修复Linux版开启托盘无法退出的问题
\n- 修复某些情况下可能导致的音源输出问题
\n- 修复某些情况下无法开始下载任务的问题
\n- 修复 tab 组件边框溢出问题
\n- 修复错误更新试听列表外的歌曲时间的问题
\n- 修复网易音乐源歌单、排行榜歌曲列表加载显示的数量与实际不对的问题,同时支持加载大于1000首歌的歌单(歌曲大于1000首会分页),注意:目前软件一下子显示太多歌曲时会卡顿,不建议在同一列表内添加太多歌曲
\n- 修复歌曲图片链接没有扩展名的情况下无法嵌入图片的问题
\n- 修复无法检测最新版本时弹窗提示的显示
\n- 修复某些情况下从托盘还原窗口后无法操作的问题
\n- 修复Linux下无法
ctrl+a全选的问题 \n- 修复主题背景图片覆盖不全的问题
\n- 修复聚合搜索音源标签的皮肤配色问题
\n
\n更变
\n\n- 修改设置-列表-是否显示歌曲源的默认设置为选中(该变更不影响之前的设置)
\n- 移除浮动按钮,现在在多选完成后可鼠标右击随意一项在弹出的右键菜单中进行原来悬浮按钮的操作
\n- 为了避免出现误会,现在下载弹窗中不可用的音质将直接隐藏
\n- 更改初始设置的搜索设置为聚合搜索(该变更不影响之前的设置)
\n
\n其他
\n\n"},{"version":"0.18.2","desc":"修复
\n\n- 修复开启托盘时,可能导致无法自动更新的问题
\n
\n"},{"version":"0.18.1","desc":"优化
\n\n- win下的托盘图标使用更大的图片
\n- 加长软件协议的强制停留时间
\n
\n修复
\n\n"},{"version":"0.18.0","desc":"新增
\n\n- 新增FLAC格式音乐标签信息写入与封面嵌入(因128k以外的音质已失效,目前该功能用不上了)
\n- 添加软件启动时是否自动聚焦搜索框的设置
\n- 新增托盘设置,默认关闭,可到设置开启,感谢 @LasyIsLazy 提交的PR
\n- 新增打开酷狗源用户歌单
\n- 新增使用协议
\n- 新增虾米音源
\n- 新增新皮肤“粉妆玉琢”、“青出于黑”,可去体验下~
\n- 新增“超大”、“巨大”窗口尺寸
\n- 新增播放详情页(退出详情页可点击右上角退出按钮或者在播放详情页任意地方鼠标快速右击两次)
\n
\n优化
\n\n- 略微加深音量条底色
\n- 优化其他界面细节
\n- 优化英语翻译,感谢 @CPCer
\n- 优化程序的流畅度
\n
\n更变
\n\n- 下载列表的歌曲下载、播放将随设置中的保存路径改变而改变,不再固定指向其初始位置
\n- 移除列表多选框,现在多选需要键盘配合,想要多选前需按下
Shift或Ctrl键然后再鼠标点击想要选中的内容即可触发多选机制,其中Shift键用于连续选择,Ctrl键用于不连续选择,Ctrl+a用于快速全选。例子一:想要选中1-5项,则先按下Shift键后,鼠标点击第一项,再点击第五项即可完成选择;例子二:想要选中1项与第3项,则先按下Ctrl键后,鼠标点击第一项,再点击第三项即可完成选择;例子三:想要选中当前列表的全部内容,键盘先按下Ctrl键不放,然后按a键,即可完成选择。用Shift或Ctrl选择时,鼠标点击未选中的内容会将其选中,点击已选择的内容会将其取消选择,若想全部取消选择,在不按Shift或Alt键的情况下,随意点击列表里的一项内容即可全部取消选择。(P.S:Ctrl键对应Mac OS上的Command键) \n- 现在进度条的封面图左击改为打开播放详情页,在列表定位歌曲改为右击
\n
\n修复
\n\n- 修复网易源某些歌曲提示没有可播放的音质的问题
\n- 修复下载管理刷新URL失败时不标记任务下载失败的问题
\n- 修复列表导出的文字描述,感谢 @CPCer
\n- 修复歌曲切换方式无法取消勾选的问题
\n- 修复打开歌单详情的情况下切到其他界面再切回来报错的问题
\n- 修正播放列表浮动按钮错误的文字提示
\n
\n移除
\n\n- 因128k以外的音质失效,So 禁止所有128k外的音质下载
\n
\n其他
\n更新 Electron 到 8.2.5
\n"},{"version":"0.17.0","desc":"新增
\n\n- 新增多语言设置,目前软件内置了简体中文、繁体中文、英语三种语言,欢迎提交PR翻译更多语言!
\n- 新增无法打开外部歌单FAQ
\n- 新增启动参数
search,使用例子:.\\lx-music-desktop.exe -search="突然的自我 - 伍佰" \n- 新增音频输出设置
\n- 新增软件内的包括字体在内的界面内容大小调整,现在当窗口大小切换到“较小/大/较大”时,软件内的元素将会适当减小或加大,窗口大小的“小”与“中”内的元素将保持之前的大小暂不做改变
\n- 新增音源别名,默认将显示别名,想要显示回原名可到设置切换(免责声明:别名仅是本软件用于描述各音源的标签,其名字归版权方所有)
\n- 新增发现新版本更新失败弹窗的忽略提醒按钮,忽略提醒后,以后同一个版本再失败时将不会弹窗提醒,但仍可到设置-版本更新手动点开更新弹窗查看或恢复提醒
\n- 新增热搜词,默认关闭,可到设置开启
\n- 新增历史搜索记录,默认关闭,可到设置开启(右击单个历史记录标签可移除所点击的记录)
\n
\n优化
\n\n- 优化月里嫦娥皮肤侧栏鼠标悬浮颜色
\n- 优化播放进度条的动画效果
\n- 现在添加下载任务时,后面添加的任务会在列表顶部插入
\n- 优化歌单打开机制,现在歌单加载失败时会提示加载失败了,并且支持直接打开企鹅、酷我手机分享出来的歌单了
\n- 优化右上角最小化/关闭按钮布局
\n
\n修复
\n\n- 修复歌单详情处于加载状态时无法返回的问题
\n- 修复鼠标右击复制列表内容时会复制音质标签的问题
\n- 修复
0.6.2及以前的版本导出的“所有数据”内的歌曲列表无法导入的问题 \n- 修复下载列表在某些情况下无法取消全选的问题
\n
\n其他
\n\n"},{"version":"0.16.0","desc":"新增
\n\n- 允许选中列表内歌曲名、歌手名、专辑名内的文字,选中后可使用键盘快捷键进行复制
\n- 新增在列表可选内容区域鼠标右击时自动复制列表已选文字的功能
\n- 新增在搜索框鼠标右击时自动粘贴剪贴板的文本到搜索框中
\n- 任务下载失败时将显示搜索按钮,方便在其他源搜索该歌曲
\n
\n优化
\n\n- 优化木叶之村主题翻页器背景颜色
\n- 优化各个主题音质标签颜色
\n- 优化其他一些界面细节及用户交互效果
\n
\n修复
\n\n- 修复启用透明窗口鼠标不穿透的bug
\n- 修复大窗口时设置的音乐来源选项不换行的问题
\n- 修复某些情况下暂停任务会自动开始任务的问题
\n- 修复移除暂停、错误的任务时不删除未下载完成的文件的问题
\n- 修复酷狗源歌单热门标签歌单列表无法加载问题
\n- 修复QQ源歌单热门标签歌单列表无法加载问题
\n
\n其他
\n\n"},{"version":"0.15.0","desc":"洛雪提前祝大家新年快乐、身体健康、阖家幸福!
\n修复
\n\n- 修复歌曲下载列表无法加载的问题
\n- 修复歌曲下载任务数大于最大下载任务数的问题
\n- 修复某些情况下歌曲下载错误的问题
\n- 修复下载列表数据没有被迁移直接被丢弃的问题
\n
\n"},{"version":"0.14.1","desc":"洛雪提前祝大家新年快乐、身体健康、阖家幸福!
\n修复
\n\n- 修复由于旧版配置文件迁移出错导致的软件界面无法显示的问题
\n
\n"},{"version":"0.14.0","desc":"洛雪提前祝大家新年快乐、身体健康、阖家幸福!
\n新增
\n\n- 新增各大平台歌单热门标签显示(显示在歌单界面的第一个下拉标签菜单中)
\n- 恢复QQ音乐源128k音质试听
\n- 新增不强制win7开启透明效果即可使用,但要配置运行参数
-nt,例如:.\\lx-music-desktop.exe -nt,添加方法可自行百度“给快捷方式加参数” \n- 新增“新年快乐”主题,可自行切换体验
\n
\n优化
\n\n- 减淡各个主题的歌曲列表分隔线颜色
\n- 在线音乐列表音质标签优化,当歌曲有无损音质时隐藏高品质标签
\n- 更新改进的歌词播放插件,现在歌词的播放显示将更准确
\n
\n修复
\n\n- 修复咪咕源无法搜索的问题
\n- 修复更新弹窗底部文字颜色没有适配当前主题颜色的问题
\n- 修复导入设置窗口大小、代理设置不立即生效的问题
\n- 修复在线音乐列表获取失败时无限循环请求的问题
\n
\n其他
\n\n- 将软件设置与播放列表分离存储成两个文件
\n- 更新 Electron 到 7.1.9
\n
\n"},{"version":"0.13.1","desc":"修复
\n\n其他
\n\n- 由于electron 7.1.3 - 7.1.5 的自动更新功能存在Bug,现降级到7.1.2
\n
\n"},{"version":"0.13.0","desc":"新增
\n\n- 新增搜索框搜索建议键盘上下方向键选择功能
\n- 聚合搜索新增音源显示
\n- 新增“离开搜索界面时清空搜索列表”设置选项,默认关闭,可到设置-强迫症设置开启
\n
\n优化
\n\n修复
\n\n- 修复存在弹出层时,搜索建议列表被弹出层覆盖的问题
\n- 修复搜索、排行榜、歌单列表多选框从不定状态到选中的Bug
\n
\n移除
\n\n其他
\n\n- 更新electron到7.1.5
\n- 更新vue到2.6.11
\n
\n"},{"version":"0.12.1","desc":"优化
\n\n- 优化定位歌曲时的列表滚动机制
\n- 优化链接点击效果
\n
\n修复
\n\n- 修复使用酷我源下载歌曲时,当歌曲无封面时下载报错的问题
\n- 修复酷我源排行榜、歌单详情列表里的歌曲音质匹配问题(原来无论歌曲有无高品、无损都会显示有)
\n- 禁止外部链接在软件内打开,将所有外部链接从默认浏览器打开
\n
\n其他
\n\n"},{"version":"0.12.0","desc":"由于新下载库仍然没有完成,但下载功能已经可用,so 移除之前使用的第三方下载库,暂时把新下载库的下载模块直接加入本程序,若出现下载问题欢迎反馈!
\n新增
\n\n- 新增下载功能对代理设置的支持,现在若在软件设置了代理服务器,下载功能也将会走代理网络了
\n
\n优化
\n\n- 新下载模块将对恢复下载的任务进行字节校验,用于解决下载进度超过100%后仍然下载的问题
\n- 注意:目前仍然无法暂停处于链接获取状态中的任务
\n
\n修复
\n\n- 修复Linux deb版本
.desktop桌面文件缺少图标的问题,新增中文名称显示、软件分类,感谢@lowy的反馈! \n- 修复下载列表歌曲状态分类列表操作Bug
\n- 修复歌曲封面下载失败时仍然执行嵌入封面操作导致报错的问题
\n- 跳过重复添加相同歌曲名与扩展名的歌曲,例如你之前下载了A歌曲的128k音质,现在想要下载它的320k音质,但由于两者都是MP3格式,会因为重名导致之前的128k音质被覆盖但列表中仍然显示两种音质的问题(但实际上都是指向后面的320k音质)
\n
\n"},{"version":"0.11.0","desc":"新增
\n\n- 新增歌曲缓冲定时器,尝试用于解决网络正常但是歌曲缓冲过久的问题
\n- 新增下载管理的任务状态分类
\n- 添加杀毒软件提示有病毒或恶意行为的说明,可到常见问题拉到最后查看(常见问题可在开源地址找到)
\n
\n优化
\n\n- 优化更新弹窗机制及其内容描述,对于可以自动更新的版本,现在可以看到软件的下载进度了
\n
\n"},{"version":"0.10.0","desc":"优化
\n\n- 大幅减少程序播放时对CPU与GPU的使用,经测试CPU使用减少60%以上,GPU使用减少90%以上,这应该能解决MAC系统上的温度上涨的问题
\n
\n修复
\n\n- 修复酷我源搜索提示、排行榜无法获取的问题
\n- 修复咪咕源无法播放的问题
\n
\n"},{"version":"0.9.1","desc":"修复
\n\n"},{"version":"0.9.0","desc":"新增
\n\n- 新增窗口大小设置,若觉得软件窗口小可以到设置页调大点
\n- 新增定位当前播放歌曲,点击播放栏左侧的歌曲图片可在播放列表定位当前播放的歌曲(该功能对播放下载列表的歌曲无效)
\n
\n修复
\n\n- 修复搜索提示失效的问题
\n- 修复从歌单或列表点击搜索按钮搜索目标歌曲时,搜索框未聚焦仍然弹出候选搜索列表的问题
\n
\n"},{"version":"0.8.2","desc":"修复
\n\n- 兼容旧版酷我源搜索列表过滤128k音质的bug(注:0.8.1版本仅修复了酷我源的歌曲过滤问题,该修复仅对以后添加的歌曲有效,如果是之前添加的歌曲仍会出现这个问题,现修复对之前旧列表数据的兼容处理)
\n
\n"},{"version":"0.8.1","desc":"修复
\n\n- 修复酷我源搜索歌曲结果未添加128k音质导致播放128k音质时显示“该歌曲没有可播放的音频”的问题
\n
\n"},{"version":"0.8.0","desc":"新增
\n\n- 新增网易云源歌曲搜索
\n- 新增网易云源歌单
\n- 新增各平台通过输入歌单链接或歌单ID打开歌单详情列表,目前只适配了网页版歌单链接,其他方式的歌单链接可能无法解析,但你可想办法获取歌单ID后输入打开。注:各平台歌单ID均为纯数字,若遇到链接里存在歌单ID但无法解析的歌单链接,可以到GitHub提交issue或发送邮件或加群830125506反馈!
\n- 新增音量调整滑动功能,现在支持鼠标左右拖动调整音量了
\n
\n优化
\n\n- 优化搜索框搜索体验
\n- 优化音量条交互视觉效果
\n- 缓存歌单详情列表数据
\n
\n修复
\n\n- 修复QQ源歌单无法翻页Bug
\n- 修复默认列表没有创建时无法显示收藏列表的Bug
\n- 修复网易云128k直接试听
\n- 修复歌曲音质不存在时仍然播放或下载的Bug
\n- 修复调整音量时,调整的位置与鼠标点击的位置不一致的问题
\n
\n"},{"version":"0.7.0","desc":"新增
\n\n- 新增“我的收藏”本地播放列表
\n- 新增缓存清理功能,可到设置-其他查看与清理软件缓存
\n- 新增QQ音乐源搜索
\n- 新增咪咕源搜索
\n- 新增咪咕源歌单
\n- 新增咪咕源排行榜
\n- 新增我的音乐列表歌曲源显示,默认关闭,可到设置-列表设置开启
\n
\n优化
\n\n- 优化选择框动画效果
\n- 尝试优化选我的音乐列表内容很多时多选的卡顿问题
\n
\n修复
\n\n- 修复列表延迟显示的Bug
\n- 修复QQ音源128k音质试听
\n
\n"},{"version":"0.6.2","desc":"祝贺祖国成立70周年~!
\n新增
\n\n修复
\n\n- 修正火影皮肤名字
\n- 修复当试听列表为空时,无法切到其他界面的Bug
\n- 修复百度源搜索结果为空时的接口处理Bug
\n- 恢复酷狗其他音质播放
\n
\n"},{"version":"0.6.1","desc":"新增
\n\n- 新增试听列表滚动条位置恢复设置(可自动恢复到上次离开时的列表滚动位置),本功能默认开启,若不需要可到设置-列表设置将其关闭
\n- 新增 《海贼王》 皮肤,喜欢个性化的可以试试~
\n
\n优化
\n\n- 新增DNS解析缓存,加快请求速度
\n- 优化代码逻辑,减少软件对系统资源的占用
\n- 优化新版本信息检测,尽量减少弹出版本获取失败弹窗弹出的概率
\n- 优化下拉列表动画效果
\n
\n修复
\n\n- 修复请求超时的逻辑处理Bug,尝试修复请求无法取消导致的正在播放的歌曲与界面显示的信息不一致的问题
\n- 修复其他一些小Bug
\n
\n移除
\n\n- 移除
192k 音质 \n- 移除酷我音源
ape 音质,无损推荐 flac 格式 \n
\n"},{"version":"0.6.0","desc":"新增
\n\n- 新增音乐聚合搜索,目前支持酷我、酷狗、百度源搜索
\n- 新增代理功能
\n
\n优化
\n\n- 优化从《梦里嫦娥》皮肤切换到其他皮肤时侧栏动画的切换效果
\n
\n修复
\n\n- 修复试听列表没有歌曲时会显示列表加载中的Bug
\n- 修复切换歌单列表详情时的UI Bug
\n
\n"},{"version":"0.5.5","desc":"新增
\n\n- 月是故乡明,祝大家中秋快乐🥮~~新增个性皮肤**《月里嫦娥》**,时间仓促,皮肤还不是很完善,可以试试喜不喜欢~😉
\n- 新增 MAC 版本退出快捷键支持
\n- 新增点击播放器中的歌曲标题可以复制标题的功能(遇到好听的歌曲方便分享)
\n
\n修复
\n\n- 修复 MAC 系统下软件关闭时再次从 dock 打开时报错的Bug
\n- 修复下载的歌曲文件名中包含命名规则不允许的符号时下载失败的问题(若歌曲名包含这些符号会自动将其移除)
\n- 修复 MAC 版本不能复制粘贴的问题
\n
\n"},{"version":"0.5.4","desc":"移除
\n\n- 下载的FLAC文件在修改歌曲信息后,软件无法播放,但使用本地播放器可以播放
\n- 为了稳妥起见,暂时移除FLAC格式的meta信息修改
\n- MP3格式无此问题
\n
\n"},{"version":"0.5.3","desc":"优化
\n\n修复
\n\n- 修复试听酷狗源的音乐仍然获取320k音质导致获取失败的Bug
\n
\n"},{"version":"0.5.2","desc":"新增
\n\n- 新增强迫症设置-离开搜索界面时是否清空搜索框
\n- 设置-关于板块新增常见问题链接
\n- 歌单左上角的分类按钮添加一个向下图标,方便识别该按钮为下拉框(该按钮可选择歌单类型,请自行尝试)
\n
\n优化
\n\n- 略微优化最小化按钮字符
\n- 优化试听列表的加载体验,当歌曲数过多时列表将延迟加载
\n
\n修复
\n\n移除
\n\n- 因接口失效,移除网易云音源,酷狗音源仅支持播放128k音质
\n
\n"},{"version":"0.5.1","desc":"新增
\n\n- 新增右上角最小化/关闭按钮鼠标滑过符号
\n- 新增下载列表定位文件按钮
\n
\n修复
\n\n- 修复百度源歌单全部分类无法加载的问题
\n- 修复更新弹窗无法弹出的问题
\n
\n"},{"version":"0.5.0","desc":"新增
\n\n- 新增封面嵌入(默认开启,可到设置-下载设置关闭)
\n- 新增歌词下载(默认关闭,可到设置-下载设置开启)
\n- 新增单例应用功能(实现软件单开功能,禁止软件多开)
\n
\n优化
\n\n修复
\n\n- 修复歌单无法翻页的问题
\n- 修复在某些情况下,添加下载歌曲导致下载列表崩溃的问题
\n- 修复版本更新弹窗Bug
\n- 修复酷狗歌单推荐歌单出现在其他分类中的Bug
\n
\n"},{"version":"0.4.0","desc":"新增
\n\n- 新增歌单功能,目前支持酷我、酷狗、百度源歌单
\n- 在设置界面-关于洛雪音乐说明部分新增最新版网盘下载地址与打赏地址
\n- 新增酷狗 电音热歌榜、DJ热歌榜
\n- 新增版本更新超时功能,对于部分无法访问GitHub的用户做更新超时提醒
\n
\n移除
\n\n- 注意:0.4.0以前的版本即将失效,请更新到0.4.0版本
\n
\n"},{"version":"0.3.5","desc":"新增
\n\n- 新增测试接口,该接口同样速度较慢,但软件的大部分功能可用,请自行切换到该接口,找接口辛苦,且用且珍惜!
\n
\n优化
\n\n- 取消需要刷新URL时windows任务栏进度显示错误状态(现显示为暂停状态)
\n
\n修复
\n\n- 修复使用临时接口时在试听列表双击灰色歌曲仍然会进行播放的Bug
\n- 修复歌词加载Bug
\n
\n"},{"version":"0.3.4","desc":"优化
\n\n- 减少接口不稳定带来的影响,适当增加请求等待时间
\n
\n修复
\n\n- 修复播放过程中URL过期不会刷新URL的问题
\n
\n"},{"version":"0.3.3","desc":"修复
\n\n- messoer的接口已经关闭,暂时切换到临时接口使用,部分功能受限。。。
\n- 修复设置界面更新出错时仍然显示更新下载中的问题
\n- 修复手动定位播放进度条时存在偏差的问题
\n- 屏蔽播放器中没有歌曲时对进度条的点击
\n
\n"},{"version":"0.3.2","desc":"新增
\n\n"},{"version":"0.3.1","desc":"修复
\n\n"},{"version":"0.3.0","desc":"新增
\n\n- 新增MAC及Linux版本(需要的可自行下载)
\n- 新增音量调整
\n- 新增任务栏播放进度条控制选项(现在可在设置界面关闭在任务栏显示的播放进度)
\n- 新增更新出错时的弹窗提示
\n- 从该版本起,非安装版也会有更新弹窗提醒了,但仍然需要手动下载新版本更新,版本信息可到设置页面查看
\n
\n修复
\n\n- 强制把临时接口设置回
messoer 接口 \n
\n"},{"version":"0.2.3","desc":"新增
\n\n- 新增任务栏程序标题改变功能(播放歌曲时任务栏标题将显示当前播放的歌曲)
\n
\n修复
\n\n- 使用临时接口时,试听列表中的下载按钮仍然能点击的Bug
\n- 修复某些情况下歌曲链接未能缓存的问题
\n
\n移除
\n\n- 移除临时接口(因服务器被攻击,本接口已关闭)
\n- 移除列表栏设置的隐藏专辑栏选项(感觉这个设置并没有什么luan用,并且还会打破布局)
\n
\n"},{"version":"0.2.2","desc":"修复
\n\n- 修复下载过程中出错重试5次都失败后不会自动开始下一个任务的Bug
\n- 修复播放到一半URL过期时不会刷新URL直接播放下一首的问题
\n
\n"},{"version":"0.2.1","desc":"优化
\n\n- 新增歌曲URL存储,当URL无效时才重新获取,以减少接口不稳定的影响
\n
\n修复
\n\n- 修复歌曲加载无法加载时自动切换混乱的Bug
\n- 修复移除列表最后一首歌曲时播放器不停止播放的问题
\n
\n"},{"version":"0.2.0","desc":"新增
\n\n- 新增百度音乐排行榜及其音乐直接试听与下载
\n- 新增网易云排行榜音乐直接试听与下载(目前仅支持128k音质)
\n- 新增酷狗排行榜音乐直接试听与下载(目前仅支持128k音质)
\n
\n修复
\n\n- 修复更新弹窗历史版本描述多余的换行问题
\n- 修复歌曲无法播放的情况下歌词仍会播放的问题
\n
\n"},{"version":"0.1.6","desc":"修复
\n\n"},{"version":"0.1.5","desc":"新增
\n\n- 新增搜索列表批量试听与下载功能
\n- 新增排行榜列表批量试听与下载功能
\n- 新增试听列表批量移除与下载功能
\n- 新增下载列表批量开始、暂停与移除功能
\n
\n优化
\n\n"},{"version":"0.1.4","desc":"新增
\n\n- 新增音乐来源切换,可到设置页面-基本设置 look look !
\n- 为搜索结果列表添加多选功能。
\nP.S:暂时没想好多选后的操作按钮放哪… \n
\n优化
\n\n- 重构与改进checkbox组件,使其支持不定选中状态
\n- 完善上一个版本的http请求封装并切换部分请求到该方法上
\n- 优化其他一些细节
\n
\n"},{"version":"0.1.3","desc":"新增
\n\n修复
\n\n- 修复安装包许可协议乱码问题
\n- messoer 提供的接口已挂,暂时切换到临时接口!
\n
\n移除
\n\n- 由于messoer接口无法使用,QQ音乐排行榜直接播放/下载功能暂时关闭
\n
\n"},{"version":"0.1.2","desc":"修复
\n\n"},{"version":"0.1.1","desc":"新增
\n\n- QQ音乐排行榜直接试听与下载(该接口貌似不太稳定,且用且珍惜!)
\n
\n优化
\n\n- 优化http请求机制
\n- 更新关于本软件说明
\n
\n修复
\n\n- 修复当上一个歌曲链接正在获取时切换歌曲请求不会取消的问题
\n- 修复切换歌曲时仍然播放上一首歌曲的问题
\n
\n"},{"version":"0.1.0","desc":"0.1.0版本发布"}]}
diff --git a/src/main/utils/flacMeta.js b/src/main/utils/flacMeta.js
index ab9a18ba..43362ac4 100644
--- a/src/main/utils/flacMeta.js
+++ b/src/main/utils/flacMeta.js
@@ -72,9 +72,9 @@ module.exports = (filePath, meta) => {
if (respones.statusCode !== 200 && respones.statusCode != 206) return writeMeta(filePath, meta)
respones
.pipe(fs.createWriteStream(picPath))
- .on('finish', () => {
+ .on('finish', async() => {
if (respones.complete) {
- writeMeta(filePath, meta, picPath)
+ await writeMeta(filePath, meta, picPath)
} else {
writeMeta(filePath, meta)
}
diff --git a/src/renderer/assets/images/defaultUser.jpg b/src/renderer/assets/images/defaultUser.jpg
new file mode 100644
index 00000000..51d5929d
Binary files /dev/null and b/src/renderer/assets/images/defaultUser.jpg differ
diff --git a/src/renderer/assets/styles/variables.less b/src/renderer/assets/styles/variables.less
index 225eaab4..1957fa74 100644
--- a/src/renderer/assets/styles/variables.less
+++ b/src/renderer/assets/styles/variables.less
@@ -23,6 +23,7 @@
@color-theme_2-font-label: fadeout(@color-theme_2-font, 50%);
// @color-theme_2-line: transparent;
@color-theme_2-line: lighten(@color-theme, 35%);
+@color-reply-floor: fadeout(@color-theme, 95%);
@color-theme-sidebar: @color-theme;
@color-btn: lighten(@color-theme, 5%);
@color-btn-background: fadeout(lighten(@color-theme, 35%), 70%);
@@ -91,6 +92,7 @@
@color-green-theme_2-font-label: fadeout(@color-green-theme_2-font, 50%);
// @color-green-theme_2-line: transparent;
@color-green-theme_2-line: lighten(@color-green-theme, 45%);
+@color-green-reply-floor: fadeout(@color-green-theme, 95%);
@color-green-theme-sidebar: @color-green-theme;
@color-green-btn: lighten(@color-green-theme, 5%);
@color-green-btn-background: fadeout(lighten(@color-green-theme, 35%), 70%);
@@ -148,6 +150,7 @@
@color-yellow-theme_2-font-label: fadeout(@color-yellow-theme_2-font, 50%);
// @color-yellow-theme_2-line: transparent;
@color-yellow-theme_2-line: lighten(@color-yellow-theme, 28%);
+@color-yellow-reply-floor: fadeout(@color-yellow-theme, 94%);
@color-yellow-theme-sidebar: @color-yellow-theme;
@color-yellow-btn: darken(@color-yellow-theme, 5%);
@color-yellow-btn-background: fadeout(lighten(@color-yellow-theme, 25%), 60%);
@@ -204,6 +207,7 @@
@color-orange-theme_2-font-label: fadeout(@color-orange-theme_2-font, 50%);
// @color-orange-theme_2-line: transparent;
@color-orange-theme_2-line: lighten(@color-orange-theme, 36%);
+@color-orange-reply-floor: fadeout(@color-orange-theme, 95%);
@color-orange-theme-sidebar: @color-orange-theme;
@color-orange-btn: lighten(@color-orange-theme, 5%);
@color-orange-btn-background: fadeout(lighten(@color-orange-theme, 25%), 60%);
@@ -260,6 +264,7 @@
@color-blue-theme_2-font-label: fadeout(@color-blue-theme_2-font, 50%);
// @color-blue-theme_2-line: transparent;
@color-blue-theme_2-line: lighten(@color-blue-theme, 42%);
+@color-blue-reply-floor: fadeout(@color-blue-theme, 95%);
@color-blue-theme-sidebar: @color-blue-theme;
@color-blue-btn: lighten(@color-blue-theme, 5%);
@color-blue-btn-background: fadeout(lighten(@color-blue-theme, 35%), 50%);
@@ -316,6 +321,7 @@
@color-red-theme_2-font-label: fadeout(@color-red-theme_2-font, 50%);
// @color-red-theme_2-line: transparent;
@color-red-theme_2-line: lighten(@color-red-theme, 42%);
+@color-red-reply-floor: fadeout(@color-red-theme, 95%);
@color-red-theme-sidebar: @color-red-theme;
@color-red-btn: lighten(@color-red-theme, 5%);
@color-red-btn-background: fadeout(lighten(@color-red-theme, 35%), 70%);
@@ -374,6 +380,7 @@
@color-pink-theme_2-font-label: fadeout(@color-pink-theme_2-font, 50%);
// @color-pink-theme_2-line: transparent;
@color-pink-theme_2-line: lighten(@color-pink-theme, 25%);
+@color-pink-reply-floor: fadeout(@color-pink-theme, 93%);
@color-pink-theme-sidebar: @color-pink-theme;
@color-pink-btn: darken(@color-pink-theme, 3%);
@color-pink-btn-background: fadeout(lighten(@color-pink-theme, 20%), 50%);
@@ -430,6 +437,7 @@
@color-purple-theme_2-font-label: fadeout(@color-purple-theme_2-font, 50%);
// @color-purple-theme_2-line: transparent;
@color-purple-theme_2-line: lighten(@color-purple-theme, 43%);
+@color-purple-reply-floor: fadeout(@color-purple-theme, 95%);
@color-purple-theme-sidebar: @color-purple-theme;
@color-purple-btn: lighten(@color-purple-theme, 5%);
@color-purple-btn-background: fadeout(lighten(@color-purple-theme, 35%), 70%);
@@ -486,6 +494,7 @@
@color-grey-theme_2-font-label: fadeout(@color-grey-theme_2-font, 50%);
// @color-grey-theme_2-line: transparent;
@color-grey-theme_2-line: lighten(@color-grey-theme, 47%);
+@color-grey-reply-floor: fadeout(@color-grey-theme, 95%);
@color-grey-theme-sidebar: @color-grey-theme;
@color-grey-btn: lighten(@color-grey-theme, 5%);
@color-grey-btn-background: fadeout(lighten(@color-grey-theme, 35%), 70%);
@@ -543,6 +552,7 @@
@color-ming-theme_2-font-label: fadeout(@color-ming-theme_2-font, 50%);
// @color-ming-theme_2-line: transparent;
@color-ming-theme_2-line: lighten(@color-ming-theme, 60%);
+@color-ming-reply-floor: fadeout(@color-ming-theme, 95%);
@color-ming-theme-sidebar: @color-ming-theme;
@color-ming-btn: lighten(@color-ming-theme, 5%);
@color-ming-btn-background: fadeout(lighten(@color-ming-theme, 35%), 75%);
@@ -602,6 +612,7 @@
@color-blue2-theme_2-font-label: fadeout(@color-blue2-theme_2-font, 50%);
// @color-blue2-theme_2-line: transparent;
@color-blue2-theme_2-line: lighten(@color-blue2-theme, 41%);
+@color-blue2-reply-floor: fadeout(@color-blue2-theme, 95%);
@color-blue2-theme-sidebar: @color-blue2-theme;
@color-blue2-btn: lighten(@color-blue2-theme, 5%);
@color-blue2-btn-background: fadeout(lighten(@color-blue2-theme, 30%), 70%);
@@ -651,7 +662,7 @@
@color-mid_autumn-theme-font: rgba(246, 233, 255, 0.9);
@color-mid_autumn-theme-font-label: fadeout(lighten(@color-mid_autumn-theme, 20%), 20%);
@color-mid_autumn-theme_2: rgba(255, 255, 255, .9);
-@color-mid_autumn-theme_2-background_1: #e7e7e9;
+@color-mid_autumn-theme_2-background_1: #ececec;
@color-mid_autumn-theme_2-background_2: fadeout(@color-mid_autumn-theme_2-background_1, 2%);
@color-mid_autumn-theme_2-hover: fadeout(lighten(@color-mid_autumn-theme, 15%), 80%);
@color-mid_autumn-theme_2-active: fadeout(lighten(@color-mid_autumn-theme, 15%), 70%);
@@ -659,6 +670,7 @@
@color-mid_autumn-theme_2-font-label: desaturate(lighten(@color-mid_autumn-theme, 30%), 45%);
// @color-mid_autumn-theme_2-line: transparent;
@color-mid_autumn-theme_2-line: lighten(@color-mid_autumn-theme, 61%);
+@color-mid_autumn-reply-floor: fadeout(@color-mid_autumn-theme, 95%);
@color-mid_autumn-theme-sidebar: rgba(255, 255, 255, 0);
@color-mid_autumn-btn: lighten(@color-mid_autumn-theme, 10%);
@color-mid_autumn-btn-background: fadeout(lighten(@color-mid_autumn-theme, 35%), 70%);
@@ -716,6 +728,7 @@
@color-mid_autumn-theme_2-font-label: desaturate(lighten(@color-mid_autumn-theme, 30%), 45%);
// @color-mid_autumn-theme_2-line: transparent;
@color-mid_autumn-theme_2-line: darken(@color-mid_autumn-theme, 18%);
+@color-mid_autumn-reply-floor: fadeout(@color-mid_autumn-theme, 95%);
@color-mid_autumn-theme-sidebar: rgba(255, 255, 255, 0);
@color-mid_autumn-btn: darken(@color-mid_autumn-theme, 10%);
@color-mid_autumn-btn-background: fadeout(lighten(@color-mid_autumn-theme, 35%), 70%);
@@ -772,6 +785,7 @@
@color-naruto-theme_2-font-label: desaturate(lighten(@color-naruto-theme, 10%), 45%);
// @color-naruto-theme_2-line: transparent;
@color-naruto-theme_2-line: fadeout(lighten(@color-naruto-theme, 36%), 70%);
+@color-naruto-reply-floor: fadeout(lighten(@color-naruto-theme, 12%), 90%);
@color-naruto-theme-sidebar: rgba(255, 255, 255, .3);
@color-naruto-btn: lighten(@color-naruto-theme, 2%);
@color-naruto-btn-background: fadeout(lighten(@color-naruto-theme, 35%), 70%);
@@ -828,6 +842,7 @@
@color-happy_new_year-theme_2-font-label: desaturate(darken(@color-happy_new_year-theme, 5%), 50%);
// @color-happy_new_year-theme_2-line: transparent;
@color-happy_new_year-theme_2-line: fadeout(lighten(@color-happy_new_year-theme, 16%), 70%);
+@color-happy_new_year-reply-floor: fadeout(lighten(@color-happy_new_year-theme, 12%), 85%);
@color-happy_new_year-theme-sidebar: rgba(119, 37, 18, 0.1);
@color-happy_new_year-btn: desaturate(@color-happy_new_year-theme, 10%);
@color-happy_new_year-btn-background: fadeout(lighten(@color-happy_new_year-theme, 15%), 60%);
diff --git a/src/renderer/components/core/Icons.vue b/src/renderer/components/core/Icons.vue
index c7e1332d..cef053fd 100644
--- a/src/renderer/components/core/Icons.vue
+++ b/src/renderer/components/core/Icons.vue
@@ -75,8 +75,8 @@ svg(version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/19
// 0 0 512 512
path(d='M511.563,434.259c-1.728-142.329-124.42-258.242-277.087-263.419V95.999c0-17.645-14.342-31.999-31.974-31.999 c-7.931,0-15.591,3.042-21.524,8.562c0,0-134.828,124.829-173.609,163.755C2.623,241.109,0,248.088,0,255.994 c0,7.906,2.623,14.885,7.369,19.687c38.781,38.915,173.609,163.745,173.609,163.745c5.933,5.521,13.593,8.562,21.524,8.562 c17.631,0,31.974-14.354,31.974-31.999v-74.591c153.479,2.156,255.792,50.603,255.792,95.924c0,5.896,4.767,10.666,10.658,10.666 c0.167,0.021,0.333,0.01,0.416,0c5.891,0,10.658-4.771,10.658-10.666C512,436.259,511.854,435.228,511.563,434.259z')
g#icon-refresh(fill='currentColor')
- // 0 0 512 512
- path(d='M440.65 12.57l4 82.77A247.16 247.16 0 0 0 255.83 8C134.73 8 33.91 94.92 12.29 209.82A12 12 0 0 0 24.09 224h49.05a12 12 0 0 0 11.67-9.26 175.91 175.91 0 0 1 317-56.94l-101.46-4.86a12 12 0 0 0-12.57 12v47.41a12 12 0 0 0 12 12H500a12 12 0 0 0 12-12V12a12 12 0 0 0-12-12h-47.37a12 12 0 0 0-11.98 12.57zM255.83 432a175.61 175.61 0 0 1-146-77.8l101.8 4.87a12 12 0 0 0 12.57-12v-47.4a12 12 0 0 0-12-12H12a12 12 0 0 0-12 12V500a12 12 0 0 0 12 12h47.35a12 12 0 0 0 12-12.6l-4.15-82.57A247.17 247.17 0 0 0 255.83 504c121.11 0 221.93-86.92 243.55-201.82a12 12 0 0 0-11.8-14.18h-49.05a12 12 0 0 0-11.67 9.26A175.86 175.86 0 0 1 255.83 432z')
+ // 0 0 24 24
+ path(d='M12,6V9L16,5L12,1V4A8,8 0 0,0 4,12C4,13.57 4.46,15.03 5.24,16.26L6.7,14.8C6.25,13.97 6,13 6,12A6,6 0 0,1 12,6M18.76,7.74L17.3,9.2C17.74,10.04 18,11 18,12A6,6 0 0,1 12,18V15L8,19L12,23V20A8,8 0 0,0 20,12C20,10.43 19.54,8.97 18.76,7.74Z')
g#icon-eraser(fill='currentColor')
// 0 0 512 512
path(d='M497.941 273.941c18.745-18.745 18.745-49.137 0-67.882l-160-160c-18.745-18.745-49.136-18.746-67.883 0l-256 256c-18.745 18.745-18.745 49.137 0 67.882l96 96A48.004 48.004 0 0 0 144 480h356c6.627 0 12-5.373 12-12v-40c0-6.627-5.373-12-12-12H355.883l142.058-142.059zm-302.627-62.627l137.373 137.373L265.373 416H150.628l-80-80 124.686-124.686z')
@@ -206,5 +206,16 @@ svg(version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/19
path(d='M256,170s-62.469-76.808-141-24C44.762,222.824,84.909,325.08,256,415c21.339-8.361,44-17,44-17,19-6.392,28.155,20.742,16,26-27.589,11.935,5.974-4.141-60,28C-35.524,313.85,43.993,149.031,95,117c86.8-65.89,162,10,162,10s58.158-60.523,140-23c104.032,58.528,64,161.9,45,196-9.152,15.154-39.559-4.159-32-16,20.34-37.888,45.522-107.349-25-150C314.919,103.92,256,170,256,170Z')
path(d='M383,368c-8.1.01-24.77-.155-40,0-15.713.16-15.282,34.964,0,35,15.1,0.035,40,0,40,0s-0.068,42.8,0,48c0.208,15.961,32.261,15.791,32-1-0.072-4.649,0-47,0-47s38.008-.031,43,0c15.732,0.046,14.947-33.98-1-34-4.884.093-42,0-42,0s-0.053-28.341,0-46c0.046-15.189-32.028-15.512-32,0C383.027,337.74,382.782,365.139,383,368Z')
+ g#icon-thumbs-up(fill='currentColor')
+ // 0 0 512 512
+ path(d='M466.27 286.69C475.04 271.84 480 256 480 236.85c0-44.015-37.218-85.58-85.82-85.58H357.7c4.92-12.81 8.85-28.13 8.85-46.54C366.55 31.936 328.86 0 271.28 0c-61.607 0-58.093 94.933-71.76 108.6-22.747 22.747-49.615 66.447-68.76 83.4H32c-17.673 0-32 14.327-32 32v240c0 17.673 14.327 32 32 32h64c14.893 0 27.408-10.174 30.978-23.95 44.509 1.001 75.06 39.94 177.802 39.94 7.22 0 15.22.01 22.22.01 77.117 0 111.986-39.423 112.94-95.33 13.319-18.425 20.299-43.122 17.34-66.99 9.854-18.452 13.664-40.343 8.99-62.99zm-61.75 53.83c12.56 21.13 1.26 49.41-13.94 57.57 7.7 48.78-17.608 65.9-53.12 65.9h-37.82c-71.639 0-118.029-37.82-171.64-37.82V240h10.92c28.36 0 67.98-70.89 94.54-97.46 28.36-28.36 18.91-75.63 37.82-94.54 47.27 0 47.27 32.98 47.27 56.73 0 39.17-28.36 56.72-28.36 94.54h103.99c21.11 0 37.73 18.91 37.82 37.82.09 18.9-12.82 37.81-22.27 37.81 13.489 14.555 16.371 45.236-5.21 65.62zM88 432c0 13.255-10.745 24-24 24s-24-10.745-24-24 10.745-24 24-24 24 10.745 24 24z')
+
+ g#icon-close(fill='currentColor')
+ // 0 0 24 24
+ path(d='M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z')
+
+ g#icon-comment(fill='currentColor')
+ // 0 0 24 24
+ path(d='M16 11H8V9H16V11M22 4V16C22 17.11 21.11 18 20 18H13.9L10.2 21.71C10 21.9 9.75 22 9.5 22H9C8.45 22 8 21.55 8 21V18H4C2.9 18 2 17.11 2 16V4C2 2.89 2.9 2 4 2H20C21.11 2 22 2.9 22 4M20 4H4V16H10V19.08L13.08 16H20V4')
diff --git a/src/renderer/components/core/Player.vue b/src/renderer/components/core/Player.vue
index 09af86de..9f6d9053 100644
--- a/src/renderer/components/core/Player.vue
+++ b/src/renderer/components/core/Player.vue
@@ -17,9 +17,9 @@ div(:class="$style.player")
div(:class="$style.volumeMask" @mousedown="handleVolumeMsDown" ref="dom_volumeMask" :tips="`${$t('core.player.volume')}${parseInt(volume * 100)}%`")
div(:class="$style.titleBtn" @click='toggleDesktopLyric' @contextmenu="handleToggleLockDesktopLyric" :tips="toggleDesktopLyricBtnTitle")
svg(v-if="setting.desktopLyric.enable" version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' height='100%' viewBox='0 0 512 512' space='preserve')
- use(xlink:href='#icon-desktop-lyric-off')
- svg(v-else version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' height='100%' viewBox='0 0 512 512' space='preserve')
use(xlink:href='#icon-desktop-lyric-on')
+ svg(v-else version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' height='100%' viewBox='0 0 512 512' space='preserve')
+ use(xlink:href='#icon-desktop-lyric-off')
div(:class="$style.titleBtn" @click='toggleNextPlayMode' :tips="nextTogglePlayName")
svg(v-if="setting.player.togglePlayMethod == 'listLoop'" version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' height='80%' viewBox='0 0 24 24' space='preserve')
use(xlink:href='#icon-list-loop')
@@ -63,10 +63,12 @@ div(:class="$style.player")
//- transition(enter-active-class="animated lightSpeedIn"
transition(enter-active-class="animated lightSpeedIn"
leave-active-class="animated slideOutDown")
- core-player-detail(v-if="isShowPlayerDetail" :musicInfo="musicInfo"
+ core-player-detail(v-if="isShowPlayerDetail" :musicInfo="listId == 'download' ? targetSong.musicInfo : targetSong"
:lyric="lyric" :list="list" :listId="listId"
:playInfo="{ nowPlayTimeStr, maxPlayTimeStr, progress, nowPlayTime, status }"
- :isPlay="isPlay" @action="handlePlayDetailAction")
+ :isPlay="isPlay" @action="handlePlayDetailAction"
+ :nextTogglePlayName="nextTogglePlayName"
+ @toggle-next-play-mode="toggleNextPlayMode" @add-music-to="addMusicTo")
material-list-add-modal(:show="isShowAddMusicTo" :musicInfo="listId == 'download' ? targetSong.musicInfo : targetSong" @close="isShowAddMusicTo = false")
svg(version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' style="display: none;")
@@ -767,6 +769,7 @@ export default {
})
},
showPlayerDetail() {
+ if (!this.targetSong) return
this.visiblePlayerDetail(true)
},
handleTransitionEnd(e) {
diff --git a/src/renderer/components/core/PlayerDetail.vue b/src/renderer/components/core/PlayerDetail.vue
index c085d7c3..2aad7d09 100644
--- a/src/renderer/components/core/PlayerDetail.vue
+++ b/src/renderer/components/core/PlayerDetail.vue
@@ -16,25 +16,44 @@
svg(:class="$style.controBtnIcon" version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' width='100%' viewBox='0 0 24 24' space='preserve')
use(xlink:href='#icon-window-close')
- div(:class="$style.main")
+ div(:class="[$style.main, isShowComment ? $style.showComment : null]")
div(:class="$style.left")
+ //- div(:class="$style.info")
div(:class="$style.info")
- div(:class="$style.img")
- img(:src="musicInfo.img" v-if="musicInfo.img")
+ img(:class="$style.img" :src="musicInfo.img" v-if="musicInfo.img")
div(:class="$style.description")
p {{$t('core.player.name')}}{{musicInfo.name}}
p {{$t('core.player.singer')}}{{musicInfo.singer}}
p(v-if="musicInfo.album") {{$t('core.player.album')}}{{musicInfo.album}}
- //- div(:class="$style.list")
- ul
div(:class="$style.right")
div(:class="[$style.lyric, lyricEvent.isMsDown ? $style.draging : null]" @wheel="handleWheel" @mousedown="handleLyricMouseDown" ref="dom_lyric")
div(:class="$style.lyricSpace")
p(v-for="(info, index) in lyricLines" :key="index" :class="lyric.line == index ? $style.lrcActive : null") {{info.text}}
div(:class="$style.lyricSpace")
+
+ material-music-comment(:class="$style.comment" :titleFormat="this.setting.download.fileName" :musicInfo="musicInfo" v-model="isShowComment")
+
div(:class="$style.footer")
- div(:class="$style.left")
+ div(:class="$style.footerLeft")
+ div(:class="$style.footerLeftControlBtns")
+ div(:class="[$style.footerLeftControlBtn, isShowComment ? $style.active : null]" @click="isShowComment = !isShowComment" :tips="$t('core.player.comment_show')")
+ svg(version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' width='95%' viewBox='0 0 24 24' space='preserve')
+ use(xlink:href='#icon-comment')
+ div(:class="$style.footerLeftControlBtn" @click="$emit('toggle-next-play-mode')" :tips="nextTogglePlayName")
+ svg(v-if="setting.player.togglePlayMethod == 'listLoop'" version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' viewBox='0 0 24 24' space='preserve')
+ use(xlink:href='#icon-list-loop')
+ svg(v-else-if="setting.player.togglePlayMethod == 'random'" version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' viewBox='0 0 24 24' space='preserve')
+ use(xlink:href='#icon-list-random')
+ svg(v-else-if="setting.player.togglePlayMethod == 'list'" version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' width='120%' viewBox='0 0 24 24' space='preserve')
+ use(xlink:href='#icon-list-order')
+ svg(v-else-if="setting.player.togglePlayMethod == 'singleLoop'" version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' width='110%' viewBox='0 0 24 24' space='preserve')
+ use(xlink:href='#icon-single-loop')
+ svg(v-else version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' width='120%' viewBox='0 0 24 24' space='preserve')
+ use(xlink:href='#icon-single')
+ div(:class="$style.footerLeftControlBtn" @click="$emit('add-music-to', musicInfo)" :tips="$t('core.player.add_music_to')")
+ svg(version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' viewBox='0 0 512 512' space='preserve')
+ use(xlink:href='#icon-add-2')
div(:class="$style.progressContainer")
div(:class="$style.progressContent")
div(:class="$style.progress")
@@ -124,6 +143,7 @@ export default {
type: Boolean,
default: false,
},
+ nextTogglePlayName: String,
},
watch: {
// 'musicInfo.img': {
@@ -205,6 +225,7 @@ export default {
_lyricLines: [],
lyricLines: [],
isSetedLines: false,
+ isShowComment: false,
}
},
mounted() {
@@ -452,33 +473,56 @@ export default {
overflow: hidden;
display: flex;
padding: 0 30px;
+
+ &.showComment {
+ .left {
+ flex-basis: 18%;
+ .description p {
+ font-size: 12px;
+ }
+ }
+ .right {
+ flex-basis: 30%;
+ .lyric {
+ font-size: 13px;
+ }
+ }
+ .comment {
+ flex-basis: 50%;
+ opacity: 1;
+ }
+ }
}
.left {
- flex: 0 0 40%;
- overflow: hidden;
-}
-.info {
+ flex: 40%;
display: flex;
flex-flow: column nowrap;
align-items: center;
+ padding: 13px;
+ overflow: hidden;
+ transition: flex-basis @transition-theme;
+}
+
+.info {
+ display: flex;
+ flex-flow: column nowrap;
+ justify-content: flex-start;
+ max-width: 300px;
+
}
.img {
- width: 300px;
- height: 300px;
- display: flex;
- justify-content: flex-start;
- align-items: center;
-
- img {
- max-width: 100%;
- max-height: 100%;
- border: 5px solid @color-theme-hover;
- // border-radius: @radius-border;
- // border: 5px solid #fff;
- }
+ max-width: 100%;
+ max-height: 100%;
+ min-width: 100%;
+ box-shadow: 0 0 4px @color-theme-hover;
+ border-radius: 6px;
+ opacity: .8;
+ // border: 5px solid @color-theme-hover;
+ // border-radius: @radius-border;
+ // border: 5px solid #fff;
}
.description {
- width: 300px;
+ max-width: 300px;
padding: 15px 0;
overflow: hidden;
p {
@@ -492,6 +536,8 @@ export default {
flex: 0 0 60%;
// padding: 0 30px;
position: relative;
+ transition: flex-basis @transition-theme;
+
&:before {
position: absolute;
top: 0;
@@ -537,18 +583,51 @@ export default {
color: @color-theme;
font-size: 1.2em;
}
+
+.comment {
+ flex: 0 0 0;
+ opacity: 0;
+ margin-left: 10px;
+}
+
.footer {
flex: 0 0 100px;
overflow: hidden;
display: flex;
align-items: center;
}
-.left {
+.footerLeft {
flex: auto;
display: flex;
flex-flow: column nowrap;
- align-items: center;
- padding-top: 13px;
+ padding: 13px;
+ overflow: hidden;
+}
+.footerLeftControlBtns {
+ color: @color-theme_2-font;
+ display: flex;
+ flex-flow: row nowrap;
+ justify-content: flex-end;
+}
+.footerLeftControlBtn {
+ width: 18px;
+ height: 18px;
+ opacity: .5;
+ cursor: pointer;
+ transition: opacity @transition-theme;
+
+ &:hover {
+ opacity: .9;
+ }
+
+ +.footerLeftControlBtn {
+ margin-left: 6px;
+ }
+
+ &.active {
+ color: @color-theme;
+ opacity: .8;
+ }
}
.progress-container {
width: 100%;
@@ -608,6 +687,7 @@ export default {
}
.time-label {
width: 100%;
+ height: 18px;
display: flex;
justify-content: space-between;
span {
@@ -686,13 +766,20 @@ each(@themes, {
}
}
.img {
- img {
- border-color: ~'@{color-@{value}-theme-hover}';
- }
+ box-shadow: 0 0 4px ~'@{color-@{value}-theme-hover}';
+ // border-color: ~'@{color-@{value}-theme-hover}';
}
.lrc-active {
color: ~'@{color-@{value}-theme}';
}
+ .footerLeftControlBtns {
+ color: ~'@{color-@{value}-theme_2-font}';
+ }
+ .footerLeftControlBtn {
+ &.active {
+ color: ~'@{color-@{value}-theme}';
+ }
+ }
.progress {
background-color: ~'@{color-@{value}-player-progress}';
}
diff --git a/src/renderer/components/material/CommentFloor.vue b/src/renderer/components/material/CommentFloor.vue
new file mode 100644
index 00000000..0a776505
--- /dev/null
+++ b/src/renderer/components/material/CommentFloor.vue
@@ -0,0 +1,162 @@
+
+ div(:class="$style.container")
+ ul
+ li(v-for="(item, index) in comments" :key="item.id" :class="$style.listItem")
+ div(:class="$style.content")
+ div(:class="$style.left")
+ img( :class="$style.avatar" :src="item.avatar || commentDefImg" @error="handleUserImg")
+ div(:class="$style.right")
+ div(:class="$style.info")
+ div.select(:class="$style.name") {{item.userName}}
+ time(:class="$style.time" v-if="item.timeStr") {{timeFormat(item.timeStr)}}
+ div(:class="$style.likes" v-if="item.likedCount != null")
+ svg(:class="$style.likesIcon" version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' viewBox='0 0 512 512' space='preserve')
+ use(xlink:href='#icon-thumbs-up')
+ | {{item.likedCount}}
+ div.select(:class="$style.comment_text")
+ p(v-for="text in item.text") {{text}}
+ material-comment-floor(v-if="item.reply && item.reply.length" :class="$style.reply_floor" :comments="item.reply")
+
+
+
+
+
diff --git a/src/renderer/components/material/MusicComment.vue b/src/renderer/components/material/MusicComment.vue
new file mode 100644
index 00000000..7b5c198e
--- /dev/null
+++ b/src/renderer/components/material/MusicComment.vue
@@ -0,0 +1,270 @@
+
+div(:class="$style.comment")
+ div(:class="$style.commentHeader")
+ h3 {{$t('core.player.comment_title', { name: title })}}
+ div(:class="$style.commentHeaderBtns")
+ div(:class="$style.commentHeaderBtn" @click="handleShowComment" :tips="$t('core.player.comment_refresh')")
+ svg(version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' style='transform: rotate(45deg);' viewBox='0 0 24 24' space='preserve')
+ use(xlink:href='#icon-refresh')
+ div(:class="$style.commentHeaderBtn" @click="$emit('input', false)")
+ svg(version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' viewBox='0 0 24 24' space='preserve')
+ use(xlink:href='#icon-close')
+
+ div.scroll(:class="$style.commentMain" ref="dom_comment")
+ div(v-if="page == 1")
+ h2(:class="$style.commentType") {{$t('core.player.comment_hot_title')}}
+ p(:class="$style.commentLabel" style="cursor: pointer;" v-if="isHotLoadError" @click="handleGetHotComment(currentMusicInfo)") {{$t('core.player.comment_hot_load_error')}}
+ p(:class="$style.commentLabel" v-else-if="isHotLoading && !hotComments.length") {{$t('core.player.comment_hot_loading')}}
+ material-comment-floor(v-if="!isHotLoadError && hotComments.length" :class="[$style.commentFloor, isHotLoading ? $style.loading : null]" :comments="hotComments")
+ p(:class="$style.commentLabel" v-else-if="!isHotLoadError && !isHotLoading") {{$t('core.player.comment_no_content')}}
+ div
+ h2(:class="$style.commentType") {{$t('core.player.comment_new_title')}} ({{total}})
+ p(:class="$style.commentLabel" style="cursor: pointer;" v-if="isNewLoadError" @click="handleGetNewComment(currentMusicInfo, nextPage, limit)") {{$t('core.player.comment_new_load_error')}}
+ p(:class="$style.commentLabel" v-else-if="isNewLoading && !newComments.length") {{$t('core.player.comment_new_loading')}}
+ material-comment-floor(v-if="!isNewLoadError && newComments.length" :class="[$style.commentFloor, isNewLoading ? $style.loading : null]" :comments="newComments")
+ p(:class="$style.commentLabel" v-else-if="!isNewLoadError && !isNewLoading") {{$t('core.player.comment_no_content')}}
+ div(:class="$style.pagination")
+ material-pagination(:count="total" :btnLength="5" :limit="limit" :page="page" @btn-click="handleToggleCommentPage")
+
+
+
+
+
diff --git a/src/renderer/lang/en-us/base.json b/src/renderer/lang/en-us/base.json
new file mode 100644
index 00000000..09199968
--- /dev/null
+++ b/src/renderer/lang/en-us/base.json
@@ -0,0 +1,5 @@
+{
+ "date_format_second": "{num} seconds ago",
+ "date_format_minute": "{num} minutes ago",
+ "date_format_hour": "{num} hours ago"
+}
diff --git a/src/renderer/lang/en-us/core/player.json b/src/renderer/lang/en-us/core/player.json
index 64cc68c1..2de3604c 100644
--- a/src/renderer/lang/en-us/core/player.json
+++ b/src/renderer/lang/en-us/core/player.json
@@ -27,5 +27,16 @@
"play_toggle_mode_random": "List Random",
"play_toggle_mode_list": "Play in order",
"play_toggle_mode_single_loop": "Single Loop",
- "play_toggle_mode_off": "Disable"
+ "play_toggle_mode_off": "Disable",
+
+ "comment_show": "Show song comments",
+ "comment_hot_loading": "Hot comments are loading",
+ "comment_new_loading": "Latest comments are loading",
+ "comment_hot_load_error": "Hot comments failed to load, click to try to reload",
+ "comment_new_load_error": "The latest comment failed to load, click to try to reload",
+ "comment_refresh": "Refresh comments",
+ "comment_no_content": "No comments yet",
+ "comment_hot_title": "Hot Comment",
+ "comment_new_title": "Latest comment",
+ "comment_title": "{name} comment"
}
diff --git a/src/renderer/lang/zh-cn/base.json b/src/renderer/lang/zh-cn/base.json
new file mode 100644
index 00000000..6a12f4bf
--- /dev/null
+++ b/src/renderer/lang/zh-cn/base.json
@@ -0,0 +1,5 @@
+{
+ "date_format_second": "{num}秒前",
+ "date_format_minute": "{num}分钟前",
+ "date_format_hour": "{num}小时前"
+}
diff --git a/src/renderer/lang/zh-cn/core/player.json b/src/renderer/lang/zh-cn/core/player.json
index 31be9f68..bcdf2b7e 100644
--- a/src/renderer/lang/zh-cn/core/player.json
+++ b/src/renderer/lang/zh-cn/core/player.json
@@ -27,5 +27,16 @@
"play_toggle_mode_random": "列表随机",
"play_toggle_mode_list": "顺序播放",
"play_toggle_mode_single_loop": "单曲循环",
- "play_toggle_mode_off": "禁用"
+ "play_toggle_mode_off": "禁用",
+
+ "comment_show": "显示歌曲评论",
+ "comment_hot_loading": "热门评论加载中",
+ "comment_new_loading": "最新评论加载中",
+ "comment_hot_load_error": "热门评论加载失败,点击尝试重新加载",
+ "comment_new_load_error": "最新评论加载失败,点击尝试重新加载",
+ "comment_refresh": "刷新评论",
+ "comment_no_content": "暂无评论",
+ "comment_hot_title": "热门评论",
+ "comment_new_title": "最新评论",
+ "comment_title": "{name} 的评论"
}
diff --git a/src/renderer/lang/zh-tw/base.json b/src/renderer/lang/zh-tw/base.json
new file mode 100644
index 00000000..8c323e89
--- /dev/null
+++ b/src/renderer/lang/zh-tw/base.json
@@ -0,0 +1,5 @@
+{
+ "date_format_second": "{num}秒前",
+ "date_format_minute": "{num}分鐘前",
+ "date_format_hour": "{num}小時前"
+}
diff --git a/src/renderer/lang/zh-tw/core/player.json b/src/renderer/lang/zh-tw/core/player.json
index c727ccb0..05eaa62c 100644
--- a/src/renderer/lang/zh-tw/core/player.json
+++ b/src/renderer/lang/zh-tw/core/player.json
@@ -27,5 +27,16 @@
"play_toggle_mode_random": "列表隨機",
"play_toggle_mode_list": "順序播放",
"play_toggle_mode_single_loop": "單曲循環",
- "play_toggle_mode_off": "禁用"
+ "play_toggle_mode_off": "禁用",
+
+ "comment_show": "顯示歌曲評論",
+ "comment_hot_loading": "熱門評論加載中",
+ "comment_new_loading": "最新評論加載中",
+ "comment_hot_load_error": "熱門評論加載失敗,點擊嘗試重新加載",
+ "comment_new_load_error": "最新評論加載失敗,點擊嘗試重新加載",
+ "comment_refresh": "刷新評論",
+ "comment_no_content": "暫無評論",
+ "comment_hot_title": "熱門評論",
+ "comment_new_title": "最新評論",
+ "comment_title": "{name} 的評論"
}
diff --git a/src/renderer/utils/index.js b/src/renderer/utils/index.js
index 3b30ed43..2c73e0fd 100644
--- a/src/renderer/utils/index.js
+++ b/src/renderer/utils/index.js
@@ -20,6 +20,39 @@ export const sizeFormate = size => {
return `${(size / Math.pow(1024, Math.floor(number))).toFixed(2)} ${units[number]}`
}
+/**
+ * 日期格式化
+ * @param {*} date 时间
+ * @param {String} format 时间格式,默认YYYY-MM-DD hh:mm:ss
+ */
+export const dateFormat = (date = new Date(), format = 'YYYY-MM-DD hh:mm:ss') => {
+ if (typeof date != 'object') date = new Date(date)
+ const munFix = (n) => n < 10 ? ('0' + n) : n
+ return format
+ .replace('YYYY', date.getFullYear())
+ .replace('MM', munFix(date.getMonth() + 1))
+ .replace('DD', munFix(date.getDate()))
+ .replace('hh', munFix(date.getHours()))
+ .replace('mm', munFix(date.getMinutes()))
+ .replace('ss', munFix(date.getSeconds()))
+}
+
+/**
+ * 时间格式化
+ */
+export const dateFormat2 = time => {
+ let differ = parseInt((Date.now() - time) / 1000)
+ if (differ < 60) {
+ return window.i18n.t('base.date_format_second', { num: differ })
+ } else if (differ < 3600) {
+ return window.i18n.t('base.date_format_minute', { num: parseInt(differ / 60) })
+ } else if (differ < 86400) {
+ return window.i18n.t('base.date_format_hour', { num: parseInt(differ / 3600) })
+ } else {
+ return dateFormat(time)
+ }
+}
+
export const formatPlayTime = time => {
let m = parseInt(time / 60)
let s = parseInt(time % 60)
diff --git a/src/renderer/utils/music/kg/comment.js b/src/renderer/utils/music/kg/comment.js
new file mode 100644
index 00000000..71515fc1
--- /dev/null
+++ b/src/renderer/utils/music/kg/comment.js
@@ -0,0 +1,75 @@
+import { httpFetch } from '../../request'
+import { dateFormat2 } from '../../'
+
+export default {
+ _requestObj: null,
+ _requestObj2: null,
+ async getComment({ hash }, page = 1, limit = 20) {
+ if (this._requestObj) this._requestObj.cancelHttp()
+
+ const _requestObj = httpFetch(`http://comment.service.kugou.com/index.php?r=commentsv2/getCommentWithLike&code=fc4be23b4e972707f36b8a828a93ba8a&extdata=${hash}&p=${page}&pagesize=${limit}&ver=1.01&clientver=8373&appid=1001&kugouid=687373022`, {
+ headers: {
+ 'User-Agent': 'Android712-AndroidPhone-8983-18-0-COMMENT-wifi',
+ },
+ })
+ const { body, statusCode } = await _requestObj.promise
+ // console.log(body)
+ if (statusCode != 200 || body.err_code !== 0) throw new Error('获取评论失败')
+ return { source: 'kg', comments: this.filterComment(body.list || []), total: body.count, page, limit, maxPage: Math.ceil(body.count / limit) || 1 }
+ },
+ async getHotComment({ hash, songmid }, page = 1, limit = 100) {
+ // console.log(songmid)
+ if (this._requestObj2) this._requestObj2.cancelHttp()
+
+ const _requestObj2 = httpFetch(`http://comment.service.kugou.com/index.php?r=commentsv2/getCommentWithLike&code=fc4be23b4e972707f36b8a828a93ba8a&extdata=${hash}&p=${page}&pagesize=${limit}&ver=1.01&clientver=8373&appid=1001&kugouid=687373022`, {
+ headers: {
+ 'User-Agent': 'Android712-AndroidPhone-8983-18-0-COMMENT-wifi',
+ },
+ })
+ const { body, statusCode } = await _requestObj2.promise
+ // console.log(body)
+ if (statusCode != 200 || body.err_code !== 0) throw new Error('获取热门评论失败')
+ return { source: 'kg', comments: this.filterComment(body.weightList || []) }
+ },
+ async getReplyComment({ songmid }, replyId, page = 1, limit = 100) {
+ if (this._requestObj2) this._requestObj2.cancelHttp()
+
+ const _requestObj2 = httpFetch(`http://comment.service.kugou.com/index.php?r=commentsv2/getReplyWithLike&code=fc4be23b4e972707f36b8a828a93ba8a&p=${page}&pagesize=${limit}&ver=1.01&clientver=8373&kugouid=687373022&appid=1001&childrenid=${songmid}&tid=${replyId}`, {
+ headers: {
+ 'User-Agent': 'Android712-AndroidPhone-8983-18-0-COMMENT-wifi',
+ },
+ })
+ const { body, statusCode } = await _requestObj2.promise
+ // console.log(body)
+ if (statusCode != 200 || body.err_code !== 0) throw new Error('获取回复评论失败')
+ return { source: 'kg', comments: this.filterComment(body.list || []) }
+ },
+ filterComment(rawList) {
+ return rawList.map(item => {
+ let data = {
+ id: item.id,
+ text: item.content.split('\n'),
+ time: item.addtime,
+ timeStr: dateFormat2(new Date(item.addtime).getTime()),
+ userName: item.user_name,
+ avatar: item.user_pic,
+ userId: item.user_id,
+ likedCount: item.like.likenum,
+ replyNum: item.reply_num,
+ reply: [],
+ }
+
+ return item.pcontent ? {
+ id: item.id,
+ text: item.pcontent.split('\n'),
+ time: null,
+ userName: item.puser,
+ avatar: null,
+ userId: item.puser_id,
+ likedCount: null,
+ replyNum: null,
+ reply: [data],
+ } : data
+ })
+ },
+}
diff --git a/src/renderer/utils/music/kg/index.js b/src/renderer/utils/music/kg/index.js
index 524c5fbd..c0ccfbb2 100644
--- a/src/renderer/utils/music/kg/index.js
+++ b/src/renderer/utils/music/kg/index.js
@@ -5,12 +5,14 @@ import musicSearch from './musicSearch'
import pic from './pic'
import lyric from './lyric'
import hotSearch from './hotSearch'
+import comment from './comment'
const kg = {
leaderboard,
songList,
musicSearch,
hotSearch,
+ comment,
getMusicUrl(songInfo, type) {
return apis('kg').getMusicUrl(songInfo, type)
},
diff --git a/src/renderer/utils/music/kw/comment.js b/src/renderer/utils/music/kw/comment.js
new file mode 100644
index 00000000..99f160b4
--- /dev/null
+++ b/src/renderer/utils/music/kw/comment.js
@@ -0,0 +1,61 @@
+import { httpFetch } from '../../request'
+import { dateFormat2 } from '../../'
+
+export default {
+ _requestObj: null,
+ _requestObj2: null,
+ async getComment({ songmid }, page = 1, limit = 20) {
+ if (this._requestObj) this._requestObj.cancelHttp()
+
+ const _requestObj = httpFetch(`http://comment.kuwo.cn/com.s?type=get_comment&uid=0&digest=15&sid=${songmid}&page=${page}&rows=${limit}&f=web&prod=MUSIC_8.7.7.0_BCS37&devid=28556413`, {
+ headers: {
+ 'User-Agent': 'Dalvik/2.1.0 (Linux; U; Android 9;)',
+ },
+ })
+ const { body, statusCode } = await _requestObj.promise
+ if (statusCode != 200 || body.result !== 'ok') throw new Error('获取评论失败')
+ // console.log(body)
+ return { source: 'kw', comments: this.filterComment(body.rows), total: body.total, page, limit, maxPage: Math.ceil(body.total / limit) || 1 }
+ },
+ async getHotComment({ songmid }, page = 1, limit = 100) {
+ if (this._requestObj2) this._requestObj2.cancelHttp()
+
+ const _requestObj2 = httpFetch(`http://comment.kuwo.cn/com.s?type=get_rec_comment&uid=0&digest=15&sid=${songmid}&page=${page}&rows=${limit}&f=web&prod=MUSIC_8.7.7.0_BCS37&devid=28556413`, {
+ headers: {
+ 'User-Agent': 'Dalvik/2.1.0 (Linux; U; Android 9;)',
+ },
+ })
+ const { body, statusCode } = await _requestObj2.promise
+ if (statusCode != 200 || body.result !== 'ok') throw new Error('获取热门评论失败')
+ // console.log(body)
+ return { source: 'kw', comments: this.filterComment(body.rows) }
+ },
+ filterComment(rawList) {
+ if (!rawList) return []
+ return rawList.map(item => {
+ let data = {
+ id: item.id,
+ text: item.msg.split('\n'),
+ time: item.time,
+ timeStr: dateFormat2(new Date(item.time).getTime()),
+ userName: decodeURIComponent(item.u_name),
+ avatar: item.u_pic,
+ userId: item.u_id,
+ likedCount: item.like_num,
+ reply: [],
+ }
+ return item.reply ? {
+ id: item.id,
+ rootId: item.reply.id,
+ text: item.reply.msg.split('\n'),
+ time: item.reply.time,
+ timeStr: dateFormat2(new Date(item.reply.time).getTime()),
+ userName: decodeURIComponent(item.reply.u_name),
+ avatar: item.reply.u_pic,
+ userId: item.reply.u_id,
+ likedCount: item.reply.like_num,
+ reply: [data],
+ } : data
+ })
+ },
+}
diff --git a/src/renderer/utils/music/kw/index.js b/src/renderer/utils/music/kw/index.js
index 19c0c143..1039305e 100644
--- a/src/renderer/utils/music/kw/index.js
+++ b/src/renderer/utils/music/kw/index.js
@@ -8,6 +8,7 @@ import pic from './pic'
import { apis } from '../api-source'
import songList from './songList'
import hotSearch from './hotSearch'
+import comment from './comment'
const kw = {
_musicInfoRequestObj: null,
@@ -36,6 +37,7 @@ const kw = {
leaderboard,
songList,
hotSearch,
+ comment,
getLyric(songInfo, isGetLyricx) {
// let singer = songInfo.singer.indexOf('、') > -1 ? songInfo.singer.split('、')[0] : songInfo.singer
return lyric.getLyric(songInfo.songmid, isGetLyricx)
diff --git a/src/renderer/utils/music/mg/album.js b/src/renderer/utils/music/mg/album.js
new file mode 100644
index 00000000..625fc3ac
--- /dev/null
+++ b/src/renderer/utils/music/mg/album.js
@@ -0,0 +1,30 @@
+import { httpFetch } from '../../request'
+
+export default {
+ getAlbum(songInfo, tryNum = 0) {
+ let requestObj = httpFetch(`http://app.c.nf.migu.cn/MIGUM2.0/v1.0/content/queryAlbumSong?albumId=${songInfo.albumId}&pageNo=1`, {
+ headers: {
+ sign: '46DB65104950B98FE451AD41047CC6C4',
+ timestamp: 1603451430776,
+ appId: 'yyapp2',
+ mode: 'android',
+ ua: 'Android_migu',
+ version: '6.9.4',
+ osVersion: 'android 7.0',
+ 'User-Agent': 'okhttp/3.9.1',
+ channel: '0146832',
+ },
+ })
+ requestObj.promise = requestObj.promise.then(({ body }) => {
+ if (body.code !== '000000') {
+ if (tryNum > 5) return Promise.reject('获取专辑失败')
+ let tryRequestObj = this.getAlbum(songInfo, ++tryNum)
+ requestObj.cancelHttp = tryRequestObj.cancelHttp.bind(tryRequestObj)
+ return tryRequestObj.promise
+ }
+ console.log(body)
+ return body.songList
+ })
+ return requestObj
+ },
+}
diff --git a/src/renderer/utils/music/mg/comment.js b/src/renderer/utils/music/mg/comment.js
new file mode 100644
index 00000000..2e9f1621
--- /dev/null
+++ b/src/renderer/utils/music/mg/comment.js
@@ -0,0 +1,95 @@
+import { httpFetch } from '../../request'
+import album from './album'
+import { dateFormat2 } from '../../'
+
+export default {
+ _requestObj: null,
+ _requestObj2: null,
+ _requestObj3: null,
+ async getSongId(musicInfo) {
+ if (this._requestObj3) this._requestObj3.cancelHttp()
+ this.requestObj3 = album.getAlbum(musicInfo)
+ const list = await this.requestObj3.promise
+ const copyrightId = musicInfo.copyrightId
+ let info = list.find(s => s.copyrightId == copyrightId)
+ const songmid = musicInfo.songmid
+ if (!info) info = list.find(s => s.songId == songmid)
+ return info ? info.songId : null
+ },
+ async getComment(musicInfo, page = 1, limit = 20) {
+ if (this._requestObj) this._requestObj.cancelHttp()
+ if (!musicInfo.songId) {
+ let id = await this.getSongId(musicInfo)
+ if (!id) throw new Error('获取评论失败')
+ musicInfo.songId = id
+ }
+
+ const _requestObj = httpFetch(`https://music.migu.cn/v3/api/comment/listComments?targetId=${musicInfo.songId}&pageSize=${limit}&pageNo=${page}`, {
+ headers: {
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4195.1 Safari/537.36',
+ Referer: 'https://music.migu.cn',
+ },
+ })
+ const { body, statusCode } = await _requestObj.promise
+ console.log(body)
+ if (statusCode != 200 || body.returnCode !== '000000') throw new Error('获取评论失败')
+ return { source: 'mg', comments: this.filterComment(body.data.items), total: body.data.itemTotal, page, limit, maxPage: Math.ceil(body.data.itemTotal / limit) || 1 }
+ },
+ async getHotComment(musicInfo, page = 1, limit = 100) {
+ if (this._requestObj2) this._requestObj2.cancelHttp()
+
+ if (!musicInfo.songId) {
+ let id = await this.getSongId(musicInfo)
+ if (!id) throw new Error('获取评论失败')
+ musicInfo.songId = id
+ }
+
+ const _requestObj2 = httpFetch(`https://music.migu.cn/v3/api/comment/listTopComments?targetId=${musicInfo.songId}&pageSize=${limit}&pageNo=${page}`, {
+ headers: {
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4195.1 Safari/537.36',
+ Referer: 'https://music.migu.cn',
+ },
+ })
+ const { body, statusCode } = await _requestObj2.promise
+ // console.log(body)
+ if (statusCode != 200 || body.returnCode !== '000000') throw new Error('获取热门评论失败')
+ return { source: 'mg', comments: this.filterComment(body.data.items) }
+ },
+ async getReplyComment(musicInfo, replyId, page = 1, limit = 100) {
+ if (this._requestObj2) this._requestObj2.cancelHttp()
+
+ const _requestObj2 = httpFetch(`https://music.migu.cn/v3/api/comment/listCommentsById?commentId=${replyId}&pageSize=${limit}&pageNo=${page}`, {
+ headers: {
+ 'User-Agent': 'Android712-AndroidPhone-8983-18-0-COMMENT-wifi',
+ },
+ })
+ const { body, statusCode } = await _requestObj2.promise
+ // console.log(body)
+ if (statusCode != 200 || body.returnCode !== '000000') throw new Error('获取回复评论失败')
+ return { source: 'mg', comments: this.filterComment(body.data.items) }
+ },
+ filterComment(rawList) {
+ return rawList.map(item => ({
+ id: item.commentId,
+ text: item.body.split('\n'),
+ time: item.createTime,
+ timeStr: dateFormat2(new Date(item.createTime).getTime()),
+ userName: item.author.name,
+ avatar: item.author.avatar,
+ userId: item.author.id,
+ likedCount: item.praiseCount,
+ replyNum: item.replyTotal,
+ reply: item.replyCommentList.map(c => ({
+ id: c.commentId,
+ text: c.body.split('\n'),
+ time: c.createTime,
+ timeStr: dateFormat2(new Date(c.createTime).getTime()),
+ userName: c.author.name,
+ avatar: c.author.avatar,
+ userId: c.author.id,
+ likedCount: c.praiseCount,
+ replyNum: c.replyTotal,
+ })),
+ }))
+ },
+}
diff --git a/src/renderer/utils/music/mg/index.js b/src/renderer/utils/music/mg/index.js
index 3ee240a8..72ccde6a 100644
--- a/src/renderer/utils/music/mg/index.js
+++ b/src/renderer/utils/music/mg/index.js
@@ -5,12 +5,14 @@ import musicSearch from './musicSearch'
import pic from './pic'
import lyric from './lyric'
import hotSearch from './hotSearch'
+import comment from './comment'
const mg = {
songList,
musicSearch,
leaderboard,
hotSearch,
+ comment,
getMusicUrl(songInfo, type) {
return apis('mg').getMusicUrl(songInfo, type)
},
diff --git a/src/renderer/utils/music/mg/leaderboard.js b/src/renderer/utils/music/mg/leaderboard.js
index 32602ffb..37dba46c 100644
--- a/src/renderer/utils/music/mg/leaderboard.js
+++ b/src/renderer/utils/music/mg/leaderboard.js
@@ -137,6 +137,7 @@ export default {
albumName: item.album,
albumId: item.albumId,
songmid: item.copyrightId,
+ songId: item.songId,
copyrightId: item.copyrightId,
source: 'mg',
interval: null,
@@ -195,7 +196,7 @@ export default {
getList(bangid, page, retryNum = 0) {
if (++retryNum > 3) return Promise.reject(new Error('try max num'))
return this.getData(this.getUrl(bangid, page)).then(({ statusCode, body }) => {
- // console.log(body)
+ console.log(body)
if (statusCode !== 200 || body.code !== this.successCode) return this.getList(bangid, page, retryNum)
const list = this.filterData(body.data.columnInfo.dataList)
return {
diff --git a/src/renderer/utils/music/mg/musicSearch.js b/src/renderer/utils/music/mg/musicSearch.js
index 9433596d..9e370395 100644
--- a/src/renderer/utils/music/mg/musicSearch.js
+++ b/src/renderer/utils/music/mg/musicSearch.js
@@ -36,7 +36,7 @@ export default {
return arr.join('、')
},
handleResult(rawData) {
- // console.log(rawData)
+ console.log(rawData)
let ids = new Set()
const list = []
rawData.forEach(item => {
@@ -82,6 +82,7 @@ export default {
albumName: albumNInfo.name,
albumId: albumNInfo.id,
songmid: item.id,
+ songId: item.songId,
copyrightId: item.copyrightId,
source: 'mg',
interval: null,
diff --git a/src/renderer/utils/music/mg/songList.js b/src/renderer/utils/music/mg/songList.js
index 0fa8ec33..2def8cce 100644
--- a/src/renderer/utils/music/mg/songList.js
+++ b/src/renderer/utils/music/mg/songList.js
@@ -24,25 +24,25 @@ export default {
list: /.+?<\/li>/g,
listInfo: /.+data-original="(.+?)".*data-id="(\d+)".*
(.+?)<\/a>.+<\/i>(.+?)<\/div>/,
- // http://music.migu.cn/v3/music/playlist/161044573?page=1
+ // https://music.migu.cn/v3/music/playlist/161044573?page=1
listDetailLink: /^.+\/playlist\/(\d+)(?:\?.*|&.*$|#.*$|$)/,
},
tagsUrl: 'https://app.c.nf.migu.cn/MIGUM2.0/v1.0/content/indexTagPage.do?needAll=0',
getSongListUrl(sortId, tagId, page) {
// if (tagId == null) {
// return sortId == 'recommend'
- // ? `http://music.migu.cn/v3/music/playlist?page=${page}&from=migu`
- // : `http://music.migu.cn/v3/music/playlist?sort=${sortId}&page=${page}&from=migu`
+ // ? `https://music.migu.cn/v3/music/playlist?page=${page}&from=migu`
+ // : `https://music.migu.cn/v3/music/playlist?sort=${sortId}&page=${page}&from=migu`
// }
- // return `http://music.migu.cn/v3/music/playlist?tagId=${tagId}&page=${page}&from=migu`
+ // return `https://music.migu.cn/v3/music/playlist?tagId=${tagId}&page=${page}&from=migu`
if (tagId == null) {
- // return `http://app.c.nf.migu.cn/MIGUM2.0/v2.0/content/getMusicData.do?count=${this.limit_list}&start=${page}&templateVersion=5&type=1`
+ // return `https://app.c.nf.migu.cn/MIGUM2.0/v2.0/content/getMusicData.do?count=${this.limit_list}&start=${page}&templateVersion=5&type=1`
// return `https://c.musicapp.migu.cn/MIGUM2.0/v2.0/content/getMusicData.do?count=${this.limit_list}&start=${page}&templateVersion=5&type=${sortId}`
- // http://app.c.nf.migu.cn/MIGUM2.0/v2.0/content/getMusicData.do?count=50&start=2&templateVersion=5&type=1
- return `http://m.music.migu.cn/migu/remoting/playlist_bycolumnid_tag?playListType=2&type=1&columnId=${sortId}&startIndex=${(page - 1) * 10}`
+ // https://app.c.nf.migu.cn/MIGUM2.0/v2.0/content/getMusicData.do?count=50&start=2&templateVersion=5&type=1
+ return `https://m.music.migu.cn/migu/remoting/playlist_bycolumnid_tag?playListType=2&type=1&columnId=${sortId}&startIndex=${(page - 1) * 10}`
}
// return `https://app.c.nf.migu.cn/MIGUM2.0/v2.0/content/getMusicData.do?area=2&count=${this.limit_list}&start=${page}&tags=${tagId}&templateVersion=5&type=3`
- return `http://m.music.migu.cn/migu/remoting/playlist_bycolumnid_tag?playListType=2&type=1&tagId=${tagId}&startIndex=${(page - 1) * 10}`
+ return `https://m.music.migu.cn/migu/remoting/playlist_bycolumnid_tag?playListType=2&type=1&tagId=${tagId}&startIndex=${(page - 1) * 10}`
},
getSongListDetailUrl(id, page) {
return `https://app.c.nf.migu.cn/MIGUM2.0/v1.0/user/queryMusicListSongs.do?musicListId=${id}&pageNo=${page}&pageSize=${this.limit_song}`
@@ -74,7 +74,7 @@ export default {
return this._requestObj_listDetail.promise.then(({ body }) => {
if (body.code !== this.successCode) return this.getListDetail(id, page, ++tryNum)
// console.log(JSON.stringify(body))
- console.log(body)
+ // console.log(body)
return {
list: this.filterListDetail(body.list),
page,
@@ -135,6 +135,7 @@ export default {
albumId: item.albumId,
songmid: item.copyrightId,
copyrightId: item.copyrightId,
+ songId: item.songId,
source: 'mg',
interval: null,
img: item.albumImgs && item.albumImgs.length ? item.albumImgs[0].img : null,
@@ -185,7 +186,6 @@ export default {
// })
return this._requestObj_list.promise.then(({ body }) => {
if (body.retCode !== '100000' || body.retMsg.code !== this.successCode) return this.getList(sortId, tagId, page, ++tryNum)
- // console.log(body)
return {
list: this.filterList(body.retMsg.playlist),
total: parseInt(body.retMsg.countSize),
diff --git a/src/renderer/utils/music/tx/comment.js b/src/renderer/utils/music/tx/comment.js
new file mode 100644
index 00000000..1367df36
--- /dev/null
+++ b/src/renderer/utils/music/tx/comment.js
@@ -0,0 +1,187 @@
+import { httpFetch } from '../../request'
+import { dateFormat2 } from '../../'
+
+const emojis = {
+ e400846: '😘',
+ e400874: '😴',
+ e400825: '😃',
+ e400847: '😙',
+ e400835: '😍',
+ e400873: '😳',
+ e400836: '😎',
+ e400867: '😭',
+ e400832: '😊',
+ e400837: '😏',
+ e400875: '😫',
+ e400831: '😉',
+ e400855: '😡',
+ e400823: '😄',
+ e400862: '😨',
+ e400844: '😖',
+ e400841: '😓',
+ e400830: '😈',
+ e400828: '😆',
+ e400833: '😋',
+ e400822: '😀',
+ e400843: '😕',
+ e400829: '😇',
+ e400824: '😂',
+ e400834: '😌',
+ e400877: '😷',
+ e400132: '🍉',
+ e400181: '🍺',
+ e401067: '☕️',
+ e400186: '🥧',
+ e400343: '🐷',
+ e400116: '🌹',
+ e400126: '🍃',
+ e400613: '💋',
+ e401236: '❤️',
+ e400622: '💔',
+ e400637: '💣',
+ e400643: '💩',
+ e400773: '🔪',
+ e400102: '🌛',
+ e401328: '🌞',
+ e400420: '👏',
+ e400914: '🙌',
+ e400408: '👍',
+ e400414: '👎',
+ e401121: '✋',
+ e400396: '👋',
+ e400384: '👉',
+ e401115: '✊',
+ e400402: '👌',
+ e400905: '🙈',
+ e400906: '🙉',
+ e400907: '🙊',
+ e400562: '👻',
+ e400932: '🙏',
+ e400644: '💪',
+ e400611: '💉',
+ e400185: '🎁',
+ e400655: '💰',
+ e400325: '🐥',
+ e400612: '💊',
+ e400198: '🎉',
+ e401685: '⚡️',
+ e400631: '💝',
+ e400768: '🔥',
+ e400432: '👑',
+}
+
+export default {
+ _requestObj: null,
+ _requestObj2: null,
+ async getComment({ songId }, page = 1, limit = 20) {
+ if (this._requestObj) this._requestObj.cancelHttp()
+
+ const _requestObj = httpFetch('http://c.y.qq.com/base/fcgi-bin/fcg_global_comment_h5.fcg', {
+ headers: {
+ 'User-Agent': 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)',
+ },
+ form: {
+ uin: '0',
+ format: 'json',
+ cid: '205360772',
+ reqtype: '2',
+ biztype: '1',
+ topid: songId,
+ cmd: '8',
+ needmusiccrit: '1',
+ pagenum: page - 1,
+ pagesize: limit,
+ },
+ })
+ const { body, statusCode } = await _requestObj.promise
+ if (statusCode != 200 || body.code !== 0) throw new Error('获取评论失败')
+ // console.log(body, statusCode)
+ const comment = body.comment
+ return {
+ source: 'tx',
+ comments: this.filterComment(comment.commentlist),
+ total: comment.commenttotal,
+ page,
+ limit,
+ maxPage: Math.ceil(comment.commenttotal / limit) || 1,
+ }
+ },
+ async getHotComment({ songId }, page = 1, limit = 100) {
+ if (this._requestObj2) this._requestObj2.cancelHttp()
+
+ const _requestObj2 = httpFetch('http://c.y.qq.com/base/fcgi-bin/fcg_global_comment_h5.fcg', {
+ headers: {
+ 'User-Agent': 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)',
+ },
+ form: {
+ uin: '0',
+ format: 'json',
+ cid: '205360772',
+ reqtype: '2',
+ biztype: '1',
+ topid: songId,
+ cmd: '9',
+ needmusiccrit: '1',
+ pagenum: page - 1,
+ pagesize: limit,
+ },
+ })
+ const { body, statusCode } = await _requestObj2.promise
+ if (statusCode != 200 || body.code !== 0) throw new Error('获取热门评论失败')
+ // console.log(body, statusCode)
+ const comment = body.comment
+ return {
+ source: 'tx',
+ comments: this.filterComment(comment.commentlist),
+ total: comment.commenttotal,
+ }
+ },
+ replaceEmoji(msg) {
+ let rxp = /^\[em\](e\d+)\[\/em\]$/
+ let result = msg.match(/\[em\]e\d+\[\/em\]/g)
+ if (!result) return msg
+ result = Array.from(new Set(result))
+ for (let item of result) {
+ let code = item.replace(rxp, '$1')
+ msg = msg.replace(new RegExp(item.replace('[em]', '\\[em\\]').replace('[/em]', '\\[\\/em\\]'), 'g'), emojis[code] || '')
+ }
+ return msg
+ },
+ filterComment(rawList) {
+ return rawList.map(item => {
+ let time = item.rootcommentid ? parseInt(item.rootcommentid.substring(item.rootcommentid.lastIndexOf('_') + 1) + '000') : null
+ if (item.middlecommentcontent) {
+ let firstItem = item.middlecommentcontent[0]
+ firstItem.avatarurl = item.avatarurl
+ firstItem.praisenum = item.praisenum
+ item.avatarurl = null
+ item.praisenum = null
+ item.middlecommentcontent.reverse()
+ }
+ return {
+ id: item.subcommentid,
+ rootId: item.rootcommentid,
+ text: item.rootcommentcontent ? this.replaceEmoji(item.rootcommentcontent).replace(/\\n/g, '\n').split('\n') : [],
+ time,
+ timeStr: time ? dateFormat2(time) : null,
+ userName: item.rootcommentnick ? item.rootcommentnick.substring(1) : '',
+ avatar: item.avatarurl,
+ userId: item.encrypt_rootcommentuin,
+ likedCount: item.praisenum,
+ reply: item.middlecommentcontent ? item.middlecommentcontent.map(c => {
+ let index = c.subcommentid.lastIndexOf('_')
+ return {
+ id: c.subcommentid,
+ text: this.replaceEmoji(c.subcommentcontent).replace(/\\n/g, '\n').split('\n'),
+ time: parseInt(c.subcommentid.substring(index + 1) + '000'),
+ timeStr: dateFormat2(parseInt(c.subcommentid.substring(index + 1) + '000')),
+ userName: c.replynick.substring(1),
+ avatar: c.avatarurl,
+ userId: c.encrypt_replyuin,
+ likedCount: c.praisenum,
+ }
+ }) : [],
+ }
+ })
+ },
+}
diff --git a/src/renderer/utils/music/tx/index.js b/src/renderer/utils/music/tx/index.js
index ffa94b54..6c1bd568 100644
--- a/src/renderer/utils/music/tx/index.js
+++ b/src/renderer/utils/music/tx/index.js
@@ -4,12 +4,14 @@ import songList from './songList'
import musicSearch from './musicSearch'
import { apis } from '../api-source'
import hotSearch from './hotSearch'
+import comment from './comment'
const tx = {
leaderboard,
songList,
musicSearch,
hotSearch,
+ comment,
getMusicUrl(songInfo, type) {
return apis('tx').getMusicUrl(songInfo, type)
diff --git a/src/renderer/utils/music/wy/comment.js b/src/renderer/utils/music/wy/comment.js
new file mode 100644
index 00000000..0847a44c
--- /dev/null
+++ b/src/renderer/utils/music/wy/comment.js
@@ -0,0 +1,138 @@
+import { httpFetch } from '../../request'
+import { weapi } from './utils/crypto'
+import { dateFormat2 } from '../../'
+
+let cursorTools = {
+ cache: {},
+ getCursor(id, page, limit) {
+ let cacheData = this.cache[id]
+ if (!cacheData) cacheData = this.cache[id] = {}
+ let orderType
+ let cursor
+ let offset
+ if (page == 1) {
+ cacheData.page = 1
+ cursor = cacheData.cursor = cacheData.prevCursor = Date.now()
+ orderType = 1
+ offset = 0
+ } else if (cacheData.page) {
+ cursor = cacheData.cursor
+ if (page > cacheData.page) {
+ orderType = 1
+ offset = (page - cacheData.page - 1) * limit
+ } else if (page < cacheData.page) {
+ orderType = 0
+ offset = (cacheData.page - page - 1) * limit
+ } else {
+ cursor = cacheData.cursor = cacheData.prevCursor
+ offset = cacheData.offset
+ orderType = cacheData.orderType
+ }
+ }
+ return {
+ orderType,
+ cursor,
+ offset,
+ }
+ },
+ setCursor(id, cursor, orderType, offset, page) {
+ let cacheData = this.cache[id]
+ if (!cacheData) cacheData = this.cache[id] = {}
+ cacheData.prevCursor = cacheData.cursor
+ cacheData.cursor = cursor
+ cacheData.orderType = orderType
+ cacheData.offset = offset
+ cacheData.page = page
+ },
+}
+
+export default {
+ _requestObj: null,
+ _requestObj2: null,
+ async getComment({ songmid }, page = 1, limit = 20) {
+ if (this._requestObj) this._requestObj.cancelHttp()
+
+ const id = 'R_SO_4_' + songmid
+
+ const cursorInfo = cursorTools.getCursor(songmid, page, limit)
+
+ const _requestObj = httpFetch('https://music.163.com/weapi/comment/resource/comments/get', {
+ 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',
+ origin: 'https://music.163.com',
+ Refere: 'http://music.163.com/',
+ },
+ form: weapi({
+ cursor: cursorInfo.cursor,
+ offset: cursorInfo.offset,
+ orderType: cursorInfo.orderType,
+ pageNo: page,
+ pageSize: limit,
+ rid: id,
+ threadId: id,
+ }),
+ })
+ const { body, statusCode } = await _requestObj.promise
+ // console.log(body)
+ if (statusCode != 200 || body.code !== 200) throw new Error('获取评论失败')
+ cursorTools.setCursor(songmid, body.data.cursor, cursorInfo.orderType, cursorInfo.offset, page)
+ return { source: 'wy', comments: this.filterComment(body.data.comments), total: body.data.totalCount, page, limit, maxPage: Math.ceil(body.data.totalCount / limit) || 1 }
+ },
+ async getHotComment({ songmid }, page = 1, limit = 100) {
+ if (this._requestObj2) this._requestObj2.cancelHttp()
+
+ const id = 'R_SO_4_' + songmid
+
+ const _requestObj2 = httpFetch('https://music.163.com/weapi/comment/resource/comments/get', {
+ 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',
+ origin: 'https://music.163.com',
+ Refere: 'http://music.163.com/',
+ },
+ form: weapi({
+ cursor: Date.now().toString(),
+ offset: 0,
+ orderType: 1,
+ pageNo: page,
+ pageSize: limit,
+ rid: id,
+ threadId: id,
+ }),
+ })
+ const { body, statusCode } = await _requestObj2.promise
+ if (statusCode != 200 || body.code !== 200) throw new Error('获取热门评论失败')
+ // console.log(body)
+ return { source: 'wy', comments: this.filterComment(body.data.hotComments) }
+ },
+ filterComment(rawList) {
+ return rawList.map(item => {
+ let data = {
+ id: item.commentId,
+ text: item.content ? item.content.split('\n') : '',
+ time: item.time ? item.time : '',
+ timeStr: item.time ? dateFormat2(item.time) : '',
+ userName: item.user.nickname,
+ avatar: item.user.avatarUrl,
+ userId: item.user.userId,
+ likedCount: item.likedCount,
+ reply: [],
+ }
+
+ let replyData = item.beReplied && item.beReplied[0]
+ return replyData ? {
+ id: item.commentId,
+ rootId: replyData.beRepliedCommentId,
+ text: replyData.content ? replyData.content.split('\n') : '',
+ time: item.time,
+ timeStr: null,
+ userName: replyData.user.nickname,
+ avatar: replyData.user.avatarUrl,
+ userId: replyData.user.userId,
+ likedCount: null,
+ reply: [data],
+ } : data
+ })
+ },
+}
diff --git a/src/renderer/utils/music/wy/index.js b/src/renderer/utils/music/wy/index.js
index a06284a4..69830372 100644
--- a/src/renderer/utils/music/wy/index.js
+++ b/src/renderer/utils/music/wy/index.js
@@ -5,12 +5,14 @@ import getMusicInfo from './musicInfo'
import musicSearch from './musicSearch'
import songList from './songList'
import hotSearch from './hotSearch'
+import comment from './comment'
const wy = {
leaderboard,
musicSearch,
songList,
hotSearch,
+ comment,
getMusicUrl(songInfo, type) {
return apis('wy').getMusicUrl(songInfo, type)
},
diff --git a/src/renderer/utils/music/wy/musicSearch.js b/src/renderer/utils/music/wy/musicSearch.js
index 6f99b12e..d7a40fd9 100644
--- a/src/renderer/utils/music/wy/musicSearch.js
+++ b/src/renderer/utils/music/wy/musicSearch.js
@@ -1,6 +1,7 @@
import { httpFetch } from '../../request'
import { weapi } from './utils/crypto'
-import { sizeFormate, formatPlayTime } from '../../index'
+// import { sizeFormate, formatPlayTime } from '../../index'
+import musicDetailApi from './musicDetail'
let searchRequest
export default {
@@ -10,8 +11,12 @@ export default {
allPage: 1,
musicSearch(str, page) {
if (searchRequest && searchRequest.cancelHttp) searchRequest.cancelHttp()
- searchRequest = httpFetch('http://music.163.com/weapi/cloudsearch/get/web?csrf_token=', {
+ searchRequest = httpFetch('https://music.163.com/weapi/search/get', {
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',
+ origin: 'https://music.163.com',
+ },
form: weapi({
s: str,
type: 1, // 1: 单曲, 10: 专辑, 100: 歌手, 1000: 歌单, 1002: 用户, 1004: MV, 1006: 歌词, 1009: 电台, 1014: 视频
@@ -19,7 +24,24 @@ export default {
offset: this.limit * (page - 1),
}),
})
- return searchRequest.promise.then(({ body }) => body)
+ return searchRequest.promise.then(({ body }) =>
+ body && body.code === 200
+ ? musicDetailApi.getList(body.result.songs.map(s => s.id)).then(({ list }) => {
+ this.total = body.result.songCount || 0
+ this.page = page
+ this.allPage = Math.ceil(this.total / this.limit)
+ return {
+ code: 200,
+ data: {
+ list,
+ allPage: this.allPage,
+ limit: this.limit,
+ total: this.total,
+ source: 'wy',
+ },
+ }
+ })
+ : body)
},
getSinger(singers) {
let arr = []
@@ -28,7 +50,7 @@ export default {
})
return arr.join('、')
},
- handleResult(rawList) {
+ /* handleResult(rawList) {
// console.log(rawList)
if (!rawList) return []
return rawList.map(item => {
@@ -78,27 +100,29 @@ export default {
typeUrl: {},
}
})
- },
+ }, */
search(str, page = 1, { limit } = {}, retryNum = 0) {
if (++retryNum > 3) return Promise.reject(new Error('try max num'))
if (limit != null) this.limit = limit
return this.musicSearch(str, page).then(result => {
+ // console.log(result)
if (!result || result.code !== 200) return this.search(str, page, { limit }, retryNum)
- let list = this.handleResult(result.result.songs || [])
+ // let list = this.handleResult(result.result.songs || [])
- if (list == null) return this.search(str, page, { limit }, retryNum)
+ // if (list == null) return this.search(str, page, { limit }, retryNum)
- this.total = result.result.songCount || 0
- this.page = page
- this.allPage = Math.ceil(this.total / this.limit)
+ // this.total = result.result.songCount || 0
+ // 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',
- })
+ // return Promise.resolve({
+ // list,
+ // allPage: this.allPage,
+ // limit: this.limit,
+ // total: this.total,
+ // source: 'wy',
+ // })
+ return result.data
})
},
}
diff --git a/src/renderer/utils/music/xm/comment.js b/src/renderer/utils/music/xm/comment.js
new file mode 100644
index 00000000..d8432cbe
--- /dev/null
+++ b/src/renderer/utils/music/xm/comment.js
@@ -0,0 +1,47 @@
+import { xmRequest } from './util'
+import { dateFormat2 } from '../../'
+
+export default {
+ _requestObj: null,
+ _requestObj2: null,
+ async getComment({ songmid }, page = 1, limit = 20) {
+ if (this._requestObj) this._requestObj.cancelHttp()
+
+ const _requestObj = xmRequest('/api/comment/getCommentList', { objectId: songmid, objectType: 'song', pagingVO: { page, pageSize: limit } })
+ const { body, statusCode } = await _requestObj.promise
+ // console.log(body)
+ if (statusCode != 200 || body.code !== 'SUCCESS') throw new Error('获取评论失败')
+ return { source: 'xm', comments: this.filterComment(body.result.data.commentList), total: body.result.data.pagingVO.count, page, limit, maxPage: Math.ceil(body.result.data.pagingVO.count / limit) || 1 }
+ },
+ async getHotComment({ songmid }, page = 1, limit = 100) {
+ if (this._requestObj2) this._requestObj2.cancelHttp()
+ if (!songmid) throw new Error('获取失败')
+ const _requestObj2 = xmRequest('/api/comment/getHotCommentList', { objectId: songmid, objectType: 'song', pagingVO: { page, pageSize: limit } })
+ const { body, statusCode } = await _requestObj2.promise
+ // console.log(body)
+ if (statusCode != 200 || body.code !== 'SUCCESS') throw new Error('获取热门评论失败')
+ return { source: 'xm', comments: this.filterComment(body.result.data.hotList) }
+ },
+ filterComment(rawList) {
+ return rawList.map(item => ({
+ id: item.commentId,
+ text: item.message.split('\n').filter(t => !!t),
+ time: item.gmtCreate,
+ timeStr: dateFormat2(item.gmtCreate),
+ userName: item.nickName,
+ avatar: item.avatar,
+ userId: item.userId,
+ likedCount: item.likes,
+ reply: item.replyData ? item.replyData.map(c => ({
+ id: c.commentId,
+ text: c.message.split('\n').filter(t => !!t),
+ time: c.gmtCreate,
+ timeStr: dateFormat2(c.gmtCreate),
+ userName: c.nickName,
+ avatar: c.avatar,
+ userId: c.userId,
+ likedCount: c.likes,
+ })) : [],
+ }))
+ },
+}
diff --git a/src/renderer/utils/music/xm/index.js b/src/renderer/utils/music/xm/index.js
index 06c07b2c..e586bf25 100644
--- a/src/renderer/utils/music/xm/index.js
+++ b/src/renderer/utils/music/xm/index.js
@@ -5,6 +5,8 @@ import musicSearch from './musicSearch'
// import pic from './pic'
import lyric from './lyric'
import hotSearch from './hotSearch'
+import comment from './comment'
+import musicInfo from './musicInfo'
import { closeVerifyModal } from './util'
const xm = {
@@ -13,6 +15,7 @@ const xm = {
leaderboard,
hotSearch,
closeVerifyModal,
+ comment,
getMusicUrl(songInfo, type) {
return apis('xm').getMusicUrl(songInfo, type)
},
@@ -24,7 +27,12 @@ const xm = {
// return pic.getPic(songInfo)
},
getMusicDetailPageUrl(songInfo) {
- return songInfo.songStringId ? `https://www.xiami.com/song/${songInfo.songStringId}` : null
+ if (songInfo.songStringId) return `https://www.xiami.com/song/${songInfo.songStringId}`
+
+ musicInfo.getMusicInfo(songInfo).then(({ data }) => {
+ songInfo.songStringId = data.songStringId
+ })
+ return `https://www.xiami.com/song/${songInfo.songmid}`
},
// init() {
// getToken()
diff --git a/src/renderer/utils/music/xm/musicInfo.js b/src/renderer/utils/music/xm/musicInfo.js
new file mode 100644
index 00000000..7ca9b1be
--- /dev/null
+++ b/src/renderer/utils/music/xm/musicInfo.js
@@ -0,0 +1,14 @@
+import { xmRequest } from './util'
+
+export default {
+ _requestObj: null,
+ async getMusicInfo({ songmid }, page = 1, limit = 20) {
+ if (this._requestObj) this._requestObj.cancelHttp()
+
+ const _requestObj = xmRequest('/api/song/initialize', { songId: songmid })
+ const { body, statusCode } = await _requestObj.promise
+ // console.log(body)
+ if (statusCode != 200 || body.code !== 'SUCCESS') throw new Error('获取歌曲信息失败')
+ return { source: 'xm', data: body.result.data.songDetail }
+ },
+}
diff --git a/src/renderer/views/Setting.vue b/src/renderer/views/Setting.vue
index 2b79d302..9d15b908 100644
--- a/src/renderer/views/Setting.vue
+++ b/src/renderer/views/Setting.vue
@@ -1,9 +1,19 @@
-div.scroll(:class="$style.setting")
- dl
- dt {{$t('view.setting.basic')}}
+//- div(:class="$style.main")
+ div.scroll(:class="$style.toc")
+ ul(:class="$style.tocList")
+ li(:class="$style.tocListItem" v-for="h2 in toc" :key="h2.id")
+ h2(:class="$style.tocH2" :tips="h2.title")
+ a(:href="'#' + h2.id") {{h2.title}}
+ ul(:class="$style.tocList" v-if="h2.children.length")
+ li(:class="$style.tocSubListItem" v-for="h3 in h2.children" :key="h3.id")
+ h3(:class="$style.tocH3" :tips="h3.title")
+ a(:href="'#' + h3.id") {{h3.title}}
+div.scroll(:class="$style.setting" ref="dom_setting")
+ dl(ref="dom_setting_list")
+ dt#basic {{$t('view.setting.basic')}}
dd
- h3 {{$t('view.setting.basic_theme')}}
+ h3#basic_theme {{$t('view.setting.basic_theme')}}
div
ul(:class="$style.theme")
li(v-for="theme in themes.list" :key="theme.id" :tips="$t('store.state.theme_' + theme.class)" @click="current_setting.themeId = theme.id" :class="[theme.class, themes.active == theme.id ? $style.active : '']")
@@ -11,79 +21,79 @@ div.scroll(:class="$style.setting")
label {{$t('store.state.theme_' + theme.class)}}
dd
- h3 {{$t('view.setting.basic_show_animation')}}
+ h3#basic_show_animation {{$t('view.setting.basic_show_animation')}}
div
material-checkbox(id="setting_show_animate" v-model="current_setting.isShowAnimation" :label="$t('view.setting.is_show')")
dd(:tips="$t('view.setting.basic_animation_title')")
- h3 {{$t('view.setting.basic_animation')}}
+ h3#basic_animation {{$t('view.setting.basic_animation')}}
div
material-checkbox(id="setting_animate" v-model="current_setting.randomAnimate" :label="$t('view.setting.is_enable')")
dd(:tips="$t('view.setting.basic_source_title')")
- h3 {{$t('view.setting.basic_source')}}
+ h3#basic_source {{$t('view.setting.basic_source')}}
div
div(v-for="item in apiSources" :key="item.id" :class="$style.gapTop")
material-checkbox(:id="`setting_api_source_${item.id}`" name="setting_api_source" @change="handleAPISourceChange(item.id)"
need v-model="current_setting.apiSource" :disabled="item.disabled" :value="item.id" :label="item.label")
dd(:tips="$t('view.setting.basic_to_tray_title')")
- h3 {{$t('view.setting.basic_to_tray')}}
+ h3#basic_to_tray {{$t('view.setting.basic_to_tray')}}
div
material-checkbox(id="setting_to_tray" v-model="current_setting.tray.isShow" @change="handleTrayShowChange" :label="$t('view.setting.is_enable')")
dd(:tips="$t('view.setting.basic_window_size_title')")
- h3 {{$t('view.setting.basic_window_size')}}
+ h3#basic_window_size {{$t('view.setting.basic_window_size')}}
div
material-checkbox(v-for="(item, index) in windowSizeList" :id="`setting_window_size_${item.id}`" name="setting_window_size" @change="handleWindowSizeChange" :class="$style.gapLeft"
need v-model="current_setting.windowSizeId" :value="item.id" :label="$t('view.setting.basic_window_size_' + item.name)" :key="item.id")
dd(:tips="$t('view.setting.basic_lang_title')")
- h3 {{$t('view.setting.basic_lang')}}
+ h3#basic_lang {{$t('view.setting.basic_lang')}}
div
material-checkbox(v-for="item in languageList" :key="item.locale" :id="`setting_lang_${item.locale}`" name="setting_lang"
@change="handleLangChange(item.locale)" :class="$style.gapLeft"
need v-model="current_setting.langId" :value="item.locale" :label="item.name")
dd(:tips="$t('view.setting.basic_sourcename_title')")
- h3 {{$t('view.setting.basic_sourcename')}}
+ h3#basic_sourcename {{$t('view.setting.basic_sourcename')}}
div
material-checkbox(v-for="item in sourceNameTypes" :key="item.id" :class="$style.gapLeft" :id="`setting_abasic_sourcename_${item.id}`"
name="setting_basic_sourcename" need v-model="current_setting.sourceNameType" :value="item.id" :label="item.label")
dd
- h3 {{$t('view.setting.basic_control_btn_position')}}
+ h3#basic_control_btn_position {{$t('view.setting.basic_control_btn_position')}}
div
material-checkbox(v-for="item in controlBtnPositionList" :key="item.id" :class="$style.gapLeft" :id="`setting_basic_control_btn_position_${item.id}`"
name="setting_basic_control_btn_position" need v-model="current_setting.controlBtnPosition" :value="item.id" :label="item.name")
- dt {{$t('view.setting.play')}}
+ dt#play {{$t('view.setting.play')}}
dd(:tips="$t('view.setting.play_toggle_title')")
- h3 {{$t('view.setting.play_toggle')}}
+ h3#play_toggle {{$t('view.setting.play_toggle')}}
div
material-checkbox(:id="`setting_player_togglePlay_${item.value}`" :class="$style.gapLeft" :value="item.value" :key="item.value"
v-model="current_setting.player.togglePlayMethod" v-for="item in togglePlayMethods" :label="item.name")
dd
- h3 {{$t('view.setting.play_lyric_transition')}}
+ h3#play_lyric_transition {{$t('view.setting.play_lyric_transition')}}
div
material-checkbox(id="setting_player_lyric_transition" v-model="current_setting.player.isShowLyricTransition" :label="$t('view.setting.is_show')")
dd(:tips="$t('view.setting.play_quality_title')")
- h3 {{$t('view.setting.play_quality')}}
+ h3#play_quality {{$t('view.setting.play_quality')}}
div
material-checkbox(id="setting_player_highQuality" v-model="current_setting.player.highQuality" :label="$t('view.setting.is_enable')")
dd(:tips="$t('view.setting.play_task_bar_title')")
- h3 {{$t('view.setting.play_task_bar')}}
+ h3#play_task_bar {{$t('view.setting.play_task_bar')}}
div
material-checkbox(id="setting_player_showTaskProgess" v-model="current_setting.player.isShowTaskProgess" :label="$t('view.setting.is_enable')")
dd(:tips="$t('view.setting.play_mediaDevice_remove_stop_play_title')")
- h3 {{$t('view.setting.play_mediaDevice_remove_stop_play')}}
+ h3#play_mediaDevice_remove_stop_play {{$t('view.setting.play_mediaDevice_remove_stop_play')}}
div
material-checkbox(id="setting_player_isMediaDeviceRemovedStopPlay" v-model="current_setting.player.isMediaDeviceRemovedStopPlay" :label="$t('view.setting.is_enable')")
dd(:tips="$t('view.setting.play_mediaDevice_title')")
- h3 {{$t('view.setting.play_mediaDevice')}}
+ h3#play_mediaDevice {{$t('view.setting.play_mediaDevice')}}
div
material-selection(:list="mediaDevices" :class="$style.gapLeft" v-model="current_setting.player.mediaDeviceId" item-key="deviceId" item-name="label")
- dt {{$t('view.setting.desktop_lyric')}}
+ dt#desktop_lyric {{$t('view.setting.desktop_lyric')}}
dd
div(:class="$style.gapTop")
material-checkbox(id="setting_desktop_lyric_enable" v-model="current_setting.desktopLyric.enable" :label="$t('view.setting.desktop_lyric_enable')")
@@ -93,38 +103,38 @@ div.scroll(:class="$style.setting")
material-checkbox(id="setting_desktop_lyric_alwaysOnTop" v-model="current_setting.desktopLyric.isAlwaysOnTop" :label="$t('view.setting.desktop_lyric_always_on_top')")
div(:class="$style.gapTop")
material-checkbox(id="setting_desktop_lyric_lockScreen" v-model="current_setting.desktopLyric.isLockScreen" :label="$t('view.setting.desktop_lyric_lock_screen')")
- dt {{$t('view.setting.search')}}
+ dt#search {{$t('view.setting.search')}}
dd(:tips="$t('view.setting.search_hot_title')")
- h3 {{$t('view.setting.search_hot')}}
+ h3#search_hot {{$t('view.setting.search_hot')}}
div
material-checkbox(id="setting_search_showHot_enable" v-model="current_setting.search.isShowHotSearch" :label="$t('view.setting.is_show')")
dd(:tips="$t('view.setting.search_history_title')")
- h3 {{$t('view.setting.search_history')}}
+ h3#search_history {{$t('view.setting.search_history')}}
div
material-checkbox(id="setting_search_showHistory_enable" v-model="current_setting.search.isShowHistorySearch" :label="$t('view.setting.is_show')")
dd(:tips="$t('view.setting.search_focus_search_box_title')")
- h3 {{$t('view.setting.search_focus_search_box')}}
+ h3#search_focus_search_box {{$t('view.setting.search_focus_search_box')}}
div
material-checkbox(id="setting_search_focusSearchBox_enable" v-model="current_setting.search.isFocusSearchBox" :label="$t('view.setting.is_enable')")
- dt {{$t('view.setting.list')}}
+ dt#list {{$t('view.setting.list')}}
dd(:tips="$t('view.setting.list_source_title')")
- h3 {{$t('view.setting.list_source')}}
+ h3#list_source {{$t('view.setting.list_source')}}
div
material-checkbox(id="setting_list_showSource_enable" v-model="current_setting.list.isShowSource" :label="$t('view.setting.is_show')")
dd(:tips="$t('view.setting.list_scroll_title')")
- h3 {{$t('view.setting.list_scroll')}}
+ h3#list_scroll {{$t('view.setting.list_scroll')}}
div
material-checkbox(id="setting_list_scroll_enable" v-model="current_setting.list.isSaveScrollLocation" :label="$t('view.setting.is_enable')")
//- dd(:tips="播放列表是否显示专辑栏")
h3 专辑栏
div
material-checkbox(id="setting_list_showalbum" v-model="current_setting.list.isShowAlbumName" label="是否显示专辑栏")
- dt {{$t('view.setting.download')}}
+ dt#download {{$t('view.setting.download')}}
dd
material-checkbox(id="setting_download_enable" v-model="current_setting.download.enable" :label="$t('view.setting.download_enable')")
dd(:tips="$t('view.setting.download_path_title')")
- h3 {{$t('view.setting.download_path')}}
+ h3#download_path {{$t('view.setting.download_path')}}
div
p
| {{$t('view.setting.download_path_label')}}
@@ -132,24 +142,24 @@ div.scroll(:class="$style.setting")
p
material-btn(:class="$style.btn" min @click="handleChangeSavePath") {{$t('view.setting.download_path_change_btn')}}
dd(:tips="$t('view.setting.download_name_title')")
- h3 {{$t('view.setting.download_name')}}
+ h3#download_name {{$t('view.setting.download_name')}}
div
material-checkbox(:id="`setting_download_musicName_${item.value}`" :class="$style.gapLeft" name="setting_download_musicName" :value="item.value" :key="item.value" need
v-model="current_setting.download.fileName" v-for="item in musicNames" :label="item.name")
dd
- h3 {{$t('view.setting.download_data_embed')}}
+ h3#download_data_embed {{$t('view.setting.download_data_embed')}}
div(:class="$style.gapTop")
material-checkbox(id="setting_download_isEmbedPic" v-model="current_setting.download.isEmbedPic" :label="$t('view.setting.download_embed_pic')")
div(:class="$style.gapTop")
material-checkbox(id="setting_download_isEmbedLyric" v-model="current_setting.download.isEmbedLyric" :label="$t('view.setting.download_embed_lyric')")
dd(:tips="$t('view.setting.download_lyric_title')")
- h3 {{$t('view.setting.download_lyric')}}
+ h3#download_lyric {{$t('view.setting.download_lyric')}}
div
material-checkbox(id="setting_download_isDownloadLrc" v-model="current_setting.download.isDownloadLrc" :label="$t('view.setting.is_enable')")
- dt {{$t('view.setting.hot_key')}}
+ dt#hot_key {{$t('view.setting.hot_key')}}
dd
- h3 {{$t('view.setting.hot_key_local_title')}}
+ h3#hot_key_local_title {{$t('view.setting.hot_key_local_title')}}
div
material-checkbox(id="setting_download_hotKeyLocal" v-model="current_hot_key.local.enable" :label="$t('view.setting.is_enable')" @change="handleHotKeySaveConfig")
div(:class="$style.hotKeyContainer" :style="{ opacity: current_hot_key.local.enable ? 1 : .6 }")
@@ -160,7 +170,7 @@ div.scroll(:class="$style.setting")
@focus="handleHotKeyFocus($event, item, 'local')"
@blur="handleHotKeyBlur($event, item, 'local')")
- h3 {{$t('view.setting.hot_key_global_title')}}
+ h3#hot_key_global_title {{$t('view.setting.hot_key_global_title')}}
div
material-checkbox(id="setting_download_hotKeyGlobal" v-model="current_hot_key.global.enable" :label="$t('view.setting.is_enable')" @change="handleEnableHotKey")
div(:class="$style.hotKeyContainer" :style="{ opacity: current_hot_key.global.enable ? 1 : .6 }")
@@ -171,9 +181,9 @@ div.scroll(:class="$style.setting")
@focus="handleHotKeyFocus($event, item, 'global')"
@blur="handleHotKeyBlur($event, item, 'global')")
- dt {{$t('view.setting.network')}}
+ dt#network {{$t('view.setting.network')}}
dd
- h3 {{$t('view.setting.network_proxy_title')}}
+ h3#network_proxy_title {{$t('view.setting.network_proxy_title')}}
div
p
material-checkbox(id="setting_network_proxy_enable" v-model="current_setting.network.proxy.enable" @change="handleProxyChange('enable')" :label="$t('view.setting.is_enable')")
@@ -183,43 +193,43 @@ div.scroll(:class="$style.setting")
p
material-input(:class="$style.gapLeft" v-model="current_setting.network.proxy.username" @change="handleProxyChange('username')" :placeholder="$t('view.setting.network_proxy_username')")
material-input(:class="$style.gapLeft" v-model="current_setting.network.proxy.password" @change="handleProxyChange('password')" type="password" :placeholder="$t('view.setting.network_proxy_password')")
- dt {{$t('view.setting.odc')}}
+ dt#odc {{$t('view.setting.odc')}}
dd
- h3 {{$t('view.setting.odc_clear_search_input')}}
+ h3#odc_clear_search_input {{$t('view.setting.odc_clear_search_input')}}
div
material-checkbox(id="setting_odc_isAutoClearSearchInput" v-model="current_setting.odc.isAutoClearSearchInput" :label="$t('view.setting.is_enable')")
dd
- h3 {{$t('view.setting.odc_clear_search_list')}}
+ h3#odc_clear_search_list {{$t('view.setting.odc_clear_search_list')}}
div
material-checkbox(id="setting_odc_isAutoClearSearchList" v-model="current_setting.odc.isAutoClearSearchList" :label="$t('view.setting.is_enable')")
- dt {{$t('view.setting.backup')}}
+ dt#backup {{$t('view.setting.backup')}}
dd
- h3 {{$t('view.setting.backup_part')}}
+ h3#backup_part {{$t('view.setting.backup_part')}}
div
material-btn(:class="[$style.btn, $style.gapLeft]" min @click="handleImportPlayList") {{$t('view.setting.backup_part_import_list')}}
material-btn(:class="[$style.btn, $style.gapLeft]" min @click="handleExportPlayList") {{$t('view.setting.backup_part_export_list')}}
material-btn(:class="[$style.btn, $style.gapLeft]" min @click="handleImportSetting") {{$t('view.setting.backup_part_import_setting')}}
material-btn(:class="[$style.btn, $style.gapLeft]" min @click="handleExportSetting") {{$t('view.setting.backup_part_export_setting')}}
dd
- h3 {{$t('view.setting.backup_all')}}
+ h3#backup_all {{$t('view.setting.backup_all')}}
div
material-btn(:class="[$style.btn, $style.gapLeft]" min @click="handleImportAllData") {{$t('view.setting.backup_all_import')}}
material-btn(:class="[$style.btn, $style.gapLeft]" min @click="handleExportAllData") {{$t('view.setting.backup_all_export')}}
- dt {{$t('view.setting.other')}}
+ dt#other {{$t('view.setting.other')}}
dd
- h3 {{$t('view.setting.other_tray_theme')}}
+ h3#other_tray_theme {{$t('view.setting.other_tray_theme')}}
div
material-checkbox(:id="'setting_tray_theme_' + item.id" v-model="current_setting.tray.themeId" name="setting_tray_theme" need :class="$style.gapLeft"
:label="$t('view.setting.other_tray_theme_' + item.name)" :key="item.id" :value="item.id" v-for="item in trayThemeList")
dd
- h3 {{$t('view.setting.other_cache')}}
+ h3#other_cache {{$t('view.setting.other_cache')}}
div
p
| {{$t('view.setting.other_cache_label')}}
span.auto-hidden(:tips="$t('view.setting.other_cache_label_title')") {{cacheSize}}
p
material-btn(:class="$style.btn" min @click="clearCache") {{$t('view.setting.other_cache_clear_btn')}}
- dt {{$t('view.setting.update')}}
+ dt#update {{$t('view.setting.update')}}
dd
p.small
| {{$t('view.setting.update_latest_label')}}{{version.newVersion ? version.newVersion.version : $t('view.setting.update_unknown')}}
@@ -232,7 +242,7 @@ div.scroll(:class="$style.setting")
span(v-if="version.isLatestVer") {{$t('view.setting.update_latest')}}
material-btn(v-else :class="[$style.btn, $style.gapLeft]" min @click="showUpdateModal") {{$t('view.setting.update_open_version_modal_btn')}}
p.small(v-else) {{$t('view.setting.update_checking')}}
- dt {{$t('view.setting.about')}}
+ dt#about {{$t('view.setting.about')}}
dd
p.small
| 本软件完全免费,代码已开源,开源地址:
@@ -582,6 +592,7 @@ export default {
},
isEditHotKey: false,
+ toc: [],
}
},
watch: {
@@ -641,12 +652,43 @@ export default {
init() {
this.current_setting = JSON.parse(JSON.stringify(this.setting))
if (!window.currentWindowSizeId) window.currentWindowSizeId = this.setting.windowSizeId
+ // this.initTOC()
this.getCacheSize()
this.getMediaDevice()
this.current_hot_key = window.appHotKeyConfig
this.initHotKeyConfig()
this.getHotKeyStatus()
},
+ // initTOC() {
+ // const list = this.$refs.dom_setting_list.children
+ // const toc = []
+ // let prevTitle
+ // for (const item of list) {
+ // if (item.tagName == 'DT') {
+ // prevTitle = {
+ // title: item.innerText.replace(/[((].+?[))]/, ''),
+ // id: item.getAttribute('id'),
+ // dom: item,
+ // children: [],
+ // }
+ // toc.push(prevTitle)
+ // continue
+ // }
+ // const h3 = item.querySelector('h3')
+ // if (h3) {
+ // prevTitle.children.push({
+ // title: h3.innerText.replace(/[((].+?[))]/, ''),
+ // id: h3.getAttribute('id'),
+ // dom: h3,
+ // })
+ // }
+ // }
+ // console.log(toc)
+ // this.toc = toc
+ // },
+ // handleListScroll(event) {
+ // // console.log(event.target.scrollTop)
+ // },
handleChangeSavePath() {
selectDir({
title: this.$t('view.setting.download_select_save_path'),
@@ -851,6 +893,7 @@ export default {
},
handleLangChange(id) {
this.$i18n.locale = id
+ // this.$nextTick(() => this.initTOC())
},
async getMediaDevice() {
const devices = await navigator.mediaDevices.enumerateDevices()
@@ -1047,12 +1090,56 @@ export default {