mirror of
https://github.com/hydralauncher/hydra.git
synced 2025-03-09 15:40:26 +00:00
feat: refactor
This commit is contained in:
parent
958a7d037f
commit
8ff925fbb9
1 changed files with 181 additions and 68 deletions
|
@ -18,7 +18,7 @@ interface UserInfo {
|
||||||
userId: string;
|
userId: string;
|
||||||
displayName: string;
|
displayName: string;
|
||||||
achievements: UserAchievement[];
|
achievements: UserAchievement[];
|
||||||
profileImageUrl: string;
|
profileImageUrl: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface AchievementsContentProps {
|
interface AchievementsContentProps {
|
||||||
|
@ -31,26 +31,14 @@ interface AchievementListProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface AchievementPanelProps {
|
interface AchievementPanelProps {
|
||||||
achievements: UserAchievement[];
|
user: UserInfo;
|
||||||
displayName: string | null;
|
otherUser: UserInfo | null;
|
||||||
profileImageUrl: string | null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function AchievementPanel({
|
function AchievementPanel({ user, otherUser }: AchievementPanelProps) {
|
||||||
achievements,
|
|
||||||
displayName,
|
|
||||||
profileImageUrl,
|
|
||||||
}: AchievementPanelProps) {
|
|
||||||
const { t } = useTranslation("achievement");
|
const { t } = useTranslation("achievement");
|
||||||
|
|
||||||
const unlockedAchievementCount = achievements.filter(
|
const getProfileImage = (imageUrl: string | null | undefined) => {
|
||||||
(achievement) => achievement.unlocked
|
|
||||||
).length;
|
|
||||||
|
|
||||||
const { userDetails } = useUserDetails();
|
|
||||||
|
|
||||||
const getProfileImage = () => {
|
|
||||||
const imageUrl = profileImageUrl || userDetails?.profileImageUrl;
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.profileAvatar}>
|
<div className={styles.profileAvatar}>
|
||||||
{imageUrl ? (
|
{imageUrl ? (
|
||||||
|
@ -62,67 +50,195 @@ function AchievementPanel({
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const totalAchievementCount = achievements.length;
|
const userTotalAchievementCount = user.achievements.length;
|
||||||
return (
|
const userUnlockedAchievementCount = user.achievements.filter(
|
||||||
<div
|
(achievement) => achievement.unlocked
|
||||||
style={{
|
).length;
|
||||||
display: "flex",
|
|
||||||
flexDirection: "row",
|
if (!otherUser) {
|
||||||
width: "100%",
|
return (
|
||||||
padding: `0 ${SPACING_UNIT * 2}px`,
|
|
||||||
gap: `${SPACING_UNIT * 2}px`,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{getProfileImage()}
|
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
flexDirection: "row",
|
||||||
width: "100%",
|
width: "100%",
|
||||||
|
padding: `0 ${SPACING_UNIT * 2}px`,
|
||||||
|
gap: `${SPACING_UNIT * 2}px`,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<h1 style={{ fontSize: "1.2em", marginBottom: "8px" }}>
|
{getProfileImage(user.profileImageUrl)}
|
||||||
{displayName
|
|
||||||
? t("user_achievements", {
|
|
||||||
displayName,
|
|
||||||
})
|
|
||||||
: t("your_achievements")}
|
|
||||||
</h1>
|
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
justifyContent: "space-between",
|
flexDirection: "column",
|
||||||
marginBottom: 8,
|
|
||||||
width: "100%",
|
width: "100%",
|
||||||
color: vars.color.muted,
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
<h1 style={{ fontSize: "1.2em", marginBottom: "8px" }}>
|
||||||
|
{t("your_achievements")}
|
||||||
|
</h1>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "center",
|
justifyContent: "space-between",
|
||||||
gap: 8,
|
marginBottom: 8,
|
||||||
|
width: "100%",
|
||||||
|
color: vars.color.muted,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<TrophyIcon size={13} />
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
gap: 8,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<TrophyIcon size={13} />
|
||||||
|
<span>
|
||||||
|
{userUnlockedAchievementCount} / {userTotalAchievementCount}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<span>
|
<span>
|
||||||
{unlockedAchievementCount} / {totalAchievementCount}
|
{formatDownloadProgress(
|
||||||
|
userUnlockedAchievementCount / userTotalAchievementCount
|
||||||
|
)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
<progress
|
||||||
<span>
|
max={1}
|
||||||
{formatDownloadProgress(
|
value={userUnlockedAchievementCount / userTotalAchievementCount}
|
||||||
unlockedAchievementCount / totalAchievementCount
|
className={styles.achievementsProgressBar}
|
||||||
)}
|
/>
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
<progress
|
|
||||||
max={1}
|
|
||||||
value={unlockedAchievementCount / totalAchievementCount}
|
|
||||||
className={styles.achievementsProgressBar}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const otherUserUnlockedAchievementCount = otherUser.achievements.filter(
|
||||||
|
(achievement) => achievement.unlocked
|
||||||
|
).length;
|
||||||
|
const otherUserTotalAchievementCount = otherUser.achievements.length;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "row",
|
||||||
|
width: "100%",
|
||||||
|
padding: `0 ${SPACING_UNIT * 2}px`,
|
||||||
|
gap: `${SPACING_UNIT * 2}px`,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{getProfileImage(otherUser.profileImageUrl)}
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
width: "100%",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<h1 style={{ fontSize: "1.2em", marginBottom: "8px" }}>
|
||||||
|
{t("user_achievements", {
|
||||||
|
displayName: otherUser.displayName,
|
||||||
|
})}
|
||||||
|
</h1>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
marginBottom: 8,
|
||||||
|
width: "100%",
|
||||||
|
color: vars.color.muted,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
gap: 8,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<TrophyIcon size={13} />
|
||||||
|
<span>
|
||||||
|
{otherUserUnlockedAchievementCount} /{" "}
|
||||||
|
{otherUserTotalAchievementCount}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<span>
|
||||||
|
{formatDownloadProgress(
|
||||||
|
otherUserUnlockedAchievementCount /
|
||||||
|
otherUserTotalAchievementCount
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<progress
|
||||||
|
max={1}
|
||||||
|
value={
|
||||||
|
otherUserUnlockedAchievementCount / otherUserTotalAchievementCount
|
||||||
|
}
|
||||||
|
className={styles.achievementsProgressBar}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "row-reverse",
|
||||||
|
width: "100%",
|
||||||
|
padding: `0 ${SPACING_UNIT * 2}px`,
|
||||||
|
gap: `${SPACING_UNIT * 2}px`,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{getProfileImage(user.profileImageUrl)}
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
width: "100%",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<h1 style={{ fontSize: "1.2em", marginBottom: "8px" }}>
|
||||||
|
{t("your_achievements")}
|
||||||
|
</h1>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
marginBottom: 8,
|
||||||
|
width: "100%",
|
||||||
|
color: vars.color.muted,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
gap: 8,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<TrophyIcon size={13} />
|
||||||
|
<span>
|
||||||
|
{userUnlockedAchievementCount} / {userTotalAchievementCount}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<span>
|
||||||
|
{formatDownloadProgress(
|
||||||
|
userUnlockedAchievementCount / userTotalAchievementCount
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<progress
|
||||||
|
max={1}
|
||||||
|
value={userUnlockedAchievementCount / userTotalAchievementCount}
|
||||||
|
className={styles.achievementsProgressBar}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,6 +374,8 @@ export function AchievementsContent({ otherUser }: AchievementsContentProps) {
|
||||||
|
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
|
const { userDetails } = useUserDetails();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (gameTitle) {
|
if (gameTitle) {
|
||||||
dispatch(setHeaderTitle(gameTitle));
|
dispatch(setHeaderTitle(gameTitle));
|
||||||
|
@ -297,7 +415,7 @@ export function AchievementsContent({ otherUser }: AchievementsContentProps) {
|
||||||
setBackdropOpacity(opacity);
|
setBackdropOpacity(opacity);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!objectId || !shop || !gameTitle) return null;
|
if (!objectId || !shop || !gameTitle || !userDetails) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.wrapper}>
|
<div className={styles.wrapper}>
|
||||||
|
@ -337,18 +455,13 @@ export function AchievementsContent({ otherUser }: AchievementsContentProps) {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={styles.panel({ stuck: isHeaderStuck })}>
|
<div className={styles.panel({ stuck: isHeaderStuck })}>
|
||||||
{otherUser && (
|
|
||||||
<AchievementPanel
|
|
||||||
displayName={otherUser.displayName}
|
|
||||||
achievements={otherUser.achievements}
|
|
||||||
profileImageUrl={otherUser.profileImageUrl}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<AchievementPanel
|
<AchievementPanel
|
||||||
displayName={null}
|
user={{
|
||||||
achievements={sortedAchievements}
|
...userDetails,
|
||||||
profileImageUrl={null}
|
userId: userDetails.id,
|
||||||
|
achievements: achievements!,
|
||||||
|
}}
|
||||||
|
otherUser={otherUser}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue