mirror of
https://github.com/DayuanJiang/next-ai-draw-io.git
synced 2026-09-01 17:10:24 +08:00
Closes #613 - Add electron-updater for Windows NSIS and Linux AppImage auto-update - macOS and Linux DEB fall back to GitHub API check with download link - Add "Check for Updates" menu item with i18n (en, zh, ja, zh-Hant) - Fix Windows CI workflow to publish correct latest.yml after code signing - Add update toast notifications in renderer via sonner
87 lines
3.3 KiB
TypeScript
87 lines
3.3 KiB
TypeScript
import { createElement, useEffect, useRef } from "react"
|
|
import { toast } from "sonner"
|
|
import { UpdateToast } from "@/components/update-toast"
|
|
|
|
export function useAutoUpdate() {
|
|
const downloadToastId = useRef<string | number | null>(null)
|
|
|
|
useEffect(() => {
|
|
const api = (window as Window).electronAPI
|
|
if (!api?.onUpdateStatus) return
|
|
|
|
const cleanup = api.onUpdateStatus((data) => {
|
|
switch (data.status) {
|
|
case "available":
|
|
toast.custom(
|
|
(t) =>
|
|
createElement(UpdateToast, {
|
|
variant: "download",
|
|
version: data.version,
|
|
onDownload: () => {
|
|
toast.dismiss(t)
|
|
api.startDownload().catch(() => {
|
|
// Error will come through update-status channel
|
|
})
|
|
},
|
|
onDismiss: () => toast.dismiss(t),
|
|
}),
|
|
{ duration: 15000 },
|
|
)
|
|
break
|
|
|
|
case "available-manual":
|
|
toast.custom(
|
|
(t) =>
|
|
createElement(UpdateToast, {
|
|
variant: "manual",
|
|
version: data.version,
|
|
url: data.url,
|
|
onDismiss: () => toast.dismiss(t),
|
|
}),
|
|
{ duration: Number.POSITIVE_INFINITY },
|
|
)
|
|
break
|
|
|
|
case "downloading": {
|
|
const id =
|
|
downloadToastId.current ??
|
|
`download-progress-${Date.now()}`
|
|
downloadToastId.current = id
|
|
toast.custom(
|
|
(t) =>
|
|
createElement(UpdateToast, {
|
|
variant: "downloading",
|
|
percent: data.percent,
|
|
onDismiss: () => toast.dismiss(t),
|
|
}),
|
|
{ id, duration: Number.POSITIVE_INFINITY },
|
|
)
|
|
break
|
|
}
|
|
|
|
case "downloaded":
|
|
// Dismiss progress toast — native restart dialog handles the rest
|
|
if (downloadToastId.current) {
|
|
toast.dismiss(downloadToastId.current)
|
|
downloadToastId.current = null
|
|
}
|
|
break
|
|
|
|
case "error":
|
|
if (downloadToastId.current) {
|
|
// Error during active download — inform the user
|
|
toast.dismiss(downloadToastId.current)
|
|
downloadToastId.current = null
|
|
toast.error(
|
|
"Update download failed. Please try again later.",
|
|
)
|
|
}
|
|
// Otherwise: silent — background check failure, logged in main process
|
|
break
|
|
}
|
|
})
|
|
|
|
return cleanup
|
|
}, [])
|
|
}
|