mirror of
https://github.com/th-ch/youtube-music.git
synced 2026-01-11 18:41:47 +00:00
Compare commits
104 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 65bcf20f97 | |||
| 1a214140fb | |||
| ffdf7ac5a8 | |||
| c8bb1f386d | |||
| 457e1bb48e | |||
| c1177adc08 | |||
| cd976ee500 | |||
| b856884bba | |||
| 2df8e58773 | |||
| da8e0106f6 | |||
| b0b2005e1c | |||
| 5817d9c3ae | |||
| 08f9187cdf | |||
| 49ac17a40e | |||
| b1c4b04ebf | |||
| 10b8066126 | |||
| d86e454d3f | |||
| 4ea8fa2561 | |||
| dbea4c5884 | |||
| 7d4e949f0c | |||
| 82917e7748 | |||
| 7c9544a528 | |||
| 960a20e899 | |||
| c9b7901681 | |||
| 95698aaf35 | |||
| 4dc87417ff | |||
| 7510f8eb08 | |||
| 59103df665 | |||
| 258d35e48d | |||
| 5e419489d5 | |||
| 0d462ac3a2 | |||
| bcb94f6de8 | |||
| fe925ec8ee | |||
| 86c77d141f | |||
| 754ca3caaa | |||
| 61ea104d7b | |||
| 573bdfae03 | |||
| cca493b7d5 | |||
| f47262d27b | |||
| 65bf9129ea | |||
| 87e9b9f7a8 | |||
| 07bc4f05fd | |||
| e3a6808087 | |||
| e9184e5d60 | |||
| a5b32d96f8 | |||
| 040db7539c | |||
| da646c1d53 | |||
| 5f5917f972 | |||
| eccb0d2f08 | |||
| 4cd9dd17df | |||
| 5de07b9a96 | |||
| 151f067beb | |||
| c68a7bd19f | |||
| b87e5e31df | |||
| 03229d61c8 | |||
| b6330eed18 | |||
| b254812ac2 | |||
| 7e243e2fbf | |||
| 307e52cc89 | |||
| f7b7ea916f | |||
| 3eccf8daca | |||
| aa48944212 | |||
| 4d51f1a412 | |||
| d3c9f76582 | |||
| d638a6cf28 | |||
| f93651b219 | |||
| cb8c6c69fe | |||
| 4e7266fb1b | |||
| 8de75ff3a5 | |||
| 3236c88eb2 | |||
| c9f0ad14c2 | |||
| 0a9199c92b | |||
| 3ffcff7d9c | |||
| ddf614d362 | |||
| 6f1a77bbb9 | |||
| 8595f9761e | |||
| cc442182fd | |||
| b827a05eea | |||
| 250abab8bc | |||
| 8e45518ccf | |||
| 7485e065ed | |||
| c1d88f91d4 | |||
| 124a2bd8d0 | |||
| f8f94f9665 | |||
| 5e98a82b23 | |||
| a5c20a66b3 | |||
| cc84116ad1 | |||
| a2e2031708 | |||
| 5001eabf23 | |||
| aac2974430 | |||
| f7f005bb3d | |||
| e1f6d5b7f2 | |||
| b6b607897e | |||
| 651ebb2b1a | |||
| 9fa24deed2 | |||
| c81022d373 | |||
| b726dc7580 | |||
| 471aa7d0a6 | |||
| f34d645ac3 | |||
| d2a11a560e | |||
| 9d185872db | |||
| d0ff71aa66 | |||
| bc8999585f | |||
| 1e1582e31f |
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@ -23,7 +23,7 @@ jobs:
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 9
|
||||
version: 10
|
||||
run_install: false
|
||||
|
||||
- name: Setup NodeJS
|
||||
@ -98,7 +98,7 @@ jobs:
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 9
|
||||
version: 10
|
||||
run_install: false
|
||||
|
||||
- name: Setup NodeJS
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 1.6 KiB |
111
changelog.md
111
changelog.md
@ -2,8 +2,119 @@
|
||||
|
||||
All notable changes to this project will be documented in this file. Dates are displayed in UTC.
|
||||
|
||||
#### [v3.7.4](https://github.com/th-ch/youtube-music/compare/v3.7.3...v3.7.4)
|
||||
|
||||
- chore(deps): update dependency rollup to v4.34.8 [`#2982`](https://github.com/th-ch/youtube-music/pull/2982)
|
||||
- fix(plugin-loader): update context filtering logic for backend mode [`#2990`](https://github.com/th-ch/youtube-music/pull/2990)
|
||||
- Update changelog for v3.7.3 [`86c77d1`](https://github.com/th-ch/youtube-music/commit/86c77d141f2bec62a4a578fff96d51ed388c05a5)
|
||||
- HOTFIX: Bump version to 3.7.4 [`0d462ac`](https://github.com/th-ch/youtube-music/commit/0d462ac3a26caee23854014cbf5e4b91e2d385e2)
|
||||
|
||||
#### [v3.7.3](https://github.com/th-ch/youtube-music/compare/v3.7.2...v3.7.3)
|
||||
|
||||
> 17 February 2025
|
||||
|
||||
- fix(downloader): use the upgrade button to check for premium status [`#2987`](https://github.com/th-ch/youtube-music/pull/2987)
|
||||
- chore(deps): update dependency electron-vite to v3 [`#2986`](https://github.com/th-ch/youtube-music/pull/2986)
|
||||
- chore(deps): update dependency @babel/runtime to v7.26.9 [`#2980`](https://github.com/th-ch/youtube-music/pull/2980)
|
||||
- fix(vite): set server.cors.origin [`#2981`](https://github.com/th-ch/youtube-music/pull/2981)
|
||||
- chore(deps-dev): bump esbuild from 0.24.2 to 0.25.0 [`#2973`](https://github.com/th-ch/youtube-music/pull/2973)
|
||||
- fix(deps): update dependency solid-transition-group to v0.3.0 [`#2949`](https://github.com/th-ch/youtube-music/pull/2949)
|
||||
- fix: remove disable-gpu-memory-buffer-video-frames flag [`#2963`](https://github.com/th-ch/youtube-music/pull/2963)
|
||||
- fix(deps): update dependency semver to v7.7.0 [`#2948`](https://github.com/th-ch/youtube-music/pull/2948)
|
||||
- chore(deps): update playwright monorepo to v1.50.1 [`#2943`](https://github.com/th-ch/youtube-music/pull/2943)
|
||||
- fix(deps): update dependency @hono/node-server to v1.13.8 [`#2944`](https://github.com/th-ch/youtube-music/pull/2944)
|
||||
- fix(deps): update dependency electron-store to v10.0.1 [`#2945`](https://github.com/th-ch/youtube-music/pull/2945)
|
||||
- chore(deps): update dependency rollup to v4.34.1 [`#2946`](https://github.com/th-ch/youtube-music/pull/2946)
|
||||
- chore(deps): update dependency typescript-eslint to v8.22.0 [`#2947`](https://github.com/th-ch/youtube-music/pull/2947)
|
||||
- fix(synced-lyrics): Fix reverse direction of synced lyrics for persian or other rtl languages [`#2940`](https://github.com/th-ch/youtube-music/pull/2940)
|
||||
- chore(deps): update dependency electron to v34.0.2 [`#2942`](https://github.com/th-ch/youtube-music/pull/2942)
|
||||
- chore(deps): update dependency discord-api-types to v0.37.119 [`#2941`](https://github.com/th-ch/youtube-music/pull/2941)
|
||||
- fix(deps): update dependency hono to v4.6.20 [`#2932`](https://github.com/th-ch/youtube-music/pull/2932)
|
||||
- chore(deps): update eslint monorepo to v9.19.0 [`#2935`](https://github.com/th-ch/youtube-music/pull/2935)
|
||||
- fix(deps): update dependency bgutils-js to v3.1.3 [`#2934`](https://github.com/th-ch/youtube-music/pull/2934)
|
||||
- fix(deps): update dependency i18next to v24.2.2 [`#2933`](https://github.com/th-ch/youtube-music/pull/2933)
|
||||
- fix(deps): update dependency happy-dom to v16.8.1 [`#2936`](https://github.com/th-ch/youtube-music/pull/2936)
|
||||
- chore(deps): update dependency @babel/runtime to v7.26.7 [`#2924`](https://github.com/th-ch/youtube-music/pull/2924)
|
||||
- chore(config): migrate renovate config [`#2925`](https://github.com/th-ch/youtube-music/pull/2925)
|
||||
- fix(deps): update dependency @ghostery/adblocker-electron-preload to v2.5.0 [`#2923`](https://github.com/th-ch/youtube-music/pull/2923)
|
||||
- fix(deps): update dependency @ghostery/adblocker-electron to v2.5.0 [`#2922`](https://github.com/th-ch/youtube-music/pull/2922)
|
||||
- chore(deps): update playwright monorepo to v1.50.0 [`#2921`](https://github.com/th-ch/youtube-music/pull/2921)
|
||||
- chore(deps): update dependency vite-plugin-inspect to v10.1.0 [`#2920`](https://github.com/th-ch/youtube-music/pull/2920)
|
||||
- chore(deps): update dependency rollup to v4.32.0 [`#2919`](https://github.com/th-ch/youtube-music/pull/2919)
|
||||
- fix(deps): update dependency hono to v4.6.18 [`#2918`](https://github.com/th-ch/youtube-music/pull/2918)
|
||||
- fix(deps): update dependency deepmerge-ts to v7.1.4 [`#2917`](https://github.com/th-ch/youtube-music/pull/2917)
|
||||
- chore(deps): update dependency vite to v6.0.11 [`#2894`](https://github.com/th-ch/youtube-music/pull/2894)
|
||||
- chore(deps): update dependency electron to v34.0.1 [`#2916`](https://github.com/th-ch/youtube-music/pull/2916)
|
||||
- chore(deps): update dependency electron-builder-squirrel-windows to v26.0.0-alpha.10 [`#2899`](https://github.com/th-ch/youtube-music/pull/2899)
|
||||
- chore(deps): update dependency electron-builder to v26.0.0-alpha.10 [`#2898`](https://github.com/th-ch/youtube-music/pull/2898)
|
||||
- chore(deps): update dependency typescript-eslint to v8.21.0 [`#2901`](https://github.com/th-ch/youtube-music/pull/2901)
|
||||
- chore(deps): update dependency discord-api-types to v0.37.117 [`#2895`](https://github.com/th-ch/youtube-music/pull/2895)
|
||||
- fix(deps): update dependency youtubei.js to v13 [`#2904`](https://github.com/th-ch/youtube-music/pull/2904)
|
||||
- chore(deps): update dependency vite to v6.0.9 [security] [`#2907`](https://github.com/th-ch/youtube-music/pull/2907)
|
||||
- fix(deps): update dependency happy-dom to v16.7.2 [`#2902`](https://github.com/th-ch/youtube-music/pull/2902)
|
||||
- fix(discord-plugin): handle album name padding if length < 2 [`#2903`](https://github.com/th-ch/youtube-music/pull/2903)
|
||||
- feat(navigation): added nav icon padding [`#2905`](https://github.com/th-ch/youtube-music/pull/2905)
|
||||
- chore(deps): update dependency rollup to v4.31.0 [`#2891`](https://github.com/th-ch/youtube-music/pull/2891)
|
||||
- chore(deps): update dependency eslint-plugin-prettier to v5.2.3 [`#2889`](https://github.com/th-ch/youtube-music/pull/2889)
|
||||
- chore(deps): update dependency vite-plugin-inspect to v10.0.7 [`#2882`](https://github.com/th-ch/youtube-music/pull/2882)
|
||||
- fix(deps): update dependency hono to v4.6.17 [`#2883`](https://github.com/th-ch/youtube-music/pull/2883)
|
||||
- fix: bump deps [`e9184e5`](https://github.com/th-ch/youtube-music/commit/e9184e5d60c2495473a7c3226ce9748ba89fceb3)
|
||||
- fix(deps): fix pnpm [`040db75`](https://github.com/th-ch/youtube-music/commit/040db7539ccd1ae40f2632fdf38168cdaa26f112)
|
||||
- chore(i18n): Translated using Weblate (Persian) [`9d18587`](https://github.com/th-ch/youtube-music/commit/9d185872dba5b56dabc691e56eafb13dc192b9cd)
|
||||
|
||||
#### [v3.7.2](https://github.com/th-ch/youtube-music/compare/v3.7.1...v3.7.2)
|
||||
|
||||
> 18 January 2025
|
||||
|
||||
- feat(api-server): add endpoint to get shuffle state [`#2792`](https://github.com/th-ch/youtube-music/pull/2792)
|
||||
- chore(deps): update dependency discord-api-types to v0.37.116 [`#2877`](https://github.com/th-ch/youtube-music/pull/2877)
|
||||
- chore(deps): update dependency eslint-plugin-prettier to v5.2.2 [`#2875`](https://github.com/th-ch/youtube-music/pull/2875)
|
||||
- chore(deps): update eslint monorepo to v9.18.0 [`#2858`](https://github.com/th-ch/youtube-music/pull/2858)
|
||||
- chore(deps): update dependency glob to v11.0.1 [`#2857`](https://github.com/th-ch/youtube-music/pull/2857)
|
||||
- chore(deps): update dependency electron-builder-squirrel-windows to v26.0.0-alpha.9 [`#2874`](https://github.com/th-ch/youtube-music/pull/2874)
|
||||
- chore(deps): update dependency electron to v34 [`#2867`](https://github.com/th-ch/youtube-music/pull/2867)
|
||||
- chore(deps): update dependency eslint-config-prettier to v10 [`#2866`](https://github.com/th-ch/youtube-music/pull/2866)
|
||||
- chore(deps): update dependency @stylistic/eslint-plugin-js to v2.13.0 [`#2864`](https://github.com/th-ch/youtube-music/pull/2864)
|
||||
- chore(deps): update dependency typescript-eslint to v8.20.0 [`#2865`](https://github.com/th-ch/youtube-music/pull/2865)
|
||||
- chore(deps): update dependency electron-builder to v26.0.0-alpha.9 [`#2869`](https://github.com/th-ch/youtube-music/pull/2869)
|
||||
- fix: fix build.linux.desktop.entry [`#2859`](https://github.com/th-ch/youtube-music/pull/2859)
|
||||
- feat(api-server): add endpoint to get volume state [`#2813`](https://github.com/th-ch/youtube-music/pull/2813)
|
||||
- chore(deps): update dependency vite-plugin-inspect to v10 [`#2856`](https://github.com/th-ch/youtube-music/pull/2856)
|
||||
- chore(deps): update dependency typescript to v5.7.3 [`#2855`](https://github.com/th-ch/youtube-music/pull/2855)
|
||||
- fix(deps): update dependency @floating-ui/dom to v1.6.13 [`#2846`](https://github.com/th-ch/youtube-music/pull/2846)
|
||||
- chore(deps): bump nanoid from 3.3.7 to 3.3.8 [`#2854`](https://github.com/th-ch/youtube-music/pull/2854)
|
||||
- chore(deps): update dependency electron to v33.3.1 [`#2841`](https://github.com/th-ch/youtube-music/pull/2841)
|
||||
- fix(deps): update dependency i18next to v24.2.1 [`#2840`](https://github.com/th-ch/youtube-music/pull/2840)
|
||||
- chore(deps): update dependency typescript-eslint to v8.19.1 [`#2836`](https://github.com/th-ch/youtube-music/pull/2836)
|
||||
- chore(deps): update dependency rollup to v4.30.1 [`#2833`](https://github.com/th-ch/youtube-music/pull/2833)
|
||||
- fix(deps): update dependency solid-js to v1.9.4 [`#2849`](https://github.com/th-ch/youtube-music/pull/2849)
|
||||
- fix(deps): update dependency fast-equals to v5.2.2 [`#2842`](https://github.com/th-ch/youtube-music/pull/2842)
|
||||
- chore: Update README.md [`#2845`](https://github.com/th-ch/youtube-music/pull/2845)
|
||||
- chore: Fixing the Content section in the README-ru.md file. [`#2847`](https://github.com/th-ch/youtube-music/pull/2847)
|
||||
- chore: Create youtube-music-hu.svg [`#2844`](https://github.com/th-ch/youtube-music/pull/2844)
|
||||
- chore: Create Transalated README-hu.md [`#2843`](https://github.com/th-ch/youtube-music/pull/2843)
|
||||
- chore(deps): update dependency vite to v6.0.7 [`#2819`](https://github.com/th-ch/youtube-music/pull/2819)
|
||||
- chore(deps): update dependency discord-api-types to v0.37.115 [`#2818`](https://github.com/th-ch/youtube-music/pull/2818)
|
||||
- fix(deps): update dependency hono to v4.6.16 [`#2829`](https://github.com/th-ch/youtube-music/pull/2829)
|
||||
- chore(deps): update dependency rollup to v4.29.2 [`#2832`](https://github.com/th-ch/youtube-music/pull/2832)
|
||||
- fix(deps): update dependency fast-equals to v5.2.0 [`#2822`](https://github.com/th-ch/youtube-music/pull/2822)
|
||||
- feat(api-server): add `insertPosition` for `addSongToQueue` [`#2808`](https://github.com/th-ch/youtube-music/pull/2808)
|
||||
- chore(deps): update dependency typescript-eslint to v8.19.0 [`#2812`](https://github.com/th-ch/youtube-music/pull/2812)
|
||||
- fix(deps): update dependency ts-morph to v25 [`#2810`](https://github.com/th-ch/youtube-music/pull/2810)
|
||||
- fix(renderer): update event handler from onVolumeTap to onVolumeClick [`#2791`](https://github.com/th-ch/youtube-music/pull/2791)
|
||||
- fix(deps): update dependency hono to v4.6.15 [`#2796`](https://github.com/th-ch/youtube-music/pull/2796)
|
||||
- chore(deps): update dependency bufferutil to v4.0.9 [`#2787`](https://github.com/th-ch/youtube-music/pull/2787)
|
||||
- feat: Refactor Menu Navigation and Update Media Control Icons [`#2783`](https://github.com/th-ch/youtube-music/pull/2783)
|
||||
- fix(synced-lyrics): Revert font-size behavior for non-fancy modes [`#2788`](https://github.com/th-ch/youtube-music/pull/2788)
|
||||
- fix(downloader): apply poToken [`#2863`](https://github.com/th-ch/youtube-music/issues/2863) [`#2780`](https://github.com/th-ch/youtube-music/issues/2780)
|
||||
- chore(deps): update dependency electron-builder to v26 [`67fc0a4`](https://github.com/th-ch/youtube-music/commit/67fc0a415cae231a11f2846aadf01edb04f5c677)
|
||||
- fix: fix lock file [`3339f99`](https://github.com/th-ch/youtube-music/commit/3339f997e3c2d4d2c32b3aee95c65d561f123fcb)
|
||||
- chore(i18n): Translated using Weblate (Romanian) [`845dac3`](https://github.com/th-ch/youtube-music/commit/845dac3c0393dadea8efdd03ba1f41b1b36e6191)
|
||||
|
||||
#### [v3.7.1](https://github.com/th-ch/youtube-music/compare/v3.7.0...v3.7.1)
|
||||
|
||||
> 27 December 2024
|
||||
|
||||
- fix(deps): update dependency node-html-parser to v7 [`#2776`](https://github.com/th-ch/youtube-music/pull/2776)
|
||||
- chore(deps): update dependency vite to v6.0.6 [`#2774`](https://github.com/th-ch/youtube-music/pull/2774)
|
||||
- feat(api-server): Add queue api [`#2767`](https://github.com/th-ch/youtube-music/pull/2767)
|
||||
|
||||
@ -147,6 +147,11 @@ export default defineConfig({
|
||||
resolve: {
|
||||
alias: resolveAlias,
|
||||
},
|
||||
server: {
|
||||
cors: {
|
||||
origin: 'https://music.youtube.com',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
if (mode === 'development') {
|
||||
|
||||
100
package.json
100
package.json
@ -2,7 +2,7 @@
|
||||
"name": "youtube-music",
|
||||
"desktopName": "com.github.th_ch.youtube_music",
|
||||
"productName": "YouTube Music",
|
||||
"version": "3.7.2",
|
||||
"version": "3.7.5",
|
||||
"description": "YouTube Music Desktop App - including custom plugins",
|
||||
"main": "./dist/main/index.js",
|
||||
"license": "MIT",
|
||||
@ -218,22 +218,22 @@
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18",
|
||||
"pnpm": ">=8"
|
||||
"pnpm": ">=10"
|
||||
},
|
||||
"pnpm": {
|
||||
"overrides": {
|
||||
"vite": "6.0.7",
|
||||
"node-gyp": "11.0.0",
|
||||
"vite": "6.2.0",
|
||||
"node-gyp": "11.1.0",
|
||||
"xml2js": "0.6.2",
|
||||
"node-fetch": "3.3.2",
|
||||
"@electron/universal": "2.0.1",
|
||||
"@babel/runtime": "7.26.0"
|
||||
"@electron/universal": "2.0.2",
|
||||
"@babel/runtime": "7.26.9"
|
||||
},
|
||||
"patchedDependencies": {
|
||||
"vudio@2.1.1": "patches/vudio@2.1.1.patch",
|
||||
"app-builder-lib@26.0.0-alpha.9": "patches/app-builder-lib@26.0.0-alpha.9.patch",
|
||||
"@malept/flatpak-bundler": "patches/@malept__flatpak-bundler.patch"
|
||||
}
|
||||
},
|
||||
"neverBuiltDependencies": []
|
||||
},
|
||||
"dependencies": {
|
||||
"@electron-toolkit/tsconfig": "1.0.1",
|
||||
@ -242,12 +242,12 @@
|
||||
"@ffmpeg.wasm/main": "0.12.0",
|
||||
"@floating-ui/dom": "1.6.13",
|
||||
"@foobar404/wave": "2.0.5",
|
||||
"@ghostery/adblocker-electron": "2.3.1",
|
||||
"@ghostery/adblocker-electron-preload": "2.3.1",
|
||||
"@hono/node-server": "1.13.7",
|
||||
"@ghostery/adblocker-electron": "2.5.0",
|
||||
"@ghostery/adblocker-electron-preload": "2.5.0",
|
||||
"@hono/node-server": "1.13.8",
|
||||
"@hono/swagger-ui": "0.5.0",
|
||||
"@hono/zod-openapi": "0.18.3",
|
||||
"@hono/zod-validator": "0.4.2",
|
||||
"@hono/zod-openapi": "0.19.0",
|
||||
"@hono/zod-validator": "0.4.3",
|
||||
"@jellybrick/dbus-next": "0.10.3",
|
||||
"@jellybrick/electron-better-web-request": "1.0.4",
|
||||
"@jellybrick/mpris-service": "2.1.5",
|
||||
@ -255,87 +255,85 @@
|
||||
"@skyra/jaro-winkler": "1.1.1",
|
||||
"@xhayper/discord-rpc": "1.2.0",
|
||||
"async-mutex": "0.5.0",
|
||||
"bgutils-js": "3.1.2",
|
||||
"bgutils-js": "3.1.3",
|
||||
"butterchurn": "3.0.0-beta.4",
|
||||
"butterchurn-presets": "3.0.0-beta.4",
|
||||
"color": "4.2.3",
|
||||
"color": "5.0.0",
|
||||
"conf": "13.1.0",
|
||||
"custom-electron-prompt": "1.5.8",
|
||||
"deepmerge-ts": "7.1.3",
|
||||
"deepmerge-ts": "7.1.5",
|
||||
"electron-debug": "4.1.0",
|
||||
"electron-is": "3.0.0",
|
||||
"electron-localshortcut": "3.2.1",
|
||||
"electron-store": "10.0.0",
|
||||
"electron-store": "10.0.1",
|
||||
"electron-unhandled": "4.0.1",
|
||||
"electron-updater": "6.3.9",
|
||||
"fast-average-color": "9.4.0",
|
||||
"fast-equals": "5.2.2",
|
||||
"filenamify": "6.0.0",
|
||||
"happy-dom": "16.6.0",
|
||||
"hono": "4.6.16",
|
||||
"happy-dom": "17.1.8",
|
||||
"hono": "4.7.2",
|
||||
"howler": "2.2.4",
|
||||
"html-to-text": "9.0.5",
|
||||
"i18next": "24.2.1",
|
||||
"i18next": "24.2.2",
|
||||
"jimp": "1.6.0",
|
||||
"keyboardevent-from-electron-accelerator": "2.0.0",
|
||||
"keyboardevents-areequal": "0.2.2",
|
||||
"node-html-parser": "7.0.1",
|
||||
"node-id3": "0.2.6",
|
||||
"node-id3": "0.2.8",
|
||||
"peerjs": "1.5.4",
|
||||
"semver": "7.6.3",
|
||||
"semver": "7.7.1",
|
||||
"serve": "14.2.4",
|
||||
"simple-youtube-age-restriction-bypass": "github:organization/Simple-YouTube-Age-Restriction-Bypass#v2.5.9",
|
||||
"solid-floating-ui": "0.3.1",
|
||||
"solid-js": "1.9.4",
|
||||
"solid-js": "1.9.5",
|
||||
"solid-styled-components": "0.28.5",
|
||||
"solid-transition-group": "0.2.3",
|
||||
"ts-morph": "25.0.0",
|
||||
"solid-transition-group": "0.3.0",
|
||||
"ts-morph": "25.0.1",
|
||||
"vudio": "2.1.1",
|
||||
"x11": "2.3.0",
|
||||
"youtubei.js": "12.2.0",
|
||||
"zod": "3.24.1"
|
||||
"youtubei.js": "13.1.0",
|
||||
"zod": "3.24.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "9.18.0",
|
||||
"@playwright/test": "1.49.1",
|
||||
"@stylistic/eslint-plugin-js": "2.13.0",
|
||||
"@eslint/js": "9.21.0",
|
||||
"@playwright/test": "1.50.1",
|
||||
"@stylistic/eslint-plugin-js": "4.1.0",
|
||||
"@total-typescript/ts-reset": "0.6.1",
|
||||
"@types/color": "4.2.0",
|
||||
"@types/electron-localshortcut": "3.1.3",
|
||||
"@types/eslint__js": "8.42.3",
|
||||
"@types/howler": "2.2.12",
|
||||
"@types/html-to-text": "9.0.4",
|
||||
"@types/semver": "7.5.8",
|
||||
"@types/trusted-types": "2.0.7",
|
||||
"bufferutil": "4.0.9",
|
||||
"builtin-modules": "4.0.0",
|
||||
"builtin-modules": "5.0.0",
|
||||
"cross-env": "7.0.3",
|
||||
"del-cli": "6.0.0",
|
||||
"discord-api-types": "0.37.116",
|
||||
"electron": "34.0.0",
|
||||
"electron-builder": "26.0.0-alpha.9",
|
||||
"electron-builder-squirrel-windows": "26.0.0-alpha.9",
|
||||
"discord-api-types": "0.37.119",
|
||||
"electron": "34.3.0",
|
||||
"electron-builder": "26.0.9",
|
||||
"electron-builder-squirrel-windows": "26.0.9",
|
||||
"electron-devtools-installer": "4.0.0",
|
||||
"electron-vite": "2.3.0",
|
||||
"esbuild": "0.24.2",
|
||||
"eslint": "9.18.0",
|
||||
"eslint-config-prettier": "10.0.1",
|
||||
"electron-vite": "3.0.0",
|
||||
"esbuild": "0.25.0",
|
||||
"eslint": "9.21.0",
|
||||
"eslint-config-prettier": "10.0.2",
|
||||
"eslint-import-resolver-exports": "1.0.0-beta.5",
|
||||
"eslint-import-resolver-typescript": "3.7.0",
|
||||
"eslint-import-resolver-typescript": "3.8.3",
|
||||
"eslint-plugin-import": "2.31.0",
|
||||
"eslint-plugin-prettier": "5.2.2",
|
||||
"eslint-plugin-prettier": "5.2.3",
|
||||
"glob": "11.0.1",
|
||||
"node-gyp": "11.0.0",
|
||||
"playwright": "1.49.1",
|
||||
"rollup": "4.30.1",
|
||||
"node-gyp": "11.1.0",
|
||||
"playwright": "1.50.1",
|
||||
"rollup": "4.34.8",
|
||||
"typescript": "5.7.3",
|
||||
"typescript-eslint": "8.20.0",
|
||||
"typescript-eslint": "8.25.0",
|
||||
"utf-8-validate": "6.0.5",
|
||||
"vite": "6.0.7",
|
||||
"vite-plugin-inspect": "10.0.6",
|
||||
"vite": "6.2.0",
|
||||
"vite-plugin-inspect": "11.0.0",
|
||||
"vite-plugin-resolve": "2.5.2",
|
||||
"vite-plugin-solid": "2.11.0",
|
||||
"ws": "8.18.0"
|
||||
"vite-plugin-solid": "2.11.6",
|
||||
"ws": "8.18.1"
|
||||
},
|
||||
"auto-changelog": {
|
||||
"hideCredit": true,
|
||||
|
||||
@ -1,21 +0,0 @@
|
||||
diff --git a/out/targets/snap.js b/out/targets/snap.js
|
||||
index f72c36355d27cd2d69fc5fdf2d8bb2451db0287f..baae112fe25ebb49ab8e25aaa48efd6bc43b598f 100644
|
||||
--- a/out/targets/snap.js
|
||||
+++ b/out/targets/snap.js
|
||||
@@ -212,14 +212,14 @@ class SnapTarget extends core_1.Target {
|
||||
args.push("--template-url", `electron4:${snapArch}`);
|
||||
}
|
||||
await (0, builder_util_1.executeAppBuilder)(args);
|
||||
- const publishConfig = findSnapPublishConfig(this.packager.config);
|
||||
+
|
||||
await packager.info.callArtifactBuildCompleted({
|
||||
file: artifactPath,
|
||||
safeArtifactName: packager.computeSafeArtifactName(artifactName, "snap", arch, false),
|
||||
target: this,
|
||||
arch,
|
||||
packager,
|
||||
- publishConfig: publishConfig == null ? { provider: "snapStore" } : publishConfig,
|
||||
+ publishConfig: options.publish == null ? { provider: "snapStore" } : null,
|
||||
});
|
||||
}
|
||||
isElectronVersionGreaterOrEqualThan(version) {
|
||||
3630
pnpm-lock.yaml
generated
3630
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -1,8 +1,6 @@
|
||||
{
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"extends": [
|
||||
"config:base"
|
||||
],
|
||||
"extends": ["config:recommended"],
|
||||
"labels": ["dependencies"],
|
||||
"postUpdateOptions": ["pnpmDedupe"]
|
||||
}
|
||||
|
||||
@ -279,6 +279,13 @@
|
||||
},
|
||||
"name": "الوضع المحيطي"
|
||||
},
|
||||
"amuse": {
|
||||
"description": "تكامل دعم YouTube Music مع ويدجت Amuse لعرض الأغنية قيد التشغيل، من إنتاج 6K Labs",
|
||||
"name": "تلسيه",
|
||||
"response": {
|
||||
"query": "خادم Amuse API قيد التشغيل. استخدم GET /query للحصول على معلومات الأغنية."
|
||||
}
|
||||
},
|
||||
"api-server": {
|
||||
"description": "يضيف خادم للتحكم في المشغل",
|
||||
"dialog": {
|
||||
@ -286,17 +293,38 @@
|
||||
"buttons": {
|
||||
"allow": "سماح",
|
||||
"deny": "رفض"
|
||||
}
|
||||
},
|
||||
"message": "السماح لـ {{ID}} ({{origin}}) بالوصول إلى واجهة برمجة التطبيقات (API)؟",
|
||||
"title": "طلب السماح بالوصول إلى واجهة برمجة التطبيقات(API)"
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"auth-strategy": {
|
||||
"label": "نهج التفويض",
|
||||
"submenu": {
|
||||
"auth-at-first": {
|
||||
"label": "التفويض المبدئي عند الطلب الأول"
|
||||
},
|
||||
"none": {
|
||||
"label": "بدون تفويض"
|
||||
}
|
||||
}
|
||||
},
|
||||
"hostname": {
|
||||
"label": "اسم المضيف"
|
||||
},
|
||||
"port": {
|
||||
"label": "المنفذ"
|
||||
}
|
||||
},
|
||||
"name": "خادم API [تجريبي]",
|
||||
"prompt": {
|
||||
"hostname": {
|
||||
"label": "أدخل اسم المضيف (مثل 0.0.0.0) لخادم API:",
|
||||
"title": "اسم الخادم"
|
||||
},
|
||||
"port": {
|
||||
"label": "أدخل المنفذ لخادم API:"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@ -279,6 +279,9 @@
|
||||
},
|
||||
"name": "Ambientní režim"
|
||||
},
|
||||
"amuse": {
|
||||
"description": "Přídá YouTube Music podporu pro Amuse právě těď hraje widget od 6k Labs"
|
||||
},
|
||||
"api-server": {
|
||||
"description": "Vlož API server abys mohl ovládat přehrávač",
|
||||
"dialog": {
|
||||
|
||||
315
src/i18n/resources/da.json
Normal file
315
src/i18n/resources/da.json
Normal file
@ -0,0 +1,315 @@
|
||||
{
|
||||
"common": {
|
||||
"console": {
|
||||
"plugins": {
|
||||
"execute-failed": "Fejl ved udføring af plugin {{pluginName}}::{{contextName}}",
|
||||
"executed-at-ms": "Plugin {{pluginName}}::{{contextName}} udført på {{ms}}ms",
|
||||
"initialize-failed": "Fejl ved igangsætning af plugin \"{{pluginName}}\"",
|
||||
"load-all": "Indlæser alle plugins",
|
||||
"load-failed": "Fejl ved indlæsning af plugin \"{{pluginName}}\"",
|
||||
"loaded": "Plugin \"{{pluginName}}\" indlæst",
|
||||
"unload-failed": "Fejl ved unload af plugin \"{{pluginName}}\""
|
||||
}
|
||||
}
|
||||
},
|
||||
"language": {
|
||||
"code": "dk",
|
||||
"local-name": "Dansk",
|
||||
"name": "Danish"
|
||||
},
|
||||
"main": {
|
||||
"console": {
|
||||
"did-finish-load": {
|
||||
"dev-tools": "Indlæsning færdig. DevTools åbnet"
|
||||
},
|
||||
"i18n": {
|
||||
"loaded": "i18n indlæst"
|
||||
},
|
||||
"second-instance": {
|
||||
"receive-command": "Modtog kommando over protokol: \"{{command}}\""
|
||||
},
|
||||
"theme": {
|
||||
"css-file-not-found": "CSS fil \"{{cssFile}}\" eksisterer ikke, ignorere"
|
||||
},
|
||||
"unresponsive": {
|
||||
"details": "Uresponsiv fejl!\n{{error}}"
|
||||
},
|
||||
"when-ready": {
|
||||
"clearing-cache-after-20s": "Rydder op i appens cache"
|
||||
},
|
||||
"window": {
|
||||
"tried-to-render-offscreen": "Windows forsøgte at indlæse uden for skærmen, windowSize={{windowSize}}, displaySize={{displaySize}}, position={{position}}"
|
||||
}
|
||||
},
|
||||
"dialog": {
|
||||
"hide-menu-enabled": {
|
||||
"detail": "Menuen er gemt, brug 'Alt' knappen for at vise den igen (eller 'Escape' hvis In-App menuen bruges)",
|
||||
"message": "Skjul menuen er aktiveret",
|
||||
"title": "Skjult menu aktiveret"
|
||||
},
|
||||
"need-to-restart": {
|
||||
"buttons": {
|
||||
"later": "Senere",
|
||||
"restart-now": "Genstart nu"
|
||||
},
|
||||
"detail": "\"{{pluginName}}\" plugin kræver en genstart for at have en effekt",
|
||||
"message": "\"{{pluginName}}\" skal genstarte",
|
||||
"title": "Genstart krævet"
|
||||
},
|
||||
"unresponsive": {
|
||||
"buttons": {
|
||||
"quit": "Afslut",
|
||||
"relaunch": "Genåben",
|
||||
"wait": "Vent"
|
||||
},
|
||||
"detail": "Vi undskylder for ubelejligheden! Vælg næste handling:",
|
||||
"message": "Appen svarer ikke",
|
||||
"title": "Vindue svarer ikke"
|
||||
},
|
||||
"update-available": {
|
||||
"buttons": {
|
||||
"disable": "Slå opdateringer fra",
|
||||
"download": "Hent",
|
||||
"ok": "OK"
|
||||
},
|
||||
"detail": "En ny version er tilgængelig og kan downloades her: {{downloadLink}}",
|
||||
"message": "En ny version er tilgængelig",
|
||||
"title": "Opdatering tilgængelig"
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"about": "Om",
|
||||
"navigation": {
|
||||
"label": "Navigering",
|
||||
"submenu": {
|
||||
"copy-current-url": "Kopier nuværende URL",
|
||||
"go-back": "Tilbage",
|
||||
"go-forward": "Frem",
|
||||
"quit": "Afslut",
|
||||
"restart": "Genstart Appen"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"label": "Indstillinger",
|
||||
"submenu": {
|
||||
"advanced-options": {
|
||||
"label": "Avancerede indstillinger",
|
||||
"submenu": {
|
||||
"auto-reset-app-cache": "Nulstil app cache når appen starter",
|
||||
"disable-hardware-acceleration": "Deaktiver hardware acceleration",
|
||||
"edit-config-json": "Rediger config.json",
|
||||
"restart-on-config-changes": "Genstart ved config ændringer",
|
||||
"set-proxy": {
|
||||
"label": "Indstil proxy",
|
||||
"prompt": {
|
||||
"label": "Skriv proxy adresse: (Efterlad tom for at deaktivere)",
|
||||
"placeholder": "Eksempel: SOCKS5://127.0.0.1:9999",
|
||||
"title": "Sæt proxy"
|
||||
}
|
||||
},
|
||||
"toggle-dev-tools": "Skift DevTools"
|
||||
}
|
||||
},
|
||||
"always-on-top": "Altid øverst",
|
||||
"auto-update": "Automatisk opdatering",
|
||||
"hide-menu": {
|
||||
"dialog": {
|
||||
"message": "Menuen vil være lukket næste gang appen starter. Brug [Alt] for at vise den (Eller backtick [`] hvis in-app-menu bruges)",
|
||||
"title": "Gemt menu aktiveret"
|
||||
},
|
||||
"label": "Skjul menu"
|
||||
},
|
||||
"language": {
|
||||
"dialog": {
|
||||
"message": "Sproget vil blive ændret efter genstart",
|
||||
"title": "Sprog ændret"
|
||||
},
|
||||
"label": "Sprog",
|
||||
"submenu": {
|
||||
"to-help-translate": "Vil du hjælpe med at oversætte? Klik her"
|
||||
}
|
||||
},
|
||||
"resume-on-start": "Genoptag sidste sang når appen starter",
|
||||
"start-at-login": "Start ved login",
|
||||
"starting-page": {
|
||||
"label": "Startside",
|
||||
"unset": "Ikke valgt"
|
||||
},
|
||||
"tray": {
|
||||
"submenu": {
|
||||
"disabled": "Deaktiveret",
|
||||
"enabled-and-show-app": "Aktiver og vis app",
|
||||
"play-pause-on-click": "Start/Stop ved klik"
|
||||
}
|
||||
},
|
||||
"visual-tweaks": {
|
||||
"submenu": {
|
||||
"like-buttons": {
|
||||
"default": "Standard",
|
||||
"hide": "Skjul",
|
||||
"label": "Like knapper"
|
||||
},
|
||||
"remove-upgrade-button": "Fjern opgrader knappen",
|
||||
"theme": {
|
||||
"dialog": {
|
||||
"button": {
|
||||
"remove": "Fjern"
|
||||
}
|
||||
},
|
||||
"label": "Tema",
|
||||
"submenu": {
|
||||
"no-theme": "Intet tema"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"enabled": "Aktiveret",
|
||||
"label": "Plugins",
|
||||
"new": "NY"
|
||||
},
|
||||
"view": {
|
||||
"label": "Vis",
|
||||
"submenu": {
|
||||
"reload": "Genindlæs",
|
||||
"zoom-in": "Zoom ind",
|
||||
"zoom-out": "Zoom ud"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tray": {
|
||||
"next": "Næste",
|
||||
"play-pause": "Afspil",
|
||||
"previous": "Sidste",
|
||||
"quit": "Luk",
|
||||
"restart": "Genstart app",
|
||||
"show": "Vis vindue",
|
||||
"tooltip": {
|
||||
"default": "YouTube Music",
|
||||
"with-song-info": "YouTube Music: {{artist}} - {{title}}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"ad-speedup": {
|
||||
"description": "Hvis en reklame afspilles, slår den lyden fra og sætter hastigheden til 16x",
|
||||
"name": "Spol igennem reklamen"
|
||||
},
|
||||
"adblocker": {
|
||||
"description": "Bloker alle reklamer og sporing fra starten af",
|
||||
"menu": {
|
||||
"blocker": "Bloker"
|
||||
},
|
||||
"name": "Bloker reklamer"
|
||||
},
|
||||
"album-color-theme": {
|
||||
"menu": {
|
||||
"color-mix-ratio": {
|
||||
"submenu": {
|
||||
"percent": "{{ratio}}%"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Albummets farve tema"
|
||||
},
|
||||
"ambient-mode": {
|
||||
"menu": {
|
||||
"blur-amount": {
|
||||
"label": "Sløringsmængde",
|
||||
"submenu": {
|
||||
"pixels": "{{blurAmount}} pixel"
|
||||
}
|
||||
},
|
||||
"buffer": {
|
||||
"label": "Buffer",
|
||||
"submenu": {
|
||||
"buffer": "{{buffer}}"
|
||||
}
|
||||
},
|
||||
"opacity": {
|
||||
"label": "Gennemsigtighed",
|
||||
"submenu": {
|
||||
"percent": "{{opacity}}%"
|
||||
}
|
||||
},
|
||||
"quality": {
|
||||
"label": "Kvalitet",
|
||||
"submenu": {
|
||||
"pixels": "{{quality}} pixel"
|
||||
}
|
||||
},
|
||||
"size": {
|
||||
"label": "Størrelse",
|
||||
"submenu": {
|
||||
"percent": "{{size}}%"
|
||||
}
|
||||
},
|
||||
"use-fullscreen": {
|
||||
"label": "Bruger fuldskærm"
|
||||
}
|
||||
}
|
||||
},
|
||||
"api-server": {
|
||||
"dialog": {
|
||||
"request": {
|
||||
"buttons": {
|
||||
"allow": "Tillad",
|
||||
"deny": "Afvis"
|
||||
},
|
||||
"message": "Tillad at {{ID}} ({{origin}}) får adgang til API'en?"
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"auth-strategy": {
|
||||
"label": "Godkendelsesstrategi"
|
||||
},
|
||||
"hostname": {
|
||||
"label": "Hostname"
|
||||
},
|
||||
"port": {
|
||||
"label": "Port"
|
||||
}
|
||||
},
|
||||
"name": "API Server [Beta]",
|
||||
"prompt": {
|
||||
"hostname": {
|
||||
"label": "Skriv API serverens hostname (f. eks. 0.0.0.0):",
|
||||
"title": "Hostname"
|
||||
},
|
||||
"port": {
|
||||
"label": "Skriv API serverens port:",
|
||||
"title": "Port"
|
||||
}
|
||||
}
|
||||
},
|
||||
"audio-compressor": {
|
||||
"name": "Lyd kompressor"
|
||||
},
|
||||
"blur-nav-bar": {
|
||||
"description": "Gør navigationsbaren gennemsigtig og sløret",
|
||||
"name": "Slør navigationsbar"
|
||||
},
|
||||
"captions-selector": {
|
||||
"menu": {
|
||||
"disable-captions": "Ingen undertekster som standard"
|
||||
},
|
||||
"name": "Vælg undertekster",
|
||||
"prompt": {
|
||||
"selector": {
|
||||
"label": "Nuværende sprog på undertekster: {{language}}",
|
||||
"none": "Ingen",
|
||||
"title": "Vælg underteksternes sprog"
|
||||
}
|
||||
}
|
||||
},
|
||||
"crossfade": {
|
||||
"description": "Fade imellem sange",
|
||||
"menu": {
|
||||
"advanced": "Avanceret"
|
||||
},
|
||||
"name": "Fade [Beta]"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -745,7 +745,8 @@
|
||||
"label": "Efecto de la línea",
|
||||
"submenu": {
|
||||
"fancy": {
|
||||
"label": "Elegante"
|
||||
"label": "Elegante",
|
||||
"tooltip": "Usar efectos grandes, similares a los de una aplicación, en la línea actual"
|
||||
},
|
||||
"focus": {
|
||||
"label": "Enfoque",
|
||||
|
||||
@ -81,12 +81,12 @@
|
||||
"menu": {
|
||||
"about": "درباره",
|
||||
"navigation": {
|
||||
"label": "ناوبری",
|
||||
"label": "کنترلهای رابط",
|
||||
"submenu": {
|
||||
"copy-current-url": "کپی کردن URL فعلی",
|
||||
"go-back": "بازگشت",
|
||||
"go-forward": "حرکت به جلو",
|
||||
"quit": "خروجی",
|
||||
"copy-current-url": "کپی کردن لینک صفحه فعلی",
|
||||
"go-back": "صفحه قبل",
|
||||
"go-forward": "صفحه بعدی",
|
||||
"quit": "خروج از برنامه",
|
||||
"restart": "راهاندازی مجدد برنامه"
|
||||
}
|
||||
},
|
||||
@ -98,8 +98,8 @@
|
||||
"submenu": {
|
||||
"auto-reset-app-cache": "ریست کردن حافظه کش برنامه هنگام شروع",
|
||||
"disable-hardware-acceleration": "غیرفعال کردن شتاب سختافزاری",
|
||||
"edit-config-json": "ویرایش config.json",
|
||||
"override-user-agent": "تغییر User-Agent",
|
||||
"edit-config-json": "config.json ویرایش",
|
||||
"override-user-agent": "User-Agent تغییر",
|
||||
"restart-on-config-changes": "راهاندازی مجدد در صورت تغییرات در پیکربندی",
|
||||
"set-proxy": {
|
||||
"label": "تنظیم پراکسی",
|
||||
@ -109,7 +109,7 @@
|
||||
"title": "تنظیم پراکسی"
|
||||
}
|
||||
},
|
||||
"toggle-dev-tools": "باز کردن DevTools"
|
||||
"toggle-dev-tools": "DevTools باز کردن"
|
||||
}
|
||||
},
|
||||
"always-on-top": "همیشه در بالا",
|
||||
@ -168,7 +168,7 @@
|
||||
},
|
||||
"label": "تم",
|
||||
"submenu": {
|
||||
"import-css-file": "وارد کردن فایل CSS سفارشی",
|
||||
"import-css-file": "سفارشی CSS وارد کردن فایل",
|
||||
"no-theme": "بدون تم"
|
||||
}
|
||||
}
|
||||
@ -177,7 +177,7 @@
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"enabled": "فعال",
|
||||
"enabled": "فعال/غیرفعال کردن",
|
||||
"label": "افزونهها",
|
||||
"new": "جدید"
|
||||
},
|
||||
@ -187,7 +187,7 @@
|
||||
"force-reload": "اجبار به بارگذاری مجدد",
|
||||
"reload": "بارگذاری مجدد",
|
||||
"reset-zoom": "اندازه واقعی",
|
||||
"toggle-fullscreen": "تغییر به تمامصفحه",
|
||||
"toggle-fullscreen": "تغییر به تمام صفحه",
|
||||
"zoom-in": "بزرگنمایی",
|
||||
"zoom-out": "کوچکنمایی"
|
||||
}
|
||||
@ -219,7 +219,7 @@
|
||||
"name": "مسدودکننده تبلیغات"
|
||||
},
|
||||
"album-actions": {
|
||||
"description": "افزودن دکمههای \"برگرفتن ناپسند\"، \"ناپسند\"، \"پسند\"، و \"حذف پسند\" برای اعمال آنها روی همه آهنگها در یک فهرست پخش یا آلبوم",
|
||||
"description": "اضافه کردن دکمههای عدم پسندیدن، پسندیدن و لغو پسندیدن برای اعمال این تغییرات به تمامی آهنگهای یک فهرست پخش یا آلبوم",
|
||||
"name": "عملیات آلبوم"
|
||||
},
|
||||
"album-color-theme": {
|
||||
@ -250,7 +250,10 @@
|
||||
}
|
||||
},
|
||||
"opacity": {
|
||||
"label": "شفافیت"
|
||||
"label": "شفافیت",
|
||||
"submenu": {
|
||||
"percent": "{{opacity}}%"
|
||||
}
|
||||
},
|
||||
"quality": {
|
||||
"label": "کیفیت",
|
||||
@ -259,7 +262,10 @@
|
||||
}
|
||||
},
|
||||
"size": {
|
||||
"label": "اندازه"
|
||||
"label": "اندازه",
|
||||
"submenu": {
|
||||
"percent": "{{size}}%"
|
||||
}
|
||||
},
|
||||
"smoothness-transition": {
|
||||
"label": "انتقال نرمی",
|
||||
@ -273,8 +279,15 @@
|
||||
},
|
||||
"name": "حالت محیطی"
|
||||
},
|
||||
"amuse": {
|
||||
"description": "حالا ویجت Amuse از YouTube Music هم پشتیبانی میکنه! (توسط 6K Labs)",
|
||||
"name": "Amuse",
|
||||
"response": {
|
||||
"query": "سرور Amuse فعال است. برای دریافت اطلاعات آهنگ، از آدرس /query استفاده کنید."
|
||||
}
|
||||
},
|
||||
"api-server": {
|
||||
"description": "افزودن یک سرور API برای کنترل پخشکننده",
|
||||
"description": "برای کنترل پخشکننده API افزودن یک سرور",
|
||||
"dialog": {
|
||||
"request": {
|
||||
"buttons": {
|
||||
@ -304,14 +317,14 @@
|
||||
"label": "پورت"
|
||||
}
|
||||
},
|
||||
"name": "سرور API [بتا]",
|
||||
"name": "[بتا]API سرور",
|
||||
"prompt": {
|
||||
"hostname": {
|
||||
"label": "نام میزبان را برای سرور API وارد کنید (مثل 0.0.0.0):",
|
||||
"label": "وارد کنید (مثل 0.0.0.0): API نام میزبان را برای سرور",
|
||||
"title": "نام میزبان"
|
||||
},
|
||||
"port": {
|
||||
"label": "پورت را برای سرور API وارد کنید:",
|
||||
"label": "وارد کنید: API پورت را برای سرور",
|
||||
"title": "پورت"
|
||||
}
|
||||
}
|
||||
@ -321,8 +334,8 @@
|
||||
"name": "فشردهساز صدا"
|
||||
},
|
||||
"blur-nav-bar": {
|
||||
"description": "شفاف و محو کردن نوار ناوبری",
|
||||
"name": "محو کردن نوار ناوبری"
|
||||
"description": "شفاف و محو کردن نوار کنترل",
|
||||
"name": "محو کردن نوار کنترل"
|
||||
},
|
||||
"bypass-age-restrictions": {
|
||||
"description": "دور زدن تأیید سن یوتیوب",
|
||||
@ -381,27 +394,27 @@
|
||||
},
|
||||
"discord": {
|
||||
"backend": {
|
||||
"already-connected": "تلاش برای اتصال با اتصال فعال",
|
||||
"connected": "متصل به Discord",
|
||||
"disconnected": "قطع اتصال از Discord"
|
||||
"already-connected": "تلاش برای برقراری ارتباط با اتصال فعال",
|
||||
"connected": "متصل به دیسکورد",
|
||||
"disconnected": "ارتباط با دیسکورد قطع شد"
|
||||
},
|
||||
"description": "نمایش آنچه گوش میدهید به دوستان با Rich Presence",
|
||||
"description": "Rich Presence نمایش آنچه گوش میدهید به دوستان با",
|
||||
"menu": {
|
||||
"auto-reconnect": "اتصال خودکار مجدد",
|
||||
"auto-reconnect": "اتصال خودکار",
|
||||
"clear-activity": "پاک کردن فعالیت",
|
||||
"clear-activity-after-timeout": "پاک کردن فعالیت پس از تایماوت",
|
||||
"connected": "متصل",
|
||||
"disconnected": "قطع شده",
|
||||
"clear-activity-after-timeout": "حذف فعالیت پس از اتمام زمان تعیینشده",
|
||||
"connected": "اتصال برقرار شد",
|
||||
"disconnected": "اتصال قطع شد",
|
||||
"hide-duration-left": "مخفی کردن مدت زمان باقیمانده",
|
||||
"hide-github-button": "مخفی کردن دکمه لینک GitHub",
|
||||
"play-on-youtube-music": "پخش در یوتیوب موسیقی",
|
||||
"set-inactivity-timeout": "تنظیم تایماوت عدم فعالیت"
|
||||
"hide-github-button": "مخفی کردن دکمه لینک گیت هاب",
|
||||
"play-on-youtube-music": "پخش در یوتیوب موزیک",
|
||||
"set-inactivity-timeout": "تنظیم زمان عدم فعالیت"
|
||||
},
|
||||
"name": "Rich Presence در Discord",
|
||||
"name": "Discord Rich Presence",
|
||||
"prompt": {
|
||||
"set-inactivity-timeout": {
|
||||
"label": "ورود تایماوت عدم فعالیت به ثانیه:",
|
||||
"title": "تنظیم تایماوت عدم فعالیت"
|
||||
"label": "محدودیت زمان عدم فعالیت را به ثانیه وارد کنید:",
|
||||
"title": "تنظیم زمان عدم فعالیت"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -478,6 +491,18 @@
|
||||
"button": "دانلود"
|
||||
}
|
||||
},
|
||||
"equalizer": {
|
||||
"description": "اضافه کردن یک اکولایزر به پخشکننده",
|
||||
"menu": {
|
||||
"presets": {
|
||||
"label": "تنظیمات از پیش تعیین شده",
|
||||
"list": {
|
||||
"bass-booster": "تقویتکننده باس صدا"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "اکولایزر"
|
||||
},
|
||||
"exponential-volume": {
|
||||
"description": "نوار لغزنده حجم را به صورت نمایی میسازد تا انتخاب حجمهای پایینتر آسانتر شود.",
|
||||
"name": "حجم نمایی"
|
||||
@ -490,17 +515,17 @@
|
||||
"name": "منوی داخل برنامه"
|
||||
},
|
||||
"lumiastream": {
|
||||
"description": "افزودن پشتیبانی از Lumia Stream",
|
||||
"description": "Lumia Stream افزودن پشتیبانی از",
|
||||
"name": "Lumia Stream [بتا]"
|
||||
},
|
||||
"lyrics-genius": {
|
||||
"description": "افزودن پشتیبانی از متن آهنگ برای بیشتر آهنگها",
|
||||
"description": "افزودن متن ترانه پشتیبان برای اکثر ترانه ها",
|
||||
"menu": {
|
||||
"romanized-lyrics": "متن رومیشده"
|
||||
"romanized-lyrics": "الفبای لاتین برای آهنگهایی با الفبای شرقی (فینگلیش)"
|
||||
},
|
||||
"name": "متن آهنگ Genius",
|
||||
"name": "Genius متن آهنگ",
|
||||
"renderer": {
|
||||
"fetched-lyrics": "متن آهنگ از Genius بازیابی شد"
|
||||
"fetched-lyrics": "بازیابی شد Genius متن ترانه توسط"
|
||||
}
|
||||
},
|
||||
"music-together": {
|
||||
@ -536,13 +561,13 @@
|
||||
"name": "Music Together [بتا]",
|
||||
"toast": {
|
||||
"add-song-failed": "افزودن آهنگ با شکست مواجه شد",
|
||||
"closed": "Music Together بسته شد",
|
||||
"disconnected": "قطع اتصال Music Together",
|
||||
"host-failed": "میزبانی Music Together با شکست مواجه شد",
|
||||
"closed": "بسته شد Music Together",
|
||||
"disconnected": "Music Together قطع اتصال",
|
||||
"host-failed": "با شکست مواجه شد Music Together میزبانی",
|
||||
"id-copied": "شناسه میزبان به کلیپبورد کپی شد",
|
||||
"id-copy-failed": "کپی شناسه میزبان به کلیپبورد با شکست مواجه شد",
|
||||
"join-failed": "پیوستن به Music Together با شکست مواجه شد",
|
||||
"joined": "به Music Together پیوست",
|
||||
"join-failed": "با شکست مواجه شد Music Together پیوستن به",
|
||||
"joined": "پیوست Music Together به",
|
||||
"permission-changed": "مجوز Music Together به \"{{permission}}\" تغییر یافت",
|
||||
"remove-song-failed": "حذف آهنگ با شکست مواجه شد",
|
||||
"user-connected": "{{name}} به Music Together پیوست",
|
||||
@ -551,11 +576,11 @@
|
||||
},
|
||||
"navigation": {
|
||||
"description": "بعدی/قبلی به طور مستقیم در رابط یکپارچه شدهاند، مانند مرورگر مورد علاقه شما",
|
||||
"name": "ناوبری"
|
||||
"name": "کنترل های رابط"
|
||||
},
|
||||
"no-google-login": {
|
||||
"description": "حذف دکمههای ورود به سیستم Google و لینکها از رابط",
|
||||
"name": "بدون ورود به Google"
|
||||
"description": "حذف دکمهها و لینکهای ورود به گوگل از رابط کاربری",
|
||||
"name": "بدون ورود به گوگل"
|
||||
},
|
||||
"notifications": {
|
||||
"description": "نمایش اعلان هنگامی که آهنگی شروع به پخش میکند (اعلانهای تعاملی در ویندوز در دسترس هستند)",
|
||||
@ -566,11 +591,11 @@
|
||||
"submenu": {
|
||||
"hide-button-text": "مخفی کردن متن دکمه",
|
||||
"refresh-on-play-pause": "تازهسازی در پخش/توقف",
|
||||
"tray-controls": "باز/بسته شدن با کلیک روی سینی"
|
||||
"tray-controls": "باز/بسته شدن با کلیک روی آیکون در نوار وظیفه"
|
||||
}
|
||||
},
|
||||
"priority": "اولویت اعلان",
|
||||
"toast-style": "سبک Toast",
|
||||
"toast-style": "Toast سبک",
|
||||
"unpause-notification": "نمایش اعلان هنگام از سرگیری پخش"
|
||||
},
|
||||
"name": "اعلانها"
|
||||
@ -578,8 +603,234 @@
|
||||
"picture-in-picture": {
|
||||
"description": "اجازه میدهد تا برنامه به حالت تصویر در تصویر تغییر کند",
|
||||
"menu": {
|
||||
"always-on-top": "همیشه در بالا"
|
||||
"always-on-top": "همیشه در بالا",
|
||||
"hotkey": {
|
||||
"label": "کلید میانبر",
|
||||
"prompt": {
|
||||
"keybind-options": {
|
||||
"hotkey": "کلید میانبر"
|
||||
},
|
||||
"label": "یک کلید میانبر انتخاب کنید برای فعال/غیرفعال کردن حالت تصویر در تصویر",
|
||||
"title": "کلید میانبر برای حالت تصویر در تصویر"
|
||||
}
|
||||
},
|
||||
"save-window-position": "ذخیره موقعیت پنجره",
|
||||
"save-window-size": "ذخیره اندازه پنجره",
|
||||
"use-native-pip": "استفاده از حالت تصویر در تصویر اصلی مرورگر"
|
||||
},
|
||||
"name": "تصویر در تصویر",
|
||||
"templates": {
|
||||
"button": "تصویر در تصویر"
|
||||
}
|
||||
},
|
||||
"playback-speed": {
|
||||
"description": "به سرعت گوش بده، به آرامی گوش بده! یک دکمه کشویی برای تنظیم سرعت آهنگ اضافه شد",
|
||||
"name": "سرعت پخش",
|
||||
"templates": {
|
||||
"button": "سرعت"
|
||||
}
|
||||
},
|
||||
"precise-volume": {
|
||||
"description": "کنترل دقیق صدا با استفاده از چرخ موس/میانبرها، همراه با HUD سفارشی و مراحل تنظیم حجم قابل تنظیم",
|
||||
"menu": {
|
||||
"arrows-shortcuts": "میانبرهای کلیدهای فلشی",
|
||||
"custom-volume-steps": "مراحل تنظیم صدای دلخواه",
|
||||
"global-shortcuts": "کلید های میانبر جهانی"
|
||||
},
|
||||
"name": "صدای دقیق",
|
||||
"prompt": {
|
||||
"global-shortcuts": {
|
||||
"keybind-options": {
|
||||
"decrease": "کاهش صدا",
|
||||
"increase": "افزایش صدا"
|
||||
},
|
||||
"label": "انتخاب کلیدهای میانبر سراسری صدا:",
|
||||
"title": "میانبرهای کلید سراسری صدا"
|
||||
},
|
||||
"volume-steps": {
|
||||
"label": "مراحل انتخاب افزایش/کاهش صدا",
|
||||
"title": "سطح صدا"
|
||||
}
|
||||
}
|
||||
},
|
||||
"quality-changer": {
|
||||
"backend": {
|
||||
"dialog": {
|
||||
"quality-changer": {
|
||||
"detail": "کیفیت کنونی: {{quality}}",
|
||||
"message": "انتخاب کیفیت ویدیو:",
|
||||
"title": "انتخاب کیفیت ویدیو"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "امکان تغییر کیفیت ویدیو با استفاده از دکمه در رابط پخش ویدیو",
|
||||
"name": "تغییر دهنده کیفیت ویدیو"
|
||||
},
|
||||
"scrobbler": {
|
||||
"description": "اضافه کردن پشتیبانی از اسکرابلینگ (etc. last.fm, Listenbrainz)",
|
||||
"dialog": {
|
||||
"lastfm": {
|
||||
"auth-failed": {
|
||||
"message": "احراز هویت با Last.fm ناموفق بود\nپنجره شناور را تا راهاندازی مجدد بعدی مخفی کن.",
|
||||
"title": "احراز هویت ناموفق بود"
|
||||
}
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"lastfm": {
|
||||
"api-settings": "تنظیمات \"Last.fm \"API"
|
||||
},
|
||||
"listenbrainz": {
|
||||
"token": "توکن کاربری ListenBrainz را وارد کنید"
|
||||
},
|
||||
"scrobble-other-media": "ردیابی رسانههای دیگر"
|
||||
},
|
||||
"name": "ابزار ثبتکنندهی آهنگ",
|
||||
"prompt": {
|
||||
"lastfm": {
|
||||
"api-key": "کلید Last.fm API",
|
||||
"api-secret": "API مخفی Last.fm"
|
||||
},
|
||||
"listenbrainz": {
|
||||
"token": {
|
||||
"label": "توکن کاربری ListenBrainz خود را وارد کنید:",
|
||||
"title": "توکن ListenBrainz"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"shortcuts": {
|
||||
"description": "امکان تنظیم میانبرهای سراسری برای کنترل (پخش/توقف/بعدی/قبلی) و خاموش کردن OSD رسانه با بازنویسی کلیدهای رسانهای، فعالسازی Ctrl/CMD + F برای جستجو، فعالسازی پشتیبانی MPRIS در لینوکس برای کلیدهای رسانهای، و میانبرهای سفارشی برای کاربران پیشرفته",
|
||||
"menu": {
|
||||
"override-media-keys": "تغییر عملکرد کلیدهای رسانه",
|
||||
"set-keybinds": "تنظیم کنترلهای سراسری آهنگ"
|
||||
},
|
||||
"name": "میانبرها (& MPRIS)",
|
||||
"prompt": {
|
||||
"keybind": {
|
||||
"keybind-options": {
|
||||
"next": "بعدی",
|
||||
"play-pause": "پخش / توقف",
|
||||
"previous": "قبلی"
|
||||
},
|
||||
"label": "انتخاب میانبرهای سراسری برای کنترل آهنگها:",
|
||||
"title": "میانبرهای کلیدی سراسری"
|
||||
}
|
||||
}
|
||||
},
|
||||
"skip-disliked-songs": {
|
||||
"description": "خودکار آهنگ های غیر موردعلاقه رد میشن",
|
||||
"name": "رد آهنگهای غیر مورد علاقه"
|
||||
},
|
||||
"skip-silences": {
|
||||
"description": "رد خودکار بخشهای بی صدا آهنگ ها",
|
||||
"name": "رد بخشهای بیصدا"
|
||||
},
|
||||
"sponsorblock": {
|
||||
"description": "بهطور خودکار بخشهای غیرموسیقی مانند مقدمه/پایان یا قسمتهایی از ویدیوهای موسیقی که آهنگ در آن پخش نمیشود را رد میکند",
|
||||
"name": "مسدودکننده اسپانسر"
|
||||
},
|
||||
"synced-lyrics": {
|
||||
"description": "ارائه متن ترانهها به صورت هماهنگ با آهنگها، با استفاده از ارائهدهندگانی مانند LRClib.",
|
||||
"errors": {
|
||||
"fetch": "⚠️هنگام بارگیری متن ترانه خطایی رخ داده است.\n\tلطفاً بعداً دوباره تلاش کنید.",
|
||||
"not-found": "⚠️ متنی برای این ترانه پیدا نشد."
|
||||
},
|
||||
"menu": {
|
||||
"default-text-string": {
|
||||
"label": "حرف/کاراکتر پیشفرض بین متنهای ترانه",
|
||||
"tooltip": "حرف/کاراکتر پیشفرض را برای فاصله بین متنهای ترانه انتخاب کنید"
|
||||
},
|
||||
"line-effect": {
|
||||
"label": "افکت خط متن",
|
||||
"submenu": {
|
||||
"fancy": {
|
||||
"label": "شیک",
|
||||
"tooltip": "استفاده از افکتهای بزرگ و شبیه به اپلیکیشنها برای خط فعلی"
|
||||
},
|
||||
"focus": {
|
||||
"label": "تمرکز",
|
||||
"tooltip": "فقط خط فعلی رو سفید کن"
|
||||
},
|
||||
"offset": {
|
||||
"label": "جابجایی",
|
||||
"tooltip": "جابجایی خط فعلی به سمت راست"
|
||||
},
|
||||
"scale": {
|
||||
"label": "مقیاس",
|
||||
"tooltip": "تغییر اندازه خط فعلی"
|
||||
}
|
||||
},
|
||||
"tooltip": "افکت مورد نظر را برای خط فعلی انتخاب کنید"
|
||||
},
|
||||
"precise-timing": {
|
||||
"label": "هماهنگسازی کامل متن ترانه",
|
||||
"tooltip": "محاسبه دقیق نمایش خط بعدی تا میلیثانیه (ممکن است تاثیر کمی بر عملکرد داشته باشد)"
|
||||
},
|
||||
"show-lyrics-even-if-inexact": {
|
||||
"label": "نمایش متن ترانه ها حتی اگر دقیق نباشد",
|
||||
"tooltip": "اگر آهنگ پیدا نشد، افزونه دوباره با یک جستجوی متفاوت امتحان میکند.\nنتیجهی این تلاش ممکن است دقیق نباشد."
|
||||
},
|
||||
"show-time-codes": {
|
||||
"label": "نمایش زمانبندیها",
|
||||
"tooltip": "نمایش زمانبندیها کنار متن ترانه"
|
||||
}
|
||||
},
|
||||
"name": "متن ترانه هماهنگ شد",
|
||||
"refetch-btn": {
|
||||
"fetching": "در حال بارگذاری...",
|
||||
"normal": "دریافت مجدد متن ترانه"
|
||||
},
|
||||
"warnings": {
|
||||
"duration-mismatch": "⚠️ - ممکن است متن ترانه به دلیل عدم تطابق زمان با مشکل هماهنگی مواجه شود.",
|
||||
"inexact": "⚠️ - ممکن است متن ترانه برای این آهنگ دقیق نباشد",
|
||||
"instrumental": "⚠️ - این آهنگ بی کلام است"
|
||||
}
|
||||
},
|
||||
"taskbar-mediacontrol": {
|
||||
"description": "کنترل پخش از نوار وظیفه ویندوز(taskbar)",
|
||||
"name": "کنترل رسانه از نوار وظیفه (taskbar)"
|
||||
},
|
||||
"touchbar": {
|
||||
"description": "افزودن ویجت TouchBar برای کاربران macOS",
|
||||
"name": "نوار لمسی"
|
||||
},
|
||||
"tuna-obs": {
|
||||
"description": "ادغام با پلاگین Tuna در OBS",
|
||||
"name": "Tuna OBS"
|
||||
},
|
||||
"video-toggle": {
|
||||
"description": "دکمهای اضافه میکند برای جابجایی بین حالت ویدیو/آهنگ. همچنین به صورت اختیاری میتواند تب ویدیو را حذف کند",
|
||||
"menu": {
|
||||
"align": {
|
||||
"label": "چینش",
|
||||
"submenu": {
|
||||
"left": "چپ",
|
||||
"middle": "میانه",
|
||||
"right": "راست"
|
||||
}
|
||||
},
|
||||
"force-hide": "حذف اجباری تب ویدیو",
|
||||
"mode": {
|
||||
"label": "حالت",
|
||||
"submenu": {
|
||||
"custom": "حالت شخصیسازی شده",
|
||||
"disabled": "غیرفعال",
|
||||
"native": "حالت پیشفرض"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "ویدیو به آهنگ",
|
||||
"templates": {
|
||||
"button": "ترانه"
|
||||
}
|
||||
},
|
||||
"visualizer": {
|
||||
"description": "اضافه کردن نمایشدهنده تصویری به پخشکننده",
|
||||
"menu": {
|
||||
"visualizer-type": "نوع نمایشدهنده تصویری"
|
||||
},
|
||||
"name": "نمایشدهنده تصویری"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -279,6 +279,12 @@
|
||||
},
|
||||
"name": "Ambient Mode"
|
||||
},
|
||||
"amuse": {
|
||||
"description": "Nagdaragdag ng suporta sa YouTube Music para sa Amuse now playing widget ng 6K Labs",
|
||||
"response": {
|
||||
"query": "Tumatakbo ang Amuse API server. Gamitin ang GET /query para makuha ang impo ng kanta."
|
||||
}
|
||||
},
|
||||
"api-server": {
|
||||
"description": "Nagdadagdag ng API Server upang kontrolin ang player",
|
||||
"dialog": {
|
||||
@ -468,6 +474,14 @@
|
||||
"button": "Mag-download"
|
||||
}
|
||||
},
|
||||
"equalizer": {
|
||||
"description": "Nagdaragdag ng equalizer sa player",
|
||||
"menu": {
|
||||
"presets": {
|
||||
"label": "Mga Preset"
|
||||
}
|
||||
}
|
||||
},
|
||||
"exponential-volume": {
|
||||
"description": "Ginagawang exponential ang volume slider para mas madaling pumili ng mas mababang volume."
|
||||
},
|
||||
@ -674,8 +688,8 @@
|
||||
"synced-lyrics": {
|
||||
"description": "Nagbibigay ng naka-sync na lyrics sa mga kanta, gamit ang mga provider tulad ng LRClib.",
|
||||
"errors": {
|
||||
"fetch": "⚠️ - Nagkaroon ng error habang kinukuha ang lyrics. Subukang muli mamaya.",
|
||||
"not-found": "⚠️ - Walang nakitang lyrics para sa kantang ito."
|
||||
"fetch": "⚠️\t Nagkaroon ng error habang kinukuha ang lyrics.\n\t Subukang muli mamaya.",
|
||||
"not-found": "⚠️ Walang nakitang lyrics para sa kantang ito."
|
||||
},
|
||||
"menu": {
|
||||
"default-text-string": {
|
||||
@ -685,6 +699,10 @@
|
||||
"line-effect": {
|
||||
"label": "Effect ng Linya",
|
||||
"submenu": {
|
||||
"fancy": {
|
||||
"label": "Magarbo",
|
||||
"tooltip": "Gumamit ng malaki, mala-app na effect sa kasalukuyang linya"
|
||||
},
|
||||
"focus": {
|
||||
"tooltip": "Gawing puti lamang ang kasalukuyang linya"
|
||||
},
|
||||
|
||||
@ -53,7 +53,8 @@
|
||||
"later": "אחר כך",
|
||||
"restart-now": "מתחיל את התוכנה מחדש עכשיו"
|
||||
},
|
||||
"message": "נדרש אתחול",
|
||||
"detail": "\"{{pluginName}}\" מצריך אתחול",
|
||||
"message": "\"{{pluginName}}\" דורש אתחול",
|
||||
"title": "נדרשת הפעלה מחדש"
|
||||
},
|
||||
"unresponsive": {
|
||||
@ -70,9 +71,10 @@
|
||||
"buttons": {
|
||||
"disable": "בטל עדכונים",
|
||||
"download": "הורדה",
|
||||
"ok": "אוקי"
|
||||
"ok": "אוקיי"
|
||||
},
|
||||
"message": "גירסא חדשה זמינה כעת",
|
||||
"detail": "גרסה חדשה זמינה, ניתן להוריד אותה ב-{{downloadLink}}",
|
||||
"message": "גירסה חדשה זמינה כעת",
|
||||
"title": "קיים עדכון חדש"
|
||||
}
|
||||
},
|
||||
@ -84,7 +86,8 @@
|
||||
"copy-current-url": "העתק את כתובת ה-URL",
|
||||
"go-back": "חזור אחורה",
|
||||
"go-forward": "לך קדימה",
|
||||
"quit": "יציאה"
|
||||
"quit": "יציאה",
|
||||
"restart": "הפעל מחדש את היישום"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
@ -94,9 +97,39 @@
|
||||
"label": "אפשרויות מתקדמות",
|
||||
"submenu": {
|
||||
"auto-reset-app-cache": "אפס את מטמון האפליקציה כאשר האפליקציה מתחילה",
|
||||
"disable-hardware-acceleration": "השבת האצת החומרה"
|
||||
"disable-hardware-acceleration": "השבת האצת החומרה",
|
||||
"edit-config-json": "ערוך את config.json",
|
||||
"restart-on-config-changes": "הפעל מחדש בשינויי תצורה",
|
||||
"set-proxy": {
|
||||
"label": "הגדר שרת proxy",
|
||||
"prompt": {
|
||||
"label": "הזן כתובת פרוקסי: (להשאיר ריק כדי להשבית)",
|
||||
"placeholder": "דוגמה: SOCKS5://127.0.0.1:9999",
|
||||
"title": "הגדר שרת proxy"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"auto-update": "עדכון אוטומטי",
|
||||
"hide-menu": {
|
||||
"dialog": {
|
||||
"message": "התפריט יוסתר בהפעלה הבאה, השתמש ב-[Alt] כדי להציג אותו (או סמן את [`] אם אתה משתמש בתפריט בתוך האפליקציה)",
|
||||
"title": "הסתר תפריט מופעל"
|
||||
},
|
||||
"label": "הסתר את התפריט"
|
||||
},
|
||||
"language": {
|
||||
"dialog": {
|
||||
"message": "השפה תשתנה לאחר הפעלת היישום מחדש",
|
||||
"title": "השפה שונתה"
|
||||
},
|
||||
"label": "שפה",
|
||||
"submenu": {
|
||||
"to-help-translate": "רוצים לעזור לתרגם? לחץ כאן"
|
||||
}
|
||||
},
|
||||
"resume-on-start": "המשך את השיר האחרון עם הפעלת האפליקציה",
|
||||
"single-instance-lock": "נעילת מופע יחיד"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -226,10 +226,50 @@
|
||||
"description": "एल्बम रंग पैलेट के आधार पर एक गतिशील थीम और दृश्य प्रभाव लागू करता है",
|
||||
"menu": {
|
||||
"color-mix-ratio": {
|
||||
"label": "रंग मिश्रण अनुपात",
|
||||
"submenu": {
|
||||
"percent": "{{ratio}}%"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "एल्बम रंग थीम"
|
||||
},
|
||||
"ambient-mode": {
|
||||
"description": "वीडियो से हल्के रंगों को आपकी स्क्रीन की पृष्ठभूमि में डालकर एक प्रकाश प्रभाव लागू करता है",
|
||||
"menu": {
|
||||
"blur-amount": {
|
||||
"label": "धुंधलापन मात्रा",
|
||||
"submenu": {
|
||||
"pixels": "{{blurAmount}} पिक्सल"
|
||||
}
|
||||
},
|
||||
"buffer": {
|
||||
"label": "बफर",
|
||||
"submenu": {
|
||||
"buffer": "{{buffer}}"
|
||||
}
|
||||
},
|
||||
"opacity": {
|
||||
"label": "अस्पष्टता",
|
||||
"submenu": {
|
||||
"percent": "{{opacity}}%"
|
||||
}
|
||||
},
|
||||
"quality": {
|
||||
"label": "गुणवत्ता",
|
||||
"submenu": {
|
||||
"pixels": "{{quality}} पिक्सल"
|
||||
}
|
||||
},
|
||||
"size": {
|
||||
"label": "माप",
|
||||
"submenu": {
|
||||
"percent": "{{size}}%"
|
||||
}
|
||||
},
|
||||
"smoothness-transition": {
|
||||
"label": "चिकनाई संक्रमण"
|
||||
}
|
||||
}
|
||||
},
|
||||
"video-toggle": {
|
||||
|
||||
@ -279,6 +279,13 @@
|
||||
},
|
||||
"name": "Mode ambient"
|
||||
},
|
||||
"amuse": {
|
||||
"description": "Menambahkan dukungan YouTube Music untuk widget Amuse yang sedang diputar oleh 6K Labs",
|
||||
"name": "Amuse",
|
||||
"response": {
|
||||
"query": "Server API Amuse sedang berjalan. GET /query untuk mendapatkan info lagu."
|
||||
}
|
||||
},
|
||||
"api-server": {
|
||||
"description": "Menambahkan server API untuk mengontrol pemutar",
|
||||
"dialog": {
|
||||
@ -726,8 +733,8 @@
|
||||
"synced-lyrics": {
|
||||
"description": "Menyediakan lirik lagu yang disinkronkan, menggunakan penyedia seperti LRClib.",
|
||||
"errors": {
|
||||
"fetch": "⚠️ - Terjadi kesalahan saat mengambil lirik. Coba lagi nanti.",
|
||||
"not-found": "⚠️ - Tidak ada lirik yang ditemukan untuk lagu ini."
|
||||
"fetch": "⚠️\tTerjadi kesalahan saat mengambil lirik.\n\tSilakan coba lagi nanti.",
|
||||
"not-found": "⚠️ Tidak ada lirik yang ditemukan untuk lagu ini."
|
||||
},
|
||||
"menu": {
|
||||
"default-text-string": {
|
||||
@ -737,6 +744,10 @@
|
||||
"line-effect": {
|
||||
"label": "Efek garis",
|
||||
"submenu": {
|
||||
"fancy": {
|
||||
"label": "Mewah",
|
||||
"tooltip": "Gunakan efek besar seperti aplikasi pada baris saat ini"
|
||||
},
|
||||
"focus": {
|
||||
"label": "Fokus",
|
||||
"tooltip": "Jadikan hanya baris saat ini berwarna putih"
|
||||
|
||||
@ -744,6 +744,9 @@
|
||||
"line-effect": {
|
||||
"label": "Effetto linea",
|
||||
"submenu": {
|
||||
"fancy": {
|
||||
"tooltip": "Usa effetti grandi, simili a quelli di un'app sulla riga attuale"
|
||||
},
|
||||
"focus": {
|
||||
"label": "Focus",
|
||||
"tooltip": "Rendi bianca solo la riga corrente"
|
||||
|
||||
@ -39,29 +39,29 @@
|
||||
"clearing-cache-after-20s": "กำลังล้างแคชแอป"
|
||||
},
|
||||
"window": {
|
||||
"tried-to-render-offscreen": "หน้าต่างพยายามแสดงผลเกินขนาดหน้าจอ windowSize={{windowSize}}, displaySize={{displaySize}}, position={{position}}"
|
||||
"tried-to-render-offscreen": "หน้าต่างพยายามแสดงผลเกินขนาดหน้าจอ ขนาดหน้าต่าง={{windowSize}}, ขนาดหน้าจอ={{displaySize}}, ตำแหน่ง={{position}}"
|
||||
}
|
||||
},
|
||||
"dialog": {
|
||||
"hide-menu-enabled": {
|
||||
"detail": "เมนูถูกซ่อนไว้ กด'Alt' เพื่อแสดงเมนู (หรือ 'Escape' หากอยู่ในเมนูแอป)",
|
||||
"message": "การซ่อนเมนูถูกเปิดใช้งาน",
|
||||
"detail": "เมนูถูกซ่อนไว้ กด'Alt' เพื่อแสดงเมนู (หรือ 'Escape' หากกำลังใช้เมนูบนแอป)",
|
||||
"message": "การซ่อนเมนูเปิดใช้งานอยู่",
|
||||
"title": "เปิดใช้งานการซ่อนเมนู"
|
||||
},
|
||||
"need-to-restart": {
|
||||
"buttons": {
|
||||
"later": "ภายหลัง",
|
||||
"restart-now": "รีสตาร์ทตอนนี้"
|
||||
"later": "รีสตาร์ตภายหลัง",
|
||||
"restart-now": "รีสตาร์ตตอนนี้"
|
||||
},
|
||||
"detail": "\"{{pluginName}}\" ปลั๊กอินต้องการการรีสตาร์ทเพื่อแสดงผล",
|
||||
"message": "\"{{pluginName}}\" ต้องการรีสตาร์ท",
|
||||
"title": "แนะนำให้รีสตาร์ท"
|
||||
"detail": "ปลั๊กอิน \"{{pluginName}}\" ต้องการการรีสตาร์ตเพื่อจะทำงานได้",
|
||||
"message": "\"{{pluginName}}\" ต้องการรีสตาร์ต",
|
||||
"title": "แนะนำให้รีสตาร์ต"
|
||||
},
|
||||
"unresponsive": {
|
||||
"buttons": {
|
||||
"quit": "ออก",
|
||||
"relaunch": "เปิดใหม่",
|
||||
"wait": "รอซักครู่"
|
||||
"relaunch": "ปิดแล้วเปิดใหม่",
|
||||
"wait": "รอให้ตอบสนอง"
|
||||
},
|
||||
"detail": "ขออภัยในความไม่สะดวก! โปรดเลือกสิ่งที่ต้องการจะทำ:",
|
||||
"message": "แอปพลิเคชันไม่ตอบสนอง",
|
||||
@ -73,7 +73,7 @@
|
||||
"download": "ดาวน์โหลด",
|
||||
"ok": "ตกลง"
|
||||
},
|
||||
"detail": "มีเวอร์ชันใหม่ให้ดาวน์โหลดแล้วที่ {{downloadLink}}",
|
||||
"detail": "มีเวอร์ชันใหม่ให้ใช้งานได้สามารถดาวน์โหลดได้ที่ {{downloadLink}}",
|
||||
"message": "มีเวอร์ชันใหม่ให้ใช้งานแล้ว",
|
||||
"title": "อัปเดตพร้อมใช้งาน"
|
||||
}
|
||||
@ -87,7 +87,7 @@
|
||||
"go-back": "ก่อนหน้า",
|
||||
"go-forward": "ถัดไป",
|
||||
"quit": "ออก",
|
||||
"restart": "รีสตาร์ทแอป"
|
||||
"restart": "รีสตาร์ตแอป"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
@ -96,23 +96,23 @@
|
||||
"advanced-options": {
|
||||
"label": "ตัวเลือกขั้นสูง",
|
||||
"submenu": {
|
||||
"auto-reset-app-cache": "รีเซตแอปแคชเมื่อเริ่มแอป",
|
||||
"auto-reset-app-cache": "รีเซตแคชของแอปเมื่อเริ่มแอป",
|
||||
"disable-hardware-acceleration": "ปิดการใช้งานตัวเร่งประสิทธิภาพด้วยฮาร์ดแวร์",
|
||||
"edit-config-json": "แก้ไข config.json",
|
||||
"override-user-agent": "แทนที่ User-Agent",
|
||||
"restart-on-config-changes": "รีสตาร์ทเมื่อมีการเปลี่ยนแปลงคอนฟิก",
|
||||
"restart-on-config-changes": "รีสตาร์ตเมื่อมีการเปลี่ยนแปลงคอนฟิก",
|
||||
"set-proxy": {
|
||||
"label": "ตั้งค่าพร็อกซี่",
|
||||
"prompt": {
|
||||
"label": "ใส่ที่อยู่พร็อกซี่: (ปล่อยให้ว่างเพื่อปิดใช้งาน)",
|
||||
"label": "ใส่ที่อยู่ของพร็อกซี่: (เว้นว่างเพื่อปิดใช้งาน)",
|
||||
"placeholder": "ตัวอย่าง: SOCKS5://127.0.0.1:9999",
|
||||
"title": "ตั้งค่าพร็อกซี่"
|
||||
}
|
||||
},
|
||||
"toggle-dev-tools": "เปิด-ปิด DevTools"
|
||||
"toggle-dev-tools": "เปิด/ปิดเครื่องมือสำหรับนักพัฒนา"
|
||||
}
|
||||
},
|
||||
"always-on-top": "อยู่ด้านบนตลอดเวลา",
|
||||
"always-on-top": "อยู่ด้านบนหน้าต่างอื่นตลอดเวลา",
|
||||
"auto-update": "อัปเดตอัตโนมัติ",
|
||||
"hide-menu": {
|
||||
"dialog": {
|
||||
@ -123,17 +123,17 @@
|
||||
},
|
||||
"language": {
|
||||
"dialog": {
|
||||
"message": "ภาษาจะเปลี่ยนหลังจากทำการรีสตาร์ท",
|
||||
"message": "ภาษาจะเปลี่ยนหลังจากทำการรีสตาร์ต",
|
||||
"title": "ภาษาถูกเปลี่ยนแล้ว"
|
||||
},
|
||||
"label": "ภาษา",
|
||||
"submenu": {
|
||||
"to-help-translate": "ต้องการช่วยแปล? คลิกที่นี่"
|
||||
"to-help-translate": "ต้องการช่วยแปลภาษา? คลิกที่นี่"
|
||||
}
|
||||
},
|
||||
"resume-on-start": "เล่นเพลงล่าสุดต่อ เมื่อแอปเริ่มต้น",
|
||||
"single-instance-lock": "ล็อกการทำงานเพียงรายการเดียว",
|
||||
"start-at-login": "เริ่มต้นที่การเข้าสู่ระบบ",
|
||||
"resume-on-start": "เล่นเพลงที่เล่นล่าสุดต่อ เมื่อเปิดแอป",
|
||||
"single-instance-lock": "ล็อกไม่ให้เปิดซำ้ซ้อน",
|
||||
"start-at-login": "เริ่มต้นเมื่อเข้าสู่ระบบ",
|
||||
"starting-page": {
|
||||
"label": "หน้าเริ่มต้น",
|
||||
"unset": "ยกเลิกการตั้งค่า"
|
||||
@ -148,7 +148,7 @@
|
||||
}
|
||||
},
|
||||
"visual-tweaks": {
|
||||
"label": "การปรับแต่งหน้าตาแอป",
|
||||
"label": "ปรับแต่งหน้าตาแอป",
|
||||
"submenu": {
|
||||
"like-buttons": {
|
||||
"default": "ค่าเริ่มต้น",
|
||||
@ -169,7 +169,7 @@
|
||||
"label": "ธีม",
|
||||
"submenu": {
|
||||
"import-css-file": "นำเข้าไฟล์ CSS ที่กำหนดเอง",
|
||||
"no-theme": "ไม่มีธีม"
|
||||
"no-theme": "ไม่ใช้ธีม"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -187,28 +187,28 @@
|
||||
"force-reload": "บังคับโหลดใหม่",
|
||||
"reload": "โหลดใหม่",
|
||||
"reset-zoom": "ขนาดจริง",
|
||||
"toggle-fullscreen": "สลับเต็มหน้าจอ",
|
||||
"toggle-fullscreen": "เปิด/ปิดโหมดเต็มหน้าจอ",
|
||||
"zoom-in": "ซูมเข้า",
|
||||
"zoom-out": "ซูมออก"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tray": {
|
||||
"next": "ค่อไป",
|
||||
"play-pause": "เล่น/พัก",
|
||||
"next": "ต่อไป",
|
||||
"play-pause": "เล่น/หยุดชั่วคราว",
|
||||
"previous": "ก่อนหน้า",
|
||||
"quit": "ออก",
|
||||
"restart": "รีสตาร์ทแอป",
|
||||
"restart": "รีสตาร์ตแอป",
|
||||
"show": "แสดงหน้าต่าง",
|
||||
"tooltip": {
|
||||
"default": "ยูทุปมิวสิค",
|
||||
"with-song-info": "ยูทูปมิวสิค: {{artist}} - {{title}}"
|
||||
"default": "YouTube Music",
|
||||
"with-song-info": "YouTube Music: {{artist}} - {{title}}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
"ad-speedup": {
|
||||
"description": "หากมีการเล่นโฆษณา เสียงจะถูกปิดและตั้งค่าความเร็วในการเล่นเป็น 16x",
|
||||
"description": "หากมีโฆษณาเล่นขึ้น เสียงจะถูกปิดและตั้งความเร็วในการเล่นเป็น 16 เท่า",
|
||||
"name": "เพิ่มความเร็วโฆษณา"
|
||||
},
|
||||
"adblocker": {
|
||||
@ -219,7 +219,7 @@
|
||||
"name": "ตัวบล็อกโฆษณา"
|
||||
},
|
||||
"album-actions": {
|
||||
"description": "เพิ่ม ยกเลิกไม่ชอบ, ไม่ชอบ, 'ถูกใจ', และ 'ยกเลิกถูกใจ' เพื่อให้สามารถใช้งานกับเพลงทั้งหมดในรายการเพลงหรืออัลบั้ม",
|
||||
"description": "เพิ่ม ยกเลิกไม่ชอบ, ไม่ชอบ, ถูกใจ, และ ยกเลิกถูกใจ ที่มีผลกับเพลงทั้งหมดในรายการเพลงหรืออัลบั้ม",
|
||||
"name": "การกระทำที่เกี่ยวกับอัลบั้ม"
|
||||
},
|
||||
"album-color-theme": {
|
||||
@ -228,14 +228,14 @@
|
||||
"color-mix-ratio": {
|
||||
"label": "สัดส่วนการผสมสี",
|
||||
"submenu": {
|
||||
"percent": "{{ratio}}เปอร์เซ็น"
|
||||
"percent": "{{ratio}}%"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "ธีมสีของอัลบั้ม"
|
||||
},
|
||||
"ambient-mode": {
|
||||
"description": "เอฟเฟกต์แสงจะใช้สีอ่อนๆจากวีดิโอมาเป็พื้นหลังสกรีน",
|
||||
"description": "เอฟเฟกต์แสงที่ดึงสีอ่อนๆจากวีดิโอมาบนพื้นหลังแอป",
|
||||
"menu": {
|
||||
"blur-amount": {
|
||||
"label": "ระดับความเบลอ",
|
||||
@ -268,9 +268,9 @@
|
||||
}
|
||||
},
|
||||
"smoothness-transition": {
|
||||
"label": "การเปลี่ยนแบบสมูท",
|
||||
"label": "ความเรียบการเปลี่ยน",
|
||||
"submenu": {
|
||||
"during": "ระหว่าง {{interpolationTime}} วินาที"
|
||||
"during": "ในระยะเวลา {{interpolationTime}} วินาที"
|
||||
}
|
||||
},
|
||||
"use-fullscreen": {
|
||||
@ -279,6 +279,13 @@
|
||||
},
|
||||
"name": "โหมดสภาพแวดล้อม"
|
||||
},
|
||||
"amuse": {
|
||||
"description": "เพิ่มการรองรับ Youtube Music สำหรับ Widget Amuse Now Playing ของ 6K Labs",
|
||||
"name": "Amuse",
|
||||
"response": {
|
||||
"query": "API Server ของ Amuse ทำงานอยู่ ส่ง GET ไปที่ /query เพื่อขอข้อมูลเกี่ยวกับเพลง"
|
||||
}
|
||||
},
|
||||
"api-server": {
|
||||
"description": "เพิ่มเซิร์ฟเวอร์ API เพื่อควบคุมการเล่น",
|
||||
"dialog": {
|
||||
@ -287,7 +294,38 @@
|
||||
"allow": "อนุญาต",
|
||||
"deny": "ปฏิเสธ"
|
||||
},
|
||||
"message": "อนุญาตให้ {{ID}} ({{origin}}) เข้าถึง API หรือไม่?"
|
||||
"message": "อนุญาตให้ {{ID}} ({{origin}}) เข้าถึง API หรือไม่?",
|
||||
"title": "คำขอลงชื่อเข้าใช้งาน API"
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"auth-strategy": {
|
||||
"label": "วิธีการลงชื่อเข้าใช้งาน",
|
||||
"submenu": {
|
||||
"auth-at-first": {
|
||||
"label": "ลงชื่อเข้าใช้งานในคำขอแรก"
|
||||
},
|
||||
"none": {
|
||||
"label": "ไม่ต้องลงชื่อเข้าใช้งาน"
|
||||
}
|
||||
}
|
||||
},
|
||||
"hostname": {
|
||||
"label": "ชื่อโฮสต์ (Hostname)"
|
||||
},
|
||||
"port": {
|
||||
"label": "พอร์ต (Port) ของ Server"
|
||||
}
|
||||
},
|
||||
"name": "เซิร์ฟเวอร์ API [เบต้า]",
|
||||
"prompt": {
|
||||
"hostname": {
|
||||
"label": "ใส่ชื่อโฮสต์ (Hostname) เช่น 0.0.0.0 สำหรับเซิร์ฟเวอร์ API:",
|
||||
"title": "ชื่อโฮสต์ (Hostname)"
|
||||
},
|
||||
"port": {
|
||||
"label": "ใส่พอร์ต (Port) ในการเข้าถึงเซิร์ฟเวอร์ API:",
|
||||
"title": "พอร์ต (Port) ของ Server"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -300,11 +338,11 @@
|
||||
"name": "เบลอแถบนำทาง"
|
||||
},
|
||||
"bypass-age-restrictions": {
|
||||
"description": "ข้ามการตรวจสอบอายุของยูทูป",
|
||||
"description": "ข้ามการตรวจสอบอายุของ YouTube",
|
||||
"name": "ข้ามข้อจำกัดอายุ"
|
||||
},
|
||||
"captions-selector": {
|
||||
"description": "ตัวเลือกคำบรรยายสำหรับเพลงในYoutube Music",
|
||||
"description": "ตัวเลือกคำบรรยายสำหรับเพลงใน YouTube Music",
|
||||
"menu": {
|
||||
"autoload": "เลือกคำบรรยายที่ใช้ครั้งล่าสุดโดยอัตโนมัติ",
|
||||
"disable-captions": "ไม่มีคำบรรยายเป็นค่าเริ่มต้น"
|
||||
@ -348,19 +386,19 @@
|
||||
}
|
||||
},
|
||||
"disable-autoplay": {
|
||||
"description": "เริ่มเพลงในโหมดหยุด",
|
||||
"description": "เริ่มเพลงในโหมดหยุดชั่วคราว",
|
||||
"menu": {
|
||||
"apply-once": "ใช้เฉพาะเมื่อเริ่มต้น"
|
||||
"apply-once": "ใช้เฉพาะเมื่อเริ่มต้นแอป"
|
||||
},
|
||||
"name": "ปิดใช้งานการเล่นอัตโนมัติ"
|
||||
},
|
||||
"discord": {
|
||||
"backend": {
|
||||
"already-connected": "พยายามเชื่อมต่อกับการเชื่อมต่อที่ทำงานอยู่",
|
||||
"already-connected": "กำลังพยายามเชื่อมต่อด้วยการเชื่อมต่อที่มีอยู่",
|
||||
"connected": "เชื่อมต่อกับดิสคอร์ดแล้ว",
|
||||
"disconnected": "ตัดการเชื่อมต่อออกจากดิสคอร์ด"
|
||||
"disconnected": "ไม่มีการเชื่อมต่อกับดิสคอร์ดอยู่"
|
||||
},
|
||||
"description": "แสดงให้เพื่อนเห็นว่าคุณกำลังฟังอะไรด้วย Rich Presence",
|
||||
"description": "แสดงให้เพื่อนเห็นว่าคุณกำลังฟังอะไรด้วย Rich Presence บนดิสคอร์ด",
|
||||
"menu": {
|
||||
"auto-reconnect": "เชื่อมต่อใหม่โดยอัตโนมัติ",
|
||||
"clear-activity": "ล้างกิจกรรม",
|
||||
@ -369,10 +407,10 @@
|
||||
"disconnected": "ตัดการเชื่อมต่อ",
|
||||
"hide-duration-left": "ซ่อนระยะเวลาที่เหลือ",
|
||||
"hide-github-button": "ซ่อนปุ่มลิงก์ GitHub",
|
||||
"play-on-youtube-music": "เล่นบนยูทูปมิวสุค",
|
||||
"play-on-youtube-music": "เล่นบน YouTube Music",
|
||||
"set-inactivity-timeout": "ตั้งระยะเวลาไม่มีกิจกรรม"
|
||||
},
|
||||
"name": "Discord Rich Presence",
|
||||
"name": "แสดงกิจกรรมบนดิสคอร์ด",
|
||||
"prompt": {
|
||||
"set-inactivity-timeout": {
|
||||
"label": "ป้อนระยะเวลาไม่มีกิจกรรมเป็นวินาที:",
|
||||
@ -426,6 +464,21 @@
|
||||
"description": "ดาวน์โหลด MP3 / เสียงต้นฉบับโดยตรงจากอินเทอร์เฟซ",
|
||||
"menu": {
|
||||
"choose-download-folder": "เลือกโฟลเดอร์ดาวน์โหลด",
|
||||
"download-finish-settings": {
|
||||
"label": "ดาวน์โหลดเมื่อเล่นเสร็จ",
|
||||
"prompt": {
|
||||
"last-percent": "หลังจาก x เปอร์เซ็นต์",
|
||||
"last-seconds": "x วินาทีล่าสุด",
|
||||
"title": "ตั่งค่าเวลาที่จะดาวน์โหลด"
|
||||
},
|
||||
"submenu": {
|
||||
"advanced": "การตั้งค่าขั้นสูง",
|
||||
"enabled": "เปิดใช้งาน",
|
||||
"mode": "โหมดเวลา",
|
||||
"percent": "โหมดเปอร์เซ็นต์",
|
||||
"seconds": "โหมดวินาที"
|
||||
}
|
||||
},
|
||||
"download-playlist": "ดาวน์โหลดเพลย์ลิสต์",
|
||||
"presets": "พรีเซ็ต",
|
||||
"skip-existing": "ข้ามไฟล์ที่มีอยู่แล้ว"
|
||||
@ -438,12 +491,24 @@
|
||||
"button": "ดาวน์โหลด"
|
||||
}
|
||||
},
|
||||
"equalizer": {
|
||||
"description": "เพิ่มอีควอไลเซอร์ให้ที่เล่นเพลง",
|
||||
"menu": {
|
||||
"presets": {
|
||||
"label": "การตั้งค่าล่วงหน้า",
|
||||
"list": {
|
||||
"bass-booster": "เพิ่มเบส"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "อีควอไลเซอร์"
|
||||
},
|
||||
"exponential-volume": {
|
||||
"description": "ทำให้ตัวเลือกความดังมีลักษณะเอ็กซ์โปเนนเชียล เพื่อให้ง่ายต่อการเลือกระดับความดังที่ต่ำลง",
|
||||
"name": "ระดับเสียงแบบเอ็กซโปเนนเชียล"
|
||||
},
|
||||
"in-app-menu": {
|
||||
"description": "ให้เมนูบาร์ดูทันสมัย มืดหรือเป็นสีของอัลบั้มอย่างน่าสนใจ",
|
||||
"description": "ให้เแถบเมนูดูทันสมัย มืดหรือเป็นสีของอัลบั้มอย่างน่าสนใจ",
|
||||
"menu": {
|
||||
"hide-dom-window-controls": "ซ่อนตัวควบคุมหน้าต่าง DOM"
|
||||
},
|
||||
@ -530,6 +595,7 @@
|
||||
}
|
||||
},
|
||||
"priority": "ลำดับความสำคัญของการแจ้งเตือน",
|
||||
"toast-style": "แบบไม่ถาวร",
|
||||
"unpause-notification": "แสดงการแจ้งเตือนเมื่อหยุดพัก"
|
||||
},
|
||||
"name": "การแจ้งเตือน"
|
||||
@ -549,8 +615,222 @@
|
||||
}
|
||||
},
|
||||
"save-window-position": "บันทึกตำแหน่งหน้าต่าง",
|
||||
"save-window-size": "บันทึกขนาดหน้าต่าง"
|
||||
"save-window-size": "บันทึกขนาดหน้าต่าง",
|
||||
"use-native-pip": "ใช้โหมดภาพซ้อนภาพของเบราเซอร์"
|
||||
},
|
||||
"name": "โหมดภาพซ้อนภาพ",
|
||||
"templates": {
|
||||
"button": "เปิดโหมดภาพซ้อนภาพ"
|
||||
}
|
||||
},
|
||||
"playback-speed": {
|
||||
"description": "ฟังเพลงได้ทั้งช้าและเร็ว เพิ่มที่เลื่อนปรับความเร็วของเพลง",
|
||||
"name": "ความเร็วเพลง",
|
||||
"templates": {
|
||||
"button": "ความเร็ว"
|
||||
}
|
||||
},
|
||||
"precise-volume": {
|
||||
"description": "ควบคุมระดับเสียงได้อย่างแม่นยำด้วยที่เลื่อนเมาส์หรือปุ่มลัด พร้อมด้วยหน้าจอแสดงข้อมูลและขั้นระดับเสียงที่ปรับแต่งได้",
|
||||
"menu": {
|
||||
"arrows-shortcuts": "ควบคุมด้วยปุ่มลูกศรเมื่ออยู่ในแอป",
|
||||
"custom-volume-steps": "ตั้งขั้นการปรับระดับเสียง",
|
||||
"global-shortcuts": "ตั้งปุ่มลัดที่ใช้ได้ทั้งระบบ"
|
||||
},
|
||||
"name": "ระดับเสียงแม่นยำ",
|
||||
"prompt": {
|
||||
"global-shortcuts": {
|
||||
"keybind-options": {
|
||||
"decrease": "ปุ่มลดระดับเสียง",
|
||||
"increase": "ปุ่มเพิ่มระดับเสียง"
|
||||
},
|
||||
"label": "ตั้งค่าปุ่มลัดระดับเสียงที่ใช้ได้ทั้งระบบ:",
|
||||
"title": "ปุ่มลัดระดับเสียงที่ใช้ได้ทั้งระบบ"
|
||||
},
|
||||
"volume-steps": {
|
||||
"label": "ตั้งขั้นการเพิ่ม/ลดระดับเสียง",
|
||||
"title": "ขั้นการปรับระดับเสียง"
|
||||
}
|
||||
}
|
||||
},
|
||||
"quality-changer": {
|
||||
"backend": {
|
||||
"dialog": {
|
||||
"quality-changer": {
|
||||
"detail": "คุณภาพปัจจุบัน: {{quality}}",
|
||||
"message": "เลือกคุณภาพวิดีโอ:",
|
||||
"title": "เลือกคุณภาพวิดีโอ"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "อนุญาตให้เปลี่ยนคุณภาพของวิดีโอด้วยปุ่มที่แสดงเหนือวิดีโอ",
|
||||
"name": "ที่เปลี่ยนคุณภาพวิดีโอ"
|
||||
},
|
||||
"scrobbler": {
|
||||
"description": "รองรับการบันทึกการเล่นเพลง (เช่น last.fm, Listenbrainz)",
|
||||
"dialog": {
|
||||
"lastfm": {
|
||||
"auth-failed": {
|
||||
"message": "เกิดปัญหาระหว่างเข้าใช้งาน Last.fm\nซ่อนข้อความนี้จนการรีสตาร์ตครั้งถัดไป",
|
||||
"title": "เกิดปัญหาในการเข้าใช้งาน"
|
||||
}
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"lastfm": {
|
||||
"api-settings": "การตั้งค่า API Last.fm"
|
||||
},
|
||||
"listenbrainz": {
|
||||
"token": "ใส่ user token ของ ListenBrainz"
|
||||
},
|
||||
"scrobble-other-media": "บันทึกการเล่นสื่ออื่นๆ"
|
||||
},
|
||||
"name": "บันทึกการเล่น (Scrobbler)",
|
||||
"prompt": {
|
||||
"lastfm": {
|
||||
"api-key": "API Key ของ Last.fm",
|
||||
"api-secret": "API secret ของ Last.fm"
|
||||
},
|
||||
"listenbrainz": {
|
||||
"token": {
|
||||
"label": "ใส่ user token ListenBrainz ของคุณ:",
|
||||
"title": "token ListenBrainz"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"shortcuts": {
|
||||
"description": "อนุญาตให้ตั้งปุ่มลัดทั่วระบบสำหรับการเล่น (เล่น/หยุดชั่วคราว/ถัดไป/ก่อนหน้า) และปิดการแสดงผลสื่อโดยทับปุ่มควบคุมสื่อ เปิด Ctrl/CMD + F เพื่อค้นหา เปิดการใช้งานการควบคุมเพลงผ่าน MPRIS สำหรับ Linux และปุ่มลัดที่กำหนดเองได้สำหรับผู้ใช้ขั้นสูง",
|
||||
"menu": {
|
||||
"override-media-keys": "เปลี่ยนการทำงานของปุ่มควบคุมสื่อ",
|
||||
"set-keybinds": "ตั้งค่าปุ่มลัดควบคุมเพลง"
|
||||
},
|
||||
"name": "ปุ่มลัด (และ MPRIS)",
|
||||
"prompt": {
|
||||
"keybind": {
|
||||
"keybind-options": {
|
||||
"next": "เพลงถัดไป",
|
||||
"play-pause": "เล่น/หยุดชั่วคราว",
|
||||
"previous": "เพลงก่อนหน้า"
|
||||
},
|
||||
"label": "ตั้งค่าปุ่มลัดทั่วระบบสำหรับควบคุมเพลง:",
|
||||
"title": "ปุ่มลัดทั่วระบบ"
|
||||
}
|
||||
}
|
||||
},
|
||||
"skip-disliked-songs": {
|
||||
"description": "ข้ามเพลงที่ไม่ถูกใจ",
|
||||
"name": "ข้ามเพลงที่ไม่ถูกใจ"
|
||||
},
|
||||
"skip-silences": {
|
||||
"description": "ข้ามช่วงที่เงียบในเพลงโดยอัตโนมัติ",
|
||||
"name": "ข้ามช่วงเงียบ"
|
||||
},
|
||||
"sponsorblock": {
|
||||
"description": "ข้ามช่วงที่ไม่ใช่เพลงเช่น intro/outro หรือ ช่วงที่ไม่มีเพลงเล่นใน mv โดยอัตโนมัติ",
|
||||
"name": "SponsorBlock"
|
||||
},
|
||||
"synced-lyrics": {
|
||||
"description": "ให้เนื้อเพลงที่ตรงกับเวลาของเพลง ผ่านผู้ให้บริการเช่น LRClib",
|
||||
"errors": {
|
||||
"fetch": "⚠️\tเกิดปัญหาในการดึงเนื้อเพลง\n\tกรุณาลองใหม่ภายหลัง",
|
||||
"not-found": "⚠️ ไม่เจอเนื้อเพลงสำหรับเพลงนี้"
|
||||
},
|
||||
"menu": {
|
||||
"default-text-string": {
|
||||
"label": "อักขระคั่นระหว่างเนื้อเพลง",
|
||||
"tooltip": "เลือกอักขระที่คั่นในช่วงที่อยู่ระหว่างเนื้อเพลง"
|
||||
},
|
||||
"line-effect": {
|
||||
"label": "เอฟเฟกต์บรรทัด",
|
||||
"submenu": {
|
||||
"fancy": {
|
||||
"label": "อลังการ",
|
||||
"tooltip": "ใช้เอฟเฟกต์ใหญ่คล้ายบนแอพ บนบรรทัดปัจจุบัน"
|
||||
},
|
||||
"focus": {
|
||||
"label": "เด่น",
|
||||
"tooltip": "ทำให้แค่บรรทัดปัจจุบันสีขาว"
|
||||
},
|
||||
"offset": {
|
||||
"label": "เลื่อน",
|
||||
"tooltip": "เลื่อนบรรทัดปัจจุบันไปทางขวา"
|
||||
},
|
||||
"scale": {
|
||||
"label": "ขยายขนาด",
|
||||
"tooltip": "ขยายบรรทัดปัจจุบันให้ใหญ่ขึ้น"
|
||||
}
|
||||
},
|
||||
"tooltip": "เลือกเอฟเฟกต์ที่จะใช้กับบรรทัดปัจจุบัน"
|
||||
},
|
||||
"precise-timing": {
|
||||
"label": "ให้เนื้อเพลงตรงกับเพลงเป๊ะๆ",
|
||||
"tooltip": "คำนวณมิลิวินาทีในการแสดงบรรทัดถัดไป (มีผลเล็กน้อยกับประสิทธิภาพการทำงาน)"
|
||||
},
|
||||
"show-lyrics-even-if-inexact": {
|
||||
"label": "แสดงเนื้อเพลงแม้ไม่ตรงเป๊ะ",
|
||||
"tooltip": "ถ้าหาเนื้อเพลงไม่เจอจะลองหาด้วยคำค้นหาที่ต่างกัน\nอาจได้เนื้อเพลงไม่ตรง"
|
||||
},
|
||||
"show-time-codes": {
|
||||
"label": "แสดงตำแหน่งเวลา",
|
||||
"tooltip": "แสดงตำแหน่งเวลาข้างๆเนื้อเพลง"
|
||||
}
|
||||
},
|
||||
"name": "เนื้อเพลงตรงกับเพลง",
|
||||
"refetch-btn": {
|
||||
"fetching": "กำลังดึงข้อมูล...",
|
||||
"normal": "ดึงเนื้อเพลงใหม่"
|
||||
},
|
||||
"warnings": {
|
||||
"duration-mismatch": "⚠️ - เนื้อเพลงอาจไม่ตรงกับเวลาเนื่องจากความยาวไม่ตรงกัน",
|
||||
"inexact": "⚠️ - เนื้อเพลงอาจไม่ตรง",
|
||||
"instrumental": "⚠️ - เพลงนี้เป็นเพลงบรรเลง"
|
||||
}
|
||||
},
|
||||
"taskbar-mediacontrol": {
|
||||
"description": "ควบคุมการเล่นผ่าน taskbar ของ Windows",
|
||||
"name": "ควบคุมสื่อผ่าน Taskbar"
|
||||
},
|
||||
"touchbar": {
|
||||
"description": "เพิ่ม Widget บน TouchBar สำหรับผู้ใช้ macOS",
|
||||
"name": "TouchBar"
|
||||
},
|
||||
"tuna-obs": {
|
||||
"description": "ใช้งานร่วมกันกับปลั้กอิน Tuna บน OBS",
|
||||
"name": "Tuna OBS"
|
||||
},
|
||||
"video-toggle": {
|
||||
"description": "เพิ่มปุ่มสลับระหว่างโหมดเพลงกับโหมดวิดีโอ หรือลบแถบวิดีโอออกทั้งแถบ",
|
||||
"menu": {
|
||||
"align": {
|
||||
"label": "ตำแหน่งปุ่ม",
|
||||
"submenu": {
|
||||
"left": "ซ้าย",
|
||||
"middle": "กลาง",
|
||||
"right": "ขวา"
|
||||
}
|
||||
},
|
||||
"force-hide": "บังคับลบแถบวิดีโอ",
|
||||
"mode": {
|
||||
"label": "โหมด",
|
||||
"submenu": {
|
||||
"custom": "ปุ่มกำหนดเอง",
|
||||
"disabled": "ปิด",
|
||||
"native": "ปุ่มเริ่มต้น"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "ปุ่มวิดีโอ",
|
||||
"templates": {
|
||||
"button": "เพลง"
|
||||
}
|
||||
},
|
||||
"visualizer": {
|
||||
"description": "เพิ่มวิชวลไลเซอร์ให้ที่เล่นเพลง",
|
||||
"menu": {
|
||||
"visualizer-type": "ประเภทวิชวลไลเซอร์"
|
||||
},
|
||||
"name": "วิชวลไลเซอร์"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -279,6 +279,12 @@
|
||||
},
|
||||
"name": "Chế độ Môi trường xung quanh"
|
||||
},
|
||||
"amuse": {
|
||||
"name": "Amuse",
|
||||
"response": {
|
||||
"query": "Máy chủ API của Amuse đang chạy. GET /query để lấy thông tin về bài hát."
|
||||
}
|
||||
},
|
||||
"api-server": {
|
||||
"description": "Thêm máy chủ API để điều khiển trình phát",
|
||||
"dialog": {
|
||||
@ -299,7 +305,7 @@
|
||||
"label": "Xác thực ngay yêu cầu đầu tiên"
|
||||
},
|
||||
"none": {
|
||||
"label": "Không/Chưa xác thực (Need context)"
|
||||
"label": "Không xác thực"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@ -201,8 +201,8 @@
|
||||
"restart": "重启应用",
|
||||
"show": "显示窗口",
|
||||
"tooltip": {
|
||||
"default": "YouTube Music",
|
||||
"with-song-info": "YouTube Music: {{artist}} - {{title}}"
|
||||
"default": "优兔音乐",
|
||||
"with-song-info": "优兔音乐: {{artist}} - {{title}}"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -281,7 +281,7 @@
|
||||
},
|
||||
"amuse": {
|
||||
"description": "为 6K Labs 的 Amuse 正在播放小部件添加 YouTube Music 支持",
|
||||
"name": "Amuse",
|
||||
"name": "逗笑",
|
||||
"response": {
|
||||
"query": "Amuse API服务器已在运行。使用 /query 以获取歌曲信息。"
|
||||
}
|
||||
@ -734,7 +734,7 @@
|
||||
"description": "透过 LRClib 等服务提供滚动歌词显示。",
|
||||
"errors": {
|
||||
"fetch": "⚠️ - 获取歌词时发生错误。请稍后再试。",
|
||||
"not-found": "⚠️ - 未找到此歌曲的歌词。"
|
||||
"not-found": "⚠️ 未找到此歌曲的歌词。"
|
||||
},
|
||||
"menu": {
|
||||
"default-text-string": {
|
||||
|
||||
@ -134,14 +134,6 @@ if (is.linux()) {
|
||||
// Overrides WM_CLASS for X11 to correspond to icon filename
|
||||
app.setName('com.github.th_ch.youtube_music');
|
||||
|
||||
// Workaround for issue #2248
|
||||
if (
|
||||
process.env.XDG_SESSION_TYPE === 'wayland' ||
|
||||
process.env.WAYLAND_DISPLAY
|
||||
) {
|
||||
app.commandLine.appendSwitch('disable-gpu-memory-buffer-video-frames');
|
||||
}
|
||||
|
||||
// Stops chromium from launching its own MPRIS service
|
||||
if (config.plugins.isEnabled('shortcuts')) {
|
||||
app.commandLine.appendSwitch('disable-features', 'MediaSessionService');
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { FastAverageColor } from 'fast-average-color';
|
||||
import Color from 'color';
|
||||
import Color, { ColorInstance } from 'color';
|
||||
|
||||
import style from './style.css?inline';
|
||||
|
||||
@ -14,8 +14,8 @@ export default createPlugin<
|
||||
unknown,
|
||||
unknown,
|
||||
{
|
||||
color?: Color;
|
||||
darkColor?: Color;
|
||||
color?: ColorInstance;
|
||||
darkColor?: ColorInstance;
|
||||
|
||||
playerPage: HTMLElement | null;
|
||||
navBarBackground: HTMLElement | null;
|
||||
|
||||
@ -154,15 +154,14 @@ export const backend = createBackend<
|
||||
// @see https://discord.com/developers/docs/topics/gateway#activity-object
|
||||
// not all options are transfered through https://github.com/discordjs/RPC/blob/6f83d8d812c87cb7ae22064acd132600407d7d05/src/client.js#L518-530
|
||||
const hangulFillerUnicodeCharacter = '\u3164'; // This is an empty character
|
||||
if (songInfo.title.length < 2) {
|
||||
songInfo.title += hangulFillerUnicodeCharacter.repeat(
|
||||
2 - songInfo.title.length,
|
||||
);
|
||||
}
|
||||
if (songInfo.artist.length < 2) {
|
||||
songInfo.artist += hangulFillerUnicodeCharacter.repeat(
|
||||
2 - songInfo.title.length,
|
||||
);
|
||||
const paddedInfoKeys: (keyof SongInfo)[] = ['title', 'artist', 'album'];
|
||||
for (const key of paddedInfoKeys) {
|
||||
const keyLength = (songInfo[key] as string)?.length;
|
||||
if (keyLength < 2) {
|
||||
(songInfo[key] as string) += hangulFillerUnicodeCharacter.repeat(
|
||||
2 - keyLength,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// see https://github.com/th-ch/youtube-music/issues/1664
|
||||
|
||||
@ -55,10 +55,20 @@ let yt: Innertube;
|
||||
let win: BrowserWindow;
|
||||
let playingUrl: string;
|
||||
|
||||
const isYouTubePremium = () =>
|
||||
win.webContents.executeJavaScript(
|
||||
'!document.querySelector(\'#endpoint[href="/music_premium"]\')',
|
||||
) as Promise<boolean>;
|
||||
const isYouTubeMusicPremium = async () => {
|
||||
const upgradeBtnIconPathData = (await win.webContents.executeJavaScript(
|
||||
'document.querySelector(\'iron-iconset-svg[name="yt-sys-icons"] #youtube_music_monochrome\')?.firstChild?.getAttribute("d")?.substring(0, 15)',
|
||||
)) as string | null;
|
||||
|
||||
// Fallback to non-premium if the icon is not found
|
||||
if (!upgradeBtnIconPathData) return false;
|
||||
|
||||
const selector = `ytmusic-guide-entry-renderer:has(> tp-yt-paper-item > yt-icon path[d^="${upgradeBtnIconPathData}"])`;
|
||||
|
||||
return (await win.webContents.executeJavaScript(
|
||||
`!document.querySelector('${selector}')`,
|
||||
)) as boolean;
|
||||
};
|
||||
|
||||
const sendError = (error: Error, source?: string) => {
|
||||
win.setProgressBar(-1); // Close progress bar
|
||||
@ -116,6 +126,11 @@ export const onMainLoad = async ({
|
||||
const visitorData = yt.session.context.client.visitorData;
|
||||
|
||||
if (visitorData) {
|
||||
const cleanUp = (context: Partial<typeof globalThis>) => {
|
||||
delete context.window;
|
||||
delete context.document;
|
||||
};
|
||||
|
||||
try {
|
||||
const [width, height] = win.getSize();
|
||||
// emulate jsdom using linkedom
|
||||
@ -153,16 +168,16 @@ export const onMainLoad = async ({
|
||||
program: bgChallenge.program,
|
||||
globalName: bgChallenge.globalName,
|
||||
bgConfig,
|
||||
}).finally(() => {
|
||||
cleanUp(globalThis);
|
||||
});
|
||||
|
||||
yt.session.po_token = poTokenResult.poToken;
|
||||
} else {
|
||||
cleanUp(globalThis);
|
||||
}
|
||||
} finally {
|
||||
// Bypass TypeScript checks
|
||||
((x: Partial<typeof globalThis>) => {
|
||||
delete x.window;
|
||||
delete x.document;
|
||||
})(globalThis);
|
||||
} catch {
|
||||
cleanUp(globalThis);
|
||||
}
|
||||
}
|
||||
|
||||
@ -365,7 +380,7 @@ async function downloadSongUnsafe(
|
||||
}
|
||||
|
||||
const downloadOptions: FormatOptions = {
|
||||
type: (await isYouTubePremium()) ? 'audio' : 'video+audio', // Audio, video or video+audio
|
||||
type: (await isYouTubeMusicPremium()) ? 'audio' : 'video+audio', // Audio, video or video+audio
|
||||
quality: 'best', // Best, bestefficiency, 144p, 240p, 480p, 720p and so on.
|
||||
format: 'any', // Media container format
|
||||
};
|
||||
@ -624,7 +639,12 @@ export async function downloadPlaylist(givenUrl?: string | URL) {
|
||||
try {
|
||||
playlist = await yt.music.getPlaylist(playlistId);
|
||||
if (playlist?.items) {
|
||||
items.push(...playlist.items.as(YTNodes.MusicResponsiveListItem));
|
||||
const filteredItems = playlist.items.filter(
|
||||
(item): item is YTNodes.MusicResponsiveListItem =>
|
||||
item instanceof YTNodes.MusicResponsiveListItem,
|
||||
);
|
||||
|
||||
items.push(...filteredItems);
|
||||
}
|
||||
} catch (error: unknown) {
|
||||
sendError(
|
||||
@ -659,9 +679,13 @@ export async function downloadPlaylist(givenUrl?: string | URL) {
|
||||
|
||||
while (playlist.has_continuation) {
|
||||
playlist = await playlist.getContinuation();
|
||||
if (playlist?.items) {
|
||||
items.push(...playlist.items.as(YTNodes.MusicResponsiveListItem));
|
||||
}
|
||||
|
||||
const filteredItems = playlist.items.filter(
|
||||
(item): item is YTNodes.MusicResponsiveListItem =>
|
||||
item instanceof YTNodes.MusicResponsiveListItem,
|
||||
);
|
||||
|
||||
items.push(...filteredItems);
|
||||
}
|
||||
|
||||
if (items.length === 1) {
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
align-items: center;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
cursor: pointer;
|
||||
margin: 0 var(--ytd-rich-grid-item-margin);
|
||||
margin: 0 var(--ytd-margin-2x, 8px);
|
||||
}
|
||||
|
||||
.navigation-item:hover {
|
||||
@ -32,4 +32,5 @@
|
||||
width: var(--iron-icon-width, 24px);
|
||||
height: var(--iron-icon-height, 24px);
|
||||
animation: var(--iron-icon_-_animation);
|
||||
padding: var(--ytd-margin-base, 4px) var(--ytd-margin-2x, 8px);
|
||||
}
|
||||
|
||||
@ -22,27 +22,5 @@ export default createPlugin({
|
||||
node.remove();
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the library button
|
||||
const libraryIconPath =
|
||||
'M16,6v2h-2v5c0,1.1-0.9,2-2,2s-2-0.9-2-2s0.9-2,2-2c0.37,0,0.7,0.11,1,0.28V6H16z M18,20H4V6H3v15h15V20z M21,3H6v15h15V3z M7,4h13v13H7V4z';
|
||||
const observer = new MutationObserver(() => {
|
||||
const menuEntries = document.querySelectorAll(
|
||||
'#items ytmusic-guide-entry-renderer',
|
||||
);
|
||||
menuEntries.forEach((item) => {
|
||||
const icon = item.querySelector('path');
|
||||
if (icon) {
|
||||
observer.disconnect();
|
||||
if (icon.getAttribute('d') === libraryIconPath) {
|
||||
item.remove();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
observer.observe(document.documentElement, {
|
||||
childList: true,
|
||||
subtree: true,
|
||||
});
|
||||
},
|
||||
});
|
||||
});
|
||||
@ -50,7 +50,7 @@ export const SyncedLine = ({ line }: SyncedLineProps) => {
|
||||
_ytAPI?.seekTo(line.timeInMs / 1000);
|
||||
}}
|
||||
>
|
||||
<div class="text-lyrics description ytmusic-description-shelf-renderer">
|
||||
<div dir="auto" class="text-lyrics description ytmusic-description-shelf-renderer">
|
||||
<yt-formatted-string
|
||||
text={{
|
||||
runs: [{ text: config()?.showTimeCodes ? `[${line.time}] ` : '' }],
|
||||
|
||||
@ -71,7 +71,7 @@ export function throttle<T extends (...params: unknown[]) => unknown>(
|
||||
}) as T;
|
||||
}
|
||||
|
||||
function memoize<T extends (...params: unknown[]) => unknown>(fn: T): T {
|
||||
export function memoize<T extends (...params: unknown[]) => unknown>(fn: T): T {
|
||||
const cache = new Map();
|
||||
|
||||
return ((...args) => {
|
||||
@ -84,7 +84,7 @@ function memoize<T extends (...params: unknown[]) => unknown>(fn: T): T {
|
||||
}) as T;
|
||||
}
|
||||
|
||||
function retry<T extends (...params: unknown[]) => Promise<unknown>>(
|
||||
export function retry<T extends (...params: unknown[]) => Promise<unknown>>(
|
||||
fn: T,
|
||||
{ retries = 3, delay = 1000 } = {},
|
||||
) {
|
||||
@ -102,12 +102,3 @@ function retry<T extends (...params: unknown[]) => Promise<unknown>>(
|
||||
throw latestError;
|
||||
};
|
||||
}
|
||||
|
||||
export default {
|
||||
singleton,
|
||||
debounce,
|
||||
cache,
|
||||
throttle,
|
||||
memoize,
|
||||
retry,
|
||||
};
|
||||
|
||||
@ -7,15 +7,15 @@ import { Project } from 'ts-morph';
|
||||
const snakeToCamel = (text: string) =>
|
||||
text.replace(/-(\w)/g, (_, letter: string) => letter.toUpperCase());
|
||||
|
||||
export const i18nImporter = () => {
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const project = new Project({
|
||||
tsConfigFilePath: resolve(__dirname, '..', 'tsconfig.json'),
|
||||
skipAddingFilesFromTsConfig: true,
|
||||
skipLoadingLibFiles: true,
|
||||
skipFileDependencyResolution: true,
|
||||
});
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const globalProject = new Project({
|
||||
tsConfigFilePath: resolve(__dirname, '..', 'tsconfig.json'),
|
||||
skipAddingFilesFromTsConfig: true,
|
||||
skipLoadingLibFiles: true,
|
||||
skipFileDependencyResolution: true,
|
||||
});
|
||||
|
||||
export const i18nImporter = () => {
|
||||
const srcPath = resolve(__dirname, '..', 'src');
|
||||
const plugins = globSync(['src/i18n/resources/*.json']).map((path) => {
|
||||
const nameWithExt = basename(path);
|
||||
@ -24,24 +24,28 @@ export const i18nImporter = () => {
|
||||
return { name, path };
|
||||
});
|
||||
|
||||
const src = project.createSourceFile('vm:i18n', (writer) => {
|
||||
// prettier-ignore
|
||||
for (const { name, path } of plugins) {
|
||||
const src = globalProject.createSourceFile(
|
||||
'vm:i18n',
|
||||
(writer) => {
|
||||
// prettier-ignore
|
||||
for (const { name, path } of plugins) {
|
||||
const relativePath = relative(resolve(srcPath, '..'), path).replace(/\\/g, '/');
|
||||
writer.writeLine(`import ${snakeToCamel(name)}Json from "./${relativePath}";`);
|
||||
}
|
||||
|
||||
writer.blankLine();
|
||||
writer.blankLine();
|
||||
|
||||
writer.writeLine('export const languageResources = {');
|
||||
for (const { name } of plugins) {
|
||||
writer.writeLine(` "${name}": {`);
|
||||
writer.writeLine(` translation: ${snakeToCamel(name)}Json,`);
|
||||
writer.writeLine(' },');
|
||||
}
|
||||
writer.writeLine('};');
|
||||
writer.blankLine();
|
||||
});
|
||||
writer.writeLine('export const languageResources = {');
|
||||
for (const { name } of plugins) {
|
||||
writer.writeLine(` "${name}": {`);
|
||||
writer.writeLine(` translation: ${snakeToCamel(name)}Json,`);
|
||||
writer.writeLine(' },');
|
||||
}
|
||||
writer.writeLine('};');
|
||||
writer.blankLine();
|
||||
},
|
||||
{ overwrite: true },
|
||||
);
|
||||
|
||||
return src.getText();
|
||||
};
|
||||
|
||||
@ -7,17 +7,17 @@ import { Project } from 'ts-morph';
|
||||
const snakeToCamel = (text: string) =>
|
||||
text.replace(/-(\w)/g, (_, letter: string) => letter.toUpperCase());
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const globalProject = new Project({
|
||||
tsConfigFilePath: resolve(__dirname, '..', 'tsconfig.json'),
|
||||
skipAddingFilesFromTsConfig: true,
|
||||
skipLoadingLibFiles: true,
|
||||
skipFileDependencyResolution: true,
|
||||
});
|
||||
|
||||
export const pluginVirtualModuleGenerator = (
|
||||
mode: 'main' | 'preload' | 'renderer',
|
||||
) => {
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const project = new Project({
|
||||
tsConfigFilePath: resolve(__dirname, '..', 'tsconfig.json'),
|
||||
skipAddingFilesFromTsConfig: true,
|
||||
skipLoadingLibFiles: true,
|
||||
skipFileDependencyResolution: true,
|
||||
});
|
||||
|
||||
const srcPath = resolve(__dirname, '..', 'src');
|
||||
const plugins = globSync([
|
||||
'src/plugins/*/index.{js,ts}',
|
||||
@ -35,35 +35,39 @@ export const pluginVirtualModuleGenerator = (
|
||||
return { name, path };
|
||||
});
|
||||
|
||||
const src = project.createSourceFile('vm:pluginIndexes', (writer) => {
|
||||
// prettier-ignore
|
||||
for (const { name, path } of plugins) {
|
||||
const src = globalProject.createSourceFile(
|
||||
'vm:pluginIndexes',
|
||||
(writer) => {
|
||||
// prettier-ignore
|
||||
for (const { name, path } of plugins) {
|
||||
const relativePath = relative(resolve(srcPath, '..'), path).replace(/\\/g, '/');
|
||||
writer.writeLine(`import ${snakeToCamel(name)}Plugin, { pluginStub as ${snakeToCamel(name)}PluginStub } from "./${relativePath}";`);
|
||||
}
|
||||
|
||||
writer.blankLine();
|
||||
writer.blankLine();
|
||||
|
||||
// Context-specific exports
|
||||
writer.writeLine(`export const ${mode}Plugins = {`);
|
||||
for (const { name } of plugins) {
|
||||
const checkMode = mode === 'main' ? 'backend' : mode;
|
||||
// HACK: To avoid situation like importing renderer plugins in main
|
||||
writer.writeLine(
|
||||
` ...(${snakeToCamel(name)}Plugin['${checkMode}'] ? { "${name}": ${snakeToCamel(name)}Plugin } : {}),`,
|
||||
);
|
||||
}
|
||||
writer.writeLine('};');
|
||||
writer.blankLine();
|
||||
// Context-specific exports
|
||||
writer.writeLine(`export const ${mode}Plugins = {`);
|
||||
for (const { name } of plugins) {
|
||||
const checkMode = mode === 'main' ? 'backend' : mode;
|
||||
// HACK: To avoid situation like importing renderer plugins in main
|
||||
writer.writeLine(
|
||||
` ...(${snakeToCamel(name)}Plugin['${checkMode}'] ? { "${name}": ${snakeToCamel(name)}Plugin } : {}),`,
|
||||
);
|
||||
}
|
||||
writer.writeLine('};');
|
||||
writer.blankLine();
|
||||
|
||||
// All plugins export (stub only) // Omit<Plugin, 'backend' | 'preload' | 'renderer'>
|
||||
writer.writeLine('export const allPlugins = {');
|
||||
for (const { name } of plugins) {
|
||||
writer.writeLine(` "${name}": ${snakeToCamel(name)}PluginStub,`);
|
||||
}
|
||||
writer.writeLine('};');
|
||||
writer.blankLine();
|
||||
});
|
||||
// All plugins export (stub only) // Omit<Plugin, 'backend' | 'preload' | 'renderer'>
|
||||
writer.writeLine('export const allPlugins = {');
|
||||
for (const { name } of plugins) {
|
||||
writer.writeLine(` "${name}": ${snakeToCamel(name)}PluginStub,`);
|
||||
}
|
||||
writer.writeLine('};');
|
||||
writer.blankLine();
|
||||
},
|
||||
{ overwrite: true },
|
||||
);
|
||||
|
||||
return src.getText();
|
||||
};
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { readFile } from 'node:fs/promises';
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { resolve, basename, dirname } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
@ -8,10 +8,34 @@ import {
|
||||
ts,
|
||||
ObjectLiteralExpression,
|
||||
VariableDeclarationKind,
|
||||
Node,
|
||||
type ObjectLiteralElementLike,
|
||||
} from 'ts-morph';
|
||||
|
||||
import type { PluginOption } from 'vite';
|
||||
|
||||
// Initialize a global project instance to reuse across load calls
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const globalProject = new Project({
|
||||
tsConfigFilePath: resolve(__dirname, '..', 'tsconfig.json'),
|
||||
skipAddingFilesFromTsConfig: true,
|
||||
skipLoadingLibFiles: true,
|
||||
skipFileDependencyResolution: true,
|
||||
});
|
||||
|
||||
// Helper to extract a property’s name from its node
|
||||
const getPropertyName = (prop: Node): string | null => {
|
||||
const kind = prop.getKind();
|
||||
if (
|
||||
kind === ts.SyntaxKind.PropertyAssignment ||
|
||||
kind === ts.SyntaxKind.ShorthandPropertyAssignment ||
|
||||
kind === ts.SyntaxKind.MethodDeclaration
|
||||
) {
|
||||
return prop.getFirstChildByKindOrThrow(ts.SyntaxKind.Identifier).getText();
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
export default function (
|
||||
mode: 'backend' | 'preload' | 'renderer' | 'none',
|
||||
): PluginOption {
|
||||
@ -22,131 +46,96 @@ export default function (
|
||||
|
||||
return {
|
||||
name: 'ytm-plugin-loader',
|
||||
async load(id) {
|
||||
load(id) {
|
||||
if (!pluginFilter(id)) return null;
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
const project = new Project({
|
||||
tsConfigFilePath: resolve(__dirname, '..', 'tsconfig.json'),
|
||||
skipAddingFilesFromTsConfig: true,
|
||||
skipLoadingLibFiles: true,
|
||||
skipFileDependencyResolution: true,
|
||||
});
|
||||
|
||||
const src = project.createSourceFile(
|
||||
// Read file asynchronously
|
||||
const fileContent = readFileSync(id, 'utf8');
|
||||
// Create or update source file in the global project instance
|
||||
const src = globalProject.createSourceFile(
|
||||
'_pf' + basename(id),
|
||||
await readFile(id, 'utf8'),
|
||||
fileContent,
|
||||
{ overwrite: true },
|
||||
);
|
||||
|
||||
const exports = src.getExportedDeclarations();
|
||||
let objExpr: ObjectLiteralExpression | undefined = undefined;
|
||||
let objExpr: ObjectLiteralExpression | undefined;
|
||||
|
||||
for (const [name, [expr]] of exports) {
|
||||
if (name !== 'default') continue;
|
||||
|
||||
switch (expr.getKind()) {
|
||||
case ts.SyntaxKind.ObjectLiteralExpression: {
|
||||
objExpr = expr.asKindOrThrow(ts.SyntaxKind.ObjectLiteralExpression);
|
||||
break;
|
||||
}
|
||||
case ts.SyntaxKind.CallExpression: {
|
||||
const callExpr = expr.asKindOrThrow(ts.SyntaxKind.CallExpression);
|
||||
if (callExpr.getArguments().length !== 1) continue;
|
||||
|
||||
const name = callExpr.getExpression().getText();
|
||||
if (name !== 'createPlugin') continue;
|
||||
// Identify the default export as an object literal, or via a 'createPlugin' call
|
||||
for (const [exportName, declarations] of exports) {
|
||||
if (exportName !== 'default') continue;
|
||||
const expr = declarations[0];
|
||||
|
||||
const exprKind = expr.getKind();
|
||||
if (exprKind === ts.SyntaxKind.ObjectLiteralExpression) {
|
||||
objExpr = expr.asKindOrThrow(ts.SyntaxKind.ObjectLiteralExpression);
|
||||
break;
|
||||
} else if (exprKind === ts.SyntaxKind.CallExpression) {
|
||||
const callExpr = expr.asKindOrThrow(ts.SyntaxKind.CallExpression);
|
||||
if (
|
||||
callExpr.getArguments().length === 1 &&
|
||||
callExpr.getExpression().getText() === 'createPlugin'
|
||||
) {
|
||||
const arg = callExpr.getArguments()[0];
|
||||
if (arg.getKind() !== ts.SyntaxKind.ObjectLiteralExpression)
|
||||
continue;
|
||||
|
||||
objExpr = arg.asKindOrThrow(ts.SyntaxKind.ObjectLiteralExpression);
|
||||
break;
|
||||
if (arg.getKind() === ts.SyntaxKind.ObjectLiteralExpression) {
|
||||
objExpr = arg.asKindOrThrow(
|
||||
ts.SyntaxKind.ObjectLiteralExpression,
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!objExpr) return null;
|
||||
|
||||
const properties = objExpr.getProperties();
|
||||
const propertyNames = properties.map((prop) => {
|
||||
switch (prop.getKind()) {
|
||||
case ts.SyntaxKind.PropertyAssignment:
|
||||
return prop
|
||||
.asKindOrThrow(ts.SyntaxKind.PropertyAssignment)
|
||||
.getName();
|
||||
case ts.SyntaxKind.ShorthandPropertyAssignment:
|
||||
return prop
|
||||
.asKindOrThrow(ts.SyntaxKind.ShorthandPropertyAssignment)
|
||||
.getName();
|
||||
case ts.SyntaxKind.MethodDeclaration:
|
||||
return prop
|
||||
.asKindOrThrow(ts.SyntaxKind.MethodDeclaration)
|
||||
.getName();
|
||||
default:
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
});
|
||||
// Build a map of property names to their AST nodes for fast lookup
|
||||
const propMap = new Map<string, ObjectLiteralElementLike>();
|
||||
for (const prop of objExpr.getProperties()) {
|
||||
const name = getPropertyName(prop);
|
||||
if (name) propMap.set(name, prop);
|
||||
}
|
||||
|
||||
const contexts = ['backend', 'preload', 'renderer', 'menu'];
|
||||
for (const ctx of contexts) {
|
||||
if (mode === 'none') {
|
||||
const index = propertyNames.indexOf(ctx);
|
||||
if (index === -1) continue;
|
||||
|
||||
objExpr.getProperty(propertyNames[index])?.remove();
|
||||
if (mode === 'none' && propMap.has(ctx)) {
|
||||
propMap.get(ctx)?.remove();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ctx === mode) continue;
|
||||
if (ctx === 'menu' && mode === 'backend') continue;
|
||||
|
||||
const index = propertyNames.indexOf(ctx);
|
||||
if (index === -1) continue;
|
||||
|
||||
objExpr.getProperty(propertyNames[index])?.remove();
|
||||
if (ctx === mode || (ctx === 'menu' && mode === 'backend')) continue;
|
||||
if (propMap.has(ctx)) propMap.get(ctx)?.remove();
|
||||
}
|
||||
|
||||
const stubObjExpr = src
|
||||
.addVariableStatement({
|
||||
isExported: true,
|
||||
declarationKind: VariableDeclarationKind.Const,
|
||||
declarations: [
|
||||
{
|
||||
name: 'pluginStub',
|
||||
initializer: (writer) => writer.write(objExpr.getText()),
|
||||
},
|
||||
],
|
||||
})
|
||||
.getDeclarations()[0]
|
||||
.getInitializer() as ObjectLiteralExpression;
|
||||
|
||||
const stubProperties = stubObjExpr.getProperties();
|
||||
const stubPropertyNames = stubProperties.map((prop) => {
|
||||
switch (prop.getKind()) {
|
||||
case ts.SyntaxKind.PropertyAssignment:
|
||||
return prop
|
||||
.asKindOrThrow(ts.SyntaxKind.PropertyAssignment)
|
||||
.getName();
|
||||
case ts.SyntaxKind.ShorthandPropertyAssignment:
|
||||
return prop
|
||||
.asKindOrThrow(ts.SyntaxKind.ShorthandPropertyAssignment)
|
||||
.getName();
|
||||
case ts.SyntaxKind.MethodDeclaration:
|
||||
return prop
|
||||
.asKindOrThrow(ts.SyntaxKind.MethodDeclaration)
|
||||
.getName();
|
||||
default:
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
// Add an exported variable 'pluginStub' with the modified object literal's text
|
||||
const varStmt = src.addVariableStatement({
|
||||
isExported: true,
|
||||
declarationKind: VariableDeclarationKind.Const,
|
||||
declarations: [
|
||||
{
|
||||
name: 'pluginStub',
|
||||
initializer: (writer) => writer.write(objExpr.getText()),
|
||||
},
|
||||
],
|
||||
});
|
||||
const stubObjExpr = varStmt
|
||||
.getDeclarations()[0]
|
||||
.getInitializerIfKindOrThrow(ts.SyntaxKind.ObjectLiteralExpression);
|
||||
|
||||
if (mode === 'backend') contexts.pop();
|
||||
for (const ctx of contexts) {
|
||||
const index = stubPropertyNames.indexOf(ctx);
|
||||
if (index === -1) continue;
|
||||
// Similarly build a map for the stub properties
|
||||
const stubMap = new Map<string, ObjectLiteralElementLike>();
|
||||
for (const prop of stubObjExpr.getProperties()) {
|
||||
const name = getPropertyName(prop);
|
||||
if (name) stubMap.set(name, prop);
|
||||
}
|
||||
|
||||
stubObjExpr.getProperty(stubPropertyNames[index])?.remove();
|
||||
const stubContexts =
|
||||
mode === 'backend'
|
||||
? contexts.filter((ctx) => ctx !== 'menu')
|
||||
: contexts;
|
||||
for (const ctx of stubContexts) {
|
||||
if (stubMap.has(ctx)) {
|
||||
stubMap.get(ctx)?.remove();
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user