Commit 7d26b57a authored by Adam Štěpánek's avatar Adam Štěpánek
Browse files

Merge branch 'web/fix-2025-06-02' into 'main'

Web/fix 2025 06 02

See merge request legtvar/pivo!16
parents 3bff3d7c 11dc682f
Loading
Loading
Loading
Loading
Loading
+11 −4
Original line number Diff line number Diff line
@@ -3,8 +3,8 @@ import { t } from 'i18next';
import ReactPlayer, { ReactPlayerProps } from 'react-player';
import { GameMedia } from '../../client';
import { defaultStreamUrl } from '../../utils/getStreamUrl';
import { Video } from './Player/Video';
import { PivoImage } from './PivoImage';
import { Video } from './Player/Video';

interface IContentViewerProps {
    media: GameMedia;
@@ -28,7 +28,8 @@ export function ContentViewer({ media, autoplay, videoProps, onPrevious, onNext
                        subtitles={subtitleSources}
                        minW="100%"
                        maxW="100%"
                        h="60vmin"
                        minH="100%"
                        maxH="100%"
                        autoplay={autoplay}
                        onPrevious={onPrevious}
                        onNext={onNext}
@@ -41,7 +42,7 @@ export function ContentViewer({ media, autoplay, videoProps, onPrevious, onNext
                        alt={''}
                        style={{
                            width: '100%',
                            height: '60vmin',
                            height: '100%',
                            objectFit: 'contain',
                            objectPosition: 'center center',
                        }}
@@ -85,13 +86,19 @@ export function ContentPreview({ media, autoplay, ...props }: IContentViewerProp
                                <PivoImage
                                    id={media.attachmentId}
                                    sizes="25vw"
                                    style={{
                                        width: '100%',
                                        height: '100%',
                                        objectFit: 'cover',
                                        objectPosition: 'center center',
                                    }}
                                    imageProps={{
                                        style: {
                                            width: '100%',
                                            height: '100%',
                                            objectFit: 'cover',
                                            objectPosition: 'center center',
                                        }
                                        },
                                    }}
                                />
                            );
+1 −1
Original line number Diff line number Diff line
@@ -57,7 +57,7 @@ export function Events() {
                    </Text>
                    . {t('events.part2')} -{' '}
                    <Text as="span" textStyle="link">
                        <Link to="/ecosystem">{t('menuButtons.community')}</Link>
                        <Link to="/community">{t('menuButtons.community')}</Link>
                    </Text>
                    .
                </Text>
+154 −141
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@ import {
    AccordionIcon,
    AccordionItem,
    AccordionPanel,
    AspectRatio,
    Box,
    Breadcrumb,
    BreadcrumbItem,
@@ -13,6 +14,8 @@ import {
    CardBody,
    Center,
    Flex,
    Grid,
    GridItem,
    HStack,
    Heading,
    Highlight,
@@ -45,6 +48,7 @@ import {
} from 'react-icons/ri';
import { Link as RouterLink, useSearchParams } from 'react-router-dom';
import { getApiV1Games, getApiV1Tags } from '../../client';
import { GALLERY_PAGE_SIZE, MEDIA_ASPECT } from '../../constants';
import { getPrefered } from '../../utils/preferedLanguage';
import { sequence } from '../../utils/sequence';
import { PivoImage } from '../media/PivoImage';
@@ -54,8 +58,6 @@ import { Loading } from '../utils/Loading';
import { OutletOrChildren } from '../utils/OutletOrChildren';
import { PageTitle } from '../utils/PageTitle';

const PAGE_SIZE = 16;

export function GamesGallery() {
    const [loaded, setLoaded] = useState<boolean>(false);
    const [selectedSort, _setSelectedSort] = useState<string>('recent');
@@ -380,7 +382,7 @@ export function GamesGallery() {
                            <AwaitAPI
                                request={getApiV1Games({
                                    query: {
                                        pageSize: PAGE_SIZE,
                                        pageSize: GALLERY_PAGE_SIZE,
                                        pageIndex: page,
                                        sort: sortBy[selectedSort].value,
                                        lang: i18next.language,
@@ -392,7 +394,7 @@ export function GamesGallery() {
                            >
                                {(gameItems, isLoading, headers) => {
                                    const total = parseInt(headers['x-total-count']) /* WIP item */ + 1;
                                    const pages = Math.ceil(total / PAGE_SIZE);
                                    const pages = Math.ceil(total / GALLERY_PAGE_SIZE);

                                    return (
                                        <Box position="relative">
@@ -408,10 +410,21 @@ export function GamesGallery() {
                                                    <Loading large center />
                                                </Center>
                                            )}
                                            <Flex paddingTop={5} gap={5} wrap="wrap" opacity={isLoading ? 0.2 : 1}>
                                            <Grid
                                                paddingTop={5}
                                                columnGap={6}
                                                rowGap={8}
                                                opacity={isLoading ? 0.2 : 1}
                                                templateColumns={{
                                                    base: '1fr',
                                                    md: 'repeat(2, minmax(0, 1fr))',
                                                    lg: 'repeat(3, minmax(0, 1fr))',
                                                    xl: 'repeat(4, minmax(0, 1fr))',
                                                }}
                                            >
                                                {gameItems.map((game) => (
                                                    <GridItem key={game.id}>
                                                        <Link
                                                        key={game.id}
                                                            as={RouterLink}
                                                            to={
                                                                game.id +
@@ -421,14 +434,15 @@ export function GamesGallery() {
                                                            }
                                                        >
                                                            <Card
                                                            maxW="xs"
                                                                variant="unstyled"
                                                                backgroundColor="transparent"
                                                                flexGrow={1}
                                                                flexShrink={0}
                                                            >
                                                                <CardBody>
                                                                <Center
                                                                    w={{ base: 60, md: 80 }}
                                                                    h={{ base: 36, md: 56 }}
                                                                    <AspectRatio
                                                                        ratio={MEDIA_ASPECT}
                                                                        w="100%"
                                                                        borderRadius="md"
                                                                        sx={{
                                                                            boxShadow: useColorModeValue(
@@ -458,16 +472,16 @@ export function GamesGallery() {
                                                                                }}
                                                                            />
                                                                        ) : (
                                                                        <>
                                                                            <Center>
                                                                                <RiGameFill size={40} />
                                                                                <RiCircleFill size={10} />
                                                                                <span style={{ width: 5 }} />
                                                                                <RiCircleFill size={10} />
                                                                                <span style={{ width: 5 }} />
                                                                                <RiCircleFill size={10} />
                                                                        </>
                                                                    )}
                                                                            </Center>
                                                                        )}
                                                                    </AspectRatio>

                                                                    <Stack mt="4" spacing="1">
                                                                        <Heading size="md">
@@ -517,7 +531,8 @@ export function GamesGallery() {
                                                                                            mr={2}
                                                                                            mb={2}
                                                                                            _hover={{
                                                                                            backgroundColor: isSelected
                                                                                                backgroundColor:
                                                                                                    isSelected
                                                                                                        ? undefined
                                                                                                        : useColorModeValue(
                                                                                                              'gray.200',
@@ -525,7 +540,9 @@ export function GamesGallery() {
                                                                                                          ),
                                                                                            }}
                                                                                            onClick={(event) => {
                                                                                            toggleTag(tagDetails.id);
                                                                                                toggleTag(
                                                                                                    tagDetails.id,
                                                                                                );
                                                                                                event.preventDefault();
                                                                                                event.stopPropagation();
                                                                                            }}
@@ -542,17 +559,13 @@ export function GamesGallery() {
                                                                </CardBody>
                                                            </Card>
                                                        </Link>
                                                    </GridItem>
                                                ))}

                                                {page === pages - 1 && (
                                                    <Card maxW="xs" variant="unstyled" backgroundColor="transparent">
                                                        <CardBody>
                                                            <Center
                                                                w={{ base: 60, md: 80 }}
                                                                h="100%"
                                                                overflow="hidden"
                                                                opacity={0.2}
                                                            >
                                                            <Center h="100%" overflow="hidden" opacity={0.2}>
                                                                <VStack textAlign="center" px={4}>
                                                                    <Icon as={RiGamepadFill} boxSize={20} />
                                                                    <Text fontWeight="bold">{t('games.wip1')}</Text>
@@ -583,7 +596,7 @@ export function GamesGallery() {
                                                        </CardBody>
                                                    </Card>
                                                )}
                                            </Flex>
                                            </Grid>
                                            <HStack mt={8} mb={6}>
                                                <IconButton
                                                    isDisabled={page === 0}
+63 −50
Original line number Diff line number Diff line
@@ -36,7 +36,7 @@ import Avatar from 'boring-avatars';
import { CZ, GB, SK } from 'country-flag-icons/react/3x2';
import { t } from 'i18next';
import moment from 'moment';
import { useState } from 'react';
import { useMemo, useState } from 'react';
import { FaItchIo } from 'react-icons/fa';
import {
    RiArrowDropDownLine,
@@ -48,15 +48,16 @@ import {
} from 'react-icons/ri';
import { useParams } from 'react-router-dom';
import { GameMedia, getApiV1GamesById, getApiV1ReleasesById } from '../../client';
import { MEDIA_ASPECT } from '../../constants';
import { capitalize } from '../../utils/capitalize';
import { defaultStreamUrl } from '../../utils/getStreamUrl';
import { getPrefered } from '../../utils/preferedLanguage';
import { ContentPreview, ContentViewer } from '../media/ContentViewer';
import { PivoImage } from '../media/PivoImage';
import { AwaitAPI } from '../utils/AwaitAPI';
import { ChakraMarkdown } from '../utils/ChakraMarkdown';
import { Error } from '../utils/Error';
import { PageTitle } from '../utils/PageTitle';
import { PivoImage } from '../media/PivoImage';

const iconMap = {
    'steampowered.com': <RiSteamFill size={20} />,
@@ -109,22 +110,30 @@ export function Release() {
        }
    };

    return (
        <AwaitAPI
            request={getApiV1ReleasesById({
    const releaseGetter = useMemo(
        () =>
            getApiV1ReleasesById({
                path: {
                    id: releaseId,
                },
            })}
        >
            {(release) => (
                <AwaitAPI
                    request={getApiV1GamesById({
            }),
        [releaseId],
    );

    const gameGetter = useMemo(
        () =>
            getApiV1GamesById({
                path: {
                    id: gameId,
                },
                    })}
                >
            }),
        [gameId],
    );

    return (
        <AwaitAPI request={releaseGetter}>
            {(release) => (
                <AwaitAPI request={gameGetter}>
                    {(game) => {
                        // Correct way to access the second media item, if it exists
                        const primaryMediaId = release.media?.filter((media) => media.mediaType.startsWith('image'))[0]
@@ -143,17 +152,17 @@ export function Release() {
                                                id={primaryMediaId}
                                                sizes="100vw"
                                                imageProps={{
                                                    alt: "heading-game",
                                                    w: "100%",
                                                    alt: 'heading-game',
                                                    w: '100%',
                                                    h: { base: 36, sm: 36, md: 56, lg: 72 },
                                                    objectFit: "cover",
                                                    objectFit: 'cover',
                                                    objectPosition: 'center center',
                                                    sx: {
                                                        boxShadow: useColorModeValue(
                                                            '2px 2px 10px rgba(128, 128, 128, 0.7)',
                                                            '2px 2px 10px rgba(44, 48, 68, 0.7)',
                                                        ),
                                                    }
                                                    },
                                                }}
                                            />
                                            <Box
@@ -428,24 +437,29 @@ export function Release() {

                                    <Grid
                                        marginBottom={5}
                                        templateRows={{
                                            base: 'auto',
                                            md: `repeat(${Math.max(
                                                2,
                                                1 + Math.ceil((release.media.length - 1) / 4),
                                            )}, 1fr)`,
                                        templateColumns={{
                                            base: '1',
                                            md: 'repeat(2, minmax(0, 1fr))',
                                            lg: 'repeat(3, minmax(0, 1fr))',
                                            xl: 'repeat(4, minmax(0, 1fr))',
                                        }}
                                        templateColumns={{ base: '1', md: 'repeat(4, 1fr)' }}
                                        gap={5}
                                        gap={0}
                                    >
                                        {release.media?.map((media, index) => {
                                            const isHighlighted = index === 0;

                                            return (
                                                <GridItem
                                                    aspectRatio={MEDIA_ASPECT}
                                                    key={media.attachmentId}
                                                    rowSpan={isHighlighted ? 2 : 1}
                                                    colSpan={isHighlighted ? 2 : 1}
                                                    rowSpan={{ base: 1, md: isHighlighted ? 2 : 1 }}
                                                    colSpan={{ base: 1, md: isHighlighted ? 2 : 1 }}
                                                    pr={4}
                                                    pb={4}
                                                >
                                                    <Box
                                                        w="100%"
                                                        h="100%"
                                                        borderRadius="md"
                                                        overflow={'hidden'}
                                                        sx={{
@@ -456,7 +470,11 @@ export function Release() {
                                                        }}
                                                        cursor={'pointer'}
                                                    >
                                                    <ContentPreview media={media} onClick={() => openModal(media)} />
                                                        <ContentPreview
                                                            media={media}
                                                            onClick={() => openModal(media)}
                                                        />
                                                    </Box>
                                                </GridItem>
                                            );
                                        })}
@@ -654,19 +672,14 @@ export function Release() {
                                    )}
                                </VStack>

                                <Modal isOpen={isModalOpen} onClose={closeModal} size={'3xl'} isCentered>
                                <Modal isOpen={isModalOpen} onClose={closeModal} size={'full'} isCentered>
                                    <ModalOverlay />
                                    <ModalContent m={0} borderRadius="none">
                                        <ModalCloseButton
                                            size="lg"
                                            _hover={{ color: 'black' }}
                                            zIndex="1"
                                            position="absolute"
                                            top="4"
                                            right="4"
                                        />
                                        <ModalBody p={0}>
                                    <ModalContent m={0} borderRadius="none" bg="none">
                                        <ModalCloseButton size="lg" zIndex="1" position="absolute" top="4" right="4" />
                                        <ModalBody p={0} overflow="hidden" position="relative">
                                            <Box position="absolute" inset={{ base: 0, md: 10 }}>
                                                {selectedMedia && <ContentViewer media={selectedMedia} />}
                                            </Box>
                                        </ModalBody>
                                    </ModalContent>
                                </Modal>

Web/src/constants.ts

0 → 100644
+3 −0
Original line number Diff line number Diff line
export const GALLERY_PAGE_SIZE = 12; // Divisible by 1, 2, 3, 4

export const MEDIA_ASPECT = 16 / 9;