Compare commits

...

1482 Commits

Author SHA1 Message Date
lyswhut
66b965d9f7 Merge branch 'dev' 2022-09-03 01:17:26 +08:00
lyswhut
f4285ae106 发布v1.22.3 2022-09-03 01:17:05 +08:00
lyswhut
657e65bc6a 修复因音源的域名到期导致的音源失效的问题 2022-09-03 01:16:23 +08:00
lyswhut
41fc8d2e2e 修正错误 2022-09-03 01:15:24 +08:00
lyswhut
25ca781d76 更新faq 2022-08-22 18:39:08 +08:00
lyswhut
41f4130e5d Merge branch 'dev' 2022-08-18 17:15:24 +08:00
lyswhut
8e19f3fc0b 发布v1.22.2 2022-08-18 17:15:00 +08:00
lyswhut
c4b8ac8b0b 修复hires类型显示 2022-08-11 17:20:07 +08:00
lyswhut
0ac2df1297 更新版本号 2022-08-11 17:01:18 +08:00
lyswhut
251450fd50 修复企鹅音乐搜索失效的问题 2022-08-11 15:44:37 +08:00
lyswhut
85c5595f43 更新依赖 2022-08-06 18:26:10 +08:00
lyswhut
ca3188c930 优化列表保存性能 2022-08-06 18:20:58 +08:00
lyswhut
2f47f82b0f 修复某些缺失的繁体中文翻译 2022-08-06 17:33:23 +08:00
lyswhut
0e09598b10 降级electron到v15.5.7 2022-08-05 10:45:17 +08:00
lyswhut
a705420528 修复依赖安全警告 2022-08-04 09:31:39 +08:00
lyswhut
4089887514 升级electron到v18.3.7 2022-08-04 09:18:53 +08:00
lyswhut
a3d02e5f39 修复列表移动的更新问题 2022-08-04 08:38:30 +08:00
lyswhut
6e09363832 修复无法批量排序歌曲的问题 2022-08-04 08:37:57 +08:00
lyswhut
1c58a64847 修复wy源音质获取问题 2022-07-22 14:29:57 +08:00
lyswhut
2a716e4d5a 更新依赖 2022-07-17 12:40:21 +08:00
lyswhut
a2c613d380 修复默认设置的语言显示问题 2022-07-10 16:06:07 +08:00
lyswhut
aa4b09436c Merge branch 'dev' 2022-07-09 12:03:42 +08:00
lyswhut
9521bba4ba 发布v1.22.1 2022-07-09 12:03:16 +08:00
lyswhut
55d10021f8 更新依赖 2022-07-08 19:03:36 +08:00
lyswhut
7fe35748d0 更新依赖 2022-07-08 16:43:28 +08:00
lyswhut
ff9efbd4ea 歌单列表添加歌单内歌曲数量显示 2022-07-08 16:39:56 +08:00
lyswhut
23b8c325f4 修复tx源搜索失效的问题 2022-07-08 09:12:45 +08:00
lyswhut
ecfccb4c40 修复临时列表meta信息丢失的问题 2022-07-03 22:55:33 +08:00
lyswhut
2472574cde 更新依赖 2022-07-03 22:16:06 +08:00
lyswhut
bf81c8facc 更新版本号 2022-06-25 13:23:30 +08:00
lyswhut
9bf0d69ab6 更新依赖 2022-06-25 10:29:55 +08:00
lyswhut
cf9d98d434 修复若桌面歌词窗口与主窗口重叠时,鼠标划过重叠区域鼠标会闪烁的问题 2022-06-20 12:02:55 +08:00
lyswhut
da8e67d4e5 修复处于不支持的源时,歌单、排行榜的右键下载菜单没有禁用的问题 2022-06-19 14:36:04 +08:00
lyswhut
d695cdef08 Merge branch 'dev' 2022-06-19 12:34:09 +08:00
lyswhut
d7a7701c09 发布v1.22.0 2022-06-19 11:59:11 +08:00
lyswhut
a31180260b 屏蔽设置 2022-06-18 11:50:54 +08:00
lyswhut
f33947287c 更新版本号 2022-06-17 20:26:08 +08:00
lyswhut
c054ceeab5 修复 2022-06-17 20:17:42 +08:00
lyswhut
c8dce1bcb6 更新更新 Electron 到 v17.4.7 2022-06-17 20:16:07 +08:00
lyswhut
6195c10646 更新常见问题地址 2022-06-17 19:20:08 +08:00
lyswhut
535cbbbd16 修复ctrl跳转播放失效的问题 2022-06-17 14:44:28 +08:00
lyswhut
fa99f35bc0 修复歌词显示问题 2022-06-15 11:08:00 +08:00
lyswhut
5800f0e354 添加导入文件错误时的指引提示 2022-06-15 09:30:58 +08:00
lyswhut
aa5e621184 新增设置-桌面歌词设置-鼠标移入歌词区域时降低歌词透明度(#883) 2022-06-14 11:43:18 +08:00
lyswhut
283bdd6246 添加歌曲列表更新操作的二次确认 2022-06-13 12:57:25 +08:00
lyswhut
2884e67109 修复esc键冲突问题 2022-06-12 18:01:26 +08:00
lyswhut
4542f9b2e3 更新依赖 2022-06-12 14:46:34 +08:00
lyswhut
9d08f91079 修复在新建歌单输入框、歌单内歌曲搜索输入框会意外触发设置的全局快捷键的问题(#879) 2022-06-12 14:39:58 +08:00
lyswhut
0704a4ad12 修复设置快捷键时的处理逻辑问题 2022-06-11 18:52:52 +08:00
lyswhut
bb8509a21c 支持mg源逐字歌词的播放 2022-06-09 13:03:46 +08:00
lyswhut
f2e3d4a53d 更新版本号 2022-06-07 19:49:01 +08:00
lyswhut
b8a221e67e 更新t文档 2022-06-07 08:52:19 +08:00
lyswhut
f4147cce37 添加其他开发者工具打开方式 2022-06-07 08:51:41 +08:00
lyswhut
01f9fd502f 还原文档 2022-06-06 10:00:12 +08:00
lyswhut
5d20adc81e 更新依赖 2022-06-05 14:51:58 +08:00
lyswhut
6a78f659e3 移除http_proxy环境变量 2022-06-05 14:51:46 +08:00
lyswhut
211f584bf8 更新文档说明 2022-06-04 13:03:20 +08:00
lyswhut
fcfba8b12c 新增添加歌曲到“我的列表”时,若按住ctrl键,则不会自动关闭添加窗口 2022-06-04 12:48:26 +08:00
lyswhut
85e4c7555a 修复多选后切换列表后不会清空多选内容的问题 2022-06-04 12:43:15 +08:00
lyswhut
19dccffdde 优化换源匹配 2022-05-31 09:13:59 +08:00
lyswhut
359514a83c 修复变量移除问题 2022-05-29 10:58:04 +08:00
lyswhut
90ea0dc857 修复环境变量被替换的问题 2022-05-29 10:48:05 +08:00
lyswhut
ae18db45a4 修复若配置了http_proxy环境变量时,会意外使用此代理配置的问题 2022-05-29 10:39:14 +08:00
lyswhut
4783c9be8d 更新依赖 2022-05-26 13:02:52 +08:00
lyswhut
ff41fa9829 修复kuwo歌词解析 2022-05-26 12:03:40 +08:00
lyswhut
aa56dafd5f 新增设置-以全屏模式启动设置 2022-05-24 08:57:04 +08:00
lyswhut
f2f2008d5d Merge branch 'dev' 2022-05-22 11:17:47 +08:00
lyswhut
15d2589db8 发布v1.21.0 2022-05-22 11:17:13 +08:00
lyswhut
47a8da49ca 修改包大小提示 2022-05-22 01:50:34 +08:00
lyswhut
2250cac7f9 不处理可能存在翻译的歌词 2022-05-22 01:50:02 +08:00
lyswhut
94e3063307 添加flac 24bit显示 2022-05-20 19:32:31 +08:00
lyswhut
88691b3f18 更新依赖 2022-05-19 17:33:12 +08:00
lyswhut
3851880007 添加稍后播放说明 2022-05-19 15:19:37 +08:00
lyswhut
e5d2e089f4 在全屏状态下使用Esc键可以退出全屏 2022-05-19 14:57:42 +08:00
lyswhut
bfe7f24a4b 删除未下载完成的任务时,只同时尝试删除已有下载进度的本地文件(#849) 2022-05-17 10:07:34 +08:00
lyswhut
0d1e2c3349 更新链接 2022-05-17 09:22:43 +08:00
lyswhut
bc6272a0ed 更新依赖 2022-05-17 09:11:52 +08:00
lyswhut
56a752dc26 更新依赖 2022-05-13 10:48:32 +08:00
lyswhut
0fe443c92a 修复潜在歌单更新失败的问题 2022-05-12 12:03:45 +08:00
lyswhut
74afdb2a46 更新依赖 2022-05-11 15:52:04 +08:00
lyswhut
ebd6ff36ed 合并打包的页面文件 2022-05-11 15:37:06 +08:00
lyswhut
a5ec36bf89 新增设置-播放设置-显示歌词罗马音 2022-05-10 11:12:14 +08:00
lyswhut
c65802c1c3 修复长度大于一行的歌词在使用歌词调整播放进度时的时间不准问题 2022-05-10 09:36:12 +08:00
lyswhut
784515e411 修复原始歌词存在偏移时,歌词偏移设置的重置未按预期工作的问题 2022-05-09 14:07:31 +08:00
lyswhut
e859d39b2b 更新依赖 2022-05-08 13:34:59 +08:00
lyswhut
62c4bfb9eb 修复评论换行处理问题 2022-05-07 12:56:46 +08:00
lyswhut
8ab1bdf30a 修复关闭“显示切换动画”设置后,在应用启动时该设置没有被应用的问题 2022-05-05 16:02:09 +08:00
lyswhut
c758066e25 禁用透明窗口时右侧不再偏移5px距离 2022-05-05 14:57:04 +08:00
lyswhut
06b7f69b3c 同时删除一首歌以上时将需要二次确认删除 2022-05-04 10:06:02 +08:00
lyswhut
c3c43a2645 修复某些情况下歌曲播放出错时不会自动切歌的问题 2022-05-03 19:53:13 +08:00
lyswhut
343395a5de 更新依赖 2022-05-03 18:55:39 +08:00
lyswhut
3c9bb74b61 lint fix 2022-04-26 13:04:28 +08:00
lyswhut
c9cf30692f 更新依赖 2022-04-26 13:04:19 +08:00
lyswhut
c979339c4e Merge branch 'dev' 2022-04-17 10:06:33 +08:00
lyswhut
9393906eb9 修复构建 2022-04-17 10:06:13 +08:00
lyswhut
1b4c910264 Merge branch 'dev' 2022-04-17 09:08:06 +08:00
lyswhut
4db5d26b1e 发布v1.20.0 2022-04-17 09:07:44 +08:00
lyswhut
c09a4131db 修复歌词菜单弹出位置问题 2022-04-16 14:41:58 +08:00
lyswhut
ce6f3f23c6 修复歌曲匹配 2022-04-16 14:19:19 +08:00
lyswhut
7b898c2d91 更新依赖 2022-04-16 13:49:29 +08:00
lyswhut
3da797a0ad 修复linux构建 2022-04-13 20:04:25 +08:00
lyswhut
517899cd03 优化逻辑 2022-04-13 11:52:01 +08:00
lyswhut
1d6a14685e 更新依赖 2022-04-13 11:09:30 +08:00
lyswhut
737d00f550 修复正在下载的歌曲暂停任务后,再开始会导致程序卡死的问题 2022-04-13 11:08:29 +08:00
lyswhut
68798a9627 优化歌词选择UI问题 2022-04-11 11:56:22 +08:00
lyswhut
5b1dfee05c 修复歌曲信息更新时的保存问题 2022-04-10 22:40:28 +08:00
lyswhut
e75863e99d 跳过空白歌词 2022-04-10 22:25:25 +08:00
lyswhut
1c542a9b17 跳过空白歌词 2022-04-10 22:11:42 +08:00
lyswhut
729ac5a0d7 修复全屏切换的事件清理问题 2022-04-10 21:37:25 +08:00
lyswhut
ff8195df46 添加列表元数据清理 2022-04-10 21:03:40 +08:00
lyswhut
692ab6dacb 更新依赖 2022-04-10 20:28:29 +08:00
lyswhut
128039d678 修复歌词偏移处理问题 2022-04-09 13:42:12 +08:00
lyswhut
bb5de056d4 更新依赖 2022-04-09 10:40:45 +08:00
lyswhut
d927ac90e7 修复按键监听问题 2022-04-08 14:04:50 +08:00
lyswhut
f61099ecad 修改按键绑定 2022-04-08 11:43:43 +08:00
lyswhut
f96b663bbe 更新版本号 2022-04-07 19:29:18 +08:00
lyswhut
f65213f8aa 修复启用代理时,https请求可能被挂起或被转为http的问题 2022-04-07 14:41:09 +08:00
lyswhut
2e5adeb50c 优化滚动 2022-04-07 09:54:06 +08:00
lyswhut
6de84d3b9b 修复歌词调整时间显示问题 2022-04-07 09:24:09 +08:00
lyswhut
65ae08add6 修复网易歌单详情无法打开的问题 2022-04-07 08:28:02 +08:00
lyswhut
3c970c24c1 修复换源失败时的处理问题 2022-04-05 22:08:35 +08:00
lyswhut
93f3507dc8 添加说明 2022-04-05 17:15:29 +08:00
lyswhut
e92e291409 修复鼠标自动隐藏问题 2022-04-05 16:47:37 +08:00
lyswhut
4b4de8937e 更新windows下的图标 2022-04-05 14:34:56 +08:00
lyswhut
27a036bc00 优化布局 2022-04-04 20:56:40 +08:00
lyswhut
1eb2540c67 更新依赖 2022-04-04 20:11:30 +08:00
lyswhut
3a5bd6029f 更新版本号 2022-04-03 14:00:20 +08:00
lyswhut
249ff7f2d2 尝试修改应用名称 2022-04-03 13:56:39 +08:00
lyswhut
9afa965d5d 修复使用Scheme URL搜索歌曲时,不会自动关闭播放详情页(若处于打开状态)的问题 2022-04-03 00:37:38 +08:00
lyswhut
28b7b5581d 添加提示 2022-04-02 22:14:47 +08:00
lyswhut
26aab15e50 修复wy源搜索某些歌曲时第一页之后的歌曲无法加载的问题 2022-04-02 21:16:41 +08:00
lyswhut
92351049f1 修复潜在更新问题 2022-04-02 14:26:31 +08:00
lyswhut
47d3c50863 新增列表更新管理 2022-04-02 14:13:58 +08:00
lyswhut
36ac3532e6 修复歌词菜单的弹出问题 2022-04-01 14:29:07 +08:00
lyswhut
dee16f6943 修复播放详情页的鼠标隐藏问题 2022-04-01 14:28:22 +08:00
lyswhut
3541b568c9 更新版本号 2022-03-31 17:54:35 +08:00
lyswhut
4dfa4d9525 新增设置-桌面歌词设置-自动刷新歌词置顶 2022-03-31 17:54:22 +08:00
lyswhut
5938f4e591 修复窗口尺寸设置对应的字体大小在启动后不生效的问题 2022-03-31 13:19:50 +08:00
lyswhut
9ac26be65d 记录连接时间 2022-03-30 16:22:13 +08:00
lyswhut
5099ba9c96 添加源有效性校验 2022-03-30 13:14:23 +08:00
lyswhut
bca5b13516 修复鼠标不会隐藏的问题 2022-03-28 20:28:33 +08:00
lyswhut
6ceb984393 更新版本号 2022-03-28 19:04:40 +08:00
lyswhut
17b29f376a 更新说明文档 2022-03-28 18:46:13 +08:00
lyswhut
36bef673d3 在全屏状态下鼠标在空白处静止不动3秒后自动将其隐藏 2022-03-28 18:05:58 +08:00
lyswhut
c2fa4e5220 修复不启用热门搜索时,搜索历史不显示的问题 2022-03-28 14:11:03 +08:00
lyswhut
ddf06d20c2 移除右击调整 2022-03-28 13:04:43 +08:00
lyswhut
e51f640371 在全屏状态下的播放详情页仍会显示退出播放详情页按钮 2022-03-28 09:41:30 +08:00
lyswhut
e302f53d5c Update 2022-03-27 12:23:48 +08:00
lyswhut
b2058b9581 调整颜色 2022-03-26 14:59:13 +08:00
lyswhut
35501d328b 加深颜色 2022-03-26 13:15:39 +08:00
lyswhut
cb746c64db 更新版本号 2022-03-26 13:06:34 +08:00
lyswhut
e2f6d117bc 优化播放详情页背景显示 2022-03-26 13:06:07 +08:00
lyswhut
9fd9449eca 新增播放错误时自动切换歌曲设置 2022-03-25 15:52:33 +08:00
lyswhut
1f97af6ff1 修复歌词解析问题 2022-03-25 15:52:19 +08:00
lyswhut
f1a7862a9c 更新node版本 2022-03-25 14:34:12 +08:00
lyswhut
8aeac3ed2e 更新依赖 2022-03-25 10:24:47 +08:00
lyswhut
469832a598 通过歌词调整进度时添加对偏移时间的计算 2022-03-23 17:49:34 +08:00
lyswhut
e0e65e4374 更新版本号 2022-03-22 20:21:01 +08:00
lyswhut
66f78d6979 修复偏移标签的匹配问题 2022-03-22 20:19:16 +08:00
lyswhut
efc58f7dd1 更新版本号 2022-03-22 17:49:18 +08:00
lyswhut
bc301c27c2 新增播放详情页歌词右键菜单,新增歌词偏移设置 2022-03-22 16:55:44 +08:00
lyswhut
82ea1935de 修复任务栏收藏按钮的下载列表歌曲收藏问题 2022-03-21 10:03:35 +08:00
lyswhut
226fb05337 修复Linux无法全屏的问题 2022-03-20 20:16:01 +08:00
lyswhut
be219f03d5 typo 2022-03-20 14:28:59 +08:00
lyswhut
f10c1e923e Merge branch 'dev' 2022-03-20 13:52:15 +08:00
lyswhut
66121e5ff3 发布v1.19.0 2022-03-20 13:50:32 +08:00
lyswhut
478b71172d 添加切歌逻辑注释 2022-03-20 12:53:48 +08:00
lyswhut
e7370f12ae 切换devtools版本 2022-03-20 12:26:03 +08:00
lyswhut
b844a577c7 迁移提示文本字段 2022-03-20 12:04:01 +08:00
lyswhut
9bf33fdb25 优化播放下载列表时的切歌性能 2022-03-20 01:47:09 +08:00
lyswhut
8b988b227b 修复下载列表播放歌曲序号更新问题 2022-03-20 00:43:16 +08:00
lyswhut
8b2be019c6 移除偏移 2022-03-19 19:46:13 +08:00
lyswhut
4d7d92759f 过滤id重复的歌曲 2022-03-19 16:25:28 +08:00
lyswhut
798b840472 fix syntax 2022-03-19 13:07:43 +08:00
lyswhut
48db75a995 更新依赖 2022-03-19 13:05:49 +08:00
lyswhut
7072541ba7 Generate file MD5 2022-03-19 13:03:10 +08:00
lyswhut
7119c915ec 修复依赖漏洞警告问题 2022-03-18 20:30:58 +08:00
lyswhut
5e3035cc15 更新依赖 2022-03-18 19:32:00 +08:00
lyswhut
7cf2e4c4ed 修复歌单详情获取流程问题 2022-03-18 14:56:29 +08:00
lyswhut
674a3a0a3f 优化歌词解析 2022-03-18 14:36:00 +08:00
lyswhut
7486a99494 修改延迟 2022-03-18 13:15:52 +08:00
lyswhut
783d96bd7d 更新文档 2022-03-18 11:38:08 +08:00
lyswhut
64eea42092 优化歌词播放机制 2022-03-18 11:27:31 +08:00
lyswhut
8453ad0fb4 修复歌词播放问题 2022-03-18 11:26:52 +08:00
lyswhut
0acfeff006 优化托盘菜单操作#686 2022-03-18 10:56:28 +08:00
lyswhut
a338b7ef39 取消默认偏移 2022-03-15 15:29:53 +08:00
lyswhut
e821660124 添加动画 2022-03-15 11:23:58 +08:00
lyswhut
bad6045164 修复歌词解析问题 2022-03-15 10:54:51 +08:00
lyswhut
6779fd7ae5 优化歌词偏移时间计算 2022-03-15 10:23:47 +08:00
lyswhut
04858cc42c 修复歌词解析问题 2022-03-14 19:38:48 +08:00
lyswhut
916975b0a9 更新版本号 2022-03-14 17:59:38 +08:00
lyswhut
644db88e58 添加对歌词offset字段的支持 2022-03-14 17:37:27 +08:00
lyswhut
b025af45fa 优化歌词播放器 2022-03-14 17:06:50 +08:00
lyswhut
0f11731c01 修复歌词解析问题 2022-03-14 15:37:44 +08:00
lyswhut
ea1d21a3ef 修复歌词解析问题 2022-03-14 10:24:30 +08:00
lyswhut
545ba6521b 新增对kw源卡拉OK歌词的支持 2022-03-14 10:02:31 +08:00
lyswhut
1fd3e6c9fa 更换kw歌词获取方式 2022-03-13 15:00:43 +08:00
lyswhut
2913c0c7de 优化音频可视化与音频设备输出设置冲突的提示机制 2022-03-13 11:32:40 +08:00
lyswhut
a4c851899f 修复依赖漏洞警告 2022-03-12 21:32:51 +08:00
lyswhut
df1c58e79b 修复依赖安全警告 2022-03-12 20:53:59 +08:00
lyswhut
67edeab09b 更新版本号 2022-03-11 21:44:46 +08:00
lyswhut
fe07ac025a 修复设置的迁移问题 2022-03-11 21:44:38 +08:00
lyswhut
fc72d99ab3 优化大屏的UI布局 2022-03-11 21:36:33 +08:00
lyswhut
377f665361 修复UI问题 2022-03-11 20:44:40 +08:00
lyswhut
4e458ec4cb 修复计算问题 2022-03-11 20:08:41 +08:00
lyswhut
6f4500f31a 修复与优化列表渲染 2022-03-11 15:10:29 +08:00
lyswhut
a363c5525b 修复使用链接导入的歌单无法在我的列表打开原歌单详情页的问题 2022-03-11 12:02:59 +08:00
lyswhut
65027fceba 修复设置迁移问题 2022-03-11 11:30:47 +08:00
lyswhut
2b0c75a649 添加提示 2022-03-11 11:29:30 +08:00
lyswhut
bcc79541c1 优化大屏下的UI展示 2022-03-11 10:52:13 +08:00
lyswhut
081d6dc91e 修复评论列表显示问题 2022-03-11 10:10:01 +08:00
lyswhut
09a5111e36 修复列表渲染问题 2022-03-10 19:52:03 +08:00
lyswhut
253746843c 更新描述 2022-03-10 19:02:09 +08:00
lyswhut
5d2fac9247 更新版本号 2022-03-10 17:47:05 +08:00
lyswhut
3c2a1093a0 更新依赖 2022-03-10 17:46:41 +08:00
lyswhut
88b3d8ee4a 新增动态主题“道法自然” 2022-03-10 16:07:51 +08:00
lyswhut
d35a6f504f 优化下载、歌曲添加弹窗在大屏幕下的排版 2022-03-09 15:03:35 +08:00
lyswhut
4965dad6a2 修复评论宽度计算问题 2022-03-09 15:02:49 +08:00
lyswhut
3ad4584159 修复设置意外被更改的问题 2022-03-08 18:20:09 +08:00
lyswhut
5e291255bb 修复切换全屏问题 2022-03-08 18:02:45 +08:00
lyswhut
205c99372e 修复标签列表宽度问题 2022-03-08 17:42:42 +08:00
lyswhut
a05f3a969b 更新版本号 2022-03-08 17:19:57 +08:00
lyswhut
3acc0931d8 新增全屏状态 2022-03-08 17:19:34 +08:00
lyswhut
05f6a953ea 添加音频可视化与音频输出设备冲突的提示 2022-03-08 14:51:29 +08:00
lyswhut
6253368f05 更新版本号 2022-03-08 08:32:00 +08:00
lyswhut
9483f2f178 修复依赖 2022-03-07 19:10:15 +08:00
lyswhut
8df6e7ef90 修复展开评论时的歌词大小问题 2022-03-07 17:23:33 +08:00
lyswhut
b09dba0a95 添加通过歌词调整播放进度开关设置 2022-03-07 16:10:18 +08:00
lyswhut
cfee4a0b24 新增通过播放详情页歌词调整播放进度 2022-03-07 15:33:04 +08:00
lyswhut
34febf4949 确保音频输出改变时能暂停播放 2022-03-06 21:57:32 +08:00
lyswhut
6aed9dfb9f 修复Windows任务栏缩略图工具栏控制按钮的歌曲收藏按钮状态更新问题 2022-03-06 21:38:45 +08:00
lyswhut
c7360993c9 更新说明 2022-03-06 14:29:44 +08:00
lyswhut
34a072bada 修复展开评论时的歌词间隔问题 2022-03-06 13:43:58 +08:00
lyswhut
dda0d54f20 添加歌词间隔跟随字体大小改变 2022-03-06 13:33:13 +08:00
lyswhut
d710c31d48 修复翻译依赖导致的错误 2022-03-06 13:11:03 +08:00
lyswhut
02c74f7d96 修复AppImage包无法运行的问题 2022-03-06 10:27:37 +08:00
lyswhut
5bdccba29e 修复高度塌陷的问题 2022-03-05 16:11:25 +08:00
lyswhut
cdc819fbe8 新增对播放详情页歌词大小、是否缩放、对齐方式的设置 2022-03-05 16:06:45 +08:00
lyswhut
4629d4cd3e 修复桌面歌词没有处理停止播放状态的问题 2022-03-03 17:39:33 +08:00
lyswhut
ba3a70c524 更新快捷操作说明 2022-03-03 13:15:56 +08:00
lyswhut
52b985dd8e 更新依赖 2022-03-02 18:41:29 +08:00
lyswhut
b51c8e1552 修复“当前的声音输出设备被改变时暂停播放歌曲”设置无效的问题 2022-02-28 12:00:54 +08:00
lyswhut
86f9c03707 添加LX中定义的快捷操作汇总说明 2022-02-27 12:25:53 +08:00
lyswhut
e61c84ee08 优化Windows任务栏缩略图工具栏控制按钮在浅色任务栏下的显示效果 2022-02-27 11:36:18 +08:00
lyswhut
2f39808275 Merge branch 'dev' 2022-02-26 13:39:58 +08:00
lyswhut
f5aee4cbd0 修复依赖 2022-02-26 13:39:37 +08:00
lyswhut
9fd9bb4eef Merge branch 'dev' 2022-02-26 13:31:14 +08:00
lyswhut
685cae8993 更新依赖 2022-02-26 13:30:54 +08:00
lyswhut
ec14aadec6 Merge branch 'dev' 2022-02-26 13:14:33 +08:00
lyswhut
b934770e1e 更新依赖 2022-02-26 13:14:19 +08:00
lyswhut
2f76433f34 Merge branch 'dev' 2022-02-26 12:58:31 +08:00
lyswhut
535c63be2b 修改构建顺序 2022-02-26 12:57:58 +08:00
lyswhut
53d4f08ee7 Merge branch 'dev' 2022-02-26 12:22:00 +08:00
lyswhut
81b72fe72b 发布v1.18.0 2022-02-26 12:21:40 +08:00
lyswhut
e496794052 更新依赖 2022-02-26 12:19:48 +08:00
lyswhut
442b4fb30f 分离方法 2022-02-25 10:26:59 +08:00
lyswhut
9528b10d01 添加debug启动参数 2022-02-25 10:18:57 +08:00
lyswhut
a9f9c887b5 更新版本号 2022-02-24 17:25:03 +08:00
lyswhut
6105a331aa 修复播放器的停止逻辑问题 2022-02-24 17:23:33 +08:00
lyswhut
0f0be95c12 修复任务栏按钮的控制问题 2022-02-24 17:21:36 +08:00
lyswhut
d6ca9e4539 修复windows平台下软件目录存在portable文件夹时,仍会在默认目录创建文件的问题 2022-02-24 13:09:13 +08:00
lyswhut
d3b5171237 优化滚动 2022-02-22 17:05:18 +08:00
lyswhut
cf501ac19e 修复字体设置不生效的问题 2022-02-22 08:56:10 +08:00
lyswhut
4fd4746ddf 更新版本号 2022-02-21 17:41:56 +08:00
lyswhut
61c1476823 新增任务栏缩略图工具栏控制按钮 2022-02-21 16:05:41 +08:00
lyswhut
e28b8bb6e8 修改默认字体 2022-02-21 10:28:09 +08:00
lyswhut
5eb9107adf 新增设置-基本设置-软件字体设置 2022-02-20 17:22:58 +08:00
lyswhut
83ddf74890 修复歌单详情的播放按钮无效的问题 2022-02-18 17:21:11 +08:00
lyswhut
6aa7f2a0ee 移除多余样式 2022-02-18 16:34:35 +08:00
lyswhut
d801d55c3c 修复进度条动画问题 2022-02-18 16:21:03 +08:00
lyswhut
491e644c3c 修改进度条高度 2022-02-18 16:15:08 +08:00
lyswhut
5844232a00 添加源数量限制 2022-02-18 15:50:51 +08:00
lyswhut
abbf067625 修复歌单无法从用data传参调用的问题 2022-02-18 14:48:15 +08:00
lyswhut
806c882965 更新说明 2022-02-18 11:26:17 +08:00
lyswhut
3fe5a85ffe 更新依赖 2022-02-18 10:33:56 +08:00
lyswhut
95dae62bb3 更新说明 2022-02-17 16:29:42 +08:00
lyswhut
f7edd54ea7 修复宽度计算问题 2022-02-17 15:48:55 +08:00
lyswhut
78ae89199e 更新说明 2022-02-17 14:53:51 +08:00
lyswhut
fc12a235f2 自定义源添加更新地址参数 2022-02-17 10:13:45 +08:00
lyswhut
48fc96226c 更新版本号 2022-02-16 18:38:11 +08:00
lyswhut
3534dd27dc 自定义源新增更新弹窗方法 2022-02-16 18:32:55 +08:00
lyswhut
a7e3c1a0c4 优化进度条动画 2022-02-16 11:30:35 +08:00
lyswhut
43c5051158 打开播放详情页时隐藏外部进度条 2022-02-16 10:33:52 +08:00
lyswhut
2f56a7090a 新增Scheme URL对音乐搜索的调用支持;新增Scheme URL以url传参的方式调用 2022-02-15 18:49:02 +08:00
lyswhut
13ffcfbbcd 更新调用错误信息弹窗按钮文案 2022-02-15 15:29:13 +08:00
lyswhut
1aeb8e29e2 更新依赖 2022-02-15 15:13:25 +08:00
lyswhut
a3b844d2e3 添加缺失的翻译 2022-02-14 15:55:12 +08:00
lyswhut
5aa027f1a9 修复问题 2022-02-14 15:48:43 +08:00
lyswhut
c12be6a1c8 新增定时暂停播放功能 2022-02-14 15:38:27 +08:00
lyswhut
c891ed81e1 修复某些歌曲无法下载的问题 2022-02-13 14:17:38 +08:00
lyswhut
c48921990d 修复下载功能的歌词换源时会进入死循环的问题 2022-02-13 14:16:45 +08:00
lyswhut
54bfd945e5 修复wy源某些歌曲获取歌词翻译的问题处理 2022-02-13 14:14:23 +08:00
lyswhut
1d8c4db5eb 更新版本号 2022-02-12 18:25:39 +08:00
lyswhut
055ab98d4c 把歌曲的热门评论与最新评论拆分成两个列表显示 2022-02-11 19:38:51 +08:00
lyswhut
777551cb43 新增打开收藏的在线列表的对应平台详情页功能 2022-02-11 16:51:39 +08:00
lyswhut
68827f7697 修复修改列表名时无法使用Ctrl键的问题 2022-02-11 16:06:07 +08:00
lyswhut
8e5b144f00 新增“双击列表里的歌曲时自动切换到当前列表播放”设置 2022-02-10 12:48:01 +08:00
lyswhut
748a420b64 修复排行榜名字右击菜单的播放功能在播放非激活的列表时的列表获取问题 2022-02-09 21:02:43 +08:00
lyswhut
80fc43a075 更新依赖 2022-02-09 19:53:26 +08:00
lyswhut
0588f2846b 添加链接 2022-02-08 17:34:58 +08:00
lyswhut
8e4e7d9efa 更新依赖 2022-02-07 13:02:46 +08:00
lyswhut
6df01edc7a 更新electron到v13.6.9 2022-02-04 18:30:06 +08:00
lyswhut
996396c943 过滤tx源某些不支持播放的歌曲,解决播放此类内容会导致意外的问题 2022-02-04 18:29:48 +08:00
lyswhut
e3dddb9288 Merge branch 'dev' 2022-01-28 19:16:01 +08:00
lyswhut
47ce71c959 发布v1.17.1 2022-01-28 19:09:56 +08:00
lyswhut
8921aeb3f2 更新依赖 2022-01-28 19:08:13 +08:00
lyswhut
35be9739d4 修复列表的聚焦问题 2022-01-27 09:33:49 +08:00
lyswhut
f5ce46431b 修复快捷键与默认按键行为冲突的问题 2022-01-27 09:31:28 +08:00
lyswhut
81ed70d291 更新依赖 2022-01-26 17:49:25 +08:00
lyswhut
4b0fdceb76 优化kw源英文与翻译歌词的匹配 2022-01-26 17:47:03 +08:00
lyswhut
58e537732c 更新依赖 2022-01-25 17:36:35 +08:00
lyswhut
02ad79b12a 更新依赖 2022-01-24 16:01:26 +08:00
lyswhut
b179887efc 更新链接 2022-01-22 13:27:06 +08:00
lyswhut
0580b059fc Merge branch 'dev' 2022-01-22 13:02:05 +08:00
lyswhut
bebd0e7258 发布v1.17.0 2022-01-22 13:01:38 +08:00
lyswhut
6e96b2163e 更新依赖 2022-01-22 13:00:18 +08:00
lyswhut
ca15ac987c 更新依赖 2022-01-21 16:46:01 +08:00
lyswhut
6d3414caa9 更新版本号 2022-01-18 16:41:18 +08:00
lyswhut
85b80312e0 修改颜色 2022-01-18 16:04:26 +08:00
lyswhut
30d5f53c1d 更新已收藏的在线列表时,将始终重新加载,不再使用缓存 2022-01-18 15:34:48 +08:00
lyswhut
bad2e98757 更新依赖 2022-01-18 08:49:56 +08:00
lyswhut
45da396cb2 修复tx源无搜索结果的问题 2022-01-18 08:49:36 +08:00
lyswhut
d195176a46 修复列表跳转问题 2022-01-17 09:21:12 +08:00
lyswhut
53078f79a6 新增桌面歌词是否延迟滚动设置 2022-01-16 20:00:22 +08:00
lyswhut
dbb7f0c683 更新版本号 2022-01-16 13:54:54 +08:00
lyswhut
cb7703ecbb 修复从网页打开歌单时无法收藏的问题 2022-01-16 13:54:07 +08:00
lyswhut
e63d7174bb 加深颜色 2022-01-16 11:34:07 +08:00
lyswhut
31ab7a0493 更新文档 2022-01-15 16:28:21 +08:00
lyswhut
c503f09529 新增“便携”功能 2022-01-15 16:28:16 +08:00
lyswhut
f5bb9189af 修复播放状态的提示问题 2022-01-14 17:24:38 +08:00
lyswhut
9ed8ba80c4 更新依赖 2022-01-14 13:34:29 +08:00
lyswhut
f9cce82a93 更新依赖 2022-01-14 11:19:26 +08:00
lyswhut
79d418d1a1 修复依赖 2022-01-13 08:39:48 +08:00
lyswhut
15d7f73aca 更新依赖 2022-01-12 22:59:51 +08:00
lyswhut
4561870ece 修复构建 2022-01-12 18:01:40 +08:00
lyswhut
dbc8c9d07d 更新依赖 2022-01-12 17:16:21 +08:00
lyswhut
d81a2029ec 更新版本号 2022-01-12 16:55:51 +08:00
lyswhut
d04a5a2f92 更新依赖 2022-01-12 16:52:12 +08:00
lyswhut
5146f083ff 新增打开主窗口开发者工具快捷键 2022-01-11 16:58:33 +08:00
lyswhut
57122c6eea 优化代码 2022-01-11 15:40:06 +08:00
lyswhut
ca748906c0 修复从Scheme URL启动软件打开歌单详情时会加载两次的问题 2022-01-11 15:25:35 +08:00
lyswhut
4d31bde98a 更新版本号 2022-01-08 01:36:31 +08:00
lyswhut
3f98c332bd 修复问题 2022-01-08 01:25:05 +08:00
lyswhut
fb3eced1fb 添加类型 2022-01-07 23:02:01 +08:00
lyswhut
9641ea0b3a 修复url长度校验 2022-01-07 23:01:50 +08:00
lyswhut
1df05a5529 修复文档显示问题 2022-01-07 17:59:40 +08:00
lyswhut
a393bb02dd 新增 Scheme URL 支持 2022-01-07 17:23:48 +08:00
lyswhut
20518cbe2b 更新依赖 2022-01-07 09:42:02 +08:00
lyswhut
9447034deb 修复稍后播放问题 2022-01-06 18:27:30 +08:00
lyswhut
c7f0fcbe9f 调整音频可视化参数 2022-01-05 15:51:49 +08:00
lyswhut
fce8719432 优化程序初始化逻辑,修复无网络的情况下的初始化问题 2022-01-05 11:50:13 +08:00
lyswhut
ce383769da 更新版本号 2022-01-05 11:18:14 +08:00
lyswhut
342af62aea 修复openDevTools选项无效的问题 2022-01-05 11:17:29 +08:00
lyswhut
b3ab05cc86 新增启动参数-proxy-server-proxy-bypass-list 2022-01-04 15:27:25 +08:00
lyswhut
36966e220c 修复代理不生效的问题 2022-01-04 15:27:20 +08:00
lyswhut
8ae3347c05 减淡新年主题搜索框底色 2022-01-04 10:13:41 +08:00
lyswhut
4f51a8ce31 优化频谱、修改频谱均值加成 2022-01-04 09:41:18 +08:00
lyswhut
1371bbe6fb 为可视化音频的频谱整体添加频谱均值加成,使频谱显示更有节奏感 2022-01-03 16:36:08 +08:00
lyswhut
94f4c9e334 修复播放列表为空时点击播放按钮会报错的问题 2022-01-01 16:26:17 +08:00
lyswhut
c5c89f9d9e Merge branch 'dev' 2022-01-01 15:28:19 +08:00
lyswhut
6a79f8ec0d 发布v1.16.0 2022-01-01 15:27:52 +08:00
lyswhut
aa940ef9f7 更新依赖 2022-01-01 15:06:46 +08:00
lyswhut
7a20f06cf4 修复界面切换问题 2022-01-01 15:06:17 +08:00
lyswhut
b9596f2a6e 更新新年皮肤 2022-01-01 14:37:40 +08:00
lyswhut
bb2dfc269c 修正错别字 2021-12-31 19:29:58 +08:00
lyswhut
684af4e7db 调整添加按钮宽度 2021-12-31 11:55:55 +08:00
lyswhut
1c946ac661 添加帮助图标 2021-12-31 11:48:11 +08:00
lyswhut
f8d06d38ab 修改右边位置时的控制按钮为windows风格 2021-12-31 10:07:05 +08:00
lyswhut
2a679c914b 降级node 2021-12-30 19:12:58 +08:00
lyswhut
3f8d5ed570 更新版本号 2021-12-27 18:14:58 +08:00
lyswhut
028c2f9f03 我的列表新增拖动调整位置功能 2021-12-27 18:14:43 +08:00
lyswhut
b783c0c227 修复列表无法重命名的问题 2021-12-27 15:57:02 +08:00
lyswhut
30787a372e 禁用拼写检查 2021-12-27 11:19:11 +08:00
lyswhut
b99169cc3b 更新说明 2021-12-25 22:56:59 +08:00
lyswhut
78cf146a92 修复潜在歌词滚动问题 2021-12-25 15:42:32 +08:00
lyswhut
b867167b78 优化 2021-12-24 19:31:50 +08:00
lyswhut
d8dfbf6995 更新版本号 2021-12-24 17:40:16 +08:00
lyswhut
c2d6737796 播放详情页新增音频可视化功能 2021-12-24 17:39:50 +08:00
lyswhut
dcfe055461 更新依赖 2021-12-24 11:40:31 +08:00
lyswhut
c86b1c259c 为播放详情页、桌面歌词添加延迟滚动,播放详情页略微减小已激活歌词的缩放大小及桌面歌词翻译大小 2021-12-24 11:06:00 +08:00
lyswhut
400c16ba2d 更新版本号 2021-12-23 17:49:37 +08:00
lyswhut
3ff0dbb7ef 优化歌单、排行榜一键播放按钮的播放机制 2021-12-23 15:28:01 +08:00
lyswhut
469a88f368 优化歌词滚动 2021-12-23 11:31:38 +08:00
lyswhut
217ff27e72 优化列表滚动性能 2021-12-23 10:37:51 +08:00
lyswhut
e337f7121b 为导出CSV文件头部自动应用相应翻译 2021-12-19 19:41:51 +08:00
lyswhut
665ac5ee99 更新版本号 2021-12-19 19:09:09 +08:00
lyswhut
f06c493458 调整评论组件位置 2021-12-19 18:23:42 +08:00
lyswhut
f383e47344 修复播放栏的歌曲添加按钮打开的添加窗口不会自动关闭的问题 2021-12-19 18:23:21 +08:00
lyswhut
e15518cd51 为CSV格式添加头部 2021-12-18 13:06:26 +08:00
lyswhut
27ce62dd4f 修复列表顺序同步问题 2021-12-18 13:03:26 +08:00
lyswhut
26202d8e56 更新版本号 2021-12-17 17:46:28 +08:00
lyswhut
d93b5a3374 支持对移动端的位置同步调整 2021-12-17 17:36:10 +08:00
lyswhut
e3acb7ce4e 同步功能添加对列表顺序调整的控制 2021-12-17 17:18:56 +08:00
lyswhut
5b7c965c48 更新依赖 2021-12-17 14:51:58 +08:00
lyswhut
5f1e670dd7 更新win图标 2021-12-16 17:29:58 +08:00
lyswhut
ab1562ea33 添加一个获取歌曲URL超时的定时器 2021-12-15 09:00:55 +08:00
lyswhut
2359a1444b 修复最小化托盘设置不起作用的问题 2021-12-14 23:00:20 +08:00
lyswhut
9075b6629f 整理事件代码 2021-12-14 20:24:11 +08:00
lyswhut
583e8c43d6 移除多余代码 2021-12-14 20:02:39 +08:00
lyswhut
26369dd14b 更新版本号 2021-12-14 17:47:27 +08:00
lyswhut
9d40e7c004 修复热搜词获取问题 2021-12-13 15:57:45 +08:00
lyswhut
267535844e 更新依赖 2021-12-13 14:10:32 +08:00
lyswhut
0f5d2189e0 修复无法关闭状态栏歌曲进度的问题 2021-12-13 14:07:26 +08:00
lyswhut
f76f4d9d29 修复保存歌曲进度设置问题 2021-12-13 13:12:50 +08:00
lyswhut
2ba5e40012 移除多余代码 2021-12-12 21:48:36 +08:00
lyswhut
1fe6ae4556 修复某些情况下切歌会导致错误的状态提示内容 2021-12-12 20:14:10 +08:00
lyswhut
3d8a1894f6 还原linux平台下的图标更改 2021-12-11 17:14:07 +08:00
lyswhut
70cfce833c 更新版本号 2021-12-11 16:24:27 +08:00
lyswhut
96c3034a07 修复调整当前播放歌曲的位置时会导致切歌的问题 2021-12-11 16:24:00 +08:00
lyswhut
5aad81c696 修复刚从线列表的歌曲无法批量添加、添加到我的列表后无法调整顺序等问题 2021-12-11 15:54:08 +08:00
lyswhut
b0e2f44f01 修复歌曲搜索多选不准确的问题 2021-12-11 15:32:56 +08:00
lyswhut
442e633800 修复无法移动歌曲的问题 2021-12-11 14:46:27 +08:00
lyswhut
5f1e788a25 调整linux、Mac平台下的图标大小 2021-12-11 13:50:05 +08:00
lyswhut
3808e7e78f 修改图标大小 2021-12-10 21:02:17 +08:00
lyswhut
650edc1b1e 修复歌曲排序描述 2021-12-10 20:28:04 +08:00
lyswhut
cb5e1bd795 更新依赖 2021-12-10 14:21:09 +08:00
lyswhut
3282557769 修复无法批量稍后播放的问题 2021-12-10 08:37:26 +08:00
lyswhut
dff18b6b9d 修复潜在报错 2021-12-09 17:51:51 +08:00
lyswhut
2a64ead1c4 添加加载超时时尝试刷新URL 2021-12-08 17:51:06 +08:00
lyswhut
eb0a61d35b 添加图片加载失败的处理 2021-12-08 17:18:37 +08:00
lyswhut
ddca70980e 修改托盘图标顺序 2021-12-07 17:48:01 +08:00
lyswhut
5aa3502ef5 调整黑色主题翻页器背景颜色 2021-12-07 15:07:23 +08:00
lyswhut
3b02703805 添加vue devtools 2021-12-07 11:32:19 +08:00
lyswhut
f39d13c8f8 更新版本号 2021-12-06 18:58:02 +08:00
lyswhut
16a203227a 修复问题 2021-12-06 18:56:56 +08:00
lyswhut
b350f133b0 新增将播放与下载的歌词转换为繁体中文选项 2021-12-06 16:07:12 +08:00
lyswhut
ec3a0e08c3 新增根据歌曲名、歌手名等字段对列表自动排序的功能 2021-12-06 15:33:36 +08:00
lyswhut
a96eea5e44 修复切换切歌模式切换时提示实时不更新的问题 2021-12-05 23:17:27 +08:00
lyswhut
0dc7815e35 新增将我的列表保存为TXT、CSV格式 2021-12-05 21:36:46 +08:00
lyswhut
7f6e1c25e9 修复列表搜索不能用键盘选择的问题 2021-12-05 19:16:33 +08:00
lyswhut
9291c35b00 修复某些歌曲评论的时间显示 2021-12-05 18:58:30 +08:00
lyswhut
90b67fc05c 优化快捷键设置 2021-12-04 20:32:22 +08:00
lyswhut
09afd2c6f8 修复列表高度计算问题 2021-12-04 19:10:04 +08:00
lyswhut
1def571191 添加源显示 2021-12-04 18:09:21 +08:00
lyswhut
ef52f2465e 优化 2021-12-04 17:32:02 +08:00
lyswhut
845e5de43f 移除日志 2021-12-04 17:28:55 +08:00
lyswhut
b7433264eb 更新版本号 2021-12-04 17:26:36 +08:00
lyswhut
60e606a413 修复问题 2021-12-04 17:25:21 +08:00
lyswhut
9afafec9d6 修复列表问题 2021-12-04 02:25:55 +08:00
lyswhut
c9cb84a28d 修复导入 2021-12-04 02:15:08 +08:00
lyswhut
8949383ade 修复列表操作问题 2021-12-04 01:55:36 +08:00
lyswhut
f732ea4dab 关闭devtools 2021-12-04 01:45:28 +08:00
lyswhut
162842415f 移除日志 2021-12-04 01:44:20 +08:00
lyswhut
07d200a752 修复同步问题 2021-12-04 01:30:34 +08:00
lyswhut
822e1ea6c9 修复搜索问题 2021-12-04 00:27:13 +08:00
lyswhut
f79ae1541d 修复批量下载 2021-12-04 00:00:19 +08:00
lyswhut
2dfa93383f 修复kw源某些歌曲的歌词提取异常的问题 2021-12-03 23:46:41 +08:00
lyswhut
1ab5db8507 添加vue eslint规则,修复问题 2021-12-03 23:45:03 +08:00
lyswhut
ccd951b5d3 修复 2021-12-03 22:27:36 +08:00
lyswhut
6259690d12 更新依赖 2021-12-03 22:12:42 +08:00
lyswhut
8059d9cd73 升级到 vue3 2021-12-03 22:11:11 +08:00
lyswhut
c6635e554a 更新依赖 2021-12-03 21:49:49 +08:00
lyswhut
d7ca662e70 更新说明 2021-11-29 10:45:55 +08:00
lyswhut
b6f885b250 优化歌词自动换源机制 2021-11-28 01:54:45 +08:00
lyswhut
63141c4ac9 优化进度条逻辑 2021-11-28 00:15:51 +08:00
lyswhut
94e9f01e62 Merge branch 'dev' 2021-11-21 12:13:30 +08:00
lyswhut
cffa74b1c2 发布v1.15.3 2021-11-21 12:12:00 +08:00
lyswhut
1fb917941e 更新依赖 2021-11-21 12:10:45 +08:00
lyswhut
08c6a4e2fb 修复列表切换问题 2021-11-19 22:15:58 +08:00
lyswhut
976be6d96f 修复因kw源歌词接口停用导致该源歌词获取失败的问题 2021-11-18 14:51:00 +08:00
lyswhut
fe95b45820 更新依赖 2021-11-13 23:29:18 +08:00
lyswhut
47dffeee76 修复潜在的音乐加载超时不会切歌的问题 2021-11-13 23:29:09 +08:00
lyswhut
be7b06f5c8 修复播放下载列表时存在失效的歌曲会导致切歌不准确的问题 2021-11-13 23:29:00 +08:00
lyswhut
3a371f8d75 修复设置-控制按钮位置选项与下载歌词编码格式选项命名冲突导致选项显示异常的问题 2021-11-13 23:04:27 +08:00
lyswhut
fa97058895 优化字典#682 2021-11-13 21:57:01 +08:00
lyswhut
df9289367b 修改文案 2021-11-09 20:07:29 +08:00
lyswhut
3a824b1d5e 更新模板 2021-11-09 20:03:03 +08:00
lyswhut
6f72da87b1 Merge branch 'dev' of github.com:lyswhut/lx-music-desktop into dev 2021-11-09 19:34:55 +08:00
lyswhut
1b1c5ad6da Merge branch 'dev' 2021-11-09 18:37:40 +08:00
lyswhut
f4777f787c 发布v1.15.2 2021-11-09 18:37:19 +08:00
lyswhut
6bcf45fba7 降级electron到v13.4.0 2021-11-09 18:35:17 +08:00
lyswhut
1e8a05e313 更新问题模板 2021-11-09 16:54:55 +08:00
lyswhut
1cf0f2dd0b Merge branch 'dev' 2021-11-09 09:25:40 +08:00
lyswhut
25a0439928 发布v1.15.1 2021-11-09 09:25:13 +08:00
lyswhut
df20e97d60 添加媒体播放进度条的信息设置 2021-11-09 09:17:21 +08:00
lyswhut
fd764a28a4 更新electron到v15.3.1 2021-11-09 08:52:00 +08:00
lyswhut
81bd8fbb74 支持启动软件时恢复播放下载列表里的歌曲 2021-11-06 16:15:29 +08:00
lyswhut
47ee572640 更新依赖 2021-11-06 14:26:33 +08:00
lyswhut
a0b9553158 优化播放详情页的打开 2021-11-06 14:26:16 +08:00
lyswhut
7659a6cadf 更新说明 2021-11-03 16:30:31 +08:00
lyswhut
a65bae8243 移除过时的选项 2021-11-03 16:30:22 +08:00
lyswhut
421abac30a 更新依赖 2021-11-03 16:29:58 +08:00
lyswhut
0b11e97427 添加列表歌手、专辑的提示气泡 2021-11-03 16:27:13 +08:00
lyswhut
fbe1ff73f1 修复下载列表无法切下一首歌的问题 2021-11-03 16:26:43 +08:00
lyswhut
68e831468b 修复潜在播放详情页问题 2021-11-01 09:21:54 +08:00
lyswhut
e382f0dba0 优化下载功能的添加、删除、暂停任务时的流畅度 2021-10-31 21:50:57 +08:00
lyswhut
f0f92952d6 优化我的列表、下载列表等列表的滚动流畅度 2021-10-30 12:16:58 +08:00
lyswhut
58f016ca00 修复潜在同步问题 2021-10-30 10:07:08 +08:00
lyswhut
faff0edb4a 更新 2021-10-29 21:16:30 +08:00
lyswhut
5e9a9e5b55 移除多余代码 2021-10-29 20:29:28 +08:00
lyswhut
e182dde718 修复了某些情况下会列表同步失败,导致连接断开无限重连的问题 2021-10-29 20:09:43 +08:00
lyswhut
7dfc2e8736 修复列表数据过大导致同步失败的问题 2021-10-29 20:09:37 +08:00
lyswhut
b27a547fb8 修复某些情况下获取URL失败时会意外切歌的问题 2021-10-29 20:05:11 +08:00
lyswhut
379c752cf8 Merge branch 'dev' 2021-10-29 15:15:03 +08:00
lyswhut
35abdc63d4 降级 electron-builder 2021-10-29 15:14:41 +08:00
lyswhut
a386915b50 Merge branch 'dev' 2021-10-29 14:23:27 +08:00
lyswhut
ab16bc849d 发布v1.15.0 2021-10-29 14:23:03 +08:00
lyswhut
90007127ba 更新依赖 2021-10-29 14:21:04 +08:00
lyswhut
a1935cbdac 修复列表项高度随窗口的大小适配问题 2021-10-29 14:20:51 +08:00
lyswhut
7de91bd923 更新图标 2021-10-28 09:56:23 +08:00
lyswhut
cdbcae21ac 添加黑色托盘图标 2021-10-27 17:11:35 +08:00
lyswhut
ea62033cf3 修改图标 2021-10-27 16:21:41 +08:00
lyswhut
a48423944a 修复缺失的包问题 2021-10-27 14:22:02 +08:00
lyswhut
b7fb3cd208 调整图标尺寸 2021-10-27 14:21:32 +08:00
lyswhut
34825b5063 兼容桌面歌词以触摸的方式移动、调整大小 2021-10-26 15:51:48 +08:00
lyswhut
7737012103 更新依赖 2021-10-26 15:33:14 +08:00
lyswhut
3912a375c5 更新版本号 2021-10-26 14:44:35 +08:00
lyswhut
35ca6db1ee 优化我的列表、下载、歌单、排行榜列表性能 2021-10-26 14:44:15 +08:00
lyswhut
0d20869337 优化进入、离开播放详情页的性能 2021-10-26 10:30:01 +08:00
lyswhut
89d161268e 更新说明 2021-10-23 20:12:49 +08:00
lyswhut
5ae39ef8d3 更新依赖 2021-10-21 14:57:34 +08:00
lyswhut
e57696d4ff 优化开关评论时的动画性能 2021-10-17 13:49:35 +08:00
lyswhut
15c9a5468b 更新依赖 2021-10-15 20:08:46 +08:00
lyswhut
30318b7c61 更新版本号 2021-10-15 19:56:01 +08:00
lyswhut
8b0fc9bf5f 更新 Electron 到 v15.2.0 2021-10-15 19:54:48 +08:00
lyswhut
5fdba7720c 添加弹窗 2021-10-14 08:54:33 +08:00
lyswhut
ca12dc604d 完善评论 2021-10-13 12:00:02 +08:00
lyswhut
09f4d8ac0c 修复同一首歌的URL、歌词等同时需要换源时的处理问题 2021-10-09 10:21:34 +08:00
lyswhut
254b82cc60 修复kg源的歌单链接无法打开的问题 2021-10-07 20:01:19 +08:00
lyswhut
d4240006f1 自定义源新增version字段,新增utils.buffer.bufToString方法 2021-10-07 12:28:03 +08:00
lyswhut
68518e609d 增加自定义脚本名字长度 2021-10-07 10:22:30 +08:00
lyswhut
001eba6729 优化列表同步代码逻辑 2021-10-06 13:37:23 +08:00
lyswhut
ff47a224c7 Merge branch 'dev' 2021-10-04 12:28:08 +08:00
lyswhut
8810e25ea9 发布v1.14.1 2021-10-04 12:22:52 +08:00
lyswhut
eb67d67a60 修复v1.14.0出现的备份与恢复功能备份的数据无法恢复的问题 2021-10-04 12:22:16 +08:00
lyswhut
e12f95ff74 更新版本号 2021-10-03 11:00:20 +08:00
lyswhut
2fe213d060 修复我的列表搜索输入某些字符会导致应用崩溃的问题 2021-10-03 10:55:09 +08:00
lyswhut
b726ee42f7 Merge branch 'dev' 2021-10-02 13:43:46 +08:00
lyswhut
6b71b4709e 发布v1.14.0 2021-10-02 13:43:19 +08:00
lyswhut
0701b78720 优化英文歌曲名匹配 2021-10-01 22:47:55 +08:00
lyswhut
82d1ac1e83 更新依赖 2021-10-01 22:18:50 +08:00
lyswhut
8acf98631f 更新版本号 2021-10-01 22:16:08 +08:00
lyswhut
0a31d19561 新增重复歌曲列表 2021-10-01 22:15:45 +08:00
lyswhut
91279922f1 新增歌词文本选择复制功能 2021-10-01 12:30:07 +08:00
lyswhut
96804ae2e2 更新版本号 2021-09-30 16:45:20 +08:00
lyswhut
3ae8a89961 更新依赖 2021-09-30 16:44:32 +08:00
lyswhut
f8f13fd32c 优化歌词处理 2021-09-30 14:56:35 +08:00
lyswhut
ae61d2c629 调整位置 2021-09-30 14:56:24 +08:00
lyswhut
b1918e8b15 新增删除列表前的确认弹窗 2021-09-30 14:45:14 +08:00
lyswhut
ce7bca5b36 新增单个列表导入/导出功能 2021-09-30 14:27:32 +08:00
lyswhut
51be62bc29 更新依赖 2021-09-30 08:52:14 +08:00
Unintended
c1ff3971de Typo (#643) 2021-09-25 11:16:56 +08:00
Wei Yijun
57db286405 修复GNOME等桌面下每次打开应用时需重新设置歌词窗口置顶的问题 (#636) 2021-09-22 10:33:48 +08:00
lyswhut
592b670e96 更新版本号 2021-09-18 17:31:21 +08:00
lyswhut
97fdcaac51 新增歌词简体中文转繁体中文,当软件语言被设置为繁体中文后,播放歌曲的歌词也将自动转成繁体中文显示 2021-09-18 17:30:46 +08:00
lyswhut
271d9ac13e 更新依赖 2021-09-15 17:08:38 +08:00
lyswhut
b6cea110a7 修复在有提示信息的地方长按鼠标按键时提示信息会闪烁的问题 2021-09-11 15:39:02 +08:00
lyswhut
4b5dae4779 修复点击播放详情页的进度条跳进度时会出现偏移的问题 2021-09-10 14:31:07 +08:00
lyswhut
a250317a28 修复mg排行榜无法加载的问题 2021-09-09 16:45:10 +08:00
lyswhut
431605e793 Merge branch 'dev' of github.com:lyswhut/lx-music-desktop into dev 2021-09-07 22:20:06 +08:00
lyswhut
a4d3c06119 Merge branch 'dev' 2021-09-05 12:16:56 +08:00
lyswhut
246412cb2c 发布v1.13.0 2021-09-05 12:14:17 +08:00
lyswhut
2fb013fb41 修正排版 2021-09-05 12:13:44 +08:00
lyswhut
6f9d684b2d 复从电脑浏览器复制的企鹅歌单链接无法打开的问题 2021-09-05 12:13:32 +08:00
lyswhut
af6a2ec581 更新依赖 2021-09-04 21:24:42 +08:00
lyswhut
488b28921f 添加“Windows 7 下桌面歌词字体列表为空”问题解答 2021-08-29 21:31:44 +08:00
lyswhut
4c23fc1011 移除eiows包 2021-08-29 18:32:03 +08:00
lyswhut
db1c903f1b 更新版本号 2021-08-29 18:27:38 +08:00
lyswhut
3fdf7411fc 新增桌面歌词字体设置 2021-08-29 18:27:01 +08:00
lyswhut
1da275ff3a 更新依赖 2021-08-28 13:25:34 +08:00
lyswhut
bc5167f38d 使用中文括号 2021-08-26 16:21:26 +08:00
lyswhut
609b6f3123 更新版本号 2021-08-26 16:00:43 +08:00
lyswhut
fe35081e03 新增“下载的歌词文件编码格式”设置 2021-08-26 16:00:03 +08:00
lyswhut
72df1a35a0 更新推荐的DNS值 2021-08-26 08:54:58 +08:00
lyswhut
90ffcf5071 更新依赖 2021-08-25 16:29:11 +08:00
lyswhut
35f60cc536 添加说明 2021-08-24 08:46:42 +08:00
lyswhut
31bb40c50b 更新版本号 2021-08-23 11:25:53 +08:00
lyswhut
bc7b35f816 修复无法从歌单界面打开网易歌单详情的问题 2021-08-23 11:23:42 +08:00
lyswhut
0c76612a4c 更新版本号 2021-08-22 13:10:28 +08:00
lyswhut
ab86674aa3 软件内快捷键的最小化触发时,如果已启用托盘,则隐藏程序,否则最小化程序 2021-08-22 10:26:59 +08:00
lyswhut
8cd5a01dd5 更新依赖 2021-08-20 21:59:16 +08:00
lyswhut
4ef5bafcca 更新依赖 2021-08-20 21:56:15 +08:00
lyswhut
2c783e0657 修复错误 2021-08-20 11:15:51 +08:00
lyswhut
0c7ead5b21 Merge branch 'dev' of github.com:lyswhut/lx-music-desktop into dev 2021-08-19 19:27:42 +08:00
lyswhut
57a8b7842e 修复某些情况下列表同步不一致的问题 2021-08-19 15:23:29 +08:00
lyswhut
4b5a7b6a74 添加测试群 2021-08-18 17:04:38 +08:00
lyswhut
c09c31767d 更新依赖 2021-08-18 16:10:13 +08:00
lyswhut
ecff04618b 支持网易源“我喜欢”歌单以注入token的方式打开 2021-08-18 14:03:00 +08:00
lyswhut
c377469dad 歌曲搜索框新增清理按钮 2021-08-16 15:46:43 +08:00
lyswhut
ecb41382cb 更新常见问题 2021-08-16 09:10:23 +08:00
lyswhut
3150b12b99 修复重名问题 2021-08-15 19:45:11 +08:00
lyswhut
364260b070 修复某些情况下同步功能会导致切歌混乱的问题 2021-08-12 10:40:45 +08:00
lyswhut
5ccf6f077d Merge branch 'dev' 2021-08-11 17:07:02 +08:00
lyswhut
5b113c5c22 发布v1.12.2 2021-08-11 17:06:18 +08:00
lyswhut
ff53900ea3 修复同步服务器启动失败时,关闭同步服务不会清空失败信息的问题 2021-08-11 16:39:33 +08:00
lyswhut
b0b0403d9a 移除多余内容 2021-08-11 15:23:20 +08:00
lyswhut
21c3b3ab57 修复上一曲切换问题 2021-08-11 13:28:51 +08:00
lyswhut
e85709a341 修复稍后播放切歌问题 2021-08-11 11:57:41 +08:00
lyswhut
04be42a4d6 添加规则 2021-08-11 10:22:15 +08:00
lyswhut
8196e8a84d 更新依赖 2021-08-11 10:00:04 +08:00
lyswhut
1f85492690 修复播放下载列表的歌曲时切歌、歌词显示问题 2021-08-11 09:59:47 +08:00
lyswhut
e15178150b 移除日志 2021-08-08 12:16:22 +08:00
lyswhut
d83aee2507 Merge branch 'dev' 2021-08-08 11:54:46 +08:00
lyswhut
354a9904e9 发布v1.12.1 2021-08-08 11:54:21 +08:00
lyswhut
fe3379ffbb 修复随机播放下无法切歌的问题 2021-08-08 11:54:13 +08:00
lyswhut
0164936038 Merge branch 'dev' 2021-08-08 10:29:09 +08:00
lyswhut
9106d6455f 发布v1.12.0 2021-08-08 10:28:43 +08:00
lyswhut
5ddea2b1da 修复图片为空时设置歌曲信息出错的问题 2021-08-07 19:35:13 +08:00
lyswhut
2549c5587e 更新依赖 2021-08-07 13:45:44 +08:00
lyswhut
c9f28d8105 更新依赖 2021-08-05 10:39:59 +08:00
lyswhut
75b2db4749 添加播放器对系统媒体控制与显示的兼容处理 2021-08-05 10:21:20 +08:00
lyswhut
b6f291d721 添加提示语 2021-08-02 14:32:45 +08:00
lyswhut
4f7e227392 移除日志输出 2021-08-01 20:12:38 +08:00
lyswhut
7d95eb34c7 修复同步服务启动失败刷新连接码按钮仍然可以点击的问题 2021-08-01 20:11:38 +08:00
lyswhut
7e3ee38920 修复删除列表中正在播放的歌曲时不会自动切歌的问题 2021-08-01 20:07:40 +08:00
lyswhut
d44c2c26a8 修复beta版MAC包构建失败的问题 2021-08-01 13:46:16 +08:00
lyswhut
d77a41c20f 更新版本 2021-08-01 13:35:58 +08:00
lyswhut
c50c747691 完善代码 2021-08-01 13:28:12 +08:00
lyswhut
bcf3dde60d 完成同步功能 2021-08-01 12:57:13 +08:00
lyswhut
33ec3de1b4 更新依赖 2021-08-01 12:46:17 +08:00
lyswhut
26be5b5c4f 移除多余依赖 2021-07-23 22:01:34 +08:00
lyswhut
56af57c682 修复某些情况下所显示的歌词、封面图片与当前正在播放的歌曲不一致的问题 2021-07-23 16:14:56 +08:00
lyswhut
3a5cb3f7c2 修复导入kg歌单最多只能加载100、500首歌曲的问题 2021-07-21 15:33:41 +08:00
lyswhut
724c6be85b 禁用win arm版本的自动下载更新 2021-07-18 14:56:18 +08:00
lyswhut
1c4a56f95b Merge branch 'dev' 2021-07-18 13:59:58 +08:00
lyswhut
9c21e96538 发布v1.11.0 2021-07-18 13:56:26 +08:00
lyswhut
67074bd682 更新依赖 2021-07-17 16:40:52 +08:00
lyswhut
b535987392 更新依赖 2021-07-14 14:27:59 +08:00
lyswhut
d5c0c2e3d3 更新依赖 2021-07-10 12:26:14 +08:00
lyswhut
7580c79c00 替换过时API 2021-07-07 15:02:46 +08:00
lyswhut
c0a13622b0 更新依赖 2021-07-06 16:51:18 +08:00
lyswhut
58d7326f77 优化mg源打开歌单的链接兼容 2021-07-06 16:51:13 +08:00
lyswhut
45d7a12d0d 更新依赖 2021-07-05 10:08:44 +08:00
lyswhut
40b4f15340 更新说明 2021-07-02 14:58:14 +08:00
lyswhut
9c28ff67c1 更新 2021-07-02 10:28:32 +08:00
lyswhut
e3f146dabf 移除wy源歌单列表按“最新”排序的按钮 2021-06-30 11:55:32 +08:00
lyswhut
2b2a6a7f10 更新依赖 2021-06-30 11:44:51 +08:00
lyswhut
192574dfe8 更新依赖 2021-06-27 14:47:19 +08:00
lyswhut
8e95e06b2d 添加网易歌单无法打开的说明 2021-06-24 14:50:04 +08:00
lyswhut
1963b3ee71 修复mg源搜索失效的问题 2021-06-19 13:26:58 +08:00
lyswhut
507f66b3b6 修复dns查询问题 2021-06-18 15:13:15 +08:00
lyswhut
94bf9eae8b 更新依赖 2021-06-17 15:38:03 +08:00
lyswhut
0fa32f976c 移除日志输出 2021-06-16 16:24:39 +08:00
lyswhut
198238d4b5 优化网络请求,尝试去解决无法连接服务器的问题 2021-06-16 10:23:48 +08:00
lyswhut
66631ac105 修复进度条高度问题 2021-06-14 13:52:46 +08:00
lyswhut
19c5996351 更新依赖 2021-06-11 16:25:36 +08:00
lyswhut
cd3140a9c7 新增“添加歌曲到列表时的位置”设置 2021-06-11 15:45:09 +08:00
lyswhut
56201d6a01 更新依赖 2021-06-10 18:10:52 +08:00
lyswhut
654cb41e3e 添加 win arm64 架构的安装包构建 2021-06-07 09:04:34 +08:00
lyswhut
fa744d9204 添加i18n-ally扩展设置 2021-06-06 20:31:09 +08:00
lyswhut
3e1c56ff82 修复打包失败的问题 2021-06-05 12:18:43 +08:00
lyswhut
5d5164c4e9 更新依赖 2021-06-04 16:08:15 +08:00
lyswhut
0791e760a4 修复打开kw歌单失败时会无限重试的问题 2021-06-03 15:12:53 +08:00
lyswhut
b53fe2dd5e 优化wy源歌单导入匹配 2021-06-03 14:50:37 +08:00
lyswhut
1648b0c2dd 更新依赖 2021-05-31 17:12:53 +08:00
lyswhut
1a5adfabf4 更新依赖 2021-05-27 08:44:37 +08:00
lyswhut
c538e9c4fc Merge branch 'dev' 2021-05-25 16:19:49 +08:00
lyswhut
98422b296d 发布v1.10.2 2021-05-25 16:19:23 +08:00
lyswhut
e35068137d 修复企鹅音乐搜索歌曲没有结果的问题 2021-05-25 16:18:45 +08:00
lyswhut
83dda92603 Merge branch 'dev' 2021-05-25 15:42:13 +08:00
lyswhut
6bbcb519d7 发布v1.10.1 2021-05-25 15:40:57 +08:00
lyswhut
7fa3baacfd 更新依赖 2021-05-25 15:40:07 +08:00
lyswhut
f94c1ef852 不允许播放空列表 2021-05-24 11:03:21 +08:00
lyswhut
cc4cb1a6a7 修复企鹅音乐搜索歌曲没有结果的问题 2021-05-23 16:31:31 +08:00
lyswhut
247a322366 修复播放在空的歌单列表点击播放全部时报错的问题 2021-05-23 16:31:26 +08:00
lyswhut
7ec7023d1b Merge branch 'dev' 2021-05-20 08:28:13 +08:00
lyswhut
b4edd95bab 移除多余选项 2021-05-20 08:22:44 +08:00
lyswhut
50ddc8caa3 去除多余选项 2021-05-20 01:16:44 +08:00
lyswhut
6263dbbd0f Merge branch 'dev' 2021-05-20 00:14:56 +08:00
lyswhut
64c45daf16 修改安装包构建顺序,使latest.yml仍指向x86_64版本的包 2021-05-20 00:14:36 +08:00
lyswhut
5ed41cb5ac Merge branch 'dev' 2021-05-19 21:19:05 +08:00
lyswhut
29dea5f829 添加win x64与x86版本安装包的单独构建 2021-05-19 21:17:27 +08:00
lyswhut
e51b21421d Merge branch 'dev' 2021-05-19 18:28:10 +08:00
lyswhut
5cae4ae0bf 使用更新的node版本 2021-05-19 18:27:48 +08:00
lyswhut
5f2cbb30c2 Merge branch 'dev' 2021-05-19 18:21:49 +08:00
lyswhut
1ddec2cb69 发布v1.10.0 2021-05-19 18:21:16 +08:00
lyswhut
96b54cc77a 稍微加高进度条 2021-05-19 18:15:41 +08:00
lyswhut
4da6524493 修复了一个歌曲下载失败时不会跳过任务的问题 2021-05-19 18:15:04 +08:00
lyswhut
1364d58065 新增Mac arm64位dmg包的构建 2021-05-19 16:55:02 +08:00
lyswhut
4383966051 更新依赖 2021-05-19 11:15:36 +08:00
lyswhut
86451fb5d0 更新依赖 2021-05-17 16:47:09 +08:00
lyswhut
0878c7398d 排行榜界面添加播放、收藏整个排行榜功能 2021-05-17 15:43:47 +08:00
lyswhut
81643165c2 修复在线列表的请求取消问题 2021-05-16 22:46:46 +08:00
lyswhut
b37802949c 更新依赖 2021-05-16 14:12:11 +08:00
lyswhut
a53f2388b4 更新网盘地址 2021-05-16 14:09:03 +08:00
lyswhut
e823543cad 更新 2021-05-15 20:40:01 +08:00
lyswhut
bdf7f903e9 修复mg源歌单标签、排行榜歌曲列表无法加载的问题 2021-05-15 20:39:53 +08:00
lyswhut
336b40a102 修复wy源的歌曲音质匹配问题 2021-05-15 17:27:25 +08:00
lyswhut
354922195f 修复请求重试bug 2021-05-15 01:42:23 +08:00
lyswhut
9c1199fc48 更新FAQ 2021-05-12 17:20:38 +08:00
lyswhut
ea35ed25d8 修复kw部分歌单无法打开的问题 2021-05-12 14:04:08 +08:00
lyswhut
add05ef913 修复在当前正常播放的列表中使用稍后播放功能时,播放完后稍后播放的歌曲后不会恢复原来播放位置播放的问题 2021-05-10 16:35:34 +08:00
lyswhut
e3aa4110fc 更新依赖 2021-05-09 13:33:46 +08:00
lyswhut
8a0ed1bc13 更新说明 2021-05-03 12:41:03 +08:00
lyswhut
0db490d444 更新依赖 2021-04-30 21:22:50 +08:00
lyswhut
4fd89c8a83 修正错别字 2021-04-28 17:47:33 +08:00
lyswhut
4fe17e556e 修复快捷键设置框内的提示问题 2021-04-26 15:17:01 +08:00
lyswhut
e95553163c 修复全局快捷键对桌面歌词无效的问题 2021-04-26 14:13:11 +08:00
lyswhut
8ae72074ef 更新 2021-04-25 13:18:49 +08:00
lyswhut
b6c1403f4b 显示换源提示 2021-04-25 10:29:08 +08:00
lyswhut
920d696d0b 更新歌曲无法下载、播放说明 2021-04-24 17:22:45 +08:00
lyswhut
a8dcb0b973 优化逻辑 2021-04-24 17:22:28 +08:00
lyswhut
895198b7b8 修正描述 2021-04-24 16:10:22 +08:00
lyswhut
144941d991 Merge branch 'dev' 2021-04-24 15:55:49 +08:00
lyswhut
f203517ce8 发布1.9.0版本 2021-04-24 15:55:40 +08:00
lyswhut
6dd6741237 Merge branch 'dev' 2021-04-24 15:53:37 +08:00
lyswhut
066e9c2fd5 修复上传包名匹配 2021-04-24 15:38:02 +08:00
lyswhut
f500b9b2d5 优化beta打包流程 2021-04-24 15:13:10 +08:00
lyswhut
c80e35872e 修改打包名 2021-04-24 14:34:52 +08:00
lyswhut
05eda6e406 修复打包失败 2021-04-24 14:13:13 +08:00
lyswhut
1686182616 更新版本号 2021-04-24 13:50:34 +08:00
lyswhut
fd5720451e 更新依赖 2021-04-24 13:48:27 +08:00
lyswhut
5b9adc8daa 修复属性计算 2021-04-23 10:57:47 +08:00
lyswhut
3efd6867d8 新增自动换源下载功能 2021-04-22 16:01:47 +08:00
lyswhut
cd1a55652f 修复换源错误的处理 2021-04-18 15:06:21 +08:00
lyswhut
47d0a4a343 修复正在播放“稍后播放”的歌曲时,对“稍后播放”前播放的列表进行添加、删除操作会导致切歌的问题 2021-04-16 16:58:20 +08:00
lyswhut
fe76d103f0 更新依赖 2021-04-16 14:18:53 +08:00
lyswhut
789a9bfe1a 更新依赖 2021-04-15 09:21:35 +08:00
lyswhut
391f97d3bb 修复js加载顺序问题 2021-04-14 16:11:57 +08:00
lyswhut
d077a03e60 优化配色 2021-04-14 15:38:59 +08:00
lyswhut
3317b6a9e5 优化配色 2021-04-14 15:01:55 +08:00
lyswhut
0b0f0e4649 新增黑色皮肤“黑纸白字” 2021-04-14 14:46:57 +08:00
lyswhut
f75e416479 添加黑色皮肤 2021-04-14 13:33:36 +08:00
lyswhut
d83db6bdf5 Merge branch 'dev' into 黑色主题 2021-04-14 08:35:00 +08:00
lyswhut
92ec461a77 修正设置页“搜索设置”部分内容的缩进显示问题 2021-04-13 15:57:25 +08:00
lyswhut
144fe3b8ac 更新依赖 2021-04-10 20:43:20 +08:00
lyswhut
af2e650538 兼容打开咪咕移动端分享的歌单链接,添加打开歌单的信息显示 2021-04-06 15:39:16 +08:00
lyswhut
1c585dc479 分离歌曲URL的缓存 2021-04-05 19:31:07 +08:00
lyswhut
c6853b197c 修复列表清除Bug 2021-04-03 21:31:19 +08:00
lyswhut
ef591c883a 移除列表lrc存储 2021-04-03 21:17:27 +08:00
lyswhut
4918db9cb1 分离歌词与歌曲列表信息的保存 2021-04-03 20:26:28 +08:00
lyswhut
b8250b67c9 升级到 webpack 5 2021-04-03 13:58:10 +08:00
lyswhut
d6f87894aa 更新依赖 2021-04-03 13:12:11 +08:00
lyswhut
c808500083 新增Windows arm64位免安装版的构建 2021-03-31 08:54:47 +08:00
lyswhut
3a6c2be48a 更新依赖 2021-03-29 08:54:55 +08:00
lyswhut
a28d01704a 更新faq 2021-03-27 19:34:45 +08:00
lyswhut
8bed654756 修复聚合搜索总页计算问题 2021-03-24 11:06:18 +08:00
lyswhut
8845884b24 更新发布流程 2021-03-21 13:23:13 +08:00
lyswhut
ea5de9a289 优化歌曲自动换源匹配 2021-03-20 20:55:44 +08:00
lyswhut
7922920f51 修改默认每页条数 2021-03-20 20:19:04 +08:00
lyswhut
dcf6ab0792 清理列表缓存将同时清理歌词 2021-03-20 19:52:02 +08:00
lyswhut
57fe510138 更新网盘链接 2021-03-20 00:10:36 +08:00
lyswhut
b4c7a6e448 自动禁用空代理 2021-03-18 17:30:44 +08:00
lyswhut
1d8702e95f 添加路径提示支持 2021-03-16 11:01:57 +08:00
lyswhut
8171fcd346 序启动时对数据文件做读取校验,数据出现损坏时自动备份损坏的数据 2021-03-14 02:06:35 +08:00
lyswhut
b1ccdeb0d3 修正错误 2021-03-13 16:49:05 +08:00
lyswhut
969b03b364 略微减小翻译字体大小 2021-03-13 15:25:35 +08:00
lyswhut
5ed81132fb 优化错误处理 2021-03-13 14:35:20 +08:00
lyswhut
c663cdbe0d 分离store逻辑 2021-03-13 14:10:36 +08:00
lyswhut
a4d46fd501 修正描述 2021-03-12 22:49:27 +08:00
lyswhut
c3e1ead90a Merge branch 'dhmkh' into dev 2021-03-12 22:42:17 +08:00
lyswhut
92c10eb534 修改协议阅读时间 2021-03-12 16:30:27 +08:00
lyswhut
08d0758616 修复备份与恢复功能在恢复数据时某些设置不立即生效的问题 2021-03-12 16:22:22 +08:00
lyswhut
68d8369a8b 修正单词拼写错误 2021-03-12 09:02:40 +08:00
lyswhut
af59a4472a 调整翻译字体大小 2021-03-11 17:34:29 +08:00
lyswhut
269546add1 Merge branch 'dev' 2021-03-10 10:23:50 +08:00
lyswhut
65246f8856 修正beta打包规则 2021-03-10 10:22:19 +08:00
lyswhut
ab35fe793d Merge branch 'dev' 2021-03-10 10:20:34 +08:00
lyswhut
e7b897e67c 优化打包命令 2021-03-10 10:19:49 +08:00
lyswhut
0b5dbb464d Merge branch 'dev' 2021-03-10 09:36:04 +08:00
lyswhut
60419f4319 修正徽章地址 2021-03-10 09:35:48 +08:00
lyswhut
1ddf0db18d 重命名beta打包工作流文件名 2021-03-10 09:34:43 +08:00
lyswhut
0732ca37b8 优化打包规则 2021-03-10 09:33:04 +08:00
lyswhut
801ea899e6 迁移到GitHub Actions 2021-03-10 09:21:43 +08:00
lyswhut
ba5159d2ad 修复Linux构建错误 2021-03-10 01:39:08 +08:00
lyswhut
ab2cf5a50f 修正错误,添加dev构建 2021-03-10 01:34:58 +08:00
lyswhut
d533c12315 修复Linux配置 2021-03-10 01:24:28 +08:00
lyswhut
1d90719053 Merge branch 'dev' 2021-03-10 01:18:49 +08:00
lyswhut
127d279266 修正语法错误 2021-03-10 01:15:30 +08:00
lyswhut
a484f66e69 修正语法错误 2021-03-10 01:02:30 +08:00
lyswhut
b34924e264 Merge branch 'dev' 2021-03-10 00:59:36 +08:00
lyswhut
4d5494c256 更新文件夹名 2021-03-10 00:59:06 +08:00
lyswhut
46b094a57a Merge branch 'dev' 2021-03-10 00:51:44 +08:00
lyswhut
0ef89c30e3 更新更新日志 2021-03-10 00:50:55 +08:00
lyswhut
dc2a89ce3f Merge branch 'dev' 2021-03-10 00:47:42 +08:00
lyswhut
47adcfec30 添加缓存 2021-03-10 00:42:27 +08:00
lyswhut
25e848702f 更新依赖 2021-03-10 00:42:15 +08:00
lyswhut
756a285978 修复收藏的在线列表id迁移保存出错的问题 2021-03-10 00:41:38 +08:00
lyswhut
fcf79bda03 Merge branch 'dev' 2021-03-09 22:55:20 +08:00
lyswhut
6b170f3116 尝试迁移到GitHub Actions 2021-03-09 22:50:08 +08:00
lyswhut
ea6bc245ff Merge branch 'dev' 2021-03-09 20:50:50 +08:00
lyswhut
61dc344d89 发布v1.8.2 2021-03-09 20:49:49 +08:00
lyswhut
fa6b7eacaa 修复歌曲ID存储变更导致酷狗图片获取失败的问题 2021-03-09 17:40:33 +08:00
lyswhut
23dafe539d 修正错误 2021-03-08 19:20:49 +08:00
lyswhut
0a654efda0 修改api窗口名 2021-03-07 21:43:00 +08:00
lyswhut
bec10ebe34 Merge branch 'dev' 2021-03-07 17:56:13 +08:00
lyswhut
0e03ca5d48 发布v1.8.1 2021-03-07 17:55:04 +08:00
lyswhut
4b1bf29ea0 新增启动参数-dhmkh 2021-03-07 17:54:02 +08:00
lyswhut
b391b2c16d 添加链接锚点 2021-03-07 17:53:24 +08:00
lyswhut
7b9cf93b40 修复歌词翻译的主题颜色适配问题 2021-03-07 15:07:22 +08:00
lyswhut
dd55e5e086 修改api窗口名 2021-03-07 13:30:47 +08:00
lyswhut
ba2b1dac92 Merge branch 'dev' 2021-03-07 12:38:11 +08:00
lyswhut
56ffeb3008 发布v1.8.0 2021-03-07 12:36:57 +08:00
lyswhut
b3757fd6b5 修复在下载列表右击未下载完成的歌曲弹出的右击菜单中没有开始下载选项的问题 2021-03-07 12:22:53 +08:00
lyswhut
e0de81230e Merge branch 'api' into dev 2021-03-07 12:01:59 +08:00
lyswhut
2bc669c828 添加更新日志 2021-03-07 01:29:23 +08:00
lyswhut
493f7809a4 优化歌词特殊字符移除 2021-03-07 01:22:25 +08:00
lyswhut
ef52cd6991 Merge branch 'dev' into lrc 2021-03-07 01:18:54 +08:00
lyswhut
480f15b6f6 优化酷狗搜索结果 2021-03-07 01:18:44 +08:00
lyswhut
fcfee88ef4 移除日志打印 2021-03-07 00:56:00 +08:00
lyswhut
19f647e6ab Merge branch 'dev' into lrc 2021-03-04 15:27:45 +08:00
lyswhut
27e5ec02f4 优化单首歌曲的“添加到列表”弹窗歌曲列表状态的显示 2021-03-04 15:27:29 +08:00
lyswhut
0808d77a2d 修复鼠标显示状态 2021-03-04 14:33:23 +08:00
lyswhut
90d9e9b911 修复歌词缩放设置失效的问题 2021-03-04 13:20:19 +08:00
lyswhut
ebfbc11c20 Merge branch 'dev' into lrc 2021-03-03 17:21:13 +08:00
lyswhut
2764743062 更新说明 2021-03-03 16:52:19 +08:00
lyswhut
c66d7d6187 完善歌词 2021-03-03 16:51:02 +08:00
lyswhut
f2b6c0a443 支持桌面歌词拖动 2021-03-02 18:41:27 +08:00
lyswhut
aef0ffa506 修改桌面歌词为逐字播放 2021-03-02 18:10:12 +08:00
lyswhut
040fcfba4f 初步完善歌词 2021-03-02 08:32:26 +08:00
lyswhut
9f72831e4a 更新依赖 2021-02-23 19:51:01 +08:00
lyswhut
fa0d9ad4c3 新增启动参数-play 2021-02-22 12:59:39 +08:00
lyswhut
b6107b7281 优化列表存储逻辑 2021-02-21 16:19:08 +08:00
lyswhut
6ffe61562b 移除自动换源清理 2021-02-21 15:46:19 +08:00
lyswhut
b5f5e13f22 移除xm verify窗口 2021-02-21 12:34:50 +08:00
lyswhut
376b7545e1 修复我的列表的灰色歌曲会显示下载按钮的问题 2021-02-20 01:01:58 +08:00
lyswhut
ffaa3e591b 修复kg获取图片失败的错误处理 2021-02-20 00:50:00 +08:00
lyswhut
24d5722ef7 移除log 2021-02-19 22:10:37 +08:00
lyswhut
9e1fe0a6c1 移除多余代码 2021-02-19 21:59:58 +08:00
lyswhut
d128aeb6ef 修复kg歌曲详情页的歌曲无法播放的问题 2021-02-19 11:47:25 +08:00
lyswhut
ef371dedb4 修正描述 2021-02-15 19:53:46 +08:00
lyswhut
00d262f0e6 修复mg源歌单列表无法加载的问题 2021-02-15 12:40:12 +08:00
lyswhut
475b8924c3 修复歌单列表加载失败时无法进入歌单打开界面的问题 2021-02-15 10:52:29 +08:00
lyswhut
0afb1417a3 修复下载列表数据存储问题 2021-02-06 00:09:09 +08:00
lyswhut
b6b41660d6 移除未使用的变量 2021-02-05 23:07:36 +08:00
lyswhut
c78811fe36 移除虾米源,允许播放除了搜索列表以外的所有歌曲 2021-02-05 23:06:08 +08:00
lyswhut
a0254eb4f2 优化英文名歌曲匹配 2021-02-04 17:26:11 +08:00
lyswhut
e9c96ecde2 修复搜索列表双击不支持播放的源时会导致切歌的问题 2021-02-04 14:37:52 +08:00
lyswhut
f9cbf9254c 新增设置-其他-列表缓存信息清理功能 2021-02-02 15:08:07 +08:00
lyswhut
70d24ffdfd 修复音乐搜索列表的稍后播放功能无效的问题 2021-02-01 18:26:26 +08:00
lyswhut
84530ca0a2 添加网盘无法打开的提示 2021-02-01 16:17:57 +08:00
lyswhut
e848fda4e3 将下载列表与我的列表分离存储 2021-02-01 14:55:39 +08:00
lyswhut
51964e51c6 Merge branch 'dev' 2021-01-30 14:33:58 +08:00
lyswhut
0c63268df1 发布v1.7.1版本 2021-01-30 14:30:05 +08:00
lyswhut
316f62c3c8 修复MAC下xm音乐滑块验证问题 2021-01-30 14:29:20 +08:00
lyswhut
9e37800426 修复非透明模式下右侧滚动条无法拖动的问题 2021-01-30 14:18:12 +08:00
lyswhut
3e0ee374c9 移除对changelog的html对version.json的写入 2021-01-30 13:46:46 +08:00
lyswhut
bb411a365c Merge branch 'dev' 2021-01-30 13:17:47 +08:00
lyswhut
da0878a7a7 更新依赖到最新 2021-01-30 13:15:32 +08:00
lyswhut
d0328f17e1 发布v1.7.0版本 2021-01-30 13:14:33 +08:00
lyswhut
c6f49984a7 修改默认弹出层动画 2021-01-30 12:53:39 +08:00
lyswhut
f53fb071f0 更新electron到9.4.2 2021-01-29 22:24:37 +08:00
lyswhut
2cc8af71d0 修复自动换源遇到不支持的源时报错的问题 2021-01-29 10:18:48 +08:00
lyswhut
006da66028 导出歌单移除换源信息 2021-01-28 14:09:22 +08:00
lyswhut
2a74abdef4 修复xm源验证问题 2021-01-28 10:22:26 +08:00
lyswhut
269b14394d 修复了一个由版本更新日志显示导致的潜在远程代码执行攻击漏洞 2021-01-27 19:20:29 +08:00
lyswhut
d6d6fae2ca 禁止打开非http协议链接 2021-01-26 08:43:07 +08:00
lyswhut
331afc37df 新增“记住播放进度”功能的控制,优化设置项展示 2021-01-25 10:44:03 +08:00
lyswhut
041bfdaf3c 修复切换音乐来源可能无法切歌的问题 2021-01-23 19:36:29 +08:00
lyswhut
023cd15cd0 调整加载动画速度 2021-01-23 16:45:01 +08:00
lyswhut
f2fb37df4c 修复快速切换歌曲时, 会出现播放的歌曲和界面展示的歌曲不一致的问题 2021-01-23 16:33:12 +08:00
lyswhut
c4ae0dddb0 修改自动更新阶段的描述 2021-01-23 15:43:14 +08:00
lyswhut
f66077f012 修复手动切歌不清除稍后播放列表的问题 2021-01-23 14:56:57 +08:00
lyswhut
a31d6bc5ae 修改菜单大小 2021-01-23 14:42:01 +08:00
lyswhut
fad13f517b 更新electron到9.4.1 2021-01-21 16:26:46 +08:00
lyswhut
ef36517a26 修复恢复播放会导致重复播放的问题 2021-01-21 15:16:46 +08:00
lyswhut
085e45a50f 新增“稍后播放”功能 2021-01-21 14:39:37 +08:00
lyswhut
43b06a686b 修改构建命令 2021-01-20 14:55:34 +08:00
lyswhut
e8dba4d133 优化播放歌曲换源匹配规则 2021-01-18 16:28:11 +08:00
lyswhut
1af3cd1d77 优化播放歌曲换源匹配 2021-01-18 16:21:57 +08:00
lyswhut
4c44310fea 移除下面热搜词的加载 2021-01-16 01:11:55 +08:00
lyswhut
3e343a80fd 搜索界面新增搜索状态的提示 2021-01-16 01:11:17 +08:00
lyswhut
313fac9f18 Merge branch 'dev' 2021-01-13 21:35:00 +08:00
lyswhut
2c242c66e5 发布v1.6.1版本 2021-01-13 21:34:28 +08:00
lyswhut
4e2b525c99 移除initTOC调用 2021-01-13 14:06:59 +08:00
lyswhut
93c76d4ba0 添加参数修改说明 2021-01-13 14:05:47 +08:00
lyswhut
b69ecca252 修改目录 2021-01-13 11:16:16 +08:00
lyswhut
947011103c 降级electron到9.3.3修复部分系统没有声音的问题 2021-01-13 11:14:53 +08:00
lyswhut
2fd7e4503a 修复自动换源导致的搜索列表每页变成10条数据的问题 2021-01-12 11:42:56 +08:00
lyswhut
a5fce15661 改进自动换源时的歌曲匹配 2021-01-12 11:09:27 +08:00
lyswhut
f1561ddc21 修复某些情况下自动换源的时间过长时会终止换源自动切歌的问题 2021-01-11 16:21:08 +08:00
lyswhut
74ce094d79 更新无法试听解决方法 2021-01-11 14:12:58 +08:00
lyswhut
f832d70701 更新-dha参数的描述 2021-01-10 13:14:50 +08:00
lyswhut
24521bf50d Merge branch 'dev' 2021-01-10 12:53:15 +08:00
lyswhut
cfe84fc2dd 发布v1.6.0版本 2021-01-10 12:52:45 +08:00
lyswhut
8efeb169af 优化歌曲匹配 2021-01-09 21:10:58 +08:00
lyswhut
7b7711d410 Merge branch 'dev' into 黑色主题 2021-01-09 20:32:55 +08:00
lyswhut
8b0779ac17 修复对dt参数的读取 2021-01-09 20:13:32 +08:00
lyswhut
1e904e5ebb 优化自动换源功能 2021-01-09 19:40:31 +08:00
lyswhut
1d3b93d4a3 更新依赖 2021-01-09 18:28:51 +08:00
lyswhut
7756b62f4c 优化歌曲匹配规则 2021-01-09 15:15:52 +08:00
lyswhut
7990e841e0 优化歌曲查找匹配功能 2021-01-09 01:15:20 +08:00
lyswhut
ae348a71e6 移除log 2021-01-09 00:48:59 +08:00
lyswhut
9a1a537bfd 新增播放自动换源功能 2021-01-09 00:45:15 +08:00
lyswhut
6b7d2ea657 整理代码 2021-01-08 22:57:10 +08:00
lyswhut
98ef7c2385 新增-dha参数,修复-nt启动参数不真正生效的问题 2021-01-08 22:09:08 +08:00
lyswhut
093bfd26a3 我的列表右键菜单添加搜索当前歌曲功能 2021-01-06 15:04:00 +08:00
lyswhut
9953c61d62 添加对tips实例的销毁处理 2021-01-03 14:07:50 +08:00
lyswhut
e61072ddc9 更新快速隐藏详情页英文翻译 2021-01-03 01:24:06 +08:00
lyswhut
2269cd54be 隐藏播放详情页按钮添加快速隐藏详情页提示 2021-01-03 01:22:25 +08:00
lyswhut
76d5e64097 添加桌面歌词字体、透明度调整按钮微调提示 2021-01-03 01:11:08 +08:00
lyswhut
06073f3982 添加鼠标提示的自动关闭功能 2021-01-03 00:46:13 +08:00
lyswhut
0f71a93c5e 添加鼠标指向歌曲封面的提示 2021-01-03 00:04:33 +08:00
lyswhut
fa41c32a3e 更新依赖 2020-12-26 10:20:10 +08:00
lyswhut
3b00efdeae Merge branch 'dev' into 黑色主题 2020-12-24 17:22:30 +08:00
lyswhut
0f323ce04f Merge branch 'dev' 2020-12-24 17:22:22 +08:00
lyswhut
ad2acc2a16 更新更新日志 2020-12-24 17:20:27 +08:00
lyswhut
162fea6e28 移除多余文件 2020-12-24 17:17:54 +08:00
lyswhut
30e939c354 更新electron版本到9.5.0 2020-12-24 14:27:57 +08:00
lyswhut
94c25b5dcb 优化列表排序弹窗界面 2020-12-24 14:27:44 +08:00
lyswhut
a58d65e8af 修复恢复上次播放的歌曲时在随机播放模式下不把恢复播放的歌曲放入已播放队列的问题 2020-12-24 11:33:01 +08:00
lyswhut
06b453ebe7 新增歌曲下载失败FAQ 2020-12-23 17:03:38 +08:00
lyswhut
f00c6b1cb6 更新Linux桌面歌词说明 2020-12-19 15:39:33 +08:00
lyswhut
027466dfc2 更新排序说明 2020-12-19 15:19:24 +08:00
lyswhut
bc69a98df1 我的列表右键菜单新增列表排序功能 2020-12-19 15:16:22 +08:00
lyswhut
ba9fd8d1f1 新增 更新已收藏的在线歌单 问答 2020-12-18 19:36:38 +08:00
lyswhut
0fcc3f257d 修正描述 2020-12-18 19:36:29 +08:00
lyswhut
382235c556 移除多余代码 2020-12-13 13:30:21 +08:00
lyswhut
0a919d7076 修复getAttribute的报错 2020-12-13 12:32:55 +08:00
lyswhut
0709aa56a4 Merge branch 'dev' 2020-12-13 11:48:17 +08:00
lyswhut
684d90d0e7 发布v1.5.0 2020-12-13 11:47:46 +08:00
lyswhut
227c05a696 降级electron到9.3.3 2020-12-12 21:00:58 +08:00
lyswhut
8cf1a4a790 更新依赖 2020-12-12 19:35:10 +08:00
lyswhut
75e3976bfa 添加同步歌单状态指示 2020-12-12 09:41:31 +08:00
lyswhut
e9791fd493 修正进度条状态 2020-12-12 09:26:15 +08:00
lyswhut
f9f445489c Update template 2020-12-11 08:34:47 +08:00
lyswhut
10e5460e39 优化软件启动时恢复上一次播放的歌曲进度功能 2020-12-11 08:29:30 +08:00
lyswhut
f1049169b5 直接从歌单详情收藏的列表新增同步功能 2020-12-10 12:57:48 +08:00
lyswhut
2056bdb43d 搜索框为空时不进行歌单打开 2020-12-07 17:32:21 +08:00
lyswhut
785bf3ce3a 添加Linux arm64 deb包的构建 2020-12-06 22:54:03 +08:00
lyswhut
c29bf61e59 修复某些酷狗源歌单链接无法打开的问题 2020-12-06 21:33:39 +08:00
lyswhut
a98c0516a3 修复酷狗源的某些歌曲没有专辑字段导致的列表加载失败问题 2020-12-06 21:17:18 +08:00
lyswhut
a6989a2aba 移除log 2020-12-04 21:34:11 +08:00
lyswhut
30e43170f8 修复MAC平台首次运行软件最小化、关闭控制按钮默认在右边的问题 2020-11-30 09:59:38 +08:00
lyswhut
d8feb3e794 修改相对路径别名 2020-11-28 20:23:17 +08:00
lyswhut
99bdf6d173 增加歌曲加载等待时间 2020-11-28 20:22:58 +08:00
lyswhut
8424a9e4de 降级node-id3修复MAC平台上下载歌曲封面嵌入无法显示的问题 2020-11-28 20:22:33 +08:00
lyswhut
4c0cbe3253 Merge branch 'dev' 2020-11-25 08:27:53 +08:00
lyswhut
462dc5da51 发布v1.4.1版本 2020-11-25 08:26:43 +08:00
lyswhut
40fad5f785 调整FAQ顺序 2020-11-24 15:17:04 +08:00
lyswhut
c0791acbf6 修复某些电脑上的某些歌曲没有声音的问题 2020-11-24 15:16:46 +08:00
lyswhut
3cb0a56647 修复歌曲URL过期时,等待刷新URL的自动切换歌曲时间间隔太短的问题 2020-11-23 10:18:35 +08:00
lyswhut
95f38e8048 修复有歌词翻译与无歌词的音乐间切换会导致歌词翻译残留显示的问题 2020-11-22 11:06:45 +08:00
lyswhut
a3493a6c74 Merge branch 'dev' 2020-11-21 19:01:16 +08:00
lyswhut
3535bb4e4e 发布v01.4.0 2020-11-21 19:00:35 +08:00
lyswhut
3be6242cb5 更新多选说明 2020-11-20 10:55:23 +08:00
lyswhut
64a53830e4 新增播放进度信息保存 2020-11-19 15:52:00 +08:00
lyswhut
b3e3860b23 修复kg源歌曲信息带有单引号等特殊字符被转义的问题 2020-11-17 17:14:47 +08:00
lyswhut
4db560fb4b 修复移动单首歌曲时出现的问题 2020-11-15 14:08:11 +08:00
lyswhut
b00de4d976 托盘菜单新增显示、隐藏主界面选项,为Linux、MAC版添加托盘菜单 2020-11-14 22:29:27 +08:00
lyswhut
0a0d6969ec 初始提交 2020-11-14 11:48:51 +08:00
lyswhut
ac162103a7 更新依赖 2020-11-14 10:22:47 +08:00
lyswhut
16876502d1 修复播放状态栏切换“上一首”歌曲按钮提示错误的问题 2020-11-13 14:57:45 +08:00
lyswhut
4cdd2110a6 更新依赖 2020-11-10 10:59:45 +08:00
lyswhut
b820adf0bf 优化切歌逻辑 2020-11-10 08:33:07 +08:00
lyswhut
1cee2febf4 修复专辑图片无法嵌入的问题 2020-11-10 08:31:47 +08:00
lyswhut
43f8d9d72b 更新FAQ问题顺序 2020-11-06 21:33:27 +08:00
lyswhut
66ffe03224 修改评论按钮提示 2020-11-04 09:08:18 +08:00
lyswhut
5c96c83f98 移除kg源的歌词文件开头的空白字符串 2020-11-02 15:13:09 +08:00
lyswhut
6d1ddece92 Merge branch 'dev' 2020-11-01 18:18:15 +08:00
lyswhut
897107ca23 发布v1.3.0版本 2020-11-01 18:17:34 +08:00
lyswhut
0baaffdad8 修复小芸源评论的翻页加载问题 2020-11-01 18:01:04 +08:00
lyswhut
784d2fda6d 修复小芸源音乐搜索结果最多只有20条搜索结果的问题 2020-11-01 14:36:53 +08:00
lyswhut
19817249db 更新依赖 2020-11-01 01:23:04 +08:00
lyswhut
240260e598 修正用户名英文字母的行高问题 2020-11-01 00:59:50 +08:00
lyswhut
fcf92f06ef 修复tx源某些评论的换行问题 2020-11-01 00:50:49 +08:00
lyswhut
fe1c2a1896 添加目录 2020-10-30 08:37:32 +08:00
lyswhut
d55c65e275 更新依赖 2020-10-29 09:08:39 +08:00
lyswhut
93064bb18b 完善评论功能 2020-10-29 09:07:25 +08:00
lyswhut
dec1b24c86 修正错别字 2020-10-28 11:02:21 +08:00
lyswhut
8c76c3d81c 播放详情页新增歌曲评论加载显示 2020-10-27 18:09:17 +08:00
lyswhut
8d8cabd5b3 完善评论功能 2020-10-24 02:08:31 +08:00
lyswhut
aa948b0149 添加评论界面 2020-10-23 22:40:23 +08:00
lyswhut
a25ef6e2a0 修改播放详情页的歌曲图片的显示效果 2020-10-22 21:00:12 +08:00
lyswhut
c404d3ac8d Merge branch 'dev' 2020-10-18 12:01:12 +08:00
lyswhut
8eb71495a1 发布v1.2.2版本 2020-10-18 12:00:28 +08:00
lyswhut
db824c4601 更新版本号 2020-10-18 11:48:46 +08:00
lyswhut
029886cc87 降级 Electron 到 9.x.x 版本修复 Linux 版桌面歌词窗口变白的问题 2020-10-18 11:47:38 +08:00
lyswhut
42604ec737 Merge branch 'dev' 2020-10-18 09:23:57 +08:00
lyswhut
caaa62db30 发布v1.2.1版本 2020-10-18 09:22:34 +08:00
lyswhut
0f135e0587 更新依赖 2020-10-17 16:09:29 +08:00
lyswhut
dae6826cc1 Linux版的软件界面默认使用圆角与阴影,顺便修复了桌面歌词窗口变白的问题 2020-10-14 18:20:03 +08:00
lyswhut
ddf2ac7ece 更新FAQ 2020-10-08 22:22:11 +08:00
lyswhut
5e011356f2 更新依赖 2020-10-08 17:15:19 +08:00
lyswhut
82e047dc66 修复输入框组件bug 2020-10-08 17:09:26 +08:00
lyswhut
7720b416d5 更新依赖 2020-10-07 21:37:02 +08:00
lyswhut
c40dc0fa50 修复聚合搜索的分页问题 2020-10-02 12:59:41 +08:00
lyswhut
36ed7bca66 Merge branch 'dev' 2020-09-30 01:15:41 +08:00
lyswhut
1fa015704a 发布 v1.2.0 版本 2020-09-30 01:15:08 +08:00
lyswhut
7e2097ba6d 更新 Electron 到 v10.1.3 2020-09-29 22:05:20 +08:00
lyswhut
3a630edaa5 优化提示查找逻辑 2020-09-29 14:41:41 +08:00
lyswhut
1b561bbf4c 优化提示出现的位置 2020-09-29 11:14:29 +08:00
lyswhut
37de0b59c3 优化软件内文本悬浮提示 2020-09-29 10:37:41 +08:00
lyswhut
2f528d2a03 Merge branch 'dev' of github.com:lyswhut/lx-music-desktop into dev 2020-09-29 08:46:23 +08:00
lyswhut
686d55a672 优化特征匹配 2020-09-29 00:34:39 +08:00
lyswhut
07c58e2ce7 修复关闭切换动画时从搜索候选列表点击内容无效的问题 2020-09-28 23:00:53 +08:00
lyswhut
6fe794fdf5 修复酷狗歌词格式问题 2020-09-28 22:53:20 +08:00
lyswhut
d0ec90130c 修复歌曲封面无法嵌入的Bug 2020-09-28 22:52:50 +08:00
lyswhut
f7806d9781 播放控制栏开启/关闭桌面歌词按钮 新增右击按钮时锁定/解锁桌面歌词功能 2020-09-28 16:40:51 +08:00
lyswhut
63219b49f2 修复搜索历史列表的保存问题 2020-09-28 10:04:17 +08:00
lyswhut
320e84627c 更新依赖到最新 2020-09-28 09:56:48 +08:00
lyswhut
fc9e697249 修复迁移列表滚动位置设置时的bug 2020-09-28 09:54:36 +08:00
lyswhut
a68c626fa2 Merge branch 'dev' of github.com:lyswhut/lx-music-desktop into dev 2020-09-28 08:35:53 +08:00
lyswhut
66f17cf05b 更新log 2020-09-28 01:33:15 +08:00
lyswhut
5949e8fb3f 优化我的列表滚动条位置的保存逻辑 2020-09-28 01:33:06 +08:00
lyswhut
3bb0fcc4cd 修复重启软件后试听列表与收藏列表无法恢复上次的滚动位置的问题 2020-09-28 01:32:53 +08:00
lyswhut
d32d5d0eb8 修复初始化搜索历史列表功能 2020-09-28 01:32:45 +08:00
lyswhut
5ee2c030ec 更新设置-备份与恢复功能的描述 2020-09-23 17:00:16 +08:00
lyswhut
58ca7df105 修复网易云KTV嗨榜无法加载的问题 2020-09-20 12:17:47 +08:00
lyswhut
fc77dbc73b 优化代码 2020-09-19 16:18:13 +08:00
lyswhut
8aedde2422 修复桌面歌词窗口不允许拖出桌面之外的位置计算偏移Bug 2020-09-19 16:00:03 +08:00
lyswhut
526b5fe140 Merge branch 'dev' 2020-09-19 13:00:24 +08:00
lyswhut
1c4e9ed474 发布v1.1.1版本 2020-09-19 12:59:55 +08:00
lyswhut
21cbb441e2 更新依赖到最新 2020-09-19 12:56:07 +08:00
lyswhut
01fedc59e2 修复某些情况下桌面歌词不会播放的问题 2020-09-19 12:55:51 +08:00
lyswhut
b3d13c3a90 Merge branch 'dev' 2020-09-18 20:24:48 +08:00
lyswhut
24ee42e0c7 修正更新描述 2020-09-18 20:24:09 +08:00
lyswhut
3a18eccdd6 更新travis-ci地址 2020-09-18 20:11:40 +08:00
lyswhut
a3b763ecc9 发布 v1.1.0 版本 2020-09-18 20:08:04 +08:00
lyswhut
822c74ad2f 更新依赖到最新 2020-09-18 20:02:12 +08:00
lyswhut
0a71e34459 播放状态栏新增桌面歌词的开关、播放模式的切换、歌曲的收藏按钮 2020-09-18 12:03:41 +08:00
lyswhut
25b68081ea 迁移travis-ci.org到travis-ci.com 2020-09-16 08:54:57 +08:00
lyswhut
ac0e1e7698 移除对百度音乐的支持 2020-09-05 15:13:49 +08:00
lyswhut
4be5bcc979 新增酷狗歌词翻译 2020-09-05 03:50:30 +08:00
lyswhut
f3c2d7e43a 更新依赖到最新 2020-09-05 03:46:33 +08:00
lyswhut
9fa0700f72 更新css-loader 2020-09-02 14:00:01 +08:00
lyswhut
868da542ab 更新网盘地址 2020-08-30 13:24:23 +08:00
lyswhut
04c810e292 添加没有写入权限的提示 2020-08-30 12:25:02 +08:00
lyswhut
86478c0268 更新electron到 10.1.0 2020-08-29 14:44:37 +08:00
lyswhut
b453a8934f 新增显示切换动画设置 2020-08-24 00:44:55 +08:00
lyswhut
669c1fe490 新增显示歌词翻译设置,默认开启 2020-08-23 15:45:08 +08:00
lyswhut
c15895ab45 新增 不允许将歌词窗口拖出主屏幕之外 的设置项 2020-08-23 12:13:17 +08:00
lyswhut
44acc7d5ac 移除默认的全局声音媒体快捷键接管 2020-08-22 14:17:34 +08:00
lyswhut
341df0dab7 在歌单详情界面新增播放当前歌单按钮、收藏歌单按钮 2020-08-22 14:06:16 +08:00
lyswhut
8df3ff3536 更新依赖 2020-08-22 12:49:43 +08:00
lyswhut
85c683b714 优化随机播放机制 2020-08-10 22:24:38 +08:00
lyswhut
6606edafb9 修复窗口在较小模式下最小化/关闭按钮不居中的问题 2020-08-10 09:51:31 +08:00
lyswhut
91ff7b658a 更新依赖 2020-08-09 12:39:49 +08:00
lyswhut
27c500e950 移除无用代码 2020-08-09 12:39:24 +08:00
lyswhut
078245cb96 修复我的列表搜索对最后一个字符的匹配问题 2020-08-04 09:05:23 +08:00
lyswhut
e54597b944 为区分静音状态,静音时音量条会变淡,调整音量条时将会取消静音 2020-08-04 08:54:26 +08:00
lyswhut
1af9b3a018 静音时隐藏音量条 2020-08-02 14:40:38 +08:00
lyswhut
315d041fc7 桌面歌词当前播放行改为上下居中 2020-08-01 23:26:35 +08:00
lyswhut
f7f1cdab34 优化逻辑 2020-07-31 11:00:55 +08:00
lyswhut
597f0da42f 移除多余脚本命令 2020-07-27 12:06:54 +08:00
lyswhut
497add09b3 修复使用全局快捷键还原窗口时,窗口没有获取焦点的问题 2020-07-27 11:38:59 +08:00
lyswhut
ff05225b56 修复git文件名大小写问题 2020-07-26 16:25:32 +08:00
lyswhut
ac053e9ac9 移除多余文件 2020-07-26 16:21:53 +08:00
lyswhut
9aeae1e460 移除重复的文件 2020-07-26 16:19:52 +08:00
lyswhut
d710f204b3 更新faq 2020-07-26 12:33:23 +08:00
lyswhut
be016aa4bb 发布v1.0.1版本 2020-07-25 19:49:04 +08:00
lyswhut
04e62cba24 更新到v1.0.1版本 2020-07-25 19:42:02 +08:00
lyswhut
4d476dc641 修复在 Windows 系统下缩放比非100%时,拖动桌面歌词会自动加大桌面歌词窗口的问题 2020-07-25 19:40:44 +08:00
lyswhut
85c3a812da 对我的列表歌曲搜索结果进行相似度排序 2020-07-25 19:36:46 +08:00
lyswhut
e985e70303 更新多选描述 2020-07-24 22:18:27 +08:00
lyswhut
9dbf96c259 发布 1.0.0 版本 2020-07-24 20:49:44 +08:00
lyswhut
6eba7c9a2f 更新文档 2020-07-24 20:48:20 +08:00
lyswhut
c1966e9301 更新FAQ 2020-07-24 20:45:50 +08:00
lyswhut
a6fb72f1de 调整主题颜色 2020-07-24 20:28:07 +08:00
lyswhut
a695a69f0f 更新依赖 2020-07-23 00:42:17 +08:00
lyswhut
a8632297eb 新增在歌单详情列表按退格键可快速返回歌单列表 2020-07-19 13:40:09 +08:00
lyswhut
ca4218b309 点击确定时打开备份文件位置 2020-07-18 22:49:28 +08:00
lyswhut
65df71239a 更新package-lock.json 2020-07-14 20:57:29 +08:00
lyswhut
fdd8f3b214 更新依赖 2020-07-14 20:41:10 +08:00
lyswhut
1887573301 更新electron到9.1.0 2020-07-08 02:01:46 +08:00
lyswhut
1efd56f48b 新增当列表文件损坏时对损坏文件的备份 2020-07-06 18:15:03 +08:00
lyswhut
bcd13b6f27 压缩备份数据文件 2020-07-06 16:14:18 +08:00
lyswhut
e4e880edd9 优化歌单操作体验 2020-07-04 21:14:29 +08:00
lyswhut
75da9c2e73 修复无法开启托盘的bug 2020-07-04 17:32:43 +08:00
lyswhut
7a933dbd5e 修正桌面歌词透明度按钮描述 2020-07-04 13:17:42 +08:00
lyswhut
4b097b83b1 更新依赖到最新 2020-07-04 11:58:39 +08:00
lyswhut
b3f9a691f5 重新提交重命名后的文件 2020-07-04 11:50:55 +08:00
lyswhut
50cd94a280 Merge branch 'master' into dev 2020-07-04 11:32:51 +08:00
lyswhut
82982b3cda 调整图标 2020-07-04 01:50:08 +08:00
lyswhut
a5243ff58c 支持flac文件歌词写入 2020-07-03 09:16:20 +08:00
lyswhut
3b25e0a112 新增将歌词嵌入音频文件中 2020-07-02 12:03:18 +08:00
lyswhut
d94d880569 修复搜索界面批量添加歌曲时程序异常的bug 2020-07-01 23:46:52 +08:00
lyswhut
8eec07b5bd 更改默认搜索设置为聚合搜索 2020-07-01 17:07:25 +08:00
lyswhut
9f72a51458 新增开关下载功能控制 2020-07-01 17:04:43 +08:00
lyswhut
9fd181ee06 新增托盘图标样式设置 2020-06-29 01:06:06 +08:00
lyswhut
f18875682b 修复透明度按钮提示错误的问题 2020-06-28 12:04:00 +08:00
lyswhut
897a17e303 修复版本对比问题 2020-06-27 21:22:02 +08:00
lyswhut
c9d0aafbfa 优化右击菜单逻辑 2020-06-27 13:43:27 +08:00
lyswhut
fbd2a57a35 新增我的列表内歌曲搜索 2020-06-26 16:24:23 +08:00
lyswhut
ccd5c91283 添加右击菜单对不可用音源的处理 2020-06-26 12:21:07 +08:00
lyswhut
c78b9f07a2 修复聚合搜索音源标签的皮肤配色问题 2020-06-26 12:17:11 +08:00
lyswhut
ffc3300fe4 移除无用代码 2020-06-26 01:12:08 +08:00
lyswhut
b02d32929c 优化默认设置 2020-06-26 00:17:09 +08:00
lyswhut
e29d3e3eaa 隐藏下载弹窗中不可用的音质 2020-06-25 23:39:48 +08:00
lyswhut
5d91643637 歌曲列表右击菜单新增跳转到当前歌曲源官方详情页菜单 2020-06-25 23:10:38 +08:00
lyswhut
9eec1adf77 支持加载大于1000首歌的歌单 2020-06-25 21:29:05 +08:00
lyswhut
9cebaa0d97 新增歌词区域触摸板、鼠标滚轮等对歌词滚动的支持 2020-06-25 19:39:12 +08:00
lyswhut
48cfebd5ae 改进聚合搜索的搜索结果排序 2020-06-25 19:37:54 +08:00
lyswhut
0c3899840b 添加静音处理 2020-06-25 15:18:56 +08:00
lyswhut
93bab6bbdd 优化逻辑 2020-06-24 22:55:47 +08:00
lyswhut
69368b884f 修复默认快捷键绑定问题 2020-06-24 20:20:19 +08:00
lyswhut
f59b2d26ad 优化播放控制按钮交互效果 2020-06-24 16:18:05 +08:00
lyswhut
32ffe33e1a 修复禁用快捷键的情况下设置全局快捷键的bug,优化启用/禁用视觉效果 2020-06-24 16:17:24 +08:00
lyswhut
cc5d119ba4 新增首次运行时自动根据当前系统使用的语言设置软件显示的语言 2020-06-24 16:12:02 +08:00
lyswhut
637727faa0 修改播放界面布局 2020-06-24 14:18:32 +08:00
lyswhut
9b82cdfe53 新增快捷键设置 2020-06-24 01:20:56 +08:00
lyswhut
2424c76c50 修复Linux下无法ctrl+a全选的问题 2020-06-20 15:32:39 +08:00
lyswhut
f0dc76c7a4 修复某些情况下从托盘还原窗口后无法操作的问题 2020-06-20 13:15:23 +08:00
lyswhut
798f5cd0a6 优化界面显示时的效果 2020-06-15 20:28:41 +08:00
lyswhut
a904896269 修复进度条开始部分无法选择的问题 2020-06-14 18:07:41 +08:00
lyswhut
be482bd683 优化打开歌单输入框宽度 2020-06-14 00:22:30 +08:00
lyswhut
e9a624c896 优化选择逻辑 2020-06-13 16:11:43 +08:00
lyswhut
b3a13a25f0 优化UI 2020-06-12 19:15:40 +08:00
lyswhut
30e55f5acb 修复事件绑定bug 2020-06-11 22:24:55 +08:00
lyswhut
7a67263cf9 添加阴影 2020-06-11 22:18:54 +08:00
lyswhut
b811906bae 新增软件最小化、关闭按钮位置设置 2020-06-11 21:41:15 +08:00
lyswhut
2a81d41c2c 新增桌面歌词 2020-06-11 21:16:59 +08:00
dependabot[bot]
51d0037a4b Bump websocket-extensions from 0.1.3 to 0.1.4 (#225)
Bumps [websocket-extensions](https://github.com/faye/websocket-extensions-node) from 0.1.3 to 0.1.4.
- [Release notes](https://github.com/faye/websocket-extensions-node/releases)
- [Changelog](https://github.com/faye/websocket-extensions-node/blob/master/CHANGELOG.md)
- [Commits](https://github.com/faye/websocket-extensions-node/compare/0.1.3...0.1.4)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-06-07 21:19:55 +08:00
lyswhut
25fc0226aa 移除多余代码 2020-05-24 15:12:35 +08:00
lyswhut
cfef06a15b 新增我的列表右键菜单复制歌曲名选项 2020-05-23 22:44:19 +08:00
lyswhut
5ce6aafc07 修改排行榜顺序 2020-05-23 22:31:24 +08:00
lyswhut
fe833033df 改变排行榜布局,新增更多排行榜 2020-05-23 22:24:20 +08:00
lyswhut
a47be148c8 更新electron到 v9 2020-05-23 16:32:28 +08:00
lyswhut
af426d28c1 修复错误更新试听列表外的歌曲时间的问题 2020-05-20 23:54:49 +08:00
lyswhut
0332b81d58 完善自定义列表、新增右键菜单 2020-05-20 22:52:37 +08:00
lyswhut
88b416c949 更新描述 2020-05-16 20:44:12 +08:00
lyswhut
66c4e62d9b 更新配置 2020-05-16 20:39:59 +08:00
lyswhut
9091c2c346 Merge branch 'v1' into dev 2020-05-16 20:29:27 +08:00
lyswhut
e29ca2e79c 整理配置逻辑 2020-05-16 20:19:58 +08:00
lyswhut
afc3f48f51 新增自定义列表 2020-05-16 19:21:21 +08:00
lyswhut
eed8b36dc1 Merge branch 'dev' into v1 2020-05-15 11:51:48 +08:00
lyswhut
b20942d254 修改按键绑定机制 2020-05-15 11:50:22 +08:00
lyswhut
e707beffd6 Merge branch 'dev' into v1 2020-05-14 13:24:34 +08:00
lyswhut
747c75fb18 更新依赖 2020-05-14 09:19:19 +08:00
lyswhut
42f0a9df4b 改进媒体设备改变暂停播放逻辑 2020-05-13 23:17:51 +08:00
lyswhut
10ee6bcc7f 新增酷我歌单显示歌曲文件大小 2020-05-10 18:55:20 +08:00
lyswhut
bcba194a31 Merge branch 'dev' into v1 2020-05-09 20:42:04 +08:00
lyswhut
8605f63ac6 完善音频输出设备改变暂停机制 2020-05-09 20:41:48 +08:00
lyswhut
a02827a7ac Merge branch 'dev' into v1 2020-05-08 20:24:12 +08:00
lyswhut
16903b0f5a 修复可能导致渲染进程无响应的问题 2020-05-08 20:23:23 +08:00
lyswhut
26bdf25423 新增所选音频输出设备被移除时是否暂停播放 2020-05-08 19:14:44 +08:00
lyswhut
3c0f4be533 Merge branch 'dev' into v1 2020-05-07 23:12:11 +08:00
lyswhut
ecf9dce758 修复 tab 组件边框溢出问题 2020-05-07 23:11:59 +08:00
lyswhut
90e40d5245 Merge branch 'dev' into v1 2020-05-07 20:38:03 +08:00
lyswhut
b76424ba9b 修改设置-列表-是否显示歌曲源的默认设置为选中 2020-05-06 18:22:24 +08:00
lyswhut
ded75563e9 更新图标 2020-05-05 20:56:25 +08:00
lyswhut
1eb9920bcf 更新图标 2020-05-04 12:19:57 +08:00
lyswhut
7e029b5495 修复某些情况下无法开始下载任务的问题 2020-05-04 01:53:37 +08:00
lyswhut
37f9491d5e 修改布局 2020-05-04 01:19:49 +08:00
lyswhut
6aec78e153 调整代码顺序 2020-05-03 12:49:57 +08:00
lyswhut
685e34bc83 修复某些情况下可能导致的音源输出问题 2020-05-03 12:30:29 +08:00
lyswhut
fb828788df 更新图标 2020-05-03 12:12:49 +08:00
lyswhut
eff49af00c 改为构建 x64 pacman 包 2020-05-02 21:37:54 +08:00
lyswhut
7f02b85eb8 修复报错 2020-05-02 21:20:28 +08:00
lyswhut
1de84c66d6 更新配置 2020-05-02 21:15:34 +08:00
lyswhut
e382ccff9b 安装rpm 2020-05-02 20:57:48 +08:00
lyswhut
33e6202835 新增rpm、pacman包的打包 2020-05-02 20:42:53 +08:00
lyswhut
bd8b8d5b64 配置图标 2020-05-02 20:22:05 +08:00
lyswhut
db9dc18118 为appImage配置图标 2020-05-02 20:10:53 +08:00
lyswhut
7cc373c07f 更新版本 2020-05-02 20:03:07 +08:00
lyswhut
aa87640687 修复Linux版开启托盘无法退出的问题 2020-05-02 20:01:36 +08:00
lyswhut
6724912c73 修改布局 2020-05-02 19:52:43 +08:00
lyswhut
2cabe6e58e 修复多选机制问题 2020-05-02 18:49:24 +08:00
lyswhut
33383cd3bd 初步完善 2020-05-02 18:21:20 +08:00
lyswhut
78c5250f1b 发布v0.18.2 2020-05-02 12:44:00 +08:00
lyswhut
9797d98fac 修复开启托盘时,可能导致无法自动更新的问题 2020-05-02 12:43:00 +08:00
lyswhut
43c2dc3dec 发布v0.18.1 2020-05-02 12:22:47 +08:00
lyswhut
50e140e606 修复导入设置某些设置未立即生效的问题 2020-05-02 12:14:28 +08:00
lyswhut
3f88701751 win下的托盘图标使用更大的图片 2020-05-02 11:53:03 +08:00
lyswhut
7d89d53b1b 加长阅读时间 2020-05-01 22:26:13 +08:00
lyswhut
09f7989cab 修复无法全选的问题 2020-05-01 21:03:43 +08:00
lyswhut
6255cfd401 将electron移到devDependencies 2020-05-01 20:24:28 +08:00
lyswhut
e7e4897dcd 发布v0.18.0版本 2020-05-01 20:15:57 +08:00
lyswhut
9639143893 更新依赖 2020-05-01 20:14:14 +08:00
lyswhut
3be3b0ca36 修复mac下只能全选一次的问题 2020-05-01 20:02:18 +08:00
lyswhut
afc81b6308 将托盘挂到全局变量中 2020-05-01 18:28:33 +08:00
lyswhut
36d140d4bd 修复Mac下的虾米验证、托盘问题 2020-05-01 18:22:19 +08:00
lyswhut
edff998be9 调试 2020-05-01 14:37:07 +08:00
lyswhut
5a856e468e 解决 MAC 首次加载页面无法拖动滑块的问题 2020-05-01 13:42:43 +08:00
lyswhut
d2845f91b5 修正dmg配置 2020-05-01 00:23:35 +08:00
lyswhut
9040c13c3f 修改验证窗口属性 2020-05-01 00:01:31 +08:00
lyswhut
7ed95ff523 修复mac下开启托盘时无法从dock退出的问题 2020-04-30 23:41:45 +08:00
lyswhut
aed9889a2e 修复 mac 托盘图标问题 2020-04-30 21:49:35 +08:00
lyswhut
0090f484d8 尝试新增包到bintray 2020-04-30 18:14:17 +08:00
lyswhut
0c576c65a8 转义歌词字符 2020-04-30 17:03:51 +08:00
lyswhut
b94cde5fbe 更新依赖 2020-04-30 13:24:13 +08:00
lyswhut
df2582d1de 禁止图片拖动 2020-04-30 10:24:40 +08:00
lyswhut
f237a9aab5 修复开始任务时对任务开始失败时的错误处理 2020-04-30 00:19:14 +08:00
lyswhut
12c370d7cb 修复可能导致无法操作任务的问题 2020-04-29 23:34:24 +08:00
lyswhut
015c17e2dc 优化下载列表流畅度 2020-04-29 19:18:53 +08:00
lyswhut
d8a3466914 修复播放下载列表无法切换歌曲的问题 2020-04-29 16:09:44 +08:00
lyswhut
05d2ffe8fa 更新源码使用方法 2020-04-29 12:37:44 +08:00
lyswhut
a62d8304e2 分离可用音质控制逻辑 2020-04-29 12:33:41 +08:00
lyswhut
e51ee8c1ad 添加其他动画 2020-04-28 14:28:51 +08:00
lyswhut
6d0f668f88 更新许可协议 2020-04-28 13:48:46 +08:00
lyswhut
ed5e590859 更新依赖 2020-04-28 13:36:04 +08:00
lyswhut
346fa2c004 新增播放详情页 2020-04-28 13:33:55 +08:00
lyswhut
db04b0c285 优化列表选择逻辑 2020-04-27 22:29:49 +08:00
lyswhut
07800bdb83 添加描述 2020-04-27 22:10:14 +08:00
lyswhut
ad8b338bd9 修复潜在的bug 2020-04-27 21:22:29 +08:00
lyswhut
031c0c263d 修改绑定的键 2020-04-27 11:29:23 +08:00
lyswhut
d54053003e 调整颜色 2020-04-26 23:54:12 +08:00
lyswhut
adb453c216 新增“超大”、“巨大”窗口尺寸 2020-04-26 23:31:38 +08:00
lyswhut
ef04e43323 修复协议弹窗在导入数据时不倒计时的问题 2020-04-26 22:44:47 +08:00
lyswhut
9ff5147418 替换程序中所有同步API的调用 2020-04-26 22:08:23 +08:00
lyswhut
cdbedf3d64 移除列表选择框,新增键盘选择机制 2020-04-26 22:06:13 +08:00
lyswhut
3d52fa059e 更新依赖 2020-04-26 13:29:33 +08:00
lyswhut
ef46d1a308 减淡颜色 2020-04-26 13:20:59 +08:00
lyswhut
d57cfa90fc 新增新皮肤“粉妆玉琢”、“青出于黑” 2020-04-26 13:01:17 +08:00
lyswhut
7aece7dd7e 隐藏多余提示 2020-04-23 21:43:55 +08:00
lyswhut
ccf362db41 新增虾米音源 2020-04-23 12:50:46 +08:00
lyswhut
7bd4002f09 新增使用协议 2020-04-23 12:12:46 +08:00
lyswhut
9460b12cf9 移除多余代码 2020-04-22 22:52:41 +08:00
lyswhut
8cac592182 移除多余依赖 2020-04-22 22:40:58 +08:00
lyswhut
83b25b0c33 修复提示颜色适应 2020-04-19 19:20:00 +08:00
lyswhut
1832ec753c 修复官方歌单的打开 2020-04-19 14:11:20 +08:00
lyswhut
0c4f943d72 添加支持对酷狗码打开的打开 2020-04-19 13:56:08 +08:00
lyswhut
116ee25e28 更新faq 2020-04-16 13:10:45 +08:00
lyswhut
6149c2a8a8 更新关于软件描述 2020-04-15 20:57:53 +08:00
lyswhut
b2e475b857 修正播放列表浮动按钮错误的文字提示 2020-04-15 08:56:45 +08:00
lyswhut
f7e4e98b01 更新依赖 2020-04-15 08:55:44 +08:00
lyswhut
c4a9919652 更新关于软件 2020-04-13 23:06:14 +08:00
lyswhut
5c1fb7d4e8 调换位置 2020-04-13 13:30:28 +08:00
lyswhut
b1d0a4e7ad 更新网盘链接 2020-04-13 11:46:15 +08:00
lyswhut
75db995342 优化聚合热门搜索排序 2020-04-12 18:25:18 +08:00
lyswhut
c318856534 下载列表的歌曲下载、播放将随设置中的保存路径改变而改变 2020-04-12 12:32:44 +08:00
lyswhut
cf42e1846e 修复打开歌单详情的情况下切到其他界面再切回来报错的问题 2020-04-12 11:09:24 +08:00
lyswhut
56a5ebbb9d 更新 readme 2020-04-11 22:41:24 +08:00
lyswhut
7431e1e605 更新依赖 2020-04-11 12:33:03 +08:00
lyswhut
4b6a460e69 更新依赖 2020-04-09 20:45:46 +08:00
lyswhut
f6f0c2f1dc 添加加群说明 2020-04-09 12:33:33 +08:00
lyswhut
90357ae386 修复CheckBox bug 2020-04-09 12:31:05 +08:00
lyswhut
bdc6b08234 修复歌曲切换方式无法取消勾选的问题 2020-04-09 11:59:12 +08:00
lyswhut
1ba68d67ba 暂停不覆盖歌词 2020-04-09 10:58:06 +08:00
lyswhut
d0518e6dfe 兼容另一种用户歌单打开方式 2020-04-08 16:54:29 +08:00
lyswhut
3be6a78568 移除多余代码 2020-04-08 11:44:35 +08:00
lyswhut
a6b8881e30 修复无法打开官方歌单的问题 2020-04-08 11:22:35 +08:00
lyswhut
23c057ac08 去重 2020-04-06 17:54:26 +08:00
lyswhut
07460ba06f 兼容其他歌单分享方式 2020-04-06 17:42:26 +08:00
lyswhut
bcbedbe053 优化逻辑 2020-04-06 14:18:40 +08:00
lyswhut
ba26037c7f 修正拼写错误 2020-04-06 14:00:20 +08:00
lyswhut
60243215a0 加强兼容性 2020-04-06 01:33:14 +08:00
lyswhut
9c3ab28da9 新增打开酷狗源用户歌单 2020-04-06 01:28:10 +08:00
lyswhut
2b1076f09e 修复npm安全漏洞警告,优化编译时cli的显示状态 2020-04-05 15:28:36 +08:00
lyswhut
241859232b npm audit fix 2020-04-05 13:13:55 +08:00
lyswhut
456fdc0fca 修复最小化托盘时再次运行程序时无法恢复窗口显示的问题 2020-04-03 21:45:10 +08:00
lyswhut
be84bd27d3 修复启用托盘后无法退出程序的问题 2020-04-03 21:30:48 +08:00
lyswhut
2e84788d53 修复窗口还原时闪烁的问题 2020-04-03 21:19:44 +08:00
lyswhut
76b3b3b23d 修复托盘创建显示隐藏Bug 2020-04-03 20:42:02 +08:00
lyswhut
426c88c4ed 更新更新日志 2020-04-03 20:15:52 +08:00
lyswhut
d625b0d567 Merge branch 'master' into dev 2020-04-03 20:13:54 +08:00
lyswhut
e350c5f070 切换换行符 2020-04-03 20:09:43 +08:00
Lasy
1e481edc67 增加“关闭时最小化到托盘”的设置 (#166)
添加托盘设置,调整主进程代码架构
2020-04-03 20:00:43 +08:00
lyswhut
12f02dda98 更新依赖 2020-03-31 15:49:44 +08:00
lyswhut
ef50d90a18 修复开发模式下页面无法刷新的问题 2020-03-31 15:46:19 +08:00
lyswhut
25ae72cd26 更新Windows 7下界面异常描述 2020-03-30 19:37:26 +08:00
lyswhut
eb8f83786c 更新更新日志 2020-03-29 23:15:44 +08:00
lyswhut
cd7b075016 添加空格 2020-03-29 23:12:28 +08:00
lyswhut
19068dc6b0 Merge branch 'master' into dev 2020-03-29 23:02:12 +08:00
lyswhut
93ba0bd807 修改换行符 2020-03-29 22:55:19 +08:00
Words
15a76486ef English updates and a Chinese string fault (#163)
* Update English language files

- 修正:`backup_part_export_list_desc`的文字描述问题
- 修正:英文翻译问题

Co-authored-by: Madoka☆Magica! <adsh@pku.edu.cn>
Co-authored-by: lyswhut <lyswhut@qq.com>
2020-03-29 22:47:05 +08:00
lyswhut
f01e367785 限制导航及窗口打开 2020-03-29 14:48:02 +08:00
lyswhut
9b536f8dc1 优化程序启动窗口显示机制 2020-03-28 10:50:31 +08:00
lyswhut
664a0e4ad8 完善符号转义 2020-03-28 10:42:46 +08:00
lyswhut
9ed64354fc 更新依赖到最新 2020-03-25 21:16:27 +08:00
lyswhut
f59a160249 修复字段为空时写入undefined的问题 2020-03-24 11:53:36 +08:00
lyswhut
cdd7774a73 添加软件启动时是否自动聚焦搜索框的设置 2020-03-24 09:47:36 +08:00
lyswhut
a10777d598 完善部分翻译 2020-03-24 09:10:23 +08:00
lyswhut
a4c5670409 新增FLAC格式音乐标签信息写入与封面嵌入 2020-03-22 18:33:51 +08:00
lyswhut
343c53b41c 更新win7界面显示异常标题 2020-03-21 23:28:44 +08:00
lyswhut
4c97bc34ce 修复下载管理刷新URL失败时不标记任务下载失败的问题 2020-03-21 23:08:46 +08:00
lyswhut
83f0ca918a 新增FLAC格式音乐标签信息写入 2020-03-21 22:31:02 +08:00
lyswhut
bc7c3968b6 更新地址协议 2020-03-20 20:15:21 +08:00
lyswhut
1aba217b1a 修复网易源某些歌曲提示没有可播放的音质的问题 2020-03-19 17:23:53 +08:00
lyswhut
a95e87a08f 更新依赖 2020-03-19 13:54:54 +08:00
lyswhut
b75e299b2f Merge branch 'master' into dev 2020-03-17 09:55:59 +08:00
lyswhut
3e63b49c3c 更新软件调用摄像头的说明 2020-03-17 09:34:43 +08:00
lyswhut
1eaf2372bb 略微减少列表行高 2020-03-16 18:27:16 +08:00
lyswhut
8b8400e5be 略微加深音量条底色 2020-03-16 14:40:51 +08:00
lyswhut
c6551c9ea3 优化子节点判断 2020-03-16 12:51:14 +08:00
lyswhut
b04c676288 更换反馈方式 2020-03-15 21:15:15 +08:00
lyswhut
01e2a2bdb2 发布0.17.0版本 2020-03-15 20:10:58 +08:00
lyswhut
670533807a 新增热搜词、历史搜索记录 2020-03-15 17:17:41 +08:00
lyswhut
9d1270374e 优化右上角最小化/关闭按钮布局 2020-03-15 00:15:52 +08:00
lyswhut
353e8bd0de 支持打开短链接歌单 2020-03-14 23:36:38 +08:00
lyswhut
9ca0ec82a8 修复下载列表标签切换及全选bug 2020-03-14 23:13:36 +08:00
lyswhut
bb5fd44750 更新歌单打开描述 2020-03-14 22:56:12 +08:00
lyswhut
1e435b0ff8 支持直接打开酷我手机版分享出来的歌单地址 2020-03-14 22:54:19 +08:00
lyswhut
bb080c2d18 优化歌单打开机制 2020-03-14 20:58:03 +08:00
lyswhut
91063075d3 新增发现新版本更新失败弹窗的忽略提醒按钮 2020-03-14 18:08:02 +08:00
lyswhut
ccaf485c91 修复数据导入Bug 2020-03-14 00:49:13 +08:00
lyswhut
125207226b 改变下载任务插入方式 2020-03-13 19:44:55 +08:00
lyswhut
393affbd90 优化选择器显示 2020-03-13 16:37:00 +08:00
lyswhut
4f06fe45d3 新增音源别名 2020-03-13 16:16:42 +08:00
lyswhut
ba1a981c87 修改默认窗口大小为重 2020-03-13 14:45:06 +08:00
lyswhut
6d51240a27 修复选择器bug,新增较小、较大窗口设置 2020-03-13 13:38:02 +08:00
lyswhut
527143405f 恢复更新超时时间 2020-03-13 12:24:50 +08:00
lyswhut
2808fdd3c0 添加供应链攻击科普链接 2020-03-13 12:22:19 +08:00
lyswhut
a2c84392f4 新增软件界面元素大小调整 2020-03-12 23:33:19 +08:00
lyswhut
3fdff4e6eb 完善翻译 2020-03-12 21:12:12 +08:00
lyswhut
dd41e00691 移除窗口恢复事件 2020-03-12 19:02:59 +08:00
lyswhut
29bcaa9558 更新依赖 2020-03-12 16:59:16 +08:00
lyswhut
3be3e8546f 修复鼠标右击复制列表内容时会复制音质标签文字的问题 2020-03-12 16:06:12 +08:00
lyswhut
0bbb760e61 完善音频输出功能 2020-03-10 23:31:25 +08:00
lyswhut
4f238f4f62 完善音频输出设置功能 2020-03-10 12:40:47 +08:00
lyswhut
a244c6d5e3 Merge branch 'md' into dev 2020-03-10 12:20:14 +08:00
lyswhut
aa5765971e 完善选择器 2020-03-07 13:21:13 +08:00
lyswhut
2a66edd1c5 完善默认值显示 2020-03-07 11:55:31 +08:00
lyswhut
a6e86e8d6b 修复歌单详情处于加载状态时无法返回的问题 2020-03-07 10:52:43 +08:00
lyswhut
f30cb9da59 Merge branch 'dev' into md 2020-03-03 12:31:40 +08:00
lyswhut
e94d17a922 添加启动参数说明 2020-03-02 16:21:40 +08:00
lyswhut
53f5c168ad 新增启动参数 search 2020-03-02 15:57:26 +08:00
lyswhut
4533f7b1d5 优化播放进度条的动画效果 2020-03-02 15:50:05 +08:00
lyswhut
b9398e882a 初步完善 2020-02-28 13:19:49 +08:00
lyswhut
66f19d72da 更新依赖 2020-02-28 13:18:44 +08:00
lyswhut
35e85cfdcb 修复文件导入顺序导致的恢复设置语言报错 2020-02-27 23:25:21 +08:00
lyswhut
6d6b63cce1 新增对主题名字的翻译 2020-02-27 23:21:28 +08:00
lyswhut
a7d5e77a1c 更新无法打开外部歌单描述 2020-02-26 11:16:51 +08:00
lyswhut
0332b22c4a 补上翻译 2020-02-23 23:56:09 +08:00
lyswhut
09a7974818 支持搜索源翻译 2020-02-19 22:11:48 +08:00
lyswhut
66d2f0d550 修复歌单标签翻译读取bug 2020-02-19 21:51:41 +08:00
lyswhut
d2556fed20 优化月里嫦娥皮肤侧栏鼠标悬浮颜色 2020-02-19 21:44:50 +08:00
lyswhut
49cd8536a7 新增无法打开外部歌单FAQ 2020-02-19 21:15:27 +08:00
lyswhut
b8f15bcca9 新增多语言设置 2020-02-19 20:41:34 +08:00
lyswhut
a17ba9f62c update issue template 2020-02-18 12:28:20 +08:00
lyswhut
a9aa9a2e20 发布0.16.0版本 2020-02-16 11:09:25 +08:00
lyswhut
43da07ca4c 优化版本对比机制 2020-02-15 22:16:16 +08:00
lyswhut
1b22abcd50 优化版本号对比机制 2020-02-15 21:02:47 +08:00
lyswhut
f85c83169d 设置响应时间限制 2020-02-15 19:39:50 +08:00
lyswhut
ecff344473 更新electron到8.0.1 2020-02-15 18:08:49 +08:00
lyswhut
cde380782f 从request模块切换到needle 2020-02-15 18:08:04 +08:00
lyswhut
d557149326 加载新列表时清空当前列表 2020-02-15 18:07:12 +08:00
lyswhut
ecdcb040ee 优化列表加载交互 2020-02-15 12:59:35 +08:00
lyswhut
e58471fe37 修复QQ源歌单热门标签歌单列表无法加载问题 2020-02-15 12:00:53 +08:00
lyswhut
30e66473db 修复酷狗歌单热门标签列表无法加载问题 2020-02-15 00:15:11 +08:00
lyswhut
5357ed3746 修复无结果时的错误处理 2020-02-14 23:57:21 +08:00
lyswhut
337f443cbf 优化音质标签判断显示逻辑 2020-02-14 19:25:23 +08:00
lyswhut
e7ad1b8496 优化各个主题音质标签颜色 2020-02-14 19:24:56 +08:00
lyswhut
aea01de449 更新软件界面无法显示解决方案 2020-02-13 15:22:34 +08:00
lyswhut
b7fb75a49e 更新issue模板 2020-02-13 14:54:50 +08:00
lyswhut
57752d09cd 调整火影主题翻页器背景颜色 2020-02-12 15:03:23 +08:00
lyswhut
bd395f557a 添加单独win x64 x32安装包构建 2020-02-11 17:08:25 +08:00
lyswhut
2d865d8fed 添加单独win x64 x32安装包构建 2020-02-11 16:45:14 +08:00
lyswhut
5bff74e7a9 移除多个空格 2020-02-10 18:12:38 +08:00
lyswhut
a9e3723764 新增在搜索框鼠标右击时自动粘贴剪贴板的文本到搜索框中 2020-02-10 18:05:16 +08:00
lyswhut
b811227c41 更新electron到 8.0.0 2020-02-10 17:25:58 +08:00
lyswhut
4896c4dda5 新增在列表可选内容区域鼠标右击时自动复制列表已选文字的功能 2020-02-10 17:25:07 +08:00
lyswhut
b4ee1ade2d 修正描述 2020-02-07 23:09:23 +08:00
lyswhut
a6e2308282 修正邮箱地址 2020-02-03 23:01:49 +08:00
lyswhut
f56c42f353 修复某些情况下暂停任务会自动开始任务的问题 2020-02-01 14:45:52 +08:00
lyswhut
5edf51810d 新增下载失败时显示搜索按钮 2020-02-01 14:44:15 +08:00
lyswhut
81985b0e31 添加主进程代码编译错误输出 2020-01-31 12:00:10 +08:00
lyswhut
163830f1bd 更新electron到7.1.11 2020-01-31 11:59:20 +08:00
lyswhut
867ae2991c 允许选中列表内的部分文字,优化界面 2020-01-30 11:54:04 +08:00
lyswhut
ee3d04ba23 更新更新提示 2020-01-29 20:45:26 +08:00
lyswhut
71dd8c14f8 更新软件启动后,界面无法显示的解决方案 2020-01-29 20:33:45 +08:00
lyswhut
88dc9c2a74 修复大窗口时设置的音乐来源选项不换行的问题 2020-01-28 13:49:05 +08:00
lyswhut
98f012de4d 更新electron到 7.1.10 2020-01-28 12:39:42 +08:00
lyswhut
c85a036ac6 修复启用透明窗口鼠标不穿透的bug 2020-01-28 12:38:29 +08:00
lyswhut
1f8b632d95 修正架构包名 2020-01-23 17:50:44 +08:00
lyswhut
59dd56e542 发布0.15.0版本 2020-01-23 01:32:22 +08:00
lyswhut
1bfa8dcb3f bug 修复 2020-01-23 01:26:46 +08:00
lyswhut
1b381af7a7 修复歌曲下载列表无法加载的问题 2020-01-23 01:01:02 +08:00
lyswhut
2bc4912416 发布0.14.1版本 2020-01-22 22:31:39 +08:00
lyswhut
474f0d8291 修正描述 2020-01-22 22:31:04 +08:00
lyswhut
231fe54408 修复由于旧版配置文件迁移出错导致的软件界面无法显示的问题 2020-01-22 22:30:50 +08:00
lyswhut
78bef70735 发布0.14.0版本 2020-01-22 19:50:34 +08:00
lyswhut
ce7247e209 新增获取版本信息的备用链接 2020-01-22 10:12:10 +08:00
lyswhut
1d807e2a89 更新Windows 7 下界面异常问题描述 2020-01-20 13:46:41 +08:00
lyswhut
749141c10e 适配输入框提示文本颜色 2020-01-19 18:05:16 +08:00
lyswhut
e2c7c0596c 修复标签列表颜色适配 2020-01-19 17:43:40 +08:00
lyswhut
392cd72f83 优化新年快乐皮肤 2020-01-19 17:32:43 +08:00
lyswhut
340a9d937b 优化音质标签颜色 2020-01-19 17:26:53 +08:00
lyswhut
5d7ad836db 新增“新年快乐”主题 2020-01-19 16:00:01 +08:00
lyswhut
f8e449b017 新增不强制win7开启透明效果即可使用 2020-01-19 13:56:54 +08:00
lyswhut
bb0b59080a 更新依赖到最新 2020-01-17 21:52:36 +08:00
lyswhut
95b08c2406 修复无搜索结果的处理 2020-01-17 21:26:31 +08:00
lyswhut
3ef5e0e55a 更新 Electron 到 7.1.8 2020-01-14 13:06:45 +08:00
lyswhut
ae9b4bc2f5 更换migu搜索接口 2020-01-13 13:20:04 +08:00
lyswhut
914e738931 修复在线音乐列表获取失败时无限循环请求的问题 2020-01-13 12:49:09 +08:00
lyswhut
e4c19c0f2a 恢复QQ音乐源128k音质试听 2020-01-11 17:45:22 +08:00
lyswhut
54354518d0 简化写法 2020-01-10 22:19:24 +08:00
lyswhut
d36e21ab56 更新软件依赖到最新 2020-01-10 22:14:21 +08:00
lyswhut
b496e3c667 更换songmid的id值 2020-01-10 22:13:53 +08:00
lyswhut
d10434285f 更新关于软件说明 2020-01-10 22:13:10 +08:00
lyswhut
d6c8886fdb 更新“软件启动后,界面无法显示”的问题解决方案 2020-01-07 13:11:36 +08:00
lyswhut
51e3c8605c 调整列表字体颜色深度 2020-01-06 12:01:33 +08:00
lyswhut
d4d6b9c9aa 修复咪咕源无法搜索的问题 2020-01-06 00:30:52 +08:00
lyswhut
0c9c3c61fc 更新关于软件说明 2020-01-03 15:47:51 +08:00
lyswhut
0228850d6d 新增各大平台歌单热门标签显示 2019-12-31 16:12:46 +08:00
lyswhut
529078dc67 当歌曲有无损音质时隐藏高品质标签 2019-12-29 13:53:54 +08:00
lyswhut
aadb68ba08 减淡各个主题的歌曲列表分隔线颜色 2019-12-28 17:26:23 +08:00
lyswhut
c81171a39e 监听所有未捕获错误事件并记录到日志中 2019-12-27 21:42:19 +08:00
lyswhut
a50ecff189 将软件设置与播放列表分离存储成两个文件 2019-12-23 19:24:35 +08:00
lyswhut
73321829ae 给代理添加提示 2019-12-23 16:09:52 +08:00
lyswhut
e88c837482 添加软件无法联网帮助 2019-12-22 14:34:52 +08:00
lyswhut
2b263cae87 修复更新弹窗底部文字颜色适配问题 2019-12-17 12:56:25 +08:00
lyswhut
e93052f0cb 发布0.13.1版本 2019-12-16 21:19:27 +08:00
lyswhut
9539083f7e 降级electron到7.1.2 2019-12-16 21:04:22 +08:00
lyswhut
8f26eb1c69 修复全局更新弹窗无法遮盖搜索框的问题 2019-12-16 00:24:32 +08:00
lyswhut
a126e5b4c8 发布0.13.0版本 2019-12-15 21:33:46 +08:00
lyswhut
033c3cd8e9 多修复选框不定状态到选中的Bug 2019-12-15 21:23:52 +08:00
lyswhut
50d029c671 移除Q音源的试听与下载 2019-12-15 21:03:19 +08:00
lyswhut
6a3f7e6150 修复搜索建议列表被弹出层覆盖的问题 2019-12-15 19:18:31 +08:00
lyswhut
aadfbefbe9 更新electron及vue到最新 2019-12-14 14:01:53 +08:00
lyswhut
edbcaf0f90 优化“信口雌黄”皮肤配色 2019-12-14 13:54:22 +08:00
lyswhut
207427e993 新增“离开搜索界面时清空搜索列表”设置 2019-12-13 13:34:35 +08:00
lyswhut
e109dd876a 修正缓存描述 2019-12-13 13:09:44 +08:00
lyswhut
64ac69c48b 聚合搜索新增音源显示 2019-12-11 16:05:07 +08:00
lyswhut
652b06c116 更新依赖到最新 2019-12-06 20:55:12 +08:00
lyswhut
654035a469 update issue template 2019-12-04 10:45:31 +08:00
lyswhut
cd50e0086b update issue template 2019-12-03 13:03:09 +08:00
lyswhut
66a119e9dc 新增搜索框搜索建议键盘上下方向键选择功能 2019-12-02 20:46:27 +08:00
lyswhut
14ec7d48f6 更新接口文字描述 2019-12-01 14:29:26 +08:00
lyswhut
5ad5b211e9 发布0.12.1版本 2019-12-01 13:51:13 +08:00
lyswhut
aac4b6ccfe 将所有外部链接从默认浏览器打开 2019-12-01 13:45:48 +08:00
lyswhut
cfc6967fdc 优化链接点击效果 2019-12-01 13:42:16 +08:00
lyswhut
8a0b960985 更新依赖到最新 2019-12-01 12:38:54 +08:00
lyswhut
bd260c3dc5 移除多余的字 2019-12-01 12:34:48 +08:00
lyswhut
203dff8d98 修复酷我源排行榜、歌单详情列表里的歌曲音质匹配问题 2019-11-30 18:36:44 +08:00
lyswhut
ca56089a3e 取消对导出数据的格式化 2019-11-29 21:47:13 +08:00
lyswhut
a012d1b927 更新依赖到最新 2019-11-29 21:35:42 +08:00
lyswhut
0af322a3a8 优化tab布局 2019-11-29 21:33:11 +08:00
lyswhut
8d743803c8 优化滚动方法 2019-11-29 00:01:04 +08:00
lyswhut
63fed77c5b 更新安装失败、缺少dll帮助 2019-11-25 16:58:16 +08:00
lyswhut
f2077dca04 新增数据传输结束时文件下载完成情况的判断 2019-11-25 11:44:31 +08:00
lyswhut
cccfb6a08a 歌曲无封面时下载报错的问题 2019-11-25 11:41:51 +08:00
lyswhut
fa6dead83d 更新依赖到最新 2019-11-24 19:38:45 +08:00
lyswhut
605418d750 更新electron到7.1.2 2019-11-21 20:20:31 +08:00
lyswhut
8aa869b2e4 更新appImage包的分类 2019-11-20 13:19:26 +08:00
lyswhut
558b6e0ccf 发布0.12.0版本 2019-11-17 12:29:23 +08:00
lyswhut
6a695368da 修复Linux图标显示问题 2019-11-17 12:28:01 +08:00
lyswhut
ce89f29aeb 更新Linux图标配置 2019-11-17 10:50:10 +08:00
lyswhut
6d935d8589 更换下载库 2019-11-16 20:16:09 +08:00
lyswhut
967093328f 添加数据保存节流 2019-11-16 20:15:27 +08:00
lyswhut
48e1da128d 修复封面下载出错问题 2019-11-16 20:13:48 +08:00
lyswhut
369de684a6 add electron version tag 2019-11-16 20:12:42 +08:00
lyswhut
d5f65eea06 更新常见问题链接 2019-11-13 21:11:14 +08:00
lyswhut
8e5deb5bf4 添加软件启动后,界面无法显示的问题 2019-11-11 23:36:22 +08:00
lyswhut
df653258bb 更换成commonjs写法 2019-11-10 15:39:40 +08:00
lyswhut
ed28a59fcb 发布0.11.0版本 2019-11-10 13:29:54 +08:00
lyswhut
adc46411b2 新增杀毒软件提示有病毒或恶意行为说明 2019-11-10 13:27:53 +08:00
lyswhut
fcc4d666ec 移除残留remote模块的使用 2019-11-10 01:50:56 +08:00
lyswhut
9d89f5d48d 更新electron到7.1.1 2019-11-09 02:14:49 +08:00
lyswhut
88c62e01ad 新增下载管理的任务状态分类 2019-11-08 21:07:37 +08:00
lyswhut
1823598a8b 新增歌曲缓冲定时器 2019-11-07 21:56:00 +08:00
lyswhut
3fd22988c1 修正获取新版信息失败提示内容 2019-11-06 23:18:27 +08:00
lyswhut
a3ade4cde2 默认使用临时接口 2019-11-06 21:53:12 +08:00
lyswhut
55c2286eca 更新electron到7.1.0 2019-11-06 01:04:08 +08:00
lyswhut
1afa050698 移除log 2019-11-03 17:29:00 +08:00
lyswhut
dfa15c6952 优化更新弹窗机制及其内容描述 2019-11-03 17:18:44 +08:00
lyswhut
a2af321c5e 分离主进程与渲染进程的功能,禁用remote模块 2019-11-03 09:53:19 +08:00
lyswhut
fddfaf23ce 更新配置 2019-11-02 11:51:49 +08:00
lyswhut
ae0ee2048a 新增nodejs版本输出 2019-11-02 11:42:31 +08:00
lyswhut
6659d1fe43 更新nodejs版本配置 2019-11-02 11:22:27 +08:00
lyswhut
f601e61f8d 发布0.10.0版本 2019-11-02 11:00:21 +08:00
lyswhut
f8ed7a112a 更新依赖到最新,更新electron到7.0.1 2019-11-02 10:59:12 +08:00
lyswhut
b0d6181bd7 完善token获取机制 2019-10-31 20:26:53 +08:00
lyswhut
82843b14b4 更新依赖 2019-10-31 00:42:48 +08:00
lyswhut
0df3ca3c5f 新增音乐sdk初始化方法 2019-10-30 22:29:14 +08:00
lyswhut
c881f8e886 更新描述 2019-10-30 01:43:27 +08:00
lyswhut
f1bf274de1 修复咪咕源无法播放的问题 2019-10-29 13:17:06 +08:00
lyswhut
91e4e9c2d5 简化写法 2019-10-28 22:48:30 +08:00
lyswhut
63a5f94a67 修复酷我源搜索提示、排行榜接口挂掉的问题 2019-10-28 22:42:01 +08:00
lyswhut
1bd8694262 减少播放时对CPU与GPU的使用 2019-10-27 17:35:29 +08:00
lyswhut
501231adff 更新依赖到最新,更新electron到7.0.0 2019-10-27 17:34:11 +08:00
lyswhut
3a033b66c4 发布0.9.1版本 2019-10-27 12:00:04 +08:00
lyswhut
46aacba037 修复没有配置文件时程序启动出错的问题 2019-10-27 11:58:55 +08:00
lyswhut
10ef80da75 发布0.9.0版本 2019-10-27 10:54:16 +08:00
lyswhut
75b7897ad6 更新安装版安装失败问题解决方法 2019-10-27 10:47:13 +08:00
lyswhut
14423e0eb3 修复搜索框bug 2019-10-27 10:00:43 +08:00
lyswhut
fe44581a61 修复搜索提示失效的问题 2019-10-25 21:36:07 +08:00
lyswhut
0d612bd6df 修改滚动高度 2019-10-24 15:16:59 +08:00
lyswhut
b7eba95ab2 新增定位当前播放歌曲 2019-10-24 14:04:44 +08:00
lyswhut
59091a5ea9 更改URL重试刷新次数 2019-10-22 01:36:25 +08:00
lyswhut
31e8b466cf 新增窗口大小设置 2019-10-22 01:25:03 +08:00
lyswhut
c97bc5edfc 修复单选框组件v-model为数字时的 bug 2019-10-21 23:05:26 +08:00
lyswhut
74f8e9544b 发布0.8.2版本 2019-10-20 18:21:43 +08:00
lyswhut
0a5e7c44ff 容旧版酷我源搜索列表过滤128k音质的bug 2019-10-20 18:20:58 +08:00
lyswhut
5c32160a58 发布0.8.1版本 2019-10-20 10:11:36 +08:00
lyswhut
2fc81c03ec 修复酷我源搜索歌曲结果处理问题 2019-10-20 02:48:28 +08:00
lyswhut
cc485df42f 移除192k试听 2019-10-20 00:32:36 +08:00
lyswhut
d575dd24ca 发布0.8.0版本 2019-10-19 12:08:53 +08:00
lyswhut
e47586cea3 更新请求头 2019-10-19 12:04:15 +08:00
lyswhut
1ce63c7550 修复酷狗歌曲无封面时报错的问题 2019-10-19 11:48:19 +08:00
lyswhut
36d69da3b7 缓存歌单详情列表数据 2019-10-19 11:47:15 +08:00
lyswhut
529be08420 优化音量条交互视觉效果 2019-10-18 21:47:10 +08:00
lyswhut
ffe11c7015 更新与分离常见问题 2019-10-18 18:04:28 +08:00
lyswhut
76b796bde7 修复歌单地址无效时无限重复请求的bug 2019-10-18 17:46:33 +08:00
lyswhut
f81715f07f 更新歌单导入描述 2019-10-18 13:32:01 +08:00
lyswhut
ec3f667b75 修复音量调整Bug,新增拖动调整音量 2019-10-18 12:03:01 +08:00
lyswhut
87f0b4fd17 修复传参问题 2019-10-17 22:41:24 +08:00
lyswhut
c7e95c5166 新增各平台通过输入歌单链接或歌单ID打开歌单详情列表 2019-10-17 17:01:49 +08:00
lyswhut
6ea0837cce 新增腾讯、网易云歌单链接打开 2019-10-17 14:05:29 +08:00
lyswhut
59627e048f 分离搜索框业务逻辑,优化搜索框搜索体验 2019-10-17 10:58:09 +08:00
lyswhut
45fea5726b 修复歌曲音质不存在时仍然播放或下载的Bug 2019-10-16 21:26:59 +08:00
lyswhut
e539f29f6d 修复音质过滤导致的歌单无法显示问题 2019-10-16 21:00:46 +08:00
lyswhut
1d2810e98f 新增网易云源歌单 2019-10-16 19:54:13 +08:00
lyswhut
1cbafc9750 新增网易云源歌曲搜索 2019-10-16 10:38:42 +08:00
lyswhut
e675f7ac06 更新描述 2019-10-16 00:59:19 +08:00
lyswhut
9dc9d3b1b7 修复网易云128k直接试听 2019-10-16 00:40:36 +08:00
lyswhut
a104ce688e 修复默认列表没有创建时无法显示收藏列表的Bug 2019-10-13 09:20:44 +08:00
lyswhut
2dd1ceb0b9 更新依赖到最新 2019-10-11 22:52:27 +08:00
lyswhut
9379328d96 修复QQ源歌单无法翻页Bug 2019-10-10 18:43:04 +08:00
lyswhut
d8969c327c 改变请求头 2019-10-10 13:24:14 +08:00
lyswhut
c3624fb7d6 Create LICENSE 2019-10-08 10:20:46 +08:00
lyswhut
b2de230100 remove license file 2019-10-08 10:19:46 +08:00
481 changed files with 72207 additions and 20422 deletions

View File

@@ -1,21 +0,0 @@
platform:
- x64
cache:
- node_modules
- '%APPDATA%\npm-cache'
- '%LOCALAPPDATA%\electron\Cache'
- '%LOCALAPPDATA%\electron-builder\Cache'
install:
- ps: Install-Product node 12 x64
- npm install
build_script:
- npm run publish:gh
test: off
branches:
only:
- master

View File

@@ -6,17 +6,20 @@
"corejs": "3",
"useBuiltIns": "usage"
}
],
[
"minify",
{
"builtIns": false,
"evaluate": false,
"mangle": false
}
]
// [
// "minify",
// {
// "builtIns": false,
// "evaluate": false,
// "mangle": false
// }
// ]
],
"plugins": [
"@babel/plugin-syntax-dynamic-import"
"@babel/plugin-syntax-dynamic-import",
"@babel/plugin-transform-modules-umd",
"@babel/plugin-transform-runtime",
"@babel/plugin-proposal-class-properties"
]
}

View File

@@ -1,9 +1,15 @@
{
"extends": "standard",
"extends": [
// "plugin:vue/vue3-recommended",
"standard"
],
"plugins": [
"html"
],
"parser": "babel-eslint",
"parser": "@babel/eslint-parser",
"parserOptions": {
"requireConfigFile": false
},
"rules": {
"no-new": "off",
"camelcase": "off",
@@ -16,9 +22,13 @@
"no-multiple-empty-lines": [1, {"max": 2}],
"comma-dangle": [2, "always-multiline"],
"standard/no-callback-literal": "off",
"prefer-const": "off"
"prefer-const": "off",
"no-labels": "off",
"node/no-callback-literal": "off",
"vue/multi-word-component-names": "off"
},
"settings": {
"html/html-extensions": [".html", ".vue"]
}
},
"ignorePatterns": ["vendors", "*.min.js", "dist", "node_modules"]
}

View File

@@ -1,17 +0,0 @@
---
name: 功能请求
about: 为这个项目提出一个想法
title: 例如添加xxx功能、优化xxx功能
labels: ''
assignees: ''
---
**描述您想要的解决方案**
简洁明了地描述您要发生的事情。
**描述您考虑过的替代方案**
对您考虑过的所有替代解决方案或功能的简洁明了的描述。
**其他内容**
在此处添加有关功能请求的任何其他上下文或屏幕截图。

40
.github/ISSUE_TEMPLATE/----.yml vendored Normal file
View File

@@ -0,0 +1,40 @@
name: ✨功能请求
description: 为这个项目提出一个想法请先查看常见问题及搜索issue列表中有无你要提的问题
title: "[Feature]: "
body:
- type: checkboxes
id: check-answer
attributes:
label: 解决方案检查
description: 请确保你已完成以下所有操作
options:
- label: 我已阅读常见问题(<https://lyswhut.github.io/lx-music-doc/desktop/faq>),但没有找到解决方案
required: true
- label: 我已搜索issue列表(<https://github.com/lyswhut/lx-music-desktop/issues?utf8=✓&q=>),但没有发现类似的问题
required: true
- type: textarea
id: problem-description
attributes:
label: 问题描述
description: 请添加清晰简洁的描述,说明你希望通过此功能请求解决的问题
validations:
required: true
- type: textarea
id: proposed-solution
attributes:
label: 描述你想要的解决方案
description: 简洁明了地描述你要发生的事情
validations:
required: true
- type: textarea
id: alternatives-considered
attributes:
label: 描述你考虑过的替代方案
description: 对你考虑过的所有替代解决方案或功能的简洁明了的描述
validations:
required: false
- type: textarea
id: additional-information
attributes:
label: 附加信息
description: 如果你的问题需要进一步解释,或者想要表达其他内容,请在此处添加更多信息。(直接把图片、视频拖到编辑框即可添加图片或视频)

View File

@@ -1,31 +0,0 @@
---
name: 报告Bug
about: 创建报告以帮助我们改进
title: 例如:音乐无法播放
labels: ''
assignees: ''
---
**描述错误**
清楚简洁地说明错误是什么。
**重现**
重现行为的步骤:
1.转到“ ...”
2.点击“ ....”
3.向下滚动到“ ....”
4.看到错误
**预期行为**
对您期望发生的事情的简洁明了的描述。
**截图**
如果适用,请添加屏幕截图以帮助解释您的问题。
**环境:**
  -操作系统及版本:[例如Windows 10 64位 18362.156]
  -软件安装包及版本:[例如Windows 64位绿色版 1.0.0]
**其他内容**
在此处添加有关该问题的任何其他上下文。

55
.github/ISSUE_TEMPLATE/--bug.yml vendored Normal file
View File

@@ -0,0 +1,55 @@
name: 🐞报告Bug
description: 报告bug请先查看常见问题及搜索issue列表中有无你要提的问题
title: "[Bug]: "
body:
- type: checkboxes
id: check-answer
attributes:
label: 解决方案检查
description: 请确保你已完成以下所有操作
options:
- label: 我已阅读常见问题(<https://lyswhut.github.io/lx-music-doc/desktop/faq>),并没有找到解决方案
required: true
- label: 我已搜索issue列表(<https://github.com/lyswhut/lx-music-desktop/issues?utf8=✓&q=>),并没有发现类似的问题
required: true
- type: textarea
id: expected-behavior
attributes:
label: 预期行为
description: 对期望发生的事情的清晰简明描述
validations:
required: true
- type: textarea
id: actual-behavior
attributes:
label: 实际行为
description: 对实际发生的事情的清晰简明描述
validations:
required: true
- type: input
id: version
attributes:
label: Lx Music 版本
description: 你使用什么版本的LX Music
placeholder: 1.15.0
validations:
required: true
- type: input
id: last-known-working-version
attributes:
label: 最后正常的版本
description: 如果有,请在此处填写最后正常的版本是多少?
placeholder: 1.15.0
- type: input
id: operating-system-version
attributes:
label: 操作系统版本
description: 您使用的是什么操作系统版本?在 Windows 上,单击开始按钮 > 设置 > 系统 > 关于;在 macOS 上,单击 Apple 菜单 > 关于本机;在 Linux 上,使用 lsb_release 或 uname -a
placeholder: "例如 Windows 10 版本 1909、macOS Catalina 10.15.7 或 Ubuntu 20.04"
validations:
required: true
- type: textarea
id: additional-information
attributes:
label: 附加信息
description: 如果你的问题需要进一步解释,或者你所遇到的问题不容易重现,请在此处添加更多信息。(直接把图片、视频拖到编辑框即可添加图片或视频)

254
.github/workflows/beta-pack.yml vendored Normal file
View File

@@ -0,0 +1,254 @@
name: Build Beta
on:
push:
branches:
- beta
jobs:
Windows:
name: Windows
runs-on: windows-latest
steps:
- name: Check out git repository
uses: actions/checkout@v2
- name: Install Node.js
uses: actions/setup-node@v2
with:
node-version: '16'
- name: Cache file
uses: actions/cache@v2
with:
path: |
node_modules
%APPDATA%\npm-cache
%LOCALAPPDATA%\electron\Cache
%LOCALAPPDATA%\electron-builder\Cache
key: ${{ runner.os }}-build-caches-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-
- name: Install Dependencies
run: |
npm install npm@8.5 -g
npm install
- name: Build src code
run: npm run build:src
- name: Build Package Setup x64
run: npm run pack:win:setup:x64
- name: Upload Artifact Setup x64
uses: actions/upload-artifact@v2
with:
name: lx-music-desktop-x64-Setup
path: build/* x64 Setup.exe
- name: Build Package Setup x86
run: npm run pack:win:setup:x86
- name: Upload Artifact Setup x86
uses: actions/upload-artifact@v2
with:
name: lx-music-desktop-x86-Setup
path: build/* x86 Setup.exe
- name: Build Package Setup arm64
run: npm run pack:win:setup:arm64
- name: Upload Artifact Setup arm64
uses: actions/upload-artifact@v2
with:
name: lx-music-desktop-arm64-Setup
path: build/* arm64 Setup.exe
- name: Build Package Setup x86_64
run: npm run pack:win:setup:x86_64
- name: Upload Artifact Setup x86_64
uses: actions/upload-artifact@v2
with:
name: lx-music-desktop-x86_64-Setup
path: build/*x86_64 Setup.exe
- name: Build Package 7z x64
run: npm run pack:win:7z:x64
- name: Upload Artifact 7z x64
uses: actions/upload-artifact@v2
with:
name: lx-music-desktop-win_x64-green
path: build/*win_x64 green.7z
- name: Build Package 7z x86
run: npm run pack:win:7z:x86
- name: Upload Artifact 7z x86
uses: actions/upload-artifact@v2
with:
name: lx-music-desktop-win_x86-green
path: build/*win_x86 green.7z
- name: Build Package 7z arm64
run: npm run pack:win:7z:arm64
- name: Upload Artifact 7z arm64
uses: actions/upload-artifact@v2
with:
name: lx-music-desktop-win_arm64-green
path: build/*win_arm64 green.7z
- name: Generate file MD5
run: |
cd build
Get-FileHash *.exe,*.7z -Algorithm MD5 | Format-List
Mac:
name: Mac
runs-on: macos-latest
steps:
- name: Check out git repository
uses: actions/checkout@v2
- name: Install Node.js
uses: actions/setup-node@v2
with:
node-version: '16'
- name: Cache file
uses: actions/cache@v2
with:
path: |
node_modules
$HOME/.cache/electron
$HOME/.cache/electron-builder
$HOME/.npm/_prebuilds
key: ${{ runner.os }}-build-caches-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-
- name: Install Dependencies
run: |
npm install npm@8.5 -g
npm install
- name: Build src code
run: npm run build:src
- name: Build Package dmg
run: |
npm run pack:mac:dmg
npm run pack:mac:dmg:arm64
env:
ELECTRON_CACHE: $HOME/.cache/electron
ELECTRON_BUILDERCACHE: $HOME/.cache/electron-builder
- name: Upload Artifact dmg
uses: actions/upload-artifact@v2
with:
name: lx-music-desktop-mac-dmg
path: |
build/*.dmg
!build/*-arm64.dmg
- name: Upload Artifact dmg
uses: actions/upload-artifact@v2
with:
name: lx-music-desktop-mac-dmg-arm64
path: build/*-arm64.dmg
- name: Generate file MD5
run: |
cd build
md5 *.dmg
Linux:
name: Linux
runs-on: ubuntu-latest
steps:
- name: Install package
run: sudo apt-get update && sudo apt-get install -y rpm libarchive-tools
- name: Check out git repository
uses: actions/checkout@v2
- name: Install Node.js
uses: actions/setup-node@v2
with:
node-version: '16'
- name: Cache file
uses: actions/cache@v2
with:
path: |
node_modules
$HOME/.cache/electron
$HOME/.cache/electron-builder
$HOME/.npm/_prebuilds
key: ${{ runner.os }}-build-caches-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-
- name: Install Dependencies
run: |
npm install npm@8.5 -g
npm install
- name: Build src code
run: npm run build:src
- name: Build Package deb x64
run: npm run pack:linux:deb:x64
- name: Upload Artifact deb x64
uses: actions/upload-artifact@v2
with:
name: lx-music-desktop-deb-x64
path: build/* x64.deb
- name: Build Package deb x86
run: npm run pack:linux:deb:x86
- name: Upload Artifact deb x86
uses: actions/upload-artifact@v2
with:
name: lx-music-desktop-deb-x86
path: build/* x86.deb
- name: Build Package deb arm64
run: npm run pack:linux:deb:arm64
- name: Upload Artifact deb arm64
uses: actions/upload-artifact@v2
with:
name: lx-music-desktop-deb-arm64
path: build/* arm64.deb
- name: Build Package deb armv7l
run: npm run pack:linux:deb:armv7l
- name: Upload Artifact deb armv7l
uses: actions/upload-artifact@v2
with:
name: lx-music-desktop-deb-armv7l
path: build/* armv7l.deb
- name: Build Package x64 appImage
run: npm run pack:linux:appImage
- name: Upload Artifact x64 appImage
uses: actions/upload-artifact@v2
with:
name: lx-music-desktop-x64-appImage
path: build/* x64.AppImage
- name: Build Package x64 rpm
run: npm run pack:linux:rpm
- name: Upload Artifact x64 rpm
uses: actions/upload-artifact@v2
with:
name: lx-music-desktop-x64-rpm
path: build/* x64.rpm
- name: Build Package x64 pacman
run: npm run pack:linux:pacman
- name: Upload Artifact x64 pacman
uses: actions/upload-artifact@v2
with:
name: lx-music-desktop-x64-pacman
path: build/* x64.pacman
- name: Generate file MD5
run: |
cd build
md5sum *.deb *.rpm *.pacman *.AppImage

157
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,157 @@
name: Build
on:
push:
branches:
- master
jobs:
Windows:
name: Windows
runs-on: windows-latest
steps:
- name: Check out git repository
uses: actions/checkout@v2
- name: Install Node.js
uses: actions/setup-node@v2
with:
node-version: '16'
- name: Cache file
uses: actions/cache@v2
with:
path: |
node_modules
%APPDATA%\npm-cache
%LOCALAPPDATA%\electron\Cache
%LOCALAPPDATA%\electron-builder\Cache
key: ${{ runner.os }}-build-caches-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-
- name: Install Dependencies
run: |
npm install npm@8.5 -g
npm install
- name: Build src code
run: npm run build:src
- name: Release package
run: |
npm run publish:win:setup:x64:always
npm run publish:win:setup:x86
npm run publish:win:setup:arm64
npm run publish:win:setup:x86_64
npm run publish:win:7z:x64
npm run publish:win:7z:x86
npm run publish:win:7z:arm64
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BT_TOKEN: ${{ secrets.BT_TOKEN }}
- name: Generate file MD5
run: |
cd build
Get-FileHash *.exe,*.7z -Algorithm MD5 | Format-List
Mac:
name: Mac
runs-on: macos-latest
steps:
- name: Check out git repository
uses: actions/checkout@v2
- name: Install Node.js
uses: actions/setup-node@v2
with:
node-version: '16'
- name: Cache file
uses: actions/cache@v2
with:
path: |
node_modules
$HOME/.cache/electron
$HOME/.cache/electron-builder
$HOME/.npm/_prebuilds
key: ${{ runner.os }}-build-caches-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-
- name: Install Dependencies
run: |
npm install npm@8.5 -g
npm install
- name: Build src code
run: npm run build:src
- name: Release package
run: |
npm run publish:mac:dmg:always
npm run publish:mac:dmg:arm64
env:
ELECTRON_CACHE: $HOME/.cache/electron
ELECTRON_BUILDERCACHE: $HOME/.cache/electron-builder
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BT_TOKEN: ${{ secrets.BT_TOKEN }}
- name: Generate file MD5
run: |
cd build
md5 *.dmg
Linux:
name: Linux
runs-on: ubuntu-latest
steps:
- name: Install package
run: sudo apt-get update && sudo apt-get install -y rpm libarchive-tools
- name: Check out git repository
uses: actions/checkout@v2
- name: Install Node.js
uses: actions/setup-node@v2
with:
node-version: '16'
- name: Cache file
uses: actions/cache@v2
with:
path: |
node_modules
$HOME/.cache/electron
$HOME/.cache/electron-builder
$HOME/.npm/_prebuilds
key: ${{ runner.os }}-build-caches-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-
- name: Install Dependencies
run: |
npm install npm@8.5 -g
npm install
- name: Build src code
run: npm run build:src
- name: Release package
run: |
npm run publish:linux:deb:x64:always
npm run publish:linux:deb:x86
npm run publish:linux:deb:arm64
npm run publish:linux:deb:armv7l
npm run publish:linux:appImage
npm run publish:linux:rpm
npm run publish:linux:pacman
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BT_TOKEN: ${{ secrets.BT_TOKEN }}
- name: Generate file MD5
run: |
cd build
md5sum *.deb *.rpm *.pacman *.AppImage

14
.ncurc.js Normal file
View File

@@ -0,0 +1,14 @@
module.exports = {
upgrade: true,
reject: [
'electron',
'chalk',
'del',
],
// target: 'newest',
// filter: [
// /^vue/,
// 'electron-builder',
// 'electron-updater',
// ],
}

View File

@@ -1,43 +0,0 @@
matrix:
include:
- os: osx
osx_image: xcode10.2
language: node_js
node_js: "12"
env:
- ELECTRON_CACHE=$HOME/.cache/electron
- ELECTRON_BUILDER_CACHE=$HOME/.cache/electron-builder
- os: linux
language: node_js
node_js: "12"
dist: trusty
services: docker
language: generic
cache:
directories:
- node_modules
- $HOME/.cache/electron
- $HOME/.cache/electron-builder
- $HOME/.npm/_prebuilds
notifications:
email: false
script:
- |
if [ "$TRAVIS_OS_NAME" == "linux" ]; then
npm install && npm run publish:gh:linux
else
npm run publish:gh:mac
fi
before_cache:
- rm -rf $HOME/.cache/electron-builder/wine
# only run this script on pull requests and merges into
# the 'master' and 'prod' branches
branches:
only:
- master

14
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,14 @@
{
"i18n-ally.localesPaths": [
"src/lang"
],
// "i18n-ally.fullReloadOnChanged": true,
"i18n-ally.keystyle": "nested",
"i18n-ally.displayLanguage": "zh-cn",
"i18n-ally.sourceLanguage": "zh-cn",
"i18n-ally.translate.engines": [
"google-cn",
"google"
],
"i18n-ally.sortKeys": true
}

File diff suppressed because it is too large Load Diff

565
FAQ.md Normal file
View File

@@ -0,0 +1,565 @@
# lx-music-desktop 常见问题
本文档已迁移到:<https://lyswhut.github.io/lx-music-doc/desktop/faq>
在阅读本常见问题后仍然无法解决你的问题请提交issue或者加企鹅群`830125506`反馈(无事勿加,入群先看群公告),反馈时请**注明**已阅读常见问题!
## ~~软件为什么没有桌面歌词与自定义列表功能~~
洛雪音乐的最初定位不是作为播放器开发的,它主要用于**查找歌曲**,软件的播放功能仅用于试听,不建议用作为常用播放器使用。
## 音乐播放列表机制
1. 默认情况下,播放搜索列表、歌单列表、排行榜列表的歌曲时会自动将该歌曲添加到“我的列表”的试听列表后再播放,这与手动将歌曲添加到试听列表,再去试听列表找到这首歌点播放是等价的
2. 如果你想要播放多首歌曲,需要使用多选功能(若不知道如何多选请看常见问题)多选后,将这些歌曲添加到“我的列表”播放,或使用稍后播放功能播放
3. 第2条适用于搜索列表、歌单列表、排行榜列表、我的列表中的歌曲
4. 对于歌单详情列表除了可以使用第2条的方式播放外你可以点击详情页上面的播放按钮临时播放当前歌单或点击收藏将当前歌单收藏到“我的列表”后再去播放
5. 对于排行榜详情列表除了可以使用第2条的方式播放外你可以在右击排行榜名字后弹出的菜单中播放或收藏整个排行榜这与第四条的歌单中的播放、与收藏按钮功能一致
6. v1.18.0及之后新增了“双击列表里的歌曲时自动切换到当前列表播放”设置,默认关闭,此功能仅对歌单、排行榜有效
7. 将歌曲添加“稍后播放”后,它们会被放在一个优先级最高的特殊队列中,点击“下一曲”时会消耗该队列中的歌曲,并且无法通过“上一曲”功能播放该队列的上一首歌曲
8. 在切歌时若不是通过“上一曲”、“下一曲”功能切歌(例如直接点击“排行榜列表”、“我的列表”中的歌曲切歌),“稍后播放”队列将会被清空
## 可用的鼠标、键盘快捷操作
- 鼠标右击播放栏的歌曲图片封面可以定位当前播放的歌曲
- 鼠标右击播放栏进度条上的`LRC`按钮可以锁定/解锁桌面歌词
- 歌曲搜索框、歌单链接输入框内鼠标右击可以将当前剪贴板上的文字粘贴到输入框内
- 鼠标右击搜索界面中的单条搜索历史可以将其移除
- 歌曲列表内的文字在选中后,鼠标右击可以复制已选中的文字,此功能只对搜索、歌单、排行榜、我的列表中的列表有效
- 鼠标在播放详情页内右键双击可以关闭播放详情页
- 鼠标左击播放栏上的歌曲名字可以将它复制
- 鼠标右击设置-主题设置的“道法自然英文Auto”主题可以打开亮、暗主题设置窗口
- 歌曲搜索框的候选内容可以用键盘上下方向键选择,按回车键搜索已选内容
- 在歌单详情页按退格键可以返回歌单列表
- 歌曲列表中可以使用`Ctrl``Shift`键进行多选这类似Windows下的文件选择详情看常见问题列表多选部分
- 在我的列表内可以使用`Ctrl + f`键打开搜索框进行列表内歌曲搜索,搜索框按`Esc`键可以关闭搜索框,搜索框内按上下方向键可以选择歌曲,按`回车`键跳转到已选歌曲,按`Ctrl + 回车`可以跳转并播放已选歌曲
- 在我的列表按住`Ctrl`键可以进入列表拖动模式,此时可以用鼠标拖动列表调整列表的位置
- 编辑列表名时按`Esc`键可以取消编辑
-`F11`可以进入、退出全屏状态v1.19.0新增)
- 在歌曲添加弹窗中,若按住`Ctrl`键后再点击列表名将不会自动关闭添加窗口这对想要将同一首一批歌曲添加到多个列表时会很有用v1.22.0新增)
在macOS上`Ctrl`键对应`Command`
## 歌曲无法试听与下载
### 所有歌曲都提示 `请求异常😮,可以多试几次,若还是不行就换一首吧。。。`
尝试更换网络,如切换到移动网络,若移动网络还是不行则尝试开关下手机的飞行模式后再试,<br>
若使用家庭网络的话可尝试将光猫断电5分钟左右再通电联网后播放。
### 提示 `getaddrinfo EAI_AGAIN ...` 或 `无法连接到服务器`
尝试在在浏览器打开这个地址`http://ts.tempmusics.tk`浏览器显示404是正常的如果不是404那就证明所在网络无法访问接口服务器。
若网页无法打开或打开来不是404则可能是DNS的问题可以尝试以下办法
1. 将DNS改成自动获取试试改完可能需要清理下系统DNS缓存才生效
2. 手动把DNS改一下不要用360的DNS可以把DNS改成`223.6.6.6``8.8.8.8`改完可能需要清理下系统DNS缓存才生效
改完DNS后可能需要重启软件才生效
### 通用解决方法
尝试按以下顺序解决:
1. 尝试更新到最新版本
2. 尝试切换其他歌曲(或直接搜索该歌曲),若全部歌曲都无法试听与下载则进行下一步
3. 尝试到 设置-音乐来源 切换到其他接口
4. 尝试切换网络,比如用手机开热点(所有歌曲都提示请求异常时可通过此方法解决,或等一两天后再试)
5. 若还不行请到这个链接查看详情:<https://github.com/lyswhut/lx-music-desktop/issues/5>
6. 若没有在第5条链接中的第一条评论中看到接口无法使用的说明则应该是你网络无法访问接口服务器的问题如果接口有问题我会在那里说明。
想要知道是不是自己网络的问题可以看看`http://ts.tempmusics.tk`能不能在浏览器打开浏览器显示404是正常的如果不是404那就证明所在网络无法访问接口服务器。
若网页无法打开或打来不是404则应该是DNS的问题可以尝试以下办法
1. 将DNS改成自动获取试试
2. 手动把DNS改一下不要用360的DNS可以把DNS改成`223.6.6.6``8.8.8.8`
### Windows版所有歌曲都提示 `音频加载错误5秒后切换下一首`
尝试关闭 Internet选项 的代理设置。
如果你不知道怎么做,可以尝试按以下步骤去做:
<kbd>windows</kbd>+<kbd>r</kbd>键打开“运行”窗口,输入`inetcpl.cpl`后回车,在打开的 Internet选项 对话框中,切换到 连接 -> 局域网设置,在弹出的新窗口中把代理服务器下的勾去掉,如果自动配置下的勾也有被勾选,那么建议也去掉,最后按确定关闭所有弹窗。
> 来源:<https://github.com/lyswhut/lx-music-desktop/issues/873#issuecomment-1146945724>
## 列表多选
从v0.18.0起,列表多选需要键盘配合,想要多选前需按下`Shift``Ctrl`键然后再鼠标点击想要选中的内容即可触发多选机制,其中`Shift`键用于连续选择,`Ctrl`键用于不连续选择,`Ctrl+a`用于快速全选。
- 例子一想要选中1-5项则先按下`Shift`键后,鼠标点击第一项,再点击第五项即可完成选择;
- 例子二想要选中1项与第3项则先按下`Ctrl`键后,鼠标点击第一项,再点击第三项即可完成选择;
- 例子三:想要选中当前列表的全部内容,键盘先按下`Ctrl`键不放,然后按`a`键,即可完成选择。
`Shift``Ctrl`选择时,鼠标点击未选中的内容会将其选中,点击已选择的内容会将其取消选择,若想全部取消选择,在不按`Shift``Alt`键的情况下,随意点击列表里的一项内容即可全部取消选择。(P.S`Ctrl`键对应Mac OS上的`Command`键)
注:选完后可用鼠标右击弹出右键菜单操作已选的内容
## 播放整个歌单或排行榜
播放在线列表内的歌曲需要将它们都添加到我的列表才能播放,你可以全选列表内的歌曲然后添加到现有列表或者新创建的列表,然后去播放该列表内的歌曲。
从v1.10.0起,你可以右击排行榜名字的弹出菜单中直接播放或收藏整个排行榜的歌曲。
## 无法打开外部歌单
不支持跨源打开歌单,请**确认**你需要打开的歌单平台是否与软件标签所写的**歌单源**对应(不一样的话请通过右上角切换歌单源);<br>
对于分享出来的歌单若打开失败可尝试先在浏览器中打开后再从浏览器地址栏复制URL地址到软件打开<br>
或者如果你知道歌单 id 也可以直接输入歌单 id 打开。<br>
注:网易源的“我喜欢”歌单无法在未登录的情况下打开,所以你需要手动创建一个歌单后将“我喜欢”里的歌曲移动到该歌单打开
### 打开网易源“我喜欢”歌单
由于网易源的“我喜欢”歌单需要登录才能打开从v1.13.0起提供了可以以注入token的方式打开网易源“我喜欢”歌单的功能现若想要打开此类歌单需要在歌单链接或id后面拼上 `###` 再加上有效的token拼接格式`[id|url]###token`例子最后面的xxxxxx替换成你的token
- `https://music.163.com/#/playlist?id=11332&userid=123456###xxxxxx`
- `11332###xxxxxx`
即:将 `歌单链接或者歌单ID``###``token` 这三者拼到一起。
#### `token`的获取方法
**注:`token`是你账号的临时身份令牌,不要随便泄露给他人**<br>
在浏览器打开登录网易云音乐并**登录**后,按`F12`,此时将会打开开发者窗口,然后按你使用的浏览器操作:
##### Chrome、360、QQ等浏览器
这些浏览器打开此窗口时界面可能是中文也可能是英文,英文的话按括号里的来
1. 点击窗口顶部`应用程序(application)`(若找不到此选项,则可能是被折叠起来了,看看顶部菜单的`>>`
2. 展开左侧 `Cookies`
3. 点击 `https://music.163.com`
4. 在右侧窗口找到 `名称(Name)``MUSIC_U` 的这行,这行的第二列(`值(Value)`)内的那串内容就是`token`,双击它进入编辑状态,然后按`ctrl + c`键就可以将它复制
##### 火狐浏览器
1. 点击窗口顶部`存储`
2. 展开左侧 `Cookie`
3. 点击 `https://music.163.com`
4. 在右侧窗口找到 `名称``MUSIC_U` 的这行,这行的最后一列(`值`)内的那串内容就是`token`,双击它进入编辑状态,然后按`ctrl + c`键就可以将它复制
## 更新已收藏的在线歌单
该功能仅对直接从歌单详情页点“收藏”按钮收藏的歌单有效,可右击已收藏的列表名从弹出的菜单中选择“更新”使用该功能,
需要注意的是:这将会覆盖本地的目标列表,歌曲将被替换成最新的在线列表。
## 调整我的列表的列表顺序
按住Ctrl键Mac上对应Command键的时候将进入“拖动模式”此时可以拖动列表的位置来调整顺序。
## 同步功能的使用(实验性,首次使用前建议先备份一次列表)
**注意:由于同步传输时的数据是明文传输,请在受信任的网络下使用此功能!**<br>
此功能需要配合移动端使用PC端与移动端处在同一个局域网路由器的网络下时可以多端实时同步歌曲列表使用方法
1. 在PC端的设置-数据同步开启同步功能(这时如果出现安全软件、防火墙等提示网络连接弹窗时需要点击允许)
2. 在移动端的设置-同步-同步服务器地址输入PC端显示的同步服务器地址如果显示可以多个则输入与**移动端上显示的本机地址**最相似的那个端口号与PC端的同步端口一致**输入完毕后需要按一下键盘上的回车键使输入的内容生效**
3. 输入完这两项后点击“启动同步”
4. 若连接成功对于首次同步时若两边的设备的列表不为空则PC端会弹出选择列表同步方式的弹窗同步方式的说明弹窗下面有介绍
#### 关于同步弹窗的说明
对于首次同步时若两边的设备的列表不为空则PC端会弹出选择列表同步方式的弹窗此弹窗内的同步方式仅针对**首次同步**<br>
第一次同步成功后,以后再同步时将会自动根据两边设备的列表内容合并同步,不信你可以在同步完成后断开两边的连接,然后在两边增删一些歌曲或列表后再同步试试看~😉
#### 连接同步服务失败的可能原因
- 此功能需要PC端与移动端都连接在同一个路由器下的网络才能使用
- 检查防火墙是否拦截了PC端的服务端口
- 路由器若开启了AP隔离则此功能无法使用
#### 连接同步服务失败的检查
1. 确保PC端的同步服务已启用成功若连接码、同步服务地址没有内容则证明服务启动失败此时看启用同步功能复选框后面的错误信息自行解决另外若你不知道端口号是什么意思就不要乱改或不要改得太大与太小
2. 在手机浏览器地址栏输入`http://x.x.x.x:23332/hello` **(注:将`x.x.x.x`换成PC端显示的同步服务地址`23332`为PC端的端口号** 后回车,若此地址可以打开并显示 `Hello~::^-^::`则证明移动端与PC端网络已互通
3. 若移动端无法打开第2步的地址则在PC端的浏览器地址栏输入并打开该地址若可以打开则要么是被LX Music PC端被电脑防火墙拦截要么PC端与移动端不在同一个网络下或者路由器开启了AP隔离一般在公共网络下会出现这种情况
## 界面异常(界面显示不完整)
### Windows 10、11界面异常、界面无法显示
尝试添加运行参数 `--disable-gpu-sandbox` 启动,例如:`.\lx-music-desktop.exe --disable-gpu-sandbox`,添加方法可自行百度“给快捷方式加参数”。
若以上方法无效,则尝试将 `--disable-gpu-sandbox` 逐个换成以下参数启动,直到恢复正常为止:
- `--no-sandbox`
- `-dha`
- `--disable-gpu`
:::caution
这些参数会禁用程序的某些安全特性或降低程序性能,没有遇到问题不要使用它们!
:::
对于界面无法显示,任务栏里也没看到图标,但是任务管理器里面看到进程的问题,还可尝试更换软件安装目录(对于安装版需要先卸载再换目录安装,绿色版直接剪切移动即可,只要目录换了就行),<br />
此方法的相关讨论看:<https://github.com/lyswhut/lx-music-desktop/issues/943#issuecomment-1217832186>
### Windows 7 下界面异常
由于软件默认使用了透明窗口根据Electron官方文档的[说明](https://www.electronjs.org/docs/latest/tutorial/window-customization#limitations)
> 在 windows 操作系统上, 当 DWM 被禁用时, 透明窗口将无法工作。
因此,当 win7 没有使用**Aero**主题时界面将会显示异常开启AERO的方法请自行百度`win7开启Aero效果`(开启后可看到任务栏变透明)。<br>
`0.14.0`版本起不再强制要求开启透明效果,若你实在不想开启(若非电脑配置太低,墙裂建议开启!),可通过添加运行参数`-dt`来运行程序即可,例如:`.\lx-music-desktop.exe -dt`,添加方法可自行百度“给快捷方式加参数”,该参数的作用是用来控制程序是否使用非透明窗口运行。
注:启用**Aero**主题后,若软件出现黑边框,则重启软件即可恢复正常。
对于一些完全无法正常显示界面、开启了AERO后问题仍未解决的情况请阅读下面的 **Window 7 下软件启动后,界面无法显示** 解决。
### Linux 下界面异常
根据Electron里issue的[解决方案](https://github.com/electron/electron/issues/2170#issuecomment-736223269)<br>
若你遇到透明问题可尝试添加启动参数 `-dha` 来禁用硬件加速,例如:`.\lx-music-desktop.exe -dha`
v1.6.0及之后的版本才支持`-dha`参数
## Windows 7 下软件启动后,界面无法显示
对于软件启动后,可以在任务栏看到软件,但软件界面在桌面上无任何显示,或者整个界面偶尔闪烁的情况。<br>
原始问题看:<https://github.com/electron/electron/issues/19569#issuecomment-522231083><br>
解决办法:下载`.NET Framework 4.7.1`或**更高**版本安装即可(建议安装最新版,若安装过程中遇到问题可尝试自行百度解决)。<br>
微软官方下载地址:<https://dotnet.microsoft.com/download/dotnet-framework><br>
下载`Runtime(运行时)`版即可,安装完成后可能需要重启才生效,**若出现闪烁的情况**,可阅读下面的**Windows 7 下整个界面闪烁**解决。
## Windows 7 下整个界面闪烁(消失又出现)
可尝试在关掉软件后,在桌面空白处鼠标右击,在弹出的菜单中选择**个性化**,在弹出的窗口中**切换到系统内置的Aero主题**,然后再启动软件看是否解决。
## Windows 7 下桌面歌词字体列表为空
Windows 7 系统系统需要安装 Powershell 5.1及以上版本才可正常获取系统字体列表。
想要查看当前 Powershell 版本可以在 Powershell 窗口输入命令:`Get-Host`
最新 Powershell 安装包可以去官方 [Github releases](https://github.com/PowerShell/PowerShell/releases) 页下载,安装过程中若出现错误,请自行按照提示或者百度/Google解决。
## 安装版安装失败,提示安装程序并未成功地运行完成
对于部分电脑出现安装失败的问题,可以做出以下尝试:
- 若你之前可以安装成功,但现在安装失败,就去**控制面板-程序和功能**或用第三方卸载工具看下有没有之前的版本残留,若同时在不同路径下安装了多个版本就可能会出现该问题,这种情况卸载掉所有版本重新安装即可
- 清理安装路径下的残留文件
- 清理注册表(建议用清理工具清理)
## 软件无法联网
软件的排行榜、歌单、搜索列表**都**无法加载:
- 检查是否在设置界面开启了代理(当代理乱设置时软件将无法联网)
- 检查软件是否被第三方软件/防火墙阻止联网
## 桌面歌词显示异常
### Windows 7 系统桌面歌词显示异常
Windows 7 未开启 Aero 效果时桌面歌词会有问题,详情看上面的 **Windows 7 下界面异常** 方法解决。
### MAC OS 系统、桌面歌词有残留阴影
此问题似乎是Electron的Bug翻阅electron的issue列表发现该Bug以存在很久了遗憾的是没有一直都没有修复由于我没有装MAC平台的电脑没法重现就没再去electron提issue更多信息看
- <https://github.com/electron/electron/issues/21173>
- <https://github.com/electron/electron/issues/14304>
### Linux 系统下桌面歌词窗口异常
`v1.2.1`以前的版本在 Ubuntu 18.10 下第一次开启桌面歌词时歌词窗口会变白,需要关闭后再开启,
`v1.2.1`及之后的版本已修复该问题。
其他 Linux 系统未测试,如有异常也是意料之中,目前不打算去处理 Linux 平台的桌面歌词问题,但你可以尝试按照`Linux 下界面异常`的解决方案去解决。
## 歌曲下载失败,提示 `ENOENT: no such file or directory, mkdir`
更换下载歌曲目录即可解决(一般是设置的歌曲下载目录没有读写权限导致的)。
## 使用软件时导致耳机意外关机
据反馈,漫步者部分型号的耳机与本软件一起使用时将会导致耳机意外关机,
详情看:<https://github.com/lyswhut/lx-music-desktop/issues/457>
若出现该问题可尝试添加`-dhmkh`启动参数解决启动参数添加方法请自行百度“windows给快捷方式添加启动参数”。
## 软件安装包说明
软件发布页及网盘中有多个类型的安装文件,以下是对这些类型文件的说明:
文件名带 `win_` 的是在Windows系统上运行的版本<br>
其中安装版Setup可自动更新软件<br>
绿色版green为免安装版自动更新功能不可用
**`.dmg`** 结尾的文件为 MAC 版本;
**`.AppImage`**、**`.deb`**、**`.rpm`**、**`.pacman`** 结尾的为 Linux 版本。
带有`x64`的为64位的系统版本`x86`的为32位的系统版本若两个都带有的则为集合版安装时会自动根据系统位数选择对应的版本安装带有`arm`的为arm架构系统的版本。
## 软件更新
软件启动时若发现新版本时会自动从本仓库下载安装包,下载完毕会弹窗提示更新。<br>
若下载未完成时软件被关闭,下次启动软件会再次自动下载。<br>
若还是**更新失败**可能是无法访问GitHub导致的这时需要手动更新即下载最新安装包直接覆盖安装即可。<br>
注意:**绿色版**的软件自动更新功能**不可用**,建议使用安装版!!<br>
注意:**Mac版**、**Linux**版不支持自动更新!
### Windows 安装版在升级后,卸载了旧版本,但没有安装新版本
出现这个问题的原因一般是你当初在安装本软件的时候是以管理员身份安装的,运行软件的时候没有以管理员身份运行,所以卸载后无法再装上。
安装本软件时建议选择 `为当前用户安装`,并安装在当前用户目录或者安装在不需要管理员权限的目录(即其他分区下),不要选`为所有用户安装`
## 缺少`xxx.dll`
这个是电脑缺少某些dll导致的正常的系统是没有这个问题的可以尝试如下几个解决办法
- 以管理员权限打开`cmd`,输入`sfc /scannow`回车等待检查完成重启电脑
- 若上面的方法**修复、重启**电脑后仍然不行,就自行百度弹出的**错误信息**看下别人是怎么解决的
## MAC OS无法启动软件提示 lx-music-desktop 已损坏
这是因为软件没有签名,被系统阻止运行,<br>
在终端里输入 `sudo xattr -rd com.apple.quarantine /Applications/lx-music-desktop.app`,然后输入你的电脑密码即可
还可以参考:
- <http://www.pc6.com/edu/168719.html>
- <https://blog.csdn.net/for641/article/details/104811538>
## 数据存储路径
默认情况下,软件的数据存储在:
- Windows`%APPDATA%/lx-music-desktop`
- Linux`$XDG_CONFIG_HOME/lx-music-desktop``~/.config/lx-music-desktop`
- macOS`~/Library/Application/lx-music-desktop`
在Windows平台下若程序目录下存在`portable`目录则自动使用此目录作为数据存储目录v1.17.0新增)。
## 杀毒软件提示有病毒或恶意行为
本人只能保证我写的代码不包含任何**恶意代码**、**收集用户信息**的行为并且软件代码已开源请自行查阅软件安装包也是由CI拉取源代码构建构建日志[GitHub Actions](https://github.com/lyswhut/lx-music-desktop/actions)<br>
尽管如此但这不意味着软件是100%安全的,由于软件使用了第三方依赖,当这些依赖存在恶意行为时([供应链攻击](https://docs.microsoft.com/zh-cn/windows/security/threat-protection/intelligence/supply-chain-malware)),软件也将会受到牵连,所以我只能尽量选择使用较多人用、信任度较高的依赖。<br>
当然,以上说明建立的前提是在你所用的安装包是从**本项目主页上写的链接**下载的,或者有相关能力者还可以下载源代码自己构建安装包。
`v0.17.0`起,由于加入了音频输出设备切换功能,该功能调用了 [MediaDevices.enumerateDevices()](https://developer.mozilla.org/zh-CN/docs/Web/API/MediaDevices/enumerateDevices),可能导致安全软件提示洛雪要访问摄像头(目前发现卡巴斯基会提示),但实际上没有用到摄像头,并且摄像头的提示灯也不会亮,你可以选择阻止访问。
最后,若出现杀毒软件报毒、存在恶意行为,请自行判断选择是否继续使用本软件!
## 启动参数
目前软件已支持的启动参数如下:
- `-search` 启动软件时自动在搜索框搜索指定的内容,例如:`-search="突然的自我 - 伍佰"`
- `-dha` 禁用硬件加速启动Disable Hardware Acceleration窗口显示有问题时可以尝试添加此参数启动v1.6.0起新增)
- `-dt` 以非透明模式启动Disable Transparent对于未开启AERO效果的win7系统可加此参数启动以确保界面正常显示该参数对桌面歌词无效原来的`-nt`参数已重命名为`-dt`v1.6.0起重命名)
- `-dhmkh` 禁用硬件媒体密钥处理Disable Hardware Media Key Handling此选项将禁用Chromium的Hardware Media Key Handling特性v1.9.0起新增)
- `-proxy-server` 设置代理服务器,代理应用的所有流量,例:`-proxy-server="127.0.0.1:1081"`不支持设置账号密码v1.17.0起新增)。注:应用内“设置-网络-代理设置”仅代理接口请求的流量,优先级更高
- `-proxy-bypass-list` 以分号分隔的主机列表绕过代理服务器,例:`-proxy-bypass-list="<local>;*.google.com;*foo.com;1.2.3.4:5678"`(与`-proxy-server`一起使用才有效v1.17.0起新增)。注:此设置对应用内接口请求无效
- `-play` 启动时播放指定列表的音乐,参数说明:
- `type`:播放类型,目前固定为`songList`
- `source`:播放源,可用值为`kw/kg/tx/wy/mg/myList`,其中`kw/kg/tx/wy/mg`对应各源的在线列表,`myList`为本地列表
- `link`要播放的在线列表歌单链接、或IDsource为`kw/kg/tx/wy/mg`之一(在线列表)时必传,举例:`./lx-music-desktop -play="type=songList&source=kw&link=歌单URL or ID"`注意如果传入URL时必须对URL进行编码后再传入
- `name`要播放的本地列表歌单名字source为`myList`时必传,举例:`./lx-music-desktop -play="type=songList&source=myList&name=默认列表"`
- `index`:从列表的哪个位置开始播放,选传,若不传默认播放第一首歌曲,举例:`./lx-music-desktop -play="type=songList&source=myList&name=默认列表&index=2"`
## Scheme URL支持
从v1.17.0起支持 Scheme URL可以使用此功能从浏览器等场景下调用LX Music我们开发了一个[油猴脚本](https://github.com/lyswhut/lx-music-script#readme)配套使用<br>
脚本安装地址:<https://greasyfork.org/zh-CN/scripts/438148><br>
以下是目前可用的Scheme URL调用方式
- URL统一以`lxmusic://`开头
- 若无特别说明,源的可用值为:`kw/kg/tx/wy/mg`
- 若无特别说明,音质的可用值为:`128k/320k/flac/flac32bit`
目前支持两种传参方式:
- 通过`data`传参以经过URL编码的JSON数据传参`lxmusic://music/play?data=xxxx`,其中`xxxx`为经过URL编码后的JSON数据支持复杂的参数调用
- 通过`URL`传参适用于简单传参的调用不需要转成JSON格式`lxmusic://music/search/xxxx`但仍然需要对数据进行URL编码只适应于简单参数调用v1.18.0新增)
### `data`方式传参
以经过URL编码的JSON数据传参`lxmusic://music/play?data=xxxx`,其中`xxxx`为经过URL编码后的JSON数据JSON数据内容取决于下表的参数部分
| 描述 | URL | 参数
| --- | --- | ---
| 打开歌单 | `songlist/open` | `source<String>`(源,必须)<br>`id<String/Number>`歌单ID可选<br>`url<String>`歌单URL可选其中ID与URL必需传一个
| 播放歌单 | `songlist/play` | `source<String>`(源,必须)<br>`id<String/Number>`歌单ID可选<br>`url<String>`歌单URL可选其中`id``url`必需传一个<br>`index<Number>`播放第几首歌可选从0开始
| 搜索歌曲 | `music/search` | `keywords<String/Number>`(要搜索的内容,必须)<br>`source<String>`(源,可选)
| 播放歌曲 | `music/play` | `name<String>`(歌曲名,必传)<br>`singer<String>`(艺术家名,必传)<br>`source<String>`(源,必传)<br>`songmid<String/Number>`歌曲ID必传<br>`img<String>`(歌曲图片链接,选传)<br>`albumId<String/Number>`歌曲专辑ID选传<br>`interval<String>`(格式化后的歌曲时长,选传,例:`03:55`<br>`albumName<String>`(歌曲专辑名称,选传)<br>`types<Object>`(歌曲可用音质数组,必传,<br>数组格式:`[{"type": "<音质>", size: "<格式化后的文件大小,选传>", hash: "<kg源必传>"}]`<br>例:`[{"type": "128k", size: "3.56M"}, {"type": "320k", size: null}]`<br><br>以下为平台特定参数:<br>`hash<String>`歌曲hashkg源必传<br>`strMediaMid<String>`歌曲strMediaMidtx源必传<br>`albumMid<String>`歌曲albumMidtx源专用选传<br>`copyrightId<String>`歌曲copyrightIdmg源必传<br>`lrcUrl<String>`歌曲lrcUrlmg源专用选传
### `URL`方式传参
由于URL传参只适用于简单传参场景所以目前只支持以下功能的调用
| 描述 | URL | 参数
| --- | --- | ---
| 搜索歌曲 | `music/search/{source}/{keywords}` | `source`(源,可选)<br>`keywords`(要搜索的内容,必须)<br>例:`music/search/kw/xxx``music/search/xxx`
| 打开歌单 | `songlist/open/{source}/{id/url}` | `source`(源,必须)<br>`id/url`歌单ID或歌单URL必须<br>例:`songlist/open/kw/123456`
## 自定义源脚本编写说明
文件请使用UTF-8编码格式编写脚本所用编程语言为JavaScript可以使用ES6+语法,脚本与应用的交互是使用类似事件收发的方式进行,这是一个基本的脚本例子:
```js
/**
* @name 测试音乐源
* @description 我只是一个测试音乐源哦
* @version 1.0.0
* @author xxx
* @homepage http://xxx
*/
const { EVENT_NAMES, request, on, send } = window.lx
const qualitys = {
kw: {
'128k': '128',
'320k': '320',
flac: 'flac',
},
}
const httpRequest = (url, options) => new Promise((resolve, reject) => {
request(url, options, (err, resp) => {
if (err) return reject(err)
resolve(resp.body)
})
})
const apis = {
kw: {
musicUrl({ songmid }, quality) {
return httpRequest('http://xxx').then(data => {
return data.url
})
},
},
}
// 注册应用API请求事件
// source 音乐源可能的值取决于初始化时传入的sources对象的源key值
// info 请求附加信息内容根据action变化
// action 请求操作类型目前只有musicUrl即获取音乐URL链接
// 当action为musicUrl时info的结构{type, musicInfo}
// info.type音乐质量可能的值有128k / 320k / flac取决于初始化时对应源传入的qualitys值中的一个
// info.musicInfo音乐信息对象里面有音乐ID、名字等信息
on(EVENT_NAMES.request, ({ source, action, info }) => {
// 回调必须返回 Promise 对象
switch (action) {
// action 为 musicUrl 时需要在 Promise 返回歌曲 url
case 'musicUrl':
return apis[source].musicUrl(info.musicInfo, qualitys[source][info.type]).catch(err => {
console.log(err)
return Promise.reject(err)
})
}
})
// 脚本初始化完成后需要发送inited事件告知应用
send(EVENT_NAMES.inited, {
status: true, // 初始化成功 or 失败
openDevTools: false, // 是否打开开发者工具,方便用于调试脚本
sources: { // 当前脚本支持的源
kw: { // 支持的源对象可用key值kw/kg/tx/wy/mg
name: '酷我音乐',
type: 'music', // 目前固定为 music
actions: ['musicUrl'], // 目前固定为 ['musicUrl']
qualitys: ['128k', '320k', 'flac'], // 当前脚本的该源所支持获取的Url音质有效的值有['128k', '320k', 'flac']
},
},
})
```
### 自定义源信息
文件的开头必须包含以下注释:
```js
/**
* @name 测试脚本
* @description 我只是一个测试脚本
* @version 1.0.0
* @author xxx
* @homepage http://xxx
*/
```
- `@name `源的名字建议不要过长24个字符以内
- `@description `源的描述建议不要过长36个字符以内可不填不填时必须保留 @description
- `@version`:源的版本号,可不填,不填时可以删除 @version
- `@author `:脚本作者名字,可不填,不填时可以删除 @author
- `@homepage `:脚本主页,可不填,不填时可以删除 @homepage
### `window.lx`
应用为脚本暴露的API对象。
#### `window.lx.version`
自定义源API版本API变更时此版本号将会更改新增于v1.14.0之后)
#### `window.lx.EVENT_NAMES`
常量事件名称对象,发送、注册事件时传入事件名时使用,可用值:
| 事件名 | 描述
| --- | ---
| `inited` | 脚本初始化完成后发送给应用的事件名,发送该事件时需要传入以下信息:`{status, sources, openDevTools}`<br>`status`:初始化结果(`true`成功,`false`失败)<br>`openDevTools`是否打开DevTools此选项可用于开发脚本时的调试<br>`sources`:支持的源信息对象,<br>`sources[kw/kg/tx/wy/mg].name`:源的名字(目前非必须)<br>`sources[kw/kg/tx/wy/mg].type`:源类型,目前固定值需为`music`<br>`sources[kw/kg/tx/wy/mg].actions`支持的actions由于目前只支持`musicUrl`,所以固定传`['musicUrl']`即可<br>`sources[kw/kg/tx/wy/mg].qualitys`:该源支持的音质列表,有效的值为`['128k', '320k', 'flac']`,该字段用于控制应用可用的音质类型
| `request` | 应用API请求事件名回调入参`handler({ source, action, info})`,回调必须返回`Promise`对象<br>`source`:音乐源,可能的值取决于初始化时传入的`sources`对象的源key值<br>`info`:请求附加信息,内容根据`action`变化<br>`action`:请求操作类型,目前只有`musicUrl`即获取音乐URL链接需要在 Promise 返回歌曲 url`info`的结构:`{type, musicInfo}``info.type`:音乐质量,可能的值有`128k` / `320k` / `flac`(取决于初始化时对应源传入的`qualitys`值中的一个),`info.musicInfo`音乐信息对象里面有音乐ID、名字等信息
| `updateAlert` | 显示源更新弹窗,发送该事件时的参数:`{log, updateUrl}`<br>`log`:更新日志,必传,字符串类型,内容可以使用`\n`换行最大长度1024超过此长度后将被截取超出的部分<br>`updateUrl`更新地址用于引导用户去该地址更新源选传需为http协议的url地址最大长度1024<br>此事件每次运行脚本只能调用一次源版本v1.2.0新增)<br>例子:`lx.send(lx.EVENT_NAMES.updateAlert, { log: 'hello world', updateUrl: 'https://xxx.com' })`
#### `window.lx.on`
事件注册方法,应用主动与脚本通信时使用:
```js
/**
* @param event_name 事件名
* @param handler 事件处理回调 -- 注意:注册的回调必须返回 Promise 对象
*/
window.lx.on(event_name, handler)
```
**注意:** 注册的回调必须返回 `Promise` 对象。
#### `window.lx.send`
事件发送方法,脚本主动与应用通信时使用:
```js
/**
* @param event_name 事件名
* @param datas 要传给应用的数据
*/
window.lx.send(event_name, datas)
```
#### `window.lx.request`
HTTP请求方法用于发送HTTP请求此HTTP请求方法不受跨域规则限制
```js
/**
* @param url 请求的URL
* @param options 请求选项,可用选项有 method / headers / body / form / formData / timeout
* @param callback 请求结果的回调 入参err, resp, body
* @return 返回一个方法调用此方法可以终止HTTP请求
*/
const cancelHttp = window.lx.request(url, options, callback)
```
#### `window.lx.utils`
应用提供给脚本的工具方法:
- `window.lx.utils.buffer.from`对应Node.js的 `Buffer.from`
- `window.lx.utils.buffer.bufToString`Buffer转字符串 `bufToString(buffer, format)``format`对应Node.js `Buffer.toString`的参数v1.14.0之后新增)
- `window.lx.utils.crypto.aesEncrypt`AES加密 `aesEncrypt(buffer, mode, key, iv)`
- `window.lx.utils.crypto.md5`MD5加密 `md5(str)`
- `window.lx.utils.crypto.randomBytes`:生成随机字符串 `randomBytes(size)`
- `window.lx.utils.crypto.rsaEncrypt`RSA加密 `rsaEncrypt(buffer, key)`
目前仅提供以上工具方法如果需要其他方法可以开issue讨论。

124
README.md
View File

@@ -2,8 +2,9 @@
<p align="center">
<a href="https://github.com/lyswhut/lx-music-desktop/releases"><img src="https://img.shields.io/github/release/lyswhut/lx-music-desktop" alt="Release version"></a>
<a href="https://ci.appveyor.com/project/lyswhut/lx-music-desktop"><img src="https://ci.appveyor.com/api/projects/status/flrsqd5ymp8fnte5?svg=true" alt="Build status"></a>
<a href="https://travis-ci.org/lyswhut/lx-music-desktop"><img src="https://travis-ci.org/lyswhut/lx-music-desktop.svg?branch=master" alt="Build status"></a>
<a href="https://github.com/lyswhut/lx-music-desktop/actions/workflows/release.yml"><img src="https://github.com/lyswhut/lx-music-desktop/workflows/Build/badge.svg" alt="Build status"></a>
<a href="https://github.com/lyswhut/lx-music-desktop/actions/workflows/beta-pack.yml"><img src="https://github.com/lyswhut/lx-music-desktop/workflows/Build%20Beta/badge.svg" alt="Build status"></a>
<a href="https://electronjs.org/releases/stable"><img src="https://img.shields.io/github/package-json/dependency-version/lyswhut/lx-music-desktop/dev/electron/master" alt="Electron version"></a>
<!-- <a href="https://github.com/lyswhut/lx-music-desktop/releases"><img src="https://img.shields.io/github/downloads/lyswhut/lx-music-desktop/latest/total" alt="Downloads"></a> -->
<a href="https://github.com/lyswhut/lx-music-desktop/tree/dev"><img src="https://img.shields.io/github/package-json/v/lyswhut/lx-music-desktop/dev" alt="Dev branch version"></a>
<!-- <a href="https://github.com/lyswhut/lx-music-desktop/blob/master/LICENSE"><img src="https://img.shields.io/github/license/lyswhut/lx-music-desktop" alt="License"></a> -->
@@ -35,8 +36,8 @@
所用技术栈:
- Electron 6.x
- Vue 2.x
- Electron 17
- Vue 3
已支持的平台:
@@ -46,17 +47,44 @@
软件变化请查看:[更新日志](https://github.com/lyswhut/lx-music-desktop/blob/master/CHANGELOG.md)<br>
软件下载请转到:[发布页面](https://github.com/lyswhut/lx-music-desktop/releases)<br>
或者到网盘下载网盘内有MAC、windows版`https://www.lanzous.com/b906260/` 密码:`glqw`<br>
使用常见问题请转至:[常见问题](https://github.com/lyswhut/lx-music-desktop#常见问题)
或者到网盘下载网盘内有MAC、windows版`https://www.lanzoui.com/b0bf2cfa/` 密码:`glqw`(若链接无法打开请百度:蓝奏云链接打不开)<br>
使用常见问题请转至:[常见问题](https://lyswhut.github.io/lx-music-doc/desktop/faq)<br>
移动版项目地址:<https://github.com/lyswhut/lx-music-mobile>
#### TODO
#### Scheme URL支持
- [ ] 新增拉取各大平台歌单
- [ ] 新增聚合搜索
从v1.17.0起支持 Scheme URL可以使用此功能从浏览器等场景下调用LX Music我们开发了一个[油猴脚本](https://github.com/lyswhut/lx-music-script#readme)配套使用,<br>
脚本安装地址:<https://greasyfork.org/zh-CN/scripts/438148><br>
若你想自己调用LX Music可以看[Scheme URL支持](https://lyswhut.github.io/lx-music-doc/desktop/scheme-url)
#### 启动参数
目前软件已支持的启动参数如下:
- `-proxy-server` 设置代理服务器,代理应用的所有流量
- `-proxy-bypass-list` 以分号分隔的主机列表绕过代理服务器
- `-play` 启动时播放指定列表的音乐
- `-search` 启动软件时自动在搜索框搜索指定的内容
- `-dha` 禁用硬件加速启动Disable Hardware Acceleration
- `-dt` 以非透明模式启动Disable Transparent
- `-dhmkh` 禁用硬件媒体密钥处理Disable Hardware Media Key Handling
启动参数的详细说明请看[启动参数说明](https://lyswhut.github.io/lx-music-doc/desktop/run-params)
#### 数据存储路径
默认情况下,软件的数据存储在:
- Windows`%APPDATA%/lx-music-desktop`
- Linux`$XDG_CONFIG_HOME/lx-music-desktop``~/.config/lx-music-desktop`
- macOS`~/Library/Application Support/lx-music-desktop`
在Windows平台下若程序目录下存在`portable`目录则自动使用此目录作为数据存储目录v1.17.0新增)。
### 源码使用方法
环境要求Node.js 12.x
环境要求Node.js 16+
```bash
# 开发模式
@@ -65,8 +93,14 @@ npm run dev
# 构建免安装版
npm run pack:dir
# 构建安装包(windows版
npm run pack
# 构建安装包(Windows版
npm run pack:win
# 构建安装包Mac版
npm run pack:mac
# 构建安装包Linux版
npm run pack:linux
```
@@ -76,62 +110,22 @@ npm run pack
### 常见问题
#### 歌曲无法试听与下载
常见问题已移至:<https://lyswhut.github.io/lx-music-doc/desktop/faq>
该问题解决顺序如下:
### 项目协议
1. 尝试更新到最新版本
2. 尝试切换其他歌曲(或直接搜索该歌曲),若全部歌曲都无法试听与下载则进行下一步
3. 尝试到设置-接口来源切换到其他接口
4. 尝试切换网络,比如用手机开热点(目前存在某些网络无法访问接口服务器的情况)
5. 若还不行请到这个链接查看详情:<https://github.com/lyswhut/lx-music-desktop/issues/5>
6. 若没有在第5条链接中的第一条评论中看到接口无法使用的说明则应该是你网络无法访问接口服务器的问题如果接口有问题我会在那里说明。
本项目基于 [Apache License 2.0](https://github.com/lyswhut/lx-music-desktop/blob/master/LICENSE) 许可证发行,以下协议是对于 Apache License 2.0 的补充,如有冲突,以以下协议为准。
#### 软件安装包说明
词语约定:本协议中的“本项目”指洛雪音乐桌面版项目;“使用者”指签署本协议的使用者;“官方音乐平台”指对本项目内置的包括酷我、酷狗、咪咕等音乐源的官方平台统称;“版权数据”指包括但不限于图像、音频、名字等在内的他人拥有所属版权的数据。
软件发布页及网盘中有多个类型的安装文件,以下是对这些类型文件的说明:
1. 本项目的数据来源原理是从各官方音乐平台的公开服务器中拉取数据,经过对数据简单地筛选与合并后进行展示,因此本项目不对数据的准确性负责。
2. 使用本项目的过程中可能会产生版权数据,对于这些版权数据,本项目不拥有它们的所有权,为了避免造成侵权,使用者务必在**24小时**内清除使用本项目的过程中所产生的版权数据。
3. 本项目内的官方音乐平台别名为本项目内对官方音乐平台的一个称呼,不包含恶意,如果官方音乐平台觉得不妥,可联系本项目更改或移除。
4. 本项目内使用的部分包括但不限于字体、图片等资源来源于互联网,如果出现侵权可联系本项目移除。
5. 由于使用本项目产生的包括由于本协议或由于使用或无法使用本项目而引起的任何性质的任何直接、间接、特殊、偶然或结果性损害(包括但不限于因商誉损失、停工、计算机故障或故障引起的损害赔偿,或任何及所有其他商业损害或损失)由使用者负责。
6. 本项目完全免费,且开源发布于 GitHub 面向全世界人用作对技术的学习交流,本项目不对项目内的技术可能存在违反当地法律法规的行为作保证,**禁止在违反当地法律法规的情况下使用本项目**,对于使用者在明知或不知当地法律法规不允许的情况下使用本项目所造成的任何违法违规行为由使用者承担,本项目不承担由此造成的任何直接、间接、特殊、偶然或结果性责任。
文件名带 `win_` 的是在Windows系统上运行的版本<br>
其中安装版Setup可自动更新软件<br>
绿色版green为免安装版自动更新功能不可用
若你使用了本项目,将代表你接受以上协议。
**`.dmg`** 结尾的文件为 MAC 版本;
**`.AppImage`**、**`.deb`** 结尾的为 Linux 版本。
带有`x64`的为64位的系统版本`x86`的为32位的系统版本若两个都带有的则为集合版安装时会自动根据系统位数选择对应的版本安装。
#### 软件更新
软件启动时若发现新版本时会自动从本仓库下载安装包,下载完毕会弹窗提示更新。<br>
若下载未完成时软件被关闭,下次启动软件会再次自动下载。<br>
若还是**更新失败**可能是无法访问GitHub导致的这时需要手动更新即下载最新安装包直接覆盖安装即可。<br>
注意:**绿色版**的软件自动更新功能**不可用**,建议使用安装版!!<br>
注意:**Mac版**、**Linux deb**版不支持自动更新!
#### Windows 7 下界面异常
当 win7 没有开启**透明效果**时界面将会显示异常,开启方法请自行百度。
#### 安装版安装失败,提示应用未安装
对于部分电脑出现安装失败的问题我也不懂什么原因,,可以尝试清理下安装文件,或者重启电脑试试。
#### 缺少`xxx.dll`
这个是电脑缺少某些dll导致的正常的系统是没有这个问题的解决办法需自行百度弹出的错误信息看下别人是怎么解决的。
### 致谢
感谢 [@messoer](https://github.com/messoer) 曾经提供的部分音乐API
### 免责声明
本项目**不开发或者破解直接获取音频数据**的功能,所有音频数据均来自**第三方接口**<br>
本软件仅用于**测试 `electron 6.x` 在各种系统上的兼容性**及用于**对比各大音乐平台歌单、排行榜等数据列表的差异性**,使用本软件产生的**任何涉及版权相关的数据**请于**24小时内删除**。<br>
本软件仅用于学习交流使用,禁止用于商业用途,使用本软件所造成的的后果由使用者承担!<br>
若对此有疑问请 mail to: lyswhut@qq.com
### 许可证
[Apache License 2.0](https://github.com/lyswhut/lx-music-desktop/blob/master/LICENSE)
音乐平台不易,请尊重版权,支持正版。<br>
若对此有疑问请 mail to: lyswhut+qq.com (请将`+`替换成`@`)

View File

@@ -2,7 +2,8 @@ const isDev = process.env.NODE_ENV === 'development'
module.exports = {
modules: {
localIdentName: isDev ? '[folder]-[name]--[local]--[hash:base64:5]' : '[hash:base64:5]',
localIdentName: isDev ? '[path][name]__[local]--[hash:base64:5]' : '[hash:base64:5]',
exportLocalsConvention: 'camelCase',
},
localsConvention: 'camelCase',
sourceMap: isDev,
}

View File

@@ -1,39 +1,31 @@
const path = require('path')
const ESLintPlugin = require('eslint-webpack-plugin')
module.exports = {
target: 'electron-main',
output: {
filename: '[name].js',
libraryTarget: 'commonjs2',
path: path.join(__dirname, '../../dist/electron'),
path: path.join(__dirname, '../../dist'),
},
resolve: {
alias: {
common: path.join(__dirname, '../../src/common'),
'@main': path.join(__dirname, '../../src/main'),
'@renderer': path.join(__dirname, '../../src/renderer'),
'@lyric': path.join(__dirname, '../../src/renderer-lyric'),
'@common': path.join(__dirname, '../../src/common'),
},
extensions: ['*', '.js', '.json', '.node'],
},
module: {
rules: [
{
test: /\.js$/,
use: {
loader: 'eslint-loader',
options: {
formatter: require('eslint-formatter-friendly'),
},
},
exclude: /node_modules/,
enforce: 'pre',
test: /\.node$/,
use: 'node-loader',
},
// {
// test: /\.js$/,
// loader: 'babel-loader',
// exclude: /node_modules/,
// },
],
},
performance: {
maxEntrypointSize: 300000,
},
plugins: [
new ESLintPlugin(),
],
}

View File

@@ -1,5 +1,5 @@
const path = require('path')
const merge = require('webpack-merge')
const { merge } = require('webpack-merge')
const webpack = require('webpack')
const baseConfig = require('./webpack.config.base')
@@ -16,7 +16,11 @@ module.exports = merge(baseConfig, {
NODE_ENV: '"development"',
},
__static: `"${path.join(__dirname, '../../src/static').replace(/\\/g, '\\\\')}"`,
__userApi: `"${path.join(__dirname, '../../src/main/modules/userApi').replace(/\\/g, '\\\\')}"`,
}),
new webpack.NoEmitOnErrorsPlugin(),
],
performance: {
maxEntrypointSize: 1024 * 1024 * 50,
maxAssetSize: 1024 * 1024 * 30,
},
})

View File

@@ -1,6 +1,7 @@
const path = require('path')
const merge = require('webpack-merge')
const { merge } = require('webpack-merge')
const webpack = require('webpack')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const baseConfig = require('./webpack.config.base')
@@ -14,16 +15,36 @@ module.exports = merge(baseConfig, {
},
externals: [
...Object.keys(dependencies || {}),
// 'font-list',
],
node: {
__dirname: false,
__filename: false,
},
plugins: [
new CopyWebpackPlugin({
patterns: [
{
from: path.join(__dirname, '../../src/main/modules/userApi/renderer'),
to: path.join(__dirname, '../../dist/userApi/renderer'),
},
{
from: path.join(__dirname, '../../src/main/modules/userApi/rendererEvent/name.js'),
to: path.join(__dirname, '../../dist/userApi/rendererEvent/name.js'),
},
],
}),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"',
},
}),
],
performance: {
maxEntrypointSize: 1024 * 1024 * 10,
maxAssetSize: 1024 * 1024 * 20,
},
optimization: {
minimize: false,
},
})

View File

@@ -3,52 +3,67 @@ process.env.NODE_ENV = 'production'
const chalk = require('chalk')
const del = require('del')
const webpack = require('webpack')
const Multispinner = require('multispinner')
const Spinnies = require('spinnies')
const mainConfig = require('./main/webpack.config.prod')
const rendererConfig = require('./renderer/webpack.config.prod')
const rendererLyricConfig = require('./renderer-lyric/webpack.config.prod')
const errorLog = chalk.bgRed.white(' ERROR ') + ' '
const okayLog = chalk.bgGreen.white(' OKAY ') + ' '
function build() {
del.sync(['dist/electron', 'build'])
const tasks = ['main', 'renderer']
const m = new Multispinner(tasks, {
preText: 'building',
postText: 'process',
})
del.sync(['dist/**', 'build/**'])
const spinners = new Spinnies({ color: 'blue' })
spinners.add('main', { text: 'main building' })
spinners.add('renderer', { text: 'renderer building' })
spinners.add('renderer-lyric', { text: 'renderer-lyric building' })
let results = ''
m.on('success', () => {
// m.on('success', () => {
// process.stdout.write('\x1B[2J\x1B[0f')
// console.log(`\n\n${results}`)
// console.log(`${okayLog}take it away ${chalk.yellow('`electron-builder`')}\n`)
// process.exit()
// })
function handleSuccess() {
process.stdout.write('\x1B[2J\x1B[0f')
console.log(`\n\n${results}`)
console.log(`${okayLog}take it away ${chalk.yellow('`electron-builder`')}\n`)
process.exit()
})
}
pack(mainConfig).then(result => {
results += result + '\n\n'
m.success('main')
}).catch(err => {
m.error('main')
console.log(`\n ${errorLog}failed to build main process`)
console.error(`\n${err}\n`)
process.exit(1)
})
pack(rendererConfig).then(result => {
results += result + '\n\n'
m.success('renderer')
}).catch(err => {
m.error('renderer')
console.log(`\n ${errorLog}failed to build renderer process`)
console.error(`\n${err}\n`)
process.exit(1)
})
Promise.all([
pack(mainConfig).then(result => {
results += result + '\n\n'
spinners.succeed('main', { text: 'main build success!' })
}).catch(err => {
spinners.fail('main', { text: 'main build fail :(' })
console.log(`\n ${errorLog}failed to build main process`)
console.error(`\n${err}\n`)
process.exit(1)
}),
pack(rendererConfig).then(result => {
results += result + '\n\n'
spinners.succeed('renderer', { text: 'renderer build success!' })
}).catch(err => {
spinners.fail('renderer', { text: 'renderer build fail :(' })
console.log(`\n ${errorLog}failed to build renderer process`)
console.error(`\n${err}\n`)
process.exit(1)
}),
pack(rendererLyricConfig).then(result => {
results += result + '\n\n'
spinners.succeed('renderer-lyric', { text: 'renderer-lyric build success!' })
}).catch(err => {
spinners.fail('renderer-lyric', { text: 'renderer-lyric build fail :(' })
console.log(`\n ${errorLog}failed to build renderer-lyric process`)
console.error(`\n${err}\n`)
process.exit(1)
}),
]).then(handleSuccess)
}
function pack(config) {

View File

@@ -0,0 +1,150 @@
const path = require('path')
const { VueLoaderPlugin } = require('vue-loader')
const HTMLPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const ESLintPlugin = require('eslint-webpack-plugin')
const vueLoaderConfig = require('../vue-loader.config')
const { mergeCSSLoader } = require('../utils')
const isDev = process.env.NODE_ENV === 'development'
module.exports = {
target: 'electron-renderer',
entry: {
'renderer-lyric': path.join(__dirname, '../../src/renderer-lyric/main.js'),
},
output: {
filename: '[name].js',
libraryTarget: 'commonjs2',
path: path.join(__dirname, '../../dist'),
publicPath: 'auto',
},
resolve: {
alias: {
'@': path.join(__dirname, '../../src'),
'@main': path.join(__dirname, '../../src/main'),
'@renderer': path.join(__dirname, '../../src/renderer'),
'@lyric': path.join(__dirname, '../../src/renderer-lyric'),
'@static': path.join(__dirname, '../../src/static'),
'@common': path.join(__dirname, '../../src/common'),
},
extensions: ['*', '.js', '.json', '.vue', '.node'],
},
module: {
rules: [
{
test: /\.node$/,
use: 'node-loader',
},
{
test: /\.vue$/,
loader: 'vue-loader',
options: vueLoaderConfig,
},
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/,
},
{
test: /\.css$/,
oneOf: mergeCSSLoader(),
},
{
test: /\.less$/,
oneOf: mergeCSSLoader({
loader: 'less-loader',
options: {
sourceMap: true,
},
}),
},
{
test: /\.pug$/,
oneOf: [
// Use pug-plain-loader handle .vue file
{
resourceQuery: /vue/,
use: ['pug-plain-loader'],
},
// Use pug-loader handle .pug file
{
use: ['pug-loader'],
},
],
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
exclude: path.join(__dirname, '../../src/renderer/assets/svgs'),
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 10000,
},
},
generator: {
filename: 'imgs/[name]-[contenthash:8][ext]',
},
},
{
test: /\.svg$/,
include: path.join(__dirname, '../../src/renderer/assets/svgs'),
use: [
{
loader: 'svg-sprite-loader',
options: {
symbolId: 'icon-[name]',
},
},
'svg-transform-loader',
'svgo-loader',
],
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 10000,
},
},
generator: {
filename: 'media/[name]-[contenthash:8][ext]',
},
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 10000,
},
},
generator: {
filename: 'fonts/[name]-[contenthash:8][ext]',
},
},
],
},
plugins: [
new HTMLPlugin({
filename: 'lyric.html',
template: path.join(__dirname, '../../src/renderer-lyric/index.pug'),
isProd: process.env.NODE_ENV == 'production',
browser: process.browser,
__dirname,
}),
new VueLoaderPlugin(),
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: isDev ? '[name].css' : '[name].[contenthash:8].css',
chunkFilename: isDev ? '[id].css' : '[id].[contenthash:8].css',
}),
new ESLintPlugin({
extensions: ['js', 'vue'],
formatter: require('eslint-formatter-friendly'),
}),
],
}

View File

@@ -0,0 +1,26 @@
const path = require('path')
const webpack = require('webpack')
const { merge } = require('webpack-merge')
const baseConfig = require('./webpack.config.base')
module.exports = merge(baseConfig, {
mode: 'development',
devtool: 'eval-source-map',
plugins: [
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"development"',
ELECTRON_DISABLE_SECURITY_WARNINGS: 'true',
},
__VUE_OPTIONS_API__: 'true',
__VUE_PROD_DEVTOOLS__: 'false',
__static: `"${path.join(__dirname, '../../src/static').replace(/\\/g, '\\\\')}"`,
}),
],
performance: {
hints: false,
},
})

View File

@@ -0,0 +1,48 @@
// const path = require('path')
const webpack = require('webpack')
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')
const TerserPlugin = require('terser-webpack-plugin')
const { merge } = require('webpack-merge')
const baseConfig = require('./webpack.config.base')
const { dependencies } = require('../../package.json')
// let whiteListedModules = ['vue']
let whiteListedModules = ['vue', 'vue-router', 'vuex', 'vue-i18n']
module.exports = merge(baseConfig, {
mode: 'production',
devtool: false,
externals: [
...Object.keys(dependencies || {}).filter(d => !whiteListedModules.includes(d)),
],
plugins: [
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"',
},
__VUE_OPTIONS_API__: 'true',
__VUE_PROD_DEVTOOLS__: 'false',
}),
],
optimization: {
minimize: false,
minimizer: [
new TerserPlugin(),
new CssMinimizerPlugin(),
],
},
performance: {
maxEntrypointSize: 1024 * 1024 * 10,
maxAssetSize: 1024 * 1024 * 20,
hints: 'warning',
},
node: {
__dirname: false,
__filename: false,
},
})

View File

@@ -1,9 +1,13 @@
const path = require('path')
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const { VueLoaderPlugin } = require('vue-loader')
const HTMLPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const ESLintPlugin = require('eslint-webpack-plugin')
const vueLoaderConfig = require('../vue-loader.config')
const { mergeCSSLoader } = require('../utils')
const isDev = process.env.NODE_ENV === 'development'
module.exports = {
target: 'electron-renderer',
@@ -13,28 +17,25 @@ module.exports = {
output: {
filename: '[name].js',
libraryTarget: 'commonjs2',
path: path.join(__dirname, '../../dist/electron'),
publicPath: './',
path: path.join(__dirname, '../../dist'),
publicPath: 'auto',
},
resolve: {
alias: {
'@': path.join(__dirname, '../../src/renderer'),
common: path.join(__dirname, '../../src/common'),
'@': path.join(__dirname, '../../src'),
'@main': path.join(__dirname, '../../src/main'),
'@renderer': path.join(__dirname, '../../src/renderer'),
'@lyric': path.join(__dirname, '../../src/renderer-lyric'),
'@static': path.join(__dirname, '../../src/static'),
'@common': path.join(__dirname, '../../src/common'),
},
extensions: ['*', '.js', '.json', '.vue', '.node'],
},
module: {
rules: [
{
test: /\.(vue|js)$/,
use: {
loader: 'eslint-loader',
options: {
formatter: require('eslint-formatter-friendly'),
},
},
exclude: /node_modules/,
enforce: 'pre',
test: /\.node$/,
use: 'node-loader',
},
{
test: /\.vue$/,
@@ -46,6 +47,19 @@ module.exports = {
loader: 'babel-loader',
exclude: /node_modules/,
},
{
test: /\.css$/,
oneOf: mergeCSSLoader(),
},
{
test: /\.less$/,
oneOf: mergeCSSLoader({
loader: 'less-loader',
options: {
sourceMap: true,
},
}),
},
{
test: /\.pug$/,
oneOf: [
@@ -62,41 +76,75 @@ module.exports = {
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: 'imgs/[name]--[folder].[ext]',
exclude: path.join(__dirname, '../../src/renderer/assets/svgs'),
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 10000,
},
},
generator: {
filename: 'imgs/[name]-[contenthash:8][ext]',
},
},
{
test: /\.svg$/,
include: path.join(__dirname, '../../src/renderer/assets/svgs'),
use: [
{
loader: 'svg-sprite-loader',
options: {
symbolId: 'icon-[name]',
},
},
'svg-transform-loader',
'svgo-loader',
],
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: 'media/[name]--[folder].[ext]',
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 10000,
},
},
generator: {
filename: 'media/[name]-[contenthash:8][ext]',
},
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: 'fonts/[name]--[folder].[ext]',
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 10000,
},
},
generator: {
filename: 'fonts/[name]-[contenthash:8][ext]',
},
},
],
},
performance: {
maxEntrypointSize: 300000,
},
plugins: [
new HTMLPlugin({
filename: 'index.html',
template: path.join(__dirname, '../../src/index.pug'),
template: path.join(__dirname, '../../src/renderer/index.html'),
isProd: process.env.NODE_ENV == 'production',
browser: process.browser,
__dirname,
}),
new VueLoaderPlugin(),
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: isDev ? '[name].css' : '[name].[contenthash:8].css',
chunkFilename: isDev ? '[id].css' : '[id].[contenthash:8].css',
}),
new ESLintPlugin({
extensions: ['js', 'vue'],
formatter: require('eslint-formatter-friendly'),
}),
],
}

View File

@@ -1,51 +1,22 @@
const path = require('path')
const webpack = require('webpack')
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
const merge = require('webpack-merge')
const { merge } = require('webpack-merge')
const baseConfig = require('./webpack.config.base')
const { mergeCSSLoaderDev } = require('../utils')
module.exports = merge(baseConfig, {
mode: 'development',
devtool: 'eval-source-map',
module: {
rules: [
{
test: /\.css$/,
oneOf: mergeCSSLoaderDev(),
},
{
test: /\.less$/,
oneOf: mergeCSSLoaderDev({
loader: 'less-loader',
options: {
sourceMap: true,
},
}),
},
{
test: /\.styl(:?us)?$/,
oneOf: mergeCSSLoaderDev({
loader: 'stylus-loader',
options: {
sourceMap: true,
},
}),
},
],
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin(),
new FriendlyErrorsPlugin(),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"development"',
ELECTRON_DISABLE_SECURITY_WARNINGS: 'true',
},
ENVIRONMENT: 'process.env',
__VUE_OPTIONS_API__: 'true',
__VUE_PROD_DEVTOOLS__: 'false',
__static: `"${path.join(__dirname, '../../src/static').replace(/\\/g, '\\\\')}"`,
}),
],

View File

@@ -1,17 +1,15 @@
const path = require('path')
const webpack = require('webpack')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')
const TerserPlugin = require('terser-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const merge = require('webpack-merge')
const { merge } = require('webpack-merge')
const baseConfig = require('./webpack.config.base')
const { mergeCSSLoaderProd } = require('../utils')
const { dependencies } = require('../../package.json')
let whiteListedModules = ['vue']
let whiteListedModules = ['vue', 'vue-router', 'vuex', 'vue-i18n']
module.exports = merge(baseConfig, {
@@ -20,61 +18,34 @@ module.exports = merge(baseConfig, {
externals: [
...Object.keys(dependencies || {}).filter(d => !whiteListedModules.includes(d)),
],
module: {
rules: [
{
test: /\.css$/,
oneOf: mergeCSSLoaderProd(),
},
{
test: /\.less$/,
oneOf: mergeCSSLoaderProd({
loader: 'less-loader',
options: {
sourceMap: true,
},
}),
},
{
test: /\.styl(:?us)?$/,
oneOf: mergeCSSLoaderProd({
loader: 'stylus-loader',
options: {
sourceMap: true,
},
}),
},
],
},
plugins: [
new CopyWebpackPlugin([
{
from: path.join(__dirname, '../../src/static'),
to: path.join(__dirname, '../../dist/electron/static'),
ignore: ['.*'],
},
]),
new CopyWebpackPlugin({
patterns: [
{
from: path.join(__dirname, '../../src/static'),
to: path.join(__dirname, '../../dist/static'),
},
],
}),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"',
},
ENVIRONMENT: 'process.env',
__VUE_OPTIONS_API__: 'true',
__VUE_PROD_DEVTOOLS__: 'false',
}),
new MiniCssExtractPlugin({
filename: '[name].css',
}),
new webpack.NamedChunksPlugin(),
],
optimization: {
minimize: false,
minimizer: [
new TerserPlugin({
cache: true,
parallel: true,
sourceMap: false, // set to true if you want JS source maps
}),
new OptimizeCSSAssetsPlugin({}),
new TerserPlugin(),
new CssMinimizerPlugin(),
],
},
performance: {
maxEntrypointSize: 1024 * 1024 * 10,
maxAssetSize: 1024 * 1024 * 20,
hints: 'warning',
},
node: {

View File

@@ -7,16 +7,17 @@ const path = require('path')
const { spawn } = require('child_process')
const webpack = require('webpack')
const WebpackDevServer = require('webpack-dev-server')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const webpackHotMiddleware = require('webpack-hot-middleware')
const mainConfig = require('./main/webpack.config.dev')
const rendererConfig = require('./renderer/webpack.config.dev')
const { logStats } = require('./utils')
const rendererLyricConfig = require('./renderer-lyric/webpack.config.dev')
let electronProcess = null
let manualRestart = false
let hotMiddleware
let hotMiddlewareRenderer
let hotMiddlewareRendererLyric
function startRenderer() {
@@ -24,45 +25,89 @@ function startRenderer() {
// rendererConfig.entry.renderer = [path.join(__dirname, 'dev-client')].concat(rendererConfig.entry.renderer)
// rendererConfig.mode = 'development'
const compiler = webpack(rendererConfig)
hotMiddleware = webpackHotMiddleware(compiler, {
hotMiddlewareRenderer = webpackHotMiddleware(compiler, {
log: false,
heartbeat: 2500,
})
compiler.hooks.compilation.tap('compilation', compilation => {
// console.log(Object.keys(compilation.hooks))
compilation.hooks.htmlWebpackPluginAfterEmit.tapAsync('html-webpack-plugin-after-emit', (data, cb) => {
hotMiddleware.publish({ action: 'reload' })
HtmlWebpackPlugin.getHooks(compilation).beforeEmit.tapAsync('html-webpack-plugin-after-emit', (data, cb) => {
hotMiddlewareRenderer.publish({ action: 'reload' })
cb()
})
})
compiler.hooks.done.tap('done', stats => {
// logStats('Renderer', 'Compile done')
// logStats('Renderer', stats)
// compiler.hooks.done.tap('done', stats => {
// // logStats('Renderer', 'Compile done')
// // logStats('Renderer', stats)
// })
const server = new WebpackDevServer({
port: 9080,
hot: true,
historyApiFallback: true,
// static: {
// directory: path.join(__dirname, '../'),
// },
client: {
logging: 'warn',
overlay: true,
},
setupMiddlewares(middlewares, devServer) {
devServer.app.use(hotMiddlewareRenderer)
devServer.middleware.waitUntilValid(resolve)
return middlewares
},
}, compiler)
server.start()
})
}
function startRendererLyric() {
return new Promise((resolve, reject) => {
// rendererConfig.entry.renderer = [path.join(__dirname, 'dev-client')].concat(rendererConfig.entry.renderer)
// rendererConfig.mode = 'development'
const compiler = webpack(rendererLyricConfig)
hotMiddlewareRendererLyric = webpackHotMiddleware(compiler, {
log: false,
heartbeat: 2500,
})
const server = new WebpackDevServer(
compiler,
{
contentBase: path.join(__dirname, '../'),
quiet: true,
hot: true,
historyApiFallback: true,
clientLogLevel: 'warning',
overlay: {
errors: true,
},
before(app, ctx) {
app.use(hotMiddleware)
ctx.middleware.waitUntilValid(() => {
resolve()
})
},
}
)
compiler.hooks.compilation.tap('compilation', compilation => {
// console.log(Object.keys(compilation.hooks))
HtmlWebpackPlugin.getHooks(compilation).beforeEmit.tapAsync('html-webpack-plugin-after-emit', (data, cb) => {
hotMiddlewareRendererLyric.publish({ action: 'reload' })
cb()
})
})
server.listen(9080)
// compiler.hooks.done.tap('done', stats => {
// // logStats('Renderer', 'Compile done')
// // logStats('Renderer', stats)
// })
const server = new WebpackDevServer({
port: 9081,
hot: true,
historyApiFallback: true,
// static: {
// directory: path.join(__dirname, '../'),
// },
client: {
logging: 'warn',
overlay: true,
},
setupMiddlewares(middlewares, devServer) {
devServer.app.use(hotMiddlewareRenderer)
devServer.middleware.waitUntilValid(resolve)
return middlewares
},
}, compiler)
server.start()
})
}
@@ -73,8 +118,8 @@ function startMain() {
const compiler = webpack(mainConfig)
compiler.hooks.watchRun.tapAsync('watch-run', (compilation, done) => {
logStats('Main', chalk.white.bold('compiling...'))
hotMiddleware.publish({ action: 'compiling' })
hotMiddlewareRenderer.publish({ action: 'compiling' })
hotMiddlewareRendererLyric.publish({ action: 'compiling' })
done()
})
@@ -106,7 +151,7 @@ function startElectron() {
let args = [
'--inspect=5858',
// 'NODE_ENV=development',
path.join(__dirname, '../dist/electron/main.js'),
path.join(__dirname, '../dist/main.js'),
]
// detect yarn or npm and process commandline args accordingly
@@ -133,38 +178,39 @@ function startElectron() {
function electronLog(data, color) {
let log = data.toString()
if (/[0-9A-z]+/.test(log)) {
// 抑制 user api 窗口使用 data url 加载页面时 vue扩展 的报错日志刷屏的问题
if (color == 'red' && typeof log === 'string' && log.includes('"Extension server error: Operation failed: Permission denied", source: devtools://devtools/bundled/extensions/extensions.js')) return
console.log(chalk[color](log))
}
}
function greeting() {
/* const cols = process.stdout.columns
let text = ''
if (cols > 104) text = 'electron-vue'
else if (cols > 76) text = 'electron-|vue'
else text = false
if (text) {
say(text, {
colors: ['yellow'],
font: 'simple3d',
space: false,
})
} else console.log(chalk.yellow.bold('\n electron-vue')) */
console.log(chalk.blue('getting ready...') + '\n')
}
function init() {
greeting()
const Spinnies = require('spinnies')
const spinners = new Spinnies({ color: 'blue' })
spinners.add('main', { text: 'main compiling' })
spinners.add('renderer', { text: 'renderer compiling' })
spinners.add('renderer-lyric', { text: 'renderer-lyric compiling' })
function handleSuccess(name) {
spinners.succeed(name, { text: name + ' compile success!' })
}
function handleFail(name) {
spinners.fail(name, { text: name + ' compile fail!' })
}
Promise.all([startRenderer(), startMain()])
.then(() => {
startElectron()
})
.catch(err => {
console.error(err)
})
Promise.all([
startRenderer().then(() => handleSuccess('renderer')).catch((err) => {
console.error(err.message)
return handleFail('renderer')
}),
startRendererLyric().then(() => handleSuccess('renderer-lyric')).catch((err) => {
console.error(err.message)
return handleFail('renderer-lyric')
}),
startMain().then(() => handleSuccess('main')).catch(() => handleFail('main')),
]).then(startElectron).catch(err => {
console.error(err)
})
}
init()

View File

@@ -2,62 +2,19 @@ const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const cssLoaderConfig = require('./css-loader.config')
const chalk = require('chalk')
// merge css-loader in development
exports.mergeCSSLoaderDev = beforeLoader => {
// merge css-loader
exports.mergeCSSLoader = beforeLoader => {
const loader = [
// 这里匹配 `<style module>`
{
resourceQuery: /module/,
use: [
'vue-style-loader',
{
loader: 'css-loader',
options: Object.assign({
sourceMap: true,
}, cssLoaderConfig),
},
{
loader: 'postcss-loader',
loader: MiniCssExtractPlugin.loader,
options: {
sourceMap: true,
esModule: false,
},
},
],
},
// 这里匹配普通的 `<style>` 或 `<style scoped>`
{
use: [
'vue-style-loader',
{
loader: 'css-loader',
options: {
sourceMap: true,
},
},
{
loader: 'postcss-loader',
options: {
sourceMap: true,
},
},
],
},
]
if (beforeLoader) {
loader[0].use.push(beforeLoader)
loader[1].use.push(beforeLoader)
}
return loader
}
// merge css-loader in production
exports.mergeCSSLoaderProd = beforeLoader => {
const loader = [
// 这里匹配 `<style module>`
{
resourceQuery: /module/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: cssLoaderConfig,
@@ -68,7 +25,12 @@ exports.mergeCSSLoaderProd = beforeLoader => {
// 这里匹配普通的 `<style>` 或 `<style scoped>`
{
use: [
MiniCssExtractPlugin.loader,
{
loader: MiniCssExtractPlugin.loader,
options: {
esModule: false,
},
},
'css-loader',
'postcss-loader',
],

View File

@@ -1,97 +0,0 @@
const path = require('path')
const webpack = require('webpack')
const HTMLPlugin = require('html-webpack-plugin')
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const vueLoaderConfig = require('../vue-loader.config')
module.exports = {
target: 'web',
entry: path.join(__dirname, '../../src/renderer/main.js'),
output: {
path: path.join(__dirname, '../../dist/web'),
},
resolve: {
alias: {
'@': path.join(__dirname, '../../src/renderer'),
common: path.join(__dirname, '../../src/common'),
},
extensions: ['*', '.js', '.vue', '.json', '.css'],
},
module: {
rules: [
{
test: /\.(vue|js)$/,
use: {
loader: 'eslint-loader',
options: {
formatter: require('eslint-formatter-friendly'),
},
},
exclude: /node_modules/,
enforce: 'pre',
},
{
test: /\.vue$/,
loader: 'vue-loader',
options: vueLoaderConfig,
},
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/,
},
{
test: /\.pug$/,
oneOf: [
// Use pug-plain-loader handle .vue file
{
resourceQuery: /vue/,
use: ['pug-plain-loader'],
},
// Use pug-loader handle .pug file
{
use: ['pug-loader'],
},
],
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
name: 'imgs/[name].[ext]',
},
},
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
name: 'fonts/[name].[ext]',
},
},
},
],
},
performance: {
maxEntrypointSize: 300000,
},
plugins: [
new VueLoaderPlugin(),
new HTMLPlugin({
filename: 'index.html',
template: path.resolve(__dirname, '../../src/index.pug'),
nodeModules: false,
isProd: process.env.NODE_ENV == 'production',
browser: process.browser,
__dirname,
}),
new webpack.DefinePlugin({
'process.env.IS_WEB': 'true',
}),
],
}

View File

@@ -1,57 +0,0 @@
const path = require('path')
const webpack = require('webpack')
const merge = require('webpack-merge')
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
const baseConfig = require('./webpack.config.base')
const { mergeCSSLoaderDev } = require('../utils')
module.exports = merge(baseConfig, {
mode: 'development',
devtool: 'eval-source-map',
output: {
filename: '[name].js',
path: path.join(__dirname, '../../dist/web'),
},
module: {
rules: [
{
test: /\.css$/,
oneOf: mergeCSSLoaderDev(),
},
{
test: /\.less$/,
oneOf: mergeCSSLoaderDev({
loader: 'less-loader',
options: {
sourceMap: true,
},
}),
},
{
test: /\.styl$/,
oneOf: mergeCSSLoaderDev({
loader: 'stylus-loader',
options: {
sourceMap: true,
},
}),
},
],
},
plugins: [
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"development"',
},
}),
new FriendlyErrorsPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin(),
],
performance: {
hints: false,
},
})

View File

@@ -1,94 +0,0 @@
const path = require('path')
const webpack = require('webpack')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const merge = require('webpack-merge')
const TerserPlugin = require('terser-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
const baseConfig = require('./webpack.config.base')
const { mergeCSSLoaderProd } = require('../utils')
module.exports = merge(baseConfig, {
mode: 'production',
devtool: false,
output: {
filename: '[name].[chunkhash:8].js',
},
module: {
rules: [
{
test: /\.css$/,
oneOf: mergeCSSLoaderProd(),
},
{
test: /\.less$/,
oneOf: mergeCSSLoaderProd({
loader: 'less-loader',
options: {
sourceMap: true,
},
}),
},
{
test: /\.styl$/,
oneOf: mergeCSSLoaderProd({
loader: 'stylus-loader',
options: {
sourceMap: true,
},
}),
},
],
},
plugins: [
new CopyWebpackPlugin([
{
from: path.join(__dirname, '../../src/static'),
to: path.join(__dirname, '../dist/web/static'),
ignore: ['.*'],
},
]),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"',
},
}),
new MiniCssExtractPlugin({
filename: '[name].[contentHash:8].css',
}),
new webpack.NamedChunksPlugin(),
],
optimization: {
minimizer: [
new TerserPlugin({
cache: true,
parallel: true,
sourceMap: false, // set to true if you want JS source maps
}),
new OptimizeCSSAssetsPlugin({}),
],
splitChunks: {
cacheGroups: {
// chunks: 'all',
vendors: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
enforce: true,
chunks: 'all',
},
styles: {
name: 'styles',
test: /\.(css|less)$/,
chunks: 'all',
enforce: true,
},
},
},
runtimeChunk: true,
},
performance: {
hints: 'warning',
},
})

17
jsconfig.json Normal file
View File

@@ -0,0 +1,17 @@
{
"compilerOptions": {
"baseUrl": "./",
"paths": {
"@/*": ["src/*"],
"@main/*": ["src/main/*"],
"@renderer/*": ["src/renderer/*"],
"@lyric/*": ["src/renderer-lyric/*"],
"@static/*": ["src/static/*"],
"@common/*": ["src/common/*"],
},
},
"vueCompilerOptions": {
"experimentalDisableTemplateSupport": true
},
"exclude": ["node_modules", "build", "dist"]
}

View File

@@ -1,45 +1,49 @@
{\rtf1\adeflang1025\ansi\ansicpg936\uc2\adeff31507\deff0\stshfdbch31505\stshfloch31506\stshfhich31506\stshfbi31507\deflang1033\deflangfe2052\themelang1033\themelangfe2052\themelangcs0{\fonttbl{\f2\fbidi \fmodern\fcharset0\fprq1{\*\panose 02070309020205020404}Courier New;}
{\rtf1\adeflang1025\ansi\ansicpg936\uc2\adeff0\deff0\stshfdbch31505\stshfloch31506\stshfhich31506\stshfbi0\deflang1033\deflangfe2052\themelang1033\themelangfe2052\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f2\fbidi \fmodern\fcharset0\fprq1{\*\panose 02070309020205020404}Courier New;}
{\f13\fbidi \fnil\fcharset134\fprq2{\*\panose 02010600030101010101}\'cb\'ce\'cc\'e5{\*\falt SimSun};}{\f34\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria Math;}
{\f44\fbidi \fnil\fcharset134\fprq2{\*\panose 02010600030101010101}@\'cb\'ce\'cc\'e5;}{\flomajor\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}
{\f44\fbidi \fnil\fcharset134\fprq2{\*\panose 00000000000000000000}@\'cb\'ce\'cc\'e5;}{\flomajor\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}
{\fdbmajor\f31501\fbidi \fnil\fcharset134\fprq2{\*\panose 02010600030101010101}\'b5\'c8\'cf\'df Light;}{\fhimajor\f31502\fbidi \fnil\fcharset134\fprq2{\*\panose 02010600030101010101}\'b5\'c8\'cf\'df Light;}
{\fbimajor\f31503\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\flominor\f31504\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}
{\fdbminor\f31505\fbidi \fnil\fcharset134\fprq2{\*\panose 02010600030101010101}\'b5\'c8\'cf\'df{\*\falt DengXian};}{\fhiminor\f31506\fbidi \fnil\fcharset134\fprq2{\*\panose 02010600030101010101}\'b5\'c8\'cf\'df{\*\falt DengXian};}
{\fbiminor\f31507\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f65\fbidi \fmodern\fcharset238\fprq1 Courier New CE;}{\f66\fbidi \fmodern\fcharset204\fprq1 Courier New Cyr;}
{\fbiminor\f31507\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f45\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\f46\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
{\f48\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f49\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f50\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f51\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
{\f52\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f53\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f65\fbidi \fmodern\fcharset238\fprq1 Courier New CE;}{\f66\fbidi \fmodern\fcharset204\fprq1 Courier New Cyr;}
{\f68\fbidi \fmodern\fcharset161\fprq1 Courier New Greek;}{\f69\fbidi \fmodern\fcharset162\fprq1 Courier New Tur;}{\f70\fbidi \fmodern\fcharset177\fprq1 Courier New (Hebrew);}{\f71\fbidi \fmodern\fcharset178\fprq1 Courier New (Arabic);}
{\f72\fbidi \fmodern\fcharset186\fprq1 Courier New Baltic;}{\f73\fbidi \fmodern\fcharset163\fprq1 Courier New (Vietnamese);}{\f177\fbidi \fnil\fcharset0\fprq2 SimSun Western{\*\falt SimSun};}{\f487\fbidi \fnil\fcharset0\fprq2 @SimSun Western;}
{\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}
{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbmajor\f31520\fbidi \fnil\fcharset0\fprq2 DengXian Light Western;}
{\fdbmajor\f31518\fbidi \fnil\fcharset238\fprq2 DengXian Light CE;}{\fdbmajor\f31519\fbidi \fnil\fcharset204\fprq2 DengXian Light Cyr;}{\fdbmajor\f31521\fbidi \fnil\fcharset161\fprq2 DengXian Light Greek;}
{\fhimajor\f31530\fbidi \fnil\fcharset0\fprq2 DengXian Light Western;}{\fhimajor\f31528\fbidi \fnil\fcharset238\fprq2 DengXian Light CE;}{\fhimajor\f31529\fbidi \fnil\fcharset204\fprq2 DengXian Light Cyr;}
{\fhimajor\f31531\fbidi \fnil\fcharset161\fprq2 DengXian Light Greek;}{\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbimajor\f31539\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}
{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}
{\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flominor\f31549\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}
{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbminor\f31560\fbidi \fnil\fcharset0\fprq2 DengXian Western{\*\falt DengXian};}
{\fdbminor\f31558\fbidi \fnil\fcharset238\fprq2 DengXian CE{\*\falt DengXian};}{\fdbminor\f31559\fbidi \fnil\fcharset204\fprq2 DengXian Cyr{\*\falt DengXian};}{\fdbminor\f31561\fbidi \fnil\fcharset161\fprq2 DengXian Greek{\*\falt DengXian};}
{\fhiminor\f31570\fbidi \fnil\fcharset0\fprq2 DengXian Western{\*\falt DengXian};}{\fhiminor\f31568\fbidi \fnil\fcharset238\fprq2 DengXian CE{\*\falt DengXian};}{\fhiminor\f31569\fbidi \fnil\fcharset204\fprq2 DengXian Cyr{\*\falt DengXian};}
{\fhiminor\f31571\fbidi \fnil\fcharset161\fprq2 DengXian Greek{\*\falt DengXian};}{\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbiminor\f31579\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}
{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}
{\f45\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\f46\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\f48\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f49\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}
{\f50\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f51\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\f52\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}
{\f53\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;
\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;\red0\green0\blue0;\red0\green0\blue0;}
{\*\defchp \fs21\kerning2\loch\af31506\hich\af31506\dbch\af31505 }{\*\defpap \ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{
\qj \li0\ri0\nowidctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \fs21\lang1033\langfe2052\kerning2\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp2052
{\f72\fbidi \fmodern\fcharset186\fprq1 Courier New Baltic;}{\f73\fbidi \fmodern\fcharset163\fprq1 Courier New (Vietnamese);}{\f177\fbidi \fnil\fcharset0\fprq2 SimSun Western{\*\falt SimSun};}{\f385\fbidi \froman\fcharset238\fprq2 Cambria Math CE;}
{\f386\fbidi \froman\fcharset204\fprq2 Cambria Math Cyr;}{\f388\fbidi \froman\fcharset161\fprq2 Cambria Math Greek;}{\f389\fbidi \froman\fcharset162\fprq2 Cambria Math Tur;}{\f392\fbidi \froman\fcharset186\fprq2 Cambria Math Baltic;}
{\f393\fbidi \froman\fcharset163\fprq2 Cambria Math (Vietnamese);}{\f487\fbidi \fnil\fcharset0\fprq2 @SimSun Western;}{\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}
{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}
{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}
{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbmajor\f31520\fbidi \fnil\fcharset0\fprq2 DengXian Light Western;}{\fdbmajor\f31518\fbidi \fnil\fcharset238\fprq2 DengXian Light CE;}
{\fdbmajor\f31519\fbidi \fnil\fcharset204\fprq2 DengXian Light Cyr;}{\fdbmajor\f31521\fbidi \fnil\fcharset161\fprq2 DengXian Light Greek;}{\fhimajor\f31530\fbidi \fnil\fcharset0\fprq2 DengXian Light Western;}
{\fhimajor\f31528\fbidi \fnil\fcharset238\fprq2 DengXian Light CE;}{\fhimajor\f31529\fbidi \fnil\fcharset204\fprq2 DengXian Light Cyr;}{\fhimajor\f31531\fbidi \fnil\fcharset161\fprq2 DengXian Light Greek;}
{\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbimajor\f31539\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}
{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}
{\flominor\f31549\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}
{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}
{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbminor\f31560\fbidi \fnil\fcharset0\fprq2 DengXian Western{\*\falt DengXian};}{\fdbminor\f31558\fbidi \fnil\fcharset238\fprq2 DengXian CE{\*\falt DengXian};}
{\fdbminor\f31559\fbidi \fnil\fcharset204\fprq2 DengXian Cyr{\*\falt DengXian};}{\fdbminor\f31561\fbidi \fnil\fcharset161\fprq2 DengXian Greek{\*\falt DengXian};}{\fhiminor\f31570\fbidi \fnil\fcharset0\fprq2 DengXian Western{\*\falt DengXian};}
{\fhiminor\f31568\fbidi \fnil\fcharset238\fprq2 DengXian CE{\*\falt DengXian};}{\fhiminor\f31569\fbidi \fnil\fcharset204\fprq2 DengXian Cyr{\*\falt DengXian};}{\fhiminor\f31571\fbidi \fnil\fcharset161\fprq2 DengXian Greek{\*\falt DengXian};}
{\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbiminor\f31579\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}
{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;
\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;
\red192\green192\blue192;\red0\green0\blue0;\red0\green0\blue0;\chyperlink\ctint255\cshade255\red5\green99\blue193;\red96\green94\blue92;\red225\green223\blue221;\cfollowedhyperlink\ctint255\cshade255\red149\green79\blue114;}{\*\defchp
\fs21\kerning2\loch\af31506\hich\af31506\dbch\af31505 }{\*\defpap \ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{
\qj \li0\ri0\nowidctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 \fs21\lang1033\langfe2052\kerning2\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp2052
\snext0 \sqformat \spriority0 Normal;}{\*\cs10 \additive \ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\*
\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv
\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \fs21\lang1033\langfe2052\kerning2\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp2052
\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs21\alang1025 \ltrch\fcs0 \fs21\lang1033\langfe2052\kerning2\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp2052
\snext11 \ssemihidden \sunhideused Normal Table;}{\s15\qj \li0\ri0\nowidctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af2\afs22\alang1025 \ltrch\fcs0
\fs21\lang1033\langfe2052\kerning2\loch\f31505\hich\af2\dbch\af31505\cgrid\langnp1033\langfenp2052 \sbasedon0 \snext15 \slink16 \sunhideused Plain Text;}{\*\cs16 \additive \rtlch\fcs1 \af2 \ltrch\fcs0 \loch\f31505\hich\af2 \sbasedon10 \slink15 \slocked
\'b4\'bf\'ce\'c4\'b1\'be \'d7\'d6\'b7\'fb;}}{\*\rsidtbl \rsid927107\rsid3950508\rsid11081282\rsid12910709\rsid13643782\rsid14384001}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0
\mnaryLim1}{\info{\author lysyw}{\operator lysyw}{\creatim\yr2019\mo8\dy17\hr10\min22}{\revtim\yr2019\mo8\dy17\hr10\min22}{\version2}{\edmins0}{\nofpages1}{\nofwords8}{\nofchars49}{\nofcharsws56}{\vern111}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.co
m/office/word/2003/wordml}}\paperw11906\paperh16838\margl2253\margr2253\margt1440\margb1440\gutter0\ltrsect
\'b4\'bf\'ce\'c4\'b1\'be \'d7\'d6\'b7\'fb;}{\*\cs17 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \ul\cf19 \sbasedon10 \sunhideused \styrsid9533173 Hyperlink;}{\*\cs18 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \cf20\chshdng0\chcfpat0\chcbpat21
\sbasedon10 \ssemihidden \sunhideused \styrsid9533173 Unresolved Mention;}{\*\cs19 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \ul\cf22 \sbasedon10 \ssemihidden \sunhideused \styrsid9533173 FollowedHyperlink;}}{\*\pgptbl {\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}}
{\*\rsidtbl \rsid927107\rsid1398824\rsid2109456\rsid3950508\rsid4133944\rsid4355753\rsid9533173\rsid10447395\rsid11081282\rsid12910709\rsid13643782\rsid14384001\rsid15226681}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0
\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1}{\info{\author lysyw}{\operator lysyw}{\creatim\yr2019\mo8\dy17\hr10\min22}{\revtim\yr2020\mo4\dy28\hr13\min46}{\version8}{\edmins3}{\nofpages1}{\nofwords135}{\nofchars772}{\nofcharsws906}{\vern1}}
{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/word/2003/wordml}}\paperw11906\paperh16838\margl2253\margr2253\margt1440\margb1440\gutter0\ltrsect
\deftab420\ftnbj\aenddoc\trackmoves0\trackformatting1\donotembedsysfont1\relyonvml0\donotembedlingdata0\grfdocevents0\validatexml1\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors1\formshade\horzdoc\dgmargin\dghspace180\dgvspace156
\dghorigin2253\dgvorigin1440\dghshow0\dgvshow2\jcompress\lnongrid
\viewkind1\viewscale100\splytwnine\ftnlytwnine\htmautsp\useltbaln\alntblind\lytcalctblwd\lyttblrtgr\lnbrkrule\nobrkwrptbl\snaptogridincell\allowfieldendsel\wrppunct\asianbrkrule\rsidroot3950508\newtblstyruls
\viewkind1\viewscale120\splytwnine\ftnlytwnine\htmautsp\useltbaln\alntblind\lytcalctblwd\lyttblrtgr\lnbrkrule\nobrkwrptbl\snaptogridincell\allowfieldendsel\wrppunct\asianbrkrule\rsidroot3950508\newtblstyruls
\nogrowautofit\usenormstyforlist\noindnmbrts\felnbrelev\nocxsptable\indrlsweleven\noafcnsttbl\afelev\utinl\hwelev\spltpgpar\notcvasp\notbrkcnstfrctbl\notvatxbx\krnprsnet\cachedcolbal \nouicompat {\upr{\*\fchars
!%),.:\'3b>?]\'7d\'a1\'e9\'a1\'a7\'a1\'e3\'a1\'a4\'a1\'a6\'a1\'a5\'a8\'44\'a1\'ac\'a1\'af\'a1\'b1\'a1\'ad\'a1\'eb\'a1\'e4\'a1\'e5?\'a1\'e6\'a1\'c3\'a1\'a2\'a1\'a3\'a1\'a8\'a1\'b5\'a1\'b7\'a1\'b9\'a1\'bb\'a1\'bf\'a1\'b3\'a1\'bd\'a8\'95\'a6\'e1\'a6\'e3\'a6\'e7\'a6\'e5\'a6\'eb\'a9\'77\'a9\'79\'a9\'7b\'a3\'a1\'a3\'a2\'a3\'a5\'a3\'a7\'a3\'a9\'a3\'ac\'a3\'ae\'a3\'ba\'a3\'bb\'a3\'bf\'a3\'dd\'a3\'e0\'a3\'fc\'a3\'fd\'a1\'ab\'a1\'e9
}{\*\ud\uc0{\*\fchars
@@ -49,18 +53,67 @@ $([\'7b{\uc2\u163 \'a1\'ea\u165 \'a3\'a4\'a1\'a4\'a1\'ae\'a1\'b0\'a1\'b4\'a1\'b6
\ilfomacatclnup0\ltrpar \sectd \ltrsect\linex0\headery851\footery992\colsx425\endnhere\sectlinegrid312\sectspecifyl\sectrsid2109456\sftnbj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta \dbch .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang
{\pntxta \dbch .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta \dbch .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta \dbch )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb \dbch (}{\pntxta \dbch )}}{\*\pnseclvl6
\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb \dbch (}{\pntxta \dbch )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb \dbch (}{\pntxta \dbch )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb \dbch (}{\pntxta \dbch )}}{\*\pnseclvl9
\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb \dbch (}{\pntxta \dbch )}}\pard\plain \ltrpar\s15\qj \li0\ri0\nowidctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid12910709 \rtlch\fcs1 \af2\afs22\alang1025 \ltrch\fcs0
\fs21\lang1033\langfe2052\kerning2\loch\af31505\hich\af2\dbch\af31505\cgrid\langnp1033\langfenp2052 {\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid12910709\charrsid12910709 \loch\af13\hich\af13\dbch\f13 \'b1\'be\'b3\'cc\'d0\'f2
\'bd\'f6\'d3\'c3\'d3\'da\'d1\'a7\'cf\'b0\'bd\'bb\'c1\'f7\'ca\'b9\'d3\'c3\'a3\'a1}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid12910709\charrsid12910709
\par }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid12910709\charrsid12910709 \loch\af13\hich\af13\dbch\f13 \'c7\'eb\'ce\'f0\'d3\'c3\'d3\'da\'c9\'cc\'d2\'b5\'d3\'c3\'cd\'be\'a3\'a1\'a3\'a1}{\rtlch\fcs1 \af13 \ltrch\fcs0
\loch\af13\hich\af13\dbch\af13\insrsid12910709\charrsid12910709
\par }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid12910709\charrsid12910709 \loch\af13\hich\af13\dbch\f13 \'ca\'b9\'d3\'c3\'b1\'be\'c8\'ed\'bc\'fe\'d4\'ec\'b3\'c9\'b5\'c4\'d2\'bb\'c7\'d0\'ba\'f3\'b9\'fb\'d3\'c9\'ca\'b9\'d3\'c3\'d5\'df
\'b3\'d0\'b5\'a3\'a3\'a1}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid12910709\charrsid12910709
\par
\par \hich\af13\dbch\af13\loch\f13 By: }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid12910709\charrsid12910709 \loch\af13\hich\af13\dbch\f13 \'c2\'e4\'d1\'a9\'ce\'de\'ba\'db}{\rtlch\fcs1 \af13 \ltrch\fcs0
\loch\af13\hich\af13\dbch\af13\insrsid12910709\charrsid12910709
\par
\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb \dbch (}{\pntxta \dbch )}}\pard\plain \ltrpar\s15\qj \li0\ri0\nowidctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid1398824 \rtlch\fcs1 \af2\afs22\alang1025 \ltrch\fcs0
\fs21\lang1033\langfe2052\kerning2\loch\af31505\hich\af2\dbch\af31505\cgrid\langnp1033\langfenp2052 {\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid1398824\charrsid1398824 \loch\af13\hich\af13\dbch\f13 \'b1\'be\'cf\'ee\'c4\'bf\'a3\'a8
\'c8\'ed\'bc\'fe\'a3\'a9\'bb\'f9\'d3\'da}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid1398824\charrsid4133944 \hich\af13\dbch\af13\loch\f13 Apache License 2.0}{\rtlch\fcs1 \af13 \ltrch\fcs0
\loch\af13\hich\af13\dbch\af13\insrsid1398824\charrsid1398824 \hich\af13\dbch\af13\loch\f13 }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid1398824\charrsid1398824 \loch\af13\hich\af13\dbch\f13 \'d0\'ed\'bf\'c9\'d6\'a4\'b7\'a2
\'d0\'d0\'a3\'ac\'d4\'da\'ca\'b9\'d3\'c3\'b1\'be\'c8\'ed\'bc\'fe\'c7\'b0\'a3\'ac\'c4\'e3\'a3\'a8\'ca\'b9\'d3\'c3\'d5\'df\'a3\'a9\'d0\'e8\'c7\'a9\'ca\'f0\'b1\'be\'d0\'ad\'d2\'e9\'b2\'c5\'bf\'c9\'bc\'cc\'d0\'f8\'ca\'b9\'d3\'c3\'a3\'ac\'d2\'d4\'cf\'c2
\'d0\'ad\'d2\'e9\'ca\'c7\'b6\'d4\'d3\'da}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid1398824\charrsid1398824 \hich\af13\dbch\af13\loch\f13 Apache Li\hich\af13\dbch\af13\loch\f13 cense 2.0 }{\rtlch\fcs1 \af13 \ltrch\fcs0
\loch\af13\hich\af13\dbch\af13\insrsid1398824\charrsid1398824 \loch\af13\hich\af13\dbch\f13 \'b5\'c4\'b2\'b9\'b3\'e4\'a3\'ac\'c8\'e7\'d3\'d0\'b3\'e5\'cd\'bb\'a3\'ac\'d2\'d4\'d2\'d4\'cf\'c2\'d0\'ad\'d2\'e9\'ce\'aa\'d7\'bc\'a1\'a3}{\rtlch\fcs1 \af13
\ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid1398824
\par }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid15226681
\par }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid10447395\charrsid1398824
\par }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid1398824\charrsid1398824 \loch\af13\hich\af13\dbch\f13 \'b4\'ca\'d3\'ef\'d4\'bc\'b6\'a8\'a3\'ba\'b1\'be\'d0\'ad\'d2\'e9\'d6\'d0\'b5\'c4\'a1\'b0\'b1\'be\'c8\'ed\'bc\'fe\'a1\'b1\'d6\'b8
\'c2\'e5\'d1\'a9\'d2\'f4\'c0\'d6\'d7\'c0\'c3\'e6\'b0\'e6\'cf\'ee\'c4\'bf\'a3\'bb\'a1\'b0\'ca\'b9\'d3\'c3\'d5\'df\'a1\'b1\'d6\'b8\'c7\'a9\'ca\'f0\'b1\'be\'d0\'ad\'d2\'e9\'b5\'c4\'ca\'b9\'d3\'c3\'d5\'df\'a3\'bb\'a1\'b0\'b9\'d9\'b7\'bd\'d2\'f4\'c0\'d6
\'c6\'bd\'cc\'a8\'a1\'b1\'d6\'b8\'b6\'d4\'b1\'be\'c8\'ed\'bc\'fe\'c4\'da\'d6\'c3\'b5\'c4\'b0\'fc\'c0\'a8\'bf\'e1\'ce\'d2\'a1\'a2\'bf\'e1\'b9\'b7\'a1\'a2\'df\'e4\'b9\'be\'b5\'c8\'d2\'f4\'c0\'d6\'d4\'b4\'b5\'c4\'b9\'d9\'b7\'bd\'c6\'bd\'cc\'a8\'cd\'b3
\'b3\'c6\'a3\'bb\'a1\'b0\'b0\'e6\'c8\'a8\'ca\'fd\'be\'dd\'a1\'b1\'d6\'b8\'b0\'fc\'c0\'a8\'b5\'ab\'b2\'bb\'cf\'de\'d3\'da\'cd\'bc\'cf\'f1\'a1\'a2\'d2\'f4\'c6\'b5\'a1\'a2\'c3\'fb\'d7\'d6\'b5\'c8\'d4\'da\'c4\'da\'b5\'c4\'cb\'fb\'c8\'cb\'d3\'b5\'d3\'d0
\'cb\'f9\'ca\'f4\'b0\'e6\'c8\'a8\'b5\'c4\'ca\'fd\'be\'dd\'a1\'a3}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid1398824\charrsid1398824
\par
\par \hich\af13\dbch\af13\loch\f13 1}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid1398824\charrsid1398824 \loch\af13\hich\af13\dbch\f13 \'a1\'a2\'b1\'be\'c8\'ed\'bc\'fe\'b5\'c4\'ca\'fd\'be\'dd\'c0\'b4\'d4\'b4\'d4\'ad\'c0\'ed\'ca\'c7
\'b4\'d3\'b8\'f7\'b9\'d9\'b7\'bd\'d2\'f4\'c0\'d6\'c6\'bd\'cc\'a8\'b5\'c4\'b9\'ab\'bf\'aa\'b7\'fe\'ce\'f1\'c6\'f7\'d6\'d0\'c0\'ad\'c8\'a1\'ca\'fd\'be\'dd\'a3\'ac\'be\'ad\'b9\'fd\'b6\'d4\'ca\'fd\'be\'dd\'bc\'f2\'b5\'a5\'b5\'d8\'c9\'b8\'d1\'a1\'d3\'eb
\'ba\'cf\'b2\'a2\'ba\'f3\'bd\'f8\'d0\'d0\'d5\'b9\'ca\'be\'a3\'ac\'d2\'f2\'b4\'cb\'b1\'be\'c8\'ed\'bc\'fe\'b2\'bb\'b6\'d4\'ca\'fd\'be\'dd\'b5\'c4\'d7\'bc\'c8\'b7\'d0\'d4\'b8\'ba\'d4\'f0\'a1\'a3}{\rtlch\fcs1 \af13 \ltrch\fcs0
\loch\af13\hich\af13\dbch\af13\insrsid1398824\charrsid1398824
\par \hich\af13\dbch\af13\loch\f13 2}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid1398824\charrsid1398824 \loch\af13\hich\af13\dbch\f13 \'a1\'a2\'ca\'b9\'d3\'c3\'b1\'be\'c8\'ed\'bc\'fe\'b5\'c4\'b9\'fd\'b3\'cc\'d6\'d0\'bf\'c9\'c4\'dc
\'bb\'e1\'b2\'fa\'c9\'fa\'b0\'e6\'c8\'a8\'ca\'fd\'be\'dd\'a3\'ac\'b6\'d4\'d3\'da\'d5\'e2\'d0\'a9\'b0\'e6\'c8\'a8\'ca\'fd\'be\'dd\'a3\'ac\'b1\'be\'c8\'ed\'bc\'fe\'b2\'bb\'d3\'b5\'d3\'d0\'cb\'fc\loch\af13\hich\af13\dbch\f13 \'c3\'c7\'b5\'c4\'cb\'f9\'d3\'d0
\'c8\'a8\'a3\'ac\'ce\'aa\'c1\'cb\'b1\'dc\'c3\'e2\'d4\'ec\'b3\'c9\'c7\'d6\'c8\'a8\'a3\'ac\'ca\'b9\'d3\'c3\'d5\'df\'ce\'f1\'b1\'d8\'d4\'da}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid1398824\charrsid1398824
\hich\af13\dbch\af13\loch\f13 24}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid1398824\charrsid1398824 \loch\af13\hich\af13\dbch\f13 \'d0\'a1\'ca\'b1\'c4\'da\'c7\'e5\'b3\'fd\'ca\'b9\'d3\'c3\'b1\'be\'c8\'ed\'bc\'fe\'b5\'c4\'b9\'fd
\'b3\'cc\'d6\'d0\'cb\'f9\'b2\'fa\'c9\'fa\'b5\'c4\'b0\'e6\'c8\'a8\'ca\'fd\'be\'dd\'a1\'a3}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid1398824\charrsid1398824
\par \hich\af13\dbch\af13\loch\f13 3}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid1398824\charrsid1398824 \loch\af13\hich\af13\dbch\f13 \'a1\'a2\'b1\'be\'c8\'ed\'bc\'fe\'c4\'da\'b5\'c4\'b9\'d9\'b7\'bd\'d2\'f4\'c0\'d6\'c6\'bd\'cc\'a8
\'b1\'f0\'c3\'fb\'ce\'aa\'b1\'be\'c8\'ed\'bc\'fe\'c4\'da\'b6\'d4\'b9\'d9\'b7\'bd\'d2\'f4\'c0\'d6\'c6\'bd\'cc\'a8\'b5\'c4\'d2\'bb\'b8\'f6\'b3\'c6\'ba\'f4\'a3\'ac\'b2\'bb\'b0\'fc\'ba\'ac\'b6\'f1\'d2\'e2\'a3\'ac\'c8\'e7\'b9\'fb\'b9\'d9\'b7\'bd\'d2\'f4
\'c0\'d6\'c6\'bd\'cc\'a8\'be\'f5\'b5\'c3\'b2\'bb\'cd\'d7\'a3\'ac\'bf\'c9\'c1\'aa\'cf\'b5\'b1\'be\'c8\'ed\'bc\'fe\'b8\'fc\'b8\'c4\'bb\'f2\'d2\'c6\'b3\'fd\'a1\'a3}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid1398824\charrsid1398824
\par \hich\af13\dbch\af13\loch\f13 4}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid1398824\charrsid1398824 \loch\af13\hich\af13\dbch\f13 \'a1\'a2\'b1\'be\'c8\'ed\'bc\'fe\'c4\'da\'ca\'b9\'d3\'c3\'b5\'c4\'b2\'bf\'b7\'d6\'b0\'fc\'c0\'a8
\'b5\'ab\'b2\'bb\'cf\'de\'d3\'da\'d7\'d6\'cc\'e5\'a1\'a2\'cd\'bc\'c6\'ac\'b5\'c8\'d7\'ca\'d4\'b4\'c0\'b4\'d4\'b4\'d3\'da\'bb\'a5\'c1\'aa\'cd\'f8\'a3\'ac\'c8\'e7\'b9\'fb\'b3\'f6\'cf\'d6\'c7\'d6\'c8\'a8\'bf\'c9\'c1\'aa\'cf\'b5\'b1\'be\'c8\'ed\'bc\'fe
\'d2\'c6\'b3\'fd\'a1\'a3}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid1398824\charrsid1398824
\par \hich\af13\dbch\af13\loch\f13 5}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid1398824\charrsid1398824 \loch\af13\hich\af13\dbch\f13 \'a1\'a2\'d3\'c9\'d3\'da\'ca\'b9\'d3\'c3\'b1\'be\'c8\'ed\'bc\'fe\'b2\'fa\'c9\'fa\'b5\'c4\'b0\'fc
\'c0\'a8\'d3\'c9\'d3\'da\'b1\'be\'d0\'ad\'d2\'e9\'bb\'f2\'d3\'c9\'d3\'da\'ca\'b9\'d3\'c3\'bb\'f2\'ce\'de\'b7\'a8\'ca\'b9\'d3\'c3\'b1\'be\'c8\'ed\'bc\'fe\'b6\'f8\'d2\'fd\'c6\'f0\'b5\'c4\'c8\'ce\'ba\'ce\'d0\'d4\'d6\'ca\'b5\'c4\'c8\'ce\'ba\'ce\'d6\'b1
\'bd\'d3\'a1\'a2\'bc\'e4\'bd\'d3\'a1\'a2\'cc\'d8\'ca\'e2\'a1\'a2\'c5\'bc\'c8\'bb\'bb\'f2\'bd\'e1\'b9\'fb\'d0\'d4\'cb\'f0\'ba\'a6\'a3\'a8\'b0\'fc\'c0\'a8\'b5\'ab\'b2\'bb\'cf\'de\'d3\'da\'d2\'f2\'c9\'cc\'d3\'fe\'cb\'f0\'ca\'a7\'a1\'a2\'cd\'a3\'b9\'a4
\'a1\'a2\'bc\'c6\'cb\'e3\'bb\'fa\'b9\'ca\'d5\'cf\'bb\'f2\'b9\'ca\'d5\'cf\'d2\'fd\'c6\'f0\'b5\'c4\'cb\'f0\'ba\'a6\'c5\'e2\'b3\'a5\'a3\'ac\'bb\'f2\'c8\'ce\'ba\'ce\'bc\'b0\loch\af13\hich\af13\dbch\f13 \'cb\'f9\'d3\'d0\'c6\'e4\'cb\'fb\'c9\'cc\'d2\'b5\'cb\'f0
\'ba\'a6\'bb\'f2\'cb\'f0\'ca\'a7\'a3\'a9\'d3\'c9\'ca\'b9\'d3\'c3\'d5\'df\'b8\'ba\'d4\'f0\'a1\'a3}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid1398824\charrsid1398824
\par \hich\af13\dbch\af13\loch\f13 6}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid1398824\charrsid1398824 \loch\af13\hich\af13\dbch\f13 \'a1\'a2\'b1\'be\'cf\'ee\'c4\'bf\'cd\'ea\'c8\'ab\'c3\'e2\'b7\'d1\'a3\'ac\'c7\'d2\'bf\'aa\'d4\'b4
\'b7\'a2\'b2\'bc\'d3\'da}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid1398824\charrsid1398824 \hich\af13\dbch\af13\loch\f13 GitHub }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid1398824\charrsid1398824
\loch\af13\hich\af13\dbch\f13 \'c3\'e6\'cf\'f2\'c8\'ab\'ca\'c0\'bd\'e7\'c8\'cb\'d3\'c3\'d7\'f7\'b6\'d4\'bc\'bc\'ca\'f5\'b5\'c4\'d1\'a7\'cf\'b0\'bd\'bb\'c1\'f7\'a3\'ac\'b1\'be\'c8\'ed\'bc\'fe\'b2\'bb\'b6\'d4\'cf\'ee\'c4\'bf\'c4\'da\'b5\'c4\'bc\'bc\'ca\'f5
\'bf\'c9\'c4\'dc\'b4\'e6\'d4\'da\'ce\'a5\'b7\'b4\'b5\'b1\'b5\'d8\'b7\'a8\'c2\'c9\'b7\'a8\'b9\'e6\'b5\'c4\'d0\'d0\'ce\'aa\'d7\'f7\'b1\'a3\'d6\'a4\'a3\'ac\'bd\'fb\'d6\'b9\'d4\'da\'ce\'a5\'b7\'b4\'b5\'b1\'b5\'d8\'b7\'a8\'c2\'c9\'b7\'a8\'b9\'e6\'b5\'c4
\'c7\'e9\'bf\'f6\'cf\'c2\'ca\'b9\'d3\'c3\'b1\'be\'c8\'ed\'bc\'fe\'a3\'ac\'b6\'d4\'d3\'da\'ca\'b9\'d3\'c3\'d5\'df\'d4\'da\'c3\'f7\'d6\'aa\'bb\'f2\'b2\'bb\'d6\'aa\'b5\'b1\'b5\'d8\'b7\'a8\'c2\'c9\'b7\'a8\'b9\'e6\'b2\'bb\'d4\'ca\'d0\'ed\'b5\'c4\'c7\'e9
\'bf\'f6\'cf\'c2\'ca\'b9\'d3\'c3\'b1\'be\'c8\'ed\'bc\'fe\'cb\'f9\'d4\'ec\'b3\'c9\'b5\'c4\'c8\'ce\'ba\'ce\'ce\'a5\'b7\'a8\'ce\'a5\'b9\'e6\'d0\'d0\'ce\'aa\'d3\'c9\'ca\'b9\'d3\'c3\'d5\'df\'b3\'d0\'b5\'a3\'a3\'ac\'b1\'be\'c8\'ed\'bc\'fe\'b2\'bb\'b3\'d0
\'b5\'a3\'d3\'c9\'b4\'cb\'d4\'ec\'b3\'c9\'b5\'c4\'c8\'ce\'ba\'ce\'d6\'b1\'bd\'d3\'a1\'a2\'bc\'e4\'bd\'d3\'a1\'a2\'cc\'d8\'ca\'e2\'a1\'a2\'c5\'bc\'c8\'bb\'bb\'f2\'bd\'e1\'b9\'fb\'d0\'d4\'d4\'f0\'c8\'ce\'a1\'a3}{\rtlch\fcs1 \af13 \ltrch\fcs0
\loch\af13\hich\af13\dbch\af13\insrsid1398824
\par }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid15226681
\par }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid10447395\charrsid1398824
\par }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid1398824\charrsid1398824 \hich\af13\dbch\af13\loch\f13 * }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid1398824\charrsid1398824 \loch\af13\hich\af13\dbch\f13
\'c8\'f4\'d0\'ad\'d2\'e9\'b8\'fc\'d0\'c2\'a3\'ac\'cb\'a1\'b2\'bb\'c1\'ed\'d0\'d0\'cd\'a8\'d6\'aa\'a3\'ac\'bf\'c9\'b5\'bd\'bf\'aa\'d4\'b4\'b5\'d8\'d6\'b7\'b2\'e9\'bf\'b4\'a1\'a3}{\rtlch\fcs1 \af13 \ltrch\fcs0
\loch\af13\hich\af13\dbch\af13\insrsid1398824\charrsid15226681
\par }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid1398824\charrsid1398824 \hich\af13\dbch\af13\loch\f13 * }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid1398824\charrsid1398824 \loch\af13\hich\af13\dbch\f13
\'b1\'be\'c8\'ed\'bc\'fe\'b5\'c4\'b3\'f5\'d6\'d4\'ca\'c7\'b0\'ef\'d6\'fa\'b9\'d9\'b7\'bd\'d2\'f4\'c0\'d6\'c6\'bd\'cc\'a8\'bc\'f2\'bb\'af\'ca\'fd\'be\'dd\'ba\'f3\'b4\'fa\'ce\'aa\'d5\'b9\'ca\'be\'a3\'ac\'b0\'ef\'d6\'fa\'ca\'b9\'d3\'c3\'d5\'df\'b8\'f9
\'be\'dd\'b8\'e8\'c7\'fa\loch\af13\hich\af13\dbch\f13 \'c3\'fb\'a1\'a2\'d2\'d5\'ca\'f5\'bc\'d2\'b5\'c8\'b9\'d8\'bc\'fc\'d7\'d6\'bf\'ec\'cb\'d9\'b5\'d8\'b6\'a8\'ce\'bb\'cb\'f9\'d0\'e8\'c4\'da\'c8\'dd\'cb\'f9\'d4\'da\'b5\'c4\'d2\'f4\'c0\'d6\'c6\'bd\'cc\'a8
\'a1\'a3}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid1398824\charrsid15226681
\par }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid1398824\charrsid1398824 \hich\af13\dbch\af13\loch\f13 * }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid1398824\charrsid1398824 \loch\af13\hich\af13\dbch\f13
\'d2\'f4\'c0\'d6\'c6\'bd\'cc\'a8\'b2\'bb\'d2\'d7\'a3\'ac\'bd\'a8\'d2\'e9\'b5\'bd\'b6\'d4\'d3\'a6\'d2\'f4\'c0\'d6\'c6\'bd\'cc\'a8\'d6\'a7\'b3\'d6\'d5\'fd\'b0\'e6\'d7\'ca\'d4\'b4\'a1\'a3}{\rtlch\fcs1 \af13 \ltrch\fcs0
\loch\af13\hich\af13\dbch\af13\insrsid12910709
\par }{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid9533173\charrsid15226681
\par }\pard \ltrpar\s15\qj \li0\ri0\nowidctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid12910709 {\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid12910709\charrsid12910709 \hich\af13\dbch\af13\loch\f13 By: }{
\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid12910709\charrsid12910709 \loch\af13\hich\af13\dbch\f13 \'c2\'e4\'d1\'a9\'ce\'de\'ba\'db}{\rtlch\fcs1 \af13 \ltrch\fcs0 \loch\af13\hich\af13\dbch\af13\insrsid12910709\charrsid12910709
\par }{\*\themedata 504b030414000600080000002100e9de0fbfff0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb4ec3301045f748fc83e52d4a
9cb2400825e982c78ec7a27cc0c8992416c9d8b2a755fbf74cd25442a820166c2cd933f79e3be372bd1f07b5c3989ca74aaff2422b24eb1b475da5df374fd9ad
5689811a183c61a50f98f4babebc2837878049899a52a57be670674cb23d8e90721f90a4d2fa3802cb35762680fd800ecd7551dc18eb899138e3c943d7e503b6
@@ -114,7 +167,7 @@ e4350d363f2451eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8
617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169
6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363
656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e}
{\*\latentstyles\lsdstimax377\lsdlockeddef0\lsdsemihiddendef0\lsdunhideuseddef0\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1;
{\*\latentstyles\lsdstimax376\lsdlockeddef0\lsdsemihiddendef0\lsdunhideuseddef0\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1;
\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 2;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 3;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 4;
\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 5;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 6;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 7;
\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 8;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 9;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 1;
@@ -143,18 +196,8 @@ e4350d363f2451eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Address;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Cite;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Code;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Definition;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Keyboard;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Preformatted;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Sample;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Typewriter;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 HTML Variable;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 annotation subject;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 No List;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 1;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Simple 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Simple 2;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Simple 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Classic 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Classic 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Classic 3;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Classic 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Colorful 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Colorful 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Colorful 3;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Columns 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Columns 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Columns 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Columns 4;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Columns 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 3;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 6;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 7;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Grid 8;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 3;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 4;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 5;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 6;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 7;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table List 8;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table 3D effects 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table 3D effects 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table 3D effects 3;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Contemporary;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Elegant;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Professional;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Subtle 1;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Subtle 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Web 1;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Table Web 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Balloon Text;
\lsdpriority39 \lsdlocked0 Table Grid;\lsdsemihidden1 \lsdlocked0 Placeholder Text;\lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing;\lsdpriority60 \lsdlocked0 Light Shading;\lsdpriority61 \lsdlocked0 Light List;\lsdpriority62 \lsdlocked0 Light Grid;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 2;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Outline List 3;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Balloon Text;\lsdpriority39 \lsdlocked0 Table Grid;
\lsdsemihidden1 \lsdlocked0 Placeholder Text;\lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing;\lsdpriority60 \lsdlocked0 Light Shading;\lsdpriority61 \lsdlocked0 Light List;\lsdpriority62 \lsdlocked0 Light Grid;
\lsdpriority63 \lsdlocked0 Medium Shading 1;\lsdpriority64 \lsdlocked0 Medium Shading 2;\lsdpriority65 \lsdlocked0 Medium List 1;\lsdpriority66 \lsdlocked0 Medium List 2;\lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdpriority68 \lsdlocked0 Medium Grid 2;
\lsdpriority69 \lsdlocked0 Medium Grid 3;\lsdpriority70 \lsdlocked0 Dark List;\lsdpriority71 \lsdlocked0 Colorful Shading;\lsdpriority72 \lsdlocked0 Colorful List;\lsdpriority73 \lsdlocked0 Colorful Grid;\lsdpriority60 \lsdlocked0 Light Shading Accent 1;
\lsdpriority61 \lsdlocked0 Light List Accent 1;\lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1;\lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1;\lsdpriority65 \lsdlocked0 Medium List 1 Accent 1;
@@ -202,8 +245,8 @@ e4350d363f2451eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8
\lsdpriority49 \lsdlocked0 List Table 4 Accent 5;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 5;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 5;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 5;
\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 6;\lsdpriority47 \lsdlocked0 List Table 2 Accent 6;\lsdpriority48 \lsdlocked0 List Table 3 Accent 6;\lsdpriority49 \lsdlocked0 List Table 4 Accent 6;
\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 6;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Mention;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Smart Hyperlink;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Hashtag;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Unresolved Mention;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Smart Link;
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Smart Link Error;}}{\*\datastore 0105000002000000180000004d73786d6c322e534158584d4c5265616465722e362e3000000000000000000000060000
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Smart Hyperlink;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Hashtag;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Unresolved Mention;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Smart Link;}}{\*\datastore 01050000
02000000180000004d73786d6c322e534158584d4c5265616465722e362e3000000000000000000000060000
d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff090006000000000000000000000001000000010000000000000000100000feffffff00000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
@@ -212,8 +255,8 @@ fffffffffffffffffdfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffff0c6ad98892f1d411a65f0040963251e5000000000000000000000000908a
0599a254d501feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000
ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffff0c6ad98892f1d411a65f0040963251e5000000000000000000000000b026
8d59201dd601feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000105000000000000}}

View File

@@ -1,5 +1,18 @@
This program is only for learning to communicate!
Do not use for commercial purposes! !
All consequences of using this software are borne by the user!
This project (software) is issued based on the Apache License 2.0 license. Before using this software, you (users) need to sign this agreement before you can continue to use it. The following agreement is a supplement to the Apache License 2.0. In case of conflict, use the following agreement Shall prevail.
Terms agreed: "this software" in this agreement refers to the Luo Xue Music desktop version of the project; "user" refers to the user who signed this agreement; "official music platform" refers to the built-in software including Kuwo, Kugou, Migu The official platforms of music sources, etc. are collectively referred to; "copyright data" refers to data including but not limited to images, audio, names, etc. that others own the copyright.
1. The principle of the data source of this software is to pull data from the public servers of each official music platform. After simply filtering and merging the data for display, this software is not responsible for the accuracy of the data.
2. Copyright data may be generated during the use of this software. For this copyright data, the software does not own their ownership. In order to avoid infringement, users must clear the copyright generated during the use of this software within 24 hours data.
3. The alias of the official music platform in this software is a name for the official music platform in the software. It does not contain maliciousness. If the official music platform feels inappropriate, you can contact the software to change or remove it.
4. The parts used in this software include but are not limited to fonts, pictures and other resources from the Internet. If there is infringement, you can contact this software to remove it.
5. Any direct, indirect, special, accidental or consequential damage of any nature arising from the use of this software, including this agreement or the use or inability to use this software (including but not limited to due to loss of goodwill, work stoppage, Compensation for computer failure or damage caused by the failure, or any and all other commercial damage or loss) is the responsibility of the user.
6. This project is completely free, and the open source is published on GitHub. It is used by people all over the world to learn and exchange technology. This software does not guarantee that the technology in the project may violate local laws and regulations. It is prohibited to violate local laws and regulations. Using this software, the user shall be responsible for any violations caused by the user's use of the software without knowing or not permitted by local laws and regulations. The software shall not be responsible for any direct, indirect, special, accidental Or consequential responsibility.
* If the agreement is updated without prior notice, you can check it at the open source address.
* The original intention of this software is to help the official music platform to simplify the data generation for display, and to help users quickly locate the music platform where the desired content is based on the song title, artist and other keywords.
* Music platform is not easy, it is recommended to support genuine resources to the corresponding music platform.
By: lyswhut

View File

@@ -1,5 +1,18 @@
程序仅用于学习交流使用!
请勿用于商业用途!!
使用本软件造成的一切后果由使用者承担!
项目软件基于Apache License 2.0 许可证发行,在使用本软件前,你(使用者)需签署本协议才可继续使用,以下协议是对于 Apache License 2.0 的补充,如有冲突,以以下协议为准。
词语约定:本协议中的“本软件”指洛雪音乐桌面版项目;“使用者”指签署本协议的使用者;“官方音乐平台”指对本软件内置的包括酷我、酷狗、咪咕等音乐源的官方平台统称;“版权数据”指包括但不限于图像、音频、名字等在内的他人拥有所属版权的数据。
1、本软件的数据来源原理是从各官方音乐平台的公开服务器中拉取数据经过对数据简单地筛选与合并后进行展示因此本软件不对数据的准确性负责。
2、使用本软件的过程中可能会产生版权数据对于这些版权数据本软件不拥有它们的所有权为了避免造成侵权使用者务必在24小时内清除使用本软件的过程中所产生的版权数据。
3、本软件内的官方音乐平台别名为本软件内对官方音乐平台的一个称呼不包含恶意如果官方音乐平台觉得不妥可联系本软件更改或移除。
4、本软件内使用的部分包括但不限于字体、图片等资源来源于互联网如果出现侵权可联系本软件移除。
5、由于使用本软件产生的包括由于本协议或由于使用或无法使用本软件而引起的任何性质的任何直接、间接、特殊、偶然或结果性损害包括但不限于因商誉损失、停工、计算机故障或故障引起的损害赔偿或任何及所有其他商业损害或损失由使用者负责。
6、本项目完全免费且开源发布于 GitHub 面向全世界人用作对技术的学习交流,本软件不对项目内的技术可能存在违反当地法律法规的行为作保证,禁止在违反当地法律法规的情况下使用本软件,对于使用者在明知或不知当地法律法规不允许的情况下使用本软件所造成的任何违法违规行为由使用者承担,本软件不承担由此造成的任何直接、间接、特殊、偶然或结果性责任。
* 若协议更新,恕不另行通知,可到开源地址查看。
* 本软件的初衷是帮助官方音乐平台简化数据后代为展示,帮助使用者根据歌曲名、艺术家等关键字快速地定位所需内容所在的音乐平台。
* 音乐平台不易,建议到对应音乐平台支持正版资源。
By: 落雪无痕

41303
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,82 +1,123 @@
{
"name": "lx-music-desktop",
"version": "0.7.0",
"description": "一个免费的音乐下载助手",
"main": "./dist/electron/main.js",
"version": "1.22.3",
"description": "一个免费的音乐查找助手",
"main": "./dist/main.js",
"productName": "lx-music-desktop",
"scripts": {
"pack": "node build-config/pack.js && npm run pack:win",
"pack:win": "npm run pack:win:setup && npm run pack:win:7z",
"pack:win:setup": "cross-env TARGET=win_安装版 ARCH=x64_x86 electron-builder -w=nsis --x64 --ia32",
"pack:win:portable": "npm run pack:win:portable:x64_x86 && npm run pack:win:portable:x64 && npm run pack:win:portable:x86",
"pack:win:portable:x64_x86": "cross-env TARGET=便携版 ARCH=x64_x86 electron-builder -w=portable --x64 --ia32",
"pack:win:portable:x64": "cross-env TARGET=便携版 ARCH=x64 electron-builder -w=portable --x64",
"pack:win:portable:x86": "cross-env TARGET=便携版 ARCH=x86 electron-builder -w=portable --ia32",
"pack": "node build-config/pack.js && npm run pack:win:setup:x64",
"pack:win": "node build-config/pack.js && npm run pack:win:setup:x64 && npm run pack:win:setup:x86 && npm run pack:win:setup:arm64 && npm run pack:win:setup:x86_64 && npm run pack:win:7z",
"pack:win:setup:x86_64": "cross-env TARGET=Setup ARCH=x86_64 electron-builder -w=nsis --x64 --ia32 -p never",
"pack:win:setup:x64": "cross-env TARGET=Setup ARCH=x64 electron-builder -w=nsis --x64 -p never",
"pack:win:setup:x86": "cross-env TARGET=Setup ARCH=x86 electron-builder -w=nsis --ia32 -p never",
"pack:win:setup:arm64": "cross-env TARGET=Setup ARCH=arm64 electron-builder -w=nsis --arm64 -p never",
"pack:win:portable": "npm run pack:win:portable:x86_64 && npm run pack:win:portable:x64 && npm run pack:win:portable:x86",
"pack:win:portable:x86_64": "cross-env TARGET=portable ARCH=x86_64 electron-builder -w=portable --x64 --ia32 -p never",
"pack:win:portable:x64": "cross-env TARGET=portable ARCH=x64 electron-builder -w=portable --x64 -p never",
"pack:win:portable:x86": "cross-env TARGET=portable ARCH=x86 electron-builder -w=portable --ia32 -p never",
"pack:win:7z": "npm run pack:win:7z:x64 && npm run pack:win:7z:x86",
"pack:win:7z:x64": "cross-env TARGET=win_绿色版 ARCH=x64 electron-builder -w=7z --x64",
"pack:win:7z:x86": "cross-env TARGET=win_绿色版 ARCH=x86 electron-builder -w=7z --ia32",
"pack:win:7z:x64": "cross-env TARGET=green ARCH=win_x64 electron-builder -w=7z --x64 -p never",
"pack:win:7z:x86": "cross-env TARGET=green ARCH=win_x86 electron-builder -w=7z --ia32 -p never",
"pack:win:7z:arm64": "cross-env TARGET=green ARCH=win_arm64 electron-builder -w=7z --arm64 -p never",
"pack:linux": "node build-config/pack.js && npm run pack:linux:deb && npm run pack:linux:appImage && npm run pack:linux:rpm && npm run pack:linux:pacman",
"pack:linux:appImage": "cross-env ARCH=x64 electron-builder -l=AppImage -p never",
"pack:linux:deb": "npm run pack:linux:deb:x64 && npm run pack:linux:deb:x86 && npm run pack:linux:deb:arm64 && npm run pack:linux:deb:armv7l",
"pack:linux:deb:x64": "cross-env ARCH=x64 electron-builder -l=deb --x64 -p never",
"pack:linux:deb:x86": "cross-env ARCH=x86 electron-builder -l=deb --ia32 -p never",
"pack:linux:deb:arm64": "cross-env ARCH=arm64 electron-builder -l=deb --arm64 -p never",
"pack:linux:deb:armv7l": "cross-env ARCH=armv7l electron-builder -l=deb --armv7l -p never",
"pack:linux:rpm": "cross-env ARCH=x64 electron-builder -l=rpm --x64 -p never",
"pack:linux:pacman": "cross-env ARCH=x64 electron-builder -l=pacman --x64 -p never",
"pack:mac": "node build-config/pack.js && npm run pack:mac:dmg && npm run pack:mac:dmg:arm64",
"pack:mac:dmg": "cross-env electron-builder -m=dmg -p never",
"pack:mac:dmg:arm64": "cross-env electron-builder -m=dmg --arm64 -p never",
"pack:dir": "node build-config/pack.js && electron-builder --dir",
"publish": "node publish",
"publish:gh": "node build-config/pack.js && npm run publish:win",
"publish:win": "npm run publish:win:7z && npm run publish:win:setup",
"publish:win:setup": "cross-env TARGET=Setup ARCH=x64_x86 electron-builder -w=nsis --x64 --ia32 -p onTagOrDraft",
"publish:win:portable": "npm run publish:win:portable:x64_x86 && npm run publish:win:portable:x64 && npm run publish:win:portable:x86",
"publish:win:portable:x64_x86": "cross-env TARGET=portable ARCH=x64_x86 electron-builder -w=portable --x64 --ia32 -p onTagOrDraft",
"publish:win:setup:x64:always": "cross-env TARGET=Setup ARCH=x64 electron-builder -w=nsis --x64 -p always",
"publish:win:setup:x64": "cross-env TARGET=Setup ARCH=x64 electron-builder -w=nsis --x64 -p always",
"publish:win:setup:x86": "cross-env TARGET=Setup ARCH=x86 electron-builder -w=nsis --ia32 -p onTagOrDraft",
"publish:win:setup:arm64": "cross-env TARGET=Setup ARCH=arm64 electron-builder -w=nsis --arm64 -p onTagOrDraft",
"publish:win:setup:x86_64": "cross-env TARGET=Setup ARCH=x86_64 electron-builder -w=nsis --x64 --ia32 -p onTagOrDraft",
"publish:win:portable": "npm run publish:win:portable:x86_64 && npm run publish:win:portable:x64 && npm run publish:win:portable:x86",
"publish:win:portable:x86_64": "cross-env TARGET=portable ARCH=x86_64 electron-builder -w=portable --x64 --ia32 -p onTagOrDraft",
"publish:win:portable:x64": "cross-env TARGET=portable ARCH=x64 electron-builder -w=portable --x64 -p onTagOrDraft",
"publish:win:portable:x86": "cross-env TARGET=portable ARCH=x86 electron-builder -w=portable --ia32 -p onTagOrDraft",
"publish:win:7z": "npm run publish:win:7z:x64 && npm run publish:win:7z:x86",
"publish:win:7z:x64": "cross-env TARGET=green ARCH=win_x64 electron-builder -w=7z --x64 -p always",
"publish:win:7z:x64": "cross-env TARGET=green ARCH=win_x64 electron-builder -w=7z --x64 -p onTagOrDraft",
"publish:win:7z:x86": "cross-env TARGET=green ARCH=win_x86 electron-builder -w=7z --ia32 -p onTagOrDraft",
"publish:gh:mac": "node build-config/pack.js && npm run publish:mac",
"publish:mac": "npm run publish:mac:dmg",
"publish:win:7z:arm64": "cross-env TARGET=green ARCH=win_arm64 electron-builder -w=7z --arm64 -p onTagOrDraft",
"publish:mac:dmg:always": "electron-builder -m=dmg -p always",
"publish:mac:dmg": "electron-builder -m=dmg -p onTagOrDraft",
"publish:gh:linux": "node build-config/pack.js && npm run publish:linux",
"publish:linux": "npm run publish:linux:deb && npm run publish:linux:appImage",
"publish:linux:appImage": "cross-env ARCH=x64 electron-builder -l=AppImage -p onTagOrDraft",
"publish:linux:deb": "npm run publish:linux:deb:x64 && npm run publish:linux:deb:x86",
"publish:mac:dmg:arm64": "electron-builder -m=dmg --arm64 -p onTagOrDraft",
"publish:linux:deb:x64:always": "cross-env ARCH=x64 electron-builder -l=deb --x64 -p always",
"publish:linux:deb:x64": "cross-env ARCH=x64 electron-builder -l=deb --x64 -p onTagOrDraft",
"publish:linux:deb:x86": "cross-env ARCH=x86 electron-builder -l=deb --ia32 -p onTagOrDraft",
"pack:linux": "node build-config/pack.js && electron-builder -l",
"pack:dir": "node build-config/pack.js && electron-builder --dir",
"publish:linux:deb:arm64": "cross-env ARCH=arm64 electron-builder -l=deb --arm64 -p onTagOrDraft",
"publish:linux:deb:armv7l": "cross-env ARCH=armv7l electron-builder -l=deb --armv7l -p onTagOrDraft",
"publish:linux:appImage": "cross-env ARCH=x64 electron-builder -l=AppImage -p onTagOrDraft",
"publish:linux:rpm": "cross-env ARCH=x64 electron-builder -l=rpm --x64 -p onTagOrDraft",
"publish:linux:pacman": "cross-env ARCH=x64 electron-builder -l=pacman --x64 -p onTagOrDraft",
"dev": "node build-config/runner-dev.js",
"clean:electron": "rimraf dist/electron",
"clean:web": "rimraf dist/web",
"clean:electron": "rimraf dist",
"clean": "rimraf dist && rimraf build",
"build:main": "cross-env NODE_ENV=production webpack --config build-config/main/webpack.config.prod.js --progress --hide-modules",
"build:renderer": "cross-env NODE_ENV=production webpack --config build-config/renderer/webpack.config.prod.js --progress --hide-modules",
"build:web": "npm run clean:web && cross-env NODE_ENV=production webpack --config build-config/web/webpack.config.prod.js --progress --hide-modules",
"build": "npm run clean:electron && npm run build:main && npm run build:renderer",
"lint": "eslint --ext .js,.vue -f ./node_modules/eslint-formatter-friendly src",
"lint:fix": "eslint --ext .js,.vue -f ./node_modules/eslint-formatter-friendly --fix src"
"build:src": "node build-config/pack.js",
"build:main": "cross-env NODE_ENV=production webpack --config build-config/main/webpack.config.prod.js --progress",
"build:renderer": "cross-env NODE_ENV=production webpack --config build-config/renderer/webpack.config.prod.js --progress",
"build:renderer-lyric": "cross-env NODE_ENV=production webpack --config build-config/renderer-lyric/webpack.config.prod.js --progress",
"build": "npm run clean:electron && npm run build:main && npm run build:renderer && npm run build:renderer-lyric",
"lint": "eslint --ext .js,.vue -f node_modules/eslint-formatter-friendly src",
"lint:fix": "eslint --ext .js,.vue -f node_modules/eslint-formatter-friendly --fix src",
"dp": "cross-env ELECTRON_GET_USE_PROXY=true GLOBAL_AGENT_HTTPS_PROXY=http://localhost:1081 npm run pack",
"up": "cross-env ELECTRON_GET_USE_PROXY=true GLOBAL_AGENT_HTTPS_PROXY=http://localhost:1081 npm i"
},
"browserslist": [
"Chrome >= 76"
"Electron 15.5.7"
],
"engines": {
"node": ">= 12"
"node": ">= 16",
"npm": ">=8.5.2"
},
"build": {
"appId": "cn.toside.music.desktop",
"protocols": {
"name": "lx-music-protocol",
"schemes": [
"lxmusic"
]
},
"directories": {
"buildResources": "./resources",
"output": "./build"
},
"files": [
"dist/electron/**/*"
"dist/**/*"
],
"asar": {
"smartUnpack": false
},
"extraResources": [
"./licenses"
],
"win": {
"icon": "./resources/icons/256x256.ico",
"icon": "./resources/icons/icon.ico",
"legalTrademarks": "lyswhut",
"artifactName": "${productName} v${version} ${env.ARCH} ${env.TARGET}.${ext}"
},
"mac": {
"icon": "./resources/icons/512x512.png",
"category": "public.app-category.music"
"icon": "./resources/icons/icon.icns",
"category": "public.app-category.music",
"extendInfo": {
"CFBundleName": "lx-music-desktop",
"CFBundleDisplayName": "LX Music"
}
},
"linux": {
"maintainer": "lyswhut <lyswuhut@qq.com>",
"artifactName": "${productName} v${version} ${env.ARCH}.${ext}"
"maintainer": "lyswhut <lyswhut@qq.com>",
"artifactName": "${productName} v${version} ${env.ARCH}.${ext}",
"icon": "./resources/icons",
"category": "Utility;AudioVideo;Audio;Player;Music;",
"desktop": {
"Name[zh_CN]": "洛雪音乐助手"
}
},
"nsis": {
"oneClick": false,
@@ -84,28 +125,31 @@
"allowToChangeInstallationDirectory": true,
"differentialPackage": true,
"license": "./licenses/license.rtf",
"shortcutName": "lx-music"
"shortcutName": "LX Music"
},
"dmg": {
"window": {
"width": 600,
"height": 400
},
"contents": [
{
"x": 110,
"y": 150,
"name": "lx-music"
"x": 106,
"y": 252,
"name": "LX Music"
},
{
"x": 240,
"y": 150,
"x": 490,
"y": 252,
"type": "link",
"path": "/Applications",
"name": "lx-music"
"path": "/Applications"
}
],
"title": "洛雪音乐助手 v${version}"
},
"appImage": {
"license": "./licenses/license_zh.txt",
"category": "Audio"
"category": "Utility;AudioVideo;Audio;Player;Music;"
},
"publish": [
{
@@ -126,7 +170,7 @@
],
"author": {
"name": "lyswhut",
"email": "lyswuhut@qq.com"
"email": "lyswhut@qq.com"
},
"license": "Apache-2.0",
"bugs": {
@@ -134,83 +178,96 @@
},
"homepage": "https://github.com/lyswhut/lx-music-desktop#readme",
"devDependencies": {
"@babel/core": "^7.6.2",
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
"@babel/polyfill": "^7.6.0",
"@babel/preset-env": "^7.6.2",
"autoprefixer": "^9.6.4",
"babel-eslint": "^10.0.3",
"babel-loader": "^8.0.6",
"babel-minify-webpack-plugin": "^0.3.1",
"babel-preset-minify": "^0.5.1",
"cfonts": "^2.4.5",
"chalk": "^2.4.2",
"changelog-parser": "^2.8.0",
"copy-webpack-plugin": "^5.0.4",
"core-js": "^3.2.1",
"cos-nodejs-sdk-v5": "^2.5.12",
"cross-env": "^6.0.3",
"css-loader": "^3.2.0",
"del": "^5.1.0",
"electron": "^6.0.11",
"electron-builder": "^21.2.0",
"electron-debug": "^3.0.1",
"electron-devtools-installer": "^2.2.4",
"eslint": "^6.5.1",
"eslint-config-standard": "^14.1.0",
"eslint-formatter-friendly": "^7.0.0",
"eslint-loader": "^3.0.2",
"eslint-plugin-html": "^6.0.0",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-node": "^10.0.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.0.1",
"file-loader": "^4.2.0",
"friendly-errors-webpack-plugin": "^1.7.0",
"html-webpack-plugin": "^3.2.0",
"less": "^3.10.3",
"less-loader": "^5.0.0",
"markdown-it": "^10.0.0",
"mini-css-extract-plugin": "^0.8.0",
"multispinner": "^0.2.1",
"optimize-css-assets-webpack-plugin": "^5.0.3",
"postcss-loader": "^3.0.0",
"pug": "^2.0.4",
"@babel/core": "^7.18.10",
"@babel/eslint-parser": "^7.18.9",
"@babel/plugin-proposal-class-properties": "^7.18.6",
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/plugin-transform-modules-umd": "^7.18.6",
"@babel/plugin-transform-runtime": "^7.18.10",
"@babel/preset-env": "^7.18.10",
"babel-loader": "^8.2.5",
"babel-preset-minify": "^0.5.2",
"browserslist": "^4.21.3",
"chalk": "^4.1.2",
"changelog-parser": "^2.8.1",
"copy-webpack-plugin": "^11.0.0",
"core-js": "^3.24.1",
"cross-env": "^7.0.3",
"css-loader": "^6.7.1",
"css-minimizer-webpack-plugin": "^4.0.0",
"del": "^6.1.1",
"electron": "^15.5.7",
"electron-builder": "^23.3.3",
"electron-debug": "^3.2.0",
"electron-devtools-installer": "^3.2.0",
"electron-to-chromium": "^1.4.224",
"electron-updater": "^5.2.1",
"eslint": "^8.22.0",
"eslint-config-standard": "^17.0.0",
"eslint-formatter-friendly": "git+https://github.com/lyswhut/eslint-friendly-formatter.git#2170d1320e2fad13615a9dcf229669f0bb473a53",
"eslint-plugin-html": "^7.1.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^6.0.0",
"eslint-webpack-plugin": "^3.2.0",
"file-loader": "^6.2.0",
"html-webpack-plugin": "^5.5.0",
"less": "^4.1.3",
"less-loader": "^11.0.0",
"mini-css-extract-plugin": "^2.6.1",
"node-loader": "^2.0.0",
"postcss": "^8.4.16",
"postcss-loader": "^7.0.1",
"postcss-pxtorem": "^6.0.0",
"pug": "^3.0.2",
"pug-loader": "^2.4.0",
"pug-plain-loader": "^1.0.0",
"raw-loader": "^3.1.0",
"rimraf": "^3.0.0",
"stylus": "^0.54.7",
"stylus-loader": "^3.0.2",
"terser-webpack-plugin": "^2.1.2",
"url-loader": "^2.2.0",
"vue-loader": "^15.7.1",
"vue-style-loader": "^4.1.2",
"vue-template-compiler": "^2.6.10",
"webpack": "^4.41.0",
"webpack-cli": "^3.3.9",
"webpack-dev-server": "^3.8.2",
"webpack-hot-middleware": "^2.25.0",
"webpack-merge": "^4.2.2"
"pug-plain-loader": "^1.1.0",
"raw-loader": "^4.0.2",
"rimraf": "^3.0.2",
"spinnies": "git+https://github.com/lyswhut/spinnies.git#233305c58694aa3b053e3ab9af9049993f918b9d",
"svg-sprite-loader": "^6.0.11",
"svg-transform-loader": "^2.0.13",
"svgo-loader": "^3.0.1",
"terser": "^5.14.2",
"terser-webpack-plugin": "^5.3.5",
"url-loader": "^4.1.1",
"vue-loader": "^17.0.0",
"vue-template-compiler": "^2.7.8",
"webpack": "^5.74.0",
"webpack-cli": "^4.10.0",
"webpack-dev-server": "^4.10.0",
"webpack-hot-middleware": "git+https://github.com/lyswhut/webpack-hot-middleware.git#329c4375134b89d39da23a56a94db651247c74a1",
"webpack-merge": "^5.8.0"
},
"dependencies": {
"axios": "^0.19.0",
"crypto-js": "^3.1.9-1",
"dnscache": "^1.0.2",
"electron-log": "^3.0.8",
"electron-store": "^5.0.0",
"electron-updater": "^4.1.2",
"flac-metadata": "^0.1.1",
"js-htmlencode": "^0.3.0",
"lrc-file-parser": "^0.1.12",
"node-downloader-helper": "^1.0.10",
"node-id3": "^0.1.11",
"request": "^2.88.0",
"vue": "^2.6.10",
"vue-electron": "^1.0.6",
"vue-router": "^3.1.3",
"vuex": "^3.1.1",
"vuex-electron": "^1.0.3",
"vuex-router-sync": "^5.0.0"
"bufferutil": "^4.0.6",
"crypto-js": "^4.1.1",
"electron-log": "^4.4.8",
"electron-store": "^8.1.0",
"font-list": "git+https://github.com/lyswhut/node-font-list.git#4edbb1933b49a9bac1eedd63a31da16b487fe57d",
"http-terminator": "^3.2.0",
"iconv-lite": "^0.6.3",
"image-size": "^1.0.2",
"koa": "^2.13.4",
"long": "^5.2.0",
"mitt": "^3.0.0",
"needle": "^3.1.0",
"node-id3": "^0.2.3",
"request": "^2.88.2",
"socket.io": "^4.5.1",
"sortablejs": "^1.15.0",
"tunnel": "^0.0.6",
"utf-8-validate": "^5.0.9",
"vue": "^3.2.37",
"vue-i18n": "^9.2.2",
"vue-router": "^4.1.3",
"vuex": "^4.0.2"
},
"overrides": {
"async": "^2.3.0",
"got": "^11.8.5",
"svg-sprite-loader": {
"postcss": "8.2.13"
}
}
}

View File

@@ -1,7 +1,28 @@
const autoprefixer = require('autoprefixer')
// const autoprefixer = require('autoprefixer')
const pxtorem = require('postcss-pxtorem')
module.exports = {
plugins: [
autoprefixer(),
pxtorem({
rootValue: 16,
unitPrecision: 5,
propList: [
'font', 'font-size',
'letter-spacing',
'padding', 'margin',
'padding-*', 'margin-*',
'height', 'width',
'*-height', '*-width',
'flex', '::-webkit-scrollbar',
'top', 'left', 'bottom', 'right',
'border-radius', 'gap',
],
selectorBlackList: ['html', 'ignore-to-rem'],
replace: true,
mediaQuery: false,
minPixelValue: 0,
exclude: [/node_modules/i],
}),
// autoprefixer(),
],
}

View File

@@ -1,19 +1,3 @@
#### 新增
### 修复
- 新增“我的收藏”本地播放列表
- 新增缓存清理功能,可到**设置-其他**查看与清理软件缓存
- 新增QQ音乐源搜索
- 新增咪咕源搜索
- 新增咪咕源歌单
- 新增咪咕源排行榜
- 新增我的音乐列表歌曲源显示,默认关闭,可到**设置-列表设置**开启
#### 优化
- 优化选择框动画效果
- 尝试优化选我的音乐列表内容很多时多选的卡顿问题
#### 修复
- 修复列表延迟显示的Bug
- 修复QQ音源128k音质试听
- 修复因音源的域名到期导致的音源失效的问题

View File

@@ -9,12 +9,12 @@ const version_bak = JSON.stringify(version, null, 2)
const parseChangelog = require('changelog-parser')
const changelogPath = jp('../../CHANGELOG.md')
const md_renderer = markdownStr => new (require('markdown-it'))({
html: true,
linkify: true,
typographer: true,
breaks: true,
}).render(markdownStr)
// const md_renderer = markdownStr => new (require('markdown-it'))({
// html: true,
// linkify: true,
// typographer: true,
// breaks: true,
// }).render(markdownStr)
const getPrevVer = () => parseChangelog(changelogPath).then(res => {
if (!res.versions.length) throw new Error('CHANGELOG 无法解析到版本号')
@@ -25,10 +25,10 @@ const updateChangeLog = async(newVerNum, newChangeLog) => {
let changeLog = fs.readFileSync(changelogPath, 'utf-8')
const prevVer = await getPrevVer()
const log = `## [${newVerNum}](${pkg.repository.url.replace(/^git\+(http.+)\.git$/, '$1')}/compare/v${prevVer}...v${newVerNum}) - ${formatTime()}\n\n${newChangeLog}`
fs.writeFileSync(changelogPath, changeLog.replace(new RegExp(`(## [?0.1.1]?)`), log + '\n$1'), 'utf-8')
fs.writeFileSync(changelogPath, changeLog.replace(new RegExp('(## [?0.1.1]?)'), log + '\n$1'), 'utf-8')
}
const renderChangeLog = md => md_renderer(md)
// const renderChangeLog = md => md_renderer(md)
module.exports = async newVerNum => {
@@ -38,18 +38,18 @@ module.exports = async newVerNum => {
newVerNum = verArr.join('.')
}
const newMDChangeLog = fs.readFileSync(jp('../changeLog.md'), 'utf-8')
const newChangeLog = renderChangeLog(newMDChangeLog)
// const newChangeLog = renderChangeLog(newMDChangeLog)
version.history.unshift({
version: version.version,
desc: version.desc,
})
version.version = newVerNum
version.desc = newChangeLog
version.desc = newMDChangeLog.replace(/(?:^|(\n))#{1,6} (.+)\n/g, '$1$2').trim()
pkg.version = newVerNum
console.log(chalk.blue('new version: ') + chalk.green(newVerNum))
fs.writeFileSync(jp('../version.json'), JSON.stringify(version, null, 2) + '\n', 'utf-8')
fs.writeFileSync(jp('../version.json'), JSON.stringify(version) + '\n', 'utf-8')
fs.writeFileSync(jp(pkgDir), JSON.stringify(pkg, null, 2) + '\n', 'utf-8')
@@ -58,7 +58,7 @@ module.exports = async newVerNum => {
return {
pkg_bak,
version_bak,
changeLog: newChangeLog,
// changeLog: newChangeLog,
}
}

File diff suppressed because one or more lines are too long

BIN
resources/icons/128x128.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

BIN
resources/icons/16x16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 488 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

BIN
resources/icons/256x256.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

BIN
resources/icons/32x32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 901 B

BIN
resources/icons/48x48.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 17 KiB

BIN
resources/icons/64x64.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
resources/icons/icon.icns Normal file

Binary file not shown.

BIN
resources/icons/icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
resources/icons/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

130
src/common/config.js Normal file
View File

@@ -0,0 +1,130 @@
module.exports = {
windowSizeList: [
{
id: 0,
name: 'smaller',
width: 828,
height: 530,
fontSize: '14px',
},
{
id: 1,
name: 'small',
width: 920,
height: 590,
fontSize: '16px',
},
{
id: 2,
name: 'medium',
width: 1018,
height: 650,
fontSize: '16px',
},
{
id: 3,
name: 'big',
width: 1114,
height: 708,
fontSize: '17px',
},
{
id: 4,
name: 'larger',
width: 1202,
height: 766,
fontSize: '17px',
},
{
id: 5,
name: 'oversized',
width: 1382,
height: 886,
fontSize: '18px',
},
{
id: 6,
name: 'huge',
width: 1686,
height: 1062,
fontSize: '19px',
},
],
navigationUrlWhiteList: [
],
themes: [
{
id: 0,
name: '绿意盎然',
className: 'green',
},
{
id: 1,
name: '蓝田生玉',
className: 'blue',
},
{
id: 2,
name: '信口雌黄',
className: 'yellow',
},
{
id: 3,
name: '橙黄橘绿',
className: 'orange',
},
{
id: 4,
name: '热情似火',
className: 'red',
},
{
id: 10,
name: '粉装玉琢',
className: 'pink',
},
{
id: 5,
name: '重斤球紫',
className: 'purple',
},
{
id: 6,
name: '灰常美丽',
className: 'grey',
},
{
id: 11,
name: '青出于黑',
className: 'ming',
},
{
id: 12,
name: '青出于黑',
className: 'blue2',
},
{
id: 13,
name: '黑灯瞎火',
className: 'black',
},
{
id: 7,
name: '月里嫦娥',
className: 'mid_autumn',
},
{
id: 8,
name: '木叶之村',
className: 'naruto',
},
{
id: 9,
name: '新年快乐',
className: 'happy_new_year',
},
],
themeLights: [0, 1, 2, 3, 4, 10, 5, 6, 11, 12, 7, 8, 9],
themeDarks: [13, 7],
}

View File

@@ -0,0 +1,89 @@
const { player: hotKeyPlayer, common: hotKeyCommon, desktop_lyric: hotKeyDesktopLyric } = require('./hotKey')
module.exports = {
local: {
enable: true,
keys: {
'mod+f5': {
type: hotKeyPlayer.toggle_play.type,
name: hotKeyPlayer.toggle_play.name,
action: hotKeyPlayer.toggle_play.action,
},
'mod+arrowleft': {
type: hotKeyPlayer.prev.type,
name: hotKeyPlayer.prev.name,
action: hotKeyPlayer.prev.action,
},
'mod+arrowright': {
type: hotKeyPlayer.next.type,
name: hotKeyPlayer.next.name,
action: hotKeyPlayer.next.action,
},
f1: {
type: hotKeyCommon.focusSearchInput.type,
name: hotKeyCommon.focusSearchInput.name,
action: hotKeyCommon.focusSearchInput.action,
},
},
},
global: {
enable: false,
keys: {
MediaPlayPause: {
type: hotKeyPlayer.toggle_play.type,
name: null,
action: hotKeyPlayer.toggle_play.action,
},
MediaPreviousTrack: {
type: hotKeyPlayer.prev.type,
name: null,
action: hotKeyPlayer.prev.action,
},
MediaNextTrack: {
type: hotKeyPlayer.next.type,
name: null,
action: hotKeyPlayer.next.action,
},
'mod+alt+f5': {
type: hotKeyPlayer.toggle_play.type,
name: hotKeyPlayer.toggle_play.name,
action: hotKeyPlayer.toggle_play.action,
},
'mod+alt+arrowleft': {
type: hotKeyPlayer.prev.type,
name: hotKeyPlayer.prev.name,
action: hotKeyPlayer.prev.action,
},
'mod+alt+arrowright': {
type: hotKeyPlayer.next.type,
name: hotKeyPlayer.next.name,
action: hotKeyPlayer.next.action,
},
'mod+alt+arrowup': {
type: hotKeyPlayer.volume_up.type,
name: hotKeyPlayer.volume_up.name,
action: hotKeyPlayer.volume_up.action,
},
'mod+alt+arrowdown': {
type: hotKeyPlayer.volume_down.type,
name: hotKeyPlayer.volume_down.name,
action: hotKeyPlayer.volume_down.action,
},
'mod+alt+0': {
type: hotKeyDesktopLyric.toggle_visible.type,
name: hotKeyDesktopLyric.toggle_visible.name,
action: hotKeyDesktopLyric.toggle_visible.action,
},
'mod+alt+-': {
type: hotKeyDesktopLyric.toggle_lock.type,
name: hotKeyDesktopLyric.toggle_lock.name,
action: hotKeyDesktopLyric.toggle_lock.action,
},
'mod+alt+=': {
type: hotKeyDesktopLyric.toggle_always_top.type,
name: hotKeyDesktopLyric.toggle_always_top.name,
action: hotKeyDesktopLyric.toggle_always_top.action,
},
},
},
}

View File

@@ -0,0 +1,142 @@
const path = require('path')
const os = require('os')
const defaultSetting = {
version: '1.0.59',
player: {
togglePlayMethod: 'listLoop',
highQuality: false,
isShowTaskProgess: true,
volume: 1,
isMute: false,
mediaDeviceId: 'default',
isMediaDeviceRemovedStopPlay: false,
isShowLyricTranslation: false,
isShowLyricRoma: false,
isS2t: false, // 是否将歌词从简体转换为繁体
isPlayLxlrc: true,
isSavePlayTime: false,
audioVisualization: false,
waitPlayEndStop: true,
waitPlayEndStopTime: '',
autoSkipOnError: true,
},
playDetail: {
isZoomActiveLrc: true,
isShowLyricProgressSetting: false,
style: {
fontSize: 100,
align: 'center',
},
},
desktopLyric: {
enable: false,
isLock: false,
isAlwaysOnTop: false,
isAlwaysOnTopLoop: false,
width: 450,
height: 300,
x: null,
y: null,
theme: 0,
isLockScreen: true,
isDelayScroll: true,
isHoverHide: false,
style: {
font: '',
fontSize: 120,
opacity: 95,
isZoomActiveLrc: true,
},
},
list: {
isClickPlayList: false,
isShowAlbumName: true,
isShowSource: true,
isSaveScrollLocation: true,
addMusicLocationType: 'top',
},
download: {
enable: false,
savePath: path.join(os.homedir(), 'Desktop'),
fileName: '歌名 - 歌手',
maxDownloadNum: 3,
isDownloadLrc: false,
lrcFormat: 'utf8',
isEmbedPic: true,
isEmbedLyric: false,
isUseOtherSource: false,
},
leaderboard: {
source: 'kw',
tabId: 'kw__16',
},
songList: {
source: 'kg',
sortId: '5',
tagInfo: {
name: '默认',
id: null,
},
},
odc: {
isAutoClearSearchInput: false,
isAutoClearSearchList: false,
},
search: {
searchSource: 'all',
tempSearchSource: 'kw',
isShowHotSearch: false,
isShowHistorySearch: false,
isFocusSearchBox: false,
},
network: {
proxy: {
enable: false,
host: '',
port: '',
username: '',
password: '',
},
},
tray: {
isShow: false,
isToTray: false,
themeId: 0,
},
sync: {
enable: false,
port: '23332',
},
windowSizeId: 2,
startInFullscreen: false,
theme: {
id: 0,
lightId: 0,
darkId: 13,
},
langId: null,
sourceId: 'kw',
apiSource: 'temp',
sourceNameType: 'alias',
font: '',
isShowAnimation: true,
randomAnimate: true,
ignoreVersion: null,
isAgreePact: false,
controlBtnPosition: process.platform === 'darwin' ? 'left' : 'right',
}
const overwriteSetting = {
}
// 使用新年皮肤
if (new Date().getMonth() < 2) {
defaultSetting.theme.id = 9
defaultSetting.desktopLyric.theme = 3
}
exports.defaultSetting = defaultSetting
exports.overwriteSetting = overwriteSetting

12
src/common/error.js Normal file
View File

@@ -0,0 +1,12 @@
const { log } = require('./utils')
process.on('uncaughtException', function(err) {
console.error('An uncaught error occurred!')
console.error(err)
log.error(err)
})
process.on('unhandledRejection', (reason, p) => {
console.error('Unhandled Rejection at: Promise ', p)
console.error(' reason: ', reason)
log.error(reason)
})

84
src/common/hotKey.js Normal file
View File

@@ -0,0 +1,84 @@
const names = require('@main/events/_name')
const hotKey = {
common: {
min: {
name: 'min',
action: 'min',
},
min_toggle: {
name: 'toggle_min',
action: 'toggle_min',
},
hide_toggle: {
name: 'toggle_hide',
action: 'toggle_hide',
},
close: {
name: 'toggle_close',
action: 'toggle_close',
},
focusSearchInput: {
name: 'focus_search_input',
action: 'focus_search_input',
},
},
player: {
toggle_play: {
name: 'toggle_play',
action: 'toggle_play',
},
next: {
name: 'next',
action: 'next',
},
prev: {
name: 'prev',
action: 'prev',
},
volume_up: {
name: 'volume_up',
action: 'volume_up',
},
volume_down: {
name: 'volume_down',
action: 'volume_down',
},
volume_mute: {
name: 'volume_mute',
action: 'volume_mute',
},
},
desktop_lyric: {
toggle_visible: {
name: 'toggle_visible',
action: 'toggle_visible',
},
toggle_lock: {
name: 'toggle_lock',
action: 'toggle_lock',
},
toggle_always_top: {
name: 'toggle_always_top',
action: 'toggle_always_top',
},
},
}
const keyName = {
common: names.mainWindow.name,
player: names.mainWindow.name,
desktop_lyric: names.winLyric.name,
}
for (const type of Object.keys(hotKey)) {
let item = hotKey[type]
for (const key of Object.keys(item)) {
item[key].action = `${type}_${item[key].action}`
item[key].name = `${type}_${item[key].name}`
item[key].type = keyName[type]
}
}
exports.common = hotKey.common
exports.player = hotKey.player
exports.desktop_lyric = hotKey.desktop_lyric

View File

@@ -1,19 +0,0 @@
const { ipcMain, ipcRenderer } = require('electron')
export const mainSend = (name, params) => {
ipcMain.send(name, params)
}
export const mainOn = (name, callback) => {
ipcMain.on(name, callback)
}
export const rendererSend = (name, params) => {
ipcRenderer.send(name, params)
}
export const rendererOn = (name, callback) => {
ipcRenderer.on(name, callback)
}

52
src/common/ipc.js Normal file
View File

@@ -0,0 +1,52 @@
const { ipcMain, ipcRenderer } = require('electron')
const names = require('./ipcNames')
exports.mainOn = (name, callback) => {
ipcMain.on(name, callback)
}
exports.mainOnce = (name, callback) => {
ipcMain.once(name, callback)
}
exports.mainOff = (name, callback) => {
ipcMain.removeListener(name, callback)
}
exports.mainOffAll = name => {
ipcMain.removeAllListeners(name)
}
exports.mainHandle = (name, callback) => {
ipcMain.handle(name, callback)
}
exports.mainHandleOnce = (name, callback) => {
ipcMain.handleOnce(name, callback)
}
exports.mainHandleRemove = name => {
ipcMain.removeListener(name)
}
exports.mainSend = (window, name, params) => {
window.webContents.send(name, params)
}
exports.rendererSend = (name, params) => {
ipcRenderer.send(name, params)
}
exports.rendererSendSync = (name, params) => ipcRenderer.sendSync(name, params)
exports.rendererInvoke = (name, params) => ipcRenderer.invoke(name, params)
exports.rendererOn = (name, callback) => {
ipcRenderer.on(name, callback)
}
exports.rendererOnce = (name, callback) => {
ipcRenderer.once(name, callback)
}
exports.rendererOff = (name, callback) => {
ipcRenderer.removeListener(name, callback)
}
exports.rendererOffAll = name => {
ipcRenderer.removeAllListeners(name)
}
exports.NAMES = names

126
src/common/ipcNames.js Normal file
View File

@@ -0,0 +1,126 @@
const names = {
mainWindow: {
focus: 'focus',
close: 'close',
min: 'min',
max: 'max',
fullscreen: 'fullscreen',
set_app_name: 'set_app_name',
clear_cache: 'clear_cache',
get_cache_size: 'get_cache_size',
get_env_params: 'get_env_params',
clear_env_params_deeplink: 'clear_env_params_deeplink',
wait: 'wait',
wait_cancel: 'wait_cancel',
interval: 'interval',
interval_callback: 'interval_callback',
interval_cancel: 'interval_cancel',
open_dev_tools: 'open_dev_tools',
system_theme_change: 'system_theme_change',
set_music_meta: 'set_music_meta',
progress: 'progress',
change_tray: 'change_tray',
quit_update: 'quit_update',
update_available: 'update_available',
update_error: 'update_error',
update_progress: 'update_progress',
update_downloaded: 'update_downloaded',
update_not_available: 'update_not_available',
set_ignore_mouse_events: 'set_ignore_mouse_events',
set_app_setting: 'set_app_setting',
set_window_size: 'set_window_size',
show_save_dialog: 'show_save_dialog',
get_system_fonts: 'get_system_fonts',
handle_request: 'handle_request',
cancel_request: 'cancel_request',
handle_xm_verify_open: 'handle_xm_verify_open',
handle_xm_verify_close: 'handle_xm_verify_close',
select_dir: 'select_dir',
restart_window: 'restart_window',
lang_s2t: 'lang_s2t',
handle_kw_decode_lyric: 'handle_kw_decode_lyric',
get_lyric_info: 'get_lyric_info',
set_lyric_info: 'set_lyric_info',
set_config: 'set_config',
set_hot_key_config: 'set_hot_key_config',
key_down: 'key_down',
quit: 'quit',
min_toggle: 'min_toggle',
hide_toggle: 'hide_toggle',
get_data_path: 'get_data_path',
show_dialog: 'show_dialog',
get_setting: 'get_setting',
get_playlist: 'get_playlist',
save_playlist: 'save_playlist',
get_data: 'get_data',
save_data: 'save_data',
get_hot_key: 'get_hot_key',
import_user_api: 'import_user_api',
remove_user_api: 'remove_user_api',
set_user_api: 'set_user_api',
get_user_api_list: 'get_user_api_list',
request_user_api: 'request_user_api',
request_user_api_cancel: 'request_user_api_cancel',
get_user_api_status: 'get_user_api_status',
user_api_status: 'user_api_status',
user_api_show_update_alert: 'user_api_show_update_alert',
user_api_set_allow_update_alert: 'user_api_set_allow_update_alert',
get_lyric: 'get_lyric',
save_lyric: 'save_lyric',
clear_lyric: 'clear_lyric',
get_lyric_raw: 'get_lyric_raw',
save_lyric_raw: 'save_lyric_raw',
clear_lyric_raw: 'clear_lyric_raw',
get_lyric_edited: 'get_lyric_edited',
save_lyric_edited: 'save_lyric_edited',
remove_lyric_edited: 'remove_lyric_edited',
get_music_url: 'get_music_url',
save_music_url: 'save_music_url',
clear_music_url: 'clear_music_url',
sync_enable: 'sync_enable',
sync_status: 'sync_status',
sync_get_status: 'sync_get_status',
sync_generate_code: 'sync_generate_code',
sync_action_list: 'sync_action_list',
sync_list: 'sync_list',
taskbar_set_thumbar_buttons: 'taskbar_set_thumbar_buttons',
taskbar_set_thumbnail_clip: 'taskbar_set_thumbnail_clip',
taskbar_on_thumbar_button_click: 'taskbar_on_thumbar_button_click',
},
winLyric: {
close: 'close',
set_lyric_info: 'set_lyric_info',
get_lyric_info: 'get_lyric_info',
set_lyric_config: 'set_lyric_config',
get_lyric_config: 'get_lyric_config',
set_win_bounds: 'set_win_bounds',
key_down: 'key_down',
},
hotKey: {
enable: 'enable',
status: 'status',
set_config: 'set_config',
},
}
for (const item of Object.keys(names)) {
let name = names[item]
for (const key of Object.keys(name)) {
name[key] = `${item}_${name[key]}`
}
}
exports.mainWindow = names.mainWindow
exports.winLyric = names.winLyric
exports.hotKey = names.hotKey

42
src/common/store.js Normal file
View File

@@ -0,0 +1,42 @@
const Store = require('electron-store')
const { dialog, app, shell } = require('electron')
const path = require('path')
const fs = require('fs')
const log = require('electron-log')
const stores = {}
/**
* 获取 Store 对象
* @param {*} name store 名
* @param {*} isIgnoredError 是否忽略错误
* @param {*} isShowErrorAlert 是否显示错误弹窗
* @returns Store
*/
module.exports = (name, isIgnoredError = true, isShowErrorAlert = true) => {
if (stores[name]) return stores[name]
let store
try {
store = stores[name] = new Store({ name, clearInvalidConfig: false })
} catch (error) {
log.error(error)
if (!isIgnoredError) throw error
const backPath = path.join(app.getPath('userData'), name + '.json.bak')
fs.copyFileSync(path.join(app.getPath('userData'), name + '.json'), backPath)
if (isShowErrorAlert) {
dialog.showMessageBoxSync({
type: 'error',
message: name + ' data load error',
detail: `We have helped you back up the old ${name} file to: ${backPath}\nYou can try to repair and restore it manually\n\nError detail: ${error.message}`,
})
shell.showItemInFolder(backPath)
}
store = new Store({ name, clearInvalidConfig: true })
}
return store
}

View File

@@ -1,8 +1,222 @@
const log = require('electron-log')
const { defaultSetting, overwriteSetting } = require('./defaultSetting')
// const apiSource = require('../renderer/utils/music/api-source-info')
const getStore = require('./store')
const defaultHotKey = require('./defaultHotKey')
exports.isLinux = process.platform == 'linux'
exports.isWin = process.platform == 'win32'
exports.isMac = process.platform == 'darwin'
/**
* 生成节流函数
* @param {*} fn
* @param {*} delay
*/
exports.throttle = (fn, delay = 100) => {
let timer = null
let _args = null
return function(...args) {
_args = args
if (timer) return
timer = setTimeout(() => {
timer = null
fn.apply(this, _args)
}, delay)
}
}
/**
* 生成防抖函数
* @param {*} fn
* @param {*} delay
*/
exports.debounce = (fn, delay = 100) => {
let timer = null
let _args = null
return function(...args) {
_args = args
if (timer) clearTimeout(timer)
timer = setTimeout(() => {
timer = null
fn.apply(this, _args)
}, delay)
}
}
exports.log = log
// https://stackoverflow.com/a/53387532
exports.compareVer = (currentVer, targetVer) => {
// treat non-numerical characters as lower version
// replacing them with a negative number based on charcode of each character
const fix = s => `.${s.toLowerCase().charCodeAt(0) - 2147483647}.`
currentVer = ('' + currentVer).replace(/[^0-9.]/g, fix).split('.')
targetVer = ('' + targetVer).replace(/[^0-9.]/g, fix).split('.')
let c = Math.max(currentVer.length, targetVer.length)
for (let i = 0; i < c; i++) {
// convert to integer the most efficient way
currentVer[i] = ~~currentVer[i]
targetVer[i] = ~~targetVer[i]
if (currentVer[i] > targetVer[i]) return 1
else if (currentVer[i] < targetVer[i]) return -1
}
return 0
}
exports.isObject = item => item && typeof item === 'object' && !Array.isArray(item)
/**
* 对象深度合并
* @param {} target 要合并源对象
* @param {} source 要合并目标对象
*/
exports.objectDeepMerge = (target, source, mergedObj) => {
if (!mergedObj) {
mergedObj = new Set()
mergedObj.add(target)
}
let base = {}
Object.keys(source).forEach(item => {
if (exports.isObject(source[item])) {
if (mergedObj.has(source[item])) return
if (!exports.isObject(target[item])) target[item] = {}
mergedObj.add(source[item])
exports.objectDeepMerge(target[item], source[item], mergedObj)
return
}
base[item] = source[item]
})
Object.assign(target, base)
}
exports.mergeSetting = (setting, version) => {
let defaultSettingCopy = JSON.parse(JSON.stringify(defaultSetting))
let overwriteSettingCopy = JSON.parse(JSON.stringify(overwriteSetting))
const defaultVersion = defaultSettingCopy.version
if (!version) {
if (setting) {
version = setting.version
delete setting.version
}
}
if (!setting) {
setting = defaultSettingCopy
} else if (exports.compareVer(version, defaultVersion) < 0) {
exports.objectDeepMerge(defaultSettingCopy, setting)
exports.objectDeepMerge(defaultSettingCopy, overwriteSettingCopy)
setting = defaultSettingCopy
}
// if (!apiSource.some(api => api.id === setting.apiSource && !api.disabled)) {
// let api = apiSource.find(api => !api.disabled)
// if (api) setting.apiSource = api.id
// }
return { setting, version: defaultVersion }
}
/**
* 初始化设置
* @param {*} setting
* @param {*} isShowErrorAlert
*/
exports.initSetting = isShowErrorAlert => {
const electronStore_list = getStore('playList', true, isShowErrorAlert)
const electronStore_config = getStore('config')
const electronStore_downloadList = getStore('downloadList')
let setting = electronStore_config.get('setting')
if (setting) {
let version = electronStore_config.get('version')
if (!version) { // 迁移配置
version = electronStore_config.get('setting.version')
electronStore_config.set('version', version)
electronStore_config.delete('setting.version')
const list = electronStore_config.get('list')
if (list) {
if (list.defaultList) electronStore_list.set('defaultList', list.defaultList)
if (list.loveList) electronStore_list.set('loveList', list.loveList)
electronStore_config.delete('list')
}
const downloadList = electronStore_config.get('download')
if (downloadList) {
if (downloadList.list) electronStore_downloadList.set('list', downloadList.list)
electronStore_config.delete('download')
}
}
// 迁移列表滚动位置设置 ~0.18.3
if (setting.list.scroll) {
let scroll = setting.list.scroll
electronStore_config.delete('setting.list.scroll')
electronStore_config.set('setting.list.isSaveScrollLocation', scroll.enable)
delete setting.list.scroll
}
}
// 从我的列表分离下载列表 v1.7.0 后
let downloadList = electronStore_list.get('downloadList')
if (downloadList) {
electronStore_downloadList.set('list', downloadList)
electronStore_list.delete('downloadList')
}
const { version: settingVersion, setting: newSetting } = exports.mergeSetting(setting, electronStore_config.get('version'))
// 修正拼写问题 v1.8.2 及以前
if (newSetting.player.isShowLyricTransition != null) {
newSetting.player.isShowLyricTranslation = newSetting.player.isShowLyricTransition
delete newSetting.player.isShowLyricTransition
}
// 迁移v1.19.0之前的主题设置
if (newSetting.themeId != null) {
newSetting.theme.id = newSetting.themeId
delete newSetting.themeId
}
// 重置 ^0.18.2 排行榜ID
if (!newSetting.leaderboard.tabId.includes('__')) newSetting.leaderboard.tabId = 'kw__16'
// newSetting.controlBtnPosition = 'right'
electronStore_config.set({ version: settingVersion, setting: newSetting })
return { version: settingVersion, setting: newSetting }
}
/**
* 初始化快捷键设置
*/
exports.initHotKey = () => {
const electronStore_hotKey = getStore('hotKey')
let localConfig = electronStore_hotKey.get('local')
if (!localConfig) {
localConfig = defaultHotKey.local
electronStore_hotKey.set('local', localConfig)
}
let globalConfig = electronStore_hotKey.get('global')
// 移除v1.0.1及之前设置的全局声音媒体快捷键接管
if (globalConfig && globalConfig.keys.VolumeUp) {
delete globalConfig.keys.VolumeUp
delete globalConfig.keys.VolumeDown
delete globalConfig.keys.VolumeMute
electronStore_hotKey.set('global', globalConfig)
}
if (!globalConfig) {
globalConfig = defaultHotKey.global
electronStore_hotKey.set('global', globalConfig)
}
return {
global: globalConfig,
local: localConfig,
}
}

View File

@@ -1,15 +0,0 @@
html(lang="cn")
head
meta(charset="UTF-8")
meta(name="viewport" content="width=device-width, initial-scale=1.0")
meta(http-equiv="X-UA-Compatible" content="ie=edge")
title 洛雪音乐助手
body
#root
//- if htmlWebpackPlugin.options.isProd
//- script.
//- window.__static = '!{require('path').join(htmlWebpackPlugin.options.__dirname, '/static').replace(/\\/g, '\\\\')}'
//- if !htmlWebpackPlugin.options.browser && htmlWebpackPlugin.options.isProd
script.
window.__static = require('path').join(__dirname, '/resources').replace(/\\/g, '\\\\')

39
src/lang/Readme.md Normal file
View File

@@ -0,0 +1,39 @@
新增语言时创建的语言文件夹需要与以下列表对应:
- `ar-sa` - Arabic Saudi Arabia
- `cs-cz` - Czech Czech Republic
- `da-dk` - Danish Denmark
- `de-de` - German Germany
- `el-gr` - Modern Greek Greece
- `en-au` - English Australia
- `en-gb` - English United Kingdom
- `en-ie` - English Ireland
- `en-us` - English United States
- `en-za` - English South Africa
- `es-es` - Spanish Spain
- `es-mx` - Spanish Mexico
- `fi-fi` - Finnish Finland
- `fr-ca` - French Canada
- `fr-fr` - French France
- `he-il` - Hebrew Israel
- `hi-in` - Hindi India
- `hu-hu` - Hungarian Hungary
- `id-id` - Indonesian Indonesia
- `it-it` - Italian Italy
- `ja-jp` - Japanese Japan
- `ko-kr` - Korean Republic of Korea
- `nl-be` - Dutch Belgium
- `nl-nl` - Dutch Netherlands
- `no-no` - Norwegian Norway
- `pl-pl` - Polish Poland
- `pt-br` - Portuguese Brazil
- `pt-pt` - Portuguese Portugal
- `ro-ro` - Romanian Romania
- `ru-ru` - Russian Russian Federation
- `sk-sk` - Slovak Slovakia
- `sv-se` - Swedish Sweden
- `th-th` - Thai Thailand
- `tr-tr` - Turkish Turkey
- `zh-cn` - Chinese China
- `zh-hk` - Chinese Hong Kong
- `zh-tw` - Chinese Taiwan

478
src/lang/en-us.json Normal file
View File

@@ -0,0 +1,478 @@
{
"action": "Manage",
"agree": "Accept",
"alert_button_text": "All right",
"audio_visualization": "Audio visualization (experimental)",
"back": "Back",
"cancel_button_text": "Cancel",
"close": "Close",
"comment__hot_load_error": "Hot comments failed to load, click to try to reload",
"comment__hot_loading": "Hot comments are loading",
"comment__hot_title": "Hot Comment",
"comment__new_load_error": "The latest comment failed to load, click to try to reload",
"comment__new_loading": "Latest comments are loading",
"comment__new_title": "Latest comment",
"comment__no_content": "No comments yet",
"comment__refresh": "Refresh comments",
"comment__show": "Song comments",
"comment__title": "{name} comment",
"confirm_button_text": "Yes",
"copy_tip": " (Click to copy)",
"date_format_hour": "{num} hours ago",
"date_format_minute": "{num} minutes ago",
"date_format_second": "{num} seconds ago",
"deep_link__handle_error_tip": "Call failed: {message}",
"default": "Default",
"default_list": "Recently Played",
"desktop_lyric__back": "Back",
"desktop_lyric__close": "Close",
"desktop_lyric__font_decrease": "Reduce font size (Right click to fine-tune)",
"desktop_lyric__font_increase": "Increase font size (Right click to fine-tune)",
"desktop_lyric__lock": "Lock Lyrics",
"desktop_lyric__lrc_active_zoom_off": "Unzoom the currently playing lyrics",
"desktop_lyric__lrc_active_zoom_on": "Zoom the currently playing lyrics",
"desktop_lyric__opactiy_decrease": "Increase Transparency (Right click to fine-tune)",
"desktop_lyric__opactiy_increase": "Decrease Transparency (Right click to fine-tune)",
"desktop_lyric__theme": "Theme Color",
"desktop_lyric__unlock": "Unlock Lyrics",
"desktop_lyric__win_top_off": "Cancel the top lyrics interface",
"desktop_lyric__win_top_on": "Top lyrics interface",
"download": "Downloads",
"download__all": "All Tasks",
"download__error": "Error",
"download__finished": "Download complete",
"download__high_quality": "High Quality",
"download__lossless": "Lossless",
"download__multiple_tip": "{len} song selected",
"download__multiple_tip2": "Select preferred download quality",
"download__normal": "Normal",
"download__not_available_tip": "The audio quality is not available",
"download__paused": "Paused",
"download__progress": "Progress",
"download__quality": "Quality",
"download__runing": "Downloading",
"download__status": "Status",
"export": "Export",
"fullscreen_exit": "Exit Full Screen",
"history_clear": "Clear History",
"history_remove": "Right click to remove this entry",
"history_search": "History Searches",
"import": "Import",
"leaderboard": "Charts",
"list__add_to": "Add to ...",
"list__collect": "Collect",
"list__copy_name": "Copy name",
"list__download": "Download",
"list__export_part_desc": "Choose where to save the list file",
"list__file": "Locate the file",
"list__import_part_button_cancel": "Don't",
"list__import_part_button_confirm": "Overwrite",
"list__import_part_confirm": "The imported list ({importName}) has the same ID as the local list ({localName}). Do you want to overwrite the local list?",
"list__import_part_desc": "Select List File",
"list__load_failed": "Ah, the loading failed 😭",
"list__loading": "List loading...⏳",
"list__move_to": "Move to ...",
"list__movedown": "Movedown",
"list__moveup": "Move up",
"list__new_list_btn": "New List",
"list__new_list_input": "New list...",
"list__pause": "Pause Task",
"list__play": "Play",
"list__play_later": "Play later",
"list__remove": "Remove",
"list__remove_tip": "Do you really want to remove {name}?",
"list__remove_tip_button": "Yes, that's right",
"list__rename": "Rename",
"list__search": "Search",
"list__sort": "Adjust position",
"list__source_detail": "Song Page",
"list__start": "Start Task",
"list__sync": "Update",
"list_add__btn_title": "Add the song(s) to {name}",
"list_add__multiple_btn_title": "Add these song(s) to {name}",
"list_add__multiple_title_add": "Add the selected {num} song(s) to ...",
"list_add__multiple_title_move": "Move the selected {num} song(s) to ...",
"list_add__title_first_add": "Add",
"list_add__title_first_move": "Move",
"list_add__title_last": "to...",
"list_import_tip__alldata": "Import failed, this is an all data backup file, you need to go here to import: \nSettings -> Backup and Restore -> All Data -> Import",
"list_import_tip__playlist": "Import failed, this is a list backup file, you need to go here to import: \nSettings -> Backup and Restore -> Import List",
"list_import_tip__playlist_part": "The import failed, this is a single-list file, you need to go here to import: \nMy List -> Right-click on any list name -> Select Import in the pop-up menu",
"list_import_tip__setting": "Import failed, this is a settings backup file, you need to go here to import: \nSettings -> Backup and Restore -> Partial Data -> Settings Import",
"list_import_tip__unknown": "Import failed, unknown file type, please try to upgrade to the latest version and try again",
"list_sort_modal_by_album": "Album name",
"list_sort_modal_by_down": "Descending",
"list_sort_modal_by_field": "Sort field",
"list_sort_modal_by_name": "Song name",
"list_sort_modal_by_singer": "Singer name",
"list_sort_modal_by_source": "Song source",
"list_sort_modal_by_time": "Duration",
"list_sort_modal_by_type": "Sort categories",
"list_sort_modal_by_up": "Ascending",
"list_sort_modal_tip_confirm": "Are you sure you want to do this?",
"list_update_modal__auto_update": "auto update",
"list_update_modal__tips": "💡 The list with \"Automatic Updates\" checked will be automatically updated each time the software is launched",
"list_update_modal__title": "List update management",
"list_update_modal__update": "Sync",
"lists__duplicate": "Duplicate song",
"lists__export": "Export",
"lists__export_part_desc": "Choose where to save the list file",
"lists__import": "Import",
"lists__import_part_button_cancel": "No",
"lists__import_part_button_confirm": "Overwrite",
"lists__import_part_confirm": "The imported list ({importName}) has the same ID as the local list ({localName}). Do you overwrite the local list?",
"lists__import_part_desc": "Select list file",
"lists__new_list_btn": "Create list",
"lists__new_list_input": "New list...",
"lists__remove": "Remove",
"lists__remove music_tip": "Do you really want to remove the selected {len} songs?",
"lists__remove_tip": "Do you really want to remove {name}?",
"lists__remove_tip_button": "Yes, that's right",
"lists__rename": "Rename",
"lists__sort_list": "Sort songs",
"lists__source_detail": "Playlist Page",
"lists__sync": "Update",
"lists__sync_confirm_tip": "This will replace the songs in {name} with the songs in the online list, are you sure you want to update?",
"load_list_file_error_detail": "We have helped you back up the old list file to {path}\nIt is stored in JSON format, you can try to repair and restore it manually\n\nError details: {detail}",
"load_list_file_error_title": "Error loading playlist data",
"loding_list": "Loading...",
"love_list": "Favorites",
"lyric__load_error": "Failed to get lyrics",
"lyric__select": "Lyric text selection",
"lyric_menu__align": "Lyric Alignment",
"lyric_menu__align_center": "Centered",
"lyric_menu__align_left": "Left",
"lyric_menu__lrc_size": "Font size [{size}]",
"lyric_menu__offset": "Offset [ {offset}ms ]",
"lyric_menu__offset_add_10": "10ms faster",
"lyric_menu__offset_add_100": "100ms faster",
"lyric_menu__offset_dec_10": "10ms slow down (right click slows down 5ms)",
"lyric_menu__offset_dec_100": "slow down by 100ms",
"lyric_menu__offset_reset": "Reset",
"lyric_menu__size_add": "Increase font size (right click to fine-tune)",
"lyric_menu__size_dec": "Decrease font (right click to fine tune)",
"lyric_menu__size_reset": "Reset",
"min": "Minimize",
"music_album": "Album",
"music_duplicate": "Duplicate song",
"music_name": "Name",
"music_singer": "Artist",
"music_sort__btn_cancel": "Cancel",
"music_sort__btn_confirm": "Confirm",
"music_sort__input_tip": "Please input which position you want to adjust to",
"music_sort__title": "Adjust the position of {name} to:",
"music_sort__title_multiple": "Adjust the position of the selected {num} songs to:",
"music_time": "Length",
"my_list": "Your Library",
"no_item": "Nothing's here...",
"not_agree": "Not accept",
"ok": "OK",
"pagination__next": "Next page",
"pagination__page": "Page {num}",
"pagination__prev": "Previous page",
"play_timeout": "Timed pause",
"play_timeout_close": "Close",
"play_timeout_confirm": "Confirm",
"play_timeout_end": "Wait for the song to finish before pausing",
"play_timeout_stop": "Cancel timer",
"play_timeout_tip": "Pause after {time}",
"play_timeout_unit": "minute",
"play_timeout_update": "Update timing",
"player__add_music_to": "Add the current song to...",
"player__buffering": "Buffering...",
"player__desktop_lyric_lock": "Right click to lock lyrics",
"player__desktop_lyric_off": "Close Desktop Lyrics",
"player__desktop_lyric_on": "Open Desktop Lyrics",
"player__desktop_lyric_unlock": "Right click to unlock lyrics",
"player__end": "Stopped",
"player__error": "Error loading music. Switch to next song after 5 seconds",
"player__geting_url": "Getting music link...",
"player__hide_detail_tip": "Hide detail page (Right-click in the view to quickly hide the details page)",
"player__loading": "Music loading...",
"player__music_album": "Album: ",
"player__music_name": "Name: ",
"player__music_singer": "Artist: ",
"player__next": "Next",
"player__pause": "Pause",
"player__pic_tip": "Play details page (right-click to locate the currently playing song in \"My List\")",
"player__play": "Play",
"player__play_toggle_mode_list": "Play in order",
"player__play_toggle_mode_list_loop": "List Loop",
"player__play_toggle_mode_off": "Disable",
"player__play_toggle_mode_random": "List Random",
"player__play_toggle_mode_single_loop": "Single Loop",
"player__playing": "Now playing...",
"player__prev": "Prev",
"player__refresh_url": "Music URL expired, refreshing...",
"player__stop": "Paused",
"player__volume": "Volume: ",
"search": "Search",
"search__hot_search": "Top Searches",
"search__welcome": "Search what I want to 😉",
"setting": "Settings",
"setting__about": "About lx-music-desktop",
"setting__backup": "Backup and restore",
"setting__backup_all": "All data (list data and setting data)",
"setting__backup_all_export": "Export",
"setting__backup_all_export_desc": "Select the backup to...",
"setting__backup_all_import": "Import",
"setting__backup_all_import_desc": "Select a backup file",
"setting__backup_other": "Other backup formats (recovery of such backup files is not currently supported)",
"setting__backup_other_export_dir": "Choose where to save the file",
"setting__backup_other_export_list_csv": "Export list in CSV format",
"setting__backup_other_export_list_text": "Export list in TXT format",
"setting__backup_other_export_list_text_confirm": "Do you want to merge all the lists into one file?",
"setting__backup_part": "Partial data (list data includes audition list, favorite list, user-defined list, setting data does not include shortcut key settings)",
"setting__backup_part_export_list": "Export lists",
"setting__backup_part_export_list_desc": "Save the list to...",
"setting__backup_part_export_setting": "Export settings",
"setting__backup_part_export_setting_desc": "Save the list to...",
"setting__backup_part_import_list": "Import lists",
"setting__backup_part_import_list_desc": "Select a list backup",
"setting__backup_part_import_setting": "Import settings",
"setting__backup_part_import_setting_desc": "Select the Settings file",
"setting__basic": "General",
"setting__basic_animation": "Random pop-up animation",
"setting__basic_control_btn_position": "Control Button Position",
"setting__basic_control_btn_position_left": "Left",
"setting__basic_control_btn_position_right": "Right",
"setting__basic_font": "Font",
"setting__basic_lang": "Language",
"setting__basic_lang_title": "The language displayed in the software",
"setting__basic_show_animation": "Show switching animation",
"setting__basic_source": "Music source",
"setting__basic_source_status_failed": "Initialization failed",
"setting__basic_source_status_initing": "Initializing",
"setting__basic_source_status_success": "Initialization successful",
"setting__basic_source_temp": "Temporary API (some features not available; workaround if Test API unavailable)",
"setting__basic_source_test": "Test API (Available for most software features)",
"setting__basic_source_title": "Choose a music source",
"setting__basic_source_user_api_btn": "Custom Source Management",
"setting__basic_sourcename": "Source name",
"setting__basic_sourcename_alias": "Aliases",
"setting__basic_sourcename_real": "Original",
"setting__basic_sourcename_title": "Select the name of music source",
"setting__basic_start_in_fullscreen": "Start in fullscreen mode",
"setting__basic_theme": "Theme",
"setting__basic_theme_auto_tip": "This is a dynamic theme, you can preset a light theme and a dark theme, and then it will automatically switch to the corresponding theme you preset according to the system's light and dark theme colors.\nNote: Right-click this theme item to open the light and dark theme setting window.",
"setting__basic_to_tray": "Do not exit the software when closing the software and minimize it to the system tray",
"setting__basic_window_size": "Window size",
"setting__basic_window_size_big": "Large",
"setting__basic_window_size_huge": "Huge",
"setting__basic_window_size_larger": "Larger",
"setting__basic_window_size_medium": "Medium",
"setting__basic_window_size_oversized": "Oversized",
"setting__basic_window_size_small": "Small",
"setting__basic_window_size_smaller": "Smaller",
"setting__basic_window_size_title": "Set the window size",
"setting__click_copy": "Click to copy",
"setting__click_open": "Click to open",
"setting__desktop_lyric": "Desktop Lyric Settings",
"setting__desktop_lyric_always_on_top": "Make the lyrics always above other windows",
"setting__desktop_lyric_always_on_top_loop": "Automatically refresh the top of the lyrics (try to enable this setting when the lyrics are still blocked by some programs)",
"setting__desktop_lyric_delay_scroll": "Delayed lyrics scroll",
"setting__desktop_lyric_enable": "Display lyrics",
"setting__desktop_lyric_font": "Lyric font",
"setting__desktop_lyric_font_default": "Default",
"setting__desktop_lyric_hover_hide": "Reduce the transparency of lyrics when the mouse moves into the lyrics area (this feature has platform compatibility issues)",
"setting__desktop_lyric_lock": "Lock lyrics",
"setting__desktop_lyric_lock_screen": "It is not allowed to drag the lyrics window out of the main screen",
"setting__download": "Download",
"setting__download_data_embed": "Whether to embed the following content in the audio file",
"setting__download_embed_lyric": "Embedding lyric",
"setting__download_embed_pic": "Embedding cover",
"setting__download_enable": "Whether to enable download function",
"setting__download_lyric": "Lyrics download",
"setting__download_lyric_format": "Downloaded lyrics file encoding format",
"setting__download_lyric_format_gbk": "GBK (Try to select this format when Chinese garbled characters appear on some devices)",
"setting__download_lyric_format_utf8": "UTF-8",
"setting__download_lyric_title": "Select whether to download the lyrics file",
"setting__download_name": "Music file naming",
"setting__download_name1": "Title - Artist",
"setting__download_name2": "Artist - Title",
"setting__download_name3": "Title only",
"setting__download_name_title": "Select the music naming method for downloading",
"setting__download_path": "Download path",
"setting__download_path_change_btn": "Change",
"setting__download_path_label": "Current: ",
"setting__download_path_open_label": "Click to open this path",
"setting__download_path_title": "Define the path to downloading",
"setting__download_select_save_path": "Select the save path",
"setting__download_use_other_source": "Auto source download",
"setting__download_use_other_source_tip": "When the song cannot be downloaded from the original source, try to switch to another source to download. Note: This function does not 100% guarantee that the version of the song after changing the source is consistent with the original version",
"setting__hot_key": "Shortcut Key Settings",
"setting__hot_key_common_focus_search_input": "Focus Search Box",
"setting__hot_key_common_min": "Minimize the program",
"setting__hot_key_common_toggle_close": "Quit Program",
"setting__hot_key_common_toggle_hide": "Show/Hide Program",
"setting__hot_key_common_toggle_min": "Minimize/Restore Program",
"setting__hot_key_desktop_lyric_toggle_always_top": "Top Desktop Lyrics Switch",
"setting__hot_key_desktop_lyric_toggle_lock": "Desktop Lyric Lock Switch",
"setting__hot_key_desktop_lyric_toggle_visible": "Turn on/off desktop lyrics",
"setting__hot_key_global_title": "Global Shortcut Key",
"setting__hot_key_local_title": "Shortcut Keys in Software",
"setting__hot_key_player_next": "Next Song",
"setting__hot_key_player_prev": "Previous Song",
"setting__hot_key_player_toggle_play": "Play/Pause Control",
"setting__hot_key_player_volume_down": "Reduce Volume",
"setting__hot_key_player_volume_mute": "Mute Switch",
"setting__hot_key_player_volume_up": "Increase Volume",
"setting__hot_key_tip_input": "Please enter a new key",
"setting__hot_key_unset_input": "Not Set",
"setting__is_enable": "Enabled",
"setting__is_show": "Showed",
"setting__list": "List",
"setting__list_add_music_location_type": "Position when adding a song to the list",
"setting__list_add_music_location_type_bottom": "Bottom",
"setting__list_add_music_location_type_top": "Top",
"setting__list_click_action": "Automatically switch to the current list when double-clicking a song in the list (only valid for playlists and rankings)",
"setting__list_scroll": "Remember the position of the scroll bar of the playlist (only valid for my music classification)",
"setting__list_source": "Show song source (only valid for my music category)",
"setting__network": "Network",
"setting__network_proxy_host": "Host",
"setting__network_proxy_password": "Password",
"setting__network_proxy_port": "Port",
"setting__network_proxy_title": "HTTP Proxy (False setting would block Internet connections)",
"setting__network_proxy_username": "Username",
"setting__odc": "Auto clear",
"setting__odc_clear_search_input": "Clear the search box when you are not searching",
"setting__odc_clear_search_list": "Clear the search list when you are not searching",
"setting__other": "Extras",
"setting__other_play_list_cache": "List cache management",
"setting__other_play_list_cache_clear_btn": "Clear list cache information",
"setting__other_play_list_cache_tip": "The cached song links and playback sources in my list need to be re-acquired when playing or downloading songs after cleaning. Do not clean up if there are no issues related to song playback",
"setting__other_play_list_cache_tip_confirm": "In my list, the cached song links and play alternative sources need to be re-obtained when playing and downloading songs after cleaning. Do not clean up if there are no issues related to song playback. Are you sure to clean up?",
"setting__other_resource_cache": "Resource cache management",
"setting__other_resource_cache_clear_btn": "Clear resource cache",
"setting__other_resource_cache_confirm": "I want to clear",
"setting__other_resource_cache_label": "The software has used cache size: ",
"setting__other_resource_cache_tip": "Picture, audio, and other caches. After cleaning, resources such as pictures will need to be downloaded again. It is not recommended to clean up. The software will dynamically manage the cache size according to the disk space.",
"setting__other_resource_cache_tip_confirm": "Involving the cache of pictures, audios, etc., the pictures and other resources will need to be downloaded again after cleaning. It is not recommended to clean up. The software will dynamically manage the cache size according to the disk space. Do you still need to clean up?",
"setting__other_tray_theme": "Tray Icon Style",
"setting__other_tray_theme_black": "Black Color",
"setting__other_tray_theme_native": "White",
"setting__other_tray_theme_origin": "Primary Color",
"setting__play": "Play",
"setting__play_auto_skip_on_error": "Automatically switch songs on playback error",
"setting__play_detail": "Play details page settings",
"setting__play_detail_align": "Lyric Alignment",
"setting__play_detail_align_center": "Centered",
"setting__play_detail_align_left": "Left",
"setting__play_detail_align_right": "Right",
"setting__play_detail_font_size": "Lyrics font size (you can use the keyboard + - adjust the font size on the playback details page)",
"setting__play_detail_font_size_current": "Current font size: {size}",
"setting__play_detail_font_size_reset": "Reset",
"setting__play_detail_font_zoom": "Zoom the currently playing lyrics",
"setting__play_detail_lyric_progress": "Allows to adjust playback progress by lyrics",
"setting__play_lyric_lxlrc": "Play with karaoke-style lyrics (if available)",
"setting__play_lyric_roma": "Show lyrics roman",
"setting__play_lyric_s2t": "Convert the playing and downloading lyrics to Traditional Chinese",
"setting__play_lyric_transition": "Show lyrics translation",
"setting__play_mediaDevice": "Audio output",
"setting__play_mediaDevice_remove_stop_play": "Pause the song when the current sound output device is changed",
"setting__play_mediaDevice_title": "Select a media device for audio output",
"setting__play_media_device_error_tip": "This function conflicts with the audio visualization function. You have enabled audio visualization when you started the software this time. This setting is temporarily unavailable. Please restart the software and then modify this setting.",
"setting__play_media_device_tip": "This feature conflicts with Audio Visualization, both cannot be enabled at the same time, would you like to turn Audio Visualization off and apply the selected audio output settings?",
"setting__play_quality": "Priority playback of 320K quality songs (if available)",
"setting__play_save_play_time": "Remember playback progress",
"setting__play_task_bar": "Show playing progress on the taskbar",
"setting__play_timeout": "Timed pause",
"setting__player_audio_visualization_tip": "The custom audio output device will conflict with the audio visualization function. After the audio visualization is enabled, the audio output device will be reset to the default output device. At present, this problem cannot be solved. Do you still want to enable it?",
"setting__search": "Search",
"setting__search_focus_search_box": "Automatically focus the search box on startup",
"setting__search_history": "Search history",
"setting__search_hot": "Top Searches",
"setting__sync": "Data synchronization",
"setting__sync_address": "Synchronization service address: {address}",
"setting__sync_auth_code": "Connection code: {code}",
"setting__sync_device": "Connected devices: {devices}",
"setting__sync_enable": "Enable the synchronization function (because the data is transmitted in clear text, please use it under a trusted network)",
"setting__sync_port": "Sync port settings",
"setting__sync_port_tip": "Please enter the synchronization service port number",
"setting__sync_refresh_code": "Refresh the connection code",
"setting__sync_tip": "For how to use it, please see the \"Sync function\" section of the FAQ",
"setting__update": "Update",
"setting__update_checking": "Checking for updates...",
"setting__update_current_label": "Current version: ",
"setting__update_downloading": "Update is found and being downloaded...⏳",
"setting__update_init": "Processing update...",
"setting__update_latest": "The software is up-to-date, enjoy yourself!🥂",
"setting__update_latest_label": "Latest version: ",
"setting__update_open_version_modal_btn": "Open the update window🚀",
"setting__update_progress": "Download progress: ",
"setting__update_unknown": "Unknown",
"song_list": "Playlists",
"songlist__import_input_tip": "Enter songlist link or songlist ID",
"songlist__import_input_tip_1": "Cross-source playlists are not supported, please confirm whether the playlist to be opened corresponds to the current playlist source",
"songlist__import_input_tip_2": "If you encounter a link to a playlist that cannot be opened, welcome feedback",
"songlist__import_input_tip_3": "Kugou source does not support opening with playlist ID, but supports Kugou code opening",
"songlist__open_list": "open {name} playlist",
"source_alias_all": "Aggregated",
"source_alias_bd": "BD Music",
"source_alias_kg": "KG Music",
"source_alias_kw": "KW Music",
"source_alias_mg": "MG Music",
"source_alias_tx": "TX Music",
"source_alias_wy": "WY Music",
"source_alias_xm": "XM Music",
"source_all": "Aggregated",
"source_bd": "Baidu",
"source_kg": "Kugou",
"source_kw": "Kuwo",
"source_mg": "Migu",
"source_tx": "Tencent",
"source_wy": "Netease",
"source_xm": "Xiami",
"sync__merge_btn_local_remote": "Local list merge remote list",
"sync__merge_btn_remote_local": "Remote list merge local list",
"sync__merge_label": "Merge",
"sync__merge_tip": "Merge:",
"sync__merge_tip_desc": "Merge the two lists together, the same song will be removed (the song of the merged person is removed), and different songs will be added.",
"sync__other_label": "Other",
"sync__other_tip": "Other: ",
"sync__other_tip_desc": "\"Only use real-time synchronization function\" will not modify the lists of both parties, only real-time synchronization operations; \"Cancel synchronization\" will directly disconnect the two parties.",
"sync__overwrite": "Full coverage",
"sync__overwrite_btn_cancel": "Cancel sync",
"sync__overwrite_btn_local_remote": "Local list Overwrite remote list",
"sync__overwrite_btn_none": "Only use real-time synchronization",
"sync__overwrite_btn_remote_local": "Remote list Overwrite local list",
"sync__overwrite_label": "Cover",
"sync__overwrite_tip": "Cover: ",
"sync__overwrite_tip_desc": "The list with the same ID of the covered person and the covered list will be deleted and replaced with the list of the covered person (lists with different list IDs will be merged together). If you check Complete coverage, all lists of the covered person will be moved. \nDivide, and then replace with a list of overriders.",
"sync__title": "Choose how to synchronize the list with {name}",
"tag__high_quality": "HQ",
"tag__lossless": "SQ",
"tag__lossless_24bit": "24bit",
"theme_auto": "Auto",
"theme_auto_tip": "Right-click to open the light and dark theme settings window",
"theme_black": "Black",
"theme_blue": "Blue",
"theme_blue2": "Purple Blue",
"theme_green": "Green",
"theme_grey": "Grey",
"theme_happy_new_year": "New Year",
"theme_mid_autumn": "Mid-Autumn",
"theme_ming": "Ming",
"theme_naruto": "Naruto",
"theme_orange": "Orange",
"theme_pink": "Pink",
"theme_purple": "Purple",
"theme_red": "Red",
"theme_selector_modal__dark_title": "dark theme",
"theme_selector_modal__light_title": "Bright theme",
"theme_selector_modal__title": "Follow system theme settings",
"theme_selector_modal__title_tip": "Note: You can set a light theme and a dark theme in advance, and then it will automatically switch to the corresponding theme you set in advance according to the light and dark theme colors of the system.",
"theme_yellow": "Yellow",
"user_api__allow_show_update_alert": "Allow update popup to show",
"user_api__btn_export": "Export",
"user_api__btn_import": "Import",
"user_api__btn_remove": "Remove",
"user_api__import_file": "Select music API script file",
"user_api__max_tip": "There can only be a maximum of 20 sources at the same time🤪\nIf you want to continue importing, please remove some old sources to make room",
"user_api__noitem": "There is nothing here...😲",
"user_api__note": "Tip: Although we have isolated the script's running environment as much as possible, importing scripts containing malicious behaviors may still affect your system. Please import them carefully.",
"user_api__readme": "Source writing instructions: ",
"user_api__title": "Custom Source Management",
"user_api__update_alert": "Custom source [{name}] found new version:",
"user_api__update_alert_open_url": "Open update address"
}

43
src/lang/index.js Normal file
View File

@@ -0,0 +1,43 @@
import zh_cn from './zh-cn.json'
import zh_tw from './zh-tw.json'
import en_us from './en-us.json'
const langs = [
{
name: '简体中文',
locale: 'zh-cn',
alternate: 'zh-hans',
country: 'cn',
fallback: true,
message: zh_cn,
},
{
name: '繁体中文',
locale: 'zh-tw',
alternate: 'zh-hk',
country: 'cn',
message: zh_tw,
},
{
name: 'English',
locale: 'en-us',
country: 'us',
message: en_us,
},
]
const langList = []
const messages = {}
langs.forEach(item => {
langList.push({
name: item.name,
locale: item.locale,
alternate: item.alternate,
})
messages[item.locale] = item.message
})
export {
langList,
messages,
}

20
src/lang/languages.json Normal file
View File

@@ -0,0 +1,20 @@
[
{
"name": "简体中文",
"locale": "zh-cn",
"alternate": "zh-hans",
"country": "cn",
"fallback": true
},
{
"name": "繁体中文",
"locale": "zh-tw",
"alternate": "zh-hk",
"country": "cn"
},
{
"name": "English",
"locale": "en-us",
"country": "us"
}
]

478
src/lang/zh-cn.json Normal file
View File

@@ -0,0 +1,478 @@
{
"action": "操作",
"agree": "接受",
"alert_button_text": "好吧",
"audio_visualization": "音频可视化(实验性)",
"back": "返回",
"cancel_button_text": "我不",
"close": "关闭",
"comment__hot_load_error": "热门评论加载失败,点击尝试重新加载",
"comment__hot_loading": "热门评论加载中",
"comment__hot_title": "热门评论",
"comment__new_load_error": "最新评论加载失败,点击尝试重新加载",
"comment__new_loading": "最新评论加载中",
"comment__new_title": "最新评论",
"comment__no_content": "暂无评论",
"comment__refresh": "刷新评论",
"comment__show": "歌曲评论",
"comment__title": "{name} 的评论",
"confirm_button_text": "是的",
"copy_tip": "(点击复制)",
"date_format_hour": "{num}小时前",
"date_format_minute": "{num}分钟前",
"date_format_second": "{num}秒前",
"deep_link__handle_error_tip": "调用失败:{message}",
"default": "默认",
"default_list": "试听列表",
"desktop_lyric__back": "返回",
"desktop_lyric__close": "关闭",
"desktop_lyric__font_decrease": "减小字体大小(右击可微调)",
"desktop_lyric__font_increase": "增加字体大小(右击可微调)",
"desktop_lyric__lock": "锁定歌词",
"desktop_lyric__lrc_active_zoom_off": "取消缩放当前播放的歌词",
"desktop_lyric__lrc_active_zoom_on": "缩放当前播放的歌词",
"desktop_lyric__opactiy_decrease": "增加透明度(右击可微调)",
"desktop_lyric__opactiy_increase": "减小透明度(右击可微调)",
"desktop_lyric__theme": "主题配色",
"desktop_lyric__unlock": "解锁歌词",
"desktop_lyric__win_top_off": "取消置顶歌词界面",
"desktop_lyric__win_top_on": "置顶歌词界面",
"download": "下载",
"download__all": "全部任务",
"download__error": "出错",
"download__finished": "下载完成",
"download__high_quality": "高品音质",
"download__lossless": "无损音质",
"download__multiple_tip": "已选择 {len} 首歌曲",
"download__multiple_tip2": "请选择要优先下载的音质",
"download__normal": "普通音质",
"download__not_available_tip": "该音质不可用",
"download__paused": "已暂停",
"download__progress": "进度",
"download__quality": "品质",
"download__runing": "正在下载",
"download__status": "状态",
"export": "导出",
"fullscreen_exit": "退出全屏",
"history_clear": "清空搜索历史",
"history_remove": "右击移除该历史",
"history_search": "历史搜索",
"import": "导入",
"leaderboard": "排行榜",
"list__add_to": "添加到...",
"list__collect": "收藏",
"list__copy_name": "复制歌曲名",
"list__download": "下载",
"list__export_part_desc": "选择列表文件保存位置",
"list__file": "定位文件",
"list__import_part_button_cancel": "不要啊",
"list__import_part_button_confirm": "覆盖掉",
"list__import_part_confirm": "导入的列表({importName})与本地列表({localName}的ID相同是否覆盖本地列表",
"list__import_part_desc": "选择列表文件",
"list__load_failed": "啊,加载失败了😭",
"list__loading": "列表加载中...⏳",
"list__move_to": "移动到...",
"list__movedown": "下移",
"list__moveup": "上移",
"list__new_list_btn": "新建列表",
"list__new_list_input": "新列表...",
"list__pause": "暂停任务",
"list__play": "播放",
"list__play_later": "稍后播放",
"list__remove": "删除",
"list__remove_tip": "你真的想要移除 {name} 吗?",
"list__remove_tip_button": "是的 没错",
"list__rename": "重命名",
"list__search": "搜索",
"list__sort": "调整位置",
"list__source_detail": "歌曲详情页",
"list__start": "开始任务",
"list__sync": "更新",
"list_add__btn_title": "把该歌曲添加到 {name}",
"list_add__multiple_btn_title": "把这些歌曲添加到 {name}",
"list_add__multiple_title_add": "添加已选的 {num} 首歌曲到...",
"list_add__multiple_title_move": "移动已选的 {num} 首歌曲到...",
"list_add__title_first_add": "添加",
"list_add__title_first_move": "移动",
"list_add__title_last": "到...",
"list_import_tip__alldata": "导入失败,这是一个所有数据备份文件,你需要去这里导入:\n设置 -> 备份与恢复 -> 所有数据 -> 导入",
"list_import_tip__playlist": "导入失败,这是一个列表备份文件,你需要去这里导入:\n设置 -> 备份与恢复 -> 部分数据 -> 导入列表",
"list_import_tip__playlist_part": "导入失败,这是一个单列表文件,你需要去这里导入:\n我的列表 -> 右击任意一个列表名 -> 在弹出的菜单中选择导入",
"list_import_tip__setting": "导入失败,这是一个设置备份文件,你需要去这里导入:\n设置 -> 备份与恢复 -> 部分数据 -> 设置导入",
"list_import_tip__unknown": "导入失败,未知的文件类型,请尝试升级到最新版本后再试",
"list_sort_modal_by_album": "专辑名",
"list_sort_modal_by_down": "降序",
"list_sort_modal_by_field": "排序字段",
"list_sort_modal_by_name": "歌曲名",
"list_sort_modal_by_singer": "歌手名",
"list_sort_modal_by_source": "歌曲源",
"list_sort_modal_by_time": "时长",
"list_sort_modal_by_type": "排序类别",
"list_sort_modal_by_up": "升序",
"list_sort_modal_tip_confirm": "你确定要这么做吗?",
"list_update_modal__auto_update": "自动更新",
"list_update_modal__tips": "💡 每次启动软件时将会自动更新已勾选“自动更新”的列表",
"list_update_modal__title": "列表更新管理",
"list_update_modal__update": "立即更新",
"lists__duplicate": "重复歌曲",
"lists__export": "导出",
"lists__export_part_desc": "选择列表文件保存位置",
"lists__import": "导入",
"lists__import_part_button_cancel": "不要啊",
"lists__import_part_button_confirm": "覆盖掉",
"lists__import_part_confirm": "导入的列表({importName})与本地列表({localName}的ID相同是否覆盖本地列表",
"lists__import_part_desc": "选择列表文件",
"lists__new_list_btn": "新建列表",
"lists__new_list_input": "新列表...",
"lists__remove": "删除",
"lists__remove music_tip": "你真的要移除所选的 {len} 首歌曲吗?",
"lists__remove_tip": "你真的想要移除 {name} 吗?",
"lists__remove_tip_button": "是的 没错",
"lists__rename": "重命名",
"lists__sort_list": "排序歌曲",
"lists__source_detail": "歌单详情页",
"lists__sync": "更新",
"lists__sync_confirm_tip": "这将会把 {name} 内的歌曲替换成在线列表的歌曲,你确认要更新吗?",
"load_list_file_error_detail": "我们已经帮你把旧的列表文件备份到{path}\n它以 JSON 格式存储,你可以尝试手动修复并恢复它\n\n错误详情{detail}",
"load_list_file_error_title": "播放列表数据加载错误建议到GitHub或加群反馈",
"loding": "加载中...",
"love_list": "收藏",
"lyric__load_error": "歌词获取失败",
"lyric__select": "歌词文本选择",
"lyric_menu__align": "歌词对齐方式",
"lyric_menu__align_center": "居中",
"lyric_menu__align_left": "居左",
"lyric_menu__lrc_size": "字体大小 [ {size} ]",
"lyric_menu__offset": "歌词偏移 [ {offset}ms ]",
"lyric_menu__offset_add_10": "加快10毫秒",
"lyric_menu__offset_add_100": "加快100毫秒",
"lyric_menu__offset_dec_10": "减慢10毫秒",
"lyric_menu__offset_dec_100": "减慢100毫秒",
"lyric_menu__offset_reset": "重置",
"lyric_menu__size_add": "加大字体(右击可微调)",
"lyric_menu__size_dec": "减小字体(右击可微调)",
"lyric_menu__size_reset": "重置",
"min": "最小化",
"music_album": "专辑名",
"music_duplicate": "重复歌曲",
"music_name": "歌曲名",
"music_singer": "艺术家",
"music_sort__btn_cancel": "取消",
"music_sort__btn_confirm": "确定",
"music_sort__input_tip": "请输入要调整到第几个位置",
"music_sort__title": "将 {name} 的位置调整到:",
"music_sort__title_multiple": "将已选的 {num} 首歌曲的位置调整到:",
"music_time": "时长",
"my_list": "我的列表",
"no_item": "列表竟然是空的...",
"not_agree": "不接受",
"ok": "我知道了",
"pagination__next": "下一页",
"pagination__page": "第 {num} 页",
"pagination__prev": "上一页",
"play_timeout": "定时暂停",
"play_timeout_close": "关闭",
"play_timeout_confirm": "确认",
"play_timeout_end": "等待歌曲播放完毕再暂停",
"play_timeout_stop": "取消定时",
"play_timeout_tip": "{time} 后暂停播放",
"play_timeout_unit": "分钟",
"play_timeout_update": "更新定时",
"player__add_music_to": "添加当前歌曲到...",
"player__buffering": "缓冲中...",
"player__desktop_lyric_lock": "右击锁定歌词",
"player__desktop_lyric_off": "关闭桌面歌词",
"player__desktop_lyric_on": "开启桌面歌词",
"player__desktop_lyric_unlock": "右击解锁歌词",
"player__end": "播放完毕",
"player__error": "音频加载出错5 秒后切换下一首",
"player__geting_url": "歌曲链接获取中...",
"player__hide_detail_tip": "隐藏详情页(界面内右键双击可快速隐藏详情页)",
"player__loading": "音乐加载中...",
"player__music_album": "专辑名:",
"player__music_name": "歌曲名:",
"player__music_singer": "艺术家:",
"player__next": "下一首",
"player__pause": "暂停",
"player__pic_tip": "播放详情页(右击在“我的列表”定位当前播放的歌曲)",
"player__play": "播放",
"player__play_toggle_mode_list": "顺序播放",
"player__play_toggle_mode_list_loop": "列表循环",
"player__play_toggle_mode_off": "禁用",
"player__play_toggle_mode_random": "列表随机",
"player__play_toggle_mode_single_loop": "单曲循环",
"player__playing": "播放中...",
"player__prev": "上一首",
"player__refresh_url": "URL过期正在刷新URL...",
"player__stop": "暂停播放",
"player__volume": "当前音量:",
"search": "搜索",
"search__hot_search": "热门搜索",
"search__welcome": "搜我所想~~😉",
"setting": "设置",
"setting__about": "关于洛雪音乐",
"setting__backup": "备份与恢复",
"setting__backup_all": "所有数据(列表数据与设置数据)",
"setting__backup_all_export": "导出",
"setting__backup_all_export_desc": "选择备份保存位置",
"setting__backup_all_import": "导入",
"setting__backup_all_import_desc": "选择备份文件",
"setting__backup_other": "其他备份格式(目前不支持恢复此类备份文件)",
"setting__backup_other_export_dir": "选择文件保存位置",
"setting__backup_other_export_list_csv": "导出 CSV 格式的列表",
"setting__backup_other_export_list_text": "导出 TXT 格式的列表",
"setting__backup_other_export_list_text_confirm": "是否将所有列表合并为一个文件?",
"setting__backup_part": "部分数据(列表数据包括试听列表、收藏列表、用户自定义列表,设置数据不包括快捷键设置)",
"setting__backup_part_export_list": "导出列表",
"setting__backup_part_export_list_desc": "选择歌单保存位置",
"setting__backup_part_export_setting": "导出设置",
"setting__backup_part_export_setting_desc": "选择设置保存位置",
"setting__backup_part_import_list": "导入列表",
"setting__backup_part_import_list_desc": "选择列表文件",
"setting__backup_part_import_setting": "导入设置",
"setting__backup_part_import_setting_desc": "选择配置文件",
"setting__basic": "基本设置",
"setting__basic_animation": "弹出层随机动画",
"setting__basic_control_btn_position": "控制按钮位置",
"setting__basic_control_btn_position_left": "左边",
"setting__basic_control_btn_position_right": "右边",
"setting__basic_font": "字体",
"setting__basic_lang": "语言",
"setting__basic_lang_title": "软件显示的语言",
"setting__basic_show_animation": "显示切换动画",
"setting__basic_source": "音乐来源",
"setting__basic_source_status_failed": "初始化失败",
"setting__basic_source_status_initing": "初始化中",
"setting__basic_source_status_success": "初始化成功",
"setting__basic_source_temp": "临时接口(软件的某些功能不可用,建议测试接口不可用再使用本接口)",
"setting__basic_source_test": "测试接口(几乎软件的所有功能都可用)",
"setting__basic_source_title": "选择音乐来源",
"setting__basic_source_user_api_btn": "自定义源管理",
"setting__basic_sourcename": "音源名字",
"setting__basic_sourcename_alias": "别名",
"setting__basic_sourcename_real": "原名",
"setting__basic_sourcename_title": "选择音源名字类型",
"setting__basic_start_in_fullscreen": "以全屏模式启动",
"setting__basic_theme": "主题颜色",
"setting__basic_theme_auto_tip": "此乃动态主题,你可以预先设置一个亮色主题及暗色主题,此后将根据系统的亮、暗主题色自动切换为你预先设置的相应主题。\n注鼠标 右击 此主题项即可打开亮、暗色主题设置窗口。",
"setting__basic_to_tray": "关闭软件时不退出软件将其最小化到系统托盘",
"setting__basic_window_size": "窗口尺寸",
"setting__basic_window_size_big": "大",
"setting__basic_window_size_huge": "巨大",
"setting__basic_window_size_larger": "较大",
"setting__basic_window_size_medium": "中",
"setting__basic_window_size_oversized": "超大",
"setting__basic_window_size_small": "小",
"setting__basic_window_size_smaller": "较小",
"setting__basic_window_size_title": "设置软件窗口尺寸",
"setting__click_copy": "点击复制",
"setting__click_open": "点击打开",
"setting__desktop_lyric": "桌面歌词设置",
"setting__desktop_lyric_always_on_top": "使歌词总是在其他窗口之上",
"setting__desktop_lyric_always_on_top_loop": "自动刷新歌词置顶(当歌词置顶后仍被某些程序遮挡时可尝试启用此设置)",
"setting__desktop_lyric_delay_scroll": "延迟歌词滚动",
"setting__desktop_lyric_enable": "显示歌词",
"setting__desktop_lyric_font": "歌词字体",
"setting__desktop_lyric_font_default": "默认",
"setting__desktop_lyric_hover_hide": "鼠标移入歌词区域时降低歌词透明度(此功能存在平台兼容性问题)",
"setting__desktop_lyric_lock": "锁定歌词",
"setting__desktop_lyric_lock_screen": "不允许歌词窗口拖出主屏幕之外",
"setting__download": "下载设置",
"setting__download_data_embed": "是否将以下内容嵌入到音频文件中",
"setting__download_embed_lyric": "歌词嵌入",
"setting__download_embed_pic": "封面嵌入",
"setting__download_enable": "是否启用下载功能",
"setting__download_lyric": "歌词下载",
"setting__download_lyric_format": "下载的歌词文件编码格式",
"setting__download_lyric_format_gbk": "GBK在某些设备上出现中文乱码时可尝试选择此格式",
"setting__download_lyric_format_utf8": "UTF-8",
"setting__download_lyric_title": "是否同时下载歌词文件",
"setting__download_name": "文件命名方式",
"setting__download_name1": "歌名 - 歌手",
"setting__download_name2": "歌手 - 歌名",
"setting__download_name3": "歌名",
"setting__download_name_title": "下载歌曲时的命名方式",
"setting__download_path": "下载路径",
"setting__download_path_change_btn": "更改",
"setting__download_path_label": "当前下载路径:",
"setting__download_path_open_label": "点击打开当前路径",
"setting__download_path_title": "下载歌曲保存的路径",
"setting__download_select_save_path": "选择歌曲保存路径",
"setting__download_use_other_source": "自动换源下载",
"setting__download_use_other_source_tip": "当无法从歌曲的原始源下载时尝试切换到其他源下载此功能不100%保证换源后的歌曲版本与原版一致",
"setting__hot_key": "快捷键设置",
"setting__hot_key_common_focus_search_input": "聚焦搜索框",
"setting__hot_key_common_min": "最小化程序",
"setting__hot_key_common_toggle_close": "退出程序",
"setting__hot_key_common_toggle_hide": "显示/隐藏程序",
"setting__hot_key_common_toggle_min": "最小化/还原程序",
"setting__hot_key_desktop_lyric_toggle_always_top": "桌面歌词置顶切换",
"setting__hot_key_desktop_lyric_toggle_lock": "桌面歌词锁定切换",
"setting__hot_key_desktop_lyric_toggle_visible": "开/关桌面歌词",
"setting__hot_key_global_title": "全局快捷键",
"setting__hot_key_local_title": "软件内快捷键",
"setting__hot_key_player_next": "下一首歌曲",
"setting__hot_key_player_prev": "上一首歌曲",
"setting__hot_key_player_toggle_play": "播放/暂停控制",
"setting__hot_key_player_volume_down": "减少音量",
"setting__hot_key_player_volume_mute": "静音切换",
"setting__hot_key_player_volume_up": "增加音量",
"setting__hot_key_tip_input": "请输入新的按键",
"setting__hot_key_unset_input": "未设置",
"setting__is_enable": "是否启用",
"setting__is_show": "是否显示",
"setting__list": "列表设置",
"setting__list_add_music_location_type": "添加歌曲到列表时的位置",
"setting__list_add_music_location_type_bottom": "底部",
"setting__list_add_music_location_type_top": "顶部",
"setting__list_click_action": "双击列表里的歌曲时自动切换到当前列表播放(仅对歌单、排行榜有效)",
"setting__list_scroll": "记住播放列表滚动条位置(仅对我的音乐分类有效)",
"setting__list_source": "显示歌曲源(仅对我的音乐分类有效)",
"setting__network": "网络设置",
"setting__network_proxy_host": "主机",
"setting__network_proxy_password": "密码",
"setting__network_proxy_port": "端口",
"setting__network_proxy_title": "HTTP代理设置乱设置软件将无法联网",
"setting__network_proxy_username": "用户名",
"setting__odc": "强迫症设置",
"setting__odc_clear_search_input": "离开搜索界面时清空搜索框",
"setting__odc_clear_search_list": "离开搜索界面时清空搜索列表",
"setting__other": "其他",
"setting__other_play_list_cache": "列表缓存管理",
"setting__other_play_list_cache_clear_btn": "清理列表缓存信息",
"setting__other_play_list_cache_tip": "我的列表中已缓存的歌曲链接、播放代替源,清理后播放、下载歌曲时需要重新获取,没有歌曲播放相关的问题不要清理",
"setting__other_play_list_cache_tip_confirm": "我的列表中已缓存的歌曲链接、播放代替源,清理后播放、下载歌曲时需要重新获取,没有歌曲播放相关的问题不要清理,是否确认清理?",
"setting__other_resource_cache": "资源缓存管理",
"setting__other_resource_cache_clear_btn": "清理资源缓存",
"setting__other_resource_cache_confirm": "我要清掉",
"setting__other_resource_cache_label": "软件已使用缓存大小:",
"setting__other_resource_cache_tip": "图片、音频等缓存,清理后图片等资源将需要重新下载,不建议清理,软件会根据磁盘空间动态管理缓存大小",
"setting__other_resource_cache_tip_confirm": "涉及图片、音频等缓存,清理后图片等资源将需要重新下载,不建议清理,软件会根据磁盘空间动态管理缓存大小,是否仍要清理?",
"setting__other_tray_theme": "托盘图标样式",
"setting__other_tray_theme_black": "黑色",
"setting__other_tray_theme_native": "白色",
"setting__other_tray_theme_origin": "原色",
"setting__play": "播放设置",
"setting__play_auto_skip_on_error": "播放错误时自动切换歌曲",
"setting__play_detail": "播放详情页设置",
"setting__play_detail_align": "歌词对齐方式",
"setting__play_detail_align_center": "居中",
"setting__play_detail_align_left": "居左",
"setting__play_detail_align_right": "居右",
"setting__play_detail_font_size": "歌词字体大小(可以在播放详情页使用键盘的 + - 调整字体大小)",
"setting__play_detail_font_size_current": "当前字体大小:{size}",
"setting__play_detail_font_size_reset": "重置",
"setting__play_detail_font_zoom": "缩放当前正在播放的歌词",
"setting__play_detail_lyric_progress": "允许通过歌词调整播放进度",
"setting__play_lyric_lxlrc": "使用卡拉OK式歌词播放如果可用",
"setting__play_lyric_roma": "显示歌词罗马音(如果可用)",
"setting__play_lyric_s2t": "将播放与下载的歌词转换为繁体中文",
"setting__play_lyric_transition": "显示歌词翻译(如果可用)",
"setting__play_mediaDevice": "音频输出",
"setting__play_mediaDevice_remove_stop_play": "当前的声音输出设备被改变时暂停播放歌曲",
"setting__play_mediaDevice_title": "选择声音输出的媒体设备",
"setting__play_media_device_error_tip": "此功能与音频可视化功能冲突,你本次启动软件时已启用过音频可视化,此设置暂不可用,请 重启 软件后,再来修改此设置。",
"setting__play_media_device_tip": "此功能与音频可视化功能冲突,两者无法同时启用,是否将音频可视化关闭 并 应用所选音频输出设置?",
"setting__play_quality": "优先播放320K品质的歌曲如果可用",
"setting__play_save_play_time": "记住播放进度",
"setting__play_task_bar": "在任务栏上显示当前歌曲播放进度",
"setting__play_timeout": "定时暂停",
"setting__player_audio_visualization_tip": "自定义音频输出设备与音频可视化功能会冲突,启用了音频可视化后音频输出设备将会被重置为默认的输出设备,目前此问题暂无法解决,是否仍要开启?",
"setting__search": "搜索设置",
"setting__search_focus_search_box": "启动时自动聚焦搜索框",
"setting__search_history": "显示历史搜索记录",
"setting__search_hot": "显示热门搜索",
"setting__sync": "数据同步",
"setting__sync_address": "同步服务地址:{address}",
"setting__sync_auth_code": "连接码:{code}",
"setting__sync_device": "已连接的设备:{devices}",
"setting__sync_enable": "启用同步功能(由于数据是明文传输,请在受信任的网络下使用)",
"setting__sync_port": "同步端口设置",
"setting__sync_port_tip": "请输入同步服务端口号",
"setting__sync_refresh_code": "刷新连接码",
"setting__sync_tip": "使用方式请看常见问题“同步功能”部分",
"setting__update": "软件更新",
"setting__update_checking": "检查更新中...",
"setting__update_current_label": "当前版本:",
"setting__update_downloading": "发现新版本并在努力下载中,请稍后...⏳",
"setting__update_init": "处理更新中...",
"setting__update_latest": "软件已是最新,尽情地体验吧~🥂",
"setting__update_latest_label": "最新版本:",
"setting__update_open_version_modal_btn": "打开更新窗口 🚀",
"setting__update_progress": "下载进度:",
"setting__update_unknown": "未知",
"song_list": "歌单",
"songlist__import_input_tip": "输入歌单链接或歌单ID",
"songlist__import_input_tip_1": "不支持跨源打开歌单,请确认要打开的歌单与当前歌单源是否对应",
"songlist__import_input_tip_2": "若遇到无法打开的歌单链接,欢迎反馈",
"songlist__import_input_tip_3": "酷狗源不支持用歌单ID打开但支持酷狗码打开",
"songlist__open_list": "打开{name}歌单",
"source_alias_all": "聚合大会",
"source_alias_bd": "小杜音乐",
"source_alias_kg": "小枸音乐",
"source_alias_kw": "小蜗音乐",
"source_alias_mg": "小蜜音乐",
"source_alias_tx": "小秋音乐",
"source_alias_wy": "小芸音乐",
"source_alias_xm": "小霞音乐",
"source_all": "聚合搜索",
"source_bd": "百度音乐",
"source_kg": "酷狗音乐",
"source_kw": "酷我音乐",
"source_mg": "咪咕音乐",
"source_tx": "企鹅音乐",
"source_wy": "网易音乐",
"source_xm": "虾米音乐",
"sync__merge_btn_local_remote": "本机列表 合并 远程列表",
"sync__merge_btn_remote_local": "远程列表 合并 本机列表",
"sync__merge_label": "合并",
"sync__merge_tip": "合并:",
"sync__merge_tip_desc": "将两边的列表合并到一起,相同的歌曲将被去掉(去掉的是被合并者的歌曲),不同的歌曲将被添加。",
"sync__other_label": "其他",
"sync__other_tip": "其他:",
"sync__other_tip_desc": "“仅使用实时同步功能”将不修改双方的列表,仅实时同步操作;“取消同步”将直接断开双方的连接。",
"sync__overwrite": "完全覆盖",
"sync__overwrite_btn_cancel": "取消同步",
"sync__overwrite_btn_local_remote": "本机列表 覆盖 远程列表",
"sync__overwrite_btn_none": "仅使用实时同步功能",
"sync__overwrite_btn_remote_local": "远程列表 覆盖 本机列表",
"sync__overwrite_label": "覆盖",
"sync__overwrite_tip": "覆盖:",
"sync__overwrite_tip_desc": "被覆盖者与覆盖者列表ID相同的列表将被删除后替换成覆盖者的列表列表ID不同的列表将被合并到一起若勾选完全覆盖则被覆盖者的所有列表将被移除然后替换成覆盖者的列表。",
"sync__title": "选择与 {name} 的列表同步方式",
"tag__high_quality": "HQ",
"tag__lossless": "SQ",
"tag__lossless_24bit": "24bit",
"theme_auto": "道法自然",
"theme_auto_tip": "鼠标 右击 可打开亮、暗主题设置窗口",
"theme_black": "黑灯瞎火",
"theme_blue": "蓝田生玉",
"theme_blue2": "清热版蓝",
"theme_green": "绿意盎然",
"theme_grey": "灰常美丽",
"theme_happy_new_year": "新年快乐",
"theme_mid_autumn": "月里嫦娥",
"theme_ming": "青出于黑",
"theme_naruto": "木叶之村",
"theme_orange": "橙黄橘绿",
"theme_pink": "粉装玉琢",
"theme_purple": "重斤球紫",
"theme_red": "热情似火",
"theme_selector_modal__dark_title": "暗色主题",
"theme_selector_modal__light_title": "亮色主题",
"theme_selector_modal__title": "跟随系统主题设置",
"theme_selector_modal__title_tip": "注:你可以预先设置一个亮色主题及暗色主题,此后将根据系统的亮、暗主题色自动切换为你预先设置的相应主题。",
"theme_yellow": "信口雌黄",
"user_api__allow_show_update_alert": "允许显示更新弹窗",
"user_api__btn_export": "导出",
"user_api__btn_import": "导入",
"user_api__btn_remove": "移除",
"user_api__import_file": "选择音乐API脚本文件",
"user_api__max_tip": "最多只能同时存在20个源哦🤪\n想要继续导入的话请先移除一些旧的源腾出位置吧",
"user_api__noitem": "这里竟然是空的 😲",
"user_api__note": "提示:虽然我们已经尽可能地隔离了脚本的运行环境,但导入包含恶意行为的脚本仍可能会影响你的系统,请谨慎导入。",
"user_api__readme": "源编写说明:",
"user_api__title": "自定义源管理",
"user_api__update_alert": "自定义源 [{name}] 发现新版本:",
"user_api__update_alert_open_url": "打开更新地址"
}

478
src/lang/zh-tw.json Normal file
View File

@@ -0,0 +1,478 @@
{
"action": "操作",
"agree": "接受",
"alert_button_text": "好吧",
"audio_visualization": "音頻可視化(實驗性)",
"back": "返回",
"cancel_button_text": "取消",
"close": "關閉",
"comment__hot_load_error": "熱門評論加載失敗,點擊嘗試重新加載",
"comment__hot_loading": "熱門評論加載中",
"comment__hot_title": "熱門評論",
"comment__new_load_error": "最新評論加載失敗,點擊嘗試重新加載",
"comment__new_loading": "最新評論加載中",
"comment__new_title": "最新評論",
"comment__no_content": "暫無評論",
"comment__refresh": "刷新評論",
"comment__show": "歌曲評論",
"comment__title": "{name} 的評論",
"confirm_button_text": "是的",
"copy_tip": "(點擊複製)",
"date_format_hour": "{num}小時前",
"date_format_minute": "{num}分鐘前",
"date_format_second": "{num}秒前",
"deep_link__handle_error_tip": "調用失敗:{message}",
"default": "默認",
"default_list": "試聽列表",
"desktop_lyric__back": "返回",
"desktop_lyric__close": "關閉",
"desktop_lyric__font_decrease": "減小字體大小(右擊可微調)",
"desktop_lyric__font_increase": "增加字體大小(右擊可微調)",
"desktop_lyric__lock": "鎖定歌詞",
"desktop_lyric__lrc_active_zoom_off": "取消縮放當前播放的歌詞",
"desktop_lyric__lrc_active_zoom_on": "縮放當前播放的歌詞",
"desktop_lyric__opactiy_decrease": "增加透明度(右擊可微調)",
"desktop_lyric__opactiy_increase": "減小透明度(右擊可微調)",
"desktop_lyric__theme": "主題配色",
"desktop_lyric__unlock": "解鎖歌詞",
"desktop_lyric__win_top_off": "取消置頂歌詞界面",
"desktop_lyric__win_top_on": "置頂歌詞界面",
"download": "下載",
"download__all": "全部任務",
"download__error": "出錯",
"download__finished": "下載完成",
"download__high_quality": "高品音質",
"download__lossless": "無損音質",
"download__multiple_tip": "已選擇 {len} 首歌曲",
"download__multiple_tip2": "請選擇要優先下載的音質",
"download__normal": "普通音質",
"download__not_available_tip": "該音質不可用",
"download__paused": "已暫停",
"download__progress": "進度",
"download__quality": "品質",
"download__runing": "正在下載",
"download__status": "狀態",
"export": "導出",
"fullscreen_exit": "退出全屏",
"history_clear": "清空搜索歷史",
"history_remove": "右擊移除該歷史",
"history_search": "歷史搜索",
"import": "導入",
"leaderboard": "排行榜",
"list__add_to": "添加到...",
"list__collect": "收藏",
"list__copy_name": "複製歌曲名",
"list__download": "下載",
"list__export_part_desc": "選擇列表文件保存位置",
"list__file": "定位文件",
"list__import_part_button_cancel": "不要啊",
"list__import_part_button_confirm": "覆蓋掉",
"list__import_part_confirm": "導入的列表({importName})與本地列表({localName}的ID相同是否覆蓋本地列表",
"list__import_part_desc": "選擇列表文件",
"list__load_failed": "啊,加載失敗了😭",
"list__loading": "列表加載中...⏳",
"list__move_to": "移動到...",
"list__movedown": "下移",
"list__moveup": "上移",
"list__new_list_btn": "新建列表",
"list__new_list_input": "新列表...",
"list__pause": "暫停任務",
"list__play": "播放",
"list__play_later": "稍後播放",
"list__remove": "刪除",
"list__remove_tip": "你真的想要移除 {name} 嗎?",
"list__remove_tip_button": "是的 沒錯",
"list__rename": "重命名",
"list__search": "搜索",
"list__sort": "調整位置",
"list__source_detail": "歌曲詳情頁",
"list__start": "開始任務",
"list__sync": "更新",
"list_add__btn_title": "把該歌曲添加到 {name}",
"list_add__multiple_btn_title": "把這些歌曲添加到 {name}",
"list_add__multiple_title_add": "添加已選的 {num} 首歌曲到...",
"list_add__multiple_title_move": "移動已選的 {num} 首歌曲到...",
"list_add__title_first_add": "添加",
"list_add__title_first_move": "移動",
"list_add__title_last": "到...",
"list_import_tip__alldata": "導入失敗,這是一個所有數據備份文件,你需要去這裡導入:\n設置 -> 備份與恢復 -> 所有數據 -> 導入",
"list_import_tip__playlist": "導入失敗,這是一個列表備份文件,你需要去這裡導入:\n設置 -> 備份與恢復 -> 部分數據 -> 導入列表",
"list_import_tip__playlist_part": "導入失敗,這是一個單列表文件,你需要去這裡導入:\n我的列表 -> 右擊任意一個列表名 -> 在彈出的菜單中選擇導入",
"list_import_tip__setting": "導入失敗,這是一個設置備份文件,你需要去這裡導入:\n設置 -> 備份與恢復 -> 部分數據 -> 設置導入",
"list_import_tip__unknown": "導入失敗,未知的文件類型,請嘗試升級到最新版本後再試",
"list_sort_modal_by_album": "專輯名",
"list_sort_modal_by_down": "降序",
"list_sort_modal_by_field": "排序字段",
"list_sort_modal_by_name": "歌曲名",
"list_sort_modal_by_singer": "歌手名",
"list_sort_modal_by_source": "歌曲源",
"list_sort_modal_by_time": "時長",
"list_sort_modal_by_type": "排序類別",
"list_sort_modal_by_up": "升序",
"list_sort_modal_tip_confirm": "你確定要這麼做嗎?",
"list_update_modal__auto_update": "自動更新",
"list_update_modal__tips": "💡 每次啟動軟件時將會自動更新已勾選“自動更新”的列表",
"list_update_modal__title": "列表更新管理",
"list_update_modal__update": "立即更新",
"lists__duplicate": "重複歌曲",
"lists__export": "導出",
"lists__export_part_desc": "選擇列表文件保存位置",
"lists__import": "導入",
"lists__import_part_button_cancel": "不要啊",
"lists__import_part_button_confirm": "覆蓋掉",
"lists__import_part_confirm": "導入的列表({importName})與本地列表({localName}的ID相同是否覆蓋本地列表",
"lists__import_part_desc": "選擇列表文件",
"lists__new_list_btn": "新建列表",
"lists__new_list_input": "新列表...",
"lists__remove": "刪除",
"lists__remove music_tip": "你真的要移除所選的 {len} 首歌曲嗎?",
"lists__remove_tip": "你真的想要移除 {name} 嗎?",
"lists__remove_tip_button": "是的 沒錯",
"lists__rename": "重命名",
"lists__sort_list": "排序歌曲",
"lists__source_detail": "歌單詳情頁",
"lists__sync": "更新",
"lists__sync_confirm_tip": "這將會把 {name} 內的歌曲替換成在線列表的歌曲,你確認要更新嗎?",
"load_list_file_error_detail": "我們已經幫你把舊的列表文件備份到{path}\n它以 JSON 格式存儲,你可以嘗試手動修復並恢復它\n\n錯誤詳情{detail}",
"load_list_file_error_title": "播放列表數據加載錯誤建議到GitHub或加群反饋",
"loding": "加載中...",
"love_list": "收藏",
"lyric__load_error": "歌詞獲取失敗",
"lyric__select": "歌詞文本選擇",
"lyric_menu__align": "歌詞對齊方式",
"lyric_menu__align_center": "居中",
"lyric_menu__align_left": "居左",
"lyric_menu__lrc_size": "字體大小 [ {size} ]",
"lyric_menu__offset": "歌詞偏移 [ {offset}ms ]",
"lyric_menu__offset_add_10": "加快10毫秒",
"lyric_menu__offset_add_100": "加快100毫秒",
"lyric_menu__offset_dec_10": "減慢10毫秒",
"lyric_menu__offset_dec_100": "減慢100毫秒",
"lyric_menu__offset_reset": "重置",
"lyric_menu__size_add": "加大字體(右擊可微調)",
"lyric_menu__size_dec": "減小字體(右擊可微調)",
"lyric_menu__size_reset": "重置",
"min": "最小化",
"music_album": "專輯名",
"music_duplicate": "重複歌曲",
"music_name": "歌曲名",
"music_singer": "藝術家",
"music_sort__btn_cancel": "取消",
"music_sort__btn_confirm": "確定",
"music_sort__input_tip": "請輸入要調整到第幾個位置",
"music_sort__title": "將 {name} 的位置調整到:",
"music_sort__title_multiple": "將已選的 {num} 首歌曲的位置調整到:",
"music_time": "時長",
"my_list": "我的列表",
"no_item": "列表竟然是空的...",
"not_agree": "不接受",
"ok": "我知道了",
"pagination__next": "下一頁",
"pagination__page": "第 {num} 頁",
"pagination__prev": "上一頁",
"play_timeout": "定時暫停",
"play_timeout_close": "關閉",
"play_timeout_confirm": "確認",
"play_timeout_end": "等待歌曲播放完畢再暫停",
"play_timeout_stop": "取消定時",
"play_timeout_tip": "{time} 後暫停播放",
"play_timeout_unit": "分鐘",
"play_timeout_update": "更新定時",
"player__add_music_to": "添加當前歌曲到...",
"player__buffering": "緩衝中...",
"player__desktop_lyric_lock": "右擊鎖定歌詞",
"player__desktop_lyric_off": "關閉桌面歌詞",
"player__desktop_lyric_on": "開啟桌面歌詞",
"player__desktop_lyric_unlock": "右擊解鎖歌詞",
"player__end": "播放完畢",
"player__error": "音頻加載出錯5 秒後切換下一首",
"player__geting_url": "歌曲鏈接獲取中...",
"player__hide_detail_tip": "隱藏詳情頁(界面內右鍵雙擊可快速隱藏詳情頁)",
"player__loading": "音樂加載中...",
"player__music_album": "專輯名:",
"player__music_name": "歌曲名:",
"player__music_singer": "藝術家:",
"player__next": "下一首",
"player__pause": "暫停",
"player__pic_tip": "播放詳情頁(右擊在“我的列表”定位當前播放的歌曲)",
"player__play": "播放",
"player__play_toggle_mode_list": "順序播放",
"player__play_toggle_mode_list_loop": "列表循環",
"player__play_toggle_mode_off": "禁用",
"player__play_toggle_mode_random": "列表隨機",
"player__play_toggle_mode_single_loop": "單曲循環",
"player__playing": "播放中...",
"player__prev": "上一首",
"player__refresh_url": "URL過期正在刷新URL...",
"player__stop": "暫停播放",
"player__volume": "當前音量:",
"search": "搜索",
"search__hot_search": "熱門搜索",
"search__welcome": "搜我所想~~😉",
"setting": "設置",
"setting__about": "關於洛雪音樂",
"setting__backup": "備份與恢復",
"setting__backup_all": "所有數據(列表數據與設置數據)",
"setting__backup_all_export": "導出",
"setting__backup_all_export_desc": "選擇備份保存位置",
"setting__backup_all_import": "導入",
"setting__backup_all_import_desc": "選擇備份文件",
"setting__backup_other": "其他備份格式(目前不支持恢復此類備份文件)",
"setting__backup_other_export_dir": "選擇文件保存位置",
"setting__backup_other_export_list_csv": "導出 CSV 格式的列表",
"setting__backup_other_export_list_text": "導出 TXT 格式的列表",
"setting__backup_other_export_list_text_confirm": "是否將所有列表合併為一個文件?",
"setting__backup_part": "部分數據(列表數據包括試聽列表、收藏列表、用戶自定義列表,設置數據不包括快捷鍵設置)",
"setting__backup_part_export_list": "導出列表",
"setting__backup_part_export_list_desc": "選擇歌單保存位置",
"setting__backup_part_export_setting": "導出設置",
"setting__backup_part_export_setting_desc": "選擇設置保存位置",
"setting__backup_part_import_list": "導入列表",
"setting__backup_part_import_list_desc": "選擇列表文件",
"setting__backup_part_import_setting": "導入設置",
"setting__backup_part_import_setting_desc": "選擇配置文件",
"setting__basic": "基本設置",
"setting__basic_animation": "彈出層隨機動畫",
"setting__basic_control_btn_position": "控制按鈕位置",
"setting__basic_control_btn_position_left": "左邊",
"setting__basic_control_btn_position_right": "右邊",
"setting__basic_font": "字體",
"setting__basic_lang": "語言",
"setting__basic_lang_title": "軟件顯示的語言",
"setting__basic_show_animation": "顯示切換動畫",
"setting__basic_source": "音樂來源",
"setting__basic_source_status_failed": "初始化失敗",
"setting__basic_source_status_initing": "初始化中",
"setting__basic_source_status_success": "初始化成功",
"setting__basic_source_temp": "臨時接口(軟件的某些功能不可用,建議測試接口不可用再使用本接口)",
"setting__basic_source_test": "測試接口(幾乎軟件的所有功能都可用)",
"setting__basic_source_title": "選擇音樂來源",
"setting__basic_source_user_api_btn": "自定義源管理",
"setting__basic_sourcename": "音源名字",
"setting__basic_sourcename_alias": "別名",
"setting__basic_sourcename_real": "原名",
"setting__basic_sourcename_title": "選擇音源名字類型",
"setting__basic_start_in_fullscreen": "以全屏模式啟動",
"setting__basic_theme": "主題顏色",
"setting__basic_theme_auto_tip": "此乃動態主題,你可以預先設置一個亮色主題及暗色主題,此後將根據系統的亮、暗主題色自動切換為你預先設置的相應主題。\n注鼠標 右擊 此主題項即可打開亮、暗色主題設置窗口。",
"setting__basic_to_tray": "關閉軟件時不退出軟件將其最小化到系統托盤",
"setting__basic_window_size": "窗口尺寸",
"setting__basic_window_size_big": "大",
"setting__basic_window_size_huge": "巨大",
"setting__basic_window_size_larger": "較大",
"setting__basic_window_size_medium": "中",
"setting__basic_window_size_oversized": "超大",
"setting__basic_window_size_small": "小",
"setting__basic_window_size_smaller": "較小",
"setting__basic_window_size_title": "設置軟件窗口尺寸",
"setting__click_copy": "點擊複製",
"setting__click_open": "點擊打開",
"setting__desktop_lyric": "桌面歌詞設置",
"setting__desktop_lyric_always_on_top": "使歌詞總是在其他窗口之上",
"setting__desktop_lyric_always_on_top_loop": "自動刷新歌詞置頂(當歌詞置頂後仍被某些程序遮擋時可嘗試啟用此設置)",
"setting__desktop_lyric_delay_scroll": "延遲歌詞滾動",
"setting__desktop_lyric_enable": "顯示歌詞",
"setting__desktop_lyric_font": "歌詞字體",
"setting__desktop_lyric_font_default": "默認",
"setting__desktop_lyric_hover_hide": "鼠標移入歌詞區域時降低歌詞透明度(此功能存在平台兼容性問題)",
"setting__desktop_lyric_lock": "鎖定歌詞",
"setting__desktop_lyric_lock_screen": "不允許歌詞窗口拖出主屏幕之外",
"setting__download": "下載設置",
"setting__download_data_embed": "是否將以下內容嵌入到音頻文件中",
"setting__download_embed_lyric": "歌詞嵌入",
"setting__download_embed_pic": "封面嵌入",
"setting__download_enable": "是否啟用下載功能",
"setting__download_lyric": "歌詞下載",
"setting__download_lyric_format": "下載的歌詞文件編碼格式",
"setting__download_lyric_format_gbk": "GBK在某些設備上出現中文亂碼時可嘗試選擇此格式",
"setting__download_lyric_format_utf8": "UTF-8",
"setting__download_lyric_title": "是否同時下載歌詞文件",
"setting__download_name": "文件命名方式",
"setting__download_name1": "歌名 - 歌手",
"setting__download_name2": "歌手 - 歌名",
"setting__download_name3": "歌名",
"setting__download_name_title": "下載歌曲時的命名方式",
"setting__download_path": "下載路徑",
"setting__download_path_change_btn": "更改",
"setting__download_path_label": "當前下載路徑:",
"setting__download_path_open_label": "點擊打開當前路徑",
"setting__download_path_title": "下載歌曲保存的路徑",
"setting__download_select_save_path": "選擇歌曲保存路徑",
"setting__download_use_other_source": "自動換源下載",
"setting__download_use_other_source_tip": "當無法從歌曲的原始源下載時嘗試切換到其他源下載此功能不100%保證換源後的歌曲版本與原版一致",
"setting__hot_key": "快捷鍵設置",
"setting__hot_key_common_focus_search_input": "聚焦搜索框",
"setting__hot_key_common_min": "最小化程序",
"setting__hot_key_common_toggle_close": "退出程序",
"setting__hot_key_common_toggle_hide": "顯示/隱藏程序",
"setting__hot_key_common_toggle_min": "最小化/還原程序",
"setting__hot_key_desktop_lyric_toggle_always_top": "桌面歌詞置頂切換",
"setting__hot_key_desktop_lyric_toggle_lock": "桌面歌詞鎖定切換",
"setting__hot_key_desktop_lyric_toggle_visible": "開/關桌面歌詞",
"setting__hot_key_global_title": "全局快捷鍵",
"setting__hot_key_local_title": "軟件內快捷鍵",
"setting__hot_key_player_next": "下一首歌曲",
"setting__hot_key_player_prev": "上一首歌曲",
"setting__hot_key_player_toggle_play": "播放/暫停控制",
"setting__hot_key_player_volume_down": "減少音量",
"setting__hot_key_player_volume_mute": "靜音切換",
"setting__hot_key_player_volume_up": "增加音量",
"setting__hot_key_tip_input": "請輸入新的按鍵",
"setting__hot_key_unset_input": "未設置",
"setting__is_enable": "是否啟用",
"setting__is_show": "是否顯示",
"setting__list": "列表設置",
"setting__list_add_music_location_type": "添加歌曲到列表時的位置",
"setting__list_add_music_location_type_bottom": "底部",
"setting__list_add_music_location_type_top": "頂部",
"setting__list_click_action": "雙擊列表裡的歌曲時自動切換到當前列表播放(僅對歌單、排行榜有效)",
"setting__list_scroll": "記住播放列表滾動條位置(僅對我的音樂分類有效)",
"setting__list_source": "顯示歌曲源(僅對我的音樂分類有效)",
"setting__network": "網絡設置",
"setting__network_proxy_host": "主機",
"setting__network_proxy_password": "密碼",
"setting__network_proxy_port": "端口",
"setting__network_proxy_title": "HTTP代理設置亂設置軟件將無法聯網",
"setting__network_proxy_username": "用戶名",
"setting__odc": "強迫症設置",
"setting__odc_clear_search_input": "離開搜索界面時清空搜索框",
"setting__odc_clear_search_list": "離開搜索界面時清空搜索列表",
"setting__other": "其他",
"setting__other_play_list_cache": "列表緩存管理",
"setting__other_play_list_cache_clear_btn": "清理列表緩存信息",
"setting__other_play_list_cache_tip": "我的列表中已緩存的歌曲鏈接、播放代替源,清理後播放、下載歌曲時需要重新獲取,沒有歌曲播放相關的問題不要清理",
"setting__other_play_list_cache_tip_confirm": "我的列表中已緩存的歌曲鏈接、播放代替源,清理後播放、下載歌曲時需要重新獲取,沒有歌曲播放相關的問題不要清理,是否確認清理?",
"setting__other_resource_cache": "資源緩存管理",
"setting__other_resource_cache_clear_btn": "清理資源緩存",
"setting__other_resource_cache_confirm": "我要清掉",
"setting__other_resource_cache_label": "軟件已使用緩存大小:",
"setting__other_resource_cache_tip": "圖片、音頻等緩存,清理後圖片等資源將需要重新下載,不建議清理,軟件會根據磁盤空間動態管理緩存大小",
"setting__other_resource_cache_tip_confirm": "涉及圖片、音頻等緩存,清理後圖片等資源將需要重新下載,不建議清理,軟件會根據磁盤空間動態管理緩存大小,是否仍要清理?",
"setting__other_tray_theme": "托盤圖標樣式",
"setting__other_tray_theme_black": "黑色",
"setting__other_tray_theme_native": "白色",
"setting__other_tray_theme_origin": "原色",
"setting__play": "播放設置",
"setting__play_auto_skip_on_error": "播放錯誤時自動切換歌曲",
"setting__play_detail": "播放詳情頁設置",
"setting__play_detail_align": "歌詞對齊方式",
"setting__play_detail_align_center": "居中",
"setting__play_detail_align_left": "居左",
"setting__play_detail_align_right": "居右",
"setting__play_detail_font_size": "歌詞字體大小(可以在播放詳情頁使用鍵盤的 + - 調整字體大小)",
"setting__play_detail_font_size_current": "當前字體大小:{size}",
"setting__play_detail_font_size_reset": "重置",
"setting__play_detail_font_zoom": "縮放當前正在播放的歌詞",
"setting__play_detail_lyric_progress": "允許通過歌詞調整播放進度",
"setting__play_lyric_lxlrc": "使用卡拉OK式歌詞播放如果可用",
"setting__play_lyric_roma": "顯示歌詞羅馬音(如果可用)",
"setting__play_lyric_s2t": "將播放與下載的歌詞轉換為繁體中文",
"setting__play_lyric_transition": "顯示歌詞翻譯(如果可用)",
"setting__play_mediaDevice": "音頻輸出",
"setting__play_mediaDevice_remove_stop_play": "當前的聲音輸出設備被改變時暫停播放歌曲",
"setting__play_mediaDevice_title": "選擇聲音輸出的媒體設備",
"setting__play_media_device_error_tip": "此功能與音頻可視化功能衝突,你本次啟動軟件時已啟用過音頻可視化,此設置暫不可用,請 重啟 軟件後,再來修改此設置。",
"setting__play_media_device_tip": "此功能與音頻可視化功能衝突,兩者無法同時啟用,是否將音頻可視化關閉 並 應用所選音頻輸出設置?",
"setting__play_quality": "優先播放320K品質的歌曲如果可用",
"setting__play_save_play_time": "記住播放進度",
"setting__play_task_bar": "在任務欄上顯示當前歌曲播放進度",
"setting__play_timeout": "定時暫停",
"setting__player_audio_visualization_tip": "自定義音頻輸出設備與音頻可視化功能會衝突,啟用了音頻可視化後音頻輸出設備將會被重置為默認的輸出設備,目前此問題暫無法解決,是否仍要開啟?",
"setting__search": "搜索設置",
"setting__search_focus_search_box": "啟動時自動聚焦搜索框",
"setting__search_history": "顯示歷史搜索記錄",
"setting__search_hot": "顯示熱門搜索",
"setting__sync": "數據同步",
"setting__sync_address": "同步服務地址:{address}",
"setting__sync_auth_code": "連接碼:{code}",
"setting__sync_device": "已連接的設備:{devices}",
"setting__sync_enable": "啟用同步功能(由於數據是明文傳輸,請在受信任的網絡下使用)",
"setting__sync_port": "同步端口設置",
"setting__sync_port_tip": "請輸入同步服務端口號",
"setting__sync_refresh_code": "刷新連接碼",
"setting__sync_tip": "使用方式請看常見問題“同步功能”部分",
"setting__update": "軟件更新",
"setting__update_checking": "檢查更新中...",
"setting__update_current_label": "當前版本:",
"setting__update_downloading": "發現新版本並在努力下載中,請稍後...⏳",
"setting__update_init": "處理更新中...",
"setting__update_latest": "軟件已是最新,盡情地體驗吧~🥂",
"setting__update_latest_label": "最新版本:",
"setting__update_open_version_modal_btn": "打開更新窗口 🚀",
"setting__update_progress": "下載進度:",
"setting__update_unknown": "未知",
"song_list": "歌單",
"songlist__import_input_tip": "輸入歌單鏈接或歌單ID",
"songlist__import_input_tip_1": "不支持跨源打開歌單,請確認要打開的歌單與當前歌單源是否對應",
"songlist__import_input_tip_2": "若遇到無法打開的歌單鏈接,歡迎反饋",
"songlist__import_input_tip_3": "酷狗源不支持用歌單ID打開但支持酷狗碼打開",
"songlist__open_list": "打開{name}歌單",
"source_alias_all": "聚合大會",
"source_alias_bd": "小杜音樂",
"source_alias_kg": "小枸音樂",
"source_alias_kw": "小蝸音樂",
"source_alias_mg": "小蜜音樂",
"source_alias_tx": "小秋音樂",
"source_alias_wy": "小芸音樂",
"source_alias_xm": "小霞音樂",
"source_all": "聚合搜索",
"source_bd": "百度音樂",
"source_kg": "酷狗音樂",
"source_kw": "酷我音樂",
"source_mg": "咪咕音樂",
"source_tx": "企鵝音樂",
"source_wy": "網易音樂",
"source_xm": "蝦米音樂",
"sync__merge_btn_local_remote": "本機列表 合併 遠程列表",
"sync__merge_btn_remote_local": "遠程列表 合併 本機列表",
"sync__merge_label": "合併",
"sync__merge_tip": "合併:",
"sync__merge_tip_desc": "將兩邊的列表合併到一起,相同的歌曲將被去掉(去掉的是被合併者的歌曲),不同的歌曲將被添加。",
"sync__other_label": "其他",
"sync__other_tip": "其他:",
"sync__other_tip_desc": "“僅使用實時同步功能”將不修改雙方的列表,僅實時同步操作;“取消同步”將直接斷開雙方的連接。",
"sync__overwrite": "完全覆蓋",
"sync__overwrite_btn_cancel": "取消同步",
"sync__overwrite_btn_local_remote": "本機列表 覆蓋 遠程列表",
"sync__overwrite_btn_none": "僅使用實時同步功能",
"sync__overwrite_btn_remote_local": "遠程列表 覆蓋 本機列表",
"sync__overwrite_label": "覆蓋",
"sync__overwrite_tip": "覆蓋:",
"sync__overwrite_tip_desc": "被覆蓋者與覆蓋者列表ID相同的列表將被刪除後替換成覆蓋者的列表列表ID不同的列表將被合併到一起若勾選完全覆蓋則被覆蓋者的所有列表將被移除然後替換成覆蓋者的列表。",
"sync__title": "選擇與 {name} 的列表同步方式",
"tag__high_quality": "HQ",
"tag__lossless": "SQ",
"tag__lossless_24bit": "24bit",
"theme_auto": "道法自然",
"theme_auto_tip": "鼠標 右擊 可打開亮、暗主題設置窗口",
"theme_black": "黑燈瞎火",
"theme_blue": "藍田生玉",
"theme_blue2": "清熱版藍",
"theme_green": "綠意盎然",
"theme_grey": "灰常美麗",
"theme_happy_new_year": "新年快樂",
"theme_mid_autumn": "月裡嫦娥",
"theme_ming": "青出於黑",
"theme_naruto": "木葉之村",
"theme_orange": "橙黃橘綠",
"theme_pink": "粉裝玉琢",
"theme_purple": "重斤球紫",
"theme_red": "熱情似火",
"theme_selector_modal__dark_title": "暗色主題",
"theme_selector_modal__light_title": "亮色主題",
"theme_selector_modal__title": "跟隨系統主題設置",
"theme_selector_modal__title_tip": "注:你可以預先設置一個亮色主題及暗色主題,此後將根據系統的亮、暗主題色自動切換為你預先設置的相應主題。",
"theme_yellow": "信口雌黃",
"user_api__allow_show_update_alert": "允許顯示更新彈窗",
"user_api__btn_export": "導出",
"user_api__btn_import": "導入",
"user_api__btn_remove": "移除",
"user_api__import_file": "選擇音樂API腳本文件",
"user_api__max_tip": "最多只能同時存在20個源哦🤪\n想要繼續導入的話請先移除一些舊的源騰出位置吧",
"user_api__noitem": "這裡竟然是空的 😲",
"user_api__note": "提示:雖然我們已經盡可能地隔離了腳本的運行環境,但導入包含惡意行為的腳本仍可能會影響你的系統,請謹慎導入。",
"user_api__readme": "源編寫說明:",
"user_api__title": "自定義源管理",
"user_api__update_alert": "自定義源 [{name}] 發現新版本:",
"user_api__update_alert_open_url": "打開更新地址"
}

23
src/main/env/cmdParams.js vendored Normal file
View File

@@ -0,0 +1,23 @@
const urlSchemeRxp = /^lxmusic:\/\//
const parseEnv = () => {
const params = {}
const rx = /^-\w+/
for (let param of process.argv) {
if (urlSchemeRxp.test(param)) {
global.envParams.deeplink = param
}
if (!rx.test(param)) continue
param = param.substring(1)
let index = param.indexOf('=')
if (index < 0) {
params[param] = true
} else {
params[param.substring(0, index)] = param.substring(index + 1)
}
}
return params
}
global.envParams.cmdParams = parseEnv()

4
src/main/env/index.js vendored Normal file
View File

@@ -0,0 +1,4 @@
global.envParams = {}
require('./cmdParams')
require('./screen')

11
src/main/env/screen.js vendored Normal file
View File

@@ -0,0 +1,11 @@
const { app, screen } = require('electron')
const initScreenParams = () => {
global.envParams.workAreaSize = screen.getPrimaryDisplay().workAreaSize
}
app.on('ready', () => {
screen.on('display-metrics-changed', initScreenParams)
initScreenParams()
})

34
src/main/event.js Normal file
View File

@@ -0,0 +1,34 @@
const { common: COMMON_EVENT_NAME, mainWindow: MAIN_WINDOW_EVENT_NAME } = require('./events/_name')
const { mainSend, NAMES: { mainWindow: ipcMainWindowNames } } = require('./../common/ipc')
const { getAppHotKeyConfig } = require('./utils')
global.lx_event.common.on(COMMON_EVENT_NAME.configStatus, name => {
if (MAIN_WINDOW_EVENT_NAME.name === name) return
if (global.modules.mainWindow) mainSend(global.modules.mainWindow, ipcMainWindowNames.set_config, global.appSetting)
})
global.lx_event.common.on(COMMON_EVENT_NAME.initHotKey, () => {
global.appHotKey.config = getAppHotKeyConfig()
})
global.lx_event.mainWindow.on(MAIN_WINDOW_EVENT_NAME.quit, () => {
global.isTrafficLightClose = false
global.isQuitting = true
global.modules.mainWindow.close()
})
global.lx_event.mainWindow.on(MAIN_WINDOW_EVENT_NAME.toggle_minimize, () => {
if (global.modules.mainWindow.isMinimized()) {
if (!global.modules.mainWindow.isVisible()) {
global.modules.mainWindow.show()
}
global.modules.mainWindow.restore()
global.modules.mainWindow.focus()
} else {
global.modules.mainWindow.minimize()
}
})
global.lx_event.mainWindow.on(MAIN_WINDOW_EVENT_NAME.toggle_hide, () => {
global.modules.mainWindow.isVisible()
? global.modules.mainWindow.hide()
: global.modules.mainWindow.show()
})

20
src/main/events/Common.js Normal file
View File

@@ -0,0 +1,20 @@
const { EventEmitter } = require('events')
const { common: COMMON_EVENT_NAME } = require('./_name')
class Common extends EventEmitter {
initSetting() {
this.emit(COMMON_EVENT_NAME.initConfig)
this.configStatus(null)
}
configStatus(name) {
this.emit(COMMON_EVENT_NAME.configStatus, name)
}
saveMyList(data) {
this.emit(COMMON_EVENT_NAME.saveMyList, data)
}
}
module.exports = Common

21
src/main/events/HotKey.js Normal file
View File

@@ -0,0 +1,21 @@
const { EventEmitter } = require('events')
const { hotKey: HOT_KEY_EVENT_NAME } = require('./_name')
const { saveAppHotKeyConfig } = require('../utils')
class HotKey extends EventEmitter {
init() {
this.emit(HOT_KEY_EVENT_NAME.init)
}
saveConfig(config, source) {
if (config) saveAppHotKeyConfig(config)
this.emit(HOT_KEY_EVENT_NAME.config, config, source)
}
keyDown(info) {
this.emit(HOT_KEY_EVENT_NAME.keyDown, info)
}
}
module.exports = HotKey

View File

@@ -0,0 +1,42 @@
const { EventEmitter } = require('events')
const { mainWindow: MAIN_WINDOW_EVENT_NAME } = require('./_name')
class MainWindow extends EventEmitter {
setLyricInfo(info) {
this.emit(MAIN_WINDOW_EVENT_NAME.setLyricInfo, info)
}
quit() {
this.emit(MAIN_WINDOW_EVENT_NAME.quit)
}
toggleMinimize() {
this.emit(MAIN_WINDOW_EVENT_NAME.toggle_minimize)
}
toggleHide() {
this.emit(MAIN_WINDOW_EVENT_NAME.toggle_hide)
}
readyToShow() {
this.emit(MAIN_WINDOW_EVENT_NAME.ready_to_show)
}
show() {
this.emit(MAIN_WINDOW_EVENT_NAME.show)
}
focus() {
this.emit(MAIN_WINDOW_EVENT_NAME.focus)
}
blur() {
this.emit(MAIN_WINDOW_EVENT_NAME.blur)
}
hide() {
this.emit(MAIN_WINDOW_EVENT_NAME.hide)
}
}
module.exports = MainWindow

14
src/main/events/Tray.js Normal file
View File

@@ -0,0 +1,14 @@
const { EventEmitter } = require('events')
const { tray: TRAY_EVENT_NAME } = require('./_name')
class Tray extends EventEmitter {
create() {
this.emit(TRAY_EVENT_NAME.create)
}
destroy() {
this.emit(TRAY_EVENT_NAME.destroy)
}
}
module.exports = Tray

View File

@@ -0,0 +1,15 @@
const { EventEmitter } = require('events')
const { winLyric: WIN_LYRIC_EVENT_NAME } = require('./_name')
// const { updateSetting } = require('../utils')
class WinLyric extends EventEmitter {
create() {
this.emit(WIN_LYRIC_EVENT_NAME.create)
}
close() {
this.emit(WIN_LYRIC_EVENT_NAME.close)
}
}
module.exports = WinLyric

38
src/main/events/_name.js Normal file
View File

@@ -0,0 +1,38 @@
exports.common = {
initConfig: 'initConfig',
configStatus: 'config',
saveMyList: 'saveMyList',
}
exports.mainWindow = {
name: 'mainWindow',
setLyricInfo: 'setLyricInfo',
destroy: 'destroy',
quit: 'quit',
toggle_minimize: 'toggle_minimize',
toggle_hide: 'toggle_hide',
ready_to_show: 'ready_to_show',
show: 'show',
hide: 'hide',
focus: 'focus',
blur: 'blur',
}
exports.tray = {
name: 'tray',
create: 'create',
destroy: 'destroy',
}
exports.winLyric = {
name: 'winLyric',
create: 'create',
close: 'close',
}
exports.hotKey = {
name: 'hotKey',
init: 'init',
config: 'config',
keyDown: 'keyDown',
}

View File

@@ -1,6 +1,21 @@
if (!global.lx_event) global.lx_event = {}
require('./request')
// require('./appName')
require('./progressBar')
require('./trafficLight')
require('./musicMeta')
const Common = require('./Common')
const MainWindow = require('./MainWindow')
const Tray = require('./Tray')
const WinLyric = require('./WinLyric')
const HotKey = require('./HotKey')
const { Event: TaskBar } = require('../modules/taskbar')
const { Event: UserApi } = require('../modules/userApi')
const { Event: Sync } = require('../modules/sync')
if (!global.lx_event.common) global.lx_event.common = new Common()
if (!global.lx_event.mainWindow) global.lx_event.mainWindow = new MainWindow()
if (!global.lx_event.tray) global.lx_event.tray = new Tray()
if (!global.lx_event.winLyric) global.lx_event.winLyric = new WinLyric()
if (!global.lx_event.hotKey) global.lx_event.hotKey = new HotKey()
if (!global.lx_event.taskbar) global.lx_event.taskbar = new TaskBar()
if (!global.lx_event.userApi) global.lx_event.userApi = new UserApi()
if (!global.lx_event.sync) global.lx_event.sync = new Sync()

View File

@@ -1,6 +0,0 @@
const { mainOn } = require('../../common/icp')
const { setMeta } = require('../utils/musicMeta')
mainOn('setMusicMeta', (event, { filePath, meta }) => {
setMeta(filePath, meta)
})

View File

@@ -1,10 +0,0 @@
const { mainOn } = require('../../common/icp')
mainOn('progress', (event, params) => {
// console.log(params)
global.mainWindow && global.mainWindow.setProgressBar(params.status, {
mode: params.mode || 'normal',
})
})

View File

@@ -1,11 +0,0 @@
const { mainOn } = require('../../common/icp')
const { dialog } = require('electron')
module.exports = win => {
mainOn('selectPath', (event, params) => {
let path = dialog.showOpenDialog(win, params.options)
if (path === undefined) return
event.sender.send(params.eventName, path)
})
}

View File

@@ -1,22 +0,0 @@
// const { app } = require('electron')
const { mainOn } = require('../../common/icp')
mainOn('min', event => {
if (global.mainWindow) {
global.mainWindow.minimize()
}
})
// mainOn('max', event => {
// if (global.mainWindow) {
// global.mainWindow.maximize()
// }
// })
mainOn('close', event => {
if (global.mainWindow) {
// global.mainWindowdow.destroy()
// console.log('close')
// app.quit()
global.mainWindow.close()
}
})

View File

@@ -1,130 +1,250 @@
const { app, BrowserWindow, Menu } = require('electron')
const { app, BrowserWindow, shell, nativeTheme } = require('electron')
const path = require('path')
const urlSchemeRxp = /^lxmusic:\/\//
// 单例应用程序
if (!app.requestSingleInstanceLock()) {
app.quit()
return
process.exit(0)
}
if (!global.modules) global.modules = {}
app.on('second-instance', (event, argv, cwd) => {
if (mainWindow) {
if (mainWindow.isMinimized()) mainWindow.restore()
mainWindow.focus()
for (const param of argv) {
if (urlSchemeRxp.test(param)) {
global.envParams.deeplink = param
break
}
}
if (global.modules.mainWindow) {
if (global.modules.mainWindow.isMinimized()) {
global.modules.mainWindow.restore()
}
if (global.modules.mainWindow.isVisible()) {
global.modules.mainWindow.focus()
} else {
global.modules.mainWindow.show()
}
} else {
app.quit()
}
})
// windows平台下如果应用目录下存在 portable 文件夹则将数据存在此文件下
if (process.platform === 'win32') {
const fs = require('fs')
const portablePath = path.join(path.dirname(app.getPath('exe')), '/portable')
if (fs.existsSync(portablePath)) {
app.setPath('appData', portablePath)
const appDataPath = path.join(portablePath, '/userData')
if (!fs.existsSync(appDataPath)) fs.mkdirSync(appDataPath)
app.setPath('userData', appDataPath)
}
}
const isDev = global.isDev = process.env.NODE_ENV !== 'production'
require('./env')
// console.log(global.envParams.cmdParams)
// Is disable hardware acceleration
if (global.envParams.cmdParams.dha) app.disableHardwareAcceleration()
if (global.envParams.cmdParams.dt == null && global.envParams.cmdParams.nt != null) global.envParams.cmdParams.dt = global.envParams.cmdParams.nt
if (global.envParams.cmdParams.dhmkh) app.commandLine.appendSwitch('disable-features', 'HardwareMediaKeyHandling')
// fix linux transparent fail. https://github.com/electron/electron/issues/25153#issuecomment-843688494
if (process.platform == 'linux') app.commandLine.appendSwitch('use-gl', 'desktop')
// https://github.com/electron/electron/issues/22691
app.commandLine.appendSwitch('wm-window-animations-disabled')
// proxy
if (global.envParams.cmdParams['proxy-server']) {
app.commandLine.appendSwitch('proxy-server', global.envParams.cmdParams['proxy-server'])
app.commandLine.appendSwitch('proxy-bypass-list', global.envParams.cmdParams['proxy-bypass-list'] ?? '<local>')
}
// if (global.envParams.cmdParams['proxy-pac-url']) app.commandLine.appendSwitch('proxy-pac-url', global.envParams.cmdParams['proxy-pac-url'])
// deep link
app.on('open-url', (event, url) => {
if (!urlSchemeRxp.test(url)) return
event.preventDefault()
global.envParams.deeplink = url
if (global.modules.mainWindow) {
if (global.modules.mainWindow.isMinimized()) {
global.modules.mainWindow.restore()
}
if (global.modules.mainWindow.isVisible()) {
global.modules.mainWindow.focus()
} else {
global.modules.mainWindow.show()
}
} else if (global.modules.mainWindow === null) {
init()
}
})
// if (isDev && process.platform === 'win32') {
// // Set the path of electron.exe and your app.
// // These two additional parameters are only available on windows.
// // console.log(process.execPath, process.argv)
// app.setAsDefaultProtocolClient('lxmusic', process.execPath, process.argv.slice(1))
// }
if (!isDev) app.setAsDefaultProtocolClient('lxmusic')
const { navigationUrlWhiteList, themes } = require('../common/config')
const { getWindowSizeInfo, initSetting, updateSetting } = require('./utils')
const { isMac, isLinux, initHotKey } = require('../common/utils')
// https://github.com/electron/electron/issues/18397
// 开发模式下为true时 多次引入native模块会导致渲染进程卡死
// https://github.com/electron/electron/issues/22791
// app.allowRendererProcessReuse = !isDev
app.on('web-contents-created', (event, contents) => {
contents.on('will-navigate', (event, navigationUrl) => {
if (isDev) return console.log('navigation to url:', navigationUrl)
if (!navigationUrlWhiteList.some(url => url.test(navigationUrl))) return event.preventDefault()
console.log('navigation to url:', navigationUrl)
})
contents.setWindowOpenHandler(({ url }) => {
if (!/^devtools/.test(url) && /^https?:\/\//.test(url)) {
shell.openExternal(url)
}
console.log(url)
return { action: 'deny' }
})
contents.on('will-attach-webview', (event, webPreferences, params) => {
// Strip away preload scripts if unused or verify their location is legitimate
delete webPreferences.preload
delete webPreferences.preloadURL
// Disable Node.js integration
webPreferences.nodeIntegration = false
// Verify URL being loaded
if (!navigationUrlWhiteList.some(url => url.test(params.src))) {
event.preventDefault()
}
})
// disable create dictionary
// https://github.com/lyswhut/lx-music-desktop/issues/773
contents.session.setSpellCheckerDictionaryDownloadURL('http://0.0.0.0')
})
require('../common/error')
require('./events')
require('./event')
require('./rendererEvents')
const winEvent = require('./rendererEvents/winEvent')
const autoUpdate = require('./utils/autoUpdate')
const { isLinux, isMac } = require('../common/utils')
const isDev = process.env.NODE_ENV !== 'production'
/**
* Set `__static` path to static files in production
* https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-static-assets.html
*/
let mainWindow
let winURL
let isFirstCheckedUpdate = true
if (isDev) {
global.__static = path.join(__dirname, '../static')
// eslint-disable-next-line no-undef
global.__static = __static
winURL = 'http://localhost:9080'
} else {
global.__static = path.join(__dirname, '/static')
winURL = `file://${__dirname}/index.html`
winURL = `file://${path.join(__dirname, 'index.html')}`
}
function createWindow() {
const windowSizeInfo = getWindowSizeInfo(global.appSetting)
/**
* Initial window options
*/
mainWindow = global.mainWindow = new BrowserWindow({
height: 590,
const options = {
height: windowSizeInfo.height,
useContentSize: true,
width: 920,
width: windowSizeInfo.width,
frame: false,
transparent: !isLinux,
transparent: !global.envParams.cmdParams.dt,
enableRemoteModule: false,
// icon: path.join(global.__static, isWin ? 'icons/256x256.ico' : 'icons/512x512.png'),
resizable: false,
maximizable: false,
fullscreenable: false,
fullscreenable: true,
show: false,
webPreferences: {
// contextIsolation: true,
contextIsolation: false,
webSecurity: !isDev,
nodeIntegration: true,
spellcheck: false, // 禁用拼写检查器
},
})
mainWindow.loadURL(winURL)
mainWindow.on('close', () => {
mainWindow.setProgressBar(-1)
})
mainWindow.on('closed', () => {
mainWindow = global.mainWindow = null
})
// mainWindow.webContents.openDevTools()
if (!isDev) {
autoUpdate(isFirstCheckedUpdate)
isFirstCheckedUpdate = false
}
if (global.appSetting.startInFullscreen) {
options.fullscreen = true
if (isLinux) options.resizable = true
}
global.modules.mainWindow = new BrowserWindow(options)
const shouldUseDarkColors = nativeTheme.shouldUseDarkColors
const themeId = global.appSetting.theme.id == 'auto'
? shouldUseDarkColors
? global.appSetting.theme.darkId
: global.appSetting.theme.lightId
: global.appSetting.theme.id
const themeClass = themes.find(t => t.id == themeId)?.className ?? themes[0].className
global.modules.mainWindow.loadURL(winURL + `?dt=${!!global.envParams.cmdParams.dt}&dark=${shouldUseDarkColors}&theme=${themeClass}`)
winEvent(global.modules.mainWindow)
if (global.envParams.cmdParams.odt) require('@main/utils').openDevTools(global.modules.mainWindow.webContents)
// global.modules.mainWindow.webContents.openDevTools()
if (!isDev) autoUpdate()
}
if (isMac) {
const template = [
{
label: app.getName(),
submenu: [
{ label: '关于洛雪音乐', role: 'about' },
{ type: 'separator' },
{ label: '隐藏', role: 'hide' },
{ label: '显示其他', role: 'hideothers' },
{ label: '显示全部', role: 'unhide' },
{ type: 'separator' },
{ label: '退出', accelerator: 'Command+Q', click: () => app.quit() },
],
},
{
label: '窗口',
role: 'window',
submenu: [
{ label: '最小化', role: 'minimize' },
{ label: '关闭', role: 'close' },
],
},
{
label: '编辑',
submenu: [
{ label: '撤销', accelerator: 'CmdOrCtrl+Z', role: 'undo' },
{ label: '恢复', accelerator: 'Shift+CmdOrCtrl+Z', role: 'redo' },
{ type: 'separator' },
{ label: '剪切', accelerator: 'CmdOrCtrl+X', role: 'cut' },
{ label: '复制', accelerator: 'CmdOrCtrl+C', role: 'copy' },
{ label: '粘贴', accelerator: 'CmdOrCtrl+V', role: 'paste' },
{ label: '选择全部', accelerator: 'CmdOrCtrl+A', role: 'selectAll' },
],
},
]
Menu.setApplicationMenu(Menu.buildFromTemplate(template))
} else {
Menu.setApplicationMenu(null)
global.appHotKey = {
enable: true,
config: {},
state: null,
}
app.on('ready', createWindow)
global.lx_core = {
setAppConfig(setting, name) {
updateSetting(setting)
global.lx_event.common.configStatus(name)
},
}
app.on('window-all-closed', () => {
if (!isMac) app.quit()
})
function init() {
console.log('init')
initSetting()
global.appHotKey.config = initHotKey()
global.lx_event.common.initSetting()
global.lx_event.hotKey.init()
createWindow()
}
// https://github.com/electron/electron/issues/16809
app.on('ready', isLinux ? () => setTimeout(init, 300) : init)
app.on('activate', () => {
if (mainWindow === null) {
createWindow()
if (global.modules.mainWindow) {
if (global.modules.mainWindow.isMinimized()) {
global.modules.mainWindow.restore()
} else if (global.modules.mainWindow.isVisible()) {
global.modules.mainWindow.focus()
} else {
global.modules.mainWindow.show()
}
} else if (global.modules.mainWindow === null) {
init()
}
})
app.on('window-all-closed', () => {
if (isMac) {
global.lx_event.tray.destroy()
} else {
app.quit()
}
})
require('./modules')

View File

@@ -0,0 +1,48 @@
const { app, Menu } = require('electron')
const { isMac } = require('../../common/utils')
if (isMac) {
const template = [
{
label: app.getName(),
submenu: [
{ label: '关于洛雪音乐', role: 'about' },
{ type: 'separator' },
{ label: '隐藏', role: 'hide' },
{ type: 'separator' },
{
label: '退出',
accelerator: 'Command+Q',
click() {
global.isQuitting = true
app.quit()
},
},
],
},
{
label: '窗口',
role: 'window',
submenu: [
{ label: '最小化', role: 'minimize', accelerator: 'Command+W' },
{ label: '关闭', role: 'close' },
],
},
{
label: '编辑',
submenu: [
{ label: '撤销', accelerator: 'Command+Z', role: 'undo' },
{ label: '恢复', accelerator: 'Shift+Command+Z', role: 'redo' },
{ type: 'separator' },
{ label: '剪切', accelerator: 'Command+X', role: 'cut' },
{ label: '复制', accelerator: 'Command+C', role: 'copy' },
{ label: '粘贴', accelerator: 'Command+V', role: 'paste' },
{ label: '选择全部', accelerator: 'Command+A', role: 'selectAll' },
],
},
]
Menu.setApplicationMenu(Menu.buildFromTemplate(template))
} else {
Menu.setApplicationMenu(null)
}

View File

@@ -0,0 +1,12 @@
const { app } = require('electron')
const { init, unRegisterHotkeyAll } = require('./utils')
const { hotKey: HOT_KEY_EVENT_NAME } = require('../../events/_name')
global.appHotKey.state = {}
app.on('will-quit', unRegisterHotkeyAll)
global.lx_event.hotKey.on(HOT_KEY_EVENT_NAME.init, init)
require('./rendererEvent')

View File

@@ -0,0 +1,28 @@
const {
mainHandle,
NAMES: {
hotKey: ipcHotKeyNames,
},
} = require('../../../common/ipc')
const { init, registerHotkey, unRegisterHotkey, unRegisterHotkeyAll } = require('./utils')
mainHandle(ipcHotKeyNames.set_config, async(event, { action, data, source }) => {
switch (action) {
case 'config':
global.lx_event.hotKey.saveConfig(data, source)
return true
case 'enable':
data ? init(true) : unRegisterHotkeyAll()
return true
case 'register':
return registerHotkey(data)
case 'unregister':
return unRegisterHotkey(data)
}
})
mainHandle(ipcHotKeyNames.status, async() => global.appHotKey.state)
mainHandle(ipcHotKeyNames.enable, async(event, flag) => {
flag ? init() : unRegisterHotkeyAll()
})

View File

@@ -0,0 +1,67 @@
const { globalShortcut } = require('electron')
const { log } = require('../../../common/utils')
const handleKeyDown = key => {
if (!global.appHotKey.enable) return
global.lx_event.hotKey.keyDown({ type: 'global', key })
}
const transformedKeyRxp = /(^|\+)[a-z]/g
const transformedKey = key => {
if (key.includes('arrow')) key = key.replace(/arrow/g, '')
return key.replace('mod', 'CommandOrControl').replace(transformedKeyRxp, l => l.toUpperCase())
}
exports.registerHotkey = ({ key, info }) => {
if (global.appHotKey.state[key] && global.appHotKey.state[key].status) return true
let transKey = transformedKey(key)
// console.log('Register key:', transKey)
if (!global.appHotKey.state[key]) {
global.appHotKey.state[key] = {
status: false,
info: null,
}
}
global.appHotKey.state[key].info = info
let status = global.appHotKey.state[key].status = globalShortcut.isRegistered(transKey)
? false
: globalShortcut.register(transKey, () => {
handleKeyDown(key)
})
return status
}
exports.unRegisterHotkey = key => {
let transKey = transformedKey(key)
// console.log('Unregister key:', transKey)
globalShortcut.unregister(transKey)
delete global.appHotKey.state[key]
}
exports.unRegisterHotkeyAll = () => {
global.appHotKey.state = {}
globalShortcut.unregisterAll()
}
exports.handleKeyDown = handleKeyDown
exports.transformedKey = transformedKey
const handleRegisterHotkey = data => {
let ret = exports.registerHotkey(data)
if (!ret) log.info('Register hot key failed:', data.key)
}
exports.init = (isForce = false) => {
exports.unRegisterHotkeyAll()
if (!isForce && !global.appHotKey.config.global.enable) return
global.appHotKey.state = {}
// console.log(global.appHotKey.config.global.keys)
for (const key of Object.keys(global.appHotKey.config.global.keys)) {
try {
handleRegisterHotkey({ key, info: global.appHotKey.config.global.keys[key] })
} catch (err) {
log.info(err)
}
}
}

View File

@@ -0,0 +1,4 @@
require('./appMenu')
require('./winLyric')
require('./tray')
require('./hotKey')

View File

@@ -0,0 +1,23 @@
const { EventEmitter } = require('events')
const SYNC_EVENT_NAME = require('./name')
class Sync extends EventEmitter {
status(status) {
this.emit(SYNC_EVENT_NAME.status, status)
}
sync_list(data) {
this.emit(SYNC_EVENT_NAME.sync_list, data)
}
sync_handle_list(data) {
this.emit(SYNC_EVENT_NAME.sync_handle_list, data)
}
action_list(data) {
this.emit(SYNC_EVENT_NAME.sync_action_list, data)
}
}
module.exports = Sync

View File

@@ -0,0 +1,6 @@
module.exports = {
sync_action_list: 'sync_action_list',
sync_list: 'sync_list',
sync_handle_list: 'sync_handle_list',
status: 'status',
}

View File

@@ -0,0 +1,15 @@
const Event = require('./event/event')
const eventNames = require('./event/name')
const modules = require('./modules')
const { startServer, stopServer, getStatus, generateCode } = require('./server/server')
module.exports = {
startServer,
stopServer,
getStatus,
generateCode,
Event,
eventNames,
modules,
}

View File

@@ -0,0 +1 @@
exports.list = require('./list')

View File

@@ -0,0 +1,41 @@
const { encryptMsg, decryptMsg } = require('../server/utils')
let io
const handleListAction = ({ action, data }) => {
// console.log(action, data)
global.lx_event.sync.action_list({ action, data })
}
// const addMusic = (orderId, callback) => {
// // ...
// }
const broadcast = async(action, data, excludeIds = []) => {
if (!io) return
const sockets = await io.fetchSockets()
for (const socket of sockets) {
if (excludeIds.includes(socket.data.keyInfo.clientId)) continue
socket.emit(action, encryptMsg(socket.data.keyInfo, data))
}
}
exports.sendListAction = (action, data) => {
// io.sockets
return broadcast('list:action', JSON.stringify({ action, data }))
}
exports.registerListHandler = (_io, socket) => {
io = _io
socket.on('list:action', msg => {
// console.log(msg)
msg = decryptMsg(socket.data.keyInfo, msg)
if (!msg) return
handleListAction(JSON.parse(msg))
broadcast('list:action', msg, [socket.data.keyInfo.clientId])
// socket.broadcast.emit('list:action', { action: 'list_remove', data: { id: 'default', index: 0 } })
})
// socket.on('list:add', addMusic)
}
exports.unregisterListHandler = () => {
io = null
}

View File

@@ -0,0 +1,69 @@
const { aesEncrypt, aesDecrypt, createClientKeyInfo, getClientKeyInfo, setClientKeyInfo } = require('./utils')
const authMsg = 'lx-music auth::'
const helloMsg = 'Hello~::^-^::'
exports.authCode = async(req, res, authCode) => {
let code = 401
let msg = 'Forbidden'
// console.log(req.headers)
if (req.headers.m) {
label:
if (req.headers.i) {
const keyInfo = getClientKeyInfo(req.headers.i)
if (!keyInfo) break label
let text
try {
text = aesDecrypt(req.headers.m, keyInfo.key, keyInfo.iv)
} catch (err) {
break label
}
console.log(text)
if (text.startsWith(authMsg)) {
code = 200
const deviceName = text.replace(authMsg, '') || 'Unknown'
if (deviceName != keyInfo.deviceName) {
keyInfo.deviceName = deviceName
setClientKeyInfo(keyInfo)
}
msg = aesEncrypt(helloMsg, keyInfo.key, keyInfo.iv)
}
} else {
let key = ''.padStart(16, Buffer.from(authCode).toString('hex'))
const iv = Buffer.from(key.split('').reverse().join('')).toString('base64')
key = Buffer.from(key).toString('base64')
// console.log(authCode, key, iv)
let text
try {
text = aesDecrypt(req.headers.m, key, iv)
} catch (err) {
break label
}
console.log(text)
if (text.startsWith(authMsg)) {
code = 200
const deviceName = text.replace(authMsg, '') || 'Unknown'
msg = aesEncrypt(JSON.stringify(createClientKeyInfo(deviceName)), key, iv)
}
}
}
res.writeHead(code)
res.end(msg)
}
exports.authConnect = async req => {
const { i, t } = req._query
label:
if (i && t) {
const keyInfo = getClientKeyInfo(i)
if (!keyInfo) break label
let text
try {
text = aesDecrypt(t, keyInfo.key, keyInfo.iv)
} catch (err) {
break label
}
if (text == 'lx-music connect') return
}
throw new Error('failed')
}

View File

@@ -0,0 +1,7 @@
const { startServer, stopServer, getStatus } = require('./server')
module.exports = {
startServer,
stopServer,
getStatus,
}

View File

@@ -0,0 +1,178 @@
const http = require('http')
const sio = require('socket.io')
const { createHttpTerminator } = require('http-terminator')
const modules = require('../modules')
const { authCode, authConnect } = require('./auth')
const { getAddress, getServerId, generateCode, getClientKeyInfo, setClientKeyInfo } = require('./utils')
const { syncList, removeSnapshot } = require('./syncList')
const { log } = require('@common/utils')
let status = {
status: false,
message: '',
address: [],
code: '',
devices: [],
}
const handleConnection = (io, socket) => {
console.log('connection')
// console.log(socket.handshake.query)
for (const module of Object.values(modules)) {
module.registerListHandler(io, socket)
}
}
const authConnection = (req, callback) => {
// console.log(req.headers)
// // console.log(req.auth)
// console.log(req._query.authCode)
authConnect(req).then(() => {
callback(null, true)
}).catch(err => {
callback(err, false)
})
}
let httpTerminator = null
let io = null
const handleStartServer = (port = 9527) => new Promise((resolve, reject) => {
const httpServer = http.createServer((req, res) => {
// console.log(req.url)
let code
let msg
switch (req.url) {
case '/hello':
code = 200
msg = 'Hello~::^-^::'
break
case '/id':
code = 200
msg = 'OjppZDo6' + getServerId()
break
case '/ah':
authCode(req, res, status.code)
break
default:
code = 401
msg = 'Forbidden'
break
}
if (!code) return
res.writeHead(code)
res.end(msg)
})
httpTerminator = createHttpTerminator({
server: httpServer,
})
io = sio(httpServer, {
path: '/sync',
serveClient: false,
connectTimeout: 10000,
pingTimeout: 30000,
maxHttpBufferSize: 1e9, // 1G
allowRequest: authConnection,
transports: ['websocket'],
})
io.on('connection', async socket => {
socket.on('disconnect', reason => {
console.log('disconnect', reason)
status.devices.splice(status.devices.findIndex(k => k.clientId == keyInfo.clientId), 1)
global.lx_event.sync.status(status)
})
const keyInfo = getClientKeyInfo(socket.handshake.query.i)
keyInfo.connectionTime = Date.now()
setClientKeyInfo(keyInfo)
// socket.lx_keyInfo = keyInfo
socket.data.keyInfo = keyInfo
try {
await syncList(io, socket)
} catch (err) {
// console.log(err)
log.warn(err)
return
}
status.devices.push(keyInfo)
handleConnection(io, socket, keyInfo)
global.lx_event.sync.status(status)
})
httpServer.on('error', error => {
console.log(error)
reject(error)
})
httpServer.on('listening', () => {
const addr = httpServer.address()
const bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port
console.info(`Listening on ${bind}`)
resolve()
})
httpServer.listen(port)
})
const handleStopServer = async() => {
if (!httpTerminator) return
await io.close()
await httpTerminator.terminate().catch(() => {})
io = null
httpTerminator = null
}
exports.stopServer = async() => {
if (!status.status) {
status.status = false
status.message = ''
status.address = []
status.code = ''
global.lx_event.sync.status(status)
return
}
console.log('stoping sync server...')
return handleStopServer().then(() => {
console.log('sync server stoped')
status.status = false
status.message = ''
status.address = []
status.code = ''
}).catch(err => {
console.log(err)
status.message = err.message
}).finally(() => {
global.lx_event.sync.status(status)
})
}
exports.startServer = async port => {
if (status.status) await handleStopServer()
console.log('starting sync server...')
return handleStartServer(port).then(() => {
console.log('sync server started')
status.status = true
status.message = ''
status.address = getAddress()
status.code = generateCode()
}).catch(err => {
console.log(err)
status.status = false
status.message = err.message
status.address = []
status.code = ''
}).finally(() => {
global.lx_event.sync.status(status)
})
}
exports.getStatus = () => status
exports.generateCode = async() => {
status.code = generateCode()
global.lx_event.sync.status(status)
return status.code
}
exports.removeSnapshot = removeSnapshot

View File

@@ -0,0 +1,438 @@
const fs = require('fs')
const fsPromises = fs.promises
const { encryptMsg, decryptMsg, getSnapshotFilePath } = require('./utils')
const SYNC_EVENT_NAMES = require('../event/name')
const { common: COMMON_EVENT_NAME } = require('@main/events/_name')
const { throttle } = require('@common/utils')
let io
let syncingId = null
const wait = (time = 1000) => new Promise((resolve, reject) => setTimeout(resolve, time))
const patchListData = listData => {
return Object.assign({}, {
defaultList: {
id: 'default',
name: '试听列表',
list: [],
},
loveList: {
id: 'love',
name: '我的收藏',
list: [],
},
userList: [],
}, listData)
}
const getRemoteListData = socket => new Promise((resolve, reject) => {
console.log('getRemoteListData')
const handleError = reason => {
reject(new Error(reason))
}
const handleSuccess = enData => {
socket.removeListener('disconnect', handleError)
socket.removeListener('list:sync', handleSuccess)
console.log('getRemoteListData', 'handleSuccess')
const data = JSON.parse(decryptMsg(socket.data.keyInfo, enData))
if (!data) return reject(new Error('Get remote list data failed'))
if (data.action != 'getData') return
resolve(patchListData(data.data))
}
socket.on('disconnect', handleError)
socket.on('list:sync', handleSuccess)
socket.emit('list:sync', encryptMsg(socket.data.keyInfo, JSON.stringify({ action: 'getData', data: 'all' })))
})
const getLocalListData = () => new Promise((resolve, reject) => {
const handleSuccess = ({ action, data }) => {
if (action !== 'getData') return
global.lx_event.sync.off(SYNC_EVENT_NAMES.sync_handle_list, handleSuccess)
resolve(patchListData(data))
}
global.lx_event.sync.on(SYNC_EVENT_NAMES.sync_handle_list, handleSuccess)
global.lx_event.sync.sync_list({
action: 'getData',
})
})
const getSyncMode = keyInfo => new Promise((resolve, reject) => {
const handleSuccess = ({ action, data }) => {
if (action !== 'selectMode') return
global.lx_event.sync.off(SYNC_EVENT_NAMES.sync_handle_list, handleSuccess)
resolve(data)
}
global.lx_event.sync.on(SYNC_EVENT_NAMES.sync_handle_list, handleSuccess)
global.lx_event.sync.sync_list({
action: 'selectMode',
data: keyInfo,
})
})
const finishedSync = socket => {
return socket.emit('list:sync', encryptMsg(socket.data.keyInfo, JSON.stringify({
action: 'finished',
})))
}
const setLocalList = listData => {
global.lx_event.sync.sync_list({
action: 'setData',
data: listData,
})
}
const setRemotelList = async(socket, listData) => {
if (!io) return
const sockets = await io.fetchSockets()
for (const socket of sockets) {
// if (excludeIds.includes(socket.data.keyInfo.clientId)) continue
socket.emit('list:sync', encryptMsg(socket.data.keyInfo, JSON.stringify({ action: 'setData', data: listData })))
}
}
let writeFilePromises = {}
const updateSnapshot = (path, data) => {
console.log('updateSnapshot', path)
let writeFilePromise = writeFilePromises[path] || Promise.resolve()
return writeFilePromise.then(() => {
writeFilePromise = writeFilePromises[path] = fsPromises.writeFile(path, data)
return writeFilePromise
})
}
const createUserListDataObj = listData => {
const userListDataObj = {}
for (const list of listData.userList) userListDataObj[list.id] = list
return userListDataObj
}
const handleMergeList = (sourceList, targetList, addMusicLocationType) => {
let newList
switch (addMusicLocationType) {
case 'top':
newList = [...targetList.list, ...sourceList.list]
break
case 'bottom':
default:
newList = [...sourceList.list, ...targetList.list]
break
}
const map = {}
const ids = []
switch (addMusicLocationType) {
case 'top':
newList = [...targetList.list, ...sourceList.list]
for (let i = newList.length - 1; i > -1; i--) {
const item = newList[i]
if (map[item.songmid]) continue
ids.unshift(item.songmid)
map[item.songmid] = item
}
break
case 'bottom':
default:
newList = [...sourceList.list, ...targetList.list]
for (const item of newList) {
if (map[item.songmid]) continue
ids.push(item.songmid)
map[item.songmid] = item
}
break
}
return {
...sourceList,
list: ids.map(id => map[id]),
}
}
const mergeList = (sourceListData, targetListData) => {
const addMusicLocationType = global.appSetting.list.addMusicLocationType
const newListData = {}
newListData.defaultList = handleMergeList(sourceListData.defaultList, targetListData.defaultList, addMusicLocationType)
newListData.loveList = handleMergeList(sourceListData.loveList, targetListData.loveList, addMusicLocationType)
const userListDataObj = createUserListDataObj(sourceListData)
newListData.userList = [...sourceListData.userList]
targetListData.userList.forEach((list, index) => {
const targetUpdateTime = list?.locationUpdateTime ?? 0
const sourceList = userListDataObj[list.id]
if (sourceList) {
sourceList.list = handleMergeList(sourceList, list, addMusicLocationType).list
const sourceUpdateTime = sourceList?.locationUpdateTime ?? 0
if (targetUpdateTime >= sourceUpdateTime) return
// 调整位置
const [newList] = newListData.userList.splice(newListData.userList.findIndex(l => l.id == list.id), 1)
newList.locationUpdateTime = targetUpdateTime
newListData.userList.splice(index, 0, newList)
} else {
if (targetUpdateTime) {
newListData.userList.splice(index, 0, list)
} else {
newListData.userList.push(list)
}
}
})
return newListData
}
const overwriteList = (sourceListData, targetListData) => {
const newListData = {}
newListData.defaultList = sourceListData.defaultList
newListData.loveList = sourceListData.loveList
const userListDataObj = createUserListDataObj(sourceListData)
newListData.userList = [...sourceListData.userList]
targetListData.userList.forEach((list, index) => {
if (userListDataObj[list.id]) return
if (list?.locationUpdateTime) {
newListData.userList.splice(index, 0, list)
} else {
newListData.userList.push(list)
}
})
return newListData
}
const handleMergeListData = async socket => {
let isSelectingMode = false
const handleDisconnect = () => {
if (!isSelectingMode) return
global.lx_event.sync.sync_list({
action: 'closeSelectMode',
})
}
socket.on('disconnect', handleDisconnect)
isSelectingMode = true
const mode = await getSyncMode(socket.data.keyInfo)
isSelectingMode = false
const [remoteListData, localListData] = await Promise.all([getRemoteListData(socket), getLocalListData()])
console.log('handleMergeListData', 'remoteListData, localListData')
let listData
switch (mode) {
case 'merge_local_remote':
listData = mergeList(localListData, remoteListData)
break
case 'merge_remote_local':
listData = mergeList(remoteListData, localListData)
break
case 'overwrite_local_remote':
listData = overwriteList(localListData, remoteListData)
break
case 'overwrite_remote_local':
listData = overwriteList(remoteListData, localListData)
break
case 'overwrite_local_remote_full':
listData = localListData
break
case 'overwrite_remote_local_full':
listData = remoteListData
break
case 'none': return
case 'cancel':
socket.disconnect(true)
throw new Error('cancel')
}
return listData
}
const handleSyncList = async socket => {
const [remoteListData, localListData] = await Promise.all([getRemoteListData(socket), getLocalListData()])
console.log('handleSyncList', 'remoteListData, localListData')
const listData = {}
if (localListData.defaultList.list.length || localListData.loveList.list.length || localListData.userList.length) {
if (remoteListData.defaultList.list.length || remoteListData.loveList.list.length || remoteListData.userList.length) {
const mergedList = await handleMergeListData(socket)
console.log('handleMergeListData', 'mergedList')
console.log(mergedList)
if (!mergedList) return
listData.defaultList = mergedList.defaultList
listData.loveList = mergedList.loveList
listData.userList = mergedList.userList
setLocalList(mergedList)
setRemotelList(socket, mergedList)
} else {
setRemotelList(socket, localListData)
listData.defaultList = localListData.defaultList
listData.loveList = localListData.loveList
listData.userList = localListData.userList
}
} else {
if (remoteListData.defaultList.list.length || remoteListData.loveList.list.length || remoteListData.userList.length) {
setLocalList(remoteListData)
listData.defaultList = remoteListData.defaultList
listData.loveList = remoteListData.loveList
listData.userList = remoteListData.userList
} else {
listData.defaultList = localListData.defaultList
listData.loveList = localListData.loveList
listData.userList = localListData.userList
}
}
return updateSnapshot(socket.data.snapshotFilePath, JSON.stringify({
defaultList: listData.defaultList,
loveList: listData.loveList,
userList: listData.userList,
})).then(() => {
socket.data.isCreatedSnapshot = true
return listData
})
}
const mergeListDataFromSnapshot = (sourceList, targetList, snapshotList, addMusicLocationType) => {
const removedListIds = new Set()
const sourceListItemIds = new Set()
const targetListItemIds = new Set()
for (const m of sourceList.list) sourceListItemIds.add(m.songmid)
for (const m of targetList.list) targetListItemIds.add(m.songmid)
if (snapshotList) {
for (const m of snapshotList.list) {
if (!sourceListItemIds.has(m.songmid) || !targetListItemIds.has(m.songmid)) removedListIds.add(m.songmid)
}
}
let newList
const map = {}
const ids = []
switch (addMusicLocationType) {
case 'top':
newList = [...targetList.list, ...sourceList.list]
for (let i = newList.length - 1; i > -1; i--) {
const item = newList[i]
if (map[item.songmid] || removedListIds.has(item.songmid)) continue
ids.unshift(item.songmid)
map[item.songmid] = item
}
break
case 'bottom':
default:
newList = [...sourceList.list, ...targetList.list]
for (const item of newList) {
if (map[item.songmid] || removedListIds.has(item.songmid)) continue
ids.push(item.songmid)
map[item.songmid] = item
}
break
}
return {
...sourceList,
list: ids.map(id => map[id]),
}
}
const handleMergeListDataFromSnapshot = async(socket, snapshot) => {
const addMusicLocationType = global.appSetting.list.addMusicLocationType
const [remoteListData, localListData] = await Promise.all([getRemoteListData(socket), getLocalListData()])
const newListData = {}
newListData.defaultList = mergeListDataFromSnapshot(localListData.defaultList, remoteListData.defaultList, snapshot.defaultList, addMusicLocationType)
newListData.loveList = mergeListDataFromSnapshot(localListData.loveList, remoteListData.loveList, snapshot.loveList, addMusicLocationType)
const localUserListData = createUserListDataObj(localListData)
const remoteUserListData = createUserListDataObj(remoteListData)
const snapshotUserListData = createUserListDataObj(snapshot)
const removedListIds = new Set()
const localUserListIds = new Set()
const remoteUserListIds = new Set()
for (const l of localListData.userList) localUserListIds.add(l.id)
for (const l of remoteListData.userList) remoteUserListIds.add(l.id)
for (const l of snapshot.userList) {
if (!localUserListIds.has(l.id) || !remoteUserListIds.has(l.id)) removedListIds.add(l.id)
}
let newUserList = []
for (const list of localListData.userList) {
if (removedListIds.has(list.id)) continue
const remoteList = remoteUserListData[list.id]
let newList
if (remoteList) {
newList = mergeListDataFromSnapshot(list, remoteList, snapshotUserListData[list.id], addMusicLocationType)
} else {
newList = { ...list }
}
newUserList.push(newList)
}
remoteListData.userList.forEach((list, index) => {
if (removedListIds.has(list.id)) return
const remoteUpdateTime = list?.locationUpdateTime ?? 0
if (localUserListData[list.id]) {
const localUpdateTime = localUserListData[list.id]?.locationUpdateTime ?? 0
if (localUpdateTime >= remoteUpdateTime) return
// 调整位置
const [newList] = newUserList.splice(newUserList.findIndex(l => l.id == list.id), 1)
newList.locationUpdateTime = localUpdateTime
newUserList.splice(index, 0, newList)
} else {
if (remoteUpdateTime) {
newUserList.splice(index, 0, { ...list })
} else {
newUserList.push({ ...list })
}
}
})
newListData.userList = newUserList
setLocalList(newListData)
setRemotelList(socket, newListData)
return updateSnapshot(socket.data.snapshotFilePath, JSON.stringify({
defaultList: newListData.defaultList,
loveList: newListData.loveList,
userList: newListData.userList,
})).then(() => {
socket.data.isCreatedSnapshot = true
return newListData
})
}
const registerUpdateSnapshotTask = (socket, snapshot) => {
if (!socket.data.isCreatedSnapshot) return
const handleUpdateSnapshot = throttle(({ defaultList, loveList, userList }) => {
if (defaultList != null) snapshot.defaultList = defaultList
if (loveList != null) snapshot.loveList = loveList
if (userList != null) snapshot.userList = userList
updateSnapshot(socket.data.snapshotFilePath, JSON.stringify(snapshot))
}, 2000)
global.lx_event.common.on(COMMON_EVENT_NAME.saveMyList, handleUpdateSnapshot)
socket.on('disconnect', () => {
global.lx_event.common.off(COMMON_EVENT_NAME.saveMyList, handleUpdateSnapshot)
})
}
const syncList = async socket => {
socket.data.snapshotFilePath = getSnapshotFilePath(socket.data.keyInfo)
let fileData
let isSyncRequired = false
try {
fileData = await fsPromises.readFile(socket.data.snapshotFilePath)
fileData = JSON.parse(fileData)
} catch (err) {
if (err.code !== 'ENOENT') throw err
isSyncRequired = true
}
console.log('isSyncRequired', isSyncRequired)
if (isSyncRequired) return handleSyncList(socket)
return handleMergeListDataFromSnapshot(socket, patchListData(fileData))
}
const checkSyncQueue = async() => {
if (!syncingId) return
await wait()
return checkSyncQueue()
}
exports.syncList = async(_io, socket) => {
io = _io
await checkSyncQueue()
syncingId = socket.data.keyInfo.clientId
return syncList(socket).then(newListData => {
registerUpdateSnapshotTask(socket, { ...newListData })
return finishedSync(socket)
}).finally(() => {
syncingId = null
})
}
exports.removeSnapshot = keyInfo => {
const filePath = getSnapshotFilePath(keyInfo)
return fsPromises.unlink(filePath)
}

Some files were not shown because too many files have changed in this diff Show More