From 2d51efd71612ec969b83c62d6aa0dac6df9391a3 Mon Sep 17 00:00:00 2001 From: sct Date: Tue, 8 Dec 2020 02:11:14 +0000 Subject: [PATCH] feat(frontend): only load request/tmdb cards when in the browser view --- README.md | 1 + package.json | 1 + src/components/RequestCard/index.tsx | 12 ++++++++++-- src/components/RequestList/RequestItem/index.tsx | 8 ++++++-- src/components/TitleCard/TmdbTitleCard.tsx | 12 ++++++++++-- yarn.lock | 5 +++++ 6 files changed, 33 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index f6cb6ae46..c414c996a 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ Overseerr

+Overseerr Release Overseerr CI Discord diff --git a/package.json b/package.json index 03d7ca99e..cfca949ac 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "pug": "^3.0.0", "react": "16.13.1", "react-dom": "16.13.1", + "react-intersection-observer": "^8.31.0", "react-intl": "^5.8.5", "react-spring": "^8.0.27", "react-toast-notifications": "^2.4.0", diff --git a/src/components/RequestCard/index.tsx b/src/components/RequestCard/index.tsx index 14ecac074..ee305e5c8 100644 --- a/src/components/RequestCard/index.tsx +++ b/src/components/RequestCard/index.tsx @@ -1,4 +1,5 @@ import React, { useContext, useState } from 'react'; +import { useInView } from 'react-intersection-observer'; import type { MediaRequest } from '../../../server/entity/MediaRequest'; import type { TvDetails } from '../../../server/models/Tv'; import type { MovieDetails } from '../../../server/models/Movie'; @@ -42,6 +43,9 @@ interface RequestCardProps { } const RequestCard: React.FC = ({ request }) => { + const { ref, inView } = useInView({ + triggerOnce: true, + }); const intl = useIntl(); const { hasPermission } = useUser(); const { locale } = useContext(LanguageContext); @@ -50,7 +54,7 @@ const RequestCard: React.FC = ({ request }) => { ? `/api/v1/movie/${request.media.tmdbId}` : `/api/v1/tv/${request.media.tmdbId}`; const { data: title, error } = useSWR( - `${url}?language=${locale}` + inView ? `${url}?language=${locale}` : null ); const { data: requestData, error: requestError, revalidate } = useSWR< MediaRequest @@ -67,7 +71,11 @@ const RequestCard: React.FC = ({ request }) => { }; if (!title && !error) { - return ; + return ( +

+ +
+ ); } if (!requestData && !requestError) { diff --git a/src/components/RequestList/RequestItem/index.tsx b/src/components/RequestList/RequestItem/index.tsx index e00b022f1..a36037d39 100644 --- a/src/components/RequestList/RequestItem/index.tsx +++ b/src/components/RequestList/RequestItem/index.tsx @@ -1,4 +1,5 @@ import React, { useContext } from 'react'; +import { useInView } from 'react-intersection-observer'; import type { MediaRequest } from '../../../../server/entity/MediaRequest'; import { useIntl, @@ -36,6 +37,9 @@ interface RequestItemProps { } const RequestItem: React.FC = ({ request, onDelete }) => { + const { ref, inView } = useInView({ + triggerOnce: true, + }); const intl = useIntl(); const { hasPermission } = useUser(); const { locale } = useContext(LanguageContext); @@ -44,7 +48,7 @@ const RequestItem: React.FC = ({ request, onDelete }) => { ? `/api/v1/movie/${request.media.tmdbId}` : `/api/v1/tv/${request.media.tmdbId}`; const { data: title, error } = useSWR( - `${url}?language=${locale}` + inView ? `${url}?language=${locale}` : null ); const { data: requestData, error: requestError, revalidate } = useSWR< MediaRequest @@ -68,7 +72,7 @@ const RequestItem: React.FC = ({ request, onDelete }) => { if (!title && !error) { return ( - + ); diff --git a/src/components/TitleCard/TmdbTitleCard.tsx b/src/components/TitleCard/TmdbTitleCard.tsx index 8370a8125..40325a30b 100644 --- a/src/components/TitleCard/TmdbTitleCard.tsx +++ b/src/components/TitleCard/TmdbTitleCard.tsx @@ -1,4 +1,5 @@ import React, { useContext } from 'react'; +import { useInView } from 'react-intersection-observer'; import useSWR from 'swr'; import type { MovieDetails } from '../../../server/models/Movie'; import type { TvDetails } from '../../../server/models/Tv'; @@ -15,15 +16,22 @@ const isMovie = (movie: MovieDetails | TvDetails): movie is MovieDetails => { }; const TmdbTitleCard: React.FC = ({ tmdbId, type }) => { + const { ref, inView } = useInView({ + triggerOnce: true, + }); const { locale } = useContext(LanguageContext); const url = type === 'movie' ? `/api/v1/movie/${tmdbId}` : `/api/v1/tv/${tmdbId}`; const { data: title, error } = useSWR( - `${url}?language=${locale}` + inView ? `${url}?language=${locale}` : null ); if (!title && !error) { - return ; + return ( +
+ +
+ ); } if (!title) { diff --git a/yarn.lock b/yarn.lock index 9feb2dcf2..6c43d07c7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11160,6 +11160,11 @@ react-fast-compare@^2.0.1: resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-2.0.4.tgz#e84b4d455b0fec113e0402c329352715196f81f9" integrity sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw== +react-intersection-observer@^8.31.0: + version "8.31.0" + resolved "https://registry.yarnpkg.com/react-intersection-observer/-/react-intersection-observer-8.31.0.tgz#0ed21aaf93c4c0475b22b0ccaba6169076d01605" + integrity sha512-XraIC/tkrD9JtrmVA7ypEN1QIpKc52mXBH1u/bz/aicRLo8QQEJQAMUTb8mz4B6dqpPwyzgjrr7Ljv/2ACDtqw== + react-intl@^5.8.5: version "5.8.5" resolved "https://registry.yarnpkg.com/react-intl/-/react-intl-5.8.5.tgz#bc5dfab259049830621e129b8bffb1ac33ef4124"