feat: get image assets from api

This commit is contained in:
Zamitto
2025-05-07 21:05:50 -03:00
parent b6c433dea9
commit 30584492af
11 changed files with 58 additions and 104 deletions

View File

@@ -6,7 +6,8 @@ export const LUDUSAVI_MANIFEST_URL = "https://cdn.losbroxas.org/manifest.yaml";
export const defaultDownloadsPath = SystemPath.getPath("downloads");
export const isStaging = import.meta.env.MAIN_VITE_API_URL.includes("staging");
export const isStaging =
true || import.meta.env.MAIN_VITE_API_URL.includes("staging");
export const windowsStartMenuPath = path.join(
SystemPath.getPath("appData"),

View File

@@ -11,12 +11,12 @@ const getTrendingGames = async (_event: Electron.IpcMainInvokeEvent) => {
.then((language) => language || "en");
const trendingGames = await HydraApi.get<TrendingGame[]>(
"/games/trending",
"/games/featured",
{ language },
{ needsAuth: false }
).catch(() => []);
return trendingGames;
return trendingGames.slice(0, 1);
};
registerEvent("getTrendingGames", getTrendingGames);

View File

@@ -1,25 +1,6 @@
import { registerEvent } from "../register-event";
import { HydraApi, logger } from "@main/services";
import { steamGamesWorker } from "@main/workers";
import { HydraApi } from "@main/services";
import type { UserProfile } from "@types";
import { steamUrlBuilder } from "@shared";
const getSteamGame = async (objectId: string) => {
try {
const steamGame = await steamGamesWorker.run(Number(objectId), {
name: "getById",
});
return {
title: steamGame.name as string,
iconUrl: steamUrlBuilder.icon(objectId, steamGame.clientIcon),
};
} catch (err) {
logger.error("Failed to get Steam game", err);
return null;
}
};
const getUser = async (
_event: Electron.IpcMainInvokeEvent,
@@ -30,62 +11,11 @@ const getUser = async (
if (!profile) return null;
const recentGames = await Promise.all(
profile.recentGames
.map(async (game) => {
const steamGame = await getSteamGame(game.objectId);
return {
...game,
...steamGame,
};
})
.filter((game) => game)
);
const libraryGames = await Promise.all(
profile.libraryGames
.map(async (game) => {
const steamGame = await getSteamGame(game.objectId);
return {
...game,
...steamGame,
};
})
.filter((game) => game)
);
if (profile.currentGame) {
const steamGame = await getSteamGame(profile.currentGame.objectId);
if (steamGame) {
profile.currentGame = {
...profile.currentGame,
...steamGame,
};
}
}
const friends = await Promise.all(
profile.friends.map(async (friend) => {
if (!friend.currentGame) return friend;
const currentGame = await getSteamGame(friend.currentGame.objectId);
return {
...friend,
currentGame: {
...friend.currentGame,
...currentGame,
},
};
})
);
const recentGames = profile.recentGames.filter((game) => game);
const libraryGames = profile.libraryGames.filter((game) => game);
return {
...profile,
friends,
libraryGames,
recentGames,
};

View File

@@ -1,6 +1,4 @@
import { HydraApi } from "../hydra-api";
import { steamGamesWorker } from "@main/workers";
import { steamUrlBuilder } from "@shared";
import { gamesSublevel, levelKeys } from "@main/level";
export const mergeWithRemoteGames = async () => {
@@ -31,20 +29,12 @@ export const mergeWithRemoteGames = async () => {
playTimeInMilliseconds: updatedPlayTime,
});
} else {
const steamGame = await steamGamesWorker.run(Number(game.objectId), {
name: "getById",
});
const iconUrl = steamGame?.clientIcon
? steamUrlBuilder.icon(game.objectId, steamGame.clientIcon)
: null;
await gamesSublevel.put(levelKeys.game(game.shop, game.objectId), {
objectId: game.objectId,
title: steamGame?.name,
title: game.title,
remoteId: game.id,
shop: game.shop,
iconUrl,
iconUrl: game.iconUrl,
lastTimePlayed: game.lastTimePlayed,
playTimeInMilliseconds: game.playTimeInMilliseconds,
isDeleted: false,

View File

@@ -9,7 +9,6 @@ import { useTranslation } from "react-i18next";
import { Badge } from "../badge/badge";
import { useCallback, useState, useMemo } from "react";
import { useFormat, useRepacks } from "@renderer/hooks";
import { steamUrlBuilder } from "@shared";
export interface GameCardProps
extends React.DetailedHTMLProps<
@@ -63,7 +62,7 @@ export function GameCard({ game, ...props }: GameCardProps) {
>
<div className="game-card__backdrop">
<img
src={steamUrlBuilder.library(game.objectId)}
src={game.libraryImageUrl}
alt={game.title}
className="game-card__cover"
loading="lazy"

View File

@@ -43,7 +43,7 @@ export function Hero() {
<div className="hero__backdrop">
<img
src={game.background}
alt={game.description}
alt={game.description ?? ""}
className="hero__media"
/>
@@ -52,7 +52,7 @@ export function Hero() {
<img
src={game.logo}
width="250px"
alt={game.description}
alt={game.description ?? ""}
loading="eager"
/>
)}

View File

@@ -33,6 +33,7 @@ import type {
Badge,
Auth,
ShortcutLocation,
CatalogueSearchResult,
} from "@types";
import type { AxiosProgressEvent } from "axios";
import type disk from "diskusage";
@@ -69,7 +70,7 @@ declare global {
payload: CatalogueSearchPayload,
take: number,
skip: number
) => Promise<{ edges: any[]; count: number }>;
) => Promise<{ edges: CatalogueSearchResult[]; count: number }>;
getCatalogue: (category: CatalogueCategory) => Promise<any[]>;
getGameShopDetails: (
objectId: string,

View File

@@ -1,4 +1,4 @@
import type { DownloadSource } from "@types";
import type { CatalogueSearchResult, DownloadSource } from "@types";
import {
useAppDispatch,
@@ -44,7 +44,7 @@ export default function Catalogue() {
const [downloadSources, setDownloadSources] = useState<DownloadSource[]>([]);
const [isLoading, setIsLoading] = useState(true);
const [results, setResults] = useState<any[]>([]);
const [results, setResults] = useState<CatalogueSearchResult[]>([]);
const [itemsCount, setItemsCount] = useState(0);

View File

@@ -1,15 +1,15 @@
import { Badge } from "@renderer/components";
import { buildGameDetailsPath } from "@renderer/helpers";
import { useAppSelector, useRepacks } from "@renderer/hooks";
import { steamUrlBuilder } from "@shared";
import { useMemo } from "react";
import { useNavigate } from "react-router-dom";
import "./game-item.scss";
import { useTranslation } from "react-i18next";
import { CatalogueSearchResult } from "@types";
export interface GameItemProps {
game: any;
game: CatalogueSearchResult;
}
export function GameItem({ game }: GameItemProps) {
@@ -51,7 +51,7 @@ export function GameItem({ game }: GameItemProps) {
>
<img
className="game-item__cover"
src={steamUrlBuilder.library(game.objectId)}
src={game.libraryImageUrl}
alt={game.title}
loading="lazy"
/>

View File

@@ -12,7 +12,6 @@ import { userProfileContext } from "@renderer/context";
import { ClockIcon, TrophyIcon } from "@primer/octicons-react";
import { MAX_MINUTES_TO_SHOW_IN_PLAYTIME } from "@renderer/constants";
import { useTranslation } from "react-i18next";
import { steamUrlBuilder } from "@shared";
import "./user-library-game-card.scss";
interface UserLibraryGameCardProps {
@@ -150,7 +149,7 @@ export function UserLibraryGameCard({
</div>
<img
src={steamUrlBuilder.cover(game.objectId)}
src={game.coverImageUrl}
alt={game.title}
className="user-library-game__game-image"
/>

View File

@@ -50,7 +50,10 @@ export interface UserGame {
shop: GameShop;
title: string;
iconUrl: string | null;
cover: string;
libraryHeroImageUrl: string;
libraryImageUrl: string;
logoImageUrl: string;
coverImageUrl: string;
playTimeInSeconds: number;
lastTimePlayed: Date | null;
unlockedAchievementCount: number;
@@ -103,6 +106,10 @@ export interface UserFriend {
currentGame: {
title: string;
iconUrl: string;
libraryHeroImageUrl: string;
libraryImageUrl: string;
logoImageUrl: string;
coverImageUrl: string;
objectId: string;
shop: GameShop;
sessionDurationInSeconds: number;
@@ -141,6 +148,10 @@ export interface UserRelation {
export interface UserProfileCurrentGame extends Omit<GameRunning, "objectId"> {
objectId: string;
sessionDurationInSeconds: number;
libraryHeroImageUrl: string;
libraryImageUrl: string;
logoImageUrl: string;
coverImageUrl: string;
}
export type ProfileVisibility = "PUBLIC" | "PRIVATE" | "FRIENDS";
@@ -218,10 +229,14 @@ export interface GameStats {
}
export interface TrendingGame {
uri: string;
description: string;
objectId: string;
shop: GameShop;
title: string;
description: string | null;
background: string;
logo: string | null;
logo: string;
logoPosition: string | null;
uri: string;
}
export interface UserStatsPercentile {
@@ -302,6 +317,25 @@ export interface CatalogueSearchPayload {
developers: string[];
}
export interface CatalogueSearchResult {
id: string;
tags: string[];
genres: string[];
objectId: string;
shop: GameShop;
createdAt: Date;
updatedAt: Date;
title: string;
installCount: number;
achievementCount: number;
iconUrl: string;
libraryHeroImageUrl: string;
libraryImageUrl: string;
logoImageUrl: string;
coverImageUrl: string;
shopData: string;
}
export interface LibraryGame extends Game {
id: string;
download: Download | null;