From 95110099947cfaaba61b585f85e6a9794f41120c Mon Sep 17 00:00:00 2001 From: Rakesh Merugu Date: Sun, 23 Jun 2024 23:04:30 +0530 Subject: [PATCH] feat: full screen mode in manga reader --- src/components/AnimeCard.tsx | 2 +- src/components/MangaCard.tsx | 14 ++---- src/hooks/useFullScreenMode.tsx | 38 ++++++++++++++++ src/screens/mangaDetailsScreen.tsx | 43 +++++++++---------- src/screens/mangaReaderScreen.tsx | 69 +++++++++++++++++++++++------- 5 files changed, 117 insertions(+), 49 deletions(-) create mode 100644 src/hooks/useFullScreenMode.tsx diff --git a/src/components/AnimeCard.tsx b/src/components/AnimeCard.tsx index f4b42fc..39d9bf9 100644 --- a/src/components/AnimeCard.tsx +++ b/src/components/AnimeCard.tsx @@ -27,7 +27,7 @@ export function AnimeCard({ data, onClick }: { data: any; onClick?: () => void } ); } diff --git a/src/hooks/useFullScreenMode.tsx b/src/hooks/useFullScreenMode.tsx new file mode 100644 index 0000000..3ed2ca5 --- /dev/null +++ b/src/hooks/useFullScreenMode.tsx @@ -0,0 +1,38 @@ +import { useCallback, useEffect, useRef, useState } from 'react'; + +export function useFullScreenMode() { + const ref = useRef(null); + + const [isFullScreen, setIsFullScreen] = useState(false); + + const handleFullScreen = useCallback(async () => { + if (document.fullscreenElement) document.exitFullscreen(); + else ref.current?.requestFullscreen(); + }, [ref]); + + const handleFullscreenchange = useCallback( + (e: Event) => { + console.log('full-screen-change-event', e); + setIsFullScreen(!isFullScreen); + }, + [setIsFullScreen, isFullScreen], + ); + const handleKeyDown = useCallback( + (event: KeyboardEvent) => { + if (['f', 'F'].includes(event.key)) handleFullScreen(); + }, + [handleFullScreen], + ); + + useEffect(() => { + ref.current?.addEventListener('fullscreenchange', handleFullscreenchange); + return () => ref.current?.removeEventListener('fullscreenchange', handleFullscreenchange); + }, [ref, handleFullscreenchange]); + + useEffect(() => { + window?.addEventListener('keydown', handleKeyDown); + return () => window?.removeEventListener('keydown', handleKeyDown); + }, [handleKeyDown]); + + return { fullScreenRef: ref, handleFullScreen, isFullScreen }; +} diff --git a/src/screens/mangaDetailsScreen.tsx b/src/screens/mangaDetailsScreen.tsx index 82f2cde..b8e3bcf 100644 --- a/src/screens/mangaDetailsScreen.tsx +++ b/src/screens/mangaDetailsScreen.tsx @@ -204,18 +204,20 @@ export function MangaDetailsScreen() { {volTxt} - - - {data?.type} - + {data?.type ? ( + + + {data?.type} + + ) : null} {data?.status && ( {data?.status} @@ -247,18 +249,15 @@ export function MangaDetailsScreen() { {data.genres?.length ? (
- + Genre - {data.genres && - data.genres.map((item, index) => { - return ( - - {item} - - ); - })} + {data.genres?.map((item, index) => ( + + {item} + + ))}
) : null} @@ -269,7 +268,7 @@ export function MangaDetailsScreen() { alignItems: 'flex-end', }}> {isLoading ? ( - + ) : ( )} diff --git a/src/screens/mangaReaderScreen.tsx b/src/screens/mangaReaderScreen.tsx index 7a4711d..cd07b3c 100644 --- a/src/screens/mangaReaderScreen.tsx +++ b/src/screens/mangaReaderScreen.tsx @@ -1,12 +1,14 @@ -import { Box, Center, Flex, Heading, Image, Skeleton, Text } from '@chakra-ui/react'; +import { Box, Center, Flex, Heading, Icon, Image, Skeleton, Text, Tooltip } from '@chakra-ui/react'; import { useQuery } from '@tanstack/react-query'; import { useEffect, useMemo, useState } from 'react'; +import { GoScreenFull, GoScreenNormal } from 'react-icons/go'; import { useSearchParams } from 'react-router-dom'; import { GoBackBtn } from 'src/components/GoBackBtn'; import { localImagesPath } from 'src/constants/images'; import server from 'src/utils/axios'; import { TMangaChapters, getMangaDetails } from './getMangaDetails'; +import { useFullScreenMode } from '../hooks/useFullScreenMode'; export function MangaReaderScreen() { const [searchParams] = useSearchParams(); @@ -93,8 +95,11 @@ function MangaReader({ chapters, isLoading }: { chapters: TMangaChapters; isLoad } }, [chapters]); + const { isFullScreen, fullScreenRef, handleFullScreen } = useFullScreenMode(); + return (
- + Chapters @@ -142,24 +147,50 @@ function MangaReader({ chapters, isLoading }: { chapters: TMangaChapters; isLoad />
- - - +
+ + + + + +
+ + + + ); } @@ -307,6 +338,12 @@ function MangaChapterImages({ alt={`manga-chapter-${idx}-image`} width={'65%'} style={{ + userSelect: 'none', + msUserSelect: 'none', + MozUserSelect: 'none', + WebkitUserSelect: 'none', + msTouchSelect: 'none', + pointerEvents: 'none', borderRadius: 20, objectFit: 'contain', }}