add page title

This commit is contained in:
Aria Moradi 2021-01-22 17:00:33 +03:30
parent 9a61f58043
commit 6401b946b6
13 changed files with 133 additions and 43 deletions

View File

@ -8,6 +8,7 @@ import ir.armor.tachidesk.util.getExtensionList
import ir.armor.tachidesk.util.getManga
import ir.armor.tachidesk.util.getMangaList
import ir.armor.tachidesk.util.getPages
import ir.armor.tachidesk.util.getSource
import ir.armor.tachidesk.util.getSourceList
import ir.armor.tachidesk.util.installAPK
import ir.armor.tachidesk.util.sourceFilters
@ -33,6 +34,10 @@ class Main {
@JvmStatic
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
applicationSetup()
@ -75,6 +80,11 @@ class Main {
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 ->
val sourceId = ctx.pathParam("sourceId").toLong()
val pageNum = ctx.pathParam("pageNum").toInt()

View File

@ -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 {
val chapterEntry = ChapterTable.select { ChapterTable.id eq chapterId }.firstOrNull()!!
assert(mangaId == chapterEntry[ChapterTable.manga].value) // sanity check
@ -67,12 +67,24 @@ fun getPages(chapterId: Int, mangaId: Int): List<PageDataClass> {
}
).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(
it.index,
getTrueImageUrl(it, source)
)
}
return@transaction Pair(chapter, pages)
}
}

View File

@ -40,7 +40,7 @@ fun getMangaList(sourceId: Long, pageNum: Int = 1, popular: Boolean): List<Manga
MangaDataClass(
mangaEntityId,
sourceId.toLong(),
sourceId,
manga.url,
manga.title,

View File

@ -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
)
}
}

View File

@ -1,4 +1,4 @@
import React from 'react';
import React, { useState } from 'react';
import {
BrowserRouter as Router, Route, Switch,
} from 'react-router-dom';
@ -10,38 +10,44 @@ import MangaList from './screens/MangaList';
import Manga from './screens/Manga';
import Reader from './screens/Reader';
import Search from './screens/Search';
import NavBarTitle from './context/NavbarTitle';
export default function App() {
const [title, setTitle] = useState<string>('Tachidesk');
const contextValue = { title, setTitle };
return (
<Router>
<NavBar />
<NavBarTitle.Provider value={contextValue}>
<NavBar />
<Switch>
<Route path="/search">
<Search />
</Route>
<Route path="/extensions">
<Extensions />
</Route>
<Route path="/sources/:sourceId/popular/">
<MangaList popular />
</Route>
<Route path="/sources/:sourceId/latest/">
<MangaList popular={false} />
</Route>
<Route path="/sources">
<Sources />
</Route>
<Route path="/manga/:mangaId/chapter/:chapterId">
<Reader />
</Route>
<Route path="/manga/:id">
<Manga />
</Route>
<Route path="/">
<Home />
</Route>
</Switch>
<Switch>
<Route path="/search">
<Search />
</Route>
<Route path="/extensions">
<Extensions />
</Route>
<Route path="/sources/:sourceId/popular/">
<MangaList popular />
</Route>
<Route path="/sources/:sourceId/latest/">
<MangaList popular={false} />
</Route>
<Route path="/sources">
<Sources />
</Route>
<Route path="/manga/:mangaId/chapter/:chapterId">
<Reader />
</Route>
<Route path="/manga/:id">
<Manga />
</Route>
<Route path="/">
<Home />
</Route>
</Switch>
</NavBarTitle.Provider>
</Router>
);
}

View File

