mirror of
				https://github.com/hydralauncher/hydra.git
				synced 2025-03-09 15:40:26 +00:00 
			
		
		
		
	feat: update achievements page
This commit is contained in:
		
							parent
							
								
									8fb31e0e64
								
							
						
					
					
						commit
						fa026f82a6
					
				
					 9 changed files with 228 additions and 52 deletions
				
			
		| 
						 | 
					@ -333,6 +333,8 @@
 | 
				
			||||||
    "your_friend_code": "Your friend code:"
 | 
					    "your_friend_code": "Your friend code:"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "achievement": {
 | 
					  "achievement": {
 | 
				
			||||||
    "achievement_unlocked": "Achievement unlocked"
 | 
					    "achievement_unlocked": "Achievement unlocked",
 | 
				
			||||||
 | 
					    "user_achievements": "{{displayName}}'s Achievements",
 | 
				
			||||||
 | 
					    "your_achievements": "Your Achievements"
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -335,6 +335,8 @@
 | 
				
			||||||
    "your_friend_code": "Seu código de amigo:"
 | 
					    "your_friend_code": "Seu código de amigo:"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "achievement": {
 | 
					  "achievement": {
 | 
				
			||||||
    "achievement_unlocked": "Conquista desbloqueada"
 | 
					    "achievement_unlocked": "Conquista desbloqueada",
 | 
				
			||||||
 | 
					    "your_achievements": "Suas Conquistas",
 | 
				
			||||||
 | 
					    "user_achievements": "Conquistas de {{displayName}}"
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -83,9 +83,9 @@ export const getGameAchievements = async (
 | 
				
			||||||
        unlocked: false,
 | 
					        unlocked: false,
 | 
				
			||||||
        unlockTime: null,
 | 
					        unlockTime: null,
 | 
				
			||||||
        icongray,
 | 
					        icongray,
 | 
				
			||||||
      };
 | 
					      } as GameAchievement;
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
    .sort((a: GameAchievement, b: GameAchievement) => {
 | 
					    .sort((a, b) => {
 | 
				
			||||||
      if (a.unlocked && !b.unlocked) return -1;
 | 
					      if (a.unlocked && !b.unlocked) return -1;
 | 
				
			||||||
      if (!a.unlocked && b.unlocked) return 1;
 | 
					      if (!a.unlocked && b.unlocked) return 1;
 | 
				
			||||||
      if (a.unlocked && b.unlocked) {
 | 
					      if (a.unlocked && b.unlocked) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -53,7 +53,7 @@ const getPathFromCracker = (cracker: Cracker) => {
 | 
				
			||||||
  if (cracker === Cracker.onlineFix) {
 | 
					  if (cracker === Cracker.onlineFix) {
 | 
				
			||||||
    return [
 | 
					    return [
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        folderPath: path.join(publicDocuments, Cracker.onlineFix),
 | 
					        folderPath: path.join(publicDocuments, "OnlineFix"),
 | 
				
			||||||
        fileLocation: ["Stats", "Achievements.ini"],
 | 
					        fileLocation: ["Stats", "Achievements.ini"],
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
    ];
 | 
					    ];
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -34,5 +34,20 @@ export const buildGameDetailsPath = (
 | 
				
			||||||
  return `/game/${game.shop}/${game.objectId}?${searchParams.toString()}`;
 | 
					  return `/game/${game.shop}/${game.objectId}?${searchParams.toString()}`;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const buildGameAchievementPath = (
 | 
				
			||||||
 | 
					  game: { shop: GameShop; objectId: string; title: string },
 | 
				
			||||||
 | 
					  user?: { userId: string; displayName: string }
 | 
				
			||||||
 | 
					) => {
 | 
				
			||||||
 | 
					  const searchParams = new URLSearchParams({
 | 
				
			||||||
 | 
					    title: game.title,
 | 
				
			||||||
 | 
					    shop: game.shop,
 | 
				
			||||||
 | 
					    objectId: game.objectId,
 | 
				
			||||||
 | 
					    userId: user?.userId || "",
 | 
				
			||||||
 | 
					    displayName: user?.displayName || "",
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return `/achievements/?${searchParams.toString()}`;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const darkenColor = (color: string, amount: number, alpha: number = 1) =>
 | 
					export const darkenColor = (color: string, amount: number, alpha: number = 1) =>
 | 
				
			||||||
  new Color(color).darken(amount).alpha(alpha).toString();
 | 
					  new Color(color).darken(amount).alpha(alpha).toString();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										82
									
								
								src/renderer/src/pages/achievement/achievements.css.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								src/renderer/src/pages/achievement/achievements.css.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,82 @@
 | 
				
			||||||
 | 
					import { SPACING_UNIT, vars } from "../../theme.css";
 | 
				
			||||||
 | 
					import { style } from "@vanilla-extract/css";
 | 
				
			||||||
 | 
					import { recipe } from "@vanilla-extract/recipes";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const container = style({
 | 
				
			||||||
 | 
					  width: "100%",
 | 
				
			||||||
 | 
					  padding: `${SPACING_UNIT * 2}px`,
 | 
				
			||||||
 | 
					  display: "flex",
 | 
				
			||||||
 | 
					  flexDirection: "column",
 | 
				
			||||||
 | 
					  gap: `${SPACING_UNIT * 2}px`,
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const header = style({
 | 
				
			||||||
 | 
					  display: "flex",
 | 
				
			||||||
 | 
					  gap: `${SPACING_UNIT}px`,
 | 
				
			||||||
 | 
					  width: "50%",
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const headerImage = style({
 | 
				
			||||||
 | 
					  borderRadius: "4px",
 | 
				
			||||||
 | 
					  objectFit: "cover",
 | 
				
			||||||
 | 
					  cursor: "pointer",
 | 
				
			||||||
 | 
					  height: "160px",
 | 
				
			||||||
 | 
					  transition: "all ease 0.2s",
 | 
				
			||||||
 | 
					  ":hover": {
 | 
				
			||||||
 | 
					    transform: "scale(1.05)",
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const list = style({
 | 
				
			||||||
 | 
					  listStyle: "none",
 | 
				
			||||||
 | 
					  margin: "0",
 | 
				
			||||||
 | 
					  display: "flex",
 | 
				
			||||||
 | 
					  flexDirection: "column",
 | 
				
			||||||
 | 
					  gap: `${SPACING_UNIT * 2}px`,
 | 
				
			||||||
 | 
					  padding: 0,
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const listItem = style({
 | 
				
			||||||
 | 
					  display: "flex",
 | 
				
			||||||
 | 
					  transition: "all ease 0.1s",
 | 
				
			||||||
 | 
					  color: vars.color.muted,
 | 
				
			||||||
 | 
					  width: "100%",
 | 
				
			||||||
 | 
					  overflow: "hidden",
 | 
				
			||||||
 | 
					  borderRadius: "4px",
 | 
				
			||||||
 | 
					  padding: `${SPACING_UNIT}px ${SPACING_UNIT}px`,
 | 
				
			||||||
 | 
					  gap: `${SPACING_UNIT * 2}px`,
 | 
				
			||||||
 | 
					  alignItems: "center",
 | 
				
			||||||
 | 
					  textAlign: "left",
 | 
				
			||||||
 | 
					  ":hover": {
 | 
				
			||||||
 | 
					    backgroundColor: "rgba(255, 255, 255, 0.15)",
 | 
				
			||||||
 | 
					    textDecoration: "none",
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const listItemImage = recipe({
 | 
				
			||||||
 | 
					  base: {
 | 
				
			||||||
 | 
					    width: "54px",
 | 
				
			||||||
 | 
					    height: "54px",
 | 
				
			||||||
 | 
					    borderRadius: "4px",
 | 
				
			||||||
 | 
					    objectFit: "cover",
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  variants: {
 | 
				
			||||||
 | 
					    unlocked: {
 | 
				
			||||||
 | 
					      false: {
 | 
				
			||||||
 | 
					        filter: "grayscale(100%)",
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const achievementsProgressBar = style({
 | 
				
			||||||
 | 
					  width: "100%",
 | 
				
			||||||
 | 
					  height: "8px",
 | 
				
			||||||
 | 
					  transition: "all ease 0.2s",
 | 
				
			||||||
 | 
					  "::-webkit-progress-bar": {
 | 
				
			||||||
 | 
					    backgroundColor: "rgba(255, 255, 255, 0.15)",
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "::-webkit-progress-value": {
 | 
				
			||||||
 | 
					    backgroundColor: vars.color.muted,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
| 
						 | 
					@ -1,9 +1,17 @@
 | 
				
			||||||
import { setHeaderTitle } from "@renderer/features";
 | 
					import { setHeaderTitle } from "@renderer/features";
 | 
				
			||||||
import { useAppDispatch, useDate } from "@renderer/hooks";
 | 
					import { useAppDispatch, useDate } from "@renderer/hooks";
 | 
				
			||||||
import { SPACING_UNIT } from "@renderer/theme.css";
 | 
					import { steamUrlBuilder } from "@shared";
 | 
				
			||||||
import { GameAchievement, GameShop } from "@types";
 | 
					import type { GameAchievement, GameShop } from "@types";
 | 
				
			||||||
import { useEffect, useState } from "react";
 | 
					import { useEffect, useState } from "react";
 | 
				
			||||||
import { useSearchParams } from "react-router-dom";
 | 
					import { useTranslation } from "react-i18next";
 | 
				
			||||||
 | 
					import { useNavigate, useSearchParams } from "react-router-dom";
 | 
				
			||||||
 | 
					import * as styles from "./achievements.css";
 | 
				
			||||||
 | 
					import {
 | 
				
			||||||
 | 
					  buildGameDetailsPath,
 | 
				
			||||||
 | 
					  formatDownloadProgress,
 | 
				
			||||||
 | 
					} from "@renderer/helpers";
 | 
				
			||||||
 | 
					import { TrophyIcon } from "@primer/octicons-react";
 | 
				
			||||||
 | 
					import { vars } from "@renderer/theme.css";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function Achievement() {
 | 
					export function Achievement() {
 | 
				
			||||||
  const [searchParams] = useSearchParams();
 | 
					  const [searchParams] = useSearchParams();
 | 
				
			||||||
| 
						 | 
					@ -11,8 +19,12 @@ export function Achievement() {
 | 
				
			||||||
  const shop = searchParams.get("shop");
 | 
					  const shop = searchParams.get("shop");
 | 
				
			||||||
  const title = searchParams.get("title");
 | 
					  const title = searchParams.get("title");
 | 
				
			||||||
  const userId = searchParams.get("userId");
 | 
					  const userId = searchParams.get("userId");
 | 
				
			||||||
 | 
					  const displayName = searchParams.get("displayName");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const { t } = useTranslation("achievement");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const { format } = useDate();
 | 
					  const { format } = useDate();
 | 
				
			||||||
 | 
					  const navigate = useNavigate();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const dispatch = useAppDispatch();
 | 
					  const dispatch = useAppDispatch();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -30,53 +42,109 @@ export function Achievement() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  useEffect(() => {
 | 
					  useEffect(() => {
 | 
				
			||||||
    if (title) {
 | 
					    if (title) {
 | 
				
			||||||
      dispatch(setHeaderTitle(title + " Achievements"));
 | 
					      dispatch(setHeaderTitle(title));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }, [dispatch, title]);
 | 
					  }, [dispatch, title]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  if (!objectId || !shop || !title) return null;
 | 
				
			||||||
    <div>
 | 
					 | 
				
			||||||
      <h1>Achievement</h1>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      <div
 | 
					  const unlockedAchievementCount = achievements.filter(
 | 
				
			||||||
        style={{
 | 
					    (achievement) => achievement.unlocked
 | 
				
			||||||
          display: "flex",
 | 
					  ).length;
 | 
				
			||||||
          flexDirection: "column",
 | 
					
 | 
				
			||||||
          gap: `${SPACING_UNIT}px`,
 | 
					  const totalAchievementCount = achievements.length;
 | 
				
			||||||
          padding: `${SPACING_UNIT * 2}px`,
 | 
					
 | 
				
			||||||
        }}
 | 
					  const handleClickGame = () => {
 | 
				
			||||||
      >
 | 
					    navigate(
 | 
				
			||||||
        {achievements.map((achievement, index) => (
 | 
					      buildGameDetailsPath({
 | 
				
			||||||
 | 
					        shop: shop as GameShop,
 | 
				
			||||||
 | 
					        objectId,
 | 
				
			||||||
 | 
					        title,
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <div className={styles.container}>
 | 
				
			||||||
 | 
					      <div className={styles.header}>
 | 
				
			||||||
 | 
					        <button onClick={handleClickGame}>
 | 
				
			||||||
 | 
					          <img
 | 
				
			||||||
 | 
					            src={steamUrlBuilder.cover(objectId)}
 | 
				
			||||||
 | 
					            alt={title}
 | 
				
			||||||
 | 
					            className={styles.headerImage}
 | 
				
			||||||
 | 
					          />
 | 
				
			||||||
 | 
					        </button>
 | 
				
			||||||
 | 
					        <div
 | 
				
			||||||
 | 
					          style={{
 | 
				
			||||||
 | 
					            width: "100%",
 | 
				
			||||||
 | 
					            display: "flex",
 | 
				
			||||||
 | 
					            flexDirection: "column",
 | 
				
			||||||
 | 
					          }}
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					          <h1>
 | 
				
			||||||
 | 
					            {displayName
 | 
				
			||||||
 | 
					              ? t("user_achievements", {
 | 
				
			||||||
 | 
					                  displayName,
 | 
				
			||||||
 | 
					                })
 | 
				
			||||||
 | 
					              : t("your_achievements")}
 | 
				
			||||||
 | 
					          </h1>
 | 
				
			||||||
          <div
 | 
					          <div
 | 
				
			||||||
            key={index}
 | 
					 | 
				
			||||||
            style={{
 | 
					            style={{
 | 
				
			||||||
              display: "flex",
 | 
					              display: "flex",
 | 
				
			||||||
              flexDirection: "row",
 | 
					              justifyContent: "space-between",
 | 
				
			||||||
              alignItems: "center",
 | 
					              marginBottom: 8,
 | 
				
			||||||
              gap: `${SPACING_UNIT}px`,
 | 
					              color: vars.color.muted,
 | 
				
			||||||
            }}
 | 
					            }}
 | 
				
			||||||
            title={achievement.description}
 | 
					 | 
				
			||||||
          >
 | 
					          >
 | 
				
			||||||
            <img
 | 
					            <div
 | 
				
			||||||
              style={{
 | 
					              style={{
 | 
				
			||||||
                height: "60px",
 | 
					                display: "flex",
 | 
				
			||||||
                width: "60px",
 | 
					                alignItems: "center",
 | 
				
			||||||
                filter: achievement.unlocked ? "none" : "grayscale(100%)",
 | 
					                gap: 8,
 | 
				
			||||||
              }}
 | 
					              }}
 | 
				
			||||||
 | 
					            >
 | 
				
			||||||
 | 
					              <TrophyIcon size={13} />
 | 
				
			||||||
 | 
					              <span>
 | 
				
			||||||
 | 
					                {unlockedAchievementCount} / {totalAchievementCount}
 | 
				
			||||||
 | 
					              </span>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <span>
 | 
				
			||||||
 | 
					              {formatDownloadProgress(
 | 
				
			||||||
 | 
					                unlockedAchievementCount / totalAchievementCount
 | 
				
			||||||
 | 
					              )}
 | 
				
			||||||
 | 
					            </span>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					          <progress
 | 
				
			||||||
 | 
					            max={1}
 | 
				
			||||||
 | 
					            value={unlockedAchievementCount / totalAchievementCount}
 | 
				
			||||||
 | 
					            className={styles.achievementsProgressBar}
 | 
				
			||||||
 | 
					          />
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      <ul className={styles.list}>
 | 
				
			||||||
 | 
					        {achievements.map((achievement, index) => (
 | 
				
			||||||
 | 
					          <li key={index} className={styles.listItem}>
 | 
				
			||||||
 | 
					            <img
 | 
				
			||||||
 | 
					              className={styles.listItemImage({
 | 
				
			||||||
 | 
					                unlocked: achievement.unlocked,
 | 
				
			||||||
 | 
					              })}
 | 
				
			||||||
              src={
 | 
					              src={
 | 
				
			||||||
                achievement.unlocked ? achievement.icon : achievement.icongray
 | 
					                achievement.unlocked ? achievement.icon : achievement.icongray
 | 
				
			||||||
              }
 | 
					              }
 | 
				
			||||||
              alt={achievement.displayName}
 | 
					 | 
				
			||||||
              loading="lazy"
 | 
					              loading="lazy"
 | 
				
			||||||
            />
 | 
					            />
 | 
				
			||||||
            <div>
 | 
					            <div>
 | 
				
			||||||
              <p>{achievement.displayName}</p>
 | 
					              <p>{achievement.displayName}</p>
 | 
				
			||||||
              <p>{achievement.description}</p>
 | 
					              <p>{achievement.description}</p>
 | 
				
			||||||
              {achievement.unlockTime && format(achievement.unlockTime)}
 | 
					              <small>
 | 
				
			||||||
 | 
					                {achievement.unlockTime && format(achievement.unlockTime)}
 | 
				
			||||||
 | 
					              </small>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
          </div>
 | 
					          </li>
 | 
				
			||||||
        ))}
 | 
					        ))}
 | 
				
			||||||
      </div>
 | 
					      </ul>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,6 +10,7 @@ import { DownloadIcon, PeopleIcon } from "@primer/octicons-react";
 | 
				
			||||||
import { HowLongToBeatSection } from "./how-long-to-beat-section";
 | 
					import { HowLongToBeatSection } from "./how-long-to-beat-section";
 | 
				
			||||||
import { howLongToBeatEntriesTable } from "@renderer/dexie";
 | 
					import { howLongToBeatEntriesTable } from "@renderer/dexie";
 | 
				
			||||||
import { SidebarSection } from "../sidebar-section/sidebar-section";
 | 
					import { SidebarSection } from "../sidebar-section/sidebar-section";
 | 
				
			||||||
 | 
					import { buildGameAchievementPath } from "@renderer/helpers";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function Sidebar() {
 | 
					export function Sidebar() {
 | 
				
			||||||
  const [howLongToBeat, setHowLongToBeat] = useState<{
 | 
					  const [howLongToBeat, setHowLongToBeat] = useState<{
 | 
				
			||||||
| 
						 | 
					@ -28,16 +29,6 @@ export function Sidebar() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const { numberFormatter } = useFormat();
 | 
					  const { numberFormatter } = useFormat();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const buildGameAchievementPath = () => {
 | 
					 | 
				
			||||||
    const urlParams = new URLSearchParams({
 | 
					 | 
				
			||||||
      objectId: objectId!,
 | 
					 | 
				
			||||||
      shop,
 | 
					 | 
				
			||||||
      title: gameTitle,
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return `/achievements?${urlParams.toString()}`;
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  useEffect(() => {
 | 
					  useEffect(() => {
 | 
				
			||||||
    if (objectId) {
 | 
					    if (objectId) {
 | 
				
			||||||
      setHowLongToBeat({ isLoading: true, data: null });
 | 
					      setHowLongToBeat({ isLoading: true, data: null });
 | 
				
			||||||
| 
						 | 
					@ -88,7 +79,11 @@ export function Sidebar() {
 | 
				
			||||||
            {achievements.slice(0, 4).map((achievement, index) => (
 | 
					            {achievements.slice(0, 4).map((achievement, index) => (
 | 
				
			||||||
              <li key={index}>
 | 
					              <li key={index}>
 | 
				
			||||||
                <Link
 | 
					                <Link
 | 
				
			||||||
                  to={buildGameAchievementPath()}
 | 
					                  to={buildGameAchievementPath({
 | 
				
			||||||
 | 
					                    shop: shop,
 | 
				
			||||||
 | 
					                    objectId: objectId!,
 | 
				
			||||||
 | 
					                    title: gameTitle,
 | 
				
			||||||
 | 
					                  })}
 | 
				
			||||||
                  className={styles.listItem}
 | 
					                  className={styles.listItem}
 | 
				
			||||||
                  title={achievement.description}
 | 
					                  title={achievement.description}
 | 
				
			||||||
                >
 | 
					                >
 | 
				
			||||||
| 
						 | 
					@ -116,7 +111,11 @@ export function Sidebar() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <Link
 | 
					            <Link
 | 
				
			||||||
              style={{ textAlign: "center" }}
 | 
					              style={{ textAlign: "center" }}
 | 
				
			||||||
              to={buildGameAchievementPath()}
 | 
					              to={buildGameAchievementPath({
 | 
				
			||||||
 | 
					                shop: shop,
 | 
				
			||||||
 | 
					                objectId: objectId!,
 | 
				
			||||||
 | 
					                title: gameTitle,
 | 
				
			||||||
 | 
					              })}
 | 
				
			||||||
            >
 | 
					            >
 | 
				
			||||||
              {t("see_all_achievements")}
 | 
					              {t("see_all_achievements")}
 | 
				
			||||||
            </Link>
 | 
					            </Link>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,7 +16,7 @@ import { FriendsBox } from "./friends-box";
 | 
				
			||||||
import { RecentGamesBox } from "./recent-games-box";
 | 
					import { RecentGamesBox } from "./recent-games-box";
 | 
				
			||||||
import { UserGame } from "@types";
 | 
					import { UserGame } from "@types";
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  buildGameDetailsPath,
 | 
					  buildGameAchievementPath,
 | 
				
			||||||
  formatDownloadProgress,
 | 
					  formatDownloadProgress,
 | 
				
			||||||
} from "@renderer/helpers";
 | 
					} from "@renderer/helpers";
 | 
				
			||||||
import { MAX_MINUTES_TO_SHOW_IN_PLAYTIME } from "@renderer/constants";
 | 
					import { MAX_MINUTES_TO_SHOW_IN_PLAYTIME } from "@renderer/constants";
 | 
				
			||||||
| 
						 | 
					@ -44,11 +44,19 @@ export function ProfileContent() {
 | 
				
			||||||
    return userProfile?.relation?.status === "ACCEPTED";
 | 
					    return userProfile?.relation?.status === "ACCEPTED";
 | 
				
			||||||
  }, [userProfile]);
 | 
					  }, [userProfile]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const buildUserGameDetailsPath = (game: UserGame) =>
 | 
					  const buildUserGameDetailsPath = (game: UserGame) => {
 | 
				
			||||||
    buildGameDetailsPath({
 | 
					    // TODO: check if user has hydra cloud
 | 
				
			||||||
      ...game,
 | 
					    // buildGameDetailsPath({
 | 
				
			||||||
      objectId: game.objectId,
 | 
					    //   ...game,
 | 
				
			||||||
    });
 | 
					    //   objectId: game.objectId,
 | 
				
			||||||
 | 
					    // });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const userParams = userProfile
 | 
				
			||||||
 | 
					      ? { userId: userProfile.id, displayName: userProfile.displayName }
 | 
				
			||||||
 | 
					      : undefined;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return buildGameAchievementPath({ ...game }, userParams);
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const formatPlayTime = useCallback(
 | 
					  const formatPlayTime = useCallback(
 | 
				
			||||||
    (playTimeInSeconds = 0) => {
 | 
					    (playTimeInSeconds = 0) => {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue