Compare commits

...

8 Commits

Author SHA1 Message Date
02e2fb6a83 Bump version to 3.4.1 2024-07-15 00:18:37 +09:00
91bee4880e chore(i18n): Translated using Weblate (Spanish)
Currently translated at 100.0% (355 of 355 strings)

Translation: th-ch/youtube-music/i18n
Translate-URL: https://hosted.weblate.org/projects/youtube-music/i18n/es/
2024-07-14 17:15:57 +02:00
7de7303ebb fix(mpris): fix mpris position
- fix #2225
2024-07-15 00:14:49 +09:00
363d869cff fix(deb): fix depends
- fix #1983
2024-07-14 23:48:15 +09:00
2512af80af fix: fix touchbar icon
- fix #2183
2024-07-14 23:19:06 +09:00
887979932c fix: fix "Starting page"
- fix #1822
2024-07-14 22:59:05 +09:00
eeaaf2f158 fix: fix album actions
- fix #2202
2024-07-14 22:50:24 +09:00
e91e995b95 fix: fix playback slider
- fix #2045
2024-07-14 22:32:56 +09:00
12 changed files with 271 additions and 228 deletions

View File

@ -1,7 +1,7 @@
{ {
"name": "youtube-music", "name": "youtube-music",
"productName": "YouTube Music", "productName": "YouTube Music",
"version": "3.4.0", "version": "3.4.1",
"description": "YouTube Music Desktop App - including custom plugins", "description": "YouTube Music Desktop App - including custom plugins",
"main": "./dist/main/index.js", "main": "./dist/main/index.js",
"license": "MIT", "license": "MIT",
@ -77,6 +77,20 @@
"rpm" "rpm"
] ]
}, },
"deb": {
"depends": [
"libgtk-3-0",
"libnotify4",
"libnss3",
"libxss1",
"libxtst6",
"xdg-utils",
"libatspi2.0-0",
"libuuid1",
"libasound2",
"libgbm1"
]
},
"rpm": { "rpm": {
"depends": [ "depends": [
"/usr/lib64/libuuid.so.1" "/usr/lib64/libuuid.so.1"

View File

@ -410,6 +410,21 @@
"description": "Descarga MP3 / audio fuente directamente desde la interfaz", "description": "Descarga MP3 / audio fuente directamente desde la interfaz",
"menu": { "menu": {
"choose-download-folder": "Elija la carpeta de descarga", "choose-download-folder": "Elija la carpeta de descarga",
"download-finish-settings": {
"label": "Descargar al finalizar",
"prompt": {
"last-percent": "Después del x por ciento",
"last-seconds": "Últimos x segundos",
"title": "Configurar cuándo descargar"
},
"submenu": {
"advanced": "Avanzado",
"enabled": "Activado",
"mode": "Modo de tiempo",
"percent": "Porcentaje",
"seconds": "Segundos"
}
},
"download-playlist": "Descargar lista de reproducción", "download-playlist": "Descargar lista de reproducción",
"presets": "Preajustes", "presets": "Preajustes",
"skip-existing": "Saltar archivos existentes" "skip-existing": "Saltar archivos existentes"

View File

@ -112,8 +112,13 @@ export default createPlugin<
i++; i++;
} }
} }
const menu = document.querySelector('.detail-page-menu'); const menuParent = document.querySelector('#action-buttons')?.parentElement;
if (menu && !document.querySelector('.like-menu')) { if (menuParent && !document.querySelector('.like-menu')) {
const menu = document.createElement('div');
menu.id = 'ytmd-album-action-buttons';
menu.className = 'action-buttons style-scope ytmusic-responsive-header-renderer';
menuParent.insertBefore(menu, menuParent.children[menuParent.children.length - 1]);
for (const button of buttons) { for (const button of buttons) {
menu.appendChild(button); menu.appendChild(button);
button.addEventListener('click', this.loadFullList); button.addEventListener('click', this.loadFullList);

View File

@ -1,11 +1,12 @@
<button <div class="style-scope">
<button
id="alldislike" id="alldislike"
data-type="dislike" data-type="dislike"
data-filled="false" data-filled="false"
class="like-menu yt-spec-button-shape-next yt-spec-button-shape-next--text yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m yt-spec-button-shape-next--icon-button" class="like-menu yt-spec-button-shape-next yt-spec-button-shape-next--text yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m yt-spec-button-shape-next--icon-button"
aria-pressed="false" aria-pressed="false"
aria-label="Dislike all" aria-label="Dislike all"
> >
<div <div
class="yt-spec-button-shape-next__icon" class="yt-spec-button-shape-next__icon"
style="color: var(--ytmusic-setting-item-toggle-active)" style="color: var(--ytmusic-setting-item-toggle-active)"
@ -71,4 +72,5 @@
<div class="yt-spec-touch-feedback-shape__fill"></div> <div class="yt-spec-touch-feedback-shape__fill"></div>
</div> </div>
</yt-touch-feedback-shape> </yt-touch-feedback-shape>
</button> </button>
</div>

View File

@ -1,11 +1,12 @@
<button <div class="style-scope">
<button
id="alllike" id="alllike"
data-type="like" data-type="like"
data-filled="false" data-filled="false"
class="like-menu yt-spec-button-shape-next yt-spec-button-shape-next--text yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m yt-spec-button-shape-next--icon-button" class="like-menu yt-spec-button-shape-next yt-spec-button-shape-next--text yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m yt-spec-button-shape-next--icon-button"
aria-pressed="false" aria-pressed="false"
aria-label="Like all" aria-label="Like all"
> >
<div <div
class="yt-spec-button-shape-next__icon" class="yt-spec-button-shape-next__icon"
style="color: var(--ytmusic-setting-item-toggle-active)" style="color: var(--ytmusic-setting-item-toggle-active)"
@ -71,4 +72,5 @@
<div class="yt-spec-touch-feedback-shape__fill"></div> <div class="yt-spec-touch-feedback-shape__fill"></div>
</div> </div>
</yt-touch-feedback-shape> </yt-touch-feedback-shape>
</button> </button>
</div>

View File

@ -1,11 +1,12 @@
<button <div class="style-scope">
<button
id="allundislike" id="allundislike"
data-type="dislike" data-type="dislike"
data-filled="true" data-filled="true"
class="like-menu yt-spec-button-shape-next yt-spec-button-shape-next--text yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m yt-spec-button-shape-next--icon-button" class="like-menu yt-spec-button-shape-next yt-spec-button-shape-next--text yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m yt-spec-button-shape-next--icon-button"
aria-pressed="false" aria-pressed="false"
aria-label="Undislike all" aria-label="Undislike all"
> >
<div <div
class="yt-spec-button-shape-next__icon" class="yt-spec-button-shape-next__icon"
style="color: var(--ytmusic-setting-item-toggle-active)" style="color: var(--ytmusic-setting-item-toggle-active)"
@ -71,4 +72,5 @@
<div class="yt-spec-touch-feedback-shape__fill"></div> <div class="yt-spec-touch-feedback-shape__fill"></div>
</div> </div>
</yt-touch-feedback-shape> </yt-touch-feedback-shape>
</button> </button>
</div>

View File

@ -1,11 +1,12 @@
<button <div class="style-scope">
<button
id="allunlike" id="allunlike"
data-type="like" data-type="like"
data-filled="true" data-filled="true"
class="like-menu yt-spec-button-shape-next yt-spec-button-shape-next--text yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m yt-spec-button-shape-next--icon-button" class="like-menu yt-spec-button-shape-next yt-spec-button-shape-next--text yt-spec-button-shape-next--mono yt-spec-button-shape-next--size-m yt-spec-button-shape-next--icon-button"
aria-pressed="false" aria-pressed="false"
aria-label="Unlike all" aria-label="Unlike all"
> >
<div <div
class="yt-spec-button-shape-next__icon" class="yt-spec-button-shape-next__icon"
style="color: var(--ytmusic-setting-item-toggle-active)" style="color: var(--ytmusic-setting-item-toggle-active)"
@ -71,4 +72,5 @@
<div class="yt-spec-touch-feedback-shape__fill"></div> <div class="yt-spec-touch-feedback-shape__fill"></div>
</div> </div>
</yt-touch-feedback-shape> </yt-touch-feedback-shape>
</button> </button>
</div>

View File

@ -55,9 +55,6 @@ const observePopupContainer = () => {
if ( if (
menu && menu &&
(
menu.parentElement as HTMLElement & { eventSink_: Element | null }
)?.eventSink_?.matches('ytmusic-menu-renderer.ytmusic-player-bar') &&
!menu.contains(slider) !menu.contains(slider)
) { ) {
menu.prepend(slider); menu.prepend(slider);

View File

@ -102,18 +102,21 @@ function registerMPRIS(win: BrowserWindow) {
return videoId.replace(/-/g, '_MINUS_'); return videoId.replace(/-/g, '_MINUS_');
}; };
const player = setupMPRIS();
const seekTo = (event: Position) => { const seekTo = (event: Position) => {
if ( if (
currentSongInfo?.videoId && currentSongInfo?.videoId &&
event.trackId.endsWith(correctId(currentSongInfo.videoId)) event.trackId.endsWith(correctId(currentSongInfo.videoId))
) { ) {
win.webContents.send('ytmd:seek-to', microToSec(event.position ?? 0)); win.webContents.send('ytmd:seek-to', microToSec(event.position ?? 0));
player.setPosition(event.position ?? 0);
} }
}; };
const seekBy = (offset: number) => const seekBy = (offset: number) => {
win.webContents.send('ytmd:seek-by', microToSec(offset)); win.webContents.send('ytmd:seek-by', microToSec(offset));
player.setPosition(player.getPosition() + offset);
const player = setupMPRIS(); };
ipcMain.on('ytmd:player-api-loaded', () => { ipcMain.on('ytmd:player-api-loaded', () => {
win.webContents.send('ytmd:setup-seeked-listener', 'mpris'); win.webContents.send('ytmd:setup-seeked-listener', 'mpris');
@ -126,7 +129,10 @@ function registerMPRIS(win: BrowserWindow) {
requestQueueInformation(); requestQueueInformation();
}); });
ipcMain.on('ytmd:seeked', (_, t: number) => player.seeked(secToMicro(t))); ipcMain.on('ytmd:seeked', (_, t: number) => {
player.setPosition(secToMicro(t));
player.seeked(secToMicro(t));
});
ipcMain.on('ytmd:time-changed', (_, t: number) => { ipcMain.on('ytmd:time-changed', (_, t: number) => {
player.setPosition(secToMicro(t)); player.setPosition(secToMicro(t));

View File

@ -1,10 +1,12 @@
import { type NativeImage, TouchBar } from 'electron'; import { nativeImage, type NativeImage, TouchBar } from 'electron';
import { createPlugin } from '@/utils'; import { createPlugin } from '@/utils';
import getSongControls from '@/providers/song-controls'; import getSongControls from '@/providers/song-controls';
import registerCallback from '@/providers/song-info'; import registerCallback from '@/providers/song-info';
import { t } from '@/i18n'; import { t } from '@/i18n';
import youtubeMusicIcon from '@assets/youtube-music.png?asset&asarUnpack';
export default createPlugin({ export default createPlugin({
name: () => t('plugins.touchbar.name'), name: () => t('plugins.touchbar.name'),
description: () => t('plugins.touchbar.description'), description: () => t('plugins.touchbar.description'),
@ -89,9 +91,9 @@ export default createPlugin({
pausePlayButton.label = songInfo.isPaused ? '▶️' : '⏸'; pausePlayButton.label = songInfo.isPaused ? '▶️' : '⏸';
// Get image source // Get image source
songImage.icon = songInfo.image songImage.icon = (
? songInfo.image.resize({ height: 23 }) songInfo.image ? songInfo.image : nativeImage.createFromPath(youtubeMusicIcon)
: undefined; ).resize({ height: 23 });
window.setTouchBar(touchBar); window.setTouchBar(touchBar);
}); });

View File

@ -17,7 +17,3 @@ export const startingPages: Record<string, string> = {
'Uploaded Albums': 'FEmusic_library_privately_owned_releases', 'Uploaded Albums': 'FEmusic_library_privately_owned_releases',
'Uploaded Artists': 'FEmusic_library_privately_owned_artists', 'Uploaded Artists': 'FEmusic_library_privately_owned_artists',
}; };
export default {
startingPages,
};

View File

@ -35,7 +35,7 @@ async function listenForApiLoad() {
} }
interface YouTubeMusicAppElement extends HTMLElement { interface YouTubeMusicAppElement extends HTMLElement {
navigate_(page: string): void; navigate(page: string): void;
} }
async function onApiLoaded() { async function onApiLoaded() {
@ -167,7 +167,7 @@ async function onApiLoaded() {
if (startingPage && startingPages[startingPage]) { if (startingPage && startingPages[startingPage]) {
document document
.querySelector<YouTubeMusicAppElement>('ytmusic-app') .querySelector<YouTubeMusicAppElement>('ytmusic-app')
?.navigate_(startingPages[startingPage]); ?.navigate(startingPages[startingPage]);
} }
// Remove upgrade button // Remove upgrade button