mirror of
https://github.com/hydralauncher/hydra.git
synced 2025-02-15 04:32:13 +00:00
Add slider functionality
This commit is contained in:
parent
40adf3da0e
commit
de1d4c347f
4 changed files with 71 additions and 22 deletions
|
@ -6,7 +6,7 @@
|
||||||
<title>Hydra</title>
|
<title>Hydra</title>
|
||||||
<meta
|
<meta
|
||||||
http-equiv="Content-Security-Policy"
|
http-equiv="Content-Security-Policy"
|
||||||
content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: hydra: https://steamcdn-a.akamaihd.net https://cdn.cloudflare.steamstatic.com https://cdn2.steamgriddb.com https://cdn.akamai.steamstatic.com;"
|
content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: hydra: https://steamcdn-a.akamaihd.net https://cdn.cloudflare.steamstatic.com https://cdn2.steamgriddb.com https://cdn.akamai.steamstatic.com; media-src 'self' data: hydra: https://steamcdn-a.akamaihd.net https://cdn.cloudflare.steamstatic.com https://cdn2.steamgriddb.com https://cdn.akamai.steamstatic.com;"
|
||||||
/>
|
/>
|
||||||
</head>
|
</head>
|
||||||
<body style="background-color: #1c1c1c">
|
<body style="background-color: #1c1c1c">
|
||||||
|
|
|
@ -1,41 +1,65 @@
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { ShopDetails } from "@types";
|
import { ShopDetails, SteamMovies, SteamScreenshot } from "@types";
|
||||||
import { ChevronRightIcon, ChevronLeftIcon } from "@primer/octicons-react";
|
import { ChevronRightIcon, ChevronLeftIcon } from "@primer/octicons-react";
|
||||||
import * as styles from "./game-details.css";
|
import * as styles from "./game-details.css";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
|
|
||||||
export interface GallerySliderProps {
|
export interface GallerySliderProps {
|
||||||
gameDetails: ShopDetails | null;
|
gameDetails: ShopDetails | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function GallerySlider({gameDetails}: GallerySliderProps){
|
export function GallerySlider({ gameDetails }: GallerySliderProps) {
|
||||||
const [imageIndex, setImageIndex] = useState<number>(0)
|
const [mediaIndex, setMediaIndex] = useState<number>(0);
|
||||||
|
const [mediaType, setMediaType] = useState<'video' | 'image'>('video');
|
||||||
|
const { t } = useTranslation("game_details");
|
||||||
|
|
||||||
const showNextImage = () => {
|
const showNextImage = () => {
|
||||||
setImageIndex((index:number) => {
|
setMediaIndex((index: number) => {
|
||||||
if(gameDetails?.screenshots.length && index === (gameDetails?.screenshots.length - 1)) return 0
|
if (gameDetails?.movies.length && index === (gameDetails?.movies.length - 1) && mediaType === 'video') {
|
||||||
|
setMediaType('image')
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
if (gameDetails?.screenshots.length && index === (gameDetails?.screenshots.length - 1) && mediaType === 'image') {
|
||||||
|
setMediaType('video')
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
return index + 1
|
return index + 1
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
const showPrevImage = () => {
|
const showPrevImage = () => {
|
||||||
setImageIndex((index:number) => {
|
setMediaIndex((index: number) => {
|
||||||
if(index === 0 && gameDetails?.screenshots) return gameDetails?.screenshots.length - 1
|
if (gameDetails?.screenshots.length && index === 0 && mediaType === 'video') {
|
||||||
|
setMediaType('image')
|
||||||
|
return gameDetails?.screenshots.length - 1
|
||||||
|
}
|
||||||
|
if (gameDetails?.movies.length && index === 1 && mediaType === 'image') {
|
||||||
|
setMediaType('video')
|
||||||
|
return gameDetails?.movies.length - 1
|
||||||
|
}
|
||||||
|
|
||||||
return index - 1
|
return index - 1
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{gameDetails?.screenshots && (
|
{gameDetails?.screenshots && (
|
||||||
<div className={styles.gallerySliderContainer}>
|
<div className={styles.gallerySliderContainer}>
|
||||||
<h2 className={styles.gallerySliderTitle}>Gallery</h2>
|
<h2 className={styles.gallerySliderTitle}>{t('Videos and screenshots')}</h2>
|
||||||
<img className={styles.gallerySliderImage} src={gameDetails?.screenshots[imageIndex].path_full} />
|
<div className={styles.gallerySliderAnimationContainer}>
|
||||||
<button onClick={showPrevImage} className={styles.gallerySliderButton} style={{left: 0}}><ChevronLeftIcon className={styles.gallerySliderIcons}/></button>
|
{gameDetails.movies.map((video: SteamMovies) => (
|
||||||
<button onClick={showNextImage} className={styles.gallerySliderButton} style={{right: 0}}><ChevronRightIcon className={styles.gallerySliderIcons}/></button>
|
<video controls className={styles.gallerySliderMedia} poster={video.thumbnail} style={{translate: `${-100 * mediaIndex}%`}}>
|
||||||
|
<source src={video.webm.max.replace('http', 'https')} />
|
||||||
|
</video>
|
||||||
|
))}
|
||||||
|
{gameDetails.screenshots.map((image: SteamScreenshot) => (
|
||||||
|
<img className={styles.gallerySliderMedia} src={image.path_full} style={{translate: `${ -100 * mediaIndex}%`}}/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
<button onClick={showPrevImage} className={styles.gallerySliderButton} style={{ left: 0 }}><ChevronLeftIcon className={styles.gallerySliderIcons} /></button>
|
||||||
|
<button onClick={showNextImage} className={styles.gallerySliderButton} style={{ right: 0 }}><ChevronRightIcon className={styles.gallerySliderIcons} /></button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
|
|
@ -89,12 +89,22 @@ export const gallerySliderTitle = style({
|
||||||
padding: `${SPACING_UNIT}px 0`,
|
padding: `${SPACING_UNIT}px 0`,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const gallerySliderImage = style({
|
export const gallerySliderMedia = style({
|
||||||
|
|
||||||
width: "100%",
|
width: "100%",
|
||||||
|
height: "100%",
|
||||||
display: "block",
|
display: "block",
|
||||||
|
flexShrink: 0,
|
||||||
|
flexGrow: 0,
|
||||||
|
transition: "translate 300ms ease-in-out"
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const gallerySliderAnimationContainer = style({
|
||||||
|
width: "100%",
|
||||||
|
height: "100%",
|
||||||
|
display: "flex",
|
||||||
|
overflow: "hidden"
|
||||||
|
})
|
||||||
|
|
||||||
export const gallerySliderButton = style({
|
export const gallerySliderButton = style({
|
||||||
all: "unset",
|
all: "unset",
|
||||||
display: "block",
|
display: "block",
|
||||||
|
|
|
@ -12,6 +12,20 @@ export interface SteamScreenshot {
|
||||||
path_full: string;
|
path_full: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface SteamVideoSource {
|
||||||
|
max: string;
|
||||||
|
'480': string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SteamMovies {
|
||||||
|
id: number;
|
||||||
|
mp4: SteamVideoSource;
|
||||||
|
webm: SteamVideoSource;
|
||||||
|
thumbnail: string;
|
||||||
|
name: string;
|
||||||
|
highlight: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
export interface SteamAppDetails {
|
export interface SteamAppDetails {
|
||||||
name: string;
|
name: string;
|
||||||
detailed_description: string;
|
detailed_description: string;
|
||||||
|
@ -19,6 +33,7 @@ export interface SteamAppDetails {
|
||||||
short_description: string;
|
short_description: string;
|
||||||
publishers: string[];
|
publishers: string[];
|
||||||
genres: SteamGenre[];
|
genres: SteamGenre[];
|
||||||
|
movies: SteamMovies[];
|
||||||
screenshots: SteamScreenshot[];
|
screenshots: SteamScreenshot[];
|
||||||
pc_requirements: {
|
pc_requirements: {
|
||||||
minimum: string;
|
minimum: string;
|
||||||
|
|
Loading…
Reference in a new issue