make DependenciesSetupProgressIndicatorDialog support execute more than 1 tasks (pervious support download puppeteer only)

This commit is contained in:
bossgeekgo
2024-02-20 01:35:17 +08:00
parent 001a903259
commit 831dbadc74
6 changed files with 89 additions and 42 deletions
@@ -12,10 +12,8 @@ const cacheDir = path.join(
) )
const getPuppeteerManagerModule = async () => { const getPuppeteerManagerModule = async () => {
const runtimeDependencies = await import( const puppeteerManager = await import('@puppeteer/browsers')
path.join(os.homedir(), '.bossgeekgo', 'external-node-runtime-dependencies/index.mjs') return puppeteerManager
)
return runtimeDependencies.puppeteerManager
} }
export const getExpectPuppeteerExecutablePath = async () => { export const getExpectPuppeteerExecutablePath = async () => {
@@ -29,14 +27,21 @@ export const getExpectPuppeteerExecutablePath = async () => {
} }
export const checkPuppeteerExecutable = async () => { export const checkPuppeteerExecutable = async () => {
const executablePath = await getExpectPuppeteerExecutablePath() try {
return fs.existsSync(executablePath) const executablePath = await getExpectPuppeteerExecutablePath()
return fs.existsSync(executablePath)
} catch {
// should limit [ERR_MODULE_NOT_FOUND]
return false
}
} }
const checkAndDownloadPuppeteer = async (options: { const checkAndDownloadPuppeteer = async (
downloadProgressCallback?: (downloadedBytes: number, totalBytes: number) => void, options: {
confirmContinuePromise?: Promise<void> downloadProgressCallback?: (downloadedBytes: number, totalBytes: number) => void
} = {}) => { confirmContinuePromise?: Promise<void>
} = {}
) => {
const puppeteerManager = await getPuppeteerManagerModule() const puppeteerManager = await getPuppeteerManagerModule()
let installedBrowser: InstalledBrowser let installedBrowser: InstalledBrowser
if (!(await checkPuppeteerExecutable())) { if (!(await checkPuppeteerExecutable())) {
+4 -1
View File
@@ -130,7 +130,10 @@ export function createMainWindow(): void {
}) })
ipcMain.handle('check-dependencies', async () => { ipcMain.handle('check-dependencies', async () => {
return await checkPuppeteerExecutable() const [puppeteerExecutableAvailable] = await Promise.all([checkPuppeteerExecutable()])
return {
puppeteerExecutableAvailable
}
}) })
let subProcessOfCheckAndDownloadDependencies: ChildProcess | null = null let subProcessOfCheckAndDownloadDependencies: ChildProcess | null = null
@@ -1,46 +1,84 @@
<template> <template>
<el-dialog v-bind="$attrs" @open="percentage = 0"> <el-dialog v-bind="$attrs" @open="handleDialogOpen">
<div>Downloading the necessary dependencies...</div> <template v-if="!copiedDependenciesStatus.puppeteerExecutableAvailable">
<el-progress :percentage="percentage" :format="(n) => `${n.toFixed(1)}%`" /> <div>Downloading Dedicate Browser</div>
<el-progress :percentage="browserDownloadPercentage" :format="(n) => `${n.toFixed(1)}%`" />
</template>
</el-dialog> </el-dialog>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref, onUnmounted, onMounted } from 'vue' import { ref, onUnmounted, PropType } from 'vue'
import { ElMessageBox } from 'element-plus'; import { ElMessageBox } from 'element-plus'
const props = defineProps({ const props = defineProps({
dispose: Function dispose: Function,
dependenciesStatus: {
type: Object as PropType<Record<string, boolean>>,
default: () => ({})
}
}) })
const percentage = ref(0) // shallow copy
const handleProgress = (ev, { downloadedBytes, totalBytes }) => { const copiedDependenciesStatus = {
percentage.value = (downloadedBytes / totalBytes) * 100 ...props.dependenciesStatus
} }
electron.ipcRenderer.on('PUPPETEER_DOWNLOAD_PROGRESS', handleProgress)
const handleDialogOpen = () => {
browserDownloadPercentage.value = 0
}
const browserDownloadPercentage = ref(0)
const handleBrowserDownloadProgress = (ev, { downloadedBytes, totalBytes }) => {
browserDownloadPercentage.value = (downloadedBytes / totalBytes) * 100
}
electron.ipcRenderer.on('PUPPETEER_DOWNLOAD_PROGRESS', handleBrowserDownloadProgress)
onUnmounted(() => onUnmounted(() =>
electron.ipcRenderer.removeListener('PUPPETEER_DOWNLOAD_PROGRESS', handleProgress) electron.ipcRenderer.removeListener('PUPPETEER_DOWNLOAD_PROGRESS', handleBrowserDownloadProgress)
) )
const downloadProcessExitCode = ref(0) const downloadProcessExitCode = ref(0)
const processDownload = async () => { const processDownloadBrowser = async () => {
downloadProcessExitCode.value = 0 downloadProcessExitCode.value = 0
percentage.value = 0 browserDownloadPercentage.value = 0
try { try {
await electron.ipcRenderer.invoke('setup-dependencies') await electron.ipcRenderer.invoke('setup-dependencies')
props.dispose?.() browserDownloadPercentage.value = 100
} catch(err) { } catch (err) {
downloadProcessExitCode.value = 1 downloadProcessExitCode.value = 1
throw err
ElMessageBox.confirm('Encounter error while setup dependencies. Retry?')
.then(() => {
processDownload()
})
.catch(() => {
// FIXME: should exit app here
props.dispose?.()
})
} }
} }
processDownload()
const promiseList: Array<Promise<void>> = []
const processTasks = async () => {
if (!copiedDependenciesStatus.puppeteerExecutableAvailable) {
const p = processDownloadBrowser()
promiseList.push(p)
p.then(() => {
copiedDependenciesStatus.puppeteerExecutableAvailable = true
}).finally(() => {
const idx = promiseList.indexOf(p)
idx >= 0 && promiseList.splice(idx, 1)
})
}
while (promiseList.length) {
try {
await promiseList[0]
} catch {
ElMessageBox.confirm('Encounter error while setup dependencies. Retry?')
.then(() => {
processTasks()
})
.catch(() => {
// FIXME: should exit app here
promiseList.length = 0
props.dispose?.()
})
}
}
}
processTasks()
</script> </script>
@@ -2,7 +2,7 @@ import { createApp } from 'vue'
import ElementPlus from 'element-plus' import ElementPlus from 'element-plus'
import DependenciesSetupProgressIndicatorDialog from './index.vue' import DependenciesSetupProgressIndicatorDialog from './index.vue'
export const mountGlobalDialog = () => { export const mountGlobalDialog = (dependenciesStatus: Record<string, boolean>) => {
const containerElId = `elForDependenciesSetupProgressIndicatorDialog` const containerElId = `elForDependenciesSetupProgressIndicatorDialog`
if (document.getElementById(containerElId)) { if (document.getElementById(containerElId)) {
@@ -27,7 +27,8 @@ export const mountGlobalDialog = () => {
onClosed() { onClosed() {
dispose() dispose()
}, },
dispose dispose,
dependenciesStatus
}).use(ElementPlus) }).use(ElementPlus)
app.mount(containerEl) app.mount(containerEl)
@@ -95,8 +95,8 @@ const handleSubmit = async () => {
message: `Some dependencies might be corrupt. I'm trying to check and fix them.` message: `Some dependencies might be corrupt. I'm trying to check and fix them.`
}) })
const checkDependenciesResult = await electron.ipcRenderer.invoke('check-dependencies') const checkDependenciesResult = await electron.ipcRenderer.invoke('check-dependencies')
if (!checkDependenciesResult) { if (Object.values(checkDependenciesResult).includes(false)) {
mountDependenciesSetupProgressIndicatorDialog() mountDependenciesSetupProgressIndicatorDialog(checkDependenciesResult)
// TODO: should continue interrupted task // TODO: should continue interrupted task
} }
} }
@@ -15,8 +15,8 @@ onUnmounted(() => {
}) })
;(async () => { ;(async () => {
const checkDependenciesResult = await electron.ipcRenderer.invoke('check-dependencies') const checkDependenciesResult = await electron.ipcRenderer.invoke('check-dependencies')
if (!checkDependenciesResult) { if (Object.values(checkDependenciesResult).includes(false)) {
mountDependenciesSetupProgressIndicatorDialog() mountDependenciesSetupProgressIndicatorDialog(checkDependenciesResult)
} }
})() })()
</script> </script>