Compare commits

...

1449 Commits

Author SHA1 Message Date
c94b22b82c Bump version to 3.5.3 2024-09-17 21:32:22 +09:00
cab3cb49f0 chore(deps): update dependency electron to v32.1.0 2024-09-17 21:31:29 +09:00
e42084f008 fix(deps): update dependency @floating-ui/dom to v1.6.11 2024-09-17 21:30:11 +09:00
adca273ec3 chore(deps): update dependency typescript to v5.6.2 2024-09-17 21:28:03 +09:00
91dceb3c22 chore(deps): update playwright monorepo to v1.47.1 2024-09-17 21:27:47 +09:00
216e76f4a1 fix(music-together): fix ? operator 2024-09-17 21:09:30 +09:00
178bfa483f fix: openToast to toastService 2024-09-17 21:05:35 +09:00
10ecf5d2fe fix(src/index): fix typo 2024-09-17 20:40:23 +09:00
7099b81296 fix(src/index): ignore eslint error 2024-09-17 20:40:23 +09:00
1f15376b00 chore(deps): update dependency vite to v5.4.6 2024-09-17 20:39:32 +09:00
02b7a39753 chore(deps): update dependency eslint to v8.57.1 2024-09-17 20:38:38 +09:00
6edc84a8bd chore(deps): update dependency rollup to v4.21.3 2024-09-17 20:38:19 +09:00
11a0d39064 fix(song-info-front): fix nullable issue 2024-09-17 20:27:11 +09:00
d5a5ed35b6 fix: fix trustedHTML issue
- (Maybe) fix #2339, caused by YouTube's A/B testing
2024-09-17 20:05:22 +09:00
dbb9e95b32 fix(deps): update dependency i18next to v23.15.1 2024-09-17 18:27:27 +09:00
d4c8a4320d chore(deps): update typescript-eslint monorepo to v8.6.0 2024-09-17 18:27:05 +09:00
68d4f38e41 chore(i18n): Translated using Weblate (Hungarian)
Currently translated at 94.7% (362 of 382 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/hu/
2024-09-15 22:09:12 +00:00
2204784e89 chore(i18n): Translated using Weblate (Icelandic)
Currently translated at 92.9% (355 of 382 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/is/
2024-09-15 22:09:12 +00:00
c3b995b0a8 chore(i18n): Translated using Weblate (Hebrew)
Currently translated at 6.0% (23 of 382 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/he/
2024-09-11 22:09:24 +02:00
ed0a344077 chore(i18n): Translated using Weblate (Polish)
Currently translated at 95.2% (364 of 382 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/pl/
2024-09-09 22:09:15 +00:00
199d912823 Update changelog for v3.5.2 2024-09-07 12:27:30 +00:00
089eff3152 Revert "chore(deps): update dependency electron-builder to v25"
This reverts commit fe4c89c349.
2024-09-07 20:22:27 +09:00
306ee8dba5 Bump version to 3.5.2 2024-09-07 19:09:15 +09:00
a4992bafb2 fix(synced-lyric): fix timestamp
- Close #2323
- Close #2379
2024-09-07 19:06:52 +09:00
5b004eedff fix(song-info): fix regex 2024-09-07 18:40:24 +09:00
2a66076d31 fix(synced-lyric): optimize logic 2024-09-07 18:37:37 +09:00
f48e46d29c chore(deps): update dependency eslint-plugin-import to v2.30.0 2024-09-07 18:29:22 +09:00
20296f5463 chore(deps): update dependency rollup to v4.21.2 2024-09-07 18:29:16 +09:00
fe4c89c349 chore(deps): update dependency electron-builder to v25 2024-09-07 18:29:09 +09:00
3640527c8c fix(synced-lyrics): LRCLIB returns 0 results if album is undefined
- inspired by #2381
2024-09-07 18:28:13 +09:00
3326582a16 chore(deps): update dependency electron to v32 2024-09-07 18:21:41 +09:00
5dcb9fe9ba fix(deps): update dependency i18next to v23.14.0 2024-09-07 18:19:15 +09:00
336fa1e6fd fix(deps): update dependency youtubei.js to v10.4.0 2024-09-07 18:19:09 +09:00
3679a109d6 chore(deps): update dependency esbuild to v0.23.1 2024-09-07 18:15:01 +09:00
5290ed3de2 chore(deps): update playwright monorepo to v1.47.0 2024-09-07 18:14:40 +09:00
fe5195714f chore(deps): update typescript-eslint monorepo to v8.4.0 (#2401)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-07 18:14:27 +09:00
8eb846262d chore(deps): update dependency @total-typescript/ts-reset to v0.6.1 (#2396)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-07 18:09:00 +09:00
e9a1c2a91f chore(deps): update dependency electron to v31.5.0 (#2397)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-07 18:08:41 +09:00
2d1f78b383 chore(deps): update dependency eslint-import-resolver-typescript to v3.6.3 (#2376)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-07 18:06:07 +09:00
1899064fd3 chore(deps): update dependency discord-api-types to v0.37.100 (#2394)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-07 18:06:00 +09:00
e0280e5fe2 fix(deps): update dependency electron-updater to v6.3.4 (#2395)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-07 18:05:54 +09:00
d577e0fba6 chore(deps): update dependency @babel/runtime to v7.25.6 (#2388)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-07 17:26:24 +09:00
37577c2f7f chore(deps): update dependency vite-plugin-inspect to v0.8.7 (#2389)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-07 17:26:16 +09:00
c880f0a4eb chore(i18n): Translated using Weblate (Portuguese)
Currently translated at 100.0% (382 of 382 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/pt/
2024-09-05 21:09:15 +02:00
4875955914 chore(deps): update dependency discord-api-types to v0.37.99 (#2374)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-04 23:47:50 +09:00
5b28c780bd chore(deps): update dependency vite to v5.4.3 (#2377)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-04 23:47:42 +09:00
4db2674b15 chore(i18n): Translated using Weblate (Greek)
Currently translated at 52.6% (201 of 382 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/el/
2024-09-02 23:09:12 +00:00
Sen
a454a0163f chore(i18n): Translated using Weblate (Dutch)
Currently translated at 74.0% (283 of 382 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/nl/
2024-08-31 21:09:31 +02:00
61eb28e780 fix: incorrect regex when splitting artistName (#2378)
Fixes the incorrect regex used to split a string in the form of `Name1 & Name2` or `Name1, Name2`.

Previously the regex was actually splitting on `Name1 &, Name2`...
2024-08-29 07:48:18 +09:00
e165e64952 chore(i18n): Translated using Weblate (Hungarian)
Currently translated at 93.7% (358 of 382 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/hu/
2024-08-28 13:09:22 +00:00
f380822e11 chore(deps): update dependency @babel/runtime to v7.25.4 (#2373)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-28 12:22:29 +09:00
6b1995145a synced-lyrics: make the lyrics search more reliable (#2343)
* fix: comparing multiple artists on a single track

* fix: get song info on startup

* chore: also split on commas

* chore: re-apply .toLowerCase() on the artist names

* chore: remove redundant code

* chore: attempt at improving the initial videodata

* oops

* eureka!

* stuff
2024-08-28 12:21:58 +09:00
9317e99f43 fix(deps): update dependency solid-js to v1.8.22 (#2354)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-28 12:20:37 +09:00
66d05d8683 chore(deps): update typescript-eslint monorepo to v8.3.0 (#2350)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-28 12:20:26 +09:00
545a3a4bb6 fix(deps): update dependency electron-debug to v4.0.1 (#2349)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-28 12:20:07 +09:00
04a6d16dbe chore(deps): update dependency electron to v31.4.0 (#2356)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-28 12:19:53 +09:00
3c36477b1e fix: hide native-controls on linux when in-app-menu is used (#2366) 2024-08-28 12:19:30 +09:00
c5c191492e fix: detect the upgrade btn using the icon (#2364) 2024-08-23 07:13:55 +09:00
b12e2f607c chore(i18n): Translated using Weblate (Filipino)
Currently translated at 86.6% (331 of 382 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/fil/
2024-08-20 03:09:10 +00:00
1d77ad6de4 fix: exclude build-id files from rpm (#2361) 2024-08-19 07:46:05 +09:00
25bd26d7f3 chore(i18n): Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (382 of 382 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/zh_Hant/
2024-08-17 12:09:10 +02:00
d11d0abe73 chore(i18n): Translated using Weblate (Japanese)
Currently translated at 100.0% (382 of 382 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ja/
2024-08-17 12:09:10 +02:00
8a643c465d chore(i18n): Translated using Weblate (Estonian)
Currently translated at 18.8% (72 of 382 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/et/
2024-08-15 22:09:31 +00:00
233673b8d8 chore(i18n): Translated using Weblate (Estonian)
Currently translated at 14.1% (54 of 382 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/et/
2024-08-13 21:09:13 +02:00
5a448fab31 chore(i18n): Translated using Weblate (Catalan)
Currently translated at 100.0% (382 of 382 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ca/
2024-08-13 21:09:12 +02:00
42e8262cda fix(deps): update dependency i18next to v23.12.3 (#2352)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-13 11:57:27 +09:00
f64769b1d3 fix(deps): update dependency @floating-ui/dom to v1.6.10 (#2340)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-12 12:12:08 +09:00
e12998761b fix(deps): update dependency electron-updater to v6.3.3 (#2347)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-12 12:11:55 +09:00
2e20fa83b8 chore(i18n): Translated using Weblate (German)
Currently translated at 99.2% (379 of 382 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/de/
2024-08-11 10:09:24 +00:00
5149757af3 chore(i18n): Translated using Weblate (German)
Currently translated at 99.2% (379 of 382 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/de/
2024-08-11 10:09:24 +00:00
655741f108 chore(i18n): Translated using Weblate (German)
Currently translated at 96.3% (368 of 382 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/de/
2024-08-10 11:41:12 +02:00
4e58571ad0 chore(i18n): Translated using Weblate (German)
Currently translated at 96.3% (368 of 382 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/de/
2024-08-10 11:41:12 +02:00
1e4a615b47 chore(i18n): Translated using Weblate (German)
Currently translated at 94.7% (362 of 382 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/de/
2024-08-10 11:39:20 +02:00
dedcf0c9ff fix(deps): update dependency solid-js to v1.8.20 (#2345)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-10 10:58:28 +09:00
a84a7d236a chore(deps): update dependency vite to v5.4.0 (#2342)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-10 10:54:05 +09:00
e56b4b21f0 chore(i18n): Update translation files
Updated by "Remove blank strings" hook in Weblate.

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/
2024-08-09 16:09:15 +02:00
361f9e42bd chore(i18n): Translated using Weblate (Malay)
Currently translated at 19.6% (75 of 382 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ms/
2024-08-09 16:09:13 +02:00
918736d2ca chore(i18n): Translated using Weblate (German)
Currently translated at 94.2% (360 of 382 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/de/
2024-08-09 16:09:12 +02:00
8f3d5b08ac chore(i18n): Translated using Weblate (Russian)
Currently translated at 97.3% (372 of 382 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ru/
2024-08-08 00:09:19 +02:00
4ca327d801 chore(deps): update typescript-eslint monorepo to v8.0.1 (#2335)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-07 23:03:13 +09:00
8d0aa057ad fix(deps): update dependency @floating-ui/dom to v1.6.9 (#2337)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-07 23:02:23 +09:00
b7ffee089b chore(deps): update playwright monorepo to v1.46.0 (#2336)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-07 23:02:12 +09:00
d72b994f66 chore(README): Translation README to Russian and adding Synced Lyrics to main README (#2338)
* Translation of README.md to Russian and adding Synced Lyrics to default README.md

* Syntax fixes

* Sorting of Synced Lyrics Alphabetically
2024-08-07 23:01:49 +09:00
e6dafdb068 chore(i18n): Update translation files
Updated by "Remove blank strings" hook in Weblate.

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/
2024-08-06 11:09:21 +02:00
14886dd4bd chore(i18n): Translated using Weblate (Catalan)
Currently translated at 100.0% (382 of 382 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ca/
2024-08-06 11:09:17 +02:00
c9f2f88bac chore(i18n): Translated using Weblate (Russian)
Currently translated at 97.3% (372 of 382 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ru/
2024-08-06 11:09:17 +02:00
1eabbc0bbe chore(i18n): Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (382 of 382 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/zh_Hans/
2024-08-05 09:09:19 +02:00
32a572b35a fix(downloader): fix playabilityStatus 2024-08-04 16:33:28 +09:00
59a5679cbb fix(cache): use cacheNoArgs for better performance 2024-08-04 16:31:07 +09:00
ac51f798c3 fix(synced-lyric): fix album_name 2024-08-04 15:49:30 +09:00
7599cc694a Revert "fix(MPRIS): Prevents player to start with invalid MPRIS interface (#1996)"
This reverts commit eaf9d310aa.

Fix #2225
2024-08-04 15:26:14 +09:00
53595654b1 chore(adblocker): add comment 2024-08-04 14:50:14 +09:00
7656c41dbc fix(adblocker/inplayer): fix Response.prototype.json
fix #2310
2024-08-04 14:36:10 +09:00
ff0c5b87c9 chore(i18n): Translated using Weblate (Estonian)
Currently translated at 2.8% (11 of 382 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/et/
2024-08-03 22:09:19 +00:00
506c95740a chore(i18n): Translated using Weblate (Vietnamese)
Currently translated at 99.4% (380 of 382 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/vi/
2024-08-03 22:09:18 +00:00
575a42e28a chore(i18n): Translated using Weblate (Indonesian)
Currently translated at 100.0% (382 of 382 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/id/
2024-08-03 22:09:17 +00:00
dcdc6a825f chore(i18n): Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (382 of 382 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/zh_Hant/
2024-08-03 22:09:16 +00:00
0a41bb1cd6 chore(i18n): Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (382 of 382 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/zh_Hant/
2024-08-03 22:09:16 +00:00
72a4736dc9 chore(i18n): Translated using Weblate (Greek)
Currently translated at 47.3% (181 of 382 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/el/
2024-08-03 22:09:15 +00:00
f2b1e6b6bf chore(deps): update dependency rollup to v4.20.0 (#2326)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-03 18:47:56 +09:00
bc0e28ad6d chore(i18n): Added translation using Weblate (Estonian) 2024-08-02 23:59:14 +02:00
8ebae91c02 chore(i18n): Translated using Weblate (Hungarian)
Currently translated at 93.7% (358 of 382 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/hu/
2024-08-02 23:59:13 +02:00
954ad90733 chore(i18n): Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (382 of 382 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/zh_Hant/
2024-08-02 23:59:13 +02:00
5af0643788 chore(i18n): Translated using Weblate (French)
Currently translated at 100.0% (382 of 382 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/fr/
2024-08-02 23:59:13 +02:00
be633ac1f2 chore(i18n): Translated using Weblate (Chinese (Traditional))
Currently translated at 99.7% (381 of 382 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/zh_Hant/
2024-08-02 21:58:41 +02:00
0d047c1fd5 chore(i18n): Translated using Weblate (Chinese (Traditional))
Currently translated at 99.7% (381 of 382 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/zh_Hant/
2024-08-02 21:58:41 +02:00
e8b1aca629 chore(i18n): Translated using Weblate (Turkish)
Currently translated at 100.0% (382 of 382 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/tr/
2024-08-02 21:58:41 +02:00
5b9bacf390 chore(i18n): Translated using Weblate (Filipino)
Currently translated at 85.3% (326 of 382 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/fil/
2024-08-02 14:09:23 +02:00
ccd16f4a5f chore(i18n): Translated using Weblate (Chinese (Traditional))
Currently translated at 93.4% (357 of 382 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/zh_Hant/
2024-08-02 14:09:22 +02:00
02e519dab3 chore(i18n): Translated using Weblate (Spanish)
Currently translated at 100.0% (382 of 382 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/es/
2024-08-02 14:09:21 +02:00
473ea78f12 synced-lyrics: fix album name? 2024-08-01 15:46:53 +03:00
e7f366b770 Update changelog for v3.5.1 2024-08-01 11:49:06 +00:00
66816ac42d Bump version to 3.5.1 2024-08-01 20:39:44 +09:00
08b985f2ab chore(i18n): Translated using Weblate (Korean)
Currently translated at 100.0% (382 of 382 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ko/
2024-08-01 13:38:36 +02:00
747bde2136 fix(synced-lyrics): fix lyric load
fix #2295
2024-08-01 20:19:08 +09:00
eabc28b39f fix(wait-for-element): add 100ms timeout for improve performance 2024-08-01 20:19:08 +09:00
3537dc19ee chore(i18n): Translated using Weblate (Hungarian)
Currently translated at 97.8% (358 of 366 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/hu/
2024-08-01 10:57:05 +00:00
6afeb60557 chore(i18n): Translated using Weblate (Vietnamese)
Currently translated at 100.0% (366 of 366 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/vi/
2024-08-01 10:57:04 +00:00
71115dedee chore(i18n): Translated using Weblate (Italian)
Currently translated at 100.0% (366 of 366 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/it/
2024-08-01 10:57:04 +00:00
8750b54f76 fix(synced-lyrics): fix i18n 2024-08-01 19:56:32 +09:00
482a1c5073 fix(deps): update dependency youtubei.js to v10.3.0 (#2306)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-01 19:27:58 +09:00
c8d516c40b fix: Window gets stuck offscreen in some instances (#2303)
Improved offscreen detection logic, fixes th-ch#1894
2024-08-01 19:27:01 +09:00
c1ad168c32 fix: Incorrect window size on multi-monitor scaled displays (#2302)
see discussion on th-ch#2258
2024-08-01 19:26:37 +09:00
5f5be5d02f chore(deps): update dependency rollup to v4.19.2 (#2304)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-01 19:25:59 +09:00
61ef56dccc chore: enable sourcemaps in dev 2024-08-01 11:02:21 +03:00
a73b5acc75 chore(deps): update typescript-eslint monorepo to v8 (major) (#2297)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-01 16:37:08 +09:00
877573532c ts-fix: disambiguate ElectronStore typings 2024-08-01 10:10:52 +03:00
7b033b5caf fix(ambient-mode): fix ambient-mode not working for videos after restart (#2294)
* Fix Ambient Mode not working for videos after restart (#2255)

This should fix https://github.com/th-ch/youtube-music/issues/1641

* fix: fix waitForElement

---------

Co-authored-by: craftgeil <80261988+craftgeil@users.noreply.github.com>
2024-07-31 22:08:45 +09:00
8924ec29d3 fix(deps): update dependency @xhayper/discord-rpc to v1.2.0 (#2291)
* fix(deps): update dependency @xhayper/discord-rpc to v1.2.0

* fix: discord-rpc

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: JellyBrick <shlee1503@naver.com>
2024-07-31 21:57:37 +09:00
23e688aaf8 Update changelog for v3.5.0 2024-07-31 12:04:22 +00:00
9b3cbe8e01 Bump version to 3.5.0 2024-07-31 20:53:02 +09:00
67a89e8ed4 chore(i18n): Translated using Weblate (Korean)
Currently translated at 100.0% (366 of 366 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ko/
2024-07-31 13:51:24 +02:00
464a2b94ea fix: bump electron-builder version to 6.3.2 2024-07-31 20:37:38 +09:00
9357a15116 fix(synced-lyrics): fix type error 2024-07-31 20:32:34 +09:00
ee820bb01c Delete test-results directory 2024-07-31 19:55:51 +09:00
6b81735811 chore(i18n): Translated using Weblate (French)
Currently translated at 100.0% (357 of 357 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/fr/
2024-07-31 12:54:43 +02:00
8ce91b143a plugin: Synced Lyrics (#2207)
* Added Plugin File

* Added Logic

* Known issue

* Finished Backend part

* Before cleanup

* Added Style
Removed log

* Fixed time and visibility issues

* Changed lyrics style

* Changed way lyrics are selected

* Fix

* Added style lyrics options

* Cleanup

* Fix lyrics styling
Changed how lyrics status are changed

* Moved code to make file more readable

* Change Tab Size

* Fixed issue with overlapping lyrics

* Removed debug console.log

* Added style adaptation for music videos

* Changed file indent

* Revered back to original pnpm file

* Removed unnecessary option

* Fix lyrics status bug
Removed leftover logs

* Started to implement fetching for genius lyrics

* feat(synced-lyrics): add `addedVersion` field

* Made changes according to feedbacks

* fix: add a delay of 300ms to the current time

- Since the transition takes 300ms, we need to add a delay of 300ms to the current time

* Removed test about genius.com scraping

* Removed 300ms delay

* chore: cleaned up the code

* Specified path and variable

* chore: always enable lyrics tab

* chore: use SolidJS to render the lyrics

* chore: remove useless signal

* chore: feature-parity with original PR (+some nice stuff)

* recreate lock file

* show json decode error

* feat(synced-lyrics): improve ui
- Change type assertion code
- Replace span to `yt-formatted-string`
- Add refetch button

* chore: make the lyric styling a solidjs effect

* feat: i18n

* chore: apply suggestion

---------

Co-authored-by: Su-Yong <simssy2205@gmail.com>
Co-authored-by: JellyBrick <shlee1503@naver.com>
Co-authored-by: Angelos Bouklis <53124886+ArjixWasTaken@users.noreply.github.com>
2024-07-31 19:54:21 +09:00
116dbad9bc chore(deps): update dependency electron to v31.3.1 (#2290)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-31 19:52:47 +09:00
977af3d617 chore(deps): update typescript-eslint monorepo to v7.18.0 (#2292)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-31 19:52:38 +09:00
6da8defc73 chore(i18n): Translated using Weblate (Sinhala)
Currently translated at 4.4% (16 of 357 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/si/
2024-07-29 01:09:20 +00:00
0e93a963e1 chore(i18n): Translated using Weblate (Korean)
Currently translated at 100.0% (357 of 357 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ko/
2024-07-29 01:09:19 +00:00
1e98b2e75a fix(deps): update dependency youtubei.js to v10.2.0 (#2285)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-29 01:30:01 +09:00
6f5f13a840 chore(deps): update dependency electron to v31.3.0 (#2282)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-28 14:10:07 +00:00
822bcedadf chore(deps): update typescript-eslint monorepo to v7.17.0 (#2283)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-28 14:09:48 +00:00
2b6aea82c3 fix(deps): update dependency solid-js to v1.8.19 (#2280)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-28 19:21:49 +09:00
4f4efb407e fix(deps): update dependency @xhayper/discord-rpc to v1.1.4 (#2279)
* fix(deps): update dependency @xhayper/discord-rpc to v1.1.4

* Update and rename @xhayper__discord-rpc@1.1.2.patch to @xhayper__discord-rpc@1.1.4.patch

* Update package.json

* fix: update pnpm-lock.yaml

* fix: use Listening instead of Playing

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: JellyBrick <shlee1503@naver.com>
2024-07-28 19:21:35 +09:00
6159e0e652 chore(deps): update dependency @babel/runtime to v7.25.0 (#2281)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-28 19:07:01 +09:00
3957e06174 fix(deps): update dependency @floating-ui/dom to v1.6.8 (#2278)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-28 19:06:26 +09:00
c78f823b9b Fix: Incorrect window size on scaled displays (#2258)
fix th-ch#1716
2024-07-28 19:02:08 +09:00
1be3bb360e chore(deps): update dependency vite-plugin-resolve to v2.5.2 (#2276)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-28 15:06:22 +09:00
ba2afd2652 chore(deps): update playwright monorepo to v1.45.3 (#2277)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-28 15:06:07 +09:00
5e283c9ea5 fix(deps): update dependency deepmerge-ts to v7.1.0 (#2263)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-28 14:59:23 +09:00
ddb1c56111 chore(deps): update dependency typescript to v5.5.4 (#2274)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-28 14:59:13 +09:00
ebd167f3f2 chore(deps): update dependency vite to v5.3.5 (#2275)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-28 14:55:57 +09:00
178a62b9d3 fix(deps): update dependency i18next to v23.12.2 (#2260)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-28 14:46:26 +09:00
f98a2cf766 chore(deps): update dependency discord-api-types to v0.37.93 (#2273)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-28 14:46:06 +09:00
fdbe6f7331 chore(deps): update dependency rollup to v4.19.1 (#2261)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-28 14:45:54 +09:00
57c2cdc91e chore(i18n): Translated using Weblate (Portuguese)
Currently translated at 100.0% (357 of 357 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/pt/
2024-07-26 18:09:17 +02:00
0f5074f8ab chore(i18n): Translated using Weblate (French)
Currently translated at 100.0% (357 of 357 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/fr/
2024-07-26 18:09:13 +02:00
661396226d fix(deps): update dependency custom-electron-prompt to v1.5.8 (#2262)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-26 12:42:17 +09:00
36f27fe2e6 chore(i18n): Translated using Weblate (Polish)
Currently translated at 100.0% (357 of 357 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/pl/
2024-07-25 15:09:16 +02:00
adf1ce4bc7 chore(i18n): Translated using Weblate (Vietnamese)
Currently translated at 100.0% (357 of 357 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/vi/
2024-07-22 14:09:21 +02:00
43b4b8df5e chore(i18n): Translated using Weblate (German)
Currently translated at 100.0% (357 of 357 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/de/
2024-07-22 14:09:20 +02:00
4a8440c281 chore(i18n): Translated using Weblate (Catalan)
Currently translated at 100.0% (357 of 357 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ca/
2024-07-20 18:09:24 +02:00
32fe9fcffe chore(i18n): Translated using Weblate (French)
Currently translated at 100.0% (357 of 357 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/fr/
2024-07-20 18:09:22 +02:00
a9896845da chore(i18n): Added translation using Weblate (Catalan) 2024-07-19 17:02:32 +02:00
a59aa07334 chore(i18n): Translated using Weblate (Filipino)
Currently translated at 83.7% (299 of 357 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/fil/
2024-07-19 10:09:32 +02:00
e07d7395e7 chore(i18n): Translated using Weblate (Spanish)
Currently translated at 100.0% (357 of 357 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/es/
2024-07-19 10:09:31 +02:00
9bb6f32ece chore(i18n): Translated using Weblate (Czech)
Currently translated at 96.3% (344 of 357 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/cs/
2024-07-19 10:09:30 +02:00
ccb19a0dc9 feat(adblocker): add new option AdSpeedup (#2235)
* Ad speedup code

* And ad-speedup translations

* Update index.ts

* fix error

* Update build.yml

* add AdSpeedup as adBlock option

* remove it as own plugin

* remove console.log

* add semicolons
2024-07-18 13:16:46 +09:00
64fb6c2597 fix: disable multi-plane format for software video (#2254) 2024-07-18 13:15:26 +09:00
73c3e355fe chore(deps): update dependency eslint-plugin-prettier to v5.2.1 (#2253)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-18 03:42:41 +09:00
fc7a504643 chore(deps): update dependency vite to v5.3.4 (#2243)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-18 03:42:34 +09:00
764dc0f895 chore(deps): update typescript-eslint monorepo to v7.16.1 (#2239)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-18 03:42:26 +09:00
9f33f49ec4 chore(deps): update playwright monorepo to v1.45.2 (#2244)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-18 03:32:19 +09:00
87ae6d29bb chore(deps): update dependency vite-plugin-inspect to v0.8.5 (#2252)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-18 03:31:55 +09:00
093c8e3ca6 fix(deps): update dependency semver to v7.6.3 (#2250)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-18 03:29:19 +09:00
fec26a010d chore(deps): update dependency electron to v31.2.1 (#2241)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-17 18:08:17 +09:00
5d8aaccc55 chore(i18n): Translated using Weblate (Hebrew)
Currently translated at 4.5% (16 of 355 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/he/
2024-07-17 08:09:14 +00:00
cda03078a9 chore(i18n): Translated using Weblate (Turkish)
Currently translated at 100.0% (355 of 355 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/tr/
2024-07-16 02:46:56 +02:00
9c139b96f4 chore(i18n): Translated using Weblate (French)
Currently translated at 98.8% (351 of 355 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/fr/
2024-07-16 02:46:55 +02:00
9b2816c156 chore(i18n): Translated using Weblate (Finnish)
Currently translated at 80.8% (287 of 355 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/fi/
2024-07-15 19:09:19 +00:00
b1b8847134 chore(i18n): Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (355 of 355 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/zh_Hant/
2024-07-15 19:09:19 +00:00
bf9e698288 chore(i18n): Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (355 of 355 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/zh_Hans/
2024-07-15 19:09:18 +00:00
28e8a1c5dd chore(i18n): Translated using Weblate (Polish)
Currently translated at 99.7% (354 of 355 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/pl/
2024-07-15 19:09:17 +00:00
18e0b1b863 Update changelog for v3.4.1 2024-07-14 15:26:58 +00:00
02e2fb6a83 Bump version to 3.4.1 2024-07-15 00:18:37 +09:00
91bee4880e chore(i18n): Translated using Weblate (Spanish)
Currently translated at 100.0% (355 of 355 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/es/
2024-07-14 17:15:57 +02:00
7de7303ebb fix(mpris): fix mpris position
- fix #2225
2024-07-15 00:14:49 +09:00
363d869cff fix(deb): fix depends
- fix #1983
2024-07-14 23:48:15 +09:00
2512af80af fix: fix touchbar icon
- fix #2183
2024-07-14 23:19:06 +09:00
887979932c fix: fix "Starting page"
- fix #1822
2024-07-14 22:59:05 +09:00
eeaaf2f158 fix: fix album actions
- fix #2202
2024-07-14 22:50:24 +09:00
e91e995b95 fix: fix playback slider
- fix #2045
2024-07-14 22:32:56 +09:00
49dd2ecac6 fix(deps): update dependency i18next to v23.12.1 (#2230)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-14 22:09:44 +09:00
06f419abc4 Bump version to 3.4.0 2024-07-14 22:08:17 +09:00
2c29461e61 fix(downloader): update types 2024-07-14 22:05:21 +09:00
a9b9e74477 chore(i18n): Translated using Weblate (Korean)
Currently translated at 100.0% (355 of 355 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ko/
2024-07-14 15:05:05 +02:00
30848b7c4a feat(downloader): New option to download on finish (#1964)
Co-authored-by: JellyBrick <shlee1503@naver.com>
2024-07-14 22:00:40 +09:00
83023c19a6 chore(i18n): Translated using Weblate (Romanian)
Currently translated at 100.0% (346 of 346 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ro/
2024-07-14 11:09:21 +00:00
45931a25b0 fix: rollback eslint version to v8 2024-07-14 19:24:46 +09:00
98d4ff83b1 chore(deps): update typescript-eslint monorepo to v8.0.0-alpha.42 (#2228)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-14 16:58:05 +09:00
35f1d75832 chore(deps): update dependency eslint to v9.7.0 (#2226)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-13 11:40:56 +09:00
cbbba6ec76 chore(deps): update dependency @babel/runtime to v7.24.8 (#2221)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-12 21:03:22 +09:00
35383e4730 chore(deps): update dependency node-gyp to v10.2.0 (#2216)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-12 20:58:37 +09:00
b7029cfc60 chore(deps): update dependency ws to v8.18.0 (#2217)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-11 23:32:24 +09:00
d8328e0ad5 chore(deps): update dependency glob to v11 (#2219)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-11 23:32:05 +09:00
7ccb72d399 chore(deps): update dependency esbuild to v0.23.0 (#2215)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-11 23:27:28 +09:00
5108f19ee5 chore(deps): update dependency electron to v31.2.0 (#2214)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-11 23:27:13 +09:00
041574570f fix(deps): update dependency youtubei.js to v10.1.0 (#2218)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-11 16:44:14 +09:00
9505195835 chore(i18n): Translated using Weblate (Malay)
Currently translated at 8.0% (28 of 346 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ms/
2024-07-11 06:09:18 +00:00
b33f5ff94d chore(deps): update playwright monorepo to v1.45.1 (#2212)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-10 19:18:51 +09:00
097f488ba0 chore(deps): update typescript-eslint monorepo to v8.0.0-alpha.41 (#2213)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-10 19:18:39 +09:00
521d1d8ee7 chore(deps): update dependency rollup to v4.18.1 (#2210)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-10 19:16:22 +09:00
f38ce093f5 chore(deps): update dependency eslint to v9.6.0 (#2192)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-10 18:33:38 +09:00
2e63985ed3 chore(deps): update dependency vite to v5.3.3 (#2211)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-10 18:30:38 +09:00
a22d08e983 chore(deps): update dependency glob to v10.4.5 (#2205)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-10 18:29:38 +09:00
d1b998aebd chore(deps): update dependency discord-api-types to v0.37.92 (#2204)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-10 18:24:13 +09:00
7f598b5856 fix(deps): update dependency solid-js to v1.8.18 (#2189)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-10 18:23:49 +09:00
373e27ac5b chore(deps): update dependency typescript to v5.5.3 (#2206)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-10 18:23:21 +09:00
dcd53a9234 chore(i18n): Translated using Weblate (Hungarian)
Currently translated at 94.5% (327 of 346 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/hu/
2024-07-07 21:09:22 +02:00
c59b11b63b chore(deps): update dependency electron to v31.1.0 (#2190)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-07 22:25:20 +09:00
4d8fd8718f chore(deps): update typescript-eslint monorepo to v8.0.0-alpha.40 (#2193)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-07 22:25:03 +09:00
f0c4d1da36 fix(deps): update dependency @floating-ui/dom to v1.6.7 (#2196)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-07 22:23:56 +09:00
79c669e7c1 chore(i18n): Translated using Weblate (Finnish)
Currently translated at 82.6% (286 of 346 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/fi/
2024-07-05 01:09:19 +02:00
e8156fc0fe chore(i18n): Translated using Weblate (Finnish)
Currently translated at 82.6% (286 of 346 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/fi/
2024-07-05 01:09:19 +02:00
348c70dca4 chore(i18n): Translated using Weblate (Finnish)
Currently translated at 64.1% (222 of 346 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/fi/
2024-07-04 00:47:01 +02:00
3439dded3b chore(i18n): Translated using Weblate (Finnish)
Currently translated at 64.1% (222 of 346 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/fi/
2024-07-04 00:47:01 +02:00
2ee0101e97 chore(i18n): Added translation using Weblate (Finnish) 2024-07-03 10:54:29 +02:00
6a037083dd chore(deps): update dependency vite to v5.3.2 (#2188)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-29 09:46:54 +09:00
1d1705e471 chore(deps): update dependency discord-api-types to v0.37.91 (#2187)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-29 09:42:23 +09:00
0f7fe74d40 chore(deps): update typescript-eslint monorepo to v8.0.0-alpha.34 (#2184)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-29 09:42:11 +09:00
d9f24d2c4e fix(deps): update dependency @floating-ui/dom to v1.6.6 (#2182)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-29 09:41:57 +09:00
7b6a7377a8 chore(deps): update playwright monorepo to v1.45.0 (#2181)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-29 09:41:09 +09:00
bd8468a8c1 fix(deps): update dependency ts-morph to v23 (#2180)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-29 09:40:54 +09:00
aec088f95d chore(deps): update dependency electron-vite to v2.3.0 (#2178)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-29 09:40:31 +09:00
4b12b43f57 chore(i18n): Translated using Weblate (Arabic)
Currently translated at 28.9% (100 of 346 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ar/
2024-06-28 14:09:24 +02:00
f47287de94 chore(i18n): Translated using Weblate (Thai)
Currently translated at 78.9% (273 of 346 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/th/
2024-06-28 14:09:23 +02:00
58317f4c10 chore(i18n): Translated using Weblate (Lithuanian)
Currently translated at 88.1% (305 of 346 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/lt/
2024-06-23 22:09:20 +02:00
c0aae7b2ac fix(deps): update dependency conf to v13.0.1 (#2175)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-23 16:43:25 +09:00
76547ad602 chore(deps): update dependency glob to v10.4.2 (#2168)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-22 09:49:13 +09:00
8b128273c8 chore(deps): update dependency discord-api-types to v0.37.90 (#2167)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-22 08:59:25 +09:00
25d1127b21 chore(deps): update dependency typescript to v5.5.2 (#2173)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-22 08:58:53 +09:00
b3ab08b354 chore(deps): update dependency electron to v31.0.2 (#2170)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-22 08:56:45 +09:00
2ef8b4f14c chore(i18n): Translated using Weblate (Filipino)
Currently translated at 83.2% (288 of 346 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/fil/
2024-06-21 13:09:24 +02:00
b39baf6d88 chore(i18n): Translated using Weblate (Thai)
Currently translated at 74.5% (258 of 346 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/th/
2024-06-21 13:09:23 +02:00
40f0b9b852 chore(i18n): Translated using Weblate (Slovenian)
Currently translated at 43.9% (152 of 346 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/sl/
2024-06-18 19:09:35 +00:00
3fe8115f32 chore(i18n): Translated using Weblate (Ukrainian)
Currently translated at 100.0% (346 of 346 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/uk/
2024-06-18 19:09:34 +00:00
47d3b34e4b chore(i18n): Added translation using Weblate (Slovenian) 2024-06-18 16:15:21 +02:00
d0889bb622 chore(deps): update dependency ws to v8.17.1 (#2164)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-18 16:22:45 +09:00
d6a7cbfa6f chore(i18n): Translated using Weblate (Polish)
Currently translated at 100.0% (346 of 346 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/pl/
2024-06-17 09:09:27 +00:00
c6541b6897 chore(deps): update dependency eslint to v9.5.0 (#2162)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-16 13:44:56 +09:00
865578037b fix(deps): update dependency youtubei.js to v10 (#2136)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-16 13:43:51 +09:00
d4176eeb8a chore(deps): update dependency discord-api-types to v0.37.89 (#2153)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-16 13:43:35 +09:00
b88bbbc680 chore(deps): update dependency vite to v5.3.1 (#2154)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-16 13:43:06 +09:00
67aaccce86 fix(deps): update dependency electron-store to v10 (#2157)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-16 13:42:47 +09:00
b95b69bf50 fix(deps): update dependency conf to v13 (#2156)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-16 13:40:13 +09:00
894531fd93 chore(i18n): Update translation files
Updated by "Remove blank strings" hook in Weblate.

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/
2024-06-14 04:09:29 +00:00
8a20566e0f chore(i18n): Translated using Weblate (Filipino)
Currently translated at 82.6% (286 of 346 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/fil/
2024-06-14 04:09:27 +00:00
253325a3cf chore(i18n): Translated using Weblate (Hebrew)
Currently translated at 1.1% (4 of 346 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/he/
2024-06-14 04:09:20 +00:00
ee6716a0eb chore(i18n): Translated using Weblate (Indonesian)
Currently translated at 100.0% (346 of 346 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/id/
2024-06-14 04:09:20 +00:00
8fe5450ace chore(i18n): Translated using Weblate (Japanese)
Currently translated at 100.0% (346 of 346 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ja/
2024-06-14 04:09:19 +00:00
1bb36b38bc chore(deps): update dependency electron to v31.0.1 (#2148)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-13 17:09:51 +09:00
25cec993bc chore(i18n): Translated using Weblate (Czech)
Currently translated at 98.5% (341 of 346 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/cs/
2024-06-12 17:09:11 +00:00
c744619664 chore(i18n): Translated using Weblate (Italian)
Currently translated at 100.0% (346 of 346 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/it/
2024-06-11 18:09:14 +02:00
451d30517e chore(i18n): Translated using Weblate (Czech)
Currently translated at 91.3% (316 of 346 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/cs/
2024-06-11 18:09:13 +02:00
dbb345ba1f chore(deps): update dependency discord-api-types to v0.37.88 (#2138)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-11 10:27:46 +09:00
c60edf9718 chore(deps): update typescript-eslint monorepo to v8.0.0-alpha.30 (#2139)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-11 10:27:03 +09:00
bd4e3a91c8 chore(deps): update dependency electron to v31 (#2141)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-11 10:26:52 +09:00
0f8b586b75 chore(deps): update dependency esbuild to v0.21.5 (#2135)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-11 10:26:27 +09:00
262c17a5bd chore(i18n): Translated using Weblate (Japanese)
Currently translated at 99.4% (344 of 346 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ja/
2024-06-10 15:09:22 +02:00
542cb916b5 chore(deps): update typescript-eslint monorepo to v8.0.0-alpha.29 (#2132)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-09 20:40:36 +09:00
2627ebd675 Update changelog for v3.3.12 2024-06-08 11:04:55 +00:00
89ed7d2345 Bump version to 3.3.12 2024-06-08 19:56:02 +09:00
3c4abc1418 hotfix: Revert "chore(deps): update dependencies @cliqz/adblocker-electron, @cliqz/adblocker-electron-preload"
This reverts commit 680f4143f5.
2024-06-08 19:51:38 +09:00
de224444c2 Update changelog for v3.3.11 2024-06-08 05:11:16 +00:00
e9ae2d44c9 Bump version to 3.3.11 2024-06-08 14:01:49 +09:00
680f4143f5 chore(deps): update dependencies @cliqz/adblocker-electron, @cliqz/adblocker-electron-preload 2024-06-08 12:45:24 +09:00
23b553ea4b Revert "fix(deps): update dependency @cliqz/adblocker-electron to v1.27.10" (#2129)
This reverts commit d97aa1a8a0.
2024-06-08 11:52:15 +09:00
e2a91022fd chore(deps): update dependency vite to v5.2.13 (#2127)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-08 11:43:10 +09:00
d97aa1a8a0 fix(deps): update dependency @cliqz/adblocker-electron to v1.27.10 2024-06-07 21:18:57 +09:00
ede11307ef fix(menu): fix menubar items doesn't rendered
resolve #2113
2024-06-07 21:16:48 +09:00
b74c1a0207 chore(i18n): Translated using Weblate (Vietnamese)
Currently translated at 100.0% (346 of 346 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/vi/
2024-06-07 13:09:20 +02:00
104c1284f6 chore(deps): update dependency electron to v30.1.0 (#2126)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-07 19:21:03 +09:00
8af1b36551 fix(deps): update dependency deepmerge-ts to v7.0.3 (#2125)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-07 19:19:44 +09:00
ce5421ffce chore(deps): update dependency @babel/runtime to v7.24.7 (#2124)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-07 19:19:19 +09:00
98b1fd8787 chore(deps): update typescript-eslint monorepo to v8.0.0-alpha.28 (#2121)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-07 19:16:36 +09:00
ed5f1ecde3 fix(deps): update dependency electron-updater to v6.2.1 (#2120)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-07 19:16:20 +09:00
efbd9922fd chore(deps): update dependency discord-api-types to v0.37.87 (#2119)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-07 19:14:10 +09:00
463bc2c976 chore(i18n): Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (346 of 346 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/zh_Hans/
2024-06-05 18:09:13 +00:00
e71a70d25c chore(i18n): Translated using Weblate (German)
Currently translated at 100.0% (346 of 346 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/de/
2024-06-05 18:09:13 +00:00
4ae9a2820e chore(i18n): Translated using Weblate (Nepali)
Currently translated at 100.0% (346 of 346 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ne/
2024-06-04 06:09:19 +00:00
3ac1cc9204 fix(deps): update dependency deepmerge-ts to v7.0.2 (#2118)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-03 19:06:50 +09:00
2938c93803 chore(deps): update typescript-eslint monorepo to v8.0.0-alpha.25 (#2114)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-03 19:02:38 +09:00
7e8d31172c chore(i18n): Translated using Weblate (Nepali)
Currently translated at 21.0% (73 of 346 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ne/
2024-06-03 07:09:16 +02:00
e0353a88ce chore(i18n): Translated using Weblate (Sinhala)
Currently translated at 2.0% (7 of 346 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/si/
2024-06-03 07:09:15 +02:00
635f3334a6 chore(i18n): Translated using Weblate (Thai)
Currently translated at 68.7% (238 of 346 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/th/
2024-06-03 07:09:15 +02:00
7800e106cb chore(i18n): Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (346 of 346 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/zh_Hant/
2024-06-03 07:09:14 +02:00
e436e6eae0 chore(i18n): Translated using Weblate (Russian)
Currently translated at 100.0% (346 of 346 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ru/
2024-06-03 07:09:13 +02:00
0c24b70f23 chore(i18n): Added translation using Weblate (Nepali) 2024-06-03 06:04:30 +02:00
2693a1598a chore(i18n): Added translation using Weblate (Sinhala) 2024-06-02 17:09:31 +02:00
7a87e90edf chore(i18n): Added translation using Weblate (Arabic) 2024-06-02 08:29:33 +02:00
d333fc1075 Update changelog for v3.3.10 2024-06-02 03:56:07 +00:00
1f99db3217 Bump version to 3.3.10 2024-06-02 12:49:41 +09:00
4fa9762a50 fix(deps): bump deps 2024-06-02 12:47:32 +09:00
1e5bea85b3 fix(deps): bump @typescript-eslint/eslint-plugin version to 8.0.0-alpha.24
ESLint v9
2024-06-02 12:33:29 +09:00
739518a6fd fix(adblocker): fix blank screen
- Revert @cliqz/adblocker-electron version from 1.27.3 to 1.27.1

- fix #2103
- fix #2105
2024-06-02 12:30:17 +09:00
24b0ae2c6b chore(i18n): Translated using Weblate (Croatian)
Currently translated at 1.4% (5 of 346 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/hr/
2024-06-02 05:16:48 +02:00
dae6fc9149 chore(i18n): Translated using Weblate (Croatian)
Currently translated at 0.5% (2 of 346 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/hr/
2024-06-02 03:20:31 +02:00
25958a7bb1 chore(i18n): Translated using Weblate (Hungarian)
Currently translated at 90.4% (313 of 346 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/hu/
2024-06-02 03:20:30 +02:00
8b901789dd chore(i18n): Added translation using Weblate (Croatian) 2024-06-01 16:10:33 +02:00
09a582192f Update changelog for v3.3.9 2024-06-01 01:14:52 +00:00
8735107eb0 Bump version to 3.3.9 2024-06-01 10:07:12 +09:00
5b9e947b8f feat(adblocker): improve In-Player adblocker 2024-06-01 10:01:53 +09:00
1f1efac466 fix(adblocker): fix In-Player adblocker
fix #1817
2024-06-01 09:50:13 +09:00
ee9c5a149b chore(deps): update dependency eslint to v9.4.0 (#2106)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-01 09:30:58 +09:00
79151cb3aa chore(i18n): Translated using Weblate (Malay)
Currently translated at 0.8% (3 of 346 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ms/
2024-06-01 02:28:08 +02:00
328530ea2c chore(i18n): Translated using Weblate (Hebrew)
Currently translated at 0.8% (3 of 346 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/he/
2024-06-01 02:28:08 +02:00
9e809b002d chore(i18n): Translated using Weblate (French)
Currently translated at 100.0% (346 of 346 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/fr/
2024-06-01 02:28:08 +02:00
200226f42d Update changelog for v3.3.8 2024-05-31 19:43:15 +00:00
5d99a854e2 Bump version to 3.3.8 2024-06-01 04:35:36 +09:00
cd4f0ccad7 fix(adblocker): fix blank screen
- fix #1942
- fix #2100
- fix #2103
2024-06-01 04:34:21 +09:00
b572623442 Update changelog for v3.3.7 2024-05-31 16:29:54 +00:00
ef02fdcf45 Bump version to 3.3.7 2024-06-01 01:22:18 +09:00
25d5c16af0 fix: release CI 2024-06-01 01:10:44 +09:00
6f49313f03 fix: fix lock file 2024-06-01 00:52:26 +09:00
55c7456c69 chore(deps): update dependency electron to v30.0.9 (#2098)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-01 00:07:07 +09:00
78c435b3c4 Revert "fix(deps): update dependency @cliqz/adblocker-electron to v1.27.6" (#2101) 2024-06-01 00:07:00 +09:00
5e43f38348 fix(deps): update dependency @cliqz/adblocker-electron to v1.27.6 (#2096)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-01 00:05:17 +09:00
24000acda0 chore(i18n): Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (346 of 346 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/zh_Hant/
2024-05-31 15:09:17 +02:00
24becf0337 chore(i18n): Translated using Weblate (Turkish)
Currently translated at 100.0% (346 of 346 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/tr/
2024-05-30 13:09:18 +02:00
8c80922b6b chore(deps): update dependency discord-api-types to v0.37.86 (#2092)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-28 22:54:09 +09:00
813a089f0d chore(deps): update dependency vite to v5.2.12 (#2094)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-28 22:53:59 +09:00
197bead857 chore(deps): update dependency @typescript-eslint/eslint-plugin to v7.11.0 (#2093)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-28 22:53:46 +09:00
5f7a705394 chore(i18n): Translated using Weblate (Portuguese)
Currently translated at 100.0% (346 of 346 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/pt/
2024-05-28 01:09:11 +00:00
646c0d79a3 chore(i18n): Translated using Weblate (Hungarian)
Currently translated at 58.0% (201 of 346 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/hu/
2024-05-26 15:09:19 +02:00
5a1313397e chore(i18n): Translated using Weblate (Polish)
Currently translated at 100.0% (346 of 346 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/pl/
2024-05-26 15:09:18 +02:00
4bc70ac2b8 chore(i18n): Translated using Weblate (Spanish)
Currently translated at 100.0% (346 of 346 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/es/
2024-05-26 15:09:18 +02:00
dc5b2f96be chore(docs): Added README-es.md and linked to README.md (#2090)
* Added README.md in spanish language and in original README.md added the link to spanish README.md

* Update README-es.md screenshots

* Correction on README-es.md

* Correction on README-es.md

* Correction on README-es.md

* Update README.md
2024-05-26 08:58:00 +09:00
d10b297d75 feat(i18n): add korean translation 2024-05-25 21:26:00 +09:00
933b4cc8f0 feat(menu): add theme list in menu 2024-05-25 21:26:00 +09:00
4557aff9b6 fix(renderer): fix macos traffic lights gap
- resolve #2035
2024-05-25 21:24:06 +09:00
3a42d700fe fix(album-color-theme): fix fullscreen layout issue 2024-05-25 20:51:28 +09:00
1a142a8a39 fix(deps): update dependency deepmerge-ts to v7 (#2085)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-25 20:22:19 +09:00
922b04cd54 chore(deps): update dependency builtin-modules to v4 (#2084)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-25 20:21:49 +09:00
bdfae8ce24 fix(deps): update dependency electron-debug to v4 (#2086)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-25 20:21:27 +09:00
08a537e509 fix(deps): update dependency electron-store to v9 (#2087)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-25 20:12:18 +09:00
51d8145f13 fix(deps): update dependency conf to v12 (#1463)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-25 20:11:24 +09:00
7e74f33030 fix(deps): update dependency youtubei.js to v9.4.0 (#2083)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-25 20:07:03 +09:00
0bb8d9bcd9 chore(deps): update playwright monorepo to v1.44.1 (#2082)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-25 20:06:50 +09:00
19a4cb901b chore(deps): update dependency ws to v8.17.0 (#2081)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-25 20:06:36 +09:00
c497dff69b chore(deps): update dependency glob to v10.4.1 (#2080)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-25 20:05:37 +09:00
cd0164b665 chore(deps): update dependency eslint to v9.3.0 (#2079)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-25 20:03:27 +09:00
ab35cd3049 fix(deps): update dependency peerjs to v1.5.4 (#2075)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-25 20:02:54 +09:00
13b2ff3a2e chore(deps): update dependency esbuild to v0.21.4 (#2078)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-25 20:02:30 +09:00
e00c1b51c7 fix(deps): update dependency semver to v7.6.2 (#2076)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-25 20:00:41 +09:00
0a2a289939 chore(deps): update dependency electron-vite to v2.2.0 (#2077)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-25 20:00:31 +09:00
919b6ba7cb fix(deps): update dependency i18next to v23.11.5 (#2074)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-25 20:00:11 +09:00
f0683177d8 chore(i18n): Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (342 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/zh_Hant/
2024-05-25 09:09:12 +02:00
13450580d0 fix(deps): update dependency @cliqz/adblocker-electron to v1.27.3 (#2071)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-25 15:38:37 +09:00
2375067d19 chore(deps): update dependency vite to v5.2.11 (#2070)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-25 15:38:18 +09:00
b2fe0f21cb fix(deps): update dependency @floating-ui/dom to v1.6.5 (#2073)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-25 15:38:07 +09:00
3e0257ba07 fix(deps): update dependency @cliqz/adblocker-electron-preload to v1.27.3 (#2072)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-25 15:37:38 +09:00
4f078284f3 chore(deps): update pnpm to v9 (#1980)
* chore(deps): update pnpm to v9

* fix: Update package.json

* fix: Update build.yml

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: JellyBrick <shlee1503@naver.com>
2024-05-25 08:52:35 +09:00
e87fa12fdc chore(deps): update dependency electron to v30.0.8 (#2068)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-25 08:40:59 +09:00
354c44d717 chore(deps-dev): bump ejs from 3.1.9 to 3.1.10 (#2023)
Bumps [ejs](https://github.com/mde/ejs) from 3.1.9 to 3.1.10.
- [Release notes](https://github.com/mde/ejs/releases)
- [Commits](https://github.com/mde/ejs/compare/v3.1.9...v3.1.10)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-25 08:40:38 +09:00
f55faa0a8a chore(deps): update dependency utf-8-validate to v6.0.4 (#2069)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-25 08:40:25 +09:00
eaf9d310aa fix(MPRIS): Prevents player to start with invalid MPRIS interface (#1996)
Co-authored-by: andreas <andreas.angerer@github.com>
2024-05-25 08:36:52 +09:00
bbd10b657d fix(deps): update dependency solid-js to v1.8.17 (#2002)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-25 08:34:49 +09:00
8600b5558f chore(deps): update dependency @typescript-eslint/eslint-plugin to v7.10.0 (#2000)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-25 08:34:32 +09:00
9c7eb5dc26 chore(deps): update dependency discord-api-types to v0.37.85 (#1998)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-25 08:34:17 +09:00
ac63a6a200 fix(deps): update dependency serve to v14.2.3 (#1997)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-25 08:34:05 +09:00
3389994ff9 chore(deps): update dependency rollup to v4.18.0 (#1990)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-25 08:33:49 +09:00
adaee80913 feat: Enable arm64 for deb and rpm (#2033)
Co-authored-by: Aaron Honeycutt <aaronhoneycutt@proton.me>
2024-05-25 08:33:21 +09:00
4e467d9308 chore (README-is.md): Replace viðbót with tengiforrit (#2004)
* chore (README-is.md): Replace viðbót with tengiforrit

better translation for 'plugin', I wish i knew this word existed earlier smh

* fix broken link

---------

Co-authored-by: Angelos Bouklis <me@arjix.dev>
2024-05-25 08:32:21 +09:00
a85fc609cb chore(docs): readme file translated to french (#2049) 2024-05-25 08:29:47 +09:00
96f69953f2 chore(deps): update dependency @babel/runtime to v7.24.6 (#2039)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-25 08:28:51 +09:00
9095b46a15 chore(i18n): Translated using Weblate (Greek)
Currently translated at 36.8% (126 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/el/
2024-05-19 16:01:56 +02:00
4415927465 fix nav bar color change onscroll 2024-05-16 16:57:18 +09:00
e6b25119cd fix scrollbar over titlebar 2024-05-16 16:57:18 +09:00
09e02aeac8 chore(i18n): Translated using Weblate (Filipino)
Currently translated at 38.8% (133 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/fil/
2024-05-15 04:02:00 +00:00
f3de17112a chore(i18n): Translated using Weblate (Hungarian)
Currently translated at 45.3% (155 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/hu/
2024-05-15 04:01:59 +00:00
91392c0c7e chore(i18n): Translated using Weblate (Filipino)
Currently translated at 29.5% (101 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/fil/
2024-05-10 09:31:19 +02:00
54683a233f chore(i18n): Translated using Weblate (Filipino)
Currently translated at 10.5% (36 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/fil/
2024-05-07 20:07:38 +02:00
8d12eeb033 chore(i18n): Added translation using Weblate (Filipino) 2024-05-06 08:08:29 +02:00
0ba35890b1 chore(i18n): Translated using Weblate (Dutch)
Currently translated at 77.7% (266 of 342 strings)

Co-authored-by: tsafen <nefastable@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/nl/
Translation: th-ch/youtube-music/i18n
2024-05-03 11:07:14 +02:00
4783ca5942 chore(i18n): Translated using Weblate (Dutch)
Currently translated at 77.1% (264 of 342 strings)

Co-authored-by: Rémy Flament <flament.remy1@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/nl/
Translation: th-ch/youtube-music/i18n
2024-05-01 22:07:22 +02:00
1517a60215 chore(i18n): Translated using Weblate (French)
Currently translated at 99.1% (339 of 342 strings)

Co-authored-by: Mattias <watgytb+weblate@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/fr/
Translation: th-ch/youtube-music/i18n
2024-05-01 22:07:20 +02:00
4ca3c8b7e2 Merge pull request #2015 from BryanGIG/fix-fullscreen-patch-1
Fix substract `margin-top` in fullscreen mode
2024-04-28 15:30:54 +03:00
93081c89c8 Fix substract margin-top in fullscreen mode
Fix #2013
2024-04-28 07:42:56 +07:00
09255b626b fix: vite-inspect for renderer 2024-04-27 19:10:10 +03:00
33fe008b5c chore(i18n): Translated using Weblate (Icelandic)
Currently translated at 98.8% (338 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/is/
2024-04-25 03:07:22 +02:00
e72ac3d9d0 chore(deps): update dependency vite-plugin-inspect to v0.8.4 2024-04-21 23:15:23 +09:00
14a926aa88 chore(deps): update dependency vite to v5.2.10 2024-04-21 22:58:30 +09:00
99311dba6d chore(deps): update dependency eslint to v9.1.0 2024-04-21 22:58:20 +09:00
5e9f545e4e chore(deps): update dependency electron to v30 2024-04-21 22:58:07 +09:00
0cc8fdf564 chore(deps): update dependency vite to v5.2.9 2024-04-18 16:48:00 +09:00
27e0e7173a chore(deps): update dependency @typescript-eslint/eslint-plugin to v7.7.0 2024-04-18 16:47:39 +09:00
2710c62b82 chore(i18n): Translated using Weblate (Dutch)
Currently translated at 77.1% (264 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/nl/
2024-04-18 05:03:38 +02:00
a50de65a66 fix(deps): update dependency i18next to v23.11.2 2024-04-16 16:58:50 +09:00
c21758f8e6 chore(deps): update dependency rollup to v4.14.3 2024-04-16 16:58:35 +09:00
1a5f6c2a8f chore(deps): update pnpm to v8.15.7 (#1970)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-14 09:31:24 +09:00
d521a84f85 Update changelog for v3.3.6 2024-04-13 14:34:39 +00:00
aa29a0fa65 Bump version to 3.3.6 2024-04-13 23:26:40 +09:00
a8469d7d8d fix: electron-builder snap bug 2024-04-13 23:03:44 +09:00
d09858cbec chore(deps): bump electron-builder version to 24.13.3 2024-04-13 22:43:06 +09:00
855f67bb1e fix: add AdGuard as blocklist sources (#1966) 2024-04-13 16:45:08 +09:00
8508620e53 chore(deps): update dependency rollup to v4.14.2 (#1968)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-13 16:43:27 +09:00
e9fbfe36cc fix(deps): update dependency youtubei.js to v9.3.0 (#1967)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-13 16:37:09 +09:00
f158a7865a chore(deps): update playwright monorepo to v1.43.1 (#1969)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-13 16:36:58 +09:00
74860edc6e fix: rollback electron-builder version to 24.9.2 2024-04-11 19:02:25 +09:00
1712b70fb5 fix: rollback electron-builder version to 24.9.3 2024-04-11 18:55:12 +09:00
4a57cc5ee9 fix: rollback electron-builder version to 24.9.4 2024-04-11 18:45:10 +09:00
4db0f72864 chore(deps): update dependency electron to v29.3.0 (#1961)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-11 18:18:47 +09:00
bfe624dc57 fix(mpris): use global regex to replace minus in the video ID (#1963) 2024-04-11 18:16:02 +09:00
994fdaf436 fix(deps): update dependency @cliqz/adblocker-electron-preload to v1.27.1 (#1954)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-11 00:59:45 +09:00
9ac9146d78 chore(deps): update dependency typescript to v5.4.5 (#1958)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-11 00:47:36 +09:00
fbbfc540c2 fix(deps): update dependency youtubei.js to v9.2.1 (#1957)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-11 00:47:30 +09:00
ac3f42d507 fix(deps): update dependency i18next to v23.11.1 (#1956)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-11 00:47:20 +09:00
993655fdee fix(deps): update dependency @cliqz/adblocker-electron to v1.27.1 (#1953)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-11 00:47:08 +09:00
eff2f550c6 chore(i18n): Added translation using Weblate (Malay) 2024-04-09 11:44:56 +02:00
aef03ab9fd chore: update electron-builder to 25.0.0-alpha.6 2024-04-09 07:18:39 +09:00
f822373c30 chore: update overrides 2024-04-09 07:17:12 +09:00
19313f9cc9 chore(deps): update dependency @typescript-eslint/eslint-plugin to v7.6.0 (#1947)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-09 06:56:03 +09:00
c3b64b097f fix(deps): update dependency i18next to v23.11.0 (#1946)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-09 06:55:20 +09:00
6668d735a0 chore(deps): update dependency node-gyp to v10.1.0 (#1941)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-07 20:29:51 +09:00
e2d801168e chore(deps): update dependency eslint to v9 (#1940)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-07 20:29:42 +09:00
86f5223350 chore(deps): update dependency rollup to v4.14.1 (#1944)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-07 20:29:19 +09:00
9ee6940856 chore(deps): update dependency node-gyp to v10.1.0 (#1937)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-05 09:26:49 +09:00
bffea06343 chore(deps): update dependency typescript to v5.4.4 (#1936)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-05 09:26:22 +09:00
e0ab14b4ea chore(deps): update playwright monorepo to v1.43.0 (#1938)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-05 09:25:56 +09:00
1cb5f628c8 chore(deps): bump undici from 5.28.3 to 5.28.4 (#1935)
Bumps [undici](https://github.com/nodejs/undici) from 5.28.3 to 5.28.4.
- [Release notes](https://github.com/nodejs/undici/releases)
- [Commits](https://github.com/nodejs/undici/compare/v5.28.3...v5.28.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-05 09:25:45 +09:00
1ac9704cf4 chore(deps): update dependency vite to v5.2.8 (#1930)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-04 21:36:50 +09:00
7ebcc51646 chore(deps): update dependency discord-api-types to v0.37.79 (#1933)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-04 21:34:22 +09:00
f4ccde2734 chore(deps): update dependency node-gyp to v10.1.0 2024-04-04 21:33:02 +09:00
e6d7c5cdfc chore(deps): update dependency electron to v29.2.0 2024-04-04 21:32:16 +09:00
9e3f32a233 chore(deps): update dependency node-gyp to v10.1.0 2024-04-03 19:55:25 +09:00
8ed813427f chore(deps): update dependency @typescript-eslint/eslint-plugin to v7.5.0 2024-04-03 19:51:38 +09:00
2db0d79af6 chore(deps): update dependency discord-api-types to v0.37.78 2024-04-03 19:48:05 +09:00
28ba662d6f chore(deps): update pnpm to v8.15.6 2024-04-03 19:47:56 +09:00
e041a83121 chore(deps): update dependency node-gyp to v10.1.0 2024-04-03 19:47:44 +09:00
42185e59d5 chore(deps): update dependency rollup to v4.14.0 2024-04-03 19:47:37 +09:00
975e9719ad fix(deps): update dependency youtubei.js to v9.2.0 2024-04-01 01:30:18 +09:00
31e51a67db chore(i18n): Update translation files
Updated by "Cleanup translation files" hook in Weblate.

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/
2024-03-31 16:39:49 +02:00
d5f829d8d0 Fixing the dislike skipping issue #1902 2024-03-31 23:39:42 +09:00
0dbf0295b8 i18n Translation to Dutch/nl 2024-03-31 23:39:42 +09:00
daaf48f453 chore(deps): update dependency node-gyp to v10.1.0 (#1910)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-31 03:04:02 +09:00
1d9e021681 chore(deps): update dependency node-gyp to v10.1.0 (#1908)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-31 02:50:07 +09:00
6dd36c74e0 fix(deps): update dependency @cliqz/adblocker-electron to v1.27.0 (#1906)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-31 02:49:57 +09:00
b933218762 fix(deps): update dependency @cliqz/adblocker-electron-preload to v1.27.0 (#1907)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-30 03:51:10 +09:00
26f8814a97 chore(deps): update dependency rollup to v4.13.2 (#1901)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-29 21:02:37 +09:00
236ba7536e chore(deps): update dependency glob to v10.3.12 (#1900)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-29 21:00:50 +09:00
faaf996b16 chore(deps): update dependency vite to v5.2.7 (#1905)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-29 21:00:15 +09:00
5a637fd6e7 fix(deps): update dependency node-html-parser to v6.1.13 (#1903)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-29 21:00:08 +09:00
aca1d30d2f chore(i18n): Translated using Weblate (Dutch)
Currently translated at 16.3% (56 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/nl/
2024-03-28 15:35:09 +01:00
5c3eecb3fd chore(deps): update dependency discord-api-types to v0.37.77 (#1899)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-28 23:11:31 +09:00
9da3ad2fb7 chore(deps): update dependency electron to v29.1.6 (#1898)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-28 17:30:29 +09:00
d45d597136 chore(i18n): Translated using Weblate (Portuguese)
Currently translated at 100.0% (342 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/pt/
2024-03-28 07:47:08 +01:00
2495d5da99 chore(i18n): Translated using Weblate (Dutch)
Currently translated at 5.5% (19 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/nl/
2024-03-27 21:31:00 +01:00
33aeafd19c chore(i18n): Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (342 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/zh_Hant/
2024-03-27 21:31:00 +01:00
374d0ce5e7 chore(i18n): Translated using Weblate (Russian)
Currently translated at 100.0% (342 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ru/
2024-03-27 21:31:00 +01:00
371805334b Improve video title filters (#1667) 2024-03-28 02:54:16 +09:00
47dbeff0d0 fix: fix switch-repeat
fix #1810
2024-03-28 02:40:29 +09:00
17652b5b77 chore(deps): update dependency rollup to v4.13.1 (#1896)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-28 01:12:07 +09:00
9608c2a7fc chore(i18n): Added translation using Weblate (Hebrew) 2024-03-27 08:26:39 +01:00
8abe2823d7 chore(deps): update dependency node-gyp to v10.1.0 (#1890)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-27 01:18:08 +09:00
dbc7f23ab8 chore(deps): update dependency node-gyp to v10.1.0 (#1889)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-26 20:31:13 +09:00
357bd935e4 Update changelog for v3.3.5 2024-03-26 10:58:49 +00:00
f99ca53a6d Bump version to 3.3.5 2024-03-26 11:51:38 +01:00
8700c1a110 chore(deps): update dependency node-gyp to v10.1.0 (#1885)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-26 19:51:34 +09:00
c5e37b791c chore(deps): update dependency @typescript-eslint/eslint-plugin to v7.4.0 (#1886)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-26 19:51:29 +09:00
307f6387ab fix(style): resolve #1887 2024-03-26 19:09:51 +09:00
652a150a0a chore(i18n): Translated using Weblate (Swedish)
Currently translated at 8.4% (29 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/sv/
2024-03-26 10:45:23 +01:00
2c59badb46 chore(i18n): Update translation files
Updated by "Remove blank strings" hook in Weblate.

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/
2024-03-26 10:41:31 +01:00
69087bbf1f chore(i18n): Translated using Weblate (Swedish)
Currently translated at 7.6% (26 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/sv/
2024-03-26 10:41:31 +01:00
af78f1596a chore(i18n): Translated using Weblate (French)
Currently translated at 98.8% (338 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/fr/
2024-03-26 10:41:30 +01:00
fca936a698 chore(i18n): Added translation using Weblate (Swedish) 2024-03-25 19:06:56 +01:00
54b70f6b3e chore(deps): update dependency vite to v5.2.6 (#1883)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-25 05:08:49 +09:00
62f7d440fa Update changelog for v3.3.4 2024-03-23 18:21:29 +00:00
752ccbf482 Bump version to 3.3.4 2024-03-24 03:14:20 +09:00
a8bc53912d fix(style): fix miniplayer style 2024-03-24 02:07:36 +09:00
ed700c2916 fix(style): fix fullscreen style and in-app-menu 2024-03-24 01:28:34 +09:00
97695444af Update changelog for v3.3.3 2024-03-23 15:44:08 +00:00
85e5e1814a Bump version to 3.3.3 2024-03-24 00:37:13 +09:00
88c84a50d0 chore(deps): update dependency electron to v29.1.5 (#1876)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-24 00:24:06 +09:00
0004fb3fc8 chore(deps): update dependency typescript to v5.4.3 (#1877)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-24 00:22:34 +09:00
9cbaf5797b chore(deps): update dependency discord-api-types to v0.37.76 (#1878)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-24 00:22:28 +09:00
1df75ae82f chore(deps): update dependency vite to v5.2.4 (#1881)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-24 00:22:22 +09:00
4d86af5437 Ambient Plugin cleanup (#1880) 2024-03-24 00:22:15 +09:00
ba0876fd8b chore(i18n): Translated using Weblate (Thai)
Currently translated at 69.5% (238 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/th/
2024-03-21 19:01:58 +01:00
a3a3fca694 chore(i18n): Translated using Weblate (Thai)
Currently translated at 69.2% (237 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/th/
2024-03-20 18:50:45 +01:00
de4396936d chore(deps): update dependency vite to v5.2.2 (#1875)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-21 00:58:59 +09:00
164575296f fix(deps): update dependency solid-js to v1.8.16 (#1873)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-20 17:36:36 +09:00
7e8cbfc4c0 chore(i18n): Translated using Weblate (Portuguese)
Currently translated at 97.3% (333 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/pt/
2024-03-19 16:01:50 +01:00
679938ccf7 fix: add support for Wayland
fix #1864
2024-03-19 21:11:10 +09:00
5a6d681bf4 chore(deps): update dependency @typescript-eslint/eslint-plugin to v7.3.1 (#1868)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-19 18:10:26 +09:00
62304b723e chore(deps): update dependency discord-api-types to v0.37.75 (#1867)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-19 18:10:04 +09:00
c89bb4606f chore(i18n): Translated using Weblate (Hungarian)
Currently translated at 12.8% (44 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/hu/
2024-03-18 12:01:57 +01:00
14c50e0d57 chore(deps): update pnpm to v8.15.5 (#1865)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-18 13:37:14 +09:00
f7e9cf9a29 fix: Fix Miniplayer image size (#1863) 2024-03-18 02:46:44 +09:00
4bb3f41828 fix(style): fixed image/video alignment when toggle is active (#1862) 2024-03-18 02:46:23 +09:00
e4759ebe25 chore(i18n): Translated using Weblate (Lithuanian)
Currently translated at 84.7% (290 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/lt/
2024-03-17 11:13:36 +01:00
ce33a92f02 chore(i18n): Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (342 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/zh_Hant/
2024-03-17 11:13:36 +01:00
dd44c07450 chore(i18n): Translated using Weblate (Russian)
Currently translated at 100.0% (342 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ru/
2024-03-17 11:13:36 +01:00
15a5b7a820 chore(i18n): Translated using Weblate (German)
Currently translated at 100.0% (342 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/de/
2024-03-17 11:13:36 +01:00
41b7e095eb chore: Update README-is.md (#1858) 2024-03-17 11:53:15 +09:00
f34a297fcf chore(deps): update dependency vite-plugin-solid to v2.10.2 (#1859)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-17 11:52:59 +09:00
9b2c1a320b fix: Ambient Mode intialization improvement (#1857) 2024-03-17 11:52:46 +09:00
70ed6f8e6c chore(i18n): Update translation files
Updated by "Remove blank strings" hook in Weblate.

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/
2024-03-17 02:01:51 +01:00
5a2489f0bf chore(i18n): Translated using Weblate (Dutch)
Currently translated at 4.9% (17 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/nl/
2024-03-17 02:01:50 +01:00
a7d035022a chore(i18n): Translated using Weblate (Thai)
Currently translated at 69.0% (236 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/th/
2024-03-17 02:01:50 +01:00
b879a70b24 chore(i18n): Added translation using Weblate (Dutch) 2024-03-16 14:48:17 +01:00
ec4e9a1d47 chore(deps): bump follow-redirects from 1.15.5 to 1.15.6 (#1856)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-15 14:45:05 +09:00
d9c52c0a7f chore(README): Nicer Readme 2.0 (#1833) 2024-03-15 14:43:57 +09:00
81ecf18231 chore(deps): update dependency discord-api-types to v0.37.74 (#1854)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-15 14:40:22 +09:00
b0b12a075d chore(deps): update dependency esbuild to v0.20.2 (#1855)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-15 14:40:16 +09:00
54c428083c Improve ambient mode (#1853) 2024-03-15 14:39:31 +09:00
60228a387a chore(deps): update dependency electron to v29.1.4 (#1852)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-14 18:32:17 +09:00
3e04baef00 chore(deps): update dependency electron to v29.1.3 (#1851)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-14 13:34:42 +09:00
573bcba1a0 chore(i18n): Translated using Weblate (Bulgarian)
Currently translated at 25.7% (88 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/bg/
2024-03-13 18:01:58 +01:00
ae2fad5db3 chore(i18n): Translated using Weblate (French)
Currently translated at 95.6% (327 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/fr/
2024-03-13 18:01:56 +01:00
c8fc12569c chore(deps): update dependency rollup to v4.13.0 (#1850)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-13 08:00:29 +09:00
df8efe3fa4 chore(i18n): Translated using Weblate (Bulgarian)
Currently translated at 11.1% (38 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/bg/
2024-03-12 17:01:53 +01:00
HKi
251131b9b5 chore(i18n): Translated using Weblate (Vietnamese)
Currently translated at 99.4% (340 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/vi/
2024-03-12 17:01:53 +01:00
35fb61087a fix(deps): update dependency electron-store to v8.2.0 (#1843)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-12 07:45:40 +09:00
cbec88ff47 chore(deps): update dependency electron to v29.1.1 (#1841)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-12 07:43:13 +09:00
f4319616a6 fix(deps): update dependency i18next to v23.10.1 (#1842)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-12 07:43:04 +09:00
1534b7a67f chore(deps): update dependency @typescript-eslint/eslint-plugin to v7.2.0 (#1848)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-12 07:05:33 +09:00
cbfcc9d140 chore(deps): update dependency vite to v5.1.6 (#1847)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-12 07:05:27 +09:00
60d10a9222 fix(deps): update dependency async-mutex to v0.5.0 (#1849)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-12 07:05:18 +09:00
17e090d5c5 chore(i18n): Translated using Weblate (Hungarian)
Currently translated at 8.4% (29 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/hu/
2024-03-11 07:01:55 +01:00
fa6b4fa83b chore(i18n): Translated using Weblate (Japanese)
Currently translated at 100.0% (342 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ja/
2024-03-11 07:01:54 +01:00
e4b5244d95 fix(deps): update dependency ts-morph to v22 (#1846)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-11 08:27:01 +09:00
04dc5d6314 chore(i18n): Added translation using Weblate (Hungarian) 2024-03-10 16:54:07 +01:00
33ccb03f90 chore(i18n): Translated using Weblate (Italian)
Currently translated at 100.0% (342 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/it/
2024-03-08 23:01:58 +01:00
80011ed3aa chore(i18n): Translated using Weblate (Polish)
Currently translated at 100.0% (342 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/pl/
2024-03-07 20:01:57 +01:00
3e43cf5959 chore(deps): update dependency discord-api-types to v0.37.73 (#1840)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-08 04:00:53 +09:00
bbd590dde8 chore(deps): update dependency rollup to v4.12.1 (#1837)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-07 19:47:53 +09:00
0975a951e4 chore: Changed a single word (README-is.md) (#1836) 2024-03-07 05:27:39 +09:00
8b78f227a7 chore(deps): update dependency typescript to v5.4.2 (#1838)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-07 05:27:06 +09:00
5a93a04b61 chore(deps): update dependency electron-vite to v2.1.0 (#1823)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-05 15:47:51 +09:00
b971eb4191 chore(deps): update dependency @typescript-eslint/eslint-plugin to v7.1.1 (#1829)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-05 15:41:23 +09:00
403e825b8d chore(deps): update dependency vite to v5.1.5 (#1831)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-05 15:41:15 +09:00
9164eba88c Revert "chore(deps): update dependency electron-builder to v24.13.3" (#1818) 2024-03-03 04:56:49 +09:00
bb83bbac38 chore(deps): update dependency electron-builder to v24.13.3 (#1774)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-03 04:50:28 +09:00
651a641b22 chore: Update bug_report.yml 2024-03-02 23:56:23 +09:00
441b5fc8dd fix(style): fix navigation bar items are not working
resolve #1381
resolve #1396
resolve #1649
2024-03-02 23:51:18 +09:00
4fba9445d1 chore(i18n): Translated using Weblate (Norwegian Bokmål)
Currently translated at 66.6% (228 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/nb_NO/
2024-03-02 08:07:24 +01:00
3fb5e01ca5 chore(i18n): Translated using Weblate (Spanish)
Currently translated at 100.0% (342 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/es/
2024-03-02 08:07:24 +01:00
09b2b0d507 chore(deps): update playwright monorepo to v1.42.1 (#1816)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-02 15:31:55 +09:00
a9be35481a chore(i18n): Translated using Weblate (Romanian)
Currently translated at 100.0% (342 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ro/
2024-03-01 15:00:24 +01:00
c871506a69 chore(i18n): Translated using Weblate (Romanian)
Currently translated at 100.0% (342 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ro/
2024-03-01 15:00:24 +01:00
8e6790d366 chore(i18n): Translated using Weblate (Norwegian Bokmål)
Currently translated at 66.0% (226 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/nb_NO/
2024-03-01 15:00:22 +01:00
46620c5ec9 fix(tray): fix tray icon ratio in macOS 2024-03-01 03:20:37 +09:00
5f090169da fix: Add scale ratio for tray icons (#1811) 2024-03-01 03:14:51 +09:00
2205150b86 chore(i18n): Translated using Weblate (Romanian)
Currently translated at 19.5% (67 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ro/
2024-02-29 14:48:03 +01:00
3c4bb8a8fc chore(i18n): Translated using Weblate (Ukrainian)
Currently translated at 100.0% (342 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/uk/
2024-02-29 14:48:03 +01:00
77d0e71529 chore(i18n): Added translation using Weblate (Romanian) 2024-02-29 13:18:59 +01:00
cf974e2d62 chore(i18n): Translated using Weblate (Icelandic)
Currently translated at 98.8% (338 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/is/
2024-02-29 01:02:08 +01:00
ee03db4745 fix(README-is): image path 2024-02-28 14:59:36 +09:00
efd2061058 Icelandic translation of the readme file (#1806) 2024-02-28 14:58:32 +09:00
e7ed20f62f chore(deps): update dependency electron to v29.1.0 (#1808)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-28 14:58:25 +09:00
36d4c08a56 chore(deps): update playwright monorepo to v1.42.0 (#1805)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-28 14:57:10 +09:00
2a939e615c chore(deps): update dependency eslint to v8.57.0 (#1793)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-27 04:39:40 +09:00
9825165286 chore(deps): update dependency @typescript-eslint/eslint-plugin to v7.1.0 (#1800)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-27 04:30:11 +09:00
55c934ac7c fix: remove possible memory leak 2024-02-27 02:42:55 +09:00
c7715115ee chore(i18n): Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (342 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/zh_Hans/
2024-02-26 18:01:55 +01:00
e93b5e8135 chore(deps): update dependency discord-api-types to v0.37.71 (#1799)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-27 01:20:07 +09:00
fd6ba1eda1 fix(downloader): fix memory leak reported in #1791 2024-02-26 19:14:13 +09:00
34f5411aec chore(i18n): Translated using Weblate (Indonesian)
Currently translated at 100.0% (342 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/id/
2024-02-25 13:02:04 +01:00
2b74ec2ef8 chore(i18n): Translated using Weblate (German)
Currently translated at 99.7% (341 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/de/
2024-02-25 13:02:03 +01:00
14dd0e8e03 chore(deps): update pnpm to v8.15.4 (#1795)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-25 17:40:19 +09:00
b0156261b7 chore(deps): update dependency @types/semver to v7.5.8 (#1797)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-25 17:40:12 +09:00
05d520f1c1 chore(i18n): Translated using Weblate (Icelandic)
Currently translated at 98.8% (338 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/is/
2024-02-23 15:02:00 +01:00
ccd44c79e8 fix: center the pause icon (#1786) 2024-02-23 22:56:40 +09:00
7be48ab05e fix(deps): update dependency @cliqz/adblocker-electron to v1.26.16 (#1788)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-23 22:56:19 +09:00
2d40b410b5 fix(deps): update dependency @cliqz/adblocker-electron-preload to v1.26.16 (#1789)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-23 22:47:34 +09:00
f54df86eec fix(deps): update dependency youtubei.js to v9.1.0 (#1790)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-23 20:55:24 +09:00
1be476de54 fix(deps): update dependency i18next to v23.10.0 (#1785)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-22 22:17:30 +09:00
82fa8719a9 chore(i18n): Translated using Weblate (Icelandic)
Currently translated at 97.0% (332 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/is/
2024-02-22 11:02:05 +01:00
7600620c4a chore(i18n): Translated using Weblate (Turkish)
Currently translated at 100.0% (342 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/tr/
2024-02-22 11:02:03 +01:00
c5217f3e1e chore(i18n): Translated using Weblate (Polish)
Currently translated at 100.0% (342 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/pl/
2024-02-22 11:02:03 +01:00
706279852a chore(i18n): Translated using Weblate (Spanish)
Currently translated at 100.0% (342 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/es/
2024-02-22 11:02:03 +01:00
3a6274504f fix(ytm-bugs): fixed a scrollbar-color bug that affected Chromium 121 and later
fix #1737
2024-02-22 12:53:34 +09:00
3aa9398481 chore(deps): update dependency electron to v29 (#1773)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-22 11:58:40 +09:00
7cca435b1d chore(deps): update dependency vite to v5.1.4 (#1778)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-22 00:10:41 +09:00
241b5800d1 chore(deps): bump ip from 2.0.0 to 2.0.1 (#1777)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-21 11:02:47 +09:00
8abb8acdd3 chore(i18n): Translated using Weblate (Icelandic)
Currently translated at 19.0% (65 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/is/
2024-02-21 02:54:14 +01:00
ef8226c091 chore(i18n): Translated using Weblate (Spanish)
Currently translated at 100.0% (342 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/es/
2024-02-21 02:54:13 +01:00
7484e1bf9a chore(i18n): Added translation using Weblate (Icelandic) 2024-02-20 23:55:29 +01:00
2919fd54b7 Update changelog for v3.3.2 2024-02-20 12:07:35 +00:00
9eeb1c986a release 3.3.2 2024-02-20 20:59:48 +09:00
d37cd2418c fix: fix bugs in MPRIS, and improve MPRIS (#1760)
Co-authored-by: JellyBrick <shlee1503@naver.com>
Co-authored-by: Totto <32566573+Totto16@users.noreply.github.com>
2024-02-20 20:50:55 +09:00
8bd05f525d chore(deps): rollback dependency electron-builder to v24.9.1 2024-02-20 15:24:27 +09:00
47b23b414c chore(deps): update dependency electron-builder to v24.13.1 2024-02-20 14:43:04 +09:00
6f70d179c7 fix: fixed an issue that caused infinite loops when using Music Together
fix #1752
2024-02-20 12:57:49 +09:00
62a86e9267 fix(deps): update dependency electron-updater to v6.1.8 (#1770)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-20 12:55:26 +09:00
6358a2d0b1 chore(deps): update dependency electron-builder to v24.12.0 (#1771)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-20 12:55:17 +09:00
273633c2ce chore(i18n): Translated using Weblate (Korean)
Currently translated at 100.0% (342 of 342 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ko/
2024-02-20 04:15:04 +01:00
8b1209ef73 chore(i18n): Translated using Weblate (Italian)
Currently translated at 100.0% (340 of 340 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/it/
2024-02-20 03:55:03 +01:00
47505e9748 chore(i18n): Translated using Weblate (German)
Currently translated at 100.0% (340 of 340 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/de/
2024-02-20 03:55:03 +01:00
5178cc6bd8 feat(scrobblers): use BrowserWindow instead of shell.openExternal (#1758) 2024-02-20 11:54:57 +09:00
d9a27fff42 chore(deps): update dependency @typescript-eslint/eslint-plugin to v7.0.2 (#1763)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-20 11:54:37 +09:00
9e6560b814 chore(i18n): Translated using Weblate (Italian)
Currently translated at 99.7% (339 of 340 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/it/
2024-02-19 19:01:59 +01:00
afdb19a742 chore(deps): update dependency esbuild to v0.20.1 (#1759)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-19 18:23:04 +09:00
0ae5b668f5 fix(in-app-menu): default config 2024-02-19 17:06:01 +09:00
10533e28fa fix: error.html path 2024-02-19 16:53:32 +09:00
6189e67819 fix(deps): update dependency i18next to v23.9.0 (#1754)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-19 14:29:22 +09:00
f9ad505e40 fix: scrobbler migration 2024-02-19 14:27:24 +09:00
9b011101ed Update changelog for v3.3.1 2024-02-18 12:43:37 +00:00
a6ed8bf3aa release 3.3.1 (HOTFIX) 2024-02-18 21:36:04 +09:00
87acf4cf04 hotfix: in-app-menu position issue 2024-02-18 21:35:41 +09:00
b6fe2afd75 chore: Update README.md 2024-02-18 20:57:38 +09:00
6d9bb8eb1c Update changelog for v3.3.0 2024-02-18 11:40:17 +00:00
192fd0620f release 3.3.0 2024-02-18 20:32:45 +09:00
00d0b31980 fix(scrobbler): remove snake_case 2024-02-18 20:21:19 +09:00
5edb2131d2 fix(in-app-menu): implement auto close 2024-02-18 20:00:52 +09:00
4657aeca45 fix: apply fix from eslint 2024-02-18 11:58:26 +09:00
9f5651a8ba fix: fix upgrade button
fix #1199
2024-02-18 10:50:36 +09:00
570dcfee29 fix: revert fbc02a494a 2024-02-18 10:50:15 +09:00
2c130ce80d chore(mpris): use override keyword 2024-02-18 10:34:29 +09:00
8457115105 fix(mpris): fix mpris invalid position
- fix #1726
2024-02-18 10:26:45 +09:00
fbc02a494a fix(in-app-menu): simplified if-statement 2024-02-18 09:50:20 +09:00
7e2c254ecf fix(in-app-menu): should be disabled by default in linux env 2024-02-18 09:47:05 +09:00
11936a889e fix(deps): update dependency i18next to v23.8.3 (#1751)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-18 07:33:35 +09:00
f33970addd import fixed ./constants (#1748) 2024-02-18 07:33:11 +09:00
2c02b7193d chore(deps): update dependency rollup to v4.12.0 (#1743)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-17 10:08:33 +09:00
3f80b598ae chore(deps): bump undici from 5.28.2 to 5.28.3 (#1747)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-17 10:07:19 +09:00
477068ed49 chore(deps): update dependency vite to v5.1.3 (#1742)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-16 08:44:31 +09:00
b4083874ac fix: invalid podcast artist name
🤦
2024-02-16 08:41:00 +09:00
c5d0673b2f chore(deps): update dependency vite-plugin-solid to v2.10.1 (#1734)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-15 22:32:18 +09:00
9ccc44474b chore(deps): update dependency discord-api-types to v0.37.70 (#1740)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-15 22:31:50 +09:00
98e341f122 chore(deps): update dependency electron to v28.2.3 (#1736)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-15 22:29:11 +09:00
b23eba51dd chore(deps): update pnpm to v8.15.3 (#1739)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-15 22:28:47 +09:00
980005a58c chore(deps): update dependency rollup to v4.11.0 (#1738)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-15 22:28:41 +09:00
aba58b1d34 fix(deps): update dependency solid-js to v1.8.15 (#1735)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-15 22:28:17 +09:00
bb6a127d22 chore(deps): update dependency vite to v5.1.2 (#1733)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-15 20:32:18 +09:00
ac6e30a6b6 chore(i18n): Translated using Weblate (Polish)
Currently translated at 98.2% (334 of 340 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/pl/
2024-02-14 19:01:58 +01:00
3f23282eed chore(deps): update dependency vite-plugin-solid to v2.10.0 (#1732)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-14 20:36:09 +09:00
199a77819c chore(deps): update pnpm to v8.15.2 (#1729)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-14 01:16:33 +09:00
89a53b2854 Update Copyright - 2024 (#1730) 2024-02-14 01:06:26 +09:00
c57bf79b08 chore(i18n): Translated using Weblate (Indonesian)
Currently translated at 100.0% (340 of 340 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/id/
2024-02-12 23:42:44 +01:00
eabb3392b4 fix: discord RPC (fix #1664) 2024-02-13 07:41:32 +09:00
c78cc3a38d chore(deps): update dependency @typescript-eslint/eslint-plugin to v7 (#1728)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-13 07:10:13 +09:00
011ffd538b fix(deps): update dependency @floating-ui/dom to v1.6.3 (#1727)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-13 06:41:43 +09:00
f386576196 chore(deps): update dependency electron to v28.2.2 (#1717)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-12 05:07:22 +09:00
bab3526f0f chore(deps): update dependency vite to v5.1.1 (#1718)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-12 05:07:14 +09:00
115923b422 chore(deps): update dependency @types/semver to v7.5.7 (#1724)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-12 05:07:07 +09:00
fefa8c8750 fix(deps): update dependency @floating-ui/dom to v1.6.2 (#1725)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-12 05:07:01 +09:00
3aa80c0f01 chore(i18n): Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (340 of 340 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/zh_Hant/
2024-02-11 04:02:12 +01:00
aea219994a chore(deps): update dependency rollup to v4.10.0 (#1719)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-11 00:36:55 +09:00
74e22ccecd chore(i18n): Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (340 of 340 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/zh_Hans/
2024-02-09 17:44:03 +01:00
db09cf5ffb chore(i18n): Translated using Weblate (Indonesian)
Currently translated at 58.8% (200 of 340 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/id/
2024-02-07 14:01:55 +01:00
cc1d13f203 chore(i18n): Translated using Weblate (Spanish)
Currently translated at 100.0% (340 of 340 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/es/
2024-02-07 14:01:54 +01:00
0cd1ce6a79 fix(deps): update dependency solid-js to v1.8.14 (#1713)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-06 18:00:05 +09:00
95254fc2ff chore(deps): update dependency @typescript-eslint/eslint-plugin to v6.21.0 (#1711) 2024-02-06 05:20:13 +09:00
205376aadf fix(deps): update dependency semver to v7.6.0 (#1712) 2024-02-06 05:20:04 +09:00
6f057bfbfc fix(in-app-menu): remove unused style 2024-02-06 03:09:16 +09:00
bb39481666 fix(plugins): fix many bugs (in-app-menu, album-color-theme, blur-nav-bar) 2024-02-06 02:02:08 +09:00
ddb9968195 fix: workarounds for region restrict 2024-02-06 01:30:36 +09:00
a309729fa4 fix: revert electron version to v28 2024-02-06 01:30:09 +09:00
ba7e065ba6 fix: remove sign-in button (fix #1199) 2024-02-06 00:34:43 +09:00
ee05893d4c feat(album-color-theme): change nav-bar style 2024-02-06 00:00:32 +09:00
febc63edef fix(in-app-menu): fix app crash in production 2024-02-05 23:14:00 +09:00
b3c05c8647 refactor(in-app-menu): refactor in-app-menu plugin (#1710)
Co-authored-by: JellyBrick <shlee1503@naver.com>
2024-02-05 22:26:25 +09:00
cd8701d0e5 chore(i18n): Translated using Weblate (Ukrainian)
Currently translated at 100.0% (340 of 340 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/uk/
2024-02-05 02:02:48 +01:00
3b41edb62d chore(i18n): Translated using Weblate (Japanese)
Currently translated at 100.0% (340 of 340 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ja/
2024-02-05 02:02:38 +01:00
ab3b8495df chore(i18n): Translated using Weblate (Czech)
Currently translated at 89.7% (305 of 340 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/cs/
2024-02-05 02:02:37 +01:00
b04cd79bcf chore(i18n): Translated using Weblate (Indonesian)
Currently translated at 52.0% (177 of 340 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/id/
2024-02-02 15:01:47 +01:00
c864e5764a chore(i18n): Translated using Weblate (Turkish)
Currently translated at 100.0% (340 of 340 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/tr/
2024-02-02 15:01:47 +01:00
1f71df6c41 chore(i18n): Translated using Weblate (Russian)
Currently translated at 100.0% (340 of 340 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ru/
2024-02-02 15:01:47 +01:00
0decda57ab chore(deps): update playwright monorepo to v1.41.2 (#1706)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-02 17:47:46 +09:00
5bfd3a4562 chore(deps): update dependency electron to v29.0.0-beta.5 (#1707)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-02 17:47:36 +09:00
d4af820ae8 chore(i18n): Translated using Weblate (Korean)
Currently translated at 100.0% (340 of 340 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ko/
2024-02-01 14:50:56 +01:00
3ec25b7779 chore(i18n): Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (338 of 338 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/zh_Hans/
2024-02-01 14:12:03 +01:00
a9ee12b05e chore(i18n): Translated using Weblate (Turkish)
Currently translated at 100.0% (338 of 338 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/tr/
2024-02-01 14:12:03 +01:00
a612d1c1fd feat(album-color-theme): support album color theme in all pages (#1685) 2024-02-01 22:11:57 +09:00
fb48d24e0d fix(deps): update dependency youtubei.js to v9.0.2 (#1704)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-01 15:55:16 +09:00
38d19d9ea7 fix(deps): update dependency i18next to v23.8.2 (#1702)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-01 01:55:17 +09:00
4950abc399 fix(PiP): fix multiple handler 2024-01-31 18:40:36 +09:00
e3ad804dc4 feat: Support disabling scrobbling for non-music content (#1665)
Co-authored-by: JellyBrick <shlee1503@naver.com>
2024-01-31 17:41:55 +09:00
A L
f2f15bc3cc chore(i18n): Translated using Weblate (Bulgarian)
Currently translated at 5.0% (17 of 337 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/bg/
2024-01-30 23:01:21 +01:00
4624a1022a fix(deps): update dependency youtubei.js to v9 (#1682)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-30 19:04:03 +09:00
A L
cc169da6d4 chore(i18n): Added translation using Weblate (Bulgarian) 2024-01-30 10:10:26 +01:00
c58ed21661 chore(deps): update dependency electron to v29.0.0-beta.4 (#1698)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-30 09:16:36 +09:00
c483733bc3 fix(deps): update dependency i18next to v23.8.1 (#1694)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-30 09:13:41 +09:00
9738f2f6ae chore(deps): update dependency @typescript-eslint/eslint-plugin to v6.20.0 (#1700)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-30 09:10:18 +09:00
ecdd8eb9f6 chore(deps): update pnpm to v8.15.1 (#1699)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-30 09:10:06 +09:00
47e2052ce0 chore(i18n): Translated using Weblate (Russian)
Currently translated at 100.0% (337 of 337 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ru/
2024-01-29 19:07:33 +01:00
a34eb31d9c chore(i18n): Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (337 of 337 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/zh_Hant/
2024-01-29 18:47:29 +01:00
c03cab179e chore(i18n): Translated using Weblate (Russian)
Currently translated at 88.7% (299 of 337 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ru/
2024-01-29 18:47:29 +01:00
0d61cf906d Fix #1617
Remove duplicated call of `titleBar.appendChild(logo);`.
2024-01-29 14:50:41 +02:00
b3c1aa6b4b chore(deps): update dependency esbuild to v0.20.0 (#1691)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-28 07:07:22 +09:00
4904620ce6 chore(deps): update pnpm to v8.15.0 (#1692)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-28 07:07:09 +09:00
feaccb593d fix(deps): update dependency i18next to v23.7.20 (#1684)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-27 18:29:12 +09:00
9ad2baea59 chore(deps): update dependency electron to v29.0.0-beta.3 (#1683)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-27 18:29:01 +09:00
df77086039 chore(deps): update dependency electron to v29.0.0-beta.2 (#1681)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-26 09:45:16 +09:00
ceb844473a chore(deps): update dependency rollup to v4.9.6 (#1663)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-26 09:44:12 +09:00
a0932b0dc4 chore(i18n): Translated using Weblate (Italian)
Currently translated at 100.0% (337 of 337 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/it/
2024-01-25 23:01:50 +01:00
0be37716ef chore(deps): update dependency electron to v29.0.0-beta.1 (#1670) 2024-01-26 00:17:06 +09:00
c07b05a7be fix(deps): update dependency i18next to v23.7.19 (#1680) 2024-01-26 00:16:55 +09:00
94b1da9db0 chore(deps): update dependency @typescript-eslint/eslint-plugin to v6.19.1 (#1669) 2024-01-26 00:16:28 +09:00
5fa7a1273f chore(deps): update pnpm to v8.14.3 (#1668) 2024-01-26 00:16:18 +09:00
cf9088785b chore(deps): update dependency vite-plugin-inspect to v0.8.3 (#1672) 2024-01-26 00:15:44 +09:00
adf3e3150e chore(deps): update dependency esbuild to v0.19.12 (#1673) 2024-01-26 00:13:11 +09:00
dbeb63018e fix(deps): update dependency @electron/remote to v2.1.2 (#1676) 2024-01-26 00:12:55 +09:00
51a39d240c chore: Update issue templates (#1661)
* Update bug_report.yml

* Update feature_request.yml

* Update bug_report.yml
2024-01-26 00:08:39 +09:00
4061f8e0e6 chore(i18n): Translated using Weblate (Japanese)
Currently translated at 100.0% (337 of 337 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ja/
2024-01-24 14:01:53 +01:00
d32e60249a chore(i18n): Translated using Weblate (Indonesian)
Currently translated at 52.5% (177 of 337 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/id/
2024-01-23 08:01:49 +01:00
b84a1e43af chore(i18n): Translated using Weblate (Thai)
Currently translated at 18.3% (62 of 337 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/th/
2024-01-23 08:01:48 +01:00
f5c22b63aa chore(i18n): Translated using Weblate (French)
Currently translated at 83.6% (282 of 337 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/fr/
2024-01-23 08:01:47 +01:00
41700799c7 chore(i18n): Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (337 of 337 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/zh_Hans/
2024-01-22 07:01:47 +01:00
b15b421975 chore(i18n): Translated using Weblate (Japanese)
Currently translated at 92.5% (312 of 337 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ja/
2024-01-22 07:01:47 +01:00
cca4de8684 chore(deps): update playwright monorepo to v1.41.1 (#1660)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-21 12:46:32 +09:00
946c2790c4 fix(deps): update dependency i18next to v23.7.18 (#1662)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-21 12:46:15 +09:00
3a033f1bab chore(deps): update actions/dependency-review-action action to v4 (#1654)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-21 12:44:10 +09:00
67a04a2840 chore(deps): update dependency electron to v29.0.0-alpha.11 (#1656)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-21 12:43:57 +09:00
dd48e46854 chore(deps): update dependency vite to v5.0.12 [security] (#1659)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-21 12:43:17 +09:00
99edb15c77 chore(i18n): Translated using Weblate (Indonesian)
Currently translated at 32.6% (110 of 337 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/id/
2024-01-21 04:29:51 +01:00
8503afeac7 chore(i18n): Translated using Weblate (Japanese)
Currently translated at 85.7% (289 of 337 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ja/
2024-01-21 04:29:50 +01:00
0528637135 chore(i18n): Translated using Weblate (Vietnamese)
Currently translated at 99.4% (335 of 337 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/vi/
2024-01-19 09:00:21 +01:00
bf20a2b3be chore(i18n): Translated using Weblate (German)
Currently translated at 99.4% (335 of 337 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/de/
2024-01-19 09:00:19 +01:00
0db55ce4f3 fix(deps): update dependency async-mutex to v0.4.1 (#1653)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-18 17:40:11 +09:00
21347e9d0a chore(i18n): Translated using Weblate (Vietnamese)
Currently translated at 43.3% (146 of 337 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/vi/
2024-01-17 16:06:28 +01:00
4333a25c31 chore(i18n): Translated using Weblate (Ukrainian)
Currently translated at 100.0% (337 of 337 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/uk/
2024-01-17 16:06:26 +01:00
5b20e491bd chore(i18n): Translated using Weblate (Turkish)
Currently translated at 100.0% (337 of 337 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/tr/
2024-01-17 16:06:25 +01:00
bc05f5849d chore(i18n): Translated using Weblate (Spanish)
Currently translated at 100.0% (337 of 337 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/es/
2024-01-17 16:06:25 +01:00
b1046bc28d chore(deps): update playwright monorepo to v1.41.0 (#1651)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-17 11:31:10 +09:00
d5ab36f42e fix(crossfade): fix #1633 2024-01-16 22:38:05 +09:00
922d78dcee fix: notification close 2024-01-16 21:14:37 +09:00
de6506e6b4 fix: notification closing 2024-01-16 21:13:07 +09:00
9d136c8dd5 fix: apply fix from eslint 2024-01-16 21:02:55 +09:00
26de7f940e fix: fix #1621 2024-01-16 20:34:00 +09:00
7c404ba2ea chore(song-info): fix typo 2024-01-16 19:14:16 +09:00
96d2a72bfa chore(song-info): change from array to Set
change from `array` to `Set` to prevent the duplicate callback from being stored
2024-01-16 19:13:35 +09:00
10f41bddad fix(i18n): use dash (-) instead of under-bar (_) 2024-01-16 17:36:48 +09:00
39d2f3ec80 chore(i18n): Translated using Weblate (Korean)
Currently translated at 100.0% (337 of 337 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ko/
2024-01-16 09:33:15 +01:00
512b446a3d chore(i18n): Translated using Weblate (English)
Currently translated at 100.0% (337 of 337 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/en/
2024-01-16 09:33:15 +01:00
c9b96f0488 fix(tuna-obs): partially fix #1596 2024-01-16 17:27:27 +09:00
c84ea257d5 fix: os-specific plugin 2024-01-16 17:14:02 +09:00
6512f5ad2a fix(discord): fix hide duration button
fix #1644

Thanks to @DronovasP
2024-01-16 16:41:23 +09:00
e5d0eced5d fix(store): remove duplicated if-statement 2024-01-16 16:40:06 +09:00
f424ee5170 feat: Better Scrobbler Plugin (#1640)
Co-authored-by: JellyBrick <shlee1503@naver.com>
2024-01-16 16:36:27 +09:00
ea0f6c401d chore(deps): update dependency electron to v29.0.0-alpha.10 (#1645)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-16 14:34:05 +09:00
5c5f51b3de chore(deps): update dependency @typescript-eslint/eslint-plugin to v6.19.0 (#1643)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-16 12:52:28 +09:00
7caf02ebba chore(i18n): Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (331 of 331 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/zh_Hans/
2024-01-16 04:06:12 +01:00
f6a444b970 chore(i18n): Translated using Weblate (Russian)
Currently translated at 73.1% (242 of 331 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ru/
2024-01-15 02:26:24 +01:00
d19a36b44f chore(i18n): Translated using Weblate (Polish)
Currently translated at 100.0% (331 of 331 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/pl/
2024-01-15 02:26:23 +01:00
aacb126fb5 chore(i18n): Translated using Weblate (Korean)
Currently translated at 100.0% (331 of 331 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ko/
2024-01-15 02:26:23 +01:00
5adf45cde2 chore(i18n): Translated using Weblate (Italian)
Currently translated at 100.0% (331 of 331 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/it/
2024-01-15 02:26:23 +01:00
0980aad060 chore(i18n): Translated using Weblate (Spanish)
Currently translated at 100.0% (331 of 331 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/es/
2024-01-15 02:26:23 +01:00
069e5ac8b8 chore(README): Fix plugins names and add plugins in/to Readme (in menu too) (#1624) 2024-01-14 14:50:40 +09:00
b5f6762997 chore(i18n): Translated using Weblate (Polish)
Currently translated at 100.0% (331 of 331 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/pl/
2024-01-14 06:50:01 +01:00
c2abfe4b41 chore(i18n): Translated using Weblate (Polish)
Currently translated at 91.2% (302 of 331 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/pl/
2024-01-13 13:43:07 +01:00
3964d03a3b fix: apply fix for album-actions 2024-01-13 17:28:12 +09:00
a82c4ce499 fix(album-actions): Fixed album actions (#1639) 2024-01-13 17:08:51 +09:00
2f54fa19e6 fix(yt-music bugs): fix margin in video mode 2024-01-13 12:35:54 +09:00
aacb4b3147 fix(deps): update dependency @xhayper/discord-rpc to v1.1.2 2024-01-13 10:10:32 +09:00
60980251f2 chore: update pnpm-lock 2024-01-13 10:07:55 +09:00
f8e55f95df fix(yt-music bugs): fixed a weird margin-bottom issue when using YouTube Premium 2024-01-13 10:02:18 +09:00
bebd232af0 chore(deps): update playwright monorepo to v1.41.0-beta-1705101589000 (#1638)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-13 09:08:02 +09:00
1a89fbe612 fix(#1543): fix song control doesn't work (#1637)
Co-authored-by: Su-Yong <simssy2205@gmail.com>
2024-01-13 09:06:41 +09:00
e73584c2aa feat(issue-template): add checklist 2024-01-13 07:34:00 +09:00
96a713074f chore(deps): update playwright monorepo to v1.41.0-beta-1705092460000 (#1635)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-13 07:20:59 +09:00
aedfa4ca06 chore(deps): update dependency rollup to v4.9.5 (#1629)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-13 07:17:58 +09:00
ac187f722b chore(i18n): Translated using Weblate (Vietnamese)
Currently translated at 29.6% (98 of 331 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/vi/
2024-01-12 23:16:48 +01:00
cd87642384 chore(i18n): Translated using Weblate (Indonesian)
Currently translated at 4.5% (15 of 331 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/id/
2024-01-12 23:16:48 +01:00
4a736d3211 chore(i18n): Translated using Weblate (Thai)
Currently translated at 1.2% (4 of 331 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/th/
2024-01-12 23:16:48 +01:00
e586940c57 chore(i18n): Translated using Weblate (Portuguese)
Currently translated at 100.0% (331 of 331 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/pt/
2024-01-12 23:16:47 +01:00
ab36a21583 chore(i18n): Translated using Weblate (French)
Currently translated at 86.4% (286 of 331 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/fr/
2024-01-12 23:16:47 +01:00
c0c1c3b626 chore(i18n): Translated using Weblate (German)
Currently translated at 91.5% (303 of 331 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/de/
2024-01-12 23:16:47 +01:00
918bd7fdb1 chore(deps): update dependency electron to v29.0.0-alpha.9 (#1627)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-12 11:57:43 +09:00
971d1a5776 chore(i18n): Translated using Weblate (Vietnamese)
Currently translated at 16.9% (56 of 331 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/vi/
2024-01-11 18:06:13 +01:00
1235d46e73 chore(i18n): Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (331 of 331 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/zh_Hans/
2024-01-11 18:06:13 +01:00
451b98833b chore(i18n): Translated using Weblate (Portuguese)
Currently translated at 99.3% (329 of 331 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/pt/
2024-01-11 18:06:12 +01:00
48f9be9712 chore(i18n): Translated using Weblate (Italian)
Currently translated at 100.0% (331 of 331 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/it/
2024-01-11 18:06:12 +01:00
fd8d59bada chore: update pnpm-lock 2024-01-11 08:47:46 +09:00
99ce0b7f9c chore(deps): update dependency electron to v29.0.0-alpha.8 (#1608)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-11 08:08:37 +09:00
88ace9ab35 fix(deps): update dependency @cliqz/adblocker-electron to v1.26.15 (#1615)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-11 08:06:41 +09:00
63b0ea60e4 chore(deps): update dependency rollup to v4.9.4 (#1591)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-11 08:02:31 +09:00
b4ecf0f935 fix(deps): update dependency @cliqz/adblocker-electron-preload to v1.26.15 (#1616)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-11 08:02:10 +09:00
c846f18086 chore(deps): update pnpm to v8.14.1 (#1619)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-11 08:02:03 +09:00
8a851b06f9 chore(deps): update dependency eslint-plugin-prettier to v5.1.3 (#1618)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-10 14:36:19 +09:00
5484dc8bd1 chore(deps): update dependency @typescript-eslint/eslint-plugin to v6.18.1 (#1612)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-09 19:36:07 +09:00
6c47ac36e3 fix(deps): update dependency youtubei.js to v8.2.0 (#1614)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-09 19:31:02 +09:00
3554496803 chore(deps): update dependency electron-vite to v2.0.0 (#1609)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-09 19:30:50 +09:00
b8a197615e chore(deps): update dependency @typescript-eslint/eslint-plugin to v6.18.0 (#1603)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-08 23:22:16 +09:00
2ed949920f chore(i18n): Translated using Weblate (Ukrainian)
Currently translated at 100.0% (331 of 331 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/uk/
2024-01-08 14:06:18 +00:00
d76f4dade3 chore(i18n): Translated using Weblate (Ukrainian)
Currently translated at 100.0% (331 of 331 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/uk/
2024-01-08 14:06:17 +00:00
aacd01ce7c chore(i18n): Translated using Weblate (Ukrainian)
Currently translated at 100.0% (331 of 331 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/uk/
2024-01-08 14:06:16 +00:00
d501b016fc chore(i18n): Translated using Weblate (Turkish)
Currently translated at 100.0% (331 of 331 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/tr/
2024-01-08 14:06:14 +00:00
b1503cfb87 chore(deps): update dependency electron-vite to v2.0.0-beta.4 (#1602)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-07 04:19:01 +09:00
8a004ae9dd chore(i18n): Translated using Weblate (Spanish)
Currently translated at 100.0% (331 of 331 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/es/
2024-01-06 18:06:15 +01:00
de709cc7c9 fix: download/pip button for podcast video 2024-01-06 11:05:15 +09:00
6b7c43925a feat: rename IPC 2024-01-06 10:17:40 +09:00
5d5cc58f59 chore(tuna-obs): set keepAlive to true for reuse TCP socket 2024-01-06 09:37:47 +09:00
3e6bab7f15 fix(in-app-menu): fix invalid margin-top
fix #1597
2024-01-06 09:15:57 +09:00
7e17a8b73b fix(README): fix plugins path
fix #1598
2024-01-06 09:03:42 +09:00
129b798d8f chore(README): add demo image 2024-01-06 06:00:07 +09:00
a3a411e197 fix(config): fix duplicated array value 2024-01-06 01:07:57 +09:00
6e6acd6f19 Update changelog for v3.2.2 2024-01-05 14:44:33 +00:00
34cb79eeaf Bump version to 3.2.2 2024-01-05 23:33:42 +09:00
1c30a07031 chore(deps): update dependency playwright to v1.41.0-alpha-jan-5-2024 2024-01-05 23:30:16 +09:00
5dd5f41ef5 chore(deps): update dependency electron to v29.0.0-alpha.7
Change to electron v29 to use node.js v20.
2024-01-05 23:28:24 +09:00
45a3c11d51 chore(i18n): Translated using Weblate (Korean)
Currently translated at 100.0% (331 of 331 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ko/
2024-01-05 14:24:44 +00:00
8bd3b4d3f0 fix(visualizer): fixed an issue with audio getting unusually loud 2024-01-05 23:23:39 +09:00
4e3cb5806d fix(music-together): modernize code 2024-01-05 23:11:26 +09:00
6563eb4ddd chore(i18n): Translated using Weblate (Spanish)
Currently translated at 100.0% (330 of 330 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/es/
2024-01-05 14:02:12 +00:00
895386f6f8 fix(music-together): typing 2024-01-05 23:01:55 +09:00
3810955e56 fix(skip-silences): fix audio distorted
fix #1141
2024-01-05 21:58:36 +09:00
59c521e53f fix: download button not working 2024-01-05 21:04:52 +09:00
25d266f8f9 feat(tray): Add song info and paused icon (#1592) 2024-01-05 20:56:47 +09:00
0c3c380591 chore(deps): update dependency rollup to v4.9.3 2024-01-05 20:56:17 +09:00
a20cfa30a1 chore(deps): update dependency vite to v5.0.11 2024-01-05 20:43:13 +09:00
fefe899393 chore(i18n): Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (328 of 328 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/zh_Hans/
2024-01-05 11:12:50 +01:00
55759e8d7a chore(i18n): Translated using Weblate (Italian)
Currently translated at 100.0% (328 of 328 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/it/
2024-01-05 11:12:50 +01:00
ddb561937f fix(deps): update dependency i18next to v23.7.16 2024-01-04 22:41:16 +09:00
198cb71a4c chore(deps): update dependency electron to v28.1.1 2024-01-04 22:38:45 +09:00
c34b880752 chore(deps): update dependency electron-vite to v2.0.0-beta.3 2024-01-04 22:38:30 +09:00
76944e3e41 fix(deps): update dependency i18next to v23.7.14 2024-01-03 17:35:30 +09:00
68cd76f2af chore(deps): update pnpm to v8.14.0 2024-01-03 17:35:23 +09:00
81145b52b7 fix(#1580): fix NEW badge doesn't show 2024-01-03 15:02:29 +09:00
2a19dab061 chore(i18n): Translated using Weblate (Vietnamese)
Currently translated at 3.3% (11 of 328 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/vi/
2024-01-02 10:52:22 +01:00
6958d59d4f chore(i18n): Translated using Weblate (Lithuanian)
Currently translated at 89.6% (294 of 328 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/lt/
2024-01-02 09:49:04 +01:00
8a51dfad87 chore(i18n): Translated using Weblate (Chinese (Simplified))
Currently translated at 89.6% (294 of 328 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/zh_Hans/
2024-01-02 09:49:04 +01:00
5bb4d9efbe chore(i18n): Translated using Weblate (Turkish)
Currently translated at 100.0% (328 of 328 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/tr/
2024-01-02 09:49:04 +01:00
927aa5f24b chore(i18n): Translated using Weblate (Portuguese)
Currently translated at 89.6% (294 of 328 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/pt/
2024-01-02 09:49:03 +01:00
d695bc93a1 chore(i18n): Translated using Weblate (Polish)
Currently translated at 89.3% (293 of 328 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/pl/
2024-01-02 09:49:03 +01:00
b05fb4ccbe chore(i18n): Translated using Weblate (Norwegian Bokmål)
Currently translated at 67.9% (223 of 328 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/nb_NO/
2024-01-02 09:49:03 +01:00
299eb7e7d6 chore(i18n): Translated using Weblate (Italian)
Currently translated at 89.3% (293 of 328 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/it/
2024-01-02 09:49:03 +01:00
ae26333224 chore(i18n): Translated using Weblate (French)
Currently translated at 85.9% (282 of 328 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/fr/
2024-01-02 09:49:03 +01:00
35176469b0 chore(i18n): Translated using Weblate (Spanish)
Currently translated at 100.0% (328 of 328 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/es/
2024-01-02 09:49:03 +01:00
4e74f9cbc5 chore(i18n): Translated using Weblate (Czech)
Currently translated at 94.8% (311 of 328 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/cs/
2024-01-02 09:49:02 +01:00
4091b36f36 chore(i18n): Translated using Weblate (English)
Currently translated at 100.0% (328 of 328 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/en/
2024-01-02 09:49:02 +01:00
b3f805fce6 chore(i18n): Translated using Weblate (Vietnamese)
Currently translated at 2.4% (8 of 328 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/vi/
2024-01-02 09:43:14 +01:00
b129a3e8d8 chore(i18n): Translated using Weblate (Chinese (Simplified))
Currently translated at 89.9% (295 of 328 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/zh_Hans/
2024-01-02 09:43:13 +01:00
64ea1fdb58 chore(i18n): Translated using Weblate (Turkish)
Currently translated at 100.0% (328 of 328 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/tr/
2024-01-02 09:43:13 +01:00
8fcf59ed0a chore(i18n): Translated using Weblate (Spanish)
Currently translated at 100.0% (328 of 328 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/es/
2024-01-02 09:43:12 +01:00
9811ca63de chore(i18n): Translated using Weblate (Czech)
Currently translated at 94.8% (311 of 328 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/cs/
2024-01-02 09:43:12 +01:00
9028f88299 chore(i18n): Translated using Weblate (English)
Currently translated at 100.0% (328 of 328 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/en/
2024-01-02 09:43:12 +01:00
fd47766d93 chore(deps): update dependency @typescript-eslint/eslint-plugin to v6.17.0 2024-01-02 17:34:04 +09:00
26b12c7208 chore(i18n): Added translation using Weblate (Vietnamese) 2024-01-02 07:19:07 +01:00
8da9b3454d chore(deps): update dependency esbuild to v0.19.11 2024-01-01 20:32:13 +09:00
205cbefc83 Update changelog for v3.2.1 2024-01-01 00:32:24 +00:00
0e94c72eef Bump version to 3.2.1 2024-01-01 09:22:46 +09:00
c055641351 chore(i18n): Translated using Weblate (Korean)
Currently translated at 100.0% (328 of 328 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ko/
2024-01-01 01:19:52 +01:00
c0a3aa99de chore(i18n): Translated using Weblate (English)
Currently translated at 100.0% (328 of 328 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/en/
2024-01-01 01:19:52 +01:00
8a8976acef chore(i18n): Translated using Weblate (Czech)
Currently translated at 94.8% (311 of 328 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/cs/
2024-01-01 01:06:02 +01:00
e409165e1b chore(i18n): Translated using Weblate (English)
Currently translated at 100.0% (328 of 328 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/en/
2024-01-01 01:06:02 +01:00
b278140796 chore(i18n): Update translation files
Updated by "Remove blank strings" hook in Weblate.

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/
2024-01-01 01:01:00 +01:00
397056a54d chore(i18n): Translated using Weblate (Turkish)
Currently translated at 26.5% (87 of 328 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/tr/
2024-01-01 01:01:00 +01:00
edecd65419 chore(i18n): Translated using Weblate (Korean)
Currently translated at 100.0% (328 of 328 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ko/
2024-01-01 01:01:00 +01:00
4d2d0b7bd6 chore(i18n): Translated using Weblate (Czech)
Currently translated at 85.6% (281 of 328 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/cs/
2024-01-01 01:01:00 +01:00
0ca4e34efd chore(i18n): Translated using Weblate (Czech)
Currently translated at 85.6% (281 of 328 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/cs/
2024-01-01 01:00:59 +01:00
43f3226c3a fix: fix #1574 2024-01-01 08:36:48 +09:00
0a6dbecc05 fix: fix #1575 2024-01-01 08:36:22 +09:00
f5aa179cd6 chore(i18n): Translated using Weblate
Co-authored-by: Allan Nordhøy <epost@anotheragency.no>
Co-authored-by: inson1 <vaclav.svarc01@seznam.cz>
Co-authored-by: Anonymous <noreply@weblate.org>
2024-01-01 04:53:59 +09:00
3140e91dda Update changelog for v3.2.0 2023-12-31 16:31:59 +00:00
022f8ff65c Merge branch 'master' of https://github.com/th-ch/youtube-music 2024-01-01 01:23:01 +09:00
5e63cc2e89 Bump version to 3.2.0 2024-01-01 01:22:48 +09:00
880ed99846 Revert "fix(deps): update dependency @xhayper/discord-rpc to v1.1.2"
This reverts commit 050d55c736.
2024-01-01 00:34:49 +09:00
222e78c85b fix(in-app-menu): fix in-app-menu tooltip position 2023-12-31 23:48:01 +09:00
050d55c736 fix(deps): update dependency @xhayper/discord-rpc to v1.1.2 2023-12-31 23:40:26 +09:00
13ef8560ff fix: pnpm build error 2023-12-31 23:40:09 +09:00
78d990c079 feat(album-color-theme): improve Album Color Theme style (#1571) 2023-12-31 23:04:44 +09:00
4d3e2c09da feat(menu): add more detail in Menu (#1570) 2023-12-31 20:56:24 +09:00
aa899d247a chore(plugins): change default config album-actions, music-together 2023-12-31 13:56:42 +09:00
ee0c512529 feat(music-together): Add new plugin Music Together (#1562)
* feat(music-together): test `peerjs`

* feat(music-together): replace `prompt` to `custom-electron-prompt`

* fix(music-together): fix

* test fix

* wow

* test

* feat(music-together): improve `onStart`

* fix: adblocker

* fix(adblock): fix crash with `peerjs`

* feat(music-together): add host UI

* feat(music-together): implement addSong, removeSong, syncQueue

* feat(music-together): inject panel

* feat(music-together): redesign music together panel

* feat(music-together): sync queue, profile

* feat(music-together): sync progress, song, state

* fix(music-together): fix some bug

* fix(music-together): fix sync queue

* feat(music-together): support i18n

* feat(music-together): improve sync queue

* feat(music-together): add profile in music item

* refactor(music-together): refactor structure

* feat(music-together): add permission

* fix(music-together): fix queue sync bug

* fix(music-together): fix some bugs

* fix(music-together): fix permission not working on guest mode

* fix(music-together): fix queue sync relate bugs

* fix(music-together): fix automix items not append using music together

* fix(music-together): fix

* feat(music-together): improve video injection

* fix(music-together): fix injection code

* fix(music-together): fix broadcast guest

* feat(music-together): add more permission

* fix(music-together): fix injector

* fix(music-together): fix guest add song logic

* feat(music-together): add popup close listener

* fix(music-together): fix connection issue

* fix(music-together): fix connection issue 2

* feat(music-together): reserve playlist

* fix(music-together): exclude automix songs

* fix(music-together): fix playlist index sync bug

* fix(music-together): fix connection failed error and sync index

* fix(music-together): fix host set index bug

* fix: apply fix from eslint

* feat(util): add `ImageElementFromSrc`

* chore(util): update jsdoc

* feat(music-together): add owner name

* chore(music-together): add translation

* feat(music-together): add progress sync

* chore(music-together): remove `console.log`

---------

Co-authored-by: JellyBrick <shlee1503@naver.com>
2023-12-31 13:52:15 +09:00
5f9b522307 chore(deps): update dependency rollup to v4.9.2 (#1567)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-31 04:05:49 +09:00
c207e29980 fix(deps): update dependency i18next to v23.7.13 (#1569)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-31 04:05:44 +09:00
df4d2d6b72 chore(ambient-mode): remove console.log 2023-12-31 02:28:31 +09:00
c3dd20cabd chore(i18n): Translated using Weblate (Korean)
Currently translated at 100.0% (296 of 296 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ko/
2023-12-30 17:09:06 +00:00
7a6db95d1a chore(i18n): Translated using Weblate (Czech)
Currently translated at 80.4% (238 of 296 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/cs/
2023-12-30 17:09:05 +00:00
bc6825d63b chore(i18n): Translated using Weblate (Czech)
Currently translated at 76.8% (226 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/cs/
2023-12-29 16:14:02 +01:00
5e79e9e0f2 feat: Add new plugin Album actions (#1515)
Co-authored-by: JellyBrick <shlee1503@naver.com>
2023-12-30 00:13:56 +09:00
5e303c2ba8 fix(deps): update dependency i18next to v23.7.12 (#1564)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-29 22:26:41 +09:00
0bd9c16356 fix: Only apply scale factor on Windows (#1565) 2023-12-29 22:26:24 +09:00
f0f5d9da2f feat(ambient-mode): support ambient mode on Song section
resolve #1555
2023-12-29 21:46:27 +09:00
TC
f46c431f4c Move cask definition to separate repo 2023-12-29 11:26:55 +01:00
62410e9ee2 feat(in-app-menu): add show on hover 2023-12-29 17:52:31 +09:00
46f76f1408 chore(i18n): Translated using Weblate (Indonesian)
Currently translated at 3.7% (11 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/id/
2023-12-27 18:20:59 +01:00
5e071e16d8 chore(i18n): Translated using Weblate (Turkish)
Currently translated at 29.2% (86 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/tr/
2023-12-27 18:20:58 +01:00
c0238588bd chore(i18n): Translated using Weblate (Russian)
Currently translated at 78.5% (231 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ru/
2023-12-27 18:20:58 +01:00
Nik
30002d660a chore(i18n): Translated using Weblate (Russian)
Currently translated at 78.5% (231 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ru/
2023-12-27 18:20:58 +01:00
48eeb6bca3 fix: picture-in-picture icon 2023-12-28 02:17:42 +09:00
e67699fed5 fix: fixed an issue with the download button disappearing
- resolve #1551
2023-12-28 02:08:03 +09:00
8aeae45965 chore(i18n): Translated using Weblate (Ukrainian)
Currently translated at 77.2% (227 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/uk/
2023-12-27 13:09:36 +01:00
ce7491941b chore(i18n): Translated using Weblate (Russian)
Currently translated at 74.8% (220 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ru/
2023-12-27 13:09:36 +01:00
1dce03c4f2 chore(i18n): Translated using Weblate (Polish)
Currently translated at 100.0% (294 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/pl/
2023-12-27 13:09:36 +01:00
62eae6d5d0 chore(deps): update dependency @typescript-eslint/eslint-plugin to v6.16.0 (#1556)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-27 18:37:06 +09:00
15b2b26b84 chore(deps): update pnpm to v8.13.1 (#1557)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-27 18:36:57 +09:00
9664c17c47 chore(deps): update dependency ws to v8.16.0 (#1559)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-27 18:36:51 +09:00
8067dad2fa fix(deps): update dependency youtubei.js to v8.1.0 (#1560)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-27 18:36:42 +09:00
4dcaa510d9 chore(i18n): Translated using Weblate (Indonesian)
Currently translated at 3.7% (11 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/id/
2023-12-25 12:42:54 +01:00
b6e918089d chore(i18n): Translated using Weblate (Turkish)
Currently translated at 29.2% (86 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/tr/
2023-12-25 12:42:54 +01:00
1c9e6b1bb8 chore(i18n): Translated using Weblate (Polish)
Currently translated at 97.9% (288 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/pl/
2023-12-25 12:42:54 +01:00
ebd304c252 fix(deps): update dependency node-html-parser to v6.1.12 (#1554)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-25 20:37:05 +09:00
36083c4173 Revert "fix(deps): update dependency @xhayper/discord-rpc to v1.1.2" (#1552) 2023-12-25 03:48:15 +09:00
a084b060d8 chore(deps): update dependency electron to v28.1.0 2023-12-25 03:32:28 +09:00
432c79b606 fix(deps): update dependency @xhayper/discord-rpc to v1.1.2 2023-12-25 03:32:07 +09:00
0f1f0ee933 chore(deps): update dependency eslint-plugin-prettier to v5.1.2 2023-12-25 03:31:59 +09:00
9b1a4b8d88 chore(i18n): Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (294 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/zh_Hant/
2023-12-23 21:07:03 +01:00
1a7a665915 chore(i18n): Translated using Weblate (Czech)
Currently translated at 76.5% (225 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/cs/
2023-12-22 03:06:46 +01:00
623ecf7fb8 chore(i18n): Update translation files
Updated by "Remove blank strings" hook in Weblate.

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/
2023-12-20 17:44:47 +01:00
0dc9c6a1a9 chore(i18n): Translated using Weblate (Czech)
Currently translated at 72.7% (214 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/cs/
2023-12-20 17:44:47 +01:00
72c5eaa5ff chore(i18n): Translated using Weblate (Czech)
Currently translated at 82.3% (242 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/cs/
2023-12-20 13:54:56 +01:00
0f47b94b7d chore(i18n): Update translation files
Updated by "Remove blank strings" hook in Weblate.

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/
2023-12-20 13:53:36 +01:00
9abe15f1ad chore(i18n): Translated using Weblate (Czech)
Currently translated at 82.3% (242 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/cs/
2023-12-20 13:53:35 +01:00
96afda92c8 chore(i18n): Translated using Weblate (Czech)
Currently translated at 80.9% (238 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/cs/
2023-12-20 13:33:50 +01:00
5c6fd4a739 Update README-ko.md 2023-12-20 14:11:53 +02:00
23b87a876d chore(deps): update dependency eslint-plugin-prettier to v5.1.0 2023-12-20 13:59:40 +09:00
737fd05369 chore(deps): update dependency electron-vite to v2.0.0-beta.2 2023-12-20 13:59:28 +09:00
c5bcd89f16 chore(deps): update dependency @typescript-eslint/eslint-plugin to v6.15.0 2023-12-19 16:32:46 +09:00
377e1be0b2 fix(deps): update dependency @foobar404/wave to v2.0.5 2023-12-19 16:32:31 +09:00
a92049c0c9 chore(i18n): Translated using Weblate (Lithuanian)
Currently translated at 100.0% (294 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/lt/
2023-12-19 07:21:28 +01:00
27a2955bba fix: fix homebrew cask
- resolve #1514
2023-12-18 22:02:38 +09:00
cc940e2020 Update changelog for v3.1.1 2023-12-18 12:57:28 +00:00
203c80767d Bump version to 3.1.1 2023-12-18 21:49:31 +09:00
f564039438 chore: fix the example plugins in the README 2023-12-18 14:47:18 +02:00
d6566fb870 chore(i18n): Translated using Weblate (Lithuanian)
Currently translated at 84.3% (248 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/lt/
2023-12-18 13:46:47 +01:00
55ab17e789 chore(i18n): Translated using Weblate (Portuguese)
Currently translated at 100.0% (294 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/pt/
2023-12-18 13:43:08 +01:00
e0eeb720cd feat: upgrade to Vite v5 2023-12-18 21:10:47 +09:00
53ac7ff257 fix: electron-vite dev --watch 2023-12-18 20:00:00 +09:00
a4e2f10afa chore(deps): update dependency playwright to v1.41.0-alpha-dec-18-2023 2023-12-18 19:58:33 +09:00
c9c9d766e6 chore(deps): update dependency rollup to v4.9.1 2023-12-18 19:56:14 +09:00
b82d161180 chore: Update bug_report.yml 2023-12-18 19:47:51 +09:00
7cadacd8cf fix: vite dev mode
fix an issue caused by da3bc5aeb7
2023-12-18 19:07:43 +09:00
fc1a7cda62 chore(i18n): Translated using Weblate (Lithuanian)
Currently translated at 84.3% (248 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/lt/
2023-12-18 10:56:31 +01:00
da3bc5aeb7 fix: renderer plugin load timing
MAGIC OF JAVASCRIPT
2023-12-18 18:42:01 +09:00
ee98344064 chore(i18n): Added translation using Weblate (Lithuanian) 2023-12-17 21:43:08 +01:00
da10eabf99 chore(i18n): Translated using Weblate (Ukrainian)
Currently translated at 69.3% (204 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/uk/
2023-12-17 14:55:42 +01:00
ce3c63c386 chore(i18n): Translated using Weblate (Portuguese)
Currently translated at 73.8% (217 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/pt/
2023-12-17 14:55:42 +01:00
f8c3cff5a9 chore(i18n): Translated using Weblate (Korean)
Currently translated at 100.0% (294 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ko/
2023-12-17 14:55:41 +01:00
08f369f8bc chore(i18n): Translated using Weblate (Portuguese)
Currently translated at 43.5% (128 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/pt/
2023-12-17 08:28:44 +01:00
1517230ede chore(i18n): Translated using Weblate (German)
Currently translated at 100.0% (294 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/de/
2023-12-17 08:28:44 +01:00
45aeadef86 fix(song-info-front): fix type 2023-12-17 16:05:26 +09:00
5ec7c346ca fix(song-info-front): fix parser to parse album name 2023-12-17 15:51:35 +09:00
4b68de1606 fix: update types 2023-12-16 22:39:57 +09:00
7710bcdacc chore(i18n): Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (294 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/zh_Hant/
2023-12-16 11:58:32 +01:00
4c19bcc983 chore(i18n): Translated using Weblate (Turkish)
Currently translated at 26.1% (77 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/tr/
2023-12-16 03:33:06 +01:00
2f50b1423a chore(i18n): Translated using Weblate (French)
Currently translated at 95.9% (282 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/fr/
2023-12-16 03:33:06 +01:00
15768c9691 chore(deps): update dependency eslint to v8.56.0 2023-12-16 11:28:58 +09:00
442eb75b8d chore(i18n): Translated using Weblate (Portuguese)
Currently translated at 43.1% (127 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/pt/
2023-12-16 03:09:12 +01:00
8facd27125 chore(i18n): Translated using Weblate (Italian)
Currently translated at 100.0% (294 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/it/
2023-12-16 03:09:11 +01:00
a302cb6ebf chore(i18n): Translated using Weblate (Spanish)
Currently translated at 100.0% (294 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/es/
2023-12-16 03:09:11 +01:00
32422c7ba9 fix(deps): update dependency i18next to v23.7.11 2023-12-15 13:42:50 +09:00
ca131cb156 chore(deps): update dependency eslint-plugin-import to v2.29.1 2023-12-15 13:42:44 +09:00
5f8262ede1 chore(i18n): Translated using Weblate (Ukrainian)
Currently translated at 65.3% (192 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/uk/
2023-12-14 02:11:40 +01:00
88db9d3693 chore(i18n): Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (294 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/zh_Hant/
2023-12-13 21:33:32 +01:00
0fa6f344f9 chore(i18n): Translated using Weblate (Polish)
Currently translated at 97.6% (287 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/pl/
2023-12-13 21:33:31 +01:00
d1642b3dfb chore(i18n): Translated using Weblate (Polish)
Currently translated at 97.6% (287 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/pl/
2023-12-13 21:33:31 +01:00
7599fce5f5 chore(i18n): Translated using Weblate (Spanish)
Currently translated at 97.6% (287 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/es/
2023-12-13 21:33:31 +01:00
9bd0dc9a7b chore(i18n): Translated using Weblate (Greek)
Currently translated at 23.8% (70 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/el/
2023-12-13 21:33:31 +01:00
dad7cafebc chore(i18n): Translated using Weblate (Russian)
Currently translated at 72.7% (214 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ru/
2023-12-13 16:20:54 +01:00
4febb28201 chore(deps): update dependency rollup to v4.9.0 2023-12-13 21:13:41 +09:00
ced943bad3 chore(deps): update pnpm to v8.12.1 2023-12-13 21:12:07 +09:00
202b8717a2 chore(i18n): Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (294 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/zh_Hant/
2023-12-13 13:10:46 +01:00
eba7026b89 chore(i18n): Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (294 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/zh_Hans/
2023-12-13 13:10:46 +01:00
6b2adca1f4 fix(downloader): fix download button i18n 2023-12-13 18:02:18 +09:00
0c9d3cc057 chore(i18n): Translated using Weblate (Ukrainian)
Currently translated at 42.8% (126 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/uk/
2023-12-13 05:07:02 +01:00
45ec11aaed chore(deps): update pnpm-lock.yaml 2023-12-13 13:06:10 +09:00
4d47fa3fac fix(deps): update dependency @electron/remote to v2.1.1 2023-12-13 12:24:55 +09:00
6322d5bb09 chore(i18n): Translated using Weblate (Indonesian)
Currently translated at 3.0% (9 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/id/
2023-12-12 21:56:36 +01:00
2e8a579049 chore(i18n): Translated using Weblate (Thai)
Currently translated at 1.0% (3 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/th/
2023-12-12 21:56:36 +01:00
9db7e99d7f chore(i18n): Translated using Weblate (Korean)
Currently translated at 100.0% (294 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ko/
2023-12-12 21:56:36 +01:00
ef73989995 chore(i18n): Translated using Weblate (Czech)
Currently translated at 79.9% (235 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/cs/
2023-12-12 21:56:36 +01:00
61024084e9 chore(deps): update dependency ws to v8.15.1 2023-12-13 05:46:56 +09:00
1c71b2020f fix(deps): update dependency i18next to v23.7.9 2023-12-13 05:45:52 +09:00
3b2b545388 chore(i18n): Translated using Weblate (Russian)
Currently translated at 67.6% (199 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ru/
2023-12-12 21:44:51 +01:00
fafc7f94fd chore(i18n): Translated using Weblate (Italian)
Currently translated at 100.0% (294 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/it/
2023-12-12 21:44:50 +01:00
5fa88b5ce9 fix: fix renderer plugin load timing
- fix #1522
2023-12-12 12:53:41 +09:00
a8fe4167db fix(pip): fix invalid position config 2023-12-12 11:11:41 +09:00
0e6b0ddc26 chore(i18n): Translated using Weblate (Korean)
Currently translated at 100.0% (294 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ko/
2023-12-12 02:24:41 +01:00
af88db3865 chore(i18n): Translated using Weblate (Japanese)
Currently translated at 100.0% (294 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ja/
2023-12-12 02:24:41 +01:00
0a1bef556c chore(i18n): Translated using Weblate (English)
Currently translated at 100.0% (294 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/en/
2023-12-12 02:24:41 +01:00
7030181dc1 chore(i18n): Translated using Weblate (English)
Currently translated at 100.0% (294 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/en/
2023-12-12 02:24:41 +01:00
98cb2f61ab chore(deps): update dependency playwright to v1.41.0-alpha-dec-12-2023 2023-12-12 10:23:59 +09:00
a601d0b3d2 chore(deps): update dependency rollup to v4.8.0 2023-12-12 10:22:23 +09:00
8d18923065 chore(i18n): Translated using Weblate (Norwegian Bokmål)
Currently translated at 75.1% (221 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/nb_NO/
2023-12-12 01:08:34 +01:00
4b6a7e0bd7 chore(i18n): Translated using Weblate (English)
Currently translated at 100.0% (294 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/en/
2023-12-12 01:08:34 +01:00
44f87853d6 chore(i18n): Translated using Weblate (Norwegian Bokmål)
Currently translated at 74.8% (220 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/nb_NO/
2023-12-12 01:02:37 +01:00
4ff47bee03 chore(i18n): Translated using Weblate (Norwegian Bokmål)
Currently translated at 74.1% (218 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/nb_NO/
2023-12-12 00:54:03 +01:00
7a2c28df21 chore(i18n): Translated using Weblate (English)
Currently translated at 100.0% (294 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/en/
2023-12-12 00:54:02 +01:00
f7241d1e4a chore(i18n): Added translation using Weblate (Indonesian) 2023-12-12 00:33:55 +01:00
2b5daf3a75 chore(deps): update dependency @typescript-eslint/eslint-plugin to v6.14.0 2023-12-12 06:43:20 +09:00
d7184cf75d chore(i18n): Translated using Weblate (Russian)
Currently translated at 54.0% (159 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ru/
2023-12-11 19:59:59 +01:00
1313d18d44 chore(i18n): Translated using Weblate (Czech)
Currently translated at 80.9% (238 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/cs/
2023-12-11 19:59:58 +01:00
605e9481d9 chore(i18n): Translated using Weblate (English)
Currently translated at 100.0% (294 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/en/
2023-12-11 19:59:58 +01:00
cf4c89f825 chore(i18n): Added translation using Weblate (Thai) 2023-12-11 10:17:18 +01:00
f4f1d4d373 chore(i18n): Translated using Weblate (Norwegian Bokmål)
Currently translated at 46.2% (136 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/nb_NO/
2023-12-11 09:00:43 +01:00
6557b40924 Translated using Weblate (Spanish)
Currently translated at 100.0% (294 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/es/
2023-12-11 00:20:44 +01:00
e01a29c5d1 Translated using Weblate (Spanish)
Currently translated at 100.0% (294 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/es/
2023-12-11 00:20:44 +01:00
d9a7e16d63 Translated using Weblate (Italian)
Currently translated at 99.3% (292 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/it/
2023-12-11 00:20:44 +01:00
d170199d85 Update changelog for v3.1.0 2023-12-10 23:10:52 +00:00
e650aae491 Bump version to 3.1.0 2023-12-11 08:00:42 +09:00
49058dbeab chore: update pnpm-lock.yaml 2023-12-11 07:59:42 +09:00
31d2d91566 Translated using Weblate (Japanese)
Currently translated at 100.0% (294 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ja/
2023-12-10 23:57:22 +01:00
abf2a52b46 fix: in-player adblocker inject timing issue
- fix #1478
2023-12-11 07:46:01 +09:00
d0ca10e1a1 Translated using Weblate (Chinese (Simplified))
Currently translated at 1.0% (3 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/zh_Hans/
2023-12-10 22:57:39 +01:00
fe99a04174 Translated using Weblate (Portuguese)
Currently translated at 31.6% (93 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/pt/
2023-12-10 22:57:39 +01:00
916900ae6a Translated using Weblate (Spanish)
Currently translated at 100.0% (294 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/es/
2023-12-10 22:57:39 +01:00
826c9ba48e fix(package.json): fix RPM version libuuid issue
- fix #1508
2023-12-11 06:57:32 +09:00
7783cc5f30 Translated using Weblate (Chinese (Simplified))
Currently translated at 0.3% (1 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/zh_Hans/
2023-12-10 22:49:58 +01:00
035d7f19ea Translated using Weblate (Spanish)
Currently translated at 99.3% (292 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/es/
2023-12-10 22:49:58 +01:00
294cf15d58 Translated using Weblate (Spanish)
Currently translated at 99.3% (292 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/es/
2023-12-10 22:49:58 +01:00
11fa0dcbc6 Translated using Weblate (Spanish)
Currently translated at 99.3% (292 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/es/
2023-12-10 22:49:58 +01:00
85b53db439 Translated using Weblate (Korean)
Currently translated at 100.0% (294 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ko/
2023-12-10 22:49:57 +01:00
200df100f4 Translated using Weblate (English)
Currently translated at 100.0% (294 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/en/
2023-12-10 22:49:57 +01:00
ba202a8572 chore(deps): update dependency electron to v28 (#1498)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: JellyBrick <shlee1503@naver.com>
2023-12-11 06:44:59 +09:00
daf05239a1 Enable/Disable Navigation without restart (#1507) 2023-12-11 04:21:17 +09:00
b73b5735ec Translated using Weblate (Spanish)
Currently translated at 90.8% (267 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/es/
2023-12-10 04:08:22 +01:00
292248dd35 Translated using Weblate (Spanish)
Currently translated at 90.8% (267 of 294 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/es/
2023-12-10 04:08:22 +01:00
2e240541c8 Turkish(tr)_lang_file (#1513) 2023-12-10 08:41:46 +09:00
ab62ae3682 chore(deps): update dependency ws to v8.15.0 2023-12-10 04:28:02 +09:00
5c3f5d05d3 chore(deps): update pnpm to v8.12.0 2023-12-09 12:38:32 +09:00
c81af537b6 Translated using Weblate (Spanish)
Currently translated at 83.5% (244 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/es/
2023-12-09 01:37:30 +00:00
7295c73371 Translated using Weblate (Spanish)
Currently translated at 83.5% (244 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/es/
2023-12-09 01:37:29 +00:00
5a65e08a94 Translated using Weblate (Spanish)
Currently translated at 83.5% (244 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/es/
2023-12-09 01:37:28 +00:00
45e5bc7df5 Skip Disliked Songs (#1505)
* Added skip-disliked-songs

* Changed it to activate and deactivate without restart

* Added waiter for Element

* MutationObserver can be null

Co-authored-by: JellyBrick <shlee1503@naver.com>

* MutationObserver could not exist

Co-authored-by: JellyBrick <shlee1503@naver.com>

* Update src/plugins/skip-disliked-songs/index.ts

Co-authored-by: JellyBrick <shlee1503@naver.com>

* Replaced double quotes with single quotes

---------

Co-authored-by: JellyBrick <shlee1503@naver.com>
2023-12-09 10:37:17 +09:00
a81cb9515c Translated using Weblate (Spanish)
Currently translated at 39.7% (116 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/es/
2023-12-08 21:55:06 +01:00
88e5cc2728 Translated using Weblate (Spanish)
Currently translated at 39.7% (116 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/es/
2023-12-08 21:55:06 +01:00
1685648328 Translated using Weblate (Spanish)
Currently translated at 39.0% (114 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/es/
2023-12-08 21:54:40 +01:00
9334adacf6 Translated using Weblate (Spanish)
Currently translated at 39.0% (114 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/es/
2023-12-08 21:54:39 +01:00
efbe557dce Update translation files
Updated by "Remove blank strings" hook in Weblate.

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/
2023-12-08 20:37:43 +01:00
52b2625486 Translated using Weblate (Spanish)
Currently translated at 10.6% (31 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/es/
2023-12-08 20:37:43 +01:00
aa0424db08 Translated using Weblate (Spanish)
Currently translated at 10.6% (31 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/es/
2023-12-08 20:37:43 +01:00
157619aa4f chore(deps): update dependency rollup to v4.7.0 2023-12-09 03:23:17 +09:00
ce637968b2 Translated using Weblate (Italian)
Currently translated at 100.0% (292 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/it/
2023-12-08 11:32:34 +01:00
b2a3ed7428 Translated using Weblate (Spanish)
Currently translated at 4.1% (12 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/es/
2023-12-08 11:08:18 +01:00
ca856e4d88 Translated using Weblate (Spanish)
Currently translated at 4.1% (12 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/es/
2023-12-08 11:08:17 +01:00
2ef2536766 Translated using Weblate (Italian)
Currently translated at 100.0% (292 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/it/
2023-12-08 11:08:17 +01:00
1b22633388 Translated using Weblate (Italian)
Currently translated at 100.0% (292 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/it/
2023-12-08 11:08:17 +01:00
db306ad4e0 Translated using Weblate (Italian)
Currently translated at 65.4% (191 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/it/
2023-12-07 19:20:03 +01:00
34a44cb9c6 Translated using Weblate (Italian)
Currently translated at 65.4% (191 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/it/
2023-12-07 19:20:03 +01:00
8c499a6e20 Translated using Weblate (Italian)
Currently translated at 51.3% (150 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/it/
2023-12-07 18:58:33 +01:00
3b816a6fd9 Translated using Weblate (Italian)
Currently translated at 51.3% (150 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/it/
2023-12-07 18:58:33 +01:00
35aba8e25a Translated using Weblate (Italian)
Currently translated at 46.9% (137 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/it/
2023-12-07 18:52:44 +01:00
0eb6723f27 Translated using Weblate (Italian)
Currently translated at 46.9% (137 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/it/
2023-12-07 18:52:44 +01:00
2250ec9372 Translated using Weblate (Spanish)
Currently translated at 1.0% (3 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/es/
2023-12-07 13:48:08 +00:00
ef02b53284 Translated using Weblate (Italian)
Currently translated at 42.1% (123 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/it/
2023-12-07 13:48:08 +00:00
57df7cf3f9 Translated using Weblate (Italian)
Currently translated at 42.1% (123 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/it/
2023-12-07 13:48:07 +00:00
f0cd540726 Translated using Weblate (Ukrainian)
Currently translated at 1.0% (3 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/uk/
2023-12-07 13:48:06 +00:00
7e919395eb chore(deps): update dependency typescript to v5.3.3 2023-12-07 10:03:26 +09:00
facc7252c2 fix(deps): update dependency i18next to v23.7.8 2023-12-07 10:03:06 +09:00
09b8943f69 Translated using Weblate (Italian)
Currently translated at 32.1% (94 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/it/
2023-12-07 01:45:31 +01:00
aa84ffc7e1 Translated using Weblate (French)
Currently translated at 100.0% (292 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/fr/
2023-12-07 01:45:31 +01:00
10162c948b chore: Create zh-CN.json 2023-12-07 09:45:08 +09:00
e8c1cbdd94 BC-BREAK: bump node engines version 2023-12-07 02:52:14 +09:00
5459f623ec Translated using Weblate (Italian)
Currently translated at 32.1% (94 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/it/
2023-12-05 18:59:01 +01:00
2a2cba3539 Translated using Weblate (Italian)
Currently translated at 32.1% (94 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/it/
2023-12-05 18:59:01 +01:00
1ce84607e6 Translated using Weblate (Portuguese)
Currently translated at 30.8% (90 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/pt/
2023-12-05 17:59:26 +01:00
075c54d39f Translated using Weblate (Portuguese)
Currently translated at 30.8% (90 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/pt/
2023-12-05 17:59:26 +01:00
aabb826cb8 Translated using Weblate (Italian)
Currently translated at 13.0% (38 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/it/
2023-12-05 17:59:26 +01:00
3791b1ae1c Translated using Weblate (Italian)
Currently translated at 13.0% (38 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/it/
2023-12-05 17:59:26 +01:00
d4b87d098b Added translation using Weblate (Portuguese) 2023-12-05 17:39:07 +01:00
57e9c13d13 Translated using Weblate (Italian)
Currently translated at 6.8% (20 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/it/
2023-12-05 05:59:05 +01:00
e48e570e69 Translated using Weblate (Italian)
Currently translated at 6.8% (20 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/it/
2023-12-05 05:59:05 +01:00
b7d4d5b022 Translated using Weblate (Czech)
Currently translated at 61.3% (179 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/cs/
2023-12-05 05:59:05 +01:00
dc8b0173e9 Added translation using Weblate (Spanish) 2023-12-05 05:59:05 +01:00
840729126e fix(macos): fix app crash in macOS 2023-12-05 13:36:23 +09:00
ed90b97a92 chore(deps): update dependency vite to v4.5.1 2023-12-05 13:29:45 +09:00
bbe4f07651 chore(deps): update dependency @typescript-eslint/eslint-plugin to v6.13.2 (#1452)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-05 13:29:23 +09:00
66df83a86d fix: Homebrew latest release url parsing (#1496)
Co-authored-by: Gian Marco Cinalli <gianmarco.cinalli@immobiliare.it>
2023-12-05 10:56:59 +09:00
dfedd8f091 Translated using Weblate (Italian)
Currently translated at 4.1% (12 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/it/
2023-12-04 19:15:58 +01:00
58ec6eebfb Translated using Weblate (Czech)
Currently translated at 58.5% (171 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/cs/
2023-12-04 19:15:58 +01:00
3ba4130bc6 Translated using Weblate (Czech)
Currently translated at 58.5% (171 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/cs/
2023-12-04 19:15:58 +01:00
7dbbf38e78 Added translation using Weblate (Italian) 2023-12-04 17:31:24 +01:00
51e04162a7 Translated using Weblate (Czech)
Currently translated at 57.1% (167 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/cs/
2023-12-04 09:58:03 +01:00
d3325e2490 Translated using Weblate (Czech)
Currently translated at 56.1% (164 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/cs/
2023-12-04 05:05:31 +01:00
d2708ee32f Translated using Weblate (Czech)
Currently translated at 56.1% (164 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/cs/
2023-12-04 05:05:31 +01:00
781a09c717 Translated using Weblate (Czech)
Currently translated at 55.4% (162 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/cs/
2023-12-04 04:55:52 +01:00
11605293dd Translated using Weblate (Czech)
Currently translated at 55.4% (162 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/cs/
2023-12-04 04:55:52 +01:00
3f0b946190 Translated using Weblate (Czech)
Currently translated at 52.7% (154 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/cs/
2023-12-03 23:49:11 +01:00
74972f053a Translated using Weblate (Czech)
Currently translated at 52.7% (154 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/cs/
2023-12-03 23:49:11 +01:00
d85190ace1 Translated using Weblate (Czech)
Currently translated at 51.7% (151 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/cs/
2023-12-03 23:39:39 +01:00
5755b4ac7f Translated using Weblate (Czech)
Currently translated at 51.7% (151 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/cs/
2023-12-03 23:39:38 +01:00
3c24f2edcd Translated using Weblate (Czech)
Currently translated at 51.3% (150 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/cs/
2023-12-03 23:26:36 +01:00
6828520853 Translated using Weblate (Czech)
Currently translated at 51.3% (150 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/cs/
2023-12-03 23:26:36 +01:00
2ba7dddb95 Translated using Weblate (Czech)
Currently translated at 50.6% (148 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/cs/
2023-12-03 22:17:53 +00:00
57a8922d04 Translated using Weblate (Czech)
Currently translated at 51.0% (149 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/cs/
2023-12-03 22:17:53 +00:00
640098860a Translated using Weblate (Czech)
Currently translated at 51.0% (149 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/cs/
2023-12-03 22:17:52 +00:00
53384d9f3b Translated using Weblate (Russian)
Currently translated at 13.6% (40 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ru/
2023-12-03 22:17:51 +00:00
89d8d98a35 fix: remove import 'process' 2023-12-04 03:53:24 +09:00
7b78ba6761 Translated using Weblate (Polish)
Currently translated at 100.0% (292 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/pl/
2023-12-03 17:43:49 +01:00
3926a9a0c0 Translated using Weblate (French)
Currently translated at 99.6% (291 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/fr/
2023-12-03 17:43:48 +01:00
0708cd5a38 Added translation using Weblate (Polish) 2023-12-03 11:35:51 +01:00
e20e9ca771 Added translation using Weblate (Ukrainian) 2023-12-03 10:26:51 +01:00
be1038bafd Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (292 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/zh_Hant/
2023-12-03 01:50:48 +01:00
ebc087963b Translated using Weblate (French)
Currently translated at 85.2% (249 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/fr/
2023-12-03 01:50:48 +01:00
020bdc0811 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (292 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/zh_Hant/
2023-12-02 23:23:55 +00:00
a0d1ad6a47 Translated using Weblate (French)
Currently translated at 19.1% (56 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/fr/
2023-12-02 23:23:54 +00:00
62e5679791 fix(deps): update dependency ts-morph to v21 2023-12-03 07:50:56 +09:00
35568bd299 Translated using Weblate (Chinese (Traditional))
Currently translated at 46.5% (136 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/zh_Hant/
2023-12-02 21:13:54 +01:00
1e40b377af Translated using Weblate (Chinese (Traditional))
Currently translated at 46.5% (136 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/zh_Hant/
2023-12-02 21:13:54 +01:00
1073de1b45 Translated using Weblate (Czech)
Currently translated at 46.5% (136 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/cs/
2023-12-02 21:13:45 +01:00
1d5788acaf Translated using Weblate (Chinese (Traditional))
Currently translated at 35.6% (104 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/zh_Hant/
2023-12-02 20:27:58 +01:00
8fb446588d Translated using Weblate (Chinese (Traditional))
Currently translated at 35.6% (104 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/zh_Hant/
2023-12-02 20:27:58 +01:00
6cec34b2ac Translated using Weblate (Chinese (Traditional))
Currently translated at 35.6% (104 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/zh_Hant/
2023-12-02 20:27:58 +01:00
763d3e8f74 Translated using Weblate (German)
Currently translated at 100.0% (292 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/de/
2023-12-02 20:27:58 +01:00
7da0a913f1 Update changelog for v3.0.2 2023-12-02 18:39:16 +00:00
ca04c4561b Bump version to 3.0.2 2023-12-03 03:30:08 +09:00
7d8fbf49a8 Translated using Weblate (Chinese (Traditional))
Currently translated at 23.6% (69 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/zh_Hant/
2023-12-02 19:29:34 +01:00
75e15b948d Translated using Weblate (Chinese (Traditional))
Currently translated at 23.6% (69 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/zh_Hant/
2023-12-02 19:29:28 +01:00
125b69fd75 Translated using Weblate (Chinese (Traditional))
Currently translated at 23.6% (69 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/zh_Hant/
2023-12-02 19:29:28 +01:00
a68d6b64dd Translated using Weblate (French)
Currently translated at 8.9% (26 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/fr/
2023-12-02 19:29:28 +01:00
a60d4264dc fix: pnpm install doesn't refresh lock file 2023-12-03 03:16:07 +09:00
9e2c6b1afa fix: update pnpm-lock.yaml 2023-12-03 03:07:11 +09:00
14965a93e9 fix: simple-youtube-age-restriction-bypass 2023-12-03 02:49:17 +09:00
f62664b6a5 fix(adblocker): fix In-Player adblocker
- resolves #1478
2023-12-03 02:06:49 +09:00
60cb7f32f1 fix(in-app-menu/i18n): fix hide-dom-window-controls 2023-12-03 01:00:33 +09:00
008b3ad710 Translated using Weblate (Chinese (Traditional))
Currently translated at 1.0% (3 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/zh_Hant/
2023-12-02 16:59:02 +01:00
8cae64f496 fix(menu): crash on linux
- resolves #1477
2023-12-03 00:54:36 +09:00
5cdc1bc762 Update translation files
Updated by "Remove blank strings" hook in Weblate.

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/
2023-12-02 16:29:40 +01:00
15c455105b Translated using Weblate (French)
Currently translated at 8.5% (25 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/fr/
2023-12-02 16:29:40 +01:00
14407a98c9 Translated using Weblate (English)
Currently translated at 100.0% (292 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/en/
2023-12-02 16:29:40 +01:00
0d004d5caf Added translation using Weblate (Chinese (Traditional)) 2023-12-02 16:29:40 +01:00
4b75a2405c Update changelog for v3.0.1 2023-12-02 14:32:40 +00:00
1f7e28b6fb Bump version to 3.0.1 (hotfix) 2023-12-02 23:23:26 +09:00
c41b2ce861 fix: if locale is not present, set to unspecified 2023-12-02 23:23:13 +09:00
7f02afc5a6 Translated using Weblate (French)
Currently translated at 3.4% (10 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/fr/
2023-12-02 14:14:53 +00:00
496b3ffc1b fix(adblocker): remove unused statement 2023-12-02 23:14:04 +09:00
e9a395f67a hotfix(adblocker): fix #1475 2023-12-02 23:13:21 +09:00
0660f0b7ce Translated using Weblate (German)
Currently translated at 100.0% (292 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/de/
2023-12-02 14:41:50 +01:00
3ac09b9dc1 Added translation using Weblate (French) 2023-12-02 14:41:50 +01:00
fe4904a4af fix(index): i18n translate 2023-12-02 22:35:49 +09:00
d8c8bd17ec Update changelog for v3.0.0 2023-12-02 13:21:02 +00:00
e9d4d5ba14 Bump version to 3.0.0 2023-12-02 22:12:51 +09:00
5b2e69588f Translated using Weblate (Korean)
Currently translated at 100.0% (292 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ko/
2023-12-02 14:11:43 +01:00
c1591402a0 Translated using Weblate (Korean)
Currently translated at 100.0% (292 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ko/
2023-12-02 13:11:07 +00:00
e2e9c03895 chore(deps): update dependency vite-plugin-inspect to v0.8.1 2023-12-02 22:06:08 +09:00
deac4ef56b Translated using Weblate (German)
Currently translated at 99.6% (291 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/de/
2023-12-02 14:03:09 +01:00
7c39e658ce Translated using Weblate (German)
Currently translated at 99.6% (291 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/de/
2023-12-02 13:49:31 +01:00
6b026f57bc Translated using Weblate (Japanese)
Currently translated at 100.0% (292 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ja/
2023-12-02 13:27:29 +01:00
dc07cbda6f Translated using Weblate (German)
Currently translated at 99.6% (291 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/de/
2023-12-02 13:27:29 +01:00
1cf43fcd42 Translated using Weblate (German)
Currently translated at 99.6% (291 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/de/
2023-12-02 13:27:29 +01:00
e2cf550bed Translated using Weblate (Japanese)
Currently translated at 100.0% (292 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ja/
2023-12-02 13:18:24 +01:00
2917da1138 Translated using Weblate (Korean)
Currently translated at 100.0% (292 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ko/
2023-12-02 13:18:24 +01:00
b74eeb5688 Translated using Weblate (Japanese)
Currently translated at 100.0% (292 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ja/
2023-12-02 13:16:20 +01:00
0b084a6441 Translated using Weblate (German)
Currently translated at 99.3% (290 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/de/
2023-12-02 13:16:20 +01:00
865efa1b12 Translated using Weblate (Japanese)
Currently translated at 100.0% (292 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ja/
2023-12-02 13:13:10 +01:00
6a248e5336 Translated using Weblate (Czech)
Currently translated at 46.2% (135 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/cs/
2023-12-02 13:13:10 +01:00
eb9c256a5d Translated using Weblate (German)
Currently translated at 99.3% (290 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/de/
2023-12-02 13:13:10 +01:00
4bd54dcb2d Translated using Weblate (Japanese)
Currently translated at 40.0% (117 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ja/
2023-12-02 10:58:23 +01:00
17b035d317 Translated using Weblate (Japanese)
Currently translated at 38.6% (113 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ja/
2023-12-02 10:49:31 +01:00
28bcd1fefc Translated using Weblate (Korean)
Currently translated at 100.0% (292 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ko/
2023-12-02 02:16:18 +00:00
59bb1d9124 feat(README): add i18n README
- resolves https://github.com/th-ch/youtube-music/discussions/719
2023-12-02 10:06:55 +09:00
d9255c1cec Translated using Weblate (Korean)
Currently translated at 100.0% (292 of 292 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ko/
2023-12-02 00:27:27 +01:00
4ab4bb4cb3 feat(menu): add 'to-help-translate' button 2023-12-02 08:25:07 +09:00
a6c8b887e3 fix(in-app-menu): hide 'invisible' item from menu 2023-12-02 08:06:15 +09:00
1db0abf32d Update translation files
Updated by "Remove blank strings" hook in Weblate.

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/
2023-12-02 00:02:39 +01:00
ff899b8720 Translated using Weblate (German)
Currently translated at 99.6% (290 of 291 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/de/
2023-12-02 00:02:39 +01:00
18004c4441 Update translation files
Updated by "Remove blank strings" hook in Weblate.

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/
2023-12-01 23:56:30 +01:00
ce1cde72bd Translated using Weblate (Norwegian Bokmål)
Currently translated at 20.2% (59 of 291 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/nb_NO/
2023-12-01 23:56:30 +01:00
453f4d92c9 Translated using Weblate (Czech)
Currently translated at 37.8% (110 of 291 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/cs/
2023-12-01 23:56:30 +01:00
37740e78b4 Translated using Weblate (Russian)
Currently translated at 11.6% (34 of 291 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ru/
2023-12-01 23:56:30 +01:00
8ace123179 Translated using Weblate (Greek)
Currently translated at 9.6% (28 of 291 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/el/
2023-12-01 23:56:30 +01:00
bcdb9de41a chore(deps): update dependency eslint to v8.55.0 2023-12-02 07:12:19 +09:00
9fdb6eb7e5 fix(security): fix vulnerability detected by snyk 2023-12-02 07:06:39 +09:00
88cd1d2390 chore(README): replace snyk badge 2023-12-02 07:00:19 +09:00
943bcd322d Translated using Weblate (German)
Currently translated at 99.6% (290 of 291 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/de/
2023-12-01 22:42:08 +01:00
7774128d7e Translated using Weblate (Korean)
Currently translated at 100.0% (291 of 291 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ko/
2023-12-01 22:42:08 +01:00
b9b9e2ba00 Translated using Weblate (English)
Currently translated at 100.0% (291 of 291 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/en/
2023-12-01 22:42:08 +01:00
0ce4f20ec5 fix(downloader): call submenu 2023-12-02 06:39:33 +09:00
51b87312c4 feat: changed Zoom shortcuts to standard
- resolves #1458
2023-12-02 06:16:38 +09:00
9ffd7af8a7 Translated using Weblate (Japanese)
Currently translated at 36.5% (106 of 290 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ja/
2023-12-01 21:48:39 +01:00
4a453a4f3d Translated using Weblate (German)
Currently translated at 99.6% (289 of 290 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/de/
2023-12-01 21:48:39 +01:00
dc8a472cdb Translated using Weblate (Korean)
Currently translated at 100.0% (290 of 290 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ko/
2023-12-01 21:48:39 +01:00
d2eabaa4bb Translated using Weblate (English)
Currently translated at 100.0% (290 of 290 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/en/
2023-12-01 21:48:39 +01:00
39c8ca66d1 fix: add (Language) to Language setting 2023-12-02 05:14:22 +09:00
806098a5ef feat(tray): add separator 2023-12-02 05:11:27 +09:00
5f6cfd9558 Translated using Weblate (Japanese)
Currently translated at 34.1% (99 of 290 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ja/
2023-12-01 21:03:01 +01:00
b4b7ad824b Translated using Weblate (Korean)
Currently translated at 100.0% (290 of 290 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ko/
2023-12-01 21:03:01 +01:00
7b5d602f63 Translated using Weblate (Japanese)
Currently translated at 31.3% (91 of 290 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ja/
2023-12-01 21:03:01 +01:00
7eeeb89457 Translated using Weblate (Japanese)
Currently translated at 31.3% (91 of 290 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ja/
2023-12-01 21:03:01 +01:00
6e8447b5d1 feat: run prettier 2023-12-02 05:01:29 +09:00
a6445bacf0 Translated using Weblate (Japanese)
Currently translated at 27.9% (81 of 290 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ja/
2023-12-01 20:36:58 +01:00
bd9b4f1b1a Translated using Weblate (Korean)
Currently translated at 100.0% (290 of 290 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ko/
2023-12-01 20:36:58 +01:00
9a816b3f07 fix(song-info-front): fix eslint warning 2023-12-02 04:29:05 +09:00
4dcac23688 feat: async video event dispatch 2023-12-02 04:28:38 +09:00
97ef6ff997 fix(quality-changer): i18n 2023-12-02 04:24:02 +09:00
244a656671 Translated using Weblate (Japanese)
Currently translated at 19.4% (54 of 277 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ja/
2023-12-01 19:50:33 +01:00
f8a2829adb Translated using Weblate (Japanese)
Currently translated at 19.4% (54 of 277 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ja/
2023-12-01 19:50:33 +01:00
24daadbef8 Translated using Weblate (Czech)
Currently translated at 39.7% (110 of 277 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/cs/
2023-12-01 19:50:33 +01:00
bf2ac88847 Translated using Weblate (German)
Currently translated at 87.7% (243 of 277 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/de/
2023-12-01 19:50:33 +01:00
e42423b100 Translated using Weblate (Korean)
Currently translated at 100.0% (277 of 277 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ko/
2023-12-01 19:50:33 +01:00
de0c02efaf Translated using Weblate (Korean)
Currently translated at 100.0% (277 of 277 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ko/
2023-12-01 19:50:33 +01:00
b8290417f8 fix(en): fix 'quit' string 2023-12-02 03:50:23 +09:00
b92205a228 fix: i18n for default menu 2023-12-02 03:49:25 +09:00
5f642007ba feat(executed-at-ms): displaying a float to 2 decimal places
e.g. 58.399999998509884ms -> 58.39ms
2023-12-02 03:18:30 +09:00
ee40d278d4 Translated using Weblate (Korean)
Currently translated at 100.0% (277 of 277 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ko/
2023-12-01 18:35:12 +01:00
02d2e8ea92 Translated using Weblate (English)
Currently translated at 100.0% (277 of 277 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/en/
2023-12-01 18:35:12 +01:00
70715e5e8a fix(discord): connected, disconnected i18n 2023-12-02 02:33:54 +09:00
5ae4f564b7 fix(i18n): plugin name, description i18n 2023-12-02 02:33:40 +09:00
123eabd77a Translated using Weblate (Czech)
Currently translated at 39.6% (109 of 275 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/cs/
2023-12-01 17:14:58 +00:00
fd3438a20d feat(i18n): i18n auto-importer 2023-12-02 02:13:49 +09:00
c8554a12f6 fix(i18n): fix locale name (Norwegian (Bokmal)) 2023-12-02 01:54:32 +09:00
4a687ade9c Translated using Weblate (German)
Currently translated at 86.1% (237 of 275 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/de/
2023-12-01 17:43:01 +01:00
f77aa372cc Translated using Weblate (Japanese)
Currently translated at 5.0% (14 of 275 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ja/
2023-12-01 17:37:32 +01:00
0b9eef94c4 Translated using Weblate (German)
Currently translated at 85.8% (236 of 275 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/de/
2023-12-01 17:37:32 +01:00
71b2f69f98 Translated using Weblate (German)
Currently translated at 85.8% (236 of 275 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/de/
2023-12-01 17:37:31 +01:00
4b61c5307e Translated using Weblate (German)
Currently translated at 75.6% (208 of 275 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/de/
2023-12-01 17:06:02 +01:00
a617b91263 Update translation files
Updated by "Remove blank strings" hook in Weblate.

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/
2023-12-01 17:06:02 +01:00
fc79bdd0f3 Translated using Weblate (Norwegian Bokmål)
Currently translated at 21.0% (58 of 275 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/nb_NO/
2023-12-01 17:06:02 +01:00
e5e1e547d5 Translated using Weblate (Japanese)
Currently translated at 4.0% (11 of 275 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ja/
2023-12-01 17:06:02 +01:00
edac9b0c20 Translated using Weblate (German)
Currently translated at 75.2% (207 of 275 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/de/
2023-12-01 17:06:02 +01:00
dfaf3cf95a Translated using Weblate (Russian)
Currently translated at 11.2% (31 of 275 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ru/
2023-12-01 17:06:02 +01:00
bae90ce8f3 Translated using Weblate (Russian)
Currently translated at 11.2% (31 of 275 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ru/
2023-12-01 17:06:02 +01:00
188e56ce30 Translated using Weblate (Czech)
Currently translated at 39.6% (109 of 275 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/cs/
2023-12-01 17:06:02 +01:00
19b48b123f Translated using Weblate (German)
Currently translated at 51.6% (142 of 275 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/de/
2023-12-01 17:06:02 +01:00
549961f297 Translated using Weblate (Korean)
Currently translated at 100.0% (275 of 275 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ko/
2023-12-01 17:06:02 +01:00
ba7bc68ac3 Translated using Weblate (Norwegian Bokmål)
Currently translated at 10.5% (29 of 275 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/nb_NO/
2023-12-01 17:06:02 +01:00
bbfe272d41 Translated using Weblate (Japanese)
Currently translated at 2.5% (7 of 275 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ja/
2023-12-01 17:06:02 +01:00
8a3e0a31ca Translated using Weblate (Czech)
Currently translated at 39.6% (109 of 275 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/cs/
2023-12-01 17:06:02 +01:00
8fbda97885 Translated using Weblate (Czech)
Currently translated at 39.6% (109 of 275 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/cs/
2023-12-01 17:06:02 +01:00
1856deb0f5 Translated using Weblate (German)
Currently translated at 30.5% (84 of 275 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/de/
2023-12-01 17:06:02 +01:00
fec7c5c130 Translated using Weblate (Korean)
Currently translated at 60.0% (165 of 275 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ko/
2023-12-01 17:06:02 +01:00
936b4b28bb Added translation using Weblate (Norwegian Bokmål) 2023-12-01 17:06:02 +01:00
f3092d0778 Added translation using Weblate (Japanese) 2023-12-01 17:06:02 +01:00
fc1adfae6c Translated using Weblate (Czech)
Currently translated at 32.7% (90 of 275 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/cs/
2023-12-01 17:06:02 +01:00
e279aaed64 Translated using Weblate (Czech)
Currently translated at 100.0% (0 of 0 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/cs/
2023-12-01 17:06:02 +01:00
4d346a9471 Translated using Weblate (German)
Currently translated at 29.8% (82 of 275 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/de/
2023-12-01 17:06:02 +01:00
cfc504da34 Added translation using Weblate (Czech) 2023-12-01 17:06:02 +01:00
0919a4b9b7 Translated using Weblate (German)
Currently translated at 100.0% (0 of 0 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/de/
2023-12-01 17:06:02 +01:00
f46ad2ea0e Added translation using Weblate (German) 2023-12-01 17:06:02 +01:00
252719bc71 Translated using Weblate (Russian)
Currently translated at 100.0% (0 of 0 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ru/
2023-12-01 17:06:02 +01:00
45f49361ea Translated using Weblate (Greek)
Currently translated at 6.9% (19 of 275 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/el/
2023-12-01 17:06:02 +01:00
c4a74c6c7e Translated using Weblate (Korean)
Currently translated at 44.0% (121 of 275 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ko/
2023-12-01 17:06:02 +01:00
05f197948d Added translation using Weblate (Russian) 2023-12-01 17:06:02 +01:00
5a1d230538 Translated using Weblate (Greek)
Currently translated at 100.0% (0 of 0 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/el/
2023-12-01 17:06:02 +01:00
a7ad260a00 Translated using Weblate (Korean)
Currently translated at 18.1% (50 of 275 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ko/
2023-12-01 17:06:02 +01:00
ef068cccd9 Added translation using Weblate (Greek) 2023-12-01 17:06:02 +01:00
166067920d Translated using Weblate (Korean)
Currently translated at 1.0% (3 of 275 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/ko/
2023-12-01 17:06:02 +01:00
8227853cf9 fix: load i18n 2023-12-01 23:50:15 +09:00
324a539b89 fix(in-app-menu): resize
- Window controls: 36px -> 32px
- Font size: 14px -> 12px
2023-12-01 23:04:49 +09:00
ce7557353c Add text to Translation section (#1470) 2023-12-01 21:41:13 +09:00
7b7923fe9b fix(downloader): fix i18n 2023-12-01 21:40:03 +09:00
105d5c78e7 chore(deps): update dependency rollup to v4.6.1 2023-12-01 21:31:13 +09:00
b25183a8f5 fix(deps): update dependency youtubei.js to v8 (#1473)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-01 21:20:15 +09:00
adde33d1f5 chore(deps): update dependency electron to v27.1.3 (#1471)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-01 21:18:54 +09:00
ad325ccb10 fix(deps): update dependency @xhayper/discord-rpc to v1.1.1 (#1472)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-01 21:17:28 +09:00
2e7ea6969c chore(README): add translation info 2023-12-01 02:24:23 +09:00
7401cf69ad feat: add support i18n (#1468) 2023-12-01 01:30:46 +09:00
7f71c36dc0 doc: Add warning in index.html 2023-11-30 11:07:32 +02:00
a3104fda4b feat: run prettier 2023-11-30 11:59:27 +09:00
44c42310f1 feat(.eslintrc.js): add prettier 2023-11-30 11:48:03 +09:00
a22a8ac5c9 feat: add description for plugins 2023-11-30 11:42:34 +09:00
aa5c3bac4e chore(deps): bump deps 2023-11-30 10:27:11 +09:00
30b3beee18 Merge pull request #1401 from organization/feat/refactor-plugin-system 2023-11-30 10:07:43 +09:00
b059e43fb1 fix(discord): rename from 'timout' to 'timeout' 2023-11-30 10:00:39 +09:00
3b04d0ba19 feat(discord): apply config as dynamic 2023-11-30 09:54:10 +09:00
959f99beae fix(blur-nav-bar): set restartNeeded to true 2023-11-30 09:41:05 +09:00
ed402933d3 fix(in-app-menu): fix #1436 2023-11-30 09:38:51 +09:00
ef8bb95884 chore(deps): update playwright monorepo to v1.40.1 2023-11-30 03:13:09 +09:00
1b79d2e429 fix(song-info-front): add type 2023-11-30 03:03:04 +09:00
ec786748be fix: dispatch event 2023-11-30 03:02:20 +09:00
06f1c7effe fix(ambient-mode): fix unload 2023-11-30 02:45:44 +09:00
d78da237fc fix: fix an issue with videodatachangefired timing 2023-11-30 00:45:15 +09:00
4c0cce89ee fix(video-toggle): remove unnecessary querySelector call 2023-11-29 19:23:58 +09:00
888ced8fd1 fix(loadAllPreloadPlugins): remove await 2023-11-29 18:27:45 +09:00
e1690720b3 fix: disable auto-play 2023-11-29 18:05:32 +09:00
bbff0a6bc2 feat: plugin load await 2023-11-29 18:04:37 +09:00
5db759150c feat: use '.call' instead of '.bind' 2023-11-29 01:27:51 +09:00
ae239f6700 fix(precise-volume): fix precise-volume plugin 2023-11-28 12:37:31 +09:00
1d26d10e57 fix: menu await 2023-11-28 12:32:07 +09:00
da70a4ce7e fix: fix audioCanPlay event
- e.g. Visualizer Plugin
2023-11-28 12:11:48 +09:00
75ae9f4fad fix: fix unloader 2023-11-28 11:48:09 +09:00
8f7933c111 fix: fix restartNeeded 2023-11-28 11:29:43 +09:00
29a0dedcce chore(action/build): fix version tag 2023-11-28 11:10:41 +09:00
4d62993177 chore(action/build): add notes for Windows
resolve https://github.com/th-ch/youtube-music/discussions/1343
2023-11-28 11:07:44 +09:00
8714f33fa2 feat: use app.whenReady() instead of app.on('ready', ...) 2023-11-28 10:55:33 +09:00
5dacd50ff6 feat: use LoggerPrefix const instead of hardcoded string 2023-11-28 10:51:19 +09:00
8d06dcc7b6 fix(utils/index): little fix (lint) 2023-11-28 10:44:48 +09:00
b8f6dd2584 chore(deps): update dependency @typescript-eslint/eslint-plugin to v6.13.0 2023-11-28 10:41:39 +09:00
0650205b86 chore: update README 2023-11-28 10:28:39 +09:00
3e8a0ec49a fix: plugin config default value 2023-11-28 10:21:08 +09:00
04d7b32d3f feat: createBackend, createPreload, createRenderer
Introduced the mentioned helper methods in order to help split big plugins into manageable chunks.
2023-11-28 00:06:59 +02:00
eaaf170cc8 make log prefix consistent 2023-11-27 23:31:05 +02:00
09450fb8c7 fix(store): fix TypeError: Cannot convert undefined or null to object 2023-11-28 05:51:47 +09:00
ac0b78eefb fix(store): fix Cannot read properties of undefined 'global' 2023-11-28 05:46:49 +09:00
90103d9853 fix: lifecycle check
edge case:
 - There may be plugins that don't have a start or stop function
2023-11-28 05:23:35 +09:00
bf27c73f1d fix(album-color-theme): more simple assign 2023-11-28 04:50:24 +09:00
845c9365be fix(album-color-theme): sidebar color 2023-11-28 04:44:17 +09:00
91cf5f5c25 fix: fix Cannot access 'Ba' before initialization on first run 2023-11-28 04:21:58 +09:00
783a892e26 bump rollup version 2023-11-28 01:59:15 +09:00
41d8f86962 Merge branch 'master' into feat/refactor-plugin-system 2023-11-28 01:51:31 +09:00
252349579e chore(deps): update dependency rollup to v4.6.0 2023-11-28 01:51:10 +09:00
99b1cfbde4 fix: fix pnpm-lock 2023-11-28 01:50:46 +09:00
3f70d912d7 Merge branch 'master' into feat/refactor-plugin-system 2023-11-28 01:48:38 +09:00
bf33c4e7b4 Merge branch 'feat/new-plugin-system' into feat/refactor-plugin-system 2023-11-28 01:43:51 +09:00
3152842a30 fix: this binding
Co-authored-by: Su-Yong <simssy2205@gmail.com>
2023-11-28 01:39:11 +09:00
d84416b27c fix: crash 2023-11-28 01:02:05 +09:00
cc38978bd3 feat: label sort 2023-11-28 00:51:16 +09:00
7a76079ff4 fix: load plugins
Co-authored-by: Su-Yong <simssy2205@gmail.com>
2023-11-28 00:34:36 +09:00
2fe28cf126 clean code 2023-11-27 19:26:45 +09:00
3ffbfbe0e3 convert plugins 2023-11-27 18:41:50 +09:00
4fad456619 fix eslint warning 2023-11-27 05:10:35 +09:00
7591f13505 in-app-menu 2023-11-27 05:09:33 +09:00
11d06c50a5 WIP 2 2023-11-27 04:59:20 +09:00
e0a3489640 fix: remove PluginBaseConfig 2023-11-27 00:57:05 +09:00
e55a1d3076 fix: fix onConfigChange 2023-11-27 00:44:46 +09:00
563d431c00 WIP
Co-authored-by: Su-Yong <simssy2205@gmail.com>
2023-11-27 00:18:34 +09:00
3a1b77ebd8 fix: electron-vite setting
Co-authored-by: Su-Yong <simssy2205@gmail.com>
2023-11-26 23:25:57 +09:00
3f8030a9c5 fix: inject multiple stylesheet 2023-11-26 23:25:38 +09:00
e12e67af0e feat: reimplement inject css, fix types 2023-11-26 23:12:19 +09:00
3ab4cd5d05 change plugin system 2023-11-26 01:17:24 +02:00
738adbed98 chore(deps): update dependency electron-builder to v24.9.1 2023-11-25 20:44:32 +09:00
365a078600 fix(deps): update dependency electron-updater to v6.1.7 2023-11-25 20:41:44 +09:00
04fc43e18b chore(deps): update pnpm to v8.11.0 2023-11-25 20:41:33 +09:00
54273baec7 chore(deps): update dependency rollup to v4.5.2 2023-11-24 20:56:29 +09:00
51e62ef47b fix(discord): update application client-id
fix #1431
2023-11-23 12:12:08 +09:00
a330ebcda7 chore(deps): update dependency electron to v27.1.2 (#1441)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-23 09:21:08 +09:00
a023fff2d0 Nicer Readme (#1439) 2023-11-22 15:33:49 +09:00
abb25ea6fb chore(deps): update dependency @typescript-eslint/eslint-plugin to v6.12.0 2023-11-22 15:29:51 +09:00
ef49bcdb5f chore(deps): update dependency typescript to v5.3.2 2023-11-22 15:25:37 +09:00
b4f1b112d6 chore(deps): update dependency rollup to v4.5.1 2023-11-22 15:23:11 +09:00
f24ec0ae9d chore(deps): update dependency rollup to v4.5.0 2023-11-20 15:44:36 +09:00
ebb51fe37b chore(deps): update dependency eslint to v8.54.0 2023-11-20 15:44:28 +09:00
e8ee18f903 chore(deps): update dependency electron-vite to v1.0.29 2023-11-20 15:42:36 +09:00
a593de705c chore(deps): update playwright monorepo to v1.40.0 2023-11-20 15:42:25 +09:00
03dd024704 Windows Zoom, ScaleFactor (#1402) 2023-11-20 15:42:04 +09:00
528c3535dd fix(deps): update dependency @xhayper/discord-rpc to v1.1.0 2023-11-19 21:01:47 +09:00
0e0f80a2d0 chore(deps): update dependency electron to v27.1.0 2023-11-16 09:26:50 +09:00
6b67fb136a fix(deps): update dependency conf to v12 2023-11-15 21:52:58 +09:00
9fe1c14869 chore(deps): update dependency @electron/universal to v2 2023-11-15 18:09:00 +09:00
8a96dddf54 pnpm dedupe 2023-11-15 18:08:25 +09:00
230422c98b pnpm dedupe 2023-11-15 18:02:51 +09:00
d16ffc531f fix: renovate.json 2023-11-15 18:02:05 +09:00
f614199ea5 feat: remove support for npm
- remove yarpm
2023-11-15 17:56:52 +09:00
55a1c2e9e3 fix(package.json): fix spaces in overrides 2023-11-15 17:53:32 +09:00
bee1f77812 chore(deps): bump rollup & pnpm 2023-11-15 17:51:53 +09:00
fdf982ada5 chore(deps): bump deps 2023-11-15 17:50:07 +09:00
ff02fc7855 chore(deps): bump axios from 1.5.1 to 1.6.1 (#1400)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-15 17:43:16 +09:00
01ed289400 feat(renovate): add labels for dependency update 2023-11-13 01:40:33 +09:00
TC
aedb2db655 Add renovate config file 2023-11-12 17:35:02 +01:00
10a54b9de0 feat: update README 2023-11-12 02:56:02 +09:00
ccd029c040 fix: update types 2023-11-12 02:55:44 +09:00
3a431841b7 fix(plugin): fix always show restart dialog 2023-11-12 02:10:50 +09:00
deceae8354 chore(plugin): clean import 2023-11-12 02:10:11 +09:00
c8628670cf fix(ambient-plugin): fix plugin definition 2023-11-12 02:05:12 +09:00
ffe53d5596 feat(plugin): show dialog need to restart 2023-11-12 02:02:54 +09:00
a4f4ecb569 feat(plugin): add onPlayerApiReady hook
Co-authored-by: JellyBrick <shlee1503@naver.com>
2023-11-12 01:51:26 +09:00
2097f42efb feat(plugin): support dynamic plugin load / unload 2023-11-12 01:16:34 +09:00
9c59f56aac refactor(plugin): apply new plugin loader at all type of plugin 2023-11-12 00:50:09 +09:00
dfcc4107b7 feat(menu): sort plugin name 2023-11-12 00:31:48 +09:00
ef71abfff1 refactor(plugin): add renderer-plugin-loader 2023-11-12 00:21:34 +09:00
bc916f3a6e refactor(plugin): refactor plugin loader and add dynamic loading 2023-11-12 00:09:56 +09:00
c7ff0dcbf6 fix: remove defaults
Co-authored-by: Su-Yong <simssy2205@gmail.com>
2023-11-11 22:43:51 +09:00
7242f9bfd0 fix(plugin): fix onChangeConfig hook 2023-11-11 22:08:44 +09:00
bb2e865880 wip: trying to fix electron-store issue
Co-authored-by: JellyBrick <shlee1503@naver.com>
2023-11-11 21:48:51 +09:00
6ab3cf9ac9 fix(frontend): fix cannot apply style 2023-11-11 20:58:16 +09:00
b77f5c9ecc fix: fix insert 2023-11-11 20:05:38 +09:00
b470dbd6b9 fix: add default config 2023-11-11 19:32:05 +09:00
1f96b6b44d fix: plugin load 2023-11-11 19:23:17 +09:00
de0b228ae8 feat: electron-vite hot-reload 2023-11-11 18:12:20 +09:00
f35d192650 fix(downloader): fix downloader plugin 2023-11-11 18:11:24 +09:00
794d00ce9e feat: migrate to new plugin api
Co-authored-by: Su-Yong <simssy2205@gmail.com>
2023-11-11 18:02:22 +09:00
739e7a448b remove unused Promise.resolve 2023-11-11 11:51:06 +09:00
7fa8a454b6 fix: fix setPartial 2023-11-11 11:50:02 +09:00
5cd1d9abe8 feat(plugin): migrate some plugin (WIP)
Co-authored-by: JellyBrick <shlee1503@naver.com>
2023-11-11 00:03:26 +09:00
e0e17cac99 feat(plugin): migrating plugins to new plugin system (WIP)
Co-authored-by: JellyBrick <shlee1503@naver.com>
2023-11-10 21:32:05 +09:00
840039330f fix: Update bug_report.yml 2023-11-10 20:09:23 +09:00
734409dc3f chore: Update bug_report.yml 2023-11-10 20:09:04 +09:00
34564c8c55 Updated mac icon to better reflect the Mac styling (#1395) 2023-11-10 12:33:17 +09:00
afe6accab8 refactor(plugin): new plugin system poc 2023-11-09 22:54:58 +09:00
b6e7e75ae8 plugin system poc 2023-11-09 12:43:41 +09:00
06dc0e80f0 feat: rename plugins to clarify context (#1392) 2023-11-09 11:35:43 +09:00
47cccbce7c feat: refactor plugin utils (#1391) 2023-11-09 11:06:06 +09:00
269352af97 chore(deps): update dependency electron to v27.0.4
- fix #1324
2023-11-09 10:39:43 +09:00
fa62f79dce chore(deps): bump deps 2023-11-09 10:31:30 +09:00
9f88b37f41 fix(in-app-menu): panel should close with the window when it is closed
- fix #1389
2023-11-09 10:27:07 +09:00
55ae9eac1e fix: fixed issues identified in eslint 2023-11-09 10:06:03 +09:00
05564d4a58 feat: add auto-importer for menu 2023-11-09 09:57:32 +09:00
59426c56db feat: plugin auto-importer with vite-plugin-resolve (#1385) 2023-11-09 09:22:23 +09:00
18cd4c0c9a chore(navigation): remove unused css attribute 2023-11-08 18:15:24 +09:00
a0e2a33e28 fix: change titleBarOverlay height based on zoomFactor
- fix #1375
2023-11-08 17:48:32 +09:00
7bdb46e161 fix: fixed an issue if "Always on top" is enabled, the dialog is displayed below the window
- fix #1379
2023-11-08 16:35:19 +09:00
f560b62de0 fix(precise-volume): fix precise-volume plugin 2023-11-08 02:59:20 +09:00
adc1f6822b fix: image path 2023-11-07 23:43:16 +09:00
2da29fcfa7 feat: migrate from rollup to electron-vite (#1364)
* feat: electron-vite PoC

* fix: fix preload path

* remove rollup deps and config

* fix: debug mode

* fix: build mode, asset path

* fix: remove unused dependencies

* feat: use `executeJavaScriptInIsolatedWorld` instead of `executeJavaScript`

* feat: enable `minify`

* fix(actions): update task name

* fix: fix dev mode check

* fix: remove unused variable
2023-11-07 19:49:28 +09:00
c5d0314db6 fix(winget): fix env name 2023-11-07 08:27:20 +09:00
8c052faedd fix: fix winget version (fix #1363) 2023-11-06 17:38:57 +09:00
37067ff950 fix: update jsdoc 2023-11-06 17:22:46 +09:00
6366dc026e feat: enable context-isolation (#1361) 2023-11-06 17:21:29 +09:00
6e52178074 fix: fix README 2023-11-06 17:13:47 +09:00
47f38cc690 fix: add workaround for podcast type video (#1362) 2023-11-04 16:56:41 +09:00
fdd6d9929f fix: temporary workaround for #1356 2023-11-04 10:58:32 +09:00
1707261f49 chore(deps): bump deps 2023-11-04 10:58:14 +09:00
6712fced6d fix: fix broken menu-layout (#1360) 2023-11-04 10:46:49 +09:00
6dabfaa9ba fix: use window instead of (global as any) 2023-11-04 10:30:39 +09:00
a41db79c35 fix(deps): fix pnpm.overrides 2023-11-03 10:09:04 +09:00
87786d9aef chore(deps): update dependency node-gyp to v10.0.1 2023-11-03 09:57:24 +09:00
22f5866050 chore(deps): update dependency @electron/universal to v1.4.4 2023-11-03 09:57:12 +09:00
04894fbcf5 chore(deps): update dependency node-gyp to v10 2023-11-02 12:51:52 +09:00
c17c624ba4 chore(deps): bump deps 2023-11-02 12:48:44 +09:00
bfe7249df8 Add Homebrew cask install option for MacOS. (#1357) 2023-11-02 09:42:13 +09:00
13c570efe9 fix: use node-fetch v3 instead of v2
- auto-change: moved from devDependencies to npx
2023-10-29 06:17:33 +09:00
b299846f0f fix: fix node-gyp version 2023-10-29 06:09:47 +09:00
59e9289d27 remove: remove patch-package
- see https://github.com/LuanRT/YouTube.js/pull/509
2023-10-29 06:05:15 +09:00
8dc29caa1b chore(actions): update setup-node v3 to v4 2023-10-29 06:02:03 +09:00
7fedf88654 chore(deps): bump deps version
- rollup: 4.1.4 to 4.1.5
- node-gyp: 9.4.0 to 9.4.1
- @cliqz/adblocker: 1.26.8 to 1.26.9
- youtubei.js: 6.4.1 to 7.0.0
- pnpm: 8.9.2 to 8.10.0
2023-10-29 05:54:43 +09:00
5da0202425 Update changelog for v2.2.0 2023-10-26 17:16:26 +00:00
6288d0b171 Bump version to 2.2.0 2023-10-27 02:01:44 +09:00
4248d20e8e bump deps 2023-10-25 16:46:59 +09:00
0b413492ad feat(ambient-mode): add config for ambient-mode plugin (#1349) 2023-10-25 15:37:51 +09:00
dc73561c8a Update changelog for v2.1.3 2023-10-22 15:50:12 +00:00
949a2f6428 Bump version to 2.1.3 2023-10-23 00:35:10 +09:00
bceaa05197 fix(store): fix listenAlong statement 2023-10-23 00:29:59 +09:00
776cdac30d feat(discord): rename Listen Along to Play on YTM
resolve #1341
2023-10-23 00:27:43 +09:00
4333891cca chore(deps): bump deps 2023-10-23 00:19:42 +09:00
8a89bbccf7 fix: fixed bugs in downloader (#1342) 2023-10-23 00:19:01 +09:00
fa4c69d228 Update changelog for v2.1.2 2023-10-19 13:55:04 +00:00
c25def8901 Bump version to 2.1.2 2023-10-19 22:39:14 +09:00
284a59b721 fix: fix unresponsive (fix #1325) 2023-10-19 22:35:32 +09:00
5fcba8619a feat(in-app-menu): add an option to hide the window controls (#1335) 2023-10-19 22:34:18 +09:00
f3cd759276 fix: fixed an issue where the album name was missing (#1334) 2023-10-19 21:45:46 +09:00
9d3981e361 chore: Update build.yml 2023-10-19 21:33:54 +09:00
787326948b chore: making actions more efficient 2023-10-19 09:51:31 +09:00
779251933c chore(deps): update dependency electron to v27.0.1 (#1331) 2023-10-19 09:42:41 +09:00
1efe835c69 fix: fixed an issue where only the first 100 songs in a playlist were downloaded (#1329) 2023-10-19 05:40:05 +09:00
5702978227 chore(deps): update dependencies 2023-10-18 18:18:28 +09:00
fa3d742838 chore(deps): update dependency @typescript-eslint/eslint-plugin to v6.8.0 2023-10-18 02:21:25 +09:00
c460cc2296 Updated readme plugins list (#1326) 2023-10-17 20:04:23 +09:00
4e4af5e830 fix(actions): fix if statement 2023-10-16 22:55:04 +09:00
9a4e98063b chore(actions): disable pnpm cache for macOS 2023-10-16 22:54:11 +09:00
8bfe04bb50 chore: update issue template
Thanks to Alipoodle for writing this question.
2023-10-16 22:42:02 +09:00
6774d54f5e chore(deps): update dependency rollup to v4.1.4 2023-10-16 16:41:36 +09:00
9705f8489d chore(deps): Bump @rollup/plugin-commonjs, pnpm version, Remove ytpl 2023-10-16 16:24:16 +09:00
a7229cbe14 Bump @rollup/plugin-commonjs, pnpm version 2023-10-16 03:08:04 +09:00
7577aba45e feat: use test:debug for CI 2023-10-16 02:08:25 +09:00
d78fbe476e hotfix: fix Cannot read properties of undefined (reading 'removeChild') 2023-10-16 01:09:24 +09:00
bfe4b2bba7 fix(actions): use GabrielBB/xvfb-action instead of coactions/setup-xvfb 2023-10-16 00:58:02 +09:00
7625a3aa52 QOL: Move source code under the src directory. (#1318) 2023-10-15 21:52:48 +09:00
30c8dcf730 fix: release action 2023-10-15 18:54:25 +09:00
00a3e8d35e chore(deps): Bump rollup, @xhayper/discord-rpc version 2023-10-15 18:35:57 +09:00
4d01cdfa6c fix(blocker): remove the app.isPackaged check (fix #1315) 2023-10-15 18:33:14 +09:00
f924b6c8e3 fix(actions): install pnpm before call setup-node 2023-10-15 18:28:09 +09:00
926d98174c fix: fix build actions 2023-10-15 18:22:19 +09:00
41b3972f54 chore(README): add pnpm install guide 2023-10-15 18:20:49 +09:00
467f29e363 feat: migrate from npm to pnpm (#1316) 2023-10-15 18:18:20 +09:00
9cc13c3757 Merge pull request #1317 from foonathan/fix-loop-status 2023-10-15 04:23:33 +09:00
f8ccb86156 Fix mpris player.loopStatus 2023-10-14 21:03:06 +02:00
b316aa2301 chore(deps): update dependency rollup to v4.1.0 2023-10-14 22:33:09 +09:00
5c49b28664 fix(discord): Discord RPC fails if a song's title is only one character (fix #1314) 2023-10-14 20:27:58 +09:00
dedf96afd3 Update changelog for v2.1.1 2023-10-14 05:49:56 +00:00
3bb5bc2ca1 Bump version to 2.1.1 2023-10-14 14:34:39 +09:00
c79fdd9887 fix: empty title playlist directory path 2023-10-14 14:03:47 +09:00
d7b821727d hotfix(downloader): can't get an album title (fix #1313) 2023-10-14 13:55:57 +09:00
TC
21c45faf20 Add "about" menu to show app version 2023-10-13 22:04:50 +02:00
92cab89d17 Update changelog for v2.1.0 2023-10-13 19:27:20 +00:00
394 changed files with 53128 additions and 19798 deletions

View File

@ -1,3 +1 @@
.eslintrc.js
rollup.main.config.ts
rollup.preload.config.ts

View File

@ -7,7 +7,7 @@ module.exports = {
'plugin:@typescript-eslint/recommended',
'plugin:@typescript-eslint/recommended-requiring-type-checking',
],
plugins: ['@typescript-eslint', 'import'],
plugins: ['prettier', '@typescript-eslint', 'import'],
parser: '@typescript-eslint/parser',
parserOptions: {
project: './tsconfig.json',
@ -26,6 +26,7 @@ module.exports = {
'import/newline-after-import': 'error',
'import/no-default-export': 'off',
'import/no-duplicates': 'error',
'import/no-unresolved': ['error', { ignore: ['^virtual:', '\\?inline$', '\\?raw$', '\\?asset&asarUnpack'] }],
'import/order': [
'error',
{
@ -66,4 +67,14 @@ module.exports = {
es6: true,
},
ignorePatterns: ['dist', 'node_modules'],
root: true,
settings: {
'import/parsers': {
'@typescript-eslint/parser': ['.ts']
},
'import/resolver': {
typescript: {},
exports: {},
},
},
};

View File

@ -12,16 +12,24 @@ body:
required: true
- label: I have searched the [issue tracker](https://github.com/th-ch/youtube-music/issues) for a bug report that matches the one I want to file, without success.
required: true
- label: I understand that **th-ch/youtube-music has NO affiliation with Google or YouTube**
required: true
- type: input
attributes:
label: YouTube Music (Application) Version
description: |
What version of YouTube Music Application are you using?
What version of the YouTube Music Application are you using?
Note: Please check if this issue is reproducible with the latest stable release.
placeholder: 2.0.0
validations:
required: true
- type: checkboxes
attributes:
label: Checklists
options:
- label: I use the portable version of the YouTube Music Application.
- label: I can reproduce this issue in the [official version of (WEB) YTM](https://music.youtube.com).
- type: dropdown
attributes:
label: What operating system are you using?
@ -36,13 +44,13 @@ body:
- type: input
attributes:
label: Operating System Version
description: What operating system version are you using? On Windows, click Start button > Settings > System > About. On macOS, click the Apple Menu > About This Mac. On Linux, use lsb_release or uname -a.
description: What operating system version are you using? On Windows, click the Start button > Settings > System > About. On macOS, click the Apple Menu > About This Mac. On Linux, use lsb_release or uname -a.
placeholder: "e.g. Windows 10 version 1909, macOS Catalina 10.15.7, or Ubuntu 20.04"
validations:
required: true
- type: dropdown
attributes:
label: What arch are you using?
label: What CPU architecture are you using?
options:
- x64
- ia32
@ -55,10 +63,17 @@ body:
label: Last Known Working YouTube Music (Application) version
description: (If applicable) What is the last version of YouTube Music this worked in?
placeholder: 1.20.0
- type: textarea
attributes:
label: Reproduction steps
description: Provide steps to reproduce the issue.
placeholder: 1. Enable the X plugin.
validations:
required: true
- type: textarea
attributes:
label: Expected Behavior
description: A clear and concise description of what you expected to happen. (Add a replication step if applicable)
description: A clear and concise description of what you expected to happen.
validations:
required: true
- type: textarea
@ -67,6 +82,13 @@ body:
description: A clear description of what actually happens.
validations:
required: true
- type: textarea
attributes:
label: Enabled plugins
description: Provide the list of plugins you enabled.
placeholder: 1. Album Color Theme
validations:
required: true
- type: textarea
attributes:
label: Additional Information

View File

@ -15,7 +15,7 @@ body:
- type: textarea
attributes:
label: Problem Description
description: Please add a clear and concise description of the problem you are seeking to solve with this feature request.
description: A clear and concise description of the problem you are seeking to solve with this feature request.
validations:
required: true
- type: textarea
@ -33,6 +33,6 @@ body:
- type: textarea
attributes:
label: Additional Information
description: Add any other context about the problem here.
description: Any other context about the problem.
validations:
required: false

View File

@ -20,59 +20,64 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Install pnpm
uses: pnpm/action-setup@v2
with:
version: 9
run_install: false
- name: Setup NodeJS
uses: actions/setup-node@v3
if: startsWith(matrix.os, 'macOS') != true
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'pnpm'
- name: Setup NodeJS for macOS
if: startsWith(matrix.os, 'macOS')
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: npm ci
run: pnpm install --frozen-lockfile
# Only vite build without release if it is a fork, or it is a pull-request
- name: Vite Build
if: github.repository == 'th-ch/youtube-music' && github.event_name == 'pull_request'
run: |
pnpm build
# Build and release if it's the main repository and is not pull-request
- name: Build and release on Mac
if: startsWith(matrix.os, 'macOS') && (github.repository == 'th-ch/youtube-music' && github.event_name != 'pull_request')
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
pnpm release:mac
- name: Build and release on Linux
if: startsWith(matrix.os, 'ubuntu') && (github.repository == 'th-ch/youtube-music' && github.event_name != 'pull_request')
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
sudo snap install snapcraft --classic
pnpm release:linux
- name: Build and release on Windows
if: startsWith(matrix.os, 'windows') && (github.repository == 'th-ch/youtube-music' && github.event_name != 'pull_request')
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
pnpm release:win
- name: Test
uses: GabrielBB/xvfb-action@v1
uses: coactions/setup-xvfb@v1
env:
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1
with:
run: npm run test
run: pnpm test:debug
# Build and release if it's the main repository
- name: Build and release on Mac
if: startsWith(matrix.os, 'macOS') && github.repository == 'th-ch/youtube-music'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
npm run release:mac
- name: Build and release on Linux
if: startsWith(matrix.os, 'ubuntu') && github.repository == 'th-ch/youtube-music'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
npm run release:linux
- name: Build and release on Windows
if: startsWith(matrix.os, 'windows') && github.repository == 'th-ch/youtube-music'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
npm run release:win
# Only build without release if it is a fork
- name: Build on Mac
if: startsWith(matrix.os, 'macOS') && github.repository != 'th-ch/youtube-music'
run: |
npm run build:mac
- name: Build on Linux
if: startsWith(matrix.os, 'ubuntu') && github.repository != 'th-ch/youtube-music'
run: |
npm run build:linux
- name: Build on Windows
if: startsWith(matrix.os, 'windows') && github.repository != 'th-ch/youtube-music'
run: |
npm run build:win
release:
runs-on: ubuntu-latest
@ -84,14 +89,27 @@ jobs:
with:
fetch-depth: 0
- name: Install pnpm
uses: pnpm/action-setup@v2
with:
version: 9
run_install: false
- name: Setup NodeJS
uses: actions/setup-node@v3
if: startsWith(matrix.os, 'macOS') != true
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'pnpm'
- name: Setup NodeJS for macOS
if: startsWith(matrix.os, 'macOS')
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: npm ci
run: pnpm install --frozen-lockfile
- name: Get version
run: |
@ -129,10 +147,12 @@ jobs:
Thanks to all contributors! 🏅
(Note for Windows: `YouTube-Music-Web-Setup-${{ env.VERSION_TAG }}.exe` is an installer, and `YouTube-Music-${{ env.VERSION_TAG }}.exe` is a portable version)
- name: Update changelog
if: ${{ env.VERSION_HASH == '' }}
run: |
npm run changelog
pnpm changelog
- name: Commit changelog
if: ${{ env.VERSION_HASH == '' }}

View File

@ -17,4 +17,4 @@ jobs:
- name: "Checkout Repository"
uses: actions/checkout@v4
- name: "Dependency Review"
uses: actions/dependency-review-action@v3
uses: actions/dependency-review-action@v4

View File

@ -15,12 +15,16 @@ jobs:
name: Publish winget package
runs-on: ubuntu-latest
steps:
- name: Set winget version env
env:
TAG_NAME: ${{ inputs.tag_name || github.event.release.tag_name }}
run: echo "WINGET_TAG_NAME=$(echo ${TAG_NAME#v})" >> $GITHUB_ENV
- name: Submit package to Windows Package Manager Community Repository
uses: vedantmgoyal2009/winget-releaser@v2
with:
identifier: th-ch.YouTubeMusic
installers-regex: '^YouTube-Music-Web-Setup-[\d\.]+\.exe$'
version: ${{ inputs.tag_name || github.event.release.tag_name }}
version: ${{ env.WINGET_TAG_NAME }}
release-tag: ${{ inputs.tag_name || github.event.release.tag_name }}
token: ${{ secrets.WINGET_ACC_TOKEN }}
fork-user: youtube-music-winget

1
.gitignore vendored
View File

@ -12,3 +12,4 @@ electron-builder.yml
!.yarn/releases
!.yarn/sdks
!.yarn/versions
.vite-inspect

5
.prettierrc Normal file
View File

@ -0,0 +1,5 @@
{
"tabWidth": 2,
"useTabs": false,
"singleQuote": true
}

View File

@ -1,31 +1,176 @@
# YouTube Music
<div align="center">
# YouTube Music
[![GitHub release](https://img.shields.io/github/release/th-ch/youtube-music.svg?style=for-the-badge&logo=youtube-music)](https://github.com/th-ch/youtube-music/releases/)
[![GitHub license](https://img.shields.io/github/license/th-ch/youtube-music.svg?style=for-the-badge)](https://github.com/th-ch/youtube-music/blob/master/LICENSE)
[![eslint code style](https://img.shields.io/badge/code_style-eslint-5ed9c7.svg?style=for-the-badge)](https://github.com/th-ch/youtube-music/blob/master/.eslintrc.js)
[![Build status](https://img.shields.io/github/actions/workflow/status/th-ch/youtube-music/build.yml?branch=master&style=for-the-badge&logo=youtube-music)](https://GitHub.com/th-ch/youtube-music/releases/)
[![Known Vulnerabilities](https://img.shields.io/snyk/vulnerabilities/github/th-ch/youtube-music?style=for-the-badge)](https://snyk.io/test/github/th-ch/youtube-music)
[![GitHub All Releases](https://img.shields.io/github/downloads/th-ch/youtube-music/total?style=for-the-badge&logo=youtube-music)](https://GitHub.com/th-ch/youtube-music/releases/)
[![AUR](https://img.shields.io/aur/version/youtube-music-bin?color=blueviolet&style=for-the-badge&logo=youtube-music)](https://aur.archlinux.org/packages/youtube-music-bin)
[![Known Vulnerabilities](https://snyk.io/test/github/th-ch/youtube-music/badge.svg)](https://snyk.io/test/github/th-ch/youtube-music)
</div>
![Screenshot](web/screenshot.jpg "Screenshot")
<div align="center">
<a href="https://github.com/th-ch/youtube-music/releases/latest">
<img src="web/youtube-music.svg" width="400" height="100">
<img src="web/youtube-music.svg" width="400" height="100" alt="YouTube Music SVG">
</a>
</div>
Read this in other languages: [🇰🇷](./docs/readme/README-ko.md), [🇮🇸](./docs/readme/README-is.md), [🇨🇱 🇪🇸](./docs/readme/README-es.md), [🇷🇺](./docs/readme/README-ru.md)
**Electron wrapper around YouTube Music featuring:**
- Native look & feel, aims at keeping the original interface
- Framework for custom plugins: change YouTube Music to your needs (style, content, features), enable/disable plugins in
one click
## Demo Image
| Player Screen (album color theme & ambient light) |
|:---------------------------------------------------------------------------------------------------------:|
|![Screenshot1](https://github.com/th-ch/youtube-music/assets/16558115/53efdf73-b8fa-4d7b-a235-b96b91ea77fc)|
## Content
- [Features](#features)
- [Available plugins](#available-plugins)
- [Translation](#translation)
- [Download](#download)
- [Arch Linux](#arch-linux)
- [MacOS](#macos)
- [Windows](#windows)
- [How to install without a network connection? (in Windows)](#how-to-install-without-a-network-connection-in-windows)
- [Themes](#themes)
- [Dev](#dev)
- [Build your own plugins](#build-your-own-plugins)
- [Creating a plugin](#creating-a-plugin)
- [Common use cases](#common-use-cases)
- [Build](#build)
- [Production Preview](#production-preview)
- [Tests](#tests)
- [License](#license)
- [FAQ](#faq)
## Features:
- **Auto confirm when paused** (Always Enabled): disable
the ["Continue Watching?"](https://user-images.githubusercontent.com/61631665/129977894-01c60740-7ec6-4bf0-9a2c-25da24491b0e.png)
popup that pause music after a certain time
- And more ...
## Available plugins:
- **Ad Blocker**: Block all ads and tracking out of the box
- **Album Actions**: Adds Undislike, Dislike, Like, and Unlike buttons to apply this to all songs in a playlist or album
- **Album Color Theme**: Applies a dynamic theme and visual effects based on the album color palette
- **Ambient Mode**: Applies a lighting effect by casting gentle colors from the video, into your screens background
- **Audio Compressor**: Apply compression to audio (lowers the volume of the loudest parts of the signal and raises the
volume of the softest parts)
- **Blur Navigation Bar**: makes navigation bar transparent and blurry
- **Bypass Age Restrictions**: bypass YouTube's age verification
- **Captions Selector**: Enable captions
- **Compact Sidebar**: Always set the sidebar in compact mode
- **Crossfade**: Crossfade between songs
- **Disable Autoplay**: Makes every song start in "paused" mode
- **[Discord](https://discord.com/) Rich Presence**: Show your friends what you listen to
with [Rich Presence](https://user-images.githubusercontent.com/28219076/104362104-a7a0b980-5513-11eb-9744-bb89eabe0016.png)
- **Downloader**: downloads
MP3 [directly from the interface](https://user-images.githubusercontent.com/61631665/129977677-83a7d067-c192-45e1-98ae-b5a4927393be.png) [(youtube-dl)](https://github.com/ytdl-org/youtube-dl)
- **Exponential Volume**: Makes the volume
slider [exponential](https://greasyfork.org/en/scripts/397686-youtube-music-fix-volume-ratio/) so it's easier to
select lower volumes
- **In-App Menu**: [gives bars a fancy, dark look](https://user-images.githubusercontent.com/78568641/112215894-923dbf00-8c29-11eb-95c3-3ce15db27eca.png)
> (see [this post](https://github.com/th-ch/youtube-music/issues/410#issuecomment-952060709) if you have problem
accessing the menu after enabling this plugin and hide-menu option)
- **Scrobbler**: Adds scrobbling support for [Last.fm](https://www.last.fm/) and [ListenBrainz](https://listenbrainz.org/)
- **Lumia Stream**: Adds [Lumia Stream](https://lumiastream.com/) support
- **Lyrics Genius**: Adds lyrics support for most songs
- **Music Together**: Share a playlist with others. When the host plays a song, everyone else will hear the same song
- **Navigation**: Next/Back navigation arrows directly integrated in the interface, like in your favorite browser
- **No Google Login**: Remove Google login buttons and links from the interface
- **Notifications**: Display a notification when a song starts
playing ([interactive notifications](https://user-images.githubusercontent.com/78568641/114102651-63ce0e00-98d0-11eb-9dfe-c5a02bb54f9c.png)
are available on windows)
- **Picture-in-picture**: allows to switch the app to picture-in-picture mode
- **Playback Speed**: Listen fast, listen
slow! [Adds a slider that controls song speed](https://user-images.githubusercontent.com/61631665/129976003-e55db5ba-bf42-448c-a059-26a009775e68.png)
- **Precise Volume**: Control the volume precisely using mousewheel/hotkeys, with a custom hud and customizable volume
steps
- **Shortcuts (& MPRIS)**: Allows setting global hotkeys for playback (play/pause/next/previous) +
disable [media osd](https://user-images.githubusercontent.com/84923831/128601225-afa38c1f-dea8-4209-9f72-0f84c1dd8b54.png)
by overriding media keys + enable Ctrl/CMD + F to search + enable linux mpris support for
mediakeys + [custom hotkeys](https://github.com/Araxeus/youtube-music/blob/1e591d6a3df98449bcda6e63baab249b28026148/providers/song-controls.js#L13-L50)
for [advanced users](https://github.com/th-ch/youtube-music/issues/106#issuecomment-952156902)
- **Skip Disliked Song**: Skips disliked songs
- **Skip Silences**: Automatically skip silenced sections
- [**SponsorBlock**](https://github.com/ajayyy/SponsorBlock): Automatically Skips non-music parts like intro/outro or
parts of music videos where the song isn't playing
- **Synced Lyrics**: Provides synced lyrics to songs, using providers like [LRClib](https://lrclib.net).
- **Taskbar Media Control**: Control playback from
your [Windows taskbar](https://user-images.githubusercontent.com/78568641/111916130-24a35e80-8a82-11eb-80c8-5021c1aa27f4.png)
- **TouchBar**: Custom TouchBar layout for macOS
- **Tuna OBS**: Integration with [OBS](https://obsproject.com/)'s
plugin [Tuna](https://obsproject.com/forum/resources/tuna.843/)
- **Video Quality Changer**: Allows changing the video quality with
a [button](https://user-images.githubusercontent.com/78568641/138574366-70324a5e-2d64-4f6a-acdd-dc2a2b9cecc5.png) on
the video overlay
- **Video Toggle**: Adds
a [button](https://user-images.githubusercontent.com/28893833/173663950-63e6610e-a532-49b7-9afa-54cb57ddfc15.png) to
switch between Video/Song mode. can also optionally remove the whole video tab
- **Visualizer**: Different music visualizers
## Translation
You can help with translation on [Hosted Weblate](https://hosted.weblate.org/projects/youtube-music/).
<a href="https://hosted.weblate.org/engage/youtube-music/">
<img src="https://hosted.weblate.org/widget/youtube-music/i18n/multi-auto.svg" alt="translation status" />
<img src="https://hosted.weblate.org/widget/youtube-music/i18n/287x66-black.png" alt="translation status 2" />
</a>
## Download
You can check out the [latest release](https://github.com/th-ch/youtube-music/releases/latest) to quickly find the
@ -33,12 +178,18 @@ latest version.
### Arch Linux
Install the `youtube-music-bin` package from the AUR. For AUR installation instructions, take a look at
Install the [`youtube-music-bin`](https://aur.archlinux.org/packages/youtube-music-bin) package from the AUR. For AUR installation instructions, take a look at
this [wiki page](https://wiki.archlinux.org/index.php/Arch_User_Repository#Installing_packages).
### MacOS
### macOS
If you get an error "is damaged and cant be opened." when launching the app, run the following in the Terminal:
You can install the app using Homebrew (see the [cask definition](https://github.com/th-ch/homebrew-youtube-music)):
```bash
brew install th-ch/youtube-music/youtube-music
```
If you install the app manually and get an error "is damaged and cant be opened." when launching the app, run the following in the Terminal:
```bash
xattr -cr /Applications/YouTube\ Music.app
@ -75,98 +226,6 @@ winget install th-ch.YouTubeMusic
- Place them in the **same directory**.
- Run the installer.
## Available plugins:
- **Ad Blocker**: Block all ads and tracking out of the box
- **Audio Compressor**: Apply compression to audio (lowers the volume of the loudest parts of the signal and raises the
volume of the softest parts)
- **Blur Nav Bar**: makes navigation bar transparent and blurry
- **Bypass age restrictions**: bypass YouTube's age verification
- **Captions selector**: Enable captions
- **Compact sidebar**: Always set the sidebar in compact mode
- **Crossfade**: Crossfade between songs
- **Disable Autoplay**: Makes every song start in "paused" mode
- [**Discord**](https://discord.com/): Show your friends what you listen to
with [Rich Presence](https://user-images.githubusercontent.com/28219076/104362104-a7a0b980-5513-11eb-9744-bb89eabe0016.png)
- **Downloader**: downloads
MP3 [directly from the interface](https://user-images.githubusercontent.com/61631665/129977677-83a7d067-c192-45e1-98ae-b5a4927393be.png) [(youtube-dl)](https://github.com/ytdl-org/youtube-dl)
- **Exponential Volume**: Makes the volume
slider [exponential](https://greasyfork.org/en/scripts/397686-youtube-music-fix-volume-ratio/) so it's easier to
select lower volumes.
- **In-App Menu**: [gives bars a fancy, dark look](https://user-images.githubusercontent.com/78568641/112215894-923dbf00-8c29-11eb-95c3-3ce15db27eca.png)
> (see [this post](https://github.com/th-ch/youtube-music/issues/410#issuecomment-952060709) if you have problem
accessing the menu after enabling this plugin and hide-menu option)
- [**Last.fm**](https://www.last.fm/): Scrobbles support
- **Lyrics Genius**: Adds lyrics support for most songs
- **Navigation**: Next/Back navigation arrows directly integrated in the interface, like in your favorite browser
- **No Google Login**: Remove Google login buttons and links from the interface
- **Notifications**: Display a notification when a song starts
playing ([interactive notifications](https://user-images.githubusercontent.com/78568641/114102651-63ce0e00-98d0-11eb-9dfe-c5a02bb54f9c.png)
are available on windows)
- **Picture in picture**: allows to switch the app to picture-in-picture mode
- **Playback Speed**: Listen fast, listen
slow! [Adds a slider that controls song speed](https://user-images.githubusercontent.com/61631665/129976003-e55db5ba-bf42-448c-a059-26a009775e68.png)
- **Precise Volume**: Control the volume precisely using mousewheel/hotkeys, with a custom hud and customizable volume
steps
- **Quality Changer**: Allows changing the video quality with
a [button](https://user-images.githubusercontent.com/78568641/138574366-70324a5e-2d64-4f6a-acdd-dc2a2b9cecc5.png) on
the video overlay
- **Shortcuts**: Allows setting global hotkeys for playback (play/pause/next/previous) +
disable [media osd](https://user-images.githubusercontent.com/84923831/128601225-afa38c1f-dea8-4209-9f72-0f84c1dd8b54.png)
by overriding media keys + enable Ctrl/CMD + F to search + enable linux mpris support for
mediakeys + [custom hotkeys](https://github.com/Araxeus/youtube-music/blob/1e591d6a3df98449bcda6e63baab249b28026148/providers/song-controls.js#L13-L50)
for [advanced users](https://github.com/th-ch/youtube-music/issues/106#issuecomment-952156902)
- **Skip-Silences** - Automatically skip silenced sections
- [**SponsorBlock**](https://github.com/ajayyy/SponsorBlock): Automatically Skips non-music parts like intro/outro or
parts of music videos where the song isn't playing
- **Taskbar Media Control**: Control playback from
your [Windows taskbar](https://user-images.githubusercontent.com/78568641/111916130-24a35e80-8a82-11eb-80c8-5021c1aa27f4.png)
- **Touchbar**: Custom TouchBar layout for macOS
- **Tuna-OBS**: Integration with [OBS](https://obsproject.com/)'s
plugin [Tuna](https://obsproject.com/forum/resources/tuna.843/)
- **Video Toggle**: Adds
a [button](https://user-images.githubusercontent.com/28893833/173663950-63e6610e-a532-49b7-9afa-54cb57ddfc15.png) to
switch between Video/Song mode. can also optionally remove the whole video tab
- **Visualizer**: Different music visualizers
---
- **Auto confirm when paused** (Always Enabled): disable
the ["Continue Watching?"](https://user-images.githubusercontent.com/61631665/129977894-01c60740-7ec6-4bf0-9a2c-25da24491b0e.png)
popup that pause music after a certain time
> If `Hide Menu` option is on - you can show the menu with the <kbd>alt</kbd> key (or <kbd>\`</kbd> [backtick] if using
> the in-app-menu plugin)
## Themes
You can load CSS files to change the look of the application (Options > Visual Tweaks > Themes).
@ -178,8 +237,8 @@ Some predefined themes are available in https://github.com/kerichdev/themes-for-
```bash
git clone https://github.com/th-ch/youtube-music
cd youtube-music
npm ci
npm run start
pnpm install --frozen-lockfile
pnpm dev
```
## Build your own plugins
@ -191,49 +250,72 @@ Using plugins, you can:
### Creating a plugin
Create a folder in `plugins/YOUR-PLUGIN-NAME`:
- if you need to manipulate the BrowserWindow, create a file with the following template:
Create a folder in `src/plugins/YOUR-PLUGIN-NAME`:
- `index.ts`: the main file of the plugin
```typescript
// file: back.ts
export default (win: Electron.BrowserWindow, config: ConfigType<'YOUR-PLUGIN-NAME'>) => {
// something
};
```
import style from './style.css?inline'; // import style as inline
then, register the plugin in `index.ts`:
import { createPlugin } from '@/utils';
```typescript
import yourPlugin from './plugins/YOUR-PLUGIN-NAME/back';
export default createPlugin({
name: 'Plugin Label',
restartNeeded: true, // if value is true, ytmusic show restart dialog
config: {
enabled: false,
}, // your custom config
stylesheets: [style], // your custom style,
menu: async ({ getConfig, setConfig }) => {
// All *Config methods are wrapped Promise<T>
const config = await getConfig();
return [
{
label: 'menu',
submenu: [1, 2, 3].map((value) => ({
label: `value ${value}`,
type: 'radio',
checked: config.value === value,
click() {
setConfig({ value });
},
})),
},
];
},
backend: {
start({ window, ipc }) {
window.maximize();
// ...
const mainPlugins = {
// ...
'YOUR-PLUGIN-NAME': yourPlugin,
};
```
- if you need to change the front, create a file with the following template:
```typescript
// file: front.ts
export default (config: ConfigType<'YOUR-PLUGIN-NAME'>) => {
// This function will be called as a preload script
// So you can use front features like `document.querySelector`
};
```
then, register the plugin in `preload.ts`:
```typescript
import yourPlugin from './plugins/YOUR-PLUGIN-NAME/front';
const rendererPlugins: PluginMapper<'renderer'> = {
// ...
'YOUR-PLUGIN-NAME': yourPlugin,
};
// you can communicate with renderer plugin
ipc.handle('some-event', () => {
return 'hello';
});
},
// it fired when config changed
onConfigChange(newConfig) { /* ... */ },
// it fired when plugin disabled
stop(context) { /* ... */ },
},
renderer: {
async start(context) {
console.log(await context.ipc.invoke('some-event'));
},
// Only renderer available hook
onPlayerApiReady(api: YoutubePlayer, context: RendererContext) {
// set plugin config easily
context.setConfig({ myConfig: api.getVolume() });
},
onConfigChange(newConfig) { /* ... */ },
stop(_context) { /* ... */ },
},
preload: {
async start({ getConfig }) {
const config = await getConfig();
},
onConfigChange(newConfig) {},
stop(_context) {},
},
});
```
### Common use cases
@ -241,45 +323,70 @@ const rendererPlugins: PluginMapper<'renderer'> = {
- injecting custom CSS: create a `style.css` file in the same folder then:
```typescript
import path from 'node:path';
import { injectCSS } from '../utils';
// index.ts
import style from './style.css?inline'; // import style as inline
// back.ts
export default (win: Electron.BrowserWindow) => {
injectCSS(win.webContents, path.join(__dirname, 'style.css'));
};
import { createPlugin } from '@/utils';
export default createPlugin({
name: 'Plugin Label',
restartNeeded: true, // if value is true, ytmusic will show a restart dialog
config: {
enabled: false,
}, // your custom config
stylesheets: [style], // your custom style
renderer() {} // define renderer hook
});
```
- changing the HTML:
- If you want to change the HTML:
```typescript
// front.ts
export default () => {
// Remove the login button
document.querySelector(".sign-in-link.ytmusic-nav-bar").remove();
};
import { createPlugin } from '@/utils';
export default createPlugin({
name: 'Plugin Label',
restartNeeded: true, // if value is true, ytmusic will show the restart dialog
config: {
enabled: false,
}, // your custom config
renderer() {
// Remove the login button
document.querySelector(".sign-in-link.ytmusic-nav-bar").remove();
} // define renderer hook
});
```
- communicating between the front and back: can be done using the ipcMain module from electron. See `utils.js` file and
example in `navigation` plugin.
- communicating between the front and back: can be done using the ipcMain module from electron. See `index.ts` file and
example in `sponsorblock` plugin.
## Build
1. Clone the repo
2. Run `npm i` to install dependencies
3. Run `npm run build:OS`
2. Follow [this guide](https://pnpm.io/installation) to install `pnpm`
3. Run `pnpm install --frozen-lockfile` to install dependencies
4. Run `pnpm build:OS`
- `npm run dist:win` - Windows
- `npm run dist:linux` - Linux
- `npm run dist:mac` - MacOS
- `pnpm dist:win` - Windows
- `pnpm dist:linux` - Linux (amd64)
- `pnpm dist:linux:deb-arm64` - Linux (arm64 for Debian)
- `pnpm dist:linux:rpm-arm64` - Linux (arm64 for Fedora)
- `pnpm dist:mac` - macOS (amd64)
- `pnpm dist:mac:arm64` - macOS (arm64)
Builds the app for macOS, Linux, and Windows,
using [electron-builder](https://github.com/electron-userland/electron-builder).
## Production Preview
```bash
pnpm start
```
## Tests
```bash
npm run test
pnpm test
```
Uses [Playwright](https://playwright.dev/) to test the app.
@ -287,3 +394,10 @@ Uses [Playwright](https://playwright.dev/) to test the app.
## License
MIT © [th-ch](https://github.com/th-ch/youtube-music)
## FAQ
### Why apps menu isn't showing up?
If `Hide Menu` option is on - you can show the menu with the <kbd>alt</kbd> key (or <kbd>\`</kbd> [backtick] if using
the in-app-menu plugin)

50
assets/error.html Normal file
View File

@ -0,0 +1,50 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>Cannot load YouTube Music</title>
<style>
body {
background: #000;
}
.container {
margin: 0;
font-family: Roboto, Arial, sans-serif;
font-size: 20px;
font-weight: 500;
color: rgba(255, 255, 255, 0.5);
position: absolute;
top: 50%;
left: 50%;
margin-right: -50%;
transform: translate(-50%, -50%);
text-align: center;
}
.button {
background: #065fd4;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: white;
font: inherit;
text-transform: uppercase;
text-decoration: none;
border-radius: 2px;
font-size: 16px;
font-weight: normal;
text-align: center;
padding: 8px 22px;
display: inline-block;
}
</style>
</head>
<body>
<div class="container">
<p>Cannot load YouTube Music… Internet disconnected?</p>
<a class="button" href="#" onclick="reload()">Retry</a>
</div>
</body>
</html>

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -2,8 +2,714 @@
All notable changes to this project will be documented in this file. Dates are displayed in UTC.
#### [v3.5.2](https://github.com/th-ch/youtube-music/compare/v3.5.1...v3.5.2)
- chore(deps): update typescript-eslint monorepo to v8.4.0 [`#2401`](https://github.com/th-ch/youtube-music/pull/2401)
- chore(deps): update dependency @total-typescript/ts-reset to v0.6.1 [`#2396`](https://github.com/th-ch/youtube-music/pull/2396)
- chore(deps): update dependency electron to v31.5.0 [`#2397`](https://github.com/th-ch/youtube-music/pull/2397)
- chore(deps): update dependency eslint-import-resolver-typescript to v3.6.3 [`#2376`](https://github.com/th-ch/youtube-music/pull/2376)
- chore(deps): update dependency discord-api-types to v0.37.100 [`#2394`](https://github.com/th-ch/youtube-music/pull/2394)
- fix(deps): update dependency electron-updater to v6.3.4 [`#2395`](https://github.com/th-ch/youtube-music/pull/2395)
- chore(deps): update dependency @babel/runtime to v7.25.6 [`#2388`](https://github.com/th-ch/youtube-music/pull/2388)
- chore(deps): update dependency vite-plugin-inspect to v0.8.7 [`#2389`](https://github.com/th-ch/youtube-music/pull/2389)
- chore(deps): update dependency discord-api-types to v0.37.99 [`#2374`](https://github.com/th-ch/youtube-music/pull/2374)
- chore(deps): update dependency vite to v5.4.3 [`#2377`](https://github.com/th-ch/youtube-music/pull/2377)
- fix: incorrect regex when splitting artistName [`#2378`](https://github.com/th-ch/youtube-music/pull/2378)
- chore(deps): update dependency @babel/runtime to v7.25.4 [`#2373`](https://github.com/th-ch/youtube-music/pull/2373)
- synced-lyrics: make the lyrics search more reliable [`#2343`](https://github.com/th-ch/youtube-music/pull/2343)
- fix(deps): update dependency solid-js to v1.8.22 [`#2354`](https://github.com/th-ch/youtube-music/pull/2354)
- chore(deps): update typescript-eslint monorepo to v8.3.0 [`#2350`](https://github.com/th-ch/youtube-music/pull/2350)
- fix(deps): update dependency electron-debug to v4.0.1 [`#2349`](https://github.com/th-ch/youtube-music/pull/2349)
- chore(deps): update dependency electron to v31.4.0 [`#2356`](https://github.com/th-ch/youtube-music/pull/2356)
- fix: hide native-controls on linux when in-app-menu is used [`#2366`](https://github.com/th-ch/youtube-music/pull/2366)
- fix: detect the upgrade btn using the icon [`#2364`](https://github.com/th-ch/youtube-music/pull/2364)
- fix: exclude build-id files from rpm [`#2361`](https://github.com/th-ch/youtube-music/pull/2361)
- fix(deps): update dependency i18next to v23.12.3 [`#2352`](https://github.com/th-ch/youtube-music/pull/2352)
- fix(deps): update dependency @floating-ui/dom to v1.6.10 [`#2340`](https://github.com/th-ch/youtube-music/pull/2340)
- fix(deps): update dependency electron-updater to v6.3.3 [`#2347`](https://github.com/th-ch/youtube-music/pull/2347)
- fix(deps): update dependency solid-js to v1.8.20 [`#2345`](https://github.com/th-ch/youtube-music/pull/2345)
- chore(deps): update dependency vite to v5.4.0 [`#2342`](https://github.com/th-ch/youtube-music/pull/2342)
- chore(deps): update typescript-eslint monorepo to v8.0.1 [`#2335`](https://github.com/th-ch/youtube-music/pull/2335)
- fix(deps): update dependency @floating-ui/dom to v1.6.9 [`#2337`](https://github.com/th-ch/youtube-music/pull/2337)
- chore(deps): update playwright monorepo to v1.46.0 [`#2336`](https://github.com/th-ch/youtube-music/pull/2336)
- chore(README): Translation README to Russian and adding Synced Lyrics to main README [`#2338`](https://github.com/th-ch/youtube-music/pull/2338)
- chore(deps): update dependency rollup to v4.20.0 [`#2326`](https://github.com/th-ch/youtube-music/pull/2326)
- fix(synced-lyric): fix timestamp [`#2323`](https://github.com/th-ch/youtube-music/issues/2323) [`#2379`](https://github.com/th-ch/youtube-music/issues/2379)
- Revert "fix(MPRIS): Prevents player to start with invalid MPRIS interface (#1996)" [`#2225`](https://github.com/th-ch/youtube-music/issues/2225)
- fix(adblocker/inplayer): fix Response.prototype.json [`#2310`](https://github.com/th-ch/youtube-music/issues/2310)
- chore(deps): update dependency eslint-plugin-import to v2.30.0 [`f48e46d`](https://github.com/th-ch/youtube-music/commit/f48e46d29cf09c76c5172fd56d2d0f705616e4e3)
- Revert "chore(deps): update dependency electron-builder to v25" [`089eff3`](https://github.com/th-ch/youtube-music/commit/089eff3152903c8b55ad3e5571b944062a647e27)
- chore(deps): update dependency electron-builder to v25 [`fe4c89c`](https://github.com/th-ch/youtube-music/commit/fe4c89c349bb9f4f54d95c2018943095ccfdab0c)
#### [v3.5.1](https://github.com/th-ch/youtube-music/compare/v3.5.0...v3.5.1)
> 1 August 2024
- fix(deps): update dependency youtubei.js to v10.3.0 [`#2306`](https://github.com/th-ch/youtube-music/pull/2306)
- fix: Window gets stuck offscreen in some instances [`#2303`](https://github.com/th-ch/youtube-music/pull/2303)
- fix: Incorrect window size on multi-monitor scaled displays [`#2302`](https://github.com/th-ch/youtube-music/pull/2302)
- chore(deps): update dependency rollup to v4.19.2 [`#2304`](https://github.com/th-ch/youtube-music/pull/2304)
- chore(deps): update typescript-eslint monorepo to v8 (major) [`#2297`](https://github.com/th-ch/youtube-music/pull/2297)
- fix(ambient-mode): fix ambient-mode not working for videos after restart [`#2294`](https://github.com/th-ch/youtube-music/pull/2294)
- fix(deps): update dependency @xhayper/discord-rpc to v1.2.0 [`#2291`](https://github.com/th-ch/youtube-music/pull/2291)
- fix(synced-lyrics): fix lyric load [`#2295`](https://github.com/th-ch/youtube-music/issues/2295)
- fix(ambient-mode): fix ambient-mode not working for videos after restart (#2294) [`#1641`](https://github.com/th-ch/youtube-music/issues/1641)
- fix(synced-lyrics): fix i18n [`8750b54`](https://github.com/th-ch/youtube-music/commit/8750b54f766c735ff039c6be454427f17d4737e2)
- ts-fix: disambiguate ElectronStore typings [`8775735`](https://github.com/th-ch/youtube-music/commit/877573532c1b68af861a3fdc44d093f3097d36ab)
- chore(i18n): Translated using Weblate (Hungarian) [`3537dc1`](https://github.com/th-ch/youtube-music/commit/3537dc19eecce7f7deb2478942f70d3c7b72148d)
#### [v3.5.0](https://github.com/th-ch/youtube-music/compare/v3.4.1...v3.5.0)
> 31 July 2024
- plugin: Synced Lyrics [`#2207`](https://github.com/th-ch/youtube-music/pull/2207)
- chore(deps): update dependency electron to v31.3.1 [`#2290`](https://github.com/th-ch/youtube-music/pull/2290)
- chore(deps): update typescript-eslint monorepo to v7.18.0 [`#2292`](https://github.com/th-ch/youtube-music/pull/2292)
- fix(deps): update dependency youtubei.js to v10.2.0 [`#2285`](https://github.com/th-ch/youtube-music/pull/2285)
- chore(deps): update dependency electron to v31.3.0 [`#2282`](https://github.com/th-ch/youtube-music/pull/2282)
- chore(deps): update typescript-eslint monorepo to v7.17.0 [`#2283`](https://github.com/th-ch/youtube-music/pull/2283)
- fix(deps): update dependency solid-js to v1.8.19 [`#2280`](https://github.com/th-ch/youtube-music/pull/2280)
- fix(deps): update dependency @xhayper/discord-rpc to v1.1.4 [`#2279`](https://github.com/th-ch/youtube-music/pull/2279)
- chore(deps): update dependency @babel/runtime to v7.25.0 [`#2281`](https://github.com/th-ch/youtube-music/pull/2281)
- fix(deps): update dependency @floating-ui/dom to v1.6.8 [`#2278`](https://github.com/th-ch/youtube-music/pull/2278)
- Fix: Incorrect window size on scaled displays [`#2258`](https://github.com/th-ch/youtube-music/pull/2258)
- chore(deps): update dependency vite-plugin-resolve to v2.5.2 [`#2276`](https://github.com/th-ch/youtube-music/pull/2276)
- chore(deps): update playwright monorepo to v1.45.3 [`#2277`](https://github.com/th-ch/youtube-music/pull/2277)
- fix(deps): update dependency deepmerge-ts to v7.1.0 [`#2263`](https://github.com/th-ch/youtube-music/pull/2263)
- chore(deps): update dependency typescript to v5.5.4 [`#2274`](https://github.com/th-ch/youtube-music/pull/2274)
- chore(deps): update dependency vite to v5.3.5 [`#2275`](https://github.com/th-ch/youtube-music/pull/2275)
- fix(deps): update dependency i18next to v23.12.2 [`#2260`](https://github.com/th-ch/youtube-music/pull/2260)
- chore(deps): update dependency discord-api-types to v0.37.93 [`#2273`](https://github.com/th-ch/youtube-music/pull/2273)
- chore(deps): update dependency rollup to v4.19.1 [`#2261`](https://github.com/th-ch/youtube-music/pull/2261)
- fix(deps): update dependency custom-electron-prompt to v1.5.8 [`#2262`](https://github.com/th-ch/youtube-music/pull/2262)
- feat(adblocker): add new option AdSpeedup [`#2235`](https://github.com/th-ch/youtube-music/pull/2235)
- fix: disable multi-plane format for software video [`#2254`](https://github.com/th-ch/youtube-music/pull/2254)
- chore(deps): update dependency eslint-plugin-prettier to v5.2.1 [`#2253`](https://github.com/th-ch/youtube-music/pull/2253)
- chore(deps): update dependency vite to v5.3.4 [`#2243`](https://github.com/th-ch/youtube-music/pull/2243)
- chore(deps): update typescript-eslint monorepo to v7.16.1 [`#2239`](https://github.com/th-ch/youtube-music/pull/2239)
- chore(deps): update playwright monorepo to v1.45.2 [`#2244`](https://github.com/th-ch/youtube-music/pull/2244)
- chore(deps): update dependency vite-plugin-inspect to v0.8.5 [`#2252`](https://github.com/th-ch/youtube-music/pull/2252)
- fix(deps): update dependency semver to v7.6.3 [`#2250`](https://github.com/th-ch/youtube-music/pull/2250)
- chore(deps): update dependency electron to v31.2.1 [`#2241`](https://github.com/th-ch/youtube-music/pull/2241)
- chore(i18n): Translated using Weblate (Catalan) [`4a8440c`](https://github.com/th-ch/youtube-music/commit/4a8440c281c341977ab3687982cec8cbc5af6cf7)
- Update changelog for v3.4.1 [`18e0b1b`](https://github.com/th-ch/youtube-music/commit/18e0b1b86341b13f1cbc713bfbd7b5d7a45ee392)
- fix(synced-lyrics): fix type error [`9357a15`](https://github.com/th-ch/youtube-music/commit/9357a15116a8526d22ba6142c0a02f31688743f2)
#### [v3.4.1](https://github.com/th-ch/youtube-music/compare/v3.4.0...v3.4.1)
> 15 July 2024
- fix(mpris): fix mpris position [`#2225`](https://github.com/th-ch/youtube-music/issues/2225)
- fix(deb): fix depends [`#1983`](https://github.com/th-ch/youtube-music/issues/1983)
- fix: fix touchbar icon [`#2183`](https://github.com/th-ch/youtube-music/issues/2183)
- fix: fix "Starting page" [`#1822`](https://github.com/th-ch/youtube-music/issues/1822)
- fix: fix album actions [`#2202`](https://github.com/th-ch/youtube-music/issues/2202)
- fix: fix playback slider [`#2045`](https://github.com/th-ch/youtube-music/issues/2045)
- chore(i18n): Translated using Weblate (Spanish) [`91bee48`](https://github.com/th-ch/youtube-music/commit/91bee4880ed2c6fdd887814a2620877d89bea311)
- Bump version to 3.4.1 [`02e2fb6`](https://github.com/th-ch/youtube-music/commit/02e2fb6a83844f439f760e72cdcb935b86000df2)
#### [v3.4.0](https://github.com/th-ch/youtube-music/compare/v3.3.12...v3.4.0)
> 14 July 2024
- fix(deps): update dependency i18next to v23.12.1 [`#2230`](https://github.com/th-ch/youtube-music/pull/2230)
- feat(downloader): New option to download on finish [`#1964`](https://github.com/th-ch/youtube-music/pull/1964)
- chore(deps): update typescript-eslint monorepo to v8.0.0-alpha.42 [`#2228`](https://github.com/th-ch/youtube-music/pull/2228)
- chore(deps): update dependency eslint to v9.7.0 [`#2226`](https://github.com/th-ch/youtube-music/pull/2226)
- chore(deps): update dependency @babel/runtime to v7.24.8 [`#2221`](https://github.com/th-ch/youtube-music/pull/2221)
- chore(deps): update dependency node-gyp to v10.2.0 [`#2216`](https://github.com/th-ch/youtube-music/pull/2216)
- chore(deps): update dependency ws to v8.18.0 [`#2217`](https://github.com/th-ch/youtube-music/pull/2217)
- chore(deps): update dependency glob to v11 [`#2219`](https://github.com/th-ch/youtube-music/pull/2219)
- chore(deps): update dependency esbuild to v0.23.0 [`#2215`](https://github.com/th-ch/youtube-music/pull/2215)
- chore(deps): update dependency electron to v31.2.0 [`#2214`](https://github.com/th-ch/youtube-music/pull/2214)
- fix(deps): update dependency youtubei.js to v10.1.0 [`#2218`](https://github.com/th-ch/youtube-music/pull/2218)
- chore(deps): update playwright monorepo to v1.45.1 [`#2212`](https://github.com/th-ch/youtube-music/pull/2212)
- chore(deps): update typescript-eslint monorepo to v8.0.0-alpha.41 [`#2213`](https://github.com/th-ch/youtube-music/pull/2213)
- chore(deps): update dependency rollup to v4.18.1 [`#2210`](https://github.com/th-ch/youtube-music/pull/2210)
- chore(deps): update dependency eslint to v9.6.0 [`#2192`](https://github.com/th-ch/youtube-music/pull/2192)
- chore(deps): update dependency vite to v5.3.3 [`#2211`](https://github.com/th-ch/youtube-music/pull/2211)
- chore(deps): update dependency glob to v10.4.5 [`#2205`](https://github.com/th-ch/youtube-music/pull/2205)
- chore(deps): update dependency discord-api-types to v0.37.92 [`#2204`](https://github.com/th-ch/youtube-music/pull/2204)
- fix(deps): update dependency solid-js to v1.8.18 [`#2189`](https://github.com/th-ch/youtube-music/pull/2189)
- chore(deps): update dependency typescript to v5.5.3 [`#2206`](https://github.com/th-ch/youtube-music/pull/2206)
- chore(deps): update dependency electron to v31.1.0 [`#2190`](https://github.com/th-ch/youtube-music/pull/2190)
- chore(deps): update typescript-eslint monorepo to v8.0.0-alpha.40 [`#2193`](https://github.com/th-ch/youtube-music/pull/2193)
- fix(deps): update dependency @floating-ui/dom to v1.6.7 [`#2196`](https://github.com/th-ch/youtube-music/pull/2196)
- chore(deps): update dependency vite to v5.3.2 [`#2188`](https://github.com/th-ch/youtube-music/pull/2188)
- chore(deps): update dependency discord-api-types to v0.37.91 [`#2187`](https://github.com/th-ch/youtube-music/pull/2187)
- chore(deps): update typescript-eslint monorepo to v8.0.0-alpha.34 [`#2184`](https://github.com/th-ch/youtube-music/pull/2184)
- fix(deps): update dependency @floating-ui/dom to v1.6.6 [`#2182`](https://github.com/th-ch/youtube-music/pull/2182)
- chore(deps): update playwright monorepo to v1.45.0 [`#2181`](https://github.com/th-ch/youtube-music/pull/2181)
- fix(deps): update dependency ts-morph to v23 [`#2180`](https://github.com/th-ch/youtube-music/pull/2180)
- chore(deps): update dependency electron-vite to v2.3.0 [`#2178`](https://github.com/th-ch/youtube-music/pull/2178)
- fix(deps): update dependency conf to v13.0.1 [`#2175`](https://github.com/th-ch/youtube-music/pull/2175)
- chore(deps): update dependency glob to v10.4.2 [`#2168`](https://github.com/th-ch/youtube-music/pull/2168)
- chore(deps): update dependency discord-api-types to v0.37.90 [`#2167`](https://github.com/th-ch/youtube-music/pull/2167)
- chore(deps): update dependency typescript to v5.5.2 [`#2173`](https://github.com/th-ch/youtube-music/pull/2173)
- chore(deps): update dependency electron to v31.0.2 [`#2170`](https://github.com/th-ch/youtube-music/pull/2170)
- chore(deps): update dependency ws to v8.17.1 [`#2164`](https://github.com/th-ch/youtube-music/pull/2164)
- chore(deps): update dependency eslint to v9.5.0 [`#2162`](https://github.com/th-ch/youtube-music/pull/2162)
- fix(deps): update dependency youtubei.js to v10 [`#2136`](https://github.com/th-ch/youtube-music/pull/2136)
- chore(deps): update dependency discord-api-types to v0.37.89 [`#2153`](https://github.com/th-ch/youtube-music/pull/2153)
- chore(deps): update dependency vite to v5.3.1 [`#2154`](https://github.com/th-ch/youtube-music/pull/2154)
- fix(deps): update dependency electron-store to v10 [`#2157`](https://github.com/th-ch/youtube-music/pull/2157)
- fix(deps): update dependency conf to v13 [`#2156`](https://github.com/th-ch/youtube-music/pull/2156)
- chore(deps): update dependency electron to v31.0.1 [`#2148`](https://github.com/th-ch/youtube-music/pull/2148)
- chore(deps): update dependency discord-api-types to v0.37.88 [`#2138`](https://github.com/th-ch/youtube-music/pull/2138)
- chore(deps): update typescript-eslint monorepo to v8.0.0-alpha.30 [`#2139`](https://github.com/th-ch/youtube-music/pull/2139)
- chore(deps): update dependency electron to v31 [`#2141`](https://github.com/th-ch/youtube-music/pull/2141)
- chore(deps): update dependency esbuild to v0.21.5 [`#2135`](https://github.com/th-ch/youtube-music/pull/2135)
- chore(deps): update typescript-eslint monorepo to v8.0.0-alpha.29 [`#2132`](https://github.com/th-ch/youtube-music/pull/2132)
- fix: rollback eslint version to v8 [`45931a2`](https://github.com/th-ch/youtube-music/commit/45931a25b08ab8a406f9e102486585311fd14bf9)
- chore(i18n): Translated using Weblate (Filipino) [`8a20566`](https://github.com/th-ch/youtube-music/commit/8a20566e0f2736f72d46282188ada69df1d7076a)
- chore(i18n): Translated using Weblate (Slovenian) [`40f0b9b`](https://github.com/th-ch/youtube-music/commit/40f0b9b852dcd9146e1c1e6c741b5baaf55ac079)
#### [v3.3.12](https://github.com/th-ch/youtube-music/compare/v3.3.11...v3.3.12)
> 8 June 2024
- hotfix: Revert "chore(deps): update dependencies `@cliqz/adblocker-electron`, `@cliqz/adblocker-electron-preload`" [`3c4abc1`](https://github.com/th-ch/youtube-music/commit/3c4abc14187e51f7e47c1ae71b3513f6d8c9912a)
- Update changelog for v3.3.11 [`de22444`](https://github.com/th-ch/youtube-music/commit/de224444c2a6d9030aa22a3b263ceacbc4b41914)
- Bump version to 3.3.12 [`89ed7d2`](https://github.com/th-ch/youtube-music/commit/89ed7d2345001fea59514944f4c1d56d2b7bd888)
#### [v3.3.11](https://github.com/th-ch/youtube-music/compare/v3.3.10...v3.3.11)
> 8 June 2024
- Revert "fix(deps): update dependency @cliqz/adblocker-electron to v1.27.10" [`#2129`](https://github.com/th-ch/youtube-music/pull/2129)
- chore(deps): update dependency vite to v5.2.13 [`#2127`](https://github.com/th-ch/youtube-music/pull/2127)
- chore(deps): update dependency electron to v30.1.0 [`#2126`](https://github.com/th-ch/youtube-music/pull/2126)
- fix(deps): update dependency deepmerge-ts to v7.0.3 [`#2125`](https://github.com/th-ch/youtube-music/pull/2125)
- chore(deps): update dependency @babel/runtime to v7.24.7 [`#2124`](https://github.com/th-ch/youtube-music/pull/2124)
- chore(deps): update typescript-eslint monorepo to v8.0.0-alpha.28 [`#2121`](https://github.com/th-ch/youtube-music/pull/2121)
- fix(deps): update dependency electron-updater to v6.2.1 [`#2120`](https://github.com/th-ch/youtube-music/pull/2120)
- chore(deps): update dependency discord-api-types to v0.37.87 [`#2119`](https://github.com/th-ch/youtube-music/pull/2119)
- fix(deps): update dependency deepmerge-ts to v7.0.2 [`#2118`](https://github.com/th-ch/youtube-music/pull/2118)
- chore(deps): update typescript-eslint monorepo to v8.0.0-alpha.25 [`#2114`](https://github.com/th-ch/youtube-music/pull/2114)
- fix(menu): fix menubar items doesn't rendered [`#2113`](https://github.com/th-ch/youtube-music/issues/2113)
- chore(i18n): Translated using Weblate (Nepali) [`4ae9a28`](https://github.com/th-ch/youtube-music/commit/4ae9a2820e9d453635094956264dd8b42c4997f7)
- chore(i18n): Translated using Weblate (Nepali) [`7e8d311`](https://github.com/th-ch/youtube-music/commit/7e8d31172ceb175ba07f307d248fc1246265a4c0)
- fix(deps): update dependency @cliqz/adblocker-electron to v1.27.10 [`d97aa1a`](https://github.com/th-ch/youtube-music/commit/d97aa1a8a003f15eea63c8cb2dabd0f215e885f1)
#### [v3.3.10](https://github.com/th-ch/youtube-music/compare/v3.3.9...v3.3.10)
> 2 June 2024
- fix(adblocker): fix blank screen [`#2103`](https://github.com/th-ch/youtube-music/issues/2103) [`#2105`](https://github.com/th-ch/youtube-music/issues/2105)
- chore(i18n): Translated using Weblate (Hungarian) [`25958a7`](https://github.com/th-ch/youtube-music/commit/25958a7bb1fea20e59676e7821f3dd8819602b68)
- fix(deps): bump deps [`4fa9762`](https://github.com/th-ch/youtube-music/commit/4fa9762a506544ce453894ce2df13033225e6c7d)
- fix(deps): bump `@typescript-eslint/eslint-plugin` version to 8.0.0-alpha.24 [`1e5bea8`](https://github.com/th-ch/youtube-music/commit/1e5bea85b31da5de868d9eff8758e5d2d888c2c8)
#### [v3.3.9](https://github.com/th-ch/youtube-music/compare/v3.3.8...v3.3.9)
> 1 June 2024
- chore(deps): update dependency eslint to v9.4.0 [`#2106`](https://github.com/th-ch/youtube-music/pull/2106)
- fix(adblocker): fix In-Player adblocker [`#1817`](https://github.com/th-ch/youtube-music/issues/1817)
- feat(adblocker): improve In-Player adblocker [`5b9e947`](https://github.com/th-ch/youtube-music/commit/5b9e947b8feebb57d9a2122ae7b7ab2ff7c37c06)
- chore(i18n): Translated using Weblate (French) [`9e809b0`](https://github.com/th-ch/youtube-music/commit/9e809b002d10f6ec0202a7d56d3d0b73f8093012)
- chore(i18n): Translated using Weblate (Malay) [`79151cb`](https://github.com/th-ch/youtube-music/commit/79151cb3aa6c087b8d8bb500322f505797b822bd)
#### [v3.3.8](https://github.com/th-ch/youtube-music/compare/v3.3.7...v3.3.8)
> 1 June 2024
- fix(adblocker): fix blank screen [`#1942`](https://github.com/th-ch/youtube-music/issues/1942) [`#2100`](https://github.com/th-ch/youtube-music/issues/2100) [`#2103`](https://github.com/th-ch/youtube-music/issues/2103)
- Update changelog for v3.3.7 [`b572623`](https://github.com/th-ch/youtube-music/commit/b572623442fc8b45b593dc0c91623fbf814115b4)
- Bump version to 3.3.8 [`5d99a85`](https://github.com/th-ch/youtube-music/commit/5d99a854e2f29bdb6682beeffa4e6b9b8be0f60f)
#### [v3.3.7](https://github.com/th-ch/youtube-music/compare/v3.3.6...v3.3.7)
> 1 June 2024
- chore(deps): update dependency electron to v30.0.9 [`#2098`](https://github.com/th-ch/youtube-music/pull/2098)
- Revert "fix(deps): update dependency @cliqz/adblocker-electron to v1.27.6" [`#2101`](https://github.com/th-ch/youtube-music/pull/2101)
- fix(deps): update dependency @cliqz/adblocker-electron to v1.27.6 [`#2096`](https://github.com/th-ch/youtube-music/pull/2096)
- chore(deps): update dependency discord-api-types to v0.37.86 [`#2092`](https://github.com/th-ch/youtube-music/pull/2092)
- chore(deps): update dependency vite to v5.2.12 [`#2094`](https://github.com/th-ch/youtube-music/pull/2094)
- chore(deps): update dependency @typescript-eslint/eslint-plugin to v7.11.0 [`#2093`](https://github.com/th-ch/youtube-music/pull/2093)
- chore(docs): Added README-es.md and linked to README.md [`#2090`](https://github.com/th-ch/youtube-music/pull/2090)
- fix(deps): update dependency deepmerge-ts to v7 [`#2085`](https://github.com/th-ch/youtube-music/pull/2085)
- chore(deps): update dependency builtin-modules to v4 [`#2084`](https://github.com/th-ch/youtube-music/pull/2084)
- fix(deps): update dependency electron-debug to v4 [`#2086`](https://github.com/th-ch/youtube-music/pull/2086)
- fix(deps): update dependency electron-store to v9 [`#2087`](https://github.com/th-ch/youtube-music/pull/2087)
- fix(deps): update dependency conf to v12 [`#1463`](https://github.com/th-ch/youtube-music/pull/1463)
- fix(deps): update dependency youtubei.js to v9.4.0 [`#2083`](https://github.com/th-ch/youtube-music/pull/2083)
- chore(deps): update playwright monorepo to v1.44.1 [`#2082`](https://github.com/th-ch/youtube-music/pull/2082)
- chore(deps): update dependency ws to v8.17.0 [`#2081`](https://github.com/th-ch/youtube-music/pull/2081)
- chore(deps): update dependency glob to v10.4.1 [`#2080`](https://github.com/th-ch/youtube-music/pull/2080)
- chore(deps): update dependency eslint to v9.3.0 [`#2079`](https://github.com/th-ch/youtube-music/pull/2079)
- fix(deps): update dependency peerjs to v1.5.4 [`#2075`](https://github.com/th-ch/youtube-music/pull/2075)
- chore(deps): update dependency esbuild to v0.21.4 [`#2078`](https://github.com/th-ch/youtube-music/pull/2078)
- fix(deps): update dependency semver to v7.6.2 [`#2076`](https://github.com/th-ch/youtube-music/pull/2076)
- chore(deps): update dependency electron-vite to v2.2.0 [`#2077`](https://github.com/th-ch/youtube-music/pull/2077)
- fix(deps): update dependency i18next to v23.11.5 [`#2074`](https://github.com/th-ch/youtube-music/pull/2074)
- fix(deps): update dependency @cliqz/adblocker-electron to v1.27.3 [`#2071`](https://github.com/th-ch/youtube-music/pull/2071)
- chore(deps): update dependency vite to v5.2.11 [`#2070`](https://github.com/th-ch/youtube-music/pull/2070)
- fix(deps): update dependency @floating-ui/dom to v1.6.5 [`#2073`](https://github.com/th-ch/youtube-music/pull/2073)
- fix(deps): update dependency @cliqz/adblocker-electron-preload to v1.27.3 [`#2072`](https://github.com/th-ch/youtube-music/pull/2072)
- chore(deps): update pnpm to v9 [`#1980`](https://github.com/th-ch/youtube-music/pull/1980)
- chore(deps): update dependency electron to v30.0.8 [`#2068`](https://github.com/th-ch/youtube-music/pull/2068)
- chore(deps-dev): bump ejs from 3.1.9 to 3.1.10 [`#2023`](https://github.com/th-ch/youtube-music/pull/2023)
- chore(deps): update dependency utf-8-validate to v6.0.4 [`#2069`](https://github.com/th-ch/youtube-music/pull/2069)
- fix(MPRIS): Prevents player to start with invalid MPRIS interface [`#1996`](https://github.com/th-ch/youtube-music/pull/1996)
- fix(deps): update dependency solid-js to v1.8.17 [`#2002`](https://github.com/th-ch/youtube-music/pull/2002)
- chore(deps): update dependency @typescript-eslint/eslint-plugin to v7.10.0 [`#2000`](https://github.com/th-ch/youtube-music/pull/2000)
- chore(deps): update dependency discord-api-types to v0.37.85 [`#1998`](https://github.com/th-ch/youtube-music/pull/1998)
- fix(deps): update dependency serve to v14.2.3 [`#1997`](https://github.com/th-ch/youtube-music/pull/1997)
- chore(deps): update dependency rollup to v4.18.0 [`#1990`](https://github.com/th-ch/youtube-music/pull/1990)
- feat: Enable arm64 for deb and rpm [`#2033`](https://github.com/th-ch/youtube-music/pull/2033)
- chore (README-is.md): Replace viðbót with tengiforrit [`#2004`](https://github.com/th-ch/youtube-music/pull/2004)
- chore(docs): readme file translated to french [`#2049`](https://github.com/th-ch/youtube-music/pull/2049)
- chore(deps): update dependency @babel/runtime to v7.24.6 [`#2039`](https://github.com/th-ch/youtube-music/pull/2039)
- Fix substract `margin-top` in fullscreen mode [`#2015`](https://github.com/th-ch/youtube-music/pull/2015)
- chore(deps): update pnpm to v8.15.7 [`#1970`](https://github.com/th-ch/youtube-music/pull/1970)
- fix(renderer): fix macos traffic lights gap [`#2035`](https://github.com/th-ch/youtube-music/issues/2035)
- Fix substract `margin-top` in fullscreen mode [`#2013`](https://github.com/th-ch/youtube-music/issues/2013)
- chore(i18n): Translated using Weblate (Hungarian) [`f3de171`](https://github.com/th-ch/youtube-music/commit/f3de17112af787437362f31b5c4e2d4149ba1436)
- feat(menu): add theme list in menu [`933b4cc`](https://github.com/th-ch/youtube-music/commit/933b4cc8f062b3442afd4516a40eb2938db98fc6)
- chore(i18n): Translated using Weblate (Filipino) [`91392c0`](https://github.com/th-ch/youtube-music/commit/91392c0c7efaf3b33da4be4aaa7946af7108d676)
#### [v3.3.6](https://github.com/th-ch/youtube-music/compare/v3.3.5...v3.3.6)
> 13 April 2024
- fix: add AdGuard as blocklist sources [`#1966`](https://github.com/th-ch/youtube-music/pull/1966)
- chore(deps): update dependency rollup to v4.14.2 [`#1968`](https://github.com/th-ch/youtube-music/pull/1968)
- fix(deps): update dependency youtubei.js to v9.3.0 [`#1967`](https://github.com/th-ch/youtube-music/pull/1967)
- chore(deps): update playwright monorepo to v1.43.1 [`#1969`](https://github.com/th-ch/youtube-music/pull/1969)
- chore(deps): update dependency electron to v29.3.0 [`#1961`](https://github.com/th-ch/youtube-music/pull/1961)
- fix(mpris): use global regex to replace minus in the video ID [`#1963`](https://github.com/th-ch/youtube-music/pull/1963)
- fix(deps): update dependency @cliqz/adblocker-electron-preload to v1.27.1 [`#1954`](https://github.com/th-ch/youtube-music/pull/1954)
- chore(deps): update dependency typescript to v5.4.5 [`#1958`](https://github.com/th-ch/youtube-music/pull/1958)
- fix(deps): update dependency youtubei.js to v9.2.1 [`#1957`](https://github.com/th-ch/youtube-music/pull/1957)
- fix(deps): update dependency i18next to v23.11.1 [`#1956`](https://github.com/th-ch/youtube-music/pull/1956)
- fix(deps): update dependency @cliqz/adblocker-electron to v1.27.1 [`#1953`](https://github.com/th-ch/youtube-music/pull/1953)
- chore(deps): update dependency @typescript-eslint/eslint-plugin to v7.6.0 [`#1947`](https://github.com/th-ch/youtube-music/pull/1947)
- fix(deps): update dependency i18next to v23.11.0 [`#1946`](https://github.com/th-ch/youtube-music/pull/1946)
- chore(deps): update dependency node-gyp to v10.1.0 [`#1941`](https://github.com/th-ch/youtube-music/pull/1941)
- chore(deps): update dependency eslint to v9 [`#1940`](https://github.com/th-ch/youtube-music/pull/1940)
- chore(deps): update dependency rollup to v4.14.1 [`#1944`](https://github.com/th-ch/youtube-music/pull/1944)
- chore(deps): update dependency node-gyp to v10.1.0 [`#1937`](https://github.com/th-ch/youtube-music/pull/1937)
- chore(deps): update dependency typescript to v5.4.4 [`#1936`](https://github.com/th-ch/youtube-music/pull/1936)
- chore(deps): update playwright monorepo to v1.43.0 [`#1938`](https://github.com/th-ch/youtube-music/pull/1938)
- chore(deps): bump undici from 5.28.3 to 5.28.4 [`#1935`](https://github.com/th-ch/youtube-music/pull/1935)
- chore(deps): update dependency vite to v5.2.8 [`#1930`](https://github.com/th-ch/youtube-music/pull/1930)
- chore(deps): update dependency discord-api-types to v0.37.79 [`#1933`](https://github.com/th-ch/youtube-music/pull/1933)
- chore(deps): update dependency node-gyp to v10.1.0 [`#1910`](https://github.com/th-ch/youtube-music/pull/1910)
- chore(deps): update dependency node-gyp to v10.1.0 [`#1908`](https://github.com/th-ch/youtube-music/pull/1908)
- fix(deps): update dependency @cliqz/adblocker-electron to v1.27.0 [`#1906`](https://github.com/th-ch/youtube-music/pull/1906)
- fix(deps): update dependency @cliqz/adblocker-electron-preload to v1.27.0 [`#1907`](https://github.com/th-ch/youtube-music/pull/1907)
- chore(deps): update dependency rollup to v4.13.2 [`#1901`](https://github.com/th-ch/youtube-music/pull/1901)
- chore(deps): update dependency glob to v10.3.12 [`#1900`](https://github.com/th-ch/youtube-music/pull/1900)
- chore(deps): update dependency vite to v5.2.7 [`#1905`](https://github.com/th-ch/youtube-music/pull/1905)
- fix(deps): update dependency node-html-parser to v6.1.13 [`#1903`](https://github.com/th-ch/youtube-music/pull/1903)
- chore(deps): update dependency discord-api-types to v0.37.77 [`#1899`](https://github.com/th-ch/youtube-music/pull/1899)
- chore(deps): update dependency electron to v29.1.6 [`#1898`](https://github.com/th-ch/youtube-music/pull/1898)
- Improve video title filters [`#1667`](https://github.com/th-ch/youtube-music/pull/1667)
- chore(deps): update dependency rollup to v4.13.1 [`#1896`](https://github.com/th-ch/youtube-music/pull/1896)
- chore(deps): update dependency node-gyp to v10.1.0 [`#1890`](https://github.com/th-ch/youtube-music/pull/1890)
- chore(deps): update dependency node-gyp to v10.1.0 [`#1889`](https://github.com/th-ch/youtube-music/pull/1889)
- fix: fix `switch-repeat` [`#1810`](https://github.com/th-ch/youtube-music/issues/1810)
- i18n Translation to Dutch/nl [`0dbf029`](https://github.com/th-ch/youtube-music/commit/0dbf0295b805f9883522ee00983b338060fbddbe)
- fix: rollback electron-builder version to 24.9.4 [`4a57cc5`](https://github.com/th-ch/youtube-music/commit/4a57cc5ee9ab2ad6835cff75b8b3aead75d9e564)
- chore: update electron-builder to 25.0.0-alpha.6 [`aef03ab`](https://github.com/th-ch/youtube-music/commit/aef03ab9fd440fe19c41e315cffab27e976c723d)
#### [v3.3.5](https://github.com/th-ch/youtube-music/compare/v3.3.4...v3.3.5)
> 26 March 2024
- chore(deps): update dependency node-gyp to v10.1.0 [`#1885`](https://github.com/th-ch/youtube-music/pull/1885)
- chore(deps): update dependency @typescript-eslint/eslint-plugin to v7.4.0 [`#1886`](https://github.com/th-ch/youtube-music/pull/1886)
- chore(deps): update dependency vite to v5.2.6 [`#1883`](https://github.com/th-ch/youtube-music/pull/1883)
- fix(style): resolve #1887 [`#1887`](https://github.com/th-ch/youtube-music/issues/1887)
- chore(i18n): Translated using Weblate (Swedish) [`69087bb`](https://github.com/th-ch/youtube-music/commit/69087bbf1fac1ba58e992146deb1d6f1706b1e3c)
- chore(i18n): Translated using Weblate (French) [`af78f15`](https://github.com/th-ch/youtube-music/commit/af78f1596ab8db2fa7069fdb1c4f078099ce4446)
- Update changelog for v3.3.4 [`62f7d44`](https://github.com/th-ch/youtube-music/commit/62f7d440fab5bdbe9f49a3a5f8c32e7aaf2f28f6)
#### [v3.3.4](https://github.com/th-ch/youtube-music/compare/v3.3.3...v3.3.4)
> 24 March 2024
- Update changelog for v3.3.3 [`9769544`](https://github.com/th-ch/youtube-music/commit/97695444affbacb71dd73ae7107d4c987e285a37)
- fix(style): fix fullscreen style and in-app-menu [`ed700c2`](https://github.com/th-ch/youtube-music/commit/ed700c2916cc7e6ccd2010d0c552364af116eb4f)
- fix(style): fix miniplayer style [`a8bc539`](https://github.com/th-ch/youtube-music/commit/a8bc53912d1f4137008ecb2d9d5d9d9eb06ee2a8)
#### [v3.3.3](https://github.com/th-ch/youtube-music/compare/v3.3.2...v3.3.3)
> 24 March 2024
- chore(deps): update dependency electron to v29.1.5 [`#1876`](https://github.com/th-ch/youtube-music/pull/1876)
- chore(deps): update dependency typescript to v5.4.3 [`#1877`](https://github.com/th-ch/youtube-music/pull/1877)
- chore(deps): update dependency discord-api-types to v0.37.76 [`#1878`](https://github.com/th-ch/youtube-music/pull/1878)
- chore(deps): update dependency vite to v5.2.4 [`#1881`](https://github.com/th-ch/youtube-music/pull/1881)
- Ambient Plugin cleanup [`#1880`](https://github.com/th-ch/youtube-music/pull/1880)
- chore(deps): update dependency vite to v5.2.2 [`#1875`](https://github.com/th-ch/youtube-music/pull/1875)
- fix(deps): update dependency solid-js to v1.8.16 [`#1873`](https://github.com/th-ch/youtube-music/pull/1873)
- chore(deps): update dependency @typescript-eslint/eslint-plugin to v7.3.1 [`#1868`](https://github.com/th-ch/youtube-music/pull/1868)
- chore(deps): update dependency discord-api-types to v0.37.75 [`#1867`](https://github.com/th-ch/youtube-music/pull/1867)
- chore(deps): update pnpm to v8.15.5 [`#1865`](https://github.com/th-ch/youtube-music/pull/1865)
- fix: Fix Miniplayer image size [`#1863`](https://github.com/th-ch/youtube-music/pull/1863)
- fix(style): fixed image/video alignment when toggle is active [`#1862`](https://github.com/th-ch/youtube-music/pull/1862)
- chore: Update README-is.md [`#1858`](https://github.com/th-ch/youtube-music/pull/1858)
- chore(deps): update dependency vite-plugin-solid to v2.10.2 [`#1859`](https://github.com/th-ch/youtube-music/pull/1859)
- fix: Ambient Mode intialization improvement [`#1857`](https://github.com/th-ch/youtube-music/pull/1857)
- chore(deps): bump follow-redirects from 1.15.5 to 1.15.6 [`#1856`](https://github.com/th-ch/youtube-music/pull/1856)
- chore(README): Nicer Readme 2.0 [`#1833`](https://github.com/th-ch/youtube-music/pull/1833)
- chore(deps): update dependency discord-api-types to v0.37.74 [`#1854`](https://github.com/th-ch/youtube-music/pull/1854)
- chore(deps): update dependency esbuild to v0.20.2 [`#1855`](https://github.com/th-ch/youtube-music/pull/1855)
- Improve ambient mode [`#1853`](https://github.com/th-ch/youtube-music/pull/1853)
- chore(deps): update dependency electron to v29.1.4 [`#1852`](https://github.com/th-ch/youtube-music/pull/1852)
- chore(deps): update dependency electron to v29.1.3 [`#1851`](https://github.com/th-ch/youtube-music/pull/1851)
- chore(deps): update dependency rollup to v4.13.0 [`#1850`](https://github.com/th-ch/youtube-music/pull/1850)
- fix(deps): update dependency electron-store to v8.2.0 [`#1843`](https://github.com/th-ch/youtube-music/pull/1843)
- chore(deps): update dependency electron to v29.1.1 [`#1841`](https://github.com/th-ch/youtube-music/pull/1841)
- fix(deps): update dependency i18next to v23.10.1 [`#1842`](https://github.com/th-ch/youtube-music/pull/1842)
- chore(deps): update dependency @typescript-eslint/eslint-plugin to v7.2.0 [`#1848`](https://github.com/th-ch/youtube-music/pull/1848)
- chore(deps): update dependency vite to v5.1.6 [`#1847`](https://github.com/th-ch/youtube-music/pull/1847)
- fix(deps): update dependency async-mutex to v0.5.0 [`#1849`](https://github.com/th-ch/youtube-music/pull/1849)
- fix(deps): update dependency ts-morph to v22 [`#1846`](https://github.com/th-ch/youtube-music/pull/1846)
- chore(deps): update dependency discord-api-types to v0.37.73 [`#1840`](https://github.com/th-ch/youtube-music/pull/1840)
- chore(deps): update dependency rollup to v4.12.1 [`#1837`](https://github.com/th-ch/youtube-music/pull/1837)
- chore: Changed a single word (README-is.md) [`#1836`](https://github.com/th-ch/youtube-music/pull/1836)
- chore(deps): update dependency typescript to v5.4.2 [`#1838`](https://github.com/th-ch/youtube-music/pull/1838)
- chore(deps): update dependency electron-vite to v2.1.0 [`#1823`](https://github.com/th-ch/youtube-music/pull/1823)
- chore(deps): update dependency @typescript-eslint/eslint-plugin to v7.1.1 [`#1829`](https://github.com/th-ch/youtube-music/pull/1829)
- chore(deps): update dependency vite to v5.1.5 [`#1831`](https://github.com/th-ch/youtube-music/pull/1831)
- Revert "chore(deps): update dependency electron-builder to v24.13.3" [`#1818`](https://github.com/th-ch/youtube-music/pull/1818)
- chore(deps): update dependency electron-builder to v24.13.3 [`#1774`](https://github.com/th-ch/youtube-music/pull/1774)
- chore(deps): update playwright monorepo to v1.42.1 [`#1816`](https://github.com/th-ch/youtube-music/pull/1816)
- fix: Add scale ratio for tray icons [`#1811`](https://github.com/th-ch/youtube-music/pull/1811)
- Icelandic translation of the readme file [`#1806`](https://github.com/th-ch/youtube-music/pull/1806)
- chore(deps): update dependency electron to v29.1.0 [`#1808`](https://github.com/th-ch/youtube-music/pull/1808)
- chore(deps): update playwright monorepo to v1.42.0 [`#1805`](https://github.com/th-ch/youtube-music/pull/1805)
- chore(deps): update dependency eslint to v8.57.0 [`#1793`](https://github.com/th-ch/youtube-music/pull/1793)
- chore(deps): update dependency @typescript-eslint/eslint-plugin to v7.1.0 [`#1800`](https://github.com/th-ch/youtube-music/pull/1800)
- chore(deps): update dependency discord-api-types to v0.37.71 [`#1799`](https://github.com/th-ch/youtube-music/pull/1799)
- chore(deps): update pnpm to v8.15.4 [`#1795`](https://github.com/th-ch/youtube-music/pull/1795)
- chore(deps): update dependency @types/semver to v7.5.8 [`#1797`](https://github.com/th-ch/youtube-music/pull/1797)
- fix: center the pause icon [`#1786`](https://github.com/th-ch/youtube-music/pull/1786)
- fix(deps): update dependency @cliqz/adblocker-electron to v1.26.16 [`#1788`](https://github.com/th-ch/youtube-music/pull/1788)
- fix(deps): update dependency @cliqz/adblocker-electron-preload to v1.26.16 [`#1789`](https://github.com/th-ch/youtube-music/pull/1789)
- fix(deps): update dependency youtubei.js to v9.1.0 [`#1790`](https://github.com/th-ch/youtube-music/pull/1790)
- fix(deps): update dependency i18next to v23.10.0 [`#1785`](https://github.com/th-ch/youtube-music/pull/1785)
- chore(deps): update dependency electron to v29 [`#1773`](https://github.com/th-ch/youtube-music/pull/1773)
- chore(deps): update dependency vite to v5.1.4 [`#1778`](https://github.com/th-ch/youtube-music/pull/1778)
- chore(deps): bump ip from 2.0.0 to 2.0.1 [`#1777`](https://github.com/th-ch/youtube-music/pull/1777)
- fix: add support for Wayland [`#1864`](https://github.com/th-ch/youtube-music/issues/1864)
- fix(style): fix navigation bar items are not working [`#1381`](https://github.com/th-ch/youtube-music/issues/1381) [`#1396`](https://github.com/th-ch/youtube-music/issues/1396) [`#1649`](https://github.com/th-ch/youtube-music/issues/1649)
- fix(ytm-bugs): fixed a `scrollbar-color` bug that affected Chromium 121 and later [`#1737`](https://github.com/th-ch/youtube-music/issues/1737)
- chore(i18n): Translated using Weblate (Icelandic) [`82fa871`](https://github.com/th-ch/youtube-music/commit/82fa8719a96abdfaaa8548a0077f4db2164ec09b)
- chore(i18n): Translated using Weblate (Romanian) [`c871506`](https://github.com/th-ch/youtube-music/commit/c871506a69180308ab4fc587b6e8a33f193087e8)
- chore(i18n): Translated using Weblate (Thai) [`a7d0350`](https://github.com/th-ch/youtube-music/commit/a7d035022a229f0b245694d1fc7a484befe1c269)
#### [v3.3.2](https://github.com/th-ch/youtube-music/compare/v3.3.1...v3.3.2)
> 20 February 2024
- fix: fix bugs in MPRIS, and improve MPRIS [`#1760`](https://github.com/th-ch/youtube-music/pull/1760)
- fix(deps): update dependency electron-updater to v6.1.8 [`#1770`](https://github.com/th-ch/youtube-music/pull/1770)
- chore(deps): update dependency electron-builder to v24.12.0 [`#1771`](https://github.com/th-ch/youtube-music/pull/1771)
- feat(scrobblers): use `BrowserWindow` instead of `shell.openExternal` [`#1758`](https://github.com/th-ch/youtube-music/pull/1758)
- chore(deps): update dependency @typescript-eslint/eslint-plugin to v7.0.2 [`#1763`](https://github.com/th-ch/youtube-music/pull/1763)
- chore(deps): update dependency esbuild to v0.20.1 [`#1759`](https://github.com/th-ch/youtube-music/pull/1759)
- fix(deps): update dependency i18next to v23.9.0 [`#1754`](https://github.com/th-ch/youtube-music/pull/1754)
- fix: fixed an issue that caused infinite loops when using Music Together [`#1752`](https://github.com/th-ch/youtube-music/issues/1752)
- chore(deps): rollback dependency electron-builder to v24.9.1 [`8bd05f5`](https://github.com/th-ch/youtube-music/commit/8bd05f525df98671f0a516b159cccab302b7ae99)
- chore(deps): update dependency electron-builder to v24.13.1 [`47b23b4`](https://github.com/th-ch/youtube-music/commit/47b23b414c8feb25c4d9a23d6adb7cbf1ac818fb)
- chore(i18n): Translated using Weblate (German) [`47505e9`](https://github.com/th-ch/youtube-music/commit/47505e97482f9e953ee451b968d0950585616ffa)
#### [v3.3.1](https://github.com/th-ch/youtube-music/compare/v3.3.0...v3.3.1)
> 18 February 2024
- Update changelog for v3.3.0 [`6d9bb8e`](https://github.com/th-ch/youtube-music/commit/6d9bb8eb1cc2d892a5552ffb1f7c20859aa80f67)
- hotfix: in-app-menu position issue [`87acf4c`](https://github.com/th-ch/youtube-music/commit/87acf4cf042ba32a000a4aeaec5c17c93501d333)
- release 3.3.1 (HOTFIX) [`a6ed8bf`](https://github.com/th-ch/youtube-music/commit/a6ed8bf3aa20ca8e950e85d88f981ccf9edc7498)
#### [v3.3.0](https://github.com/th-ch/youtube-music/compare/v3.2.2...v3.3.0)
> 18 February 2024
- fix(deps): update dependency i18next to v23.8.3 [`#1751`](https://github.com/th-ch/youtube-music/pull/1751)
- import fixed ./constants [`#1748`](https://github.com/th-ch/youtube-music/pull/1748)
- chore(deps): update dependency rollup to v4.12.0 [`#1743`](https://github.com/th-ch/youtube-music/pull/1743)
- chore(deps): bump undici from 5.28.2 to 5.28.3 [`#1747`](https://github.com/th-ch/youtube-music/pull/1747)
- chore(deps): update dependency vite to v5.1.3 [`#1742`](https://github.com/th-ch/youtube-music/pull/1742)
- chore(deps): update dependency vite-plugin-solid to v2.10.1 [`#1734`](https://github.com/th-ch/youtube-music/pull/1734)
- chore(deps): update dependency discord-api-types to v0.37.70 [`#1740`](https://github.com/th-ch/youtube-music/pull/1740)
- chore(deps): update dependency electron to v28.2.3 [`#1736`](https://github.com/th-ch/youtube-music/pull/1736)
- chore(deps): update pnpm to v8.15.3 [`#1739`](https://github.com/th-ch/youtube-music/pull/1739)
- chore(deps): update dependency rollup to v4.11.0 [`#1738`](https://github.com/th-ch/youtube-music/pull/1738)
- fix(deps): update dependency solid-js to v1.8.15 [`#1735`](https://github.com/th-ch/youtube-music/pull/1735)
- chore(deps): update dependency vite to v5.1.2 [`#1733`](https://github.com/th-ch/youtube-music/pull/1733)
- chore(deps): update dependency vite-plugin-solid to v2.10.0 [`#1732`](https://github.com/th-ch/youtube-music/pull/1732)
- chore(deps): update pnpm to v8.15.2 [`#1729`](https://github.com/th-ch/youtube-music/pull/1729)
- Update Copyright - 2024 [`#1730`](https://github.com/th-ch/youtube-music/pull/1730)
- chore(deps): update dependency @typescript-eslint/eslint-plugin to v7 [`#1728`](https://github.com/th-ch/youtube-music/pull/1728)
- fix(deps): update dependency @floating-ui/dom to v1.6.3 [`#1727`](https://github.com/th-ch/youtube-music/pull/1727)
- chore(deps): update dependency electron to v28.2.2 [`#1717`](https://github.com/th-ch/youtube-music/pull/1717)
- chore(deps): update dependency vite to v5.1.1 [`#1718`](https://github.com/th-ch/youtube-music/pull/1718)
- chore(deps): update dependency @types/semver to v7.5.7 [`#1724`](https://github.com/th-ch/youtube-music/pull/1724)
- fix(deps): update dependency @floating-ui/dom to v1.6.2 [`#1725`](https://github.com/th-ch/youtube-music/pull/1725)
- chore(deps): update dependency rollup to v4.10.0 [`#1719`](https://github.com/th-ch/youtube-music/pull/1719)
- fix(deps): update dependency solid-js to v1.8.14 [`#1713`](https://github.com/th-ch/youtube-music/pull/1713)
- chore(deps): update dependency @typescript-eslint/eslint-plugin to v6.21.0 [`#1711`](https://github.com/th-ch/youtube-music/pull/1711)
- fix(deps): update dependency semver to v7.6.0 [`#1712`](https://github.com/th-ch/youtube-music/pull/1712)
- refactor(in-app-menu): refactor `in-app-menu` plugin [`#1710`](https://github.com/th-ch/youtube-music/pull/1710)
- chore(deps): update playwright monorepo to v1.41.2 [`#1706`](https://github.com/th-ch/youtube-music/pull/1706)
- chore(deps): update dependency electron to v29.0.0-beta.5 [`#1707`](https://github.com/th-ch/youtube-music/pull/1707)
- feat(album-color-theme): support album color theme in all pages [`#1685`](https://github.com/th-ch/youtube-music/pull/1685)
- fix(deps): update dependency youtubei.js to v9.0.2 [`#1704`](https://github.com/th-ch/youtube-music/pull/1704)
- fix(deps): update dependency i18next to v23.8.2 [`#1702`](https://github.com/th-ch/youtube-music/pull/1702)
- feat: Support disabling scrobbling for non-music content [`#1665`](https://github.com/th-ch/youtube-music/pull/1665)
- fix(deps): update dependency youtubei.js to v9 [`#1682`](https://github.com/th-ch/youtube-music/pull/1682)
- chore(deps): update dependency electron to v29.0.0-beta.4 [`#1698`](https://github.com/th-ch/youtube-music/pull/1698)
- fix(deps): update dependency i18next to v23.8.1 [`#1694`](https://github.com/th-ch/youtube-music/pull/1694)
- chore(deps): update dependency @typescript-eslint/eslint-plugin to v6.20.0 [`#1700`](https://github.com/th-ch/youtube-music/pull/1700)
- chore(deps): update pnpm to v8.15.1 [`#1699`](https://github.com/th-ch/youtube-music/pull/1699)
- chore(deps): update dependency esbuild to v0.20.0 [`#1691`](https://github.com/th-ch/youtube-music/pull/1691)
- chore(deps): update pnpm to v8.15.0 [`#1692`](https://github.com/th-ch/youtube-music/pull/1692)
- fix(deps): update dependency i18next to v23.7.20 [`#1684`](https://github.com/th-ch/youtube-music/pull/1684)
- chore(deps): update dependency electron to v29.0.0-beta.3 [`#1683`](https://github.com/th-ch/youtube-music/pull/1683)
- chore(deps): update dependency electron to v29.0.0-beta.2 [`#1681`](https://github.com/th-ch/youtube-music/pull/1681)
- chore(deps): update dependency rollup to v4.9.6 [`#1663`](https://github.com/th-ch/youtube-music/pull/1663)
- chore(deps): update dependency electron to v29.0.0-beta.1 [`#1670`](https://github.com/th-ch/youtube-music/pull/1670)
- fix(deps): update dependency i18next to v23.7.19 [`#1680`](https://github.com/th-ch/youtube-music/pull/1680)
- chore(deps): update dependency @typescript-eslint/eslint-plugin to v6.19.1 [`#1669`](https://github.com/th-ch/youtube-music/pull/1669)
- chore(deps): update pnpm to v8.14.3 [`#1668`](https://github.com/th-ch/youtube-music/pull/1668)
- chore(deps): update dependency vite-plugin-inspect to v0.8.3 [`#1672`](https://github.com/th-ch/youtube-music/pull/1672)
- chore(deps): update dependency esbuild to v0.19.12 [`#1673`](https://github.com/th-ch/youtube-music/pull/1673)
- fix(deps): update dependency @electron/remote to v2.1.2 [`#1676`](https://github.com/th-ch/youtube-music/pull/1676)
- chore: Update issue templates [`#1661`](https://github.com/th-ch/youtube-music/pull/1661)
- chore(deps): update playwright monorepo to v1.41.1 [`#1660`](https://github.com/th-ch/youtube-music/pull/1660)
- fix(deps): update dependency i18next to v23.7.18 [`#1662`](https://github.com/th-ch/youtube-music/pull/1662)
- chore(deps): update actions/dependency-review-action action to v4 [`#1654`](https://github.com/th-ch/youtube-music/pull/1654)
- chore(deps): update dependency electron to v29.0.0-alpha.11 [`#1656`](https://github.com/th-ch/youtube-music/pull/1656)
- chore(deps): update dependency vite to v5.0.12 [security] [`#1659`](https://github.com/th-ch/youtube-music/pull/1659)
- fix(deps): update dependency async-mutex to v0.4.1 [`#1653`](https://github.com/th-ch/youtube-music/pull/1653)
- chore(deps): update playwright monorepo to v1.41.0 [`#1651`](https://github.com/th-ch/youtube-music/pull/1651)
- feat: Better Scrobbler Plugin [`#1640`](https://github.com/th-ch/youtube-music/pull/1640)
- chore(deps): update dependency electron to v29.0.0-alpha.10 [`#1645`](https://github.com/th-ch/youtube-music/pull/1645)
- chore(deps): update dependency @typescript-eslint/eslint-plugin to v6.19.0 [`#1643`](https://github.com/th-ch/youtube-music/pull/1643)
- chore(README): Fix plugins names and add plugins in/to Readme (in menu too) [`#1624`](https://github.com/th-ch/youtube-music/pull/1624)
- fix(album-actions): Fixed album actions [`#1639`](https://github.com/th-ch/youtube-music/pull/1639)
- chore(deps): update playwright monorepo to v1.41.0-beta-1705101589000 [`#1638`](https://github.com/th-ch/youtube-music/pull/1638)
- fix(#1543): fix song control doesn't work [`#1637`](https://github.com/th-ch/youtube-music/pull/1637)
- chore(deps): update playwright monorepo to v1.41.0-beta-1705092460000 [`#1635`](https://github.com/th-ch/youtube-music/pull/1635)
- chore(deps): update dependency rollup to v4.9.5 [`#1629`](https://github.com/th-ch/youtube-music/pull/1629)
- chore(deps): update dependency electron to v29.0.0-alpha.9 [`#1627`](https://github.com/th-ch/youtube-music/pull/1627)
- chore(deps): update dependency electron to v29.0.0-alpha.8 [`#1608`](https://github.com/th-ch/youtube-music/pull/1608)
- fix(deps): update dependency @cliqz/adblocker-electron to v1.26.15 [`#1615`](https://github.com/th-ch/youtube-music/pull/1615)
- chore(deps): update dependency rollup to v4.9.4 [`#1591`](https://github.com/th-ch/youtube-music/pull/1591)
- fix(deps): update dependency @cliqz/adblocker-electron-preload to v1.26.15 [`#1616`](https://github.com/th-ch/youtube-music/pull/1616)
- chore(deps): update pnpm to v8.14.1 [`#1619`](https://github.com/th-ch/youtube-music/pull/1619)
- chore(deps): update dependency eslint-plugin-prettier to v5.1.3 [`#1618`](https://github.com/th-ch/youtube-music/pull/1618)
- chore(deps): update dependency @typescript-eslint/eslint-plugin to v6.18.1 [`#1612`](https://github.com/th-ch/youtube-music/pull/1612)
- fix(deps): update dependency youtubei.js to v8.2.0 [`#1614`](https://github.com/th-ch/youtube-music/pull/1614)
- chore(deps): update dependency electron-vite to v2.0.0 [`#1609`](https://github.com/th-ch/youtube-music/pull/1609)
- chore(deps): update dependency @typescript-eslint/eslint-plugin to v6.18.0 [`#1603`](https://github.com/th-ch/youtube-music/pull/1603)
- chore(deps): update dependency electron-vite to v2.0.0-beta.4 [`#1602`](https://github.com/th-ch/youtube-music/pull/1602)
- fix: fix upgrade button [`#1199`](https://github.com/th-ch/youtube-music/issues/1199)
- fix(mpris): fix mpris invalid position [`#1726`](https://github.com/th-ch/youtube-music/issues/1726)
- fix: discord RPC (fix #1664) [`#1664`](https://github.com/th-ch/youtube-music/issues/1664)
- fix: remove sign-in button (fix #1199) [`#1199`](https://github.com/th-ch/youtube-music/issues/1199)
- Fix #1617 [`#1617`](https://github.com/th-ch/youtube-music/issues/1617)
- fix(crossfade): fix #1633 [`#1633`](https://github.com/th-ch/youtube-music/issues/1633)
- fix: fix #1621 [`#1621`](https://github.com/th-ch/youtube-music/issues/1621)
- fix(tuna-obs): partially fix #1596 [`#1596`](https://github.com/th-ch/youtube-music/issues/1596)
- fix(discord): fix hide duration button [`#1644`](https://github.com/th-ch/youtube-music/issues/1644)
- fix(in-app-menu): fix invalid `margin-top` [`#1597`](https://github.com/th-ch/youtube-music/issues/1597)
- fix(README): fix `plugins` path [`#1598`](https://github.com/th-ch/youtube-music/issues/1598)
- chore(i18n): Translated using Weblate (Vietnamese) [`0528637`](https://github.com/th-ch/youtube-music/commit/05286371353e8b4c36a5b9fe9011ae5dfdc7ee82)
- chore: update pnpm-lock [`fd8d59b`](https://github.com/th-ch/youtube-music/commit/fd8d59bada56dab4e156d22394fe0c5efec5abc4)
- fix(in-app-menu): fix app crash in production [`febc63e`](https://github.com/th-ch/youtube-music/commit/febc63edef375bd82db48b7fb460ec5a601ab872)
#### [v3.2.2](https://github.com/th-ch/youtube-music/compare/v3.2.1...v3.2.2)
> 5 January 2024
- feat(tray): Add song info and paused icon [`#1592`](https://github.com/th-ch/youtube-music/pull/1592)
- fix(skip-silences): fix audio distorted [`#1141`](https://github.com/th-ch/youtube-music/issues/1141)
- chore(deps): update dependency rollup to v4.9.3 [`0c3c380`](https://github.com/th-ch/youtube-music/commit/0c3c3805918adf2a185a7f1dc67ea3af8135863d)
- chore(i18n): Translated using Weblate (Turkish) [`64ea1fd`](https://github.com/th-ch/youtube-music/commit/64ea1fdb58fdf2766ae3284ac1a51bfac8894b36)
- fix(music-together): typing [`895386f`](https://github.com/th-ch/youtube-music/commit/895386f6f8c649f77ea15c88f6fb7ecc5b775554)
#### [v3.2.1](https://github.com/th-ch/youtube-music/compare/v3.2.0...v3.2.1)
> 1 January 2024
- fix: fix #1574 [`#1574`](https://github.com/th-ch/youtube-music/issues/1574)
- fix: fix #1575 [`#1575`](https://github.com/th-ch/youtube-music/issues/1575)
- chore(i18n): Translated using Weblate [`f5aa179`](https://github.com/th-ch/youtube-music/commit/f5aa179cd639eb4b8f70f1264b5b459ebcc16695)
- chore(i18n): Translated using Weblate (English) [`e409165`](https://github.com/th-ch/youtube-music/commit/e409165e1bed85f3d1aea3a565e7b9e462b1e05b)
- chore(i18n): Translated using Weblate (Czech) [`0ca4e34`](https://github.com/th-ch/youtube-music/commit/0ca4e34efd86e877314e5a245f266065b4cf0013)
#### [v3.2.0](https://github.com/th-ch/youtube-music/compare/v3.1.1...v3.2.0)
> 1 January 2024
- feat(album-color-theme): improve `Album Color Theme` style [`#1571`](https://github.com/th-ch/youtube-music/pull/1571)
- feat(menu): add more detail in Menu [`#1570`](https://github.com/th-ch/youtube-music/pull/1570)
- feat(music-together): Add new plugin `Music Together` [`#1562`](https://github.com/th-ch/youtube-music/pull/1562)
- chore(deps): update dependency rollup to v4.9.2 [`#1567`](https://github.com/th-ch/youtube-music/pull/1567)
- fix(deps): update dependency i18next to v23.7.13 [`#1569`](https://github.com/th-ch/youtube-music/pull/1569)
- feat: Add new plugin `Album actions` [`#1515`](https://github.com/th-ch/youtube-music/pull/1515)
- fix(deps): update dependency i18next to v23.7.12 [`#1564`](https://github.com/th-ch/youtube-music/pull/1564)
- fix: Only apply scale factor on Windows [`#1565`](https://github.com/th-ch/youtube-music/pull/1565)
- chore(deps): update dependency @typescript-eslint/eslint-plugin to v6.16.0 [`#1556`](https://github.com/th-ch/youtube-music/pull/1556)
- chore(deps): update pnpm to v8.13.1 [`#1557`](https://github.com/th-ch/youtube-music/pull/1557)
- chore(deps): update dependency ws to v8.16.0 [`#1559`](https://github.com/th-ch/youtube-music/pull/1559)
- fix(deps): update dependency youtubei.js to v8.1.0 [`#1560`](https://github.com/th-ch/youtube-music/pull/1560)
- fix(deps): update dependency node-html-parser to v6.1.12 [`#1554`](https://github.com/th-ch/youtube-music/pull/1554)
- Revert "fix(deps): update dependency @xhayper/discord-rpc to v1.1.2" [`#1552`](https://github.com/th-ch/youtube-music/pull/1552)
- feat(ambient-mode): support ambient mode on `Song section` [`#1555`](https://github.com/th-ch/youtube-music/issues/1555)
- fix: fixed an issue with the download button disappearing [`#1551`](https://github.com/th-ch/youtube-music/issues/1551)
- fix: fix `homebrew cask` [`#1514`](https://github.com/th-ch/youtube-music/issues/1514)
- fix: pnpm build error [`13ef856`](https://github.com/th-ch/youtube-music/commit/13ef8560ff43353030537403be7da82542ba535e)
- chore(i18n): Translated using Weblate (Czech) [`0dc9c6a`](https://github.com/th-ch/youtube-music/commit/0dc9c6a1a90bce6505614617b827e816cbaaf875)
- chore(deps): update dependency @typescript-eslint/eslint-plugin to v6.15.0 [`c5bcd89`](https://github.com/th-ch/youtube-music/commit/c5bcd89f164b51d7380486a8ae35edd0caeea842)
#### [v3.1.1](https://github.com/th-ch/youtube-music/compare/v3.1.0...v3.1.1)
> 18 December 2023
- fix: fix renderer plugin load timing [`#1522`](https://github.com/th-ch/youtube-music/issues/1522)
- chore(i18n): Translated using Weblate (Lithuanian) [`fc1a7cd`](https://github.com/th-ch/youtube-music/commit/fc1a7cda62b6e33e5f5d57a5a6e0adef6a32bf9a)
- chore(i18n): Translated using Weblate (Chinese (Simplified)) [`eba7026`](https://github.com/th-ch/youtube-music/commit/eba7026b89bbfdd3ac07cf728a66ba9bdd274ec0)
- chore(deps): update dependency rollup to v4.8.0 [`a601d0b`](https://github.com/th-ch/youtube-music/commit/a601d0b3d2dee0fabad79a18e1a7dd0ca84ccf01)
#### [v3.1.0](https://github.com/th-ch/youtube-music/compare/v3.0.2...v3.1.0)
> 11 December 2023
- chore(deps): update dependency electron to v28 [`#1498`](https://github.com/th-ch/youtube-music/pull/1498)
- Enable/Disable Navigation without restart [`#1507`](https://github.com/th-ch/youtube-music/pull/1507)
- Turkish(tr)_lang_file [`#1513`](https://github.com/th-ch/youtube-music/pull/1513)
- Skip Disliked Songs [`#1505`](https://github.com/th-ch/youtube-music/pull/1505)
- chore(deps): update dependency @typescript-eslint/eslint-plugin to v6.13.2 [`#1452`](https://github.com/th-ch/youtube-music/pull/1452)
- fix: Homebrew latest release url parsing [`#1496`](https://github.com/th-ch/youtube-music/pull/1496)
- fix: in-player adblocker inject timing issue [`#1478`](https://github.com/th-ch/youtube-music/issues/1478)
- fix(package.json): fix RPM version `libuuid` issue [`#1508`](https://github.com/th-ch/youtube-music/issues/1508)
- Translated using Weblate (Polish) [`7b78ba6`](https://github.com/th-ch/youtube-music/commit/7b78ba67613f14be65a45751efeb06431b405a91)
- Translated using Weblate (French) [`ebc0879`](https://github.com/th-ch/youtube-music/commit/ebc087963b23265ff00528c8305d51597abf587a)
- Translated using Weblate (Chinese (Traditional)) [`020bdc0`](https://github.com/th-ch/youtube-music/commit/020bdc0811ea45ad6c2853c62a05ae6695c5c4f9)
#### [v3.0.2](https://github.com/th-ch/youtube-music/compare/v3.0.1...v3.0.2)
> 3 December 2023
- fix(adblocker): fix In-Player adblocker [`#1478`](https://github.com/th-ch/youtube-music/issues/1478)
- fix(menu): crash on linux [`#1477`](https://github.com/th-ch/youtube-music/issues/1477)
- fix: update pnpm-lock.yaml [`9e2c6b1`](https://github.com/th-ch/youtube-music/commit/9e2c6b1afa33b5708853c8328946e68ec45b09c3)
- Translated using Weblate (Chinese (Traditional)) [`125b69f`](https://github.com/th-ch/youtube-music/commit/125b69fd75a05c3eb893886119e2d9f2332b3e56)
- Translated using Weblate (French) [`15c4551`](https://github.com/th-ch/youtube-music/commit/15c455105b5100a8ee2bd0a4631548d3d455f047)
#### [v3.0.1](https://github.com/th-ch/youtube-music/compare/v3.0.0...v3.0.1)
> 2 December 2023
- hotfix(adblocker): fix #1475 [`#1475`](https://github.com/th-ch/youtube-music/issues/1475)
- Translated using Weblate (French) [`7f02afc`](https://github.com/th-ch/youtube-music/commit/7f02afc5a6839adfe8437d4e2cc8dee13a93b311)
- Update changelog for v3.0.0 [`d8c8bd1`](https://github.com/th-ch/youtube-music/commit/d8c8bd17ecfbdf96ebd29eb4c5748c07876ee242)
- Translated using Weblate (German) [`0660f0b`](https://github.com/th-ch/youtube-music/commit/0660f0b7ce6895ef5800f48ade1da2d7f8e0c1f7)
### [v3.0.0](https://github.com/th-ch/youtube-music/compare/v2.2.0...v3.0.0)
> 2 December 2023
- Add text to Translation section [`#1470`](https://github.com/th-ch/youtube-music/pull/1470)
- fix(deps): update dependency youtubei.js to v8 [`#1473`](https://github.com/th-ch/youtube-music/pull/1473)
- chore(deps): update dependency electron to v27.1.3 [`#1471`](https://github.com/th-ch/youtube-music/pull/1471)
- fix(deps): update dependency @xhayper/discord-rpc to v1.1.1 [`#1472`](https://github.com/th-ch/youtube-music/pull/1472)
- feat: add support i18n [`#1468`](https://github.com/th-ch/youtube-music/pull/1468)
- chore(deps): update dependency electron to v27.1.2 [`#1441`](https://github.com/th-ch/youtube-music/pull/1441)
- Nicer Readme [`#1439`](https://github.com/th-ch/youtube-music/pull/1439)
- Windows Zoom, ScaleFactor [`#1402`](https://github.com/th-ch/youtube-music/pull/1402)
- chore(deps): bump axios from 1.5.1 to 1.6.1 [`#1400`](https://github.com/th-ch/youtube-music/pull/1400)
- Updated mac icon to better reflect the Mac styling [`#1395`](https://github.com/th-ch/youtube-music/pull/1395)
- feat: rename plugins to clarify context [`#1392`](https://github.com/th-ch/youtube-music/pull/1392)
- feat: refactor plugin utils [`#1391`](https://github.com/th-ch/youtube-music/pull/1391)
- feat: plugin auto-importer with `vite-plugin-resolve` [`#1385`](https://github.com/th-ch/youtube-music/pull/1385)
- feat: migrate from `rollup` to `electron-vite` [`#1364`](https://github.com/th-ch/youtube-music/pull/1364)
- feat: enable `context-isolation` [`#1361`](https://github.com/th-ch/youtube-music/pull/1361)
- fix: add workaround for `podcast` type video [`#1362`](https://github.com/th-ch/youtube-music/pull/1362)
- fix: fix broken menu-layout [`#1360`](https://github.com/th-ch/youtube-music/pull/1360)
- Add Homebrew cask install option for MacOS. [`#1357`](https://github.com/th-ch/youtube-music/pull/1357)
- feat: changed Zoom shortcuts to standard [`#1458`](https://github.com/th-ch/youtube-music/issues/1458)
- fix(in-app-menu): fix #1436 [`#1436`](https://github.com/th-ch/youtube-music/issues/1436)
- fix(discord): update application client-id [`#1431`](https://github.com/th-ch/youtube-music/issues/1431)
- chore(deps): update dependency electron to v27.0.4 [`#1324`](https://github.com/th-ch/youtube-music/issues/1324)
- fix(in-app-menu): panel should close with the window when it is closed [`#1389`](https://github.com/th-ch/youtube-music/issues/1389)
- fix: change titleBarOverlay height based on zoomFactor [`#1375`](https://github.com/th-ch/youtube-music/issues/1375)
- fix: fixed an issue if "Always on top" is enabled, the dialog is displayed below the window [`#1379`](https://github.com/th-ch/youtube-music/issues/1379)
- fix: fix winget version (fix #1363) [`#1363`](https://github.com/th-ch/youtube-music/issues/1363)
- feat: run prettier [`a3104fd`](https://github.com/th-ch/youtube-music/commit/a3104fda4b0d58b076d0c737111636a66e468acc)
- Translated using Weblate (Korean) [`b4b7ad8`](https://github.com/th-ch/youtube-music/commit/b4b7ad824b8c489ae483eba139b46e5b200231fc)
- Translated using Weblate (English) [`d2eabaa`](https://github.com/th-ch/youtube-music/commit/d2eabaa4bbccd89eae529eae52cec035e8e2620c)
#### [v2.2.0](https://github.com/th-ch/youtube-music/compare/v2.1.3...v2.2.0)
> 27 October 2023
- feat(ambient-mode): add config for `ambient-mode` plugin [`#1349`](https://github.com/th-ch/youtube-music/pull/1349)
- bump deps [`4248d20`](https://github.com/th-ch/youtube-music/commit/4248d20e8ef926ce7b1d07eb83743755a341d9f6)
- Update changelog for v2.1.3 [`dc73561`](https://github.com/th-ch/youtube-music/commit/dc73561c8a8acfc8ba91aff2dc78e4267869f2fd)
- Bump version to 2.2.0 [`6288d0b`](https://github.com/th-ch/youtube-music/commit/6288d0b171a65ea015922cdf3af6c7bd9a1f269b)
#### [v2.1.3](https://github.com/th-ch/youtube-music/compare/v2.1.2...v2.1.3)
> 23 October 2023
- fix: fixed bugs in downloader [`#1342`](https://github.com/th-ch/youtube-music/pull/1342)
- feat(discord): rename `Listen Along` to `Play on YTM` [`#1341`](https://github.com/th-ch/youtube-music/issues/1341)
- chore(deps): bump deps [`4333891`](https://github.com/th-ch/youtube-music/commit/4333891ccabe42aedf756fd48618be715db13262)
- Update changelog for v2.1.2 [`fa4c69d`](https://github.com/th-ch/youtube-music/commit/fa4c69d228d4e06a7858e2b22fcdfa075a8ca766)
- fix(store): fix listenAlong statement [`bceaa05`](https://github.com/th-ch/youtube-music/commit/bceaa05197d47a4a4bbd22e767d1e4d6ec277514)
#### [v2.1.2](https://github.com/th-ch/youtube-music/compare/v2.1.1...v2.1.2)
> 19 October 2023
- feat(in-app-menu): add an option to hide the window controls [`#1335`](https://github.com/th-ch/youtube-music/pull/1335)
- fix: fixed an issue where the album name was missing [`#1334`](https://github.com/th-ch/youtube-music/pull/1334)
- chore(deps): update dependency electron to v27.0.1 [`#1331`](https://github.com/th-ch/youtube-music/pull/1331)
- fix: fixed an issue where only the first 100 songs in a playlist were downloaded [`#1329`](https://github.com/th-ch/youtube-music/pull/1329)
- Updated readme plugins list [`#1326`](https://github.com/th-ch/youtube-music/pull/1326)
- QOL: Move source code under the src directory. [`#1318`](https://github.com/th-ch/youtube-music/pull/1318)
- feat: migrate from `npm` to `pnpm` [`#1316`](https://github.com/th-ch/youtube-music/pull/1316)
- fix: fix unresponsive (fix #1325) [`#1325`](https://github.com/th-ch/youtube-music/issues/1325)
- fix(blocker): remove the `app.isPackaged` check (fix #1315) [`#1315`](https://github.com/th-ch/youtube-music/issues/1315)
- fix(discord): `Discord RPC fails if a song's title is only one character` (fix #1314) [`#1314`](https://github.com/th-ch/youtube-music/issues/1314)
- chore(deps): Bump @rollup/plugin-commonjs, pnpm version, Remove ytpl [`9705f84`](https://github.com/th-ch/youtube-music/commit/9705f8489d7bf262bfd8b15ab84c2d3485f10eae)
- chore(deps): Bump rollup, @xhayper/discord-rpc version [`00a3e8d`](https://github.com/th-ch/youtube-music/commit/00a3e8d35ec335e1913be19f30ae09dbe0b7acdd)
- chore(deps): update dependency rollup to v4.1.4 [`6774d54`](https://github.com/th-ch/youtube-music/commit/6774d54f5eca432edc2e11743d9d1b1c2fda9ac8)
#### [v2.1.1](https://github.com/th-ch/youtube-music/compare/v2.1.0...v2.1.1)
> 14 October 2023
- hotfix(downloader): can't get an album title (fix #1313) [`#1313`](https://github.com/th-ch/youtube-music/issues/1313)
- Update changelog for v2.1.0 [`92cab89`](https://github.com/th-ch/youtube-music/commit/92cab89d17175741e60e65ea61633e23ebdc1f45)
- Bump version to 2.1.1 [`3bb5bc2`](https://github.com/th-ch/youtube-music/commit/3bb5bc2ca1856f4e222ee1e01e865f1ab804fdba)
- Add "about" menu to show app version [`21c45fa`](https://github.com/th-ch/youtube-music/commit/21c45faf2043cf72a7c14d5cf6c8d848d0448528)
#### [v2.1.0](https://github.com/th-ch/youtube-music/compare/v2.0.4...v2.1.0)
> 14 October 2023
- feat(downloader): Added support for audio format auto-detection [`#1310`](https://github.com/th-ch/youtube-music/pull/1310)
- feat(in-app-menu): enable in-app-menu by default (in Windows) [`#1311`](https://github.com/th-ch/youtube-music/pull/1311)
- fix: winget publish [`#1307`](https://github.com/th-ch/youtube-music/pull/1307)
- hotfix(downloader): fix invalid query selector (fix #1308) [`#1308`](https://github.com/th-ch/youtube-music/issues/1308)
- chore(deps): bump dependencies [`3c6b3ae`](https://github.com/th-ch/youtube-music/commit/3c6b3aeff0aae32adb2f2ad9c091b0a9701d3c24)
- chore(actions): create winget-cla.yml [`37181a7`](https://github.com/th-ch/youtube-music/commit/37181a7b5e2aa5bed6a36298eac3a66aac2762b8)
- Update changelog for v2.0.4 [`e9398ad`](https://github.com/th-ch/youtube-music/commit/e9398adac34a8abb11801e32999a915a8be0ece6)
#### [v2.0.4](https://github.com/th-ch/youtube-music/compare/v2.0.3...v2.0.4)
> 12 October 2023
- hotfix(adblocker): fix `ipcRenderer.sendSync() with ...` [`#1301`](https://github.com/th-ch/youtube-music/pull/1301)
- fix(downloader): Korean filename is broken on non-macOS devices [`#1297`](https://github.com/th-ch/youtube-music/pull/1297)
- chore(deps): bump deps [`b6894dc`](https://github.com/th-ch/youtube-music/commit/b6894dca2974c63fa2945d3a4995665d11eb2a78)

View File

@ -1,287 +0,0 @@
import { blockers } from '../plugins/adblocker/blocker-types';
import { DefaultPresetList } from '../plugins/downloader/types';
export interface WindowSizeConfig {
width: number;
height: number;
}
export interface DefaultConfig {
'window-size': {
width: number;
height: number;
}
'window-maximized': boolean;
'window-position': {
x: number;
y: number;
}
url: string;
options: {
tray: boolean;
appVisible: boolean;
autoUpdates: boolean;
alwaysOnTop: boolean;
hideMenu: boolean;
hideMenuWarned: boolean;
startAtLogin: boolean;
disableHardwareAcceleration: boolean;
removeUpgradeButton: boolean;
restartOnConfigChanges: boolean;
trayClickPlayPause: boolean;
autoResetAppCache: boolean;
resumeOnStart: boolean;
likeButtons: string;
proxy: string;
startingPage: string;
overrideUserAgent: boolean;
themes: string[];
}
}
const defaultConfig = {
'window-size': {
width: 1100,
height: 550,
},
'window-maximized': false,
'window-position': {
x: -1,
y: -1,
},
'url': 'https://music.youtube.com',
'options': {
tray: false,
appVisible: true,
autoUpdates: true,
alwaysOnTop: false,
hideMenu: false,
hideMenuWarned: false,
startAtLogin: false,
disableHardwareAcceleration: false,
removeUpgradeButton: false,
restartOnConfigChanges: false,
trayClickPlayPause: false,
autoResetAppCache: false,
resumeOnStart: true,
likeButtons: '',
proxy: '',
startingPage: '',
overrideUserAgent: false,
themes: [] as string[],
},
/** please order alphabetically */
'plugins': {
'adblocker': {
enabled: true,
cache: true,
blocker: blockers.WithBlocklists as string,
additionalBlockLists: [], // Additional list of filters, e.g "https://raw.githubusercontent.com/uBlockOrigin/uAssets/master/filters/filters.txt"
disableDefaultLists: false,
},
'album-color-theme': {},
'ambient-mode': {},
'audio-compressor': {},
'blur-nav-bar': {},
'bypass-age-restrictions': {},
'captions-selector': {
enabled: false,
disableCaptions: false,
autoload: false,
lastCaptionsCode: '',
},
'compact-sidebar': {},
'crossfade': {
enabled: false,
fadeInDuration: 1500, // Ms
fadeOutDuration: 5000, // Ms
secondsBeforeEnd: 10, // S
fadeScaling: 'linear', // 'linear', 'logarithmic' or a positive number in dB
},
'disable-autoplay': {
applyOnce: false,
},
'discord': {
enabled: false,
autoReconnect: true, // If enabled, will try to reconnect to discord every 5 seconds after disconnecting or failing to connect
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
hideGitHubButton: false, // Disable the "View App On GitHub" button
hideDurationLeft: false, // Hides the start and end time of the song to rich presence
},
'downloader': {
enabled: false,
downloadFolder: undefined as string | undefined, // Custom download folder (absolute path)
selectedPreset: 'mp3 (256kbps)', // Selected preset
customPresetSetting: DefaultPresetList['mp3 (256kbps)'], // Presets
skipExisting: false,
playlistMaxItems: undefined as number | undefined,
},
'exponential-volume': {},
'in-app-menu': {
/**
* true in Windows, false in Linux and macOS (see youtube-music/config/store.ts)
*/
enabled: false,
},
'last-fm': {
enabled: false,
token: undefined as string | undefined, // Token used for authentication
session_key: undefined as string | undefined, // Session key used for scrobbling
api_root: 'http://ws.audioscrobbler.com/2.0/',
api_key: '04d76faaac8726e60988e14c105d421a', // Api key registered by @semvis123
secret: 'a5d2a36fdf64819290f6982481eaffa2',
},
'lumiastream': {},
'lyrics-genius': {
romanizedLyrics: false,
},
'navigation': {
enabled: true,
},
'no-google-login': {},
'notifications': {
enabled: false,
unpauseNotification: false,
urgency: 'normal', // Has effect only on Linux
// the following has effect only on Windows
interactive: true,
toastStyle: 1, // See plugins/notifications/utils for more info
refreshOnPlayPause: false,
trayControls: true,
hideButtonText: false,
},
'picture-in-picture': {
'enabled': false,
'alwaysOnTop': true,
'savePosition': true,
'saveSize': false,
'hotkey': 'P',
'pip-position': [10, 10],
'pip-size': [450, 275],
'isInPiP': false,
'useNativePiP': false,
},
'playback-speed': {},
'precise-volume': {
enabled: false,
steps: 1, // Percentage of volume to change
arrowsShortcut: true, // Enable ArrowUp + ArrowDown local shortcuts
globalShortcuts: {
volumeUp: '',
volumeDown: '',
},
savedVolume: undefined as number | undefined, // Plugin save volume between session here
},
'quality-changer': {},
'shortcuts': {
enabled: false,
overrideMediaKeys: false,
global: {
previous: '',
playPause: '',
next: '',
} as Record<string, string>,
local: {
previous: '',
playPause: '',
next: '',
} as Record<string, string>,
},
'skip-silences': {
onlySkipBeginning: false,
},
'sponsorblock': {
enabled: false,
apiURL: 'https://sponsor.ajay.app',
categories: [
'sponsor',
'intro',
'outro',
'interaction',
'selfpromo',
'music_offtopic',
],
},
'taskbar-mediacontrol': {},
'touchbar': {},
'tuna-obs': {},
'video-toggle': {
enabled: false,
hideVideo: false,
mode: 'custom',
forceHide: false,
align: '',
},
'visualizer': {
enabled: false,
type: 'butterchurn',
// Config per visualizer
butterchurn: {
preset: 'martin [shadow harlequins shape code] - fata morgana',
renderingFrequencyInMs: 500,
blendTimeInSeconds: 2.7,
},
vudio: {
effect: 'lighting',
accuracy: 128,
lighting: {
maxHeight: 160,
maxSize: 12,
lineWidth: 1,
color: '#49f3f7',
shadowBlur: 2,
shadowColor: 'rgba(244,244,244,.5)',
fadeSide: true,
prettify: false,
horizontalAlign: 'center',
verticalAlign: 'middle',
dottify: true,
},
},
wave: {
animations: [
{
type: 'Cubes',
config: {
bottom: true,
count: 30,
cubeHeight: 5,
fillColor: { gradient: ['#FAD961', '#F76B1C'] },
lineColor: 'rgba(0,0,0,0)',
radius: 20,
},
},
{
type: 'Cubes',
config: {
top: true,
count: 12,
cubeHeight: 5,
fillColor: { gradient: ['#FAD961', '#F76B1C'] },
lineColor: 'rgba(0,0,0,0)',
radius: 10,
},
},
{
type: 'Circles',
config: {
lineColor: {
gradient: ['#FAD961', '#FAD961', '#F76B1C'],
rotate: 90,
},
lineWidth: 4,
diameter: 20,
count: 10,
frequencyBand: 'base',
},
},
],
},
},
},
};
export default defaultConfig;

View File

@ -1,241 +0,0 @@
/* eslint-disable @typescript-eslint/require-await */
import { ipcMain, ipcRenderer } from 'electron';
import defaultConfig from './defaults';
import { getOptions, setMenuOptions, setOptions } from './plugins';
import { sendToFront } from '../providers/app-controls';
import { Entries } from '../utils/type-utils';
export type DefaultPluginsConfig = typeof defaultConfig.plugins;
export type OneOfDefaultConfigKey = keyof DefaultPluginsConfig;
export type OneOfDefaultConfig = typeof defaultConfig.plugins[OneOfDefaultConfigKey];
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const activePlugins: { [key in OneOfDefaultConfigKey]?: PluginConfig<any> } = {};
/**
* [!IMPORTANT!]
* The method is **sync** in the main process and **async** in the renderer process.
*/
export const getActivePlugins
= process.type === 'renderer'
? async () => ipcRenderer.invoke('get-active-plugins')
: () => activePlugins;
if (process.type === 'browser') {
ipcMain.handle('get-active-plugins', getActivePlugins);
}
/**
* [!IMPORTANT!]
* The method is **sync** in the main process and **async** in the renderer process.
*/
export const isActive
= process.type === 'renderer'
? async (plugin: string) =>
plugin in (await ipcRenderer.invoke('get-active-plugins'))
: (plugin: string): boolean => plugin in activePlugins;
interface PluginConfigOptions {
enableFront: boolean;
initialOptions?: OneOfDefaultConfig;
}
/**
* This class is used to create a dynamic synced config for plugins.
*
* [!IMPORTANT!]
* The methods are **sync** in the main process and **async** in the renderer process.
*
* @param {string} name - The name of the plugin.
* @param {boolean} [options.enableFront] - Whether the config should be available in front.js. Default: false.
* @param {object} [options.initialOptions] - The initial options for the plugin. Default: loaded from store.
*
* @example
* const { PluginConfig } = require("../../config/dynamic");
* const config = new PluginConfig("plugin-name", { enableFront: true });
* module.exports = { ...config };
*
* // or
*
* module.exports = (win, options) => {
* const config = new PluginConfig("plugin-name", {
* enableFront: true,
* initialOptions: options,
* });
* setupMyPlugin(win, config);
* };
*/
export type ConfigType<T extends OneOfDefaultConfigKey> = typeof defaultConfig.plugins[T];
type ValueOf<T> = T[keyof T];
type Mode<T, Mode extends 'r' | 'm'> = Mode extends 'r' ? Promise<T> : T;
export class PluginConfig<T extends OneOfDefaultConfigKey> {
private readonly name: string;
private readonly config: ConfigType<T>;
private readonly defaultConfig: ConfigType<T>;
private readonly enableFront: boolean;
private subscribers: { [key in keyof ConfigType<T>]?: (config: ConfigType<T>) => void } = {};
private allSubscribers: ((config: ConfigType<T>) => void)[] = [];
constructor(
name: T,
options: PluginConfigOptions = {
enableFront: false,
},
) {
const pluginDefaultConfig = defaultConfig.plugins[name] ?? {};
const pluginConfig = options.initialOptions || getOptions(name) || {};
this.name = name;
this.enableFront = options.enableFront;
this.defaultConfig = pluginDefaultConfig;
this.config = { ...pluginDefaultConfig, ...pluginConfig };
if (this.enableFront) {
this.setupFront();
}
activePlugins[name] = this;
}
get<Key extends keyof ConfigType<T> = keyof ConfigType<T>>(key: Key): ConfigType<T>[Key] {
return this.config?.[key];
}
set(key: keyof ConfigType<T>, value: ValueOf<ConfigType<T>>) {
this.config[key] = value;
this.onChange(key);
this.save();
}
getAll(): ConfigType<T> {
return { ...this.config };
}
setAll(options: Partial<ConfigType<T>>) {
if (!options || typeof options !== 'object') {
throw new Error('Options must be an object.');
}
let changed = false;
for (const [key, value] of Object.entries(options) as Entries<typeof options>) {
if (this.config[key] !== value) {
if (value !== undefined) this.config[key] = value;
this.onChange(key, false);
changed = true;
}
}
if (changed) {
for (const fn of this.allSubscribers) {
fn(this.config);
}
}
this.save();
}
getDefaultConfig() {
return this.defaultConfig;
}
/**
* Use this method to set an option and restart the app if `appConfig.restartOnConfigChange === true`
*
* Used for options that require a restart to take effect.
*/
setAndMaybeRestart(key: keyof ConfigType<T>, value: ValueOf<ConfigType<T>>) {
this.config[key] = value;
setMenuOptions(this.name, this.config);
this.onChange(key);
}
subscribe(valueName: keyof ConfigType<T>, fn: (config: ConfigType<T>) => void) {
this.subscribers[valueName] = fn;
}
subscribeAll(fn: (config: ConfigType<T>) => void) {
this.allSubscribers.push(fn);
}
/** Called only from back */
private save() {
setOptions(this.name, this.config);
}
private onChange(valueName: keyof ConfigType<T>, single: boolean = true) {
this.subscribers[valueName]?.(this.config[valueName] as ConfigType<T>);
if (single) {
for (const fn of this.allSubscribers) {
fn(this.config);
}
}
}
private setupFront() {
const ignoredMethods = ['subscribe', 'subscribeAll'];
if (process.type === 'renderer') {
for (const [fnName, fn] of Object.entries(this) as Entries<this>) {
if (typeof fn !== 'function' || fn.name in ignoredMethods) {
return;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any,@typescript-eslint/no-unsafe-return
this[fnName] = (async (...args: any) => await ipcRenderer.invoke(
`${this.name}-config-${String(fnName)}`,
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
...args,
)) as typeof this[keyof this];
this.subscribe = (valueName, fn: (config: ConfigType<T>) => void) => {
if (valueName in this.subscribers) {
console.error(`Already subscribed to ${String(valueName)}`);
}
this.subscribers[valueName] = fn;
ipcRenderer.on(
`${this.name}-config-changed-${String(valueName)}`,
(_, value: ConfigType<T>) => {
fn(value);
},
);
ipcRenderer.send(`${this.name}-config-subscribe`, valueName);
};
this.subscribeAll = (fn: (config: ConfigType<T>) => void) => {
ipcRenderer.on(`${this.name}-config-changed`, (_, value: ConfigType<T>) => {
fn(value);
});
ipcRenderer.send(`${this.name}-config-subscribe-all`);
};
}
} else if (process.type === 'browser') {
for (const [fnName, fn] of Object.entries(this) as Entries<this>) {
if (typeof fn !== 'function' || fn.name in ignoredMethods) {
return;
}
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument,@typescript-eslint/no-unsafe-return
ipcMain.handle(`${this.name}-config-${String(fnName)}`, (_, ...args) => fn(...args));
}
ipcMain.on(`${this.name}-config-subscribe`, (_, valueName: keyof ConfigType<T>) => {
this.subscribe(valueName, (value) => {
sendToFront(`${this.name}-config-changed-${String(valueName)}`, value);
});
});
ipcMain.on(`${this.name}-config-subscribe-all`, () => {
this.subscribeAll((value) => {
sendToFront(`${this.name}-config-changed`, value);
});
});
}
}
}

View File

@ -1,53 +0,0 @@
import Store from 'electron-store';
import defaultConfig from './defaults';
import plugins from './plugins';
import store from './store';
import { restart } from '../providers/app-controls';
const set = (key: string, value: unknown) => {
store.set(key, value);
};
function setMenuOption(key: string, value: unknown) {
set(key, value);
if (store.get('options.restartOnConfigChanges')) {
restart();
}
}
// MAGIC OF TYPESCRIPT
type Prev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...0[]]
type Join<K, P> = K extends string | number ?
P extends string | number ?
`${K}${'' extends P ? '' : '.'}${P}`
: never : never;
type Paths<T, D extends number = 10> = [D] extends [never] ? never : T extends object ?
{ [K in keyof T]-?: K extends string | number ?
`${K}` | Join<K, Paths<T[K], Prev[D]>>
: never
}[keyof T] : ''
type SplitKey<K> = K extends `${infer A}.${infer B}` ? [A, B] : [K, string];
type PathValue<T, K extends string> =
SplitKey<K> extends [infer A extends keyof T, infer B extends string]
? PathValue<T[A], B>
: T;
const get = <Key extends Paths<typeof defaultConfig>>(key: Key) => store.get(key) as PathValue<typeof defaultConfig, typeof key>;
export default {
defaultConfig,
get,
set,
setMenuOption,
edit: () => store.openInEditor(),
watch(cb: Parameters<Store['onDidChange']>[1]) {
store.onDidChange('options', cb);
store.onDidChange('plugins', cb);
},
plugins,
};

View File

@ -1,63 +0,0 @@
import store from './store';
import defaultConfig from './defaults';
import { restart } from '../providers/app-controls';
import { Entries } from '../utils/type-utils';
interface Plugin {
enabled: boolean;
}
type DefaultPluginsConfig = typeof defaultConfig.plugins;
export function getEnabled() {
const plugins = store.get('plugins') as DefaultPluginsConfig;
return (Object.entries(plugins) as Entries<DefaultPluginsConfig>).filter(([plugin]) =>
isEnabled(plugin),
);
}
export function isEnabled(plugin: string) {
const pluginConfig = (store.get('plugins') as Record<string, Plugin>)[plugin];
return pluginConfig !== undefined && pluginConfig.enabled;
}
export function setOptions<T>(plugin: string, options: T) {
const plugins = store.get('plugins') as Record<string, T>;
store.set('plugins', {
...plugins,
[plugin]: {
...plugins[plugin],
...options,
},
});
}
export function setMenuOptions<T>(plugin: string, options: T) {
setOptions(plugin, options);
if (store.get('options.restartOnConfigChanges')) {
restart();
}
}
export function getOptions<T>(plugin: string): T {
return (store.get('plugins') as Record<string, T>)[plugin];
}
export function enable(plugin: string) {
setMenuOptions(plugin, { enabled: true });
}
export function disable(plugin: string) {
setMenuOptions(plugin, { enabled: false });
}
export default {
isEnabled,
getEnabled,
enable,
disable,
setOptions,
setMenuOptions,
getOptions,
};

View File

@ -1,154 +0,0 @@
import Store from 'electron-store';
import Conf from 'conf';
import is from 'electron-is';
import defaults from './defaults';
import { DefaultPresetList, type Preset } from '../plugins/downloader/types';
const getDefaults = () => {
if (is.windows()) {
defaults.plugins['in-app-menu'].enabled = true;
}
return defaults;
};
const setDefaultPluginOptions = (store: Conf<Record<string, unknown>>, plugin: keyof typeof defaults.plugins) => {
if (!store.get(`plugins.${plugin}`)) {
store.set(`plugins.${plugin}`, defaults.plugins[plugin]);
}
};
const migrations = {
'>=2.1.0'(store: Conf<Record<string, unknown>>) {
const originalPreset = store.get('plugins.downloader.preset') as string | undefined;
if (originalPreset) {
if (originalPreset !== 'opus') {
store.set('plugins.downloader.selectedPreset', 'Custom');
store.set('plugins.downloader.customPresetSetting', {
extension: 'mp3',
ffmpegArgs: store.get('plugins.downloader.ffmpegArgs') as string[] ?? DefaultPresetList['mp3 (256kbps)'].ffmpegArgs,
} satisfies Preset);
} else {
store.set('plugins.downloader.selectedPreset', 'Source');
store.set('plugins.downloader.customPresetSetting', {
extension: null,
ffmpegArgs: store.get('plugins.downloader.ffmpegArgs') as string[] ?? [],
} satisfies Preset);
}
store.delete('plugins.downloader.preset');
store.delete('plugins.downloader.ffmpegArgs');
}
},
'>=1.20.0'(store: Conf<Record<string, unknown>>) {
setDefaultPluginOptions(store, 'visualizer');
if (store.get('plugins.notifications.toastStyle') === undefined) {
const pluginOptions = store.get('plugins.notifications') || {};
store.set('plugins.notifications', {
...defaults.plugins.notifications,
...pluginOptions,
});
}
if (store.get('options.ForceShowLikeButtons')) {
store.delete('options.ForceShowLikeButtons');
store.set('options.likeButtons', 'force');
}
},
'>=1.17.0'(store: Conf<Record<string, unknown>>) {
setDefaultPluginOptions(store, 'picture-in-picture');
if (store.get('plugins.video-toggle.mode') === undefined) {
store.set('plugins.video-toggle.mode', 'custom');
}
},
'>=1.14.0'(store: Conf<Record<string, unknown>>) {
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: Conf<Record<string, unknown>>) {
if (store.get('plugins.discord.listenAlong') === undefined) {
store.set('plugins.discord.listenAlong', true);
}
},
'>=1.12.0'(store: Conf<Record<string, unknown>>) {
const options = store.get('plugins.shortcuts') as Record<string, {
action: string;
shortcut: unknown;
}[] | Record<string, unknown>>;
let updated = false;
for (const optionType of ['global', 'local']) {
if (Array.isArray(options[optionType])) {
const optionsArray = options[optionType] as {
action: string;
shortcut: unknown;
}[];
const updatedOptions: Record<string, unknown> = {};
for (const optionObject of optionsArray) {
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: Conf<Record<string, unknown>>) {
if (store.get('options.resumeOnStart') === undefined) {
store.set('options.resumeOnStart', true);
}
},
'>=1.7.0'(store: Conf<Record<string, unknown>>) {
const enabledPlugins = store.get('plugins') as string[];
if (!Array.isArray(enabledPlugins)) {
console.warn('Plugins are not in array format, cannot migrate');
return;
}
// Include custom options
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const plugins: Record<string, any> = {
adblocker: {
enabled: true,
cache: true,
additionalBlockLists: [],
},
downloader: {
enabled: false,
ffmpegArgs: [], // E.g. ["-b:a", "192k"] for an audio bitrate of 192kb/s
downloadFolder: undefined, // Custom download folder (absolute path)
},
};
for (const enabledPlugin of enabledPlugins) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
plugins[enabledPlugin] = {
...plugins[enabledPlugin],
enabled: true,
};
}
store.set('plugins', plugins);
},
};
export default new Store({
defaults: getDefaults(),
clearInvalidConfig: false,
migrations,
});

View File

@ -478,7 +478,7 @@
</a>
</li>
</ul>
<div class="footer-copyright">© 2021 th-ch</div>
<div class="footer-copyright">© 2024 th-ch</div>
</div>
</div>
</div>

390
docs/readme/README-es.md Normal file
View File

@ -0,0 +1,390 @@
<div align="center">
# YouTube Music
[![GitHub release](https://img.shields.io/github/release/th-ch/youtube-music.svg?style=for-the-badge&logo=youtube-music)](https://github.com/th-ch/youtube-music/releases/)
[![GitHub license](https://img.shields.io/github/license/th-ch/youtube-music.svg?style=for-the-badge)](https://github.com/th-ch/youtube-music/blob/master/LICENSE)
[![eslint code style](https://img.shields.io/badge/code_style-eslint-5ed9c7.svg?style=for-the-badge)](https://github.com/th-ch/youtube-music/blob/master/.eslintrc.js)
[![Build status](https://img.shields.io/github/actions/workflow/status/th-ch/youtube-music/build.yml?branch=master&style=for-the-badge&logo=youtube-music)](https://GitHub.com/th-ch/youtube-music/releases/)
[![GitHub All Releases](https://img.shields.io/github/downloads/th-ch/youtube-music/total?style=for-the-badge&logo=youtube-music)](https://GitHub.com/th-ch/youtube-music/releases/)
[![AUR](https://img.shields.io/aur/version/youtube-music-bin?color=blueviolet&style=for-the-badge&logo=youtube-music)](https://aur.archlinux.org/packages/youtube-music-bin)
[![Known Vulnerabilities](https://snyk.io/test/github/th-ch/youtube-music/badge.svg)](https://snyk.io/test/github/th-ch/youtube-music)
</div>
![Screenshot](/web/screenshot.jpg "Screenshot")
<div align="center">
<a href="https://github.com/th-ch/youtube-music/releases/latest">
<img src="/web/youtube-music.svg" width="400" height="100" alt="YouTube Music SVG">
</a>
</div>
**Electron wrapper de YouTube Music con las siguientes características:**
- Apariencia y sensación nativa, tiene como objetivo mantener la interfaz original
- Framework para plugins personalizados: cambia YouTube Music según tus necesidades (estilo, contenido, funciones), habilita/deshabilita plugins con un solo clic
## Imagen de demostración
| Pantalla del reproductor (color del álbum como tema y luz ambiental) |
|:---------------------------------------------------------------------------------------------------------:|
|![Screenshot1](https://github.com/th-ch/youtube-music/assets/16558115/53efdf73-b8fa-4d7b-a235-b96b91ea77fc)|
## Contenido
- [Características](#características)
- [Plugins disponibles](#plugins-disponibles)
- [Traducción](#traducción)
- [Descarga](#descarga)
- [Arch Linux](#arch-linux)
- [macOS](#macos)
- [Windows](#windows)
- [Cómo instalar sin conexión a internet? (en Windows)](#cómo-instalar-sin-conexión-a-internet-en-windows)
- [Temas](#temas)
- [Dev](#dev)
- [Crea tus propios plugins](#crea-tus-propios-plugins)
- [Creación de un plugin](#creación-de-un-plugin)
- [Casos de uso comunes](#casos-de-uso-comunes)
- [Compilar](#compilar)
- [Vista previa de producción](#vista-previa-de-producción)
- [Tests](#tests)
- [Licencia](#licencia)
- [Preguntas frecuentes](#preguntas-frecuentes)
## Características:
- **Confirmación automática al pausar** (Siempre habilitado): desactiva
el mensaje emergente ["¿Continuar reproduciendo?"](https://user-images.githubusercontent.com/61631665/129977894-01c60740-7ec6-4bf0-9a2c-25da24491b0e.png)
que pausa la música después de cierto tiempo
- Y más ...
## Plugins disponibles:
- **Bloqueador de Anuncios**: Bloquea todos los anuncios y rastreadores de forma predeterminada
- **Acciones de Álbum**: Agrega botones de deshacer No me gusta, No me gusta, Me gusta, y Deshacer me gusta a todas las canciones de una lista de reproducción o álbum
- **Tema de Color del Álbum**: Aplica un tema dinámico y efectos visuales basados en la paleta de colores del álbum
- **Modo Ambiente**: Aplica un efecto de iluminación proyectando colores suaves del video en el fondo de tu pantalla
- **Compresor de Audio**: Aplica compresión al audio (reduce el volumen de las partes más fuertes de la señal y aumenta el
volumen de las partes más suaves)
- **Barra de Navegación Difuminada**: hace que la barra de navegación sea transparente y borrosa
- **Omitir Restricciones de Edades**: omite la verificación de edad de YouTube
- **Selector de Subtítulos**: Habilita los subtítulos
- **Barra Lateral Compacta**: Siempre muestra la barra lateral en modo compacto
- **Crossfade**: Transición suave entre canciones
- **Desactivar Reproducción Automática**: Hace que cada canción comience en modo "pausado"
- **[Discord](https://discord.com/) Rich Presence**: Muestra a tus amigos lo que estás escuchando
con [Rich Presence](https://user-images.githubusercontent.com/28219076/104362104-a7a0b980-5513-11eb-9744-bb89eabe0016.png)
- **Descargador**: Descarga
MP3 [directamente desde la interfaz](https://user-images.githubusercontent.com/61631665/129977677-83a7d067-c192-45e1-98ae-b5a4927393be.png) [(youtube-dl)](https://github.com/ytdl-org/youtube-dl)
- **Volumen Exponencial**: Hace que el control de volumen
sea [exponencial](https://greasyfork.org/en/scripts/397686-youtube-music-fix-volume-ratio/) para facilitar la
selección de volúmenes más bajos
- **Menú en la Aplicación**: [da a las barras un aspecto elegante y oscuro](https://user-images.githubusercontent.com/78568641/112215894-923dbf00-8c29-11eb-95c3-3ce15db27eca.png)
> (consulta [esta publicación](https://github.com/th-ch/youtube-music/issues/410#issuecomment-952060709) si tienes problemas
para acceder al menú después de habilitar este plugin y la opción hide-menu)
- **Scrobbler**: Agrega soporte para scrobbling en [Last.fm](https://www.last.fm/) y [ListenBrainz](https://listenbrainz.org/)
- **Lumia Stream**: Agrega soporte para [Lumia Stream](https://lumiastream.com/)
- **Letras Genius**: Agrega soporte de letras para la mayoría de las canciones
- **Music Together**: Comparte una lista de reproducción con otros. Cuando el anfitrión reproduce una canción, todos los demás escucharán la misma canción
- **Navegación**: Flechas de siguiente/anterior integradas directamente en la interfaz, como en tu navegador favorito
- **Sin Inicio de Sesión de Google**: Elimina los botones y enlaces de inicio de sesión de Google de la interfaz
- **Notificaciones**: Muestra una notificación cuando comienza una canción
a reproducirse ([notificaciones interactivas](https://user-images.githubusercontent.com/78568641/114102651-63ce0e00-98d0-11eb-9dfe-c5a02bb54f9c.png)
están disponibles en Windows)
- **Picture-in-picture**: permite cambiar la aplicación al modo picture-in-picture
- **Velocidad de Reproducción**: Escucha rápido, escucha
lento! [Agrega un deslizador que controla la velocidad de reproducción de las canciones](https://user-images.githubusercontent.com/61631665/129976003-e55db5ba-bf42-448c-a059-26a009775e68.png)
- **Volumen Preciso**: Controla el volumen de forma precisa utilizando la rueda del mouse/atajos de teclado, con un HUD personalizado y pasos de volumen personalizables
- **Atajos (& MPRIS)**: Permite configurar atajos globales para la reproducción (reproducir/pausar/siguiente/anterior) +
desactivar [osd multimedia](https://user-images.githubusercontent.com/84923831/128601225-afa38c1f-dea8-4209-9f72-0f84c1dd8b54.png)
al anular las teclas multimedia + habilitar Ctrl/CMD + F para buscar + habilitar el soporte mpris de Linux para
teclas multimedia + [atajos personalizados](https://github.com/Araxeus/youtube-music/blob/1e591d6a3df98449bcda6e63baab249b28026148/providers/song-controls.js#L13-L50)
para [usuarios avanzados](https://github.com/th-ch/youtube-music/issues/106#issuecomment-952156902)
- **Saltar Canción no Gustada**: Salta las canciones que no te gustan
- **Saltar Silencios**: Salta automáticamente las secciones de silencio
- [**SponsorBlock**](https://github.com/ajayyy/SponsorBlock): Salta automáticamente las partes que no son de música, como la introducción/final o
partes de videos musicales donde no se reproduce la canción
- **Control Multimedia en la Barra de Tareas**: Controla la reproducción desde
la [barra de tareas de Windows](https://user-images.githubusercontent.com/78568641/111916130-24a35e80-8a82-11eb-80c8-5021c1aa27f4.png)
- **TouchBar**: Diseño personalizado de TouchBar para macOS
- **Tuna OBS**: Integración con el complemento [Tuna](https://obsproject.com/forum/resources/tuna.843/) de [OBS](https://obsproject.com/)
- **Cambiador de Calidad de Video**: Permite cambiar la calidad del video con
un [botón](https://user-images.githubusercontent.com/78568641/138574366-70324a5e-2d64-4f6a-acdd-dc2a2b9cecc5.png) en
la superposición de video
- **Alternar Video**: Agrega
un [botón](https://user-images.githubusercontent.com/28893833/173663950-63e6610e-a532-49b7-9afa-54cb57ddfc15.png) para
alternar entre el modo de video/canción. también puede eliminar opcionalmente toda la pestaña de video
- **Visualizador**: Diferentes visualizadores de música
## Traducción
Puedes ayudar con la traducción en [Hosted Weblate](https://hosted.weblate.org/projects/youtube-music/).
<a href="https://hosted.weblate.org/engage/youtube-music/">
<img src="https://hosted.weblate.org/widget/youtube-music/i18n/multi-auto.svg" alt="estado de traducción" />
<img src="https://hosted.weblate.org/widget/youtube-music/i18n/287x66-black.png" alt="estado de traducción 2" />
</a>
## Descarga
Puedes consultar la [última versión](https://github.com/th-ch/youtube-music/releases/latest) para encontrar rápidamente la versión más reciente.
### Arch Linux
Instala el paquete [`youtube-music-bin`](https://aur.archlinux.org/packages/youtube-music-bin) desde AUR. Para obtener instrucciones de instalación de AUR, consulta esta [página del wiki](https://wiki.archlinux.org/index.php/Arch_User_Repository#Installing_packages).
### macOS
Puedes instalar la aplicación usando Homebrew (consulta la [definición de cask](https://github.com/th-ch/homebrew-youtube-music)):
```bash
brew install th-ch/youtube-music/youtube-music
```
Si instalas la aplicación manualmente y obtienes un error "está dañado y no se puede abrir" al iniciar la aplicación, ejecuta lo siguiente en la Terminal:
```bash
xattr -cr /Applications/YouTube\ Music.app
```
### Windows
Puedes usar el [administrador de paquetes Scoop](https://scoop.sh) para instalar el paquete `youtube-music` desde
el [`extras` bucket](https://github.com/ScoopInstaller/Extras).
```bash
scoop bucket add extras
scoop install extras/youtube-music
```
Alternativamente, puedes usar [Winget](https://learn.microsoft.com/en-us/windows/package-manager/winget/), el administrador de paquetes CLI oficial de Windows 11 para instalar el paquete `th-ch.YouTubeMusic`.
*Nota: Microsoft Defender SmartScreen podría bloquear la instalación ya que proviene de un "editor desconocido". Esto también esválido para la instalación manual al intentar ejecutar el ejecutable (.exe) después de una descarga manual aquí en GitHub (mismo archivo).*
```bash
winget install th-ch.YouTubeMusic
```
#### Cómo instalar sin conexión a Internet? (en Windows)
- Descarga el archivo `*.nsis.7z` para _la arquitectura de tu dispositivo_ en la [página de lanzamientos](https://github.com/th-ch/youtube-music/releases/latest).
- `x64` para Windows de 64 bits
- `ia32` para Windows de 32 bits
- `arm64` para Windows ARM64
- Descarga el instalador en la página de lanzamientos. (`*-Setup.exe`)
- Colócalos en el **mismo directorio**.
- Ejecuta el instalador.
## Temas
Puedes cargar archivos CSS para cambiar la apariencia de la aplicación (Opciones > Ajustes visuales > Tema).
Algunos temas predefinidos están disponibles en https://github.com/kerichdev/themes-for-ytmdesktop-player.
## Dev
```bash
git clone https://github.com/th-ch/youtube-music
cd youtube-music
pnpm install --frozen-lockfile
pnpm dev
```
## Crea tus propios plugins
Usando plugins, puedes:
- manipular la aplicación - se pasa el `BrowserWindow` de electron al controlador del plugin
- cambiar la interfaz manipulando el HTML/CSS
### Creación de un plugin
Crea una carpeta en `src/plugins/NOMBRE-DEL-PLUGIN`:
- `index.ts`: el archivo principal del plugin
```typescript
import style from './style.css?inline'; // importar estilo como inline
import { createPlugin } from '@/utils';
export default createPlugin({
name: "Plugin Label",
restartNeeded: true, // si el valor es true, ytmusic muestra el diálogo de reinicio
config: {
enabled: false,
}, // tu configuración personalizada
stylesheets: [style], // tu estilo personalizado,
menu: async ({ getConfig, setConfig }) => {
// Todos los métodos *Config están envueltos en Promise<T>
const config = await getConfig();
return [
{
label: "menu",
submenu: [1, 2, 3].map((value) => ({
label: `value ${value}`,
type: "radio",
checked: config.value === value,
click() {
setConfig({ value });
},
})),
},
];
},
backend: {
start({ window, ipc }) {
window.maximize();
// puedes comunicarte con el plugin de renderizado
ipc.handle("some-event", () => {
return "hello";
});
},
// se activa cuando cambia la configuración
onConfigChange(newConfig) { /* ... */ },
// se activa cuando se desactiva el plugin
stop(context) { /* ... */ },
},
renderer: {
async start(context) {
console.log(await context.ipc.invoke("some-event"));
},
// Solo disponible en el plugin de renderizado
onPlayerApiReady(api: YoutubePlayer, context: RendererContext) {
// establecer la configuración del plugin fácilmente
context.setConfig({ myConfig: api.getVolume() });
},
onConfigChange(newConfig) { /* ... */ },
stop(_context) { /* ... */ },
},
preload: {
async start({ getConfig }) {
const config = await getConfig();
},
onConfigChange(newConfig) {},
stop(_context) {},
},
});
```
### Casos de uso comunes
- inyectar CSS personalizado: crea un archivo `style.css` en la misma carpeta y luego:
```typescript
// index.ts
import style from './style.css?inline'; // importar estilo como inline
import { createPlugin } from '@/utils';
export default createPlugin({
name: 'Plugin Label',
restartNeeded: true, // si el valor es true, ytmusic mostrará el diálogo de reinicio
config: {
enabled: false,
}, // tu configuración personalizada
stylesheets: [style], // tu estilo personalizado
renderer() {} // define el hook del renderizador
});
```
- Si quieres cambiar el HTML:
```typescript
import { createPlugin } from '@/utils';
export default createPlugin({
name: 'Plugin Label',
restartNeeded: true, // si el valor es true, ytmusic mostrará el diálogo de reinicio
config: {
enabled: false,
}, // tu configuración personalizada
renderer() {
// Elimina el botón de inicio de sesión
document.querySelector(".sign-in-link.ytmusic-nav-bar").remove();
} // define el hook del renderizador
});
```
- comunicación entre el front y el back: se puede hacer utilizando el módulo ipcMain de electron. Ver archivo `index.ts` y
ejemplo en el plugin `sponsorblock`.
## Compilar
1. Clonar el repositorio
2. Seguir [esta guía](https://pnpm.io/es/installation) para instalar `pnpm`
3. Ejecutar `pnpm install --frozen-lockfile` para instalar las dependencias
4. Ejecutar `pnpm build:OS`
- `pnpm dist:win` - Windows
- `pnpm dist:linux` - Linux (amd64)
- `pnpm dist:linux:deb-arm64` - Linux (arm64 para Debian)
- `pnpm dist:linux:rpm-arm64` - Linux (arm64 para Fedora)
- `pnpm dist:mac` - macOS (amd64)
- `pnpm dist:mac:arm64` - macOS (arm64)
Construye la aplicación para macOS, Linux y Windows,
utilizando [electron-builder](https://github.com/electron-userland/electron-builder).
## Vista previa de producción
```bash
pnpm start
```
## Tests
```bash
pnpm test
```
Utiliza [Playwright](https://playwright.dev/) para probar la aplicación.
## Licencia
MIT © [th-ch](https://github.com/th-ch/youtube-music)
## Preguntas frecuentes
### ¿Por qué no se muestra el menú de aplicaciones?
Si la opción `Ocultar menú` está activada - puedes mostrar el menú con la tecla <kbd>alt</kbd> (o <kbd>\`</kbd> [acento grave] si estás utilizando el plugin in-app-menu)

388
docs/readme/README-fr.md Normal file
View File

@ -0,0 +1,388 @@
<div align="center">
# YouTube Music
[![GitHub release](https://img.shields.io/github/release/th-ch/youtube-music.svg?style=for-the-badge&logo=youtube-music)](https://github.com/th-ch/youtube-music/releases/)
[![Licence GitHub](https://img.shields.io/github/license/th-ch/youtube-music.svg?style=for-the-badge)](https://github.com/th-ch/youtube-music/blob/master/LICENSE)
[![style de code eslint](https://img.shields.io/badge/style_de_code-eslint-5ed9c7.svg?style=for-the-badge)](https://github.com/th-ch/youtube-music/blob/master/.eslintrc.js)
[![Statut de la construction](https://img.shields.io/github/actions/workflow/status/th-ch/youtube-music/build.yml?branch=master&style=for-the-badge&logo=youtube-music)](https://GitHub.com/th-ch/youtube-music/releases/)
[![Toutes les versions GitHub](https://img.shields.io/github/downloads/th-ch/youtube-music/total?style=for-the-badge&logo=youtube-music)](https://GitHub.com/th-ch/youtube-music/releases/)
[![AUR](https://img.shields.io/aur/version/youtube-music-bin?color=blueviolet&style=for-the-badge&logo=youtube-music)](https://aur.archlinux.org/packages/youtube-music-bin)
[![Vulnérabilités connues](https://snyk.io/test/github/th-ch/youtube-music/badge.svg)](https://snyk.io/test/github/th-ch/youtube-music)
</div>
![Capture d'écran](https://github.com/th-ch/youtube-music/raw/master/web/screenshot.jpg "Capture d'écran")
<div align="center">
<a href="https://github.com/th-ch/youtube-music/releases/latest">
<img src="https://github.com/th-ch/youtube-music/raw/master/web/youtube-music.svg" width="400" height="100" alt="SVG YouTube Music">
</a>
</div>
**Enveloppe Electron autour de YouTube Music offrant :**
- Aspect & sensation naturels, vise à conserver l'interface originale
- Cadre pour les plugins personnalisés : modifiez YouTube Music selon vos besoins (style, contenu, fonctionnalités), activez/désactivez les plugins en
un clic
## Image de démonstration
| Écran du lecteur (thème de couleur de l'album & lumière ambiante) |
|:---------------------------------------------------------------------------------------------------------:|
|![Capture d'écran1](https://github.com/th-ch/youtube-music/assets/16558115/53efdf73-b8fa-4d7b-a235-b96b91ea77fc)|
## Contenu
- [Fonctionnalités](#fonctionnalités)
- [Plugins disponibles](#plugins-disponibles)
- [Traduction](#traduction)
- [Téléchargement](#téléchargement)
- [Arch Linux](#arch-linux)
- [MacOS](#macos)
- [Windows](#windows)
- [Comment installer sans connexion réseau ? (sous Windows)](#comment-installer-sans-connexion-réseau-sous-windows)
- [Thèmes](#thèmes)
- [Dev](#dev)
- [Créez vos propres plugins](#créez-vos-propres-plugins)
- [Créer un plugin](#créer-un-plugin)
- [Cas d'utilisation courants](#cas-dutilisation-courants)
- [Construction](#construction)
- [Aperçu de la production](#aperçu-de-la-production)
- [Tests](#tests)
- [Licence](#licence)
- [FAQ](#faq)
## Fonctionnalités :
- **Confirmation automatique lors de la pause** (Toujours activé) : désactiver
la pop-up ["Continuer à regarder ?"](https://user-images.githubusercontent.com/61631665/129977894-01c60740-7ec6-4bf0-9a2c-25da24491b0e.png)
qui pause la musique après un certain temps
- Et plus encore ...
## Plugins disponibles :
- **Bloqueur de publicités** : Bloquez toutes les publicités et le suivi dès le départ
- **Actions d'album** : Ajoute des boutons Je n'aime pas, Dislike, J'aime, et Unlike pour appliquer cela à toutes les chansons dans une playlist ou un album
- **Thème de couleur d'album** : Applique un thème dynamique et des effets visuels basés sur la palette de couleurs de l'album
- **Mode Ambiant** : Applique un effet d'éclairage en projetant des couleurs douces de la vidéo, sur l'arrière-plan de votre écran
- **Compresseur Audio** : Appliquer une compression audio (diminue le volume des parties les plus fortes du signal et augmente le
volume des parties les plus douces)
- **Barre de navigation floue** : rend la barre de navigation transparente et floue
- **Contournement des restrictions d'âge** : contourner la vérification d'âge de YouTube
- **Sélecteur de sous-titres** : Activer les sous-titres
- **Barre latérale compacte** : Toujours définir la barre latérale en mode compact
- **Fondu enchaîné** : Fondu enchaîné entre les chansons
- **Désactiver la lecture automatique** : Fait démarrer chaque chanson en mode "pause"
- **[Discord](https://discord.com/) Présence riche** : Montrez à vos amis ce que vous écoutez
avec [Présence riche](https://user-images.githubusercontent.com/28219076/104362104-a7a0b980-5513-11eb-9744-bb89eabe0016.png)
- **Téléchargeur** : télécharge des
MP3 [directement depuis l'interface](https://user-images.githubusercontent.com/61631665/129977677-83a7d067-c192-45e1-98ae-b5a4927393be.png) [(youtube-dl)](https://github.com/ytdl-org/youtube-dl)
- **Volume exponentiel** : Rend le curseur de volume
[exponentiel](https://greasyfork.org/en/scripts/397686-youtube-music-fix-volume-ratio/) afin qu'il soit plus facile de
sélectionner des volumes plus bas
- **Menu In-App** : [donne aux barres un aspect chic et sombre](https://user-images.githubusercontent.com/78568641/112215894-923dbf00-8c29-11eb-95c3-3ce15db27eca.png)
> (voir [ce poste](https://github.com/th-ch/youtube-music/issues/410#issuecomment-952060709) si vous avez des problèmes
pour accéder au menu après avoir activé ce plugin et l'option masquer-menu)
- **Scrobbler** : Ajoute le support de scrobbling pour [Last.fm](https://www.last.fm/) et [ListenBrainz](https://listenbrainz.org/)
- **Lumia Stream** : Ajoute le support de [Lumia Stream](https://lumiastream.com/)
- **Lyrics Genius** : Ajoute le support des paroles pour la plupart des chansons
- **Musique Ensemble** : Partagez une playlist avec d'autres. Lorsque l'hôte joue une chanson, tout le monde entendra la même chanson
- **Navigation** : Flèches de navigation Suivant/Retour directement intégrées dans l'interface, comme dans votre navigateur préféré
- **Pas de connexion Google** : Supprime les boutons et les liens de connexion Google de l'interface
- **Notifications** : Affiche une notification lorsqu'une chanson commence à jouer ([notifications interactives](https://user-images.githubusercontent.com/78568641/114102651-63ce0e00-98d0-11eb-9dfe-c5a02bb54f9c.png)
sont disponibles sur Windows)
- **Image dans l'image** : permet de passer l'application en mode image dans l'image
- **Vitesse de lecture** : Écoutez rapidement, écoutez lentement ! [Ajoute un curseur qui contrôle la vitesse des chansons](https://user-images.githubusercontent.com/61631665/129976003-e55db5ba-bf42-448c-a059-26a009775e68.png)
- **Volume précis** : Contrôlez le volume précisément en utilisant la molette de la souris/raccourcis clavier, avec un hud personnalisé et des étapes de volume personnalisables
- **Raccourcis (& MPRIS)** : Permet de définir des raccourcis globaux pour la lecture (lecture/pause/suivant/précédent) +
désactive [osd média](https://user-images.githubusercontent.com/84923831/128601225-afa38c1f-dea8-4209-9f72-0f84c1dd8b54.png)
en remplaçant les touches multimédias + activer Ctrl/CMD + F pour rechercher + activer le support mpris linux pour
les touches multimédias + [raccourcis personnalisés](https://github.com/Araxeus/youtube-music/blob/1e591d6a3df98449bcda6e63baab249b28026148/providers/song-controls.js#L13-L50)
pour [utilisateurs avancés](https://github.com/th-ch/youtube-music/issues/106#issuecomment-952156902)
- **Passer la chanson non aimée** : passe les chansons non aimées
- **Passer les silences** : passe automatiquement les sections silencieuses
- [**SponsorBlock**](https://github.com/ajayyy/SponsorBlock) : Saute automatiquement les parties non musicales comme les intros/outros ou
les parties des clips vidéo où la chanson n'est pas jouée
- **Contrôle multimédia de la barre des tâches** : Contrôlez la lecture depuis
votre [barre des tâches Windows](https://user-images.githubusercontent.com/78568641/111916130-24a35e80-8a82-11eb-80c8-5021c1aa27f4.png)
- **TouchBar** : Disposition personnalisée de la TouchBar pour macOS
- **Tuna OBS** : Intégration avec le
plugin [Tuna](https://obsproject.com/forum/resources/tuna.843/) d'[OBS](https://obsproject.com/)
- **Changeur de qualité vidéo** : Permet de changer la qualité vidéo avec
un [bouton](https://user-images.githubusercontent.com/78568641/138574366-70324a5e-2d64-4f6a-acdd-dc2a2b9cecc5.png) sur
l'overlay vidéo
- **Bascule vidéo** : Ajoute
un [bouton](https://user-images.githubusercontent.com/28893833/173663950-63e6610e-a532-49b7-9afa-54cb57ddfc15.png) pour
basculer entre le mode Vidéo/Chanson. peut également supprimer l'onglet vidéo entier
- **Visualiseur** : Différents visualiseurs musicaux
## Traduction
Vous pouvez aider à la traduction sur [Hosted Weblate](https://hosted.weblate.org/projects/youtube-music/).
<a href="https://hosted.weblate.org/engage/youtube-music/">
<img src="https://hosted.weblate.org/widget/youtube-music/i18n/multi-auto.svg" alt="statut de la traduction" />
<img src="https://hosted.weblate.org/widget/youtube-music/i18n/287x66-black.png" alt="statut de la traduction 2" />
</a>
## Téléchargement
Vous pouvez consulter la [dernière sortie](https://github.com/th-ch/youtube-music/releases/latest) pour trouver rapidement la
dernière version.
### Arch Linux
Installez le paquet [`youtube-music-bin`](https://aur.archlinux.org/packages/youtube-music-bin) depuis l'AUR. Pour les instructions d'installation de l'AUR, consultez
cette [page wiki](https://wiki.archlinux.org/index.php/Arch_User_Repository#Installing_packages).
### MacOS
Vous pouvez installer l'application en utilisant Homebrew (voir la [définition du fût](https://github.com/th-ch/homebrew-youtube-music)) :
```bash
brew install th-ch/youtube-music/youtube-music
```
Si vous installez l'application manuellement et obtenez une erreur "est endommagé et ne peut pas être ouvert." lors du lancement de l'application, exécutez ce qui suit dans le Terminal :
```bash
xattr -cr /Applications/YouTube\ Music.app
```
### Windows
Vous pouvez utiliser le [gestionnaire de paquets Scoop](https://scoop.sh) pour installer le paquet `youtube-music` depuis le [seau `extras`](https://github.com/ScoopInstaller/Extras).
```bash
scoop bucket add extras
scoop install extras/youtube-music
```
Alternativement, vous pouvez utiliser [Winget](https://learn.microsoft.com/fr-fr/windows/package-manager/winget/), le gestionnaire de paquets CLI officiel de Windows 11, pour installer le paquet `th-ch.YouTubeMusic`.
*Note : Microsoft Defender SmartScreen pourrait bloquer l'installation car elle provient d'un "éditeur inconnu". Ceci est également vrai pour l'installation manuelle lors de l'essai d'exécution de l'exécutable (.exe) après un téléchargement manuel ici sur GitHub (même fichier).*
```bash
winget install th-ch.YouTubeMusic
```
#### Comment installer sans connexion réseau ? (sous Windows)
- Téléchargez le fichier `*.nsis.7z` pour _l'architecture de votre appareil_ sur la [page des versions](https://github.com/th-ch/youtube-music/releases/latest).
- `x64` pour Windows 64 bits
- `ia32` pour Windows 32 bits
- `arm64` pour Windows ARM64
- Téléchargez l'installeur sur la page des versions. (`*-Setup.exe`)
- Placez-les dans le **même dossier**.
- Exécutez l'installeur.
## Thèmes
Vous pouvez charger des fichiers CSS pour changer l'apparence de l'application (Options > Ajustements visuels > Thèmes).
Certains thèmes prédéfinis sont disponibles sur [https://github.com/kerichdev/themes-for-ytmdesktop-player](https://github.com/kerichdev/themes-for-ytmdesktop-player).
## Dev
```bash
git clone https://github.com/th-ch/youtube-music
cd youtube-music
pnpm install --frozen-lockfile
pnpm dev
```
## Créez vos propres plugins
En utilisant des plugins, vous pouvez :
- manipuler l'application - la `BrowserWindow` d'Electron est passée au gestionnaire de plugin
- changer le front en manipulant le HTML/CSS
### Créer un plugin
Créez un dossier dans `src/plugins/NOM-DE-VOTRE-PLUGIN` :
- `index.ts` : le fichier principal du plugin
```typescript
import style from './style.css?inline'; // importez le style comme inline
import { createPlugin } from '@/utils';
export default createPlugin({
name: 'Étiquette du plugin',
restartNeeded: true, // si la valeur est vraie, ytmusic affichera la boîte de dialogue de redémarrage
config: {
enabled: false,
}, // votre configuration personnalisée
stylesheets: [style], // votre style personnalisé,
menu: async ({ getConfig, setConfig }) => {
// Toutes les méthodes *Config sont des promesses encapsulées <T>
const config = await getConfig();
return [
{
label: 'menu',
submenu: [1, 2, 3].map((value) => ({
label: `valeur ${value}`,
type: 'radio',
checked: config.value === value,
click() {
setConfig({ value });
},
})),
},
];
},
backend: {
start({ window, ipc }) {
window.maximize();
// vous pouvez communiquer avec le plugin du rendu
ipc.handle('un événement', () => {
return 'bonjour';
});
},
// il est déclenché lorsque la configuration change
onConfigChange(newConfig) { /* ... */ },
// il est déclenché lorsque le plugin est désactivé
stop(context) { /* ... */ },
},
renderer: {
async start(context) {
console.log(await context.ipc.invoke('un événement'));
},
// Seul le crochet disponible pour le rendu
onPlayerApiReady(api: YoutubePlayer, context: RendererContext) {
// définir facilement la configuration du plugin
context.setConfig({ myConfig: api.getVolume() });
},
onConfigChange(newConfig) { /* ... */ },
stop(_context) { /* ... */ },
},
preload: {
async start({ getConfig }) {
const config is obtained by `getConfig` method.
},
onConfigChange(newConfig) {},
stop(_context) {},
},
});
```
### Cas d'utilisation courants
- **Injection de CSS personnalisé** : créez un fichier `style.css` dans le même dossier puis :
```typescript
// index.ts
import style from './style.css?inline'; // importez le style comme en ligne
import { createPlugin } from '@/utils';
export default createPlugin({
name: 'Étiquette du plugin',
restartNeeded: true, // si la valeur est vraie, ytmusic affichera la boîte de dialogue de redémarrage
config: {
enabled: false,
}, // votre configuration personnalisée
stylesheets: [style], // votre style personnalisé
renderer() {} // définissez le crochet de rendu
});
```
- **Si vous voulez modifier le HTML** :
```typescript
import { createPlugin } from '@/utils';
export default createPlugin({
name: 'Étiquette du plugin',
restartNeeded: true, // si la valeur est vraie, ytmusic affichera la boîte de dialogue de redémarrage
config: {
enabled: false,
}, // votre configuration personnalisée
renderer() {
// Supprimez le bouton de connexion
document.querySelector(".sign-in-link.ytmusic-nav-bar").remove();
} // définissez le crochet de rendu
});
```
- **Communication entre le front et le back** : cela peut se faire en utilisant le module ipcMain d'Electron. Voir le fichier `index.ts` et l'exemple dans le plugin `sponsorblock`.
## Construction
1. Clonez le dépôt
2. Suivez [ce guide](https://pnpm.io/installation) pour installer `pnpm`
3. Exécutez `pnpm install --frozen-lockfile` pour installer les dépendances
4. Exécutez `pnpm build:OS`
- `pnpm dist:win` - pour Windows
- `pnpm dist:linux` - pour Linux
- `pnpm dist:mac` - pour MacOS
Construit l'application pour macOS, Linux et Windows,
en utilisant [electron-builder](https://github.com/electron-userland/electron-builder).
## Aperçu de la production
```bash
pnpm start
```
## Tests
```bash
pnpm test
```
Utilise [Playwright](https://playwright.dev/) pour tester l'application.
## Licence
MIT © [th-ch](https://github.com/th-ch/youtube-music)
## FAQ
### Pourquoi le menu de l'application ne s'affiche-t-il pas ?
Si l'option `Masquer le menu` est activée - vous pouvez afficher le menu avec la touche <kbd>alt</kbd> (ou <kbd>\`</kbd> [backtick] si vous utilisez le plugin du menu intégré)

388
docs/readme/README-is.md Normal file
View File

@ -0,0 +1,388 @@
<div align="center">
# YouTube Tónlist
[![GitHub release](https://img.shields.io/github/release/th-ch/youtube-music.svg?style=for-the-badge&logo=youtube-music)](https://github.com/th-ch/youtube-music/releases/)
[![GitHub license](https://img.shields.io/github/license/th-ch/youtube-music.svg?style=for-the-badge)](https://github.com/th-ch/youtube-music/blob/master/LICENSE)
[![eslint code style](https://img.shields.io/badge/code_style-eslint-5ed9c7.svg?style=for-the-badge)](https://github.com/th-ch/youtube-music/blob/master/.eslintrc.js)
[![Build status](https://img.shields.io/github/actions/workflow/status/th-ch/youtube-music/build.yml?branch=master&style=for-the-badge&logo=youtube-music)](https://GitHub.com/th-ch/youtube-music/releases/)
[![GitHub All Releases](https://img.shields.io/github/downloads/th-ch/youtube-music/total?style=for-the-badge&logo=youtube-music)](https://GitHub.com/th-ch/youtube-music/releases/)
[![AUR](https://img.shields.io/aur/version/youtube-music-bin?color=blueviolet&style=for-the-badge&logo=youtube-music)](https://aur.archlinux.org/packages/youtube-music-bin)
[![Known Vulnerabilities](https://snyk.io/test/github/th-ch/youtube-music/badge.svg)](https://snyk.io/test/github/th-ch/youtube-music)
</div>
![Screenshot](../../web/screenshot.jpg "Screenshot")
<div align="center">
<a href="https://github.com/th-ch/youtube-music/releases/latest">
<img src="../../web/youtube-music.svg" width="400" height="100" alt="YouTube Music SVG">
</a>
</div>
**Electron umbúðir utan um YouTube Tónlist sem inniheldur:**
- Innfæddur útlit og tilfinning, miðar að því að halda upprunalegu viðmótinu
- Rammi fyrir sérsniðnar tengiforrit: breyttu YouTube Tónlist að þínum þörfum (stíl, efni, eiginleikar), virkjaðu/slökktu á viðbætur í
einn smellur
## Sýnishornsmynd
| Spilaraskjár (albúmslitaþema & umhverfisljós) |
|:---------------------------------------------------------------------------------------------------------:|
|![Screenshot1](https://github.com/th-ch/youtube-music/assets/16558115/53efdf73-b8fa-4d7b-a235-b96b91ea77fc)|
## Efni
- [Eiginleikar](#eiginleikar)
- [Tiltæk tengiforrit](#tiltæk-tengiforrit)
- [Þýðing](#þýðing)
- [Sækja](#sækja)
- [Arch Linux](#arch-linux)
- [MacOS](#macos)
- [Windows](#windows)
- [Hvernig á að setja upp án nettengingar? (í Windows)](#hvernig-á-að-setja-upp-án-nettengingar-í-windows)
- [Þemu](#þemu)
- [Þróun](#þróun)
- [Búðu til þín eigin viðbætur](#búðu-til-þín-eigin-viðbætur)
- [Er að búa til viðbót](#er-að-búa-til-viðbót)
- [Algeng notkunartilvik](#algeng-notkunartilvik)
- [Byggja](#byggja)
- [Framleiðsluforskoðun](#framleiðsluforskoðun)
- [Prófanir](#prófanir)
- [Leyfi](#leyfi)
- [Algengustu spurningar](#algengustu-spurningar)
## Eiginleikar:
- **Sjálfvirk staðfesting þegar gert er hlé** (Alltaf virkt): slökkva á
["Halda áfram að horfa?"](https://user-images.githubusercontent.com/61631665/129977894-01c60740-7ec6-4bf0-9a2c-25da24491b0e.png)
popup sem gerir hlé á tónlist eftir ákveðinn tíma
- Og meira...
## Tiltæk tengiforrit:
- **Auglýsingablokkari**: Lokaðu fyrir allar auglýsingar og rakningar úr kassanum
- **Albúmsaðgerðir**: Bætir Ódíslika, Mislíkt, Líkt, og Ólíkt til að nota þetta á öll lög á spilunarlista eða albúm
- **Albúmslitaþema**: Beitir kraftmikið þema og sjónrænum áhrifum sem byggjast á litavali albúmsins
- **Umhverfishamur**: Beitir lýsingaráhrifum með því að varpa mildum litum úr myndbandinu í bakgrunn skjásins
- **Hljóðþjöppur**: Notaðu þjöppun á hljóð (lækkar hljóðstyrk háværustu hluta merkis og hækkar hljóðstyrk í mýkstu hlutunum)
- **Þoka Leiðsagnarstika**: Gerir leiðsögustikuna gagnsæja og óskýrt
- **Farið Framhjá Aldurstakmörkunum**: Framhjá aldursstaðfestingu YouTube
- **Yfirskriftarval**: Virkja skjátexta
- **Fyrirferðarlítillhliðarstika**: Stilltu hliðarstikuna alltaf í þétta stillingu
- **Krossfæra**: Krossfæra á milli lög
- **Slökkva á Sjálfvirkri Spilun**: Gerir lag að byrja í "hlé" ham
- **[Discord](https://discord.com/) Rík Nærveru**: Sýndu vinum þínum hvað þú hlustar á
með [Rík Nærveru](https://user-images.githubusercontent.com/28219076/104362104-a7a0b980-5513-11eb-9744-bb89eabe0016.png)
- **Niðurhalari**: Niðurhalum
MP3 [beint úr viðmótinu](https://user-images.githubusercontent.com/61631665/129977677-83a7d067-c192-45e1-98ae-b5a4927393be.png) [(youtube-dl)](https://github.com/ytdl-org/youtube-dl)
- **Veldibundiðrúmmál**: Gerir hljóðstyrkssleðann [veldisvísis](https://greasyfork.org/en/scripts/397686-youtube-music-fix-volume-ratio/)
svo það er auðveldara að velja lægra hljóðstyrk.
- **Valmynd í Forriti**: [Gefur börum flott, dökkt útlit](https://user-images.githubusercontent.com/78568641/112215894-923dbf00-8c29-11eb-95c3-3ce15db27eca.png)
> (sjá [þessa færslu](https://github.com/th-ch/youtube-music/issues/410#issuecomment-952060709) ef þú átt í vandræðum
með að fá aðgang að valmyndinni eftir að hafa virkjað þessa viðbót og fela valmyndarvalkostinn)
- **Scrobbler**: Bætir við scrobbling stuðningi fyrir [Last.fm](https://www.last.fm/) og [ListenBrainz](https://listenbrainz.org/)
- **Lumia Stream**: Bætir við [Lumia Stream](https://lumiastream.com/) stuðningi
- **Söngtexti Snilld**: Bætir stuðningi við texta fyrir flest lög
- **Tónlist Saman**: Deila spilunarlista með öðrum. Þegar gestgjafinn spilar lag munu allir aðrir heyra sama lagið
- **Leiðsögn**: Næsta/Til baka leiðsagnarörvar beint samþættar í viðmótinu, eins og í uppáhalds vafranum þínum
- **Engin Google Innskráning**: Fjarlægðu Google innskráningarhnappa og tengla úr viðmótinu
- **Tilkynningar**: Birta tilkynningu þegar lag byrjar að spila
([gagnvirkartilkynningar](https://user-images.githubusercontent.com/78568641/114102651-63ce0e00-98d0-11eb-9dfe-c5a02bb54f9c.png) eru fáanlegar á Windows)
- **Mynd-í-Mynd**: Gerir kleift að skipta forritinu yfir í mynd-í-mynd stillingu
- **Spilunarhraði**: Hlustaðu hratt, hlustaðu hægt!
[Bætir við sleða sem stjórnar lagahraðanum](https://user-images.githubusercontent.com/61631665/129976003-e55db5ba-bf42-448c-a059-26a009775e68.png)
- **Nákvæmshljóðstyrkur**: Stjórnaðu hljóðstyrknum nákvæmlega með músarhjóli/hraðtökkum, með sérsniðnum HUD og sérsniðnum hljóðstyrksþrepum
- **Flýtileiðir (og MPRIS)**: Leyfir að stilla alþjóðlegarflýtilyklar fyrir spilun (spila/gera hlé/næsta/fyrri) +
óvirkja [media osd](https://user-images.githubusercontent.com/84923831/128601225-afa38c1f-dea8-4209-9f72-0f84c1dd8b54.png)
með því að hnekkja miðlunarlyklum + virkja Ctrl/CMD + F til að leita + virkja linux mpris stuðning fyrir
miðlunarlyklar + [sérsniðnir flýtilyklar](https://github.com/Araxeus/youtube-music/blob/1e591d6a3df98449bcda6e63baab249b28026148/providers/song-controls.js#L13-L50)
fyrir [háþróaða notendur](https://github.com/th-ch/youtube-music/issues/106#issuecomment-952156902)
- **Slepptu Lögum sem Mislíkuðust**: Sleppir mislíkaði lög
- **Slepptu Þögnum**: Slepptu sjálfkrafa þagnarköflum í lögum
- [**Styrktarblokk**](https://github.com/ajayyy/SponsorBlock): Sleppur sjálfkrafa hlutum sem ekki eru tónlist, eins og inngangur/lok
eða hlutar af tónlistarmyndböndum þar sem lag er ekki að spila
- **Miðlunarstýringarverkefnastikunnar**: Stjórnaðu spilun frá [Windows verkefnastikunni þinni](https://user-images.githubusercontent.com/78568641/111916130-24a35e80-8a82-11eb-80c8-5021c1aa27f4.png)
- **Snertistiku**: Sérsniðið Snertistikuútlit fyrir macOS
- **Tuna OBS**: Samþætting við [OBS](https://obsproject.com/)
viðbótina [Tuna](https://obsproject.com/forum/resources/tuna.843/)
- **Myndbandgæðisbreyting**: Leyfir að breyta myndbandgæðum með
[hnappi](https://user-images.githubusercontent.com/78568641/138574366-70324a5e-2d64-4f6a-acdd-dc2a2b9cecc5.png) á
myndbandsyfirlaginu
- **Myndbandsrofi**: Bætir við [hnappi](https://user-images.githubusercontent.com/28893833/173663950-63e6610e-a532-49b7-9afa-54cb57ddfc15.png) til
að skipta á milli myndbands/lagshams. Getur einnig valfrjálst fjarlægt allan myndbandsflipann
- **Sjónrænir**: Mismunandi tónlist sjónrænir
## Þýðing
Þú getur aðstoðað við þýðingar á [Hosted Weblate](https://hosted.weblate.org/projects/youtube-music/).
<a href="https://hosted.weblate.org/engage/youtube-music/">
<img src="https://hosted.weblate.org/widget/youtube-music/i18n/multi-auto.svg" alt="translation status" />
<img src="https://hosted.weblate.org/widget/youtube-music/i18n/287x66-black.png" alt="translation status 2" />
</a>
## Sækja
Þú getur skoðað [nýjustu útgáfuna](https://github.com/th-ch/youtube-music/releases/latest) til að finna fljótt
nýjustu útgáfuna.
### Arch Linux
Settu upp [`youtube-music-bin`](https://aur.archlinux.org/packages/youtube-music-bin) pakkann frá AUR. Fyrir AUR uppsetningarleiðbeiningar skaltu skoða
þessa [wiki síðu](https://wiki.archlinux.org/index.php/Arch_User_Repository#Installing_packages).
### MacOS
Þú getur sett upp appið með því að nota Homebrew (sjá [cask skilgreiningu](https://github.com/th-ch/homebrew-youtube-music))
```bash
brew install th-ch/youtube-music/youtube-music
```
Ef þú setur upp forritið handvirkt og færð villu "er skemmd og ekki er hægt að opna það," þegar þú ræsir forritið skaltu keyra eftirfarandi í flugstöðinni:
```bash
xattr -cr /Applications/YouTube\ Music.app
```
### Windows
Þú getur notað [Scoop pakkastjórnun](https://scoop.sh) til að setja upp `youtube-music` pakkann frá
[`extras` fötunni](https://github.com/ScoopInstaller/Extras).
```bash
scoop bucket add extras
scoop install extras/youtube-music
```
Að öðrum kosti geturðu notað [Winget](https://learn.microsoft.com/en-us/windows/package-manager/winget/), Windows 11s
opinber CLI pakkastjóri til að setja upp `th-ch.YouTubeMusic` pakkann.
*Athugið: Microsoft Defender SmartScreen gæti lokað uppsetningunni þar sem hún er frá „óþekktum útgefanda“. Þetta er einnig
satt fyrir handvirka uppsetningu þegar reynt er að keyra executable(.exe) eftir handvirkt niðurhal hér á github (sama
skrá).*
```bash
winget install th-ch.YouTubeMusic
```
#### Hvernig á að setja upp án nettengingar? (í Windows)
- Sæktu `*.nsis.7z` skrána fyrir _arkitektúr tækisins þíns_ á [útgáfusíðu](https://github.com/th-ch/youtube-music/releases/latest).
- `x64` fyrir 64-bita Windows
- `ia32` fyrir 32-bita Windows
- `arm64` fyrir ARM64 Windows
- Sæktu uppsetningarforrit á útgáfusíðu. (`*-Setup.exe`)
- Settu þær í **sömu möppuna**.
- Keyrðu uppsetningarforritið.
## Þemu
Þú getur hlaðið CSS skrám til að breyta útliti forritsins (Valkostir > Sjónræn klip > Þemu).
Sum fyrirframskilgreind þemu eru fáanleg á https://github.com/kerichdev/themes-for-ytmdesktop-player.
## Þróun
```bash
git clone https://github.com/th-ch/youtube-music
cd youtube-music
pnpm install --frozen-lockfile
pnpm dev
```
## Búðu til þín eigin tengiforrit
Með því að nota tengiforrit geturðu:
- vinna með appið - `BrowserWindow` frá electron er sent til tengiforritsstjórans
- breyttu framhliðinni með því að vinna með HTML/CSS
### Er að búa til tengiforrit
Búðu til möppu í `src/plugins/YOUR-PLUGIN-NAME`:
- `index.ts`: aðal skránni af tengiforritið
```typescript
import style from './style.css?inline'; // flytja inn stíl sem inline
import { createPlugin } from '@/utils';
export default createPlugin({
name: 'Plugin Label',
restartNeeded: true, // ef gildi er satt, ytmusic sjá endurræsa gluggann
config: {
enabled: false,
}, // sérsniðnastillingar þinn
stylesheets: [style], // sérsniðnastílinn þinn
menu: async ({ getConfig, setConfig }) => {
// Allar *stillingaraðferðir eru umvafnar Lofor<T>
const config = await getConfig();
return [
{
label: 'menu',
submenu: [1, 2, 3].map((value) => ({
label: `value ${value}`,
type: 'radio',
checked: config.value === value,
click() {
setConfig({ value });
},
})),
},
];
},
backend: {
start({ window, ipc }) {
window.maximize();
// þú getur tengst við renderer tengiforritið
ipc.handle('some-event', () => {
return 'hello';
});
},
// það kviknaði þegar stillingum var breytt
onConfigChange(newConfig) { /* ... */ },
// it fired when plugin disabled
stop(context) { /* ... */ },
},
renderer: {
async start(context) {
console.log(await context.ipc.invoke('some-event'));
},
// Aðeins krókur sem er í boði fyrir renderer
onPlayerApiReady(api: YoutubePlayer, context: RendererContext) {
// stilltu stillingar viðbótarinnar auðveldlega
context.setConfig({ myConfig: api.getVolume() });
},
onConfigChange(newConfig) { /* ... */ },
stop(_context) { /* ... */ },
},
preload: {
async start({ getConfig }) {
const config = await getConfig();
},
onConfigChange(newConfig) {},
stop(_context) {},
},
});
```
### Algeng notkunartilvik
- er að sprauta sérsniðnum CSS: búðu til `style.css` skrá í sömu möppu þá:
```typescript
// index.ts
import style from './style.css?inline'; // flytja inn stíl sem inline
import { createPlugin } from '@/utils';
export default createPlugin({
name: 'Plugin Label',
restartNeeded: true, // ef gildi er satt, ytmusic sjá endurræsa gluggann
config: {
enabled: false,
}, // sérsniðnastillingar þinn
stylesheets: [style], // sérsniðnastílinn þinn
renderer() {} // skilgreina renderer krók
});
```
- Ef þú vilt breyta HTML:
```typescript
import { createPlugin } from '@/utils';
export default createPlugin({
name: 'Plugin Label',
restartNeeded: true, // ef gildi er satt, ytmusic sjá endurræsa gluggann
config: {
enabled: false,
}, // sérsniðnastillingar þinn
renderer() {
// Fjarlægðu innskráningarhnappinn
document.querySelector(".sign-in-link.ytmusic-nav-bar").remove();
} // skilgreina renderer krók
});
```
- samskipti á milli að framan og aftan: hægt að gera með því að nota ipcMain eininguna frá electron. Sjá `index.ts` skrá og
dæmi í 'styrktarblokk' tengiforritinu.
## Byggja
1. Klóna geymsluna
2. Fylgdu [þessa handbók](https://pnpm.io/installation) til að setja upp 'pnpm'
3. Keyrðu `pnpm install --frozen-lockfile` til að setja upp ósjálfstæði
4. Keyrðu `pnpm build:OS`
- `pnpm dist:win` - Windows
- `pnpm dist:linux` - Linux
- `pnpm dist:mac` - MacOS
Byggir appið fyrir macOS, Linux og Windows,
með því að nota [electron-builder](https://github.com/electron-userland/electron-builder).
## Framleiðsluforskoðun
```bash
pnpm start
```
## Prófanir
```bash
pnpm test
```
Notar [Playwright](https://playwright.dev/) til að prófa forritið.
## Leyfi
MIT © [th-ch](https://github.com/th-ch/youtube-music)
## Algengustu Spurningar
### Hvers vegna forritavalmynd birtist ekki?
Ef valmöguleikinn „Fela valmynd“ er á - þú getur sýnt valmyndina með <kbd>alt</kbd> lyklinum (eða <kbd>\`</kbd> [bakka]
ef þú notar viðbótina fyrir valmynd í forriti)

348
docs/readme/README-ko.md Normal file
View File

@ -0,0 +1,348 @@
<div align="center">
# 유튜브 뮤직 (YouTube Music)
[![GitHub release](https://img.shields.io/github/release/th-ch/youtube-music.svg?style=for-the-badge&logo=youtube-music)](https://github.com/th-ch/youtube-music/releases/)
[![GitHub license](https://img.shields.io/github/license/th-ch/youtube-music.svg?style=for-the-badge)](https://github.com/th-ch/youtube-music/blob/master/LICENSE)
[![eslint code style](https://img.shields.io/badge/code_style-eslint-5ed9c7.svg?style=for-the-badge)](https://github.com/th-ch/youtube-music/blob/master/.eslintrc.js)
[![Build status](https://img.shields.io/github/actions/workflow/status/th-ch/youtube-music/build.yml?branch=master&style=for-the-badge&logo=youtube-music)](https://GitHub.com/th-ch/youtube-music/releases/)
[![GitHub All Releases](https://img.shields.io/github/downloads/th-ch/youtube-music/total?style=for-the-badge&logo=youtube-music)](https://GitHub.com/th-ch/youtube-music/releases/)
[![AUR](https://img.shields.io/aur/version/youtube-music-bin?color=blueviolet&style=for-the-badge&logo=youtube-music)](https://aur.archlinux.org/packages/youtube-music-bin)
[![Known Vulnerabilities](https://snyk.io/test/github/th-ch/youtube-music/badge.svg)](https://snyk.io/test/github/th-ch/youtube-music)
</div>
![Screenshot](../../web/screenshot.jpg "Screenshot")
<div align="center">
<a href="https://github.com/th-ch/youtube-music/releases/latest">
<img src="../../web/youtube-music.svg" width="400" height="100" alt="YouTube Music SVG">
</a>
</div>
**유튜브 뮤직의 Electron 래퍼; 기능:**
- 원래의 인터페이스를 유지하는 것을 목표로 하는 네이티브 디자인 및 느낌
- 맞춤 플러그인을 위한 프레임워크: 스타일, 콘텐츠, 기능 등 필요에 따라 유튜브 뮤직을 변경하고, 클릭 한 번으로 플러그인을 활성화/비활성화할 수 있습니다.
## Content
- [기능](#기능)
- [사용 가능한 플러그인](#사용-가능한-플러그인)
- [번역](#번역)
- [다운로드](#다운로드)
- [Arch Linux](#arch-linux)
- [MacOS](#macos)
- [Windows](#windows)
- [(Windows에서) 네트워크에 연결하지 않고 설치하는 방법은 무엇인가요?](#windows에서-네트워크에-연결하지-않고-설치하는-방법은-무엇인가요)
- [테마](#테마)
- [개발](#개발)
- [나만의 플러그인 만들기](#나만의-플러그인-만들기)
- [플러그인 만들기](#플러그인-만들기)
- [일반적인 사용 예](#일반적인-사용-예)
- [빌드](#빌드)
- [프로덕션 빌드 미리보기](#프로덕션-빌드-미리보기)
- [테스트](#테스트)
- [라이선스](#라이선스)
- [자주 묻는 질문](#자주-묻는-질문)
## 기능:
- **일시 정지 시 자동 확인** (항상 활성화 됨): 일정 시간이 지나면 음악을 일시 정지하는 ["계속 시청하시겠습니까?"](https://user-images.githubusercontent.com/61631665/129977894-01c60740-7ec6-4bf0-9a2c-25da24491b0e.png) 팝업을 비활성화합니다.
- 이외에 더 많은 기능 ...
## 사용 가능한 플러그인:
- **애드블록**: 모든 광고와 트래커를 즉시 차단합니다
- **앨범 컬러 기반 테마**: 앨범 색상 팔레트를 기반으로 동적 테마 및 시각 효과를 적용합니다
- **앰비언트 모드**: 영상의 간접 조명을 화면 배경에 투사합니다.
- **오디오 컴프레서**: 오디오에 컴프레서를 적용합니다 (신호에서 가장 시끄러운 부분의 음량을 낮추고 가장 조용한 부분의 음량을 높임)
- **네비게이션 바 흐림 효과**: 내비게이션 바를 투명하고 흐릿하게 만듭니다
- **나이 제한 우회**: 유튜브의 나이 제한을 우회합니다
- **자막 선택기**: 자막을 활성화합니다
- **컴팩트 사이드바**: 사이드바를 항상 컴팩트 모드로 설정합니다
- **크로스페이드**: 노래 사이에 크로스페이드 효과를 적용합니다
- **자동 재생 해제**: 노래를 '일시 정지' 모드로 시작하게 합니다
- [**디스코드 활동 상태**](https://discord.com/): [활동 상태 (Rich Presence)](https://user-images.githubusercontent.com/28219076/104362104-a7a0b980-5513-11eb-9744-bb89eabe0016.png)를 사용하여 친구들에게 내가 듣는 음악을 보여주세요
- **다운로더**: UI에서 [직접](https://user-images.githubusercontent.com/61631665/129977677-83a7d067-c192-45e1-98ae-b5a4927393be.png) MP3/소스 오디오를 다운로드하세요
- **지수 볼륨**: 음량 슬라이더를 [지수적](https://greasyfork.org/en/scripts/397686-youtube-music-fix-volume-ratio/)으로 만들어 더 낮은 음량을 쉽게 선택할 수 있도록 합니다.
- **인앱 메뉴**: [메뉴 표시줄을 더 멋지게, 그리고 다크 또는 앨범의 색상으로 만듭니다](https://user-images.githubusercontent.com/78568641/112215894-923dbf00-8c29-11eb-95c3-3ce15db27eca.png)
> (이 플러그인 및 메뉴 숨기기 옵션을 활성화한 후 메뉴에 액세스하는 데 문제가 있는 경우 [이 글](https://github.com/th-ch/youtube-music/issues/410#issuecomment-952060709)을 참조하세요)
- [**Last.fm**](https://www.last.fm/): Last.fm에 대한 스크러블 지원을 추가합니다
- **Lumia Stream**: [Lumia Stream](https://lumiastream.com/) 지원을 추가합니다
- **Genius 가사**: 더 많은 곡에 대해 가사 지원을 추가합니다
- **네비게이션**: 브라우저에서처럼, UI에 직접 통합된 앞으로/뒤로 탐색하는 화살표를 추가합니다
- **Google 로그인 제거**: UI에서 Google 로그인 버튼 및 링크 제거하기
- **알림**: 노래 재생이 시작되면 알림을 표시 (Windows에서는 [대화형 알림](https://user-images.githubusercontent.com/78568641/114102651-63ce0e00-98d0-11eb-9dfe-c5a02bb54f9c.png) 사용 가능)
- **PiP**: 앱을 PiP 모드로 전환할 수 있게 허용합니다
- **재생 속도**: 빨리 듣거나, 천천히 들어보세요! [노래 속도를 제어하는 슬라이더를 추가합니다](https://user-images.githubusercontent.com/61631665/129976003-e55db5ba-bf42-448c-a059-26a009775e68.png)
- **정확한 음량**: 사용자 지정 HUD와 사용자 지정 음량 단계 및 마우스 휠/단축키를 사용하여 음량을 정확하게 제어하세요
- **영상 품질 체인저**: 영상 오버레이의 [버튼](https://user-images.githubusercontent.com/78568641/138574366-70324a5e-2d64-4f6a-acdd-dc2a2b9cecc5.png)으로 영상 품질을 변경할 수 있게 합니다
- **단축키 (& MPRIS)**: 재생을 위한 전역 단축키 설정 허용 (재생/일시 정지/다음/이전) + 미디어 키를 재정의하여 [미디어 osd](https://user-images.githubusercontent.com/84923831/128601225-afa38c1f-dea8-4209-9f72-0f84c1dd8b54.png) 비활성화 + Ctrl/CMD + F 검색 활성화 + 미디어 키에 대한 리눅스 MPRIS 지원 활성화 + [고급 사용자](https://github.com/th-ch/youtube-music/issues/106#issuecomment-952156902)를 위한 [사용자 지정 단축키](https://github.com/Araxeus/youtube-music/blob/1e591d6a3df98449bcda6e63baab249b28026148/providers/song-controls.js#L13-L50) 지원
- **무음 건너뛰기** - 노래의 무음 부분을 자동으로 건너뜁니다
- [**SponsorBlock**](https://github.com/ajayyy/SponsorBlock): 인트로/아웃트로와 같은 음악이 아닌 부분이나, 노래가 재생되지 않는 뮤직 비디오의 일부를 자동으로 건너뜁니다
- **작업표시줄 미디어 컨트롤**: [Windows 작업표시줄](https://user-images.githubusercontent.com/78568641/111916130-24a35e80-8a82-11eb-80c8-5021c1aa27f4.png)에서 재생을 제어하세요
- **TouchBar**: macOS 사용자를 위한 TouchBar 위젯을 추가합니다
- **Tuna-OBS**: [OBS](https://obsproject.com/)의 플러그인, [Tuna](https://obsproject.com/forum/resources/tuna.843/)와 통합을 활성화합니다
- **영상 전환**: 영상/노래 모드를 전환하는 [버튼](https://user-images.githubusercontent.com/28893833/173663950-63e6610e-a532-49b7-9afa-54cb57ddfc15.png)을 추가합니다. 선택적으로 전체 영상 탭을 제거할 수도 있습니다
- **비주얼라이저**: 플레이어에 시각화 도구 추가
## 번역
[Hosted Weblate](https://hosted.weblate.org/projects/youtube-music/)에서 번역을 도울 수 있습니다.
<a href="https://hosted.weblate.org/engage/youtube-music/">
<img src="https://hosted.weblate.org/widget/youtube-music/i18n/multi-auto.svg" alt="번역 상태" />
<img src="https://hosted.weblate.org/widget/youtube-music/i18n/287x66-black.png" alt="번역 상태 2" />
</a>
## 다운로드
[최신 릴리즈](https://github.com/th-ch/youtube-music/releases/latest)를 확인하여 최신 버전을 빠르게 찾을 수 있습니다.
### Arch Linux
AUR에서 [`youtube-music-bin`](https://aur.archlinux.org/packages/youtube-music-bin) 패키지를 설치합니다. AUR 설치 지침은 [이 위키 페이지](https://wiki.archlinux.org/index.php/Arch_User_Repository#Installing_packages)를 참조하세요.
### MacOS
Homebrew를 사용하여 앱을 설치할 수 있습니다:
```bash
brew install --cask https://raw.githubusercontent.com/th-ch/youtube-music/master/youtube-music.rb
```
(앱을 수동으로 설치하고) 앱을 실행할 때 `손상되었기 때문에 열 수 없습니다.`라는 오류가 발생하면 터미널에서 다음을 실행하세요:
```bash
xattr -cr /Applications/YouTube\ Music.app
```
### Windows
[Scoop 패키지 매니저](https://scoop.sh)를 사용하여 [`extras` 버킷](https://github.com/ScoopInstaller/Extras)에서 `youtube-music` 패키지를 설치할 수 있습니다.
```bash
scoop bucket add extras
scoop install extras/youtube-music
```
또는 Windows 11의 공식 CLI 패키지 관리자인 [Winget](https://learn.microsoft.com/en-us/windows/package-manager/winget/)을 사용하여 `th-ch.YouTubeMusic` 패키지를 설치할 수 있습니다.
*참고: "알 수 없는 게시자"의 파일이기 때문에 Microsoft Defender의 SmartScreen에서 설치를 차단할 수 있습니다. 이는 GitHub에서 동일 파일을 수동으로 다운로드한 후 실행 파일(.exe)을 실행하려고 할 때도 마찬가지로 발생합니다.*
```bash
winget install th-ch.YouTubeMusic
```
#### (Windows에서) 네트워크에 연결하지 않고 설치하는 방법은 무엇인가요?
- [릴리즈 페이지](https://github.com/th-ch/youtube-music/releases/latest)에서 _본인 기기 아키텍처_에 맞는 `*.nsis.7z` 파일을 다운로드하세요.
- `x64`는 64비트 Windows 용입니다.
- `ia32`는 32비트 Windows 용입니다.
- `arm64`는 ARM64 Windows 용입니다.
- 릴리즈 페이지에서 설치기를 다운로드하세요. (`*-Setup.exe`)
- 두 파일을 **동일한 위치**에 놓아주세요.
- 설치기를 실행하세요.
## 테마
CSS 파일을 로드하여 애플리케이션의 모양을 변경할 수 있습니다(설정 > 시각적 변경 > 테마).
일부 사전 정의 테마는 https://github.com/kerichdev/themes-for-ytmdesktop-player 에서 사용할 수 있습니다.
## 개발
```bash
git clone https://github.com/th-ch/youtube-music
cd youtube-music
pnpm install --frozen-lockfile
pnpm dev
```
## 나만의 플러그인 만들기
플러그인을 사용하면 할 수 있는 것들:
- 앱 조작 - Electron에서 `BrowserWindow`가 플러그인 핸들러로 전달
- HTML/CSS를 조작하여 프론트엔드를 변경
### 플러그인 만들기
`plugins/나만의-플러그인-이름`에 폴더를 만듭니다:
- `index.ts`: 플러그인의 메인 파일입니다.
```typescript
import style from './style.css?inline'; // 스타일을 인라인으로 가져옵니다
import { createPlugin } from '@/utils';
export default createPlugin({
name: 'Plugin Label',
restartNeeded: true, // 값이 true면, YTM은 재시작 다이얼로그를 표시합니다
config: {
enabled: false,
}, // 나의 커스텀 config
stylesheets: [style], // 나의 스타일
menu: async ({ getConfig, setConfig }) => {
// 모든 *Config 메서드는 Promise<T>로 래핑됩니다
const config = await getConfig();
return [
{
label: 'menu',
submenu: [1, 2, 3].map((value) => ({
label: `value ${value}`,
type: 'radio',
checked: config.value === value,
click() {
setConfig({ value });
},
})),
},
];
},
backend: {
start({ window, ipc }) {
window.maximize();
// 이를 사용하여 렌더러 플러그인과 통신할 수 있습니다
ipc.handle('some-event', () => {
return 'hello';
});
},
// config가 변경되면 실행됩니다
onConfigChange(newConfig) { /* ... */ },
// 플러그인이 비활성화되면 실행됩니다
stop(context) { /* ... */ },
},
renderer: {
async start(context) {
console.log(await context.ipc.invoke('some-event'));
},
// 렌더러에서만 사용 가능한 훅입니다
onPlayerApiReady(api: YoutubePlayer, context: RendererContext<T>) {
// 플러그인의 config를 간단하게 설정할 수 있습니다
context.setConfig({ myConfig: api.getVolume() });
},
onConfigChange(newConfig) { /* ... */ },
stop(_context) { /* ... */ },
},
preload: {
async start({ getConfig }) {
const config = await getConfig();
},
onConfigChange(newConfig) {},
stop(_context) {},
},
});
```
### 일반적인 사용 예
- 사용자 정의 CSS 삽입: 같은 폴더에 `style.css` 파일을 생성합니다:
```typescript
// index.ts
import style from './style.css?inline'; // 스타일을 인라인으로 가져옵니다
import { createPlugin } from '@/utils';
export default createPlugin({
name: 'Plugin Label',
restartNeeded: true, // 값이 true면, YTM은 재시작 다이얼로그를 표시합니다
config: {
enabled: false,
}, // 나의 커스텀 config
stylesheets: [style], // 나의 커스텀 스타일
renderer() {} // 렌더러 훅 정의
});
```
- HTML을 변경하려는 경우:
```typescript
import { createPlugin } from '@/utils';
export default createPlugin({
name: 'Plugin Label',
restartNeeded: true, // 값이 true면, YTM은 재시작 다이얼로그를 표시합니다
config: {
enabled: false,
}, // 나의 커스텀 config
renderer() {
// 로그인 버튼을 제거합니다
document.querySelector(".sign-in-link.ytmusic-nav-bar").remove();
} // 렌더러 훅 정의
});
```
- 프론트엔드와 백엔드 간의 통신: Electron의 `ipcMain` 모듈을 사용하여 수행할 수 있습니다. `SponsorBlock` 플러그인의 `index.ts` 파일과 예제를 참조하세요.
## 빌드
1. 레포지토리를 복제 (clone) 합니다
2. [이 가이드](https://pnpm.io/installation)에 따라 `pnpm`을 설치합니다.
3. `pnpm install --frozen-lockfile`을 실행하여 종속성을 설치합니다.
4. `pnpm build:OS`을 실행합니다.
- `pnpm dist:win` - Windows
- `pnpm dist:linux` - Linux
- `pnpm dist:mac` - MacOS
[electron-builder](https://github.com/electron-userland/electron-builder)를 사용하여 macOS, Linux 및 Windows용 앱을 빌드합니다.
## 프로덕션 빌드 미리보기
```bash
pnpm start
```
## 테스트
```bash
pnpm test
```
[Playwright](https://playwright.dev/)를 사용하여 앱을 테스트합니다.
## 라이선스
MIT © [th-ch](https://github.com/th-ch/youtube-music)
## 자주 묻는 질문
### 앱 메뉴가 표시되지 않는 이유는 무엇인가요?
`메뉴 숨기기` 옵션이 켜져 있는 경우 - <kbd>alt</kbd> 키(또는 인앱 메뉴 플러그인을 사용하는 경우 <kbd>\`</kbd> [백틱] 키)로 메뉴를 표시할 수 있습니다.

374
docs/readme/README-ru.md Normal file
View File

@ -0,0 +1,374 @@
<div align="center">
# YouTube Music
[![GitHub release](https://img.shields.io/github/release/th-ch/youtube-music.svg?style=for-the-badge&logo=youtube-music)](https://github.com/th-ch/youtube-music/releases/)
[![GitHub license](https://img.shields.io/github/license/th-ch/youtube-music.svg?style=for-the-badge)](https://github.com/th-ch/youtube-music/blob/master/LICENSE)
[![eslint code style](https://img.shields.io/badge/code_style-eslint-5ed9c7.svg?style=for-the-badge)](https://github.com/th-ch/youtube-music/blob/master/.eslintrc.js)
[![Build status](https://img.shields.io/github/actions/workflow/status/th-ch/youtube-music/build.yml?branch=master&style=for-the-badge&logo=youtube-music)](https://GitHub.com/th-ch/youtube-music/releases/)
[![GitHub All Releases](https://img.shields.io/github/downloads/th-ch/youtube-music/total?style=for-the-badge&logo=youtube-music)](https://GitHub.com/th-ch/youtube-music/releases/)
[![AUR](https://img.shields.io/aur/version/youtube-music-bin?color=blueviolet&style=for-the-badge&logo=youtube-music)](https://aur.archlinux.org/packages/youtube-music-bin)
[![Known Vulnerabilities](https://snyk.io/test/github/th-ch/youtube-music/badge.svg)](https://snyk.io/test/github/th-ch/youtube-music)
</div>
![Screenshot](web/screenshot.jpg "Screenshot")
<div align="center">
<a href="https://github.com/th-ch/youtube-music/releases/latest">
<img src="web/youtube-music.svg" width="400" height="100" alt="YouTube Music SVG">
</a>
</div>
**Клиент для YouTube Music основанный на Electron с поддержкой:**
- Нативный вид приложения, нацелен на сохранение оригинального интерфейса
- Фреймворк для пользовательских плагинов: изменяйте YouTube Music под ваши нужды (внешний вид, контент, возможности), включайте/выключайте плагины в один клик
## Демо-изображение
| Экран плеера (цветовая тема альбома & режим Ambient) |
|:---------------------------------------------------------------------------------------------------------:|
|![Screenshot1](https://github.com/th-ch/youtube-music/assets/16558115/53efdf73-b8fa-4d7b-a235-b96b91ea77fc)|
## Содержание
- [Возможности](#features)
- [Доступные плагины](#available-plugins)
- [Перевод](#translation)
- [Скачать](#download)
- [Arch Linux](#arch-linux)
- [MacOS](#macos)
- [Windows](#windows)
- [Как установить без подключения к интернету? (в Windows)](#how-to-install-without-a-network-connection-in-windows)
- [Темы](#themes)
- [Для разработчиков](#dev)
- [Создайте свои собственные плагины](#build-your-own-plugins)
- [Создание плагина](#creating-a-plugin)
- [Примеры использования](#common-use-cases)
- [Сборка](#build)
- [Предварительный просмотр](#production-preview)
- [Тестирование](#tests)
- [Лицензия](#license)
- [Часто задаваемые вопросы](#faq)
## Возможности:
- **Авто-подтверждение при паузе** (Всегда включено): отключает всплывающие уведомление ["Продолжить просмотр?"](https://user-images.githubusercontent.com/61631665/129977894-01c60740-7ec6-4bf0-9a2c-25da24491b0e.png),
которое приостанавливает воспроизведение через определённое время
- И больше ...
## Доступные плагины:
- **Блокировщик рекламы**: Блокирует всю рекламу и трекеры
- **Действия с альбомом**: Добавляет кнопки "Убрать дизлайк", "Дизлайк", "Лайк", "Убрать лайк" и применяет их действия ко всем трекам в плейлисте или альбоме
- **Цветовая тема альбома**: Применяет динамическую тему и эффекты, основываясь на цветовой палитре альбома
- **Режим Ambient**: Применяет световой эффект, проецируя нежные цвета из видео на задний фон вашего экрана
- **Нормализация аудио**: Применяет нормализацию к аудио (уменьшает громкость громких частей трека и повышает громкость тихих частей трека)
- **Размытие панели навигации**: Делает панель навигации прозрачной и размытой
- **Обход возрастных ограничений**: Обходит проверку возраста YouTube
- **Выбор субтитров**: Включить субтитры
- **Компактная боковая панель**: Всегда показывать боковую панель компактно
- **Плавный переход**: Плавный переход между треками
- **Отключить автопроигрыш**: Каждый трек начинается в режиме паузы
- **[Discord](https://discord.com/) Rich Presence**: Показывает вашим друзьям, что вы слушаете с помощью [Rich Presence](https://user-images.githubusercontent.com/28219076/104362104-a7a0b980-5513-11eb-9744-bb89eabe0016.png)
- **Загрузчик**: Загрузка MP3 [напрямую из интерфейса](https://user-images.githubusercontent.com/61631665/129977677-83a7d067-c192-45e1-98ae-b5a4927393be.png) [(youtube-dl)](https://github.com/ytdl-org/youtube-dl)
- **Расширенная громкость**: Делает слайдер громкости [расширенным](https://greasyfork.org/en/scripts/397686-youtube-music-fix-volume-ratio/) облегчая выбор громкости
- **Меню в приложении**: [Придаёт панели меню красивый тёмный вид](https://user-images.githubusercontent.com/78568641/112215894-923dbf00-8c29-11eb-95c3-3ce15db27eca.png)
> (посмотрите [этот пост,](https://github.com/th-ch/youtube-music/issues/410#issuecomment-952060709) если у вас есть проблемы с доступом к меню после включения этого плагина и опции "Скрыть меню")
- **Скробблер**: Добавляет поддержку скробблинга [Last.fm](https://www.last.fm/) и [ListenBrainz](https://listenbrainz.org/)
- **Lumia Stream**: Добавляет поддержку [Lumia Stream](https://lumiastream.com/)
- **Тесты песен Genius**: Добавляет поддержку текстов для большинства песен
- **Music Together**: Делитесь плейлистом с другими. Когда ведущий воспроизводит трек, все остальные будут слушать этот же трек.
- **Навигация**: Кнопки Назад/Вперед интегрированы в интерфейс, как в вашем любимом браузере
- **Без входа в систему Google**: Убирает из интерфейса кнопки и ссылки для входа через Google
- **Уведомления**: Показывает уведомление, когда трек начинает играть ([интерактивные уведомления](https://user-images.githubusercontent.com/78568641/114102651-63ce0e00-98d0-11eb-9dfe-c5a02bb54f9c.png) доступны только для Windows)
- **Картинка в картинке**: Позволяет переключить приложение в режим "картинка в картинке"
- **Скорость воспроизведения**: Слушайте быстрее, слушайте медленнее! [Добавляет слайдер для контроля скорости трека](https://user-images.githubusercontent.com/61631665/129976003-e55db5ba-bf42-448c-a059-26a009775e68.png)
- **Точная громкость**: Точечно управляйте громкостью с помощью колеса мыши/горячих клавиш, с кастомным интерфейсом и настраиваемыми шагами громкости
- **Ярлыки (и MPRIS)**: Позволяет настроить глобальные горячие клавиши управления воспроизведением (плей/пауза/следующий/предыдущий) + отключает [отображение медиа на экране,](https://user-images.githubusercontent.com/84923831/128601225-afa38c1f-dea8-4209-9f72-0f84c1dd8b54.png) переопределяя клавиши управления + включает Ctrl/CMD + F для поиска + включает поддержку linux mpris для клавиш управления медиа + [настраиваемые сочетания клавиш](https://github.com/Araxeus/youtube-music/blob/1e591d6a3df98449bcda6e63baab249b28026148/providers/song-controls.js#L13-L50) для [продвинутых пользователей](https://github.com/th-ch/youtube-music/issues/106#issuecomment-952156902)
- **Пропускать непонравившиеся треки**: Пропускает непонравившиеся треки
- **Пропуск тишины**: Автоматически пропускает тихие моменты в песнях
- [**SponsorBlock**](https://github.com/ajayyy/SponsorBlock): Автоматически пропускает немузыкальные части, такие как интро/аутро музыкальных видео, где трек не играет
- **Управление воспроизведением из панели задач**: Управляйте воспроизведением из [панели задач Windows](https://user-images.githubusercontent.com/78568641/111916130-24a35e80-8a82-11eb-80c8-5021c1aa27f4.png)
- **TouchBar**: Кастомная раскладка TouchBar для MacOS
- **Tuna OBS**: Интеграция с [OBS](https://obsproject.com/) плагином [Tuna](https://obsproject.com/forum/resources/tuna.843/)
- **Изменение качества видео**: Позволяет менять качество видео [кнопкой](https://user-images.githubusercontent.com/78568641/138574366-70324a5e-2d64-4f6a-acdd-dc2a2b9cecc5.png) на медиаплеере видео
- **Переключатель видео**: Добавляет
[кнопку](https://user-images.githubusercontent.com/28893833/173663950-63e6610e-a532-49b7-9afa-54cb57ddfc15.png) переключения режимов Трек/Видео. Также может удалять вкладку "Видео" полностью
- **Визуализатор**: Различные визуализаторы музыки
- **Synced Lyrics**:
Предоставляет синхронизированные слова для песен из таких источников, как [LRClib](https://lrclib.net).
## Перевод
Вы можете помочь с переводом на ваш язык на [Hosted Weblate](https://hosted.weblate.org/projects/youtube-music/).
<a href="https://hosted.weblate.org/engage/youtube-music/">
<img src="https://hosted.weblate.org/widget/youtube-music/i18n/multi-auto.svg" alt="translation status" />
<img src="https://hosted.weblate.org/widget/youtube-music/i18n/287x66-black.png" alt="translation status 2" />
</a>
## Скачать
Вы можете посмотреть [latest release,](https://github.com/th-ch/youtube-music/releases/latest) чтобы быстро найти новую версию.
### Arch Linux
Установите пакет [`youtube-music-bin`](https://aur.archlinux.org/packages/youtube-music-bin) из AUR. Инструкции по установке из AUR можете найти на этой [вики-странице](https://wiki.archlinux.org/index.php/Arch_User_Repository#Installing_packages).
### macOS
Вы можете установить приложение с помощью Homebrew (сморите [cask definition](https://github.com/th-ch/homebrew-youtube-music)):
```bash
brew install th-ch/youtube-music/youtube-music
```
Если вы устанавливаете приложение вручную и получаете ошибку "is damaged and cant be opened.", запустите в терминале следующую команду:
```bash
xattr -cr /Applications/YouTube\ Music.app
```
### Windows
Вы можете использовать [пакетный менеджер Scoop](https://scoop.sh) для установки пакета `youtube-music` из [`extras` bucket](https://github.com/ScoopInstaller/Extras).
```bash
scoop bucket add extras
scoop install extras/youtube-music
```
Также для установки вы можете использовать [Winget](https://learn.microsoft.com/en-us/windows/package-manager/winget/), официальный пакетный менеджер командной строки Windows 11, для установки пакета `th-ch.YouTubeMusic`.
*К сведению: SmartScreen защитника Windows может блокировать установку, так как она от "неизвестного издателя". Это также применимо к методу ручной установки, когда вы пытаетесь запустить исполняемый файл(.exe) после загрузки здесь, на GitHub (тот же файл).*
```bash
winget install th-ch.YouTubeMusic
```
#### Установка без подключения к Интернету? (в Windows)
- Скачайте файл `*.nsis.7z` из _архетиктура вашего устройства_ на [release page](https://github.com/th-ch/youtube-music/releases/latest).
- `x64` для 64-bit Windows
- `ia32` для 32-bit Windows
- `arm64` для ARM64 Windows
- Скачайте установщик в release page. (`*-Setup.exe`)
- Поместите их в **одной директории**.
- Запустите установщик.
## Темы
Вы можете загрузить файл CSS для смены внешнего вида приложения (Настройки > Визуальные настройки > Тема).
Некоторые предустановленные темы доступны здесь: https://github.com/kerichdev/themes-for-ytmdesktop-player.
## Для разработчиков
```bash
git clone https://github.com/th-ch/youtube-music
cd youtube-music
pnpm install --frozen-lockfile
pnpm dev
```
## Создайте свои собственные плагины
Используя плагины вы можете:
- Манипулировать приложением - `BrowserWindow` из electron проброшен обработчику плагинов
- Изменять внешний вид, манипулируя HTML/CSS
### Создание плагина
Создайте директорию в `src/plugins/YOUR-PLUGIN-NAME`:
- `index.ts`: основной файл плагина
```typescript
import style from './style.css?inline'; // import style as inline
import { createPlugin } from '@/utils';
export default createPlugin({
name: 'Plugin Label',
restartNeeded: true, // if value is true, ytmusic show restart dialog
config: {
enabled: false,
}, // your custom config
stylesheets: [style], // your custom style,
menu: async ({ getConfig, setConfig }) => {
// All *Config methods are wrapped Promise<T>
const config = await getConfig();
return [
{
label: 'menu',
submenu: [1, 2, 3].map((value) => ({
label: `value ${value}`,
type: 'radio',
checked: config.value === value,
click() {
setConfig({ value });
},
})),
},
];
},
backend: {
start({ window, ipc }) {
window.maximize();
// you can communicate with renderer plugin
ipc.handle('some-event', () => {
return 'hello';
});
},
// it fired when config changed
onConfigChange(newConfig) { /* ... */ },
// it fired when plugin disabled
stop(context) { /* ... */ },
},
renderer: {
async start(context) {
console.log(await context.ipc.invoke('some-event'));
},
// Only renderer available hook
onPlayerApiReady(api: YoutubePlayer, context: RendererContext) {
// set plugin config easily
context.setConfig({ myConfig: api.getVolume() });
},
onConfigChange(newConfig) { /* ... */ },
stop(_context) { /* ... */ },
},
preload: {
async start({ getConfig }) {
const config = await getConfig();
},
onConfigChange(newConfig) {},
stop(_context) {},
},
});
```
### Примеры использования
- Кастомный CSS: создайте файл `style.css` в той же директории, затем:
```typescript
// index.ts
import style from './style.css?inline'; // import style as inline
import { createPlugin } from '@/utils';
export default createPlugin({
name: 'Plugin Label',
restartNeeded: true, // if value is true, ytmusic will show a restart dialog
config: {
enabled: false,
}, // your custom config
stylesheets: [style], // your custom style
renderer() {} // define renderer hook
});
```
- Если вы хотите изменить HTML:
```typescript
import { createPlugin } from '@/utils';
export default createPlugin({
name: 'Plugin Label',
restartNeeded: true, // if value is true, ytmusic will show the restart dialog
config: {
enabled: false,
}, // your custom config
renderer() {
// Remove the login button
document.querySelector(".sign-in-link.ytmusic-nav-bar").remove();
} // define renderer hook
});
```
- обмен между фронтом и бэком может быть выполнен с помощью модуля ipcMain из electron. Смотрите файл `index.ts` и
пример в плагине `sponsorblock`.
## Сборка
1. Склонируйте репозиторий
2. Следуйте [этой инструкции,](https://pnpm.io/installation) чтобы установить `pnpm`
3. Запустите `pnpm install --frozen-lockfile` для установки зависимостей
4. Запустите `pnpm build:OS`
- `pnpm dist:win` - Windows
- `pnpm dist:linux` - Linux (amd64)
- `pnpm dist:linux:deb-arm64` - Linux (arm64 for Debian)
- `pnpm dist:linux:rpm-arm64` - Linux (arm64 for Fedora)
- `pnpm dist:mac` - macOS (amd64)
- `pnpm dist:mac:arm64` - macOS (arm64)
Сборка приложения для macOS, Linux, и Windows,
используя [electron-builder](https://github.com/electron-userland/electron-builder).
## Предварительный просмотр
```bash
pnpm start
```
## Тестирование
```bash
pnpm test
```
Использует [Playwright](https://playwright.dev/) для тестирования приложения.
## Лицензия
MIT © [th-ch](https://github.com/th-ch/youtube-music)
## Часто задаваемые вопросы
### Почему меня приложения не отображается?
Если опция `Скрыть меню` включена - вы можете отобразить меню с помощью клавиши <kbd>alt</kbd> (или <kbd>\`</kbd> [обратный апостроф], если используете плагин "Меню в приложении")

172
electron.vite.config.mts Normal file
View File

@ -0,0 +1,172 @@
import { resolve, dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';
import { UserConfig } from 'vite';
import { defineConfig, defineViteConfig } from 'electron-vite';
import builtinModules from 'builtin-modules';
import viteResolve from 'vite-plugin-resolve';
import Inspect from 'vite-plugin-inspect';
import solidPlugin from 'vite-plugin-solid';
import { pluginVirtualModuleGenerator } from './vite-plugins/plugin-importer.mjs';
import pluginLoader from './vite-plugins/plugin-loader.mjs';
import { i18nImporter } from './vite-plugins/i18n-importer.mjs';
const __dirname = dirname(fileURLToPath(import.meta.url));
const resolveAlias = {
'@': resolve(__dirname, './src'),
'@assets': resolve(__dirname, './assets'),
};
export default defineConfig({
main: defineViteConfig(({ mode }) => {
const commonConfig: UserConfig = {
plugins: [
pluginLoader('backend'),
viteResolve({
'virtual:i18n': i18nImporter(),
'virtual:plugins': pluginVirtualModuleGenerator('main'),
}),
],
publicDir: 'assets',
build: {
lib: {
entry: 'src/index.ts',
formats: ['cjs'],
},
outDir: 'dist/main',
commonjsOptions: {
ignoreDynamicRequires: true,
},
rollupOptions: {
external: ['electron', 'custom-electron-prompt', ...builtinModules],
input: './src/index.ts',
},
},
resolve: {
alias: resolveAlias,
},
};
if (mode === 'development') {
commonConfig.build!.sourcemap = 'inline';
commonConfig.plugins?.push(
Inspect({
build: true,
outputDir: join(__dirname, '.vite-inspect/backend'),
}),
);
return commonConfig;
}
return {
...commonConfig,
build: {
...commonConfig.build,
minify: true,
cssMinify: true,
},
};
}),
preload: defineViteConfig(({ mode }) => {
const commonConfig: UserConfig = {
plugins: [
pluginLoader('preload'),
viteResolve({
'virtual:i18n': i18nImporter(),
'virtual:plugins': pluginVirtualModuleGenerator('preload'),
}),
],
build: {
lib: {
entry: 'src/preload.ts',
formats: ['cjs'],
},
outDir: 'dist/preload',
commonjsOptions: {
ignoreDynamicRequires: true,
},
rollupOptions: {
external: ['electron', 'custom-electron-prompt', ...builtinModules],
input: './src/preload.ts',
},
},
resolve: {
alias: resolveAlias,
},
};
if (mode === 'development') {
commonConfig.build!.sourcemap = 'inline';
commonConfig.plugins?.push(
Inspect({
build: true,
outputDir: join(__dirname, '.vite-inspect/preload'),
}),
);
return commonConfig;
}
return {
...commonConfig,
build: {
...commonConfig.build,
minify: true,
cssMinify: true,
},
};
}),
renderer: defineViteConfig(({ mode }) => {
const commonConfig: UserConfig = {
plugins: [
pluginLoader('renderer'),
viteResolve({
'virtual:i18n': i18nImporter(),
'virtual:plugins': pluginVirtualModuleGenerator('renderer'),
}),
solidPlugin(),
],
root: './src/',
build: {
lib: {
entry: 'src/index.html',
formats: ['iife'],
name: 'renderer',
},
outDir: 'dist/renderer',
commonjsOptions: {
ignoreDynamicRequires: true,
},
rollupOptions: {
external: ['electron', ...builtinModules],
input: './src/index.html',
},
},
resolve: {
alias: resolveAlias,
},
};
if (mode === 'development') {
commonConfig.build!.sourcemap = 'inline';
commonConfig.plugins?.push(
Inspect({
build: true,
outputDir: join(__dirname, '.vite-inspect/renderer'),
}),
);
return commonConfig;
}
return {
...commonConfig,
build: {
...commonConfig.build,
minify: true,
cssMinify: true,
},
};
}),
});

View File

@ -1,50 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Cannot load YouTube Music</title>
<style>
body {
background: #000;
}
.container {
margin: 0;
font-family: Roboto, Arial, sans-serif;
font-size: 20px;
font-weight: 500;
color: rgba(255, 255, 255, 0.5);
position: absolute;
top: 50%;
left: 50%;
margin-right: -50%;
transform: translate(-50%, -50%);
text-align: center;
}
.button {
background: #065fd4;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: white;
font: inherit;
text-transform: uppercase;
text-decoration: none;
border-radius: 2px;
font-size: 16px;
font-weight: normal;
text-align: center;
padding: 8px 22px;
display: inline-block;
}
</style>
</head>
<body>
<div class="container">
<p>Cannot load YouTube Music… Internet disconnected?</p>
<a class="button" href="#" onclick="reload()">Retry</a>
</div>
</body>
</html>

639
index.ts
View File

@ -1,639 +0,0 @@
import path from 'node:path';
import { BrowserWindow, app, screen, globalShortcut, session, shell, dialog, ipcMain } from 'electron';
import enhanceWebRequest, { BetterSession } from '@jellybrick/electron-better-web-request';
import is from 'electron-is';
import unhandled from 'electron-unhandled';
import { autoUpdater } from 'electron-updater';
import electronDebug from 'electron-debug';
import config from './config';
import { refreshMenu, setApplicationMenu } from './menu';
import { fileExists, injectCSS, injectCSSAsFile } from './plugins/utils';
import { isTesting } from './utils/testing';
import { setUpTray } from './tray';
import { setupSongInfo } from './providers/song-info';
import { restart, setupAppControls } from './providers/app-controls';
import { APP_PROTOCOL, handleProtocol, setupProtocolHandler } from './providers/protocol-handler';
import adblocker from './plugins/adblocker/back';
import albumColorTheme from './plugins/album-color-theme/back';
import ambientMode from './plugins/ambient-mode/back';
import blurNavigationBar from './plugins/blur-nav-bar/back';
import captionsSelector from './plugins/captions-selector/back';
import crossfade from './plugins/crossfade/back';
import discord from './plugins/discord/back';
import downloader from './plugins/downloader/back';
import inAppMenu from './plugins/in-app-menu/back';
import lastFm from './plugins/last-fm/back';
import lumiaStream from './plugins/lumiastream/back';
import lyricsGenius from './plugins/lyrics-genius/back';
import navigation from './plugins/navigation/back';
import noGoogleLogin from './plugins/no-google-login/back';
import notifications from './plugins/notifications/back';
import pictureInPicture, { setOptions as pipSetOptions } from './plugins/picture-in-picture/back';
import preciseVolume from './plugins/precise-volume/back';
import qualityChanger from './plugins/quality-changer/back';
import shortcuts from './plugins/shortcuts/back';
import sponsorBlock from './plugins/sponsorblock/back';
import taskbarMediaControl from './plugins/taskbar-mediacontrol/back';
import touchbar from './plugins/touchbar/back';
import tunaObs from './plugins/tuna-obs/back';
import videoToggle from './plugins/video-toggle/back';
import visualizer from './plugins/visualizer/back';
import youtubeMusicCSS from './youtube-music.css';
// Catch errors and log them
unhandled({
logger: console.error,
showDialog: false,
});
// Disable Node options if the env var is set
process.env.NODE_OPTIONS = '';
// Prevent window being garbage collected
let mainWindow: Electron.BrowserWindow | null;
autoUpdater.autoDownload = false;
const gotTheLock = app.requestSingleInstanceLock();
if (!gotTheLock) {
app.exit();
}
// SharedArrayBuffer: Required for downloader (@ffmpeg/core-mt)
// OverlayScrollbar: Required for overlay scrollbars
app.commandLine.appendSwitch('enable-features', 'OverlayScrollbar,SharedArrayBuffer');
if (config.get('options.disableHardwareAcceleration')) {
if (is.dev()) {
console.log('Disabling hardware acceleration');
}
app.disableHardwareAcceleration();
}
if (is.linux() && config.plugins.isEnabled('shortcuts')) {
// Stops chromium from launching its own MPRIS service
app.commandLine.appendSwitch('disable-features', 'MediaSessionService');
}
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
electronDebug({
showDevTools: false, // Disable automatic devTools on new window
});
let icon = 'assets/youtube-music.png';
if (process.platform === 'win32') {
icon = 'assets/generated/icon.ico';
} else if (process.platform === 'darwin') {
icon = 'assets/generated/icon.icns';
}
function onClosed() {
// Dereference the window
// For multiple Windows store them in an array
mainWindow = null;
}
const mainPlugins = {
'adblocker': adblocker,
'album-color-theme': albumColorTheme,
'ambient-mode': ambientMode,
'blur-nav-bar': blurNavigationBar,
'captions-selector': captionsSelector,
'crossfade': crossfade,
'discord': discord,
'downloader': downloader,
'in-app-menu': inAppMenu,
'last-fm': lastFm,
'lumiastream': lumiaStream,
'lyrics-genius': lyricsGenius,
'navigation': navigation,
'no-google-login': noGoogleLogin,
'notifications': notifications,
'picture-in-picture': pictureInPicture,
'precise-volume': preciseVolume,
'quality-changer': qualityChanger,
'shortcuts': shortcuts,
'sponsorblock': sponsorBlock,
'taskbar-mediacontrol': undefined as typeof taskbarMediaControl | undefined,
'touchbar': undefined as typeof touchbar | undefined,
'tuna-obs': tunaObs,
'video-toggle': videoToggle,
'visualizer': visualizer,
};
export const mainPluginNames = Object.keys(mainPlugins);
if (is.windows()) {
mainPlugins['taskbar-mediacontrol'] = taskbarMediaControl;
delete mainPlugins['touchbar'];
} else if (is.macOS()) {
mainPlugins['touchbar'] = touchbar;
delete mainPlugins['taskbar-mediacontrol'];
} else {
delete mainPlugins['touchbar'];
delete mainPlugins['taskbar-mediacontrol'];
}
ipcMain.handle('get-main-plugin-names', () => Object.keys(mainPlugins));
async function loadPlugins(win: BrowserWindow) {
injectCSS(win.webContents, youtubeMusicCSS);
// Load user CSS
const themes: string[] = config.get('options.themes');
if (Array.isArray(themes)) {
for (const cssFile of themes) {
fileExists(
cssFile,
() => {
injectCSSAsFile(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();
}
});
for (const [plugin, options] of config.plugins.getEnabled()) {
try {
if (Object.hasOwn(mainPlugins, plugin)) {
console.log('Loaded plugin - ' + plugin);
const handler = mainPlugins[plugin as keyof typeof mainPlugins];
if (handler) {
await handler(win, options as never);
}
}
} catch (e) {
console.error(`Failed to load plugin "${plugin}"`, e);
}
}
}
async function createMainWindow() {
const windowSize = config.get('window-size');
const windowMaximized = config.get('window-maximized');
const windowPosition: Electron.Point = config.get('window-position');
const useInlineMenu = config.plugins.isEnabled('in-app-menu');
const win = new BrowserWindow({
icon,
width: windowSize.width,
height: windowSize.height,
backgroundColor: '#000',
show: false,
webPreferences: {
// TODO: re-enable contextIsolation once it can work with FFMpeg.wasm
// Possible bundling? https://github.com/ffmpegwasm/ffmpeg.wasm/issues/126
contextIsolation: false,
preload: path.join(__dirname, 'preload.js'),
nodeIntegrationInSubFrames: true,
...(isTesting()
? undefined
: {
// Sandbox is only enabled in tests for now
// See https://www.electronjs.org/docs/latest/tutorial/sandbox#preload-scripts
sandbox: false,
}),
},
frame: !is.macOS() && !useInlineMenu,
titleBarOverlay: {
color: '#00000000',
symbolColor: '#ffffff',
height: 36,
},
titleBarStyle: useInlineMenu
? 'hidden'
: (is.macOS()
? 'hiddenInset'
: 'default'),
autoHideMenuBar: config.get('options.hideMenu'),
});
await loadPlugins(win);
if (windowPosition) {
const { x: windowX, y: windowY } = windowPosition;
const winSize = win.getSize();
const displaySize
= screen.getDisplayNearestPoint(windowPosition).bounds;
if (
windowX + winSize[0] < displaySize.x - 8
|| windowX - winSize[0] > displaySize.x + displaySize.width
|| windowY < displaySize.y - 8
|| windowY > displaySize.y + displaySize.height
) {
// Window is offscreen
if (is.dev()) {
console.log(
`Window tried to render offscreen, windowSize=${String(winSize)}, displaySize=${String(displaySize)}, position=${String(windowPosition)}`,
);
}
} else {
win.setPosition(windowX, windowY);
}
}
if (windowMaximized) {
win.maximize();
}
if (config.get('options.alwaysOnTop')) {
win.setAlwaysOnTop(true);
}
const urlToLoad = config.get('options.resumeOnStart')
? config.get('url')
: config.defaultConfig.url;
win.on('closed', onClosed);
type PiPOptions = typeof config.defaultConfig.plugins['picture-in-picture'];
const setPiPOptions = config.plugins.isEnabled('picture-in-picture')
// eslint-disable-next-line @typescript-eslint/no-var-requires
? (key: string, value: unknown) => pipSetOptions({ [key]: value })
: () => {};
win.on('move', () => {
if (win.isMaximized()) {
return;
}
const position = win.getPosition();
const isPiPEnabled: boolean
= config.plugins.isEnabled('picture-in-picture')
&& config.plugins.getOptions<PiPOptions>('picture-in-picture').isInPiP;
if (!isPiPEnabled) {
lateSave('window-position', { x: position[0], y: position[1] });
} else if (config.plugins.getOptions<PiPOptions>('picture-in-picture').savePosition) {
lateSave('pip-position', position, setPiPOptions);
}
});
let winWasMaximized: boolean;
win.on('resize', () => {
const windowSize = win.getSize();
const isMaximized = win.isMaximized();
const isPiPEnabled
= config.plugins.isEnabled('picture-in-picture')
&& config.plugins.getOptions<PiPOptions>('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<PiPOptions>('picture-in-picture').saveSize) {
lateSave('pip-size', windowSize, setPiPOptions);
}
});
const savedTimeouts: Record<string, NodeJS.Timeout | undefined> = {};
function lateSave(key: string, value: unknown, fn: (key: string, value: unknown) => void = config.set) {
if (savedTimeouts[key]) {
clearTimeout(savedTimeouts[key]);
}
savedTimeouts[key] = setTimeout(() => {
fn(key, value);
savedTimeouts[key] = undefined;
}, 600);
}
app.on('render-process-gone', (event, webContents, details) => {
showUnresponsiveDialog(win, details);
});
win.once('ready-to-show', () => {
if (config.get('options.appVisible')) {
win.show();
}
});
removeContentSecurityPolicy();
win.webContents.loadURL(urlToLoad);
return win;
}
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);
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 (errorCode !== -3) { // -3 is a false positive
win.webContents.send('log', log);
win.webContents.loadFile(path.join(__dirname, 'error.html'));
}
});
win.webContents.on('will-prevent-unload', (event) => {
event.preventDefault();
});
});
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
// Unregister all shortcuts.
globalShortcut.unregisterAll();
});
app.on('activate', async () => {
// On OS X it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
mainWindow = await createMainWindow();
} else if (!mainWindow.isVisible()) {
mainWindow.show();
}
});
app.on('ready', async () => {
if (config.get('options.autoResetAppCache')) {
// Clear cache after 20s
const clearCacheTimeout = setTimeout(() => {
if (is.dev()) {
console.log('Clearing app cache.');
}
session.defaultSession.clearCache();
clearTimeout(clearCacheTimeout);
}, 20_000);
}
// 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 = 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
shell.writeShortcutLink(
shortcutPath,
error === 'needUpdate' ? 'update' : 'create',
{
target: appLocation,
cwd: path.dirname(appLocation),
description: 'YouTube Music Desktop App - including custom plugins',
appUserModelId: appID,
},
);
}
}
}
mainWindow = await createMainWindow();
setApplicationMenu(mainWindow);
refreshMenu(mainWindow);
setUpTray(app, mainWindow);
setupProtocolHandler(mainWindow);
app.on('second-instance', (_, commandLine) => {
const uri = `${APP_PROTOCOL}://`;
const protocolArgv = commandLine.find((arg) => arg.startsWith(uri));
if (protocolArgv) {
const lastIndex = protocolArgv.endsWith('/') ? -1 : undefined;
const command = protocolArgv.slice(uri.length, lastIndex);
if (is.dev()) {
console.debug(`Received command over protocol: "${command}"`);
}
handleProtocol(command);
return;
}
if (!mainWindow) {
return;
}
if (mainWindow.isMinimized()) {
mainWindow.restore();
}
if (!mainWindow.isVisible()) {
mainWindow.show();
}
mainWindow.focus();
});
// Autostart at login
app.setLoginItemSettings({
openAtLogin: config.get('options.startAtLogin'),
});
if (!is.dev() && config.get('options.autoUpdates')) {
const updateTimeout = setTimeout(() => {
autoUpdater.checkForUpdatesAndNotify();
clearTimeout(updateTimeout);
}, 2000);
autoUpdater.on('update-available', () => {
const downloadLink
= 'https://github.com/th-ch/youtube-music/releases/latest';
const dialogOptions: Electron.MessageBoxOptions = {
type: 'info',
buttons: ['OK', 'Download', 'Disable updates'],
title: 'Application Update',
message: 'A new version is available',
detail: `A new version is available and can be downloaded at ${downloadLink}`,
};
dialog.showMessageBox(dialogOptions).then((dialogOutput) => {
switch (dialogOutput.response) {
// Download
case 1: {
shell.openExternal(downloadLink);
break;
}
// Disable updates
case 2: {
config.set('options.autoUpdates', false);
break;
}
default: {
break;
}
}
});
});
}
if (config.get('options.hideMenu') && !config.get('options.hideMenuWarned')) {
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);
}
// Optimized for Mac OS X
if (is.macOS() && !config.get('options.appVisible')) {
app.dock.hide();
}
let forceQuit = false;
app.on('before-quit', () => {
forceQuit = true;
});
if (is.macOS() || config.get('options.tray')) {
mainWindow.on('close', (event) => {
// Hide the window instead of quitting (quit is available in tray options)
if (!forceQuit) {
event.preventDefault();
mainWindow!.hide();
}
});
}
});
function showUnresponsiveDialog(win: BrowserWindow, details: Electron.RenderProcessGoneDetails) {
if (details) {
console.log('Unresponsive Error!\n' + JSON.stringify(details, null, '\t'));
}
dialog.showMessageBox(win, {
type: 'error',
title: 'Window Unresponsive',
message: 'The Application is Unresponsive',
detail: '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(
betterSession: BetterSession = session.defaultSession as BetterSession,
) {
// Allows defining multiple "onHeadersReceived" listeners
// by enhancing the session.
// Some plugins (e.g. adblocker) also define a "onHeadersReceived" listener
enhanceWebRequest(betterSession);
// Custom listener to tweak the content security policy
betterSession.webRequest.onHeadersReceived((details, callback) => {
details.responseHeaders ??= {};
// Remove the content security policy
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
betterSession.webRequest.setResolver('onHeadersReceived', async (listeners) => {
return listeners.reduce(
async (accumulator, listener) => {
const acc = await accumulator;
if (acc.cancel) {
return acc;
}
const result = await listener.apply();
return { ...accumulator, ...result };
},
Promise.resolve({ cancel: false }),
);
});
}

474
menu.ts
View File

@ -1,474 +0,0 @@
import is from 'electron-is';
import { app, BrowserWindow, clipboard, dialog, Menu } from 'electron';
import prompt from 'custom-electron-prompt';
import { restart } from './providers/app-controls';
import config from './config';
import { startingPages } from './providers/extracted-data';
import promptOptions from './providers/prompt-options';
import adblockerMenu from './plugins/adblocker/menu';
import captionsSelectorMenu from './plugins/captions-selector/menu';
import crossfadeMenu from './plugins/crossfade/menu';
import disableAutoplayMenu from './plugins/disable-autoplay/menu';
import discordMenu from './plugins/discord/menu';
import downloaderMenu from './plugins/downloader/menu';
import lyricsGeniusMenu from './plugins/lyrics-genius/menu';
import notificationsMenu from './plugins/notifications/menu';
import pictureInPictureMenu from './plugins/picture-in-picture/menu';
import preciseVolumeMenu from './plugins/precise-volume/menu';
import shortcutsMenu from './plugins/shortcuts/menu';
import videoToggleMenu from './plugins/video-toggle/menu';
import visualizerMenu from './plugins/visualizer/menu';
import { getAvailablePluginNames } from './plugins/utils';
export type MenuTemplate = Electron.MenuItemConstructorOptions[];
// True only if in-app-menu was loaded on launch
const inAppMenuActive = config.plugins.isEnabled('in-app-menu');
const betaPlugins = ['crossfade', 'lumiastream'];
const pluginMenus = {
'adblocker': adblockerMenu,
'disable-autoplay': disableAutoplayMenu,
'captions-selector': captionsSelectorMenu,
'crossfade': crossfadeMenu,
'discord': discordMenu,
'downloader': downloaderMenu,
'lyrics-genius': lyricsGeniusMenu,
'notifications': notificationsMenu,
'picture-in-picture': pictureInPictureMenu,
'precise-volume': preciseVolumeMenu,
'shortcuts': shortcutsMenu,
'video-toggle': videoToggleMenu,
'visualizer': visualizerMenu,
};
const pluginEnabledMenu = (plugin: string, label = '', hasSubmenu = false, refreshMenu: (() => void ) | undefined = undefined): Electron.MenuItemConstructorOptions => ({
label: label || plugin,
type: 'checkbox',
checked: config.plugins.isEnabled(plugin),
click(item: Electron.MenuItem) {
if (item.checked) {
config.plugins.enable(plugin);
} else {
config.plugins.disable(plugin);
}
if (hasSubmenu) {
refreshMenu?.();
}
},
});
export const refreshMenu = (win: BrowserWindow) => {
setApplicationMenu(win);
if (inAppMenuActive) {
win.webContents.send('refreshMenu');
}
};
export const mainMenuTemplate = (win: BrowserWindow): MenuTemplate => {
const innerRefreshMenu = () => refreshMenu(win);
return [
{
label: 'Plugins',
submenu:
getAvailablePluginNames().map((pluginName) => {
let pluginLabel = pluginName;
if (betaPlugins.includes(pluginLabel)) {
pluginLabel += ' [beta]';
}
if (Object.hasOwn(pluginMenus, pluginName)) {
const getPluginMenu = pluginMenus[pluginName as keyof typeof pluginMenus];
if (!config.plugins.isEnabled(pluginName)) {
return pluginEnabledMenu(pluginName, pluginLabel, true, innerRefreshMenu);
}
return {
label: pluginLabel,
submenu: [
pluginEnabledMenu(pluginName, 'Enabled', true, innerRefreshMenu),
{ type: 'separator' },
...getPluginMenu(win, config.plugins.getOptions(pluginName), innerRefreshMenu),
],
} satisfies Electron.MenuItemConstructorOptions;
}
return pluginEnabledMenu(pluginName, pluginLabel);
}),
},
{
label: 'Options',
submenu: [
{
label: 'Auto-update',
type: 'checkbox',
checked: config.get('options.autoUpdates'),
click(item) {
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: 'Starting page',
submenu: (() => {
const subMenuArray: Electron.MenuItemConstructorOptions[] = Object.keys(startingPages).map((name) => ({
label: name,
type: 'radio',
checked: config.get('options.startingPage') === name,
click() {
config.set('options.startingPage', name);
},
}));
subMenuArray.unshift({
label: 'Unset',
type: 'radio',
checked: config.get('options.startingPage') === '',
click() {
config.set('options.startingPage', '');
},
});
return subMenuArray;
})(),
},
{
label: 'Visual Tweaks',
submenu: [
{
label: 'Remove upgrade button',
type: 'checkbox',
checked: config.get('options.removeUpgradeButton'),
click(item) {
config.setMenuOption('options.removeUpgradeButton', item.checked);
},
},
{
label: 'Like buttons',
submenu: [
{
label: 'Default',
type: 'radio',
checked: !config.get('options.likeButtons'),
click() {
config.set('options.likeButtons', '');
},
},
{
label: 'Force show',
type: 'radio',
checked: config.get('options.likeButtons') === 'force',
click() {
config.set('options.likeButtons', 'force');
},
},
{
label: 'Hide',
type: 'radio',
checked: config.get('options.likeButtons') === 'hide',
click() {
config.set('options.likeButtons', 'hide');
},
},
],
},
{
label: 'Theme',
submenu: [
{
label: 'No theme',
type: 'radio',
checked: config.get('options.themes')?.length === 0, // Todo rename "themes"
click() {
config.set('options.themes', []);
},
},
{ type: 'separator' },
{
label: 'Import custom CSS file',
type: 'normal',
async click() {
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: true,
click(item) {
if (!item.checked && app.hasSingleInstanceLock()) {
app.releaseSingleInstanceLock();
} else if (item.checked && !app.hasSingleInstanceLock()) {
app.requestSingleInstanceLock();
}
},
},
{
label: 'Always on top',
type: 'checkbox',
checked: config.get('options.alwaysOnTop'),
click(item) {
config.setMenuOption('options.alwaysOnTop', item.checked);
win.setAlwaysOnTop(item.checked);
},
},
...(is.windows() || is.linux()
? [
{
label: 'Hide menu',
type: 'checkbox',
checked: config.get('options.hideMenu'),
click(item) {
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 backtick [`] if using in-app-menu)',
});
}
},
},
]
: []) satisfies Electron.MenuItemConstructorOptions[],
...(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.setMenuOption('options.startAtLogin', item.checked);
},
},
]
: []) satisfies Electron.MenuItemConstructorOptions[],
{
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.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.setMenuOption('options.tray', true);
config.setMenuOption('options.appVisible', false);
},
},
{ type: 'separator' },
{
label: 'Play/Pause on click',
type: 'checkbox',
checked: config.get('options.trayClickPlayPause'),
click(item) {
config.setMenuOption('options.trayClickPlayPause', item.checked);
},
},
],
},
{ type: 'separator' },
{
label: 'Advanced options',
submenu: [
{
label: 'Set Proxy',
type: 'normal',
async click(item) {
await 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 {
webContents.openDevTools();
}
},
}
: { role: 'toggleDevTools' },
{
label: 'Edit config.json',
click() {
config.edit();
},
},
],
},
],
},
{
label: 'View',
submenu: [
{ role: 'reload' },
{ role: 'forceReload' },
{ type: 'separator' },
{ role: 'zoomIn', accelerator: process.platform === 'darwin' ? 'Cmd+I' : 'Ctrl+I' },
{ role: 'zoomOut', accelerator: process.platform === 'darwin' ? 'Cmd+O' : 'Ctrl+O' },
{ 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: 'Copy current URL',
click() {
const currentURL = win.webContents.getURL();
clipboard.writeText(currentURL);
},
},
{
label: 'Restart App',
click: restart,
},
{ role: 'quit' },
],
},
];
};
export const setApplicationMenu = (win: Electron.BrowserWindow) => {
const menuTemplate: MenuTemplate = [...mainMenuTemplate(win)];
if (process.platform === 'darwin') {
const { name } = app;
menuTemplate.unshift({
label: name,
submenu: [
{ role: 'about' },
{ type: 'separator' },
{ role: 'hide' },
{ role: 'hideOthers' },
{ role: 'unhide' },
{ type: 'separator' },
{ role: 'selectAll' },
{ role: 'cut' },
{ role: 'copy' },
{ role: 'paste' },
{ type: 'separator' },
{ role: 'minimize' },
{ role: 'close' },
{ role: 'quit' },
],
});
}
const menu = Menu.buildFromTemplate(menuTemplate);
Menu.setApplicationMenu(menu);
};
async function setProxy(item: Electron.MenuItem, win: BrowserWindow) {
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
}
}

10137
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,9 @@
{
"name": "youtube-music",
"productName": "YouTube Music",
"version": "2.1.0",
"version": "3.5.3",
"description": "YouTube Music Desktop App - including custom plugins",
"main": "./dist/index.js",
"main": "./dist/main/index.js",
"license": "MIT",
"repository": "th-ch/youtube-music",
"author": {
@ -17,6 +17,7 @@
"files": [
"!*",
"dist",
"assets",
"license",
"!node_modules",
"node_modules/custom-electron-prompt/**",
@ -25,6 +26,9 @@
"!node_modules/**/*.map",
"!node_modules/**/*.ts"
],
"asarUnpack": [
"assets"
],
"mac": {
"identity": null,
"target": [
@ -73,6 +77,29 @@
"rpm"
]
},
"deb": {
"depends": [
"libgtk-3-0",
"libnotify4",
"libnss3",
"libxss1",
"libxtst6",
"xdg-utils",
"libatspi2.0-0",
"libuuid1",
"libasound2",
"libgbm1"
]
},
"rpm": {
"depends": [
"/usr/lib64/libuuid.so.1"
],
"fpm": [
"--rpm-rpmbuild-define",
"_build_id_links none"
]
},
"snap": {
"slots": [
{
@ -87,101 +114,135 @@
}
},
"scripts": {
"test": "npm run build && playwright test",
"test:debug": "DEBUG=pw:browser* npm run build && playwright test",
"rollup:preload": "rollup -c rollup.preload.config.ts --configPlugin @rollup/plugin-typescript --bundleConfigAsCjs",
"rollup:main": "rollup -c rollup.main.config.ts --configPlugin @rollup/plugin-typescript --bundleConfigAsCjs",
"build": "npm run rollup:preload && npm run rollup:main",
"start": "npm run build && electron ./dist/index.js",
"start:debug": "ELECTRON_ENABLE_LOGGING=1 npm run start",
"postinstall": "patch-package",
"clean": "del-cli dist && del-cli pack",
"dist": "npm run clean && npm run build && electron-builder --win --mac --linux -p never",
"dist:linux": "npm run clean && npm run build && electron-builder --linux -p never",
"dist:mac": "npm run clean && npm run build && electron-builder --mac dmg:x64 -p never",
"dist:mac:arm64": "npm run clean && npm run build && electron-builder --mac dmg:arm64 -p never",
"dist:win": "npm run clean && npm run build && electron-builder --win -p never",
"dist:win:x64": "npm run clean && npm run build && electron-builder --win nsis-web:x64 -p never",
"test": "playwright test",
"test:debug": "cross-env DEBUG=pw:*,-pw:test:protocol playwright test",
"build": "electron-vite build",
"vite:inspect": "pnpm clean && electron-vite build --mode development && pnpm exec serve .vite-inspect",
"start": "electron-vite preview",
"start:debug": "cross-env ELECTRON_ENABLE_LOGGING=1 pnpm start",
"dev": "cross-env NODE_OPTIONS=--enable-source-maps electron-vite dev --watch",
"dev:debug": "cross-env ELECTRON_ENABLE_LOGGING=1 pnpm dev",
"clean": "del-cli dist && del-cli pack && del-cli .vite-inspect",
"dist": "pnpm clean && pnpm build && pnpm electron-builder --win --mac --linux -p never",
"dist:linux": "pnpm clean && pnpm build && pnpm electron-builder --linux -p never",
"dist:linux:deb-arm64": "pnpm clean && pnpm build && pnpm electron-builder --linux deb:arm64 -p never",
"dist:linux:rpm-arm64": "pnpm clean && pnpm build && pnpm electron-builder --linux rpm:arm64 -p never",
"dist:mac": "pnpm clean && pnpm build && pnpm electron-builder --mac dmg:x64 -p never",
"dist:mac:arm64": "pnpm clean && pnpm build && pnpm electron-builder --mac dmg:arm64 -p never",
"dist:win": "pnpm clean && pnpm build && pnpm electron-builder --win -p never",
"dist:win:x64": "pnpm clean && pnpm build && pnpm electron-builder --win nsis-web:x64 -p never",
"lint": "eslint .",
"changelog": "auto-changelog",
"release:linux": "npm run clean && npm run build && electron-builder --linux -p always -c.snap.publish=github",
"release:mac": "npm run clean && npm run build && electron-builder --mac -p always",
"release:win": "npm run clean && npm run build && electron-builder --win -p always",
"changelog": "npx --yes auto-changelog",
"release:linux": "pnpm clean && pnpm build && pnpm electron-builder --linux -p always -c.snap.publish=github",
"release:mac": "pnpm clean && pnpm build && pnpm electron-builder --mac -p always",
"release:win": "pnpm clean && pnpm build && pnpm electron-builder --win -p always",
"typecheck": "tsc -p tsconfig.json --noEmit"
},
"engines": {
"node": ">=16.0.0"
"node": ">=18.0.0",
"pnpm": ">=8"
},
"pnpm": {
"overrides": {
"usocket": "1.0.1",
"node-gyp": "10.2.0",
"xml2js": "0.6.2",
"node-fetch": "3.3.2",
"@electron/universal": "2.0.1",
"@babel/runtime": "7.25.6"
},
"patchedDependencies": {
"vudio@2.1.1": "patches/vudio@2.1.1.patch",
"app-builder-lib@24.13.3": "patches/app-builder-lib@24.13.3.patch"
}
},
"dependencies": {
"@cliqz/adblocker-electron": "1.26.8",
"@cliqz/adblocker-electron": "1.27.1",
"@cliqz/adblocker-electron-preload": "1.27.1",
"@electron-toolkit/tsconfig": "1.0.1",
"@electron/remote": "2.1.2",
"@ffmpeg.wasm/core-mt": "0.12.0",
"@ffmpeg.wasm/main": "0.12.0",
"@foobar404/wave": "2.0.4",
"@floating-ui/dom": "1.6.11",
"@foobar404/wave": "2.0.5",
"@jellybrick/electron-better-web-request": "1.0.4",
"@jellybrick/mpris-service": "2.1.4",
"@xhayper/discord-rpc": "1.0.23",
"async-mutex": "0.4.0",
"@skyra/jaro-winkler": "^1.1.1",
"@xhayper/discord-rpc": "1.2.0",
"async-mutex": "0.5.0",
"butterchurn": "3.0.0-beta.4",
"butterchurn-presets": "3.0.0-beta.4",
"conf": "10.2.0",
"custom-electron-prompt": "1.5.7",
"electron-debug": "3.2.0",
"color": "4.2.3",
"conf": "13.0.1",
"custom-electron-prompt": "1.5.8",
"dbus-next": "0.10.2",
"deepmerge-ts": "7.1.0",
"electron-debug": "4.0.1",
"electron-is": "3.0.0",
"electron-localshortcut": "3.2.1",
"electron-store": "8.1.0",
"electron-store": "10.0.0",
"electron-unhandled": "4.0.1",
"electron-updater": "6.1.4",
"electron-updater": "6.3.4",
"fast-average-color": "9.4.0",
"fast-equals": "5.0.1",
"filenamify": "6.0.0",
"howler": "2.2.4",
"html-to-text": "9.0.5",
"i18next": "23.15.1",
"keyboardevent-from-electron-accelerator": "2.0.0",
"keyboardevents-areequal": "0.2.2",
"node-html-parser": "6.1.13",
"node-id3": "0.2.6",
"simple-youtube-age-restriction-bypass": "git+https://github.com/organization/Simple-YouTube-Age-Restriction-Bypass.git#v2.5.8",
"peerjs": "1.5.4",
"semver": "7.6.3",
"serve": "14.2.3",
"simple-youtube-age-restriction-bypass": "github:organization/Simple-YouTube-Age-Restriction-Bypass#v2.5.9",
"solid-floating-ui": "0.3.1",
"solid-js": "1.8.22",
"solid-styled-components": "0.28.5",
"solid-transition-group": "0.2.3",
"ts-morph": "23.0.0",
"vudio": "2.1.1",
"x11": "2.3.0",
"youtubei.js": "6.4.1",
"ytpl": "2.3.0"
},
"overrides": {
"rollup": "4.0.2",
"node-gyp": "9.4.0",
"xml2js": "0.6.2",
"node-fetch": "2.7.0",
"@electron/universal": "1.4.2",
"@babel/runtime": "7.23.2"
"youtubei.js": "10.4.0"
},
"devDependencies": {
"@playwright/test": "1.39.0",
"@rollup/plugin-commonjs": "25.0.5",
"@rollup/plugin-image": "3.0.3",
"@rollup/plugin-json": "6.0.1",
"@rollup/plugin-node-resolve": "15.2.3",
"@rollup/plugin-terser": "0.4.4",
"@rollup/plugin-typescript": "11.1.5",
"@rollup/plugin-wasm": "6.2.2",
"@total-typescript/ts-reset": "0.5.1",
"@types/electron-localshortcut": "3.1.1",
"@types/howler": "2.2.9",
"@types/html-to-text": "9.0.2",
"@typescript-eslint/eslint-plugin": "6.7.5",
"auto-changelog": "2.4.0",
"@playwright/test": "1.47.1",
"@total-typescript/ts-reset": "0.6.1",
"@types/color": "3.0.6",
"@types/electron-localshortcut": "3.1.3",
"@types/howler": "2.2.11",
"@types/html-to-text": "9.0.4",
"@types/semver": "7.5.8",
"@types/trusted-types": "2.0.7",
"@typescript-eslint/eslint-plugin": "8.6.0",
"@typescript-eslint/parser": "8.6.0",
"bufferutil": "4.0.8",
"builtin-modules": "4.0.0",
"cross-env": "7.0.3",
"del-cli": "5.1.0",
"electron": "27.0.0",
"electron-builder": "24.6.4",
"discord-api-types": "0.37.100",
"electron": "32.1.0",
"electron-builder": "24.13.3",
"electron-devtools-installer": "3.2.0",
"eslint": "8.51.0",
"eslint-plugin-import": "2.28.1",
"eslint-plugin-prettier": "5.0.1",
"node-gyp": "9.4.0",
"patch-package": "8.0.0",
"playwright": "1.39.0",
"rollup": "4.0.2",
"rollup-plugin-copy": "3.5.0",
"rollup-plugin-import-css": "3.3.5",
"rollup-plugin-string": "3.0.0",
"typescript": "5.2.2"
"electron-vite": "2.3.0",
"esbuild": "0.23.1",
"eslint": "8.57.1",
"eslint-import-resolver-exports": "1.0.0-beta.5",
"eslint-import-resolver-typescript": "3.6.3",
"eslint-plugin-import": "2.30.0",
"eslint-plugin-prettier": "5.2.1",
"glob": "11.0.0",
"node-gyp": "10.2.0",
"playwright": "1.47.1",
"rollup": "4.21.3",
"typescript": "5.6.2",
"utf-8-validate": "6.0.4",
"vite": "5.4.6",
"vite-plugin-inspect": "0.8.7",
"vite-plugin-resolve": "2.5.2",
"vite-plugin-solid": "2.10.2",
"ws": "8.18.0"
},
"auto-changelog": {
"hideCredit": true,

View File

@ -0,0 +1,21 @@
diff --git a/out/targets/snap.js b/out/targets/snap.js
index f72c36355d27cd2d69fc5fdf2d8bb2451db0287f..baae112fe25ebb49ab8e25aaa48efd6bc43b598f 100644
--- a/out/targets/snap.js
+++ b/out/targets/snap.js
@@ -212,14 +212,14 @@ class SnapTarget extends core_1.Target {
args.push("--template-url", `electron4:${snapArch}`);
}
await (0, builder_util_1.executeAppBuilder)(args);
- const publishConfig = findSnapPublishConfig(this.packager.config);
+
await packager.info.callArtifactBuildCompleted({
file: artifactPath,
safeArtifactName: packager.computeSafeArtifactName(artifactName, "snap", arch, false),
target: this,
arch,
packager,
- publishConfig: publishConfig == null ? { provider: "snapStore" } : publishConfig,
+ publishConfig: options.publish == null ? { provider: "snapStore" } : null,
});
}
isElectronVersionGreaterOrEqualThan(version) {

View File

@ -0,0 +1,161 @@
diff --git a/lib/importDeclaration.js b/lib/importDeclaration.js
index afb4de779034cfea080825a5f4320661c48bee32..f10b0a11a39577fbd42569e6b0e768255c1ef276 100644
--- a/lib/importDeclaration.js
+++ b/lib/importDeclaration.js
@@ -1,5 +1,5 @@
-"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports["default"] = importDeclaration;function importDeclaration(context) {
- var ancestors = context.getAncestors();
+"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports["default"] = importDeclaration;function importDeclaration(context, node) {
+ var ancestors = context.getSourceCode().getAncestors(node);
return ancestors[ancestors.length - 1];
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9pbXBvcnREZWNsYXJhdGlvbi5qcyJdLCJuYW1lcyI6WyJpbXBvcnREZWNsYXJhdGlvbiIsImNvbnRleHQiLCJhbmNlc3RvcnMiLCJnZXRBbmNlc3RvcnMiLCJsZW5ndGgiXSwibWFwcGluZ3MiOiJnR0FBd0JBLGlCLENBQVQsU0FBU0EsaUJBQVQsQ0FBMkJDLE9BQTNCLEVBQW9DO0FBQ2pELE1BQU1DLFlBQVlELFFBQVFFLFlBQVIsRUFBbEI7QUFDQSxTQUFPRCxVQUFVQSxVQUFVRSxNQUFWLEdBQW1CLENBQTdCLENBQVA7QUFDRCIsImZpbGUiOiJpbXBvcnREZWNsYXJhdGlvbi5qcyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGltcG9ydERlY2xhcmF0aW9uKGNvbnRleHQpIHtcbiAgY29uc3QgYW5jZXN0b3JzID0gY29udGV4dC5nZXRBbmNlc3RvcnMoKTtcbiAgcmV0dXJuIGFuY2VzdG9yc1thbmNlc3RvcnMubGVuZ3RoIC0gMV07XG59XG4iXX0=
\ No newline at end of file
diff --git a/lib/rules/first.js b/lib/rules/first.js
index a77168660cf32c8c3e96f3ff4b8240a36d7de3a6..c0e00d75f9989916057fef3999eeee8d21820292 100644
--- a/lib/rules/first.js
+++ b/lib/rules/first.js
@@ -66,7 +66,7 @@ module.exports = {
}
}
if (nonImportCount > 0) {var _iteratorNormalCompletion = true;var _didIteratorError = false;var _iteratorError = undefined;try {
- for (var _iterator = context.getDeclaredVariables(node)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {var variable = _step.value;
+ for (var _iterator = sourceCode.getDeclaredVariables(node)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {var variable = _step.value;
if (!shouldSort) {break;}
var references = variable.references;
if (references.length) {var _iteratorNormalCompletion2 = true;var _didIteratorError2 = false;var _iteratorError2 = undefined;try {
diff --git a/lib/rules/namespace.js b/lib/rules/namespace.js
index 574d89a60d15c7e0e712956ea6a3ad2d0eac7f08..82e7cb3cff4246592d762cce86323f2b72de92e4 100644
--- a/lib/rules/namespace.js
+++ b/lib/rules/namespace.js
@@ -86,7 +86,7 @@ module.exports = {
// same as above, but does not add names to local map
ExportNamespaceSpecifier: function () {function ExportNamespaceSpecifier(namespace) {
- var declaration = (0, _importDeclaration2['default'])(context);
+ var declaration = (0, _importDeclaration2['default'])(context, namespace);
var imports = _ExportMap2['default'].get(declaration.source.value, context);
if (imports == null) {return null;}
diff --git a/lib/rules/newline-after-import.js b/lib/rules/newline-after-import.js
index 6cc15686464a17803a0b976c35b99627cdbfabee..520eec6d9a375527ab72c459960fe4416c046c17 100644
--- a/lib/rules/newline-after-import.js
+++ b/lib/rules/newline-after-import.js
@@ -194,7 +194,7 @@ module.exports = {
}return CallExpression;}(),
'Program:exit': function () {function ProgramExit() {
log('exit processing for', context.getPhysicalFilename ? context.getPhysicalFilename() : context.getFilename());
- var scopeBody = getScopeBody(context.getScope());
+ var scopeBody = getScopeBody(context.getSourceCode().getScope(node));
log('got scope:', scopeBody);
requireCalls.forEach(function (node, index) {
diff --git a/lib/rules/no-amd.js b/lib/rules/no-amd.js
index 7ac108bf812ca4f78bfa6fe5ae8b9cf38e2ff497..346c3105dc70f72c4d76fcc6b96b946d1d4ec6d5 100644
--- a/lib/rules/no-amd.js
+++ b/lib/rules/no-amd.js
@@ -23,7 +23,7 @@ module.exports = {
create: function () {function create(context) {
return {
CallExpression: function () {function CallExpression(node) {
- if (context.getScope().type !== 'module') {return;}
+ if (context.getSourceCode().getScope(node).type !== 'module') {return;}
if (node.callee.type !== 'Identifier') {return;}
if (node.callee.name !== 'require' && node.callee.name !== 'define') {return;}
diff --git a/lib/rules/no-commonjs.js b/lib/rules/no-commonjs.js
index befeff0026d61d3ac1e6bbcea29f5c471dc1d353..e91c5ed34e968d5867e884ea800e166cda345aef 100644
--- a/lib/rules/no-commonjs.js
+++ b/lib/rules/no-commonjs.js
@@ -107,7 +107,7 @@ module.exports = {
// exports.
if (node.object.name === 'exports') {
- var isInScope = context.getScope().
+ var isInScope = context.getSourceCode().getScope(node).
variables.
some(function (variable) {return variable.name === 'exports';});
if (!isInScope) {
@@ -117,7 +117,7 @@ module.exports = {
}return MemberExpression;}(),
CallExpression: function () {function CallExpression(call) {
- if (!validateScope(context.getScope())) {return;}
+ if (!validateScope(context.getSourceCode().getScope(call))) {return;}
if (call.callee.type !== 'Identifier') {return;}
if (call.callee.name !== 'require') {return;}
diff --git a/lib/rules/no-mutable-exports.js b/lib/rules/no-mutable-exports.js
index 40bd1b4cfa95d41732bb13bba0ed1969a91cc7ff..8a25abfbfadb299204b36a6cbf283259bcc2e790 100644
--- a/lib/rules/no-mutable-exports.js
+++ b/lib/rules/no-mutable-exports.js
@@ -32,7 +32,7 @@ module.exports = {
}
function handleExportDefault(node) {
- var scope = context.getScope();
+ var scope = context.getSourceCode().getScope(node);
if (node.declaration.name) {
checkDeclarationsInScope(scope, node.declaration.name);
@@ -40,7 +40,7 @@ module.exports = {
}
function handleExportNamed(node) {
- var scope = context.getScope();
+ var scope = context.getSourceCode().getScope(node);
if (node.declaration) {
checkDeclaration(node.declaration);
diff --git a/lib/rules/no-named-as-default-member.js b/lib/rules/no-named-as-default-member.js
index 0c15051e027ad7d1d45f1b51c20be1c000b0af01..5b3d6ba415511b7f9f83a52e1acfebe5a1045a7b 100644
--- a/lib/rules/no-named-as-default-member.js
+++ b/lib/rules/no-named-as-default-member.js
@@ -35,7 +35,7 @@ module.exports = {
return {
ImportDefaultSpecifier: function () {function ImportDefaultSpecifier(node) {
- var declaration = (0, _importDeclaration2['default'])(context);
+ var declaration = (0, _importDeclaration2['default'])(context, node);
var exportMap = _ExportMap2['default'].get(declaration.source.value, context);
if (exportMap == null) {return;}
diff --git a/lib/rules/no-named-as-default.js b/lib/rules/no-named-as-default.js
index 63378a33a1c7da004c57a524cec1a1cddf23e210..c81b1f93b11628676158b79f1c4015911943cc7d 100644
--- a/lib/rules/no-named-as-default.js
+++ b/lib/rules/no-named-as-default.js
@@ -18,7 +18,7 @@ module.exports = {
// #566: default is a valid specifier
if (defaultSpecifier[nameKey].name === 'default') {return;}
- var declaration = (0, _importDeclaration2['default'])(context);
+ var declaration = (0, _importDeclaration2['default'])(context, defaultSpecifier);
var imports = _ExportMap2['default'].get(declaration.source.value, context);
if (imports == null) {return;}
diff --git a/lib/rules/no-namespace.js b/lib/rules/no-namespace.js
index 2b0c783adea788101b779b17f977bbcb582cfd3f..a7f7b202ac7c4a342febef2a993586c4cc84fc7a 100644
--- a/lib/rules/no-namespace.js
+++ b/lib/rules/no-namespace.js
@@ -43,7 +43,7 @@ var _docsUrl = require('../docsUrl');var _docsUrl2 = _interopRequireDefault(_doc
return;
}
- var scopeVariables = context.getScope().variables;
+ var scopeVariables = context.getSourceCode().getScope(node).variables;
var namespaceVariable = scopeVariables.find(function (variable) {return variable.defs[0].node === node;});
var namespaceReferences = namespaceVariable.references;
var namespaceIdentifiers = namespaceReferences.map(function (reference) {return reference.identifier;});
diff --git a/package.json b/package.json
index 5c0af48543483a21791fa23a4a583071d3551772..5deeac3d0accc3878ef0fc93dfb52a8ca7c46e84 100644
--- a/package.json
+++ b/package.json
@@ -72,7 +72,7 @@
"chai": "^4.3.10",
"cross-env": "^4.0.0",
"escope": "^3.6.0",
- "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8",
+ "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9",
"eslint-doc-generator": "^1.6.1",
"eslint-import-resolver-node": "file:./resolvers/node",
"eslint-import-resolver-typescript": "^1.0.2 || ^1.1.1",

20
patches/vudio@2.1.1.patch Normal file
View File

@ -0,0 +1,20 @@
diff --git a/umd/vudio.js b/umd/vudio.js
index d0d1127e57125ad4e77442af2db4a26998c7b385..c0b66bd4327c65c31dc6e588bfa4ae6ec70bd3b8 100644
--- a/umd/vudio.js
+++ b/umd/vudio.js
@@ -147,7 +147,6 @@
source.connect(this.analyser);
this.analyser.fftSize = this.option.accuracy * 2;
- this.analyser.connect(audioContext.destination);
this.freqByteData = new Uint8Array(this.analyser.frequencyBinCount);
@@ -207,7 +206,6 @@
source.connect(this.analyser);
this.analyser.fftSize = this.option.accuracy * 2;
- this.analyser.connect(audioContext.destination);
},
__rebuildData : function (freqByteData, horizontalAlign) {

View File

@ -1,38 +0,0 @@
diff --git a/node_modules/youtubei.js/bundle/node.cjs b/node_modules/youtubei.js/bundle/node.cjs
index 7e3072e..bf5be6a 100644
--- a/node_modules/youtubei.js/bundle/node.cjs
+++ b/node_modules/youtubei.js/bundle/node.cjs
@@ -16969,7 +16969,13 @@ var _Cache_createCache;
var meta_url = import_meta.url;
var is_cjs = !meta_url;
var __dirname__ = is_cjs ? __dirname : import_path.default.dirname((0, import_url.fileURLToPath)(meta_url));
-var package_json = JSON.parse((0, import_fs.readFileSync)(import_path.default.resolve(__dirname__, is_cjs ? "../package.json" : "../../package.json"), "utf-8"));
+var package_json = {
+ homepage: "https://github.com/LuanRT/YouTube.js#readme",
+ version: "6.4.1",
+ bugs: {
+ url: "https://github.com/LuanRT/YouTube.js/issues"
+ }
+};
var repo_url = (_a3 = package_json.homepage) === null || _a3 === void 0 ? void 0 : _a3.split("#")[0];
var Cache = class {
constructor(persistent = false, persistent_directory) {
diff --git a/node_modules/youtubei.js/dist/src/platform/node.js b/node_modules/youtubei.js/dist/src/platform/node.js
index 0e1b2ca..17b437c 100644
--- a/node_modules/youtubei.js/dist/src/platform/node.js
+++ b/node_modules/youtubei.js/dist/src/platform/node.js
@@ -16,7 +16,13 @@ import evaluate from './jsruntime/jinter.js';
const meta_url = import.meta.url;
const is_cjs = !meta_url;
const __dirname__ = is_cjs ? __dirname : path.dirname(fileURLToPath(meta_url));
-const package_json = JSON.parse(readFileSync(path.resolve(__dirname__, is_cjs ? '../package.json' : '../../package.json'), 'utf-8'));
+const package_json = {
+ homepage: "https://github.com/LuanRT/YouTube.js#readme",
+ version: "6.4.1",
+ bugs: {
+ url: "https://github.com/LuanRT/YouTube.js/issues"
+ }
+};
const repo_url = (_a = package_json.homepage) === null || _a === void 0 ? void 0 : _a.split('#')[0];
class Cache {
constructor(persistent = false, persistent_directory) {

View File

@ -1,19 +0,0 @@
import { BrowserWindow } from 'electron';
import { loadAdBlockerEngine } from './blocker';
import { shouldUseBlocklists } from './config';
import type { ConfigType } from '../../config/dynamic';
type AdBlockOptions = ConfigType<'adblocker'>;
export default async (win: BrowserWindow, options: AdBlockOptions) => {
if (shouldUseBlocklists()) {
await loadAdBlockerEngine(
win.webContents.session,
options.cache,
options.additionalBlockLists,
options.disableDefaultLists,
);
}
};

View File

@ -1,72 +0,0 @@
// Used for caching
import path from 'node:path';
import fs, { promises } from 'node:fs';
import { ElectronBlocker } from '@cliqz/adblocker-electron';
import { app, net } from 'electron';
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',
'https://raw.githubusercontent.com/uBlockOrigin/uAssets/master/filters/filters-2022.txt',
'https://raw.githubusercontent.com/uBlockOrigin/uAssets/master/filters/filters-2023.txt',
// Fanboy Annoyances
'https://secure.fanboy.co.nz/fanboy-annoyance_ubo.txt',
];
export const loadAdBlockerEngine = async (
session: Electron.Session | undefined = undefined,
cache = true,
additionalBlockLists = [],
disableDefaultLists: boolean | unknown[] = false,
) => {
// Only use cache if no additional blocklists are passed
let cacheDirectory: string;
if (app.isPackaged) {
cacheDirectory = path.join(app.getPath('userData'), 'adblock_cache');
} else {
cacheDirectory = path.resolve(__dirname, 'adblock_cache');
}
if (!fs.existsSync(cacheDirectory)) {
fs.mkdirSync(cacheDirectory);
}
const cachingOptions
= cache && additionalBlockLists.length === 0
? {
path: path.join(cacheDirectory, 'adblocker-engine.bin'),
read: promises.readFile,
write: promises.writeFile,
}
: undefined;
const lists = [
...(
(disableDefaultLists && !Array.isArray(disableDefaultLists)) ||
(Array.isArray(disableDefaultLists) && disableDefaultLists.length > 0) ? [] : SOURCES
),
...additionalBlockLists,
];
try {
const blocker = await ElectronBlocker.fromLists(
(url: string) => net.fetch(url),
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,
);
if (session) {
blocker.enableBlockingInSession(session);
}
} catch (error) {
console.log('Error loading adBlocker engine', error);
}
};
export default { loadAdBlockerEngine };

View File

@ -1,15 +0,0 @@
/* eslint-disable @typescript-eslint/await-thenable */
/* renderer */
import { blockers } from './blocker-types';
import { PluginConfig } from '../../config/dynamic';
const config = new PluginConfig('adblocker', { enableFront: true });
export const shouldUseBlocklists = () => config.get('blocker') !== blockers.InPlayer;
export default Object.assign(config, {
shouldUseBlocklists,
blockers,
});

View File

@ -1,3 +0,0 @@
const inject: () => void;
export default inject;

View File

@ -1,435 +0,0 @@
/* eslint-disable */
// Source: https://addons.mozilla.org/en-US/firefox/addon/adblock-for-youtube/
// https://robwu.nl/crxviewer/?crx=https%3A%2F%2Faddons.mozilla.org%2Fen-US%2Ffirefox%2Faddon%2Fadblock-for-youtube%2F
/*
Parts of this code is derived from set-constant.js:
https://github.com/gorhill/uBlock/blob/5de0ce975753b7565759ac40983d31978d1f84ca/assets/resources/scriptlets.js#L704
*/
module.exports = () => {
{
const pruner = function (o) {
delete o.playerAds;
delete o.adPlacements;
//
if (o.playerResponse) {
delete o.playerResponse.playerAds;
delete o.playerResponse.adPlacements;
}
//
return o;
};
JSON.parse = new Proxy(JSON.parse, {
apply() {
return pruner(Reflect.apply(...arguments));
},
});
Response.prototype.json = new Proxy(Response.prototype.json, {
apply() {
return Reflect.apply(...arguments).then((o) => pruner(o));
},
});
}
(function () {
let cValue = 'undefined';
const chain = 'playerResponse.adPlacements';
const thisScript = document.currentScript;
//
switch (cValue) {
case 'null': {
cValue = null;
break;
}
case "''": {
cValue = '';
break;
}
case 'true': {
cValue = true;
break;
}
case 'false': {
cValue = false;
break;
}
case 'undefined': {
cValue = undefined;
break;
}
case 'noopFunc': {
cValue = function () {
};
break;
}
case 'trueFunc': {
cValue = function () {
return true;
};
break;
}
case 'falseFunc': {
cValue = function () {
return false;
};
break;
}
default: {
if (/^\d+$/.test(cValue)) {
cValue = Number.parseFloat(cValue);
//
if (isNaN(cValue)) {
return;
}
if (Math.abs(cValue) > 0x7F_FF) {
return;
}
} else {
return;
}
}
}
//
let aborted = false;
const mustAbort = function (v) {
if (aborted) {
return true;
}
aborted
= v !== undefined
&& v !== null
&& cValue !== undefined
&& cValue !== null
&& typeof v !== typeof cValue;
return aborted;
};
/*
Support multiple trappers for the same property:
https://github.com/uBlockOrigin/uBlock-issues/issues/156
*/
const trapProp = function (owner, prop, configurable, handler) {
if (handler.init(owner[prop]) === false) {
return;
}
//
const odesc = Object.getOwnPropertyDescriptor(owner, prop);
let previousGetter;
let previousSetter;
if (odesc instanceof Object) {
if (odesc.configurable === false) {
return;
}
if (odesc.get instanceof Function) {
previousGetter = odesc.get;
}
if (odesc.set instanceof Function) {
previousSetter = odesc.set;
}
}
//
Object.defineProperty(owner, prop, {
configurable,
get() {
if (previousGetter !== undefined) {
previousGetter();
}
//
return handler.getter();
},
set(a) {
if (previousSetter !== undefined) {
previousSetter(a);
}
//
handler.setter(a);
},
});
};
const trapChain = function (owner, chain) {
const pos = chain.indexOf('.');
if (pos === -1) {
trapProp(owner, chain, false, {
v: undefined,
getter() {
return document.currentScript === thisScript ? this.v : cValue;
},
setter(a) {
if (mustAbort(a) === false) {
return;
}
cValue = a;
},
init(v) {
if (mustAbort(v)) {
return false;
}
//
this.v = v;
return true;
},
});
//
return;
}
//
const prop = chain.slice(0, pos);
const v = owner[prop];
//
chain = chain.slice(pos + 1);
if (v instanceof Object || (typeof v === 'object' && v !== null)) {
trapChain(v, chain);
return;
}
//
trapProp(owner, prop, true, {
v: undefined,
getter() {
return this.v;
},
setter(a) {
this.v = a;
if (a instanceof Object) {
trapChain(a, chain);
}
},
init(v) {
this.v = v;
return true;
},
});
};
//
trapChain(window, chain);
})();
(function () {
let cValue = 'undefined';
const thisScript = document.currentScript;
const chain = 'ytInitialPlayerResponse.adPlacements';
//
switch (cValue) {
case 'null': {
cValue = null;
break;
}
case "''": {
cValue = '';
break;
}
case 'true': {
cValue = true;
break;
}
case 'false': {
cValue = false;
break;
}
case 'undefined': {
cValue = undefined;
break;
}
case 'noopFunc': {
cValue = function () {
};
break;
}
case 'trueFunc': {
cValue = function () {
return true;
};
break;
}
case 'falseFunc': {
cValue = function () {
return false;
};
break;
}
default: {
if (/^\d+$/.test(cValue)) {
cValue = Number.parseFloat(cValue);
//
if (isNaN(cValue)) {
return;
}
if (Math.abs(cValue) > 0x7F_FF) {
return;
}
} else {
return;
}
}
}
//
let aborted = false;
const mustAbort = function (v) {
if (aborted) {
return true;
}
aborted
= v !== undefined
&& v !== null
&& cValue !== undefined
&& cValue !== null
&& typeof v !== typeof cValue;
return aborted;
};
/*
Support multiple trappers for the same property:
https://github.com/uBlockOrigin/uBlock-issues/issues/156
*/
const trapProp = function (owner, prop, configurable, handler) {
if (handler.init(owner[prop]) === false) {
return;
}
//
const odesc = Object.getOwnPropertyDescriptor(owner, prop);
let previousGetter;
let previousSetter;
if (odesc instanceof Object) {
if (odesc.configurable === false) {
return;
}
if (odesc.get instanceof Function) {
previousGetter = odesc.get;
}
if (odesc.set instanceof Function) {
previousSetter = odesc.set;
}
}
//
Object.defineProperty(owner, prop, {
configurable,
get() {
if (previousGetter !== undefined) {
previousGetter();
}
//
return handler.getter();
},
set(a) {
if (previousSetter !== undefined) {
previousSetter(a);
}
//
handler.setter(a);
},
});
};
const trapChain = function (owner, chain) {
const pos = chain.indexOf('.');
if (pos === -1) {
trapProp(owner, chain, false, {
v: undefined,
getter() {
return document.currentScript === thisScript ? this.v : cValue;
},
setter(a) {
if (mustAbort(a) === false) {
return;
}
cValue = a;
},
init(v) {
if (mustAbort(v)) {
return false;
}
//
this.v = v;
return true;
},
});
//
return;
}
//
const prop = chain.slice(0, pos);
const v = owner[prop];
//
chain = chain.slice(pos + 1);
if (v instanceof Object || (typeof v === 'object' && v !== null)) {
trapChain(v, chain);
return;
}
//
trapProp(owner, prop, true, {
v: undefined,
getter() {
return this.v;
},
setter(a) {
this.v = a;
if (a instanceof Object) {
trapChain(a, chain);
}
},
init(v) {
this.v = v;
return true;
},
});
};
//
trapChain(window, chain);
})();
};

View File

@ -1,21 +0,0 @@
import config from './config';
import { blockers } from './blocker-types';
import { MenuTemplate } from '../../menu';
export default (): MenuTemplate => {
return [
{
label: 'Blocker',
submenu: Object.values(blockers).map((blocker: string) => ({
label: blocker,
type: 'radio',
checked: (config.get('blocker') || blockers.WithBlocklists) === blocker,
click() {
config.set('blocker', blocker);
},
})),
},
];
};

View File

@ -1,15 +0,0 @@
import config, { shouldUseBlocklists } from './config';
import inject from './inject';
import injectCliqzPreload from './inject-cliqz-preload';
import { blockers } from './blocker-types';
export default async () => {
if (shouldUseBlocklists()) {
// Preload adblocker to inject scripts/styles
await injectCliqzPreload();
// eslint-disable-next-line @typescript-eslint/await-thenable
} else if ((config.get('blocker')) === blockers.InPlayer) {
inject();
}
};

View File

@ -1,9 +0,0 @@
import { BrowserWindow } from 'electron';
import style from './style.css';
import { injectCSS } from '../utils';
export default (win: BrowserWindow) => {
injectCSS(win.webContents, style);
};

View File

@ -1,127 +0,0 @@
import { FastAverageColor } from 'fast-average-color';
import { ConfigType } from '../../config/dynamic';
function hexToHSL(H: string) {
// Convert hex to RGB first
let r = 0;
let g = 0;
let b = 0;
if (H.length == 4) {
r = Number('0x' + H[1] + H[1]);
g = Number('0x' + H[2] + H[2]);
b = Number('0x' + H[3] + H[3]);
} else if (H.length == 7) {
r = Number('0x' + H[1] + H[2]);
g = Number('0x' + H[3] + H[4]);
b = Number('0x' + H[5] + H[6]);
}
// Then to HSL
r /= 255;
g /= 255;
b /= 255;
const cmin = Math.min(r, g, b);
const cmax = Math.max(r, g, b);
const delta = cmax - cmin;
let h: number;
let s: number;
let l: number;
if (delta == 0) {
h = 0;
} else if (cmax == r) {
h = ((g - b) / delta) % 6;
} else if (cmax == g) {
h = ((b - r) / delta) + 2;
} else {
h = ((r - g) / delta) + 4;
}
h = Math.round(h * 60);
if (h < 0) {
h += 360;
}
l = (cmax + cmin) / 2;
s = delta == 0 ? 0 : delta / (1 - Math.abs((2 * l) - 1));
s = +(s * 100).toFixed(1);
l = +(l * 100).toFixed(1);
//return "hsl(" + h + "," + s + "%," + l + "%)";
return [h,s,l];
}
let hue = 0;
let saturation = 0;
let lightness = 0;
function changeElementColor(element: HTMLElement | null, hue: number, saturation: number, lightness: number){
if (element) {
element.style.backgroundColor = `hsl(${hue}, ${saturation}%, ${lightness}%)`;
}
}
export default (_: ConfigType<'album-color-theme'>) => {
// updated elements
const playerPage = document.querySelector<HTMLElement>('#player-page');
const navBarBackground = document.querySelector<HTMLElement>('#nav-bar-background');
const ytmusicPlayerBar = document.querySelector<HTMLElement>('ytmusic-player-bar');
const playerBarBackground = document.querySelector<HTMLElement>('#player-bar-background');
const sidebarBig = document.querySelector<HTMLElement>('#guide-wrapper');
const sidebarSmall = document.querySelector<HTMLElement>('#mini-guide-background');
const ytmusicAppLayout = document.querySelector<HTMLElement>('#layout');
const observer = new MutationObserver((mutationsList) => {
for (const mutation of mutationsList) {
if (mutation.type === 'attributes') {
const isPageOpen = ytmusicAppLayout?.hasAttribute('player-page-open');
if (isPageOpen) {
changeElementColor(sidebarSmall, hue, saturation, lightness - 30);
} else {
if (sidebarSmall) {
sidebarSmall.style.backgroundColor = 'black';
}
}
}
}
});
if (playerPage) {
observer.observe(playerPage, { attributes: true });
}
document.addEventListener('apiLoaded', (apiEvent) => {
const fastAverageColor = new FastAverageColor();
apiEvent.detail.addEventListener('videodatachange', (name: string) => {
if (name === 'dataloaded') {
const playerResponse = apiEvent.detail.getPlayerResponse();
const thumbnail = playerResponse?.videoDetails?.thumbnail?.thumbnails?.at(0);
if (thumbnail) {
fastAverageColor.getColorAsync(thumbnail.url)
.then((albumColor) => {
if (albumColor) {
[hue, saturation, lightness] = hexToHSL(albumColor.hex);
changeElementColor(playerPage, hue, saturation, lightness - 30);
changeElementColor(navBarBackground, hue, saturation, lightness - 15);
changeElementColor(ytmusicPlayerBar, hue, saturation, lightness - 15);
changeElementColor(playerBarBackground, hue, saturation, lightness - 15);
changeElementColor(sidebarBig, hue, saturation, lightness - 15);
if (ytmusicAppLayout?.hasAttribute('player-page-open')) {
changeElementColor(sidebarSmall, hue, saturation, lightness - 30);
}
const ytRightClickList = document.querySelector<HTMLElement>('tp-yt-paper-listbox');
changeElementColor(ytRightClickList, hue, saturation, lightness - 15);
} else {
if (playerPage) {
playerPage.style.backgroundColor = '#000000';
}
}
})
.catch((e) => console.error(e));
}
}
});
});
};

View File

@ -1,29 +0,0 @@
yt-page-navigation-progress {
--yt-page-navigation-container-color: #00000046 !important;
--yt-page-navigation-progress-color: white !important;
}
#player-page {
transition: transform 300ms,background-color 300ms cubic-bezier(0.2,0,0.6,1) !important;
}
#nav-bar-background {
transition: opacity 200ms,background-color 300ms cubic-bezier(0.2,0,0.6,1) !important;
}
#mini-guide-background {
transition: opacity 200ms,background-color 300ms cubic-bezier(0.2,0,0.6,1) !important;
border-right: 0px !important;
}
#guide-wrapper {
transition: opacity 200ms,background-color 300ms cubic-bezier(0.2,0,0.6,1) !important;
}
#img, #player, .song-media-controls.style-scope.ytmusic-player {
border-radius: 2% !important;
}
#items {
border-radius: 10px !important;
}

View File

@ -1,10 +0,0 @@
import { BrowserWindow } from 'electron';
import style from './style.css';
import { injectCSS } from '../utils';
export default (win: BrowserWindow) => {
injectCSS(win.webContents, style);
};

View File

@ -1,138 +0,0 @@
import { ConfigType } from '../../config/dynamic';
export default (_: ConfigType<'ambient-mode'>) => {
const interpolationTime = 3000; // interpolation time (ms)
const framerate = 30; // frame
const qualityRatio = 50; // width size (pixel)
let unregister: (() => void) | null = null;
const injectBlurVideo = (): (() => void) | null => {
const songVideo = document.querySelector<HTMLDivElement>('#song-video');
const video = document.querySelector<HTMLVideoElement>('#song-video .html5-video-container > video');
const wrapper = document.querySelector('#song-video > .player-wrapper');
if (!songVideo) return null;
if (!video) return null;
if (!wrapper) return null;
const blurCanvas = document.createElement('canvas');
blurCanvas.classList.add('html5-blur-canvas');
const context = blurCanvas.getContext('2d', { willReadFrequently: true });
/* effect */
let lastEffectWorkId: number | null = null;
let lastImageData: ImageData | null = null;
const onSync = () => {
if (typeof lastEffectWorkId === 'number') cancelAnimationFrame(lastEffectWorkId);
lastEffectWorkId = requestAnimationFrame(() => {
if (!context) return;
const width = qualityRatio;
let height = Math.max(Math.floor(blurCanvas.height / blurCanvas.width * width), 1);
if (!Number.isFinite(height)) height = width;
context.globalAlpha = 1;
if (lastImageData) {
const frameOffset = (1 / framerate) * (1000 / interpolationTime);
context.globalAlpha = 1 - (frameOffset * 2); // because of alpha value must be < 1
context.putImageData(lastImageData, 0, 0);
context.globalAlpha = frameOffset;
}
context.drawImage(video, 0, 0, width, height);
const nowImageData = context.getImageData(0, 0, width, height);
lastImageData = nowImageData;
lastEffectWorkId = null;
});
};
const applyVideoAttributes = () => {
const rect = video.getBoundingClientRect();
const newWidth = Math.floor(video.width || rect.width);
const newHeight = Math.floor(video.height || rect.height);
if (newWidth === 0 || newHeight === 0) return;
blurCanvas.width = qualityRatio;
blurCanvas.height = Math.floor(newHeight / newWidth * qualityRatio);
blurCanvas.style.width = `${newWidth}px`;
blurCanvas.style.height = `${newHeight}px`;
};
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.type === 'attributes') {
applyVideoAttributes();
}
});
});
const resizeObserver = new ResizeObserver(() => {
applyVideoAttributes();
});
/* hooking */
let canvasInterval: NodeJS.Timeout | null = null;
canvasInterval = setInterval(onSync, Math.max(1, Math.ceil(1000 / framerate)));
applyVideoAttributes();
observer.observe(songVideo, { attributes: true });
resizeObserver.observe(songVideo);
window.addEventListener('resize', applyVideoAttributes);
const onPause = () => {
if (canvasInterval) clearInterval(canvasInterval);
canvasInterval = null;
};
const onPlay = () => {
if (canvasInterval) clearInterval(canvasInterval);
canvasInterval = setInterval(onSync, Math.max(1, Math.ceil(1000 / framerate)));
};
songVideo.addEventListener('pause', onPause);
songVideo.addEventListener('play', onPlay);
/* injecting */
wrapper.prepend(blurCanvas);
/* cleanup */
return () => {
if (canvasInterval) clearInterval(canvasInterval);
songVideo.removeEventListener('pause', onPause);
songVideo.removeEventListener('play', onPlay);
observer.disconnect();
resizeObserver.disconnect();
window.removeEventListener('resize', applyVideoAttributes);
wrapper.removeChild(blurCanvas);
};
};
const playerPage = document.querySelector<HTMLElement>('#player-page');
const ytmusicAppLayout = document.querySelector<HTMLElement>('#layout');
const observer = new MutationObserver((mutationsList) => {
for (const mutation of mutationsList) {
if (mutation.type === 'attributes') {
const isPageOpen = ytmusicAppLayout?.hasAttribute('player-page-open');
if (isPageOpen) {
unregister?.();
unregister = injectBlurVideo() ?? null;
} else {
unregister?.();
unregister = null;
}
}
}
});
if (playerPage) {
observer.observe(playerPage, { attributes: true });
}
};

View File

@ -1,7 +0,0 @@
#song-video canvas.html5-blur-canvas{
position: absolute;
left: 0;
top: 0;
filter: blur(100px);
}

View File

@ -1,17 +0,0 @@
export default () =>
document.addEventListener('audioCanPlay', (e) => {
const { audioContext } = e.detail;
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;
e.detail.audioSource.connect(compressor);
compressor.connect(audioContext.destination);
}, {
once: true, // Only create the audio compressor once, not on each video
passive: true,
});

View File

@ -1,9 +0,0 @@
import { BrowserWindow } from 'electron';
import style from './style.css';
import { injectCSS } from '../utils';
export default (win: BrowserWindow) => {
injectCSS(win.webContents, style);
};

View File

@ -1,10 +0,0 @@
#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

@ -1,4 +0,0 @@
export default async () => {
// See https://github.com/zerodytrash/Simple-YouTube-Age-Restriction-Bypass#userscript
await import('simple-youtube-age-restriction-bypass');
};

View File

@ -1,19 +0,0 @@
import { BrowserWindow, ipcMain } from 'electron';
import prompt from 'custom-electron-prompt';
import promptOptions from '../../providers/prompt-options';
export default (win: BrowserWindow) => {
ipcMain.handle('captionsSelector', async (_, captionLabels: Record<string, string>, currentIndex: string) => await prompt(
{
title: 'Choose Caption',
label: `Current Caption: ${captionLabels[currentIndex] || 'None'}`,
type: 'select',
value: currentIndex,
selectOptions: captionLabels,
resizable: true,
...promptOptions(),
},
win,
));
};

View File

@ -1,4 +0,0 @@
import { PluginConfig } from '../../config/dynamic';
const config = new PluginConfig('captions-selector', { enableFront: true });
export default config;

View File

@ -1,101 +0,0 @@
/* eslint-disable @typescript-eslint/await-thenable */
/* renderer */
import { ipcRenderer } from 'electron';
import configProvider from './config';
import CaptionsSettingsButtonHTML from './templates/captions-settings-template.html';
import { ElementFromHtml } from '../utils';
import { YoutubePlayer } from '../../types/youtube-player';
import type { ConfigType } from '../../config/dynamic';
interface LanguageOptions {
displayName: string;
id: string | null;
is_default: boolean;
is_servable: boolean;
is_translateable: boolean;
kind: string;
languageCode: string; // 2 length
languageName: string;
name: string | null;
vss_id: string;
}
let config: ConfigType<'captions-selector'>;
const $ = <Element extends HTMLElement>(selector: string): Element => document.querySelector(selector)!;
const captionsSettingsButton = ElementFromHtml(CaptionsSettingsButtonHTML);
export default async () => {
// RENDERER
config = await configProvider.getAll();
configProvider.subscribeAll((newConfig) => {
config = newConfig;
});
document.addEventListener('apiLoaded', (event) => setup(event.detail), { once: true, passive: true });
};
function setup(api: YoutubePlayer) {
$('.right-controls-buttons').append(captionsSettingsButton);
let captionTrackList = api.getOption<LanguageOptions[]>('captions', 'tracklist') ?? [];
$('video').addEventListener('srcChanged', () => {
if (config.disableCaptions) {
setTimeout(() => api.unloadModule('captions'), 100);
captionsSettingsButton.style.display = 'none';
return;
}
api.loadModule('captions');
setTimeout(() => {
captionTrackList = api.getOption('captions', 'tracklist') ?? [];
if (config.autoload && config.lastCaptionsCode) {
api.setOption('captions', 'track', {
languageCode: config.lastCaptionsCode,
});
}
captionsSettingsButton.style.display = captionTrackList?.length
? 'inline-block'
: 'none';
}, 250);
});
captionsSettingsButton.addEventListener('click', async () => {
if (captionTrackList?.length) {
const currentCaptionTrack = api.getOption<LanguageOptions>('captions', 'track')!;
let currentIndex = currentCaptionTrack
? captionTrackList.indexOf(captionTrackList.find((track) => track.languageCode === currentCaptionTrack.languageCode)!)
: null;
const captionLabels = [
...captionTrackList.map((track) => track.displayName),
'None',
];
currentIndex = await ipcRenderer.invoke('captionsSelector', captionLabels, currentIndex) as number;
if (currentIndex === null) {
return;
}
const newCaptions = captionTrackList[currentIndex];
configProvider.set('lastCaptionsCode', newCaptions?.languageCode);
if (newCaptions) {
api.setOption('captions', 'track', { languageCode: newCaptions.languageCode });
} else {
api.setOption('captions', 'track', {});
}
setTimeout(() => api.playVideo());
}
});
}

View File

@ -1,22 +0,0 @@
import config from './config';
import { MenuTemplate } from '../../menu';
export default (): MenuTemplate => [
{
label: 'Automatically select last used caption',
type: 'checkbox',
checked: config.get('autoload'),
click(item) {
config.set('autoload', item.checked);
},
},
{
label: 'No captions by default',
type: 'checkbox',
checked: config.get('disableCaptions'),
click(item) {
config.set('disableCaptions', item.checked);
},
},
];

View File

@ -1,17 +0,0 @@
<tp-yt-paper-icon-button aria-disabled="false" aria-label="Open captions selector"
class="player-captions-button style-scope ytmusic-player" icon="yt-icons:subtitles"
role="button" tabindex="0"
title="Open captions selector">
<tp-yt-iron-icon class="style-scope tp-yt-paper-icon-button" id="icon">
<svg class="style-scope yt-icon"
focusable="false" preserveAspectRatio="xMidYMid meet"
style="pointer-events: none; display: block; width: 100%; height: 100%;"
viewBox="0 0 24 24">
<g class="style-scope yt-icon">
<path
class="style-scope tp-yt-iron-icon"
d="M20 4H4c-1.103 0-2 .897-2 2v12c0 1.103.897 2 2 2h16c1.103 0 2-.897 2-2V6c0-1.103-.897-2-2-2zm-9 6H8v4h3v2H8c-1.103 0-2-.897-2-2v-4c0-1.103.897-2 2-2h3v2zm7 0h-3v4h3v2h-3c-1.103 0-2-.897-2-2v-4c0-1.103.897-2 2-2h3v2z"></path>
</g>
</svg>
</tp-yt-iron-icon>
</tp-yt-paper-icon-button>

View File

@ -1,10 +0,0 @@
export default () => {
const compactSidebar = document.querySelector('#mini-guide');
const isCompactSidebarDisabled
= compactSidebar === null
|| window.getComputedStyle(compactSidebar).display === 'none';
if (isCompactSidebarDisabled) {
document.querySelector<HTMLButtonElement>('#button')?.click();
}
};

View File

@ -1,11 +0,0 @@
import { ipcMain } from 'electron';
import { Innertube } from 'youtubei.js';
export default async () => {
const yt = await Innertube.create();
ipcMain.handle('audio-url', async (_, videoID: string) => {
const info = await yt.getBasicInfo(videoID);
return info.streaming_data?.formats[0].decipher(yt.session.player);
});
};

View File

@ -1,4 +0,0 @@
import { PluginConfig } from '../../config/dynamic';
const config = new PluginConfig('crossfade', { enableFront: true });
export default config;

View File

@ -1,164 +0,0 @@
/* eslint-disable @typescript-eslint/await-thenable */
/* renderer */
import { ipcRenderer } from 'electron';
import { Howl } from 'howler';
// Extracted from https://github.com/bitfasching/VolumeFader
import { VolumeFader } from './fader';
import configProvider from './config';
import defaultConfigs from '../../config/defaults';
import type { ConfigType } from '../../config/dynamic';
let transitionAudio: Howl; // Howler audio used to fade out the current music
let firstVideo = true;
let waitForTransition: Promise<unknown>;
const defaultConfig = defaultConfigs.plugins.crossfade;
let config: ConfigType<'crossfade'>;
const configGetNumber = (key: keyof ConfigType<'crossfade'>): number => Number(config[key]) || (defaultConfig[key] as number);
const getStreamURL = async (videoID: string) => ipcRenderer.invoke('audio-url', videoID) as Promise<string>;
const getVideoIDFromURL = (url: string) => new URLSearchParams(url.split('?')?.at(-1)).get('v');
const isReadyToCrossfade = () => transitionAudio && transitionAudio.state() === 'loaded';
const watchVideoIDChanges = (cb: (id: string) => void) => {
window.navigation.addEventListener('navigate', (event) => {
const currentVideoID = getVideoIDFromURL(
(event.currentTarget as Navigation).currentEntry?.url ?? '',
);
const nextVideoID = getVideoIDFromURL(event.destination.url ?? '');
if (
nextVideoID
&& currentVideoID
&& (firstVideo || nextVideoID !== currentVideoID)
) {
if (isReadyToCrossfade()) {
crossfade(() => {
cb(nextVideoID);
});
} else {
cb(nextVideoID);
firstVideo = false;
}
}
});
};
const createAudioForCrossfade = (url: string) => {
if (transitionAudio) {
transitionAudio.unload();
}
transitionAudio = new Howl({
src: url,
html5: true,
volume: 0,
});
syncVideoWithTransitionAudio();
};
const syncVideoWithTransitionAudio = () => {
const video = document.querySelector('video')!;
const videoFader = new VolumeFader(video, {
fadeScaling: configGetNumber('fadeScaling'),
fadeDuration: configGetNumber('fadeInDuration'),
});
transitionAudio.play();
transitionAudio.seek(video.currentTime);
video.addEventListener('seeking', () => {
transitionAudio.seek(video.currentTime);
});
video.addEventListener('pause', () => {
transitionAudio.pause();
});
video.addEventListener('play', () => {
transitionAudio.play();
transitionAudio.seek(video.currentTime);
// Fade in
const videoVolume = video.volume;
video.volume = 0;
videoFader.fadeTo(videoVolume);
});
// Exit just before the end for the transition
const transitionBeforeEnd = () => {
if (
video.currentTime >= video.duration - configGetNumber('secondsBeforeEnd')
&& isReadyToCrossfade()
) {
video.removeEventListener('timeupdate', transitionBeforeEnd);
// Go to next video - XXX: does not support "repeat 1" mode
document.querySelector<HTMLButtonElement>('.next-button')?.click();
}
};
video.addEventListener('timeupdate', transitionBeforeEnd);
};
const onApiLoaded = () => {
watchVideoIDChanges(async (videoID) => {
await waitForTransition;
const url = await getStreamURL(videoID);
if (!url) {
return;
}
await createAudioForCrossfade(url);
});
};
const crossfade = (cb: () => void) => {
if (!isReadyToCrossfade()) {
cb();
return;
}
let resolveTransition: () => void;
waitForTransition = new Promise<void>((resolve) => {
resolveTransition = resolve;
});
const video = document.querySelector('video')!;
const fader = new VolumeFader(transitionAudio._sounds[0]._node, {
initialVolume: video.volume,
fadeScaling: configGetNumber('fadeScaling'),
fadeDuration: configGetNumber('fadeOutDuration'),
});
// Fade out the music
video.volume = 0;
fader.fadeOut(() => {
resolveTransition();
cb();
});
};
export default async () => {
config = await configProvider.getAll();
configProvider.subscribeAll((newConfig) => {
config = newConfig;
});
document.addEventListener('apiLoaded', onApiLoaded, {
once: true,
passive: true,
});
};

View File

@ -1,86 +0,0 @@
import prompt from 'custom-electron-prompt';
import { BrowserWindow } from 'electron';
import config from './config';
import promptOptions from '../../providers/prompt-options';
import configOptions from '../../config/defaults';
import { MenuTemplate } from '../../menu';
import type { ConfigType } from '../../config/dynamic';
const defaultOptions = configOptions.plugins.crossfade;
export default (win: BrowserWindow): MenuTemplate => [
{
label: 'Advanced',
async click() {
const newOptions = await promptCrossfadeValues(win, config.getAll());
if (newOptions) {
config.setAll(newOptions);
}
},
},
];
async function promptCrossfadeValues(win: BrowserWindow, options: ConfigType<'crossfade'>): Promise<Partial<ConfigType<'crossfade'>> | undefined> {
const res = await prompt(
{
title: 'Crossfade Options',
type: 'multiInput',
multiInputOptions: [
{
label: 'Fade in duration (ms)',
value: options.fadeInDuration || defaultOptions.fadeInDuration,
inputAttrs: {
type: 'number',
required: true,
min: '0',
step: '100',
},
},
{
label: 'Fade out duration (ms)',
value: options.fadeOutDuration || defaultOptions.fadeOutDuration,
inputAttrs: {
type: 'number',
required: true,
min: '0',
step: '100',
},
},
{
label: 'Crossfade x seconds before end',
value:
options.secondsBeforeEnd || defaultOptions.secondsBeforeEnd,
inputAttrs: {
type: 'number',
required: true,
min: '0',
},
},
{
label: 'Fade scaling',
selectOptions: { linear: 'Linear', logarithmic: 'Logarithmic' },
value: options.fadeScaling || defaultOptions.fadeScaling,
},
],
resizable: true,
height: 360,
...promptOptions(),
},
win,
).catch(console.error);
if (!res) {
return undefined;
}
return {
fadeInDuration: Number(res[0]),
fadeOutDuration: Number(res[1]),
secondsBeforeEnd: Number(res[2]),
fadeScaling: res[3],
};
}

View File

@ -1,23 +0,0 @@
import type { ConfigType } from '../../config/dynamic';
export default (options: ConfigType<'disable-autoplay'>) => {
const timeUpdateListener = (e: Event) => {
if (e.target instanceof HTMLVideoElement) {
e.target.pause();
}
};
document.addEventListener('apiLoaded', (apiEvent) => {
const eventListener = (name: string) => {
if (options.applyOnce) {
apiEvent.detail.removeEventListener('videodatachange', eventListener);
}
if (name === 'dataloaded') {
apiEvent.detail.pauseVideo();
document.querySelector<HTMLVideoElement>('video')?.addEventListener('timeupdate', timeUpdateListener, { once: true });
}
};
apiEvent.detail.addEventListener('videodatachange', eventListener);
}, { once: true, passive: true });
};

View File

@ -1,20 +0,0 @@
import { BrowserWindow } from 'electron';
import { setMenuOptions } from '../../config/plugins';
import { MenuTemplate } from '../../menu';
import type { ConfigType } from '../../config/dynamic';
export default (_: BrowserWindow, options: ConfigType<'disable-autoplay'>): MenuTemplate => [
{
label: 'Applies only on startup',
type: 'checkbox',
checked: options.applyOnce,
click() {
setMenuOptions('disable-autoplay', {
applyOnce: !options.applyOnce,
});
}
}
];

View File

@ -1,220 +0,0 @@
import { app, dialog, ipcMain } from 'electron';
import { Client as DiscordClient } from '@xhayper/discord-rpc';
import { dev } from 'electron-is';
import { SetActivity } from '@xhayper/discord-rpc/dist/structures/ClientUser';
import registerCallback, { type SongInfoCallback, type SongInfo } from '../../providers/song-info';
import type { ConfigType } from '../../config/dynamic';
// Application ID registered by @Zo-Bro-23
const clientId = '1043858434585526382';
export interface Info {
rpc: DiscordClient;
ready: boolean;
autoReconnect: boolean;
lastSongInfo?: SongInfo;
}
const info: Info = {
rpc: new DiscordClient({
clientId,
}),
ready: false,
autoReconnect: true,
lastSongInfo: undefined,
};
/**
* @type {(() => void)[]}
*/
const refreshCallbacks: (() => void)[] = [];
const resetInfo = () => {
info.ready = false;
clearTimeout(clearActivity);
if (dev()) {
console.log('discord disconnected');
}
for (const cb of refreshCallbacks) {
cb();
}
};
const connectTimeout = () => new Promise((resolve, reject) => setTimeout(() => {
if (!info.autoReconnect || info.rpc.isConnected) {
return;
}
info.rpc.login().then(resolve).catch(reject);
}, 5000));
const connectRecursive = () => {
if (!info.autoReconnect || info.rpc.isConnected) {
return;
}
connectTimeout().catch(connectRecursive);
};
let window: Electron.BrowserWindow;
export const connect = (showError = false) => {
if (info.rpc.isConnected) {
if (dev()) {
console.log('Attempted to connect with active connection');
}
return;
}
info.ready = false;
// Startup the rpc client
info.rpc.login().catch((error: Error) => {
resetInfo();
if (dev()) {
console.error(error);
}
if (info.autoReconnect) {
connectRecursive();
} else if (showError) {
dialog.showMessageBox(window, {
title: 'Connection failed',
message: error.message || String(error),
type: 'error',
});
}
});
};
let clearActivity: NodeJS.Timeout | undefined;
let updateActivity: SongInfoCallback;
type DiscordOptions = ConfigType<'discord'>;
export default (
win: Electron.BrowserWindow,
options: DiscordOptions,
) => {
info.rpc.on('connected', () => {
if (dev()) {
console.log('discord connected');
}
for (const cb of refreshCallbacks) {
cb();
}
});
info.rpc.on('ready', () => {
info.ready = true;
if (info.lastSongInfo) {
updateActivity(info.lastSongInfo);
}
});
info.rpc.on('disconnected', () => {
resetInfo();
if (info.autoReconnect) {
connectTimeout();
}
});
info.autoReconnect = options.autoReconnect;
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 && options.activityTimoutEnabled && options.activityTimoutTime === 0) {
info.rpc.user?.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: SetActivity = {
details: songInfo.title,
state: songInfo.artist,
largeImageKey: songInfo.imageSrc ?? '',
largeImageText: songInfo.album ?? '',
buttons: [
...(options.listenAlong ? [{ label: 'Listen Along', url: songInfo.url ?? '' }] : []),
...(options.hideGitHubButton ? [] : [{ label: 'View App On GitHub', url: 'https://github.com/th-ch/youtube-music' }]),
],
};
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 (options.activityTimoutEnabled) {
clearActivity = setTimeout(() => info.rpc.user?.clearActivity().catch(console.error), options.activityTimoutTime ?? 10_000);
}
} else if (!options.hideDurationLeft) {
// Add the start and end time of the song
const songStartTime = Date.now() - ((songInfo.elapsedSeconds ?? 0) * 1000);
activityInfo.startTimestamp = songStartTime;
activityInfo.endTimestamp
= songStartTime + (songInfo.songDuration * 1000);
}
info.rpc.user?.setActivity(activityInfo).catch(console.error);
};
// If the page is ready, register the callback
win.once('ready-to-show', () => {
let lastSongInfo: SongInfo;
registerCallback((songInfo) => {
lastSongInfo = songInfo;
updateActivity(songInfo);
});
connect();
let lastSent = Date.now();
ipcMain.on('timeChanged', (_, t: number) => {
const currentTime = Date.now();
// if lastSent is more than 5 seconds ago, send the new time
if (currentTime - lastSent > 5000) {
lastSent = currentTime;
lastSongInfo.elapsedSeconds = t;
updateActivity(lastSongInfo);
}
});
});
app.on('window-all-closed', clear);
};
export const clear = () => {
if (info.rpc) {
info.rpc.user?.clearActivity();
}
clearTimeout(clearActivity);
};
export const registerRefresh = (cb: () => void) => refreshCallbacks.push(cb);
export const isConnected = () => info.rpc !== null;

View File

@ -1,98 +0,0 @@
import prompt from 'custom-electron-prompt';
import { clear, connect, isConnected, registerRefresh } from './back';
import { setMenuOptions } from '../../config/plugins';
import promptOptions from '../../providers/prompt-options';
import { singleton } from '../../providers/decorators';
import { MenuTemplate } from '../../menu';
import type { ConfigType } from '../../config/dynamic';
const registerRefreshOnce = singleton((refreshMenu: () => void) => {
registerRefresh(refreshMenu);
});
type DiscordOptions = ConfigType<'discord'>;
export default (win: Electron.BrowserWindow, options: DiscordOptions, refreshMenu: () => void): MenuTemplate => {
registerRefreshOnce(refreshMenu);
return [
{
label: isConnected() ? 'Connected' : 'Reconnect',
enabled: !isConnected(),
click: () => connect(),
},
{
label: 'Auto reconnect',
type: 'checkbox',
checked: options.autoReconnect,
click(item: Electron.MenuItem) {
options.autoReconnect = item.checked;
setMenuOptions('discord', options);
},
},
{
label: 'Clear activity',
click: clear,
},
{
label: 'Clear activity after timeout',
type: 'checkbox',
checked: options.activityTimoutEnabled,
click(item: Electron.MenuItem) {
options.activityTimoutEnabled = item.checked;
setMenuOptions('discord', options);
},
},
{
label: 'Listen Along',
type: 'checkbox',
checked: options.listenAlong,
click(item: Electron.MenuItem) {
options.listenAlong = item.checked;
setMenuOptions('discord', options);
},
},
{
label: 'Hide GitHub link Button',
type: 'checkbox',
checked: options.hideGitHubButton,
click(item: Electron.MenuItem) {
options.hideGitHubButton = item.checked;
setMenuOptions('discord', options);
},
},
{
label: 'Hide duration left',
type: 'checkbox',
checked: options.hideDurationLeft,
click(item: Electron.MenuItem) {
options.hideDurationLeft = item.checked;
setMenuOptions('discord', options);
},
},
{
label: 'Set inactivity timeout',
click: () => setInactivityTimeout(win, options),
},
];
};
async function setInactivityTimeout(win: Electron.BrowserWindow, options: DiscordOptions) {
const output = await prompt({
title: 'Set Inactivity Timeout',
label: 'Enter inactivity timeout in seconds:',
value: String(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,4 +0,0 @@
import { PluginConfig } from '../../config/dynamic';
const config = new PluginConfig('downloader');
export default config;

View File

@ -1,83 +0,0 @@
import { ipcRenderer } from 'electron';
import downloadHTML from './templates/download.html';
import defaultConfig from '../../config/defaults';
import { getSongMenu } from '../../providers/dom-elements';
import { ElementFromHtml } from '../utils';
import { getSongInfo } from '../../providers/song-info-front';
let menu: Element | null = null;
let progress: Element | null = null;
const downloadButton = ElementFromHtml(downloadHTML);
let doneFirstLoad = false;
const menuObserver = new MutationObserver(() => {
if (!menu) {
menu = getSongMenu();
if (!menu) {
return;
}
}
if (menu.contains(downloadButton)) {
return;
}
const menuUrl = document.querySelector<HTMLAnchorElement>('tp-yt-paper-listbox [tabindex="0"] #navigation-endpoint')?.href;
if (!menuUrl?.includes('watch?') && doneFirstLoad) {
return;
}
menu.prepend(downloadButton);
progress = document.querySelector('#ytmcustom-download');
if (doneFirstLoad) {
return;
}
setTimeout(() => doneFirstLoad ||= true, 500);
});
// TODO: re-enable once contextIsolation is set to true
// contextBridge.exposeInMainWorld("downloader", {
// download: () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any,@typescript-eslint/no-unsafe-member-access
(global as any).download = () => {
let videoUrl = getSongMenu()
// Selector of first button which is always "Start Radio"
?.querySelector('ytmusic-menu-navigation-item-renderer[tabindex="-1"] #navigation-endpoint')
?.getAttribute('href');
if (videoUrl) {
if (videoUrl.startsWith('watch?')) {
videoUrl = defaultConfig.url + '/' + videoUrl;
}
if (videoUrl.includes('?playlist=')) {
ipcRenderer.send('download-playlist-request', videoUrl);
return;
}
} else {
videoUrl = getSongInfo().url || window.location.href;
}
ipcRenderer.send('download-song', videoUrl);
};
export default () => {
document.addEventListener('apiLoaded', () => {
menuObserver.observe(document.querySelector('ytmusic-popup-container')!, {
childList: true,
subtree: true,
});
}, { once: true, passive: true });
ipcRenderer.on('downloader-feedback', (_, feedback: string) => {
if (progress) {
progress.innerHTML = feedback || 'Download';
} else {
console.warn('Cannot update progress');
}
});
};

View File

@ -1,46 +0,0 @@
import { dialog } from 'electron';
import { downloadPlaylist } from './back';
import { defaultMenuDownloadLabel, getFolder } from './utils';
import { DefaultPresetList } from './types';
import config from './config';
import { MenuTemplate } from '../../menu';
export default (): MenuTemplate => [
{
label: defaultMenuDownloadLabel,
click: () => downloadPlaylist(),
},
{
label: 'Choose download folder',
click() {
const result = dialog.showOpenDialogSync({
properties: ['openDirectory', 'createDirectory'],
defaultPath: getFolder(config.get('downloadFolder') ?? ''),
});
if (result) {
config.set('downloadFolder', result[0]);
} // Else = user pressed cancel
},
},
{
label: 'Presets',
submenu: Object.keys(DefaultPresetList).map((preset) => ({
label: preset,
type: 'radio',
checked: config.get('selectedPreset') === preset,
click() {
config.set('selectedPreset', preset);
},
})),
},
{
label: 'Skip existing files',
type: 'checkbox',
checked: config.get('skipExisting'),
click(item) {
config.set('skipExisting', item.checked);
},
},
];

View File

@ -1,116 +0,0 @@
export interface Preset {
extension?: string | null;
ffmpegArgs: string[];
}
// Presets for FFmpeg
export const DefaultPresetList: Record<string, Preset> = {
'mp3 (256kbps)': {
extension: 'mp3',
ffmpegArgs: ['-b:a', '256k'],
},
'Source': {
extension: undefined,
ffmpegArgs: ['-acodec', 'copy'],
},
'Custom': {
extension: null,
ffmpegArgs: [],
}
};
export interface YouTubeFormat {
itag: number;
container: string;
content: string;
resolution: string;
bitrate: string;
range: string;
vrOr3D: string;
}
// converted from https://gist.github.com/sidneys/7095afe4da4ae58694d128b1034e01e2#file-youtube_format_code_itag_list-md
export const YoutubeFormatList: YouTubeFormat[] = [
{ itag: 5, container: 'flv', content: 'audio/video', resolution: '240p', bitrate: '-', range: '-', vrOr3D: '-' },
{ itag: 6, container: 'flv', content: 'audio/video', resolution: '270p', bitrate: '-', range: '-', vrOr3D: '-' },
{ itag: 17, container: '3gp', content: 'audio/video', resolution: '144p', bitrate: '-', range: '-', vrOr3D: '-' },
{ itag: 18, container: 'mp4', content: 'audio/video', resolution: '360p', bitrate: '-', range: '-', vrOr3D: '-' },
{ itag: 22, container: 'mp4', content: 'audio/video', resolution: '720p', bitrate: '-', range: '-', vrOr3D: '-' },
{ itag: 34, container: 'flv', content: 'audio/video', resolution: '360p', bitrate: '-', range: '-', vrOr3D: '-' },
{ itag: 35, container: 'flv', content: 'audio/video', resolution: '480p', bitrate: '-', range: '-', vrOr3D: '-' },
{ itag: 36, container: '3gp', content: 'audio/video', resolution: '180p', bitrate: '-', range: '-', vrOr3D: '-' },
{ itag: 37, container: 'mp4', content: 'audio/video', resolution: '1080p', bitrate: '-', range: '-', vrOr3D: '-' },
{ itag: 38, container: 'mp4', content: 'audio/video', resolution: '3072p', bitrate: '-', range: '-', vrOr3D: '-' },
{ itag: 43, container: 'webm', content: 'audio/video', resolution: '360p', bitrate: '-', range: '-', vrOr3D: '-' },
{ itag: 44, container: 'webm', content: 'audio/video', resolution: '480p', bitrate: '-', range: '-', vrOr3D: '-' },
{ itag: 45, container: 'webm', content: 'audio/video', resolution: '720p', bitrate: '-', range: '-', vrOr3D: '-' },
{ itag: 46, container: 'webm', content: 'audio/video', resolution: '1080p', bitrate: '-', range: '-', vrOr3D: '-' },
{ itag: 82, container: 'mp4', content: 'audio/video', resolution: '360p', bitrate: '-', range: '-', vrOr3D: '3D' },
{ itag: 83, container: 'mp4', content: 'audio/video', resolution: '480p', bitrate: '-', range: '-', vrOr3D: '3D' },
{ itag: 84, container: 'mp4', content: 'audio/video', resolution: '720p', bitrate: '-', range: '-', vrOr3D: '3D' },
{ itag: 85, container: 'mp4', content: 'audio/video', resolution: '1080p', bitrate: '-', range: '-', vrOr3D: '3D' },
{ itag: 91, container: 'hls', content: 'audio/video', resolution: '144p', bitrate: '-', range: '-', vrOr3D: '3D' },
{ itag: 92, container: 'hls', content: 'audio/video', resolution: '240p', bitrate: '-', range: '-', vrOr3D: '3D' },
{ itag: 93, container: 'hls', content: 'audio/video', resolution: '360p', bitrate: '-', range: '-', vrOr3D: '3D' },
{ itag: 94, container: 'hls', content: 'audio/video', resolution: '480p', bitrate: '-', range: '-', vrOr3D: '3D' },
{ itag: 95, container: 'hls', content: 'audio/video', resolution: '720p', bitrate: '-', range: '-', vrOr3D: '3D' },
{ itag: 96, container: 'hls', content: 'audio/video', resolution: '1080p', bitrate: '-', range: '-', vrOr3D: '-' },
{ itag: 100, container: 'webm', content: 'audio/video', resolution: '360p', bitrate: '-', range: '-', vrOr3D: '3D' },
{ itag: 101, container: 'webm', content: 'audio/video', resolution: '480p', bitrate: '-', range: '-', vrOr3D: '3D' },
{ itag: 102, container: 'webm', content: 'audio/video', resolution: '720p', bitrate: '-', range: '-', vrOr3D: '3D' },
{ itag: 132, container: 'hls', content: 'audio/video', resolution: '240p', bitrate: '-', range: '-', vrOr3D: '' },
{ itag: 133, container: 'mp4', content: 'video', resolution: '240p', bitrate: '-', range: '-', vrOr3D: '' },
{ itag: 134, container: 'mp4', content: 'video', resolution: '360p', bitrate: '-', range: '-', vrOr3D: '' },
{ itag: 135, container: 'mp4', content: 'video', resolution: '480p', bitrate: '-', range: '-', vrOr3D: '' },
{ itag: 136, container: 'mp4', content: 'video', resolution: '720p', bitrate: '-', range: '-', vrOr3D: '' },
{ itag: 137, container: 'mp4', content: 'video', resolution: '1080p', bitrate: '-', range: '-', vrOr3D: '' },
{ itag: 138, container: 'mp4', content: 'video', resolution: '2160p60', bitrate: '-', range: '-', vrOr3D: '' },
{ itag: 139, container: 'm4a', content: 'audio', resolution: '-', bitrate: '48k', range: '-', vrOr3D: '' },
{ itag: 140, container: 'm4a', content: 'audio', resolution: '-', bitrate: '128k', range: '-', vrOr3D: '' },
{ itag: 141, container: 'm4a', content: 'audio', resolution: '-', bitrate: '256k', range: '-', vrOr3D: '' },
{ itag: 151, container: 'hls', content: 'audio/video', resolution: '72p', bitrate: '-', range: '-', vrOr3D: '' },
{ itag: 160, container: 'mp4', content: 'video', resolution: '144p', bitrate: '-', range: '-', vrOr3D: '' },
{ itag: 167, container: 'webm', content: 'video', resolution: '360p', bitrate: '-', range: '-', vrOr3D: '' },
{ itag: 168, container: 'webm', content: 'video', resolution: '480p', bitrate: '-', range: '-', vrOr3D: '' },
{ itag: 169, container: 'webm', content: 'video', resolution: '1080p', bitrate: '-', range: '-', vrOr3D: '' },
{ itag: 171, container: 'webm', content: 'audio', resolution: '-', bitrate: '128k', range: '-', vrOr3D: '' },
{ itag: 218, container: 'webm', content: 'video', resolution: '480p', bitrate: '-', range: '-', vrOr3D: '' },
{ itag: 219, container: 'webm', content: 'video', resolution: '144p', bitrate: '-', range: '-', vrOr3D: '' },
{ itag: 242, container: 'webm', content: 'video', resolution: '240p', bitrate: '-', range: '-', vrOr3D: '' },
{ itag: 243, container: 'webm', content: 'video', resolution: '360p', bitrate: '-', range: '-', vrOr3D: '' },
{ itag: 244, container: 'webm', content: 'video', resolution: '480p', bitrate: '-', range: '-', vrOr3D: '' },
{ itag: 245, container: 'webm', content: 'video', resolution: '480p', bitrate: '-', range: '-', vrOr3D: '' },
{ itag: 246, container: 'webm', content: 'video', resolution: '480p', bitrate: '-', range: '-', vrOr3D: '' },
{ itag: 247, container: 'webm', content: 'video', resolution: '720p', bitrate: '-', range: '-', vrOr3D: '' },
{ itag: 248, container: 'webm', content: 'video', resolution: '1080p', bitrate: '-', range: '-', vrOr3D: '' },
{ itag: 249, container: 'webm', content: 'audio', resolution: '-', bitrate: '50k', range: '-', vrOr3D: '' },
{ itag: 250, container: 'webm', content: 'audio', resolution: '-', bitrate: '70k', range: '-', vrOr3D: '' },
{ itag: 251, container: 'webm', content: 'audio', resolution: '-', bitrate: '160k', range: '-', vrOr3D: '' },
{ itag: 264, container: 'mp4', content: 'video', resolution: '1440p', bitrate: '-', range: '-', vrOr3D: '' },
{ itag: 266, container: 'mp4', content: 'video', resolution: '2160p60', bitrate: '-', range: '-', vrOr3D: '' },
{ itag: 271, container: 'webm', content: 'video', resolution: '1440p', bitrate: '-', range: '-', vrOr3D: '' },
{ itag: 272, container: 'webm', content: 'video', resolution: '4320p', bitrate: '-', range: '-', vrOr3D: '' },
{ itag: 278, container: 'webm', content: 'video', resolution: '144p', bitrate: '-', range: '-', vrOr3D: '' },
{ itag: 298, container: 'mp4', content: 'video', resolution: '720p60', bitrate: '-', range: '-', vrOr3D: '' },
{ itag: 299, container: 'mp4', content: 'video', resolution: '1080p60', bitrate: '-', range: '-', vrOr3D: '' },
{ itag: 302, container: 'webm', content: 'video', resolution: '720p60', bitrate: '-', range: '-', vrOr3D: '' },
{ itag: 303, container: 'webm', content: 'video', resolution: '1080p60', bitrate: '-', range: '-', vrOr3D: '' },
{ itag: 308, container: 'webm', content: 'video', resolution: '1440p60', bitrate: '-', range: '-', vrOr3D: '' },
{ itag: 313, container: 'webm', content: 'video', resolution: '2160p', bitrate: '-', range: '-', vrOr3D: '' },
{ itag: 315, container: 'webm', content: 'video', resolution: '2160p60', bitrate: '-', range: '-', vrOr3D: '' },
{ itag: 330, container: 'webm', content: 'video', resolution: '144p60', bitrate: '-', range: 'hdr', vrOr3D: '' },
{ itag: 331, container: 'webm', content: 'video', resolution: '240p60', bitrate: '-', range: 'hdr', vrOr3D: '' },
{ itag: 332, container: 'webm', content: 'video', resolution: '360p60', bitrate: '-', range: 'hdr', vrOr3D: '' },
{ itag: 333, container: 'webm', content: 'video', resolution: '480p60', bitrate: '-', range: 'hdr', vrOr3D: '' },
{ itag: 334, container: 'webm', content: 'video', resolution: '720p60', bitrate: '-', range: 'hdr', vrOr3D: '' },
{ itag: 335, container: 'webm', content: 'video', resolution: '1080p60', bitrate: '-', range: 'hdr', vrOr3D: '' },
{ itag: 336, container: 'webm', content: 'video', resolution: '1440p60', bitrate: '-', range: 'hdr', vrOr3D: '' },
{ itag: 337, container: 'webm', content: 'video', resolution: '2160p60', bitrate: '-', range: 'hdr', vrOr3D: '' },
{ itag: 272, container: 'webm', content: 'video', resolution: '2880p/4320p', bitrate: '-', range: '-', vrOr3D: '' },
{ itag: 399, container: 'mp4', content: 'video', resolution: '1080p', bitrate: '-', range: '-', vrOr3D: '' },
{ itag: 400, container: 'mp4', content: 'video', resolution: '1440p', bitrate: '-', range: '-', vrOr3D: '' },
{ itag: 401, container: 'mp4', content: 'video', resolution: '2160p', bitrate: '-', range: '-', vrOr3D: '' },
{ itag: 402, container: 'mp4', content: 'video', resolution: '2880p', bitrate: '-', range: '-', vrOr3D: '' },
{ itag: 571, container: 'mp4', content: 'video', resolution: '3840p', bitrate: '-', range: '-', vrOr3D: '' },
{ itag: 702, container: 'mp4', content: 'video', resolution: '3840p', bitrate: '-', range: '-', vrOr3D: '' },
];

View File

@ -1,45 +0,0 @@
// "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<HTMLMediaElement, number>();
const propertyDescriptor = Object.getOwnPropertyDescriptor(
HTMLMediaElement.prototype,
'volume',
);
Object.defineProperty(HTMLMediaElement.prototype, 'volume', {
get(this: HTMLMediaElement) {
const lowVolume = propertyDescriptor?.get?.call(this) as number ?? 0;
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) ?? 0;
const storedDeviation = Math.abs(
storedOriginalVolume - calculatedOriginalVolume,
);
return storedDeviation < 0.01
? storedOriginalVolume
: calculatedOriginalVolume;
},
set(this: HTMLMediaElement, originalVolume: number) {
const lowVolume = originalVolume ** EXPONENT;
storedOriginalVolumes.set(this, originalVolume);
propertyDescriptor?.set?.call(this, lowVolume);
},
});
};
export default () =>
document.addEventListener('apiLoaded', exponentialVolume, {
once: true,
passive: true,
});

View File

@ -1,3 +0,0 @@
<svg fill="none" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path fill="#ffffff" d="m4.21 4.387.083-.094a1 1 0 0 1 1.32-.083l.094.083L12 10.585l6.293-6.292a1 1 0 1 1 1.414 1.414L13.415 12l6.292 6.293a1 1 0 0 1 .083 1.32l-.083.094a1 1 0 0 1-1.32.083l-.094-.083L12 13.415l-6.293 6.292a1 1 0 0 1-1.414-1.414L10.585 12 4.293 5.707a1 1 0 0 1-.083-1.32l.083-.094-.083.094Z"/>
</svg>

Before

Width:  |  Height:  |  Size: 392 B

View File

@ -1,3 +0,0 @@
<svg fill="none" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path fill="#ffffff" d="M6 3h12a3 3 0 0 1 3 3v12a3 3 0 0 1-3 3H6a3 3 0 0 1-3-3V6a3 3 0 0 1 3-3Zm0 2a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V6a1 1 0 0 0-1-1H6Z"/>
</svg>

Before

Width:  |  Height:  |  Size: 252 B

View File

@ -1,3 +0,0 @@
<svg width="24" height="24" fill="none" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="M3 17h12a1 1 0 0 1 .117 1.993L15 19H3a1 1 0 0 1-.117-1.993L3 17h12H3Zm0-6h18a1 1 0 0 1 .117 1.993L21 13H3a1 1 0 0 1-.117-1.993L3 11h18H3Zm0-6h15a1 1 0 0 1 .117 1.993L18 7H3a1 1 0 0 1-.117-1.993L3 5h15H3Z" fill="#ffffff"/>
</svg>

Before

Width:  |  Height:  |  Size: 338 B

View File

@ -1,3 +0,0 @@
<svg fill="none" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path fill="#ffffff" d="M3.755 12.5h16.492a.75.75 0 0 0 0-1.5H3.755a.75.75 0 0 0 0 1.5Z" />
</svg>

Before

Width:  |  Height:  |  Size: 174 B

View File

@ -1,3 +0,0 @@
<svg fill="none" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path fill="#ffffff" d="M7.518 5H6.009a3.25 3.25 0 0 1 3.24-3h8.001A4.75 4.75 0 0 1 22 6.75v8a3.25 3.25 0 0 1-3 3.24v-1.508a1.75 1.75 0 0 0 1.5-1.732v-8a3.25 3.25 0 0 0-3.25-3.25h-8A1.75 1.75 0 0 0 7.518 5ZM5.25 6A3.25 3.25 0 0 0 2 9.25v9.5A3.25 3.25 0 0 0 5.25 22h9.5A3.25 3.25 0 0 0 18 18.75v-9.5A3.25 3.25 0 0 0 14.75 6h-9.5ZM3.5 9.25c0-.966.784-1.75 1.75-1.75h9.5c.967 0 1.75.784 1.75 1.75v9.5a1.75 1.75 0 0 1-1.75 1.75h-9.5a1.75 1.75 0 0 1-1.75-1.75v-9.5Z"/>
</svg>

Before

Width:  |  Height:  |  Size: 546 B

View File

@ -1,67 +0,0 @@
import { register } from 'electron-localshortcut';
import { BrowserWindow, Menu, MenuItem, ipcMain } from 'electron';
import titlebarStyle from './titlebar.css';
import { injectCSS } from '../utils';
// Tracks menu visibility
export default (win: BrowserWindow) => {
injectCSS(win.webContents, titlebarStyle);
win.once('ready-to-show', () => {
register(win, '`', () => {
win.webContents.send('toggleMenu');
});
});
ipcMain.handle(
'get-menu',
() => JSON.parse(JSON.stringify(
Menu.getApplicationMenu(),
(key: string, value: unknown) => (key !== 'commandsMap' && key !== 'menu') ? value : undefined),
),
);
const getMenuItemById = (commandId: number): MenuItem | null => {
const menu = Menu.getApplicationMenu();
let target: MenuItem | null = null;
const stack = [...menu?.items ?? []];
while (stack.length > 0) {
const now = stack.shift();
now?.submenu?.items.forEach((item) => stack.push(item));
if (now?.commandId === commandId) {
target = now;
break;
}
}
return target;
};
ipcMain.handle('menu-event', (event, commandId: number) => {
const target = getMenuItemById(commandId);
if (target) target.click(undefined, BrowserWindow.fromWebContents(event.sender), event.sender);
});
ipcMain.handle('get-menu-by-id', (_, commandId: number) => {
const result = getMenuItemById(commandId);
return JSON.parse(JSON.stringify(
result,
(key: string, value: unknown) => (key !== 'commandsMap' && key !== 'menu') ? value : undefined),
);
});
ipcMain.handle('window-is-maximized', () => win.isMaximized());
ipcMain.handle('window-close', () => win.close());
ipcMain.handle('window-minimize', () => win.minimize());
ipcMain.handle('window-maximize', () => win.maximize());
win.on('maximize', () => win.webContents.send('window-maximize'));
ipcMain.handle('window-unmaximize', () => win.unmaximize());
win.on('unmaximize', () => win.webContents.send('window-unmaximize'));
};

View File

@ -1,163 +0,0 @@
import { ipcRenderer, Menu } from 'electron';
import { createPanel } from './menu/panel';
import logo from './assets/menu.svg';
import close from './assets/close.svg';
import minimize from './assets/minimize.svg';
import maximize from './assets/maximize.svg';
import unmaximize from './assets/unmaximize.svg';
import { isEnabled } from '../../config/plugins';
import config from '../../config';
function $<E extends Element = Element>(selector: string) {
return document.querySelector<E>(selector);
}
const isMacOS = navigator.userAgent.includes('Macintosh');
const isNotWindowsOrMacOS = !navigator.userAgent.includes('Windows') && !isMacOS;
export default async () => {
let hideMenu = config.get('options.hideMenu');
const titleBar = document.createElement('title-bar');
const navBar = document.querySelector<HTMLDivElement>('#nav-bar-background');
let maximizeButton: HTMLButtonElement;
if (isMacOS) titleBar.style.setProperty('--offset-left', '70px');
logo.classList.add('title-bar-icon');
const logoClick = () => {
hideMenu = !hideMenu;
let visibilityStyle: string;
if (hideMenu) {
visibilityStyle = 'hidden';
} else {
visibilityStyle = 'visible';
}
const menus = document.querySelectorAll<HTMLElement>('menu-button');
menus.forEach((menu) => {
menu.style.visibility = visibilityStyle;
});
};
logo.onclick = logoClick;
ipcRenderer.on('toggleMenu', logoClick);
if (!isMacOS) titleBar.appendChild(logo);
document.body.appendChild(titleBar);
titleBar.appendChild(logo);
const addWindowControls = async () => {
// Create window control buttons
const minimizeButton = document.createElement('button');
minimizeButton.classList.add('window-control');
minimizeButton.appendChild(minimize);
minimizeButton.onclick = () => ipcRenderer.invoke('window-minimize');
maximizeButton = document.createElement('button');
if (await ipcRenderer.invoke('window-is-maximized')) {
maximizeButton.classList.add('window-control');
maximizeButton.appendChild(unmaximize);
} else {
maximizeButton.classList.add('window-control');
maximizeButton.appendChild(maximize);
}
maximizeButton.onclick = async () => {
if (await ipcRenderer.invoke('window-is-maximized')) {
// change icon to maximize
maximizeButton.removeChild(maximizeButton.firstChild!);
maximizeButton.appendChild(maximize);
// call unmaximize
await ipcRenderer.invoke('window-unmaximize');
} else {
// change icon to unmaximize
maximizeButton.removeChild(maximizeButton.firstChild!);
maximizeButton.appendChild(unmaximize);
// call maximize
await ipcRenderer.invoke('window-maximize');
}
};
const closeButton = document.createElement('button');
closeButton.classList.add('window-control');
closeButton.appendChild(close);
closeButton.onclick = () => ipcRenderer.invoke('window-close');
// Create a container div for the window control buttons
const windowControlsContainer = document.createElement('div');
windowControlsContainer.classList.add('window-controls-container');
windowControlsContainer.appendChild(minimizeButton);
windowControlsContainer.appendChild(maximizeButton);
windowControlsContainer.appendChild(closeButton);
// Add window control buttons to the title bar
titleBar.appendChild(windowControlsContainer);
};
if (isNotWindowsOrMacOS) await addWindowControls();
if (navBar) {
const observer = new MutationObserver((mutations) => {
mutations.forEach(() => {
titleBar.style.setProperty('--titlebar-background-color', navBar.style.backgroundColor);
document.querySelector('html')!.style.setProperty('--titlebar-background-color', navBar.style.backgroundColor);
});
});
observer.observe(navBar, { attributes : true, attributeFilter : ['style'] });
}
const updateMenu = async () => {
const children = [...titleBar.children];
children.forEach((child) => {
if (child !== logo) child.remove();
});
const menu = await ipcRenderer.invoke('get-menu') as Menu | null;
if (!menu) return;
menu.items.forEach((menuItem) => {
const menu = document.createElement('menu-button');
createPanel(titleBar, menu, menuItem.submenu?.items ?? []);
menu.append(menuItem.label);
titleBar.appendChild(menu);
if (hideMenu) {
menu.style.visibility = 'hidden';
}
});
if (isNotWindowsOrMacOS) await addWindowControls();
};
await updateMenu();
document.title = 'Youtube Music';
ipcRenderer.on('refreshMenu', () => updateMenu());
ipcRenderer.on('window-maximize', () => {
maximizeButton.removeChild(maximizeButton.firstChild!);
maximizeButton.appendChild(unmaximize);
});
ipcRenderer.on('window-unmaximize', () => {
maximizeButton.removeChild(maximizeButton.firstChild!);
maximizeButton.appendChild(maximize);
});
if (isEnabled('picture-in-picture')) {
ipcRenderer.on('pip-toggle', () => {
updateMenu();
});
}
// 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', () => {
const htmlHeadStyle = $('head > div > style');
if (htmlHeadStyle) {
// HACK: This is a hack to remove the scrollbar width
htmlHeadStyle.innerHTML = htmlHeadStyle.innerHTML.replace('html::-webkit-scrollbar {width: var(--ytmusic-scrollbar-width);', 'html::-webkit-scrollbar {');
}
}, { once: true, passive: true });
};

View File

@ -1,10 +0,0 @@
const Icons = {
submenu: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none" /><polyline points="9 6 15 12 9 18" /></svg>',
checkbox: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M5 12l5 5l10 -10" /></svg>',
radio: {
checked: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" style="padding: 2px"><path fill="currentColor" d="M10,5 C7.2,5 5,7.2 5,10 C5,12.8 7.2,15 10,15 C12.8,15 15,12.8 15,10 C15,7.2 12.8,5 10,5 L10,5 Z M10,0 C4.5,0 0,4.5 0,10 C0,15.5 4.5,20 10,20 C15.5,20 20,15.5 20,10 C20,4.5 15.5,0 10,0 L10,0 Z M10,18 C5.6,18 2,14.4 2,10 C2,5.6 5.6,2 10,2 C14.4,2 18,5.6 18,10 C18,14.4 14.4,18 10,18 L10,18 Z" /></svg>',
unchecked: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" style="padding: 2px"><path fill="currentColor" d="M10,0 C4.5,0 0,4.5 0,10 C0,15.5 4.5,20 10,20 C15.5,20 20,15.5 20,10 C20,4.5 15.5,0 10,0 L10,0 Z M10,18 C5.6,18 2,14.4 2,10 C2,5.6 5.6,2 10,2 C14.4,2 18,5.6 18,10 C18,14.4 14.4,18 10,18 L10,18 Z" /></svg>',
},
};
export default Icons;

View File

@ -1,134 +0,0 @@
import { nativeImage, type MenuItem, ipcRenderer, Menu } from 'electron';
import Icons from './icons';
import { ElementFromHtml } from '../../utils';
interface PanelOptions {
placement?: 'bottom' | 'right';
order?: number;
}
export const createPanel = (
parent: HTMLElement,
anchor: HTMLElement,
items: MenuItem[],
options: PanelOptions = { placement: 'bottom', order: 0 },
) => {
const childPanels: HTMLElement[] = [];
const panel = document.createElement('menu-panel');
panel.style.zIndex = `${options.order}`;
const updateIconState = (iconWrapper: HTMLElement, item: MenuItem) => {
if (item.type === 'checkbox') {
if (item.checked) iconWrapper.innerHTML = Icons.checkbox;
else iconWrapper.innerHTML = '';
} else if (item.type === 'radio') {
if (item.checked) iconWrapper.innerHTML = Icons.radio.checked;
else iconWrapper.innerHTML = Icons.radio.unchecked;
} else {
const nativeImageIcon = typeof item.icon === 'string' ? nativeImage.createFromPath(item.icon) : item.icon;
const iconURL = nativeImageIcon?.toDataURL();
if (iconURL) iconWrapper.style.background = `url(${iconURL})`;
}
};
const radioGroups: [MenuItem, HTMLElement][] = [];
items.map((item) => {
if (item.type === 'separator') return panel.appendChild(document.createElement('menu-separator'));
const menu = document.createElement('menu-item');
const iconWrapper = document.createElement('menu-icon');
updateIconState(iconWrapper, item);
menu.appendChild(iconWrapper);
menu.append(item.label);
menu.addEventListener('click', async () => {
await ipcRenderer.invoke('menu-event', item.commandId);
const menuItem = await ipcRenderer.invoke('get-menu-by-id', item.commandId) as MenuItem | null;
if (menuItem) {
updateIconState(iconWrapper, menuItem);
if (menuItem.type === 'radio') {
await Promise.all(
radioGroups.map(async ([item, iconWrapper]) => {
if (item.commandId === menuItem.commandId) return;
const newItem = await ipcRenderer.invoke('get-menu-by-id', item.commandId) as MenuItem | null;
if (newItem) updateIconState(iconWrapper, newItem);
})
);
}
}
});
if (item.type === 'radio') {
radioGroups.push([item, iconWrapper]);
}
if (item.type === 'submenu') {
const subMenuIcon = document.createElement('menu-icon');
subMenuIcon.appendChild(ElementFromHtml(Icons.submenu));
menu.appendChild(subMenuIcon);
const [child, , children] = createPanel(parent, menu, item.submenu?.items ?? [], {
placement: 'right',
order: (options?.order ?? 0) + 1,
});
childPanels.push(child);
children.push(...children);
}
panel.appendChild(menu);
});
/* methods */
const isOpened = () => panel.getAttribute('open') === 'true';
const close = () => panel.setAttribute('open', 'false');
const open = () => {
const rect = anchor.getBoundingClientRect();
if (options.placement === 'bottom') {
panel.style.setProperty('--x', `${rect.x}px`);
panel.style.setProperty('--y', `${rect.y + rect.height}px`);
} else {
panel.style.setProperty('--x', `${rect.x + rect.width}px`);
panel.style.setProperty('--y', `${rect.y}px`);
}
panel.setAttribute('open', 'true');
// Children are placed below their parent item, which can cause
// long lists to squeeze their children at the bottom of the screen
// (This needs to be done *after* setAttribute)
panel.classList.remove('position-by-bottom');
if (options.placement === 'right' && panel.scrollHeight > panel.clientHeight ) {
panel.style.setProperty('--y', `${rect.y + rect.height}px`);
panel.classList.add('position-by-bottom');
}
};
anchor.addEventListener('click', () => {
if (isOpened()) close();
else open();
});
document.body.addEventListener('click', (event) => {
const path = event.composedPath();
const isInside = path.some((it) => it === panel || it === anchor || childPanels.includes(it as HTMLElement));
if (!isInside) close();
});
parent.appendChild(panel);
return [
panel,
{ isOpened, close, open },
childPanels,
] as const;
};

View File

@ -1,180 +0,0 @@
:root {
--titlebar-background-color: #030303;
--menu-bar-height: 36px;
}
title-bar {
-webkit-app-region: drag;
box-sizing: border-box;
position: fixed;
top: 0;
z-index: 10000000;
width: 100%;
height: var(--menu-bar-height, 36px);
display: flex;
flex-flow: row;
justify-content: flex-start;
align-items: center;
gap: 4px;
color: #f1f1f1;
font-size: 14px;
padding: 4px 12px;
padding-left: var(--offset-left, 12px);
background-color: var(--titlebar-background-color, #030303);
user-select: none;
transition: opacity 200ms ease 0s, background-color 300ms cubic-bezier(0.2, 0, 0.6, 1) 0s;
}
menu-button {
-webkit-app-region: none;
display: flex;
justify-content: center;
align-items: center;
align-self: stretch;
padding: 2px 8px;
border-radius: 4px;
cursor: pointer;
}
menu-button:hover {
background-color: rgba(255, 255, 255, 0.1);
}
menu-panel {
position: fixed;
top: var(--y, 0);
left: var(--x, 0);
max-height: calc(100vh - var(--menu-bar-height, 36px) - 16px - var(--y, 0));
display: flex;
flex-flow: column;
justify-content: flex-start;
align-items: stretch;
gap: 0;
overflow: auto;
padding: 4px;
border-radius: 8px;
pointer-events: none;
background-color: color-mix(in srgb, var(--titlebar-background-color, #030303) 50%, rgba(0, 0, 0, 0.1));
backdrop-filter: blur(8px);
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.05), 0 2px 8px rgba(0, 0, 0, 0.2);
z-index: 0;
opacity: 0;
transform: scale(0.8);
transform-origin: top left;
transition: opacity 200ms ease 0s, transform 200ms ease 0s;
}
menu-panel[open="true"] {
pointer-events: all;
opacity: 1;
transform: scale(1);
}
menu-panel.position-by-bottom {
top: unset;
bottom: calc(100vh - var(--y, 100%));
max-height: calc(var(--y, 0) - var(--menu-bar-height, 36px) - 16px);
}
menu-item {
-webkit-app-region: none;
min-height: 32px;
height: 32px;
display: grid;
grid-template-columns: 32px 1fr minmax(32px, auto);
justify-content: flex-start;
align-items: center;
border-radius: 4px;
cursor: pointer;
}
menu-item:hover {
background-color: rgba(255, 255, 255, 0.1);
}
menu-item > menu-icon {
height: 32px;
padding: 4px;
box-sizing: border-box;
}
menu-separator {
min-height: 1px;
height: 1px;
margin: 4px 0;
background-color: rgba(255, 255, 255, 0.2);
}
/* classes */
.title-bar-icon {
height: calc(100% - 8px);
object-fit: cover;
margin-left: -4px;
}
/* Window control container */
.window-controls-container {
-webkit-app-region: no-drag;
display: flex;
justify-content: flex-end; /* Align to the right end of the title-bar */
align-items: center;
gap: 4px; /* Add spacing between the window control buttons */
position: absolute; /* Position it absolutely within title-bar */
right: 4px; /* Adjust the right position as needed */
}
/* Window control buttons */
.window-control {
width: 24px;
height: 24px;
background: none;
border: none;
cursor: pointer;
display: flex;
align-items: center;
color: #f1f1f1;
font-size: 14px;
padding: 0;
}
/* youtube-music style */
ytmusic-app-layout {
margin-top: var(--menu-bar-height, 36px) !important;
}
ytmusic-app-layout>[slot=nav-bar], #nav-bar-background.ytmusic-app-layout {
top: var(--menu-bar-height, 36px) !important;
}
#nav-bar-divider.ytmusic-app-layout {
top: calc(var(--ytmusic-nav-bar-height) + var(--menu-bar-height, 36px)) !important;
}
ytmusic-app[is-bauhaus-sidenav-enabled] #guide-spacer.ytmusic-app,
ytmusic-app[is-bauhaus-sidenav-enabled] #mini-guide-spacer.ytmusic-app {
margin-top: calc(var(--ytmusic-nav-bar-height) + var(--menu-bar-height, 36px)) !important;
}
ytmusic-app-layout>[slot=player-page] {
margin-top: var(--menu-bar-height);
height: calc(100vh - var(--menu-bar-height) - var(--ytmusic-nav-bar-height) - var(--ytmusic-player-bar-height)) !important;
}
ytmusic-guide-renderer {
height: calc(100vh - var(--menu-bar-height) - var(--ytmusic-nav-bar-height)) !important;
}

View File

@ -1,203 +0,0 @@
import crypto from 'node:crypto';
import { BrowserWindow, net, shell } from 'electron';
import { setOptions } from '../../config/plugins';
import registerCallback, { SongInfo } from '../../providers/song-info';
import defaultConfig from '../../config/defaults';
import type { ConfigType } from '../../config/dynamic';
type LastFMOptions = ConfigType<'last-fm'>;
interface LastFmData {
method: string,
timestamp?: number,
}
interface LastFmSongData {
track?: string,
duration?: number,
artist?: string,
album?: string,
api_key: string,
sk?: string,
format: string,
method: string,
timestamp?: number,
api_sig?: string,
}
const createFormData = (parameters: LastFmSongData) => {
// Creates the body for in the post request
const formData = new URLSearchParams();
for (const key in parameters) {
formData.append(key, String(parameters[key as keyof LastFmSongData]));
}
return formData;
};
const createQueryString = (parameters: Record<string, unknown>, apiSignature: string) => {
// Creates a querystring
const queryData = [];
parameters.api_sig = apiSignature;
for (const key in parameters) {
queryData.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(parameters[key]))}`);
}
return '?' + queryData.join('&');
};
const createApiSig = (parameters: LastFmSongData, secret: string) => {
// This function creates the api signature, see: https://www.last.fm/api/authspec
const keys = Object.keys(parameters);
keys.sort();
let sig = '';
for (const key of keys) {
if (String(key) === 'format') {
continue;
}
sig += `${key}${parameters[key as keyof LastFmSongData]}`;
}
sig += secret;
sig = crypto.createHash('md5').update(sig, 'utf-8').digest('hex');
return sig;
};
const createToken = async ({ api_key: apiKey, api_root: apiRoot, secret }: LastFMOptions) => {
// Creates and stores the auth token
const data = {
method: 'auth.gettoken',
api_key: apiKey,
format: 'json',
};
const apiSigature = createApiSig(data, secret);
const response = await net.fetch(`${apiRoot}${createQueryString(data, apiSigature)}`);
const json = await response.json() as Record<string, string>;
return json?.token;
};
const authenticate = async (config: LastFMOptions) => {
// Asks the user for authentication
await shell.openExternal(`https://www.last.fm/api/auth/?api_key=${config.api_key}&token=${config.token}`);
};
const getAndSetSessionKey = async (config: LastFMOptions) => {
// Get and store the session key
const data = {
api_key: config.api_key,
format: 'json',
method: 'auth.getsession',
token: config.token,
};
const apiSignature = createApiSig(data, config.secret);
const response = await net.fetch(`${config.api_root}${createQueryString(data, apiSignature)}`);
const json = await response.json() as {
error?: string,
session?: {
key: string,
}
};
if (json.error) {
config.token = await createToken(config);
await authenticate(config);
setOptions('last-fm', config);
}
if (json.session) {
config.session_key = json.session.key;
}
setOptions('last-fm', config);
return config;
};
const postSongDataToAPI = async (songInfo: SongInfo, config: LastFMOptions, data: LastFmData) => {
// This sends a post request to the api, and adds the common data
if (!config.session_key) {
await getAndSetSessionKey(config);
}
const postData: LastFmSongData = {
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);
const formData = createFormData(postData);
net.fetch('https://ws.audioscrobbler.com/2.0/', { method: 'POST', body: formData })
.catch(async (error: {
response?: {
data?: {
error: number,
}
}
}) => {
if (error?.response?.data?.error === 9) {
// Session key is invalid, so remove it from the config and reauthenticate
config.session_key = undefined;
config.token = await createToken(config);
await authenticate(config);
setOptions('last-fm', config);
}
});
};
const addScrobble = (songInfo: SongInfo, config: LastFMOptions) => {
// This adds one scrobbled song to last.fm
const data = {
method: 'track.scrobble',
timestamp: Math.trunc((Date.now() - (songInfo.elapsedSeconds ?? 0)) / 1000),
};
postSongDataToAPI(songInfo, config, data);
};
const setNowPlaying = (songInfo: SongInfo, config: LastFMOptions) => {
// 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: NodeJS.Timeout | undefined;
const lastfm = async (_win: BrowserWindow, config: LastFMOptions) => {
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 halfway through, or has passed the 4-minute mark
const scrobbleTime = Math.min(Math.ceil(songInfo.songDuration / 2), 4 * 60);
if (scrobbleTime > (songInfo.elapsedSeconds ?? 0)) {
// Scrobble still needs to happen
const timeToWait = (scrobbleTime - (songInfo.elapsedSeconds ?? 0)) * 1000;
scrobbleTimer = setTimeout(addScrobble, timeToWait, songInfo, config);
}
}
});
};
export default lastfm;

View File

@ -1,82 +0,0 @@
import { BrowserWindow , net } from 'electron';
import registerCallback from '../../providers/song-info';
const secToMilisec = (t?: number) => t ? Math.round(Number(t) * 1e3) : undefined;
const previousStatePaused = null;
type LumiaData = {
origin: string;
eventType: string;
url?: string;
videoId?: string;
playlistId?: string;
cover?: string|null;
cover_url?: string|null;
title?: string;
artists?: string[];
status?: string;
progress?: number;
duration?: number;
album_url?: string|null;
album?: string|null;
views?: number;
isPaused?: boolean;
}
const data: LumiaData = {
origin: 'youtubemusic',
eventType: 'switchSong',
};
const post = (data: LumiaData) => {
const port = 39231;
const headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Access-Control-Allow-Headers': '*',
'Access-Control-Allow-Origin': '*',
};
const url = `http://localhost:${port}/api/media`;
net.fetch(url, { method: 'POST', body: JSON.stringify({ token: 'lsmedia_ytmsI7812', data }), headers })
.catch((error: { code: number, errno: number }) => {
console.log(
`Error: '${
error.code || error.errno
}' - when trying to access lumiastream webserver at port ${port}`
);
});
};
export default (_: BrowserWindow) => {
registerCallback((songInfo) => {
if (!songInfo.title && !songInfo.artist) {
return;
}
if (previousStatePaused === null) {
data.eventType = 'switchSong';
} else if (previousStatePaused !== songInfo.isPaused) {
data.eventType = 'playPause';
}
data.duration = secToMilisec(songInfo.songDuration);
data.progress = secToMilisec(songInfo.elapsedSeconds);
data.url = songInfo.url;
data.videoId = songInfo.videoId;
data.playlistId = songInfo.playlistId;
data.cover = songInfo.imageSrc;
data.cover_url = songInfo.imageSrc;
data.album_url = songInfo.imageSrc;
data.title = songInfo.title;
data.artists = [songInfo.artist];
data.status = songInfo.isPaused ? 'stopped' : 'playing';
data.isPaused = songInfo.isPaused;
data.album = songInfo.album;
data.views = songInfo.views;
post(data);
});
};

View File

@ -1,19 +0,0 @@
import { BrowserWindow, MenuItem } from 'electron';
import { LyricGeniusType, toggleRomanized } from './back';
import { setOptions } from '../../config/plugins';
import { MenuTemplate } from '../../menu';
export default (_: BrowserWindow, options: LyricGeniusType): MenuTemplate => [
{
label: 'Romanized Lyrics',
type: 'checkbox',
checked: options.romanizedLyrics,
click(item: MenuItem) {
options.romanizedLyrics = item.checked;
setOptions('lyrics-genius', options);
toggleRomanized();
},
},
];

View File

@ -1,13 +0,0 @@
import { BrowserWindow } from 'electron';
import style from './style.css';
import { injectCSS } from '../utils';
export function handle(win: BrowserWindow) {
injectCSS(win.webContents, style, () => {
win.webContents.send('navigation-css-ready');
});
}
export default handle;

View File

@ -1,20 +0,0 @@
import { ipcRenderer } from 'electron';
import forwardHTML from './templates/forward.html';
import backHTML from './templates/back.html';
import { ElementFromHtml } from '../utils';
export function run() {
ipcRenderer.on('navigation-css-ready', () => {
const forwardButton = ElementFromHtml(forwardHTML);
const backButton = ElementFromHtml(backHTML);
const menu = document.querySelector('#right-content');
if (menu) {
menu.prepend(backButton, forwardButton);
}
});
}
export default run;

View File

@ -1,33 +0,0 @@
<div
class="style-scope ytmusic-pivot-bar-renderer navigation-item"
onclick="history.back()"
role="tab"
tab-id="FEmusic_back"
>
<div
aria-disabled="false"
class="search-icon style-scope ytmusic-search-box"
role="button"
tabindex="0"
title="Go to previous page"
>
<div
class="tab-icon style-scope paper-icon-button navigation-icon"
id="icon"
>
<svg
class="style-scope iron-icon"
focusable="false"
preserveAspectRatio="xMidYMid meet"
style="pointer-events: none; display: block; width: 100%; height: 100%"
viewBox="0 0 492 492"
>
<g class="style-scope iron-icon">
<path
d="M109.3 265.2l218.9 218.9c5.1 5.1 11.8 7.9 19 7.9s14-2.8 19-7.9l16.1-16.1c10.5-10.5 10.5-27.6 0-38.1L198.6 246.1 382.7 62c5.1-5.1 7.9-11.8 7.9-19 0-7.2-2.8-14-7.9-19L366.5 7.9c-5.1-5.1-11.8-7.9-19-7.9-7.2 0-14 2.8-19 7.9L109.3 227c-5.1 5.1-7.9 11.9-7.8 19.1 0 7.2 2.8 14 7.8 19.1z"
></path>
</g>
</svg>
</div>
</div>
</div>

View File

@ -1,9 +0,0 @@
import { BrowserWindow } from 'electron';
import style from './style.css';
import { injectCSS } from '../utils';
export default (win: BrowserWindow) => {
injectCSS(win.webContents, style);
};

View File

@ -1,37 +0,0 @@
function removeLoginElements() {
const elementsToRemove = [
'.sign-in-link.ytmusic-nav-bar',
'.ytmusic-pivot-bar-renderer[tab-id="FEmusic_liked"]',
];
for (const selector of elementsToRemove) {
const node = document.querySelector(selector);
if (node) {
node.remove();
}
}
// Remove the library button
const libraryIconPath
= 'M16,6v2h-2v5c0,1.1-0.9,2-2,2s-2-0.9-2-2s0.9-2,2-2c0.37,0,0.7,0.11,1,0.28V6H16z M18,20H4V6H3v15h15V20z M21,3H6v15h15V3z M7,4h13v13H7V4z';
const observer = new MutationObserver(() => {
const menuEntries = document.querySelectorAll(
'#items ytmusic-guide-entry-renderer',
);
menuEntries.forEach((item) => {
const icon = item.querySelector('path');
if (icon) {
observer.disconnect();
if (icon.getAttribute('d') === libraryIconPath) {
item.remove();
}
}
});
});
observer.observe(document.documentElement, {
childList: true,
subtree: true,
});
}
export default removeLoginElements;

View File

@ -1,5 +0,0 @@
import { PluginConfig } from '../../config/dynamic';
const config = new PluginConfig('notifications');
export default config;

View File

@ -1,257 +0,0 @@
import path from 'node:path';
import { app, BrowserWindow, ipcMain, Notification } from 'electron';
import { notificationImage, secondsToMinutes, ToastStyles } from './utils';
import config from './config';
import getSongControls from '../../providers/song-controls';
import registerCallback, { SongInfo } from '../../providers/song-info';
import { changeProtocolHandler } from '../../providers/protocol-handler';
import { setTrayOnClick, setTrayOnDoubleClick } from '../../tray';
import { getMediaIconLocation, mediaIcons, saveMediaIcon } from '../utils';
let songControls: ReturnType<typeof getSongControls>;
let savedNotification: Notification | undefined;
export default (win: BrowserWindow) => {
songControls = getSongControls(win);
let currentSeconds = 0;
ipcMain.on('apiLoaded', () => win.webContents.send('setupTimeChangedListener'));
ipcMain.on('timeChanged', (_, t: number) => currentSeconds = t);
if (app.isPackaged) {
saveMediaIcon();
}
let savedSongInfo: SongInfo;
let lastUrl: string | undefined;
// Register songInfoCallback
registerCallback((songInfo) => {
if (!songInfo.artist && !songInfo.title) {
return;
}
savedSongInfo = { ...songInfo };
if (!songInfo.isPaused
&& (songInfo.url !== lastUrl || config.get('unpauseNotification'))
) {
lastUrl = songInfo.url;
sendNotification(songInfo);
}
});
if (config.get('trayControls')) {
setTrayOnClick(() => {
if (savedNotification) {
savedNotification.close();
savedNotification = undefined;
} else if (savedSongInfo) {
sendNotification({
...savedSongInfo,
elapsedSeconds: currentSeconds,
});
}
});
setTrayOnDoubleClick(() => {
if (win.isVisible()) {
win.hide();
} else {
win.show();
}
});
}
app.once('before-quit', () => {
savedNotification?.close();
});
changeProtocolHandler(
(cmd) => {
if (Object.keys(songControls).includes(cmd)) {
songControls[cmd as keyof typeof songControls]();
if (config.get('refreshOnPlayPause') && (
cmd === 'pause'
|| (cmd === 'play' && !config.get('unpauseNotification'))
)
) {
setImmediate(() =>
sendNotification({
...savedSongInfo,
isPaused: cmd === 'pause',
elapsedSeconds: currentSeconds,
}),
);
}
}
},
);
};
function sendNotification(songInfo: SongInfo) {
const iconSrc = notificationImage(songInfo);
savedNotification?.close();
let icon: string;
if (typeof iconSrc === 'object') {
icon = iconSrc.toDataURL();
} else {
icon = iconSrc;
}
savedNotification = new Notification({
title: songInfo.title || 'Playing',
body: songInfo.artist,
icon: iconSrc,
silent: true,
// https://learn.microsoft.com/en-us/uwp/schemas/tiles/toastschema/schema-root
// https://learn.microsoft.com/en-us/windows/apps/design/shell/tiles-and-notifications/toast-schema
// https://learn.microsoft.com/en-us/windows/apps/design/shell/tiles-and-notifications/adaptive-interactive-toasts?tabs=xml
// https://learn.microsoft.com/en-us/uwp/api/windows.ui.notifications.toasttemplatetype
toastXml: getXml(songInfo, icon),
});
savedNotification.on('close', () => {
savedNotification = undefined;
});
savedNotification.show();
}
const getXml = (songInfo: SongInfo, iconSrc: string) => {
switch (config.get('toastStyle')) {
default:
case ToastStyles.logo:
case ToastStyles.legacy: {
return xmlLogo(songInfo, iconSrc);
}
case ToastStyles.banner_top_custom: {
return xmlBannerTopCustom(songInfo, iconSrc);
}
case ToastStyles.hero: {
return xmlHero(songInfo, iconSrc);
}
case ToastStyles.banner_bottom: {
return xmlBannerBottom(songInfo, iconSrc);
}
case ToastStyles.banner_centered_bottom: {
return xmlBannerCenteredBottom(songInfo, iconSrc);
}
case ToastStyles.banner_centered_top: {
return xmlBannerCenteredTop(songInfo, iconSrc);
}
}
};
const display = (kind: keyof typeof mediaIcons) => {
if (config.get('toastStyle') === ToastStyles.legacy) {
return `content="${mediaIcons[kind]}"`;
}
return `\
content="${config.get('hideButtonText') ? '' : kind.charAt(0).toUpperCase() + kind.slice(1)}"\
imageUri="file:///${path.resolve(getMediaIconLocation(), `${kind}.png`)}"
`;
};
const getButton = (kind: keyof typeof mediaIcons) =>
`<action ${display(kind)} activationType="protocol" arguments="youtubemusic://${kind}"/>`;
const getButtons = (isPaused: boolean) => `\
<actions>
${getButton('previous')}
${isPaused ? getButton('play') : getButton('pause')}
${getButton('next')}
</actions>\
`;
const toast = (content: string, isPaused: boolean) => `\
<toast>
<audio silent="true" />
<visual>
<binding template="ToastGeneric">
${content}
</binding>
</visual>
${getButtons(isPaused)}
</toast>`;
const xmlImage = ({ title, artist, isPaused }: SongInfo, imgSrc: string, placement: string) => toast(`\
<image id="1" src="${imgSrc}" name="Image" ${placement}/>
<text id="1">${title}</text>
<text id="2">${artist}</text>\
`, isPaused ?? false);
const xmlLogo = (songInfo: SongInfo, imgSrc: string) => xmlImage(songInfo, imgSrc, 'placement="appLogoOverride"');
const xmlHero = (songInfo: SongInfo, imgSrc: string) => xmlImage(songInfo, imgSrc, 'placement="hero"');
const xmlBannerBottom = (songInfo: SongInfo, imgSrc: string) => xmlImage(songInfo, imgSrc, '');
const xmlBannerTopCustom = (songInfo: SongInfo, imgSrc: string) => toast(`\
<image id="1" src="${imgSrc}" name="Image" />
<text></text>
<group>
<subgroup>
<text hint-style="body">${songInfo.title}</text>
<text hint-style="captionSubtle">${songInfo.artist}</text>
</subgroup>
${xmlMoreData(songInfo)}
</group>\
`, songInfo.isPaused ?? false);
const xmlMoreData = ({ album, elapsedSeconds, songDuration }: SongInfo) => `\
<subgroup hint-textStacking="bottom">
${album
? `<text hint-style="captionSubtle" hint-wrap="true" hint-align="right">${album}</text>` : ''}
<text hint-style="captionSubtle" hint-wrap="true" hint-align="right">${secondsToMinutes(elapsedSeconds ?? 0)} / ${secondsToMinutes(songDuration)}</text>
</subgroup>\
`;
const xmlBannerCenteredBottom = ({ title, artist, isPaused }: SongInfo, imgSrc: string) => toast(`\
<text></text>
<group>
<subgroup hint-weight="1" hint-textStacking="center">
<text hint-align="center" hint-style="${titleFontPicker(title)}">${title}</text>
<text hint-align="center" hint-style="SubtitleSubtle">${artist}</text>
</subgroup>
</group>
<image id="1" src="${imgSrc}" name="Image" hint-removeMargin="true" />\
`, isPaused ?? false);
const xmlBannerCenteredTop = ({ title, artist, isPaused }: SongInfo, imgSrc: string) => toast(`\
<image id="1" src="${imgSrc}" name="Image" />
<text></text>
<group>
<subgroup hint-weight="1" hint-textStacking="center">
<text hint-align="center" hint-style="${titleFontPicker(title)}">${title}</text>
<text hint-align="center" hint-style="SubtitleSubtle">${artist}</text>
</subgroup>
</group>\
`, isPaused ?? false);
const titleFontPicker = (title: string) => {
if (title.length <= 13) {
return 'Header';
}
if (title.length <= 22) {
return 'Subheader';
}
if (title.length <= 26) {
return 'Title';
}
return 'Subtitle';
};

View File

@ -1,93 +0,0 @@
import is from 'electron-is';
import { BrowserWindow, MenuItem } from 'electron';
import { snakeToCamel, ToastStyles, urgencyLevels } from './utils';
import config from './config';
import { MenuTemplate } from '../../menu';
import type { ConfigType } from '../../config/dynamic';
const getMenu = (options: ConfigType<'notifications'>): MenuTemplate => {
if (is.linux()) {
return [
{
label: 'Notification Priority',
submenu: urgencyLevels.map((level) => ({
label: level.name,
type: 'radio',
checked: options.urgency === level.value,
click: () => config.set('urgency', level.value),
})),
}
];
} else if (is.windows()) {
return [
{
label: 'Interactive Notifications',
type: 'checkbox',
checked: options.interactive,
// Doesn't update until restart
click: (item: MenuItem) => config.setAndMaybeRestart('interactive', item.checked),
},
{
// Submenu with settings for interactive notifications (name shouldn't be too long)
label: 'Interactive Settings',
submenu: [
{
label: 'Open/Close on tray click',
type: 'checkbox',
checked: options.trayControls,
click: (item: MenuItem) => config.set('trayControls', item.checked),
},
{
label: 'Hide Button Text',
type: 'checkbox',
checked: options.hideButtonText,
click: (item: MenuItem) => config.set('hideButtonText', item.checked),
},
{
label: 'Refresh on Play/Pause',
type: 'checkbox',
checked: options.refreshOnPlayPause,
click: (item: MenuItem) => config.set('refreshOnPlayPause', item.checked),
},
],
},
{
label: 'Style',
submenu: getToastStyleMenuItems(options),
},
];
} else {
return [];
}
};
export default (_win: BrowserWindow, options: ConfigType<'notifications'>): MenuTemplate => [
...getMenu(options),
{
label: 'Show notification on unpause',
type: 'checkbox',
checked: options.unpauseNotification,
click: (item: MenuItem) => config.set('unpauseNotification', item.checked),
},
];
export function getToastStyleMenuItems(options: ConfigType<'notifications'>) {
const array = Array.from({ length: Object.keys(ToastStyles).length });
// ToastStyles index starts from 1
for (const [name, index] of Object.entries(ToastStyles)) {
array[index - 1] = {
label: snakeToCamel(name),
type: 'radio',
checked: options.toastStyle === index,
click: () => config.set('toastStyle', index),
} satisfies Electron.MenuItemConstructorOptions;
}
return array as Electron.MenuItemConstructorOptions[];
}

View File

@ -1,111 +0,0 @@
import { app, BrowserWindow, ipcMain } from 'electron';
import style from './style.css';
import { injectCSS } from '../utils';
import { setOptions as setPluginOptions } from '../../config/plugins';
import type { ConfigType } from '../../config/dynamic';
let isInPiP = false;
let originalPosition: number[];
let originalSize: number[];
let originalFullScreen: boolean;
let originalMaximized: boolean;
let win: BrowserWindow;
type PiPOptions = ConfigType<'picture-in-picture'>;
let options: Partial<PiPOptions>;
const pipPosition = () => (options.savePosition && options['pip-position']) || [10, 10];
const pipSize = () => (options.saveSize && options['pip-size']) || [450, 275];
const setLocalOptions = (_options: Partial<PiPOptions>) => {
options = { ...options, ..._options };
setPluginOptions('picture-in-picture', _options);
};
const togglePiP = () => {
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.setMaximizable(false);
win.setFullScreenable(false);
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.setMaximizable(true);
win.setFullScreenable(true);
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: Electron.Event, input: Electron.Input) => {
const key = input.key.toLowerCase();
if (key === 'f') {
event.preventDefault();
} else if (key === 'escape') {
togglePiP();
event.preventDefault();
}
};
export default (_win: BrowserWindow, _options: PiPOptions) => {
options ??= _options;
win ??= _win;
setLocalOptions({ isInPiP });
injectCSS(win.webContents, style);
ipcMain.on('picture-in-picture', () => {
togglePiP();
});
};
export const setOptions = setLocalOptions;

View File

@ -1,75 +0,0 @@
import prompt from 'custom-electron-prompt';
import { BrowserWindow } from 'electron';
import { setOptions } from './back';
import promptOptions from '../../providers/prompt-options';
import { MenuTemplate } from '../../menu';
import type { ConfigType } from '../../config/dynamic';
export default (win: BrowserWindow, options: ConfigType<'picture-in-picture'>): MenuTemplate => [
{
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,
async click(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;
}
},
},
{
label: 'Use native PiP',
type: 'checkbox',
checked: options.useNativePiP,
click(item) {
setOptions({ useNativePiP: item.checked });
},
},
];

View File

@ -1,117 +0,0 @@
import sliderHTML from './templates/slider.html';
import { getSongMenu } from '../../providers/dom-elements';
import { ElementFromHtml } from '../utils';
import { singleton } from '../../providers/decorators';
function $<E extends Element = Element>(selector: string) {
return document.querySelector<E>(selector);
}
const slider = ElementFromHtml(sliderHTML);
const roundToTwo = (n: number) => Math.round(n * 1e2) / 1e2;
const MIN_PLAYBACK_SPEED = 0.07;
const MAX_PLAYBACK_SPEED = 16;
let playbackSpeed = 1;
const updatePlayBackSpeed = () => {
const videoElement = $<HTMLVideoElement>('video');
if (videoElement) {
videoElement.playbackRate = playbackSpeed;
}
const playbackSpeedElement = $('#playback-speed-value');
if (playbackSpeedElement) {
playbackSpeedElement.innerHTML = String(playbackSpeed);
}
};
let menu: Element | null = null;
const setupSliderListener = singleton(() => {
$('#playback-speed-slider')?.addEventListener('immediate-value-changed', (e) => {
playbackSpeed = (e as CustomEvent<{ value: number; }>).detail.value || MIN_PLAYBACK_SPEED;
if (isNaN(playbackSpeed)) {
playbackSpeed = 1;
}
updatePlayBackSpeed();
});
});
const observePopupContainer = () => {
const observer = new MutationObserver(() => {
if (!menu) {
menu = getSongMenu();
}
if (
menu &&
(menu.parentElement as HTMLElement & { eventSink_: Element | null })
?.eventSink_
?.matches('ytmusic-menu-renderer.ytmusic-player-bar')&& !menu.contains(slider)
) {
menu.prepend(slider);
setupSliderListener();
}
});
const popupContainer = $('ytmusic-popup-container');
if (popupContainer) {
observer.observe(popupContainer, {
childList: true,
subtree: true,
});
}
};
const observeVideo = () => {
const video = $<HTMLVideoElement>('video');
if (video) {
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
const playbackSpeedSilder = $<HTMLElement & { value: number }>('#playback-speed-slider');
if (playbackSpeedSilder) {
playbackSpeedSilder.value = playbackSpeed;
}
});
};
function forcePlaybackRate(e: Event) {
if (e.target instanceof HTMLVideoElement) {
const videoElement = e.target;
if (videoElement.playbackRate !== playbackSpeed) {
videoElement.playbackRate = playbackSpeed;
}
}
}
export default () => {
document.addEventListener('apiLoaded', () => {
observePopupContainer();
observeVideo();
setupWheelListener();
}, { once: true, passive: true });
};

View File

@ -1,28 +0,0 @@
import { globalShortcut, BrowserWindow } from 'electron';
import volumeHudStyle from './volume-hud.css';
import { injectCSS } from '../utils';
import type { ConfigType } from '../../config/dynamic';
/*
This is used to determine if plugin is actually active
(not if it's only enabled in options)
*/
let isEnabled = false;
export const enabled = () => isEnabled;
export default (win: BrowserWindow, options: ConfigType<'precise-volume'>) => {
isEnabled = true;
injectCSS(win.webContents, volumeHudStyle);
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));
}
};

View File

@ -1,270 +0,0 @@
import { ipcRenderer } from 'electron';
import { setOptions, setMenuOptions, isEnabled } from '../../config/plugins';
import { debounce } from '../../providers/decorators';
import { YoutubePlayer } from '../../types/youtube-player';
import type { ConfigType } from '../../config/dynamic';
function $<E extends Element = Element>(selector: string) {
return document.querySelector<E>(selector);
}
let api: YoutubePlayer;
let options: ConfigType<'precise-volume'>;
export default (_options: ConfigType<'precise-volume'>) => {
options = _options;
document.addEventListener('apiLoaded', (e) => {
api = e.detail;
ipcRenderer.on('changeVolume', (_, toIncrease: boolean) => changeVolume(toIncrease));
ipcRenderer.on('setVolume', (_, value: number) => setVolume(value));
firstRun();
}, { once: true, passive: true });
};
// Without this function it would rewrite config 20 time when volume change by 20
const writeOptions = debounce(() => {
setOptions('precise-volume', options);
}, 1000);
export const moveVolumeHud = debounce((showVideo: boolean) => {
const volumeHud = $<HTMLElement>('#volumeHud');
if (!volumeHud) {
return;
}
volumeHud.style.top = showVideo
? `${($('ytmusic-player')!.clientHeight - $('video')!.clientHeight) / 2}px`
: '0';
}, 250);
const hideVolumeHud = debounce((volumeHud: HTMLElement) => {
volumeHud.style.opacity = '0';
}, 2000);
const hideVolumeSlider = debounce((slider: HTMLElement) => {
slider.classList.remove('on-hover');
}, 2500);
/** 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) {
setVolume(options.savedVolume);
}
}
setupPlaybar();
setupLocalArrowShortcuts();
// Workaround: computedStyleMap().get(string) returns CSSKeywordValue instead of CSSStyleValue
const noVid = ($('#main-panel')?.computedStyleMap().get('display') as CSSKeywordValue)?.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: boolean) {
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>`,
);
}
}
function showVolumeHud(volume: number) {
const volumeHud = $<HTMLElement>('#volumeHud');
if (!volumeHud) {
return;
}
volumeHud.textContent = `${volume}%`;
volumeHud.style.opacity = '1';
hideVolumeHud(volumeHud);
}
/** Add onwheel event to video player */
function setupVideoPlayerOnwheel() {
const panel = $<HTMLElement>('#main-panel');
if (!panel) return;
panel.addEventListener('wheel', (event) => {
event.preventDefault();
// Event.deltaY < 0 means wheel-up
changeVolume(event.deltaY < 0);
});
}
function saveVolume(volume: number) {
options.savedVolume = volume;
writeOptions();
}
/** Add onwheel event to play bar and also track if play bar is hovered */
function setupPlaybar() {
const playerbar = $<HTMLElement>('ytmusic-player-bar');
if (!playerbar) return;
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) {
if (mutation.target instanceof HTMLInputElement) {
// This checks that volume-slider was manually set
const target = mutation.target;
const targetValueNumeric = Number(target.value);
if (mutation.oldValue !== target.value
&& (typeof options.savedVolume !== 'number' || Math.abs(options.savedVolume - targetValueNumeric) > 4)) {
// Diff>4 means it was manually set
setTooltip(targetValueNumeric);
saveVolume(targetValueNumeric);
}
}
}
});
const slider = $('#volume-slider');
if (!slider) return;
// Observing only changes in 'value' of volume-slider
sliderObserver.observe(slider, {
attributeFilter: ['value'],
attributeOldValue: true,
});
}
function setVolume(value: number) {
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: boolean) {
// 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() {
const savedVolume = options.savedVolume ?? 0;
// Slider value automatically rounds to multiples of 5
for (const slider of ['#volume-slider', '#expand-volume-slider']) {
const silderElement = $<HTMLInputElement>(slider);
if (silderElement) {
silderElement.value = String(savedVolume > 0 && savedVolume < 5 ? 5 : savedVolume);
}
}
}
function showVolumeSlider() {
const slider = $<HTMLElement>('#volume-slider');
if (!slider) return;
// This class display the volume slider if not in minimized mode
slider.classList.add('on-hover');
hideVolumeSlider(slider);
}
// 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: number) {
for (const target of tooltipTargets) {
const tooltipTargetElement = $<HTMLElement>(target);
if (tooltipTargetElement) {
tooltipTargetElement.title = `${volume}%`;
}
}
}
function setupLocalArrowShortcuts() {
if (options.arrowsShortcut) {
window.addEventListener('keydown', (event) => {
if ($<HTMLElement & { opened: boolean }>('ytmusic-search-box')?.opened) {
return;
}
switch (event.code) {
case 'ArrowUp': {
event.preventDefault();
changeVolume(true);
break;
}
case 'ArrowDown': {
event.preventDefault();
changeVolume(false);
break;
}
}
});
}
}

View File

@ -1,94 +0,0 @@
import prompt, { KeybindOptions } from 'custom-electron-prompt';
import { BrowserWindow, MenuItem } from 'electron';
import { enabled } from './back';
import { setMenuOptions } from '../../config/plugins';
import promptOptions from '../../providers/prompt-options';
import { MenuTemplate } from '../../menu';
import type { ConfigType } from '../../config/dynamic';
function changeOptions(changedOptions: Partial<ConfigType<'precise-volume'>>, options: ConfigType<'precise-volume'>, win: BrowserWindow) {
for (const option in changedOptions) {
// HACK: Weird TypeScript error
(options as Record<string, unknown>)[option] = (changedOptions as Record<string, unknown>)[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);
}
}
export default (win: BrowserWindow, options: ConfigType<'precise-volume'>): MenuTemplate => [
{
label: 'Local Arrowkeys Controls',
type: 'checkbox',
checked: Boolean(options.arrowsShortcut),
click(item) {
changeOptions({ arrowsShortcut: item.checked }, options, win);
},
},
{
label: 'Global Hotkeys',
type: 'checkbox',
checked: Boolean(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_: string, value_: string, default_: string): KeybindOptions => ({ 'value': value_, 'label': label_, 'default': default_ || undefined });
async function promptVolumeSteps(win: BrowserWindow, options: ConfigType<'precise-volume'>) {
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: BrowserWindow, options: ConfigType<'precise-volume'>, item: MenuItem) {
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) {
const newGlobalShortcuts: {
volumeUp: string;
volumeDown: string;
} = { volumeUp: '', volumeDown: '' };
for (const { value, accelerator } of output) {
newGlobalShortcuts[value as keyof typeof newGlobalShortcuts] = accelerator;
}
changeOptions({ globalShortcuts: newGlobalShortcuts }, options, win);
item.checked = Boolean(options.globalShortcuts.volumeUp) || Boolean(options.globalShortcuts.volumeDown);
} else {
// Reset checkbox if prompt was canceled
item.checked = !item.checked;
}
}

View File

@ -1,41 +0,0 @@
/* what */
/* eslint-disable @typescript-eslint/ban-ts-comment */
import is from 'electron-is';
const ignored = {
id: ['volume-slider', 'expand-volume-slider'],
types: ['mousewheel', 'keydown', 'keyup'],
};
function overrideAddEventListener() {
// YO WHAT ARE YOU DOING NOW?!?!
// Save native addEventListener
// @ts-ignore
// eslint-disable-next-line @typescript-eslint/unbound-method
Element.prototype._addEventListener = Element.prototype.addEventListener;
// Override addEventListener to Ignore specific events in volume-slider
Element.prototype.addEventListener = function (type: string, listener: (event: Event) => void, useCapture = false) {
if (!(
ignored.id.includes(this.id)
&& ignored.types.includes(type)
)) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any,@typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
(this as any)._addEventListener(type, listener, useCapture);
} else if (is.dev()) {
console.log(`Ignoring event: "${this.id}.${type}()"`);
}
};
}
export default () => {
overrideAddEventListener();
// Restore original function after finished loading to avoid keeping Element.prototype altered
window.addEventListener('load', () => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-explicit-any,@typescript-eslint/no-unsafe-member-access
Element.prototype.addEventListener = (Element.prototype as any)._addEventListener;
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-explicit-any,@typescript-eslint/no-unsafe-member-access
(Element.prototype as any)._addEventListener = undefined;
}, { once: true });
};

View File

@ -1,13 +0,0 @@
import { ipcMain, dialog } from 'electron';
export default () => {
ipcMain.handle('qualityChanger', async (_, qualityLabels: string[], currentIndex: number) => await dialog.showMessageBox({
type: 'question',
buttons: qualityLabels,
defaultId: currentIndex,
title: 'Choose Video Quality',
message: 'Choose Video Quality:',
detail: `Current Quality: ${qualityLabels[currentIndex]}`,
cancelId: -1,
}));
};

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