From 2811ba4e29cd27b5893fba676278f29b155068cb Mon Sep 17 00:00:00 2001 From: xXJSONDeruloXx Date: Wed, 16 Jul 2025 17:11:00 -0400 Subject: non modal updater --- src/components/PluginUpdateChecker.tsx | 187 +++++++++++++++++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100644 src/components/PluginUpdateChecker.tsx (limited to 'src/components/PluginUpdateChecker.tsx') diff --git a/src/components/PluginUpdateChecker.tsx b/src/components/PluginUpdateChecker.tsx new file mode 100644 index 0000000..0028a79 --- /dev/null +++ b/src/components/PluginUpdateChecker.tsx @@ -0,0 +1,187 @@ +import React, { useState, useEffect } from 'react'; +import { + ButtonItem, + PanelSection +} from '@decky/ui'; +import { checkForPluginUpdate, downloadPluginUpdate, UpdateCheckResult, UpdateDownloadResult } from '../api/lsfgApi'; + +interface PluginUpdateCheckerProps { + // Add any props if needed +} + +interface UpdateInfo { + updateAvailable: boolean; + currentVersion: string; + latestVersion: string; + releaseNotes: string; + releaseDate: string; + downloadUrl: string; +} + +export const PluginUpdateChecker: React.FC = () => { + const [checkingUpdate, setCheckingUpdate] = useState(false); + const [downloadingUpdate, setDownloadingUpdate] = useState(false); + const [updateInfo, setUpdateInfo] = useState(null); + const [updateError, setUpdateError] = useState(null); + const [downloadResult, setDownloadResult] = useState(null); + + // Auto-hide error messages after 5 seconds + useEffect(() => { + if (updateError) { + const timer = setTimeout(() => { + setUpdateError(null); + }, 5000); + return () => clearTimeout(timer); + } + return undefined; + }, [updateError]); + + const handleCheckForUpdate = async () => { + setCheckingUpdate(true); + setUpdateError(null); + setUpdateInfo(null); + setDownloadResult(null); // Clear previous download result + + try { + const result: UpdateCheckResult = await checkForPluginUpdate(); + + if (result.success) { + setUpdateInfo({ + updateAvailable: result.update_available, + currentVersion: result.current_version, + latestVersion: result.latest_version, + releaseNotes: result.release_notes, + releaseDate: result.release_date, + downloadUrl: result.download_url + }); + + // Simple console log instead of toast since showToast may not be available + if (result.update_available) { + console.log("Update available!", `Version ${result.latest_version} is now available.`); + } else { + console.log("Up to date!", "You have the latest version installed."); + } + } else { + setUpdateError(result.error || "Failed to check for updates"); + } + } catch (error) { + setUpdateError(`Error checking for updates: ${error}`); + } finally { + setCheckingUpdate(false); + } + }; + + const handleDownloadUpdate = async () => { + if (!updateInfo?.downloadUrl) return; + + setDownloadingUpdate(true); + setUpdateError(null); + setDownloadResult(null); + + try { + const result: UpdateDownloadResult = await downloadPluginUpdate(updateInfo.downloadUrl); + + if (result.success) { + setDownloadResult(result); + console.log("✓ Download complete!", `Plugin downloaded to ${result.download_path}`); + } else { + setUpdateError(result.error || "Failed to download update"); + } + } catch (error) { + setUpdateError(`Error downloading update: ${error}`); + } finally { + setDownloadingUpdate(false); + } + }; + + const getStatusMessage = () => { + if (!updateInfo) return null; + + if (updateInfo.updateAvailable) { + if (downloadResult?.success) { + return ( +
+ ✓ v{updateInfo.latestVersion} downloaded - ready to install +
+ ); + } else { + return ( +
+ Update available: v{updateInfo.latestVersion} +
+ ); + } + } else { + return ( +
+ Up to date (v{updateInfo.currentVersion}) +
+ ); + } + }; + + return ( + + + {checkingUpdate ? 'Checking for updates...' : 'Check for Updates'} + + + {updateInfo && updateInfo.updateAvailable && !downloadResult?.success && ( + + {downloadingUpdate ? 'Downloading...' : 'Download Update'} + + )} + + {downloadResult?.success && ( +
+
+ ✓ Download Complete! +
+
+ File saved to: {downloadResult.download_path} +
+
+ Installation Instructions: +
    +
  1. Go to Decky Loader settings
  2. +
  3. Click "Developer" tab
  4. +
  5. Click "Uninstall" next to "Lossless Scaling"
  6. +
  7. Click "Install from ZIP"
  8. +
  9. Select the downloaded file
  10. +
  11. Restart Steam or reload plugins
  12. +
+
+
+ )} + + {updateError && ( +
+ {updateError} +
+ )} +
+ ); +}; -- cgit v1.2.3