diff --git a/src/index.ts b/src/index.ts index 16a5d44b..5bb7138f 100644 --- a/src/index.ts +++ b/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 // In dev mode, get string from process.env.VITE_DEV_SERVER_URL, else use fs.readFileSync if (is.dev() && process.env.ELECTRON_RENDERER_URL) { // 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'); const viteScript = document.createElement('script'); viteScript.type = 'module'; @@ -606,7 +606,7 @@ app.whenReady().then(async () => { document.body.appendChild(viteScript); document.body.appendChild(rendererScript); 0 - `); + `]; } else { const rendererPath = path.join(__dirname, '..', 'renderer'); const indexHTML = parse( @@ -618,16 +618,7 @@ app.whenReady().then(async () => { scriptSrc.getAttribute('src')!, ); const scriptString = fs.readFileSync(scriptPath, 'utf-8'); - await mainWindow?.webContents.executeJavaScriptInIsolatedWorld( - 0, - [ - { - code: scriptString + ';0', - url: url.pathToFileURL(scriptPath).toString(), - }, - ], - true, - ); + event.returnValue = [url.pathToFileURL(scriptPath).toString(), scriptString + ';0']; } }); diff --git a/src/preload.ts b/src/preload.ts index 71573edb..ac13fbae 100644 --- a/src/preload.ts +++ b/src/preload.ts @@ -1,4 +1,4 @@ -import { contextBridge, ipcRenderer, IpcRendererEvent } from 'electron'; +import { contextBridge, ipcRenderer, IpcRendererEvent, webFrame } from 'electron'; import is from 'electron-is'; import config from './config'; @@ -54,4 +54,18 @@ contextBridge.exposeInMainWorld( 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); diff --git a/src/renderer.ts b/src/renderer.ts index 8327385b..259d41a5 100644 --- a/src/renderer.ts +++ b/src/renderer.ts @@ -21,37 +21,6 @@ let isPluginLoaded = false; let isApiLoaded = false; let firstDataLoaded = false; -const observer = new MutationObserver(() => { - const playerApi = document.querySelector( - '#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() { if (!isApiLoaded) { api = document.querySelector('#movie_player'); @@ -176,14 +145,16 @@ const defineYTMDTransElements = () => { ); }; -(async () => { +const preload = async () => { await loadI18n(); await setLanguage(window.mainConfig.get('options.language') ?? 'en'); window.i18n = { t: i18t.bind(i18next), }; defineYTMDTransElements(); +}; +const main = async () => { await loadAllRendererPlugins(); isPluginLoaded = true; @@ -226,4 +197,50 @@ const defineYTMDTransElements = () => { console.log(JSON.parse(log)); }); } -})(); +}; + +const initObserver = async () => { + // check document.documentElement is ready + await new Promise((resolve) => { + document.addEventListener( + 'DOMContentLoaded', + () => { + resolve(); + }, + { once: true }, + ); + }); + + const observer = new MutationObserver(() => { + const playerApi = document.querySelector( + '#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);