feat: add profileImage to achievements page

This commit is contained in:
Zamitto 2024-10-15 12:36:24 -03:00
parent c5764a49e1
commit 958a7d037f
5 changed files with 86 additions and 35 deletions

View file

@ -36,7 +36,7 @@ export const buildGameDetailsPath = (
export const buildGameAchievementPath = (
game: { shop: GameShop; objectId: string; title: string },
user?: { userId: string; displayName: string }
user?: { userId: string; displayName: string; profileImageUrl: string | null }
) => {
const searchParams = new URLSearchParams({
title: game.title,
@ -44,6 +44,7 @@ export const buildGameAchievementPath = (
objectId: game.objectId,
userId: user?.userId || "",
displayName: user?.displayName || "",
profileImageUrl: user?.profileImageUrl || "",
});
return `/achievements/?${searchParams.toString()}`;

View file

@ -1,11 +1,11 @@
import { setHeaderTitle } from "@renderer/features";
import { useAppDispatch, useDate } from "@renderer/hooks";
import { useAppDispatch, useDate, useUserDetails } from "@renderer/hooks";
import { steamUrlBuilder } from "@shared";
import { useContext, useEffect, useMemo, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import * as styles from "./achievements.css";
import { formatDownloadProgress } from "@renderer/helpers";
import { TrophyIcon } from "@primer/octicons-react";
import { PersonIcon, TrophyIcon } from "@primer/octicons-react";
import { SPACING_UNIT, vars } from "@renderer/theme.css";
import { gameDetailsContext } from "@renderer/context";
import { UserAchievement } from "@types";
@ -14,12 +14,15 @@ import Color from "color";
const HERO_ANIMATION_THRESHOLD = 25;
interface UserInfo {
userId: string;
displayName: string;
achievements: UserAchievement[];
profileImageUrl: string;
}
interface AchievementsContentProps {
otherUser: {
userId: string;
displayName: string;
achievements: UserAchievement[];
} | null;
otherUser: UserInfo | null;
}
interface AchievementListProps {
@ -30,11 +33,13 @@ interface AchievementListProps {
interface AchievementPanelProps {
achievements: UserAchievement[];
displayName: string | null;
profileImageUrl: string | null;
}
function AchievementPanel({
achievements,
displayName,
profileImageUrl,
}: AchievementPanelProps) {
const { t } = useTranslation("achievement");
@ -42,56 +47,81 @@ function AchievementPanel({
(achievement) => achievement.unlocked
).length;
const { userDetails } = useUserDetails();
const getProfileImage = () => {
const imageUrl = profileImageUrl || userDetails?.profileImageUrl;
return (
<div className={styles.profileAvatar}>
{imageUrl ? (
<img className={styles.profileAvatar} src={imageUrl} alt={"teste"} />
) : (
<PersonIcon size={24} />
)}
</div>
);
};
const totalAchievementCount = achievements.length;
return (
<div
style={{
display: "flex",
flexDirection: "column",
flexDirection: "row",
width: "100%",
padding: `0 ${SPACING_UNIT * 2}px`,
gap: `${SPACING_UNIT * 2}px`,
}}
>
<h1 style={{ fontSize: "1.2em", marginBottom: "8px" }}>
{displayName
? t("user_achievements", {
displayName,
})
: t("your_achievements")}
</h1>
{getProfileImage()}
<div
style={{
display: "flex",
justifyContent: "space-between",
marginBottom: 8,
flexDirection: "column",
width: "100%",
color: vars.color.muted,
}}
>
<h1 style={{ fontSize: "1.2em", marginBottom: "8px" }}>
{displayName
? t("user_achievements", {
displayName,
})
: t("your_achievements")}
</h1>
<div
style={{
display: "flex",
alignItems: "center",
gap: 8,
justifyContent: "space-between",
marginBottom: 8,
width: "100%",
color: vars.color.muted,
}}
>
<TrophyIcon size={13} />
<div
style={{
display: "flex",
alignItems: "center",
gap: 8,
}}
>
<TrophyIcon size={13} />
<span>
{unlockedAchievementCount} / {totalAchievementCount}
</span>
</div>
<span>
{unlockedAchievementCount} / {totalAchievementCount}
{formatDownloadProgress(
unlockedAchievementCount / totalAchievementCount
)}
</span>
</div>
<span>
{formatDownloadProgress(
unlockedAchievementCount / totalAchievementCount
)}
</span>
<progress
max={1}
value={unlockedAchievementCount / totalAchievementCount}
className={styles.achievementsProgressBar}
/>
</div>
<progress
max={1}
value={unlockedAchievementCount / totalAchievementCount}
className={styles.achievementsProgressBar}
/>
</div>
);
}
@ -311,12 +341,14 @@ export function AchievementsContent({ otherUser }: AchievementsContentProps) {
<AchievementPanel
displayName={otherUser.displayName}
achievements={otherUser.achievements}
profileImageUrl={otherUser.profileImageUrl}
/>
)}
<AchievementPanel
displayName={null}
achievements={sortedAchievements}
profileImageUrl={null}
/>
</div>
<div

View file

@ -176,3 +176,15 @@ export const listItemSkeleton = style({
padding: `${SPACING_UNIT}px ${SPACING_UNIT}px`,
gap: `${SPACING_UNIT * 2}px`,
});
export const profileAvatar = style({
height: "65px",
width: "65px",
borderRadius: "4px",
display: "flex",
justifyContent: "center",
alignItems: "center",
backgroundColor: vars.color.background,
position: "relative",
objectFit: "cover",
});

View file

@ -19,6 +19,7 @@ export function Achievement() {
const title = searchParams.get("title");
const userId = searchParams.get("userId");
const displayName = searchParams.get("displayName");
const profileImageUrl = searchParams.get("profileImageUrl");
const { userDetails } = useUserDetails();
@ -59,6 +60,7 @@ export function Achievement() {
userId: otherUserId,
displayName: displayName || "",
achievements: otherUserAchievements || [],
profileImageUrl: profileImageUrl || "",
}
: null;

View file

@ -52,7 +52,11 @@ export function ProfileContent() {
// });
const userParams = userProfile
? { userId: userProfile.id, displayName: userProfile.displayName }
? {
userId: userProfile.id,
displayName: userProfile.displayName,
profileImageUrl: userProfile.profileImageUrl,
}
: undefined;
return buildGameAchievementPath({ ...game }, userParams);