mirror of
https://github.com/th-ch/youtube-music.git
synced 2026-01-10 10:11:46 +00:00
Compare commits
28 Commits
v3.3.3
...
feat/webno
| Author | SHA1 | Date | |
|---|---|---|---|
| 22b74113b6 | |||
| 9da3ad2fb7 | |||
| d45d597136 | |||
| 2495d5da99 | |||
| 33aeafd19c | |||
| 374d0ce5e7 | |||
| 371805334b | |||
| 47dbeff0d0 | |||
| 17652b5b77 | |||
| 9608c2a7fc | |||
| 8abe2823d7 | |||
| dbc7f23ab8 | |||
| 357bd935e4 | |||
| f99ca53a6d | |||
| 8700c1a110 | |||
| c5e37b791c | |||
| 307f6387ab | |||
| 652a150a0a | |||
| 2c59badb46 | |||
| 69087bbf1f | |||
| af78f1596a | |||
| fca936a698 | |||
| 54b70f6b3e | |||
| 62f7d440fa | |||
| 752ccbf482 | |||
| a8bc53912d | |||
| ed700c2916 | |||
| 97695444af |
88
changelog.md
88
changelog.md
@ -2,8 +2,96 @@
|
||||
|
||||
All notable changes to this project will be documented in this file. Dates are displayed in UTC.
|
||||
|
||||
#### [v3.3.5](https://github.com/th-ch/youtube-music/compare/v3.3.4...v3.3.5)
|
||||
|
||||
- chore(deps): update dependency node-gyp to v10.1.0 [`#1885`](https://github.com/th-ch/youtube-music/pull/1885)
|
||||
- chore(deps): update dependency @typescript-eslint/eslint-plugin to v7.4.0 [`#1886`](https://github.com/th-ch/youtube-music/pull/1886)
|
||||
- chore(deps): update dependency vite to v5.2.6 [`#1883`](https://github.com/th-ch/youtube-music/pull/1883)
|
||||
- fix(style): resolve #1887 [`#1887`](https://github.com/th-ch/youtube-music/issues/1887)
|
||||
- chore(i18n): Translated using Weblate (Swedish) [`69087bb`](https://github.com/th-ch/youtube-music/commit/69087bbf1fac1ba58e992146deb1d6f1706b1e3c)
|
||||
- chore(i18n): Translated using Weblate (French) [`af78f15`](https://github.com/th-ch/youtube-music/commit/af78f1596ab8db2fa7069fdb1c4f078099ce4446)
|
||||
- Update changelog for v3.3.4 [`62f7d44`](https://github.com/th-ch/youtube-music/commit/62f7d440fab5bdbe9f49a3a5f8c32e7aaf2f28f6)
|
||||
|
||||
#### [v3.3.4](https://github.com/th-ch/youtube-music/compare/v3.3.3...v3.3.4)
|
||||
|
||||
> 24 March 2024
|
||||
|
||||
- Update changelog for v3.3.3 [`9769544`](https://github.com/th-ch/youtube-music/commit/97695444affbacb71dd73ae7107d4c987e285a37)
|
||||
- fix(style): fix fullscreen style and in-app-menu [`ed700c2`](https://github.com/th-ch/youtube-music/commit/ed700c2916cc7e6ccd2010d0c552364af116eb4f)
|
||||
- fix(style): fix miniplayer style [`a8bc539`](https://github.com/th-ch/youtube-music/commit/a8bc53912d1f4137008ecb2d9d5d9d9eb06ee2a8)
|
||||
|
||||
#### [v3.3.3](https://github.com/th-ch/youtube-music/compare/v3.3.2...v3.3.3)
|
||||
|
||||
> 24 March 2024
|
||||
|
||||
- chore(deps): update dependency electron to v29.1.5 [`#1876`](https://github.com/th-ch/youtube-music/pull/1876)
|
||||
- chore(deps): update dependency typescript to v5.4.3 [`#1877`](https://github.com/th-ch/youtube-music/pull/1877)
|
||||
- chore(deps): update dependency discord-api-types to v0.37.76 [`#1878`](https://github.com/th-ch/youtube-music/pull/1878)
|
||||
- chore(deps): update dependency vite to v5.2.4 [`#1881`](https://github.com/th-ch/youtube-music/pull/1881)
|
||||
- Ambient Plugin cleanup [`#1880`](https://github.com/th-ch/youtube-music/pull/1880)
|
||||
- chore(deps): update dependency vite to v5.2.2 [`#1875`](https://github.com/th-ch/youtube-music/pull/1875)
|
||||
- fix(deps): update dependency solid-js to v1.8.16 [`#1873`](https://github.com/th-ch/youtube-music/pull/1873)
|
||||
- chore(deps): update dependency @typescript-eslint/eslint-plugin to v7.3.1 [`#1868`](https://github.com/th-ch/youtube-music/pull/1868)
|
||||
- chore(deps): update dependency discord-api-types to v0.37.75 [`#1867`](https://github.com/th-ch/youtube-music/pull/1867)
|
||||
- chore(deps): update pnpm to v8.15.5 [`#1865`](https://github.com/th-ch/youtube-music/pull/1865)
|
||||
- fix: Fix Miniplayer image size [`#1863`](https://github.com/th-ch/youtube-music/pull/1863)
|
||||
- fix(style): fixed image/video alignment when toggle is active [`#1862`](https://github.com/th-ch/youtube-music/pull/1862)
|
||||
- chore: Update README-is.md [`#1858`](https://github.com/th-ch/youtube-music/pull/1858)
|
||||
- chore(deps): update dependency vite-plugin-solid to v2.10.2 [`#1859`](https://github.com/th-ch/youtube-music/pull/1859)
|
||||
- fix: Ambient Mode intialization improvement [`#1857`](https://github.com/th-ch/youtube-music/pull/1857)
|
||||
- chore(deps): bump follow-redirects from 1.15.5 to 1.15.6 [`#1856`](https://github.com/th-ch/youtube-music/pull/1856)
|
||||
- chore(README): Nicer Readme 2.0 [`#1833`](https://github.com/th-ch/youtube-music/pull/1833)
|
||||
- chore(deps): update dependency discord-api-types to v0.37.74 [`#1854`](https://github.com/th-ch/youtube-music/pull/1854)
|
||||
- chore(deps): update dependency esbuild to v0.20.2 [`#1855`](https://github.com/th-ch/youtube-music/pull/1855)
|
||||
- Improve ambient mode [`#1853`](https://github.com/th-ch/youtube-music/pull/1853)
|
||||
- chore(deps): update dependency electron to v29.1.4 [`#1852`](https://github.com/th-ch/youtube-music/pull/1852)
|
||||
- chore(deps): update dependency electron to v29.1.3 [`#1851`](https://github.com/th-ch/youtube-music/pull/1851)
|
||||
- chore(deps): update dependency rollup to v4.13.0 [`#1850`](https://github.com/th-ch/youtube-music/pull/1850)
|
||||
- fix(deps): update dependency electron-store to v8.2.0 [`#1843`](https://github.com/th-ch/youtube-music/pull/1843)
|
||||
- chore(deps): update dependency electron to v29.1.1 [`#1841`](https://github.com/th-ch/youtube-music/pull/1841)
|
||||
- fix(deps): update dependency i18next to v23.10.1 [`#1842`](https://github.com/th-ch/youtube-music/pull/1842)
|
||||
- chore(deps): update dependency @typescript-eslint/eslint-plugin to v7.2.0 [`#1848`](https://github.com/th-ch/youtube-music/pull/1848)
|
||||
- chore(deps): update dependency vite to v5.1.6 [`#1847`](https://github.com/th-ch/youtube-music/pull/1847)
|
||||
- fix(deps): update dependency async-mutex to v0.5.0 [`#1849`](https://github.com/th-ch/youtube-music/pull/1849)
|
||||
- fix(deps): update dependency ts-morph to v22 [`#1846`](https://github.com/th-ch/youtube-music/pull/1846)
|
||||
- chore(deps): update dependency discord-api-types to v0.37.73 [`#1840`](https://github.com/th-ch/youtube-music/pull/1840)
|
||||
- chore(deps): update dependency rollup to v4.12.1 [`#1837`](https://github.com/th-ch/youtube-music/pull/1837)
|
||||
- chore: Changed a single word (README-is.md) [`#1836`](https://github.com/th-ch/youtube-music/pull/1836)
|
||||
- chore(deps): update dependency typescript to v5.4.2 [`#1838`](https://github.com/th-ch/youtube-music/pull/1838)
|
||||
- chore(deps): update dependency electron-vite to v2.1.0 [`#1823`](https://github.com/th-ch/youtube-music/pull/1823)
|
||||
- chore(deps): update dependency @typescript-eslint/eslint-plugin to v7.1.1 [`#1829`](https://github.com/th-ch/youtube-music/pull/1829)
|
||||
- chore(deps): update dependency vite to v5.1.5 [`#1831`](https://github.com/th-ch/youtube-music/pull/1831)
|
||||
- Revert "chore(deps): update dependency electron-builder to v24.13.3" [`#1818`](https://github.com/th-ch/youtube-music/pull/1818)
|
||||
- chore(deps): update dependency electron-builder to v24.13.3 [`#1774`](https://github.com/th-ch/youtube-music/pull/1774)
|
||||
- chore(deps): update playwright monorepo to v1.42.1 [`#1816`](https://github.com/th-ch/youtube-music/pull/1816)
|
||||
- fix: Add scale ratio for tray icons [`#1811`](https://github.com/th-ch/youtube-music/pull/1811)
|
||||
- Icelandic translation of the readme file [`#1806`](https://github.com/th-ch/youtube-music/pull/1806)
|
||||
- chore(deps): update dependency electron to v29.1.0 [`#1808`](https://github.com/th-ch/youtube-music/pull/1808)
|
||||
- chore(deps): update playwright monorepo to v1.42.0 [`#1805`](https://github.com/th-ch/youtube-music/pull/1805)
|
||||
- chore(deps): update dependency eslint to v8.57.0 [`#1793`](https://github.com/th-ch/youtube-music/pull/1793)
|
||||
- chore(deps): update dependency @typescript-eslint/eslint-plugin to v7.1.0 [`#1800`](https://github.com/th-ch/youtube-music/pull/1800)
|
||||
- chore(deps): update dependency discord-api-types to v0.37.71 [`#1799`](https://github.com/th-ch/youtube-music/pull/1799)
|
||||
- chore(deps): update pnpm to v8.15.4 [`#1795`](https://github.com/th-ch/youtube-music/pull/1795)
|
||||
- chore(deps): update dependency @types/semver to v7.5.8 [`#1797`](https://github.com/th-ch/youtube-music/pull/1797)
|
||||
- fix: center the pause icon [`#1786`](https://github.com/th-ch/youtube-music/pull/1786)
|
||||
- fix(deps): update dependency @cliqz/adblocker-electron to v1.26.16 [`#1788`](https://github.com/th-ch/youtube-music/pull/1788)
|
||||
- fix(deps): update dependency @cliqz/adblocker-electron-preload to v1.26.16 [`#1789`](https://github.com/th-ch/youtube-music/pull/1789)
|
||||
- fix(deps): update dependency youtubei.js to v9.1.0 [`#1790`](https://github.com/th-ch/youtube-music/pull/1790)
|
||||
- fix(deps): update dependency i18next to v23.10.0 [`#1785`](https://github.com/th-ch/youtube-music/pull/1785)
|
||||
- chore(deps): update dependency electron to v29 [`#1773`](https://github.com/th-ch/youtube-music/pull/1773)
|
||||
- chore(deps): update dependency vite to v5.1.4 [`#1778`](https://github.com/th-ch/youtube-music/pull/1778)
|
||||
- chore(deps): bump ip from 2.0.0 to 2.0.1 [`#1777`](https://github.com/th-ch/youtube-music/pull/1777)
|
||||
- fix: add support for Wayland [`#1864`](https://github.com/th-ch/youtube-music/issues/1864)
|
||||
- fix(style): fix navigation bar items are not working [`#1381`](https://github.com/th-ch/youtube-music/issues/1381) [`#1396`](https://github.com/th-ch/youtube-music/issues/1396) [`#1649`](https://github.com/th-ch/youtube-music/issues/1649)
|
||||
- fix(ytm-bugs): fixed a `scrollbar-color` bug that affected Chromium 121 and later [`#1737`](https://github.com/th-ch/youtube-music/issues/1737)
|
||||
- chore(i18n): Translated using Weblate (Icelandic) [`82fa871`](https://github.com/th-ch/youtube-music/commit/82fa8719a96abdfaaa8548a0077f4db2164ec09b)
|
||||
- chore(i18n): Translated using Weblate (Romanian) [`c871506`](https://github.com/th-ch/youtube-music/commit/c871506a69180308ab4fc587b6e8a33f193087e8)
|
||||
- chore(i18n): Translated using Weblate (Thai) [`a7d0350`](https://github.com/th-ch/youtube-music/commit/a7d035022a229f0b245694d1fc7a484befe1c269)
|
||||
|
||||
#### [v3.3.2](https://github.com/th-ch/youtube-music/compare/v3.3.1...v3.3.2)
|
||||
|
||||
> 20 February 2024
|
||||
|
||||
- fix: fix bugs in MPRIS, and improve MPRIS [`#1760`](https://github.com/th-ch/youtube-music/pull/1760)
|
||||
- fix(deps): update dependency electron-updater to v6.1.8 [`#1770`](https://github.com/th-ch/youtube-music/pull/1770)
|
||||
- chore(deps): update dependency electron-builder to v24.12.0 [`#1771`](https://github.com/th-ch/youtube-music/pull/1771)
|
||||
|
||||
18
package.json
18
package.json
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "youtube-music",
|
||||
"productName": "YouTube Music",
|
||||
"version": "3.3.3",
|
||||
"version": "3.3.5",
|
||||
"description": "YouTube Music Desktop App - including custom plugins",
|
||||
"main": "./dist/main/index.js",
|
||||
"license": "MIT",
|
||||
@ -172,6 +172,7 @@
|
||||
"node-html-parser": "6.1.12",
|
||||
"node-id3": "0.2.6",
|
||||
"peerjs": "1.5.2",
|
||||
"reconnecting-websocket": "4.4.0",
|
||||
"semver": "7.6.0",
|
||||
"serve": "14.2.1",
|
||||
"simple-youtube-age-restriction-bypass": "github:organization/Simple-YouTube-Age-Restriction-Bypass#v2.5.9",
|
||||
@ -181,6 +182,7 @@
|
||||
"solid-transition-group": "0.2.3",
|
||||
"ts-morph": "22.0.0",
|
||||
"vudio": "2.1.1",
|
||||
"ws": "8.16.0",
|
||||
"x11": "2.3.0",
|
||||
"youtubei.js": "9.1.0"
|
||||
},
|
||||
@ -192,13 +194,14 @@
|
||||
"@types/howler": "2.2.11",
|
||||
"@types/html-to-text": "9.0.4",
|
||||
"@types/semver": "7.5.8",
|
||||
"@typescript-eslint/eslint-plugin": "7.3.1",
|
||||
"@types/ws": "8.5.10",
|
||||
"@typescript-eslint/eslint-plugin": "7.4.0",
|
||||
"bufferutil": "4.0.8",
|
||||
"builtin-modules": "3.3.0",
|
||||
"cross-env": "7.0.3",
|
||||
"del-cli": "5.1.0",
|
||||
"discord-api-types": "0.37.76",
|
||||
"electron": "29.1.5",
|
||||
"electron": "29.1.6",
|
||||
"electron-builder": "24.9.1",
|
||||
"electron-devtools-installer": "3.2.0",
|
||||
"electron-vite": "2.1.0",
|
||||
@ -209,16 +212,15 @@
|
||||
"eslint-plugin-import": "2.29.1",
|
||||
"eslint-plugin-prettier": "5.1.3",
|
||||
"glob": "10.3.10",
|
||||
"node-gyp": "10.0.1",
|
||||
"node-gyp": "10.1.0",
|
||||
"playwright": "1.42.1",
|
||||
"rollup": "4.13.0",
|
||||
"rollup": "4.13.1",
|
||||
"typescript": "5.4.3",
|
||||
"utf-8-validate": "6.0.3",
|
||||
"vite": "5.2.4",
|
||||
"vite": "5.2.6",
|
||||
"vite-plugin-inspect": "0.8.3",
|
||||
"vite-plugin-resolve": "2.5.1",
|
||||
"vite-plugin-solid": "2.10.2",
|
||||
"ws": "8.16.0"
|
||||
"vite-plugin-solid": "2.10.2"
|
||||
},
|
||||
"auto-changelog": {
|
||||
"hideCredit": true,
|
||||
|
||||
466
pnpm-lock.yaml
generated
466
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -105,7 +105,7 @@
|
||||
"label": "Définir un proxy",
|
||||
"prompt": {
|
||||
"label": "Entrez l'adresse proxy : (laissez vide pour désactiver)",
|
||||
"placeholder": "Exemple: socks5://127.0.0.1:9999",
|
||||
"placeholder": "Exemple: SOCKS5://127.0.0.1:9999",
|
||||
"title": "Définir un proxy"
|
||||
}
|
||||
},
|
||||
@ -212,10 +212,18 @@
|
||||
},
|
||||
"album-color-theme": {
|
||||
"description": "Applique un thème dynamique et des effets visuels basés sur la palette des couleurs de l'album",
|
||||
"menu": {
|
||||
"color-mix-ratio": {
|
||||
"label": "Ratio de mélange des couleurs",
|
||||
"submenu": {
|
||||
"percent": "{{ratio}}%"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Thème de couleur d'album"
|
||||
},
|
||||
"ambient-mode": {
|
||||
"description": "Applique un effet d'éclairage en jetant des couleurs douces de la vidéo, dans le fond de votre écran.",
|
||||
"description": "Applique un effet d'éclairage en jetant des couleurs douces de la vidéo, dans le fond de votre écran",
|
||||
"menu": {
|
||||
"blur-amount": {
|
||||
"label": "Quantité de flou",
|
||||
@ -302,8 +310,8 @@
|
||||
"prompt": {
|
||||
"options": {
|
||||
"multi-input": {
|
||||
"fade-in-duration": "Durée du fondu (millisecondes)",
|
||||
"fade-out-duration": "Durée du fondu (millisecondes)",
|
||||
"fade-in-duration": "Durée du début du fondu (ms)",
|
||||
"fade-out-duration": "Durée de sortie du fondu (ms)",
|
||||
"fade-scaling": {
|
||||
"label": "Mise à l'échelle du fondu",
|
||||
"linear": "Linéaire",
|
||||
|
||||
1
src/i18n/resources/he.json
Normal file
1
src/i18n/resources/he.json
Normal file
@ -0,0 +1 @@
|
||||
{}
|
||||
@ -37,6 +37,14 @@
|
||||
},
|
||||
"when-ready": {
|
||||
"clearing-cache-after-20s": "App-cache wissen"
|
||||
},
|
||||
"window": {
|
||||
"tried-to-render-offscreen": "Venster probeerde buiten het scherm te renderen, venstergrootte={{windowSize}}, schermgrootte={{displaySize}}, positie={{position}}"
|
||||
}
|
||||
},
|
||||
"dialog": {
|
||||
"hide-menu-enabled": {
|
||||
"detail": "Menu is verborgen, gebruik 'Alt' om het te tonen (of 'Escape' als u het In-App Menu gebruikt)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -207,13 +207,14 @@
|
||||
"name": "Bloqueador de anúncios"
|
||||
},
|
||||
"album-actions": {
|
||||
"description": "Adiciona os botões Gostei e Não Gostei para ser aplicado a todas as músicas em uma lista de reprodução ou álbum.",
|
||||
"description": "Adiciona os botões Anular Rejeição, Não Gostei, Gostei e Anular o Gosto para ser aplicado a todas as músicas de uma lista de reprodução ou álbum",
|
||||
"name": "Ações no álbum"
|
||||
},
|
||||
"album-color-theme": {
|
||||
"description": "Aplica um tema dinâmico e efeitos visuais com base na paleta de cores do álbum",
|
||||
"menu": {
|
||||
"color-mix-ratio": {
|
||||
"label": "Rácio de mistura das cores",
|
||||
"submenu": {
|
||||
"percent": "Proporção"
|
||||
}
|
||||
@ -577,9 +578,11 @@
|
||||
"name": "Trocador de qualidade do vídeo"
|
||||
},
|
||||
"scrobbler": {
|
||||
"description": "Adicionar suporte para scrobbling (Last.fm, ListenBrainz)",
|
||||
"dialog": {
|
||||
"lastfm": {
|
||||
"auth-failed": {
|
||||
"message": "Falha ao autenticar com a Last.fm\nOculte o pop-up até a próxima reinicialização.",
|
||||
"title": "Falha na autenticação"
|
||||
}
|
||||
}
|
||||
@ -587,9 +590,18 @@
|
||||
"menu": {
|
||||
"lastfm": {
|
||||
"api-settings": "Configurações de API Last.fm"
|
||||
}
|
||||
},
|
||||
"listenbrainz": {
|
||||
"token": "Insira o token de utilizador ListenBrainz"
|
||||
},
|
||||
"scrobble-other-media": "Scrobble outros mídia"
|
||||
},
|
||||
"name": "Scrobbler",
|
||||
"prompt": {
|
||||
"lastfm": {
|
||||
"api-key": "Chave de API Last.fm",
|
||||
"api-secret": "Segredo da API Last.fm"
|
||||
},
|
||||
"listenbrainz": {
|
||||
"token": {
|
||||
"label": "Insira seu token de usuário do ListenBrainz:",
|
||||
|
||||
@ -491,7 +491,7 @@
|
||||
},
|
||||
"no-google-login": {
|
||||
"description": "Убрать из интерфейса кнопки и ссылки для входа через Google",
|
||||
"name": "Нет входа в систему Google"
|
||||
"name": "Без входа в систему Google"
|
||||
},
|
||||
"notifications": {
|
||||
"description": "Показывать уведомления о начале воспроизведения песни (интерактивные уведомления доступны в Windows)",
|
||||
@ -578,7 +578,7 @@
|
||||
"name": "Изменение качества видео"
|
||||
},
|
||||
"scrobbler": {
|
||||
"description": "Добавьте поддержку скробблинга (например, last.fm, Listenbrainz)",
|
||||
"description": "Добавляет поддержку скробблинга (last.fm, Listenbrainz)",
|
||||
"dialog": {
|
||||
"lastfm": {
|
||||
"auth-failed": {
|
||||
|
||||
107
src/i18n/resources/sv.json
Normal file
107
src/i18n/resources/sv.json
Normal file
@ -0,0 +1,107 @@
|
||||
{
|
||||
"language": {
|
||||
"code": "sv",
|
||||
"local-name": "Svenska",
|
||||
"name": "Swedish"
|
||||
},
|
||||
"plugins": {
|
||||
"navigation": {
|
||||
"name": "Navigering"
|
||||
},
|
||||
"no-google-login": {
|
||||
"name": "Inget Google Login"
|
||||
},
|
||||
"notifications": {
|
||||
"name": "Notiser"
|
||||
},
|
||||
"picture-in-picture": {
|
||||
"menu": {
|
||||
"hotkey": {
|
||||
"label": "Snabbkommando",
|
||||
"prompt": {
|
||||
"keybind-options": {
|
||||
"hotkey": "Snabbkommando"
|
||||
},
|
||||
"title": "Bild-I-Bild genväg"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Bild-I-Bild",
|
||||
"templates": {
|
||||
"button": "Bild-i-bild"
|
||||
}
|
||||
},
|
||||
"playback-speed": {
|
||||
"name": "Uppspelningshastighet",
|
||||
"templates": {
|
||||
"button": "Hasighet"
|
||||
}
|
||||
},
|
||||
"precise-volume": {
|
||||
"prompt": {
|
||||
"global-shortcuts": {
|
||||
"keybind-options": {
|
||||
"decrease": "Minska Volym",
|
||||
"increase": "Öka Volym"
|
||||
}
|
||||
},
|
||||
"volume-steps": {
|
||||
"title": "Volymsteg"
|
||||
}
|
||||
}
|
||||
},
|
||||
"quality-changer": {
|
||||
"backend": {
|
||||
"dialog": {
|
||||
"quality-changer": {
|
||||
"detail": "Nuvarande kvalité: {{quality}}",
|
||||
"message": "Välj Video Kvalité:",
|
||||
"title": "Välj Video Kvalité"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"scrobbler": {
|
||||
"prompt": {
|
||||
"lastfm": {
|
||||
"api-key": "Last.fm API nyckel"
|
||||
},
|
||||
"listenbrainz": {
|
||||
"token": {
|
||||
"title": "ListenBrainz token"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"shortcuts": {
|
||||
"prompt": {
|
||||
"keybind": {
|
||||
"keybind-options": {
|
||||
"next": "Nästa",
|
||||
"play-pause": "Spela / Pausa",
|
||||
"previous": "Föregående"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"video-toggle": {
|
||||
"menu": {
|
||||
"align": {
|
||||
"submenu": {
|
||||
"left": "Vänster",
|
||||
"middle": "Mitten",
|
||||
"right": "Höger"
|
||||
}
|
||||
},
|
||||
"mode": {
|
||||
"submenu": {
|
||||
"disabled": "Inaktiverad"
|
||||
}
|
||||
}
|
||||
},
|
||||
"templates": {
|
||||
"button": "Låt"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -83,7 +83,7 @@
|
||||
"navigation": {
|
||||
"label": "導覽列",
|
||||
"submenu": {
|
||||
"copy-current-url": "複製目前的網址",
|
||||
"copy-current-url": "複製當前頁面的網址",
|
||||
"go-back": "回到上一頁",
|
||||
"go-forward": "回到下一頁",
|
||||
"quit": "退出",
|
||||
@ -112,7 +112,7 @@
|
||||
"toggle-dev-tools": "切換開發者人員工具"
|
||||
}
|
||||
},
|
||||
"always-on-top": "永遠顯示在最上層",
|
||||
"always-on-top": "最上層顯示",
|
||||
"auto-update": "自動更新",
|
||||
"hide-menu": {
|
||||
"dialog": {
|
||||
@ -128,22 +128,22 @@
|
||||
},
|
||||
"label": "語言",
|
||||
"submenu": {
|
||||
"to-help-translate": "想要協助翻譯?按一下這裡"
|
||||
"to-help-translate": "想協助翻譯?按一下這裡"
|
||||
}
|
||||
},
|
||||
"resume-on-start": "應用啟動時繼續上次播放的歌曲",
|
||||
"single-instance-lock": "單視窗鎖定",
|
||||
"single-instance-lock": "單實例模式",
|
||||
"start-at-login": "開機時啟動",
|
||||
"starting-page": {
|
||||
"label": "啟動頁面",
|
||||
"unset": "不指定"
|
||||
},
|
||||
"tray": {
|
||||
"label": "系統閘圖式",
|
||||
"label": "系統閘",
|
||||
"submenu": {
|
||||
"disabled": "已停用",
|
||||
"enabled-and-hide-app": "啟用並隱藏應用程式",
|
||||
"enabled-and-show-app": "啟用並顯示應用程式",
|
||||
"enabled-and-hide-app": "啟用並最小化應用程式",
|
||||
"enabled-and-show-app": "啟用但持續顯示應用程式",
|
||||
"play-pause-on-click": "點擊時播放/暫停"
|
||||
}
|
||||
},
|
||||
@ -514,7 +514,7 @@
|
||||
"picture-in-picture": {
|
||||
"description": "允許應用程式切換至子母畫面模式",
|
||||
"menu": {
|
||||
"always-on-top": "永遠顯示在最上層",
|
||||
"always-on-top": "最上層顯示",
|
||||
"hotkey": {
|
||||
"label": "快捷鍵",
|
||||
"prompt": {
|
||||
|
||||
@ -24,19 +24,13 @@ yt-page-navigation-progress {
|
||||
background-color 300ms cubic-bezier(0.2, 0, 0.6, 1) !important;
|
||||
}
|
||||
|
||||
#img,
|
||||
#player,
|
||||
.song-media-controls.style-scope.ytmusic-player {
|
||||
border-radius: 2% !important;
|
||||
}
|
||||
|
||||
#items {
|
||||
border-radius: 10px !important;
|
||||
}
|
||||
|
||||
/* fix blur navigation bar */
|
||||
|
||||
ytmusic-app-layout > [slot='player-page'] {
|
||||
ytmusic-app-layout > [slot="player-page"]:not([is-mweb-modernization-enabled]) {
|
||||
padding-top: 90px;
|
||||
margin-top: calc(-90px + var(--menu-bar-height, 0px)) !important;
|
||||
}
|
||||
|
||||
@ -29,7 +29,7 @@
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#player:not([video-mode]):not(.video-mode):not([player-ui-state='MINIPLAYER']) {
|
||||
#player:not([video-mode]):not(.video-mode):not([player-ui-state='MINIPLAYER']):not([is-mweb-modernization-enabled]) {
|
||||
width: 100%;
|
||||
margin: 0 auto !important;
|
||||
overflow: visible;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { Menu, MenuItem } from 'electron';
|
||||
import { createEffect, createResource, createSignal, Index, Match, onMount, Show, Switch } from 'solid-js';
|
||||
import { createEffect, createResource, createSignal, Index, Match, onCleanup, onMount, Show, Switch } from 'solid-js';
|
||||
import { css } from 'solid-styled-components';
|
||||
import { TransitionGroup } from 'solid-transition-group';
|
||||
|
||||
@ -38,11 +38,16 @@ const titleStyle = cache(() => css`
|
||||
user-select: none;
|
||||
|
||||
transition: opacity 200ms ease 0s,
|
||||
transform 300ms cubic-bezier(0.2, 0, 0.6, 1) 0s,
|
||||
background-color 300ms cubic-bezier(0.2, 0, 0.6, 1) 0s;
|
||||
|
||||
&[data-macos="true"] {
|
||||
padding: 4px 4px 4px 74px;
|
||||
}
|
||||
|
||||
ytmusic-app:has(ytmusic-player[player-ui-state=FULLSCREEN]) ~ &:not([data-show="true"]) {
|
||||
transform: translateY(calc(-1 * var(--menu-bar-height, 32px)));
|
||||
}
|
||||
`);
|
||||
|
||||
const separatorStyle = cache(() => css`
|
||||
@ -162,6 +167,7 @@ export const TitleBar = (props: TitleBarProps) => {
|
||||
const [ignoreTransition, setIgnoreTransition] = createSignal(false);
|
||||
const [openTarget, setOpenTarget] = createSignal<HTMLElement | null>(null);
|
||||
const [menu, setMenu] = createSignal<Menu | null>(null);
|
||||
const [mouseY, setMouseY] = createSignal(0);
|
||||
|
||||
const [data, { refetch }] = createResource(async () => await props.ipc.invoke('get-menu') as Promise<Menu | null>);
|
||||
const [isMaximized, { refetch: refetchMaximize }] = createResource(async () => await props.ipc.invoke('window-is-maximized') as Promise<boolean>);
|
||||
@ -224,6 +230,10 @@ export const TitleBar = (props: TitleBarProps) => {
|
||||
setMenu(await refreshMenuItem(menuData, commandId));
|
||||
};
|
||||
|
||||
const listener = (e: MouseEvent) => {
|
||||
setMouseY(e.clientY);
|
||||
};
|
||||
|
||||
onMount(() => {
|
||||
props.ipc.on('close-all-in-app-menu-panel', async () => {
|
||||
setIgnoreTransition(true);
|
||||
@ -257,6 +267,9 @@ export const TitleBar = (props: TitleBarProps) => {
|
||||
setOpenTarget(null);
|
||||
}
|
||||
});
|
||||
|
||||
// tracking mouse position
|
||||
window.addEventListener('mousemove', listener);
|
||||
});
|
||||
|
||||
createEffect(() => {
|
||||
@ -265,8 +278,12 @@ export const TitleBar = (props: TitleBarProps) => {
|
||||
}
|
||||
});
|
||||
|
||||
onCleanup(() => {
|
||||
window.removeEventListener('mousemove', listener);
|
||||
});
|
||||
|
||||
return (
|
||||
<nav data-ytmd-main-panel={true} class={titleStyle()} data-macos={props.isMacOS}>
|
||||
<nav data-ytmd-main-panel={true} class={titleStyle()} data-macos={props.isMacOS} data-show={mouseY() < 32}>
|
||||
<IconButton
|
||||
onClick={() => setCollapsed(!collapsed())}
|
||||
style={{
|
||||
|
||||
@ -52,6 +52,11 @@ ytmusic-guide-renderer {
|
||||
) !important;
|
||||
}
|
||||
|
||||
/* fix mini player behavior */
|
||||
ytmusic-app-layout ytmusic-player-page[is-mweb-modernization-enabled] .side-panel.ytmusic-player-page {
|
||||
transform: translate(0, calc(var(--ytmusic-player-page-inner-height) - var(--ytmusic-player-page-tabs-header-height) - var(--ytmusic-player-page-player-bar-height) - var(--menu-bar-height, 32px) ));
|
||||
}
|
||||
|
||||
/* ytm-bugs: see https://github.com/th-ch/youtube-music/issues/1737 */
|
||||
html {
|
||||
scrollbar-color: unset;
|
||||
|
||||
145
src/plugins/webnowplaying/index.ts
Normal file
145
src/plugins/webnowplaying/index.ts
Normal file
@ -0,0 +1,145 @@
|
||||
import { net } from 'electron';
|
||||
|
||||
import is from 'electron-is';
|
||||
|
||||
import { createPlugin } from '@/utils';
|
||||
import registerCallback from '@/providers/song-info';
|
||||
import { t } from '@/i18n';
|
||||
|
||||
import { WebSocket } from 'ws';
|
||||
|
||||
import ReconnectingWebSocket from 'reconnecting-websocket';
|
||||
|
||||
import type { RepeatMode } from '@/types/datahost-get-state';
|
||||
|
||||
interface Data {
|
||||
player: string;
|
||||
state: 'PLAYING' | 'PAUSED' | 'STOPPED';
|
||||
title: string;
|
||||
artist: string;
|
||||
album: string;
|
||||
cover: string;
|
||||
duration: string;
|
||||
position: string;
|
||||
volume: number;
|
||||
rating: number;
|
||||
repeat: 'ALL' | 'ONE' | 'NONE';
|
||||
shuffle: boolean;
|
||||
}
|
||||
|
||||
export default createPlugin({
|
||||
name: () => t('plugins.webnowplaying.name'),
|
||||
description: () => t('plugins.webnowplaying.description'),
|
||||
restartNeeded: true,
|
||||
config: {
|
||||
enabled: false,
|
||||
},
|
||||
backend: {
|
||||
liteMode: false,
|
||||
data: {
|
||||
player: 'YouTube Music',
|
||||
state: 'STOPPED',
|
||||
title: '',
|
||||
artist: '',
|
||||
album: '',
|
||||
cover: '',
|
||||
duration: '0:00',
|
||||
// position and volume are fetched in sendUpdate()
|
||||
position: '0:00',
|
||||
volume: 100,
|
||||
rating: 0,
|
||||
repeat: 'NONE',
|
||||
shuffle: false
|
||||
} as Data,
|
||||
start({ ipc }) {
|
||||
const timeInSecondsToString = (timeInSeconds: number) => {
|
||||
const timeInMinutes = Math.floor(timeInSeconds / 60);
|
||||
if (timeInMinutes < 60) return `${timeInMinutes}:${Math.floor(timeInSeconds % 60).toString().padStart(2, '0')}`;
|
||||
|
||||
return `${Math.floor(timeInMinutes / 60)}:${Math.floor(timeInMinutes % 60).toString().padStart(2, '0')}:${Math.floor(timeInSeconds % 60).toString().padStart(2, '0')}`;
|
||||
};
|
||||
|
||||
const ws = new ReconnectingWebSocket('ws://localhost:8974', undefined, {
|
||||
WebSocket: WebSocket,
|
||||
maxEnqueuedMessages: 0,
|
||||
});
|
||||
ws.onmessage = () => {
|
||||
|
||||
};
|
||||
|
||||
const post = (data: Data) => {
|
||||
const port = 1608;
|
||||
const headers = {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
'Access-Control-Allow-Headers': '*',
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
};
|
||||
const url = `http://127.0.0.1:${port}/`;
|
||||
net
|
||||
.fetch(url, {
|
||||
method: this.liteMode ? 'OPTIONS' : 'POST',
|
||||
headers,
|
||||
keepalive: true,
|
||||
body: this.liteMode ? undefined : JSON.stringify({ data }),
|
||||
})
|
||||
.then(() => {
|
||||
if (this.liteMode) {
|
||||
this.liteMode = false;
|
||||
console.debug(
|
||||
`obs-tuna webserver at port ${port} is now accessible. disable lite mode`,
|
||||
);
|
||||
post(data);
|
||||
}
|
||||
})
|
||||
.catch((error: { code: number; errno: number }) => {
|
||||
if (!this.liteMode && is.dev()) {
|
||||
console.debug(
|
||||
`Error: '${
|
||||
error.code || error.errno
|
||||
}' - when trying to access obs-tuna webserver at port ${port}. enable lite mode`,
|
||||
);
|
||||
this.liteMode = true;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
ipc.on('ytmd:player-api-loaded', () => {
|
||||
ipc.send('ytmd:setup-time-changed-listener');
|
||||
ipc.send('ytmd:setup-repeat-changed-listener');
|
||||
ipc.send('ytmd:setup-volume-changed-listener');
|
||||
});
|
||||
ipc.on('ytmd:time-changed', (t: number) => {
|
||||
if (!this.data.title) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.data.position = timeInSecondsToString(t);
|
||||
post(this.data);
|
||||
});
|
||||
ipc.on('ytmd:repeat-changed', (mode: RepeatMode) => {
|
||||
this.data.repeat = mode;
|
||||
post(this.data);
|
||||
});
|
||||
ipc.on('ytmd:volume-changed', (newVolume: number) => {
|
||||
this.data.volume = newVolume;
|
||||
post(this.data);
|
||||
});
|
||||
|
||||
registerCallback((songInfo) => {
|
||||
if (!songInfo.title && !songInfo.artist) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.data.duration = timeInSecondsToString(songInfo.songDuration);
|
||||
this.data.position = timeInSecondsToString(songInfo.elapsedSeconds ?? 0);
|
||||
this.data.cover = songInfo.imageSrc ?? '';
|
||||
this.data.title = songInfo.title;
|
||||
this.data.artist = songInfo.artist;
|
||||
this.data.state = songInfo.isPaused ? 'PAUSED' : 'PLAYING';
|
||||
this.data.album = songInfo.album ?? '';
|
||||
post(this.data);
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
@ -209,10 +209,19 @@ const registerProvider = (win: BrowserWindow) => {
|
||||
};
|
||||
|
||||
const suffixesToRemove = [
|
||||
' - topic',
|
||||
'vevo',
|
||||
' (performance video)',
|
||||
' (clip official)',
|
||||
// Artist names
|
||||
/\s*(- topic)$/i,
|
||||
/\s*vevo$/i,
|
||||
|
||||
// Video titles
|
||||
/\s*[(|\[]official(.*?)[)|\]]/i, // (Official Music Video), [Official Visualizer], etc...
|
||||
/\s*[(|\[]((lyrics?|visualizer|audio)\s*(video)?)[)|\]]/i,
|
||||
/\s*[(|\[](performance video)[)|\]]/i,
|
||||
/\s*[(|\[](clip official)[)|\]]/i,
|
||||
/\s*[(|\[](video version)[)|\]]/i,
|
||||
/\s*[(|\[](HD|HQ)\s*?(?:audio)?[)|\]]$/i,
|
||||
/\s*[(|\[](live)[)|\]]$/i,
|
||||
/\s*[(|\[]4K\s*?(?:upgrade)?[)|\]]$/i,
|
||||
];
|
||||
|
||||
export function cleanupName(name: string): string {
|
||||
@ -220,15 +229,8 @@ export function cleanupName(name: string): string {
|
||||
return name;
|
||||
}
|
||||
|
||||
name = name.replace(
|
||||
/\((?:official)? ?(?:music)? ?(?:lyrics?)? ?(?:video)?\)$/i,
|
||||
'',
|
||||
);
|
||||
const lowCaseName = name.toLowerCase();
|
||||
for (const suffix of suffixesToRemove) {
|
||||
if (lowCaseName.endsWith(suffix)) {
|
||||
return name.slice(0, -suffix.length);
|
||||
}
|
||||
name = name.replace(suffix, '');
|
||||
}
|
||||
|
||||
return name;
|
||||
|
||||
@ -59,7 +59,7 @@ async function onApiLoaded() {
|
||||
});
|
||||
window.ipcRenderer.on('ytmd:switch-repeat', (_, repeat = 1) => {
|
||||
for (let i = 0; i < repeat; i++) {
|
||||
document.querySelector<HTMLElement & { onRepeatButtonTap: () => void }>('ytmusic-player-bar')?.onRepeatButtonTap();
|
||||
document.querySelector<HTMLElement & { onRepeatButtonClick: () => void }>('ytmusic-player-bar')?.onRepeatButtonClick();
|
||||
}
|
||||
});
|
||||
window.ipcRenderer.on('ytmd:update-volume', (_, volume: number) => {
|
||||
|
||||
@ -65,12 +65,18 @@ tp-yt-paper-item.ytmusic-guide-entry-renderer::before {
|
||||
border-radius: 8px !important;
|
||||
}
|
||||
|
||||
/* fix video player align */
|
||||
#av-id {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
#av-id ~ #player.ytmusic-player-page {
|
||||
#av-id ~ #player.ytmusic-player-page:not([player-ui-state="FULLSCREEN"]) {
|
||||
margin-top: auto !important;
|
||||
margin-bottom: auto !important;
|
||||
max-height: calc(100% - (var(--ytmusic-player-page-vertical-padding) * 2));
|
||||
max-width: calc(100% - var(--ytmusic-player-page-vertical-padding) * 2);
|
||||
}
|
||||
|
||||
ytmusic-player[player-ui-state=FULLSCREEN] {
|
||||
top: calc(var(--menu-bar-height, 32px) * -1) !important;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user