mirror of
https://github.com/tachiyomiorg/tachiyomi-extensions-inspector.git
synced 2024-12-24 15:51:49 +01:00
better messages, axios client
This commit is contained in:
parent
954084bd82
commit
7157e07328
@ -8,6 +8,7 @@
|
||||
"@testing-library/jest-dom": "^5.11.4",
|
||||
"@testing-library/react": "^11.1.0",
|
||||
"@testing-library/user-event": "^12.1.10",
|
||||
"axios": "^0.21.1",
|
||||
"fontsource-roboto": "^4.0.0",
|
||||
"react": "^17.0.1",
|
||||
"react-beautiful-dnd": "^13.0.0",
|
||||
|
@ -18,7 +18,7 @@ export default function Extensions() {
|
||||
}, []);
|
||||
|
||||
if (extensions.length === 0) {
|
||||
return <h3>wait</h3>;
|
||||
return <h3>loading...</h3>;
|
||||
}
|
||||
return <>{extensions.map((it) => <ExtensionCard extension={it} />)}</>;
|
||||
}
|
||||
|
@ -6,10 +6,12 @@ import { Tab, Tabs } from '@material-ui/core';
|
||||
import React, { useContext, useEffect, useState } from 'react';
|
||||
import MangaGrid from '../components/MangaGrid';
|
||||
import NavBarTitle from '../context/NavbarTitle';
|
||||
import client from '../util/client';
|
||||
|
||||
interface IMangaCategory {
|
||||
category: ICategory
|
||||
mangas: IManga[]
|
||||
isFetched: boolean
|
||||
}
|
||||
|
||||
interface TabPanelProps {
|
||||
@ -46,66 +48,62 @@ export default function Library() {
|
||||
setTitle('Library');
|
||||
}, []);
|
||||
|
||||
const handleTabChange = (newTab: number) => {
|
||||
setTabNum(newTab);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
Promise.all<IManga[], ICategory[]>([
|
||||
client.get('/api/v1/library').then((response) => response.data),
|
||||
client.get('/api/v1/category').then((response) => response.data),
|
||||
])
|
||||
.then(
|
||||
([libraryMangas, categories]) => {
|
||||
const categoryTabs = categories.map((category) => ({
|
||||
category,
|
||||
mangas: [] as IManga[],
|
||||
isFetched: false,
|
||||
}));
|
||||
|
||||
if (libraryMangas.length > 0 || categoryTabs.length === 0) {
|
||||
const defaultCategoryTab = {
|
||||
category: {
|
||||
name: 'Default',
|
||||
isLanding: true,
|
||||
order: 0,
|
||||
id: -1,
|
||||
},
|
||||
mangas: libraryMangas,
|
||||
isFetched: true,
|
||||
};
|
||||
setTabs(
|
||||
[defaultCategoryTab, ...categoryTabs],
|
||||
);
|
||||
} else {
|
||||
setTabs(categoryTabs);
|
||||
setTabNum(1);
|
||||
}
|
||||
},
|
||||
);
|
||||
}, []);
|
||||
|
||||
// fetch the current tab
|
||||
useEffect(() => {
|
||||
tabs.forEach((tab, index) => {
|
||||
if (tab.category.order === tabNum && !tab.isFetched) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-shadow
|
||||
const fetchAndSetMangas = (tabs: IMangaCategory[], tab: IMangaCategory, index: number) => {
|
||||
fetch(`http://127.0.0.1:4567/api/v1/category/${tab.category.id}`)
|
||||
.then((response) => response.json())
|
||||
.then((data: IManga[]) => {
|
||||
const tabsClone = JSON.parse(JSON.stringify(tabs));
|
||||
tabsClone[index].mangas = data;
|
||||
tabsClone[index].isFetched = true;
|
||||
|
||||
setTabs(tabsClone); // clone the object
|
||||
});
|
||||
};
|
||||
|
||||
const handleTabChange = (newTab: number) => {
|
||||
setTabNum(newTab);
|
||||
tabs.forEach((tab, index) => {
|
||||
if (tab.category.order === newTab && tab.mangas.length === 0) {
|
||||
// mangas are empty, fetch the mangas
|
||||
fetchAndSetMangas(tabs, tab, index);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetch('http://127.0.0.1:4567/api/v1/library')
|
||||
.then((response) => response.json())
|
||||
.then((data: IManga[]) => {
|
||||
// if some manga with no category exist, they will be added under a virtual category
|
||||
if (data.length > 0) {
|
||||
return [
|
||||
{
|
||||
category: {
|
||||
name: 'Default', isLanding: true, order: 0, id: -1,
|
||||
},
|
||||
mangas: data,
|
||||
},
|
||||
]; // will set state on the next fetch
|
||||
}
|
||||
|
||||
// no default category so the first tab is 1
|
||||
setTabNum(1);
|
||||
return [];
|
||||
})
|
||||
.then(
|
||||
(newTabs: IMangaCategory[]) => {
|
||||
fetch('http://127.0.0.1:4567/api/v1/category')
|
||||
.then((response) => response.json())
|
||||
.then((data: ICategory[]) => {
|
||||
const mangaCategories = data.map((category) => ({
|
||||
category,
|
||||
mangas: [] as IManga[],
|
||||
}));
|
||||
const newNewTabs = [...newTabs, ...mangaCategories];
|
||||
setTabs(newNewTabs);
|
||||
|
||||
// if no default category, we must fetch the first tab now...
|
||||
// eslint-disable-next-line max-len
|
||||
if (newTabs.length === 0) { fetchAndSetMangas(newNewTabs, newNewTabs[0], 0); }
|
||||
});
|
||||
},
|
||||
);
|
||||
}, []);
|
||||
}, [tabNum]);
|
||||
|
||||
let toRender;
|
||||
if (tabs.length > 1) {
|
||||
@ -119,6 +117,7 @@ export default function Library() {
|
||||
hasNextPage={false}
|
||||
lastPageNum={lastPageNum}
|
||||
setLastPageNum={setLastPageNum}
|
||||
message={tab.isFetched ? 'Category is Empty' : 'Loading...'}
|
||||
/>
|
||||
</TabPanel>
|
||||
));
|
||||
@ -149,6 +148,7 @@ export default function Library() {
|
||||
hasNextPage={false}
|
||||
lastPageNum={lastPageNum}
|
||||
setLastPageNum={setLastPageNum}
|
||||
message={tabs.length > 0 ? 'Library is Empty' : undefined}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -10,15 +10,17 @@ export default function Sources() {
|
||||
const { setTitle } = useContext(NavBarTitle);
|
||||
setTitle('Sources');
|
||||
const [sources, setSources] = useState<ISource[]>([]);
|
||||
const [fetched, setFetched] = useState<boolean>(false);
|
||||
|
||||
useEffect(() => {
|
||||
fetch('http://127.0.0.1:4567/api/v1/source/list')
|
||||
.then((response) => response.json())
|
||||
.then((data) => setSources(data));
|
||||
.then((data) => { setSources(data); setFetched(true); });
|
||||
}, []);
|
||||
|
||||
if (sources.length === 0) {
|
||||
return (<h3>wait</h3>);
|
||||
if (fetched) return (<h3>No sources found. Install Some Extensions first.</h3>);
|
||||
return (<h3>loading...</h3>);
|
||||
}
|
||||
return <>{sources.map((it) => <SourceCard source={it} />)}</>;
|
||||
}
|
||||
|
10
webUI/react/src/util/client.tsx
Normal file
10
webUI/react/src/util/client.tsx
Normal file
@ -0,0 +1,10 @@
|
||||
import axios from 'axios';
|
||||
import storage from './storage';
|
||||
|
||||
const clientMaker = () => axios.create({
|
||||
baseURL: storage.getItem('baseURL', 'http://127.0.0.1:4567'),
|
||||
});
|
||||
|
||||
const client = clientMaker();
|
||||
|
||||
export default client;
|
22
webUI/react/src/util/storage.tsx
Normal file
22
webUI/react/src/util/storage.tsx
Normal file
@ -0,0 +1,22 @@
|
||||
function getItem<T>(key: string, defaultValue: T) : T {
|
||||
try {
|
||||
const item = window.localStorage.getItem(key);
|
||||
|
||||
if (item !== null) { return JSON.parse(item); }
|
||||
|
||||
window.localStorage.setItem(key, JSON.stringify(defaultValue));
|
||||
} finally {
|
||||
// eslint-disable-next-line no-unsafe-finally
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
function setItem<T>(key: string, value: T): void {
|
||||
try {
|
||||
window.localStorage.setItem(key, JSON.stringify(value));
|
||||
|
||||
// eslint-disable-next-line no-empty
|
||||
} catch (error) { }
|
||||
}
|
||||
|
||||
export default { getItem, setItem };
|
@ -2625,6 +2625,13 @@ axe-core@^4.0.2:
|
||||
resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.1.1.tgz#70a7855888e287f7add66002211a423937063eaf"
|
||||
integrity sha512-5Kgy8Cz6LPC9DJcNb3yjAXTu3XihQgEdnIg50c//zOC/MyLP0Clg+Y8Sh9ZjjnvBrDZU4DgXS9C3T9r4/scGZQ==
|
||||
|
||||
axios@^0.21.1:
|
||||
version "0.21.1"
|
||||
resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8"
|
||||
integrity sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==
|
||||
dependencies:
|
||||
follow-redirects "^1.10.0"
|
||||
|
||||
axobject-query@^2.2.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be"
|
||||
@ -5233,6 +5240,11 @@ follow-redirects@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.1.tgz#5f69b813376cee4fd0474a3aba835df04ab763b7"
|
||||
integrity sha512-SSG5xmZh1mkPGyKzjZP8zLjltIfpW32Y5QpdNJyjcfGxK3qo3NDDkZOZSFiGn1A6SclQxY9GzEwAHQ3dmYRWpg==
|
||||
|
||||
follow-redirects@^1.10.0:
|
||||
version "1.13.3"
|
||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.3.tgz#e5598ad50174c1bc4e872301e82ac2cd97f90267"
|
||||
integrity sha512-DUgl6+HDzB0iEptNQEXLx/KhTmDb8tZUHSeLqpnjpknR70H0nC2t9N73BK6fN4hOvJ84pKlIQVQ4k5FFlBedKA==
|
||||
|
||||
fontsource-roboto@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fontsource-roboto/-/fontsource-roboto-4.0.0.tgz#35eacd4fb8d90199053c0eec9b34a57fb79cd820"
|
||||
|
Loading…
Reference in New Issue
Block a user