mirror of
https://github.com/Novattz/creamlinux-installer.git
synced 2026-05-16 11:12:44 -04:00
Epic games item list and game card
This commit is contained in:
@@ -0,0 +1,119 @@
|
|||||||
|
import { useState, useEffect } from 'react'
|
||||||
|
import { EpicGame } from '@/types/EpicGame'
|
||||||
|
import { ActionButton, Button } from '@/components/buttons'
|
||||||
|
import { Icon } from '@/components/icons'
|
||||||
|
|
||||||
|
interface EpicGameItemProps {
|
||||||
|
game: EpicGame
|
||||||
|
installing?: boolean
|
||||||
|
onInstall: (game: EpicGame) => void
|
||||||
|
onUninstallScream: (game: EpicGame) => void
|
||||||
|
onUninstallKoaloader: (game: EpicGame) => void
|
||||||
|
onSettings: (game: EpicGame) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
const EpicGameItem = ({
|
||||||
|
game,
|
||||||
|
installing,
|
||||||
|
onInstall,
|
||||||
|
onUninstallScream,
|
||||||
|
onUninstallKoaloader,
|
||||||
|
onSettings,
|
||||||
|
}: EpicGameItemProps) => {
|
||||||
|
const [imageUrl, setImageUrl] = useState<string | null>(null)
|
||||||
|
const [hasError, setHasError] = useState(false)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (game.box_art_url) {
|
||||||
|
setImageUrl(game.box_art_url)
|
||||||
|
}
|
||||||
|
}, [game.box_art_url])
|
||||||
|
|
||||||
|
const backgroundImage =
|
||||||
|
imageUrl && !hasError
|
||||||
|
? `url(${imageUrl})`
|
||||||
|
: 'linear-gradient(135deg, #232323, #1A1A1A)'
|
||||||
|
|
||||||
|
const anyInstalled = game.scream_installed || game.koaloader_installed
|
||||||
|
const isWorking = !!installing
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="game-item-card"
|
||||||
|
style={{
|
||||||
|
backgroundImage,
|
||||||
|
backgroundSize: 'cover',
|
||||||
|
backgroundPosition: 'center',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{imageUrl && !hasError && (
|
||||||
|
<img
|
||||||
|
src={imageUrl}
|
||||||
|
alt=""
|
||||||
|
style={{ display: 'none' }}
|
||||||
|
onError={() => setHasError(true)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div className="game-item-overlay">
|
||||||
|
<div className="game-badges">
|
||||||
|
<span className="status-badge epic">Epic</span>
|
||||||
|
{game.scream_installed && <span className="status-badge smoke">ScreamAPI</span>}
|
||||||
|
{game.koaloader_installed && <span className="status-badge smoke">Koaloader</span>}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="game-title">
|
||||||
|
<h3>{game.title}</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="game-actions">
|
||||||
|
{/* Nothing installed - install button */}
|
||||||
|
{!anyInstalled && (
|
||||||
|
<ActionButton
|
||||||
|
action="install_unlocker"
|
||||||
|
isInstalled={false}
|
||||||
|
isWorking={isWorking}
|
||||||
|
onClick={() => { if (!isWorking) onInstall(game) }}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* ScreamAPI installed - uninstall + settings */}
|
||||||
|
{game.scream_installed && (
|
||||||
|
<ActionButton
|
||||||
|
action="uninstall_smoke"
|
||||||
|
isInstalled={true}
|
||||||
|
isWorking={isWorking}
|
||||||
|
onClick={() => { if (!isWorking) onUninstallScream(game) }}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Koaloader installed - uninstall */}
|
||||||
|
{game.koaloader_installed && (
|
||||||
|
<ActionButton
|
||||||
|
action="uninstall_smoke"
|
||||||
|
isInstalled={true}
|
||||||
|
isWorking={isWorking}
|
||||||
|
onClick={() => { if (!isWorking) onUninstallKoaloader(game) }}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Settings button - only for direct ScreamAPI (not Koaloader) */}
|
||||||
|
{game.scream_installed && !game.koaloader_installed && (
|
||||||
|
<Button
|
||||||
|
variant="secondary"
|
||||||
|
size="small"
|
||||||
|
onClick={() => onSettings(game)}
|
||||||
|
disabled={isWorking}
|
||||||
|
title="Configure ScreamAPI"
|
||||||
|
className="edit-button settings-icon-button"
|
||||||
|
leftIcon={<Icon name="Settings" variant="solid" size="md" />}
|
||||||
|
iconOnly
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default EpicGameItem
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
import { useMemo } from 'react'
|
||||||
|
import EpicGameItem from '@/components/games/EpicGameItem'
|
||||||
|
import { EpicGame } from '@/types/EpicGame'
|
||||||
|
import LoadingIndicator from '../common/LoadingIndicator'
|
||||||
|
|
||||||
|
interface EpicGameListProps {
|
||||||
|
games: EpicGame[]
|
||||||
|
isLoading: boolean
|
||||||
|
installingId: string | null
|
||||||
|
onInstall: (game: EpicGame) => void
|
||||||
|
onUninstallScream: (game: EpicGame) => void
|
||||||
|
onUninstallKoaloader: (game: EpicGame) => void
|
||||||
|
onSettings: (game: EpicGame) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
const EpicGameList = ({
|
||||||
|
games,
|
||||||
|
isLoading,
|
||||||
|
installingId,
|
||||||
|
onInstall,
|
||||||
|
onUninstallScream,
|
||||||
|
onUninstallKoaloader,
|
||||||
|
onSettings,
|
||||||
|
}: EpicGameListProps) => {
|
||||||
|
const sortedGames = useMemo(
|
||||||
|
() => [...games].sort((a, b) => a.title.localeCompare(b.title)),
|
||||||
|
[games]
|
||||||
|
)
|
||||||
|
|
||||||
|
if (isLoading) {
|
||||||
|
return (
|
||||||
|
<div className="game-list">
|
||||||
|
<LoadingIndicator type="spinner" size="large" message="Scanning for Epic games..." />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="game-list">
|
||||||
|
<h2>Epic Games ({games.length})</h2>
|
||||||
|
|
||||||
|
{games.length === 0 ? (
|
||||||
|
<div className="no-games-message">
|
||||||
|
No Epic games found. Make sure Heroic is installed and has games downloaded.
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="game-grid">
|
||||||
|
{sortedGames.map((game) => (
|
||||||
|
<EpicGameItem
|
||||||
|
key={game.app_name}
|
||||||
|
game={game}
|
||||||
|
installing={installingId === game.app_name}
|
||||||
|
onInstall={onInstall}
|
||||||
|
onUninstallScream={onUninstallScream}
|
||||||
|
onUninstallKoaloader={onUninstallKoaloader}
|
||||||
|
onSettings={onSettings}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default EpicGameList
|
||||||
Reference in New Issue
Block a user