mirror of
https://github.com/th-ch/youtube-music.git
synced 2026-01-12 11:01:45 +00:00
Compare commits
57 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 34cb79eeaf | |||
| 1c30a07031 | |||
| 5dd5f41ef5 | |||
| 45a3c11d51 | |||
| 8bd3b4d3f0 | |||
| 4e3cb5806d | |||
| 6563eb4ddd | |||
| 895386f6f8 | |||
| 3810955e56 | |||
| 59c521e53f | |||
| 25d266f8f9 | |||
| 0c3c380591 | |||
| a20cfa30a1 | |||
| fefe899393 | |||
| 55759e8d7a | |||
| ddb561937f | |||
| 198cb71a4c | |||
| c34b880752 | |||
| 76944e3e41 | |||
| 68cd76f2af | |||
| 81145b52b7 | |||
| 2a19dab061 | |||
| 6958d59d4f | |||
| 8a51dfad87 | |||
| 5bb4d9efbe | |||
| 927aa5f24b | |||
| d695bc93a1 | |||
| b05fb4ccbe | |||
| 299eb7e7d6 | |||
| ae26333224 | |||
| 35176469b0 | |||
| 4e74f9cbc5 | |||
| 4091b36f36 | |||
| b3f805fce6 | |||
| b129a3e8d8 | |||
| 64ea1fdb58 | |||
| 8fcf59ed0a | |||
| 9811ca63de | |||
| 9028f88299 | |||
| fd47766d93 | |||
| 26b12c7208 | |||
| 8da9b3454d | |||
| 205cbefc83 | |||
| 0e94c72eef | |||
| c055641351 | |||
| c0a3aa99de | |||
| 8a8976acef | |||
| e409165e1b | |||
| b278140796 | |||
| 397056a54d | |||
| edecd65419 | |||
| 4d2d0b7bd6 | |||
| 0ca4e34efd | |||
| 43f3226c3a | |||
| 0a6dbecc05 | |||
| f5aa179cd6 | |||
| 3140e91dda |
BIN
assets/youtube-music-tray-paused.png
Normal file
BIN
assets/youtube-music-tray-paused.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.9 KiB |
35
changelog.md
35
changelog.md
@ -2,8 +2,43 @@
|
|||||||
|
|
||||||
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.2.1](https://github.com/th-ch/youtube-music/compare/v3.2.0...v3.2.1)
|
||||||
|
|
||||||
|
- fix: fix #1574 [`#1574`](https://github.com/th-ch/youtube-music/issues/1574)
|
||||||
|
- fix: fix #1575 [`#1575`](https://github.com/th-ch/youtube-music/issues/1575)
|
||||||
|
- chore(i18n): Translated using Weblate [`f5aa179`](https://github.com/th-ch/youtube-music/commit/f5aa179cd639eb4b8f70f1264b5b459ebcc16695)
|
||||||
|
- chore(i18n): Translated using Weblate (English) [`e409165`](https://github.com/th-ch/youtube-music/commit/e409165e1bed85f3d1aea3a565e7b9e462b1e05b)
|
||||||
|
- chore(i18n): Translated using Weblate (Czech) [`0ca4e34`](https://github.com/th-ch/youtube-music/commit/0ca4e34efd86e877314e5a245f266065b4cf0013)
|
||||||
|
|
||||||
|
#### [v3.2.0](https://github.com/th-ch/youtube-music/compare/v3.1.1...v3.2.0)
|
||||||
|
|
||||||
|
> 1 January 2024
|
||||||
|
|
||||||
|
- feat(album-color-theme): improve `Album Color Theme` style [`#1571`](https://github.com/th-ch/youtube-music/pull/1571)
|
||||||
|
- feat(menu): add more detail in Menu [`#1570`](https://github.com/th-ch/youtube-music/pull/1570)
|
||||||
|
- feat(music-together): Add new plugin `Music Together` [`#1562`](https://github.com/th-ch/youtube-music/pull/1562)
|
||||||
|
- chore(deps): update dependency rollup to v4.9.2 [`#1567`](https://github.com/th-ch/youtube-music/pull/1567)
|
||||||
|
- fix(deps): update dependency i18next to v23.7.13 [`#1569`](https://github.com/th-ch/youtube-music/pull/1569)
|
||||||
|
- feat: Add new plugin `Album actions` [`#1515`](https://github.com/th-ch/youtube-music/pull/1515)
|
||||||
|
- fix(deps): update dependency i18next to v23.7.12 [`#1564`](https://github.com/th-ch/youtube-music/pull/1564)
|
||||||
|
- fix: Only apply scale factor on Windows [`#1565`](https://github.com/th-ch/youtube-music/pull/1565)
|
||||||
|
- chore(deps): update dependency @typescript-eslint/eslint-plugin to v6.16.0 [`#1556`](https://github.com/th-ch/youtube-music/pull/1556)
|
||||||
|
- chore(deps): update pnpm to v8.13.1 [`#1557`](https://github.com/th-ch/youtube-music/pull/1557)
|
||||||
|
- chore(deps): update dependency ws to v8.16.0 [`#1559`](https://github.com/th-ch/youtube-music/pull/1559)
|
||||||
|
- fix(deps): update dependency youtubei.js to v8.1.0 [`#1560`](https://github.com/th-ch/youtube-music/pull/1560)
|
||||||
|
- fix(deps): update dependency node-html-parser to v6.1.12 [`#1554`](https://github.com/th-ch/youtube-music/pull/1554)
|
||||||
|
- Revert "fix(deps): update dependency @xhayper/discord-rpc to v1.1.2" [`#1552`](https://github.com/th-ch/youtube-music/pull/1552)
|
||||||
|
- feat(ambient-mode): support ambient mode on `Song section` [`#1555`](https://github.com/th-ch/youtube-music/issues/1555)
|
||||||
|
- fix: fixed an issue with the download button disappearing [`#1551`](https://github.com/th-ch/youtube-music/issues/1551)
|
||||||
|
- fix: fix `homebrew cask` [`#1514`](https://github.com/th-ch/youtube-music/issues/1514)
|
||||||
|
- fix: pnpm build error [`13ef856`](https://github.com/th-ch/youtube-music/commit/13ef8560ff43353030537403be7da82542ba535e)
|
||||||
|
- chore(i18n): Translated using Weblate (Czech) [`0dc9c6a`](https://github.com/th-ch/youtube-music/commit/0dc9c6a1a90bce6505614617b827e816cbaaf875)
|
||||||
|
- chore(deps): update dependency @typescript-eslint/eslint-plugin to v6.15.0 [`c5bcd89`](https://github.com/th-ch/youtube-music/commit/c5bcd89f164b51d7380486a8ae35edd0caeea842)
|
||||||
|
|
||||||
#### [v3.1.1](https://github.com/th-ch/youtube-music/compare/v3.1.0...v3.1.1)
|
#### [v3.1.1](https://github.com/th-ch/youtube-music/compare/v3.1.0...v3.1.1)
|
||||||
|
|
||||||
|
> 18 December 2023
|
||||||
|
|
||||||
- fix: fix renderer plugin load timing [`#1522`](https://github.com/th-ch/youtube-music/issues/1522)
|
- fix: fix renderer plugin load timing [`#1522`](https://github.com/th-ch/youtube-music/issues/1522)
|
||||||
- chore(i18n): Translated using Weblate (Lithuanian) [`fc1a7cd`](https://github.com/th-ch/youtube-music/commit/fc1a7cda62b6e33e5f5d57a5a6e0adef6a32bf9a)
|
- chore(i18n): Translated using Weblate (Lithuanian) [`fc1a7cd`](https://github.com/th-ch/youtube-music/commit/fc1a7cda62b6e33e5f5d57a5a6e0adef6a32bf9a)
|
||||||
- chore(i18n): Translated using Weblate (Chinese (Simplified)) [`eba7026`](https://github.com/th-ch/youtube-music/commit/eba7026b89bbfdd3ac07cf728a66ba9bdd274ec0)
|
- chore(i18n): Translated using Weblate (Chinese (Simplified)) [`eba7026`](https://github.com/th-ch/youtube-music/commit/eba7026b89bbfdd3ac07cf728a66ba9bdd274ec0)
|
||||||
|
|||||||
29
package.json
29
package.json
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "youtube-music",
|
"name": "youtube-music",
|
||||||
"productName": "YouTube Music",
|
"productName": "YouTube Music",
|
||||||
"version": "3.2.0",
|
"version": "3.2.2",
|
||||||
"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",
|
||||||
@ -123,14 +123,17 @@
|
|||||||
},
|
},
|
||||||
"pnpm": {
|
"pnpm": {
|
||||||
"overrides": {
|
"overrides": {
|
||||||
"esbuild": "0.18.20",
|
"esbuild": "0.19.11",
|
||||||
"usocket": "1.0.1",
|
"usocket": "1.0.1",
|
||||||
"rollup": "4.9.2",
|
"rollup": "4.9.3",
|
||||||
"node-gyp": "10.0.1",
|
"node-gyp": "10.0.1",
|
||||||
"xml2js": "0.6.2",
|
"xml2js": "0.6.2",
|
||||||
"node-fetch": "3.3.2",
|
"node-fetch": "3.3.2",
|
||||||
"@electron/universal": "2.0.1",
|
"@electron/universal": "2.0.1",
|
||||||
"@babel/runtime": "7.23.7"
|
"@babel/runtime": "7.23.7"
|
||||||
|
},
|
||||||
|
"patchedDependencies": {
|
||||||
|
"vudio@2.1.1": "patches/vudio@2.1.1.patch"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -163,7 +166,7 @@
|
|||||||
"filenamify": "6.0.0",
|
"filenamify": "6.0.0",
|
||||||
"howler": "2.2.4",
|
"howler": "2.2.4",
|
||||||
"html-to-text": "9.0.5",
|
"html-to-text": "9.0.5",
|
||||||
"i18next": "23.7.13",
|
"i18next": "23.7.16",
|
||||||
"keyboardevent-from-electron-accelerator": "2.0.0",
|
"keyboardevent-from-electron-accelerator": "2.0.0",
|
||||||
"keyboardevents-areequal": "0.2.2",
|
"keyboardevents-areequal": "0.2.2",
|
||||||
"node-html-parser": "6.1.12",
|
"node-html-parser": "6.1.12",
|
||||||
@ -178,23 +181,23 @@
|
|||||||
"youtubei.js": "8.1.0"
|
"youtubei.js": "8.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@playwright/test": "1.41.0-alpha-dec-18-2023",
|
"@playwright/test": "1.41.0-alpha-jan-5-2024",
|
||||||
"@total-typescript/ts-reset": "0.5.1",
|
"@total-typescript/ts-reset": "0.5.1",
|
||||||
"@types/color": "3.0.6",
|
"@types/color": "3.0.6",
|
||||||
"@types/electron-localshortcut": "3.1.3",
|
"@types/electron-localshortcut": "3.1.3",
|
||||||
"@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.6",
|
"@types/semver": "7.5.6",
|
||||||
"@typescript-eslint/eslint-plugin": "6.16.0",
|
"@typescript-eslint/eslint-plugin": "6.17.0",
|
||||||
"bufferutil": "4.0.8",
|
"bufferutil": "4.0.8",
|
||||||
"builtin-modules": "3.3.0",
|
"builtin-modules": "3.3.0",
|
||||||
"cross-env": "7.0.3",
|
"cross-env": "7.0.3",
|
||||||
"del-cli": "5.1.0",
|
"del-cli": "5.1.0",
|
||||||
"electron": "28.1.0",
|
"electron": "29.0.0-alpha.7",
|
||||||
"electron-builder": "24.9.1",
|
"electron-builder": "24.9.1",
|
||||||
"electron-devtools-installer": "3.2.0",
|
"electron-devtools-installer": "3.2.0",
|
||||||
"electron-vite": "2.0.0-beta.2",
|
"electron-vite": "2.0.0-beta.3",
|
||||||
"esbuild": "0.18.20",
|
"esbuild": "0.19.11",
|
||||||
"eslint": "8.56.0",
|
"eslint": "8.56.0",
|
||||||
"eslint-import-resolver-exports": "1.0.0-beta.5",
|
"eslint-import-resolver-exports": "1.0.0-beta.5",
|
||||||
"eslint-import-resolver-typescript": "3.6.1",
|
"eslint-import-resolver-typescript": "3.6.1",
|
||||||
@ -202,11 +205,11 @@
|
|||||||
"eslint-plugin-prettier": "5.1.2",
|
"eslint-plugin-prettier": "5.1.2",
|
||||||
"glob": "10.3.10",
|
"glob": "10.3.10",
|
||||||
"node-gyp": "10.0.1",
|
"node-gyp": "10.0.1",
|
||||||
"playwright": "1.41.0-alpha-dec-18-2023",
|
"playwright": "1.41.0-alpha-jan-5-2024",
|
||||||
"rollup": "4.9.2",
|
"rollup": "4.9.3",
|
||||||
"typescript": "5.3.3",
|
"typescript": "5.3.3",
|
||||||
"utf-8-validate": "6.0.3",
|
"utf-8-validate": "6.0.3",
|
||||||
"vite": "5.0.10",
|
"vite": "5.0.11",
|
||||||
"vite-plugin-inspect": "0.8.1",
|
"vite-plugin-inspect": "0.8.1",
|
||||||
"vite-plugin-resolve": "2.5.1",
|
"vite-plugin-resolve": "2.5.1",
|
||||||
"ws": "8.16.0"
|
"ws": "8.16.0"
|
||||||
@ -217,5 +220,5 @@
|
|||||||
"unreleased": true,
|
"unreleased": true,
|
||||||
"output": "changelog.md"
|
"output": "changelog.md"
|
||||||
},
|
},
|
||||||
"packageManager": "pnpm@8.13.1"
|
"packageManager": "pnpm@8.14.0"
|
||||||
}
|
}
|
||||||
|
|||||||
20
patches/vudio@2.1.1.patch
Normal file
20
patches/vudio@2.1.1.patch
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
diff --git a/umd/vudio.js b/umd/vudio.js
|
||||||
|
index d0d1127e57125ad4e77442af2db4a26998c7b385..c0b66bd4327c65c31dc6e588bfa4ae6ec70bd3b8 100644
|
||||||
|
--- a/umd/vudio.js
|
||||||
|
+++ b/umd/vudio.js
|
||||||
|
@@ -147,7 +147,6 @@
|
||||||
|
|
||||||
|
source.connect(this.analyser);
|
||||||
|
this.analyser.fftSize = this.option.accuracy * 2;
|
||||||
|
- this.analyser.connect(audioContext.destination);
|
||||||
|
|
||||||
|
this.freqByteData = new Uint8Array(this.analyser.frequencyBinCount);
|
||||||
|
|
||||||
|
@@ -207,7 +206,6 @@
|
||||||
|
|
||||||
|
source.connect(this.analyser);
|
||||||
|
this.analyser.fftSize = this.option.accuracy * 2;
|
||||||
|
- this.analyser.connect(audioContext.destination);
|
||||||
|
},
|
||||||
|
|
||||||
|
__rebuildData : function (freqByteData, horizontalAlign) {
|
||||||
746
pnpm-lock.yaml
generated
746
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -8,8 +8,7 @@
|
|||||||
"load-all": "Načítání všech pluginů",
|
"load-all": "Načítání všech pluginů",
|
||||||
"load-failed": "Selhalo načtení \"{{pluginName}}\" pluginu",
|
"load-failed": "Selhalo načtení \"{{pluginName}}\" pluginu",
|
||||||
"loaded": "Plugin \"{{pluginName}}\" načten",
|
"loaded": "Plugin \"{{pluginName}}\" načten",
|
||||||
"unload-failed": "Selhalo unload \"{{pluginName}}\" pluginu",
|
"unload-failed": "Selhalo unload \"{{pluginName}}\" pluginu"
|
||||||
"unloaded": "Plugin \"{{pluginName}}\" unloaded"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -170,7 +169,8 @@
|
|||||||
},
|
},
|
||||||
"plugins": {
|
"plugins": {
|
||||||
"enabled": "Povoleno",
|
"enabled": "Povoleno",
|
||||||
"label": "Pluginy"
|
"label": "Pluginy",
|
||||||
|
"new": "NOVÉ"
|
||||||
},
|
},
|
||||||
"view": {
|
"view": {
|
||||||
"label": "Zobrazení",
|
"label": "Zobrazení",
|
||||||
@ -293,7 +293,7 @@
|
|||||||
"menu": {
|
"menu": {
|
||||||
"advanced": "Pokročilý"
|
"advanced": "Pokročilý"
|
||||||
},
|
},
|
||||||
"name": "Prolínání [beta]",
|
"name": "Prolínání [Beta]",
|
||||||
"prompt": {
|
"prompt": {
|
||||||
"options": {
|
"options": {
|
||||||
"multi-input": {
|
"multi-input": {
|
||||||
@ -360,6 +360,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"feedback": {
|
"feedback": {
|
||||||
|
"conversion-progress": "Konverze: {{percent}}%",
|
||||||
"done": "Hotovo: {{filePath}}",
|
"done": "Hotovo: {{filePath}}",
|
||||||
"download-info": "Stahování {{artist}} - {{title}} [{{videoId}}",
|
"download-info": "Stahování {{artist}} - {{title}} [{{videoId}}",
|
||||||
"download-progress": "Stahování: {{percent}}%",
|
"download-progress": "Stahování: {{percent}}%",
|
||||||
@ -401,7 +402,10 @@
|
|||||||
"name": "Exponenciální hlasitost"
|
"name": "Exponenciální hlasitost"
|
||||||
},
|
},
|
||||||
"in-app-menu": {
|
"in-app-menu": {
|
||||||
"description": "Dává menu panelům fancy, tmavý nebo album-color vzhled"
|
"description": "Dává menu panelům fancy, tmavý nebo album-color vzhled",
|
||||||
|
"menu": {
|
||||||
|
"hide-dom-window-controls": "Skrýt DOM window controls"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"last-fm": {
|
"last-fm": {
|
||||||
"description": "Přidat scrobbling podporu pro Last.fm",
|
"description": "Přidat scrobbling podporu pro Last.fm",
|
||||||
@ -409,7 +413,7 @@
|
|||||||
},
|
},
|
||||||
"lumiastream": {
|
"lumiastream": {
|
||||||
"description": "Přidává Lumia Stream podporu",
|
"description": "Přidává Lumia Stream podporu",
|
||||||
"name": "Lumia Stream [beta]"
|
"name": "Lumia Stream [Beta]"
|
||||||
},
|
},
|
||||||
"lyrics-genius": {
|
"lyrics-genius": {
|
||||||
"description": "Přidává lyrics podporu pro většinu písniček",
|
"description": "Přidává lyrics podporu pro většinu písniček",
|
||||||
@ -417,6 +421,50 @@
|
|||||||
"fetched-lyrics": "Fetched lyrics pro Genius"
|
"fetched-lyrics": "Fetched lyrics pro Genius"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"music-together": {
|
||||||
|
"description": "Sdílejte seznam písniček s ostatními. Když the host hraje písničku, uslyší jí i všichni ostatní.",
|
||||||
|
"dialog": {
|
||||||
|
"enter-host": "Zadejte Host ID"
|
||||||
|
},
|
||||||
|
"internal": {
|
||||||
|
"save": "Uložit",
|
||||||
|
"unknown-user": "Neznámý uživatel"
|
||||||
|
},
|
||||||
|
"menu": {
|
||||||
|
"click-to-copy-id": "Zkopírovat Host ID",
|
||||||
|
"close": "Zavřít Hudba Spolu",
|
||||||
|
"connected-users": "Připojení uživatelé",
|
||||||
|
"disconnect": "Odpojit od Hudby Spolu",
|
||||||
|
"empty-user": "Žadní připojení uživatelé",
|
||||||
|
"host": "Hudba Spolu Host",
|
||||||
|
"join": "Připojit se k Hudbě Spolu",
|
||||||
|
"permission": {
|
||||||
|
"all": "Povolit hostům ovládat seznam písniček a přehrávač",
|
||||||
|
"host-only": "Jenom host může ovládat seznam písniček a přehrávač",
|
||||||
|
"playlist": "Povolit hostům ovládat seznam písniček"
|
||||||
|
},
|
||||||
|
"set-permission": "Změnit ovládací oprávnění",
|
||||||
|
"status": {
|
||||||
|
"disconnected": "Odpojen",
|
||||||
|
"guest": "Připojený/á jako Guest",
|
||||||
|
"host": "Připojený/á jako Host"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": "Hudba Spolu [Beta]",
|
||||||
|
"toast": {
|
||||||
|
"add-song-failed": "Selhalo přidání písničky",
|
||||||
|
"closed": "Hudba Spolu zavřena",
|
||||||
|
"disconnected": "Hudba Spolu odpojena",
|
||||||
|
"host-failed": "Selhalo hostování Hudby Spolu",
|
||||||
|
"id-copied": "Host ID zkopírováno do schránky",
|
||||||
|
"join-failed": "Selhalo připojení k Hudba Spolu",
|
||||||
|
"joined": "Připojil/a jste se k Hudbě Spolu",
|
||||||
|
"permission-changed": "Oprávnění Hudby Spolu se změnilo na \"{{permission}}\"",
|
||||||
|
"remove-song-failed": "Selhalo odstranění písničky",
|
||||||
|
"user-connected": "{{name}} se připojil/a k Hudbě Spolu",
|
||||||
|
"user-disconnected": "{{name}} odpustil/a Hudba Spolu"
|
||||||
|
}
|
||||||
|
},
|
||||||
"navigation": {
|
"navigation": {
|
||||||
"description": "Další/Zpátky navigační šipky přímo integrovány do rozhraní, jako ve vašem oblíbeném prohlížeči",
|
"description": "Další/Zpátky navigační šipky přímo integrovány do rozhraní, jako ve vašem oblíbeném prohlížeči",
|
||||||
"name": "Navigace"
|
"name": "Navigace"
|
||||||
@ -539,7 +587,7 @@
|
|||||||
"name": "SponsorBlock"
|
"name": "SponsorBlock"
|
||||||
},
|
},
|
||||||
"taskbar-mediacontrol": {
|
"taskbar-mediacontrol": {
|
||||||
"description": "Ovládejte přehrávání z vašeho hlavního panelu Windows",
|
"description": "Ovládejte přehrávání z vašeho Windows hlavního panelu",
|
||||||
"name": "Hlavní panel Media Control"
|
"name": "Hlavní panel Media Control"
|
||||||
},
|
},
|
||||||
"touchbar": {
|
"touchbar": {
|
||||||
|
|||||||
@ -186,6 +186,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tray": {
|
"tray": {
|
||||||
|
"tooltip": {
|
||||||
|
"default": "YouTube Music",
|
||||||
|
"with-song-info": "YouTube Music: {{artist}} - {{title}}"
|
||||||
|
},
|
||||||
"next": "Next",
|
"next": "Next",
|
||||||
"play-pause": "Play/Pause",
|
"play-pause": "Play/Pause",
|
||||||
"previous": "Previous",
|
"previous": "Previous",
|
||||||
@ -202,6 +206,10 @@
|
|||||||
},
|
},
|
||||||
"name": "Adblocker"
|
"name": "Adblocker"
|
||||||
},
|
},
|
||||||
|
"album-actions": {
|
||||||
|
"description": "Adds Undislike, Dislike, Like, and Unlike buttons to apply this to all songs in a playlist or album.",
|
||||||
|
"name": "Album actions"
|
||||||
|
},
|
||||||
"album-color-theme": {
|
"album-color-theme": {
|
||||||
"description": "Applies a dynamic theme and visual effects based on the album color palette",
|
"description": "Applies a dynamic theme and visual effects based on the album color palette",
|
||||||
"name": "Album Color Theme"
|
"name": "Album Color Theme"
|
||||||
@ -290,7 +298,7 @@
|
|||||||
"menu": {
|
"menu": {
|
||||||
"advanced": "Advanced"
|
"advanced": "Advanced"
|
||||||
},
|
},
|
||||||
"name": "Crossfade [beta]",
|
"name": "Crossfade [Beta]",
|
||||||
"prompt": {
|
"prompt": {
|
||||||
"options": {
|
"options": {
|
||||||
"multi-input": {
|
"multi-input": {
|
||||||
@ -415,7 +423,7 @@
|
|||||||
},
|
},
|
||||||
"lumiastream": {
|
"lumiastream": {
|
||||||
"description": "Adds Lumia Stream support",
|
"description": "Adds Lumia Stream support",
|
||||||
"name": "Lumia Stream [beta]"
|
"name": "Lumia Stream [Beta]"
|
||||||
},
|
},
|
||||||
"lyrics-genius": {
|
"lyrics-genius": {
|
||||||
"description": "Adds lyrics support for most songs",
|
"description": "Adds lyrics support for most songs",
|
||||||
@ -427,6 +435,52 @@
|
|||||||
"fetched-lyrics": "Fetched lyrics for Genius"
|
"fetched-lyrics": "Fetched lyrics for Genius"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"music-together": {
|
||||||
|
"description": "Share a playlist with others. When the host plays a song, everyone else will hear the same song",
|
||||||
|
"dialog": {
|
||||||
|
"enter-host": "Enter Host ID"
|
||||||
|
},
|
||||||
|
"internal": {
|
||||||
|
"save": "Save",
|
||||||
|
"track-source": "Track Source",
|
||||||
|
"unknown-user": "Unknown User"
|
||||||
|
},
|
||||||
|
"menu": {
|
||||||
|
"click-to-copy-id": "Copy Host ID",
|
||||||
|
"close": "Close Music Together",
|
||||||
|
"connected-users": "Connected Users",
|
||||||
|
"disconnect": "Disconnect Music Together",
|
||||||
|
"empty-user": "No connected users",
|
||||||
|
"host": "Music Together Host",
|
||||||
|
"join": "Join Music Together",
|
||||||
|
"permission": {
|
||||||
|
"all": "Allow guests to control playlist and player",
|
||||||
|
"host-only": "Only the host can control playlist and player",
|
||||||
|
"playlist": "Allow guests to control playlist"
|
||||||
|
},
|
||||||
|
"set-permission": "Change Control Permission",
|
||||||
|
"status": {
|
||||||
|
"disconnected": "Disconnected",
|
||||||
|
"guest": "Connected as Guest",
|
||||||
|
"host": "Connected as Host"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": "Music Together [Beta]",
|
||||||
|
"toast": {
|
||||||
|
"add-song-failed": "Failed to add song",
|
||||||
|
"closed": "Music Together closed",
|
||||||
|
"disconnected": "Music Together disconnected",
|
||||||
|
"host-failed": "Failed to host Music Together",
|
||||||
|
"id-copied": "Host ID copied to clipboard",
|
||||||
|
"id-copy-failed": "Failed to copy Host ID to clipboard",
|
||||||
|
"join-failed": "Failed to join Music Together",
|
||||||
|
"joined": "Joined Music Together",
|
||||||
|
"permission-changed": "Music Together permission changed to \"{{permission}}\"",
|
||||||
|
"remove-song-failed": "Failed to remove song",
|
||||||
|
"user-connected": "{{name}} joined Music Together",
|
||||||
|
"user-disconnected": "{{name}} left Music Together"
|
||||||
|
}
|
||||||
|
},
|
||||||
"navigation": {
|
"navigation": {
|
||||||
"description": "Next/Back navigation arrows directly integrated in the interface, like in your favorite browser",
|
"description": "Next/Back navigation arrows directly integrated in the interface, like in your favorite browser",
|
||||||
"name": "Navigation"
|
"name": "Navigation"
|
||||||
@ -435,51 +489,6 @@
|
|||||||
"description": "Remove Google login buttons and links from the interface",
|
"description": "Remove Google login buttons and links from the interface",
|
||||||
"name": "No Google Login"
|
"name": "No Google Login"
|
||||||
},
|
},
|
||||||
"music-together": {
|
|
||||||
"name": "Music Together [Beta]",
|
|
||||||
"description": "Share a playlist with others. When the host plays a song, everyone else will hear the same song",
|
|
||||||
"internal": {
|
|
||||||
"unknown-user": "Unknown User",
|
|
||||||
"track-source": "Track Source",
|
|
||||||
"save": "Save"
|
|
||||||
},
|
|
||||||
"menu": {
|
|
||||||
"disconnect": "Disconnect Music Together",
|
|
||||||
"click-to-copy-id": "Copy Host ID",
|
|
||||||
"close": "Close Music Together",
|
|
||||||
"host": "Music Together Host",
|
|
||||||
"join": "Join Music Together",
|
|
||||||
"connected-users": "Connected Users",
|
|
||||||
"empty-user": "No connected users",
|
|
||||||
"set-permission": "Change Control Permission",
|
|
||||||
"status": {
|
|
||||||
"disconnected": "Disconnected",
|
|
||||||
"host": "Connected as Host",
|
|
||||||
"guest": "Connected as Guest"
|
|
||||||
},
|
|
||||||
"permission": {
|
|
||||||
"host-only": "Host Only",
|
|
||||||
"playlist": "Playlist Control",
|
|
||||||
"all": "All Control"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"dialog": {
|
|
||||||
"enter-host": "Enter Host ID"
|
|
||||||
},
|
|
||||||
"toast": {
|
|
||||||
"add-song-failed": "Failed to add song",
|
|
||||||
"remove-song-failed": "Failed to remove song",
|
|
||||||
"closed": "Music Together closed",
|
|
||||||
"disconnected": "Music Together disconnected",
|
|
||||||
"id-copied": "Host ID copied to clipboard",
|
|
||||||
"host-failed": "Failed to host Music Together",
|
|
||||||
"joined": "Joined Music Together",
|
|
||||||
"user-connected": "{{name}} joined Music Together",
|
|
||||||
"user-disconnected": "{{name}} left Music Together",
|
|
||||||
"join-failed": "Failed to join Music Together",
|
|
||||||
"permission-changed": "Music Together permission changed to \"{{permission}}\""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notifications": {
|
"notifications": {
|
||||||
"description": "Display a notification when a song starts playing (interactive notifications are available on Windows)",
|
"description": "Display a notification when a song starts playing (interactive notifications are available on Windows)",
|
||||||
"menu": {
|
"menu": {
|
||||||
@ -639,10 +648,6 @@
|
|||||||
"visualizer-type": "Visualizer Type"
|
"visualizer-type": "Visualizer Type"
|
||||||
},
|
},
|
||||||
"name": "Visualizer"
|
"name": "Visualizer"
|
||||||
},
|
|
||||||
"album-actions": {
|
|
||||||
"description": "Adds Undislike, Dislike, Like, and Unlike buttons to apply this to all songs in a playlist or album.",
|
|
||||||
"name": "Album actions"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -170,7 +170,8 @@
|
|||||||
},
|
},
|
||||||
"plugins": {
|
"plugins": {
|
||||||
"enabled": "Habilitado",
|
"enabled": "Habilitado",
|
||||||
"label": "Plugins"
|
"label": "Plugins",
|
||||||
|
"new": "NUEVO"
|
||||||
},
|
},
|
||||||
"view": {
|
"view": {
|
||||||
"label": "Ver",
|
"label": "Ver",
|
||||||
@ -190,7 +191,11 @@
|
|||||||
"previous": "Anterior",
|
"previous": "Anterior",
|
||||||
"quit": "Salir",
|
"quit": "Salir",
|
||||||
"restart": "Reiniciar la aplicación",
|
"restart": "Reiniciar la aplicación",
|
||||||
"show": "Mostrar ventana"
|
"show": "Mostrar ventana",
|
||||||
|
"tooltip": {
|
||||||
|
"default": "YouTube Music",
|
||||||
|
"with-song-info": "YouTube Music: {{artist}} - {{title}}"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"plugins": {
|
"plugins": {
|
||||||
@ -201,6 +206,10 @@
|
|||||||
},
|
},
|
||||||
"name": "Adblocker"
|
"name": "Adblocker"
|
||||||
},
|
},
|
||||||
|
"album-actions": {
|
||||||
|
"description": "Añade los botones \"No me gusta\", \"No me gusta\", \"Me gusta\" y \"No me gusta\" para aplicarlos a todas las canciones de una lista de reproducción o un álbum.",
|
||||||
|
"name": "Acciones del álbum"
|
||||||
|
},
|
||||||
"album-color-theme": {
|
"album-color-theme": {
|
||||||
"description": "Aplica un tema dinámico y efectos visuales basados en la paleta de colores del álbum",
|
"description": "Aplica un tema dinámico y efectos visuales basados en la paleta de colores del álbum",
|
||||||
"name": "Color del álbum"
|
"name": "Color del álbum"
|
||||||
@ -289,7 +298,7 @@
|
|||||||
"menu": {
|
"menu": {
|
||||||
"advanced": "Avanzado"
|
"advanced": "Avanzado"
|
||||||
},
|
},
|
||||||
"name": "Crossfade [beta]",
|
"name": "Crossfade [Beta]",
|
||||||
"prompt": {
|
"prompt": {
|
||||||
"options": {
|
"options": {
|
||||||
"multi-input": {
|
"multi-input": {
|
||||||
@ -414,7 +423,7 @@
|
|||||||
},
|
},
|
||||||
"lumiastream": {
|
"lumiastream": {
|
||||||
"description": "Agrega soporte para Lumia Stream",
|
"description": "Agrega soporte para Lumia Stream",
|
||||||
"name": "Lumia Stream [beta]"
|
"name": "Lumia Stream [Beta]"
|
||||||
},
|
},
|
||||||
"lyrics-genius": {
|
"lyrics-genius": {
|
||||||
"description": "Añade el soporte para las letras para la mayoría de las canciones",
|
"description": "Añade el soporte para las letras para la mayoría de las canciones",
|
||||||
@ -426,6 +435,51 @@
|
|||||||
"fetched-lyrics": "Letras recuperadas de Genius"
|
"fetched-lyrics": "Letras recuperadas de Genius"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"music-together": {
|
||||||
|
"description": "Comparte una lista de reproducción con los demás. Cuando el anfitrión reproduzca una canción, todos los demás escucharán la misma",
|
||||||
|
"dialog": {
|
||||||
|
"enter-host": "Introduzca el ID del host"
|
||||||
|
},
|
||||||
|
"internal": {
|
||||||
|
"save": "Guardar",
|
||||||
|
"track-source": "Fuente de la pista",
|
||||||
|
"unknown-user": "Usuario desconocido"
|
||||||
|
},
|
||||||
|
"menu": {
|
||||||
|
"click-to-copy-id": "Copiar el ID del host",
|
||||||
|
"close": "Cerrar Music Together",
|
||||||
|
"connected-users": "Usuarios conectados",
|
||||||
|
"disconnect": "Desactivar Music Together",
|
||||||
|
"empty-user": "No hay usuarios conectados",
|
||||||
|
"host": "Host de Music Together",
|
||||||
|
"join": "Únase a Music Together",
|
||||||
|
"permission": {
|
||||||
|
"all": "Permite a los invitados controlar la lista de reproducción y el reproductor",
|
||||||
|
"host-only": "Sólo el anfitrión puede controlar la lista de reproducción y el reproductor",
|
||||||
|
"playlist": "Permita que los invitados controlen la lista de reproducción"
|
||||||
|
},
|
||||||
|
"set-permission": "Permiso de control de cambios",
|
||||||
|
"status": {
|
||||||
|
"disconnected": "Desconectado",
|
||||||
|
"guest": "Conectado como invitado",
|
||||||
|
"host": "Conectado como anfitrión"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": "Music Together [Beta]",
|
||||||
|
"toast": {
|
||||||
|
"add-song-failed": "No se puede añadir la canción",
|
||||||
|
"closed": "Music Together cerrado",
|
||||||
|
"disconnected": "Music Together desconectados",
|
||||||
|
"host-failed": "Fallo el host de Music Together",
|
||||||
|
"id-copied": "ID del host copiado en el portapapeles",
|
||||||
|
"join-failed": "Fallo en la unión a Music Together",
|
||||||
|
"joined": "Unido a Music Together",
|
||||||
|
"permission-changed": "Permiso de Music Together cambiado a \"{{permission}}\"",
|
||||||
|
"remove-song-failed": "Error al eliminar la canción",
|
||||||
|
"user-connected": "{{name}} se unió a Music Together",
|
||||||
|
"user-disconnected": "{{name}} dejó Music Together"
|
||||||
|
}
|
||||||
|
},
|
||||||
"navigation": {
|
"navigation": {
|
||||||
"description": "Flechas de navegación Siguiente/Atrás directamente integradas en la interfaz, como en tu navegador favorito",
|
"description": "Flechas de navegación Siguiente/Atrás directamente integradas en la interfaz, como en tu navegador favorito",
|
||||||
"name": "Navegación"
|
"name": "Navegación"
|
||||||
|
|||||||
@ -289,7 +289,7 @@
|
|||||||
"menu": {
|
"menu": {
|
||||||
"advanced": "Avancé"
|
"advanced": "Avancé"
|
||||||
},
|
},
|
||||||
"name": "Fondu enchaîné [bêta]",
|
"name": "Fondu enchaîné [Bêta]",
|
||||||
"prompt": {
|
"prompt": {
|
||||||
"options": {
|
"options": {
|
||||||
"multi-input": {
|
"multi-input": {
|
||||||
@ -414,7 +414,7 @@
|
|||||||
},
|
},
|
||||||
"lumiastream": {
|
"lumiastream": {
|
||||||
"description": "Ajoute la prise en charge de Lumia Stream",
|
"description": "Ajoute la prise en charge de Lumia Stream",
|
||||||
"name": "Lumia Stream [bêta]"
|
"name": "Lumia Stream [Bêta]"
|
||||||
},
|
},
|
||||||
"lyrics-genius": {
|
"lyrics-genius": {
|
||||||
"description": "Ajoute la prise en charge des paroles pour la plupart des chansons",
|
"description": "Ajoute la prise en charge des paroles pour la plupart des chansons",
|
||||||
|
|||||||
@ -170,7 +170,8 @@
|
|||||||
},
|
},
|
||||||
"plugins": {
|
"plugins": {
|
||||||
"enabled": "Attivato",
|
"enabled": "Attivato",
|
||||||
"label": "Plugin"
|
"label": "Plugin",
|
||||||
|
"new": "NUOVO"
|
||||||
},
|
},
|
||||||
"view": {
|
"view": {
|
||||||
"label": "Visualizzazione",
|
"label": "Visualizzazione",
|
||||||
@ -201,6 +202,10 @@
|
|||||||
},
|
},
|
||||||
"name": "Adblocker"
|
"name": "Adblocker"
|
||||||
},
|
},
|
||||||
|
"album-actions": {
|
||||||
|
"description": "Aggiunge i pulsanti Undislike, Dislike, Like e Unlike a tutti i brani di una playlist o di un album.",
|
||||||
|
"name": "Azioni album"
|
||||||
|
},
|
||||||
"album-color-theme": {
|
"album-color-theme": {
|
||||||
"description": "Applica un tema dinamico e degli effetti visivi basandosi sul colore dell'album",
|
"description": "Applica un tema dinamico e degli effetti visivi basandosi sul colore dell'album",
|
||||||
"name": "Tema abbinato a colore album"
|
"name": "Tema abbinato a colore album"
|
||||||
@ -414,7 +419,7 @@
|
|||||||
},
|
},
|
||||||
"lumiastream": {
|
"lumiastream": {
|
||||||
"description": "Aggiungi supporto per Lumia Stream",
|
"description": "Aggiungi supporto per Lumia Stream",
|
||||||
"name": "Lumia Stream [beta]"
|
"name": "Lumia Stream [Beta]"
|
||||||
},
|
},
|
||||||
"lyrics-genius": {
|
"lyrics-genius": {
|
||||||
"description": "Aggiunge il supporto dei testi per la maggior parte delle canzoni",
|
"description": "Aggiunge il supporto dei testi per la maggior parte delle canzoni",
|
||||||
@ -426,6 +431,51 @@
|
|||||||
"fetched-lyrics": "Testi recuperati per Genius"
|
"fetched-lyrics": "Testi recuperati per Genius"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"music-together": {
|
||||||
|
"description": "Condividi una playlist con altri. Quando l'Host riproduce un brano, tutti gli altri ascolteranno lo stesso brano",
|
||||||
|
"dialog": {
|
||||||
|
"enter-host": "Inserisci l'ID dell'Host"
|
||||||
|
},
|
||||||
|
"internal": {
|
||||||
|
"save": "Salva",
|
||||||
|
"track-source": "Traccia sorgente",
|
||||||
|
"unknown-user": "Utente sconosciuto"
|
||||||
|
},
|
||||||
|
"menu": {
|
||||||
|
"click-to-copy-id": "Copia l'ID dell'Host",
|
||||||
|
"close": "Chiudi Music Together",
|
||||||
|
"connected-users": "Utenti connessi",
|
||||||
|
"disconnect": "Disconetti Music Together",
|
||||||
|
"empty-user": "Utenti non connessi",
|
||||||
|
"host": "Music Together Host",
|
||||||
|
"join": "Unisciti a Music Together",
|
||||||
|
"permission": {
|
||||||
|
"all": "Consenti ai Guest di controllare la playlist e il player",
|
||||||
|
"host-only": "Solo l'Host può controllare la playlist e il player",
|
||||||
|
"playlist": "Consenti ai Guest di controllare la playlist"
|
||||||
|
},
|
||||||
|
"set-permission": "Cambia autorizzazione di controllo",
|
||||||
|
"status": {
|
||||||
|
"disconnected": "Disconnesso",
|
||||||
|
"guest": "Connesso come Guest",
|
||||||
|
"host": "Connesso come Host"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": "Music Together [Beta]",
|
||||||
|
"toast": {
|
||||||
|
"add-song-failed": "Impossibile aggiungere il brano",
|
||||||
|
"closed": "Music Together chiuso",
|
||||||
|
"disconnected": "Music Together disconnesso",
|
||||||
|
"host-failed": "Impossibile ospitare Music Together",
|
||||||
|
"id-copied": "L'ID dell Host è stato copiato negli appunti",
|
||||||
|
"join-failed": "Impossibile unirsi a Music Together",
|
||||||
|
"joined": "Unito a Music Together",
|
||||||
|
"permission-changed": "L'autorizzazione di Music Together è cambiata in {{permission}}",
|
||||||
|
"remove-song-failed": "Impossibile rimuovere il brano",
|
||||||
|
"user-connected": "{{name}} si è unito a Music Together",
|
||||||
|
"user-disconnected": "{{name}} ha lasciato Music Together"
|
||||||
|
}
|
||||||
|
},
|
||||||
"navigation": {
|
"navigation": {
|
||||||
"description": "Frecce di navigazione Avanti/Indietro integrate direttamente nell'interfaccia, come nel tuo browser preferito",
|
"description": "Frecce di navigazione Avanti/Indietro integrate direttamente nell'interfaccia, come nel tuo browser preferito",
|
||||||
"name": "Navigazione"
|
"name": "Navigazione"
|
||||||
|
|||||||
@ -191,7 +191,11 @@
|
|||||||
"previous": "이전",
|
"previous": "이전",
|
||||||
"quit": "종료",
|
"quit": "종료",
|
||||||
"restart": "앱 재시작",
|
"restart": "앱 재시작",
|
||||||
"show": "창 표시"
|
"show": "창 표시",
|
||||||
|
"tooltip": {
|
||||||
|
"default": "유튜브 뮤직",
|
||||||
|
"with-song-info": "유튜브 뮤직: {{artist}} - {{title}}"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"plugins": {
|
"plugins": {
|
||||||
@ -432,48 +436,49 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"music-together": {
|
"music-together": {
|
||||||
"name": "Music Together [베타]",
|
|
||||||
"description": "여러명과 함께 플레이리스트를 공유합니다. 호스트가 음악을 재생하면, 다른 사용자들도 같은 노래를 들을 수 있습니다",
|
"description": "여러명과 함께 플레이리스트를 공유합니다. 호스트가 음악을 재생하면, 다른 사용자들도 같은 노래를 들을 수 있습니다",
|
||||||
"internal": {
|
|
||||||
"unknown-user": "알 수 없는 사용자",
|
|
||||||
"track-source": "재생 중인 트랙 출처",
|
|
||||||
"save": "저장"
|
|
||||||
},
|
|
||||||
"menu": {
|
|
||||||
"disconnect": "Music Together 연결 끊기",
|
|
||||||
"click-to-copy-id": "호스트 아이디 복사",
|
|
||||||
"close": "Music Together 닫기",
|
|
||||||
"host": "Music Together 호스트",
|
|
||||||
"join": "Music Together 참여",
|
|
||||||
"connected-users": "연결된 사용자",
|
|
||||||
"empty-user": "연결된 사용자 없음",
|
|
||||||
"set-permission": "제어 권한 변경",
|
|
||||||
"status": {
|
|
||||||
"disconnected": "연결 끊김",
|
|
||||||
"host": "호스트로 연결됨",
|
|
||||||
"guest": "게스트로 연결됨"
|
|
||||||
},
|
|
||||||
"permission": {
|
|
||||||
"host-only": "호스트만 제어 가능",
|
|
||||||
"playlist": "재생목록 제어 가능",
|
|
||||||
"all": "모두 제어 가능"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"dialog": {
|
"dialog": {
|
||||||
"enter-host": "호스트 아이디를 입력하세요"
|
"enter-host": "호스트 아이디를 입력하세요"
|
||||||
},
|
},
|
||||||
|
"internal": {
|
||||||
|
"save": "저장",
|
||||||
|
"track-source": "재생 중인 트랙 출처",
|
||||||
|
"unknown-user": "알 수 없는 사용자"
|
||||||
|
},
|
||||||
|
"menu": {
|
||||||
|
"click-to-copy-id": "호스트 아이디 복사",
|
||||||
|
"close": "Music Together 닫기",
|
||||||
|
"connected-users": "연결된 사용자",
|
||||||
|
"disconnect": "Music Together 연결 끊기",
|
||||||
|
"empty-user": "연결된 사용자 없음",
|
||||||
|
"host": "Music Together 호스트",
|
||||||
|
"join": "Music Together 참여",
|
||||||
|
"permission": {
|
||||||
|
"all": "게스트가 모두 제어 가능",
|
||||||
|
"host-only": "호스트만 제어 가능",
|
||||||
|
"playlist": "게스트가 재생목록 제어 가능"
|
||||||
|
},
|
||||||
|
"set-permission": "제어 권한 변경",
|
||||||
|
"status": {
|
||||||
|
"disconnected": "연결 끊김",
|
||||||
|
"guest": "게스트로 연결됨",
|
||||||
|
"host": "호스트로 연결됨"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": "Music Together [베타]",
|
||||||
"toast": {
|
"toast": {
|
||||||
"add-song-failed": "노래 추가 실패",
|
"add-song-failed": "노래 추가 실패",
|
||||||
"remove-song-failed": "노래 제거 실패",
|
|
||||||
"closed": "Music Together가 닫혔습니다",
|
"closed": "Music Together가 닫혔습니다",
|
||||||
"disconnected": "Music Together 연결이 끊어졌습니다",
|
"disconnected": "Music Together 연결이 끊어졌습니다",
|
||||||
"id-copied": "호스트 아이디가 클립보드에 복사되었습니다",
|
|
||||||
"host-failed": "Music Together를 열 수 없습니다",
|
"host-failed": "Music Together를 열 수 없습니다",
|
||||||
"joined": "Music Together에 참여했습니다",
|
"id-copied": "호스트 아이디가 클립보드에 복사되었습니다",
|
||||||
"user-connected": "{{name}}님이 Music Together에 참여했습니다",
|
"id-copy-failed": "호스트 ID를 클립보드에 복사하지 못했습니다",
|
||||||
"user-disconnected": "{{name}}님이 Music Together에서 나갔습니다",
|
|
||||||
"join-failed": "Music Together에 참여할 수 없습니다",
|
"join-failed": "Music Together에 참여할 수 없습니다",
|
||||||
"permission-changed": "Music Together 제어 권한이 \"{{permission}}\" 변경되었습니다"
|
"joined": "Music Together에 참여했습니다",
|
||||||
|
"permission-changed": "Music Together 제어 권한이 \"{{permission}}\"(으)로 변경되었습니다",
|
||||||
|
"remove-song-failed": "노래 제거 실패",
|
||||||
|
"user-connected": "{{name}}님이 Music Together에 참여했습니다",
|
||||||
|
"user-disconnected": "{{name}}님이 Music Together에서 나갔습니다"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"navigation": {
|
"navigation": {
|
||||||
|
|||||||
@ -289,7 +289,7 @@
|
|||||||
"menu": {
|
"menu": {
|
||||||
"advanced": "Išplėstinė"
|
"advanced": "Išplėstinė"
|
||||||
},
|
},
|
||||||
"name": "Perliejimas [beta]",
|
"name": "Perliejimas [Beta]",
|
||||||
"prompt": {
|
"prompt": {
|
||||||
"options": {
|
"options": {
|
||||||
"multi-input": {
|
"multi-input": {
|
||||||
@ -414,7 +414,7 @@
|
|||||||
},
|
},
|
||||||
"lumiastream": {
|
"lumiastream": {
|
||||||
"description": "Prideda \"Lumia Stream\" palaikymą",
|
"description": "Prideda \"Lumia Stream\" palaikymą",
|
||||||
"name": "Lumia Stream [beta]"
|
"name": "Lumia Stream [Beta]"
|
||||||
},
|
},
|
||||||
"lyrics-genius": {
|
"lyrics-genius": {
|
||||||
"description": "Prideda daugumai dainių žodžių tekstus",
|
"description": "Prideda daugumai dainių žodžių tekstus",
|
||||||
|
|||||||
@ -287,7 +287,7 @@
|
|||||||
"menu": {
|
"menu": {
|
||||||
"advanced": "Avansert"
|
"advanced": "Avansert"
|
||||||
},
|
},
|
||||||
"name": "Overgang [beta]",
|
"name": "Overgang [Beta]",
|
||||||
"prompt": {
|
"prompt": {
|
||||||
"options": {
|
"options": {
|
||||||
"multi-input": {
|
"multi-input": {
|
||||||
@ -412,7 +412,7 @@
|
|||||||
},
|
},
|
||||||
"lumiastream": {
|
"lumiastream": {
|
||||||
"description": "Legger til Lumia Stream-støtte",
|
"description": "Legger til Lumia Stream-støtte",
|
||||||
"name": "Lumia Stream [beta]"
|
"name": "Lumia Stream [Beta]"
|
||||||
},
|
},
|
||||||
"lyrics-genius": {
|
"lyrics-genius": {
|
||||||
"description": "Gir sangtekststøtte for de fleste spor",
|
"description": "Gir sangtekststøtte for de fleste spor",
|
||||||
|
|||||||
@ -414,7 +414,7 @@
|
|||||||
},
|
},
|
||||||
"lumiastream": {
|
"lumiastream": {
|
||||||
"description": "Dodaje obsługę Lumia Stream",
|
"description": "Dodaje obsługę Lumia Stream",
|
||||||
"name": "Lumia Stream [beta]"
|
"name": "Lumia Stream [Beta]"
|
||||||
},
|
},
|
||||||
"lyrics-genius": {
|
"lyrics-genius": {
|
||||||
"description": "Dodaje obsługę tekstów dla większości piosenek",
|
"description": "Dodaje obsługę tekstów dla większości piosenek",
|
||||||
|
|||||||
@ -289,7 +289,7 @@
|
|||||||
"menu": {
|
"menu": {
|
||||||
"advanced": "Avançado"
|
"advanced": "Avançado"
|
||||||
},
|
},
|
||||||
"name": "Transição entre músicas [beta]",
|
"name": "Transição entre músicas [Beta]",
|
||||||
"prompt": {
|
"prompt": {
|
||||||
"options": {
|
"options": {
|
||||||
"multi-input": {
|
"multi-input": {
|
||||||
@ -414,7 +414,7 @@
|
|||||||
},
|
},
|
||||||
"lumiastream": {
|
"lumiastream": {
|
||||||
"description": "Adiciona suporte Lumia Stream",
|
"description": "Adiciona suporte Lumia Stream",
|
||||||
"name": "Lumia Stream [beta]"
|
"name": "Lumia Stream [Beta]"
|
||||||
},
|
},
|
||||||
"lyrics-genius": {
|
"lyrics-genius": {
|
||||||
"description": "Adiciona suporte a letras para a maioria das músicas",
|
"description": "Adiciona suporte a letras para a maioria das músicas",
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
"load-all": "Tüm eklentiler yükleniyor",
|
"load-all": "Tüm eklentiler yükleniyor",
|
||||||
"load-failed": "\"{{pluginName}}\" eklentisi yüklenemedi",
|
"load-failed": "\"{{pluginName}}\" eklentisi yüklenemedi",
|
||||||
"loaded": "\"{{pluginName}}\" eklentisi yüklendi",
|
"loaded": "\"{{pluginName}}\" eklentisi yüklendi",
|
||||||
"unload-failed": "\"{{pluginName}}\" eklentisi kaldırılamadı.",
|
"unload-failed": "\"{{pluginName}}\" eklentisi çıkartılamadı",
|
||||||
"unloaded": "\"{{pluginName}}\" eklentisi kaldırıldı"
|
"unloaded": "\"{{pluginName}}\" eklentisi kaldırıldı"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -48,50 +48,119 @@
|
|||||||
"message": "Menüyü gizle etkinleştirildi",
|
"message": "Menüyü gizle etkinleştirildi",
|
||||||
"title": "Menüyü gizle etkinleştirildi"
|
"title": "Menüyü gizle etkinleştirildi"
|
||||||
},
|
},
|
||||||
|
"need-to-restart": {
|
||||||
|
"buttons": {
|
||||||
|
"later": "Daha Sonra",
|
||||||
|
"restart-now": "Şimdi yeniden başlat"
|
||||||
|
},
|
||||||
|
"detail": "\"{{pluginName}}\" eklentisinin çalışabilmesi için yeniden başlatman gerekiyor",
|
||||||
|
"message": "\"{{pluginName}}\" için yeniden başlatman gerekiyor",
|
||||||
|
"title": "Uygulamayı yeniden başlatman gerekiyor"
|
||||||
|
},
|
||||||
|
"unresponsive": {
|
||||||
|
"buttons": {
|
||||||
|
"quit": "Çıkış",
|
||||||
|
"relaunch": "Yeniden Başlat",
|
||||||
|
"wait": "Bekle"
|
||||||
|
},
|
||||||
|
"detail": "Rahatsızlık için özür dileriz! Lütfen ne yapacağınızı seçin:",
|
||||||
|
"message": "Uygulama yanıt vermiyor",
|
||||||
|
"title": "Pencere yanıt vermiyor"
|
||||||
|
},
|
||||||
"update-available": {
|
"update-available": {
|
||||||
"buttons": {
|
"buttons": {
|
||||||
|
"disable": "Güncellemeleri devre dışı bırak",
|
||||||
"download": "İndir",
|
"download": "İndir",
|
||||||
"ok": "Tamam"
|
"ok": "Tamam"
|
||||||
}
|
},
|
||||||
|
"detail": "Yeni bir sürüm mevcut. {{downloadLink}} adresi üzerinden indirebilirsin",
|
||||||
|
"message": "Yeni bir sürüm mevcut",
|
||||||
|
"title": "Güncelleme Mevcut"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"menu": {
|
"menu": {
|
||||||
|
"about": "Hakkında",
|
||||||
"navigation": {
|
"navigation": {
|
||||||
"label": "Navigasyon"
|
"label": "Navigasyon",
|
||||||
|
"submenu": {
|
||||||
|
"copy-current-url": "Geçerli Url'yi kopyala",
|
||||||
|
"go-back": "Geri dön",
|
||||||
|
"go-forward": "İlerle",
|
||||||
|
"quit": "Çıkış",
|
||||||
|
"restart": "Uygulamayı Yeniden Başlat"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"options": {
|
"options": {
|
||||||
"label": "Seçenekler",
|
"label": "Seçenekler",
|
||||||
"submenu": {
|
"submenu": {
|
||||||
"advanced-options": {
|
"advanced-options": {
|
||||||
|
"label": "Gelişmiş Seçenekler",
|
||||||
"submenu": {
|
"submenu": {
|
||||||
|
"auto-reset-app-cache": "Uygulama başlatıldığında uygulama önbelleğini sıfırla",
|
||||||
|
"disable-hardware-acceleration": "Donanım hızlandırmayı devre dışı bırak",
|
||||||
|
"edit-config-json": "Düzenle config.json",
|
||||||
|
"override-user-agent": "\"User-Agent \"ı geçersiz kıl",
|
||||||
|
"restart-on-config-changes": "Yapılandırma değişikliğinde yeniden başlat",
|
||||||
"set-proxy": {
|
"set-proxy": {
|
||||||
"label": "Proxy ayarla",
|
"label": "Proxy ayarla",
|
||||||
"prompt": {
|
"prompt": {
|
||||||
|
"label": "Proxy Adresini Gir: (devre dışı bırakmak için boş bırakın)",
|
||||||
|
"placeholder": "Örnek: SOCKS5://127.0.0.1:9999",
|
||||||
"title": "Proxy ayarla"
|
"title": "Proxy ayarla"
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"toggle-dev-tools": "DevTools'u Aç / Kapat"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"always-on-top": "Her zaman üstte",
|
||||||
"auto-update": "Otomatik Güncelleme",
|
"auto-update": "Otomatik Güncelleme",
|
||||||
"language": {
|
"hide-menu": {
|
||||||
"label": "Dil"
|
"dialog": {
|
||||||
|
"message": "Menü bir sonraki açılışta gizlenecektir, göstermek için [Alt] tuşunu kullanın (veya uygulama-içi-menü kullanıyorsanız [`] tuşuna geri basın)",
|
||||||
|
"title": "Gizli Menü Aktif"
|
||||||
|
},
|
||||||
|
"label": "Gizli Menü"
|
||||||
},
|
},
|
||||||
|
"language": {
|
||||||
|
"dialog": {
|
||||||
|
"message": "Dil değişikliği yeniden başlattıktan sonra etkinleşecektir",
|
||||||
|
"title": "Dil değiştirildi"
|
||||||
|
},
|
||||||
|
"label": "Dil",
|
||||||
|
"submenu": {
|
||||||
|
"to-help-translate": "Çeviriye yardım etmek ister misiniz? Buraya tıklayın"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"resume-on-start": "Uygulama başlatıldığında son şarkıyı devam ettir",
|
||||||
|
"single-instance-lock": "Tek Örnek Kilidi",
|
||||||
"start-at-login": "Başlangıçta çalıştır",
|
"start-at-login": "Başlangıçta çalıştır",
|
||||||
|
"starting-page": {
|
||||||
|
"label": "Başlangıç sayfası",
|
||||||
|
"unset": "Ayarlanmadı"
|
||||||
|
},
|
||||||
"tray": {
|
"tray": {
|
||||||
"label": "Tepsi",
|
"label": "Tepsi",
|
||||||
"submenu": {
|
"submenu": {
|
||||||
"enabled-and-hide-app": "Uygulamayı etkinleştirin gizleyin.",
|
"disabled": "Devre Dışı",
|
||||||
"play-pause-on-click": "Tıklaynınca Oynat-Duraklat"
|
"enabled-and-hide-app": "Uygulamayı etkinleştirin gizleyin",
|
||||||
|
"enabled-and-show-app": "Etkinleştir ve uygulamayı göster",
|
||||||
|
"play-pause-on-click": "Tıklandığında Oynat/Duraklat"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"visual-tweaks": {
|
"visual-tweaks": {
|
||||||
|
"label": "Görsel İnce Ayarlar",
|
||||||
"submenu": {
|
"submenu": {
|
||||||
"like-buttons": {
|
"like-buttons": {
|
||||||
"default": "Varsayılan"
|
"default": "Varsayılan",
|
||||||
|
"force-show": "Zorla göster",
|
||||||
|
"hide": "Gizle",
|
||||||
|
"label": "Beğenme düğmeleri"
|
||||||
},
|
},
|
||||||
|
"remove-upgrade-button": "Yükseltme düğmesini kaldır",
|
||||||
"theme": {
|
"theme": {
|
||||||
"label": "Tema",
|
"label": "Tema",
|
||||||
"submenu": {
|
"submenu": {
|
||||||
|
"import-css-file": "Özel CSS dosyanı içeri aktar",
|
||||||
"no-theme": "Tema Yok"
|
"no-theme": "Tema Yok"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -100,31 +169,54 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"plugins": {
|
"plugins": {
|
||||||
"label": "Eklentiler"
|
"enabled": "Aktif",
|
||||||
|
"label": "Eklentiler",
|
||||||
|
"new": "YENİ"
|
||||||
},
|
},
|
||||||
"view": {
|
"view": {
|
||||||
"label": "Görüntü"
|
"label": "Görüntü",
|
||||||
|
"submenu": {
|
||||||
|
"force-reload": "Zorla yeniden başlat",
|
||||||
|
"reload": "Yeniden Başlat",
|
||||||
|
"reset-zoom": "Asıl Boyut",
|
||||||
|
"toggle-fullscreen": "Tam Ekran'a Geçiş",
|
||||||
|
"zoom-in": "Yakınlaştır",
|
||||||
|
"zoom-out": "Uzaklaştır"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"tray": {
|
||||||
|
"next": "Sonraki",
|
||||||
|
"play-pause": "Oynat/Durdur",
|
||||||
|
"previous": "Önceki",
|
||||||
|
"quit": "Çıkış",
|
||||||
|
"restart": "Yeniden başlat",
|
||||||
|
"show": "Pencereyi görüntüle"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"plugins": {
|
"plugins": {
|
||||||
"adblocker": {
|
"adblocker": {
|
||||||
"description": "Tüm reklamları ve izleyicileri engelle",
|
"description": "Tüm reklamları ve izleyicileri engelle",
|
||||||
"menu": {
|
"menu": {
|
||||||
"blocker": "Engelleme Yöntemi"
|
"blocker": "Engelleyici"
|
||||||
},
|
},
|
||||||
"name": "Adblocker"
|
"name": "Reklam Engelleyici"
|
||||||
|
},
|
||||||
|
"album-actions": {
|
||||||
|
"description": "Çalma listesindeki veya albümdeki tüm şarkılara Beğendim ve Beğenmedim düğmeleri ekler.",
|
||||||
|
"name": "Albüm Eylemleri"
|
||||||
},
|
},
|
||||||
"album-color-theme": {
|
"album-color-theme": {
|
||||||
"description": "Albümün renk paletine dayalı dinamik bir tema ve efektler uygular.",
|
"description": "Albümün renk paletine dayalı dinamik bir tema ve efektler uygular",
|
||||||
"name": "Albüm Renk Teması"
|
"name": "Albüm Renk Teması"
|
||||||
},
|
},
|
||||||
"ambient-mode": {
|
"ambient-mode": {
|
||||||
"description": "Videodaki yumuşak renkleri ekranınızın arka planına yansıtarak bir ışık efekti uygular..",
|
"description": "Videodaki yumuşak renkleri ekranınızın arka planına yansıtarak bir ışık efekti uygular..",
|
||||||
"menu": {
|
"menu": {
|
||||||
"blur-amount": {
|
"blur-amount": {
|
||||||
|
"label": "Bulanıklık miktarı",
|
||||||
"submenu": {
|
"submenu": {
|
||||||
"pixels": "{{blurAmount}} pixels"
|
"pixels": "{{blurAmount}} piksel"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"buffer": {
|
"buffer": {
|
||||||
@ -140,53 +232,82 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"quality": {
|
"quality": {
|
||||||
|
"label": "Kalite",
|
||||||
"submenu": {
|
"submenu": {
|
||||||
"pixels": "{{quality}} pixels"
|
"pixels": "{{quality}} piksel"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"size": {
|
"size": {
|
||||||
|
"label": "Boyut",
|
||||||
"submenu": {
|
"submenu": {
|
||||||
"percent": "{{size}}%"
|
"percent": "{{size}}%"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"smoothness-transition": {
|
"smoothness-transition": {
|
||||||
|
"label": "Yumuşak Geçiş",
|
||||||
"submenu": {
|
"submenu": {
|
||||||
"during": "{{interpolationTime}} saniye içinde"
|
"during": "{{interpolationTime}} saniye boyunca"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"use-fullscreen": {
|
||||||
|
"label": "Tam ekran kullanılıyor"
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"name": "Ambiyans Modu"
|
||||||
},
|
},
|
||||||
"audio-compressor": {
|
"audio-compressor": {
|
||||||
"description": "Ses sıkıştırma (dalganın en gürültülü bölümlerinin ses düzeyini azaltır ve daha yumuşak bölümlerin ses düzeyini artırır)"
|
"description": "Ses sıkıştırma (dalganın en gürültülü bölümlerinin ses düzeyini azaltır ve daha yumuşak bölümlerin ses düzeyini artırır)",
|
||||||
|
"name": "Ses Sıkıştırma"
|
||||||
},
|
},
|
||||||
"blur-nav-bar": {
|
"blur-nav-bar": {
|
||||||
"description": "Gezinme çubuğunu şeffaf ve bulanık yapar"
|
"description": "Gezinme çubuğunu şeffaf ve bulanık yapar",
|
||||||
|
"name": "Navigasyon barını bulanıklaştır"
|
||||||
},
|
},
|
||||||
"bypass-age-restrictions": {
|
"bypass-age-restrictions": {
|
||||||
"description": "YouTube yaş doğrulamasını atla"
|
"description": "YouTube yaş doğrulamasını atla",
|
||||||
|
"name": "Yaş doğrulamasını atla"
|
||||||
},
|
},
|
||||||
"captions-selector": {
|
"captions-selector": {
|
||||||
|
"description": "YouTube Music için altyazı seçici",
|
||||||
|
"menu": {
|
||||||
|
"autoload": "Son kullanılan altyazıyı otomatik olarak seç",
|
||||||
|
"disable-captions": "Varsayılan olarak altyazı yok"
|
||||||
|
},
|
||||||
|
"name": "Altyazı Seçici",
|
||||||
"prompt": {
|
"prompt": {
|
||||||
"selector": {
|
"selector": {
|
||||||
"none": "Hiçbiri"
|
"label": "Geçerli altyazı dili: {{language}}",
|
||||||
|
"none": "Hiçbiri",
|
||||||
|
"title": "Altyazı dilini seç"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"templates": {
|
||||||
|
"title": "Altyazı seçiciyi aç"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"compact-sidebar": {
|
"compact-sidebar": {
|
||||||
"description": "Her zaman kompakt kenar çubugu"
|
"description": "Her zaman kompakt kenar çubugu",
|
||||||
|
"name": "Kompakt Kenar Çubuğu"
|
||||||
},
|
},
|
||||||
"crossfade": {
|
"crossfade": {
|
||||||
|
"description": "Şarkılar arasında Çapraz Geçiş",
|
||||||
"menu": {
|
"menu": {
|
||||||
"advanced": "İleri düzey için"
|
"advanced": "Gelişmiş"
|
||||||
},
|
},
|
||||||
|
"name": "Çapraz Geçiş [Beta]",
|
||||||
"prompt": {
|
"prompt": {
|
||||||
"options": {
|
"options": {
|
||||||
"multi-input": {
|
"multi-input": {
|
||||||
|
"fade-in-duration": "Güçlenme süresi (ms)",
|
||||||
|
"fade-out-duration": "Zayıflama süresi (ms)",
|
||||||
"fade-scaling": {
|
"fade-scaling": {
|
||||||
|
"label": "Zayıflama Ölçeği",
|
||||||
"linear": "Doğrusal",
|
"linear": "Doğrusal",
|
||||||
"logarithmic": "Logaritmik"
|
"logarithmic": "Logaritmik"
|
||||||
}
|
},
|
||||||
}
|
"seconds-before-end": "Bitişten N saniye önce çapraz geçiş"
|
||||||
|
},
|
||||||
|
"title": "Çapraz Geçiş ayarları"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -194,14 +315,33 @@
|
|||||||
"description": "Şarkıların otomatik olarak duraklatılmasını sağlar",
|
"description": "Şarkıların otomatik olarak duraklatılmasını sağlar",
|
||||||
"menu": {
|
"menu": {
|
||||||
"apply-once": "Yalnızca ilk şarkı için geçerlidir"
|
"apply-once": "Yalnızca ilk şarkı için geçerlidir"
|
||||||
}
|
},
|
||||||
|
"name": "Otomatik oynatmayı devre dışı bırak"
|
||||||
},
|
},
|
||||||
"discord": {
|
"discord": {
|
||||||
"description": "Rich Presence ile Discord'da ne dinlediğinizi gösterin.",
|
"backend": {
|
||||||
|
"already-connected": "Aktif bağlantı olduğu halde bağlantı kurulmaya çalışıldı",
|
||||||
|
"connected": "Discord'a bağlandı",
|
||||||
|
"disconnected": "Discord ile bağlantı kesildi"
|
||||||
|
},
|
||||||
|
"description": "Rich Presence ile Discord'da ne dinlediğinizi gösterin",
|
||||||
"menu": {
|
"menu": {
|
||||||
|
"auto-reconnect": "Otomatik yeniden bağlan",
|
||||||
|
"clear-activity": "Etkinliği temizle",
|
||||||
|
"clear-activity-after-timeout": "Zaman aşımından sonra etkinliği temizle",
|
||||||
|
"connected": "Bağlı",
|
||||||
|
"disconnected": "Bağlantı kesildi",
|
||||||
"hide-duration-left": "Kalan süreyi gizle",
|
"hide-duration-left": "Kalan süreyi gizle",
|
||||||
"hide-github-button": "GitHub bağlantısını gizle",
|
"hide-github-button": "GitHub bağlantısını gizle",
|
||||||
|
"play-on-youtube-music": "YouTube Music de oynat",
|
||||||
"set-inactivity-timeout": "Hareketsizlik zaman aşımını ayarla"
|
"set-inactivity-timeout": "Hareketsizlik zaman aşımını ayarla"
|
||||||
|
},
|
||||||
|
"name": "Discord Rich Presence",
|
||||||
|
"prompt": {
|
||||||
|
"set-inactivity-timeout": {
|
||||||
|
"label": "Hareketsizlik zaman aşımını saniye cinsinden girin:",
|
||||||
|
"title": "Hareketsizlik zaman aşımını ayarla"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"downloader": {
|
"downloader": {
|
||||||
@ -211,71 +351,298 @@
|
|||||||
"buttons": {
|
"buttons": {
|
||||||
"ok": "Tamam"
|
"ok": "Tamam"
|
||||||
},
|
},
|
||||||
"title": "İndirmede hata meydana geldi!"
|
"message": "Argh! Özür dilerim, indirme başarısız oldu…",
|
||||||
|
"title": "İndirme sırasında bir hata meydana geldi!"
|
||||||
},
|
},
|
||||||
"start-download-playlist": {
|
"start-download-playlist": {
|
||||||
"buttons": {
|
"buttons": {
|
||||||
"ok": "Tamam"
|
"ok": "Tamam"
|
||||||
},
|
},
|
||||||
"message": "Çalma listesini indir : {{playlistTitle}}",
|
"detail": "({{playlistSize}} şarkı)",
|
||||||
|
"message": "Oynatma listesini indir : {{playlistTitle}}",
|
||||||
"title": "İndirme Başladı"
|
"title": "İndirme Başladı"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"feedback": {
|
"feedback": {
|
||||||
"conversion-progress": "Dönüştürme : {{percent}}%",
|
"conversion-progress": "Dönüştürme : {{percent}}%",
|
||||||
|
"converting": "Dönüştürülüyor…",
|
||||||
|
"done": "Tamamlandı: {{filePath}}",
|
||||||
|
"download-info": "{{artist}} - {{title}} [{{videoId}} indiriliyor",
|
||||||
"download-progress": "İndirme : {{percent}}%",
|
"download-progress": "İndirme : {{percent}}%",
|
||||||
"preparing-file": "Dosya Hazırlanıyor…"
|
"downloading": "İndiriliyor…",
|
||||||
|
"downloading-counter": "İndiriliyor {{current}}/{{total}}…",
|
||||||
|
"downloading-playlist": "\"{{playlistTitle}}\" şarkı listesi indiriliyor - {{playlistSize}} şarkı ({{playlistId}})",
|
||||||
|
"error-while-downloading": "\"{{author}} - {{title}}\" indirilirken hata oluştu: {{error}}",
|
||||||
|
"folder-already-exists": "{{playlistFolder}} klasörü zaten mevcut",
|
||||||
|
"getting-playlist-info": "Oynatma listesi bilgisi alınıyor…",
|
||||||
|
"loading": "Yükleniyor…",
|
||||||
|
"playlist-has-only-one-song": "Oynatma listesinde yalnızca bir şarkı var, doğrudan indiriliyor",
|
||||||
|
"playlist-id-not-found": "Oynatma listesi ID'si bulunamadı",
|
||||||
|
"playlist-is-empty": "Oynatma listesi boş",
|
||||||
|
"playlist-is-mix-or-private": "Çalma listesi bilgisi alınırken hata oluştu: özel veya \"Size özel karışık\" bir çalma listesi olmadığından emin olun\n\n{{error}}",
|
||||||
|
"preparing-file": "Dosya Hazırlanıyor…",
|
||||||
|
"saving": "Kaydediliyor…",
|
||||||
|
"trying-to-get-playlist-id": "Çalma listesi ID'si alınmaya çalışılıyor: {{playlistId}}",
|
||||||
|
"video-id-not-found": "Video bulunamadı",
|
||||||
|
"writing-id3": "ID3 etiketleri yazılıyor…"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"description": "MP3 / kaynak sesini doğrudan arayüzden indir",
|
||||||
|
"menu": {
|
||||||
|
"choose-download-folder": "İndirme klasörünü seç",
|
||||||
|
"download-playlist": "Oynatma listesini indir",
|
||||||
|
"presets": "Hazır Ayarlar",
|
||||||
|
"skip-existing": "Mevcut dosyaları atla"
|
||||||
|
},
|
||||||
|
"name": "İndirici",
|
||||||
|
"renderer": {
|
||||||
|
"can-not-update-progress": "İlerleme güncellenemiyor"
|
||||||
|
},
|
||||||
"templates": {
|
"templates": {
|
||||||
"button": "İndir"
|
"button": "İndir"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"exponential-volume": {
|
||||||
|
"description": "Ses seviyesi kaydırıcısını üstel hale getirir, böylece daha düşük ses seviyelerini seçmek daha kolay olur.",
|
||||||
|
"name": "Üstel Ses Seviyesi"
|
||||||
|
},
|
||||||
|
"in-app-menu": {
|
||||||
|
"description": "Menü çubuklarına süslü, koyu veya albüm renginde bir görünüm verir",
|
||||||
|
"menu": {
|
||||||
|
"hide-dom-window-controls": "DOM penceresi kontrollerini gizle"
|
||||||
|
},
|
||||||
|
"name": "Uygulama İçi Menü"
|
||||||
|
},
|
||||||
"last-fm": {
|
"last-fm": {
|
||||||
|
"description": "Last.fm için scrobbling desteği ekler",
|
||||||
"name": "Last.fm"
|
"name": "Last.fm"
|
||||||
},
|
},
|
||||||
|
"lumiastream": {
|
||||||
|
"description": "Lumia Stream desteği ekler",
|
||||||
|
"name": "Lumia Stream [Beta]"
|
||||||
|
},
|
||||||
|
"lyrics-genius": {
|
||||||
|
"description": "Çoğu şarkı için şarkı sözü desteği ekler",
|
||||||
|
"menu": {
|
||||||
|
"romanized-lyrics": "Romanlaştırılmış Şarkı Sözleri"
|
||||||
|
},
|
||||||
|
"name": "Genius Şarkı Sözleri",
|
||||||
|
"renderer": {
|
||||||
|
"fetched-lyrics": "Şarkı sözleri genius tarafından alındı"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"music-together": {
|
||||||
|
"description": "Oynatma listesini başkalarıyla paylaşın. Sunucu sahibi bir şarkı çaldığında, diğer herkes aynı şarkıyı duyacak",
|
||||||
|
"dialog": {
|
||||||
|
"enter-host": "Sunucu ID'si Girin"
|
||||||
|
},
|
||||||
|
"internal": {
|
||||||
|
"save": "Kaydet",
|
||||||
|
"track-source": "Parça Kaynağı",
|
||||||
|
"unknown-user": "Bilinmeyen Kullanıcı"
|
||||||
|
},
|
||||||
|
"menu": {
|
||||||
|
"click-to-copy-id": "Sunucu ID'sini kopyala",
|
||||||
|
"close": "Birlikte Müziği Kapat",
|
||||||
|
"connected-users": "Bağlanan Kullanıcılar",
|
||||||
|
"disconnect": "Birlikte Müzik Bağlantısını Kesin",
|
||||||
|
"empty-user": "Bağlı kullanıcı bulunmuyor",
|
||||||
|
"host": "Birlikte Müzik Sunucusu",
|
||||||
|
"join": "Birlikte Müziğe Katıl",
|
||||||
|
"permission": {
|
||||||
|
"all": "Konukların oynatma listesini ve oynatıcıyı kontrol etmesine izin verin",
|
||||||
|
"host-only": "Çalma listesini ve oynatıcıyı yalnızca yönetici kontrol edebilir",
|
||||||
|
"playlist": "Konukların oynatma listesini kontrol etmesine izin ver"
|
||||||
|
},
|
||||||
|
"set-permission": "Kontrol İznini Değiştir",
|
||||||
|
"status": {
|
||||||
|
"disconnected": "Bağlantı kesildi",
|
||||||
|
"guest": "Misafir olarak bağlandı",
|
||||||
|
"host": "Ev Sahibi olarak bağlandı"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": "Birlikte Müzik [Beta]",
|
||||||
|
"toast": {
|
||||||
|
"add-song-failed": "Şarkı eklenirken bir hata meydana geldi",
|
||||||
|
"closed": "Birlikte Müzik kapatıldı",
|
||||||
|
"disconnected": "Birlikte Müzik bağlantı kesildi",
|
||||||
|
"host-failed": "Birlikte Müzik sunucusu kurulamadı",
|
||||||
|
"id-copied": "Sunucu ID'si kopyalandı",
|
||||||
|
"join-failed": "Birlikte Müziğe katılırken bir hata meydana geldi",
|
||||||
|
"joined": "Birlikte Müziğe Katıldı",
|
||||||
|
"permission-changed": "Birlikte Müzik yetkisi \"{{permission}}\" olarak değiştirildi",
|
||||||
|
"remove-song-failed": "Şarkı kaldırılırken bir hata meydana geldi",
|
||||||
|
"user-connected": "{{name}} Birlikte Müziğe Katıldı",
|
||||||
|
"user-disconnected": "{{name}} Birlikte Müzik'ten ayrıldı"
|
||||||
|
}
|
||||||
|
},
|
||||||
"navigation": {
|
"navigation": {
|
||||||
|
"description": "Favori tarayıcınızdaki gibi doğrudan arayüze entegre edilmiş İleri/Geri gezinme okları",
|
||||||
"name": "Navigasyon"
|
"name": "Navigasyon"
|
||||||
},
|
},
|
||||||
"no-google-login": {
|
"no-google-login": {
|
||||||
|
"description": "Google giriş düğmelerini ve bağlantılarını arayüzden kaldır",
|
||||||
"name": "Google Girişini Kaldır"
|
"name": "Google Girişini Kaldır"
|
||||||
},
|
},
|
||||||
"notifications": {
|
"notifications": {
|
||||||
|
"description": "Bir şarkı çalmaya başladığında bir bildirim görüntüler (etkileşimli bildirimler Windows'ta mevcuttur)",
|
||||||
|
"menu": {
|
||||||
|
"interactive": "İnteraktif Bildirimler",
|
||||||
|
"interactive-settings": {
|
||||||
|
"label": "İnteraktif Ayarlar",
|
||||||
|
"submenu": {
|
||||||
|
"hide-button-text": "Buton metnini gizle",
|
||||||
|
"refresh-on-play-pause": "Oynat/Duraklat'ta Yenile",
|
||||||
|
"tray-controls": "Tepsi tıklamasıyla Aç/Kapat"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"priority": "Bildirim Önceliği",
|
||||||
|
"toast-style": "Bildirim Tarzı",
|
||||||
|
"unpause-notification": "Şarkı tekrar oynatılınca bildirim göster"
|
||||||
|
},
|
||||||
"name": "Bildirimler"
|
"name": "Bildirimler"
|
||||||
},
|
},
|
||||||
"shortcuts": {
|
"picture-in-picture": {
|
||||||
"prompt": {
|
"description": "Uygulamayı resim-içinde-resim moduna geçirmeye izin verir",
|
||||||
"keybind": {
|
"menu": {
|
||||||
"keybind-options": {
|
"always-on-top": "Her zaman üstte",
|
||||||
"next": "İler"
|
"hotkey": {
|
||||||
|
"label": "Kısayol",
|
||||||
|
"prompt": {
|
||||||
|
"keybind-options": {
|
||||||
|
"hotkey": "Kısayol"
|
||||||
|
},
|
||||||
|
"label": "Resim-içinde-resim arasında geçiş yapmak için bir kısayol tuşu seçin",
|
||||||
|
"title": "Resim-içinde-resim Kısayol Tuşu"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"save-window-position": "Pencere konumunu kaydet",
|
||||||
|
"save-window-size": "Pencere boyutunu kaydet",
|
||||||
|
"use-native-pip": "Tarayıcı yerel PiP'sini kullan"
|
||||||
|
},
|
||||||
|
"name": "Resim-içinde-resim",
|
||||||
|
"templates": {
|
||||||
|
"button": "Resim-içinde-resim"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"playback-speed": {
|
||||||
|
"description": "Hızlı dinle, yavaş dinle! Şarkı hızını kontrol eden bir kaydırıcı ekler",
|
||||||
|
"name": "Oynatma Hızı",
|
||||||
|
"templates": {
|
||||||
|
"button": "Hız"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"precise-volume": {
|
||||||
|
"description": "Özel bir HUD ve özelleştirilebilir ses seviyesi adımları ile fare tekerleği / kısayol tuşlarını kullanarak ses seviyesini hassas bir şekilde kontrol edin",
|
||||||
|
"menu": {
|
||||||
|
"arrows-shortcuts": "Yerel Ok Tuşu Kontrolleri",
|
||||||
|
"custom-volume-steps": "Özel Ses Seviyesi Adımlarını Ayarlama",
|
||||||
|
"global-shortcuts": "Genel Kısayol Tuşları"
|
||||||
|
},
|
||||||
|
"name": "Hassas Ses Seviyesi",
|
||||||
|
"prompt": {
|
||||||
|
"global-shortcuts": {
|
||||||
|
"keybind-options": {
|
||||||
|
"decrease": "Ses Seviyesi Azaltma",
|
||||||
|
"increase": "Ses Seviyesi Yükseltme"
|
||||||
|
},
|
||||||
|
"label": "Genel Ses Tuş Atamalarını seçin:",
|
||||||
|
"title": "Genel Ses Tuş Atamaları"
|
||||||
|
},
|
||||||
|
"volume-steps": {
|
||||||
|
"label": "Ses Artırma/Azaltma Kademelerini Seçin",
|
||||||
|
"title": "Ses Kademeleri"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"quality-changer": {
|
||||||
|
"backend": {
|
||||||
|
"dialog": {
|
||||||
|
"quality-changer": {
|
||||||
|
"detail": "Mevcut Kalite: {{quality}}",
|
||||||
|
"message": "Video Kalitesini Seçin:",
|
||||||
|
"title": "Video Kalitesini Seçin"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"description": "Video katmanı üzerindeki bir düğme ile video kalitesinin değiştirilmesine izin verir",
|
||||||
|
"name": "Video Kalitesi Değiştirici"
|
||||||
|
},
|
||||||
|
"shortcuts": {
|
||||||
|
"description": "Oynatma için global kısayol tuşları (oynat/duraklat/sonraki/önceki) ayarlamaya ve medya tuşlarını geçersiz kılarak medya OSD'sini kapatmaya, arama yapmak için Ctrl/CMD + F tuşlarını açmaya, medya tuşları için Linux MPRIS desteğini açmaya ve ileri düzey kullanıcılar için özel kısayol tuşlarına izin verir.",
|
||||||
|
"menu": {
|
||||||
|
"override-media-keys": "Medya Tuşlarını Geçersiz Kıl",
|
||||||
|
"set-keybinds": "Global Şarkı Kontrollerini Ayarla"
|
||||||
|
},
|
||||||
|
"name": "Kısayollar (& MPRIS)",
|
||||||
|
"prompt": {
|
||||||
|
"keybind": {
|
||||||
|
"keybind-options": {
|
||||||
|
"next": "İler",
|
||||||
|
"play-pause": "Oynat / Durdur",
|
||||||
|
"previous": "Önceki"
|
||||||
|
},
|
||||||
|
"label": "Şarkı Kontrolü için Genel Tuş Atamaları'nı seçin:",
|
||||||
|
"title": "Genel Tuş Atamaları"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"skip-disliked-songs": {
|
||||||
|
"description": "Beğenmediğin şarkıları atlar",
|
||||||
|
"name": "Beğenmediklerini Atla"
|
||||||
|
},
|
||||||
|
"skip-silences": {
|
||||||
|
"description": "Şarkılardaki sessiz bölümleri otomatik olarak atlar",
|
||||||
|
"name": "Sessizlikleri Atla"
|
||||||
|
},
|
||||||
"sponsorblock": {
|
"sponsorblock": {
|
||||||
|
"description": "Giriş/Çıkış gibi müzik olmayan kısımları veya müzik videolarında şarkının çalmadığı kısımları otomatik olarak atlar",
|
||||||
"name": "SponsorBlock"
|
"name": "SponsorBlock"
|
||||||
},
|
},
|
||||||
|
"taskbar-mediacontrol": {
|
||||||
|
"description": "Windows görev çubuğu üzerinden oynatmayı kontrol edebilmenize olanak sağlar",
|
||||||
|
"name": "Görev Çubuğu Medya Kontrolü"
|
||||||
|
},
|
||||||
"touchbar": {
|
"touchbar": {
|
||||||
|
"description": "macOS kullanıcıları için bir TouchBar widget'ı ekler",
|
||||||
"name": "TouchBar"
|
"name": "TouchBar"
|
||||||
},
|
},
|
||||||
"tuna-obs": {
|
"tuna-obs": {
|
||||||
|
"description": "OBS eklentisi Tuna ile entegrasyon sağlar",
|
||||||
"name": "Tuna OBS"
|
"name": "Tuna OBS"
|
||||||
},
|
},
|
||||||
"video-toggle": {
|
"video-toggle": {
|
||||||
|
"description": "Video/Şarkı modu arasında geçiş yapmak için bir düğme ekler. ayrıca isteğe bağlı olarak tüm video sekmesini kaldırabilir",
|
||||||
"menu": {
|
"menu": {
|
||||||
"align": {
|
"align": {
|
||||||
|
"label": "Hizalama",
|
||||||
"submenu": {
|
"submenu": {
|
||||||
|
"left": "Sol",
|
||||||
"middle": "Orta",
|
"middle": "Orta",
|
||||||
"right": "Sağ"
|
"right": "Sağ"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"force-hide": "Video sekmesini kaldırmaya zorla",
|
||||||
"mode": {
|
"mode": {
|
||||||
"label": "Mod"
|
"label": "Mod",
|
||||||
|
"submenu": {
|
||||||
|
"custom": "Özel Ayar",
|
||||||
|
"disabled": "Devre dışı",
|
||||||
|
"native": "Yerel geçiş"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"name": "Video Geçiş",
|
||||||
"templates": {
|
"templates": {
|
||||||
"button": "Şarkı"
|
"button": "Şarkı"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"visualizer": {
|
||||||
|
"description": "Oynatıcıya bir görselleştirici ekler",
|
||||||
|
"menu": {
|
||||||
|
"visualizer-type": "Görselleştirici Tipi"
|
||||||
|
},
|
||||||
|
"name": "Görselleştirici"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
21
src/i18n/resources/vi.json
Normal file
21
src/i18n/resources/vi.json
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"common": {
|
||||||
|
"console": {
|
||||||
|
"plugins": {
|
||||||
|
"execute-failed": "Lỗi khi bắt đầu phần mở rộng {{pluginName}}::{{contextName}}",
|
||||||
|
"executed-at-ms": "Phần mở rộng {{pluginName}}::{{contextName}} đã bắt đầu trong {{ms}}ms",
|
||||||
|
"initialize-failed": "Lỗi khi khởi động phần mở rộng \"{{pluginName}}\"",
|
||||||
|
"load-all": "Đang tải tất cả phần mở rộng",
|
||||||
|
"load-failed": "Lỗi khi tải phần mở rộng\"{{pluginName}}\"",
|
||||||
|
"loaded": "Đã tải phần mở rộng \"{{pluginName}}\"",
|
||||||
|
"unload-failed": "Lỗi khi hủy tải phần mở rộng \"{{pluginName}}\"",
|
||||||
|
"unloaded": "Đã hủy tải phần mở rộng \"{{pluginName}}\""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"language": {
|
||||||
|
"code": "vi",
|
||||||
|
"local-name": "Tiếng Việt",
|
||||||
|
"name": "Vietnamese"
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -170,7 +170,8 @@
|
|||||||
},
|
},
|
||||||
"plugins": {
|
"plugins": {
|
||||||
"enabled": "已启用",
|
"enabled": "已启用",
|
||||||
"label": "插件"
|
"label": "插件",
|
||||||
|
"new": "新建"
|
||||||
},
|
},
|
||||||
"view": {
|
"view": {
|
||||||
"label": "视图",
|
"label": "视图",
|
||||||
@ -201,6 +202,10 @@
|
|||||||
},
|
},
|
||||||
"name": "广告屏蔽器"
|
"name": "广告屏蔽器"
|
||||||
},
|
},
|
||||||
|
"album-actions": {
|
||||||
|
"description": "添加作用于播放列表或专辑中所有歌曲的全局“点赞/取消点赞”与“喜欢/取消喜欢”按钮。",
|
||||||
|
"name": "专辑操作"
|
||||||
|
},
|
||||||
"album-color-theme": {
|
"album-color-theme": {
|
||||||
"description": "根据专辑封面配色动态改变主题与视觉效果",
|
"description": "根据专辑封面配色动态改变主题与视觉效果",
|
||||||
"name": "专辑配色主题"
|
"name": "专辑配色主题"
|
||||||
@ -289,7 +294,7 @@
|
|||||||
"menu": {
|
"menu": {
|
||||||
"advanced": "高级"
|
"advanced": "高级"
|
||||||
},
|
},
|
||||||
"name": "交叉淡化 [beta]",
|
"name": "交叉淡化 [Beta]",
|
||||||
"prompt": {
|
"prompt": {
|
||||||
"options": {
|
"options": {
|
||||||
"multi-input": {
|
"multi-input": {
|
||||||
@ -426,6 +431,51 @@
|
|||||||
"fetched-lyrics": "已从 Genius 获取字幕"
|
"fetched-lyrics": "已从 Genius 获取字幕"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"music-together": {
|
||||||
|
"description": "与他人共享播放列表。当发起人播放歌曲时,其他人也会听到相同歌曲",
|
||||||
|
"dialog": {
|
||||||
|
"enter-host": "输入发起人 ID"
|
||||||
|
},
|
||||||
|
"internal": {
|
||||||
|
"save": "保存",
|
||||||
|
"track-source": "追踪来源",
|
||||||
|
"unknown-user": "未知用户"
|
||||||
|
},
|
||||||
|
"menu": {
|
||||||
|
"click-to-copy-id": "复制发起者 ID",
|
||||||
|
"close": "关闭 Music Together",
|
||||||
|
"connected-users": "已连接用户",
|
||||||
|
"disconnect": "断开 Music Together 连接",
|
||||||
|
"empty-user": "没有已连接的用户",
|
||||||
|
"host": "Music Together 发起者",
|
||||||
|
"join": "加入 Music Together",
|
||||||
|
"permission": {
|
||||||
|
"all": "允许来宾控制播放列表与播放器",
|
||||||
|
"host-only": "仅发起人可以控制播放列表与播放器",
|
||||||
|
"playlist": "允许来宾控制播放列表"
|
||||||
|
},
|
||||||
|
"set-permission": "更改控制权限",
|
||||||
|
"status": {
|
||||||
|
"disconnected": "已断开连接",
|
||||||
|
"guest": "已作为来宾连接",
|
||||||
|
"host": "已作为发起人连接"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": "Music Together [测试]",
|
||||||
|
"toast": {
|
||||||
|
"add-song-failed": "添加歌曲失败",
|
||||||
|
"closed": "Music Together 已关闭",
|
||||||
|
"disconnected": "Music Together 已断开连接",
|
||||||
|
"host-failed": "发起 Music Together 失败",
|
||||||
|
"id-copied": "已将发起者 ID 复制到剪切板",
|
||||||
|
"join-failed": "加入 Music Together 失败",
|
||||||
|
"joined": "已加入 Music Together",
|
||||||
|
"permission-changed": "Music Together 权限已改为 \"{{permission}}\"",
|
||||||
|
"remove-song-failed": "移除歌曲失败",
|
||||||
|
"user-connected": "{{name}} 加入了 Music Together",
|
||||||
|
"user-disconnected": "{{name}} 离开了 Music Together"
|
||||||
|
}
|
||||||
|
},
|
||||||
"navigation": {
|
"navigation": {
|
||||||
"description": "如同浏览器般,在应用界面内直接显示前进/后退导航按钮",
|
"description": "如同浏览器般,在应用界面内直接显示前进/后退导航按钮",
|
||||||
"name": "导航"
|
"name": "导航"
|
||||||
|
|||||||
@ -687,13 +687,15 @@ app.whenReady().then(async () => {
|
|||||||
const dialogOptions: Electron.MessageBoxOptions = {
|
const dialogOptions: Electron.MessageBoxOptions = {
|
||||||
type: 'info',
|
type: 'info',
|
||||||
buttons: [
|
buttons: [
|
||||||
t('main.dialog.update-available.buttons.download'),
|
|
||||||
t('main.dialog.update-available.buttons.ok'),
|
t('main.dialog.update-available.buttons.ok'),
|
||||||
|
t('main.dialog.update-available.buttons.download'),
|
||||||
t('main.dialog.update-available.buttons.disable'),
|
t('main.dialog.update-available.buttons.disable'),
|
||||||
],
|
],
|
||||||
title: t('main.dialog.update-available.title'),
|
title: t('main.dialog.update-available.title'),
|
||||||
message: t('main.dialog.update-available.message'),
|
message: t('main.dialog.update-available.message'),
|
||||||
detail: t('main.dialog.update-available.detail', { downloadLink }),
|
detail: t('main.dialog.update-available.detail', { downloadLink }),
|
||||||
|
defaultId: 1,
|
||||||
|
cancelId: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
let dialogPromise: Promise<Electron.MessageBoxReturnValue>;
|
let dialogPromise: Promise<Electron.MessageBoxReturnValue>;
|
||||||
@ -717,7 +719,7 @@ app.whenReady().then(async () => {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default: {
|
case 0: {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,7 +11,7 @@ export default createPlugin({
|
|||||||
name: () => t('plugins.album-actions.name'),
|
name: () => t('plugins.album-actions.name'),
|
||||||
description: () => t('plugins.album-actions.description'),
|
description: () => t('plugins.album-actions.description'),
|
||||||
restartNeeded: false,
|
restartNeeded: false,
|
||||||
addedVersion: '3.2.0',
|
addedVersion: '3.2.X',
|
||||||
config: {
|
config: {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -22,8 +22,7 @@ title-bar {
|
|||||||
|
|
||||||
color: #f1f1f1;
|
color: #f1f1f1;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
padding: 4px 12px;
|
padding: 4px 12px 4px var(--offset-left, 12px);
|
||||||
padding-left: var(--offset-left, 12px);
|
|
||||||
background-color: var(--titlebar-background-color, #030303);
|
background-color: var(--titlebar-background-color, #030303);
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
|
||||||
@ -233,10 +232,7 @@ ytmusic-app-layout > [slot='nav-bar'],
|
|||||||
var(--ytmusic-nav-bar-height) + var(--menu-bar-height, 36px)
|
var(--ytmusic-nav-bar-height) + var(--menu-bar-height, 36px)
|
||||||
) !important;
|
) !important;
|
||||||
}
|
}
|
||||||
ytmusic-app[is-bauhaus-sidenav-enabled] #guide-spacer.ytmusic-app {
|
ytmusic-app[is-bauhaus-sidenav-enabled] #guide-spacer.ytmusic-app,
|
||||||
margin-top: calc(var(--menu-bar-height, 36px)) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
ytmusic-app[is-bauhaus-sidenav-enabled] #mini-guide-spacer.ytmusic-app {
|
ytmusic-app[is-bauhaus-sidenav-enabled] #mini-guide-spacer.ytmusic-app {
|
||||||
margin-top: calc(
|
margin-top: calc(
|
||||||
var(--ytmusic-nav-bar-height) + var(--menu-bar-height, 36px)
|
var(--ytmusic-nav-bar-height) + var(--menu-bar-height, 36px)
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
import prompt from 'custom-electron-prompt';
|
import prompt from 'custom-electron-prompt';
|
||||||
|
|
||||||
|
import { DataConnection } from 'peerjs';
|
||||||
|
|
||||||
import { t } from '@/i18n';
|
import { t } from '@/i18n';
|
||||||
import { createPlugin } from '@/utils';
|
import { createPlugin } from '@/utils';
|
||||||
import promptOptions from '@/providers/prompt-options';
|
import promptOptions from '@/providers/prompt-options';
|
||||||
@ -17,7 +19,6 @@ import style from './style.css?inline';
|
|||||||
import type { YoutubePlayer } from '@/types/youtube-player';
|
import type { YoutubePlayer } from '@/types/youtube-player';
|
||||||
import type { RendererContext } from '@/types/contexts';
|
import type { RendererContext } from '@/types/contexts';
|
||||||
import type { VideoDataChanged } from '@/types/video-data-changed';
|
import type { VideoDataChanged } from '@/types/video-data-changed';
|
||||||
import { DataConnection } from 'peerjs';
|
|
||||||
|
|
||||||
type RawAccountData = {
|
type RawAccountData = {
|
||||||
accountName: {
|
accountName: {
|
||||||
@ -34,59 +35,84 @@ type RawAccountData = {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export default createPlugin({
|
export default createPlugin<
|
||||||
|
unknown,
|
||||||
|
unknown,
|
||||||
|
{
|
||||||
|
connection?: Connection;
|
||||||
|
ipc?: RendererContext<never>['ipc'];
|
||||||
|
api: HTMLElement & AppAPI | null;
|
||||||
|
queue?: Queue;
|
||||||
|
playerApi?: YoutubePlayer;
|
||||||
|
showPrompt: (title: string, label: string) => Promise<string>;
|
||||||
|
popups: {
|
||||||
|
host: ReturnType<typeof createHostPopup>;
|
||||||
|
guest: ReturnType<typeof createGuestPopup>;
|
||||||
|
setting: ReturnType<typeof createSettingPopup>;
|
||||||
|
};
|
||||||
|
elements: {
|
||||||
|
setting: HTMLElement;
|
||||||
|
icon: SVGElement;
|
||||||
|
spinner: HTMLElement;
|
||||||
|
};
|
||||||
|
stateInterval?: number;
|
||||||
|
updateNext: boolean;
|
||||||
|
ignoreChange: boolean;
|
||||||
|
rollbackInjector?: (() => void);
|
||||||
|
me?: Omit<Profile, 'id'>;
|
||||||
|
profiles: Record<string, Profile>;
|
||||||
|
permission: Permission;
|
||||||
|
videoChangeListener: (event: CustomEvent<VideoDataChanged>) => void;
|
||||||
|
videoStateChangeListener: () => void;
|
||||||
|
onHost: () => Promise<boolean>;
|
||||||
|
onJoin: () => Promise<boolean>;
|
||||||
|
onStop: () => void;
|
||||||
|
putProfile: (id: string, profile?: Profile) => void;
|
||||||
|
showSpinner: () => void;
|
||||||
|
hideSpinner: () => void;
|
||||||
|
initMyProfile: () => void;
|
||||||
|
}
|
||||||
|
>({
|
||||||
name: () => t('plugins.music-together.name'),
|
name: () => t('plugins.music-together.name'),
|
||||||
description: () => t('plugins.music-together.description'),
|
description: () => t('plugins.music-together.description'),
|
||||||
restartNeeded: false,
|
restartNeeded: false,
|
||||||
addedVersion: '3.2.0',
|
addedVersion: '3.2.X',
|
||||||
config: {
|
config: {
|
||||||
enabled: false
|
enabled: false
|
||||||
},
|
},
|
||||||
stylesheets: [style],
|
stylesheets: [style],
|
||||||
backend: {
|
backend({ ipc }) {
|
||||||
async start({ ipc }) {
|
ipc.handle('music-together:prompt', async (title: string, label: string) => prompt({
|
||||||
ipc.handle('music-together:prompt', async (title: string, label: string) => prompt({
|
title,
|
||||||
title,
|
label,
|
||||||
label,
|
type: 'input',
|
||||||
type: 'input',
|
...promptOptions()
|
||||||
...promptOptions()
|
}));
|
||||||
}));
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
renderer: {
|
renderer: {
|
||||||
connection: null as Connection | null,
|
updateNext: false,
|
||||||
ipc: null as RendererContext<never>['ipc'] | null,
|
ignoreChange: false,
|
||||||
|
permission: 'playlist',
|
||||||
api: null as (HTMLElement & AppAPI) | null,
|
|
||||||
queue: null as Queue | null,
|
|
||||||
playerApi: null as YoutubePlayer | null,
|
|
||||||
showPrompt: (async () => null) as ((title: string, label: string) => Promise<string | null>),
|
|
||||||
|
|
||||||
elements: {} as {
|
|
||||||
setting: HTMLElement;
|
|
||||||
icon: SVGElement;
|
|
||||||
spinner: HTMLElement;
|
|
||||||
},
|
|
||||||
popups: {} as {
|
popups: {} as {
|
||||||
host: ReturnType<typeof createHostPopup>;
|
host: ReturnType<typeof createHostPopup>;
|
||||||
guest: ReturnType<typeof createGuestPopup>;
|
guest: ReturnType<typeof createGuestPopup>;
|
||||||
setting: ReturnType<typeof createSettingPopup>;
|
setting: ReturnType<typeof createSettingPopup>;
|
||||||
},
|
},
|
||||||
stateInterval: null as number | null,
|
elements: {} as {
|
||||||
updateNext: false,
|
setting: HTMLElement;
|
||||||
ignoreChange: false,
|
icon: SVGElement;
|
||||||
rollbackInjector: null as (() => void) | null,
|
spinner: HTMLElement;
|
||||||
|
},
|
||||||
me: null as Omit<Profile, 'id'> | null,
|
profiles: {},
|
||||||
profiles: {} as Record<string, Profile>,
|
showPrompt: () => Promise.resolve(''),
|
||||||
permission: 'playlist' as Permission,
|
api: null,
|
||||||
|
|
||||||
/* events */
|
/* events */
|
||||||
videoChangeListener(event: CustomEvent<VideoDataChanged>) {
|
videoChangeListener(event: CustomEvent<VideoDataChanged>) {
|
||||||
if (event.detail.name === 'dataloaded' || this.updateNext) {
|
if (event.detail.name === 'dataloaded' || this.updateNext) {
|
||||||
if (this.connection?.mode === 'host') {
|
if (this.connection?.mode === 'host') {
|
||||||
const videoList: VideoData[] = this.queue?.flatItems.map((it: any) => ({
|
const videoList: VideoData[] = this.queue?.flatItems.map((it) => ({
|
||||||
videoId: it.videoId,
|
videoId: it!.videoId,
|
||||||
ownerId: this.connection!.id
|
ownerId: this.connection!.id
|
||||||
} satisfies VideoData)) ?? [];
|
} satisfies VideoData)) ?? [];
|
||||||
|
|
||||||
@ -123,8 +149,8 @@ export default createPlugin({
|
|||||||
if (!wait) return false;
|
if (!wait) return false;
|
||||||
|
|
||||||
if (!this.me) this.me = getDefaultProfile(this.connection.id);
|
if (!this.me) this.me = getDefaultProfile(this.connection.id);
|
||||||
const rawItems = this.queue?.flatItems?.map((it: any) => ({
|
const rawItems = this.queue?.flatItems?.map((it) => ({
|
||||||
videoId: it.videoId,
|
videoId: it!.videoId,
|
||||||
ownerId: this.connection!.id
|
ownerId: this.connection!.id
|
||||||
} satisfies VideoData)) ?? [];
|
} satisfies VideoData)) ?? [];
|
||||||
this.queue?.setOwner({
|
this.queue?.setOwner({
|
||||||
@ -170,7 +196,7 @@ export default createPlugin({
|
|||||||
case 'REMOVE_SONG': {
|
case 'REMOVE_SONG': {
|
||||||
if (conn && this.permission === 'host-only') return;
|
if (conn && this.permission === 'host-only') return;
|
||||||
|
|
||||||
await this.queue?.removeVideo(event.payload.index);
|
this.queue?.removeVideo(event.payload.index);
|
||||||
await this.connection?.broadcast('REMOVE_SONG', event.payload);
|
await this.connection?.broadcast('REMOVE_SONG', event.payload);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -295,11 +321,11 @@ export default createPlugin({
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'REMOVE_SONG': {
|
case 'REMOVE_SONG': {
|
||||||
await this.queue?.removeVideo(event.payload.index);
|
this.queue?.removeVideo(event.payload.index);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'MOVE_SONG': {
|
case 'MOVE_SONG': {
|
||||||
await this.queue?.moveItem(event.payload.fromIndex, event.payload.toIndex);
|
this.queue?.moveItem(event.payload.fromIndex, event.payload.toIndex);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'IDENTIFY': {
|
case 'IDENTIFY': {
|
||||||
@ -461,7 +487,7 @@ export default createPlugin({
|
|||||||
this.queue?.removeQueueOwner();
|
this.queue?.removeQueueOwner();
|
||||||
if (this.rollbackInjector) {
|
if (this.rollbackInjector) {
|
||||||
this.rollbackInjector();
|
this.rollbackInjector();
|
||||||
this.rollbackInjector = null;
|
this.rollbackInjector = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.profiles = {};
|
this.profiles = {};
|
||||||
@ -530,7 +556,7 @@ export default createPlugin({
|
|||||||
|
|
||||||
start({ ipc }) {
|
start({ ipc }) {
|
||||||
this.ipc = ipc;
|
this.ipc = ipc;
|
||||||
this.showPrompt = async (title: string, label: string) => ipc.invoke('music-together:prompt', title, label);
|
this.showPrompt = async (title: string, label: string) => ipc.invoke('music-together:prompt', title, label) as Promise<string>;
|
||||||
this.api = document.querySelector<HTMLElement & AppAPI>('ytmusic-app');
|
this.api = document.querySelector<HTMLElement & AppAPI>('ytmusic-app');
|
||||||
|
|
||||||
/* setup */
|
/* setup */
|
||||||
@ -571,10 +597,15 @@ export default createPlugin({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (id === 'music-together-copy-id') {
|
if (id === 'music-together-copy-id') {
|
||||||
navigator.clipboard.writeText(this.connection?.id ?? '');
|
navigator.clipboard.writeText(this.connection?.id ?? '')
|
||||||
|
.then(() => {
|
||||||
this.api?.openToast(t('plugins.music-together.toast.id-copied'));
|
this.api?.openToast(t('plugins.music-together.toast.id-copied'));
|
||||||
hostPopup.dismiss();
|
hostPopup.dismiss();
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.api?.openToast(t('plugins.music-together.toast.id-copy-failed'));
|
||||||
|
hostPopup.dismiss();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (id === 'music-together-permission') {
|
if (id === 'music-together-permission') {
|
||||||
@ -614,9 +645,14 @@ export default createPlugin({
|
|||||||
this.hideSpinner();
|
this.hideSpinner();
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
navigator.clipboard.writeText(this.connection?.id ?? '');
|
navigator.clipboard.writeText(this.connection?.id ?? '')
|
||||||
this.api?.openToast(t('plugins.music-together.toast.id-copied'));
|
.then(() => {
|
||||||
hostPopup.showAtAnchor(setting);
|
this.api?.openToast(t('plugins.music-together.toast.id-copied'));
|
||||||
|
hostPopup.showAtAnchor(setting);
|
||||||
|
}).catch(() => {
|
||||||
|
this.api?.openToast(t('plugins.music-together.toast.id-copy-failed'));
|
||||||
|
hostPopup.showAtAnchor(setting);
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
this.api?.openToast(t('plugins.music-together.toast.host-failed'));
|
this.api?.openToast(t('plugins.music-together.toast.host-failed'));
|
||||||
}
|
}
|
||||||
@ -642,7 +678,7 @@ export default createPlugin({
|
|||||||
guest: guestPopup,
|
guest: guestPopup,
|
||||||
setting: settingPopup
|
setting: settingPopup
|
||||||
};
|
};
|
||||||
setting.addEventListener('click', async () => {
|
setting.addEventListener('click', () => {
|
||||||
let popup = settingPopup;
|
let popup = settingPopup;
|
||||||
if (this.connection?.mode === 'host') popup = hostPopup;
|
if (this.connection?.mode === 'host') popup = hostPopup;
|
||||||
if (this.connection?.mode === 'guest') popup = guestPopup;
|
if (this.connection?.mode === 'guest') popup = guestPopup;
|
||||||
|
|||||||
@ -1,15 +1,12 @@
|
|||||||
import { SHA1Hash } from './sha1hash';
|
import { SHA1Hash } from './sha1hash';
|
||||||
|
|
||||||
export const extractToken = (cookie = document.cookie) => cookie.match(/SAPISID=([^;]+);/)?.[1] ?? cookie.match(/__Secure\-3PAPISID=([^;]+);/)?.[1];
|
export const extractToken = (cookie = document.cookie) => cookie.match(/SAPISID=([^;]+);/)?.[1] ?? cookie.match(/__Secure-3PAPISID=([^;]+);/)?.[1];
|
||||||
|
|
||||||
export const getHash = (papisid: string, millis = Date.now(), origin: string = 'https://music.youtube.com') => {
|
export const getHash = async (papisid: string, millis = Date.now(), origin: string = 'https://music.youtube.com') =>
|
||||||
const hash = SHA1Hash();
|
(await SHA1Hash(`${millis} ${papisid} ${origin}`)).toLowerCase();
|
||||||
hash.update(`${millis} ${papisid} ${origin}`);
|
|
||||||
return hash.digestString().toLowerCase();
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getAuthorizationHeader = (papisid: string, millis = Date.now(), origin: string = 'https://music.youtube.com') => {
|
export const getAuthorizationHeader = async (papisid: string, millis = Date.now(), origin: string = 'https://music.youtube.com') => {
|
||||||
return `SAPISIDHASH ${millis}_${getHash(papisid, millis, origin)}`;
|
return `SAPISIDHASH ${millis}_${await getHash(papisid, millis, origin)}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getClient = () => {
|
export const getClient = () => {
|
||||||
|
|||||||
@ -1,12 +1,51 @@
|
|||||||
import { getMusicQueueRenderer } from './song';
|
import { getMusicQueueRenderer } from './song';
|
||||||
import { mapQueueItem } from './utils';
|
import { mapQueueItem } from './utils';
|
||||||
|
|
||||||
import type { Profile, QueueAPI, VideoData } from '../types';
|
|
||||||
import { ConnectionEventUnion } from '@/plugins/music-together/connection';
|
import { ConnectionEventUnion } from '@/plugins/music-together/connection';
|
||||||
import { t } from '@/i18n';
|
import { t } from '@/i18n';
|
||||||
|
|
||||||
|
import type { Profile, QueueAPI, VideoData } from '../types';
|
||||||
|
import type { QueueItem } from '@/types/datahost-get-state';
|
||||||
|
|
||||||
const getHeaderPayload = (() => {
|
const getHeaderPayload = (() => {
|
||||||
let payload: unknown = null;
|
let payload: {
|
||||||
|
items?: QueueItem[] | undefined;
|
||||||
|
title: {
|
||||||
|
runs: {
|
||||||
|
text: string;
|
||||||
|
}[];
|
||||||
|
};
|
||||||
|
subtitle: {
|
||||||
|
runs: {
|
||||||
|
text: string;
|
||||||
|
}[];
|
||||||
|
};
|
||||||
|
buttons: {
|
||||||
|
chipCloudChipRenderer: {
|
||||||
|
style: {
|
||||||
|
styleType: string;
|
||||||
|
};
|
||||||
|
text: {
|
||||||
|
runs: {
|
||||||
|
text: string;
|
||||||
|
}[];
|
||||||
|
};
|
||||||
|
navigationEndpoint: {
|
||||||
|
saveQueueToPlaylistCommand: unknown;
|
||||||
|
};
|
||||||
|
icon: {
|
||||||
|
iconType: string;
|
||||||
|
};
|
||||||
|
accessibilityData: {
|
||||||
|
accessibilityData: {
|
||||||
|
label: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
isSelected: boolean;
|
||||||
|
uniqueId: string;
|
||||||
|
};
|
||||||
|
}[];
|
||||||
|
} | null = null;
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
if (!payload) {
|
if (!payload) {
|
||||||
@ -58,7 +97,7 @@ const getHeaderPayload = (() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return payload;
|
return payload;
|
||||||
}
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
export type QueueOptions = {
|
export type QueueOptions = {
|
||||||
@ -70,11 +109,11 @@ export type QueueOptions = {
|
|||||||
export type QueueEventListener = (event: ConnectionEventUnion) => void;
|
export type QueueEventListener = (event: ConnectionEventUnion) => void;
|
||||||
|
|
||||||
export class Queue {
|
export class Queue {
|
||||||
private queue: (HTMLElement & QueueAPI) | null = null;
|
private queue: (HTMLElement & QueueAPI);
|
||||||
private originalDispatch: ((obj: {
|
private originalDispatch?: (obj: {
|
||||||
type: string;
|
type: string;
|
||||||
payload?: unknown;
|
payload?: { items?: QueueItem[] | undefined; };
|
||||||
}) => void) | null = null;
|
}) => void;
|
||||||
private internalDispatch = false;
|
private internalDispatch = false;
|
||||||
private ignoreFlag = false;
|
private ignoreFlag = false;
|
||||||
private listeners: QueueEventListener[] = [];
|
private listeners: QueueEventListener[] = [];
|
||||||
@ -83,7 +122,7 @@ export class Queue {
|
|||||||
|
|
||||||
constructor(options: QueueOptions) {
|
constructor(options: QueueOptions) {
|
||||||
this.getProfile = options.getProfile;
|
this.getProfile = options.getProfile;
|
||||||
this.queue = options.queue ?? document.querySelector<HTMLElement & QueueAPI>('#queue');
|
this.queue = options.queue ?? document.querySelector<HTMLElement & QueueAPI>('#queue')!;
|
||||||
this.owner = options.owner ?? null;
|
this.owner = options.owner ?? null;
|
||||||
this._videoList = options.videoList ?? [];
|
this._videoList = options.videoList ?? [];
|
||||||
}
|
}
|
||||||
@ -96,7 +135,7 @@ export class Queue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get selectedIndex() {
|
get selectedIndex() {
|
||||||
return mapQueueItem((it) => it?.selected, this.queue?.store.getState().queue.items).findIndex(Boolean) ?? 0;
|
return mapQueueItem((it) => it?.selected, this.queue.store.getState().queue.items).findIndex(Boolean) ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
get rawItems() {
|
get rawItems() {
|
||||||
@ -146,7 +185,7 @@ export class Queue {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
async removeVideo(index: number) {
|
removeVideo(index: number) {
|
||||||
this.internalDispatch = true;
|
this.internalDispatch = true;
|
||||||
this._videoList.splice(index, 1);
|
this._videoList.splice(index, 1);
|
||||||
this.queue?.dispatch({
|
this.queue?.dispatch({
|
||||||
@ -233,10 +272,10 @@ export class Queue {
|
|||||||
if (event.type === 'ADD_ITEMS') {
|
if (event.type === 'ADD_ITEMS') {
|
||||||
if (this.ignoreFlag) {
|
if (this.ignoreFlag) {
|
||||||
this.ignoreFlag = false;
|
this.ignoreFlag = false;
|
||||||
const videoList = mapQueueItem((it: any) => ({
|
const videoList = mapQueueItem((it) => ({
|
||||||
videoId: it.videoId,
|
videoId: it!.videoId,
|
||||||
ownerId: this.owner!.id
|
ownerId: this.owner!.id
|
||||||
} satisfies VideoData), (event.payload as any).items);
|
} satisfies VideoData), event.payload!.items!);
|
||||||
const index = this._videoList.length + videoList.length - 1;
|
const index = this._videoList.length + videoList.length - 1;
|
||||||
|
|
||||||
if (videoList.length > 0) {
|
if (videoList.length > 0) {
|
||||||
@ -255,15 +294,17 @@ export class Queue {
|
|||||||
]
|
]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if ((event.payload as any).items.length === 1) {
|
} else if ((event.payload as {
|
||||||
|
items: unknown[];
|
||||||
|
}).items.length === 1) {
|
||||||
this.broadcast({ // add playlist
|
this.broadcast({ // add playlist
|
||||||
type: 'ADD_SONGS',
|
type: 'ADD_SONGS',
|
||||||
payload: {
|
payload: {
|
||||||
// index: (event.payload as any).index,
|
// index: (event.payload as any).index,
|
||||||
videoList: mapQueueItem((it: any) => ({
|
videoList: mapQueueItem((it) => ({
|
||||||
videoId: it.videoId,
|
videoId: it!.videoId,
|
||||||
ownerId: this.owner!.id
|
ownerId: this.owner!.id
|
||||||
} satisfies VideoData), (event.payload as any).items)
|
} satisfies VideoData), event.payload!.items!)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -275,8 +316,12 @@ export class Queue {
|
|||||||
this.broadcast({
|
this.broadcast({
|
||||||
type: 'MOVE_SONG',
|
type: 'MOVE_SONG',
|
||||||
payload: {
|
payload: {
|
||||||
fromIndex: (event.payload as any).fromIndex,
|
fromIndex: (event.payload as {
|
||||||
toIndex: (event.payload as any).toIndex
|
fromIndex: number;
|
||||||
|
}).fromIndex,
|
||||||
|
toIndex: (event.payload as {
|
||||||
|
toIndex: number;
|
||||||
|
}).toIndex
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
@ -306,7 +351,7 @@ export class Queue {
|
|||||||
event.payload = undefined;
|
event.payload = undefined;
|
||||||
}
|
}
|
||||||
if (event.type === 'SET_PLAYER_UI_STATE') {
|
if (event.type === 'SET_PLAYER_UI_STATE') {
|
||||||
if (event.payload === 'INACTIVE' && this.videoList.length > 0) {
|
if (event.payload as string === 'INACTIVE' && this.videoList.length > 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -321,12 +366,12 @@ export class Queue {
|
|||||||
dispatch: this.originalDispatch
|
dispatch: this.originalDispatch
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
this.originalDispatch!.call(fakeContext, event);
|
this.originalDispatch?.call(fakeContext, event);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sync */
|
/* sync */
|
||||||
async initQueue() {
|
initQueue() {
|
||||||
if (!this.queue) return;
|
if (!this.queue) return;
|
||||||
|
|
||||||
this.internalDispatch = true;
|
this.internalDispatch = true;
|
||||||
@ -369,13 +414,13 @@ export class Queue {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
async syncQueueOwner() {
|
syncQueueOwner() {
|
||||||
const allQueue = document.querySelectorAll('#queue');
|
const allQueue = document.querySelectorAll('#queue');
|
||||||
|
|
||||||
allQueue.forEach((queue) => {
|
allQueue.forEach((queue) => {
|
||||||
const list = Array.from(queue?.querySelectorAll<HTMLElement>('ytmusic-player-queue-item') ?? []);
|
const list = Array.from(queue?.querySelectorAll<HTMLElement>('ytmusic-player-queue-item') ?? []);
|
||||||
|
|
||||||
list.forEach((item, index) => {
|
list.forEach((item, index: number | undefined) => {
|
||||||
if (typeof index !== 'number') return;
|
if (typeof index !== 'number') return;
|
||||||
|
|
||||||
const id = this._videoList[index]?.ownerId;
|
const id = this._videoList[index]?.ownerId;
|
||||||
|
|||||||
@ -1,117 +1,7 @@
|
|||||||
export function SHA1Hash(): {
|
export const SHA1Hash = async (str: string) => {
|
||||||
reset: () => void,
|
const enc = new TextEncoder();
|
||||||
update: (message: string | number[], length?: number) => void,
|
const hash = await crypto.subtle.digest('SHA-1', enc.encode(str));
|
||||||
digest: () => number[],
|
return Array.from(new Uint8Array(hash))
|
||||||
digestString: () => string
|
.map((v) => v.toString(16).padStart(2, '0'))
|
||||||
} {
|
.join('');
|
||||||
let hash: number[];
|
};
|
||||||
|
|
||||||
function initialize(): void {
|
|
||||||
hash = [1732584193, 4023233417, 2562383102, 271733878, 3285377520];
|
|
||||||
totalLength = currentLength = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
function processBlock(block: number[]): void {
|
|
||||||
let words: number[] = [];
|
|
||||||
for (let i = 0; i < 64; i += 4) {
|
|
||||||
words[i / 4] = block[i] << 24 | block[i + 1] << 16 | block[i + 2] << 8 | block[i + 3];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 16; i < 80; i++) {
|
|
||||||
let temp = words[i - 3] ^ words[i - 8] ^ words[i - 14] ^ words[i - 16];
|
|
||||||
words[i] = (temp << 1 | temp >>> 31) & 4294967295;
|
|
||||||
}
|
|
||||||
|
|
||||||
let a = hash[0],
|
|
||||||
b = hash[1],
|
|
||||||
c = hash[2],
|
|
||||||
d = hash[3],
|
|
||||||
e = hash[4];
|
|
||||||
for (let i = 0; i < 80; i++) {
|
|
||||||
let f, k;
|
|
||||||
if (i < 20) {
|
|
||||||
f = d ^ b & (c ^ d);
|
|
||||||
k = 1518500249;
|
|
||||||
} else if (i < 40) {
|
|
||||||
f = b ^ c ^ d;
|
|
||||||
k = 1859775393;
|
|
||||||
} else if (i < 60) {
|
|
||||||
f = b & c | d & (b | c);
|
|
||||||
k = 2400959708;
|
|
||||||
} else {
|
|
||||||
f = b ^ c ^ d;
|
|
||||||
k = 3395469782;
|
|
||||||
}
|
|
||||||
let temp = ((a << 5 | a >>> 27) & 4294967295) + f + e + k + words[i] & 4294967295;
|
|
||||||
e = d;
|
|
||||||
d = c;
|
|
||||||
c = (b << 30 | b >>> 2) & 4294967295;
|
|
||||||
b = a;
|
|
||||||
a = temp;
|
|
||||||
}
|
|
||||||
hash[0] = hash[0] + a & 4294967295;
|
|
||||||
hash[1] = hash[1] + b & 4294967295;
|
|
||||||
hash[2] = hash[2] + c & 4294967295;
|
|
||||||
hash[3] = hash[3] + d & 4294967295;
|
|
||||||
hash[4] = hash[4] + e & 4294967295;
|
|
||||||
}
|
|
||||||
|
|
||||||
function update(message: string | number[], length?: number): void {
|
|
||||||
if ('string' === typeof message) {
|
|
||||||
message = unescape(encodeURIComponent(message));
|
|
||||||
let bytes: number[] = [];
|
|
||||||
for (let i = 0, len = message.length; i < len; ++i)
|
|
||||||
bytes.push(message.charCodeAt(i));
|
|
||||||
message = bytes;
|
|
||||||
}
|
|
||||||
length || (length = message.length);
|
|
||||||
let i = 0;
|
|
||||||
if (0 == currentLength)
|
|
||||||
for (; i + 64 < length;)
|
|
||||||
processBlock(message.slice(i, i + 64)),
|
|
||||||
i += 64,
|
|
||||||
totalLength += 64;
|
|
||||||
for (; i < length;)
|
|
||||||
if (buffer[currentLength++] = message[i++],
|
|
||||||
totalLength++,
|
|
||||||
64 == currentLength)
|
|
||||||
for (currentLength = 0,
|
|
||||||
processBlock(buffer); i + 64 < length;)
|
|
||||||
processBlock(message.slice(i, i + 64)),
|
|
||||||
i += 64,
|
|
||||||
totalLength += 64;
|
|
||||||
}
|
|
||||||
|
|
||||||
function finalize(): number[] {
|
|
||||||
let result: number[] = []
|
|
||||||
, bits = 8 * totalLength;
|
|
||||||
if (currentLength < 56)
|
|
||||||
update(padding, 56 - currentLength);
|
|
||||||
else
|
|
||||||
update(padding, 64 - (currentLength - 56));
|
|
||||||
for (let i = 63; i >= 56; i--)
|
|
||||||
buffer[i] = bits & 255,
|
|
||||||
bits >>>= 8;
|
|
||||||
processBlock(buffer);
|
|
||||||
for (let i = 0; i < 5; i++)
|
|
||||||
for (let j = 24; j >= 0; j -= 8)
|
|
||||||
result.push(hash[i] >> j & 255);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
let buffer: number[] = [], padding: number[] = [128], totalLength: number, currentLength: number;
|
|
||||||
for (let i = 1; i < 64; ++i)
|
|
||||||
padding[i] = 0;
|
|
||||||
initialize();
|
|
||||||
return {
|
|
||||||
reset: initialize,
|
|
||||||
update: update,
|
|
||||||
digest: finalize,
|
|
||||||
digestString: function(): string {
|
|
||||||
let hash = finalize(), hex = '';
|
|
||||||
for (let i = 0; i < hash.length; i++)
|
|
||||||
hex += '0123456789ABCDEF'.charAt(Math.floor(hash[i] / 16)) + '0123456789ABCDEF'.charAt(hash[i] % 16);
|
|
||||||
return hex;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|||||||
@ -33,8 +33,8 @@ export const getMusicQueueRenderer = async (videoIds: string[]): Promise<QueueRe
|
|||||||
}),
|
}),
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
Origin: 'https://music.youtube.com',
|
'Origin': 'https://music.youtube.com',
|
||||||
Authorization: getAuthorizationHeader(token)
|
'Authorization': await getAuthorizationHeader(token),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,15 +1,21 @@
|
|||||||
export const mapQueueItem = <T>(map: (item: any | null) => T, array: any[]): T[] => array
|
import {
|
||||||
|
ItemPlaylistPanelVideoRenderer,
|
||||||
|
PlaylistPanelVideoWrapperRenderer,
|
||||||
|
QueueItem
|
||||||
|
} from '@/types/datahost-get-state';
|
||||||
|
|
||||||
|
export const mapQueueItem = <T>(map: (item?: ItemPlaylistPanelVideoRenderer) => T, array: QueueItem[]): T[] => array
|
||||||
.map((item) => {
|
.map((item) => {
|
||||||
if ('playlistPanelVideoWrapperRenderer' in item) {
|
if ('playlistPanelVideoWrapperRenderer' in item) {
|
||||||
const keys = Object.keys(item.playlistPanelVideoWrapperRenderer.primaryRenderer);
|
const keys = Object.keys(item.playlistPanelVideoWrapperRenderer!.primaryRenderer) as (keyof PlaylistPanelVideoWrapperRenderer['primaryRenderer'])[];
|
||||||
return item.playlistPanelVideoWrapperRenderer.primaryRenderer[keys[0]];
|
return item.playlistPanelVideoWrapperRenderer!.primaryRenderer[keys[0]];
|
||||||
}
|
}
|
||||||
if ('playlistPanelVideoRenderer' in item) {
|
if ('playlistPanelVideoRenderer' in item) {
|
||||||
return item.playlistPanelVideoRenderer;
|
return item.playlistPanelVideoRenderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.error('Music Together: Unknown item', item);
|
console.error('Music Together: Unknown item', item);
|
||||||
return null;
|
return undefined;
|
||||||
})
|
})
|
||||||
.map(map);
|
.map(map);
|
||||||
|
|
||||||
|
|||||||
@ -1,14 +1,14 @@
|
|||||||
<div class="music-together-status">
|
<div class="music-together-status">
|
||||||
<div class="music-together-status-container">
|
<div class="music-together-status-container">
|
||||||
<img class="music-together-profile big">
|
<img class="music-together-profile big" alt="Profile Image">
|
||||||
<div class="music-together-status-item">
|
<div class="music-together-status-item">
|
||||||
<ytmd-trans key="plugins.music-together.name"></ytmd-trans>
|
<ytmd-trans key="plugins.music-together.name"></ytmd-trans>
|
||||||
<span id="music-together-status-label">
|
<span id="music-together-status-label">
|
||||||
<ytmd-trans key="plugins.music-together.menu.status.disconnected"></ytmd-trans>
|
<ytmd-trans key="plugins.music-together.menu.status.disconnected"></ytmd-trans>
|
||||||
</span>
|
</span>
|
||||||
<span id="music-together-permission-label">
|
<marquee id="music-together-permission-label">
|
||||||
<ytmd-trans key="plugins.music-together.menu.permission.playlist" style="color: rgba(255, 255, 255, 0.75)"></ytmd-trans>
|
<ytmd-trans key="plugins.music-together.menu.permission.playlist" style="color: rgba(255, 255, 255, 0.75)"></ytmd-trans>
|
||||||
</span>
|
</marquee>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="music-together-divider horizontal" style="margin: 16px 0;"></div>
|
<div class="music-together-divider horizontal" style="margin: 16px 0;"></div>
|
||||||
|
|||||||
@ -1,15 +1,19 @@
|
|||||||
import { YoutubePlayer } from '@/types/youtube-player';
|
import { YoutubePlayer } from '@/types/youtube-player';
|
||||||
type StoreState = any;
|
import { GetState, QueueItem } from '@/types/datahost-get-state';
|
||||||
|
|
||||||
|
type StoreState = GetState;
|
||||||
type Store = {
|
type Store = {
|
||||||
dispatch: (obj: {
|
dispatch: (obj: {
|
||||||
type: string;
|
type: string;
|
||||||
payload?: unknown;
|
payload?: {
|
||||||
|
items?: QueueItem[];
|
||||||
|
};
|
||||||
}) => void;
|
}) => void;
|
||||||
|
|
||||||
getState: () => StoreState;
|
getState: () => StoreState;
|
||||||
replaceReducer: (param1: unknown) => unknown;
|
replaceReducer: (param1: unknown) => unknown;
|
||||||
subscribe: (callback: () => void) => unknown;
|
subscribe: (callback: () => void) => unknown;
|
||||||
};
|
}
|
||||||
export type QueueAPI = {
|
export type QueueAPI = {
|
||||||
dispatch(obj: {
|
dispatch(obj: {
|
||||||
type: string;
|
type: string;
|
||||||
@ -28,8 +32,6 @@ export type AppAPI = {
|
|||||||
// TODO: Add more
|
// TODO: Add more
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export type Profile = {
|
export type Profile = {
|
||||||
id: string;
|
id: string;
|
||||||
handleId: string;
|
handleId: string;
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
import { ElementFromHtml } from '@/plugins/utils/renderer';
|
import { ElementFromHtml } from '@/plugins/utils/renderer';
|
||||||
import statusHTML from '../templates/status.html?raw';
|
|
||||||
import { t } from '@/i18n';
|
import { t } from '@/i18n';
|
||||||
|
|
||||||
|
import statusHTML from '../templates/status.html?raw';
|
||||||
|
|
||||||
import type { Permission, Profile } from '../types';
|
import type { Permission, Profile } from '../types';
|
||||||
|
|
||||||
export const createStatus = () => {
|
export const createStatus = () => {
|
||||||
@ -9,7 +11,7 @@ export const createStatus = () => {
|
|||||||
|
|
||||||
const profile = element.querySelector<HTMLImageElement>('.music-together-profile')!;
|
const profile = element.querySelector<HTMLImageElement>('.music-together-profile')!;
|
||||||
const statusLabel = element.querySelector<HTMLSpanElement>('#music-together-status-label')!;
|
const statusLabel = element.querySelector<HTMLSpanElement>('#music-together-status-label')!;
|
||||||
const permissionLabel = element.querySelector<HTMLSpanElement>('#music-together-permission-label')!;
|
const permissionLabel = element.querySelector<HTMLMarqueeElement>('#music-together-permission-label')!;
|
||||||
|
|
||||||
profile.src = icon?.src ?? '';
|
profile.src = icon?.src ?? '';
|
||||||
|
|
||||||
|
|||||||
@ -40,7 +40,6 @@ const audioCanPlayListener = (e: CustomEvent<Compressor>) => {
|
|||||||
const fftBins = new Float32Array(analyser.frequencyBinCount);
|
const fftBins = new Float32Array(analyser.frequencyBinCount);
|
||||||
|
|
||||||
sourceNode.connect(analyser);
|
sourceNode.connect(analyser);
|
||||||
analyser.connect(audioContext.destination);
|
|
||||||
|
|
||||||
const looper = () => {
|
const looper = () => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
|||||||
@ -127,7 +127,7 @@ export default (api: YoutubePlayer) => {
|
|||||||
|
|
||||||
const waitingEvent = new Set<string>();
|
const waitingEvent = new Set<string>();
|
||||||
// Name = "dataloaded" and abit later "dataupdated"
|
// Name = "dataloaded" and abit later "dataupdated"
|
||||||
api.addEventListener('videodatachange', (name: string, videoData) => {
|
api.addEventListener('videodatachange', (name, videoData) => {
|
||||||
videoEventDispatcher(name, videoData);
|
videoEventDispatcher(name, videoData);
|
||||||
|
|
||||||
if (name === 'dataupdated' && waitingEvent.has(videoData.videoId)) {
|
if (name === 'dataupdated' && waitingEvent.has(videoData.videoId)) {
|
||||||
|
|||||||
28
src/tray.ts
28
src/tray.ts
@ -1,10 +1,12 @@
|
|||||||
import { Menu, nativeImage, Tray } from 'electron';
|
import { Menu, nativeImage, Tray } from 'electron';
|
||||||
|
|
||||||
import youtubeMusicTrayIcon from '@assets/youtube-music-tray.png?asset&asarUnpack';
|
import defaultTrayIconAsset from '@assets/youtube-music-tray.png?asset&asarUnpack';
|
||||||
|
import pausedTrayIconAsset from '@assets/youtube-music-tray-paused.png?asset&asarUnpack';
|
||||||
|
|
||||||
import config from './config';
|
import config from './config';
|
||||||
|
|
||||||
import { restart } from './providers/app-controls';
|
import { restart } from './providers/app-controls';
|
||||||
|
import registerCallback from './providers/song-info';
|
||||||
import getSongControls from './providers/song-controls';
|
import getSongControls from './providers/song-controls';
|
||||||
|
|
||||||
import { t } from '@/i18n';
|
import { t } from '@/i18n';
|
||||||
@ -46,14 +48,18 @@ export const setUpTray = (app: Electron.App, win: Electron.BrowserWindow) => {
|
|||||||
|
|
||||||
const { playPause, next, previous } = getSongControls(win);
|
const { playPause, next, previous } = getSongControls(win);
|
||||||
|
|
||||||
const trayIcon = nativeImage.createFromPath(youtubeMusicTrayIcon).resize({
|
const defaultTrayIcon = nativeImage.createFromPath(defaultTrayIconAsset).resize({
|
||||||
|
width: 16,
|
||||||
|
height: 16,
|
||||||
|
});
|
||||||
|
const pausedTrayIcon = nativeImage.createFromPath(pausedTrayIconAsset).resize({
|
||||||
width: 16,
|
width: 16,
|
||||||
height: 16,
|
height: 16,
|
||||||
});
|
});
|
||||||
|
|
||||||
tray = new Tray(trayIcon);
|
tray = new Tray(defaultTrayIcon);
|
||||||
|
|
||||||
tray.setToolTip('YouTube Music');
|
tray.setToolTip(t('main.tray.tooltip.default'));
|
||||||
|
|
||||||
// MacOS only
|
// MacOS only
|
||||||
tray.setIgnoreDoubleClickEvents(true);
|
tray.setIgnoreDoubleClickEvents(true);
|
||||||
@ -110,4 +116,18 @@ export const setUpTray = (app: Electron.App, win: Electron.BrowserWindow) => {
|
|||||||
|
|
||||||
const trayMenu = Menu.buildFromTemplate(template);
|
const trayMenu = Menu.buildFromTemplate(template);
|
||||||
tray.setContextMenu(trayMenu);
|
tray.setContextMenu(trayMenu);
|
||||||
|
|
||||||
|
registerCallback(songInfo => {
|
||||||
|
if (typeof songInfo.isPaused === 'undefined') {
|
||||||
|
tray.setImage(defaultTrayIcon);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tray.setToolTip(t('main.tray.tooltip.with-song-info', {
|
||||||
|
artist: songInfo.artist,
|
||||||
|
title: songInfo.title,
|
||||||
|
}));
|
||||||
|
|
||||||
|
tray.setImage(songInfo.isPaused ? pausedTrayIcon : defaultTrayIcon);
|
||||||
|
})
|
||||||
};
|
};
|
||||||
|
|||||||
@ -256,6 +256,7 @@ export type VideoDataChangeValue = Record<string, unknown> & {
|
|||||||
export interface PlayerAPIEvents {
|
export interface PlayerAPIEvents {
|
||||||
videodatachange: {
|
videodatachange: {
|
||||||
value: VideoDataChangeValue;
|
value: VideoDataChangeValue;
|
||||||
} & ({ name: 'dataloaded' } | { name: 'dataupdated ' });
|
name: 'dataloaded' | 'dataupdated';
|
||||||
|
};
|
||||||
onStateChange: number;
|
onStateChange: number;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -357,8 +357,8 @@ export interface YoutubePlayer {
|
|||||||
type: K,
|
type: K,
|
||||||
listener: (
|
listener: (
|
||||||
this: Document,
|
this: Document,
|
||||||
name: PlayerAPIEvents[K]['name'],
|
name: K extends 'videodatachange' ? PlayerAPIEvents[K]['name'] : never,
|
||||||
data: PlayerAPIEvents[K]['value'],
|
data: K extends 'videodatachange' ? PlayerAPIEvents[K]['value'] : never,
|
||||||
) => void,
|
) => void,
|
||||||
options?: boolean | AddEventListenerOptions | undefined,
|
options?: boolean | AddEventListenerOptions | undefined,
|
||||||
) => void;
|
) => void;
|
||||||
@ -366,8 +366,8 @@ export interface YoutubePlayer {
|
|||||||
type: K,
|
type: K,
|
||||||
listener: (
|
listener: (
|
||||||
this: Document,
|
this: Document,
|
||||||
name: PlayerAPIEvents[K]['name'],
|
name: K extends 'videodatachange' ? PlayerAPIEvents[K]['name'] : never,
|
||||||
data: PlayerAPIEvents[K]['value'],
|
data: K extends 'videodatachange' ? PlayerAPIEvents[K]['value'] : never,
|
||||||
) => void,
|
) => void,
|
||||||
options?: boolean | EventListenerOptions | undefined,
|
options?: boolean | EventListenerOptions | undefined,
|
||||||
) => void;
|
) => void;
|
||||||
|
|||||||
@ -24,10 +24,6 @@ ytmusic-app-layout {
|
|||||||
--ytmusic-nav-bar-height: 90px;
|
--ytmusic-nav-bar-height: 90px;
|
||||||
}
|
}
|
||||||
|
|
||||||
ytmusic-search-box.ytmusic-nav-bar {
|
|
||||||
margin-top: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Blocking annoying elements */
|
/* Blocking annoying elements */
|
||||||
ytmusic-mealbar-promo-renderer {
|
ytmusic-mealbar-promo-renderer {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
|
|||||||
Reference in New Issue
Block a user