refactor: simplify game details hero section layout and scrolling

This commit is contained in:
Hachi-R 2025-02-17 20:06:39 -03:00
parent 0b4c3a6cd2
commit c5206c68ee
2 changed files with 12 additions and 47 deletions

View file

@ -16,13 +16,8 @@ import { useUserDetails } from "@renderer/hooks";
import { useSubscription } from "@renderer/hooks/use-subscription";
import "./game-details.scss";
const HERO_HEIGHT = 300;
const HERO_ANIMATION_THRESHOLD = 25;
export function GameDetailsContent() {
const heroRef = useRef<HTMLDivElement | null>(null);
const containerRef = useRef<HTMLDivElement | null>(null);
const [isHeaderStuck, setIsHeaderStuck] = useState(false);
const { t } = useTranslation("game_details");
@ -61,7 +56,7 @@ export function GameDetailsContent() {
return t("no_shop_details");
}, [shopDetails, t]);
const [backdropOpactiy, setBackdropOpacity] = useState(1);
const [backdropOpacity, setBackdropOpacity] = useState(1);
const handleHeroLoad = async () => {
const output = await average(steamUrlBuilder.libraryHero(objectId!), {
@ -80,26 +75,6 @@ export function GameDetailsContent() {
setBackdropOpacity(1);
}, [objectId]);
const onScroll: React.UIEventHandler<HTMLElement> = (event) => {
const heroHeight = heroRef.current?.clientHeight ?? HERO_HEIGHT;
const scrollY = (event.target as HTMLDivElement).scrollTop;
const opacity = Math.max(
0,
1 - scrollY / (heroHeight - HERO_ANIMATION_THRESHOLD)
);
if (scrollY >= heroHeight && !isHeaderStuck) {
setIsHeaderStuck(true);
}
if (scrollY <= heroHeight && isHeaderStuck) {
setIsHeaderStuck(false);
}
setBackdropOpacity(opacity);
};
const handleCloudSaveButtonClick = () => {
if (!userDetails) {
window.electron.openAuthWindow(AuthPage.SignIn);
@ -122,31 +97,25 @@ export function GameDetailsContent() {
<div
className={`game-details__wrapper ${hasNSFWContentBlocked ? "game-details__wrapper--blurred" : ""}`}
>
<img
src={steamUrlBuilder.libraryHero(objectId!)}
className="game-details__hero-image"
alt={game?.title}
onLoad={handleHeroLoad}
/>
<section
ref={containerRef}
onScroll={onScroll}
className="game-details__container"
>
<section className="game-details__container">
<div ref={heroRef} className="game-details__hero">
<img
src={steamUrlBuilder.libraryHero(objectId!)}
className="game-details__hero-image"
alt={game?.title}
onLoad={handleHeroLoad}
/>
<div
className="game-details__hero-backdrop"
style={{
backgroundColor: gameColor,
flex: 1,
opacity: Math.min(1, 1 - backdropOpactiy),
}}
/>
<div
className="game-details__hero-logo-backdrop"
style={{ opacity: backdropOpactiy }}
style={{ opacity: backdropOpacity }}
>
<div className="game-details__hero-content">
<img
@ -173,7 +142,7 @@ export function GameDetailsContent() {
</div>
</div>
<HeroPanel isHeaderStuck={isHeaderStuck} />
<HeroPanel />
<div className="game-details__description-container">
<div className="game-details__description-content">

View file

@ -9,11 +9,7 @@ import { HeroPanelPlaytime } from "./hero-panel-playtime";
import { gameDetailsContext } from "@renderer/context";
import "./hero-panel.scss";
export interface HeroPanelProps {
isHeaderStuck: boolean;
}
export function HeroPanel({ isHeaderStuck }: HeroPanelProps) {
export function HeroPanel() {
const { t } = useTranslation("game_details");
const { formatDate } = useDate();
@ -56,7 +52,7 @@ export function HeroPanel({ isHeaderStuck }: HeroPanelProps) {
return (
<div
style={{ backgroundColor: gameColor }}
className={`hero-panel ${isHeaderStuck ? "hero-panel--stuck" : ""}`}
className="hero-panel"
>
<div className="hero-panel__content">{getInfo()}</div>
<div className="hero-panel__actions">