fix: favorite and pin button overlapping playtime

This commit is contained in:
Moyasee
2025-09-29 22:04:01 +03:00
parent a39f9ebb70
commit bd053a1635
4 changed files with 59 additions and 3 deletions

View File

@@ -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",

View File

@@ -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": "Библиотека",

View File

@@ -86,7 +86,7 @@
top: 8px;
right: 8px;
display: flex;
gap: 6px;
gap: 4px;
z-index: 2;
}

View File

@@ -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<HTMLLIElement>(null);
const playtimeRef = useRef<HTMLElement>(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 (
<>
<li
ref={cardRef}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
className="user-library-game__wrapper"
@@ -157,6 +205,7 @@ export function UserLibraryGameCard({
</div>
)}
<small
ref={playtimeRef}
className="user-library-game__playtime"
data-tooltip-place="top"
data-tooltip-content={
@@ -174,7 +223,10 @@ export function UserLibraryGameCard({
) : (
<ClockIcon size={11} />
)}
{formatPlayTime(game.playTimeInSeconds)}
{useShortFormat
? formatPlayTimeShort(game.playTimeInSeconds)
: formatPlayTime(game.playTimeInSeconds)
}
</small>
{userProfile?.hasActiveSubscription &&