diff --git a/src/components/MangaGrid.tsx b/src/components/MangaGrid.tsx index d06da71b..80755082 100644 --- a/src/components/MangaGrid.tsx +++ b/src/components/MangaGrid.tsx @@ -9,7 +9,6 @@ import React, { ForwardedRef, forwardRef, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react'; import Grid, { GridTypeMap } from '@mui/material/Grid'; import Box from '@mui/material/Box'; -import Typography from '@mui/material/Typography'; import { GridItemProps, GridStateSnapshot, VirtuosoGrid } from 'react-virtuoso'; import { useLocation } from 'react-router-dom'; import { EmptyView } from '@/components/util/EmptyView'; @@ -212,9 +211,9 @@ const VerticalGrid = forwardRef( }, ); -export interface IMangaGridProps extends Omit { - message?: string; - messageExtra?: JSX.Element; +export interface IMangaGridProps + extends Omit, + Partial> { hasNextPage: boolean; loadMore: () => void; horizontal?: boolean | undefined; @@ -237,6 +236,7 @@ export const MangaGrid: React.FC = (props) => { selectedMangaIds, handleSelection, mode, + retry, } = props; const gridRef = useRef(null); @@ -314,20 +314,7 @@ export const MangaGrid: React.FC = (props) => { const hasNoItems = !isLoading && mangas.length === 0; if (hasNoItems) { - if (noFaces) { - return ( - - {message} - {messageExtra} - - ); - } - - return ; + return ; } return ( @@ -370,8 +357,3 @@ export const MangaGrid: React.FC = (props) => { ); }; - -MangaGrid.defaultProps = { - message: '', - messageExtra: undefined, -}; diff --git a/src/components/library/LibraryMangaGrid.tsx b/src/components/library/LibraryMangaGrid.tsx index e2a14151..b1187d71 100644 --- a/src/components/library/LibraryMangaGrid.tsx +++ b/src/components/library/LibraryMangaGrid.tsx @@ -14,21 +14,18 @@ import { useLibraryOptionsContext } from '@/components/context/LibraryOptionsCon import { IMangaGridProps, MangaGrid } from '@/components/MangaGrid'; interface LibraryMangaGridProps - extends Required> { + extends Required>, + Pick { mangas: TManga[]; showFilteredOutMessage: boolean; isLoading: boolean; - message?: string; } export const LibraryMangaGrid: React.FC = ({ - mangas, showFilteredOutMessage, - isLoading, message, - isSelectModeActive, - selectedMangaIds, - handleSelection, + messageExtra, + ...gridProps }) => { const { t } = useTranslation(); @@ -42,15 +39,12 @@ export const LibraryMangaGrid: React.FC = ({ return ( undefined} message={showFilteredOutMessage ? t('library.error.label.no_matches') : message} + messageExtra={showFilteredOutMessage ? undefined : messageExtra} gridLayout={options.gridLayout} - isSelectModeActive={isSelectModeActive} - selectedMangaIds={selectedMangaIds} - handleSelection={handleSelection} /> ); }; diff --git a/src/components/util/EmptyView.tsx b/src/components/util/EmptyView.tsx index 7bf24f50..58d51013 100644 --- a/src/components/util/EmptyView.tsx +++ b/src/components/util/EmptyView.tsx @@ -27,9 +27,10 @@ interface IProps { message: string; messageExtra?: JSX.Element | string; retry?: () => void; + noFaces?: boolean; } -export function EmptyView({ message, messageExtra, retry }: IProps) { +export function EmptyView({ message, messageExtra, retry, noFaces }: IProps) { const { t } = useTranslation(); const theme = useTheme(); const isMobileWidth = useMediaQuery(theme.breakpoints.down('sm')); @@ -47,9 +48,11 @@ export function EmptyView({ message, messageExtra, retry }: IProps) { alignItems: 'center', }} > - - {errorFace} - + {!noFaces && ( + + {errorFace} + + )} {retry && } {message} {messageExtra} diff --git a/src/screens/Library.tsx b/src/screens/Library.tsx index 7a37181f..617818ab 100644 --- a/src/screens/Library.tsx +++ b/src/screens/Library.tsx @@ -9,7 +9,7 @@ import Chip from '@mui/material/Chip'; import Tab from '@mui/material/Tab'; import { styled } from '@mui/material/styles'; -import React, { useContext, useEffect, useMemo, useState } from 'react'; +import React, { useCallback, useContext, useEffect, useMemo, useState } from 'react'; import { useQueryParam, NumberParam } from 'use-query-params'; import { useTranslation } from 'react-i18next'; import { requestManager } from '@/lib/requests/RequestManager.ts'; @@ -31,6 +31,7 @@ import { PARTIAL_MANGA_FIELDS } from '@/lib/graphql/Fragments.ts'; import { MangaActionMenuItems } from '@/components/manga/MangaActionMenuItems.tsx'; import { TabsMenu } from '@/components/tabs/TabsMenu.tsx'; import { TabsWrapper } from '@/components/tabs/TabsWrapper.tsx'; +import { defaultPromiseErrorHandler } from '@/util/defaultPromiseErrorHandler.ts'; const TitleWithSizeTag = styled('span')({ display: 'flex', @@ -49,7 +50,8 @@ export function Library() { data: categoriesResponse, error: tabsError, loading: areCategoriesLoading, - } = requestManager.useGetCategories(); + refetch: refetchCategories, + } = requestManager.useGetCategories({ notifyOnNetworkStatusChange: true }); const tabsData = categoriesResponse?.categories.nodes.filter( (category) => category.id !== 0 || (category.id === 0 && category.mangas.totalCount), ); @@ -66,10 +68,16 @@ export function Library() { data: categoryMangaResponse, error: mangaError, loading: mangaLoading, - } = requestManager.useGetCategoryMangas(activeTab?.id, { skip: !activeTab }); + refetch: refetchCategoryMangas, + } = requestManager.useGetCategoryMangas(activeTab?.id, { skip: !activeTab, notifyOnNetworkStatusChange: true }); const categoryMangas = categoryMangaResponse?.mangas.nodes ?? []; const { visibleMangas: mangas, showFilteredOutMessage } = useGetVisibleLibraryMangas(categoryMangas); + const retryFetchCategoryMangas = useCallback( + () => refetchCategoryMangas().catch(defaultPromiseErrorHandler('Library::refetchCategoryMangas')), + [refetchCategoryMangas, activeTab], + ); + const mangaIds = useMemo(() => mangas.map((manga) => manga.id), [mangas]); const [isSelectModeActive, setIsSelectModeActive] = useState(false); @@ -189,7 +197,8 @@ export function Library() { return ( refetchCategories().catch(defaultPromiseErrorHandler('Library::refetchCategories'))} /> ); } @@ -207,12 +216,14 @@ export function Library() { <> {selectionFab} @@ -238,23 +249,21 @@ export function Library() { {tabs.map((tab) => ( - {tab === activeTab && - (mangaError ? ( - - ) : ( - - ))} + {tab === activeTab && ( + + )} ))} {selectionFab}