From f5d5aa39dc192e4138c98a75077558d4e117cde5 Mon Sep 17 00:00:00 2001
From: Zamitto <167933696+zamitto@users.noreply.github.com>
Date: Wed, 25 Dec 2024 20:28:56 -0300
Subject: [PATCH 1/7] feat: game card animation
---
.../services/download/download-manager.ts | 4 +-
.../profile-content/profile-content.tsx | 168 +--------------
.../user-library-game-card.tsx | 204 ++++++++++++++++++
3 files changed, 210 insertions(+), 166 deletions(-)
create mode 100644 src/renderer/src/pages/profile/profile-content/user-library-game-card.tsx
diff --git a/src/main/services/download/download-manager.ts b/src/main/services/download/download-manager.ts
index 80a3f6fb..0d9f5cbb 100644
--- a/src/main/services/download/download-manager.ts
+++ b/src/main/services/download/download-manager.ts
@@ -244,7 +244,7 @@ export class DownloadManager {
private static async getDownloadPayload(game: Game) {
switch (game.downloader) {
case Downloader.Gofile: {
- const id = game!.uri!.split("/").pop();
+ const id = game.uri!.split("/").pop();
const token = await GofileApi.authorize();
const downloadLink = await GofileApi.getDownloadLink(id!);
@@ -258,7 +258,7 @@ export class DownloadManager {
};
}
case Downloader.PixelDrain: {
- const id = game!.uri!.split("/").pop();
+ const id = game.uri!.split("/").pop();
return {
action: "start",
diff --git a/src/renderer/src/pages/profile/profile-content/profile-content.tsx b/src/renderer/src/pages/profile/profile-content/profile-content.tsx
index 2217d569..ed63029b 100644
--- a/src/renderer/src/pages/profile/profile-content/profile-content.tsx
+++ b/src/renderer/src/pages/profile/profile-content/profile-content.tsx
@@ -3,26 +3,18 @@ import { useCallback, useContext, useEffect, useMemo } from "react";
import { ProfileHero } from "../profile-hero/profile-hero";
import { useAppDispatch, useFormat } from "@renderer/hooks";
import { setHeaderTitle } from "@renderer/features";
-import { steamUrlBuilder } from "@shared";
-import { SPACING_UNIT, vars } from "@renderer/theme.css";
-
+import { SPACING_UNIT } from "@renderer/theme.css";
import * as styles from "./profile-content.css";
-import { ClockIcon, TelescopeIcon, TrophyIcon } from "@primer/octicons-react";
+import { TelescopeIcon } from "@primer/octicons-react";
import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom";
import { LockedProfile } from "./locked-profile";
import { ReportProfile } from "../report-profile/report-profile";
import { FriendsBox } from "./friends-box";
import { RecentGamesBox } from "./recent-games-box";
-import type { UserGame } from "@types";
-import {
- buildGameAchievementPath,
- buildGameDetailsPath,
- formatDownloadProgress,
-} from "@renderer/helpers";
import { MAX_MINUTES_TO_SHOW_IN_PLAYTIME } from "@renderer/constants";
import { UserStatsBox } from "./user-stats-box";
-import HydraIcon from "@renderer/assets/icons/hydra.svg?react";
+import { UserLibraryGameCard } from "./user-library-game-card";
export function ProfileContent() {
const { userProfile, isMe, userStats } = useContext(userProfileContext);
@@ -47,26 +39,6 @@ export function ProfileContent() {
return userProfile?.relation?.status === "ACCEPTED";
}, [userProfile]);
- const buildUserGameDetailsPath = useCallback(
- (game: UserGame) => {
- if (!userProfile?.hasActiveSubscription || game.achievementCount === 0) {
- return buildGameDetailsPath({
- ...game,
- objectId: game.objectId,
- });
- }
-
- const userParams = userProfile
- ? {
- userId: userProfile.id,
- }
- : undefined;
-
- return buildGameAchievementPath({ ...game }, userParams);
- },
- [userProfile]
- );
-
const formatPlayTime = useCallback(
(playTimeInSeconds = 0) => {
const minutes = playTimeInSeconds / 60;
@@ -129,137 +101,7 @@ export function ProfileContent() {
{userProfile?.libraryGames?.map((game) => (
- -
-
-
+
))}
>
@@ -271,7 +113,6 @@ export function ProfileContent() {
-
)}
@@ -284,7 +125,6 @@ export function ProfileContent() {
userStats,
numberFormatter,
t,
- buildUserGameDetailsPath,
formatPlayTime,
navigate,
]);
diff --git a/src/renderer/src/pages/profile/profile-content/user-library-game-card.tsx b/src/renderer/src/pages/profile/profile-content/user-library-game-card.tsx
new file mode 100644
index 00000000..8f437a1d
--- /dev/null
+++ b/src/renderer/src/pages/profile/profile-content/user-library-game-card.tsx
@@ -0,0 +1,204 @@
+import { UserGame } from "@types";
+import * as styles from "./profile-content.css";
+import HydraIcon from "@renderer/assets/icons/hydra.svg?react";
+import { useFormat } from "@renderer/hooks";
+import { useNavigate } from "react-router-dom";
+import { useCallback, useContext } from "react";
+import {
+ buildGameAchievementPath,
+ buildGameDetailsPath,
+ formatDownloadProgress,
+} from "@renderer/helpers";
+import { userProfileContext } from "@renderer/context";
+import { vars } from "@renderer/theme.css";
+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";
+
+interface UserLibraryGameCardProps {
+ game: UserGame;
+}
+
+export function UserLibraryGameCard({ game }: UserLibraryGameCardProps) {
+ const { userProfile } = useContext(userProfileContext);
+ const { t } = useTranslation("user_profile");
+ const { numberFormatter } = useFormat();
+ const navigate = useNavigate();
+
+ // const handleCloseClick = useCallback(() => {
+ // setIsClosing(true);
+ // const zero = performance.now();
+
+ // requestAnimationFrame(function animateClosing(time) {
+ // if (time - zero <= 400) {
+ // requestAnimationFrame(animateClosing);
+ // } else {
+ // onClose();
+ // setIsClosing(false);
+ // }
+ // });
+ // }, [onClose]);
+
+ const buildUserGameDetailsPath = useCallback(
+ (game: UserGame) => {
+ if (!userProfile?.hasActiveSubscription || game.achievementCount === 0) {
+ return buildGameDetailsPath({
+ ...game,
+ objectId: game.objectId,
+ });
+ }
+
+ const userParams = userProfile
+ ? {
+ userId: userProfile.id,
+ }
+ : undefined;
+
+ return buildGameAchievementPath({ ...game }, userParams);
+ },
+ [userProfile]
+ );
+
+ const formatPlayTime = useCallback(
+ (playTimeInSeconds = 0) => {
+ const minutes = playTimeInSeconds / 60;
+
+ if (minutes < MAX_MINUTES_TO_SHOW_IN_PLAYTIME) {
+ return t("amount_minutes", {
+ amount: minutes.toFixed(0),
+ });
+ }
+
+ const hours = minutes / 60;
+ return t("amount_hours", { amount: numberFormatter.format(hours) });
+ },
+ [numberFormatter, t]
+ );
+
+ return (
+
+
+
+ );
+}
From a9f8d1b42c6febe1dbcb4b923065d4d27bcf841d Mon Sep 17 00:00:00 2001
From: Lianela <140931995+Lianela@users.noreply.github.com>
Date: Wed, 25 Dec 2024 18:38:38 -0600
Subject: [PATCH 2/7] feat: spanish translation updated
added seeding strings, updated hydra cloud and achievements strings, fixed mistake from previous commits
---
src/locales/es/translation.json | 22 +++++++++++++++++-----
1 file changed, 17 insertions(+), 5 deletions(-)
diff --git a/src/locales/es/translation.json b/src/locales/es/translation.json
index b3dd42f8..516b329d 100644
--- a/src/locales/es/translation.json
+++ b/src/locales/es/translation.json
@@ -50,7 +50,7 @@
"developers": "Desarrolladores",
"genres": "Géneros",
"tags": "Marcadores",
- "publishers": "Distribuidoras",
+ "publishers": "Editores",
"download_sources": "Fuentes de descarga",
"result_count": "{{resultCount}} resultados",
"filter_count": "{{filterCount}} disponibles",
@@ -175,7 +175,7 @@
"backup_from": "Copia de seguridad de {{date}}",
"custom_backup_location_set": "Se configuró la carpeta de copia de seguridad",
"clear": "Limpiar",
- "no_directory_selected": "No se seleccionó un directório"
+ "no_directory_selected": "No se seleccionó un directorio"
},
"activation": {
"title": "Activar Hydra",
@@ -208,7 +208,11 @@
"queued": "En cola",
"no_downloads_title": "Esto está tan... vacío",
"no_downloads_description": "No has descargado nada con Hydra... aún, ¡pero nunca es tarde para comenzar!.",
- "checking_files": "Verificando archivos…"
+ "checking_files": "Verificando archivos…",
+ "seeding": "Seeding",
+ "stop_seeding": "Detener seeding",
+ "resume_seeding": "Continuar seeding",
+ "options": "Gestionar"
},
"settings": {
"downloads_path": "Ruta de descarga",
@@ -376,7 +380,12 @@
"subscription_needed": "Se necesita una suscripción a Hydra Cloud necesita para ver este contenido",
"new_achievements_unlocked": "Desbloqueados {{achievementCount}} nuevos logros de {{gameCount}} juegos",
"achievement_progress": "{{unlockedCount}}/{{totalCount}} logros",
- "achievements_unlocked_for_game": "Se han desbloqueado {{achievementCount}} nuevos logros de {{gameTitle}}"
+ "achievements_unlocked_for_game": "Se han desbloqueado {{achievementCount}} nuevos logros de {{gameTitle}}",
+ "hidden_achievement_tooltip": "Este es un logro oculto",
+ "achievement_earn_points": "Obtén {{points}} puntos con este logro",
+ "earned_points": "Puntos obtenidos:",
+ "available_points": "Puntos disponibles:",
+ "how_to_earn_achievements_points": "¿Cómo obtener puntos de logros?"
},
"hydra_cloud": {
"subscription_tour_title": "Suscripción Hydra Cloud",
@@ -386,6 +395,9 @@
"animated_profile_picture": "Fotos de perfil animadas",
"premium_support": "Soporte Premium",
"show_and_compare_achievements": "Muestra y compara tus logros con otros usuarios",
- "animated_profile_banner": "Fondo de perfil animado"
+ "animated_profile_banner": "Fondo de perfil animado",
+ "hydra_cloud": "Hydra Cloud",
+ "hydra_cloud_feature_found": "¡Has descubierto una característica de Hydra Cloud!",
+ "learn_more": "Aprender más"
}
}
From d6bd0ec221551cf3fa3cb4280bbc2857303140da Mon Sep 17 00:00:00 2001
From: Lianela <140931995+Lianela@users.noreply.github.com>
Date: Wed, 25 Dec 2024 18:52:56 -0600
Subject: [PATCH 3/7] feat: profile strings
---
src/locales/es/translation.json | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/src/locales/es/translation.json b/src/locales/es/translation.json
index 516b329d..931ee058 100644
--- a/src/locales/es/translation.json
+++ b/src/locales/es/translation.json
@@ -269,7 +269,9 @@
"user_unblocked": "El usuario ha sido desbloqueado",
"enable_achievement_notifications": "Cuando un logro se desbloquea",
"launch_minimized": "Iniciar Hydra minimizado",
- "disable_nsfw_alert": "Desactivar alerta NSFW"
+ "disable_nsfw_alert": "Desactivar alerta NSFW",
+ "seed_after_download_complete": "Realizar seeding después de que se completa la descarga",
+ "show_hidden_achievement_description": "Ocultar descripción de logros ocultos antes de desbloquearlos"
},
"notifications": {
"download_complete": "Descarga completada",
@@ -370,7 +372,16 @@
"upload_banner": "Subir un banner",
"uploading_banner": "Subiendo banner…",
"background_image_updated": "Imagen de fondo actualizada",
- "playing": "Jugando {{game}}"
+ "playing": "Jugando {{game}}",
+ "achievements": "logros",
+ "achievements_unlocked": "Logros desbloqueados",
+ "earned_points": "Puntos Obtenidos",
+ "show_achievements_on_profile": "Mostrar tus logros en tu perfil",
+ "show_points_on_profile": "Mostrar tus puntos obtenidos en tu perfil",
+ "games": "Juegos",
+ "ranking_updated_weekly": "El Ranking se actualiza semanalmente",
+ "stats": "Estadísticas",
+ "top_percentile": "Top {{percentile}}%"
},
"achievement": {
"achievement_unlocked": "Logro desbloqueado",
From ec289fe4c7093b63bcba308c6f801d47a7f6e4de Mon Sep 17 00:00:00 2001
From: Zamitto <167933696+zamitto@users.noreply.github.com>
Date: Thu, 26 Dec 2024 15:06:49 -0300
Subject: [PATCH 4/7] feat: animation
---
.../user-library-game-card.tsx | 131 +++++++++++-------
1 file changed, 82 insertions(+), 49 deletions(-)
diff --git a/src/renderer/src/pages/profile/profile-content/user-library-game-card.tsx b/src/renderer/src/pages/profile/profile-content/user-library-game-card.tsx
index 8f437a1d..d35a4d30 100644
--- a/src/renderer/src/pages/profile/profile-content/user-library-game-card.tsx
+++ b/src/renderer/src/pages/profile/profile-content/user-library-game-card.tsx
@@ -3,7 +3,7 @@ import * as styles from "./profile-content.css";
import HydraIcon from "@renderer/assets/icons/hydra.svg?react";
import { useFormat } from "@renderer/hooks";
import { useNavigate } from "react-router-dom";
-import { useCallback, useContext } from "react";
+import { useCallback, useContext, useEffect, useState } from "react";
import {
buildGameAchievementPath,
buildGameDetailsPath,
@@ -26,19 +26,35 @@ export function UserLibraryGameCard({ game }: UserLibraryGameCardProps) {
const { numberFormatter } = useFormat();
const navigate = useNavigate();
- // const handleCloseClick = useCallback(() => {
- // setIsClosing(true);
- // const zero = performance.now();
+ const [mediaIndex, setMediaIndex] = useState(0);
- // requestAnimationFrame(function animateClosing(time) {
- // if (time - zero <= 400) {
- // requestAnimationFrame(animateClosing);
- // } else {
- // onClose();
- // setIsClosing(false);
- // }
- // });
- // }, [onClose]);
+ const statsItemCount =
+ Number(Boolean(game.achievementsPointsEarnedSum)) +
+ Number(Boolean(game.unlockedAchievementCount));
+
+ console.log(game.title, statsItemCount);
+
+ useEffect(() => {
+ if (statsItemCount <= 1) return;
+
+ let zero = performance.now();
+ const animation = requestAnimationFrame(function animateClosing(time) {
+ if (time - zero <= 4000) {
+ requestAnimationFrame(animateClosing);
+ } else {
+ setMediaIndex((index) => {
+ if (index === statsItemCount - 1) return 0;
+ return index + 1;
+ });
+ zero = performance.now();
+ requestAnimationFrame(animateClosing);
+ }
+ });
+
+ return () => {
+ cancelAnimationFrame(animation);
+ };
+ }, [setMediaIndex, statsItemCount]);
const buildUserGameDetailsPath = useCallback(
(game: UserGame) => {
@@ -129,59 +145,76 @@ export function UserLibraryGameCard({ game }: UserLibraryGameCardProps) {
{userProfile?.hasActiveSubscription && game.achievementCount > 0 && (
+
+
+
+
+
+ {game.unlockedAchievementCount} / {game.achievementCount}
+
+
+
+
+ {formatDownloadProgress(
+ game.unlockedAchievementCount / game.achievementCount
+ )}
+
+
+
+
+
+
{game.achievementsPointsEarnedSum > 0 && (
{numberFormatter.format(game.achievementsPointsEarnedSum)}
)}
-
-
-
-
- {game.unlockedAchievementCount} / {game.achievementCount}
-
-
-
-
- {formatDownloadProgress(
- game.unlockedAchievementCount / game.achievementCount
- )}
-
-
-
-
)}
From 16eaf4261addbf1c282c6c2b1fda03161c85437b Mon Sep 17 00:00:00 2001
From: Zamitto <167933696+zamitto@users.noreply.github.com>
Date: Thu, 26 Dec 2024 18:43:06 -0300
Subject: [PATCH 5/7] feat: animation and number format
---
src/renderer/src/helpers.ts | 9 +-
.../profile-content/profile-content.css.ts | 8 ++
.../profile-content/profile-content.tsx | 63 +++++---
.../user-library-game-card.tsx | 134 ++++++++----------
4 files changed, 119 insertions(+), 95 deletions(-)
diff --git a/src/renderer/src/helpers.ts b/src/renderer/src/helpers.ts
index a241bf47..972cdfc9 100644
--- a/src/renderer/src/helpers.ts
+++ b/src/renderer/src/helpers.ts
@@ -2,14 +2,17 @@ import type { GameShop } from "@types";
import Color from "color";
-export const formatDownloadProgress = (progress?: number) => {
+export const formatDownloadProgress = (
+ progress?: number,
+ fractionDigits?: number
+) => {
if (!progress) return "0%";
const progressPercentage = progress * 100;
- if (Number(progressPercentage.toFixed(2)) % 1 === 0)
+ if (Number(progressPercentage.toFixed(fractionDigits ?? 2)) % 1 === 0)
return `${Math.floor(progressPercentage)}%`;
- return `${progressPercentage.toFixed(2)}%`;
+ return `${progressPercentage.toFixed(fractionDigits ?? 2)}%`;
};
export const getSteamLanguage = (language: string) => {
diff --git a/src/renderer/src/pages/profile/profile-content/profile-content.css.ts b/src/renderer/src/pages/profile/profile-content/profile-content.css.ts
index cc462a95..847e9492 100644
--- a/src/renderer/src/pages/profile/profile-content/profile-content.css.ts
+++ b/src/renderer/src/pages/profile/profile-content/profile-content.css.ts
@@ -228,3 +228,11 @@ export const link = style({
cursor: "pointer",
},
});
+
+export const gameCardStats = style({
+ width: "100%",
+ height: "100%",
+ transition: "transform 0.5s ease-in-out",
+ flexShrink: "0",
+ flexGrow: "0",
+});
diff --git a/src/renderer/src/pages/profile/profile-content/profile-content.tsx b/src/renderer/src/pages/profile/profile-content/profile-content.tsx
index ed63029b..a8f65f0f 100644
--- a/src/renderer/src/pages/profile/profile-content/profile-content.tsx
+++ b/src/renderer/src/pages/profile/profile-content/profile-content.tsx
@@ -1,5 +1,5 @@
import { userProfileContext } from "@renderer/context";
-import { useCallback, useContext, useEffect, useMemo } from "react";
+import { useContext, useEffect, useMemo, useRef, useState } from "react";
import { ProfileHero } from "../profile-hero/profile-hero";
import { useAppDispatch, useFormat } from "@renderer/hooks";
import { setHeaderTitle } from "@renderer/features";
@@ -12,12 +12,16 @@ import { LockedProfile } from "./locked-profile";
import { ReportProfile } from "../report-profile/report-profile";
import { FriendsBox } from "./friends-box";
import { RecentGamesBox } from "./recent-games-box";
-import { MAX_MINUTES_TO_SHOW_IN_PLAYTIME } from "@renderer/constants";
import { UserStatsBox } from "./user-stats-box";
import { UserLibraryGameCard } from "./user-library-game-card";
+const GAME_STAT_ANIMATION_DURATION_IN_MS = 3500;
+
export function ProfileContent() {
const { userProfile, isMe, userStats } = useContext(userProfileContext);
+ const [statsIndex, setStatsIndex] = useState(0);
+ const [isAnimationRunning, setIsAnimationRunning] = useState(true);
+ const statsAnimation = useRef(-1);
const dispatch = useAppDispatch();
@@ -31,6 +35,35 @@ export function ProfileContent() {
}
}, [userProfile, dispatch]);
+ const handleOnMouseEnterGameCard = () => {
+ setIsAnimationRunning(false);
+ };
+
+ const handleOnMouseLeaveGameCard = () => {
+ setIsAnimationRunning(true);
+ };
+
+ useEffect(() => {
+ let zero = performance.now();
+ if (!isAnimationRunning) return;
+
+ statsAnimation.current = requestAnimationFrame(
+ function animateClosing(time) {
+ if (time - zero <= GAME_STAT_ANIMATION_DURATION_IN_MS) {
+ statsAnimation.current = requestAnimationFrame(animateClosing);
+ } else {
+ setStatsIndex((index) => index + 1);
+ zero = performance.now();
+ statsAnimation.current = requestAnimationFrame(animateClosing);
+ }
+ }
+ );
+
+ return () => {
+ cancelAnimationFrame(statsAnimation.current);
+ };
+ }, [setStatsIndex, isAnimationRunning]);
+
const { numberFormatter } = useFormat();
const navigate = useNavigate();
@@ -39,22 +72,6 @@ export function ProfileContent() {
return userProfile?.relation?.status === "ACCEPTED";
}, [userProfile]);
- const formatPlayTime = useCallback(
- (playTimeInSeconds = 0) => {
- const minutes = playTimeInSeconds / 60;
-
- if (minutes < MAX_MINUTES_TO_SHOW_IN_PLAYTIME) {
- return t("amount_minutes", {
- amount: minutes.toFixed(0),
- });
- }
-
- const hours = minutes / 60;
- return t("amount_hours", { amount: numberFormatter.format(hours) });
- },
- [numberFormatter, t]
- );
-
const content = useMemo(() => {
if (!userProfile) return null;
@@ -101,7 +118,13 @@ export function ProfileContent() {
{userProfile?.libraryGames?.map((game) => (
-
+
))}
>
@@ -125,8 +148,8 @@ export function ProfileContent() {
userStats,
numberFormatter,
t,
- formatPlayTime,
navigate,
+ statsIndex,
]);
return (
diff --git a/src/renderer/src/pages/profile/profile-content/user-library-game-card.tsx b/src/renderer/src/pages/profile/profile-content/user-library-game-card.tsx
index d35a4d30..b61935f5 100644
--- a/src/renderer/src/pages/profile/profile-content/user-library-game-card.tsx
+++ b/src/renderer/src/pages/profile/profile-content/user-library-game-card.tsx
@@ -3,7 +3,7 @@ import * as styles from "./profile-content.css";
import HydraIcon from "@renderer/assets/icons/hydra.svg?react";
import { useFormat } from "@renderer/hooks";
import { useNavigate } from "react-router-dom";
-import { useCallback, useContext, useEffect, useState } from "react";
+import { useCallback, useContext } from "react";
import {
buildGameAchievementPath,
buildGameDetailsPath,
@@ -18,43 +18,27 @@ import { steamUrlBuilder } from "@shared";
interface UserLibraryGameCardProps {
game: UserGame;
+ statIndex: number;
+ onMouseEnter: () => void;
+ onMouseLeave: () => void;
}
-export function UserLibraryGameCard({ game }: UserLibraryGameCardProps) {
+export function UserLibraryGameCard({
+ game,
+ statIndex,
+ onMouseEnter,
+ onMouseLeave,
+}: UserLibraryGameCardProps) {
const { userProfile } = useContext(userProfileContext);
const { t } = useTranslation("user_profile");
const { numberFormatter } = useFormat();
const navigate = useNavigate();
- const [mediaIndex, setMediaIndex] = useState(0);
-
- const statsItemCount =
- Number(Boolean(game.achievementsPointsEarnedSum)) +
- Number(Boolean(game.unlockedAchievementCount));
-
- console.log(game.title, statsItemCount);
-
- useEffect(() => {
- if (statsItemCount <= 1) return;
-
- let zero = performance.now();
- const animation = requestAnimationFrame(function animateClosing(time) {
- if (time - zero <= 4000) {
- requestAnimationFrame(animateClosing);
- } else {
- setMediaIndex((index) => {
- if (index === statsItemCount - 1) return 0;
- return index + 1;
- });
- zero = performance.now();
- requestAnimationFrame(animateClosing);
- }
- });
-
- return () => {
- cancelAnimationFrame(animation);
- };
- }, [setMediaIndex, statsItemCount]);
+ const getStatsItemCount = useCallback(() => {
+ let statsCount = 1;
+ if (game.achievementsPointsEarnedSum > 0) statsCount++;
+ return statsCount;
+ }, [game]);
const buildUserGameDetailsPath = useCallback(
(game: UserGame) => {
@@ -76,6 +60,14 @@ export function UserLibraryGameCard({ game }: UserLibraryGameCardProps) {
[userProfile]
);
+ const formatAchievementPoints = (number: number) => {
+ if (number < 100_000) return numberFormatter.format(number);
+
+ if (number < 1_000_000) return `${(number / 1000).toFixed(1)}K`;
+
+ return `${(number / 1_000_000).toFixed(1)}M`;
+ };
+
const formatPlayTime = useCallback(
(playTimeInSeconds = 0) => {
const minutes = playTimeInSeconds / 60;
@@ -94,7 +86,8 @@ export function UserLibraryGameCard({ game }: UserLibraryGameCardProps) {
return (
@@ -147,33 +140,32 @@ export function UserLibraryGameCard({ game }: UserLibraryGameCardProps) {
style={{
width: "100%",
display: "flex",
- overflow: "hidden",
+ flexDirection: "column",
}}
>
@@ -182,39 +174,37 @@ export function UserLibraryGameCard({ game }: UserLibraryGameCardProps) {
-
- {formatDownloadProgress(
- game.unlockedAchievementCount / game.achievementCount
- )}
-
+ {game.achievementsPointsEarnedSum > 0 && (
+
+
+ {formatAchievementPoints(
+ game.achievementsPointsEarnedSum
+ )}
+
+ )}
-
+
+ {formatDownloadProgress(
+ game.unlockedAchievementCount / game.achievementCount,
+ 1
+ )}
+
- {game.achievementsPointsEarnedSum > 0 && (
-
-
- {numberFormatter.format(game.achievementsPointsEarnedSum)}
-
- )}
+
)}
From 4e282921ef9bbe8749c3110776b6d04e5edf3cb8 Mon Sep 17 00:00:00 2001
From: Zamitto <167933696+zamitto@users.noreply.github.com>
Date: Fri, 27 Dec 2024 17:42:12 -0300
Subject: [PATCH 6/7] chore: dont remove installation dirs in custom install
script
---
build/installer.nsh | 2 --
1 file changed, 2 deletions(-)
diff --git a/build/installer.nsh b/build/installer.nsh
index 9ae2d42b..3b267a34 100644
--- a/build/installer.nsh
+++ b/build/installer.nsh
@@ -1,7 +1,5 @@
!macro customUnInstall
${ifNot} ${isUpdated}
- RMDir /r "$APPDATA\${APP_PACKAGE_NAME}"
- RMDir /r "$APPDATA\hydra"
RMDir /r "$LOCALAPPDATA\hydralauncher-updater"
${endIf}
!macroend
From db2688f3a70c53cb89b029d93419111c2fe289ff Mon Sep 17 00:00:00 2001
From: Zamitto <167933696+zamitto@users.noreply.github.com>
Date: Sat, 28 Dec 2024 11:28:43 -0300
Subject: [PATCH 7/7] feat: rename variable
---
.../pages/profile/profile-content/profile-content.tsx | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/renderer/src/pages/profile/profile-content/profile-content.tsx b/src/renderer/src/pages/profile/profile-content/profile-content.tsx
index a8f65f0f..951eb41b 100644
--- a/src/renderer/src/pages/profile/profile-content/profile-content.tsx
+++ b/src/renderer/src/pages/profile/profile-content/profile-content.tsx
@@ -15,7 +15,7 @@ import { RecentGamesBox } from "./recent-games-box";
import { UserStatsBox } from "./user-stats-box";
import { UserLibraryGameCard } from "./user-library-game-card";
-const GAME_STAT_ANIMATION_DURATION_IN_MS = 3500;
+const GAME_STATS_ANIMATION_DURATION_IN_MS = 3500;
export function ProfileContent() {
const { userProfile, isMe, userStats } = useContext(userProfileContext);
@@ -48,13 +48,13 @@ export function ProfileContent() {
if (!isAnimationRunning) return;
statsAnimation.current = requestAnimationFrame(
- function animateClosing(time) {
- if (time - zero <= GAME_STAT_ANIMATION_DURATION_IN_MS) {
- statsAnimation.current = requestAnimationFrame(animateClosing);
+ function animateGameStats(time) {
+ if (time - zero <= GAME_STATS_ANIMATION_DURATION_IN_MS) {
+ statsAnimation.current = requestAnimationFrame(animateGameStats);
} else {
setStatsIndex((index) => index + 1);
zero = performance.now();
- statsAnimation.current = requestAnimationFrame(animateClosing);
+ statsAnimation.current = requestAnimationFrame(animateGameStats);
}
}
);