From 03cae08df14f7bdc03feb23e2d5e30c42b2fe957 Mon Sep 17 00:00:00 2001 From: Novattz Date: Sat, 17 Jan 2026 17:56:46 +0100 Subject: [PATCH] implement unlocker selection #61 --- src/App.tsx | 14 ++++++++++++ src/components/games/GameItem.tsx | 38 +++++++++++++++++++++++++++---- src/contexts/AppContext.tsx | 10 ++++++++ src/contexts/AppProvider.tsx | 10 ++++++++ 4 files changed, 67 insertions(+), 5 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 6abfe13..2e03e69 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -21,6 +21,7 @@ import { SettingsDialog, ConflictDialog, DisclaimerDialog, + UnlockerSelectionDialog, } from '@/components/dialogs' // Game components @@ -64,6 +65,10 @@ function App() { handleSettingsClose, handleSmokeAPISettingsOpen, showToast, + unlockerSelectionDialog, + handleSelectCreamLinux, + handleSelectSmokeAPI, + closeUnlockerDialog, } = useAppContext() // Conflict detection @@ -182,6 +187,15 @@ function App() { onClose={closeDialog} /> + {/* Unlocker Selection Dialog */} + + {/* Disclaimer Dialog - Shows AFTER everything is loaded */} diff --git a/src/components/games/GameItem.tsx b/src/components/games/GameItem.tsx index 0cbd647..8e552f9 100644 --- a/src/components/games/GameItem.tsx +++ b/src/components/games/GameItem.tsx @@ -51,11 +51,14 @@ const GameItem = ({ game, onAction, onEdit, onSmokeAPISettings }: GameItemProps) }, [game.id, imageUrl]) // Determine if we should show CreamLinux buttons (only for native games) - const shouldShowCream = game.native === true + const shouldShowCream = game.native && game.cream_installed // Only show if installed (for uninstall) // Determine if we should show SmokeAPI buttons (only for non-native games with API files) const shouldShowSmoke = !game.native && game.api_files && game.api_files.length > 0 + // Show generic button if nothing installed + const shouldShowUnlocker = game.native && !game.cream_installed && !game.smoke_installed + // Check if this is a Proton game without API files const isProtonNoApi = !game.native && (!game.api_files || game.api_files.length === 0) @@ -71,6 +74,11 @@ const GameItem = ({ game, onAction, onEdit, onSmokeAPISettings }: GameItemProps) onAction(game.id, action) } + const handleUnlockerAction = () => { + if (game.installing) return + onAction(game.id, 'install_unlocker') + } + // Handle edit button click const handleEdit = () => { if (onEdit && game.cream_installed) { @@ -116,17 +124,27 @@ const GameItem = ({ game, onAction, onEdit, onSmokeAPISettings }: GameItemProps)
- {/* Show CreamLinux button only for native games */} + {/* Show generic "Install" button for native games with nothing installed */} + {shouldShowUnlocker && ( + + )} + + {/* Show CreamLinux uninstall button if CreamLinux is installed */} {shouldShowCream && ( )} - {/* Show SmokeAPI button only for Proton/Windows games with API files */} + {/* Show SmokeAPI button for Proton games OR native games with SmokeAPI installed */} {shouldShowSmoke && ( )} + {/* Show SmokeAPI uninstall for native games if installed */} + {game.native && game.smoke_installed && ( + + )} + {/* Show message for Proton games without API files */} {isProtonNoApi && (
diff --git a/src/contexts/AppContext.tsx b/src/contexts/AppContext.tsx index 10b0f0f..911150b 100644 --- a/src/contexts/AppContext.tsx +++ b/src/contexts/AppContext.tsx @@ -62,6 +62,16 @@ export interface AppContextType { type: 'success' | 'error' | 'warning' | 'info', options?: Record ) => void + + // Unlocker selection + unlockerSelectionDialog: { + visible: boolean + gameId: string | null + gameTitle: string | null + } + handleSelectCreamLinux: () => void + handleSelectSmokeAPI: () => void + closeUnlockerDialog: () => void } // Create the context with a default value diff --git a/src/contexts/AppProvider.tsx b/src/contexts/AppProvider.tsx index 12e1e4f..8302206 100644 --- a/src/contexts/AppProvider.tsx +++ b/src/contexts/AppProvider.tsx @@ -33,6 +33,10 @@ export const AppProvider = ({ children }: AppProviderProps) => { handleCloseProgressDialog, handleGameAction: executeGameAction, handleDlcConfirm: executeDlcConfirm, + unlockerSelectionDialog, + handleSelectCreamLinux, + handleSelectSmokeAPI, + closeUnlockerDialog, } = useGameActions() const { toasts, removeToast, success, error: showError, warning, info } = useToasts() @@ -241,6 +245,12 @@ export const AppProvider = ({ children }: AppProviderProps) => { // Toast notifications showToast, + + // Unlocker selection + unlockerSelectionDialog, + handleSelectCreamLinux, + handleSelectSmokeAPI, + closeUnlockerDialog, } return (