mirror of
https://github.com/th-ch/youtube-music.git
synced 2026-01-14 20:01:47 +00:00
fix(ambient-mode): fix ambient-mode not working for videos after restart (#2294)
* Fix Ambient Mode not working for videos after restart (#2255) This should fix https://github.com/th-ch/youtube-music/issues/1641 * fix: fix waitForElement --------- Co-authored-by: craftgeil <80261988+craftgeil@users.noreply.github.com>
This commit is contained in:
@ -1,6 +1,7 @@
|
|||||||
import { t } from '@/i18n';
|
import { t } from '@/i18n';
|
||||||
import { createPlugin } from '@/utils';
|
import { createPlugin } from '@/utils';
|
||||||
import { ElementFromHtml } from '@/plugins/utils/renderer';
|
import { ElementFromHtml } from '@/plugins/utils/renderer';
|
||||||
|
import { waitForElement } from '@/utils/wait-for-element';
|
||||||
|
|
||||||
import undislikeHTML from './templates/undislike.html?raw';
|
import undislikeHTML from './templates/undislike.html?raw';
|
||||||
import dislikeHTML from './templates/dislike.html?raw';
|
import dislikeHTML from './templates/dislike.html?raw';
|
||||||
@ -16,7 +17,6 @@ export default createPlugin<
|
|||||||
changeObserver?: MutationObserver;
|
changeObserver?: MutationObserver;
|
||||||
waiting: boolean;
|
waiting: boolean;
|
||||||
onPageChange(): void;
|
onPageChange(): void;
|
||||||
waitForElem(selector: string): Promise<HTMLElement>;
|
|
||||||
loadFullList: (event: MouseEvent) => void;
|
loadFullList: (event: MouseEvent) => void;
|
||||||
applyToList(id: string, loader: HTMLElement): void;
|
applyToList(id: string, loader: HTMLElement): void;
|
||||||
start(): void;
|
start(): void;
|
||||||
@ -50,7 +50,7 @@ export default createPlugin<
|
|||||||
} else {
|
} else {
|
||||||
this.waiting = true;
|
this.waiting = true;
|
||||||
}
|
}
|
||||||
const continuations = await this.waitForElem('#continuations');
|
const continuations = await waitForElement<HTMLElement>('#continuations');
|
||||||
this.waiting = false;
|
this.waiting = false;
|
||||||
//Gets the for buttons
|
//Gets the for buttons
|
||||||
const buttons: Array<HTMLElement> = [
|
const buttons: Array<HTMLElement> = [
|
||||||
@ -183,16 +183,5 @@ export default createPlugin<
|
|||||||
button.remove();
|
button.remove();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
waitForElem(selector: string) {
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
const interval = setInterval(() => {
|
|
||||||
const elem = document.querySelector<HTMLElement>(selector);
|
|
||||||
if (!elem) return;
|
|
||||||
|
|
||||||
clearInterval(interval);
|
|
||||||
resolve(elem);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import { t } from '@/i18n';
|
|||||||
import { createPlugin } from '@/utils';
|
import { createPlugin } from '@/utils';
|
||||||
import { menu } from './menu';
|
import { menu } from './menu';
|
||||||
import { AmbientModePluginConfig } from './types';
|
import { AmbientModePluginConfig } from './types';
|
||||||
|
import { waitForElement } from '@/utils/wait-for-element';
|
||||||
|
|
||||||
const defaultConfig: AmbientModePluginConfig = {
|
const defaultConfig: AmbientModePluginConfig = {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
@ -36,7 +37,7 @@ export default createPlugin({
|
|||||||
unregister: null as (() => void) | null,
|
unregister: null as (() => void) | null,
|
||||||
update: null as (() => void) | null,
|
update: null as (() => void) | null,
|
||||||
interval: null as NodeJS.Timeout | null,
|
interval: null as NodeJS.Timeout | null,
|
||||||
lastMediaType: null as "video" | "image" | null,
|
lastMediaType: null as 'video' | 'image' | null,
|
||||||
lastVideoSource: null as string | null,
|
lastVideoSource: null as string | null,
|
||||||
lastImageSource: null as string | null,
|
lastImageSource: null as string | null,
|
||||||
|
|
||||||
@ -53,7 +54,8 @@ export default createPlugin({
|
|||||||
const songImage = document.querySelector<HTMLImageElement>('#song-image');
|
const songImage = document.querySelector<HTMLImageElement>('#song-image');
|
||||||
const songVideo = document.querySelector<HTMLDivElement>('#song-video');
|
const songVideo = document.querySelector<HTMLDivElement>('#song-video');
|
||||||
const image = songImage?.querySelector<HTMLImageElement>('yt-img-shadow > img');
|
const image = songImage?.querySelector<HTMLImageElement>('yt-img-shadow > img');
|
||||||
const video = songVideo?.querySelector<HTMLVideoElement>('.html5-video-container > video');
|
const video = await waitForElement<HTMLVideoElement>('.html5-video-container > video');
|
||||||
|
|
||||||
const videoWrapper = document.querySelector('#song-video > .player-wrapper');
|
const videoWrapper = document.querySelector('#song-video > .player-wrapper');
|
||||||
|
|
||||||
const injectBlurImage = () => {
|
const injectBlurImage = () => {
|
||||||
@ -179,12 +181,12 @@ export default createPlugin({
|
|||||||
const isVideoMode = () => {
|
const isVideoMode = () => {
|
||||||
const songVideo = document.querySelector<HTMLDivElement>('#song-video');
|
const songVideo = document.querySelector<HTMLDivElement>('#song-video');
|
||||||
if (!songVideo) {
|
if (!songVideo) {
|
||||||
this.lastMediaType = "image";
|
this.lastMediaType = 'image';
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const isVideo = getComputedStyle(songVideo).display !== 'none';
|
const isVideo = getComputedStyle(songVideo).display !== 'none';
|
||||||
this.lastMediaType = isVideo ? "video" : "image";
|
this.lastMediaType = isVideo ? 'video' : 'image';
|
||||||
return isVideo;
|
return isVideo;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -196,8 +198,8 @@ export default createPlugin({
|
|||||||
if (isPageOpen) {
|
if (isPageOpen) {
|
||||||
const isVideo = isVideoMode();
|
const isVideo = isVideoMode();
|
||||||
if (!force) {
|
if (!force) {
|
||||||
if (this.lastMediaType === "video" && this.lastVideoSource === video?.src) return false;
|
if (this.lastMediaType === 'video' && this.lastVideoSource === video?.src) return false;
|
||||||
if (this.lastMediaType === "image" && this.lastImageSource === image?.src) return false;
|
if (this.lastMediaType === 'image' && this.lastImageSource === image?.src) return false;
|
||||||
}
|
}
|
||||||
this.unregister?.();
|
this.unregister?.();
|
||||||
this.unregister = (isVideo ? injectBlurVideo() : injectBlurImage()) ?? null;
|
this.unregister = (isVideo ? injectBlurVideo() : injectBlurImage()) ?? null;
|
||||||
@ -205,7 +207,7 @@ export default createPlugin({
|
|||||||
this.unregister?.();
|
this.unregister?.();
|
||||||
this.unregister = null;
|
this.unregister = null;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
/* needed for switching between different views (e.g. miniplayer) */
|
/* needed for switching between different views (e.g. miniplayer) */
|
||||||
const observer = new MutationObserver((mutationsList) => {
|
const observer = new MutationObserver((mutationsList) => {
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
import { t } from '@/i18n';
|
import { t } from '@/i18n';
|
||||||
import { createPlugin } from '@/utils';
|
import { createPlugin } from '@/utils';
|
||||||
|
import { waitForElement } from '@/utils/wait-for-element';
|
||||||
|
|
||||||
export default createPlugin<
|
export default createPlugin<
|
||||||
unknown,
|
unknown,
|
||||||
unknown,
|
unknown,
|
||||||
{
|
{
|
||||||
observer?: MutationObserver;
|
observer?: MutationObserver;
|
||||||
waitForElem(selector: string): Promise<HTMLElement>;
|
|
||||||
start(): void;
|
start(): void;
|
||||||
stop(): void;
|
stop(): void;
|
||||||
}
|
}
|
||||||
@ -15,19 +15,8 @@ export default createPlugin<
|
|||||||
description: () => t('plugins.skip-disliked-songs.description'),
|
description: () => t('plugins.skip-disliked-songs.description'),
|
||||||
restartNeeded: false,
|
restartNeeded: false,
|
||||||
renderer: {
|
renderer: {
|
||||||
waitForElem(selector: string) {
|
|
||||||
return new Promise<HTMLElement>((resolve) => {
|
|
||||||
const interval = setInterval(() => {
|
|
||||||
const elem = document.querySelector<HTMLElement>(selector);
|
|
||||||
if (!elem) return;
|
|
||||||
|
|
||||||
clearInterval(interval);
|
|
||||||
resolve(elem);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
start() {
|
start() {
|
||||||
this.waitForElem('#dislike-button-renderer').then((dislikeBtn) => {
|
waitForElement<HTMLElement>('#dislike-button-renderer').then((dislikeBtn) => {
|
||||||
this.observer = new MutationObserver(() => {
|
this.observer = new MutationObserver(() => {
|
||||||
if (dislikeBtn?.getAttribute('like-status') == 'DISLIKE') {
|
if (dislikeBtn?.getAttribute('like-status') == 'DISLIKE') {
|
||||||
document
|
document
|
||||||
|
|||||||
11
src/utils/wait-for-element.ts
Normal file
11
src/utils/wait-for-element.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
export const waitForElement = <T extends Element>(selector: string): Promise<T> => {
|
||||||
|
return new Promise<T>((resolve) => {
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
const elem = document.querySelector<T>(selector);
|
||||||
|
if (!elem) return;
|
||||||
|
|
||||||
|
clearInterval(interval);
|
||||||
|
resolve(elem);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user