fix(synced-lyrics): fix lyric load

fix #2295
This commit is contained in:
JellyBrick
2024-08-01 20:18:02 +09:00
parent eabc28b39f
commit 747bde2136
3 changed files with 16 additions and 15 deletions

View File

@ -1,4 +1,5 @@
import { createRenderer } from '@/utils'; import { createRenderer } from '@/utils';
import { waitForElement } from '@/utils/wait-for-element';
import { makeLyricsRequest } from './lyrics'; import { makeLyricsRequest } from './lyrics';
import { selectors, tabStates } from './utils'; import { selectors, tabStates } from './utils';
@ -15,10 +16,9 @@ export let _ytAPI: YoutubePlayer | null = null;
export const renderer = createRenderer<{ export const renderer = createRenderer<{
observerCallback: MutationCallback; observerCallback: MutationCallback;
onPlayerApiReady: (api: YoutubePlayer) => void;
hasAddedEvents: boolean; hasAddedEvents: boolean;
observer?: MutationObserver; observer?: MutationObserver;
videoDataChange: () => void; videoDataChange: () => Promise<void>;
progressCallback: (evt: Event) => void; progressCallback: (evt: Event) => void;
}, SyncedLyricsPluginConfig>({ }, SyncedLyricsPluginConfig>({
onConfigChange(newConfig) { onConfigChange(newConfig) {
@ -42,17 +42,17 @@ export const renderer = createRenderer<{
} }
}, },
onPlayerApiReady(api: YoutubePlayer) { async onPlayerApiReady(api: YoutubePlayer) {
_ytAPI = api; _ytAPI = api;
api.addEventListener('videodatachange', this.videoDataChange); api.addEventListener('videodatachange', this.videoDataChange);
this.videoDataChange(); await this.videoDataChange();
}, },
hasAddedEvents: false, hasAddedEvents: false,
videoDataChange() { async videoDataChange() {
if (!this.hasAddedEvents) { if (!this.hasAddedEvents) {
const video = document.querySelector('video'); const video = document.querySelector('video');
@ -61,15 +61,14 @@ export const renderer = createRenderer<{
if (video) this.hasAddedEvents = true; if (video) this.hasAddedEvents = true;
} }
const header = document.querySelector<HTMLElement>(selectors.head);
if (!header) return;
this.observer ??= new MutationObserver( this.observer ??= new MutationObserver(
this.observerCallback, this.observerCallback,
); );
// Force the lyrics tab to be enabled at all times. // Force the lyrics tab to be enabled at all times.
this.observer.disconnect(); this.observer.disconnect();
const header = await waitForElement<HTMLElement>(selectors.head);
this.observer.observe(header, { attributes: true }); this.observer.observe(header, { attributes: true });
header.removeAttribute('disabled'); header.removeAttribute('disabled');
}, },

View File

@ -1,5 +1,7 @@
import { render } from 'solid-js/web'; import { render } from 'solid-js/web';
import { waitForElement } from '@/utils/wait-for-element';
import { LyricsRenderer, setIsVisible, setPlayerState } from './renderer'; import { LyricsRenderer, setIsVisible, setPlayerState } from './renderer';
import type { VideoDetails } from '@/types/video-details'; import type { VideoDetails } from '@/types/video-details';
@ -13,18 +15,17 @@ export const selectors = {
}; };
export const tabStates = { export const tabStates = {
true: (data?: VideoDetails) => { true: async (data?: VideoDetails) => {
setIsVisible(true); setIsVisible(true);
setPlayerState(data ?? null); setPlayerState(data ?? null);
const tabRenderer = document.querySelector<HTMLElement>(
selectors.body.tabRenderer,
);
if (!tabRenderer) return;
let container = document.querySelector('#synced-lyrics-container'); let container = document.querySelector('#synced-lyrics-container');
if (container) return; if (container) return;
const tabRenderer = await waitForElement<HTMLElement>(
selectors.body.tabRenderer,
);
container = Object.assign(document.createElement('div'), { container = Object.assign(document.createElement('div'), {
id: 'synced-lyrics-container', id: 'synced-lyrics-container',
}); });

View File

@ -241,7 +241,8 @@ export interface FlagEndpoint {
flagAction: string; flagAction: string;
} }
export type VideoDataChangeValue = { // see song-info-front.ts
export type VideoDataChangeValue = Record<string, unknown> & {
videoId: string; videoId: string;
title: string; title: string;
author: string; author: string;