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
|
@ -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({
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
|
@ -236,3 +255,25 @@ export const gameCardStats = style({
|
|||
flexShrink: "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 { useContext, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { useContext, useEffect, useMemo, useState, useRef } from "react";
|
||||
import { ProfileHero } from "../profile-hero/profile-hero";
|
||||
import { useAppDispatch, useFormat } from "@renderer/hooks";
|
||||
import { setHeaderTitle } from "@renderer/features";
|
||||
import { SPACING_UNIT } from "@renderer/theme.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 { LockedProfile } from "./locked-profile";
|
||||
import { ReportProfile } from "../report-profile/report-profile";
|
||||
|
@ -13,6 +18,7 @@ import { FriendsBox } from "./friends-box";
|
|||
import { RecentGamesBox } from "./recent-games-box";
|
||||
import { UserStatsBox } from "./user-stats-box";
|
||||
import { UserLibraryGameCard } from "./user-library-game-card";
|
||||
import { sortBy } from "lodash-es";
|
||||
|
||||
const GAME_STATS_ANIMATION_DURATION_IN_MS = 3500;
|
||||
|
||||
|
@ -26,6 +32,8 @@ export function ProfileContent() {
|
|||
|
||||
const { t } = useTranslation("user_profile");
|
||||
|
||||
const [sortOption, setSortOption] = useState("lastPlayed"); // Estado para o critério de ordenação
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(setHeaderTitle(""));
|
||||
|
||||
|
@ -69,6 +77,25 @@ export function ProfileContent() {
|
|||
return userProfile?.relation?.status === "ACCEPTED";
|
||||
}, [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(() => {
|
||||
if (!userProfile) return null;
|
||||
|
||||
|
@ -84,6 +111,8 @@ export function ProfileContent() {
|
|||
|
||||
const shouldShowRightContent = hasGames || userProfile.friends.length > 0;
|
||||
|
||||
const sortedGames = sortGames(userProfile.libraryGames || []); // Ordena os jogos conforme o critério
|
||||
|
||||
return (
|
||||
<section
|
||||
style={{
|
||||
|
@ -113,8 +142,51 @@ export function ProfileContent() {
|
|||
)}
|
||||
</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}>
|
||||
{userProfile?.libraryGames?.map((game) => (
|
||||
{sortedGames.map((game) => (
|
||||
<UserLibraryGameCard
|
||||
game={game}
|
||||
key={game.objectId}
|
||||
|
@ -146,6 +218,7 @@ export function ProfileContent() {
|
|||
numberFormatter,
|
||||
t,
|
||||
statsIndex,
|
||||
sortOption,
|
||||
]);
|
||||
|
||||
return (
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue