add browser auto find logic to first run

This commit is contained in:
geekgeekrun
2026-02-08 01:58:44 +08:00
parent 8cc94baa18
commit e746bf70e9
9 changed files with 149 additions and 31 deletions
@@ -4,9 +4,9 @@ import {
browserAssistantWindow browserAssistantWindow
} from '../window/browserAssistantWindow' } from '../window/browserAssistantWindow'
export async function configWithBrowserAssistant({ windowOption } = {}) { export async function configWithBrowserAssistant({ windowOption, autoFind } = {}) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
createBrowserAssistantWindow({ ...windowOption }) createBrowserAssistantWindow({ ...windowOption }, { autoFind })
let processDone = false let processDone = false
function handler() { function handler() {
@@ -3,6 +3,11 @@ import os from 'os'
import path from 'path' import path from 'path'
import buildInfo from '../../common/build-info.json' import buildInfo from '../../common/build-info.json'
import { ensureStorageFileExist } from '@geekgeekrun/geek-auto-start-chat-with-boss/runtime-file-utils.mjs' import { ensureStorageFileExist } from '@geekgeekrun/geek-auto-start-chat-with-boss/runtime-file-utils.mjs'
import {
createFirstLaunchNoticeWindow,
firstLaunchNoticeWindow
} from '../window/firstLaunchNoticeWindow'
import { ipcMain } from 'electron'
export const firstLaunchNoticeApproveFlagPath = path.join( export const firstLaunchNoticeApproveFlagPath = path.join(
os.homedir(), os.homedir(),
@@ -10,8 +15,28 @@ export const firstLaunchNoticeApproveFlagPath = path.join(
'ui-first-launch-notice-flag' 'ui-first-launch-notice-flag'
) )
export const isFirstLaunchNoticeApproveFlagExist = () => fs.existsSync(firstLaunchNoticeApproveFlagPath) export const isFirstLaunchNoticeApproveFlagExist = () =>
fs.existsSync(firstLaunchNoticeApproveFlagPath)
export const createFirstLaunchNoticeApproveFlag = () => { export const createFirstLaunchNoticeApproveFlag = () => {
ensureStorageFileExist() ensureStorageFileExist()
fs.writeFileSync(firstLaunchNoticeApproveFlagPath, buildInfo.version) fs.writeFileSync(firstLaunchNoticeApproveFlagPath, buildInfo.version)
} }
export async function waitForUserApproveAgreement({ windowOption } = {}) {
return new Promise((resolve, reject) => {
createFirstLaunchNoticeWindow({ ...windowOption })
let processDone = false
function handler() {
processDone = true
firstLaunchNoticeWindow.close()
}
ipcMain.once('first-launch-notice-approve', handler)
firstLaunchNoticeWindow.once('closed', () => {
ipcMain.off('first-launch-notice-approve', handler)
if (processDone) {
resolve(true)
} else {
reject(new Error('USER_CANCELLED'))
}
})
})
}
@@ -19,7 +19,8 @@ const registerHandleWithWindow = (
} }
export function createBrowserAssistantWindow( export function createBrowserAssistantWindow(
opt?: Electron.BrowserWindowConstructorOptions opt?: Electron.BrowserWindowConstructorOptions,
{ autoFind } = {}
): BrowserWindow { ): BrowserWindow {
// Create the browser window. // Create the browser window.
if (browserAssistantWindow) { if (browserAssistantWindow) {
@@ -45,11 +46,15 @@ export function createBrowserAssistantWindow(
// HMR for renderer base on electron-vite cli. // HMR for renderer base on electron-vite cli.
// Load the remote URL for development or the local html file for production. // Load the remote URL for development or the local html file for production.
let routePath = '#/browserAssistant'
if (autoFind) {
routePath = '#/browserAutoFind'
}
if (process.env.NODE_ENV === 'development' && process.env['ELECTRON_RENDERER_URL']) { if (process.env.NODE_ENV === 'development' && process.env['ELECTRON_RENDERER_URL']) {
browserAssistantWindow.loadURL(process.env['ELECTRON_RENDERER_URL'] + '#/browserAssistant') browserAssistantWindow.loadURL(process.env['ELECTRON_RENDERER_URL'] + routePath)
} else { } else {
browserAssistantWindow.loadURL( browserAssistantWindow.loadURL(
'file://' + path.join(__dirname, '../renderer/index.html') + '#/browserAssistant' 'file://' + path.join(__dirname, '../renderer/index.html') + routePath
) )
} }
@@ -1,6 +1,5 @@
import { BrowserWindow, ipcMain } from 'electron' import { BrowserWindow } from 'electron'
import path from 'path' import path from 'path'
import { createFirstLaunchNoticeApproveFlag } from '../features/first-launch-notice-window'
export let firstLaunchNoticeWindow: BrowserWindow | null = null export let firstLaunchNoticeWindow: BrowserWindow | null = null
export function createFirstLaunchNoticeWindow( export function createFirstLaunchNoticeWindow(
@@ -41,11 +40,3 @@ export function createFirstLaunchNoticeWindow(
return firstLaunchNoticeWindow! return firstLaunchNoticeWindow!
} }
export const initIpc = () => {
ipcMain.handle('first-launch-notice-approve', () => {
createFirstLaunchNoticeApproveFlag()
firstLaunchNoticeWindow?.close()
})
}
initIpc()
+36 -9
View File
@@ -1,9 +1,14 @@
import { BrowserWindow, shell } from 'electron' import { app, BrowserWindow, shell } from 'electron'
import path from 'path' import path from 'path'
import { openDevTools } from '../commands' import { openDevTools } from '../commands'
import { createFirstLaunchNoticeWindow } from './firstLaunchNoticeWindow' import {
import { isFirstLaunchNoticeApproveFlagExist } from '../features/first-launch-notice-window' createFirstLaunchNoticeApproveFlag,
isFirstLaunchNoticeApproveFlagExist,
waitForUserApproveAgreement
} from '../features/first-launch-notice-window'
import { daemonEE } from '../flow/OPEN_SETTING_WINDOW/connect-to-daemon' import { daemonEE } from '../flow/OPEN_SETTING_WINDOW/connect-to-daemon'
import { getLastUsedAndAvailableBrowser } from '../flow/DOWNLOAD_DEPENDENCIES/utils/browser-history'
import { configWithBrowserAssistant } from '../features/config-with-browser-assistant'
export let mainWindow: BrowserWindow | null = null export let mainWindow: BrowserWindow | null = null
export function createMainWindow(): BrowserWindow { export function createMainWindow(): BrowserWindow {
@@ -29,12 +34,34 @@ export function createMainWindow(): BrowserWindow {
mainWindow.show() mainWindow.show()
}) })
mainWindow.on('ready-to-show', async () => { mainWindow.on('ready-to-show', async () => {
!isFirstLaunchNoticeApproveFlagExist() && if (!isFirstLaunchNoticeApproveFlagExist()) {
createFirstLaunchNoticeWindow({ try {
parent: mainWindow!, await waitForUserApproveAgreement({
modal: true, windowOption: {
show: true parent: mainWindow!,
}) modal: true,
show: true
}
})
createFirstLaunchNoticeApproveFlag()
} catch {
app.exit(0)
return
}
}
const lastBrowser = await getLastUsedAndAvailableBrowser()
if (!lastBrowser) {
try {
await configWithBrowserAssistant({
windowOption: {
parent: mainWindow!,
modal: true,
show: true
},
autoFind: true
})
} catch (err) {}
}
}) })
mainWindow.on('ready-to-show', async () => { mainWindow.on('ready-to-show', async () => {
process.env.NODE_ENV === 'development' && process.env.NODE_ENV === 'development' &&
@@ -50,11 +50,14 @@
@click="autoDetectPuppeteerExecutable" @click="autoDetectPuppeteerExecutable"
>自动检测</a >自动检测</a
>按钮再次尝试目前2026.2.7已知 Chrome 最新版本为 144.0.7559.133 >按钮再次尝试目前2026.2.7已知 Chrome 最新版本为 144.0.7559.133
多数情况下本程序都可以正常工作但由于浏览器会自动升级版本不固定可能存在<span color-orange 多数情况下本程序都可以正常工作但由于浏览器会自动升级版本不固定可能存在<span
color-orange
>浏览器升级后某些功能不兼容导致本程序不能正确运行</span >浏览器升级后某些功能不兼容导致本程序不能正确运行</span
>的问题您可以<a href="javascript:;" @click="handleFeedbackClick" >的问题如果您确实遇到不能正常运行的问题<a
href="javascript:;"
@click="handleFeedbackClick"
>提交 Issue</a >提交 Issue</a
>来反馈新版本浏览器不能正常运行的问题同时请再尝试方案一 >来反馈同时请再尝试方案一
</li> </li>
</ul> </ul>
</div> </div>
@@ -202,7 +205,9 @@ const handleFeedbackClick = () => {
} }
const handleClickLaunchBrowserDownloader = async () => { const handleClickLaunchBrowserDownloader = async () => {
gtagRenderer('launch_browser_downloader_clicked') gtagRenderer('launch_browser_downloader_clicked')
const downloadedBrowserPath = await electron.ipcRenderer.invoke('download-browser-with-downloader') const downloadedBrowserPath = await electron.ipcRenderer.invoke(
'download-browser-with-downloader'
)
if (downloadedBrowserPath) { if (downloadedBrowserPath) {
formData.value.browserPath = downloadedBrowserPath formData.value.browserPath = downloadedBrowserPath
ElMessage({ ElMessage({
@@ -0,0 +1,58 @@
<template>
<div class="h-screen of-hidden flex flex-col flex-items-center flex-justify-center">
<div>
<div>你可能是第一次安装本程序</div>
<div>正在查找可用浏览器请稍等...</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import { gtagRenderer as baseGtagRenderer } from '@renderer/utils/gtag'
const { ipcRenderer } = electron
const router = useRouter()
// const checkDependenciesResult = ref({})
// const downloadProcessWaitee = ref(null)
const gtagRenderer = (name, params?: object) => {
return baseGtagRenderer(name, {
scene: 'browser-auto-find',
...params
})
}
async function autoDetectPuppeteerExecutable() {
const result = await ipcRenderer.invoke('get-any-available-puppeteer-executable')
if (!result) {
gtagRenderer('first-run-auto-detect-pptr-exe-fail')
ElMessage({
message: '未找到可用浏览器的可执行文件,请尝试手动配置',
type: 'warning',
grouping: true
})
router.replace({
path: '/browserAssistant',
query: {
firstRun: 1
}
})
return
}
gtagRenderer('first-run-auto-detect-pptr-exe-success')
await ipcRenderer.send('browser-config-saved')
}
autoDetectPuppeteerExecutable()
</script>
<style lang="scss" scoped>
a:link,
a:visited,
a:hover,
a:active {
color: #409eff;
}
</style>
@@ -129,7 +129,7 @@ const readmeItemCheckStatusList = ref<number[]>([])
const handleCancel = async () => { const handleCancel = async () => {
gtagRenderer('cancel_clicked') gtagRenderer('cancel_clicked')
await sleep(500) await sleep(500)
electron.ipcRenderer.invoke('exit-app-immediately') window.close()
} }
const unreadItemsAfterClickSubmit = ref<Record<number, true>>({}) const unreadItemsAfterClickSubmit = ref<Record<number, true>>({})
@@ -150,7 +150,7 @@ const handleSubmit = () => {
} }
return return
} }
electron.ipcRenderer.invoke('first-launch-notice-approve') electron.ipcRenderer.send('first-launch-notice-approve')
gtagRenderer('submit_done') gtagRenderer('submit_done')
} }
const handleReadmeItemCheckStatusListChange = (value: number[]) => { const handleReadmeItemCheckStatusListChange = (value: number[]) => {
@@ -24,6 +24,13 @@ const routes: Array<RouteRecordRaw> = [
title: '浏览器助手' title: '浏览器助手'
} }
}, },
{
path: '/browserAutoFind',
component: () => import('@renderer/page/BrowserAutoFind/index.vue'),
meta: {
title: '浏览器助手 - 自动查找浏览器'
}
},
{ {
path: '/browserDownloadProgress', path: '/browserDownloadProgress',
component: () => import('@renderer/page/BrowserDownloadProgress/index.vue'), component: () => import('@renderer/page/BrowserDownloadProgress/index.vue'),