import React, { useState, useEffect } from 'react';
import { Box, Button, Snackbar, Alert, Typography, Link, CircularProgress, LinearProgress } from '@mui/material';
import UpdateIcon from '@mui/icons-material/Update';
import { useTranslation } from 'react-i18next';
const UpdateChecker = () => {
const { t } = useTranslation();
const [updateAvailable, setUpdateAvailable] = useState(false);
const [updateInfo, setUpdateInfo] = useState(null);
const [open, setOpen] = useState(false);
const [checking, setChecking] = useState(false);
const [downloading, setDownloading] = useState(false);
const [downloadProgress, setDownloadProgress] = useState(0);
const [updateDownloaded, setUpdateDownloaded] = useState(false);
const [updateError, setUpdateError] = useState(null);
// 检查更新
const checkForUpdates = async () => {
if (!window.electron?.updater) {
console.warn('Update feature is not available, possibly running in browser environment');
return;
}
try {
setChecking(true);
setUpdateError(null);
const result = await window.electron.updater.checkForUpdates();
console.log('Update check result:', result);
// 返回当前版本信息
if (result) {
setUpdateInfo(prev => ({
...prev,
currentVersion: result.currentVersion
}));
}
} catch (error) {
console.error('Failed to check for updates:', error);
// setUpdateError(error.message || 'Failed to check for updates');
} finally {
setChecking(false);
}
};
// 下载更新
const downloadUpdate = async () => {
if (!window.electron?.updater) return;
try {
setDownloading(true);
setUpdateError(null);
await window.electron.updater.downloadUpdate();
} catch (error) {
console.error('下载更新失败:', error);
setUpdateError(error.message || '下载更新失败');
setDownloading(false);
}
};
// 安装更新
const installUpdate = async () => {
if (!window.electron?.updater) return;
try {
await window.electron.updater.installUpdate();
} catch (error) {
console.error('Failed to install update:', error);
// setUpdateError(error.message || 'Failed to install update');
}
};
// 设置更新事件监听
useEffect(() => {
if (!window.electron?.updater) return;
// 有可用更新
const removeUpdateAvailable = window.electron.updater.onUpdateAvailable(info => {
console.log('发现新版本:', info);
setUpdateAvailable(true);
setUpdateInfo(prev => ({
...prev,
...info,
releaseUrl: `https://github.com/ConardLi/easy-dataset/releases`
}));
setOpen(true);
});
// 没有可用更新
const removeUpdateNotAvailable = window.electron.updater.onUpdateNotAvailable(() => {
console.log('没有可用更新');
setUpdateAvailable(false);
});
// 更新错误
const removeUpdateError = window.electron.updater.onUpdateError(error => {
console.error('更新错误:', error);
// setUpdateError(error);
});
// 下载进度
const removeDownloadProgress = window.electron.updater.onDownloadProgress(progress => {
console.log('下载进度:', progress);
setDownloadProgress(progress.percent || 0);
});
// 更新下载完成
const removeUpdateDownloaded = window.electron.updater.onUpdateDownloaded(info => {
console.log('更新下载完成:', info);
setDownloading(false);
setUpdateDownloaded(true);
});
// 组件挂载时检查更新
const timer = setTimeout(() => {
checkForUpdates();
}, 5000);
// 清理函数
return () => {
clearTimeout(timer);
removeUpdateAvailable();
removeUpdateNotAvailable();
removeUpdateError();
removeDownloadProgress();
removeUpdateDownloaded();
};
}, []);
// 定期检查更新(每小时一次)
useEffect(() => {
if (!window.electron?.updater) return;
const interval = setInterval(
() => {
checkForUpdates();
},
60 * 60 * 1000
);
return () => clearInterval(interval);
}, []);
const handleClose = () => {
setOpen(false);
};
// 如果没有更新或者不在 Electron 环境中,不显示任何内容
if (!updateAvailable && !open) return null;
return (
<>
{updateAvailable && (
} onClick={() => setOpen(true)} sx={{ ml: 1 }}>
{t('update.newVersion')}
)}
{t('update.newVersionAvailable')}
{updateInfo && (
<>
{t('update.currentVersion')}: {updateInfo.currentVersion}
{t('update.latestVersion')}: {updateInfo.version}
>
)}
{checking && (
{t('update.checking')}
)}
{updateError && (
{updateError}
)}
{downloading && (
{t('update.downloading')}: {Math.round(downloadProgress)}%
)}
{/* {!downloading && !updateDownloaded ? (
) : updateDownloaded ? (
) : null} */}
{updateInfo?.releaseUrl && (
)}
>
);
};
export default UpdateChecker;