mirror of
https://github.com/Suwayomi/Suwayomi-Server.git
synced 2026-07-02 18:34:39 -05:00
single source search done
This commit is contained in:
@@ -9,7 +9,7 @@ import Extensions from './screens/Extensions';
|
||||
import MangaList from './screens/MangaList';
|
||||
import Manga from './screens/Manga';
|
||||
import Reader from './screens/Reader';
|
||||
import Search from './screens/Search';
|
||||
import Search from './screens/SearchSingle';
|
||||
import NavBarTitle from './context/NavbarTitle';
|
||||
|
||||
export default function App() {
|
||||
@@ -22,7 +22,7 @@ export default function App() {
|
||||
<NavBar />
|
||||
|
||||
<Switch>
|
||||
<Route path="/search">
|
||||
<Route path="/sources/:sourceId/search/">
|
||||
<Search />
|
||||
</Route>
|
||||
<Route path="/extensions">
|
||||
|
||||
@@ -65,8 +65,9 @@ export default function SourceCard(props: IProps) {
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ display: 'flex' }}>
|
||||
{supportsLatest && <Button variant="outlined" style={{ marginLeft: 20 }} onClick={() => { window.location.href = `sources/${id}/latest/`; }}>Latest</Button>}
|
||||
<Button variant="outlined" style={{ marginLeft: 20 }} onClick={() => { window.location.href = `sources/${id}/popular/`; }}>Browse</Button>
|
||||
<Button variant="outlined" style={{ marginLeft: 20 }} onClick={() => { window.location.href = `/sources/${id}/search/`; }}>Search</Button>
|
||||
{supportsLatest && <Button variant="outlined" style={{ marginLeft: 20 }} onClick={() => { window.location.href = `/sources/${id}/latest/`; }}>Latest</Button>}
|
||||
<Button variant="outlined" style={{ marginLeft: 20 }} onClick={() => { window.location.href = `/sources/${id}/popular/`; }}>Browse</Button>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
@@ -48,14 +48,14 @@ export default function TemporaryDrawer({ drawerOpen, setDrawerOpen }: IProps) {
|
||||
<ListItemText primary="Sources" />
|
||||
</ListItem>
|
||||
</Link>
|
||||
<Link to="/search" style={{ color: 'inherit', textDecoration: 'none' }}>
|
||||
{/* <Link to="/search" style={{ color: 'inherit', textDecoration: 'none' }}>
|
||||
<ListItem button key="Search">
|
||||
<ListItemIcon>
|
||||
<InboxIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary="Global Search" />
|
||||
</ListItem>
|
||||
</Link>
|
||||
</Link> */}
|
||||
</List>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -19,8 +19,8 @@ export default function MangaList(props: { popular: boolean }) {
|
||||
const sourceType = props.popular ? 'popular' : 'latest';
|
||||
fetch(`http://127.0.0.1:4567/api/v1/source/${sourceId}/${sourceType}/${lastPageNum}`)
|
||||
.then((response) => response.json())
|
||||
.then((data: { title: string, thumbnail_url: string, id:number }[]) => setMangas(
|
||||
data.map((it) => ({ title: it.title, thumbnailUrl: it.thumbnail_url, id: it.id })),
|
||||
.then((data: IManga[]) => setMangas(
|
||||
data.map((it) => ({ title: it.title, thumbnailUrl: it.thumbnailUrl, id: it.id })),
|
||||
));
|
||||
}, []);
|
||||
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
import React, { useContext, useState } from 'react';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import TextField from '@material-ui/core/TextField';
|
||||
import Button from '@material-ui/core/Button';
|
||||
import MangaGrid from '../components/MangaGrid';
|
||||
import NavBarTitle from '../context/NavbarTitle';
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
root: {
|
||||
TextField: {
|
||||
margin: theme.spacing(1),
|
||||
width: '25ch',
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
export default function Search() {
|
||||
const { setTitle } = useContext(NavBarTitle);
|
||||
setTitle('Search');
|
||||
const classes = useStyles();
|
||||
const [error, setError] = useState<boolean>(false);
|
||||
const [mangas, setMangas] = useState<IManga[]>([]);
|
||||
const [message, setMessage] = useState<string>('');
|
||||
|
||||
const textInput = React.createRef<HTMLInputElement>();
|
||||
|
||||
function doSearch() {
|
||||
if (textInput.current) {
|
||||
const { value } = textInput.current;
|
||||
if (value === '') { setError(true); } else {
|
||||
setError(false);
|
||||
setMangas([]);
|
||||
setMessage('button pressed');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const mangaGrid = <MangaGrid mangas={mangas} message={message} />;
|
||||
|
||||
return (
|
||||
<>
|
||||
<form className={classes.root} noValidate autoComplete="off">
|
||||
<TextField inputRef={textInput} error={error} id="standard-basic" label="Search text.." />
|
||||
<Button variant="contained" color="primary" onClick={() => doSearch()}>
|
||||
Primary
|
||||
</Button>
|
||||
</form>
|
||||
{mangaGrid}
|
||||
</>
|
||||
);
|
||||
}
|
||||
81
webUI/react/src/screens/SearchSingle.tsx
Normal file
81
webUI/react/src/screens/SearchSingle.tsx
Normal file
@@ -0,0 +1,81 @@
|
||||
import React, { useContext, useEffect, useState } from 'react';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import TextField from '@material-ui/core/TextField';
|
||||
import Button from '@material-ui/core/Button';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import MangaGrid from '../components/MangaGrid';
|
||||
import NavBarTitle from '../context/NavbarTitle';
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
root: {
|
||||
TextField: {
|
||||
margin: theme.spacing(1),
|
||||
width: '25ch',
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
export default function SearchSingle() {
|
||||
const { setTitle } = useContext(NavBarTitle);
|
||||
const { sourceId } = useParams<{sourceId: string}>();
|
||||
const classes = useStyles();
|
||||
const [error, setError] = useState<boolean>(false);
|
||||
const [mangas, setMangas] = useState<IManga[]>([]);
|
||||
const [message, setMessage] = useState<string>('');
|
||||
const [lastPageNum] = useState<number>(1);
|
||||
const [searchTerm, setSearchTerm] = useState<string>('');
|
||||
|
||||
const textInput = React.createRef<HTMLInputElement>();
|
||||
|
||||
useEffect(() => {
|
||||
fetch(`http://127.0.0.1:4567/api/v1/source/${sourceId}`)
|
||||
.then((response) => response.json())
|
||||
.then((data: { name: string }) => setTitle(`Search: ${data.name}`));
|
||||
}, []);
|
||||
|
||||
function processInput() {
|
||||
if (textInput.current) {
|
||||
const { value } = textInput.current;
|
||||
if (value === '') {
|
||||
setError(true);
|
||||
setMessage('Type something to search');
|
||||
} else {
|
||||
setError(false);
|
||||
setSearchTerm(value);
|
||||
setMessage('');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (searchTerm.length > 0) {
|
||||
fetch(`http://127.0.0.1:4567/api/v1/source/${sourceId}/search/${searchTerm}/${lastPageNum}`)
|
||||
.then((response) => response.json())
|
||||
.then((data: IManga[]) => {
|
||||
if (data.length > 0) {
|
||||
setMangas(
|
||||
data.map((it) => (
|
||||
{ title: it.title, thumbnailUrl: it.thumbnailUrl, id: it.id }
|
||||
)),
|
||||
);
|
||||
} else {
|
||||
setMessage('search qeury returned nothing.');
|
||||
}
|
||||
});
|
||||
}
|
||||
}, [searchTerm]);
|
||||
|
||||
const mangaGrid = <MangaGrid mangas={mangas} message={message} />;
|
||||
|
||||
return (
|
||||
<>
|
||||
<form className={classes.root} noValidate autoComplete="off">
|
||||
<TextField inputRef={textInput} error={error} id="standard-basic" label="Search text.." />
|
||||
<Button variant="contained" color="primary" onClick={() => processInput()}>
|
||||
Primary
|
||||
</Button>
|
||||
</form>
|
||||
{mangaGrid}
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user