Compare commits

...

420 commits

Author SHA1 Message Date
71817baad0 去除听歌打卡功能 2025-06-17 09:13:43 +08:00
f6735c9c26
Update README.md
Some checks failed
Release / release (macos-latest) (push) Has been cancelled
Release / release (ubuntu-22.04) (push) Has been cancelled
Release / release (windows-latest) (push) Has been cancelled
更换demo的url
2025-06-15 22:39:46 +08:00
708a1a8eb8 去除签到功能、邮箱和登录入口 2025-06-14 12:36:22 +08:00
runnableAir
70ab357799
fix: 随机模式下当前播放歌曲于列表中的位置出现错误和不同步的情况 (#2378)
* fix(Player.js): 随机模式下列表初始化时当前歌曲的下标异常

异常情况:假设歌曲A其在歌单中的位置为10,随机模式下双击该歌曲后,this.current != 10
原因:随机模式下,通过 indexOf 计算 current 时,调用的数组与真实的列表数组不一致

* fix(Player.js): 随机模式切换时未同步当前歌曲下标

* fix: 随机播放顺序与实际列表不一致

使用 filter 不保证返回的数组的元素顺序与传入的id 顺序对应
2025-05-30 19:59:52 +08:00
李洋
c7e69158d2
Update package.json (#2347)
将版本号从0.4.8改成了0.4.9(有点强迫症)
2025-03-03 19:08:59 +08:00
Yi-Jyun Pan
022009b140
chore: upgrade dependencies 2024-11-01 15:01:39 +08:00
Yi-Jyun Pan
6849632abe
chore: add AppKit framework for macOS 2024-11-01 15:00:45 +08:00
Yi-Jyun Pan
c929beaf6c
Merge branch 'feat-realip' 2024-11-01 14:55:35 +08:00
Yi-Jyun Pan
dfb09b3ccd
chore: add devenv configuration 2024-11-01 14:55:06 +08:00
CuSO4Deposit
9809a758b4
style: Reformat with Prettier (#2296) 2024-11-01 14:20:55 +08:00
Frz
c9739b2d0e
feat: use cover image for Discord RPC (#2294) 2024-11-01 14:20:30 +08:00
bestlaw66
25e274a4f8
docs: 宝塔面板部署教程 2024-11-01 14:19:23 +08:00
pan93412
fc1c8d8512
Merge pull request #2292 from Younglina/master
添加复制歌词功能
2024-11-01 14:18:45 +08:00
StarsEnd
e27879aa94 update: NeteaseCloudMusicApi (iPhone OS fix) 2024-10-16 00:16:23 +08:00
StarsEnd
d219e48541 fix: real-ip config disabled css style 2024-10-16 00:14:38 +08:00
StarsEnd33A2D17
107f5765b0 Update to the latest NeteaseCloudMusicApi 2024-10-08 20:29:05 +08:00
StarsEnd33A2D17
adafffd86b feat: add RealIP setting 2024-09-30 13:35:22 +08:00
Younglina
9d807d1d63 feat: 复制歌词 2024-08-27 13:21:01 +08:00
Younglina
481ba6bce3
fix: 相似歌手接口需要登录;未登录获取艺人热门歌曲没有图片 (#2286) 2024-08-13 18:20:52 +08:00
StarsEnd
df82c7cd22
feat(ui): add fullscreen button (#2276)
* feat(ui): add fullscreen button

* fix: fullscreen图标修改,添加exit icon
2024-08-13 14:28:05 +08:00
Younglina
bd5af9c721
fix: 默认值错误导致加载空节点 (#2280) 2024-08-13 14:26:02 +08:00
5unV
7cb063d511
fix: 纠正脏标的判断 (#2268) 2024-08-07 22:37:29 +08:00
Felix_SANA
904e61bee6
fix: 阻止搜索引擎爬虫爬取网站的内容 (#2239) 2024-08-07 22:36:52 +08:00
Younglina
24477694f8
fix: 手机号placeholder显示问题 (#2197) 2024-03-18 15:16:48 +08:00
pan93412
87ef48b826
Merge pull request #2193 from rainbowflesh/master
fix github action missing env
2024-03-05 06:51:01 -06:00
是虹川肉
da8afc12cf
Update request.js 2024-03-05 19:00:27 +08:00
是虹川肉
84613dcf8a
Update build.yaml 2024-03-05 18:45:29 +08:00
pan93412
dd8aa175d1
chore: bump to 0.4.8 2024-03-05 00:16:14 +08:00
pan93412
e3caa24ca4
Merge pull request #2185 from undefined-ux/master
fix typo
2024-03-04 10:15:14 -06:00
pan93412
ae352f27e1
Merge pull request #2187 from DaiQiangReal/master
Fix: Fix build error and  /tmp/anonymous_token not exist.
2024-03-04 10:15:06 -06:00
代强
552a1d4b44 chore: remove useless space 2024-03-04 19:24:19 +08:00
代强
b0ed85689b chore: remove useless space 2024-03-04 19:24:10 +08:00
代强
a18e093d4a fix: fix build && adapte for bugs in NeteasyCloudMusicAPI 2024-03-04 19:22:47 +08:00
undefined
79a7c6d991
fix typo 2024-03-02 13:08:49 +08:00
pan93412
1a2c3e2843
Merge pull request #2178 from thedavidweng/master
Upstream Sync
2024-03-01 00:24:57 -06:00
pan93412
741fdc973c
Merge pull request #2127 from runnableAir/fix_player_enable
Fix: 右键播放歌曲无法激活播放栏
2024-03-01 00:13:14 -06:00
pan93412
1400636201
Merge pull request #2129 from jsonleex/patch
fix: play icon not appear in Safari
2024-03-01 00:12:22 -06:00
GH Action - Upstream Sync
6e737b50ee Merge branch 'master' of https://github.com/qier222/YesPlayMusic 2024-03-01 06:12:01 +00:00
pan93412
c409e3b6ed
Merge pull request #2167 from colawithsauce/master
[Feature] support UnblockNeteaseMusic with docker-compose deploy.
2024-03-01 00:11:16 -06:00
pan93412
e738d1e46d
Merge pull request #2176 from krishukr/master
fix(components): 修正描述小字内艺人链接
2024-03-01 00:10:25 -06:00
Davy
380c55a653
Create sync.yml 2024-02-05 17:05:06 -08:00
Kris Hu
9241b3a26a
same thing on MvRow 2024-01-31 12:33:12 +00:00
Kris Hu
3093b6f386
修正专辑下描述内艺人链接 2024-01-31 12:25:38 +00:00
colawithsauce
42366f4a32 remove unneeded empty line. 2023-12-09 01:01:04 +08:00
colawithsauce
6d6fd9a88c Make docker works 2023-12-09 00:55:11 +08:00
colawithsauce
dc1e0aaf90 Make docker works 2023-12-09 00:28:00 +08:00
colawithsauce
a5cb1f729d Remove unneeded env setting 2023-12-08 18:54:23 +08:00
colawithsauce
e997cd9907 Support unblock via docker. 2023-12-08 18:46:10 +08:00
leex
c5c7ccc89e
fix: play icon not appear in Safari 2023-09-04 22:49:21 +08:00
runnableAir
61d0b5953f refactor(Player.js): 确保在播放时播放器处于enabled状态 2023-08-31 06:16:05 +08:00
runnableAir
a5bf5c7dfd fix(Player.js): 右键播放不显示播放器(#1965) 2023-08-31 06:16:04 +08:00
pan93412
fd40a29180
Merge pull request #1818 from Revincx/revincx-pr 2023-08-26 11:17:42 +08:00
Revincx
486b04b70b
feat(player): sync playing progress to mpris service on linux
Co-authored-by: alex3236 <45303195+alex3236@users.noreply.github.com>
2023-08-26 10:31:43 +08:00
Revincx
6ad756b215
fix(ui): add max-width attr for settings selector 2023-08-26 10:31:43 +08:00
Revincx
ed1daab1f6
feat: use osdlyrics dbus interface to send lyric contents 2023-08-26 10:31:23 +08:00
runnableAir
f2f4e2ce58
fix(player): 插队曲目切换后下一首曲目丢失 (#2118) 2023-08-26 10:15:33 +08:00
Lvc Revincx
845bc8a921
Merge branch 'qier222:master' into revincx-pr 2023-08-25 23:28:35 +08:00
拆家大主教
f2efc4e682
feat(lyrics): Add pronunciation lyric mode (#2091)
* feat: Add pronunciation lyric mode

* fix(lyrics): Fixed issue where lyric-mode-switch displays when the translation setting is off
2023-08-07 23:32:28 +08:00
poly000
f4d3d67132
feat(mpris): Add xesam:url field (#2095)
chore: do not use fuo scheme, only netease music id is preserved

fix: lint prettier error
2023-08-07 23:31:38 +08:00
poly000
e14e6d73c6
ci: Use Ubuntu 22.04 for Packaging (#2107) 2023-08-07 23:30:37 +08:00
Siykt
4ec550dc46
fix(login): clear last interval when calling checkQrCodeLogin (#2094)
Fixed #2093
2023-07-24 13:01:49 +08:00
Anmizi
dd6d4bf1c6
feat(settings): Internationalize some strings (#2016) 2023-07-03 12:45:08 +08:00
guaqiu
a6e433bdc5
chore(deps): Add prettier to devDependencies (#2071) 2023-06-18 13:47:43 +08:00
Arthals
59898c7883
fix(navbar): Fixed the issue of overlapping with the control bar (#2073) 2023-06-18 13:47:20 +08:00
Kris Hu
1b7e33c222
fix: 艺人页面专辑区不显示精选集 (#2046) 2023-05-02 00:24:08 +08:00
Lvc Revincx
221ca63d3d
fix(player): Skip track when audio source not supported (#2033) 2023-04-15 10:26:38 +08:00
洩氏诹诹子
b7f7ac8d31
fix(player): 修复歌曲时长过长时的进度显示问题 (#1936)
原先进度条遇到时长超过 1hr 的歌曲,
不会呈现小时数的部分。这个 commit
将歌曲时长小时数加到分钟数中。
2023-04-08 23:16:01 +08:00
Holger
65f5df8a60
fix(request): cross domain api issue (#2026)
Fix the issue when NCMapi is not under the same domain
as the one frontend uses. The original method using
Vercel to proxy requests may cause latency under
some circumstances.
2023-04-08 23:13:28 +08:00
Younglina
8a50337854
fix(tracklist): TrackListItem 序号问题 (#2011)
直接使用 track.no 可能导致歌曲编号重复。改使用曲目在
阵列中的实际索引位置。
2023-04-08 23:12:13 +08:00
moonrailgun
7b97ac0139
chore: define node engines (#1943)
The `@achrinza/node-ipc` version we use in 1.x does not allow
a version of Node.js greater than 17. As YesPlayMusic has been in
maintenance mode, we define our supported Node.js engine version
rather than upgrade this dependency.

It may indicate the Vercel platform to not use 18 (or greater) in their
deployment.

The error message is:

    error @achrinza/node-ipc@9.2.2: The engine "node" is incompatible with this module. Expected version "8 || 10 || 12 || 14 || 16 || 17". Got "18.12.1"
2023-04-08 23:08:52 +08:00
qier222
1cb3e4b29f
Update README.md 2023-03-27 00:09:47 +08:00
Younglina
c89ebbdd22
fix: album.company显示问题 (#2009) 2023-03-22 14:16:47 +08:00
qier222
ce738f6b40
revert: change port to workaround 21H2's port 2023-01-30 12:38:38 +08:00
qier222
2a0af8f975
fix: update version 2023-01-28 12:16:47 +08:00
qier222
2f452dbe74
fix: bugs 2023-01-28 12:06:57 +08:00
タイムライン
622f95439d
fix: player volume bug (#1918)
* fix: player volume bug

* Update Player.js

* Update Player.js

* Update Player.js

* Update Player.js
2023-01-28 11:53:54 +08:00
タイムライン
210e65dd9a
update copyright year (#1917) 2023-01-27 01:11:48 +08:00
草方块
241de709da
fix: 更新依赖以解决手机号登录问题;UnblockNeteaseMusic 更新 (#1915)
* fix: 更新api以尝试解决邮箱登录问题

* fix: 又双更新api版本以修复手机号登录问题

(可能

* deps: [测试]更新UNM到0.4.0
2023-01-24 20:09:33 +08:00
草方块
c6804decfc fix: 更新api以尝试解决邮箱登录问题 2022-12-30 17:02:49 +08:00
Karbob
75d3e28ef8 feat: mount local time and time zone 2022-12-15 09:36:25 +08:00
Karbob
99371def54 refactor(dockerfile): separate nginx config from Dockerfile 2022-12-15 09:36:25 +08:00
Karbob
70d2713643 refactor(dockerfile): use awk to find NCMAPI version 2022-12-15 09:36:25 +08:00
Revincx
41b72563ff
refactor: improve lyric file download implement 2022-10-22 13:59:49 +08:00
Revincx
345f3588bd
chore: improve translations 2022-10-22 12:36:57 +08:00
Revincx
022f740c3f
feat: osdlyrics desktop lyrics support 2022-10-05 16:21:18 +08:00
Revincx
ce778afff6
feat: Tray icon theme now follows system theme 2022-10-05 15:23:11 +08:00
Kay W
9fcb6da960
feat: Add status text to like button when hover event triggers (#1789)
Signed-off-by: Kay Wei <weikaiii@sina.cn>
2022-09-09 12:45:22 +08:00
jbwfu
b589f82b6c
feat: add tutorial to deploy on Replit (#1731) 2022-08-31 12:08:13 +08:00
pan93412
f9e6164245
fix(ipcMain): unexpected “本草綱目“ from migu
This is just a workaround, and the core issue is on UNM.
However, refactoring UNM is time-comsuming and also requires
a lot of hard work. Therefore, we disable "migu" at this moment
simply.

Fixed #1713
Fixed #1711 (?)
2022-06-28 11:34:20 +08:00
pan93412
43c5bda806
chore(deps): upgrade dependencies (#1708) 2022-06-22 14:29:38 +08:00
pan93412
6d3508c62a
fix: change port to workaround 21H2's port (#1706)
* fix: change port to 35216 → workaround 21H2's port
* style: with restyled (#1707)
* Restyled by clang-format
* Restyled by prettier
* fix: change 21232 to 41342

Co-authored-by: restyled-io[bot] <32688539+restyled-io[bot]@users.noreply.github.com>
Co-authored-by: Restyled.io <commits@restyled.io>
2022-06-22 14:29:18 +08:00
marcus
9e64222bdf
feat: Add time to lyric page (#1676)
* feat: Add time on lyrics page

* feat: Add the setting item of whether to display the time on the lyrics page

* fix: fix some issue
2022-06-21 13:45:43 +08:00
marcus
7b911c1658
feat: Add "Volume Control" to Lyrics Page (#1672)
* feat: Add "Volume Control" to Lyrics Page

* fix: fix mute button
2022-06-21 13:45:32 +08:00
Viyerelu23333
a31d552788
fix(dockerfile): 设置 NCMAPI 版本 (#1689)
* fix: dockerfile ncapi pinning

* feat: ncmapi follows version in package.json
2022-06-19 20:54:08 +08:00
marcus
000cfda922
feat: Added "Add to Playlist" on lyrics page (#1671) 2022-06-19 20:53:28 +08:00
Changjian Gao
0abd616ca1
feat: Add context menu on MV page (#1670) 2022-06-19 20:52:26 +08:00
memorydream
2a2ac5a37d
fix: 私人推荐歌单 (#1665)
* fix: 私人推荐歌单

* update
2022-06-19 20:51:42 +08:00
memorydream
1496a8a0d0
fix: 歌名翻译文本位置 & FMCard背景颜色 (#1650)
* fix: 歌名翻译文本位置

* fix: 使FMCard的背景颜色永远随着歌曲改变
2022-06-19 20:51:30 +08:00
memorydream
6b690baef6
fix: 修复在长时间暂停后无法播放的问题 (#1627)
* fix: 修复在长时间暂停后无法播放的问题

* 增加doc
2022-06-19 20:51:16 +08:00
郭桓桓
b9cdade832 chore(ci/cd): bump actions/upload-artifact to v3 2022-06-03 14:45:50 +08:00
郭桓桓
fbc1e9903e chore(ci/cd): bump actions/checkout to v3 2022-06-03 14:45:50 +08:00
memorydream
439f368fd6
fix: 音乐库收藏的歌单少了第一张歌单 (#1657) 2022-05-23 01:27:49 +08:00
memorydream
bbbd729fdf
fix: 部分linux发行版环境的托盘行为 (#1647) 2022-05-21 06:03:24 +08:00
memorydream
c1efcb895c
fix: 歌词页视觉效果缺陷 (#1649) 2022-05-21 06:03:11 +08:00
qier222
cb59eb94a1
docs: update vercel links 2022-05-20 00:07:55 +08:00
pan93412
f355d5da50
fix(dockerfile): 限制最大標頭大小
原本的Nginx.conf没有定义最大标头大小。若不手动更改,则会出现无法登陆的bug,且Nginx会返回Header too big错误。

Fixed #1604

Co-Authored-By: huangyinhaow <64564727+huangyinhaow@users.noreply.github.com>
2022-05-14 20:07:13 +08:00
memorydream
6e1d58964e
fix: 专辑分碟排序错误 (#1630)
* fix: 专辑分碟排序错误

* update
2022-05-12 01:23:13 +08:00
qier222
c3aea5ee8d
fix: bug 2022-05-10 12:15:03 +08:00
qier222
f064859a27
docs: add powered by vercel 2022-05-10 12:10:47 +08:00
Hawtim
9e787bab03
Merge pull request #1598 from hawtim/fix-history-list-error
fix: render weekData error
2022-05-02 14:44:48 +08:00
Hawtim
97ac4117db
Merge pull request #1600 from hawtim/fix-node-vibrant-worker
Fix-node-vibrant-worker
2022-05-02 14:38:08 +08:00
Hawtim
8cd8ae4255
Merge pull request #1597 from hawtim/feature/support-image-lazy-loading
feat: add img tag with loading attribute for lazy loading
2022-05-02 14:36:06 +08:00
hawtimzhang
35edd84c22 fix: vibrant worker error 2022-05-02 14:30:11 +08:00
hawtimzhang
4613feff18 fix: render weekData error 2022-05-02 11:27:08 +08:00
hawtimzhang
fab099c6fb feat: add img tag with loading attribute for lazy loading 2022-05-02 00:47:42 +08:00
memorydream
107bf53a39
fix: 错误的选择了音源质量 (#1589) 2022-05-01 14:13:11 +08:00
qier222
e0f2d3fd57
build: release 0.4.5 2022-05-01 01:25:16 +08:00
memorydream
93c7ba2fd8
feat: 支持Hi-Res (#1585) 2022-05-01 01:24:20 +08:00
memorydream
5dd00bec87
fix: 修复因为使用了electron的clipboard导致的异常 (#1582) 2022-04-30 17:24:13 +08:00
memorydream
21c7b5ae44
feat: UNM 设置页面 l10n (#1578)
* feat: UNM 设置页面 l10n

* update translate

* update
2022-04-30 14:49:24 +08:00
memorydream
a9b05d66a6
fix(components/Titlebar): 还原/最大化按钮在双击标题栏时不会更新的问题 (#1575)
* fix(components/Titlebar): `还原/最大化`按钮在双击标题栏时不会更新的问题

* update
2022-04-29 19:52:22 +08:00
memorydream
c85af59b21
fix: bilibili音源无法播放的问题 (#1573) 2022-04-28 14:45:00 +08:00
pan93412
93ae57adbe
feat: switch to UNM (Rust) (#1536)
* refactor: use unm-rust-napi

* ci(build): install UNM dependencies for certain platforms

* feat: add the ability to configure UNM

* feat: add the UNM configuration in settings page

* refactor(jsconfig): jsx -> preserve

* fix(ci/build): use bash to get unm version

* chore(deps): upgrade UNM to 0.3.0-pre.0

* refactor(electron/ipcMain): update default sources

* fix(views/settings): remove duplicated config entry

* feat(settings): allow configuring QQ cookie

We also removed some duplicate entries in views/settings.vue.

* chore(deps): UNM -> 0.3.0-pre.1

* refactor: remove unused old UNM

* fix(utils/player): do not include rust-napi in client code

As we only imported the constant, I just expand it as the integer.

Co-authored-by: qier222 <qier222@outlook.com>
2022-04-28 01:02:41 +08:00
pan93412
e1f7618cbd refactor(views/lyrics): tweak size 2022-04-27 20:53:49 +08:00
memorydream
3c798a5606
feat: 使用svg输出登陆二维码 (#1568) 2022-04-27 18:38:37 +08:00
pan93412
d87c4bad21
chore(deps): update some dependencies to latest (#1564)
* chore(deps): upgrade dependencies

* chore(deps): upgrade some deps to major version

已經查過這些 packages 的 Changelog,確定是安全、可升級的。此外也進行了簡單的 E2E 測試,可正常使用。
2022-04-27 18:37:52 +08:00
pan93412
177a8c8eff fix(views/loginAccount): improve clarity of QR Code
渲染 384px 的 QR Code,而顯示在 192px 的方框中。這樣 QR Code 大小不變,但清晰度為原本的兩倍。

Fixed #1562
2022-04-26 07:10:47 +08:00
pan93412
aeda63faf7
fix(deps): correct the vue-gtag version (#1556) 2022-04-23 17:19:43 +08:00
pan93412
0a1c847b4b
fix(views/lyrics): use scale to make animation smooth (#1554) 2022-04-23 17:19:31 +08:00
pan93412
ab85c51831
fix(utils/player): preload & autoUnlock (#1557)
* fix(utils/player): preload & autoUnlock

* style: clang-format & prettier
2022-04-23 17:19:16 +08:00
qier222
f88addc95d
feat: update ga 2022-04-16 03:06:16 +08:00
GalvinGao
ea4b20755d
feat: add copy track link & fixed various visual defects (#1489)
* feat: add copy track link

* fix: various visual defects

* feat: add track low res fallback

* chore: remove redundant locale strings

* chore: separate playbackState for a new PR

* build: fix netlify failing to build site
2022-04-12 16:16:46 +08:00
amphineko
16b525915e
feat(utils/request): override realIP param with env var (#1514) 2022-04-12 00:08:44 +08:00
pan93412
af0a997609
ci: configure restyled.io better (#1499) 2022-04-09 01:15:30 +08:00
memorydream
3fca7d16bb fix: APP启动时检查窗口位置,避免窗口启动在屏幕外 2022-04-05 14:41:48 +08:00
memorydream
7d64dea29b fix: 禁止在TrackListItem上导航到id为0的歌手页 2022-04-05 14:41:48 +08:00
pan93412
999bf6fdb4
chore(release): 0.4.4-1 2022-04-04 00:47:53 +08:00
pan93412
871217713a
revert: isCreateTray 在瀏覽器環境應永遠為應永遠為 false
部分環境沒有 process.env.IS_ELECTRON,以致發生錯誤。

This reverts commit 748db54f52.
2022-04-04 00:46:08 +08:00
qier222
e5d1af49bf
revert: "fix(ci/build): 暫時不要登入 (#1452)"
This reverts commit fe660cf1a9.
2022-04-03 16:10:24 +08:00
pan93412
fe660cf1a9
fix(ci/build): 暫時不要登入 (#1452)
目前 YPM 的 snapcraft_token 似乎失效了?
2022-03-28 17:57:17 +08:00
pan93412
5ff8868d3e
fix(utils/request): token 過期 (301) 時重新導向至登入頁面 (#1448) 2022-03-27 15:16:55 +08:00
HengYi Wei
1c25f11821
Update README.md: 添加了 Scoop 安装方式介绍 (#1445) 2022-03-26 21:52:35 +08:00
Jiang Menghao
626786a008
fix(components/DailyTracksCard): 修复了每日推荐在 Safari 不显示圆角的bug (#1444) 2022-03-26 18:55:42 +08:00
memorydream
b1c5873bd6
fix: firefox scrollbar (#1425) 2022-03-20 18:05:35 +08:00
memorydream
748db54f52 fix(utils/platform): isCreateTray 在瀏覽器環境應永遠為應永遠為 false 2022-03-16 15:50:20 +08:00
pan93412
fbf695eb16 feat(utils/player): 播放、暫停時淡入淡出 2022-03-16 15:50:20 +08:00
pan93412
98068f55cb
chore: upgrade dependencies (#1390)
- UnblockNeteaseMusic@0.27.0-rc.6
- dayjs@1.10.8
- electron-builder@23.0.2
- music-metadata@7.12.2
- NeteaseCloudMusicApi@4.5.8
- eslint-config-prettier@8.5.0
2022-03-10 15:37:57 +08:00
memorydream
ef7f51ecf0
feat(library): i18n & l10n (#1386)
* Update library translations

* Update zh-TW.js
2022-03-08 12:22:27 +08:00
pan93412
be35a8ded4
feat(ci): 允許手動觸發執行檔編譯流程 [skip ci] 2022-03-07 20:52:17 +08:00
memorydream
7dad7d810a
fix: 修复部分按钮失效的问题 (#1380) 2022-03-06 11:55:57 +08:00
pan93412
596204dc58
build(ci): 加上 dependencies 快取
順帶將 setup-node 升級至 v3。
2022-02-26 16:05:18 +08:00
pan93412
6ed5f274e6
build(ci): 將 Node.js 的版本切換至 v16 2022-02-26 16:04:57 +08:00
pan93412
b65a8b9da0
chore: 更新 lockfile
使用 yarn upgrade 更新部分 dependencies。
2022-02-26 16:04:00 +08:00
郭桓桓
8e68d7e796
chore(license): update copyright year (#1354) 2022-02-26 12:29:18 +08:00
pan93412
3d5d40c476
feat(components/Navbar): 自訂和微調各系統的 titlebar (#1343)
* feat: linux custom titlebar
* add settings init
* Update zh-TW.js
* fix: color

Co-authored-by: memorydream <34763046+memorydream@users.noreply.github.com>
2022-02-25 07:36:56 +08:00
pan93412
3e1dc62fa0
chore: 更新依賴、更換為 prettier 新規則 (#1340)
* chore: upgrade dependencies
* style: prettier
2022-02-25 07:36:13 +08:00
Chuwen
76b358445e
build: 优化打包体积 (#1323)
* 移除生产环境不必要的 map 文件
* webpack 添加 LimitChunkCountPlugin 用以解决 chunk 包太多的问题
2022-02-23 23:26:37 +08:00
qier222
91b4e08449
build: release v0.4.4-beta.1 2022-02-03 22:29:38 +08:00
memorydream
80b19192c3
fix(views/lyrics): don't open empty artist link (#1286) 2022-02-03 20:37:18 +08:00
CNawalol
d15b58d805
feat: mpris support (#1279)
* feat: mpris support

* fix: 修复网页版无法播放

* fix: 修复在 Player.js 里 ipcRenderer 为空时引发的错误

* docs: update README

* docs: update README

Co-authored-by: memorydream <34763046+memorydream@users.noreply.github.com>
2022-01-30 00:37:12 +08:00
pan93412
5a5fb1f191
refactor(ncmapi): use upstream version (#1278)
* refactor(ncmapi): use upstream version

FIXME: After #1457 released,
switch to the NPM version.

* fix(docker): install NeteaseCloudMusicApi early

* fix: remove useless submodule entry

* fix(ncmapi): update to 4.5.2
2022-01-30 00:19:55 +08:00
memorydream
c8b9c0dae8
fix(utils/lyrics): format 2022-01-28 15:17:34 +08:00
memorydream
769ba47a1d
fix(utils/lyrics): [min:sec] timestamp lyrics parse (#1277)
* fix(utils/lyrics): [min:sec] timestamp lyrics parse

* refactor(utils/lyrics): simplify time expression

* style(utils/lyrics): remove duplicate space

Co-authored-by: pan93412 <pan93412@gmail.com>
2022-01-28 14:54:40 +08:00
pan93412
8a6c13e62f
refactor(utils/lyrics): support multi-timestamp lyrics (#1268)
* refactor(utils/lyrics): support multi-timestamp lyrics

Fully rewrited and improved the performance.

* refactor(utils/lyrics): remove useless .map

* fix(utils/lyrics): enhance the extraction logic
2022-01-27 16:25:45 +08:00
memorydream
7b7b8745b6
fix: netease_api install and prettier (#1267) 2022-01-27 11:17:15 +08:00
memorydream
171f4708d8
remove comment 2022-01-27 01:49:18 +08:00
pan93412
9ae5e4f059
fix(utils/lyrics): do not preserve the empty lyric 2022-01-27 00:07:09 +08:00
pan93412
3ddfe9c3bb
refactor(utils/lyrics): better parsing logic 2022-01-26 23:41:53 +08:00
pan93412
1c7344beaf
fix(build): try to fix up the ARM64 build issue
https://github.com/qier222/YesPlayMusic/runs/4950356054
2022-01-26 20:38:21 +08:00
pan93412
240c1560db
feat(ci): also build on "ci/" branch 2022-01-26 18:35:26 +08:00
pan93412
6af6b86e87
build: add arm64 support for Linux 2022-01-26 18:27:38 +08:00
pan93412
50171911f9
chore: upgrade electron to 13.6.7 2022-01-26 18:15:28 +08:00
pan93412
e6abbe244b
refactor(babel): use corejs 2022-01-26 18:15:28 +08:00
pan93412
ebd863f5b6
refactor(ncmapi): manage NCMAPI with submodule
also:
  - docs: tells user to clone repo recursively
  - feat(ci): clone recursively
  - feat(ncmapi): backport my change
    https://github.com/Binaryify/NeteaseCloudMusicApi/pull/1453
  - refactor: rewrite startNeteaseMusicApi()
2022-01-26 18:13:55 +08:00
pan93412
d5ffacae3a
fix(npm): forcibly resolve 'icon-gen' to v3
Seems like no any API breaking changes in icon-gen v3.
Besides, we can throw phantomjs away.

Fix #1265
Fix #1260
2022-01-26 09:41:01 +08:00
Rick
a870dc3185
fix: docker build failed (#1259)
* fix: docker build failed #1258

* refactor(docker): maximum the usage of cache

* fix(docker): "RUN" repeats two times

Fix #1258

Co-authored-by: pan93412 <pan93412@gmail.com>
2022-01-22 21:07:33 +08:00
Wenqi Huang
4b22651a07
fix: set "onend" callback for howler properly (#1249)
Fix #1090
2022-01-22 20:39:26 +08:00
memorydream
75fed70c38
fix: retry when personalFM not found data (#1231)
* fix: retry when personalFM not found data

* fix

* fix: retry count
2022-01-17 23:23:39 +08:00
memorydream
d716bb8cde
feat: refactor tray (#1227)
* feat: support set tray icon tooltip info

* fix: name

* refactor tray impl and add tray playing state change

* fix: linux impl

* add pause icon

* add tray like state

* fix

* fix: linux impl

* better pause icon
2022-01-17 23:23:21 +08:00
memorydream
3cbb8d9b25
fix: wrong trim all white space lyric (#1233) 2022-01-17 21:12:40 +08:00
chen310
585691aa0f
fix: 云盘加载歌曲数增加至1000 (#1242)
FIXME: 超过 1000 的部分仍无法显示 

Fix #940
Fix #1024
Fix #1240
2022-01-17 20:38:09 +08:00
GalvinGao
42f3da9b37
feat: add reversed mode & improvements to lyrics animation (#1226)
* feat(reversed-mode): add reversed mode & improvements to lyrics animation

* feat(lyrics-animation): improve `:active` style

* fix: extra white space after artist in lyrics view

* refactor: remove unused function

* feat: slightly add duration of transition to improve replication from Apple Music style
2022-01-14 15:30:19 +08:00
memorydream
3ea5446fcc
fix : PersonalFM can not found next track (#1217)
* fix : PersonalFM can not found next track

* do not call _loadPersonalFMNextTrack() when reload personal FM

* fix: revert

* fix: separate playNextTrack

* fix: moveToFMTrash

* fix

* fix: shortcut and _loadPersonalFMNextTrack()

* show toast when personal timeout

* fix: name
2022-01-12 01:04:40 +08:00
Rick
c7c6583523
fix: docker build image error (#1212) (#1216) 2022-01-11 19:07:48 +08:00
chen310
d4ca9d6dcf
fix: 解决云盘和听歌排行歌曲变灰的问题 (#1215) 2022-01-11 19:07:35 +08:00
memorydream
76a8742d61
feat: better lyrics filter (#1210)
* feat: better filter lyrics

* change

* replace filter text with RegExp

* more change

* add try catch

* better author filter
2022-01-11 19:06:47 +08:00
memorydream
73df7f28f4
feat: 当只有一句歌词且内容为'纯音乐,请欣赏'时,隐藏歌词面板 (#1205) 2022-01-09 18:34:30 +08:00
Rick
a87686098c
feat: 增加心动模式/智能播放 (#323) (#1206) 2022-01-09 18:33:42 +08:00
memorydream
b501214c02
fix: context menu position (#1207)
* fix: context menu position

* fix: context menu position with player disabled
2022-01-09 18:12:30 +08:00
Rick
66f9b4f526
chore: 支持 Docker 部署 (#1195) (#1200) 2022-01-08 19:26:11 +08:00
memorydream
14566b20b2
fix: library extract lyric part (#1201) 2022-01-08 17:33:41 +08:00
memorydream
07b5d4de3d
fix: lyrics sort (#1199) 2022-01-08 01:12:16 +08:00
Rick
3d71e9fc00
feat: 增加我的听歌排行 (#274) (#1197) 2022-01-07 21:32:00 +08:00
pan93412
5071e82e1c
build: degrade electron to 13.0.1
Seems like Electron 13.6 breaks the Windows 7 support.
We degrade Electron's version to what 0.4.2 uses.

Related: #1179
2022-01-05 21:27:46 +08:00
chen310
98ac9fd1ac
fix: 解决某些歌曲(如已购专辑)能播放但仍然变灰的问题 (#1173) 2022-01-04 18:35:31 +08:00
qier222
f9ad6aef05
build: release 0.4.3 2022-01-03 15:56:22 +08:00
qier222
92d0b2ea8b
docs: update README 2022-01-03 15:45:59 +08:00
是虹川飴
cbeb64a65c
fix #1152 (#1157) 2021-12-31 18:56:16 +08:00
pan93412
d153810205
fix(views/library): better lyric-picking logic (#1143)
* fix(views/library): better lyric-picking logic

* feat(views/library): filter out lines with "作詞" and "作曲" included
2021-12-29 07:37:58 +08:00
pan93412
f5cdbea379
refactor(views/library): 修改取词逻辑 (#1135)
* refactor(views/library): 修改取词逻辑

* refactor(views/library): clean up long-winded code

Co-authored-by: 是虹川飴 <r0akg9yxh@relay.firefox.com>
Closed: #1133
Fixed: #1019 #1127 #1067 #1064 #1058 #1022
2021-12-28 17:58:31 +08:00
Vidocq
e838f1d6d4
fix: toast covered by modal (#1137) 2021-12-28 01:04:33 +08:00
pan93412
83b78bab34
feat: allow customizing UNM's sources (#1134)
* feat(ipcMain/unm): allow passing customized source

* feat(utils/Player): pass settings.unmSource

According to c280221a44608777a69038306a6ea8e92953fb9a,
we can let users customize their desired source now.

* feat(views/settings): allow configuring sources

We haven't supported specifying the environment variable in YPM yet.
2021-12-28 00:49:31 +08:00
memorydream
c73da5c5ad
fix: firefox lyrics scrollbar (#1128) 2021-12-25 13:08:01 +08:00
pan93412
836b7d0ce9
fix(player): release object urls (#1121) 2021-12-24 17:19:16 +08:00
pan93412
d049eb4903
fix(settings): update URL to our UNM fork's (#1120) 2021-12-24 15:22:27 +08:00
是虹川飴
4a99f31aed
fix: 修复 issues #1019 的跟进问题 (#1113)
* issues #1019 的迫真修复

* 修复 issues #1019

* 修复 issues #1019

* 改回 pickedLyric() 逻辑

* 更进一步的避免取词卡死问题

* 更新网易云 api 到 4.2.0

* Update README.md

* Revert "Update README.md"

This reverts commit b862ef7d4dabd40c8fe57e4837fc6220806a1456.

* Update lyrics.vue

* 过滤歌词
2021-12-21 10:20:04 +08:00
memorydream
47862d6710
fix: disc color (#1114) 2021-12-21 10:12:06 +08:00
是虹川飴
e9d9c3aee8
fix: issues #1076 (#1080)
* issues #1019 的迫真修复

* 修复 issues #1019

* 修复 issues #1019

* 改回 pickedLyric() 逻辑

* 更进一步的避免取词卡死问题

* 更新网易云 api 到 4.2.0

* Update README.md

* Revert "Update README.md"

This reverts commit b862ef7d4dabd40c8fe57e4837fc6220806a1456.

* Update lyrics.vue
2021-12-20 19:00:59 +08:00
Chiro
d322a29b72
fix: #1063 #1010 (#1083) 2021-12-20 19:00:33 +08:00
Changjian Gao
5c6eaa8fda
feat: Add "Open in Browser" context menu item to artist and album page (#1096) 2021-12-20 18:57:45 +08:00
pan93412
16c3613267
feat: Use actively maintained unblockNeteaseMusic (#1105)
* refactor: use @unblockneteasemusic/server

we also use ipcMain.handle for unblock-music.

* refactor(utils/nativeAlert): remove the deprecated "remote"

* refactor(ipcMain): use our default sources

* style(config/vue): prettier

* feat(README): update for new UNM
2021-12-20 18:56:26 +08:00
人工知能
3bc9d24677
fix: update zh-TW.js (#1087)
Localize translations
本地化翻譯
2021-12-19 16:46:35 +08:00
是虹川飴
0d3df4a1e4
fix: 修复 issues #1019 的跟进问题 (#1068)
* issues #1019 的迫真修复

* 修复 issues #1019

* 修复 issues #1019

* 改回 pickedLyric() 逻辑

* 更进一步的避免取词卡死问题

* 更新网易云 api 到 4.2.0

* Update README.md

* Revert "Update README.md"

This reverts commit b862ef7d4dabd40c8fe57e4837fc6220806a1456.
2021-12-06 18:27:24 +08:00
是虹川飴
8341727882
fix: 修复 issues #1019 (#1040)
* issues #1019 的迫真修复

* 修复 issues #1019

* 修复 issues #1019

* 改回 pickedLyric() 逻辑
2021-11-09 10:55:36 +08:00
memorydream
e4298fdad6
fix: name (#1033) 2021-11-08 14:37:52 +08:00
memorydream
d580e63358
fix: #1009 (#1018)
* fix: goToList bug

* lyrics page title go to fix

* change
2021-10-28 22:02:58 +08:00
Hawtim
ee59479ff8
feat: enhance (#1016) 2021-10-28 01:09:00 +08:00
qier222
9b565c41c2
chore: update package.json 2021-10-22 20:44:39 +08:00
qier222
d0ae7fee72
chore: update .env.example 2021-10-22 20:43:42 +08:00
火花✨
75bb6b9e2d
fix: remove zh-tw flag emoji (#991)
* fix: correct zh-tw flag emoji

* Update settings.vue

Co-authored-by: qier222 <qier222@outlook.com>
2021-10-22 16:52:00 +08:00
memorydream
c25a3065e1
fix: 在windows和linux中,当启动第二个窗口时,呼出已经启动的窗口 (#992)
* fix: 在windows和linux中,当启动第二个窗口时,呼出已经启动的窗口

* prettier code

* change
2021-10-22 16:51:04 +08:00
memorydream
9d18ad51f6
fix: 修复Linux下,关闭主面板时... 询问选项无效的bug (#969)
* fix: Linux close app ask cant work

* Update background.js

* fix: bug
2021-10-11 10:19:37 +08:00
memorydream
704732a046
try tray context on linux | 尝试在linux上实现托盘菜单 (#926)
* try tray context on linux

* 调整linux下托盘菜单的选项位置

* bug fix

* fix : linux tray contextMenu cant open

* prettier code

* 移除 显示主面板 的图标
2021-10-11 10:19:27 +08:00
memorydream
b6cc6f8284
fix: 当不存在专辑时,不在歌词界面显示多余的符号 (#941)
* code clear

* 当不存在专辑时,不在歌词界面显示 - 符号

* some change
2021-10-11 10:19:10 +08:00
memorydream
d424f2cad5
fix: 修改歌名翻译的实现,以避免展示重复的信息 (#958)
* change song translate impl

* i18n

* 修改个变量名

* bug fix?
2021-10-11 10:18:49 +08:00
memorydream
de818282c8
fix: 增强并明确关闭app的相关行为 (#938)
* 分离close和minimize按钮行为

* bug fix
2021-09-28 19:05:34 +08:00
qier222
8b59a72506
chore: update package.json & build.yaml 2021-09-26 00:49:49 +08:00
qier222
aa418cd0d7
fix: 云盘无法上传的bug 2021-09-25 23:53:50 +08:00
qier222
dd65c67568
fix: 更新build.yaml 2021-09-25 19:16:02 +08:00
qier222
14f47f8cfc
fix: 全局快捷键相关bug 2021-09-25 19:10:37 +08:00
qier222
bb87b7f20d
fix: bugs 2021-09-25 18:49:05 +08:00
memorydream
17ef0e927c
feat: more operations for close | 为关闭app操作提供更多选项 (#918)
* feat: more operations for close

* remove minimizeToTray form initLocalStorage

Co-authored-by: qier222 <qier222@outlook.com>
Co-authored-by: qier222 <qier2222@gmail.com>
2021-09-25 16:12:30 +08:00
BakerBunker
8b089e6cf4
feat: support separate album by disc (#861)
Co-authored-by: BakerBunker <bakerbunker@nwpu.edu.cn>
2021-09-25 16:11:49 +08:00
memorydream
dfcae06496
fix: empty Album artist page can't open (#839) 2021-09-25 15:23:12 +08:00
qier222
eb94aae801
fix: 扫码登录问题 2021-09-25 15:16:34 +08:00
qier222
cc914d4799
docs: 增加部署到vercel后api跨域的解决方法 2021-09-25 12:52:15 +08:00
qier222
b052b462e3
refactor: 网页版路由使用history模式 2021-09-25 12:52:15 +08:00
qier222
060569ee92
fix: bugs 2021-09-25 12:52:15 +08:00
qier222
e96e93f965
fix: 扫描二维码无法登陆的问题 2021-09-25 12:52:14 +08:00
Vidocq
89d346b2ff
fix: cloudpan music playing error (#812) 2021-06-30 22:26:54 +08:00
Changjian Gao
daadad7bf3
fix: show toast when search failed (#789) 2021-06-17 12:31:26 +08:00
zuotiya
610f663c24
fix: scroll bar click problem (#793)
Fixed the scroll bar click problem
2021-06-17 12:30:51 +08:00
Changjian Gao
c091e4cb9f
fix: add more i18n for artist and album pages (#790) 2021-06-17 12:29:09 +08:00
leko
9dcf9f5db1
feat: add zh-TW locale (#786) 2021-06-17 12:28:34 +08:00
Changjian Gao
12cae1b921
fix: incomplete albums and artists in library (#765) #704 2021-06-11 10:56:05 +08:00
qier222
dd315e573d
docs: update README.md 2021-06-10 23:55:30 +08:00
qier222
caaf62ea20
fix: remove osdlyrics 2021-06-10 13:50:31 +08:00
qier222
c7681df0e8
fix: bug #753 2021-06-09 22:32:58 +08:00
qier222
ed0bb1c031
chore: update package.json 2021-06-09 21:19:43 +08:00
qier222
f3076f21b2
fix: bugs 2021-06-09 20:53:33 +08:00
qier222
e54c606c6d
feat: custom shortcuts 2021-06-09 20:39:00 +08:00
qier222
78d90f15f5
feat: add music language preference 2021-06-08 17:17:34 +08:00
qier222
f89fc84f95
refactor: only show NProgress when loading time is too long 2021-06-08 16:37:05 +08:00
qier222
723cf1b3b3
style: new lyrics background 2021-06-08 00:37:35 +08:00
qier222
c506dea02b
fix: bugs 2021-06-08 00:09:30 +08:00
qier222
22c9691a73
style: personal fm card 2021-06-07 18:33:05 +08:00
qier222
d70fd44d8e
feat: qrcode login 2021-06-07 18:27:46 +08:00
qier222
04bc4770b4
fix: lyric page bugs 2021-06-06 01:57:43 +08:00
qier222
7781ac8ec2
feat: cache track details, lyrics and album 2021-06-06 01:00:27 +08:00
qier222
3d29bb5ca1
fix: bugs 2021-06-05 23:41:29 +08:00
qier222
571d0d71f8
feat: support cloud disk 2021-06-05 21:29:18 +08:00
qier222
996904f056
refactor: netease api routes 2021-06-05 18:01:41 +08:00
qier222
7c79afd0d1
feat: virtual scrollbar 2021-06-05 14:16:53 +08:00
qier222
226a2145c4
fix: bugs 2021-06-05 07:27:41 +08:00
qier222
41ff8058b2
feat: remember window position 2021-06-04 15:06:37 +08:00
qier222
61d1d0ab4d
fix: cache limit issue 2021-06-02 19:08:25 +08:00
qier222
efd67346fd
chore: update Electron version 2021-06-02 17:55:43 +08:00
qier222
0d610c45a7
fix: #729 #678 2021-06-02 17:55:43 +08:00
Changjian Gao
a00d27d0c9
fix: Add i18n for playlist context menu (#734) 2021-06-01 18:04:35 +08:00
BakerBunker
347bc1665d
fix: Add new localizations (#722)
Co-authored-by: bakerbunker <bakerbunker@nwpu.edu.cn>
2021-05-30 18:25:35 +08:00
memorydream
5869f889f9
fix: empty artist link (#705) 2021-05-26 16:46:50 +08:00
Changjian Gao
e233aa9f1d
fix: OSD lyrics button title (#709) 2021-05-26 16:46:19 +08:00
Changjian Gao
b9da9a41fd
feat: Support copy artist and album URL (#708) 2021-05-26 16:46:00 +08:00
qier222
e226afbaff
chore: update package.json 2021-05-25 20:02:21 +08:00
memorydream
6910d5ba87
feat: add song title translate (#691) 2021-05-24 12:21:50 +08:00
Shi Liang
427806b0d7
fix: 当部署到服务器上时,不显示桌面歌词切换图标 (#689)
* Add OSD Lyrics

* tidy files

* fix OSDLyrics: last line of lyrics not showing, performance

* tidy files

* make user can resize the lyrics window

* Fix bug of initial window size

* Fix: 1. auto resize osdlyrics window after packaging; 2. lyric parser problem with %;

* tidy files

* hide osdlyrics button if not in electron

* tidy files
2021-05-24 12:17:49 +08:00
Revincx
2d712eefe1
fix qq music of unblockneteasemusic | 修复qq音源不能解析的问题 (#695)
* fix: change to @revincx/unblockneteasemusic moudle

* Update README.md

* Update README.md

* Add OSD Lyrics

* tidy files

* fix OSDLyrics: last line of lyrics not showing, performance

* tidy files

* make user can resize the lyrics window

* update unblockneteasemusic

* update unblockneteasemusic again

Co-authored-by: qier222 <qier222@outlook.com>
Co-authored-by: Shi Liang <shilianggoo@gmail.com>
2021-05-24 12:17:37 +08:00
Shi Liang
85592142af
feat. OSD Lyrics | 增加桌面歌词功能 (#685)
* Add OSD Lyrics

* tidy files

* fix OSDLyrics: last line of lyrics not showing, performance

* tidy files

* make user can resize the lyrics window

* Fix bug of initial window size

* Fix: 1. auto resize osdlyrics window after packaging; 2. lyric parser problem with %;

* tidy files
2021-05-21 17:15:30 +08:00
MUXTER117
d464e30d83
fix: update App.vue (#681)
上次修改字体名称写错了,已改正。
2021-05-19 19:21:06 +08:00
qier222
fe949ccdc0
fix: bug #680 2021-05-19 00:05:35 +08:00
qier222
e57847c6e1
refactor: replace google fonts with local fonts 2021-05-19 00:04:53 +08:00
qier222
41a30a25c0
fix: bugs 2021-05-18 16:57:37 +08:00
qier222
ad0c585371
fix: bug #593 2021-05-18 15:35:23 +08:00
qier222
3678839522
fix: bug #674 2021-05-18 15:24:59 +08:00
qier222
c627f4684f
fix: bug #675 2021-05-18 15:20:19 +08:00
Changjian Gao
8d68ee0ee3
feat: Add artist description (#676) 2021-05-18 14:14:56 +08:00
qier222
5d80ca89ea
chore: update package.json 2021-05-18 01:00:02 +08:00
Revincx
920b216466
fix the UnblockNeteaseMusic | 修复UnblockNeteaseMusic无法使用的问题 (#670)
* fix: change to @revincx/unblockneteasemusic moudle

* Update README.md

* Update README.md

Co-authored-by: qier222 <qier222@outlook.com>
2021-05-17 23:59:02 +08:00
qier222
b05a686180
feat: add clear queue button to next page 2021-05-17 23:53:45 +08:00
qier222
ba4d211ee7
feat: add latest mv section to artist page 2021-05-17 23:13:32 +08:00
qier222
6ce9055484
fix: bugs 2021-05-17 19:20:38 +08:00
qier222
5b6619d1de
fix: proxy issue 2021-05-17 19:20:37 +08:00
Ethan Wong
cc6b364b87
fix: make Express listen on localhost only (#656) 2021-05-08 23:30:21 +08:00
Map1en_
c8adba7f13
feat(shortcut): add show-hide keyboard shortcut (#650) 2021-05-07 21:51:33 +08:00
qier222
b98d69af18
fix: bugs 2021-05-06 02:02:55 +08:00
Vidocq
79de3009ad
feat: playlist search in likepage (#627) 2021-04-30 16:13:32 +08:00
qier222
95f22f47fe
fix: bugs 2021-04-28 13:44:37 +08:00
Vidocq
fa9f2d9785
fix: output device switch (#618) 2021-04-28 01:09:37 +08:00
qier222
07455c8ecd
feat: send current track to main process and provide an api 2021-04-28 01:09:17 +08:00
qier222
c564d03c17
docs: update README.md 2021-04-27 18:25:27 +08:00
qier222
f8e194a691
chore: update package.json 2021-04-27 17:39:47 +08:00
qier222
b059de17fb
fix: bugs 2021-04-27 17:39:26 +08:00
qier222
1f02f6c71f
fix: bug #578 2021-04-27 17:12:59 +08:00
Map1en_
fa9acc9c89
feat(lyrics): add static lyrics background (#614)
* feat(lyrics): add static lyrics background

close #607

* add high GPU usage message
2021-04-27 17:09:10 +08:00
qier222
f1e3d8ebf0
fix: bugs 2021-04-27 16:51:37 +08:00
qier222
9ccce5b468
fix: bugs 2021-04-27 02:00:44 +08:00
qier222
2b22c7e050
feat(electron): add proxy support 2021-04-27 01:59:09 +08:00
qier222
458f6dd447
feat: add playlist filter to library page 2021-04-27 00:08:00 +08:00
Map1en_
aa269cf2ca
fix(lyrics): hide the scrollbar in lyrics page (#605)
* fix(lyrics): hide the scrollbar in lyrics page

close #571

* fix(tracklist): close context menu when scrolling

* fix: disable scrolling when modal show
2021-04-26 22:42:10 +08:00
Map1en_
fa98085dcf
fix(lyrics): fix style (#606) 2021-04-26 18:48:09 +08:00
qier222
9351f6bc89
chore: format codes 2021-04-26 16:31:03 +08:00
Map1en_
6922c716e2
perf(lyrics): optimize GPU usage for dynamic lyric backgrounds (#602)
optimize GPU usage for dynamic lyric backgrounds

#484
2021-04-26 15:39:10 +08:00
qier222
2c8ba10e20
fix: bugs 2021-04-26 15:38:39 +08:00
qier222
603e39f362
refactor: library page 2021-04-26 15:29:47 +08:00
qier222
b537081f2a
chore: update prettier config 2021-04-25 17:27:19 +08:00
qier222
fab0227ed3
refactor: move all states+actions inside player.vue to Player.js 2021-04-25 16:53:53 +08:00
qier222
5355caa4e4
fix: bugs 2021-04-25 14:24:04 +08:00
qier222
7d580e7113
feat: add UnblockNeteaseMusic switch 2021-04-25 14:01:55 +08:00
qier222
b47ea5aa1f
fix: bug #501 2021-04-25 12:20:56 +08:00
Rick
cf7dd55bf4
fix: newAlbum issue (#573) (#582) 2021-04-23 13:32:26 +08:00
Vidocq
64c56e33f0
fix: likelist does not change when account switching (#557) 2021-04-22 12:52:43 +08:00
qier222
021941d212
fix: last.fm auth #569 2021-04-22 12:28:46 +08:00
qier222
e3c198b32b
chore: add new eslint rule 2021-04-22 10:59:00 +08:00
qier222
c2793cf9ff
fix: artist and album show as unknow in lyrics page 2021-04-22 10:54:38 +08:00
qier222
e0c9fa38d3
chore: update package.json 2021-04-20 15:44:54 +08:00
qier222
f16d08ab6d
refactor: explore category 2021-04-20 14:40:44 +08:00
qier222
2f0e8e1e24
fix: bugs 2021-04-20 14:40:44 +08:00
Map1en_
fc08992244
fix(lyrics): fix resetting the previous page when lyrics switchoff (#547) 2021-04-20 11:51:14 +08:00
Map1en_
dceb5cdb2c
fix(settings): fix typo (#551)
#549
2021-04-19 15:13:40 +08:00
qier222
4e023502ca
fix: remove sentry 2021-04-19 11:33:38 +08:00
Map1en_
9708064d26
feat(settings): add show music library default setting (#549)
* feat(settings): add show music library default setting

resolve #301

* adj zh-cn text

Co-authored-by: qier222 <qier2222@gmail.com>
2021-04-19 10:44:59 +08:00
Map1en_
9ae15c198d
feat(cache): add songs cache limit feature (#548)
resolve #232
2021-04-19 10:43:52 +08:00
qier222
a47697fbfa
fix: bugs 2021-04-15 14:00:43 +08:00
qier222
f702c33834
fix: win32 titlebar issue 2021-04-15 14:00:42 +08:00
Map1en_
2ecba8e161
feat(nyancat): add the status of stillness nyancat (#541) 2021-04-14 01:38:38 +08:00
qier222
4f4f2b09e3
fix: bugs 2021-04-12 14:14:11 +08:00
Map1en_
872fd73b05
fix(player): fix can't read prop seek of null (#537)
fix #488 fix #497
2021-04-12 01:16:28 +08:00
Map1en_
5cf0092b4f
fix(player): fix cannot switch next track in personalFM (#536)
fix #501
2021-04-12 01:16:05 +08:00
Map1en_
f50c210725
fix: fix typo (#531)
fix #374
2021-04-07 13:50:47 +08:00
Map1en_
43a293da6a
fix(electron): set appearance during init of electron window (#525)
resolve #512
2021-04-04 21:00:47 +08:00
Ethan Wong
1e7274e97f
fix: alert issue on Windows by using native messageBox (#509)
* Fix alert issue on Windows by using native messageBox

* Update related docs for alert fix

* Remove unlocalized hint
2021-04-04 21:00:11 +08:00
Vidocq
025e28399e
fix: search bug when searching in playlist (#495) 2021-03-29 11:52:20 +08:00
qier222
d9c8489c92
fix: bugs 2021-03-25 22:10:22 +08:00
wenjie
36447ae5d8
feat: add global shortcut setting (#470)
* feat: add global short cut setting

* fix: fix settings not work

* fix: call initIpcMan after createWindow

* fix: fix build error (typo)
2021-03-25 21:20:53 +08:00
qier222
b98bf909fb
fix: bugs 2021-03-25 19:29:55 +08:00
qier222
91ae6bb107
feat: cache next track 2021-03-25 19:29:40 +08:00
qier222
fee97f7f3c
refactor: use dexie.js instead of localforage 2021-03-25 19:28:40 +08:00
wenjie
bf61fe6e28
feat: add turkish automatic recognition (#486)
* feat: add turkish automatic recognition

* Update src/store/index.js
2021-03-25 15:17:44 +08:00
qier222
750e1997e6
feat: support turkish 2021-03-24 22:39:27 +08:00
qier222
fd16d470bd
fix: bugs 2021-03-24 22:28:24 +08:00
sr.zer
044720c531
feat: create a lang json for turkish (#479)
Create a lang json for turkish
2021-03-23 23:47:41 +08:00
qier222
55585a921f
feat: support Last.fm scrobble 2021-03-23 23:43:29 +08:00
Vidocq
cc50faeb09
feat: add search in playlist | 增加歌单内搜索 (#450) 2021-03-22 16:24:11 +08:00
qier222
2098170867
chore: update package.json 2021-03-19 14:59:57 +08:00
qier222
752d7cb482
fix: bugs 2021-03-19 14:46:41 +08:00
qier222
7efe109c83
feat: support global shortcuts 2021-03-19 14:24:39 +08:00
Rick
2a9a53a940
fix: Navbar i18n & Github -> GitHub (#443)
* update: Navbar i18n

* update: Github -> GitHub
2021-03-19 09:58:17 +08:00
qier222
849f67d335
fix: bugs 2021-03-19 01:39:08 +08:00
qier222
3bbab6ba27
feat: support daily recommend songs 2021-03-19 01:23:08 +08:00
wenjie
59397ed535
feat: lyrics dynamic background (#424)
* feat: init dynamic background

* feat: another way to achieve

* feat: add setting for dynamic background

* feat: add contrast and brightness for better UI

* fix: remove shadow when exit lyrics

* feat: UI improve, field name change

* refactor: scope variables
2021-03-18 20:54:01 +08:00
qier222
387917e3ee
fix: add version info 2021-03-18 17:40:56 +08:00
qier222
4cbe9f98ce
fix: UX improvement 2021-03-18 17:07:26 +08:00
Vidocq
d69080b695
fix: source and add track name in discord large image text (#437) 2021-03-17 23:15:10 +08:00
wenjie
f656b314f7
docs: use existing script to setup API (#431) 2021-03-17 17:55:31 +08:00
Vidocq
267a678f2a
feat: Add DiscordRichPresence | 增加DiscordRichPresence (#408) 2021-03-16 17:50:22 +08:00
wenjie
0e6c40f32f
docs: add dev readme, format readme with prettier (#422)
* docs: add dev readme, format file

* Update README.md
2021-03-16 12:25:02 +08:00
wenjie
915c828fac
fix: set svg fill to currentColor (#420)
* fix: set svg fill to currentColor

* chore: move eslint to devDependencies
2021-03-16 01:42:29 +08:00
wenjie
ffb782fe0c
chore: set binary type for files (#417) 2021-03-16 01:41:50 +08:00
qier222
42ad13dc3c
fix: bugs 2021-03-12 22:11:49 +08:00
Rick
6b68287e62
feat: Lyric font size adjustment | 歌词字体大小可调节 (#398)
* feat: Lyric font size adjustment | 歌词字体大小可调节
2021-03-12 21:40:28 +08:00
wenjie
52d7a2af26
chore: Feature/prettier eslint (#397)
* feat: add translations

* refactor: use trinocular operators instead if

* style: add prettier to eslint, fix lint errors

* chore: add .gitattr
2021-03-11 15:42:44 +08:00
qier222
a25c874b7d
docs: update README.md 2021-03-09 17:53:36 +08:00
qier222
82c179c9ae
fix(electron): unable to add a song to library 2021-03-08 13:15:55 +08:00
qier222
4b2d5a2b3c
fix: PWA issue 2021-03-08 13:12:36 +08:00
qier222
0adae696cf
fix: bugs 2021-03-08 00:20:27 +08:00
qier222
2cf99fc1e6
docs: update README.md 2021-03-07 17:33:25 +08:00
qier222
89216f2387
chore: update package.json 2021-03-07 20:05:56 +08:00
qier222
ee248be2c5
fix: bugs 2021-03-07 17:31:38 +08:00
qier222
0b701d23da
fix: add netease_api 2021-03-06 22:07:16 +08:00
Vidocq
fc0367c9b4
fix: open microphone whenever enter setting page | 删除获取麦克风权限 (#350)
* fix: bugs

* delete getMediaUser

Co-authored-by: qier222 <qier222@outlook.com>
2021-03-06 21:48:40 +08:00
qier222
ee77b34ee9
fix: bugs 2021-03-06 21:45:33 +08:00
qier222
11eb29b3b8
feat: personal FM (finally🎉) 2021-03-06 18:02:54 +08:00
qier222
e169ee19e2
fix: CORS 2021-03-06 17:08:16 +08:00
qier222
94ef0934a5
fix: revert some code 2021-03-06 17:02:06 +08:00
qier222
6e57766433
fix: audio output device switching outside electron app | 修复输出设备切换
fix: audio output device switching outside electron app | 修复输出设备切换
2021-03-05 15:38:55 +08:00
Vidocq
c96df58dea prettified 2021-03-04 01:17:23 +08:00
Vidocq
bcd05803e2 fix output switching outside electron 2021-03-04 01:16:15 +08:00
qier222
aaa68c5808
feat: Added output devices selection | 增加输出设备选择
Added output devices selection | 增加输出设备选择
2021-03-02 18:14:19 +08:00
Vidocq
498fcf7402 delete useless code 2021-02-26 02:18:18 +08:00
Vidocq
c74c47564e Merge branch 'dev' 2021-02-26 02:13:58 +08:00
Vidocq
7e33afa94d fix media session 2021-02-26 00:00:12 +08:00
Vidocq
bccf52d34a
Fix css and syntax 2021-02-24 03:25:44 +08:00
Vidocq
5223089dc7 add output device switching 2021-02-24 03:14:29 +08:00
Vidocq
970124f70d Merge branch 'dev' 2021-02-24 03:11:53 +08:00
Vidocq
8a30558ac1 add output device switching 2021-02-24 03:07:34 +08:00
qier222
da586ed219
fix: touchbar icon display | 修复 touchbar 图标显示问号
fix: touchbar icon display | 修复 touchbar 图标显示问号
2021-02-23 15:52:34 +08:00
qier222
4831095925
Merge pull request #315 from fengkx/fix/lyric-selection
fix: prevent lyric selection from seeking
2021-02-23 15:23:26 +08:00
mayandev
76c0120e5b Merge remote-tracking branch 'upstream/master' 2021-02-23 15:21:11 +08:00
mayandev
4de69bd647 fix: touchbar icon display 2021-02-23 15:18:52 +08:00
fengkx
b489c847fd
fix: prevent lyric selection from seeking 2021-02-21 23:23:06 +08:00
qier222
39c56af8c1
feat: Add search in playlist #305
Add search in playlist | 增加歌单内的歌曲搜索
2021-02-20 18:02:15 +08:00
Vidocq
25c35c4e79 add search in playlist 2021-02-19 22:27:38 +08:00
Vidocq
bcc1b1e72e add search in playlist 2021-02-19 21:40:43 +08:00
mayandev
733005489f fix(tray.js): delete unused closing brace 2021-02-18 16:51:18 +08:00
qier222
c6ddf9ac3f
chore: use devServer.proxy 2021-02-16 14:22:41 +08:00
qier222
a75c039a40
Merge pull request #285 from MrWillCom/issue-280
Fix ev.target.children.forEach is not a function (#280)
2021-02-14 13:15:02 +08:00
qier222
cf093064e9
Merge pull request #282 from TestGifts/master
拓展托盘菜单项及图标
2021-02-14 13:14:45 +08:00
qier222
3f114dda91
Merge branch 'master' into master 2021-02-14 13:14:28 +08:00
MrWillCom
8db5af5b7a Fix ev.target.children.forEach is not a function (#280) 2021-02-13 14:18:43 +00:00
TestGifts
d425edf7ea 拓展托盘菜单项及图标 2021-02-13 13:14:07 +08:00
TestGifts
b9adf9ef7e 拓展托盘菜单及增加图标 2021-02-13 13:02:46 +08:00
久治明千树汐
0c2098d01f
fix: the missing svg images and a little changes (#279) 2021-02-13 08:23:59 +08:00
Mr. Will
51fc57efe8
为 Windows 平台添加沉浸式标题栏 (#277) 2021-02-12 20:03:01 +08:00
TestGifts
c0c4597cd8
feat: Expand tray menu (#253)
* Expand tray menu

增加了托盘菜单图标及功能

* Revert "Expand tray menu"

This reverts commit ea52c32400.
2021-02-12 15:19:17 +08:00
Mr. Will
1d34aa794f
Update animations for lyrics, panels and tracklists | 为歌词、面板和列表更新动画 (#249)
* Update lyrics scrolling animation

* Remove the useless module imported by mistake

* Auto prettify the changed code

* Update lyrics animation curve and add blur effect to lyrics

* Auto prettify the changed code

* Add initial lyrics blur filter

* Update lyrics blur and fade effect

* Update open and close animation for explore page's panel

* Update tracklist hover animation

* Add scale animation to lyrics

* Auto prettify the changed code

* Update lyrics blur effect with CSS variables

* Support small screen devices for all pages

* Fix paddings for some pages

* Auto prettify the changed code

* Update lyrics page for small screen devices
2021-02-12 15:18:55 +08:00
TestGifts
a473df2afc Revert "Expand tray menu"
This reverts commit ea52c32400.
2021-02-08 20:25:30 +08:00
TestGifts
ea52c32400 Expand tray menu
增加了托盘菜单图标及功能
2021-02-08 20:24:26 +08:00
fengkx
97f2ce043b
fix: description style with newline (#246) 2021-02-07 11:27:49 +08:00
TestGifts
96a90eea25
Update tray.js (#193) 2021-02-03 12:13:28 +08:00
Vanilla
236075a1f8
[+] Install by using Homebrew > README.md (#171) 2021-02-01 10:24:40 +08:00
186 changed files with 20134 additions and 9453 deletions

16
.dockerignore Normal file
View file

@ -0,0 +1,16 @@
node_modules
npm-debug.log
Dockerfile*
docker-compose*
.dockerignore
.git
.github
.gitignore
README.md
LICENSE
.vscode
dist
dist_electron
build
images
script

View file

@ -1,5 +1,7 @@
VUE_APP_NETEASE_API_URL=http://127.0.0.1:3000 VUE_APP_NETEASE_API_URL=/api
VUE_APP_ELECTRON_API_URL=/api VUE_APP_ELECTRON_API_URL=/api
VUE_APP_ELECTRON_API_URL_DEV=http://127.0.0.1:3000 VUE_APP_ELECTRON_API_URL_DEV=http://127.0.0.1:10754
VUE_APP_ENABLE_SENTRY=false VUE_APP_LASTFM_API_KEY=09c55292403d961aa517ff7f5e8a3d9c
DEV_SERVER_PORT=20201 VUE_APP_LASTFM_API_SHARED_SECRET=307c9fda32b3904e53654baff215cb67
DEV_SERVER_PORT=20201

4
.envrc Normal file
View file

@ -0,0 +1,4 @@
source_url "https://raw.githubusercontent.com/cachix/devenv/82c0147677e510b247d8b9165c54f73d32dfd899/direnvrc" "sha256-7u4iDd1nZpxL4tCzmPG0dQgC5V+/44Ba+tHkPob1v2k="
export NIXPKGS_ALLOW_INSECURE=1
use devenv

7
.gitattributes vendored Normal file
View file

@ -0,0 +1,7 @@
* text eol=lf
# Denote all files that are truly binary and should not be modified.
*.png binary
*.jpg binary
*.mp3 binary
*.icns binary
*.gif binary

View file

@ -1,6 +1,15 @@
name: Build/release name: Release
on: [push, pull_request] env:
YARN_INSTALL_NOPT: yarn add --ignore-platform --ignore-optional
on:
push:
branches:
- master
tags:
- v*
workflow_dispatch:
jobs: jobs:
release: release:
@ -8,19 +17,75 @@ jobs:
strategy: strategy:
matrix: matrix:
os: [macos-latest, windows-latest] os: [macos-latest, windows-latest, ubuntu-22.04]
steps: steps:
- name: Check out Git repository - name: Check out Git repository
uses: actions/checkout@v2 uses: actions/checkout@v3
with:
submodules: "recursive"
- name: Install Node.js, NPM and Yarn - name: Install Node.js, NPM and Yarn
uses: actions/setup-node@v1 uses: actions/setup-node@v3
with: with:
node-version: 12.16.3 node-version: 16
cache: 'yarn'
- name: Install RPM & Pacman (on Ubuntu)
if: runner.os == 'Linux'
run: |
sudo apt-get update &&
sudo apt-get install --no-install-recommends -y rpm &&
sudo apt-get install --no-install-recommends -y libarchive-tools &&
sudo apt-get install --no-install-recommends -y libopenjp2-tools
- name: Install Snapcraft (on Ubuntu)
uses: samuelmeuli/action-snapcraft@v1
if: startsWith(matrix.os, 'ubuntu')
with:
snapcraft_token: ${{ secrets.snapcraft_token }}
- id: get_unm_version
name: Get the installed UNM version
run: |
yarn --ignore-optional
unm_version=$(node -e "console.log(require('./node_modules/@unblockneteasemusic/rust-napi/package.json').version)")
echo "::set-output name=unmver::${unm_version}"
shell: bash
- name: Install UNM dependencies for Windows
if: runner.os == 'Windows'
run: |
${{ env.YARN_INSTALL_NOPT }} \
@unblockneteasemusic/rust-napi-win32-x64-msvc@${{steps.get_unm_version.outputs.unmver}}
shell: bash
- name: Install UNM dependencies for macOS
if: runner.os == 'macOS'
run: |
${{ env.YARN_INSTALL_NOPT }} \
@unblockneteasemusic/rust-napi-darwin-x64@${{steps.get_unm_version.outputs.unmver}} \
@unblockneteasemusic/rust-napi-darwin-arm64@${{steps.get_unm_version.outputs.unmver}} \
dmg-license
shell: bash
- name: Install UNM dependencies for Linux
if: runner.os == 'Linux'
run: |
${{ env.YARN_INSTALL_NOPT }} \
@unblockneteasemusic/rust-napi-linux-x64-gnu@${{steps.get_unm_version.outputs.unmver}} \
@unblockneteasemusic/rust-napi-linux-arm64-gnu@${{steps.get_unm_version.outputs.unmver}} \
@unblockneteasemusic/rust-napi-linux-arm-gnueabihf@${{steps.get_unm_version.outputs.unmver}}
shell: bash
- name: Build/release Electron app - name: Build/release Electron app
uses: samuelmeuli/action-electron-builder@v1 uses: samuelmeuli/action-electron-builder@v1.6.0
env:
VUE_APP_NETEASE_API_URL: /api
VUE_APP_ELECTRON_API_URL: /api
VUE_APP_ELECTRON_API_URL_DEV: http://127.0.0.1:10754
VUE_APP_LASTFM_API_KEY: 09c55292403d961aa517ff7f5e8a3d9c
VUE_APP_LASTFM_API_SHARED_SECRET: 307c9fda32b3904e53654baff215cb67
with: with:
# GitHub token, automatically provided to the action # GitHub token, automatically provided to the action
# (No need to define this secret in the repo settings) # (No need to define this secret in the repo settings)
@ -32,14 +97,20 @@ jobs:
use_vue_cli: true use_vue_cli: true
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v3
with: with:
name: YesPlayMusic-mac name: YesPlayMusic-mac
path: dist_electron/*.dmg path: dist_electron/*-universal.dmg
if-no-files-found: ignore if-no-files-found: ignore
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v3
with: with:
name: YesPlayMusic-win name: YesPlayMusic-win
path: dist_electron/*.exe path: dist_electron/*Setup*.exe
if-no-files-found: ignore
- uses: actions/upload-artifact@v3
with:
name: YesPlayMusic-linux
path: dist_electron/*.AppImage
if-no-files-found: ignore if-no-files-found: ignore

48
.github/workflows/sync.yml vendored Normal file
View file

@ -0,0 +1,48 @@
name: Upstream Sync
permissions:
contents: write
issues: write
actions: write
on:
schedule:
- cron: '0 * * * *' # every hour
workflow_dispatch:
jobs:
sync_latest_from_upstream:
name: Sync latest commits from upstream repo
runs-on: ubuntu-latest
if: ${{ github.event.repository.fork }}
steps:
- uses: actions/checkout@v4
- name: Clean issue notice
uses: actions-cool/issues-helper@v3
with:
actions: 'close-issues'
labels: '🚨 Sync Fail'
- name: Sync upstream changes
id: sync
uses: aormsby/Fork-Sync-With-Upstream-action@v3.4
with:
upstream_sync_repo: qier222/YesPlayMusic
upstream_sync_branch: master
target_sync_branch: master
target_repo_token: ${{ secrets.GITHUB_TOKEN }} # automatically generated, no need to set
test_mode: false
- name: Sync check
if: failure()
uses: actions-cool/issues-helper@v3
with:
actions: 'create-issue'
title: '🚨 同步失败 | Sync Fail'
labels: '🚨 Sync Fail'
body: |
Due to a change in the workflow file of the upstream repository, GitHub has automatically suspended the scheduled automatic update. You need to manually sync your fork.
由于上游仓库的 workflow 文件变更,导致 GitHub 自动暂停了本次自动更新,你需要手动 Sync Fork 一次。

16
.gitignore vendored
View file

@ -1,8 +1,6 @@
.DS_Store .DS_Store
node_modules node_modules
/dist /dist
dist_electron
Icon?
# local env files # local env files
.env .env
@ -25,9 +23,21 @@ pnpm-debug.log*
*.sw? *.sw?
.vercel .vercel
/netease_api
#Electron-builder output #Electron-builder output
/dist_electron /dist_electron
NeteaseCloudMusicApi-master NeteaseCloudMusicApi-master
NeteaseCloudMusicApi-master.zip NeteaseCloudMusicApi-master.zip
# Local Netlify folder
.netlify
vercel.json
# Devenv
.devenv*
devenv.local.nix
# direnv
.direnv
# pre-commit
.pre-commit-config.yaml

4
.npmrc
View file

@ -1,4 +0,0 @@
# 如果发现 npm / yarn 安装太慢,可以解除注释
# registry=https://registry.npm.taobao.org/
# ELECTRON_MIRROR=https://npm.taobao.org/mirrors/electron
# phantomjs_cdnurl=https://npm.taobao.org/dist/phantomjs

1
.nvmrc Normal file
View file

@ -0,0 +1 @@
14

View file

@ -1,5 +1,3 @@
build build
coverage coverage
dist dist
netease_api

View file

@ -3,10 +3,9 @@
"tabWidth": 2, "tabWidth": 2,
"useTabs": false, "useTabs": false,
"semi": true, "semi": true,
"singleQuote": false, "singleQuote": true,
"jsxSingleQuote": true, "jsxSingleQuote": true,
"jsxBracketSameLine": false, "arrowParens": "avoid",
"arrowParens": "always",
"endOfLine": "lf", "endOfLine": "lf",
"bracketSpacing": true, "bracketSpacing": true,
"htmlWhitespaceSensitivity": "strict" "htmlWhitespaceSensitivity": "strict"

25
Dockerfile Normal file
View file

@ -0,0 +1,25 @@
FROM node:16.13.1-alpine as build
ENV VUE_APP_NETEASE_API_URL=/api
WORKDIR /app
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories &&\
apk add --no-cache python3 make g++ git
COPY package.json yarn.lock ./
RUN yarn install
COPY . .
RUN yarn config set electron_mirror https://npmmirror.com/mirrors/electron/ && \
yarn build
FROM nginx:1.20.2-alpine as app
COPY --from=build /app/package.json /usr/local/lib/
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories &&\
apk add --no-cache --repository http://dl-cdn.alpinelinux.org/alpine/v3.14/main libuv \
&& apk add --no-cache --update-cache --repository http://dl-cdn.alpinelinux.org/alpine/v3.14/main nodejs npm \
&& npm i -g $(awk -F \" '{if($2=="NeteaseCloudMusicApi") print $2"@"$4}' /usr/local/lib/package.json) \
&& rm -f /usr/local/lib/package.json
COPY --from=build /app/docker/nginx.conf.example /etc/nginx/conf.d/default.conf
COPY --from=build /app/dist /usr/share/nginx/html
CMD nginx ; exec npx NeteaseCloudMusicApi

View file

@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2020 qier222 Copyright (c) 2020-2023 qier222
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.

204
README.md
View file

@ -8,69 +8,221 @@
<p align="center"> <p align="center">
高颜值的第三方网易云播放器 高颜值的第三方网易云播放器
<br /> <br />
<a href="https://music.qier222.com" target="blank"><strong>🌎 访问DEMO</strong></a>&nbsp;&nbsp;|&nbsp;&nbsp; <a href="https://music.ineko.cc" target="blank"><strong>🌎 访问DEMO</strong></a>&nbsp;&nbsp;|&nbsp;&nbsp;
<a href="#%EF%B8%8F-安装" target="blank"><strong>📦️ 下载安装包</strong></a> <a href="#%EF%B8%8F-安装" target="blank"><strong>📦️ 下载安装包</strong></a>&nbsp;&nbsp;|&nbsp;&nbsp;
<a href="https://t.me/yesplaymusic" target="blank"><strong>💬 加入交流群</strong></a>
<br /> <br />
<br /> <br />
</p> </p>
</p> </p>
[![Library][library-screenshot]](https://music.qier222.com) [![Library][library-screenshot]](https://music.ineko.cc)
## 全新版本
全新2.0 Alpha测试版已发布欢迎前往 [Releases](https://github.com/qier222/YesPlayMusic/releases) 页面下载。
当前版本将会进入维护模式除重大bug修复外不会再更新新功能。
## ✨ 特性 ## ✨ 特性
- ✅ 使用 Vue.js 全家桶开发 - ✅ 使用 Vue.js 全家桶开发
- 🔴 网易云账号登录 - 🔴 网易云账号登录(扫码/手机/邮箱登录)
- 📺 MV 播放 - 📺 支持 MV 播放
- 📃 支持歌词显示 - 📃 支持歌词显示
- 📻 支持私人 FM / 每日推荐歌曲
- 🚫🤝 无任何社交功能 - 🚫🤝 无任何社交功能
- 🌎️ 海外用户可直接播放(需要登录网易云账号) - 🌎️ 海外用户可直接播放(需要登录网易云账号)
- 🔐 支持 [UnblockNeteaseMusic](https://github.com/nondanee/UnblockNeteaseMusic),自动使用 QQ/酷狗/酷我音源替换变灰歌曲链接 (网页版不支持) - 🔐 支持 [UnblockNeteaseMusic](https://github.com/UnblockNeteaseMusic/server#音源清单),自动使用[各类音源](https://github.com/UnblockNeteaseMusic/server#音源清单)替换变灰歌曲链接 (网页版不支持)
- ⏭️ 支持 MediaSession API可以使用系统快捷键操作上一首下一首 - 「各类音源」指默认启用的音源。
- YouTube 音源需自行安装 `yt-dlp`
- ✔️ 每日自动签到(手机端和电脑端同时签到) - ✔️ 每日自动签到(手机端和电脑端同时签到)
- 🌚 Light/Dark Mode 自动切换 - 🌚 Light/Dark Mode 自动切换
- 👆 支持 Touch Bar - 👆 支持 Touch Bar
- 🖥️ 支持 PWA可在 Chrome/Edge 里点击地址栏右边的 安装到电脑 - 🖥️ 支持 PWA可在 Chrome/Edge 里点击地址栏右边的 安装到电脑
- 🙉 支持显示歌曲和专辑的 Explicit 标志 - 🟥 支持 Last.fm Scrobble
- ☁️ 支持音乐云盘
- ⌨️ 自定义快捷键和全局快捷键
- 🎧 支持 Mpris
- 🛠 更多特性开发中 - 🛠 更多特性开发中
## 📦️ 安装 ## 📦️ 安装
Electron 版本由 [@hawtim](https://github.com/hawtim) 和 [@qier222](https://github.com/qier222) 适配并维护,支持 macOS、Windows、Linux。 Electron 版本由 [@hawtim](https://github.com/hawtim) 和 [@qier222](https://github.com/qier222) 适配并维护,支持 macOS、Windows、Linux。
访问本项目的 [Releases](https://github.com/qier222/YesPlayMusic/releases) 页面下载安装包,或者访问 [镜像下载站 (大陆访问更快)](https://dl.qier222.com/YesPlayMusic/) 下载。 访问本项目的 [Releases](https://github.com/qier222/YesPlayMusic/releases)
页面下载安装包。
## ⚙️ 部署至服务器 - macOS 用户可以通过 Homebrew 来安装:`brew install --cask yesplaymusic`
除了下载安装包使用,你还可以将本项目部署到你的服务器上。 - Windows 用户可以通过 Scoop 来安装:`scoop install extras/yesplaymusic`
## ⚙️ 部署至 Vercel
除了下载安装包使用,你还可以将本项目部署到 Vercel 或你的服务器上。下面是部署到 Vercel 的方法。
本项目的 Demo (https://music.qier222.com) 就是部署在 Vercel 上的网站。
[![Powered by Vercel](https://www.datocms-assets.com/31049/1618983297-powered-by-vercel.svg)](https://vercel.com/?utm_source=ohmusic&utm_campaign=oss)
1. 部署网易云 API详情参见 [Binaryify/NeteaseCloudMusicApi](https://neteasecloudmusicapi.vercel.app/#/?id=%e5%ae%89%e8%a3%85)
。你也可以将 API 部署到 Vercel。
2. 点击本仓库右上角的 Fork复制本仓库到你的 GitHub 账号。
3. 点击仓库的 Add File选择 Create new file输入 `vercel.json`,将下面的内容复制粘贴到文件中,并将 `https://your-netease-api.example.com` 替换为你刚刚部署的网易云 API 地址:
```json
{
"rewrites": [
{
"source": "/api/:match*",
"destination": "https://your-netease-api.example.com/:match*"
}
]
}
```
4. 打开 [Vercel.com](https://vercel.com),使用 GitHub 登录。
5. 点击 Import Git Repository 并选择你刚刚复制的仓库并点击 Import。
6. 点击 PERSONAL ACCOUNT 旁边的 Select。
7. 点击 Environment Variables填写 Name 为 `VUE_APP_NETEASE_API_URL`Value 为 `/api`,点击 Add。最后点击底部的 Deploy 就可以部署到
Vercel 了。
## ⚙️ 部署到自己的服务器
除了部署到 Vercel你还可以部署到自己的服务器上
1. 部署网易云 API详情参见 [Binaryify/NeteaseCloudMusicApi](https://github.com/Binaryify/NeteaseCloudMusicApi) 1. 部署网易云 API详情参见 [Binaryify/NeteaseCloudMusicApi](https://github.com/Binaryify/NeteaseCloudMusicApi)
2. 克隆本仓库 2. 克隆本仓库
```sh ```sh
git clone https://github.com/qier222/YesPlayMusic.git git clone --recursive https://github.com/qier222/YesPlayMusic.git
``` ```
3. 安装依赖 3. 安装依赖
```sh ```sh
yarn install yarn install
``` ```
4. 复制 `/.env.example` 文件为 `/.env`,修改里面 `VUE_APP_NETEASE_API_URL` 的值为网易云 API 地址。本地开发的话可以填写 API 地址为 `http://localhost:3000`YesPlayMusic 地址为 `http://localhost:8080` 4. (可选)使用 Nginx 反向代理 API将 API 路径映射为 `/api`,如果 API 和网页不在同一个域名下的话(跨域),会有一些 bug。
5. 复制 `/.env.example` 文件为 `/.env`,修改里面 `VUE_APP_NETEASE_API_URL` 的值为网易云 API 地址。本地开发的话可以填写 API 地址为 `http://localhost:3000`YesPlayMusic 地址为 `http://localhost:8080`。如果你使用了反向代理 API可以填写 API 地址为 `/api`
``` ```
VUE_APP_NETEASE_API_URL=http://localhost:3000 VUE_APP_NETEASE_API_URL=http://localhost:3000
``` ```
5. 编译打包 6. 编译打包
```sh ```sh
yarn run build yarn run build
``` ```
6. 将 `/dist` 目录下的文件上传到你的 Web 服务器 7. 将 `/dist` 目录下的文件上传到你的 Web 服务器
## ⚙️ 宝塔面板 docker应用商店 部署
1. 安装宝塔面板,前往[宝塔面板官网](https://www.bt.cn/new/download.html) ,选择正式版的脚本下载安装。
2. 安装后登录宝塔面板,在左侧导航栏中点击 Docker首次进入会提示安装Docker服务点击立即安装按提示完成安装
3. 安装完成后在应用商店中找到YesPlayMusic点击安装配置域名、端口等基本信息即可完成安装。
4. 安装后在浏览器输入上一步骤设置的域名即可访问。
## ⚙️ Docker 部署
1. 构建 Docker Image
```sh
docker build -t yesplaymusic .
```
2. 启动 Docker Container
```sh
docker run -d --name YesPlayMusic -p 80:80 yesplaymusic
```
3. Docker Compose 启动
```sh
docker-compose up -d
```
YesPlayMusic 地址为 `http://localhost`
## ⚙️ 部署至 Replit
1. 新建 Repl选择 Bash 模板
2. 在 Replit shell 中运行以下命令
```sh
bash <(curl -s -L https://raw.githubusercontent.com/qier222/YesPlayMusic/main/install-replit.sh)
```
3. 首次运行成功后,只需点击绿色按钮 `Run` 即可再次运行
4. 由于 replit 个人版限制内存为 1G教育版为 3G构建过程中可能会失败请再次运行上述命令或运行以下命令
```sh
cd /home/runner/${REPL_SLUG}/music && yarn install && yarn run build
```
## 👷‍♂️ 打包客户端
如果在 Release 页面没有找到适合你的设备的安装包的话,你可以根据下面的步骤来打包自己的客户端。
1. 打包 Electron 需要用到 Node.js 和 Yarn。可前往 [Node.js 官网](https://nodejs.org/zh-cn/) 下载安装包。安装 Node.js
后可在终端里执行 `npm install -g yarn` 来安装 Yarn。
2. 使用 `git clone --recursive https://github.com/qier222/YesPlayMusic.git` 克隆本仓库到本地。
3. 使用 `yarn install` 安装项目依赖。
4. 复制 `/.env.example` 文件为 `/.env`
5. 选择下列表格的命令来打包适合的你的安装包,打包出来的文件在 `/dist_electron` 目录下。了解更多信息可访问 [electron-builder 文档](https://www.electron.build/cli)
| 命令 | 说明 |
| ------------------------------------------ | ------------------------- |
| `yarn electron:build --windows nsis:ia32` | Windows 32 位 |
| `yarn electron:build --windows nsis:arm64` | Windows ARM |
| `yarn electron:build --linux deb:armv7l` | Debian armv7l树莓派等 |
| `yarn electron:build --macos dir:arm64` | macOS ARM |
## :computer: 配置开发环境
本项目由 [NeteaseCloudMusicApi](https://github.com/Binaryify/NeteaseCloudMusicApi) 提供 API。
运行本项目
```shell
# 安装依赖
yarn install
# 创建本地环境变量
cp .env.example .env
# 运行(网页端)
yarn serve
# 运行electron
yarn electron:serve
```
本地运行 NeteaseCloudMusicApi或者将 API [部署至 Vercel](#%EF%B8%8F-部署至-vercel)
```shell
# 运行 API (默认 3000 端口)
yarn netease_api:run
```
## ☑️ Todo ## ☑️ Todo
@ -86,6 +238,8 @@ yarn run build
## 灵感来源 ## 灵感来源
API 源代码来自 [Binaryify/NeteaseCloudMusicApi](https://github.com/Binaryify/NeteaseCloudMusicApi)
- [Apple Music](https://music.apple.com) - [Apple Music](https://music.apple.com)
- [YouTube Music](https://music.youtube.com) - [YouTube Music](https://music.youtube.com)
- [Spotify](https://www.spotify.com) - [Spotify](https://www.spotify.com)
@ -93,12 +247,14 @@ yarn run build
## 🖼️ 截图 ## 🖼️ 截图
[![artist][artist-screenshot]](https://music.qier222.com) ![lyrics][lyrics-screenshot]
[![album][album-screenshot]](https://music.qier222.com) ![library-dark][library-dark-screenshot]
[![playlist][playlist-screenshot]](https://music.qier222.com) ![album][album-screenshot]
[![explore][explore-screenshot]](https://music.qier222.com) ![home-2][home-2-screenshot]
[![search][search-screenshot]](https://music.qier222.com) ![artist][artist-screenshot]
[![home][home-screenshot]](https://music.qier222.com) ![search][search-screenshot]
![home][home-screenshot]
![explore][explore-screenshot]
<!-- MARKDOWN LINKS & IMAGES --> <!-- MARKDOWN LINKS & IMAGES -->
<!-- https://www.markdownguide.org/basic-syntax/#reference-style-links --> <!-- https://www.markdownguide.org/basic-syntax/#reference-style-links -->
@ -107,6 +263,8 @@ yarn run build
[artist-screenshot]: images/artist.png [artist-screenshot]: images/artist.png
[explore-screenshot]: images/explore.png [explore-screenshot]: images/explore.png
[home-screenshot]: images/home.png [home-screenshot]: images/home.png
[home-2-screenshot]: images/home-2.png
[lyrics-screenshot]: images/lyrics.png
[library-screenshot]: images/library.png [library-screenshot]: images/library.png
[playlist-screenshot]: images/playlist.png [library-dark-screenshot]: images/library-dark.png
[search-screenshot]: images/search.png [search-screenshot]: images/search.png

View file

@ -1,7 +1,11 @@
module.exports = { module.exports = {
presets: ["@vue/cli-plugin-babel/preset"], presets: [
plugins: [ [
"@babel/plugin-proposal-nullish-coalescing-operator", '@vue/cli-plugin-babel/preset',
"@babel/plugin-proposal-optional-chaining", {
useBuiltIns: 'usage',
shippedProposals: true,
},
],
], ],
}; };

132
devenv.lock Normal file
View file

@ -0,0 +1,132 @@
{
"nodes": {
"devenv": {
"locked": {
"dir": "src/modules",
"lastModified": 1730412360,
"owner": "cachix",
"repo": "devenv",
"rev": "45847cb1f14a6d8cfa86ea943703c54a8798ae7e",
"type": "github"
},
"original": {
"dir": "src/modules",
"owner": "cachix",
"repo": "devenv",
"type": "github"
}
},
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1696426674,
"owner": "edolstra",
"repo": "flake-compat",
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"gitignore": {
"inputs": {
"nixpkgs": [
"pre-commit-hooks",
"nixpkgs"
]
},
"locked": {
"lastModified": 1709087332,
"owner": "hercules-ci",
"repo": "gitignore.nix",
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "gitignore.nix",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1730272153,
"owner": "nixos",
"repo": "nixpkgs",
"rev": "2d2a9ddbe3f2c00747398f3dc9b05f7f2ebb0f53",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-stable": {
"locked": {
"lastModified": 1730327045,
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "080166c15633801df010977d9d7474b4a6c549d7",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-24.05",
"repo": "nixpkgs",
"type": "github"
}
},
"nodejs16": {
"locked": {
"lastModified": 1700230496,
"owner": "nixos",
"repo": "nixpkgs",
"rev": "a71323f68d4377d12c04a5410e214495ec598d4c",
"type": "github"
},
"original": {
"owner": "nixos",
"repo": "nixpkgs",
"rev": "a71323f68d4377d12c04a5410e214495ec598d4c",
"type": "github"
}
},
"pre-commit-hooks": {
"inputs": {
"flake-compat": "flake-compat",
"gitignore": "gitignore",
"nixpkgs": [
"nixpkgs"
],
"nixpkgs-stable": "nixpkgs-stable"
},
"locked": {
"lastModified": 1730302582,
"owner": "cachix",
"repo": "pre-commit-hooks.nix",
"rev": "af8a16fe5c264f5e9e18bcee2859b40a656876cf",
"type": "github"
},
"original": {
"owner": "cachix",
"repo": "pre-commit-hooks.nix",
"type": "github"
}
},
"root": {
"inputs": {
"devenv": "devenv",
"nixpkgs": "nixpkgs",
"nodejs16": "nodejs16",
"pre-commit-hooks": "pre-commit-hooks"
}
}
},
"root": "root",
"version": 7
}

53
devenv.nix Normal file
View file

@ -0,0 +1,53 @@
{ pkgs, lib, config, inputs, ... }:
let
nodejs16 = import inputs.nodejs16 { system = pkgs.stdenv.system; };
in
{
# https://devenv.sh/basics/
env.GREET = "devenv";
# https://devenv.sh/packages/
packages = [ pkgs.git ] ++ lib.optionals pkgs.stdenv.isDarwin (with pkgs.darwin.apple_sdk; [
frameworks.AppKit
]);
# https://devenv.sh/languages/
languages.javascript.enable = true;
languages.javascript.package = nodejs16.pkgs.nodejs_16;
languages.javascript.corepack.enable = true;
# languages.rust.enable = true;
# https://devenv.sh/processes/
# processes.cargo-watch.exec = "cargo-watch";
# https://devenv.sh/services/
# services.postgres.enable = true;
# https://devenv.sh/scripts/
scripts.hello.exec = ''
echo hello from $GREET
'';
enterShell = ''
hello
git --version
'';
# https://devenv.sh/tasks/
# tasks = {
# "myproj:setup".exec = "mytool build";
# "devenv:enterShell".after = [ "myproj:setup" ];
# };
# https://devenv.sh/tests/
enterTest = ''
echo "Running tests"
git --version | grep --color=auto "${pkgs.git.version}"
'';
# https://devenv.sh/pre-commit-hooks/
# pre-commit.hooks.shellcheck.enable = true;
# See full reference at https://devenv.sh/reference/options/
}

19
devenv.yaml Normal file
View file

@ -0,0 +1,19 @@
# yaml-language-server: $schema=https://devenv.sh/devenv.schema.json
inputs:
nixpkgs:
url: github:nixos/nixpkgs/nixpkgs-unstable
nodejs16:
url: github:nixos/nixpkgs/a71323f68d4377d12c04a5410e214495ec598d4c
# https://github.com/cachix/devenv/issues/792#issuecomment-2043166453
impure: true
# If you're using non-OSS software, you can set allowUnfree to true.
# allowUnfree: true
# If you're willing to use a package that's vulnerable
# permittedInsecurePackages:
# - "openssl-1.1.1w"
# If you have more than one devenv you can merge them
#imports:
# - ./backend

39
docker-compose.yml Normal file
View file

@ -0,0 +1,39 @@
services:
YesPlayMusic:
build:
context: .
image: yesplaymusic
container_name: YesPlayMusic
volumes:
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
- ./docker/nginx.conf.example:/etc/nginx/conf.d/default.conf:ro
ports:
- 80:80
restart: always
depends_on:
- UnblockNeteaseMusic
environment:
- NODE_TLS_REJECT_UNAUTHORIZED=0
networks:
my_network:
UnblockNeteaseMusic:
image: pan93412/unblock-netease-music-enhanced
command: -o kugou kuwo migu bilibili pyncmd -p 80:443 -f 45.127.129.53 -e -
# environment:
# JSON_LOG: true
# LOG_LEVEL: debug
networks:
my_network:
aliases:
- music.163.com
- interface.music.163.com
- interface3.music.163.com
- interface.music.163.com.163jiasu.com
- interface3.music.163.com.163jiasu.com
restart: always
networks:
my_network:
driver: bridge

28
docker/nginx.conf.example Normal file
View file

@ -0,0 +1,28 @@
server {
gzip on;
listen 80;
listen [::]:80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html;
try_files $uri $uri/ /index.html;
}
location @rewrites {
rewrite ^(.*)$ /index.html last;
}
location /api/ {
proxy_buffers 16 32k;
proxy_buffer_size 128k;
proxy_busy_buffers_size 128k;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Host $remote_addr;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://localhost:3000/;
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 804 KiB

After

Width:  |  Height:  |  Size: 253 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 730 KiB

After

Width:  |  Height:  |  Size: 228 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

After

Width:  |  Height:  |  Size: 354 KiB

Before After
Before After

BIN
images/home-2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 312 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

After

Width:  |  Height:  |  Size: 389 KiB

Before After
Before After

BIN
images/library-dark.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 335 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 324 KiB

Before After
Before After

BIN
images/lyrics.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 339 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1 MiB

After

Width:  |  Height:  |  Size: 276 KiB

Before After
Before After

28
install-replit.sh Normal file
View file

@ -0,0 +1,28 @@
#!/usr/bin/bash
# 初始化 .replit 和 replit.nix
if [[ $1 == i ]];then
echo -e 'run = ["bash", "main.sh"]\n\nentrypoint = "main.sh"' >.replit
echo -e "{ pkgs }: {\n\t\tdeps = [\n\t\t\tpkgs.nodejs-16_x\n\t\t\tpkgs.yarn\n\t\t\tpkgs.bashInteractive\n\t\t];\n}" > replit.nix
exit
fi
# 安装
if [[ ! -d api ]];then
mkdir api
git clone https://github.com/Binaryify/NeteaseCloudMusicApi ./api && \
cd api && npm install && cd ..
fi
if [[ ! -d music ]];then
mkdir music
git clone https://github.com/qier222/YesPlayMusic ./music && \
cd music && cp .env.example .env && npm install --force && npm run build && cd ..
fi
# 启动
PID=`ps -ef | grep npm | awk '{print $2}' | sed '$d'`
if [[ ! -z ${PID} ]];then echo $PID | xargs kill;fi
nohup bash -c 'cd api && PORT=35216 node app.js' > api.log 2>&1
nohup bash -c 'npx serve music/dist/' > music.log 2>&1

View file

@ -7,7 +7,8 @@
}, },
"target": "ES6", "target": "ES6",
"module": "commonjs", "module": "commonjs",
"allowSyntheticDefaultImports": true "allowSyntheticDefaultImports": true,
"jsx": "preserve"
}, },
"include": ["src/**/*"], "include": ["src/**/*"],
"exclude": ["node_modules"] "exclude": ["node_modules"]

View file

@ -1,9 +1,9 @@
{ {
"name": "YesPlayMusic", "name": "yesplaymusic",
"version": "0.3.3", "version": "0.4.9",
"private": true, "private": true,
"description": "A third party music application for Netease Music", "description": "A third party music player for Netease Music",
"author": "hawtim<hawtimzhang@gmail.com>", "author": "qier222<qier222@outlook.com>",
"scripts": { "scripts": {
"serve": "vue-cli-service serve", "serve": "vue-cli-service serve",
"build": "vue-cli-service build", "build": "vue-cli-service build",
@ -18,57 +18,68 @@
"electron:publish": "vue-cli-service electron:build -mwl -p always", "electron:publish": "vue-cli-service electron:build -mwl -p always",
"postinstall": "electron-builder install-app-deps", "postinstall": "electron-builder install-app-deps",
"postuninstall": "electron-builder install-app-deps", "postuninstall": "electron-builder install-app-deps",
"prettier": "npx prettier --write ./src ./script", "prettier": "npx prettier --write ./src",
"netease_api:run": "cd ./netease_api && npm run start", "netease_api:run": "npx NeteaseCloudMusicApi"
"netease_api:pull": "node script/pull.js",
"netease_api:install": "cd ./netease_api && npm install",
"netease_api:setup": "npm run netease_api:pull && npm run netease_api:install"
}, },
"main": "background.js", "main": "background.js",
"engines": {
"node": "14 || 16"
},
"dependencies": { "dependencies": {
"@njzy/unblockneteasemusic": "^0.25.3", "@unblockneteasemusic/rust-napi": "^0.4.0",
"axios": "^0.21.0", "NeteaseCloudMusicApi": "^4.23.3",
"big-integer": "^1.6.48", "axios": "^0.26.1",
"change-case": "^4.1.2", "change-case": "^4.1.2",
"cli-color": "^2.0.0",
"color": "^4.2.3",
"core-js": "^3.6.5", "core-js": "^3.6.5",
"crypto-js": "^4.0.0", "crypto-js": "^4.0.0",
"dayjs": "^1.8.36", "dayjs": "^1.8.36",
"electron": "11.0.2", "dexie": "^3.0.3",
"electron-context-menu": "^2.3.0", "discord-rich-presence": "^0.0.8",
"electron": "^13.6.7",
"electron-builder": "^23.0.0",
"electron-context-menu": "^3.1.2",
"electron-debug": "^3.1.0", "electron-debug": "^3.1.0",
"electron-devtools-installer": "^3.1.1", "electron-devtools-installer": "^3.2",
"electron-icon-builder": "^1.0.2", "electron-icon-builder": "^2.0.1",
"electron-is-dev": "^1.2.0", "electron-is-dev": "^2.0.0",
"electron-log": "^4.3.0", "electron-log": "^4.3.0",
"electron-store": "^6.0.1", "electron-store": "^8.0.1",
"electron-updater": "^4.3.5", "electron-updater": "^5.0.1",
"esbuild": "^0.20.1",
"esbuild-loader": "^4.0.3",
"express": "^4.17.1", "express": "^4.17.1",
"express-fileupload": "^1.2.0", "express-fileupload": "^1.2.0",
"express-http-proxy": "^1.6.2", "express-http-proxy": "^1.6.2",
"extract-zip": "^2.0.1", "extract-zip": "^2.0.1",
"howler": "^2.2.0", "howler": "^2.2.3",
"js-cookie": "^2.2.1", "js-cookie": "^2.2.1",
"localforage": "^1.9.0", "jsbi": "^4.1.0",
"lodash": "^4.17.20", "lodash": "^4.17.20",
"md5": "^2.3.0",
"mpris-service": "^2.1.2",
"music-metadata": "^7.5.3",
"node-vibrant": "^3.2.1-alpha.1",
"nprogress": "^0.2.0", "nprogress": "^0.2.0",
"pac-proxy-agent": "^4.1.0", "pac-proxy-agent": "^4.1.0",
"plyr": "^3.6.2", "plyr": "^3.6.2",
"prettier": "2.1.2", "qrcode": "^1.4.4",
"register-service-worker": "^1.7.1", "register-service-worker": "^1.7.1",
"svg-sprite-loader": "^5.0.0", "svg-sprite-loader": "^6.0.11",
"tunnel": "^0.0.6", "tunnel": "^0.0.6",
"vscode-codicons": "^0.0.17",
"vue": "^2.6.11", "vue": "^2.6.11",
"vue-analytics": "^5.22.1", "vue-clipboard2": "^0.3.1",
"vue-electron": "^1.0.6", "vue-gtag": "1",
"vue-i18n": "^8.22.0", "vue-i18n": "^8.22.0",
"vue-router": "^3.4.3", "vue-router": "^3.4.3",
"vue-slider-component": "^3.2.5", "vue-slider-component": "^3.2.5",
"vuex": "^3.4.0" "vuex": "^3.4.0",
"x11": "^2.3.0"
}, },
"devDependencies": { "devDependencies": {
"@sentry/browser": "^5.27.0", "@types/node": "^17.0.0",
"@sentry/integrations": "^5.27.0",
"@sentry/tracing": "^5.27.0",
"@vue/cli-plugin-babel": "~4.5.0", "@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0", "@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-plugin-pwa": "~4.5.0", "@vue/cli-plugin-pwa": "~4.5.0",
@ -76,13 +87,21 @@
"@vue/cli-service": "~4.5.0", "@vue/cli-service": "~4.5.0",
"babel-eslint": "^10.1.0", "babel-eslint": "^10.1.0",
"eslint": "^6.7.2", "eslint": "^6.7.2",
"eslint-plugin-vue": "^6.2.2", "eslint-config-prettier": "^8.1.0",
"eslint-plugin-prettier": "^3.3.1",
"eslint-plugin-vue": "^7.9.0",
"husky": "^4.3.0", "husky": "^4.3.0",
"prettier": "2.5.1",
"sass": "^1.26.11", "sass": "^1.26.11",
"sass-loader": "^10.0.2", "sass-loader": "^10.0.2",
"vue-cli-plugin-electron-builder": "~2.0.0-rc.4", "vue-cli-plugin-electron-builder": "~2.1.1",
"vue-template-compiler": "^2.6.11" "vue-template-compiler": "^2.6.11"
}, },
"resolutions": {
"icon-gen": "3.0.0",
"degenerator": "2.2.0",
"electron-builder": "^23.0.0"
},
"eslintConfig": { "eslintConfig": {
"root": true, "root": true,
"env": { "env": {
@ -91,6 +110,8 @@
}, },
"extends": [ "extends": [
"plugin:vue/essential", "plugin:vue/essential",
"plugin:vue/recommended",
"plugin:prettier/recommended",
"eslint:recommended" "eslint:recommended"
], ],
"parserOptions": { "parserOptions": {

BIN
public/img/icons/exit.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 B

BIN
public/img/icons/left.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 B

BIN
public/img/icons/like.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 308 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Before After
Before After

BIN
public/img/icons/pause.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 953 B

BIN
public/img/icons/play.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 396 B

BIN
public/img/icons/repeat.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 B

BIN
public/img/icons/right.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 B

BIN
public/img/icons/unlike.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 932 B

BIN
public/img/logos/lastfm.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 816 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 750 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 801 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 779 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 871 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 855 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 656 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 610 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 499 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 746 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -1,23 +1,25 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="referrer" content="no-referrer" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<link rel="icon" href="<%= BASE_URL %>favicon.ico" />
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body> <head>
<noscript> <meta charset="utf-8" />
<strong <meta http-equiv="X-UA-Compatible" content="IE=edge" />
>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work <meta name="referrer" content="no-referrer" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="<%= BASE_URL %>favicon.ico" />
<title>
<%= htmlWebpackPlugin.options.title %>
</title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work
properly without JavaScript enabled. Please enable it to properly without JavaScript enabled. Please enable it to
continue.</strong continue.</strong>
> </noscript>
</noscript> <div id="app"></div>
<div id="app"></div> <!-- built files will be auto injected -->
<!-- built files will be auto injected --> </body>
</body>
</html> </html>

View file

@ -1,2 +1,2 @@
User-agent: * User-agent: *
Disallow: Disallow: /

7
restyled.yml Normal file
View file

@ -0,0 +1,7 @@
commit_template: 'style: with ${restyler.name}'
restylers:
- prettier
- prettier-json
- prettier-markdown
- prettier-yaml
- whitespace

View file

@ -1,103 +0,0 @@
// node module
const fs = require("fs");
const https = require("https");
const resolve = require("path").resolve;
const join = require("path").resolve;
const extract = require("extract-zip");
// 函数参数
const dest = resolve(__dirname, "../");
const fileName = "NeteaseCloudMusicApi-master.zip";
const options = {
hostname: "github.91chifun.workers.dev",
path: `//https://github.com/Binaryify/NeteaseCloudMusicApi/archive/master.zip`,
};
// 完整的流程控制
/**
* 1. 检查本地文件是否已有
* 2. 下载默认/指定版本的 zip 压缩包等待下载
* 3. 解压缩
* 4. 进入目录安装依赖 npm install
*/
function fix2(number) {
return number.toFixed(2);
}
async function download(options, fileName, callback) {
return await new Promise((resolve, reject) => {
const destPath = join(__dirname, "../" + fileName);
// Check if exist
if (fs.existsSync(destPath)) return resolve(destPath);
const file = fs.createWriteStream(destPath);
const request = https.get(options, (res) => {
let len = res.headers && parseInt(res.headers["content-length"], 10);
let cur = 0;
// 1048576 - bytes in 1Megabyte
const MEGA = 1048576;
let total = 0;
if (len) {
total = len / MEGA;
}
if (!len) {
console.log(
"Downloading, but can not get content-length, please be patient."
);
}
res.on("data", (chunk) => {
if (len) {
cur += chunk.length;
console.log(
`Downloading ${fix2((100.0 * cur) / len)}% ${fix2(
cur / MEGA
)}/${fix2(total)}mb`
);
}
});
res.on("end", () => {
callback("Downloading complete!");
});
res.pipe(file);
file.on("finish", () => {
file.close(() => {
callback("File wrote complete!");
resolve(destPath);
});
});
file.on("error", (err) => {
fs.unlink(destPath);
reject(err);
});
request.on("error", (err) => {
console.log("Error: " + err.message);
});
});
});
}
async function unzip(source, target) {
try {
await extract(source, {
dir: target,
});
console.log("Extraction complete");
return true;
} catch (err) {
// handle any errors
if (err.message === "end of central directory record signature not found") {
console.log("Not a full_downloaded zip file, removed!");
fs.unlinkSync(source);
}
return false;
}
}
// Download process
download(options, fileName, (text) => {
console.log(text);
}).then((path) => {
console.log(path);
// Unzip process
return unzip(path, dest);
});

View file

@ -1,39 +1,43 @@
<template> <template>
<div id="app"> <div id="app" :class="{ 'user-select-none': userSelectNone }">
<Navbar ref="navbar" /> <Scrollbar v-show="!showLyrics" ref="scrollbar" />
<main v-show="!this.$store.state.showLyrics"> <Navbar v-show="showNavbar" ref="navbar" />
<main
ref="main"
:style="{ overflow: enableScrolling ? 'auto' : 'hidden' }"
@scroll="handleScroll"
>
<keep-alive> <keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view> <router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive> </keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view> <router-view v-if="!$route.meta.keepAlive"></router-view>
</main> </main>
<transition name="slide-up"> <transition name="slide-up">
<Player <Player v-if="enablePlayer" v-show="showPlayer" ref="player" />
v-if="this.$store.state.player.enabled" </transition>
ref="player"
v-show="showPlayer"
/></transition>
<Toast /> <Toast />
<ModalAddTrackToPlaylist v-if="isAccountLoggedIn" /> <ModalAddTrackToPlaylist v-if="isAccountLoggedIn" />
<ModalNewPlaylist v-if="isAccountLoggedIn" /> <ModalNewPlaylist v-if="isAccountLoggedIn" />
<transition name="slide-up" v-if="this.$store.state.player.enabled"> <transition v-if="enablePlayer" name="slide-up">
<Lyrics v-show="this.$store.state.showLyrics" /> <Lyrics v-show="showLyrics" />
</transition> </transition>
</div> </div>
</template> </template>
<script> <script>
import ModalAddTrackToPlaylist from "./components/ModalAddTrackToPlaylist.vue"; import ModalAddTrackToPlaylist from './components/ModalAddTrackToPlaylist.vue';
import ModalNewPlaylist from "./components/ModalNewPlaylist.vue"; import ModalNewPlaylist from './components/ModalNewPlaylist.vue';
import Navbar from "./components/Navbar.vue"; import Scrollbar from './components/Scrollbar.vue';
import Player from "./components/Player.vue"; import Navbar from './components/Navbar.vue';
import Toast from "./components/Toast.vue"; import Player from './components/Player.vue';
import { ipcRenderer } from "./electron/ipcRenderer"; import Toast from './components/Toast.vue';
import { isAccountLoggedIn } from "@/utils/auth"; import { ipcRenderer } from './electron/ipcRenderer';
import Lyrics from "./views/lyrics.vue"; import { isAccountLoggedIn, isLooseLoggedIn } from '@/utils/auth';
import Lyrics from './views/lyrics.vue';
import { mapState } from 'vuex';
export default { export default {
name: "App", name: 'App',
components: { components: {
Navbar, Navbar,
Player, Player,
@ -41,163 +45,104 @@ export default {
ModalAddTrackToPlaylist, ModalAddTrackToPlaylist,
ModalNewPlaylist, ModalNewPlaylist,
Lyrics, Lyrics,
Scrollbar,
}, },
data() { data() {
return { return {
isElectron: process.env.IS_ELECTRON, // true || undefined isElectron: process.env.IS_ELECTRON, // true || undefined
userSelectNone: false,
}; };
}, },
computed: { computed: {
...mapState(['showLyrics', 'settings', 'player', 'enableScrolling']),
isAccountLoggedIn() { isAccountLoggedIn() {
return isAccountLoggedIn(); return isAccountLoggedIn();
}, },
showPlayer() { showPlayer() {
return ( return (
["mv", "loginUsername", "login", "loginAccount"].includes( [
this.$route.name 'mv',
) === false 'loginUsername',
'login',
'loginAccount',
'lastfmCallback',
].includes(this.$route.name) === false
); );
}, },
enablePlayer() {
return this.player.enabled && this.$route.name !== 'lastfmCallback';
},
showNavbar() {
return this.$route.name !== 'lastfmCallback';
},
}, },
created() { created() {
if (this.isElectron) { if (this.isElectron) ipcRenderer(this);
ipcRenderer(this); window.addEventListener('keydown', this.handleKeydown);
} this.fetchData();
window.addEventListener("keydown", this.handleKeydown);
}, },
methods: { methods: {
handleKeydown(e) { handleKeydown(e) {
if (e.code === "Space") { if (e.code === 'Space') {
if (e.target.tagName === "INPUT") return false; if (e.target.tagName === 'INPUT') return false;
if (this.$route.name === "mv") return false; if (this.$route.name === 'mv') return false;
e.preventDefault(); e.preventDefault();
this.$refs.player.play(); this.player.playOrPause();
} }
}, },
fetchData() {
if (!isLooseLoggedIn()) return;
this.$store.dispatch('fetchLikedSongs');
this.$store.dispatch('fetchLikedSongsWithDetails');
this.$store.dispatch('fetchLikedPlaylist');
if (isAccountLoggedIn()) {
this.$store.dispatch('fetchLikedAlbums');
this.$store.dispatch('fetchLikedArtists');
this.$store.dispatch('fetchLikedMVs');
this.$store.dispatch('fetchCloudDisk');
}
},
handleScroll() {
this.$refs.scrollbar.handleScroll();
},
}, },
}; };
</script> </script>
<style lang="scss"> <style lang="scss">
@import url("https://fonts.googleapis.com/css2?family=Barlow:ital,wght@0,500;0,600;0,700;0,800;0,900;1,500;1,600;1,700;1,800;1,900&display=swap");
:root {
--color-body-bg: #ffffff;
--color-text: #000;
--color-primary: #335eea;
--color-primary-bg: #eaeffd;
--color-secondary: #7a7a7b;
--color-secondary-bg: #f5f5f7;
--color-navbar-bg: rgba(255, 255, 255, 0.86);
--color-primary-bg-for-transparent: rgba(189, 207, 255, 0.28);
--color-secondary-bg-for-transparent: rgba(209, 209, 214, 0.28);
}
[data-theme="dark"] {
--color-body-bg: #222222;
--color-text: #ffffff;
--color-primary: #335eea;
--color-primary-bg: #bbcdff;
--color-secondary: #7a7a7b;
--color-secondary-bg: #323232;
--color-navbar-bg: rgba(34, 34, 34, 0.86);
--color-primary-bg-for-transparent: rgba(255, 255, 255, 0.12);
--color-secondary-bg-for-transparent: rgba(255, 255, 255, 0.08);
}
#app { #app {
width: 100%; width: 100%;
transition: all 0.4s; transition: all 0.4s;
} }
#app,
input {
font-family: "Barlow", -apple-system, BlinkMacSystemFont, Helvetica Neue,
PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC,
WenQuanYi Micro Hei, sans-serif;
}
body {
background-color: var(--color-body-bg);
}
html {
overflow-y: overlay;
min-width: 768px;
}
main { main {
margin-top: 84px; position: fixed;
margin-bottom: 96px; top: 0;
padding: { bottom: 0;
right: 10vw; right: 0;
left: 10vw; left: 0;
} overflow: auto;
padding: 64px 10vw 96px 10vw;
box-sizing: border-box;
scrollbar-width: none; // firefox
} }
@media (max-width: 1336px) { @media (max-width: 1336px) {
main { main {
padding: 0 5vw; padding: 64px 5vw 96px 5vw;
} }
} }
select, main::-webkit-scrollbar {
button { width: 0px;
font-family: inherit;
}
button {
background: none;
border: none;
cursor: pointer;
}
input,
button {
&:focus {
outline: none;
}
}
a {
color: inherit;
text-decoration: none;
cursor: pointer;
&:hover {
text-decoration: underline;
}
}
/* Let's get this party started */
::-webkit-scrollbar {
width: 8px;
}
::-webkit-scrollbar-track {
background: transparent;
border-left: 1px solid rgba(128, 128, 128, 0.18);
background: var(--color-body-bg);
}
::-webkit-scrollbar-thumb {
-webkit-border-radius: 10px;
border-radius: 10px;
background: rgba(128, 128, 128, 0.38);
}
[data-theme="dark"] ::-webkit-scrollbar-thumb {
background: var(--color-secondary-bg);
} }
.slide-up-enter-active, .slide-up-enter-active,
.slide-up-leave-active { .slide-up-leave-active {
transition: all 0.4s; transition: transform 0.4s;
} }
.slide-up-enter, .slide-up-leave-to /* .fade-leave-active below version 2.1.8 */ { .slide-up-enter,
.slide-up-leave-to {
transform: translateY(100%); transform: translateY(100%);
} }
[data-electron="yes"] {
button,
.navigation-links a,
.playlist-info .description {
cursor: default !important;
}
}
</style> </style>

View file

@ -1,5 +1,6 @@
import request from "@/utils/request"; import request from '@/utils/request';
import { mapTrackPlayableStatus } from "@/utils/common"; import { mapTrackPlayableStatus } from '@/utils/common';
import { cacheAlbum, getAlbumFromCache } from '@/utils/db';
/** /**
* 获取专辑内容 * 获取专辑内容
@ -7,15 +8,23 @@ import { mapTrackPlayableStatus } from "@/utils/common";
* @param {number} id * @param {number} id
*/ */
export function getAlbum(id) { export function getAlbum(id) {
return request({ const fetchLatest = () => {
url: "/album", return request({
method: "get", url: '/album',
params: { method: 'get',
id, params: {
}, id,
}).then((data) => { },
data.songs = mapTrackPlayableStatus(data.songs); }).then(data => {
return data; cacheAlbum(id, data);
data.songs = mapTrackPlayableStatus(data.songs);
return data;
});
};
fetchLatest();
return getAlbumFromCache(id).then(result => {
return result ?? fetchLatest();
}); });
} }
@ -32,8 +41,8 @@ export function getAlbum(id) {
*/ */
export function newAlbums(params) { export function newAlbums(params) {
return request({ return request({
url: "/album/new", url: '/album/new',
method: "get", method: 'get',
params, params,
}); });
} }
@ -46,8 +55,8 @@ export function newAlbums(params) {
*/ */
export function albumDynamicDetail(id) { export function albumDynamicDetail(id) {
return request({ return request({
url: "/album/detail/dynamic", url: '/album/detail/dynamic',
method: "get", method: 'get',
params: { id, timestamp: new Date().getTime() }, params: { id, timestamp: new Date().getTime() },
}); });
} }
@ -63,8 +72,8 @@ export function albumDynamicDetail(id) {
*/ */
export function likeAAlbum(params) { export function likeAAlbum(params) {
return request({ return request({
url: "/album/sub", url: '/album/sub',
method: "post", method: 'post',
params, params,
}); });
} }

View file

@ -1,5 +1,7 @@
import request from "@/utils/request"; import request from '@/utils/request';
import { mapTrackPlayableStatus } from "@/utils/common"; import { mapTrackPlayableStatus } from '@/utils/common';
import { isAccountLoggedIn } from '@/utils/auth';
import { getTrackDetail } from '@/api/track';
/** /**
* 获取歌手单曲 * 获取歌手单曲
@ -8,13 +10,19 @@ import { mapTrackPlayableStatus } from "@/utils/common";
*/ */
export function getArtist(id) { export function getArtist(id) {
return request({ return request({
url: "/artists", url: '/artists',
method: "get", method: 'get',
params: { params: {
id, id,
timestamp: new Date().getTime(), timestamp: new Date().getTime(),
}, },
}).then((data) => { }).then(async data => {
if (!isAccountLoggedIn()) {
const trackIDs = data.hotSongs.map(t => t.id);
const tracks = await getTrackDetail(trackIDs.join(','));
data.hotSongs = tracks.songs;
return data;
}
data.hotSongs = mapTrackPlayableStatus(data.hotSongs); data.hotSongs = mapTrackPlayableStatus(data.hotSongs);
return data; return data;
}); });
@ -33,8 +41,8 @@ export function getArtist(id) {
*/ */
export function getArtistAlbum(params) { export function getArtistAlbum(params) {
return request({ return request({
url: "/artist/album", url: '/artist/album',
method: "get", method: 'get',
params, params,
}); });
} }
@ -50,12 +58,14 @@ export function getArtistAlbum(params) {
* @param {number=} type * @param {number=} type
*/ */
export function toplistOfArtists(type = null) { export function toplistOfArtists(type = null) {
let params = {};
if (type) {
params.type = type;
}
return request({ return request({
url: "/toplist/artist", url: '/toplist/artist',
method: "get", method: 'get',
params: { params,
type,
},
}); });
} }
/** /**
@ -67,8 +77,8 @@ export function toplistOfArtists(type = null) {
*/ */
export function artistMv(params) { export function artistMv(params) {
return request({ return request({
url: "/artist/mv", url: '/artist/mv',
method: "get", method: 'get',
params, params,
}); });
} }
@ -84,8 +94,8 @@ export function artistMv(params) {
*/ */
export function followAArtist(params) { export function followAArtist(params) {
return request({ return request({
url: "/artist/sub", url: '/artist/sub',
method: "post", method: 'post',
params, params,
}); });
} }
@ -98,8 +108,8 @@ export function followAArtist(params) {
*/ */
export function similarArtists(id) { export function similarArtists(id) {
return request({ return request({
url: "/simi/artist", url: '/simi/artist',
method: "post", method: 'post',
params: { id }, params: { id },
}); });
} }

View file

@ -1,4 +1,4 @@
import request from "@/utils/request"; import request from '@/utils/request';
/** /**
* 手机登录 * 手机登录
@ -14,11 +14,12 @@ import request from "@/utils/request";
*/ */
export function loginWithPhone(params) { export function loginWithPhone(params) {
return request({ return request({
url: "/login/cellphone", url: '/login/cellphone',
method: "post", method: 'post',
params, params,
}); });
} }
/** /**
* 邮箱登录 * 邮箱登录
* - email: 163 网易邮箱 * - email: 163 网易邮箱
@ -31,12 +32,60 @@ export function loginWithPhone(params) {
*/ */
export function loginWithEmail(params) { export function loginWithEmail(params) {
return request({ return request({
url: "/login", url: '/login',
method: "post", method: 'post',
params, params,
}); });
} }
/**
* 二维码key生成接口
*/
export function loginQrCodeKey() {
return request({
url: '/login/qr/key',
method: 'get',
params: {
timestamp: new Date().getTime(),
},
});
}
/**
* 二维码生成接口
* 说明: 调用此接口传入上一个接口生成的key可生成二维码图片的base64和二维码信息,
* 可使用base64展示图片,或者使用二维码信息内容自行使用第三方二维码生产库渲染二维码
* @param {Object} params
* @param {string} params.key
* @param {string=} params.qrimg 传入后会额外返回二维码图片base64编码
*/
export function loginQrCodeCreate(params) {
return request({
url: '/login/qr/create',
method: 'get',
params: {
...params,
timestamp: new Date().getTime(),
},
});
}
/**
* 二维码检测扫码状态接口
* 说明: 轮询此接口可获取二维码扫码状态,800为二维码过期,801为等待扫码,802为待确认,803为授权登录成功(803状态码下会返回cookies)
* @param {string} key
*/
export function loginQrCodeCheck(key) {
return request({
url: '/login/qr/check',
method: 'get',
params: {
key,
timestamp: new Date().getTime(),
},
});
}
/** /**
* 刷新登录 * 刷新登录
* 说明 : 调用此接口 , 可刷新登录状态 * 说明 : 调用此接口 , 可刷新登录状态
@ -44,8 +93,8 @@ export function loginWithEmail(params) {
*/ */
export function refreshCookie() { export function refreshCookie() {
return request({ return request({
url: "/login/refresh", url: '/login/refresh',
method: "post", method: 'post',
}); });
} }
@ -55,7 +104,7 @@ export function refreshCookie() {
*/ */
export function logout() { export function logout() {
return request({ return request({
url: "/logout", url: '/logout',
method: "post", method: 'post',
}); });
} }

80
src/api/lastfm.js Normal file
View file

@ -0,0 +1,80 @@
// Last.fm API documents 👉 https://www.last.fm/api
import axios from 'axios';
import md5 from 'crypto-js/md5';
const apiKey = process.env.VUE_APP_LASTFM_API_KEY;
const apiSharedSecret = process.env.VUE_APP_LASTFM_API_SHARED_SECRET;
const baseUrl = window.location.origin;
const url = 'https://ws.audioscrobbler.com/2.0/';
const sign = params => {
const sortParamsKeys = Object.keys(params).sort();
const sortedParams = sortParamsKeys.reduce((acc, key) => {
acc[key] = params[key];
return acc;
}, {});
let signature = '';
for (const [key, value] of Object.entries(sortedParams)) {
signature += `${key}${value}`;
}
return md5(signature + apiSharedSecret).toString();
};
export function auth() {
const url = process.env.IS_ELECTRON
? `https://www.last.fm/api/auth/?api_key=${apiKey}&cb=${baseUrl}/#/lastfm/callback`
: `https://www.last.fm/api/auth/?api_key=${apiKey}&cb=${baseUrl}/lastfm/callback`;
window.open(url);
}
export function authGetSession(token) {
const signature = md5(
`api_key${apiKey}methodauth.getSessiontoken${token}${apiSharedSecret}`
).toString();
return axios({
url,
method: 'GET',
params: {
method: 'auth.getSession',
format: 'json',
api_key: apiKey,
api_sig: signature,
token,
},
});
}
export function trackUpdateNowPlaying(params) {
params.api_key = apiKey;
params.method = 'track.updateNowPlaying';
params.sk = JSON.parse(localStorage.getItem('lastfm'))['key'];
const signature = sign(params);
return axios({
url,
method: 'POST',
params: {
...params,
api_sig: signature,
format: 'json',
},
});
}
export function trackScrobble(params) {
params.api_key = apiKey;
params.method = 'track.scrobble';
params.sk = JSON.parse(localStorage.getItem('lastfm'))['key'];
const signature = sign(params);
return axios({
url,
method: 'POST',
params: {
...params,
api_sig: signature,
format: 'json',
},
});
}

View file

@ -1,4 +1,4 @@
import request from "@/utils/request"; import request from '@/utils/request';
/** /**
* 获取 mv 数据 * 获取 mv 数据
@ -9,8 +9,8 @@ import request from "@/utils/request";
*/ */
export function mvDetail(mvid) { export function mvDetail(mvid) {
return request({ return request({
url: "/mv/detail", url: '/mv/detail',
method: "get", method: 'get',
params: { params: {
mvid, mvid,
timestamp: new Date().getTime(), timestamp: new Date().getTime(),
@ -30,8 +30,8 @@ export function mvDetail(mvid) {
*/ */
export function mvUrl(params) { export function mvUrl(params) {
return request({ return request({
url: "/mv/url", url: '/mv/url',
method: "get", method: 'get',
params, params,
}); });
} }
@ -43,8 +43,8 @@ export function mvUrl(params) {
*/ */
export function simiMv(mvid) { export function simiMv(mvid) {
return request({ return request({
url: "/simi/mv", url: '/simi/mv',
method: "get", method: 'get',
params: { mvid }, params: { mvid },
}); });
} }
@ -62,8 +62,8 @@ export function simiMv(mvid) {
export function likeAMV(params) { export function likeAMV(params) {
params.timestamp = new Date().getTime(); params.timestamp = new Date().getTime();
return request({ return request({
url: "/mv/sub", url: '/mv/sub',
method: "post", method: 'post',
params, params,
}); });
} }

View file

@ -1,5 +1,5 @@
import request from "@/utils/request"; import request from '@/utils/request';
import { mapTrackPlayableStatus } from "@/utils/common"; import { mapTrackPlayableStatus } from '@/utils/common';
/** /**
* 搜索 * 搜索
@ -18,12 +18,33 @@ import { mapTrackPlayableStatus } from "@/utils/common";
*/ */
export function search(params) { export function search(params) {
return request({ return request({
url: "/search", url: '/search',
method: "get", method: 'get',
params, params,
}).then((data) => { }).then(data => {
if (data.result?.song !== undefined) if (data.result?.song !== undefined)
data.result.song.songs = mapTrackPlayableStatus(data.result.song.songs); data.result.song.songs = mapTrackPlayableStatus(data.result.song.songs);
return data; return data;
}); });
} }
export function personalFM() {
return request({
url: '/personal_fm',
method: 'get',
params: {
timestamp: new Date().getTime(),
},
});
}
export function fmTrash(id) {
return request({
url: '/fm_trash',
method: 'post',
params: {
timestamp: new Date().getTime(),
id,
},
});
}

View file

@ -1,5 +1,5 @@
import request from "@/utils/request"; import request from '@/utils/request';
import { mapTrackPlayableStatus } from "@/utils/common"; import { mapTrackPlayableStatus } from '@/utils/common';
/** /**
* 推荐歌单 * 推荐歌单
@ -11,8 +11,8 @@ import { mapTrackPlayableStatus } from "@/utils/common";
*/ */
export function recommendPlaylist(params) { export function recommendPlaylist(params) {
return request({ return request({
url: "/personalized", url: '/personalized',
method: "get", method: 'get',
params, params,
}); });
} }
@ -24,9 +24,12 @@ export function recommendPlaylist(params) {
*/ */
export function dailyRecommendPlaylist(params) { export function dailyRecommendPlaylist(params) {
return request({ return request({
url: "/recommend/resource", url: '/recommend/resource',
method: "get", method: 'get',
params, params: {
params,
timestamp: Date.now(),
},
}); });
} }
/** /**
@ -43,14 +46,16 @@ export function getPlaylistDetail(id, noCache = false) {
let params = { id }; let params = { id };
if (noCache) params.timestamp = new Date().getTime(); if (noCache) params.timestamp = new Date().getTime();
return request({ return request({
url: "/playlist/detail", url: '/playlist/detail',
method: "get", method: 'get',
params, params,
}).then((data) => { }).then(data => {
data.playlist.tracks = mapTrackPlayableStatus( if (data.playlist) {
data.playlist.tracks, data.playlist.tracks = mapTrackPlayableStatus(
data.privileges || [] data.playlist.tracks,
); data.privileges || []
);
}
return data; return data;
}); });
} }
@ -67,8 +72,8 @@ export function getPlaylistDetail(id, noCache = false) {
*/ */
export function highQualityPlaylist(params) { export function highQualityPlaylist(params) {
return request({ return request({
url: "/top/playlist/highquality", url: '/top/playlist/highquality',
method: "get", method: 'get',
params, params,
}); });
} }
@ -86,8 +91,8 @@ export function highQualityPlaylist(params) {
*/ */
export function topPlaylist(params) { export function topPlaylist(params) {
return request({ return request({
url: "/top/playlist", url: '/top/playlist',
method: "get", method: 'get',
params, params,
}); });
} }
@ -98,8 +103,8 @@ export function topPlaylist(params) {
*/ */
export function playlistCatlist() { export function playlistCatlist() {
return request({ return request({
url: "/playlist/catlist", url: '/playlist/catlist',
method: "get", method: 'get',
}); });
} }
@ -109,8 +114,8 @@ export function playlistCatlist() {
*/ */
export function toplists() { export function toplists() {
return request({ return request({
url: "/toplist", url: '/toplist',
method: "get", method: 'get',
}); });
} }
@ -126,8 +131,8 @@ export function toplists() {
export function subscribePlaylist(params) { export function subscribePlaylist(params) {
params.timestamp = new Date().getTime(); params.timestamp = new Date().getTime();
return request({ return request({
url: "/playlist/subscribe", url: '/playlist/subscribe',
method: "post", method: 'post',
params, params,
}); });
} }
@ -140,8 +145,8 @@ export function subscribePlaylist(params) {
*/ */
export function deletePlaylist(id) { export function deletePlaylist(id) {
return request({ return request({
url: "/playlist/delete", url: '/playlist/delete',
method: "post", method: 'post',
params: { id }, params: { id },
}); });
} }
@ -160,8 +165,8 @@ export function deletePlaylist(id) {
export function createPlaylist(params) { export function createPlaylist(params) {
params.timestamp = new Date().getTime(); params.timestamp = new Date().getTime();
return request({ return request({
url: "/playlist/create", url: '/playlist/create',
method: "post", method: 'post',
params, params,
}); });
} }
@ -178,8 +183,47 @@ export function createPlaylist(params) {
export function addOrRemoveTrackFromPlaylist(params) { export function addOrRemoveTrackFromPlaylist(params) {
params.timestamp = new Date().getTime(); params.timestamp = new Date().getTime();
return request({ return request({
url: "/playlist/tracks", url: '/playlist/tracks',
method: "post", method: 'post',
params,
});
}
/**
* 每日推荐歌曲
* 说明 : 调用此接口 , 可获得每日推荐歌曲 ( 需要登录 )
* @param {Object} params
* @param {string} params.op
* @param {string} params.pid
*/
export function dailyRecommendTracks() {
return request({
url: '/recommend/songs',
method: 'get',
params: { timestamp: new Date().getTime() },
}).then(result => {
result.data.dailySongs = mapTrackPlayableStatus(
result.data.dailySongs,
result.data.privileges
);
return result;
});
}
/**
* 心动模式/智能播放
* 说明 : 登录后调用此接口 , 可获取心动模式/智能播放列表 必选参数 : id : 歌曲 id
* - id : 歌曲 id
* - pid : 歌单 id
* - sid : 要开始播放的歌曲的 id (可选参数)
* @param {Object} params
* @param {number=} params.id
* @param {number=} params.pid
*/
export function intelligencePlaylist(params) {
return request({
url: '/playmode/intelligence/list',
method: 'get',
params, params,
}); });
} }

View file

@ -1,6 +1,13 @@
import store from "@/store"; import store from '@/store';
import request from "@/utils/request"; import request from '@/utils/request';
import { mapTrackPlayableStatus } from "@/utils/common"; import { mapTrackPlayableStatus } from '@/utils/common';
import {
cacheTrackDetail,
getTrackDetailFromCache,
cacheLyric,
getLyricFromCache,
} from '@/utils/db';
/** /**
* 获取音乐 url * 获取音乐 url
* 说明 : 使用歌单详情接口后 , 能得到的音乐的 id, 但不能得到的音乐 url, 调用此接口, 传入的音乐 id( 可多个 , 用逗号隔开 ), 可以获取对应的音乐的 url, * 说明 : 使用歌单详情接口后 , 能得到的音乐的 id, 但不能得到的音乐 url, 调用此接口, 传入的音乐 id( 可多个 , 用逗号隔开 ), 可以获取对应的音乐的 url,
@ -8,51 +15,85 @@ import { mapTrackPlayableStatus } from "@/utils/common";
* @param {string} id - 音乐的 id例如 id=405998841,33894312 * @param {string} id - 音乐的 id例如 id=405998841,33894312
*/ */
export function getMP3(id) { export function getMP3(id) {
let br = const getBr = () => {
store.state.settings?.musicQuality !== undefined // 当返回的 quality >= 400000时就会优先返回 hi-res
? store.state.settings.musicQuality const quality = store.state.settings?.musicQuality ?? '320000';
: 320000; return quality === 'flac' ? '350000' : quality;
};
return request({ return request({
url: "/song/url", url: '/song/url',
method: "get", method: 'get',
params: { params: {
id, id,
br, br: getBr(),
}, },
}); });
} }
/** /**
* 获取歌曲详情 * 获取歌曲详情
* 说明 : 调用此接口 , 传入音乐 id(支持多个 id, , 隔开), 可获得歌曲详情(注意:歌曲封面现在需要通过专辑内容接口获取) * 说明 : 调用此接口 , 传入音乐 id(支持多个 id, , 隔开), 可获得歌曲详情(注意:歌曲封面现在需要通过专辑内容接口获取)
* @param {string} ids - 音乐 id, 例如 ids=405998841,33894312 * @param {string} ids - 音乐 id, 例如 ids=405998841,33894312
*/ */
export function getTrackDetail(ids) { export function getTrackDetail(ids) {
return request({ const fetchLatest = () => {
url: "/song/detail", return request({
method: "get", url: '/song/detail',
params: { method: 'get',
ids, params: {
}, ids,
}).then((data) => { },
data.songs = mapTrackPlayableStatus(data.songs, data.privileges); }).then(data => {
return data; data.songs.map(song => {
const privileges = data.privileges.find(t => t.id === song.id);
cacheTrackDetail(song, privileges);
});
data.songs = mapTrackPlayableStatus(data.songs, data.privileges);
return data;
});
};
fetchLatest();
let idsInArray = [String(ids)];
if (typeof ids === 'string') {
idsInArray = ids.split(',');
}
return getTrackDetailFromCache(idsInArray).then(result => {
if (result) {
result.songs = mapTrackPlayableStatus(result.songs, result.privileges);
}
return result ?? fetchLatest();
}); });
} }
/** /**
* 获取歌词 * 获取歌词
* 说明 : 调用此接口 , 传入音乐 id 可获得对应音乐的歌词 ( 不需要登录 ) * 说明 : 调用此接口 , 传入音乐 id 可获得对应音乐的歌词 ( 不需要登录 )
* @param {number} id - 音乐 id * @param {number} id - 音乐 id
*/ */
export function getLyric(id) { export function getLyric(id) {
return request({ const fetchLatest = () => {
url: "/lyric", return request({
method: "get", url: '/lyric',
params: { method: 'get',
id, params: {
}, id,
},
}).then(result => {
cacheLyric(id, result);
return result;
});
};
fetchLatest();
return getLyricFromCache(id).then(result => {
return result ?? fetchLatest();
}); });
} }
/** /**
* 新歌速递 * 新歌速递
* 说明 : 调用此接口 , 可获取新歌速递 * 说明 : 调用此接口 , 可获取新歌速递
@ -60,13 +101,14 @@ export function getLyric(id) {
*/ */
export function topSong(type) { export function topSong(type) {
return request({ return request({
url: "/top/song", url: '/top/song',
method: "get", method: 'get',
params: { params: {
type, type,
}, },
}); });
} }
/** /**
* 喜欢音乐 * 喜欢音乐
* 说明 : 调用此接口 , 传入音乐 id, 可喜欢该音乐 * 说明 : 调用此接口 , 传入音乐 id, 可喜欢该音乐
@ -79,8 +121,8 @@ export function topSong(type) {
export function likeATrack(params) { export function likeATrack(params) {
params.timestamp = new Date().getTime(); params.timestamp = new Date().getTime();
return request({ return request({
url: "/like", url: '/like',
method: "get", method: 'get',
params, params,
}); });
} }
@ -99,8 +141,8 @@ export function likeATrack(params) {
export function scrobble(params) { export function scrobble(params) {
params.timestamp = new Date().getTime(); params.timestamp = new Date().getTime();
return request({ return request({
url: "/scrobble", url: '/scrobble',
method: "get", method: 'get',
params, params,
}); });
} }

View file

@ -1,4 +1,4 @@
import request from "@/utils/request"; import request from '@/utils/request';
/** /**
* 获取用户详情 * 获取用户详情
@ -8,10 +8,25 @@ import request from "@/utils/request";
*/ */
export function userDetail(uid) { export function userDetail(uid) {
return request({ return request({
url: "/user/detail", url: '/user/detail',
method: "get", method: 'get',
params: { params: {
uid, uid,
timestamp: new Date().getTime(),
},
});
}
/**
* 获取账号详情
* 说明 : 登录后调用此接口 ,可获取用户账号信息
*/
export function userAccount() {
return request({
url: '/user/account',
method: 'get',
params: {
timestamp: new Date().getTime(),
}, },
}); });
} }
@ -29,8 +44,25 @@ export function userDetail(uid) {
*/ */
export function userPlaylist(params) { export function userPlaylist(params) {
return request({ return request({
url: "/user/playlist", url: '/user/playlist',
method: "get", method: 'get',
params,
});
}
/**
* 获取用户播放记录
* 说明 : 登录后调用此接口 , 传入用户 id, 可获取用户播放记录
* - uid : 用户 id
* - type : type=1 时只返回 weekData, type=0 时返回 allData
* @param {Object} params
* @param {number} params.uid
* @param {number} params.type
*/
export function userPlayHistory(params) {
return request({
url: '/user/record',
method: 'get',
params, params,
}); });
} }
@ -43,8 +75,8 @@ export function userPlaylist(params) {
*/ */
export function userLikedSongsIDs(uid) { export function userLikedSongsIDs(uid) {
return request({ return request({
url: "/likelist", url: '/likelist',
method: "get", method: 'get',
params: { params: {
uid, uid,
timestamp: new Date().getTime(), timestamp: new Date().getTime(),
@ -60,8 +92,8 @@ export function userLikedSongsIDs(uid) {
*/ */
export function dailySignin(type = 0) { export function dailySignin(type = 0) {
return request({ return request({
url: "/daily_signin", url: '/daily_signin',
method: "post", method: 'post',
params: { params: {
type, type,
timestamp: new Date().getTime(), timestamp: new Date().getTime(),
@ -72,17 +104,18 @@ export function dailySignin(type = 0) {
/** /**
* 获取收藏的专辑需要登录 * 获取收藏的专辑需要登录
* 说明 : 调用此接口可获取到用户收藏的专辑 * 说明 : 调用此接口可获取到用户收藏的专辑
* - limit : 返回数量 , 默认为 30 * - limit : 返回数量 , 默认为 25
* - offset : 偏移数量用于分页 , :( 页数 -1)*30, 其中 30 limit 的值 , 默认为 0 * - offset : 偏移数量用于分页 , :( 页数 -1)*25, 其中 25 limit 的值 , 默认为 0
* @param {Object} params * @param {Object} params
* @param {number} params.limit * @param {number} params.limit
* @param {number=} params.offset * @param {number=} params.offset
*/ */
export function likedAlbums() { export function likedAlbums(params) {
return request({ return request({
url: "/album/sublist", url: '/album/sublist',
method: "get", method: 'get',
params: { params: {
limit: params.limit,
timestamp: new Date().getTime(), timestamp: new Date().getTime(),
}, },
}); });
@ -92,11 +125,12 @@ export function likedAlbums() {
* 获取收藏的歌手需要登录 * 获取收藏的歌手需要登录
* 说明 : 调用此接口可获取到用户收藏的歌手 * 说明 : 调用此接口可获取到用户收藏的歌手
*/ */
export function likedArtists() { export function likedArtists(params) {
return request({ return request({
url: "/artist/sublist", url: '/artist/sublist',
method: "get", method: 'get',
params: { params: {
limit: params.limit,
timestamp: new Date().getTime(), timestamp: new Date().getTime(),
}, },
}); });
@ -106,12 +140,82 @@ export function likedArtists() {
* 获取收藏的MV需要登录 * 获取收藏的MV需要登录
* 说明 : 调用此接口可获取到用户收藏的MV * 说明 : 调用此接口可获取到用户收藏的MV
*/ */
export function likedMVs() { export function likedMVs(params) {
return request({ return request({
url: "/mv/sublist", url: '/mv/sublist',
method: "get", method: 'get',
params: { params: {
limit: params.limit,
timestamp: new Date().getTime(), timestamp: new Date().getTime(),
}, },
}); });
} }
/**
* 上传歌曲到云盘需要登录
*/
export function uploadSong(file) {
let formData = new FormData();
formData.append('songFile', file);
return request({
url: '/cloud',
method: 'post',
params: {
timestamp: new Date().getTime(),
},
data: formData,
headers: {
'Content-Type': 'multipart/form-data',
},
timeout: 200000,
}).catch(error => {
alert(`上传失败Error: ${error}`);
});
}
/**
* 获取云盘歌曲需要登录
* 说明 : 登录后调用此接口 , 可获取云盘数据 , 获取的数据没有对应 url, 需要再调用一 /song/url 获取 url
* - limit : 返回数量 , 默认为 200
* - offset : 偏移数量用于分页 , :( 页数 -1)*200, 其中 200 limit 的值 , 默认为 0
* @param {Object} params
* @param {number} params.limit
* @param {number=} params.offset
*/
export function cloudDisk(params = {}) {
params.timestamp = new Date().getTime();
return request({
url: '/user/cloud',
method: 'get',
params,
});
}
/**
* 获取云盘歌曲详情需要登录
*/
export function cloudDiskTrackDetail(id) {
return request({
url: '/user/cloud/detail',
method: 'get',
params: {
timestamp: new Date().getTime(),
id,
},
});
}
/**
* 删除云盘歌曲需要登录
* @param {Array} id
*/
export function cloudDiskTrackDelete(id) {
return request({
url: '/user/cloud/del',
method: 'get',
params: {
timestamp: new Date().getTime(),
id,
},
});
}

135
src/assets/css/global.scss Normal file
View file

@ -0,0 +1,135 @@
@font-face {
font-family: 'Barlow';
font-weight: normal;
src: url('~@/assets/fonts/Barlow-Regular.woff2') format('woff2'),
url('~@/assets/fonts/Barlow-Regular.ttf') format('truetype');
}
@font-face {
font-family: 'Barlow';
font-weight: medium;
src: url('~@/assets/fonts/Barlow-Medium.woff2') format('woff2'),
url('~@/assets/fonts/Barlow-Medium.ttf') format('truetype');
}
@font-face {
font-family: 'Barlow';
font-weight: 600;
src: url('~@/assets/fonts/Barlow-SemiBold.woff2') format('woff2'),
url('~@/assets/fonts/Barlow-SemiBold.ttf') format('truetype');
}
@font-face {
font-family: 'Barlow';
font-weight: bold;
src: url('~@/assets/fonts/Barlow-Bold.woff2') format('woff2'),
url('~@/assets/fonts/Barlow-Bold.ttf') format('truetype');
}
@font-face {
font-family: 'Barlow';
font-weight: 800;
src: url('~@/assets/fonts/Barlow-ExtraBold.woff2') format('woff2'),
url('~@/assets/fonts/Barlow-ExtraBold.ttf') format('truetype');
}
@font-face {
font-family: 'Barlow';
font-weight: 900;
src: url('~@/assets/fonts/Barlow-Black.woff2') format('woff2'),
url('~@/assets/fonts/Barlow-Black.ttf') format('truetype');
}
:root {
--color-body-bg: #ffffff;
--color-text: #000;
--color-primary: #335eea;
--color-primary-bg: #eaeffd;
--color-secondary: #7a7a7b;
--color-secondary-bg: #f5f5f7;
--color-navbar-bg: rgba(255, 255, 255, 0.86);
--color-primary-bg-for-transparent: rgba(189, 207, 255, 0.28);
--color-secondary-bg-for-transparent: rgba(209, 209, 214, 0.28);
--html-overflow-y: overlay;
}
[data-theme='dark'] {
--color-body-bg: #222222;
--color-text: #ffffff;
--color-primary: #335eea;
--color-primary-bg: #bbcdff;
--color-secondary: #7a7a7b;
--color-secondary-bg: #323232;
--color-navbar-bg: rgba(34, 34, 34, 0.86);
--color-primary-bg-for-transparent: rgba(255, 255, 255, 0.12);
--color-secondary-bg-for-transparent: rgba(255, 255, 255, 0.08);
}
#app,
input {
font-family: 'Barlow', ui-sans-serif, system-ui, -apple-system,
BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei,
Source Han Sans SC, Noto Sans CJK SC, WenQuanYi Micro Hei, sans-serif,
microsoft uighur;
}
body {
background-color: var(--color-body-bg);
}
html {
overflow-y: var(--html-overflow-y);
min-width: 768px;
overscroll-behavior: none;
}
select,
button {
font-family: inherit;
}
button {
background: none;
border: none;
cursor: pointer;
user-select: none;
}
input,
button {
&:focus {
outline: none;
}
}
a {
color: inherit;
text-decoration: none;
cursor: pointer;
&:hover {
text-decoration: underline;
}
}
[data-electron='yes'] {
button,
.navigation-links a,
.playlist-info .description {
cursor: default !important;
}
}
::-webkit-scrollbar {
width: 8px;
}
::-webkit-scrollbar-track {
background: transparent;
border-left: 1px solid rgba(128, 128, 128, 0.18);
background: var(--color-body-bg);
}
::-webkit-scrollbar-thumb {
-webkit-border-radius: 10px;
border-radius: 10px;
background: rgba(128, 128, 128, 0.38);
}
[data-theme='dark'] ::-webkit-scrollbar-thumb {
background: var(--color-secondary-bg);
}
.user-select-none {
user-select: none;
}

View file

@ -265,17 +265,17 @@ a.plyr__control::before {
display: none; display: none;
} }
.plyr [data-plyr="airplay"], .plyr [data-plyr='airplay'],
.plyr [data-plyr="captions"], .plyr [data-plyr='captions'],
.plyr [data-plyr="fullscreen"], .plyr [data-plyr='fullscreen'],
.plyr [data-plyr="pip"] { .plyr [data-plyr='pip'] {
display: none; display: none;
} }
.plyr--airplay-supported [data-plyr="airplay"], .plyr--airplay-supported [data-plyr='airplay'],
.plyr--captions-enabled [data-plyr="captions"], .plyr--captions-enabled [data-plyr='captions'],
.plyr--fullscreen-enabled [data-plyr="fullscreen"], .plyr--fullscreen-enabled [data-plyr='fullscreen'],
.plyr--pip-supported [data-plyr="pip"] { .plyr--pip-supported [data-plyr='pip'] {
display: inline-block; display: inline-block;
} }
@ -288,11 +288,11 @@ a.plyr__control::before {
transition: transform 0.3s ease; transition: transform 0.3s ease;
} }
.plyr__menu .plyr__control[aria-expanded="true"] svg { .plyr__menu .plyr__control[aria-expanded='true'] svg {
transform: rotate(90deg); transform: rotate(90deg);
} }
.plyr__menu .plyr__control[aria-expanded="true"] .plyr__tooltip { .plyr__menu .plyr__control[aria-expanded='true'] .plyr__tooltip {
display: none; display: none;
} }
@ -327,7 +327,7 @@ a.plyr__control::before {
border: var(--plyr-menu-arrow-size, 4px) solid transparent; border: var(--plyr-menu-arrow-size, 4px) solid transparent;
border-top-color: rgba(255, 255, 255, 0.9); border-top-color: rgba(255, 255, 255, 0.9);
border-top-color: var(--plyr-menu-background, rgba(255, 255, 255, 0.9)); border-top-color: var(--plyr-menu-background, rgba(255, 255, 255, 0.9));
content: ""; content: '';
height: 0; height: 0;
position: absolute; position: absolute;
right: calc(((18px / 2) + calc(10px * 0.7)) - (4px / 2)); right: calc(((18px / 2) + calc(10px * 0.7)) - (4px / 2));
@ -341,18 +341,18 @@ a.plyr__control::before {
width: 0; width: 0;
} }
.plyr__menu__container [role="menu"] { .plyr__menu__container [role='menu'] {
padding: calc(10px * 0.7); padding: calc(10px * 0.7);
padding: calc(var(--plyr-control-spacing, 10px) * 0.7); padding: calc(var(--plyr-control-spacing, 10px) * 0.7);
} }
.plyr__menu__container [role="menuitem"], .plyr__menu__container [role='menuitem'],
.plyr__menu__container [role="menuitemradio"] { .plyr__menu__container [role='menuitemradio'] {
margin-top: 2px; margin-top: 2px;
} }
.plyr__menu__container [role="menuitem"]:first-child, .plyr__menu__container [role='menuitem']:first-child,
.plyr__menu__container [role="menuitemradio"]:first-child { .plyr__menu__container [role='menuitemradio']:first-child {
margin-top: 0; margin-top: 0;
} }
@ -386,7 +386,7 @@ a.plyr__control::before {
.plyr__menu__container .plyr__control::after { .plyr__menu__container .plyr__control::after {
border: 4px solid transparent; border: 4px solid transparent;
border: var(--plyr-menu-item-arrow-size, 4px) solid transparent; border: var(--plyr-menu-item-arrow-size, 4px) solid transparent;
content: ""; content: '';
position: absolute; position: absolute;
top: 50%; top: 50%;
transform: translateY(-50%); transform: translateY(-50%);
@ -441,7 +441,7 @@ a.plyr__control::before {
background: var(--plyr-menu-back-border-color, #dcdfe5); background: var(--plyr-menu-back-border-color, #dcdfe5);
box-shadow: 0 1px 0 #fff; box-shadow: 0 1px 0 #fff;
box-shadow: 0 1px 0 var(--plyr-menu-back-border-shadow-color, #fff); box-shadow: 0 1px 0 var(--plyr-menu-back-border-shadow-color, #fff);
content: ""; content: '';
height: 1px; height: 1px;
left: 0; left: 0;
margin-top: calc(calc(10px * 0.7) / 2); margin-top: calc(calc(10px * 0.7) / 2);
@ -457,19 +457,19 @@ a.plyr__control::before {
border-right-color: currentColor; border-right-color: currentColor;
} }
.plyr__menu__container .plyr__control[role="menuitemradio"] { .plyr__menu__container .plyr__control[role='menuitemradio'] {
padding-left: calc(10px * 0.7); padding-left: calc(10px * 0.7);
padding-left: calc(var(--plyr-control-spacing, 10px) * 0.7); padding-left: calc(var(--plyr-control-spacing, 10px) * 0.7);
} }
.plyr__menu__container .plyr__control[role="menuitemradio"]::after, .plyr__menu__container .plyr__control[role='menuitemradio']::after,
.plyr__menu__container .plyr__control[role="menuitemradio"]::before { .plyr__menu__container .plyr__control[role='menuitemradio']::before {
border-radius: 100%; border-radius: 100%;
} }
.plyr__menu__container .plyr__control[role="menuitemradio"]::before { .plyr__menu__container .plyr__control[role='menuitemradio']::before {
background: rgba(0, 0, 0, 0.1); background: rgba(0, 0, 0, 0.1);
content: ""; content: '';
display: block; display: block;
flex-shrink: 0; flex-shrink: 0;
height: 16px; height: 16px;
@ -479,7 +479,7 @@ a.plyr__control::before {
width: 16px; width: 16px;
} }
.plyr__menu__container .plyr__control[role="menuitemradio"]::after { .plyr__menu__container .plyr__control[role='menuitemradio']::after {
background: #fff; background: #fff;
border: 0; border: 0;
height: 6px; height: 6px;
@ -492,7 +492,7 @@ a.plyr__control::before {
} }
.plyr__menu__container .plyr__menu__container
.plyr__control[role="menuitemradio"][aria-checked="true"]::before { .plyr__control[role='menuitemradio'][aria-checked='true']::before {
background: #00b3ff; background: #00b3ff;
background: var( background: var(
--plyr-control-toggle-checked-background, --plyr-control-toggle-checked-background,
@ -501,14 +501,14 @@ a.plyr__control::before {
} }
.plyr__menu__container .plyr__menu__container
.plyr__control[role="menuitemradio"][aria-checked="true"]::after { .plyr__control[role='menuitemradio'][aria-checked='true']::after {
opacity: 1; opacity: 1;
transform: translateY(-50%) scale(1); transform: translateY(-50%) scale(1);
} }
.plyr__menu__container .plyr__menu__container
.plyr__control[role="menuitemradio"].plyr__tab-focus::before, .plyr__control[role='menuitemradio'].plyr__tab-focus::before,
.plyr__menu__container .plyr__control[role="menuitemradio"]:hover::before { .plyr__menu__container .plyr__control[role='menuitemradio']:hover::before {
background: rgba(35, 40, 47, 0.1); background: rgba(35, 40, 47, 0.1);
} }
@ -524,7 +524,7 @@ a.plyr__control::before {
pointer-events: none; pointer-events: none;
} }
.plyr--full-ui input[type="range"] { .plyr--full-ui input[type='range'] {
-webkit-appearance: none; -webkit-appearance: none;
background: 0 0; background: 0 0;
border: 0; border: 0;
@ -547,7 +547,7 @@ a.plyr__control::before {
width: 100%; width: 100%;
} }
.plyr--full-ui input[type="range"]::-webkit-slider-runnable-track { .plyr--full-ui input[type='range']::-webkit-slider-runnable-track {
background: 0 0; background: 0 0;
border: 0; border: 0;
border-radius: calc(5px / 2); border-radius: calc(5px / 2);
@ -566,7 +566,7 @@ a.plyr__control::before {
); );
} }
.plyr--full-ui input[type="range"]::-webkit-slider-thumb { .plyr--full-ui input[type='range']::-webkit-slider-thumb {
background: #fff; background: #fff;
background: var(--plyr-range-thumb-background, #fff); background: var(--plyr-range-thumb-background, #fff);
border: 0; border: 0;
@ -596,7 +596,7 @@ a.plyr__control::before {
); );
} }
.plyr--full-ui input[type="range"]::-moz-range-track { .plyr--full-ui input[type='range']::-moz-range-track {
background: 0 0; background: 0 0;
border: 0; border: 0;
border-radius: calc(5px / 2); border-radius: calc(5px / 2);
@ -608,7 +608,7 @@ a.plyr__control::before {
user-select: none; user-select: none;
} }
.plyr--full-ui input[type="range"]::-moz-range-thumb { .plyr--full-ui input[type='range']::-moz-range-thumb {
background: #fff; background: #fff;
background: var(--plyr-range-thumb-background, #fff); background: var(--plyr-range-thumb-background, #fff);
border: 0; border: 0;
@ -628,7 +628,7 @@ a.plyr__control::before {
width: var(--plyr-range-thumb-height, 13px); width: var(--plyr-range-thumb-height, 13px);
} }
.plyr--full-ui input[type="range"]::-moz-range-progress { .plyr--full-ui input[type='range']::-moz-range-progress {
background: currentColor; background: currentColor;
border-radius: calc(5px / 2); border-radius: calc(5px / 2);
border-radius: calc(var(--plyr-range-track-height, 5px) / 2); border-radius: calc(var(--plyr-range-track-height, 5px) / 2);
@ -636,7 +636,7 @@ a.plyr__control::before {
height: var(--plyr-range-track-height, 5px); height: var(--plyr-range-track-height, 5px);
} }
.plyr--full-ui input[type="range"]::-ms-track { .plyr--full-ui input[type='range']::-ms-track {
background: 0 0; background: 0 0;
border: 0; border: 0;
border-radius: calc(5px / 2); border-radius: calc(5px / 2);
@ -650,7 +650,7 @@ a.plyr__control::before {
color: transparent; color: transparent;
} }
.plyr--full-ui input[type="range"]::-ms-fill-upper { .plyr--full-ui input[type='range']::-ms-fill-upper {
background: 0 0; background: 0 0;
border: 0; border: 0;
border-radius: calc(5px / 2); border-radius: calc(5px / 2);
@ -663,7 +663,7 @@ a.plyr__control::before {
user-select: none; user-select: none;
} }
.plyr--full-ui input[type="range"]::-ms-fill-lower { .plyr--full-ui input[type='range']::-ms-fill-lower {
background: 0 0; background: 0 0;
border: 0; border: 0;
border-radius: calc(5px / 2); border-radius: calc(5px / 2);
@ -677,7 +677,7 @@ a.plyr__control::before {
background: currentColor; background: currentColor;
} }
.plyr--full-ui input[type="range"]::-ms-thumb { .plyr--full-ui input[type='range']::-ms-thumb {
background: #fff; background: #fff;
background: var(--plyr-range-thumb-background, #fff); background: var(--plyr-range-thumb-background, #fff);
border: 0; border: 0;
@ -698,20 +698,20 @@ a.plyr__control::before {
margin-top: 0; margin-top: 0;
} }
.plyr--full-ui input[type="range"]::-ms-tooltip { .plyr--full-ui input[type='range']::-ms-tooltip {
display: none; display: none;
} }
.plyr--full-ui input[type="range"]:focus { .plyr--full-ui input[type='range']:focus {
outline: 0; outline: 0;
} }
.plyr--full-ui input[type="range"]::-moz-focus-outer { .plyr--full-ui input[type='range']::-moz-focus-outer {
border: 0; border: 0;
} }
.plyr--full-ui .plyr--full-ui
input[type="range"].plyr__tab-focus::-webkit-slider-runnable-track { input[type='range'].plyr__tab-focus::-webkit-slider-runnable-track {
outline-color: #00b3ff; outline-color: #00b3ff;
outline-color: var( outline-color: var(
--plyr-tab-focus-color, --plyr-tab-focus-color,
@ -722,7 +722,7 @@ a.plyr__control::before {
outline-width: 3px; outline-width: 3px;
} }
.plyr--full-ui input[type="range"].plyr__tab-focus::-moz-range-track { .plyr--full-ui input[type='range'].plyr__tab-focus::-moz-range-track {
outline-color: #00b3ff; outline-color: #00b3ff;
outline-color: var( outline-color: var(
--plyr-tab-focus-color, --plyr-tab-focus-color,
@ -733,7 +733,7 @@ a.plyr__control::before {
outline-width: 3px; outline-width: 3px;
} }
.plyr--full-ui input[type="range"].plyr__tab-focus::-ms-track { .plyr--full-ui input[type='range'].plyr__tab-focus::-ms-track {
outline-color: #00b3ff; outline-color: #00b3ff;
outline-color: var( outline-color: var(
--plyr-tab-focus-color, --plyr-tab-focus-color,
@ -769,7 +769,7 @@ a.plyr__control::before {
} }
.plyr__time + .plyr__time::before { .plyr__time + .plyr__time::before {
content: "\2044"; content: '\2044';
margin-right: 10px; margin-right: 10px;
margin-right: var(--plyr-control-spacing, 10px); margin-right: var(--plyr-control-spacing, 10px);
} }
@ -821,7 +821,7 @@ a.plyr__control::before {
var(--plyr-tooltip-background, rgba(255, 255, 255, 0.9)); var(--plyr-tooltip-background, rgba(255, 255, 255, 0.9));
bottom: calc(4px * -1); bottom: calc(4px * -1);
bottom: calc(var(--plyr-tooltip-arrow-size, 4px) * -1); bottom: calc(var(--plyr-tooltip-arrow-size, 4px) * -1);
content: ""; content: '';
height: 0; height: 0;
left: 50%; left: 50%;
position: absolute; position: absolute;
@ -906,7 +906,7 @@ a.plyr__control::before {
position: relative; position: relative;
} }
.plyr__progress input[type="range"], .plyr__progress input[type='range'],
.plyr__progress__buffer { .plyr__progress__buffer {
margin-left: calc(13px * -0.5); margin-left: calc(13px * -0.5);
margin-left: calc(var(--plyr-range-thumb-height, 13px) * -0.5); margin-left: calc(var(--plyr-range-thumb-height, 13px) * -0.5);
@ -916,7 +916,7 @@ a.plyr__control::before {
width: calc(100% + var(--plyr-range-thumb-height, 13px)); width: calc(100% + var(--plyr-range-thumb-height, 13px));
} }
.plyr__progress input[type="range"] { .plyr__progress input[type='range'] {
position: relative; position: relative;
z-index: 2; z-index: 2;
} }
@ -1024,7 +1024,7 @@ a.plyr__control::before {
width: 20%; width: 20%;
} }
.plyr__volume input[type="range"] { .plyr__volume input[type='range'] {
margin-left: calc(10px / 2); margin-left: calc(10px / 2);
margin-left: calc(var(--plyr-control-spacing, 10px) / 2); margin-left: calc(var(--plyr-control-spacing, 10px) / 2);
margin-right: calc(10px / 2); margin-right: calc(10px / 2);
@ -1054,7 +1054,7 @@ a.plyr__control::before {
.plyr--audio .plyr__control.plyr__tab-focus, .plyr--audio .plyr__control.plyr__tab-focus,
.plyr--audio .plyr__control:hover, .plyr--audio .plyr__control:hover,
.plyr--audio .plyr__control[aria-expanded="true"] { .plyr--audio .plyr__control[aria-expanded='true'] {
background: #00b3ff; background: #00b3ff;
background: var( background: var(
--plyr-audio-control-background-hover, --plyr-audio-control-background-hover,
@ -1064,7 +1064,7 @@ a.plyr__control::before {
color: var(--plyr-audio-control-color-hover, #fff); color: var(--plyr-audio-control-color-hover, #fff);
} }
.plyr--full-ui.plyr--audio input[type="range"]::-webkit-slider-runnable-track { .plyr--full-ui.plyr--audio input[type='range']::-webkit-slider-runnable-track {
background-color: rgba(193, 200, 209, 0.6); background-color: rgba(193, 200, 209, 0.6);
background-color: var( background-color: var(
--plyr-audio-range-track-background, --plyr-audio-range-track-background,
@ -1072,7 +1072,7 @@ a.plyr__control::before {
); );
} }
.plyr--full-ui.plyr--audio input[type="range"]::-moz-range-track { .plyr--full-ui.plyr--audio input[type='range']::-moz-range-track {
background-color: rgba(193, 200, 209, 0.6); background-color: rgba(193, 200, 209, 0.6);
background-color: var( background-color: var(
--plyr-audio-range-track-background, --plyr-audio-range-track-background,
@ -1080,7 +1080,7 @@ a.plyr__control::before {
); );
} }
.plyr--full-ui.plyr--audio input[type="range"]::-ms-track { .plyr--full-ui.plyr--audio input[type='range']::-ms-track {
background-color: rgba(193, 200, 209, 0.6); background-color: rgba(193, 200, 209, 0.6);
background-color: var( background-color: var(
--plyr-audio-range-track-background, --plyr-audio-range-track-background,
@ -1088,7 +1088,7 @@ a.plyr__control::before {
); );
} }
.plyr--full-ui.plyr--audio input[type="range"]:active::-webkit-slider-thumb { .plyr--full-ui.plyr--audio input[type='range']:active::-webkit-slider-thumb {
box-shadow: 0 1px 1px rgba(35, 40, 47, 0.15), 0 0 0 1px rgba(35, 40, 47, 0.2), box-shadow: 0 1px 1px rgba(35, 40, 47, 0.15), 0 0 0 1px rgba(35, 40, 47, 0.2),
0 0 0 3px rgba(35, 40, 47, 0.1); 0 0 0 3px rgba(35, 40, 47, 0.1);
box-shadow: var( box-shadow: var(
@ -1100,7 +1100,7 @@ a.plyr__control::before {
var(--plyr-audio-range-thumb-active-shadow-color, rgba(35, 40, 47, 0.1)); var(--plyr-audio-range-thumb-active-shadow-color, rgba(35, 40, 47, 0.1));
} }
.plyr--full-ui.plyr--audio input[type="range"]:active::-moz-range-thumb { .plyr--full-ui.plyr--audio input[type='range']:active::-moz-range-thumb {
box-shadow: 0 1px 1px rgba(35, 40, 47, 0.15), 0 0 0 1px rgba(35, 40, 47, 0.2), box-shadow: 0 1px 1px rgba(35, 40, 47, 0.15), 0 0 0 1px rgba(35, 40, 47, 0.2),
0 0 0 3px rgba(35, 40, 47, 0.1); 0 0 0 3px rgba(35, 40, 47, 0.1);
box-shadow: var( box-shadow: var(
@ -1112,7 +1112,7 @@ a.plyr__control::before {
var(--plyr-audio-range-thumb-active-shadow-color, rgba(35, 40, 47, 0.1)); var(--plyr-audio-range-thumb-active-shadow-color, rgba(35, 40, 47, 0.1));
} }
.plyr--full-ui.plyr--audio input[type="range"]:active::-ms-thumb { .plyr--full-ui.plyr--audio input[type='range']:active::-ms-thumb {
box-shadow: 0 1px 1px rgba(35, 40, 47, 0.15), 0 0 0 1px rgba(35, 40, 47, 0.2), box-shadow: 0 1px 1px rgba(35, 40, 47, 0.15), 0 0 0 1px rgba(35, 40, 47, 0.2),
0 0 0 3px rgba(35, 40, 47, 0.1); 0 0 0 3px rgba(35, 40, 47, 0.1);
box-shadow: var( box-shadow: var(
@ -1207,7 +1207,7 @@ a.plyr__control::before {
.plyr--video .plyr__control.plyr__tab-focus, .plyr--video .plyr__control.plyr__tab-focus,
.plyr--video .plyr__control:hover, .plyr--video .plyr__control:hover,
.plyr--video .plyr__control[aria-expanded="true"] { .plyr--video .plyr__control[aria-expanded='true'] {
background: #00b3ff; background: #00b3ff;
background: var( background: var(
--plyr-video-control-background-hover, --plyr-video-control-background-hover,
@ -1258,7 +1258,7 @@ a.plyr__control::before {
display: block; display: block;
} }
.plyr--full-ui.plyr--video input[type="range"]::-webkit-slider-runnable-track { .plyr--full-ui.plyr--video input[type='range']::-webkit-slider-runnable-track {
background-color: rgba(255, 255, 255, 0.25); background-color: rgba(255, 255, 255, 0.25);
background-color: var( background-color: var(
--plyr-video-range-track-background, --plyr-video-range-track-background,
@ -1266,7 +1266,7 @@ a.plyr__control::before {
); );
} }
.plyr--full-ui.plyr--video input[type="range"]::-moz-range-track { .plyr--full-ui.plyr--video input[type='range']::-moz-range-track {
background-color: rgba(255, 255, 255, 0.25); background-color: rgba(255, 255, 255, 0.25);
background-color: var( background-color: var(
--plyr-video-range-track-background, --plyr-video-range-track-background,
@ -1274,7 +1274,7 @@ a.plyr__control::before {
); );
} }
.plyr--full-ui.plyr--video input[type="range"]::-ms-track { .plyr--full-ui.plyr--video input[type='range']::-ms-track {
background-color: rgba(255, 255, 255, 0.25); background-color: rgba(255, 255, 255, 0.25);
background-color: var( background-color: var(
--plyr-video-range-track-background, --plyr-video-range-track-background,
@ -1282,7 +1282,7 @@ a.plyr__control::before {
); );
} }
.plyr--full-ui.plyr--video input[type="range"]:active::-webkit-slider-thumb { .plyr--full-ui.plyr--video input[type='range']:active::-webkit-slider-thumb {
box-shadow: 0 1px 1px rgba(35, 40, 47, 0.15), 0 0 0 1px rgba(35, 40, 47, 0.2), box-shadow: 0 1px 1px rgba(35, 40, 47, 0.15), 0 0 0 1px rgba(35, 40, 47, 0.2),
0 0 0 3px rgba(255, 255, 255, 0.5); 0 0 0 3px rgba(255, 255, 255, 0.5);
box-shadow: var( box-shadow: var(
@ -1297,7 +1297,7 @@ a.plyr__control::before {
); );
} }
.plyr--full-ui.plyr--video input[type="range"]:active::-moz-range-thumb { .plyr--full-ui.plyr--video input[type='range']:active::-moz-range-thumb {
box-shadow: 0 1px 1px rgba(35, 40, 47, 0.15), 0 0 0 1px rgba(35, 40, 47, 0.2), box-shadow: 0 1px 1px rgba(35, 40, 47, 0.15), 0 0 0 1px rgba(35, 40, 47, 0.2),
0 0 0 3px rgba(255, 255, 255, 0.5); 0 0 0 3px rgba(255, 255, 255, 0.5);
box-shadow: var( box-shadow: var(
@ -1312,7 +1312,7 @@ a.plyr__control::before {
); );
} }
.plyr--full-ui.plyr--video input[type="range"]:active::-ms-thumb { .plyr--full-ui.plyr--video input[type='range']:active::-ms-thumb {
box-shadow: 0 1px 1px rgba(35, 40, 47, 0.15), 0 0 0 1px rgba(35, 40, 47, 0.2), box-shadow: 0 1px 1px rgba(35, 40, 47, 0.15), 0 0 0 1px rgba(35, 40, 47, 0.2),
0 0 0 3px rgba(255, 255, 255, 0.5); 0 0 0 3px rgba(255, 255, 255, 0.5);
box-shadow: var( box-shadow: var(
@ -1713,7 +1713,7 @@ a.plyr__control::before {
var(--plyr-tooltip-background, rgba(255, 255, 255, 0.9)); var(--plyr-tooltip-background, rgba(255, 255, 255, 0.9));
bottom: calc(4px * -1); bottom: calc(4px * -1);
bottom: calc(var(--plyr-tooltip-arrow-size, 4px) * -1); bottom: calc(var(--plyr-tooltip-arrow-size, 4px) * -1);
content: ""; content: '';
height: 0; height: 0;
left: 50%; left: 50%;
position: absolute; position: absolute;

View file

@ -89,7 +89,7 @@
} }
.nyancat .vue-slider-dot-handle { .nyancat .vue-slider-dot-handle {
background: url("/img/logos/nyancat.gif"); background: url('/img/logos/nyancat.gif');
background-size: 36px; background-size: 36px;
width: 36px; width: 36px;
height: 24px; height: 24px;
@ -100,6 +100,11 @@
visibility: visible; visibility: visible;
} }
.nyancat-stop .vue-slider-dot-handle {
background-image: url('/img/logos/nyancat-stop.png');
transition: 300ms;
}
/* lyrics */ /* lyrics */
.lyrics-page .vue-slider-rail { .lyrics-page .vue-slider-rail {
background-color: rgba(128, 128, 128, 0.18); background-color: rgba(128, 128, 128, 0.18);
@ -121,10 +126,19 @@
display: none; display: none;
} }
body[data-theme="dark"] .lyrics-page .vue-slider-process { body[data-theme='dark'] .lyrics-page .vue-slider-process {
background-color: #fafafa; background-color: #fafafa;
} }
body[data-theme="dark"] .lyrics-page .vue-slider-dot-handle { body[data-theme='dark'] .lyrics-page .vue-slider-dot-handle {
background-color: #fff;
}
.lyrics-page[data-theme='dark'] .vue-slider-rail {
background-color: rgba(255, 255, 255, 0.18);
}
.lyrics-page[data-theme='dark'] .vue-slider-process,
.lyrics-page[data-theme='dark'] .vue-slider-dot-handle {
background-color: #fff; background-color: #fff;
} }

BIN
src/assets/fonts/Barlow-Black.ttf Executable file

Binary file not shown.

Binary file not shown.

BIN
src/assets/fonts/Barlow-Bold.ttf Executable file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1 @@
<?xml version="1.0" ?><!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'><svg enable-background="new 0 0 32 32" height="32px" id="Layer_1" version="1.1" viewBox="0 0 32 32" width="32px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M14.77,23.795L5.185,14.21c-0.879-0.879-0.879-2.317,0-3.195l0.8-0.801c0.877-0.878,2.316-0.878,3.194,0 l7.315,7.315l7.316-7.315c0.878-0.878,2.317-0.878,3.194,0l0.8,0.801c0.879,0.878,0.879,2.316,0,3.195l-9.587,9.585 c-0.471,0.472-1.104,0.682-1.723,0.647C15.875,24.477,15.243,24.267,14.77,23.795z" fill="currentColor"/></svg>

After

Width:  |  Height:  |  Size: 666 B

View file

@ -0,0 +1 @@
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="arrow-up" class="svg-inline--fa fa-arrow-up fa-w-14" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="currentColor" d="M34.9 289.5l-22.2-22.2c-9.4-9.4-9.4-24.6 0-33.9L207 39c9.4-9.4 24.6-9.4 33.9 0l194.3 194.3c9.4 9.4 9.4 24.6 0 33.9L413 289.4c-9.5 9.5-25 9.3-34.3-.4L264 168.6V456c0 13.3-10.7 24-24 24h-32c-13.3 0-24-10.7-24-24V168.6L69.2 289.1c-9.3 9.8-24.8 10-34.3.4z"></path></svg>

After

Width:  |  Height:  |  Size: 487 B

View file

@ -0,0 +1 @@
<?xml version="1.0" ?><!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'><svg enable-background="new 0 0 32 32" height="32px" id="Layer_1" version="1.1" viewBox="0 0 32 32" width="32px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M18.221,7.206l9.585,9.585c0.879,0.879,0.879,2.317,0,3.195l-0.8,0.801c-0.877,0.878-2.316,0.878-3.194,0 l-7.315-7.315l-7.315,7.315c-0.878,0.878-2.317,0.878-3.194,0l-0.8-0.801c-0.879-0.878-0.879-2.316,0-3.195l9.587-9.585 c0.471-0.472,1.103-0.682,1.723-0.647C17.115,6.524,17.748,6.734,18.221,7.206z" fill="currentColor"/></svg>

After

Width:  |  Height:  |  Size: 668 B

View file

@ -1 +0,0 @@
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="circle" class="svg-inline--fa fa-circle fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8z"></path></svg>

Before

Width:  |  Height:  |  Size: 301 B

View file

@ -0,0 +1 @@
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="caret-down" class="svg-inline--fa fa-caret-down fa-w-10" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path fill="currentColor" d="M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z"></path></svg>

After

Width:  |  Height:  |  Size: 359 B

View file

@ -1 +0,0 @@
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="expand-alt" class="svg-inline--fa fa-expand-alt fa-w-14" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="currentColor" d="M212.686 315.314L120 408l32.922 31.029c15.12 15.12 4.412 40.971-16.97 40.971h-112C10.697 480 0 469.255 0 456V344c0-21.382 25.803-32.09 40.922-16.971L72 360l92.686-92.686c6.248-6.248 16.379-6.248 22.627 0l25.373 25.373c6.249 6.248 6.249 16.378 0 22.627zm22.628-118.628L328 104l-32.922-31.029C279.958 57.851 290.666 32 312.048 32h112C437.303 32 448 42.745 448 56v112c0 21.382-25.803 32.09-40.922 16.971L376 152l-92.686 92.686c-6.248 6.248-16.379 6.248-22.627 0l-25.373-25.373c-6.249-6.248-6.249-16.378 0-22.627z"></path></svg>

Before

Width:  |  Height:  |  Size: 749 B

1
src/assets/icons/fm.svg Normal file
View file

@ -0,0 +1 @@
<svg aria-hidden="true" focusable="false" data-prefix="far" data-icon="radio-alt" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="svg-inline--fa fa-radio-alt fa-w-16 fa-7x"><path fill="currentColor" d="M209 368h-64a16 16 0 0 0-16 16v16a16 16 0 0 0 16 16h64a16 16 0 0 0 16-16v-16a16 16 0 0 0-16-16zm144 56a72 72 0 1 0-72-72 72.09 72.09 0 0 0 72 72zm96-296H212.5l288.83-81.21a16 16 0 0 0 11.07-19.74l-4.33-15.38A16 16 0 0 0 488.33.6L47.68 124.5A64 64 0 0 0 1 186.11V448a64 64 0 0 0 64 64h384a64 64 0 0 0 64-64V192a64 64 0 0 0-64-64zm16 320a16 16 0 0 1-16 16H65a16 16 0 0 1-16-16V256h416zM113 336h128a16 16 0 0 0 16-16v-16a16 16 0 0 0-16-16H113a16 16 0 0 0-16 16v16a16 16 0 0 0 16 16z" class=""></path></svg>

After

Width:  |  Height:  |  Size: 733 B

View file

@ -0,0 +1,3 @@
<svg width="14" height="14" viewBox="0 0 14 14" data-darkreader-inline-fill="" xmlns="http://www.w3.org/2000/svg">
<path id="path" d="M1 11L3 11L3 13C3 13.55 3.45 14 4 14C4.55 14 5 13.55 5 13L5 10C5 9.45 4.55 9 4 9L1 9C0.45 9 0 9.45 0 10C0 10.55 0.45 11 1 11ZM11 3L11 1C11 0.45 10.55 0 10 0C9.45 0 9 0.45 9 1L9 4C9 4.54 9.45 5 10 5L13 5C13.55 5 14 4.54 14 4C14 3.45 13.55 3 13 3L11 3Z"/>
</svg>

After

Width:  |  Height:  |  Size: 396 B

View file

@ -0,0 +1,3 @@
<svg width="14" height="14" viewBox="0 0 14 14" data-darkreader-inline-fill="" xmlns="http://www.w3.org/2000/svg">
<path id="path" d="M1 9C0.45 9 0 9.45 0 10L0 13C0 13.55 0.45 14 1 14L4 14C4.55 14 5 13.55 5 13C5 12.45 4.55 12 4 12L2 12L2 10C2 9.45 1.55 9 1 9ZM9 1C9 1.54 9.45 2 10 2L12 2L12 4C12 4.54 12.45 5 13 5C13.55 5 14 4.54 14 4L14 1C14 0.45 13.55 0 13 0L10 0C9.45 0 9 0.45 9 1Z"/>
</svg>

After

Width:  |  Height:  |  Size: 396 B

View file

@ -1,8 +1,7 @@
import Vue from "vue"; import Vue from 'vue';
import SvgIcon from "@/components/SvgIcon"; import SvgIcon from '@/components/SvgIcon';
Vue.component("svg-icon", SvgIcon); Vue.component('svg-icon', SvgIcon);
const requireAll = (requireContext) => const requireAll = requireContext => requireContext.keys().map(requireContext);
requireContext.keys().map(requireContext); const req = require.context('./', true, /\.svg$/);
const req = require.context("./", true, /\.svg$/);
requireAll(req); requireAll(req);

View file

@ -0,0 +1 @@
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="sign-in-alt" class="svg-inline--fa fa-sign-in-alt fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M416 448h-84c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h84c17.7 0 32-14.3 32-32V160c0-17.7-14.3-32-32-32h-84c-6.6 0-12-5.4-12-12V76c0-6.6 5.4-12 12-12h84c53 0 96 43 96 96v192c0 53-43 96-96 96zm-47-201L201 79c-15-15-41-4.5-41 17v96H24c-13.3 0-24 10.7-24 24v96c0 13.3 10.7 24 24 24h136v96c0 21.5 26 32 41 17l168-168c9.3-9.4 9.3-24.6 0-34z"></path></svg>

After

Width:  |  Height:  |  Size: 579 B

View file

@ -0,0 +1 @@
<?xml version="1.0" ?><!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'><svg height="512px" id="Layer_1" style="enable-background:new 0 0 512 512;" version="1.1" viewBox="0 0 512 512" width="512px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M417.4,224H288V94.6c0-16.9-14.3-30.6-32-30.6c-17.7,0-32,13.7-32,30.6V224H94.6C77.7,224,64,238.3,64,256 c0,17.7,13.7,32,30.6,32H224v129.4c0,16.9,14.3,30.6,32,30.6c17.7,0,32-13.7,32-30.6V288h129.4c16.9,0,30.6-14.3,30.6-32 C448,238.3,434.3,224,417.4,224z"/></svg>

After

Width:  |  Height:  |  Size: 618 B

View file

@ -0,0 +1,2 @@
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="sort-amount-up" class="svg-inline--fa fa-sort-amount-up fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M304 416h-64a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h64a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM16 160h48v304a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V160h48c14.21 0 21.38-17.24 11.31-27.31l-80-96a16 16 0 0 0-22.62 0l-80 96C-5.35 142.74 1.77 160 16 160zm416 0H240a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h192a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm-64 128H240a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h128a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM496 32H240a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h256a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16z"></path></svg>

After

Width:  |  Height:  |  Size: 784 B

View file

@ -0,0 +1 @@
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="thumbs-down" class="svg-inline--fa fa-thumbs-down fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M0 56v240c0 13.255 10.745 24 24 24h80c13.255 0 24-10.745 24-24V56c0-13.255-10.745-24-24-24H24C10.745 32 0 42.745 0 56zm40 200c0-13.255 10.745-24 24-24s24 10.745 24 24-10.745 24-24 24-24-10.745-24-24zm272 256c-20.183 0-29.485-39.293-33.931-57.795-5.206-21.666-10.589-44.07-25.393-58.902-32.469-32.524-49.503-73.967-89.117-113.111a11.98 11.98 0 0 1-3.558-8.521V59.901c0-6.541 5.243-11.878 11.783-11.998 15.831-.29 36.694-9.079 52.651-16.178C256.189 17.598 295.709.017 343.995 0h2.844c42.777 0 93.363.413 113.774 29.737 8.392 12.057 10.446 27.034 6.148 44.632 16.312 17.053 25.063 48.863 16.382 74.757 17.544 23.432 19.143 56.132 9.308 79.469l.11.11c11.893 11.949 19.523 31.259 19.439 49.197-.156 30.352-26.157 58.098-59.553 58.098H350.723C358.03 364.34 384 388.132 384 430.548 384 504 336 512 312 512z"></path></svg>

After

Width:  |  Height:  |  Size: 1 KiB

View file

@ -1,3 +0,0 @@
<svg fill="currentColor" viewBox="0 0 1024 500">
<path d="M152.1 236.2c-3.5-12.1-7.8-33.2-7.8-33.2h-.5s-4.3 21.1-7.8 33.2l-11.1 37.5H163zM616 96H336v320h280c13.3 0 24-10.7 24-24V120c0-13.3-10.7-24-24-24zm-24 120c0 6.6-5.4 12-12 12h-11.4c-6.9 23.6-21.7 47.4-42.7 69.9 8.4 6.4 17.1 12.5 26.1 18 5.5 3.4 7.3 10.5 4.1 16.2l-7.9 13.9c-3.4 5.9-10.9 7.8-16.7 4.3-12.6-7.8-24.5-16.1-35.4-24.9-10.9 8.7-22.7 17.1-35.4 24.9-5.8 3.5-13.3 1.6-16.7-4.3l-7.9-13.9c-3.2-5.6-1.4-12.8 4.2-16.2 9.3-5.7 18-11.7 26.1-18-7.9-8.4-14.9-17-21-25.7-4-5.7-2.2-13.6 3.7-17.1l6.5-3.9 7.3-4.3c5.4-3.2 12.4-1.7 16 3.4 5 7 10.8 14 17.4 20.9 13.5-14.2 23.8-28.9 30-43.2H412c-6.6 0-12-5.4-12-12v-16c0-6.6 5.4-12 12-12h64v-16c0-6.6 5.4-12 12-12h16c6.6 0 12 5.4 12 12v16h64c6.6 0 12 5.4 12 12zM0 120v272c0 13.3 10.7 24 24 24h280V96H24c-13.3 0-24 10.7-24 24zm58.9 216.1L116.4 167c1.7-4.9 6.2-8.1 11.4-8.1h32.5c5.1 0 9.7 3.3 11.4 8.1l57.5 169.1c2.6 7.8-3.1 15.9-11.4 15.9h-22.9a12 12 0 0 1-11.5-8.6l-9.4-31.9h-60.2l-9.1 31.8c-1.5 5.1-6.2 8.7-11.5 8.7H70.3c-8.2 0-14-8.1-11.4-15.9z"></path>
</svg>

Before

Width:  |  Height:  |  Size: 1 KiB

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