mirror of
https://github.com/tachiyomiorg/tachiyomi-extensions-inspector.git
synced 2025-01-12 16:59:08 +01:00
add page title
This commit is contained in:
parent
9a61f58043
commit
6401b946b6
@ -8,6 +8,7 @@ import ir.armor.tachidesk.util.getExtensionList
|
|||||||
import ir.armor.tachidesk.util.getManga
|
import ir.armor.tachidesk.util.getManga
|
||||||
import ir.armor.tachidesk.util.getMangaList
|
import ir.armor.tachidesk.util.getMangaList
|
||||||
import ir.armor.tachidesk.util.getPages
|
import ir.armor.tachidesk.util.getPages
|
||||||
|
import ir.armor.tachidesk.util.getSource
|
||||||
import ir.armor.tachidesk.util.getSourceList
|
import ir.armor.tachidesk.util.getSourceList
|
||||||
import ir.armor.tachidesk.util.installAPK
|
import ir.armor.tachidesk.util.installAPK
|
||||||
import ir.armor.tachidesk.util.sourceFilters
|
import ir.armor.tachidesk.util.sourceFilters
|
||||||
@ -33,6 +34,10 @@ class Main {
|
|||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
|
System.getProperties()["proxySet"] = "true"
|
||||||
|
System.getProperties()["socksProxyHost"] = "127.0.0.1"
|
||||||
|
System.getProperties()["socksProxyPort"] = "2020"
|
||||||
|
|
||||||
// make sure everything we need exists
|
// make sure everything we need exists
|
||||||
applicationSetup()
|
applicationSetup()
|
||||||
|
|
||||||
@ -75,6 +80,11 @@ class Main {
|
|||||||
ctx.json(getSourceList())
|
ctx.json(getSourceList())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
app.get("/api/v1/source/:sourceId") { ctx ->
|
||||||
|
val sourceId = ctx.pathParam("sourceId").toLong()
|
||||||
|
ctx.json(getSource(sourceId))
|
||||||
|
}
|
||||||
|
|
||||||
app.get("/api/v1/source/:sourceId/popular/:pageNum") { ctx ->
|
app.get("/api/v1/source/:sourceId/popular/:pageNum") { ctx ->
|
||||||
val sourceId = ctx.pathParam("sourceId").toLong()
|
val sourceId = ctx.pathParam("sourceId").toLong()
|
||||||
val pageNum = ctx.pathParam("pageNum").toInt()
|
val pageNum = ctx.pathParam("pageNum").toInt()
|
||||||
|
@ -53,7 +53,7 @@ fun getChapterList(mangaId: Int): List<ChapterDataClass> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getPages(chapterId: Int, mangaId: Int): List<PageDataClass> {
|
fun getPages(chapterId: Int, mangaId: Int): Pair<ChapterDataClass, List<PageDataClass>> {
|
||||||
return transaction {
|
return transaction {
|
||||||
val chapterEntry = ChapterTable.select { ChapterTable.id eq chapterId }.firstOrNull()!!
|
val chapterEntry = ChapterTable.select { ChapterTable.id eq chapterId }.firstOrNull()!!
|
||||||
assert(mangaId == chapterEntry[ChapterTable.manga].value) // sanity check
|
assert(mangaId == chapterEntry[ChapterTable.manga].value) // sanity check
|
||||||
@ -67,12 +67,24 @@ fun getPages(chapterId: Int, mangaId: Int): List<PageDataClass> {
|
|||||||
}
|
}
|
||||||
).toBlocking().first()
|
).toBlocking().first()
|
||||||
|
|
||||||
return@transaction pagesList.map {
|
val chapter = ChapterDataClass(
|
||||||
|
chapterEntry[ChapterTable.id].value,
|
||||||
|
chapterEntry[ChapterTable.url],
|
||||||
|
chapterEntry[ChapterTable.name],
|
||||||
|
chapterEntry[ChapterTable.date_upload],
|
||||||
|
chapterEntry[ChapterTable.chapter_number],
|
||||||
|
chapterEntry[ChapterTable.scanlator],
|
||||||
|
mangaId
|
||||||
|
)
|
||||||
|
|
||||||
|
val pages = pagesList.map {
|
||||||
PageDataClass(
|
PageDataClass(
|
||||||
it.index,
|
it.index,
|
||||||
getTrueImageUrl(it, source)
|
getTrueImageUrl(it, source)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return@transaction Pair(chapter, pages)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ fun getMangaList(sourceId: Long, pageNum: Int = 1, popular: Boolean): List<Manga
|
|||||||
|
|
||||||
MangaDataClass(
|
MangaDataClass(
|
||||||
mangaEntityId,
|
mangaEntityId,
|
||||||
sourceId.toLong(),
|
sourceId,
|
||||||
|
|
||||||
manga.url,
|
manga.url,
|
||||||
manga.title,
|
manga.title,
|
||||||
|
@ -80,3 +80,17 @@ fun getSourceList(): List<SourceDataClass> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getSource(sourceId: Long): SourceDataClass {
|
||||||
|
return transaction {
|
||||||
|
val source = SourceTable.select { SourceTable.id eq sourceId }.firstOrNull()!!
|
||||||
|
|
||||||
|
return@transaction SourceDataClass(
|
||||||
|
source[SourceTable.id].value.toString(),
|
||||||
|
source[SourceTable.name],
|
||||||
|
Locale(source[SourceTable.lang]).getDisplayLanguage(Locale(source[SourceTable.lang])),
|
||||||
|
ExtensionsTable.select { ExtensionsTable.id eq source[SourceTable.extension] }.first()[ExtensionsTable.iconUrl],
|
||||||
|
getHttpSource(source[SourceTable.id].value).supportsLatest
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import React, { useState } from 'react';
|
||||||
import {
|
import {
|
||||||
BrowserRouter as Router, Route, Switch,
|
BrowserRouter as Router, Route, Switch,
|
||||||
} from 'react-router-dom';
|
} from 'react-router-dom';
|
||||||
@ -10,38 +10,44 @@ import MangaList from './screens/MangaList';
|
|||||||
import Manga from './screens/Manga';
|
import Manga from './screens/Manga';
|
||||||
import Reader from './screens/Reader';
|
import Reader from './screens/Reader';
|
||||||
import Search from './screens/Search';
|
import Search from './screens/Search';
|
||||||
|
import NavBarTitle from './context/NavbarTitle';
|
||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
|
const [title, setTitle] = useState<string>('Tachidesk');
|
||||||
|
const contextValue = { title, setTitle };
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Router>
|
<Router>
|
||||||
<NavBar />
|
<NavBarTitle.Provider value={contextValue}>
|
||||||
|
<NavBar />
|
||||||
|
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route path="/search">
|
<Route path="/search">
|
||||||
<Search />
|
<Search />
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="/extensions">
|
<Route path="/extensions">
|
||||||
<Extensions />
|
<Extensions />
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="/sources/:sourceId/popular/">
|
<Route path="/sources/:sourceId/popular/">
|
||||||
<MangaList popular />
|
<MangaList popular />
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="/sources/:sourceId/latest/">
|
<Route path="/sources/:sourceId/latest/">
|
||||||
<MangaList popular={false} />
|
<MangaList popular={false} />
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="/sources">
|
<Route path="/sources">
|
||||||
<Sources />
|
<Sources />
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="/manga/:mangaId/chapter/:chapterId">
|
<Route path="/manga/:mangaId/chapter/:chapterId">
|
||||||
<Reader />
|
<Reader />
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="/manga/:id">
|
<Route path="/manga/:id">
|
||||||
<Manga />
|
<Manga />
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="/">
|
<Route path="/">
|
||||||
<Home />
|
<Home />
|
||||||
</Route>
|
</Route>
|
||||||
</Switch>
|
</Switch>
|
||||||
|
</NavBarTitle.Provider>
|
||||||
</Router>
|
</Router>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useContext, useState } from 'react';
|
||||||
import { makeStyles } from '@material-ui/core/styles';
|
import { makeStyles } from '@material-ui/core/styles';
|
||||||
import AppBar from '@material-ui/core/AppBar';
|
import AppBar from '@material-ui/core/AppBar';
|
||||||
import Toolbar from '@material-ui/core/Toolbar';
|
import Toolbar from '@material-ui/core/Toolbar';
|
||||||
@ -6,6 +6,7 @@ import Typography from '@material-ui/core/Typography';
|
|||||||
import IconButton from '@material-ui/core/IconButton';
|
import IconButton from '@material-ui/core/IconButton';
|
||||||
import MenuIcon from '@material-ui/icons/Menu';
|
import MenuIcon from '@material-ui/icons/Menu';
|
||||||
import TemporaryDrawer from './TemporaryDrawer';
|
import TemporaryDrawer from './TemporaryDrawer';
|
||||||
|
import NavBarTitle from '../context/NavbarTitle';
|
||||||
|
|
||||||
const useStyles = makeStyles((theme) => ({
|
const useStyles = makeStyles((theme) => ({
|
||||||
root: {
|
root: {
|
||||||
@ -22,6 +23,7 @@ const useStyles = makeStyles((theme) => ({
|
|||||||
export default function NavBar() {
|
export default function NavBar() {
|
||||||
const classes = useStyles();
|
const classes = useStyles();
|
||||||
const [drawerOpen, setDrawerOpen] = useState(false);
|
const [drawerOpen, setDrawerOpen] = useState(false);
|
||||||
|
const { title } = useContext(NavBarTitle);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classes.root}>
|
<div className={classes.root}>
|
||||||
@ -38,7 +40,7 @@ export default function NavBar() {
|
|||||||
<MenuIcon />
|
<MenuIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
<Typography variant="h6" className={classes.title}>
|
<Typography variant="h6" className={classes.title}>
|
||||||
Tachidesk
|
{title}
|
||||||
</Typography>
|
</Typography>
|
||||||
</Toolbar>
|
</Toolbar>
|
||||||
</AppBar>
|
</AppBar>
|
||||||
|
13
webUI/react/src/context/NavbarTitle.tsx
Normal file
13
webUI/react/src/context/NavbarTitle.tsx
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
type ContextType = {
|
||||||
|
title: string
|
||||||
|
setTitle: React.Dispatch<React.SetStateAction<string>>
|
||||||
|
};
|
||||||
|
|
||||||
|
const NavBarTitle = React.createContext<ContextType>({
|
||||||
|
title: 'Tachidesk',
|
||||||
|
setTitle: ():void => {},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default NavBarTitle;
|
@ -1,9 +1,12 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useContext, useEffect, useState } from 'react';
|
||||||
import ExtensionCard from '../components/ExtensionCard';
|
import ExtensionCard from '../components/ExtensionCard';
|
||||||
|
import NavBarTitle from '../context/NavbarTitle';
|
||||||
|
|
||||||
export default function Extensions() {
|
export default function Extensions() {
|
||||||
let mapped;
|
const { setTitle } = useContext(NavBarTitle);
|
||||||
|
setTitle('Extensions');
|
||||||
const [extensions, setExtensions] = useState<IExtension[]>([]);
|
const [extensions, setExtensions] = useState<IExtension[]>([]);
|
||||||
|
let mapped;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetch('http://127.0.0.1:4567/api/v1/extension/list')
|
fetch('http://127.0.0.1:4567/api/v1/extension/list')
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState, useContext } from 'react';
|
||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router-dom';
|
||||||
import ChapterCard from '../components/ChapterCard';
|
import ChapterCard from '../components/ChapterCard';
|
||||||
import MangaDetails from '../components/MangaDetails';
|
import MangaDetails from '../components/MangaDetails';
|
||||||
|
import NavBarTitle from '../context/NavbarTitle';
|
||||||
|
|
||||||
export default function Manga() {
|
export default function Manga() {
|
||||||
const { id } = useParams<{id: string}>();
|
const { id } = useParams<{id: string}>();
|
||||||
|
const { setTitle } = useContext(NavBarTitle);
|
||||||
|
|
||||||
const [manga, setManga] = useState<IManga>();
|
const [manga, setManga] = useState<IManga>();
|
||||||
const [chapters, setChapters] = useState<IChapter[]>([]);
|
const [chapters, setChapters] = useState<IChapter[]>([]);
|
||||||
@ -12,7 +14,10 @@ export default function Manga() {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetch(`http://127.0.0.1:4567/api/v1/manga/${id}/`)
|
fetch(`http://127.0.0.1:4567/api/v1/manga/${id}/`)
|
||||||
.then((response) => response.json())
|
.then((response) => response.json())
|
||||||
.then((data) => setManga(data));
|
.then((data: IManga) => {
|
||||||
|
setManga(data);
|
||||||
|
setTitle(data.title);
|
||||||
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -1,12 +1,20 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useContext, useEffect, useState } from 'react';
|
||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router-dom';
|
||||||
import MangaGrid from '../components/MangaGrid';
|
import MangaGrid from '../components/MangaGrid';
|
||||||
|
import NavBarTitle from '../context/NavbarTitle';
|
||||||
|
|
||||||
export default function MangaList(props: { popular: boolean }) {
|
export default function MangaList(props: { popular: boolean }) {
|
||||||
const { sourceId } = useParams<{sourceId: string}>();
|
const { sourceId } = useParams<{sourceId: string}>();
|
||||||
|
const { setTitle } = useContext(NavBarTitle);
|
||||||
const [mangas, setMangas] = useState<IManga[]>([]);
|
const [mangas, setMangas] = useState<IManga[]>([]);
|
||||||
const [lastPageNum] = useState<number>(1);
|
const [lastPageNum] = useState<number>(1);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetch(`http://127.0.0.1:4567/api/v1/source/${sourceId}`)
|
||||||
|
.then((response) => response.json())
|
||||||
|
.then((data: { name: string }) => setTitle(data.name));
|
||||||
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const sourceType = props.popular ? 'popular' : 'latest';
|
const sourceType = props.popular ? 'popular' : 'latest';
|
||||||
fetch(`http://127.0.0.1:4567/api/v1/source/${sourceId}/${sourceType}/${lastPageNum}`)
|
fetch(`http://127.0.0.1:4567/api/v1/source/${sourceId}/${sourceType}/${lastPageNum}`)
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useContext, useEffect, useState } from 'react';
|
||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router-dom';
|
||||||
|
import NavBarTitle from '../context/NavbarTitle';
|
||||||
|
|
||||||
const style = {
|
const style = {
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
@ -14,14 +15,24 @@ interface IPage {
|
|||||||
imageUrl: string
|
imageUrl: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface IData {
|
||||||
|
first: IChapter
|
||||||
|
second: IPage[]
|
||||||
|
}
|
||||||
|
|
||||||
export default function Reader() {
|
export default function Reader() {
|
||||||
|
const { setTitle } = useContext(NavBarTitle);
|
||||||
|
|
||||||
const [pages, setPages] = useState<IPage[]>([]);
|
const [pages, setPages] = useState<IPage[]>([]);
|
||||||
const { chapterId, mangaId } = useParams<{chapterId: string, mangaId: string}>();
|
const { chapterId, mangaId } = useParams<{chapterId: string, mangaId: string}>();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetch(`http://127.0.0.1:4567/api/v1/manga/${mangaId}/chapter/${chapterId}`)
|
fetch(`http://127.0.0.1:4567/api/v1/manga/${mangaId}/chapter/${chapterId}`)
|
||||||
.then((response) => response.json())
|
.then((response) => response.json())
|
||||||
.then((data) => setPages(data));
|
.then((data:IData) => {
|
||||||
|
setTitle(data.first.name);
|
||||||
|
setPages(data.second);
|
||||||
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
pages.sort((a, b) => (a.index - b.index));
|
pages.sort((a, b) => (a.index - b.index));
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useContext, useState } from 'react';
|
||||||
import { makeStyles } from '@material-ui/core/styles';
|
import { makeStyles } from '@material-ui/core/styles';
|
||||||
import TextField from '@material-ui/core/TextField';
|
import TextField from '@material-ui/core/TextField';
|
||||||
import Button from '@material-ui/core/Button';
|
import Button from '@material-ui/core/Button';
|
||||||
import MangaGrid from '../components/MangaGrid';
|
import MangaGrid from '../components/MangaGrid';
|
||||||
|
import NavBarTitle from '../context/NavbarTitle';
|
||||||
|
|
||||||
const useStyles = makeStyles((theme) => ({
|
const useStyles = makeStyles((theme) => ({
|
||||||
root: {
|
root: {
|
||||||
@ -14,6 +15,8 @@ const useStyles = makeStyles((theme) => ({
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
export default function Search() {
|
export default function Search() {
|
||||||
|
const { setTitle } = useContext(NavBarTitle);
|
||||||
|
setTitle('Search');
|
||||||
const classes = useStyles();
|
const classes = useStyles();
|
||||||
const [error, setError] = useState<boolean>(false);
|
const [error, setError] = useState<boolean>(false);
|
||||||
const [mangas, setMangas] = useState<IManga[]>([]);
|
const [mangas, setMangas] = useState<IManga[]>([]);
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useContext, useEffect, useState } from 'react';
|
||||||
import SourceCard from '../components/SourceCard';
|
import SourceCard from '../components/SourceCard';
|
||||||
|
import NavBarTitle from '../context/NavbarTitle';
|
||||||
|
|
||||||
export default function Sources() {
|
export default function Sources() {
|
||||||
let mapped;
|
const { setTitle } = useContext(NavBarTitle);
|
||||||
|
setTitle('Sources');
|
||||||
const [sources, setSources] = useState<ISource[]>([]);
|
const [sources, setSources] = useState<ISource[]>([]);
|
||||||
|
let mapped;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetch('http://127.0.0.1:4567/api/v1/source/list')
|
fetch('http://127.0.0.1:4567/api/v1/source/list')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user