diff --git a/src/App.tsx b/src/App.tsx index 4595775..2ee8808 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,11 +1,10 @@ +import { useState } from 'react' import { useAppContext } from '@/contexts/useAppContext' -import { UpdateNotifier } from '@/components/updater' import { useAppLogic } from '@/hooks' import './styles/main.scss' // Layout components -import { Header, Sidebar, InitialLoadingScreen, ErrorBoundary } from '@/components/layout' -import AnimatedBackground from '@/components/layout/AnimatedBackground' +import { Header, Sidebar, InitialLoadingScreen, ErrorBoundary, UpdateScreen, AnimatedBackground } from '@/components/layout' // Dialog components import { ProgressDialog, DlcSelectionDialog, SettingsDialog } from '@/components/dialogs' @@ -17,6 +16,7 @@ import { GameList } from '@/components/games' * Main application component */ function App() { + const [updateComplete, setUpdateComplete] = useState(false) // Get application logic from hook const { filter, @@ -29,7 +29,7 @@ function App() { handleRefresh, isLoading, error, - } = useAppLogic({ autoLoad: true }) + } = useAppLogic({ autoLoad: updateComplete }) // Get action handlers from context const { @@ -45,7 +45,12 @@ function App() { handleSettingsClose, } = useAppContext() - // Show loading screen during initial load + // Show update screen first + if (!updateComplete) { + return setUpdateComplete(true)} /> + } + + // Then show initial loading screen if (isInitialLoad) { return } @@ -114,9 +119,6 @@ function App() { visible ={settingsDialog.visible} onClose={handleSettingsClose} /> - - {/* Simple update notifier that uses toast - no UI component */} - ) diff --git a/src/components/common/index.ts b/src/components/common/index.ts index dd9a0d6..d1a2f0d 100644 --- a/src/components/common/index.ts +++ b/src/components/common/index.ts @@ -1,3 +1,4 @@ export { default as LoadingIndicator } from './LoadingIndicator' +export { default as ProgressBar } from './ProgressBar' export type { LoadingSize, LoadingType } from './LoadingIndicator' diff --git a/src/components/layout/UpdateScreen.tsx b/src/components/layout/UpdateScreen.tsx new file mode 100644 index 0000000..7cbd8b4 --- /dev/null +++ b/src/components/layout/UpdateScreen.tsx @@ -0,0 +1,94 @@ +import { useState, useEffect, useCallback } from 'react' +import { check } from '@tauri-apps/plugin-updater' +import { relaunch } from '@tauri-apps/plugin-process' +import { ProgressBar } from '@/components/common' + +interface UpdateScreenProps { + onComplete: () => void +} + +/** + * Update screen displayed before the initial loading screen + * Checks for updates and installs them automatically + */ +const UpdateScreen = ({ onComplete }: UpdateScreenProps) => { + const [checking, setChecking] = useState(true) + const [downloading, setDownloading] = useState(false) + const [progress, setProgress] = useState(0) + const [version, setVersion] = useState('') + + const checkForUpdates = useCallback(async () => { + try { + setChecking(true) + const update = await check() + + // Check if update exists (null means no update available) + if (update) { + setChecking(false) + setDownloading(true) + setVersion(update.version) + + // Download and install the update + await update.downloadAndInstall((event) => { + switch (event.event) { + case 'Started': { + const contentLength = event.data.contentLength + console.log(`Started downloading ${contentLength} bytes`) + break + } + case 'Progress': { + const { chunkLength } = event.data + // Calculate cumulative progress + setProgress((prev) => { + const newProgress = prev + chunkLength + return Math.min(newProgress, 100) + }) + break + } + case 'Finished': + console.log('Download finished, installing...') + setProgress(100) + break + } + }) + + // Relaunch the app + await relaunch() + } else { + // No update available (update is null), proceed to normal loading + setChecking(false) + onComplete() + } + } catch (error) { + console.error('Update check failed:', error) + // On error, just continue to the app + setChecking(false) + onComplete() + } + }, [onComplete]) + + useEffect(() => { + checkForUpdates() + }, [checkForUpdates]) + + return ( +
+
+

CreamLinux

+ +
+ {checking &&
} +
+ +

+ {checking && 'Checking for updates...'} + {downloading && `Downloading update v${version}...`} +

+ + {downloading && } +
+
+ ) +} + +export default UpdateScreen \ No newline at end of file diff --git a/src/components/layout/index.ts b/src/components/layout/index.ts index 33d3b23..7f3bf29 100644 --- a/src/components/layout/index.ts +++ b/src/components/layout/index.ts @@ -4,3 +4,4 @@ export { default as Sidebar } from './Sidebar' export { default as AnimatedBackground } from './AnimatedBackground' export { default as InitialLoadingScreen } from './InitialLoadingScreen' export { default as ErrorBoundary } from './ErrorBoundary' +export { default as UpdateScreen } from './UpdateScreen'