import { Modal } from "../Modal"; import { Icon } from "../Icon"; import { GameCover } from "../grid/GameCover"; import { StateChip } from "../StateChip"; import { ActionButton } from "../ActionButton"; import { Game, InstallStatus } from "../../lib/types"; import { canStreamInstall, gameStatusLabel, gameTransferStatusPresentation, hasNewerLocalVersion, isInProgress, } from "../../lib/gameState"; import { formatBytes, formatEtiVersion, formatPlayers } from "../../lib/format"; interface Props { game: Game; thumbnailUrl: string | null; supportsStreamedInstall: boolean; onClose: () => void; onPrimary: (game: Game) => void; onStreamInstall: (game: Game) => void; onUninstall: (game: Game) => void; onRemoveDownload: (game: Game) => void; onCancelDownload: (game: Game) => void; onStartServer: (game: Game) => void; onViewFiles: (game: Game) => void; } const tagsFromGame = (game: Game): string[] => { const tags: string[] = []; if (game.genre) tags.push(game.genre); if (game.publisher) tags.push(game.publisher); if (game.release_year) tags.push(game.release_year); return tags; }; export const GameDetailModal = ({ game, thumbnailUrl, supportsStreamedInstall, onClose, onPrimary, onStreamInstall, onUninstall, onRemoveDownload, onCancelDownload, onStartServer, onViewFiles, }: Props) => { const tags = tagsFromGame(game); // Some game metadata contains a literal ; keep sanitization exact. const description = game.description.split("").join(""); const canRemoveDownload = game.downloaded && !game.installed && !isInProgress(game.install_status); const showStreamInstall = canStreamInstall(game, supportsStreamedInstall); const canViewFiles = game.downloaded || game.installed || game.install_status === InstallStatus.Downloading || game.install_status === InstallStatus.Installing; const newerThanExpected = hasNewerLocalVersion(game); const newerStatus = newerThanExpected ? `Local version ${ formatEtiVersion(game.local_version) } is newer than expected ${formatEtiVersion(game.eti_game_version)}.` : undefined; const hasOutbound = game.active_outbound_transfers !== undefined && game.active_outbound_transfers > 0; const outboundStatus = hasOutbound ? `Sharing to ${game.active_outbound_transfers} peer${ game.active_outbound_transfers === 1 ? "" : "s" }.` : undefined; const transferStatus = gameTransferStatusPresentation(game.transfer_status); const statusMessage = transferStatus?.message ?? outboundStatus ?? game.status_message ?? newerStatus; const statusLevel = transferStatus?.level ?? (hasOutbound ? "info" : (game.status_level ?? (newerStatus ? "warning" : undefined))); return ( {tags.length > 0 && ( {tags.map((t) => {t})} )} {game.name} Size {formatBytes(game.size)} Players {formatPlayers(game.max_players)} Version {formatEtiVersion(game.eti_game_version ?? game.local_version)} Status {gameStatusLabel(game)} {description && {description}} {statusMessage && ( {statusMessage} )} onPrimary(game)} onCancelDownload={onCancelDownload} /> {showStreamInstall && ( onStreamInstall(game)} > Low disk install )} {game.installed && game.can_host_server === true && ( onStartServer(game)} > Start Server )} {game.installed && ( onUninstall(game)} > Uninstall )} {canRemoveDownload && ( onRemoveDownload(game)} > Remove files )} {canViewFiles && ( <> onViewFiles(game)} > View Files > )} ); };
{description}
{statusMessage}