/* * Copyright (C) Contributors to the Suwayomi project * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ import { Tab, Tabs } from '@mui/material'; import React, { useContext, useEffect, useState } from 'react'; import NavbarContext from 'components/context/NavbarContext'; import EmptyView from 'components/util/EmptyView'; import LoadingPlaceholder from 'components/util/LoadingPlaceholder'; import TabPanel from 'components/util/TabPanel'; import LibraryToolbarMenu from 'components/library/LibraryToolbarMenu'; import LibraryMangaGrid from 'components/library/LibraryMangaGrid'; import AppbarSearch from 'components/util/AppbarSearch'; import { useQueryParam, NumberParam } from 'use-query-params'; import { useQuery } from 'util/client'; import UpdateChecker from 'components/library/UpdateChecker'; import { useTranslation } from 'react-i18next'; import { ICategory, IManga } from 'typings'; export default function Library() { const { t } = useTranslation(); const [lastLibraryUpdate, setLastLibraryUpdate] = useState(Date.now()); const { data: tabsData, error: tabsError, loading } = useQuery('/api/v1/category'); const tabs = tabsData ?? []; const [tabSearchParam, setTabSearchParam] = useQueryParam('tab', NumberParam); const activeTab = tabs.find((tab) => tab.order === tabSearchParam) ?? tabs[0]; const { data: mangaData, error: mangaError, loading: mangaLoading, } = useQuery(`/api/v1/category/${activeTab?.id}`, { isPaused: () => activeTab == null, }); const mangas = mangaData ?? []; const { setTitle, setAction } = useContext(NavbarContext); useEffect(() => { setTitle(t('library.title')); setAction( <> , ); return () => { setTitle(''); setAction(null); }; }, [t]); const handleTabChange = (newTab: number) => { setTabSearchParam(newTab === 0 ? undefined : newTab); }; if (tabsError != null) { return ( ); } if (loading) { return ; } if (tabs.length === 0) { return ; } if (tabs.length === 1) { return ( ); } // Visual Hack: 160px is min-width for viewport width of >600 const scrollableTabs = window.innerWidth < tabs.length * 160; return ( <> handleTabChange(newTab)} indicatorColor="primary" textColor="primary" centered={!scrollableTabs} variant={scrollableTabs ? 'scrollable' : 'fullWidth'} scrollButtons allowScrollButtonsMobile > {tabs.map((tab) => ( ))} {tabs.map((tab) => ( {tab === activeTab && (mangaError ? ( ) : ( ))} ))} ); }