热更新
This commit is contained in:
1 parent
9e77c8470e
commit
0aa9c21531
2 files changed
+45
-6
No files matched your search
@@ -1,5 +1,6 @@
|
||||
import { App } from '@capacitor/app'
|
||||
import { Capacitor } from '@capacitor/core'
|
||||
import { CapacitorUpdater } from '@capgo/capacitor-updater'
|
||||
import { CapacitorUpdater, type BundleInfo } from '@capgo/capacitor-updater'
|
||||
import { ElNotification } from 'element-plus'
|
||||
import http from '../api/http'
|
||||
|
||||
@@ -20,6 +21,7 @@ const updateChannel =
|
||||
import.meta.env.VITE_APP_UPDATE_CHANNEL?.trim() || 'production'
|
||||
|
||||
let checkInProgress: Promise<void> | undefined
|
||||
let updatePromptVisible = false
|
||||
|
||||
function absoluteApiUrl(relativePath: string) {
|
||||
const configuredBase = String(http.defaults.baseURL ?? '/api')
|
||||
@@ -87,9 +89,12 @@ async function checkForAppUpdate() {
|
||||
ElNotification({
|
||||
title: `新版本 ${data.version} 已就绪`,
|
||||
message:
|
||||
data.releaseNotes || '切换到后台或下次启动应用时将自动启用更新。',
|
||||
(data.releaseNotes
|
||||
? `${data.releaseNotes} 点击此提示可立即启用。`
|
||||
: '切换到后台或下次启动应用时将自动启用更新;点击此提示可立即启用。'),
|
||||
type: 'success',
|
||||
duration: 6000,
|
||||
duration: 0,
|
||||
onClick: () => void applyDownloadedUpdate(downloaded),
|
||||
})
|
||||
} catch (error) {
|
||||
// OTA failure must never stop users from entering the bundled application.
|
||||
@@ -102,6 +107,33 @@ async function checkForAppUpdate() {
|
||||
return checkInProgress
|
||||
}
|
||||
|
||||
async function applyDownloadedUpdate(bundle: BundleInfo) {
|
||||
if (updatePromptVisible) return
|
||||
updatePromptVisible = true
|
||||
try {
|
||||
await ElNotification.closeAll()
|
||||
// `set` replaces the WebView bundle and immediately reloads, so ask for a
|
||||
// deliberate confirmation instead of interrupting unsaved form input.
|
||||
await import('element-plus').then(({ ElMessageBox }) =>
|
||||
ElMessageBox.confirm(
|
||||
'将重新加载应用以启用已下载的新版本。未保存的内容请先提交。',
|
||||
'启用更新',
|
||||
{
|
||||
confirmButtonText: '立即启用',
|
||||
cancelButtonText: '稍后',
|
||||
type: 'info',
|
||||
},
|
||||
),
|
||||
)
|
||||
await CapacitorUpdater.set({ id: bundle.id })
|
||||
} catch {
|
||||
// Choosing "later" is safe: next() has already queued this bundle for
|
||||
// activation when the app backgrounds or is launched again.
|
||||
} finally {
|
||||
updatePromptVisible = false
|
||||
}
|
||||
}
|
||||
|
||||
export async function initializeAppUpdates() {
|
||||
if (!Capacitor.isNativePlatform()) return
|
||||
|
||||
@@ -117,5 +149,11 @@ export async function initializeAppUpdates() {
|
||||
// Every cold start checks the latest public release immediately. A bundle
|
||||
// downloaded here is activated when the app is next launched.
|
||||
void checkForAppUpdate()
|
||||
// Keep the native app aligned with the PWA behavior: returning to the app
|
||||
// is another opportunity to discover a newly deployed web bundle. The
|
||||
// single-flight guard prevents duplicate cold-start/foreground requests.
|
||||
void App.addListener('appStateChange', ({ isActive }) => {
|
||||
if (isActive) void checkForAppUpdate()
|
||||
})
|
||||
window.addEventListener('online', () => void checkForAppUpdate())
|
||||
}
|
||||
Reference in new issue
Block a user