mirror of
https://github.com/hydralauncher/hydra.git
synced 2025-02-12 11:12:07 +00:00
Merge pull request #1447 from leandroperin/feat-favorites
feat: favorites
This commit is contained in:
commit
110131f1d6
35 changed files with 251 additions and 60 deletions
|
@ -14,8 +14,10 @@
|
|||
"paused": "{{title}} (Спынена)",
|
||||
"downloading": "{{title}} ({{percentage}} - Сцягванне…)",
|
||||
"filter": "Фільтар бібліятэкі",
|
||||
"home": "Галоўная"
|
||||
"home": "Галоўная",
|
||||
"favorites": "Улюбленыя"
|
||||
},
|
||||
|
||||
"header": {
|
||||
"search": "Пошук",
|
||||
"home": "Галоўная",
|
||||
|
|
|
@ -26,7 +26,8 @@
|
|||
"game_has_no_executable": "Играта няма избран изпълним файл",
|
||||
"sign_in": "Вписване",
|
||||
"friends": "Приятели",
|
||||
"need_help": "Имате нужда от помощ??"
|
||||
"need_help": "Имате нужда от помощ??",
|
||||
"favorites": "Любими игри"
|
||||
},
|
||||
"header": {
|
||||
"search": "Търсене",
|
||||
|
|
|
@ -20,10 +20,12 @@
|
|||
"home": "Inici",
|
||||
"queued": "{{title}} (En espera)",
|
||||
"game_has_no_executable": "El joc encara no té un executable seleccionat",
|
||||
"sign_in": "Entra"
|
||||
"sign_in": "Entra",
|
||||
"favorites": "Favorits"
|
||||
},
|
||||
"header": {
|
||||
"search": "Cerca jocs",
|
||||
|
||||
"home": "Inici",
|
||||
"catalogue": "Catàleg",
|
||||
"downloads": "Baixades",
|
||||
|
|
|
@ -26,7 +26,8 @@
|
|||
"game_has_no_executable": "Hra nemá zvolen žádný spustitelný soubor",
|
||||
"sign_in": "Přihlásit se",
|
||||
"friends": "Přátelé",
|
||||
"need_help": "Potřebujete pomoc?"
|
||||
"need_help": "Potřebujete pomoc?",
|
||||
"favorites": "Oblíbené"
|
||||
},
|
||||
"header": {
|
||||
"search": "Vyhledat hry",
|
||||
|
|
|
@ -24,10 +24,12 @@
|
|||
"queued": "{{title}} (I køen)",
|
||||
"game_has_no_executable": "Spillet har ikke nogen eksekverbar fil valgt",
|
||||
"sign_in": "Log ind",
|
||||
"friends": "Venner"
|
||||
"friends": "Venner",
|
||||
"favorites": "Favoritter"
|
||||
},
|
||||
"header": {
|
||||
"search": "Søg efter spil",
|
||||
|
||||
"home": "Hjem",
|
||||
"catalogue": "Katalog",
|
||||
"downloads": "Downloads",
|
||||
|
|
|
@ -20,10 +20,12 @@
|
|||
"home": "Home",
|
||||
"queued": "{{title}} (In Warteschlange)",
|
||||
"game_has_no_executable": "Spiel hat keine ausführbare Datei gewählt",
|
||||
"sign_in": "Anmelden"
|
||||
"sign_in": "Anmelden",
|
||||
"favorites": "Favoriten"
|
||||
},
|
||||
"header": {
|
||||
"search": "Spiele suchen",
|
||||
|
||||
"home": "Home",
|
||||
"catalogue": "Katalog",
|
||||
"downloads": "Downloads",
|
||||
|
|
|
@ -26,7 +26,8 @@
|
|||
"game_has_no_executable": "Game has no executable selected",
|
||||
"sign_in": "Sign in",
|
||||
"friends": "Friends",
|
||||
"need_help": "Need help?"
|
||||
"need_help": "Need help?",
|
||||
"favorites": "Favorites"
|
||||
},
|
||||
"header": {
|
||||
"search": "Search games",
|
||||
|
@ -190,6 +191,7 @@
|
|||
"download_error_not_cached_in_real_debrid": "This download is not available on Real-Debrid and polling download status from Real-Debrid is not yet available.",
|
||||
"download_error_not_cached_in_torbox": "This download is not available on Torbox and polling download status from Torbox is not yet available."
|
||||
},
|
||||
|
||||
"activation": {
|
||||
"title": "Activate Hydra",
|
||||
"installation_id": "Installation ID:",
|
||||
|
|
|
@ -26,7 +26,8 @@
|
|||
"game_has_no_executable": "El juego no tiene un ejecutable seleccionado",
|
||||
"sign_in": "Iniciar sesión",
|
||||
"friends": "Amigos",
|
||||
"need_help": "¿Necesitas ayuda?"
|
||||
"need_help": "¿Necesitas ayuda?",
|
||||
"favorites": "Favoritos"
|
||||
},
|
||||
"header": {
|
||||
"search": "Buscar juegos",
|
||||
|
|
|
@ -25,7 +25,8 @@
|
|||
"queued": "{{title}} (Järjekorras)",
|
||||
"game_has_no_executable": "Mängul pole käivitusfaili valitud",
|
||||
"sign_in": "Logi sisse",
|
||||
"friends": "Sõbrad"
|
||||
"friends": "Sõbrad",
|
||||
"favorites": "Lemmikud"
|
||||
},
|
||||
"header": {
|
||||
"search": "Otsi mänge",
|
||||
|
|
|
@ -14,8 +14,10 @@
|
|||
"paused": "{{title}} (متوقف شده)",
|
||||
"downloading": "{{title}} ({{percentage}} - در حال دانلود…)",
|
||||
"filter": "فیلتر کردن کتابخانه",
|
||||
"home": "خانه"
|
||||
"home": "خانه",
|
||||
"favorites": "علاقهمندیها"
|
||||
},
|
||||
|
||||
"header": {
|
||||
"search": "جستجوی بازیها",
|
||||
"home": "خانه",
|
||||
|
|
|
@ -14,10 +14,12 @@
|
|||
"paused": "{{title}} (En pause)",
|
||||
"downloading": "{{title}} ({{percentage}} - Téléchargement en cours…)",
|
||||
"filter": "Filtrer la bibliothèque",
|
||||
"home": "Page d’accueil"
|
||||
"home": "Page d’accueil",
|
||||
"favorites": "Favoris"
|
||||
},
|
||||
"header": {
|
||||
"search": "Recherche",
|
||||
|
||||
"catalogue": "Catalogue",
|
||||
"downloads": "Téléchargements",
|
||||
"search_results": "Résultats de la recherche",
|
||||
|
|
|
@ -14,10 +14,12 @@
|
|||
"paused": "{{title}} (Szünet)",
|
||||
"downloading": "{{title}} ({{percentage}} - Letöltés…)",
|
||||
"filter": "Könyvtár szűrése",
|
||||
"home": "Főoldal"
|
||||
"home": "Főoldal",
|
||||
"favorites": "Kedvenc játékok"
|
||||
},
|
||||
"header": {
|
||||
"search": "Keresés",
|
||||
|
||||
"home": "Főoldal",
|
||||
"catalogue": "Katalógus",
|
||||
"downloads": "Letöltések",
|
||||
|
|
|
@ -20,10 +20,12 @@
|
|||
"home": "Beranda",
|
||||
"queued": "{{title}} (Antrian)",
|
||||
"game_has_no_executable": "Game tidak punya file eksekusi yang dipilih",
|
||||
"sign_in": "Masuk"
|
||||
"sign_in": "Masuk",
|
||||
"favorites": "Favorit"
|
||||
},
|
||||
"header": {
|
||||
"search": "Cari game",
|
||||
|
||||
"home": "Beranda",
|
||||
"catalogue": "Katalog",
|
||||
"downloads": "Unduhan",
|
||||
|
|
|
@ -14,10 +14,12 @@
|
|||
"paused": "{{title}} (In pausa)",
|
||||
"downloading": "{{title}} ({{percentage}} - Download…)",
|
||||
"filter": "Filtra libreria",
|
||||
"home": "Home"
|
||||
"home": "Home",
|
||||
"favorites": "Preferiti"
|
||||
},
|
||||
"header": {
|
||||
"search": "Cerca",
|
||||
|
||||
"home": "Home",
|
||||
"catalogue": "Catalogo",
|
||||
"downloads": "Download",
|
||||
|
|
|
@ -20,8 +20,10 @@
|
|||
"home": "Басты бет",
|
||||
"queued": "{{title}} (Кезекте)",
|
||||
"game_has_no_executable": "Ойынды іске қосу файлы таңдалмаған",
|
||||
"sign_in": "Кіру"
|
||||
"sign_in": "Кіру",
|
||||
"favorites": "Таңдаулылар"
|
||||
},
|
||||
|
||||
"header": {
|
||||
"search": "Іздеу",
|
||||
"home": "Басты бет",
|
||||
|
|
|
@ -14,8 +14,10 @@
|
|||
"paused": "{{title}} (일시 정지됨)",
|
||||
"downloading": "{{title}} ({{percentage}} - 다운로드 중…)",
|
||||
"filter": "라이브러리 정렬",
|
||||
"home": "홈"
|
||||
"home": "홈",
|
||||
"favorites": "즐겨찾기"
|
||||
},
|
||||
|
||||
"header": {
|
||||
"search": "게임 검색하기",
|
||||
"home": "홈",
|
||||
|
|
|
@ -24,10 +24,12 @@
|
|||
"queued": "{{title}} (I køen)",
|
||||
"game_has_no_executable": "Spillet har ikke noen kjørbar fil valgt",
|
||||
"sign_in": "Logge inn",
|
||||
"friends": "Venner"
|
||||
"friends": "Venner",
|
||||
"favorites": "Favoritter"
|
||||
},
|
||||
"header": {
|
||||
"search": "Søk efter spill",
|
||||
|
||||
"home": "Hjem",
|
||||
"catalogue": "Katalog",
|
||||
"downloads": "Nedlastinger",
|
||||
|
|
|
@ -14,10 +14,12 @@
|
|||
"paused": "{{title}} (Gepauzeerd)",
|
||||
"downloading": "{{title}} ({{percentage}} - Downloading…)",
|
||||
"filter": "Filter Bibliotheek",
|
||||
"home": "Home"
|
||||
"home": "Home",
|
||||
"favorites": "Favorieten"
|
||||
},
|
||||
"header": {
|
||||
"search": "Zoek spellen",
|
||||
|
||||
"home": "Home",
|
||||
"catalogue": "Bibliotheek",
|
||||
"downloads": "Downloads",
|
||||
|
|
|
@ -14,10 +14,12 @@
|
|||
"paused": "{{title}} (Zatrzymano)",
|
||||
"downloading": "{{title}} ({{percentage}} - Pobieranie…)",
|
||||
"filter": "Filtruj biblioteke",
|
||||
"home": "Główna"
|
||||
"home": "Główna",
|
||||
"favorites": "Ulubione"
|
||||
},
|
||||
"header": {
|
||||
"search": "Szukaj",
|
||||
|
||||
"home": "Główna",
|
||||
"catalogue": "Katalog",
|
||||
"downloads": "Pobrane",
|
||||
|
|
|
@ -26,10 +26,12 @@
|
|||
"game_has_no_executable": "Jogo não possui executável selecionado",
|
||||
"sign_in": "Login",
|
||||
"friends": "Amigos",
|
||||
"need_help": "Precisa de ajuda?"
|
||||
"need_help": "Precisa de ajuda?",
|
||||
"favorites": "Favoritos"
|
||||
},
|
||||
"header": {
|
||||
"search": "Buscar jogos",
|
||||
|
||||
"catalogue": "Catálogo",
|
||||
"downloads": "Downloads",
|
||||
"search_results": "Resultados da busca",
|
||||
|
@ -179,6 +181,7 @@
|
|||
"download_error_not_cached_in_real_debrid": "Este download não está disponível no Real-Debrid e a verificação do status do download não está disponível.",
|
||||
"download_error_not_cached_in_torbox": "Este download não está disponível no Torbox e a verificação do status do download não está disponível."
|
||||
},
|
||||
|
||||
"activation": {
|
||||
"title": "Ativação",
|
||||
"installation_id": "ID da instalação:",
|
||||
|
|
|
@ -25,10 +25,12 @@
|
|||
"queued": "{{title}} (Na fila)",
|
||||
"game_has_no_executable": "O jogo não tem um executável selecionado",
|
||||
"sign_in": "Iniciar sessão",
|
||||
"friends": "Amigos"
|
||||
"friends": "Amigos",
|
||||
"favorites": "Favoritos"
|
||||
},
|
||||
"header": {
|
||||
"search": "Procurar jogos",
|
||||
|
||||
"catalogue": "Catálogo",
|
||||
"downloads": "Transferências",
|
||||
"search_results": "Resultados da pesquisa",
|
||||
|
|
|
@ -14,10 +14,12 @@
|
|||
"paused": "{{title}} (Pauzat)",
|
||||
"downloading": "{{title}} ({{percentage}} - Se descarcă...)",
|
||||
"filter": "Filtrează biblioteca",
|
||||
"home": "Acasă"
|
||||
"home": "Acasă",
|
||||
"favorites": "Favorite"
|
||||
},
|
||||
"header": {
|
||||
"search": "Caută jocuri",
|
||||
|
||||
"home": "Acasă",
|
||||
"catalogue": "Catalog",
|
||||
"downloads": "Descărcări",
|
||||
|
|
|
@ -26,7 +26,8 @@
|
|||
"game_has_no_executable": "Файл запуска игры не выбран",
|
||||
"sign_in": "Войти",
|
||||
"friends": "Друзья",
|
||||
"need_help": "Нужна помощь?"
|
||||
"need_help": "Нужна помощь?",
|
||||
"favorites": "Избранное"
|
||||
},
|
||||
"header": {
|
||||
"search": "Поиск",
|
||||
|
|
|
@ -26,7 +26,8 @@
|
|||
"game_has_no_executable": "Oyun için bir çalıştırılabilir dosya seçilmedi",
|
||||
"sign_in": "Giriş yap",
|
||||
"friends": "Arkadaşlar",
|
||||
"need_help": "Yardıma mı ihtiyacınız var?"
|
||||
"need_help": "Yardıma mı ihtiyacınız var?",
|
||||
"favorites": "Favoriler"
|
||||
},
|
||||
"header": {
|
||||
"search": "Oyunları ara",
|
||||
|
|
|
@ -20,10 +20,12 @@
|
|||
"home": "Головна",
|
||||
"game_has_no_executable": "Не було вибрано файл для запуску гри",
|
||||
"queued": "{{title}} в черзі",
|
||||
"sign_in": "Увійти"
|
||||
"sign_in": "Увійти",
|
||||
"favorites": "Улюблені"
|
||||
},
|
||||
"header": {
|
||||
"search": "Пошук",
|
||||
|
||||
"home": "Головна",
|
||||
"catalogue": "Каталог",
|
||||
"downloads": "Завантаження",
|
||||
|
|
|
@ -25,7 +25,8 @@
|
|||
"queued": "{{title}} (已加入下载队列)",
|
||||
"game_has_no_executable": "未选择游戏的可执行文件",
|
||||
"sign_in": "登入",
|
||||
"friends": "好友"
|
||||
"friends": "好友",
|
||||
"favorites": "收藏"
|
||||
},
|
||||
"header": {
|
||||
"search": "搜索游戏",
|
||||
|
|
|
@ -13,6 +13,8 @@ import "./catalogue/get-developers";
|
|||
import "./hardware/get-disk-free-space";
|
||||
import "./hardware/check-folder-write-permission";
|
||||
import "./library/add-game-to-library";
|
||||
import "./library/add-game-to-favorites";
|
||||
import "./library/remove-game-from-favorites";
|
||||
import "./library/create-game-shortcut";
|
||||
import "./library/close-game";
|
||||
import "./library/delete-game-folder";
|
||||
|
|
25
src/main/events/library/add-game-to-favorites.ts
Normal file
25
src/main/events/library/add-game-to-favorites.ts
Normal file
|
@ -0,0 +1,25 @@
|
|||
import { registerEvent } from "../register-event";
|
||||
import { gamesSublevel, levelKeys } from "@main/level";
|
||||
import type { GameShop } from "@types";
|
||||
|
||||
const addGameToFavorites = async (
|
||||
_event: Electron.IpcMainInvokeEvent,
|
||||
shop: GameShop,
|
||||
objectId: string
|
||||
) => {
|
||||
const gameKey = levelKeys.game(shop, objectId);
|
||||
|
||||
const game = await gamesSublevel.get(gameKey);
|
||||
if (!game) return;
|
||||
|
||||
try {
|
||||
await gamesSublevel.put(gameKey, {
|
||||
...game,
|
||||
favorite: true,
|
||||
});
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to update game favorite status: ${error}`);
|
||||
}
|
||||
};
|
||||
|
||||
registerEvent("addGameToFavorites", addGameToFavorites);
|
25
src/main/events/library/remove-game-from-favorites.ts
Normal file
25
src/main/events/library/remove-game-from-favorites.ts
Normal file
|
@ -0,0 +1,25 @@
|
|||
import { registerEvent } from "../register-event";
|
||||
import { gamesSublevel, levelKeys } from "@main/level";
|
||||
import type { GameShop } from "@types";
|
||||
|
||||
const removeGameFromFavorites = async (
|
||||
_event: Electron.IpcMainInvokeEvent,
|
||||
shop: GameShop,
|
||||
objectId: string
|
||||
) => {
|
||||
const gameKey = levelKeys.game(shop, objectId);
|
||||
|
||||
const game = await gamesSublevel.get(gameKey);
|
||||
if (!game) return;
|
||||
|
||||
try {
|
||||
await gamesSublevel.put(gameKey, {
|
||||
...game,
|
||||
favorite: false,
|
||||
});
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to update game favorite status: ${error}`);
|
||||
}
|
||||
};
|
||||
|
||||
registerEvent("removeGameFromFavorites", removeGameFromFavorites);
|
|
@ -110,11 +110,16 @@ contextBridge.exposeInMainWorld("electron", {
|
|||
executablePath: string | null
|
||||
) =>
|
||||
ipcRenderer.invoke("updateExecutablePath", shop, objectId, executablePath),
|
||||
addGameToFavorites: (shop: GameShop, objectId: string) =>
|
||||
ipcRenderer.invoke("addGameToFavorites", shop, objectId),
|
||||
removeGameFromFavorites: (shop: GameShop, objectId: string) =>
|
||||
ipcRenderer.invoke("removeGameFromFavorites", shop, objectId),
|
||||
updateLaunchOptions: (
|
||||
shop: GameShop,
|
||||
objectId: string,
|
||||
launchOptions: string | null
|
||||
) => ipcRenderer.invoke("updateLaunchOptions", shop, objectId, launchOptions),
|
||||
|
||||
selectGameWinePrefix: (
|
||||
shop: GameShop,
|
||||
objectId: string,
|
||||
|
|
50
src/renderer/src/components/sidebar/sidebar-game-item.tsx
Normal file
50
src/renderer/src/components/sidebar/sidebar-game-item.tsx
Normal file
|
@ -0,0 +1,50 @@
|
|||
import SteamLogo from "@renderer/assets/steam-logo.svg?react";
|
||||
import { LibraryGame } from "@types";
|
||||
import cn from "classnames";
|
||||
import { useLocation } from "react-router-dom";
|
||||
|
||||
interface SidebarGameItemProps {
|
||||
game: LibraryGame;
|
||||
handleSidebarGameClick: (event: React.MouseEvent, game: LibraryGame) => void;
|
||||
getGameTitle: (game: LibraryGame) => string;
|
||||
}
|
||||
|
||||
export function SidebarGameItem({
|
||||
game,
|
||||
handleSidebarGameClick,
|
||||
getGameTitle,
|
||||
}: Readonly<SidebarGameItemProps>) {
|
||||
const location = useLocation();
|
||||
|
||||
return (
|
||||
<li
|
||||
key={game.id}
|
||||
className={cn("sidebar__menu-item", {
|
||||
"sidebar__menu-item--active":
|
||||
location.pathname === `/game/${game.shop}/${game.objectId}`,
|
||||
"sidebar__menu-item--muted": game.download?.status === "removed",
|
||||
})}
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
className="sidebar__menu-item-button"
|
||||
onClick={(event) => handleSidebarGameClick(event, game)}
|
||||
>
|
||||
{game.iconUrl ? (
|
||||
<img
|
||||
className="sidebar__game-icon"
|
||||
src={game.iconUrl}
|
||||
alt={game.title}
|
||||
loading="lazy"
|
||||
/>
|
||||
) : (
|
||||
<SteamLogo className="sidebar__game-icon" />
|
||||
)}
|
||||
|
||||
<span className="sidebar__menu-item-button-label">
|
||||
{getGameTitle(game)}
|
||||
</span>
|
||||
</button>
|
||||
</li>
|
||||
);
|
||||
}
|
|
@ -18,11 +18,11 @@ import "./sidebar.scss";
|
|||
|
||||
import { buildGameDetailsPath } from "@renderer/helpers";
|
||||
|
||||
import SteamLogo from "@renderer/assets/steam-logo.svg?react";
|
||||
import { SidebarProfile } from "./sidebar-profile";
|
||||
import { sortBy } from "lodash-es";
|
||||
import cn from "classnames";
|
||||
import { CommentDiscussionIcon } from "@primer/octicons-react";
|
||||
import { SidebarGameItem } from "./sidebar-game-item";
|
||||
|
||||
const SIDEBAR_MIN_WIDTH = 200;
|
||||
const SIDEBAR_INITIAL_WIDTH = 250;
|
||||
|
@ -206,6 +206,23 @@ export function Sidebar() {
|
|||
</ul>
|
||||
</section>
|
||||
|
||||
<section className="sidebar__section">
|
||||
<small className="sidebar__section-title">{t("favorites")}</small>
|
||||
|
||||
<ul className="sidebar__menu">
|
||||
{sortedLibrary
|
||||
.filter((game) => game.favorite)
|
||||
.map((game) => (
|
||||
<SidebarGameItem
|
||||
key={game.id}
|
||||
game={game}
|
||||
handleSidebarGameClick={handleSidebarGameClick}
|
||||
getGameTitle={getGameTitle}
|
||||
/>
|
||||
))}
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section className="sidebar__section">
|
||||
<small className="sidebar__section-title">{t("my_library")}</small>
|
||||
|
||||
|
@ -217,39 +234,16 @@ export function Sidebar() {
|
|||
/>
|
||||
|
||||
<ul className="sidebar__menu">
|
||||
{filteredLibrary.map((game) => (
|
||||
<li
|
||||
key={game.id}
|
||||
className={cn("sidebar__menu-item", {
|
||||
"sidebar__menu-item--active":
|
||||
location.pathname ===
|
||||
`/game/${game.shop}/${game.objectId}`,
|
||||
"sidebar__menu-item--muted":
|
||||
game.download?.status === "removed",
|
||||
})}
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
className="sidebar__menu-item-button"
|
||||
onClick={(event) => handleSidebarGameClick(event, game)}
|
||||
>
|
||||
{game.iconUrl ? (
|
||||
<img
|
||||
className="sidebar__game-icon"
|
||||
src={game.iconUrl}
|
||||
alt={game.title}
|
||||
loading="lazy"
|
||||
/>
|
||||
) : (
|
||||
<SteamLogo className="sidebar__game-icon" />
|
||||
)}
|
||||
|
||||
<span className="sidebar__menu-item-button-label">
|
||||
{getGameTitle(game)}
|
||||
</span>
|
||||
</button>
|
||||
</li>
|
||||
))}
|
||||
{filteredLibrary
|
||||
.filter((game) => !game.favorite)
|
||||
.map((game) => (
|
||||
<SidebarGameItem
|
||||
key={game.id}
|
||||
game={game}
|
||||
handleSidebarGameClick={handleSidebarGameClick}
|
||||
getGameTitle={getGameTitle}
|
||||
/>
|
||||
))}
|
||||
</ul>
|
||||
</section>
|
||||
</div>
|
||||
|
|
5
src/renderer/src/declaration.d.ts
vendored
5
src/renderer/src/declaration.d.ts
vendored
|
@ -96,6 +96,11 @@ declare global {
|
|||
objectId: string,
|
||||
executablePath: string | null
|
||||
) => Promise<void>;
|
||||
addGameToFavorites: (shop: GameShop, objectId: string) => Promise<void>;
|
||||
removeGameFromFavorites: (
|
||||
shop: GameShop,
|
||||
objectId: string
|
||||
) => Promise<void>;
|
||||
updateLaunchOptions: (
|
||||
shop: GameShop,
|
||||
objectId: string,
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import {
|
||||
DownloadIcon,
|
||||
GearIcon,
|
||||
HeartFillIcon,
|
||||
HeartIcon,
|
||||
PlayIcon,
|
||||
PlusCircleIcon,
|
||||
} from "@primer/octicons-react";
|
||||
|
@ -52,6 +54,32 @@ export function HeroPanelActions() {
|
|||
}
|
||||
};
|
||||
|
||||
const addGameToFavorites = async () => {
|
||||
setToggleLibraryGameDisabled(true);
|
||||
|
||||
try {
|
||||
if (!objectId) throw new Error("objectId is required");
|
||||
await window.electron.addGameToFavorites(shop, objectId);
|
||||
updateLibrary();
|
||||
updateGame();
|
||||
} finally {
|
||||
setToggleLibraryGameDisabled(false);
|
||||
}
|
||||
};
|
||||
|
||||
const removeGameFromFavorites = async () => {
|
||||
setToggleLibraryGameDisabled(true);
|
||||
|
||||
try {
|
||||
if (!objectId) throw new Error("objectId is required");
|
||||
await window.electron.removeGameFromFavorites(shop, objectId);
|
||||
updateLibrary();
|
||||
updateGame();
|
||||
} finally {
|
||||
setToggleLibraryGameDisabled(false);
|
||||
}
|
||||
};
|
||||
|
||||
const openGame = async () => {
|
||||
if (game) {
|
||||
if (game.executablePath) {
|
||||
|
@ -159,6 +187,16 @@ export function HeroPanelActions() {
|
|||
<div className="hero-panel-actions__container">
|
||||
{gameActionButton()}
|
||||
<div className="hero-panel-actions__separator" />
|
||||
<Button
|
||||
onClick={game.favorite ? removeGameFromFavorites : addGameToFavorites}
|
||||
theme="outline"
|
||||
disabled={deleting}
|
||||
className="hero-panel-actions__action"
|
||||
>
|
||||
{game.favorite ? <HeartFillIcon /> : <HeartIcon />}
|
||||
</Button>
|
||||
|
||||
|
||||
<Button
|
||||
onClick={() => setShowGameOptionsModal(true)}
|
||||
theme="outline"
|
||||
|
|
|
@ -42,6 +42,7 @@ export interface Game {
|
|||
winePrefixPath?: string | null;
|
||||
executablePath?: string | null;
|
||||
launchOptions?: string | null;
|
||||
favorite?: boolean;
|
||||
}
|
||||
|
||||
export interface Download {
|
||||
|
|
Loading…
Reference in a new issue