Files
suwayomi-material-you-webui/src/screens/manga/Library.tsx

145 lines
4.8 KiB
TypeScript
Raw Normal View History

/*
* Copyright (C) Contributors to the Suwayomi project
*
* This Source Code Form is subject to the terms of the Mozilla Public
2021-02-13 21:12:18 +03:30
* 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/. */
2021-09-09 17:51:22 +04:30
import { Tab, Tabs } from '@mui/material';
2021-02-13 21:12:18 +03:30
import React, { useContext, useEffect, useState } from 'react';
import NavbarContext from 'context/NavbarContext';
import client from 'util/client';
import cloneObject from 'util/cloneObject';
import EmptyView from 'components/EmptyView';
import LoadingPlaceholder from 'components/LoadingPlaceholder';
2021-10-26 12:42:30 +03:30
import TabPanel from 'components/util/TabPanel';
import LibraryOptions from '../../components/library/LibraryOptions';
import LibraryMangaGrid from '../../components/library/LibraryMangaGrid';
2021-02-13 21:12:18 +03:30
2021-02-20 01:23:52 +03:30
interface IMangaCategory {
category: ICategory
mangas: IManga[]
2021-03-07 16:27:13 +03:30
isFetched: boolean
2021-02-20 01:23:52 +03:30
}
export default function Library() {
2021-03-09 16:44:09 +03:30
const { setTitle, setAction } = useContext(NavbarContext);
useEffect(() => {
setTitle('Library'); setAction(
<>
<LibraryOptions />
</>,
);
}, []);
2021-03-09 16:44:09 +03:30
2021-08-29 20:47:57 +04:30
const [tabs, setTabs] = useState<IMangaCategory[]>();
2021-02-20 01:23:52 +03:30
const [tabNum, setTabNum] = useState<number>(0);
2021-02-13 21:12:18 +03:30
2021-02-21 04:27:41 +03:30
// a hack so MangaGrid doesn't stop working. I won't change it in case
// if I do manga pagination for library..
const [lastPageNum, setLastPageNum] = useState<number>(1);
const handleTabChange = (newTab: number) => {
setTabNum(newTab);
};
2021-02-13 21:12:18 +03:30
useEffect(() => {
2021-08-21 03:46:01 +04:30
client.get('/api/v1/category')
.then((response) => response.data)
.then((categories: ICategory[]) => {
const categoryTabs = categories.map((category) => ({
category,
mangas: [] as IManga[],
isFetched: false,
}));
setTabs(categoryTabs);
2021-08-29 20:47:57 +04:30
if (categoryTabs.length > 0) {
setTabNum(categoryTabs[0].category.order);
}
2021-08-21 03:46:01 +04:30
});
2021-02-20 01:23:52 +03:30
}, []);
2021-03-07 16:27:13 +03:30
// fetch the current tab
useEffect(() => {
2021-08-29 20:47:57 +04:30
if (tabs !== undefined) {
tabs.forEach((tab, index) => {
if (tab.category.order === tabNum && !tab.isFetched) {
// eslint-disable-next-line @typescript-eslint/no-shadow
client.get(`/api/v1/category/${tab.category.id}`)
.then((response) => response.data)
.then((data: IManga[]) => {
const tabsClone = cloneObject(tabs);
tabsClone[index].mangas = data;
tabsClone[index].isFetched = true;
setTabs(tabsClone);
});
}
});
}
}, [tabs?.length, tabNum]);
if (tabs === undefined) {
return <LoadingPlaceholder />;
2021-08-29 20:47:57 +04:30
}
2021-08-21 03:46:01 +04:30
if (tabs.length === 0) {
return <EmptyView message="Your Library is empty" />;
2021-08-21 03:46:01 +04:30
}
2021-03-07 16:27:13 +03:30
2021-02-20 01:23:52 +03:30
let toRender;
if (tabs.length > 1) {
2021-02-21 04:27:41 +03:30
// eslint-disable-next-line max-len
const tabDefines = tabs.map((tab) => (<Tab label={tab.category.name} value={tab.category.order} />));
2021-02-20 01:23:52 +03:30
2021-02-21 04:27:41 +03:30
const tabBodies = tabs.map((tab) => (
2021-10-26 12:42:30 +03:30
<TabPanel index={tab.category.order} currentIndex={tabNum}>
<LibraryMangaGrid
2021-02-20 01:23:52 +03:30
mangas={tab.mangas}
hasNextPage={false}
lastPageNum={lastPageNum}
setLastPageNum={setLastPageNum}
message="Category is Empty"
isLoading={!tab.isFetched}
2021-02-20 01:23:52 +03:30
/>
</TabPanel>
));
2021-02-20 02:28:55 +03:30
// Visual Hack: 160px is min-width for viewport width of >600
2021-02-20 02:28:55 +03:30
const scrollableTabs = window.innerWidth < tabs.length * 160;
2021-02-20 01:23:52 +03:30
toRender = (
<>
<Tabs
2021-08-29 20:47:57 +04:30
key={tabNum}
2021-02-20 01:23:52 +03:30
value={tabNum}
2021-02-21 04:27:41 +03:30
onChange={(e, newTab) => handleTabChange(newTab)}
2021-02-20 01:23:52 +03:30
indicatorColor="primary"
textColor="primary"
2021-02-20 02:28:55 +03:30
centered={!scrollableTabs}
variant={scrollableTabs ? 'scrollable' : 'fullWidth'}
2021-09-09 17:51:22 +04:30
scrollButtons
allowScrollButtonsMobile
2021-02-20 01:23:52 +03:30
>
{tabDefines}
</Tabs>
{tabBodies}
</>
);
} else {
const mangas = tabs.length === 1 ? tabs[0].mangas : [];
toRender = (
<LibraryMangaGrid
2021-02-20 01:23:52 +03:30
mangas={mangas}
hasNextPage={false}
lastPageNum={lastPageNum}
setLastPageNum={setLastPageNum}
message="Your Library is empty"
isLoading={!tabs[0].isFetched}
2021-02-20 01:23:52 +03:30
/>
);
}
return toRender;
2021-02-13 21:12:18 +03:30
}