diff --git a/src/shared/components/accordion/EventPanel.tsx b/src/shared/components/accordion/EventPanel.tsx index 71e58b2..2af92f2 100644 --- a/src/shared/components/accordion/EventPanel.tsx +++ b/src/shared/components/accordion/EventPanel.tsx @@ -1,11 +1,10 @@ import { Button, Flex, Group, Text } from '@mantine/core'; import { IconExternalLink } from '@tabler/icons-react'; +import { useTranslation } from 'react-i18next'; import { proxyApi } from '../../../services/frigate.proxy/frigate.api'; import { EventFrigate } from '../../../types/event'; import { getDurationFromTimestamps, unixTimeToDate } from '../../utils/dateUtil'; -import BlobImage from '../images/BlobImage'; import VideoPlayer from '../players/VideoPlayer'; -import { useTranslation } from 'react-i18next'; interface EventPanelProps { event: EventFrigate diff --git a/src/shared/components/accordion/EventsAccordionItem.tsx b/src/shared/components/accordion/EventsAccordionItem.tsx index 52ecfe5..b4342a4 100644 --- a/src/shared/components/accordion/EventsAccordionItem.tsx +++ b/src/shared/components/accordion/EventsAccordionItem.tsx @@ -12,6 +12,7 @@ import { routesPath } from '../../../router/routes.path'; import { proxyApi } from '../../../services/frigate.proxy/frigate.api'; import { useTranslation } from 'react-i18next'; import BlobImage from '../images/BlobImage'; +import OnScreenImage from '../images/OnScreenImage'; interface EventsAccordionItemProps { @@ -80,7 +81,7 @@ const EventsAccordionItem = ({ {!hostName ? <> : - { const [imageSrc, setImageSrc] = useState(null); - const { ref, entry } = useIntersection({ threshold: 0.1, }) - const isVisible = entry?.isIntersecting - const { data: imageBlob, refetch, isPending, isError } = useQuery({ queryKey: [src], queryFn: () => proxyApi.getImageFrigate(src), - staleTime: 60 * 1000, + staleTime: Infinity, gcTime: Infinity, - refetchInterval: isVisible ? 30 * 1000 : undefined, }); useEffect(() => { @@ -41,7 +38,11 @@ const BlobImage = ({ if (isPending || !imageSrc) return - if (isError) return + if (isError && refetchOnError) { + refetch() + } else if (isError) { + return + } return ( diff --git a/src/shared/components/images/OnScreenImage.tsx b/src/shared/components/images/OnScreenImage.tsx new file mode 100644 index 0000000..96b3db5 --- /dev/null +++ b/src/shared/components/images/OnScreenImage.tsx @@ -0,0 +1,26 @@ +import { useIntersection } from '@mantine/hooks'; +import { FC, useEffect, useState } from 'react'; +import BlobImage, { BlobImageProps } from './BlobImage'; + +const OnScreenImage: FC = ({ + ...rest +}) => { + const [renderImage, setRenderImage] = useState(false) + const { ref, entry } = useIntersection({ threshold: 0.1, }) + + useEffect(() => { + if (entry?.isIntersecting) + setRenderImage(true) + }, [entry?.isIntersecting]) + + return ( +
+ {!renderImage ? null : + + } + +
+ ); +}; + +export default OnScreenImage; \ No newline at end of file