diff --git a/src/main/events/library/change-game-playtime.ts b/src/main/events/library/change-game-playtime.ts index c8e04e18..b7240e8d 100644 --- a/src/main/events/library/change-game-playtime.ts +++ b/src/main/events/library/change-game-playtime.ts @@ -4,13 +4,12 @@ import { GameShop } from "@types"; import { gamesSublevel } from "@main/level"; import { levelKeys } from "@main/level"; - const changeGamePlaytime = async ( _event: Electron.IpcMainInvokeEvent, shop: GameShop, objectId: string, - playTimeInSeconds: number, -) => { + playTimeInSeconds: number +) => { try { await HydraApi.put(`/profile/games/${shop}/${objectId}/playtime`, { playTimeInSeconds, @@ -26,10 +25,6 @@ const changeGamePlaytime = async ( } catch (error) { throw new Error(`Failed to update game favorite status: ${error}`); } - ; }; - + registerEvent("changeGamePlayTime", changeGamePlaytime); - - - diff --git a/src/renderer/src/declaration.d.ts b/src/renderer/src/declaration.d.ts index 65033525..0744884c 100644 --- a/src/renderer/src/declaration.d.ts +++ b/src/renderer/src/declaration.d.ts @@ -162,7 +162,11 @@ declare global { ) => () => Electron.IpcRenderer; onLibraryBatchComplete: (cb: () => void) => () => Electron.IpcRenderer; resetGameAchievements: (shop: GameShop, objectId: string) => Promise; - changeGamePlayTime: (shop: GameShop, objectId: string, playtimeInSeconds: number) => Promise; + changeGamePlayTime: ( + shop: GameShop, + objectId: string, + playtimeInSeconds: number + ) => Promise; /* User preferences */ authenticateRealDebrid: (apiToken: string) => Promise; authenticateTorBox: (apiToken: string) => Promise; diff --git a/src/renderer/src/pages/game-details/modals/change-game-playtime-modal.scss b/src/renderer/src/pages/game-details/modals/change-game-playtime-modal.scss index a30285c8..41263dbc 100644 --- a/src/renderer/src/pages/game-details/modals/change-game-playtime-modal.scss +++ b/src/renderer/src/pages/game-details/modals/change-game-playtime-modal.scss @@ -36,4 +36,4 @@ align-items: center; gap: globals.$spacing-unit; } -} \ No newline at end of file +} diff --git a/src/renderer/src/pages/game-details/modals/change-game-playtime-modal.tsx b/src/renderer/src/pages/game-details/modals/change-game-playtime-modal.tsx index 78704bbe..3fc97326 100644 --- a/src/renderer/src/pages/game-details/modals/change-game-playtime-modal.tsx +++ b/src/renderer/src/pages/game-details/modals/change-game-playtime-modal.tsx @@ -30,10 +30,12 @@ export function ChangeGamePlaytimeModal({ // Prefill current playtime when modal becomes visible useEffect(() => { if (visible && game.playTimeInMilliseconds) { - const totalMinutes = Math.floor(game.playTimeInMilliseconds / (1000 * 60)); + const totalMinutes = Math.floor( + game.playTimeInMilliseconds / (1000 * 60) + ); const currentHours = Math.floor(totalMinutes / 60); const currentMinutes = totalMinutes % 60; - + setHours(currentHours.toString()); setMinutes(currentMinutes.toString()); } else if (visible) { @@ -51,19 +53,24 @@ export function ChangeGamePlaytimeModal({ const currentMinutes = parseInt(minutes) || 0; // Calculate maximum allowed values based on current input - const maxAllowedHours = Math.min(MAX_TOTAL_HOURS, Math.floor(MAX_TOTAL_HOURS - (currentMinutes / 60))); - const maxAllowedMinutes = currentHours >= MAX_TOTAL_HOURS ? 0 : Math.min(59, Math.floor((MAX_TOTAL_HOURS - currentHours) * 60)); - + const maxAllowedHours = Math.min( + MAX_TOTAL_HOURS, + Math.floor(MAX_TOTAL_HOURS - currentMinutes / 60) + ); + const maxAllowedMinutes = + currentHours >= MAX_TOTAL_HOURS + ? 0 + : Math.min(59, Math.floor((MAX_TOTAL_HOURS - currentHours) * 60)); const handleChangePlaytime = async () => { const hoursNum = parseInt(hours) || 0; const minutesNum = parseInt(minutes) || 0; - const totalSeconds = (hoursNum * 3600) + (minutesNum * 60); + const totalSeconds = hoursNum * 3600 + minutesNum * 60; if (totalSeconds < 0) return; // Prevent exceeding 10,000 hours total - if (hoursNum + (minutesNum / 60) > MAX_TOTAL_HOURS) return; + if (hoursNum + minutesNum / 60 > MAX_TOTAL_HOURS) return; setIsSubmitting(true); try { @@ -80,14 +87,14 @@ export function ChangeGamePlaytimeModal({ const handleHoursChange = (e: React.ChangeEvent) => { let value = e.target.value; - + // Remove leading zeros and prevent multiple zeros - if (value.length > 1 && value.startsWith('0')) { - value = value.replace(/^0+/, '') || '0'; + if (value.length > 1 && value.startsWith("0")) { + value = value.replace(/^0+/, "") || "0"; } - + const numValue = parseInt(value) || 0; - + // Don't allow more than the calculated maximum if (numValue <= maxAllowedHours) { setHours(value); @@ -96,14 +103,14 @@ export function ChangeGamePlaytimeModal({ const handleMinutesChange = (e: React.ChangeEvent) => { let value = e.target.value; - + // Remove leading zeros and prevent multiple zeros - if (value.length > 1 && value.startsWith('0')) { - value = value.replace(/^0+/, '') || '0'; + if (value.length > 1 && value.startsWith("0")) { + value = value.replace(/^0+/, "") || "0"; } - + const numValue = parseInt(value) || 0; - + // Don't allow more than the calculated maximum if (numValue <= maxAllowedMinutes) { setMinutes(value); @@ -128,7 +135,7 @@ export function ChangeGamePlaytimeModal({ {t("manual_playtime_warning")} )} - +
- 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 608590c7..e47093b4 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 @@ -9,7 +9,7 @@ import { formatDownloadProgress, } from "@renderer/helpers"; import { userProfileContext } from "@renderer/context"; -import { ClockIcon, TrophyIcon, AlertFillIcon} from "@primer/octicons-react"; +import { ClockIcon, TrophyIcon, AlertFillIcon } from "@primer/octicons-react"; import { MAX_MINUTES_TO_SHOW_IN_PLAYTIME } from "@renderer/constants"; import { Tooltip } from "react-tooltip"; import { useTranslation } from "react-i18next"; @@ -85,98 +85,108 @@ export function UserLibraryGameCard({ ); return ( - <> - -
  • - -
  • - setIsTooltipHovered(true)} - afterHide={() => setIsTooltipHovered(false)} - /> + {game.title} + + + setIsTooltipHovered(true)} + afterHide={() => setIsTooltipHovered(false)} + /> ); } - diff --git a/src/types/index.ts b/src/types/index.ts index 2c0a75cf..03075e2e 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -70,6 +70,7 @@ export type UserGame = { unlockedAchievementCount: number; achievementCount: number; achievementsPointsEarnedSum: number; + hasManuallyUpdatedPlaytime: boolean; } & ShopAssets; export interface GameRunning {