mirror of
https://github.com/Novattz/creamlinux-installer.git
synced 2026-05-02 04:52:03 -04:00
hook up #93
This commit is contained in:
35
src/App.tsx
35
src/App.tsx
@@ -25,7 +25,7 @@ import {
|
|||||||
} from '@/components/dialogs'
|
} from '@/components/dialogs'
|
||||||
|
|
||||||
// Game components
|
// Game components
|
||||||
import { GameList } from '@/components/games'
|
import { GameList, EpicGameList } from '@/components/games'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main application component
|
* Main application component
|
||||||
@@ -71,11 +71,25 @@ function App() {
|
|||||||
handleSelectCreamLinux,
|
handleSelectCreamLinux,
|
||||||
handleSelectSmokeAPI,
|
handleSelectSmokeAPI,
|
||||||
closeUnlockerDialog,
|
closeUnlockerDialog,
|
||||||
|
epicGames,
|
||||||
|
epicLoading,
|
||||||
|
epicInstallingId,
|
||||||
|
loadEpicGames,
|
||||||
|
handleEpicInstall,
|
||||||
|
handleEpicUninstallScream,
|
||||||
|
handleEpicUninstallKoaloader,
|
||||||
|
handleEpicSettings,
|
||||||
} = useAppContext()
|
} = useAppContext()
|
||||||
|
|
||||||
// Conflict detection
|
// Conflict detection
|
||||||
const { conflicts, showDialog, resolveConflict, closeDialog } =
|
const { conflicts, showDialog, resolveConflict, closeDialog } = useConflictDetection(games)
|
||||||
useConflictDetection(games)
|
|
||||||
|
const handleSetFilter = async (f: string) => {
|
||||||
|
setFilter(f)
|
||||||
|
if (f === 'epic' && epicGames.length === 0 && !epicLoading) {
|
||||||
|
await loadEpicGames()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Handle conflict resolution
|
// Handle conflict resolution
|
||||||
const handleConflictResolve = async (
|
const handleConflictResolve = async (
|
||||||
@@ -126,13 +140,22 @@ function App() {
|
|||||||
<div className="main-content">
|
<div className="main-content">
|
||||||
{/* Sidebar for filtering */}
|
{/* Sidebar for filtering */}
|
||||||
<Sidebar
|
<Sidebar
|
||||||
setFilter={setFilter}
|
setFilter={handleSetFilter}
|
||||||
currentFilter={filter}
|
currentFilter={filter}
|
||||||
onSettingsClick={handleSettingsOpen}
|
onSettingsClick={handleSettingsOpen}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* Show error or game list */}
|
{filter === 'epic' ? (
|
||||||
{error ? (
|
<EpicGameList
|
||||||
|
games={epicGames}
|
||||||
|
isLoading={epicLoading}
|
||||||
|
installingId={epicInstallingId}
|
||||||
|
onInstall={handleEpicInstall}
|
||||||
|
onUninstallScream={handleEpicUninstallScream}
|
||||||
|
onUninstallKoaloader={handleEpicUninstallKoaloader}
|
||||||
|
onSettings={handleEpicSettings}
|
||||||
|
/>
|
||||||
|
) : error ? (
|
||||||
<div className="error-message">
|
<div className="error-message">
|
||||||
<h3>Error Loading Games</h3>
|
<h3>Error Loading Games</h3>
|
||||||
<p>{error}</p>
|
<p>{error}</p>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { createContext } from 'react'
|
import { createContext } from 'react'
|
||||||
import { Game, DlcInfo } from '@/types'
|
import { Game, DlcInfo, EpicGame } from '@/types'
|
||||||
import { ActionType } from '@/components/buttons/ActionButton'
|
import { ActionType } from '@/components/buttons/ActionButton'
|
||||||
import { DlcDialogState } from '@/hooks/useDlcManager'
|
import { DlcDialogState } from '@/hooks/useDlcManager'
|
||||||
|
|
||||||
@@ -49,6 +49,16 @@ export interface AppContextType {
|
|||||||
handleDlcDialogClose: () => void
|
handleDlcDialogClose: () => void
|
||||||
handleUpdateDlcs: (gameId: string) => Promise<void>
|
handleUpdateDlcs: (gameId: string) => Promise<void>
|
||||||
|
|
||||||
|
// Epic Games
|
||||||
|
epicGames: EpicGame[]
|
||||||
|
epicLoading: boolean
|
||||||
|
epicInstallingId: string | null
|
||||||
|
loadEpicGames: () => Promise<void>
|
||||||
|
handleEpicInstall: (game: EpicGame) => void
|
||||||
|
handleEpicUninstallScream: (game: EpicGame) => void
|
||||||
|
handleEpicUninstallKoaloader: (game: EpicGame) => void
|
||||||
|
handleEpicSettings: (game: EpicGame) => void
|
||||||
|
|
||||||
// Game actions
|
// Game actions
|
||||||
progressDialog: ProgressDialogState
|
progressDialog: ProgressDialogState
|
||||||
handleGameAction: (gameId: string, action: ActionType) => Promise<void>
|
handleGameAction: (gameId: string, action: ActionType) => Promise<void>
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
import { ReactNode, useState, useEffect } from 'react'
|
import { ReactNode, useState, useEffect } from 'react'
|
||||||
import { AppContext, AppContextType } from './AppContext'
|
import { AppContext, AppContextType } from './AppContext'
|
||||||
import { useGames, useDlcManager, useGameActions, useToasts } from '@/hooks'
|
import { useGames, useDlcManager, useGameActions, useToasts } from '@/hooks'
|
||||||
import { DlcInfo, Config } from '@/types'
|
import { DlcInfo, Config, EpicGame } from '@/types'
|
||||||
import { ActionType } from '@/components/buttons/ActionButton'
|
import { ActionType } from '@/components/buttons/ActionButton'
|
||||||
import { ToastContainer } from '@/components/notifications'
|
import { ToastContainer } from '@/components/notifications'
|
||||||
import { SmokeAPISettingsDialog, OptInDialog, RatingDialog, SmokeAPIVotesDialog } from '@/components/dialogs'
|
import { SmokeAPISettingsDialog, OptInDialog, RatingDialog, SmokeAPIVotesDialog, EpicUnlockerSelectionDialog, ScreamAPISettingsDialog } from '@/components/dialogs'
|
||||||
import { invoke } from '@tauri-apps/api/core'
|
import { invoke } from '@tauri-apps/api/core'
|
||||||
|
import { listen } from '@tauri-apps/api/event'
|
||||||
|
|
||||||
// Context provider component
|
// Context provider component
|
||||||
interface AppProviderProps {
|
interface AppProviderProps {
|
||||||
@@ -43,6 +44,20 @@ export const AppProvider = ({ children }: AppProviderProps) => {
|
|||||||
// Settings dialog state
|
// Settings dialog state
|
||||||
const [settingsDialog, setSettingsDialog] = useState({ visible: false })
|
const [settingsDialog, setSettingsDialog] = useState({ visible: false })
|
||||||
|
|
||||||
|
const [epicGames, setEpicGames] = useState<EpicGame[]>([])
|
||||||
|
const [epicLoading, setEpicLoading] = useState(false)
|
||||||
|
const [epicInstallingId, setEpicInstallingId] = useState<string | null>(null)
|
||||||
|
|
||||||
|
const [epicUnlockerDialog, setEpicUnlockerDialog] = useState<{
|
||||||
|
visible: boolean
|
||||||
|
game: EpicGame | null
|
||||||
|
}>({ visible: false, game: null })
|
||||||
|
|
||||||
|
const [screamSettingsDialog, setScreamSettingsDialog] = useState<{
|
||||||
|
visible: boolean
|
||||||
|
game: EpicGame | null
|
||||||
|
}>({ visible: false, game: null })
|
||||||
|
|
||||||
// SmokeAPI settings dialog state
|
// SmokeAPI settings dialog state
|
||||||
const [smokeAPISettingsDialog, setSmokeAPISettingsDialog] = useState<{
|
const [smokeAPISettingsDialog, setSmokeAPISettingsDialog] = useState<{
|
||||||
visible: boolean
|
visible: boolean
|
||||||
@@ -95,6 +110,91 @@ export const AppProvider = ({ children }: AppProviderProps) => {
|
|||||||
.catch((err) => console.error('Failed to load config for reporting check:', err))
|
.catch((err) => console.error('Failed to load config for reporting check:', err))
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let unlisten: (() => void) | undefined
|
||||||
|
listen<EpicGame>('epic-game-updated', (event) => {
|
||||||
|
const updated = event.payload
|
||||||
|
const prev = epicGames.find((g) => g.app_name === updated.app_name)
|
||||||
|
|
||||||
|
setEpicGames((games) =>
|
||||||
|
games.map((g) => (g.app_name === updated.app_name ? updated : g))
|
||||||
|
)
|
||||||
|
setEpicInstallingId(null)
|
||||||
|
|
||||||
|
// Determine what changed and show appropriate toast
|
||||||
|
if (prev) {
|
||||||
|
const installedScream = !prev.scream_installed && updated.scream_installed
|
||||||
|
const uninstalledScream = prev.scream_installed && !updated.scream_installed
|
||||||
|
const installedKoa = !prev.koaloader_installed && updated.koaloader_installed
|
||||||
|
const uninstalledKoa = prev.koaloader_installed && !updated.koaloader_installed
|
||||||
|
|
||||||
|
if (installedScream) {
|
||||||
|
success(`ScreamAPI installed for ${updated.title}`)
|
||||||
|
} else if (uninstalledScream) {
|
||||||
|
info(`ScreamAPI removed from ${updated.title}`)
|
||||||
|
} else if (installedKoa) {
|
||||||
|
success(`Koaloader installed for ${updated.title}`)
|
||||||
|
} else if (uninstalledKoa) {
|
||||||
|
info(`Koaloader removed from ${updated.title}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updated.proxy_fallback_used) {
|
||||||
|
warning(
|
||||||
|
'No compatible proxy import found - installed using version.dll as a fallback. ' +
|
||||||
|
'If the game has issues, try the direct ScreamAPI method instead.'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).then((fn) => { unlisten = fn })
|
||||||
|
return () => { unlisten?.() }
|
||||||
|
}, [epicGames, success, info, warning])
|
||||||
|
|
||||||
|
const loadEpicGames = async () => {
|
||||||
|
setEpicLoading(true)
|
||||||
|
try {
|
||||||
|
const games = await invoke<EpicGame[]>('scan_epic_games')
|
||||||
|
setEpicGames(games)
|
||||||
|
} catch (e) {
|
||||||
|
showError(`Failed to scan Epic games: ${e}`)
|
||||||
|
} finally {
|
||||||
|
setEpicLoading(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const runEpicAction = async (game: EpicGame, action: string) => {
|
||||||
|
setEpicInstallingId(game.app_name)
|
||||||
|
try {
|
||||||
|
await invoke('process_epic_action', { epicAction: { game, action } })
|
||||||
|
// state updated via epic-game-updated event listener
|
||||||
|
} catch (e) {
|
||||||
|
showError(`Action failed: ${e}`)
|
||||||
|
setEpicInstallingId(null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleEpicInstall = (game: EpicGame) => {
|
||||||
|
setEpicUnlockerDialog({ visible: true, game })
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleEpicUninstallScream = (game: EpicGame) => runEpicAction(game, 'uninstall_scream')
|
||||||
|
const handleEpicUninstallKoaloader = (game: EpicGame) => runEpicAction(game, 'uninstall_koaloader')
|
||||||
|
|
||||||
|
const handleEpicSettings = (game: EpicGame) => {
|
||||||
|
setScreamSettingsDialog({ visible: true, game })
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSelectScreamAPI = () => {
|
||||||
|
const game = epicUnlockerDialog.game
|
||||||
|
setEpicUnlockerDialog({ visible: false, game: null })
|
||||||
|
if (game) runEpicAction(game, 'install_scream')
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSelectKoaloader = () => {
|
||||||
|
const game = epicUnlockerDialog.game
|
||||||
|
setEpicUnlockerDialog({ visible: false, game: null })
|
||||||
|
if (game) runEpicAction(game, 'install_koaloader')
|
||||||
|
}
|
||||||
|
|
||||||
// Settings handlers
|
// Settings handlers
|
||||||
const handleSettingsOpen = () => {
|
const handleSettingsOpen = () => {
|
||||||
setSettingsDialog({ visible: true })
|
setSettingsDialog({ visible: true })
|
||||||
@@ -366,6 +466,16 @@ export const AppProvider = ({ children }: AppProviderProps) => {
|
|||||||
handleDlcDialogClose: closeDlcDialog,
|
handleDlcDialogClose: closeDlcDialog,
|
||||||
handleUpdateDlcs: (gameId: string) => handleUpdateDlcs(gameId),
|
handleUpdateDlcs: (gameId: string) => handleUpdateDlcs(gameId),
|
||||||
|
|
||||||
|
// Epic games
|
||||||
|
epicGames,
|
||||||
|
epicLoading,
|
||||||
|
epicInstallingId,
|
||||||
|
loadEpicGames,
|
||||||
|
handleEpicInstall,
|
||||||
|
handleEpicUninstallScream,
|
||||||
|
handleEpicUninstallKoaloader,
|
||||||
|
handleEpicSettings,
|
||||||
|
|
||||||
// Game actions
|
// Game actions
|
||||||
progressDialog,
|
progressDialog,
|
||||||
handleGameAction,
|
handleGameAction,
|
||||||
@@ -458,6 +568,23 @@ export const AppProvider = ({ children }: AppProviderProps) => {
|
|||||||
gameTitle={smokeAPISettingsDialog.gameTitle}
|
gameTitle={smokeAPISettingsDialog.gameTitle}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{/* Epic Unlocker Selection Dialog */}
|
||||||
|
<EpicUnlockerSelectionDialog
|
||||||
|
visible={epicUnlockerDialog.visible}
|
||||||
|
game={epicUnlockerDialog.game}
|
||||||
|
onClose={() => setEpicUnlockerDialog({ visible: false, game: null })}
|
||||||
|
onSelectScreamAPI={handleSelectScreamAPI}
|
||||||
|
onSelectKoaloader={handleSelectKoaloader}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* ScreamAPI Settings Dialog */}
|
||||||
|
<ScreamAPISettingsDialog
|
||||||
|
visible={screamSettingsDialog.visible}
|
||||||
|
onClose={() => setScreamSettingsDialog({ visible: false, game: null })}
|
||||||
|
gamePath={screamSettingsDialog.game?.install_path ?? ''}
|
||||||
|
gameTitle={screamSettingsDialog.game?.title ?? ''}
|
||||||
|
/>
|
||||||
|
|
||||||
{/* SmokeAPI Votes Dialog */}
|
{/* SmokeAPI Votes Dialog */}
|
||||||
<SmokeAPIVotesDialog
|
<SmokeAPIVotesDialog
|
||||||
visible={smokeAPIVotesDialog.visible}
|
visible={smokeAPIVotesDialog.visible}
|
||||||
|
|||||||
Reference in New Issue
Block a user