mirror of
https://github.com/hydralauncher/hydra.git
synced 2025-02-12 19:22:28 +00:00
feat: add profileImage to achievements page
This commit is contained in:
parent
c5764a49e1
commit
958a7d037f
5 changed files with 86 additions and 35 deletions
|
@ -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()}`;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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",
|
||||
});
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue