mirror of
https://github.com/hydralauncher/hydra.git
synced 2026-01-26 12:21:03 +00:00
quick add to library button
This commit is contained in:
@@ -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%;
|
||||
|
||||
@@ -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) {
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={"game-item__plus-wrapper" + (added ? " added" : "")}
|
||||
onClick={addGameToLibrary}
|
||||
title={added ? t("already_in_library") : t("add_to_library")}
|
||||
>
|
||||
{added ? <CheckIcon size={16} /> : <PlusIcon size={16} />}
|
||||
</div>
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user