Formatting

This commit is contained in:
Tickbase
2025-05-18 18:23:06 +02:00
parent bbbd7482c1
commit 81519e89b7
61 changed files with 714 additions and 775 deletions

View File

@@ -4,54 +4,58 @@ import { ActionType } from '@/components/buttons/ActionButton'
// Types for context sub-components
export interface InstallationInstructions {
type: string;
command: string;
game_title: string;
dlc_count?: number;
type: string
command: string
game_title: string
dlc_count?: number
}
export interface DlcDialogState {
visible: boolean;
gameId: string;
gameTitle: string;
dlcs: DlcInfo[];
isLoading: boolean;
isEditMode: boolean;
progress: number;
timeLeft?: string;
visible: boolean
gameId: string
gameTitle: string
dlcs: DlcInfo[]
isLoading: boolean
isEditMode: boolean
progress: number
timeLeft?: string
}
export interface ProgressDialogState {
visible: boolean;
title: string;
message: string;
progress: number;
showInstructions: boolean;
instructions?: InstallationInstructions;
visible: boolean
title: string
message: string
progress: number
showInstructions: boolean
instructions?: InstallationInstructions
}
// Define the context type
export interface AppContextType {
// Game state
games: Game[];
isLoading: boolean;
error: string | null;
loadGames: () => Promise<boolean>;
handleProgressDialogClose: () => void;
games: Game[]
isLoading: boolean
error: string | null
loadGames: () => Promise<boolean>
handleProgressDialogClose: () => void
// DLC management
dlcDialog: DlcDialogState;
handleGameEdit: (gameId: string) => void;
handleDlcDialogClose: () => void;
dlcDialog: DlcDialogState
handleGameEdit: (gameId: string) => void
handleDlcDialogClose: () => void
// Game actions
progressDialog: ProgressDialogState;
handleGameAction: (gameId: string, action: ActionType) => Promise<void>;
handleDlcConfirm: (selectedDlcs: DlcInfo[]) => void;
progressDialog: ProgressDialogState
handleGameAction: (gameId: string, action: ActionType) => Promise<void>
handleDlcConfirm: (selectedDlcs: DlcInfo[]) => void
// Toast notifications
showToast: (message: string, type: 'success' | 'error' | 'warning' | 'info', options?: Record<string, unknown>) => void;
showToast: (
message: string,
type: 'success' | 'error' | 'warning' | 'info',
options?: Record<string, unknown>
) => void
}
// Create the context with a default value
export const AppContext = createContext<AppContextType | undefined>(undefined);
export const AppContext = createContext<AppContextType | undefined>(undefined)

View File

