Compare commits

...

21 Commits

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

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

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

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

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/pl/
2024-09-09 22:09:15 +00:00
199d912823 Update changelog for v3.5.2 2024-09-07 12:27:30 +00:00
15 changed files with 473 additions and 301 deletions

View File

@ -2,8 +2,49 @@
All notable changes to this project will be documented in this file. Dates are displayed in UTC.
#### [v3.5.2](https://github.com/th-ch/youtube-music/compare/v3.5.1...v3.5.2)
- chore(deps): update typescript-eslint monorepo to v8.4.0 [`#2401`](https://github.com/th-ch/youtube-music/pull/2401)
- chore(deps): update dependency @total-typescript/ts-reset to v0.6.1 [`#2396`](https://github.com/th-ch/youtube-music/pull/2396)
- chore(deps): update dependency electron to v31.5.0 [`#2397`](https://github.com/th-ch/youtube-music/pull/2397)
- chore(deps): update dependency eslint-import-resolver-typescript to v3.6.3 [`#2376`](https://github.com/th-ch/youtube-music/pull/2376)
- chore(deps): update dependency discord-api-types to v0.37.100 [`#2394`](https://github.com/th-ch/youtube-music/pull/2394)
- fix(deps): update dependency electron-updater to v6.3.4 [`#2395`](https://github.com/th-ch/youtube-music/pull/2395)
- chore(deps): update dependency @babel/runtime to v7.25.6 [`#2388`](https://github.com/th-ch/youtube-music/pull/2388)
- chore(deps): update dependency vite-plugin-inspect to v0.8.7 [`#2389`](https://github.com/th-ch/youtube-music/pull/2389)
- chore(deps): update dependency discord-api-types to v0.37.99 [`#2374`](https://github.com/th-ch/youtube-music/pull/2374)
- chore(deps): update dependency vite to v5.4.3 [`#2377`](https://github.com/th-ch/youtube-music/pull/2377)
- fix: incorrect regex when splitting artistName [`#2378`](https://github.com/th-ch/youtube-music/pull/2378)
- chore(deps): update dependency @babel/runtime to v7.25.4 [`#2373`](https://github.com/th-ch/youtube-music/pull/2373)
- synced-lyrics: make the lyrics search more reliable [`#2343`](https://github.com/th-ch/youtube-music/pull/2343)
- fix(deps): update dependency solid-js to v1.8.22 [`#2354`](https://github.com/th-ch/youtube-music/pull/2354)
- chore(deps): update typescript-eslint monorepo to v8.3.0 [`#2350`](https://github.com/th-ch/youtube-music/pull/2350)
- fix(deps): update dependency electron-debug to v4.0.1 [`#2349`](https://github.com/th-ch/youtube-music/pull/2349)
- chore(deps): update dependency electron to v31.4.0 [`#2356`](https://github.com/th-ch/youtube-music/pull/2356)
- fix: hide native-controls on linux when in-app-menu is used [`#2366`](https://github.com/th-ch/youtube-music/pull/2366)
- fix: detect the upgrade btn using the icon [`#2364`](https://github.com/th-ch/youtube-music/pull/2364)
- fix: exclude build-id files from rpm [`#2361`](https://github.com/th-ch/youtube-music/pull/2361)
- fix(deps): update dependency i18next to v23.12.3 [`#2352`](https://github.com/th-ch/youtube-music/pull/2352)
- fix(deps): update dependency @floating-ui/dom to v1.6.10 [`#2340`](https://github.com/th-ch/youtube-music/pull/2340)
- fix(deps): update dependency electron-updater to v6.3.3 [`#2347`](https://github.com/th-ch/youtube-music/pull/2347)
- fix(deps): update dependency solid-js to v1.8.20 [`#2345`](https://github.com/th-ch/youtube-music/pull/2345)
- chore(deps): update dependency vite to v5.4.0 [`#2342`](https://github.com/th-ch/youtube-music/pull/2342)
- chore(deps): update typescript-eslint monorepo to v8.0.1 [`#2335`](https://github.com/th-ch/youtube-music/pull/2335)
- fix(deps): update dependency @floating-ui/dom to v1.6.9 [`#2337`](https://github.com/th-ch/youtube-music/pull/2337)
- chore(deps): update playwright monorepo to v1.46.0 [`#2336`](https://github.com/th-ch/youtube-music/pull/2336)
- chore(README): Translation README to Russian and adding Synced Lyrics to main README [`#2338`](https://github.com/th-ch/youtube-music/pull/2338)
- chore(deps): update dependency rollup to v4.20.0 [`#2326`](https://github.com/th-ch/youtube-music/pull/2326)
- fix(synced-lyric): fix timestamp [`#2323`](https://github.com/th-ch/youtube-music/issues/2323) [`#2379`](https://github.com/th-ch/youtube-music/issues/2379)
- Revert "fix(MPRIS): Prevents player to start with invalid MPRIS interface (#1996)" [`#2225`](https://github.com/th-ch/youtube-music/issues/2225)
- fix(adblocker/inplayer): fix Response.prototype.json [`#2310`](https://github.com/th-ch/youtube-music/issues/2310)
- chore(deps): update dependency eslint-plugin-import to v2.30.0 [`f48e46d`](https://github.com/th-ch/youtube-music/commit/f48e46d29cf09c76c5172fd56d2d0f705616e4e3)
- Revert "chore(deps): update dependency electron-builder to v25" [`089eff3`](https://github.com/th-ch/youtube-music/commit/089eff3152903c8b55ad3e5571b944062a647e27)
- chore(deps): update dependency electron-builder to v25 [`fe4c89c`](https://github.com/th-ch/youtube-music/commit/fe4c89c349bb9f4f54d95c2018943095ccfdab0c)
#### [v3.5.1](https://github.com/th-ch/youtube-music/compare/v3.5.0...v3.5.1)
> 1 August 2024
- fix(deps): update dependency youtubei.js to v10.3.0 [`#2306`](https://github.com/th-ch/youtube-music/pull/2306)
- fix: Window gets stuck offscreen in some instances [`#2303`](https://github.com/th-ch/youtube-music/pull/2303)
- fix: Incorrect window size on multi-monitor scaled displays [`#2302`](https://github.com/th-ch/youtube-music/pull/2302)

View File

@ -1,7 +1,7 @@
{
"name": "youtube-music",
"productName": "YouTube Music",
"version": "3.5.2",
"version": "3.5.3",
"description": "YouTube Music Desktop App - including custom plugins",
"main": "./dist/main/index.js",
"license": "MIT",
@ -163,7 +163,7 @@
"@electron/remote": "2.1.2",
"@ffmpeg.wasm/core-mt": "0.12.0",
"@ffmpeg.wasm/main": "0.12.0",
"@floating-ui/dom": "1.6.10",
"@floating-ui/dom": "1.6.11",
"@foobar404/wave": "2.0.5",
"@jellybrick/electron-better-web-request": "1.0.4",
"@jellybrick/mpris-service": "2.1.4",
@ -188,7 +188,7 @@
"filenamify": "6.0.0",
"howler": "2.2.4",
"html-to-text": "9.0.5",
"i18next": "23.14.0",
"i18next": "23.15.1",
"keyboardevent-from-electron-accelerator": "2.0.0",
"keyboardevents-areequal": "0.2.2",
"node-html-parser": "6.1.13",
@ -207,37 +207,38 @@
"youtubei.js": "10.4.0"
},
"devDependencies": {
"@playwright/test": "1.47.0",
"@playwright/test": "1.47.1",
"@total-typescript/ts-reset": "0.6.1",
"@types/color": "3.0.6",
"@types/electron-localshortcut": "3.1.3",
"@types/howler": "2.2.11",
"@types/html-to-text": "9.0.4",
"@types/semver": "7.5.8",
"@typescript-eslint/eslint-plugin": "8.4.0",
"@typescript-eslint/parser": "8.4.0",
"@types/trusted-types": "2.0.7",
"@typescript-eslint/eslint-plugin": "8.6.0",
"@typescript-eslint/parser": "8.6.0",
"bufferutil": "4.0.8",
"builtin-modules": "4.0.0",
"cross-env": "7.0.3",
"del-cli": "5.1.0",
"discord-api-types": "0.37.100",
"electron": "32.0.2",
"electron": "32.1.0",
"electron-builder": "24.13.3",
"electron-devtools-installer": "3.2.0",
"electron-vite": "2.3.0",
"esbuild": "0.23.1",
"eslint": "8.57.0",
"eslint": "8.57.1",
"eslint-import-resolver-exports": "1.0.0-beta.5",
"eslint-import-resolver-typescript": "3.6.3",
"eslint-plugin-import": "2.30.0",
"eslint-plugin-prettier": "5.2.1",
"glob": "11.0.0",
"node-gyp": "10.2.0",
"playwright": "1.47.0",
"rollup": "4.21.2",
"typescript": "5.5.4",
"playwright": "1.47.1",
"rollup": "4.21.3",
"typescript": "5.6.2",
"utf-8-validate": "6.0.4",
"vite": "5.4.3",
"vite": "5.4.6",
"vite-plugin-inspect": "0.8.7",
"vite-plugin-resolve": "2.5.2",
"vite-plugin-solid": "2.10.2",

498
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -2,13 +2,14 @@
"common": {
"console": {
"plugins": {
"execute-failed": "נכשל ביצוע תוסף {{pluginName}}::{{contextName}}",
"execute-failed": "שגיאה בהרצת התוסף {{pluginName}}::{{contextName}}",
"executed-at-ms": "התוסף {{pluginName}}:{{contextName}} בוצע ב {{ms}}ms",
"initialize-failed": "טעינת התוסף \"{{pluginName}}\" נכשלה",
"load-all": "טוען את כל התוספים",
"load-failed": "טעינת התוסף \"{{pluginName}}\" נכשלה",
"load-failed": "לא ניתן לטעון את התוסף {{pluginName}}",
"loaded": "התוסף \"{{pluginName}}\" נטען",
"unload-failed": "הסרת התוסף \"{{pluginName}} נכשלה"
"unload-failed": "הסרת התוסף \"{{pluginName}} נכשלה",
"unloaded": "תוסף {{pluginName}} הורד"
}
}
},
@ -25,14 +26,28 @@
"i18n": {
"loaded": "i18n נטען"
},
"second-instance": {
"receive-command": "התקבלה פקודה מעבר פרוטוקל: {{command}}"
},
"theme": {
"css-file-not-found": "קובץ ה-CSS \"{{cssFile}}\" לא קיים. מדלג"
},
"unresponsive": {
"details": "שגיאה ללא תגובה\n{{error}}"
},
"when-ready": {
"clearing-cache-after-20s": "מוחק קבצי מתמון"
},
"window": {
"tried-to-render-offscreen": "ווינדוס ניסה להציג תוכן מחוץ למסך, גודל חלון={{windowSize}}, גודל מסך={{displaySize}}, מיקום={{position}}"
}
},
"dialog": {
"hide-menu-enabled": {
"detail": "התפריט מוחבא, השתמש \"Alt\" על להציג אותו (או \"Esacpe\" אם משתמשים בתפריט בתוך האפליקציה)",
"message": "הסתרת התפריט מופעלת",
"title": "הסתרת התפריט הופעלה"
},
"need-to-restart": {
"buttons": {
"later": "אחר כך",

View File

@ -372,6 +372,9 @@
"backend": {
"dialog": {
"error": {
"buttons": {
"ok": "Rendben"
},
"message": "Hoppá! Elnézést, a letöltés sikertelen volt…",
"title": "A letöltés során hiba történt!"
},
@ -412,6 +415,7 @@
"menu": {
"choose-download-folder": "Letöltési mappa kiválasztása",
"download-finish-settings": {
"label": "Letöltés befejezéskor",
"prompt": {
"last-percent": "x százalék után",
"last-seconds": "Utolsó x másodperc"
@ -425,7 +429,7 @@
}
},
"download-playlist": "Lejátszási lista letöltése",
"presets": "Előbeállítások",
"presets": "Sablonok",
"skip-existing": "Meglévő fájlok kihagyása"
},
"name": "Letöltő",
@ -666,6 +670,18 @@
"fetch": "⚠️ - Hiba történt a dalszövegek lekérése közben. Kérlek, próbáld újra később.",
"not-found": "⚠️ - Nem található dalszöveg ehhez a zenéhez."
},
"menu": {
"line-effect": {
"submenu": {
"scale": {
"label": "Mérték"
}
}
},
"precise-timing": {
"label": "Dalszöveg tökéletes szinkronizálása"
}
},
"name": "Szinkronizált dalszövegek",
"refetch-btn": {
"fetching": "Lekérés folyamatban...",

View File

@ -158,6 +158,14 @@
},
"remove-upgrade-button": "Fjarlægja uppgræðartakkan",
"theme": {
"dialog": {
"button": {
"cancel": "Hætta við",
"remove": "Fjarlægja"
},
"remove-theme": "Ertu viss um að þú viljir fjarlægja þetta sérsniðna þema?",
"remove-theme-message": "Þetta mun fjarlægja sérsniðna þema"
},
"label": "Þema",
"submenu": {
"import-css-file": "Flytja inn sérsniðna CSS skrá",
@ -199,6 +207,10 @@
}
},
"plugins": {
"ad-speedup": {
"description": "Ef auglýsing spilar slökknar hún á hljóðinu og stillir spilunarhraðann á 16x",
"name": "Auglýsingahraða"
},
"adblocker": {
"description": "Lokaðu fyrir allar auglýsingar og rakningar úr kassanum",
"menu": {
@ -402,6 +414,21 @@
"description": "Niðurhalar MP3 / upprunahljóði beint úr viðmótinu",
"menu": {
"choose-download-folder": "Veldu niðurhalsmöppu",
"download-finish-settings": {
"label": "Sækja þegar lokið",
"prompt": {
"last-percent": "Eftir x sekúndur",
"last-seconds": "Síðustu x sekúndur",
"title": "Stilla hvenær á að hlaða niður"
},
"submenu": {
"advanced": "Ítarlegri",
"enabled": "Virkt",
"mode": "Tímastilling",
"percent": "Hlutfall",
"seconds": "Sekúndur"
}
},
"download-playlist": "Sækja spilunarlista",
"presets": "Forstillingar",
"skip-existing": "Slepptu núverandi skrám"
@ -641,6 +668,10 @@
"description": "Sleppur sjálfkrafa hlutum sem ekki eru tónlist, eins og inngangur/lok eða hlutar af tónlistarmyndböndum þar sem lag er ekki að spila",
"name": "Styrktarblokk"
},
"synced-lyrics": {
"description": "Veitir samstillta texta við lög, með því að nota veitur eins og LRClib.",
"name": "Samstilltur texti"
},
"taskbar-mediacontrol": {
"description": "Stjórnaðu spilun frá Windows verkefnastikunni þinni",
"name": "Miðlunarstýringarverkefnastikunnar"

View File

@ -668,6 +668,22 @@
"description": "Automatycznie pomija fragmenty niebędące muzyką, takie jak wstęp/zakończenie lub fragmenty teledysków, w których utwór nie jest odtwarzany",
"name": "Pomiń nieistotne fragmenty"
},
"synced-lyrics": {
"description": "Dodaje zsynchronizowane napisy do utworów używając między innymi LRClib.",
"errors": {
"fetch": "⚠️ - Wystąpił błąd podczas pobierania tekstu utworu. Spróbuj ponownie później.",
"not-found": "⚠️ - Nie znaleziono napisów dla tego utworu."
},
"name": "Napisy zsynchronizowane",
"refetch-btn": {
"fetching": "Pobieranie napisów...",
"normal": "Odśwież napisy"
},
"warnings": {
"duration-mismatch": "⚠️ - Napisy mogą nie być zsynchronizowane z powodu różnicy w czasie trwania.",
"instrumental": "⚠️ - To jest utwór instrumentalny"
}
},
"taskbar-mediacontrol": {
"description": "Steruj odtwarzaniem z paska zadań systemu Windows",
"name": "Kontroler odtwarzania z paska zadań"

View File

@ -11,6 +11,7 @@ import {
shell,
dialog,
ipcMain,
type BrowserWindowConstructorOptions,
} from 'electron';
import enhanceWebRequest, {
BetterSession,
@ -56,7 +57,6 @@ import { loadI18n, setLanguage, t } from '@/i18n';
import ErrorHtmlAsset from '@assets/error.html?asset';
import type { PluginConfig } from '@/types/plugins';
import BrowserWindowConstructorOptions = Electron.BrowserWindowConstructorOptions;
if (!is.macOS()) {
delete allPlugins['touchbar'];
@ -618,6 +618,7 @@ app.whenReady().then(async () => {
shortcutDetails.target !== appLocation ||
shortcutDetails.appUserModelId !== appID
) {
// eslint-disable-next-line @typescript-eslint/only-throw-error
throw 'needUpdate';
}
} catch (error) {

View File

@ -166,13 +166,13 @@ export default createPlugin<
this.profiles = {};
this.connection.onConnections((connection) => {
if (!connection) {
this.api?.openToast(t('plugins.music-together.toast.disconnected'));
this.api?.toastService?.show(t('plugins.music-together.toast.disconnected'));
this.onStop();
return;
}
if (!connection.open) {
this.api?.openToast(t('plugins.music-together.toast.user-disconnected', {
this.api?.toastService?.show(t('plugins.music-together.toast.user-disconnected', {
name: this.profiles[connection.peer]?.name
}));
this.putProfile(connection.peer, undefined);
@ -219,7 +219,7 @@ export default createPlugin<
break;
}
this.api?.openToast(t('plugins.music-together.toast.user-connected', { name: event.payload.profile.name }));
this.api?.toastService?.show(t('plugins.music-together.toast.user-connected', { name: event.payload.profile.name }));
this.putProfile(conn.peer, event.payload.profile);
break;
}
@ -307,7 +307,7 @@ export default createPlugin<
if (!connection) return false;
this.connection.onConnections((connection) => {
if (!connection?.open) {
this.api?.openToast(t('plugins.music-together.toast.disconnected'));
this.api?.toastService?.show(t('plugins.music-together.toast.disconnected'));
this.onStop();
}
});
@ -381,7 +381,7 @@ export default createPlugin<
const permissionLabel = t(`plugins.music-together.menu.permission.${this.permission}`);
this.api?.openToast(t('plugins.music-together.toast.permission-changed', { permission: permissionLabel }));
this.api?.toastService?.show(t('plugins.music-together.toast.permission-changed', { permission: permissionLabel }));
break;
}
default: {
@ -593,18 +593,18 @@ export default createPlugin<
onItemClick: (id) => {
if (id === 'music-together-close') {
this.onStop();
this.api?.openToast(t('plugins.music-together.toast.closed'));
this.api?.toastService?.show(t('plugins.music-together.toast.closed'));
hostPopup.dismiss();
}
if (id === 'music-together-copy-id') {
navigator.clipboard.writeText(this.connection?.id ?? '')
.then(() => {
this.api?.openToast(t('plugins.music-together.toast.id-copied'));
this.api?.toastService?.show(t('plugins.music-together.toast.id-copied'));
hostPopup.dismiss();
})
.catch(() => {
this.api?.openToast(t('plugins.music-together.toast.id-copy-failed'));
this.api?.toastService?.show(t('plugins.music-together.toast.id-copy-failed'));
hostPopup.dismiss();
});
}
@ -620,7 +620,7 @@ export default createPlugin<
settingPopup.setPermission(this.permission);
const permissionLabel = t(`plugins.music-together.menu.permission.${this.permission}`);
this.api?.openToast(t('plugins.music-together.toast.permission-changed', { permission: permissionLabel }));
this.api?.toastService?.show(t('plugins.music-together.toast.permission-changed', { permission: permissionLabel }));
const item = hostPopup.items.find((it) => it?.element.id === id);
if (item?.type === 'item') {
item.setText(t('plugins.music-together.menu.set-permission'));
@ -632,7 +632,7 @@ export default createPlugin<
onItemClick: (id) => {
if (id === 'music-together-disconnect') {
this.onStop();
this.api?.openToast(t('plugins.music-together.toast.disconnected'));
this.api?.toastService?.show(t('plugins.music-together.toast.disconnected'));
guestPopup.dismiss();
}
}
@ -648,14 +648,14 @@ export default createPlugin<
if (result) {
navigator.clipboard.writeText(this.connection?.id ?? '')
.then(() => {
this.api?.openToast(t('plugins.music-together.toast.id-copied'));
this.api?.toastService?.show(t('plugins.music-together.toast.id-copied'));
hostPopup.showAtAnchor(setting);
}).catch(() => {
this.api?.openToast(t('plugins.music-together.toast.id-copy-failed'));
this.api?.toastService?.show(t('plugins.music-together.toast.id-copy-failed'));
hostPopup.showAtAnchor(setting);
});
} else {
this.api?.openToast(t('plugins.music-together.toast.host-failed'));
this.api?.toastService?.show(t('plugins.music-together.toast.host-failed'));
}
}
@ -666,10 +666,10 @@ export default createPlugin<
this.hideSpinner();
if (result) {
this.api?.openToast(t('plugins.music-together.toast.joined'));
this.api?.toastService?.show(t('plugins.music-together.toast.joined'));
guestPopup.showAtAnchor(setting);
} else {
this.api?.openToast(t('plugins.music-together.toast.join-failed'));
this.api?.toastService?.show(t('plugins.music-together.toast.join-failed'));
}
}
}

View File

@ -2,7 +2,7 @@ import { singleton } from './decorators';
import type { YoutubePlayer } from '@/types/youtube-player';
import type { GetState } from '@/types/datahost-get-state';
import type { AlbumDetails, VideoDataChangeValue } from '@/types/player-api-events';
import type { AlbumDetails, PlayerOverlays, VideoDataChangeValue } from '@/types/player-api-events';
import type { SongInfo } from './song-info';
import type { VideoDataChanged } from '@/types/video-data-changed';
@ -208,28 +208,35 @@ export default (api: YoutubePlayer) => {
list: playlistId
} = api.getVideoData();
const { playerOverlays } = api.getWatchNextResponse();
const watchNextResponse = api.getWatchNextResponse();
sendSongInfo(<VideoDataChangeValue>{
sendSongInfo({
title, author, videoId, playlistId,
isUpcoming: false,
lengthSeconds: video.duration,
loading: true,
uhhh: { playerOverlays }
});
ytmdWatchNextResponse: watchNextResponse,
} satisfies VideoDataChangeValue);
}
}
function sendSongInfo(videoData: VideoDataChangeValue) {
const data = api.getPlayerResponse();
data.videoDetails.album = (
Object.entries(videoData).find(
([, value]) => value && Object.hasOwn(value, 'playerOverlays'),
) as [string, AlbumDetails | undefined]
)?.[1]?.playerOverlays?.playerOverlayRenderer?.browserMediaSession?.browserMediaSessionRenderer?.album?.runs?.at(
let playerOverlay: PlayerOverlays | undefined;
if (!videoData.ytmdWatchNextResponse) {
playerOverlay = (
Object.entries(videoData).find(
([, value]) => value && Object.hasOwn(value, 'playerOverlays'),
) as [string, AlbumDetails | undefined]
)?.[1]?.playerOverlays;
} else {
playerOverlay = videoData.ytmdWatchNextResponse?.playerOverlays;
}
data.videoDetails.album = playerOverlay?.playerOverlayRenderer?.browserMediaSession?.browserMediaSessionRenderer?.album?.runs?.at(
0,
)?.text;
data.videoDetails.elapsedSeconds = 0;

View File

@ -23,6 +23,14 @@ let isPluginLoaded = false;
let isApiLoaded = false;
let firstDataLoaded = false;
if (window.trustedTypes && window.trustedTypes.createPolicy && !window.trustedTypes.defaultPolicy) {
window.trustedTypes.createPolicy('default', {
createHTML: (input) => input,
createScriptURL: (input) => input,
createScript: (input) => input,
});
}
async function listenForApiLoad() {
if (!isApiLoaded) {
api = document.querySelector('#movie_player');

2
src/reset.d.ts vendored
View File

@ -6,6 +6,7 @@ import type is from 'electron-is';
import type config from './config';
import type { VideoDataChanged } from '@/types/video-data-changed';
import type { t } from '@/i18n';
import type { trustedTypes } from 'trusted-types';
declare global {
interface Compressor {
@ -19,6 +20,7 @@ declare global {
}
interface Window {
trustedTypes?: typeof trustedTypes;
ipcRenderer: typeof electronIpcRenderer;
mainConfig: typeof config;
electronIs: typeof is;

View File

@ -1,3 +1,5 @@
import type { WatchNextResponse } from '@/types/youtube-music-desktop-internal';
export interface AlbumDetails {
responseContext: ResponseContext;
contents: Contents;
@ -252,6 +254,11 @@ export type VideoDataChangeValue = Record<string, unknown> & {
loading: boolean;
lengthSeconds: number;
/**
* YouTube Music Desktop internal variable (for album data)
**/
ytmdWatchNextResponse?: WatchNextResponse;
};
export interface PlayerAPIEvents {

View File

@ -30,11 +30,39 @@ export type QueueAPI = {
continuation?: string;
autoPlaying?: boolean;
};
export type ToastElement = HTMLElement & {
autoFitOnAttach: boolean;
duration: number;
expandSizingTargetForScrollbars: boolean;
horizontalAlign: 'left' | 'right' | 'center';
importPath?: unknown;
label: string;
noAutoFocus: boolean;
noCancelOnEscKey: boolean;
noCancelOnOutsideClick: boolean;
noIronAnnounce: boolean;
restoreFocusOnClose: boolean;
root: ToastElement;
rootPath: string;
sizingTarget: ToastElement;
verticalAlign: 'bottom' | 'top' | 'center';
};
export interface ToastService {
attached: boolean;
displaying: boolean;
messageQueue: string[];
toastElement: ToastElement;
show: (message: string) => void;
}
export type AppElement = HTMLElement & AppAPI;
export type AppAPI = {
queue_: QueueAPI;
playerApi_: YoutubePlayer;
openToast: (message: string) => void;
queue: QueueAPI;
playerApi: YoutubePlayer;
toastService: ToastService;
// TODO: Add more
};

View File

@ -1,4 +1,5 @@
import type { QueueItem } from '@/types/datahost-get-state';
import type { PlayerOverlays } from '@/types/player-api-events';
export interface QueueResponse {
items?: QueueItem[];
@ -7,15 +8,5 @@ export interface QueueResponse {
}
export interface WatchNextResponse {
playerOverlays: {
playerOverlayRenderer: {
browserMediaSession: {
browserMediaSessionRenderer: {
album: {
runs: { text: string; }[]
}
}
}
}
};
playerOverlays?: PlayerOverlays;
}