From 14a83366953ad995aaeac4cb753771557b6d2628 Mon Sep 17 00:00:00 2001 From: Victor Sales <36749678+v1ctorsales@users.noreply.github.com> Date: Sat, 31 May 2025 01:01:46 -0300 Subject: [PATCH] quick add to library button --- .../src/pages/catalogue/game-item.scss | 23 ++++++++ .../src/pages/catalogue/game-item.tsx | 53 +++++++++++++++++-- 2 files changed, 71 insertions(+), 5 deletions(-) diff --git a/src/renderer/src/pages/catalogue/game-item.scss b/src/renderer/src/pages/catalogue/game-item.scss index f49bcbf8..b1e66178 100644 --- a/src/renderer/src/pages/catalogue/game-item.scss +++ b/src/renderer/src/pages/catalogue/game-item.scss @@ -18,6 +18,29 @@ background-color: rgba(255, 255, 255, 0.05); } + &__plus-wrapper { + position: absolute; + top: 8px; + right: 8px; + opacity: 0; + pointer-events: none; + transition: opacity 0.2s ease-in-out; + cursor: pointer; + } + + &:hover .game-item__plus-wrapper { + opacity: 1; + pointer-events: auto; + } + + &__plus-wrapper.added { + opacity: 0.5; + } + + &:hover .game-item__plus-wrapper.added { + opacity: 0.5; + } + &__cover { width: 200px; height: 100%; diff --git a/src/renderer/src/pages/catalogue/game-item.tsx b/src/renderer/src/pages/catalogue/game-item.tsx index 69915f20..28d9dc9f 100644 --- a/src/renderer/src/pages/catalogue/game-item.tsx +++ b/src/renderer/src/pages/catalogue/game-item.tsx @@ -1,13 +1,13 @@ import { Badge } from "@renderer/components"; import { buildGameDetailsPath } from "@renderer/helpers"; -import { useAppSelector, useRepacks } from "@renderer/hooks"; -import { useMemo } from "react"; +import { useAppSelector, useRepacks, useLibrary } from "@renderer/hooks"; +import { useMemo, useState, useEffect } from "react"; import { useNavigate } from "react-router-dom"; import "./game-item.scss"; import { useTranslation } from "react-i18next"; import { CatalogueSearchResult } from "@types"; -import { QuestionIcon } from "@primer/octicons-react"; +import { QuestionIcon, PlusIcon, CheckIcon } from "@primer/octicons-react"; export interface GameItemProps { game: CatalogueSearchResult; @@ -16,7 +16,9 @@ export interface GameItemProps { export function GameItem({ game }: GameItemProps) { const navigate = useNavigate(); - const { i18n } = useTranslation(); + const { i18n, t } = useTranslation("game_details"); + + const language = i18n.language.split("-")[0]; const { steamGenres } = useAppSelector((state) => state.catalogueSearch); @@ -24,7 +26,41 @@ export function GameItem({ game }: GameItemProps) { const repacks = getRepacksForObjectId(game.objectId); - const language = i18n.language.split("-")[0]; + const [plusDisabled, setPlusDisabled] = useState(false); + + const [added, setAdded] = useState(false); + + const { library, updateLibrary } = useLibrary(); + + useEffect(() => { + const exists = library.some( + (libItem) => + libItem.shop === game.shop && libItem.objectId === game.objectId + ); + if (exists) { + setAdded(true); + } + }, [library, game.shop, game.objectId]); + + const addGameToLibrary = async (event: React.MouseEvent) => { + event.stopPropagation(); + if (added) return; + setPlusDisabled(true); + + try { + await window.electron.addGameToLibrary( + game.shop, + game.objectId, + game.title + ); + updateLibrary(); + setAdded(true); + } catch (error) { + console.error(error); + } finally { + setPlusDisabled(false); + } + }; const uniqueRepackers = useMemo(() => { return Array.from(new Set(repacks.map((repack) => repack.repacker))); @@ -81,6 +117,13 @@ export function GameItem({ game }: GameItemProps) { ))} +