@@ -7,7 +7,7 @@ import { ToastContainer } from '@/components/notifications'
// Context provider component
interface AppProviderProps {
children: ReactNode;
children: ReactNode
}
/**
@@ -16,13 +16,7 @@ interface AppProviderProps {
*/
export const AppProvider = ({ children }: AppProviderProps) => {
// Use our custom hooks
const {
games,
isLoading,
error,
loadGames,
setGames,
} = useGames()
const { games, isLoading, error, loadGames, setGames } = useGames()
const {
dlcDialog,
@@ -38,24 +32,17 @@ export const AppProvider = ({ children }: AppProviderProps) => {
handleGameAction: executeGameAction,
handleDlcConfirm: executeDlcConfirm,
} = useGameActions()
const {
toasts,
removeToast,
success,
error: showError,
warning,
info
} = useToasts()
const { toasts, removeToast, success, error: showError, warning, info } = useToasts()
// Game action handler with proper error reporting
const handleGameAction = async (gameId: string, action: ActionType) => {
const game = games.find(g => g.id === gameId)
const game = games.find((g) => g.id === gameId)
if (!game) {
showError("Game not found")
showError('Game not found')
return
}
// For DLC installation, we want to show the DLC selection dialog first
if (action === 'install_cream') {
try {
@@ -70,7 +57,7 @@ export const AppProvider = ({ children }: AppProviderProps) => {
isEditMode: false, // This is a new installation
progress: 0,
})
// Start streaming DLCs
streamGameDlcs(gameId)
return
@@ -79,76 +66,96 @@ export const AppProvider = ({ children }: AppProviderProps) => {
return
}
}
// For other actions (uninstall cream, install/uninstall smoke)
// Mark game as installing
setGames(prevGames =>
prevGames.map(g => g.id === gameId ? {...g, installing: true} : g)
setGames((prevGames) =>
prevGames.map((g) => (g.id === gameId ? { ...g, installing: true } : g))
)
try {
await executeGameAction(gameId, action, games)
// Show success message
if (action.includes('install')) {
success(`Successfully installed ${action.includes('cream') ? 'CreamLinux' : 'SmokeAPI'} for ${game.title}`)
success(
`Successfully installed ${action.includes('cream') ? 'CreamLinux' : 'SmokeAPI'} for ${game.title}`
)
} else {
success(`Successfully uninstalled ${action.includes('cream') ? 'CreamLinux' : 'SmokeAPI'} from ${game.title}`)
success(
`Successfully uninstalled ${action.includes('cream') ? 'CreamLinux' : 'SmokeAPI'} from ${game.title}`
)
}
} catch (error) {
showError(`Action failed: ${error}`)
} finally {
// Reset installing state
setGames(prevGames =>
prevGames.map(g => g.id === gameId ? {...g, installing: false} : g)
setGames((prevGames) =>
prevGames.map((g) => (g.id === gameId ? { ...g, installing: false } : g))
)
}
}
// DLC confirmation wrapper
const handleDlcConfirm = (selectedDlcs: DlcInfo[]) => {
const { gameId, isEditMode } = dlcDialog
// MODIFIED: Create a deep copy to ensure we don't have reference issues
const dlcsCopy = selectedDlcs.map(dlc => ({...dlc}))
const dlcsCopy = selectedDlcs.map((dlc) => ({ ...dlc }))
// Log detailed info before closing dialog
console.log(`Saving ${dlcsCopy.filter(d => d.enabled).length} enabled and ${
dlcsCopy.length - dlcsCopy.filter(d => d.enabled).length
} disabled DLCs`)
console.log(
`Saving ${dlcsCopy.filter((d) => d.enabled).length} enabled and ${
dlcsCopy.length - dlcsCopy.filter((d) => d.enabled).length
} disabled DLCs`
)
// Close dialog FIRST to avoid UI state issues
closeDlcDialog()
// Update game state to show it's installing
setGames(prevGames =>
prevGames.map(g => g.id === gameId ? { ...g, installing: true } : g)
setGames((prevGames) =>
prevGames.map((g) => (g.id === gameId ? { ...g, installing: true } : g))
)
executeDlcConfirm(dlcsCopy, gameId, isEditMode, games)
.then(() => {
success(isEditMode
? "DLC configuration updated successfully"
: "CreamLinux installed with selected DLCs")
success(
isEditMode
? 'DLC configuration updated successfully'
: 'CreamLinux installed with selected DLCs'
)
})
.catch(error => {
.catch((error) => {
showError(`DLC operation failed: ${error}`)
})
.finally(() => {
// Reset installing state
setGames(prevGames =>
prevGames.map(g => g.id === gameId ? { ...g, installing: false } : g)
setGames((prevGames) =>
prevGames.map((g) => (g.id === gameId ? { ...g, installing: false } : g))
)
})
}
// Generic toast show function
const showToast = (message: string, type: 'success' | 'error' | 'warning' | 'info', options = {}) => {
const showToast = (
message: string,
type: 'success' | 'error' | 'warning' | 'info',
options = {}
) => {
switch (type) {
case 'success': success(message, options); break;
case 'error': showError(message, options); break;
case 'warning': warning(message, options); break;
case 'info': info(message, options); break;
case 'success':
success(message, options)
break
case 'error':
showError(message, options)
break
case 'warning':
warning(message, options)
break
case 'info':
info(message, options)
break
}
}
@@ -159,20 +166,20 @@ export const AppProvider = ({ children }: AppProviderProps) => {
isLoading,
error,
loadGames,
// DLC management
dlcDialog,
handleGameEdit: (gameId: string) => {
handleGameEdit(gameId, games)
},
handleDlcDialogClose: closeDlcDialog,
// Game actions
progressDialog,
handleGameAction,
handleDlcConfirm,
handleProgressDialogClose: handleCloseProgressDialog,
// Toast notifications
showToast,
}
@@ -183,4 +190,4 @@ export const AppProvider = ({ children }: AppProviderProps) => {
<ToastContainer toasts={toasts} onDismiss={removeToast} />
</AppContext.Provider>
)
}
}

View File

@@ -1,3 +1,3 @@
export * from './AppContext';
export * from './AppProvider';
export * from './useAppContext';
export * from './AppContext'
export * from './AppProvider'
export * from './useAppContext'

View File

@@ -7,10 +7,10 @@ import { AppContext, AppContextType } from './AppContext'
*/
export const useAppContext = (): AppContextType => {
const context = useContext(AppContext)
if (context === undefined) {
throw new Error('useAppContext must be used within an AppProvider')
}
return context
}
}