97 lines
3.5 KiB
JavaScript
97 lines
3.5 KiB
JavaScript
|
|
// main/window.js
|
|||
|
|
const { app, BrowserWindow, dialog, ipcMain } = require('electron')
|
|||
|
|
const path = require('path')
|
|||
|
|
const fs = require('fs')
|
|||
|
|
const { isProcessRunningWin } = require('./services/iosai')
|
|||
|
|
|
|||
|
|
function safeLoadURL(win, url, onFail) {
|
|||
|
|
if (!win || win.isDestroyed()) return
|
|||
|
|
win.loadURL(url).catch(err => { console.warn('[loadURL fail]', err); onFail?.(err) })
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function createMainWindow({ updaterState }) {
|
|||
|
|
const win = new BrowserWindow({
|
|||
|
|
width: 1920,
|
|||
|
|
height: 1080,
|
|||
|
|
title: `YOLO(AI助手ios) v${app.getVersion()}`,
|
|||
|
|
frame: true,
|
|||
|
|
webPreferences: {
|
|||
|
|
preload: path.join(__dirname, 'preload.js'),
|
|||
|
|
contextIsolation: true,
|
|||
|
|
nodeIntegration: false,
|
|||
|
|
sandbox: true,
|
|||
|
|
webSecurity: true,
|
|||
|
|
backgroundThrottling: false,
|
|||
|
|
enableRemoteModule: false,
|
|||
|
|
offscreen: false,
|
|||
|
|
experimentalFeatures: true,
|
|||
|
|
autoplayPolicy: 'no-user-gesture-required',
|
|||
|
|
devTools: true,
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
win.setMenu(null)
|
|||
|
|
win.maximize()
|
|||
|
|
|
|||
|
|
const isProd = app.isPackaged
|
|||
|
|
const targetURL = isProd ? 'https://iosai.yolozs.com' : 'http://192.168.1.128:8080'
|
|||
|
|
console.log('[page] target:', targetURL)
|
|||
|
|
|
|||
|
|
const tryNavigate = (reason = '') => {
|
|||
|
|
const ts = Date.now()
|
|||
|
|
const go = () => safeLoadURL(win, `${targetURL}?t=${ts}`)
|
|||
|
|
if (updaterState.updateInProgress) {
|
|||
|
|
console.log(`[Nav] blocked (${reason}): updating...`)
|
|||
|
|
updaterState.pendingNavs.push(go)
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
go()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 等待页
|
|||
|
|
const loadingFile = path.join(__dirname, '..', 'waiting.html')
|
|||
|
|
if (process.platform === 'win32') {
|
|||
|
|
if (fs.existsSync(loadingFile)) {
|
|||
|
|
win.loadFile(loadingFile).catch(() => win.loadURL('data:text/html,<h3>正在等待 iproxy.exe 启动…</h3>'))
|
|||
|
|
} else {
|
|||
|
|
win.loadURL('data:text/html,<h3>正在等待 iproxy.exe 启动…</h3>')
|
|||
|
|
}
|
|||
|
|
waitForProcessAndNavigate(win, targetURL, { exeName: 'iproxy.exe' }, tryNavigate)
|
|||
|
|
} else {
|
|||
|
|
tryNavigate('non-win-first')
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 选择文件对话框(放这也行,但我在 system.js 里也提供了封装)
|
|||
|
|
ipcMain.handle('select-apk-file', async () => {
|
|||
|
|
const r = await dialog.showOpenDialog({ title: '选择 APK 文件', filters: [{ name: 'APK', extensions: ['apk'] }], properties: ['openFile'] })
|
|||
|
|
return r.canceled ? null : r.filePaths[0]
|
|||
|
|
})
|
|||
|
|
ipcMain.handle('select-file', async () => {
|
|||
|
|
const r = await dialog.showOpenDialog({ title: '选择文件', properties: ['openFile'] })
|
|||
|
|
return r.canceled ? null : r.filePaths[0]
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
return win
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function waitForProcessAndNavigate(win, targetURL, { intervalMs = 2000, timeoutMs = 999999, exeName = 'iproxy.exe' } = {}, tryNavigate) {
|
|||
|
|
let elapsed = 0
|
|||
|
|
win.setProgressBar(2, { mode: 'indeterminate' })
|
|||
|
|
const timer = setInterval(async () => {
|
|||
|
|
const ok = await isProcessRunningWin(exeName)
|
|||
|
|
if (ok) {
|
|||
|
|
clearInterval(timer)
|
|||
|
|
win.setProgressBar(-1)
|
|||
|
|
console.log(`[iproxy] running, go -> ${targetURL}`)
|
|||
|
|
tryNavigate('iproxy-ok')
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
elapsed += intervalMs
|
|||
|
|
if (elapsed >= timeoutMs) {
|
|||
|
|
console.warn(`[iproxy] wait timeout ${timeoutMs / 1000}s`)
|
|||
|
|
win.setTitle('YOLO(AI助手ios) - 正在等待 iproxy.exe 启动…(可检查连接/杀软/权限)')
|
|||
|
|
}
|
|||
|
|
}, intervalMs)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
module.exports = { createMainWindow, safeLoadURL }
|