mirror of
https://github.com/th-ch/youtube-music.git
synced 2026-01-14 03:41:46 +00:00
fix: renderer plugin load timing
MAGIC OF JAVASCRIPT
This commit is contained in:
17
src/index.ts
17
src/index.ts
@ -590,12 +590,12 @@ app.whenReady().then(async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ipcMain.handle('load-renderer-plugins', async () => {
|
ipcMain.on('get-renderer-script', (event) => {
|
||||||
// Inject index.html file as string using insertAdjacentHTML
|
// Inject index.html file as string using insertAdjacentHTML
|
||||||
// In dev mode, get string from process.env.VITE_DEV_SERVER_URL, else use fs.readFileSync
|
// In dev mode, get string from process.env.VITE_DEV_SERVER_URL, else use fs.readFileSync
|
||||||
if (is.dev() && process.env.ELECTRON_RENDERER_URL) {
|
if (is.dev() && process.env.ELECTRON_RENDERER_URL) {
|
||||||
// HACK: to make vite work with electron renderer (supports hot reload)
|
// HACK: to make vite work with electron renderer (supports hot reload)
|
||||||
await mainWindow?.webContents.executeJavaScript(`
|
event.returnValue = [null, `
|
||||||
console.log('Loading vite from dev server');
|
console.log('Loading vite from dev server');
|
||||||
const viteScript = document.createElement('script');
|
const viteScript = document.createElement('script');
|
||||||
viteScript.type = 'module';
|
viteScript.type = 'module';
|
||||||
@ -606,7 +606,7 @@ app.whenReady().then(async () => {
|
|||||||
document.body.appendChild(viteScript);
|
document.body.appendChild(viteScript);
|
||||||
document.body.appendChild(rendererScript);
|
document.body.appendChild(rendererScript);
|
||||||
0
|
0
|
||||||
`);
|
`];
|
||||||
} else {
|
} else {
|
||||||
const rendererPath = path.join(__dirname, '..', 'renderer');
|
const rendererPath = path.join(__dirname, '..', 'renderer');
|
||||||
const indexHTML = parse(
|
const indexHTML = parse(
|
||||||
@ -618,16 +618,7 @@ app.whenReady().then(async () => {
|
|||||||
scriptSrc.getAttribute('src')!,
|
scriptSrc.getAttribute('src')!,
|
||||||
);
|
);
|
||||||
const scriptString = fs.readFileSync(scriptPath, 'utf-8');
|
const scriptString = fs.readFileSync(scriptPath, 'utf-8');
|
||||||
await mainWindow?.webContents.executeJavaScriptInIsolatedWorld(
|
event.returnValue = [url.pathToFileURL(scriptPath).toString(), scriptString + ';0'];
|
||||||
0,
|
|
||||||
[
|
|
||||||
{
|
|
||||||
code: scriptString + ';0',
|
|
||||||
url: url.pathToFileURL(scriptPath).toString(),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { contextBridge, ipcRenderer, IpcRendererEvent } from 'electron';
|
import { contextBridge, ipcRenderer, IpcRendererEvent, webFrame } from 'electron';
|
||||||
import is from 'electron-is';
|
import is from 'electron-is';
|
||||||
|
|
||||||
import config from './config';
|
import config from './config';
|
||||||
@ -54,4 +54,18 @@ contextBridge.exposeInMainWorld(
|
|||||||
process.env.ELECTRON_RENDERER_URL,
|
process.env.ELECTRON_RENDERER_URL,
|
||||||
);
|
);
|
||||||
|
|
||||||
ipcRenderer.invoke('load-renderer-plugins');
|
const [path, script] = ipcRenderer.sendSync('get-renderer-script') as [string | null, string];
|
||||||
|
let blocked = true;
|
||||||
|
if (path) {
|
||||||
|
webFrame.executeJavaScriptInIsolatedWorld(0, [
|
||||||
|
{
|
||||||
|
code: script,
|
||||||
|
url: path,
|
||||||
|
},
|
||||||
|
], true, () => blocked = false);
|
||||||
|
} else {
|
||||||
|
webFrame.executeJavaScript(script, true, () => blocked = false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// HACK: Wait for the script to be executed
|
||||||
|
while (blocked);
|
||||||
|
|||||||
@ -21,37 +21,6 @@ let isPluginLoaded = false;
|
|||||||
let isApiLoaded = false;
|
let isApiLoaded = false;
|
||||||
let firstDataLoaded = false;
|
let firstDataLoaded = false;
|
||||||
|
|
||||||
const observer = new MutationObserver(() => {
|
|
||||||
const playerApi = document.querySelector<Element & YoutubePlayer>(
|
|
||||||
'#movie_player',
|
|
||||||
);
|
|
||||||
if (playerApi) {
|
|
||||||
observer.disconnect();
|
|
||||||
|
|
||||||
// Inject song-info provider
|
|
||||||
setupSongInfo(playerApi);
|
|
||||||
const dataLoadedListener = (name: string) => {
|
|
||||||
if (!firstDataLoaded && name === 'dataloaded') {
|
|
||||||
firstDataLoaded = true;
|
|
||||||
playerApi.removeEventListener('videodatachange', dataLoadedListener);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
playerApi.addEventListener('videodatachange', dataLoadedListener);
|
|
||||||
|
|
||||||
if (isPluginLoaded && !isApiLoaded) {
|
|
||||||
api = playerApi;
|
|
||||||
isApiLoaded = true;
|
|
||||||
|
|
||||||
onApiLoaded();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
observer.observe(document.documentElement, {
|
|
||||||
childList: true,
|
|
||||||
subtree: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
async function listenForApiLoad() {
|
async function listenForApiLoad() {
|
||||||
if (!isApiLoaded) {
|
if (!isApiLoaded) {
|
||||||
api = document.querySelector('#movie_player');
|
api = document.querySelector('#movie_player');
|
||||||
@ -176,14 +145,16 @@ const defineYTMDTransElements = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
(async () => {
|
const preload = async () => {
|
||||||
await loadI18n();
|
await loadI18n();
|
||||||
await setLanguage(window.mainConfig.get('options.language') ?? 'en');
|
await setLanguage(window.mainConfig.get('options.language') ?? 'en');
|
||||||
window.i18n = {
|
window.i18n = {
|
||||||
t: i18t.bind(i18next),
|
t: i18t.bind(i18next),
|
||||||
};
|
};
|
||||||
defineYTMDTransElements();
|
defineYTMDTransElements();
|
||||||
|
};
|
||||||
|
|
||||||
|
const main = async () => {
|
||||||
await loadAllRendererPlugins();
|
await loadAllRendererPlugins();
|
||||||
isPluginLoaded = true;
|
isPluginLoaded = true;
|
||||||
|
|
||||||
@ -226,4 +197,50 @@ const defineYTMDTransElements = () => {
|
|||||||
console.log(JSON.parse(log));
|
console.log(JSON.parse(log));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
})();
|
};
|
||||||
|
|
||||||
|
const initObserver = async () => {
|
||||||
|
// check document.documentElement is ready
|
||||||
|
await new Promise<void>((resolve) => {
|
||||||
|
document.addEventListener(
|
||||||
|
'DOMContentLoaded',
|
||||||
|
() => {
|
||||||
|
resolve();
|
||||||
|
},
|
||||||
|
{ once: true },
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
const observer = new MutationObserver(() => {
|
||||||
|
const playerApi = document.querySelector<Element & YoutubePlayer>(
|
||||||
|
'#movie_player',
|
||||||
|
);
|
||||||
|
if (playerApi) {
|
||||||
|
observer.disconnect();
|
||||||
|
|
||||||
|
// Inject song-info provider
|
||||||
|
setupSongInfo(playerApi);
|
||||||
|
const dataLoadedListener = (name: string) => {
|
||||||
|
if (!firstDataLoaded && name === 'dataloaded') {
|
||||||
|
firstDataLoaded = true;
|
||||||
|
playerApi.removeEventListener('videodatachange', dataLoadedListener);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
playerApi.addEventListener('videodatachange', dataLoadedListener);
|
||||||
|
|
||||||
|
if (isPluginLoaded && !isApiLoaded) {
|
||||||
|
api = playerApi;
|
||||||
|
isApiLoaded = true;
|
||||||
|
|
||||||
|
onApiLoaded();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
observer.observe(document.documentElement, {
|
||||||
|
childList: true,
|
||||||
|
subtree: true,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
initObserver().then(preload).then(main);
|
||||||
|
|||||||
Reference in New Issue
Block a user