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