Compare commits

...

18 Commits

Author SHA1 Message Date
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
26 changed files with 597 additions and 373 deletions

View File

@ -2,8 +2,45 @@
All notable changes to this project will be documented in this file. Dates are displayed in UTC. All notable changes to this project will be documented in this file. Dates are displayed in UTC.
#### [v3.5.0](https://github.com/th-ch/youtube-music/compare/v3.4.1...v3.5.0)
- 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) #### [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(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(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 touchbar icon [`#2183`](https://github.com/th-ch/youtube-music/issues/2183)

View File

@ -51,6 +51,7 @@ export default defineConfig({
}; };
if (mode === 'development') { if (mode === 'development') {
commonConfig.build!.sourcemap = 'inline';
commonConfig.plugins?.push( commonConfig.plugins?.push(
Inspect({ Inspect({
build: true, build: true,
@ -98,6 +99,7 @@ export default defineConfig({
}; };
if (mode === 'development') { if (mode === 'development') {
commonConfig.build!.sourcemap = 'inline';
commonConfig.plugins?.push( commonConfig.plugins?.push(
Inspect({ Inspect({
build: true, build: true,
@ -148,6 +150,7 @@ export default defineConfig({
}; };
if (mode === 'development') { if (mode === 'development') {
commonConfig.build!.sourcemap = 'inline';
commonConfig.plugins?.push( commonConfig.plugins?.push(
Inspect({ Inspect({
build: true, build: true,

View File

@ -1,7 +1,7 @@
{ {
"name": "youtube-music", "name": "youtube-music",
"productName": "YouTube Music", "productName": "YouTube Music",
"version": "3.5.0", "version": "3.5.1",
"description": "YouTube Music Desktop App - including custom plugins", "description": "YouTube Music Desktop App - including custom plugins",
"main": "./dist/main/index.js", "main": "./dist/main/index.js",
"license": "MIT", "license": "MIT",
@ -116,7 +116,7 @@
"vite:inspect": "pnpm clean && electron-vite build --mode development && pnpm exec serve .vite-inspect", "vite:inspect": "pnpm clean && electron-vite build --mode development && pnpm exec serve .vite-inspect",
"start": "electron-vite preview", "start": "electron-vite preview",
"start:debug": "cross-env ELECTRON_ENABLE_LOGGING=1 pnpm start", "start:debug": "cross-env ELECTRON_ENABLE_LOGGING=1 pnpm start",
"dev": "electron-vite dev --watch", "dev": "cross-env NODE_OPTIONS=--enable-source-maps electron-vite dev --watch",
"dev:debug": "cross-env ELECTRON_ENABLE_LOGGING=1 pnpm dev", "dev:debug": "cross-env ELECTRON_ENABLE_LOGGING=1 pnpm dev",
"clean": "del-cli dist && del-cli pack && del-cli .vite-inspect", "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": "pnpm clean && pnpm build && pnpm electron-builder --win --mac --linux -p never",
@ -149,7 +149,6 @@
}, },
"patchedDependencies": { "patchedDependencies": {
"vudio@2.1.1": "patches/vudio@2.1.1.patch", "vudio@2.1.1": "patches/vudio@2.1.1.patch",
"@xhayper/discord-rpc@1.1.4": "patches/@xhayper__discord-rpc@1.1.4.patch",
"app-builder-lib@24.13.3": "patches/app-builder-lib@24.13.3.patch" "app-builder-lib@24.13.3": "patches/app-builder-lib@24.13.3.patch"
} }
}, },
@ -165,7 +164,7 @@
"@jellybrick/electron-better-web-request": "1.0.4", "@jellybrick/electron-better-web-request": "1.0.4",
"@jellybrick/mpris-service": "2.1.4", "@jellybrick/mpris-service": "2.1.4",
"@skyra/jaro-winkler": "^1.1.1", "@skyra/jaro-winkler": "^1.1.1",
"@xhayper/discord-rpc": "1.1.4", "@xhayper/discord-rpc": "1.2.0",
"async-mutex": "0.5.0", "async-mutex": "0.5.0",
"butterchurn": "3.0.0-beta.4", "butterchurn": "3.0.0-beta.4",
"butterchurn-presets": "3.0.0-beta.4", "butterchurn-presets": "3.0.0-beta.4",
@ -201,7 +200,7 @@
"ts-morph": "23.0.0", "ts-morph": "23.0.0",
"vudio": "2.1.1", "vudio": "2.1.1",
"x11": "2.3.0", "x11": "2.3.0",
"youtubei.js": "10.2.0" "youtubei.js": "10.3.0"
}, },
"devDependencies": { "devDependencies": {
"@playwright/test": "1.45.3", "@playwright/test": "1.45.3",
@ -211,8 +210,8 @@
"@types/howler": "2.2.11", "@types/howler": "2.2.11",
"@types/html-to-text": "9.0.4", "@types/html-to-text": "9.0.4",
"@types/semver": "7.5.8", "@types/semver": "7.5.8",
"@typescript-eslint/eslint-plugin": "7.18.0", "@typescript-eslint/eslint-plugin": "8.0.0",
"@typescript-eslint/parser": "7.18.0", "@typescript-eslint/parser": "8.0.0",
"bufferutil": "4.0.8", "bufferutil": "4.0.8",
"builtin-modules": "4.0.0", "builtin-modules": "4.0.0",
"cross-env": "7.0.3", "cross-env": "7.0.3",
@ -231,7 +230,7 @@
"glob": "11.0.0", "glob": "11.0.0",
"node-gyp": "10.2.0", "node-gyp": "10.2.0",
"playwright": "1.45.3", "playwright": "1.45.3",
"rollup": "4.19.1", "rollup": "4.19.2",
"typescript": "5.5.4", "typescript": "5.5.4",
"utf-8-validate": "6.0.4", "utf-8-validate": "6.0.4",
"vite": "5.3.5", "vite": "5.3.5",

View File

@ -1,17 +0,0 @@
diff --git a/package.json b/package.json
index 40db5dfbd8a4455ce2987d8115eca9882e1f9f14..414fc6986b9c0cc288908eb0107b90c4bfd916b2 100644
--- a/package.json
+++ b/package.json
@@ -25,11 +25,7 @@
},
"dependencies": {
"axios": "^1.7.2",
- "ws": "^8.18.0"
- },
- "optionalDependencies": {
- "bufferutil": "^4.0.8",
- "utf-8-validate": "^6.0.4"
+ "ws": "^8.18.0"
},
"devDependencies": {
"@types/node": "^14.*",

447
pnpm-lock.yaml generated
View File

@ -13,9 +13,6 @@ overrides:
'@babel/runtime': 7.25.0 '@babel/runtime': 7.25.0
patchedDependencies: patchedDependencies:
'@xhayper/discord-rpc@1.1.4':
hash: n7icacbfxuqlodunyqwwt5lccm
path: patches/@xhayper__discord-rpc@1.1.4.patch
app-builder-lib@24.13.3: app-builder-lib@24.13.3:
hash: zcnm2qnjaggm2keyecnhiglkke hash: zcnm2qnjaggm2keyecnhiglkke
path: patches/app-builder-lib@24.13.3.patch path: patches/app-builder-lib@24.13.3.patch
@ -61,8 +58,8 @@ importers:
specifier: ^1.1.1 specifier: ^1.1.1
version: 1.1.1 version: 1.1.1
'@xhayper/discord-rpc': '@xhayper/discord-rpc':
specifier: 1.1.4 specifier: 1.2.0
version: 1.1.4(patch_hash=n7icacbfxuqlodunyqwwt5lccm) version: 1.2.0(bufferutil@4.0.8)(utf-8-validate@6.0.4)
async-mutex: async-mutex:
specifier: 0.5.0 specifier: 0.5.0
version: 0.5.0 version: 0.5.0
@ -169,8 +166,8 @@ importers:
specifier: 2.3.0 specifier: 2.3.0
version: 2.3.0 version: 2.3.0
youtubei.js: youtubei.js:
specifier: 10.2.0 specifier: 10.3.0
version: 10.2.0 version: 10.3.0
devDependencies: devDependencies:
'@playwright/test': '@playwright/test':
specifier: 1.45.3 specifier: 1.45.3
@ -194,11 +191,11 @@ importers:
specifier: 7.5.8 specifier: 7.5.8
version: 7.5.8 version: 7.5.8
'@typescript-eslint/eslint-plugin': '@typescript-eslint/eslint-plugin':
specifier: 7.18.0 specifier: 8.0.0
version: 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4) version: 8.0.0(@typescript-eslint/parser@8.0.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4)
'@typescript-eslint/parser': '@typescript-eslint/parser':
specifier: 7.18.0 specifier: 8.0.0
version: 7.18.0(eslint@8.57.0)(typescript@5.5.4) version: 8.0.0(eslint@8.57.0)(typescript@5.5.4)
bufferutil: bufferutil:
specifier: 4.0.8 specifier: 4.0.8
version: 4.0.8 version: 4.0.8
@ -234,13 +231,13 @@ importers:
version: 8.57.0 version: 8.57.0
eslint-import-resolver-exports: eslint-import-resolver-exports:
specifier: 1.0.0-beta.5 specifier: 1.0.0-beta.5
version: 1.0.0-beta.5(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0))(eslint@8.57.0) version: 1.0.0-beta.5(eslint-plugin-import@2.29.1(@typescript-eslint/parser@8.0.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0))(eslint@8.57.0)
eslint-import-resolver-typescript: eslint-import-resolver-typescript:
specifier: 3.6.1 specifier: 3.6.1
version: 3.6.1(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint-plugin-import@2.29.1)(eslint@8.57.0) version: 3.6.1(@typescript-eslint/parser@8.0.0(eslint@8.57.0)(typescript@5.5.4))(eslint-plugin-import@2.29.1)(eslint@8.57.0)
eslint-plugin-import: eslint-plugin-import:
specifier: 2.29.1 specifier: 2.29.1
version: 2.29.1(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) version: 2.29.1(@typescript-eslint/parser@8.0.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
eslint-plugin-prettier: eslint-plugin-prettier:
specifier: 5.2.1 specifier: 5.2.1
version: 5.2.1(eslint@8.57.0)(prettier@3.2.5) version: 5.2.1(eslint@8.57.0)(prettier@3.2.5)
@ -254,8 +251,8 @@ importers:
specifier: 1.45.3 specifier: 1.45.3
version: 1.45.3 version: 1.45.3
rollup: rollup:
specifier: 4.19.1 specifier: 4.19.2
version: 4.19.1 version: 4.19.2
typescript: typescript:
specifier: 5.5.4 specifier: 5.5.4
version: 5.5.4 version: 5.5.4
@ -267,7 +264,7 @@ importers:
version: 5.3.5(@types/node@20.12.5) version: 5.3.5(@types/node@20.12.5)
vite-plugin-inspect: vite-plugin-inspect:
specifier: 0.8.5 specifier: 0.8.5
version: 0.8.5(rollup@4.19.1)(vite@5.3.5(@types/node@20.12.5)) version: 0.8.5(rollup@4.19.2)(vite@5.3.5(@types/node@20.12.5))
vite-plugin-resolve: vite-plugin-resolve:
specifier: 2.5.2 specifier: 2.5.2
version: 2.5.2 version: 2.5.2
@ -431,6 +428,18 @@ packages:
resolution: {integrity: sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig==} resolution: {integrity: sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig==}
engines: {node: '>= 8.9.0'} engines: {node: '>= 8.9.0'}
'@discordjs/collection@2.1.0':
resolution: {integrity: sha512-mLcTACtXUuVgutoznkh6hS3UFqYirDYAg5Dc1m8xn6OvPjetnUlf/xjtqnnc47OwWdaoCQnHmHh9KofhD6uRqw==}
engines: {node: '>=18'}
'@discordjs/rest@2.3.0':
resolution: {integrity: sha512-C1kAJK8aSYRv3ZwMG8cvrrW4GN0g5eMdP8AuN8ODH5DyOCbHgJspze1my3xHOAgwLJdKUbWNVyAeJ9cEdduqIg==}
engines: {node: '>=16.11.0'}
'@discordjs/util@1.1.0':
resolution: {integrity: sha512-IndcI5hzlNZ7GS96RV3Xw1R2kaDuXEp7tRIy/KlhidpN/BQ1qh1NZt3377dMLTa44xDUNKT7hnXkA/oUAzD/lg==}
engines: {node: '>=16.11.0'}
'@electron-toolkit/tsconfig@1.0.1': '@electron-toolkit/tsconfig@1.0.1':
resolution: {integrity: sha512-M0Mol3odspvtCuheyujLNAW7bXq7KFNYVMRtpjFa4ZfES4MuklXBC7Nli/omvc+PRKlrklgAGx3l4VakjNo8jg==} resolution: {integrity: sha512-M0Mol3odspvtCuheyujLNAW7bXq7KFNYVMRtpjFa4ZfES4MuklXBC7Nli/omvc+PRKlrklgAGx3l4VakjNo8jg==}
peerDependencies: peerDependencies:
@ -906,86 +915,94 @@ packages:
rollup: rollup:
optional: true optional: true
'@rollup/rollup-android-arm-eabi@4.19.1': '@rollup/rollup-android-arm-eabi@4.19.2':
resolution: {integrity: sha512-XzqSg714++M+FXhHfXpS1tDnNZNpgxxuGZWlRG/jSj+VEPmZ0yg6jV4E0AL3uyBKxO8mO3xtOsP5mQ+XLfrlww==} resolution: {integrity: sha512-OHflWINKtoCFSpm/WmuQaWW4jeX+3Qt3XQDepkkiFTsoxFc5BpF3Z5aDxFZgBqRjO6ATP5+b1iilp4kGIZVWlA==}
cpu: [arm] cpu: [arm]
os: [android] os: [android]
'@rollup/rollup-android-arm64@4.19.1': '@rollup/rollup-android-arm64@4.19.2':
resolution: {integrity: sha512-thFUbkHteM20BGShD6P08aungq4irbIZKUNbG70LN8RkO7YztcGPiKTTGZS7Kw+x5h8hOXs0i4OaHwFxlpQN6A==} resolution: {integrity: sha512-k0OC/b14rNzMLDOE6QMBCjDRm3fQOHAL8Ldc9bxEWvMo4Ty9RY6rWmGetNTWhPo+/+FNd1lsQYRd0/1OSix36A==}
cpu: [arm64] cpu: [arm64]
os: [android] os: [android]
'@rollup/rollup-darwin-arm64@4.19.1': '@rollup/rollup-darwin-arm64@4.19.2':
resolution: {integrity: sha512-8o6eqeFZzVLia2hKPUZk4jdE3zW7LCcZr+MD18tXkgBBid3lssGVAYuox8x6YHoEPDdDa9ixTaStcmx88lio5Q==} resolution: {integrity: sha512-IIARRgWCNWMTeQH+kr/gFTHJccKzwEaI0YSvtqkEBPj7AshElFq89TyreKNFAGh5frLfDCbodnq+Ye3dqGKPBw==}
cpu: [arm64] cpu: [arm64]
os: [darwin] os: [darwin]
'@rollup/rollup-darwin-x64@4.19.1': '@rollup/rollup-darwin-x64@4.19.2':
resolution: {integrity: sha512-4T42heKsnbjkn7ovYiAdDVRRWZLU9Kmhdt6HafZxFcUdpjlBlxj4wDrt1yFWLk7G4+E+8p2C9tcmSu0KA6auGA==} resolution: {integrity: sha512-52udDMFDv54BTAdnw+KXNF45QCvcJOcYGl3vQkp4vARyrcdI/cXH8VXTEv/8QWfd6Fru8QQuw1b2uNersXOL0g==}
cpu: [x64] cpu: [x64]
os: [darwin] os: [darwin]
'@rollup/rollup-linux-arm-gnueabihf@4.19.1': '@rollup/rollup-linux-arm-gnueabihf@4.19.2':
resolution: {integrity: sha512-MXg1xp+e5GhZ3Vit1gGEyoC+dyQUBy2JgVQ+3hUrD9wZMkUw/ywgkpK7oZgnB6kPpGrxJ41clkPPnsknuD6M2Q==} resolution: {integrity: sha512-r+SI2t8srMPYZeoa1w0o/AfoVt9akI1ihgazGYPQGRilVAkuzMGiTtexNZkrPkQsyFrvqq/ni8f3zOnHw4hUbA==}
cpu: [arm] cpu: [arm]
os: [linux] os: [linux]
'@rollup/rollup-linux-arm-musleabihf@4.19.1': '@rollup/rollup-linux-arm-musleabihf@4.19.2':
resolution: {integrity: sha512-DZNLwIY4ftPSRVkJEaxYkq7u2zel7aah57HESuNkUnz+3bZHxwkCUkrfS2IWC1sxK6F2QNIR0Qr/YXw7nkF3Pw==} resolution: {integrity: sha512-+tYiL4QVjtI3KliKBGtUU7yhw0GMcJJuB9mLTCEauHEsqfk49gtUBXGtGP3h1LW8MbaTY6rSFIQV1XOBps1gBA==}
cpu: [arm] cpu: [arm]
os: [linux] os: [linux]
'@rollup/rollup-linux-arm64-gnu@4.19.1': '@rollup/rollup-linux-arm64-gnu@4.19.2':
resolution: {integrity: sha512-C7evongnjyxdngSDRRSQv5GvyfISizgtk9RM+z2biV5kY6S/NF/wta7K+DanmktC5DkuaJQgoKGf7KUDmA7RUw==} resolution: {integrity: sha512-OR5DcvZiYN75mXDNQQxlQPTv4D+uNCUsmSCSY2FolLf9W5I4DSoJyg7z9Ea3TjKfhPSGgMJiey1aWvlWuBzMtg==}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
'@rollup/rollup-linux-arm64-musl@4.19.1': '@rollup/rollup-linux-arm64-musl@4.19.2':
resolution: {integrity: sha512-89tFWqxfxLLHkAthAcrTs9etAoBFRduNfWdl2xUs/yLV+7XDrJ5yuXMHptNqf1Zw0UCA3cAutkAiAokYCkaPtw==} resolution: {integrity: sha512-Hw3jSfWdUSauEYFBSFIte6I8m6jOj+3vifLg8EU3lreWulAUpch4JBjDMtlKosrBzkr0kwKgL9iCfjA8L3geoA==}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
'@rollup/rollup-linux-powerpc64le-gnu@4.19.1': '@rollup/rollup-linux-powerpc64le-gnu@4.19.2':
resolution: {integrity: sha512-PromGeV50sq+YfaisG8W3fd+Cl6mnOOiNv2qKKqKCpiiEke2KiKVyDqG/Mb9GWKbYMHj5a01fq/qlUR28PFhCQ==} resolution: {integrity: sha512-rhjvoPBhBwVnJRq/+hi2Q3EMiVF538/o9dBuj9TVLclo9DuONqt5xfWSaE6MYiFKpo/lFPJ/iSI72rYWw5Hc7w==}
cpu: [ppc64] cpu: [ppc64]
os: [linux] os: [linux]
'@rollup/rollup-linux-riscv64-gnu@4.19.1': '@rollup/rollup-linux-riscv64-gnu@4.19.2':
resolution: {integrity: sha512-/1BmHYh+iz0cNCP0oHCuF8CSiNj0JOGf0jRlSo3L/FAyZyG2rGBuKpkZVH9YF+x58r1jgWxvm1aRg3DHrLDt6A==} resolution: {integrity: sha512-EAz6vjPwHHs2qOCnpQkw4xs14XJq84I81sDRGPEjKPFVPBw7fwvtwhVjcZR6SLydCv8zNK8YGFblKWd/vRmP8g==}
cpu: [riscv64] cpu: [riscv64]
os: [linux] os: [linux]
'@rollup/rollup-linux-s390x-gnu@4.19.1': '@rollup/rollup-linux-s390x-gnu@4.19.2':
resolution: {integrity: sha512-0cYP5rGkQWRZKy9/HtsWVStLXzCF3cCBTRI+qRL8Z+wkYlqN7zrSYm6FuY5Kd5ysS5aH0q5lVgb/WbG4jqXN1Q==} resolution: {integrity: sha512-IJSUX1xb8k/zN9j2I7B5Re6B0NNJDJ1+soezjNojhT8DEVeDNptq2jgycCOpRhyGj0+xBn7Cq+PK7Q+nd2hxLA==}
cpu: [s390x] cpu: [s390x]
os: [linux] os: [linux]
'@rollup/rollup-linux-x64-gnu@4.19.1': '@rollup/rollup-linux-x64-gnu@4.19.2':
resolution: {integrity: sha512-XUXeI9eM8rMP8aGvii/aOOiMvTs7xlCosq9xCjcqI9+5hBxtjDpD+7Abm1ZhVIFE1J2h2VIg0t2DX/gjespC2Q==} resolution: {integrity: sha512-OgaToJ8jSxTpgGkZSkwKE+JQGihdcaqnyHEFOSAU45utQ+yLruE1dkonB2SDI8t375wOKgNn8pQvaWY9kPzxDQ==}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
'@rollup/rollup-linux-x64-musl@4.19.1': '@rollup/rollup-linux-x64-musl@4.19.2':
resolution: {integrity: sha512-V7cBw/cKXMfEVhpSvVZhC+iGifD6U1zJ4tbibjjN+Xi3blSXaj/rJynAkCFFQfoG6VZrAiP7uGVzL440Q6Me2Q==} resolution: {integrity: sha512-5V3mPpWkB066XZZBgSd1lwozBk7tmOkKtquyCJ6T4LN3mzKENXyBwWNQn8d0Ci81hvlBw5RoFgleVpL6aScLYg==}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
'@rollup/rollup-win32-arm64-msvc@4.19.1': '@rollup/rollup-win32-arm64-msvc@4.19.2':
resolution: {integrity: sha512-88brja2vldW/76jWATlBqHEoGjJLRnP0WOEKAUbMcXaAZnemNhlAHSyj4jIwMoP2T750LE9lblvD4e2jXleZsA==} resolution: {integrity: sha512-ayVstadfLeeXI9zUPiKRVT8qF55hm7hKa+0N1V6Vj+OTNFfKSoUxyZvzVvgtBxqSb5URQ8sK6fhwxr9/MLmxdA==}
cpu: [arm64] cpu: [arm64]
os: [win32] os: [win32]
'@rollup/rollup-win32-ia32-msvc@4.19.1': '@rollup/rollup-win32-ia32-msvc@4.19.2':
resolution: {integrity: sha512-LdxxcqRVSXi6k6JUrTah1rHuaupoeuiv38du8Mt4r4IPer3kwlTo+RuvfE8KzZ/tL6BhaPlzJ3835i6CxrFIRQ==} resolution: {integrity: sha512-Mda7iG4fOLHNsPqjWSjANvNZYoW034yxgrndof0DwCy0D3FvTjeNo+HGE6oGWgvcLZNLlcp0hLEFcRs+UGsMLg==}
cpu: [ia32] cpu: [ia32]
os: [win32] os: [win32]
'@rollup/rollup-win32-x64-msvc@4.19.1': '@rollup/rollup-win32-x64-msvc@4.19.2':
resolution: {integrity: sha512-2bIrL28PcK3YCqD9anGxDxamxdiJAxA+l7fWIwM5o8UqNy1t3d1NdAweO2XhA0KTDJ5aH1FsuiT5+7VhtHliXg==} resolution: {integrity: sha512-DPi0ubYhSow/00YqmG1jWm3qt1F8aXziHc/UNy8bo9cpCacqhuWu+iSq/fp2SyEQK7iYTZ60fBU9cat3MXTjIQ==}
cpu: [x64] cpu: [x64]
os: [win32] os: [win32]
'@sapphire/async-queue@1.5.3':
resolution: {integrity: sha512-x7zadcfJGxFka1Q3f8gCts1F0xMwCKbZweM85xECGI0hBTeIZJGGCrHgLggihBoprlQ/hBmDR5LKfIPqnmHM3w==}
engines: {node: '>=v14.0.0', npm: '>=7.0.0'}
'@sapphire/snowflake@3.5.3':
resolution: {integrity: sha512-jjmJywLAFoWeBi1W7994zZyiNWPIiqRRNAmSERxyg93xRGzNYvGjlZ0gR6x0F4gPRi2+0O6S71kOZYyr3cxaIQ==}
engines: {node: '>=v14.0.0', npm: '>=7.0.0'}
'@selderee/plugin-htmlparser2@0.11.0': '@selderee/plugin-htmlparser2@0.11.0':
resolution: {integrity: sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ==} resolution: {integrity: sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ==}
@ -1119,70 +1136,73 @@ packages:
'@types/yauzl@2.10.3': '@types/yauzl@2.10.3':
resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==}
'@typescript-eslint/eslint-plugin@7.18.0': '@typescript-eslint/eslint-plugin@8.0.0':
resolution: {integrity: sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==} resolution: {integrity: sha512-STIZdwEQRXAHvNUS6ILDf5z3u95Gc8jzywunxSNqX00OooIemaaNIA0vEgynJlycL5AjabYLLrIyHd4iazyvtg==}
engines: {node: ^18.18.0 || >=20.0.0} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies: peerDependencies:
'@typescript-eslint/parser': ^7.0.0 '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0
eslint: ^8.56.0 eslint: ^8.57.0 || ^9.0.0
typescript: '*' typescript: '*'
peerDependenciesMeta: peerDependenciesMeta:
typescript: typescript:
optional: true optional: true
'@typescript-eslint/parser@7.18.0': '@typescript-eslint/parser@8.0.0':
resolution: {integrity: sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==} resolution: {integrity: sha512-pS1hdZ+vnrpDIxuFXYQpLTILglTjSYJ9MbetZctrUawogUsPdz31DIIRZ9+rab0LhYNTsk88w4fIzVheiTbWOQ==}
engines: {node: ^18.18.0 || >=20.0.0} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies: peerDependencies:
eslint: ^8.56.0 eslint: ^8.57.0 || ^9.0.0
typescript: '*' typescript: '*'
peerDependenciesMeta: peerDependenciesMeta:
typescript: typescript:
optional: true optional: true
'@typescript-eslint/scope-manager@7.18.0': '@typescript-eslint/scope-manager@8.0.0':
resolution: {integrity: sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==} resolution: {integrity: sha512-V0aa9Csx/ZWWv2IPgTfY7T4agYwJyILESu/PVqFtTFz9RIS823mAze+NbnBI8xiwdX3iqeQbcTYlvB04G9wyQw==}
engines: {node: ^18.18.0 || >=20.0.0} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@typescript-eslint/type-utils@7.18.0': '@typescript-eslint/type-utils@8.0.0':
resolution: {integrity: sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==} resolution: {integrity: sha512-mJAFP2mZLTBwAn5WI4PMakpywfWFH5nQZezUQdSKV23Pqo6o9iShQg1hP2+0hJJXP2LnZkWPphdIq4juYYwCeg==}
engines: {node: ^18.18.0 || >=20.0.0} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.56.0
typescript: '*'
peerDependenciesMeta:
typescript:
optional: true
'@typescript-eslint/types@7.18.0':
resolution: {integrity: sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==}
engines: {node: ^18.18.0 || >=20.0.0}
'@typescript-eslint/typescript-estree@7.18.0':
resolution: {integrity: sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==}
engines: {node: ^18.18.0 || >=20.0.0}
peerDependencies: peerDependencies:
typescript: '*' typescript: '*'
peerDependenciesMeta: peerDependenciesMeta:
typescript: typescript:
optional: true optional: true
'@typescript-eslint/utils@7.18.0': '@typescript-eslint/types@8.0.0':
resolution: {integrity: sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==} resolution: {integrity: sha512-wgdSGs9BTMWQ7ooeHtu5quddKKs5Z5dS+fHLbrQI+ID0XWJLODGMHRfhwImiHoeO2S5Wir2yXuadJN6/l4JRxw==}
engines: {node: ^18.18.0 || >=20.0.0} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.56.0
'@typescript-eslint/visitor-keys@7.18.0': '@typescript-eslint/typescript-estree@8.0.0':
resolution: {integrity: sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==} resolution: {integrity: sha512-5b97WpKMX+Y43YKi4zVcCVLtK5F98dFls3Oxui8LbnmRsseKenbbDinmvxrWegKDMmlkIq/XHuyy0UGLtpCDKg==}
engines: {node: ^18.18.0 || >=20.0.0} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '*'
peerDependenciesMeta:
typescript:
optional: true
'@typescript-eslint/utils@8.0.0':
resolution: {integrity: sha512-k/oS/A/3QeGLRvOWCg6/9rATJL5rec7/5s1YmdS0ZU6LHveJyGFwBvLhSRBv6i9xaj7etmosp+l+ViN1I9Aj/Q==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0
'@typescript-eslint/visitor-keys@8.0.0':
resolution: {integrity: sha512-oN0K4nkHuOyF3PVMyETbpP5zp6wfyOvm7tWhTMfoqxSSsPmJIh6JNASuZDlODE8eE+0EB9uar+6+vxr9DBTYOA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@ungap/structured-clone@1.2.0': '@ungap/structured-clone@1.2.0':
resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==}
'@xhayper/discord-rpc@1.1.4': '@vladfrangu/async_event_emitter@2.4.4':
resolution: {integrity: sha512-yq2ybstOWsfAN6LP5vogUpnxkaiKV1yXQ+8N4Sgo8YbE+3atgxuNiZWnGG6yO+XdxswvbD04AkLhnq7f9r8h3w==} resolution: {integrity: sha512-ZL62PFXEIeGUI8btfJ5S8Flc286eU1ZUSjwyFQtIGXfRUDPZKO+CDJMYb1R71LjGWRZ4n202O+a6FGjsgTw58g==}
engines: {node: '>=14.18.0'} engines: {node: '>=v14.0.0', npm: '>=7.0.0'}
'@xhayper/discord-rpc@1.2.0':
resolution: {integrity: sha512-cKjs9TKzN/7JoozijjszQjUEK1qnLHpEvcJQ2OGFBZjymUzIOH7l14KUu7TQtaIEk0Aw9Bx2w7TfQ0O6tp5mCw==}
engines: {node: '>=16.11.0'}
'@xmldom/xmldom@0.8.10': '@xmldom/xmldom@0.8.10':
resolution: {integrity: sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==} resolution: {integrity: sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==}
@ -1364,9 +1384,6 @@ packages:
resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
axios@1.7.2:
resolution: {integrity: sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==}
babel-plugin-jsx-dom-expressions@0.37.16: babel-plugin-jsx-dom-expressions@0.37.16:
resolution: {integrity: sha512-ItMD16axbk+FqVb9vIbc7AOpNowy46VaSUHaMYPn+erPGpMCxsahQ1Iv+qhPMthjxtn5ROVMZ5AJtQvzjxjiNA==} resolution: {integrity: sha512-ItMD16axbk+FqVb9vIbc7AOpNowy46VaSUHaMYPn+erPGpMCxsahQ1Iv+qhPMthjxtn5ROVMZ5AJtQvzjxjiNA==}
peerDependencies: peerDependencies:
@ -1781,6 +1798,9 @@ packages:
resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
engines: {node: '>=8'} engines: {node: '>=8'}
discord-api-types@0.37.83:
resolution: {integrity: sha512-urGGYeWtWNYMKnYlZnOnDHm8fVRffQs3U0SpE8RHeiuLKb/u92APS8HoQnPTFbnXmY1vVnXjXO4dOxcAn3J+DA==}
discord-api-types@0.37.93: discord-api-types@0.37.93:
resolution: {integrity: sha512-M5jn0x3bcXk8EI2c6F6V6LeOWq10B/cJf+YJSyqNmg7z4bdXK+Z7g9zGJwHS0h9Bfgs0nun2LQISFOzwck7G9A==} resolution: {integrity: sha512-M5jn0x3bcXk8EI2c6F6V6LeOWq10B/cJf+YJSyqNmg7z4bdXK+Z7g9zGJwHS0h9Bfgs0nun2LQISFOzwck7G9A==}
@ -2188,15 +2208,6 @@ packages:
flatted@3.2.9: flatted@3.2.9:
resolution: {integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==} resolution: {integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==}
follow-redirects@1.15.6:
resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==}
engines: {node: '>=4.0'}
peerDependencies:
debug: '*'
peerDependenciesMeta:
debug:
optional: true
for-each@0.3.3: for-each@0.3.3:
resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
@ -2684,8 +2695,8 @@ packages:
engines: {node: '>=10'} engines: {node: '>=10'}
hasBin: true hasBin: true
jintr@2.0.0: jintr@2.1.1:
resolution: {integrity: sha512-RiVlevxttZ4eHEYB2dXKXDXluzHfRuw0DJQGsYuKCc5IvZj5/GbOakeqVX+Bar/G9kTty9xDJREcxukurkmYLA==} resolution: {integrity: sha512-89cwX4ouogeDGOBsEVsVYsnWWvWjchmwXBB4kiBhmjOKw19FiOKhNhMhpxhTlK2ctl7DS+d/ethfmuBpzoNNgA==}
js-tokens@4.0.0: js-tokens@4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
@ -2836,6 +2847,9 @@ packages:
resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
engines: {node: '>=10'} engines: {node: '>=10'}
magic-bytes.js@1.10.0:
resolution: {integrity: sha512-/k20Lg2q8LE5xiaaSkMXk4sfvI+9EGEykFS4b0CHHGWqDYU0bGUFSwchNOMA56D7TCs9GwVTkqe9als1/ns8UQ==}
magic-string@0.30.10: magic-string@0.30.10:
resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==} resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==}
@ -3266,9 +3280,6 @@ packages:
resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==} resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==}
engines: {node: '>=10'} engines: {node: '>=10'}
proxy-from-env@1.1.0:
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
pump@3.0.0: pump@3.0.0:
resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==}
@ -3383,8 +3394,8 @@ packages:
resolution: {integrity: sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==} resolution: {integrity: sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==}
engines: {node: '>=8.0'} engines: {node: '>=8.0'}
rollup@4.19.1: rollup@4.19.2:
resolution: {integrity: sha512-K5vziVlg7hTpYfFBI+91zHBEMo6jafYXpkMlqZjg7/zhIG9iHqazBf4xz9AVdjS9BruRn280ROqLI7G3OFRIlw==} resolution: {integrity: sha512-6/jgnN1svF9PjNYJ4ya3l+cqutg49vOZ4rVgsDKxdl+5gpGPnByFXWGyfH9YGx9i3nfBwSu1Iyu6vGwFFA0BdQ==}
engines: {node: '>=18.0.0', npm: '>=8.0.0'} engines: {node: '>=18.0.0', npm: '>=8.0.0'}
hasBin: true hasBin: true
@ -3806,6 +3817,10 @@ packages:
resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==} resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==}
engines: {node: '>=14.0'} engines: {node: '>=14.0'}
undici@6.13.0:
resolution: {integrity: sha512-Q2rtqmZWrbP8nePMq7mOJIN98M0fYvSgV89vwl/BQRT4mDOeY2GXZngfGpcBBhtky3woM7G24wZV3Q304Bv6cw==}
engines: {node: '>=18.0'}
unique-filename@3.0.0: unique-filename@3.0.0:
resolution: {integrity: sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==} resolution: {integrity: sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==}
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
@ -4035,8 +4050,8 @@ packages:
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
engines: {node: '>=10'} engines: {node: '>=10'}
youtubei.js@10.2.0: youtubei.js@10.3.0:
resolution: {integrity: sha512-JLKW9AHQ1qrTwBbre1aDkH8UJFmNcc4+kOSaVou5jSY7AzfFPFJK0yvX6afnLst0UVC9wfXHrLiNx93sutVErA==} resolution: {integrity: sha512-tLmeJCECK2xF2hZZtF2nEqirdKVNLFSDpa0LhTaXY3tngtL7doQXyy7M2CLueramDTlmCnFaW+rctHirTPFaRQ==}
zip-stream@4.1.1: zip-stream@4.1.1:
resolution: {integrity: sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==} resolution: {integrity: sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==}
@ -4244,6 +4259,22 @@ snapshots:
ajv: 6.12.6 ajv: 6.12.6
ajv-keywords: 3.5.2(ajv@6.12.6) ajv-keywords: 3.5.2(ajv@6.12.6)
'@discordjs/collection@2.1.0': {}
'@discordjs/rest@2.3.0':
dependencies:
'@discordjs/collection': 2.1.0
'@discordjs/util': 1.1.0
'@sapphire/async-queue': 1.5.3
'@sapphire/snowflake': 3.5.3
'@vladfrangu/async_event_emitter': 2.4.4
discord-api-types: 0.37.83
magic-bytes.js: 1.10.0
tslib: 2.6.2
undici: 6.13.0
'@discordjs/util@1.1.0': {}
'@electron-toolkit/tsconfig@1.0.1(@types/node@20.12.5)': '@electron-toolkit/tsconfig@1.0.1(@types/node@20.12.5)':
dependencies: dependencies:
'@types/node': 20.12.5 '@types/node': 20.12.5
@ -4612,62 +4643,66 @@ snapshots:
'@remusao/trie@1.4.1': {} '@remusao/trie@1.4.1': {}
'@rollup/pluginutils@5.1.0(rollup@4.19.1)': '@rollup/pluginutils@5.1.0(rollup@4.19.2)':
dependencies: dependencies:
'@types/estree': 1.0.5 '@types/estree': 1.0.5
estree-walker: 2.0.2 estree-walker: 2.0.2
picomatch: 2.3.1 picomatch: 2.3.1
optionalDependencies: optionalDependencies:
rollup: 4.19.1 rollup: 4.19.2
'@rollup/rollup-android-arm-eabi@4.19.1': '@rollup/rollup-android-arm-eabi@4.19.2':
optional: true optional: true
'@rollup/rollup-android-arm64@4.19.1': '@rollup/rollup-android-arm64@4.19.2':
optional: true optional: true
'@rollup/rollup-darwin-arm64@4.19.1': '@rollup/rollup-darwin-arm64@4.19.2':
optional: true optional: true
'@rollup/rollup-darwin-x64@4.19.1': '@rollup/rollup-darwin-x64@4.19.2':
optional: true optional: true
'@rollup/rollup-linux-arm-gnueabihf@4.19.1': '@rollup/rollup-linux-arm-gnueabihf@4.19.2':
optional: true optional: true
'@rollup/rollup-linux-arm-musleabihf@4.19.1': '@rollup/rollup-linux-arm-musleabihf@4.19.2':
optional: true optional: true
'@rollup/rollup-linux-arm64-gnu@4.19.1': '@rollup/rollup-linux-arm64-gnu@4.19.2':
optional: true optional: true
'@rollup/rollup-linux-arm64-musl@4.19.1': '@rollup/rollup-linux-arm64-musl@4.19.2':
optional: true optional: true
'@rollup/rollup-linux-powerpc64le-gnu@4.19.1': '@rollup/rollup-linux-powerpc64le-gnu@4.19.2':
optional: true optional: true
'@rollup/rollup-linux-riscv64-gnu@4.19.1': '@rollup/rollup-linux-riscv64-gnu@4.19.2':
optional: true optional: true
'@rollup/rollup-linux-s390x-gnu@4.19.1': '@rollup/rollup-linux-s390x-gnu@4.19.2':
optional: true optional: true
'@rollup/rollup-linux-x64-gnu@4.19.1': '@rollup/rollup-linux-x64-gnu@4.19.2':
optional: true optional: true
'@rollup/rollup-linux-x64-musl@4.19.1': '@rollup/rollup-linux-x64-musl@4.19.2':
optional: true optional: true
'@rollup/rollup-win32-arm64-msvc@4.19.1': '@rollup/rollup-win32-arm64-msvc@4.19.2':
optional: true optional: true
'@rollup/rollup-win32-ia32-msvc@4.19.1': '@rollup/rollup-win32-ia32-msvc@4.19.2':
optional: true optional: true
'@rollup/rollup-win32-x64-msvc@4.19.1': '@rollup/rollup-win32-x64-msvc@4.19.2':
optional: true optional: true
'@sapphire/async-queue@1.5.3': {}
'@sapphire/snowflake@3.5.3': {}
'@selderee/plugin-htmlparser2@0.11.0': '@selderee/plugin-htmlparser2@0.11.0':
dependencies: dependencies:
domhandler: 5.0.3 domhandler: 5.0.3
@ -4816,14 +4851,14 @@ snapshots:
'@types/node': 20.12.5 '@types/node': 20.12.5
optional: true optional: true
'@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4)': '@typescript-eslint/eslint-plugin@8.0.0(@typescript-eslint/parser@8.0.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4)':
dependencies: dependencies:
'@eslint-community/regexpp': 4.11.0 '@eslint-community/regexpp': 4.11.0
'@typescript-eslint/parser': 7.18.0(eslint@8.57.0)(typescript@5.5.4) '@typescript-eslint/parser': 8.0.0(eslint@8.57.0)(typescript@5.5.4)
'@typescript-eslint/scope-manager': 7.18.0 '@typescript-eslint/scope-manager': 8.0.0
'@typescript-eslint/type-utils': 7.18.0(eslint@8.57.0)(typescript@5.5.4) '@typescript-eslint/type-utils': 8.0.0(eslint@8.57.0)(typescript@5.5.4)
'@typescript-eslint/utils': 7.18.0(eslint@8.57.0)(typescript@5.5.4) '@typescript-eslint/utils': 8.0.0(eslint@8.57.0)(typescript@5.5.4)
'@typescript-eslint/visitor-keys': 7.18.0 '@typescript-eslint/visitor-keys': 8.0.0
eslint: 8.57.0 eslint: 8.57.0
graphemer: 1.4.0 graphemer: 1.4.0
ignore: 5.3.1 ignore: 5.3.1
@ -4834,12 +4869,12 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4)': '@typescript-eslint/parser@8.0.0(eslint@8.57.0)(typescript@5.5.4)':
dependencies: dependencies:
'@typescript-eslint/scope-manager': 7.18.0 '@typescript-eslint/scope-manager': 8.0.0
'@typescript-eslint/types': 7.18.0 '@typescript-eslint/types': 8.0.0
'@typescript-eslint/typescript-estree': 7.18.0(typescript@5.5.4) '@typescript-eslint/typescript-estree': 8.0.0(typescript@5.5.4)
'@typescript-eslint/visitor-keys': 7.18.0 '@typescript-eslint/visitor-keys': 8.0.0
debug: 4.3.5 debug: 4.3.5
eslint: 8.57.0 eslint: 8.57.0
optionalDependencies: optionalDependencies:
@ -4847,29 +4882,29 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@typescript-eslint/scope-manager@7.18.0': '@typescript-eslint/scope-manager@8.0.0':
dependencies: dependencies:
'@typescript-eslint/types': 7.18.0 '@typescript-eslint/types': 8.0.0
'@typescript-eslint/visitor-keys': 7.18.0 '@typescript-eslint/visitor-keys': 8.0.0
'@typescript-eslint/type-utils@7.18.0(eslint@8.57.0)(typescript@5.5.4)': '@typescript-eslint/type-utils@8.0.0(eslint@8.57.0)(typescript@5.5.4)':
dependencies: dependencies:
'@typescript-eslint/typescript-estree': 7.18.0(typescript@5.5.4) '@typescript-eslint/typescript-estree': 8.0.0(typescript@5.5.4)
'@typescript-eslint/utils': 7.18.0(eslint@8.57.0)(typescript@5.5.4) '@typescript-eslint/utils': 8.0.0(eslint@8.57.0)(typescript@5.5.4)
debug: 4.3.5 debug: 4.3.5
eslint: 8.57.0
ts-api-utils: 1.3.0(typescript@5.5.4) ts-api-utils: 1.3.0(typescript@5.5.4)
optionalDependencies: optionalDependencies:
typescript: 5.5.4 typescript: 5.5.4
transitivePeerDependencies: transitivePeerDependencies:
- eslint
- supports-color - supports-color
'@typescript-eslint/types@7.18.0': {} '@typescript-eslint/types@8.0.0': {}
'@typescript-eslint/typescript-estree@7.18.0(typescript@5.5.4)': '@typescript-eslint/typescript-estree@8.0.0(typescript@5.5.4)':
dependencies: dependencies:
'@typescript-eslint/types': 7.18.0 '@typescript-eslint/types': 8.0.0
'@typescript-eslint/visitor-keys': 7.18.0 '@typescript-eslint/visitor-keys': 8.0.0
debug: 4.3.5 debug: 4.3.5
globby: 11.1.0 globby: 11.1.0
is-glob: 4.0.3 is-glob: 4.0.3
@ -4881,33 +4916,35 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@typescript-eslint/utils@7.18.0(eslint@8.57.0)(typescript@5.5.4)': '@typescript-eslint/utils@8.0.0(eslint@8.57.0)(typescript@5.5.4)':
dependencies: dependencies:
'@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
'@typescript-eslint/scope-manager': 7.18.0 '@typescript-eslint/scope-manager': 8.0.0
'@typescript-eslint/types': 7.18.0 '@typescript-eslint/types': 8.0.0
'@typescript-eslint/typescript-estree': 7.18.0(typescript@5.5.4) '@typescript-eslint/typescript-estree': 8.0.0(typescript@5.5.4)
eslint: 8.57.0 eslint: 8.57.0
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
- typescript - typescript
'@typescript-eslint/visitor-keys@7.18.0': '@typescript-eslint/visitor-keys@8.0.0':
dependencies: dependencies:
'@typescript-eslint/types': 7.18.0 '@typescript-eslint/types': 8.0.0
eslint-visitor-keys: 3.4.3 eslint-visitor-keys: 3.4.3
'@ungap/structured-clone@1.2.0': {} '@ungap/structured-clone@1.2.0': {}
'@xhayper/discord-rpc@1.1.4(patch_hash=n7icacbfxuqlodunyqwwt5lccm)': '@vladfrangu/async_event_emitter@2.4.4': {}
'@xhayper/discord-rpc@1.2.0(bufferutil@4.0.8)(utf-8-validate@6.0.4)':
dependencies: dependencies:
axios: 1.7.2 '@discordjs/rest': 2.3.0
'@vladfrangu/async_event_emitter': 2.4.4
discord-api-types: 0.37.93
ws: 8.18.0(bufferutil@4.0.8)(utf-8-validate@6.0.4) ws: 8.18.0(bufferutil@4.0.8)(utf-8-validate@6.0.4)
optionalDependencies:
bufferutil: 4.0.8
utf-8-validate: 6.0.4
transitivePeerDependencies: transitivePeerDependencies:
- debug - bufferutil
- utf-8-validate
'@xmldom/xmldom@0.8.10': {} '@xmldom/xmldom@0.8.10': {}
@ -5147,14 +5184,6 @@ snapshots:
available-typed-arrays@1.0.5: {} available-typed-arrays@1.0.5: {}
axios@1.7.2:
dependencies:
follow-redirects: 1.15.6
form-data: 4.0.0
proxy-from-env: 1.1.0
transitivePeerDependencies:
- debug
babel-plugin-jsx-dom-expressions@0.37.16(@babel/core@7.24.7): babel-plugin-jsx-dom-expressions@0.37.16(@babel/core@7.24.7):
dependencies: dependencies:
'@babel/core': 7.24.7 '@babel/core': 7.24.7
@ -5648,6 +5677,8 @@ snapshots:
dependencies: dependencies:
path-type: 4.0.0 path-type: 4.0.0
discord-api-types@0.37.83: {}
discord-api-types@0.37.93: {} discord-api-types@0.37.93: {}
dmg-builder@24.13.3(electron-builder-squirrel-windows@24.13.3): dmg-builder@24.13.3(electron-builder-squirrel-windows@24.13.3):
@ -6013,10 +6044,10 @@ snapshots:
escape-string-regexp@5.0.0: {} escape-string-regexp@5.0.0: {}
eslint-import-resolver-exports@1.0.0-beta.5(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0))(eslint@8.57.0): eslint-import-resolver-exports@1.0.0-beta.5(eslint-plugin-import@2.29.1(@typescript-eslint/parser@8.0.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0))(eslint@8.57.0):
dependencies: dependencies:
eslint: 8.57.0 eslint: 8.57.0
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) eslint-plugin-import: 2.29.1(@typescript-eslint/parser@8.0.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
resolve.exports: 2.0.2 resolve.exports: 2.0.2
eslint-import-resolver-node@0.3.9: eslint-import-resolver-node@0.3.9:
@ -6027,13 +6058,13 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint-plugin-import@2.29.1)(eslint@8.57.0): eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@8.0.0(eslint@8.57.0)(typescript@5.5.4))(eslint-plugin-import@2.29.1)(eslint@8.57.0):
dependencies: dependencies:
debug: 4.3.5 debug: 4.3.5
enhanced-resolve: 5.15.0 enhanced-resolve: 5.15.0
eslint: 8.57.0 eslint: 8.57.0
eslint-module-utils: 2.8.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0) eslint-module-utils: 2.8.0(@typescript-eslint/parser@8.0.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@8.0.0(eslint@8.57.0)(typescript@5.5.4))(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0)
eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) eslint-plugin-import: 2.29.1(@typescript-eslint/parser@8.0.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
fast-glob: 3.3.2 fast-glob: 3.3.2
get-tsconfig: 4.7.2 get-tsconfig: 4.7.2
is-core-module: 2.13.1 is-core-module: 2.13.1
@ -6044,18 +6075,18 @@ snapshots:
- eslint-import-resolver-webpack - eslint-import-resolver-webpack
- supports-color - supports-color
eslint-module-utils@2.8.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0): eslint-module-utils@2.8.0(@typescript-eslint/parser@8.0.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@8.0.0(eslint@8.57.0)(typescript@5.5.4))(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0):
dependencies: dependencies:
debug: 3.2.7 debug: 3.2.7
optionalDependencies: optionalDependencies:
'@typescript-eslint/parser': 7.18.0(eslint@8.57.0)(typescript@5.5.4) '@typescript-eslint/parser': 8.0.0(eslint@8.57.0)(typescript@5.5.4)
eslint: 8.57.0 eslint: 8.57.0
eslint-import-resolver-node: 0.3.9 eslint-import-resolver-node: 0.3.9
eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint-plugin-import@2.29.1)(eslint@8.57.0) eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@8.0.0(eslint@8.57.0)(typescript@5.5.4))(eslint-plugin-import@2.29.1)(eslint@8.57.0)
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0): eslint-plugin-import@2.29.1(@typescript-eslint/parser@8.0.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0):
dependencies: dependencies:
array-includes: 3.1.7 array-includes: 3.1.7
array.prototype.findlastindex: 1.2.3 array.prototype.findlastindex: 1.2.3
@ -6065,7 +6096,7 @@ snapshots:
doctrine: 2.1.0 doctrine: 2.1.0
eslint: 8.57.0 eslint: 8.57.0
eslint-import-resolver-node: 0.3.9 eslint-import-resolver-node: 0.3.9
eslint-module-utils: 2.8.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0) eslint-module-utils: 2.8.0(@typescript-eslint/parser@8.0.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@8.0.0(eslint@8.57.0)(typescript@5.5.4))(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0)
hasown: 2.0.0 hasown: 2.0.0
is-core-module: 2.13.1 is-core-module: 2.13.1
is-glob: 4.0.3 is-glob: 4.0.3
@ -6076,7 +6107,7 @@ snapshots:
semver: 6.3.1 semver: 6.3.1
tsconfig-paths: 3.15.0 tsconfig-paths: 3.15.0
optionalDependencies: optionalDependencies:
'@typescript-eslint/parser': 7.18.0(eslint@8.57.0)(typescript@5.5.4) '@typescript-eslint/parser': 8.0.0(eslint@8.57.0)(typescript@5.5.4)
transitivePeerDependencies: transitivePeerDependencies:
- eslint-import-resolver-typescript - eslint-import-resolver-typescript
- eslint-import-resolver-webpack - eslint-import-resolver-webpack
@ -6271,8 +6302,6 @@ snapshots:
flatted@3.2.9: {} flatted@3.2.9: {}
follow-redirects@1.15.6: {}
for-each@0.3.3: for-each@0.3.3:
dependencies: dependencies:
is-callable: 1.2.7 is-callable: 1.2.7
@ -6771,7 +6800,7 @@ snapshots:
filelist: 1.0.4 filelist: 1.0.4
minimatch: 3.1.2 minimatch: 3.1.2
jintr@2.0.0: jintr@2.1.1:
dependencies: dependencies:
acorn: 8.12.1 acorn: 8.12.1
@ -6896,6 +6925,8 @@ snapshots:
dependencies: dependencies:
yallist: 4.0.0 yallist: 4.0.0
magic-bytes.js@1.10.0: {}
magic-string@0.30.10: magic-string@0.30.10:
dependencies: dependencies:
'@jridgewell/sourcemap-codec': 1.4.15 '@jridgewell/sourcemap-codec': 1.4.15
@ -7316,8 +7347,6 @@ snapshots:
err-code: 2.0.3 err-code: 2.0.3
retry: 0.12.0 retry: 0.12.0
proxy-from-env@1.1.0: {}
pump@3.0.0: pump@3.0.0:
dependencies: dependencies:
end-of-stream: 1.4.4 end-of-stream: 1.4.4
@ -7446,26 +7475,26 @@ snapshots:
sprintf-js: 1.1.3 sprintf-js: 1.1.3
optional: true optional: true
rollup@4.19.1: rollup@4.19.2:
dependencies: dependencies:
'@types/estree': 1.0.5 '@types/estree': 1.0.5
optionalDependencies: optionalDependencies:
'@rollup/rollup-android-arm-eabi': 4.19.1 '@rollup/rollup-android-arm-eabi': 4.19.2
'@rollup/rollup-android-arm64': 4.19.1 '@rollup/rollup-android-arm64': 4.19.2
'@rollup/rollup-darwin-arm64': 4.19.1 '@rollup/rollup-darwin-arm64': 4.19.2
'@rollup/rollup-darwin-x64': 4.19.1 '@rollup/rollup-darwin-x64': 4.19.2
'@rollup/rollup-linux-arm-gnueabihf': 4.19.1 '@rollup/rollup-linux-arm-gnueabihf': 4.19.2
'@rollup/rollup-linux-arm-musleabihf': 4.19.1 '@rollup/rollup-linux-arm-musleabihf': 4.19.2
'@rollup/rollup-linux-arm64-gnu': 4.19.1 '@rollup/rollup-linux-arm64-gnu': 4.19.2
'@rollup/rollup-linux-arm64-musl': 4.19.1 '@rollup/rollup-linux-arm64-musl': 4.19.2
'@rollup/rollup-linux-powerpc64le-gnu': 4.19.1 '@rollup/rollup-linux-powerpc64le-gnu': 4.19.2
'@rollup/rollup-linux-riscv64-gnu': 4.19.1 '@rollup/rollup-linux-riscv64-gnu': 4.19.2
'@rollup/rollup-linux-s390x-gnu': 4.19.1 '@rollup/rollup-linux-s390x-gnu': 4.19.2
'@rollup/rollup-linux-x64-gnu': 4.19.1 '@rollup/rollup-linux-x64-gnu': 4.19.2
'@rollup/rollup-linux-x64-musl': 4.19.1 '@rollup/rollup-linux-x64-musl': 4.19.2
'@rollup/rollup-win32-arm64-msvc': 4.19.1 '@rollup/rollup-win32-arm64-msvc': 4.19.2
'@rollup/rollup-win32-ia32-msvc': 4.19.1 '@rollup/rollup-win32-ia32-msvc': 4.19.2
'@rollup/rollup-win32-x64-msvc': 4.19.1 '@rollup/rollup-win32-x64-msvc': 4.19.2
fsevents: 2.3.3 fsevents: 2.3.3
run-applescript@7.0.0: {} run-applescript@7.0.0: {}
@ -7916,6 +7945,8 @@ snapshots:
dependencies: dependencies:
'@fastify/busboy': 2.1.0 '@fastify/busboy': 2.1.0
undici@6.13.0: {}
unique-filename@3.0.0: unique-filename@3.0.0:
dependencies: dependencies:
unique-slug: 4.0.0 unique-slug: 4.0.0
@ -7985,10 +8016,10 @@ snapshots:
extsprintf: 1.4.1 extsprintf: 1.4.1
optional: true optional: true
vite-plugin-inspect@0.8.5(rollup@4.19.1)(vite@5.3.5(@types/node@20.12.5)): vite-plugin-inspect@0.8.5(rollup@4.19.2)(vite@5.3.5(@types/node@20.12.5)):
dependencies: dependencies:
'@antfu/utils': 0.7.10 '@antfu/utils': 0.7.10
'@rollup/pluginutils': 5.1.0(rollup@4.19.1) '@rollup/pluginutils': 5.1.0(rollup@4.19.2)
debug: 4.3.5 debug: 4.3.5
error-stack-parser-es: 0.1.5 error-stack-parser-es: 0.1.5
fs-extra: 11.2.0 fs-extra: 11.2.0
@ -8022,7 +8053,7 @@ snapshots:
dependencies: dependencies:
esbuild: 0.21.5 esbuild: 0.21.5
postcss: 8.4.39 postcss: 8.4.39
rollup: 4.19.1 rollup: 4.19.2
optionalDependencies: optionalDependencies:
'@types/node': 20.12.5 '@types/node': 20.12.5
fsevents: 2.3.3 fsevents: 2.3.3
@ -8137,9 +8168,9 @@ snapshots:
yocto-queue@0.1.0: {} yocto-queue@0.1.0: {}
youtubei.js@10.2.0: youtubei.js@10.3.0:
dependencies: dependencies:
jintr: 2.0.0 jintr: 2.1.1
tslib: 2.6.2 tslib: 2.6.2
undici: 5.28.4 undici: 5.28.4

View File

@ -1,9 +1,8 @@
import Store from 'electron-store';
import { deepmergeCustom } from 'deepmerge-ts'; import { deepmergeCustom } from 'deepmerge-ts';
import defaultConfig from './defaults'; import defaultConfig from './defaults';
import store from './store'; import store, { IStore } from './store';
import plugins from './plugins'; import plugins from './plugins';
import { restart } from '@/providers/app-controls'; import { restart } from '@/providers/app-controls';
@ -62,20 +61,19 @@ type Join<K, P> = K extends string | number
type Paths<T, D extends number = 10> = [D] extends [never] type Paths<T, D extends number = 10> = [D] extends [never]
? never ? never
: T extends object : T extends object
? { ? {
[K in keyof T]-?: K extends string | number [K in keyof T]-?: K extends string | number
? `${K}` | Join<K, Paths<T[K], Prev[D]>> ? `${K}` | Join<K, Paths<T[K], Prev[D]>>
: never; : never;
}[keyof T] }[keyof T]
: ''; : '';
type SplitKey<K> = K extends `${infer A}.${infer B}` ? [A, B] : [K, string]; type SplitKey<K> = K extends `${infer A}.${infer B}` ? [A, B] : [K, string];
type PathValue<T, K extends string> = SplitKey<K> extends [ type PathValue<T, K extends string> =
infer A extends keyof T, SplitKey<K> extends [infer A extends keyof T, infer B extends string]
infer B extends string, ? PathValue<T[A], B>
] : T;
? PathValue<T[A], B>
: T;
const get = <Key extends Paths<typeof defaultConfig>>(key: Key) => const get = <Key extends Paths<typeof defaultConfig>>(key: Key) =>
store.get(key) as PathValue<typeof defaultConfig, typeof key>; store.get(key) as PathValue<typeof defaultConfig, typeof key>;
@ -86,7 +84,7 @@ export default {
setPartial, setPartial,
setMenuOption, setMenuOption,
edit: () => store.openInEditor(), edit: () => store.openInEditor(),
watch(cb: Parameters<Store['onDidAnyChange']>[0]) { watch(cb: Parameters<IStore['onDidAnyChange']>[0]) {
store.onDidAnyChange(cb); store.onDidAnyChange(cb);
}, },
plugins, plugins,

View File

@ -1,12 +1,14 @@
import Store from 'electron-store'; import Store from 'electron-store';
import Conf from 'conf';
import defaults from './defaults'; import defaults from './defaults';
import { DefaultPresetList, type Preset } from '@/plugins/downloader/types'; import { DefaultPresetList, type Preset } from '@/plugins/downloader/types';
// prettier-ignore
export type IStore = InstanceType<typeof import('conf/dist/source/index').default<Record<string, unknown>>>;
const migrations = { const migrations = {
'>=3.3.0'(store: Conf<Record<string, unknown>>) { '>=3.3.0'(store: IStore) {
const lastfmConfig = store.get('plugins.lastfm') as { const lastfmConfig = store.get('plugins.lastfm') as {
enabled?: boolean; enabled?: boolean;
token?: string; token?: string;
@ -16,21 +18,21 @@ const migrations = {
secret?: string; secret?: string;
}; };
if (lastfmConfig) { if (lastfmConfig) {
let scrobblerConfig = store.get( let scrobblerConfig = store.get('plugins.scrobbler') as
'plugins.scrobbler', | {
) as {
enabled?: boolean;
scrobblers?: {
lastfm?: {
enabled?: boolean; enabled?: boolean;
token?: string; scrobblers?: {
sessionKey?: string; lastfm?: {
apiRoot?: string; enabled?: boolean;
apiKey?: string; token?: string;
secret?: string; sessionKey?: string;
}; apiRoot?: string;
}; apiKey?: string;
} | undefined; secret?: string;
};
};
}
| undefined;
if (!scrobblerConfig) { if (!scrobblerConfig) {
scrobblerConfig = { scrobblerConfig = {
@ -56,7 +58,7 @@ const migrations = {
store.delete('plugins.lastfm'); store.delete('plugins.lastfm');
} }
}, },
'>=3.0.0'(store: Conf<Record<string, unknown>>) { '>=3.0.0'(store: IStore) {
const discordConfig = store.get('plugins.discord') as Record< const discordConfig = store.get('plugins.discord') as Record<
string, string,
unknown unknown
@ -78,14 +80,14 @@ const migrations = {
} }
} }
}, },
'>=2.1.3'(store: Conf<Record<string, unknown>>) { '>=2.1.3'(store: IStore) {
const listenAlong = store.get('plugins.discord.listenAlong'); const listenAlong = store.get('plugins.discord.listenAlong');
if (listenAlong !== undefined) { if (listenAlong !== undefined) {
store.set('plugins.discord.playOnYouTubeMusic', listenAlong); store.set('plugins.discord.playOnYouTubeMusic', listenAlong);
store.delete('plugins.discord.listenAlong'); store.delete('plugins.discord.listenAlong');
} }
}, },
'>=2.1.0'(store: Conf<Record<string, unknown>>) { '>=2.1.0'(store: IStore) {
const originalPreset = store.get('plugins.downloader.preset') as const originalPreset = store.get('plugins.downloader.preset') as
| string | string
| undefined; | undefined;
@ -110,7 +112,7 @@ const migrations = {
store.delete('plugins.downloader.ffmpegArgs'); store.delete('plugins.downloader.ffmpegArgs');
} }
}, },
'>=1.20.0'(store: Conf<Record<string, unknown>>) { '>=1.20.0'(store: IStore) {
store.delete('plugins.visualizer'); // default value is now in the plugin store.delete('plugins.visualizer'); // default value is now in the plugin
if (store.get('plugins.notifications.toastStyle') === undefined) { if (store.get('plugins.notifications.toastStyle') === undefined) {
@ -125,14 +127,14 @@ const migrations = {
store.set('options.likeButtons', 'force'); store.set('options.likeButtons', 'force');
} }
}, },
'>=1.17.0'(store: Conf<Record<string, unknown>>) { '>=1.17.0'(store: IStore) {
store.delete('plugins.picture-in-picture'); // default value is now in the plugin store.delete('plugins.picture-in-picture'); // default value is now in the plugin
if (store.get('plugins.video-toggle.mode') === undefined) { if (store.get('plugins.video-toggle.mode') === undefined) {
store.set('plugins.video-toggle.mode', 'custom'); store.set('plugins.video-toggle.mode', 'custom');
} }
}, },
'>=1.14.0'(store: Conf<Record<string, unknown>>) { '>=1.14.0'(store: IStore) {
if ( if (
typeof store.get('plugins.precise-volume.globalShortcuts') !== 'object' typeof store.get('plugins.precise-volume.globalShortcuts') !== 'object'
) { ) {
@ -144,12 +146,12 @@ const migrations = {
store.set('plugins.video-toggle.enabled', true); store.set('plugins.video-toggle.enabled', true);
} }
}, },
'>=1.13.0'(store: Conf<Record<string, unknown>>) { '>=1.13.0'(store: IStore) {
if (store.get('plugins.discord.listenAlong') === undefined) { if (store.get('plugins.discord.listenAlong') === undefined) {
store.set('plugins.discord.listenAlong', true); store.set('plugins.discord.listenAlong', true);
} }
}, },
'>=1.12.0'(store: Conf<Record<string, unknown>>) { '>=1.12.0'(store: IStore) {
const options = store.get('plugins.shortcuts') as const options = store.get('plugins.shortcuts') as
| Record< | Record<
string, string,
@ -187,12 +189,12 @@ const migrations = {
} }
} }
}, },
'>=1.11.0'(store: Conf<Record<string, unknown>>) { '>=1.11.0'(store: IStore) {
if (store.get('options.resumeOnStart') === undefined) { if (store.get('options.resumeOnStart') === undefined) {
store.set('options.resumeOnStart', true); store.set('options.resumeOnStart', true);
} }
}, },
'>=1.7.0'(store: Conf<Record<string, unknown>>) { '>=1.7.0'(store: IStore) {
const enabledPlugins = store.get('plugins') as string[]; const enabledPlugins = store.get('plugins') as string[];
if (!Array.isArray(enabledPlugins)) { if (!Array.isArray(enabledPlugins)) {
console.warn('Plugins are not in array format, cannot migrate'); console.warn('Plugins are not in array format, cannot migrate');
@ -233,4 +235,4 @@ export default new Store({
}, },
clearInvalidConfig: false, clearInvalidConfig: false,
migrations, migrations,
}); }) as Store & IStore;

View File

@ -683,6 +683,42 @@
"refetch-btn": { "refetch-btn": {
"normal": "Refetch lyrics", "normal": "Refetch lyrics",
"fetching": "Fetching..." "fetching": "Fetching..."
},
"menu": {
"precise-timing": {
"label": "Make the lyrics perfectly synced",
"tooltip": "Calculate to the milisecond the display of the next line (can have a small impact on performance)"
},
"line-effect": {
"label": "Line effect",
"tooltip": "Choose the effect to apply to the current line",
"submenu": {
"scale": {
"label": "Scale",
"tooltip": "Scale the current line"
},
"offset": {
"label": "Offset",
"tooltip": "Offset on the right the current line"
},
"focus": {
"label": "Focus",
"tooltip": "Make only the current line white"
}
}
},
"default-text-string": {
"label": "Default character between lyrics",
"tooltip": "Choose the default character to use for the gap between lyrics"
},
"show-time-codes": {
"label": "Show time codes",
"tooltip": "Show the time codes next to the lyrics"
},
"show-lyrics-even-if-inexact": {
"label": "Show lyrics even if inexact",
"tooltip": "If the song is not found, the plugin tries again with a different search query.\nThe result from the second attempt may not be exact."
}
} }
}, },
"taskbar-mediacontrol": { "taskbar-mediacontrol": {

View File

@ -207,6 +207,10 @@
} }
}, },
"plugins": { "plugins": {
"ad-speedup": {
"description": "Ha reklám szól, elnémítja a hangot és a lejátszási sebességet 16x-ra állítja",
"name": "Gyorsítás hozzáadása"
},
"adblocker": { "adblocker": {
"description": "Alapértelmezés szerint blokkolja az összes hirdetést és nyomkövetést", "description": "Alapértelmezés szerint blokkolja az összes hirdetést és nyomkövetést",
"menu": { "menu": {
@ -407,7 +411,21 @@
"description": "MP3 / forrás hanganyag letöltése közvetlenül az interfészről", "description": "MP3 / forrás hanganyag letöltése közvetlenül az interfészről",
"menu": { "menu": {
"choose-download-folder": "Letöltési mappa kiválasztása", "choose-download-folder": "Letöltési mappa kiválasztása",
"download-finish-settings": {
"prompt": {
"last-percent": "x százalék után",
"last-seconds": "Utolsó x másodperc"
},
"submenu": {
"advanced": "Speciális",
"enabled": "Engedélyezve",
"mode": "Időmód",
"percent": "Százalék",
"seconds": "Másodpercek"
}
},
"download-playlist": "Lejátszási lista letöltése", "download-playlist": "Lejátszási lista letöltése",
"presets": "Előbeállítások",
"skip-existing": "Meglévő fájlok kihagyása" "skip-existing": "Meglévő fájlok kihagyása"
}, },
"name": "Letöltő", "name": "Letöltő",
@ -489,6 +507,7 @@
} }
}, },
"navigation": { "navigation": {
"description": "Következő/Vissza navigációs nyilak közvetlenül az interfészbe integrálva, mint a kedvenc böngésződben",
"name": "Navigáció" "name": "Navigáció"
}, },
"no-google-login": { "no-google-login": {
@ -502,10 +521,14 @@
"interactive-settings": { "interactive-settings": {
"label": "Interaktív beállítások", "label": "Interaktív beállítások",
"submenu": { "submenu": {
"hide-button-text": "Gombok szövegének elrejtése" "hide-button-text": "Gombok szövegének elrejtése",
"refresh-on-play-pause": "Frissítés lejátszás/szünet megnyomásakor",
"tray-controls": "Megnyitás/Bezárás tálca ikonra kattintva"
} }
}, },
"priority": "Értesítési prioritás" "priority": "Értesítési prioritás",
"toast-style": "Értesítés stílusa",
"unpause-notification": "Értesítés megjelenítése a lejátszás folytatásakor"
}, },
"name": "Értesítések" "name": "Értesítések"
}, },
@ -542,6 +565,8 @@
"precise-volume": { "precise-volume": {
"description": "A hangerő precíz szabályozása egérgörgővel/gyorsbillentyűkkel, egy egyedi HUD és testreszabható hangerő csuszka segítségével", "description": "A hangerő precíz szabályozása egérgörgővel/gyorsbillentyűkkel, egy egyedi HUD és testreszabható hangerő csuszka segítségével",
"menu": { "menu": {
"arrows-shortcuts": "Helyi nyíl-billentyűkkel való vezérlés",
"custom-volume-steps": "Egyedi hangerőléptetés beállítása",
"global-shortcuts": "Globális gyorsbillentyűk" "global-shortcuts": "Globális gyorsbillentyűk"
}, },
"name": "Precíz hangerő", "name": "Precíz hangerő",
@ -553,6 +578,10 @@
}, },
"label": "Válaszd ki a globális hangerő gyorsbillentyűket:", "label": "Válaszd ki a globális hangerő gyorsbillentyűket:",
"title": "Globális hangerő gyorsbillentyűk" "title": "Globális hangerő gyorsbillentyűk"
},
"volume-steps": {
"label": "Hangerő növelés/csökkentés léptékének kiválasztása",
"title": "Hangerő lépték"
} }
} }
}, },
@ -566,7 +595,8 @@
} }
} }
}, },
"description": "Lehetővé teszi a videó minőségének megváltoztatását egy gombbal a videó fedvényen" "description": "Lehetővé teszi a videó minőségének megváltoztatását egy gombbal a videó fedvényen",
"name": "Videóminőség modosító"
}, },
"scrobbler": { "scrobbler": {
"description": "Scrobbling támogatás hozzáadása (pl. last.fm, ListenBrainz)", "description": "Scrobbling támogatás hozzáadása (pl. last.fm, ListenBrainz)",
@ -613,6 +643,7 @@
"play-pause": "Lejátszás / Szünet", "play-pause": "Lejátszás / Szünet",
"previous": "Előző" "previous": "Előző"
}, },
"label": "Globális billentyűparancsok választása a dalok vezérléséhez:",
"title": "Globális gyorsbillentyűk" "title": "Globális gyorsbillentyűk"
} }
} }
@ -629,8 +660,26 @@
"description": "Automatikusan kihagyja a nem zenés részeket, mint például az intro/outro vagy a zenei videók olyan részeit, ahol a zene nem szól", "description": "Automatikusan kihagyja a nem zenés részeket, mint például az intro/outro vagy a zenei videók olyan részeit, ahol a zene nem szól",
"name": "SzponzorBlokk" "name": "SzponzorBlokk"
}, },
"synced-lyrics": {
"description": "Szinkronizált dalszövegeket biztosít dalokhoz, LRClib-hez hasonló szolgáltatókat használva.",
"errors": {
"fetch": "⚠️ - Hiba történt a dalszövegek lekérése közben. Kérlek, próbáld újra később.",
"not-found": "⚠️ - Nem található dalszöveg ehhez a zenéhez."
},
"name": "Szinkronizált dalszövegek",
"refetch-btn": {
"fetching": "Lekérés folyamatban...",
"normal": "Dalszöveg újra lekérése"
},
"warnings": {
"duration-mismatch": "⚠️ - A dalszövegek időzítése eltérhet a zene hossza miatt.",
"inexact": "⚠️ - Ennek a zenének a dalszövege pontatlan lehet",
"instrumental": "⚠️ - Ez egy hangszerekkel játszott zene"
}
},
"taskbar-mediacontrol": { "taskbar-mediacontrol": {
"description": "Lejátszás vezérlése a Windows tálcáról" "description": "Lejátszás vezérlése a Windows tálcáról",
"name": "Médiavezérlés a tálcán"
}, },
"touchbar": { "touchbar": {
"description": "macOS felhasználók számára hozzáad egy widgetet a TouchBar-hoz", "description": "macOS felhasználók számára hozzáad egy widgetet a TouchBar-hoz",
@ -667,6 +716,7 @@
} }
}, },
"visualizer": { "visualizer": {
"description": "Vizualizációt ad a lejátszóhoz",
"menu": { "menu": {
"visualizer-type": "Vizualizáció típus" "visualizer-type": "Vizualizáció típus"
}, },

View File

@ -207,6 +207,10 @@
} }
}, },
"plugins": { "plugins": {
"ad-speedup": {
"description": "Se viene riprodotto un annuncio, l'audio viene disattivato e viene impostata la velocità di riproduzione su 16x",
"name": "Accelerazione ad"
},
"adblocker": { "adblocker": {
"description": "Blocca tutti gli annunci e i tracker", "description": "Blocca tutti gli annunci e i tracker",
"menu": { "menu": {
@ -410,6 +414,21 @@
"description": "Download MP3 / sorgenti audio direttamente dall'interfaccia", "description": "Download MP3 / sorgenti audio direttamente dall'interfaccia",
"menu": { "menu": {
"choose-download-folder": "Scegli cartella download", "choose-download-folder": "Scegli cartella download",
"download-finish-settings": {
"label": "Scarica al termine",
"prompt": {
"last-percent": "Dopo x percento",
"last-seconds": "Ultimi x secondi",
"title": "Configura quando scaricare"
},
"submenu": {
"advanced": "Avanzato",
"enabled": "Abilitato",
"mode": "Modalità tempo",
"percent": "Percentuale",
"seconds": "Secondi"
}
},
"download-playlist": "Scarica la playlist", "download-playlist": "Scarica la playlist",
"presets": "Preimpostazioni", "presets": "Preimpostazioni",
"skip-existing": "Salta i file esistenti" "skip-existing": "Salta i file esistenti"
@ -649,6 +668,23 @@
"description": "Salta automaticamente le parti non musicali, come l'intro/outro delle canzoni o le parti dei video musicali in cui non viene riprodotto il brano", "description": "Salta automaticamente le parti non musicali, come l'intro/outro delle canzoni o le parti dei video musicali in cui non viene riprodotto il brano",
"name": "Blocco sponsor" "name": "Blocco sponsor"
}, },
"synced-lyrics": {
"description": "Fornisce testi sincronizzati alle canzoni, utilizzando provider come LRClib.",
"errors": {
"fetch": "⚠️ - Si è verificato un errore nel recuperare il testo. Per favore riprova più tardi.",
"not-found": "⚠️ - Nessun testo trovato per questa canzone."
},
"name": "Testi sincronizzati",
"refetch-btn": {
"fetching": "Sto recuperando...",
"normal": "Recupera i testi"
},
"warnings": {
"duration-mismatch": "⚠️ - I testi potrebbero non essere sincronizzati a causa di una mancata corrispondenza della durata.",
"inexact": "⚠️ - Il testo di questa canzone potrebbe essere inesatto",
"instrumental": "⚠️ - Questo è un brano strumentale"
}
},
"taskbar-mediacontrol": { "taskbar-mediacontrol": {
"description": "Controlla riproduzione dalla taskbar di Windows", "description": "Controlla riproduzione dalla taskbar di Windows",
"name": "Controlli multimediali sulla taskbar" "name": "Controlli multimediali sulla taskbar"

View File

@ -674,6 +674,42 @@
"fetch": "⚠️ - 가사를 불러오는 동안 오류가 발생했습니다. 나중에 다시 시도해 주세요.", "fetch": "⚠️ - 가사를 불러오는 동안 오류가 발생했습니다. 나중에 다시 시도해 주세요.",
"not-found": "⚠️ - 이 노래의 가사를 찾을 수 없습니다." "not-found": "⚠️ - 이 노래의 가사를 찾을 수 없습니다."
}, },
"menu": {
"default-text-string": {
"label": "가사 사이에 표시할 문자",
"tooltip": "가사 사이의 빈 공간에 사용할 문자를 선택합니다"
},
"line-effect": {
"label": "줄 표시 효과",
"submenu": {
"focus": {
"label": "포커스",
"tooltip": "현재 줄만 하얀색으로 표시"
},
"offset": {
"label": "오프셋",
"tooltip": "현재 줄의 오른쪽에 오프셋 적용"
},
"scale": {
"label": "스케일",
"tooltip": "현재 줄에 스케일 적용"
}
},
"tooltip": "현재 줄에 적용할 효과를 선택합니다"
},
"precise-timing": {
"label": "가사를 최대한 정교하게 동기화",
"tooltip": "다음 줄의 표시를 밀리초 단위로 계산합니다 (성능에 약간의 영향을 미칠 수 있음)"
},
"show-lyrics-even-if-inexact": {
"label": "가사가 정확하지 않더라도 표시",
"tooltip": "노래를 찾을 수 없는 경우, 플러그인이 다른 검색어로 다시 검색합니다.\n두번째 검색 결과는 정확하지 않을 수 있습니다."
},
"show-time-codes": {
"label": "시간 코드 표시",
"tooltip": "가사 옆에 시간 코드 표시"
}
},
"name": "싱크 가사", "name": "싱크 가사",
"refetch-btn": { "refetch-btn": {
"fetching": "가져오는 중...", "fetching": "가져오는 중...",

View File

@ -668,6 +668,23 @@
"description": "Tự động bỏ qua các phần không phải âm nhạc như phần giới thiệu/kết thúc hoặc các phần của video nhạc mà bài hát không được phát", "description": "Tự động bỏ qua các phần không phải âm nhạc như phần giới thiệu/kết thúc hoặc các phần của video nhạc mà bài hát không được phát",
"name": "SponsorBlock" "name": "SponsorBlock"
}, },
"synced-lyrics": {
"description": "Cung cấp lời bài hát được đồng bộ hoá với các bài hát, sử dụng những nhà cung cấp như LRClib.",
"errors": {
"fetch": "⚠️ - Đã xảy ra lỗi khi tìm nạp lời bài hát, Vui lòng thử lại sau.",
"not-found": "⚠️ - Không tìm thấy lời cho bài hát này."
},
"name": "Lời bài hát được đồng bộ hoá",
"refetch-btn": {
"fetching": "Đang tìm nạp...",
"normal": "Tải lại lời bài hát"
},
"warnings": {
"duration-mismatch": "⚠️ - Lời bài hát có thể không đồng bộ do thời lượng không khớp.",
"inexact": "⚠️ - Lời bài hát này có thể không chính xác",
"instrumental": "⚠️ - Đây là một bài hát trình diễn bằng nhạc khí"
}
},
"taskbar-mediacontrol": { "taskbar-mediacontrol": {
"description": "Kiểm soát phát lại từ thanh tác vụ Windows của bạn", "description": "Kiểm soát phát lại từ thanh tác vụ Windows của bạn",
"name": "Kiểm soát phương tiện trên thanh tác vụ" "name": "Kiểm soát phương tiện trên thanh tác vụ"

View File

@ -321,27 +321,29 @@ async function createMainWindow() {
const { x: windowX, y: windowY } = windowPosition; const { x: windowX, y: windowY } = windowPosition;
const winSize = win.getSize(); const winSize = win.getSize();
const display = screen.getDisplayNearestPoint(windowPosition); const display = screen.getDisplayNearestPoint(windowPosition);
const primaryDisplay = screen.getPrimaryDisplay();
const scaledWidth = windowSize.width; const scaleFactor = is.windows() ? primaryDisplay.scaleFactor / display.scaleFactor : 1;
const scaledHeight = windowSize.height; const scaledWidth = Math.floor(windowSize.width * scaleFactor);
const scaledHeight = Math.floor(windowSize.height * scaleFactor);
const scaledX = windowX; const scaledX = windowX;
const scaledY = windowY; const scaledY = windowY;
if ( if (
scaledX + scaledWidth < display.bounds.x - 8 || scaledX + (scaledWidth / 2) < display.bounds.x - 8 || // Left
scaledX - scaledWidth > display.bounds.x + display.bounds.width || scaledX + (scaledWidth / 2) > display.bounds.x + display.bounds.width || // Right
scaledY < display.bounds.y - 8 || scaledY < display.bounds.y - 8 || // Top
scaledY > display.bounds.y + display.bounds.height scaledY + (scaledHeight / 2) > display.bounds.y + display.bounds.height // Bottom
) { ) {
// Window is offscreen // Window is offscreen
if (is.dev()) { if (is.dev()) {
console.warn( console.warn(
LoggerPrefix, LoggerPrefix,
t('main.console.window.tried-to-render-offscreen', { t('main.console.window.tried-to-render-offscreen', {
winSize: String(winSize), windowSize: String(winSize),
displaySize: String(display.bounds), displaySize: JSON.stringify(display.bounds),
windowPosition: String(windowPosition), position: JSON.stringify(windowPosition),
}), }),
); );
} }

View File

@ -1,6 +1,7 @@
import { t } from '@/i18n'; import { t } from '@/i18n';
import { createPlugin } from '@/utils'; import { createPlugin } from '@/utils';
import { ElementFromHtml } from '@/plugins/utils/renderer'; import { ElementFromHtml } from '@/plugins/utils/renderer';
import { waitForElement } from '@/utils/wait-for-element';
import undislikeHTML from './templates/undislike.html?raw'; import undislikeHTML from './templates/undislike.html?raw';
import dislikeHTML from './templates/dislike.html?raw'; import dislikeHTML from './templates/dislike.html?raw';
@ -16,7 +17,6 @@ export default createPlugin<
changeObserver?: MutationObserver; changeObserver?: MutationObserver;
waiting: boolean; waiting: boolean;
onPageChange(): void; onPageChange(): void;
waitForElem(selector: string): Promise<HTMLElement>;
loadFullList: (event: MouseEvent) => void; loadFullList: (event: MouseEvent) => void;
applyToList(id: string, loader: HTMLElement): void; applyToList(id: string, loader: HTMLElement): void;
start(): void; start(): void;
@ -50,7 +50,7 @@ export default createPlugin<
} else { } else {
this.waiting = true; this.waiting = true;
} }
const continuations = await this.waitForElem('#continuations'); const continuations = await waitForElement<HTMLElement>('#continuations');
this.waiting = false; this.waiting = false;
//Gets the for buttons //Gets the for buttons
const buttons: Array<HTMLElement> = [ const buttons: Array<HTMLElement> = [
@ -183,16 +183,5 @@ export default createPlugin<
button.remove(); button.remove();
} }
}, },
waitForElem(selector: string) {
return new Promise((resolve) => {
const interval = setInterval(() => {
const elem = document.querySelector<HTMLElement>(selector);
if (!elem) return;
clearInterval(interval);
resolve(elem);
});
});
},
}, },
}); });

View File

@ -4,6 +4,7 @@ import { t } from '@/i18n';
import { createPlugin } from '@/utils'; import { createPlugin } from '@/utils';
import { menu } from './menu'; import { menu } from './menu';
import { AmbientModePluginConfig } from './types'; import { AmbientModePluginConfig } from './types';
import { waitForElement } from '@/utils/wait-for-element';
const defaultConfig: AmbientModePluginConfig = { const defaultConfig: AmbientModePluginConfig = {
enabled: false, enabled: false,
@ -36,7 +37,7 @@ export default createPlugin({
unregister: null as (() => void) | null, unregister: null as (() => void) | null,
update: null as (() => void) | null, update: null as (() => void) | null,
interval: null as NodeJS.Timeout | null, interval: null as NodeJS.Timeout | null,
lastMediaType: null as "video" | "image" | null, lastMediaType: null as 'video' | 'image' | null,
lastVideoSource: null as string | null, lastVideoSource: null as string | null,
lastImageSource: null as string | null, lastImageSource: null as string | null,
@ -53,7 +54,8 @@ export default createPlugin({
const songImage = document.querySelector<HTMLImageElement>('#song-image'); const songImage = document.querySelector<HTMLImageElement>('#song-image');
const songVideo = document.querySelector<HTMLDivElement>('#song-video'); const songVideo = document.querySelector<HTMLDivElement>('#song-video');
const image = songImage?.querySelector<HTMLImageElement>('yt-img-shadow > img'); const image = songImage?.querySelector<HTMLImageElement>('yt-img-shadow > img');
const video = songVideo?.querySelector<HTMLVideoElement>('.html5-video-container > video'); const video = await waitForElement<HTMLVideoElement>('.html5-video-container > video');
const videoWrapper = document.querySelector('#song-video > .player-wrapper'); const videoWrapper = document.querySelector('#song-video > .player-wrapper');
const injectBlurImage = () => { const injectBlurImage = () => {
@ -179,12 +181,12 @@ export default createPlugin({
const isVideoMode = () => { const isVideoMode = () => {
const songVideo = document.querySelector<HTMLDivElement>('#song-video'); const songVideo = document.querySelector<HTMLDivElement>('#song-video');
if (!songVideo) { if (!songVideo) {
this.lastMediaType = "image"; this.lastMediaType = 'image';
return false; return false;
} }
const isVideo = getComputedStyle(songVideo).display !== 'none'; const isVideo = getComputedStyle(songVideo).display !== 'none';
this.lastMediaType = isVideo ? "video" : "image"; this.lastMediaType = isVideo ? 'video' : 'image';
return isVideo; return isVideo;
}; };
@ -196,8 +198,8 @@ export default createPlugin({
if (isPageOpen) { if (isPageOpen) {
const isVideo = isVideoMode(); const isVideo = isVideoMode();
if (!force) { if (!force) {
if (this.lastMediaType === "video" && this.lastVideoSource === video?.src) return false; if (this.lastMediaType === 'video' && this.lastVideoSource === video?.src) return false;
if (this.lastMediaType === "image" && this.lastImageSource === image?.src) return false; if (this.lastMediaType === 'image' && this.lastImageSource === image?.src) return false;
} }
this.unregister?.(); this.unregister?.();
this.unregister = (isVideo ? injectBlurVideo() : injectBlurImage()) ?? null; this.unregister = (isVideo ? injectBlurVideo() : injectBlurImage()) ?? null;
@ -205,7 +207,7 @@ export default createPlugin({
this.unregister?.(); this.unregister?.();
this.unregister = null; this.unregister = null;
} }
} };
/* needed for switching between different views (e.g. miniplayer) */ /* needed for switching between different views (e.g. miniplayer) */
const observer = new MutationObserver((mutationsList) => { const observer = new MutationObserver((mutationsList) => {

View File

@ -209,8 +209,8 @@ export const backend = createBackend<
info.rpc.user?.setActivity(activityInfo).catch(console.error); info.rpc.user?.setActivity(activityInfo).catch(console.error);
}, },
async start({ window: win, getConfig }) { async start(ctx) {
this.config = await getConfig(); this.config = await ctx.getConfig();
info.rpc.on('connected', () => { info.rpc.on('connected', () => {
if (dev()) { if (dev()) {
@ -239,10 +239,10 @@ export const backend = createBackend<
info.autoReconnect = this.config.autoReconnect; info.autoReconnect = this.config.autoReconnect;
window = win; window = ctx.window;
// If the page is ready, register the callback // If the page is ready, register the callback
win.once('ready-to-show', () => { ctx.window.once('ready-to-show', () => {
let lastSongInfo: SongInfo; let lastSongInfo: SongInfo;
registerCallback((songInfo) => { registerCallback((songInfo) => {
lastSongInfo = songInfo; lastSongInfo = songInfo;

View File

@ -1,12 +1,12 @@
import { t } from '@/i18n'; import { t } from '@/i18n';
import { createPlugin } from '@/utils'; import { createPlugin } from '@/utils';
import { waitForElement } from '@/utils/wait-for-element';
export default createPlugin< export default createPlugin<
unknown, unknown,
unknown, unknown,
{ {
observer?: MutationObserver; observer?: MutationObserver;
waitForElem(selector: string): Promise<HTMLElement>;
start(): void; start(): void;
stop(): void; stop(): void;
} }
@ -15,19 +15,8 @@ export default createPlugin<
description: () => t('plugins.skip-disliked-songs.description'), description: () => t('plugins.skip-disliked-songs.description'),
restartNeeded: false, restartNeeded: false,
renderer: { renderer: {
waitForElem(selector: string) {
return new Promise<HTMLElement>((resolve) => {
const interval = setInterval(() => {
const elem = document.querySelector<HTMLElement>(selector);
if (!elem) return;
clearInterval(interval);
resolve(elem);
});
});
},
start() { start() {
this.waitForElem('#dislike-button-renderer').then((dislikeBtn) => { waitForElement<HTMLElement>('#dislike-button-renderer').then((dislikeBtn) => {
this.observer = new MutationObserver(() => { this.observer = new MutationObserver(() => {
if (dislikeBtn?.getAttribute('like-status') == 'DISLIKE') { if (dislikeBtn?.getAttribute('like-status') == 'DISLIKE') {
document document

View File

@ -1,12 +1,11 @@
import style from './style.css?inline'; import style from './style.css?inline';
import { createPlugin } from '@/utils'; import { createPlugin } from '@/utils';
import { t } from '@/i18n';
import { SyncedLyricsPluginConfig } from './types';
import { menu } from './menu'; import { menu } from './menu';
import { renderer } from './renderer'; import { renderer } from './renderer';
import { t } from '@/i18n'; import type { SyncedLyricsPluginConfig } from './types';
export default createPlugin({ export default createPlugin({
name: () => t('plugins.synced-lyrics.name'), name: () => t('plugins.synced-lyrics.name'),
@ -15,12 +14,13 @@ export default createPlugin({
restartNeeded: true, restartNeeded: true,
addedVersion: '3.5.X', addedVersion: '3.5.X',
config: { config: {
enabled: false,
preciseTiming: true, preciseTiming: true,
showLyricsEvenIfInexact: true, showLyricsEvenIfInexact: true,
showTimeCodes: false, showTimeCodes: false,
defaultTextString: '♪', defaultTextString: '♪',
lineEffect: 'scale', lineEffect: 'scale',
} as SyncedLyricsPluginConfig, } satisfies SyncedLyricsPluginConfig,
menu, menu,
renderer, renderer,

View File

@ -1,7 +1,9 @@
import { MenuItemConstructorOptions } from 'electron'; import { MenuItemConstructorOptions } from 'electron';
import { MenuContext } from '@/types/contexts'; import { t } from '@/i18n';
import { SyncedLyricsPluginConfig } from './types';
import type { MenuContext } from '@/types/contexts';
import type { SyncedLyricsPluginConfig } from './types';
export const menu = async ({ export const menu = async ({
getConfig, getConfig,
@ -13,9 +15,8 @@ export const menu = async ({
return [ return [
{ {
label: 'Make the lyrics perfectly synced', label: t('plugins.synced-lyrics.menu.precise-timing.label'),
toolTip: toolTip: t('plugins.synced-lyrics.menu.precise-timing.tooltip'),
'Calculate to the milisecond the display of the next line (can have a small impact on performance)',
type: 'checkbox', type: 'checkbox',
checked: config.preciseTiming, checked: config.preciseTiming,
click(item) { click(item) {
@ -25,13 +26,13 @@ export const menu = async ({
}, },
}, },
{ {
label: 'Line effect', label: t('plugins.synced-lyrics.menu.line-effect.label'),
toolTip: 'Choose the effect to apply to the current line', toolTip: t('plugins.synced-lyrics.menu.line-effect.tooltip'),
type: 'submenu', type: 'submenu',
submenu: [ submenu: [
{ {
label: 'Scale', label: t('plugins.synced-lyrics.menu.line-effect.submenu.scale.label'),
toolTip: 'Scale the current line', toolTip: t('plugins.synced-lyrics.menu.line-effect.submenu.scale.tooltip'),
type: 'radio', type: 'radio',
checked: config.lineEffect === 'scale', checked: config.lineEffect === 'scale',
click() { click() {
@ -41,8 +42,8 @@ export const menu = async ({
}, },
}, },
{ {
label: 'Offset', label: t('plugins.synced-lyrics.menu.line-effect.submenu.offset.label'),
toolTip: 'Offset on the right the current line', toolTip: t('plugins.synced-lyrics.menu.line-effect.submenu.offset.tooltip'),
type: 'radio', type: 'radio',
checked: config.lineEffect === 'offset', checked: config.lineEffect === 'offset',
click() { click() {
@ -52,8 +53,8 @@ export const menu = async ({
}, },
}, },
{ {
label: 'Focus', label: t('plugins.synced-lyrics.menu.line-effect.submenu.focus.label'),
toolTip: 'Make only the current line white', toolTip: t('plugins.synced-lyrics.menu.line-effect.submenu.focus.tooltip'),
type: 'radio', type: 'radio',
checked: config.lineEffect === 'focus', checked: config.lineEffect === 'focus',
click() { click() {
@ -65,8 +66,8 @@ export const menu = async ({
], ],
}, },
{ {
label: 'Default character between lyrics', label: t('plugins.synced-lyrics.menu.default-text-string.label'),
toolTip: 'Choose the default string to use for the gap between lyrics', toolTip: t('plugins.synced-lyrics.menu.default-text-string.tooltip'),
type: 'submenu', type: 'submenu',
submenu: [ submenu: [
{ {
@ -80,7 +81,7 @@ export const menu = async ({
}, },
}, },
{ {
label: '[SPACE]', label: '" "',
type: 'radio', type: 'radio',
checked: config.defaultTextString === ' ', checked: config.defaultTextString === ' ',
click() { click() {
@ -112,8 +113,8 @@ export const menu = async ({
], ],
}, },
{ {
label: 'Show time codes', label: t('plugins.synced-lyrics.menu.show-time-codes.label'),
toolTip: 'Show the time codes next to the lyrics', toolTip: t('plugins.synced-lyrics.menu.show-time-codes.tooltip'),
type: 'checkbox', type: 'checkbox',
checked: config.showTimeCodes, checked: config.showTimeCodes,
click(item) { click(item) {
@ -123,9 +124,8 @@ export const menu = async ({
}, },
}, },
{ {
label: 'Show lyrics even if inexact', label: t('plugins.synced-lyrics.menu.show-lyrics-even-if-inexact.label'),
toolTip: toolTip: t('plugins.synced-lyrics.menu.show-lyrics-even-if-inexact.tooltip'),
'If the song is not found, the plugin tries again with a different search query.\nThe result from the second attempt may not be exact.',
type: 'checkbox', type: 'checkbox',
checked: config.showLyricsEvenIfInexact, checked: config.showLyricsEvenIfInexact,
click(item) { click(item) {

View File

@ -5,7 +5,6 @@ import { SyncedLine } from './SyncedLine';
import { t } from '@/i18n'; import { t } from '@/i18n';
import { getSongInfo } from '@/providers/song-info-front'; import { getSongInfo } from '@/providers/song-info-front';
import { LineLyrics } from '../../types';
import { import {
differentDuration, differentDuration,
hadSecondAttempt, hadSecondAttempt,
@ -14,6 +13,8 @@ import {
makeLyricsRequest, makeLyricsRequest,
} from '../lyrics/fetch'; } from '../lyrics/fetch';
import type { LineLyrics } from '../../types';
export const [debugInfo, setDebugInfo] = createSignal<string>(); export const [debugInfo, setDebugInfo] = createSignal<string>();
export const [lineLyrics, setLineLyrics] = createSignal<LineLyrics[]>([]); export const [lineLyrics, setLineLyrics] = createSignal<LineLyrics[]>([]);
export const [currentTime, setCurrentTime] = createSignal<number>(-1); export const [currentTime, setCurrentTime] = createSignal<number>(-1);

View File

@ -1,4 +1,5 @@
import { createRenderer } from '@/utils'; import { createRenderer } from '@/utils';
import { waitForElement } from '@/utils/wait-for-element';
import { makeLyricsRequest } from './lyrics'; import { makeLyricsRequest } from './lyrics';
import { selectors, tabStates } from './utils'; import { selectors, tabStates } from './utils';
@ -15,10 +16,9 @@ export let _ytAPI: YoutubePlayer | null = null;
export const renderer = createRenderer<{ export const renderer = createRenderer<{
observerCallback: MutationCallback; observerCallback: MutationCallback;
onPlayerApiReady: (api: YoutubePlayer) => void;
hasAddedEvents: boolean; hasAddedEvents: boolean;
observer?: MutationObserver; observer?: MutationObserver;
videoDataChange: () => void; videoDataChange: () => Promise<void>;
progressCallback: (evt: Event) => void; progressCallback: (evt: Event) => void;
}, SyncedLyricsPluginConfig>({ }, SyncedLyricsPluginConfig>({
onConfigChange(newConfig) { onConfigChange(newConfig) {
@ -42,17 +42,17 @@ export const renderer = createRenderer<{
} }
}, },
onPlayerApiReady(api: YoutubePlayer) { async onPlayerApiReady(api: YoutubePlayer) {
_ytAPI = api; _ytAPI = api;
api.addEventListener('videodatachange', this.videoDataChange); api.addEventListener('videodatachange', this.videoDataChange);
this.videoDataChange(); await this.videoDataChange();
}, },
hasAddedEvents: false, hasAddedEvents: false,
videoDataChange() { async videoDataChange() {
if (!this.hasAddedEvents) { if (!this.hasAddedEvents) {
const video = document.querySelector('video'); const video = document.querySelector('video');
@ -61,15 +61,14 @@ export const renderer = createRenderer<{
if (video) this.hasAddedEvents = true; if (video) this.hasAddedEvents = true;
} }
const header = document.querySelector<HTMLElement>(selectors.head);
if (!header) return;
this.observer ??= new MutationObserver( this.observer ??= new MutationObserver(
this.observerCallback, this.observerCallback,
); );
// Force the lyrics tab to be enabled at all times. // Force the lyrics tab to be enabled at all times.
this.observer.disconnect(); this.observer.disconnect();
const header = await waitForElement<HTMLElement>(selectors.head);
this.observer.observe(header, { attributes: true }); this.observer.observe(header, { attributes: true });
header.removeAttribute('disabled'); header.removeAttribute('disabled');
}, },

View File

@ -1,12 +1,13 @@
import { createSignal } from 'solid-js'; import { createSignal } from 'solid-js';
import { jaroWinkler } from '@skyra/jaro-winkler'; import { jaroWinkler } from '@skyra/jaro-winkler';
import { SongInfo } from '@/providers/song-info';
import { LineLyrics, LRCLIBSearchResponse } from '../../types';
import { config } from '../renderer'; import { config } from '../renderer';
import { setDebugInfo, setLineLyrics } from '../components/LyricsContainer'; import { setDebugInfo, setLineLyrics } from '../components/LyricsContainer';
import type { SongInfo } from '@/providers/song-info';
import type { LineLyrics, LRCLIBSearchResponse } from '../../types';
// prettier-ignore // prettier-ignore
export const [isInstrumental, setIsInstrumental] = createSignal(false); export const [isInstrumental, setIsInstrumental] = createSignal(false);
// prettier-ignore // prettier-ignore

View File

@ -1,10 +1,9 @@
import { createSignal, Show } from 'solid-js'; import { createSignal, Show } from 'solid-js';
import { VideoDetails } from '@/types/video-details';
import { LyricsContainer } from './components/LyricsContainer'; import { LyricsContainer } from './components/LyricsContainer';
import { SyncedLyricsPluginConfig } from '../types'; import type { VideoDetails } from '@/types/video-details';
import type { SyncedLyricsPluginConfig } from '../types';
export const [isVisible, setIsVisible] = createSignal<boolean>(false); export const [isVisible, setIsVisible] = createSignal<boolean>(false);

View File

@ -1,7 +1,10 @@
import { render } from 'solid-js/web'; import { render } from 'solid-js/web';
import { waitForElement } from '@/utils/wait-for-element';
import { LyricsRenderer, setIsVisible, setPlayerState } from './renderer'; import { LyricsRenderer, setIsVisible, setPlayerState } from './renderer';
import { VideoDetails } from '@/types/video-details';
import type { VideoDetails } from '@/types/video-details';
export const selectors = { export const selectors = {
head: '#tabsContent > .tab-header:nth-of-type(2)', head: '#tabsContent > .tab-header:nth-of-type(2)',
@ -12,18 +15,17 @@ export const selectors = {
}; };
export const tabStates = { export const tabStates = {
true: (data?: VideoDetails) => { true: async (data?: VideoDetails) => {
setIsVisible(true); setIsVisible(true);
setPlayerState(data ?? null); setPlayerState(data ?? null);
const tabRenderer = document.querySelector<HTMLElement>(
selectors.body.tabRenderer,
);
if (!tabRenderer) return;
let container = document.querySelector('#synced-lyrics-container'); let container = document.querySelector('#synced-lyrics-container');
if (container) return; if (container) return;
const tabRenderer = await waitForElement<HTMLElement>(
selectors.body.tabRenderer,
);
container = Object.assign(document.createElement('div'), { container = Object.assign(document.createElement('div'), {
id: 'synced-lyrics-container', id: 'synced-lyrics-container',
}); });

View File

@ -241,7 +241,8 @@ export interface FlagEndpoint {
flagAction: string; flagAction: string;
} }
export type VideoDataChangeValue = { // see song-info-front.ts
export type VideoDataChangeValue = Record<string, unknown> & {
videoId: string; videoId: string;
title: string; title: string;
author: string; author: string;

View File

@ -0,0 +1,11 @@
export const waitForElement = <T extends Element>(selector: string): Promise<T> => {
return new Promise<T>((resolve) => {
const interval = setInterval(() => {
const elem = document.querySelector<T>(selector);
if (!elem) return;
clearInterval(interval);
resolve(elem);
}, 100 /* ms */);
});
};