fix: apply fix for album-actions

This commit is contained in:
JellyBrick
2024-01-13 17:28:12 +09:00
parent a82c4ce499
commit 3964d03a3b

View File

@ -7,7 +7,22 @@ import dislikeHTML from './templates/dislike.html?raw';
import likeHTML from './templates/like.html?raw'; import likeHTML from './templates/like.html?raw';
import unlikeHTML from './templates/unlike.html?raw'; import unlikeHTML from './templates/unlike.html?raw';
export default createPlugin({ export default createPlugin<
unknown,
unknown,
{
observer?: MutationObserver;
loadObserver?: MutationObserver;
changeObserver?: MutationObserver;
waiting: boolean;
onPageChange(): void;
waitForElem(selector: string): Promise<HTMLElement>;
loadFullList: (event: MouseEvent) => void;
applyToList(id: string, loader: HTMLElement): void;
start(): void;
stop(): void;
}
>({
name: () => t('plugins.album-actions.name'), name: () => t('plugins.album-actions.name'),
description: () => t('plugins.album-actions.description'), description: () => t('plugins.album-actions.description'),
restartNeeded: false, restartNeeded: false,
@ -16,119 +31,118 @@ export default createPlugin({
enabled: false, enabled: false,
}, },
renderer: { renderer: {
observer: null as MutationObserver | null, waiting: false,
loadObserver: null as MutationObserver | null,
changeObserver: null as MutationObserver | null,
waiting: false as boolean,
start() { start() {
//Waits for pagechange // Waits for pagechange
this.onPageChange(); this.onPageChange();
this.observer = new MutationObserver(() => { this.observer = new MutationObserver(() => {
this.onPageChange(); this.onPageChange();
}); });
this.observer.observe(document.querySelector('#browse-page'), { this.observer.observe(document.querySelector('#browse-page')!, {
attributes: false, attributes: false,
childList: true, childList: true,
subtree: true, subtree: true,
}); });
}, },
onPageChange() { async onPageChange() {
if (this.waiting) { if (this.waiting) {
return; return;
} else { } else {
this.waiting = true; this.waiting = true;
} }
this.waitForElem('#continuations').then((continuations: HTMLElement) => { const continuations = await this.waitForElem('#continuations');
this.waiting = false; this.waiting = false;
//Gets the for buttons //Gets the for buttons
let buttons: Array<HTMLElement> = [ const buttons: Array<HTMLElement> = [
ElementFromHtml(undislikeHTML), ElementFromHtml(undislikeHTML),
ElementFromHtml(dislikeHTML), ElementFromHtml(dislikeHTML),
ElementFromHtml(likeHTML), ElementFromHtml(likeHTML),
ElementFromHtml(unlikeHTML), ElementFromHtml(unlikeHTML),
]; ];
//Finds the playlist //Finds the playlist
const playlist = const playlist =
document.querySelector('ytmusic-shelf-renderer') ?? document.querySelector('ytmusic-shelf-renderer') ??
document.querySelector('ytmusic-playlist-shelf-renderer'); document.querySelector('ytmusic-playlist-shelf-renderer')!;
//Adds an observer for every button so it gets updated when one is clicked // Adds an observer for every button, so it gets updated when one is clicked
this.changeObserver?.disconnect(); this.changeObserver?.disconnect();
this.changeObserver = new MutationObserver(() => { this.changeObserver = new MutationObserver(() => {
this.stop(); this.stop();
this.start(); this.start();
});
const allButtons = playlist.querySelectorAll(
'yt-button-shape.ytmusic-like-button-renderer',
);
for (const btn of allButtons) {
this.changeObserver.observe(btn, {
attributes: true,
childList: false,
subtree: false,
}); });
const allButtons = playlist.querySelectorAll( }
'yt-button-shape.ytmusic-like-button-renderer', //Determine if button is needed and colors the percentage
); const listsLength = playlist.querySelectorAll(
for (const btn of allButtons) '#button-shape-dislike > button',
this.changeObserver.observe(btn, { ).length;
attributes: true, if (continuations.children.length == 0 && listsLength > 0) {
childList: false, const counts = [
subtree: false, playlist?.querySelectorAll(
}); '#button-shape-dislike[aria-pressed=true] > button',
//Determine if button is needed and colors the percentage ).length,
const listsLength = playlist.querySelectorAll( playlist?.querySelectorAll(
'#button-shape-dislike > button', '#button-shape-dislike[aria-pressed=false] > button',
).length; ).length,
if (continuations.children.length == 0 && listsLength > 0) { playlist?.querySelectorAll(
const counts = [ '#button-shape-like[aria-pressed=false] > button',
playlist?.querySelectorAll( ).length,
'#button-shape-dislike[aria-pressed=true] > button', playlist?.querySelectorAll(
).length, '#button-shape-like[aria-pressed=true] > button',
playlist?.querySelectorAll( ).length,
'#button-shape-dislike[aria-pressed=false] > button', ];
).length, let i = 0;
playlist?.querySelectorAll( for (const count of counts) {
'#button-shape-like[aria-pressed=false] > button', if (count == 0) {
).length, buttons.splice(i, 1);
playlist?.querySelectorAll( i--;
'#button-shape-like[aria-pressed=true] > button', } else {
).length, (buttons[i].children[0].children[0] as HTMLElement).style.setProperty(
]; '-webkit-mask-size',
let i = 0; `100% ${100 - ((count / listsLength) * 100)}%`,
for (const count of counts) { );
if (count == 0) {
buttons.splice(i, 1);
i--;
} else {
buttons[i].children[0].children[0].style.setProperty(
'-webkit-mask-size',
`100% ${100 - (count / listsLength) * 100}%`,
);
}
i++;
} }
i++;
} }
const menu = document.querySelector('.detail-page-menu'); }
if (menu && !document.querySelector('.like-menu')) { const menu = document.querySelector('.detail-page-menu');
for (const button of buttons) { if (menu && !document.querySelector('.like-menu')) {
menu.appendChild(button); for (const button of buttons) {
button.addEventListener('click', this.loadFullList); menu.appendChild(button);
} button.addEventListener('click', this.loadFullList);
} }
}); }
}, },
loadFullList(event) { loadFullList(event: MouseEvent) {
event.stopPropagation(); if (event.currentTarget instanceof Element) {
const id: string = event.currentTarget.id, event.stopPropagation();
loader = document.getElementById('continuations'); const id = event.currentTarget.id;
this.loadObserver = new MutationObserver(() => { const loader = document.getElementById('continuations')!;
this.loadObserver = new MutationObserver(() => {
this.applyToList(id, loader);
});
this.applyToList(id, loader); this.applyToList(id, loader);
}); this.loadObserver.observe(loader, {
this.applyToList(id, loader); attributes: true,
this.loadObserver.observe(loader, { childList: true,
attributes: true, subtree: true,
childList: true, });
subtree: true, loader?.style.setProperty('top', '0');
}); loader?.style.setProperty('left', '50%');
loader?.style.setProperty('top', '0'); loader?.style.setProperty('position', 'absolute');
loader?.style.setProperty('left', '50%'); }
loader?.style.setProperty('position', 'absolute');
}, },
applyToList(id: string, loader: HTMLElement) { applyToList(id: string, loader: HTMLElement) {
if (loader.children.length != 0) return; if (loader.children.length != 0) return;
this.loadObserver?.disconnect(); this.loadObserver?.disconnect();
let playlistButtons: NodeListOf<Element> | undefined; let playlistButtons: NodeListOf<HTMLElement> | undefined;
const playlist = document.querySelector('ytmusic-shelf-renderer') const playlist = document.querySelector('ytmusic-shelf-renderer')
? document.querySelector('ytmusic-shelf-renderer') ? document.querySelector('ytmusic-shelf-renderer')
: document.querySelector('ytmusic-playlist-shelf-renderer'); : document.querySelector('ytmusic-playlist-shelf-renderer');
@ -167,7 +181,7 @@ export default createPlugin({
waitForElem(selector: string) { waitForElem(selector: string) {
return new Promise((resolve) => { return new Promise((resolve) => {
const interval = setInterval(() => { const interval = setInterval(() => {
const elem = document.querySelector(selector); const elem = document.querySelector<HTMLElement>(selector);
if (!elem) return; if (!elem) return;
clearInterval(interval); clearInterval(interval);