feat(update): add download action and guide users to download page when (#12)
* feat(update): add download action and guide users to download page when * fix(updater): always initialize auto-updater in non-prod builds for testing
This commit is contained in:
@@ -107,11 +107,6 @@ function setupDownloadEvents(): void {
|
||||
}
|
||||
|
||||
function initAutoUpdater(): void {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
log.info('Skipping auto-updater initialization in development mode')
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
log.info('Initializing auto-updater...')
|
||||
|
||||
@@ -123,6 +118,12 @@ function initAutoUpdater(): void {
|
||||
autoUpdater.on('update-available', (info) => {
|
||||
log.info('Update available:', info.version)
|
||||
mainWindow?.webContents.send('update:available', info)
|
||||
|
||||
// If auto-update is enabled, the update will be downloaded automatically
|
||||
// because autoDownload is set to true
|
||||
if (settingsManager.get('autoUpdate')) {
|
||||
log.info('Auto-update is enabled, update will be downloaded automatically')
|
||||
}
|
||||
})
|
||||
|
||||
autoUpdater.on('update-not-available', (info) => {
|
||||
@@ -153,12 +154,18 @@ function initAutoUpdater(): void {
|
||||
}
|
||||
})
|
||||
|
||||
if (settingsManager.get('autoUpdate')) {
|
||||
log.info('Auto-update is enabled, checking for updates...')
|
||||
void autoUpdater.checkForUpdatesAndNotify()
|
||||
}
|
||||
|
||||
log.info('Auto-updater initialized successfully')
|
||||
|
||||
// Check for updates immediately if auto-update is enabled
|
||||
const autoUpdateEnabled = settingsManager.get('autoUpdate')
|
||||
if (autoUpdateEnabled) {
|
||||
log.info('Auto-update is enabled, checking for updates immediately...')
|
||||
// Use checkForUpdates instead of checkForUpdatesAndNotify
|
||||
// because we have our own notification system and want to ensure immediate download
|
||||
void autoUpdater.checkForUpdates()
|
||||
} else {
|
||||
log.info('Auto-update is disabled, skipping automatic update check')
|
||||
}
|
||||
} catch (error) {
|
||||
log.error('Failed to initialize auto-updater:', error)
|
||||
}
|
||||
|
||||
@@ -61,43 +61,30 @@ function AppContent() {
|
||||
}
|
||||
}
|
||||
|
||||
const startUpdateDownload = async () => {
|
||||
if (updateDownloadInProgressRef.current) {
|
||||
return
|
||||
}
|
||||
|
||||
updateDownloadInProgressRef.current = true
|
||||
toast.info(t('about.notifications.downloadStarted'))
|
||||
|
||||
try {
|
||||
const result = await ipcServices.update.downloadUpdate()
|
||||
if (!result.success) {
|
||||
throw new Error(result.error ?? 'Unknown error')
|
||||
}
|
||||
} catch (error) {
|
||||
updateDownloadInProgressRef.current = false
|
||||
const message =
|
||||
error instanceof Error && error.message
|
||||
? error.message
|
||||
: t('about.notifications.unknownErrorFallback')
|
||||
toast.error(t('about.notifications.updateError', { error: message }))
|
||||
const handleGoToDownloadPage = () => {
|
||||
if (typeof window !== 'undefined') {
|
||||
window.open('https://vidbee.org/download/', '_blank', 'noopener,noreferrer')
|
||||
}
|
||||
}
|
||||
|
||||
const handleUpdateAvailable = (rawInfo: unknown) => {
|
||||
const info = (rawInfo ?? {}) as { version?: string }
|
||||
const versionLabel = info.version ?? ''
|
||||
toast.success(t('about.notifications.updateAvailable', { version: versionLabel }))
|
||||
|
||||
if (autoUpdateEnabled) {
|
||||
void startUpdateDownload()
|
||||
} else {
|
||||
toast(t('about.notifications.downloadUpdate', { version: versionLabel }), {
|
||||
// Update will be downloaded automatically because autoDownload is enabled in main process
|
||||
toast.success(t('about.notifications.updateAvailable', { version: versionLabel }), {
|
||||
action: {
|
||||
label: t('about.notifications.manualDownloadAction'),
|
||||
onClick: () => {
|
||||
void startUpdateDownload()
|
||||
}
|
||||
label: t('about.actions.goToDownload'),
|
||||
onClick: handleGoToDownloadPage
|
||||
}
|
||||
})
|
||||
// No need to manually call downloadUpdate() because autoDownload is true
|
||||
} else {
|
||||
toast.success(t('about.notifications.updateAvailable', { version: versionLabel }), {
|
||||
action: {
|
||||
label: t('about.actions.goToDownload'),
|
||||
onClick: handleGoToDownloadPage
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
"about": {
|
||||
"actions": {
|
||||
"checkUpdates": "Check updates",
|
||||
"download": "Download",
|
||||
"email": "Email",
|
||||
"feedback": "Feedback",
|
||||
"goToDownload": "Go to download page",
|
||||
"openRepo": "Open GitHub repository",
|
||||
"view": "View",
|
||||
"visit": "Visit"
|
||||
@@ -32,6 +34,7 @@
|
||||
"restartToUpdate": "Restart now to install update?",
|
||||
"restartNowAction": "Restart now",
|
||||
"updateAvailable": "Update available: {{version}}",
|
||||
"updateAvailableMessage": "A new version {{version}} is available. Please download it from the official website.",
|
||||
"updateDownloaded": "Update downloaded, restart to install",
|
||||
"updateDownloadedVersion": "Update {{version}} downloaded, restart to install",
|
||||
"updateError": "Failed to check for updates: {{error}}",
|
||||
|
||||
@@ -11,6 +11,7 @@ import { Switch } from '@renderer/components/ui/switch'
|
||||
import { useAtom, useSetAtom } from 'jotai'
|
||||
import type { LucideIcon } from 'lucide-react'
|
||||
import {
|
||||
Download,
|
||||
Facebook,
|
||||
FileText,
|
||||
Github,
|
||||
@@ -77,6 +78,47 @@ export function About() {
|
||||
) => {
|
||||
await saveSetting({ key, value })
|
||||
toast.success(t('notifications.settingsSaved'))
|
||||
|
||||
// If auto-update is enabled, check for updates immediately
|
||||
if (key === 'autoUpdate' && value === true) {
|
||||
try {
|
||||
toast.info(t('about.notifications.checkingUpdates'))
|
||||
const result = await ipcServices.update.checkForUpdates()
|
||||
|
||||
if (result.available) {
|
||||
// The update will be downloaded automatically because autoDownload is enabled
|
||||
toast.success(t('about.notifications.updateAvailable', { version: result.version }), {
|
||||
action: {
|
||||
label: t('about.actions.goToDownload'),
|
||||
onClick: handleGoToDownload
|
||||
}
|
||||
})
|
||||
setLatestVersionState({
|
||||
status: 'available',
|
||||
version: result.version ?? ''
|
||||
})
|
||||
} else if (result.error) {
|
||||
toast.error(t('about.notifications.updateError', { error: result.error }))
|
||||
setLatestVersionState({
|
||||
status: 'error',
|
||||
error: result.error
|
||||
})
|
||||
} else {
|
||||
toast.success(t('about.notifications.noUpdatesAvailable'))
|
||||
setLatestVersionState({
|
||||
status: 'uptodate',
|
||||
version: result.version ?? appVersion
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to check for updates:', error)
|
||||
toast.error(t('about.notifications.updateError', { error: 'Unknown error' }))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const handleGoToDownload = () => {
|
||||
openShareUrl('https://vidbee.org/download/')
|
||||
}
|
||||
|
||||
const handleCheckForUpdates = async () => {
|
||||
@@ -85,7 +127,12 @@ export function About() {
|
||||
const result = await ipcServices.update.checkForUpdates()
|
||||
|
||||
if (result.available) {
|
||||
toast.success(t('about.notifications.updateAvailable', { version: result.version }))
|
||||
toast.success(t('about.notifications.updateAvailable', { version: result.version }), {
|
||||
action: {
|
||||
label: t('about.actions.goToDownload'),
|
||||
onClick: handleGoToDownload
|
||||
}
|
||||
})
|
||||
setLatestVersionState({
|
||||
status: 'available',
|
||||
version: result.version ?? ''
|
||||
@@ -247,6 +294,12 @@ export function About() {
|
||||
<Github className="h-4 w-4" />
|
||||
</a>
|
||||
</Button>
|
||||
{latestVersionState?.status === 'available' ? (
|
||||
<Button onClick={handleGoToDownload} variant="default" className="gap-2">
|
||||
<Download className="h-4 w-4" />
|
||||
{t('about.actions.goToDownload')}
|
||||
</Button>
|
||||
) : null}
|
||||
<Button onClick={handleCheckForUpdates} className="gap-2">
|
||||
<RefreshCw className="h-4 w-4" />
|
||||
{t('about.actions.checkUpdates')}
|
||||
|
||||
Reference in New Issue
Block a user