mirror of
https://github.com/hydralauncher/hydra.git
synced 2025-03-09 15:40:26 +00:00
Merge 438c2d96b0
into 3247fcda60
This commit is contained in:
commit
896efcd651
4 changed files with 119 additions and 5 deletions
|
@ -1,2 +1,2 @@
|
||||||
MAIN_VITE_API_URL=API_URL
|
MAIN_VITE_API_URL=API_URL
|
||||||
MAIN_VITE_AUTH_URL=AUTH_URL
|
MAIN_VITE_AUTH_URL=AUTH_URL
|
|
@ -229,6 +229,25 @@ export const link = style({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const gridSorting = style({
|
||||||
|
display: "flex", // Usa flexbox para organizar o layout
|
||||||
|
justifyContent: "space-between", // Espaça o label e os botões
|
||||||
|
alignItems: "center", // Centraliza verticalmente
|
||||||
|
marginBottom: `${SPACING_UNIT * 2}px`,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const sortOption = style({
|
||||||
|
transition: "all ease 0.2s",
|
||||||
|
display: "inline-flex", // Altera para inline-flex para alinhar itens no botão
|
||||||
|
alignItems: "center", // Centraliza o ícone e o texto verticalmente
|
||||||
|
gap: "10px", // Define o espaçamento entre o ícone e o texto
|
||||||
|
color: vars.color.body,
|
||||||
|
":hover": {
|
||||||
|
color: "white",
|
||||||
|
cursor: "pointer",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
export const gameCardStats = style({
|
export const gameCardStats = style({
|
||||||
width: "100%",
|
width: "100%",
|
||||||
height: "100%",
|
height: "100%",
|
||||||
|
@ -236,3 +255,25 @@ export const gameCardStats = style({
|
||||||
flexShrink: "0",
|
flexShrink: "0",
|
||||||
flexGrow: "0",
|
flexGrow: "0",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const selectedSortOption = style({
|
||||||
|
transition: "all ease 0.2s",
|
||||||
|
display: "inline-flex", // Altera para inline-flex para alinhar itens no botão
|
||||||
|
alignItems: "center", // Centraliza o ícone e o texto verticalmente
|
||||||
|
color: "white",
|
||||||
|
gap: "10px", // Define o espaçamento entre o ícone e o texto
|
||||||
|
":hover": {
|
||||||
|
cursor: "pointer",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const sortOptionsWrapper = style({
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "row",
|
||||||
|
gap: "5px",
|
||||||
|
});
|
||||||
|
|
||||||
|
export const sortDivider = style({
|
||||||
|
border: `0.5px solid ${vars.color.body}`,
|
||||||
|
margin: "0px 5px",
|
||||||
|
});
|
||||||
|
|
|
@ -1,11 +1,16 @@
|
||||||
import { userProfileContext } from "@renderer/context";
|
import { userProfileContext } from "@renderer/context";
|
||||||
import { useContext, useEffect, useMemo, useRef, useState } from "react";
|
import { useContext, useEffect, useMemo, useState, useRef } from "react";
|
||||||
import { ProfileHero } from "../profile-hero/profile-hero";
|
import { ProfileHero } from "../profile-hero/profile-hero";
|
||||||
import { useAppDispatch, useFormat } from "@renderer/hooks";
|
import { useAppDispatch, useFormat } from "@renderer/hooks";
|
||||||
import { setHeaderTitle } from "@renderer/features";
|
import { setHeaderTitle } from "@renderer/features";
|
||||||
import { SPACING_UNIT } from "@renderer/theme.css";
|
import { SPACING_UNIT } from "@renderer/theme.css";
|
||||||
import * as styles from "./profile-content.css";
|
import * as styles from "./profile-content.css";
|
||||||
import { TelescopeIcon } from "@primer/octicons-react";
|
import {
|
||||||
|
ClockIcon,
|
||||||
|
TelescopeIcon,
|
||||||
|
TrophyIcon,
|
||||||
|
HistoryIcon,
|
||||||
|
} from "@primer/octicons-react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { LockedProfile } from "./locked-profile";
|
import { LockedProfile } from "./locked-profile";
|
||||||
import { ReportProfile } from "../report-profile/report-profile";
|
import { ReportProfile } from "../report-profile/report-profile";
|
||||||
|
@ -13,6 +18,7 @@ import { FriendsBox } from "./friends-box";
|
||||||
import { RecentGamesBox } from "./recent-games-box";
|
import { RecentGamesBox } from "./recent-games-box";
|
||||||
import { UserStatsBox } from "./user-stats-box";
|
import { UserStatsBox } from "./user-stats-box";
|
||||||
import { UserLibraryGameCard } from "./user-library-game-card";
|
import { UserLibraryGameCard } from "./user-library-game-card";
|
||||||
|
import { sortBy } from "lodash-es";
|
||||||
|
|
||||||
const GAME_STATS_ANIMATION_DURATION_IN_MS = 3500;
|
const GAME_STATS_ANIMATION_DURATION_IN_MS = 3500;
|
||||||
|
|
||||||
|
@ -26,6 +32,8 @@ export function ProfileContent() {
|
||||||
|
|
||||||
const { t } = useTranslation("user_profile");
|
const { t } = useTranslation("user_profile");
|
||||||
|
|
||||||
|
const [sortOption, setSortOption] = useState("lastPlayed"); // Estado para o critério de ordenação
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
dispatch(setHeaderTitle(""));
|
dispatch(setHeaderTitle(""));
|
||||||
|
|
||||||
|
@ -69,6 +77,25 @@ export function ProfileContent() {
|
||||||
return userProfile?.relation?.status === "ACCEPTED";
|
return userProfile?.relation?.status === "ACCEPTED";
|
||||||
}, [userProfile]);
|
}, [userProfile]);
|
||||||
|
|
||||||
|
const sortGames = (games) => {
|
||||||
|
if (sortOption === "playtime") {
|
||||||
|
return sortBy(games, (game) => -game.playTimeInSeconds);
|
||||||
|
} else if (sortOption === "achievements") {
|
||||||
|
return sortBy(games, (game) => {
|
||||||
|
return game.achievementCount > 0
|
||||||
|
? -(game.unlockedAchievementCount / game.achievementCount)
|
||||||
|
: 0;
|
||||||
|
});
|
||||||
|
} else if (sortOption === "lastPlayed") {
|
||||||
|
return sortBy(games, (game) => {
|
||||||
|
return game.lastTimePlayed
|
||||||
|
? -new Date(game.lastTimePlayed).getTime()
|
||||||
|
: 0;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return games;
|
||||||
|
};
|
||||||
|
|
||||||
const content = useMemo(() => {
|
const content = useMemo(() => {
|
||||||
if (!userProfile) return null;
|
if (!userProfile) return null;
|
||||||
|
|
||||||
|
@ -84,6 +111,8 @@ export function ProfileContent() {
|
||||||
|
|
||||||
const shouldShowRightContent = hasGames || userProfile.friends.length > 0;
|
const shouldShowRightContent = hasGames || userProfile.friends.length > 0;
|
||||||
|
|
||||||
|
const sortedGames = sortGames(userProfile.libraryGames || []); // Ordena os jogos conforme o critério
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section
|
<section
|
||||||
style={{
|
style={{
|
||||||
|
@ -113,8 +142,51 @@ export function ProfileContent() {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.gridSorting}>
|
||||||
|
<div>
|
||||||
|
<label htmlFor="sort-options">Ordenar por: </label>
|
||||||
|
</div>
|
||||||
|
<div className={styles.sortOptionsWrapper}>
|
||||||
|
<button
|
||||||
|
className={`${sortOption === "lastPlayed" ? styles.selectedSortOption : styles.sortOption}`}
|
||||||
|
onClick={() => setSortOption("lastPlayed")}
|
||||||
|
onKeyDown={(e) =>
|
||||||
|
e.key === "Enter" && setSortOption("lastPlayed")
|
||||||
|
} // Add keyboard support
|
||||||
|
tabIndex={0} // Optional if you keep using <span>
|
||||||
|
>
|
||||||
|
<HistoryIcon size={14} />
|
||||||
|
Jogados recentemente
|
||||||
|
</button>
|
||||||
|
<div className={styles.sortDivider} />
|
||||||
|
<button
|
||||||
|
className={`${sortOption === "playtime" ? styles.selectedSortOption : styles.sortOption}`}
|
||||||
|
onClick={() => setSortOption("playtime")}
|
||||||
|
onKeyDown={(e) =>
|
||||||
|
e.key === "Enter" && setSortOption("playtime")
|
||||||
|
} // Add keyboard support
|
||||||
|
tabIndex={0} // Optional if you keep using <span>
|
||||||
|
>
|
||||||
|
<ClockIcon size={14} />
|
||||||
|
Tempo jogado
|
||||||
|
</button>
|
||||||
|
<div className={styles.sortDivider} />
|
||||||
|
<button
|
||||||
|
className={`${sortOption === "achievements" ? styles.selectedSortOption : styles.sortOption}`}
|
||||||
|
onClick={() => setSortOption("achievements")}
|
||||||
|
onKeyDown={(e) =>
|
||||||
|
e.key === "Enter" && setSortOption("achievements")
|
||||||
|
} // Add keyboard support
|
||||||
|
tabIndex={0} // Optional if you keep using <span>
|
||||||
|
>
|
||||||
|
<TrophyIcon size={14} />
|
||||||
|
Conquistas obtidas
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<ul className={styles.gamesGrid}>
|
<ul className={styles.gamesGrid}>
|
||||||
{userProfile?.libraryGames?.map((game) => (
|
{sortedGames.map((game) => (
|
||||||
<UserLibraryGameCard
|
<UserLibraryGameCard
|
||||||
game={game}
|
game={game}
|
||||||
key={game.objectId}
|
key={game.objectId}
|
||||||
|
@ -146,6 +218,7 @@ export function ProfileContent() {
|
||||||
numberFormatter,
|
numberFormatter,
|
||||||
t,
|
t,
|
||||||
statsIndex,
|
statsIndex,
|
||||||
|
sortOption,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -23,4 +23,4 @@
|
||||||
"@shared": ["src/shared/index.ts"]
|
"@shared": ["src/shared/index.ts"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue