mirror of
				https://github.com/hydralauncher/hydra.git
				synced 2025-03-09 15:40:26 +00:00 
			
		
		
		
	refactor: simplify game details hero section layout and scrolling
This commit is contained in:
		
							parent
							
								
									0b4c3a6cd2
								
							
						
					
					
						commit
						c5206c68ee
					
				
					 2 changed files with 12 additions and 47 deletions
				
			
		|  | @ -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"> | ||||
|  |  | |||
|  | @ -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"> | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue