mirror of
https://github.com/Suwayomi/Suwayomi-Server.git
synced 2026-07-03 02:44:34 -05:00
migrate to axios, front-end part of configurable ServerAddress
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
import React, { useContext, useEffect, useState } from 'react';
|
||||
import ExtensionCard from '../components/ExtensionCard';
|
||||
import NavBarTitle from '../context/NavbarTitle';
|
||||
import client from '../util/client';
|
||||
|
||||
export default function Extensions() {
|
||||
const { setTitle } = useContext(NavBarTitle);
|
||||
@@ -12,8 +13,8 @@ export default function Extensions() {
|
||||
const [extensions, setExtensions] = useState<IExtension[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
fetch('http://127.0.0.1:4567/api/v1/extension/list')
|
||||
.then((response) => response.json())
|
||||
client.get('/api/v1/extension/list')
|
||||
.then((response) => response.data)
|
||||
.then((data) => setExtensions(data));
|
||||
}, []);
|
||||
|
||||
|
||||
@@ -87,13 +87,14 @@ export default function Library() {
|
||||
);
|
||||
}, []);
|
||||
|
||||
// console.log(client.defaults.baseURL);
|
||||
// fetch the current tab
|
||||
useEffect(() => {
|
||||
tabs.forEach((tab, index) => {
|
||||
if (tab.category.order === tabNum && !tab.isFetched) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-shadow
|
||||
fetch(`http://127.0.0.1:4567/api/v1/category/${tab.category.id}`)
|
||||
.then((response) => response.json())
|
||||
client.get(`/api/v1/category/${tab.category.id}`)
|
||||
.then((response) => response.data)
|
||||
.then((data: IManga[]) => {
|
||||
const tabsClone = JSON.parse(JSON.stringify(tabs));
|
||||
tabsClone[index].mangas = data;
|
||||
@@ -122,7 +123,7 @@ export default function Library() {
|
||||
</TabPanel>
|
||||
));
|
||||
|
||||
// 160px is min-width for viewport width of >600
|
||||
// Visual Hack: 160px is min-width for viewport width of >600
|
||||
const scrollableTabs = window.innerWidth < tabs.length * 160;
|
||||
toRender = (
|
||||
<>
|
||||
|
||||
@@ -7,6 +7,7 @@ import { useParams } from 'react-router-dom';
|
||||
import ChapterCard from '../components/ChapterCard';
|
||||
import MangaDetails from '../components/MangaDetails';
|
||||
import NavBarTitle from '../context/NavbarTitle';
|
||||
import client from '../util/client';
|
||||
|
||||
export default function Manga() {
|
||||
const { id } = useParams<{id: string}>();
|
||||
@@ -16,8 +17,8 @@ export default function Manga() {
|
||||
const [chapters, setChapters] = useState<IChapter[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
fetch(`http://127.0.0.1:4567/api/v1/manga/${id}/`)
|
||||
.then((response) => response.json())
|
||||
client.get(`/api/v1/manga/${id}/`)
|
||||
.then((response) => response.data)
|
||||
.then((data: IManga) => {
|
||||
setManga(data);
|
||||
setTitle(data.title);
|
||||
@@ -25,8 +26,8 @@ export default function Manga() {
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
fetch(`http://127.0.0.1:4567/api/v1/manga/${id}/chapters`)
|
||||
.then((response) => response.json())
|
||||
client.get(`/api/v1/manga/${id}/chapters`)
|
||||
.then((response) => response.data)
|
||||
.then((data) => setChapters(data));
|
||||
}, []);
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
import React, { useContext, useEffect, useState } from 'react';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import NavBarTitle from '../context/NavbarTitle';
|
||||
import client from '../util/client';
|
||||
import useLocalStorage from '../util/useLocalStorage';
|
||||
|
||||
const style = {
|
||||
display: 'flex',
|
||||
@@ -17,14 +19,15 @@ const style = {
|
||||
const range = (n:number) => Array.from({ length: n }, (value, key) => key);
|
||||
|
||||
export default function Reader() {
|
||||
const [serverAddress] = useLocalStorage<String>('serverBaseURL', '');
|
||||
const { setTitle } = useContext(NavBarTitle);
|
||||
|
||||
const [pageCount, setPageCount] = useState<number>(-1);
|
||||
const { chapterId, mangaId } = useParams<{chapterId: string, mangaId: string}>();
|
||||
|
||||
useEffect(() => {
|
||||
fetch(`http://127.0.0.1:4567/api/v1/manga/${mangaId}/chapter/${chapterId}`)
|
||||
.then((response) => response.json())
|
||||
client.get(`/api/v1/manga/${mangaId}/chapter/${chapterId}`)
|
||||
.then((response) => response.data)
|
||||
.then((data:IChapter) => {
|
||||
setTitle(data.name);
|
||||
setPageCount(data.pageCount);
|
||||
@@ -41,7 +44,7 @@ export default function Reader() {
|
||||
|
||||
const mapped = range(pageCount).map((index) => (
|
||||
<div style={{ margin: '0 auto' }}>
|
||||
<img src={`http://127.0.0.1:4567/api/v1/manga/${mangaId}/chapter/${chapterId}/page/${index}`} alt="f" style={{ maxWidth: '100%' }} />
|
||||
<img src={`${serverAddress}/api/v1/manga/${mangaId}/chapter/${chapterId}/page/${index}`} alt="F" style={{ maxWidth: '100%' }} />
|
||||
</div>
|
||||
));
|
||||
return (
|
||||
|
||||
@@ -9,6 +9,7 @@ import Button from '@material-ui/core/Button';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import MangaGrid from '../components/MangaGrid';
|
||||
import NavBarTitle from '../context/NavbarTitle';
|
||||
import client from '../util/client';
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
root: {
|
||||
@@ -33,8 +34,8 @@ export default function SearchSingle() {
|
||||
const textInput = React.createRef<HTMLInputElement>();
|
||||
|
||||
useEffect(() => {
|
||||
fetch(`http://127.0.0.1:4567/api/v1/source/${sourceId}`)
|
||||
.then((response) => response.json())
|
||||
client.get(`/api/v1/source/${sourceId}`)
|
||||
.then((response) => response.data)
|
||||
.then((data: { name: string }) => setTitle(`Search: ${data.name}`));
|
||||
}, []);
|
||||
|
||||
@@ -54,8 +55,8 @@ export default function SearchSingle() {
|
||||
|
||||
useEffect(() => {
|
||||
if (searchTerm.length > 0) {
|
||||
fetch(`http://127.0.0.1:4567/api/v1/source/${sourceId}/search/${searchTerm}/${lastPageNum}`)
|
||||
.then((response) => response.json())
|
||||
client.get(`/api/v1/source/${sourceId}/search/${searchTerm}/${lastPageNum}`)
|
||||
.then((response) => response.data)
|
||||
.then((data: { mangaList: IManga[], hasNextPage: boolean }) => {
|
||||
if (data.mangaList.length > 0) {
|
||||
setMangas([
|
||||
|
||||
@@ -2,16 +2,21 @@
|
||||
* 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 React, { useContext } from 'react';
|
||||
import React, { useContext, useState } from 'react';
|
||||
import List from '@material-ui/core/List';
|
||||
import ListItem, { ListItemProps } from '@material-ui/core/ListItem';
|
||||
import ListItemIcon from '@material-ui/core/ListItemIcon';
|
||||
import ListItemText from '@material-ui/core/ListItemText';
|
||||
import InboxIcon from '@material-ui/icons/Inbox';
|
||||
import Brightness6Icon from '@material-ui/icons/Brightness6';
|
||||
import { ListItemSecondaryAction, Switch } from '@material-ui/core';
|
||||
import DnsIcon from '@material-ui/icons/Dns';
|
||||
import EditIcon from '@material-ui/icons/Edit';
|
||||
import {
|
||||
Button, Dialog, DialogActions, DialogContent,
|
||||
DialogContentText, IconButton, ListItemSecondaryAction, Switch, TextField,
|
||||
ListItemIcon, ListItemText,
|
||||
} from '@material-ui/core';
|
||||
import ListItem, { ListItemProps } from '@material-ui/core/ListItem';
|
||||
import NavBarTitle from '../context/NavbarTitle';
|
||||
import DarkTheme from '../context/DarkTheme';
|
||||
import useLocalStorage from '../util/useLocalStorage';
|
||||
|
||||
function ListItemLink(props: ListItemProps<'a', { button?: true }>) {
|
||||
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||
@@ -22,9 +27,26 @@ export default function Settings() {
|
||||
const { setTitle } = useContext(NavBarTitle);
|
||||
setTitle('Settings');
|
||||
const { darkTheme, setDarkTheme } = useContext(DarkTheme);
|
||||
const [serverAddress, setServerAddress] = useLocalStorage<String>('serverBaseURL', '');
|
||||
const [dialogOpen, setDialogOpen] = useState(false);
|
||||
const [dialogValue, setDialogValue] = useState(serverAddress);
|
||||
|
||||
const handleDialogOpen = () => {
|
||||
setDialogValue(serverAddress);
|
||||
setDialogOpen(true);
|
||||
};
|
||||
|
||||
const handleDialogCancel = () => {
|
||||
setDialogOpen(false);
|
||||
};
|
||||
|
||||
const handleDialogSubmit = () => {
|
||||
setDialogOpen(false);
|
||||
setServerAddress(dialogValue);
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<>
|
||||
<List component="nav" style={{ padding: 0 }}>
|
||||
<ListItemLink href="/settings/categories">
|
||||
<ListItemIcon>
|
||||
@@ -45,7 +67,49 @@ export default function Settings() {
|
||||
/>
|
||||
</ListItemSecondaryAction>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<ListItemIcon>
|
||||
<DnsIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary="Server Address" secondary={serverAddress} />
|
||||
<ListItemSecondaryAction>
|
||||
<IconButton
|
||||
onClick={() => {
|
||||
handleDialogOpen();
|
||||
}}
|
||||
>
|
||||
<EditIcon />
|
||||
</IconButton>
|
||||
|
||||
</ListItemSecondaryAction>
|
||||
</ListItem>
|
||||
</List>
|
||||
</div>
|
||||
|
||||
<Dialog open={dialogOpen} onClose={handleDialogCancel}>
|
||||
<DialogContent>
|
||||
<DialogContentText>
|
||||
Enter new category name.
|
||||
</DialogContentText>
|
||||
<TextField
|
||||
autoFocus
|
||||
margin="dense"
|
||||
id="name"
|
||||
label="Category Name"
|
||||
type="text"
|
||||
fullWidth
|
||||
value={dialogValue}
|
||||
onChange={(e) => setDialogValue(e.target.value)}
|
||||
/>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={handleDialogCancel} color="primary">
|
||||
Cancel
|
||||
</Button>
|
||||
<Button onClick={handleDialogSubmit} color="primary">
|
||||
Set
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import React, { useContext, useEffect, useState } from 'react';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import MangaGrid from '../components/MangaGrid';
|
||||
import NavBarTitle from '../context/NavbarTitle';
|
||||
import client from '../util/client';
|
||||
|
||||
export default function SourceMangas(props: { popular: boolean }) {
|
||||
const { sourceId } = useParams<{sourceId: string}>();
|
||||
@@ -15,15 +16,15 @@ export default function SourceMangas(props: { popular: boolean }) {
|
||||
const [lastPageNum, setLastPageNum] = useState<number>(1);
|
||||
|
||||
useEffect(() => {
|
||||
fetch(`http://127.0.0.1:4567/api/v1/source/${sourceId}`)
|
||||
.then((response) => response.json())
|
||||
client.get(`/api/v1/source/${sourceId}`)
|
||||
.then((response) => response.data)
|
||||
.then((data: { name: string }) => setTitle(data.name));
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const sourceType = props.popular ? 'popular' : 'latest';
|
||||
fetch(`http://127.0.0.1:4567/api/v1/source/${sourceId}/${sourceType}/${lastPageNum}`)
|
||||
.then((response) => response.json())
|
||||
client.get(`/api/v1/source/${sourceId}/${sourceType}/${lastPageNum}`)
|
||||
.then((response) => response.data)
|
||||
.then((data: { mangaList: IManga[], hasNextPage: boolean }) => {
|
||||
setMangas([
|
||||
...mangas,
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
import React, { useContext, useEffect, useState } from 'react';
|
||||
import SourceCard from '../components/SourceCard';
|
||||
import NavBarTitle from '../context/NavbarTitle';
|
||||
import client from '../util/client';
|
||||
|
||||
export default function Sources() {
|
||||
const { setTitle } = useContext(NavBarTitle);
|
||||
@@ -13,8 +14,8 @@ export default function Sources() {
|
||||
const [fetched, setFetched] = useState<boolean>(false);
|
||||
|
||||
useEffect(() => {
|
||||
fetch('http://127.0.0.1:4567/api/v1/source/list')
|
||||
.then((response) => response.json())
|
||||
client.get('/api/v1/source/list')
|
||||
.then((response) => response.data)
|
||||
.then((data) => { setSources(data); setFetched(true); });
|
||||
}, []);
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ import DialogContent from '@material-ui/core/DialogContent';
|
||||
import DialogContentText from '@material-ui/core/DialogContentText';
|
||||
import DialogTitle from '@material-ui/core/DialogTitle';
|
||||
import NavBarTitle from '../../context/NavbarTitle';
|
||||
import client from '../../util/client';
|
||||
|
||||
const getItemStyle = (isDragging, draggableStyle, palette) => ({
|
||||
// styles we need to apply on draggables
|
||||
@@ -43,7 +44,7 @@ export default function Categories() {
|
||||
setTitle('Categories');
|
||||
const [categories, setCategories] = useState([]);
|
||||
const [categoryToEdit, setCategoryToEdit] = useState(-1); // -1 means new category
|
||||
const [dialogOpen, setDialogOpen] = React.useState(false);
|
||||
const [dialogOpen, setDialogOpen] = useState(false);
|
||||
const [dialogValue, setDialogValue] = useState('');
|
||||
const theme = useTheme();
|
||||
|
||||
@@ -52,8 +53,8 @@ export default function Categories() {
|
||||
|
||||
useEffect(() => {
|
||||
if (!dialogOpen) {
|
||||
fetch('http://127.0.0.1:4567/api/v1/category/')
|
||||
.then((response) => response.json())
|
||||
client.get('/api/v1/category/')
|
||||
.then((response) => response.data)
|
||||
.then((data) => setCategories(data));
|
||||
}
|
||||
}, [updateTriggerHolder]);
|
||||
@@ -64,11 +65,8 @@ export default function Categories() {
|
||||
const formData = new FormData();
|
||||
formData.append('from', from + 1);
|
||||
formData.append('to', to + 1);
|
||||
fetch(`http://127.0.0.1:4567/api/v1/category/${category.id}/reorder`, {
|
||||
method: 'PATCH',
|
||||
mode: 'cors',
|
||||
body: formData,
|
||||
}).finally(() => triggerUpdate());
|
||||
client.post(`/api/v1/category/${category.id}/reorder`, formData)
|
||||
.finally(() => triggerUpdate());
|
||||
|
||||
// also move it in local state to avoid jarring moving behviour...
|
||||
const result = Array.from(list);
|
||||
@@ -90,48 +88,40 @@ export default function Categories() {
|
||||
));
|
||||
};
|
||||
|
||||
const handleDialogOpen = () => {
|
||||
setDialogOpen(true);
|
||||
};
|
||||
|
||||
const resetDialog = () => {
|
||||
setDialogOpen(false);
|
||||
setDialogValue('');
|
||||
setCategoryToEdit(-1);
|
||||
};
|
||||
|
||||
const handleDialogCancel = () => {
|
||||
const handleDialogOpen = () => {
|
||||
resetDialog();
|
||||
setDialogOpen(true);
|
||||
};
|
||||
|
||||
const handleDialogCancel = () => {
|
||||
setDialogOpen(false);
|
||||
};
|
||||
|
||||
const handleDialogSubmit = () => {
|
||||
resetDialog();
|
||||
setDialogOpen(false);
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('name', dialogValue);
|
||||
|
||||
if (categoryToEdit === -1) {
|
||||
fetch('http://127.0.0.1:4567/api/v1/category/', {
|
||||
method: 'POST',
|
||||
mode: 'cors',
|
||||
body: formData,
|
||||
}).finally(() => triggerUpdate());
|
||||
client.post('/api/v1/category/', formData)
|
||||
.finally(() => triggerUpdate());
|
||||
} else {
|
||||
const category = categories[categoryToEdit];
|
||||
fetch(`http://127.0.0.1:4567/api/v1/category/${category.id}`, {
|
||||
method: 'PATCH',
|
||||
mode: 'cors',
|
||||
body: formData,
|
||||
}).finally(() => triggerUpdate());
|
||||
client.patch(`/api/v1/category/${category.id}`, formData)
|
||||
.finally(() => triggerUpdate());
|
||||
}
|
||||
};
|
||||
|
||||
const deleteCategory = (index) => {
|
||||
const category = categories[index];
|
||||
fetch(`http://127.0.0.1:4567/api/v1/category/${category.id}`, {
|
||||
method: 'DELETE',
|
||||
mode: 'cors',
|
||||
}).finally(() => triggerUpdate());
|
||||
client.delete(`/api/v1/category/${category.id}`)
|
||||
.finally(() => triggerUpdate());
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -167,8 +157,8 @@ export default function Categories() {
|
||||
/>
|
||||
<IconButton
|
||||
onClick={() => {
|
||||
setCategoryToEdit(index);
|
||||
handleDialogOpen();
|
||||
setCategoryToEdit(index);
|
||||
}}
|
||||
>
|
||||
<EditIcon />
|
||||
@@ -201,7 +191,7 @@ export default function Categories() {
|
||||
>
|
||||
<AddIcon />
|
||||
</Fab>
|
||||
<Dialog open={dialogOpen} onClose={handleDialogCancel} aria-labelledby="form-dialog-title">
|
||||
<Dialog open={dialogOpen} onClose={handleDialogCancel}>
|
||||
<DialogTitle id="form-dialog-title">
|
||||
{categoryToEdit === -1 ? 'New Catalog' : `Rename: ${categories[categoryToEdit].name}`}
|
||||
</DialogTitle>
|
||||
|
||||
Reference in New Issue
Block a user