Compare commits

...

1060 Commits

Author SHA1 Message Date
TC
b843825f72 Bump version to 1.18.0 2022-09-05 08:48:06 +02:00
b66d3bc3d4 Merge pull request #816 from th-ch/fix-downloader
Bump ytdl-core (bug fix)
2022-09-05 08:45:22 +02:00
TC
9adabd41d9 Bump ytdl-core (bug fix) 2022-09-05 00:43:58 +02:00
TC
3f3df09819 Set NODE_ENV programmatically 2022-09-05 00:38:24 +02:00
TC
1f5f597561 Prepare migration for sandboxing (path.join in preload) 2022-09-05 00:31:29 +02:00
TC
91e4433aba Hide login button in plugin 2022-09-04 23:56:41 +02:00
2d3ce4a8b3 Merge pull request #813 from th-ch/fix-tests
Bump electron and fix tests in CI
2022-09-04 23:36:19 +02:00
TC
971b7f05c5 Bump electron to latest version 2022-09-04 22:32:16 +02:00
TC
bb6115fec1 Remove jest 2022-09-04 22:24:09 +02:00
TC
2a6dc30366 Remove test environment 2022-09-04 22:24:09 +02:00
TC
5e2d843742 Migrate to playwright/test 2022-09-04 22:24:09 +02:00
TC
7aaef26cc8 Add electron flags in tests 2022-09-04 22:21:51 +02:00
TC
0a08eaaa3c Skip downloading browsers in playwright 2022-09-04 22:21:43 +02:00
TC
0d22446f20 Bump playwright and electron 2022-08-25 23:03:38 +02:00
a0543d15a6 Merge pull request #800 from th-ch/custom-css-file
Allow user to pass custom CSS file
2022-08-25 22:52:42 +02:00
TC
e62ee35b42 Rename cssFiles option to themes and add menu entry 2022-08-25 22:50:33 +02:00
TC
ef6fb402bf Allow user to pass custom CSS file 2022-08-21 23:36:02 +02:00
a8301f44be Merge pull request #799 from th-ch/snyk-upgrade-260cfeaaaf6aa5359f78e9f589e807a0
[Snyk] Upgrade html-to-text from 8.2.0 to 8.2.1
2022-08-21 22:54:52 +02:00
1ead86a220 Merge pull request #772 from th-ch/snyk-upgrade-3ee19fd614169422c21264d4fe016fa1
[Snyk] Upgrade electron-store from 8.0.1 to 8.0.2
2022-08-21 22:54:14 +02:00
03e716fe17 Merge pull request #756 from th-ch/dependabot/npm_and_yarn/jpeg-js-0.4.4
Bump jpeg-js from 0.4.3 to 0.4.4
2022-08-21 22:53:54 +02:00
f0bb328981 Merge pull request #749 from foonathan/master
Support MPRIS loop and volume change
2022-08-21 22:53:29 +02:00
f40183f0ca fix: upgrade html-to-text from 8.2.0 to 8.2.1
Snyk has created this PR to upgrade html-to-text from 8.2.0 to 8.2.1.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=referral&page=upgrade-pr
2022-08-20 22:45:27 +00:00
5b004acdc1 Update readme.md 2022-08-12 20:19:49 +02:00
0f96da9928 Change volume observer 2022-07-14 20:59:35 +02:00
dfba3d9c2d Support precise volume changes in MPRIS when possible 2022-07-11 20:20:13 +02:00
d9c51063f4 Add MPRIS volume control
Fixes #776.
2022-07-11 19:55:16 +02:00
cd9012691a fix: upgrade electron-store from 8.0.1 to 8.0.2
Snyk has created this PR to upgrade electron-store from 8.0.1 to 8.0.2.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=referral&page=upgrade-pr
2022-07-01 19:06:53 +00:00
2499f574ef Use triple equals in more places 2022-06-26 19:43:03 +02:00
e7e873866d Use triple equals 2022-06-26 17:37:25 +02:00
4ccbc741b8 Merge pull request #742 from th-ch/snyk-upgrade-45c0c305b24fe7d1bf9286a6c90b0320
[Snyk] Upgrade @cliqz/adblocker-electron from 1.23.7 to 1.23.8
2022-06-25 21:23:52 +02:00
8ec965a1a4 Merge pull request #745 from lukaszg84/master
Use ; instead of space for play/pause.
2022-06-25 21:22:50 +02:00
0936e9a258 Merge pull request #750 from EsmailELBoBDev2/patch-1
Update readme.md
2022-06-25 21:20:10 +02:00
32a5597573 Merge pull request #753 from Araxeus/fix-lyrics-font-size
fix lyrics font size
2022-06-25 21:18:44 +02:00
9932fd7647 Fix mpris playback status on play/pause 2022-06-22 18:30:49 +02:00
68429be1ce Bump jpeg-js from 0.4.3 to 0.4.4
Bumps [jpeg-js](https://github.com/eugeneware/jpeg-js) from 0.4.3 to 0.4.4.
- [Release notes](https://github.com/eugeneware/jpeg-js/releases)
- [Commits](https://github.com/eugeneware/jpeg-js/compare/v0.4.3...v0.4.4)

---
updated-dependencies:
- dependency-name: jpeg-js
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-17 01:59:01 +00:00
d7ac493337 fix lyrics font size 2022-06-16 17:21:13 +03:00
686a0a340e Update readme.md 2022-06-14 20:37:32 +02:00
bba499044b Style changes for review 2022-06-14 19:43:36 +02:00
6e1c50ede1 Support MPRIS loop 2022-06-14 15:45:58 +02:00
6e739e2723 Use ; instead of space for play/pause. 2022-06-10 11:08:36 +02:00
86029a0a73 fix: upgrade @cliqz/adblocker-electron from 1.23.7 to 1.23.8
Snyk has created this PR to upgrade @cliqz/adblocker-electron from 1.23.7 to 1.23.8.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=referral&page=upgrade-pr
2022-06-07 19:11:28 +00:00
b458925aa6 Merge pull request #734 from Araxeus/fix-in-app-menu-top-gap
fix top gap between nav-bar and browse-page
2022-06-06 20:51:11 +02:00
86a1c3c850 Merge pull request #605 from Araxeus/migrate-from-remote-to-ipc
migrate from remote to ipc + fix restart in portable app
2022-06-06 20:48:59 +02:00
8666f934cd Merge pull request #717 from th-ch/snyk-upgrade-7b576b920d24e12003dead59064f8564
[Snyk] Upgrade custom-electron-prompt from 1.4.2 to 1.5.0
2022-06-06 20:40:40 +02:00
59a93916a8 Merge pull request #685 from Araxeus/pip-part-2
Picture in Picture v2
2022-06-06 20:36:18 +02:00
f06a3c8c70 fix top gap between nav-bar and browse-page 2022-05-28 19:22:14 +03:00
7fe937b21e lint 2022-05-20 19:26:55 +03:00
a4aa22aae9 update Electron 2022-05-18 20:21:37 +03:00
TC
96b2aab683 Bump version and changelog to 1.17.0 2022-05-16 18:47:00 +02:00
54d25a26c7 fix: upgrade custom-electron-prompt from 1.4.2 to 1.5.0
Snyk has created this PR to upgrade custom-electron-prompt from 1.4.2 to 1.5.0.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=referral&page=upgrade-pr
2022-05-12 19:29:13 +00:00
f5622970c6 Merge branch 'master' into migrate-from-remote-to-ipc 2022-05-01 23:09:13 +03:00
ea09825ece Merge branch 'master' into pip-part-2 2022-05-01 23:06:30 +03:00
247764b64b Merge pull request #712 from th-ch/dependabot/npm_and_yarn/ejs-3.1.7
Bump ejs from 3.1.6 to 3.1.7
2022-05-01 22:04:08 +02:00
5e187b47d8 Merge pull request #693 from Araxeus/fix-event-listener-overload
fix injectCSS `did-finish-load` listener overload
2022-05-01 22:03:01 +02:00
1194befa48 Merge pull request #689 from th-ch/snyk-upgrade-809de6dcc81fbd20573d9ed4667b0c70
[Snyk] Upgrade @cliqz/adblocker-electron from 1.23.6 to 1.23.7
2022-05-01 22:01:17 +02:00
74d3358487 Merge branch 'master' into snyk-upgrade-809de6dcc81fbd20573d9ed4667b0c70 2022-05-01 21:59:41 +02:00
769a613ea5 Merge pull request #686 from th-ch/snyk-upgrade-ded3705d02b70c981cf38d50be5ccece
[Snyk] Upgrade custom-electron-prompt from 1.4.1 to 1.4.2
2022-05-01 21:59:00 +02:00
7280e02709 Bump ejs from 3.1.6 to 3.1.7
Bumps [ejs](https://github.com/mde/ejs) from 3.1.6 to 3.1.7.
- [Release notes](https://github.com/mde/ejs/releases)
- [Changelog](https://github.com/mde/ejs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/mde/ejs/compare/v3.1.6...v3.1.7)

---
updated-dependencies:
- dependency-name: ejs
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-01 19:54:27 +00:00
7b3a767003 Merge pull request #684 from th-ch/snyk-upgrade-82480fa720c2520dafdd84fa5f54d19b
[Snyk] Upgrade @electron/remote from 2.0.7 to 2.0.8
2022-05-01 21:54:09 +02:00
96b0d4e367 Merge pull request #699 from Araxeus/improve-plugin-submenu-ux
Improve plugin submenu ux
2022-05-01 21:53:38 +02:00
TC
ae8365f721 Bump electron-builder to fix Mac build script 2022-05-01 21:52:42 +02:00
8d85bbf5ec Merge pull request #702 from Araxeus/update-build-action
update build action
2022-05-01 21:51:11 +02:00
61cd2ef9dc Merge pull request #700 from Araxeus/rip-video-toggle-plugin
add different modes to video-toggle plugin
2022-05-01 21:43:06 +02:00
3394d647a1 Merge pull request #701 from Araxeus/lint
lint
2022-05-01 21:35:36 +02:00
882ad63fa8 Merge pull request #703 from Araxeus/imgbot
[ImgBot] Optimize images
2022-05-01 21:34:31 +02:00
5fd88ce522 Merge pull request #695 from Araxeus/add-album-to-lastfm
add album to lastfm if available
2022-05-01 21:33:16 +02:00
de280195c5 Merge pull request #680 from Araxeus/in-app-menu-hide-icon-option
[in-app-menu] add hide icon option
2022-05-01 21:32:10 +02:00
7bd69e447a update Electron 2022-04-30 15:24:37 +03:00
357f12c4d1 [ImgBot] Optimize images
*Total -- 828.18kb -> 733.19kb (11.47%)

/assets/youtube-music-tray.png -- 3.29kb -> 1.44kb (56.14%)
/web/youtube-music.svg -- 9.23kb -> 5.75kb (37.67%)
/web/screenshot.jpg -- 815.67kb -> 726.00kb (10.99%)

Signed-off-by: ImgBotApp <ImgBotHelp@gmail.com>
2022-04-23 02:52:10 +03:00
d164cd6fb9 update build action 2022-04-22 23:48:32 +03:00
5d3dc6442f stylelint: declaration-block-no-duplicate-properties 2022-04-22 16:58:49 +03:00
cb7c9bda16 eslint: no-unused-vars 2022-04-22 16:58:41 +03:00
6f2552814f stylelint: declaration-block-no-shorthand-property-overrides 2022-04-22 16:58:41 +03:00
9beebd3772 add different modes to video-toggle plugin
* Custom: like before but slightly position

* Native: use the native video-toggle

* Disabled: force disable the native video-toggle
2022-04-20 18:46:59 +03:00
7cd9506122 add separator after plugin enabled button 2022-04-20 18:27:34 +03:00
f6de5c7c22 PiP options defaults + migrations 2022-04-20 15:21:10 +03:00
2ac3df0455 add album to lastfm if available 2022-04-18 18:45:53 +03:00
2dfe098521 fix injectCSS did-finish-load listener overload 2022-04-17 18:20:08 +03:00
77d4e9cb84 add optional PiP hotkey 2022-04-15 15:57:48 +03:00
b420998458 disable the video-toggle button when in PiP mode 2022-04-15 15:27:31 +03:00
feb06b015e dont save maximized state in PiP mode 2022-04-15 15:27:16 +03:00
09ba760aff fix: upgrade @cliqz/adblocker-electron from 1.23.6 to 1.23.7
Snyk has created this PR to upgrade @cliqz/adblocker-electron from 1.23.6 to 1.23.7.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=referral&page=upgrade-pr
2022-04-13 17:15:33 +00:00
0f192aab2b fix precise-volume position in PiP 2022-04-13 17:17:25 +03:00
c992ec4607 fix: upgrade custom-electron-prompt from 1.4.1 to 1.4.2
Snyk has created this PR to upgrade custom-electron-prompt from 1.4.1 to 1.4.2.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=referral&page=upgrade-pr
2022-04-11 17:03:23 +00:00
30840804fa fix: sync pip and index.js options 2022-04-11 00:15:19 +03:00
8000a8326f fix: in-app-menu bg color edge case
when item weren't initially rendered because the window was too small, but were then accessed via the arrow keys - backgrounds was missing
2022-04-10 21:39:06 +03:00
d23bfe9368 v3 2022-04-10 21:16:43 +03:00
047085e72b fix: upgrade @electron/remote from 2.0.7 to 2.0.8
Snyk has created this PR to upgrade @electron/remote from 2.0.7 to 2.0.8.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=referral&page=upgrade-pr
2022-04-10 16:51:23 +00:00
768ec7bda7 v2 2022-04-10 19:19:20 +03:00
c25a6f9d2a launch pip from video overlay v1 2022-04-10 01:12:06 +03:00
23058729f3 Merge pull request #682 from th-ch/bypass-age-restrictions-plugin
Add plugin to bypass age restrictions
2022-04-09 23:21:46 +02:00
TC
a1c6dfb199 Add plugin for age restrictions 2022-04-09 23:00:02 +02:00
TC
89ebc230e0 Add plugin to bypass age restrictions (with userscript) 2022-04-09 22:57:57 +02:00
b4b785d773 feat: in-app-menu hideIcon option 2022-04-09 22:56:01 +03:00
57ec0a463d Merge pull request #674 from th-ch/picture-in-picture-plugin
Add "Picture in picture" plugin
2022-04-09 21:53:34 +02:00
TC
6be9b76550 Improve style and remove draggable CSS that blocks login 2022-04-09 16:59:44 +02:00
TC
ebe3baf4bc Make PiP window bigger (follow up: make it configurable) 2022-04-09 16:59:24 +02:00
648d540ca9 Merge pull request #679 from th-ch/thibaut.c/lyrics-metadata-genius
Set lyrics metadata from Genius
2022-04-09 16:54:49 +02:00
cb910a6fd7 Merge branch 'master' into migrate-from-remote-to-ipc 2022-04-09 17:04:06 +03:00
TC
e071f768b4 Force minimist 1.2.6 to fix vuln 2022-04-09 15:21:59 +02:00
TC
05b6435a5c nit: lint package.json 2022-04-09 15:03:06 +02:00
TC
71e9f280a1 Set lyrics metadata if Genius plugin is enabled 2022-04-09 15:02:54 +02:00
TC
dbc34e6d0d Export fetchFromGenius util 2022-04-09 15:02:11 +02:00
TC
d0532d691e Process lyrics HTML in Genius util 2022-04-09 15:02:06 +02:00
2f218ef108 Merge pull request #677 from th-ch/tray-app-hidden
MacOS: bring back the app in dock when using tray + app hidden
2022-04-09 12:17:06 +02:00
TC
14326d2440 Only save size/position if not in PiP 2022-04-09 12:16:30 +02:00
TC
d37e557f79 Block some shortcuts (esc, f) in PiP 2022-04-09 12:15:38 +02:00
TC
5ca0c6b8a9 Ensure player is open when going PiP + add class 2022-04-09 12:14:42 +02:00
TC
e58a580b2b Restore fullscreenable after switching to PiP mode 2022-04-09 12:13:33 +02:00
TC
f3641f5072 Set in config when PiP mode is enabled 2022-04-09 12:11:05 +02:00
TC
296ecb6740 Always inject style 2022-04-09 12:10:22 +02:00
28b5645a56 Merge branch 'master' into migrate-from-remote-to-ipc 2022-04-08 17:00:49 +03:00
742a949680 Update plugins/picture-in-picture/back.js
Co-authored-by: Araxeus <oaeben@gmail.com>
2022-04-08 15:45:33 +02:00
57290c4164 Update plugins/picture-in-picture/back.js
Co-authored-by: Araxeus <oaeben@gmail.com>
2022-04-08 15:44:03 +02:00
6d5fe9561e Update plugins/picture-in-picture/back.js
Co-authored-by: Araxeus <oaeben@gmail.com>
2022-04-08 15:43:57 +02:00
735901095f Merge pull request #644 from th-ch/snyk-upgrade-1b73c27fe4a98c0629769eba2ee53e6a
[Snyk] Upgrade @electron/remote from 2.0.4 to 2.0.5
2022-04-08 15:42:35 +02:00
27454ab527 Merge pull request #660 from th-ch/snyk-upgrade-25706373301b148d087cae43d9039d28
[Snyk] Upgrade ytpl from 2.2.3 to 2.3.0
2022-04-08 15:41:46 +02:00
TC
c345d2cb34 Merge branch 'master' of github.com:th-ch/youtube-music into snyk-upgrade
* 'master' of github.com:th-ch/youtube-music:
  Bump plist from 3.0.2 to 3.0.5
  use spread syntax instead of Array.from
  Fix lyrics genius missing parts
  feat: option to force show like buttons
  Fix lyrics genius missing parts
  [precise-volume] fix expand-volume-slider not updating its value
  fix: upgrade ytdl-core from 4.10.1 to 4.11.0
  add always-on-top option
  fix volumeHud position in miniplayer
  fix: upgrade @cliqz/adblocker-electron from 1.23.4 to 1.23.5
2022-04-08 15:41:14 +02:00
1da297a356 Merge pull request #659 from th-ch/snyk-upgrade-943da220bfc070d47a809365f06e4136
[Snyk] Upgrade ytdl-core from 4.10.1 to 4.11.0
2022-04-08 15:33:12 +02:00
8ebdaf6fa0 Merge branch 'master' into snyk-upgrade-1b73c27fe4a98c0629769eba2ee53e6a 2022-04-08 15:31:29 +02:00
d4d82867f5 Merge pull request #678 from th-ch/dependabot/npm_and_yarn/plist-3.0.5
Bump plist from 3.0.2 to 3.0.5
2022-04-08 15:30:44 +02:00
2e99d6b9bb Bump plist from 3.0.2 to 3.0.5
Bumps [plist](https://github.com/TooTallNate/node-plist) from 3.0.2 to 3.0.5.
- [Release notes](https://github.com/TooTallNate/node-plist/releases)
- [Changelog](https://github.com/TooTallNate/plist.js/blob/master/History.md)
- [Commits](https://github.com/TooTallNate/node-plist/commits)

---
updated-dependencies:
- dependency-name: plist
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-08 13:25:18 +00:00
a1e740b881 Merge pull request #624 from th-ch/snyk-upgrade-8a29fb2f6f9f73947c0629bb91d5a7f1
[Snyk] Upgrade @cliqz/adblocker-electron from 1.23.4 to 1.23.5
2022-04-08 15:24:47 +02:00
TC
de14d64927 nit: re-align quit menu 2022-04-08 15:17:36 +02:00
TC
6c93d635d0 Bring back the app in the dock (MacOS) when it was hidden 2022-04-08 15:17:26 +02:00
f4df6fceee Merge branch 'migrate-from-remote-to-ipc' of https://github.com/Araxeus/youtube-music into migrate-from-remote-to-ipc 2022-04-07 22:12:54 +03:00
d69c8a754e Merge branch 'local-upstream/master' into migrate-from-remote-to-ipc 2022-04-07 22:12:25 +03:00
c3d90d8b27 update Electron
+ update electron-unhandled
2022-04-07 22:09:54 +03:00
10681e4e99 Merge pull request #645 from Araxeus/fix-volumeHud-position-on-miniplayer
[Precise-Volume] fix volumeHud position in miniplayer
2022-04-07 21:02:22 +02:00
48aa3ba0d8 Merge pull request #655 from Araxeus/add-always-on-top-option
add always-on-top option
2022-04-07 21:01:15 +02:00
f98e4ea749 Merge pull request #670 from Araxeus/fix-precise-volume-not-updating-expand-slider
[precise-volume] fix expand-volume-slider not updating its value
2022-04-07 21:00:19 +02:00
dc500efb79 Merge pull request #671 from Araxeus/lyrics]-fix-part-of-lyrics-is-missing
Fix lyrics genius missing parts
2022-04-07 20:59:30 +02:00
8d9dafb149 Merge pull request #673 from Araxeus/force-show-like-buttons
feat: option to force show like buttons
2022-04-07 20:56:34 +02:00
TC
4ddd2f339b add PiP plugin to readme list 2022-04-07 20:05:13 +02:00
TC
d2265b59d7 Create first version of picture in picture plugin 2022-04-07 20:01:29 +02:00
d47b03c23d use spread syntax instead of Array.from 2022-04-06 20:15:24 +03:00
4c857cb9e9 Merge branch 'lyrics]-fix-part-of-lyrics-is-missing' of https://github.com/Araxeus/youtube-music into lyrics]-fix-part-of-lyrics-is-missing 2022-04-06 20:05:22 +03:00
c31f6cc797 Fix lyrics genius missing parts 2022-04-06 20:04:26 +03:00
0d3fa261a7 feat: option to force show like buttons 2022-04-06 19:48:58 +03:00
b6ee861166 Fix lyrics genius missing parts 2022-04-06 18:57:39 +03:00
f9cf12b7d3 [precise-volume] fix expand-volume-slider not updating its value 2022-04-06 18:26:05 +03:00
bed8d0a7f2 update Electron
+ update electron-unhandled
2022-03-30 18:47:51 +03:00
afac520ff8 fix: upgrade ytpl from 2.2.3 to 2.3.0
Snyk has created this PR to upgrade ytpl from 2.2.3 to 2.3.0.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=referral&page=upgrade-pr
2022-03-26 17:12:51 +00:00
1332c66050 fix: upgrade ytdl-core from 4.10.1 to 4.11.0
Snyk has created this PR to upgrade ytdl-core from 4.10.1 to 4.11.0.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=referral&page=upgrade-pr
2022-03-26 17:12:48 +00:00
7f08579671 add always-on-top option 2022-03-21 18:17:22 +02:00
d5e4f3af46 fix volumeHud position in miniplayer 2022-03-14 22:00:57 +02:00
bdceb4d462 fix: upgrade @electron/remote from 2.0.4 to 2.0.5
Snyk has created this PR to upgrade @electron/remote from 2.0.4 to 2.0.5.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=referral&page=upgrade-pr
2022-03-14 18:16:47 +00:00
2758a44965 fix: upgrade @cliqz/adblocker-electron from 1.23.4 to 1.23.5
Snyk has created this PR to upgrade @cliqz/adblocker-electron from 1.23.4 to 1.23.5.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=referral&page=upgrade-pr
2022-02-28 18:26:03 +00:00
704fba9aba fix portable app restart 2022-02-24 20:52:16 +02:00
5cffb6f062 Merge pull request #619 from Araxeus/fix-prompt-options
fix custom titlebar in prompt options
2022-02-24 19:27:56 +01:00
407887254f Merge branch 'master' into migrate-from-remote-to-ipc 2022-02-23 17:34:24 +02:00
47729130c9 fix custom titlebar in prompt options 2022-02-23 17:15:10 +02:00
7088941179 update electron 2022-02-22 18:27:45 +02:00
TC
ff39ddb277 Update changelog 2022-02-20 19:15:07 +01:00
TC
1d9bfe8ac8 Add automatic changelog 2022-02-20 18:50:12 +01:00
TC
edfa9d2ff5 Re-format package.json 2022-02-20 18:46:50 +01:00
1eeaf1dd0a remove @electron/remote 2022-02-20 19:38:42 +02:00
TC
efd2c912a8 Bump version to 1.16.0 2022-02-20 18:37:48 +01:00
9abf7a77d8 Merge branch 'local-upstream/master' into migrate-from-remote-to-ipc 2022-02-20 19:34:18 +02:00
2dd208c21b Merge pull request #596 from Araxeus/update-custom-electron-titlebar
update in-app-menu
2022-02-20 18:31:59 +01:00
c7fe81475f Merge pull request #602 from xn-oah/master
Fix clientID
2022-02-20 18:25:25 +01:00
0acd16fd5d Update yarn.lock 2022-02-15 19:01:23 +02:00
107c79f6a8 Merge branch 'master' of https://github.com/xn-oah/youtube-music 2022-02-13 16:02:53 -06:00
6aa789fb6a fixed clientID 2022-02-13 16:02:50 -06:00
94c86491d0 Merge branch 'th-ch:master' into master 2022-02-13 16:00:29 -06:00
a9f5f376d0 fixed clientID 2022-02-13 15:59:53 -06:00
5bd97685b9 migrate from remote to ipc 2022-02-13 23:45:53 +02:00
TC
ea35da52c3 Refactor Genius logic into separate util 2022-02-13 22:19:16 +01:00
6cad6871bf fix directory path 2022-02-13 22:02:12 +01:00
TC
f865dfd1b6 Fix https://github.com/th-ch/youtube-music/pull/578#issuecomment-1035517531 2022-02-13 19:56:46 +01:00
37e84d3287 Merge pull request #600 from th-ch/snoretoast-custom-compile
Add snoretoast custom compile script
2022-02-13 19:44:27 +01:00
7192b253eb Merge pull request #591 from Araxeus/update-snoretoast
fix interactive notifications icon + exclude platform specific plugins from build
2022-02-13 19:43:46 +01:00
1b99cc6930 use custom snoretoast on release #600 2022-02-13 20:40:09 +02:00
7f0d62383d Merge pull request #587 from xn-oah/master
Add album title to largeImage and change paused icon
2022-02-13 19:07:43 +01:00
TC
44300e757f Add snoretoast custom compile script 2022-02-13 18:14:57 +01:00
dc928542f8 lighten up menuItem background color 2022-02-11 16:29:11 +02:00
1834e1e938 Merge branch 'th-ch:master' into update-snoretoast 2022-02-11 15:54:13 +02:00
8263918033 add toggle fullscreen to view menu
enables f11 shortcut
2022-02-11 15:49:33 +02:00
247777bcc4 remove remote module from prompt-options 2022-02-11 15:24:42 +02:00
023db03278 Merge branch 'master' into update-custom-electron-titlebar 2022-02-10 23:13:55 +02:00
TC
a3f7eebd14 Bump version 2022-02-10 00:37:35 +01:00
5c7d612e97 Merge pull request #595 from Araxeus/useragent-option
make useragent override optional
2022-02-10 00:33:59 +01:00
465e8e1717 Merge branch 'master' into useragent-option 2022-02-10 00:32:52 +01:00
621c5de357 Merge pull request #588 from Araxeus/fix-album-name
get album name from DOM
2022-02-10 00:15:02 +01:00
TC
4d890c4941 Fix warnings in genius plugin 2022-02-10 00:08:40 +01:00
9b7c1a8d37 Merge pull request #584 from Araxeus/fix-lyrics
fix various lyrics issues
2022-02-10 00:07:33 +01:00
05b877b702 Merge pull request #580 from Araxeus/discord-timeout-time-prompt
discord set inactivity timeout prompt
2022-02-09 23:49:31 +01:00
8268b18eee Merge branch 'master' into discord-timeout-time-prompt 2022-02-09 23:47:01 +01:00
ed15ee92df Merge pull request #578 from Araxeus/single-instance-lock-option
add single instance lock option
2022-02-09 23:44:54 +01:00
c2fdfcca58 Merge pull request #561 from Araxeus/fix-restart-on-config-change
fix "restart app on config change" option
2022-02-09 23:40:57 +01:00
ac54d33fa7 Merge pull request #562 from Araxeus/fix-window-position-save-spam
fix window position save spam
2022-02-09 23:37:56 +01:00
38ffc093c3 Merge branch 'master' into update-custom-electron-titlebar 2022-02-07 20:57:15 +02:00
37c0ceaafe Merge branch 'master' into fix-restart-on-config-change 2022-02-07 17:27:27 +02:00
47f71a6022 Merge branch 'master' into discord-timeout-time-prompt 2022-02-07 17:24:44 +02:00
08a39a59d3 Merge branch 'master' into fix-lyrics 2022-02-07 17:14:20 +02:00
e6e83de89d Merge pull request #583 from Araxeus/fix-adblocker-loading-late
load adblocker sooner
2022-02-07 00:49:21 +01:00
1d1a9f5094 Merge pull request #585 from Araxeus/update-readme
add description of new plugins to readme
2022-02-07 00:45:28 +01:00
a5ba0b1a1a Merge pull request #573 from lazerl0rd/patch-1
Use `center` alignment for lyrics text
2022-02-07 00:43:54 +01:00
d785b9b95b Merge pull request #567 from Araxeus/fix-precise-volume-hud-position
fix precise-volume hud positioning
2022-02-07 00:42:33 +01:00
2f5e0c0038 Merge pull request #565 from Araxeus/update-electron
update electron and dependencies
2022-02-07 00:34:43 +01:00
09bd271df2 update in-app-menu 2022-02-06 03:32:15 +02:00
766dd21cb7 make useragent override optional 2022-02-05 18:24:37 +02:00
fef711549f update electron to v17.0.0 2022-02-05 15:20:14 +02:00
ca624f4df8 Merge branch 'master' into update-electron 2022-02-01 22:56:08 +02:00
8be07bcb7a update dependencies 2022-02-01 22:53:10 +02:00
271d5258ca fix interactive notifications icon 2022-02-01 19:47:01 +02:00
721f733dc4 update electron to 16.0.8 2022-01-31 23:50:38 +02:00
9b8d9c4905 get album name from DOM 2022-01-31 01:02:28 +02:00
543db59a55 fix formatting 2022-01-30 13:15:29 -06:00
e9a670831c Add album title to largeImage and change paused icon 2022-01-30 12:48:15 -06:00
24f694737a add new plugins to readme 2022-01-30 19:12:42 +02:00
fc111e2513 keep footer out of contents div 2022-01-29 18:05:55 +02:00
187f6833f4 Merge branch 'fix-lyrics' of https://github.com/Araxeus/youtube-music into fix-lyrics 2022-01-29 17:58:47 +02:00
b042d0a8ca use regex on cleanupName() 2022-01-29 17:57:39 +02:00
eff0995d78 fix showing old lyrics if new lyrics couldn't be resolved 2022-01-29 17:57:14 +02:00
366c90f71d fix showing old lyrics if new lyrics couldn't be resolved 2022-01-29 17:10:47 +02:00
909036108f reenable lyrics footer 2022-01-29 16:56:55 +02:00
41b9ab4815 lint 2022-01-29 16:35:52 +02:00
60bb5b861d change to new lyrics even if lyrics tab was already selected 2022-01-29 11:35:18 +02:00
900c44d9c0 fix disabled lyrics tab 2022-01-29 11:14:03 +02:00
babc50099c fix lyrics css styling 2022-01-29 11:13:53 +02:00
ea191a3005 load adblocker sooner 2022-01-29 09:37:02 +02:00
02081d8272 fix precise-volume hud positioning 2022-01-27 22:41:55 +02:00
03e27519db discord set inactivity timeout prompt 2022-01-27 22:32:45 +02:00
1248f1c8ec add single instance lock option 2022-01-27 10:00:35 +02:00
766bd378fd Use center alignment for lyrics text
This seems to be the case for most music applications [that I've used] and also provides the benefit of "fixing" how lyrics appear in RTL languages (such as Arabic).
2022-01-26 15:58:50 +00:00
61eb23614a Merge pull request #557 from Araxeus/fix-filepath-error
filenamify playlist folder name
2022-01-23 14:48:10 +01:00
3f606695bf Merge pull request #554 from th-ch/snyk-fix-6b7a813ed44a44be91e81ec320a8fde1
[Snyk] Security upgrade node-fetch from 2.6.6 to 2.6.7 (3.1.1 incompatible)
2022-01-23 14:40:53 +01:00
74b67c3d33 fix restart app on config change option 2022-01-23 00:12:20 +02:00
TC
8dd41cca09 Use v2.6.7 of node-fetch 2022-01-22 20:02:06 +01:00
TC
89ea66ba2b Simplify off-screen check 2022-01-22 19:57:23 +01:00
199d8ba4d7 Merge pull request #548 from Araxeus/offscreen-app-fix
fix app starting offscreen
2022-01-22 19:56:12 +01:00
b0f29dde94 Merge pull request #566 from th-ch/release-mac-arm64
Release Mac arm64
2022-01-22 19:54:40 +01:00
TC
90f4c9383f Release Mac arm64 2022-01-22 19:47:10 +01:00
4c8996096a Merge pull request #553 from arunim2405/master
Build command for Apple (m1) silicon macs
2022-01-22 19:45:57 +01:00
315048722f update electron to 16.0.7 2022-01-22 18:07:47 +02:00
9403804128 fix multiple monitor calculations 2022-01-21 21:58:44 +02:00
28b6d99599 lint 2022-01-21 00:05:05 +02:00
92fc8f325a Merge branch 'fix-window-position-save-spam' of https://github.com/Araxeus/youtube-music into fix-window-position-save-spam 2022-01-21 00:02:14 +02:00
a744a2ebde fix window position save spam 2022-01-21 00:01:14 +02:00
c8f62f6d19 fix window position save spam
(and also window position being forgotten on maximizing)
2022-01-20 23:45:57 +02:00
7fd9d5a971 use -8 insteaf of 0
(often maximized app will have -8,-8 coordinates)
2022-01-19 19:40:58 +02:00
cb920194ce filenamify playlist folder name 2022-01-18 18:32:25 +02:00
dc728786ee fix: package.json & yarn.lock to reduce vulnerabilities
The following vulnerabilities are fixed with an upgrade:
- https://snyk.io/vuln/SNYK-JS-NODEFETCH-2342118
2022-01-17 18:10:50 +00:00
8cfc8d1ba1 support build for arm64 macs 2022-01-17 11:58:52 +05:30
68bd691702 check if window.y is offscreen 2022-01-16 20:02:35 +02:00
44aa62c9c8 Merge pull request #545 from th-ch/snyk-upgrade-d09c6b75ea60c0149b8328cb6bad2f0d
[Snyk] Upgrade custom-electron-titlebar from 3.2.9 to 3.2.10
2022-01-16 17:31:38 +01:00
2ad6c0fcdc Merge pull request #551 from Araxeus/fix-linux-duplicate-mediasession
Fix duplicate media session on linux
2022-01-16 17:29:58 +01:00
TC
40fbf3441a Backport missing changes for playlist badge 2022-01-16 17:29:21 +01:00
96f0d30818 Merge pull request #550 from Araxeus/download-playlist-badge-count
show a badge remaining items when downloading a playlist
2022-01-16 17:26:14 +01:00
90d6f13b56 Merge branch 'master' into download-playlist-badge-count 2022-01-16 17:23:43 +01:00
a0f2233db4 Merge pull request #549 from Araxeus/fix-download-button-on-playlist-menu
allow downloading playlists from popup menu
2022-01-16 17:19:51 +01:00
57ace9d504 lint 2022-01-14 00:08:43 +02:00
c2cc3cf7a0 fix duplicate mpris session 2022-01-13 14:46:41 +02:00
17a24cbb04 set badge on downloader playlist 2022-01-12 14:29:56 +02:00
74f61a532d downloader lint&refactor 2022-01-12 09:49:27 +02:00
c7e793b66e fix playback speed slider showing up where it shouldn't 2022-01-11 23:41:17 +02:00
21c149efc7 update ytdl-core 2022-01-11 22:54:53 +02:00
5e68d2487f allow downloading playlists from popup menu 2022-01-11 22:54:53 +02:00
e8bbc5ec1c fix app starting offscreen 2022-01-11 20:14:33 +02:00
97013d8373 fix: upgrade custom-electron-titlebar from 3.2.9 to 3.2.10
Snyk has created this PR to upgrade custom-electron-titlebar from 3.2.9 to 3.2.10.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=referral&page=upgrade-pr
2022-01-08 19:06:52 +00:00
ec4c2e92af Merge pull request #539 from markbaas/mpris-artist-fix
xesam:artist should be a list
2022-01-07 22:11:54 +01:00
TC
81dadeddb9 Disable NODE_OPTIONS in entry file 2022-01-07 22:09:26 +01:00
7f3a554bc3 Merge pull request #537 from Araxeus/fix-song-info-bugs
fix notifications showing thumbnail of last song
2022-01-07 22:04:47 +01:00
98f990fcdd dont send callback on playPause() if still handling data from new song
fix notifications showing thumbnail of last song
2022-01-04 19:40:06 +02:00
75999e9dcf xesam:artist should be a list 2022-01-04 15:18:19 +01:00
4d595f56d5 Update readme (Spectron -> Playwright) 2022-01-02 22:31:19 +01:00
TC
f44b6f0c33 Bump version to 1.15.0 2021-12-30 19:39:20 +01:00
TC
c45e4e50fc Bump electron to 16.0.5 2021-12-30 19:39:03 +01:00
TC
9839a973f7 nit: re-format package.json 2021-12-30 19:35:53 +01:00
9ea967f03b Merge pull request #531 from th-ch/fix-tests
Switch from spectron to playwright to fix tests
2021-12-30 19:35:00 +01:00
TC
9d6765125b Switch from spectron to playwright to fix tests 2021-12-30 19:26:01 +01:00
TC
8d66735585 Add presets to FFmpeg in menu 2021-12-30 18:46:43 +01:00
14b4c55ce7 Merge pull request #529 from th-ch/snyk-upgrade-27f67e987dd094f8f1db19ad7f90c292
[Snyk] Upgrade @cliqz/adblocker-electron from 1.23.0 to 1.23.1
2021-12-30 17:59:53 +01:00
1d1f4bbcc3 Merge branch 'master' into snyk-upgrade-27f67e987dd094f8f1db19ad7f90c292 2021-12-30 17:59:34 +01:00
bd520c7eff Merge pull request #525 from Araxeus/fix-precise-volume-options-sync
fix precise-volume options sync
2021-12-30 17:57:13 +01:00
73e201bb2c Merge pull request #524 from MulverineX/patch-1
Add album art/thumbnail to discord activity
2021-12-30 15:10:07 +01:00
81b08917ae Merge pull request #521 from Araxeus/fix-skip-silences
fix skip-silences plugin
2021-12-30 15:08:56 +01:00
81c2ab34d9 Merge pull request #520 from th-ch/snyk-upgrade-7535be87da222abdba60d9fa36da34b5
[Snyk] Upgrade electron-updater from 4.6.2 to 4.6.3
2021-12-30 15:06:06 +01:00
TC
33faa2deb3 nit: improve comment for shared Array Buffer 2021-12-30 14:59:11 +01:00
TC
4d4ac56486 Ensure NODE_OPTIONS are unset in dev mode to avoid warning 2021-12-30 14:58:21 +01:00
56ac2b3b06 Merge pull request #515 from Araxeus/fix-useragents
update electron & remote & user agents
2021-12-30 14:57:36 +01:00
c72ea4bad5 fix: upgrade @cliqz/adblocker-electron from 1.23.0 to 1.23.1
Snyk has created this PR to upgrade @cliqz/adblocker-electron from 1.23.0 to 1.23.1.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=referral&page=upgrade-pr
2021-12-27 20:52:46 +00:00
d60069555e Merge pull request #513 from markbaas/master
fixes mpris bug in snap
2021-12-27 16:12:40 +01:00
ed7025b4a2 fix precise-volume options sync 2021-12-24 02:13:21 +02:00
5fbc0f8122 Add album art/thumbnail to discord activity 2021-12-23 11:36:11 -07:00
02a989ca07 fix unnecessary skips 2021-12-18 21:03:32 +02:00
7c6fe6748e fix: upgrade electron-updater from 4.6.2 to 4.6.3
Snyk has created this PR to upgrade electron-updater from 4.6.2 to 4.6.3.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=referral&page=upgrade-pr
2021-12-18 11:02:24 +00:00
8f2ed3039a add comment to useragent fix 2021-12-16 19:29:09 +02:00
baeebd1959 downloader fixes
* --experimental-wasm-bulk-memory
* SharedArrayBuffer
* getFolder from front
* ytdl-core 4.9.2
2021-12-16 19:15:55 +02:00
49edbf723f fix custom-electron-prompt & remote 2021-12-16 18:28:49 +02:00
3764ce9a7c update custom-electron-titlebar 2021-12-16 18:01:11 +02:00
46943520bd Merge branch 'master' into fix-useragents 2021-12-15 19:32:14 +02:00
1048b3f99a Merge pull request #519 from th-ch/skip-silences-plugin
Add "Skip silences" plugin
2021-12-14 23:31:14 +01:00
TC
b1e40271e6 nit: re-order dependencies 2021-12-14 23:17:06 +01:00
TC
11429978c9 Add plugin to skip silences 2021-12-14 23:16:41 +01:00
47ca6e0b1f use session.webRequest.onBeforeSendHeaders for useragent 2021-12-14 19:22:02 +02:00
a273f6f73c fix video toggle button appearing when in song mode 2021-12-14 00:34:32 +02:00
c8ba85be76 use firefox as falllback useragent 2021-12-14 00:34:10 +02:00
6633243628 use @rozzzly/custom-electron-titlebar 2021-12-13 21:10:59 +02:00
2fb47933ac fix useragents 2021-12-13 21:06:52 +02:00
4fd683ed23 update electron & remote module 2021-12-13 20:10:36 +02:00
e1e9748002 always on useragent 2021-12-13 01:11:13 +02:00
dd122666c5 update useragents 2021-12-13 00:56:13 +02:00
5483f0ee36 Merge pull request #510 from MiepHD/master
Aligned lyric design
2021-12-10 21:15:36 +01:00
2c6c80d829 Merge pull request #509 from Araxeus/mpris-urgent-fix
Fix mpris bugs - follows #480
2021-12-10 21:14:31 +01:00
584d3e83c6 fixes mpris bug in snap 2021-12-10 20:52:16 +01:00
58d5256dd2 1vw would fit perfectly 2021-12-05 17:41:59 +01:00
920d61a1c6 Aligned lyric design
I aligned the lyric to the normal lyrics so that the lyric isn't that tiny
2021-12-04 20:53:19 +01:00
c5c2d5b74c Hide cast button which doesn't work 2021-12-03 16:56:51 +02:00
2daee01ff7 Fix bugs from bad merge conflict solving
-fix missing songControls
-use player.seeked directly
-fix 'seeked' event listener
-fix e.target instead of e.detail in apiLoaded event
-fix document.querySelector('video') before apiLoaded
-setup timeChange Listener if linux+shortcuts enabled
2021-12-03 15:55:40 +02:00
d13c9b7ca6 Merge pull request #476 from Araxeus/mix-fixes
Various small fixes (discord, video-toggle, precise-volume, playback-speed, shortcuts, lyrics)
2021-12-02 21:11:28 +01:00
5296a88525 Merge pull request #480 from Araxeus/mpris+tuna-fix
Mpris + obs-tuna fixes
2021-12-02 21:03:03 +01:00
8ce4b5b297 lint 2021-12-01 21:44:48 +02:00
2c39c0efed Merge branch 'master' into mpris+tuna-fix 2021-12-01 20:11:59 +02:00
e917abaec9 fix merge error 2021-12-01 00:08:55 +02:00
bdd0a2e8db Merge branch 'master' into mix-fixes 2021-12-01 00:06:15 +02:00
362003e10e Merge pull request #498 from th-ch/snyk-upgrade-9d2eea8c019b6593f1ef01f7fe8f404b
[Snyk] Upgrade node-fetch from 2.6.5 to 2.6.6
2021-11-30 00:16:34 +01:00
4e4b557413 Merge pull request #491 from Araxeus/fix-blur
fix interaction between blur navbar & in-app-menu
2021-11-30 00:14:49 +01:00
3a068af925 Merge pull request #475 from th-ch/snyk-upgrade-55c8a0f6d6911f431ebf75ad846e8f6c
[Snyk] Upgrade @cliqz/adblocker-electron from 1.22.7 to 1.23.0
2021-11-30 00:12:21 +01:00
44ca812330 Merge pull request #488 from Rubecks/exponential-volume-plugin
New Plugin: Exponential Volume
2021-11-30 00:10:48 +01:00
74a69e1c7a Merge pull request #474 from th-ch/snyk-upgrade-267eeda31c348d529d38d5a6413ef858
[Snyk] Upgrade electron-updater from 4.6.0 to 4.6.1
2021-11-30 00:06:42 +01:00
c3ef16c3dd Merge pull request #477 from Araxeus/fix-loadeddata/metdata-events-rarely-not-firing
Fix loadeddata/metadata video events rarely not firing (+other small fixes)
2021-11-29 23:52:23 +01:00
8c5ac17cdf fix multiple songInfo calls on start 2021-11-23 18:53:04 +02:00
c99b95e611 use config.plugins.isEnabled 2021-11-22 22:52:38 +02:00
4362101c0a lint 2021-11-22 22:08:24 +02:00
7ba205cc6c fix backquotes in keybind prompt 2021-11-22 18:59:29 +02:00
abc1712cf7 fix counter prompt 2021-11-22 18:33:32 +02:00
92452f804f fix song-info-request 2021-11-22 18:20:12 +02:00
c76df84ce3 fix: upgrade node-fetch from 2.6.5 to 2.6.6
Snyk has created this PR to upgrade node-fetch from 2.6.5 to 2.6.6.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=referral&page=upgrade-pr
2021-11-22 04:09:33 +00:00
185ebbf417 fix downloader playlist download 2021-11-21 19:44:01 +02:00
6726e2600b rework songInfo pause listener 2021-11-14 23:49:19 +02:00
93e0664f95 fix height & blur of search page item header 2021-11-14 22:02:37 +02:00
bf45ed10aa fix #490 2021-11-14 21:45:34 +02:00
8da78d50c4 Exponential Volume Plugin 2021-11-12 17:58:39 -03:00
b27a959c2b fix video-toggle&precise-volume interaction 2021-11-12 18:42:58 +02:00
cfe719b6bd use native thumbnail without modifiers 2021-11-12 17:46:40 +02:00
071799c435 fix some shortcuts 2021-11-12 16:39:43 +02:00
87ee7ed83d lint video-toggle 2021-11-10 22:35:49 +02:00
08fdd07969 speed up sponsorblock 2021-11-10 20:44:13 +02:00
02d5b78f55 add songInfo.album 2021-11-10 20:11:45 +02:00
5492afe5f6 add catch to fetch 2021-11-10 19:08:19 +02:00
9a7baeac23 fix tuna time update 2021-11-10 18:45:42 +02:00
ccfe7434bf fix mpris 2021-11-10 18:23:55 +02:00
6dbed73e6b fix disable autoplay 2021-11-09 18:52:03 +02:00
895136af0a used youtube's videodatachange event 2021-11-09 17:57:06 +02:00
72b4398024 lint&fix video-toggle plugin 2021-11-09 15:17:26 +02:00
65ce62adc1 use $('video') srcChanged event instead of loadeddata/metadata 2021-11-09 13:29:41 +02:00
eafdd5046d fix lyric text size 2021-11-09 10:42:32 +02:00
bbece751c0 lint playback speed 2021-11-09 10:03:06 +02:00
719c244e32 fix #472 2021-11-09 10:01:33 +02:00
e70b41b256 fix: upgrade @cliqz/adblocker-electron from 1.22.7 to 1.23.0
Snyk has created this PR to upgrade @cliqz/adblocker-electron from 1.22.7 to 1.23.0.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=referral&page=upgrade-pr
2021-11-09 05:45:20 +00:00
f4b6fd53f3 fix: upgrade electron-updater from 4.6.0 to 4.6.1
Snyk has created this PR to upgrade electron-updater from 4.6.0 to 4.6.1.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=referral&page=upgrade-pr
2021-11-09 05:45:17 +00:00
f40ed04899 Merge pull request #467 from th-ch/snyk-upgrade-cfd310bb818846c87b2239715bd6d1c1
[Snyk] Upgrade custom-electron-prompt from 1.1.0 to 1.2.0
2021-11-07 15:56:27 +01:00
c897323be0 fix: upgrade custom-electron-prompt from 1.1.0 to 1.2.0
Snyk has created this PR to upgrade custom-electron-prompt from 1.1.0 to 1.2.0.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=referral&page=upgrade-pr
2021-11-02 06:46:27 +00:00
TC
d7c4716a6e Re-order plugins in readme 2021-11-01 22:49:34 +01:00
TC
461cac741b nit: add new line at end of file 2021-11-01 22:42:28 +01:00
TC
cee2e066b9 Fix apiLoaded event listener in video-toggle plugin 2021-11-01 22:42:03 +01:00
TC
953d6fe3e4 Migrate old "hide-video-player" plugin to new one 2021-11-01 22:40:26 +01:00
c592a26e42 Merge pull request #448 from Araxeus/new-hide-video-player
Video Toggle Plugin
2021-11-01 22:11:38 +01:00
62bacf76d0 change file names to lower case 2021-11-01 23:10:15 +02:00
fc254db010 Merge pull request #462 from Araxeus/fix-playback-speed-plugin
fix playback speed plugin
2021-11-01 22:10:02 +01:00
0287b69424 fix missing thumbnails
+forced push fix woupsie
2021-11-01 23:04:39 +02:00
ceebd99927 Merge pull request #465 from Araxeus/fix-sponsorblock-v2
Fix sponsorblock skipping when not needed
2021-11-01 21:54:05 +01:00
41285ac9fc fix slider not working on tap 2021-11-01 22:23:26 +02:00
7b9415033f use loadedmetadata instead of loadeddata 2021-11-01 20:03:57 +02:00
b1ffd93bc2 lint in-app-menu 2021-11-01 19:57:28 +02:00
64637a6ac5 Reset segments on song end 2021-11-01 19:57:15 +02:00
b83afa22d9 Merge remote-tracking branch 'upstream/master' into fix-playback-speed-plugin 2021-11-01 18:07:54 +02:00
c68daabeab lint audio-compressor plugin 2021-11-01 18:07:21 +02:00
9ec0830a65 Merge remote-tracking branch 'upstream/master' into new-hide-video-player 2021-11-01 17:59:35 +02:00
48943ee74b lint 2021-11-01 16:06:55 +02:00
29d5b3c7db lint 2021-11-01 16:02:27 +02:00
TC
3de574a2e4 Remove debug log from genius plugin + add a dev log 2021-11-01 12:13:22 +01:00
e765d18ab0 Merge pull request #463 from Araxeus/use-apiLoaded-event-for-time-update
Sponsorblock fix + use new apiLoaded event
2021-11-01 12:03:47 +01:00
4629759eec Merge pull request #458 from Araxeus/use-apiReady-on-audio-compressor-plugin
use apiLoaded event in audio-compressor plugin
2021-11-01 11:47:11 +01:00
a14d27da70 Merge pull request #456 from Araxeus/hide-menu-initial-alert
alert on initial hide-menu enabled
2021-11-01 11:44:27 +01:00
5256ffcf77 Merge pull request #451 from Araxeus/fix-blur-plugin
Blur plugin tweaks and integration with in-app-menu
2021-11-01 11:34:54 +01:00
e2bbc6abbc Merge pull request #449 from Araxeus/fix-resume-on-start
set resume on start url to songInfo.url
2021-11-01 11:30:03 +01:00
6243e6fd48 set max playback speed to 16 ;) 2021-10-30 15:56:12 +03:00
1434849142 simplify playback rate steps 2021-10-30 15:40:45 +03:00
9bd089adb0 add check for lowest playback speed (0.07) 2021-10-30 14:57:16 +03:00
6c1a4c0ac2 playbackSpeed wheel listener 2021-10-30 14:49:03 +03:00
d35fef82fe fix sponsoblock spam updating time 2021-10-30 13:30:38 +03:00
bca22d8e24 update electron to v12.2.2 fixes fetch CERT_HAS_EXPIRED error 2021-10-30 13:17:47 +03:00
754eac6ee0 use apiLoaded 'once'
lint
2021-10-30 12:53:14 +03:00
762566cce6 lint 2021-10-30 12:52:04 +03:00
286bc0113e fix sponsorblock plugin 2021-10-30 12:43:51 +03:00
62e8e673eb use apiLoaded 'once' 2021-10-30 12:17:32 +03:00
68996809f0 add apiLoaded event to disable-autoplay plugin 2021-10-30 12:05:03 +03:00
48a2a13163 fix playback speed plugin 2021-10-30 12:00:29 +03:00
6e94422b15 use apiLoaded event in audio-compressor plugin 2021-10-26 20:57:56 +03:00
713e005aa8 Update readme.md 2021-10-26 20:45:43 +03:00
3f3ab766ce Update readme.md 2021-10-26 20:34:44 +03:00
00e1bbf994 Update readme.md 2021-10-26 20:31:27 +03:00
b45adac847 Update readme.md 2021-10-26 20:03:01 +03:00
3d9b495863 Update readme.md 2021-10-26 19:50:15 +03:00
a70364facf lint 2021-10-26 19:23:10 +03:00
02cb39602f alert on initial hide-menu enabled 2021-10-26 19:07:10 +03:00
12c31725fe fixes scrollbar position relative to navbar depending on player-page-open 2021-10-25 22:45:11 +03:00
e0841060df fix comment typo 2021-10-25 20:20:52 +03:00
b7b55b5c83 Add blur to (library)header + make in-app-menu compatible 2021-10-25 00:43:42 +03:00
43a9093eb7 set resume on start url to songInfo.url 2021-10-24 21:17:45 +03:00
67e43bc0e3 Video Toggle Plugin 2021-10-24 20:09:30 +03:00
TC
a47c906ab2 Add audio compressor plugin to readme 2021-10-24 17:55:37 +02:00
TC
41a01ba58a Bump dev deps 2021-10-24 14:32:35 +02:00
TC
ca2bd011e2 Document quality changer plugin in readme 2021-10-24 14:08:47 +02:00
2106914aff Merge pull request #446 from Araxeus/quality-changer-plugin
quality-changer-plugin
2021-10-24 14:06:08 +02:00
1c11ddbb7d Merge branch 'master' into quality-changer-plugin 2021-10-24 14:03:40 +02:00
TC
fc1211f7a1 Bump version to 1.14.0 2021-10-24 14:02:13 +02:00
TC
18f87c7b0d Add migration for precise-volume plugin (globalShortcuts key) 2021-10-24 14:02:01 +02:00
TC
f9a4bffa55 Fix styling of store migrations 2021-10-24 14:01:29 +02:00
TC
02f4aabead Fix condition on query selector 2021-10-24 14:01:00 +02:00
f97dade168 Merge pull request #443 from Araxeus/songInfo-straight-from-youtube-api
get songInfo from youtube API
2021-10-24 13:42:59 +02:00
8c3a6472f8 Merge branch 'master' into songInfo-straight-from-youtube-api 2021-10-24 13:40:48 +02:00
315f9783f5 Merge pull request #442 from cdaydreamer/master
New plugin: Blur navigation bar
2021-10-24 13:34:45 +02:00
ada78837ce Merge branch 'master' into master 2021-10-24 13:34:15 +02:00
58c6a12e53 Merge pull request #440 from cpiber/discord-clean
Discord plugin: Clean Up Export (follow-up #380)
2021-10-24 13:29:34 +02:00
005c930d58 Merge pull request #434 from Araxeus/remove-upgrade-button
remove upgrade button + makes images unselectable
2021-10-24 13:28:43 +02:00
7c2891b732 Merge branch 'master' into remove-upgrade-button 2021-10-24 13:28:15 +02:00
8b36139dab Merge pull request #433 from Araxeus/new-auto-confirm
new auto confirm when paused
2021-10-24 12:44:19 +02:00
a045d65e58 Merge pull request #431 from itzmanish/fix/mpris
fix: mpris instance not registering itself and media controls
2021-10-24 12:42:31 +02:00
7b064c1e6f Merge pull request #288 from thymue/compressor-plugin
Audio compressor plugin
2021-10-24 12:17:28 +02:00
6a2e3ab6c1 Merge pull request #275 from Araxeus/precise-volume-HUD
precise-volume plugin fixes & updates
2021-10-24 11:40:54 +02:00
362da8c308 Merge pull request #243 from Araxeus/custom-electron-prompt
Custom Prompt for changing options
2021-10-24 11:22:20 +02:00
5658765f54 quality-changer-plugin 2021-10-24 02:24:25 +03:00
38449f003a use apiLoad event 2021-10-23 18:28:38 +03:00
df75e480a6 use apiLoad event 2021-10-23 18:27:35 +03:00
79a95f133b use apiLoad event 2021-10-23 18:22:17 +03:00
9b1a5b8d26 clarify var names in cleanupName() 2021-10-23 17:18:58 +03:00
bb2e1bd616 use youtube native api to change volume 2021-10-23 16:57:44 +03:00
2d518abc19 remove leftover console.log 2021-10-23 16:26:45 +03:00
978aca1f9a use loadeddata instead of loadedmetadata
send event closer to actual initial start time of video
2021-10-23 16:21:42 +03:00
2224786478 lint 2021-10-23 16:19:45 +03:00
51364b63e7 get songInfo from youtube API 2021-10-23 16:13:06 +03:00
c897bedd90 New plugin: Blur navigation bar 2021-10-23 15:38:46 +03:00
831b1ea8e1 access window._lact directly 2021-10-23 15:21:49 +03:00
4d4dacbc71 discord: clean up export (follow-up #380) 2021-10-19 18:40:27 +02:00
1cd4f53657 Merge branch 'master' into custom-electron-prompt 2021-10-19 15:55:00 +03:00
2eda0e4948 Merge branch 'master' into new-auto-confirm 2021-10-19 15:19:58 +03:00
f2e04f9170 Merge pull request #412 from th-ch/snyk-upgrade-3ac551b4f96cf4c26f3157f42a916769
[Snyk] Upgrade async-mutex from 0.3.1 to 0.3.2
2021-10-18 23:34:29 +02:00
c92b3915d9 Merge pull request #414 from th-ch/dependabot/npm_and_yarn/tmpl-1.0.5
build(deps): bump tmpl from 1.0.4 to 1.0.5
2021-10-18 23:31:59 +02:00
6118a17b08 Merge pull request #416 from th-ch/snyk-upgrade-d31d43c15fe12eab06e73b6f8faeda29
[Snyk] Upgrade node-fetch from 2.6.1 to 2.6.2
2021-10-18 23:30:04 +02:00
1490c0f179 Merge pull request #429 from th-ch/snyk-upgrade-129504aaea5df4956b1cd910a6775c4a
[Snyk] Upgrade @cliqz/adblocker-electron from 1.22.5 to 1.22.6
2021-10-18 23:23:27 +02:00
fdf203e70a Merge pull request #430 from th-ch/dependabot/npm_and_yarn/electron-12.1.0
build(deps-dev): bump electron from 12.0.8 to 12.1.0
2021-10-18 23:18:29 +02:00
8114a28964 Merge pull request #380 from cpiber/discord
Fix discord clearActivity, menu, listen along option
2021-10-18 23:10:24 +02:00
663507b3f8 fix: player status when play at start 2021-10-17 11:06:26 +05:30
79d0c7b666 fix: typo 2021-10-17 10:54:05 +05:30
ce4580605d remove upgrade button + makes img unselectable 2021-10-15 15:40:34 +03:00
dda18a72af new auto confirm when paused 2021-10-15 14:38:09 +03:00
f7a1de05c8 defensive coding 2021-10-15 05:41:47 +03:00
361606427a fix: remove unused play pause functions 2021-10-14 10:18:05 +05:30
81fb5118aa fix: don't create play pause method unneccessarily 2021-10-14 10:16:36 +05:30
a76f12c01c feat: add play and pause seperate song controller. 2021-10-13 12:27:13 +05:30
88ee0fb989 fix: mpris was not registering itself before.
Sorry I missed that somehow, because playerctl controls were working.
That was because of chromium was also registering itself for mpris.
2021-10-13 12:26:38 +05:30
3ec49bca74 build(deps-dev): bump electron from 12.0.8 to 12.1.0
Bumps [electron](https://github.com/electron/electron) from 12.0.8 to 12.1.0.
- [Release notes](https://github.com/electron/electron/releases)
- [Changelog](https://github.com/electron/electron/blob/main/docs/breaking-changes.md)
- [Commits](https://github.com/electron/electron/compare/v12.0.8...v12.1.0)

---
updated-dependencies:
- dependency-name: electron
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-10-12 22:10:41 +00:00
1908921ae6 fix: upgrade @cliqz/adblocker-electron from 1.22.5 to 1.22.6
Snyk has created this PR to upgrade @cliqz/adblocker-electron from 1.22.5 to 1.22.6.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=referral&page=upgrade-pr
2021-10-11 21:23:58 +00:00
b9dbd8bd4d Allow disable listen along (#426) 2021-10-11 15:02:24 +02:00
587818b91e Add type, clear on close 2021-10-05 10:10:36 +02:00
157ae05f80 fix: upgrade node-fetch from 2.6.1 to 2.6.2
Snyk has created this PR to upgrade node-fetch from 2.6.1 to 2.6.2.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=referral&page=upgrade-pr
2021-09-27 19:13:33 +00:00
f2039e29e7 build(deps): bump tmpl from 1.0.4 to 1.0.5
Bumps [tmpl](https://github.com/daaku/nodejs-tmpl) from 1.0.4 to 1.0.5.
- [Release notes](https://github.com/daaku/nodejs-tmpl/releases)
- [Commits](https://github.com/daaku/nodejs-tmpl/commits/v1.0.5)

---
updated-dependencies:
- dependency-name: tmpl
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-09-21 21:12:33 +00:00
ea2d33c3cf fix: upgrade async-mutex from 0.3.1 to 0.3.2
Snyk has created this PR to upgrade async-mutex from 0.3.1 to 0.3.2.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=upgrade-pr
2021-09-21 03:24:11 +00:00
d775e3d588 Merge pull request #406 from th-ch/snyk-upgrade-3c48abddd3d31d59f08172a32b5dd378
[Snyk] Upgrade @cliqz/adblocker-electron from 1.22.4 to 1.22.5
2021-09-19 16:13:09 +02:00
e7ec15e90f fix: upgrade @cliqz/adblocker-electron from 1.22.4 to 1.22.5
Snyk has created this PR to upgrade @cliqz/adblocker-electron from 1.22.4 to 1.22.5.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=upgrade-pr
2021-09-16 00:27:20 +00:00
TC
403470be69 Bump version 2021-09-15 22:59:06 +02:00
6dc0ba74c4 Merge pull request #384 from konhi/useragent
Fix incorrect Google alert caused by changing user agent coresponding to current platform
2021-09-15 22:54:10 +02:00
TC
6dcfb336c2 Fix missing import in shortcuts plugin 2021-09-15 22:51:58 +02:00
84516b2ac1 Merge pull request #401 from th-ch/snyk-upgrade-4b273faf3969a8ede6309124c5ce3e75
[Snyk] Upgrade electron-updater from 4.4.3 to 4.4.6
2021-09-15 22:50:15 +02:00
57cf2a8cdd fix: upgrade electron-updater from 4.4.3 to 4.4.6
Snyk has created this PR to upgrade electron-updater from 4.4.3 to 4.4.6.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=upgrade-pr
2021-09-13 01:17:33 +00:00
e3ae97fec4 Merge pull request #370 from th-ch/snyk-upgrade-eeb9d7e7304322861f42850feedf7f74
[Snyk] Upgrade electron-updater from 4.4.0 to 4.4.1
2021-09-12 23:10:47 +02:00
TC
ee76e2cb45 Merge branch 'master' of github.com:th-ch/youtube-music into snyk-upgrade-eeb9d7e7304322861f42850feedf7f74
* 'master' of github.com:th-ch/youtube-music:
  Bump node to v14
  nit: fix code style for tuna obs (+ typo)
  add tuna plugin for obs
  Add mpris support
  Update menu buttons to new format
  Bump jszip from 3.5.0 to 3.7.1
  Add Genius lyrics plugin
  Apply clean up util to title + enrich prefixes
  Bump node to v14
  fix: upgrade @cliqz/adblocker-electron from 1.22.2 to 1.22.3
  Add "Listen Along" button
  sort alphabetically
  suggestions from @Araxeus and @cpiber
  Fix broken link
  update descriptions and add images
  List missing plugins
  Bump path-parse from 1.0.6 to 1.0.7
2021-09-12 23:03:23 +02:00
de01bb6e75 Merge pull request #375 from th-ch/dependabot/npm_and_yarn/path-parse-1.0.7
Bump path-parse from 1.0.6 to 1.0.7
2021-09-12 23:02:52 +02:00
TC
42668c3e99 Merge branch 'master' of github.com:th-ch/youtube-music into dependabot/npm_and_yarn/path-parse-1.0.7
* 'master' of github.com:th-ch/youtube-music:
  Bump node to v14
  nit: fix code style for tuna obs (+ typo)
  add tuna plugin for obs
  Add mpris support
  Update menu buttons to new format
  Bump jszip from 3.5.0 to 3.7.1
  Add Genius lyrics plugin
  Apply clean up util to title + enrich prefixes
  Bump node to v14
  fix: upgrade @cliqz/adblocker-electron from 1.22.2 to 1.22.3
  Add "Listen Along" button
  sort alphabetically
  suggestions from @Araxeus and @cpiber
  Fix broken link
  update descriptions and add images
  List missing plugins
2021-09-12 22:55:08 +02:00
05f3c56e47 Merge pull request #385 from th-ch/snyk-upgrade-f132bed3bdbd1c212a2d1580af9a445a
[Snyk] Upgrade @cliqz/adblocker-electron from 1.22.2 to 1.22.3
2021-09-12 22:53:39 +02:00
TC
d54977b9ee Bump node to v14 2021-09-12 22:42:31 +02:00
b89fb4dc2f Merge pull request #388 from th-ch/dependabot/npm_and_yarn/jszip-3.7.1
Bump jszip from 3.5.0 to 3.7.1
2021-09-12 22:33:50 +02:00
a0cf77edfb Merge pull request #382 from konhi/patch-1
List missing plugins
2021-09-12 22:20:53 +02:00
TC
069f9855d1 nit: fix code style for tuna obs (+ typo) 2021-09-12 22:17:54 +02:00
e3e0775401 Merge pull request #397 from mesmerx/master
add tuna plugin for obs
2021-09-12 22:16:22 +02:00
d255e5ffe1 Merge pull request #389 from th-ch/fix-menu-buttons
Update menu buttons to new format
2021-09-12 22:13:46 +02:00
fea460a374 Merge pull request #387 from th-ch/lyrics-genius-plugin
Plugin to fetch lyrics from Genius
2021-09-12 22:10:43 +02:00
302d3f693f add tuna plugin for obs 2021-09-08 22:45:49 -03:00
9cc320d74b Merge pull request #395 from itzmanish/feat/mpris-support
Add mpris support with cherry picked commit from previous PR https://github.com/th-ch/youtube-music/pull/394
2021-09-07 00:12:34 +02:00
e255777283 Add mpris support 2021-09-02 16:00:42 +05:30
ef66612cc8 Discord show error dialog on reconnect error 2021-08-27 17:07:23 +02:00
4bed835347 Merge branch 'master' of https://github.com/th-ch/youtube-music into discord 2021-08-27 16:37:50 +02:00
b5fd6b4969 Discord add reconnecting functionality
Clear rpc on disconnect
Add menu button to reconnect
2021-08-27 16:32:55 +02:00
fe0f213919 Merge pull request #383 from konhi/discord
Add "Listen Along" button, solve #353
2021-08-23 01:19:00 +02:00
TC
e888b5c896 Update menu buttons to new format 2021-08-23 01:17:29 +02:00
f27ff52689 Bump jszip from 3.5.0 to 3.7.1
Bumps [jszip](https://github.com/Stuk/jszip) from 3.5.0 to 3.7.1.
- [Release notes](https://github.com/Stuk/jszip/releases)
- [Changelog](https://github.com/Stuk/jszip/blob/master/CHANGES.md)
- [Commits](https://github.com/Stuk/jszip/compare/v3.5.0...v3.7.1)

---
updated-dependencies:
- dependency-name: jszip
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-22 23:16:24 +00:00
TC
acbe0ac25d Add Genius lyrics plugin 2021-08-23 01:12:53 +02:00
TC
c66ff2bf05 Apply clean up util to title + enrich prefixes 2021-08-23 01:12:53 +02:00
d089487aa8 Merge pull request #386 from th-ch/bump-node-version
Bump node to v14
2021-08-23 01:12:27 +02:00
TC
6bc1d1606f Bump node to v14 2021-08-23 01:05:45 +02:00
9df5d921c7 Chrome -> Firefox, simplified using electron-is
suggestions by @Araxeus
2021-08-20 12:33:46 +02:00
4b1dfa1173 fix: upgrade @cliqz/adblocker-electron from 1.22.2 to 1.22.3
Snyk has created this PR to upgrade @cliqz/adblocker-electron from 1.22.2 to 1.22.3.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=upgrade-pr
2021-08-19 21:20:28 +00:00
f98318e737 Add platform-based user-agent 2021-08-19 16:49:34 +02:00
7fa1278b31 Add "Listen Along" button 2021-08-19 16:16:49 +02:00
878ec1f6c1 sort alphabetically 2021-08-19 15:09:31 +02:00
086048780a suggestions from @Araxeus and @cpiber 2021-08-19 15:04:47 +02:00
65eaaecae5 Merge branch 'master' into custom-electron-prompt 2021-08-19 13:44:42 +03:00
aff0415816 Fix broken link
Oops.
2021-08-19 00:15:25 +02:00
6040fe1cbd update descriptions and add images 2021-08-19 00:08:17 +02:00
36bc9c62b0 Discord timeout 0 clear activity directly 2021-08-18 21:39:40 +02:00
3901457218 Discord add menu button for clearing activity 2021-08-17 10:09:47 +02:00
52f4e9d796 List missing plugins 2021-08-16 18:49:15 +02:00
183bad43f6 Fix discord clearActivity, menu
The callback sends multiple events, in particular two pause when going to the
next song, so the timeout wasn't properly cleared.
Add menu buttons for the two options
2021-08-15 12:25:00 +02:00
09fe80cae7 Bump path-parse from 1.0.6 to 1.0.7
Bumps [path-parse](https://github.com/jbgutierrez/path-parse) from 1.0.6 to 1.0.7.
- [Release notes](https://github.com/jbgutierrez/path-parse/releases)
- [Commits](https://github.com/jbgutierrez/path-parse/commits/v1.0.7)

---
updated-dependencies:
- dependency-name: path-parse
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-12 03:24:48 +00:00
817b48dc9d fix: upgrade electron-updater from 4.4.0 to 4.4.1
Snyk has created this PR to upgrade electron-updater from 4.4.0 to 4.4.1.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=upgrade-pr
2021-08-06 21:42:35 +00:00
c6f8c42c45 Merge pull request #350 from th-ch/snyk-upgrade-4809caaf0847354b9b537aa0f8a0999d
[Snyk] Upgrade electron-updater from 4.3.9 to 4.3.10
2021-08-06 23:23:12 +02:00
TC
0535686129 Merge branch 'master' of github.com:th-ch/youtube-music into snyk-upgrade-4809caaf0847354b9b537aa0f8a0999d
# By TC (1) and snyk-bot (1)
# Via GitHub (1) and TC (1)
* 'master' of github.com:th-ch/youtube-music:
  Bump ytdl/ytpl
  fix: upgrade chokidar from 3.5.1 to 3.5.2
2021-08-06 23:22:44 +02:00
53a77255ca Merge pull request #354 from th-ch/snyk-upgrade-1a48119c8989bb533950b3384b3bce29
[Snyk] Upgrade chokidar from 3.5.1 to 3.5.2
2021-08-06 23:17:51 +02:00
TC
c01506dc44 Bump ytdl/ytpl 2021-08-06 23:12:29 +02:00
a49817fdc3 Merge branch 'master' into custom-electron-prompt 2021-07-20 11:06:08 +03:00
52a4608d76 create options.global if needed 2021-07-20 10:57:32 +03:00
6f5f9386ff fix: upgrade chokidar from 3.5.1 to 3.5.2
Snyk has created this PR to upgrade chokidar from 3.5.1 to 3.5.2.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=upgrade-pr
2021-07-07 05:50:15 +00:00
fddd0607e6 fix: upgrade electron-updater from 4.3.9 to 4.3.10
Snyk has created this PR to upgrade electron-updater from 4.3.9 to 4.3.10.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=upgrade-pr
2021-07-02 06:17:28 +00:00
TC
2cb6f56feb Bump version 2021-07-01 22:43:35 +02:00
TC
46285a5ed0 Bump glob-parent and add lint script (xo) 2021-06-27 21:19:33 +02:00
TC
496836b33b Bump dependencies to fix vulnerabilities 2021-06-27 21:12:28 +02:00
af127879a5 Merge pull request #339 from th-ch/fix-downloader-plugin
Fix downloader plugin
2021-06-27 21:10:35 +02:00
TC
38ef452801 Bump ffmpeg version 2021-06-27 20:46:48 +02:00
TC
a9a5d99676 Do not add network filters in adblocker cache to fix session enhancing 2021-06-27 20:46:48 +02:00
TC
e5ab50cebd Override content security policy to allow FFmpeg worker 2021-06-27 20:46:46 +02:00
TC
49194f8141 nit: re-order dependencies 2021-06-27 20:39:05 +02:00
TC
641ae27efd Update ytdl-core and ytpl 2021-06-27 20:38:08 +02:00
47a5dec465 Merge pull request #337 from th-ch/snyk-upgrade-fe663d0d7c5fc658f327e05ae5966f76
[Snyk] Upgrade @cliqz/adblocker-electron from 1.22.0 to 1.22.1
2021-06-25 23:11:25 +02:00
c93eabb400 Merge pull request #249 from Araxeus/update-in-app-menu
Update and simplify in-app-menu
2021-06-25 23:03:05 +02:00
664be51de2 Merge branch 'master' into custom-electron-prompt 2021-06-25 12:21:40 +03:00
492a47321d Merge branch 'master' into update-in-app-menu 2021-06-25 12:19:39 +03:00
c89f6af8c6 fix: upgrade @cliqz/adblocker-electron from 1.22.0 to 1.22.1
Snyk has created this PR to upgrade @cliqz/adblocker-electron from 1.22.0 to 1.22.1.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=upgrade-pr
2021-06-25 04:53:24 +00:00
9687c6c8e4 Merge pull request #331 from th-ch/dependabot/npm_and_yarn/hosted-git-info-2.8.9
Bump hosted-git-info from 2.8.8 to 2.8.9
2021-06-24 22:06:27 +02:00
ef0a89126a Merge pull request #330 from th-ch/dependabot/npm_and_yarn/lodash-4.17.21
Bump lodash from 4.17.20 to 4.17.21
2021-06-24 22:05:46 +02:00
8ce71d628d Bump lodash from 4.17.20 to 4.17.21
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.20 to 4.17.21.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.20...4.17.21)

---
updated-dependencies:
- dependency-name: lodash
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-24 20:04:35 +00:00
ca95d105c8 Merge pull request #328 from th-ch/snyk-upgrade-dacfb8f0b574367961e405e4912a4659
[Snyk] Upgrade ytdl-core from 4.8.0 to 4.8.2
2021-06-24 22:04:32 +02:00
12568c2b09 Merge pull request #324 from th-ch/snyk-upgrade-f650e2139b30a36951a4a00ed1b78d70
[Snyk] Upgrade electron-updater from 4.3.8 to 4.3.9
2021-06-24 22:03:15 +02:00
82abb4d4d3 Merge pull request #323 from th-ch/dependabot/npm_and_yarn/normalize-url-4.5.1
Bump normalize-url from 4.5.0 to 4.5.1
2021-06-24 22:02:52 +02:00
3c0a5dbbe5 Merge pull request #320 from th-ch/dependabot/npm_and_yarn/trim-newlines-3.0.1
Bump trim-newlines from 3.0.0 to 3.0.1
2021-06-24 22:02:33 +02:00
0b98eef06f Merge pull request #317 from th-ch/snyk-upgrade-a785f5d95c7765e2d47737e150a2263d
[Snyk] Upgrade @ffmpeg/core from 0.9.0 to 0.10.0
2021-06-24 22:02:05 +02:00
TC
18e69c9f2a Merge branch 'master' of github.com:th-ch/youtube-music into snyk-upgrade-a785f5d95c7765e2d47737e150a2263d
# By Araxeus (2) and snyk-bot (2)
# Via GitHub (3) and Araxeus (1)
* 'master' of github.com:th-ch/youtube-music:
  check if native image is empty before writing id tag
  fix unsupported hidden webp coverart
  fix: upgrade @ffmpeg/ffmpeg from 0.9.8 to 0.10.0
  fix: upgrade custom-electron-titlebar from 3.2.6 to 3.2.7
2021-06-24 22:01:16 +02:00
8f5d06d420 Merge pull request #316 from th-ch/snyk-upgrade-6e93904bf885d198521c6a5d8110bde3
[Snyk] Upgrade @ffmpeg/ffmpeg from 0.9.8 to 0.10.0
2021-06-24 22:00:07 +02:00
8a299461a0 Merge pull request #311 from th-ch/snyk-upgrade-44a5db26689d4091f6a2c3c3c69b869a
[Snyk] Upgrade custom-electron-titlebar from 3.2.6 to 3.2.7
2021-06-24 21:49:53 +02:00
0c58bec921 Bump hosted-git-info from 2.8.8 to 2.8.9
Bumps [hosted-git-info](https://github.com/npm/hosted-git-info) from 2.8.8 to 2.8.9.
- [Release notes](https://github.com/npm/hosted-git-info/releases)
- [Changelog](https://github.com/npm/hosted-git-info/blob/v2.8.9/CHANGELOG.md)
- [Commits](https://github.com/npm/hosted-git-info/compare/v2.8.8...v2.8.9)

---
updated-dependencies:
- dependency-name: hosted-git-info
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-19 20:29:37 +00:00
e0cb132686 Merge pull request #318 from Araxeus/fix-hidden-webp-cover-art
fix hidden webp thumbnail throwing MIME type error in downloader
2021-06-19 22:28:59 +02:00
2a192f39f9 fix: upgrade ytdl-core from 4.8.0 to 4.8.2
Snyk has created this PR to upgrade ytdl-core from 4.8.0 to 4.8.2.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=upgrade-pr
2021-06-19 05:30:04 +00:00
b7ebb7d499 fix: upgrade electron-updater from 4.3.8 to 4.3.9
Snyk has created this PR to upgrade electron-updater from 4.3.8 to 4.3.9.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=upgrade-pr
2021-06-12 04:23:30 +00:00
fffeac21b7 Bump normalize-url from 4.5.0 to 4.5.1
Bumps [normalize-url](https://github.com/sindresorhus/normalize-url) from 4.5.0 to 4.5.1.
- [Release notes](https://github.com/sindresorhus/normalize-url/releases)
- [Commits](https://github.com/sindresorhus/normalize-url/commits)

---
updated-dependencies:
- dependency-name: normalize-url
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-11 04:46:20 +00:00
4387cb485d Bump trim-newlines from 3.0.0 to 3.0.1
Bumps [trim-newlines](https://github.com/sindresorhus/trim-newlines) from 3.0.0 to 3.0.1.
- [Release notes](https://github.com/sindresorhus/trim-newlines/releases)
- [Commits](https://github.com/sindresorhus/trim-newlines/commits)

---
updated-dependencies:
- dependency-name: trim-newlines
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-09 18:57:55 +00:00
2a58dc823a check if native image is empty before writing id tag 2021-06-09 20:05:14 +03:00
8eb38271ff fix unsupported hidden webp coverart 2021-06-09 19:53:04 +03:00
1987ad1d4f fix: upgrade @ffmpeg/core from 0.9.0 to 0.10.0
Snyk has created this PR to upgrade @ffmpeg/core from 0.9.0 to 0.10.0.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=upgrade-pr
2021-06-08 04:08:44 +00:00
cc4dae60ef fix: upgrade @ffmpeg/ffmpeg from 0.9.8 to 0.10.0
Snyk has created this PR to upgrade @ffmpeg/ffmpeg from 0.9.8 to 0.10.0.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=upgrade-pr
2021-06-08 04:08:41 +00:00
1943116aa1 fix: upgrade custom-electron-titlebar from 3.2.6 to 3.2.7
Snyk has created this PR to upgrade custom-electron-titlebar from 3.2.6 to 3.2.7.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=upgrade-pr
2021-06-05 03:53:12 +00:00
3485d26b11 Merge pull request #308 from th-ch/sponsorblock-plugin
Add Sponsorblock plugin
2021-06-04 22:25:26 +02:00
TC
4a60aa9f20 Keep segments when skipping 2021-06-03 22:15:36 +02:00
TC
cda07c9675 Update adblocking 2021-06-03 22:04:49 +02:00
TC
ca64a77ed0 Add SponsorBlock plugin 2021-06-03 21:47:26 +02:00
TC
30e94d1d6f Refactor videoElement getter into a provider with callback 2021-06-03 21:45:28 +02:00
TC
b8c6ebfa53 Set test environment per test file 2021-06-03 21:43:07 +02:00
b26748ded8 Merge pull request #305 from th-ch/snyk-upgrade-15656c519a90f5bc0f5c8742a9fb04e9
[Snyk] Upgrade @ffmpeg/ffmpeg from 0.9.7 to 0.9.8
2021-05-31 22:06:17 +02:00
f186da0834 fix: upgrade @ffmpeg/ffmpeg from 0.9.7 to 0.9.8
Snyk has created this PR to upgrade @ffmpeg/ffmpeg from 0.9.7 to 0.9.8.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=upgrade-pr
2021-05-29 04:38:22 +00:00
c52c2d886a Merge pull request #303 from th-ch/dependabot/npm_and_yarn/ws-7.4.6
Bump ws from 7.4.3 to 7.4.6
2021-05-28 23:40:55 +02:00
e5dc1f8a58 Bump ws from 7.4.3 to 7.4.6
Bumps [ws](https://github.com/websockets/ws) from 7.4.3 to 7.4.6.
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/compare/7.4.3...7.4.6)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-28 21:39:25 +00:00
6dbf4134de Merge pull request #301 from th-ch/dependabot/npm_and_yarn/browserslist-4.16.6
Bump browserslist from 4.16.3 to 4.16.6
2021-05-28 23:38:48 +02:00
e1cc49a74d Merge pull request #300 from th-ch/snyk-upgrade-ce2777733d9dee231391c0a822c24a84
[Snyk] Upgrade @cliqz/adblocker-electron from 1.20.4 to 1.20.5
2021-05-28 23:35:11 +02:00
TC
4489a400b7 Merge branch 'master' of github.com:th-ch/youtube-music into snyk-upgrade-ce2777733d9dee231391c0a822c24a84
# By Araxeus (5) and others
# Via GitHub (5) and TC (2)
* 'master' of github.com:th-ch/youtube-music:
  Bump electron to 12.0.8
  fix: upgrade ytdl-core from 4.5.0 to 4.7.0
  fix: upgrade @ffmpeg/core from 0.8.5 to 0.9.0
  fix notificationOnUnpause option
  fix: upgrade filenamify from 4.2.0 to 4.3.0
  switch to `registerCallback()` on song info
  fix: upgrade ytpl from 2.1.1 to 2.2.0
  lint
  refactor notifications plugin
  setup SongInfo **once**
2021-05-28 23:33:20 +02:00
28aa1c0b22 Merge pull request #299 from th-ch/snyk-upgrade-37e43892f5a34f935e8486a98b3598fb
[Snyk] Upgrade ytdl-core from 4.5.0 to 4.7.0
2021-05-28 23:32:29 +02:00
TC
c540788d20 Merge branch 'master' of github.com:th-ch/youtube-music into snyk-upgrade-37e43892f5a34f935e8486a98b3598fb
# By Araxeus (5) and others
# Via GitHub (4) and TC (1)
* 'master' of github.com:th-ch/youtube-music:
  Bump electron to 12.0.8
  fix: upgrade @ffmpeg/core from 0.8.5 to 0.9.0
  fix notificationOnUnpause option
  fix: upgrade filenamify from 4.2.0 to 4.3.0
  switch to `registerCallback()` on song info
  fix: upgrade ytpl from 2.1.1 to 2.2.0
  lint
  refactor notifications plugin
  setup SongInfo **once**
2021-05-28 23:32:05 +02:00
4ab07dc875 Merge pull request #298 from th-ch/snyk-upgrade-d305cdce94133f6db9615e7b16007c87
[Snyk] Upgrade @ffmpeg/core from 0.8.5 to 0.9.0
2021-05-28 23:28:26 +02:00
5033de13ef Merge pull request #293 from th-ch/snyk-upgrade-335ec370c7caa5a759c54a46b2e27cf5
[Snyk] Upgrade filenamify from 4.2.0 to 4.3.0
2021-05-28 23:23:49 +02:00
55a8787a16 Merge pull request #285 from th-ch/snyk-upgrade-7b9c569f5bdd092f76adf7d412b0eea1
[Snyk] Upgrade ytpl from 2.1.1 to 2.2.0
2021-05-28 23:21:51 +02:00
3515bf364d Merge pull request #269 from Araxeus/fix-XHR-duplicate-callback
fix song-info callback duplication
2021-05-28 23:18:10 +02:00
TC
d8f3246e46 Bump electron to 12.0.8 2021-05-28 23:13:07 +02:00
cd613aaba2 Bump browserslist from 4.16.3 to 4.16.6
Bumps [browserslist](https://github.com/browserslist/browserslist) from 4.16.3 to 4.16.6.
- [Release notes](https://github.com/browserslist/browserslist/releases)
- [Changelog](https://github.com/browserslist/browserslist/blob/main/CHANGELOG.md)
- [Commits](https://github.com/browserslist/browserslist/compare/4.16.3...4.16.6)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-27 02:56:37 +00:00
c5f84b568b fix: upgrade @cliqz/adblocker-electron from 1.20.4 to 1.20.5
Snyk has created this PR to upgrade @cliqz/adblocker-electron from 1.20.4 to 1.20.5.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=upgrade-pr
2021-05-26 04:36:08 +00:00
14dc78984f fix: upgrade ytdl-core from 4.5.0 to 4.7.0
Snyk has created this PR to upgrade ytdl-core from 4.5.0 to 4.7.0.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=upgrade-pr
2021-05-26 04:36:06 +00:00
fb61dbfa6c fix: upgrade @ffmpeg/core from 0.8.5 to 0.9.0
Snyk has created this PR to upgrade @ffmpeg/core from 0.8.5 to 0.9.0.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=upgrade-pr
2021-05-26 04:36:03 +00:00
33855f17dd update refreshMenu() function 2021-05-23 17:57:54 +03:00
8124623142 fix notificationOnUnpause option 2021-05-22 18:38:36 +03:00
e99c91ce6e get rid of (hopefully) unnecessary watchDOMElement 2021-05-19 21:50:40 +02:00
177ce5721f fix: upgrade filenamify from 4.2.0 to 4.3.0
Snyk has created this PR to upgrade filenamify from 4.2.0 to 4.3.0.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=upgrade-pr
2021-05-19 05:31:34 +00:00
4fb0b1dd08 switch to registerCallback() on song info 2021-05-19 00:22:12 +03:00
177ad2ce7c minify firstRun() 2021-05-18 19:20:09 +03:00
9b88769585 remove leftover console.log 2021-05-18 19:02:56 +03:00
fd044072a1 use front load event instead of webcontents.did-finish-load 2021-05-18 18:53:00 +03:00
bae5155e19 use let and const instead of var 2021-05-17 13:42:27 +02:00
1e2085b990 compressor plugin 2021-05-17 12:33:43 +02:00
bbe5a7d50b fix: upgrade ytpl from 2.1.1 to 2.2.0
Snyk has created this PR to upgrade ytpl from 2.1.1 to 2.2.0.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=upgrade-pr
2021-05-17 04:44:57 +00:00
e5473cdfe4 lint 2021-05-17 00:07:28 +03:00
9c7a70e056 use .toFixed(2) on volume decimals 2021-05-16 23:50:59 +03:00
5bc8e86353 Merge pull request #270 from Araxeus/fix-normal-notification-showing-appID
fix notification showing appID instead of app name on windows
2021-05-16 22:46:54 +02:00
5b00465558 Merge pull request #273 from th-ch/upgrade-electron
Upgrade electron to v12
2021-05-16 22:31:07 +02:00
28b70f6459 added timeout when writing volume to config 2021-05-16 22:59:05 +03:00
6961cdee95 override youtube automatically changing the volume 2021-05-16 22:39:38 +03:00
58557505ae show mute icon when volume=0 2021-05-16 22:39:11 +03:00
65178b259f fix video muting when volume < 3 2021-05-16 21:32:40 +03:00
541c7f34b7 restore menuItems roles that were fixed 2021-05-15 17:24:01 +03:00
b2c209837c fix empty string input validation in setProxy 2021-05-14 03:12:27 +03:00
355f61188a use placeholder proxy example 2021-05-13 07:08:17 +03:00
ea672c2423 show volume hud in videoplayer if available 2021-05-13 03:18:24 +03:00
71ba6b8e55 lint 2021-05-12 20:58:43 +03:00
8a07fccf8f setup on page reload 2021-05-12 18:58:29 +03:00
7bc35f4cee add volume hud 2021-05-12 18:31:11 +03:00
002081bcb9 use store migration 2021-05-12 00:47:41 +03:00
TC
0e8e78362b Upgrade electron to v12 2021-05-11 22:56:07 +02:00
cb6a5a478e lint 2021-05-11 16:47:51 +03:00
d615030222 register appID on windows reguardless of shortcut 2021-05-11 00:34:40 +03:00
e43c01da64 lint 2021-05-11 00:20:00 +03:00
cb5ef1d6e5 check that app is installed / unpacked 2021-05-11 00:15:54 +03:00
78a7dcb7e8 lint 2021-05-10 23:46:56 +03:00
8cca9f3eeb create shortcut only if needed 2021-05-10 23:23:17 +03:00
93d4d3c976 writeShortcut on windows 2021-05-10 22:13:45 +03:00
8284b56075 set appID on windows 2021-05-10 20:40:25 +03:00
580caeffb9 destructure keybind output 2021-05-10 16:53:57 +03:00
b266037bb4 lint 2021-05-10 06:05:39 +03:00
cb743de7fd refactor notifications plugin 2021-05-10 05:00:58 +03:00
7cf78c6635 setup SongInfo **once** 2021-05-10 04:15:56 +03:00
0eca30367f lint 2021-05-10 01:56:41 +03:00
36317c953a globalize promptOptions 2021-05-10 01:43:50 +03:00
f910593fb6 use spread operator + async await 2021-05-10 00:40:02 +03:00
7942efa202 Merge pull request #267 from Araxeus/last-fm-config-check-fix
fix last-fm overwrite config on each start
2021-05-09 21:47:07 +02:00
792c2931b0 fix config overwrite on each start 2021-05-09 22:10:20 +03:00
TC
a3778af48a Downloader: rename UrlToJPG to urlToJPG 2021-05-08 22:48:18 +02:00
TC
163dc7e1d1 Downloader: catch error when fetching playlist 2021-05-08 22:41:56 +02:00
0a59122ac2 Merge pull request #265 from Araxeus/ensure-download-from-radio-button
Downloader tweaks + taskbar progress bar
2021-05-08 22:40:24 +02:00
d2a5110f3b querySelector optimization #2 2021-05-08 23:06:18 +03:00
cf4bbf94e4 update radioButton querySelector 2021-05-08 23:02:52 +03:00
d7e42471a4 lint 2021-05-08 23:01:57 +03:00
d634c41e75 Merge pull request #262 from Araxeus/remove-open-dependency
remove `open` dependency from last-fm plugin
2021-05-08 21:58:51 +02:00
6b88397f82 lint 2021-05-08 21:21:07 +03:00
da3c709ff0 remove videoDetails?.media query from XHR
(it never exists in the XHR responce)
2021-05-08 20:46:15 +03:00
ccd320d8ff minimize getArtist() 2021-05-08 20:40:44 +03:00
3831e61d10 differentiate names of different metadata sources 2021-05-08 19:45:33 +03:00
e46e7b74e2 fix sendError() 2021-05-08 19:34:57 +03:00
b3da77a6bc small refactor 2021-05-08 19:24:25 +03:00
96a74f8955 use original metadata only if not already captured from ytpl.getInfo() 2021-05-08 19:19:11 +03:00
3ea17e6f46 refactor 2021-05-08 08:05:38 +03:00
a8ac2c3af9 download progress bar on taskbar
+ Get the best possible artwork
2021-05-08 07:11:54 +03:00
2168cbca30 use image from imageSrc if transfered 2021-05-08 04:04:35 +03:00
cceb45319a debug videoUrl from start Radio button in menu 2021-05-08 04:03:34 +03:00
e985b78241 lint 2021-05-08 01:08:24 +03:00
090ca828c0 Merge branch 'master' into update-in-app-menu 2021-05-08 01:03:14 +03:00
3522925dec remove open dependency 2021-05-08 01:00:23 +03:00
5418ef7ae2 Merge branch 'master' into custom-electron-prompt 2021-05-08 00:21:16 +03:00
5faeddb99b Merge pull request #252 from Araxeus/fix-download-idtag-if-not-playing
Fix downloader metadata if not currently playing
2021-05-07 23:11:10 +02:00
1140c3e2e7 lint 2021-05-07 23:40:14 +03:00
TC
3fb08d27c7 Add start:debug command to enable dev with electron debug 2021-05-07 22:29:21 +02:00
250940d083 Merge pull request #259 from Araxeus/force-pause
fix playPause bugs by directly playPause video element
2021-05-07 22:24:03 +02:00
e00be8f010 lint 2021-05-07 05:43:26 +03:00
8b471c0772 create cleanupArtistName() in song-info 2021-05-07 04:47:24 +03:00
88e738c796 check if yns_pause exists 2021-05-07 04:17:17 +03:00
TC
c76d8c79d8 Bump version to 1.12.1 2021-05-06 22:29:04 +02:00
b396431a8b Merge pull request #260 from th-ch/dependabot/npm_and_yarn/ua-parser-js-0.7.28
Bump ua-parser-js from 0.7.23 to 0.7.28
2021-05-06 22:18:37 +02:00
d1795a82f7 Merge pull request #253 from Araxeus/fix-precise-volume-listener-override
Fix precise volume listener override
2021-05-06 21:45:09 +02:00
9b821a0dfe Bump ua-parser-js from 0.7.23 to 0.7.28
Bumps [ua-parser-js](https://github.com/faisalman/ua-parser-js) from 0.7.23 to 0.7.28.
- [Release notes](https://github.com/faisalman/ua-parser-js/releases)
- [Commits](https://github.com/faisalman/ua-parser-js/compare/0.7.23...0.7.28)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-06 19:41:13 +00:00
bf89842ee8 Merge pull request #255 from Araxeus/fix-css-on-reload
fix css not inserting on reload
2021-05-06 21:40:13 +02:00
d274e80f75 minify 2021-05-06 21:41:08 +03:00
a98b8945fb lint 2021-05-06 21:32:44 +03:00
6b72599f80 directly playPause video element 2021-05-06 21:20:42 +03:00
4b6fe78a1a fix css not inserting on reload 2021-05-06 18:40:56 +03:00
d000c03fca lint 2021-05-06 05:40:31 +03:00
c0a185ba68 refactor addEventListener 2021-05-06 05:18:06 +03:00
ef0813e638 fix preventDefault() being called on *all* keys 2021-05-06 04:58:05 +03:00
25e9f44260 fix listener override condition 2021-05-06 04:56:06 +03:00
2d6e858e8f lint 2021-05-06 04:43:31 +03:00
53bf7c5068 playlist download progressBar using chokidar 2021-05-06 04:41:58 +03:00
13fb686188 started playlist downlaod messageBox 2021-05-06 03:33:49 +03:00
61c5494588 custom metadata on playlist-download 2021-05-06 03:02:06 +03:00
d96fefbc24 fix error thrown when downloading playlist 2021-05-06 02:51:10 +03:00
e18b7c1013 allow unlimited playlist size 2021-05-06 02:28:35 +03:00
f190b51dcc lint 2021-05-06 02:17:48 +03:00
ca41c12f7c use media propery if exist in song-info 2021-05-06 02:05:48 +03:00
844edbe2f4 fix metadata when downloading unplayed song 2021-05-06 01:46:14 +03:00
78974c02e5 save in-app-menu activation state on launch 2021-05-05 21:12:52 +03:00
4508464fd1 update custom-electron-titlebar version 2021-05-05 20:39:08 +03:00
dd6455a559 update in-app-menu 2021-05-05 20:37:29 +03:00
6b147b098a fix prompt width 2021-05-05 03:48:07 +03:00
834f8674a3 massive prompt speed boost with v1.1.0 2021-05-05 03:27:47 +03:00
5cee331abe update prompt version and lint 2021-05-05 02:53:05 +03:00
98c00f7a60 format proxy example 2021-05-05 02:30:08 +03:00
db8d946178 fix electron dependency 2021-05-05 02:08:24 +03:00
b97a86f6dc Update yarn.lock 2021-05-05 01:55:25 +03:00
34a4e6be3d proxy url check 2021-05-05 01:47:53 +03:00
22c5ea5000 lint 2021-05-05 01:25:45 +03:00
79acf6c0ba Volume Steps Prompt
Precise-Volume Global Shortcuts Prompt
2021-05-05 00:42:42 +03:00
ebaa01896f Merge remote-tracking branch 'upstream/master' into custom-electron-prompt 2021-05-04 23:48:27 +03:00
TC
d4811b7901 Revert "Remove preload.js in plugin uses and use front plugin injection"
This reverts commit 4cb658daca.
2021-05-04 22:31:49 +02:00
TC
bf409967b2 Import front logger at top level 2021-05-04 21:30:10 +02:00
TC
4cb658daca Remove preload.js in plugin uses and use front plugin injection 2021-05-04 21:29:39 +02:00
8aeddcf8d8 Merge pull request #224 from Araxeus/menu-fixes
Menu tweaks
2021-05-04 21:24:29 +02:00
fb81e1bdd5 ignore did-fail-load error code -3
bug with in-app-menu
2021-05-04 02:04:17 +03:00
d5b9e3c960 stringify did-fail-load error
directly preload front-logger
simplify front-logger
2021-05-04 01:22:47 +03:00
TC
c7ff536ed5 Bump version to 1.12.0 2021-05-03 22:24:19 +02:00
TC
7dbb5fc86d Update electron to 11.4.4 2021-05-02 22:41:38 +02:00
8f766bcbaa resolve merge conflict 2021-05-02 23:41:16 +03:00
TC
f65c6c89ae Fix package.json indent, update yarn.lock 2021-05-02 22:30:24 +02:00
472462cdcb Merge pull request #228 from Araxeus/interactive-notifications
Interactive notifications for windows
2021-05-02 22:27:36 +02:00
8575996e46 Merge branch 'menu-fixes' of https://github.com/Araxeus/youtube-music into menu-fixes 2021-05-02 23:26:27 +03:00
02d16ca510 fix typo
Co-authored-by: th-ch <th-ch@users.noreply.github.com>
2021-05-02 23:25:46 +03:00
1f69048c86 minify switch case
Co-authored-by: th-ch <th-ch@users.noreply.github.com>
2021-05-02 23:25:34 +03:00
442aafd2c5 remove redundant dialog import 2021-05-02 23:25:20 +03:00
6082a6549a Merge branch 'master' into interactive-notifications 2021-05-02 22:25:01 +02:00
2567702b44 Merge pull request #236 from Araxeus/precise-volume
[Plugin] Precise volume control
2021-05-02 21:41:17 +02:00
ec981ac547 refactor registerAllShortcuts 2021-04-30 05:09:49 +03:00
d0d4ada7c2 restore original menu lint 2021-04-30 04:33:23 +03:00
54cbe3faa4 lint 2021-04-30 04:29:01 +03:00
49e51de274 update shortcuts config 2021-04-30 04:13:03 +03:00
e456035f29 fix typo 2021-04-30 03:22:36 +03:00
964974c142 add keybind changer v1 2021-04-30 03:04:38 +03:00
b63eb1c8b4 Merge pull request #244 from th-ch/snyk-upgrade-99aee86a0f7b96c0f871bcfabfb6e986
[Snyk] Upgrade electron-store from 7.0.2 to 7.0.3
2021-04-29 23:36:33 +02:00
603bcf7d9d Merge pull request #233 from th-ch/snyk-upgrade-db0717b422c1c3d1fcb50ff90a0b95cd
[Snyk] Upgrade @cliqz/adblocker-electron from 1.20.3 to 1.20.4
2021-04-29 23:34:51 +02:00
TC
0468a23c4f Fix getFolder util (main/renderer process) 2021-04-29 23:28:27 +02:00
f95e29df45 Merge pull request #231 from Araxeus/dependencies-update
Dependencies update
2021-04-29 23:27:21 +02:00
79d95d9477 Merge branch 'master' into dependencies-update 2021-04-29 23:10:52 +02:00
a406ba4ca0 Merge pull request #245 from th-ch/fix-downloader-metadata
Fix downloader metadata
2021-04-29 23:05:17 +02:00
TC
dfbda7c10b Set metadata in back (to have cover) 2021-04-29 22:57:47 +02:00
TC
c11ecd3323 Set max file length to 255 in downloader 2021-04-29 22:57:12 +02:00
TC
8a5c39ee53 Fix download URL 2021-04-29 22:56:33 +02:00
c38035188b fix: upgrade electron-store from 7.0.2 to 7.0.3
Snyk has created this PR to upgrade electron-store from 7.0.2 to 7.0.3.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=upgrade-pr
2021-04-29 02:19:11 +00:00
TC
ba02d372f7 Update yarn.lock 2021-04-28 22:23:31 +02:00
5312b3694b Merge pull request #196 from semvis123/lastfm
Last.fm support
2021-04-28 22:22:44 +02:00
d0800bb31c small refactor 2021-04-28 16:58:14 +03:00
e272d38ca5 fix typo 2021-04-28 16:54:05 +03:00
66517af81c fix typo 2021-04-28 16:33:12 +03:00
d2925ee3f9 make variable names clearer 2021-04-28 04:30:19 +03:00
729714375b update camelCase 2021-04-28 04:27:50 +03:00
b77643b928 remove proxy from menu 2021-04-28 03:54:59 +03:00
0491babe0a fix typo 2021-04-28 03:36:00 +03:00
0adb36cfb8 leave debug for next PR 2021-04-28 03:08:25 +03:00
8dc486f18f remove local prompt 2021-04-28 02:51:19 +03:00
a229ba9c15 disable reload of plugins on window created 2021-04-28 02:46:13 +03:00
e4eed2e519 add custom-electron-prompt
also use it to set proxy option
2021-04-28 02:41:44 +03:00
395eac26a3 switch function name to camelCase
Co-authored-by: th-ch <th-ch@users.noreply.github.com>
2021-04-27 23:52:08 +03:00
e9d7ddebb2 defensive code
Co-authored-by: th-ch <th-ch@users.noreply.github.com>
2021-04-27 23:51:29 +03:00
5dc1179d54 implement keybind prompt 2021-04-27 23:48:06 +03:00
8decdf4346 Merge pull request #239 from Araxeus/discord-fix
simple fix for discord plugin
2021-04-27 21:51:07 +02:00
98fd6240ba update inline doc 2021-04-26 21:09:42 +03:00
5a77528526 enable global volume shortcuts in advanced config 2021-04-26 21:01:19 +03:00
d4fdced538 addEventListener insead of .onwheel 2021-04-25 02:22:08 +03:00
8b1bbdf360 Add Video Player Mousewheel Volume Control
(if hide-video-player plugin is disabled)
2021-04-23 05:29:03 +03:00
eae4cca148 Update readme.md 2021-04-23 04:25:48 +03:00
a194046168 win.once() instead of win.on 2021-04-23 04:06:54 +03:00
7c6ed7bb31 once instead of on 2021-04-23 04:01:40 +03:00
20123d8245 revert to original lint format 2021-04-23 03:50:00 +03:00
650945418d simple fix 2021-04-23 03:42:00 +03:00
064facb048 remove slider on-hover after 3 seconds if !focused 2021-04-23 01:20:03 +03:00
0bc1b5e0d3 lint 2021-04-22 16:30:34 +03:00
65f6822199 Show volume slider on volume change 2021-04-22 14:44:37 +03:00
021d2a8a54 disable native volume-slider listeners 2021-04-22 05:34:54 +03:00
5fa8f3ef6f add option for plugin to have a preload.js 2021-04-22 05:34:43 +03:00
10dffdbde2 refactor + lint 2021-04-19 01:45:32 +03:00
72716afcd3 lint 2021-04-18 01:44:18 +03:00
00468c7d0e use timeout ID to stop callback 2021-04-18 00:44:22 +03:00
b7b1316e70 add rapidFire option to counter prompt 2021-04-17 22:55:25 +03:00
97a9e63231 xo --fix 2021-04-17 21:17:07 +03:00
3f50ab7cfc lint 2021-04-17 20:43:48 +03:00
341a06aae7 add prompt with number counter 2021-04-17 20:30:06 +03:00
c48260f10c add advanced option to change volume steps 2021-04-17 16:42:13 +03:00
12a2517697 xo --fix 2021-04-17 15:03:19 +03:00
49698ea669 fix changing settings when plugin is disabled 2021-04-17 05:08:07 +03:00
834202411d enable changing shortcut setting without restart 2021-04-17 04:38:23 +03:00
94e152bb57 add optional arrowkeys controls option 2021-04-17 04:14:54 +03:00
5adcc3efad fix set volume on first run after not using plugin 2021-04-17 02:38:45 +03:00
b65bc65d7c save volume to settings 2021-04-17 02:01:19 +03:00
06958c424c refactor 2021-04-16 23:30:43 +03:00
02896cac03 xo --fix 2021-04-16 23:02:16 +03:00
c0ec1bc5cf update inline doc 2021-04-16 22:37:34 +03:00
40968d573c add precise scrollwheel control + precise tooltip 2021-04-16 21:52:56 +03:00
9f848e3e76 fix: upgrade @cliqz/adblocker-electron from 1.20.3 to 1.20.4
Snyk has created this PR to upgrade @cliqz/adblocker-electron from 1.20.3 to 1.20.4.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=upgrade-pr
2021-04-16 02:19:07 +00:00
f765fb63f0 scrape artistName from playBar 2021-04-15 15:59:41 +03:00
ff6a486daf fix unresponsive dialog response 2021-04-15 15:35:22 +03:00
bb6ad14111 navbar background black fix visual bug 2021-04-15 12:40:09 +03:00
a2207a2cb3 remove " - Topic" from artist name 2021-04-14 13:44:32 +03:00
c764d657d7 cleanup unresponsiveDialog 2021-04-14 13:42:39 +03:00
2b6cecc441 Update ytpl 2021-04-12 20:56:52 +03:00
61d83be52e taskbar-mediacontrol no longer override win.hide
(electron 11.4.2 fixed the bug that required that)
2021-04-12 20:19:36 +03:00
9f2362d346 update dependecies 2021-04-12 20:19:35 +03:00
193c3823b6 remove downloads-folder and use electron instead 2021-04-12 20:19:35 +03:00
09d9f72db2 add unresponsive listener 2021-04-10 02:51:38 +03:00
3d41d04818 Revert "fix rare crash due to unfocus effect"
This reverts commit 80b1207640.
2021-04-09 22:28:55 +03:00
46ac0a1ed3 change notification priority to show only on linux 2021-04-09 19:10:20 +03:00
e6d77c165e Center Icon on ALL notifications
Delete notification on windowclosed
Refactor notifications.utils.setOption
2021-04-09 18:39:57 +03:00
18f041f1c6 clarify button purpose 2021-04-09 03:26:46 +03:00
9c0a633677 fix unPause option compatibility 2021-04-09 03:15:57 +03:00
095196785a add note to notifications.interactive 2021-04-09 02:32:14 +03:00
80b1207640 fix rare crash due to unfocus effect 2021-04-09 02:19:06 +03:00
ba6244780c minify 2021-04-09 02:14:11 +03:00
d8dc4656e4 stylecheck 2021-04-09 01:08:22 +03:00
30675e0567 remove appID because of bug:
Button would not transmit event
2021-04-08 18:56:13 +03:00
e6efddc639 add windows interactive notifications 2021-04-08 16:54:46 +03:00
47eace97bd Merge branch 'menu-fixes' of https://github.com/Araxeus/youtube-music into menu-fixes 2021-04-06 21:58:58 +03:00
980ffb45e9 Create readme.md
refactor and css fix

xo --fix

add inline doc

fix typo
2021-04-06 21:57:16 +03:00
17fd499420 fix typo 2021-04-06 01:51:11 +03:00
0e9b15722a add inline doc 2021-04-06 01:30:47 +03:00
724c213af1 xo --fix 2021-04-05 23:18:54 +03:00
a215035d07 refactor and css fix 2021-04-05 18:28:27 +03:00
25d0f50f3d Create readme.md 2021-04-05 04:52:22 +03:00
6d44a579a4 move prompt to provide 2021-04-05 04:21:52 +03:00
106e461beb fix typo 2021-04-05 04:08:55 +03:00
6472002f8a fix hide-menu timing + minify log function 2021-04-05 04:04:29 +03:00
11bd1adbd4 stylecheck 2021-04-05 03:25:45 +03:00
28d366ab19 add back-to-front logger
This somehow fix "did-fail-load" being called on song start, with in-app-plugin-activated
2021-04-05 03:04:06 +03:00
10e29090d8 stylecheck 2021-04-04 21:52:16 +03:00
73b0ddc2ce css tweaks 2021-04-04 21:25:41 +03:00
7c8e946871 implement custom prompt 2021-04-04 19:58:25 +03:00
d12d16348a custom dark skin for prompt 2021-04-04 15:06:14 +03:00
421fe67930 ignore proxy if equal to example 2021-04-04 02:46:12 +03:00
8291cdfc12 disable dev tools on electron-prompt 2021-04-04 02:37:19 +03:00
2e6fffc903 Revert "fix Connection Error when using in-app-menu"
This reverts commit 8b6c60bb17.
2021-04-03 23:46:16 +03:00
8b6c60bb17 fix Connection Error when using in-app-menu 2021-04-03 22:59:20 +03:00
1cae35a62b fix in-app-menu hideMenu on launch 2021-04-03 22:34:12 +03:00
70b03b71e4 refactor and stylecheck 2021-04-03 22:04:40 +03:00
317521bba6 fix memory leak +
in-app-menu updates menu only if needed
2021-04-03 21:53:39 +03:00
061e4a9e5f add 'electron-prompt' and use it for setting proxy 2021-04-03 21:51:35 +03:00
ec3adff706 fix bug when loading window with no connection 2021-04-03 20:15:48 +03:00
5524a14c87 move advanced options to dedicated submenu +
add "Use Proxy" checkbox
2021-04-03 19:20:56 +03:00
e1e8c943f3 Merge branch 'master' into lastfm 2021-04-03 17:21:56 +02:00
0c6630d2d9 additional cleanup/refactoring 2021-04-03 17:12:28 +02:00
80a7d2c255 remove redundant roles 2021-04-03 15:54:51 +03:00
2b3a20c5ff Minimalize tray menu
-doesnt include main menu template anymore
2021-04-03 15:47:32 +03:00
216205200c fix in-app-menu navbar opacity + scrollbar color 2021-04-03 15:30:33 +03:00
TC
61e7124516 Support proxy in advanced options 2021-04-03 12:20:48 +02:00
2ab216effc Merge pull request #215 from th-ch/menu-options
In-app-menu plugin - rename plugin & configure menu builder
2021-04-03 12:10:56 +02:00
TC
1e59301c0e Write metadata in front + pass it along (useful if the song is changed) 2021-04-03 12:04:49 +02:00
TC
d5a2c1cad6 Format front downloader 2021-04-03 12:01:31 +02:00
TC
b5c60ee6a9 Re-format front metadata lib 2021-04-03 11:35:31 +02:00
TC
533b8a8cb7 Metadata: call getImage in front 2021-04-03 11:34:55 +02:00
TC
fecb193ded Re-use default config to get base url in downloader 2021-04-03 11:34:23 +02:00
dc5d257082 Merge pull request #221 from Araxeus/download-song-that-isnt-playing
Allows downloading songs that aren't currently playing
2021-04-03 11:29:20 +02:00
c690473b2e Merge pull request #222 from Keyboardsheep/master
Updated download plugin icon color to match other icons
2021-04-03 10:58:37 +02:00
04fa5eb289 updated download.html svg 2021-04-03 00:10:09 -05:00
d6cd3a0ead updated download.html svg 2021-04-03 00:06:58 -05:00
a23f281734 updated download.html svg 2021-04-03 00:05:36 -05:00
135d58e1f5 updated download.html svg 2021-04-02 23:55:32 -05:00
832ff19e51 allows downloading song that aren't playing 2021-04-03 05:38:21 +03:00
c7bef5ac7b Merge pull request #216 from Araxeus/fix-duplicate-notification
[Notification Plugin] Fix duplicate notification
2021-04-02 23:10:19 +02:00
2254cac15b Merge pull request #213 from th-ch/song-info-front
Pass metadata to front + use metadata URL in downloader
2021-04-02 22:59:57 +02:00
TC
01d574a302 Merge branch 'master' of github.com:th-ch/youtube-music into menu-options
# By Araxeus
# Via GitHub (2) and Araxeus (1)
* 'master' of github.com:th-ch/youtube-music:
  remove 'shortcuts'+'discord' from default plugins
  cleanup styled-bars code
  only refresh if plugin has a menu.js
  update styled-bars to support all changes permantly
  Refresh menu on plugin enable/disable
2021-04-02 22:40:31 +02:00
d67d697847 Merge pull request #217 from Araxeus/Refresh-menu-on-plugin-enable/disable
Refresh menu on plugin enable/disable (show/hide submenu)
2021-04-02 21:43:12 +02:00
8c9e37f8a1 Merge pull request #218 from Araxeus/remove-shortcuts-from-default-plugins
remove 'shortcuts' from default plugins
2021-04-02 21:38:18 +02:00
TC
77393c5324 Replace click callback by override in custom menu 2021-04-02 21:20:50 +02:00
e66db051a9 remove 'shortcuts'+'discord' from default plugins 2021-04-01 21:24:11 +03:00
5670a6d1b4 cleanup styled-bars code 2021-04-01 21:09:31 +03:00
02d45bed74 only refresh if plugin has a menu.js 2021-04-01 19:21:21 +03:00
adc0d145c3 update styled-bars to support
all changes permantly
2021-04-01 19:02:39 +03:00
58481e3133 Refresh menu on plugin enable/disable 2021-04-01 18:10:08 +03:00
a3ec9b7b78 add notification on unpause option 2021-04-01 17:44:40 +03:00
2d534b0293 fix duplicate notification 2021-04-01 15:50:26 +03:00
d73d0cf8ce fix duplicate notification 2021-04-01 15:39:07 +03:00
fbe490c28d Merge remote-tracking branch 'upstream/master' into styled-bars-download-chooser 2021-04-01 02:56:11 +03:00
TC
c09de43154 Rename plugin to in-app-menu + hidden titleBarStyle 2021-03-31 22:37:12 +02:00
TC
be651ebb4b Parameter in menu builder for tray 2021-03-31 22:35:01 +02:00
TC
3fe793cd4d CSS: border radius compatibility 2021-03-31 21:18:31 +02:00
TC
a8cfe399b3 Rename bar var 2021-03-31 21:15:52 +02:00
TC
ff9e39e2ee Re-order dependencies 2021-03-31 21:15:16 +02:00
TC
0d2b61472c Use template builder in custom menu plugin 2021-03-31 21:14:59 +02:00
TC
f9f3482bf1 Pass callback in menu builder 2021-03-31 21:14:55 +02:00
TC
400a2a9bab Add option to menu to render without roles 2021-03-31 20:18:20 +02:00
TC
36864b4c2f Format custom menu plugin 2021-03-31 20:17:12 +02:00
TC
5671b99b7e Format new menu items 2021-03-31 20:15:55 +02:00
76f88686da Merge pull request #201 from Araxeus/styled-bars
[Plugin] styled-bars
2021-03-31 20:07:41 +02:00
ba42a8b269 increase font size for menu and menuItems 2021-03-30 02:18:02 +03:00
ae7def2313 Rename variables and function for clarity 2021-03-30 02:00:35 +03:00
e55176511f Merge pull request #212 from SapuSeven/master
Add configurable notification urgency
2021-03-29 22:42:17 +02:00
TC
640f146373 Use metadata URL in downloader (fallback to current URL) 2021-03-29 22:00:49 +02:00
TC
ebe8755613 Song provider: call callbacks when data is updated 2021-03-29 21:59:45 +02:00
TC
05eee7cb0f Store metadata in front 2021-03-29 21:33:33 +02:00
TC
7ac9fda1eb Send back metadata to front 2021-03-29 21:33:07 +02:00
TC
6987a0a585 Set isPaused default to undefined 2021-03-29 21:32:41 +02:00
1a338fb9e5 Add advanced configuration menu for notifications 2021-03-28 23:33:10 +02:00
8dc18bbe5e Add configurable notification urgency 2021-03-28 23:23:45 +02:00
TC
64c2b32b24 Add url to song info 2021-03-28 22:17:57 +02:00
TC
f01ef5d955 Ensure filename is not empty in downloader plugin 2021-03-28 21:54:21 +02:00
TC
221ee0be05 Order deps in menu file in downloader plugin (+ prettier) 2021-03-28 21:53:50 +02:00
2b8ba02c2a Merge pull request #207 from Araxeus/Download-Plugin-Directory-Chooser
add Download Folder Chooser
2021-03-28 21:51:02 +02:00
TC
b06583afce Bundle imports + prettier 2021-03-28 21:16:33 +02:00
b8b1ae7e88 Merge pull request #194 from semvis123/songprovider-update
Improved songinfo provider, by using the data from the '/player' request
2021-03-28 21:12:03 +02:00
b67b1bed13 refactor for clarity 2021-03-26 20:32:30 +03:00
33fa9f8f50 fix array input + use getFolder() 2021-03-26 17:52:23 +03:00
a7087aaa38 uses getFolder() now 2021-03-26 17:41:12 +03:00
a7170762d4 Merge pull request #10 from Araxeus/Download-Plugin-Directory-Chooser
Download plugin directory chooser
2021-03-26 05:59:45 +03:00
ea3d198723 in tray, delete quit button from submenu
also delete useless nonfunctional view submenu
2021-03-26 05:25:46 +03:00
fe8f048571 add Download Folder Chooser 2021-03-26 04:07:45 +03:00
09d2feb15b Add quit + restart button to main menu ) 2021-03-26 00:24:03 +02:00
33d4c1a60e Refactor into switchMenuVisibility 2021-03-26 00:23:28 +02:00
cbd7a13275 Merge pull request #180 from th-ch/snyk-upgrade-58542eeb4b38266ae86c95a43f335043
[Snyk] Upgrade @cliqz/adblocker-electron from 1.20.0 to 1.20.1
2021-03-25 22:22:23 +01:00
903b7f8718 lint 2021-03-25 23:16:00 +02:00
TC
88cd1651c3 Clean metadata + apply pngcrush on images in taskbar plugin 2021-03-25 22:15:39 +01:00
13ff5f26a2 Plugin doesn't create a new menu anymore
instead it modifies the original menu
2021-03-25 23:13:54 +02:00
57345a5fd2 Merge pull request #200 from Araxeus/master
[Plugin] taskbar-mediacontrol  (for Windows)
2021-03-25 22:11:49 +01:00
bd82bd2249 added extra comments and corrected existing ones 2021-03-25 21:27:33 +01:00
f253a69656 added comment for the added function 2021-03-25 21:11:55 +01:00
493a5835f8 Merge branch 'master' into lastfm 2021-03-25 20:34:40 +01:00
bffbcb229d Made the suffixes configurable and added VEVO suffix to remove 2021-03-25 20:15:43 +01:00
b5ec431b0a Merge remote-tracking branch 'upstream/master' into styled-bars 2021-03-25 18:39:06 +02:00
259706478f Merge remote-tracking branch 'upstream/master' 2021-03-25 18:33:48 +02:00
c9f172ef21 fix scrollbar clash with nav bar 2021-03-25 16:43:01 +02:00
eb32c98b76 fix tray option radio selection 2021-03-25 07:51:06 +02:00
95c3f04c10 more fixes for plugin options menu 2021-03-25 02:18:23 +02:00
d4daf7231c merge source (#3)
* Added Discord timeout

* Add getOptions in plugin util

* Mutex in ffmpeg conversion (only supports one command at a time)

* Add menu customization in plugin system

* Add ytpl package (playlist info)

* Handle ffmpeg metadata flags when metadata is not present

* Only use artist in file name if present

* Export sendError method

* Handle image not present in metadata util

* Add downloader utils (getFolder and default menu label)

* Pass (optional) existing metadata and subfolder in mp3 converter

* Add listener to download playlist

* Add custom menu in downloader plugin ("download playlist" item)

* nit: fix main CSS style

* Only set the "enable" item in menu if plugin not enabled

* Navigation plugin: inject HTML once CSS is loaded

Co-authored-by: Sem Visscher <semvisscher10@gmail.com>
Co-authored-by: TC <th-ch@users.noreply.github.com>
2021-03-25 01:36:22 +02:00
9a95f435ad merge source (#2)
* Added Discord timeout

* Add getOptions in plugin util

* Mutex in ffmpeg conversion (only supports one command at a time)

* Add menu customization in plugin system

* Add ytpl package (playlist info)

* Handle ffmpeg metadata flags when metadata is not present

* Only use artist in file name if present

* Export sendError method

* Handle image not present in metadata util

* Add downloader utils (getFolder and default menu label)

* Pass (optional) existing metadata and subfolder in mp3 converter

* Add listener to download playlist

* Add custom menu in downloader plugin ("download playlist" item)

* nit: fix main CSS style

* Only set the "enable" item in menu if plugin not enabled

* Navigation plugin: inject HTML once CSS is loaded

Co-authored-by: Sem Visscher <semvisscher10@gmail.com>
Co-authored-by: TC <th-ch@users.noreply.github.com>
2021-03-25 01:02:42 +02:00
5218b80cab preparation for plugin menu update 2021-03-25 01:00:06 +02:00
TC
b1665c880b Navigation plugin: inject HTML once CSS is loaded 2021-03-24 23:06:35 +01:00
6395dfe425 Merge pull request #203 from th-ch/downloader-plugin-playlist
Add playlist feature in downloader plugin + custom menus in plugin system
2021-03-24 22:39:50 +01:00
304ad6e767 Merge pull request #192 from semvis123/master
Added Discord timeout
2021-03-24 22:38:56 +01:00
TC
587a093aff Only set the "enable" item in menu if plugin not enabled 2021-03-24 21:55:53 +01:00
TC
91b49e4a16 nit: fix main CSS style 2021-03-24 21:52:33 +01:00
TC
e72915c5d0 Add custom menu in downloader plugin ("download playlist" item) 2021-03-24 21:52:12 +01:00
TC
bee2da567b Add listener to download playlist 2021-03-24 21:51:11 +01:00
TC
951689c5ea Pass (optional) existing metadata and subfolder in mp3 converter 2021-03-24 21:50:46 +01:00
TC
4146ae60bc Add downloader utils (getFolder and default menu label) 2021-03-24 21:50:31 +01:00
TC
6bcf5efb65 Handle image not present in metadata util 2021-03-24 21:48:12 +01:00
TC
ddf10f1052 Export sendError method 2021-03-24 21:45:59 +01:00
TC
7edca44ed8 Only use artist in file name if present 2021-03-24 21:44:54 +01:00
TC
ebc3f16597 Handle ffmpeg metadata flags when metadata is not present 2021-03-24 21:44:54 +01:00
TC
9dad31775c Add ytpl package (playlist info) 2021-03-24 21:44:54 +01:00
TC
b1089b66c3 Add menu customization in plugin system 2021-03-24 21:44:54 +01:00
TC
84142ab27e Mutex in ffmpeg conversion (only supports one command at a time) 2021-03-24 21:44:48 +01:00
TC
fd518e39ff Add getOptions in plugin util 2021-03-24 21:36:17 +01:00
2fb4cbcf02 move icons to 'assets' folder 2021-03-24 19:38:45 +02:00
d3337c7d3c titlebar dragArea fix + refactor 2021-03-24 00:13:38 +02:00
5fd11bf009 fixed search page header height 2021-03-23 22:15:16 +02:00
92603a1e7f fix search button alignment 2021-03-23 22:09:10 +02:00
7d8afe3476 style check 2021-03-23 22:03:48 +02:00
f9c66ead50 css color fix 2021-03-23 19:47:47 +02:00
a12d5a982f fix library UI bug 2021-03-23 19:29:07 +02:00
c1f176fa21 Fixed MenuItem roles + add restart+quit button 2021-03-23 16:17:50 +02:00
f1dbe4ab6c Allow hide menu options (uses Escape key) 2021-03-23 15:07:31 +02:00
459ebf7070 xo lint --fix 2021-03-23 03:58:19 +02:00
8cf0ec16bb Merge branch 'styled-bars' of https://github.com/Araxeus/youtube-music into styled-bars 2021-03-23 03:51:16 +02:00
87558c67c8 stylecheck 2021-03-23 03:50:59 +02:00
8727a2e299 separate plugins to different branches 2021-03-23 02:51:12 +02:00
b8c5c87cfa Styled Bars [Titlebar + Scrollbar] 2021-03-23 02:46:13 +02:00
ce2970eefa fixed line that xo-lint broke 2021-03-22 13:48:08 +02:00
24fea5a24a added back original yarn.lock
(was deleted by accident)
2021-03-22 04:22:23 +02:00
5285680eed xo lint --fix 2021-03-22 04:17:39 +02:00
17e63194ad fixed typo bug 2021-03-22 04:06:42 +02:00
6427b3406c Override hide(),show(),isVisible from inside plugin
instead of changing source code
2021-03-22 04:01:19 +02:00
df8c77cd3e Wait for song to start before setting thumbar 2021-03-22 03:01:46 +02:00
41796aec06 Tray Break Thumbar Fix
using  win.minimize()
and win.setSkipTaskbar(bool)
instead of win.hide() / win.show()
2021-03-22 01:26:20 +02:00
1355b692b9 Remove the - Topic for more matches 2021-03-21 22:28:05 +01:00
2c13ef40e2 taskbar-mediacontrol plugin
Add UI Control to windows taskbar preview
2021-03-21 20:08:07 +02:00
2bb67db888 Fixed backwards compatibility 2021-03-21 18:47:16 +01:00
204f384d01 fetch highest resolution image instead of lowest resolution 2021-03-21 14:14:26 +01:00
42e3d48caf Added now playing to last-fm 2021-03-19 22:00:00 +01:00
4747050b60 Added working lastfm support
currently only played songs are added
2021-03-19 21:32:33 +01:00
TC
c926db7f13 Increase top margin for MacOS 2021-03-18 22:12:18 +01:00
TC
8cce3f4503 Add view/navigation menu 2021-03-18 22:02:19 +01:00
3464b0383c small readability changes 2021-03-18 17:53:30 +01:00
d852029d25 Improved songinfo provider, by using the data from the '/player' request 2021-03-18 17:48:56 +01:00
ca8d62d4e2 Added Discord timeout 2021-03-17 10:22:19 +01:00
0632920a6f fix: upgrade @cliqz/adblocker-electron from 1.20.0 to 1.20.1
Snyk has created this PR to upgrade @cliqz/adblocker-electron from 1.20.0 to 1.20.1.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=upgrade-pr
2021-03-10 02:19:11 +00:00
c5bda4f3be Merge pull request #178 from th-ch/snyk-upgrade-da4beb25f2fa1631098996298cd49f89
[Snyk] Upgrade electron-store from 7.0.1 to 7.0.2
2021-03-09 19:50:17 +01:00
3dc92b4939 fix: upgrade electron-store from 7.0.1 to 7.0.2
Snyk has created this PR to upgrade electron-store from 7.0.1 to 7.0.2.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=upgrade-pr
2021-03-05 02:19:09 +00:00
TC
150146385f Bump version 2021-03-04 23:09:27 +01:00
TC
f50bd32fa3 Fix resumeOnStart option 2021-03-04 23:09:01 +01:00
0dcf820944 Merge pull request #177 from NNowakowski/resume-last-song-on-start
Added function to toggle resuming of last song when app starts
2021-03-04 22:57:41 +01:00
6fd16684f7 Merge pull request #175 from th-ch/snyk-upgrade-024effb4b0bec6e73345b87366580cf3
[Snyk] Upgrade discord-rpc from 3.1.4 to 3.2.0
2021-03-04 22:54:13 +01:00
TC
eaa957168f Add plugin to disable autoplay 2021-03-04 22:47:53 +01:00
TC
796a7aaaf1 Fix download/speed menu item 2021-03-04 21:29:37 +01:00
9aaae7b2d9 🚀 Added function to toggle resuming of last song when app starts 2021-03-04 14:14:49 +01:00
c00609223b fix: upgrade discord-rpc from 3.1.4 to 3.2.0
Snyk has created this PR to upgrade discord-rpc from 3.1.4 to 3.2.0.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=upgrade-pr
2021-03-04 02:19:26 +00:00
5641c3fc87 Merge pull request #154 from th-ch/snyk-upgrade-3f26f6e01fe99104189d358a840963dd
[Snyk] Upgrade @cliqz/adblocker-electron from 1.19.0 to 1.20.0
2021-02-24 23:11:02 +01:00
dd1bdae947 Added metadata to downloader plugin, and updated packages 2021-02-24 22:53:31 +01:00
TC
70973b2281 Clear cache after 20s if option is enabled 2021-02-24 21:08:25 +01:00
TC
5842a6d42f Handle uncaught errors 2021-02-24 20:53:41 +01:00
538ab52abd fix: upgrade @cliqz/adblocker-electron from 1.19.0 to 1.20.0
Snyk has created this PR to upgrade @cliqz/adblocker-electron from 1.19.0 to 1.20.0.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=upgrade-pr
2021-02-12 02:19:15 +00:00
TC
5a1358b310 Bump version 2021-02-07 18:30:01 +01:00
TC
024ed9085c Allow custom shortcuts in plugin 2021-02-07 18:29:35 +01:00
TC
b2c9e445b7 Fix shortcuts 2021-02-07 18:29:08 +01:00
TC
5b8d5d5ee4 Do not run the app after Windows install 2021-02-07 14:43:37 +01:00
TC
a82efaf91b Bump YoutubeNonStop 2021-02-07 14:38:30 +01:00
TC
980090f108 Remember window position 2021-02-07 13:25:01 +01:00
TC
f7f31850d3 Add plugin to control playback speed like in YouTube (from 0.25 to 2) 2021-02-07 11:46:57 +01:00
3415ce3965 Merge pull request #146 from th-ch/snyk-upgrade-aba6333ac62e918200d72118a7613fb6
[Snyk] Upgrade @ffmpeg/ffmpeg from 0.9.6 to 0.9.7
2021-02-06 22:34:21 +01:00
436d9ef3e1 Merge pull request #144 from semvis123/master
Reuse the same notification, instead of creating a new one each time the song changes.
2021-02-06 22:30:35 +01:00
TC
da61621a62 Check updates after 2s 2021-02-06 22:25:23 +01:00
TC
3976d1c862 Add option to reset cache 2021-02-06 22:15:57 +01:00
a9980190d0 fix: upgrade @ffmpeg/ffmpeg from 0.9.6 to 0.9.7
Snyk has created this PR to upgrade @ffmpeg/ffmpeg from 0.9.6 to 0.9.7.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=upgrade-pr
2021-02-05 02:19:17 +00:00
e75dfcf41c little fixes 2021-02-01 22:00:18 +01:00
1fdf2416ad Update back.js 2021-02-01 21:34:56 +01:00
df627788c9 small formatting changes 2021-02-01 20:23:46 +01:00
c1ee58b47f Reuse the same notifcation, instead of creating a new notification each time. 2021-02-01 20:18:16 +01:00
d6f7c54370 Merge pull request #136 from th-ch/snyk-upgrade-57f12acf80f9a08801a63b7852a10ff8
[Snyk] Upgrade ytdl-core from 4.2.1 to 4.3.0
2021-01-23 12:53:18 +01:00
3a03fb51cd fix: upgrade ytdl-core from 4.2.1 to 4.3.0
Snyk has created this PR to upgrade ytdl-core from 4.2.1 to 4.3.0.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=upgrade-pr
2021-01-22 02:21:11 +00:00
TC
e19964edf6 GH page: fix canvas size 2021-01-18 21:58:18 +01:00
TC
3bcf409f2b GH page 2021-01-17 20:32:23 +01:00
TC
37289b9cbe Downloader: 'artist - title' format for filename 2021-01-16 10:19:10 +01:00
TC
227902b7cc Add shortcuts to provider 2021-01-15 23:16:47 +01:00
TC
644950ccc0 Bump version 2021-01-15 09:31:34 +01:00
TC
d848937e6a Rename discord plugin 2021-01-14 23:16:59 +01:00
446aa8becc Merge pull request #121 from th-ch/snyk-upgrade-d29b51f488ba9deb228b72952a3f7b8e
[Snyk] Upgrade electron-debug from 3.1.0 to 3.2.0
2021-01-14 23:12:27 +01:00
TC
d52dbee13c Prettier utils 2021-01-14 23:09:16 +01:00
TC
ed09304ed7 Refactor tray to use provider + play/pause on click 2021-01-14 23:09:04 +01:00
TC
2861473097 Set title/artist metadata in downloader 2021-01-14 23:01:26 +01:00
39dc22973e Merge pull request #1 from th-ch/master
bring the new commits to this fork
2021-01-14 22:24:21 +01:00
25fd48697b Merge pull request #125 from th-ch/refactor-providers
Refactor providers
2021-01-14 21:03:26 +01:00
TC
aec542e95e Update discord plugin for new provider + wait for ready 2021-01-13 22:22:22 +01:00
TC
eae95befe1 Merge branch 'master' of github.com:th-ch/youtube-music into refactor-providers
# By TC (9) and semvis123 (2)
# Via GitHub (4) and semvis123 (1)
* 'master' of github.com:th-ch/youtube-music:
  renamed DiscordRPC to Discord
  Downloader plugin: log audio bitrate
  Disable context isolation (to load ffmpeg wasm)
  Use contextBridge in preload script + update navigation plugin
  Fix downloader plugin with context isolation
  Bump version
  Add portable target to windows builds
  Added Discord rich presence and added extra properties to songinfo provider
  Bump version
  Allow custom audio extensions in downloader
  Defensive: handle null/undefined ffmpeg args
2021-01-13 22:10:10 +01:00
f0200e7b38 Merge pull request #124 from semvis123/master
Added Discord rich presence and added extra properties to songInfo provider
2021-01-13 22:08:10 +01:00
70775f4988 renamed DiscordRPC to Discord 2021-01-13 21:56:53 +01:00
074840ef56 Merge pull request #127 from th-ch/fix-plugins-context-isolation
Fix plugins with context isolation
2021-01-13 21:44:37 +01:00
TC
b54c501eeb Downloader plugin: log audio bitrate 2021-01-13 21:36:16 +01:00
6d587cb432 Merge pull request #126 from th-ch/windows-portable
Windows portable exe
2021-01-13 21:32:53 +01:00
TC
39c8031cd7 Disable context isolation (to load ffmpeg wasm) 2021-01-13 21:28:42 +01:00
TC
9ad1dad6df Use contextBridge in preload script + update navigation plugin 2021-01-12 22:54:04 +01:00
TC
79e8fc2fac Fix downloader plugin with context isolation 2021-01-12 22:52:21 +01:00
TC
67c4422eb8 Bump version 2021-01-12 21:37:02 +01:00
TC
18df1223af Add portable target to windows builds 2021-01-12 21:36:38 +01:00
0fafed7c53 Merge pull request #118 from th-ch/dl-custom-audio-format
Downloader plugin - custom audio format
2021-01-12 21:35:55 +01:00
TC
f7cbf2c221 No autoloading of providers (loaded on demand in plugins) 2021-01-12 21:19:01 +01:00
TC
87d2693e2b Use refactored provider in shortcuts plugin 2021-01-12 21:18:32 +01:00
TC
de1e4196d9 Use refactored provider in notification plugin 2021-01-12 21:18:05 +01:00
TC
9110e79c16 Use refactored providers in touchbar plugin 2021-01-12 21:17:40 +01:00
TC
0743034de0 Split providers in 2 2021-01-12 21:17:08 +01:00
TC
f1ddb92886 nit: prettier 2021-01-12 21:16:29 +01:00
a8ce87f2cc Added Discord rich presence and added extra properties to songinfo provider 2021-01-12 20:16:49 +01:00
86a329a61b fix: upgrade electron-debug from 3.1.0 to 3.2.0
Snyk has created this PR to upgrade electron-debug from 3.1.0 to 3.2.0.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=upgrade-pr
2021-01-12 02:24:30 +00:00
77e24f41a5 Merge pull request #102 from semvis123/master
Globalized the song info and song controls, and updated Touch Bar for it.
2021-01-10 22:15:11 +01:00
3a5d9bd973 Loads providers before plugins 2021-01-10 21:37:50 +01:00
69f486d53f moved the song info file and removed the capital letters in folder name 2021-01-10 21:22:01 +01:00
5d89043884 fixed typo, plugins/songInfo/back.js
Co-authored-by: th-ch <th-ch@users.noreply.github.com>
2021-01-10 20:31:55 +01:00
2b297c245a Merge pull request #120 from th-ch/bump-electron
Bump electron to v11
2021-01-10 14:37:07 +01:00
TC
945a61fafd Remove warning by setting contextIsolation 2021-01-10 14:10:16 +01:00
TC
1ba166a172 Bump electron to v11 2021-01-10 12:29:12 +01:00
TC
a9a840b6c3 Bump version 2021-01-08 22:41:17 +01:00
TC
6a100c8cb1 Allow custom audio extensions in downloader 2021-01-08 22:29:25 +01:00
TC
b04e2ea130 Defensive: handle null/undefined ffmpeg args 2021-01-08 22:26:44 +01:00
5ac356bf91 Merge pull request #116 from th-ch/snyk-upgrade-041c3272121410c1cb380e1fbc7f9dce
[Snyk] Upgrade electron-updater from 4.3.5 to 4.3.6
2021-01-08 21:29:50 +01:00
35ceb7e83e Merge pull request #117 from th-ch/snyk-upgrade-7528cf91d37d9330a45f611ce738e40e
[Snyk] Upgrade @cliqz/adblocker-electron from 1.18.8 to 1.19.0
2021-01-08 21:28:08 +01:00
5c0cc08d80 fix: upgrade @cliqz/adblocker-electron from 1.18.8 to 1.19.0
Snyk has created this PR to upgrade @cliqz/adblocker-electron from 1.18.8 to 1.19.0.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=upgrade-pr
2021-01-07 02:19:51 +00:00
0bf77e592a fix: upgrade electron-updater from 4.3.5 to 4.3.6
Snyk has created this PR to upgrade electron-updater from 4.3.5 to 4.3.6.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=upgrade-pr
2021-01-05 02:20:56 +00:00
ec3c1578d2 Merge pull request #109 from th-ch/snyk-upgrade-4e8a81615c57edf69b21ad2a68431dfd
[Snyk] Upgrade ytdl-core from 4.1.1 to 4.1.2
2020-12-29 16:35:55 +01:00
e8ed580ecc Merge pull request #104 from th-ch/dependabot/npm_and_yarn/node-notifier-8.0.1
Bump node-notifier from 8.0.0 to 8.0.1
2020-12-29 16:30:59 +01:00
e2cc2628ae fix: upgrade ytdl-core from 4.1.1 to 4.1.2
Snyk has created this PR to upgrade ytdl-core from 4.1.1 to 4.1.2.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=upgrade-pr
2020-12-25 02:20:03 +00:00
9e31e753f0 Bump node-notifier from 8.0.0 to 8.0.1
Bumps [node-notifier](https://github.com/mikaelbr/node-notifier) from 8.0.0 to 8.0.1.
- [Release notes](https://github.com/mikaelbr/node-notifier/releases)
- [Changelog](https://github.com/mikaelbr/node-notifier/blob/v8.0.1/CHANGELOG.md)
- [Commits](https://github.com/mikaelbr/node-notifier/compare/v8.0.0...v8.0.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-22 16:02:44 +00:00
588e0019d6 Changed function style in notifications 2020-12-21 22:11:23 +01:00
5bffdbd628 Simplifies the notification plugin to use the globalized song info 2020-12-21 21:35:02 +01:00
ee239da647 removed unnecessary await keyword 2020-12-21 21:11:00 +01:00
9be3e1afe9 Globalized the songinfo and song controls, and changed the pause/play button.
Globalized the songinfo and song controls, and changed the pause/play button. The songInfo file should eventually get another location, because it isn't really a plugin.
2020-12-21 18:18:34 +01:00
TC
af02b60ce3 Bump version 2020-12-20 20:17:24 +01:00
fbdae0452c Add touchbar plugin to list 2020-12-20 20:16:35 +01:00
d68d73eb4c Merge pull request #101 from semvis123/master
Added Touch Bar plugin
2020-12-20 20:14:49 +01:00
2de27d2e24 Merge pull request #99 from th-ch/snyk-upgrade-d3ff12c0e23681ac817994e603d37491
[Snyk] Upgrade @ffmpeg/core from 0.8.4 to 0.8.5
2020-12-19 22:03:40 +01:00
TC
15591e24d7 Merge branch 'master' of github.com:th-ch/youtube-music into snyk-upgrade-d3ff12c0e23681ac817994e603d37491
# By snyk-bot
# Via GitHub (1) and snyk-bot (1)
* 'master' of github.com:th-ch/youtube-music:
  fix: upgrade @ffmpeg/ffmpeg from 0.9.5 to 0.9.6
2020-12-19 21:50:24 +01:00
715d59e3d4 Merge pull request #100 from th-ch/snyk-upgrade-9aa7c0fdfaaeba26ca66fb92b731a1af
[Snyk] Upgrade @ffmpeg/ffmpeg from 0.9.5 to 0.9.6
2020-12-19 21:32:10 +01:00
f71e0e9da9 Switched like/dislike positions
Switched like/dislike positions to match youtube musics layout
2020-12-16 20:30:01 +01:00
ba3779db07 Updated comment - touchbar plugin 2020-12-16 20:10:05 +01:00
d99aa0242f Added like and dislike buttons 2020-12-16 19:54:44 +01:00
3ea859de09 Added song image 2020-12-16 19:44:26 +01:00
7473677477 touchbar plugin - fixed code style 2020-12-16 15:57:24 +01:00
c3e2c13808 added initial touchbar support 2020-12-16 15:52:01 +01:00
5074ba2f48 fix: upgrade @ffmpeg/ffmpeg from 0.9.5 to 0.9.6
Snyk has created this PR to upgrade @ffmpeg/ffmpeg from 0.9.5 to 0.9.6.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=upgrade-pr
2020-12-16 02:20:20 +00:00
a8b8f1079f fix: upgrade @ffmpeg/core from 0.8.4 to 0.8.5
Snyk has created this PR to upgrade @ffmpeg/core from 0.8.4 to 0.8.5.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=upgrade-pr
2020-12-16 02:20:16 +00:00
e52987df92 Merge pull request #96 from th-ch/svg-readme
[Readme] Web folder for readme assets + new SVG animation
2020-12-13 16:40:55 +01:00
TC
01fc965170 Web folder for readme assets + new svg animation 2020-12-13 16:19:33 +01:00
ff71f29206 Merge pull request #94 from th-ch/linux-deb-rpm
Add new Linux targets (deb, freebsd, rpm)
2020-12-13 13:40:07 +01:00
TC
a47c5144ac Additional linux targets 2020-12-12 23:08:05 +01:00
TC
9b979b2273 Bump version 2020-12-12 22:28:38 +01:00
TC
81198192bb Add new linux targets (deb, rpm) 2020-12-12 22:28:30 +01:00
129 changed files with 11175 additions and 5575 deletions

View File

@ -13,18 +13,18 @@ jobs:
os: [macos-latest, ubuntu-latest, windows-latest]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Setup NodeJS
uses: actions/setup-node@v1
uses: actions/setup-node@v3
with:
node-version: "12.x"
node-version: "16.x"
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v2
- uses: actions/cache@v3
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
@ -35,8 +35,64 @@ jobs:
- name: Install dependencies
run: yarn --frozen-lockfile
######################
# Patch SnoreToast to fix App ID - see https://github.com/th-ch/youtube-music/issues/479#issuecomment-965473559
- name: SnoreToast - parameters
id: snoretoast-params
if: startsWith(matrix.os, 'windows')
shell: bash
run: |
echo "::set-output name=version::v0.8.0"
echo "::set-output name=path::./vendor/snoretoast"
- name: SnoreToast - cache
id: snoretoast-cache
uses: actions/cache@v2
if: startsWith(matrix.os, 'windows')
with:
path: ${{ steps.snoretoast-params.outputs.path }}
key: snoretoast-${{ steps.snoretoast-params.outputs.version }}
- name: SnoreToast - compile
if: |
startsWith(matrix.os, 'windows') &&
steps.snoretoast-cache.outputs.cache-hit != 'true'
shell: bash
run: |
SNORETOAST_TAG="${{ steps.snoretoast-params.outputs.version }}"
echo "Compiling SnoreToast $SNORETOAST_TAG"
git config --global user.email "th-ch@users.noreply.github.com"
git config --global user.name "YouTube Music"
git clone -c advice.detachedHead=false --branch $SNORETOAST_TAG --depth 1 https://github.com/KDE/snoretoast.git ${{ steps.snoretoast-params.outputs.path }}
cd ${{ steps.snoretoast-params.outputs.path }}
# Apply https://github.com/KDE/snoretoast/pull/15/commits/c5faeceaf36f4b9fb27e5269990b716a25ecbe43
# Patch generated with `git format-patch -1 c5faeceaf36f4b9fb27e5269990b716a25ecbe43`
git am < ../snoretoast-patch/0001-Fix-activation-not-writing-to-pipe.patch
# Compile for win32
cmake -A Win32 -B build32
cmake --build build32 --config Release
# Compile for x64
cmake -A x64 -B build64
cmake --build build64 --config Release
- name: SnoreToast - overwrite with custom build
if: startsWith(matrix.os, 'windows')
shell: bash
run: |
# Override SnoreToast with the patched versions
cp ${{ steps.snoretoast-params.outputs.path }}/build32/bin/Release/snoretoast.exe ./node_modules/node-notifier/vendor/snoreToast/snoretoast-x86.exe
cp ${{ steps.snoretoast-params.outputs.path }}/build64/bin/Release/snoretoast.exe ./node_modules/node-notifier/vendor/snoreToast/snoretoast-x64.exe
# End of SnoreToast patch
######################
- name: Test
uses: GabrielBB/xvfb-action@v1
env:
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1
with:
run: yarn test

1
.gitignore vendored
View File

@ -2,3 +2,4 @@ node_modules
/dist
/assets/generated
electron-builder.yml
.vscode/settings.json

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

570
changelog.md Normal file
View File

@ -0,0 +1,570 @@
### Changelog
All notable changes to this project will be documented in this file. Dates are displayed in UTC.
#### [v1.18.0](https://github.com/th-ch/youtube-music/compare/v1.17.0...v1.18.0)
- Bump ytdl-core (bug fix) [`#816`](https://github.com/th-ch/youtube-music/pull/816)
- Bump electron and fix tests in CI [`#813`](https://github.com/th-ch/youtube-music/pull/813)
- Allow user to pass custom CSS file [`#800`](https://github.com/th-ch/youtube-music/pull/800)
- [Snyk] Upgrade html-to-text from 8.2.0 to 8.2.1 [`#799`](https://github.com/th-ch/youtube-music/pull/799)
- [Snyk] Upgrade electron-store from 8.0.1 to 8.0.2 [`#772`](https://github.com/th-ch/youtube-music/pull/772)
- Bump jpeg-js from 0.4.3 to 0.4.4 [`#756`](https://github.com/th-ch/youtube-music/pull/756)
- Support MPRIS loop and volume change [`#749`](https://github.com/th-ch/youtube-music/pull/749)
- [Snyk] Upgrade @cliqz/adblocker-electron from 1.23.7 to 1.23.8 [`#742`](https://github.com/th-ch/youtube-music/pull/742)
- Use ; instead of space for play/pause. [`#745`](https://github.com/th-ch/youtube-music/pull/745)
- Update readme.md [`#750`](https://github.com/th-ch/youtube-music/pull/750)
- fix lyrics font size [`#753`](https://github.com/th-ch/youtube-music/pull/753)
- fix top gap between nav-bar and browse-page [`#734`](https://github.com/th-ch/youtube-music/pull/734)
- migrate from remote to ipc + fix restart in portable app [`#605`](https://github.com/th-ch/youtube-music/pull/605)
- [Snyk] Upgrade custom-electron-prompt from 1.4.2 to 1.5.0 [`#717`](https://github.com/th-ch/youtube-music/pull/717)
- Picture in Picture v2 [`#685`](https://github.com/th-ch/youtube-music/pull/685)
- Add MPRIS volume control [`#776`](https://github.com/th-ch/youtube-music/issues/776)
- Remove jest [`bb6115f`](https://github.com/th-ch/youtube-music/commit/bb6115fec1a18a416edb365a442eb0b0ee330768)
- migrate from remote to ipc [`5bd9768`](https://github.com/th-ch/youtube-music/commit/5bd97685b9e07c656e0b57a9e02819afc70af1b1)
- v3 [`d23bfe9`](https://github.com/th-ch/youtube-music/commit/d23bfe936840b947ca101fd304464f65d36e88cc)
#### [v1.17.0](https://github.com/th-ch/youtube-music/compare/v1.16.0...v1.17.0)
> 16 May 2022
- Bump ejs from 3.1.6 to 3.1.7 [`#712`](https://github.com/th-ch/youtube-music/pull/712)
- fix injectCSS `did-finish-load` listener overload [`#693`](https://github.com/th-ch/youtube-music/pull/693)
- [Snyk] Upgrade @cliqz/adblocker-electron from 1.23.6 to 1.23.7 [`#689`](https://github.com/th-ch/youtube-music/pull/689)
- [Snyk] Upgrade custom-electron-prompt from 1.4.1 to 1.4.2 [`#686`](https://github.com/th-ch/youtube-music/pull/686)
- [Snyk] Upgrade @electron/remote from 2.0.7 to 2.0.8 [`#684`](https://github.com/th-ch/youtube-music/pull/684)
- Improve plugin submenu ux [`#699`](https://github.com/th-ch/youtube-music/pull/699)
- update build action [`#702`](https://github.com/th-ch/youtube-music/pull/702)
- add different modes to video-toggle plugin [`#700`](https://github.com/th-ch/youtube-music/pull/700)
- lint [`#701`](https://github.com/th-ch/youtube-music/pull/701)
- [ImgBot] Optimize images [`#703`](https://github.com/th-ch/youtube-music/pull/703)
- add album to lastfm if available [`#695`](https://github.com/th-ch/youtube-music/pull/695)
- [in-app-menu] add hide icon option [`#680`](https://github.com/th-ch/youtube-music/pull/680)
- Add plugin to bypass age restrictions [`#682`](https://github.com/th-ch/youtube-music/pull/682)
- Add "Picture in picture" plugin [`#674`](https://github.com/th-ch/youtube-music/pull/674)
- Set lyrics metadata from Genius [`#679`](https://github.com/th-ch/youtube-music/pull/679)
- MacOS: bring back the app in dock when using tray + app hidden [`#677`](https://github.com/th-ch/youtube-music/pull/677)
- [Snyk] Upgrade @electron/remote from 2.0.4 to 2.0.5 [`#644`](https://github.com/th-ch/youtube-music/pull/644)
- [Snyk] Upgrade ytpl from 2.2.3 to 2.3.0 [`#660`](https://github.com/th-ch/youtube-music/pull/660)
- [Snyk] Upgrade ytdl-core from 4.10.1 to 4.11.0 [`#659`](https://github.com/th-ch/youtube-music/pull/659)
- Bump plist from 3.0.2 to 3.0.5 [`#678`](https://github.com/th-ch/youtube-music/pull/678)
- [Snyk] Upgrade @cliqz/adblocker-electron from 1.23.4 to 1.23.5 [`#624`](https://github.com/th-ch/youtube-music/pull/624)
- [Precise-Volume] fix volumeHud position in miniplayer [`#645`](https://github.com/th-ch/youtube-music/pull/645)
- add always-on-top option [`#655`](https://github.com/th-ch/youtube-music/pull/655)
- [precise-volume] fix expand-volume-slider not updating its value [`#670`](https://github.com/th-ch/youtube-music/pull/670)
- Fix lyrics genius missing parts [`#671`](https://github.com/th-ch/youtube-music/pull/671)
- feat: option to force show like buttons [`#673`](https://github.com/th-ch/youtube-music/pull/673)
- fix custom titlebar in prompt options [`#619`](https://github.com/th-ch/youtube-music/pull/619)
- Process lyrics HTML in Genius util [`d0532d6`](https://github.com/th-ch/youtube-music/commit/d0532d691e56f955ef0b41f5fe2efe6295dddf9e)
- Create first version of picture in picture plugin [`d2265b5`](https://github.com/th-ch/youtube-music/commit/d2265b59d78143cf51fe4dc3d5dee9da66873cc1)
- Bump electron-builder to fix Mac build script [`ae8365f`](https://github.com/th-ch/youtube-music/commit/ae8365f721eafda6c502d02eee86d098f2b9e2a1)
#### [v1.16.0](https://github.com/th-ch/youtube-music/compare/v1.15.0...v1.16.0)
> 20 February 2022
- update in-app-menu [`#596`](https://github.com/th-ch/youtube-music/pull/596)
- Fix clientID [`#602`](https://github.com/th-ch/youtube-music/pull/602)
- Add snoretoast custom compile script [`#600`](https://github.com/th-ch/youtube-music/pull/600)
- fix interactive notifications icon + exclude platform specific plugins from build [`#591`](https://github.com/th-ch/youtube-music/pull/591)
- Add album title to largeImage and change paused icon [`#587`](https://github.com/th-ch/youtube-music/pull/587)
- make useragent override optional [`#595`](https://github.com/th-ch/youtube-music/pull/595)
- get album name from DOM [`#588`](https://github.com/th-ch/youtube-music/pull/588)
- fix various lyrics issues [`#584`](https://github.com/th-ch/youtube-music/pull/584)
- discord set inactivity timeout prompt [`#580`](https://github.com/th-ch/youtube-music/pull/580)
- add single instance lock option [`#578`](https://github.com/th-ch/youtube-music/pull/578)
- fix "restart app on config change" option [`#561`](https://github.com/th-ch/youtube-music/pull/561)
- fix window position save spam [`#562`](https://github.com/th-ch/youtube-music/pull/562)
- load adblocker sooner [`#583`](https://github.com/th-ch/youtube-music/pull/583)
- add description of new plugins to readme [`#585`](https://github.com/th-ch/youtube-music/pull/585)
- Use `center` alignment for lyrics text [`#573`](https://github.com/th-ch/youtube-music/pull/573)
- fix precise-volume hud positioning [`#567`](https://github.com/th-ch/youtube-music/pull/567)
- update electron and dependencies [`#565`](https://github.com/th-ch/youtube-music/pull/565)
- filenamify playlist folder name [`#557`](https://github.com/th-ch/youtube-music/pull/557)
- [Snyk] Security upgrade node-fetch from 2.6.6 to 2.6.7 (3.1.1 incompatible) [`#554`](https://github.com/th-ch/youtube-music/pull/554)
- fix app starting offscreen [`#548`](https://github.com/th-ch/youtube-music/pull/548)
- Release Mac arm64 [`#566`](https://github.com/th-ch/youtube-music/pull/566)
- Build command for Apple (m1) silicon macs [`#553`](https://github.com/th-ch/youtube-music/pull/553)
- [Snyk] Upgrade custom-electron-titlebar from 3.2.9 to 3.2.10 [`#545`](https://github.com/th-ch/youtube-music/pull/545)
- Fix duplicate media session on linux [`#551`](https://github.com/th-ch/youtube-music/pull/551)
- show a badge remaining items when downloading a playlist [`#550`](https://github.com/th-ch/youtube-music/pull/550)
- allow downloading playlists from popup menu [`#549`](https://github.com/th-ch/youtube-music/pull/549)
- xesam:artist should be a list [`#539`](https://github.com/th-ch/youtube-music/pull/539)
- fix notifications showing thumbnail of last song [`#537`](https://github.com/th-ch/youtube-music/pull/537)
- Fix https://github.com/th-ch/youtube-music/pull/578#issuecomment-1035517531 [`#578`](https://github.com/th-ch/youtube-music/pull/578)
- Add automatic changelog [`1d9bfe8`](https://github.com/th-ch/youtube-music/commit/1d9bfe8ac8869cde648164979986964baa52c2f9)
- update electron to v17.0.0 [`fef7115`](https://github.com/th-ch/youtube-music/commit/fef711549fa9862f8ea23301edde747c5802e352)
- update dependencies [`8be07bc`](https://github.com/th-ch/youtube-music/commit/8be07bcb7ad8b727d97c36aa0760aed4e2fc481f)
#### [v1.15.0](https://github.com/th-ch/youtube-music/compare/v1.14.0...v1.15.0)
> 30 December 2021
- Switch from spectron to playwright to fix tests [`#531`](https://github.com/th-ch/youtube-music/pull/531)
- [Snyk] Upgrade @cliqz/adblocker-electron from 1.23.0 to 1.23.1 [`#529`](https://github.com/th-ch/youtube-music/pull/529)
- fix precise-volume options sync [`#525`](https://github.com/th-ch/youtube-music/pull/525)
- Add album art/thumbnail to discord activity [`#524`](https://github.com/th-ch/youtube-music/pull/524)
- fix skip-silences plugin [`#521`](https://github.com/th-ch/youtube-music/pull/521)
- [Snyk] Upgrade electron-updater from 4.6.2 to 4.6.3 [`#520`](https://github.com/th-ch/youtube-music/pull/520)
- update electron & remote & user agents [`#515`](https://github.com/th-ch/youtube-music/pull/515)
- fixes mpris bug in snap [`#513`](https://github.com/th-ch/youtube-music/pull/513)
- Add "Skip silences" plugin [`#519`](https://github.com/th-ch/youtube-music/pull/519)
- Aligned lyric design [`#510`](https://github.com/th-ch/youtube-music/pull/510)
- Fix mpris bugs - follows #480 [`#509`](https://github.com/th-ch/youtube-music/pull/509)
- Various small fixes (discord, video-toggle, precise-volume, playback-speed, shortcuts, lyrics) [`#476`](https://github.com/th-ch/youtube-music/pull/476)
- Mpris + obs-tuna fixes [`#480`](https://github.com/th-ch/youtube-music/pull/480)
- [Snyk] Upgrade node-fetch from 2.6.5 to 2.6.6 [`#498`](https://github.com/th-ch/youtube-music/pull/498)
- fix interaction between blur navbar & in-app-menu [`#491`](https://github.com/th-ch/youtube-music/pull/491)
- [Snyk] Upgrade @cliqz/adblocker-electron from 1.22.7 to 1.23.0 [`#475`](https://github.com/th-ch/youtube-music/pull/475)
- New Plugin: Exponential Volume [`#488`](https://github.com/th-ch/youtube-music/pull/488)
- [Snyk] Upgrade electron-updater from 4.6.0 to 4.6.1 [`#474`](https://github.com/th-ch/youtube-music/pull/474)
- Fix loadeddata/metadata video events rarely not firing (+other small fixes) [`#477`](https://github.com/th-ch/youtube-music/pull/477)
- fix #490 [`#490`](https://github.com/th-ch/youtube-music/issues/490)
- fix #472 [`#472`](https://github.com/th-ch/youtube-music/issues/472)
- fix mpris [`ccfe743`](https://github.com/th-ch/youtube-music/commit/ccfe7434bf708ee58156c2952234a049706edfc2)
- lint [`4362101`](https://github.com/th-ch/youtube-music/commit/4362101c0a2ebb7f0536f615cecba8a55ac96702)
- rework songInfo pause listener [`6726e26`](https://github.com/th-ch/youtube-music/commit/6726e2600b3ca3a8d68e3e1b95b50da211fa354d)
#### [v1.14.0](https://github.com/th-ch/youtube-music/compare/v1.13.0...v1.14.0)
> 7 November 2021
- [Snyk] Upgrade custom-electron-prompt from 1.1.0 to 1.2.0 [`#467`](https://github.com/th-ch/youtube-music/pull/467)
- Video Toggle Plugin [`#448`](https://github.com/th-ch/youtube-music/pull/448)
- fix playback speed plugin [`#462`](https://github.com/th-ch/youtube-music/pull/462)
- Fix sponsorblock skipping when not needed [`#465`](https://github.com/th-ch/youtube-music/pull/465)
- Sponsorblock fix + use new apiLoaded event [`#463`](https://github.com/th-ch/youtube-music/pull/463)
- use apiLoaded event in audio-compressor plugin [`#458`](https://github.com/th-ch/youtube-music/pull/458)
- alert on initial hide-menu enabled [`#456`](https://github.com/th-ch/youtube-music/pull/456)
- Blur plugin tweaks and integration with in-app-menu [`#451`](https://github.com/th-ch/youtube-music/pull/451)
- set resume on start url to songInfo.url [`#449`](https://github.com/th-ch/youtube-music/pull/449)
- quality-changer-plugin [`#446`](https://github.com/th-ch/youtube-music/pull/446)
- get songInfo from youtube API [`#443`](https://github.com/th-ch/youtube-music/pull/443)
- New plugin: Blur navigation bar [`#442`](https://github.com/th-ch/youtube-music/pull/442)
- Discord plugin: Clean Up Export (follow-up #380) [`#440`](https://github.com/th-ch/youtube-music/pull/440)
- remove upgrade button + makes images unselectable [`#434`](https://github.com/th-ch/youtube-music/pull/434)
- new auto confirm when paused [`#433`](https://github.com/th-ch/youtube-music/pull/433)
- fix: mpris instance not registering itself and media controls [`#431`](https://github.com/th-ch/youtube-music/pull/431)
- Audio compressor plugin [`#288`](https://github.com/th-ch/youtube-music/pull/288)
- precise-volume plugin fixes & updates [`#275`](https://github.com/th-ch/youtube-music/pull/275)
- Custom Prompt for changing options [`#243`](https://github.com/th-ch/youtube-music/pull/243)
- [Snyk] Upgrade async-mutex from 0.3.1 to 0.3.2 [`#412`](https://github.com/th-ch/youtube-music/pull/412)
- build(deps): bump tmpl from 1.0.4 to 1.0.5 [`#414`](https://github.com/th-ch/youtube-music/pull/414)
- [Snyk] Upgrade node-fetch from 2.6.1 to 2.6.2 [`#416`](https://github.com/th-ch/youtube-music/pull/416)
- [Snyk] Upgrade @cliqz/adblocker-electron from 1.22.5 to 1.22.6 [`#429`](https://github.com/th-ch/youtube-music/pull/429)
- build(deps-dev): bump electron from 12.0.8 to 12.1.0 [`#430`](https://github.com/th-ch/youtube-music/pull/430)
- Fix discord clearActivity, menu, listen along option [`#380`](https://github.com/th-ch/youtube-music/pull/380)
- Bump dev deps [`41a01ba`](https://github.com/th-ch/youtube-music/commit/41a01ba58a17056ba5143fdbd10d3bae11dd8d52)
- Discord add reconnecting functionality [`b5fd6b4`](https://github.com/th-ch/youtube-music/commit/b5fd6b4969a318b3738583e7f33eb2c0cf295237)
- add custom-electron-prompt [`e4eed2e`](https://github.com/th-ch/youtube-music/commit/e4eed2e51979378e62dab902e425218cae5108dc)
#### [v1.13.0](https://github.com/th-ch/youtube-music/compare/v1.12.2...v1.13.0)
> 19 September 2021
- [Snyk] Upgrade @cliqz/adblocker-electron from 1.22.4 to 1.22.5 [`#406`](https://github.com/th-ch/youtube-music/pull/406)
- Fix incorrect Google alert caused by changing user agent coresponding to current platform [`#384`](https://github.com/th-ch/youtube-music/pull/384)
- [Snyk] Upgrade electron-updater from 4.4.3 to 4.4.6 [`#401`](https://github.com/th-ch/youtube-music/pull/401)
- [Snyk] Upgrade electron-updater from 4.4.0 to 4.4.1 [`#370`](https://github.com/th-ch/youtube-music/pull/370)
- Bump path-parse from 1.0.6 to 1.0.7 [`#375`](https://github.com/th-ch/youtube-music/pull/375)
- [Snyk] Upgrade @cliqz/adblocker-electron from 1.22.2 to 1.22.3 [`#385`](https://github.com/th-ch/youtube-music/pull/385)
- Bump jszip from 3.5.0 to 3.7.1 [`#388`](https://github.com/th-ch/youtube-music/pull/388)
- List missing plugins [`#382`](https://github.com/th-ch/youtube-music/pull/382)
- add tuna plugin for obs [`#397`](https://github.com/th-ch/youtube-music/pull/397)
- Update menu buttons to new format [`#389`](https://github.com/th-ch/youtube-music/pull/389)
- Plugin to fetch lyrics from Genius [`#387`](https://github.com/th-ch/youtube-music/pull/387)
- Add mpris support with cherry picked commit from previous PR https://github.com/th-ch/youtube-music/pull/394 [`#395`](https://github.com/th-ch/youtube-music/pull/395)
- Add "Listen Along" button, solve #353 [`#383`](https://github.com/th-ch/youtube-music/pull/383)
- Bump node to v14 [`#386`](https://github.com/th-ch/youtube-music/pull/386)
- [Snyk] Upgrade electron-updater from 4.3.9 to 4.3.10 [`#350`](https://github.com/th-ch/youtube-music/pull/350)
- [Snyk] Upgrade chokidar from 3.5.1 to 3.5.2 [`#354`](https://github.com/th-ch/youtube-music/pull/354)
- Bump ytdl/ytpl [`c01506d`](https://github.com/th-ch/youtube-music/commit/c01506dc441bfc538471dc2c552c1a8a2800c611)
- Add mpris support [`e255777`](https://github.com/th-ch/youtube-music/commit/e255777283c7b16611404cbfe260bfcca75a1e40)
- Add Genius lyrics plugin [`acbe0ac`](https://github.com/th-ch/youtube-music/commit/acbe0ac25d568c25fedb514e0e96c66497b0f2d6)
#### [v1.12.2](https://github.com/th-ch/youtube-music/compare/v1.12.1...v1.12.2)
> 1 July 2021
- Fix downloader plugin [`#339`](https://github.com/th-ch/youtube-music/pull/339)
- [Snyk] Upgrade @cliqz/adblocker-electron from 1.22.0 to 1.22.1 [`#337`](https://github.com/th-ch/youtube-music/pull/337)
- Update and simplify in-app-menu [`#249`](https://github.com/th-ch/youtube-music/pull/249)
- Bump hosted-git-info from 2.8.8 to 2.8.9 [`#331`](https://github.com/th-ch/youtube-music/pull/331)
- Bump lodash from 4.17.20 to 4.17.21 [`#330`](https://github.com/th-ch/youtube-music/pull/330)
- [Snyk] Upgrade ytdl-core from 4.8.0 to 4.8.2 [`#328`](https://github.com/th-ch/youtube-music/pull/328)
- [Snyk] Upgrade electron-updater from 4.3.8 to 4.3.9 [`#324`](https://github.com/th-ch/youtube-music/pull/324)
- Bump normalize-url from 4.5.0 to 4.5.1 [`#323`](https://github.com/th-ch/youtube-music/pull/323)
- Bump trim-newlines from 3.0.0 to 3.0.1 [`#320`](https://github.com/th-ch/youtube-music/pull/320)
- [Snyk] Upgrade @ffmpeg/core from 0.9.0 to 0.10.0 [`#317`](https://github.com/th-ch/youtube-music/pull/317)
- [Snyk] Upgrade @ffmpeg/ffmpeg from 0.9.8 to 0.10.0 [`#316`](https://github.com/th-ch/youtube-music/pull/316)
- [Snyk] Upgrade custom-electron-titlebar from 3.2.6 to 3.2.7 [`#311`](https://github.com/th-ch/youtube-music/pull/311)
- fix hidden webp thumbnail throwing MIME type error in downloader [`#318`](https://github.com/th-ch/youtube-music/pull/318)
- Add Sponsorblock plugin [`#308`](https://github.com/th-ch/youtube-music/pull/308)
- [Snyk] Upgrade @ffmpeg/ffmpeg from 0.9.7 to 0.9.8 [`#305`](https://github.com/th-ch/youtube-music/pull/305)
- Bump dependencies to fix vulnerabilities [`496836b`](https://github.com/th-ch/youtube-music/commit/496836b33b116e06b8d1361ce1f47ab6c9138cae)
- update refreshMenu() function [`33855f1`](https://github.com/th-ch/youtube-music/commit/33855f17dd80c099117a3d84bbd9b5021776771c)
- Add SponsorBlock plugin [`ca64a77`](https://github.com/th-ch/youtube-music/commit/ca64a77ed0236fd9cfb4b40e450578a186638dc7)
#### [v1.12.1](https://github.com/th-ch/youtube-music/compare/v1.12.0...v1.12.1)
> 28 May 2021
- Bump ws from 7.4.3 to 7.4.6 [`#303`](https://github.com/th-ch/youtube-music/pull/303)
- Bump browserslist from 4.16.3 to 4.16.6 [`#301`](https://github.com/th-ch/youtube-music/pull/301)
- [Snyk] Upgrade @cliqz/adblocker-electron from 1.20.4 to 1.20.5 [`#300`](https://github.com/th-ch/youtube-music/pull/300)
- [Snyk] Upgrade ytdl-core from 4.5.0 to 4.7.0 [`#299`](https://github.com/th-ch/youtube-music/pull/299)
- [Snyk] Upgrade @ffmpeg/core from 0.8.5 to 0.9.0 [`#298`](https://github.com/th-ch/youtube-music/pull/298)
- [Snyk] Upgrade filenamify from 4.2.0 to 4.3.0 [`#293`](https://github.com/th-ch/youtube-music/pull/293)
- [Snyk] Upgrade ytpl from 2.1.1 to 2.2.0 [`#285`](https://github.com/th-ch/youtube-music/pull/285)
- fix song-info callback duplication [`#269`](https://github.com/th-ch/youtube-music/pull/269)
- fix notification showing appID instead of app name on windows [`#270`](https://github.com/th-ch/youtube-music/pull/270)
- Upgrade electron to v12 [`#273`](https://github.com/th-ch/youtube-music/pull/273)
- fix last-fm overwrite config on each start [`#267`](https://github.com/th-ch/youtube-music/pull/267)
- Downloader tweaks + taskbar progress bar [`#265`](https://github.com/th-ch/youtube-music/pull/265)
- remove `open` dependency from last-fm plugin [`#262`](https://github.com/th-ch/youtube-music/pull/262)
- Fix downloader metadata if not currently playing [`#252`](https://github.com/th-ch/youtube-music/pull/252)
- fix playPause bugs by directly playPause video element [`#259`](https://github.com/th-ch/youtube-music/pull/259)
- Bump ua-parser-js from 0.7.23 to 0.7.28 [`#260`](https://github.com/th-ch/youtube-music/pull/260)
- Fix precise volume listener override [`#253`](https://github.com/th-ch/youtube-music/pull/253)
- fix css not inserting on reload [`#255`](https://github.com/th-ch/youtube-music/pull/255)
- playlist download progressBar using `chokidar` [`53bf7c5`](https://github.com/th-ch/youtube-music/commit/53bf7c5068fdc14f5aa469d47b3174d27f40e05c)
- download progress bar on taskbar [`a8ac2c3`](https://github.com/th-ch/youtube-music/commit/a8ac2c3af988f299be85010e7fea541096b7e261)
- fix: upgrade @cliqz/adblocker-electron from 1.20.4 to 1.20.5 [`c5f84b5`](https://github.com/th-ch/youtube-music/commit/c5f84b568b0c3480af1abc8ff111771e2170a50e)
#### [v1.12.0](https://github.com/th-ch/youtube-music/compare/v1.11.0...v1.12.0)
> 4 May 2021
- Menu tweaks [`#224`](https://github.com/th-ch/youtube-music/pull/224)
- Interactive notifications for windows [`#228`](https://github.com/th-ch/youtube-music/pull/228)
- [Plugin] Precise volume control [`#236`](https://github.com/th-ch/youtube-music/pull/236)
- [Snyk] Upgrade electron-store from 7.0.2 to 7.0.3 [`#244`](https://github.com/th-ch/youtube-music/pull/244)
- [Snyk] Upgrade @cliqz/adblocker-electron from 1.20.3 to 1.20.4 [`#233`](https://github.com/th-ch/youtube-music/pull/233)
- Dependencies update [`#231`](https://github.com/th-ch/youtube-music/pull/231)
- Fix downloader metadata [`#245`](https://github.com/th-ch/youtube-music/pull/245)
- Last.fm support [`#196`](https://github.com/th-ch/youtube-music/pull/196)
- simple fix for discord plugin [`#239`](https://github.com/th-ch/youtube-music/pull/239)
- In-app-menu plugin - rename plugin & configure menu builder [`#215`](https://github.com/th-ch/youtube-music/pull/215)
- Allows downloading songs that aren't currently playing [`#221`](https://github.com/th-ch/youtube-music/pull/221)
- Updated download plugin icon color to match other icons [`#222`](https://github.com/th-ch/youtube-music/pull/222)
- [Notification Plugin] Fix duplicate notification [`#216`](https://github.com/th-ch/youtube-music/pull/216)
- Pass metadata to front + use metadata URL in downloader [`#213`](https://github.com/th-ch/youtube-music/pull/213)
- Refresh menu on plugin enable/disable (show/hide submenu) [`#217`](https://github.com/th-ch/youtube-music/pull/217)
- remove 'shortcuts' from default plugins [`#218`](https://github.com/th-ch/youtube-music/pull/218)
- [Plugin] styled-bars [`#201`](https://github.com/th-ch/youtube-music/pull/201)
- Add configurable notification urgency [`#212`](https://github.com/th-ch/youtube-music/pull/212)
- add Download Folder Chooser [`#207`](https://github.com/th-ch/youtube-music/pull/207)
- Improved songinfo provider, by using the data from the '/player' request [`#194`](https://github.com/th-ch/youtube-music/pull/194)
- Download plugin directory chooser [`#10`](https://github.com/th-ch/youtube-music/pull/10)
- [Snyk] Upgrade @cliqz/adblocker-electron from 1.20.0 to 1.20.1 [`#180`](https://github.com/th-ch/youtube-music/pull/180)
- [Plugin] taskbar-mediacontrol (for Windows) [`#200`](https://github.com/th-ch/youtube-music/pull/200)
- merge source [`#3`](https://github.com/th-ch/youtube-music/pull/3)
- merge source [`#2`](https://github.com/th-ch/youtube-music/pull/2)
- Add playlist feature in downloader plugin + custom menus in plugin system [`#203`](https://github.com/th-ch/youtube-music/pull/203)
- Added Discord timeout [`#192`](https://github.com/th-ch/youtube-music/pull/192)
- Override hide(),show(),isVisible from inside plugin [`6427b34`](https://github.com/th-ch/youtube-music/commit/6427b3406c8d84c5b7ecbe6a28158d5dc895c3c2)
- added back original yarn.lock [`24fea5a`](https://github.com/th-ch/youtube-music/commit/24fea5a24afd4f547628549962d24756cca5e413)
- remove local prompt [`8dc486f`](https://github.com/th-ch/youtube-music/commit/8dc486f18fe02a218b149838dc7ab939ec1b698a)
#### [v1.11.0](https://github.com/th-ch/youtube-music/compare/v1.10.0...v1.11.0)
> 9 March 2021
- [Snyk] Upgrade electron-store from 7.0.1 to 7.0.2 [`#178`](https://github.com/th-ch/youtube-music/pull/178)
- Added function to toggle resuming of last song when app starts [`#177`](https://github.com/th-ch/youtube-music/pull/177)
- [Snyk] Upgrade discord-rpc from 3.1.4 to 3.2.0 [`#175`](https://github.com/th-ch/youtube-music/pull/175)
- [Snyk] Upgrade @cliqz/adblocker-electron from 1.19.0 to 1.20.0 [`#154`](https://github.com/th-ch/youtube-music/pull/154)
- Added metadata to downloader plugin, and updated packages [`dd1bdae`](https://github.com/th-ch/youtube-music/commit/dd1bdae9478ef831ee2a00b29be04c65626933f8)
- Fix download/speed menu item [`796a7aa`](https://github.com/th-ch/youtube-music/commit/796a7aaaf1ecaf80b2ef113137f2222499803e29)
- fix: upgrade @cliqz/adblocker-electron from 1.19.0 to 1.20.0 [`538ab52`](https://github.com/th-ch/youtube-music/commit/538ab52abd46c2e3c6abb529c5137b5286d29670)
#### [v1.10.0](https://github.com/th-ch/youtube-music/compare/v1.9.0...v1.10.0)
> 7 February 2021
- [Snyk] Upgrade @ffmpeg/ffmpeg from 0.9.6 to 0.9.7 [`#146`](https://github.com/th-ch/youtube-music/pull/146)
- Reuse the same notification, instead of creating a new one each time the song changes. [`#144`](https://github.com/th-ch/youtube-music/pull/144)
- [Snyk] Upgrade ytdl-core from 4.2.1 to 4.3.0 [`#136`](https://github.com/th-ch/youtube-music/pull/136)
- bring the new commits to this fork [`#1`](https://github.com/th-ch/youtube-music/pull/1)
- GH page [`3bcf409`](https://github.com/th-ch/youtube-music/commit/3bcf409f2b1629333714b187c606891cedb12512)
- Add plugin to control playback speed like in YouTube (from 0.25 to 2) [`f7f3185`](https://github.com/th-ch/youtube-music/commit/f7f31850d3d9879002dc47326e4f6ec9a52c25a1)
- Update back.js [`1fdf241`](https://github.com/th-ch/youtube-music/commit/1fdf2416ad414035104bfb51b8450d82e566cb13)
#### [v1.9.0](https://github.com/th-ch/youtube-music/compare/v1.8.2...v1.9.0)
> 15 January 2021
- [Snyk] Upgrade electron-debug from 3.1.0 to 3.2.0 [`#121`](https://github.com/th-ch/youtube-music/pull/121)
- Refactor providers [`#125`](https://github.com/th-ch/youtube-music/pull/125)
- Added Discord rich presence and added extra properties to songInfo provider [`#124`](https://github.com/th-ch/youtube-music/pull/124)
- Fix plugins with context isolation [`#127`](https://github.com/th-ch/youtube-music/pull/127)
- Windows portable exe [`#126`](https://github.com/th-ch/youtube-music/pull/126)
- Split providers in 2 [`0743034`](https://github.com/th-ch/youtube-music/commit/0743034de0443e889ec11d7ea83727ff4fb96599)
- Added Discord rich presence and added extra properties to songinfo provider [`a8ce87f`](https://github.com/th-ch/youtube-music/commit/a8ce87f2ccb4f0fdbd36676883e6a0497bebc263)
- Update discord plugin for new provider + wait for ready [`aec542e`](https://github.com/th-ch/youtube-music/commit/aec542e95e2837f54bf19de675f311444789ea4e)
#### [v1.8.2](https://github.com/th-ch/youtube-music/compare/v1.8.1...v1.8.2)
> 12 January 2021
- Downloader plugin - custom audio format [`#118`](https://github.com/th-ch/youtube-music/pull/118)
- Globalized the song info and song controls, and updated Touch Bar for it. [`#102`](https://github.com/th-ch/youtube-music/pull/102)
- Bump electron to v11 [`#120`](https://github.com/th-ch/youtube-music/pull/120)
- Globalized the songinfo and song controls, and changed the pause/play button. [`9be3e1a`](https://github.com/th-ch/youtube-music/commit/9be3e1afe91f0aa3419040bba65e7b3b83b469c6)
- Simplifies the notification plugin to use the globalized song info [`5bffdbd`](https://github.com/th-ch/youtube-music/commit/5bffdbd6285a6816749c467d6e912d14748f9959)
- Loads providers before plugins [`3a5d9bd`](https://github.com/th-ch/youtube-music/commit/3a5d9bd973bdd67e77f8a7687c1430245a9490bd)
#### [v1.8.1](https://github.com/th-ch/youtube-music/compare/v1.8.0...v1.8.1)
> 8 January 2021
- [Snyk] Upgrade electron-updater from 4.3.5 to 4.3.6 [`#116`](https://github.com/th-ch/youtube-music/pull/116)
- [Snyk] Upgrade @cliqz/adblocker-electron from 1.18.8 to 1.19.0 [`#117`](https://github.com/th-ch/youtube-music/pull/117)
- [Snyk] Upgrade ytdl-core from 4.1.1 to 4.1.2 [`#109`](https://github.com/th-ch/youtube-music/pull/109)
- Bump node-notifier from 8.0.0 to 8.0.1 [`#104`](https://github.com/th-ch/youtube-music/pull/104)
- fix: upgrade electron-updater from 4.3.5 to 4.3.6 [`0bf77e5`](https://github.com/th-ch/youtube-music/commit/0bf77e592a87eb8a5222cf2c1588488a51044422)
- fix: upgrade @cliqz/adblocker-electron from 1.18.8 to 1.19.0 [`5c0cc08`](https://github.com/th-ch/youtube-music/commit/5c0cc08d80d60c46e8b27343c6fc302f64fe89e2)
- fix: upgrade ytdl-core from 4.1.1 to 4.1.2 [`e2cc262`](https://github.com/th-ch/youtube-music/commit/e2cc2628aea653739f878ec2cd2e72e2e70018a1)
#### [v1.8.0](https://github.com/th-ch/youtube-music/compare/v1.7.5...v1.8.0)
> 20 December 2020
- Added Touch Bar plugin [`#101`](https://github.com/th-ch/youtube-music/pull/101)
- [Snyk] Upgrade @ffmpeg/core from 0.8.4 to 0.8.5 [`#99`](https://github.com/th-ch/youtube-music/pull/99)
- [Snyk] Upgrade @ffmpeg/ffmpeg from 0.9.5 to 0.9.6 [`#100`](https://github.com/th-ch/youtube-music/pull/100)
- [Readme] Web folder for readme assets + new SVG animation [`#96`](https://github.com/th-ch/youtube-music/pull/96)
- Add new Linux targets (deb, freebsd, rpm) [`#94`](https://github.com/th-ch/youtube-music/pull/94)
- Web folder for readme assets + new svg animation [`01fc965`](https://github.com/th-ch/youtube-music/commit/01fc9651705f457da63615ff774f00957f783d3d)
- touchbar plugin - fixed code style [`7473677`](https://github.com/th-ch/youtube-music/commit/7473677477071ca5e7b18bda3193e345d7fd549f)
- added initial touchbar support [`c3e2c13`](https://github.com/th-ch/youtube-music/commit/c3e2c1380810d156d9d6863fffc804242171bec0)
#### [v1.7.5](https://github.com/th-ch/youtube-music/compare/v1.7.4...v1.7.5)
> 12 December 2020
- Bump ini from 1.3.5 to 1.3.7 [`#92`](https://github.com/th-ch/youtube-music/pull/92)
- Fix adblocking [`#90`](https://github.com/th-ch/youtube-music/pull/90)
- Bump adblocker dependency [`49497d0`](https://github.com/th-ch/youtube-music/commit/49497d0efb28ee0be5b16d0f1c3660efafcd289c)
- Fix adblocker preloading to inject scripts/styles [`66c5ce4`](https://github.com/th-ch/youtube-music/commit/66c5ce46caa85a7ae4ceb3d63a9e168827015c71)
- Add uBlock Origin filters to default sources [`79c7959`](https://github.com/th-ch/youtube-music/commit/79c795927a3be96456a2f45159285c64166a29b8)
#### [v1.7.4](https://github.com/th-ch/youtube-music/compare/v1.7.3...v1.7.4)
> 8 December 2020
#### [v1.7.3](https://github.com/th-ch/youtube-music/compare/v1.7.2...v1.7.3)
> 8 December 2020
- Adblocker: add option to disable default lists [`22c7f70`](https://github.com/th-ch/youtube-music/commit/22c7f70c938566a9db9c4d46a57224cfdee43df0)
#### [v1.7.2](https://github.com/th-ch/youtube-music/compare/v1.7.1...v1.7.2)
> 6 December 2020
- Add AUR badge + beautify badges [`#82`](https://github.com/th-ch/youtube-music/pull/82)
- Bugfix: only use cache with no additional blocklists [`467171a`](https://github.com/th-ch/youtube-music/commit/467171a17e648331d63f166c2da2f3134e95b37f)
- Add AUR tag + beautify tags [`d212206`](https://github.com/th-ch/youtube-music/commit/d21220693b9ffa26e05fe1963376b636b40b9952)
- Readme: add youtube-music logo to badges [`3022fac`](https://github.com/th-ch/youtube-music/commit/3022facbead40ccd81629c37b870ab33ce7fa106)
#### [v1.7.1](https://github.com/th-ch/youtube-music/compare/v1.7.0...v1.7.1)
> 3 December 2020
- Option to restart the app on config changes [`fd97576`](https://github.com/th-ch/youtube-music/commit/fd97576611ae80b959ffe7984e88ddc8d28a1ffc)
- Bump version to 1.7.1 [`e07cac2`](https://github.com/th-ch/youtube-music/commit/e07cac240691b1c9d6909e457824616182374c3a)
#### [v1.7.0](https://github.com/th-ch/youtube-music/compare/v1.6.5...v1.7.0)
> 3 December 2020
- Refactor config, custom plugin options [`#79`](https://github.com/th-ch/youtube-music/pull/79)
- Refactor config for simpler use and advanced options in plugins [`8ab2da0`](https://github.com/th-ch/youtube-music/commit/8ab2da0482b6211b6b6d43423ec06daed48dac4f)
- Allow editing config (advanced) [`f4fe5c2`](https://github.com/th-ch/youtube-music/commit/f4fe5c2a58e1ad555c321f27c00d2d78184fc687)
- Adblocker - advanced options (caching or not, additional lists) [`b94d0d4`](https://github.com/th-ch/youtube-music/commit/b94d0d4e8bd3a92bbb5e012a63fa782baa774be7)
#### [v1.6.5](https://github.com/th-ch/youtube-music/compare/v1.6.4...v1.6.5)
> 2 December 2020
- Add option to disable hardware acceleration [`#77`](https://github.com/th-ch/youtube-music/pull/77)
- Downloader plugin - retry and upgrade dependencies [`#76`](https://github.com/th-ch/youtube-music/pull/76)
- Reflect Arch Linux package name change [`#70`](https://github.com/th-ch/youtube-music/pull/70)
- Option to hide menu [`#67`](https://github.com/th-ch/youtube-music/pull/67)
- Add Arch Linux installation instructions [`#68`](https://github.com/th-ch/youtube-music/pull/68)
- Update ytdl-core to 4.1.1 [`33a11ef`](https://github.com/th-ch/youtube-music/commit/33a11efe9acad234e41ad9044ae9e67fd573b7f4)
- Autoupdate modal: add download/disable updates buttons [`ae5b85d`](https://github.com/th-ch/youtube-music/commit/ae5b85d8d748659f2e23d417560026f24ab8ce9c)
- Option to hide menu (win/linux) [`4bac3ac`](https://github.com/th-ch/youtube-music/commit/4bac3ace186c5be2cb9409d2b703f960bd662145)
#### [v1.6.4](https://github.com/th-ch/youtube-music/compare/v1.6.3...v1.6.4)
> 24 November 2020
#### [v1.6.3](https://github.com/th-ch/youtube-music/compare/v1.6.2...v1.6.3)
> 24 November 2020
- Improve CI [`#64`](https://github.com/th-ch/youtube-music/pull/64)
- Ensure menu is visible on all platforms [`#63`](https://github.com/th-ch/youtube-music/pull/63)
- [Snyk] Upgrade @cliqz/adblocker-electron from 1.18.3 to 1.18.4 [`#62`](https://github.com/th-ch/youtube-music/pull/62)
- fix: upgrade @cliqz/adblocker-electron from 1.18.3 to 1.18.4 [`2b243f6`](https://github.com/th-ch/youtube-music/commit/2b243f6dcb00d3b6f27fd066c093e7b16bb384e2)
- CI: cache yarn directory [`0fd4933`](https://github.com/th-ch/youtube-music/commit/0fd49330d3218ec5f1bc62b72ace28e79d02bc93)
- Run CI on every push/PR [`cf4827d`](https://github.com/th-ch/youtube-music/commit/cf4827d780fee510a27eecf42453b0505c52bcf9)
#### [v1.6.2](https://github.com/th-ch/youtube-music/compare/v1.6.0...v1.6.2)
> 22 November 2020
- Add github action to build/release [`#60`](https://github.com/th-ch/youtube-music/pull/60)
- Bump to node 12 [`#59`](https://github.com/th-ch/youtube-music/pull/59)
- Bump to node 12 [`#59`](https://github.com/th-ch/youtube-music/pull/59)
- Add downloader (video -&gt; mp3) plugin (in music menu) [`e197087`](https://github.com/th-ch/youtube-music/commit/e197087a5027af1ca71ecde7bbdf6351137555b9)
- Delete AppVeyor/Travis CI integration [`941dd90`](https://github.com/th-ch/youtube-music/commit/941dd90d77a5c46ed5505918374693fcd892af1f)
- GH action to build/release [`fc4754a`](https://github.com/th-ch/youtube-music/commit/fc4754a1709e6eb70d662f89eafd360aa4a77aa2)
#### [v1.6.0](https://github.com/th-ch/youtube-music/compare/v1.5.0...v1.6.0)
> 11 November 2020
- [Snyk] Upgrade electron-store from 6.0.0 to 6.0.1 [`#54`](https://github.com/th-ch/youtube-music/pull/54)
- Add notifications plugin (notify of song on play event) [`bcff6e5`](https://github.com/th-ch/youtube-music/commit/bcff6e51348645395549c206717225fb16a29cda)
- Plugins/event handlers in each window [`9bc81da`](https://github.com/th-ch/youtube-music/commit/9bc81da6f2c7f5f35769489e179851bdd80a7da8)
- Option to toggle devtools [`3e97e93`](https://github.com/th-ch/youtube-music/commit/3e97e9307cf0991adc5584a603c292b03bc6202d)
#### [v1.5.0](https://github.com/th-ch/youtube-music/compare/v1.4.0...v1.5.0)
> 4 October 2020
- Bump node-fetch from 2.6.0 to 2.6.1 [`#45`](https://github.com/th-ch/youtube-music/pull/45)
- [Snyk] Upgrade @cliqz/adblocker-electron from 1.17.0 to 1.18.0 [`#47`](https://github.com/th-ch/youtube-music/pull/47)
- [Snyk] Upgrade electron-updater from 4.3.3 to 4.3.4 [`#40`](https://github.com/th-ch/youtube-music/pull/40)
- Bump elliptic from 6.5.2 to 6.5.3 [`#38`](https://github.com/th-ch/youtube-music/pull/38)
- [Snyk] Upgrade @cliqz/adblocker-electron from 1.16.0 to 1.16.1 [`#37`](https://github.com/th-ch/youtube-music/pull/37)
- Bump lodash from 4.17.15 to 4.17.19 [`#34`](https://github.com/th-ch/youtube-music/pull/34)
- Option to start at login [`#32`](https://github.com/th-ch/youtube-music/pull/32)
- Bump dependencies [`97dce5a`](https://github.com/th-ch/youtube-music/commit/97dce5ad41ba7ff7a12d4e57a6a0acfeccd666d8)
- Bump electron to v10 (+ remove devtron, bump spectron) [`5f0dcbb`](https://github.com/th-ch/youtube-music/commit/5f0dcbb3fc9b2912bba690db232184d32c599150)
- Navigation plugin: fix arrow style [`8d74a0a`](https://github.com/th-ch/youtube-music/commit/8d74a0a9b52c5b5a04b0986e5fbec9b47a35823e)
#### [v1.4.0](https://github.com/th-ch/youtube-music/compare/v1.3.3...v1.4.0)
> 12 July 2020
- Bump electron from 8.2.1 to 8.2.4 [`#31`](https://github.com/th-ch/youtube-music/pull/31)
- [Snyk] Upgrade electron-store from 5.1.1 to 5.2.0 [`#30`](https://github.com/th-ch/youtube-music/pull/30)
- [Snyk] Upgrade @cliqz/adblocker-electron from 1.14.4 to 1.15.0 [`#29`](https://github.com/th-ch/youtube-music/pull/29)
- [Snyk] Upgrade electron-debug from 3.0.1 to 3.1.0 [`#28`](https://github.com/th-ch/youtube-music/pull/28)
- [Snyk] Upgrade electron-updater from 4.3.1 to 4.3.2 [`#27`](https://github.com/th-ch/youtube-music/pull/27)
- [Snyk] Upgrade electron-updater from 4.3.0 to 4.3.1 [`#26`](https://github.com/th-ch/youtube-music/pull/26)
- [Snyk] Upgrade @cliqz/adblocker-electron from 1.14.1 to 1.14.2 [`#25`](https://github.com/th-ch/youtube-music/pull/25)
- [Tests] Add integration tests [`#24`](https://github.com/th-ch/youtube-music/pull/24)
- Add jest, spectron and getPort util for tests [`736a706`](https://github.com/th-ch/youtube-music/commit/736a70680108620cdecab2da9dd48e10354c713e)
- fix: upgrade electron-updater from 4.3.1 to 4.3.2 [`8c94510`](https://github.com/th-ch/youtube-music/commit/8c945100e24187885dbbe5bb7830b1da11e4eaa2)
- Add jest config and test environment to launch app [`bce5b7d`](https://github.com/th-ch/youtube-music/commit/bce5b7d8ebd96886d462a3c999d72e6c69b6f807)
#### [v1.3.3](https://github.com/th-ch/youtube-music/compare/v1.3.2...v1.3.3)
> 29 April 2020
- Move tray click callback in setUpTray [`4824dda`](https://github.com/th-ch/youtube-music/commit/4824dda5d52565deb5cd6ef4b51d2d742677a154)
- Bump version to 1.3.3 [`37cac19`](https://github.com/th-ch/youtube-music/commit/37cac19d9ccae59b89a68b995eaf7e08c7d24d11)
#### [v1.3.2](https://github.com/th-ch/youtube-music/compare/v1.3.1...v1.3.2)
> 26 April 2020
- [Snyk] Upgrade electron-updater from 4.2.5 to 4.3.0 [`#22`](https://github.com/th-ch/youtube-music/pull/22)
- fix: upgrade electron-updater from 4.2.5 to 4.3.0 [`9821300`](https://github.com/th-ch/youtube-music/commit/98213005d09d00bf013d2217809736bdc334ede6)
- Hide the app (no quit) on close if tray enabled [`430687f`](https://github.com/th-ch/youtube-music/commit/430687f4d6d301aaeaeeaa11ae34d971ac3280df)
- Show/hide window when clicking on tray [`058371a`](https://github.com/th-ch/youtube-music/commit/058371ace8fbd3d9f126454fdc7dbff86df05506)
#### [v1.3.1](https://github.com/th-ch/youtube-music/compare/v1.2.0...v1.3.1)
> 12 April 2020
- Add options and tray [`#21`](https://github.com/th-ch/youtube-music/pull/21)
- Upgrade outdated dependencies [`#20`](https://github.com/th-ch/youtube-music/pull/20)
- [Plugins] Migrate ad blocker [`#19`](https://github.com/th-ch/youtube-music/pull/19)
- Upgrade xo [`297de08`](https://github.com/th-ch/youtube-music/commit/297de08278c2704b3baf65c455bba72f72acc06f)
- Bump electron-builder (needed after electron upgrade) [`3d9e59d`](https://github.com/th-ch/youtube-music/commit/3d9e59dc90e0e994e20af55af9134477e68907a5)
- Migrate from adblock-rs to cliqz [`422c3fc`](https://github.com/th-ch/youtube-music/commit/422c3fc28d83da309a80447dcd5064a4346580e8)
#### [v1.2.0](https://github.com/th-ch/youtube-music/compare/v1.1.6...v1.2.0)
> 15 March 2020
- [Snyk] Upgrade electron-localshortcut from 3.1.0 to 3.2.1 [`#13`](https://github.com/th-ch/youtube-music/pull/13)
- [Snyk] Upgrade electron-updater from 4.0.6 to 4.2.2 [`#12`](https://github.com/th-ch/youtube-music/pull/12)
- [Snyk] Upgrade electron-debug from 2.1.0 to 2.2.0 [`#15`](https://github.com/th-ch/youtube-music/pull/15)
- Fix vulnerability [`#16`](https://github.com/th-ch/youtube-music/pull/16)
- Plugin: autoconfirm when paused [`#11`](https://github.com/th-ch/youtube-music/pull/11)
- Migrate to yarn to install packages without package.json (but keep npm rebuild) [`9371a48`](https://github.com/th-ch/youtube-music/commit/9371a4827e2312258a4f692c18f964155d57ceb8)
- Bump electron-store to fix a vulnerability [`7050dfc`](https://github.com/th-ch/youtube-music/commit/7050dfca5c6a545dabc334690572d7f88b37e027)
- Bump electron updater [`f25bb59`](https://github.com/th-ch/youtube-music/commit/f25bb59065d84cde202b5192688847c528c6ef61)
#### [v1.1.6](https://github.com/th-ch/youtube-music/compare/v1.1.5...v1.1.6)
> 11 September 2019
- Bump eslint-utils from 1.3.1 to 1.4.2 [`#7`](https://github.com/th-ch/youtube-music/pull/7)
- Bump lodash.mergewith from 4.6.1 to 4.6.2 [`#4`](https://github.com/th-ch/youtube-music/pull/4)
- Bump lodash from 4.17.11 to 4.17.14 [`#5`](https://github.com/th-ch/youtube-music/pull/5)
- npm audit fix [`1a72129`](https://github.com/th-ch/youtube-music/commit/1a72129108935cbe732621d93b877e90d11a4195)
- Fix Google login [`746b5f1`](https://github.com/th-ch/youtube-music/commit/746b5f13bb08c614df290e69946cfd116a550521)
- Bump version to 1.1.6 [`6fd10ea`](https://github.com/th-ch/youtube-music/commit/6fd10ea4a0f63e9a46e7307d811977f4e0f3213f)
#### [v1.1.5](https://github.com/th-ch/youtube-music/compare/v1.1.4...v1.1.5)
> 6 July 2019
- Fix navigation plugin [`b10a1bb`](https://github.com/th-ch/youtube-music/commit/b10a1bb32dbea187422a43487527c379a9ddbb26)
- Bump version to 1.1.5 [`07c4a42`](https://github.com/th-ch/youtube-music/commit/07c4a429c15f22b173629618518abb97d9ec0100)
#### [v1.1.4](https://github.com/th-ch/youtube-music/compare/v1.1.3...v1.1.4)
> 8 June 2019
- isDev -&gt; is package [`a85325f`](https://github.com/th-ch/youtube-music/commit/a85325f33dbd40517b6029e500569fc1640af2ef)
- Add titlebar/frame only on MacOS [`b1c4cc9`](https://github.com/th-ch/youtube-music/commit/b1c4cc9c45cc48413118aec8ce54767b1983a3e7)
- Bump version to 1.1.4 [`0420f2e`](https://github.com/th-ch/youtube-music/commit/0420f2e49e295cede0db22dbb1f35ffafd6318ed)
#### [v1.1.3](https://github.com/th-ch/youtube-music/compare/v1.1.2...v1.1.3)
> 2 June 2019
- Bump fstream from 1.0.11 to 1.0.12 [`#3`](https://github.com/th-ch/youtube-music/pull/3)
- Version 1.1.3 + npm audit fix [`147ac48`](https://github.com/th-ch/youtube-music/commit/147ac48de6540c836e835fefe47e66e55dbdc9bc)
- Fix case for {en/dis}ablePlugin [`e86d63d`](https://github.com/th-ch/youtube-music/commit/e86d63da8cb083b89c2a26e6514a5b0df8868b13)
- Remove outdated download links [`ec58b5c`](https://github.com/th-ch/youtube-music/commit/ec58b5cbedda8d6f881f0e81f185a1707dbe5fab)
#### [v1.1.2](https://github.com/th-ch/youtube-music/compare/v1.1.1...v1.1.2)
> 1 May 2019
- Display error/retry in case of failure [`5a1d7fb`](https://github.com/th-ch/youtube-music/commit/5a1d7fbf230fcd840a3ea654f31602fb5f504852)
- Bump version to 1.1.2 [`eac2c5c`](https://github.com/th-ch/youtube-music/commit/eac2c5cf14d0a348704f7fbf0ff0bdce02758670)
#### [v1.1.1](https://github.com/th-ch/youtube-music/compare/v1.1.0...v1.1.1)
> 28 April 2019
- Update package lock [`2d3f77d`](https://github.com/th-ch/youtube-music/commit/2d3f77d96211460bb81a73c8c62b9e5407a7cf30)
- Add travis config [`5279a45`](https://github.com/th-ch/youtube-music/commit/5279a45f3537170006ba04cd5d59ac8b879d78a5)
- Add Appveyor config [`abc2bb8`](https://github.com/th-ch/youtube-music/commit/abc2bb8a4f749704f2daf376c0d392030f030caf)
#### [v1.1.0](https://github.com/th-ch/youtube-music/compare/v1.0.0...v1.1.0)
> 19 April 2019
- Build script + check for updates [`b3c24a5`](https://github.com/th-ch/youtube-music/commit/b3c24a521281c352c37d649e8334b581b2a1de4f)
- Add download section in readme [`828e8d4`](https://github.com/th-ch/youtube-music/commit/828e8d472ca3d76dea71d95a85f8fa726404b8e7)
- Add release/licence badge in readme [`9d343bf`](https://github.com/th-ch/youtube-music/commit/9d343bf779f2fa830302cc84c484bf4a93a25f36)
#### v1.0.0
> 19 April 2019
- Initial commit - app + 4 plugins [`8787b5c`](https://github.com/th-ch/youtube-music/commit/8787b5c175d02b52de65f2c559b411d999fa51e4)
- Fix screenshot shadow + compress image [`c5c128f`](https://github.com/th-ch/youtube-music/commit/c5c128fa0f77c69e9bf12f6ca551315b37c51e84)
- Missing quote in readme [`4b446ac`](https://github.com/th-ch/youtube-music/commit/4b446ac7c816c660cf369f3b8b6e420f766ee35f)

View File

@ -12,25 +12,83 @@ const defaultConfig = {
startAtLogin: false,
disableHardwareAcceleration: false,
restartOnConfigChanges: false,
trayClickPlayPause: false,
autoResetAppCache: false,
resumeOnStart: true,
proxy: "",
},
plugins: {
// Enabled plugins
navigation: {
enabled: true,
},
shortcuts: {
enabled: true,
},
adblocker: {
enabled: true,
cache: true,
additionalBlockLists: [], // Additional list of filters, e.g "https://raw.githubusercontent.com/uBlockOrigin/uAssets/master/filters/filters.txt"
},
// Disabled plugins
shortcuts: {
enabled: false,
overrideMediaKeys: false,
},
downloader: {
enabled: false,
ffmpegArgs: [], // e.g. ["-b:a", "192k"] for an audio bitrate of 192kb/s
downloadFolder: undefined, // Custom download folder (absolute path)
preset: "mp3",
},
"last-fm": {
enabled: false,
api_root: "http://ws.audioscrobbler.com/2.0/",
api_key: "04d76faaac8726e60988e14c105d421a", // api key registered by @semvis123
secret: "a5d2a36fdf64819290f6982481eaffa2",
},
discord: {
enabled: false,
activityTimoutEnabled: true, // if enabled, the discord rich presence gets cleared when music paused after the time specified below
activityTimoutTime: 10 * 60 * 1000, // 10 minutes
listenAlong: true, // add a "listen along" button to rich presence
},
notifications: {
enabled: false,
unpauseNotification: false,
urgency: "normal", //has effect only on Linux
interactive: false //has effect only on Windows
},
"precise-volume": {
enabled: false,
steps: 1, //percentage of volume to change
arrowsShortcut: true, //enable ArrowUp + ArrowDown local shortcuts
globalShortcuts: {
volumeUp: "",
volumeDown: ""
},
savedVolume: undefined //plugin save volume between session here
},
sponsorblock: {
enabled: false,
apiURL: "https://sponsor.ajay.app",
categories: [
"sponsor",
"intro",
"outro",
"interaction",
"selfpromo",
"music_offtopic",
],
},
"video-toggle": {
enabled: false,
mode: "custom",
forceHide: false,
},
"picture-in-picture": {
"enabled": false,
"alwaysOnTop": true,
"savePosition": true,
"saveSize": false,
"hotkey": "P"
},
},
};

View File

@ -1,17 +1,26 @@
const defaultConfig = require("./defaults");
const plugins = require("./plugins");
const store = require("./store");
const { restart } = require("../providers/app-controls");
const set = (key, value) => {
store.set(key, value);
};
function setMenuOption(key, value) {
set(key, value);
if (store.get("options.restartOnConfigChanges")) restart();
}
const get = (key) => {
return store.get(key);
};
module.exports = {
defaultConfig,
get,
set,
setMenuOption,
edit: () => store.openInEditor(),
watch: (cb) => {
store.onDidChange("options", cb);

View File

@ -1,4 +1,5 @@
const store = require("./store");
const { restart } = require("../providers/app-controls");
function getEnabled() {
const plugins = store.get("plugins");
@ -24,12 +25,21 @@ function setOptions(plugin, options) {
});
}
function setMenuOptions(plugin, options) {
setOptions(plugin, options);
if (store.get("options.restartOnConfigChanges")) restart();
}
function getOptions(plugin) {
return store.get("plugins")[plugin];
}
function enable(plugin) {
setOptions(plugin, { enabled: true });
setMenuOptions(plugin, { enabled: true });
}
function disable(plugin) {
setOptions(plugin, { enabled: false });
setMenuOptions(plugin, { enabled: false });
}
module.exports = {
@ -38,4 +48,6 @@ module.exports = {
enable,
disable,
setOptions,
setMenuOptions,
getOptions,
};

View File

@ -2,7 +2,63 @@ const Store = require("electron-store");
const defaults = require("./defaults");
const setDefaultPluginOptions = (store, plugin) => {
if (!store.get(`plugins.${plugin}`)) {
store.set(`plugins.${plugin}`, defaults.plugins[plugin]);
}
}
const migrations = {
">=1.17.0": (store) => {
setDefaultPluginOptions(store, "picture-in-picture");
if (store.get("plugins.video-toggle.mode") === undefined) {
store.set("plugins.video-toggle.mode", "custom");
}
},
">=1.14.0": (store) => {
if (
typeof store.get("plugins.precise-volume.globalShortcuts") !== "object"
) {
store.set("plugins.precise-volume.globalShortcuts", {});
}
if (store.get("plugins.hide-video-player.enabled")) {
store.delete("plugins.hide-video-player");
store.set("plugins.video-toggle.enabled", true);
}
},
">=1.13.0": (store) => {
if (store.get("plugins.discord.listenAlong") === undefined) {
store.set("plugins.discord.listenAlong", true);
}
},
">=1.12.0": (store) => {
const options = store.get("plugins.shortcuts");
let updated = false;
for (const optionType of ["global", "local"]) {
if (Array.isArray(options[optionType])) {
const updatedOptions = {};
for (const optionObject of options[optionType]) {
if (optionObject.action && optionObject.shortcut) {
updatedOptions[optionObject.action] = optionObject.shortcut;
}
}
options[optionType] = updatedOptions;
updated = true;
}
}
if (updated) {
store.set("plugins.shortcuts", options);
}
},
">=1.11.0": (store) => {
if (store.get("options.resumeOnStart") === undefined) {
store.set("options.resumeOnStart", true);
}
},
">=1.7.0": (store) => {
const enabledPlugins = store.get("plugins");
if (!Array.isArray(enabledPlugins)) {

BIN
docs/favicon/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 247 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
docs/favicon/favicon_32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 365 B

BIN
docs/favicon/favicon_48.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 493 B

BIN
docs/favicon/favicon_96.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 860 B

1
docs/img/adblock.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="400"><g transform="translate(183.604 196.396)" stroke="#fff" stroke-width="2.23"><path style="line-height:normal;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration-line:none;text-transform:none;block-progression:tb;marker:none" d="M-116.99 106.245l31.82 31.82 236.31-236.31-31.82-31.82z" color="#000" font-weight="400" font-family="Sans" overflow="visible" fill="#fff" stroke="none"/><circle r="171.304" cy="4" cx="16" fill="none" stroke-width="44.6"/></g></svg>

After

Width:  |  Height:  |  Size: 552 B

1
docs/img/bg-bottom.svg Normal file
View File

@ -0,0 +1 @@
<svg width="1440" height="347" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="a"><stop stop-color="#606483" stop-opacity="0" offset="0%"/><stop stop-color="#0B0D19" stop-opacity=".72" offset="100%"/></linearGradient><linearGradient x1="50%" y1="0%" x2="39.334%" y2="79.282%" id="b"><stop stop-color="#0B0D19" offset="0%"/><stop stop-color="#0B0D19" stop-opacity="0" offset="100%"/></linearGradient></defs><g fill="none" fill-rule="evenodd"><path d="M177.486 208.219c78.18 89.285 218.65-81.067 218.65-119.337 0-38.27-86.408-69.295-193-69.295-106.59 0-193 31.024-193 69.295 0 38.27 89.17 30.051 167.35 119.337z" transform="rotate(6 -140.175 3980.948)" fill="url(#a)"/><path d="M252.464 335.471c101.27 115.965 283.227-105.29 283.227-154.996 0-49.705-111.929-90-250-90s-250 40.295-250 90c0 49.706 115.503 39.032 216.773 154.996z" fill="url(#a)" transform="rotate(24 321.92 -247.724)"/><path d="M302.512 242.909c88.025 32.428 156-25.04 156-55.93 0-30.888-69.844-55.928-156-55.928-86.157 0-156 25.04-156 55.929 0 30.888 67.974 23.5 156 55.929z" fill="url(#b)" transform="rotate(24 338.741 -285.505)"/></g></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

1
docs/img/bg-top.svg Normal file
View File

@ -0,0 +1 @@
<svg width="1440" height="318" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient x1="38.706%" y1="-187.115%" x2="18.675%" y2="110.984%" id="a"><stop stop-color="#FFF" stop-opacity="0" offset="0%"/><stop stop-color="#c3352e" offset="100%"/></linearGradient><linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="c"><stop stop-color="#606483" stop-opacity="0" offset="0%"/><stop stop-color="#0B0D19" stop-opacity=".72" offset="100%"/></linearGradient><linearGradient x1="50%" y1="0%" x2="39.334%" y2="79.282%" id="d"><stop stop-color="#0B0D19" stop-opacity=".32" offset="0%"/><stop stop-color="#0B0D19" stop-opacity="0" offset="100%"/></linearGradient><filter id="b"><feTurbulence type="fractalNoise" numOctaves="2" baseFrequency=".3" result="turb"/><feComposite in="turb" operator="arithmetic" k1=".1" k2=".1" k3=".1" k4=".1" result="result1"/><feComposite operator="in" in="result1" in2="SourceGraphic" result="finalFilter"/><feBlend mode="multiply" in="finalFilter" in2="SourceGraphic"/></filter></defs><g fill="none" fill-rule="evenodd"><path d="M88.494 90c67.04 7.177 161.094-24.753 224.996-90H.2c25.3 48.079 42.361 85.083 88.294 90z" transform="translate(1051)" fill="url(#a)" filter="url(#b)"/><path d="M250.464 367.471c101.27 115.965 283.227-105.29 283.227-154.996 0-49.705-111.929-90-250-90s-250 40.295-250 90c0 49.706 115.503 39.032 216.773 154.996z" fill="url(#c)" transform="rotate(143 810.285 354.367)"/><path d="M373.408 256.178c88.026 32.429 156-25.04 156-55.929 0-30.888-69.843-55.929-156-55.929-86.156 0-156 25.04-156 55.93 0 30.888 67.975 23.5 156 55.928z" fill="url(#d)" transform="rotate(136 905.21 332.676)"/></g></svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

1
docs/img/code.svg Normal file
View File

@ -0,0 +1 @@
<svg width="96" height="48" xmlns="http://www.w3.org/2000/svg"><text y="35" x="48" fill="#fff" stroke-width="0" font-size="36" font-family="Monospace" text-anchor="middle" stroke="#fff">&lt;/&gt;</text></svg>

After

Width:  |  Height:  |  Size: 208 B

1
docs/img/download.svg Normal file
View File

@ -0,0 +1 @@
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" class="style-scope yt-icon" style="width:100%;height:100%" pointer-events="none" display="block" fill="#fff"><g class="style-scope yt-icon"><path d="M25.462 19.105v6.848H4.515v-6.848H.489v8.861c0 1.111.9 2.012 2.016 2.012h24.967c1.115 0 2.016-.9 2.016-2.012v-8.861h-4.026zM14.62 18.426l-5.764-6.965s-.877-.828.074-.828h3.248V9.217.494S12.049 0 12.793 0h4.572c.536 0 .524.416.524.416V10.424h2.998c1.154 0 .285.867.285.867s-4.904 6.51-5.588 7.193c-.492.495-.964-.058-.964-.058z" class="style-scope yt-icon"/></g></svg>

After

Width:  |  Height:  |  Size: 576 B

1
docs/img/footer.svg Normal file
View File

@ -0,0 +1 @@
<svg width="1440" height="582" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="a"><stop stop-color="#606483" stop-opacity="0" offset="0%"/><stop stop-color="#363636" stop-opacity=".72" offset="100%"/></linearGradient><linearGradient x1="50%" y1="0%" x2="39.334%" y2="79.282%" id="b"><stop stop-color="#363636" offset="0%"/><stop stop-color="#363636" stop-opacity="0" offset="100%"/></linearGradient><radialGradient cx="33.3%" cy="43.394%" fx="33.3%" fy="43.394%" r="57.93%" gradientTransform="matrix(.24796 -.96592 .92535 .25883 -.151 .643)" id="c"><stop stop-color="#c3352e" stop-opacity="0" offset="0%"/><stop stop-color="#c3352e" stop-opacity=".64" offset="51.712%"/><stop stop-color="#c3352e" stop-opacity=".24" offset="100%"/></radialGradient><filter id="d"><feTurbulence type="fractalNoise" numOctaves="2" baseFrequency=".3" result="turb"/><feComposite in="turb" operator="arithmetic" k1=".1" k2=".1" k3=".1" k4=".1" result="result1"/><feComposite operator="in" in="result1" in2="SourceGraphic" result="finalFilter"/><feBlend mode="multiply" in="finalFilter" in2="SourceGraphic"/></filter></defs><g fill="none" fill-rule="evenodd"><path d="M252.464 335.471c101.27 115.965 283.227-105.29 283.227-154.996 0-49.705-111.929-90-250-90s-250 40.295-250 90c0 49.706 115.503 39.032 216.773 154.996z" fill="url(#a)" transform="rotate(24 -272.272 -82.087)"/><path d="M302.512 242.909c88.025 32.428 156-25.04 156-55.93 0-30.888-69.844-55.928-156-55.928-86.157 0-156 25.04-156 55.929 0 30.888 67.974 23.5 156 55.929z" fill="url(#b)" transform="rotate(24 -255.451 -119.868)"/><path d="M103.064 315.218c128.156 12.998 192.38 157.059 218.627 106.632 26.247-50.427-44.059-106.456 60.397-202.707 104.457-96.252-143.2-285.785-172.392-122.551C180.503 259.825-25.091 302.22 103.064 315.218z" transform="translate(1176 -33)" fill="url(#c)" filter="url(#d)"/></g></svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

1
docs/img/plugins.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 60 60" fill="#fff"><path d="M45.563 29.174l-22-15A1 1 0 0022 15v30a.999.999 0 001.563.826l22-15a1 1 0 000-1.652zM24 43.107V16.893L43.225 30 24 43.107z"/><path d="M30 0C13.458 0 0 13.458 0 30s13.458 30 30 30 30-13.458 30-30S46.542 0 30 0zm0 58C14.561 58 2 45.439 2 30S14.561 2 30 2s28 12.561 28 28-12.561 28-28 28z"/></svg>

After

Width:  |  Height:  |  Size: 375 B

BIN
docs/img/youtube-music.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 227 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 176 176" width="32" height="32"><circle fill="red" cx="88" cy="88" r="88"/><path fill="#FFF" d="M88 46c23.1 0 42 18.8 42 42s-18.8 42-42 42-42-18.8-42-42 18.9-42 42-42m0-4c-25.4 0-46 20.6-46 46s20.6 46 46 46 46-20.6 46-46-20.6-46-46-46z"/><path fill="#FFF" d="M72 111l39-24-39-22z"/></svg>

After

Width:  |  Height:  |  Size: 341 B

490
docs/index.html Normal file
View File

@ -0,0 +1,490 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>YouTube Music Desktop App (Unofficial)</title>
<link
rel="icon"
href="./favicon/favicon.ico"
sizes="16x16"
type="image/x-icon"
/>
<link
rel="icon"
href="./favicon/favicon_32.png"
sizes="32x32"
type="image/png"
/>
<link
rel="icon"
href="./favicon/favicon_48.png"
sizes="48x48"
type="image/png"
/>
<link
rel="icon"
href="./favicon/favicon_96.png"
sizes="96x96"
type="image/png"
/>
<link
rel="icon"
href="./favicon/favicon_144.png"
sizes="144x144"
type="image/png"
/>
<meta name="theme-color" content="#131313" />
<meta
name="description"
content="YouTube Music Unofficial Desktop App with built-in ad blocker and downloader"
/>
<meta
property="og:site_name"
content="YouTube&nbsp;Music&nbsp;Desktop&nbsp;App"
/>
<meta
property="og:url"
class="meta-url"
content="https://th-ch.github.io/youtube-music"
/>
<meta property="og:type" content="website" />
<meta
name="twitter:url"
class="meta-url"
content="https://th-ch.github.io/youtube-music"
/>
<link href="./style/fonts.css" rel="stylesheet" />
<link rel="stylesheet" href="./style/style.css" />
<script src="https://unpkg.com/scrollreveal"></script>
</head>
<body class="has-animations vsc-initialized" style="height: 100%;">
<div class="body-wrap boxed-container">
<header class="site-header text-light">
<div class="container">
<div class="site-header-inner">
<div class="brand header-brand">
<h1 class="m-0">
<a href="https://github.com/th-ch/youtube-music">
<img
class="header-logo-image"
src="./img/youtube-music.svg"
alt="YouTube Music"
/>
</a>
</h1>
</div>
</div>
</div>
</header>
<main>
<section class="hero text-center text-light">
<div class="hero-bg"></div>
<div class="hero-particles-container">
<canvas id="hero-particles"></canvas>
</div>
<div class="container-sm">
<div class="hero-inner">
<div class="hero-copy">
<h1 class="hero-title mt-0">
Custom YouTube Music Desktop App
</h1>
<p class="hero-paragraph">
Open source, cross-platform, unofficial YouTube Music Desktop
App with built-in <strong>ad blocker</strong> and
<strong>downloader</strong>
</p>
<div class="hero-cta">
<a
class="button button-primary button-wide-mobile"
href="https://github.com/th-ch/youtube-music/releases/latest"
>Download</a
>
</div>
</div>
<div class="mockup-container">
<div class="mockup-bg">
<img
src="./img/youtube-music.png"
id="mockup-header-img"
alt="YouTube Music"
/>
</div>
</div>
</div>
</div>
</section>
<section class="features-extended section">
<div class="features-extended-inner section-inner">
<div class="features-extended-wrap">
<div class="container">
<div class="feature-extended">
<div class="feature-extended-image">
<img
class="device-mockup"
src="./img/adblock.svg"
width="100px"
alt="Adblocker"
data-sr-id="0"
style="
visibility: visible;
opacity: 1;
transform: matrix3d(
1,
0,
0,
0,
0,
1,
0,
0,
0,
0,
1,
0,
0,
0,
0,
1
);
transition: opacity 0.6s
cubic-bezier(0.215, 0.61, 0.355, 1) 0s,
transform 0.6s cubic-bezier(0.215, 0.61, 0.355, 1) 0s;
"
/>
</div>
<div
class="feature-extended-body"
data-sr-id="5"
style="
visibility: visible;
opacity: 1;
transform: matrix3d(
1,
0,
0,
0,
0,
1,
0,
0,
0,
0,
1,
0,
0,
0,
0,
1
);
transition: opacity 0.6s
cubic-bezier(0.215, 0.61, 0.355, 1) 0s,
transform 0.6s cubic-bezier(0.215, 0.61, 0.355, 1) 0s;
"
>
<h3 class="mt-0 mb-16">Built-in adblocker</h3>
<p class="m-0">Block all ads and tracking out of the box</p>
</div>
</div>
<div class="feature-extended">
<div class="feature-extended-image">
<img
class="device-mockup"
src="./img/download.svg"
alt="Downloader"
data-sr-id="2"
style="
visibility: visible;
opacity: 1;
transform: matrix3d(
1,
0,
0,
0,
0,
1,
0,
0,
0,
0,
1,
0,
0,
0,
0,
1
);
transition: opacity 0.6s
cubic-bezier(0.215, 0.61, 0.355, 1) 0s,
transform 0.6s cubic-bezier(0.215, 0.61, 0.355, 1) 0s;
"
/>
</div>
<div
class="feature-extended-body"
data-sr-id="6"
style="
visibility: visible;
opacity: 1;
transform: matrix3d(
1,
0,
0,
0,
0,
1,
0,
0,
0,
0,
1,
0,
0,
0,
0,
1
);
transition: opacity 0.6s
cubic-bezier(0.215, 0.61, 0.355, 1) 0s,
transform 0.6s cubic-bezier(0.215, 0.61, 0.355, 1) 0s;
"
>
<h3 class="mt-0 mb-16">Built-in downloader</h3>
<p class="m-0">
Download (like youtube-dl) to custom formats (mp3, opus,
etc) directly from the interface
</p>
</div>
</div>
<div class="feature-extended">
<div class="feature-extended-image">
<img
class="device-mockup"
src="./img/plugins.svg"
alt="Plugins"
data-sr-id="3"
style="
visibility: visible;
opacity: 1;
transform: matrix3d(
1,
0,
0,
0,
0,
1,
0,
0,
0,
0,
1,
0,
0,
0,
0,
1
);
transition: opacity 0.6s
cubic-bezier(0.215, 0.61, 0.355, 1) 0s,
transform 0.6s cubic-bezier(0.215, 0.61, 0.355, 1) 0s;
"
/>
</div>
<div
class="feature-extended-body"
data-sr-id="7"
style="
visibility: visible;
opacity: 1;
transform: matrix3d(
1,
0,
0,
0,
0,
1,
0,
0,
0,
0,
1,
0,
0,
0,
0,
1
);
transition: opacity 0.6s
cubic-bezier(0.215, 0.61, 0.355, 1) 0s,
transform 0.6s cubic-bezier(0.215, 0.61, 0.355, 1) 0s;
"
>
<h3 class="mt-0 mb-16">Many other plugins in one click</h3>
<p class="m-0">
Enhance your user experience with media keys, integrations
(Discord), cosmetic filters, notifications, TouchBar,
auto-unpause and many more! Every plugin can be enabled or
disabled in one click.
</p>
</div>
</div>
<div class="feature-extended">
<div class="feature-extended-image">
<img
class="device-mockup"
src="./img/code.svg"
alt="Code"
data-sr-id="4"
style="
visibility: visible;
width: 200%;
opacity: 1;
transform: matrix3d(
1,
0,
0,
0,
0,
1,
0,
0,
0,
0,
1,
0,
0,
0,
0,
1
);
transition: opacity 0.6s
cubic-bezier(0.215, 0.61, 0.355, 1) 0s,
transform 0.6s cubic-bezier(0.215, 0.61, 0.355, 1) 0s;
"
/>
</div>
<div
class="feature-extended-body"
data-sr-id="8"
style="
visibility: visible;
opacity: 1;
transform: matrix3d(
1,
0,
0,
0,
0,
1,
0,
0,
0,
0,
1,
0,
0,
0,
0,
1
);
transition: opacity 0.6s
cubic-bezier(0.215, 0.61, 0.355, 1) 0s,
transform 0.6s cubic-bezier(0.215, 0.61, 0.355, 1) 0s;
"
>
<h3 class="mt-0 mb-16">Open source & Cross platform</h3>
<p class="m-0">
Available for Windows (installer and portable), Mac and
Linux (AppImage, deb, etc)
</p>
</div>
</div>
</div>
</div>
</div>
<div class="main-particles-container">
<canvas id="main-particles"></canvas>
</div>
</section>
</main>
<footer class="site-footer">
<div class="footer-particles-container">
<canvas id="footer-particles"></canvas>
</div>
<div class="site-footer-top">
<section class="cta section text-light">
<div class="container-sm">
<div class="cta-inner section-inner">
<div class="cta-header text-center">
<h2 class="section-title mt-0">Download and/or contribute</h2>
<p class="section-paragraph">Pull requests welcome!</p>
<div class="cta-cta">
<a
class="button button-primary button-wide-mobile"
href="https://github.com/th-ch/youtube-music"
>Go to code</a
>
</div>
</div>
</div>
</div>
</section>
</div>
<div class="site-footer-bottom">
<div class="container">
<div class="site-footer-inner">
<div class="brand footer-brand">
<a href="https://github.com/th-ch/youtube-music">
<img src="./img/youtube-music.svg" alt="YouTube Music logo" />
</a>
</div>
<ul class="footer-links list-reset">
<li>
<a href="https://github.com/th-ch/youtube-music">Main page</a>
</li>
<li>
<a href="https://github.com/th-ch/youtube-music/issues"
>Issues</a
>
</li>
<li>
<a href="https://github.com/th-ch/youtube-music/pulls"
>Pull requests</a
>
</li>
</ul>
<ul class="footer-social-links list-reset">
<li>
<a href="https://github.com/th-ch/youtube-music">
<span class="screen-reader-text">GitHub</span>
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
viewBox="0 0 1792 1792"
>
<path
d="M896 128q209 0 385.5 103t279.5 279.5 103 385.5q0 251-146.5 451.5t-378.5 277.5q-27 5-40-7t-13-30q0-3 .5-76.5t.5-134.5q0-97-52-142 57-6 102.5-18t94-39 81-66.5 53-105 20.5-150.5q0-119-79-206 37-91-8-204-28-9-81 11t-92 44l-38 24q-93-26-192-26t-192 26q-16-11-42.5-27t-83.5-38.5-85-13.5q-45 113-8 204-79 87-79 206 0 85 20.5 150t52.5 105 80.5 67 94 39 102.5 18q-39 36-49 103-21 10-45 15t-57 5-65.5-21.5-55.5-62.5q-19-32-48.5-52t-49.5-24l-20-3q-21 0-29 4.5t-5 11.5 9 14 13 12l7 5q22 10 43.5 38t31.5 51l10 23q13 38 44 61.5t67 30 69.5 7 55.5-3.5l23-4q0 38 .5 88.5t.5 54.5q0 18-13 30t-40 7q-232-77-378.5-277.5t-146.5-451.5q0-209 103-385.5t279.5-279.5 385.5-103zm-477 1103q3-7-7-12-10-3-13 2-3 7 7 12 9 6 13-2zm31 34q7-5-2-16-10-9-16-3-7 5 2 16 10 10 16 3zm30 45q9-7 0-19-8-13-17-6-9 5 0 18t17 7zm42 42q8-8-4-19-12-12-20-3-9 8 4 19 12 12 20 3zm57 25q3-11-13-16-15-4-19 7t13 15q15 6 19-6zm63 5q0-13-17-11-16 0-16 11 0 13 17 11 16 0 16-11zm58-10q-2-11-18-9-16 3-14 15t18 8 14-14z"
fill="#fff"
/>
</svg>
</a>
</li>
</ul>
<div class="footer-copyright">© 2021 th-ch</div>
</div>
</div>
</div>
</footer>
</div>
<script src="./js/main.js"></script>
</body>
</html>

262
docs/js/main.js Normal file
View File

@ -0,0 +1,262 @@
// Constants
const element = document.documentElement,
body = document.body,
revealOnScroll = (window.sr = ScrollReveal({ mobile: false }));
// Load animations
element.classList.remove("no-js");
element.classList.add("js");
window.addEventListener("load", function () {
body.classList.add("is-loaded");
});
if (body.classList.contains("has-animations")) {
window.addEventListener("load", function () {
revealOnScroll.reveal(".feature-extended .device-mockup", {
duration: 600,
distance: "100px",
easing: "cubic-bezier(0.215, 0.61, 0.355, 1)",
origin: "bottom",
viewFactor: 0.6,
});
revealOnScroll.reveal(".feature-extended .feature-extended-body", {
duration: 600,
distance: "40px",
easing: "cubic-bezier(0.215, 0.61, 0.355, 1)",
origin: "top",
viewFactor: 0.6,
});
});
}
// Bubble canvas
let bubbleCanvas = function (t) {
let e = this;
e.parentNode = t;
e.setCanvasSize();
window.addEventListener("resize", function () {
e.setCanvasSize();
});
e.mouseX = 0;
e.mouseY = 0;
window.addEventListener("mousemove", function (t) {
(e.mouseX = t.clientX), (e.mouseY = t.clientY);
});
e.randomise();
};
bubbleCanvas.prototype.setCanvasSize = function () {
this.canvasWidth = this.parentNode.clientWidth;
this.canvasHeight = this.parentNode.clientHeight;
};
bubbleCanvas.prototype.generateDecimalBetween = function (start, end) {
return (Math.random() * (start - end) + end).toFixed(2);
};
bubbleCanvas.prototype.update = function () {
let t = this;
t.translateX = t.translateX - t.movementX;
t.translateY = t.translateY - t.movementY;
t.posX += (t.mouseX / (t.staticity / t.magnetism) - t.posX) / t.smoothFactor;
t.posY += (t.mouseY / (t.staticity / t.magnetism) - t.posY) / t.smoothFactor;
if (
t.translateY + t.posY < 0 ||
t.translateX + t.posX < 0 ||
t.translateX + t.posX > t.canvasWidth
) {
t.randomise();
t.translateY = t.canvasHeight;
}
};
bubbleCanvas.prototype.randomise = function () {
this.colors = ["195,53,46", "172,54,46"];
this.velocity = 20;
this.smoothFactor = 50;
this.staticity = 30;
this.magnetism = 0.1 + 4 * Math.random();
this.color = this.colors[Math.floor(Math.random() * this.colors.length)];
this.alpha = this.generateDecimalBetween(5, 10) / 10;
this.size = this.generateDecimalBetween(1, 4);
this.posX = 0;
this.posY = 0;
this.movementX = this.generateDecimalBetween(-2, 2) / this.velocity;
this.movementY = this.generateDecimalBetween(1, 20) / this.velocity;
this.translateX = this.generateDecimalBetween(0, this.canvasWidth);
this.translateY = this.generateDecimalBetween(0, this.canvasHeight);
};
let drawBubbleCanvas = function (t) {
this.canvas = document.getElementById(t);
this.ctx = this.canvas.getContext("2d");
this.dpr = window.devicePixelRatio;
};
drawBubbleCanvas.prototype.start = function (bubbleDensity) {
let t = this;
t.bubbleDensity = bubbleDensity;
t.setCanvasSize();
window.addEventListener("resize", function () {
t.setCanvasSize();
});
t.bubblesList = [];
t.generateBubbles();
t.animate();
};
drawBubbleCanvas.prototype.setCanvasSize = function () {
this.container = this.canvas.parentNode;
this.w = this.container.offsetWidth;
this.h = this.container.offsetHeight;
this.wdpi = this.w * this.dpr;
this.hdpi = this.h * this.dpr;
this.canvas.width = this.wdpi;
this.canvas.height = this.hdpi;
this.canvas.style.width = this.w + "px";
this.canvas.style.height = this.h + "px";
this.ctx.scale(this.dpr, this.dpr);
};
drawBubbleCanvas.prototype.animate = function () {
let t = this;
t.ctx.clearRect(0, 0, t.canvas.clientWidth, t.canvas.clientHeight);
t.bubblesList.forEach(function (e) {
e.update();
t.ctx.translate(e.translateX, e.translateY);
t.ctx.beginPath();
t.ctx.arc(e.posX, e.posY, e.size, 0, 2 * Math.PI);
t.ctx.fillStyle = "rgba(" + e.color + "," + e.alpha + ")";
t.ctx.fill();
t.ctx.setTransform(t.dpr, 0, 0, t.dpr, 0, 0);
});
requestAnimationFrame(this.animate.bind(this));
};
drawBubbleCanvas.prototype.addBubble = function (t) {
return this.bubblesList.push(t);
};
drawBubbleCanvas.prototype.generateBubbles = function () {
let t = this;
for (let e = 0; e < t.bubbleDensity; e++)
t.addBubble(new bubbleCanvas(t.canvas.parentNode));
};
// Night sky with stars canvas
let starCanvas = function (t) {
this.canvas = document.getElementById(t);
this.ctx = this.canvas.getContext("2d");
this.dpr = window.devicePixelRatio;
};
starCanvas.prototype.start = function () {
let w;
let h;
const setCanvasExtents = () => {
w = this.canvas.parentNode.clientWidth;
h = this.canvas.parentNode.clientHeight;
this.canvas.width = w;
this.canvas.height = h;
};
setCanvasExtents();
window.onresize = () => {
setCanvasExtents();
};
const makeStars = (count) => {
const out = [];
for (let i = 0; i < count; i++) {
const s = {
x: Math.random() * w - w / 2,
y: Math.random() * h - h / 2,
z: Math.random() * 1000,
};
out.push(s);
}
return out;
};
let stars = makeStars(10000);
const clear = () => {
this.ctx.fillStyle = "#212121";
this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
};
const putPixel = (x, y, brightness) => {
const intensity = brightness * 255;
const rgb = "rgb(" + intensity + "," + intensity + "," + intensity + ")";
this.ctx.beginPath();
this.ctx.arc(x, y, 0.9, 0, 2 * Math.PI);
this.ctx.fillStyle = rgb;
this.ctx.fill();
};
const moveStars = (distance) => {
const count = stars.length;
for (var i = 0; i < count; i++) {
const s = stars[i];
s.z -= distance;
while (s.z <= 1) {
s.z += 1000;
}
}
};
let prevTime;
const init = (time) => {
prevTime = time;
requestAnimationFrame(tick);
};
const tick = (time) => {
let elapsed = time - prevTime;
prevTime = time;
moveStars(elapsed * 0.1);
clear();
const cx = w / 2;
const cy = h / 2;
const count = stars.length;
for (var i = 0; i < count; i++) {
const star = stars[i];
const x = cx + star.x / (star.z * 0.001);
const y = cy + star.y / (star.z * 0.001);
if (x < 0 || x >= w || y < 0 || y >= h) {
continue;
}
const d = star.z / 1000.0;
const b = 1 - d * d;
putPixel(x, y, b);
}
requestAnimationFrame(tick);
};
requestAnimationFrame(init);
};
// Start canvas animations
window.addEventListener("load", function () {
// Stars
const headCanvas = new starCanvas("hero-particles");
// Bubbles
const footerCanvas = new drawBubbleCanvas("footer-particles");
const mainCanvas = new drawBubbleCanvas("main-particles");
headCanvas.start();
footerCanvas.start(30);
mainCanvas.start(200);
});

48
docs/style/fonts.css Normal file
View File

@ -0,0 +1,48 @@
/* hebrew */
@font-face {
font-family: 'Heebo';
font-style: normal;
font-weight: 400;
src: url(https://fonts.gstatic.com/s/heebo/v9/NGS6v5_NC0k9P9H0TbFhsqMA6aw.woff2) format('woff2');
unicode-range: U+0590-05FF, U+20AA, U+25CC, U+FB1D-FB4F;
}
/* latin */
@font-face {
font-family: 'Heebo';
font-style: normal;
font-weight: 400;
src: url(https://fonts.gstatic.com/s/heebo/v9/NGS6v5_NC0k9P9H2TbFhsqMA.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* hebrew */
@font-face {
font-family: 'Heebo';
font-style: normal;
font-weight: 700;
src: url(https://fonts.gstatic.com/s/heebo/v9/NGS6v5_NC0k9P9H0TbFhsqMA6aw.woff2) format('woff2');
unicode-range: U+0590-05FF, U+20AA, U+25CC, U+FB1D-FB4F;
}
/* latin */
@font-face {
font-family: 'Heebo';
font-style: normal;
font-weight: 700;
src: url(https://fonts.gstatic.com/s/heebo/v9/NGS6v5_NC0k9P9H2TbFhsqMA.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
font-family: 'Oxygen';
font-style: normal;
font-weight: 700;
src: url(https://fonts.gstatic.com/s/oxygen/v10/2sDcZG1Wl4LcnbuCNWgzZmW5Kb8VZBHR.woff2) format('woff2');
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Oxygen';
font-style: normal;
font-weight: 700;
src: url(https://fonts.gstatic.com/s/oxygen/v10/2sDcZG1Wl4LcnbuCNWgzaGW5Kb8VZA.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

1561
docs/style/style.css Normal file

File diff suppressed because it is too large Load Diff

381
index.js
View File

@ -2,7 +2,9 @@
const path = require("path");
const electron = require("electron");
const enhanceWebRequest = require("electron-better-web-request").default;
const is = require("electron-is");
const unhandled = require("electron-unhandled");
const { autoUpdater } = require("electron-updater");
const config = require("./config");
@ -10,13 +12,41 @@ const { setApplicationMenu } = require("./menu");
const { fileExists, injectCSS } = require("./plugins/utils");
const { isTesting } = require("./utils/testing");
const { setUpTray } = require("./tray");
const { setupSongInfo } = require("./providers/song-info");
const { setupAppControls, restart } = require("./providers/app-controls");
// Catch errors and log them
unhandled({
logger: console.error,
showDialog: false,
});
// Disable Node options if the env var is set
process.env.NODE_OPTIONS = "";
const app = electron.app;
// Prevent window being garbage collected
let mainWindow;
autoUpdater.autoDownload = false;
if(config.get("options.singleInstanceLock")){
const gotTheLock = app.requestSingleInstanceLock();
if (!gotTheLock) app.quit();
app.on('second-instance', () => {
if (!mainWindow) return;
if (mainWindow.isMinimized()) mainWindow.restore();
if (!mainWindow.isVisible()) mainWindow.show();
mainWindow.focus();
});
}
app.commandLine.appendSwitch(
"js-flags",
// WebAssembly flags
"--experimental-wasm-threads --experimental-wasm-bulk-memory"
"--experimental-wasm-threads"
);
app.commandLine.appendSwitch("enable-features", "SharedArrayBuffer"); // Required for downloader
app.allowRendererProcessReuse = true; // https://github.com/electron/electron/issues/18397
if (config.get("options.disableHardwareAcceleration")) {
if (is.dev()) {
@ -25,12 +55,19 @@ if (config.get("options.disableHardwareAcceleration")) {
app.disableHardwareAcceleration();
}
// Adds debug features like hotkeys for triggering dev tools and reload
require("electron-debug")();
if (is.linux() && config.plugins.isEnabled("shortcuts")) {
//stops chromium from launching it's own mpris service
app.commandLine.appendSwitch('disable-features', 'MediaSessionService');
}
// Prevent window being garbage collected
let mainWindow;
autoUpdater.autoDownload = false;
if (config.get("options.proxy")) {
app.commandLine.appendSwitch("proxy-server", config.get("options.proxy"));
}
// Adds debug features like hotkeys for triggering dev tools and reload
require("electron-debug")({
showDevTools: false //disable automatic devTools on new window
});
let icon = "assets/youtube-music.png";
if (process.platform == "win32") {
@ -47,7 +84,23 @@ function onClosed() {
function loadPlugins(win) {
injectCSS(win.webContents, path.join(__dirname, "youtube-music.css"));
win.webContents.on("did-finish-load", () => {
// Load user CSS
const themes = config.get("options.themes");
if (Array.isArray(themes)) {
themes.forEach((cssFile) => {
fileExists(
cssFile,
() => {
injectCSS(win.webContents, cssFile);
},
() => {
console.warn(`CSS file "${cssFile}" does not exist, ignoring`);
}
);
});
}
win.webContents.once("did-finish-load", () => {
if (is.dev()) {
console.log("did finish load");
win.webContents.openDevTools();
@ -67,6 +120,8 @@ function loadPlugins(win) {
function createMainWindow() {
const windowSize = config.get("window-size");
const windowMaximized = config.get("window-maximized");
const windowPosition = config.get("window-position");
const useInlineMenu = config.plugins.isEnabled("in-app-menu");
const win = new electron.BrowserWindow({
icon: icon,
@ -75,86 +130,194 @@ function createMainWindow() {
backgroundColor: "#000",
show: false,
webPreferences: {
nodeIntegration: isTesting(), // Only necessary when testing with Spectron
// TODO: re-enable contextIsolation once it can work with ffmepg.wasm
// Possible bundling? https://github.com/ffmpegwasm/ffmpeg.wasm/issues/126
contextIsolation: false,
preload: path.join(__dirname, "preload.js"),
nodeIntegrationInSubFrames: true,
nativeWindowOpen: true, // window.open return Window object(like in regular browsers), not BrowserWindowProxy
enableRemoteModule: true,
affinity: "main-window", // main window, and addition windows should work in one process
...(!isTesting()
? {
// Sandbox is only enabled in tests for now
// See https://www.electronjs.org/docs/latest/tutorial/sandbox#preload-scripts
sandbox: false,
}
: undefined),
},
frame: !is.macOS(),
titleBarStyle: is.macOS() ? "hiddenInset" : "default",
frame: !is.macOS() && !useInlineMenu,
titleBarStyle: useInlineMenu
? "hidden"
: is.macOS()
? "hiddenInset"
: "default",
autoHideMenuBar: config.get("options.hideMenu"),
});
if (windowPosition) {
const { x, y } = windowPosition;
const winSize = win.getSize();
const displaySize =
electron.screen.getDisplayNearestPoint(windowPosition).bounds;
if (
x + winSize[0] < displaySize.x - 8 ||
x - winSize[0] > displaySize.x + displaySize.width ||
y < displaySize.y - 8 ||
y > displaySize.y + displaySize.height
) {
//Window is offscreen
if (is.dev()) {
console.log(
`Window tried to render offscreen, windowSize=${winSize}, displaySize=${displaySize}, position=${windowPosition}`
);
}
} else {
win.setPosition(x, y);
}
}
if (windowMaximized) {
win.maximize();
}
win.webContents.loadURL(config.get("url"));
if(config.get("options.alwaysOnTop")){
win.setAlwaysOnTop(true);
}
const urlToLoad = config.get("options.resumeOnStart")
? config.get("url")
: config.defaultConfig.url;
win.webContents.loadURL(urlToLoad);
win.on("closed", onClosed);
const setPiPOptions = config.plugins.isEnabled("picture-in-picture")
? (key, value) => require("./plugins/picture-in-picture/back").setOptions({ [key]: value })
: () => {};
win.on("move", () => {
if (win.isMaximized()) return;
let position = win.getPosition();
config.set("window-position", { x: position[0], y: position[1] });
const isPiPEnabled =
config.plugins.isEnabled("picture-in-picture") &&
config.plugins.getOptions("picture-in-picture")["isInPiP"];
if (!isPiPEnabled) {
lateSave("window-position", { x: position[0], y: position[1] });
} else if(config.plugins.getOptions("picture-in-picture")["savePosition"]) {
lateSave("pip-position", position, setPiPOptions);
}
});
let winWasMaximized;
win.on("resize", () => {
const windowSize = win.getSize();
const isMaximized = win.isMaximized();
config.set("window-maximized", win.isMaximized());
if (!win.isMaximized()) {
config.set("window-size", {
const isPiPEnabled =
config.plugins.isEnabled("picture-in-picture") &&
config.plugins.getOptions("picture-in-picture")["isInPiP"];
if (!isPiPEnabled && winWasMaximized !== isMaximized) {
winWasMaximized = isMaximized;
config.set("window-maximized", isMaximized);
}
if (isMaximized) return;
if (!isPiPEnabled) {
lateSave("window-size", {
width: windowSize[0],
height: windowSize[1],
});
} else if(config.plugins.getOptions("picture-in-picture")["saveSize"]) {
lateSave("pip-size", windowSize, setPiPOptions);
}
});
let savedTimeouts = {};
function lateSave(key, value, fn = config.set) {
if (savedTimeouts[key]) clearTimeout(savedTimeouts[key]);
savedTimeouts[key] = setTimeout(() => {
fn(key, value);
savedTimeouts[key] = undefined;
}, 600);
}
win.webContents.on("render-process-gone", (event, webContents, details) => {
showUnresponsiveDialog(win, details);
});
win.once("ready-to-show", () => {
if (config.get("options.appVisible")) {
win.show();
}
});
removeContentSecurityPolicy();
return win;
}
app.on("browser-window-created", (event, win) => {
loadPlugins(win);
win.webContents.on("did-fail-load", () => {
if (is.dev()) {
console.log("did fail load");
app.once("browser-window-created", (event, win) => {
if (config.get("options.overrideUserAgent")) {
// User agents are from https://developers.whatismybrowser.com/useragents/explore/
const originalUserAgent = win.webContents.userAgent;
const userAgents = {
mac: "Mozilla/5.0 (Macintosh; Intel Mac OS X 12.1; rv:95.0) Gecko/20100101 Firefox/95.0",
windows: "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0",
linux: "Mozilla/5.0 (Linux x86_64; rv:95.0) Gecko/20100101 Firefox/95.0",
}
const updatedUserAgent =
is.macOS() ? userAgents.mac :
is.windows() ? userAgents.windows :
userAgents.linux;
win.webContents.userAgent = updatedUserAgent;
app.userAgentFallback = updatedUserAgent;
win.webContents.session.webRequest.onBeforeSendHeaders((details, cb) => {
// this will only happen if login failed, and "retry" was pressed
if (win.webContents.getURL().startsWith("https://accounts.google.com") && details.url.startsWith("https://accounts.google.com")) {
details.requestHeaders["User-Agent"] = originalUserAgent;
}
cb({ requestHeaders: details.requestHeaders });
});
}
setupSongInfo(win);
loadPlugins(win);
setupAppControls();
win.webContents.on("did-fail-load", (
_event,
errorCode,
errorDescription,
validatedURL,
isMainFrame,
frameProcessId,
frameRoutingId,
) => {
const log = JSON.stringify({
error: "did-fail-load",
errorCode,
errorDescription,
validatedURL,
isMainFrame,
frameProcessId,
frameRoutingId,
}, null, "\t");
if (is.dev()) {
console.log(log);
}
if( !(config.plugins.isEnabled("in-app-menu") && errorCode === -3)) { // -3 is a false positive with in-app-menu
win.webContents.send("log", log);
win.webContents.loadFile(path.join(__dirname, "error.html"));
}
win.webContents.loadFile(path.join(__dirname, "error.html"));
});
win.webContents.on("will-prevent-unload", (event) => {
event.preventDefault();
});
win.webContents.on("did-navigate-in-page", () => {
const url = win.webContents.getURL();
if (url.startsWith("https://music.youtube.com")) {
config.set("url", url);
}
});
win.webContents.on("will-navigate", (_, url) => {
if (url.startsWith("https://accounts.google.com")) {
// Force user-agent "Firefox Windows" for Google OAuth to work
// From https://github.com/firebase/firebase-js-sdk/issues/2478#issuecomment-571356751
// Only set on accounts.google.com, otherwise querySelectors in preload scripts fail (?)
const userAgent =
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:70.0) Gecko/20100101 Firefox/70.0";
win.webContents.session.webRequest.onBeforeSendHeaders((details, cb) => {
details.requestHeaders["User-Agent"] = userAgent;
cb({ requestHeaders: details.requestHeaders });
});
}
});
win.webContents.on(
"new-window",
(e, url, frameName, disposition, options) => {
@ -187,14 +350,48 @@ app.on("activate", () => {
});
app.on("ready", () => {
if (config.get("options.autoResetAppCache")) {
// Clear cache after 20s
const clearCacheTimeout = setTimeout(() => {
if (is.dev()) {
console.log("Clearing app cache.");
}
electron.session.defaultSession.clearCache();
clearTimeout(clearCacheTimeout);
}, 20000);
}
// Register appID on windows
if (is.windows()) {
const appID = "com.github.th-ch.youtube-music";
app.setAppUserModelId(appID);
const appLocation = process.execPath;
const appData = app.getPath("appData");
// check shortcut validity if not in dev mode / running portable app
if (!is.dev() && !appLocation.startsWith(path.join(appData, "..", "Local", "Temp"))) {
const shortcutPath = path.join(appData, "Microsoft", "Windows", "Start Menu", "Programs", "YouTube Music.lnk");
try { // check if shortcut is registered and valid
const shortcutDetails = electron.shell.readShortcutLink(shortcutPath); // throw error if doesn't exist yet
if (shortcutDetails.target !== appLocation || shortcutDetails.appUserModelId !== appID) {
throw "needUpdate";
}
} catch (error) { // if not valid -> Register shortcut
electron.shell.writeShortcutLink(
shortcutPath,
error === "needUpdate" ? "update" : "create",
{
target: appLocation,
cwd: appLocation.slice(0, appLocation.lastIndexOf(path.sep)),
description: "YouTube Music Desktop App - including custom plugins",
appUserModelId: appID
}
);
}
}
}
mainWindow = createMainWindow();
setApplicationMenu(mainWindow);
if (config.get("options.restartOnConfigChanges")) {
config.watch(() => {
app.relaunch();
app.exit();
});
}
setUpTray(app, mainWindow);
// Autostart at login
@ -203,7 +400,10 @@ app.on("ready", () => {
});
if (!is.dev() && config.get("options.autoUpdates")) {
autoUpdater.checkForUpdatesAndNotify();
const updateTimeout = setTimeout(() => {
autoUpdater.checkForUpdatesAndNotify();
clearTimeout(updateTimeout);
}, 2000);
autoUpdater.on("update-available", () => {
const downloadLink =
"https://github.com/th-ch/youtube-music/releases/latest";
@ -231,14 +431,20 @@ app.on("ready", () => {
});
}
// Optimized for Mac OS X
if (is.macOS()) {
if (!config.get("options.appVisible")) {
app.dock.hide();
}
if (config.get("options.hideMenu") && !config.get("options.hideMenuWarned")) {
electron.dialog.showMessageBox(mainWindow, {
type: 'info', title: 'Hide Menu Enabled',
message: "Menu is hidden, use 'Alt' to show it (or 'Escape' if using in-app-menu)"
});
config.set("options.hideMenuWarned", true);
}
var forceQuit = false;
// Optimized for Mac OS X
if (is.macOS() && !config.get("options.appVisible")) {
app.dock.hide();
}
let forceQuit = false;
app.on("before-quit", () => {
forceQuit = true;
});
@ -253,3 +459,60 @@ app.on("ready", () => {
});
}
});
function showUnresponsiveDialog(win, details) {
if (!!details) {
console.log("Unresponsive Error!\n"+JSON.stringify(details, null, "\t"))
}
electron.dialog.showMessageBox(win, {
type: "error",
title: "Window Unresponsive",
message: "The Application is Unresponsive",
details: "We are sorry for the inconvenience! please choose what to do:",
buttons: ["Wait", "Relaunch", "Quit"],
cancelId: 0
}).then( result => {
switch (result.response) {
case 1: restart(); break;
case 2: app.quit(); break;
}
});
}
function removeContentSecurityPolicy(
session = electron.session.defaultSession
) {
// Allows defining multiple "onHeadersReceived" listeners
// by enhancing the session.
// Some plugins (e.g. adblocker) also define a "onHeadersReceived" listener
enhanceWebRequest(session);
// Custom listener to tweak the content security policy
session.webRequest.onHeadersReceived(function (details, callback) {
if (
!details.responseHeaders["content-security-policy-report-only"] &&
!details.responseHeaders["content-security-policy"]
)
return callback({ cancel: false });
delete details.responseHeaders["content-security-policy-report-only"];
delete details.responseHeaders["content-security-policy"];
callback({ cancel: false, responseHeaders: details.responseHeaders });
});
// When multiple listeners are defined, apply them all
session.webRequest.setResolver("onHeadersReceived", (listeners) => {
const response = listeners.reduce(
async (accumulator, listener) => {
if (accumulator.cancel) {
return accumulator;
}
const result = await listener.apply();
return { ...accumulator, ...result };
},
{ cancel: false }
);
return response;
});
}

View File

@ -2,6 +2,5 @@ module.exports = {
globals: {
__APP__: undefined, // A different app will be launched in each test environment
},
testEnvironment: "./tests/environment",
testTimeout: 30000, // 30s
};

445
menu.js
View File

@ -1,146 +1,343 @@
const { app, Menu } = require("electron");
const { existsSync } = require("fs");
const path = require("path");
const { app, Menu, dialog } = require("electron");
const is = require("electron-is");
const { restart } = require("./providers/app-controls");
const { getAllPlugins } = require("./plugins/utils");
const config = require("./config");
const mainMenuTemplate = (win) => [
{
label: "Plugins",
submenu: [
...getAllPlugins().map((plugin) => {
return {
label: plugin,
const prompt = require("custom-electron-prompt");
const promptOptions = require("./providers/prompt-options");
// true only if in-app-menu was loaded on launch
const inAppMenuActive = config.plugins.isEnabled("in-app-menu");
const pluginEnabledMenu = (plugin, label = "", hasSubmenu = false, refreshMenu = undefined) => ({
label: label || plugin,
type: "checkbox",
checked: config.plugins.isEnabled(plugin),
click: (item) => {
if (item.checked) {
config.plugins.enable(plugin);
} else {
config.plugins.disable(plugin);
}
if (hasSubmenu) {
refreshMenu();
}
},
});
const mainMenuTemplate = (win) => {
const refreshMenu = () => {
this.setApplicationMenu(win);
if (inAppMenuActive) {
win.webContents.send("refreshMenu");
}
}
return [
{
label: "Plugins",
submenu: [
...getAllPlugins().map((plugin) => {
const pluginPath = path.join(__dirname, "plugins", plugin, "menu.js")
if (existsSync(pluginPath)) {
if (!config.plugins.isEnabled(plugin)) {
return pluginEnabledMenu(plugin, "", true, refreshMenu);
}
const getPluginMenu = require(pluginPath);
return {
label: plugin,
submenu: [
pluginEnabledMenu(plugin, "Enabled", true, refreshMenu),
{ type: "separator" },
...getPluginMenu(win, config.plugins.getOptions(plugin), refreshMenu),
],
};
}
return pluginEnabledMenu(plugin);
}),
],
},
{
label: "Options",
submenu: [
{
label: "Auto-update",
type: "checkbox",
checked: config.plugins.isEnabled(plugin),
checked: config.get("options.autoUpdates"),
click: (item) => {
if (item.checked) {
config.plugins.enable(plugin);
} else {
config.plugins.disable(plugin);
config.setMenuOption("options.autoUpdates", item.checked);
},
},
{
label: "Resume last song when app starts",
type: "checkbox",
checked: config.get("options.resumeOnStart"),
click: (item) => {
config.setMenuOption("options.resumeOnStart", item.checked);
},
},
{
label: "Visual Tweaks",
submenu: [
{
label: "Remove upgrade button",
type: "checkbox",
checked: config.get("options.removeUpgradeButton"),
click: (item) => {
config.setMenuOption("options.removeUpgradeButton", item.checked);
},
},
{
label: "Force show like buttons",
type: "checkbox",
checked: config.get("options.ForceShowLikeButtons"),
click: (item) => {
config.set("options.ForceShowLikeButtons", item.checked);
},
},
{
label: "Theme",
submenu: [
{
label: "No theme",
type: "radio",
checked: !config.get("options.themes"), // todo rename "themes"
click: () => {
config.set("options.themes", []);
},
},
{ type: "separator" },
{
label: "Import custom CSS file",
type: "radio",
checked: false,
click: async () => {
const { filePaths } = await dialog.showOpenDialog({
filters: [{ name: "CSS Files", extensions: ["css"] }],
properties: ["openFile", "multiSelections"],
});
if (filePaths) {
config.set("options.themes", filePaths);
}
},
},
],
},
],
},
{
label: "Single instance lock",
type: "checkbox",
checked: config.get("options.singleInstanceLock"),
click: (item) => {
config.setMenuOption("options.singleInstanceLock", item.checked);
if (item.checked && !app.hasSingleInstanceLock()) {
app.requestSingleInstanceLock();
} else if (!item.checked && app.hasSingleInstanceLock()) {
app.releaseSingleInstanceLock();
}
},
};
}),
{ type: "separator" },
{
label: "Advanced options",
click: () => {
config.edit();
},
},
],
},
{
label: "Options",
submenu: [
{
label: "Auto-update",
type: "checkbox",
checked: config.get("options.autoUpdates"),
click: (item) => {
config.set("options.autoUpdates", item.checked);
{
label: "Always on top",
type: "checkbox",
checked: config.get("options.alwaysOnTop"),
click: (item) => {
config.setMenuOption("options.alwaysOnTop", item.checked);
win.setAlwaysOnTop(item.checked);
},
},
},
{
label: "Disable hardware acceleration",
type: "checkbox",
checked: config.get("options.disableHardwareAcceleration"),
click: (item) => {
config.set("options.disableHardwareAcceleration", item.checked);
},
},
{
label: "Restart on config changes",
type: "checkbox",
checked: config.get("options.restartOnConfigChanges"),
click: (item) => {
config.set("options.restartOnConfigChanges", item.checked);
},
},
...(is.windows() || is.linux()
? [
...(is.windows() || is.linux()
? [
{
label: "Hide menu",
type: "checkbox",
checked: config.get("options.hideMenu"),
click: (item) => {
config.set("options.hideMenu", item.checked);
config.setMenuOption("options.hideMenu", item.checked);
if (item.checked && !config.get("options.hideMenuWarned")) {
dialog.showMessageBox(win, {
type: 'info', title: 'Hide Menu Enabled',
message: "Menu will be hidden on next launch, use 'Alt' to show it (or 'Escape' if using in-app-menu)"
});
}
},
},
]
: []),
...(is.windows() || is.macOS()
? // Only works on Win/Mac
// https://www.electronjs.org/docs/api/app#appsetloginitemsettingssettings-macos-windows
[
]
: []),
...(is.windows() || is.macOS()
? // Only works on Win/Mac
// https://www.electronjs.org/docs/api/app#appsetloginitemsettingssettings-macos-windows
[
{
label: "Start at login",
type: "checkbox",
checked: config.get("options.startAtLogin"),
click: (item) => {
config.set("options.startAtLogin", item.checked);
config.setMenuOption("options.startAtLogin", item.checked);
},
},
]
: []),
{
label: "Tray",
submenu: [
{
label: "Disabled",
type: "radio",
checked: !config.get("options.tray"),
click: () => {
config.set("options.tray", false);
config.set("options.appVisible", true);
]
: []),
{
label: "Tray",
submenu: [
{
label: "Disabled",
type: "radio",
checked: !config.get("options.tray"),
click: () => {
config.setMenuOption("options.tray", false);
config.setMenuOption("options.appVisible", true);
},
},
},
{
label: "Enabled + app visible",
type: "radio",
checked:
config.get("options.tray") && config.get("options.appVisible"),
click: () => {
config.set("options.tray", true);
config.set("options.appVisible", true);
{
label: "Enabled + app visible",
type: "radio",
checked:
config.get("options.tray") && config.get("options.appVisible"),
click: () => {
config.setMenuOption("options.tray", true);
config.setMenuOption("options.appVisible", true);
},
},
},
{
label: "Enabled + app hidden",
type: "radio",
checked:
config.get("options.tray") && !config.get("options.appVisible"),
click: () => {
config.set("options.tray", true);
config.set("options.appVisible", false);
{
label: "Enabled + app hidden",
type: "radio",
checked:
config.get("options.tray") && !config.get("options.appVisible"),
click: () => {
config.setMenuOption("options.tray", true);
config.setMenuOption("options.appVisible", false);
},
},
},
],
},
{ type: "separator" },
{
label: "Toggle DevTools",
// Cannot use "toggleDevTools" role in MacOS
click: () => {
const { webContents } = win;
if (webContents.isDevToolsOpened()) {
webContents.closeDevTools();
} else {
const devToolsOptions = {};
webContents.openDevTools(devToolsOptions);
}
{ type: "separator" },
{
label: "Play/Pause on click",
type: "checkbox",
checked: config.get("options.trayClickPlayPause"),
click: (item) => {
config.setMenuOption("options.trayClickPlayPause", item.checked);
},
},
],
},
},
{
label: "Advanced options",
click: () => {
config.edit();
{ type: "separator" },
{
label: "Advanced options",
submenu: [
{
label: "Proxy",
type: "checkbox",
checked: !!config.get("options.proxy"),
click: (item) => {
setProxy(item, win);
},
},
{
label: "Override useragent",
type: "checkbox",
checked: config.get("options.overrideUserAgent"),
click: (item) => {
config.setMenuOption("options.overrideUserAgent", item.checked);
}
},
{
label: "Disable hardware acceleration",
type: "checkbox",
checked: config.get("options.disableHardwareAcceleration"),
click: (item) => {
config.setMenuOption("options.disableHardwareAcceleration", item.checked);
},
},
{
label: "Restart on config changes",
type: "checkbox",
checked: config.get("options.restartOnConfigChanges"),
click: (item) => {
config.setMenuOption("options.restartOnConfigChanges", item.checked);
},
},
{
label: "Reset App cache when app starts",
type: "checkbox",
checked: config.get("options.autoResetAppCache"),
click: (item) => {
config.setMenuOption("options.autoResetAppCache", item.checked);
},
},
{ type: "separator" },
is.macOS() ?
{
label: "Toggle DevTools",
// Cannot use "toggleDevTools" role in MacOS
click: () => {
const { webContents } = win;
if (webContents.isDevToolsOpened()) {
webContents.closeDevTools();
} else {
const devToolsOptions = {};
webContents.openDevTools(devToolsOptions);
}
},
} :
{ role: "toggleDevTools" },
{
label: "Edit config.json",
click: () => {
config.edit();
},
},
]
},
},
],
},
];
],
},
{
label: "View",
submenu: [
{ role: "reload" },
{ role: "forceReload" },
{ type: "separator" },
{ role: "zoomIn" },
{ role: "zoomOut" },
{ role: "resetZoom" },
{ type: "separator" },
{ role: "togglefullscreen" },
],
},
{
label: "Navigation",
submenu: [
{
label: "Go back",
click: () => {
if (win.webContents.canGoBack()) {
win.webContents.goBack();
}
},
},
{
label: "Go forward",
click: () => {
if (win.webContents.canGoForward()) {
win.webContents.goForward();
}
},
},
{
label: "Restart App",
click: restart
},
{ role: "quit" },
],
},
];
}
module.exports.mainMenuTemplate = mainMenuTemplate;
module.exports.setApplicationMenu = (win) => {
@ -175,3 +372,25 @@ module.exports.setApplicationMenu = (win) => {
const menu = Menu.buildFromTemplate(menuTemplate);
Menu.setApplicationMenu(menu);
};
async function setProxy(item, win) {
const output = await prompt({
title: 'Set Proxy',
label: 'Enter Proxy Address: (leave empty to disable)',
value: config.get("options.proxy"),
type: 'input',
inputAttrs: {
type: 'url',
placeholder: "Example: 'socks5://127.0.0.1:9999"
},
width: 450,
...promptOptions()
}, win);
if (typeof output === "string") {
config.setMenuOption("options.proxy", output);
item.checked = output !== "";
} else { //user pressed cancel
item.checked = !item.checked; //reset checkbox
}
}

View File

@ -1,7 +1,7 @@
{
"name": "youtube-music",
"productName": "YouTube Music",
"version": "1.7.4",
"version": "1.18.0",
"description": "YouTube Music Desktop App - including custom plugins",
"license": "MIT",
"repository": "th-ch/youtube-music",
@ -15,71 +15,147 @@
"productName": "YouTube Music",
"mac": {
"identity": null,
"files": [
"!plugins/taskbar-mediacontrol${/*}"
],
"target": [
{
"target": "dmg",
"arch": [
"x64",
"arm64"
]
}
],
"icon": "assets/generated/icons/mac/icon.icns"
},
"win": {
"icon": "assets/generated/icons/win/icon.ico"
"icon": "assets/generated/icons/win/icon.ico",
"files": [
"!plugins/touchbar${/*}"
],
"target": [
"nsis",
"portable"
]
},
"nsis": {
"runAfterFinish": false
},
"linux": {
"icon": "assets/generated/icons/png",
"category": "AudioVideo"
"files": [
"!plugins/{touchbar,taskbar-mediacontrol}${/*}"
],
"category": "AudioVideo",
"target": [
"AppImage",
"snap",
"freebsd",
"deb",
"rpm"
]
},
"snap": {
"slots": [
{
"mpris": {
"interface": "mpris"
}
}
]
}
},
"scripts": {
"test": "jest",
"test": "playwright test",
"test:debug": "DEBUG=pw:browser* playwright test",
"start": "electron .",
"start:debug": "ELECTRON_ENABLE_LOGGING=1 electron .",
"icon": "rimraf assets/generated && electron-icon-maker --input=assets/youtube-music.png --output=assets/generated",
"generate:package": "node utils/generate-package-json.js",
"postinstall": "yarn run icon && yarn run plugins",
"clean": "rimraf dist",
"build": "yarn run clean && electron-builder --win --mac --linux",
"build:linux": "yarn run clean && electron-builder --linux",
"build:mac": "yarn run clean && electron-builder --mac",
"build:mac": "yarn run clean && electron-builder --mac dmg:x64",
"build:mac:arm64": "yarn run clean && electron-builder --mac dmg:arm64",
"build:win": "yarn run clean && electron-builder --win",
"plugins": "yarn run plugin:adblocker && yarn run plugin:autoconfirm",
"lint": "xo",
"changelog": "auto-changelog",
"plugins": "yarn run plugin:adblocker",
"plugin:adblocker": "rimraf plugins/adblocker/ad-blocker-engine.bin && node plugins/adblocker/blocker.js",
"plugin:autoconfirm": "yarn run generate:package YoutubeNonStop",
"release:linux": "yarn run clean && electron-builder --linux -p always -c.snap.publish=github",
"release:mac": "yarn run clean && electron-builder --mac -p always",
"release:win": "yarn run clean && electron-builder --win -p always"
},
"engines": {
"node": ">=12.16.1",
"node": ">=14.0.0",
"npm": "Please use yarn and not npm"
},
"dependencies": {
"@cliqz/adblocker-electron": "^1.18.8",
"@ffmpeg/core": "^0.8.4",
"@ffmpeg/ffmpeg": "^0.9.5",
"YoutubeNonStop": "git://github.com/lawfx/YoutubeNonStop.git#v0.8.0",
"downloads-folder": "^3.0.1",
"electron-debug": "^3.1.0",
"@cliqz/adblocker-electron": "^1.23.8",
"@ffmpeg/core": "^0.10.0",
"@ffmpeg/ffmpeg": "^0.10.1",
"Simple-YouTube-Age-Restriction-Bypass": "https://gitpkg.now.sh/zerodytrash/Simple-YouTube-Age-Restriction-Bypass/dist?v2.4.6",
"async-mutex": "^0.3.2",
"browser-id3-writer": "^4.4.0",
"chokidar": "^3.5.3",
"custom-electron-prompt": "^1.5.0",
"custom-electron-titlebar": "^4.1.0",
"discord-rpc": "^4.0.1",
"electron-better-web-request": "^1.0.1",
"electron-debug": "^3.2.0",
"electron-is": "^3.0.0",
"electron-localshortcut": "^3.2.1",
"electron-store": "^6.0.1",
"electron-updater": "^4.3.5",
"filenamify": "^4.2.0",
"node-fetch": "^2.6.1",
"ytdl-core": "^4.1.1"
"electron-store": "^8.0.2",
"electron-unhandled": "^4.0.1",
"electron-updater": "^4.6.3",
"filenamify": "^4.3.0",
"hark": "^1.2.3",
"html-to-text": "^8.2.1",
"md5": "^2.3.0",
"mpris-service": "^2.1.2",
"node-fetch": "^2.6.7",
"node-notifier": "^10.0.1",
"ytdl-core": "^4.11.1",
"ytpl": "^2.3.0"
},
"devDependencies": {
"electron": "^10.1.3",
"electron-builder": "^22.8.1",
"@playwright/test": "^1.25.1",
"auto-changelog": "^2.4.0",
"electron": "^20.1.1",
"electron-builder": "^23.0.3",
"electron-devtools-installer": "^3.1.1",
"electron-icon-maker": "0.0.5",
"get-port": "^5.1.1",
"jest": "^26.4.2",
"playwright": "^1.25.1",
"rimraf": "^3.0.2",
"spectron": "^12.0.0",
"xo": "^0.33.1"
"xo": "^0.45.0"
},
"resolutions": {
"glob-parent": "5.1.2",
"minimist": "1.2.6",
"yargs-parser": "18.1.3"
},
"auto-changelog": {
"hideCredit": true,
"package": true,
"unreleased": true,
"output": "changelog.md"
},
"xo": {
"envs": [
"node",
"browser"
]
],
"rules": {
"quotes": [
"error",
"double",
{
"avoidEscape": true,
"allowTemplateLiterals": true
}
]
}
}
}

View File

@ -8,7 +8,9 @@ const SOURCES = [
"https://raw.githubusercontent.com/kbinani/adblock-youtube-ads/master/signed.txt",
// uBlock Origin
"https://raw.githubusercontent.com/uBlockOrigin/uAssets/master/filters/filters.txt",
"https://raw.githubusercontent.com/uBlockOrigin/uAssets/master/filters/filters-2020.txt",
"https://raw.githubusercontent.com/uBlockOrigin/uAssets/master/filters/filters-2021.txt",
// Fanboy Annoyances
"https://secure.fanboy.co.nz/fanboy-annoyance_ubo.txt",
];
const loadAdBlockerEngine = (
@ -31,7 +33,17 @@ const loadAdBlockerEngine = (
...additionalBlockLists,
];
ElectronBlocker.fromLists(fetch, lists, {}, cachingOptions)
ElectronBlocker.fromLists(
fetch,
lists,
{
// when generating the engine for caching, do not load network filters
// So that enhancing the session works as expected
// Allowing to define multiple webRequest listeners
loadNetworkFilters: session !== undefined,
},
cachingOptions
)
.then((blocker) => {
if (session) {
blocker.enableBlockingInSession(session);

View File

@ -0,0 +1,17 @@
const applyCompressor = () => {
const audioContext = new AudioContext();
const compressor = audioContext.createDynamicsCompressor();
compressor.threshold.value = -50;
compressor.ratio.value = 12;
compressor.knee.value = 40;
compressor.attack.value = 0;
compressor.release.value = 0.25;
const source = audioContext.createMediaElementSource(document.querySelector("video"));
source.connect(compressor);
compressor.connect(audioContext.destination);
};
module.exports = () => document.addEventListener('apiLoaded', applyCompressor, { once: true, passive: true });

View File

@ -1,12 +0,0 @@
// Define global chrome object to be compliant with the extension code
global.chrome = {
runtime: {
getManifest: () => ({
version: 1
})
}
};
module.exports = () => {
require("YoutubeNonStop/autoconfirm.js");
};

View File

@ -1,5 +1,5 @@
const { injectCSS } = require("../utils");
const path = require("path");
const { injectCSS } = require("../utils");
module.exports = win => {
injectCSS(win.webContents, path.join(__dirname, "style.css"));

View File

@ -0,0 +1,10 @@
#nav-bar-background,
#header.ytmusic-item-section-renderer,
ytmusic-tabs {
background: rgba(0, 0, 0, 0.3) !important;
backdrop-filter: blur(8px) !important;
}
#nav-bar-divider {
display: none !important;
}

View File

@ -0,0 +1,4 @@
module.exports = () => {
// See https://github.com/zerodytrash/Simple-YouTube-Age-Restriction-Bypass#userscript
require("simple-youtube-age-restriction-bypass/Simple-YouTube-Age-Restriction-Bypass.user.js");
};

View File

@ -0,0 +1,14 @@
module.exports = () => {
document.addEventListener('apiLoaded', apiEvent => {
apiEvent.detail.addEventListener('videodatachange', name => {
if (name === 'dataloaded') {
apiEvent.detail.pauseVideo();
document.querySelector('video').ontimeupdate = e => {
e.target.pause();
}
} else {
document.querySelector('video').ontimeupdate = null;
}
})
}, { once: true, passive: true })
};

145
plugins/discord/back.js Normal file
View File

@ -0,0 +1,145 @@
const Discord = require("discord-rpc");
const { dev } = require("electron-is");
const { dialog, app } = require("electron");
const registerCallback = require("../../providers/song-info");
// Application ID registered by @xn-oah
const clientId = "942539762227630162";
/**
* @typedef {Object} Info
* @property {import('discord-rpc').Client} rpc
* @property {boolean} ready
* @property {import('../../providers/song-info').SongInfo} lastSongInfo
*/
/**
* @type {Info}
*/
const info = {
rpc: null,
ready: false,
lastSongInfo: null,
};
/**
* @type {(() => void)[]}
*/
const refreshCallbacks = [];
const resetInfo = () => {
info.rpc = null;
info.ready = false;
clearTimeout(clearActivity);
if (dev()) console.log("discord disconnected");
refreshCallbacks.forEach(cb => cb());
};
let window;
const connect = (showErr = false) => {
if (info.rpc) {
if (dev())
console.log('Attempted to connect with active RPC object');
return;
}
info.rpc = new Discord.Client({
transport: "ipc",
});
info.ready = false;
info.rpc.once("connected", () => {
if (dev()) console.log("discord connected");
refreshCallbacks.forEach(cb => cb());
});
info.rpc.once("ready", () => {
info.ready = true;
if (info.lastSongInfo) updateActivity(info.lastSongInfo)
});
info.rpc.once("disconnected", resetInfo);
// Startup the rpc client
info.rpc.login({ clientId }).catch(err => {
resetInfo();
if (dev()) console.error(err);
if (showErr) dialog.showMessageBox(window, { title: 'Connection failed', message: err.message || String(err), type: 'error' });
});
};
let clearActivity;
/**
* @type {import('../../providers/song-info').songInfoCallback}
*/
let updateActivity;
module.exports = (win, { activityTimoutEnabled, activityTimoutTime, listenAlong }) => {
window = win;
// We get multiple events
// Next song: PAUSE(n), PAUSE(n+1), PLAY(n+1)
// Skip time: PAUSE(N), PLAY(N)
updateActivity = songInfo => {
if (songInfo.title.length === 0 && songInfo.artist.length === 0) {
return;
}
info.lastSongInfo = songInfo;
// stop the clear activity timout
clearTimeout(clearActivity);
// stop early if discord connection is not ready
// do this after clearTimeout to avoid unexpected clears
if (!info.rpc || !info.ready) {
return;
}
// clear directly if timeout is 0
if (songInfo.isPaused && activityTimoutEnabled && activityTimoutTime === 0) {
info.rpc.clearActivity().catch(console.error);
return;
}
// Song information changed, so lets update the rich presence
// @see https://discord.com/developers/docs/topics/gateway#activity-object
// not all options are transfered through https://github.com/discordjs/RPC/blob/6f83d8d812c87cb7ae22064acd132600407d7d05/src/client.js#L518-530
const activityInfo = {
type: 2, // Listening, addressed in https://github.com/discordjs/RPC/pull/149
details: songInfo.title,
state: songInfo.artist,
largeImageKey: songInfo.imageSrc,
largeImageText: songInfo.album,
buttons: listenAlong ? [
{ label: "Listen Along", url: songInfo.url },
] : undefined,
};
if (songInfo.isPaused) {
// Add a paused icon to show that the song is paused
activityInfo.smallImageKey = "paused";
activityInfo.smallImageText = "Paused";
// Set start the timer so the activity gets cleared after a while if enabled
if (activityTimoutEnabled)
clearActivity = setTimeout(() => info.rpc.clearActivity().catch(console.error), activityTimoutTime ?? 10000);
} else {
// Add the start and end time of the song
const songStartTime = Date.now() - songInfo.elapsedSeconds * 1000;
activityInfo.startTimestamp = songStartTime;
activityInfo.endTimestamp =
songStartTime + songInfo.songDuration * 1000;
}
info.rpc.setActivity(activityInfo).catch(console.error);
};
// If the page is ready, register the callback
win.once("ready-to-show", () => {
registerCallback(updateActivity);
connect();
});
app.on('window-all-closed', module.exports.clear)
};
module.exports.clear = () => {
if (info.rpc) info.rpc.clearActivity();
clearTimeout(clearActivity);
};
module.exports.connect = connect;
module.exports.registerRefresh = (cb) => refreshCallbacks.push(cb);
module.exports.isConnected = () => info.rpc !== null;

65
plugins/discord/menu.js Normal file
View File

@ -0,0 +1,65 @@
const prompt = require("custom-electron-prompt");
const { setMenuOptions } = require("../../config/plugins");
const promptOptions = require("../../providers/prompt-options");
const { clear, connect, registerRefresh, isConnected } = require("./back");
let hasRegisterred = false;
module.exports = (win, options, refreshMenu) => {
if (!hasRegisterred) {
registerRefresh(refreshMenu);
hasRegisterred = true;
}
return [
{
label: isConnected() ? "Connected" : "Reconnect",
enabled: !isConnected(),
click: connect,
},
{
label: "Clear activity",
click: clear,
},
{
label: "Clear activity after timeout",
type: "checkbox",
checked: options.activityTimoutEnabled,
click: (item) => {
options.activityTimoutEnabled = item.checked;
setMenuOptions('discord', options);
},
},
{
label: "Listen Along",
type: "checkbox",
checked: options.listenAlong,
click: (item) => {
options.listenAlong = item.checked;
setMenuOptions('discord', options);
},
},
{
label: "Set inactivity timeout",
click: () => setInactivityTimeout(win, options),
},
];
};
async function setInactivityTimeout(win, options) {
let output = await prompt({
title: 'Set Inactivity Timeout',
label: 'Enter inactivity timeout in seconds:',
value: Math.round((options.activityTimoutTime ?? 0) / 1e3),
type: "counter",
counterOptions: { minimum: 0, multiFire: true },
width: 450,
...promptOptions()
}, win)
if (output) {
options.activityTimoutTime = Math.round(output * 1e3);
setMenuOptions("discord", options);
}
}

View File

@ -1,6 +1,8 @@
const CHANNEL = "downloader";
const ACTIONS = {
ERROR: "error",
METADATA: "metadata",
PROGRESS: "progress",
};
module.exports = {

View File

@ -1,33 +1,98 @@
const { writeFileSync } = require("fs");
const { join } = require("path");
const { dialog } = require("electron");
const ID3Writer = require("browser-id3-writer");
const { dialog, ipcMain } = require("electron");
const registerCallback = require("../../providers/song-info");
const { injectCSS, listenAction } = require("../utils");
const { cropMaxWidth } = require("./utils");
const { ACTIONS, CHANNEL } = require("./actions.js");
const { isEnabled } = require("../../config/plugins");
const { getImage } = require("../../providers/song-info");
const { fetchFromGenius } = require("../lyrics-genius/back");
const sendError = (win, err) => {
const dialogOpts = {
const sendError = (win, error) => {
win.setProgressBar(-1); // close progress bar
dialog.showMessageBox({
type: "info",
buttons: ["OK"],
title: "Error in download!",
message: "Argh! Apologies, download failed…",
detail: err.toString(),
};
dialog.showMessageBox(dialogOpts);
detail: error.toString(),
});
};
let nowPlayingMetadata = {};
function handle(win) {
injectCSS(win.webContents, join(__dirname, "style.css"));
registerCallback((info) => {
nowPlayingMetadata = info;
});
listenAction(CHANNEL, (event, action, error) => {
listenAction(CHANNEL, (event, action, arg) => {
switch (action) {
case ACTIONS.ERROR:
sendError(win, error);
case ACTIONS.ERROR: // arg = error
sendError(win, arg);
break;
case ACTIONS.METADATA:
event.returnValue = JSON.stringify(nowPlayingMetadata);
break;
case ACTIONS.PROGRESS: // arg = progress
win.setProgressBar(arg);
break;
default:
console.log("Unknown action: " + action);
}
});
ipcMain.on("add-metadata", async (event, filePath, songBuffer, currentMetadata) => {
let fileBuffer = songBuffer;
const songMetadata = currentMetadata.imageSrcYTPL ? // This means metadata come from ytpl.getInfo();
{
...currentMetadata,
image: cropMaxWidth(await getImage(currentMetadata.imageSrcYTPL))
} :
{ ...nowPlayingMetadata, ...currentMetadata };
try {
const coverBuffer = songMetadata.image && !songMetadata.image.isEmpty() ?
songMetadata.image.toPNG() : null;
const writer = new ID3Writer(songBuffer);
// Create the metadata tags
writer
.setFrame("TIT2", songMetadata.title)
.setFrame("TPE1", [songMetadata.artist]);
if (coverBuffer) {
writer.setFrame("APIC", {
type: 3,
data: coverBuffer,
description: ""
});
}
if (isEnabled("lyrics-genius")) {
const lyrics = await fetchFromGenius(songMetadata);
if (lyrics) {
writer.setFrame("USLT", {
description: lyrics,
lyrics: lyrics,
});
}
}
writer.addTag();
fileBuffer = Buffer.from(writer.arrayBuffer);
} catch (error) {
sendError(win, error);
}
writeFileSync(filePath, fileBuffer);
// Notify the youtube-dl file
event.reply("add-metadata-done");
});
}
module.exports = handle;
module.exports.sendError = sendError;

View File

@ -1,3 +1,7 @@
const { ipcRenderer } = require("electron");
const { defaultConfig } = require("../../config");
const { getSongMenu } = require("../../providers/dom-elements");
const { ElementFromFile, templatePath, triggerAction } = require("../utils");
const { ACTIONS, CHANNEL } = require("./actions.js");
const { downloadVideoToMP3 } = require("./youtube-dl");
@ -9,18 +13,21 @@ const downloadButton = ElementFromFile(
);
let pluginOptions = {};
const observer = new MutationObserver((mutations, observer) => {
const observer = new MutationObserver(() => {
if (!menu) {
menu = document.querySelector("ytmusic-menu-popup-renderer paper-listbox");
menu = getSongMenu();
if (!menu) return;
}
if (menu.contains(downloadButton)) return;
const menuUrl = document.querySelector('tp-yt-paper-listbox [tabindex="0"] #navigation-endpoint')?.href;
if (menuUrl && !menuUrl.includes('watch?')) return;
if (menu && !menu.contains(downloadButton)) {
menu.prepend(downloadButton);
progress = document.querySelector("#ytmcustom-download");
}
menu.prepend(downloadButton);
progress = document.querySelector("#ytmcustom-download");
});
const reinit = () => {
triggerAction(CHANNEL, ACTIONS.PROGRESS, -1); // closes progress bar
if (!progress) {
console.warn("Cannot update progress");
} else {
@ -28,33 +35,64 @@ const reinit = () => {
}
};
const baseUrl = defaultConfig.url;
// TODO: re-enable once contextIsolation is set to true
// contextBridge.exposeInMainWorld("downloader", {
// download: () => {
global.download = () => {
const videoUrl = window.location.href;
triggerAction(CHANNEL, ACTIONS.PROGRESS, 2); // starts with indefinite progress bar
let metadata;
let videoUrl = getSongMenu()
// selector of first button which is always "Start Radio"
?.querySelector('ytmusic-menu-navigation-item-renderer[tabindex="0"] #navigation-endpoint')
?.getAttribute("href");
if (videoUrl) {
if (videoUrl.startsWith('watch?')) {
videoUrl = baseUrl + "/" + videoUrl;
}
if (videoUrl.includes('?playlist=')) {
ipcRenderer.send('download-playlist-request', videoUrl);
return;
}
metadata = null;
} else {
metadata = global.songInfo;
videoUrl = metadata.url || window.location.href;
}
downloadVideoToMP3(
videoUrl,
(feedback) => {
(feedback, ratio = undefined) => {
if (!progress) {
console.warn("Cannot update progress");
} else {
progress.innerHTML = feedback;
}
if (ratio) {
triggerAction(CHANNEL, ACTIONS.PROGRESS, ratio);
}
},
(error) => {
triggerAction(CHANNEL, ACTIONS.ERROR, error);
reinit();
},
reinit,
pluginOptions
pluginOptions,
metadata
);
};
// });
function observeMenu(options) {
pluginOptions = { ...pluginOptions, ...options };
observer.observe(document, {
childList: true,
subtree: true,
});
document.addEventListener('apiLoaded', () => {
observer.observe(document.querySelector('ytmusic-popup-container'), {
childList: true,
subtree: true,
});
}, { once: true, passive: true })
}
module.exports = observeMenu;

151
plugins/downloader/menu.js Normal file
View File

@ -0,0 +1,151 @@
const { existsSync, mkdirSync } = require("fs");
const { join } = require("path");
const { dialog, ipcMain } = require("electron");
const is = require("electron-is");
const ytpl = require("ytpl");
const chokidar = require('chokidar');
const filenamify = require('filenamify');
const { setMenuOptions } = require("../../config/plugins");
const { sendError } = require("./back");
const { defaultMenuDownloadLabel, getFolder, presets, setBadge } = require("./utils");
let downloadLabel = defaultMenuDownloadLabel;
let playingUrl = undefined;
let callbackIsRegistered = false;
// Playlist radio modifier needs to be cut from playlist ID
const INVALID_PLAYLIST_MODIFIER = 'RDAMPL';
const getPlaylistID = aURL => {
const result = aURL?.searchParams.get("list") || aURL?.searchParams.get("playlist");
if (result?.startsWith(INVALID_PLAYLIST_MODIFIER)) {
return result.slice(6)
}
return result;
};
module.exports = (win, options) => {
if (!callbackIsRegistered) {
ipcMain.on("video-src-changed", async (_, data) => {
playingUrl = JSON.parse(data)?.microformat?.microformatDataRenderer?.urlCanonical;
});
ipcMain.on("download-playlist-request", async (_event, url) => downloadPlaylist(url, win, options));
callbackIsRegistered = true;
}
return [
{
label: downloadLabel,
click: () => downloadPlaylist(undefined, win, options),
},
{
label: "Choose download folder",
click: () => {
let result = dialog.showOpenDialogSync({
properties: ["openDirectory", "createDirectory"],
defaultPath: getFolder(options.downloadFolder),
});
if (result) {
options.downloadFolder = result[0];
setMenuOptions("downloader", options);
} // else = user pressed cancel
},
},
{
label: "Presets",
submenu: Object.keys(presets).map((preset) => ({
label: preset,
type: "radio",
click: () => {
options.preset = preset;
setMenuOptions("downloader", options);
},
checked: options.preset === preset || presets[preset] === undefined,
})),
},
];
};
async function downloadPlaylist(givenUrl, win, options) {
if (givenUrl) {
try {
givenUrl = new URL(givenUrl);
} catch {
givenUrl = undefined;
};
}
const playlistId = getPlaylistID(givenUrl)
|| getPlaylistID(new URL(win.webContents.getURL()))
|| getPlaylistID(new URL(playingUrl));
if (!playlistId) {
sendError(win, new Error("No playlist ID found"));
return;
}
console.log(`trying to get playlist ID: '${playlistId}'`);
let playlist;
try {
playlist = await ytpl(playlistId, {
limit: options.playlistMaxItems || Infinity,
});
} catch (e) {
sendError(win, e);
return;
}
const safePlaylistTitle = filenamify(playlist.title, {replacement: ' '});
const folder = getFolder(options.downloadFolder);
const playlistFolder = join(folder, safePlaylistTitle);
if (existsSync(playlistFolder)) {
sendError(
win,
new Error(`The folder ${playlistFolder} already exists`)
);
return;
}
mkdirSync(playlistFolder, { recursive: true });
dialog.showMessageBox({
type: "info",
buttons: ["OK"],
title: "Started Download",
message: `Downloading Playlist "${playlist.title}"`,
detail: `(${playlist.items.length} songs)`,
});
if (is.dev()) {
console.log(
`Downloading playlist "${playlist.title}" - ${playlist.items.length} songs (${playlistId})`
);
}
win.setProgressBar(2); // starts with indefinite bar
let downloadCount = 0;
setBadge(playlist.items.length);
let dirWatcher = chokidar.watch(playlistFolder);
dirWatcher.on('add', () => {
downloadCount += 1;
if (downloadCount >= playlist.items.length) {
win.setProgressBar(-1); // close progress bar
setBadge(0); // close badge counter
dirWatcher.close().then(() => (dirWatcher = null));
} else {
win.setProgressBar(downloadCount / playlist.items.length);
setBadge(playlist.items.length - downloadCount);
}
});
playlist.items.forEach((song) => {
win.webContents.send(
"downloader-download-playlist",
song.url,
safePlaylistTitle,
options
);
});
}

View File

@ -6,8 +6,16 @@
cursor: pointer;
}
.menu-item > .yt-simple-endpoint:hover {
background-color: var(--ytmusic-menu-item-hover-background-color);
}
.menu-icon {
flex: var(--ytmusic-menu-item-icon_-_flex);
margin: var(--ytmusic-menu-item-icon_-_margin);
fill: var(--ytmusic-menu-item-icon_-_fill);
stroke: var(--iron-icon-stroke-color, none);
width: var(--iron-icon-width, 24px);
height: var(--iron-icon-height, 24px);
animation: var(--iron-icon_-_animation);
}

View File

@ -1,5 +1,5 @@
<div
class="menu-item ytmusic-menu-popup-renderer"
class="style-scope menu-item ytmusic-menu-popup-renderer"
role="option"
tabindex="-1"
aria-disabled="false"
@ -7,31 +7,39 @@
onclick="download()"
>
<div
class="menu-icon yt-icon-container yt-icon ytmusic-toggle-menu-service-item-renderer"
id="navigation-endpoint"
class="yt-simple-endpoint style-scope ytmusic-menu-navigation-item-renderer"
tabindex="-1"
>
<svg
viewBox="0 0 24 24"
preserveAspectRatio="xMidYMid meet"
focusable="false"
class="style-scope yt-icon"
style="pointer-events: none; display: block; width: 100%; height: 100%;"
<div
class="icon menu-icon style-scope ytmusic-menu-navigation-item-renderer"
>
<g class="style-scope yt-icon">
<path
d="M25.462,19.105v6.848H4.515v-6.848H0.489v8.861c0,1.111,0.9,2.012,2.016,2.012h24.967c1.115,0,2.016-0.9,2.016-2.012v-8.861H25.462z"
class="style-scope yt-icon"
/>
<path
d="M14.62,18.426l-5.764-6.965c0,0-0.877-0.828,0.074-0.828s3.248,0,3.248,0s0-0.557,0-1.416c0-2.449,0-6.906,0-8.723c0,0-0.129-0.494,0.615-0.494c0.75,0,4.035,0,4.572,0c0.536,0,0.524,0.416,0.524,0.416c0,1.762,0,6.373,0,8.742c0,0.768,0,1.266,0,1.266s1.842,0,2.998,0c1.154,0,0.285,0.867,0.285,0.867s-4.904,6.51-5.588,7.193C15.092,18.979,14.62,18.426,14.62,18.426z"
class="style-scope yt-icon"
/>
</g>
</svg>
</div>
<div
class="text style-scope ytmusic-toggle-menu-service-item-renderer"
id="ytmcustom-download"
>
Download
<svg
viewBox="0 0 24 24"
preserveAspectRatio="xMidYMid meet"
focusable="false"
class="style-scope yt-icon"
style="pointer-events: none; display: block; width: 100%; height: 100%"
>
<g class="style-scope yt-icon">
<path
d="M25.462,19.105v6.848H4.515v-6.848H0.489v8.861c0,1.111,0.9,2.012,2.016,2.012h24.967c1.115,0,2.016-0.9,2.016-2.012v-8.861H25.462z"
class="style-scope yt-icon"
fill="#aaaaaa"
/>
<path
d="M14.62,18.426l-5.764-6.965c0,0-0.877-0.828,0.074-0.828s3.248,0,3.248,0s0-0.557,0-1.416c0-2.449,0-6.906,0-8.723c0,0-0.129-0.494,0.615-0.494c0.75,0,4.035,0,4.572,0c0.536,0,0.524,0.416,0.524,0.416c0,1.762,0,6.373,0,8.742c0,0.768,0,1.266,0,1.266s1.842,0,2.998,0c1.154,0,0.285,0.867,0.285,0.867s-4.904,6.51-5.588,7.193C15.092,18.979,14.62,18.426,14.62,18.426z"
class="style-scope yt-icon"
fill="#aaaaaa"
/>
</g>
</svg>
</div>
<div
class="text style-scope ytmusic-menu-navigation-item-renderer"
id="ytmcustom-download"
>
Download
</div>
</div>
</div>

View File

@ -0,0 +1,46 @@
const electron = require("electron");
const is = require('electron-is');
module.exports.getFolder = customFolder => customFolder || electron.app.getPath("downloads");
module.exports.defaultMenuDownloadLabel = "Download playlist";
const orderedQualityList = ["maxresdefault", "hqdefault", "mqdefault", "sdddefault"];
module.exports.urlToJPG = (imgUrl, videoId) => {
if (!imgUrl || imgUrl.includes(".jpg")) return imgUrl;
//it will almost never get further than hqdefault
for (const quality of orderedQualityList) {
if (imgUrl.includes(quality)) {
return `https://img.youtube.com/vi/${videoId}/${quality}.jpg`;
}
}
return `https://img.youtube.com/vi/${videoId}/default.jpg`;
}
module.exports.cropMaxWidth = (image) => {
const imageSize = image.getSize();
// standart youtube artwork width with margins from both sides is 280 + 720 + 280
if (imageSize.width === 1280 && imageSize.height === 720) {
return image.crop({
x: 280,
y: 0,
width: 720,
height: 720
});
}
return image;
}
// Presets for FFmpeg
module.exports.presets = {
"None (defaults to mp3)": undefined,
opus: {
extension: "opus",
ffmpegArgs: ["-acodec", "libopus"],
},
};
module.exports.setBadge = n => {
if (is.linux() || is.macOS()) {
electron.app.setBadgeCount(n);
}
}

View File

@ -1,8 +1,8 @@
const { randomBytes } = require("crypto");
const { writeFileSync } = require("fs");
const { join } = require("path");
const downloadsFolder = require("downloads-folder");
const Mutex = require("async-mutex").Mutex;
const { ipcRenderer } = require("electron");
const is = require("electron-is");
const filenamify = require("filenamify");
@ -12,22 +12,45 @@ const filenamify = require("filenamify");
const FFmpeg = require("@ffmpeg/ffmpeg/dist/ffmpeg.min");
const ytdl = require("ytdl-core");
const { triggerAction, triggerActionSync } = require("../utils");
const { ACTIONS, CHANNEL } = require("./actions.js");
const { presets, urlToJPG } = require("./utils");
const { cleanupName } = require("../../providers/song-info");
const { createFFmpeg } = FFmpeg;
const ffmpeg = createFFmpeg({
log: false,
logger: () => {}, // console.log,
progress: () => {}, // console.log,
});
const ffmpegMutex = new Mutex();
const downloadVideoToMP3 = (
const downloadVideoToMP3 = async (
videoUrl,
sendFeedback,
sendError,
reinit,
options
options,
metadata = undefined,
subfolder = ""
) => {
sendFeedback("Downloading…");
if (metadata === null) {
const { videoDetails } = await ytdl.getInfo(videoUrl);
const thumbnails = videoDetails?.thumbnails;
metadata = {
artist:
videoDetails?.media?.artist ||
cleanupName(videoDetails?.author?.name) ||
"",
title: videoDetails?.media?.song || videoDetails?.title || "",
imageSrcYTPL: thumbnails ?
urlToJPG(thumbnails[thumbnails.length - 1].url, videoDetails?.videoId)
: ""
}
}
let videoName = "YouTube Music - Unknown title";
let videoReadableStream;
try {
@ -47,20 +70,35 @@ const downloadVideoToMP3 = (
.on("data", (chunk) => {
chunks.push(chunk);
})
.on("progress", (chunkLength, downloaded, total) => {
const progress = Math.floor((downloaded / total) * 100);
sendFeedback("Download: " + progress + "%");
.on("progress", (_chunkLength, downloaded, total) => {
const ratio = downloaded / total;
const progress = Math.floor(ratio * 100);
sendFeedback("Download: " + progress + "%", ratio);
})
.on("info", (info, format) => {
videoName = info.videoDetails.title.replace("|", "").toString("ascii");
if (is.dev()) {
console.log("Downloading video - name:", videoName);
console.log(
"Downloading video - name:",
videoName,
"- quality:",
format.audioBitrate + "kbits/s"
);
}
})
.on("error", sendError)
.on("end", () => {
.on("end", async () => {
const buffer = Buffer.concat(chunks);
toMP3(videoName, buffer, sendFeedback, sendError, reinit, options);
await toMP3(
videoName,
buffer,
sendFeedback,
sendError,
reinit,
options,
metadata,
subfolder
);
});
};
@ -70,13 +108,18 @@ const toMP3 = async (
sendFeedback,
sendError,
reinit,
options
options,
existingMetadata = undefined,
subfolder = ""
) => {
const convertOptions = { ...presets[options.preset], ...options };
const safeVideoName = randomBytes(32).toString("hex");
const extension = convertOptions.extension || "mp3";
const releaseFFmpegMutex = await ffmpegMutex.acquire();
try {
if (!ffmpeg.isLoaded()) {
sendFeedback("Loading…");
sendFeedback("Loading…", 2); // indefinite progress bar after download
await ffmpeg.load();
}
@ -84,26 +127,74 @@ const toMP3 = async (
ffmpeg.FS("writeFile", safeVideoName, buffer);
sendFeedback("Converting…");
const metadata = existingMetadata || getMetadata();
await ffmpeg.run(
"-i",
safeVideoName,
...options.ffmpegArgs,
safeVideoName + ".mp3"
...getFFmpegMetadataArgs(metadata),
...(convertOptions.ffmpegArgs || []),
safeVideoName + "." + extension
);
const folder = options.downloadFolder || downloadsFolder();
const filename = filenamify(videoName + ".mp3", { replacement: "_" });
writeFileSync(
join(folder, filename),
ffmpeg.FS("readFile", safeVideoName + ".mp3")
);
const folder = options.downloadFolder || await ipcRenderer.invoke('getDownloadsFolder');
const name = metadata.title
? `${metadata.artist ? `${metadata.artist} - ` : ""}${metadata.title}`
: videoName;
const filename = filenamify(name + "." + extension, {
replacement: "_",
maxLength: 255,
});
reinit();
const filePath = join(folder, subfolder, filename);
const fileBuffer = ffmpeg.FS("readFile", safeVideoName + "." + extension);
// Add the metadata
sendFeedback("Adding metadata…");
ipcRenderer.send("add-metadata", filePath, fileBuffer, {
artist: metadata.artist,
title: metadata.title,
imageSrcYTPL: metadata.imageSrcYTPL
});
ipcRenderer.once("add-metadata-done", reinit);
} catch (e) {
sendError(e);
} finally {
releaseFFmpegMutex();
}
};
const getMetadata = () => {
return JSON.parse(triggerActionSync(CHANNEL, ACTIONS.METADATA));
};
const getFFmpegMetadataArgs = (metadata) => {
if (!metadata) {
return;
}
return [
...(metadata.title ? ["-metadata", `title=${metadata.title}`] : []),
...(metadata.artist ? ["-metadata", `artist=${metadata.artist}`] : []),
];
};
module.exports = {
downloadVideoToMP3,
};
ipcRenderer.on(
"downloader-download-playlist",
(_, url, playlistFolder, options) => {
downloadVideoToMP3(
url,
() => {},
(error) => {
triggerAction(CHANNEL, ACTIONS.ERROR, error);
},
() => {},
options,
null,
playlistFolder
);
}
);

View File

@ -0,0 +1,47 @@
// "Youtube Music fix volume ratio 0.4" by Marco Pfeiffer
// https://greasyfork.org/en/scripts/397686-youtube-music-fix-volume-ratio/
const exponentialVolume = () => {
// manipulation exponent, higher value = lower volume
// 3 is the value used by pulseaudio, which Barteks2x figured out this gist here: https://gist.github.com/Barteks2x/a4e189a36a10c159bb1644ffca21c02a
// 0.05 (or 5%) is the lowest you can select in the UI which with an exponent of 3 becomes 0.000125 or 0.0125%
const EXPONENT = 3;
const storedOriginalVolumes = new WeakMap();
const { get, set } = Object.getOwnPropertyDescriptor(
HTMLMediaElement.prototype,
"volume"
);
Object.defineProperty(HTMLMediaElement.prototype, "volume", {
get() {
const lowVolume = get.call(this);
const calculatedOriginalVolume = lowVolume ** (1 / EXPONENT);
// The calculated value has some accuracy issues which can lead to problems for implementations that expect exact values.
// To avoid this, I'll store the unmodified volume to return it when read here.
// This mostly solves the issue, but the initial read has no stored value and the volume can also change though external influences.
// To avoid ill effects, I check if the stored volume is somewhere in the same range as the calculated volume.
const storedOriginalVolume = storedOriginalVolumes.get(this);
const storedDeviation = Math.abs(
storedOriginalVolume - calculatedOriginalVolume
);
const originalVolume =
storedDeviation < 0.01
? storedOriginalVolume
: calculatedOriginalVolume;
return originalVolume;
},
set(originalVolume) {
const lowVolume = originalVolume ** EXPONENT;
storedOriginalVolumes.set(this, originalVolume);
set.call(this, lowVolume);
},
});
};
module.exports = () =>
document.addEventListener("apiLoaded", exponentialVolume, {
once: true,
passive: true,
});

View File

@ -0,0 +1,33 @@
const path = require("path");
const electronLocalshortcut = require("electron-localshortcut");
const config = require("../../config");
const { injectCSS } = require("../utils");
const { setupTitlebar, attachTitlebarToWindow } = require('custom-electron-titlebar/main');
setupTitlebar();
//tracks menu visibility
let visible = !config.get("options.hideMenu");
module.exports = (win) => {
// css for custom scrollbar + disable drag area(was causing bugs)
injectCSS(win.webContents, path.join(__dirname, "style.css"));
win.once("ready-to-show", () => {
attachTitlebarToWindow(win);
//register keyboard shortcut && hide menu if hideMenu is enabled
if (config.get("options.hideMenu")) {
electronLocalshortcut.register(win, "Esc", () => {
setMenuVisibility(!visible);
});
}
});
function setMenuVisibility(value) {
visible = value;
win.webContents.send("refreshMenu", visible);
}
};

View File

@ -0,0 +1,54 @@
const { ipcRenderer } = require("electron");
const config = require("../../config");
const { Titlebar, Color } = require("custom-electron-titlebar");
const { isEnabled } = require("../../config/plugins");
function $(selector) { return document.querySelector(selector); }
module.exports = (options) => {
let visible = !config.get("options.hideMenu");
const bar = new Titlebar({
backgroundColor: Color.fromHex("#050505"),
itemBackgroundColor: Color.fromHex("#1d1d1d"),
svgColor: Color.WHITE,
menu: visible ? undefined : null
});
bar.updateTitle(" ");
document.title = "Youtube Music";
const hideIcon = hide => $('.cet-window-icon').style.display = hide ? 'none' : 'flex';
if (options.hideIcon) hideIcon(true);
ipcRenderer.on("refreshMenu", (_, showMenu) => {
if (showMenu === undefined && !visible) return;
if (showMenu === false) {
bar.updateMenu(null);
visible = false;
} else {
bar.refreshMenu();
visible = true;
}
});
if (isEnabled("picture-in-picture")) {
ipcRenderer.on("pip-toggle", (_, pipEnabled) => {
bar.refreshMenu();
});
}
ipcRenderer.on("hideIcon", (_, hide) => hideIcon(hide));
// Increases the right margin of Navbar background when the scrollbar is visible to avoid blocking it (z-index doesn't affect it)
document.addEventListener('apiLoaded', () => {
setNavbarMargin();
const playPageObserver = new MutationObserver(setNavbarMargin);
playPageObserver.observe($('ytmusic-app-layout'), { attributeFilter: ['player-page-open_', 'playerPageOpen_'] })
}, { once: true, passive: true })
};
function setNavbarMargin() {
$('#nav-bar-background').style.right =
$('ytmusic-app-layout').playerPageOpen_ ?
'0px' :
'12px';
}

View File

@ -0,0 +1,14 @@
const { setOptions } = require("../../config/plugins");
module.exports = (win, options) => [
{
label: "Hide Icon",
type: "checkbox",
checked: options.hideIcon,
click: (item) => {
win.webContents.send("hideIcon", item.checked);
options.hideIcon = item.checked;
setOptions("in-app-menu", options);
},
}
];

View File

@ -0,0 +1,82 @@
/* increase font size for menu and menuItems */
.titlebar,
.menubar-menu-container .action-label {
font-size: 14px !important;
}
/* fixes nav-bar-background opacity bug, reposition it, and allows clicking scrollbar through it */
#nav-bar-background {
opacity: 1 !important;
pointer-events: none !important;
position: sticky !important;
top: 0 !important;
height: 75px !important;
}
/* fixes top gap between nav-bar and browse-page */
#browse-page {
padding-top: 0 !important;
}
/* remove window dragging for nav bar (conflict with titlebar drag) */
ytmusic-nav-bar,
.tab-titleiron-icon,
ytmusic-pivot-bar-item-renderer {
-webkit-app-region: unset !important;
}
/* move up item selection renderers */
ytmusic-item-section-renderer.stuck #header.ytmusic-item-section-renderer,
ytmusic-tabs.stuck {
top: calc(var(--ytmusic-nav-bar-height) - 15px) !important;
}
/* fix weird positioning in search screen*/
ytmusic-header-renderer.ytmusic-search-page {
position: unset !important;
}
/* Move navBar downwards */
ytmusic-nav-bar[slot="nav-bar"] {
top: 17px !important;
}
/* fix page progress bar position*/
yt-page-navigation-progress,
#progress.yt-page-navigation-progress {
top: 30px !important;
}
/* Custom scrollbar */
::-webkit-scrollbar {
width: 12px;
background-color: #030303;
border-radius: 100px;
-moz-border-radius: 100px;
-webkit-border-radius: 100px;
}
/* hover effect for both scrollbar area, and scrollbar 'thumb' */
::-webkit-scrollbar:hover {
background-color: rgba(15, 15, 15, 0.699);
}
/* The scrollbar 'thumb' ...that marque oval shape in a scrollbar */
::-webkit-scrollbar-thumb:vertical {
border: 2px solid rgba(0, 0, 0, 0);
background: #3a3a3a;
background-clip: padding-box;
border-radius: 100px;
-moz-border-radius: 100px;
-webkit-border-radius: 100px;
}
::-webkit-scrollbar-thumb:vertical:active {
background: #4d4c4c; /* Some darker color when you click it */
border-radius: 100px;
-moz-border-radius: 100px;
-webkit-border-radius: 100px;
}
.cet-menubar-menu-container .cet-action-item {
background-color: inherit
}

161
plugins/last-fm/back.js Normal file
View File

@ -0,0 +1,161 @@
const fetch = require('node-fetch');
const md5 = require('md5');
const { shell } = require('electron');
const { setOptions } = require('../../config/plugins');
const registerCallback = require('../../providers/song-info');
const defaultConfig = require('../../config/defaults');
const createFormData = params => {
// creates the body for in the post request
const formData = new URLSearchParams();
for (const key in params) {
formData.append(key, params[key]);
}
return formData;
}
const createQueryString = (params, api_sig) => {
// creates a querystring
const queryData = [];
params.api_sig = api_sig;
for (const key in params) {
queryData.push(`${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`);
}
return '?'+queryData.join('&');
}
const createApiSig = (params, secret) => {
// this function creates the api signature, see: https://www.last.fm/api/authspec
const keys = [];
for (const key in params) {
keys.push(key);
}
keys.sort();
let sig = '';
for (const key of keys) {
if (String(key) === 'format')
continue
sig += `${key}${params[key]}`;
}
sig += secret;
sig = md5(sig);
return sig;
}
const createToken = async ({ api_key, api_root, secret }) => {
// creates and stores the auth token
const data = {
method: 'auth.gettoken',
api_key: api_key,
format: 'json'
};
const api_sig = createApiSig(data, secret);
let response = await fetch(`${api_root}${createQueryString(data, api_sig)}`);
response = await response.json();
return response?.token;
}
const authenticate = async config => {
// asks the user for authentication
config.token = await createToken(config);
setOptions('last-fm', config);
shell.openExternal(`https://www.last.fm/api/auth/?api_key=${config.api_key}&token=${config.token}`);
return config;
}
const getAndSetSessionKey = async config => {
// get and store the session key
const data = {
api_key: config.api_key,
format: 'json',
method: 'auth.getsession',
token: config.token,
};
const api_sig = createApiSig(data, config.secret);
let res = await fetch(`${config.api_root}${createQueryString(data, api_sig)}`);
res = await res.json();
if (res.error)
await authenticate(config);
config.session_key = res?.session?.key;
setOptions('last-fm', config);
return config;
}
const postSongDataToAPI = async (songInfo, config, data) => {
// this sends a post request to the api, and adds the common data
if (!config.session_key)
await getAndSetSessionKey(config);
const postData = {
track: songInfo.title,
duration: songInfo.songDuration,
artist: songInfo.artist,
...(songInfo.album ? { album: songInfo.album } : undefined), // will be undefined if current song is a video
api_key: config.api_key,
sk: config.session_key,
format: 'json',
...data,
};
postData.api_sig = createApiSig(postData, config.secret);
fetch('https://ws.audioscrobbler.com/2.0/', {method: 'POST', body: createFormData(postData)})
.catch(res => {
if (res.response.data.error == 9) {
// session key is invalid, so remove it from the config and reauthenticate
config.session_key = undefined;
setOptions('last-fm', config);
authenticate(config);
}
});
}
const addScrobble = (songInfo, config) => {
// this adds one scrobbled song to last.fm
const data = {
method: 'track.scrobble',
timestamp: ~~((Date.now() - songInfo.elapsedSeconds) / 1000),
};
postSongDataToAPI(songInfo, config, data);
}
const setNowPlaying = (songInfo, config) => {
// this sets the now playing status in last.fm
const data = {
method: 'track.updateNowPlaying',
};
postSongDataToAPI(songInfo, config, data);
}
// this will store the timeout that will trigger addScrobble
let scrobbleTimer = undefined;
const lastfm = async (_win, config) => {
if (!config.api_root) {
// settings are not present, creating them with the default values
config = defaultConfig.plugins['last-fm'];
config.enabled = true;
setOptions('last-fm', config);
}
if (!config.session_key) {
// not authenticated
config = await getAndSetSessionKey(config);
}
registerCallback( songInfo => {
// set remove the old scrobble timer
clearTimeout(scrobbleTimer);
if (!songInfo.isPaused) {
setNowPlaying(songInfo, config);
// scrobble when the song is half way through, or has passed the 4 minute mark
const scrobbleTime = Math.min(Math.ceil(songInfo.songDuration / 2), 4 * 60);
if (scrobbleTime > songInfo.elapsedSeconds) {
// scrobble still needs to happen
const timeToWait = (scrobbleTime - songInfo.elapsedSeconds) * 1000;
scrobbleTimer = setTimeout(addScrobble, timeToWait, songInfo, config);
}
}
});
}
module.exports = lastfm;

View File

@ -0,0 +1,71 @@
const { join } = require("path");
const { ipcMain } = require("electron");
const is = require("electron-is");
const { convert } = require("html-to-text");
const fetch = require("node-fetch");
const { cleanupName } = require("../../providers/song-info");
const { injectCSS } = require("../utils");
module.exports = async (win) => {
injectCSS(win.webContents, join(__dirname, "style.css"));
ipcMain.on("search-genius-lyrics", async (event, extractedSongInfo) => {
const metadata = JSON.parse(extractedSongInfo);
event.returnValue = await fetchFromGenius(metadata);
});
};
const fetchFromGenius = async (metadata) => {
const queryString = `${cleanupName(metadata.artist)} ${cleanupName(
metadata.title
)}`;
let response = await fetch(
`https://genius.com/api/search/multi?per_page=5&q=${encodeURI(queryString)}`
);
if (!response.ok) {
return null;
}
const info = await response.json();
let url = "";
try {
url = info.response.sections.filter((section) => section.type === "song")[0]
.hits[0].result.url;
} catch {
return null;
}
if (is.dev()) {
console.log("Fetching lyrics from Genius:", url);
}
response = await fetch(url);
if (!response.ok) {
return null;
}
const html = await response.text();
const lyrics = convert(html, {
baseElements: {
selectors: ['[class^="Lyrics__Container"]', ".lyrics"],
},
selectors: [
{
selector: "a",
format: "linkFormatter",
},
],
formatters: {
// Remove links by keeping only the content
linkFormatter: (elem, walk, builder) => {
walk(elem.children, builder);
},
},
});
return lyrics;
};
module.exports.fetchFromGenius = fetchFromGenius;

View File

@ -0,0 +1,94 @@
const { ipcRenderer } = require("electron");
const is = require("electron-is");
module.exports = () => {
ipcRenderer.on("update-song-info", (_, extractedSongInfo) => {
const tabList = document.querySelectorAll("tp-yt-paper-tab");
const tabs = {
upNext: tabList[0],
lyrics: tabList[1],
discover: tabList[2],
}
// Check if disabled
if (!tabs.lyrics?.hasAttribute("disabled")) {
return;
}
let hasLyrics = true;
const lyrics = ipcRenderer.sendSync(
"search-genius-lyrics",
extractedSongInfo
);
if (!lyrics) {
// Delete previous lyrics if tab is open and couldn't get new lyrics
checkLyricsContainer(() => {
hasLyrics = false;
setTabsOnclick(undefined);
});
return;
}
if (is.dev()) {
console.log("Fetched lyrics from Genius");
}
enableLyricsTab();
setTabsOnclick(enableLyricsTab);
checkLyricsContainer();
tabs.lyrics.onclick = () => {
const tabContainer = document.querySelector("ytmusic-tab-renderer");
const observer = new MutationObserver((_, observer) => {
checkLyricsContainer(() => observer.disconnect());
});
observer.observe(tabContainer, {
attributes: true,
childList: true,
subtree: true,
});
};
function checkLyricsContainer(callback = () => {}) {
const lyricsContainer = document.querySelector(
'[page-type="MUSIC_PAGE_TYPE_TRACK_LYRICS"] > ytmusic-message-renderer'
);
if (lyricsContainer) {
callback();
setLyrics(lyricsContainer)
}
}
function setLyrics(lyricsContainer) {
lyricsContainer.innerHTML = `<div id="contents" class="style-scope ytmusic-section-list-renderer description ytmusic-description-shelf-renderer genius-lyrics">
${
hasLyrics
? lyrics.replace(/(?:\r\n|\r|\n)/g, "<br/>")
: "Could not retrieve lyrics from genius"
}
</div>
<yt-formatted-string class="footer style-scope ytmusic-description-shelf-renderer" style="align-self: baseline"></yt-formatted-string>`;
if (hasLyrics) {
lyricsContainer.querySelector('.footer').textContent = 'Source: Genius';
enableLyricsTab();
}
}
function setTabsOnclick(callback) {
for (const tab of [tabs.upNext, tabs.discover]) {
if (tab) {
tab.onclick = callback;
}
}
}
function enableLyricsTab() {
tabs.lyrics.removeAttribute("disabled");
tabs.lyrics.removeAttribute("aria-disabled");
}
});
};

View File

@ -0,0 +1,12 @@
/* Disable links in Genius lyrics */
.genius-lyrics a {
color: var(--ytmusic-text-primary);
display: inline-block;
pointer-events: none;
text-decoration: none;
}
.description {
font-size: clamp(1.4rem, 1.1vmax, 3rem) !important;
text-align: center !important;
}

View File

@ -1,24 +1,24 @@
const { triggerAction } = require('../utils');
const { triggerAction } = require("../utils");
const CHANNEL = "navigation";
const ACTIONS = {
NEXT: "next",
BACK: 'back',
}
NEXT: "next",
BACK: "back",
};
function goToNextPage() {
triggerAction(CHANNEL, ACTIONS.NEXT);
triggerAction(CHANNEL, ACTIONS.NEXT);
}
function goToPreviousPage() {
triggerAction(CHANNEL, ACTIONS.BACK);
triggerAction(CHANNEL, ACTIONS.BACK);
}
module.exports = {
CHANNEL: CHANNEL,
ACTIONS: ACTIONS,
global: {
goToNextPage: goToNextPage,
goToPreviousPage: goToPreviousPage,
}
CHANNEL: CHANNEL,
ACTIONS: ACTIONS,
actions: {
goToNextPage: goToNextPage,
goToPreviousPage: goToPreviousPage,
},
};

View File

@ -1,23 +1,26 @@
const path = require("path");
const { injectCSS, listenAction } = require("../utils");
const { ACTIONS, CHANNEL } = require("./actions.js");
const { ACTIONS, CHANNEL } = require("./actions.js");
function handle(win) {
injectCSS(win.webContents, path.join(__dirname, "style.css"));
injectCSS(win.webContents, path.join(__dirname, "style.css"), () => {
win.webContents.send("navigation-css-ready");
});
listenAction(CHANNEL, (event, action) => {
switch (action) {
case ACTIONS.NEXT:
case ACTIONS.NEXT:
if (win.webContents.canGoForward()) {
win.webContents.goForward();
}
break;
case ACTIONS.BACK:
case ACTIONS.BACK:
if (win.webContents.canGoBack()) {
win.webContents.goBack();
}
break;
default:
default:
console.log("Unknown action: " + action);
}
});

View File

@ -1,15 +1,19 @@
const { ipcRenderer } = require("electron");
const { ElementFromFile, templatePath } = require("../utils");
function run() {
const forwardButton = ElementFromFile(
templatePath(__dirname, "forward.html")
);
const backButton = ElementFromFile(templatePath(__dirname, "back.html"));
const menu = document.querySelector("ytmusic-pivot-bar-renderer");
ipcRenderer.on("navigation-css-ready", () => {
const forwardButton = ElementFromFile(
templatePath(__dirname, "forward.html")
);
const backButton = ElementFromFile(templatePath(__dirname, "back.html"));
const menu = document.querySelector("ytmusic-pivot-bar-renderer");
if (menu) {
menu.prepend(backButton, forwardButton);
}
if (menu) {
menu.prepend(backButton, forwardButton);
}
});
}
module.exports = run;

View File

@ -3,7 +3,6 @@
font-size: 20px;
line-height: var(--ytmusic-title-1_-_line-height);
font-weight: 500;
color: #fff;
--yt-endpoint-color: #fff;
--yt-endpoint-hover-color: #fff;
--yt-endpoint-visited-color: #fff;

View File

@ -20,7 +20,7 @@
preserveAspectRatio="xMidYMid meet"
focusable="false"
class="style-scope iron-icon"
style="pointer-events: none; display: block; width: 100%; height: 100%;"
style="pointer-events: none; display: block; width: 100%; height: 100%"
>
<g class="style-scope iron-icon">
<path

View File

@ -1,3 +1,4 @@
.ytmusic-pivot-bar-renderer[tab-id="FEmusic_liked"] {
.ytmusic-pivot-bar-renderer[tab-id="FEmusic_liked"],
.sign-in-link {
display: none !important;
}

View File

@ -1,18 +0,0 @@
const { triggerAction } = require("../utils");
const CHANNEL = "notification";
const ACTIONS = {
NOTIFICATION: "notification",
};
function notify(info) {
triggerAction(CHANNEL, ACTIONS.NOTIFICATION, info);
}
module.exports = {
CHANNEL,
ACTIONS,
global: {
notify,
},
};

View File

@ -1,33 +1,44 @@
const { nativeImage, Notification } = require("electron");
const { Notification } = require("electron");
const is = require("electron-is");
const registerCallback = require("../../providers/song-info");
const { notificationImage } = require("./utils");
const { listenAction } = require("../utils");
const { ACTIONS, CHANNEL } = require("./actions.js");
function notify(info) {
let notificationImage = "assets/youtube-music.png";
if (info.image) {
notificationImage = nativeImage.createFromDataURL(info.image);
}
const notify = (info, options) => {
// Fill the notification with content
const notification = {
title: info.title || "Playing",
body: info.artist,
icon: notificationImage,
icon: notificationImage(info),
silent: true,
urgency: options.urgency,
};
new Notification(notification).show();
}
function listenAndNotify() {
listenAction(CHANNEL, (event, action, imageSrc) => {
switch (action) {
case ACTIONS.NOTIFICATION:
notify(imageSrc);
break;
default:
console.log("Unknown action: " + action);
// Send the notification
const currentNotification = new Notification(notification);
currentNotification.show()
return currentNotification;
};
const setup = (options) => {
let oldNotification;
let currentUrl;
registerCallback(songInfo => {
if (!songInfo.isPaused && (songInfo.url !== currentUrl || options.unpauseNotification)) {
// Close the old notification
oldNotification?.close();
currentUrl = songInfo.url;
// This fixes a weird bug that would cause the notification to be updated instead of showing
setTimeout(() => { oldNotification = notify(songInfo, options) }, 10);
}
});
}
module.exports = listenAndNotify;
module.exports = (win, options) => {
// Register the callback for new song information
is.windows() && options.interactive ?
require("./interactive")(win, options.unpauseNotification) :
setup(options);
};

View File

@ -1,86 +0,0 @@
let videoElement = null;
let image = null;
const observer = new MutationObserver((mutations, observer) => {
if (!videoElement) {
videoElement = document.querySelector("video");
}
if (!image) {
image = document.querySelector(".ytmusic-player-bar.image");
}
if (videoElement !== null && image !== null) {
observer.disconnect();
let notificationImage = null;
videoElement.addEventListener("play", () => {
notify({
title: getTitle(),
artist: getArtist(),
image: notificationImage,
});
});
image.addEventListener("load", () => {
notificationImage = null;
const imageInBase64 = convertImageToBase64(image);
if (image && image.complete && image.naturalHeight !== 0) {
notificationImage = imageInBase64;
}
});
}
});
// Convert an image (DOM element) to base64 string
const convertImageToBase64 = (image, size = 256) => {
image.setAttribute("crossorigin", "anonymous");
const c = document.createElement("canvas");
c.height = size;
c.width = size;
const ctx = c.getContext("2d");
ctx.drawImage(
image,
0,
0,
image.naturalWidth,
image.naturalHeight,
0,
0,
c.width,
c.height
);
const imageInBase64 = c.toDataURL();
return imageInBase64;
};
const getTitle = () => {
const title = document.querySelector(".title.ytmusic-player-bar").textContent;
return title;
};
const getArtist = () => {
const bar = document.querySelectorAll(".subtitle.ytmusic-player-bar")[0];
let artist;
if (bar.querySelectorAll(".yt-simple-endpoint.yt-formatted-string")[0]) {
artist = bar.querySelectorAll(".yt-simple-endpoint.yt-formatted-string")[0]
.textContent;
} else if (bar.querySelectorAll(".byline.ytmusic-player-bar")[0]) {
artist = bar.querySelectorAll(".byline.ytmusic-player-bar")[0].textContent;
}
return artist;
};
const observeVideoAndThumbnail = () => {
observer.observe(document, {
childList: true,
subtree: true,
});
};
module.exports = observeVideoAndThumbnail;

View File

@ -0,0 +1,106 @@
const { notificationImage, icons } = require("./utils");
const getSongControls = require('../../providers/song-controls');
const registerCallback = require("../../providers/song-info");
const is = require("electron-is");
const WindowsToaster = require('node-notifier').WindowsToaster;
const notifier = new WindowsToaster({ withFallback: true });
//store song controls reference on launch
let controls;
let notificationOnUnpause;
module.exports = (win, unpauseNotification) => {
//Save controls and onPause option
const { playPause, next, previous } = getSongControls(win);
controls = { playPause, next, previous };
notificationOnUnpause = unpauseNotification;
let currentUrl;
// Register songInfoCallback
registerCallback(songInfo => {
if (!songInfo.isPaused && (songInfo.url !== currentUrl || notificationOnUnpause)) {
currentUrl = songInfo.url;
sendToaster(songInfo);
}
});
win.webContents.once("closed", () => {
deleteNotification()
});
}
//delete old notification
let toDelete;
function deleteNotification() {
if (toDelete !== undefined) {
// To remove the notification it has to be done this way
const removeNotif = Object.assign(toDelete, {
remove: toDelete.id
})
notifier.notify(removeNotif)
toDelete = undefined;
}
}
//New notification
function sendToaster(songInfo) {
deleteNotification();
//download image and get path
let imgSrc = notificationImage(songInfo, true);
toDelete = {
appID: is.dev() ? undefined : "com.github.th-ch.youtube-music",
title: songInfo.title || "Playing",
message: songInfo.artist,
id: parseInt(Math.random() * 1000000, 10),
icon: imgSrc,
actions: [
icons.previous,
songInfo.isPaused ? icons.play : icons.pause,
icons.next
],
sound: false,
};
//send notification
notifier.notify(
toDelete,
(err, data) => {
// Will also wait until notification is closed.
if (err) {
console.log(`ERROR = ${err.toString()}\n DATA = ${data}`);
}
switch (data) {
//buttons
case icons.previous.normalize():
controls.previous();
return;
case icons.next.normalize():
controls.next();
return;
case icons.play.normalize():
controls.playPause();
// dont delete notification on play/pause
toDelete = undefined;
//manually send notification if not sending automatically
if (!notificationOnUnpause) {
songInfo.isPaused = false;
sendToaster(songInfo);
}
return;
case icons.pause.normalize():
controls.playPause();
songInfo.isPaused = true;
toDelete = undefined;
sendToaster(songInfo);
return;
//Native datatype
case "dismissed":
case "timeout":
deleteNotification();
}
}
);
}

View File

@ -0,0 +1,30 @@
const { urgencyLevels, setOption } = require("./utils");
const is = require("electron-is");
module.exports = (win, options) => [
...(is.linux() ?
[{
label: "Notification Priority",
submenu: urgencyLevels.map(level => ({
label: level.name,
type: "radio",
checked: options.urgency === level.value,
click: () => setOption(options, "urgency", level.value)
})),
}] :
[]),
...(is.windows() ?
[{
label: "Interactive Notifications",
type: "checkbox",
checked: options.interactive,
click: (item) => setOption(options, "interactive", item.checked)
}] :
[]),
{
label: "Show notification on unpause",
type: "checkbox",
checked: options.unpauseNotification,
click: (item) => setOption(options, "unpauseNotification", item.checked)
},
];

View File

@ -0,0 +1,56 @@
const { setMenuOptions } = require("../../config/plugins");
const path = require("path");
const { app } = require("electron");
const fs = require("fs");
const icon = "assets/youtube-music.png";
const tempIcon = path.join(app.getPath("userData"), "tempIcon.png");
module.exports.icons = {
play: "\u{1405}", // ᐅ
pause: "\u{2016}", // ‖
next: "\u{1433}", //
previous: "\u{1438}" //
}
module.exports.setOption = (options, option, value) => {
options[option] = value;
setMenuOptions("notifications", options)
}
module.exports.urgencyLevels = [
{ name: "Low", value: "low" },
{ name: "Normal", value: "normal" },
{ name: "High", value: "critical" },
];
module.exports.notificationImage = function (songInfo, saveIcon = false) {
//return local path to temp icon
if (saveIcon && !!songInfo.image) {
try {
fs.writeFileSync(tempIcon,
centerNativeImage(songInfo.image)
.toPNG()
);
} catch (err) {
console.log(`Error writing song icon to disk:\n${err.toString()}`)
return icon;
}
return tempIcon;
}
//else: return image
return songInfo.image
? centerNativeImage(songInfo.image)
: icon
};
function centerNativeImage(nativeImage) {
const tempImage = nativeImage.resize({ height: 256 });
const margin = Math.max((tempImage.getSize().width - 256), 0);
return tempImage.crop({
x: Math.round(margin / 2),
y: 0,
width: 256, height: 256
})
}

View File

@ -0,0 +1,37 @@
const { Menu, app } = require("electron");
const { setApplicationMenu } = require("../../../menu");
module.exports = (win, options, setOptions, togglePip, isInPip) => {
if (isInPip) {
Menu.setApplicationMenu(Menu.buildFromTemplate([
{
label: "App",
submenu: [
{
label: "Exit Picture in Picture",
click: togglePip,
},
{
label: "Always on top",
type: "checkbox",
checked: options.alwaysOnTop,
click: (item) => {
setOptions({ alwaysOnTop: item.checked });
win.setAlwaysOnTop(item.checked);
},
},
{
label: "Restart",
click: () => {
app.relaunch();
app.quit();
},
},
{ role: "quit" },
],
},
]));
} else {
setApplicationMenu(win);
}
};

View File

@ -0,0 +1,109 @@
const path = require("path");
const { app, ipcMain } = require("electron");
const electronLocalshortcut = require("electron-localshortcut");
const { setOptions, isEnabled } = require("../../config/plugins");
const { injectCSS } = require("../utils");
let isInPiP = false;
let originalPosition;
let originalSize;
let originalFullScreen;
let originalMaximized;
let win;
let options;
const pipPosition = () => (options.savePosition && options["pip-position"]) || [10, 10];
const pipSize = () => (options.saveSize && options["pip-size"]) || [450, 275];
const setLocalOptions = (_options) => {
options = { ...options, ..._options };
setOptions("picture-in-picture", _options);
}
const adaptors = [];
const runAdaptors = () => adaptors.forEach(a => a());
if (isEnabled("in-app-menu")) {
let adaptor = require("./adaptors/in-app-menu");
adaptors.push(() => adaptor(win, options, setLocalOptions, togglePiP, isInPiP));
}
const togglePiP = async () => {
isInPiP = !isInPiP;
setLocalOptions({ isInPiP });
if (isInPiP) {
originalFullScreen = win.isFullScreen();
if (originalFullScreen) win.setFullScreen(false);
originalMaximized = win.isMaximized();
if (originalMaximized) win.unmaximize();
originalPosition = win.getPosition();
originalSize = win.getSize();
win.webContents.on("before-input-event", blockShortcutsInPiP);
win.setFullScreenable(false);
runAdaptors();
win.webContents.send("pip-toggle", true);
app.dock?.hide();
win.setVisibleOnAllWorkspaces(true, {
visibleOnFullScreen: true,
});
app.dock?.show();
if (options.alwaysOnTop) {
win.setAlwaysOnTop(true, "screen-saver", 1);
}
} else {
win.webContents.removeListener("before-input-event", blockShortcutsInPiP);
win.setFullScreenable(true);
runAdaptors();
win.webContents.send("pip-toggle", false);
win.setVisibleOnAllWorkspaces(false);
win.setAlwaysOnTop(false);
if (originalFullScreen) win.setFullScreen(true);
if (originalMaximized) win.maximize();
}
const [x, y] = isInPiP ? pipPosition() : originalPosition;
const [w, h] = isInPiP ? pipSize() : originalSize;
win.setPosition(x, y);
win.setSize(w, h);
win.setWindowButtonVisibility?.(!isInPiP);
};
const blockShortcutsInPiP = (event, input) => {
const key = input.key.toLowerCase();
if (key === "f") {
event.preventDefault();
} else if (key === 'escape') {
togglePiP();
event.preventDefault();
};
};
module.exports = (_win, _options) => {
options ??= _options;
win ??= _win;
setLocalOptions({ isInPiP });
injectCSS(win.webContents, path.join(__dirname, "style.css"));
ipcMain.on("picture-in-picture", async () => {
await togglePiP();
});
if (options.hotkey) {
electronLocalshortcut.register(win, options.hotkey, togglePiP);
}
};
module.exports.setOptions = setLocalOptions;

View File

@ -0,0 +1,90 @@
const { ipcRenderer } = require("electron");
const { getSongMenu } = require("../../providers/dom-elements");
const { ElementFromFile, templatePath } = require("../utils");
function $(selector) { return document.querySelector(selector); }
let menu = null;
const pipButton = ElementFromFile(
templatePath(__dirname, "picture-in-picture.html")
);
const observer = new MutationObserver(() => {
if (!menu) {
menu = getSongMenu();
if (!menu) return;
}
if (menu.contains(pipButton)) return;
const menuUrl = $(
'tp-yt-paper-listbox [tabindex="0"] #navigation-endpoint'
)?.href;
if (menuUrl && !menuUrl.includes("watch?")) return;
menu.prepend(pipButton);
});
global.togglePictureInPicture = () => {
ipcRenderer.send("picture-in-picture");
};
const listenForToggle = () => {
const originalExitButton = $(".exit-fullscreen-button");
const clonedExitButton = originalExitButton.cloneNode(true);
clonedExitButton.onclick = () => togglePictureInPicture();
const appLayout = $("ytmusic-app-layout");
const expandMenu = $('#expanding-menu');
const middleControls = $('.middle-controls');
const playerPage = $("ytmusic-player-page");
const togglePlayerPageButton = $(".toggle-player-page-button");
const fullScreenButton = $(".fullscreen-button");
const player = $('#player');
const onPlayerDblClick = player.onDoubleClick_;
ipcRenderer.on('pip-toggle', (_, isPip) => {
if (isPip) {
$(".exit-fullscreen-button").replaceWith(clonedExitButton);
player.onDoubleClick_ = () => {};
expandMenu.onmouseleave = () => middleControls.click();
if (!playerPage.playerPageOpen_) {
togglePlayerPageButton.click();
}
fullScreenButton.click();
appLayout.classList.add("pip");
} else {
$(".exit-fullscreen-button").replaceWith(originalExitButton);
player.onDoubleClick_ = onPlayerDblClick;
expandMenu.onmouseleave = undefined;
originalExitButton.click();
appLayout.classList.remove("pip");
}
});
}
function observeMenu(options) {
document.addEventListener(
"apiLoaded",
() => {
listenForToggle();
const minButton = $(".player-minimize-button");
// remove native listeners
minButton.replaceWith(minButton.cloneNode(true));
$(".player-minimize-button").onclick = () => {
global.togglePictureInPicture();
setTimeout(() => $('#player').click());
};
// allows easily closing the menu by programmatically clicking outside of it
$("#expanding-menu").removeAttribute("no-cancel-on-outside-click");
// TODO: think about wether an additional button in songMenu is needed
observer.observe($("ytmusic-popup-container"), {
childList: true,
subtree: true,
});
},
{ once: true, passive: true }
);
}
module.exports = observeMenu;

View File

@ -0,0 +1,60 @@
const prompt = require("custom-electron-prompt");
const promptOptions = require("../../providers/prompt-options");
const { setOptions } = require("./back.js");
module.exports = (win, options) => [
{
label: "Always on top",
type: "checkbox",
checked: options.alwaysOnTop,
click: (item) => {
setOptions({ alwaysOnTop: item.checked });
win.setAlwaysOnTop(item.checked);
},
},
{
label: "Save window position",
type: "checkbox",
checked: options.savePosition,
click: (item) => {
setOptions({ savePosition: item.checked });
},
},
{
label: "Save window size",
type: "checkbox",
checked: options.saveSize,
click: (item) => {
setOptions({ saveSize: item.checked });
},
},
{
label: "Hotkey",
type: "checkbox",
checked: options.hotkey,
click: async (item) => {
const output = await prompt({
title: "Picture in Picture Hotkey",
label: "Choose a hotkey for toggling Picture in Picture",
type: "keybind",
keybindOptions: [{
value: "hotkey",
label: "Hotkey",
default: options.hotkey
}],
...promptOptions()
}, win)
if (output) {
const { value, accelerator } = output[0];
setOptions({ [value]: accelerator });
item.checked = !!accelerator;
} else {
// Reset checkbox if prompt was canceled
item.checked = !item.checked;
}
},
}
];

View File

@ -0,0 +1,26 @@
/* improve visibility of the player bar elements */
ytmusic-app-layout.pip ytmusic-player-bar svg,
ytmusic-app-layout.pip ytmusic-player-bar .time-info,
ytmusic-app-layout.pip ytmusic-player-bar yt-formatted-string,
ytmusic-app-layout.pip ytmusic-player-bar .yt-formatted-string {
filter: drop-shadow(2px 4px 6px black);
color: white !important;
fill: white !important;
}
/* improve the style of the player bar expanding menu */
ytmusic-app-layout.pip ytmusic-player-expanding-menu {
border-radius: 30px;
background-color: rgba(0, 0, 0, 0.3);
backdrop-filter: blur(5px) brightness(20%);
}
/* fix volumeHud position when both in-app-menu and PiP are active */
.cet-container ytmusic-app-layout.pip #volumeHud {
top: 22px !important;
}
/* disable the video-toggle button when in PiP mode */
ytmusic-app-layout.pip .video-switch-button {
display: none !important;
}

View File

@ -0,0 +1,51 @@
<div
class="style-scope menu-item ytmusic-menu-popup-renderer"
role="option"
tabindex="-1"
aria-disabled="false"
aria-selected="false"
onclick="togglePictureInPicture()"
>
<div
id="navigation-endpoint"
class="yt-simple-endpoint style-scope ytmusic-menu-navigation-item-renderer"
tabindex="-1"
>
<div
class="icon menu-icon style-scope ytmusic-menu-navigation-item-renderer"
>
<svg
version="1.1"
id="Layer_1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
x="0px"
y="0px"
viewBox="0 0 512 512"
style="enable-background: new 0 0 512 512"
xml:space="preserve"
>
<style type="text/css">
.st0 {
fill: #aaaaaa;
}
</style>
<g id="XMLID_6_">
<path
id="XMLID_11_"
class="st0"
d="M418.5,139.4H232.4v139.8h186.1V139.4z M464.8,46.7H46.3C20.5,46.7,0,68.1,0,93.1v325.9
c0,25.8,21.4,46.3,46.3,46.3h419.4c25.8,0,46.3-20.5,46.3-46.3V93.1C512,67.2,490.6,46.7,464.8,46.7z M464.8,418.9H46.3V92.2h419.4
v326.8H464.8z"
/>
</g>
</svg>
</div>
<div
class="text style-scope ytmusic-menu-navigation-item-renderer"
id="ytmcustom-pip"
>
Picture in picture
</div>
</div>
</div>

View File

@ -0,0 +1,93 @@
const { getSongMenu } = require("../../providers/dom-elements");
const { ElementFromFile, templatePath } = require("../utils");
function $(selector) { return document.querySelector(selector); }
const slider = ElementFromFile(templatePath(__dirname, "slider.html"));
const roundToTwo = n => Math.round(n * 1e2) / 1e2;
const MIN_PLAYBACK_SPEED = 0.07;
const MAX_PLAYBACK_SPEED = 16;
let playbackSpeed = 1;
const updatePlayBackSpeed = () => {
$('video').playbackRate = playbackSpeed;
const playbackSpeedElement = $("#playback-speed-value");
if (playbackSpeedElement) {
playbackSpeedElement.innerHTML = playbackSpeed;
}
};
let menu;
let observingSlider = false;
const observePopupContainer = () => {
const observer = new MutationObserver(() => {
if (!menu) {
menu = getSongMenu();
}
if (menu && menu.lastElementChild.lastElementChild.innerText.startsWith('Stats') && !menu.contains(slider)) {
menu.prepend(slider);
if (!observingSlider) {
setupSliderListener();
observingSlider = true;
}
}
});
observer.observe($('ytmusic-popup-container'), {
childList: true,
subtree: true,
});
};
const observeVideo = () => {
$('video').addEventListener('ratechange', forcePlaybackRate)
$('video').addEventListener('srcChanged', forcePlaybackRate)
}
const setupWheelListener = () => {
slider.addEventListener('wheel', e => {
e.preventDefault();
if (isNaN(playbackSpeed)) {
playbackSpeed = 1;
}
// e.deltaY < 0 means wheel-up
playbackSpeed = roundToTwo(e.deltaY < 0 ?
Math.min(playbackSpeed + 0.01, MAX_PLAYBACK_SPEED) :
Math.max(playbackSpeed - 0.01, MIN_PLAYBACK_SPEED)
);
updatePlayBackSpeed();
// update slider position
$('#playback-speed-slider').value = playbackSpeed;
})
}
function setupSliderListener() {
$('#playback-speed-slider').addEventListener('immediate-value-changed', e => {
playbackSpeed = e.detail.value || MIN_PLAYBACK_SPEED;
if (isNaN(playbackSpeed)) {
playbackSpeed = 1;
}
updatePlayBackSpeed();
})
}
function forcePlaybackRate(e) {
if (e.target.playbackRate !== playbackSpeed) {
e.target.playbackRate = playbackSpeed
}
}
module.exports = () => {
document.addEventListener('apiLoaded', () => {
observePopupContainer();
observeVideo();
setupWheelListener();
}, { once: true, passive: true })
};

View File

@ -0,0 +1,88 @@
<div
class="style-scope menu-item ytmusic-menu-popup-renderer"
role="option"
tabindex="-1"
aria-disabled="false"
aria-selected="false"
>
<div
id="navigation-endpoint"
class="yt-simple-endpoint style-scope ytmusic-menu-navigation-item-renderer"
tabindex="-1"
>
<tp-yt-paper-slider
id="playback-speed-slider"
class="volume-slider style-scope ytmusic-player-bar on-hover"
style="display: inherit !important"
max="2"
min="0"
step="0.125"
dir="ltr"
title="Playback speed"
aria-label="Playback speed"
role="slider"
tabindex="0"
aria-valuemin="0"
aria-valuemax="2"
aria-valuenow="1"
aria-disabled="false"
value="1"
><!--css-build:shady-->
<div id="sliderContainer" class="style-scope tp-yt-paper-slider">
<div class="bar-container style-scope tp-yt-paper-slider">
<tp-yt-paper-progress
id="sliderBar"
aria-hidden="true"
class="style-scope tp-yt-paper-slider"
role="progressbar"
value="1"
aria-valuenow="1"
aria-valuemin="0"
aria-valuemax="2"
aria-disabled="false"
style="touch-action: none"
><!--css-build:shady-->
<div
id="progressContainer"
class="style-scope tp-yt-paper-progress"
>
<div
id="secondaryProgress"
class="style-scope tp-yt-paper-progress"
hidden="true"
style="transform: scaleX(0)"
></div>
<div
id="primaryProgress"
class="style-scope tp-yt-paper-progress"
style="transform: scaleX(0.5)"
></div>
</div>
</tp-yt-paper-progress>
</div>
<dom-if class="style-scope tp-yt-paper-slider"
><template is="dom-if"></template
></dom-if>
<div
id="sliderKnob"
class="slider-knob style-scope tp-yt-paper-slider"
style="left: 50%; touch-action: none"
>
<div
class="slider-knob-inner style-scope tp-yt-paper-slider"
value="1"
></div>
</div>
</div>
<dom-if class="style-scope tp-yt-paper-slider"
><template is="dom-if"></template></dom-if
></tp-yt-paper-slider>
<div
class="text style-scope ytmusic-menu-navigation-item-renderer"
id="ytmcustom-playback-speed"
>
Speed (<span id="playback-speed-value">1</span>)
</div>
</div>
</div>

View File

@ -0,0 +1,24 @@
const { injectCSS } = require("../utils");
const path = require("path");
/*
This is used to determine if plugin is actually active
(not if its only enabled in options)
*/
let enabled = false;
const { globalShortcut } = require('electron');
module.exports = (win, options) => {
enabled = true;
injectCSS(win.webContents, path.join(__dirname, "volume-hud.css"));
if (options.globalShortcuts?.volumeUp) {
globalShortcut.register((options.globalShortcuts.volumeUp), () => win.webContents.send('changeVolume', true));
}
if (options.globalShortcuts?.volumeDown) {
globalShortcut.register((options.globalShortcuts.volumeDown), () => win.webContents.send('changeVolume', false));
}
}
module.exports.enabled = () => enabled;

View File

@ -0,0 +1,250 @@
const { ipcRenderer } = require("electron");
const { setOptions, setMenuOptions, isEnabled } = require("../../config/plugins");
function $(selector) { return document.querySelector(selector); }
let api, options;
module.exports = (_options) => {
options = _options;
document.addEventListener('apiLoaded', e => {
api = e.detail;
ipcRenderer.on('changeVolume', (_, toIncrease) => changeVolume(toIncrease));
ipcRenderer.on('setVolume', (_, value) => setVolume(value));
firstRun();
}, { once: true, passive: true })
};
module.exports.moveVolumeHud = moveVolumeHud;
/** Restore saved volume and setup tooltip */
function firstRun() {
if (typeof options.savedVolume === "number") {
// Set saved volume as tooltip
setTooltip(options.savedVolume);
if (api.getVolume() !== options.savedVolume) {
api.setVolume(options.savedVolume);
}
}
setupPlaybar();
setupLocalArrowShortcuts();
const noVid = $("#main-panel")?.computedStyleMap().get("display").value === "none";
injectVolumeHud(noVid);
if (!noVid) {
setupVideoPlayerOnwheel();
if (!isEnabled('video-toggle')) {
//video-toggle handles hud positioning on its own
const videoMode = () => api.getPlayerResponse().videoDetails?.musicVideoType !== 'MUSIC_VIDEO_TYPE_ATV';
$("video").addEventListener("srcChanged", () => moveVolumeHud(videoMode()));
}
}
// Change options from renderer to keep sync
ipcRenderer.on("setOptions", (_event, newOptions = {}) => {
Object.assign(options, newOptions)
setMenuOptions("precise-volume", options);
});
}
function injectVolumeHud(noVid) {
if (noVid) {
const position = "top: 18px; right: 60px;";
const mainStyle = "font-size: xx-large;";
$(".center-content.ytmusic-nav-bar").insertAdjacentHTML("beforeend",
`<span id="volumeHud" style="${position + mainStyle}"></span>`)
} else {
const position = `top: 10px; left: 10px;`;
const mainStyle = "font-size: xxx-large; webkit-text-stroke: 1px black; font-weight: 600;";
$("#song-video").insertAdjacentHTML('afterend',
`<span id="volumeHud" style="${position + mainStyle}"></span>`)
}
}
let hudMoveTimeout;
function moveVolumeHud(showVideo) {
clearTimeout(hudMoveTimeout);
const volumeHud = $('#volumeHud');
if (!volumeHud) return;
hudMoveTimeout = setTimeout(() => {
volumeHud.style.top = showVideo ? `${($('ytmusic-player').clientHeight - $('video').clientHeight) / 2}px` : 0;
}, 250)
}
let hudFadeTimeout;
function showVolumeHud(volume) {
let volumeHud = $("#volumeHud");
if (!volumeHud) return;
volumeHud.textContent = volume + '%';
volumeHud.style.opacity = 1;
if (hudFadeTimeout) {
clearTimeout(hudFadeTimeout);
}
hudFadeTimeout = setTimeout(() => {
volumeHud.style.opacity = 0;
hudFadeTimeout = null;
}, 2000);
}
/** Add onwheel event to video player */
function setupVideoPlayerOnwheel() {
$("#main-panel").addEventListener("wheel", event => {
event.preventDefault();
// Event.deltaY < 0 means wheel-up
changeVolume(event.deltaY < 0);
});
}
function saveVolume(volume) {
options.savedVolume = volume;
writeOptions();
}
//without this function it would rewrite config 20 time when volume change by 20
let writeTimeout;
function writeOptions() {
if (writeTimeout) clearTimeout(writeTimeout);
writeTimeout = setTimeout(() => {
setOptions("precise-volume", options);
writeTimeout = null;
}, 1000)
}
/** Add onwheel event to play bar and also track if play bar is hovered*/
function setupPlaybar() {
const playerbar = $("ytmusic-player-bar");
playerbar.addEventListener("wheel", event => {
event.preventDefault();
// Event.deltaY < 0 means wheel-up
changeVolume(event.deltaY < 0);
});
// Keep track of mouse position for showVolumeSlider()
playerbar.addEventListener("mouseenter", () => {
playerbar.classList.add("on-hover");
});
playerbar.addEventListener("mouseleave", () => {
playerbar.classList.remove("on-hover");
});
setupSliderObserver();
}
/** Save volume + Update the volume tooltip when volume-slider is manually changed */
function setupSliderObserver() {
const sliderObserver = new MutationObserver(mutations => {
for (const mutation of mutations) {
// This checks that volume-slider was manually set
if (mutation.oldValue !== mutation.target.value &&
(typeof options.savedVolume !== "number" || Math.abs(options.savedVolume - mutation.target.value) > 4)) {
// Diff>4 means it was manually set
setTooltip(mutation.target.value);
saveVolume(mutation.target.value);
}
}
});
// Observing only changes in 'value' of volume-slider
sliderObserver.observe($("#volume-slider"), {
attributeFilter: ["value"],
attributeOldValue: true
});
}
function setVolume(value) {
api.setVolume(value);
// Save the new volume
saveVolume(value);
// change slider position (important)
updateVolumeSlider();
// Change tooltips to new value
setTooltip(value);
// Show volume slider
showVolumeSlider();
// Show volume HUD
showVolumeHud(value);
}
/** if (toIncrease = false) then volume decrease */
function changeVolume(toIncrease) {
// Apply volume change if valid
const steps = Number(options.steps || 1);
setVolume(toIncrease ?
Math.min(api.getVolume() + steps, 100) :
Math.max(api.getVolume() - steps, 0));
}
function updateVolumeSlider() {
// Slider value automatically rounds to multiples of 5
for (const slider of ["#volume-slider", "#expand-volume-slider"]) {
$(slider).value =
options.savedVolume > 0 && options.savedVolume < 5
? 5
: options.savedVolume;
}
}
let volumeHoverTimeoutID;
function showVolumeSlider() {
const slider = $("#volume-slider");
// This class display the volume slider if not in minimized mode
slider.classList.add("on-hover");
// Reset timeout if previous one hasn't completed
if (volumeHoverTimeoutID) {
clearTimeout(volumeHoverTimeoutID);
}
// Timeout to remove volume preview after 3 seconds if playbar isn't hovered
volumeHoverTimeoutID = setTimeout(() => {
volumeHoverTimeoutID = null;
if (!$("ytmusic-player-bar").classList.contains("on-hover")) {
slider.classList.remove("on-hover");
}
}, 3000);
}
// Set new volume as tooltip for volume slider and icon + expanding slider (appears when window size is small)
const tooltipTargets = [
"#volume-slider",
"tp-yt-paper-icon-button.volume",
"#expand-volume-slider",
"#expand-volume"
];
function setTooltip(volume) {
for (target of tooltipTargets) {
$(target).title = `${volume}%`;
}
}
function setupLocalArrowShortcuts() {
if (options.arrowsShortcut) {
window.addEventListener('keydown', (event) => {
switch (event.code) {
case "ArrowUp":
event.preventDefault();
changeVolume(true);
break;
case "ArrowDown":
event.preventDefault();
changeVolume(false);
break;
}
});
}
}

View File

@ -0,0 +1,82 @@
const { enabled } = require("./back");
const { setMenuOptions } = require("../../config/plugins");
const prompt = require("custom-electron-prompt");
const promptOptions = require("../../providers/prompt-options");
function changeOptions(changedOptions, options, win) {
for (option in changedOptions) {
options[option] = changedOptions[option];
}
// Dynamically change setting if plugin is enabled
if (enabled()) {
win.webContents.send("setOptions", changedOptions);
} else { // Fallback to usual method if disabled
setMenuOptions("precise-volume", options);
}
}
module.exports = (win, options) => [
{
label: "Local Arrowkeys Controls",
type: "checkbox",
checked: !!options.arrowsShortcut,
click: item => {
changeOptions({ arrowsShortcut: item.checked }, options, win);
}
},
{
label: "Global Hotkeys",
type: "checkbox",
checked: !!options.globalShortcuts.volumeUp || !!options.globalShortcuts.volumeDown,
click: item => promptGlobalShortcuts(win, options, item)
},
{
label: "Set Custom Volume Steps",
click: () => promptVolumeSteps(win, options)
}
];
// Helper function for globalShortcuts prompt
const kb = (label_, value_, default_) => { return { value: value_, label: label_, default: default_ || undefined }; };
async function promptVolumeSteps(win, options) {
const output = await prompt({
title: "Volume Steps",
label: "Choose Volume Increase/Decrease Steps",
value: options.steps || 1,
type: "counter",
counterOptions: { minimum: 0, maximum: 100, multiFire: true },
width: 380,
...promptOptions()
}, win)
if (output || output === 0) { // 0 is somewhat valid
changeOptions({ steps: output}, options, win);
}
}
async function promptGlobalShortcuts(win, options, item) {
const output = await prompt({
title: "Global Volume Keybinds",
label: "Choose Global Volume Keybinds:",
type: "keybind",
keybindOptions: [
kb("Increase Volume", "volumeUp", options.globalShortcuts?.volumeUp),
kb("Decrease Volume", "volumeDown", options.globalShortcuts?.volumeDown)
],
...promptOptions()
}, win)
if (output) {
let newGlobalShortcuts = {};
for (const { value, accelerator } of output) {
newGlobalShortcuts[value] = accelerator;
}
changeOptions({ globalShortcuts: newGlobalShortcuts }, options, win);
item.checked = !!options.globalShortcuts.volumeUp || !!options.globalShortcuts.volumeDown;
} else {
// Reset checkbox if prompt was canceled
item.checked = !item.checked;
}
}

View File

@ -0,0 +1,32 @@
const is = require("electron-is");
let ignored = {
id: ["volume-slider", "expand-volume-slider"],
types: ["mousewheel", "keydown", "keyup"]
};
function overrideAddEventListener() {
// Save native addEventListener
Element.prototype._addEventListener = Element.prototype.addEventListener;
// Override addEventListener to Ignore specific events in volume-slider
Element.prototype.addEventListener = function (type, listener, useCapture = false) {
if (!(
ignored.id.includes(this.id) &&
ignored.types.includes(type)
)) {
this._addEventListener(type, listener, useCapture);
} else if (is.dev()) {
console.log(`Ignoring event: "${this.id}.${type}()"`);
}
};
}
module.exports = () => {
overrideAddEventListener();
// Restore original function after finished loading to avoid keeping Element.prototype altered
window.addEventListener('load', () => {
Element.prototype.addEventListener = Element.prototype._addEventListener;
Element.prototype._addEventListener = undefined;
ignored = undefined;
}, { once: true });
};

View File

@ -0,0 +1,11 @@
#volumeHud {
z-index: 999;
position: absolute;
transition: opacity 0.6s;
pointer-events: none;
padding: 10px;
}
ytmusic-player[player-ui-state_="MINIPLAYER"] #volumeHud {
top: 0 !important;
}

View File

@ -0,0 +1,15 @@
const { ipcMain, dialog } = require("electron");
module.exports = () => {
ipcMain.handle('qualityChanger', async (_, qualityLabels, currentIndex) => {
return await dialog.showMessageBox({
type: "question",
buttons: qualityLabels,
defaultId: currentIndex,
title: "Choose Video Quality",
message: "Choose Video Quality:",
detail: `Current Quality: ${qualityLabels[currentIndex]}`,
cancelId: -1
})
})
};

View File

@ -0,0 +1,34 @@
const { ElementFromFile, templatePath } = require("../utils");
const { ipcRenderer } = require("electron");
function $(selector) { return document.querySelector(selector); }
const qualitySettingsButton = ElementFromFile(
templatePath(__dirname, "qualitySettingsTemplate.html")
);
module.exports = () => {
document.addEventListener('apiLoaded', setup, { once: true, passive: true });
}
function setup(event) {
const api = event.detail;
$('.top-row-buttons.ytmusic-player').prepend(qualitySettingsButton);
qualitySettingsButton.onclick = function chooseQuality() {
setTimeout(() => $('#player').click());
const qualityLevels = api.getAvailableQualityLevels();
const currentIndex = qualityLevels.indexOf(api.getPlaybackQuality());
ipcRenderer.invoke('qualityChanger', api.getAvailableQualityLabels(), currentIndex).then(promise => {
if (promise.response === -1) return;
const newQuality = qualityLevels[promise.response];
api.setPlaybackQualityRange(newQuality);
api.setPlaybackQuality(newQuality)
});
}
}

View File

@ -0,0 +1,13 @@
<tp-yt-paper-icon-button class="player-quality-button style-scope ytmusic-player" icon="yt-icons:settings"
title="Open player quality changer" aria-label="Open player quality changer" role="button" tabindex="0" aria-disabled="false">
<tp-yt-iron-icon id="icon" class="style-scope tp-yt-paper-icon-button"><svg viewBox="0 0 24 24"
preserveAspectRatio="xMidYMid meet" focusable="false" class="style-scope yt-icon"
style="pointer-events: none; display: block; width: 100%; height: 100%;">
<g class="style-scope yt-icon">
<path
d="M19.43 12.98c.04-.32.07-.64.07-.98s-.03-.66-.07-.98l2.1-1.65c.2-.15.25-.42.13-.64l-2-3.46c-.12-.22-.4-.3-.6-.22l-2.5 1c-.52-.4-1.08-.73-1.7-.98l-.37-2.65c-.06-.24-.27-.42-.5-.42h-4c-.27 0-.48.18-.5.42l-.4 2.65c-.6.25-1.17.6-1.7.98l-2.48-1c-.23-.1-.5 0-.6.22l-2 3.46c-.14.22-.08.5.1.64l2.12 1.65c-.04.32-.07.65-.07.98s.02.66.06.98l-2.1 1.65c-.2.15-.25.42-.13.64l2 3.46c.12.22.4.3.6.22l2.5-1c.52.4 1.08.73 1.7.98l.37 2.65c.04.24.25.42.5.42h4c.25 0 .46-.18.5-.42l.37-2.65c.6-.25 1.17-.6 1.7-.98l2.48 1c.23.1.5 0 .6-.22l2-3.46c.13-.22.08-.5-.1-.64l-2.12-1.65zM12 15.5c-1.93 0-3.5-1.57-3.5-3.5s1.57-3.5 3.5-3.5 3.5 1.57 3.5 3.5-1.57 3.5-3.5 3.5z"
class="style-scope yt-icon"></path>
</g>
</svg>
</tp-yt-iron-icon>
</tp-yt-paper-icon-button>

View File

@ -1,12 +1,8 @@
const { globalShortcut } = require("electron");
const is = require("electron-is");
const electronLocalshortcut = require("electron-localshortcut");
const {
playPause,
nextTrack,
previousTrack,
startSearch
} = require("./youtube.js");
const getSongControls = require("../../providers/song-controls");
const registerMPRIS = require("./mpris");
function _registerGlobalShortcut(webContents, shortcut, action) {
globalShortcut.register(shortcut, () => {
@ -20,12 +16,47 @@ function _registerLocalShortcut(win, shortcut, action) {
});
}
function registerShortcuts(win) {
_registerGlobalShortcut(win.webContents, "MediaPlayPause", playPause);
_registerGlobalShortcut(win.webContents, "MediaNextTrack", nextTrack);
_registerGlobalShortcut(win.webContents, "MediaPreviousTrack", previousTrack);
_registerLocalShortcut(win, "CommandOrControl+F", startSearch);
_registerLocalShortcut(win, "CommandOrControl+L", startSearch);
function registerShortcuts(win, options) {
const songControls = getSongControls(win);
const { playPause, next, previous, search } = songControls;
if (options.overrideMediaKeys) {
_registerGlobalShortcut(win.webContents, "MediaPlayPause", playPause);
_registerGlobalShortcut(win.webContents, "MediaNextTrack", next);
_registerGlobalShortcut(win.webContents, "MediaPreviousTrack", previous);
}
_registerLocalShortcut(win, "CommandOrControl+F", search);
_registerLocalShortcut(win, "CommandOrControl+L", search);
if (is.linux()) registerMPRIS(win);
const { global, local } = options;
const shortcutOptions = { global, local };
for (const optionType in shortcutOptions) {
registerAllShortcuts(shortcutOptions[optionType], optionType);
}
function registerAllShortcuts(container, type) {
for (const action in container) {
if (!container[action]) {
continue; // Action accelerator is empty
}
console.debug(`Registering ${type} shortcut`, container[action], ":", action);
if (!songControls[action]) {
console.warn("Invalid action", action);
continue;
}
if (type === "global") {
_registerGlobalShortcut(win.webContents, container[action], songControls[action]);
} else { // type === "local"
_registerLocalShortcut(win, local[action], songControls[action]);
}
}
}
}
module.exports = registerShortcuts;

53
plugins/shortcuts/menu.js Normal file
View File

@ -0,0 +1,53 @@
const { setMenuOptions } = require("../../config/plugins");
const prompt = require("custom-electron-prompt");
const promptOptions = require("../../providers/prompt-options");
module.exports = (win, options) => [
{
label: "Set Global Song Controls",
click: () => promptKeybind(options, win)
},
{
label: "Override MediaKeys",
type: "checkbox",
checked: options.overrideMediaKeys,
click: item => setOption(options, "overrideMediaKeys", item.checked)
}
];
function setOption(options, key = null, newValue = null) {
if (key && newValue !== null) {
options[key] = newValue;
}
setMenuOptions("shortcuts", options);
}
// Helper function for keybind prompt
const kb = (label_, value_, default_) => { return { value: value_, label: label_, default: default_ }; };
async function promptKeybind(options, win) {
const output = await prompt({
title: "Global Keybinds",
label: "Choose Global Keybinds for Songs Control:",
type: "keybind",
keybindOptions: [ // If default=undefined then no default is used
kb("Previous", "previous", options.global?.previous),
kb("Play / Pause", "playPause", options.global?.playPause),
kb("Next", "next", options.global?.next)
],
height: 270,
...promptOptions()
}, win);
if (output) {
if (!options.global) {
options.global = {};
}
for (const { value, accelerator } of output) {
options.global[value] = accelerator;
}
setOption(options);
}
// else -> pressed cancel
}

139
plugins/shortcuts/mpris.js Normal file
View File

@ -0,0 +1,139 @@
const mpris = require("mpris-service");
const { ipcMain } = require("electron");
const registerCallback = require("../../providers/song-info");
const getSongControls = require("../../providers/song-controls");
const config = require("../../config");
function setupMPRIS() {
const player = mpris({
name: "youtube-music",
identity: "YouTube Music",
canRaise: true,
supportedUriSchemes: ["https"],
supportedMimeTypes: ["audio/mpeg"],
supportedInterfaces: ["player"],
desktopEntry: "youtube-music",
});
return player;
}
function registerMPRIS(win) {
const songControls = getSongControls(win);
const { playPause, next, previous, volumeMinus10, volumePlus10 } = songControls;
try {
const secToMicro = n => Math.round(Number(n) * 1e6);
const microToSec = n => Math.round(Number(n) / 1e6);
const seekTo = e => win.webContents.send("seekTo", microToSec(e.position));
const seekBy = o => win.webContents.send("seekBy", microToSec(o));
const player = setupMPRIS();
ipcMain.on('seeked', (_, t) => player.seeked(secToMicro(t)));
let currentSeconds = 0;
ipcMain.on('timeChanged', (_, t) => currentSeconds = t);
let currentLoopStatus = undefined;
let manuallySwitchingStatus = false;
ipcMain.on("repeatChanged", (_, mode) => {
if (manuallySwitchingStatus)
return;
if (mode === "Repeat off")
currentLoopStatus = "None";
else if (mode === "Repeat one")
currentLoopStatus = "Track";
else if (mode === "Repeat all")
currentLoopStatus = "Playlist";
player.loopStatus = currentLoopStatus;
});
player.on("loopStatus", (status) => {
// switchRepeat cycles between states in that order
const switches = ["None", "Playlist", "Track"];
const currentIndex = switches.indexOf(currentLoopStatus);
const targetIndex = switches.indexOf(status);
// Get a delta in the range [0,2]
const delta = (targetIndex - currentIndex + 3) % 3;
manuallySwitchingStatus = true;
songControls.switchRepeat(delta);
manuallySwitchingStatus = false;
})
player.getPosition = () => secToMicro(currentSeconds)
player.on("raise", () => {
win.setSkipTaskbar(false);
win.show();
});
player.on("play", () => {
if (player.playbackStatus !== 'Playing') {
player.playbackStatus = 'Playing';
playPause()
}
});
player.on("pause", () => {
if (player.playbackStatus !== 'Paused') {
player.playbackStatus = 'Paused';
playPause()
}
});
player.on("playpause", () => {
player.playbackStatus = player.playbackStatus === 'Playing' ? "Paused" : "Playing";
playPause();
});
player.on("next", next);
player.on("previous", previous);
player.on('seek', seekBy);
player.on('position', seekTo);
ipcMain.on('volumeChanged', (_, value) => {
player.volume = value;
});
player.on('volume', (newVolume) => {
if (config.plugins.isEnabled('precise-volume')) {
// With precise volume we can set the volume to the exact value.
win.webContents.send('setVolume', newVolume)
} else {
// With keyboard shortcuts we can only change the volume in increments of 10, so round it.
const deltaVolume = Math.round((newVolume - player.volume) / 10);
if (deltaVolume > 0) {
for (let i = 0; i < deltaVolume; i++)
volumePlus10();
} else {
for (let i = 0; i < -deltaVolume; i++)
volumeMinus10();
}
}
});
registerCallback(songInfo => {
if (player) {
const data = {
'mpris:length': secToMicro(songInfo.songDuration),
'mpris:artUrl': songInfo.imageSrc,
'xesam:title': songInfo.title,
'xesam:artist': [songInfo.artist],
'mpris:trackid': '/'
};
if (songInfo.album) data['xesam:album'] = songInfo.album;
player.metadata = data;
player.seeked(secToMicro(songInfo.elapsedSeconds))
player.playbackStatus = songInfo.isPaused ? "Paused" : "Playing"
}
})
} catch (e) {
console.warn("Error in MPRIS", e);
}
}
module.exports = registerMPRIS;

View File

@ -1,29 +0,0 @@
function _keyboardInput(webContents, key) {
return webContents.sendInputEvent({
type : "keydown",
keyCode: key
});
}
function playPause(webContents) {
return _keyboardInput(webContents, "Space");
}
function nextTrack(webContents) {
return _keyboardInput(webContents, "j");
}
function previousTrack(webContents) {
return _keyboardInput(webContents, "k");
}
function startSearch(webContents) {
return _keyboardInput(webContents, "/");
}
module.exports = {
playPause : playPause,
nextTrack : nextTrack,
previousTrack: previousTrack,
startSearch : startSearch
};

View File

@ -0,0 +1,37 @@
const hark = require("hark/hark.bundle.js");
module.exports = () => {
let isSilent = false;
document.addEventListener("apiLoaded", () => {
const video = document.querySelector("video");
const speechEvents = hark(video, {
threshold: -100, // dB (-100 = absolute silence, 0 = loudest)
interval: 2, // ms
});
const skipSilence = () => {
if (isSilent && !video.paused) {
video.currentTime += 0.2; // in s
}
};
speechEvents.on("speaking", function () {
isSilent = false;
});
speechEvents.on("stopped_speaking", function () {
if (!(video.paused || video.seeking || video.ended)) {
isSilent = true;
skipSilence();
}
});
video.addEventListener("play", function () {
skipSilence();
});
video.addEventListener("seeked", function () {
skipSilence();
});
});
};

View File

@ -0,0 +1,51 @@
const fetch = require("node-fetch");
const is = require("electron-is");
const { ipcMain } = require("electron");
const defaultConfig = require("../../config/defaults");
const { sortSegments } = require("./segments");
let videoID;
module.exports = (win, options) => {
const { apiURL, categories } = {
...defaultConfig.plugins.sponsorblock,
...options,
};
ipcMain.on("video-src-changed", async (_, data) => {
videoID = JSON.parse(data)?.videoDetails?.videoId;
const segments = await fetchSegments(apiURL, categories);
win.webContents.send("sponsorblock-skip", segments);
});
};
const fetchSegments = async (apiURL, categories) => {
const sponsorBlockURL = `${apiURL}/api/skipSegments?videoID=${videoID}&categories=${JSON.stringify(
categories
)}`;
try {
const resp = await fetch(sponsorBlockURL, {
method: "GET",
headers: {
"Content-Type": "application/json",
},
redirect: "follow",
});
if (resp.status !== 200) {
return [];
}
const segments = await resp.json();
const sortedSegments = sortSegments(
segments.map((submission) => submission.segment)
);
return sortedSegments;
} catch (e) {
if (is.dev()) {
console.log('error on sponsorblock request:', e);
}
return [];
}
};

View File

@ -0,0 +1,31 @@
const { ipcRenderer } = require("electron");
const is = require("electron-is");
let currentSegments = [];
module.exports = () => {
ipcRenderer.on("sponsorblock-skip", (_, segments) => {
currentSegments = segments;
});
document.addEventListener('apiLoaded', () => {
const video = document.querySelector('video');
video.addEventListener('timeupdate', e => {
currentSegments.forEach((segment) => {
if (
e.target.currentTime >= segment[0] &&
e.target.currentTime < segment[1]
) {
e.target.currentTime = segment[1];
if (is.dev()) {
console.log("SponsorBlock: skipping segment", segment);
}
}
});
})
// Reset segments on song end
video.addEventListener('emptied', () => currentSegments = []);
}, { once: true, passive: true })
};

View File

@ -0,0 +1,29 @@
// Segments are an array [ [start, end], … ]
module.exports.sortSegments = (segments) => {
segments.sort((segment1, segment2) =>
segment1[0] === segment2[0]
? segment1[1] - segment2[1]
: segment1[0] - segment2[0]
);
const compiledSegments = [];
let currentSegment;
segments.forEach((segment) => {
if (!currentSegment) {
currentSegment = segment;
return;
}
if (currentSegment[1] < segment[0]) {
compiledSegments.push(currentSegment);
currentSegment = segment;
return;
}
currentSegment[1] = Math.max(currentSegment[1], segment[1]);
});
compiledSegments.push(currentSegment);
return compiledSegments;
};

View File

@ -0,0 +1,36 @@
const { test, expect } = require("@playwright/test");
const { sortSegments } = require("../segments");
test("Segment sorting", () => {
expect(
sortSegments([
[0, 3],
[7, 8],
[5, 6],
])
).toEqual([
[0, 3],
[5, 6],
[7, 8],
]);
expect(
sortSegments([
[0, 5],
[6, 8],
[4, 6],
])
).toEqual([[0, 8]]);
expect(
sortSegments([
[0, 6],
[7, 8],
[4, 6],
])
).toEqual([
[0, 6],
[7, 8],
]);
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 250 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 265 B

View File

@ -0,0 +1,53 @@
const getSongControls = require('../../providers/song-controls');
const registerCallback = require('../../providers/song-info');
const path = require('path');
let controls;
let currentSongInfo;
module.exports = win => {
const { playPause, next, previous } = getSongControls(win);
controls = { playPause, next, previous };
registerCallback(songInfo => {
//update currentsonginfo for win.on('show')
currentSongInfo = songInfo;
// update thumbar
setThumbar(win, songInfo);
});
// need to set thumbar again after win.show
win.on("show", () => {
setThumbar(win, currentSongInfo)
})
};
function setThumbar(win, songInfo) {
// Wait for song to start before setting thumbar
if (!songInfo?.title) {
return;
}
// Win32 require full rewrite of components
win.setThumbarButtons([
{
tooltip: 'Previous',
icon: get('backward.png'),
click() { controls.previous(win.webContents); }
}, {
tooltip: 'Play/Pause',
// Update icon based on play state
icon: songInfo.isPaused ? get('play.png') : get('pause.png'),
click() { controls.playPause(win.webContents); }
}, {
tooltip: 'Next',
icon: get('forward.png'),
click() { controls.next(win.webContents); }
}
]);
}
// Util
function get(file) {
return path.join(__dirname, "assets", file);
}

86
plugins/touchbar/back.js Normal file
View File

@ -0,0 +1,86 @@
const { TouchBar } = require("electron");
const {
TouchBarButton,
TouchBarLabel,
TouchBarSpacer,
TouchBarSegmentedControl,
TouchBarScrubber,
} = TouchBar;
const registerCallback = require("../../providers/song-info");
const getSongControls = require("../../providers/song-controls");
// Songtitle label
const songTitle = new TouchBarLabel({
label: "",
});
// This will store the song controls once available
let controls = [];
// This will store the song image once available
const songImage = {};
// Pause/play button
const pausePlayButton = new TouchBarButton();
// The song control buttons (control functions are in the same order)
const buttons = new TouchBarSegmentedControl({
mode: "buttons",
segments: [
new TouchBarButton({
label: "⏮",
}),
pausePlayButton,
new TouchBarButton({
label: "⏭",
}),
new TouchBarButton({
label: "👎",
}),
new TouchBarButton({
label: "👍",
}),
],
change: (i) => controls[i](),
});
// This is the touchbar object, this combines everything with proper layout
const touchBar = new TouchBar({
items: [
new TouchBarScrubber({
items: [songImage, songTitle],
continuous: false,
}),
new TouchBarSpacer({
size: "flexible",
}),
buttons,
],
});
module.exports = (win) => {
const { playPause, next, previous, like, dislike } = getSongControls(win);
// If the page is ready, register the callback
win.once("ready-to-show", () => {
controls = [previous, playPause, next, like, dislike];
// Register the callback
registerCallback((songInfo) => {
// Song information changed, so lets update the touchBar
// Set the song title
songTitle.label = songInfo.title;
// Changes the pause button if paused
pausePlayButton.label = songInfo.isPaused ? "▶️" : "⏸";
// Get image source
songImage.icon = songInfo.image
? songInfo.image.resize({ height: 23 })
: null;
win.setTouchBar(touchBar);
});
});
};

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