diff --git a/src/locales/en/translation.json b/src/locales/en/translation.json index ce8b4de1..93fd5b0a 100755 --- a/src/locales/en/translation.json +++ b/src/locales/en/translation.json @@ -506,6 +506,8 @@ "user_profile": { "amount_hours": "{{amount}} hours", "amount_minutes": "{{amount}} minutes", + "amount_hours_short": "{{amount}}h", + "amount_minutes_short": "{{amount}}m", "last_time_played": "Last played {{period}}", "activity": "Recent Activity", "library": "Library", diff --git a/src/locales/ru/translation.json b/src/locales/ru/translation.json index 58235989..c92d7902 100644 --- a/src/locales/ru/translation.json +++ b/src/locales/ru/translation.json @@ -486,6 +486,8 @@ "user_profile": { "amount_hours": "{{amount}} часов", "amount_minutes": "{{amount}} минут", + "amount_hours_short": "{{amount}}ч", + "amount_minutes_short": "{{amount}}м", "last_time_played": "Последняя игра {{period}}", "activity": "Недавняя активность", "library": "Библиотека", diff --git a/src/renderer/src/pages/profile/profile-content/user-library-game-card.scss b/src/renderer/src/pages/profile/profile-content/user-library-game-card.scss index f072fdd5..e40061de 100644 --- a/src/renderer/src/pages/profile/profile-content/user-library-game-card.scss +++ b/src/renderer/src/pages/profile/profile-content/user-library-game-card.scss @@ -86,7 +86,7 @@ top: 8px; right: 8px; display: flex; - gap: 6px; + gap: 4px; z-index: 2; } 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 860c6758..d30dbf8a 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 @@ -2,7 +2,7 @@ import { UserGame } from "@types"; import HydraIcon from "@renderer/assets/icons/hydra.svg?react"; import { useFormat, useToast } from "@renderer/hooks"; import { useNavigate } from "react-router-dom"; -import { useCallback, useContext, useState } from "react"; +import { useCallback, useContext, useState, useEffect, useRef } from "react"; import { buildGameAchievementPath, buildGameDetailsPath, @@ -43,6 +43,9 @@ export function UserLibraryGameCard({ const navigate = useNavigate(); const [isTooltipHovered, setIsTooltipHovered] = useState(false); const [isPinning, setIsPinning] = useState(false); + const [useShortFormat, setUseShortFormat] = useState(false); + const cardRef = useRef(null); + const playtimeRef = useRef(null); const getStatsItemCount = useCallback(() => { let statsCount = 1; @@ -94,6 +97,50 @@ export function UserLibraryGameCard({ [numberFormatter, t] ); + const formatPlayTimeShort = useCallback( + (playTimeInSeconds = 0) => { + const minutes = playTimeInSeconds / 60; + + if (minutes < MAX_MINUTES_TO_SHOW_IN_PLAYTIME) { + return t("amount_minutes_short", { + amount: minutes.toFixed(0), + }); + } + + const hours = minutes / 60; + return t("amount_hours_short", { amount: Math.floor(hours) }); + }, + [t] + ); + + const checkForOverlap = useCallback(() => { + if (!cardRef.current || !playtimeRef.current) return; + + const cardWidth = cardRef.current.offsetWidth; + const hasButtons = game.isFavorite || isMe; + + if (hasButtons && cardWidth < 180) { + setUseShortFormat(true); + } else { + setUseShortFormat(false); + } + }, [game.isFavorite, isMe]); + + useEffect(() => { + checkForOverlap(); + + const handleResize = () => { + checkForOverlap(); + }; + + window.addEventListener('resize', handleResize); + return () => window.removeEventListener('resize', handleResize); + }, [checkForOverlap]); + + useEffect(() => { + checkForOverlap(); + }, [game.isFavorite, isMe, checkForOverlap]); + const toggleGamePinned = async () => { setIsPinning(true); @@ -119,6 +166,7 @@ export function UserLibraryGameCard({ return ( <>
  • )} )} - {formatPlayTime(game.playTimeInSeconds)} + {useShortFormat + ? formatPlayTimeShort(game.playTimeInSeconds) + : formatPlayTime(game.playTimeInSeconds) + } {userProfile?.hasActiveSubscription &&