feat: preload cli browser view

This commit is contained in:
Shantur Rathore
2025-11-20 10:51:14 +00:00
parent 85c0632719
commit 038cf3c762

View File

@@ -1,4 +1,4 @@
import { app, BrowserWindow, nativeImage, session } from "electron"
import { app, BrowserView, BrowserWindow, nativeImage, session } from "electron"
import { dirname, join } from "path"
import { fileURLToPath } from "url"
import { createApplicationMenu } from "./menu"
@@ -11,6 +11,10 @@ const __dirname = dirname(__filename)
const isMac = process.platform === "darwin"
const cliManager = new CliProcessManager()
let mainWindow: BrowserWindow | null = null
let cliView: BrowserView | null = null
let cliViewReady = false
let pendingCliUrl: string | null = null
let loadingScreenVisible = true
if (isMac) {
app.commandLine.appendSwitch("disable-spell-checking")
@@ -58,6 +62,7 @@ function createWindow() {
const loadingHtml = getLoadingHtmlPath()
mainWindow.loadFile(loadingHtml)
loadingScreenVisible = true
if (process.env.NODE_ENV === "development") {
mainWindow.webContents.openDevTools({ mode: "detach" })
@@ -66,9 +71,108 @@ function createWindow() {
createApplicationMenu(mainWindow)
setupCliIPC(mainWindow, cliManager)
mainWindow.on("resize", resizeCliView)
mainWindow.on("enter-full-screen", resizeCliView)
mainWindow.on("leave-full-screen", resizeCliView)
mainWindow.on("closed", () => {
destroyCliBrowserView()
mainWindow = null
})
attachCliBrowserView()
}
function destroyCliBrowserView() {
if (!cliView) {
cliViewReady = false
return
}
try {
if (mainWindow && !mainWindow.isDestroyed()) {
try {
mainWindow.removeBrowserView(cliView)
} catch (error) {
console.warn("[cli] failed to remove BrowserView", error)
}
}
const contents = cliView.webContents as any
contents?.destroy?.()
} catch (error) {
console.warn("[cli] failed to destroy BrowserView", error)
}
cliView = null
cliViewReady = false
}
function createCliBrowserView(url: string) {
pendingCliUrl = url
cliViewReady = false
destroyCliBrowserView()
const view = new BrowserView({
webPreferences: {
preload: join(__dirname, "../preload/index.cjs"),
contextIsolation: true,
nodeIntegration: false,
spellcheck: !isMac,
},
})
cliView = view
view.webContents
.loadURL(url)
.catch((error) => console.error("[cli] failed to load BrowserView:", error))
view.webContents.once("did-finish-load", () => {
if (cliView !== view) {
const contents = view.webContents as any
contents?.destroy?.()
return
}
cliViewReady = true
attachCliBrowserView()
})
}
function attachCliBrowserView() {
if (!mainWindow || mainWindow.isDestroyed() || !cliView || !cliViewReady) {
return
}
try {
mainWindow.setBrowserView(cliView)
resizeCliView()
loadingScreenVisible = false
} catch (error) {
console.error("[cli] failed to attach BrowserView:", error)
}
}
function resizeCliView() {
if (!mainWindow || !cliView) {
return
}
const [width, height] = mainWindow.getContentSize()
cliView.setBounds({ x: 0, y: 0, width, height })
cliView.setAutoResize({ width: true, height: true })
}
function showLoadingScreen() {
destroyCliBrowserView()
if (!mainWindow || mainWindow.isDestroyed()) {
return
}
if (!loadingScreenVisible) {
const loadingHtml = getLoadingHtmlPath()
loadingScreenVisible = true
mainWindow.loadFile(loadingHtml).catch((error) => console.error("[cli] failed to load loading screen:", error))
}
}
async function startCli() {
@@ -86,9 +190,16 @@ async function startCli() {
}
cliManager.on("ready", (status) => {
if (status.url && mainWindow && !mainWindow.isDestroyed()) {
console.info(`[cli] navigating main window to ${status.url}`)
mainWindow.loadURL(status.url)
if (!status.url) {
return
}
createCliBrowserView(status.url)
})
cliManager.on("status", (status) => {
if (status.state !== "ready") {
pendingCliUrl = null
showLoadingScreen()
}
})