2025-10-01 15:40:10 -05:00
|
|
|
import React, { useState, useEffect } from "react";
|
|
|
|
|
import { Button } from "@/components/ui/button.tsx";
|
|
|
|
|
import { VersionAlert } from "@/components/ui/version-alert.tsx";
|
|
|
|
|
import { useTranslation } from "react-i18next";
|
|
|
|
|
import { checkElectronUpdate, isElectron } from "@/ui/main-axios.ts";
|
|
|
|
|
|
|
|
|
|
interface VersionCheckModalProps {
|
|
|
|
|
onContinue: () => void;
|
|
|
|
|
isAuthenticated?: boolean;
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-05 10:36:16 -06:00
|
|
|
export function ElectronVersionCheck({
|
2025-10-01 15:40:10 -05:00
|
|
|
onContinue,
|
|
|
|
|
isAuthenticated = false,
|
|
|
|
|
}: VersionCheckModalProps) {
|
|
|
|
|
const { t } = useTranslation();
|
2025-11-05 10:36:16 -06:00
|
|
|
const [versionInfo, setVersionInfo] = useState<Record<
|
|
|
|
|
string,
|
|
|
|
|
unknown
|
|
|
|
|
> | null>(null);
|
2025-10-01 15:40:10 -05:00
|
|
|
const [versionChecking, setVersionChecking] = useState(false);
|
2025-11-05 10:36:16 -06:00
|
|
|
const [versionDismissed] = useState(false);
|
2025-10-01 15:40:10 -05:00
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (isElectron()) {
|
|
|
|
|
checkForUpdates();
|
|
|
|
|
} else {
|
|
|
|
|
onContinue();
|
|
|
|
|
}
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
const checkForUpdates = async () => {
|
|
|
|
|
setVersionChecking(true);
|
|
|
|
|
try {
|
|
|
|
|
const updateInfo = await checkElectronUpdate();
|
|
|
|
|
setVersionInfo(updateInfo);
|
|
|
|
|
|
2025-11-05 10:36:16 -06:00
|
|
|
const currentVersion = await (window as any).electronAPI?.getAppVersion();
|
|
|
|
|
const dismissedVersion = localStorage.getItem(
|
|
|
|
|
"electron-version-check-dismissed",
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (dismissedVersion === currentVersion) {
|
|
|
|
|
onContinue();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-01 15:40:10 -05:00
|
|
|
if (updateInfo?.status === "up_to_date") {
|
2025-11-05 10:36:16 -06:00
|
|
|
if (currentVersion) {
|
|
|
|
|
localStorage.setItem(
|
|
|
|
|
"electron-version-check-dismissed",
|
|
|
|
|
currentVersion,
|
|
|
|
|
);
|
|
|
|
|
}
|
2025-10-01 15:40:10 -05:00
|
|
|
onContinue();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Failed to check for updates:", error);
|
|
|
|
|
setVersionInfo({ success: false, error: "Check failed" });
|
|
|
|
|
} finally {
|
|
|
|
|
setVersionChecking(false);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleDownloadUpdate = () => {
|
|
|
|
|
if (versionInfo?.latest_release?.html_url) {
|
|
|
|
|
window.open(versionInfo.latest_release.html_url, "_blank");
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2025-11-05 10:36:16 -06:00
|
|
|
const handleContinue = async () => {
|
|
|
|
|
const currentVersion = await (window as any).electronAPI?.getAppVersion();
|
|
|
|
|
if (currentVersion) {
|
|
|
|
|
localStorage.setItem("electron-version-check-dismissed", currentVersion);
|
|
|
|
|
}
|
2025-10-01 15:40:10 -05:00
|
|
|
onContinue();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (!isElectron()) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (versionChecking && !versionInfo) {
|
|
|
|
|
return (
|
|
|
|
|
<div className="fixed inset-0 flex items-center justify-center z-50">
|
|
|
|
|
<div className="bg-dark-bg border-2 border-dark-border rounded-lg p-6 max-w-md w-full mx-4 relative z-10">
|
|
|
|
|
<div className="flex items-center justify-center mb-4">
|
|
|
|
|
<div className="w-8 h-8 border-2 border-primary border-t-transparent rounded-full animate-spin" />
|
|
|
|
|
</div>
|
|
|
|
|
<p className="text-center text-muted-foreground">
|
|
|
|
|
{t("versionCheck.checkingUpdates")}
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!versionInfo || versionDismissed) {
|
|
|
|
|
return (
|
|
|
|
|
<div className="fixed inset-0 flex items-center justify-center z-50">
|
|
|
|
|
<div className="bg-dark-bg border-2 border-dark-border rounded-lg p-6 max-w-md w-full mx-4 relative z-10">
|
|
|
|
|
<div className="mb-4">
|
|
|
|
|
<h2 className="text-lg font-semibold">
|
|
|
|
|
{t("versionCheck.checkUpdates")}
|
|
|
|
|
</h2>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{versionInfo && !versionDismissed && (
|
|
|
|
|
<div className="mb-4">
|
|
|
|
|
<VersionAlert
|
|
|
|
|
updateInfo={versionInfo}
|
|
|
|
|
onDownload={handleDownloadUpdate}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
<div className="flex gap-2">
|
|
|
|
|
<Button onClick={handleContinue} className="flex-1 h-10">
|
|
|
|
|
{t("common.continue")}
|
|
|
|
|
</Button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div className="fixed inset-0 flex items-center justify-center z-50">
|
|
|
|
|
<div className="bg-dark-bg border-2 border-dark-border rounded-lg p-6 max-w-md w-full mx-4 relative z-10">
|
|
|
|
|
<div className="mb-4">
|
|
|
|
|
<h2 className="text-lg font-semibold">
|
|
|
|
|
{t("versionCheck.updateRequired")}
|
|
|
|
|
</h2>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className="mb-4">
|
|
|
|
|
<VersionAlert
|
|
|
|
|
updateInfo={versionInfo}
|
|
|
|
|
onDownload={handleDownloadUpdate}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className="flex gap-2">
|
|
|
|
|
<Button onClick={handleContinue} className="flex-1 h-10">
|
|
|
|
|
{t("common.continue")}
|
|
|
|
|
</Button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|