@ -1,4 +1,4 @@
import React, { useState } from 'react';
import React, { useContext, useState } from 'react';
import { makeStyles } from '@material-ui/core/styles';
import AppBar from '@material-ui/core/AppBar';
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 MenuIcon from '@material-ui/icons/Menu';
import TemporaryDrawer from './TemporaryDrawer';
import NavBarTitle from '../context/NavbarTitle';
const useStyles = makeStyles((theme) => ({
root: {
@ -22,6 +23,7 @@ const useStyles = makeStyles((theme) => ({
export default function NavBar() {
const classes = useStyles();
const [drawerOpen, setDrawerOpen] = useState(false);
const { title } = useContext(NavBarTitle);
return (
<div className={classes.root}>
@ -38,7 +40,7 @@ export default function NavBar() {
<MenuIcon />
</IconButton>
<Typography variant="h6" className={classes.title}>
Tachidesk
{title}
</Typography>
</Toolbar>
</AppBar>

View 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;

View File

@ -1,9 +1,12 @@
import React, { useEffect, useState } from 'react';
import React, { useContext, useEffect, useState } from 'react';
import ExtensionCard from '../components/ExtensionCard';
import NavBarTitle from '../context/NavbarTitle';
export default function Extensions() {
let mapped;
const { setTitle } = useContext(NavBarTitle);
setTitle('Extensions');
const [extensions, setExtensions] = useState<IExtension[]>([]);
let mapped;
useEffect(() => {
fetch('http://127.0.0.1:4567/api/v1/extension/list')

View File

@ -1,10 +1,12 @@
import React, { useEffect, useState } from 'react';
import React, { useEffect, useState, useContext } from 'react';
import { useParams } from 'react-router-dom';
import ChapterCard from '../components/ChapterCard';
import MangaDetails from '../components/MangaDetails';
import NavBarTitle from '../context/NavbarTitle';
export default function Manga() {
const { id } = useParams<{id: string}>();
const { setTitle } = useContext(NavBarTitle);
const [manga, setManga] = useState<IManga>();
const [chapters, setChapters] = useState<IChapter[]>([]);
@ -12,7 +14,10 @@ export default function Manga() {
useEffect(() => {
fetch(`http://127.0.0.1:4567/api/v1/manga/${id}/`)
.then((response) => response.json())
.then((data) => setManga(data));
.then((data: IManga) => {
setManga(data);
setTitle(data.title);
});
}, []);
useEffect(() => {

View File

@ -1,12 +1,20 @@
import React, { useEffect, useState } from 'react';
import React, { useContext, useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
import MangaGrid from '../components/MangaGrid';
import NavBarTitle from '../context/NavbarTitle';
export default function MangaList(props: { popular: boolean }) {
const { sourceId } = useParams<{sourceId: string}>();
const { setTitle } = useContext(NavBarTitle);
const [mangas, setMangas] = useState<IManga[]>([]);
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(() => {
const sourceType = props.popular ? 'popular' : 'latest';
fetch(`http://127.0.0.1:4567/api/v1/source/${sourceId}/${sourceType}/${lastPageNum}`)

View File

@ -1,5 +1,6 @@
import React, { useEffect, useState } from 'react';
import React, { useContext, useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
import NavBarTitle from '../context/NavbarTitle';
const style = {
display: 'flex',
@ -14,14 +15,24 @@ interface IPage {
imageUrl: string
}
interface IData {
first: IChapter
second: IPage[]
}
export default function Reader() {
const { setTitle } = useContext(NavBarTitle);
const [pages, setPages] = useState<IPage[]>([]);
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())
.then((data) => setPages(data));
.then((data:IData) => {
setTitle(data.first.name);
setPages(data.second);
});
}, []);
pages.sort((a, b) => (a.index - b.index));

View File

@ -1,8 +1,9 @@
import React, { useState } from 'react';
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: {
@ -14,6 +15,8 @@ const useStyles = makeStyles((theme) => ({
}));
export default function Search() {
const { setTitle } = useContext(NavBarTitle);
setTitle('Search');
const classes = useStyles();
const [error, setError] = useState<boolean>(false);
const [mangas, setMangas] = useState<IManga[]>([]);

View File

@ -1,9 +1,12 @@
import React, { useEffect, useState } from 'react';
import React, { useContext, useEffect, useState } from 'react';
import SourceCard from '../components/SourceCard';
import NavBarTitle from '../context/NavbarTitle';
export default function Sources() {
let mapped;
const { setTitle } = useContext(NavBarTitle);
setTitle('Sources');
const [sources, setSources] = useState<ISource[]>([]);
let mapped;
useEffect(() => {
fetch('http://127.0.0.1:4567/api/v1/source/list')