mirror of
https://github.com/hydralauncher/hydra.git
synced 2025-03-09 15:40:26 +00:00
feat: get trending games from api
This commit is contained in:
parent
87cacdf16c
commit
3199e56661
6 changed files with 66 additions and 48 deletions
22
src/main/events/catalogue/get-trending-games.ts
Normal file
22
src/main/events/catalogue/get-trending-games.ts
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
import { registerEvent } from "../register-event";
|
||||||
|
import { HydraApi } from "@main/services";
|
||||||
|
import { userPreferencesRepository } from "@main/repository";
|
||||||
|
import { TrendingGame } from "@types";
|
||||||
|
|
||||||
|
const getTrendingGames = async (_event: Electron.IpcMainInvokeEvent) => {
|
||||||
|
const userPreferences = await userPreferencesRepository.findOne({
|
||||||
|
where: { id: 1 },
|
||||||
|
});
|
||||||
|
|
||||||
|
const language = userPreferences?.language || "en";
|
||||||
|
|
||||||
|
const trendingGames = await HydraApi.get<TrendingGame[]>(
|
||||||
|
"/games/trending",
|
||||||
|
{ language },
|
||||||
|
{ needsAuth: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
return trendingGames;
|
||||||
|
};
|
||||||
|
|
||||||
|
registerEvent("getTrendingGames", getTrendingGames);
|
|
@ -8,6 +8,7 @@ import "./catalogue/get-how-long-to-beat";
|
||||||
import "./catalogue/get-random-game";
|
import "./catalogue/get-random-game";
|
||||||
import "./catalogue/search-games";
|
import "./catalogue/search-games";
|
||||||
import "./catalogue/search-game-repacks";
|
import "./catalogue/search-game-repacks";
|
||||||
|
import "./catalogue/get-trending-games";
|
||||||
import "./hardware/get-disk-free-space";
|
import "./hardware/get-disk-free-space";
|
||||||
import "./library/add-game-to-library";
|
import "./library/add-game-to-library";
|
||||||
import "./library/create-game-shortcut";
|
import "./library/create-game-shortcut";
|
||||||
|
|
|
@ -44,6 +44,7 @@ contextBridge.exposeInMainWorld("electron", {
|
||||||
ipcRenderer.invoke("getGames", take, prevCursor),
|
ipcRenderer.invoke("getGames", take, prevCursor),
|
||||||
searchGameRepacks: (query: string) =>
|
searchGameRepacks: (query: string) =>
|
||||||
ipcRenderer.invoke("searchGameRepacks", query),
|
ipcRenderer.invoke("searchGameRepacks", query),
|
||||||
|
getTrendingGames: () => ipcRenderer.invoke("getTrendingGames"),
|
||||||
|
|
||||||
/* User preferences */
|
/* User preferences */
|
||||||
getUserPreferences: () => ipcRenderer.invoke("getUserPreferences"),
|
getUserPreferences: () => ipcRenderer.invoke("getUserPreferences"),
|
||||||
|
|
|
@ -1,20 +1,15 @@
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import * as styles from "./hero.css";
|
import * as styles from "./hero.css";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { ShopDetails } from "@types";
|
import { TrendingGame } from "@types";
|
||||||
import {
|
|
||||||
buildGameDetailsPath,
|
|
||||||
getSteamLanguage,
|
|
||||||
steamUrlBuilder,
|
|
||||||
} from "@renderer/helpers";
|
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
import Skeleton, { SkeletonTheme } from "react-loading-skeleton";
|
||||||
const FEATURED_GAME_TITLE = "ELDEN RING";
|
import { vars } from "@renderer/theme.css";
|
||||||
const FEATURED_GAME_ID = "1245620";
|
|
||||||
|
|
||||||
export function Hero() {
|
export function Hero() {
|
||||||
const [featuredGameDetails, setFeaturedGameDetails] =
|
const [featuredGameDetails, setFeaturedGameDetails] = useState<
|
||||||
useState<ShopDetails | null>(null);
|
TrendingGame[] | null
|
||||||
|
>(null);
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
|
||||||
const { i18n } = useTranslation();
|
const { i18n } = useTranslation();
|
||||||
|
@ -25,11 +20,7 @@ export function Hero() {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
|
|
||||||
window.electron
|
window.electron
|
||||||
.getGameShopDetails(
|
.getTrendingGames()
|
||||||
FEATURED_GAME_ID,
|
|
||||||
"steam",
|
|
||||||
getSteamLanguage(i18n.language)
|
|
||||||
)
|
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
setFeaturedGameDetails(result);
|
setFeaturedGameDetails(result);
|
||||||
})
|
})
|
||||||
|
@ -38,41 +29,36 @@ export function Hero() {
|
||||||
});
|
});
|
||||||
}, [i18n.language]);
|
}, [i18n.language]);
|
||||||
|
|
||||||
|
if (isLoading) {
|
||||||
return (
|
return (
|
||||||
|
<SkeletonTheme baseColor={vars.color.background} highlightColor="#444">
|
||||||
|
<Skeleton className={styles.hero} />
|
||||||
|
</SkeletonTheme>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (featuredGameDetails?.length) {
|
||||||
|
return featuredGameDetails.map((game, index) => (
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() =>
|
onClick={() => navigate(game.uri)}
|
||||||
navigate(
|
|
||||||
buildGameDetailsPath({
|
|
||||||
title: FEATURED_GAME_TITLE,
|
|
||||||
objectID: FEATURED_GAME_ID,
|
|
||||||
shop: "steam",
|
|
||||||
})
|
|
||||||
)
|
|
||||||
}
|
|
||||||
className={styles.hero}
|
className={styles.hero}
|
||||||
|
key={index}
|
||||||
>
|
>
|
||||||
<div className={styles.backdrop}>
|
<div className={styles.backdrop}>
|
||||||
<img
|
<img
|
||||||
src="https://cdn2.steamgriddb.com/hero/95eb39b541856d43649b208b65b6ca9f.jpg"
|
src={game.background}
|
||||||
alt={FEATURED_GAME_TITLE}
|
alt={game.description}
|
||||||
className={styles.heroMedia}
|
className={styles.heroMedia}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className={styles.content}>
|
<div className={styles.content}>
|
||||||
<img
|
<p className={styles.description}>{game.description}</p>
|
||||||
src={steamUrlBuilder.logo(FEATURED_GAME_ID)}
|
|
||||||
width="250px"
|
|
||||||
alt={FEATURED_GAME_TITLE}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{!isLoading && featuredGameDetails && (
|
|
||||||
<p className={styles.description}>
|
|
||||||
{featuredGameDetails?.short_description}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
);
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
2
src/renderer/src/declaration.d.ts
vendored
2
src/renderer/src/declaration.d.ts
vendored
|
@ -18,6 +18,7 @@ import type {
|
||||||
FriendRequestAction,
|
FriendRequestAction,
|
||||||
UserFriends,
|
UserFriends,
|
||||||
UserBlocks,
|
UserBlocks,
|
||||||
|
TrendingGame,
|
||||||
} from "@types";
|
} from "@types";
|
||||||
import type { DiskSpace } from "check-disk-space";
|
import type { DiskSpace } from "check-disk-space";
|
||||||
|
|
||||||
|
@ -56,6 +57,7 @@ declare global {
|
||||||
prevCursor?: number
|
prevCursor?: number
|
||||||
) => Promise<{ results: CatalogueEntry[]; cursor: number }>;
|
) => Promise<{ results: CatalogueEntry[]; cursor: number }>;
|
||||||
searchGameRepacks: (query: string) => Promise<GameRepack[]>;
|
searchGameRepacks: (query: string) => Promise<GameRepack[]>;
|
||||||
|
getTrendingGames: () => Promise<TrendingGame[]>;
|
||||||
|
|
||||||
/* Library */
|
/* Library */
|
||||||
addGameToLibrary: (
|
addGameToLibrary: (
|
||||||
|
|
|
@ -339,3 +339,9 @@ export interface DownloadSource {
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
updatedAt: Date;
|
updatedAt: Date;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface TrendingGame {
|
||||||
|
uri: string;
|
||||||
|
description: string;
|
||||||
|
background: string;
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue